From 0f005da92ad0104d83a2d0da78ae5f28468f0c36 Mon Sep 17 00:00:00 2001 From: davem Date: Sat, 11 Apr 2009 08:33:35 +0000 Subject: [PATCH] Missed these in previous commits, sorry. --- boot/sparc64/ieee1275/boot.S | 196 +++++++++++++++++++++++++++ boot/sparc64/ieee1275/diskboot.S | 145 ++++++++++++++++++++ conf/sparc64-ieee1275.mk | 2 +- config.h.in | 6 + include/grub/sparc64/ieee1275/boot.h | 58 ++++++++ 5 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 boot/sparc64/ieee1275/boot.S create mode 100644 boot/sparc64/ieee1275/diskboot.S create mode 100644 include/grub/sparc64/ieee1275/boot.h diff --git a/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S new file mode 100644 index 000000000..74f4ee014 --- /dev/null +++ b/boot/sparc64/ieee1275/boot.S @@ -0,0 +1,196 @@ +/* -*-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 . + */ + +#include +#include + + .text + .align 4 + .globl _start +_start: + /* OF CIF entry point arrives in %o4 */ +pic_base: + call boot_continue + mov %o4, CIF_REG + + . = _start + GRUB_BOOT_MACHINE_VER_MAJ +boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR + + /* The offsets to these locations are defined by the + * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h, + * and grub-setup uses this to patch these next three values as needed. + * + * The boot_path will be the OF device path of the partition where the + * rest of the GRUB kernel image resides. kernel_sector will be set to + * the location of the first block of the GRUB kernel, and + * kernel_address is the location where we should load that first block. + * + * After loading in that block we will execute it by jumping to the + * load address plus the size of the prepended A.OUT header (32 bytes). + */ +boot_path: + . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR +kernel_sector: .xword 2 +kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR + +prom_finddev_name: .asciz "finddevice" +prom_chosen_path: .asciz "/chosen" +prom_getprop_name: .asciz "getprop" +prom_stdout_name: .asciz "stdout" +prom_write_name: .asciz "write" +prom_bootpath_name: .asciz "bootpath" +prom_open_name: .asciz "open" +prom_seek_name: .asciz "seek" +prom_read_name: .asciz "read" +prom_exit_name: .asciz "exit" +grub_name: .asciz "GRUB " +#define GRUB_NAME_LEN 5 + + .align 4 + +prom_open_error: + GET_ABS(prom_open_name, %o2) + call console_write + mov 4, %o3 + /* fallthru */ + +prom_error: + GET_ABS(prom_exit_name, %o0) + /* fallthru */ + + /* %o0: OF call name + * %o1: input arg 1 + */ +prom_call_1_1: + mov 1, %g1 + ba prom_call + mov 1, %o5 + + /* %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 + +boot_continue: + mov %o7, PIC_REG /* PIC base */ + sethi %hi(SCRATCH_PAD), %l1 /* OF argument slots */ + + /* Find the /chosen node so we can fetch the stdout handle, + * and thus perform console output. + * + * chosen_node = prom_finddevice("/chosen") + */ + GET_ABS(prom_finddev_name, %o0) + GET_ABS(prom_chosen_path, %o1) + call prom_call_1_1 + clr %o2 + + ldx [%l1 + 0x20], CHOSEN_NODE_REG + brz CHOSEN_NODE_REG, prom_error + + /* getprop(chosen_node, "stdout", &buffer, buffer_size) */ + GET_ABS(prom_getprop_name, %o0) + mov 4, %g1 + mov 1, %o5 + mov CHOSEN_NODE_REG, %o1 + GET_ABS(prom_stdout_name, %o2) + add %l1, 256, %o3 + mov 1024, %o4 + call prom_call + stx %g1, [%l1 + 256] + + lduw [%l1 + 256], STDOUT_NODE_REG + brz,pn STDOUT_NODE_REG, prom_error + + /* write(stdout_node, "GRUB ", strlen("GRUB ")) */ + GET_ABS(grub_name, %o2) + call console_write + mov GRUB_NAME_LEN, %o3 + + /* Open up the boot_path, and use that handle to read the + * first block of the GRUB kernel image. + * + * bootdev_handle = open(boot_path) + */ + GET_ABS(prom_open_name, %o0) + GET_ABS(boot_path, %o1) + call prom_call_1_1 + clr %o2 + + ldx [%l1 + 0x20], BOOTDEV_REG + brz,pn BOOTDEV_REG, prom_open_error + + /* Since we have 64-bit cells, the high cell of the seek offset + * is zero and the low cell is the entire value. + * + * seek(bootdev, 0, *kernel_sector << 9) + */ + GET_ABS(prom_seek_name, %o0) + mov BOOTDEV_REG, %o1 + clr %o2 + LDX_ABS(kernel_sector, 0x00, %o3) + call prom_call_3_1 + sllx %o3, 9, %o3 + + /* read(bootdev, *kernel_address, 512) */ + GET_ABS(prom_read_name, %o0) + mov BOOTDEV_REG, %o1 + LDUW_ABS(kernel_address, 0x00, %o2) + call prom_call_3_1 + mov 512, %o3 + + LDUW_ABS(kernel_address, 0x00, %o2) + jmpl %o2, %o7 + nop + +1: ba,a 1b + + . = _start + GRUB_BOOT_MACHINE_CODE_END + +/* the last 4 bytes in the sector 0 contain the signature */ + .word GRUB_BOOT_MACHINE_SIGNATURE diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S new file mode 100644 index 000000000..68ed0eee0 --- /dev/null +++ b/boot/sparc64/ieee1275/diskboot.S @@ -0,0 +1,145 @@ +/* -*-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 . + */ + +#include +#include + + .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: diff --git a/conf/sparc64-ieee1275.mk b/conf/sparc64-ieee1275.mk index d68b40eef..571b9cfe3 100644 --- a/conf/sparc64-ieee1275.mk +++ b/conf/sparc64-ieee1275.mk @@ -189,7 +189,7 @@ kernel_elf-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h kernel_elf_CFLAGS = $(COMMON_CFLAGS) kernel_elf_ASFLAGS = $(COMMON_ASFLAGS) -kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc +kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc # Modules. #_linux.mod linux.mod diff --git a/config.h.in b/config.h.in index c110d6307..e825f7c41 100644 --- a/config.h.in +++ b/config.h.in @@ -79,6 +79,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_USB_H +/* Define to 1 if you have the `__bswapdi2' function. */ +#undef HAVE___BSWAPDI2 + +/* Define to 1 if you have the `__bswapsi2' function. */ +#undef HAVE___BSWAPSI2 + /* Define to 1 if you enable memory manager debugging. */ #undef MM_DEBUG diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h new file mode 100644 index 000000000..95f311ce5 --- /dev/null +++ b/include/grub/sparc64/ieee1275/boot.h @@ -0,0 +1,58 @@ +/* + * 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 . + */ + +#ifndef GRUB_BOOT_MACHINE_HEADER +#define GRUB_BOOT_MACHINE_HEADER 1 + +#define CIF_REG %l0 +#define CHOSEN_NODE_REG %l4 +#define STDOUT_NODE_REG %l5 +#define BOOTDEV_REG %l6 +#define PIC_REG %l7 + +#define SCRATCH_PAD 0x10000 + +#define GET_ABS(symbol, reg) \ + add PIC_REG, (symbol - pic_base), reg +#define LDUW_ABS(symbol, offset, reg) \ + lduw [PIC_REG + (symbol - pic_base) + (offset)], reg +#define LDX_ABS(symbol, offset, reg) \ + ldx [PIC_REG + (symbol - pic_base) + (offset)], reg + +#define GRUB_BOOT_AOUT_HEADER_SIZE 32 + +#define GRUB_BOOT_MACHINE_SIGNATURE 0xbb44aa55 + +#define GRUB_BOOT_MACHINE_VER_MAJ 0x08 + +#define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a + +#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80 + +#define GRUB_BOOT_MACHINE_KERNEL_SECTOR 0x88 + +#define GRUB_BOOT_MACHINE_CODE_END \ + (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) + +#define GRUB_BOOT_MACHINE_LIST_SIZE 12 + +#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS 0x200000 + +#define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 + +#endif /* ! BOOT_MACHINE_HEADER */