From 8828fb20a0df7f0747d5c6678328d261f310fc64 Mon Sep 17 00:00:00 2001 From: Jiri Gaisler Date: Tue, 5 Nov 2019 17:45:01 +0100 Subject: Replaced windows flushing with reg cache --- interf.c | 7 +++++- sis.h | 8 ++++++- sparc.c | 80 ++++++++++++++++++++++++++-------------------------------------- sparc.h | 7 +----- 4 files changed, 46 insertions(+), 56 deletions(-) diff --git a/interf.c b/interf.c index 259e793..d23d3a0 100644 --- a/interf.c +++ b/interf.c @@ -98,6 +98,11 @@ sim_read (uint32 mem, char *buf, int length) { int i, len; + if (sis_gdb_break && (cputype <= CPU_LEON3) && (length >= 4)) + { + if (gdb_sp_read (mem, buf, length)) + return length; + } for (i = 0; i < length; i++) { ms->sis_memory_read ((mem + i) ^ arch->endian, &buf[i], 1); @@ -124,7 +129,7 @@ sim_resume (int step) simstat = run_sim_gdb (UINT64_MAX / 2, 0); if (sis_gdb_break && (cputype != CPU_RISCV)) - flush_windows (&sregs[cpu]); + save_sp (&sregs[cpu]); } int diff --git a/sis.h b/sis.h index 4e12686..04f0a6b 100644 --- a/sis.h +++ b/sis.h @@ -23,6 +23,7 @@ #define VAL(x) strtoul(x,(char **)NULL,0) #define I_ACC_EXC 1 +#define NWIN 8 /* Maximum events in event queue */ #define EVENT_MAX 256 @@ -164,6 +165,8 @@ struct pstate uint64 l1imiss; uint32 l1dtags[L1DTAGS]; uint64 l1dmiss; + + uint32 sp[NWIN]; }; struct evcell @@ -307,7 +310,7 @@ extern int delta; /* time slice for MP simulation */ extern void pwd_enter (struct pstate *sregs); extern void remove_event (void (*cfunc) (), int32 arg); extern int run_sim (uint64 icount, int dis); -void flush_windows (struct pstate *sregs); +void save_sp (struct pstate *sregs); void cov_start (int address); void cov_exec (int address); void cov_bt (int address1, int address2); @@ -379,6 +382,9 @@ extern int sim_remove_swbreakpoint (uint32 addr, int len); extern int sim_set_watchpoint (uint32 mem, int length, int type); extern int sim_clear_watchpoint (uint32 mem, int length, int type); +/* sparc.c */ +extern int gdb_sp_read (uint32 mem, char *buf, int length); + /* FPU timing based on Meiko */ #define T_FABSs 2 diff --git a/sparc.c b/sparc.c index a06aa6b..1fad8d2 100644 --- a/sparc.c +++ b/sparc.c @@ -1,10 +1,13 @@ -#include "sparc.h" #include #include #include #include #include #include +#include "sparc.h" + +static int fpexec (uint32 op3, uint32 rd, uint32 rs1, uint32 rs2, + struct pstate *sregs); static uint32 sub_cc (psr, operand1, operand2, result) @@ -2250,65 +2253,46 @@ disp_reg (sregs, reg) sparc_disp_regs (sregs, VAL (®[1])); } -/* Flush all register windows out to the stack. Starting after the invalid - window, flush all windows up to, and including the current window. This - allows GDB to do backtraces and look at local variables for frames that - are still in the register windows. Note that strictly speaking, this - behavior is *wrong* for several reasons. First, it doesn't use the window - overflow handlers. It therefore assumes standard frame layouts and window - handling policies. Second, it changes system state behind the back of the - target program. I expect this to mainly pose problems when debugging trap - handlers. +/* Save stack pointer in each valid register window. Used to detect if gdb + wants to read a memory location which is cached in a register. */ void -flush_windows (struct pstate *sregs) +save_sp (struct pstate *sregs) { - int invwin; - int cwp; int win; - int ws; - - /* Skip if window potentially not valid */ - - if ((!(sregs->psr & PSR_ET)) || ((sregs->psr & PSR_PIL) == 0x0f00)) - return; - - /* Keep current window handy */ - cwp = sregs->psr & PSR_CWP; - - /* Calculate the invalid window from the wim. */ - - for (invwin = 0; invwin <= PSR_CWP; invwin++) - if ((sregs->wim >> invwin) & 1) - break; - - /* Start saving with the window after the invalid window. */ + for (win = 0; win < NWIN; win++) + { + if ((sregs->wim >> win) & 1) + sregs->sp[win] = 0; + else + sregs->sp[win] = sregs->r[win * 16 + 14]; + } +} - invwin = (invwin - 1) & PSR_CWP; +int +gdb_sp_read (uint32 mem, char *buf, int length) +{ + int i, j, len; + char *data; - for (win = invwin;; win = (win - 1) & PSR_CWP) + for (i = 0; i < NWIN; i++) { - uint32 sp; - int i; - - sp = sregs->r[(win * 16 + 14) & 0x7f]; -#if 1 - if (sis_verbose > 2) + if ((mem >= sregs[cpu].sp[i]) && (mem < (sregs[cpu].sp[i] + 64))) { - uint32 fp = sregs->r[(win * 16 + 30) & 0x7f]; - printf ("flush_window: win %d, sp %x, fp %x\n", win, sp, fp); + data = + (char *) &sregs[cpu]. + r[((i + 1) * 16 + ((mem - sregs->sp[i]) >> 2)) % (NWIN * 16)]; + for (j = 0; j < length; j++) + buf[j] = data[j ^ arch->endian]; + if (sis_verbose) + printf("gdb_sp_read: 0x%08x\n", mem); + return length; } -#endif - - for (i = 0; i < 16; i++) - ms->memory_write (sp + 4 * i, &sregs->r[(win * 16 + 16 + i) & 0x7f], - 2, &ws); - - if (win == cwp) - break; } + + return 0; } static void diff --git a/sparc.h b/sparc.h index 19f3561..2d69713 100644 --- a/sparc.h +++ b/sparc.h @@ -54,7 +54,7 @@ #define PSR_V 0x0200000 #define PSR_C 0x0100000 #define PSR_CC 0x0F00000 -#define PSR_CWP 0x7 +#define PSR_CWP (NWIN - 1) #define PSR_PIL 0x0f00 #define ICC_N (icc >> 3) @@ -191,8 +191,3 @@ /* # of cycles overhead when a trap is taken */ #define TRAP_C 3 - -/* Forward declarations */ - -static int fpexec (uint32 op3, uint32 rd, uint32 rs1, uint32 rs2, - struct pstate *sregs); -- cgit v1.2.3