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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [debug/] [debug_unit.c] - Blame information for rev 642

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

powered by: WebSVN 2.1.0

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