diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index 632567f35..b450d2b0f 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -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; } diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index a66d0bf17..894694896 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -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); } diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 2e980dcb4..aea6d7a94 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -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; } diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index ad70f4caa..8e06bd5fd 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -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);