-
Notifications
You must be signed in to change notification settings - Fork 0
/
cpu32-mc68360.c
336 lines (255 loc) · 7.97 KB
/
cpu32-mc68360.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/*
Copyright (c) 2001 by William A. Gatliff
All rights reserved. [email protected]
See the file COPYING for details.
This file is provided "as-is", and without any express or implied
warranties, including, without limitation, the implied warranties of
merchantability and fitness for a particular purpose.
The author welcomes feedback regarding this file.
**
Generic MC68360 support, generously funded by Michael Dorin,
[email protected], of EDI Enterprises, Inc. Thanks, Mike!
Written Oct 2001 by Bill Gatliff, [email protected]
SMC1UART - serial i/o on SMC1 in UART mode (polled)
This stub assumes that DPRBASE == 0xffff0000, and the built-in
startup code, if used, consumes the first 1024 bytes of the
dual-port RAM for stack and data storage. The first part of this
area is the register file and other data; the last few bytes are
used for the transmit and receive buffers (one byte each) and the
buffer descriptors (one each for transmit and receive). The stack
starts immediately above the buffer descriptors.
To build this stub, do something like the following:
$ m68k-elf-gcc -mcpu32 -Wall -nostartfiles \
-o gdbstub.out -Wl,--script=cpu32-mc68360.x \
-DCRT0 -DSMC1UART gdb.c cpu32.c cpu32-mc68360.c
$ m68k-elf-objcopy -O srec gdbstub.out gdbstub.s19
You will need a .gdbinit file, as the stub does very little in the
way of setting up peripheral registers, etc. in the host
microcontroller. The file cpu32-mc68360.gdbinit is a start. Note
that the setting for $dprbase in your gdbinit must match what the
stub uses. The stub isn't yet clever enough to deal with changes to
MBAR at runtime.
You will also need to put a statement somewhere that sets up the
initial stack pointer, frame pointer, and program status register,
because the stub does not initialize its register file to sane
values (this is your job, not the stub's). If the values chosen are
relatively constant then you can put them in your gdbinit file, or
just type them in:
(gdb) set $sp=$fp=0x1000800
(gdb) set $ps=0x2700
Since the SMC1UART driver is polled, a ctrl-C from gdb is ignored.
To fix this, provide an interrupt-driven getc() and putc(), and
forcibly give control to the exception handler when a ctrl-C is
received.
$Id: cpu32-mc68360.c,v 1.2 2002/03/20 02:26:01 bgat Exp $
*/
#include "gdb.h"
#include "cpu32.h"
typedef struct
{
volatile short status;
volatile short length;
volatile char *buf;
} bd_T;
/* Until someone figures out some clever macros, do not change DPRBASE
without making the corresponding changes in the vector table and
startup code in the CRT0 block below. */
#define DPRBASE 0xffff0000UL
#define REGB (DPRBASE + 4096)
#define SMC1BASE (DPRBASE + 0xe80)
#define PBPAR ((volatile long* )(REGB + 0x6bc))
#define PBDIR ((volatile long* )(REGB + 0x6b8))
#define PBODR ((volatile short*)(REGB + 0x6c2))
#define SIMODE ((volatile long* )(REGB + 0x6e0))
#define BRGC1 ((volatile long* )(REGB + 0x5f0))
#define SMCE1 ((volatile char* )(REGB + 0x686))
#define SMCM1 ((volatile char* )(REGB + 0x68a))
#define SMCMR1 ((volatile short*)(REGB + 0x682))
#define CR ((volatile short*)(REGB + 0x5c0))
#define SDCR ((volatile short*)(REGB + 0x51e))
#define SYPCR ((volatile char* )(REGB + 0x22))
#define RBASE ((volatile short*)(SMCBASE + 0))
#define TBASE ((volatile short*)(SMCBASE + 2))
#define RFCR ((volatile char* )(SMCBASE + 4))
#define TFCR ((volatile char* )(SMCBASE + 5))
#define MRBLR ((volatile short*)(SMCBASE + 6))
#define RSTATE ((volatile long* )(SMCBASE + 8))
#define RBPTR ((volatile short*)(SMCBASE + 0x10))
#define TSTATE ((volatile long* )(SMCBASE + 0x18))
#define TBPTR ((volatile short*)(SMCBASE + 0x20))
#define MAX_IDL ((volatile short*)(SMCBASE + 0x28))
#define BRKLN ((volatile short*)(SMCBASE + 0x2c))
#define BRKEC ((volatile short*)(SMCBASE + 0x2e))
#define BRKCR ((volatile short*)(SMCBASE + 0x30))
#define TX_READY 0x8000
#define TX_WRAP 0x2000
#define RX_EMPTY 0x8000
#define RX_WRAP 0x2000
#define BD ((volatile bd_T* )(DPRBASE + 0x3e0))
#define RXBD BD
#define TXBD (BD + 1)
#define RXBUF ((volatile char* )(BD + 2))
#define TXBUF ((volatile char* )(RXBUF + 1))
#if defined(SMC1UART)
#define SMCBASE SMC1BASE
#define BRGC BRGC1
#define SMCE SMCE1
#define SMCM SMCM1
#define SMCMR SMCMR1
#define BAUD_115200 0x10022
#define BAUD_57600 0x10044
#define BAUD_9600 0x10144
#endif
#if !defined(BAUD)
#define BAUD BAUD_115200
#endif
int gdb_putc (int c)
{
#if defined(SMC1UART)
while (TXBD->status & TX_READY) {}
*TXBUF = c;
TXBD->length = 1;
TXBD->status |= TX_READY;
#else
#warning Null gdb_putc().
#endif
return c & 0xff;
}
int gdb_getc (void)
{
char retval = 0;
#if defined(SMC1UART)
while (RXBD->status & RX_EMPTY) {}
retval = *RXBUF;
RXBD->status |= RX_EMPTY;
#else
#warning Null gdb_getc().
#endif
return retval;
}
void gdb_startup (void)
{
#if defined(SMC1UART)
/* see MC68360 QUad Integrated Communications Controller User's
Manual, section 7.11.8, "SMC UART Example" for details on this */
/* TODO: this puts a bunch of crap on the tx line */
RXBD->status = RX_EMPTY + RX_WRAP;
RXBD->buf = RXBUF;
RXBD->length = 0;
TXBD->status = TX_WRAP;
TXBD->buf = TXBUF;
TXBD->length = 0;
*SDCR = 0x740;
*BRGC = BAUD;
*PBPAR = 0xcce;
*PBDIR = 0x3033f;
*PBODR = 0;
*SIMODE &= 0xffff0fff;
*RBASE = (long)RXBD - DPRBASE;
*TBASE = (long)TXBD - DPRBASE;
*CR = 1; while( *CR & 1 );
*RFCR = 0x18;
*TFCR = 0x18;
*MRBLR = 1;
*MAX_IDL = 0;
*BRKLN = 0;
*BRKEC = 0;
*BRKCR = 0;
*SMCE = 0xff;
*SMCM = 0;
*SMCMR = 0x4820;
*SMCMR = 0x4823;
#else
#warning Null gdb_startup().
#endif
}
#if defined(CRT0)
__asm__("
.global gdb_startup
.global gdb_monitor
.global gdb_interrupt_handler
.align 2
.section .vect
.global _vector_table
_vector_table:
.long 0xffff03dc
.long _start
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.long gdb_interrupt_handler
.align 2
.section .text
.global _start
_start:
/* set up MBAR */
move #7, %d0
movec %d0, %sfc
movec %d0, %dfc
move.l #0xffff0001, %d0
moves.l %d0, (0x3ff00)
/* disable SWT */
move.b #0xc, (0xffff1022)
/* initialize */
jsr gdb_startup
/* drop into the monitor and stay there */
to_monitor:
pea 5
jsr gdb_monitor
bra to_monitor
");
#endif