Werner Zeh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36019 )
Change subject: x86 gdb: Extend GDB stub memory access with word and dword access ......................................................................
x86 gdb: Extend GDB stub memory access with word and dword access
Add extension to the memory read and write commands so that one can define the access width to the memory. Up to now only byte access was possible. Now the user can specify whether he wants to access the memory ion 8- 16- or 32-bit. The extension keeps the original command format so that an unmodified GDB client can still use this commands as usual.
NOT FOR MERGE!!!
Change-Id: If0800577857471eef96550a2c7122032bd1b7f37 Signed-off-by: Werner Zeh werner.zeh@siemens.com --- M src/arch/x86/exception.c 1 file changed, 122 insertions(+), 4 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/19/36019/1
diff --git a/src/arch/x86/exception.c b/src/arch/x86/exception.c index 4759015..71d96fc 100644 --- a/src/arch/x86/exception.c +++ b/src/arch/x86/exception.c @@ -297,6 +297,46 @@ *buf = 0; }
+/* convert the memory pointed to by mem into hex, placing result in buf */ +/* return a pointer to the last char put in buf (null) */ +/* Use 16 bit wide memory access. */ +static void copy_to_hex_word(char *buf, void *addr, unsigned long count) +{ + unsigned short ch; + short *mem = addr; + + while (count--) { + ch = *mem++; + *buf++ = hexchars[(ch >> 12) & 0x0f]; + *buf++ = hexchars[(ch >> 8) & 0x0f]; + *buf++ = hexchars[(ch >> 4) & 0x0f]; + *buf++ = hexchars[ch & 0x0f]; + } + *buf = 0; +} + +/* convert the memory pointed to by mem into hex, placing result in buf */ +/* return a pointer to the last char put in buf (null) */ +/* Use 32 bit wide memory access. */ +static void copy_to_hex_long(char *buf, void *addr, unsigned long count) +{ + unsigned long ch; + long *mem = addr; + + while (count--) { + ch = *mem++; + *buf++ = hexchars[(ch >> 28) & 0x0f]; + *buf++ = hexchars[(ch >> 24) & 0x0f]; + *buf++ = hexchars[(ch >> 20) & 0x0f]; + *buf++ = hexchars[(ch >> 16) & 0x0f]; + *buf++ = hexchars[(ch >> 12) & 0x0f]; + *buf++ = hexchars[(ch >> 8) & 0x0f]; + *buf++ = hexchars[(ch >> 4) & 0x0f]; + *buf++ = hexchars[ch & 0x0f]; + } + *buf = 0; +} +
/* convert the hex array pointed to by buf into binary to be placed in mem */ /* return a pointer to the character AFTER the last byte written */ @@ -312,6 +352,46 @@ } }
+/* convert the hex array pointed to by buf into binary to be placed in mem */ +/* return a pointer to the character AFTER the last byte written */ +/* Use 16 bit wide memory access */ +static void copy_from_hex_word(void *addr, char *buf, unsigned long count) +{ + unsigned short ch; + short *mem = addr; + + while (count--) { + ch = 0; + ch |= hex(*buf++) << 12; + ch |= hex(*buf++) << 8; + ch |= hex(*buf++) << 4; + ch |= hex(*buf++); + *mem++ = ch; + } +} + +/* convert the hex array pointed to by buf into binary to be placed in mem */ +/* return a pointer to the character AFTER the last byte written */ +/* Use 32 bit wide memory access */ +static void copy_from_hex_long(void *addr, char *buf, unsigned long count) +{ + unsigned long ch; + long *mem = addr; + + while (count--) { + ch = 0; + ch |= hex(*buf++) << 28; + ch |= hex(*buf++) << 24; + ch |= hex(*buf++) << 20; + ch |= hex(*buf++) << 16; + ch |= hex(*buf++) << 12; + ch |= hex(*buf++) << 8; + ch |= hex(*buf++) << 4; + ch |= hex(*buf++); + *mem++ = ch; + } +} +
/* scan for the sequence $<data>#<checksum> */
@@ -475,25 +555,63 @@ memcpy(out_buffer, "OK", 3); break; case 'm': - /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + /* mAA..AA,LLLL,w Read LLLL bytes at address AA..AA */ + /* ,w is optional and can define the access width to */ + /* the memory (b: 8bit, w:16 bit, l: 32 bit */ ptr = &in_buffer[1]; if (parse_ulong(&ptr, &addr) && (*ptr++ == ',') && parse_ulong(&ptr, &length)) { - copy_to_hex(out_buffer, (void *)addr, length); + if (*ptr != ',') { + copy_to_hex(out_buffer, (void *)addr, + length); + } else { + char width = *(++ptr); + if (width == 'l') { + copy_to_hex_long(out_buffer, + (void *)addr, + length); + } else if (width == 'w') { + copy_to_hex_word(out_buffer, + (void *)addr, + length); + } else { + memcpy(out_buffer, "E01", 4); + } + } } else memcpy(out_buffer, "E01", 4); break; case 'M': - /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA + /* MAA..AA,LLLL:,w Write LLLL bytes at address AA.AA * return OK + * ,w is optional and can define the access width to + * the memory (b: 8bit, w:16 bit, l: 32 bit */ ptr = &in_buffer[1]; if (parse_ulong(&ptr, &addr) && (*(ptr++) == ',') && parse_ulong(&ptr, &length) && (*(ptr++) == ':')) { - copy_from_hex((void *)addr, ptr, length); + if (*ptr != ',') { + copy_from_hex((void *)addr, ptr, + length); + } else { + char width; + ptr++; /* move away from ',' */ + width = *ptr++; + if (width == 'l') { + copy_from_hex_long((void *)addr, + ptr, + length); + } else if (width == 'w') { + copy_from_hex_word((void *)addr, + ptr, + length); + } else { + memcpy(out_buffer, "E02", 4); + } + } memcpy(out_buffer, "OK", 3); } else memcpy(out_buffer, "E02", 4);