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 884

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

powered by: WebSVN 2.1.0

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