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 1244

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

powered by: WebSVN 2.1.0

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