RISC-V: Assign hwcap as per comman capabilities.

Currently, we set hwcap based on first valid hart from DT. This may not
be correct always as that hart might not be current booting cpu or may
have a different capability.

Set hwcap as the capabilities supported by all possible harts with "okay"
status.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
Atish Patra 2019-02-22 11:41:40 -08:00 committed by Palmer Dabbelt
parent 291debb38d
commit fbdc6193dc
No known key found for this signature in database
GPG Key ID: EF4CA1502CCBAB41
1 changed files with 22 additions and 19 deletions

View File

@ -20,6 +20,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/hwcap.h> #include <asm/hwcap.h>
#include <asm/smp.h>
unsigned long elf_hwcap __read_mostly; unsigned long elf_hwcap __read_mostly;
#ifdef CONFIG_FPU #ifdef CONFIG_FPU
@ -42,28 +43,30 @@ void riscv_fill_hwcap(void)
elf_hwcap = 0; elf_hwcap = 0;
/*
* We don't support running Linux on hertergenous ISA systems. For
* now, we just check the ISA of the first "okay" processor.
*/
for_each_of_cpu_node(node) { for_each_of_cpu_node(node) {
if (riscv_of_processor_hartid(node) >= 0) unsigned long this_hwcap = 0;
break;
}
if (!node) {
pr_warn("Unable to find \"cpu\" devicetree entry\n");
return;
}
if (of_property_read_string(node, "riscv,isa", &isa)) { if (riscv_of_processor_hartid(node) < 0)
pr_warn("Unable to find \"riscv,isa\" devicetree entry\n"); continue;
of_node_put(node);
return;
}
of_node_put(node);
for (i = 0; i < strlen(isa); ++i) if (of_property_read_string(node, "riscv,isa", &isa)) {
elf_hwcap |= isa2hwcap[(unsigned char)(isa[i])]; pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
continue;
}
for (i = 0; i < strlen(isa); ++i)
this_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
/*
* All "okay" hart should have same isa. Set HWCAP based on
* common capabilities of every "okay" hart, in case they don't
* have.
*/
if (elf_hwcap)
elf_hwcap &= this_hwcap;
else
elf_hwcap = this_hwcap;
}
/* We don't support systems with F but without D, so mask those out /* We don't support systems with F but without D, so mask those out
* here. */ * here. */