2006-05-19 05:57:08 +08:00
|
|
|
/*
|
|
|
|
* OpenBIOS Sparc OBIO driver
|
2008-07-08 02:35:51 +08:00
|
|
|
*
|
2006-05-19 05:57:08 +08:00
|
|
|
* (C) 2004 Stefan Reinauer <stepan@openbios.org>
|
|
|
|
* (C) 2005 Ed Schouten <ed@fxq.nl>
|
2008-07-08 02:35:51 +08:00
|
|
|
*
|
2006-05-19 05:57:08 +08:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* version 2
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "openbios/config.h"
|
|
|
|
#include "openbios/bindings.h"
|
|
|
|
#include "openbios/kernel.h"
|
|
|
|
#include "libc/byteorder.h"
|
|
|
|
#include "libc/vsprintf.h"
|
|
|
|
|
|
|
|
#include "openbios/drivers.h"
|
2006-05-23 06:10:54 +08:00
|
|
|
#include "openbios/nvram.h"
|
2009-01-03 21:45:02 +08:00
|
|
|
#include "ofmem.h"
|
2006-05-23 06:10:54 +08:00
|
|
|
#include "obio.h"
|
2008-07-08 02:35:51 +08:00
|
|
|
#define cpu_to_be16(x) __cpu_to_be16(x)
|
2007-11-15 03:25:43 +08:00
|
|
|
#include "openbios/firmware_abi.h"
|
2008-09-19 02:41:26 +08:00
|
|
|
#define NO_QEMU_PROTOS
|
|
|
|
#include "openbios/fw_cfg.h"
|
2009-01-13 01:46:19 +08:00
|
|
|
#include "escc.h"
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
|
|
|
|
|
2006-07-23 22:29:29 +08:00
|
|
|
#define PROMDEV_KBD 0 /* input from keyboard */
|
|
|
|
#define PROMDEV_SCREEN 0 /* output to screen */
|
|
|
|
#define PROMDEV_TTYA 1 /* in/out to ttya */
|
2006-05-23 06:10:54 +08:00
|
|
|
|
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 08:59:05 +08:00
|
|
|
/* "NCPU" is an historical name that's now a bit of a misnomer. The sun4m
|
|
|
|
* architecture registers NCPU CPU-specific interrupts along with one
|
|
|
|
* system-wide interrupt, regardless of the number of actual CPUs installed.
|
|
|
|
* See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/
|
|
|
|
* project/opssrc/sys.sunos/sun4m/devaddr.h>.
|
|
|
|
*/
|
|
|
|
#define SUN4M_NCPU 4
|
|
|
|
|
|
|
|
/* The kernel may want to examine the arguments, so hold a copy in OBP's
|
|
|
|
* mapped memory.
|
|
|
|
*/
|
|
|
|
#define OBIO_CMDLINE_MAX 256
|
2008-07-08 02:35:51 +08:00
|
|
|
static char obio_cmdline[OBIO_CMDLINE_MAX];
|
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 08:59:05 +08:00
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
/* DECLARE data structures for the nodes. */
|
|
|
|
DECLARE_UNNAMED_NODE( ob_obio, INSTALL_OPEN, sizeof(int) );
|
2006-05-19 05:57:08 +08:00
|
|
|
|
2009-01-13 01:46:19 +08:00
|
|
|
void
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_new_obio_device(const char *name, const char *type)
|
2006-05-19 05:57:08 +08:00
|
|
|
{
|
2006-05-23 06:10:54 +08:00
|
|
|
push_str("/obio");
|
2006-05-19 05:57:08 +08:00
|
|
|
fword("find-device");
|
2006-05-23 06:10:54 +08:00
|
|
|
fword("new-device");
|
|
|
|
|
|
|
|
push_str(name);
|
|
|
|
fword("device-name");
|
|
|
|
|
|
|
|
if (type) {
|
|
|
|
push_str(type);
|
|
|
|
fword("device-type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned long
|
2007-12-10 01:04:51 +08:00
|
|
|
map_reg(uint64_t base, uint64_t offset, unsigned long size, int map,
|
|
|
|
int phys_hi)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
2007-12-10 01:04:51 +08:00
|
|
|
PUSH(phys_hi);
|
2006-05-23 06:10:54 +08:00
|
|
|
fword("encode-int");
|
|
|
|
PUSH(offset);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(size);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
push_str("reg");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
if (map) {
|
|
|
|
unsigned long addr;
|
|
|
|
|
|
|
|
addr = (unsigned long)map_io(base + offset, size);
|
|
|
|
|
|
|
|
PUSH(addr);
|
|
|
|
fword("encode-int");
|
|
|
|
PUSH(4);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
push_str("address");
|
|
|
|
fword("property");
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-01-13 01:46:19 +08:00
|
|
|
unsigned long
|
2007-12-10 01:04:51 +08:00
|
|
|
ob_reg(uint64_t base, uint64_t offset, unsigned long size, int map)
|
|
|
|
{
|
|
|
|
return map_reg(base, offset, size, map, 0);
|
|
|
|
}
|
|
|
|
|
2009-01-13 01:46:19 +08:00
|
|
|
void
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_intr(int intr)
|
|
|
|
{
|
|
|
|
PUSH(intr);
|
2006-05-19 05:57:08 +08:00
|
|
|
fword("encode-int");
|
2006-05-23 06:10:54 +08:00
|
|
|
PUSH(0);
|
2006-05-19 05:57:08 +08:00
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
2006-05-23 06:10:54 +08:00
|
|
|
push_str("intr");
|
2006-05-19 05:57:08 +08:00
|
|
|
fword("property");
|
2006-05-23 06:10:54 +08:00
|
|
|
}
|
|
|
|
|
2008-09-19 02:41:26 +08:00
|
|
|
static void
|
2007-12-10 01:04:51 +08:00
|
|
|
ob_eccmemctl_init(void)
|
|
|
|
{
|
|
|
|
uint32_t version, *regs;
|
|
|
|
const char *mc_type;
|
|
|
|
|
|
|
|
push_str("/");
|
|
|
|
fword("find-device");
|
|
|
|
fword("new-device");
|
|
|
|
|
|
|
|
push_str("eccmemctl");
|
|
|
|
fword("device-name");
|
|
|
|
|
|
|
|
PUSH(0x20);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("width");
|
|
|
|
fword("property");
|
|
|
|
|
2008-07-08 02:35:51 +08:00
|
|
|
regs = (uint32_t *)map_reg(ECC_BASE, 0, ECC_SIZE, 1, ECC_BASE >> 32);
|
2007-12-10 01:04:51 +08:00
|
|
|
|
|
|
|
version = regs[0];
|
|
|
|
switch (version) {
|
|
|
|
case 0x00000000:
|
|
|
|
mc_type = "MCC";
|
|
|
|
break;
|
|
|
|
case 0x10000000:
|
|
|
|
mc_type = "EMC";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case 0x20000000:
|
|
|
|
mc_type = "SMC";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
push_str(mc_type);
|
|
|
|
fword("encode-string");
|
|
|
|
push_str("mc-type");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
fword("finish-device");
|
|
|
|
}
|
|
|
|
|
2007-04-09 20:35:41 +08:00
|
|
|
static unsigned char *nvram;
|
2008-11-30 19:54:01 +08:00
|
|
|
static ohwcfg_v3_t nv_info;
|
2007-11-15 03:25:43 +08:00
|
|
|
|
|
|
|
#define NVRAM_OB_START (sizeof(ohwcfg_v3_t) + sizeof(struct sparc_arch_cfg))
|
|
|
|
#define NVRAM_OB_SIZE ((NVRAM_IDPROM - NVRAM_OB_START) & ~15)
|
2006-05-23 06:10:54 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
arch_nvram_get(char *data)
|
|
|
|
{
|
2007-11-15 03:25:43 +08:00
|
|
|
memcpy(data, &nvram[NVRAM_OB_START], NVRAM_OB_SIZE);
|
2006-05-23 06:10:54 +08:00
|
|
|
}
|
2006-05-19 05:57:08 +08:00
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
void
|
|
|
|
arch_nvram_put(char *data)
|
|
|
|
{
|
2007-11-15 03:25:43 +08:00
|
|
|
memcpy(&nvram[NVRAM_OB_START], data, NVRAM_OB_SIZE);
|
2006-05-23 06:10:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
arch_nvram_size(void)
|
|
|
|
{
|
2007-11-15 03:25:43 +08:00
|
|
|
return NVRAM_OB_SIZE;
|
2006-05-23 06:10:54 +08:00
|
|
|
}
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
static void mb86904_init(void)
|
|
|
|
{
|
|
|
|
PUSH(32);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("cache-line-size");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
PUSH(512);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("cache-nlines");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
PUSH(0x23);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("mask_rev");
|
|
|
|
fword("property");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void tms390z55_init(void)
|
|
|
|
{
|
|
|
|
push_str("");
|
|
|
|
fword("encode-string");
|
|
|
|
push_str("ecache-parity?");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
push_str("");
|
|
|
|
fword("encode-string");
|
|
|
|
push_str("bfill?");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
push_str("");
|
|
|
|
fword("encode-string");
|
|
|
|
push_str("bcopy?");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
push_str("");
|
|
|
|
fword("encode-string");
|
|
|
|
push_str("cache-physical?");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
PUSH(0xf);
|
|
|
|
fword("encode-int");
|
|
|
|
PUSH(0xf8fffffc);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(4);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
|
|
|
|
PUSH(0xf);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(0xf8c00000);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(0x1000);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
|
|
|
|
PUSH(0xf);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(0xf8000000);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(0x1000);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
|
|
|
|
PUSH(0xf);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(0xf8800000);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(0x1000);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
push_str("reg");
|
|
|
|
fword("property");
|
|
|
|
}
|
|
|
|
|
2007-04-30 03:55:08 +08:00
|
|
|
static void rt625_init(void)
|
|
|
|
{
|
|
|
|
PUSH(32);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("cache-line-size");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
PUSH(512);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("cache-nlines");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-11-10 04:40:09 +08:00
|
|
|
static void bad_cpu_init(void)
|
|
|
|
{
|
|
|
|
printk("This CPU is not supported yet, freezing.\n");
|
|
|
|
for(;;);
|
|
|
|
}
|
|
|
|
|
2007-04-09 20:35:41 +08:00
|
|
|
struct cpudef {
|
|
|
|
unsigned long iu_version;
|
2007-04-26 03:57:23 +08:00
|
|
|
const char *name;
|
|
|
|
int psr_impl, psr_vers, impl, vers;
|
|
|
|
int dcache_line_size, dcache_lines, dcache_assoc;
|
|
|
|
int icache_line_size, icache_lines, icache_assoc;
|
|
|
|
int ecache_line_size, ecache_lines, ecache_assoc;
|
|
|
|
int mmu_nctx;
|
|
|
|
void (*initfn)(void);
|
2007-04-09 20:35:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct cpudef sparc_defs[] = {
|
2007-11-10 04:40:09 +08:00
|
|
|
{
|
|
|
|
.iu_version = 0x00 << 24, /* Impl 0, ver 0 */
|
|
|
|
.name = "FMI,MB86900",
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
2007-04-09 20:35:41 +08:00
|
|
|
{
|
|
|
|
.iu_version = 0x04 << 24, /* Impl 0, ver 4 */
|
2007-04-26 03:57:23 +08:00
|
|
|
.name = "FMI,MB86904",
|
|
|
|
.psr_impl = 0,
|
|
|
|
.psr_vers = 5,
|
|
|
|
.impl = 0,
|
|
|
|
.vers = 5,
|
2007-04-30 03:55:08 +08:00
|
|
|
.dcache_line_size = 0x10,
|
|
|
|
.dcache_lines = 0x200,
|
|
|
|
.dcache_assoc = 1,
|
|
|
|
.icache_line_size = 0x20,
|
|
|
|
.icache_lines = 0x200,
|
|
|
|
.icache_assoc = 1,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x4000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x100,
|
|
|
|
.initfn = mb86904_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x05 << 24, /* Impl 0, ver 5 */
|
|
|
|
.name = "FMI,MB86907",
|
|
|
|
.psr_impl = 0,
|
|
|
|
.psr_vers = 5,
|
|
|
|
.impl = 0,
|
|
|
|
.vers = 5,
|
2007-04-26 03:57:23 +08:00
|
|
|
.dcache_line_size = 0x20,
|
|
|
|
.dcache_lines = 0x200,
|
|
|
|
.dcache_assoc = 1,
|
|
|
|
.icache_line_size = 0x20,
|
|
|
|
.icache_lines = 0x200,
|
|
|
|
.icache_assoc = 1,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x4000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x100,
|
|
|
|
.initfn = mb86904_init,
|
2007-04-09 20:35:41 +08:00
|
|
|
},
|
2007-11-10 04:40:09 +08:00
|
|
|
{
|
|
|
|
.iu_version = 0x10 << 24, /* Impl 1, ver 0 */
|
|
|
|
.name = "LSI,L64811",
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x11 << 24, /* Impl 1, ver 1 */
|
|
|
|
.name = "CY,CY7C601",
|
|
|
|
.psr_impl = 1,
|
|
|
|
.psr_vers = 1,
|
|
|
|
.impl = 1,
|
|
|
|
.vers = 1,
|
|
|
|
.mmu_nctx = 0x10,
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x13 << 24, /* Impl 1, ver 3 */
|
|
|
|
.name = "CY,CY7C611",
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x40000000,
|
|
|
|
.name = "TI,TMS390Z55",
|
|
|
|
.psr_impl = 4,
|
|
|
|
.psr_vers = 0,
|
|
|
|
.impl = 0,
|
|
|
|
.vers = 4,
|
|
|
|
.dcache_line_size = 0x20,
|
|
|
|
.dcache_lines = 0x80,
|
|
|
|
.dcache_assoc = 4,
|
|
|
|
.icache_line_size = 0x40,
|
|
|
|
.icache_lines = 0x40,
|
|
|
|
.icache_assoc = 5,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x8000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x10000,
|
|
|
|
.initfn = tms390z55_init,
|
|
|
|
},
|
2007-04-30 03:55:08 +08:00
|
|
|
{
|
|
|
|
.iu_version = 0x41000000,
|
|
|
|
.name = "TI,TMS390S10",
|
|
|
|
.psr_impl = 4,
|
|
|
|
.psr_vers = 1,
|
|
|
|
.impl = 4,
|
|
|
|
.vers = 1,
|
|
|
|
.dcache_line_size = 0x10,
|
|
|
|
.dcache_lines = 0x80,
|
|
|
|
.dcache_assoc = 4,
|
|
|
|
.icache_line_size = 0x20,
|
|
|
|
.icache_lines = 0x80,
|
|
|
|
.icache_assoc = 5,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x8000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x10000,
|
|
|
|
.initfn = tms390z55_init,
|
|
|
|
},
|
2007-04-09 20:35:41 +08:00
|
|
|
{
|
2007-11-10 04:40:09 +08:00
|
|
|
.iu_version = 0x42000000,
|
|
|
|
.name = "TI,TMS390S10",
|
2007-04-26 03:57:23 +08:00
|
|
|
.psr_impl = 4,
|
2007-11-10 04:40:09 +08:00
|
|
|
.psr_vers = 2,
|
|
|
|
.impl = 4,
|
|
|
|
.vers = 2,
|
|
|
|
.dcache_line_size = 0x10,
|
|
|
|
.dcache_lines = 0x80,
|
|
|
|
.dcache_assoc = 4,
|
|
|
|
.icache_line_size = 0x20,
|
|
|
|
.icache_lines = 0x80,
|
|
|
|
.icache_assoc = 5,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x8000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x10000,
|
|
|
|
.initfn = tms390z55_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x43000000,
|
|
|
|
.name = "TI,TMS390S10",
|
|
|
|
.psr_impl = 4,
|
|
|
|
.psr_vers = 3,
|
|
|
|
.impl = 4,
|
|
|
|
.vers = 3,
|
|
|
|
.dcache_line_size = 0x10,
|
|
|
|
.dcache_lines = 0x80,
|
|
|
|
.dcache_assoc = 4,
|
|
|
|
.icache_line_size = 0x20,
|
|
|
|
.icache_lines = 0x80,
|
|
|
|
.icache_assoc = 5,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x8000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x10000,
|
|
|
|
.initfn = tms390z55_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x44000000,
|
|
|
|
.name = "TI,TMS390S10",
|
|
|
|
.psr_impl = 4,
|
|
|
|
.psr_vers = 4,
|
|
|
|
.impl = 4,
|
2007-04-26 03:57:23 +08:00
|
|
|
.vers = 4,
|
2007-11-10 04:40:09 +08:00
|
|
|
.dcache_line_size = 0x10,
|
2007-04-26 03:57:23 +08:00
|
|
|
.dcache_lines = 0x80,
|
|
|
|
.dcache_assoc = 4,
|
2007-11-10 04:40:09 +08:00
|
|
|
.icache_line_size = 0x20,
|
|
|
|
.icache_lines = 0x80,
|
2007-04-26 03:57:23 +08:00
|
|
|
.icache_assoc = 5,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x8000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x10000,
|
|
|
|
.initfn = tms390z55_init,
|
2007-04-09 20:35:41 +08:00
|
|
|
},
|
2007-04-30 03:55:08 +08:00
|
|
|
{
|
|
|
|
.iu_version = 0x1e000000,
|
|
|
|
.name = "Ross,RT625",
|
|
|
|
.psr_impl = 1,
|
|
|
|
.psr_vers = 14,
|
|
|
|
.impl = 1,
|
|
|
|
.vers = 7,
|
|
|
|
.dcache_line_size = 0x20,
|
|
|
|
.dcache_lines = 0x80,
|
|
|
|
.dcache_assoc = 4,
|
|
|
|
.icache_line_size = 0x40,
|
|
|
|
.icache_lines = 0x40,
|
|
|
|
.icache_assoc = 5,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x8000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x10000,
|
|
|
|
.initfn = rt625_init,
|
|
|
|
},
|
2007-11-10 04:40:09 +08:00
|
|
|
{
|
|
|
|
.iu_version = 0x1f000000,
|
|
|
|
.name = "Ross,RT620",
|
|
|
|
.psr_impl = 1,
|
|
|
|
.psr_vers = 15,
|
|
|
|
.impl = 1,
|
|
|
|
.vers = 7,
|
|
|
|
.dcache_line_size = 0x20,
|
|
|
|
.dcache_lines = 0x80,
|
|
|
|
.dcache_assoc = 4,
|
|
|
|
.icache_line_size = 0x40,
|
|
|
|
.icache_lines = 0x40,
|
|
|
|
.icache_assoc = 5,
|
|
|
|
.ecache_line_size = 0x20,
|
|
|
|
.ecache_lines = 0x8000,
|
|
|
|
.ecache_assoc = 1,
|
|
|
|
.mmu_nctx = 0x10000,
|
|
|
|
.initfn = rt625_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x20000000,
|
|
|
|
.name = "BIT,B5010",
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x50000000,
|
|
|
|
.name = "MC,MN10501",
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0x90 << 24, /* Impl 9, ver 0 */
|
|
|
|
.name = "Weitek,W8601",
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0xf2000000,
|
|
|
|
.name = "GR,LEON2",
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.iu_version = 0xf3000000,
|
|
|
|
.name = "GR,LEON3",
|
|
|
|
.initfn = bad_cpu_init,
|
|
|
|
},
|
2007-04-09 20:35:41 +08:00
|
|
|
};
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
static const struct cpudef *
|
2007-04-09 20:35:41 +08:00
|
|
|
id_cpu(void)
|
|
|
|
{
|
|
|
|
unsigned long iu_version;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
asm("rd %%psr, %0\n"
|
|
|
|
: "=r"(iu_version) :);
|
|
|
|
iu_version &= 0xff000000;
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(sparc_defs)/sizeof(struct cpudef); i++) {
|
|
|
|
if (iu_version == sparc_defs[i].iu_version)
|
2007-04-26 03:57:23 +08:00
|
|
|
return &sparc_defs[i];
|
2007-04-09 20:35:41 +08:00
|
|
|
}
|
2007-04-26 03:57:23 +08:00
|
|
|
printk("Unknown cpu (psr %lx), freezing!\n", iu_version);
|
|
|
|
for (;;);
|
2007-04-09 20:35:41 +08:00
|
|
|
}
|
|
|
|
|
2008-09-19 02:41:26 +08:00
|
|
|
static void dummy_mach_init(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
struct machdef {
|
|
|
|
uint16_t machine_id;
|
|
|
|
const char *banner_name;
|
|
|
|
const char *model;
|
|
|
|
const char *name;
|
|
|
|
int mid_offset;
|
|
|
|
void (*initfn)(void);
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct machdef sun4m_defs[] = {
|
|
|
|
{
|
|
|
|
.machine_id = 32,
|
|
|
|
.banner_name = "SPARCstation 5",
|
|
|
|
.model = "SUNW,501-3059",
|
|
|
|
.name = "SUNW,SPARCstation-5",
|
|
|
|
.mid_offset = 0,
|
|
|
|
.initfn = dummy_mach_init,
|
|
|
|
},
|
2008-09-29 03:55:25 +08:00
|
|
|
{
|
|
|
|
.machine_id = 33,
|
|
|
|
.banner_name = "SPARCstation Voyager",
|
|
|
|
.model = "SUNW,501-2581",
|
|
|
|
.name = "SUNW,SPARCstation-Voyager",
|
|
|
|
.mid_offset = 0,
|
|
|
|
.initfn = dummy_mach_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.machine_id = 34,
|
|
|
|
.banner_name = "SPARCstation LX",
|
|
|
|
.model = "SUNW,501-2031",
|
|
|
|
.name = "SUNW,SPARCstation-LX",
|
|
|
|
.mid_offset = 0,
|
|
|
|
.initfn = dummy_mach_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.machine_id = 35,
|
|
|
|
.banner_name = "SPARCstation 4",
|
|
|
|
.model = "SUNW,501-2572",
|
|
|
|
.name = "SUNW,SPARCstation-4",
|
|
|
|
.mid_offset = 0,
|
|
|
|
.initfn = dummy_mach_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.machine_id = 36,
|
|
|
|
.banner_name = "SPARCstation Classic",
|
|
|
|
.model = "SUNW,501-2326",
|
|
|
|
.name = "SUNW,SPARCstation-Classic",
|
|
|
|
.mid_offset = 0,
|
|
|
|
.initfn = dummy_mach_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.machine_id = 37,
|
|
|
|
.banner_name = "Tadpole S3 GX",
|
|
|
|
.model = "S3",
|
|
|
|
.name = "Tadpole_S3GX",
|
|
|
|
.mid_offset = 0,
|
|
|
|
.initfn = dummy_mach_init,
|
|
|
|
},
|
2008-09-19 02:41:26 +08:00
|
|
|
{
|
|
|
|
.machine_id = 64,
|
|
|
|
.banner_name = "SPARCstation 10 (1 X 390Z55)",
|
|
|
|
.model = "SUNW,S10,501-2365",
|
|
|
|
.name = "SUNW,SPARCstation-10",
|
|
|
|
.mid_offset = 8,
|
|
|
|
.initfn = ob_eccmemctl_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.machine_id = 65,
|
|
|
|
.banner_name = "SPARCstation 20 (1 X 390Z55)",
|
|
|
|
.model = "SUNW,S20,501-2324",
|
|
|
|
.name = "SUNW,SPARCstation-20",
|
|
|
|
.mid_offset = 8,
|
|
|
|
.initfn = ob_eccmemctl_init,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.machine_id = 66,
|
|
|
|
.banner_name = "SPARCsystem 600(1 X 390Z55)",
|
|
|
|
.model = NULL,
|
|
|
|
.name = "SUNW,SPARCsystem-600",
|
|
|
|
.mid_offset = 8,
|
|
|
|
.initfn = ob_eccmemctl_init,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct machdef *
|
|
|
|
id_machine(uint16_t machine_id)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(sun4m_defs)/sizeof(struct machdef); i++) {
|
|
|
|
if (machine_id == sun4m_defs[i].machine_id)
|
|
|
|
return &sun4m_defs[i];
|
|
|
|
}
|
|
|
|
printk("Unknown machine (ID %d), freezing!\n", machine_id);
|
|
|
|
for (;;);
|
|
|
|
}
|
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
static volatile uint16_t *fw_cfg_cmd;
|
|
|
|
static volatile uint8_t *fw_cfg_data;
|
|
|
|
|
|
|
|
static void
|
|
|
|
fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
*fw_cfg_cmd = cmd;
|
|
|
|
for (i = 0; i < nbytes; i++)
|
|
|
|
buf[i] = *fw_cfg_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t
|
|
|
|
fw_cfg_read_i32(uint16_t cmd)
|
|
|
|
{
|
|
|
|
char buf[sizeof(uint32_t)];
|
|
|
|
|
|
|
|
fw_cfg_read(cmd, buf, sizeof(uint32_t));
|
|
|
|
|
|
|
|
return __le32_to_cpu(*(uint32_t *)buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint16_t
|
|
|
|
fw_cfg_read_i16(uint16_t cmd)
|
|
|
|
{
|
|
|
|
char buf[sizeof(uint16_t)];
|
|
|
|
|
|
|
|
fw_cfg_read(cmd, buf, sizeof(uint16_t));
|
|
|
|
|
|
|
|
return __le16_to_cpu(*(uint16_t *)buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t qemu_uuid[16];
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
static void
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_nvram_init(uint64_t base, uint64_t offset)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
2007-04-26 03:57:23 +08:00
|
|
|
const char *stdin, *stdout;
|
2006-06-07 06:23:04 +08:00
|
|
|
unsigned int i;
|
2006-07-23 22:29:29 +08:00
|
|
|
char nographic;
|
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 08:59:05 +08:00
|
|
|
uint32_t size;
|
2008-09-19 02:41:26 +08:00
|
|
|
uint16_t machine_id;
|
2008-07-08 02:35:51 +08:00
|
|
|
const struct cpudef *cpu;
|
2008-09-19 02:41:26 +08:00
|
|
|
const struct machdef *mach;
|
2007-11-15 03:25:43 +08:00
|
|
|
ohwcfg_v3_t *header;
|
2008-09-19 02:41:26 +08:00
|
|
|
char buf[256];
|
|
|
|
uint32_t temp;
|
2009-01-17 17:55:09 +08:00
|
|
|
phandle_t chosen;
|
2006-06-07 06:23:04 +08:00
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_new_obio_device("eeprom", NULL);
|
|
|
|
|
2008-11-30 03:31:28 +08:00
|
|
|
nvram = (unsigned char *)ob_reg(base, offset, NVRAM_SIZE, 1);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2006-06-07 17:19:11 +08:00
|
|
|
PUSH((unsigned long)nvram);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("address");
|
|
|
|
fword("property");
|
2008-07-08 02:35:51 +08:00
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
push_str("mk48t08");
|
|
|
|
fword("model");
|
|
|
|
|
|
|
|
fword("finish-device");
|
|
|
|
|
2008-09-19 02:41:26 +08:00
|
|
|
fw_cfg_cmd = map_io(CFG_ADDR, CFG_SIZE);
|
|
|
|
fw_cfg_data = (uint8_t *)fw_cfg_cmd + 2;
|
2007-04-09 20:35:41 +08:00
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
fw_cfg_read(FW_CFG_SIGNATURE, buf, 4);
|
2008-09-19 02:41:26 +08:00
|
|
|
buf[4] = '\0';
|
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
printk("Configuration device id %s", buf);
|
2008-09-19 02:41:26 +08:00
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
temp = fw_cfg_read_i32(FW_CFG_ID);
|
|
|
|
machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID);
|
2008-09-19 02:41:26 +08:00
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
printk(" version %d machine id %d\n", temp, machine_id);
|
2008-09-19 02:41:26 +08:00
|
|
|
|
2008-12-23 21:38:11 +08:00
|
|
|
if (temp != 1) {
|
|
|
|
printk("Incompatible configuration device version, freezing\n");
|
|
|
|
for(;;);
|
|
|
|
}
|
|
|
|
|
2008-09-19 02:41:26 +08:00
|
|
|
memcpy(&nv_info, nvram, sizeof(nv_info));
|
2006-05-23 06:10:54 +08:00
|
|
|
kernel_image = nv_info.kernel_image;
|
|
|
|
kernel_size = nv_info.kernel_size;
|
2007-04-07 17:37:28 +08:00
|
|
|
size = nv_info.cmdline_size;
|
2007-04-09 20:19:41 +08:00
|
|
|
if (size > OBIO_CMDLINE_MAX - 1)
|
|
|
|
size = OBIO_CMDLINE_MAX - 1;
|
2008-07-08 02:35:51 +08:00
|
|
|
memcpy(&obio_cmdline, (void *)(long)nv_info.cmdline, size);
|
2007-04-07 17:37:28 +08:00
|
|
|
obio_cmdline[size] = '\0';
|
2008-07-08 02:35:51 +08:00
|
|
|
qemu_cmdline = (uint32_t) &obio_cmdline;
|
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 08:59:05 +08:00
|
|
|
cmdline_size = size;
|
2007-11-15 03:25:43 +08:00
|
|
|
header = (ohwcfg_v3_t *)nvram;
|
|
|
|
header->kernel_image = 0;
|
|
|
|
header->kernel_size = 0;
|
|
|
|
header->cmdline_size = 0;
|
2007-11-18 02:56:43 +08:00
|
|
|
header->crc = OHW_compute_crc(header, 0x00, 0xF8);
|
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 08:59:05 +08:00
|
|
|
|
2007-11-15 03:25:43 +08:00
|
|
|
boot_device = nv_info.boot_devices[0];
|
2008-12-23 21:14:33 +08:00
|
|
|
fw_cfg_read(FW_CFG_NOGRAPHIC, &nographic, 1);
|
|
|
|
graphic_depth = fw_cfg_read_i16(FW_CFG_SUN4M_DEPTH);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
// Add /uuid
|
|
|
|
fw_cfg_read(FW_CFG_UUID, (char *)qemu_uuid, 16);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2008-12-23 21:14:33 +08:00
|
|
|
printk("UUID: " UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], qemu_uuid[2],
|
|
|
|
qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], qemu_uuid[6],
|
|
|
|
qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], qemu_uuid[10],
|
|
|
|
qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], qemu_uuid[14],
|
|
|
|
qemu_uuid[15]);
|
|
|
|
|
|
|
|
push_str("/");
|
|
|
|
fword("find-device");
|
|
|
|
|
|
|
|
PUSH((long)&qemu_uuid);
|
|
|
|
PUSH(16);
|
|
|
|
fword("encode-bytes");
|
|
|
|
push_str("uuid");
|
|
|
|
fword("property");
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2006-06-07 06:23:04 +08:00
|
|
|
// Add /idprom
|
2006-05-23 06:10:54 +08:00
|
|
|
push_str("/");
|
2006-05-19 05:57:08 +08:00
|
|
|
fword("find-device");
|
2008-07-08 02:35:51 +08:00
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
PUSH((long)&nvram[NVRAM_IDPROM]);
|
|
|
|
PUSH(32);
|
|
|
|
fword("encode-bytes");
|
|
|
|
push_str("idprom");
|
|
|
|
fword("property");
|
2006-06-07 06:23:04 +08:00
|
|
|
|
2008-09-19 02:41:26 +08:00
|
|
|
mach = id_machine(machine_id);
|
|
|
|
|
|
|
|
mach->initfn();
|
|
|
|
|
|
|
|
push_str(mach->banner_name);
|
|
|
|
fword("encode-string");
|
|
|
|
push_str("banner-name");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
if (mach->model) {
|
|
|
|
push_str(mach->model);
|
2007-04-15 13:46:25 +08:00
|
|
|
fword("encode-string");
|
2007-04-09 20:35:41 +08:00
|
|
|
push_str("model");
|
|
|
|
fword("property");
|
|
|
|
}
|
2008-09-19 02:41:26 +08:00
|
|
|
push_str(mach->name);
|
|
|
|
fword("encode-string");
|
|
|
|
push_str("name");
|
|
|
|
fword("property");
|
|
|
|
|
2006-06-07 06:23:04 +08:00
|
|
|
// Add cpus
|
2008-12-23 21:14:33 +08:00
|
|
|
temp = fw_cfg_read_i32(FW_CFG_NB_CPUS);
|
2008-09-19 02:41:26 +08:00
|
|
|
|
|
|
|
printk("CPUs: %x", temp);
|
2007-11-10 04:40:09 +08:00
|
|
|
cpu = id_cpu();
|
|
|
|
printk(" x %s\n", cpu->name);
|
2008-09-19 02:41:26 +08:00
|
|
|
for (i = 0; i < temp; i++) {
|
2006-06-07 06:23:04 +08:00
|
|
|
push_str("/");
|
|
|
|
fword("find-device");
|
|
|
|
|
|
|
|
fword("new-device");
|
2007-04-09 20:35:41 +08:00
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
push_str(cpu->name);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("device-name");
|
|
|
|
|
|
|
|
push_str("cpu");
|
|
|
|
fword("device-type");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->psr_impl);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
2007-04-26 03:57:23 +08:00
|
|
|
push_str("psr-implementation");
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->psr_vers);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
2007-04-26 03:57:23 +08:00
|
|
|
push_str("psr-version");
|
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 08:59:05 +08:00
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->impl);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
2007-04-26 03:57:23 +08:00
|
|
|
push_str("implementation");
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->vers);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
2007-04-26 03:57:23 +08:00
|
|
|
push_str("version");
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("property");
|
|
|
|
|
|
|
|
PUSH(4096);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("page-size");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->dcache_line_size);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("dcache-line-size");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->dcache_lines);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("dcache-nlines");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->dcache_assoc);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("dcache-associativity");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->icache_line_size);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("icache-line-size");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->icache_lines);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("icache-nlines");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->icache_assoc);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("icache-associativity");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->ecache_line_size);
|
2006-06-07 17:19:11 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("ecache-line-size");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->ecache_lines);
|
2006-06-07 17:19:11 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("ecache-nlines");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->ecache_assoc);
|
2006-06-07 17:19:11 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("ecache-associativity");
|
|
|
|
fword("property");
|
2008-07-08 02:35:51 +08:00
|
|
|
|
2006-06-07 06:23:04 +08:00
|
|
|
PUSH(2);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("ncaches");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
PUSH(cpu->mmu_nctx);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("mmu-nctx");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
PUSH(8);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("sparc-version");
|
|
|
|
fword("property");
|
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
push_str("");
|
|
|
|
fword("encode-string");
|
|
|
|
push_str("cache-coherence?");
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("property");
|
|
|
|
|
2008-09-19 02:41:26 +08:00
|
|
|
PUSH(i + mach->mid_offset);
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("encode-int");
|
|
|
|
push_str("mid");
|
|
|
|
fword("property");
|
2008-07-08 02:35:51 +08:00
|
|
|
|
2007-04-26 03:57:23 +08:00
|
|
|
cpu->initfn();
|
|
|
|
|
2006-06-07 06:23:04 +08:00
|
|
|
fword("finish-device");
|
|
|
|
}
|
2006-07-23 22:29:29 +08:00
|
|
|
|
|
|
|
if (nographic) {
|
|
|
|
obp_stdin = PROMDEV_TTYA;
|
|
|
|
obp_stdout = PROMDEV_TTYA;
|
2009-01-17 18:15:13 +08:00
|
|
|
stdin = "ttya";
|
|
|
|
stdout = "ttya";
|
2006-07-23 22:29:29 +08:00
|
|
|
} else {
|
|
|
|
obp_stdin = PROMDEV_KBD;
|
|
|
|
obp_stdout = PROMDEV_SCREEN;
|
2009-01-17 18:15:13 +08:00
|
|
|
stdin = "keyboard";
|
|
|
|
stdout = "screen";
|
2006-07-23 22:29:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
push_str("/");
|
|
|
|
fword("find-device");
|
2009-01-17 17:55:09 +08:00
|
|
|
|
2006-07-23 22:29:29 +08:00
|
|
|
push_str(stdin);
|
2009-01-17 18:15:13 +08:00
|
|
|
fword("pathres-resolve-aliases");
|
2006-07-23 22:29:29 +08:00
|
|
|
fword("encode-string");
|
|
|
|
push_str("stdin-path");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
push_str(stdout);
|
2009-01-17 18:15:13 +08:00
|
|
|
fword("pathres-resolve-aliases");
|
2006-07-23 22:29:29 +08:00
|
|
|
fword("encode-string");
|
|
|
|
push_str("stdout-path");
|
|
|
|
fword("property");
|
|
|
|
|
2009-01-17 17:55:09 +08:00
|
|
|
chosen = find_dev("/chosen");
|
|
|
|
push_str(stdin);
|
|
|
|
fword("open-dev");
|
|
|
|
set_int_property(chosen, "stdin", POP());
|
|
|
|
|
|
|
|
chosen = find_dev("/chosen");
|
|
|
|
push_str(stdout);
|
|
|
|
fword("open-dev");
|
|
|
|
set_int_property(chosen, "stdout", POP());
|
|
|
|
|
|
|
|
push_str(stdin);
|
|
|
|
push_str("input-device");
|
|
|
|
fword("$setenv");
|
|
|
|
|
|
|
|
push_str(stdout);
|
|
|
|
push_str("output-device");
|
|
|
|
fword("$setenv");
|
|
|
|
|
|
|
|
push_str(stdin);
|
|
|
|
fword("input");
|
|
|
|
|
2006-07-23 22:29:29 +08:00
|
|
|
obp_stdin_path = stdin;
|
|
|
|
obp_stdout_path = stdout;
|
2006-05-23 06:10:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_fd_init(uint64_t base, uint64_t offset, int intr)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
|
|
|
ob_new_obio_device("SUNW,fdtwo", "block");
|
|
|
|
|
|
|
|
ob_reg(base, offset, FD_REGS, 0);
|
|
|
|
|
|
|
|
ob_intr(intr);
|
|
|
|
|
|
|
|
fword("finish-device");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_sconfig_init(uint64_t base, uint64_t offset)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
|
|
|
ob_new_obio_device("slavioconfig", NULL);
|
|
|
|
|
|
|
|
ob_reg(base, offset, SCONFIG_REGS, 0);
|
|
|
|
|
|
|
|
fword("finish-device");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_auxio_init(uint64_t base, uint64_t offset)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
|
|
|
ob_new_obio_device("auxio", NULL);
|
|
|
|
|
|
|
|
ob_reg(base, offset, AUXIO_REGS, 0);
|
|
|
|
|
|
|
|
fword("finish-device");
|
|
|
|
}
|
|
|
|
|
2008-07-06 00:57:17 +08:00
|
|
|
volatile unsigned char *power_reg;
|
|
|
|
volatile unsigned int *reset_reg;
|
2007-07-20 19:23:30 +08:00
|
|
|
|
|
|
|
static void
|
|
|
|
sparc32_reset_all(void)
|
|
|
|
{
|
|
|
|
*reset_reg = 1;
|
|
|
|
}
|
2007-05-28 03:49:35 +08:00
|
|
|
|
2008-02-02 03:58:56 +08:00
|
|
|
// AUX 2 (Software Powerdown Control) and reset
|
2006-05-23 06:10:54 +08:00
|
|
|
static void
|
2008-02-02 03:58:56 +08:00
|
|
|
ob_aux2_reset_init(uint64_t base, uint64_t offset, int intr)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
|
|
|
ob_new_obio_device("power", NULL);
|
|
|
|
|
2008-07-08 02:35:51 +08:00
|
|
|
power_reg = (void *)ob_reg(base, offset, AUXIO2_REGS, 1);
|
2007-05-28 03:49:35 +08:00
|
|
|
|
|
|
|
// Not in device tree
|
|
|
|
reset_reg = map_io(base + (uint64_t)SLAVIO_RESET, RESET_REGS);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2007-07-20 19:23:30 +08:00
|
|
|
bind_func("sparc32-reset-all", sparc32_reset_all);
|
|
|
|
push_str("' sparc32-reset-all to reset-all");
|
|
|
|
fword("eval");
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_intr(intr);
|
|
|
|
|
|
|
|
fword("finish-device");
|
|
|
|
}
|
|
|
|
|
2007-12-25 16:26:21 +08:00
|
|
|
volatile struct sun4m_timer_regs *counter_regs;
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
static void
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_counter_init(uint64_t base, unsigned long offset)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
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 08:59:05 +08:00
|
|
|
int i;
|
2006-05-23 06:10:54 +08:00
|
|
|
|
|
|
|
ob_new_obio_device("counter", NULL);
|
|
|
|
|
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 08:59:05 +08:00
|
|
|
for (i = 0; i < SUN4M_NCPU; i++) {
|
|
|
|
PUSH(0);
|
|
|
|
fword("encode-int");
|
|
|
|
if (i != 0) fword("encode+");
|
|
|
|
PUSH(offset + (i * PAGE_SIZE));
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(COUNTER_REGS);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
}
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
PUSH(0);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(offset + 0x10000);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(COUNTER_REGS);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
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 08:59:05 +08:00
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
push_str("reg");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
|
2007-12-25 16:26:21 +08:00
|
|
|
counter_regs = map_io(base + (uint64_t)offset, sizeof(*counter_regs));
|
|
|
|
counter_regs->cfg = 0xffffffff;
|
|
|
|
counter_regs->l10_timer_limit = (((1000000/100) + 1) << 10);
|
|
|
|
counter_regs->cpu_timers[0].l14_timer_limit = 0;
|
|
|
|
counter_regs->cpu_timers[0].cntrl = 1;
|
2006-06-07 16:49:15 +08:00
|
|
|
|
2007-05-18 03:16:06 +08:00
|
|
|
for (i = 0; i < SUN4M_NCPU; i++) {
|
2007-12-25 16:26:21 +08:00
|
|
|
PUSH((unsigned long)&counter_regs->cpu_timers[i]);
|
2007-05-18 03:16:06 +08:00
|
|
|
fword("encode-int");
|
|
|
|
if (i != 0)
|
|
|
|
fword("encode+");
|
|
|
|
}
|
2007-12-25 16:26:21 +08:00
|
|
|
PUSH((unsigned long)&counter_regs->l10_timer_limit);
|
2006-06-07 16:49:15 +08:00
|
|
|
fword("encode-int");
|
2007-05-18 03:16:06 +08:00
|
|
|
fword("encode+");
|
2006-06-07 16:49:15 +08:00
|
|
|
push_str("address");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
fword("finish-device");
|
2006-05-23 06:10:54 +08:00
|
|
|
}
|
|
|
|
|
2006-06-07 06:23:04 +08:00
|
|
|
static volatile struct sun4m_intregs *intregs;
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
static void
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_interrupt_init(uint64_t base, unsigned long offset)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
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 08:59:05 +08:00
|
|
|
int i;
|
2006-05-23 06:10:54 +08:00
|
|
|
|
|
|
|
ob_new_obio_device("interrupt", NULL);
|
|
|
|
|
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 08:59:05 +08:00
|
|
|
for (i = 0; i < SUN4M_NCPU; i++) {
|
|
|
|
PUSH(0);
|
|
|
|
fword("encode-int");
|
|
|
|
if (i != 0) fword("encode+");
|
|
|
|
PUSH(offset + (i * PAGE_SIZE));
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(INTERRUPT_REGS);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
}
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
PUSH(0);
|
2006-05-19 05:57:08 +08:00
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
2006-05-23 06:10:54 +08:00
|
|
|
PUSH(offset + 0x10000);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(INTERRUPT_REGS);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
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 08:59:05 +08:00
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
push_str("reg");
|
2006-05-19 05:57:08 +08:00
|
|
|
fword("property");
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2007-05-19 20:55:01 +08:00
|
|
|
intregs = map_io(base | (uint64_t)offset, sizeof(*intregs));
|
2007-08-06 02:01:20 +08:00
|
|
|
intregs->clear = ~SUN4M_INT_MASKALL;
|
2006-06-07 06:23:04 +08:00
|
|
|
intregs->cpu_intregs[0].clear = ~0x17fff;
|
|
|
|
|
2007-05-18 03:16:06 +08:00
|
|
|
for (i = 0; i < SUN4M_NCPU; i++) {
|
|
|
|
PUSH((unsigned long)&intregs->cpu_intregs[i]);
|
|
|
|
fword("encode-int");
|
|
|
|
if (i != 0)
|
|
|
|
fword("encode+");
|
|
|
|
}
|
|
|
|
PUSH((unsigned long)&intregs->tbt);
|
2006-06-06 04:02:44 +08:00
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
push_str("address");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
fword("finish-device");
|
2006-06-07 06:23:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
start_cpu(unsigned int pc, unsigned int context_ptr, unsigned int context, int cpu)
|
|
|
|
{
|
2007-11-15 03:25:43 +08:00
|
|
|
ohwcfg_v3_t *header = (ohwcfg_v3_t *)nvram;
|
|
|
|
struct sparc_arch_cfg *sparc_header;
|
|
|
|
|
2006-06-07 06:23:04 +08:00
|
|
|
if (!cpu)
|
|
|
|
return -1;
|
|
|
|
|
2008-07-08 02:35:51 +08:00
|
|
|
sparc_header = (struct sparc_arch_cfg *)&nvram[header->nvram_arch_ptr];
|
2007-11-15 03:25:43 +08:00
|
|
|
sparc_header->smp_entry = pc;
|
|
|
|
sparc_header->smp_ctxtbl = context_ptr;
|
|
|
|
sparc_header->smp_ctx = context;
|
|
|
|
sparc_header->valid = 1;
|
2006-06-06 04:02:44 +08:00
|
|
|
|
2007-11-20 03:11:38 +08:00
|
|
|
cpu &= 7;
|
2006-06-07 06:23:04 +08:00
|
|
|
intregs->cpu_intregs[cpu].set = SUN4M_SOFT_INT(14);
|
|
|
|
|
|
|
|
return 0;
|
2006-05-19 05:57:08 +08:00
|
|
|
}
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2006-05-19 05:57:08 +08:00
|
|
|
static void
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_obio_open(__attribute__((unused))int *idx)
|
2006-05-19 05:57:08 +08:00
|
|
|
{
|
|
|
|
int ret=1;
|
|
|
|
RET ( -ret );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_obio_close(__attribute__((unused))int *idx)
|
2006-05-19 05:57:08 +08:00
|
|
|
{
|
|
|
|
selfword("close-deblocker");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_obio_initialize(__attribute__((unused))int *idx)
|
2006-05-19 05:57:08 +08:00
|
|
|
{
|
2006-05-23 06:10:54 +08:00
|
|
|
push_str("/");
|
|
|
|
fword("find-device");
|
|
|
|
fword("new-device");
|
|
|
|
|
|
|
|
push_str("obio");
|
|
|
|
fword("device-name");
|
|
|
|
|
|
|
|
push_str("hierarchical");
|
|
|
|
fword("device-type");
|
|
|
|
|
|
|
|
PUSH(2);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("#address-cells");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
PUSH(1);
|
|
|
|
fword("encode-int");
|
|
|
|
push_str("#size-cells");
|
|
|
|
fword("property");
|
|
|
|
|
|
|
|
fword("finish-device");
|
2006-05-19 05:57:08 +08:00
|
|
|
}
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
static void
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_set_obio_ranges(uint64_t base)
|
2006-05-23 06:10:54 +08:00
|
|
|
{
|
|
|
|
push_str("/obio");
|
|
|
|
fword("find-device");
|
|
|
|
PUSH(0);
|
|
|
|
fword("encode-int");
|
|
|
|
PUSH(0);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
2007-05-19 20:55:01 +08:00
|
|
|
PUSH(base >> 32);
|
2006-05-23 06:10:54 +08:00
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
2007-05-19 20:55:01 +08:00
|
|
|
PUSH(base & 0xffffffff);
|
2006-05-23 06:10:54 +08:00
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
PUSH(SLAVIO_SIZE);
|
|
|
|
fword("encode-int");
|
|
|
|
fword("encode+");
|
|
|
|
push_str("ranges");
|
|
|
|
fword("property");
|
|
|
|
}
|
2006-05-19 05:57:08 +08:00
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
static void
|
|
|
|
ob_obio_decodeunit(__attribute__((unused)) int *idx)
|
|
|
|
{
|
|
|
|
fword("decode-unit-sbus");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
ob_obio_encodeunit(__attribute__((unused)) int *idx)
|
|
|
|
{
|
|
|
|
fword("encode-unit-sbus");
|
|
|
|
}
|
|
|
|
|
|
|
|
NODE_METHODS(ob_obio) = {
|
2006-05-19 05:57:08 +08:00
|
|
|
{ NULL, ob_obio_initialize },
|
|
|
|
{ "open", ob_obio_open },
|
|
|
|
{ "close", ob_obio_close },
|
2006-05-23 06:10:54 +08:00
|
|
|
{ "encode-unit", ob_obio_encodeunit },
|
|
|
|
{ "decode-unit", ob_obio_decodeunit },
|
2006-05-19 05:57:08 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-05-23 06:10:54 +08:00
|
|
|
int
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_obio_init(uint64_t slavio_base, unsigned long fd_offset,
|
2008-02-02 03:58:56 +08:00
|
|
|
unsigned long counter_offset, unsigned long intr_offset,
|
|
|
|
unsigned long aux1_offset, unsigned long aux2_offset)
|
2006-05-19 05:57:08 +08:00
|
|
|
{
|
|
|
|
|
2006-06-10 09:27:11 +08:00
|
|
|
// All devices were integrated to NCR89C105, see
|
|
|
|
// http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
|
|
|
|
|
2006-05-19 05:57:08 +08:00
|
|
|
//printk("Initializing OBIO devices...\n");
|
2006-05-23 06:10:54 +08:00
|
|
|
#if 0 // XXX
|
|
|
|
REGISTER_NAMED_NODE(ob_obio, "/obio");
|
|
|
|
device_end();
|
|
|
|
#endif
|
2007-05-19 20:55:01 +08:00
|
|
|
ob_set_obio_ranges(slavio_base);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2006-06-10 09:27:11 +08:00
|
|
|
// Zilog Z8530 serial ports, see http://www.zilog.com
|
2006-05-29 02:48:47 +08:00
|
|
|
// Must be before zs@0,0 or Linux won't boot
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_zs_init(slavio_base, SLAVIO_ZS1, ZS_INTR, 0, 0);
|
|
|
|
|
2006-05-29 02:48:47 +08:00
|
|
|
ob_zs_init(slavio_base, SLAVIO_ZS, ZS_INTR, 1, 1);
|
|
|
|
|
2006-06-10 09:27:11 +08:00
|
|
|
// M48T08 NVRAM, see http://www.st.com
|
2006-05-23 06:10:54 +08:00
|
|
|
ob_nvram_init(slavio_base, SLAVIO_NVRAM);
|
|
|
|
|
2006-06-10 09:27:11 +08:00
|
|
|
// 82078 FDC
|
2007-11-12 02:02:11 +08:00
|
|
|
if (fd_offset != (unsigned long) -1)
|
|
|
|
ob_fd_init(slavio_base, fd_offset, FD_INTR);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
|
|
|
ob_sconfig_init(slavio_base, SLAVIO_SCONFIG);
|
|
|
|
|
2008-02-02 03:58:56 +08:00
|
|
|
ob_auxio_init(slavio_base, aux1_offset);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2008-02-02 03:58:56 +08:00
|
|
|
if (aux2_offset != (unsigned long) -1)
|
|
|
|
ob_aux2_reset_init(slavio_base, aux2_offset, AUXIO2_INTR);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2007-04-09 20:35:41 +08:00
|
|
|
ob_counter_init(slavio_base, counter_offset);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2007-04-09 20:35:41 +08:00
|
|
|
ob_interrupt_init(slavio_base, intr_offset);
|
2006-05-23 06:10:54 +08:00
|
|
|
|
2006-05-19 05:57:08 +08:00
|
|
|
return 0;
|
|
|
|
}
|