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 1765

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

powered by: WebSVN 2.1.0

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