Mercurial > flash_v2
annotate packages/hal/arm/arch/current/src/arm_stub.c @ 72:da3908c9cd10 ecos-sw-2000-02-17
Merge from eCos master repository on 2000-02-17-18:56:14-GMT
| author | jlarmour |
|---|---|
| date | Thu, 17 Feb 2000 19:38:13 +0000 |
| parents | bf00f99aec69 |
| children | 435cced73e2f |
| 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 | 44 |
| 45 #include <stddef.h> | |
| 46 | |
| 47 #include <pkgconf/hal.h> | |
|
50
a0774359f013
Merge from eCos master repository on 1999-11-02-17:02:15-GMT
jlarmour
parents:
46
diff
changeset
|
48 #ifdef CYGPKG_CYGMON |
|
a0774359f013
Merge from eCos master repository on 1999-11-02-17:02:15-GMT
jlarmour
parents:
46
diff
changeset
|
49 #include <pkgconf/cygmon.h> |
|
a0774359f013
Merge from eCos master repository on 1999-11-02-17:02:15-GMT
jlarmour
parents:
46
diff
changeset
|
50 #endif |
| 2 | 51 |
| 52 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS | |
| 53 | |
|
72
da3908c9cd10
Merge from eCos master repository on 2000-02-17-18:56:14-GMT
jlarmour
parents:
66
diff
changeset
|
54 #ifdef CYGPKG_HAL_ARM_SIM |
| 2 | 55 #error "GDB Stub support not implemented for ARM SIM" |
| 56 #endif | |
| 57 | |
| 58 #include <cyg/hal/hal_stub.h> | |
| 59 #include <cyg/hal/hal_arch.h> | |
| 60 #include <cyg/hal/hal_intr.h> | |
| 61 | |
| 62 #ifndef FALSE | |
| 63 #define FALSE 0 | |
| 64 #define TRUE 1 | |
| 65 #endif | |
| 66 | |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
67 |
| 2 | 68 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT |
| 69 #include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id | |
| 70 #endif | |
| 71 | |
| 72 /* Given a trap value TRAP, return the corresponding signal. */ | |
| 73 | |
| 74 int __computeSignal (unsigned int trap_number) | |
| 75 { | |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
76 // 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
|
77 // can't tell the different between a real one and a breakpoint :-( |
| 2 | 78 switch (trap_number) { |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
79 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
|
80 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
|
81 case CYGNUM_HAL_VECTOR_reserved: |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
82 return SIGBUS; |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
83 case CYGNUM_HAL_VECTOR_IRQ: |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
84 case CYGNUM_HAL_VECTOR_FIQ: |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
85 return SIGINT; |
| 2 | 86 default: |
| 87 return SIGTRAP; | |
| 88 } | |
| 89 } | |
| 90 | |
| 91 | |
| 92 /* Return the trap number corresponding to the last-taken trap. */ | |
| 93 int __get_trap_number (void) | |
| 94 { | |
| 95 // The vector is not not part of the GDB register set so get it | |
| 96 // 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
|
97 return _hal_registers->vector; |
| 2 | 98 } |
| 99 | |
| 100 /* Set the currently-saved pc register value to PC. This also updates NPC | |
| 101 as needed. */ | |
| 102 | |
| 103 void set_pc (target_register_t pc) | |
| 104 { | |
| 105 put_register (PC, pc); | |
| 106 } | |
| 107 | |
| 108 | |
| 109 /*---------------------------------------------------------------------- | |
| 110 * Single-step support | |
| 111 */ | |
| 112 | |
| 113 /* Set things up so that the next user resume will execute one instruction. | |
| 114 This may be done by setting breakpoints or setting a single step flag | |
| 115 in the saved user registers, for example. */ | |
| 116 | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
117 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
|
118 static unsigned long ss_saved_instr; |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
119 |
| 2 | 120 #define FIXME() {diag_printf("FIXME - %s\n", __FUNCTION__); } |
| 121 | |
| 122 static int | |
| 123 ins_will_execute(unsigned long ins) | |
| 124 { | |
| 125 unsigned long psr = get_register(PS); // condition codes | |
| 126 int res = 0; | |
| 127 switch ((ins & 0xF0000000) >> 28) { | |
| 128 case 0x0: // EQ | |
| 129 res = (psr & PS_Z) != 0; | |
| 130 break; | |
| 131 case 0x1: // NE | |
| 132 res = (psr & PS_Z) == 0; | |
| 133 break; | |
| 134 case 0x2: // CS | |
| 135 res = (psr & PS_C) != 0; | |
| 136 break; | |
| 137 case 0x3: // CC | |
| 138 res = (psr & PS_C) == 0; | |
| 139 break; | |
| 140 case 0x4: // MI | |
| 141 res = (psr & PS_N) != 0; | |
| 142 break; | |
| 143 case 0x5: // PL | |
| 144 res = (psr & PS_N) == 0; | |
| 145 break; | |
| 146 case 0x6: // VS | |
| 147 res = (psr & PS_V) != 0; | |
| 148 break; | |
| 149 case 0x7: // VC | |
| 150 res = (psr & PS_V) == 0; | |
| 151 break; | |
| 152 case 0x8: // HI | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
153 res = ((psr & PS_C) != 0) && ((psr & PS_Z) == 0); |
| 2 | 154 break; |
| 155 case 0x9: // LS | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
156 res = ((psr & PS_C) == 0) || ((psr & PS_Z) != 0); |
| 2 | 157 break; |
| 158 case 0xA: // GE | |
| 159 res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) || | |
| 160 ((psr & (PS_N|PS_V)) == 0); | |
| 161 break; | |
| 162 case 0xB: // LT | |
| 163 res = ((psr & (PS_N|PS_V)) == PS_N) || | |
| 164 ((psr & (PS_N|PS_V)) == PS_V); | |
| 165 break; | |
| 166 case 0xC: // GT | |
| 167 res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) || | |
| 168 ((psr & (PS_N|PS_V)) == 0); | |
| 169 res = ((psr & PS_Z) == 0) && res; | |
| 170 break; | |
| 171 case 0xD: // LE | |
| 172 res = ((psr & (PS_N|PS_V)) == PS_N) || | |
| 173 ((psr & (PS_N|PS_V)) == PS_V); | |
| 174 res = ((psr & PS_Z) == PS_Z) || res; | |
| 175 break; | |
| 176 case 0xE: // AL | |
| 177 res = TRUE; | |
| 178 break; | |
| 179 case 0xF: // NV | |
| 180 res = FALSE; | |
| 181 break; | |
| 182 } | |
| 183 return res; | |
| 184 } | |
| 185 | |
| 186 static unsigned long | |
| 187 RmShifted(int shift) | |
| 188 { | |
| 189 unsigned long Rm = get_register(shift & 0x00F); | |
| 190 int shift_count; | |
| 191 if ((shift & 0x010) == 0) { | |
| 192 shift_count = (shift & 0xF80) >> 7; | |
| 193 } else { | |
| 194 shift_count = get_register((shift & 0xF00) >> 8); | |
| 195 } | |
| 196 switch ((shift & 0x060) >> 5) { | |
| 197 case 0x0: // Logical left | |
| 198 Rm <<= shift_count; | |
| 199 break; | |
| 200 case 0x1: // Logical right | |
| 201 Rm >>= shift_count; | |
| 202 break; | |
| 203 case 0x2: // Arithmetic right | |
| 204 Rm = (unsigned long)((long)Rm >> shift_count); | |
| 205 break; | |
| 206 case 0x3: // Rotate right | |
| 207 if (shift_count == 0) { | |
| 208 // Special case, RORx | |
| 209 Rm >>= 1; | |
| 210 if (get_register(PS) & PS_C) Rm |= 0x80000000; | |
| 211 } else { | |
| 212 Rm = (Rm >> shift_count) | (Rm << (32-shift_count)); | |
| 213 } | |
| 214 break; | |
| 215 } | |
| 216 return Rm; | |
| 217 } | |
| 218 | |
| 219 // Decide the next instruction to be executed for a given instruction | |
| 220 static unsigned long * | |
| 221 target_ins(unsigned long *pc, unsigned long ins) | |
| 222 { | |
| 223 unsigned long new_pc, offset, op2; | |
| 224 unsigned long Rn; | |
| 225 int i, reg_count, c; | |
| 226 switch ((ins & 0x0C000000) >> 26) { | |
| 227 case 0x0: | |
| 228 // Data processing | |
| 229 new_pc = (unsigned long)(pc+1); | |
| 230 if ((ins & 0x0000F000) == 0x0000F000) { | |
| 231 // Destination register is PC | |
| 232 if ((ins & 0x0FBF0000) != 0x010F0000) { | |
| 233 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); | |
| 234 if ((ins & 0x02000000) == 0) { | |
| 235 op2 = RmShifted(ins & 0x00000FFF); | |
| 236 } else { | |
| 237 op2 = ins & 0x000000FF; | |
| 238 i = (ins & 0x00000F00) >> 8; // Rotate count | |
| 239 op2 = (op2 >> (i*2)) | (op2 << (32-(i*2))); | |
| 240 } | |
| 241 switch ((ins & 0x01E00000) >> 21) { | |
| 242 case 0x0: // AND | |
| 243 new_pc = Rn & op2; | |
| 244 break; | |
| 245 case 0x1: // EOR | |
| 246 new_pc = Rn ^ op2; | |
| 247 break; | |
| 248 case 0x2: // SUB | |
| 249 new_pc = Rn - op2; | |
| 250 break; | |
| 251 case 0x3: // RSB | |
| 252 new_pc = op2 - Rn; | |
| 253 break; | |
| 254 case 0x4: // ADD | |
| 255 new_pc = Rn + op2; | |
| 256 break; | |
| 257 case 0x5: // ADC | |
| 258 c = (get_register(PS) & PS_C) != 0; | |
| 259 new_pc = Rn + op2 + c; | |
| 260 break; | |
| 261 case 0x6: // SBC | |
| 262 c = (get_register(PS) & PS_C) != 0; | |
| 263 new_pc = Rn - op2 + c - 1; | |
| 264 break; | |
| 265 case 0x7: // RSC | |
| 266 c = (get_register(PS) & PS_C) != 0; | |
| 267 new_pc = op2 - Rn +c - 1; | |
| 268 break; | |
| 269 case 0x8: // TST | |
| 270 case 0x9: // TEQ | |
| 271 case 0xA: // CMP | |
| 272 case 0xB: // CMN | |
| 273 break; // PC doesn't change | |
| 274 case 0xC: // ORR | |
| 275 new_pc = Rn | op2; | |
| 276 break; | |
| 277 case 0xD: // MOV | |
| 278 new_pc = op2; | |
| 279 break; | |
| 280 case 0xE: // BIC | |
| 281 new_pc = Rn & ~op2; | |
| 282 break; | |
| 283 case 0xF: // MVN | |
| 284 new_pc = ~op2; | |
| 285 break; | |
| 286 } | |
| 287 } | |
| 288 } | |
| 289 return ((unsigned long *)new_pc); | |
| 290 case 0x1: | |
| 291 if ((ins & 0x02000010) == 0x02000010) { | |
| 292 // Undefined! | |
| 293 return (pc+1); | |
| 294 } else { | |
| 295 if ((ins & 0x00100000) == 0) { | |
| 296 // STR | |
| 297 return (pc+1); | |
| 298 } else { | |
| 299 // LDR | |
| 300 if ((ins & 0x0000F000) != 0x0000F000) { | |
| 301 // Rd not PC | |
| 302 return (pc+1); | |
| 303 } else { | |
| 304 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); | |
| 305 if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch! | |
| 306 if (ins & 0x01000000) { | |
| 307 // Add/subtract offset before | |
| 308 if ((ins & 0x02000000) == 0) { | |
| 309 // Immediate offset | |
| 310 if (ins & 0x00800000) { | |
| 311 // Add offset | |
| 312 Rn += (ins & 0x00000FFF); | |
| 313 } else { | |
| 314 // Subtract offset | |
| 315 Rn -= (ins & 0x00000FFF); | |
| 316 } | |
| 317 } else { | |
| 318 // Offset is in a register | |
| 319 if (ins & 0x00800000) { | |
| 320 // Add offset | |
| 321 Rn += RmShifted(ins & 0x00000FFF); | |
| 322 } else { | |
| 323 // Subtract offset | |
| 324 Rn -= RmShifted(ins & 0x00000FFF); | |
| 325 } | |
| 326 } | |
| 327 } | |
| 328 return ((unsigned long *)*(unsigned long *)Rn); | |
| 329 } | |
| 330 } | |
| 331 } | |
| 332 return (pc+1); | |
| 333 case 0x2: // Branch, LDM/STM | |
| 334 if ((ins & 0x02000000) == 0) { | |
| 335 // LDM/STM | |
| 336 if ((ins & 0x00100000) == 0) { | |
| 337 // STM | |
| 338 return (pc+1); | |
| 339 } else { | |
| 340 // LDM | |
| 341 if ((ins & 0x00008000) == 0) { | |
| 342 // PC not in list | |
| 343 return (pc+1); | |
| 344 } else { | |
| 345 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); | |
| 346 if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch! | |
| 347 offset = ins & 0x0000FFFF; | |
| 348 reg_count = 0; | |
| 349 for (i = 0; i < 15; i++) { | |
| 350 if (offset & (1<<i)) reg_count++; | |
| 351 } | |
| 352 if (ins & 0x00800000) { | |
| 353 // Add offset | |
| 354 Rn += reg_count*4; | |
| 355 } else { | |
| 356 // Subtract offset | |
| 357 Rn -= 4; | |
| 358 } | |
| 359 return ((unsigned long *)*(unsigned long *)Rn); | |
| 360 } | |
| 361 } | |
| 362 } else { | |
| 363 // Branch | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
364 if (ins_will_execute(ins)) { |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
365 offset = (ins & 0x00FFFFFF) << 2; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
366 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
|
367 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
|
368 return ((unsigned long *)new_pc); |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
369 } else { |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
370 // Falls through |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
371 return (pc+1); |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
372 } |
| 2 | 373 } |
| 374 case 0x3: // Coprocessor & SWI | |
| 375 return (pc+1); | |
| 376 } | |
| 377 } | |
| 378 | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
379 |
| 2 | 380 void __single_step (void) |
| 381 { | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
382 unsigned long pc = get_register(PC); |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
383 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
|
384 if (ins_will_execute(curins)) { |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
385 // 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
|
386 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
|
387 curins); |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
388 } else { |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
389 // 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
|
390 // don't hold) |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
391 ss_saved_pc = pc+4; |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
392 } |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
393 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
|
394 *(unsigned long*)ss_saved_pc = HAL_BREAKINST_ARM; |
| 2 | 395 } |
| 396 | |
| 397 /* Clear the single-step state. */ | |
| 398 | |
| 399 void __clear_single_step (void) | |
| 400 { | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
401 if (ss_saved_pc != 0) { |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
402 // ARM instruction |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
403 *(unsigned long*)ss_saved_pc = ss_saved_instr; |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
404 ss_saved_pc = 0; |
| 2 | 405 } |
| 406 } | |
| 407 | |
| 408 void __install_breakpoints (void) | |
| 409 { | |
| 410 // FIXME(); | |
| 411 } | |
| 412 | |
| 413 void __clear_breakpoints (void) | |
| 414 { | |
| 415 // FIXME(); | |
| 416 } | |
| 417 | |
| 418 /* If the breakpoint we hit is in the breakpoint() instruction, return a | |
| 419 non-zero value. */ | |
| 420 | |
| 421 int | |
| 422 __is_breakpoint_function () | |
| 423 { | |
| 424 return get_register (PC) == (target_register_t)&CYG_LABEL_NAME(breakinst); | |
| 425 } | |
| 426 | |
| 427 | |
| 428 /* Skip the current instruction. Since this is only called by the | |
| 429 stub when the PC points to a breakpoint or trap instruction, | |
| 430 we can safely just skip 4. */ | |
| 431 | |
| 432 void __skipinst (void) | |
| 433 { | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
434 unsigned long pc = get_register(PC); |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
435 pc += 4; |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
436 |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
437 put_register(PC, pc); |
| 2 | 438 } |
| 439 | |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
440 |
|
46
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
38
diff
changeset
|
441 |
| 2 | 442 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
