On 6/19/2013 9:44 AM, Bob Breuer wrote:
So how about if I setup an interrupt handler that skips over the faulting instruction when a global flag is set, otherwise continues as is today. Then cpeek can become:
- set skip_datafault flag
- clear SFSR
- chain to c@
- clear skip_datafault flag
- check SFSR
- if fault, fixup stack and return false, else return true
Now, I might be able to code up this cpeek version in forth, or just leave it in C?
Here's what I've got. If it looks ok, I will finish it off by also catching trap 0x29, modify wpeek/lpeek to also use the wrapper, and make a similar change for the poke commands.
Index: forth/device/other.fs =================================================================== --- forth/device/other.fs (revision 1160) +++ forth/device/other.fs (working copy) @@ -20,8 +20,12 @@
\ 5.3.7.1 Peek/poke
+defer (peek-wrapper) +: (peek-default) execute true ; +['] (peek-default) to (peek-wrapper) + : cpeek ( addr -- false | byte true ) - c@ true + ['] c@ (peek-wrapper) ;
: wpeek ( waddr -- false | w true ) Index: arch/sparc32/vectors.S =================================================================== --- arch/sparc32/vectors.S (revision 1160) +++ arch/sparc32/vectors.S (working copy) @@ -41,6 +41,9 @@ #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 do_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,11 @@ 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 */ @@ -206,6 +213,26 @@ #include "wof.S" #include "wuf.S"
+/* data fault handler */ + .data + .align 4 + .global allow_dfault +allow_dfault: + .word 0 + + .text + .align 4 +do_dfault: + /* if allow_dfault is 0, do old behavior */ + set allow_dfault, %l4 + ld [ %l4 ], %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" Index: arch/sparc32/lib.c =================================================================== --- arch/sparc32/lib.c (revision 1160) +++ arch/sparc32/lib.c (working copy) @@ -302,6 +302,45 @@ DPRINTF("obp_dumb_memfree 0x%p (size %d)\n", va, sz); }
+#include "asm/crs.h" + +extern unsigned int allow_dfault; + +static unsigned int get_sfsr(void) +{ + unsigned int sfsr; + __asm__ __volatile__( + "lda [%1] %2, %0" + : "=r" (sfsr) + : "r" (AC_M_SFSR), "i" (ASI_M_MMUREGS)); + + return sfsr; +} + +static void sparc_peek(void) +{ + unsigned int sfsr; + + get_sfsr(); /* clear any stale fault status */ + allow_dfault = 1; + + fword("execute"); + + allow_dfault = 0; + sfsr = get_sfsr(); + + if (sfsr == 0) + { + PUSH(-1); /* true */ + } + else + { + /* drop failed read, return false */ + POP(); + PUSH(0); + } +} + void ob_init_mmu(void) { @@ -360,6 +399,9 @@ bind_func("pgmap@", pgmap_fetch); bind_func("pgmap!", pgmap_store); bind_func("map-pages", ob_map_pages); + + PUSH_xt( bind_noname_func(sparc_peek) ); + feval("to (peek-wrapper)"); }
/*