Skip to content

Commit bc69980

Browse files
committed
Adds support for the following GDB commands:
(1) 'g' : read general registers (2) 'G XX' : write general registers (3) 'p n ' : read the value of a specific register n (4) 'P n..=r..': write a specific register n with value r
1 parent b67a8c0 commit bc69980

File tree

2 files changed

+156
-3
lines changed

2 files changed

+156
-3
lines changed

src/libosd/gdbserver.c

Lines changed: 154 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16+
#include <osd/cl_cdm.h>
1617
#include <osd/gdbserver.h>
1718
#include <osd/module.h>
1819
#include <osd/osd.h>
@@ -39,6 +40,8 @@
3940
struct osd_gdbserver_ctx {
4041
struct osd_hostmod_ctx *hostmod_ctx;
4142
struct osd_log_ctx *log_ctx;
43+
struct osd_cdm_desc cdm_desc;
44+
uint16_t cdm_di_addr;
4245
int fd;
4346
char *name;
4447
char *port;
@@ -53,21 +56,25 @@ struct osd_gdbserver_ctx {
5356
API_EXPORT
5457
osd_result osd_gdbserver_new(struct osd_gdbserver_ctx **ctx,
5558
struct osd_log_ctx *log_ctx,
56-
const char *host_controller_address)
59+
const char *host_controller_address,
60+
uint16_t cdm_di_addr)
5761
{
5862
osd_result rv;
5963

6064
struct osd_gdbserver_ctx *c = calloc(1, sizeof(struct osd_gdbserver_ctx));
6165
assert(c);
6266

6367
c->log_ctx = log_ctx;
68+
c->cdm_di_addr = cdm_di_addr;
6469

6570
struct osd_hostmod_ctx *hostmod_ctx;
6671
rv = osd_hostmod_new(&hostmod_ctx, log_ctx, host_controller_address, NULL,
6772
NULL);
6873
assert(OSD_SUCCEEDED(rv));
6974
c->hostmod_ctx = hostmod_ctx;
7075

76+
// c->cdm_desc = cdm_desc;
77+
7178
*ctx = c;
7279

7380
return OSD_OK;
@@ -298,7 +305,7 @@ bool validate_rsp_packet(char *packet_buffer, int packet_len,
298305
}
299306

300307
static osd_result receive_rsp_packet(struct osd_gdbserver_ctx *ctx,
301-
int *packet_data_len, char *packet_data)
308+
char *packet_data, int *packet_data_len)
302309
{
303310
int packet_char;
304311
osd_result rv;
@@ -375,3 +382,148 @@ static osd_result send_rsp_packet(struct osd_gdbserver_ctx *ctx,
375382
}
376383
}
377384
}
385+
386+
static osd_result gdb_read_general_registers(struct osd_gdbserver_ctx *ctx,
387+
char *packet_buffer,
388+
int packet_len)
389+
{
390+
osd_result rv;
391+
// SPR register address mapped as GPR0 in OR1K
392+
// GROUP 0 REG_NUM 1024
393+
uint16_t reg_addr = 0x400;
394+
395+
rv =
396+
osd_cl_cdm_get_desc(ctx->hostmod_ctx, ctx->cdm_di_addr, &ctx->cdm_desc);
397+
if (OSD_FAILED(rv)) {
398+
return rv;
399+
}
400+
401+
int core_reg_len = ctx->cdm_desc.core_data_width;
402+
size_t reg_read_result[32];
403+
// + 1 for null character
404+
char *reg_val_packet = malloc((core_reg_len / 8) * 32 + 1);
405+
406+
// read the value of each GPR from the CPU core and
407+
// store it in the register packet
408+
for (int i = 0; i < 32; i++) {
409+
rv = cl_cdm_cpureg_read(ctx->hostmod_ctx, &ctx->cdm_desc,
410+
&reg_read_result[i], reg_addr + i, 0);
411+
if (OSD_FAILED(rv)) {
412+
return rv;
413+
}
414+
415+
char *reg_val = malloc((core_reg_len / 8) + 1);
416+
sprintf(reg_val, "%02lx", reg_read_result[i]);
417+
strcat(reg_packet, reg_val);
418+
free(reg_val);
419+
}
420+
421+
rv = send_rsp_packet(ctx, reg_val_packet, (core_reg_len / 8) * 32 + 1);
422+
if (OSD_FAILED(rv)) {
423+
return rv;
424+
}
425+
426+
free(reg_packet);
427+
428+
return OSD_OK;
429+
}
430+
431+
static osd_result gdb_write_general_registers(struct osd_gdbserver_ctx *ctx,
432+
char *packet, int packet_len)
433+
{
434+
osd_result rv;
435+
rv =
436+
osd_cl_cdm_get_desc(ctx->hostmod_ctx, ctx->cdm_di_addr, &ctx->cdm_desc);
437+
if (OSD_FAILED(rv)) {
438+
return rv;
439+
}
440+
441+
// increment by 1 to skip initial char 'G'
442+
packet++;
443+
// SPR register address mapped as GPR0 in OR1K
444+
// GROUP 0 REG_NUM 1024
445+
uint16_t reg_addr = 0x400;
446+
int core_reg_len = ctx->cdm_desc.core_data_width;
447+
448+
// write the value of each GPR in the CPU core
449+
for (int i = 0; i < 32; i++) {
450+
char cur_reg_val[core_reg_len / 4 + 1];
451+
for (int j = 0; j < core_reg_len / 4; j++) {
452+
cur_reg_val[j] = packet[i * core_reg_len + j];
453+
}
454+
455+
cur_reg_val[core_reg_len / 4] = '\0';
456+
size_t reg_val = strtoul(cur_reg_val, NULL, 16);
457+
rv = cl_cdm_cpureg_write(ctx->hostmod_ctx, &ctx->cdm_desc, &reg_val,
458+
reg_addr + i, 0);
459+
if (OSD_FAILED(rv)) {
460+
return rv;
461+
}
462+
}
463+
464+
rv = send_rsp_packet(ctx, "OK", 2);
465+
if (OSD_FAILED(rv)) {
466+
return rv;
467+
}
468+
469+
return OSD_OK;
470+
}
471+
472+
static osd_result gdb_read_register(struct osd_gdbserver_ctx *ctx, char *packet,
473+
int packet_len)
474+
{
475+
osd_result rv;
476+
uint16_t reg_addr = strtoul(packet + 1, NULL, 16);
477+
478+
rv =
479+
osd_cl_cdm_get_desc(ctx->hostmod_ctx, ctx->cdm_di_addr, &ctx->cdm_desc);
480+
if (OSD_FAILED(rv)) {
481+
return rv;
482+
}
483+
484+
int core_reg_len = ctx->cdm_desc.core_data_width;
485+
size_t reg_read_result;
486+
rv = cl_cdm_cpureg_read(ctx->hostmod_ctx, &ctx->cdm_desc, &reg_read_result,
487+
reg_addr, 0);
488+
if (OSD_FAILED(rv)) {
489+
return rv;
490+
}
491+
492+
char *reg_val = malloc(core_reg_len / 8 + 1);
493+
sprintf(reg_val, "%02lx", reg_read_result);
494+
rv = send_rsp_packet(ctx, reg_val, core_reg_len / 8 + 1);
495+
if (OSD_FAILED(rv)) {
496+
return rv;
497+
}
498+
499+
free(reg_val);
500+
501+
return OSD_OK;
502+
}
503+
504+
static osd_result gdb_write_register(struct osd_gdbserver_ctx *ctx,
505+
char *packet, int packet_len)
506+
{
507+
osd_result rv;
508+
char *equal_separator;
509+
uint16_t reg_addr = strtoul(packet + 1, &equal_separator, 16);
510+
rv =
511+
osd_cl_cdm_get_desc(ctx->hostmod_ctx, ctx->cdm_di_addr, &ctx->cdm_desc);
512+
if (OSD_FAILED(rv)) {
513+
return rv;
514+
}
515+
516+
size_t reg_val = strtoul(equal_separator + 1, NULL, 16);
517+
rv = cl_cdm_cpureg_write(ctx->hostmod_ctx, &ctx->cdm_desc, &reg_val,
518+
reg_addr, 0);
519+
if (OSD_FAILED(rv)) {
520+
return rv;
521+
}
522+
523+
rv = send_rsp_packet(ctx, "OK", 2);
524+
if (OSD_FAILED(rv)) {
525+
return rv;
526+
}
527+
528+
return OSD_OK;
529+
}

src/libosd/include/osd/gdbserver.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ struct osd_gdbserver_ctx;
4949
*/
5050
osd_result osd_gdbserver_new(struct osd_gdbserver_ctx **ctx,
5151
struct osd_log_ctx *log_ctx,
52-
const char *host_controller_address);
52+
const char *host_controller_address,
53+
uint16_t cdm_di_addr);
5354

5455
/**
5556
* Connect GDB server to the host controller followed by GDB

0 commit comments

Comments
 (0)