comparison packages/hal/powerpc/arch/current/src/ppc_stub.c @ 2:443894e2e912 ecos-v1_2_1-release

Block commit of eCos version 1.2.1
author jlarmour
date Tue, 11 May 1999 12:24:34 +0000
parents 3111d98ba7b3
children 641b639be825
comparison
equal deleted inserted replaced
1:72f549f0d891 2:443894e2e912
1 /* ppc_stub.c - helper functions for stub, generic to all PowerPC processors 1 /* ppc_stub.c - helper functions for stub, generic to all PowerPC processors
2 * 2 *
3 * Copyright (c) 1998 Cygnus Support 3 * Copyright (c) 1998,1999 Cygnus Solutions
4 * 4 *
5 * The authors hereby grant permission to use, copy, modify, distribute, 5 * The authors hereby grant permission to use, copy, modify, distribute,
6 * and license this software and its documentation for any purpose, provided 6 * and license this software and its documentation for any purpose, provided
7 * that existing copyright notices are retained in all copies and that this 7 * that existing copyright notices are retained in all copies and that this
8 * notice is included verbatim in any distributions. No written agreement, 8 * notice is included verbatim in any distributions. No written agreement,
17 17
18 #include <pkgconf/hal.h> 18 #include <pkgconf/hal.h>
19 19
20 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS 20 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
21 21
22 #ifdef CYG_HAL_POWERPC_SIM 22 #define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
23 #error "GDB Stub support not implemented for PPC SIM" 23 #include <cyg/hal/ppc_regs.h>
24 #endif
25 24
26 #include <cyg/hal/hal_stub.h> 25 #include <cyg/hal/hal_stub.h>
27 #include <cyg/hal/hal_arch.h> 26 #include <cyg/hal/hal_arch.h>
28 #include <cyg/hal/hal_intr.h> 27 #include <cyg/hal/hal_intr.h>
29 #include <cyg/hal/ppc_regs.h>
30 28
31 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT 29 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
32 #include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id 30 #include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id
33 #endif 31 #endif
34 32
35 #define SIGHUP 1 /* hangup */
36 #define SIGINT 2 /* interrupt */
37 #define SIGQUIT 3 /* quit */
38 #define SIGILL 4 /* illegal instruction (not reset when caught) */
39 #define SIGTRAP 5 /* trace trap (not reset when caught) */
40 #define SIGIOT 6 /* IOT instruction */
41 #define SIGABRT 6 /* used by abort, replace SIGIOT in the future */
42 #define SIGEMT 7 /* EMT instruction */
43 #define SIGFPE 8 /* floating point exception */
44 #define SIGKILL 9 /* kill (cannot be caught or ignored) */
45 #define SIGBUS 10 /* bus error */
46 #define SIGSEGV 11 /* segmentation violation */
47 #define SIGSYS 12 /* bad argument to system call */
48 #define SIGPIPE 13 /* write on a pipe with no one to read it */
49 #define SIGALRM 14 /* alarm clock */
50 #define SIGTERM 15 /* software termination signal from kill */
51
52 /* Saved registers. */
53
54 HAL_SavedRegisters *_hal_registers;
55
56 target_register_t * _registers; /* A pointer to the current set of registers */
57 target_register_t registers[NUMREGS];
58 target_register_t alt_registers[NUMREGS] ; /* Thread or saved process state */
59
60
61 /* Given a trap value TRAP, return the corresponding signal. */ 33 /* Given a trap value TRAP, return the corresponding signal. */
62 34
63 int __computeSignal (unsigned int trap_number) 35 int __computeSignal (unsigned int trap_number)
64 { 36 {
65 switch (trap_number) 37 switch (trap_number)
66 { 38 {
67 case CYG_VECTOR_MACHINE_CHECK: 39 case CYGNUM_HAL_VECTOR_MACHINE_CHECK:
68 /* Machine check */ 40 /* Machine check */
69 case CYG_VECTOR_DSI: 41 case CYGNUM_HAL_VECTOR_DSI:
70 /* Data access */ 42 /* Data access */
71 return SIGSEGV; 43 return SIGSEGV;
72 44
73 case CYG_VECTOR_ISI: 45 case CYGNUM_HAL_VECTOR_ISI:
74 /* Instruction access (Ifetch) */ 46 /* Instruction access (Ifetch) */
75 case CYG_VECTOR_ALIGNMENT: 47 case CYGNUM_HAL_VECTOR_ALIGNMENT:
76 /* Data access */ 48 /* Data access */
77 return SIGBUS; 49 return SIGBUS;
78 50
79 case CYG_VECTOR_INTERRUPT: 51 case CYGNUM_HAL_VECTOR_INTERRUPT:
80 /* External interrupt */ 52 /* External interrupt */
81 return SIGINT; 53 return SIGINT;
82 54
83 case CYG_VECTOR_TRACE: 55 case CYGNUM_HAL_VECTOR_TRACE:
84 /* Instruction trace */ 56 /* Instruction trace */
85 return SIGTRAP; 57 return SIGTRAP;
86 58
87 case CYG_VECTOR_PROGRAM: 59 case CYGNUM_HAL_VECTOR_PROGRAM:
60 // The register PS contains the value of SRR1 at the time of
61 // exception entry. Bits 11-15 contain information about the
62 // cause of the exception. Bits 16-31 the PS (MSR) state.
88 switch ((get_register (PS) >> 17) & 0xf){ 63 switch ((get_register (PS) >> 17) & 0xf){
89 case 1: /* trap */ 64 case 1: /* trap */
90 return SIGTRAP; 65 return SIGTRAP;
91 case 2: /* privileged instruction */ 66 case 2: /* privileged instruction */
92 case 4: /* illegal instruction */ 67 case 4: /* illegal instruction */
95 return SIGFPE; 70 return SIGFPE;
96 default: /* should never happen! */ 71 default: /* should never happen! */
97 return SIGTERM; 72 return SIGTERM;
98 } 73 }
99 74
100 case CYG_VECTOR_RESERVED_A: 75 case CYGNUM_HAL_VECTOR_RESERVED_A:
101 case CYG_VECTOR_RESERVED_B: 76 case CYGNUM_HAL_VECTOR_RESERVED_B:
102 return SIGILL; 77 return SIGILL;
103 78
104 case CYG_VECTOR_FP_UNAVAILABLE: 79 case CYGNUM_HAL_VECTOR_FP_UNAVAILABLE:
105 /* FPU disabled */ 80 /* FPU disabled */
106 case CYG_VECTOR_FP_ASSIST: 81 case CYGNUM_HAL_VECTOR_FP_ASSIST:
107 /* FPU assist */ 82 /* FPU assist */
108 return SIGFPE; 83 return SIGFPE;
109 84
110 case CYG_VECTOR_DECREMENTER: 85 case CYGNUM_HAL_VECTOR_DECREMENTER:
111 /* Decrementer alarm */ 86 /* Decrementer alarm */
112 return SIGALRM; 87 return SIGALRM;
113 88
114 case CYG_VECTOR_SYSTEM_CALL: 89 case CYGNUM_HAL_VECTOR_SYSTEM_CALL:
115 /* System call */ 90 /* System call */
116 return SIGSYS; 91 return SIGSYS;
117 92
118 #ifdef CYG_HAL_POWERPC_MP860 93 #if defined(CYG_HAL_POWERPC_MPC8xx)
119 case CYG_VECTOR_SW_EMUL: 94 case CYGNUM_HAL_VECTOR_SW_EMUL:
120 /* A SW_EMUL is generated instead of PROGRAM for illegal 95 /* A SW_EMUL is generated instead of PROGRAM for illegal
121 instructions. */ 96 instructions. */
122 return SIGILL; 97 return SIGILL;
123 98
124 case CYG_VECTOR_DATA_BP: 99 case CYGNUM_HAL_VECTOR_DATA_BP:
125 case CYG_VECTOR_INSTRUCTION_BP: 100 case CYGNUM_HAL_VECTOR_INSTRUCTION_BP:
126 case CYG_VECTOR_PERIPHERAL_BP: 101 case CYGNUM_HAL_VECTOR_PERIPHERAL_BP:
127 case CYG_VECTOR_NMI: 102 case CYGNUM_HAL_VECTOR_NMI:
128 /* Developer port debugging exceptions. */ 103 /* Developer port debugging exceptions. */
129 return SIGTRAP; 104 return SIGTRAP;
130 105
131 case CYG_VECTOR_ITLB_MISS: 106 case CYGNUM_HAL_VECTOR_ITLB_MISS:
132 case CYG_VECTOR_DTLB_MISS: 107 case CYGNUM_HAL_VECTOR_DTLB_MISS:
133 /* Software reload of TLB required. */ 108 /* Software reload of TLB required. */
134 return SIGTRAP; 109 return SIGTRAP;
135 110
136 case CYG_VECTOR_ITLB_ERROR: 111 case CYGNUM_HAL_VECTOR_ITLB_ERROR:
137 /* Invalid instruction access. */ 112 /* Invalid instruction access. */
138 return SIGBUS; 113 return SIGBUS;
139 114
140 case CYG_VECTOR_DTLB_ERROR: 115 case CYGNUM_HAL_VECTOR_DTLB_ERROR:
141 /* Invalid data access. */ 116 /* Invalid data access. */
142 return SIGSEGV; 117 return SIGSEGV;
143 #endif 118 #endif // defined(CYG_HAL_POWERPC_MPC8xx)
144 119
145 default: 120 default:
146 return SIGTERM; 121 return SIGTERM;
147 } 122 }
148 } 123 }
155 // The vector is not not part of the GDB register set so get it 130 // The vector is not not part of the GDB register set so get it
156 // directly from the save context. 131 // directly from the save context.
157 return _hal_registers->vector >> 8; 132 return _hal_registers->vector >> 8;
158 } 133 }
159 134
160 // Return the currently-saved value corresponding to register REG of
161 // the exception context.
162 target_register_t get_register (regnames_t reg)
163 {
164 return registers[reg];
165 }
166
167 // Store VALUE in the register corresponding to WHICH in the exception
168 // context.
169 void put_register (regnames_t which, target_register_t value)
170 {
171 registers[which] = value;
172 }
173
174
175 /* Set the currently-saved pc register value to PC. This also updates NPC 135 /* Set the currently-saved pc register value to PC. This also updates NPC
176 as needed. */ 136 as needed. */
177 137
178 void set_pc (target_register_t pc) 138 void set_pc (target_register_t pc)
179 { 139 {
189 This may be done by setting breakpoints or setting a single step flag 149 This may be done by setting breakpoints or setting a single step flag
190 in the saved user registers, for example. */ 150 in the saved user registers, for example. */
191 151
192 static target_register_t irq_state; 152 static target_register_t irq_state;
193 153
194 void single_step (void) 154 void __single_step (void)
195 { 155 {
196 target_register_t msr = get_register (PS); 156 target_register_t msr = get_register (PS);
197 157
198 // Set single-step flag in the exception context. 158 // Set single-step flag in the exception context.
199 msr |= (MSR_SE | MSR_BE); 159 msr |= (MSR_SE | MSR_BE);
204 put_register (PS, msr); 164 put_register (PS, msr);
205 } 165 }
206 166
207 /* Clear the single-step state. */ 167 /* Clear the single-step state. */
208 168
209 void clear_single_step (void) 169 void __clear_single_step (void)
210 { 170 {
211 target_register_t msr = get_register (PS); 171 target_register_t msr = get_register (PS);
212 172
213 // Clear single-step flag in the exception context. 173 // Clear single-step flag in the exception context.
214 msr &= ~(MSR_SE | MSR_BE); 174 msr &= ~(MSR_SE | MSR_BE);
220 180
221 put_register (PS, msr); 181 put_register (PS, msr);
222 } 182 }
223 183
224 184
225 void install_breakpoints (void) 185 void __install_breakpoints (void)
226 { 186 {
227 /* NOP since single-step HW exceptions are used instead of 187 /* NOP since single-step HW exceptions are used instead of
228 breakpoints. */ 188 breakpoints. */
229 } 189 }
230 190
191 void __clear_breakpoints (void)
192 {
193 }
194
231 195
232 /* If the breakpoint we hit is in the breakpoint() instruction, return a 196 /* If the breakpoint we hit is in the breakpoint() instruction, return a
233 non-zero value. */ 197 non-zero value. */
234 198
235 int 199 int
236 __is_breakpoint_function () 200 __is_breakpoint_function ()
237 { 201 {
238 return get_register (PC) == (target_register_t)&_breakinst; 202 return get_register (PC) == (target_register_t)&CYG_LABEL_NAME(breakinst);
239 } 203 }
240 204
241 205
242 /* Skip the current instruction. Since this is only called by the 206 /* Skip the current instruction. Since this is only called by the
243 stub when the PC points to a breakpoint or trap instruction, 207 stub when the PC points to a breakpoint or trap instruction,
246 void __skipinst (void) 210 void __skipinst (void)
247 { 211 {
248 put_register (PC, get_register (PC) + 4); 212 put_register (PC, get_register (PC) + 4);
249 } 213 }
250 214
251
252 /* Write the 'T' packet in BUFFER. SIGVAL is the signal the program
253 received. */
254
255 void __build_t_packet (int sigval, char *buf)
256 {
257 target_register_t addr;
258 char *ptr = buf;
259 target_register_t *sp;
260
261 sp = (target_register_t *) get_register (SP);
262
263 *ptr++ = 'T';
264 *ptr++ = __tohex (sigval >> 4);
265 *ptr++ = __tohex (sigval);
266
267 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
268 // Include thread ID if thread manipulation is required.
269 {
270 int id;
271
272 *ptr++ = 't';
273 *ptr++ = 'h';
274 *ptr++ = 'r';
275 *ptr++ = 'e';
276 *ptr++ = 'a';
277 *ptr++ = 'd';
278 *ptr++ = ':';
279
280 id = dbg_currthread_id ();
281 ptr = __mem2hex((char *)&id, ptr, sizeof(id), 0);
282 *ptr++ = ';';
283 }
284 #endif
285
286
287 *ptr++ = __tohex (PC >> 4);
288 *ptr++ = __tohex (PC);
289 *ptr++ = ':';
290 addr = get_register (PC);
291 ptr = __mem2hex((char *)&addr, ptr, sizeof(addr), 0);
292 *ptr++ = ';';
293
294 *ptr++ = __tohex (SP >> 4);
295 *ptr++ = __tohex (SP);
296 *ptr++ = ':';
297 ptr = __mem2hex((char *)&sp, ptr, sizeof(sp), 0);
298 *ptr++ = ';';
299
300 *ptr++ = 0;
301 }
302
303 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS 215 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS