diff options
| author | Alistair Popple <alistair@popple.id.au> | 2016-11-22 12:46:35 +1100 |
|---|---|---|
| committer | Alistair Popple <alistair@popple.id.au> | 2016-11-22 12:51:27 +1100 |
| commit | adf7f8391b4e429668fdb9e8834de9a0570d533d (patch) | |
| tree | 8cba0452a65f8cc9dfeaa3e73d34ec3c9b8f73da /src | |
| parent | 749351433237295a86afcf451b947bc6621b946f (diff) | |
| download | pdbg-adf7f8391b4e429668fdb9e8834de9a0570d533d.tar.gz pdbg-adf7f8391b4e429668fdb9e8834de9a0570d533d.zip | |
libpdbg/chip.c: Add command to read virtual addresses
Adds a command to read a 64-bit word from a given virtual address. The
address is read in the current thread context and may cause an
exception. In the case of exception it will be raised on the host when
thread execution is resumed.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 30 |
1 files changed, 22 insertions, 8 deletions
@@ -36,7 +36,7 @@ enum command { GETCFAM = 1, PUTCFAM, GETSCOM, PUTSCOM, \ GETMEM, PUTMEM, GETGPR, GETNIA, GETSPR, \ GETMSR, PUTGPR, PUTNIA, PUTSPR, PUTMSR, \ STOPCHIP, STARTCHIP, THREADSTATUS, STEP, \ - PROBE }; + PROBE, GETVMEM }; #define MAX_CMD_ARGS 2 enum command cmd = 0; @@ -113,6 +113,7 @@ static void print_usage(char *pname) printf("\tgetscom <address>\n"); printf("\tputscom <address> <value>\n"); printf("\tgetmem <address> <count>\n"); + printf("\tgetvmem <virtual address>\n"); printf("\tgetgpr <gpr>\n"); printf("\tputgpr <gpr> <value>\n"); printf("\tgetnia\n"); @@ -167,6 +168,9 @@ enum command parse_cmd(char *optarg) } else if (strcmp(optarg, "putmsr") == 0) { cmd = PUTMSR; cmd_arg_count = 1; + } else if (strcmp(optarg, "getvmem") == 0) { + cmd = GETVMEM; + cmd_arg_count = 1; } else if (strcmp(optarg, "startchip") == 0) { cmd = STARTCHIP; cmd_arg_count = 0; @@ -616,11 +620,12 @@ static int startstopstep_thread(struct target *thread, uint64_t action, uint64_t */ static int startstopstep_chip(struct target *chiplet, uint64_t action, uint64_t *data) { - for_each_class_call(&threads, filter_parent, startstopstep_thread, chiplet, action, NULL); + for_each_class_call(&threads, filter_parent, startstopstep_thread, chiplet, action, data); return 0; } +#define REG_MEM -3ULL #define REG_MSR -2ULL #define REG_NIA -1ULL #define REG_R31 31ULL @@ -663,6 +668,7 @@ static int putreg(struct target *thread, uint64_t reg, uint64_t *data) static int getreg(struct target *thread, uint64_t reg, uint64_t *data) { uint64_t status = chiplet_thread_status(thread); + uint64_t addr = *data; if (status != (THREAD_STATUS_QUIESCE | THREAD_STATUS_ACTIVE)) { PR_ERROR("Thread %d not stopped. Use stopchip first.\n", thread->index); @@ -671,17 +677,22 @@ static int getreg(struct target *thread, uint64_t reg, uint64_t *data) return 0; } - if (reg == REG_NIA) + if (reg == REG_NIA) if (ram_getnia(thread, data)) PR_ERROR("Error reading register\n"); else printf("c%02d:t%d:nia = 0x%016llx\n", thread->next->index, thread->index, *data); - else if (reg == REG_MSR) - if (ram_getmsr(thread, data)) - PR_ERROR("Error reading register\n"); - else + else if (reg == REG_MSR) + if (ram_getmsr(thread, data)) + PR_ERROR("Error reading register\n"); + else printf("c%02d:t%d:msr = 0x%016llx\n", thread->next->index, thread->index, *data); - else if (reg <= REG_R31) + else if (reg == REG_MEM) + if (ram_getmem(thread, addr, data)) + PR_ERROR("Page fault reading memory\n"); + else + printf("c%02d:t%d:0x%016llx = 0x%016llx\n", thread->next->index, thread->index, addr, *data); + else if (reg <= REG_R31) if (ram_getgpr(thread, reg, data)) PR_ERROR("Error reading register\n"); else @@ -757,6 +768,9 @@ int main(int argc, char *argv[]) case PUTMSR: rc = for_each_class_call(&threads, NULL, putreg, NULL, REG_MSR, &cmd_args[0]); break; + case GETVMEM: + rc = for_each_class_call(&threads, NULL, getreg, NULL, REG_MEM, &cmd_args[0]); + break; case THREADSTATUS: printf(" t: 0 1 2 3 4 5 6 7\n"); rc = for_each_class_call(&chiplets, NULL, print_chiplet_thread_status, NULL, 0, 0); |

