Files
openbios/arch/sparc32/entry.S

462 lines
13 KiB
ArmAsm
Raw Normal View History

/**
** Standalone startup code for Linux PROM emulator.
** Copyright 1999 Pete A. Zaitcev
** This code is licensed under GNU General Public License.
**/
/*
* $Id: head.S,v 1.12 2002/07/23 05:47:09 zaitcev Exp $
*/
#include "psr.h"
#include "asm/asi.h"
#include "asm/crs.h"
#define NO_QEMU_PROTOS
#include "openbios/fw_cfg.h"
#define CFG_ADDR 0x00000510
#define CFG_ASI 0x2d
#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */
#define PHYS_SS10_INTR0 0xf1400000
#define PHYS_SS2_INTR0 0xf5000000
#define SER_ADDR2 0xf1000004
#define PHYS_SS1000_SBI 0x02800000
#define SER_ADDR1000 0x00200004
#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
.globl entry, _entry
.section ".text", "ax"
.align 8
/* Memory map:
*
* Top +-------------------------+
* | SMP CPU table |
* | s + 0xf00 ... 0xf0f |
* | s + 0xf0c valid |
* | s + 0xf08 entry |
* | s + 0xf04 ctxtbl |
* | s + 0xf00 ctx |
* +-------------------------+
* | Bootstrap |
* | MMU L3 tables 5 * 0x100 |
* | s + 0xa00 ... 0xeff |
* +-------------------------+
* | Bootstrap |
* | MMU L2 tables 2 * 0x100 |
* | s + 0x800 ... 0x9ff |
* +-------------------------+
* | Bootstrap |
* | MMU L1 table 0x400 |
* | s + 0x400 ... 0x7ff |
* +-------------------------+
* | Bootstrap |
* | MMU L0/ctx table 0x400 |
* | s + 0x000 ... 0x3ff |
* +-------------------------+
* | |
* | ROM into RAM |
* | |
* +-------------------------+
* : :
* Bottom
*/
/*
* Entry point
* We start execution from here.
*/
_entry:
entry:
/* Switch to our main context.
* Main context is statically defined in C.
*/
! Check signature "QEMU"
set CFG_ADDR, %g5
mov FW_CFG_SIGNATURE, %g2
stha %g2, [%g5] CFG_ASI
add %g5, 2, %g5
lduba [%g5] CFG_ASI, %g2
cmp %g2, 'Q'
bne bad_conf
nop
lduba [%g5] CFG_ASI, %g2
cmp %g2, 'E'
bne bad_conf
nop
lduba [%g5] CFG_ASI, %g2
cmp %g2, 'M'
bne bad_conf
nop
lduba [%g5] CFG_ASI, %g2
cmp %g2, 'U'
bne bad_conf
nop
! Get memory size from configuration device
! NB: little endian format
mov FW_CFG_RAM_SIZE, %g2
sub %g5, 2, %g5
stha %g2, [%g5] CFG_ASI
add %g5, 2, %g5
lduba [%g5] CFG_ASI, %g4
lduba [%g5] CFG_ASI, %g3
sll %g3, 8, %g3
or %g3, %g4, %g4
lduba [%g5] CFG_ASI, %g3
sll %g3, 16, %g3
or %g3, %g4, %g4
lduba [%g5] CFG_ASI, %g3
sll %g3, 24, %g3
or %g3, %g4, %g1
! %g1 contains end of memory
! Start of private memory in %g6
set 0x1000, %g3
sub %g1, %g3, %g6
! Calculate SMP table location
add %g6, 0xf0c, %g2 ! valid?
lda [%g2] ASI_M_BYPASS, %g7
sta %g0, [%g2] ASI_M_BYPASS
! Get machine ID from configuration device
mov FW_CFG_MACHINE_ID, %g2
sub %g5, 2, %g5
stha %g2, [%g5] CFG_ASI
add %g5, 2, %g5
lduba [%g5] CFG_ASI, %g4
lduba [%g5] CFG_ASI, %g3
sll %g3, 8, %g3
or %g3, %g4, %g4
mov %g4, %y
cmp %g4, 96
bgeu ss1000
cmp %g4, 64
bgeu ss10
cmp %g4, 32
blu ss2
nop
! Ok, this is SS-5
tst %g7
bz first_cpu
nop
! Clear softints used for SMP CPU startup
set PHYS_JJ_INTR0 + 0x04, %g1
sll %g2, 12, %g2
add %g1, %g2, %g2
set 0xffffffff, %g1
sta %g1, [%g2] ASI_M_BYPASS ! clear softints
add %g2, 4, %g2
sta %g0, [%g2] ASI_M_BYPASS ! clear softints
load_ctx:
! SMP init, jump to user specified address
add %g6, 0xf04, %g5 ! ctxtbl
lda [%g5] ASI_M_BYPASS, %g2
sta %g0, [%g5] ASI_M_BYPASS
set AC_M_CTPR, %g1
sta %g2, [%g1] ASI_M_MMUREGS ! set ctx table ptr
add %g6, 0xf00, %g5 ! ctx
lda [%g5] ASI_M_BYPASS, %g2
sta %g0, [%g5] ASI_M_BYPASS
set AC_M_CXR, %g1
sta %g2, [%g1] ASI_M_MMUREGS ! set context
add %g6, 0xf08, %g5 ! entry
lda [%g5] ASI_M_BYPASS, %g2
sta %g0, [%g5] ASI_M_BYPASS
set 1, %g1
jmp %g2 ! jump to kernel
sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
ss10:
! Ok, this is SS-10 or SS-600MP
tst %g7
bz first_cpu
nop
! Clear softints used for SMP CPU startup
set PHYS_SS10_INTR0 + 0x04, %g1
sll %g2, 12, %g2
add %g1, %g2, %g2
set 0xffffffff, %g1
sta %g1, [%g2] ASI_M_CTL ! clear softints
add %g2, 4, %g2
b load_ctx
sta %g0, [%g2] ASI_M_CTL ! clear softints
ss2:
! Ok, this is SS-2
set ss2_error, %o2
b ss2_ss1000_halt
nop
ss1000:
! Ok, this is SS-1000 or SS-2000
set ss1000_error, %o2
b ss2_ss1000_halt
nop
first_cpu:
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
/* Create temporary page tables and map the ROM area to end of
RAM. This will be done properly in iommu.c later. */
! Calculate start of page tables etc. to %g6
set 0x1000, %g4
sub %g1, %g4, %g6 ! start of private memory
mov %g6, %g2 ! ctx table at s+0x0
add %g2, 0x400, %g3 ! l1 table at s+0x400
srl %g3, 0x4, %g3
or %g3, 0x1, %g3
sta %g3, [%g2] ASI_M_BYPASS
add %g2, 0x400, %g2 ! s+0x400
add %g2, 0x400, %g3 ! l2 table for ram (00xxxxxx) at s+0x800
srl %g3, 0x4, %g3
or %g3, 0x1, %g3
sta %g3, [%g2] ASI_M_BYPASS
add %g2, 0x500, %g3 ! l2 table for rom (ffxxxxxx) at s+0x900
add %g2, 0x3fc, %g2 ! s+0x7fc
srl %g3, 0x4, %g3
or %g3, 0x1, %g3
sta %g3, [%g2] ASI_M_BYPASS
add %g2, 0x4, %g2 ! s+0x800
#if 0
set 0x40, %g6
set ((7 << 2) | 2), %g3 ! 7 = U: --- S: RWX (main memory)
1: sta %g3, [%g2] ASI_M_BYPASS
add %g2, 4, %g2
deccc %g6
bne 1b
nop
#else
add %g2, 0x100, %g2
#endif
! s+0x900
add %g2, 0xa00 - 0x900, %g3 ! l3 table for rom at s+0xa00
add %g2, 0x0d0, %g2 ! s+0x9d0
srl %g3, 0x4, %g3
or %g3, 0x1, %g3
sta %g3, [%g2] ASI_M_BYPASS
add %g2, 4, %g2 ! s+0x9d4
add %g2, 0xb00 - 0x9d4, %g3 ! 2nd l3 table for rom at s+0xb00
srl %g3, 0x4, %g3
or %g3, 0x1, %g3
sta %g3, [%g2] ASI_M_BYPASS
add %g2, 4, %g2 ! s+0x9d8
add %g2, 0xc00 - 0x9d8, %g3 ! 3rd l3 table for rom at s+0xc00
srl %g3, 0x4, %g3
or %g3, 0x1, %g3
sta %g3, [%g2] ASI_M_BYPASS
add %g2, 4, %g2 ! s+0x9dc
add %g2, 0xd00 - 0x9dc, %g3 ! 4th l3 table for rom at s+0xd00
srl %g3, 0x4, %g3
or %g3, 0x1, %g3
sta %g3, [%g2] ASI_M_BYPASS
add %g2, 4, %g2 ! s+0x9e0
add %g2, 0xe00 - 0x9e0, %g3 ! 5th l3 table for rom at s+0xe00
srl %g3, 0x4, %g3
or %g3, 0x1, %g3
sta %g3, [%g2] ASI_M_BYPASS
add %g2, 0xa00-0x9e0, %g2 ! s+0xa00
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
/* Use end of ram for code, rodata, data, and bss
sections. SunOS wants to write to trap table... */
set _end, %g6
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
set _start, %g4
sub %g6, %g4, %g6
sub %g1, %g6, %g3
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
set 0x1000, %g5
sub %g3, %g5, %g3 ! start of ROM copy
mov %g3, %g7 ! save in %g7
srl %g6, 12, %g6 ! # of all pages
1: srl %g3, 0x4, %g4
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
or %g4, ((7 << 2) | 2), %g4 ! 7 = U: --- S: RWX
sta %g4, [%g2] ASI_M_BYPASS
add %g2, 4, %g2
add %g3, %g5, %g3
deccc %g6
bne 1b
nop
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
mov %g1, %g6 ! %g6 = memory size
/* Copy the code, rodata and data sections from ROM. */
sub %g7, 4, %g3
set _start - 4, %g4 ! First address of TEXT - 4
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
set _bss, %g5 ! Last address of DATA
ba 2f
nop
1:
lda [%g4] ASI_M_KERNELTXT, %g1
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
sta %g1, [%g3] ASI_M_BYPASS
2:
cmp %g4, %g5
add %g3, 0x4, %g3
bl 1b
add %g4, 0x4, %g4
set 0x1000, %g3
sub %g6, %g3, %g7 ! ctx table at s+0x0
set AC_M_CTPR, %g2
srl %g7, 4, %g7
sta %g7, [%g2] ASI_M_MMUREGS ! set ctx table ptr
set AC_M_CXR, %g2
sta %g0, [%g2] ASI_M_MMUREGS ! context 0
set highmem, %g2
set 1, %g1
jmp %g2
sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
highmem:
/*
* The code which enables traps is a simplified version of
* kernel head.S.
*
* We know number of windows as 8 so we do not calculate them.
* The deadwood is here for any case.
*/
/* Turn on Supervisor, EnableFloating, and all the PIL bits.
* Also puts us in register window zero with traps off.
*/
set (PSR_PS | PSR_S | PSR_PIL | PSR_EF), %g2
wr %g2, 0x0, %psr
WRITE_PAUSE
/* Zero out our BSS section. */
set _bss - 4, %o0 ! First address of BSS
set _estack - 4, %o1 ! Last address of BSS
ba 2f
nop
1:
st %g0, [%o0]
2:
subcc %o0, %o1, %g0
bl 1b
add %o0, 0x4, %o0
set trap_table, %g1
wr %g1, 0x0, %tbr
set qemu_mem_size, %g1
Patch for SunOS compatibility from pjcreath+openbios@gmail.com: I've been trying to get old versions of SunOS to load under qemu. In doing so, I've encountered a number of bugs in OBP. I'm not always certain of the best fix, but I can at least provide a quick hack that will get people farther along. 1) Error message: "kmem_alloc failed, nbytes 680" Bug: obp_dumb_memalloc is a bit too dumb. It needs to pick an address if passed a null address. (According to the comment in the allocator in OpenSolaris prom_alloc.c (see <http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c>), "If virthint is zero, a suitable virt is chosen.") Quick fix: If passed a null address, start doling out addresses at 10MB and increment by size. Shortcomings: The quick fix ignores the issue of free() and doesn't remove memory from the virtual-memory/available node. After the quick fix, the boot gets farther, leading us to: 2) Error message: "Unhandled Exception 0x00000080" Bug: Trap 0 (entry 0x80 in the table, i.e. syscall_trap_4x) is undefined. This is because the SunOS bootloader installs the trap by writing code in the trap table, but the trap table is in the .text section of OpenBIOS. Thus the trap 0 handler simply jumps to "bug". Quick fix: Move the trap table to the .data section. Insert a "b entry; nop; nop; nop;" before "bug:". Shortcomings: Requires the extra "b entry" code. Allows the only VM copy of the trap table to be permanently changed. OpenBIOS should copy the read-only trap table to read-write memory (and update %tbr) upon reset/entry. 3) #2 above actually exposes another bug. The write to the read-only trap table does not cause an access violation -- instead, it silently fails. The "std" instruction at 0x403e6c in the bootloader has no effect. Bug: Uncertain. It could be a systemic bug in qemu, but it appears that the VM's MMU believes that the page is writable. That means that the VM's MMU is not having the access protection flags set for pages mapped to ROM. It thinks everything is rwx. Fix?: The VM's MMU should have the access protection flags properly set for each ROM section. This should probably be done within OpenBIOS. E.g., .text should be r-x, .data should probably be rwx, etc. This is the one fix I'm really not sure how to implement. Any suggestions? This may be a problem that only affects this bootloader, so fixing #2 above may be all that's strictly necessary. But I'm not positive that this bug doesn't have other ill effects I haven't found yet. At any rate, fixing #2 gets us still further, to: 4) Error messages: "obp_devopen(sd(0,0,0):d) = 0xffd8e270 obp_inst2pkg(fd 0xffd8e270) = 0xffd57f44 obp_getprop(0xffd57f44, device_type) (not found)" Bug: The OpenBIOS "interpose" implementation is not transparent to non-interposition-aware code (in violation of the interposition spec). The inst2pkg call in this sequence returns the phandle for /packages/misc-files, instead of the proper phandle. Quick fix: Comment out the "interpose disk-label" lines in ob_sd_open. Shortcomings: It disables disk-label. The correct fix is to fix the underlying problem with interposition, but I'm not sure exactly what it is. Could someone help? Fixing #4 gets us quite a bit further, until: 5) Error message: "Unhandled Exception 0x00000009 PC = 0xf0138b20 NPC = 0xf0138b24 Stopping execution" Bug: The instruction is trying to read from 0xfd020000+4, which is an invalid address. This address isn't mapped by OBP by default on Sun hardware, so the bootloader must be trying to (a) map this address and failing silently or (b) skipping the mapping for some reason. The instruction is hard-coded to look at this absolute address. Fix: Unknown. This may be another instance of writes silently failing, hence my interest in #3 above. It could also be a side-effect of the quick fix for #4. 6) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008f0c addr=feff8008 mmu_fsr=3a6 rw=2 MMU sfsr=3a6: Invalid Address on supv data store at level 3 regs at fd008f0c: psr=4400fc7 pc=f00053f4 npc=f00053f8 ..." Bug: Real sun4m hardware registers 4 CPU-specific interrupts followed by a system-wide interrupt, regardless of the number of CPUs installed. The same is true of counters. SunOS looks at the 5th interrupt for the system-wide interrupt. OBP, since there's only one CPU, just sets up one CPU-specific interrupt followed by the system-wide interrupt, so there is no 5th interrupt. See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/project/opssrc/sys.sunos/sun4m/devaddr.h>. Fix: in obp_interrupt_init() and obp_counter_init() register 4 CPU-specific interrupts before allocating the system-wide interrupt. The kernel will then map the 5th interrupt to the system-wide interrupt. 7) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d8c addr=7ff000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d8c: psr=4000cc4 pc=f01339a4 npc=f01339a8 ..." Bug: The command-line arguments passed to the kernel are fixed at address 0x7FF000 (CMDLINE_ADDR, passed from qemu via nv_info.cmdline), which is no longer mapped by the time the kernel looks at the boot arguments. A regular Sun boot ROM will copy this into mapped memory. Fix: Copy the string in nv_info.cmdline to a OpenBIOS global (since OpenBIOS continues to be mapped) in ob_nvram_init(). 8) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008dec addr=1019000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008dec: psr=4400cc5 pc=f0131680 npc=f0131684 ..." Bug: The dumb memory allocator from bug #1 was allocating a range that the SunOS 4 kernel doesn't like. Fix: Mimic the Sun boot ROM allocator: the top of the heap should be a 0xFFEDA000 and allocations should return descending addresses. So, for example, if asking for 0x1000 bytes, the first returned pointer should be 0xFFED9000. 9) Error message: "BAD TRAP: cpu=0 type=9 rp=fd008d2c addr=b1b91000 mmu_fsr=126 rw=1 MMU sfsr=126: Invalid Address on supv data fetch at level 1 regs at fd008d2c: psr=4900cc3 pc=f0142c04 npc=f0142c08 ..." Bug: The precise underlying cause isn't clear. The bug appears due to a variation between OBP's behavior and stock Sun behavior. Fix: Add the "cache-physical?" property to the CPU node in ob_nvram_init() and bump the "mmu-nctx" property up to 4096 (from 256). git-svn-id: svn://coreboot.org/openbios/openbios-devel@114 f158a5a8-5612-0410-a976-696ce0be7e32
2007-03-09 00:59:05 +00:00
st %g6, [%g1]
set _end, %o0 ! Store va->pa conversion factor
set _start, %o2
sub %o0, %o2, %o0
sub %g6, %o0, %o0
set 0x1000, %o1
sub %o0, %o1, %o0 ! start of ROM copy
sub %o2, %o0, %o0 ! start of ROM copy
set va_shift, %g1
st %o0, [%g1]
set qemu_machine_type, %g1
mov %y, %g2
st %g2, [%g1]
/* Compute NWINDOWS and stash it away. Now uses %wim trick explained
* in the V8 manual. Ok, this method seems to work, Sparc is cool...
* No, it doesn't work, have to play the save/readCWP/restore trick.
*/
wr %g0, 0x0, %wim ! so we do not get a trap
WRITE_PAUSE
save
rd %psr, %g3
restore
and %g3, 0x1f, %g3
add %g3, 0x1, %g3
mov 2, %g1
wr %g1, 0x0, %wim ! make window 1 invalid
WRITE_PAUSE
cmp %g3, 0x7
bne 1f
nop
/* Adjust our window handling routines to
* do things correctly on 7 window Sparcs.
*/
#define PATCH_INSN(src, dest) \
set src, %g5; \
set dest, %g2; \
ld [%g5], %g4; \
st %g4, [%g2];
/* Patch for window spills... */
PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
PATCH_INSN(spnwin_patch2_7win, spnwin_patch2)
/* Patch for window fills... */
PATCH_INSN(fnwin_patch1_7win, fnwin_patch1)
PATCH_INSN(fnwin_patch2_7win, fnwin_patch2)
1:
/* Finally, turn on traps so that we can call c-code. */
rd %psr, %g3
wr %g3, 0x0, %psr
WRITE_PAUSE
wr %g3, PSR_ET, %psr
WRITE_PAUSE
call __switch_context_nosave
nop
/* We get here when the main context switches back to
* the boot context.
* Return to previous bootloader.
*/
ret
nop
ss2_ss1000_halt:
set SER_ADDR2, %o0
set SER_ADDR1000, %o1
mov 0x05, %o3 /* Reg 5, TXCTRL2 */
stba %o3, [%o0] ASI_M_BYPASS
stba %o3, [%o1] ASI_M_CTL
mov 0x68, %o3 /* 8 bits, Tx enabled */
stba %o3, [%o0] ASI_M_BYPASS
stba %o3, [%o1] ASI_M_CTL
add %o0, 2, %o0
add %o1, 2, %o1
1: lduba [%o2] ASI_M_KERNELTXT, %o3
cmp %o3, 0
be 2f
nop
stba %o3, [%o0] ASI_M_BYPASS
stba %o3, [%o1] ASI_M_CTL
b 1b
inc %o2
bad_conf:
2: b 2b
nop
.section .rodata
ss2_error:
.string "Sun4c machines are not supported by OpenBIOS yet, freezing\r\n"
ss1000_error:
.string "Sun4d machines are not supported by OpenBIOS yet, freezing\r\n"