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));
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;
LOG_WARNING("Failed to read misa at 0x%x; trying 0x%x.", 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
* address. */
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)
reg_cache_set(target, i, -1);
LOG_INFO("Examined RISCV core; XLEN=%d, misa=0x%" PRIx64,
riscv_xlen(target), r->misa);
riscv_xlen(target), r->misa[0]);
return ERROR_OK;
}

View File

@ -1072,7 +1072,7 @@ static int register_write_direct(struct target *target, unsigned number,
return ERROR_FAIL;
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) {
/* There are no instructions to move all the bits from a register, so
* we need to use some scratch RAM. */
@ -1094,7 +1094,7 @@ static int register_write_direct(struct target *target, unsigned number,
return ERROR_FAIL;
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));
else
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)
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
* register, so we need to use some scratch RAM. */
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,
scratch.hart_address) != ERROR_OK)
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));
} else {
riscv_program_insert(&program, fmv_x_w(S0, number - GDB_REGNO_FPR0));
@ -1378,7 +1380,7 @@ static int examine(struct target *target)
else
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);
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
* really slow simulators. */
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);
@ -1420,8 +1422,8 @@ static int examine(struct target *target)
riscv_count_harts(target));
for (int i = 0; i < riscv_count_harts(target); ++i) {
if (riscv_hart_enabled(target, i)) {
LOG_INFO(" hart %d: XLEN=%d, %d triggers", i, r->xlen[i],
r->trigger_count[i]);
LOG_INFO(" hart %d: XLEN=%d, misa=0x%" PRIx64 ", %d triggers", i,
r->xlen[i], r->misa[i], r->trigger_count[i]);
} else {
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_w, trigger->write);
tdata1 = set_field(tdata1, bpcontrol_x, trigger->execute);
tdata1 = set_field(tdata1, bpcontrol_u, !!(r->misa & (1 << ('U' - 'A'))));
tdata1 = set_field(tdata1, bpcontrol_s, !!(r->misa & (1 << ('S' - 'A'))));
tdata1 = set_field(tdata1, bpcontrol_h, !!(r->misa & (1 << ('H' - 'A'))));
tdata1 = set_field(tdata1, bpcontrol_u,
!!(r->misa[hartid] & (1 << ('U' - '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 = set_field(tdata1, bpcontrol_bpmatch, 0); /* exact match */
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);
tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL);
tdata1 |= MCONTROL_M;
if (r->misa & (1 << ('H' - 'A')))
if (r->misa[hartid] & (1 << ('H' - 'A')))
tdata1 |= MCONTROL_H;
if (r->misa & (1 << ('S' - 'A')))
if (r->misa[hartid] & (1 << ('S' - 'A')))
tdata1 |= MCONTROL_S;
if (r->misa & (1 << ('U' - 'A')))
if (r->misa[hartid] & (1 << ('U' - 'A')))
tdata1 |= MCONTROL_U;
if (trigger->execute)
@ -1648,7 +1651,7 @@ int riscv_step_rtos_hart(struct target *target)
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);
unsigned num;
@ -1658,7 +1661,7 @@ bool riscv_supports_extension(struct target *target, char letter)
num = letter - 'A';
else
return false;
return r->misa & (1 << num);
return r->misa[hartid] & (1 << num);
}
int riscv_xlen(const struct target *target)
@ -2192,10 +2195,12 @@ int riscv_init_registers(struct target *target)
r->feature = &feature_cpu;
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
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->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->size = 32;
} else {
@ -2326,7 +2331,8 @@ int riscv_init_registers(struct target *target)
case CSR_FFLAGS:
case CSR_FRM:
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->feature = &feature_fpu;
break;
@ -2340,15 +2346,16 @@ int riscv_init_registers(struct target *target)
case CSR_SCAUSE:
case CSR_STVAL:
case CSR_SATP:
r->exist = riscv_supports_extension(target, 'S');
r->exist = riscv_supports_extension(target,
riscv_current_hartid(target), 'S');
break;
case CSR_MEDELEG:
case CSR_MIDELEG:
/* "In systems with only M-mode, or with both M-mode and
* U-mode but without U-mode trap support, the medeleg and
* mideleg registers should not exist." */
r->exist = riscv_supports_extension(target, 'S') ||
riscv_supports_extension(target, 'N');
r->exist = riscv_supports_extension(target, riscv_current_hartid(target), 'S') ||
riscv_supports_extension(target, riscv_current_hartid(target), 'N');
break;
}

View File

@ -37,8 +37,6 @@ enum riscv_halt_reason {
typedef struct {
unsigned dtm_version;
riscv_reg_t misa;
struct command_context *cmd_ctx;
void *version_specific;
@ -68,6 +66,7 @@ typedef struct {
/* It's possible that each core has a different supported ISA set. */
int xlen[RISCV_MAX_HARTS];
riscv_reg_t misa[RISCV_MAX_HARTS];
/* The number of triggers per hart. */
unsigned trigger_count[RISCV_MAX_HARTS];
@ -183,7 +182,7 @@ int riscv_resume_one_hart(struct target *target, int hartid);
* then the only hart. */
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. */
int riscv_xlen(const struct target *target);