[OpenBIOS] sparc32 trap recovery
Bob Breuer
breuerr at mc.net
Tue Jun 25 17:40:19 CEST 2013
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)");
}
/*
More information about the OpenBIOS
mailing list