146 lines
3.1 KiB
ArmAsm
146 lines
3.1 KiB
ArmAsm
|
/* -*-Asm-*- */
|
||
|
/*
|
||
|
* GRUB -- GRand Unified Bootloader
|
||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||
|
*
|
||
|
* GRUB is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* GRUB is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include <grub/boot.h>
|
||
|
#include <grub/machine/boot.h>
|
||
|
|
||
|
.text
|
||
|
.align 4
|
||
|
.globl _start
|
||
|
_start:
|
||
|
/* First stage boot block jumps to us here. */
|
||
|
pic_base:
|
||
|
call after_info_block
|
||
|
mov %o7, PIC_REG
|
||
|
|
||
|
prom_write_name: .asciz "write"
|
||
|
prom_seek_name: .asciz "seek"
|
||
|
prom_read_name: .asciz "read"
|
||
|
prom_close_name: .asciz "close"
|
||
|
|
||
|
notification_string: .asciz "Loading kernel"
|
||
|
#define NOTIFICATION_STRING_LEN 14
|
||
|
|
||
|
notification_step: .asciz "."
|
||
|
#define NOTIFICATION_STEP_LEN 1
|
||
|
|
||
|
notification_done: .asciz "\r\n"
|
||
|
#define NOTIFICATION_DONE_LEN 2
|
||
|
|
||
|
.align 4
|
||
|
|
||
|
/* %o2: message string
|
||
|
* %o3: message length
|
||
|
*/
|
||
|
console_write:
|
||
|
GET_ABS(prom_write_name, %o0)
|
||
|
mov STDOUT_NODE_REG, %o1
|
||
|
/* fallthru */
|
||
|
|
||
|
/* %o0: OF call name
|
||
|
* %o1: input arg 1
|
||
|
* %o2: input arg 2
|
||
|
* %o3: input arg 3
|
||
|
*/
|
||
|
prom_call_3_1:
|
||
|
mov 3, %g1
|
||
|
mov 1, %o5
|
||
|
/* fallthru */
|
||
|
|
||
|
/* %o0: OF call name
|
||
|
* %g1: num inputs
|
||
|
* %o5: num outputs
|
||
|
* %o1-%o4: inputs
|
||
|
*/
|
||
|
prom_call:
|
||
|
stx %o0, [%l1 + 0x00]
|
||
|
stx %g1, [%l1 + 0x08]
|
||
|
stx %o5, [%l1 + 0x10]
|
||
|
stx %o1, [%l1 + 0x18]
|
||
|
stx %o2, [%l1 + 0x20]
|
||
|
stx %o3, [%l1 + 0x28]
|
||
|
stx %o4, [%l1 + 0x30]
|
||
|
jmpl CIF_REG, %g0
|
||
|
mov %l1, %o0
|
||
|
|
||
|
|
||
|
after_info_block:
|
||
|
sethi %hi(SCRATCH_PAD), %l1 /* OF argument slots */
|
||
|
|
||
|
GET_ABS(notification_string, %o2)
|
||
|
call console_write
|
||
|
mov NOTIFICATION_STRING_LEN, %o3
|
||
|
|
||
|
GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2)
|
||
|
set GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3
|
||
|
bootloop:
|
||
|
lduw [%l2 + 0x08], %o0
|
||
|
brz %o0, bootit
|
||
|
lduw [%l2 + 0x00], %o3
|
||
|
sllx %o3, 32, %o3
|
||
|
lduw [%l2 + 0x04], %o4
|
||
|
or %o3, %o4, %o3
|
||
|
GET_ABS(prom_seek_name, %o0)
|
||
|
mov BOOTDEV_REG, %o1
|
||
|
clr %o2
|
||
|
call prom_call_3_1
|
||
|
sllx %o3, 9, %o3
|
||
|
|
||
|
GET_ABS(prom_read_name, %o0)
|
||
|
mov BOOTDEV_REG, %o1
|
||
|
lduw [%l2 + 0x08], %o3
|
||
|
sllx %o3, 9, %o3
|
||
|
mov %l3, %o2
|
||
|
call prom_call_3_1
|
||
|
add %l3, %o3, %l3
|
||
|
|
||
|
GET_ABS(notification_step, %o2)
|
||
|
call console_write
|
||
|
mov NOTIFICATION_STEP_LEN, %o3
|
||
|
|
||
|
ba bootloop
|
||
|
sub %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2
|
||
|
|
||
|
bootit:
|
||
|
GET_ABS(prom_close_name, %o0)
|
||
|
mov 1, %g1
|
||
|
mov 0, %o5
|
||
|
call prom_call
|
||
|
mov BOOTDEV_REG, %o1
|
||
|
|
||
|
GET_ABS(notification_done, %o2)
|
||
|
call console_write
|
||
|
mov NOTIFICATION_DONE_LEN, %o3
|
||
|
sethi %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2
|
||
|
jmpl %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7
|
||
|
mov CIF_REG, %o0
|
||
|
1: ba,a 1b
|
||
|
|
||
|
lastlist:
|
||
|
.word 0
|
||
|
.word 0
|
||
|
|
||
|
. = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE)
|
||
|
blocklist_default_start:
|
||
|
.word 0
|
||
|
.word 2
|
||
|
blocklist_default_len:
|
||
|
.word 0
|
||
|
firstlist:
|