Implement data fault handling for cpeek and friends on SPARC32. Keeps the existing behavior for other architectures.
This series incorporates contributions and naming suggestions from Mark Cave-Ayland.
Bob Breuer (3): Add peek/poke hooks SPARC32: implement data fault handler SPARC32: handle data faults for peek/poke
openbios-devel/arch/sparc32/init.fs | 30 ++++++++++++++++++++++++++++++ openbios-devel/arch/sparc32/lib.c | 21 +++++++++++++++++++++ openbios-devel/arch/sparc32/vectors.S | 32 ++++++++++++++++++++++++++++++-- openbios-devel/forth/device/other.fs | 22 ++++++++++++++++------ 4 files changed, 97 insertions(+), 8 deletions(-)
Add hooks for hardware specific fault handlers for the peek and poke commands.
Signed-off-by: Bob Breuer breuerr@mc.net --- openbios-devel/forth/device/other.fs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/openbios-devel/forth/device/other.fs b/openbios-devel/forth/device/other.fs index f221a25..4746017 100644 --- a/openbios-devel/forth/device/other.fs +++ b/openbios-devel/forth/device/other.fs @@ -20,28 +20,38 @@ hex
\ 5.3.7.1 Peek/poke
+defer (peek) +:noname + execute true +; to (peek) + : cpeek ( addr -- false | byte true ) - c@ true + ['] c@ (peek) ;
: wpeek ( waddr -- false | w true ) - w@ true + ['] w@ (peek) ;
: lpeek ( qaddr -- false | quad true ) - l@ true + ['] l@ (peek) ;
+defer (poke) +:noname + execute true +; to (poke) + : cpoke ( byte addr -- okay? ) - c! true + ['] c! (poke) ;
: wpoke ( w waddr -- okay? ) - w! true + ['] w! (poke) ;
: lpoke ( quad qaddr -- okay? ) - l! true + ['] l! (poke) ;
Implement a trivial data fault handler for SPARC32 to skip over a faulting instruction when the ignore_dfault variable is non-zero.
Signed-off-by: Bob Breuer breuerr@mc.net --- openbios-devel/arch/sparc32/vectors.S | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/openbios-devel/arch/sparc32/vectors.S b/openbios-devel/arch/sparc32/vectors.S index f728d5f..6729394 100644 --- a/openbios-devel/arch/sparc32/vectors.S +++ b/openbios-devel/arch/sparc32/vectors.S @@ -41,6 +41,9 @@ trap_table: #define WINDOW_FILL \ rd %psr, %l0; rd %wim, %l3; b fill_window_entry; nop;
+#define TRAP_DFAULT(lvl) \ + rd %psr, %l0; rd %wim, %l3; b handle_dfault; mov lvl, %l7; + #define BTRAP(lvl) ba bug; mov lvl, %g1; nop; nop; #define BTRAPS(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3) BTRAP(x+4) BTRAP(x+5) BTRAP(x+6) BTRAP(x+7) #define TRAP_ENTRY_INTERRUPT(int_level) \ @@ -54,7 +57,9 @@ t_zero: b entry; nop; nop; nop; t_wovf: WINDOW_SPILL /* Window Overflow */ t_wunf: WINDOW_FILL /* Window Underflow */ BTRAP(0x7) - BTRAPS(0x8) + BTRAP(0x8) + TRAP_DFAULT(0x9) + BTRAP(0xa) BTRAP(0xb) BTRAP(0xc) BTRAP(0xd) BTRAP(0xe) BTRAP(0xf) #if 0 BAD_TRAP(0x10) t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */ @@ -80,7 +85,10 @@ t_irq10: TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 (one we use) t_irq14: TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */ BTRAP(0x1f) #endif - BTRAPS(0x20) BTRAPS(0x28) + BTRAPS(0x20) + BTRAP(0x28) + TRAP_DFAULT(0x29) + BTRAP(0x2a) BTRAP(0x2b) BTRAP(0x2c) BTRAP(0x2d) BTRAP(0x2e) BTRAP(0x2f) BTRAPS(0x30) BTRAPS(0x38) BTRAPS(0x40) BTRAPS(0x48) BTRAPS(0x50) BTRAPS(0x58) @@ -206,6 +214,26 @@ irq_entry14: #include "wof.S" #include "wuf.S"
+/* data fault handler */ + .data + .align 4 + .global ignore_dfault +ignore_dfault: + .word 0 + + .text + .align 4 +handle_dfault: + /* if ignore_dfault is 0, do old behavior */ + sethi %hi(ignore_dfault), %l4 + ld [ %l4 + %lo(ignore_dfault) ], %l4 + tst %l4 + bz,a bug + mov %l7, %g1 + /* skip the faulting instruction */ + jmp %l2 + rett %l2+4 + .section .rodata _BUG_message_0: .string "Unhandled Exception 0x"
Signed-off-by: Bob Breuer breuerr@mc.net --- openbios-devel/arch/sparc32/init.fs | 30 ++++++++++++++++++++++++++++++ openbios-devel/arch/sparc32/lib.c | 21 +++++++++++++++++++++ 2 files changed, 51 insertions(+)
diff --git a/openbios-devel/arch/sparc32/init.fs b/openbios-devel/arch/sparc32/init.fs index e2cd571..814c720 100644 --- a/openbios-devel/arch/sparc32/init.fs +++ b/openbios-devel/arch/sparc32/init.fs @@ -46,6 +46,36 @@ device-end 0 ;
+\ (peek) and (poke) implementation +defer sfsr@ +defer ignore-dfault + +:noname + \ ( addr xt -- false | value true ) + sfsr@ drop \ Clear any existing MMU fault status + + -1 ignore-dfault ! \ Disable data fault trap + execute + 0 ignore-dfault ! \ Enable data fault trap + + sfsr@ 0= if + true + else + drop false \ Failed, drop the read value + then +; to (peek) + +:noname + \ ( value addr xt -- okay? ) + sfsr@ drop \ Clear any existing MMU fault status + + -1 ignore-dfault ! \ Disable data fault trap + execute + 0 ignore-dfault ! \ Enable data fault trap + + sfsr@ 0= \ true if no fault +; to (poke) + \ Load TCX FCode driver blob [IFDEF] CONFIG_DRIVER_SBUS -1 value tcx-driver-fcode diff --git a/openbios-devel/arch/sparc32/lib.c b/openbios-devel/arch/sparc32/lib.c index 81d30ad..a871b69 100644 --- a/openbios-devel/arch/sparc32/lib.c +++ b/openbios-devel/arch/sparc32/lib.c @@ -302,6 +302,22 @@ void obp_dumb_memfree(__attribute__((unused))char *va, DPRINTF("obp_dumb_memfree 0x%p (size %d)\n", va, sz); }
+extern unsigned int ignore_dfault; + +/* Data fault handling routines */ + +/* ( -- reg ) */ +static void srmmu_get_sfsr(void) +{ + PUSH(srmmu_get_fstatus()); +} + +/* ( -- addr ) */ +static void ignore_dfault_addr(void) +{ + PUSH(pointer2cell(&ignore_dfault)); +} + void ob_init_mmu(void) { @@ -360,6 +376,11 @@ ob_init_mmu(void) bind_func("pgmap@", pgmap_fetch); bind_func("pgmap!", pgmap_store); bind_func("map-pages", ob_map_pages); + + PUSH_xt( bind_noname_func(srmmu_get_sfsr) ); + feval("to sfsr@"); + PUSH_xt( bind_noname_func(ignore_dfault_addr) ); + feval("to ignore-dfault"); }
/*
On 12/08/13 02:06, Bob Breuer wrote:
Implement data fault handling for cpeek and friends on SPARC32. Keeps the existing behavior for other architectures.
This series incorporates contributions and naming suggestions from Mark Cave-Ayland.
I've just applied this with some minor editorial work to fix whitespace issues - thanks a lot!
ATB,
Mark.