Following on from the previous work, this patchset gets tantalisingly close to bringing up a 64-bit Milax (OpenSolaris) kernel under qemu-system-sparc64:
$ ./qemu-system-sparc64 -bios openbios-builtin.elf.nostrip -cdrom milax032sparc.iso -nographic -boot d -m 256 OpenBIOS for Sparc64 Configuration device id QEMU version 1 machine id 0 kernel cmdline CPUs: 1 x SUNW,UltraSPARC-IIi UUID: 00000000-0000-0000-0000-000000000000 Welcome to OpenBIOS v1.1 built on Oct 23 2016 13:36 Type 'help' for detailed information Trying cdrom:f... Not a bootable ELF image Not a bootable a.out image
Loading FCode image... Loaded 7084 bytes entry point is 0x4000 Evaluating FCode... Evaluating FCode... Ignoring failed claim for va 1000000 memsz bf34e! Ignoring failed claim for va 1402000 memsz 303b3! Ignoring failed claim for va 1800000 memsz 60a30! SunOS Release 5.11 Version MilaX_0.3.2 64-bit Copyright 1983-2008 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. could not find debugger-vocabulary-hook>threads:interpret: exception -13 caught interpret \ ident "%Z%%M% %I% %E% SMI" \ Copyright 2005 Sun Microsystems, Inc. All rights reserved. \ Use is subject to license terms. \ \ CDDL HEADER START \ \ The contents of this file are subject to the terms of the \ Common Development and Distribution License, Version 1.0 only \ (the "License"). You may not use this file except in compliance \ with the License. \ \ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE \ or http://www.opensolaris.org/os/licensing. \ See the License for unix-tte:interpret: exception -13 caught interpret ' unix-tte is va>tte-data failed with error ffffffffffffffed WARNING: consconfig: cannot find driver for screen device /pci@1fe,0/QEMU,VGA@2 Remounting root read/write Probing for device nodes ... WARNING: pcipsy0: unable to map reg entry 1
Preparing live image for use WARNING: pcipsy0: unable to map reg entry 1
WARNING: pcipsy0: unable to map reg entry 1
Hostname: milax Requesting System Maintenance Mode (See /lib/svc/share/README for more information.) Console login service(s) cannot run
Root password for system maintenance (control-d to bypass):
Sadly at this point the console (and eventually QEMU) lock up hard which suggests an emulation bug hiding away somewhere, and I do occasionally see intermittent kernel panics on boot.
Having said that, this is still a significant milestone :)
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
Mark Cave-Ayland (9): SPARC64: add %tba to saved state context SPARC64: make sure globals are stored in the CPU context during I/D MMU traps SPARC64: comment out the context switch debug message SPARC64: increase Forth machine memory to 192K SPARC64: add support for kmdb kernel debugger SPARC64: add spacec@, spacew@, spacel@ and spacex@ Forth words SPARC64: set up small iomem region for memory-mapped devices SPARC64: memory map mk48t59 RTC and store its address in the device tree SPARC64: ensure the E (effect) bit is set for PROM TTE entries
arch/sparc64/boot.h | 1 + arch/sparc64/call-client.S | 12 --- arch/sparc64/context.c | 2 +- arch/sparc64/context.h | 4 +- arch/sparc64/cpu.fs | 11 ++- arch/sparc64/cpustate.h | 13 ++- arch/sparc64/entry.S | 9 +- arch/sparc64/ldscript | 2 +- arch/sparc64/lib.c | 7 ++ arch/sparc64/ofmem_sparc64.c | 8 +- arch/sparc64/openbios.c | 144 ++++++++++++++++++++++++++++++- arch/sparc64/spitfire.h | 1 + arch/sparc64/vectors.S | 196 +++++++++++++++++++++++++++++++++++++++++- drivers/pci.c | 14 +++ 14 files changed, 387 insertions(+), 37 deletions(-)
This means we can remove the client_tba hack in the CIF prologue and also use the full SAVE_CPU_STATE() macro for entry.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/call-client.S | 12 ------------ arch/sparc64/context.h | 4 +++- arch/sparc64/cpu.fs | 4 +++- arch/sparc64/cpustate.h | 13 +++++++++---- arch/sparc64/entry.S | 3 +-- arch/sparc64/openbios.c | 9 +++++---- 6 files changed, 21 insertions(+), 24 deletions(-)
diff --git a/arch/sparc64/call-client.S b/arch/sparc64/call-client.S index ebab6b9..4129505 100644 --- a/arch/sparc64/call-client.S +++ b/arch/sparc64/call-client.S @@ -18,8 +18,6 @@ client_context: .xword 0 client_stack: .xword 0 -client_tba: - .xword 0 client_window: .skip 2048
@@ -46,11 +44,6 @@ sparc64_of_client_interface: stx %g6, [%sp + 2047 - 248 + 232] stx %g7, [%sp + 2047 - 248 + 240]
- /* Save client trap table */ - setx client_tba, %g6, %g7 - rdpr %tba, %g6 - stx %g6, [%g7] - /* Save existing stack */ setx client_stack, %g6, %g7 stx %sp, [%g7] @@ -133,11 +126,6 @@ sparc64_of_client_interface: /* Restore stack */ setx client_stack, %g6, %g7 ldx [%g7], %sp - - /* Restore client trap table */ - setx client_tba, %g6, %g7 - ldx [%g7], %g6 - wrpr %g6, %tba /* Restore %pc */ ldx [%g1 + 0x4d0], %o7 diff --git a/arch/sparc64/context.h b/arch/sparc64/context.h index a047b9c..eb189fb 100644 --- a/arch/sparc64/context.h +++ b/arch/sparc64/context.h @@ -11,7 +11,9 @@ struct context { #define REG_O0 14 #define REG_SP 20 #define SP_LOC(ctx) (&(ctx)->regs[REG_SP]) - uint64_t tregs[20]; + uint64_t tba; + uint64_t _pad; + uint64_t tregs[16]; /* Flags */ /* Optional stack contents */ uint64_t return_addr; diff --git a/arch/sparc64/cpu.fs b/arch/sparc64/cpu.fs index b0aa611..5a8f8d6 100644 --- a/arch/sparc64/cpu.fs +++ b/arch/sparc64/cpu.fs @@ -3,9 +3,10 @@ include config.fs \ SPARC64 trap registers
: %tl-c saved-context h# c8 + @ ; +: %tba saved-context h# 4e0 + @ ;
: tl-offset ( level -- offset ) - h# 20 * h# 4e0 h# 60 + swap - ; + h# 20 * h# 4f0 h# 60 + swap - ; ;
: %tpc ( level -- n ) tl-offset saved-context + @ ; @@ -15,6 +16,7 @@ include config.fs
: .trap-registers cr + s" %tba: " type %tba u. cr s" %tl-c: " type %tl-c u. cr s" %tpc: " type %tl-c %tpc u. cr s" %tnpc: " type %tl-c %tnpc u. cr diff --git a/arch/sparc64/cpustate.h b/arch/sparc64/cpustate.h index cff7733..b4695ad 100644 --- a/arch/sparc64/cpustate.h +++ b/arch/sparc64/cpustate.h @@ -12,7 +12,7 @@ #include "autoconf.h"
/* State size for context (see below) */ -#define CONTEXT_STATE_SIZE 0x560 +#define CONTEXT_STATE_SIZE 0x570
/* Stack size for context (allocated inline of the context stack) */ #define CONTEXT_STACK_SIZE 0x2000 @@ -135,7 +135,9 @@ save_cpu_window_##type: \
#define SAVE_CPU_TRAP_STATE(type) \ /* Save trap state into context at %g1 */ \ - add %g1, 0x4e0, %g5; \ + rdpr %tba, %g5; \ + stx %g5, [%g1 + 0x4e0]; \ + add %g1, 0x4f0, %g5; \ mov 4, %g6; \ \ /* Save current trap level */ \ @@ -246,7 +248,7 @@ restore_cpu_window_##type: \
#define RESTORE_CPU_TRAP_STATE(type) \ /* Restore trap state from context at %g1 */ \ - add %g1, 0x4e0, %g5; \ + add %g1, 0x4f0, %g5; \ mov 4, %g6; \ \ restore_trap_state_##type: \ @@ -264,7 +266,10 @@ restore_trap_state_##type: \ add %g5, 0x20, %g5; \ \ ldx [%g1 + 0xc8], %g7; \ - wrpr %g7, %tl + wrpr %g7, %tl; \ + ldx [%g1 + 0x4e0], %g7; \ + wrpr %g7, %tba +
/* Restore all state from context at %g1 */ #define RESTORE_CPU_STATE(type) \ diff --git a/arch/sparc64/entry.S b/arch/sparc64/entry.S index 3a46d89..47d1139 100644 --- a/arch/sparc64/entry.S +++ b/arch/sparc64/entry.S @@ -269,8 +269,7 @@ lowmem: setx __context, %g2, %g1 ldx [%g1], %g1
- SAVE_CPU_GENERAL_STATE(entry) - SAVE_CPU_WINDOW_STATE(entry) + SAVE_CPU_STATE(entry)
/* Set up local stack pointer */ setx _estack - 2047, %o2, %sp diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c index 9a1d56c..3b7bc46 100644 --- a/arch/sparc64/openbios.c +++ b/arch/sparc64/openbios.c @@ -10,6 +10,8 @@ #include "libopenbios/openbios.h" #include "libopenbios/bindings.h" #include "libopenbios/console.h" +#include "context.h" +#include "libopenbios/initprogram.h" #include "drivers/drivers.h" #include "dict.h" #include "arch/common/nvram.h" @@ -89,17 +91,16 @@ struct cpudef { ( addr -- ? ) */
-extern volatile uint64_t client_tba; - static void set_trap_table(void) { unsigned long addr; + volatile struct context *ctx = __context;
addr = POP();
- /* Update client_tba to be updated on CIF exit */ - client_tba = addr; + /* Update %tba to be updated on exit */ + ctx->tba = (uint64_t)addr; }
/* Reset control register is defined in 17.2.7.3 of US IIi User Manual */
During I/D MMU traps, the CPU switches to the alternate memory globals. Hence we must manually switch to the original globals when saving/restoring state.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/vectors.S | 76 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-)
diff --git a/arch/sparc64/vectors.S b/arch/sparc64/vectors.S index fa30546..85399df 100644 --- a/arch/sparc64/vectors.S +++ b/arch/sparc64/vectors.S @@ -284,6 +284,10 @@ tl1_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8) obp_ticks_pointer: .xword 0
+ ! Saved context state +debug_context: + .xword 0 + .section ".text", "ax"
spill_32bit: @@ -343,6 +347,23 @@ reload_DMMU_tlb: RESET_CPU_WINDOW_STATE(dtlb) + /* Switch to ordinary globals, saving to context */ + mov %g1, %o1 + rdpr %pstate, %o2 + andn %o2, PSTATE_MG, %o2 + wrpr %o2, %pstate + + stx %g1, [%o1 + 0x30] + stx %g2, [%o1 + 0x38] + stx %g3, [%o1 + 0x40] + stx %g4, [%o1 + 0x48] + stx %g5, [%o1 + 0x50] + stx %g6, [%o1 + 0x58] + stx %g7, [%o1 + 0x60] + + /* Copy context back to %g1 */ + mov %o1, %g1 + /* 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) */ setx _fcstack_ptr, %g6, %g7 @@ -375,6 +396,22 @@ reload_DMMU_tlb: add %g1, %g5, %g1 stx %g1, [%g7] + /* Restore ordinary globals, switch back to memory globals */ + mov %g1, %o1 + rdpr %pstate, %o2 + or %o2, PSTATE_MG, %o2 + + ldx [%o1 + 0x30], %g1 + ldx [%o1 + 0x38], %g2 + ldx [%o1 + 0x40], %g3 + ldx [%o1 + 0x48], %g4 + ldx [%o1 + 0x50], %g5 + ldx [%o1 + 0x58], %g6 + ldx [%o1 + 0x60], %g7 + + wrpr %o2, %pstate + mov %o1, %g1 + RESTORE_CPU_STATE(dtlb) setx _fcstack_ptr, %g6, %g7 @@ -382,7 +419,7 @@ reload_DMMU_tlb: add %g1, CONTEXT_STATE_SIZE, %g1 stx %g1, [%g7] - retry + retry
reload_IMMU_tlb: @@ -396,6 +433,23 @@ reload_IMMU_tlb: RESET_CPU_WINDOW_STATE(itlb) + /* Switch to ordinary globals, saving to context */ + mov %g1, %o1 + rdpr %pstate, %o2 + andn %o2, PSTATE_MG, %o2 + wrpr %o2, %pstate + + stx %g1, [%o1 + 0x30] + stx %g2, [%o1 + 0x38] + stx %g3, [%o1 + 0x40] + stx %g4, [%o1 + 0x48] + stx %g5, [%o1 + 0x50] + stx %g6, [%o1 + 0x58] + stx %g7, [%o1 + 0x60] + + /* Copy context back to %g1 */ + mov %o1, %g1 + /* 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) */ setx _fcstack_ptr, %g6, %g7 @@ -428,14 +482,30 @@ reload_IMMU_tlb: add %g1, %g5, %g1 stx %g1, [%g7] + /* Restore ordinary globals, switch back to memory globals */ + mov %g1, %o1 + rdpr %pstate, %o2 + or %o2, PSTATE_MG, %o2 + + ldx [%o1 + 0x30], %g1 + ldx [%o1 + 0x38], %g2 + ldx [%o1 + 0x40], %g3 + ldx [%o1 + 0x48], %g4 + ldx [%o1 + 0x50], %g5 + ldx [%o1 + 0x58], %g6 + ldx [%o1 + 0x60], %g7 + + wrpr %o2, %pstate + mov %o1, %g1 + RESTORE_CPU_STATE(itlb) setx _fcstack_ptr, %g6, %g7 ldx [%g7], %g1 add %g1, CONTEXT_STATE_SIZE, %g1 stx %g1, [%g7] - - retry + + retry
softint_irq_tl1: softint_irq:
Debugging under kmdb is constantly switching context upon entry/exit which causes a lot of noise on the console.
This matches all other archs which don't emit a similar message upon switch.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/sparc64/context.c b/arch/sparc64/context.c index 30b19ea..48dae3d 100644 --- a/arch/sparc64/context.c +++ b/arch/sparc64/context.c @@ -127,7 +127,7 @@ struct context *switch_to(struct context *ctx) volatile struct context *save; struct context *ret;
- debug("switching to new context: entry point %#llx stack 0x%016llx\n", ctx->pc, ctx->regs[REG_SP]); + //debug("switching to new context: entry point %#llx stack 0x%016llx\n", ctx->pc, ctx->regs[REG_SP]); save = __context; __context = ctx; //asm ("pushl %cs; call __switch_context");
Otherwise when trying to boot Milax with a debugger we run out of memory.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/ofmem_sparc64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/sparc64/ofmem_sparc64.c b/arch/sparc64/ofmem_sparc64.c index 5c742cd..1711c7e 100644 --- a/arch/sparc64/ofmem_sparc64.c +++ b/arch/sparc64/ofmem_sparc64.c @@ -20,7 +20,7 @@
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
-#define MEMSIZE (128 * 1024) +#define MEMSIZE (192 * 1024) static union { char memory[MEMSIZE]; ofmem_t ofmem;
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/boot.h | 1 + arch/sparc64/cpu.fs | 7 +++ arch/sparc64/lib.c | 7 +++ arch/sparc64/vectors.S | 122 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 135 insertions(+), 2 deletions(-)
diff --git a/arch/sparc64/boot.h b/arch/sparc64/boot.h index fef0573..e1b8717 100644 --- a/arch/sparc64/boot.h +++ b/arch/sparc64/boot.h @@ -27,3 +27,4 @@ void cls(void);
// lib.c void ob_mmu_init(const char *cpuname, uint64_t ram_size); +void prom_debug_handler(void); diff --git a/arch/sparc64/cpu.fs b/arch/sparc64/cpu.fs index 5a8f8d6..45dca2d 100644 --- a/arch/sparc64/cpu.fs +++ b/arch/sparc64/cpu.fs @@ -154,5 +154,12 @@ include config.fs .globals .locals ;
+\ Debugger support +defer debugger-hook + +: init-debugger-hook ( xt ) + dup to debugger-hook +; + \ Used by Milax variable warning diff --git a/arch/sparc64/lib.c b/arch/sparc64/lib.c index 4709ca8..e9fff28 100644 --- a/arch/sparc64/lib.c +++ b/arch/sparc64/lib.c @@ -282,6 +282,13 @@ itlb_miss_handler(void) } }
+void +prom_debug_handler(void) +{ + /* Execute the current debugger-hook */ + feval("debugger-hook"); +} + /* 3.6.5 map ( phys.lo ... phys.hi virt size mode -- ) diff --git a/arch/sparc64/vectors.S b/arch/sparc64/vectors.S index 85399df..b66f0d2 100644 --- a/arch/sparc64/vectors.S +++ b/arch/sparc64/vectors.S @@ -182,7 +182,11 @@ tl0_resv130: BTRAPS(0x130) BTRAPS(0x138) tl0_resv140: BTRAPS(0x140) BTRAPS(0x148) tl0_resv150: BTRAPS(0x150) BTRAPS(0x158) tl0_resv160: BTRAPS(0x160) BTRAPS(0x168) -tl0_resv170: BTRAPS(0x170) BTRAPS(0x178) +tl0_resv170: BTRAPS(0x170) BTRAPS4(0x178) + BTRAP(0x17c) + TRAP_HANDLER(prom_debug) ! 0x17d : debugger + TRAP_HANDLER(prom_debug) ! 0x17e : debugger breakpoint + BTRAP(0x17f) tl0_resv180: BTRAPS(0x180) BTRAPS(0x188) tl0_resv190: BTRAPS(0x190) BTRAPS(0x198) tl0_resv1a0: BTRAPS(0x1a0) BTRAPS(0x1a8) @@ -265,7 +269,11 @@ tl1_resv130: BTRAPS(0x130) BTRAPS(0x138) tl1_resv140: BTRAPS(0x140) BTRAPS(0x148) tl1_resv150: BTRAPS(0x150) BTRAPS(0x158) tl1_resv160: BTRAPS(0x160) BTRAPS(0x168) -tl1_resv170: BTRAPS(0x170) BTRAPS(0x178) +tl1_resv170: BTRAPS(0x170) BTRAPS4(0x178) + BTRAP(0x17c) + TRAP_HANDLER(prom_debug) ! 0x17d : debugger + TRAP_HANDLER(prom_debug) ! 0x17e : debugger breakpoint + BTRAP(0x17f) tl1_resv180: BTRAPS(0x180) BTRAPS(0x188) tl1_resv190: BTRAPS(0x190) BTRAPS(0x198) tl1_resv1a0: BTRAPS(0x1a0) BTRAPS(0x1a8) @@ -507,6 +515,116 @@ reload_IMMU_tlb: retry
+ + .globl prom_debug_handler + +prom_debug: + + /* Make sure all windows are on the stack */ + flushw + + rdpr %tl, %g7 + rdpr %tpc, %g6 + rdpr %tnpc, %g5 + + /* 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(prom_debug) + + RESET_CPU_WINDOW_STATE(prom_debug) + + /* Switch to ordinary globals, saving to context */ + mov %g1, %o1 + rdpr %pstate, %o2 + andn %o2, PSTATE_AG, %o2 + wrpr %o2, %pstate + + stx %g1, [%o1 + 0x30] + stx %g2, [%o1 + 0x38] + stx %g3, [%o1 + 0x40] + stx %g4, [%o1 + 0x48] + stx %g5, [%o1 + 0x50] + stx %g6, [%o1 + 0x58] + stx %g7, [%o1 + 0x60] + + /* Copy context back to %g1 */ + mov %o1, %g1 + + /* Update __context to point to saved area */ + setx __context, %g6, %g7 + ldx [%g7], %g3 + setx debug_context, %g4, %g5 + stx %g3, [%g5] + stx %g1, [%g7] + + /* Switch to TLB locked OpenBIOS stack space (note we add an additional 192 bytes required for + gcc to save its arguments when building with -O0) */ + 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 + or %g7, PSTATE_IE, %g7 + wrpr %g7, %pstate + + call prom_debug_handler + nop + + /* Disable interrupts */ + 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 ordinary globals, switch back to alternate globals */ + mov %g1, %o1 + rdpr %pstate, %o2 + or %o2, PSTATE_AG, %o2 + + ldx [%o1 + 0x30], %g1 + ldx [%o1 + 0x38], %g2 + ldx [%o1 + 0x40], %g3 + ldx [%o1 + 0x48], %g4 + ldx [%o1 + 0x50], %g5 + ldx [%o1 + 0x58], %g6 + ldx [%o1 + 0x60], %g7 + + wrpr %o2, %pstate + mov %o1, %g1 + + RESTORE_CPU_STATE(prom_debug) + + /* Restore __context */ + setx debug_context, %g4, %g5 + ldx [%g5], %g3 + setx __context, %g6, %g7 + stx %g3, [%g7] + + setx _fcstack_ptr, %g6, %g7 + ldx [%g7], %g1 + add %g1, CONTEXT_STATE_SIZE, %g1 + stx %g1, [%g7] + + done + + softint_irq_tl1: softint_irq: mov 1, %g2
These perform reads using the given ASI and are used by the Milax startup code.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/openbios.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+)
diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c index 3b7bc46..d624eb2 100644 --- a/arch/sparc64/openbios.c +++ b/arch/sparc64/openbios.c @@ -128,6 +128,135 @@ sparc64_set_tas_register(unsigned long val) : : "r" (val), "r" (addr) : "memory"); }
+/* space?@ and and space?! words */ +static uint8_t +sparc64_asi_loadb(uint8_t asi, unsigned long address) +{ + uint8_t asi_save; + uint8_t ret = 0; + + __asm__ __volatile__("rd %%asi, %0" : "=r" (asi_save)); + __asm__ __volatile__("wr %0, 0, %%asi" : : "r" (asi)); + + __asm__ __volatile__("ldub [%1], %0" + : "=r" (ret) + : "r" (address)); + + __asm__ __volatile__("wr %0, 0, %%asi" : : "r" (asi_save)); + + return ret; +} + +/* spacec@ */ +static void +spacec_read(void) +{ + uint8_t ret; + + uint8_t asi = POP(); + ucell address = POP(); + + ret = sparc64_asi_loadb(asi, address); + + PUSH(ret); +} + +static uint16_t +sparc64_asi_loadw(uint8_t asi, unsigned long address) +{ + uint8_t asi_save; + uint16_t ret; + + __asm__ __volatile__("rd %%asi, %0" : "=r" (asi_save)); + __asm__ __volatile__("wr %0, 0, %%asi" : : "r" (asi)); + + __asm__ __volatile__("lduw [%1], %0" + : "=r" (ret) + : "r" (address)); + + __asm__ __volatile__("wr %0, 0, %%asi" : : "r" (asi_save)); + + return ret; +} + +/* spacew@ */ +static void +spacew_read(void) +{ + uint16_t ret; + + uint8_t asi = POP(); + ucell address = POP(); + + ret = sparc64_asi_loadw(asi, address); + + PUSH(ret); +} + +static uint32_t +sparc64_asi_loadl(uint8_t asi, unsigned long address) +{ + uint8_t asi_save; + uint32_t ret; + + __asm__ __volatile__("rd %%asi, %0" : "=r" (asi_save)); + __asm__ __volatile__("wr %0, 0, %%asi" : : "r" (asi)); + + __asm__ __volatile__("ld [%1], %0" + : "=r" (ret) + : "r" (address)); + + __asm__ __volatile__("wr %0, 0, %%asi" : : "r" (asi_save)); + + return ret; +} + +/* spacel@ */ +static void +spacel_read(void) +{ + uint32_t ret; + + uint8_t asi = POP(); + ucell address = POP(); + + ret = sparc64_asi_loadl(asi, address); + + PUSH(ret); +} + +static uint64_t +sparc64_asi_loadx(uint8_t asi, unsigned long address) +{ + uint8_t asi_save; + uint64_t ret = 0; + + __asm__ __volatile__("rd %%asi, %0" : "=r" (asi_save)); + __asm__ __volatile__("wr %0, 0, %%asi" : : "r" (asi)); + + __asm__ __volatile__("ldx [%1], %0" + : "=r" (ret) + : "r" (address)); + + __asm__ __volatile__("wr %0, 0, %%asi" : : "r" (asi_save)); + + return ret; +} + +/* spacex@ */ +static void +spacex_read(void) +{ + uint64_t ret; + + uint8_t asi = POP(); + ucell address = POP(); + + ret = sparc64_asi_loadx(asi, address); + + PUSH(ret); +} + static void cpu_generic_init(const struct cpudef *cpu, uint32_t clock_frequency) { unsigned long iu_version; @@ -586,6 +715,12 @@ arch_init( void ) fword("obp-ticks"); obp_ticks_pointer = cell2pointer(POP());
+ /* Bind to space?@ functions */ + bind_func("spacec@", spacec_read); + bind_func("spacew@", spacew_read); + bind_func("spacel@", spacel_read); + bind_func("spacex@", spacex_read); + bind_func("platform-boot", boot ); }
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/ldscript | 2 +- arch/sparc64/ofmem_sparc64.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/sparc64/ldscript b/arch/sparc64/ldscript index c5cc6a5..a55e02b 100644 --- a/arch/sparc64/ldscript +++ b/arch/sparc64/ldscript @@ -61,7 +61,7 @@ SECTIONS _estack = .; }
- . = ALIGN(4096); + . = ALIGN(8192); _end = .; _iomem = _end + IOMEM_SIZE;
diff --git a/arch/sparc64/ofmem_sparc64.c b/arch/sparc64/ofmem_sparc64.c index 1711c7e..ba4a053 100644 --- a/arch/sparc64/ofmem_sparc64.c +++ b/arch/sparc64/ofmem_sparc64.c @@ -68,13 +68,13 @@ ucell ofmem_arch_get_virt_top(void) ucell ofmem_arch_get_iomem_base(void) { /* Currently unused */ - return 0; + return (ucell)&_iomem; }
ucell ofmem_arch_get_iomem_top(void) { /* Currently unused */ - return 0; + return (ucell)&_iomem + 0x8000; }
retain_t *ofmem_arch_get_retained(void)
On Sun, 23 Oct 2016, Mark Cave-Ayland wrote:
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
arch/sparc64/ldscript | 2 +- arch/sparc64/ofmem_sparc64.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/sparc64/ldscript b/arch/sparc64/ldscript index c5cc6a5..a55e02b 100644 --- a/arch/sparc64/ldscript +++ b/arch/sparc64/ldscript @@ -61,7 +61,7 @@ SECTIONS _estack = .; }
- . = ALIGN(4096);
- . = ALIGN(8192); _end = .; _iomem = _end + IOMEM_SIZE;
diff --git a/arch/sparc64/ofmem_sparc64.c b/arch/sparc64/ofmem_sparc64.c index 1711c7e..ba4a053 100644 --- a/arch/sparc64/ofmem_sparc64.c +++ b/arch/sparc64/ofmem_sparc64.c @@ -68,13 +68,13 @@ ucell ofmem_arch_get_virt_top(void) ucell ofmem_arch_get_iomem_base(void) { /* Currently unused */
- return 0;
- return (ucell)&_iomem;
}
ucell ofmem_arch_get_iomem_top(void) { /* Currently unused */
- return 0;
- return (ucell)&_iomem + 0x8000;
}
Doesn't this make use of these functions now so the "Currently unused" comment is also invalidated?
Regards, BALATON Zoltan
retain_t *ofmem_arch_get_retained(void)
On 24/10/16 12:55, BALATON Zoltan wrote:
On Sun, 23 Oct 2016, Mark Cave-Ayland wrote:
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
arch/sparc64/ldscript | 2 +- arch/sparc64/ofmem_sparc64.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/sparc64/ldscript b/arch/sparc64/ldscript index c5cc6a5..a55e02b 100644 --- a/arch/sparc64/ldscript +++ b/arch/sparc64/ldscript @@ -61,7 +61,7 @@ SECTIONS _estack = .; }
- . = ALIGN(4096);
- . = ALIGN(8192); _end = .; _iomem = _end + IOMEM_SIZE;
diff --git a/arch/sparc64/ofmem_sparc64.c b/arch/sparc64/ofmem_sparc64.c index 1711c7e..ba4a053 100644 --- a/arch/sparc64/ofmem_sparc64.c +++ b/arch/sparc64/ofmem_sparc64.c @@ -68,13 +68,13 @@ ucell ofmem_arch_get_virt_top(void) ucell ofmem_arch_get_iomem_base(void) { /* Currently unused */
- return 0;
- return (ucell)&_iomem;
}
ucell ofmem_arch_get_iomem_top(void) { /* Currently unused */
- return 0;
- return (ucell)&_iomem + 0x8000;
}
Doesn't this make use of these functions now so the "Currently unused" comment is also invalidated?
Ooops, yes indeed. I'll update this in my local repository and push to github later assuming I receive no further comments.
ATB,
Mark.
Milax (OpenSolaris) expects the RTC to be mapped by the PROM and faults on boot if the mapping is not present.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/pci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/pci.c b/drivers/pci.c index 5fa6add..92a02d4 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -846,6 +846,8 @@ int ebus_config_cb(const pci_config_t *config) int i; uint32_t mask; int flags, space_code; + ucell virt; + phys_addr_t io_phys_base = 0;
props[0] = 0x14; props[1] = 0x3f8; @@ -878,6 +880,11 @@ int ebus_config_cb(const pci_config_t *config) config->assigned[i] & ~mask);
props[ncells++] = config->sizes[i]; + + /* Store base of IO space for NVRAM */ + if (io_phys_base == 0x0 && space_code == IO_SPACE) { + io_phys_base = pci_bus_addr_to_host_addr(space_code, config->assigned[i] & ~mask); + } }
set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0])); @@ -898,6 +905,13 @@ int ebus_config_cb(const pci_config_t *config) push_str("mk48t59"); fword("model");
+ /* OpenSolaris (e.g. Milax) requires the RTC to be pre-mapped by the PROM */ + virt = ofmem_map_io(io_phys_base + 0x2000, 0x2000); + PUSH(virt); + fword("encode-int"); + push_str("address"); + fword("property"); + push_str("eeprom"); fword("device-name"); fword("finish-device");
Milax (OpenSolaris) checks to see if this is the case, and panics on boot if the E bit isn't set for PROM mappings.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/entry.S | 6 +++--- arch/sparc64/ofmem_sparc64.c | 2 +- arch/sparc64/spitfire.h | 1 + 3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/sparc64/entry.S b/arch/sparc64/entry.S index 47d1139..224a53b 100644 --- a/arch/sparc64/entry.S +++ b/arch/sparc64/entry.S @@ -148,7 +148,7 @@ entry: srlx %g5, 19, %g6 ! %g6 = # of 512k .bss pages set 0xc0000000, %g3 sllx %g3, 32, %g3 - or %g3, 0x76, %g3 + or %g3, 0x7e, %g3 ! valid, 512k, locked, cacheable(I/E/C), priv, writable set 48, %g7 1: stxa %g4, [%g7] ASI_DMMU ! vaddr = _data + N * 0x80000, ctx=0 @@ -173,7 +173,7 @@ entry: 1: stxa %g4, [%g7] ASI_DMMU ! vaddr = _rodata, ctx=0 set 0xc0000000, %g3 sllx %g3, 32, %g3 - or %g3, 0x74, %g3 + or %g3, 0x7c, %g3 or %l2, %g3, %g3 ! valid, 512k, locked, cacheable(I/E/C), priv ! paddr = _rodata + N * 0x10000 @@ -197,7 +197,7 @@ entry: 1: stxa %g4, [%g7] ASI_IMMU ! vaddr = _start, ctx=0 set 0xc0000000, %g3 sllx %g3, 32, %g3 - or %g3, 0x74, %g3 + or %g3, 0x7c, %g3 or %l2, %g3, %g3 ! valid, 512k, locked, cacheable(I/E/C), priv ! paddr = _start + N * 0x80000 diff --git a/arch/sparc64/ofmem_sparc64.c b/arch/sparc64/ofmem_sparc64.c index ba4a053..06a16b1 100644 --- a/arch/sparc64/ofmem_sparc64.c +++ b/arch/sparc64/ofmem_sparc64.c @@ -215,7 +215,7 @@ ucell ofmem_arch_default_translation_mode( phys_addr_t phys ) ucell ofmem_arch_io_translation_mode( phys_addr_t phys ) { /* Writable, privileged and not locked */ - return SPITFIRE_TTE_CV | SPITFIRE_TTE_WRITABLE | SPITFIRE_TTE_PRIVILEGED; + return SPITFIRE_TTE_CV | SPITFIRE_TTE_WRITABLE | SPITFIRE_TTE_PRIVILEGED | SPITFIRE_TTE_EFFECT; }
/* Architecture-specific OFMEM helpers */ diff --git a/arch/sparc64/spitfire.h b/arch/sparc64/spitfire.h index 4a951b1..15dc378 100644 --- a/arch/sparc64/spitfire.h +++ b/arch/sparc64/spitfire.h @@ -38,6 +38,7 @@ /* translation table entry bits */ #define SPITFIRE_TTE_WRITABLE 0x02 #define SPITFIRE_TTE_PRIVILEGED 0x04 +#define SPITFIRE_TTE_EFFECT 0x08 #define SPITFIRE_TTE_CV 0x10 #define SPITFIRE_TTE_CP 0x20 #define SPITFIRE_TTE_LOCKED 0x40
On 23/10/16 15:22, Mark Cave-Ayland wrote:
Following on from the previous work, this patchset gets tantalisingly close to bringing up a 64-bit Milax (OpenSolaris) kernel under qemu-system-sparc64:
$ ./qemu-system-sparc64 -bios openbios-builtin.elf.nostrip -cdrom milax032sparc.iso -nographic -boot d -m 256 OpenBIOS for Sparc64 Configuration device id QEMU version 1 machine id 0 kernel cmdline CPUs: 1 x SUNW,UltraSPARC-IIi UUID: 00000000-0000-0000-0000-000000000000 Welcome to OpenBIOS v1.1 built on Oct 23 2016 13:36 Type 'help' for detailed information Trying cdrom:f... Not a bootable ELF image Not a bootable a.out image
Loading FCode image... Loaded 7084 bytes entry point is 0x4000 Evaluating FCode... Evaluating FCode... Ignoring failed claim for va 1000000 memsz bf34e! Ignoring failed claim for va 1402000 memsz 303b3! Ignoring failed claim for va 1800000 memsz 60a30! SunOS Release 5.11 Version MilaX_0.3.2 64-bit Copyright 1983-2008 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. could not find debugger-vocabulary-hook>threads:interpret: exception -13 caught interpret \ ident "%Z%%M% %I% %E% SMI" \ Copyright 2005 Sun Microsystems, Inc. All rights reserved. \ Use is subject to license terms. \ \ CDDL HEADER START \ \ The contents of this file are subject to the terms of the \ Common Development and Distribution License, Version 1.0 only \ (the "License"). You may not use this file except in compliance \ with the License. \ \ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE \ or http://www.opensolaris.org/os/licensing. \ See the License for unix-tte:interpret: exception -13 caught interpret ' unix-tte is va>tte-data failed with error ffffffffffffffed WARNING: consconfig: cannot find driver for screen device /pci@1fe,0/QEMU,VGA@2 Remounting root read/write Probing for device nodes ... WARNING: pcipsy0: unable to map reg entry 1
Preparing live image for use WARNING: pcipsy0: unable to map reg entry 1
WARNING: pcipsy0: unable to map reg entry 1
Hostname: milax Requesting System Maintenance Mode (See /lib/svc/share/README for more information.) Console login service(s) cannot run
Root password for system maintenance (control-d to bypass):
Sadly at this point the console (and eventually QEMU) lock up hard which suggests an emulation bug hiding away somewhere, and I do occasionally see intermittent kernel panics on boot.
Having said that, this is still a significant milestone :)
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
Mark Cave-Ayland (9): SPARC64: add %tba to saved state context SPARC64: make sure globals are stored in the CPU context during I/D MMU traps SPARC64: comment out the context switch debug message SPARC64: increase Forth machine memory to 192K SPARC64: add support for kmdb kernel debugger SPARC64: add spacec@, spacew@, spacel@ and spacex@ Forth words SPARC64: set up small iomem region for memory-mapped devices SPARC64: memory map mk48t59 RTC and store its address in the device tree SPARC64: ensure the E (effect) bit is set for PROM TTE entries
arch/sparc64/boot.h | 1 + arch/sparc64/call-client.S | 12 --- arch/sparc64/context.c | 2 +- arch/sparc64/context.h | 4 +- arch/sparc64/cpu.fs | 11 ++- arch/sparc64/cpustate.h | 13 ++- arch/sparc64/entry.S | 9 +- arch/sparc64/ldscript | 2 +- arch/sparc64/lib.c | 7 ++ arch/sparc64/ofmem_sparc64.c | 8 +- arch/sparc64/openbios.c | 144 ++++++++++++++++++++++++++++++- arch/sparc64/spitfire.h | 1 + arch/sparc64/vectors.S | 196 +++++++++++++++++++++++++++++++++++++++++- drivers/pci.c | 14 +++ 14 files changed, 387 insertions(+), 37 deletions(-)
No further feedback, so I've applied this with the comment removed as per Zoltan's suggestion to git master.
ATB,
Mark.