Commit 4265b0ec authored by Conor Dooley's avatar Conor Dooley Committed by Palmer Dabbelt

RISC-V: split riscv_fill_hwcap() in 3

Before adding more complexity to it, split riscv_fill_hwcap() into 3
distinct sections:
- riscv_fill_hwcap() still is the top level function, into which the
  additional complexity will be added.
- riscv_fill_hwcap_from_isa_string() handles getting the information
  from the riscv,isa/ACPI equivalent across harts & the various quirks
  there
- riscv_parse_isa_string() does what it says on the tin.
Reviewed-by: default avatarAndrew Jones <ajones@ventanamicro.com>
Signed-off-by: default avatarConor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20230713-daylight-puritan-37aeb41a4d9b@wendySigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent effc122a
......@@ -178,60 +178,9 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
void __init riscv_fill_hwcap(void)
static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct riscv_isainfo *isainfo,
unsigned long *isa2hwcap, const char *isa)
{
struct device_node *node;
const char *isa;
char print_str[NUM_ALPHA_EXTS + 1];
int i, j, rc;
unsigned long isa2hwcap[26] = {0};
struct acpi_table_header *rhct;
acpi_status status;
unsigned int cpu;
isa2hwcap['i' - 'a'] = COMPAT_HWCAP_ISA_I;
isa2hwcap['m' - 'a'] = COMPAT_HWCAP_ISA_M;
isa2hwcap['a' - 'a'] = COMPAT_HWCAP_ISA_A;
isa2hwcap['f' - 'a'] = COMPAT_HWCAP_ISA_F;
isa2hwcap['d' - 'a'] = COMPAT_HWCAP_ISA_D;
isa2hwcap['c' - 'a'] = COMPAT_HWCAP_ISA_C;
isa2hwcap['v' - 'a'] = COMPAT_HWCAP_ISA_V;
elf_hwcap = 0;
bitmap_zero(riscv_isa, RISCV_ISA_EXT_MAX);
if (!acpi_disabled) {
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
if (ACPI_FAILURE(status))
return;
}
for_each_possible_cpu(cpu) {
struct riscv_isainfo *isainfo = &hart_isa[cpu];
unsigned long this_hwcap = 0;
if (acpi_disabled) {
node = of_cpu_device_node_get(cpu);
if (!node) {
pr_warn("Unable to find cpu node\n");
continue;
}
rc = of_property_read_string(node, "riscv,isa", &isa);
of_node_put(node);
if (rc) {
pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
continue;
}
} else {
rc = acpi_get_riscv_isa(rhct, cpu, &isa);
if (rc < 0) {
pr_warn("Unable to get ISA for the hart - %d\n", cpu);
continue;
}
}
/*
* For all possible cpus, we have already validated in
* the boot process that they at least contain "rv" and
......@@ -374,7 +323,7 @@ void __init riscv_fill_hwcap(void)
int nr = tolower(*ext) - 'a';
if (riscv_isa_extension_check(nr)) {
this_hwcap |= isa2hwcap[nr];
*this_hwcap |= isa2hwcap[nr];
set_bit(nr, isainfo->isa);
}
} else {
......@@ -384,6 +333,49 @@ void __init riscv_fill_hwcap(void)
}
#undef SET_ISA_EXT_MAP
}
}
static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
{
struct device_node *node;
const char *isa;
int rc;
struct acpi_table_header *rhct;
acpi_status status;
unsigned int cpu;
if (!acpi_disabled) {
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
if (ACPI_FAILURE(status))
return;
}
for_each_possible_cpu(cpu) {
struct riscv_isainfo *isainfo = &hart_isa[cpu];
unsigned long this_hwcap = 0;
if (acpi_disabled) {
node = of_cpu_device_node_get(cpu);
if (!node) {
pr_warn("Unable to find cpu node\n");
continue;
}
rc = of_property_read_string(node, "riscv,isa", &isa);
of_node_put(node);
if (rc) {
pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
continue;
}
} else {
rc = acpi_get_riscv_isa(rhct, cpu, &isa);
if (rc < 0) {
pr_warn("Unable to get ISA for the hart - %d\n", cpu);
continue;
}
}
riscv_parse_isa_string(&this_hwcap, isainfo, isa2hwcap, isa);
/*
* Linux requires the following extensions, so we may as well
......@@ -420,6 +412,23 @@ void __init riscv_fill_hwcap(void)
if (!acpi_disabled && rhct)
acpi_put_table((struct acpi_table_header *)rhct);
}
void __init riscv_fill_hwcap(void)
{
char print_str[NUM_ALPHA_EXTS + 1];
int i, j;
unsigned long isa2hwcap[26] = {0};
isa2hwcap['i' - 'a'] = COMPAT_HWCAP_ISA_I;
isa2hwcap['m' - 'a'] = COMPAT_HWCAP_ISA_M;
isa2hwcap['a' - 'a'] = COMPAT_HWCAP_ISA_A;
isa2hwcap['f' - 'a'] = COMPAT_HWCAP_ISA_F;
isa2hwcap['d' - 'a'] = COMPAT_HWCAP_ISA_D;
isa2hwcap['c' - 'a'] = COMPAT_HWCAP_ISA_C;
isa2hwcap['v' - 'a'] = COMPAT_HWCAP_ISA_V;
riscv_fill_hwcap_from_isa_string(isa2hwcap);
/* We don't support systems with F but without D, so mask those out
* here. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment