summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/shared
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2016-04-08 18:39:38 +1000
committerChris Johns <chrisj@rtems.org>2016-05-11 11:45:01 +1000
commit014292a164b8bb5286b6c7dae7c37a469ef6f0cc (patch)
treec7343485ef520fc71f36e5cf8271e08a2c1de789 /c/src/lib/libbsp/i386/shared
parentbsp/qoriq: Add portal clear functions (diff)
downloadrtems-014292a164b8bb5286b6c7dae7c37a469ef6f0cc.tar.bz2
i386/pc386: Add support for the gdb stub to use available console drivers.
Move the gdb stub from the i386 UART code to use the libchip drivers. Use any ports discovered during the probes. Add gdb control to the boot command line. Change the device naming to the full device path, not a partial path. For example /dev/com1.
Diffstat (limited to 'c/src/lib/libbsp/i386/shared')
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO134
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c195
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/i386-stub.c179
3 files changed, 302 insertions, 206 deletions
diff --git a/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO b/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
index c57f5a5a85..d5e0326781 100644
--- a/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
+++ b/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
@@ -1,30 +1,31 @@
-1. Add GDB initilization to your target's code:
+i386/pc386 GDB Stub
-a) include file:
+The i386 GDB stub has been updated to use the libchip drivers for the
+NS16550. Make sure you have detect the device and you have added a console
+entry. On the PC the legacy and PCI boards are supported.
-#include <uart.h>
+This GDB stub glue code is specific to the UART protocol defined in libbchip.
-b) declare this variable:
+The pc386 BSP has boot command line options to manage GDB support.
-extern int BSPConsolePort;
+a) Find the minor number of the console device:
-c) To start-up GDB, run this:
+ #include <console_private.h>
- /* Init GDB glue */
+ rtems_device_minor_number minor = 0;
- if(BSPConsolePort != BSP_UART_COM2)
- {
- /*
- * If com2 is not used as console use it for
- * debugging
- */
- i386_stub_glue_init(BSP_UART_COM2);
- }
- else
- {
- /* Otherwise use com1 */
- i386_stub_glue_init(BSP_UART_COM1);
- }
+ if (console_find_console_entry("/dev/com1",
+ strlen("/dev/com1") - 1, &minor) == NULL)
+ error("driver not found\n");
+
+Note, this call is part of the private console API and may change.
+
+b) To start GDB stub, run this:
+
+ #include <bsp.h>
+
+ /* Init GDB glue */
+ i386_stub_glue_init(minor);
/* Init GDB stub itself */
set_debug_traps();
@@ -39,54 +40,45 @@ c) To start-up GDB, run this:
/* Put breakpoint in */
breakpoint();
-d) This is all you need to do for the target.
-
-2. Edit cmds: specify path to current directory and device used for debugging
- example of cmds is attached below. Make sure your paths are correct.
-3. type 'make'
-4. Boot o-pc386/<test>.exe on target computer, where <test> has the code from step 1. ( I modified and recompiled base_sp as the <test> )
-5. run 'i396-rtems-gdb --nx --command=./cmds o-pc386/<test>.coff
-
-=========================== example cmds ==============================
-/usr1/rtems/work/rtems/cpukit/ada
-/usr1/rtems/work/rtems/cpukit/libblock/src
-/usr1/rtems/work/rtems/cpukit/libcsupport/src
-/usr1/rtems/work/rtems/cpukit/libfs/src/dosfs
-/usr1/rtems/work/rtems/cpukit/libfs/src/imfs
-/usr1/rtems/work/rtems/cpukit/libmisc/capture
-/usr1/rtems/work/rtems/cpukit/libmisc/cpuuse
-/usr1/rtems/work/rtems/cpukit/libmisc/devnull
-/usr1/rtems/work/rtems/cpukit/libmisc/dummy
-/usr1/rtems/work/rtems/cpukit/libmisc/dumpbuf
-/usr1/rtems/work/rtems/cpukit/libmisc/monitor
-/usr1/rtems/work/rtems/cpukit/libmisc/mw-fb
-/usr1/rtems/work/rtems/cpukit/libmisc/rtmonuse
-/usr1/rtems/work/rtems/cpukit/libmisc/serdbg
-/usr1/rtems/work/rtems/cpukit/libmisc/shell
-/usr1/rtems/work/rtems/cpukit/libmisc/stackchk
-/usr1/rtems/work/rtems/cpukit/libmisc/untar
-/usr1/rtems/work/rtems/cpukit/libnetworking/arpa
-/usr1/rtems/work/rtems/cpukit/libnetworking/kern
-/usr1/rtems/work/rtems/cpukit/libnetworking/lib
-/usr1/rtems/work/rtems/cpukit/libnetworking/libc
-/usr1/rtems/work/rtems/cpukit/libnetworking/machine
-/usr1/rtems/work/rtems/cpukit/libnetworking/net
-/usr1/rtems/work/rtems/cpukit/libnetworking/netinet
-/usr1/rtems/work/rtems/cpukit/libnetworking/nfs
-/usr1/rtems/work/rtems/cpukit/libnetworking/rtems
-/usr1/rtems/work/rtems/cpukit/libnetworking/sys
-/usr1/rtems/work/rtems/cpukit/libnetworking/vm
-/usr1/rtems/work/rtems/cpukit/librpc/src/rpc
-/usr1/rtems/work/rtems/cpukit/librpc/src/xdr
-/usr1/rtems/work/rtems/cpukit/posix/src
-/usr1/rtems/work/rtems/cpukit/posix/inline/rtems/posix
-/usr1/rtems/work/rtems/cpukit/rtems/inline/rtems/rtems
-/usr1/rtems/work/rtems/cpukit/rtems/src
-/usr1/rtems/work/rtems/cpukit/sapi/inline/rtems
-/usr1/rtems/work/rtems/cpukit/sapi/src
-/usr1/rtems/work/rtems/cpukit/score/cpu/i386
-/usr1/rtems/work/rtems/cpukit/score/cpu/i386/rtems/score
-/usr1/rtems/work/rtems/cpukit/score/src
-/usr1/rtems/work/rtems/cpukit/score/inline/rtems/score
-set remotebaud 38400
-target remote /dev/ttyS1
+c) To run use GDB:
+
+ $ i386-rtems4.12-gdb hello.exe
+ GNU gdb (GDB) 7.11
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+ This is free software: you are free to change and redistribute it.
+ There is NO WARRANTY, to the extent permitted by law. Type "show copying"
+ and "show warranty" for details.
+ This GDB was configured as "--host=x86_64-freebsd10.1 --target=i386-rtems4.12".
+ Type "show configuration" for configuration details.
+ For bug reporting instructions, please see:
+ <http://www.gnu.org/software/gdb/bugs/>.
+ Find the GDB manual and other documentation resources online at:
+ <http://www.gnu.org/software/gdb/documentation/>.
+ For help, type "help".
+ Type "apropos word" to search for commands related to "word"...
+ Reading symbols from hello.exe...done.
+ (gdb) target remote /dev/cuaU5
+ Remote debugging using /dev/cuaU5
+ 0x00103fda in breakpoint () at i386-stub.c:1004
+ 1004 BREAKPOINT ();
+ (gdb) b Init
+ Breakpoint 1 at 0x1001e0: file init.c, line 29.
+ (gdb) c
+ Continuing.
+
+ Breakpoint 1, Init (ignored=1269800) at init.c:29
+ 29 {
+ (gdb)
+
+Pressing ^C works and if running the board should halt when GDB connects.
+
+e) Use ser2net to provide reomve access over a network to a board. Install the
+ser2net package and add a configuration for the port GDB connects to. For
+example:
+
+ 0005:raw:0:/dev/cuaU5:115200
+
+Start ser2net running then connect GDB using:
+
+ (gdb) target remote myhost:30005
diff --git a/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c b/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c
index 121eef1828..25a153ff93 100644
--- a/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c
+++ b/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c
@@ -1,23 +1,102 @@
/*
+ * Copyright (c) 2016.
+ * Chris Johns <chrisj@rtems.org>
+ *
* This software is Copyright (C) 1998 by T.sqware - all rights limited
* It is provided in to the public domain "as is", can be freely modified
* as far as this copyight notice is kept unchanged, but does not imply
* an endorsement by T.sqware of the product in which it is included.
*/
-#include <rtems/system.h>
-#include <rtems/score/cpu.h>
#include <bsp.h>
#include <bsp/irq.h>
-#include <uart.h>
-#include <assert.h>
+#include <libchip/serial.h>
+
+#include "../../../shared/console_private.h"
int putDebugChar(int ch); /* write a single character */
int getDebugChar(void); /* read and return a single char */
+/* Check is any characters received are a ^C */
+int i386_gdb_uart_ctrl_c_check(void);
+
+/* Raw interrupt handler. */
+void i386_gdb_uart_isr(void);
+
/* assign an exception handler */
void exceptionHandler(int, void (*handler)(void));
+/* User supplied remote debug option. */
+extern int remote_debug;
+
+/* Current uart and port used by the gdb stub */
+static int uart_current;
+static console_tbl* port_current;
+
+/*
+ * Interrupt service routine for all, it does it check whether ^C is received
+ * if yes it will flip TF bit before returning.
+ *
+ * Note: it should be installed as raw interrupt handler.
+ *
+ * Warning: I do not like the use of the global data, I am not
+ * sure if this is SMP safe.
+ */
+int i386_gdb_uart_isr_regsav[4] RTEMS_UNUSED;
+__asm__ (".p2align 4");
+__asm__ (".text");
+__asm__ (".globl i386_gdb_uart_isr");
+__asm__ ("i386_gdb_uart_isr:");
+__asm__ (" pusha"); /* Push all */
+__asm__ (" call i386_gdb_uart_ctrl_c_check"); /* Look for ^C */
+__asm__ (" movl %eax, i386_gdb_uart_isr_regsav"); /* Save eax */
+__asm__ (" popa"); /* Pop all */
+__asm__ (" xchgl %eax, i386_gdb_uart_isr_regsav"); /* Exchange eax */
+__asm__ (" cmpl $0, %eax"); /* 1 == ^C */
+__asm__ (" je i386_gdb_uart_isr_1"); /* branch if 0 */
+__asm__ (" movl %ebx, i386_gdb_uart_isr_regsav + 4"); /* Save ebx */
+__asm__ (" movl %edx, i386_gdb_uart_isr_regsav + 8"); /* Save edx */
+__asm__ (" popl %ebx"); /* Pop eip */
+__asm__ (" popl %edx"); /* Pop cs */
+__asm__ (" popl %eax"); /* Pop flags */
+__asm__ (" orl $0x100, %eax"); /* Modify it */
+__asm__ (" pushl %eax"); /* Push it back */
+__asm__ (" pushl %edx"); /* Push cs */
+__asm__ (" pushl %ebx"); /* Push eip */
+__asm__ (" movl i386_gdb_uart_isr_regsav + 4, %ebx"); /* Restore ebx */
+__asm__ (" movl i386_gdb_uart_isr_regsav + 8, %edx"); /* Restore edx */
+__asm__ ("i386_gdb_uart_isr_1:");
+__asm__ (" movb $0x20, %al");
+__asm__ (" outb %al, $0x20");
+__asm__ (" movl i386_gdb_uart_isr_regsav, %eax"); /* Restore eax */
+__asm__ (" iret"); /* Done */
+
+static int gdb_hello_index;
+static const char const* gdb_hello = "+";
+
+int i386_gdb_uart_ctrl_c_check(void)
+{
+ if (port_current) {
+ int c = 0;
+ while (c >= 0) {
+ c = port_current->pDeviceFns->deviceRead(uart_current);
+ if (c == 3) {
+ gdb_hello_index = 0;
+ return 1;
+ } else if (gdb_hello[gdb_hello_index] == (char) c) {
+ ++gdb_hello_index;
+ if (gdb_hello[gdb_hello_index] == '\0') {
+ gdb_hello_index = 0;
+ return 1;
+ }
+ } else {
+ gdb_hello_index = 0;
+ }
+ }
+ }
+ return 0;
+}
+
static void
nop(const rtems_raw_irq_connect_data* notused)
{
@@ -29,10 +108,12 @@ isOn(const rtems_raw_irq_connect_data* notused)
return 1;
}
-void BSP_loop(int uart);
-
-/* Current uart used by gdb stub */
-static int uart_current = 0;
+int i386_stub_glue_uart(void)
+{
+ if (port_current == NULL)
+ return -1;
+ return uart_current;
+}
/*
* Initialize glue code linking i386-stub with the rest of
@@ -41,12 +122,19 @@ static int uart_current = 0;
void
i386_stub_glue_init(int uart)
{
- assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+ rtems_device_minor_number minor = (rtems_device_minor_number) uart;
+
+ port_current = console_find_console_entry(NULL, 0, &minor);
+
+ if (port_current == NULL) {
+ printk("GDB: invalid minor number for UART\n");
+ return;
+ }
uart_current = uart;
- /* BSP_uart_init(uart, 38400, CHR_8_BITS, 0, 0, 0);*/
- BSP_uart_init(uart, 115200, CHR_8_BITS, 0, 0, 0);
+ /* Intialise the UART, assuming polled drivers */
+ port_current->pDeviceFns->deviceInitialize(uart);
}
static void BSP_uart_on(const rtems_raw_irq_connect_data* used)
@@ -72,76 +160,65 @@ void i386_stub_glue_init_breakin(void)
{
rtems_raw_irq_connect_data uart_raw_irq_data;
- assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);
+ if (port_current == NULL) {
+ printk("GDB: no port initialised\n");
+ return;
+ }
- if(uart_current == BSP_UART_COM1)
- {
- uart_raw_irq_data.idtIndex = BSP_UART_COM1_IRQ + BSP_IRQ_VECTOR_BASE;
- }
- else
- {
- uart_raw_irq_data.idtIndex = BSP_UART_COM2_IRQ + BSP_IRQ_VECTOR_BASE;
- }
+ if ((port_current->ulIntVector == 0) || (port_current->ulIntVector > 16)) {
+ printk("GDB: no UART interrupt support\n");
+ }
+ else {
+ uart_raw_irq_data.idtIndex = port_current->ulIntVector + BSP_IRQ_VECTOR_BASE;
- if(!i386_get_current_idt_entry(&uart_raw_irq_data))
- {
- printk("cannot get idt entry\n");
+ if (!i386_get_current_idt_entry(&uart_raw_irq_data)) {
+ printk("GBD: cannot get idt entry\n");
rtems_fatal_error_occurred(1);
}
- if(!i386_delete_idt_entry(&uart_raw_irq_data))
- {
- printk("cannot delete idt entry\n");
+ if (!i386_delete_idt_entry(&uart_raw_irq_data)) {
+ printk("GDB: cannot delete idt entry\n");
rtems_fatal_error_occurred(1);
}
- uart_raw_irq_data.on = BSP_uart_on;
- uart_raw_irq_data.off = BSP_uart_off;
- uart_raw_irq_data.isOn= BSP_uart_isOn;
+ uart_raw_irq_data.on = BSP_uart_on;
+ uart_raw_irq_data.off = BSP_uart_off;
+ uart_raw_irq_data.isOn= BSP_uart_isOn;
- /* Install ISR */
- if(uart_current == BSP_UART_COM1)
- {
- uart_raw_irq_data.idtIndex = BSP_UART_COM1_IRQ + BSP_IRQ_VECTOR_BASE;
- uart_raw_irq_data.hdl = BSP_uart_dbgisr_com1;
- }
- else
- {
- uart_raw_irq_data.idtIndex = BSP_UART_COM2_IRQ + BSP_IRQ_VECTOR_BASE;
- uart_raw_irq_data.hdl = BSP_uart_dbgisr_com2;
- }
+ /* Install ISR */
+ uart_raw_irq_data.idtIndex = port_current->ulIntVector + BSP_IRQ_VECTOR_BASE;
+ uart_raw_irq_data.hdl = i386_gdb_uart_isr;
- if (!i386_set_idt_entry (&uart_raw_irq_data))
- {
- printk("raw exception handler connection failed\n");
+ if (!i386_set_idt_entry (&uart_raw_irq_data)) {
+ printk("GDB: raw exception handler connection failed\n");
rtems_fatal_error_occurred(1);
}
- /* Enable interrupts */
- BSP_uart_intr_ctrl(uart_current, BSP_UART_INTR_CTRL_GDB);
-
- return;
+ /* Enable interrupts, this is a bit of a hack because we
+ * have to know the device but there is no other call. */
+ (*port_current->setRegister)(port_current->ulCtrlPort1, 1, 0x01);
+ }
}
int
putDebugChar(int ch)
{
- assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);
-
- BSP_uart_polled_write(uart_current, ch);
-
+ if (port_current != NULL) {
+ port_current->pDeviceFns->deviceWritePolled(uart_current, ch);
+ }
return 1;
}
int getDebugChar(void)
{
- int val;
-
- assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);
+ int c = -1;
- val = BSP_uart_polled_read(uart_current);
+ if (port_current != NULL) {
+ while (c < 0)
+ c = port_current->pDeviceFns->deviceRead(uart_current);
+ }
- return val;
+ return c;
}
void exceptionHandler(int vector, void (*handler)(void))
@@ -152,13 +229,13 @@ void exceptionHandler(int vector, void (*handler)(void))
if(!i386_get_current_idt_entry(&excep_raw_irq_data))
{
- printk("cannot get idt entry\n");
+ printk("GDB: cannot get idt entry\n");
rtems_fatal_error_occurred(1);
}
if(!i386_delete_idt_entry(&excep_raw_irq_data))
{
- printk("cannot delete idt entry\n");
+ printk("GDB: cannot delete idt entry\n");
rtems_fatal_error_occurred(1);
}
@@ -168,7 +245,7 @@ void exceptionHandler(int vector, void (*handler)(void))
excep_raw_irq_data.hdl = handler;
if (!i386_set_idt_entry (&excep_raw_irq_data)) {
- printk("raw exception handler connection failed\n");
+ printk("GDB: raw exception handler connection failed\n");
rtems_fatal_error_occurred(1);
}
return;
diff --git a/c/src/lib/libbsp/i386/shared/comm/i386-stub.c b/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
index bc72396370..b3630eec21 100644
--- a/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
+++ b/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
@@ -99,6 +99,8 @@
#include <string.h>
#include <stdbool.h>
+#include <bsp.h>
+
/*
* Prototypes we need to avoid warnings but not going into public space.
*/
@@ -150,11 +152,15 @@ enum regnames
/*
* these should not be static cuz they can be used outside this module
*/
-int registers[NUMREGS];
+
+int i386_gdb_registers[NUMREGS];
#define STACKSIZE 10000
-int remcomStack[STACKSIZE / sizeof (int)];
-static int *stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+int i386_gdb_remcomStack[STACKSIZE / sizeof (int)];
+int *i386_gdb_stackPtr = &i386_gdb_remcomStack[STACKSIZE / sizeof (int) - 1];
+
+
+static int gdb_connected;
/*************************** ASSEMBLY CODE MACROS *************************/
/* */
@@ -168,25 +174,25 @@ extern void
__asm__ (".text");
__asm__ (".globl return_to_prog");
__asm__ ("return_to_prog:");
-__asm__ (" movw registers+44, %ss");
-__asm__ (" movl registers+16, %esp");
-__asm__ (" movl registers+4, %ecx");
-__asm__ (" movl registers+8, %edx");
-__asm__ (" movl registers+12, %ebx");
-__asm__ (" movl registers+20, %ebp");
-__asm__ (" movl registers+24, %esi");
-__asm__ (" movl registers+28, %edi");
-__asm__ (" movw registers+48, %ds");
-__asm__ (" movw registers+52, %es");
-__asm__ (" movw registers+56, %fs");
-__asm__ (" movw registers+60, %gs");
-__asm__ (" movl registers+36, %eax");
+__asm__ (" movw i386_gdb_registers+44, %ss");
+__asm__ (" movl i386_gdb_registers+16, %esp");
+__asm__ (" movl i386_gdb_registers+4, %ecx");
+__asm__ (" movl i386_gdb_registers+8, %edx");
+__asm__ (" movl i386_gdb_registers+12, %ebx");
+__asm__ (" movl i386_gdb_registers+20, %ebp");
+__asm__ (" movl i386_gdb_registers+24, %esi");
+__asm__ (" movl i386_gdb_registers+28, %edi");
+__asm__ (" movw i386_gdb_registers+48, %ds");
+__asm__ (" movw i386_gdb_registers+52, %es");
+__asm__ (" movw i386_gdb_registers+56, %fs");
+__asm__ (" movw i386_gdb_registers+60, %gs");
+__asm__ (" movl i386_gdb_registers+36, %eax");
__asm__ (" pushl %eax"); /* saved eflags */
-__asm__ (" movl registers+40, %eax");
+__asm__ (" movl i386_gdb_registers+40, %eax");
__asm__ (" pushl %eax"); /* saved cs */
-__asm__ (" movl registers+32, %eax");
+__asm__ (" movl i386_gdb_registers+32, %eax");
__asm__ (" pushl %eax"); /* saved eip */
-__asm__ (" movl registers, %eax");
+__asm__ (" movl i386_gdb_registers, %eax");
/* use iret to restore pc and flags together so
that trace flag works right. */
__asm__ (" iret");
@@ -202,37 +208,37 @@ int gdb_i386vector = -1;
/* GDB stores segment registers in 32-bit words (that's just the way
m-i386v.h is written). So zero the appropriate areas in registers. */
#define SAVE_REGISTERS1() \
- __asm__ ("movl %eax, registers"); \
- __asm__ ("movl %ecx, registers+4"); \
- __asm__ ("movl %edx, registers+8"); \
- __asm__ ("movl %ebx, registers+12"); \
- __asm__ ("movl %ebp, registers+20"); \
- __asm__ ("movl %esi, registers+24"); \
- __asm__ ("movl %edi, registers+28"); \
- __asm__ ("movw $0, %ax"); \
- __asm__ ("movw %ds, registers+48"); \
- __asm__ ("movw %ax, registers+50"); \
- __asm__ ("movw %es, registers+52"); \
- __asm__ ("movw %ax, registers+54"); \
- __asm__ ("movw %fs, registers+56"); \
- __asm__ ("movw %ax, registers+58"); \
- __asm__ ("movw %gs, registers+60"); \
- __asm__ ("movw %ax, registers+62");
+ __asm__ ("movl %eax, i386_gdb_registers"); \
+ __asm__ ("movl %ecx, i386_gdb_registers+4"); \
+ __asm__ ("movl %edx, i386_gdb_registers+8"); \
+ __asm__ ("movl %ebx, i386_gdb_registers+12"); \
+ __asm__ ("movl %ebp, i386_gdb_registers+20"); \
+ __asm__ ("movl %esi, i386_gdb_registers+24"); \
+ __asm__ ("movl %edi, i386_gdb_registers+28"); \
+ __asm__ ("movw $0, %ax"); \
+ __asm__ ("movw %ds, i386_gdb_registers+48"); \
+ __asm__ ("movw %ax, i386_gdb_registers+50"); \
+ __asm__ ("movw %es, i386_gdb_registers+52"); \
+ __asm__ ("movw %ax, i386_gdb_registers+54"); \
+ __asm__ ("movw %fs, i386_gdb_registers+56"); \
+ __asm__ ("movw %ax, i386_gdb_registers+58"); \
+ __asm__ ("movw %gs, i386_gdb_registers+60"); \
+ __asm__ ("movw %ax, i386_gdb_registers+62");
#define SAVE_ERRCODE() \
- __asm__ ("popl %ebx"); \
+ __asm__ ("popl %ebx"); \
__asm__ ("movl %ebx, gdb_i386errcode");
#define SAVE_REGISTERS2() \
- __asm__ ("popl %ebx"); /* old eip */ \
- __asm__ ("movl %ebx, registers+32"); \
- __asm__ ("popl %ebx"); /* old cs */ \
- __asm__ ("movl %ebx, registers+40"); \
- __asm__ ("movw %ax, registers+42"); \
- __asm__ ("popl %ebx"); /* old eflags */ \
- __asm__ ("movl %ebx, registers+36"); \
- /* Now that we've done the pops, we can save the stack pointer."); */ \
- __asm__ ("movw %ss, registers+44"); \
- __asm__ ("movw %ax, registers+46"); \
- __asm__ ("movl %esp, registers+16");
+ __asm__ ("popl %ebx"); /* old eip */ \
+ __asm__ ("movl %ebx, i386_gdb_registers+32"); \
+ __asm__ ("popl %ebx"); /* old cs */ \
+ __asm__ ("movl %ebx, i386_gdb_registers+40"); \
+ __asm__ ("movw %ax, i386_gdb_registers+42"); \
+ __asm__ ("popl %ebx"); /* old eflags */ \
+ __asm__ ("movl %ebx, i386_gdb_registers+36"); \
+ /* Now that we've done the pops, we can save the stack pointer."); */ \
+ __asm__ ("movw %ss, i386_gdb_registers+44"); \
+ __asm__ ("movw %ax, i386_gdb_registers+46"); \
+ __asm__ ("movl %esp, i386_gdb_registers+16");
/* See if mem_fault_routine is set, if so just IRET to that address. */
#define CHECK_FAULT() \
@@ -449,7 +455,7 @@ extern void remcomHandler (void);
__asm__ ("_remcomHandler:");
__asm__ (" popl %eax"); /* pop off return address */
__asm__ (" popl %eax"); /* get the exception number */
-__asm__ (" movl stackPtr, %esp"); /* move to remcom stack area */
+__asm__ (" movl i386_gdb_stackPtr, %esp"); /* move to remcom stack area */
__asm__ (" pushl %eax"); /* push exception onto stack */
__asm__ (" call handle_exception"); /* this never returns */
@@ -508,10 +514,15 @@ getpacket (char *buffer)
xmitcsum += hex (getDebugChar () & 0x7f);
if ((remote_debug) && (checksum != xmitcsum))
{
- fprintf (stderr, "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
- checksum, xmitcsum, buffer);
+ printk ("bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
+ checksum, xmitcsum, buffer);
}
+ if (remote_debug) {
+ printk("GETP: $%s...%s\n", buffer,
+ checksum == xmitcsum ? "Ack" : "Nack");
+ }
+
if (checksum != xmitcsum)
putDebugChar ('-'); /* failed checksum */
else
@@ -539,13 +550,16 @@ getpacket (char *buffer)
static void
putpacket (char *buffer)
{
- unsigned char checksum;
- int count;
- char ch;
-
/* $<packet info>#<checksum>. */
- do
+ while (true)
{
+ unsigned char checksum;
+ int count;
+ char ch;
+
+ if (remote_debug)
+ printk("PUTP: $%s", buffer);
+
putDebugChar ('$');
checksum = 0;
count = 0;
@@ -562,9 +576,18 @@ putpacket (char *buffer)
putDebugChar (hexchars[checksum >> 4]);
putDebugChar (hexchars[checksum % 16]);
- }
- while ((getDebugChar () & 0x7f) != '+');
+ if (remote_debug)
+ printk("#%c%c...", hexchars[checksum >> 4], hexchars[checksum % 16]);
+ ch = getDebugChar () & 0x7f;
+ if (ch == '+') {
+ if (remote_debug)
+ printk("Ack\n");
+ break;
+ }
+ if (remote_debug)
+ printk("Nack(%c)\n", ch);
+ }
}
char remcomInBuffer[BUFMAX];
@@ -578,7 +601,7 @@ debug_error (
)
{
if (remote_debug)
- fprintf (stderr, format, parm);
+ printk (format, parm);
}
/* Address of a routine to RTE to if we get a memory fault. */
@@ -764,10 +787,10 @@ handle_exception (int exceptionVector)
gdb_i386vector = exceptionVector;
if (remote_debug)
- printf ("vector=%d, sr=0x%x, pc=0x%x\n",
+ printk ("GDB: EXECPTION: vector=%d, sr=0x%x, pc=0x%x\n",
exceptionVector,
- registers[PS],
- registers[PC]);
+ i386_gdb_registers[PS],
+ i386_gdb_registers[PC]);
/* Reply to host that an exception has occurred. Always return the
PC, SP, and FP, since gdb always wants them. */
@@ -779,31 +802,33 @@ handle_exception (int exceptionVector)
*ptr++ = hexchars[ESP];
*ptr++ = ':';
- mem2hex ((char *) &registers[ESP], ptr, REGBYTES, 0);
+ mem2hex ((char *) &i386_gdb_registers[ESP], ptr, REGBYTES, 0);
ptr += REGBYTES * 2;
*ptr++ = ';';
*ptr++ = hexchars[EBP];
*ptr++ = ':';
- mem2hex ((char *) &registers[EBP], ptr, REGBYTES, 0);
+ mem2hex ((char *) &i386_gdb_registers[EBP], ptr, REGBYTES, 0);
ptr += REGBYTES * 2;
*ptr++ = ';';
*ptr++ = hexchars[PC];
*ptr++ = ':';
- mem2hex ((char *) &registers[PC], ptr, REGBYTES, 0);
+ mem2hex ((char *) &i386_gdb_registers[PC], ptr, REGBYTES, 0);
ptr += REGBYTES * 2;
*ptr++ = ';';
*ptr = '\0';
- putpacket (remcomOutBuffer);
+ if (gdb_connected)
+ putpacket (remcomOutBuffer);
while (1 == 1)
{
error = 0;
remcomOutBuffer[0] = 0;
getpacket (remcomInBuffer);
+ gdb_connected = 1;
switch (remcomInBuffer[0])
{
case '?':
@@ -812,14 +837,14 @@ handle_exception (int exceptionVector)
remcomOutBuffer[2] = hexchars[sigval % 16];
remcomOutBuffer[3] = 0;
break;
- case 'd':
+ case 'd': /* remove */
remote_debug = !(remote_debug); /* toggle debug flag */
break;
case 'g': /* return the value of the CPU registers */
- mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);
+ mem2hex ((char *) i386_gdb_registers, remcomOutBuffer, NUMREGBYTES, 0);
break;
case 'G': /* set the value of the CPU registers - return OK */
- hex2mem (&remcomInBuffer[1], (char *) registers, NUMREGBYTES, 0);
+ hex2mem (&remcomInBuffer[1], (char *) i386_gdb_registers, NUMREGBYTES, 0);
strcpy (remcomOutBuffer, "OK");
break;
@@ -828,7 +853,7 @@ handle_exception (int exceptionVector)
if (hexToInt (&ptr, &reg)
&& *ptr++ == '=')
{
- hex2mem (ptr, (char *) &registers[reg], REGBYTES, 0);
+ hex2mem (ptr, (char *) &i386_gdb_registers[reg], REGBYTES, 0);
strcpy (remcomOutBuffer, "OK");
}
else
@@ -902,29 +927,31 @@ handle_exception (int exceptionVector)
/* try to read optional parameter, pc unchanged if no parm */
ptr = &remcomInBuffer[1];
if (hexToInt (&ptr, &addr))
- registers[PC] = addr;
+ i386_gdb_registers[PC] = addr;
/* clear the trace bit */
- registers[PS] &= 0xfffffeff;
+ i386_gdb_registers[PS] &= 0xfffffeff;
/* set the trace bit if we're stepping */
if (remcomInBuffer[0] == 's')
- registers[PS] |= 0x100;
+ i386_gdb_registers[PS] |= 0x100;
_returnFromException (); /* this is a jump */
-
break;
/* Detach. */
case 'D':
putpacket (remcomOutBuffer);
- registers[PS] &= 0xfffffeff;
+ i386_gdb_registers[PS] &= 0xfffffeff;
_returnFromException (); /* this is a jump */
-
break;
/* kill the program */
case 'k': /* do nothing */
+ bsp_reset();
+ continue;
+
+ default:
break;
} /* switch */
@@ -938,7 +965,7 @@ handle_exception (int exceptionVector)
void
set_debug_traps (void)
{
- stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+ i386_gdb_stackPtr = &i386_gdb_remcomStack[STACKSIZE / sizeof (int) - 1];
exceptionHandler (0, _catchException0);
exceptionHandler (1, _catchException1);