OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [debug/] [debug_unit.c] - Blame information for rev 1308

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 221 markom
/* debug_unit.c -- Simulation of Or1k debug unit
2
   Copyright (C) 2001 Chris Ziomkowski, chris@asics.ws
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/*
21
  This is an architectural level simulation of the Or1k debug
22
  unit as described in OpenRISC 1000 System Architecture Manual,
23
  v. 0.1 on 22 April, 2001. This unit is described in Section 13.
24
 
25
  Every attempt has been made to be as accurate as possible with
26
  respect to the registers and the behavior. There are no known
27
  limitations at this time.
28
*/
29
 
30 587 markom
//#define DEBUG_JTAG 0
31 479 markom
 
32 221 markom
#include <stdlib.h>
33
#include <stdio.h>
34
#include <string.h>
35
 
36
#include "debug_unit.h"
37
#include "sim-config.h"
38
#include "except.h"
39
#include "arch.h"
40
#include "abstract.h"
41
#include "parse.h"
42
#include "sprs.h"
43 485 markom
#include "gdb.h"
44 1308 phoenix
#include "except.h"
45 221 markom
#include "opcode/or32.h"
46 1308 phoenix
#include "debug.h"
47 221 markom
 
48
DevelopmentInterface development;
49
 
50
/* External STALL signal to debug interface */
51 479 markom
int in_reset = 0;
52 221 markom
 
53 479 markom
/* Current watchpoint state */
54
unsigned long watchpoints = 0;
55 221 markom
 
56 1244 hpanther
static int calculate_watchpoints(DebugUnitAction action, unsigned long udata);
57 221 markom
 
58 479 markom
void set_stall_state(int state)
59 221 markom
{
60 479 markom
  development.riscop &= ~RISCOP_STALL;
61
  development.riscop |= state ? RISCOP_STALL : 0;
62
  if(testsprbits(SPR_DMR1, SPR_DMR1_DXFW)) /* If debugger disabled */
63
    state = 0;
64 884 markom
  runtime.cpu.stalled = state;
65 221 markom
}
66
 
67 479 markom
void du_reset()
68 221 markom
{
69 479 markom
  development.riscop = 0;
70
  set_stall_state (0);
71 221 markom
}
72
 
73 1244 hpanther
void du_clock()
74
{
75
        watchpoints=0;
76
};
77
 
78 1308 phoenix
int CheckDebugUnit(DebugUnitAction action, unsigned long udata)
79 221 markom
{
80 479 markom
  /* Do not stop, if we have debug module disabled or during reset */
81
  if(!config.debug.enabled || in_reset)
82 221 markom
    return 0;
83 479 markom
 
84 221 markom
  /* If we're single stepping, always stop */
85 479 markom
  if(action == DebugInstructionFetch && testsprbits (SPR_DMR1, SPR_DMR1_ST))
86 221 markom
    return 1;
87
 
88 1308 phoenix
  /* is any watchpoint enabled to generate a break or count? If not, ignore */
89 1244 hpanther
  if(mfspr(SPR_DMR2) & (SPR_DMR2_WGB|SPR_DMR2_AWTC))
90
          return calculate_watchpoints(action, udata);
91
 
92 479 markom
  return 0;
93 221 markom
}
94
 
95 479 markom
/* Checks whether we should stall the RISC or cause an exception */
96 1244 hpanther
static int calculate_watchpoints(DebugUnitAction action, unsigned long udata)
97 221 markom
{
98 1244 hpanther
        int breakpoint = 0;
99
        int i, bit;
100 221 markom
 
101 1244 hpanther
        /* Hopefully this loop would be unrolled run at max. speed */
102
        for(i = 0, bit = 1; i < 11; i++, bit <<= 1) {
103
                int chain1, chain2;
104
                int match = 0;
105
                int DCR_hit = 0;
106
 
107
                /* Calculate first 8 matchpoints, result is put into DCR_hit */
108
                if (i < 8) {
109
                        unsigned long dcr = mfspr (SPR_DCR(i));
110
                        unsigned long dcr_ct=dcr&SPR_DCR_CT;    // the CT field alone
111
                        /* Is this matchpoint a propos for the current action? */
112
                        if ( ((dcr & SPR_DCR_DP) && dcr_ct) &&// DVR/DCP pair present
113
                (((action==DebugInstructionFetch) && (dcr_ct == SPR_DCR_CT_IFEA))
114
        || ((action==DebugLoadAddress) && ((dcr_ct == SPR_DCR_CT_LEA) || (dcr_ct == SPR_DCR_CT_LSEA)))
115
                || ((action==DebugStoreAddress) && ((dcr_ct == SPR_DCR_CT_SEA) || (dcr_ct == SPR_DCR_CT_LSEA)))
116
                || ((action==DebugLoadData) && ((dcr_ct == SPR_DCR_CT_LD) || (dcr_ct == SPR_DCR_CT_LSD)))
117
                || ((action==DebugStoreData) && ((dcr_ct == SPR_DCR_CT_SD) || (dcr_ct == SPR_DCR_CT_LSD)))) )
118
                        {
119
                                 unsigned long op1=udata;
120
                                 unsigned long op2 = mfspr (SPR_DVR(i));
121
                                 /* Perform signed comparison?  */
122
                                 if (dcr & SPR_DCR_SC) {
123
                                         long sop1 = op1, sop2 = op2; /* Convert to signed */
124
                                         switch(dcr & SPR_DCR_CC) {
125
                                                 case SPR_DCR_CC_MASKED: DCR_hit = sop1 & sop2; break;
126
                                                 case SPR_DCR_CC_EQUAL: DCR_hit = sop1 == sop2; break;
127
                                                 case SPR_DCR_CC_NEQUAL: DCR_hit = sop1 != sop2; break;
128
                                                 case SPR_DCR_CC_LESS: DCR_hit = sop1 < sop2; break;
129
                                                 case SPR_DCR_CC_LESSE: DCR_hit = sop1 <= sop2; break;
130
                                                 case SPR_DCR_CC_GREAT: DCR_hit = sop1 > sop2; break;
131
                                                 case SPR_DCR_CC_GREATE: DCR_hit = sop1 >= sop2; break;
132
                                         }
133
                                 } else {
134
                                         switch(dcr & SPR_DCR_CC) {
135
                                                 case SPR_DCR_CC_MASKED: DCR_hit = op1 & op2; break;
136
                                                 case SPR_DCR_CC_EQUAL: DCR_hit = op1 == op2; break;
137
                                                 case SPR_DCR_CC_NEQUAL: DCR_hit = op1 != op2; break;
138
                                                 case SPR_DCR_CC_LESS: DCR_hit = op1 < op2; break;
139
                                                 case SPR_DCR_CC_LESSE: DCR_hit = op1 <= op2; break;
140
                                                 case SPR_DCR_CC_GREAT: DCR_hit = op1 > op2; break;
141
                                                 case SPR_DCR_CC_GREATE: DCR_hit = op1 >= op2; break;
142
                                         }
143
                                 }
144
                        }
145
                }
146
 
147
                /* Chain matchpoints */
148
                switch(i)
149
                {
150
                        case 0:
151
                                chain1 = chain2 = DCR_hit;
152
                                break;
153
                        case 8:
154
                                chain1 = getsprbits (SPR_DWCR0, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR0, SPR_DWCR_MATCH);
155
                                chain2 = watchpoints & (1 << 7);
156
                                break;
157
                        case 9:
158
                                chain1 = getsprbits (SPR_DWCR1, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR1, SPR_DWCR_MATCH);
159
                                chain2 = watchpoints & (1 << 8);
160
                                break;
161
                        case 10:
162
                                /* TODO: External watchpoint - not yet handled!  */
163 479 markom
#if 0
164 1244 hpanther
                                chain1 = external_watchpoint;
165
                                chain2 = watchpoints & (1 << 9);
166 479 markom
#else
167 1244 hpanther
                                chain1 = chain2 = 0;
168 479 markom
#endif
169 1244 hpanther
                                break;
170
                        default:
171
                                chain1 = DCR_hit;
172
                                chain2 = watchpoints & (bit >> 1);
173
                                break;
174
                }
175 221 markom
 
176 1244 hpanther
                switch(getsprbits (SPR_DMR1, SPR_DMR1_CW0 << i)) {
177
                        case 0: match = chain1;           break;
178
                        case 1: match = chain1 && chain2; break;
179
                        case 2: match = chain1 || chain2; break;
180
                        default:
181
                                break;
182
                }
183 221 markom
 
184 1244 hpanther
                // Increment counters & generate counter break
185
                if(match)
186
                {
187
                        if(!(watchpoints & bit)) // watchpoint did not appear before in this clock cycle
188
                        {
189
                                int counter = (getsprbits (SPR_DMR2, SPR_DMR2_AWTC) & bit) ? 1 : 0;
190
                                int enabled = counter ? getsprbits (SPR_DMR2, SPR_DMR2_WCE1) : getsprbits (SPR_DMR2, SPR_DMR2_WCE0);
191
                                if(enabled)
192
                                        setsprbits (SPR_DWCR0 + counter, SPR_DWCR_COUNT, getsprbits (SPR_DWCR0 + counter, SPR_DWCR_COUNT) + 1);
193
                                watchpoints |= bit;
194
                        }
195 221 markom
 
196 1244 hpanther
                        // should this watchpoint generate a breakpoint?
197
                        if(getsprbits (SPR_DMR2, SPR_DMR2_WGB) & bit) breakpoint = 1;
198
                }
199
        }
200
        return breakpoint;
201 221 markom
}
202 1244 hpanther
 
203 221 markom
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL;
204
 
205 479 markom
int DebugGetRegister(unsigned int address, unsigned long* data)
206 221 markom
{
207 1244 hpanther
  int err=0;
208 221 markom
#ifdef DEBUG_JTAG
209 997 markom
  PRINTF("Debug get register %x\n",address);
210 221 markom
  fflush(stdout);
211
#endif
212
  switch(current_scan_chain)
213
    {
214
    case JTAG_CHAIN_DEBUG_UNIT:
215 479 markom
      *data = mfspr (address);
216
      debug (2, "READ  (%08x) = %08x\n", address, *data);
217 642 ivang
      if (runtime.sim.fspr_log) {
218 1308 phoenix
        fprintf(runtime.sim.fspr_log, "Read from SPR : [%08X] -> [%08lX]\n",
219
                address, *data);
220 642 ivang
      }
221 221 markom
      break;
222
    case JTAG_CHAIN_TRACE:
223
      *data = 0;  /* Scan chain not yet implemented */
224
      break;
225
    case JTAG_CHAIN_DEVELOPMENT:
226 479 markom
      err = get_devint_reg(address,data);
227 221 markom
      break;
228
    case JTAG_CHAIN_WISHBONE:
229 1244 hpanther
      err = debug_get_mem(address,data);
230 221 markom
      break;
231
    }
232
#ifdef DEBUG_JTAG
233 997 markom
  PRINTF("!get reg %x\n", *data);
234 221 markom
  fflush(stdout);
235
#endif
236
  return err;
237
}
238
 
239 479 markom
int DebugSetRegister(unsigned int address,unsigned long data)
240 221 markom
{
241 1244 hpanther
  int err=0;
242 221 markom
#ifdef DEBUG_JTAG
243 997 markom
  PRINTF("Debug set register %x <- %x\n", address, data);
244 221 markom
  fflush(stdout);
245
#endif
246
  switch(current_scan_chain)
247
    {
248
    case JTAG_CHAIN_DEBUG_UNIT:
249 479 markom
      debug (2, "WRITE (%08x) = %08x\n", address, data);
250 642 ivang
      if (runtime.sim.fspr_log) {
251 1308 phoenix
        fprintf(runtime.sim.fspr_log, "Write to SPR  : [%08X] <- [%08lX]\n",
252
                address, data);
253 642 ivang
      }
254 479 markom
      mtspr(address, data);
255 221 markom
      break;
256
    case JTAG_CHAIN_TRACE:
257
      err = JTAG_PROXY_ACCESS_EXCEPTION;
258
      break;
259
    case JTAG_CHAIN_DEVELOPMENT:
260 479 markom
      err = set_devint_reg (address, data);
261 221 markom
      break;
262
    case JTAG_CHAIN_WISHBONE:
263 479 markom
      err = debug_set_mem (address, data);
264 221 markom
      break;
265
    }
266
#ifdef DEBUG_JTAG
267 997 markom
  PRINTF("!set reg\n");
268 221 markom
  fflush(stdout);
269
#endif
270
  return err;
271
}
272
 
273
int DebugSetChain(int chain)
274
{
275
#ifdef DEBUG_JTAG
276 997 markom
  PRINTF("Debug set chain %x\n",chain);
277 221 markom
  fflush(stdout);
278
#endif
279
  switch(chain)
280
    {
281
    case JTAG_CHAIN_DEBUG_UNIT:
282
    case JTAG_CHAIN_TRACE:
283
    case JTAG_CHAIN_DEVELOPMENT:
284
    case JTAG_CHAIN_WISHBONE:
285
      current_scan_chain = chain;
286
      break;
287
    default: /* All other chains not implemented */
288
      return JTAG_PROXY_INVALID_CHAIN;
289
    }
290
 
291
#ifdef DEBUG_JTAG
292 997 markom
  PRINTF("!set chain\n");
293 221 markom
  fflush(stdout);
294
#endif
295
  return 0;
296
}
297
 
298 479 markom
void sim_reset ();
299
 
300
/* Sets development interface register */
301
int set_devint_reg(unsigned int address, unsigned long data)
302 221 markom
{
303
  int err = 0;
304 479 markom
  unsigned long value = data;
305 221 markom
  int old_value;
306
 
307 479 markom
  switch(address) {
308
    case DEVELOPINT_MODER: development.moder = value; break;
309
    case DEVELOPINT_TSEL:  development.tsel = value;  break;
310
    case DEVELOPINT_QSEL:  development.qsel = value;  break;
311
    case DEVELOPINT_SSEL:  development.ssel = value;  break;
312 221 markom
    case DEVELOPINT_RISCOP:
313 479 markom
      old_value = (development.riscop & RISCOP_RESET) != 0;
314
      development.riscop = value;
315
      in_reset = (development.riscop & RISCOP_RESET) != 0;
316 221 markom
      /* Reset the cpu on the negative edge of RESET */
317 479 markom
      if(old_value && !in_reset)
318
        sim_reset(); /* Reset all units */
319
      set_stall_state((development.riscop & RISCOP_STALL) != 0);
320 221 markom
      break;
321
    case DEVELOPINT_RECWP0:
322
    case DEVELOPINT_RECWP1:
323
    case DEVELOPINT_RECWP2:
324
    case DEVELOPINT_RECWP3:
325
    case DEVELOPINT_RECWP4:
326
    case DEVELOPINT_RECWP5:
327
    case DEVELOPINT_RECWP6:
328
    case DEVELOPINT_RECWP7:
329
    case DEVELOPINT_RECWP8:
330
    case DEVELOPINT_RECWP9:
331 479 markom
    case DEVELOPINT_RECWP10: development.recwp[address - DEVELOPINT_RECWP0] = value; break;
332
    case DEVELOPINT_RECBP0:  development.recbp = value; break;
333 221 markom
    default:
334
      err = JTAG_PROXY_INVALID_ADDRESS;
335
      break;
336
    }
337 479 markom
#ifdef DEBUG_JTAG
338 997 markom
  PRINTF("set_devint_reg %08x = %08x\n", address, data);
339 479 markom
  fflush(stdout);
340
#endif
341 221 markom
  return err;
342
}
343
 
344 1308 phoenix
/* Gets development interface register */
345 479 markom
int get_devint_reg(unsigned int address,unsigned long *data)
346 221 markom
{
347
  int err = 0;
348 479 markom
  unsigned long value = 0;
349 221 markom
 
350 479 markom
  switch(address) {
351
    case DEVELOPINT_MODER:    value = development.moder; break;
352
    case DEVELOPINT_TSEL:     value = development.tsel; break;
353
    case DEVELOPINT_QSEL:     value = development.qsel; break;
354
    case DEVELOPINT_SSEL:     value = development.ssel; break;
355
    case DEVELOPINT_RISCOP:   value = development.riscop; break;
356 221 markom
    case DEVELOPINT_RECWP0:
357
    case DEVELOPINT_RECWP1:
358
    case DEVELOPINT_RECWP2:
359
    case DEVELOPINT_RECWP3:
360
    case DEVELOPINT_RECWP4:
361
    case DEVELOPINT_RECWP5:
362
    case DEVELOPINT_RECWP6:
363
    case DEVELOPINT_RECWP7:
364
    case DEVELOPINT_RECWP8:
365
    case DEVELOPINT_RECWP9:
366 479 markom
    case DEVELOPINT_RECWP10:  value = development.recwp[address - DEVELOPINT_RECWP0]; break;
367
    case DEVELOPINT_RECBP0:   value = development.recbp; break;
368
    default:                  err = JTAG_PROXY_INVALID_ADDRESS; break;
369
  }
370 221 markom
 
371 479 markom
#ifdef DEBUG_JTAG
372 997 markom
  PRINTF("get_devint_reg %08x = %08x\n", address, value);
373 479 markom
  fflush(stdout);
374
#endif
375 221 markom
  *data = value;
376
  return err;
377
}
378
 
379 479 markom
/* Writes to bus address */
380
int debug_set_mem (unsigned int address,unsigned long data)
381 221 markom
{
382
  int err = 0;
383 479 markom
  debug (2, "MEMWRITE (%08x) = %08x\n", address, data);
384 221 markom
 
385
 
386
  if(!verify_memoryarea(address))
387 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
388
  else {
389 1244 hpanther
          // circumvent the read-only check usually done for mem accesses
390
          // data is in host order, because that's what simmem_write_word needs
391
          simmem_write_word(address, data);
392 479 markom
  }
393 221 markom
  return err;
394
}
395
 
396 1308 phoenix
/* Reads from bus address */
397 1244 hpanther
int debug_get_mem(unsigned int address,unsigned long *data)
398 221 markom
{
399
  int err = 0;
400
  if(!verify_memoryarea(address))
401 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
402 221 markom
  else
403 479 markom
  {
404 1244 hpanther
          *data=simmem_read_word(address);
405 479 markom
  }
406
  debug (2, "MEMREAD  (%08x) = %08x\n", address, *data);
407 221 markom
  return err;
408
}
409
 
410 479 markom
/* debug_ignore_exception returns 1 if the exception should be ignored. */
411
int debug_ignore_exception (unsigned long except)
412 221 markom
{
413
  int result = 0;
414 479 markom
  unsigned long dsr = mfspr (SPR_DSR);
415
  unsigned long drr = mfspr (SPR_DRR);
416
 
417 693 markom
#if DEBUG_JTAG
418 997 markom
  PRINTF ("dsr 0x%08x drr 0x%08x \n", dsr, drr);
419 693 markom
#endif
420
 
421 479 markom
  switch(except) {
422
    case EXCEPT_RESET:     drr |= result = dsr & SPR_DSR_RSTE; break;
423
    case EXCEPT_BUSERR:    drr |= result = dsr & SPR_DSR_BUSEE; break;
424
    case EXCEPT_DPF:       drr |= result = dsr & SPR_DSR_DPFE; break;
425
    case EXCEPT_IPF:       drr |= result = dsr & SPR_DSR_IPFE; break;
426 600 simons
    case EXCEPT_TICK:      drr |= result = dsr & SPR_DSR_TTE; break;
427 479 markom
    case EXCEPT_ALIGN:     drr |= result = dsr & SPR_DSR_AE; break;
428
    case EXCEPT_ILLEGAL:   drr |= result = dsr & SPR_DSR_IIE; break;
429 600 simons
    case EXCEPT_INT:       drr |= result = dsr & SPR_DSR_IE; break;
430 479 markom
    case EXCEPT_DTLBMISS:  drr |= result = dsr & SPR_DSR_DME; break;
431
    case EXCEPT_ITLBMISS:  drr |= result = dsr & SPR_DSR_IME; break;
432
    case EXCEPT_RANGE:     drr |= result = dsr & SPR_DSR_RE; break;
433
    case EXCEPT_SYSCALL:   drr |= result = dsr & SPR_DSR_SCE; break;
434
    case EXCEPT_TRAP:      drr |= result = dsr & SPR_DSR_TE; break;
435 221 markom
    default:
436
      break;
437 479 markom
  }
438 693 markom
#if DEBUG_JTAG
439 997 markom
  PRINTF ("dsr 0x%08x drr 0x%08x result %i\n", dsr, drr, result);
440 693 markom
#endif
441 221 markom
 
442 479 markom
  mtspr (SPR_DRR, drr);
443
  set_stall_state (result != 0);
444
  return (result != 0);
445 221 markom
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.