Merge pull request #197 from riscv/hetero_misa
Track misa per-hart even in -rtos mode
This commit is contained in:
commit
11445b298a
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue