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

Subversion Repositories or1k

[/] [or1k/] [tags/] [tn_m001/] [or1ksim/] [debug/] [debug_unit.c.bak] - 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 
31
#include 
32
#include 
33
#include 
34
 
35
#include "debug_unit.h"
36
#include "sim-config.h"
37
#include "except.h"
38
#include "arch.h"
39
#include "abstract.h"
40
#include "parse.h"
41
#include "trace.h"
42
#include "sprs.h"
43
#include "../gdb.h"
44
#include "../cpu/or1k/except.h"
45
#include "opcode/or32.h"
46
 
47
DebugUnit debug_unit;
48
DevelopmentInterface development;
49
 
50
typedef enum {
51
  false = 0,
52
  true = 1,
53
} Boolean;
54
static void ExecuteInducedInstruction(unsigned long);
55
 
56
/* External STALL signal to debug interface */
57
int cpu_stalled = false;
58
int in_reset = false;
59
 
60
/* An induced instruction has been written to the DIR register */
61
static Boolean induced = false;
62
static unsigned long induced_insn;
63
 
64
/* A flag to indicate that we must perform an ic mmu cycle */
65
static Boolean lookup_physical_address = false;
66
 
67
/* Variables for implementing ExecuteInducedInstruction */
68
extern unsigned long pc;
69
extern unsigned long pcnext;
70
extern unsigned long  pcdelay;
71
extern unsigned long pc_phy;
72
extern int delay_insn;
73
static void GetIQueueEntry(struct iqueue_entry*);
74
 
75
static int CalculateWatchpoints(void);
76
 
77
static  int watchpoint[10];
78
 
79
/* This function returns true if an induced instruction has
80
   been inserted into the instruction stream. It will remove
81
   that instruction and return the result. This function is
82
   called from the fetch() routine. */
83
int OverrideFetch(unsigned long* insn)
84
{
85
  int valid = induced;
86
  induced = false;
87
 
88
  if(valid)
89
    *insn = induced_insn;
90
  return valid;
91
}
92
 
93
void InduceImmediateInstruction(unsigned long insn)
94
{
95
  induced = true;
96
  induced_insn = insn;
97
 
98
  if(in_reset)
99
    return;
100
 
101
  if(cpu_stalled)
102
    {
103
      ExecuteInducedInstruction(insn);
104
      induced_insn = 0;
105
      induced = false;
106
    }
107
}
108
 
109
void SetCPUStallState(int state)
110
{
111
  if(debug_unit.DMR1.DXFW) /* If debugger disabled */
112
    state = false;
113
 
114
  if(state == cpu_stalled)
115
    return;
116
 
117
  if(state && induced)
118
    {
119
      ExecuteInducedInstruction(induced_insn);
120
      induced_insn = 0;
121
      induced = false;
122
    }
123
 
124
  cpu_stalled = state;
125
}
126
 
127
void ResetDebugUnit()
128
{
129
  memset(&debug_unit,'\0',sizeof(DebugUnit));
130
  cpu_stalled = 0;
131
}
132
 
133
#ifdef DEBUGMOD_OFF
134
#define CheckDebugUnit(x,y) 0
135
#else
136
inline int CheckDebugUnit(DebugUnitAction action,unsigned long udata)
137
{
138
  int i;
139
  DCR_CT_Settings condition = DCR_CT_Disabled;
140
  long data = (long)udata;
141
  int match;
142
 
143
  if(in_reset)
144
    return 0;
145
 
146
  /* If we're single stepping, always stop */
147
  if(debug_unit.DMR1.ST && action == DebugInstructionFetch)
148
    return 1;
149
 
150
  switch(action)
151
    {
152
    case DebugInstructionFetch:   condition = DCR_CT_InsnAddress;   break;
153
    case DebugLoadAddress:        condition = DCR_CT_LoadAddress;   break;
154
    case DebugStoreAddress:       condition = DCR_CT_StoreAddress;  break;
155
    case DebugLoadData:           condition = DCR_CT_LoadData;      break;
156
    case DebugStoreData:          condition = DCR_CT_StoreData;     break;
157
    }
158
 
159
  for(i=0;i<8;i++)
160
    {
161
      if(debug_unit.DCR[i].DP == DCR_DP_Absent)
162
        continue;
163
 
164
      if(debug_unit.DCR[i].CT == condition)
165
        {
166
          if(debug_unit.DCR[i].SC == DCR_SC_Signed)
167
            {
168
              switch(debug_unit.DCR[i].CC)
169
                {
170
                case DCR_CC_Equal:        match = data == (int)debug_unit.DVR[i];   break;
171
                case DCR_CC_LessThan:     match = data < (int)debug_unit.DVR[i];    break;
172
                case DCR_CC_LessEqual:    match = data <= (int)debug_unit.DVR[i];   break;
173
                case DCR_CC_GreaterThan:  match = data > (int)debug_unit.DVR[i];    break;
174
                case DCR_CC_GreaterEqual: match = data >= (int)debug_unit.DVR[i];   break;
175
                case DCR_CC_NotEqual:     match = data != (int)debug_unit.DVR[i];   break;
176
                default:                  match = 0;                                break;
177
                }
178
            }
179
          else
180
            {
181
              switch(debug_unit.DCR[i].CC)
182
                {
183
                case DCR_CC_Equal:        match = udata == debug_unit.DVR[i];   break;
184
                case DCR_CC_LessThan:     match = udata < debug_unit.DVR[i];    break;
185
                case DCR_CC_LessEqual:    match = udata <= debug_unit.DVR[i];   break;
186
                case DCR_CC_GreaterThan:  match = udata > debug_unit.DVR[i];    break;
187
                case DCR_CC_GreaterEqual: match = udata >= debug_unit.DVR[i];   break;
188
                case DCR_CC_NotEqual:     match = udata != debug_unit.DVR[i];   break;
189
                default:                  match = 0;                            break;
190
                }
191
            }
192
        }
193
      match <<= i;
194
      debug_unit.DCR_hit &= ~match;      /* Clear DCR compare if it has changed */
195
      debug_unit.DCR_hit |= match;  /* Save the state of each DCR compare */
196
    }
197
 
198
  return CalculateWatchpoints();
199
}
200
#endif
201
 
202
static int CalculateWatchpoints()
203
{
204
  int spec[11];
205
  int breakpoint = 0;
206
  int i,bit;
207
 
208
  spec[0] = debug_unit.DMR1.CW0;
209
  spec[1] = debug_unit.DMR1.CW1;
210
  spec[2] = debug_unit.DMR1.CW2;
211
  spec[3] = debug_unit.DMR1.CW3;
212
  spec[4] = debug_unit.DMR1.CW4;
213
  spec[5] = debug_unit.DMR1.CW5;
214
  spec[6] = debug_unit.DMR1.CW6;
215
  spec[7] = debug_unit.DMR1.CW7;
216
  spec[8] = debug_unit.DMR1.CW8;
217
  spec[9] = debug_unit.DMR1.CW9;
218
  spec[10] = debug_unit.DMR1.CW10;
219
 
220
  for(i=0,bit=1;i<11;i++,bit<<=1)
221
    {
222
      int chain1,chain2;
223
      int match = 0;
224
 
225
      switch(i)
226
        {
227
        case 0:
228
          chain1 = chain2 = debug_unit.DCR_hit & 0x01;
229
          break;
230
        case 8:
231
          chain1 = debug_unit.DWCR[0].COUNT == debug_unit.DWCR[0].MATCH;
232
          chain2 = debug_unit.watchpoint & (1 << 7);
233
          break;
234
        case 9:
235
          chain1 = debug_unit.DWCR[1].COUNT == debug_unit.DWCR[1].MATCH;
236
          chain2 = debug_unit.watchpoint & (1 << 8);
237
          break;
238
        case 10:
239
          chain1 = debug_unit.DCR_hit & 0x100; /* External hit */
240
          chain2 = debug_unit.watchpoint & (1 << 9);
241
          break;
242
        default:
243
          chain1 = debug_unit.DCR_hit & bit;
244
          chain2 = debug_unit.watchpoint & (bit >> 1);
245
          break;
246
        }
247
 
248
      switch(spec[i])
249
        {
250
        case 0: match = chain1;           break;
251
        case 1: match = chain1 && chain2; break;
252
        case 2: match = chain1 || chain2; break;
253
        default:
254
          break;
255
        }
256
 
257
      if(match & !(debug_unit.watchpoint & bit))
258
        {
259
          int counter = (debug_unit.DMR2.AWPC & bit) ? 1 : 0;
260
          int enabled = counter ? debug_unit.DMR2.WCE1 : debug_unit.DMR2.WCE0;
261
 
262
          if(enabled)
263
            debug_unit.DWCR[counter].COUNT++;
264
 
265
          if(debug_unit.DMR2.WGB & bit)
266
            breakpoint = 1;
267
        }
268
 
269
      debug_unit.watchpoint &= ~bit;
270
      debug_unit.watchpoint |= bit;
271
    }
272
 
273
  return breakpoint;
274
}
275
 
276
static void GetIQueueEntry(struct iqueue_entry* iq_entry)
277
{
278
  iq_entry->insn = induced_insn;
279
  iq_entry->insn_index = insn_decode(induced_insn);
280
  iq_entry->insn_addr = pc_phy;
281
  iq_entry->op[0] = 0;
282
  iq_entry->op[MAX_OPERANDS] = OPTYPE_LAST;
283
}
284
 
285
static void ExecuteInducedInstruction(unsigned long insn)
286
{
287
  struct iqueue_entry iq_entry;
288
  unsigned long pc_saved = pc;
289
  unsigned long pcnext_saved = pcnext;
290
  unsigned long pcdelay_saved = pcdelay;
291
  unsigned long pc_phy_saved = pc_phy;
292
 
293
  GetIQueueEntry(&iq_entry);
294
  decode_execute(&iq_entry);
295
 
296
  pc = pc_saved;
297
  pcnext = pcnext_saved;
298
  pcdelay = pcdelay_saved;
299
  pc_phy = pc_phy_saved;
300
}
301
 
302
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL;
303
 
304
int DebugGetRegister(unsigned int address,int32_t* data)
305
{
306
  int err;
307
  printf("Debug get register %x\n",address);
308
  fflush(stdout);
309
  switch(current_scan_chain)
310
    {
311
    case JTAG_CHAIN_DEBUG_UNIT:
312
      err = GetDebugUnitRegister(address,data);
313
      break;
314
    case JTAG_CHAIN_TRACE:
315
      *data = 0;  /* Scan chain not yet implemented */
316
      err = 0;
317
      break;
318
    case JTAG_CHAIN_DEVELOPMENT:
319
      err = GetDevelopmentInterfaceRegister(address,data);
320
      break;
321
    }
322
  printf("!get reg %x\n", *data);
323
  fflush(stdout);
324
  return err;
325
}
326
 
327
int DebugSetRegister(unsigned int address,int32_t data)
328
{
329
  int err;
330
  printf("Debug set register %x <- %x\n",address, data);
331
  fflush(stdout);
332
  switch(current_scan_chain)
333
    {
334
    case JTAG_CHAIN_DEBUG_UNIT:
335
      err = SetDebugUnitRegister(address,data);
336
      break;
337
    case JTAG_CHAIN_TRACE:
338
      err = JTAG_PROXY_ACCESS_EXCEPTION;
339
      break;
340
    case JTAG_CHAIN_DEVELOPMENT:
341
      err = SetDevelopmentInterfaceRegister(address,data);
342
      break;
343
    }
344
  printf("!set reg\n");
345
  fflush(stdout);
346
  return err;
347
}
348
 
349
int DebugSetChain(int chain)
350
{
351
  printf("Debug set chain %x\n",chain);
352
  fflush(stdout);
353
  switch(chain)
354
    {
355
    case JTAG_CHAIN_DEBUG_UNIT:
356
    case JTAG_CHAIN_TRACE:
357
    case JTAG_CHAIN_DEVELOPMENT:
358
      current_scan_chain = chain;
359
      break;
360
    default: /* All other chains not implemented */
361
      return JTAG_PROXY_INVALID_CHAIN;
362
    }
363
 
364
  printf("!set chain\n");
365
  fflush(stdout);
366
  return 0;
367
}
368
 
369
/* Nearly all compilers today store these bit fields as a packed structure
370
   in network byte order (Big Endian). If you happen to be unlucky enough
371
   to be working in a non standard environment, you may need to rewrite
372
   this routine or the SET_REG32 macro. */
373
int SetDevelopmentInterfaceRegister(unsigned int address,uint32_t data)
374
{
375
  int err = 0;
376
  uint32_t value = data;
377
  int old_value;
378
  char *t_ptr = (char*)&development.RISCOP;
379
 
380
  switch(address)
381
    {
382
    case DEVELOPINT_MODER:
383
      SET_REG32(development.MODER,value);
384
      break;
385
    case DEVELOPINT_TSEL:
386
      SET_REG32(development.TSEL,value);
387
      break;
388
    case DEVELOPINT_QSEL:
389
      SET_REG32(development.QSEL,value);
390
      break;
391
    case DEVELOPINT_SSEL:
392
      SET_REG32(development.SSEL,value);
393
      break;
394
    case DEVELOPINT_RISCOP:
395
      old_value = development.RISCOP.RESET;
396
      SET_REG32(development.RISCOP,value);
397
 
398
      in_reset = development.RISCOP.RESET;
399
 
400
      /* Reset the cpu on the negative edge of RESET */
401
      if(old_value && !development.RISCOP.RESET)
402
        {
403
          uart_reset();
404
          tick_reset();
405
          pm_reset();
406
          pic_reset();
407
          reset(); /* Old or new mode */
408
        }
409
 
410
      SetCPUStallState(development.RISCOP.RISCSTALL);
411
      break;
412
    case DEVELOPINT_RECWP0:
413
    case DEVELOPINT_RECWP1:
414
    case DEVELOPINT_RECWP2:
415
    case DEVELOPINT_RECWP3:
416
    case DEVELOPINT_RECWP4:
417
    case DEVELOPINT_RECWP5:
418
    case DEVELOPINT_RECWP6:
419
    case DEVELOPINT_RECWP7:
420
    case DEVELOPINT_RECWP8:
421
    case DEVELOPINT_RECWP9:
422
    case DEVELOPINT_RECWP10:
423
      SET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value);
424
      break;
425
    case DEVELOPINT_RECBP0:
426
      SET_REG32(development.RECBP[0],value);
427
      break;
428
    default:
429
      err = JTAG_PROXY_INVALID_ADDRESS;
430
      break;
431
    }
432
  return err;
433
}
434
 
435
int GetDevelopmentInterfaceRegister(unsigned int address,uint32_t *data)
436
{
437
  int err = 0;
438
  uint32_t value = 0;
439
 
440
  switch(address)
441
    {
442
    case DEVELOPINT_MODER:    GET_REG32(development.MODER,value);      break;
443
    case DEVELOPINT_TSEL:     GET_REG32(development.TSEL,value);       break;
444
    case DEVELOPINT_QSEL:     GET_REG32(development.QSEL,value);       break;
445
    case DEVELOPINT_SSEL:     GET_REG32(development.SSEL,value);       break;
446
    case DEVELOPINT_RISCOP:   GET_REG32(development.RISCOP,value);     break;
447
    case DEVELOPINT_RECWP0:
448
    case DEVELOPINT_RECWP1:
449
    case DEVELOPINT_RECWP2:
450
    case DEVELOPINT_RECWP3:
451
    case DEVELOPINT_RECWP4:
452
    case DEVELOPINT_RECWP5:
453
    case DEVELOPINT_RECWP6:
454
    case DEVELOPINT_RECWP7:
455
    case DEVELOPINT_RECWP8:
456
    case DEVELOPINT_RECWP9:
457
    case DEVELOPINT_RECWP10:  GET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value); break;
458
    case DEVELOPINT_RECBP0:   GET_REG32(development.RECBP[0],value);   break;
459
    default:                  err = JTAG_PROXY_INVALID_ADDRESS;        break;
460
    }
461
 
462
  *data = value;
463
  return err;
464
}
465
 
466
/* Nearly all compilers today store these bit fields as a packed structure
467
   in network byte order (Big Endian). If you happen to be unlucky enough
468
   to be working in a non standard environment, you may need to rewrite
469
   this routine or the SET_REG32 macro. */
470
int SetDebugUnitRegister(unsigned int address,uint32_t data)
471
{
472
  int err = 0;
473
  uint32_t value = data;
474
  int old_value;
475
  int group = address >> 11;
476
 
477
  /* This is a memory location */
478
  if(address & 0x80000000)
479
    {
480
      address &= 0x7FFFFFFF;
481
      address <<= 2;
482
 
483
      if(!verify_memoryarea(address))
484
        err = JTAG_PROXY_INVALID_ADDRESS;
485
      else
486
        {
487
          unsigned char t_data[4];
488
          int *tmp = (int*)t_data;
489
          extern char null_str[1];  /* From cpu/common/parse.c */
490
          int i;
491
 
492
          *tmp = htonl(data); /* We have already converted to host order */
493
 
494
          setsim_mem8(address++, t_data[0]); /* Back to network byte order */
495
          setsim_mem8(address++, t_data[1]);
496
          setsim_mem8(address++, t_data[2]);
497
          setsim_mem8(address++, t_data[3]);
498
        }
499
      return err;
500
    }
501
 
502
  address &= 0x07FF;
503
 
504
  /*****************************************************/
505
  /*  TEMPORARY!!!!                                    */
506
  /*****************************************************/
507
  if(group == 6)
508
    address -= 32;
509
 
510
  if(group == 6)
511
    {
512
      switch(address)
513
        {
514
        case DEBUGINT_DVR0:
515
        case DEBUGINT_DVR1:
516
        case DEBUGINT_DVR2:
517
        case DEBUGINT_DVR3:
518
        case DEBUGINT_DVR4:
519
        case DEBUGINT_DVR5:
520
        case DEBUGINT_DVR6:
521
        case DEBUGINT_DVR7:
522
          printf("DVR %d set to 0x%08x\n",address-DEBUGINT_DVR0,value);
523
          SET_REG32(debug_unit.DVR[address-DEBUGINT_DVR0],value);
524
          break;
525
        case DEBUGINT_DCR0:
526
        case DEBUGINT_DCR1:
527
        case DEBUGINT_DCR2:
528
        case DEBUGINT_DCR3:
529
        case DEBUGINT_DCR4:
530
        case DEBUGINT_DCR5:
531
        case DEBUGINT_DCR6:
532
        case DEBUGINT_DCR7:
533
          printf("DCR %d set to 0x%08x\n",address-DEBUGINT_DCR0,value);
534
          SET_REG32(debug_unit.DCR[address-DEBUGINT_DCR0],value);
535
          break;
536
        case DEBUGINT_DMR1:
537
          SET_REG32(debug_unit.DMR1,value);
538
          break;
539
        case DEBUGINT_DMR2:
540
          SET_REG32(debug_unit.DMR2,value);
541
          break;
542
        case DEBUGINT_DWCR0:
543
          SET_REG32(debug_unit.DWCR[0],value);
544
          break;
545
        case DEBUGINT_DWCR1:
546
          SET_REG32(debug_unit.DWCR[1],value);
547
          break;
548
        case DEBUGINT_DSR:
549
          SET_REG32(debug_unit.DSR,value);
550
          break;
551
        case DEBUGINT_DRR:
552
          SET_REG32(debug_unit.DRR,value);
553
          break;
554
        case DEBUGINT_DIR:
555
          InduceImmediateInstruction(value);
556
          break;
557
        default:
558
          err = JTAG_PROXY_INVALID_ADDRESS;
559
          break;
560
        }
561
    }
562
  else if(group == 0)
563
    {
564
      extern unsigned long reg[32];
565
 
566
      if(!address)
567
        err = JTAG_PROXY_ACCESS_EXCEPTION;
568
      else if(address < 32)
569
        {
570
          /* Assume that a write to the PC implies
571
             that the debugging software has recognized
572
             the exception and wants to do something
573
             else instead. */
574
 
575
          if(address == SPR_PC)
576
            {
577
              ClearPendingException();
578
              ClearPreparedPCState();
579
            }
580
          mtspr(address,data);
581
        }
582
      else if(address >= 0x0400 && address < 0x0420)
583
        reg[address - 0x0400] = data;
584
      else if(address < 0x0600 || address >= 0x0620)
585
        err = JTAG_PROXY_INVALID_ADDRESS;
586
    }
587
  else
588
    err = JTAG_PROXY_INVALID_ADDRESS;
589
 
590
  return err;
591
}
592
 
593
int GetDebugUnitRegister(unsigned int address,uint32_t *data)
594
{
595
  int err = 0;
596
  uint32_t value = 0;
597
  int group = address >> 11;
598
 
599
  /* This is a memory location */
600
  if(address & 0x80000000)
601
    {
602
      address &= 0x7FFFFFFF;
603
      address <<= 2;
604
 
605
      if(!verify_memoryarea(address))
606
        err = JTAG_PROXY_INVALID_ADDRESS;
607
      else
608
        {
609
          unsigned char t_data[4];
610
          int *tmp = (int*)t_data;
611
          int bp;
612
 
613
          t_data[0] = evalsim_mem8(address++);
614
          t_data[1] = evalsim_mem8(address++);
615
          t_data[2] = evalsim_mem8(address++);
616
          t_data[3] = evalsim_mem8(address++); /* Already in network byte order */
617
 
618
          *data = ntohl(*tmp);  /* But we assume it is in host order later */
619
        }
620
      return err;
621
    }
622
 
623
  address &= 0x07FF;
624
 
625
  /*****************************************************/
626
  /*  TEMPORARY!!!!                                    */
627
  /*****************************************************/
628
  if(group == 6)
629
    address -= 32;
630
 
631
  if(group == 6)
632
    {
633
      switch(address)
634
        {
635
        case DEBUGINT_DVR0:
636
        case DEBUGINT_DVR1:
637
        case DEBUGINT_DVR2:
638
        case DEBUGINT_DVR3:
639
        case DEBUGINT_DVR4:
640
        case DEBUGINT_DVR5:
641
        case DEBUGINT_DVR6:
642
        case DEBUGINT_DVR7:    GET_REG32(debug_unit.DVR[address-DEBUGINT_DVR0],value);  break;
643
        case DEBUGINT_DCR0:
644
        case DEBUGINT_DCR1:
645
        case DEBUGINT_DCR2:
646
        case DEBUGINT_DCR3:
647
        case DEBUGINT_DCR4:
648
        case DEBUGINT_DCR5:
649
        case DEBUGINT_DCR6:
650
        case DEBUGINT_DCR7:    GET_REG32(debug_unit.DCR[address-DEBUGINT_DCR0],value);  break;
651
        case DEBUGINT_DMR1:    GET_REG32(debug_unit.DMR1,value);         break;
652
        case DEBUGINT_DMR2:    GET_REG32(debug_unit.DMR2,value);         break;
653
        case DEBUGINT_DWCR0:   GET_REG32(debug_unit.DWCR[0],value);        break;
654
        case DEBUGINT_DWCR1:   GET_REG32(debug_unit.DWCR[1],value);        break;
655
        case DEBUGINT_DSR:     GET_REG32(debug_unit.DSR,value);          break;
656
        case DEBUGINT_DRR:     GET_REG32(debug_unit.DRR,value);          break;
657
        case DEBUGINT_DIR:     err = JTAG_PROXY_ACCESS_EXCEPTION;        break;
658
        default:               err = JTAG_PROXY_INVALID_ADDRESS;         break;
659
        }
660
    }
661
  else if(group == 0)
662
    {
663
      extern unsigned long reg[32];
664
 
665
      if(address < 32)
666
        value = mfspr(address);
667
      else if(address >= 0x0400 && address < 0x0420)
668
        value = reg[address - 0x400];
669
      else if(address >= 0x0600 && address < 0x0620)
670
        value = 0;
671
      else
672
        err = JTAG_PROXY_INVALID_ADDRESS;
673
    }
674
  else
675
    err = JTAG_PROXY_INVALID_ADDRESS;
676
 
677
  *data = value;
678
  return err;
679
}
680
 
681
/* DebugCheckException returns 1 if the exception should be ignored.
682
   Currently, this is true only if the exception is a breakpoint
683
   exception and debug_unit.DMR1.ST is set. Sorry, this is a quick
684
   hack to disable processing of breakpoint exceptions on single
685
   stepping. Just one of those historical accidents. Feel free
686
   to rewrite the behavior. */
687
int DebugCheckException(int exception)
688
{
689
  int result = 0;
690
 
691
  switch(exception)
692
    {
693
    case EXCEPT_RESET:     result = debug_unit.DRR.RSTE   = debug_unit.DSR.RSTE;   break;
694
    case EXCEPT_BUSERR:    result = debug_unit.DRR.BUSEE  = debug_unit.DSR.BUSEE;  break;
695
    case EXCEPT_DPF:       result = debug_unit.DRR.DPFE   = debug_unit.DSR.DPFE;   break;
696
    case EXCEPT_IPF:       result = debug_unit.DRR.IPFE   = debug_unit.DSR.IPFE;   break;
697
    case EXCEPT_LPINT:     result = debug_unit.DRR.LPINTE = debug_unit.DSR.LPINTE; break;
698
    case EXCEPT_ALIGN:     result = debug_unit.DRR.AE     = debug_unit.DSR.AE;     break;
699
    case EXCEPT_ILLEGAL:   result = debug_unit.DRR.IIE    = debug_unit.DSR.IIE;    break;
700
    case EXCEPT_HPINT:     result = debug_unit.DRR.HPINTE = debug_unit.DSR.HPINTE; break;
701
    case EXCEPT_DTLBMISS:  result = debug_unit.DRR.DME    = debug_unit.DSR.DME;    break;
702
    case EXCEPT_ITLBMISS:  result = debug_unit.DRR.IME    = debug_unit.DSR.IME;    break;
703
    case EXCEPT_RANGE:     result = debug_unit.DRR.RE     = debug_unit.DSR.RE;     break;
704
    case EXCEPT_SYSCALL:   result = debug_unit.DRR.SCE    = debug_unit.DSR.SCE;    break;
705
    case EXCEPT_BREAK:     result = debug_unit.DRR.BE     = debug_unit.DSR.BE;     break;
706
    case EXCEPT_TRAP:      result = debug_unit.DRR.TE     = debug_unit.DSR.TE;     break;
707
    default:
708
      break;
709
    }
710
 
711
  if(result)
712
    SetCPUStallState(true);
713
 
714
  return (debug_unit.DMR1.ST && exception == EXCEPT_BREAK);
715
}

powered by: WebSVN 2.1.0

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