3
* GRUB -- GRand Unified Bootloader
4
* Copyright (C) 2009 Free Software Foundation, Inc.
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.
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.
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/>.
20
#include <grub/boot.h>
21
#include <grub/machine/boot.h>
27
/* OF CIF entry point arrives in %o4 */
32
. = _start + GRUB_BOOT_MACHINE_VER_MAJ
33
boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
35
/* The offsets to these locations are defined by the
36
* GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h,
37
* and grub-setup uses this to patch these next three values as needed.
39
* The boot_path will be the OF device path of the partition where the
40
* rest of the GRUB kernel image resides. kernel_sector will be set to
41
* the location of the first block of the GRUB kernel, and
42
* kernel_address is the location where we should load that first block.
44
* After loading in that block we will execute it by jumping to the
45
* load address plus the size of the prepended A.OUT header (32 bytes).
48
. = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE
50
kernel_byte: .xword (2 << 9)
51
kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
53
prom_finddev_name: .asciz "finddevice"
54
prom_chosen_path: .asciz "/chosen"
55
prom_getprop_name: .asciz "getprop"
56
prom_stdout_name: .asciz "stdout"
57
prom_write_name: .asciz "write"
58
prom_bootpath_name: .asciz "bootpath"
59
prom_open_name: .asciz "open"
60
prom_seek_name: .asciz "seek"
61
prom_read_name: .asciz "read"
62
prom_exit_name: .asciz "exit"
63
grub_name: .asciz "GRUB "
64
#define GRUB_NAME_LEN 5
69
GET_ABS(prom_open_name, %o2)
75
GET_ABS(prom_exit_name, %o0)
89
mov CHOSEN_NODE_REG, %o1
91
GET_ABS(prom_getprop_name, %o0)
98
/* %o2: message string
102
GET_ABS(prom_write_name, %o0)
103
mov STDOUT_NODE_REG, %o1
123
stx %o0, [%l1 + 0x00]
124
stx %g1, [%l1 + 0x08]
125
stx %o5, [%l1 + 0x10]
126
stx %o1, [%l1 + 0x18]
127
stx %o2, [%l1 + 0x20]
128
stx %o3, [%l1 + 0x28]
129
stx %o4, [%l1 + 0x30]
134
mov %o7, PIC_REG /* PIC base */
135
sethi %hi(SCRATCH_PAD_BOOT), %l1 /* OF argument slots */
137
/* Find the /chosen node so we can fetch the stdout handle,
138
* and thus perform console output.
140
* chosen_node = prom_finddevice("/chosen")
142
GET_ABS(prom_finddev_name, %o0)
143
call prom_call_1_1_o2
144
GET_ABS(prom_chosen_path, %o1)
146
ldx [%l1 + 0x20], CHOSEN_NODE_REG
147
brz CHOSEN_NODE_REG, prom_error
149
/* getprop(chosen_node, "stdout", &buffer, buffer_size) */
150
GET_ABS(prom_stdout_name, %o2)
152
call prom_call_getprop
155
lduw [%l1 + 256], STDOUT_NODE_REG
156
brz,pn STDOUT_NODE_REG, prom_error
158
/* write(stdout_node, "GRUB ", strlen("GRUB ")) */
159
GET_ABS(grub_name, %o2)
161
mov GRUB_NAME_LEN, %o3
163
GET_ABS(boot_path, %o3)
165
brnz,pn %o1, bootpath_known
167
/* getprop(chosen_node, "bootpath", &buffer, buffer_size) */
168
GET_ABS(prom_bootpath_name, %o2)
169
call prom_call_getprop
170
mov (boot_path_end - boot_path), %o4
174
/* Open up the boot_path, and use that handle to read the
175
* first block of the GRUB kernel image.
177
* bootdev_handle = open(boot_path)
179
GET_ABS(prom_open_name, %o0)
180
call prom_call_1_1_o2
181
GET_ABS(boot_path, %o1)
183
ldx [%l1 + 0x20], BOOTDEV_REG
184
brz,pn BOOTDEV_REG, prom_open_error
186
/* Since we have 64-bit cells, the high cell of the seek offset
187
* is zero and the low cell is the entire value.
189
* seek(bootdev, 0, *kernel_byte)
191
GET_ABS(prom_seek_name, %o0)
193
call prom_call_3_1_o1
194
LDX_ABS(kernel_byte, 0x00, %o3)
196
/* read(bootdev, *kernel_address, 512) */
197
GET_ABS(prom_read_name, %o0)
198
LDUW_ABS(kernel_address, 0x00, %o2)
199
call prom_call_3_1_o1
202
LDUW_ABS(kernel_address, 0x00, %o2)
206
. = _start + GRUB_BOOT_MACHINE_CODE_END
208
/* the last 4 bytes in the sector 0 contain the signature */
209
.word GRUB_BOOT_MACHINE_SIGNATURE