1 | /** |
---|
2 | * @file |
---|
3 | * |
---|
4 | * @ingroup GDB |
---|
5 | * |
---|
6 | * @brief pc386 gdb select |
---|
7 | * |
---|
8 | * This file contains a routine to enable and select the UART the gdb stub |
---|
9 | * connects too. Currently limited to COM1 and COM2. See |
---|
10 | * shared/comm/i386-stub-glue.c file. |
---|
11 | */ |
---|
12 | |
---|
13 | /* |
---|
14 | * COPYRIGHT (c) 2016. |
---|
15 | * Chris Johns <chrisj@rtems.org> |
---|
16 | * |
---|
17 | * The license and distribution terms for this file may be |
---|
18 | * found in the file LICENSE in this distribution or at |
---|
19 | * http://www.rtems.org/license/LICENSE. |
---|
20 | */ |
---|
21 | |
---|
22 | #include <stdlib.h> |
---|
23 | #include <limits.h> |
---|
24 | |
---|
25 | #include <bsp.h> |
---|
26 | #include <rtems/libio.h> |
---|
27 | #include <rtems/console.h> |
---|
28 | #include <rtems/termiostypes.h> |
---|
29 | #include <libchip/serial.h> |
---|
30 | #include <libchip/ns16550.h> |
---|
31 | #include <bsp/bspimpl.h> |
---|
32 | |
---|
33 | #include "../../shared/dev/serial/legacy-console.h" |
---|
34 | |
---|
35 | /* |
---|
36 | * Used in the stub to print output. |
---|
37 | */ |
---|
38 | int remote_debug; |
---|
39 | /* |
---|
40 | * Defined in the stub, used here. |
---|
41 | */ |
---|
42 | void set_debug_traps(void); |
---|
43 | |
---|
44 | /* |
---|
45 | * Added here to get a valid baudrate. Needs to go once we |
---|
46 | * move to the standard UART driver. |
---|
47 | */ |
---|
48 | int BSPBaseBaud; |
---|
49 | |
---|
50 | static bool gdb_port_probe(int minor) |
---|
51 | { |
---|
52 | /* Return false as GDB has claimed the port */ |
---|
53 | return false; |
---|
54 | } |
---|
55 | |
---|
56 | void pc386_parse_gdb_arguments(void) |
---|
57 | { |
---|
58 | static const char *opt; |
---|
59 | |
---|
60 | /* |
---|
61 | * Check the command line to see if com1-com4 are disabled. |
---|
62 | */ |
---|
63 | opt = bsp_cmdline_arg("--gdb="); |
---|
64 | if ( opt ) { |
---|
65 | const char *option; |
---|
66 | const char *comma; |
---|
67 | size_t length; |
---|
68 | size_t index; |
---|
69 | rtems_device_minor_number minor; |
---|
70 | uint32_t baudrate = 115200; |
---|
71 | bool halt = false; |
---|
72 | console_tbl *port; |
---|
73 | |
---|
74 | /* |
---|
75 | * Fine the length, there can be more command line visible. |
---|
76 | */ |
---|
77 | length = 0; |
---|
78 | while ((opt[length] != ' ') && (opt[length] != '\0')) { |
---|
79 | ++length; |
---|
80 | if (length > NAME_MAX) { |
---|
81 | printk("invalid option (--gdb): too long\n"); |
---|
82 | return; |
---|
83 | } |
---|
84 | } |
---|
85 | |
---|
86 | /* |
---|
87 | * Only match up to a comma or NULL |
---|
88 | */ |
---|
89 | index = 0; |
---|
90 | while ((opt[index] != '=') && (index < length)) { |
---|
91 | ++index; |
---|
92 | } |
---|
93 | |
---|
94 | if (opt[index] != '=') { |
---|
95 | printk("invalid option (--gdb): no equals\n"); |
---|
96 | return; |
---|
97 | } |
---|
98 | |
---|
99 | ++index; |
---|
100 | option = &opt[index]; |
---|
101 | |
---|
102 | while ((opt[index] != ',') && (index < length)) { |
---|
103 | ++index; |
---|
104 | } |
---|
105 | |
---|
106 | if (opt[index] == ',') |
---|
107 | comma = &opt[index]; |
---|
108 | else |
---|
109 | comma = NULL; |
---|
110 | |
---|
111 | length = &opt[index] - option; |
---|
112 | |
---|
113 | port = console_find_console_entry( option, length, &minor ); |
---|
114 | |
---|
115 | if ( port == NULL ) { |
---|
116 | printk("invalid option (--gdb): port not found\n"); |
---|
117 | return; |
---|
118 | } |
---|
119 | |
---|
120 | if (comma) { |
---|
121 | option = comma + 1; |
---|
122 | baudrate = strtoul(option, 0, 10); |
---|
123 | switch (baudrate) { |
---|
124 | case 115200: |
---|
125 | case 57600: |
---|
126 | case 38400: |
---|
127 | case 19200: |
---|
128 | case 9600: |
---|
129 | case 4800: |
---|
130 | port->pDeviceParams = (void*) baudrate; |
---|
131 | BSPBaseBaud = baudrate; /* REMOVE ME */ |
---|
132 | break; |
---|
133 | default: |
---|
134 | printk("invalid option (--gdb): bad baudrate\n"); |
---|
135 | return; |
---|
136 | } |
---|
137 | } |
---|
138 | |
---|
139 | /* |
---|
140 | * Provide a probe that fails so the device is not part of termios. All |
---|
141 | * functions are polling. |
---|
142 | */ |
---|
143 | port->deviceProbe = gdb_port_probe; |
---|
144 | port->pDeviceFns = &ns16550_fns_polled; |
---|
145 | |
---|
146 | opt = bsp_cmdline_arg("--gdb-remote-debug"); |
---|
147 | if ( opt ) { |
---|
148 | remote_debug = 1; |
---|
149 | } |
---|
150 | |
---|
151 | opt = bsp_cmdline_arg("--gdb-break"); |
---|
152 | if ( opt ) { |
---|
153 | halt = true; |
---|
154 | } |
---|
155 | |
---|
156 | printk("GDB stub: enable %s%s%s\n", |
---|
157 | port->sDeviceName, |
---|
158 | remote_debug ? ", remote-debug" : "", |
---|
159 | halt ? ", halting" : ""); |
---|
160 | |
---|
161 | i386_stub_glue_init(minor); |
---|
162 | set_debug_traps(); |
---|
163 | i386_stub_glue_init_breakin(); |
---|
164 | |
---|
165 | if ( halt ) { |
---|
166 | printk("GDB stub: waiting for remote connection..\n"); |
---|
167 | breakpoint(); |
---|
168 | } |
---|
169 | } |
---|
170 | } |
---|