@ -33,6 +33,10 @@
#define DBG_CORE_STAT_TERM (1 << 2)
#define DBG_CORE_STAT_TERM (1 << 2)
#define DBG_CORE_NIA 0x12
#define DBG_CORE_NIA 0x12
#define DBG_CORE_MSR 0x13
#define DBG_CORE_GSPR_INDEX 0x14
#define DBG_CORE_GSPR_DATA 0x15
static bool debug;
static bool debug;
@ -356,11 +360,12 @@ static int dmi_write(uint8_t addr, uint64_t data)
static void core_status(void)
static void core_status(void)
{
{
uint64_t stat, nia;
uint64_t stat, nia, msr;
const char *statstr, *statstr2;
const char *statstr, *statstr2;
check(dmi_read(DBG_CORE_STAT, &stat), "reading core status");
check(dmi_read(DBG_CORE_STAT, &stat), "reading core status");
check(dmi_read(DBG_CORE_NIA, &nia), "reading core NIA");
check(dmi_read(DBG_CORE_NIA, &nia), "reading core NIA");
check(dmi_read(DBG_CORE_MSR, &msr), "reading core MSR");
if (debug)
if (debug)
printf("Core status = 0x%llx\n", (unsigned long long)stat);
printf("Core status = 0x%llx\n", (unsigned long long)stat);
@ -378,6 +383,7 @@ static void core_status(void)
statstr = "odd state (TERM but no STOP)";
statstr = "odd state (TERM but no STOP)";
printf("Core: %s%s\n", statstr, statstr2);
printf("Core: %s%s\n", statstr, statstr2);
printf(" NIA: %016llx\n", (unsigned long long)nia);
printf(" NIA: %016llx\n", (unsigned long long)nia);
printf(" MSR: %016llx\n", msr);
}
}
static void core_stop(void)
static void core_stop(void)
@ -392,7 +398,7 @@ static void core_start(void)
static void core_reset(void)
static void core_reset(void)
{
{
check(dmi_write(DBG_CORE_CTRL, DBG_CORE_CTRL_START), "resetting core");
check(dmi_write(DBG_CORE_CTRL, DBG_CORE_CTRL_RESET), "resetting core");
}
}
static void core_step(void)
static void core_step(void)
@ -413,19 +419,47 @@ static void icache_reset(void)
check(dmi_write(DBG_CORE_CTRL, DBG_CORE_CTRL_ICRESET), "resetting icache");
check(dmi_write(DBG_CORE_CTRL, DBG_CORE_CTRL_ICRESET), "resetting icache");
}
}
static const char *fast_spr_names[] =
{
"lr", "ctr", "srr0", "srr1", "hsrr0", "hsrr1",
"sprg0", "sprg1", "sprg2", "sprg3",
"hsprg0", "hsprg1", "xer"
};
static void gpr_read(uint64_t reg, uint64_t count)
{
uint64_t data;
reg &= 0x3f;
if (reg + count > 64)
count = 64 - reg;
for (; count != 0; --count, ++reg) {
check(dmi_write(DBG_CORE_GSPR_INDEX, reg), "setting GPR index");
data = 0xdeadbeef;
check(dmi_read(DBG_CORE_GSPR_DATA, &data), "reading GPR data");
if (reg <= 31)
printf("r%d", reg);
else if ((reg - 32) < sizeof(fast_spr_names) / sizeof(fast_spr_names[0]))
printf("%s", fast_spr_names[reg - 32]);
else
printf("gspr%d", reg);
printf(":\t%016llx\n", data);
}
}
static void mem_read(uint64_t addr, uint64_t count)
static void mem_read(uint64_t addr, uint64_t count)
{
{
uint64_t data;
uint64_t data;
int i, rc;
int i, rc;
rc = dmi_write(2, 0x7ff);
rc = dmi_write(DBG_WB_CTRL, 0x7ff);
if (rc < 0)
if (rc < 0)
return;
return;
rc = dmi_write(0, addr);
rc = dmi_write(DBG_WB_ADDR, addr);
if (rc < 0)
if (rc < 0)
return;
return;
for (i = 0; i < count; i++) {
for (i = 0; i < count; i++) {
rc = dmi_read(1, &data);
rc = dmi_read(DBG_WB_DATA, &data);
if (rc < 0)
if (rc < 0)
return;
return;
printf("%016llx: %016llx\n",
printf("%016llx: %016llx\n",
@ -435,6 +469,13 @@ static void mem_read(uint64_t addr, uint64_t count)
}
}
}
}
static void mem_write(uint64_t addr, uint64_t data)
{
check(dmi_write(DBG_WB_CTRL, 0x7ff), "writing WB_CTRL");
check(dmi_write(DBG_WB_ADDR, addr), "writing WB_ADDR");
check(dmi_write(DBG_WB_DATA, data), "writing WB_DATA");
}
static void load(const char *filename, uint64_t addr)
static void load(const char *filename, uint64_t addr)
{
{
uint64_t data;
uint64_t data;
@ -445,13 +486,8 @@ static void load(const char *filename, uint64_t addr)
fprintf(stderr, "Failed to open '%s': %s\n", filename, strerror(errno));
fprintf(stderr, "Failed to open '%s': %s\n", filename, strerror(errno));
exit(1);
exit(1);
}
}
// XX dumb, do better
check(dmi_write(DBG_WB_CTRL, 0x7ff), "writing WB_CTRL");
rc = dmi_write(2, 0x7ff);
check(dmi_write(DBG_WB_ADDR, addr), "writing WB_ADDR");
if (rc < 0)
return;
rc = dmi_write(0, addr);
if (rc < 0)
return;
count = 0;
count = 0;
for (;;) {
for (;;) {
data = 0;
data = 0;
@ -459,7 +495,7 @@ static void load(const char *filename, uint64_t addr)
if (rc <= 0)
if (rc <= 0)
break;
break;
// if (rc < 8) XXX fixup endian ?
// if (rc < 8) XXX fixup endian ?
dmi_write(1, data);
check(dmi_write(DBG_WB_DATA, data), "writing WB_DATA");
count += 8;
count += 8;
if (!(count % 1024))
if (!(count % 1024))
printf("%x...\n", count);
printf("%x...\n", count);
@ -544,6 +580,8 @@ int main(int argc, char *argv[])
dmi_write(addr, data);
dmi_write(addr, data);
} else if (strcmp(argv[i], "creset") == 0) {
} else if (strcmp(argv[i], "creset") == 0) {
core_reset();
core_reset();
} else if (strcmp(argv[i], "icreset") == 0) {
icache_reset();
} else if (strcmp(argv[i], "stop") == 0) {
} else if (strcmp(argv[i], "stop") == 0) {
core_stop();
core_stop();
} else if (strcmp(argv[i], "start") == 0) {
} else if (strcmp(argv[i], "start") == 0) {
@ -563,6 +601,14 @@ int main(int argc, char *argv[])
if (((i+1) < argc) && isdigit(argv[i+1][0]))
if (((i+1) < argc) && isdigit(argv[i+1][0]))
count = strtoul(argv[++i], NULL, 16);
count = strtoul(argv[++i], NULL, 16);
mem_read(addr, count);
mem_read(addr, count);
} else if (strcmp(argv[i], "mw") == 0) {
uint64_t addr, data;
if ((i+2) >= argc)
usage(argv[0]);
addr = strtoul(argv[++i], NULL, 16);
data = strtoul(argv[++i], NULL, 16);
mem_write(addr, data);
} else if (strcmp(argv[i], "load") == 0) {
} else if (strcmp(argv[i], "load") == 0) {
const char *filename;
const char *filename;
uint64_t addr = 0;
uint64_t addr = 0;
@ -573,6 +619,15 @@ int main(int argc, char *argv[])
if (((i+1) < argc) && isdigit(argv[i+1][0]))
if (((i+1) < argc) && isdigit(argv[i+1][0]))
addr = strtoul(argv[++i], NULL, 16);
addr = strtoul(argv[++i], NULL, 16);
load(filename, addr);
load(filename, addr);
} else if (strcmp(argv[i], "gpr") == 0) {
uint64_t reg, count = 1;
if ((i+1) >= argc)
usage(argv[0]);
reg = strtoul(argv[++i], NULL, 10);
if (((i+1) < argc) && isdigit(argv[i+1][0]))
count = strtoul(argv[++i], NULL, 10);
gpr_read(reg, count);
} else {
} else {
fprintf(stderr, "Unknown command %s\n", argv[i]);
fprintf(stderr, "Unknown command %s\n", argv[i]);
exit(1);
exit(1);