grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH]: Add sparc64 boot block code.


From: David Miller
Subject: [PATCH]: Add sparc64 boot block code.
Date: Wed, 04 Mar 2009 01:07:35 -0800 (PST)

2009-03-04  David S. Miller  <address@hidden>

        * include/grub/sparc64/ieee1275/boot.h: New file.
        * boot/sparc/ieee1275/boot.S: Likewise.
        * boot/sparc/ieee1275/diskboot.S: Likewise.
        * conf/sparc64-ieee1275.rmk: Build sparc boot blocks.
        * conf/sparc64-ieee1275.mk: Regenerate.
---
 boot/sparc/ieee1275/boot.S           |  196 ++++++++++++++++++++++++++++++++++
 boot/sparc/ieee1275/diskboot.S       |  145 +++++++++++++++++++++++++
 conf/sparc64-ieee1275.mk             |   38 +++++++
 conf/sparc64-ieee1275.rmk            |   12 ++
 include/grub/sparc64/ieee1275/boot.h |   60 ++++++++++
 5 files changed, 451 insertions(+), 0 deletions(-)
 create mode 100644 boot/sparc/ieee1275/boot.S
 create mode 100644 boot/sparc/ieee1275/diskboot.S
 create mode 100644 include/grub/sparc64/ieee1275/boot.h

diff --git a/boot/sparc/ieee1275/boot.S b/boot/sparc/ieee1275/boot.S
new file mode 100644
index 0000000..66a07a6
--- /dev/null
+++ b/boot/sparc/ieee1275/boot.S
@@ -0,0 +1,196 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  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:
+       /* 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_ADDRESS
+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 + GRUB_BOOT_AOUT_HEADER_SIZE, %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/sparc/ieee1275/diskboot.S b/boot/sparc/ieee1275/diskboot.S
new file mode 100644
index 0000000..bced6d5
--- /dev/null
+++ b/boot/sparc/ieee1275/diskboot.S
@@ -0,0 +1,145 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  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_AOUT_HEADER_SIZE - 
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 3ba2d6b..0d69eac 100644
--- a/conf/sparc64-ieee1275.mk
+++ b/conf/sparc64-ieee1275.mk
@@ -10,6 +10,44 @@ COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax
 normal/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
+IMG_FMT = a.out-sunos-big
+pkglib_IMAGES = boot.img diskboot.img
+
+# For boot.img.
+boot_img_SOURCES = boot/sparc/ieee1275/boot.S
+CLEANFILES += boot.img boot.exec boot_img-boot_sparc_ieee1275_boot.o
+MOSTLYCLEANFILES += boot_img-boot_sparc_ieee1275_boot.d
+
+boot.img: boot.exec
+       $(OBJCOPY) -O $(IMG_FMT) -R .note -R .comment -R .note.gnu.build-id $< 
$@
+
+boot.exec: boot_img-boot_sparc_ieee1275_boot.o
+       $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(boot_img_LDFLAGS)
+
+boot_img-boot_sparc_ieee1275_boot.o: boot/sparc/ieee1275/boot.S 
$(boot/sparc/ieee1275/boot.S_DEPENDENCIES)
+       $(TARGET_CC) -Iboot/sparc/ieee1275 -I$(srcdir)/boot/sparc/ieee1275 
$(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(boot_img_ASFLAGS) -MD -c -o 
$@ $<
+-include boot_img-boot_sparc_ieee1275_boot.d
+
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4000
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/sparc/ieee1275/diskboot.S
+CLEANFILES += diskboot.img diskboot.exec 
diskboot_img-boot_sparc_ieee1275_diskboot.o
+MOSTLYCLEANFILES += diskboot_img-boot_sparc_ieee1275_diskboot.d
+
+diskboot.img: diskboot.exec
+       $(OBJCOPY) -O $(IMG_FMT) -R .note -R .comment -R .note.gnu.build-id $< 
$@
+
+diskboot.exec: diskboot_img-boot_sparc_ieee1275_diskboot.o
+       $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(diskboot_img_LDFLAGS)
+
+diskboot_img-boot_sparc_ieee1275_diskboot.o: boot/sparc/ieee1275/diskboot.S 
$(boot/sparc/ieee1275/diskboot.S_DEPENDENCIES)
+       $(TARGET_CC) -Iboot/sparc/ieee1275 -I$(srcdir)/boot/sparc/ieee1275 
$(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(diskboot_img_ASFLAGS) -MD 
-c -o $@ $<
+-include diskboot_img-boot_sparc_ieee1275_diskboot.d
+
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200
 
 MOSTLYCLEANFILES += symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
index 45a580c..7504ac3 100644
--- a/conf/sparc64-ieee1275.rmk
+++ b/conf/sparc64-ieee1275.rmk
@@ -9,6 +9,18 @@ COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax
 normal/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
+IMG_FMT = a.out-sunos-big
+pkglib_IMAGES = boot.img diskboot.img
+
+# For boot.img.
+boot_img_SOURCES = boot/sparc/ieee1275/boot.S
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4000
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/sparc/ieee1275/diskboot.S
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200
 
 MOSTLYCLEANFILES += symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst
diff --git a/include/grub/sparc64/ieee1275/boot.h 
b/include/grub/sparc64/ieee1275/boot.h
new file mode 100644
index 0000000..1e8e960
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/boot.h
@@ -0,0 +1,60 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008   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/>.
+ */
+
+#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 0x80
+
+#define GRUB_BOOT_MACHINE_KERNEL_ADDRESS 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 */
-- 
1.6.1.2.253.ga34a





reply via email to

[Prev in Thread] Current Thread [Next in Thread]