annotate packages/hal/arm/arch/current/src/arm_stub.c @ 132:0ae0bc38e387 ecos-sw-2000-10-31

Merge from eCos master repository on 2000-10-31-00:30:36-GMT
author jlarmour
date Tue, 31 Oct 2000 20:53:09 +0000
parents 6ed91473a1cd
children a9ac27ec7abc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
64
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
1 //========================================================================
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
2 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
3 // arm_stub.c
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
4 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
5 // Helper functions for stub, generic to all ARM processors
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
6 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
7 //========================================================================
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
8 //####COPYRIGHTBEGIN####
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
9 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
10 // -------------------------------------------
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
11 // The contents of this file are subject to the Red Hat eCos Public License
66
bf00f99aec69 Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents: 64
diff changeset
12 // Version 1.1 (the "License"); you may not use this file except in
64
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
13 // compliance with the License. You may obtain a copy of the License at
66
bf00f99aec69 Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents: 64
diff changeset
14 // http://www.redhat.com/
64
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
15 //
66
bf00f99aec69 Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents: 64
diff changeset
16 // Software distributed under the License is distributed on an "AS IS"
64
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
18 // License for the specific language governing rights and limitations under
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
19 // the License.
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
20 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
21 // The Original Code is eCos - Embedded Configurable Operating System,
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
22 // released September 30, 1998.
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
23 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
24 // The Initial Developer of the Original Code is Red Hat.
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
25 // Portions created by Red Hat are
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
26 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
27 // All Rights Reserved.
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
28 // -------------------------------------------
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
29 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
30 //####COPYRIGHTEND####
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
31 //========================================================================
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
32 //#####DESCRIPTIONBEGIN####
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
33 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
34 // Author(s): Red Hat, gthomas
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
35 // Contributors: Red Hat, gthomas, jskov
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
36 // Date: 1998-11-26
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
37 // Purpose:
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
38 // Description: Helper functions for stub, generic to all ARM processors
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
39 // Usage:
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
40 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
41 //####DESCRIPTIONEND####
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
42 //
c38311975d4f Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents: 54
diff changeset
43 //========================================================================
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
44
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
45 #include <stddef.h>
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
46
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
47 #include <pkgconf/hal.h>
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
48
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
49 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
50
72
da3908c9cd10 Merge from eCos master repository on 2000-02-17-18:56:14-GMT
jlarmour
parents: 66
diff changeset
51 #ifdef CYGPKG_HAL_ARM_SIM
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
52 #error "GDB Stub support not implemented for ARM SIM"
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
53 #endif
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
54
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
55 #include <cyg/hal/hal_stub.h>
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
56 #include <cyg/hal/hal_arch.h>
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
57 #include <cyg/hal/hal_intr.h>
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
58
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
59 #ifndef FALSE
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
60 #define FALSE 0
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
61 #define TRUE 1
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
62 #endif
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
63
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
64 // Use bit 0 as a thumb-mode flag for next address to be executed.
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
65 // Alternative would be to keep track of it using a C variable, but
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
66 // since bit 0 is used by the BX instruction, we might as well do the
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
67 // same thing and thus avoid checking two different flags.
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
68 #define IS_THUMB_ADDR(addr) ((addr) & 1)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
69 #define MAKE_THUMB_ADDR(addr) ((addr) | 1)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
70 #define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
36
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
71
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
72 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
73 #include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
74 #endif
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
75
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
76 /* Given a trap value TRAP, return the corresponding signal. */
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
77
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
78 int __computeSignal (unsigned int trap_number)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
79 {
132
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
80 // Check to see if we stopped because of a hw watchpoint/breakpoint.
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
81 #ifdef HAL_STUB_IS_STOPPED_BY_HARDWARE
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
82 if (HAL_STUB_IS_STOPPED_BY_HARDWARE(trap_number))
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
83 return SIGTRAP;
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
84 #endif
36
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
85 // should also catch CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION here but we
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
86 // can't tell the different between a real one and a breakpoint :-(
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
87 switch (trap_number) {
36
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
88 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH: // Fall through
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
89 case CYGNUM_HAL_VECTOR_ABORT_DATA: // Fall through
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
90 case CYGNUM_HAL_VECTOR_reserved:
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
91 return SIGBUS;
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
92 case CYGNUM_HAL_VECTOR_IRQ:
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
93 case CYGNUM_HAL_VECTOR_FIQ:
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
94 return SIGINT;
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
95 default:
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
96 return SIGTRAP;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
97 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
98 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
99
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
100
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
101 /* Return the trap number corresponding to the last-taken trap. */
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
102 int __get_trap_number (void)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
103 {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
104 // The vector is not not part of the GDB register set so get it
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
105 // directly from the save context.
36
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
106 return _hal_registers->vector;
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
107 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
108
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
109 /* Set the currently-saved pc register value to PC. */
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
110
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
111 void set_pc (target_register_t pc)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
112 {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
113 put_register (PC, pc);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
114 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
115
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
116
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
117 /*----------------------------------------------------------------------
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
118 * Single-step support
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
119 */
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
120
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
121 /* Set things up so that the next user resume will execute one instruction.
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
122 This may be done by setting breakpoints or setting a single step flag
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
123 in the saved user registers, for example. */
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
124
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
125 static unsigned long ss_saved_pc = 0;
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
126 static unsigned long ss_saved_instr;
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
127 static unsigned short ss_saved_thumb_instr;
36
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
128
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
129 #define FIXME() {diag_printf("FIXME - %s\n", __FUNCTION__); }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
130
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
131 static int
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
132 ins_will_execute(unsigned long ins)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
133 {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
134 unsigned long psr = get_register(PS); // condition codes
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
135 int res = 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
136 switch ((ins & 0xF0000000) >> 28) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
137 case 0x0: // EQ
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
138 res = (psr & PS_Z) != 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
139 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
140 case 0x1: // NE
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
141 res = (psr & PS_Z) == 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
142 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
143 case 0x2: // CS
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
144 res = (psr & PS_C) != 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
145 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
146 case 0x3: // CC
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
147 res = (psr & PS_C) == 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
148 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
149 case 0x4: // MI
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
150 res = (psr & PS_N) != 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
151 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
152 case 0x5: // PL
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
153 res = (psr & PS_N) == 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
154 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
155 case 0x6: // VS
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
156 res = (psr & PS_V) != 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
157 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
158 case 0x7: // VC
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
159 res = (psr & PS_V) == 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
160 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
161 case 0x8: // HI
34
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
162 res = ((psr & PS_C) != 0) && ((psr & PS_Z) == 0);
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
163 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
164 case 0x9: // LS
34
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
165 res = ((psr & PS_C) == 0) || ((psr & PS_Z) != 0);
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
166 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
167 case 0xA: // GE
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
168 res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) ||
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
169 ((psr & (PS_N|PS_V)) == 0);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
170 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
171 case 0xB: // LT
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
172 res = ((psr & (PS_N|PS_V)) == PS_N) ||
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
173 ((psr & (PS_N|PS_V)) == PS_V);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
174 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
175 case 0xC: // GT
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
176 res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) ||
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
177 ((psr & (PS_N|PS_V)) == 0);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
178 res = ((psr & PS_Z) == 0) && res;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
179 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
180 case 0xD: // LE
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
181 res = ((psr & (PS_N|PS_V)) == PS_N) ||
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
182 ((psr & (PS_N|PS_V)) == PS_V);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
183 res = ((psr & PS_Z) == PS_Z) || res;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
184 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
185 case 0xE: // AL
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
186 res = TRUE;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
187 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
188 case 0xF: // NV
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
189 res = FALSE;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
190 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
191 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
192 return res;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
193 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
194
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
195 static unsigned long
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
196 RmShifted(int shift)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
197 {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
198 unsigned long Rm = get_register(shift & 0x00F);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
199 int shift_count;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
200 if ((shift & 0x010) == 0) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
201 shift_count = (shift & 0xF80) >> 7;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
202 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
203 shift_count = get_register((shift & 0xF00) >> 8);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
204 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
205 switch ((shift & 0x060) >> 5) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
206 case 0x0: // Logical left
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
207 Rm <<= shift_count;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
208 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
209 case 0x1: // Logical right
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
210 Rm >>= shift_count;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
211 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
212 case 0x2: // Arithmetic right
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
213 Rm = (unsigned long)((long)Rm >> shift_count);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
214 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
215 case 0x3: // Rotate right
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
216 if (shift_count == 0) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
217 // Special case, RORx
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
218 Rm >>= 1;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
219 if (get_register(PS) & PS_C) Rm |= 0x80000000;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
220 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
221 Rm = (Rm >> shift_count) | (Rm << (32-shift_count));
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
222 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
223 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
224 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
225 return Rm;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
226 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
227
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
228 // Decide the next instruction to be executed for a given instruction
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
229 static unsigned long *
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
230 target_ins(unsigned long *pc, unsigned long ins)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
231 {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
232 unsigned long new_pc, offset, op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
233 unsigned long Rn;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
234 int i, reg_count, c;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
235 switch ((ins & 0x0C000000) >> 26) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
236 case 0x0:
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
237 // BX
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
238 if ((ins & 0x0FFFFFF0) == 0x012FFF10) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
239 new_pc = (unsigned long)get_register(ins & 0x0000000F);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
240 return ((unsigned long *)new_pc);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
241 }
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
242 // Data processing
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
243 new_pc = (unsigned long)(pc+1);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
244 if ((ins & 0x0000F000) == 0x0000F000) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
245 // Destination register is PC
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
246 if ((ins & 0x0FBF0000) != 0x010F0000) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
247 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
248 if ((ins & 0x02000000) == 0) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
249 op2 = RmShifted(ins & 0x00000FFF);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
250 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
251 op2 = ins & 0x000000FF;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
252 i = (ins & 0x00000F00) >> 8; // Rotate count
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
253 op2 = (op2 >> (i*2)) | (op2 << (32-(i*2)));
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
254 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
255 switch ((ins & 0x01E00000) >> 21) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
256 case 0x0: // AND
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
257 new_pc = Rn & op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
258 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
259 case 0x1: // EOR
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
260 new_pc = Rn ^ op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
261 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
262 case 0x2: // SUB
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
263 new_pc = Rn - op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
264 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
265 case 0x3: // RSB
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
266 new_pc = op2 - Rn;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
267 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
268 case 0x4: // ADD
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
269 new_pc = Rn + op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
270 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
271 case 0x5: // ADC
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
272 c = (get_register(PS) & PS_C) != 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
273 new_pc = Rn + op2 + c;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
274 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
275 case 0x6: // SBC
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
276 c = (get_register(PS) & PS_C) != 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
277 new_pc = Rn - op2 + c - 1;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
278 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
279 case 0x7: // RSC
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
280 c = (get_register(PS) & PS_C) != 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
281 new_pc = op2 - Rn +c - 1;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
282 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
283 case 0x8: // TST
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
284 case 0x9: // TEQ
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
285 case 0xA: // CMP
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
286 case 0xB: // CMN
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
287 break; // PC doesn't change
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
288 case 0xC: // ORR
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
289 new_pc = Rn | op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
290 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
291 case 0xD: // MOV
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
292 new_pc = op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
293 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
294 case 0xE: // BIC
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
295 new_pc = Rn & ~op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
296 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
297 case 0xF: // MVN
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
298 new_pc = ~op2;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
299 break;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
300 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
301 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
302 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
303 return ((unsigned long *)new_pc);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
304 case 0x1:
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
305 if ((ins & 0x02000010) == 0x02000010) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
306 // Undefined!
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
307 return (pc+1);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
308 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
309 if ((ins & 0x00100000) == 0) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
310 // STR
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
311 return (pc+1);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
312 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
313 // LDR
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
314 if ((ins & 0x0000F000) != 0x0000F000) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
315 // Rd not PC
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
316 return (pc+1);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
317 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
318 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
319 if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch!
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
320 if (ins & 0x01000000) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
321 // Add/subtract offset before
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
322 if ((ins & 0x02000000) == 0) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
323 // Immediate offset
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
324 if (ins & 0x00800000) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
325 // Add offset
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
326 Rn += (ins & 0x00000FFF);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
327 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
328 // Subtract offset
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
329 Rn -= (ins & 0x00000FFF);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
330 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
331 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
332 // Offset is in a register
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
333 if (ins & 0x00800000) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
334 // Add offset
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
335 Rn += RmShifted(ins & 0x00000FFF);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
336 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
337 // Subtract offset
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
338 Rn -= RmShifted(ins & 0x00000FFF);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
339 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
340 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
341 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
342 return ((unsigned long *)*(unsigned long *)Rn);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
343 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
344 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
345 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
346 return (pc+1);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
347 case 0x2: // Branch, LDM/STM
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
348 if ((ins & 0x02000000) == 0) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
349 // LDM/STM
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
350 if ((ins & 0x00100000) == 0) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
351 // STM
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
352 return (pc+1);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
353 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
354 // LDM
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
355 if ((ins & 0x00008000) == 0) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
356 // PC not in list
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
357 return (pc+1);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
358 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
359 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
360 if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch!
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
361 offset = ins & 0x0000FFFF;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
362 reg_count = 0;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
363 for (i = 0; i < 15; i++) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
364 if (offset & (1<<i)) reg_count++;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
365 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
366 if (ins & 0x00800000) {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
367 // Add offset
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
368 Rn += reg_count*4;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
369 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
370 // Subtract offset
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
371 Rn -= 4;
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
372 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
373 return ((unsigned long *)*(unsigned long *)Rn);
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
374 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
375 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
376 } else {
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
377 // Branch
34
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
378 if (ins_will_execute(ins)) {
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
379 offset = (ins & 0x00FFFFFF) << 2;
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
380 if (ins & 0x00800000) offset |= 0xFC000000; // sign extend
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
381 new_pc = (unsigned long)(pc+2) + offset;
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
382 return ((unsigned long *)new_pc);
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
383 } else {
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
384 // Falls through
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
385 return (pc+1);
29bc183297e1 Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents: 2
diff changeset
386 }
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
387 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
388 case 0x3: // Coprocessor & SWI
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
389 return (pc+1);
78
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
390 default:
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
391 // Never reached - but fixes compiler warning.
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
392 return 0;
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
393 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
394 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
395
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
396 // FIXME: target_ins also needs to check for CPSR/THUMB being set and
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
397 // set the thumb bit accordingly.
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
398
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
399 static unsigned long
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
400 target_thumb_ins(unsigned long pc, unsigned short ins)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
401 {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
402 unsigned long new_pc = MAKE_THUMB_ADDR(pc+2); // default is fall-through
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
403 // to next thumb instruction
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
404 unsigned long offset, arm_ins;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
405
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
406 switch ((ins & 0xf000) >> 12) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
407 case 0x4:
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
408 // Check for BX
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
409 if ((ins & 0xff87) == 0x4700)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
410 new_pc = (unsigned long)get_register((ins & 0x00078) >> 3);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
411 break;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
412 case 0xd:
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
413 // Bcc
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
414 // Use ARM function to check condition
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
415 arm_ins = ((unsigned long)(ins & 0x0f00)) << 20;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
416 if (ins_will_execute(arm_ins)) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
417 offset = (ins & 0x00FF) << 1;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
418 if (ins & 0x0080) offset |= 0xFFFFFE00; // sign extend
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
419 new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
420 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
421 break;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
422 case 0xe:
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
423 // check for B
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
424 if ((ins & 0x0800) == 0) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
425 offset = (ins & 0x07FF) << 1;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
426 if (ins & 0x0400) offset |= 0xFFFFF800; // sign extend
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
427 new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
428 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
429 break;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
430 case 0xf:
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
431 // BL (4byte instruction!)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
432 // First instruction (bit 11 == 0) holds top-part of offset
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
433 offset = (ins & 0x07FF) << 12;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
434 if (ins & 0x0400) offset |= 0xFF800000; // sign extend
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
435 // Get second instruction
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
436 // Second instruction (bit 11 == 1) holds bottom-part of offset
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
437 ins = *(unsigned short*)(pc+2);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
438 offset |= (ins & 0x07ff) << 1;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
439 new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
440 break;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
441 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
442
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
443 return new_pc;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
444 }
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
445
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
446 void __single_step (void)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
447 {
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
448 unsigned long pc = get_register(PC);
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
449 unsigned long cpsr = get_register(PS);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
450
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
451 // Calculate address of next instruction to be executed
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
452 if (cpsr & CPSR_THUMB_ENABLE) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
453 // thumb
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
454 ss_saved_pc = target_thumb_ins(pc, *(unsigned short*)pc);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
455 } else {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
456 // ARM
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
457 unsigned long curins = *(unsigned long*)pc;
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
458 if (ins_will_execute(curins)) {
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
459 // Decode instruction to decide what the next PC will be
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
460 ss_saved_pc = (unsigned long) target_ins((unsigned long*)pc,
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
461 curins);
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
462 } else {
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
463 // The current instruction will not execute (the conditions
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
464 // don't hold)
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
465 ss_saved_pc = pc+4;
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
466 }
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
467 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
468
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
469 // Set breakpoint according to type
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
470 if (IS_THUMB_ADDR(ss_saved_pc)) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
471 // Thumb instruction
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
472 unsigned long t_pc = UNMAKE_THUMB_ADDR(ss_saved_pc);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
473 ss_saved_thumb_instr = *(unsigned short*)t_pc;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
474 *(unsigned short*)t_pc = HAL_BREAKINST_THUMB;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
475 } else {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
476 // ARM instruction
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
477 ss_saved_instr = *(unsigned long*)ss_saved_pc;
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
478 *(unsigned long*)ss_saved_pc = HAL_BREAKINST_ARM;
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
479 }
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
480 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
481
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
482 /* Clear the single-step state. */
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
483
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
484 void __clear_single_step (void)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
485 {
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
486 if (ss_saved_pc != 0) {
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
487 // Restore instruction according to type
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
488 if (IS_THUMB_ADDR(ss_saved_pc)) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
489 // Thumb instruction
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
490 unsigned long t_pc = UNMAKE_THUMB_ADDR(ss_saved_pc);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
491 *(unsigned short*)t_pc = ss_saved_thumb_instr;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
492 } else {
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
493 // ARM instruction
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
494 *(unsigned long*)ss_saved_pc = ss_saved_instr;
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
495 }
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
496 ss_saved_pc = 0;
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
497 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
498 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
499
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
500 void __install_breakpoints (void)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
501 {
132
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
502 #if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
503 /* Install the breakpoints in the breakpoint list */
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
504 __install_breakpoint_list();
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
505 #endif
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
506 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
507
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
508 void __clear_breakpoints (void)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
509 {
132
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
510 #if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
511 __clear_breakpoint_list();
0ae0bc38e387 Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents: 115
diff changeset
512 #endif
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
513 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
514
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
515 /* If the breakpoint we hit is in the breakpoint() instruction, return a
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
516 non-zero value. */
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
517
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
518 int
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
519 __is_breakpoint_function ()
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
520 {
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents: 110
diff changeset
521 return get_register (PC) == (target_register_t)&_breakinst;
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
522 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
523
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
524
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
525 /* Skip the current instruction. Since this is only called by the
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
526 stub when the PC points to a breakpoint or trap instruction,
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
527 we can safely just skip 4. */
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
528
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
529 void __skipinst (void)
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
530 {
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
531 unsigned long pc = get_register(PC);
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
532 unsigned long cpsr = get_register(PS);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
533
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
534 if (cpsr & CPSR_THUMB_ENABLE)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
535 pc += 2;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
536 else
54
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
537 pc += 4;
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
538
f10165814f1e Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents: 50
diff changeset
539 put_register(PC, pc);
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
540 }
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
541
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
542 //-----------------------------------------------------------------------
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
543 // Thumb-aware GDB interrupt handler.
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
544 // This is a brute-force replacement of the ones in hal_stub.c. Need to
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
545 // find a better way of handling it... Maybe... Probably only ARM/thumb
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
546 // that is this weird.
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
547
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
548 typedef struct
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
549 {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
550 cyg_uint32 targetAddr;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
551 union {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
552 cyg_uint32 arm_instr;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
553 cyg_uint16 thumb_instr;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
554 } savedInstr;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
555 } instrBuffer;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
556
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
557 static instrBuffer break_buffer;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
558
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
559 volatile int cyg_hal_gdb_running_step = 0;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
560
78
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
561 // This function is passed thumb/arm information about the PC address
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
562 // in bit 0. This information is passed on to the break_buffer.
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
563 void
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
564 cyg_hal_gdb_place_break (target_register_t pc)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
565 {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
566 // Clear flag that we Continued instead of Stepping
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
567 cyg_hal_gdb_running_step = 0;
78
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
568
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
569 if (0 == break_buffer.targetAddr) {
78
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
570 // Setting a breakpoint in Thumb or ARM code?
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
571 if (IS_THUMB_ADDR(pc)) {
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
572 break_buffer.targetAddr = (cyg_uint32)pc;
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
573 pc = UNMAKE_THUMB_ADDR(pc);
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
574 break_buffer.savedInstr.thumb_instr = *(cyg_uint16*)pc;
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
575 *(cyg_uint16*)pc = HAL_BREAKINST_THUMB;
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
576 } else {
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
577 break_buffer.targetAddr = (cyg_uint32)pc;
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
578 break_buffer.savedInstr.arm_instr = *(cyg_uint32*)pc;
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
579 *(cyg_uint32*)pc = HAL_BREAKINST_ARM;
59d97b6ba612 Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents: 76
diff changeset
580 }
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
581
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
582 __data_cache(CACHE_FLUSH);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
583 __instruction_cache(CACHE_FLUSH);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
584 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
585 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
586
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
587 int
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
588 cyg_hal_gdb_remove_break (target_register_t pc)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
589 {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
590 if ( cyg_hal_gdb_running_step )
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
591 return 0; // Do not remove the break: we must hit it!
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
592
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
593 if (pc == UNMAKE_THUMB_ADDR(break_buffer.targetAddr)) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
594 if (IS_THUMB_ADDR(break_buffer.targetAddr)) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
595 *(cyg_uint16*)pc = break_buffer.savedInstr.thumb_instr;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
596 } else {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
597 *(cyg_uint32*)pc = break_buffer.savedInstr.arm_instr;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
598 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
599 break_buffer.targetAddr = 0;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
600
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
601 __data_cache(CACHE_FLUSH);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
602 __instruction_cache(CACHE_FLUSH);
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
603 return 1;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
604 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
605 return 0;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
606 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
607
105
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
608 void
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
609 cyg_hal_gdb_interrupt (target_register_t pc)
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
610 {
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
611 // Clear flag that we Continued instead of Stepping
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
612 cyg_hal_gdb_running_step = 0;
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
613 // and override existing break? So that a ^C takes effect...
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
614 if (0 != break_buffer.targetAddr)
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
615 cyg_hal_gdb_remove_break( break_buffer.targetAddr );
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
616
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
617 if (0 == break_buffer.targetAddr) {
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
618 cyg_uint32 cpsr = get_register(PS);
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
619
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
620 if (cpsr & CPSR_THUMB_ENABLE) {
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
621 break_buffer.targetAddr = MAKE_THUMB_ADDR((cyg_uint32)pc);
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
622 break_buffer.savedInstr.thumb_instr = *(cyg_uint16*)pc;
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
623 *(cyg_uint16*)pc = HAL_BREAKINST_THUMB;
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
624 } else {
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
625 break_buffer.targetAddr = (cyg_uint32)pc;
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
626 break_buffer.savedInstr.arm_instr = *(cyg_uint32*)pc;
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
627 *(cyg_uint32*)pc = HAL_BREAKINST_ARM;
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
628 }
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
629
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
630 __data_cache(CACHE_FLUSH);
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
631 __instruction_cache(CACHE_FLUSH);
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
632 }
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
633 }
5a0cc6c243a9 Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents: 80
diff changeset
634
76
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
635 int
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
636 cyg_hal_gdb_break_is_set (void)
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
637 {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
638 if (0 != break_buffer.targetAddr) {
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
639 return 1;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
640 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
641 return 0;
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
642 }
435cced73e2f eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents: 72
diff changeset
643
36
e97d78785e2d Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents: 34
diff changeset
644
2
443894e2e912 Block commit of eCos version 1.2.1
jlarmour
parents:
diff changeset
645 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS