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 1487

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

powered by: WebSVN 2.1.0

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