RISC-V: Some Svpbmt fixes and cleanups
Some additionals comments and notes from autobuilders received after the series got applied, warranted some changes. * 'riscv-svpbmt' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/palmer/linux: riscv: remove usage of function-pointers from cpufeatures and t-head errata riscv: make patch-function pointer more generic in cpu_manufacturer_info struct riscv: Improve description for RISCV_ISA_SVPBMT Kconfig symbol riscv: drop cpufeature_apply_feature tracking variable riscv: fix dependency for t-head errata
This commit is contained in:
commit
73448ae620
|
@ -364,8 +364,13 @@ config RISCV_ISA_SVPBMT
|
|||
select RISCV_ALTERNATIVE
|
||||
default y
|
||||
help
|
||||
Adds support to dynamically detect the presence of the SVPBMT extension
|
||||
(Supervisor-mode: page-based memory types) and enable its usage.
|
||||
Adds support to dynamically detect the presence of the SVPBMT
|
||||
ISA-extension (Supervisor-mode: page-based memory types) and
|
||||
enable its usage.
|
||||
|
||||
The memory type for a page contains a combination of attributes
|
||||
that indicate the cacheability, idempotency, and ordering
|
||||
properties for access to that page.
|
||||
|
||||
The SVPBMT extension is only available on 64Bit cpus.
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ config ERRATA_SIFIVE_CIP_1200
|
|||
|
||||
config ERRATA_THEAD
|
||||
bool "T-HEAD errata"
|
||||
depends on !XIP_KERNEL
|
||||
select RISCV_ALTERNATIVE
|
||||
help
|
||||
All T-HEAD errata Kconfig depend on this Kconfig. Disabling
|
||||
|
|
|
@ -14,40 +14,26 @@
|
|||
#include <asm/patch.h>
|
||||
#include <asm/vendorid_list.h>
|
||||
|
||||
struct errata_info {
|
||||
char name[ERRATA_STRING_LENGTH_MAX];
|
||||
bool (*check_func)(unsigned long arch_id, unsigned long impid);
|
||||
unsigned int stage;
|
||||
};
|
||||
|
||||
static bool errata_mt_check_func(unsigned long arch_id, unsigned long impid)
|
||||
static bool errata_probe_pbmt(unsigned int stage,
|
||||
unsigned long arch_id, unsigned long impid)
|
||||
{
|
||||
if (arch_id != 0 || impid != 0)
|
||||
return false;
|
||||
|
||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT ||
|
||||
stage == RISCV_ALTERNATIVES_MODULE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct errata_info errata_list[ERRATA_THEAD_NUMBER] = {
|
||||
static u32 thead_errata_probe(unsigned int stage,
|
||||
unsigned long archid, unsigned long impid)
|
||||
{
|
||||
.name = "memory-types",
|
||||
.stage = RISCV_ALTERNATIVES_EARLY_BOOT,
|
||||
.check_func = errata_mt_check_func
|
||||
},
|
||||
};
|
||||
|
||||
static u32 thead_errata_probe(unsigned int stage, unsigned long archid, unsigned long impid)
|
||||
{
|
||||
const struct errata_info *info;
|
||||
u32 cpu_req_errata = 0;
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < ERRATA_THEAD_NUMBER; idx++) {
|
||||
info = &errata_list[idx];
|
||||
|
||||
if ((stage == RISCV_ALTERNATIVES_MODULE ||
|
||||
info->stage == stage) && info->check_func(archid, impid))
|
||||
cpu_req_errata |= (1U << idx);
|
||||
}
|
||||
if (errata_probe_pbmt(stage, archid, impid))
|
||||
cpu_req_errata |= (1U << ERRATA_THEAD_PBMT);
|
||||
|
||||
return cpu_req_errata;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ struct cpu_manufacturer_info_t {
|
|||
unsigned long vendor_id;
|
||||
unsigned long arch_id;
|
||||
unsigned long imp_id;
|
||||
void (*vendor_patch_func)(struct alt_entry *begin, struct alt_entry *end,
|
||||
void (*patch_func)(struct alt_entry *begin, struct alt_entry *end,
|
||||
unsigned long archid, unsigned long impid,
|
||||
unsigned int stage);
|
||||
};
|
||||
|
@ -40,16 +40,16 @@ static void __init_or_module riscv_fill_cpu_mfr_info(struct cpu_manufacturer_inf
|
|||
switch (cpu_mfr_info->vendor_id) {
|
||||
#ifdef CONFIG_ERRATA_SIFIVE
|
||||
case SIFIVE_VENDOR_ID:
|
||||
cpu_mfr_info->vendor_patch_func = sifive_errata_patch_func;
|
||||
cpu_mfr_info->patch_func = sifive_errata_patch_func;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_ERRATA_THEAD
|
||||
case THEAD_VENDOR_ID:
|
||||
cpu_mfr_info->vendor_patch_func = thead_errata_patch_func;
|
||||
cpu_mfr_info->patch_func = thead_errata_patch_func;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cpu_mfr_info->vendor_patch_func = NULL;
|
||||
cpu_mfr_info->patch_func = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,10 +68,10 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin,
|
|||
|
||||
riscv_cpufeature_patch_func(begin, end, stage);
|
||||
|
||||
if (!cpu_mfr_info.vendor_patch_func)
|
||||
if (!cpu_mfr_info.patch_func)
|
||||
return;
|
||||
|
||||
cpu_mfr_info.vendor_patch_func(begin, end,
|
||||
cpu_mfr_info.patch_func(begin, end,
|
||||
cpu_mfr_info.arch_id,
|
||||
cpu_mfr_info.imp_id,
|
||||
stage);
|
||||
|
|
|
@ -245,12 +245,7 @@ void __init riscv_fill_hwcap(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_RISCV_ALTERNATIVE
|
||||
struct cpufeature_info {
|
||||
char name[ERRATA_STRING_LENGTH_MAX];
|
||||
bool (*check_func)(unsigned int stage);
|
||||
};
|
||||
|
||||
static bool __init_or_module cpufeature_svpbmt_check_func(unsigned int stage)
|
||||
static bool __init_or_module cpufeature_probe_svpbmt(unsigned int stage)
|
||||
{
|
||||
#ifdef CONFIG_RISCV_ISA_SVPBMT
|
||||
switch (stage) {
|
||||
|
@ -264,26 +259,19 @@ static bool __init_or_module cpufeature_svpbmt_check_func(unsigned int stage)
|
|||
return false;
|
||||
}
|
||||
|
||||
static const struct cpufeature_info __initdata_or_module
|
||||
cpufeature_list[CPUFEATURE_NUMBER] = {
|
||||
{
|
||||
.name = "svpbmt",
|
||||
.check_func = cpufeature_svpbmt_check_func
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Probe presence of individual extensions.
|
||||
*
|
||||
* This code may also be executed before kernel relocation, so we cannot use
|
||||
* addresses generated by the address-of operator as they won't be valid in
|
||||
* this context.
|
||||
*/
|
||||
static u32 __init_or_module cpufeature_probe(unsigned int stage)
|
||||
{
|
||||
const struct cpufeature_info *info;
|
||||
u32 cpu_req_feature = 0;
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < CPUFEATURE_NUMBER; idx++) {
|
||||
info = &cpufeature_list[idx];
|
||||
|
||||
if (info->check_func(stage))
|
||||
cpu_req_feature |= (1U << idx);
|
||||
}
|
||||
if (cpufeature_probe_svpbmt(stage))
|
||||
cpu_req_feature |= (1U << CPUFEATURE_SVPBMT);
|
||||
|
||||
return cpu_req_feature;
|
||||
}
|
||||
|
@ -293,7 +281,6 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
|
|||
unsigned int stage)
|
||||
{
|
||||
u32 cpu_req_feature = cpufeature_probe(stage);
|
||||
u32 cpu_apply_feature = 0;
|
||||
struct alt_entry *alt;
|
||||
u32 tmp;
|
||||
|
||||
|
@ -307,10 +294,8 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
|
|||
}
|
||||
|
||||
tmp = (1U << alt->errata_id);
|
||||
if (cpu_req_feature & tmp) {
|
||||
if (cpu_req_feature & tmp)
|
||||
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
|
||||
cpu_apply_feature |= tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue