Merge pull request #197 from riscv/hetero_misa

Track misa per-hart even in -rtos mode
This commit is contained in:
Tim Newsome 2018-04-03 16:22:05 -07:00 committed by GitHub
commit 11445b298a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 28 deletions

View File

@ -1572,11 +1572,11 @@ static int examine(struct target *target)
} }
LOG_DEBUG("Discovered XLEN is %d", riscv_xlen(target)); LOG_DEBUG("Discovered XLEN is %d", riscv_xlen(target));
if (read_csr(target, &r->misa, CSR_MISA) != ERROR_OK) { if (read_csr(target, &r->misa[0], CSR_MISA) != ERROR_OK) {
const unsigned old_csr_misa = 0xf10; const unsigned old_csr_misa = 0xf10;
LOG_WARNING("Failed to read misa at 0x%x; trying 0x%x.", CSR_MISA, LOG_WARNING("Failed to read misa at 0x%x; trying 0x%x.", CSR_MISA,
old_csr_misa); old_csr_misa);
if (read_csr(target, &r->misa, old_csr_misa) != ERROR_OK) { if (read_csr(target, &r->misa[0], old_csr_misa) != ERROR_OK) {
/* Maybe this is an old core that still has $misa at the old /* Maybe this is an old core that still has $misa at the old
* address. */ * address. */
LOG_ERROR("Failed to read misa at 0x%x.", old_csr_misa); LOG_ERROR("Failed to read misa at 0x%x.", old_csr_misa);
@ -1598,7 +1598,7 @@ static int examine(struct target *target)
for (size_t i = 0; i < 32; ++i) for (size_t i = 0; i < 32; ++i)
reg_cache_set(target, i, -1); reg_cache_set(target, i, -1);
LOG_INFO("Examined RISCV core; XLEN=%d, misa=0x%" PRIx64, LOG_INFO("Examined RISCV core; XLEN=%d, misa=0x%" PRIx64,
riscv_xlen(target), r->misa); riscv_xlen(target), r->misa[0]);
return ERROR_OK; return ERROR_OK;
} }

View File

@ -1072,7 +1072,7 @@ static int register_write_direct(struct target *target, unsigned number,
return ERROR_FAIL; return ERROR_FAIL;
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 && if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 &&
riscv_supports_extension(target, 'D') && riscv_supports_extension(target, riscv_current_hartid(target), 'D') &&
riscv_xlen(target) < 64) { riscv_xlen(target) < 64) {
/* There are no instructions to move all the bits from a register, so /* There are no instructions to move all the bits from a register, so
* we need to use some scratch RAM. */ * we need to use some scratch RAM. */
@ -1094,7 +1094,7 @@ static int register_write_direct(struct target *target, unsigned number,
return ERROR_FAIL; return ERROR_FAIL;
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) { if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
if (riscv_supports_extension(target, 'D')) if (riscv_supports_extension(target, riscv_current_hartid(target), 'D'))
riscv_program_insert(&program, fmv_d_x(number - GDB_REGNO_FPR0, S0)); riscv_program_insert(&program, fmv_d_x(number - GDB_REGNO_FPR0, S0));
else else
riscv_program_insert(&program, fmv_w_x(number - GDB_REGNO_FPR0, S0)); riscv_program_insert(&program, fmv_w_x(number - GDB_REGNO_FPR0, S0));
@ -1150,7 +1150,8 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
set_field(mstatus, MSTATUS_FS, 1)) != ERROR_OK) set_field(mstatus, MSTATUS_FS, 1)) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
if (riscv_supports_extension(target, 'D') && riscv_xlen(target) < 64) { if (riscv_supports_extension(target, riscv_current_hartid(target), 'D')
&& riscv_xlen(target) < 64) {
/* There are no instructions to move all the bits from a /* There are no instructions to move all the bits from a
* register, so we need to use some scratch RAM. */ * register, so we need to use some scratch RAM. */
riscv_program_insert(&program, fsd(number - GDB_REGNO_FPR0, S0, riscv_program_insert(&program, fsd(number - GDB_REGNO_FPR0, S0,
@ -1163,7 +1164,8 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
if (register_write_direct(target, GDB_REGNO_S0, if (register_write_direct(target, GDB_REGNO_S0,
scratch.hart_address) != ERROR_OK) scratch.hart_address) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
} else if (riscv_supports_extension(target, 'D')) { } else if (riscv_supports_extension(target,
riscv_current_hartid(target), 'D')) {
riscv_program_insert(&program, fmv_x_d(S0, number - GDB_REGNO_FPR0)); riscv_program_insert(&program, fmv_x_d(S0, number - GDB_REGNO_FPR0));
} else { } else {
riscv_program_insert(&program, fmv_x_w(S0, number - GDB_REGNO_FPR0)); riscv_program_insert(&program, fmv_x_w(S0, number - GDB_REGNO_FPR0));
@ -1378,7 +1380,7 @@ static int examine(struct target *target)
else else
r->xlen[i] = 32; r->xlen[i] = 32;
if (register_read_direct(target, &r->misa, GDB_REGNO_MISA)) { if (register_read_direct(target, &r->misa[i], GDB_REGNO_MISA)) {
LOG_ERROR("Fatal: Failed to read MISA from hart %d.", i); LOG_ERROR("Fatal: Failed to read MISA from hart %d.", i);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -1390,7 +1392,7 @@ static int examine(struct target *target)
/* Display this as early as possible to help people who are using /* Display this as early as possible to help people who are using
* really slow simulators. */ * really slow simulators. */
LOG_DEBUG(" hart %d: XLEN=%d, misa=0x%" PRIx64, i, r->xlen[i], LOG_DEBUG(" hart %d: XLEN=%d, misa=0x%" PRIx64, i, r->xlen[i],
r->misa); r->misa[i]);
} }
LOG_DEBUG("Enumerated %d harts", r->hart_count); LOG_DEBUG("Enumerated %d harts", r->hart_count);
@ -1420,8 +1422,8 @@ static int examine(struct target *target)
riscv_count_harts(target)); riscv_count_harts(target));
for (int i = 0; i < riscv_count_harts(target); ++i) { for (int i = 0; i < riscv_count_harts(target); ++i) {
if (riscv_hart_enabled(target, i)) { if (riscv_hart_enabled(target, i)) {
LOG_INFO(" hart %d: XLEN=%d, %d triggers", i, r->xlen[i], LOG_INFO(" hart %d: XLEN=%d, misa=0x%" PRIx64 ", %d triggers", i,
r->trigger_count[i]); r->xlen[i], r->misa[i], r->trigger_count[i]);
} else { } else {
LOG_INFO(" hart %d: currently disabled", i); LOG_INFO(" hart %d: currently disabled", i);
} }

View File

@ -313,9 +313,12 @@ static int maybe_add_trigger_t1(struct target *target, unsigned hartid,
tdata1 = set_field(tdata1, bpcontrol_r, trigger->read); tdata1 = set_field(tdata1, bpcontrol_r, trigger->read);
tdata1 = set_field(tdata1, bpcontrol_w, trigger->write); tdata1 = set_field(tdata1, bpcontrol_w, trigger->write);
tdata1 = set_field(tdata1, bpcontrol_x, trigger->execute); tdata1 = set_field(tdata1, bpcontrol_x, trigger->execute);
tdata1 = set_field(tdata1, bpcontrol_u, !!(r->misa & (1 << ('U' - 'A')))); tdata1 = set_field(tdata1, bpcontrol_u,
tdata1 = set_field(tdata1, bpcontrol_s, !!(r->misa & (1 << ('S' - 'A')))); !!(r->misa[hartid] & (1 << ('U' - 'A'))));
tdata1 = set_field(tdata1, bpcontrol_h, !!(r->misa & (1 << ('H' - 'A')))); tdata1 = set_field(tdata1, bpcontrol_s,
!!(r->misa[hartid] & (1 << ('S' - 'A'))));
tdata1 = set_field(tdata1, bpcontrol_h,
!!(r->misa[hartid] & (1 << ('H' - 'A'))));
tdata1 |= bpcontrol_m; tdata1 |= bpcontrol_m;
tdata1 = set_field(tdata1, bpcontrol_bpmatch, 0); /* exact match */ tdata1 = set_field(tdata1, bpcontrol_bpmatch, 0); /* exact match */
tdata1 = set_field(tdata1, bpcontrol_bpaction, 0); /* cause bp exception */ tdata1 = set_field(tdata1, bpcontrol_bpaction, 0); /* cause bp exception */
@ -358,11 +361,11 @@ static int maybe_add_trigger_t2(struct target *target, unsigned hartid,
MCONTROL_ACTION_DEBUG_MODE); MCONTROL_ACTION_DEBUG_MODE);
tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL); tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL);
tdata1 |= MCONTROL_M; tdata1 |= MCONTROL_M;
if (r->misa & (1 << ('H' - 'A'))) if (r->misa[hartid] & (1 << ('H' - 'A')))
tdata1 |= MCONTROL_H; tdata1 |= MCONTROL_H;
if (r->misa & (1 << ('S' - 'A'))) if (r->misa[hartid] & (1 << ('S' - 'A')))
tdata1 |= MCONTROL_S; tdata1 |= MCONTROL_S;
if (r->misa & (1 << ('U' - 'A'))) if (r->misa[hartid] & (1 << ('U' - 'A')))
tdata1 |= MCONTROL_U; tdata1 |= MCONTROL_U;
if (trigger->execute) if (trigger->execute)
@ -1648,7 +1651,7 @@ int riscv_step_rtos_hart(struct target *target)
return ERROR_OK; return ERROR_OK;
} }
bool riscv_supports_extension(struct target *target, char letter) bool riscv_supports_extension(struct target *target, int hartid, char letter)
{ {
RISCV_INFO(r); RISCV_INFO(r);
unsigned num; unsigned num;
@ -1658,7 +1661,7 @@ bool riscv_supports_extension(struct target *target, char letter)
num = letter - 'A'; num = letter - 'A';
else else
return false; return false;
return r->misa & (1 << num); return r->misa[hartid] & (1 << num);
} }
int riscv_xlen(const struct target *target) int riscv_xlen(const struct target *target)
@ -2192,10 +2195,12 @@ int riscv_init_registers(struct target *target)
r->feature = &feature_cpu; r->feature = &feature_cpu;
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) { } else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
r->caller_save = true; r->caller_save = true;
if (riscv_supports_extension(target, 'D')) { if (riscv_supports_extension(target, riscv_current_hartid(target),
'D')) {
r->reg_data_type = &type_ieee_double; r->reg_data_type = &type_ieee_double;
r->size = 64; r->size = 64;
} else if (riscv_supports_extension(target, 'F')) { } else if (riscv_supports_extension(target,
riscv_current_hartid(target), 'F')) {
r->reg_data_type = &type_ieee_single; r->reg_data_type = &type_ieee_single;
r->size = 32; r->size = 32;
} else { } else {
@ -2326,7 +2331,8 @@ int riscv_init_registers(struct target *target)
case CSR_FFLAGS: case CSR_FFLAGS:
case CSR_FRM: case CSR_FRM:
case CSR_FCSR: case CSR_FCSR:
r->exist = riscv_supports_extension(target, 'F'); r->exist = riscv_supports_extension(target,
riscv_current_hartid(target), 'F');
r->group = "float"; r->group = "float";
r->feature = &feature_fpu; r->feature = &feature_fpu;
break; break;
@ -2340,15 +2346,16 @@ int riscv_init_registers(struct target *target)
case CSR_SCAUSE: case CSR_SCAUSE:
case CSR_STVAL: case CSR_STVAL:
case CSR_SATP: case CSR_SATP:
r->exist = riscv_supports_extension(target, 'S'); r->exist = riscv_supports_extension(target,
riscv_current_hartid(target), 'S');
break; break;
case CSR_MEDELEG: case CSR_MEDELEG:
case CSR_MIDELEG: case CSR_MIDELEG:
/* "In systems with only M-mode, or with both M-mode and /* "In systems with only M-mode, or with both M-mode and
* U-mode but without U-mode trap support, the medeleg and * U-mode but without U-mode trap support, the medeleg and
* mideleg registers should not exist." */ * mideleg registers should not exist." */
r->exist = riscv_supports_extension(target, 'S') || r->exist = riscv_supports_extension(target, riscv_current_hartid(target), 'S') ||
riscv_supports_extension(target, 'N'); riscv_supports_extension(target, riscv_current_hartid(target), 'N');
break; break;
} }

View File

@ -37,8 +37,6 @@ enum riscv_halt_reason {
typedef struct { typedef struct {
unsigned dtm_version; unsigned dtm_version;
riscv_reg_t misa;
struct command_context *cmd_ctx; struct command_context *cmd_ctx;
void *version_specific; void *version_specific;
@ -68,6 +66,7 @@ typedef struct {
/* It's possible that each core has a different supported ISA set. */ /* It's possible that each core has a different supported ISA set. */
int xlen[RISCV_MAX_HARTS]; int xlen[RISCV_MAX_HARTS];
riscv_reg_t misa[RISCV_MAX_HARTS];
/* The number of triggers per hart. */ /* The number of triggers per hart. */
unsigned trigger_count[RISCV_MAX_HARTS]; unsigned trigger_count[RISCV_MAX_HARTS];
@ -183,7 +182,7 @@ int riscv_resume_one_hart(struct target *target, int hartid);
* then the only hart. */ * then the only hart. */
int riscv_step_rtos_hart(struct target *target); int riscv_step_rtos_hart(struct target *target);
bool riscv_supports_extension(struct target *target, char letter); bool riscv_supports_extension(struct target *target, int hartid, char letter);
/* Returns XLEN for the given (or current) hart. */ /* Returns XLEN for the given (or current) hart. */
int riscv_xlen(const struct target *target); int riscv_xlen(const struct target *target);