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 1506

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 1506 nogj
  if(cpu_state.sprs[SPR_DMR1] & SPR_DMR1_DXFW) /* If debugger disabled */
75 479 markom
    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 1506 nogj
  if((action == DebugInstructionFetch) && (cpu_state.sprs[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 1506 nogj
      chain1 = (cpu_state.sprs[SPR_DWCR0] & SPR_DWCR_COUNT) ==
169
               (cpu_state.sprs[SPR_DWCR0] & SPR_DWCR_MATCH);
170 1351 nogj
      chain2 = watchpoints & (1 << 7);
171
      break;
172
    case 9:
173 1506 nogj
      chain1 = (cpu_state.sprs[SPR_DWCR1] & SPR_DWCR_COUNT) ==
174
               (cpu_state.sprs[SPR_DWCR1] & SPR_DWCR_MATCH);
175 1351 nogj
      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 1506 nogj
    switch((cpu_state.sprs[SPR_DMR1] >> i) & SPR_DMR1_CW0) {
193 1351 nogj
    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 1506 nogj
        int counter = (((cpu_state.sprs[SPR_DMR2] & SPR_DMR2_AWTC) >> 2) & bit) ? 1 : 0;
203
        int enabled = cpu_state.sprs[SPR_DMR2] & (counter ? SPR_DMR2_WCE1 : SPR_DMR2_WCE0);
204
        if(enabled) {
205
          uorreg_t count = cpu_state.sprs[SPR_DWCR0 + counter];
206
          count = (count & ~SPR_DWCR_COUNT) | ((count & SPR_DWCR_COUNT) + 1);
207
          cpu_state.sprs[SPR_DWCR0 + counter] = count;
208
        }
209 1351 nogj
        watchpoints |= bit;
210
      }
211 221 markom
 
212 1351 nogj
      /* should this watchpoint generate a breakpoint? */
213 1506 nogj
      if(((cpu_state.sprs[SPR_DMR2] & SPR_DMR2_WGB) >> 13) & bit)
214 1351 nogj
        breakpoint = 1;
215
    }
216
  }
217
 
218
  return breakpoint;
219 221 markom
}
220 1506 nogj
 
221 221 markom
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL;
222
 
223 479 markom
int DebugGetRegister(unsigned int address, unsigned long* data)
224 221 markom
{
225 1244 hpanther
  int err=0;
226 221 markom
#ifdef DEBUG_JTAG
227 997 markom
  PRINTF("Debug get register %x\n",address);
228 221 markom
  fflush(stdout);
229
#endif
230
  switch(current_scan_chain)
231
    {
232
    case JTAG_CHAIN_DEBUG_UNIT:
233 479 markom
      *data = mfspr (address);
234
      debug (2, "READ  (%08x) = %08x\n", address, *data);
235 642 ivang
      if (runtime.sim.fspr_log) {
236 1308 phoenix
        fprintf(runtime.sim.fspr_log, "Read from SPR : [%08X] -> [%08lX]\n",
237
                address, *data);
238 642 ivang
      }
239 221 markom
      break;
240
    case JTAG_CHAIN_TRACE:
241
      *data = 0;  /* Scan chain not yet implemented */
242
      break;
243
    case JTAG_CHAIN_DEVELOPMENT:
244 479 markom
      err = get_devint_reg(address,data);
245 221 markom
      break;
246
    case JTAG_CHAIN_WISHBONE:
247 1244 hpanther
      err = debug_get_mem(address,data);
248 221 markom
      break;
249
    }
250
#ifdef DEBUG_JTAG
251 997 markom
  PRINTF("!get reg %x\n", *data);
252 221 markom
  fflush(stdout);
253
#endif
254
  return err;
255
}
256
 
257 479 markom
int DebugSetRegister(unsigned int address,unsigned long data)
258 221 markom
{
259 1244 hpanther
  int err=0;
260 221 markom
#ifdef DEBUG_JTAG
261 997 markom
  PRINTF("Debug set register %x <- %x\n", address, data);
262 221 markom
  fflush(stdout);
263
#endif
264
  switch(current_scan_chain)
265
    {
266
    case JTAG_CHAIN_DEBUG_UNIT:
267 1350 nogj
      debug (2, "WRITE (%08x) = %08lx\n", address, data);
268 642 ivang
      if (runtime.sim.fspr_log) {
269 1308 phoenix
        fprintf(runtime.sim.fspr_log, "Write to SPR  : [%08X] <- [%08lX]\n",
270
                address, data);
271 642 ivang
      }
272 479 markom
      mtspr(address, data);
273 221 markom
      break;
274
    case JTAG_CHAIN_TRACE:
275
      err = JTAG_PROXY_ACCESS_EXCEPTION;
276
      break;
277
    case JTAG_CHAIN_DEVELOPMENT:
278 479 markom
      err = set_devint_reg (address, data);
279 221 markom
      break;
280
    case JTAG_CHAIN_WISHBONE:
281 479 markom
      err = debug_set_mem (address, data);
282 221 markom
      break;
283
    }
284
#ifdef DEBUG_JTAG
285 997 markom
  PRINTF("!set reg\n");
286 221 markom
  fflush(stdout);
287
#endif
288
  return err;
289
}
290
 
291
int DebugSetChain(int chain)
292
{
293
#ifdef DEBUG_JTAG
294 997 markom
  PRINTF("Debug set chain %x\n",chain);
295 221 markom
  fflush(stdout);
296
#endif
297
  switch(chain)
298
    {
299
    case JTAG_CHAIN_DEBUG_UNIT:
300
    case JTAG_CHAIN_TRACE:
301
    case JTAG_CHAIN_DEVELOPMENT:
302
    case JTAG_CHAIN_WISHBONE:
303
      current_scan_chain = chain;
304
      break;
305
    default: /* All other chains not implemented */
306
      return JTAG_PROXY_INVALID_CHAIN;
307
    }
308
 
309
#ifdef DEBUG_JTAG
310 997 markom
  PRINTF("!set chain\n");
311 221 markom
  fflush(stdout);
312
#endif
313
  return 0;
314
}
315
 
316 479 markom
void sim_reset ();
317
 
318
/* Sets development interface register */
319
int set_devint_reg(unsigned int address, unsigned long data)
320 221 markom
{
321
  int err = 0;
322 479 markom
  unsigned long value = data;
323 221 markom
  int old_value;
324
 
325 479 markom
  switch(address) {
326
    case DEVELOPINT_MODER: development.moder = value; break;
327
    case DEVELOPINT_TSEL:  development.tsel = value;  break;
328
    case DEVELOPINT_QSEL:  development.qsel = value;  break;
329
    case DEVELOPINT_SSEL:  development.ssel = value;  break;
330 221 markom
    case DEVELOPINT_RISCOP:
331 479 markom
      old_value = (development.riscop & RISCOP_RESET) != 0;
332
      development.riscop = value;
333
      in_reset = (development.riscop & RISCOP_RESET) != 0;
334 221 markom
      /* Reset the cpu on the negative edge of RESET */
335 479 markom
      if(old_value && !in_reset)
336
        sim_reset(); /* Reset all units */
337
      set_stall_state((development.riscop & RISCOP_STALL) != 0);
338 221 markom
      break;
339
    case DEVELOPINT_RECWP0:
340
    case DEVELOPINT_RECWP1:
341
    case DEVELOPINT_RECWP2:
342
    case DEVELOPINT_RECWP3:
343
    case DEVELOPINT_RECWP4:
344
    case DEVELOPINT_RECWP5:
345
    case DEVELOPINT_RECWP6:
346
    case DEVELOPINT_RECWP7:
347
    case DEVELOPINT_RECWP8:
348
    case DEVELOPINT_RECWP9:
349 479 markom
    case DEVELOPINT_RECWP10: development.recwp[address - DEVELOPINT_RECWP0] = value; break;
350
    case DEVELOPINT_RECBP0:  development.recbp = value; break;
351 221 markom
    default:
352
      err = JTAG_PROXY_INVALID_ADDRESS;
353
      break;
354
    }
355 479 markom
#ifdef DEBUG_JTAG
356 997 markom
  PRINTF("set_devint_reg %08x = %08x\n", address, data);
357 479 markom
  fflush(stdout);
358
#endif
359 221 markom
  return err;
360
}
361
 
362 1308 phoenix
/* Gets development interface register */
363 479 markom
int get_devint_reg(unsigned int address,unsigned long *data)
364 221 markom
{
365
  int err = 0;
366 479 markom
  unsigned long value = 0;
367 221 markom
 
368 479 markom
  switch(address) {
369
    case DEVELOPINT_MODER:    value = development.moder; break;
370
    case DEVELOPINT_TSEL:     value = development.tsel; break;
371
    case DEVELOPINT_QSEL:     value = development.qsel; break;
372
    case DEVELOPINT_SSEL:     value = development.ssel; break;
373
    case DEVELOPINT_RISCOP:   value = development.riscop; break;
374 221 markom
    case DEVELOPINT_RECWP0:
375
    case DEVELOPINT_RECWP1:
376
    case DEVELOPINT_RECWP2:
377
    case DEVELOPINT_RECWP3:
378
    case DEVELOPINT_RECWP4:
379
    case DEVELOPINT_RECWP5:
380
    case DEVELOPINT_RECWP6:
381
    case DEVELOPINT_RECWP7:
382
    case DEVELOPINT_RECWP8:
383
    case DEVELOPINT_RECWP9:
384 479 markom
    case DEVELOPINT_RECWP10:  value = development.recwp[address - DEVELOPINT_RECWP0]; break;
385
    case DEVELOPINT_RECBP0:   value = development.recbp; break;
386
    default:                  err = JTAG_PROXY_INVALID_ADDRESS; break;
387
  }
388 221 markom
 
389 479 markom
#ifdef DEBUG_JTAG
390 997 markom
  PRINTF("get_devint_reg %08x = %08x\n", address, value);
391 479 markom
  fflush(stdout);
392
#endif
393 221 markom
  *data = value;
394
  return err;
395
}
396
 
397 479 markom
/* Writes to bus address */
398
int debug_set_mem (unsigned int address,unsigned long data)
399 221 markom
{
400
  int err = 0;
401 1350 nogj
  debug (2, "MEMWRITE (%08x) = %08lx\n", address, data);
402 221 markom
 
403
 
404
  if(!verify_memoryarea(address))
405 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
406
  else {
407 1244 hpanther
          // circumvent the read-only check usually done for mem accesses
408 1359 nogj
          // data is in host order, because that's what set_direct32 needs
409 1487 nogj
          set_direct32(address, data, 0, 0);
410 479 markom
  }
411 221 markom
  return err;
412
}
413
 
414 1308 phoenix
/* Reads from bus address */
415 1244 hpanther
int debug_get_mem(unsigned int address,unsigned long *data)
416 221 markom
{
417
  int err = 0;
418
  if(!verify_memoryarea(address))
419 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
420 221 markom
  else
421 479 markom
  {
422 1487 nogj
          *data=eval_direct32(address, 0, 0);
423 479 markom
  }
424 1350 nogj
  debug (2, "MEMREAD  (%08x) = %08lx\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 693 markom
#if DEBUG_JTAG
436 997 markom
  PRINTF ("dsr 0x%08x drr 0x%08x \n", dsr, drr);
437 693 markom
#endif
438
 
439 479 markom
  switch(except) {
440
    case EXCEPT_RESET:     drr |= result = dsr & SPR_DSR_RSTE; break;
441
    case EXCEPT_BUSERR:    drr |= result = dsr & SPR_DSR_BUSEE; break;
442
    case EXCEPT_DPF:       drr |= result = dsr & SPR_DSR_DPFE; break;
443
    case EXCEPT_IPF:       drr |= result = dsr & SPR_DSR_IPFE; break;
444 600 simons
    case EXCEPT_TICK:      drr |= result = dsr & SPR_DSR_TTE; break;
445 479 markom
    case EXCEPT_ALIGN:     drr |= result = dsr & SPR_DSR_AE; break;
446
    case EXCEPT_ILLEGAL:   drr |= result = dsr & SPR_DSR_IIE; break;
447 600 simons
    case EXCEPT_INT:       drr |= result = dsr & SPR_DSR_IE; break;
448 479 markom
    case EXCEPT_DTLBMISS:  drr |= result = dsr & SPR_DSR_DME; break;
449
    case EXCEPT_ITLBMISS:  drr |= result = dsr & SPR_DSR_IME; break;
450
    case EXCEPT_RANGE:     drr |= result = dsr & SPR_DSR_RE; break;
451
    case EXCEPT_SYSCALL:   drr |= result = dsr & SPR_DSR_SCE; break;
452
    case EXCEPT_TRAP:      drr |= result = dsr & SPR_DSR_TE; break;
453 221 markom
    default:
454
      break;
455 479 markom
  }
456 693 markom
#if DEBUG_JTAG
457 997 markom
  PRINTF ("dsr 0x%08x drr 0x%08x result %i\n", dsr, drr, result);
458 693 markom
#endif
459 221 markom
 
460 479 markom
  mtspr (SPR_DRR, drr);
461
  set_stall_state (result != 0);
462
  return (result != 0);
463 221 markom
}
464 1358 nogj
 
465
/*--------------------------------------------------[ Debug configuration ]---*/
466
void debug_enabled(union param_val val, void *dat)
467
{
468
  config.debug.enabled = val.int_val;
469
}
470
 
471
void debug_gdb_enabled(union param_val val, void *dat)
472
{
473
  config.debug.gdb_enabled = val.int_val;
474
}
475
 
476
void debug_server_port(union param_val val, void *dat)
477
{
478
  config.debug.server_port = val.int_val;
479
}
480
 
481
void debug_vapi_id(union param_val val, void *dat)
482
{
483
  config.debug.vapi_id = val.int_val;
484
}
485
 
486
void reg_debug_sec(void)
487
{
488
  struct config_section *sec = reg_config_sec("debug", NULL, NULL);
489
 
490
  reg_config_param(sec, "enabled", paramt_int, debug_enabled);
491
  reg_config_param(sec, "gdb_enabled", paramt_int, debug_gdb_enabled);
492
  reg_config_param(sec, "server_port", paramt_int, debug_server_port);
493 1457 nogj
  reg_config_param(sec, "vapi_id", paramt_int, debug_vapi_id);
494 1358 nogj
}

powered by: WebSVN 2.1.0

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