diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2020-07-15 19:40:55 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2020-07-24 21:20:13 +0000 |
commit | 092c340a2062fa98b7387fc5fd63578ddae7d0b6 (patch) | |
tree | 98ec96946eeb2ae709cb0528cc6998e21bb9b290 /gdb/sh-stub.c | |
parent | 17f7cc92c258bc456a27c3e7c5a19c9409851879 (diff) | |
download | rockbox-092c340a2062fa98b7387fc5fd63578ddae7d0b6.tar.gz rockbox-092c340a2062fa98b7387fc5fd63578ddae7d0b6.zip |
[1/4] Remove SH support and all archos targets
This removes all code specific to SH targets
Change-Id: I7980523785d2596e65c06430f4638eec74a06061
Diffstat (limited to 'gdb/sh-stub.c')
-rw-r--r-- | gdb/sh-stub.c | 1618 |
1 files changed, 0 insertions, 1618 deletions
diff --git a/gdb/sh-stub.c b/gdb/sh-stub.c deleted file mode 100644 index 9daca39f72..0000000000 --- a/gdb/sh-stub.c +++ /dev/null | |||
@@ -1,1618 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | /* sh-stub.c -- debugging stub for the Hitachi-SH. | ||
22 | |||
23 | NOTE!! This code has to be compiled with optimization, otherwise the | ||
24 | function inlining which generates the exception handlers won't work. | ||
25 | |||
26 | */ | ||
27 | |||
28 | /* This is originally based on an m68k software stub written by Glenn | ||
29 | Engel at HP, but has changed quite a bit. | ||
30 | |||
31 | Modifications for the SH by Ben Lee and Steve Chamberlain | ||
32 | |||
33 | Even more modifications for GCC 3.0 and The Rockbox by Linus | ||
34 | Nielsen Feltzing | ||
35 | */ | ||
36 | |||
37 | /**************************************************************************** | ||
38 | |||
39 | THIS SOFTWARE IS NOT COPYRIGHTED | ||
40 | |||
41 | HP offers the following for use in the public domain. HP makes no | ||
42 | warranty with regard to the software or it's performance and the | ||
43 | user accepts the software "AS IS" with all faults. | ||
44 | |||
45 | HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD | ||
46 | TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
47 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
48 | |||
49 | ****************************************************************************/ | ||
50 | |||
51 | |||
52 | /* Remote communication protocol. | ||
53 | |||
54 | A debug packet whose contents are <data> | ||
55 | is encapsulated for transmission in the form: | ||
56 | |||
57 | $ <data> # CSUM1 CSUM2 | ||
58 | |||
59 | <data> must be ASCII alphanumeric and cannot include characters | ||
60 | '$' or '#'. If <data> starts with two characters followed by | ||
61 | ':', then the existing stubs interpret this as a sequence number. | ||
62 | |||
63 | CSUM1 and CSUM2 are ascii hex representation of an 8-bit | ||
64 | checksum of <data>, the most significant nibble is sent first. | ||
65 | the hex digits 0-9,a-f are used. | ||
66 | |||
67 | Receiver responds with: | ||
68 | |||
69 | + - if CSUM is correct and ready for next packet | ||
70 | - - if CSUM is incorrect | ||
71 | |||
72 | <data> is as follows: | ||
73 | All values are encoded in ascii hex digits. | ||
74 | |||
75 | Request Packet | ||
76 | |||
77 | read registers g | ||
78 | reply XX....X Each byte of register data | ||
79 | is described by two hex digits. | ||
80 | Registers are in the internal order | ||
81 | for GDB, and the bytes in a register | ||
82 | are in the same order the machine uses. | ||
83 | or ENN for an error. | ||
84 | |||
85 | write regs GXX..XX Each byte of register data | ||
86 | is described by two hex digits. | ||
87 | reply OK for success | ||
88 | ENN for an error | ||
89 | |||
90 | write reg Pn...=r... Write register n... with value r..., | ||
91 | which contains two hex digits for each | ||
92 | byte in the register (target byte | ||
93 | order). | ||
94 | reply OK for success | ||
95 | ENN for an error | ||
96 | (not supported by all stubs). | ||
97 | |||
98 | read mem mAA..AA,LLLL AA..AA is address, LLLL is length. | ||
99 | reply XX..XX XX..XX is mem contents | ||
100 | Can be fewer bytes than requested | ||
101 | if able to read only part of the data. | ||
102 | or ENN NN is errno | ||
103 | |||
104 | write mem MAA..AA,LLLL:XX..XX | ||
105 | AA..AA is address, | ||
106 | LLLL is number of bytes, | ||
107 | XX..XX is data | ||
108 | reply OK for success | ||
109 | ENN for an error (this includes the case | ||
110 | where only part of the data was | ||
111 | written). | ||
112 | |||
113 | cont cAA..AA AA..AA is address to resume | ||
114 | If AA..AA is omitted, | ||
115 | resume at same address. | ||
116 | |||
117 | step sAA..AA AA..AA is address to resume | ||
118 | If AA..AA is omitted, | ||
119 | resume at same address. | ||
120 | |||
121 | last signal ? Reply the current reason for stopping. | ||
122 | This is the same reply as is generated | ||
123 | for step or cont : SAA where AA is the | ||
124 | signal number. | ||
125 | |||
126 | There is no immediate reply to step or cont. | ||
127 | The reply comes when the machine stops. | ||
128 | It is SAA AA is the "signal number" | ||
129 | |||
130 | or... TAAn...:r...;n:r...;n...:r...; | ||
131 | AA = signal number | ||
132 | n... = register number | ||
133 | r... = register contents | ||
134 | or... WAA The process exited, and AA is | ||
135 | the exit status. This is only | ||
136 | applicable for certains sorts of | ||
137 | targets. | ||
138 | kill request k | ||
139 | |||
140 | toggle debug d toggle debug flag (see 386 & 68k stubs) | ||
141 | reset r reset -- see sparc stub. | ||
142 | reserved <other> On other requests, the stub should | ||
143 | ignore the request and send an empty | ||
144 | response ($#<checksum>). This way | ||
145 | we can extend the protocol and GDB | ||
146 | can tell whether the stub it is | ||
147 | talking to uses the old or the new. | ||
148 | search tAA:PP,MM Search backwards starting at address | ||
149 | AA for a match with pattern PP and | ||
150 | mask MM. PP and MM are 4 bytes. | ||
151 | Not supported by all stubs. | ||
152 | |||
153 | general query qXXXX Request info about XXXX. | ||
154 | general set QXXXX=yyyy Set value of XXXX to yyyy. | ||
155 | query sect offs qOffsets Get section offsets. Reply is | ||
156 | Text=xxx;Data=yyy;Bss=zzz | ||
157 | console output Otext Send text to stdout. Only comes from | ||
158 | remote target. | ||
159 | |||
160 | Responses can be run-length encoded to save space. A '*' means that | ||
161 | the next character is an ASCII encoding giving a repeat count which | ||
162 | stands for that many repititions of the character preceding the '*'. | ||
163 | The encoding is n+29, yielding a printable character where n >=3 | ||
164 | (which is where rle starts to win). Don't use an n > 126. | ||
165 | |||
166 | So | ||
167 | "0* " means the same as "0000". */ | ||
168 | |||
169 | #include "sh7034.h" | ||
170 | #include <string.h> | ||
171 | |||
172 | typedef int jmp_buf[20]; | ||
173 | |||
174 | void longjmp(jmp_buf __jmpb, int __retval); | ||
175 | int setjmp(jmp_buf __jmpb); | ||
176 | |||
177 | /* We need to undefine this from the sh7034.h file */ | ||
178 | #undef GBR | ||
179 | |||
180 | /* Hitachi SH architecture instruction encoding masks */ | ||
181 | |||
182 | #define COND_BR_MASK 0xff00 | ||
183 | #define UCOND_DBR_MASK 0xe000 | ||
184 | #define UCOND_RBR_MASK 0xf0df | ||
185 | #define TRAPA_MASK 0xff00 | ||
186 | |||
187 | #define COND_DISP 0x00ff | ||
188 | #define UCOND_DISP 0x0fff | ||
189 | #define UCOND_REG 0x0f00 | ||
190 | |||
191 | /* Hitachi SH instruction opcodes */ | ||
192 | |||
193 | #define BF_INSTR 0x8b00 | ||
194 | #define BT_INSTR 0x8900 | ||
195 | #define BRA_INSTR 0xa000 | ||
196 | #define BSR_INSTR 0xb000 | ||
197 | #define JMP_INSTR 0x402b | ||
198 | #define JSR_INSTR 0x400b | ||
199 | #define RTS_INSTR 0x000b | ||
200 | #define RTE_INSTR 0x002b | ||
201 | #define TRAPA_INSTR 0xc300 | ||
202 | #define SSTEP_INSTR 0xc37f | ||
203 | |||
204 | /* Hitachi SH processor register masks */ | ||
205 | |||
206 | #define T_BIT_MASK 0x0001 | ||
207 | |||
208 | /* | ||
209 | * BUFMAX defines the maximum number of characters in inbound/outbound | ||
210 | * buffers. At least NUMREGBYTES*2 are needed for register packets. | ||
211 | */ | ||
212 | #define BUFMAX 1024 | ||
213 | |||
214 | /* | ||
215 | * Number of bytes for registers | ||
216 | */ | ||
217 | #define NUMREGBYTES 112 /* 92 */ | ||
218 | |||
219 | /* | ||
220 | * Forward declarations | ||
221 | */ | ||
222 | |||
223 | static int hex (char); | ||
224 | static char *mem2hex (char *mem, char *buf, int count); | ||
225 | static char *hex2mem (char *buf, char *mem, int count); | ||
226 | static int hex2int (char **ptr, int *intValue); | ||
227 | static unsigned char *getpacket (void); | ||
228 | static void putpacket (register char *buffer); | ||
229 | static int computeSignal (int exceptionVector); | ||
230 | void handle_buserror (void); | ||
231 | void handle_exception (int exceptionVector); | ||
232 | void init_serial(void); | ||
233 | |||
234 | void serial_putc (char ch); | ||
235 | char serial_getc (void); | ||
236 | |||
237 | /* These are in the file but in asm statements so the compiler can't see them */ | ||
238 | void catch_exception_4 (void); | ||
239 | void catch_exception_5 (void); | ||
240 | void catch_exception_6 (void); | ||
241 | void catch_exception_7 (void); | ||
242 | void catch_exception_8 (void); | ||
243 | void catch_exception_9 (void); | ||
244 | void catch_exception_10 (void); | ||
245 | void catch_exception_11 (void); | ||
246 | void catch_exception_12 (void); | ||
247 | void catch_exception_13 (void); | ||
248 | void catch_exception_14 (void); | ||
249 | void catch_exception_15 (void); | ||
250 | void catch_exception_16 (void); | ||
251 | void catch_exception_17 (void); | ||
252 | void catch_exception_18 (void); | ||
253 | void catch_exception_19 (void); | ||
254 | void catch_exception_20 (void); | ||
255 | void catch_exception_21 (void); | ||
256 | void catch_exception_22 (void); | ||
257 | void catch_exception_23 (void); | ||
258 | void catch_exception_24 (void); | ||
259 | void catch_exception_25 (void); | ||
260 | void catch_exception_26 (void); | ||
261 | void catch_exception_27 (void); | ||
262 | void catch_exception_28 (void); | ||
263 | void catch_exception_29 (void); | ||
264 | void catch_exception_30 (void); | ||
265 | void catch_exception_31 (void); | ||
266 | void catch_exception_32 (void); | ||
267 | void catch_exception_33 (void); | ||
268 | void catch_exception_34 (void); | ||
269 | void catch_exception_35 (void); | ||
270 | void catch_exception_36 (void); | ||
271 | void catch_exception_37 (void); | ||
272 | void catch_exception_38 (void); | ||
273 | void catch_exception_39 (void); | ||
274 | void catch_exception_40 (void); | ||
275 | void catch_exception_41 (void); | ||
276 | void catch_exception_42 (void); | ||
277 | void catch_exception_43 (void); | ||
278 | void catch_exception_44 (void); | ||
279 | void catch_exception_45 (void); | ||
280 | void catch_exception_46 (void); | ||
281 | void catch_exception_47 (void); | ||
282 | void catch_exception_48 (void); | ||
283 | void catch_exception_49 (void); | ||
284 | void catch_exception_50 (void); | ||
285 | void catch_exception_51 (void); | ||
286 | void catch_exception_52 (void); | ||
287 | void catch_exception_53 (void); | ||
288 | void catch_exception_54 (void); | ||
289 | void catch_exception_55 (void); | ||
290 | void catch_exception_56 (void); | ||
291 | void catch_exception_57 (void); | ||
292 | void catch_exception_58 (void); | ||
293 | void catch_exception_59 (void); | ||
294 | void catch_exception_60 (void); | ||
295 | void catch_exception_61 (void); | ||
296 | void catch_exception_62 (void); | ||
297 | void catch_exception_63 (void); | ||
298 | void catch_exception_64 (void); | ||
299 | void catch_exception_65 (void); | ||
300 | void catch_exception_66 (void); | ||
301 | void catch_exception_67 (void); | ||
302 | void catch_exception_68 (void); | ||
303 | void catch_exception_69 (void); | ||
304 | void catch_exception_70 (void); | ||
305 | void catch_exception_71 (void); | ||
306 | void catch_exception_72 (void); | ||
307 | void catch_exception_73 (void); | ||
308 | void catch_exception_74 (void); | ||
309 | void catch_exception_75 (void); | ||
310 | void catch_exception_76 (void); | ||
311 | void catch_exception_77 (void); | ||
312 | void catch_exception_78 (void); | ||
313 | void catch_exception_79 (void); | ||
314 | void catch_exception_80 (void); | ||
315 | void catch_exception_81 (void); | ||
316 | void catch_exception_82 (void); | ||
317 | void catch_exception_83 (void); | ||
318 | void catch_exception_84 (void); | ||
319 | void catch_exception_85 (void); | ||
320 | void catch_exception_86 (void); | ||
321 | void catch_exception_87 (void); | ||
322 | void catch_exception_88 (void); | ||
323 | void catch_exception_89 (void); | ||
324 | void catch_exception_90 (void); | ||
325 | void catch_exception_91 (void); | ||
326 | void catch_exception_92 (void); | ||
327 | void catch_exception_93 (void); | ||
328 | void catch_exception_94 (void); | ||
329 | void catch_exception_95 (void); | ||
330 | void catch_exception_96 (void); | ||
331 | void catch_exception_97 (void); | ||
332 | void catch_exception_98 (void); | ||
333 | void catch_exception_99 (void); | ||
334 | void catch_exception_100 (void); | ||
335 | void catch_exception_101 (void); | ||
336 | void catch_exception_102 (void); | ||
337 | void catch_exception_103 (void); | ||
338 | void catch_exception_104 (void); | ||
339 | void catch_exception_105 (void); | ||
340 | void catch_exception_106 (void); | ||
341 | void catch_exception_107 (void); | ||
342 | void catch_exception_108 (void); | ||
343 | void catch_exception_109 (void); | ||
344 | void catch_exception_110 (void); | ||
345 | void catch_exception_111 (void); | ||
346 | void catch_exception_112 (void); | ||
347 | void catch_exception_113 (void); | ||
348 | void catch_exception_114 (void); | ||
349 | void catch_exception_115 (void); | ||
350 | void catch_exception_116 (void); | ||
351 | void catch_exception_117 (void); | ||
352 | void catch_exception_118 (void); | ||
353 | void catch_exception_119 (void); | ||
354 | void catch_exception_120 (void); | ||
355 | void catch_exception_121 (void); | ||
356 | void catch_exception_122 (void); | ||
357 | void catch_exception_123 (void); | ||
358 | void catch_exception_124 (void); | ||
359 | void catch_exception_125 (void); | ||
360 | void catch_exception_126 (void); | ||
361 | void catch_exception_127 (void); | ||
362 | |||
363 | void breakpoint (void); | ||
364 | |||
365 | |||
366 | //#define stub_stack_size 2*1024 | ||
367 | |||
368 | //int stub_stack[stub_stack_size] __attribute__ ((section (".stack"))) = {0}; | ||
369 | |||
370 | extern int stub_stack[]; | ||
371 | |||
372 | void INIT (void); | ||
373 | void start (void); | ||
374 | |||
375 | #define CPU_BUS_ERROR_VEC 9 | ||
376 | #define DMA_BUS_ERROR_VEC 10 | ||
377 | #define NMI_VEC 11 | ||
378 | #define INVALID_INSN_VEC 4 | ||
379 | #define INVALID_SLOT_VEC 6 | ||
380 | #define TRAP_VEC 32 | ||
381 | #define IO_VEC 33 | ||
382 | #define USER_VEC 127 | ||
383 | |||
384 | static char in_nmi; /* Set when handling an NMI, so we don't reenter */ | ||
385 | static int dofault; /* Non zero, bus errors will raise exception */ | ||
386 | |||
387 | static int *stub_sp; | ||
388 | |||
389 | /* debug > 0 prints ill-formed commands in valid packets & checksum errors */ | ||
390 | static int remote_debug; | ||
391 | |||
392 | /* jump buffer used for setjmp/longjmp */ | ||
393 | static jmp_buf remcomEnv; | ||
394 | |||
395 | enum regnames | ||
396 | { | ||
397 | R0, R1, R2, R3, R4, R5, R6, R7, | ||
398 | R8, R9, R10, R11, R12, R13, R14, | ||
399 | R15, PC, PR, GBR, VBR, MACH, MACL, SR, | ||
400 | TICKS, STALLS, CYCLES, INSTS, PLR | ||
401 | }; | ||
402 | |||
403 | typedef struct | ||
404 | { | ||
405 | short *memAddr; | ||
406 | short oldInstr; | ||
407 | } | ||
408 | stepData; | ||
409 | |||
410 | static int registers[NUMREGBYTES / 4]; | ||
411 | static stepData instrBuffer; | ||
412 | static char stepped; | ||
413 | static const char hexchars[] = "0123456789abcdef"; | ||
414 | static char remcomInBuffer[BUFMAX]; | ||
415 | static char remcomOutBuffer[BUFMAX]; | ||
416 | |||
417 | #define ATA_NSECTOR (*((volatile unsigned char*)0x06100102)) | ||
418 | #define ATA_COMMAND (*((volatile unsigned char*)0x06100107)) | ||
419 | |||
420 | /* You may need to change this depending on your ATA I/O address | ||
421 | ** 0x200 - 0x06200206 | ||
422 | ** 0x300 - 0x06200306 | ||
423 | */ | ||
424 | #define ATA_CONTROL (*((volatile unsigned char*)0x06200206)) | ||
425 | #define ATA_ALT_STATUS ATA_CONTROL | ||
426 | |||
427 | #define STATUS_BSY 0x80 | ||
428 | #define STATUS_RDY 0x40 | ||
429 | |||
430 | #define CMD_STANDBY_IMMEDIATE 0xE0 | ||
431 | #define CMD_STANDBY 0xE2 | ||
432 | |||
433 | void ata_wait_for_bsy(void) | ||
434 | { | ||
435 | while (ATA_ALT_STATUS & STATUS_BSY); | ||
436 | } | ||
437 | |||
438 | int ata_wait_for_rdy(void) | ||
439 | { | ||
440 | ata_wait_for_bsy(); | ||
441 | return ATA_ALT_STATUS & STATUS_RDY; | ||
442 | } | ||
443 | |||
444 | int ata_spindown(int time) | ||
445 | { | ||
446 | /* Port A setup */ | ||
447 | PAIOR |= 0x0280; /* output for ATA reset, IDE enable */ | ||
448 | PADR |= 0x0200; /* release ATA reset */ | ||
449 | PACR2 &= 0xBFFF; /* GPIO function for PA7 (IDE enable) */ | ||
450 | |||
451 | /* activate ATA */ | ||
452 | PADR &= ~0x80; | ||
453 | |||
454 | if(!ata_wait_for_rdy()) | ||
455 | return -1; | ||
456 | |||
457 | if ( time == -1 ) { | ||
458 | ATA_COMMAND = CMD_STANDBY_IMMEDIATE; | ||
459 | } | ||
460 | else { | ||
461 | if (time > 255) | ||
462 | return -1; | ||
463 | ATA_NSECTOR = time & 0xff; | ||
464 | ATA_COMMAND = CMD_STANDBY; | ||
465 | } | ||
466 | |||
467 | if (!ata_wait_for_rdy()) | ||
468 | return -1; | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | void blink(void) | ||
474 | { | ||
475 | while(1) | ||
476 | { | ||
477 | int i; | ||
478 | PBDR ^= 0x40; /* toggle PB6 */ | ||
479 | for(i = 0;i < 500000;i++) | ||
480 | { | ||
481 | } | ||
482 | } | ||
483 | } | ||
484 | |||
485 | char highhex(int x) | ||
486 | { | ||
487 | return hexchars[(x >> 4) & 0xf]; | ||
488 | } | ||
489 | |||
490 | char lowhex(int x) | ||
491 | { | ||
492 | return hexchars[x & 0xf]; | ||
493 | } | ||
494 | |||
495 | /* | ||
496 | * Assembly macros | ||
497 | */ | ||
498 | |||
499 | #define BREAKPOINT() asm("trapa #0x20"::); | ||
500 | |||
501 | |||
502 | /* | ||
503 | * Routines to handle hex data | ||
504 | */ | ||
505 | |||
506 | static int hex (char ch) | ||
507 | { | ||
508 | if ((ch >= 'a') && (ch <= 'f')) | ||
509 | return (ch - 'a' + 10); | ||
510 | if ((ch >= '0') && (ch <= '9')) | ||
511 | return (ch - '0'); | ||
512 | if ((ch >= 'A') && (ch <= 'F')) | ||
513 | return (ch - 'A' + 10); | ||
514 | return (-1); | ||
515 | } | ||
516 | |||
517 | /* convert the memory, pointed to by mem into hex, placing result in buf */ | ||
518 | /* return a pointer to the last char put in buf (null) */ | ||
519 | static char *mem2hex (char *mem, char *buf, int count) | ||
520 | { | ||
521 | int i; | ||
522 | int ch; | ||
523 | for (i = 0; i < count; i++) | ||
524 | { | ||
525 | ch = *mem++; | ||
526 | *buf++ = highhex (ch); | ||
527 | *buf++ = lowhex (ch); | ||
528 | } | ||
529 | *buf = 0; | ||
530 | return (buf); | ||
531 | } | ||
532 | |||
533 | /* convert the hex array pointed to by buf into binary, to be placed in mem */ | ||
534 | /* return a pointer to the character after the last byte written */ | ||
535 | static char *hex2mem (char *buf, char *mem, int count) | ||
536 | { | ||
537 | int i; | ||
538 | unsigned char ch; | ||
539 | for (i = 0; i < count; i++) | ||
540 | { | ||
541 | ch = hex (*buf++) << 4; | ||
542 | ch = ch + hex (*buf++); | ||
543 | *mem++ = ch; | ||
544 | } | ||
545 | return (mem); | ||
546 | } | ||
547 | |||
548 | /**********************************************/ | ||
549 | /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ | ||
550 | /* RETURN NUMBER OF CHARS PROCESSED */ | ||
551 | /**********************************************/ | ||
552 | static int hex2int (char **ptr, int *intValue) | ||
553 | { | ||
554 | int numChars = 0; | ||
555 | int hexValue; | ||
556 | |||
557 | *intValue = 0; | ||
558 | |||
559 | while (**ptr) | ||
560 | { | ||
561 | hexValue = hex (**ptr); | ||
562 | if (hexValue >= 0) | ||
563 | { | ||
564 | *intValue = (*intValue << 4) | hexValue; | ||
565 | numChars++; | ||
566 | } | ||
567 | else | ||
568 | break; | ||
569 | |||
570 | (*ptr)++; | ||
571 | } | ||
572 | |||
573 | return (numChars); | ||
574 | } | ||
575 | |||
576 | /* | ||
577 | * Routines to get and put packets | ||
578 | */ | ||
579 | |||
580 | /* scan for the sequence $<data>#<checksum> */ | ||
581 | |||
582 | unsigned char *getpacket (void) | ||
583 | { | ||
584 | unsigned char *buffer = &remcomInBuffer[0]; | ||
585 | unsigned char checksum; | ||
586 | unsigned char xmitcsum; | ||
587 | int count; | ||
588 | char ch; | ||
589 | |||
590 | while (1) | ||
591 | { | ||
592 | /* wait around for the start character, ignore all other characters */ | ||
593 | while ((ch = serial_getc ()) != '$') | ||
594 | ; | ||
595 | |||
596 | retry: | ||
597 | checksum = 0; | ||
598 | xmitcsum = -1; | ||
599 | count = 0; | ||
600 | |||
601 | /* now, read until a # or end of buffer is found */ | ||
602 | while (count < BUFMAX) | ||
603 | { | ||
604 | ch = serial_getc (); | ||
605 | if (ch == '$') | ||
606 | goto retry; | ||
607 | if (ch == '#') | ||
608 | break; | ||
609 | checksum = checksum + ch; | ||
610 | buffer[count] = ch; | ||
611 | count = count + 1; | ||
612 | } | ||
613 | buffer[count] = 0; | ||
614 | |||
615 | if (ch == '#') | ||
616 | { | ||
617 | ch = serial_getc (); | ||
618 | xmitcsum = hex (ch) << 4; | ||
619 | ch = serial_getc (); | ||
620 | xmitcsum += hex (ch); | ||
621 | |||
622 | if (checksum != xmitcsum) | ||
623 | { | ||
624 | serial_putc ('-'); /* failed checksum */ | ||
625 | } | ||
626 | else | ||
627 | { | ||
628 | serial_putc ('+'); /* successful transfer */ | ||
629 | |||
630 | /* if a sequence char is present, reply the sequence ID */ | ||
631 | if (buffer[2] == ':') | ||
632 | { | ||
633 | serial_putc (buffer[0]); | ||
634 | serial_putc (buffer[1]); | ||
635 | |||
636 | return &buffer[3]; | ||
637 | } | ||
638 | |||
639 | return &buffer[0]; | ||
640 | } | ||
641 | } | ||
642 | } | ||
643 | } | ||
644 | |||
645 | |||
646 | /* send the packet in buffer. */ | ||
647 | |||
648 | static void putpacket (register char *buffer) | ||
649 | { | ||
650 | register int checksum; | ||
651 | |||
652 | /* $<packet info>#<checksum>. */ | ||
653 | do | ||
654 | { | ||
655 | char *src = buffer; | ||
656 | serial_putc ('$'); | ||
657 | checksum = 0; | ||
658 | |||
659 | while (*src) | ||
660 | { | ||
661 | int runlen; | ||
662 | |||
663 | /* Do run length encoding */ | ||
664 | for (runlen = 0; runlen < 100; runlen ++) | ||
665 | { | ||
666 | if (src[0] != src[runlen] || runlen == 99) | ||
667 | { | ||
668 | if (runlen > 3) | ||
669 | { | ||
670 | int encode; | ||
671 | /* Got a useful amount */ | ||
672 | serial_putc (*src); | ||
673 | checksum += *src; | ||
674 | serial_putc ('*'); | ||
675 | checksum += '*'; | ||
676 | checksum += (encode = runlen + ' ' - 4); | ||
677 | serial_putc (encode); | ||
678 | src += runlen; | ||
679 | } | ||
680 | else | ||
681 | { | ||
682 | serial_putc (*src); | ||
683 | checksum += *src; | ||
684 | src++; | ||
685 | } | ||
686 | break; | ||
687 | } | ||
688 | } | ||
689 | } | ||
690 | |||
691 | |||
692 | serial_putc ('#'); | ||
693 | serial_putc (highhex(checksum)); | ||
694 | serial_putc (lowhex(checksum)); | ||
695 | } | ||
696 | while (serial_getc() != '+'); | ||
697 | } | ||
698 | |||
699 | |||
700 | /* a bus error has occurred, perform a longjmp | ||
701 | to return execution and allow handling of the error */ | ||
702 | |||
703 | void handle_buserror (void) | ||
704 | { | ||
705 | longjmp (remcomEnv, 1); | ||
706 | } | ||
707 | |||
708 | #define SIGINT 2 /* interrupt */ | ||
709 | #define SIGILL 4 /* illegal instruction (not reset when caught) */ | ||
710 | #define SIGTRAP 5 /* trace trap (not reset when caught) */ | ||
711 | #define SIGEMT 7 /* EMT instruction */ | ||
712 | #define SIGBUS 10 /* bus error */ | ||
713 | |||
714 | /* | ||
715 | * this function takes the SH-1 exception number and attempts to | ||
716 | * translate this number into a unix compatible signal value | ||
717 | */ | ||
718 | static int computeSignal (int exceptionVector) | ||
719 | { | ||
720 | int sigval; | ||
721 | switch (exceptionVector) | ||
722 | { | ||
723 | case INVALID_INSN_VEC: | ||
724 | sigval = SIGILL; | ||
725 | break; | ||
726 | case INVALID_SLOT_VEC: | ||
727 | sigval = SIGILL; | ||
728 | break; | ||
729 | case CPU_BUS_ERROR_VEC: | ||
730 | sigval = SIGBUS; | ||
731 | break; | ||
732 | case DMA_BUS_ERROR_VEC: | ||
733 | sigval = SIGBUS; | ||
734 | break; | ||
735 | case NMI_VEC: | ||
736 | sigval = SIGINT; | ||
737 | break; | ||
738 | |||
739 | case TRAP_VEC: | ||
740 | case USER_VEC: | ||
741 | sigval = SIGTRAP; | ||
742 | break; | ||
743 | |||
744 | default: | ||
745 | sigval = SIGEMT; /* "software generated"*/ | ||
746 | break; | ||
747 | } | ||
748 | return (sigval); | ||
749 | } | ||
750 | |||
751 | void doSStep (void) | ||
752 | { | ||
753 | short *instrMem; | ||
754 | int displacement; | ||
755 | int reg; | ||
756 | unsigned short opcode; | ||
757 | |||
758 | instrMem = (short *) registers[PC]; | ||
759 | |||
760 | opcode = *instrMem; | ||
761 | stepped = 1; | ||
762 | |||
763 | if ((opcode & COND_BR_MASK) == BT_INSTR) | ||
764 | { | ||
765 | if (registers[SR] & T_BIT_MASK) | ||
766 | { | ||
767 | displacement = (opcode & COND_DISP) << 1; | ||
768 | if (displacement & 0x80) | ||
769 | displacement |= 0xffffff00; | ||
770 | /* | ||
771 | * Remember PC points to second instr. | ||
772 | * after PC of branch ... so add 4 | ||
773 | */ | ||
774 | instrMem = (short *) (registers[PC] + displacement + 4); | ||
775 | } | ||
776 | else | ||
777 | instrMem += 1; | ||
778 | } | ||
779 | else if ((opcode & COND_BR_MASK) == BF_INSTR) | ||
780 | { | ||
781 | if (registers[SR] & T_BIT_MASK) | ||
782 | instrMem += 1; | ||
783 | else | ||
784 | { | ||
785 | displacement = (opcode & COND_DISP) << 1; | ||
786 | if (displacement & 0x80) | ||
787 | displacement |= 0xffffff00; | ||
788 | /* | ||
789 | * Remember PC points to second instr. | ||
790 | * after PC of branch ... so add 4 | ||
791 | */ | ||
792 | instrMem = (short *) (registers[PC] + displacement + 4); | ||
793 | } | ||
794 | } | ||
795 | else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR) | ||
796 | { | ||
797 | displacement = (opcode & UCOND_DISP) << 1; | ||
798 | if (displacement & 0x0800) | ||
799 | displacement |= 0xfffff000; | ||
800 | |||
801 | /* | ||
802 | * Remember PC points to second instr. | ||
803 | * after PC of branch ... so add 4 | ||
804 | */ | ||
805 | instrMem = (short *) (registers[PC] + displacement + 4); | ||
806 | } | ||
807 | else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR) | ||
808 | { | ||
809 | reg = (char) ((opcode & UCOND_REG) >> 8); | ||
810 | |||
811 | instrMem = (short *) registers[reg]; | ||
812 | } | ||
813 | else if (opcode == RTS_INSTR) | ||
814 | instrMem = (short *) registers[PR]; | ||
815 | else if (opcode == RTE_INSTR) | ||
816 | instrMem = (short *) registers[15]; | ||
817 | else if ((opcode & TRAPA_MASK) == TRAPA_INSTR) | ||
818 | instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2); | ||
819 | else | ||
820 | instrMem += 1; | ||
821 | |||
822 | instrBuffer.memAddr = instrMem; | ||
823 | instrBuffer.oldInstr = *instrMem; | ||
824 | *instrMem = SSTEP_INSTR; | ||
825 | } | ||
826 | |||
827 | |||
828 | /* Undo the effect of a previous doSStep. If we single stepped, | ||
829 | restore the old instruction. */ | ||
830 | void undoSStep (void) | ||
831 | { | ||
832 | if (stepped) | ||
833 | { | ||
834 | short *instrMem; | ||
835 | instrMem = instrBuffer.memAddr; | ||
836 | *instrMem = instrBuffer.oldInstr; | ||
837 | } | ||
838 | stepped = 0; | ||
839 | } | ||
840 | |||
841 | /* | ||
842 | * This function does all exception handling. It only does two things - | ||
843 | * it figures out why it was called and tells gdb, and then it reacts | ||
844 | * to gdb's requests. | ||
845 | * | ||
846 | */ | ||
847 | void gdb_handle_exception (int exceptionVector) | ||
848 | { | ||
849 | int sigval, stepping; | ||
850 | int addr, length; | ||
851 | char *ptr; | ||
852 | |||
853 | /* reply to host that an exception has occurred */ | ||
854 | sigval = computeSignal (exceptionVector); | ||
855 | remcomOutBuffer[0] = 'S'; | ||
856 | remcomOutBuffer[1] = highhex(sigval); | ||
857 | remcomOutBuffer[2] = lowhex (sigval); | ||
858 | remcomOutBuffer[3] = 0; | ||
859 | |||
860 | putpacket (remcomOutBuffer); | ||
861 | |||
862 | /* | ||
863 | * exception 127 indicates a software trap | ||
864 | * inserted in place of code ... so back up | ||
865 | * PC by one instruction, since this instruction | ||
866 | * will later be replaced by its original one! | ||
867 | */ | ||
868 | if (exceptionVector == USER_VEC | ||
869 | || exceptionVector == TRAP_VEC) | ||
870 | registers[PC] -= 2; | ||
871 | |||
872 | /* | ||
873 | * Do the things needed to undo | ||
874 | * any stepping we may have done! | ||
875 | */ | ||
876 | undoSStep (); | ||
877 | |||
878 | stepping = 0; | ||
879 | |||
880 | while (1) | ||
881 | { | ||
882 | remcomOutBuffer[0] = 0; | ||
883 | ptr = getpacket (); | ||
884 | |||
885 | switch (*ptr++) | ||
886 | { | ||
887 | case '?': | ||
888 | remcomOutBuffer[0] = 'S'; | ||
889 | remcomOutBuffer[1] = highhex (sigval); | ||
890 | remcomOutBuffer[2] = lowhex (sigval); | ||
891 | remcomOutBuffer[3] = 0; | ||
892 | break; | ||
893 | case 'd': | ||
894 | remote_debug = !(remote_debug); /* toggle debug flag */ | ||
895 | break; | ||
896 | case 'g': /* return the value of the CPU registers */ | ||
897 | mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES); | ||
898 | break; | ||
899 | case 'G': /* set the value of the CPU registers - return OK */ | ||
900 | hex2mem (ptr, (char *) registers, NUMREGBYTES); | ||
901 | strcpy (remcomOutBuffer, "OK"); | ||
902 | break; | ||
903 | |||
904 | /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ | ||
905 | case 'm': | ||
906 | if (setjmp (remcomEnv) == 0) | ||
907 | { | ||
908 | dofault = 0; | ||
909 | /* TRY, TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ | ||
910 | if (hex2int (&ptr, &addr)) | ||
911 | if (*(ptr++) == ',') | ||
912 | if (hex2int (&ptr, &length)) | ||
913 | { | ||
914 | ptr = 0; | ||
915 | mem2hex ((char *) addr, remcomOutBuffer, length); | ||
916 | } | ||
917 | if (ptr) | ||
918 | strcpy (remcomOutBuffer, "E01"); | ||
919 | } | ||
920 | else | ||
921 | strcpy (remcomOutBuffer, "E03"); | ||
922 | |||
923 | /* restore handler for bus error */ | ||
924 | dofault = 1; | ||
925 | break; | ||
926 | |||
927 | /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ | ||
928 | case 'M': | ||
929 | if (setjmp (remcomEnv) == 0) | ||
930 | { | ||
931 | dofault = 0; | ||
932 | |||
933 | /* TRY, TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ | ||
934 | if (hex2int (&ptr, &addr)) | ||
935 | if (*(ptr++) == ',') | ||
936 | if (hex2int (&ptr, &length)) | ||
937 | if (*(ptr++) == ':') | ||
938 | { | ||
939 | hex2mem (ptr, (char *) addr, length); | ||
940 | ptr = 0; | ||
941 | strcpy (remcomOutBuffer, "OK"); | ||
942 | } | ||
943 | if (ptr) | ||
944 | strcpy (remcomOutBuffer, "E02"); | ||
945 | } | ||
946 | else | ||
947 | strcpy (remcomOutBuffer, "E03"); | ||
948 | |||
949 | /* restore handler for bus error */ | ||
950 | dofault = 1; | ||
951 | break; | ||
952 | |||
953 | /* cAA..AA Continue at address AA..AA(optional) */ | ||
954 | /* sAA..AA Step one instruction from AA..AA(optional) */ | ||
955 | case 's': | ||
956 | stepping = 1; | ||
957 | case 'c': | ||
958 | { | ||
959 | /* tRY, to read optional parameter, pc unchanged if no parm */ | ||
960 | if (hex2int (&ptr, &addr)) | ||
961 | registers[PC] = addr; | ||
962 | |||
963 | if (stepping) | ||
964 | doSStep (); | ||
965 | } | ||
966 | |||
967 | return; | ||
968 | break; | ||
969 | |||
970 | /* kill the program */ | ||
971 | case 'k': /* do nothing */ | ||
972 | break; | ||
973 | |||
974 | default: | ||
975 | break; | ||
976 | } /* switch */ | ||
977 | |||
978 | /* reply to the request */ | ||
979 | putpacket (remcomOutBuffer); | ||
980 | } | ||
981 | } | ||
982 | |||
983 | |||
984 | /* We've had an exception - go into the gdb stub */ | ||
985 | void handle_exception(int exceptionVector) | ||
986 | { | ||
987 | gdb_handle_exception (exceptionVector); | ||
988 | } | ||
989 | |||
990 | /* This function will generate a breakpoint exception. It is used at the | ||
991 | beginning of a program to sync up with a debugger and can be used | ||
992 | otherwise as a quick means to stop program execution and "break" into | ||
993 | the debugger. */ | ||
994 | void breakpoint (void) | ||
995 | { | ||
996 | BREAKPOINT (); | ||
997 | } | ||
998 | |||
999 | /**** Processor-specific routines start here ****/ | ||
1000 | /**** Processor-specific routines start here ****/ | ||
1001 | /**** Processor-specific routines start here ****/ | ||
1002 | |||
1003 | extern int stack[]; | ||
1004 | |||
1005 | /* SH1/SH2 exception vector table format */ | ||
1006 | typedef struct | ||
1007 | { | ||
1008 | void (*func_cold) (void); | ||
1009 | int *stack_cold; | ||
1010 | void (*func_warm) (void); | ||
1011 | int *stack_warm; | ||
1012 | void (*(handler[128 - 4])) (void); | ||
1013 | } vec_type; | ||
1014 | |||
1015 | /* vectable is the SH1/SH2 vector table. It must be at address 0 | ||
1016 | ** or wherever your vbr points. | ||
1017 | ** Note that we only define the first 128 vectors, since the Jukebox | ||
1018 | ** firmware has its entry point at 0x200 | ||
1019 | */ | ||
1020 | const vec_type vectable __attribute__ ((section (".vectors"))) = | ||
1021 | { | ||
1022 | &start, /* 0: Power-on reset PC */ | ||
1023 | stack, /* 1: Power-on reset SP */ | ||
1024 | &start, /* 2: Manual reset PC */ | ||
1025 | stack, /* 3: Manual reset SP */ | ||
1026 | { | ||
1027 | &catch_exception_4, /* 4: General invalid instruction */ | ||
1028 | &catch_exception_5, /* 5: Reserved for system */ | ||
1029 | &catch_exception_6, /* 6: Invalid slot instruction */ | ||
1030 | &catch_exception_7, /* 7: Reserved for system */ | ||
1031 | &catch_exception_8, /* 8: Reserved for system */ | ||
1032 | &catch_exception_9, /* 9: CPU bus error */ | ||
1033 | &catch_exception_10, /* 10: DMA bus error */ | ||
1034 | &catch_exception_11, /* 11: NMI */ | ||
1035 | &catch_exception_12, /* 12: User break */ | ||
1036 | &catch_exception_13, /* 13: Reserved for system */ | ||
1037 | &catch_exception_14, /* 14: Reserved for system */ | ||
1038 | &catch_exception_15, /* 15: Reserved for system */ | ||
1039 | &catch_exception_16, /* 16: Reserved for system */ | ||
1040 | &catch_exception_17, /* 17: Reserved for system */ | ||
1041 | &catch_exception_18, /* 18: Reserved for system */ | ||
1042 | &catch_exception_19, /* 19: Reserved for system */ | ||
1043 | &catch_exception_20, /* 20: Reserved for system */ | ||
1044 | &catch_exception_21, /* 21: Reserved for system */ | ||
1045 | &catch_exception_22, /* 22: Reserved for system */ | ||
1046 | &catch_exception_23, /* 23: Reserved for system */ | ||
1047 | &catch_exception_24, /* 24: Reserved for system */ | ||
1048 | &catch_exception_25, /* 25: Reserved for system */ | ||
1049 | &catch_exception_26, /* 26: Reserved for system */ | ||
1050 | &catch_exception_27, /* 27: Reserved for system */ | ||
1051 | &catch_exception_28, /* 28: Reserved for system */ | ||
1052 | &catch_exception_29, /* 29: Reserved for system */ | ||
1053 | &catch_exception_30, /* 30: Reserved for system */ | ||
1054 | &catch_exception_31, /* 31: Reserved for system */ | ||
1055 | &catch_exception_32, /* 32: Trap instr (user vectors) */ | ||
1056 | &catch_exception_33, /* 33: Trap instr (user vectors) */ | ||
1057 | &catch_exception_34, /* 34: Trap instr (user vectors) */ | ||
1058 | &catch_exception_35, /* 35: Trap instr (user vectors) */ | ||
1059 | &catch_exception_36, /* 36: Trap instr (user vectors) */ | ||
1060 | &catch_exception_37, /* 37: Trap instr (user vectors) */ | ||
1061 | &catch_exception_38, /* 38: Trap instr (user vectors) */ | ||
1062 | &catch_exception_39, /* 39: Trap instr (user vectors) */ | ||
1063 | &catch_exception_40, /* 40: Trap instr (user vectors) */ | ||
1064 | &catch_exception_41, /* 41: Trap instr (user vectors) */ | ||
1065 | &catch_exception_42, /* 42: Trap instr (user vectors) */ | ||
1066 | &catch_exception_43, /* 43: Trap instr (user vectors) */ | ||
1067 | &catch_exception_44, /* 44: Trap instr (user vectors) */ | ||
1068 | &catch_exception_45, /* 45: Trap instr (user vectors) */ | ||
1069 | &catch_exception_46, /* 46: Trap instr (user vectors) */ | ||
1070 | &catch_exception_47, /* 47: Trap instr (user vectors) */ | ||
1071 | &catch_exception_48, /* 48: Trap instr (user vectors) */ | ||
1072 | &catch_exception_49, /* 49: Trap instr (user vectors) */ | ||
1073 | &catch_exception_50, /* 50: Trap instr (user vectors) */ | ||
1074 | &catch_exception_51, /* 51: Trap instr (user vectors) */ | ||
1075 | &catch_exception_52, /* 52: Trap instr (user vectors) */ | ||
1076 | &catch_exception_53, /* 53: Trap instr (user vectors) */ | ||
1077 | &catch_exception_54, /* 54: Trap instr (user vectors) */ | ||
1078 | &catch_exception_55, /* 55: Trap instr (user vectors) */ | ||
1079 | &catch_exception_56, /* 56: Trap instr (user vectors) */ | ||
1080 | &catch_exception_57, /* 57: Trap instr (user vectors) */ | ||
1081 | &catch_exception_58, /* 58: Trap instr (user vectors) */ | ||
1082 | &catch_exception_59, /* 59: Trap instr (user vectors) */ | ||
1083 | &catch_exception_60, /* 60: Trap instr (user vectors) */ | ||
1084 | &catch_exception_61, /* 61: Trap instr (user vectors) */ | ||
1085 | &catch_exception_62, /* 62: Trap instr (user vectors) */ | ||
1086 | &catch_exception_63, /* 63: Trap instr (user vectors) */ | ||
1087 | &catch_exception_64, /* 64: IRQ0 */ | ||
1088 | &catch_exception_65, /* 65: IRQ1 */ | ||
1089 | &catch_exception_66, /* 66: IRQ2 */ | ||
1090 | &catch_exception_67, /* 67: IRQ3 */ | ||
1091 | &catch_exception_68, /* 68: IRQ4 */ | ||
1092 | &catch_exception_69, /* 69: IRQ5 */ | ||
1093 | &catch_exception_70, /* 70: IRQ6 */ | ||
1094 | &catch_exception_71, /* 71: IRQ7 */ | ||
1095 | &catch_exception_72, | ||
1096 | &catch_exception_73, | ||
1097 | &catch_exception_74, | ||
1098 | &catch_exception_75, | ||
1099 | &catch_exception_76, | ||
1100 | &catch_exception_77, | ||
1101 | &catch_exception_78, | ||
1102 | &catch_exception_79, | ||
1103 | &catch_exception_80, | ||
1104 | &catch_exception_81, | ||
1105 | &catch_exception_82, | ||
1106 | &catch_exception_83, | ||
1107 | &catch_exception_84, | ||
1108 | &catch_exception_85, | ||
1109 | &catch_exception_86, | ||
1110 | &catch_exception_87, | ||
1111 | &catch_exception_88, | ||
1112 | &catch_exception_89, | ||
1113 | &catch_exception_90, | ||
1114 | &catch_exception_91, | ||
1115 | &catch_exception_92, | ||
1116 | &catch_exception_93, | ||
1117 | &catch_exception_94, | ||
1118 | &catch_exception_95, | ||
1119 | &catch_exception_96, | ||
1120 | &catch_exception_97, | ||
1121 | &catch_exception_98, | ||
1122 | &catch_exception_99, | ||
1123 | &catch_exception_100, | ||
1124 | &catch_exception_101, | ||
1125 | &catch_exception_102, | ||
1126 | &catch_exception_103, | ||
1127 | &catch_exception_104, | ||
1128 | &catch_exception_105, | ||
1129 | &catch_exception_106, | ||
1130 | &catch_exception_107, | ||
1131 | &catch_exception_108, | ||
1132 | &catch_exception_109, | ||
1133 | &catch_exception_110, | ||
1134 | &catch_exception_111, | ||
1135 | &catch_exception_112, | ||
1136 | &catch_exception_113, | ||
1137 | &catch_exception_114, | ||
1138 | &catch_exception_115, | ||
1139 | &catch_exception_116, | ||
1140 | &catch_exception_117, | ||
1141 | &catch_exception_118, | ||
1142 | &catch_exception_119, | ||
1143 | &catch_exception_120, | ||
1144 | &catch_exception_121, | ||
1145 | &catch_exception_122, | ||
1146 | &catch_exception_123, | ||
1147 | &catch_exception_124, | ||
1148 | &catch_exception_125, | ||
1149 | &catch_exception_126, | ||
1150 | &catch_exception_127}}; | ||
1151 | |||
1152 | void INIT (void) | ||
1153 | { | ||
1154 | /* Disable all timer interrupts */ | ||
1155 | TIER0 = 0; | ||
1156 | TIER1 = 0; | ||
1157 | TIER2 = 0; | ||
1158 | TIER3 = 0; | ||
1159 | TIER4 = 0; | ||
1160 | |||
1161 | init_serial(); | ||
1162 | |||
1163 | in_nmi = 0; | ||
1164 | dofault = 1; | ||
1165 | stepped = 0; | ||
1166 | |||
1167 | ata_spindown(-1); | ||
1168 | |||
1169 | stub_sp = stub_stack; | ||
1170 | breakpoint (); | ||
1171 | |||
1172 | /* We should never come here */ | ||
1173 | blink(); | ||
1174 | } | ||
1175 | |||
1176 | void sr(void) | ||
1177 | { | ||
1178 | /* Calling Reset does the same as pressing the button */ | ||
1179 | asm (".global _Reset\n" | ||
1180 | " .global _WarmReset\n" | ||
1181 | "_Reset:\n" | ||
1182 | "_WarmReset:\n" | ||
1183 | " mov.l L_sp,r15\n" | ||
1184 | " bra _INIT\n" | ||
1185 | " nop\n" | ||
1186 | " .align 2\n" | ||
1187 | "L_sp: .long _stack"); | ||
1188 | |||
1189 | asm("saveRegisters:\n"); | ||
1190 | asm(" mov.l @(L_reg, pc), r0\n" | ||
1191 | " mov.l @r15+, r1 ! pop R0\n" | ||
1192 | " mov.l r2, @(0x08, r0) ! save R2\n" | ||
1193 | " mov.l r1, @r0 ! save R0\n" | ||
1194 | " mov.l @r15+, r1 ! pop R1\n" | ||
1195 | " mov.l r3, @(0x0c, r0) ! save R3\n" | ||
1196 | " mov.l r1, @(0x04, r0) ! save R1\n" | ||
1197 | " mov.l r4, @(0x10, r0) ! save R4\n" | ||
1198 | " mov.l r5, @(0x14, r0) ! save R5\n" | ||
1199 | " mov.l r6, @(0x18, r0) ! save R6\n" | ||
1200 | " mov.l r7, @(0x1c, r0) ! save R7\n" | ||
1201 | " mov.l r8, @(0x20, r0) ! save R8\n" | ||
1202 | " mov.l r9, @(0x24, r0) ! save R9\n" | ||
1203 | " mov.l r10, @(0x28, r0) ! save R10\n" | ||
1204 | " mov.l r11, @(0x2c, r0) ! save R11\n" | ||
1205 | " mov.l r12, @(0x30, r0) ! save R12\n" | ||
1206 | " mov.l r13, @(0x34, r0) ! save R13\n" | ||
1207 | " mov.l r14, @(0x38, r0) ! save R14\n" | ||
1208 | " mov.l @r15+, r4 ! save arg to handleException\n" | ||
1209 | " add #8, r15 ! hide PC/SR values on stack\n" | ||
1210 | " mov.l r15, @(0x3c, r0) ! save R15\n" | ||
1211 | " add #-8, r15 ! save still needs old SP value\n" | ||
1212 | " add #92, r0 ! readjust register pointer\n" | ||
1213 | " mov r15, r2\n" | ||
1214 | " add #4, r2\n" | ||
1215 | " mov.l @r2, r2 ! R2 has SR\n" | ||
1216 | " mov.l @r15, r1 ! R1 has PC\n" | ||
1217 | " mov.l r2, @-r0 ! save SR\n" | ||
1218 | " sts.l macl, @-r0 ! save MACL\n" | ||
1219 | " sts.l mach, @-r0 ! save MACH\n" | ||
1220 | " stc.l vbr, @-r0 ! save VBR\n" | ||
1221 | " stc.l gbr, @-r0 ! save GBR\n" | ||
1222 | " sts.l pr, @-r0 ! save PR\n" | ||
1223 | " mov.l @(L_stubstack, pc), r2\n" | ||
1224 | " mov.l @(L_hdl_except, pc), r3\n" | ||
1225 | " mov.l @r2, r15\n" | ||
1226 | " jsr @r3\n" | ||
1227 | " mov.l r1, @-r0 ! save PC\n" | ||
1228 | " mov.l @(L_stubstack, pc), r0\n" | ||
1229 | " mov.l @(L_reg, pc), r1\n" | ||
1230 | " bra restoreRegisters\n" | ||
1231 | " mov.l r15, @r0 ! save __stub_stack\n" | ||
1232 | |||
1233 | " .align 2\n" | ||
1234 | "L_reg:\n" | ||
1235 | " .long _registers\n" | ||
1236 | "L_stubstack:\n" | ||
1237 | " .long _stub_sp\n" | ||
1238 | "L_hdl_except:\n" | ||
1239 | " .long _handle_exception"); | ||
1240 | } | ||
1241 | |||
1242 | void rr(void) | ||
1243 | { | ||
1244 | asm(" .align 2 \n" | ||
1245 | " .global _resume\n" | ||
1246 | "_resume:\n" | ||
1247 | " mov r4,r1\n" | ||
1248 | "restoreRegisters:\n" | ||
1249 | " add #8, r1 ! skip to R2\n" | ||
1250 | " mov.l @r1+, r2 ! restore R2\n" | ||
1251 | " mov.l @r1+, r3 ! restore R3\n" | ||
1252 | " mov.l @r1+, r4 ! restore R4\n" | ||
1253 | " mov.l @r1+, r5 ! restore R5\n" | ||
1254 | " mov.l @r1+, r6 ! restore R6\n" | ||
1255 | " mov.l @r1+, r7 ! restore R7\n" | ||
1256 | " mov.l @r1+, r8 ! restore R8\n" | ||
1257 | " mov.l @r1+, r9 ! restore R9\n" | ||
1258 | " mov.l @r1+, r10 ! restore R10\n" | ||
1259 | " mov.l @r1+, r11 ! restore R11\n" | ||
1260 | " mov.l @r1+, r12 ! restore R12\n" | ||
1261 | " mov.l @r1+, r13 ! restore R13\n" | ||
1262 | " mov.l @r1+, r14 ! restore R14\n" | ||
1263 | " mov.l @r1+, r15 ! restore programs stack\n" | ||
1264 | " mov.l @r1+, r0\n" | ||
1265 | " add #-8, r15 ! uncover PC/SR on stack \n" | ||
1266 | " mov.l r0, @r15 ! restore PC onto stack\n" | ||
1267 | " lds.l @r1+, pr ! restore PR\n" | ||
1268 | " ldc.l @r1+, gbr ! restore GBR\n" | ||
1269 | " ldc.l @r1+, vbr ! restore VBR\n" | ||
1270 | " lds.l @r1+, mach ! restore MACH\n" | ||
1271 | " lds.l @r1+, macl ! restore MACL\n" | ||
1272 | " mov.l @r1, r0 \n" | ||
1273 | " add #-88, r1 ! readjust reg pointer to R1\n" | ||
1274 | " mov.l r0, @(4, r15) ! restore SR onto stack+4\n" | ||
1275 | " mov.l r2, @-r15\n" | ||
1276 | " mov.l L_in_nmi, r0\n" | ||
1277 | " mov #0, r2\n" | ||
1278 | " mov.b r2, @r0\n" | ||
1279 | " mov.l @r15+, r2\n" | ||
1280 | " mov.l @r1+, r0 ! restore R0\n" | ||
1281 | " rte\n" | ||
1282 | " mov.l @r1, r1 ! restore R1"); | ||
1283 | } | ||
1284 | |||
1285 | static inline void code_for_catch_exception(unsigned int n) | ||
1286 | { | ||
1287 | asm(" .globl _catch_exception_%O0" : : "X" (n) ); | ||
1288 | asm(" _catch_exception_%O0:" :: "X" (n) ); | ||
1289 | |||
1290 | asm(" add #-4, r15 ! reserve spot on stack "); | ||
1291 | asm(" mov.l r1, @-r15 ! push R1 "); | ||
1292 | |||
1293 | if (n == NMI_VEC) | ||
1294 | { | ||
1295 | /* Special case for NMI - make sure that they don't nest */ | ||
1296 | asm(" mov.l r0, @-r15 ! push R0"); | ||
1297 | asm(" mov.l L_in_nmi, r0"); | ||
1298 | asm(" tas.b @r0 ! Fend off against addtnl NMIs"); | ||
1299 | asm(" bt noNMI"); | ||
1300 | asm(" mov.l @r15+, r0"); | ||
1301 | asm(" mov.l @r15+, r1"); | ||
1302 | asm(" add #4, r15"); | ||
1303 | asm(" rte"); | ||
1304 | asm(" nop"); | ||
1305 | asm(".align 2"); | ||
1306 | asm("L_in_nmi: .long _in_nmi"); | ||
1307 | asm("noNMI:"); | ||
1308 | } | ||
1309 | else | ||
1310 | { | ||
1311 | |||
1312 | if (n == CPU_BUS_ERROR_VEC) | ||
1313 | { | ||
1314 | /* Exception 9 (bus errors) are disasbleable - so that you | ||
1315 | can probe memory and get zero instead of a fault. | ||
1316 | Because the vector table may be in ROM we don't revector | ||
1317 | the interrupt like all the other stubs, we check in here | ||
1318 | */ | ||
1319 | asm("mov.l L_dofault,r1"); | ||
1320 | asm("mov.l @r1,r1"); | ||
1321 | asm("tst r1,r1"); | ||
1322 | asm("bf faultaway"); | ||
1323 | asm("bsr _handle_buserror"); | ||
1324 | asm(".align 2"); | ||
1325 | asm("L_dofault: .long _dofault"); | ||
1326 | asm("faultaway:"); | ||
1327 | } | ||
1328 | asm(" mov #15<<4, r1 "); | ||
1329 | asm(" ldc r1, sr ! disable interrupts "); | ||
1330 | asm(" mov.l r0, @-r15 ! push R0 "); | ||
1331 | } | ||
1332 | |||
1333 | /* Prepare for saving context, we've already pushed r0 and r1, stick | ||
1334 | exception number into the frame */ | ||
1335 | asm(" mov r15, r0 "); | ||
1336 | asm(" add #8, r0 "); | ||
1337 | asm(" mov %0,r1" :: "X" (n)); | ||
1338 | asm(" extu.b r1,r1 "); | ||
1339 | asm(" bra saveRegisters ! save register values "); | ||
1340 | asm(" mov.l r1, @r0 ! save exception # "); | ||
1341 | } | ||
1342 | |||
1343 | /* Here we call all defined exceptions, so the inline assembler gets | ||
1344 | generated */ | ||
1345 | void exceptions (void) | ||
1346 | { | ||
1347 | code_for_catch_exception (4); | ||
1348 | code_for_catch_exception (5); | ||
1349 | code_for_catch_exception (6); | ||
1350 | code_for_catch_exception (7); | ||
1351 | code_for_catch_exception (8); | ||
1352 | code_for_catch_exception (9); | ||
1353 | code_for_catch_exception (10); | ||
1354 | code_for_catch_exception (11); | ||
1355 | code_for_catch_exception (12); | ||
1356 | code_for_catch_exception (13); | ||
1357 | code_for_catch_exception (14); | ||
1358 | code_for_catch_exception (15); | ||
1359 | code_for_catch_exception (16); | ||
1360 | code_for_catch_exception (17); | ||
1361 | code_for_catch_exception (18); | ||
1362 | code_for_catch_exception (19); | ||
1363 | code_for_catch_exception (20); | ||
1364 | code_for_catch_exception (21); | ||
1365 | code_for_catch_exception (22); | ||
1366 | code_for_catch_exception (23); | ||
1367 | code_for_catch_exception (24); | ||
1368 | code_for_catch_exception (25); | ||
1369 | code_for_catch_exception (26); | ||
1370 | code_for_catch_exception (27); | ||
1371 | code_for_catch_exception (28); | ||
1372 | code_for_catch_exception (29); | ||
1373 | code_for_catch_exception (30); | ||
1374 | code_for_catch_exception (31); | ||
1375 | code_for_catch_exception (32); | ||
1376 | code_for_catch_exception (33); | ||
1377 | code_for_catch_exception (34); | ||
1378 | code_for_catch_exception (35); | ||
1379 | code_for_catch_exception (36); | ||
1380 | code_for_catch_exception (37); | ||
1381 | code_for_catch_exception (38); | ||
1382 | code_for_catch_exception (39); | ||
1383 | code_for_catch_exception (40); | ||
1384 | code_for_catch_exception (41); | ||
1385 | code_for_catch_exception (42); | ||
1386 | code_for_catch_exception (43); | ||
1387 | code_for_catch_exception (44); | ||
1388 | code_for_catch_exception (45); | ||
1389 | code_for_catch_exception (46); | ||
1390 | code_for_catch_exception (47); | ||
1391 | code_for_catch_exception (48); | ||
1392 | code_for_catch_exception (49); | ||
1393 | code_for_catch_exception (50); | ||
1394 | code_for_catch_exception (51); | ||
1395 | code_for_catch_exception (52); | ||
1396 | code_for_catch_exception (53); | ||
1397 | code_for_catch_exception (54); | ||
1398 | code_for_catch_exception (55); | ||
1399 | code_for_catch_exception (56); | ||
1400 | code_for_catch_exception (57); | ||
1401 | code_for_catch_exception (58); | ||
1402 | code_for_catch_exception (59); | ||
1403 | code_for_catch_exception (60); | ||
1404 | code_for_catch_exception (61); | ||
1405 | code_for_catch_exception (62); | ||
1406 | code_for_catch_exception (63); | ||
1407 | code_for_catch_exception (64); | ||
1408 | code_for_catch_exception (65); | ||
1409 | code_for_catch_exception (66); | ||
1410 | code_for_catch_exception (67); | ||
1411 | code_for_catch_exception (68); | ||
1412 | code_for_catch_exception (69); | ||
1413 | code_for_catch_exception (70); | ||
1414 | code_for_catch_exception (71); | ||
1415 | code_for_catch_exception (72); | ||
1416 | code_for_catch_exception (73); | ||
1417 | code_for_catch_exception (74); | ||
1418 | code_for_catch_exception (75); | ||
1419 | code_for_catch_exception (76); | ||
1420 | code_for_catch_exception (77); | ||
1421 | code_for_catch_exception (78); | ||
1422 | code_for_catch_exception (79); | ||
1423 | code_for_catch_exception (80); | ||
1424 | code_for_catch_exception (81); | ||
1425 | code_for_catch_exception (82); | ||
1426 | code_for_catch_exception (83); | ||
1427 | code_for_catch_exception (84); | ||
1428 | code_for_catch_exception (85); | ||
1429 | code_for_catch_exception (86); | ||
1430 | code_for_catch_exception (87); | ||
1431 | code_for_catch_exception (88); | ||
1432 | code_for_catch_exception (89); | ||
1433 | code_for_catch_exception (90); | ||
1434 | code_for_catch_exception (91); | ||
1435 | code_for_catch_exception (92); | ||
1436 | code_for_catch_exception (93); | ||
1437 | code_for_catch_exception (94); | ||
1438 | code_for_catch_exception (95); | ||
1439 | code_for_catch_exception (96); | ||
1440 | code_for_catch_exception (97); | ||
1441 | code_for_catch_exception (98); | ||
1442 | code_for_catch_exception (99); | ||
1443 | code_for_catch_exception (100); | ||
1444 | code_for_catch_exception (101); | ||
1445 | code_for_catch_exception (102); | ||
1446 | code_for_catch_exception (103); | ||
1447 | code_for_catch_exception (104); | ||
1448 | code_for_catch_exception (105); | ||
1449 | code_for_catch_exception (106); | ||
1450 | code_for_catch_exception (107); | ||
1451 | code_for_catch_exception (108); | ||
1452 | code_for_catch_exception (109); | ||
1453 | code_for_catch_exception (110); | ||
1454 | code_for_catch_exception (111); | ||
1455 | code_for_catch_exception (112); | ||
1456 | code_for_catch_exception (113); | ||
1457 | code_for_catch_exception (114); | ||
1458 | code_for_catch_exception (115); | ||
1459 | code_for_catch_exception (116); | ||
1460 | code_for_catch_exception (117); | ||
1461 | code_for_catch_exception (118); | ||
1462 | code_for_catch_exception (119); | ||
1463 | code_for_catch_exception (120); | ||
1464 | code_for_catch_exception (121); | ||
1465 | code_for_catch_exception (122); | ||
1466 | code_for_catch_exception (123); | ||
1467 | code_for_catch_exception (124); | ||
1468 | code_for_catch_exception (125); | ||
1469 | code_for_catch_exception (126); | ||
1470 | code_for_catch_exception (127); | ||
1471 | } | ||
1472 | |||
1473 | /* | ||
1474 | * Port B Control Register (PBCR1) | ||
1475 | */ | ||
1476 | #define PB15MD1 0x8000 | ||
1477 | #define PB15MD0 0x4000 | ||
1478 | #define PB14MD1 0x2000 | ||
1479 | #define PB14MD0 0x1000 | ||
1480 | #define PB13MD1 0x0800 | ||
1481 | #define PB13MD0 0x0400 | ||
1482 | #define PB12MD1 0x0200 | ||
1483 | #define PB12MD0 0x0100 | ||
1484 | #define PB11MD1 0x0080 | ||
1485 | #define PB11MD0 0x0040 | ||
1486 | #define PB10MD1 0x0020 | ||
1487 | #define PB10MD0 0x0010 | ||
1488 | #define PB9MD1 0x0008 | ||
1489 | #define PB9MD0 0x0004 | ||
1490 | #define PB8MD1 0x0002 | ||
1491 | #define PB8MD0 0x0001 | ||
1492 | |||
1493 | #define PB15MD PB15MD1|PB14MD0 | ||
1494 | #define PB14MD PB14MD1|PB14MD0 | ||
1495 | #define PB13MD PB13MD1|PB13MD0 | ||
1496 | #define PB12MD PB12MD1|PB12MD0 | ||
1497 | #define PB11MD PB11MD1|PB11MD0 | ||
1498 | #define PB10MD PB10MD1|PB10MD0 | ||
1499 | #define PB9MD PB9MD1|PB9MD0 | ||
1500 | #define PB8MD PB8MD1|PB8MD0 | ||
1501 | |||
1502 | #define PB_TXD1 PB11MD1 | ||
1503 | #define PB_RXD1 PB10MD1 | ||
1504 | #define PB_TXD0 PB9MD1 | ||
1505 | #define PB_RXD0 PB8MD1 | ||
1506 | |||
1507 | #define PB7MD PB7MD1|PB7MD0 | ||
1508 | #define PB6MD PB6MD1|PB6MD0 | ||
1509 | #define PB5MD PB5MD1|PB5MD0 | ||
1510 | #define PB4MD PB4MD1|PB4MD0 | ||
1511 | #define PB3MD PB3MD1|PB3MD0 | ||
1512 | #define PB2MD PB2MD1|PB2MD0 | ||
1513 | #define PB1MD PB1MD1|PB1MD0 | ||
1514 | #define PB0MD PB0MD1|PB0MD0 | ||
1515 | |||
1516 | |||
1517 | void handleError (char theSSR); | ||
1518 | |||
1519 | void nop (void) | ||
1520 | { | ||
1521 | } | ||
1522 | |||
1523 | void init_serial (void) | ||
1524 | { | ||
1525 | int i; | ||
1526 | |||
1527 | /* Clear Channel 1's SCR */ | ||
1528 | SCR1 = 0; | ||
1529 | |||
1530 | /* Set communication to be async, 8-bit data, | ||
1531 | no parity, 1 stop bit and use internal clock */ | ||
1532 | SMR1 = 0; | ||
1533 | |||
1534 | #ifdef RECORDER | ||
1535 | #warning 115200 | ||
1536 | BRR1 = 2; /* 115200 */ | ||
1537 | #else | ||
1538 | BRR1 = 9; /* 38400 */ | ||
1539 | #endif | ||
1540 | |||
1541 | SCR1 &= ~(SCI_CKE1 | SCI_CKE0); | ||
1542 | |||
1543 | /* let the hardware settle */ | ||
1544 | for (i = 0; i < 1000; i++) | ||
1545 | nop (); | ||
1546 | |||
1547 | /* Turn on in and out */ | ||
1548 | SCR1 |= SCI_RE | SCI_TE; | ||
1549 | |||
1550 | /* Set the PFC to make RXD1 (pin PB8) an input pin | ||
1551 | and TXD1 (pin PB9) an output pin */ | ||
1552 | PBCR1 &= ~(PB_TXD1 | PB_RXD1); | ||
1553 | PBCR1 |= PB_TXD1 | PB_RXD1; | ||
1554 | } | ||
1555 | |||
1556 | |||
1557 | int serial_waitc(void) | ||
1558 | { | ||
1559 | char mySSR; | ||
1560 | mySSR = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER ); | ||
1561 | if ( mySSR ) | ||
1562 | handleError ( mySSR ); | ||
1563 | return SSR1 & SCI_RDRF ; | ||
1564 | } | ||
1565 | |||
1566 | char serial_getc (void) | ||
1567 | { | ||
1568 | char ch; | ||
1569 | char mySSR; | ||
1570 | |||
1571 | while ( ! serial_waitc()) | ||
1572 | ; | ||
1573 | |||
1574 | ch = RDR1; | ||
1575 | SSR1 &= ~SCI_RDRF; | ||
1576 | |||
1577 | mySSR = SSR1 & (SCI_PER | SCI_FER | SCI_ORER); | ||
1578 | |||
1579 | if (mySSR) | ||
1580 | handleError (mySSR); | ||
1581 | |||
1582 | return ch; | ||
1583 | } | ||
1584 | |||
1585 | void serial_putc (char ch) | ||
1586 | { | ||
1587 | while (!(SSR1 & SCI_TDRE)) | ||
1588 | { | ||
1589 | ; | ||
1590 | } | ||
1591 | |||
1592 | /* | ||
1593 | * Write data into TDR and clear TDRE | ||
1594 | */ | ||
1595 | TDR1 = ch; | ||
1596 | SSR1 &= ~SCI_TDRE; | ||
1597 | } | ||
1598 | |||
1599 | void handleError (char theSSR) | ||
1600 | { | ||
1601 | /* Clear all error bits, otherwise the receiver will stop */ | ||
1602 | SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER); | ||
1603 | } | ||
1604 | |||
1605 | void *memcpy(void *dest, const void *src0, size_t n) | ||
1606 | { | ||
1607 | char *dst = (char *) dest; | ||
1608 | char *src = (char *) src0; | ||
1609 | |||
1610 | void *save = dest; | ||
1611 | |||
1612 | while(n--) | ||
1613 | { | ||
1614 | *dst++ = *src++; | ||
1615 | } | ||
1616 | |||
1617 | return save; | ||
1618 | } | ||