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 494

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 479 markom
#define DEBUG_JTAG 1
31
 
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 221 markom
      break;
225
    case JTAG_CHAIN_TRACE:
226
      *data = 0;  /* Scan chain not yet implemented */
227
      err = 0;
228
      break;
229
    case JTAG_CHAIN_DEVELOPMENT:
230 479 markom
      err = get_devint_reg(address,data);
231 221 markom
      break;
232
    case JTAG_CHAIN_WISHBONE:
233
      err = GetWishboneMemory(address,data);
234
      break;
235
    }
236
#ifdef DEBUG_JTAG
237
  printf("!get reg %x\n", *data);
238
  fflush(stdout);
239
#endif
240
  return err;
241
}
242
 
243 479 markom
int DebugSetRegister(unsigned int address,unsigned long data)
244 221 markom
{
245
  int err;
246
#ifdef DEBUG_JTAG
247 479 markom
  printf("Debug set register %x <- %x\n", address, data);
248 221 markom
  fflush(stdout);
249
#endif
250
  switch(current_scan_chain)
251
    {
252
    case JTAG_CHAIN_DEBUG_UNIT:
253 479 markom
      debug (2, "WRITE (%08x) = %08x\n", address, data);
254
      mtspr(address, data);
255 221 markom
      break;
256
    case JTAG_CHAIN_TRACE:
257
      err = JTAG_PROXY_ACCESS_EXCEPTION;
258
      break;
259
    case JTAG_CHAIN_DEVELOPMENT:
260 479 markom
      err = set_devint_reg (address, data);
261 221 markom
      break;
262
    case JTAG_CHAIN_WISHBONE:
263 479 markom
      err = debug_set_mem (address, data);
264 221 markom
      break;
265
    }
266
#ifdef DEBUG_JTAG
267
  printf("!set reg\n");
268
  fflush(stdout);
269
#endif
270
  return err;
271
}
272
 
273
int DebugSetChain(int chain)
274
{
275
#ifdef DEBUG_JTAG
276
  printf("Debug set chain %x\n",chain);
277
  fflush(stdout);
278
#endif
279
  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
#ifdef DEBUG_JTAG
292
  printf("!set chain\n");
293
  fflush(stdout);
294
#endif
295
  return 0;
296
}
297
 
298 479 markom
void sim_reset ();
299
 
300
/* Sets development interface register */
301
int set_devint_reg(unsigned int address, unsigned long data)
302 221 markom
{
303
  int err = 0;
304 479 markom
  unsigned long value = data;
305 221 markom
  int old_value;
306
 
307 479 markom
  switch(address) {
308
    case DEVELOPINT_MODER: development.moder = value; break;
309
    case DEVELOPINT_TSEL:  development.tsel = value;  break;
310
    case DEVELOPINT_QSEL:  development.qsel = value;  break;
311
    case DEVELOPINT_SSEL:  development.ssel = value;  break;
312 221 markom
    case DEVELOPINT_RISCOP:
313 479 markom
      old_value = (development.riscop & RISCOP_RESET) != 0;
314
      development.riscop = value;
315
      in_reset = (development.riscop & RISCOP_RESET) != 0;
316 221 markom
      /* Reset the cpu on the negative edge of RESET */
317 479 markom
      if(old_value && !in_reset)
318
        sim_reset(); /* Reset all units */
319
      set_stall_state((development.riscop & RISCOP_STALL) != 0);
320 221 markom
      break;
321
    case DEVELOPINT_RECWP0:
322
    case DEVELOPINT_RECWP1:
323
    case DEVELOPINT_RECWP2:
324
    case DEVELOPINT_RECWP3:
325
    case DEVELOPINT_RECWP4:
326
    case DEVELOPINT_RECWP5:
327
    case DEVELOPINT_RECWP6:
328
    case DEVELOPINT_RECWP7:
329
    case DEVELOPINT_RECWP8:
330
    case DEVELOPINT_RECWP9:
331 479 markom
    case DEVELOPINT_RECWP10: development.recwp[address - DEVELOPINT_RECWP0] = value; break;
332
    case DEVELOPINT_RECBP0:  development.recbp = value; break;
333 221 markom
    default:
334
      err = JTAG_PROXY_INVALID_ADDRESS;
335
      break;
336
    }
337 479 markom
#ifdef DEBUG_JTAG
338
  printf("set_devint_reg %08x = %08x\n", address, data);
339
  fflush(stdout);
340
#endif
341 221 markom
  return err;
342
}
343
 
344 479 markom
int get_devint_reg(unsigned int address,unsigned long *data)
345 221 markom
{
346
  int err = 0;
347 479 markom
  unsigned long value = 0;
348 221 markom
 
349 479 markom
  switch(address) {
350
    case DEVELOPINT_MODER:    value = development.moder; break;
351
    case DEVELOPINT_TSEL:     value = development.tsel; break;
352
    case DEVELOPINT_QSEL:     value = development.qsel; break;
353
    case DEVELOPINT_SSEL:     value = development.ssel; break;
354
    case DEVELOPINT_RISCOP:   value = development.riscop; break;
355 221 markom
    case DEVELOPINT_RECWP0:
356
    case DEVELOPINT_RECWP1:
357
    case DEVELOPINT_RECWP2:
358
    case DEVELOPINT_RECWP3:
359
    case DEVELOPINT_RECWP4:
360
    case DEVELOPINT_RECWP5:
361
    case DEVELOPINT_RECWP6:
362
    case DEVELOPINT_RECWP7:
363
    case DEVELOPINT_RECWP8:
364
    case DEVELOPINT_RECWP9:
365 479 markom
    case DEVELOPINT_RECWP10:  value = development.recwp[address - DEVELOPINT_RECWP0]; break;
366
    case DEVELOPINT_RECBP0:   value = development.recbp; break;
367
    default:                  err = JTAG_PROXY_INVALID_ADDRESS; break;
368
  }
369 221 markom
 
370 479 markom
#ifdef DEBUG_JTAG
371
  printf("get_devint_reg %08x = %08x\n", address, value);
372
  fflush(stdout);
373
#endif
374 221 markom
  *data = value;
375
  return err;
376
}
377
 
378 479 markom
/* Writes to bus address */
379
int debug_set_mem (unsigned int address,unsigned long data)
380 221 markom
{
381
  int err = 0;
382 479 markom
  debug (2, "MEMWRITE (%08x) = %08x\n", address, data);
383 221 markom
 
384
 
385
  if(!verify_memoryarea(address))
386 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
387
  else {
388
    unsigned char t_data[4];
389
    int *tmp = (int*)t_data;
390
    extern char null_str[1];  /* From cpu/common/parse.c */
391
    int i;
392 221 markom
 
393 479 markom
    *tmp = htonl(data); /* We have already converted to host order */
394 221 markom
 
395 479 markom
    setsim_mem8(address++, t_data[0]); /* Back to network byte order */
396
    setsim_mem8(address++, t_data[1]);
397
    setsim_mem8(address++, t_data[2]);
398
    setsim_mem8(address++, t_data[3]);
399
  }
400 221 markom
  return err;
401
}
402
 
403 479 markom
int GetWishboneMemory(unsigned int address,unsigned long *data)
404 221 markom
{
405
  int err = 0;
406
  if(!verify_memoryarea(address))
407 479 markom
    err = JTAG_PROXY_INVALID_ADDRESS;
408 221 markom
  else
409 479 markom
  {
410
    unsigned char t_data[4];
411
    int *tmp = (int*)t_data;
412
    int bp;
413 221 markom
 
414 479 markom
    t_data[0] = evalsim_mem8(address++);
415
    t_data[1] = evalsim_mem8(address++);
416
    t_data[2] = evalsim_mem8(address++);
417
    t_data[3] = evalsim_mem8(address++); /* Already in network byte order */
418
 
419
    *data = ntohl(*tmp);  /* But we assume it is in host order later */
420
  }
421
  debug (2, "MEMREAD  (%08x) = %08x\n", address, *data);
422 221 markom
  return err;
423
}
424
 
425 479 markom
/* debug_ignore_exception returns 1 if the exception should be ignored. */
426
int debug_ignore_exception (unsigned long except)
427 221 markom
{
428
  int result = 0;
429 479 markom
  unsigned long dsr = mfspr (SPR_DSR);
430
  unsigned long drr = mfspr (SPR_DRR);
431
 
432
  &debug_ignore_exception;
433
  printf ("0x%08x 0x%08x \n", dsr, drr);
434
  switch(except) {
435
    case EXCEPT_RESET:     drr |= result = dsr & SPR_DSR_RSTE; break;
436
    case EXCEPT_BUSERR:    drr |= result = dsr & SPR_DSR_BUSEE; break;
437
    case EXCEPT_DPF:       drr |= result = dsr & SPR_DSR_DPFE; break;
438
    case EXCEPT_IPF:       drr |= result = dsr & SPR_DSR_IPFE; break;
439
    case EXCEPT_LPINT:     drr |= result = dsr & SPR_DSR_LPINTE; break;
440
    case EXCEPT_ALIGN:     drr |= result = dsr & SPR_DSR_AE; break;
441
    case EXCEPT_ILLEGAL:   drr |= result = dsr & SPR_DSR_IIE; break;
442
    case EXCEPT_HPINT:     drr |= result = dsr & SPR_DSR_LPINTE; break;
443
    case EXCEPT_DTLBMISS:  drr |= result = dsr & SPR_DSR_DME; break;
444
    case EXCEPT_ITLBMISS:  drr |= result = dsr & SPR_DSR_IME; break;
445
    case EXCEPT_RANGE:     drr |= result = dsr & SPR_DSR_RE; break;
446
    case EXCEPT_SYSCALL:   drr |= result = dsr & SPR_DSR_SCE; break;
447
    case EXCEPT_TRAP:      drr |= result = dsr & SPR_DSR_TE; break;
448 221 markom
    default:
449
      break;
450 479 markom
  }
451
  printf ("0x%08x 0x%08x %i\n", dsr, drr, result);
452 221 markom
 
453 479 markom
  mtspr (SPR_DRR, drr);
454
  set_stall_state (result != 0);
455
  return (result != 0);
456 221 markom
}

powered by: WebSVN 2.1.0

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