diff options
Diffstat (limited to 'tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch')
-rw-r--r-- | tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch b/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch new file mode 100644 index 0000000..7078cc3 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch @@ -0,0 +1,377 @@ +From 933b0b5f256713f50959cd1f1c6ad565f40b12ab Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler <jiri@gaisler.se> +Date: Thu, 19 Feb 2015 23:21:02 +0100 +Subject: [PATCH 21/23] sim/erc32: Add data watchpoint support + + Add watchpoint to all processor targets (erc32, leon2, leon3). +--- + sim/erc32/exec.c | 54 +++++++++++++++++++++++++++------- + sim/erc32/func.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- + sim/erc32/sis.c | 32 +++++++++++++++----- + sim/erc32/sis.h | 23 ++++++++++++++- + 4 files changed, 179 insertions(+), 20 deletions(-) + +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index f4a0124..134e789 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -395,6 +395,20 @@ extract_byte_signed(uint32 data, uint32 address) + return(tmp); + } + ++/* Decode watchpoint address mask from opcode. Not correct for LDST, ++ SWAP and STFSR but watchpoints will work anyway. */ ++ ++static unsigned char ++wpmask(uint32 op3) ++{ ++ switch (op3 & 3) { ++ case 0: return(3); /* word */ ++ case 1: return(0); /* byte */ ++ case 2: return(1); /* half-word */ ++ case 3: return(7); /* double word */ ++ } ++} ++ + int + dispatch_instruction(sregs) + struct pstate *sregs; +@@ -698,6 +712,12 @@ dispatch_instruction(sregs) + } + if (eicc & 1) { + sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f)); ++ if ((sregs->trap == 129) && (sis_gdb_break) && ++ (sregs->inst == 0x91d02001)) ++ { ++ sregs->trap = WPT_TRAP; ++ sregs->bphit = 1; ++ } + } + break; + +@@ -1211,18 +1231,25 @@ dispatch_instruction(sregs) + + address = rs1 + operand2; + +- if (sregs->psr & PSR_S) +- asi = 11; +- else +- asi = 10; +- + if (op3 & 4) { + sregs->icnt = T_ST; /* Set store instruction count */ ++ if (sregs->wpwnum) { ++ if (sregs->wphit = check_wpw(sregs, address, wpmask(op3))) { ++ sregs->trap = WPT_TRAP; ++ break; ++ } ++ } + #ifdef STAT + sregs->nstore++; + #endif + } else { + sregs->icnt = T_LD; /* Set load instruction count */ ++ if (sregs->wprnum) { ++ if (sregs->wphit = check_wpr(sregs, address, wpmask(op3))) { ++ sregs->trap = WPT_TRAP; ++ break; ++ } ++ } + #ifdef STAT + sregs->nload++; + #endif +@@ -2133,12 +2160,18 @@ execute_trap(sregs) + { + int32 cwp; + +- if (sregs->trap == 256) { +- sregs->pc = 0; +- sregs->npc = 4; +- sregs->trap = 0; +- } else if (sregs->trap == 257) { ++ if (sregs->trap >= 256) { ++ switch (sregs->trap) { ++ case 256: ++ sregs->pc = 0; ++ sregs->npc = 4; ++ sregs->trap = 0; ++ break; ++ case ERROR_TRAP: + return (ERROR); ++ case WPT_TRAP: ++ return (WPT_HIT); ++ } + } else { + + if ((sregs->psr & PSR_ET) == 0) +@@ -2231,6 +2264,7 @@ init_regs(sregs) + sregs->fpu_pres = !nfp; + set_fsr(sregs->fsr); + sregs->bphit = 0; ++ sregs->wphit = 0; + sregs->ildreg = 0; + sregs->ildtime = 0; + +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index a22e800..7a8a4e4 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -61,7 +61,8 @@ uint32 last_load_addr = 0; + int nouartrx = 0; + host_callback *sim_callback; + struct memsys *ms = &erc32sys; +-int cputype = 0; /* 0 = erc32, 3 = leon3 */ ++int cputype = 0; /* 0 = erc32, 2 = leon2,3 = leon3 */ ++int sis_gdb_break; + + #ifdef ERRINJ + uint32 errcnt = 0; +@@ -624,6 +625,53 @@ exec_cmd(sregs, cmd) + stat = run_sim(sregs, UINT64_MAX, 0); + daddr = sregs->pc; + ms->sim_halt(); ++ } else if (strncmp(cmd1, "wp", clen) == 0) { ++ for (i = 0; i < sregs->wprnum; i++) { ++ printf(" %d : 0x%08x (read)\n", i + 1, sregs->wprs[i]); ++ } ++ for (i = 0; i < sregs->wpwnum; i++) { ++ printf(" %d : 0x%08x (write)\n", i + 1, sregs->wpws[i]); ++ } ++ } else if (strncmp(cmd1, "+wpr", clen) == 0) { ++ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { ++ sregs->wprs[sregs->wprnum] = VAL(cmd1) & ~0x3; ++ sregs->wprm[sregs->wprnum] = 3; ++ printf("added read watchpoint %d at 0x%08x\n", ++ sregs->wprnum + 1, sregs->wprs[sregs->wprnum]); ++ sregs->wprnum += 1; ++ } ++ } else if (strncmp(cmd1, "-wpr", clen) == 0) { ++ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { ++ i = VAL(cmd1) - 1; ++ if ((i >= 0) && (i < sregs->wprnum)) { ++ printf("deleted read watchpoint %d at 0x%08x\n", i + 1, ++ sregs->wprs[i]); ++ for (; i < sregs->wprnum - 1; i++) { ++ sregs->wprs[i] = sregs->wprs[i + 1]; ++ } ++ sregs->wprnum -= 1; ++ } ++ } ++ } else if (strncmp(cmd1, "+wpw", clen) == 0) { ++ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { ++ sregs->wpws[sregs->wpwnum] = VAL(cmd1) & ~0x3; ++ sregs->wpwm[sregs->wpwnum] = 3; ++ printf("added write watchpoint %d at 0x%08x\n", ++ sregs->wpwnum + 1, sregs->wpws[sregs->wpwnum]); ++ sregs->wpwnum += 1; ++ } ++ } else if (strncmp(cmd1, "-wpw", clen) == 0) { ++ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { ++ i = VAL(cmd1) - 1; ++ if ((i >= 0) && (i < sregs->wpwnum)) { ++ printf("deleted write watchpoint %d at 0x%08x\n", i + 1, ++ sregs->wpws[i]); ++ for (; i < sregs->wpwnum - 1; i++) { ++ sregs->wpws[i] = sregs->wpws[i + 1]; ++ } ++ sregs->wpwnum -= 1; ++ } ++ } + } else + printf("syntax error\n"); + } +@@ -714,6 +762,8 @@ init_bpt(sregs) + struct pstate *sregs; + { + sregs->bptnum = 0; ++ sregs->wprnum = 0; ++ sregs->wpwnum = 0; + sregs->histlen = 0; + sregs->histind = 0; + sregs->histbuf = NULL; +@@ -1023,6 +1073,44 @@ check_bpt(sregs) + return (0); + } + ++int ++check_wpr(sregs, address, mask) ++ struct pstate *sregs; ++ int32 address; ++ unsigned char mask; ++{ ++ int32 i, msk; ++ ++ for (i = 0; i < sregs->wprnum; i++) { ++ msk = ~(mask | sregs->wprm[i]); ++ if (((address ^ sregs->wprs[i]) & msk) == 0) { ++ sregs->wpaddress = address; ++ if (sregs->wphit) return (0); ++ return (WPT_HIT); ++ } ++ } ++ return (0); ++} ++ ++int ++check_wpw(sregs, address, mask) ++ struct pstate *sregs; ++ int32 address; ++ unsigned char mask; ++{ ++ int32 i, msk; ++ ++ for (i = 0; i < sregs->wpwnum; i++) { ++ msk = ~(mask | sregs->wpwm[i]); ++ if (((address ^ sregs->wpws[i]) & msk) == 0) { ++ sregs->wpaddress = address; ++ if (sregs->wphit) return (0); ++ return (WPT_HIT); ++ } ++ } ++ return (0); ++} ++ + void + reset_all() + { +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index 99d5286..7c984bc 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -75,11 +75,7 @@ run_sim(sregs, icount, dis) + sregs->trap = I_ACC_EXC; + } else { + if (deb) { +- if ((sregs->bphit = check_bpt(sregs)) != 0) { +- ms->restore_stdio(); +- return (BPT_HIT); +- } +- if (sregs->histlen) { ++ if (sregs->histlen) { + sregs->histbuf[sregs->histind].addr = sregs->pc; + sregs->histbuf[sregs->histind].time = ebase.simtime; + sregs->histind++; +@@ -90,14 +86,25 @@ run_sim(sregs, icount, dis) + printf(" %8" PRIu64 " ", ebase.simtime); + dis_mem(sregs->pc, 1, &dinfo); + } ++ if ((sregs->bptnum) && (sregs->bphit = check_bpt(sregs))) ++ icount = 0; ++ else { ++ dispatch_instruction(sregs); ++ icount--; ++ } ++ } else { ++ dispatch_instruction(sregs); ++ icount--; + } +- dispatch_instruction(sregs); +- icount--; + } + } + if (sregs->trap) { + irq = 0; +- sregs->err_mode = execute_trap(sregs); ++ if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) { ++ sregs->err_mode = 0; ++ sregs->trap = 0; ++ icount = 0; ++ } + if (sregs->err_mode) { + ms->error_mode(sregs->pc); + icount = 0; +@@ -118,6 +125,10 @@ run_sim(sregs, icount, dis) + ctrl_c = 0; + return (CTRL_C); + } ++ if (sregs->bphit) ++ return (BPT_HIT); ++ if (sregs->wphit) ++ return (WPT_HIT); + return (TIME_OUT); + } + +@@ -283,6 +294,11 @@ main(argc, argv) + printf(" %8" PRIu64 " ", ebase.simtime); + dis_mem(sregs.pc, 1, &dinfo); + break; ++ case WPT_HIT: ++ printf("watchpoint at 0x%08x reached, pc = 0x%08x\n", ++ sregs.wpaddress, sregs.pc); ++ sregs.wphit = 1; ++ break; + default: + break; + } +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index c043504..fda5f01 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -39,8 +39,10 @@ + /* Maximum # of floating point queue */ + #define FPUQN 1 + +-/* Maximum # of breakpoints */ ++/* Maximum # of breakpoints and watchpoints */ + #define BPT_MAX 256 ++#define WPR_MAX 256 ++#define WPW_MAX 256 + + struct histype { + unsigned addr; +@@ -108,6 +110,14 @@ struct pstate { + uint32 bptnum; + uint32 bphit; + uint32 bpts[BPT_MAX]; /* Breakpoints */ ++ uint32 wprnum; ++ uint32 wphit; ++ uint32 wprs[WPR_MAX]; /* Read Watchpoints */ ++ unsigned char wprm[WPR_MAX]; /* Read Watchpoint masks*/ ++ uint32 wpwnum; ++ uint32 wpws[WPW_MAX]; /* Write Watchpoints */ ++ unsigned char wpwm[WPW_MAX]; /* Write Watchpoint masks */ ++ uint32 wpaddress; + + uint32 ltime; /* Load interlock time */ + uint32 hold; /* IU hold cycles in current inst */ +@@ -184,12 +194,19 @@ struct memsys { + }; + + ++/* return values for run_sim */ + #define OK 0 + #define TIME_OUT 1 + #define BPT_HIT 2 + #define ERROR 3 + #define CTRL_C 4 ++#define WPT_HIT 5 + ++/* special simulator trap types */ ++#define ERROR_TRAP 257 ++#define WPT_TRAP 258 ++ ++/* cpu type defines */ + #define CPU_LEON2 2 + #define CPU_LEON3 3 + +@@ -240,6 +257,9 @@ extern void advance_time (struct pstate *sregs); + extern uint32 now (void); + extern int wait_for_irq (void); + extern int check_bpt (struct pstate *sregs); ++extern int check_wpr(struct pstate *sregs, int32 address, unsigned char mask); ++extern int check_wpw(struct pstate *sregs, int32 address, unsigned char mask); ++ + extern void reset_all (void); + extern void sys_reset (void); + extern void sys_halt (void); +@@ -249,6 +269,7 @@ extern host_callback *sim_callback; + extern int current_target_byte_order; + extern int dumbio; + extern int cputype; ++extern int sis_gdb_break; + + /* exec.c */ + extern int dispatch_instruction (struct pstate *sregs); +-- +1.9.1 + |