source: rtems-tools/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch @ bfd2b7d

4.104.115
Last change on this file since bfd2b7d was bfd2b7d, checked in by Joel Sherrill <joel.sherrill@…>, on 03/26/15 at 18:20:45

Add Jiri Gaisler SIS patch set for gdb 7.9

This patch set adds a lot of new capability including support for
the leon2 and leon3. It also eliminates the difference between
the initial state of the simulated erc32 and the real hardware.

  • Property mode set to 100644
File size: 10.1 KB
  • sim/erc32/exec.c

    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 b extract_byte_signed(uint32 data, uint32 address) 
    395395    return(tmp);
    396396}
    397397
     398/* Decode watchpoint address mask from opcode. Not correct for LDST,
     399   SWAP and STFSR but watchpoints will work anyway. */
     400
     401static unsigned char
     402wpmask(uint32 op3)
     403{
     404    switch (op3 & 3) {
     405      case 0: return(3);  /* word */
     406      case 1: return(0);  /* byte */
     407      case 2: return(1);  /* half-word */
     408      case 3: return(7);  /* double word */
     409    }
     410}
     411
    398412int
    399413dispatch_instruction(sregs)
    400414    struct pstate  *sregs;
    dispatch_instruction(sregs) 
    698712                }
    699713                if (eicc & 1) {
    700714                    sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f));
     715                    if ((sregs->trap == 129) && (sis_gdb_break) &&
     716                                (sregs->inst == 0x91d02001))
     717                    {
     718                        sregs->trap = WPT_TRAP;
     719                        sregs->bphit = 1;
     720                    }
    701721                }
    702722                break;
    703723
    dispatch_instruction(sregs) 
    12111231
    12121232        address = rs1 + operand2;
    12131233
    1214         if (sregs->psr & PSR_S)
    1215             asi = 11;
    1216          else
    1217             asi = 10;
    1218 
    12191234        if (op3 & 4) {
    12201235            sregs->icnt = T_ST; /* Set store instruction count */
     1236            if (sregs->wpwnum) {
     1237               if (sregs->wphit = check_wpw(sregs, address, wpmask(op3))) {
     1238                   sregs->trap = WPT_TRAP;
     1239                   break;
     1240               }
     1241            }
    12211242#ifdef STAT
    12221243            sregs->nstore++;
    12231244#endif
    12241245        } else {
    12251246            sregs->icnt = T_LD; /* Set load instruction count */
     1247            if (sregs->wprnum) {
     1248               if (sregs->wphit = check_wpr(sregs, address, wpmask(op3))) {
     1249                   sregs->trap = WPT_TRAP;
     1250                   break;
     1251               }
     1252            }
    12261253#ifdef STAT
    12271254            sregs->nload++;
    12281255#endif
    execute_trap(sregs) 
    21332160{
    21342161    int32           cwp;
    21352162
    2136     if (sregs->trap == 256) {
    2137         sregs->pc = 0;
    2138         sregs->npc = 4;
    2139         sregs->trap = 0;
    2140     } else if (sregs->trap == 257) {
     2163    if (sregs->trap >= 256) {
     2164        switch (sregs->trap) {
     2165        case 256:
     2166            sregs->pc = 0;
     2167            sregs->npc = 4;
     2168            sregs->trap = 0;
     2169            break;
     2170        case ERROR_TRAP:
    21412171            return (ERROR);
     2172        case WPT_TRAP:
     2173            return (WPT_HIT);
     2174        }
    21422175    } else {
    21432176
    21442177        if ((sregs->psr & PSR_ET) == 0)
    init_regs(sregs) 
    22312264    sregs->fpu_pres = !nfp;
    22322265    set_fsr(sregs->fsr);
    22332266    sregs->bphit = 0;
     2267    sregs->wphit = 0;
    22342268    sregs->ildreg = 0;
    22352269    sregs->ildtime = 0;
    22362270
  • sim/erc32/func.c

    diff --git a/sim/erc32/func.c b/sim/erc32/func.c
    index a22e800..7a8a4e4 100644
    a b uint32 last_load_addr = 0; 
    6161int             nouartrx = 0;
    6262host_callback   *sim_callback;
    6363struct memsys *ms = &erc32sys;
    64 int             cputype = 0;            /* 0 = erc32, 3 = leon3 */
     64int             cputype = 0;            /* 0 = erc32, 2 = leon2,3 = leon3 */
     65int             sis_gdb_break;
    6566
    6667#ifdef ERRINJ
    6768uint32          errcnt = 0;
    exec_cmd(sregs, cmd) 
    624625            stat = run_sim(sregs, UINT64_MAX, 0);
    625626            daddr = sregs->pc;
    626627            ms->sim_halt();
     628        } else if (strncmp(cmd1, "wp", clen) == 0) {
     629            for (i = 0; i < sregs->wprnum; i++) {
     630                printf("  %d : 0x%08x (read)\n", i + 1, sregs->wprs[i]);
     631            }
     632            for (i = 0; i < sregs->wpwnum; i++) {
     633                printf("  %d : 0x%08x (write)\n", i + 1, sregs->wpws[i]);
     634            }
     635        } else if (strncmp(cmd1, "+wpr", clen) == 0) {
     636            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
     637                sregs->wprs[sregs->wprnum] = VAL(cmd1) & ~0x3;
     638                sregs->wprm[sregs->wprnum] = 3;
     639                printf("added read watchpoint %d at 0x%08x\n",
     640                       sregs->wprnum + 1, sregs->wprs[sregs->wprnum]);
     641                sregs->wprnum += 1;
     642            }
     643        } else if (strncmp(cmd1, "-wpr", clen) == 0) {
     644            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
     645                i = VAL(cmd1) - 1;
     646                if ((i >= 0) && (i < sregs->wprnum)) {
     647                    printf("deleted read watchpoint %d at 0x%08x\n", i + 1,
     648                           sregs->wprs[i]);
     649                    for (; i < sregs->wprnum - 1; i++) {
     650                        sregs->wprs[i] = sregs->wprs[i + 1];
     651                    }
     652                    sregs->wprnum -= 1;
     653                }
     654            }
     655        } else if (strncmp(cmd1, "+wpw", clen) == 0) {
     656            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
     657                sregs->wpws[sregs->wpwnum] = VAL(cmd1) & ~0x3;
     658                sregs->wpwm[sregs->wpwnum] = 3;
     659                printf("added write watchpoint %d at 0x%08x\n",
     660                       sregs->wpwnum + 1, sregs->wpws[sregs->wpwnum]);
     661                sregs->wpwnum += 1;
     662            }
     663        } else if (strncmp(cmd1, "-wpw", clen) == 0) {
     664            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
     665                i = VAL(cmd1) - 1;
     666                if ((i >= 0) && (i < sregs->wpwnum)) {
     667                    printf("deleted write watchpoint %d at 0x%08x\n", i + 1,
     668                           sregs->wpws[i]);
     669                    for (; i < sregs->wpwnum - 1; i++) {
     670                        sregs->wpws[i] = sregs->wpws[i + 1];
     671                    }
     672                    sregs->wpwnum -= 1;
     673                }
     674            }
    627675        } else
    628676            printf("syntax error\n");
    629677    }
    init_bpt(sregs) 
    714762    struct pstate  *sregs;
    715763{
    716764    sregs->bptnum = 0;
     765    sregs->wprnum = 0;
     766    sregs->wpwnum = 0;
    717767    sregs->histlen = 0;
    718768    sregs->histind = 0;
    719769    sregs->histbuf = NULL;
    check_bpt(sregs) 
    10231073    return (0);
    10241074}
    10251075
     1076int
     1077check_wpr(sregs, address, mask)
     1078    struct pstate  *sregs;
     1079    int32          address;
     1080    unsigned char  mask;
     1081{
     1082    int32           i, msk;
     1083
     1084    for (i = 0; i < sregs->wprnum; i++) {
     1085        msk = ~(mask | sregs->wprm[i]);
     1086        if (((address ^ sregs->wprs[i]) & msk) == 0) {
     1087            sregs->wpaddress = address;
     1088            if (sregs->wphit) return (0);
     1089            return (WPT_HIT);
     1090        }
     1091    }
     1092    return (0);
     1093}
     1094
     1095int
     1096check_wpw(sregs, address, mask)
     1097    struct pstate  *sregs;
     1098    int32          address;
     1099    unsigned char  mask;
     1100{
     1101    int32           i, msk;
     1102
     1103    for (i = 0; i < sregs->wpwnum; i++) {
     1104        msk = ~(mask | sregs->wpwm[i]);
     1105        if (((address ^ sregs->wpws[i]) & msk) == 0) {
     1106            sregs->wpaddress = address;
     1107            if (sregs->wphit) return (0);
     1108            return (WPT_HIT);
     1109        }
     1110    }
     1111    return (0);
     1112}
     1113
    10261114void
    10271115reset_all()
    10281116{
  • sim/erc32/sis.c

    diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
    index 99d5286..7c984bc 100644
    a b run_sim(sregs, icount, dis) 
    7575                    sregs->trap = I_ACC_EXC;
    7676                } else {
    7777                    if (deb) {
    78                         if ((sregs->bphit = check_bpt(sregs)) != 0) {
    79                             ms->restore_stdio();
    80                             return (BPT_HIT);
    81                         }
    82                         if (sregs->histlen) {
     78                        if (sregs->histlen) {
    8379                            sregs->histbuf[sregs->histind].addr = sregs->pc;
    8480                            sregs->histbuf[sregs->histind].time = ebase.simtime;
    8581                            sregs->histind++;
    run_sim(sregs, icount, dis) 
    9086                            printf(" %8" PRIu64 " ", ebase.simtime);
    9187                            dis_mem(sregs->pc, 1, &dinfo);
    9288                        }
     89                        if ((sregs->bptnum) && (sregs->bphit = check_bpt(sregs)))
     90                            icount = 0;
     91                        else {
     92                            dispatch_instruction(sregs);
     93                            icount--;
     94                        }
     95                    } else {
     96                        dispatch_instruction(sregs);
     97                        icount--;
    9398                    }
    94                     dispatch_instruction(sregs);
    95                     icount--;
    9699                }
    97100            }
    98101            if (sregs->trap) {
    99102                irq = 0;
    100                 sregs->err_mode = execute_trap(sregs);
     103                if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) {
     104                    sregs->err_mode = 0;
     105                    sregs->trap = 0;
     106                    icount = 0;
     107                }
    101108                if (sregs->err_mode) {
    102109                    ms->error_mode(sregs->pc);
    103110                    icount = 0;
    run_sim(sregs, icount, dis) 
    118125        ctrl_c = 0;
    119126        return (CTRL_C);
    120127    }
     128    if (sregs->bphit)
     129        return (BPT_HIT);
     130    if (sregs->wphit)
     131        return (WPT_HIT);
    121132    return (TIME_OUT);
    122133}
    123134
    main(argc, argv) 
    283294            printf(" %8" PRIu64 " ", ebase.simtime);
    284295            dis_mem(sregs.pc, 1, &dinfo);
    285296            break;
     297        case WPT_HIT:
     298            printf("watchpoint at 0x%08x reached, pc = 0x%08x\n",
     299                sregs.wpaddress, sregs.pc);
     300            sregs.wphit = 1;
     301            break;
    286302        default:
    287303            break;
    288304        }
  • sim/erc32/sis.h

    diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
    index c043504..fda5f01 100644
    a b  
    3939/* Maximum # of floating point queue */
    4040#define FPUQN   1
    4141
    42 /* Maximum # of breakpoints */
     42/* Maximum # of breakpoints and watchpoints */
    4343#define BPT_MAX 256
     44#define WPR_MAX 256
     45#define WPW_MAX 256
    4446
    4547struct histype {
    4648    unsigned        addr;
    struct pstate { 
    108110    uint32          bptnum;
    109111    uint32          bphit;
    110112    uint32          bpts[BPT_MAX];      /* Breakpoints */
     113    uint32          wprnum;
     114    uint32          wphit;
     115    uint32          wprs[WPR_MAX];      /* Read Watchpoints */
     116    unsigned char   wprm[WPR_MAX];      /* Read Watchpoint masks*/
     117    uint32          wpwnum;
     118    uint32          wpws[WPW_MAX];      /* Write Watchpoints */
     119    unsigned char   wpwm[WPW_MAX];      /* Write Watchpoint masks */
     120    uint32          wpaddress;
    111121
    112122    uint32          ltime;      /* Load interlock time */
    113123    uint32          hold;       /* IU hold cycles in current inst */
    struct memsys { 
    184194};
    185195
    186196
     197/* return values for run_sim */
    187198#define OK 0
    188199#define TIME_OUT 1
    189200#define BPT_HIT 2
    190201#define ERROR 3
    191202#define CTRL_C 4
     203#define WPT_HIT 5
    192204
     205/* special simulator trap types */
     206#define ERROR_TRAP 257
     207#define WPT_TRAP   258
     208
     209/* cpu type defines */
    193210#define CPU_LEON2  2
    194211#define CPU_LEON3  3
    195212
    extern void advance_time (struct pstate *sregs); 
    240257extern uint32   now (void);
    241258extern int      wait_for_irq (void);
    242259extern int      check_bpt (struct pstate *sregs);
     260extern int      check_wpr(struct pstate *sregs, int32 address, unsigned char mask);
     261extern int      check_wpw(struct pstate *sregs, int32 address, unsigned char mask);
     262
    243263extern void     reset_all (void);
    244264extern void     sys_reset (void);
    245265extern void     sys_halt (void);
    extern host_callback *sim_callback; 
    249269extern int      current_target_byte_order;
    250270extern int      dumbio;
    251271extern int      cputype;
     272extern int      sis_gdb_break;
    252273
    253274/* exec.c */
    254275extern int      dispatch_instruction (struct pstate *sregs);
Note: See TracBrowser for help on using the repository browser.