]> git.proxmox.com Git - grub2.git/blame - grub-core/boot/sparc64/ieee1275/boot.S
Add support for modern sparc64 hardware
[grub2.git] / grub-core / boot / sparc64 / ieee1275 / boot.S
CommitLineData
4d8d554a
CW
1/* -*-Asm-*- */
2/*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
5 *
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <grub/machine/boot.h>
21
22 .text
23 .align 4
24 .globl _start
25_start:
26 /* OF CIF entry point arrives in %o4 */
27pic_base:
28 call boot_continue
29 mov %o4, CIF_REG
30
31#ifndef CDBOOT
32 /* The offsets to these locations are defined by the
33 * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h,
34 * and grub-setup uses this to patch these next three values as needed.
35 *
36 * The boot_path will be the OF device path of the partition where the
37 * rest of the GRUB kernel image resides. kernel_sector will be set to
38 * the location of the first block of the GRUB kernel, and
39 * kernel_address is the location where we should load that first block.
40 *
41 * After loading in that block we will execute it by jumping to the
42 * load address plus the size of the prepended A.OUT header (32 bytes).
43 */
44 .org GRUB_BOOT_MACHINE_BOOT_DEVPATH
45boot_path:
46 .org GRUB_BOOT_MACHINE_KERNEL_BYTE
47boot_path_end:
48kernel_byte: .xword (2 << 9)
49kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
50#else
51#define boot_path (_start + 512 + SCRATCH_PAD_BOOT_SIZE)
52#define boot_path_end (_start + 1024)
53#include <grub/offsets.h>
54
55 .org 8
56kernel_byte: .xword (2 << 9)
57kernel_size: .word 512
58kernel_address: .word GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS
59#endif
60
61prom_finddev_name: .asciz "finddevice"
62prom_chosen_path: .asciz "/chosen"
63prom_getprop_name: .asciz "getprop"
64prom_stdout_name: .asciz "stdout"
65prom_write_name: .asciz "write"
66prom_bootpath_name: .asciz "bootpath"
67prom_open_name: .asciz "open"
68prom_seek_name: .asciz "seek"
69prom_read_name: .asciz "read"
70prom_exit_name: .asciz "exit"
71grub_name: .asciz "GRUB "
e1c95655
ES
72#ifdef CDBOOT
73prom_close_name: .asciz "close"
74#endif
75
4d8d554a
CW
76#define GRUB_NAME_LEN 5
77
78 .align 4
79
80prom_open_error:
81 GET_ABS(prom_open_name, %o2)
82 call console_write
83 mov 4, %o3
84 /* fallthru */
85
86prom_error:
87 GET_ABS(prom_exit_name, %o0)
88 /* fallthru */
89
90 /* %o0: OF call name
91 * %o1: input arg 1
92 */
93prom_call_1_1_o2:
94 clr %o2
95 ba prom_call_x_1
96 mov 1, %g1
97
98prom_call_getprop:
99 mov 4, %g1
100 stx %g1, [%l1 + 256]
101 mov CHOSEN_NODE_REG, %o1
102 ba prom_call_x_1
103 GET_ABS(prom_getprop_name, %o0)
104
105prom_call_3_1_o1:
106 ba prom_call_3_1
107 mov BOOTDEV_REG, %o1
108
109
110 /* %o2: message string
111 * %o3: message length
112 */
113console_write:
114 GET_ABS(prom_write_name, %o0)
115 mov STDOUT_NODE_REG, %o1
116 /* fallthru */
117
118 /* %o0: OF call name
119 * %o1: input arg 1
120 * %o2: input arg 2
121 * %o3: input arg 3
122 */
123prom_call_3_1:
124 mov 3, %g1
125prom_call_x_1:
126 mov 1, %o5
127 /* fallthru */
128
129 /* %o0: OF call name
130 * %g1: num inputs
131 * %o5: num outputs
132 * %o1-%o4: inputs
133 */
134prom_call:
135 stx %o0, [%l1 + 0x00]
136 stx %g1, [%l1 + 0x08]
137 stx %o5, [%l1 + 0x10]
138 stx %o1, [%l1 + 0x18]
139 stx %o2, [%l1 + 0x20]
140 stx %o3, [%l1 + 0x28]
141 stx %o4, [%l1 + 0x30]
142 jmpl CIF_REG, %g0
143 mov %l1, %o0
144
145boot_continue:
146 mov %o7, PIC_REG /* PIC base */
147#ifndef CDBOOT
148 sethi %hi(SCRATCH_PAD_BOOT), %l1 /* OF argument slots */
149#else
150 GET_ABS(_start + 512, %l1) /* OF argument slots */
151#endif
152
153 /* Find the /chosen node so we can fetch the stdout handle,
154 * and thus perform console output.
155 *
156 * chosen_node = prom_finddevice("/chosen")
157 */
158 GET_ABS(prom_finddev_name, %o0)
159 call prom_call_1_1_o2
160 GET_ABS(prom_chosen_path, %o1)
161
162 ldx [%l1 + 0x20], CHOSEN_NODE_REG
163 brz CHOSEN_NODE_REG, prom_error
164
165 /* getprop(chosen_node, "stdout", &buffer, buffer_size) */
166 GET_ABS(prom_stdout_name, %o2)
167 add %l1, 256, %o3
168 call prom_call_getprop
169 mov 1024, %o4
170
171 lduw [%l1 + 256], STDOUT_NODE_REG
172 brz,pn STDOUT_NODE_REG, prom_error
173
174 /* write(stdout_node, "GRUB ", strlen("GRUB ")) */
175 GET_ABS(grub_name, %o2)
176 call console_write
177 mov GRUB_NAME_LEN, %o3
178
179 GET_ABS(boot_path, %o3)
180#ifndef CDBOOT
181 ldub [%o3], %o1
182 brnz,pn %o1, bootpath_known
183#endif
184
185 /* getprop(chosen_node, "bootpath", &buffer, buffer_size) */
186 GET_ABS(prom_bootpath_name, %o2)
187 call prom_call_getprop
188 mov (boot_path_end - boot_path), %o4
189
190bootpath_known:
191
192 /* Open up the boot_path, and use that handle to read the
193 * first block of the GRUB kernel image.
194 *
195 * bootdev_handle = open(boot_path)
196 */
197 GET_ABS(prom_open_name, %o0)
198 call prom_call_1_1_o2
199 GET_ABS(boot_path, %o1)
200
201 ldx [%l1 + 0x20], BOOTDEV_REG
202 brz,pn BOOTDEV_REG, prom_open_error
203
204 /* Since we have 64-bit cells, the high cell of the seek offset
205 * is zero and the low cell is the entire value.
206 *
207 * seek(bootdev, 0, *kernel_byte)
208 */
209 GET_ABS(prom_seek_name, %o0)
210 clr %o2
211 call prom_call_3_1_o1
212 LDX_ABS(kernel_byte, 0x00, %o3)
213
214 /* read(bootdev, *kernel_address, 512) */
215 GET_ABS(prom_read_name, %o0)
216 LDUW_ABS(kernel_address, 0x00, %o2)
217 call prom_call_3_1_o1
218#ifdef CDBOOT
219 LDUW_ABS(kernel_size, 0x00, %o3)
e1c95655
ES
220
221 GET_ABS(prom_close_name, %o0)
222 mov 1, %g1
223 mov 0, %o5
224 call prom_call
225 mov BOOTDEV_REG, %o1
4d8d554a
CW
226#else
227 mov 512, %o3
228#endif
229
230 LDUW_ABS(kernel_address, 0x00, %o2)
231 jmpl %o2, %o7
232#ifdef CDBOOT
233 mov CIF_REG, %o4
234#else
235 nop
236#endif
237 .org GRUB_BOOT_MACHINE_CODE_END
238
239/* the last 4 bytes in the sector 0 contain the signature */
240 .word GRUB_BOOT_MACHINE_SIGNATURE