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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [cygmon/] [v2_0/] [misc/] [bsp/] [arm/] [singlestep.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      singlestep.c
4
//
5
//      ARM(R) specific single-step support.
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    
44
// Contributors: gthomas
45
// Date:         1999-10-20
46
// Purpose:      ARM(R) specific single-step support. 
47
// Description:  ARM is a Registered Trademark of Advanced RISC Machines Limited.
48
//               Other Brands and Trademarks are the property of their
49
//               respective owners.
50
//
51
//####DESCRIPTIONEND####
52
//
53
//=========================================================================
54
 
55
 
56
#include <stdlib.h>
57
#include <bsp/bsp.h>
58
#include <bsp/cpu.h>
59
#include "insn.h"
60
 
61
#define DEBUG_SINGLESTEP         0
62
#define DEBUG_SINGLESTEP_VERBOSE 0
63
 
64
/*
65
 * Structure to hold opcodes hoisted when breakpoints are
66
 * set for single-stepping or async interruption.
67
 */
68
struct _bp_save {
69
    unsigned long *addr;
70
    unsigned long opcode;
71
};
72
 
73
#define NUM_BREAKS_SAVED 2
74
static struct _bp_save _breaks[NUM_BREAKS_SAVED];
75
 
76
/*
77
 *  Insert a breakpoint at 'pc' using first available
78
 *  _bp_save struct.
79
 */
80
static void
81
insert_ss_break(unsigned long *pc)
82
{
83
    struct _bp_save *p = _breaks;
84
    union arm_insn inst;
85
 
86
    if (p->addr && (++p)->addr)
87
        return;
88
 
89
    /*
90
     * We can't set a breakpoint at 0
91
     */
92
    if (pc == 0)
93
    {
94
#if DEBUG_SINGLESTEP
95
        bsp_printf("Setting BP at <0x%08lx>: Error\n", pc);
96
#endif /* DEBUG_SINGLESTEP */
97
        return;
98
    }
99
 
100
    /*
101
     * Make sure we are on a long word boundary.
102
     */
103
    if (((unsigned long)pc & 0x3) != 0)
104
    {
105
        /*
106
         * All ARM(R) instructions are on a word boundary.
107
         * This would be invalid.  Don't set a bkpt here.
108
         */
109
#if DEBUG_SINGLESTEP
110
        bsp_printf("Setting BP at <0x%08lx>: Error\n", pc);
111
#endif /* DEBUG_SINGLESTEP */
112
        return;
113
    }
114
 
115
 
116
    /*
117
     * What is the current instruction
118
     */
119
    if (bsp_memory_read(pc, 0, ARM_INST_SIZE * 8, 1, &(inst.word)) == 0)
120
    {
121
        /*
122
         * Unable to read this address, probably an invalid address.
123
         * Don't set a breakpoint here, as it will likely cause a bus error
124
         */
125
#if DEBUG_SINGLESTEP
126
        bsp_printf("Setting BP at <0x%08lx>: Error\n", pc);
127
#endif /* DEBUG_SINGLESTEP */
128
        return;
129
    }
130
 
131
    if (inst.word != BREAKPOINT_INSN)
132
    {
133
        /*
134
         * Only insert a breakpoint if we haven't done so already
135
         *
136
         * We may try to insert 2 breakpoints if we to a branch to
137
         * the immediately following instruction.
138
         */
139
#if DEBUG_SINGLESTEP
140
        bsp_printf("Setting BP at <0x%08lx>: inst <0x%08lx>\n", pc, inst.word);
141
#endif /* DEBUG_SINGLESTEP */
142
 
143
        p->addr = pc;
144
        p->opcode = inst.word;
145
        inst.word = BREAKPOINT_INSN;
146
        if (bsp_memory_write(pc, 0, ARM_INST_SIZE * 8, 1, &(inst.word)) == 0)
147
        {
148
            /*
149
             * Unable to write this address, probably an invalid address.
150
             * Don't set a breakpoint here, as it will likely cause a bus error
151
             */
152
#if DEBUG_SINGLESTEP
153
            bsp_printf("Setting BP at <0x%08lx>: Error\n", pc);
154
#endif /* DEBUG_SINGLESTEP */
155
            return;
156
        }
157
 
158
        /* flush icache and dcache, now */
159
        bsp_flush_dcache((void *)pc, ARM_INST_SIZE);
160
        bsp_flush_icache((void *)pc, ARM_INST_SIZE);
161
 
162
#if DEBUG_SINGLESTEP_VERBOSE
163
        bsp_printf("Done setting BP at <0x%08lx>: inst <0x%08lx>\n", pc, *pc);
164
#endif /* DEBUG_SINGLESTEP_VERBOSE */
165
    }
166
}
167
 
168
/*
169
 *  Cleanup after a singlestep.
170
 */
171
void
172
bsp_singlestep_cleanup(void *registers)
173
{
174
    struct _bp_save *p = _breaks;
175
    int i;
176
 
177
    for (i = 0; i < NUM_BREAKS_SAVED; i++, p++)
178
    {
179
        if (p->addr)
180
        {
181
            unsigned long *old_addr = p->addr;
182
 
183
#if DEBUG_SINGLESTEP_VERBOSE
184
            bsp_printf("Remove BP at <0x%08lx>: inst <0x%08lx>\n", old_addr, *old_addr);
185
#endif /* DEBUG_SINGLESTEP */
186
            *(p->addr) = p->opcode;
187
            p->addr = NULL;
188
 
189
            /* flush icache and dcache, now */
190
            bsp_flush_dcache((void *)old_addr, ARM_INST_SIZE);
191
            bsp_flush_icache((void *)old_addr, ARM_INST_SIZE);
192
 
193
#if DEBUG_SINGLESTEP_VERBOSE
194
            bsp_printf("Done removing BP at <0x%08lx>: inst <0x%08lx>\n", old_addr, *old_addr);
195
#endif /* DEBUG_SINGLESTEP_VERBOSE */
196
        }
197
    }
198
}
199
 
200
/*
201
 * Rotate right a value by count
202
 */
203
static unsigned long ror(unsigned long value, unsigned count)
204
{
205
    while (count-- > 0)
206
    {
207
        if (value & 0x1)
208
            value = (value >> 1) | 0x80000000;
209
        else
210
            value = (value >> 1);
211
    }
212
 
213
    return(value);
214
}
215
 
216
/*
217
 * Rotate right a value by 1 with extend
218
 */
219
static unsigned long rrx(union arm_psr sr, unsigned long value)
220
{
221
    if (sr.psr.c_bit)
222
        value = (value >> 1) | 0x80000000;
223
    else
224
        value = (value >> 1);
225
 
226
    return(value);
227
}
228
 
229
/*
230
 * Logical shift left by count
231
 */
232
static unsigned long lsl(unsigned long value, unsigned count)
233
{
234
    value <<= count;
235
 
236
    return(value);
237
}
238
 
239
/*
240
 * Logical shift right by count
241
 */
242
static unsigned long lsr(unsigned long value, unsigned count)
243
{
244
    value >>= count;
245
 
246
    return(value);
247
}
248
 
249
/*
250
 * Arithmetic shift right by count
251
 */
252
static unsigned long asr(unsigned long value, unsigned count)
253
{
254
    unsigned long sign_ext_mask = 0;
255
 
256
    if (value & 0x80000000)
257
    {
258
        if (count >= sizeof(value)*8)
259
            sign_ext_mask = ~0;
260
        else
261
            sign_ext_mask = (~0 << (sizeof(value)*8 - count));
262
    }
263
    value = (value >> count) | sign_ext_mask;
264
 
265
    return(value);
266
}
267
 
268
/*
269
 * Calculate an immediate shift operand based on input shift operand,
270
 * shift value and register address.
271
 */
272
static unsigned long immediate_shift_operand(ex_regs_t *regs, unsigned shift_immediate,
273
                                             unsigned shift, unsigned Rm)
274
{
275
    unsigned char *regs_array = (unsigned char *)regs;
276
    unsigned char *reg_ptr = &regs_array[bsp_regbyte(Rm)];
277
    unsigned long reg_value = *((unsigned long *)(reg_ptr));
278
    unsigned long rc = 0;
279
 
280
    BSP_ASSERT((shift_immediate >= 0) && (shift_immediate <= 0x1f));
281
    BSP_ASSERT((shift >= 0) && (shift <= 0x3));
282
    BSP_ASSERT((Rm >= 0) && (Rm <= 0xf));
283
    BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long));
284
 
285
    /*
286
     * According to the ARM(R) Manual, if Rm is PC then,
287
     * the value used is the address of the current instruction
288
     * plus 8
289
     */
290
    if (Rm == REG_PC)
291
        reg_value += 8;
292
 
293
    switch (shift)
294
    {
295
    case SHIFT_LSL:
296
        rc = lsl(reg_value, shift_immediate);
297
        break;
298
 
299
    case SHIFT_LSR:
300
        if (shift_immediate == 0)
301
        {
302
            /*
303
             * Special Case: LSR IMM(0) == 0
304
             */
305
            rc = 0;
306
        } else {
307
            rc = lsr(reg_value, shift_immediate);
308
        }
309
        break;
310
 
311
    case SHIFT_ASR:
312
        if (shift_immediate == 0)
313
        {
314
            /*
315
             * Special Case: ASR IMM(0)
316
             */
317
            if (reg_value & 0x80000000)
318
            {
319
                rc = 0xFFFFFFFF;
320
            } else {
321
                rc = 0;
322
            }
323
        } else {
324
            rc = asr(reg_value, shift_immediate);
325
        }
326
        break;
327
 
328
    case SHIFT_ROR:
329
        if (shift_immediate == 0)
330
        {
331
            /*
332
             * SHIFT_RRX
333
             * Special case: ROR(0) implies RRX
334
             */
335
            rc = rrx((union arm_psr)(unsigned long)regs->_cpsr, reg_value);
336
        } else {
337
            rc = ror(reg_value, shift_immediate);
338
        }
339
        break;
340
 
341
    default:
342
        BSP_ASSERT(0);
343
        break;
344
    }
345
 
346
    return (rc);
347
}
348
 
349
/*
350
 * Calculate a register shift operand based on input shift operand,
351
 * and target registers.
352
 */
353
static unsigned long register_shift_operand(ex_regs_t *regs, unsigned Rs,
354
                                            unsigned shift, unsigned Rm)
355
{
356
    unsigned char *regs_array = (unsigned char *)regs;
357
    unsigned char *Rs_ptr = &regs_array[bsp_regbyte(Rs)];
358
    unsigned char *Rm_ptr = &regs_array[bsp_regbyte(Rm)];
359
    unsigned long Rs_val = *((unsigned long *)(Rs_ptr));
360
    unsigned long Rm_val = *((unsigned long *)(Rm_ptr));
361
    unsigned long rc = 0;
362
 
363
    /*
364
     * Use only the least significant byte of Rs
365
     */
366
    Rs_val &= 0xFF;
367
 
368
    BSP_ASSERT((Rs >= 0) && (Rs <= 0xf));
369
    BSP_ASSERT((shift >= 0) && (shift <= 0x3));
370
    BSP_ASSERT((Rm >= 0) && (Rm <= 0xf));
371
    BSP_ASSERT(bsp_regsize(Rs) == sizeof(unsigned long));
372
    BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long));
373
    BSP_ASSERT((Rs_val >=0) && (Rs_val <= 0xff));
374
 
375
    /*
376
     * According to the ARM(R) Manual, if Rm is PC then,
377
     * the value used is the address of the current instruction
378
     * plus 8
379
     */
380
    if (Rm == REG_PC)
381
        Rm_val += 8;
382
 
383
    switch (shift)
384
    {
385
    case SHIFT_LSL: rc = lsl(Rm_val, Rs_val); break;
386
    case SHIFT_LSR: rc = lsr(Rm_val, Rs_val); break;
387
    case SHIFT_ASR: rc = asr(Rm_val, Rs_val); break;
388
    case SHIFT_ROR: rc = ror(Rm_val, Rs_val); break;
389
    default:        BSP_ASSERT(0);            break;
390
    }
391
 
392
    return (rc);
393
}
394
 
395
/*
396
 * Calculate a branch exchange operand based on input destination register
397
 */
398
static unsigned long branch_exchange_operand(ex_regs_t *regs, unsigned Rm)
399
{
400
    unsigned char *regs_array = (unsigned char *)regs;
401
    unsigned char *reg_ptr = &regs_array[bsp_regbyte(Rm)];
402
    unsigned long reg_value = *((unsigned long *)(reg_ptr));
403
 
404
    BSP_ASSERT((Rm >= 0) && (Rm <= 0xf));
405
    BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long));
406
 
407
    /*
408
     * Clear the low-order bit
409
     */
410
    return (reg_value & ~0x1);
411
}
412
 
413
/*
414
 * Handle a load to the PC
415
 */
416
static void handle_pc_load(unsigned size, unsigned long operand)
417
{
418
    unsigned long mem_value = 0;
419
 
420
    if (size == LS_SIZE_WORD)
421
    {
422
        if (bsp_memory_read((void*)(operand & ~0x3), 0, 32, 1, &mem_value) == 0)
423
        {
424
            /*
425
             * Unable to read the memory address.
426
             * Don't try any further.
427
             */
428
#if DEBUG_SINGLESTEP
429
            bsp_printf("Setting BP at *(0x%08lx): Error\n", operand & ~0x3);
430
#endif /* DEBUG_SINGLESTEP */
431
            return;
432
        } else {
433
#if DEBUG_SINGLESTEP
434
            bsp_printf("Setting BP at *(0x%08lx): data <0x%08lx>\n", operand & ~0x3, mem_value);
435
#endif /* DEBUG_SINGLESTEP */
436
        }
437
 
438
        /*
439
         * Handle rotations if required
440
         */
441
        switch (operand & 0x3)
442
        {
443
        case 0x0: break;
444
        case 0x1: mem_value = ror(mem_value,  8); break;
445
        case 0x2: mem_value = ror(mem_value, 16); break;
446
        case 0x3: mem_value = ror(mem_value, 24); break;
447
        }
448
    } else {
449
        /*
450
         * Byte load of the PC
451
         */
452
        if (bsp_memory_read((void*)operand, 0, 8, 1, &mem_value) == 0)
453
        {
454
            /*
455
             * Unable to read the memory address.
456
             * Don't try any further.
457
             */
458
#if DEBUG_SINGLESTEP
459
            bsp_printf("Setting BP at *(0x%08lx): Error\n", operand & ~0x3);
460
#endif /* DEBUG_SINGLESTEP */
461
            return;
462
        } else {
463
#if DEBUG_SINGLESTEP
464
            bsp_printf("Setting BP at *(0x%08lx): data <0x%08lx>\n", operand & ~0x3, mem_value);
465
#endif /* DEBUG_SINGLESTEP */
466
        }
467
    }
468
 
469
    insert_ss_break((unsigned long *)mem_value);
470
}
471
 
472
/*
473
 * Calculate a load/store w/ Immediate offset operand based on input
474
 * source register, offset value, and opcode (add/sub)
475
 */
476
static unsigned long load_store_immediate_operand(ex_regs_t *regs,
477
                                                  unsigned p_bit,
478
                                                  unsigned u_bit,
479
                                                  unsigned Rn,
480
                                                  unsigned offset)
481
{
482
    unsigned char *regs_array = (unsigned char *)regs;
483
    unsigned char *reg_ptr = &regs_array[bsp_regbyte(Rn)];
484
    unsigned long rc = *((unsigned long *)(reg_ptr));
485
 
486
    BSP_ASSERT((Rn >= 0) && (Rn <= 0xf));
487
    BSP_ASSERT(bsp_regsize(Rn) == sizeof(unsigned long));
488
    BSP_ASSERT((offset >= 0) && (offset <= 0xfff));
489
    BSP_ASSERT((p_bit >= 0) && (p_bit <= 1));
490
    BSP_ASSERT((u_bit >= 0) && (u_bit <= 1));
491
 
492
    /*
493
     * According to the ARM(R) Manual, if Rn is PC then,
494
     * the value used is the address of the current instruction
495
     * plus 8
496
     */
497
    if (Rn == REG_PC)
498
        rc += 8;
499
 
500
    /*
501
     * Do the update pre-index update
502
     */
503
    if (p_bit == LS_INDEX_PRE)
504
    {
505
        if (u_bit == LS_OFFSET_SUB)
506
            rc -= offset;
507
        else /* opcode == LS_OFFSET_ADD */
508
            rc += offset;
509
    }
510
 
511
   return (rc);
512
}
513
 
514
/*
515
 * Calculate a load/store w/ Register offset operand based on input
516
 * source register, offset value, and opcode (add/sub)
517
 *
518
 * This calculates the appropriate pre-indexed operand
519
 */
520
static unsigned long load_store_register_operand(ex_regs_t *regs,
521
                                                 unsigned p_bit,
522
                                                 unsigned u_bit,
523
                                                 unsigned Rn,
524
                                                 unsigned Rm,
525
                                                 unsigned shift,
526
                                                 unsigned shift_immed)
527
{
528
    unsigned char *regs_array = (unsigned char *)regs;
529
    unsigned char *Rn_ptr = &regs_array[bsp_regbyte(Rn)];
530
    unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
531
    unsigned long rc, index;
532
 
533
    BSP_ASSERT((Rn >= 0) && (Rn <= 0xf));
534
    BSP_ASSERT((Rm >= 0) && (Rm <= 0xf));
535
    BSP_ASSERT(bsp_regsize(Rn) == sizeof(unsigned long));
536
    BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long));
537
    BSP_ASSERT((p_bit >= 0) && (p_bit <= 1));
538
    BSP_ASSERT((u_bit >= 0) && (u_bit <= 1));
539
    BSP_ASSERT((shift >= 0) && (shift <= 0x3));
540
    BSP_ASSERT((shift_immed >= 0) && (shift_immed <= 0x1F));
541
 
542
    /*
543
     * According to the ARM(R) Manual, if Rn is PC then
544
     * the value used is the address of the current
545
     * instruction plus 8
546
     */
547
    if (Rn == REG_PC)
548
        Rn_val += 8;
549
 
550
    /*
551
     * According to the ARM(R) Manual, if Rm is PC then
552
     * the result is unpredictable.  Don't do anything
553
     * here.  Just return.
554
     */
555
    if (Rm == REG_PC)
556
        return 0;
557
 
558
    index = immediate_shift_operand(regs, shift_immed, shift, Rm);
559
 
560
    rc = Rn_val;
561
 
562
    /*
563
     * Do the update pre-index update
564
     */
565
    if (p_bit == LS_INDEX_PRE)
566
    {
567
        if (u_bit == LS_OFFSET_SUB)
568
            rc = Rn_val - index;
569
        else /* opcode == LS_OFFSET_ADD */
570
            rc = Rn_val + index;
571
    }
572
 
573
   return (rc);
574
}
575
 
576
/*
577
 * Decode all data processing immediate instructions
578
 */
579
static void decode_dpi_inst(ex_regs_t *regs, union arm_insn inst)
580
{
581
    if (inst.dpi.Rd == REG_PC)
582
    {
583
        unsigned long operand = ror(inst.dpi.immediate, (inst.dpi.rotate << 1));
584
        unsigned long *dest = 0;
585
        unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit;
586
        unsigned char *regs_array = (unsigned char *)regs;
587
        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.dpi.Rn)];
588
        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
589
 
590
#if DEBUG_SINGLESTEP_VERBOSE
591
        bsp_printf("Decoded an data processing immediate instruction.\n");
592
        bsp_printf("inst.dpi.immediate = 0x%x\n", inst.dpi.immediate);
593
        bsp_printf("inst.dpi.rotate    = 0x%x\n", inst.dpi.rotate);
594
        bsp_printf("inst.dpi.Rd        = 0x%x\n", inst.dpi.Rd);
595
        bsp_printf("inst.dpi.Rn        = 0x%x\n", inst.dpi.Rn);
596
        bsp_printf("inst.dpi.S_bit     = 0x%x\n", inst.dpi.S_bit);
597
        bsp_printf("inst.dpi.opcode    = 0x%x\n", inst.dpi.opcode);
598
        bsp_printf("inst.dpi.cond      = 0x%x\n", inst.dpi.cond);
599
        bsp_printf("operand            = 0x%x\n", operand);
600
#endif /* DEBUG_SINGLESTEP_VERBOSE */
601
 
602
        /*
603
         * According to the ARM(R) Manual, if Rn is PC then
604
         * the value used is the address of the current
605
         * instruction plus 8
606
         */
607
        if (inst.dpi.Rn == REG_PC)
608
            Rn_val += 8;
609
 
610
        switch (inst.dpi.opcode) {
611
        case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry);    break;
612
        case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand);            break;
613
        case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand);            break;
614
        case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand);           break;
615
        case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand);            break;
616
        case DP_OPCODE_MOV: dest = (unsigned long *)operand;                       break;
617
        case DP_OPCODE_MVN: dest = (unsigned long *)(~operand);                    break;
618
        case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand);            break;
619
        case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val);            break;
620
        case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry);   break;
621
        case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry);   break;
622
        case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand);            break;
623
        default:            dest = (unsigned long *)0;                             break;
624
        }
625
        dest = (unsigned long *)((unsigned long)dest & ~0x3);
626
        insert_ss_break(dest);
627
    }
628
}
629
 
630
/*
631
 * Decode all data processing immediate w/ shift instructions
632
 */
633
static void decode_dpis_inst(ex_regs_t *regs, union arm_insn inst)
634
{
635
    if (inst.dpis.Rd == REG_PC)
636
    {
637
        unsigned long operand = immediate_shift_operand(regs, inst.dpis.shift_immed,
638
                                                        inst.dpis.shift, inst.dpis.Rm);
639
        unsigned long *dest = 0;
640
        unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit;
641
        unsigned char *regs_array = (unsigned char *)regs;
642
        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.dpis.Rn)];
643
        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
644
 
645
#if DEBUG_SINGLESTEP_VERBOSE
646
        bsp_printf("Decoded an data processing immediate shift instruction.\n");
647
        bsp_printf("inst.dpis.Rm          = 0x%x\n", inst.dpis.Rm);
648
        bsp_printf("inst.dpis.shift       = 0x%x\n", inst.dpis.shift);
649
        bsp_printf("inst.dpis.shift_immed = 0x%x\n", inst.dpis.shift_immed);
650
        bsp_printf("inst.dpis.Rd          = 0x%x\n", inst.dpis.Rd);
651
        bsp_printf("inst.dpis.Rn          = 0x%x\n", inst.dpis.Rn);
652
        bsp_printf("inst.dpis.S_bit       = 0x%x\n", inst.dpis.S_bit);
653
        bsp_printf("inst.dpis.opcode      = 0x%x\n", inst.dpis.opcode);
654
        bsp_printf("inst.dpis.cond        = 0x%x\n", inst.dpis.cond);
655
        bsp_printf("operand               = 0x%x\n", operand);
656
#endif /* DEBUG_SINGLESTEP_VERBOSE */
657
 
658
        /*
659
         * According to the ARM(R) Manual, if Rn is PC then
660
         * the value used is the address of the current
661
         * instruction plus 8
662
         */
663
        if (inst.dpis.Rn == REG_PC)
664
            Rn_val += 8;
665
 
666
        switch (inst.dpis.opcode) {
667
        case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry);    break;
668
        case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand);            break;
669
        case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand);            break;
670
        case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand);           break;
671
        case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand);            break;
672
        case DP_OPCODE_MOV: dest = (unsigned long *)operand;                       break;
673
        case DP_OPCODE_MVN: dest = (unsigned long *)(~operand);                    break;
674
        case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand);            break;
675
        case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val);            break;
676
        case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry);   break;
677
        case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry);   break;
678
        case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand);            break;
679
        default:            dest = (unsigned long *)0;                             break;
680
        }
681
        dest = (unsigned long *)((unsigned long)dest & ~0x3);
682
        insert_ss_break(dest);
683
    }
684
}
685
 
686
/*
687
 * Decode all data processing register w/ shift instructions
688
 */
689
static void decode_dprs_inst(ex_regs_t *regs, union arm_insn inst)
690
{
691
    if (inst.dprs.Rd == REG_PC)
692
    {
693
        unsigned long operand = register_shift_operand(regs, inst.dprs.Rs,
694
                                                       inst.dprs.shift, inst.dprs.Rm);
695
        unsigned long *dest = 0;
696
        unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit;
697
        unsigned char *regs_array = (unsigned char *)regs;
698
        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.dprs.Rn)];
699
        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
700
 
701
#if DEBUG_SINGLESTEP_VERBOSE
702
        bsp_printf("Decoded an data processing register shift instruction.\n");
703
        bsp_printf("inst.dprs.Rm          = 0x%x\n", inst.dprs.Rm);
704
        bsp_printf("inst.dprs.rsv3        = 0x%x\n", inst.dprs.rsv3);
705
        bsp_printf("inst.dprs.shift       = 0x%x\n", inst.dprs.shift);
706
        bsp_printf("inst.dprs.rsv2        = 0x%x\n", inst.dprs.rsv2);
707
        bsp_printf("inst.dprs.Rs          = 0x%x\n", inst.dprs.Rs);
708
        bsp_printf("inst.dprs.Rd          = 0x%x\n", inst.dprs.Rd);
709
        bsp_printf("inst.dprs.Rn          = 0x%x\n", inst.dprs.Rn);
710
        bsp_printf("inst.dprs.S_bit       = 0x%x\n", inst.dprs.S_bit);
711
        bsp_printf("inst.dprs.opcode      = 0x%x\n", inst.dprs.opcode);
712
        bsp_printf("inst.dprs.rsv1        = 0x%x\n", inst.dprs.rsv1);
713
        bsp_printf("inst.dprs.cond        = 0x%x\n", inst.dprs.cond);
714
        bsp_printf("operand               = 0x%x\n", operand);
715
#endif /* DEBUG_SINGLESTEP_VERBOSE */
716
 
717
        /*
718
         * According to the ARM(R) Manual, if Rn is PC then
719
         * the value used is the address of the current
720
         * instruction plus 8
721
         */
722
        if (inst.dprs.Rn == REG_PC)
723
            Rn_val += 8;
724
 
725
        switch (inst.dprs.opcode) {
726
        case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry);    break;
727
        case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand);            break;
728
        case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand);            break;
729
        case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand);           break;
730
        case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand);            break;
731
        case DP_OPCODE_MOV: dest = (unsigned long *)operand;                       break;
732
        case DP_OPCODE_MVN: dest = (unsigned long *)(~operand);                    break;
733
        case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand);            break;
734
        case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val);            break;
735
        case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry);   break;
736
        case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry);   break;
737
        case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand);            break;
738
        default:            dest = (unsigned long *)0;                             break;
739
        }
740
 
741
        dest = (unsigned long *)((unsigned long)dest & ~0x3);
742
        insert_ss_break(dest);
743
    }
744
}
745
 
746
/*
747
 * Decode all multiply instructions
748
 */
749
static void decode_m_inst(ex_regs_t *regs, union arm_insn inst)
750
{
751
    /*
752
     * According to the ARM(R) Manual, if Rd is PC then
753
     * the result is unpredictable.  Don't do anything
754
     * here.  Just return.
755
     */
756
}
757
 
758
/*
759
 * Decode all multiply long instructions
760
 */
761
static void decode_ml_inst(ex_regs_t *regs, union arm_insn inst)
762
{
763
    /*
764
     * According to the ARM(R) Manual, if Rd is PC then
765
     * the result is unpredictable.  Don't do anything
766
     * here.  Just return.
767
     */
768
}
769
 
770
 
771
/*
772
 * Decode all move from status register instructions
773
 */
774
static void decode_mrs_inst(ex_regs_t *regs, union arm_insn inst)
775
{
776
#if 0
777
    if (inst.mrs.Rd == REG_PC)
778
    {
779
        unsigned long *dest = 0;
780
 
781
#if DEBUG_SINGLESTEP_VERBOSE
782
    bsp_printf("Decoded an move from status register instruction.\n");
783
    bsp_printf("inst.mrs.SBZ        = 0x%x\n", inst.mrs.SBZ);
784
    bsp_printf("inst.mrs.Rd         = 0x%x\n", inst.mrs.Rd);
785
    bsp_printf("inst.mrs.SBO        = 0x%x\n", inst.mrs.SBO);
786
    bsp_printf("inst.mrs.rsv2       = 0x%x\n", inst.mrs.rsv2);
787
    bsp_printf("inst.mrs.R_bit      = 0x%x\n", inst.mrs.R_bit);
788
    bsp_printf("inst.mrs.rsv1       = 0x%x\n", inst.mrs.rsv1);
789
    bsp_printf("inst.mrs.cond       = 0x%x\n", inst.mrs.cond);
790
#endif /* DEBUG_SINGLESTEP_VERBOSE */
791
 
792
        if (inst.mrs.R_bit == 1)
793
            dest = (unsigned long *)regs->_spsr;
794
        else
795
            dest = (unsigned long *)regs->_cpsr;
796
 
797
        dest = (unsigned long *)((unsigned long)dest & ~0x3);
798
        insert_ss_break(dest);
799
    }
800
#endif
801
}
802
 
803
 
804
/*
805
 * Decode all move immediate to status register instructions
806
 */
807
static void decode_misr_inst(ex_regs_t *regs, union arm_insn inst)
808
{
809
    /*
810
     * Can't update the PC w/ this instruction.
811
     * Don't set any more breakpoints
812
     */
813
}
814
 
815
 
816
/*
817
 * Decode all move register to status registers instructions
818
 */
819
static void decode_mrsr_inst(ex_regs_t *regs, union arm_insn inst)
820
{
821
    /*
822
     * Can't update the PC w/ this instruction.
823
     * Don't set any more breakpoints
824
     */
825
}
826
 
827
 
828
/*
829
 * Decode all branch/exchange instructions
830
 */
831
static void decode_bx_inst(ex_regs_t *regs, union arm_insn inst)
832
{
833
    unsigned long operand = branch_exchange_operand(regs, inst.bx.Rm);
834
 
835
#if DEBUG_SINGLESTEP_VERBOSE
836
    bsp_printf("Decoded an branch/exchange shift instruction.\n");
837
    bsp_printf("inst.bx.Rm          = 0x%x\n", inst.bx.Rm);
838
    bsp_printf("inst.bx.rsv2        = 0x%x\n", inst.bx.rsv2);
839
    bsp_printf("inst.bx.SBO3        = 0x%x\n", inst.bx.SBO3);
840
    bsp_printf("inst.bx.SBO2        = 0x%x\n", inst.bx.SBO2);
841
    bsp_printf("inst.bx.SBO1        = 0x%x\n", inst.bx.SBO1);
842
    bsp_printf("inst.bx.rsv1        = 0x%x\n", inst.bx.rsv1);
843
    bsp_printf("inst.bx.cond        = 0x%x\n", inst.bx.cond);
844
    bsp_printf("operand             = 0x%x\n", operand);
845
#endif /* DEBUG_SINGLESTEP_VERBOSE */
846
 
847
    insert_ss_break((unsigned long *)operand);
848
}
849
 
850
 
851
/*
852
 * Decode all load/store immediate offset instructions
853
 */
854
static void decode_lsio_inst(ex_regs_t *regs, union arm_insn inst)
855
{
856
    /*
857
     * Only support direct loads of the PC
858
     *
859
     * According to the ARM(R) manual, automatic updates of the PC
860
     * are UNPREDICTABLE (ie implementation defined).
861
     */
862
    if ((inst.lsio.Rd == REG_PC) && (inst.lsio.L_bit == LS_LOAD))
863
    {
864
        unsigned long operand = load_store_immediate_operand(regs, inst.lsio.P_bit,
865
                                                             inst.lsio.U_bit, inst.lsio.Rn,
866
                                                             inst.lsio.immediate);
867
 
868
#if DEBUG_SINGLESTEP_VERBOSE
869
        bsp_printf("Decoded an load/store w/ immediate offset instruction.\n");
870
        bsp_printf("inst.lsio.immediate = 0x%x\n", inst.lsio.immediate);
871
        bsp_printf("inst.lsio.Rd        = 0x%x\n", inst.lsio.Rd);
872
        bsp_printf("inst.lsio.Rn        = 0x%x\n", inst.lsio.Rn);
873
        bsp_printf("inst.lsio.L_bit     = 0x%x\n", inst.lsio.L_bit);
874
        bsp_printf("inst.lsio.W_bit     = 0x%x\n", inst.lsio.W_bit);
875
        bsp_printf("inst.lsio.B_bit     = 0x%x\n", inst.lsio.B_bit);
876
        bsp_printf("inst.lsio.U_bit     = 0x%x\n", inst.lsio.U_bit);
877
        bsp_printf("inst.lsio.P_bit     = 0x%x\n", inst.lsio.P_bit);
878
        bsp_printf("inst.lsio.rsv1      = 0x%x\n", inst.lsio.rsv1);
879
        bsp_printf("inst.lsio.cond      = 0x%x\n", inst.lsio.cond);
880
        bsp_printf("operand             = 0x%x\n", operand);
881
#endif /* DEBUG_SINGLESTEP_VERBOSE */
882
 
883
        handle_pc_load(inst.lsio.B_bit, operand);
884
    }
885
}
886
 
887
 
888
/*
889
 * Decode all load/store register offset instructions
890
 */
891
static void decode_lsro_inst(ex_regs_t *regs, union arm_insn inst)
892
{
893
    /*
894
     * Only support direct loads of the PC
895
     *
896
     * According to the ARM(R) manual, automatic updates of the PC
897
     * are UNPREDICTABLE (ie implementation defined).
898
     */
899
    if ((inst.lsro.Rd == REG_PC) && (inst.lsro.L_bit == LS_LOAD))
900
    {
901
        unsigned long operand = load_store_register_operand(regs,
902
                                                            inst.lsro.P_bit,
903
                                                            inst.lsro.U_bit,
904
                                                            inst.lsro.Rn,
905
                                                            inst.lsro.Rm,
906
                                                            inst.lsro.shift,
907
                                                            inst.lsro.shift_immed);
908
#if DEBUG_SINGLESTEP_VERBOSE
909
        bsp_printf("Decoded an load/store w/ register offset instruction.\n");
910
        bsp_printf("inst.lsro.Rm          = 0x%x\n", inst.lsro.Rm);
911
        bsp_printf("inst.lsro.rsv2        = 0x%x\n", inst.lsro.rsv2);
912
        bsp_printf("inst.lsro.shift       = 0x%x\n", inst.lsro.shift);
913
        bsp_printf("inst.lsro.shift_immed = 0x%x\n", inst.lsro.shift_immed);
914
        bsp_printf("inst.lsro.Rd          = 0x%x\n", inst.lsro.Rd);
915
        bsp_printf("inst.lsro.Rn          = 0x%x\n", inst.lsro.Rn);
916
        bsp_printf("inst.lsro.L_bit       = 0x%x\n", inst.lsro.L_bit);
917
        bsp_printf("inst.lsro.W_bit       = 0x%x\n", inst.lsro.W_bit);
918
        bsp_printf("inst.lsro.B_bit       = 0x%x\n", inst.lsro.B_bit);
919
        bsp_printf("inst.lsro.U_bit       = 0x%x\n", inst.lsro.U_bit);
920
        bsp_printf("inst.lsro.P_bit       = 0x%x\n", inst.lsro.P_bit);
921
        bsp_printf("inst.lsro.rsv1        = 0x%x\n", inst.lsro.rsv1);
922
        bsp_printf("inst.lsro.cond        = 0x%x\n", inst.lsro.cond);
923
        bsp_printf("operand               = 0x%x\n", operand);
924
#endif /* DEBUG_SINGLESTEP_VERBOSE */
925
 
926
        handle_pc_load(inst.lsro.B_bit, operand);
927
    }
928
}
929
 
930
 
931
/*
932
 * Decode all load/store halfword/signed byte immediate offset instructions
933
 */
934
static void decode_lshwi_inst(ex_regs_t *regs, union arm_insn inst)
935
{
936
    /*
937
     * According to the ARM(R) Manual, if Rd is PC then
938
     * the result is unpredictable.  Don't do anything
939
     * here.  Just return.
940
     */
941
}
942
 
943
 
944
/*
945
 * Decode all load/store halfword/signed byte register offset instructions
946
 */
947
static void decode_lshwr_inst(ex_regs_t *regs, union arm_insn inst)
948
{
949
    /*
950
     * According to the ARM(R) Manual, if Rd is PC then
951
     * the result is unpredictable.  Don't do anything
952
     * here.  Just return.
953
     */
954
}
955
 
956
 
957
/*
958
 * Decode all swap/swap byte instructions
959
 */
960
static void decode_swap_inst(ex_regs_t *regs, union arm_insn inst)
961
{
962
    /*
963
     * According to the ARM(R) Manual, if Rd is PC then
964
     * the result is unpredictable.  Don't do anything
965
     * here.  Just return.
966
     */
967
}
968
 
969
 
970
/*
971
 * Decode all load/store multiple instructions
972
 */
973
static void decode_lsm_inst(ex_regs_t *regs, union arm_insn inst)
974
{
975
    /*
976
     * Only support direct load multiples where the PC is in the
977
     * register list.
978
     *
979
     * According to the ARM(R) manual, automatic updates of the PC
980
     * are UNPREDICTABLE (ie implementation defined).
981
     */
982
    if ((inst.lsm.L_bit == LS_LOAD) && (inst.lsm.Reg_List & (0x1 << REG_PC)))
983
    {
984
        unsigned char *regs_array = (unsigned char *)regs;
985
        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.lsm.Rn)];
986
        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
987
        unsigned long offset_to_pc = 0;
988
        int i;
989
        unsigned long **dest = 0;
990
 
991
#if DEBUG_SINGLESTEP_VERBOSE
992
        bsp_printf("Decoded an load multiple instruction.\n");
993
        bsp_printf("inst.lsm.Reg_List   = 0x%x\n", inst.lsm.Reg_List);
994
 
995
        bsp_printf("inst.lsm.Rn         = 0x%x\n", inst.lsm.Rn);
996
        bsp_printf("inst.lsm.L_bit      = 0x%x\n", inst.lsm.L_bit);
997
        bsp_printf("inst.lsm.W_bit      = 0x%x\n", inst.lsm.W_bit);
998
        bsp_printf("inst.lsm.S_bit      = 0x%x\n", inst.lsm.S_bit);
999
        bsp_printf("inst.lsm.U_bit      = 0x%x\n", inst.lsm.U_bit);
1000
        bsp_printf("inst.lsm.P_bit      = 0x%x\n", inst.lsm.P_bit);
1001
        bsp_printf("inst.lsm.rsv1       = 0x%x\n", inst.lsm.rsv1);
1002
        bsp_printf("inst.lsm.cond       = 0x%x\n", inst.lsm.cond);
1003
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1004
 
1005
        if (inst.lsm.U_bit == 0)
1006
        {
1007
            /*
1008
             * We are using a ascending stack.
1009
             * That means the PC is actually the register
1010
             * nearest to Rn currently.
1011
             */
1012
            if (inst.lsm.P_bit == 1)
1013
                /*
1014
                 * Using a pre-decrement.
1015
                 */
1016
                offset_to_pc = -bsp_regsize(REG_PC);
1017
            else
1018
                offset_to_pc = 0;
1019
        } else {
1020
            /*
1021
             * We are using an descending stack.
1022
             * That means the PC is actually the register
1023
             * farthest from Rn currently.
1024
             *
1025
             * Find the number of registers stored before the PC
1026
             */
1027
            for (i = 0; i < REG_PC; i++)
1028
            {
1029
                if ((inst.lsm.Reg_List & (0x1 << i)) != 0)
1030
                {
1031
                    /*
1032
                     * Bit #i is set.  Increment our count.
1033
                     */
1034
                    offset_to_pc += bsp_regsize(i);
1035
                }
1036
            }
1037
 
1038
            /*
1039
             * Adjust the offset if we do a decrement/increment __BEFORE__
1040
             * the write.
1041
             */
1042
            if (inst.lsm.P_bit == 1)
1043
                offset_to_pc += bsp_regsize(REG_PC);
1044
        }
1045
 
1046
        /*
1047
         * Now let's calculate the real address of the stored PC
1048
         * making sure to mask out the two LO bits.
1049
         */
1050
        dest = (unsigned long **)((Rn_val + offset_to_pc) & ~0x3);
1051
 
1052
#if DEBUG_SINGLESTEP_VERBOSE
1053
        bsp_printf("Rn_val = 0x%08lx\n", Rn_val);
1054
        bsp_printf("offset_to_pc = 0x%08lx\n", offset_to_pc);
1055
        bsp_printf("dest = 0x%08lx\n", dest);
1056
        bsp_printf("*dest = 0x%08lx\n", *dest);
1057
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1058
 
1059
        insert_ss_break(*dest);
1060
    }
1061
}
1062
 
1063
 
1064
/*
1065
 * Decode all coprocessor data processing instructions
1066
 */
1067
static void decode_cpdp_inst(ex_regs_t *regs, union arm_insn inst)
1068
{
1069
    /*
1070
     * Can't possibly predict what this instruction will do.
1071
     * Don't do anything here.  Just return.
1072
     */
1073
}
1074
 
1075
 
1076
/*
1077
 * Decode all coprocessor register transfer instructions
1078
 */
1079
static void decode_cprt_inst(ex_regs_t *regs, union arm_insn inst)
1080
{
1081
    /*
1082
     * Can't possibly predict what this instruction will do.
1083
     * Don't do anything here.  Just return.
1084
     */
1085
}
1086
 
1087
 
1088
/*
1089
 * Decode all coprocessor load/store instructions
1090
 */
1091
static void decode_cpls_inst(ex_regs_t *regs, union arm_insn inst)
1092
{
1093
    /*
1094
     * Can't possibly predict what this instruction will do.
1095
     * Don't do anything here.  Just return.
1096
     */
1097
}
1098
 
1099
 
1100
/*
1101
 * Decode all branch/branch w/ link instructions
1102
 */
1103
static void decode_bbl_inst(ex_regs_t *regs, union arm_insn inst)
1104
{
1105
    unsigned long disp = inst.bbl.offset;
1106
 
1107
    /*
1108
     * Sign extend the 24 bit value
1109
     */
1110
    if (disp & 0x00800000)
1111
        disp |= 0xff000000;
1112
 
1113
    /*
1114
     * Convert to long words
1115
     */
1116
    disp <<= 2;
1117
 
1118
    /*
1119
     * Note: when the processor actually executes this instruction, the pc
1120
     *       will point to the address of the current instruction + 8 because
1121
     *       of the fetch/decode/execute cycle
1122
     */
1123
    disp += 8;
1124
 
1125
    insert_ss_break((unsigned long *)(regs->_pc + disp));
1126
}
1127
 
1128
 
1129
/*
1130
 * Decode all swi instructions
1131
 */
1132
static void decode_swi_inst(ex_regs_t *regs, union arm_insn inst)
1133
{
1134
    /*
1135
     * Can't possibly predict where we should set the breakpoint for this.
1136
     * Don't do anything here.  Just return.
1137
     */
1138
}
1139
 
1140
 
1141
/*
1142
 * Decode all undefined instructions
1143
 */
1144
static void decode_undef_inst(ex_regs_t *regs, union arm_insn inst)
1145
{
1146
    /*
1147
     * Can't possibly predict what this instruction will do.
1148
     * Don't do anything here.  Just return.
1149
     */
1150
}
1151
 
1152
 
1153
/*
1154
 * Set breakpoint instructions for single stepping.
1155
 */
1156
void
1157
bsp_singlestep_setup(void *registers)
1158
{
1159
    ex_regs_t *regs = (ex_regs_t *)registers;
1160
    union arm_insn inst;
1161
 
1162
    if (bsp_memory_read((void*)(regs->_pc), 0, ARM_INST_SIZE * 8, 1, &(inst.word)) == 0)
1163
    {
1164
        /*
1165
         * Unable to read the instruction at the current address.
1166
         * Let's not do anything with this.  We can't set breakpoints
1167
         * so let's get out now.
1168
         */
1169
        return;
1170
    }
1171
 
1172
    /*
1173
     * Handle the simple case -- linear code
1174
     */
1175
    insert_ss_break((unsigned long *)(regs->_pc + ARM_INST_SIZE));
1176
 
1177
    /*
1178
     * Now, we need to decode the instructions and figure out what
1179
     * they would do.
1180
     */
1181
    if ((inst.mrs.rsv1 == MRS_RSV1_VALUE) &&
1182
        (inst.mrs.rsv2 == MRS_RSV2_VALUE)) {
1183
#if DEBUG_SINGLESTEP_VERBOSE
1184
        bsp_printf("MRS type: 0x%08lx\n", inst.word);
1185
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1186
        decode_mrs_inst(regs, inst);
1187
    } else if ((inst.misr.rsv1 == MISR_RSV1_VALUE) &&
1188
               (inst.misr.rsv2 == MISR_RSV2_VALUE)) {
1189
#if DEBUG_SINGLESTEP_VERBOSE
1190
        bsp_printf("MISR type: 0x%08lx\n", inst.word);
1191
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1192
        decode_misr_inst(regs, inst);
1193
    } else if ((inst.mrsr.rsv1 == MRSR_RSV1_VALUE) &&
1194
               (inst.mrsr.rsv2 == MRSR_RSV2_VALUE) &&
1195
               (inst.mrsr.rsv3 == MRSR_RSV3_VALUE)) {
1196
#if DEBUG_SINGLESTEP_VERBOSE
1197
        bsp_printf("MRSR type: 0x%08lx\n", inst.word);
1198
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1199
        decode_mrsr_inst(regs, inst);
1200
    } else if (inst.dpi.rsv1 == DPI_RSV1_VALUE) {
1201
#if DEBUG_SINGLESTEP_VERBOSE
1202
        bsp_printf("DPI type: 0x%08lx\n", inst.word);
1203
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1204
        decode_dpi_inst(regs, inst);
1205
    } else if ((inst.bx.rsv1 == BX_RSV1_VALUE) &&
1206
               (inst.bx.rsv2 == BX_RSV2_VALUE)) {
1207
#if DEBUG_SINGLESTEP_VERBOSE
1208
        bsp_printf("BX type: 0x%08lx\n", inst.word);
1209
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1210
        decode_bx_inst(regs, inst);
1211
    } else if ((inst.dpis.rsv1 == DPIS_RSV1_VALUE) &&
1212
               (inst.dpis.rsv2 == DPIS_RSV2_VALUE)) {
1213
#if DEBUG_SINGLESTEP_VERBOSE
1214
        bsp_printf("DPIS type: 0x%08lx\n", inst.word);
1215
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1216
        decode_dpis_inst(regs, inst);
1217
    } else if ((inst.dprs.rsv1 == DPRS_RSV1_VALUE) &&
1218
               (inst.dprs.rsv2 == DPRS_RSV2_VALUE) &&
1219
               (inst.dprs.rsv3 == DPRS_RSV3_VALUE)) {
1220
#if DEBUG_SINGLESTEP_VERBOSE
1221
        bsp_printf("DPRS type: 0x%08lx\n", inst.word);
1222
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1223
        decode_dprs_inst(regs, inst);
1224
    } else if ((inst.m.rsv1 == M_RSV1_VALUE) &&
1225
               (inst.m.rsv2 == M_RSV2_VALUE)) {
1226
#if DEBUG_SINGLESTEP_VERBOSE
1227
        bsp_printf("M type: 0x%08lx\n", inst.word);
1228
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1229
        decode_m_inst(regs, inst);
1230
    } else if ((inst.ml.rsv1 == ML_RSV1_VALUE) &&
1231
               (inst.ml.rsv2 == ML_RSV2_VALUE)) {
1232
#if DEBUG_SINGLESTEP_VERBOSE
1233
        bsp_printf("ML type: 0x%08lx\n", inst.word);
1234
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1235
        decode_ml_inst(regs, inst);
1236
    } else if (inst.lsio.rsv1 == LSIO_RSV1_VALUE) {
1237
#if DEBUG_SINGLESTEP_VERBOSE
1238
        bsp_printf("LSIO type: 0x%08lx\n", inst.word);
1239
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1240
        decode_lsio_inst(regs, inst);
1241
    } else if ((inst.lsro.rsv1 == LSRO_RSV1_VALUE) &&
1242
               (inst.lsro.rsv2 == LSRO_RSV2_VALUE)) {
1243
#if DEBUG_SINGLESTEP_VERBOSE
1244
        bsp_printf("LSRO type: 0x%08lx\n", inst.word);
1245
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1246
        decode_lsro_inst(regs, inst);
1247
    } else if ((inst.lshwi.rsv1 == LSHWI_RSV1_VALUE) &&
1248
               (inst.lshwi.rsv2 == LSHWI_RSV2_VALUE) &&
1249
               (inst.lshwi.rsv3 == LSHWI_RSV3_VALUE) &&
1250
               (inst.lshwi.rsv4 == LSHWI_RSV4_VALUE)) {
1251
#if DEBUG_SINGLESTEP_VERBOSE
1252
        bsp_printf("LSHWI type: 0x%08lx\n", inst.word);
1253
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1254
        decode_lshwi_inst(regs, inst);
1255
    } else if ((inst.lshwr.rsv1 == LSHWR_RSV1_VALUE) &&
1256
               (inst.lshwr.rsv2 == LSHWR_RSV2_VALUE) &&
1257
               (inst.lshwr.rsv3 == LSHWR_RSV3_VALUE) &&
1258
               (inst.lshwr.rsv4 == LSHWR_RSV4_VALUE)) {
1259
#if DEBUG_SINGLESTEP_VERBOSE
1260
        bsp_printf("LSHWR type: 0x%08lx\n", inst.word);
1261
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1262
        decode_lshwr_inst(regs, inst);
1263
    } else if ((inst.swap.rsv1 == SWAP_RSV1_VALUE) &&
1264
               (inst.swap.rsv2 == SWAP_RSV2_VALUE) &&
1265
               (inst.swap.rsv3 == SWAP_RSV3_VALUE)) {
1266
#if DEBUG_SINGLESTEP_VERBOSE
1267
        bsp_printf("SWAP type: 0x%08lx\n", inst.word);
1268
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1269
        decode_swap_inst(regs, inst);
1270
    } else if (inst.lsm.rsv1 == LSM_RSV1_VALUE) {
1271
#if DEBUG_SINGLESTEP_VERBOSE
1272
        bsp_printf("LSM type: 0x%08lx\n", inst.word);
1273
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1274
        decode_lsm_inst(regs, inst);
1275
    } else if ((inst.cpdp.rsv1 == CPDP_RSV1_VALUE) &&
1276
               (inst.cpdp.rsv2 == CPDP_RSV2_VALUE)) {
1277
#if DEBUG_SINGLESTEP_VERBOSE
1278
        bsp_printf("CPDP type: 0x%08lx\n", inst.word);
1279
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1280
        decode_cpdp_inst(regs, inst);
1281
    } else if ((inst.cprt.rsv1 == CPRT_RSV1_VALUE) &&
1282
               (inst.cprt.rsv2 == CPRT_RSV2_VALUE)) {
1283
#if DEBUG_SINGLESTEP_VERBOSE
1284
        bsp_printf("CPRT type: 0x%08lx\n", inst.word);
1285
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1286
        decode_cprt_inst(regs, inst);
1287
    } else if (inst.cpls.rsv1 == CPLS_RSV1_VALUE) {
1288
#if DEBUG_SINGLESTEP_VERBOSE
1289
        bsp_printf("CPLS type: 0x%08lx\n", inst.word);
1290
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1291
        decode_cpls_inst(regs, inst);
1292
    } else if (inst.bbl.rsv1 == BBL_RSV1_VALUE) {
1293
#if DEBUG_SINGLESTEP_VERBOSE
1294
        bsp_printf("BBL type: 0x%08lx\n", inst.word);
1295
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1296
        decode_bbl_inst(regs, inst);
1297
    } else if (inst.swi.rsv1 == SWI_RSV1_VALUE) {
1298
#if DEBUG_SINGLESTEP_VERBOSE
1299
        bsp_printf("SWI type: 0x%08lx\n", inst.word);
1300
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1301
        decode_swi_inst(regs, inst);
1302
    } else if ((inst.undef.rsv1 == UNDEF_RSV1_VALUE) &&
1303
               (inst.undef.rsv2 == UNDEF_RSV2_VALUE)) {
1304
#if DEBUG_SINGLESTEP_VERBOSE
1305
        bsp_printf("UNDEF type: 0x%08lx\n", inst.word);
1306
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1307
        decode_undef_inst(regs, inst);
1308
    } else {
1309
#if DEBUG_SINGLESTEP_VERBOSE
1310
        bsp_printf("Unknown instruction type: 0x%08lx\n", inst.word);
1311
#endif /* DEBUG_SINGLESTEP_VERBOSE */
1312
    }
1313
}
1314
 
1315
void
1316
bsp_skip_instruction(void *registers)
1317
{
1318
    ex_regs_t *regs = (ex_regs_t *)registers;
1319
    regs->_pc += ARM_INST_SIZE;
1320
}

powered by: WebSVN 2.1.0

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