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 1432

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

powered by: WebSVN 2.1.0

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