From bc22f1aa8faa1af0446a76edf5e8a0bd3cbb9c32 Mon Sep 17 00:00:00 2001
From: wlott <wlott>
Date: Fri, 24 May 1991 17:50:13 +0000
Subject: [PATCH] Moved machine/arch specific stuff into machine/arch specific
 files.

---
 ldb/interrupt.c | 465 ++++++++----------------------------------------
 1 file changed, 71 insertions(+), 394 deletions(-)

diff --git a/ldb/interrupt.c b/ldb/interrupt.c
index 662e846cb..f56b84181 100644
--- a/ldb/interrupt.c
+++ b/ldb/interrupt.c
@@ -1,24 +1,24 @@
-/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/interrupt.c,v 1.27 1991/05/24 04:59:04 wlott Exp $ */
+/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/interrupt.c,v 1.28 1991/05/24 17:50:13 wlott Exp $ */
 
 /* Interrupt handing magic. */
 
+#include <stdio.h>
+
 #include <signal.h>
 #ifdef mips
 #include <mips/cpu.h>
 #endif
-#ifdef sparc
-#include <machine/trap.h>
-#endif
 
-#include "lisp.h"
 #include "ldb.h"
+
+#include "os.h"
+#include "arch.h"
+#include "lisp.h"
 #include "globals.h"
 #include "lispregs.h"
 #include "interrupt.h"
 #include "validate.h"
 
-#define crap_out(msg) do { write(2, msg, sizeof(msg)); exit(1); } while (0)
-
 #define FIXNUM_VALUE(lispobj) (((int)lispobj)>>2)
 
 boolean internal_errors_enabled = 0;
@@ -26,7 +26,8 @@ boolean internal_errors_enabled = 0;
 struct sigcontext *lisp_interrupt_contexts[MAX_INTERRUPTS];
 
 union interrupt_handler interrupt_handlers[NSIG];
-      
+void (*interrupt_low_level_handlers[NSIG])() = {0};
+
 static int pending_signal = 0, pending_code = 0, pending_mask = 0;
 static boolean maybe_gc_pending = FALSE;
 
@@ -35,7 +36,7 @@ static boolean maybe_gc_pending = FALSE;
 * Utility routines used by various signal handlers.              *
 \****************************************************************/
 
-static void fake_foreign_function_call(context)
+void fake_foreign_function_call(context)
      struct sigcontext *context;
 {
     int context_index;
@@ -106,7 +107,7 @@ static void fake_foreign_function_call(context)
     foreign_function_call_active = 1;
 }
 
-static void undo_fake_foreign_function_call(context)
+void undo_fake_foreign_function_call(context)
      struct sigcontext *context;
 {
     /* Block all blockable signals */
@@ -130,34 +131,7 @@ static void undo_fake_foreign_function_call(context)
     call_into_lisp(MAYBE_GC, SymbolFunction(MAYBE_GC), \
                    current_control_stack_pointer, 0)
 
-static void skip_instruction(context)
-     struct sigcontext *context;
-{
-#ifdef mips
-    /* Skip the offending instruction */
-    if (context->sc_cause & CAUSE_BD)
-        emulate_branch(context, *(unsigned long *)context->sc_pc);
-    else
-        context->sc_pc += 4;
-#endif
-#ifdef sparc
-    context->sc_pc = context->sc_npc;
-    context->sc_npc += 4;
-#endif
-#ifdef ibmrt
-    unsigned long pc = context->sc_iar;
-    unsigned long prev_inst = ((unsigned long *)pc)[-1];
-
-    if ((prev_inst >> 24) == 0x89) {
-	short offset = prev_inst & 0xffff;
-	context->sc_pc = pc - 4 + offset;
-    }
-    else
-	context->sc_pc = pc + 4;
-#endif
-}
-
-static void internal_error(signal, code, context, continuable)
+void interrupt_internal_error(signal, code, context, continuable)
      struct sigcontext *context;
      boolean continuable;
 {
@@ -177,13 +151,13 @@ static void internal_error(signal, code, context, continuable)
 		       args, 2);
 	undo_fake_foreign_function_call(context);
 	if (continuable)
-	    skip_instruction(context);
+	    arch_skip_instruction(context);
     }
     else
-	handle_now(signal, code, context);
+	interrupt_handle_now(signal, code, context);
 }
 
-static void handle_pending_interrupt(context)
+void interrupt_handle_pending(context)
      struct sigcontext *context;
 {
     if (foreign_function_call_active)
@@ -208,20 +182,20 @@ static void handle_pending_interrupt(context)
 	code = pending_code;
 	pending_signal = 0;
 	pending_code = 0;
-	handle_now(signal, code, context);
+	interrupt_handle_now(signal, code, context);
     }
     context->sc_mask = pending_mask;
     pending_mask = 0;
-    skip_instruction(context);
+    arch_skip_instruction(context);
 }
 
 
 /****************************************************************\
-* handle_now, maybe_now_maybe_later                              *
+* interrupt_handle_now, maybe_now_maybe_later                    *
 *    the two main signal handlers.                               *
 \****************************************************************/
 
-static handle_now(signal, code, context)
+void interrupt_handle_now(signal, code, context)
 int signal, code;
 struct sigcontext *context;
 {
@@ -231,20 +205,25 @@ struct sigcontext *context;
     lispobj callname, function;
     
     handler = interrupt_handlers[signal];
-    were_in_lisp = !foreign_function_call_active;
-    
-    if (handler.c == SIG_DFL || handler.c == SIG_IGN)
-	/* This can happen if someone tries to ignore or default on of the */
-	/* signals we need for runtime support. */
+
+    if(handler.c==SIG_IGN)
 	return;
 
+    were_in_lisp = !foreign_function_call_active;
     if (were_in_lisp)
         fake_foreign_function_call(context);
     
     /* Allow signals again. */
     sigsetmask(context->sc_mask);
 
-    if (LowtagOf(handler.lisp) == type_EvenFixnum ||
+    if(handler.c==SIG_DFL){
+	/* This can happen if someone tries to ignore or default on of the */
+	/* signals we need for runtime support. */
+	fprintf(stderr,"interrupt_handle_now: No handler for signal %d?\n",signal);
+	printf("[exit debugger to continue]\n");
+	ldb_monitor();
+    }
+    else if (LowtagOf(handler.lisp) == type_EvenFixnum ||
         LowtagOf(handler.lisp) == type_OddFixnum)
         (*handler.c)(signal, code, context);
     else {
@@ -265,7 +244,7 @@ struct sigcontext *context;
         undo_fake_foreign_function_call(context);
 }
 
-static maybe_now_maybe_later(signal, code, context)
+static void maybe_now_maybe_later(signal, code, context)
 int signal, code;
 struct sigcontext *context;
 {
@@ -292,249 +271,9 @@ struct sigcontext *context;
 	SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, T);
 #endif
     } else
-        handle_now(signal, code, context);
+        interrupt_handle_now(signal, code, context);
 }
 
-/****************************************************************\
-* PMAX specific signal handlers.                                 *
-\****************************************************************/
-
-#ifdef mips
-static sigtrap_handler(signal, code, context)
-     int signal, code;
-     struct sigcontext *context;
-{
-    switch (code) {
-      case trap_PendingInterrupt:
-	handle_pending_interrupt(context);
-	break;
-
-      case trap_Halt:
-	crap_out("%primitive halt called; the party is over.\n");
-
-      case trap_Error:
-      case trap_Cerror:
-	internal_error(signal, code, context, code==trap_Cerror);
-	break;
-
-      case trap_Breakpoint:
-	sigsetmask(context->sc_mask);
-	fake_foreign_function_call(context);
-	handle_breakpoint(signal, code, context);
-	undo_fake_foreign_function_call(context);
-	break;
-
-      default:
-	handle_now(signal, code, context);
-	break;
-    }
-}
-
-static sigfpe_handler(signal, code, context)
-int signal, code;
-struct sigcontext *context;
-{
-    unsigned long bad_inst;
-    unsigned int op, rs, rt, rd, funct, dest;
-    int immed;
-    long result;
-
-    if (context->sc_cause & CAUSE_BD)
-        bad_inst = *(unsigned long *)(context->sc_pc + 4);
-    else
-        bad_inst = *(unsigned long *)(context->sc_pc);
-
-    op = (bad_inst >> 26) & 0x3f;
-    rs = (bad_inst >> 21) & 0x1f;
-    rt = (bad_inst >> 16) & 0x1f;
-    rd = (bad_inst >> 11) & 0x1f;
-    funct = bad_inst & 0x3f;
-    immed = (((int)(bad_inst & 0xffff)) << 16) >> 16;
-
-    switch (op) {
-        case 0x0: /* SPECIAL */
-            switch (funct) {
-                case 0x20: /* ADD */
-                    result = FIXNUM_VALUE(context->sc_regs[rs]) + FIXNUM_VALUE(context->sc_regs[rt]);
-                    dest = rd;
-                    break;
-
-                case 0x22: /* SUB */
-                    result = FIXNUM_VALUE(context->sc_regs[rs]) - FIXNUM_VALUE(context->sc_regs[rt]);
-                    dest = rd;
-                    break;
-
-                default:
-                    dest = 32;
-                    break;
-            }
-            break;
-
-        case 0x8: /* ADDI */
-            result = FIXNUM_VALUE(context->sc_regs[rs]) + (immed>>2);
-            dest = rt;
-            break;
-
-        default:
-            dest = 32;
-            break;
-    }
-
-    if (dest < 32) {
-        set_global_pointer(saved_global_pointer);
-        current_dynamic_space_free_pointer =
-            (lispobj *) context->sc_regs[ALLOC];
-
-        context->sc_regs[dest] = alloc_number(result);
-
-	context->sc_regs[ALLOC] =
-	    (unsigned long) current_dynamic_space_free_pointer;
-
-        skip_instruction(context);
-
-    }
-    else
-        handle_now(signal, code, context);
-}
-#endif
-
-/****************************************************************\
-* SPARC specific signal handlers.                                *
-\****************************************************************/
-
-#ifdef sparc
-static sigill_handler(signal, code, context)
-int signal, code;
-struct sigcontext *context;
-{
-    int badinst;
-
-    if (code == T_UNIMP_INSTR) {
-	int trap;
-
-	trap = *(unsigned long *)(context->sc_pc) & 0x3fffff;
-
-	switch (trap) {
-	  case trap_PendingInterrupt:
-	    handle_pending_interrupt(context);
-	    break;
-
-	  case trap_Halt:
-	    crap_out("%primitive halt called; the party is over.\n");
-
-	  case trap_Error:
-	  case trap_Cerror:
-	    internal_error(signal, code, context, trap == trap_Cerror);
-	    break;
-
-	  default:
-	    handle_now(signal, code, context);
-	    break;
-	}
-    }
-    else if (code >= T_SOFTWARE_TRAP + 16 & code < T_SOFTWARE_TRAP + 32)
-	internal_error(signal, code, context, FALSE);
-    else
-	handle_now(signal, code, context);
-}
-
-static sigemt_handler(signal, code, context)
-     int signal, code;
-     struct sigcontext *context;
-{
-    unsigned long badinst;
-    boolean subtract, immed;
-    int rd, rs1, op1, rs2, op2, result;
-
-    badinst = *(unsigned long *)context->sc_pc;
-    if ((badinst >> 30) != 2 || ((badinst >> 20) & 0x1f) != 0x11) {
-	/* It wasn't a tagged add.  Pass the signal into lisp. */
-	handle_now(signal, code, context);
-	return;
-    }
-	
-    /* Extract the parts of the inst. */
-    subtract = badinst & (1<<19);
-    rs1 = (badinst>>14) & 0x1f;
-    op1 = context->sc_regs[rs1];
-    if ((op1 & 3) != 0) {
-	/* The first arg wan't a fixnum. */
-	internal_error(signal, code, context, FALSE);
-	return;
-    }
-
-    if (immed = badinst & (1<<13)) {
-	op2 = badinst & 0x1fff;
-	if (op2 & (1<<12))
-	    op2 |= -1<<13;
-    }
-    else {
-	rs2 = badinst & 0x1f;
-	op2 = context->sc_regs[rs2];
-    }
-
-    if ((op2 & 3) != 0) {
-	/* The second arg wan't a fixnum. */
-	internal_error(signal, code, context, FALSE);
-	return;
-    }
-
-    rd = (badinst>>25) & 0x1f;
-    if (rd != 0) {
-	/* Don't bother computing the result unless we are going to use it. */
-	if (subtract)
-	    result = (op1>>2) - (op2>>2);
-	else
-	    result = (op1>>2) + (op2>>2);
-
-        current_dynamic_space_free_pointer =
-            (lispobj *) context->sc_regs[ALLOC];
-
-	context->sc_regs[rd] = alloc_number(result);
-
-	context->sc_regs[ALLOC] =
-	    (unsigned long) current_dynamic_space_free_pointer;
-    }
-    skip_instruction(context);
-}
-#endif
-
-/****************************************************************\
-* RT Specific Signal Handlers                                    *
-\****************************************************************/
-
-#ifdef ibmrt
-static sigtrap_handler(signal, code, context)
-     int signal, code;
-     struct sigcontext *context;
-{
-    switch (*((unsigned short *)context->sc_iar+1)) {
-      case trap_PendingInterrupt:
-	handle_pending_interrupt(context);
-	break;
-
-      case trap_Halt:
-	crap_out("%primitive halt called; the party is over.\n");
-
-      case trap_Error:
-      case trap_Cerror:
-	internal_error(signal, code, context, code==trap_Cerror);
-	break;
-
-      case trap_Breakpoint:
-	sigsetmask(context->sc_mask);
-	fake_foreign_function_call(context);
-	handle_breakpoint(signal, code, context);
-	undo_fake_foreign_function_call(context);
-	break;
-
-      default:
-	handle_now(signal, code, context);
-	break;
-    }
-}
-#endif
-
 /****************************************************************\
 * Stuff to detect and handle hitting the gc trigger.             *
 \****************************************************************/
@@ -542,78 +281,18 @@ static sigtrap_handler(signal, code, context)
 static boolean gc_trigger_hit(context)
      struct sigcontext *context;
 {
-    lispobj *badaddr;
-#ifdef sparc
-    unsigned long badinst;
-    int rs1;
-#endif
 
     if (current_auto_gc_trigger == NULL)
 	return FALSE;
+    else{
+	lispobj *badaddr=(lispobj *)arch_get_bad_addr(context);
 
-#ifdef mips
-    /* Finding the bad address on the mips is easy. */
-    badaddr = (lispobj *)context->sc_badvaddr;
-#endif
-
-#ifdef sparc
-    /* On the sparc, we have to decode the instruction. */
-
-    /* Make sure it's not the pc thats bogus, and that it was lisp code */
-    /* that caused the fault. */
-    if ((context->sc_pc & 3) != 0 ||
-	((context->sc_pc < READ_ONLY_SPACE_START ||
-	  context->sc_pc >= READ_ONLY_SPACE_START+READ_ONLY_SPACE_SIZE) &&
-	 ((lispobj *)context->sc_pc < current_dynamic_space &&
-	  (lispobj *)context->sc_pc >=
-	      current_dynamic_space + DYNAMIC_SPACE_SIZE)))
-	return FALSE;
-
-    badinst = *(unsigned long *)context->sc_pc;
-
-    if ((badinst >> 30) != 3)
-	/* All load/store instructions have op = 11 (binary) */
-	return FALSE;
-
-    rs1 = (badinst>>14)&0x1f;
-
-    if (badinst & (1<<13)) {
-	/* r[rs1] + simm(13) */
-	int simm13 = badinst & 0x1fff;
-
-	if (simm13 & (1<<12))
-	    simm13 |= -1<<13;
-
-	badaddr = (lispobj *)(context->sc_regs[rs1] + simm13);
+	return (badaddr >= current_auto_gc_trigger &&
+		badaddr < current_dynamic_space + DYNAMIC_SPACE_SIZE);
     }
-    else {
-	/* r[rs1] + r[rs2] */
-	int rs2 = badinst & 0x1f;
-
-	badaddr = (lispobj *)(context->sc_regs[rs1] + context->sc_regs[rs2]);
-    }
-#endif
-
-#ifdef ibmrt
-    if (!SymbolValue(PSEUDO_ATOMIC_ATOMIC))
-	/* If we are not pseudo-atomic, then we could only have hit the */
-	/* trigger if the allocation pointer points beyond the trigger. */
-	badaddr = (lispobj *)SymbolValue(ALLOCATION_POINTER);
-    else
-	/* Otherwise, we might be inside an allocator.  The best we can do */
-	/* is to try turning off the trigger and seeing if the problem goes */
-	/* away.  If it does, then we guessed right.  If it doesn't, we will */
-	/* end up back here, except current_auto_gc_trigger will be NULL, */
-	/* so we will take the sigbus at that time. */
-	return TRUE;
-#endif
-
-    return (badaddr >= current_auto_gc_trigger &&
-	    badaddr < current_dynamic_space + DYNAMIC_SPACE_SIZE);
 }
 
-static sigbus_handler(signal, code, context)
-int signal, code;
+boolean interrupt_maybe_gc(context)
 struct sigcontext *context;
 {
     if (!foreign_function_call_active && gc_trigger_hit(context)) {
@@ -645,59 +324,57 @@ struct sigcontext *context;
 	    call_maybe_gc();
 	    undo_fake_foreign_function_call(context);
 	}
-    }
-    else
-	handle_now(signal, code, context);
+
+	return TRUE;
+    }else
+	return FALSE;
 }
 
 /****************************************************************\
 * Noise to install handlers.                                     *
 \****************************************************************/
 
+void interrupt_install_low_level_handler(signal,handler)
+int signal;
+void (*handler)();
+{
+    struct sigvec sv;
+
+    sv.sv_handler=handler;
+    sv.sv_mask=BLOCKABLE;
+    sv.sv_flags=0;
+
+    sigvec(signal,&sv,NULL);
+
+    interrupt_low_level_handlers[signal]=(handler==SIG_DFL ? 0 : handler);
+}
+
 unsigned long install_handler(signal, handler)
 int signal;
-int (*handler)();
+void (*handler)();
 {
     struct sigvec sv;
     int oldmask;
     union interrupt_handler oldhandler;
 
-#ifdef mips
-    if (signal == SIGTRAP)
-        sv.sv_handler = sigtrap_handler;
-    else if (signal == SIGFPE)
-        sv.sv_handler = sigfpe_handler;
-    else if (signal == SIGBUS || signal == SIGSEGV)
-        sv.sv_handler = sigbus_handler;
-#endif
-#ifdef sparc
-    if (signal == SIGILL)
-	sv.sv_handler = sigill_handler;
-    else if (signal == SIGEMT)
-	sv.sv_handler = sigemt_handler;
-    else if (signal == SIGBUS)
-        sv.sv_handler = sigbus_handler;
-#endif
-#ifdef ibmrt
-    if (signal == SIGTRAP)
-	sv.sv_handler = sigtrap_handler;
-    else if (signal == SIGBUS)
-        sv.sv_handler = sigbus_handler;
-#endif
-    else if (handler == SIG_DFL || handler == SIG_IGN)
-        sv.sv_handler = handler;
-    else if (sigmask(signal)&BLOCKABLE)
-        sv.sv_handler = maybe_now_maybe_later;
-    else
-        sv.sv_handler = handle_now;
-    sv.sv_mask = BLOCKABLE;
-    sv.sv_flags = 0;
-
     oldmask = sigblock(sigmask(signal));
 
+    if(interrupt_low_level_handlers[signal]==0){
+	if(handler==SIG_DFL || handler==SIG_IGN)
+	    sv.sv_handler=handler;
+	else if (sigmask(signal)&BLOCKABLE)
+	    sv.sv_handler = maybe_now_maybe_later;
+	else
+	    sv.sv_handler = interrupt_handle_now;
+
+	sv.sv_mask = BLOCKABLE;
+	sv.sv_flags = 0;
+
+	sigvec(signal, &sv, NULL);
+    }
+
     oldhandler = interrupt_handlers[signal];
     interrupt_handlers[signal].c = handler;
-    sigvec(signal, &sv, NULL);
 
     sigsetmask(oldmask);
 
-- 
GitLab