summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios
diff options
context:
space:
mode:
authorDon Dugger <n0ano@n0ano.com>2016-06-03 03:33:22 +0000
committerGerrit Code Review <gerrit@172.30.200.206>2016-06-03 03:33:23 +0000
commitda27230f80795d0028333713f036d44c53cb0e68 (patch)
treeb3d379eaf000adf72b36cb01cdf4d79c3e3f064c /qemu/roms/openbios
parent0e68cb048bb8aadb14675f5d4286d8ab2fc35449 (diff)
parent437fd90c0250dee670290f9b714253671a990160 (diff)
Merge "These changes are the raw update to qemu-2.6."
Diffstat (limited to 'qemu/roms/openbios')
-rw-r--r--qemu/roms/openbios/Makefile.target2
-rw-r--r--qemu/roms/openbios/arch/ppc/qemu/init.c67
-rw-r--r--qemu/roms/openbios/arch/ppc/qemu/methods.c36
-rw-r--r--qemu/roms/openbios/arch/ppc/qemu/qemu.fs45
-rw-r--r--qemu/roms/openbios/arch/ppc/qemu/tree.fs8
-rw-r--r--qemu/roms/openbios/arch/sparc64/call-client.S218
-rw-r--r--qemu/roms/openbios/arch/sparc64/context.c4
-rw-r--r--qemu/roms/openbios/arch/sparc64/cpustate.h244
-rw-r--r--qemu/roms/openbios/arch/sparc64/ldscript5
-rw-r--r--qemu/roms/openbios/arch/sparc64/lib.c4
-rw-r--r--qemu/roms/openbios/arch/sparc64/vectors.S300
-rwxr-xr-xqemu/roms/openbios/config/scripts/switch-arch118
-rw-r--r--qemu/roms/openbios/drivers/cuda.c21
-rw-r--r--qemu/roms/openbios/drivers/escc.c112
-rw-r--r--qemu/roms/openbios/drivers/escc.h2
-rw-r--r--qemu/roms/openbios/drivers/ide.c82
-rw-r--r--qemu/roms/openbios/drivers/ide.h2
-rw-r--r--qemu/roms/openbios/drivers/obio.c66
-rw-r--r--qemu/roms/openbios/drivers/pci.c147
-rw-r--r--qemu/roms/openbios/drivers/pci.fs68
-rw-r--r--qemu/roms/openbios/drivers/pci.h9
-rw-r--r--qemu/roms/openbios/drivers/sbus.c25
-rw-r--r--qemu/roms/openbios/drivers/usbohci_private.h28
-rw-r--r--qemu/roms/openbios/drivers/vga.fs11
-rw-r--r--qemu/roms/openbios/forth/lib/string.fs14
-rw-r--r--qemu/roms/openbios/forth/system/ciface.fs8
-rw-r--r--qemu/roms/openbios/include/arch/ppc/types.h8
-rw-r--r--qemu/roms/openbios/include/arch/sparc64/io.h2
-rw-r--r--qemu/roms/openbios/include/drivers/drivers.h1
-rw-r--r--qemu/roms/openbios/include/libopenbios/bindings.h1
-rw-r--r--qemu/roms/openbios/libopenbios/bindings.c8
-rw-r--r--qemu/roms/openbios/libopenbios/bootinfo_load.c6
32 files changed, 903 insertions, 769 deletions
diff --git a/qemu/roms/openbios/Makefile.target b/qemu/roms/openbios/Makefile.target
index a7363e667..4c54105a7 100644
--- a/qemu/roms/openbios/Makefile.target
+++ b/qemu/roms/openbios/Makefile.target
@@ -15,7 +15,7 @@ HOSTCFLAGS+= -Wstrict-aliasing -Wwrite-strings -Wmissing-prototypes -Wnested-ext
HOSTCFLAGS+= -W
# Flags for dependency generation
HOSTCFLAGS+= -MMD -MP -MT $@ -MF '$(*D)/$(*F).d'
-HOSTINCLUDES := -I$(SRCDIR)/include -I$(SRCDIR)/kernel -I$(SRCDIR)/kernel/include -I$(ODIR)/target/include
+HOSTINCLUDES := -I$(SRCDIR)/include -I$(SRCDIR)/kernel -I$(SRCDIR)/kernel/include -iquote $(ODIR)/target/include
CC := $(TARGET)gcc
AS := $(TARGET)as
diff --git a/qemu/roms/openbios/arch/ppc/qemu/init.c b/qemu/roms/openbios/arch/ppc/qemu/init.c
index 4fe8b7220..b76c5706f 100644
--- a/qemu/roms/openbios/arch/ppc/qemu/init.c
+++ b/qemu/roms/openbios/arch/ppc/qemu/init.c
@@ -302,6 +302,11 @@ cpu_generic_init(const struct cpudef *cpu)
fword("encode-string");
push_str("state");
fword("property");
+
+ PUSH(0x20);
+ fword("encode-int");
+ push_str("reservation-granule-size");
+ fword("property");
}
static void
@@ -596,6 +601,11 @@ go(void)
{
ucell addr;
+ /* Insert copyright property for MacOS 9 and below */
+ if (find_dev("/rom/macos")) {
+ fword("insert-copyright-property");
+ }
+
feval("saved-program-state >sps.entry @");
addr = POP();
@@ -680,6 +690,60 @@ static void ffilll(void)
}
}
+/*
+ * adler32 ( adler buf len -- checksum )
+ *
+ * Adapted from Mark Adler's original implementation (zlib license)
+ *
+ * Both OS 9 and BootX require this word for payload validation.
+ */
+
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+static void adler32(void)
+{
+ uint32_t len = (uint32_t)POP();
+ char *buf = (char *)POP();
+ uint32_t adler = (uint32_t)POP();
+
+ if (buf == NULL) {
+ RET(-1);
+ }
+
+ uint32_t base = 65521;
+ uint32_t nmax = 5552;
+
+ uint32_t s1 = adler & 0xffff;
+ uint32_t s2 = (adler >> 16) & 0xffff;
+
+ uint32_t k;
+ while (len > 0) {
+ k = (len < nmax ? len : nmax);
+ len -= k;
+
+ while (k >= 16) {
+ DO16(buf);
+ buf += 16;
+ k -= 16;
+ }
+ if (k != 0) {
+ do {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k);
+ }
+
+ s1 %= base;
+ s2 %= base;
+ }
+
+ RET(s2 << 16 | s1);
+}
+
void
arch_of_init(void)
{
@@ -945,6 +1009,9 @@ arch_of_init(void)
/* Implementation of filll word (required by BootX) */
bind_func("filll", ffilll);
+
+ /* Implementation of adler32 word (required by OS 9, BootX) */
+ bind_func("(adler32)", adler32);
bind_func("platform-boot", boot);
bind_func("(go)", go);
diff --git a/qemu/roms/openbios/arch/ppc/qemu/methods.c b/qemu/roms/openbios/arch/ppc/qemu/methods.c
index fd993daa9..930b47c4e 100644
--- a/qemu/roms/openbios/arch/ppc/qemu/methods.c
+++ b/qemu/roms/openbios/arch/ppc/qemu/methods.c
@@ -114,6 +114,8 @@ static void
ciface_quiesce( unsigned long args[], unsigned long ret[] )
{
usb_exit();
+
+ ob_ide_quiesce();
#if 0
unsigned long msr;
/* This seems to be the correct thing to do - but I'm not sure */
@@ -164,21 +166,21 @@ DECLARE_UNNAMED_NODE( mmu, INSTALL_OPEN, 0 );
DECLARE_NODE( mmu_ciface, 0, 0, "+/openprom/client-services" );
-/* ( phys size align --- base ) */
+/* ( [phys] size align --- base ) */
static void
mem_claim( void )
{
ucell align = POP();
ucell size = POP();
- ucell phys = POP();
- ucell ret = ofmem_claim_phys( phys, size, align );
+ phys_addr_t phys = -1;
- if( ret == -1 ) {
- printk("MEM: claim failure\n");
- throw( -13 );
- return;
+ if (!align) {
+ phys = POP();
}
- PUSH( ret );
+
+ phys = ofmem_claim_phys(phys, size, align);
+
+ PUSH(phys);
}
/* ( phys size --- ) */
@@ -188,24 +190,24 @@ mem_release( void )
POP(); POP();
}
-/* ( phys size align --- base ) */
+/* ( [virt] size align --- base ) */
static void
mmu_claim( void )
{
ucell align = POP();
ucell size = POP();
- ucell phys = POP();
- ucell ret = ofmem_claim_virt( phys, size, align );
+ ucell virt = -1;
- if( ret == -1 ) {
- printk("MMU: CLAIM failure\n");
- throw( -13 );
- return;
+ if (!align) {
+ virt = POP();
}
- PUSH( ret );
+
+ virt = ofmem_claim_virt(virt, size, align);
+
+ PUSH(virt);
}
-/* ( phys size --- ) */
+/* ( virt size --- ) */
static void
mmu_release( void )
{
diff --git a/qemu/roms/openbios/arch/ppc/qemu/qemu.fs b/qemu/roms/openbios/arch/ppc/qemu/qemu.fs
index 458af1bc7..3d99a34a1 100644
--- a/qemu/roms/openbios/arch/ppc/qemu/qemu.fs
+++ b/qemu/roms/openbios/arch/ppc/qemu/qemu.fs
@@ -93,3 +93,48 @@ variable keyboard-phandle 0 keyboard-phandle !
:noname
set-defaults
; PREPOST-initializer
+
+\ -------------------------------------------------------------------------
+\ copyright property handling
+\ -------------------------------------------------------------------------
+
+: insert-copyright-property
+ \ As required for MacOS 9 and below
+ " Pbclevtug 1983-2001 Nccyr Pbzchgre, Vap. GUVF ZRFFNTR SBE PBZCNGVOVYVGL BAYL"
+ rot13-str encode-string " copyright"
+ " /" find-package if
+ " set-property" $find if
+ execute
+ else
+ 3drop drop
+ then
+ then
+;
+
+: delete-copyright-property
+ \ Remove copyright property created above
+ active-package
+ " /" find-package if
+ active-package!
+ " copyright" delete-property
+ then
+ active-package!
+;
+
+: (exit)
+ \ Clean up before returning to the interpreter
+ delete-copyright-property
+;
+
+\ -------------------------------------------------------------------------
+\ Adler-32 wrapper
+\ -------------------------------------------------------------------------
+
+: adler32 ( adler buf len -- checksum )
+ " (adler32)" $find if
+ execute
+ else
+ ." Can't find " ( adler32-name ) type cr
+ 3drop 0
+ then
+;
diff --git a/qemu/roms/openbios/arch/ppc/qemu/tree.fs b/qemu/roms/openbios/arch/ppc/qemu/tree.fs
index 1ed838397..5b6bbc6f7 100644
--- a/qemu/roms/openbios/arch/ppc/qemu/tree.fs
+++ b/qemu/roms/openbios/arch/ppc/qemu/tree.fs
@@ -42,6 +42,14 @@ new-device
: close ;
finish-device
+new-device
+ " rom" device-name
+ h# ff800000 encode-int 0 encode-int encode+ " reg" property
+ 1 encode-int " #address-cells" property
+ h# ff800000 encode-int h# 800000 encode-int encode+
+ h# ff800000 encode-int encode+ " ranges" property
+finish-device
+
\ -------------------------------------------------------------
\ /packages
\ -------------------------------------------------------------
diff --git a/qemu/roms/openbios/arch/sparc64/call-client.S b/qemu/roms/openbios/arch/sparc64/call-client.S
index f365e3cb1..a8c0348e4 100644
--- a/qemu/roms/openbios/arch/sparc64/call-client.S
+++ b/qemu/roms/openbios/arch/sparc64/call-client.S
@@ -1,3 +1,5 @@
+#include "cpustate.h"
+
.globl sparc64_of_client_interface, client_tba
@@ -9,151 +11,9 @@
* behaviour of OBP.
*/
-#define SAVE_WINDOW_STATE(type) \
- setx client_window, %g6, %g1; \
- rdpr %cwp, %g7; \
- stx %g7, [%g1]; \
- rdpr %cansave, %g7; \
- stx %g7, [%g1 + 0x8]; \
- rdpr %canrestore, %g7; \
- stx %g7, [%g1 + 0x10]; \
- rdpr %otherwin, %g7; \
- stx %g7, [%g1 + 0x18]; \
- rdpr %wstate, %g7; \
- stx %g7, [%g1 + 0x20]; \
- rdpr %cleanwin, %g7; \
- stx %g7, [%g1 + 0x28]; \
- \
- stx %o0, [%g1 + 0x30]; \
- stx %o1, [%g1 + 0x38]; \
- stx %o2, [%g1 + 0x40]; \
- stx %o3, [%g1 + 0x48]; \
- stx %o4, [%g1 + 0x50]; \
- stx %o5, [%g1 + 0x58]; \
- stx %o6, [%g1 + 0x60]; \
- stx %o7, [%g1 + 0x68]; \
- \
- rdpr %pstate, %g7; \
- stx %g7, [%g1 + 0x70]; \
- rd %y, %g7; \
- stx %g7, [%g1 + 0x78]; \
- rd %fprs, %g7; \
- stx %g7, [%g1 + 0x80]; \
- \
- /* Now iterate through all of the windows saving all l and i registers */ \
- add %g1, 0x90, %g5; \
- \
- /* Get the number of windows in %g6 */ \
- rdpr %ver, %g6; \
- and %g6, 0xf, %g6; \
- inc %g6; \
- \
-save_cpu_window_##type: \
- deccc %g6; \
- wrpr %g6, %cwp; \
- stx %l0, [%g5]; \
- stx %l1, [%g5 + 0x8]; \
- stx %l2, [%g5 + 0x10]; \
- stx %l3, [%g5 + 0x18]; \
- stx %l4, [%g5 + 0x20]; \
- stx %l5, [%g5 + 0x28]; \
- stx %l6, [%g5 + 0x30]; \
- stx %l7, [%g5 + 0x38]; \
- stx %i0, [%g5 + 0x40]; \
- stx %i1, [%g5 + 0x48]; \
- stx %i2, [%g5 + 0x50]; \
- stx %i3, [%g5 + 0x58]; \
- stx %i4, [%g5 + 0x60]; \
- stx %i5, [%g5 + 0x68]; \
- stx %i6, [%g5 + 0x70]; \
- stx %i7, [%g5 + 0x78]; \
- bne save_cpu_window_##type; \
- add %g5, 0x80, %g5; \
- \
- /* For 8 windows with 16 registers to save in the window, memory required \
- is 16*8*8 = 0x400 bytes */ \
- \
- /* Now we should be in window 0 so update the other window registers */ \
- rdpr %ver, %g6; \
- and %g6, 0xf, %g6; \
- dec %g6; \
- wrpr %g6, %cansave; \
- \
- wrpr %g0, %cleanwin; \
- wrpr %g0, %canrestore; \
- wrpr %g0, %otherwin;
-
-
-#define RESTORE_WINDOW_STATE(type) \
- setx client_window, %g6, %g1; \
- \
- /* Get the number of windows in %g6 */ \
- rdpr %ver, %g6; \
- and %g6, 0xf, %g6; \
- inc %g6; \
- \
- /* Now iterate through all of the windows restoring all l and i registers */ \
- add %g1, 0x90, %g5; \
- \
-restore_cpu_window_##type: \
- deccc %g6; \
- wrpr %g6, %cwp; \
- ldx [%g5], %l0; \
- ldx [%g5 + 0x8], %l1; \
- ldx [%g5 + 0x10], %l2; \
- ldx [%g5 + 0x18], %l3; \
- ldx [%g5 + 0x20], %l4; \
- ldx [%g5 + 0x28], %l5; \
- ldx [%g5 + 0x30], %l6; \
- ldx [%g5 + 0x38], %l7; \
- ldx [%g5 + 0x40], %i0; \
- ldx [%g5 + 0x48], %i1; \
- ldx [%g5 + 0x50], %i2; \
- ldx [%g5 + 0x58], %i3; \
- ldx [%g5 + 0x60], %i4; \
- ldx [%g5 + 0x68], %i5; \
- ldx [%g5 + 0x70], %i6; \
- ldx [%g5 + 0x78], %i7; \
- bne restore_cpu_window_##type; \
- add %g5, 0x80, %g5; \
- \
- /* Restore the window registers to their original value */ \
- ldx [%g1], %g7; \
- wrpr %g7, %cwp; \
- ldx [%g1 + 0x8], %g7; \
- wrpr %g7, %cansave; \
- ldx [%g1 + 0x10], %g7; \
- wrpr %g7, %canrestore; \
- ldx [%g1 + 0x18], %g7; \
- wrpr %g7, %otherwin; \
- ldx [%g1 + 0x20], %g7; \
- wrpr %g7, %wstate; \
- ldx [%g1 + 0x28], %g7; \
- wrpr %g7, %cleanwin; \
- \
- ldx [%g1 + 0x30], %o0; \
- ldx [%g1 + 0x38], %o1; \
- ldx [%g1 + 0x40], %o2; \
- ldx [%g1 + 0x48], %o3; \
- ldx [%g1 + 0x50], %o4; \
- ldx [%g1 + 0x58], %o5; \
- ldx [%g1 + 0x60], %o6; \
- ldx [%g1 + 0x68], %o7; \
- \
- ldx [%g1 + 0x70], %g7; \
- wrpr %g7, %pstate; \
- ldx [%g1 + 0x78], %g7; \
- wr %g7, 0, %y; \
- ldx [%g1 + 0x80], %g7; \
- wr %g7, 0, %fprs
-
-
.data
.align 8
- .skip 16384
-openbios_stack:
-
client_stack:
.xword 0
client_tba:
@@ -176,15 +36,15 @@ client_window:
sparc64_of_client_interface:
/* Save globals on callers stack */
- add %sp, -56, %sp
+ add %sp, -248, %sp
- stx %g1, [%sp + 2047 + 0]
- stx %g2, [%sp + 2047 + 8]
- stx %g3, [%sp + 2047 + 16]
- stx %g4, [%sp + 2047 + 24]
- stx %g5, [%sp + 2047 + 32]
- stx %g6, [%sp + 2047 + 40]
- stx %g7, [%sp + 2047 + 48]
+ stx %g1, [%sp + 2047 + 192]
+ stx %g2, [%sp + 2047 + 200]
+ stx %g3, [%sp + 2047 + 208]
+ stx %g4, [%sp + 2047 + 216]
+ stx %g5, [%sp + 2047 + 224]
+ stx %g6, [%sp + 2047 + 232]
+ stx %g7, [%sp + 2047 + 240]
/* Save client trap table */
setx client_tba, %g6, %g7
@@ -196,22 +56,44 @@ sparc64_of_client_interface:
stx %sp, [%g7]
/* Save windows */
- SAVE_WINDOW_STATE(cif)
-
- /* Move to OpenBIOS stack */
- setx openbios_stack - 2047 - 192, %g6, %g7
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g1
+ add %g1, -CONTEXT_STATE_SIZE, %g1
+ stx %g1, [%g7]
+
+ SAVE_CPU_WINDOW_STATE(cif)
+
+ /* Move to OpenBIOS context stack */
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g6
+ setx CONTEXT_STACK_SIZE, %g4, %g5
+ sub %g6, %g5, %g6
+ stx %g6, [%g7]
+
+ setx - 2047 - 192, %g6, %g7
+ add %g1, %g7, %g7
mov %g7, %sp
/* Call client inteface */
call of_client_interface
ldx [%g1 + 0x30], %o0
- setx client_window, %g6, %g1
- stx %o0, [%g1 + 0x30]
-
/* Restore windows */
- RESTORE_WINDOW_STATE(cif)
-
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g1
+ setx CONTEXT_STACK_SIZE, %g4, %g5
+ add %g1, %g5, %g1
+ stx %g1, [%g7]
+
+ /* Return value */
+ stx %o0, [%g1 + 0x30]
+
+ RESTORE_CPU_WINDOW_STATE(cif)
+
+ add %g1, CONTEXT_STATE_SIZE, %g1
+ setx _fcstack_ptr, %g6, %g7
+ stx %g1, [%g7]
+
/* Restore stack */
setx client_stack, %g6, %g7
ldx [%g7], %sp
@@ -222,15 +104,15 @@ sparc64_of_client_interface:
wrpr %g6, %tba
/* Restore globals */
- ldx [%sp + 2047 + 0], %g1
- ldx [%sp + 2047 + 8], %g2
- ldx [%sp + 2047 + 16], %g3
- ldx [%sp + 2047 + 24], %g4
- ldx [%sp + 2047 + 32], %g5
- ldx [%sp + 2047 + 40], %g6
- ldx [%sp + 2047 + 48], %g7
-
- add %sp, 56, %sp
+ ldx [%sp + 2047 + 192], %g1
+ ldx [%sp + 2047 + 200], %g2
+ ldx [%sp + 2047 + 208], %g3
+ ldx [%sp + 2047 + 216], %g4
+ ldx [%sp + 2047 + 224], %g5
+ ldx [%sp + 2047 + 232], %g6
+ ldx [%sp + 2047 + 240], %g7
+
+ add %sp, 248, %sp
jmp %o7+8
nop
diff --git a/qemu/roms/openbios/arch/sparc64/context.c b/qemu/roms/openbios/arch/sparc64/context.c
index 2e7668958..98932ee9c 100644
--- a/qemu/roms/openbios/arch/sparc64/context.c
+++ b/qemu/roms/openbios/arch/sparc64/context.c
@@ -40,6 +40,10 @@ static uint8_t image_stack[IMAGE_STACK_SIZE];
/* Pointer to startup context (physical address) */
unsigned long __boot_ctx;
+/* Pointer to Forth context stack */
+void *_fcstack_ptr = &_efcstack;
+
+
/*
* Main starter
* This is the C function that runs first.
diff --git a/qemu/roms/openbios/arch/sparc64/cpustate.h b/qemu/roms/openbios/arch/sparc64/cpustate.h
new file mode 100644
index 000000000..0c276bfd1
--- /dev/null
+++ b/qemu/roms/openbios/arch/sparc64/cpustate.h
@@ -0,0 +1,244 @@
+/*
+ * Save/restore CPU state macros
+ *
+ * Copyright (C) 2015 Mark Cave-Ayland (mark.cave-ayland@ilande.co.uk>)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2
+ *
+ */
+
+/* State size for context (see below) */
+#define CONTEXT_STATE_SIZE 0x510
+
+/* Stack size for context (allocated inline of the context stack) */
+#define CONTEXT_STACK_SIZE 0x2000
+
+/*
+ * SAVE_CPU_STATE and RESTORE_CPU_STATE are macros used to enable a context switch
+ * to C to occur within the MMU I/D TLB miss handlers.
+ *
+ * Because these handlers are called on a TLB miss, we cannot use flushw to store
+ * processor window state on the stack, as the memory areas used by each window's
+ * stack pointer may not be in the TLB, causing recursive TLB miss traps.
+ *
+ * For this reason, we save window state by manually rotating the window registers
+ * and saving their contents (along with other vital registers) into a special
+ * tlb_handler_stack defined above which is guaranteed to be locked in the TLB, and
+ * so won't cause issues with trap recursion.
+ *
+ * Once this process is complete, we remain in a TL=0, CWP=0 state (with IE=1 to allow
+ * window fill/spill traps if required), switch to our safe tlb_handler_stack and
+ * invoke the miss handler.
+ */
+
+#define SAVE_CPU_WINDOW_STATE(type) \
+ /* Save window state into context at %g1 */ \
+ rdpr %cwp, %g7; \
+ stx %g7, [%g1]; \
+ rdpr %cansave, %g7; \
+ stx %g7, [%g1 + 0x8]; \
+ rdpr %canrestore, %g7; \
+ stx %g7, [%g1 + 0x10]; \
+ rdpr %otherwin, %g7; \
+ stx %g7, [%g1 + 0x18]; \
+ rdpr %wstate, %g7; \
+ stx %g7, [%g1 + 0x20]; \
+ rdpr %cleanwin, %g7; \
+ stx %g7, [%g1 + 0x28]; \
+ \
+ stx %o0, [%g1 + 0x30]; \
+ stx %o1, [%g1 + 0x38]; \
+ stx %o2, [%g1 + 0x40]; \
+ stx %o3, [%g1 + 0x48]; \
+ stx %o4, [%g1 + 0x50]; \
+ stx %o5, [%g1 + 0x58]; \
+ stx %o6, [%g1 + 0x60]; \
+ stx %o7, [%g1 + 0x68]; \
+ \
+ rdpr %pstate, %g7; \
+ stx %g7, [%g1 + 0x70]; \
+ rd %y, %g7; \
+ stx %g7, [%g1 + 0x78]; \
+ rd %fprs, %g7; \
+ stx %g7, [%g1 + 0x80]; \
+ rdpr %tl, %g7; \
+ stx %g7, [%g1 + 0x88]; \
+ \
+ /* Now iterate through all of the windows saving all l and i registers */ \
+ add %g1, 0x90, %g5; \
+ \
+ /* Get the number of windows in %g6 */ \
+ rdpr %ver, %g6; \
+ and %g6, 0xf, %g6; \
+ \
+ mov %g6, %g4; \
+ inc %g4; \
+ \
+ /* Starting cwp in g7 */ \
+ rdpr %cwp, %g7; \
+ \
+save_cpu_window_##type: \
+ wrpr %g7, %cwp; \
+ stx %l0, [%g5]; \
+ stx %l1, [%g5 + 0x8]; \
+ stx %l2, [%g5 + 0x10]; \
+ stx %l3, [%g5 + 0x18]; \
+ stx %l4, [%g5 + 0x20]; \
+ stx %l5, [%g5 + 0x28]; \
+ stx %l6, [%g5 + 0x30]; \
+ stx %l7, [%g5 + 0x38]; \
+ stx %i0, [%g5 + 0x40]; \
+ stx %i1, [%g5 + 0x48]; \
+ stx %i2, [%g5 + 0x50]; \
+ stx %i3, [%g5 + 0x58]; \
+ stx %i4, [%g5 + 0x60]; \
+ stx %i5, [%g5 + 0x68]; \
+ stx %i6, [%g5 + 0x70]; \
+ stx %i7, [%g5 + 0x78]; \
+ dec %g7; \
+ and %g7, %g6, %g7; \
+ subcc %g4, 1, %g4; \
+ bne save_cpu_window_##type; \
+ add %g5, 0x80, %g5; \
+ \
+ /* For 8 windows with 16 registers to save in the window, memory required \
+ is 16*8*8 = 0x400 bytes */ \
+ \
+ /* Now we should be in window 0 so update the other window registers */ \
+ rdpr %ver, %g6; \
+ and %g6, 0xf, %g6; \
+ dec %g6; \
+ wrpr %g6, %cansave; \
+ \
+ wrpr %g0, %cleanwin; \
+ wrpr %g0, %canrestore; \
+ wrpr %g0, %otherwin; \
+
+
+#define SAVE_CPU_TRAP_STATE(type) \
+ /* Save trap state into context at %g1 */ \
+ add %g1, 0x490, %g5; \
+ mov 4, %g6; \
+ \
+save_trap_state_##type: \
+ deccc %g6; \
+ wrpr %g6, %tl; \
+ rdpr %tpc, %g7; \
+ stx %g7, [%g5]; \
+ rdpr %tnpc, %g7; \
+ stx %g7, [%g5 + 0x8]; \
+ rdpr %tstate, %g7; \
+ stx %g7, [%g5 + 0x10]; \
+ rdpr %tt, %g7; \
+ stx %g7, [%g5 + 0x18]; \
+ bne save_trap_state_##type; \
+ add %g5, 0x20, %g5; \
+ \
+ /* For 4 trap levels with 4 registers, memory required is \
+ 4*8*4 = 0x80 bytes */
+
+/* Save all state into context at %g1 */
+#define SAVE_CPU_STATE(type) \
+ SAVE_CPU_WINDOW_STATE(type); \
+ SAVE_CPU_TRAP_STATE(type);
+
+
+#define RESTORE_CPU_WINDOW_STATE(type) \
+ /* Restore window state from context at %g1 */ \
+ \
+ /* Get the number of windows in %g6 */ \
+ rdpr %ver, %g6; \
+ and %g6, 0xf, %g6; \
+ \
+ mov %g6, %g4; \
+ inc %g4; \
+ \
+ /* Set starting window */ \
+ ldx [%g1], %g7; \
+ \
+ /* Now iterate through all of the windows restoring all l and i registers */ \
+ add %g1, 0x90, %g5; \
+ \
+restore_cpu_window_##type: \
+ wrpr %g7, %cwp; \
+ ldx [%g5], %l0; \
+ ldx [%g5 + 0x8], %l1; \
+ ldx [%g5 + 0x10], %l2; \
+ ldx [%g5 + 0x18], %l3; \
+ ldx [%g5 + 0x20], %l4; \
+ ldx [%g5 + 0x28], %l5; \
+ ldx [%g5 + 0x30], %l6; \
+ ldx [%g5 + 0x38], %l7; \
+ ldx [%g5 + 0x40], %i0; \
+ ldx [%g5 + 0x48], %i1; \
+ ldx [%g5 + 0x50], %i2; \
+ ldx [%g5 + 0x58], %i3; \
+ ldx [%g5 + 0x60], %i4; \
+ ldx [%g5 + 0x68], %i5; \
+ ldx [%g5 + 0x70], %i6; \
+ ldx [%g5 + 0x78], %i7; \
+ dec %g7; \
+ and %g7, %g6, %g7; \
+ subcc %g4, 1, %g4; \
+ bne restore_cpu_window_##type; \
+ add %g5, 0x80, %g5; \
+ \
+ /* Restore the window registers to their original value */ \
+ ldx [%g1], %g7; \
+ wrpr %g7, %cwp; \
+ ldx [%g1 + 0x8], %g7; \
+ wrpr %g7, %cansave; \
+ ldx [%g1 + 0x10], %g7; \
+ wrpr %g7, %canrestore; \
+ ldx [%g1 + 0x18], %g7; \
+ wrpr %g7, %otherwin; \
+ ldx [%g1 + 0x20], %g7; \
+ wrpr %g7, %wstate; \
+ ldx [%g1 + 0x28], %g7; \
+ wrpr %g7, %cleanwin; \
+ \
+ ldx [%g1 + 0x30], %o0; \
+ ldx [%g1 + 0x38], %o1; \
+ ldx [%g1 + 0x40], %o2; \
+ ldx [%g1 + 0x48], %o3; \
+ ldx [%g1 + 0x50], %o4; \
+ ldx [%g1 + 0x58], %o5; \
+ ldx [%g1 + 0x60], %o6; \
+ ldx [%g1 + 0x68], %o7; \
+ \
+ ldx [%g1 + 0x70], %g7; \
+ wrpr %g7, %pstate; \
+ ldx [%g1 + 0x78], %g7; \
+ wr %g7, 0, %y; \
+ ldx [%g1 + 0x80], %g7; \
+ wr %g7, 0, %fprs; \
+
+
+#define RESTORE_CPU_TRAP_STATE(type) \
+ /* Restore trap state from context at %g1 */ \
+ add %g1, 0x490, %g5; \
+ mov 4, %g6; \
+ \
+restore_trap_state_##type: \
+ deccc %g6; \
+ wrpr %g6, %tl; \
+ ldx [%g5], %g7; \
+ wrpr %g7, %tpc; \
+ ldx [%g5 + 0x8], %g7; \
+ wrpr %g7, %tnpc; \
+ ldx [%g5 + 0x10], %g7; \
+ wrpr %g7, %tstate; \
+ ldx [%g5 + 0x18], %g7; \
+ wrpr %g7, %tt; \
+ bne restore_trap_state_##type; \
+ add %g5, 0x20, %g5; \
+ \
+ ldx [%g1 + 0x88], %g7; \
+ wrpr %g7, %tl
+
+/* Restore all state from context at %g1 */
+#define RESTORE_CPU_STATE(type) \
+ RESTORE_CPU_WINDOW_STATE(type); \
+ RESTORE_CPU_TRAP_STATE(type);
diff --git a/qemu/roms/openbios/arch/sparc64/ldscript b/qemu/roms/openbios/arch/sparc64/ldscript
index 54288e825..c5cc6a5ce 100644
--- a/qemu/roms/openbios/arch/sparc64/ldscript
+++ b/qemu/roms/openbios/arch/sparc64/ldscript
@@ -50,6 +50,11 @@ SECTIONS
*(.bss.*)
*(COMMON)
+ _fcstack = .;
+ . += 32768;
+ . = ALIGN(16);
+ _efcstack = .;
+
_stack = .;
. += STACK_SIZE;
. = ALIGN(16);
diff --git a/qemu/roms/openbios/arch/sparc64/lib.c b/qemu/roms/openbios/arch/sparc64/lib.c
index e9101af52..4709ca8fe 100644
--- a/qemu/roms/openbios/arch/sparc64/lib.c
+++ b/qemu/roms/openbios/arch/sparc64/lib.c
@@ -458,10 +458,10 @@ NODE_METHODS(mmu) = {
void ob_mmu_init(const char *cpuname, uint64_t ram_size)
{
/* memory node */
- REGISTER_NODE_METHODS(memory, "/memory");
+ REGISTER_NODE(memory);
/* MMU node */
- REGISTER_NODE_METHODS(mmu, "/virtual-memory");
+ REGISTER_NODE(mmu);
ofmem_register(find_dev("/memory"), find_dev("/virtual-memory"));
diff --git a/qemu/roms/openbios/arch/sparc64/vectors.S b/qemu/roms/openbios/arch/sparc64/vectors.S
index 927c1cdc7..9d86b6bd8 100644
--- a/qemu/roms/openbios/arch/sparc64/vectors.S
+++ b/qemu/roms/openbios/arch/sparc64/vectors.S
@@ -24,6 +24,7 @@
*/
#define __ASSEMBLY__
+#include "cpustate.h"
#include "pstate.h"
#include <asm/asi.h>
#define ASI_BP ASI_PHYS_BYPASS_EC_E
@@ -276,17 +277,8 @@ tl1_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8)
.section ".data"
.align 8
- .globl tlb_handler_stack_top, tlb_handler_stack_pointer, obp_ticks_pointer
+ .globl obp_ticks_pointer
- ! Stack for the tlb MMU trap handlers
-tlb_handler_stack_bottom:
- .skip 8192
-tlb_handler_stack_top:
- .skip 8
-
- ! MMU trap handler stack pointer
-tlb_handler_stack_pointer:
- .xword tlb_handler_stack_top
! Pointer to current tick value
obp_ticks_pointer:
@@ -336,234 +328,30 @@ fill_32bit:
restored
retry
-/*
- * SAVE_CPU_STATE and RESTORE_CPU_STATE are macros used to enable a context switch
- * to C to occur within the MMU I/D TLB miss handlers.
- *
- * Because these handlers are called on a TLB miss, we cannot use flushw to store
- * processor window state on the stack, as the memory areas used by each window's
- * stack pointer may not be in the TLB, causing recursive TLB miss traps.
- *
- * For this reason, we save window state by manually rotating the window registers
- * and saving their contents (along with other vital registers) into a special
- * tlb_handler_stack defined above which is guaranteed to be locked in the TLB, and
- * so won't cause issues with trap recursion.
- *
- * Once this process is complete, we remain in a TL=0, CWP=0 state (with IE=1 to allow
- * window fill/spill traps if required), switch to our safe tlb_handler_stack and
- * invoke the miss handler.
- */
-
-#define SAVE_CPU_STATE(type) \
- /* Set up our exception stack pointer in %g1 */ \
- setx tlb_handler_stack_pointer, %g7, %g6; \
- ldx [%g6], %g1; \
- add %g1, -0x510, %g1; \
- \
- /* First save the various state registers */ \
- rdpr %cwp, %g7; \
- stx %g7, [%g1]; \
- rdpr %cansave, %g7; \
- stx %g7, [%g1 + 0x8]; \
- rdpr %canrestore, %g7; \
- stx %g7, [%g1 + 0x10]; \
- rdpr %otherwin, %g7; \
- stx %g7, [%g1 + 0x18]; \
- rdpr %wstate, %g7; \
- stx %g7, [%g1 + 0x20]; \
- rdpr %cleanwin, %g7; \
- stx %g7, [%g1 + 0x28]; \
- rdpr %pstate, %g7; \
- stx %g7, [%g1 + 0x30]; \
- \
- rd %y, %g7; \
- stx %g7, [%g1 + 0x38]; \
- rd %fprs, %g7; \
- stx %g7, [%g1 + 0x40]; \
- \
- rdpr %tl, %g7; \
- stx %g7, [%g1 + 0x48]; \
- \
- /* Trap state */ \
- add %g1, 0x50, %g5; \
- mov 4, %g6; \
- \
-save_trap_state_##type: \
- deccc %g6; \
- wrpr %g6, %tl; \
- rdpr %tpc, %g7; \
- stx %g7, [%g5]; \
- rdpr %tnpc, %g7; \
- stx %g7, [%g5 + 0x8]; \
- rdpr %tstate, %g7; \
- stx %g7, [%g5 + 0x10]; \
- rdpr %tt, %g7; \
- stx %g7, [%g5 + 0x18]; \
- bne save_trap_state_##type; \
- add %g5, 0x20, %g5; \
- \
- /* For 4 trap levels with 4 registers, memory required is
- 4*8*4 = 0x80 bytes */ \
- \
- /* Save the o registers */ \
- stx %o0, [%g1 + 0xd0]; \
- stx %o1, [%g1 + 0xd8]; \
- stx %o2, [%g1 + 0xe0]; \
- stx %o3, [%g1 + 0xe8]; \
- stx %o4, [%g1 + 0xf0]; \
- stx %o5, [%g1 + 0xf8]; \
- stx %o6, [%g1 + 0x100]; \
- stx %o7, [%g1 + 0x108]; \
- \
- /* Now iterate through all of the windows saving all l and i registers */ \
- add %g1, 0x110, %g5; \
- \
- /* Get the number of windows in %g6 */ \
- rdpr %ver, %g6; \
- and %g6, 0xf, %g6; \
- inc %g6; \
- \
-save_cpu_window_##type: \
- deccc %g6; \
- wrpr %g6, %cwp; \
- stx %l0, [%g5]; \
- stx %l1, [%g5 + 0x8]; \
- stx %l2, [%g5 + 0x10]; \
- stx %l3, [%g5 + 0x18]; \
- stx %l4, [%g5 + 0x20]; \
- stx %l5, [%g5 + 0x28]; \
- stx %l6, [%g5 + 0x30]; \
- stx %l7, [%g5 + 0x38]; \
- stx %i0, [%g5 + 0x40]; \
- stx %i1, [%g5 + 0x48]; \
- stx %i2, [%g5 + 0x50]; \
- stx %i3, [%g5 + 0x58]; \
- stx %i4, [%g5 + 0x60]; \
- stx %i5, [%g5 + 0x68]; \
- stx %i6, [%g5 + 0x70]; \
- stx %i7, [%g5 + 0x78]; \
- bne save_cpu_window_##type; \
- add %g5, 0x80, %g5; \
- \
- /* For 8 windows with 16 registers to save in the window, memory required
- is 16*8*8 = 0x400 bytes */ \
- \
- /* Now we should be in window 0 so update the other window registers */ \
- rdpr %ver, %g6; \
- and %g6, 0xf, %g6; \
- dec %g6; \
- wrpr %g6, %cansave; \
- \
- wrpr %g0, %cleanwin; \
- wrpr %g0, %canrestore; \
- wrpr %g0, %otherwin; \
- \
- /* Update our exception stack pointer */ \
- setx tlb_handler_stack_pointer, %g7, %g6; \
- stx %g1, [%g6];
-
-
-#define RESTORE_CPU_STATE(type) \
- /* Set up our exception stack pointer in %g1 */ \
- setx tlb_handler_stack_pointer, %g7, %g6; \
- ldx [%g6], %g1; \
- \
- /* Get the number of windows in %g6 */ \
- rdpr %ver, %g6; \
- and %g6, 0xf, %g6; \
- inc %g6; \
- \
- /* Now iterate through all of the windows restoring all l and i registers */ \
- add %g1, 0x110, %g5; \
- \
-restore_cpu_window_##type: \
- deccc %g6; \
- wrpr %g6, %cwp; \
- ldx [%g5], %l0; \
- ldx [%g5 + 0x8], %l1; \
- ldx [%g5 + 0x10], %l2; \
- ldx [%g5 + 0x18], %l3; \
- ldx [%g5 + 0x20], %l4; \
- ldx [%g5 + 0x28], %l5; \
- ldx [%g5 + 0x30], %l6; \
- ldx [%g5 + 0x38], %l7; \
- ldx [%g5 + 0x40], %i0; \
- ldx [%g5 + 0x48], %i1; \
- ldx [%g5 + 0x50], %i2; \
- ldx [%g5 + 0x58], %i3; \
- ldx [%g5 + 0x60], %i4; \
- ldx [%g5 + 0x68], %i5; \
- ldx [%g5 + 0x70], %i6; \
- ldx [%g5 + 0x78], %i7; \
- bne restore_cpu_window_##type; \
- add %g5, 0x80, %g5; \
- \
- /* Restore the window registers to their original value */ \
- ldx [%g1], %g7; \
- wrpr %g7, %cwp; \
- ldx [%g1 + 0x8], %g7; \
- wrpr %g7, %cansave; \
- ldx [%g1 + 0x10], %g7; \
- wrpr %g7, %canrestore; \
- ldx [%g1 + 0x18], %g7; \
- wrpr %g7, %otherwin; \
- ldx [%g1 + 0x20], %g7; \
- wrpr %g7, %wstate; \
- ldx [%g1 + 0x28], %g7; \
- wrpr %g7, %cleanwin; \
- ldx [%g1 + 0x30], %g7; \
- wrpr %g7, %pstate; \
- \
- /* Restore the o registers */ \
- ldx [%g1 + 0xd0], %o0; \
- ldx [%g1 + 0xd8], %o1; \
- ldx [%g1 + 0xe0], %o2; \
- ldx [%g1 + 0xe8], %o3; \
- ldx [%g1 + 0xf0], %o4; \
- ldx [%g1 + 0xf8], %o5; \
- ldx [%g1 + 0x100], %o6; \
- ldx [%g1 + 0x108], %o7; \
- \
- /* Restore the trap state */ \
- add %g1, 0x50, %g5; \
- mov 4, %g6; \
- \
-restore_trap_state_##type: \
- deccc %g6; \
- wrpr %g6, %tl; \
- ldx [%g5], %g7; \
- wrpr %g7, %tpc; \
- ldx [%g5 + 0x8], %g7; \
- wrpr %g7, %tnpc; \
- ldx [%g5 + 0x10], %g7; \
- wrpr %g7, %tstate; \
- ldx [%g5 + 0x18], %g7; \
- wrpr %g7, %tt; \
- bne restore_trap_state_##type; \
- add %g5, 0x20, %g5; \
- \
- ldx [%g1 + 0x38], %g7; \
- wr %g7, 0, %y; \
- ldx [%g1 + 0x40], %g7; \
- wr %g7, 0, %fprs; \
- ldx [%g1 + 0x48], %g7; \
- wrpr %g7, %tl; \
- \
- /* Restore exception stack pointer to previous value */ \
- setx tlb_handler_stack_pointer, %g7, %g6; \
- add %g1, 0x510, %g1; \
- stx %g1, [%g6];
-
.globl reload_DMMU_tlb, reload_IMMU_tlb, bug
reload_DMMU_tlb:
-
+
+ /* Save CPU state to stack */
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g1
+ add %g1, -CONTEXT_STATE_SIZE, %g1
+ stx %g1, [%g7]
+
SAVE_CPU_STATE(dtlb)
- /* Switch to TLB locked stack space (note we add an additional 192 bytes required for
+ /* Switch to 8K TLB locked OpenBIOS stack (note we add an additional 192 bytes required for
gcc to save its arguments when building with -O0) */
- add %g1, -STACK_BIAS - 192, %sp
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g6
+ setx CONTEXT_STACK_SIZE, %g4, %g5
+ sub %g6, %g5, %g6
+ stx %g6, [%g7]
+
+ setx - 2047 - 192, %g6, %g7
+ add %g1, %g7, %g7
+ mov %g7, %sp
/* Enable interrupts for window spill/fill traps */
rdpr %pstate, %g7
@@ -577,18 +365,44 @@ reload_DMMU_tlb:
rdpr %pstate, %g7
andn %g7, PSTATE_IE, %g7
wrpr %g7, %pstate
-
+
+ /* Restore CPU state from stack */
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g1
+ setx CONTEXT_STACK_SIZE, %g4, %g5
+ add %g1, %g5, %g1
+ stx %g1, [%g7]
+
RESTORE_CPU_STATE(dtlb)
-
+
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g1
+ add %g1, CONTEXT_STATE_SIZE, %g1
+ stx %g1, [%g7]
+
retry
reload_IMMU_tlb:
-
+
+ /* Save CPU state to stack */
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g1
+ add %g1, -CONTEXT_STATE_SIZE, %g1
+ stx %g1, [%g7]
+
SAVE_CPU_STATE(itlb)
- /* Switch to TLB locked stack space (note we add an additional 192 bytes required for
+ /* Switch to 8K TLB locked OpenBIOS stack (note we add an additional 192 bytes required for
gcc to save its arguments when building with -O0) */
- add %g1, -STACK_BIAS - 192, %sp
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g6
+ setx CONTEXT_STACK_SIZE, %g4, %g5
+ sub %g6, %g5, %g6
+ stx %g6, [%g7]
+
+ setx - 2047 - 192, %g6, %g7
+ add %g1, %g7, %g7
+ mov %g7, %sp
/* Enable interrupts for window spill/fill traps */
rdpr %pstate, %g7
@@ -602,8 +416,20 @@ reload_IMMU_tlb:
rdpr %pstate, %g7
andn %g7, PSTATE_IE, %g7
wrpr %g7, %pstate
-
+
+ /* Restore CPU state from stack */
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g1
+ setx CONTEXT_STACK_SIZE, %g4, %g5
+ add %g1, %g5, %g1
+ stx %g1, [%g7]
+
RESTORE_CPU_STATE(itlb)
+
+ setx _fcstack_ptr, %g6, %g7
+ ldx [%g7], %g1
+ add %g1, CONTEXT_STATE_SIZE, %g1
+ stx %g1, [%g7]
retry
diff --git a/qemu/roms/openbios/config/scripts/switch-arch b/qemu/roms/openbios/config/scripts/switch-arch
index d5e2f7710..ab3b4ce69 100755
--- a/qemu/roms/openbios/config/scripts/switch-arch
+++ b/qemu/roms/openbios/config/scripts/switch-arch
@@ -17,48 +17,57 @@ if [ x"$1" = x -o "$1" = "-help" ]; then
exit 0
fi
-crosscflags()
+is_bigendian()
{
- host=$1
- target=$2
-
- if test "$host" = "powerpc" -o "$host" = "ppc" \
- -o "$host" = "mips" -o "$host" = "s390" \
- -o "$host" = "sparc32" -o "$host" = "sparc64" \
- -o "$host" = "m68k" -o "$host" = "armv4b"; then
- hostbigendian="yes"
+ cpu=$1
+
+ if test "$cpu" = "powerpc" -o "$cpu" = "ppc" \
+ -o "$cpu" = "powerpc64" -o "$cpu" = "ppc64" \
+ -o "$cpu" = "mips" -o "$cpu" = "s390" \
+ -o "$cpu" = "sparc32" -o "$cpu" = "sparc64" \
+ -o "$cpu" = "m68k" -o "$cpu" = "armv4b"; then
+ echo yes
else
- hostbigendian="no"
+ echo no
fi
+}
-# host long bits test
- if test "$host" = "sparc64" -o "$host" = "ia64" \
- -o "$host" = "amd64" -o "$host" = "x86_64" \
- -o "$host" = "alpha"; then
- hostlongbits="64"
+longbits()
+{
+ cpu=$1
+ if test "$cpu" = "sparc64" -o "$cpu" = "ia64" \
+ -o "$cpu" = "amd64" -o "$cpu" = "x86_64" \
+ -o "$cpu" = "powerpc64" -o "$cpu" = "ppc64" \
+ -o "$cpu" = "alpha"; then
+ echo 64
else
- hostlongbits="32"
+ echo 32
fi
+}
- if test "$target" = "powerpc" -o "$target" = "ppc" \
- -o "$target" = "powerpc64" -o "$target" = "ppc64" \
- -o "$target" = "mips" -o "$target" = "s390" \
- -o "$target" = "sparc32" -o "$target" = "sparc64" \
- -o "$target" = "m68k" -o "$target" = "armv4b"; then
- targetbigendian="yes"
- else
- targetbigendian="no"
- fi
+basearch()
+{
+ arch=$1
+ case $arch in
+ powerpc|ppc64|powerpc64)
+ echo ppc
+ ;;
+ *)
+ echo $arch
+ ;;
+ esac
+}
-# target long bits test
- if test "$target" = "sparc64" -o "$target" = "ia64" \
- -o "$target" = "amd64" -o "$target" = "x86_64" \
- -o "$target" = "powerpc64" -o "$target" = "ppc64" \
- -o "$target" = "alpha"; then
- targetlongbits="64"
- else
- targetlongbits="32"
- fi
+crosscflags()
+{
+ host=$1
+ target=$2
+
+ hostbigendian=$(is_bigendian $host)
+ hostlongbits=$(longbits $host)
+
+ targetbigendian=$(is_bigendian $target)
+ targetlongbits=$(longbits $target)
if test "$targetbigendian" = "$hostbigendian"; then
cflags="-USWAP_ENDIANNESS"
@@ -99,23 +108,27 @@ archname()
select_prefix()
{
- TARGETS="${1}-unknown-linux-gnu- ${1}-linux-gnu- ${1}-linux- ${1}-elf- ${1}-eabi-"
+ BASEARCH=$(basearch $ARCH)
+ for target_arch ; do
+ TARGETS="${target_arch}-unknown-linux-gnu- ${target_arch}-linux-gnu- ${target_arch}-linux- ${target_arch}-elf- ${target_arch}-eabi-"
- if [ x"$CROSS_COMPILE" != "x" ]; then
- TARGETS=$CROSS_COMPILE
- fi
+ if [ x"$CROSS_COMPILE" != "x" ]; then
+ TARGETS=$CROSS_COMPILE
+ fi
- for TARGET in $TARGETS
- do
- if type ${TARGET}gcc > /dev/null 2>&1
- then
+ for TARGET in $TARGETS
+ do
+ if type ${TARGET}gcc > /dev/null 2>&1
+ then
+ return
+ fi
+ done
+ if [ "$BASEARCH" = "$(basearch $HOSTARCH)" ]; then
+ TARGET=""
return
fi
done
- if [ "$ARCH" = "$HOSTARCH" ]; then
- return
- fi
- echo "ERROR: no ${1} cross-compiler found !" 1>&2
+ echo "ERROR: no $* cross-compiler found !" 1>&2
exit 1
}
@@ -242,7 +255,6 @@ for ARCH in $arch_list; do
esac
done
- BASEARCH=$ARCH
case $ARCH in
amd64)
select_prefix x86_64
@@ -251,9 +263,10 @@ for ARCH in $arch_list; do
;;
ppc)
- select_prefix powerpc
+ select_prefix powerpc powerpc64
if [ "$unix" = "no" ]; then
- CFLAGS="-m32 -msoft-float -fno-builtin-bcopy -fno-builtin-log2"
+ # 604 cpu includes support for PReP as well as Mac
+ CFLAGS="-m32 -mcpu=604 -msoft-float -fno-builtin-bcopy -fno-builtin-log2"
AS_FLAGS="-m32"
else
CFLAGS="-fno-builtin"
@@ -263,13 +276,14 @@ for ARCH in $arch_list; do
ppc64)
select_prefix powerpc64
- CFLAGS="-Wa,-a64 -m64 -msoft-float -fno-builtin"
+
+ # 970 cpu is used in all 64-bit Macs but disable altivec
+ CFLAGS="-mcpu=970 -mno-altivec -Wa,-a64 -m64 -msoft-float -fno-builtin"
AS_FLAGS="-Wa,-a64"
- BASEARCH=ppc
;;
sparc32)
- select_prefix sparc
+ select_prefix sparc sparc64
CFLAGS="-Wa,-xarch=v8 -Wa,-32 -m32 -mcpu=supersparc -fno-builtin"
AS_FLAGS="-Wa,-xarch=v8 -Wa,-32"
;;
diff --git a/qemu/roms/openbios/drivers/cuda.c b/qemu/roms/openbios/drivers/cuda.c
index 9555dea49..ff5d22de2 100644
--- a/qemu/roms/openbios/drivers/cuda.c
+++ b/qemu/roms/openbios/drivers/cuda.c
@@ -144,8 +144,22 @@ static int cuda_adb_req (void *host, const uint8_t *snd_buf, int len,
// CUDA_DPRINTF("len: %d %02x\n", len, snd_buf[0]);
len = cuda_request(host, ADB_PACKET, snd_buf, len, buffer);
if (len > 1 && buffer[0] == ADB_PACKET) {
- pos = buffer + 2;
- len -= 2;
+ /* We handle 2 types of ADB packet here:
+ Normal: <type> <status> <data> ...
+ Error : <type> <status> <cmd> (<data> ...)
+ Ideally we should use buffer[1] (status) to determine whether this
+ is a normal or error packet but this requires a corresponding fix
+ in QEMU <= 2.4. Hence we temporarily handle it this way to ease
+ the transition. */
+ if (len > 2 && buffer[2] == snd_buf[0]) {
+ /* Error */
+ pos = buffer + 3;
+ len -= 3;
+ } else {
+ /* Normal */
+ pos = buffer + 2;
+ len -= 2;
+ }
} else {
pos = buffer + 1;
len = -1;
@@ -380,7 +394,8 @@ powermgt_init(char *path)
ph = find_dev(buf);
set_property(ph, "device_type", "power-mgt", 10);
- set_property(ph, "compatible", "power-mgt", 10);
+ set_property(ph, "mgt-kind", "min-consumption-pwm-led", strlen("min-consumption-pwm-led") + 1);
+ set_property(ph, "compatible", "cuda", strlen("cuda") + 1);
}
cuda_t *cuda_init (const char *path, phys_addr_t base)
diff --git a/qemu/roms/openbios/drivers/escc.c b/qemu/roms/openbios/drivers/escc.c
index 240043be3..1990e798d 100644
--- a/qemu/roms/openbios/drivers/escc.c
+++ b/qemu/roms/openbios/drivers/escc.c
@@ -380,12 +380,44 @@ ob_zs_init(phys_addr_t base, uint64_t offset, int intr, int slave, int keyboard)
static void
escc_add_channel(const char *path, const char *node, phys_addr_t addr,
- uint32_t offset)
+ int esnum)
{
char buf[64], tty[32];
phandle_t dnode, aliases;
- int len;
- cell props[2];
+
+ cell props[10];
+ ucell offset;
+ int index;
+ int legacy;
+
+ int dbdma_offsets[2][2] = {
+ /* ch-b */
+ { 0x6, 0x7 },
+ /* ch-a */
+ { 0x4, 0x5 }
+ };
+
+ int reg_offsets[2][2][3] = {
+ {
+ /* ch-b */
+ { 0x00, 0x10, 0x40 },
+ /* ch-a */
+ { 0x20, 0x30, 0x50 }
+ },{
+ /* legacy ch-b */
+ { 0x0, 0x2, 0x8 },
+ /* legacy ch-a */
+ { 0x4, 0x6, 0xa }
+ }
+ };
+
+ switch (esnum) {
+ case 2: index = 1; legacy = 0; break;
+ case 3: index = 0; legacy = 0; break;
+ case 4: index = 1; legacy = 1; break;
+ case 5: index = 0; legacy = 1; break;
+ default: return;
+ }
/* add device */
@@ -411,31 +443,49 @@ escc_add_channel(const char *path, const char *node, phys_addr_t addr,
set_property(dnode, "device_type", "serial",
strlen("serial") + 1);
- snprintf(buf, sizeof(buf), "ch-%s", node);
- len = strlen(buf) + 1;
- snprintf(buf + len, sizeof(buf) - len, "CHRP,es2");
- set_property(dnode, "compatible", buf, len + 9);
+ snprintf(buf, sizeof(buf), "chrp,es%d", esnum);
+ set_property(dnode, "compatible", buf, 9);
- props[0] = IO_ESCC_OFFSET + offset * 0x20;
- props[1] = 0x00000020;
- set_property(dnode, "reg", (char *)&props, 2 * sizeof(cell));
+ if (legacy) {
+ offset = IO_ESCC_LEGACY_OFFSET;
+ } else {
+ offset = IO_ESCC_OFFSET;
+ }
- props[0] = addr + IO_ESCC_OFFSET + offset * 0x20;
+ props[0] = offset + reg_offsets[legacy][index][0];
+ props[1] = 0x1;
+ props[2] = offset + reg_offsets[legacy][index][1];
+ props[3] = 0x1;
+ props[4] = offset + reg_offsets[legacy][index][2];
+ props[5] = 0x1;
+ props[6] = 0x8000 + dbdma_offsets[index][0] * 0x100;
+ props[7] = 0x100;
+ props[8] = 0x8000 + dbdma_offsets[index][1] * 0x100;
+ props[9] = 0x100;
+ set_property(dnode, "reg", (char *)&props, 10 * sizeof(cell));
+
+ props[0] = addr + offset + reg_offsets[legacy][index][0];
OLDWORLD(set_property(dnode, "AAPL,address",
(char *)&props, 1 * sizeof(cell)));
- props[0] = 0x00000010 - offset;
+ props[0] = 0x10 - index;
OLDWORLD(set_property(dnode, "AAPL,interrupts",
(char *)&props, 1 * sizeof(cell)));
- props[0] = (0x24) + offset;
- props[1] = 0;
+ props[0] = (0x24) + index;
+ props[1] = 0x1;
+ props[2] = dbdma_offsets[index][0];
+ props[3] = 0x0;
+ props[4] = dbdma_offsets[index][1];
+ props[5] = 0x0;
NEWWORLD(set_property(dnode, "interrupts",
- (char *)&props, 2 * sizeof(cell)));
+ (char *)&props, 6 * sizeof(cell)));
+
+ set_int_property(dnode, "slot-names", 0);
device_end();
- uart_init_line((unsigned char*)addr + IO_ESCC_OFFSET + offset * 0x20,
+ uart_init_line((unsigned char*)addr + offset + reg_offsets[legacy][index][0],
CONFIG_SERIAL_SPEED);
}
@@ -464,13 +514,39 @@ escc_init(const char *path, phys_addr_t addr)
set_property(dnode, "device_type", "escc",
strlen("escc") + 1);
set_property(dnode, "compatible", "escc\0CHRP,es0", 14);
+ set_property(dnode, "ranges", "", 0);
fword("finish-device");
- escc_add_channel(buf, "a", addr, 1);
- escc_add_channel(buf, "b", addr, 0);
+ escc_add_channel(buf, "a", addr, 2);
+ escc_add_channel(buf, "b", addr, 3);
escc_serial_dev = (unsigned char *)addr + IO_ESCC_OFFSET +
(CONFIG_SERIAL_PORT ? 0 : 0x20);
+
+ push_str(path);
+ fword("find-device");
+ fword("new-device");
+
+ push_str("escc-legacy");
+ fword("device-name");
+
+ snprintf(buf, sizeof(buf), "%s/escc-legacy", path);
+
+ dnode = find_dev(buf);
+
+ set_int_property(dnode, "#address-cells", 1);
+ props[0] = __cpu_to_be32(IO_ESCC_LEGACY_OFFSET);
+ props[1] = __cpu_to_be32(IO_ESCC_LEGACY_SIZE);
+ set_property(dnode, "reg", (char *)&props, sizeof(props));
+ set_property(dnode, "device_type", "escc-legacy",
+ strlen("escc-legacy") + 1);
+ set_property(dnode, "compatible", "chrp,es1", 9);
+ set_property(dnode, "ranges", "", 0);
+
+ fword("finish-device");
+
+ escc_add_channel(buf, "a", addr, 4);
+ escc_add_channel(buf, "b", addr, 5);
}
#endif
diff --git a/qemu/roms/openbios/drivers/escc.h b/qemu/roms/openbios/drivers/escc.h
index caaf00d40..e73f267b2 100644
--- a/qemu/roms/openbios/drivers/escc.h
+++ b/qemu/roms/openbios/drivers/escc.h
@@ -1,6 +1,8 @@
#define IO_ESCC_SIZE 0x00001000
#define IO_ESCC_OFFSET 0x00013000
+#define IO_ESCC_LEGACY_SIZE 0x00001000
+#define IO_ESCC_LEGACY_OFFSET 0x00012000
#define ZS_REGS 8
diff --git a/qemu/roms/openbios/drivers/ide.c b/qemu/roms/openbios/drivers/ide.c
index 327c64a40..1da60c895 100644
--- a/qemu/roms/openbios/drivers/ide.c
+++ b/qemu/roms/openbios/drivers/ide.c
@@ -73,13 +73,13 @@ static inline void ide_add_channel(struct ide_channel *chan)
channels = chan;
}
-static struct ide_channel *ide_seek_channel(const char *name)
+static struct ide_channel *ide_seek_channel(phandle_t ph)
{
struct ide_channel *current;
current = channels;
while (current) {
- if (!strcmp(current->name, name))
+ if (current->ph == ph)
return current;
current = current->next;
}
@@ -1247,11 +1247,10 @@ ob_ide_initialize(int *idx)
static void
ob_ide_open(int *idx)
{
- int ret=1, len;
+ int ret=1;
phandle_t ph;
struct ide_drive *drive;
struct ide_channel *chan;
- char *idename;
int unit;
fword("my-unit");
@@ -1260,9 +1259,8 @@ ob_ide_open(int *idx)
fword("my-parent");
fword("ihandle>phandle");
ph=(phandle_t)POP();
- idename=get_property(ph, "name", &len);
- chan = ide_seek_channel(idename);
+ chan = ide_seek_channel(ph);
drive = &chan->drives[unit];
*(struct ide_drive **)idx = drive;
@@ -1380,9 +1378,6 @@ int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
chan = malloc(sizeof(struct ide_channel));
- snprintf(chan->name, sizeof(chan->name),
- DEV_NAME, current_channel);
-
chan->mmio = 0;
for (j = 0; j < 8; j++)
@@ -1424,9 +1419,9 @@ int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
snprintf(nodebuff, sizeof(nodebuff), "%s/" DEV_NAME, path,
current_channel);
- REGISTER_NAMED_NODE(ob_ide_ctrl, nodebuff);
+ REGISTER_NAMED_NODE_PHANDLE(ob_ide_ctrl, nodebuff, dnode);
- dnode = find_dev(nodebuff);
+ chan->ph = dnode;
#if !defined(CONFIG_PPC) && !defined(CONFIG_SPARC64)
props[0]=14; props[1]=0;
@@ -1468,11 +1463,9 @@ int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
break;
}
IDE_DPRINTF("%s]: %s\n", media, drive->model);
- snprintf(nodebuff, sizeof(nodebuff),
- "%s/" DEV_NAME "/%s", path, current_channel,
- media);
- REGISTER_NAMED_NODE(ob_ide, nodebuff);
- dnode=find_dev(nodebuff);
+ snprintf(nodebuff, sizeof(nodebuff), "%s/%s",
+ get_path_from_ph(dnode), media);
+ REGISTER_NAMED_NODE_PHANDLE(ob_ide, nodebuff, dnode);
set_int_property(dnode, "reg", j);
/* create aliases */
@@ -1488,6 +1481,28 @@ int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
return 0;
}
+void ob_ide_quiesce(void)
+{
+ struct ide_channel *channel;
+ int i;
+
+ channel = channels;
+ while (channel) {
+ for (i = 0; i < 2; i++) {
+ struct ide_drive *drive = &channel->drives[i];
+
+ if (!drive->present)
+ continue;
+
+ ob_ide_select_drive(drive);
+ ob_ide_software_reset(drive);
+ ob_ide_device_type_check(drive);
+ }
+
+ channel = channel->next;
+ }
+}
+
#if defined(CONFIG_DRIVER_MACIO)
static unsigned char
macio_ide_inb(struct ide_channel *chan, unsigned int port)
@@ -1527,16 +1542,13 @@ int macio_ide_init(const char *path, uint32_t addr, int nb_channels)
struct ide_channel *chan;
/* IDE ports on Macs are numbered from 3.
- * Also see comments in macio.c:openpic_init() */
+ * Also see comments in pci.c:ob_pci_host_set_interrupt_map() */
current_channel = 3;
- for (i = 0; i < nb_channels; i++, current_channel++) {
+ for (i = 0; i < nb_channels; i++) {
chan = malloc(sizeof(struct ide_channel));
- snprintf(chan->name, sizeof(chan->name),
- DEV_NAME, current_channel);
-
chan->mmio = addr + MACIO_IDE_OFFSET + i * MACIO_IDE_SIZE;
chan->obide_inb = macio_ide_inb;
@@ -1574,13 +1586,19 @@ int macio_ide_init(const char *path, uint32_t addr, int nb_channels)
snprintf(nodebuff, sizeof(nodebuff), "%s/" DEV_NAME, path,
current_channel);
- REGISTER_NAMED_NODE(ob_ide_ctrl, nodebuff);
+ REGISTER_NAMED_NODE_PHANDLE(ob_ide_ctrl, nodebuff, dnode);
- dnode = find_dev(nodebuff);
+ chan->ph = dnode;
set_property(dnode, "compatible", (is_oldworld() ?
"heathrow-ata" : "keylargo-ata"), 13);
+ set_property(dnode, "model", ((current_channel == 3) ?
+ "ata-3" : "ata-4"), strlen("ata-*") + 1);
+
+ set_property(dnode, "AAPL,connector", "ata",
+ strlen("ata") + 1);
+
props[0] = 0x00000526;
props[1] = 0x00000085;
props[2] = 0x00000025;
@@ -1589,8 +1607,8 @@ int macio_ide_init(const char *path, uint32_t addr, int nb_channels)
props[5] = 0x00000000;
props[6] = 0x00000000;
props[7] = 0x00000000;
- OLDWORLD(set_property(dnode, "AAPL,pio-timing",
- (char *)&props, 8*sizeof(props[0])));
+ set_property(dnode, "AAPL,pio-timing",
+ (char *)&props, 8*sizeof(props[0]));
/* The first interrupt entry is the ide interrupt, the second
the dbdma interrupt */
@@ -1633,9 +1651,9 @@ int macio_ide_init(const char *path, uint32_t addr, int nb_channels)
OLDWORLD(set_property(dnode, "AAPL,address",
(char *)&props, 2*sizeof(props[0])));
- props[0] = 0;
- OLDWORLD(set_property(dnode, "AAPL,bus-id", (char*)props,
- 1 * sizeof(props[0])));
+ props[0] = i;
+ set_property(dnode, "AAPL,bus-id", (char*)props,
+ 1 * sizeof(props[0]));
IDE_DPRINTF(DEV_NAME": [io ports 0x%lx]\n",
current_channel, chan->mmio);
@@ -1663,11 +1681,9 @@ int macio_ide_init(const char *path, uint32_t addr, int nb_channels)
break;
}
IDE_DPRINTF("%s]: %s\n", media, drive->model);
- snprintf(nodebuff, sizeof(nodebuff),
- "%s/" DEV_NAME "/%s", path, current_channel,
- media);
- REGISTER_NAMED_NODE(ob_ide, nodebuff);
- dnode = find_dev(nodebuff);
+ snprintf(nodebuff, sizeof(nodebuff), "%s/%s",
+ get_path_from_ph(dnode), media);
+ REGISTER_NAMED_NODE_PHANDLE(ob_ide, nodebuff, dnode);
set_int_property(dnode, "reg", j);
/* create aliases */
diff --git a/qemu/roms/openbios/drivers/ide.h b/qemu/roms/openbios/drivers/ide.h
index d6c4b9f5d..8983c8ecf 100644
--- a/qemu/roms/openbios/drivers/ide.h
+++ b/qemu/roms/openbios/drivers/ide.h
@@ -167,7 +167,7 @@ struct ide_drive {
struct ide_channel {
- char name[32];
+ phandle_t ph;
struct ide_channel *next;
/*
diff --git a/qemu/roms/openbios/drivers/obio.c b/qemu/roms/openbios/drivers/obio.c
index 7c135a362..4ac063188 100644
--- a/qemu/roms/openbios/drivers/obio.c
+++ b/qemu/roms/openbios/drivers/obio.c
@@ -26,8 +26,6 @@
#define PROMDEV_SCREEN 0 /* output to screen */
#define PROMDEV_TTYA 1 /* in/out to ttya */
-/* DECLARE data structures for the nodes. */
-DECLARE_UNNAMED_NODE( ob_obio, INSTALL_OPEN, sizeof(int) );
void
ob_new_obio_device(const char *name, const char *type)
@@ -397,45 +395,6 @@ ob_smp_init(unsigned long mem_size)
}
static void
-ob_obio_open(__attribute__((unused))int *idx)
-{
- int ret=1;
- RET ( -ret );
-}
-
-static void
-ob_obio_close(__attribute__((unused))int *idx)
-{
- selfword("close-deblocker");
-}
-
-static void
-ob_obio_initialize(__attribute__((unused))int *idx)
-{
- 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");
-}
-
-static void
ob_set_obio_ranges(uint64_t base)
{
push_str("/obio");
@@ -458,27 +417,6 @@ ob_set_obio_ranges(uint64_t base)
fword("property");
}
-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) = {
- { NULL, ob_obio_initialize },
- { "open", ob_obio_open },
- { "close", ob_obio_close },
- { "encode-unit", ob_obio_encodeunit },
- { "decode-unit", ob_obio_decodeunit },
-};
-
int
ob_obio_init(uint64_t slavio_base, unsigned long fd_offset,
@@ -491,10 +429,6 @@ ob_obio_init(uint64_t slavio_base, unsigned long fd_offset,
// http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
//printk("Initializing OBIO devices...\n");
-#if 0 // XXX
- REGISTER_NAMED_NODE(ob_obio, "/obio");
- device_end();
-#endif
ob_set_obio_ranges(slavio_base);
// Zilog Z8530 serial ports, see http://www.zilog.com
diff --git a/qemu/roms/openbios/drivers/pci.c b/qemu/roms/openbios/drivers/pci.c
index 366f4a17f..5062f302f 100644
--- a/qemu/roms/openbios/drivers/pci.c
+++ b/qemu/roms/openbios/drivers/pci.c
@@ -144,9 +144,16 @@ static void dump_reg_property(const char* description, int nreg, u32 *reg)
}
#endif
-static unsigned long pci_bus_addr_to_host_addr(uint32_t ba)
+static unsigned long pci_bus_addr_to_host_addr(int space, uint32_t ba)
{
- return arch->host_pci_base + (unsigned long)ba;
+ if (space == IO_SPACE) {
+ return arch->io_base + (unsigned long)ba;
+ } else if (space == MEMORY_SPACE_32) {
+ return arch->host_pci_base + (unsigned long)ba;
+ } else {
+ /* Return unaltered to aid debugging property values */
+ return (unsigned long)ba;
+ }
}
static void
@@ -340,22 +347,27 @@ ob_pci_encode_unit(int *idx)
ss, dev, fn, buf);
}
-/* ( pci-addr.lo pci-addr.hi size -- virt ) */
+/* ( pci-addr.lo pci-addr.mid pci-addr.hi size -- virt ) */
static void
ob_pci_map_in(int *idx)
{
phys_addr_t phys;
uint32_t ba;
- ucell size, virt;
+ ucell size, virt, tmp;
+ int space;
PCI_DPRINTF("ob_pci_bar_map_in idx=%p\n", idx);
size = POP();
+ tmp = POP();
POP();
ba = POP();
- phys = pci_bus_addr_to_host_addr(ba);
+ /* Get the space from the pci-addr.hi */
+ space = ((tmp & PCI_RANGE_TYPE_MASK) >> 24);
+
+ phys = pci_bus_addr_to_host_addr(space, ba);
#if defined(CONFIG_OFMEM)
ofmem_claim_phys(phys, size, 0);
@@ -448,13 +460,18 @@ static void pci_host_set_ranges(const pci_config_t *config)
int ncells;
ncells = 0;
- /* first encode PCI configuration space */
- {
- ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
+
+#ifdef CONFIG_SPARC64
+ /* While configuration space isn't mentioned in the IEEE-1275 PCI
+ bindings, it appears in the PCI host bridge ranges property in
+ real device trees. Hence we disable this range for all host
+ bridges except for SPARC, particularly as it causes Darwin/OS X
+ to incorrectly calculated PCI memory space ranges on PPC. */
+ ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
config->dev, 0, 0);
ncells += host_encode_phys_addr(props + ncells, arch->cfg_addr);
ncells += pci_encode_size(props + ncells, arch->cfg_len);
- }
+#endif
if (arch->io_base) {
ncells += pci_encode_phys_addr(props + ncells, 0, IO_SPACE,
@@ -585,13 +602,18 @@ static void pci_set_AAPL_address(const pci_config_t *config)
{
phandle_t dev = get_cur_dev();
cell props[7];
- int ncells, i;
+ uint32_t mask;
+ int ncells, i, flags, space_code;
ncells = 0;
for (i = 0; i < 6; i++) {
if (!config->assigned[i] || !config->sizes[i])
continue;
- props[ncells++] = config->assigned[i] & ~0x0000000F;
+ pci_decode_pci_addr(config->assigned[i],
+ &flags, &space_code, &mask);
+
+ props[ncells++] = pci_bus_addr_to_host_addr(space_code,
+ config->assigned[i] & ~mask);
}
if (ncells)
set_property(dev, "AAPL,address", (char *)props,
@@ -752,13 +774,19 @@ int macio_keylargo_config_cb (const pci_config_t *config)
int vga_config_cb (const pci_config_t *config)
{
unsigned long rom;
- uint32_t rom_size, size;
+ uint32_t rom_size, size, mask;
+ int flags, space_code;
phandle_t ph;
if (config->assigned[0] != 0x00000000) {
setup_video();
- rom = pci_bus_addr_to_host_addr(config->assigned[1] & ~0x0000000F);
+ pci_decode_pci_addr(config->assigned[1],
+ &flags, &space_code, &mask);
+
+ rom = pci_bus_addr_to_host_addr(space_code,
+ config->assigned[1] & ~0x0000000F);
+
rom_size = config->sizes[1];
ph = get_cur_dev();
@@ -824,7 +852,7 @@ int ebus_config_cb(const pci_config_t *config)
ncells += pci_encode_phys_addr(props + ncells,
flags, space_code, config->dev,
PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
- 0);
+ config->assigned[i] & ~mask);
props[ncells++] = config->sizes[i];
}
@@ -997,7 +1025,10 @@ static void ob_pci_add_properties(phandle_t phandle,
}
pci_set_assigned_addresses(phandle, config, num_bars);
- OLDWORLD(pci_set_AAPL_address(config));
+
+ if (is_apple()) {
+ pci_set_AAPL_address(config);
+ }
PCI_DPRINTF("\n");
}
@@ -1397,9 +1428,11 @@ static void ob_pci_set_available(phandle_t host, unsigned long mem_base, unsigne
static void ob_pci_host_set_interrupt_map(phandle_t host)
{
- phandle_t dnode = 0;
- u32 props[128];
- int i;
+ phandle_t dnode = 0, pci_childnode = 0;
+ u32 props[128], intno;
+ int i, ncells, len;
+ u32 *val, addr;
+ char *reg;
#if defined(CONFIG_PPC)
phandle_t target_node;
@@ -1420,16 +1453,22 @@ static void ob_pci_host_set_interrupt_map(phandle_t host)
target_node = find_dev("/pci/mac-io/escc/ch-b");
set_int_property(target_node, "interrupt-parent", dnode);
+ target_node = find_dev("/pci/mac-io/escc-legacy/ch-a");
+ set_int_property(target_node, "interrupt-parent", dnode);
+
+ target_node = find_dev("/pci/mac-io/escc-legacy/ch-b");
+ set_int_property(target_node, "interrupt-parent", dnode);
+
/* QEMU only emulates 2 of the 3 ata buses currently */
/* On a new world Mac these are not numbered but named by the
* ATA version they support. Thus we have: ata-3, ata-3, ata-4
* On g3beige they all called just ide.
- * We take ata-3 and ata-4 which seems to work for both
- * at least for clients we care about */
- target_node = find_dev("/pci/mac-io/ata-3");
+ * We take 2 x ata-3 buses which seems to work for
+ * at least the clients we care about */
+ target_node = find_dev("/pci/mac-io/ata-3@20000");
set_int_property(target_node, "interrupt-parent", dnode);
- target_node = find_dev("/pci/mac-io/ata-4");
+ target_node = find_dev("/pci/mac-io/ata-3@21000");
set_int_property(target_node, "interrupt-parent", dnode);
target_node = find_dev("/pci/mac-io/via-cuda");
@@ -1437,69 +1476,61 @@ static void ob_pci_host_set_interrupt_map(phandle_t host)
target_node = find_dev("/pci");
set_int_property(target_node, "interrupt-parent", dnode);
-
- /* openpic interrupt mapping */
- for (i = 0; i < (7*8); i += 7) {
- props[i + PCI_INT_MAP_PCI0] = 0;
- props[i + PCI_INT_MAP_PCI1] = 0;
- props[i + PCI_INT_MAP_PCI2] = 0;
- props[i + PCI_INT_MAP_PCI_INT] = (i / 7) + 1; // starts at PINA=1
- props[i + PCI_INT_MAP_PIC_HANDLE] = dnode;
- props[i + PCI_INT_MAP_PIC_INT] = arch->irqs[i / 7];
- props[i + PCI_INT_MAP_PIC_POL] = 3;
- }
- set_property(host, "interrupt-map", (char *)props, 7 * 8 * sizeof(props[0]));
-
- props[PCI_INT_MAP_PCI0] = 0;
- props[PCI_INT_MAP_PCI1] = 0;
- props[PCI_INT_MAP_PCI2] = 0;
- props[PCI_INT_MAP_PCI_INT] = 0x7;
-
- set_property(host, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0]));
}
-#elif defined(CONFIG_SPARC64)
- int ncells, len;
- u32 *val, addr;
- char *reg;
+#else
+ /* PCI host bridge is the default interrupt controller */
+ dnode = host;
+#endif
/* Set interrupt-map for PCI devices with an interrupt pin present */
ncells = 0;
PUSH(host);
fword("child");
- dnode = POP();
- while (dnode) {
- if (get_int_property(dnode, "interrupts", &len)) {
- reg = get_property(dnode, "reg", &len);
- if (reg) {
+ pci_childnode = POP();
+ while (pci_childnode) {
+ intno = get_int_property(pci_childnode, "interrupts", &len);
+ if (len && intno) {
+ reg = get_property(pci_childnode, "reg", &len);
+ if (len && reg) {
val = (u32 *)reg;
for (i = 0; i < (len / sizeof(u32)); i += 5) {
addr = val[i];
/* Device address is in 1st 32-bit word of encoded PCI address for config space */
- if (!(addr & 0x03000000)) {
+ if ((addr & PCI_RANGE_TYPE_MASK) == PCI_RANGE_CONFIG) {
+#if defined(CONFIG_SPARC64)
ncells += pci_encode_phys_addr(props + ncells, 0, 0, addr, 0, 0);
- props[ncells++] = 1; /* always interrupt pin 1 for QEMU */
- props[ncells++] = host;
- props[ncells++] = SUN4U_INTERRUPT(addr, 1);
+ props[ncells++] = intno;
+ props[ncells++] = dnode;
+ props[ncells++] = SUN4U_INTERRUPT(addr, intno);
+#elif defined(CONFIG_PPC)
+ ncells += pci_encode_phys_addr(props + ncells, 0, 0, addr, 0, 0);
+ props[ncells++] = intno;
+ props[ncells++] = dnode;
+ props[ncells++] = arch->irqs[intno - 1];
+ props[ncells++] = 3;
+#else
+ /* Keep compiler quiet */
+ dnode = dnode;
+#endif
}
}
}
}
- PUSH(dnode);
+ PUSH(pci_childnode);
fword("peer");
- dnode = POP();
+ pci_childnode = POP();
}
set_property(host, "interrupt-map", (char *)props, ncells * sizeof(props[0]));
props[0] = 0x0000f800;
props[1] = 0x0;
props[2] = 0x0;
- props[3] = 7;
+ props[3] = 0x7;
set_property(host, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0]));
-#endif
}
int ob_pci_init(void)
diff --git a/qemu/roms/openbios/drivers/pci.fs b/qemu/roms/openbios/drivers/pci.fs
index 563b652a4..a7b56e1f8 100644
--- a/qemu/roms/openbios/drivers/pci.fs
+++ b/qemu/roms/openbios/drivers/pci.fs
@@ -12,59 +12,19 @@
rot encode-int encode+
;
-\ Get region offset for BAR reg
-: pci-bar-offset@ ( bar-reg -- off.lo off.hi -1 | 0 )
- " reg" active-package get-package-property 0= if
- begin
- decode-phys \ ( reg prop prop-len phys.lo phys.mid phys.hi )
- ff and 5 pick = if
- >r >r 3drop r> r>
- -1 exit
- else
- 2drop
- then
- \ Drop the size as we don't need it
- decode-int drop decode-int drop
- dup 0=
- until
- 3drop
- 0 exit
- else
- 0
- then
- ;
-
-\ Get region size for BAR reg
-: pci-bar-size@ ( bar-reg -- size )
- " reg" active-package get-package-property 0= if
- begin
- decode-phys \ ( reg prop prop-len phys.lo phys.mid phys.hi )
- ff and 5 pick = if
- 2drop decode-int drop
- decode-int
- >r 3drop r>
- exit
- else
- 2drop decode-int drop
- decode-int drop
- then
- dup 0=
- until
- 3drop
- 0 \ default size of 0 if BAR not found
- then
- ;
-
-\ Get base address for configured BAR reg
-: pci-bar-base@ ( bar-reg -- addr.lo addr.hi -1 | 0 )
+\ Get PCI physical address and size for configured BAR reg
+: pci-bar>pci-addr ( bar-reg -- addr.lo addr.mid addr.hi size -1 | 0 )
" assigned-addresses" active-package get-package-property 0= if
begin
decode-phys \ ( reg prop prop-len phys.lo phys.mid phys.hi )
- ff and 5 pick = if
- >r >r 3drop r> r>
+ dup ff and 6 pick = if
+ >r >r >r rot drop
+ decode-int drop decode-int
+ -rot 2drop
+ r> swap r> r> rot
-1 exit
else
- 2drop
+ 3drop
then
\ Drop the size as we don't need it
decode-int drop decode-int drop
@@ -77,16 +37,4 @@
then
;
-\ Get PCI bus address and size for configured BAR reg
-: pci-bar>pci-region ( bar-reg -- addr.lo addr.hi size )
- dup
- >r pci-bar-offset@ if
- swap r@ pci-bar-base@ if
- swap d+
- then
- swap r@ pci-bar-size@
- then
- r> drop
- ;
-
[THEN]
diff --git a/qemu/roms/openbios/drivers/pci.h b/qemu/roms/openbios/drivers/pci.h
index 84a2b2cf6..d5aa5f84a 100644
--- a/qemu/roms/openbios/drivers/pci.h
+++ b/qemu/roms/openbios/drivers/pci.h
@@ -59,6 +59,15 @@
#define PCI_MIN_GNT 0x3e /* 8 bits */
#define PCI_MAX_LAT 0x3f /* 8 bits */
+#define PCI_RANGE_RELOCATABLE 0x80000000
+#define PCI_RANGE_PREFETCHABLE 0x40000000
+#define PCI_RANGE_ALIASED 0x20000000
+#define PCI_RANGE_TYPE_MASK 0x03000000
+#define PCI_RANGE_MMIO_64BIT 0x03000000
+#define PCI_RANGE_MMIO 0x02000000
+#define PCI_RANGE_IOPORT 0x01000000
+#define PCI_RANGE_CONFIG 0x00000000
+
typedef struct {
u16 signature;
u8 reserved[0x16];
diff --git a/qemu/roms/openbios/drivers/sbus.c b/qemu/roms/openbios/drivers/sbus.c
index a9b26c0a0..4caa59aaf 100644
--- a/qemu/roms/openbios/drivers/sbus.c
+++ b/qemu/roms/openbios/drivers/sbus.c
@@ -369,31 +369,6 @@ sbus_probe_slot_ss600mp(unsigned int slot, uint64_t base)
}
}
-static void
-ob_sbus_open(void)
-{
- int ret=1;
- RET ( -ret );
-}
-
-static void
-ob_sbus_close(void)
-{
- selfword("close-deblocker");
-}
-
-static void
-ob_sbus_initialize(void)
-{
-}
-
-
-NODE_METHODS(ob_sbus_node) = {
- { NULL, ob_sbus_initialize },
- { "open", ob_sbus_open },
- { "close", ob_sbus_close },
-};
-
struct sbus_offset {
int slot, type;
uint64_t base;
diff --git a/qemu/roms/openbios/drivers/usbohci_private.h b/qemu/roms/openbios/drivers/usbohci_private.h
index b3a723e21..99c964100 100644
--- a/qemu/roms/openbios/drivers/usbohci_private.h
+++ b/qemu/roms/openbios/drivers/usbohci_private.h
@@ -43,7 +43,7 @@
// FIXME: fake
typedef enum { CMD} reg;
- enum {
+ extern enum {
NumberDownstreamPorts = 1<<0,
PowerSwitchingMode = 1<<8,
NoPowerSwitching = 1<<9,
@@ -53,17 +53,17 @@
PowerOnToPowerGoodTime = 1<<24
} HcRhDescriptorAReg;
- enum {
+ extern enum {
NumberDownstreamPortsMask = MASK(0, 8),
PowerOnToPowerGoodTimeMask = MASK(24, 8)
} HcRhDescriptorAMask;
- enum {
+ extern enum {
DeviceRemovable = 1<<0,
PortPowerControlMask = 1<<16
} HcRhDescriptorBReg;
- enum {
+ extern enum {
CurrentConnectStatus = 1<<0,
PortEnableStatus = 1<<1,
PortSuspendStatus = 1<<2,
@@ -77,7 +77,7 @@
PortOverCurrentIndicatorChange = 1<<19,
PortResetStatusChange = 1<<20
} HcRhPortStatusRead;
- enum {
+ extern enum {
ClearPortEnable = 1<<0,
SetPortEnable = 1<<1,
SetPortSuspend = 1<<2,
@@ -87,7 +87,7 @@
ClearPortPower = 1<<9,
} HcRhPortStatusSet;
- enum {
+ extern enum {
LocalPowerStatus = 1<<0,
OverCurrentIndicator = 1<<1,
DeviceRemoteWakeupEnable = 1<<15,
@@ -96,18 +96,18 @@
ClearRemoteWakeupEnable = 1<<31
} HcRhStatusReg;
- enum {
+ extern enum {
FrameInterval = 1<<0,
FSLargestDataPacket = 1<<16,
FrameIntervalToggle = 1<<31
} HcFmIntervalOffset;
- enum {
+ extern enum {
FrameIntervalMask = MASK(0, 14),
FSLargestDataPacketMask = MASK(16, 15),
FrameIntervalToggleMask = MASK(31, 1)
} HcFmIntervalMask;
- enum {
+ extern enum {
ControlBulkServiceRatio = 1<<0,
PeriodicListEnable = 1<<2,
IsochronousEnable = 1<<3,
@@ -119,7 +119,7 @@
RemoteWakeupEnable = 1<<10
} HcControlReg;
- enum {
+ extern enum {
ControlBulkServiceRatioMask = MASK(0, 2),
HostControllerFunctionalStateMask = MASK(6, 2)
} HcControlMask;
@@ -131,7 +131,7 @@
USBSuspend = 3*HostControllerFunctionalState
};
- enum {
+ extern enum {
HostControllerReset = 1<<0,
ControlListFilled = 1<<1,
BulkListFilled = 1<<2,
@@ -139,16 +139,16 @@
SchedulingOverrunCount = 1<<16
} HcCommandStatusReg;
- enum {
+ extern enum {
SchedulingOverrunCountMask = MASK(16, 2)
} HcCommandStatusMask;
- enum {
+ extern enum {
FrameRemaining = 1<<0,
FrameRemainingToggle = 1<<31
} HcFmRemainingReg;
- enum {
+ extern enum {
SchedulingOverrung = 1<<0,
WritebackDoneHead = 1<<1,
StartofFrame = 1<<2,
diff --git a/qemu/roms/openbios/drivers/vga.fs b/qemu/roms/openbios/drivers/vga.fs
index ec4c6c5f1..29a043a7a 100644
--- a/qemu/roms/openbios/drivers/vga.fs
+++ b/qemu/roms/openbios/drivers/vga.fs
@@ -109,16 +109,17 @@ h# 1 constant VBE_DISPI_ENABLED
\ PCI
\
-" pci-bar>pci-region" (find-xt) value pci-bar>pci-region-xt
-: pci-bar>pci-region pci-bar>pci-region-xt execute ;
+" pci-bar>pci-addr" (find-xt) value pci-bar>pci-addr-xt
+: pci-bar>pci-addr pci-bar>pci-addr-xt execute ;
h# 10 constant cfg-bar0 \ Framebuffer BAR
-1 value fb-addr
: map-fb ( -- )
- cfg-bar0 pci-bar>pci-region \ ( pci-addr.lo pci-addr.hi size )
- " pci-map-in" $call-parent
- to fb-addr
+ cfg-bar0 pci-bar>pci-addr if \ ( pci-addr.lo pci-addr.mid pci-addr.hi size )
+ " pci-map-in" $call-parent
+ to fb-addr
+ then
;
\
diff --git a/qemu/roms/openbios/forth/lib/string.fs b/qemu/roms/openbios/forth/lib/string.fs
index eb6474917..f97db232f 100644
--- a/qemu/roms/openbios/forth/lib/string.fs
+++ b/qemu/roms/openbios/forth/lib/string.fs
@@ -125,3 +125,17 @@
: parse-hex ( str len -- value )
base @ hex -rot $number if 0 then swap base !
;
+
+
+\ -----------------------------------------------------
+\ miscellaneous functions
+\ -----------------------------------------------------
+
+: rot13 ( c - c )
+ dup upc [char] A [char] M between if d# 13 + exit then
+ dup upc [char] N [char] Z between if d# 13 - then
+;
+
+: rot13-str ( str len -- newstr len )
+ strdup 2dup bounds ?do i c@ rot13 i c! loop
+;
diff --git a/qemu/roms/openbios/forth/system/ciface.fs b/qemu/roms/openbios/forth/system/ciface.fs
index fd6c54efd..85a607627 100644
--- a/qemu/roms/openbios/forth/system/ciface.fs
+++ b/qemu/roms/openbios/forth/system/ciface.fs
@@ -326,6 +326,14 @@ external
: exit ( -- )
." EXIT"
+
+ \ Execute (exit) hook if one exists
+ s" (exit)" $find if
+ execute
+ else
+ 2drop
+ then
+
outer-interpreter
;
diff --git a/qemu/roms/openbios/include/arch/ppc/types.h b/qemu/roms/openbios/include/arch/ppc/types.h
index 69b3db405..b2246d060 100644
--- a/qemu/roms/openbios/include/arch/ppc/types.h
+++ b/qemu/roms/openbios/include/arch/ppc/types.h
@@ -84,21 +84,13 @@ typedef uint32_t prom_uarg_t;
/* size named types */
typedef unsigned char u8;
-typedef unsigned char __u8;
typedef unsigned short u16;
-typedef unsigned short __u16;
typedef unsigned int u32;
-typedef unsigned int __u32;
typedef unsigned long long u64;
-typedef unsigned long long __u64;
typedef signed char s8;
-typedef signed char __s8;
typedef short s16;
-typedef short __s16;
typedef int s32;
-typedef int __s32;
typedef long long s64;
-typedef long long __s64;
#endif
diff --git a/qemu/roms/openbios/include/arch/sparc64/io.h b/qemu/roms/openbios/include/arch/sparc64/io.h
index 2e4dfa37f..0f1a73284 100644
--- a/qemu/roms/openbios/include/arch/sparc64/io.h
+++ b/qemu/roms/openbios/include/arch/sparc64/io.h
@@ -9,7 +9,7 @@
extern unsigned long va_shift; // Set in entry.S
// Defined in ldscript
-extern char _start, _data, _stack, _estack, _end, _iomem;
+extern char _start, _data, _stack, _estack, _fcstack, _efcstack, _end, _iomem;
// XXX check use and merge
#define phys_to_virt(phys) ((void *) ((unsigned long) (phys)))
diff --git a/qemu/roms/openbios/include/drivers/drivers.h b/qemu/roms/openbios/include/drivers/drivers.h
index 3b83b12d1..48f81a870 100644
--- a/qemu/roms/openbios/include/drivers/drivers.h
+++ b/qemu/roms/openbios/include/drivers/drivers.h
@@ -52,6 +52,7 @@ void kbd_init(uint64_t base);
/* drivers/ide.c */
int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
uint32_t io_port1, uint32_t ctl_port1);
+void ob_ide_quiesce(void);
int macio_ide_init(const char *path, uint32_t addr, int nb_channels);
#endif
#ifdef CONFIG_DRIVER_ESP
diff --git a/qemu/roms/openbios/include/libopenbios/bindings.h b/qemu/roms/openbios/include/libopenbios/bindings.h
index de9c77520..4ec978912 100644
--- a/qemu/roms/openbios/include/libopenbios/bindings.h
+++ b/qemu/roms/openbios/include/libopenbios/bindings.h
@@ -56,6 +56,7 @@ extern ihandle_t open_package( const char *argstr, phandle_t ph );
extern ihandle_t open_dev( const char *spec );
extern void close_package( ihandle_t ih );
extern void close_dev( ihandle_t ih );
+extern char *get_path_from_ph( phandle_t ph );
/* property access */
extern void set_property( phandle_t ph, const char *name,
diff --git a/qemu/roms/openbios/libopenbios/bindings.c b/qemu/roms/openbios/libopenbios/bindings.c
index 5323421f5..4f7a99379 100644
--- a/qemu/roms/openbios/libopenbios/bindings.c
+++ b/qemu/roms/openbios/libopenbios/bindings.c
@@ -366,6 +366,14 @@ find_dev( const char *path )
return ret;
}
+char *
+get_path_from_ph( phandle_t ph )
+{
+ PUSH(ph);
+ fword("get-package-path");
+ return pop_fstr_copy();
+}
+
phandle_t
dt_iter_begin( void )
{
diff --git a/qemu/roms/openbios/libopenbios/bootinfo_load.c b/qemu/roms/openbios/libopenbios/bootinfo_load.c
index fa9e36bd4..f33678185 100644
--- a/qemu/roms/openbios/libopenbios/bootinfo_load.c
+++ b/qemu/roms/openbios/libopenbios/bootinfo_load.c
@@ -161,6 +161,12 @@ bootinfo_init_program(void)
feval("load-size");
size = POP();
+ /* Some bootinfo scripts contain a binary payload after the
+ NULL-terminated Forth string such as OS 9. Restrict our
+ size to just the Forth section, otherwise we end up trying
+ to allocate memory for the entire binary which might fail. */
+ size = strnlen(base, size);
+
bootscript = malloc(size);
if (bootscript == NULL) {
DPRINTF("Can't malloc %d bytes\n", size);