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.
This commit is contained in:
Palmer Dabbelt 2017-04-06 16:02:18 -07:00
parent 74095335dc
commit dd4677c3df
4 changed files with 24 additions and 1 deletions

View File

@ -1810,6 +1810,9 @@ static int examine(struct target *target)
return ERROR_FAIL; return ERROR_FAIL;
} }
RISCV_INFO(r);
r->hart_count = 1;
riscv011_info_t *info = get_info(target); riscv011_info_t *info = get_info(target);
info->addrbits = get_field(dtmcontrol, DTMCONTROL_ADDRBITS); info->addrbits = get_field(dtmcontrol, DTMCONTROL_ADDRBITS);
info->dtmcontrol_idle = get_field(dtmcontrol, DTMCONTROL_IDLE); info->dtmcontrol_idle = get_field(dtmcontrol, DTMCONTROL_IDLE);

View File

@ -1220,6 +1220,20 @@ static int examine(struct target *target)
info->datacount = get_field(abstractcs, DMI_ABSTRACTCS_DATACOUNT); info->datacount = get_field(abstractcs, DMI_ABSTRACTCS_DATACOUNT);
info->progsize = get_field(abstractcs, DMI_ABSTRACTCS_PROGSIZE); 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. */ /* Halt every hart so we can probe them. */
riscv_halt_all_harts(target); riscv_halt_all_harts(target);

View File

@ -963,7 +963,10 @@ void riscv_set_rtos_hartid(struct target *target, int hartid)
int riscv_count_harts(struct target *target) 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) bool riscv_has_register(struct target *target, int hartid, int regid)

View File

@ -33,6 +33,9 @@ typedef struct {
struct command_context *cmd_ctx; struct command_context *cmd_ctx;
void *version_specific; 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 /* 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 * harts in the system. When it's disabled this just uses the regular
* multi-target mode. */ * multi-target mode. */