File indexing completed on 2025-05-11 08:23:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <bsp.h>
0012 #include <bsp/irq-generic.h>
0013 #include <libchip/serial.h>
0014
0015 #include "../../../shared/dev/serial/legacy-console.h"
0016
0017 int putDebugChar(int ch);
0018 int getDebugChar(void);
0019
0020
0021 int i386_gdb_uart_ctrl_c_check(void);
0022
0023
0024 void i386_gdb_uart_isr(void);
0025
0026
0027 void exceptionHandler(int, void (*handler)(void));
0028
0029
0030 extern int remote_debug;
0031
0032
0033 static int uart_current;
0034 static int uart_vector;
0035 static console_tbl* port_current;
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 int i386_gdb_uart_isr_regsav[4] RTEMS_UNUSED;
0047 __asm__ (".p2align 4");
0048 __asm__ (".text");
0049 __asm__ (".globl i386_gdb_uart_isr");
0050 __asm__ ("i386_gdb_uart_isr:");
0051 __asm__ (" pusha");
0052 __asm__ (" call i386_gdb_uart_ctrl_c_check");
0053 __asm__ (" movl %eax, i386_gdb_uart_isr_regsav");
0054 __asm__ (" popa");
0055 __asm__ (" xchgl %eax, i386_gdb_uart_isr_regsav");
0056 __asm__ (" cmpl $0, %eax");
0057 __asm__ (" je i386_gdb_uart_isr_1");
0058 __asm__ (" movl %ebx, i386_gdb_uart_isr_regsav + 4");
0059 __asm__ (" movl %edx, i386_gdb_uart_isr_regsav + 8");
0060 __asm__ (" popl %ebx");
0061 __asm__ (" popl %edx");
0062 __asm__ (" popl %eax");
0063 __asm__ (" orl $0x100, %eax");
0064 __asm__ (" pushl %eax");
0065 __asm__ (" pushl %edx");
0066 __asm__ (" pushl %ebx");
0067 __asm__ (" movl i386_gdb_uart_isr_regsav + 4, %ebx");
0068 __asm__ (" movl i386_gdb_uart_isr_regsav + 8, %edx");
0069 __asm__ ("i386_gdb_uart_isr_1:");
0070 __asm__ (" movl i386_gdb_uart_isr_regsav, %eax");
0071 __asm__ (" iret");
0072
0073 static int gdb_hello_index;
0074 static const char *const gdb_hello = "+";
0075
0076 static inline uint8_t BSP_i8259a_irq_in_service_reg(uint32_t ioport)
0077 {
0078 uint8_t isr;
0079 outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR | PIC_OCW3_RIS);
0080 inport_byte(ioport, isr);
0081 outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR);
0082 return isr;
0083 }
0084
0085 static inline void BSP_irq_ack_at_i8259a(const int irqLine)
0086 {
0087 uint8_t slave_isr = 0;
0088 if (irqLine >= 8) {
0089 outport_byte(PIC_SLAVE_COMMAND_IO_PORT, PIC_EOI);
0090 slave_isr = BSP_i8259a_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);
0091 }
0092
0093
0094
0095
0096
0097
0098 if (slave_isr == 0)
0099 outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);
0100 }
0101
0102 int i386_gdb_uart_ctrl_c_check(void)
0103 {
0104 BSP_irq_ack_at_i8259a(uart_vector);
0105 if (port_current) {
0106 int c = 0;
0107 while (c >= 0) {
0108 c = port_current->pDeviceFns->deviceRead(uart_current);
0109 if (c == 3) {
0110 gdb_hello_index = 0;
0111 return 1;
0112 } else if (gdb_hello[gdb_hello_index] == (char) c) {
0113 ++gdb_hello_index;
0114 if (gdb_hello[gdb_hello_index] == '\0') {
0115 gdb_hello_index = 0;
0116 return 1;
0117 }
0118 } else {
0119 gdb_hello_index = 0;
0120 }
0121 }
0122 }
0123 return 0;
0124 }
0125
0126 static void
0127 nop(const rtems_raw_irq_connect_data* notused)
0128 {
0129 }
0130
0131 static int
0132 isOn(const rtems_raw_irq_connect_data* notused)
0133 {
0134 return 1;
0135 }
0136
0137 int i386_stub_glue_uart(void)
0138 {
0139 if (port_current == NULL)
0140 return -1;
0141 return uart_current;
0142 }
0143
0144
0145
0146
0147
0148 void
0149 i386_stub_glue_init(int uart)
0150 {
0151 rtems_device_minor_number minor = (rtems_device_minor_number) uart;
0152
0153 port_current = console_find_console_entry(NULL, 0, &minor);
0154
0155 if (port_current == NULL) {
0156 printk("GDB: invalid minor number for UART\n");
0157 return;
0158 }
0159
0160 uart_current = uart;
0161
0162
0163 port_current->pDeviceFns->deviceInitialize(uart);
0164 }
0165
0166 static void BSP_uart_on(const rtems_raw_irq_connect_data* used)
0167 {
0168 bsp_interrupt_vector_enable(used->idtIndex - BSP_IRQ_VECTOR_BASE);
0169 }
0170
0171 static void BSP_uart_off(const rtems_raw_irq_connect_data* used)
0172 {
0173 bsp_interrupt_vector_disable(used->idtIndex - BSP_IRQ_VECTOR_BASE);
0174 }
0175
0176
0177
0178
0179
0180 void i386_stub_glue_init_breakin(void)
0181 {
0182 rtems_raw_irq_connect_data uart_raw_irq_data;
0183
0184 if (port_current == NULL) {
0185 printk("GDB: no port initialised\n");
0186 return;
0187 }
0188
0189 if ((port_current->ulIntVector == 0) || (port_current->ulIntVector > 16)) {
0190 printk("GDB: no UART interrupt support\n");
0191 }
0192 else {
0193 uart_vector = port_current->ulIntVector;
0194 uart_raw_irq_data.idtIndex = port_current->ulIntVector + BSP_IRQ_VECTOR_BASE;
0195
0196 if (!i386_get_current_idt_entry(&uart_raw_irq_data)) {
0197 printk("GBD: cannot get idt entry\n");
0198 rtems_fatal_error_occurred(1);
0199 }
0200
0201 if (!i386_delete_idt_entry(&uart_raw_irq_data)) {
0202 printk("GDB: cannot delete idt entry\n");
0203 rtems_fatal_error_occurred(1);
0204 }
0205
0206 uart_raw_irq_data.on = BSP_uart_on;
0207 uart_raw_irq_data.off = BSP_uart_off;
0208
0209
0210 uart_raw_irq_data.idtIndex = port_current->ulIntVector + BSP_IRQ_VECTOR_BASE;
0211 uart_raw_irq_data.hdl = i386_gdb_uart_isr;
0212
0213 if (!i386_set_idt_entry (&uart_raw_irq_data)) {
0214 printk("GDB: raw exception handler connection failed\n");
0215 rtems_fatal_error_occurred(1);
0216 }
0217
0218
0219
0220 (*port_current->setRegister)(port_current->ulCtrlPort1, 1, 0x01);
0221 }
0222 }
0223
0224 int
0225 putDebugChar(int ch)
0226 {
0227 if (port_current != NULL) {
0228 port_current->pDeviceFns->deviceWritePolled(uart_current, ch);
0229 }
0230 return 1;
0231 }
0232
0233 int getDebugChar(void)
0234 {
0235 int c = -1;
0236
0237 if (port_current != NULL) {
0238 while (c < 0)
0239 c = port_current->pDeviceFns->deviceRead(uart_current);
0240 }
0241
0242 return c;
0243 }
0244
0245 void exceptionHandler(int vector, void (*handler)(void))
0246 {
0247 rtems_raw_irq_connect_data excep_raw_irq_data;
0248
0249 excep_raw_irq_data.idtIndex = vector;
0250
0251 if(!i386_get_current_idt_entry(&excep_raw_irq_data))
0252 {
0253 printk("GDB: cannot get idt entry\n");
0254 rtems_fatal_error_occurred(1);
0255 }
0256
0257 if(!i386_delete_idt_entry(&excep_raw_irq_data))
0258 {
0259 printk("GDB: cannot delete idt entry\n");
0260 rtems_fatal_error_occurred(1);
0261 }
0262
0263 excep_raw_irq_data.on = nop;
0264 excep_raw_irq_data.off = nop;
0265 excep_raw_irq_data.isOn = isOn;
0266 excep_raw_irq_data.hdl = handler;
0267
0268 if (!i386_set_idt_entry (&excep_raw_irq_data)) {
0269 printk("GDB: raw exception handler connection failed\n");
0270 rtems_fatal_error_occurred(1);
0271 }
0272 return;
0273 }