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