Mercurial > flash_v2
annotate packages/hal/powerpc/arch/current/src/ppc_stub.c @ 1777:c16341b1bac6 default tip
* Added execute permissions to files missed in conversion from CVS
| author | alexs |
|---|---|
| date | Mon, 12 Oct 2009 02:26:09 +0100 |
| parents | 9c818dd5d9fa |
| children |
| rev | line source |
|---|---|
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
1 //======================================================================== |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
2 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
3 // ppc_stub.c |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
4 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
5 // Helper functions for stub, generic to all PowerPC processors |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
6 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
7 //======================================================================== |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
9 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
12 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later version. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
16 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
20 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
21 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
22 // You should have received a copy of the GNU General Public License along |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
23 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
25 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
26 // As a special exception, if other files instantiate templates or use macros |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
27 // or inline functions from this file, or you compile this file and link it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
28 // with other works to produce a work based on this file, this file does not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
29 // by itself cause the resulting work to be covered by the GNU General Public |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
30 // License. However the source code for this file must still be made available |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
31 // in accordance with section (3) of the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
32 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
33 // This exception does not invalidate any other reasons why a work based on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
34 // this file might be covered by the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
35 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
37 // at http://sources.redhat.com/ecos/ecos-license/ |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
38 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
39 //####ECOSGPLCOPYRIGHTEND#### |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
40 //======================================================================== |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
41 //#####DESCRIPTIONBEGIN#### |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
42 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
43 // Author(s): Red Hat, jskov |
|
149
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
44 // Contributors: Red Hat, jskov, gthomas |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
45 // Date: 1998-08-20 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
46 // Purpose: |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
47 // Description: Helper functions for stub, generic to all PowerPC processors |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
48 // Usage: |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
49 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
50 //####DESCRIPTIONEND#### |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
51 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
30
diff
changeset
|
52 //======================================================================== |
| 0 | 53 |
| 54 #include <stddef.h> | |
| 55 | |
| 56 #include <pkgconf/hal.h> | |
| 57 | |
| 58 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS | |
| 59 | |
| 2 | 60 #define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS |
| 61 #include <cyg/hal/ppc_regs.h> | |
| 0 | 62 |
| 63 #include <cyg/hal/hal_stub.h> | |
| 64 #include <cyg/hal/hal_arch.h> | |
| 65 #include <cyg/hal/hal_intr.h> | |
| 66 | |
|
149
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
67 #ifdef CYGNUM_HAL_NO_VECTOR_TRACE |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
68 #define USE_BREAKPOINTS_FOR_SINGLE_STEP |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
69 #endif |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
70 |
| 0 | 71 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT |
| 72 #include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id | |
| 73 #endif | |
| 74 | |
| 1397 | 75 #ifndef OFFSETOF |
| 76 #define OFFSETOF(_struct_, _member_) (int)((char *)(&(((_struct_*)0)->_member_))-(char *)((_struct_*)0)) | |
| 77 #endif | |
| 78 | |
| 0 | 79 /* Given a trap value TRAP, return the corresponding signal. */ |
| 80 | |
| 81 int __computeSignal (unsigned int trap_number) | |
| 82 { | |
| 83 switch (trap_number) | |
| 84 { | |
| 2 | 85 case CYGNUM_HAL_VECTOR_MACHINE_CHECK: |
| 0 | 86 /* Machine check */ |
| 2 | 87 case CYGNUM_HAL_VECTOR_DSI: |
| 0 | 88 /* Data access */ |
| 89 return SIGSEGV; | |
| 90 | |
| 2 | 91 case CYGNUM_HAL_VECTOR_ISI: |
| 0 | 92 /* Instruction access (Ifetch) */ |
| 2 | 93 case CYGNUM_HAL_VECTOR_ALIGNMENT: |
| 0 | 94 /* Data access */ |
| 95 return SIGBUS; | |
| 96 | |
| 2 | 97 case CYGNUM_HAL_VECTOR_INTERRUPT: |
| 0 | 98 /* External interrupt */ |
| 99 return SIGINT; | |
| 100 | |
| 2 | 101 case CYGNUM_HAL_VECTOR_TRACE: |
| 0 | 102 /* Instruction trace */ |
| 103 return SIGTRAP; | |
| 104 | |
| 2 | 105 case CYGNUM_HAL_VECTOR_PROGRAM: |
|
151
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
149
diff
changeset
|
106 #ifdef CYGPKG_HAL_POWERPC_PPC40x |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
149
diff
changeset
|
107 // The 40x is b0rken, returning 0 for these bits. Translate to |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
149
diff
changeset
|
108 // SIGTRAP to allow thread debugging. |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
149
diff
changeset
|
109 return SIGTRAP; |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
149
diff
changeset
|
110 #else |
| 2 | 111 // The register PS contains the value of SRR1 at the time of |
| 112 // exception entry. Bits 11-15 contain information about the | |
| 113 // cause of the exception. Bits 16-31 the PS (MSR) state. | |
|
149
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
114 #ifdef USE_BREAKPOINTS_FOR_SINGLE_STEP |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
115 if (__is_single_step(get_register(PC))) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
116 return SIGTRAP; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
117 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
118 #endif |
| 0 | 119 switch ((get_register (PS) >> 17) & 0xf){ |
| 120 case 1: /* trap */ | |
| 121 return SIGTRAP; | |
| 122 case 2: /* privileged instruction */ | |
| 123 case 4: /* illegal instruction */ | |
| 124 return SIGILL; | |
| 125 case 8: /* floating point */ | |
| 126 return SIGFPE; | |
| 127 default: /* should never happen! */ | |
|
149
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
128 return SIGILL; |
| 0 | 129 } |
|
151
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
149
diff
changeset
|
130 #endif |
| 0 | 131 |
| 2 | 132 case CYGNUM_HAL_VECTOR_RESERVED_A: |
| 133 case CYGNUM_HAL_VECTOR_RESERVED_B: | |
| 0 | 134 return SIGILL; |
| 135 | |
| 2 | 136 case CYGNUM_HAL_VECTOR_FP_UNAVAILABLE: |
| 0 | 137 /* FPU disabled */ |
| 2 | 138 case CYGNUM_HAL_VECTOR_FP_ASSIST: |
| 0 | 139 /* FPU assist */ |
| 140 return SIGFPE; | |
| 141 | |
| 2 | 142 case CYGNUM_HAL_VECTOR_DECREMENTER: |
| 0 | 143 /* Decrementer alarm */ |
| 144 return SIGALRM; | |
| 145 | |
| 2 | 146 case CYGNUM_HAL_VECTOR_SYSTEM_CALL: |
| 0 | 147 /* System call */ |
| 148 return SIGSYS; | |
| 149 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
150 #if defined(CYGPKG_HAL_POWERPC_MPC8xx) || defined(CYGPKG_HAL_POWERPC_MPC5xx) |
| 2 | 151 case CYGNUM_HAL_VECTOR_SW_EMUL: |
| 0 | 152 /* A SW_EMUL is generated instead of PROGRAM for illegal |
| 153 instructions. */ | |
| 154 return SIGILL; | |
| 155 | |
| 2 | 156 case CYGNUM_HAL_VECTOR_DATA_BP: |
| 157 case CYGNUM_HAL_VECTOR_INSTRUCTION_BP: | |
| 158 case CYGNUM_HAL_VECTOR_PERIPHERAL_BP: | |
| 159 case CYGNUM_HAL_VECTOR_NMI: | |
| 0 | 160 /* Developer port debugging exceptions. */ |
| 161 return SIGTRAP; | |
| 162 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
163 #if defined(CYGNUM_HAL_VECTOR_ITLB_MISS) |
| 2 | 164 case CYGNUM_HAL_VECTOR_ITLB_MISS: |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
165 /* Software reload of TLB required. */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
166 return SIGTRAP; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
167 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
168 #if defined(CYGNUM_HAL_VECTOR_DTLB_MISS) |
| 2 | 169 case CYGNUM_HAL_VECTOR_DTLB_MISS: |
| 0 | 170 /* Software reload of TLB required. */ |
| 171 return SIGTRAP; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
151
diff
changeset
|
172 #endif |
| 2 | 173 case CYGNUM_HAL_VECTOR_ITLB_ERROR: |
| 0 | 174 /* Invalid instruction access. */ |
| 175 return SIGBUS; | |
| 176 | |
| 2 | 177 case CYGNUM_HAL_VECTOR_DTLB_ERROR: |
| 0 | 178 /* Invalid data access. */ |
| 179 return SIGSEGV; | |
|
68
f74b2666b30d
Merge from eCos master repository on 2000-02-04-07:47:04-GMT
jlarmour
parents:
66
diff
changeset
|
180 #endif // defined(CYGPKG_HAL_POWERPC_MPC8xx) |
| 0 | 181 |
| 182 default: | |
| 183 return SIGTERM; | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 | |
| 188 /* Return the trap number corresponding to the last-taken trap. */ | |
| 189 | |
| 190 int __get_trap_number (void) | |
| 191 { | |
| 192 // The vector is not not part of the GDB register set so get it | |
| 193 // directly from the save context. | |
| 194 return _hal_registers->vector >> 8; | |
| 195 } | |
| 196 | |
| 197 /* Set the currently-saved pc register value to PC. This also updates NPC | |
| 198 as needed. */ | |
| 199 | |
| 200 void set_pc (target_register_t pc) | |
| 201 { | |
| 202 put_register (PC, pc); | |
| 203 } | |
| 204 | |
| 1397 | 205 #ifdef CYGHWR_HAL_POWERPC_FPU |
| 206 static int | |
| 207 reg_offset(regnames_t reg) | |
| 208 { | |
| 209 // We let the compiler determine the offsets in order to avoid all | |
| 210 // possible alignment problems | |
| 211 int base_offset; | |
| 212 // 32 general purpose registers | |
| 213 if(reg < F0) return reg * 4; | |
| 214 | |
| 215 // first sixteen floating point regs | |
| 216 base_offset = OFFSETOF(GDB_Registers, f0); | |
| 217 if(reg < F16) return base_offset + ((reg - F0) * 8); | |
| 218 | |
| 219 // last sixteen floating point regs | |
| 220 base_offset = OFFSETOF(GDB_Registers, f16); | |
| 221 if(reg < PC) return base_offset + ((reg - F16) * 8); | |
| 222 | |
| 223 // Other 32 bit regs | |
| 224 if(reg < PS) return(OFFSETOF(GDB_Registers, pc)); | |
| 225 if(reg < CND) return(OFFSETOF(GDB_Registers, msr)); | |
| 226 if(reg < LR) return(OFFSETOF(GDB_Registers, cr)); | |
| 227 if(reg < CNT) return(OFFSETOF(GDB_Registers, lr)); | |
| 228 if(reg < XER) return(OFFSETOF(GDB_Registers, ctr)); | |
| 229 if(reg < MQ) return(OFFSETOF(GDB_Registers, xer)); | |
| 230 | |
| 231 return OFFSETOF(GDB_Registers, mq); | |
| 232 } | |
| 233 | |
| 234 // Return the currently-saved value corresponding to register REG of | |
| 235 // the exception context. | |
| 236 target_register_t | |
| 237 get_register (regnames_t reg) | |
| 238 { | |
| 239 target_register_t val; | |
| 240 int offset = reg_offset(reg); | |
| 241 | |
| 242 if (REGSIZE(reg) > sizeof(target_register_t)) | |
| 243 return -1; | |
| 244 | |
| 245 val = _registers[offset/sizeof(target_register_t)]; | |
| 246 | |
| 247 return val; | |
| 248 } | |
| 249 | |
| 250 // Store VALUE in the register corresponding to WHICH in the exception | |
| 251 // context. | |
| 252 void | |
| 253 put_register (regnames_t which, target_register_t value) | |
| 254 { | |
| 255 int offset = reg_offset(which); | |
| 256 | |
| 257 if (REGSIZE(which) > sizeof(target_register_t)) | |
| 258 return; | |
| 259 | |
| 260 _registers[offset/sizeof(target_register_t)] = value; | |
| 261 } | |
| 262 | |
| 263 // Write the contents of register WHICH into VALUE as raw bytes. This | |
| 264 // is only used for registers larger than sizeof(target_register_t). | |
| 265 // Return non-zero if it is a valid register. | |
| 266 int | |
| 267 get_register_as_bytes (regnames_t which, char *value) | |
| 268 { | |
| 269 int offset = reg_offset(which); | |
| 270 | |
| 271 memcpy (value, (char *)_registers + offset, REGSIZE(which)); | |
| 272 return 1; | |
| 273 } | |
| 274 | |
| 275 // Alter the contents of saved register WHICH to contain VALUE. This | |
| 276 // is only used for registers larger than sizeof(target_register_t). | |
| 277 // Return non-zero if it is a valid register. | |
| 278 int | |
| 279 put_register_as_bytes (regnames_t which, char *value) | |
| 280 { | |
| 281 int offset = reg_offset(which); | |
| 282 | |
| 283 memcpy ((char *)_registers + offset, value, REGSIZE(which)); | |
| 284 return 1; | |
| 285 } | |
| 286 #endif | |
| 0 | 287 |
| 288 /*---------------------------------------------------------------------- | |
| 289 * Single-step support | |
| 290 */ | |
| 291 | |
| 292 /* Set things up so that the next user resume will execute one instruction. | |
| 293 This may be done by setting breakpoints or setting a single step flag | |
| 294 in the saved user registers, for example. */ | |
| 295 | |
|
149
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
296 #ifdef USE_BREAKPOINTS_FOR_SINGLE_STEP |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
297 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
298 #if (HAL_BREAKINST_SIZE == 1) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
299 typedef cyg_uint8 t_inst; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
300 #elif (HAL_BREAKINST_SIZE == 2) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
301 typedef cyg_uint16 t_inst; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
302 #elif (HAL_BREAKINST_SIZE == 4) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
303 typedef cyg_uint32 t_inst; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
304 #else |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
305 #error "Don't know how to handle that size" |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
306 #endif |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
307 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
308 typedef struct |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
309 { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
310 t_inst *targetAddr; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
311 t_inst savedInstr; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
312 } instrBuffer; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
313 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
314 static instrBuffer sstep_instr[2]; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
315 static target_register_t irq_state = 0; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
316 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
317 static void |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
318 __insert_break(int indx, target_register_t pc) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
319 { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
320 sstep_instr[indx].targetAddr = (t_inst *)pc; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
321 sstep_instr[indx].savedInstr = *(t_inst *)pc; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
322 *(t_inst*)pc = (t_inst)HAL_BREAKINST; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
323 __data_cache(CACHE_FLUSH); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
324 __instruction_cache(CACHE_FLUSH); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
325 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
326 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
327 static void |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
328 __remove_break(int indx) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
329 { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
330 if (sstep_instr[indx].targetAddr != 0) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
331 *(sstep_instr[indx].targetAddr) = sstep_instr[indx].savedInstr; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
332 sstep_instr[indx].targetAddr = 0; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
333 __data_cache(CACHE_FLUSH); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
334 __instruction_cache(CACHE_FLUSH); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
335 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
336 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
337 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
338 int |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
339 __is_single_step(target_register_t pc) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
340 { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
341 return (sstep_instr[0].targetAddr == pc) || |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
342 (sstep_instr[1].targetAddr == pc); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
343 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
344 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
345 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
346 // Compute the target address for this instruction, if the instruction |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
347 // is some sort of branch/flow change. |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
348 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
349 struct xl_form { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
350 unsigned int op : 6; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
351 unsigned int bo : 5; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
352 unsigned int bi : 5; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
353 unsigned int reserved : 5; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
354 unsigned int xo : 10; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
355 unsigned int lk : 1; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
356 }; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
357 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
358 struct i_form { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
359 unsigned int op : 6; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
360 signed int li : 24; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
361 unsigned int aa : 1; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
362 unsigned int lk : 1; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
363 }; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
364 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
365 struct b_form { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
366 unsigned int op : 6; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
367 unsigned int bo : 5; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
368 unsigned int bi : 5; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
369 signed int bd : 14; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
370 unsigned int aa : 1; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
371 unsigned int lk : 1; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
372 }; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
373 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
374 union ppc_insn { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
375 unsigned int word; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
376 struct i_form i; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
377 struct b_form b; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
378 struct xl_form xl; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
379 }; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
380 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
381 static target_register_t |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
382 __branch_pc(target_register_t pc) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
383 { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
384 union ppc_insn insn; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
385 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
386 insn.word = *(t_inst *)pc; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
387 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
388 // Decode the instruction to determine the instruction which will follow |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
389 // Note: there are holes in this process, but the important ones work |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
390 switch (insn.i.op) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
391 case 16: |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
392 /* bcx */ |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
393 if (insn.b.aa) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
394 return (target_register_t)(insn.b.bd << 2); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
395 } else { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
396 return (target_register_t)((insn.b.bd << 2) + (long)pc); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
397 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
398 case 18: |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
399 /* bx */ |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
400 if (insn.i.aa) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
401 return (target_register_t)(insn.i.li << 2); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
402 } else { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
403 return (target_register_t)((insn.i.li << 2) + (long)pc); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
404 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
405 case 19: |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
406 if (insn.xl.reserved == 0) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
407 if (insn.xl.xo == 528) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
408 /* bcctrx */ |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
409 return (target_register_t)(get_register(CNT) & ~3); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
410 } else if (insn.xl.xo == 16) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
411 /* bclrx */ |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
412 return (target_register_t)(get_register(LR) & ~3); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
413 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
414 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
415 break; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
416 default: |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
417 break; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
418 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
419 return (pc+4); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
420 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
421 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
422 void __single_step(void) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
423 { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
424 target_register_t msr = get_register(PS); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
425 target_register_t pc = get_register(PC); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
426 target_register_t next_pc = __branch_pc(pc); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
427 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
428 // Disable interrupts. |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
429 irq_state = msr & MSR_EE; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
430 msr &= ~MSR_EE; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
431 put_register (PS, msr); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
432 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
433 // Set a breakpoint at the next instruction |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
434 __insert_break(0, pc+4); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
435 if (next_pc != (pc+4)) { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
436 __insert_break(1, next_pc); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
437 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
438 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
439 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
440 /* Clear the single-step state. */ |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
441 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
442 void __clear_single_step(void) |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
443 { |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
444 target_register_t msr = get_register (PS); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
445 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
446 // Restore interrupt state. |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
447 // FIXME: Should check whether the executed instruction changed the |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
448 // interrupt state - or single-stepping a MSR changing instruction |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
449 // may result in a wrong EE. Not a very likely scenario though. |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
450 msr |= irq_state; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
451 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
452 // This function is called much more than its counterpart |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
453 // __single_step. Only re-enable interrupts if they where |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
454 // disabled during the previous cal to __single_step. Otherwise, |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
455 // this function only makes "extra sure" that no trace or branch |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
456 // exception will happen. |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
457 irq_state = 0; |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
458 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
459 put_register (PS, msr); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
460 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
461 // Remove breakpoints |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
462 __remove_break(0); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
463 __remove_break(1); |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
464 } |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
465 |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
466 #else |
|
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
467 |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
2
diff
changeset
|
468 static target_register_t irq_state = 0; |
| 0 | 469 |
| 2 | 470 void __single_step (void) |
| 0 | 471 { |
| 472 target_register_t msr = get_register (PS); | |
| 473 | |
| 474 // Set single-step flag in the exception context. | |
| 475 msr |= (MSR_SE | MSR_BE); | |
| 476 // Disable interrupts. | |
| 477 irq_state = msr & MSR_EE; | |
| 478 msr &= ~MSR_EE; | |
| 479 | |
| 480 put_register (PS, msr); | |
| 481 } | |
| 482 | |
| 483 /* Clear the single-step state. */ | |
| 484 | |
| 2 | 485 void __clear_single_step (void) |
| 0 | 486 { |
| 487 target_register_t msr = get_register (PS); | |
| 488 | |
| 489 // Clear single-step flag in the exception context. | |
| 490 msr &= ~(MSR_SE | MSR_BE); | |
| 491 // Restore interrupt state. | |
| 492 // FIXME: Should check whether the executed instruction changed the | |
| 493 // interrupt state - or single-stepping a MSR changing instruction | |
| 494 // may result in a wrong EE. Not a very likely scenario though. | |
| 495 msr |= irq_state; | |
| 496 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
2
diff
changeset
|
497 // This function is called much more than its counterpart |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
2
diff
changeset
|
498 // __single_step. Only re-enable interrupts if they where |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
2
diff
changeset
|
499 // disabled during the previous cal to __single_step. Otherwise, |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
2
diff
changeset
|
500 // this function only makes "extra sure" that no trace or branch |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
2
diff
changeset
|
501 // exception will happen. |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
2
diff
changeset
|
502 irq_state = 0; |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
2
diff
changeset
|
503 |
| 0 | 504 put_register (PS, msr); |
| 505 } | |
|
149
52c99470ec11
Merge from eCos master repository on 2001-01-19-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
506 #endif |
| 0 | 507 |
| 2 | 508 void __install_breakpoints (void) |
| 0 | 509 { |
| 510 /* NOP since single-step HW exceptions are used instead of | |
| 511 breakpoints. */ | |
| 512 } | |
| 513 | |
| 2 | 514 void __clear_breakpoints (void) |
| 515 { | |
| 516 } | |
| 517 | |
| 0 | 518 |
| 519 /* If the breakpoint we hit is in the breakpoint() instruction, return a | |
| 520 non-zero value. */ | |
| 521 | |
| 522 int | |
| 523 __is_breakpoint_function () | |
| 524 { | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
68
diff
changeset
|
525 return get_register (PC) == (target_register_t)&_breakinst; |
| 0 | 526 } |
| 527 | |
| 528 | |
| 529 /* Skip the current instruction. Since this is only called by the | |
| 530 stub when the PC points to a breakpoint or trap instruction, | |
| 531 we can safely just skip 4. */ | |
| 532 | |
| 533 void __skipinst (void) | |
| 534 { | |
| 535 put_register (PC, get_register (PC) + 4); | |
| 536 } | |
| 537 | |
| 538 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
