|
2
|
1 //============================================================================= |
|
|
2 // |
|
|
3 // plf_stub.c |
|
|
4 // |
|
|
5 // Platform specific code for GDB stub support. |
|
|
6 // |
|
|
7 //============================================================================= |
|
|
8 //####COPYRIGHTBEGIN#### |
|
|
9 // |
|
|
10 // ------------------------------------------- |
|
|
11 // The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 // Version 1.0 (the "License"); you may not use this file except in |
|
|
13 // compliance with the License. You may obtain a copy of the License at |
|
|
14 // http://sourceware.cygnus.com/ecos |
|
|
15 // |
|
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 // License for the specific language governing rights and limitations under |
|
|
19 // the License. |
|
|
20 // |
|
|
21 // The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 // September 30, 1998. |
|
|
23 // |
|
|
24 // The Initial Developer of the Original Code is Cygnus. Portions created |
|
|
25 // by Cygnus are Copyright (C) 1998, 1999 Cygnus Solutions. |
|
|
26 // All Rights Reserved. |
|
|
27 // ------------------------------------------- |
|
|
28 // |
|
|
29 //####COPYRIGHTEND#### |
|
|
30 //============================================================================= |
|
|
31 //#####DESCRIPTIONBEGIN#### |
|
|
32 // |
|
|
33 // Author(s): gthomas (based on the old ARM/PID hal_stub.c) |
|
|
34 // Contributors:gthomas, jskov |
|
|
35 // Date: 1999-02-15 |
|
|
36 // Purpose: Platform specific code for GDB stub support. |
|
|
37 // |
|
|
38 //####DESCRIPTIONEND#### |
|
|
39 // |
|
|
40 //============================================================================= |
|
|
41 |
|
|
42 #include <pkgconf/hal.h> |
|
|
43 |
|
|
44 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
|
|
45 |
|
|
46 #include <cyg/hal/hal_stub.h> |
|
|
47 |
|
|
48 #include <cyg/hal/hal_io.h> // HAL IO macros |
|
|
49 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT |
|
|
50 #include <cyg/hal/hal_intr.h> // HAL interrupt macros |
|
|
51 #include <cyg/hal/drv_api.h> // HAL ISR support |
|
|
52 #endif |
|
|
53 |
|
|
54 //----------------------------------------------------------------------------- |
|
|
55 // Serial definitions. |
|
|
56 #if CYGHWR_HAL_ARM_PID_GDB_PORT==0 |
|
|
57 // This is the base address of the A-channel |
|
|
58 #define CYG_DEVICE_SERIAL_RS232_16550_BASE 0x0D800000 |
|
|
59 #define CYG_DEVICE_SERIAL_INT CYGNUM_HAL_INTERRUPT_SERIALA |
|
|
60 #else |
|
|
61 // This is the base address of the B-channel |
|
|
62 #define CYG_DEVICE_SERIAL_RS232_16550_BASE 0x0D800020 |
|
|
63 #define CYG_DEVICE_SERIAL_INT CYGNUM_HAL_INTERRUPT_SERIALB |
|
|
64 #endif |
|
|
65 |
|
|
66 #if CYGHWR_HAL_ARM_PID_GDB_BAUD==9600 |
|
|
67 #define CYG_DEVICE_SERIAL_RS232_BAUD_MSB 0x00 |
|
|
68 #define CYG_DEVICE_SERIAL_RS232_BAUD_LSB 0x0C |
|
|
69 #endif |
|
|
70 #if CYGHWR_HAL_ARM_PID_GDB_BAUD==19200 |
|
|
71 #define CYG_DEVICE_SERIAL_RS232_BAUD_MSB 0x00 |
|
|
72 #define CYG_DEVICE_SERIAL_RS232_BAUD_LSB 0x06 |
|
|
73 #endif |
|
|
74 #if CYGHWR_HAL_ARM_PID_GDB_BAUD==38400 |
|
|
75 #define CYG_DEVICE_SERIAL_RS232_BAUD_MSB 0x00 |
|
|
76 #define CYG_DEVICE_SERIAL_RS232_BAUD_LSB 0x03 |
|
|
77 #endif |
|
|
78 #if CYGHWR_HAL_ARM_PID_GDB_BAUD==115200 |
|
|
79 #define CYG_DEVICE_SERIAL_RS232_BAUD_MSB 0x00 |
|
|
80 #define CYG_DEVICE_SERIAL_RS232_BAUD_LSB 0x01 |
|
|
81 #endif |
|
|
82 |
|
|
83 #ifndef CYG_DEVICE_SERIAL_RS232_BAUD_MSB |
|
|
84 #error Missing/incorrect serial baud rate defined - CDL error? |
|
|
85 #endif |
|
|
86 |
|
|
87 // Define the serial registers. |
|
|
88 #define CYG_DEVICE_SERIAL_RS232_16550_RBR \ |
|
|
89 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x00) |
|
|
90 // receiver buffer register, read, dlab = 0 |
|
|
91 #define CYG_DEVICE_SERIAL_RS232_16550_THR \ |
|
|
92 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x00) |
|
|
93 // transmitter holding register, write, dlab = 0 |
|
|
94 #define CYG_DEVICE_SERIAL_RS232_16550_DLL \ |
|
|
95 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x00) |
|
|
96 // divisor latch (LS), read/write, dlab = 1 |
|
|
97 #define CYG_DEVICE_SERIAL_RS232_16550_IER \ |
|
|
98 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x04) |
|
|
99 // interrupt enable register, read/write, dlab = 0 |
|
|
100 #define CYG_DEVICE_SERIAL_RS232_16550_DLM \ |
|
|
101 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x04) |
|
|
102 // divisor latch (MS), read/write, dlab = 1 |
|
|
103 #define CYG_DEVICE_SERIAL_RS232_16550_IIR \ |
|
|
104 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x08) |
|
|
105 // interrupt identification register, read, dlab = 0 |
|
|
106 #define CYG_DEVICE_SERIAL_RS232_16550_FCR \ |
|
|
107 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x08) |
|
|
108 // fifo control register, write, dlab = 0 |
|
|
109 #define CYG_DEVICE_SERIAL_RS232_16550_LCR \ |
|
|
110 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x0C) |
|
|
111 // line control register, read/write |
|
|
112 #define CYG_DEVICE_SERIAL_RS232_16550_MCR \ |
|
|
113 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x10) |
|
|
114 // modem control register, read/write |
|
|
115 #define CYG_DEVICE_SERIAL_RS232_16550_LSR \ |
|
|
116 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x14) |
|
|
117 // line status register, read |
|
|
118 #define CYG_DEVICE_SERIAL_RS232_16550_MSR \ |
|
|
119 ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x18) |
|
|
120 // modem status register, read |
|
|
121 |
|
|
122 // The interrupt enable register bits. |
|
|
123 #define SIO_IER_ERDAI 0x01 // enable received data available irq |
|
|
124 #define SIO_IER_ETHREI 0x02 // enable THR empty interrupt |
|
|
125 #define SIO_IER_ELSI 0x04 // enable receiver line status irq |
|
|
126 #define SIO_IER_EMSI 0x08 // enable modem status interrupt |
|
|
127 |
|
|
128 // The interrupt identification register bits. |
|
|
129 #define SIO_IIR_IP 0x01 // 0 if interrupt pending |
|
|
130 #define SIO_IIR_ID_MASK 0x0e // mask for interrupt ID bits |
|
|
131 |
|
|
132 // The line status register bits. |
|
|
133 #define SIO_LSR_DR 0x01 // data ready |
|
|
134 #define SIO_LSR_OE 0x02 // overrun error |
|
|
135 #define SIO_LSR_PE 0x04 // parity error |
|
|
136 #define SIO_LSR_FE 0x08 // framing error |
|
|
137 #define SIO_LSR_BI 0x10 // break interrupt |
|
|
138 #define SIO_LSR_THRE 0x20 // transmitter holding register empty |
|
|
139 #define SIO_LSR_TEMT 0x40 // transmitter register empty |
|
|
140 #define SIO_LSR_ERR 0x80 // any error condition |
|
|
141 |
|
|
142 // The modem status register bits. |
|
|
143 #define SIO_MSR_DCTS 0x01 // delta clear to send |
|
|
144 #define SIO_MSR_DDSR 0x02 // delta data set ready |
|
|
145 #define SIO_MSR_TERI 0x04 // trailing edge ring indicator |
|
|
146 #define SIO_MSR_DDCD 0x08 // delta data carrier detect |
|
|
147 #define SIO_MSR_CTS 0x10 // clear to send |
|
|
148 #define SIO_MSR_DSR 0x20 // data set ready |
|
|
149 #define SIO_MSR_RI 0x40 // ring indicator |
|
|
150 #define SIO_MSR_DCD 0x80 // data carrier detect |
|
|
151 |
|
|
152 // The line control register bits. |
|
|
153 #define SIO_LCR_WLS0 0x01 // word length select bit 0 |
|
|
154 #define SIO_LCR_WLS1 0x02 // word length select bit 1 |
|
|
155 #define SIO_LCR_STB 0x04 // number of stop bits |
|
|
156 #define SIO_LCR_PEN 0x08 // parity enable |
|
|
157 #define SIO_LCR_EPS 0x10 // even parity select |
|
|
158 #define SIO_LCR_SP 0x20 // stick parity |
|
|
159 #define SIO_LCR_SB 0x40 // set break |
|
|
160 #define SIO_LCR_DLAB 0x80 // divisor latch access bit |
|
|
161 |
|
|
162 // Interrupt Enable Register |
|
|
163 #define SIO_IER_RCV 0x01 |
|
|
164 #define SIO_IER_XMT 0x02 |
|
|
165 #define SIO_IER_LS 0x04 |
|
|
166 #define SIO_IER_MS 0x08 |
|
|
167 |
|
|
168 // Modem Control Register |
|
|
169 #define SIO_MCR_DTR 0x01 |
|
|
170 #define SIO_MCR_RTS 0x02 |
|
|
171 #define SIO_MCR_INT 0x08 // Enable interrupts |
|
|
172 |
|
|
173 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT |
|
|
174 static cyg_interrupt gdb_interrupt; |
|
|
175 static cyg_handle_t gdb_interrupt_handle; |
|
|
176 #endif |
|
|
177 |
|
|
178 //----------------------------------------------------------------------------- |
|
|
179 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT |
|
|
180 // This ISR is called only for serial receive interrupts. |
|
|
181 int |
|
|
182 cyg_hal_gdb_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs) |
|
|
183 { |
|
|
184 cyg_uint8 c; |
|
|
185 |
|
|
186 c = hal_pid_get_char(); // Fetch the character |
|
|
187 if( 3 == c ) { // ^C |
|
|
188 // Ctrl-C: set a breakpoint at PC so GDB will display the |
|
|
189 // correct program context when stopping rather than the |
|
|
190 // interrupt handler. |
|
|
191 cyg_hal_gdb_interrupt (regs->pc); |
|
|
192 cyg_drv_interrupt_acknowledge(CYG_DEVICE_SERIAL_INT); |
|
|
193 } |
|
|
194 return 0; // No need to run DSR |
|
|
195 } |
|
|
196 |
|
|
197 int |
|
|
198 hal_pid_interruptible(int state) |
|
|
199 { |
|
|
200 if (state) { |
|
|
201 cyg_drv_interrupt_unmask(CYG_DEVICE_SERIAL_INT); |
|
|
202 } else { |
|
|
203 cyg_drv_interrupt_mask(CYG_DEVICE_SERIAL_INT); |
|
|
204 } |
|
|
205 |
|
|
206 return 0; |
|
|
207 } |
|
|
208 #endif |
|
|
209 |
|
|
210 // Initialize the current serial port. |
|
|
211 void hal_pid_init_serial(void) |
|
|
212 { |
|
|
213 cyg_uint8 lcr; |
|
|
214 |
|
|
215 // 8-1-no parity. |
|
|
216 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_LCR, |
|
|
217 SIO_LCR_WLS0 | SIO_LCR_WLS1); |
|
|
218 |
|
|
219 HAL_READ_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_LCR, lcr); |
|
|
220 lcr |= SIO_LCR_DLAB; |
|
|
221 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_LCR, lcr); |
|
|
222 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_DLL, |
|
|
223 CYG_DEVICE_SERIAL_RS232_BAUD_LSB); |
|
|
224 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_DLM, |
|
|
225 CYG_DEVICE_SERIAL_RS232_BAUD_MSB); |
|
|
226 lcr &= ~SIO_LCR_DLAB; |
|
|
227 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_LCR, lcr); |
|
|
228 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_FCR, 0x07); // Enable & clear FIFO |
|
|
229 |
|
|
230 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT |
|
|
231 cyg_drv_interrupt_create(CYG_DEVICE_SERIAL_INT, |
|
|
232 99, // Priority - what goes here? |
|
|
233 0, // Data item passed to interrupt handler |
|
|
234 cyg_hal_gdb_isr, |
|
|
235 0, |
|
|
236 &gdb_interrupt_handle, |
|
|
237 &gdb_interrupt); |
|
|
238 cyg_drv_interrupt_attach(gdb_interrupt_handle); |
|
|
239 cyg_drv_interrupt_unmask(CYG_DEVICE_SERIAL_INT); |
|
|
240 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_IER, SIO_IER_RCV); |
|
|
241 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_MCR, SIO_MCR_INT|SIO_MCR_DTR|SIO_MCR_RTS); |
|
|
242 #endif |
|
|
243 } |
|
|
244 |
|
|
245 // Write C to the current serial port. |
|
|
246 void hal_pid_put_char(int c) |
|
|
247 { |
|
|
248 cyg_uint8 lsr; |
|
|
249 |
|
|
250 do { |
|
|
251 HAL_READ_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_LSR, lsr); |
|
|
252 } while ((lsr & SIO_LSR_THRE) == 0); |
|
|
253 |
|
|
254 HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_THR, c); |
|
|
255 } |
|
|
256 |
|
|
257 // Read one character from the current serial port. |
|
|
258 int hal_pid_get_char(void) |
|
|
259 { |
|
|
260 char c; |
|
|
261 cyg_uint8 lsr; |
|
|
262 |
|
|
263 do { |
|
|
264 HAL_READ_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_LSR, lsr); |
|
|
265 } while ((lsr & SIO_LSR_DR) == 0); |
|
|
266 |
|
|
267 HAL_READ_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_RBR, c); |
|
|
268 return c; |
|
|
269 } |
|
|
270 |
|
|
271 #endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
|
|
272 //----------------------------------------------------------------------------- |
|
|
273 // End of plf_stub.c |