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 1782

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 1351 nogj
  int breakpoint = 0;
106
  int i, bit;
107 221 markom
 
108 1351 nogj
  /* 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 1244 hpanther
 
114 1351 nogj
    /* 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) ||
122
                                           (dcr_ct == SPR_DCR_CT_LSEA))) ||
123
           ((action==DebugStoreAddress) && ((dcr_ct == SPR_DCR_CT_SEA) ||
124
                                            (dcr_ct == SPR_DCR_CT_LSEA))) ||
125
           ((action==DebugLoadData) && ((dcr_ct == SPR_DCR_CT_LD) ||
126
                                        (dcr_ct == SPR_DCR_CT_LSD))) ||
127
           ((action==DebugStoreData) && ((dcr_ct == SPR_DCR_CT_SD) ||
128
                                         (dcr_ct == SPR_DCR_CT_LSD)))) ) {
129
        unsigned long op1 = udata;
130
        unsigned long op2 = mfspr (SPR_DVR(i));
131
        /* Perform signed comparison?  */
132
        if (dcr & SPR_DCR_SC) {
133
          long sop1 = op1, sop2 = op2; /* Convert to signed */
134
          switch(dcr & SPR_DCR_CC) {
135
          case SPR_DCR_CC_MASKED: DCR_hit = sop1 & sop2; break;
136
          case SPR_DCR_CC_EQUAL: DCR_hit = sop1 == sop2; break;
137
          case SPR_DCR_CC_NEQUAL: DCR_hit = sop1 != sop2; break;
138
          case SPR_DCR_CC_LESS: DCR_hit = sop1 < sop2; break;
139
          case SPR_DCR_CC_LESSE: DCR_hit = sop1 <= sop2; break;
140
          case SPR_DCR_CC_GREAT: DCR_hit = sop1 > sop2; break;
141
          case SPR_DCR_CC_GREATE: DCR_hit = sop1 >= sop2; break;
142
          }
143
        } else {
144
          switch(dcr & SPR_DCR_CC) {
145
          case SPR_DCR_CC_MASKED: DCR_hit = op1 & op2; break;
146
          case SPR_DCR_CC_EQUAL: DCR_hit = op1 == op2; break;
147
          case SPR_DCR_CC_NEQUAL: DCR_hit = op1 != op2; break;
148
          case SPR_DCR_CC_LESS: DCR_hit = op1 < op2; break;
149
          case SPR_DCR_CC_LESSE: DCR_hit = op1 <= op2; break;
150
          case SPR_DCR_CC_GREAT: DCR_hit = op1 > op2; break;
151
          case SPR_DCR_CC_GREATE: DCR_hit = op1 >= op2; break;
152
          }
153
        }
154
      }
155
    }
156 1244 hpanther
 
157 1351 nogj
    /* Chain matchpoints */
158
    switch(i) {
159
    case 0:
160
      chain1 = chain2 = DCR_hit;
161
      break;
162
    case 8:
163
      chain1 = getsprbits(SPR_DWCR0, SPR_DWCR_COUNT) == getsprbits(SPR_DWCR0,
164
                                                                SPR_DWCR_MATCH);
165
      chain2 = watchpoints & (1 << 7);
166
      break;
167
    case 9:
168
      chain1 = getsprbits(SPR_DWCR1, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR1,
169
                                                                SPR_DWCR_MATCH);
170
      chain2 = watchpoints & (1 << 8);
171
      break;
172
    case 10:
173
      /* TODO: External watchpoint - not yet handled!  */
174 479 markom
#if 0
175 1351 nogj
      chain1 = external_watchpoint;
176
      chain2 = watchpoints & (1 << 9);
177 479 markom
#else
178 1351 nogj
      chain1 = chain2 = 0;
179 479 markom
#endif
180 1351 nogj
      break;
181
    default:
182
      chain1 = DCR_hit;
183
      chain2 = watchpoints & (bit >> 1);
184
      break;
185
    }
186 221 markom
 
187 1351 nogj
    switch(getsprbits(SPR_DMR1, SPR_DMR1_CW0 << i)) {
188
    case 0: match = chain1; break;
189
    case 1: match = chain1 && chain2; break;
190
    case 2: match = chain1 || chain2; break;
191
    }
192 221 markom
 
193 1351 nogj
    /* Increment counters & generate counter break */
194
    if(match) {
195
      /* watchpoint did not appear before in this clock cycle */
196
      if(!(watchpoints & bit)) {
197
        int counter = (getsprbits(SPR_DMR2, SPR_DMR2_AWTC) & bit) ? 1 : 0;
198
        int enabled = counter ? getsprbits(SPR_DMR2, SPR_DMR2_WCE1) :
199
                                            getsprbits(SPR_DMR2, SPR_DMR2_WCE0);
200
        if(enabled)
201
          setsprbits(SPR_DWCR0 + counter, SPR_DWCR_COUNT,
202
                     getsprbits(SPR_DWCR0 + counter, SPR_DWCR_COUNT) + 1);
203
        watchpoints |= bit;
204
      }
205 221 markom
 
206 1351 nogj
      /* should this watchpoint generate a breakpoint? */
207
      if(getsprbits(SPR_DMR2, SPR_DMR2_WGB) & bit)
208
        breakpoint = 1;
209
    }
210
  }
211
 
212
  return breakpoint;
213 221 markom
}
214 1244 hpanther
 
215 221 markom
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL;
216
 
217 479 markom
int DebugGetRegister(unsigned int address, unsigned long* data)
218 221 markom
{
219 1244 hpanther
  int err=0;
220 221 markom
#ifdef DEBUG_JTAG
221 997 markom
  PRINTF("Debug get register %x\n",address);
222 221 markom
  fflush(stdout);
223
#endif
224
  switch(current_scan_chain)
225
    {
226
    case JTAG_CHAIN_DEBUG_UNIT:
227 479 markom
      *data = mfspr (address);
228
      debug (2, "READ  (%08x) = %08x\n", address, *data);
229 642 ivang
      if (runtime.sim.fspr_log) {
230 1308 phoenix
        fprintf(runtime.sim.fspr_log, "Read from SPR : [%08X] -> [%08lX]\n",
231
                address, *data);
232 642 ivang
      }
233 221 markom
      break;
234
    case JTAG_CHAIN_TRACE:
235
      *data = 0;  /* Scan chain not yet implemented */
236
      break;
237
    case JTAG_CHAIN_DEVELOPMENT:
238 479 markom
      err = get_devint_reg(address,data);
239 221 markom
      break;
240
    case JTAG_CHAIN_WISHBONE:
241 1244 hpanther
      err = debug_get_mem(address,data);
242 221 markom
      break;
243
    }
244
#ifdef DEBUG_JTAG
245 997 markom
  PRINTF("!get reg %x\n", *data);
246 221 markom
  fflush(stdout);
247
#endif
248
  return err;
249
}
250
 
251 479 markom
int DebugSetRegister(unsigned int address,unsigned long data)
252 221 markom
{
253 1244 hpanther
  int err=0;
254 221 markom
#ifdef DEBUG_JTAG
255 997 markom
  PRINTF("Debug set register %x <- %x\n", address, data);
256 221 markom
  fflush(stdout);
257
#endif
258
  switch(current_scan_chain)
259
    {
260
    case JTAG_CHAIN_DEBUG_UNIT:
261 1350 nogj
      debug (2, "WRITE (%08x) = %08lx\n", address, data);
262 642 ivang
      if (runtime.sim.fspr_log) {
263 1308 phoenix
        fprintf(runtime.sim.fspr_log, "Write to SPR  : [%08X] <- [%08lX]\n",
264
                address, data);
265 642 ivang
      }
266 479 markom
      mtspr(address, data);
267 221 markom
      break;
268
    case JTAG_CHAIN_TRACE:
269
      err = JTAG_PROXY_ACCESS_EXCEPTION;
270
      break;
271
    case JTAG_CHAIN_DEVELOPMENT:
272 479 markom
      err = set_devint_reg (address, data);
273 221 markom
      break;
274
    case JTAG_CHAIN_WISHBONE:
275 479 markom
      err = debug_set_mem (address, data);
276 221 markom
      break;
277
    }
278
#ifdef DEBUG_JTAG
279 997 markom
  PRINTF("!set reg\n");
280 221 markom
  fflush(stdout);
281
#endif
282
  return err;
283
}
284
 
285
int DebugSetChain(int chain)
286
{
287
#ifdef DEBUG_JTAG
288 997 markom
  PRINTF("Debug set chain %x\n",chain);
289 221 markom
  fflush(stdout);
290
#endif
291
  switch(chain)
292
    {
293
    case JTAG_CHAIN_DEBUG_UNIT:
294
    case JTAG_CHAIN_TRACE:
295
    case JTAG_CHAIN_DEVELOPMENT:
296
    case JTAG_CHAIN_WISHBONE:
297
      current_scan_chain = chain;
298
      break;
299
    default: /* All other chains not implemented */
300
      return JTAG_PROXY_INVALID_CHAIN;
301
    }
302
 
303
#ifdef DEBUG_JTAG
304 997 markom
  PRINTF("!set chain\n");
305 221 markom
  fflush(stdout);
306
#endif
307
  return 0;
308
}
309
 
310 479 markom
void sim_reset ();
311
 
312
/* Sets development interface register */
313
int set_devint_reg(unsigned int address, unsigned long data)
314 221 markom
{
315
  int err = 0;
316 479 markom
  unsigned long value = data;
317 221 markom
  int old_value;
318
 
319 479 markom
  switch(address) {
320
    case DEVELOPINT_MODER: development.moder = value; break;
321
    case DEVELOPINT_TSEL:  development.tsel = value;  break;
322
    case DEVELOPINT_QSEL:  development.qsel = value;  break;
323
    case DEVELOPINT_SSEL:  development.ssel = value;  break;
324 221 markom
    case DEVELOPINT_RISCOP:
325 479 markom
      old_value = (development.riscop & RISCOP_RESET) != 0;
326
      development.riscop = value;
327
      in_reset = (development.riscop & RISCOP_RESET) != 0;
328 221 markom
      /* Reset the cpu on the negative edge of RESET */
329 479 markom
      if(old_value && !in_reset)
330
        sim_reset(); /* Reset all units */
331
      set_stall_state((development.riscop & RISCOP_STALL) != 0);
332 221 markom
      break;
333
    case DEVELOPINT_RECWP0:
334
    case DEVELOPINT_RECWP1:
335
    case DEVELOPINT_RECWP2:
336
    case DEVELOPINT_RECWP3:
337
    case DEVELOPINT_RECWP4:
338
    case DEVELOPINT_RECWP5:
339
    case DEVELOPINT_RECWP6:
340
    case DEVELOPINT_RECWP7:
341
    case DEVELOPINT_RECWP8:
342
    case DEVELOPINT_RECWP9:
343 479 markom
    case DEVELOPINT_RECWP10: development.recwp[address - DEVELOPINT_RECWP0] = value; break;
344
    case DEVELOPINT_RECBP0:  development.recbp = value; break;
345 221 markom
    default:
346
      err = JTAG_PROXY_INVALID_ADDRESS;
347
      break;
348
    }
349 479 markom
#ifdef DEBUG_JTAG
350 997 markom
  PRINTF("set_devint_reg %08x = %08x\n", address, data);
351 479 markom
  fflush(stdout);
352
#endif
353 221 markom
  return err;
354
}
355
 
356 1308 phoenix
/* Gets development interface register */
357 479 markom
int get_devint_reg(unsigned int address,unsigned long *data)
358 221 markom
{
359
  int err = 0;
360 479 markom
  unsigned long value = 0;
361 221 markom
 
362 479 markom
  switch(address) {
363
    case DEVELOPINT_MODER:    value = development.moder; break;
364
    case DEVELOPINT_TSEL:     value = development.tsel; break;
365
    case DEVELOPINT_QSEL:     value = development.qsel; break;
366
    case DEVELOPINT_SSEL:     value = development.ssel; break;
367
    case DEVELOPINT_RISCOP:   value = development.riscop; break;
368 221 markom
    case DEVELOPINT_RECWP0:
369
    case DEVELOPINT_RECWP1:
370
    case DEVELOPINT_RECWP2:
371
    case DEVELOPINT_RECWP3:
372
    case DEVELOPINT_RECWP4:
373
    case DEVELOPINT_RECWP5:
374
    case DEVELOPINT_RECWP6:
375
    case DEVELOPINT_RECWP7:
376
    case DEVELOPINT_RECWP8:
377
    case DEVELOPINT_RECWP9:
378 479 markom
    case DEVELOPINT_RECWP10:  value = development.recwp[address - DEVELOPINT_RECWP0]; break;
379
    case DEVELOPINT_RECBP0:   value = development.recbp; break;
380
    default:                  err = JTAG_PROXY_INVALID_ADDRESS; break;
381
  }
382 221 markom
 
383 479 markom
#ifdef DEBUG_JTAG
384 997 markom
  PRINTF("get_devint_reg %08x = %08x\n", address, value);
385 479 markom
  fflush(stdout);
386
#endif
387 221 markom
  *data = value;
388
  return err;
389
}
390
 
391 479 markom
/* Writes to bus address */
392
int debug_set_mem (unsigned int address,unsigned long data)
393 221 markom
{
394
  int err = 0;
395 1350 nogj
  debug (2, "MEMWRITE (%08x) = %08lx\n", address, data);
396 221 markom
 
397
 
398
  if(!verify_memoryarea(address))
399 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
400
  else {
401 1244 hpanther
          // circumvent the read-only check usually done for mem accesses
402 1359 nogj
          // data is in host order, because that's what set_direct32 needs
403
          set_direct32(address, data, NULL, 0, 0);
404 479 markom
  }
405 221 markom
  return err;
406
}
407
 
408 1308 phoenix
/* Reads from bus address */
409 1244 hpanther
int debug_get_mem(unsigned int address,unsigned long *data)
410 221 markom
{
411
  int err = 0;
412
  if(!verify_memoryarea(address))
413 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
414 221 markom
  else
415 479 markom
  {
416 1359 nogj
          *data=eval_direct32(address, NULL, 0, 0);
417 479 markom
  }
418 1350 nogj
  debug (2, "MEMREAD  (%08x) = %08lx\n", address, *data);
419 221 markom
  return err;
420
}
421
 
422 479 markom
/* debug_ignore_exception returns 1 if the exception should be ignored. */
423
int debug_ignore_exception (unsigned long except)
424 221 markom
{
425
  int result = 0;
426 479 markom
  unsigned long dsr = mfspr (SPR_DSR);
427
  unsigned long drr = mfspr (SPR_DRR);
428
 
429 693 markom
#if DEBUG_JTAG
430 997 markom
  PRINTF ("dsr 0x%08x drr 0x%08x \n", dsr, drr);
431 693 markom
#endif
432
 
433 479 markom
  switch(except) {
434
    case EXCEPT_RESET:     drr |= result = dsr & SPR_DSR_RSTE; break;
435
    case EXCEPT_BUSERR:    drr |= result = dsr & SPR_DSR_BUSEE; break;
436
    case EXCEPT_DPF:       drr |= result = dsr & SPR_DSR_DPFE; break;
437
    case EXCEPT_IPF:       drr |= result = dsr & SPR_DSR_IPFE; break;
438 600 simons
    case EXCEPT_TICK:      drr |= result = dsr & SPR_DSR_TTE; break;
439 479 markom
    case EXCEPT_ALIGN:     drr |= result = dsr & SPR_DSR_AE; break;
440
    case EXCEPT_ILLEGAL:   drr |= result = dsr & SPR_DSR_IIE; break;
441 600 simons
    case EXCEPT_INT:       drr |= result = dsr & SPR_DSR_IE; break;
442 479 markom
    case EXCEPT_DTLBMISS:  drr |= result = dsr & SPR_DSR_DME; break;
443
    case EXCEPT_ITLBMISS:  drr |= result = dsr & SPR_DSR_IME; break;
444
    case EXCEPT_RANGE:     drr |= result = dsr & SPR_DSR_RE; break;
445
    case EXCEPT_SYSCALL:   drr |= result = dsr & SPR_DSR_SCE; break;
446
    case EXCEPT_TRAP:      drr |= result = dsr & SPR_DSR_TE; break;
447 221 markom
    default:
448
      break;
449 479 markom
  }
450 693 markom
#if DEBUG_JTAG
451 997 markom
  PRINTF ("dsr 0x%08x drr 0x%08x result %i\n", dsr, drr, result);
452 693 markom
#endif
453 221 markom
 
454 479 markom
  mtspr (SPR_DRR, drr);
455
  set_stall_state (result != 0);
456
  return (result != 0);
457 221 markom
}
458 1358 nogj
 
459
/*--------------------------------------------------[ Debug configuration ]---*/
460
void debug_enabled(union param_val val, void *dat)
461
{
462
  config.debug.enabled = val.int_val;
463
}
464
 
465
void debug_gdb_enabled(union param_val val, void *dat)
466
{
467
  config.debug.gdb_enabled = val.int_val;
468
}
469
 
470
void debug_server_port(union param_val val, void *dat)
471
{
472
  config.debug.server_port = val.int_val;
473
}
474
 
475
void debug_vapi_id(union param_val val, void *dat)
476
{
477
  config.debug.vapi_id = val.int_val;
478
}
479
 
480
void reg_debug_sec(void)
481
{
482
  struct config_section *sec = reg_config_sec("debug", NULL, NULL);
483
 
484
  reg_config_param(sec, "enabled", paramt_int, debug_enabled);
485
  reg_config_param(sec, "gdb_enabled", paramt_int, debug_gdb_enabled);
486
  reg_config_param(sec, "server_port", paramt_int, debug_server_port);
487
  reg_config_param(sec, "vapi_id", paramt_int, debug_server_port);
488
}

powered by: WebSVN 2.1.0

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