Changeset View
Changeset View
Standalone View
Standalone View
sys/gdb/gdb_packet.c
Show All 39 Lines | |||||
#include <machine/kdb.h> | #include <machine/kdb.h> | ||||
#include <gdb/gdb.h> | #include <gdb/gdb.h> | ||||
#include <gdb/gdb_int.h> | #include <gdb/gdb_int.h> | ||||
static char gdb_rxbuf[GDB_BUFSZ]; | static char gdb_rxbuf[GDB_BUFSZ]; | ||||
char *gdb_rxp = NULL; | char *gdb_rxp = NULL; | ||||
size_t gdb_rxsz = 0; | size_t gdb_rxsz = 0; | ||||
static char gdb_txbuf[GDB_BUFSZ]; | |||||
/* | |||||
* The goal here is to allow in-place framing without making the math around | |||||
* 'gdb_txbuf' more complicated. A generous reading of union special rule for | |||||
* "common initial sequence" suggests this may be valid in standard C99 and | |||||
* later. | |||||
*/ | |||||
static union { | |||||
struct _midbuf { | |||||
char mb_pad1; | |||||
char mb_buf[GDB_BUFSZ]; | |||||
char mb_pad2[4]; | |||||
} __packed txu_midbuf; | |||||
/* sizeof includes trailing nul byte and this is intentional. */ | |||||
char txu_fullbuf[GDB_BUFSZ + sizeof("$#..")]; | |||||
} gdb_tx_u; | |||||
#define gdb_txbuf gdb_tx_u.txu_midbuf.mb_buf | |||||
#define gdb_tx_fullbuf gdb_tx_u.txu_fullbuf | |||||
_Static_assert(sizeof(gdb_tx_u.txu_midbuf) == sizeof(gdb_tx_u.txu_fullbuf) && | |||||
offsetof(struct _midbuf, mb_buf) == 1, | |||||
"assertions necessary for correctness"); | |||||
char *gdb_txp = NULL; /* Used in inline functions. */ | char *gdb_txp = NULL; /* Used in inline functions. */ | ||||
#define C2N(c) (((c) < 'A') ? (c) - '0' : \ | #define C2N(c) (((c) < 'A') ? (c) - '0' : \ | ||||
10 + (((c) < 'a') ? (c) - 'A' : (c) - 'a')) | 10 + (((c) < 'a') ? (c) - 'A' : (c) - 'a')) | ||||
#define N2C(n) (((n) < 10) ? (n) + '0' : (n) + 'a' - 10) | #define N2C(n) (((n) < 10) ? (n) + '0' : (n) + 'a' - 10) | ||||
/* | /* | ||||
* Get a single character | * Get a single character | ||||
▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | |||||
gdb_tx_begin(char tp) | gdb_tx_begin(char tp) | ||||
{ | { | ||||
gdb_txp = gdb_txbuf; | gdb_txp = gdb_txbuf; | ||||
if (tp != '\0') | if (tp != '\0') | ||||
gdb_tx_char(tp); | gdb_tx_char(tp); | ||||
} | } | ||||
/* | |||||
* Take raw packet buffer and perform typical GDB packet framing, but not run- | |||||
* length encoding, before forwarding to driver ::gdb_sendpacket() routine. | |||||
*/ | |||||
static void | |||||
gdb_tx_sendpacket(void) | |||||
{ | |||||
size_t msglen, i; | |||||
unsigned char csum; | |||||
msglen = gdb_txp - gdb_txbuf; | |||||
/* Add GDB packet framing */ | |||||
gdb_tx_fullbuf[0] = '$'; | |||||
csum = 0; | |||||
for (i = 0; i < msglen; i++) | |||||
csum += (unsigned char)gdb_txbuf[i]; | |||||
snprintf(&gdb_tx_fullbuf[1 + msglen], 4, "#%02x", (unsigned)csum); | |||||
gdb_cur->gdb_sendpacket(gdb_tx_fullbuf, msglen + 4); | |||||
} | |||||
int | int | ||||
gdb_tx_end(void) | gdb_tx_end(void) | ||||
{ | { | ||||
const char *p; | const char *p; | ||||
int runlen; | int runlen; | ||||
unsigned char c, cksum; | unsigned char c, cksum; | ||||
do { | do { | ||||
if (gdb_cur->gdb_sendpacket != NULL) { | |||||
gdb_tx_sendpacket(); | |||||
goto getack; | |||||
} | |||||
gdb_cur->gdb_putc('$'); | gdb_cur->gdb_putc('$'); | ||||
cksum = 0; | cksum = 0; | ||||
p = gdb_txbuf; | p = gdb_txbuf; | ||||
while (p < gdb_txp) { | while (p < gdb_txp) { | ||||
/* Send a character and start run-length encoding. */ | /* Send a character and start run-length encoding. */ | ||||
c = *p++; | c = *p++; | ||||
gdb_cur->gdb_putc(c); | gdb_cur->gdb_putc(c); | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | do { | ||||
} | } | ||||
gdb_cur->gdb_putc('#'); | gdb_cur->gdb_putc('#'); | ||||
c = cksum >> 4; | c = cksum >> 4; | ||||
gdb_cur->gdb_putc(N2C(c)); | gdb_cur->gdb_putc(N2C(c)); | ||||
c = cksum & 0x0f; | c = cksum & 0x0f; | ||||
gdb_cur->gdb_putc(N2C(c)); | gdb_cur->gdb_putc(N2C(c)); | ||||
getack: | |||||
c = gdb_getc(); | c = gdb_getc(); | ||||
} while (c != '+'); | } while (c != '+'); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
gdb_tx_mem(const unsigned char *addr, size_t size) | gdb_tx_mem(const unsigned char *addr, size_t size) | ||||
▲ Show 20 Lines • Show All 82 Lines • Show Last 20 Lines |