From 294324fe28de6c9262b5f29e2e38fa823358dc45 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Tue, 1 Oct 2024 21:24:48 -0400 Subject: [PATCH] Read registers from VB --- client.c | 15 +++++ include/client.h | 3 + main.c | 163 +++++++++++++++++++++++++++++++++++++++++++---- makefile | 2 +- 4 files changed, 170 insertions(+), 13 deletions(-) diff --git a/client.c b/client.c index 875d947..4b3c27d 100644 --- a/client.c +++ b/client.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -193,6 +194,20 @@ bool rdb_client_write_str_hex(RdbClient *self, const char *str) { return true; } +bool rdb_client_write_i8_hex(RdbClient *self, uint8_t value) { + char hi, lo; + return char_to_hex_digits(value, &hi, &lo) + && write_char(self, hi) + && write_char(self, lo); +} + +bool rdb_client_write_i32_hex(RdbClient *self, uint32_t value) { + return rdb_client_write_i8_hex(self, (uint8_t) value) + && rdb_client_write_i8_hex(self, (uint8_t) (value >> 8)) + && rdb_client_write_i8_hex(self, (uint8_t) (value >> 16)) + && rdb_client_write_i8_hex(self, (uint8_t) (value >> 24)); +} + int rdb_client_send_packet(RdbClient *self) { if (self->len + 3 > RDB_CLIENT_BUFLEN) { return -1; diff --git a/include/client.h b/include/client.h index 68d71d3..8dba7e0 100644 --- a/include/client.h +++ b/include/client.h @@ -2,6 +2,7 @@ #define RDBSERVER_CLIENT_H_ #include +#include #include #include @@ -20,6 +21,8 @@ ssize_t rdb_client_read(RdbClient *self, char *buf, size_t len); void rdb_client_begin_packet(RdbClient *self); bool rdb_client_write_str(RdbClient *self, const char *str); bool rdb_client_write_str_hex(RdbClient *self, const char *str); +bool rdb_client_write_i8_hex(RdbClient *self, uint8_t value); +bool rdb_client_write_i32_hex(RdbClient *self, uint32_t value); int rdb_client_send_packet(RdbClient *self); #endif \ No newline at end of file diff --git a/main.c b/main.c index f13836b..be2771c 100644 --- a/main.c +++ b/main.c @@ -1,9 +1,11 @@ #include #include #include +#include #include #include #include +#include const size_t BUFLEN = 8096; @@ -40,9 +42,40 @@ const char* REGISTERS[] = { "name:r29;bitsize:32;offset:116;encoding:uint;format:hex;set:General Purpose Registers;dwarf:0", "name:r30;bitsize:32;offset:120;encoding:uint;format:hex;set:General Purpose Registers;dwarf:0", "name:lp;alt-name:r31;bitsize:32;offset:124;encoding:uint;format:hex;set:General Purpose Registers;dwarf:0;generic:ra", - "name:pc;bitsize:32;offset:128;encoding:uint;format:hex;set:Special Registers;dwarf:0;generic:pc", + "name:eipc;alt-name:sr0;bitsize:32;offset:128;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:eipsw;alt-name:sr1;bitsize:32;offset:132;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:fepc;alt-name:sr2;bitsize:32;offset:136;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:fepsw;alt-name:sr3;bitsize:32;offset:140;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:ecr;alt-name:sr4;bitsize:32;offset:144;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:psw;alt-name:sr5;bitsize:32;offset:148;encoding:uint;format:hex;set:Special Registers;dwarf:0;generic:flags", + "name:pir;alt-name:sr6;bitsize:32;offset:152;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:tkcw;alt-name:sr7;bitsize:32;offset:156;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:chcw;alt-name:sr24;bitsize:32;offset:160;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:adtre;alt-name:sr25;bitsize:32;offset:164;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:sr29;bitsize:32;offset:168;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:sr30;bitsize:32;offset:172;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:sr31;bitsize:32;offset:176;encoding:uint;format:hex;set:Special Registers;dwarf:0", + "name:pc;bitsize:32;offset:180;encoding:uint;format:hex;set:Special Registers;dwarf:0;generic:pc", }; +const uint32_t SYSTEM_REGISTERS[] = { + VB_EIPC, + VB_EIPSW, + VB_FEPC, + VB_FEPSW, + VB_ECR, + VB_PSW, + VB_PIR, + VB_TKCW, + VB_CHCW, + VB_ADTRE, + 29, + 30, + 31, +}; + +const char PC_INDEX = 32 + 13; + bool read_hex_digit(char digit, char *out) { if (digit >= '0' && digit <= '9') { *out = digit - '0'; @@ -78,11 +111,23 @@ bool read_hex_byte(char *buf, char *val) { return true; } -int handle_command(RdbClient *client, char *cmd, size_t cmdlen) { +bool read_hex_i32(char *buf, int32_t *val) { + char byte; + *val = 0; + for (int i = 0; i < 8; i += 2) { + if (!read_hex_byte(buf + i, &byte)) { + return false; + } + *val |= ((int32_t) (uint8_t) byte) << i; + } + return true; +} + +int handle_command(RdbClient *client, char *cmd, size_t cmdlen, VB *sim) { rdb_client_begin_packet(client); if (!strncmp(cmd, "\x03", cmdlen)) { - rdb_client_write_str(client, "T05thread:p1.t1;threads:p1.t1;thread-pcs:07000000;00:00000000;01:00000001;20;07000000"); + rdb_client_write_str(client, "T05thread:p1.t1;threads:p1.t1"); return rdb_client_send_packet(client); } @@ -122,7 +167,7 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) { } else { if (!read_hex_byte(cmd + 13, ®)) return 1; } - if (reg < 33) { + if (reg <= PC_INDEX) { rdb_client_write_str(client, REGISTERS[(size_t) reg]); } return rdb_client_send_packet(client); @@ -147,7 +192,53 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) { return rdb_client_send_packet(client); } if (!strncmp(cmd, "p", 1)) { - rdb_client_write_str(client, "00000000"); + char reg_no; + if (cmd[2] == ';') { + if (!read_hex_digit(cmd[1], ®_no)) { + return 1; + } + } else { + if (!read_hex_byte(cmd + 1, ®_no)) { + return 1; + } + } + int32_t reg_value; + if (reg_no == PC_INDEX) { + reg_value = vbGetProgramCounter(sim); + } else if (reg_no > 31) { + reg_value = vbGetSystemRegister(sim, SYSTEM_REGISTERS[reg_no - 32]); + } else { + reg_value = vbGetProgramRegister(sim, reg_no); + } + rdb_client_write_i32_hex(client, reg_value); + return rdb_client_send_packet(client); + } + if (!strncmp(cmd, "P", 1)) { + char reg_no; + int32_t reg_value; + if (cmd[2] == '=') { + if (!read_hex_digit(cmd[1], ®_no)) { + return 1; + } + if (!read_hex_i32(cmd + 3, ®_value)) { + return 1; + } + } else { + if (!read_hex_byte(cmd + 1, ®_no)) { + return 1; + } + if (!read_hex_i32(cmd + 4, ®_value)) { + return 1; + } + } + if (reg_no == PC_INDEX) { + vbSetProgramCounter(sim, reg_value); + } else if (reg_no > 31) { + vbSetSystemRegister(sim, SYSTEM_REGISTERS[reg_no - 32], reg_value); + } else { + vbSetProgramRegister(sim, reg_no, reg_value); + } + rdb_client_write_str(client, "OK"); return rdb_client_send_packet(client); } if (!strncmp(cmd, "Hc-1", 1)) { @@ -159,7 +250,7 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) { return 0; } if (!strncmp(cmd, "?", cmdlen)) { - rdb_client_write_str(client, "T00thread:p1.t1;threads:p1.t1;thread-pcs:00000007;"); + rdb_client_write_str(client, "T00thread:p1.t1;threads:p1.t1;"); return rdb_client_send_packet(client); } if (!strncmp(cmd, "qMemoryRegionInfo:", 18)) { @@ -208,7 +299,7 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) { } -int server(int connfd) { +int server(int connfd, VB *sim) { RdbClient client; rdb_client_init(&client, connfd); @@ -224,7 +315,7 @@ int server(int connfd) { } else { printf("received command \"%.*s\"\n", (int) len, buf); fflush(stdout); - int res = handle_command(&client, buf, len); + int res = handle_command(&client, buf, len, sim); if (res != 0) { return res; } @@ -232,15 +323,63 @@ int server(int connfd) { } } +} +int readROM(VB *sim, char *filename) { + FILE *file = fopen(filename, "rb"); + long size; + + if (!file) { + perror("could not open file"); + return 1; + } + + if (fseek(file, 0, SEEK_END)) { + perror("could not seek file end"); + return 1; + } + size = ftell(file); + if (size == -1) { + perror("could not read file size"); + return 1; + } + if (fseek(file, 0, SEEK_SET)) { + perror("could not seek file start"); + return 1; + } + + sim->cart.rom = malloc(size); + sim->cart.romMask = size - 1; + + fread(sim->cart.rom, 1, size, file); + if (ferror(file)) { + perror("could not read file"); + return 1; + } + if (fclose(file)) { + perror("could not close file"); + return 1; + } + + return 0; } int main(int argc, char** argv) { + if (argc < 2) { + fprintf(stderr, "Please pass a ROM file\n"); + return 1; + } + VB sim; + if (readROM(&sim, argv[1])) { + return 1; + } + vbSetProgramCounter(&sim, 0x07000000); + short port; - if (argc > 1) { + if (argc > 2) { char *end; - port = (short) strtol(argv[1], &end, 10); - if (argv[1] == end) { + port = (short) strtol(argv[2], &end, 10); + if (argv[2] == end) { perror("could not parse port"); return 1; } @@ -279,7 +418,7 @@ int main(int argc, char** argv) { } printf("connected\n"); - int response = server(connfd); + int response = server(connfd, &sim); return close(connfd) || close(fd) || response; diff --git a/makefile b/makefile index 7d2211c..5eb48a6 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ build: @mkdir -p build - @gcc main.c client.c -I include -Werror -Wall -Wextra -o ./build/rdb + @gcc main.c client.c ../vbtest/vb.c -I include -I ../vbtest -Werror -Wall -Wextra -o ./build/rdb clean: @rm -rf build .PHONY: build clean \ No newline at end of file