diff options
Diffstat (limited to 'sim/sparc/trap32.c')
-rw-r--r-- | sim/sparc/trap32.c | 308 |
1 files changed, 0 insertions, 308 deletions
diff --git a/sim/sparc/trap32.c b/sim/sparc/trap32.c deleted file mode 100644 index fb60281..0000000 --- a/sim/sparc/trap32.c +++ /dev/null @@ -1,308 +0,0 @@ -/* sparc32 trap support - Copyright (C) 1999 Cygnus Solutions. */ - -#define WANT_CPU sparc32 -#define WANT_CPU_SPARC32 - -#include "sim-main.h" -#include "targ-vals.h" - -/* Indicate a window overflow has occured. */ - -void -sparc32_window_overflow (SIM_CPU *cpu, IADDR pc) -{ - SIM_DESC sd = CPU_STATE (cpu); - - if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) - sparc32_hw_trap (cpu, pc, TRAP32_WINDOW_OVERFLOW); - else - sparc32_hw_trap (cpu, pc, TRAP32_SIM_SPILL); -} - -/* Indicate a window underflow has occured. */ - -void -sparc32_window_underflow (SIM_CPU *cpu, IADDR pc) -{ - SIM_DESC sd = CPU_STATE (cpu); - - if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) - sparc32_hw_trap (cpu, pc, TRAP32_WINDOW_UNDERFLOW); - else - sparc32_hw_trap (cpu, pc, TRAP32_SIM_FILL); -} - -void -sparc32_invalid_insn (SIM_CPU * cpu, IADDR pc) -{ - sparc32_hw_trap (cpu, pc, TRAP32_ILLEGAL_INSN); -} - -void -sparc32_core_signal (SIM_DESC sd, SIM_CPU *cpu, sim_cia pc, - unsigned int map, int nr_bytes, address_word addr, - transfer_type transfer, sim_core_signals sig) -{ - sparc32_hw_trap (cpu, pc, - map == exec_map - ? TRAP32_INSTRUCTION_ACCESS - : TRAP32_DATA_ACCESS); -} - -/* Handle hardware generated traps when --environment=operating. */ - -static void -sparc32_hw_trap_oper (SIM_CPU *current_cpu, IADDR pc, TRAP32_TYPE trap) -{ - SIM_DESC sd = CPU_STATE (current_cpu); - IADDR new_pc = (GET_H_TBR () & 0xfffff000) | (trap << 4); - USI psr = GET_H_PSR (); - - psr &= ~PSR_ET; - psr = (psr & ~PSR_PS) | (psr & PSR_S ? PSR_PS : 0); - psr |= PSR_S; - psr = (psr & ~PSR_CWP) | NEXT_WIN (psr & PSR_CWP); - SET_H_PSR (psr); - SET_H_GR (H_GR__L1, GET_H_PC ()); - SET_H_GR (H_GR__L2, GET_H_NPC ()); - - SET_H_ANNUL_P (0); - - /* The wrtbr insn doesn't affect the tt part so SET_H_TBR doesn't either - (??? doesn't *have* to be this way though). - Therefore we can't use SET_H_TBR here. */ - CPU (h_tbr) = new_pc; - SET_H_PC (new_pc); - SET_H_NPC (new_pc + 4); - - sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL, new_pc); -} - -/* Handle hardware generated traps when --environment=user. */ - -static void -sparc32_hw_trap_user (SIM_CPU *current_cpu, IADDR pc, TRAP32_TYPE trap) -{ - SIM_DESC sd = CPU_STATE (current_cpu); - - switch (trap) - { - case TRAP32_SIM_SPILL : - /* The CWP-1 window is invalid. */ - { - int win = NEXT_WIN (GET_H_CWP ()); - int next_win = NEXT_WIN (win); - int nwindows = GET_NWINDOWS (); - unsigned int mask = (1 << nwindows) - 1; - unsigned int wim = GET_H_WIM (); - - /* There's no need to flush `current_regs' here, `next_win' can't - refer to it. */ - sparc32_flush_regwin (current_cpu, pc, next_win, 0 /* error ok (?) */); - /* Rotate WIM right one. */ - wim = ((wim & mask) >> 1) | (wim << (nwindows - 1)); - SET_H_WIM (wim & mask); - return; - } - - case TRAP32_SIM_FILL : - /* The CWP+1 window is invalid. */ - { - int win = PREV_WIN (GET_H_CWP ()); - int nwindows = GET_NWINDOWS (); - unsigned int mask = (1 << nwindows) - 1; - unsigned int wim = GET_H_WIM (); - - /* Load caller's caller's window. - There's no need to flush `current_regs' as `win' can't - refer to it. */ - sparc32_load_regwin (current_cpu, pc, win); - /* Rotate WIM left one. */ - wim = (wim << 1) | ((wim & mask) >> (nwindows - 1)); - SET_H_WIM (wim & mask); - return; - } - } - - sim_io_eprintf (sd, "Received trap %d\n", trap); - sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGABRT); -} - -/* Handle hardware generated traps. */ - -void -sparc32_hw_trap (SIM_CPU *current_cpu, IADDR pc, TRAP32_TYPE trap) -{ - SIM_DESC sd = CPU_STATE (current_cpu); - - if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) - sparc32_hw_trap_oper (current_cpu, pc, trap); - else - sparc32_hw_trap_user (current_cpu, pc, trap); -} - -/* Handle the trap insn when --environment=operating. */ - -static IADDR -sparc32_sw_trap_oper (SIM_CPU *current_cpu, IADDR pc, SI rs1, SI rs2_simm13) -{ - SIM_DESC sd = CPU_STATE (current_cpu); - int trap = 128 + ((rs1 + rs2_simm13) & 127); - IADDR new_pc; - - /* ??? Quick hack to have breakpoints work with gdb+"target sim" until - other things are working. */ - if (trap == TRAP32_BREAKPOINT) - sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); - - if (! GET_H_ET ()) - { - /* Enter error mode. - ??? wip, need to remain compatible with erc32 for now. */ - int i0 = GET_H_GR (H_GR__I0); - int i1 = GET_H_GR (H_GR__I1); - - if (i1 == LIBGLOSS_EXIT_MAGIC) - sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, i0); - else - { - sim_io_eprintf (sd, "Unexpected program termination, pc=0x%x\n", - (int) pc); - sim_engine_halt (sd, current_cpu, NULL, pc, - sim_signalled, SIM_SIGABRT); - } - } - - SET_H_ET (0); - SET_H_PSR ((GET_H_PSR () & ~(PSR_CWP | PSR_PS)) - | PSR_S - | (GET_H_S () ? PSR_PS : 0) - | (NEXT_WIN (GET_H_CWP ()))); - SET_H_GR (H_GR__L1, GET_H_PC ()); - SET_H_GR (H_GR__L2, GET_H_NPC ()); - /* The wrtbr insn doesn't affect the tt part so SET_H_TBR doesn't either - (??? doesn't *have* to be this way though). - Therefore we can't use SET_H_TBR here. */ - CPU (h_tbr) = new_pc = ((GET_H_TBR () & 0xfffff000) - | (trap << 4)); - return new_pc; -} - -/* Subroutine of sparc32_do_trap to read target memory. */ - -static int -syscall_read_mem (host_callback *cb, CB_SYSCALL *sc, - unsigned long taddr, char *buf, int bytes) -{ - SIM_DESC sd = (SIM_DESC) sc->p1; - SIM_CPU *cpu = (SIM_CPU *) sc->p2; - - return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes); -} - -/* Subroutine of sparc32_do_trap to write target memory. */ - -static int -syscall_write_mem (host_callback *cb, CB_SYSCALL *sc, - unsigned long taddr, const char *buf, int bytes) -{ - SIM_DESC sd = (SIM_DESC) sc->p1; - SIM_CPU *cpu = (SIM_CPU *) sc->p2; - - return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); -} - -/* Handle the trap insn when --environment=user. */ - -static IADDR -sparc32_sw_trap_user (SIM_CPU *current_cpu, IADDR pc, SI rs1, SI rs2_simm13) -{ - SIM_DESC sd = CPU_STATE (current_cpu); - int trap = 128 + ((rs1 + rs2_simm13) & 127); - IADDR new_pc = pc + 4; - - switch (trap) - { - case TRAP32_SYSCALL : - /* FIXME: Later make trap number runtime selectable. */ - { - CB_SYSCALL s; - - CB_SYSCALL_INIT (&s); - s.func = a_sparc_h_gr_get (current_cpu, 8); - s.arg1 = a_sparc_h_gr_get (current_cpu, 9); - s.arg2 = a_sparc_h_gr_get (current_cpu, 10); - s.arg3 = a_sparc_h_gr_get (current_cpu, 11); - if (s.func == TARGET_SYS_exit) - { - /* Tell sim_resume program called exit(). */ - sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1); - } - s.p1 = (PTR) sd; - s.p2 = (PTR) current_cpu; - s.read_mem = syscall_read_mem; - s.write_mem = syscall_write_mem; - cb_syscall (STATE_CALLBACK (CPU_STATE (current_cpu)), &s); - a_sparc_h_gr_set (current_cpu, 10, s.errcode); - a_sparc_h_gr_set (current_cpu, 8, s.result); - a_sparc_h_gr_set (current_cpu, 9, s.result2); - break; - } - - case TRAP32_BREAKPOINT : - sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); - - case TRAP32_DIVIDE_0 : - sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGFPE); - - case TRAP32_FLUSH_REGWIN : - sparc32_flush_regwins (current_cpu, pc, 0 /* error ok */); - break; - - default : - sim_io_eprintf (sd, "Unsupported trap %d\n", trap); - sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL); - } - - return new_pc; -} - -/* Called from the semantic code to handle the trap instruction. */ - -IADDR -sparc32_sw_trap (SIM_CPU *current_cpu, IADDR pc, SI rs1, SI rs2_simm13) -{ - SIM_DESC sd = CPU_STATE (current_cpu); - IADDR new_pc; - - if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) - new_pc = sparc32_sw_trap_oper (current_cpu, pc, rs1, rs2_simm13); - else - new_pc = sparc32_sw_trap_user (current_cpu, pc, rs1, rs2_simm13); - return new_pc; -} - -/* Handle the rett insn. */ - -IADDR -sparc32_do_rett (SIM_CPU *current_cpu, IADDR pc, SI rs1, SI rs2_simm13) -{ - int psr = GET_H_PSR (); - - /* FIXME: check for trap conditions. */ - - SET_H_PSR ((psr & ~(PSR_S + PSR_CWP)) - | ((psr & PSR_PS) ? PSR_S : 0) - | PSR_ET - | PREV_WIN (psr & PSR_CWP)); - - if (TRACE_INSN_P (current_cpu)) /* FIXME */ - { - trace_result (current_cpu, "sp", 'x', GET_H_GR (H_GR__SP)); - trace_result (current_cpu, "fp", 'x', GET_H_GR (H_GR__FP)); - trace_result (current_cpu, "cwp", 'x', GET_H_CWP ()); - } - - return rs1 + rs2_simm13; -} |