Read registers from VB
This commit is contained in:
parent
bf969e72b4
commit
294324fe28
15
client.c
15
client.c
|
@ -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;
|
||||||
|
|
|
@ -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
163
main.c
|
@ -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, ®)) return 1;
|
if (!read_hex_byte(cmd + 13, ®)) 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], ®_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);
|
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;
|
||||||
|
|
2
makefile
2
makefile
|
@ -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
|
Loading…
Reference in New Issue