Skip to content

Commit 86cef0f

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 86cef0f

File tree

2 files changed

+157
-3
lines changed

2 files changed

+157
-3
lines changed

src/libosd/gdbserver.c

Lines changed: 155 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,149 @@ static osd_result send_rsp_packet(struct osd_gdbserver_ctx *ctx,
375382
}
376383
}
377384
}
385+
386+
static osd_result gdb_read_general_registers_cmd(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+
// used for storing the read register value of all the GPRs
405+
char *reg_packet = malloc((core_reg_len / 8) * 32 + 1);
406+
407+
// read the value of each GPR from the CPU core and
408+
// store it in the register packet
409+
for (int i = 0; i < 32; i++) {
410+
rv = cl_cdm_cpureg_read(ctx->hostmod_ctx, &ctx->cdm_desc,
411+
&reg_read_result[i], reg_addr + i, 0);
412+
if (OSD_FAILED(rv)) {
413+
return rv;
414+
}
415+
416+
char *reg_val = malloc((core_reg_len / 8) + 1);
417+
sprintf(reg_val, "%02lx", reg_read_result[i]);
418+
strcat(reg_packet, reg_val);
419+
free(reg_val);
420+
}
421+
422+
rv = send_rsp_packet(ctx, reg_packet, (core_reg_len / 8) * 32 + 1);
423+
if (OSD_FAILED(rv)) {
424+
return rv;
425+
}
426+
427+
free(reg_packet);
428+
429+
return OSD_OK;
430+
}
431+
432+
static osd_result gdb_write_general_registers_cmd(struct osd_gdbserver_ctx *ctx,
433+
char *packet, int packet_len)
434+
{
435+
osd_result rv;
436+
rv =
437+
osd_cl_cdm_get_desc(ctx->hostmod_ctx, ctx->cdm_di_addr, &ctx->cdm_desc);
438+
if (OSD_FAILED(rv)) {
439+
return rv;
440+
}
441+
442+
// increment by 1 to skip initial char 'G'
443+
packet++;
444+
// SPR register address mapped as GPR0 in OR1K
445+
// GROUP 0 REG_NUM 1024
446+
uint16_t reg_addr = 0x400;
447+
int core_reg_len = ctx->cdm_desc.core_data_width;
448+
449+
// write the value of each GPR in the CPU core
450+
for (int i = 0; i < 32; i++) {
451+
char cur_reg_val[core_reg_len / 4 + 1];
452+
for (int j = 0; j < core_reg_len / 4; j++) {
453+
cur_reg_val[j] = packet[i * core_reg_len + j];
454+
}
455+
456+
cur_reg_val[core_reg_len / 4] = '\0';
457+
size_t reg_val = strtoul(cur_reg_val, NULL, 16);
458+
rv = cl_cdm_cpureg_write(ctx->hostmod_ctx, &ctx->cdm_desc, &reg_val,
459+
reg_addr + i, 0);
460+
if (OSD_FAILED(rv)) {
461+
return rv;
462+
}
463+
}
464+
465+
rv = send_rsp_packet(ctx, "OK", 2);
466+
if (OSD_FAILED(rv)) {
467+
return rv;
468+
}
469+
470+
return OSD_OK;
471+
}
472+
473+
static osd_result gdb_read_register_cmd(struct osd_gdbserver_ctx *ctx,
474+
char *packet, int packet_len)
475+
{
476+
osd_result rv;
477+
uint16_t reg_addr = strtoul(packet + 1, NULL, 16);
478+
479+
rv =
480+
osd_cl_cdm_get_desc(ctx->hostmod_ctx, ctx->cdm_di_addr, &ctx->cdm_desc);
481+
if (OSD_FAILED(rv)) {
482+
return rv;
483+
}
484+
485+
int core_reg_len = ctx->cdm_desc.core_data_width;
486+
size_t reg_read_result;
487+
rv = cl_cdm_cpureg_read(ctx->hostmod_ctx, &ctx->cdm_desc, &reg_read_result,
488+
reg_addr, 0);
489+
if (OSD_FAILED(rv)) {
490+
return rv;
491+
}
492+
493+
char *reg_val = malloc(core_reg_len / 8 + 1);
494+
sprintf(reg_val, "%02lx", reg_read_result);
495+
rv = send_rsp_packet(ctx, reg_val, core_reg_len / 8 + 1);
496+
if (OSD_FAILED(rv)) {
497+
return rv;
498+
}
499+
500+
free(reg_val);
501+
502+
return OSD_OK;
503+
}
504+
505+
static osd_result gdb_write_register_cmd(struct osd_gdbserver_ctx *ctx,
506+
char *packet, int packet_len)
507+
{
508+
osd_result rv;
509+
char *equal_separator;
510+
uint16_t reg_addr = strtoul(packet + 1, &equal_separator, 16);
511+
rv =
512+
osd_cl_cdm_get_desc(ctx->hostmod_ctx, ctx->cdm_di_addr, &ctx->cdm_desc);
513+
if (OSD_FAILED(rv)) {
514+
return rv;
515+
}
516+
517+
size_t reg_val = strtoul(equal_separator + 1, NULL, 16);
518+
rv = cl_cdm_cpureg_write(ctx->hostmod_ctx, &ctx->cdm_desc, &reg_val,
519+
reg_addr, 0);
520+
if (OSD_FAILED(rv)) {
521+
return rv;
522+
}
523+
524+
rv = send_rsp_packet(ctx, "OK", 2);
525+
if (OSD_FAILED(rv)) {
526+
return rv;
527+
}
528+
529+
return OSD_OK;
530+
}

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)