Read registers from VB

This commit is contained in:
Simon Gellis 2024-10-01 21:24:48 -04:00
parent bf969e72b4
commit 294324fe28
4 changed files with 170 additions and 13 deletions

View File

@ -1,5 +1,6 @@
#include <client.h> #include <client.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -193,6 +194,20 @@ bool rdb_client_write_str_hex(RdbClient *self, const char *str) {
return true; 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) { int rdb_client_send_packet(RdbClient *self) {
if (self->len + 3 > RDB_CLIENT_BUFLEN) { if (self->len + 3 > RDB_CLIENT_BUFLEN) {
return -1; return -1;

View File

@ -2,6 +2,7 @@
#define RDBSERVER_CLIENT_H_ #define RDBSERVER_CLIENT_H_
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
@ -20,6 +21,8 @@ ssize_t rdb_client_read(RdbClient *self, char *buf, size_t len);
void rdb_client_begin_packet(RdbClient *self); void rdb_client_begin_packet(RdbClient *self);
bool rdb_client_write_str(RdbClient *self, const char *str); 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_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); int rdb_client_send_packet(RdbClient *self);
#endif #endif

163
main.c
View File

@ -1,9 +1,11 @@
#include <client.h> #include <client.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <unistd.h> #include <unistd.h>
#include <vb.h>
const size_t BUFLEN = 8096; 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: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: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: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) { bool read_hex_digit(char digit, char *out) {
if (digit >= '0' && digit <= '9') { if (digit >= '0' && digit <= '9') {
*out = digit - '0'; *out = digit - '0';
@ -78,11 +111,23 @@ bool read_hex_byte(char *buf, char *val) {
return true; 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); rdb_client_begin_packet(client);
if (!strncmp(cmd, "\x03", cmdlen)) { 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); return rdb_client_send_packet(client);
} }
@ -122,7 +167,7 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) {
} else { } else {
if (!read_hex_byte(cmd + 13, &reg)) return 1; if (!read_hex_byte(cmd + 13, &reg)) return 1;
} }
if (reg < 33) { if (reg <= PC_INDEX) {
rdb_client_write_str(client, REGISTERS[(size_t) reg]); rdb_client_write_str(client, REGISTERS[(size_t) reg]);
} }
return rdb_client_send_packet(client); 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); return rdb_client_send_packet(client);
} }
if (!strncmp(cmd, "p", 1)) { if (!strncmp(cmd, "p", 1)) {
rdb_client_write_str(client, "00000000"); char reg_no;
if (cmd[2] == ';') {
if (!read_hex_digit(cmd[1], &reg_no)) {
return 1;
}
} else {
if (!read_hex_byte(cmd + 1, &reg_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], &reg_no)) {
return 1;
}
if (!read_hex_i32(cmd + 3, &reg_value)) {
return 1;
}
} else {
if (!read_hex_byte(cmd + 1, &reg_no)) {
return 1;
}
if (!read_hex_i32(cmd + 4, &reg_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); return rdb_client_send_packet(client);
} }
if (!strncmp(cmd, "Hc-1", 1)) { if (!strncmp(cmd, "Hc-1", 1)) {
@ -159,7 +250,7 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) {
return 0; return 0;
} }
if (!strncmp(cmd, "?", cmdlen)) { 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); return rdb_client_send_packet(client);
} }
if (!strncmp(cmd, "qMemoryRegionInfo:", 18)) { 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; RdbClient client;
rdb_client_init(&client, connfd); rdb_client_init(&client, connfd);
@ -224,7 +315,7 @@ int server(int connfd) {
} else { } else {
printf("received command \"%.*s\"\n", (int) len, buf); printf("received command \"%.*s\"\n", (int) len, buf);
fflush(stdout); fflush(stdout);
int res = handle_command(&client, buf, len); int res = handle_command(&client, buf, len, sim);
if (res != 0) { if (res != 0) {
return res; 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) { 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; short port;
if (argc > 1) { if (argc > 2) {
char *end; char *end;
port = (short) strtol(argv[1], &end, 10); port = (short) strtol(argv[2], &end, 10);
if (argv[1] == end) { if (argv[2] == end) {
perror("could not parse port"); perror("could not parse port");
return 1; return 1;
} }
@ -279,7 +418,7 @@ int main(int argc, char** argv) {
} }
printf("connected\n"); printf("connected\n");
int response = server(connfd); int response = server(connfd, &sim);
return close(connfd) return close(connfd)
|| close(fd) || close(fd)
|| response; || response;

View File

@ -1,6 +1,6 @@
build: build:
@mkdir -p 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: clean:
@rm -rf build @rm -rf build
.PHONY: build clean .PHONY: build clean