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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [debug/] [debug_unit.c] - Blame information for rev 1350

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

powered by: WebSVN 2.1.0

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