OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [debug/] [debug_unit.c] - Blame information for rev 1516

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
#include <stdlib.h>
31
#include <stdio.h>
32
#include <string.h>
33
 
34 1350 nogj
#include "config.h"
35
 
36
#ifdef HAVE_INTTYPES_H
37
#include <inttypes.h>
38
#endif
39
 
40
#include "port.h"
41
#include "arch.h"
42 221 markom
#include "debug_unit.h"
43
#include "sim-config.h"
44
#include "except.h"
45
#include "abstract.h"
46
#include "parse.h"
47 485 markom
#include "gdb.h"
48 1308 phoenix
#include "except.h"
49 221 markom
#include "opcode/or32.h"
50 1432 nogj
#include "spr_defs.h"
51
#include "execute.h"
52
#include "sprs.h"
53 1308 phoenix
#include "debug.h"
54 221 markom
 
55 1515 nogj
DECLARE_DEBUG_CHANNEL(jtag);
56
 
57 221 markom
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 1508 nogj
  if(cpu_state.sprs[SPR_DMR2] & (SPR_DMR2_WGB | SPR_DMR2_AWTC))
102 1350 nogj
    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 1508 nogj
      unsigned long dcr = cpu_state.sprs[SPR_DCR(i)];
122 1351 nogj
      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 1508 nogj
        unsigned long op2 = cpu_state.sprs[SPR_DVR(i)];
136 1351 nogj
        /* 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 1515 nogj
  TRACE_(jtag)("Debug get register %x\n",address);
227 221 markom
  switch(current_scan_chain)
228
    {
229
    case JTAG_CHAIN_DEBUG_UNIT:
230 1515 nogj
      *data = mfspr(address);
231
      TRACE_(jtag)("READ  (%08lx) = %08lx\n", address, *data);
232 642 ivang
      if (runtime.sim.fspr_log) {
233 1308 phoenix
        fprintf(runtime.sim.fspr_log, "Read from SPR : [%08X] -> [%08lX]\n",
234
                address, *data);
235 642 ivang
      }
236 221 markom
      break;
237
    case JTAG_CHAIN_TRACE:
238
      *data = 0;  /* Scan chain not yet implemented */
239
      break;
240
    case JTAG_CHAIN_DEVELOPMENT:
241 479 markom
      err = get_devint_reg(address,data);
242 221 markom
      break;
243
    case JTAG_CHAIN_WISHBONE:
244 1244 hpanther
      err = debug_get_mem(address,data);
245 221 markom
      break;
246
    }
247 1515 nogj
  TRACE_(jtag)("!get reg %lx\n", *data);
248 221 markom
  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 1515 nogj
  TRACE_(jtag)("Debug set register %x <- %lx\n", address, data);
255 221 markom
  switch(current_scan_chain)
256
    {
257
    case JTAG_CHAIN_DEBUG_UNIT:
258 1515 nogj
      TRACE_(jtag)("WRITE (%08x) = %08lx\n", address, data);
259 642 ivang
      if (runtime.sim.fspr_log) {
260 1308 phoenix
        fprintf(runtime.sim.fspr_log, "Write to SPR  : [%08X] <- [%08lX]\n",
261
                address, data);
262 642 ivang
      }
263 479 markom
      mtspr(address, data);
264 221 markom
      break;
265
    case JTAG_CHAIN_TRACE:
266
      err = JTAG_PROXY_ACCESS_EXCEPTION;
267
      break;
268
    case JTAG_CHAIN_DEVELOPMENT:
269 479 markom
      err = set_devint_reg (address, data);
270 221 markom
      break;
271
    case JTAG_CHAIN_WISHBONE:
272 479 markom
      err = debug_set_mem (address, data);
273 221 markom
      break;
274
    }
275 1515 nogj
  TRACE_(jtag)("!set reg\n");
276 221 markom
  return err;
277
}
278
 
279
int DebugSetChain(int chain)
280
{
281 1515 nogj
  TRACE_(jtag)("Debug set chain %x\n",chain);
282 221 markom
  switch(chain)
283
    {
284
    case JTAG_CHAIN_DEBUG_UNIT:
285
    case JTAG_CHAIN_TRACE:
286
    case JTAG_CHAIN_DEVELOPMENT:
287
    case JTAG_CHAIN_WISHBONE:
288
      current_scan_chain = chain;
289
      break;
290
    default: /* All other chains not implemented */
291
      return JTAG_PROXY_INVALID_CHAIN;
292
    }
293
 
294
  return 0;
295
}
296
 
297 479 markom
void sim_reset ();
298
 
299
/* Sets development interface register */
300
int set_devint_reg(unsigned int address, unsigned long data)
301 221 markom
{
302
  int err = 0;
303 479 markom
  unsigned long value = data;
304 221 markom
  int old_value;
305
 
306 479 markom
  switch(address) {
307
    case DEVELOPINT_MODER: development.moder = value; break;
308
    case DEVELOPINT_TSEL:  development.tsel = value;  break;
309
    case DEVELOPINT_QSEL:  development.qsel = value;  break;
310
    case DEVELOPINT_SSEL:  development.ssel = value;  break;
311 221 markom
    case DEVELOPINT_RISCOP:
312 479 markom
      old_value = (development.riscop & RISCOP_RESET) != 0;
313
      development.riscop = value;
314
      in_reset = (development.riscop & RISCOP_RESET) != 0;
315 221 markom
      /* Reset the cpu on the negative edge of RESET */
316 479 markom
      if(old_value && !in_reset)
317
        sim_reset(); /* Reset all units */
318
      set_stall_state((development.riscop & RISCOP_STALL) != 0);
319 221 markom
      break;
320
    case DEVELOPINT_RECWP0:
321
    case DEVELOPINT_RECWP1:
322
    case DEVELOPINT_RECWP2:
323
    case DEVELOPINT_RECWP3:
324
    case DEVELOPINT_RECWP4:
325
    case DEVELOPINT_RECWP5:
326
    case DEVELOPINT_RECWP6:
327
    case DEVELOPINT_RECWP7:
328
    case DEVELOPINT_RECWP8:
329
    case DEVELOPINT_RECWP9:
330 479 markom
    case DEVELOPINT_RECWP10: development.recwp[address - DEVELOPINT_RECWP0] = value; break;
331
    case DEVELOPINT_RECBP0:  development.recbp = value; break;
332 221 markom
    default:
333
      err = JTAG_PROXY_INVALID_ADDRESS;
334
      break;
335
    }
336 1515 nogj
  TRACE_(jtag)("set_devint_reg %08x = %08lx\n", address, data);
337 221 markom
  return err;
338
}
339
 
340 1308 phoenix
/* Gets development interface register */
341 479 markom
int get_devint_reg(unsigned int address,unsigned long *data)
342 221 markom
{
343
  int err = 0;
344 479 markom
  unsigned long value = 0;
345 221 markom
 
346 479 markom
  switch(address) {
347
    case DEVELOPINT_MODER:    value = development.moder; break;
348
    case DEVELOPINT_TSEL:     value = development.tsel; break;
349
    case DEVELOPINT_QSEL:     value = development.qsel; break;
350
    case DEVELOPINT_SSEL:     value = development.ssel; break;
351
    case DEVELOPINT_RISCOP:   value = development.riscop; break;
352 221 markom
    case DEVELOPINT_RECWP0:
353
    case DEVELOPINT_RECWP1:
354
    case DEVELOPINT_RECWP2:
355
    case DEVELOPINT_RECWP3:
356
    case DEVELOPINT_RECWP4:
357
    case DEVELOPINT_RECWP5:
358
    case DEVELOPINT_RECWP6:
359
    case DEVELOPINT_RECWP7:
360
    case DEVELOPINT_RECWP8:
361
    case DEVELOPINT_RECWP9:
362 479 markom
    case DEVELOPINT_RECWP10:  value = development.recwp[address - DEVELOPINT_RECWP0]; break;
363
    case DEVELOPINT_RECBP0:   value = development.recbp; break;
364
    default:                  err = JTAG_PROXY_INVALID_ADDRESS; break;
365
  }
366 221 markom
 
367 1515 nogj
  TRACE_(jtag)("get_devint_reg %08x = %08lx\n", address, value);
368 221 markom
  *data = value;
369
  return err;
370
}
371
 
372 479 markom
/* Writes to bus address */
373
int debug_set_mem (unsigned int address,unsigned long data)
374 221 markom
{
375
  int err = 0;
376 1515 nogj
  TRACE_(jtag)("MEMWRITE (%08x) = %08lx\n", address, data);
377 221 markom
 
378
 
379
  if(!verify_memoryarea(address))
380 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
381
  else {
382 1244 hpanther
          // circumvent the read-only check usually done for mem accesses
383 1359 nogj
          // data is in host order, because that's what set_direct32 needs
384 1516 nogj
          set_program32(address, data);
385 479 markom
  }
386 221 markom
  return err;
387
}
388
 
389 1308 phoenix
/* Reads from bus address */
390 1244 hpanther
int debug_get_mem(unsigned int address,unsigned long *data)
391 221 markom
{
392
  int err = 0;
393
  if(!verify_memoryarea(address))
394 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
395 221 markom
  else
396 479 markom
  {
397 1487 nogj
          *data=eval_direct32(address, 0, 0);
398 479 markom
  }
399 1515 nogj
  TRACE_(jtag)("MEMREAD  (%08x) = %08lx\n", address, *data);
400 221 markom
  return err;
401
}
402
 
403 479 markom
/* debug_ignore_exception returns 1 if the exception should be ignored. */
404
int debug_ignore_exception (unsigned long except)
405 221 markom
{
406
  int result = 0;
407 1508 nogj
  unsigned long dsr = cpu_state.sprs[SPR_DSR];
408
  unsigned long drr = cpu_state.sprs[SPR_DRR];
409 479 markom
 
410
  switch(except) {
411
    case EXCEPT_RESET:     drr |= result = dsr & SPR_DSR_RSTE; break;
412
    case EXCEPT_BUSERR:    drr |= result = dsr & SPR_DSR_BUSEE; break;
413
    case EXCEPT_DPF:       drr |= result = dsr & SPR_DSR_DPFE; break;
414
    case EXCEPT_IPF:       drr |= result = dsr & SPR_DSR_IPFE; break;
415 600 simons
    case EXCEPT_TICK:      drr |= result = dsr & SPR_DSR_TTE; break;
416 479 markom
    case EXCEPT_ALIGN:     drr |= result = dsr & SPR_DSR_AE; break;
417
    case EXCEPT_ILLEGAL:   drr |= result = dsr & SPR_DSR_IIE; break;
418 600 simons
    case EXCEPT_INT:       drr |= result = dsr & SPR_DSR_IE; break;
419 479 markom
    case EXCEPT_DTLBMISS:  drr |= result = dsr & SPR_DSR_DME; break;
420
    case EXCEPT_ITLBMISS:  drr |= result = dsr & SPR_DSR_IME; break;
421
    case EXCEPT_RANGE:     drr |= result = dsr & SPR_DSR_RE; break;
422
    case EXCEPT_SYSCALL:   drr |= result = dsr & SPR_DSR_SCE; break;
423
    case EXCEPT_TRAP:      drr |= result = dsr & SPR_DSR_TE; break;
424 221 markom
    default:
425
      break;
426 479 markom
  }
427 221 markom
 
428 1508 nogj
  cpu_state.sprs[SPR_DRR] = drr;
429 479 markom
  set_stall_state (result != 0);
430
  return (result != 0);
431 221 markom
}
432 1358 nogj
 
433
/*--------------------------------------------------[ Debug configuration ]---*/
434
void debug_enabled(union param_val val, void *dat)
435
{
436
  config.debug.enabled = val.int_val;
437
}
438
 
439
void debug_gdb_enabled(union param_val val, void *dat)
440
{
441
  config.debug.gdb_enabled = val.int_val;
442
}
443
 
444
void debug_server_port(union param_val val, void *dat)
445
{
446
  config.debug.server_port = val.int_val;
447
}
448
 
449
void debug_vapi_id(union param_val val, void *dat)
450
{
451
  config.debug.vapi_id = val.int_val;
452
}
453
 
454
void reg_debug_sec(void)
455
{
456
  struct config_section *sec = reg_config_sec("debug", NULL, NULL);
457
 
458
  reg_config_param(sec, "enabled", paramt_int, debug_enabled);
459
  reg_config_param(sec, "gdb_enabled", paramt_int, debug_gdb_enabled);
460
  reg_config_param(sec, "server_port", paramt_int, debug_server_port);
461 1457 nogj
  reg_config_param(sec, "vapi_id", paramt_int, debug_vapi_id);
462 1358 nogj
}

powered by: WebSVN 2.1.0

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