diff options
author | Palmer Dabbelt <palmer@dabbelt.com> | 2017-04-06 16:02:18 -0700 |
---|---|---|
committer | Palmer Dabbelt <palmer@dabbelt.com> | 2017-04-07 15:26:17 -0700 |
commit | dd4677c3df4eea7917e750b4c380d8fffaee27f5 (patch) | |
tree | a06e58433dfbfb6646fa3f503bf9e55855f9d8e6 | |
parent | 74095335dc2a147a75d62e1c55be2c80f16876c7 (diff) | |
download | riscv-openocd-dd4677c3df4eea7917e750b4c380d8fffaee27f5.zip riscv-openocd-dd4677c3df4eea7917e750b4c380d8fffaee27f5.tar.gz riscv-openocd-dd4677c3df4eea7917e750b4c380d8fffaee27f5.tar.bz2 |
Determine the hart count dynamically
This assumes that v0.11 targets have one hart, and that v0.13 targets
have harts IDs that start at 0 and are concecutive.
-rw-r--r-- | src/target/riscv/riscv-011.c | 3 | ||||
-rw-r--r-- | src/target/riscv/riscv-013.c | 14 | ||||
-rw-r--r-- | src/target/riscv/riscv.c | 5 | ||||
-rw-r--r-- | src/target/riscv/riscv.h | 3 |
4 files changed, 24 insertions, 1 deletions
diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index ed2a057..10612e2 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -1810,6 +1810,9 @@ static int examine(struct target *target) return ERROR_FAIL; } + RISCV_INFO(r); + r->hart_count = 1; + riscv011_info_t *info = get_info(target); info->addrbits = get_field(dtmcontrol, DTMCONTROL_ADDRBITS); info->dtmcontrol_idle = get_field(dtmcontrol, DTMCONTROL_IDLE); diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 2eb28bf..759ac08 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1220,6 +1220,20 @@ static int examine(struct target *target) info->datacount = get_field(abstractcs, DMI_ABSTRACTCS_DATACOUNT); info->progsize = get_field(abstractcs, DMI_ABSTRACTCS_PROGSIZE); + /* Before doing anything else we must first enumerate the harts. */ + RISCV_INFO(r); + for (int i = 0; i < RISCV_MAX_HARTS; ++i) { + riscv_set_current_hartid(target, i); + uint32_t s = dmi_read(target, DMI_DMSTATUS); + if (get_field(s, DMI_DMSTATUS_ANYNONEXISTENT)) + break; + r->hart_count = i + 1; + } + + /* FIXME: This is broken. */ + LOG_ERROR("Enumerated %d harts, but there's an off-by-one error in the hardware", r->hart_count); + r->hart_count--; + /* Halt every hart so we can probe them. */ riscv_halt_all_harts(target); diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 13410bd..d641155 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -963,7 +963,10 @@ void riscv_set_rtos_hartid(struct target *target, int hartid) int riscv_count_harts(struct target *target) { - return 3; + if (target == NULL) return 1; + RISCV_INFO(r); + if (r == NULL) return 1; + return r->hart_count; } bool riscv_has_register(struct target *target, int hartid, int regid) diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 7ce2622..3b83a08 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -33,6 +33,9 @@ typedef struct { struct command_context *cmd_ctx; void *version_specific; + /* The number of harts on this system. */ + int hart_count; + /* When the RTOS is enabled this target is expected to handle all the * harts in the system. When it's disabled this just uses the regular * multi-target mode. */ |