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 1147

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

powered by: WebSVN 2.1.0

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