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 479

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

powered by: WebSVN 2.1.0

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