Unverified Commit 73448ae6 authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

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
parents 89793a61 1771c8c9
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -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.

+1 −0
Original line number Diff line number Diff line
@@ -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
+12 −26
Original line number Diff line number Diff line
@@ -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;
}

static const struct errata_info errata_list[ERRATA_THEAD_NUMBER] = {
	{
		.name = "memory-types",
		.stage = RISCV_ALTERNATIVES_EARLY_BOOT,
		.check_func = errata_mt_check_func
	},
};
	return false;
}

static u32 thead_errata_probe(unsigned int stage, unsigned long archid, unsigned long impid)
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;
}
+9 −9
Original line number Diff line number Diff line
@@ -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);
+11 −26
Original line number Diff line number Diff line
@@ -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