From: Ma Wupeng mawupeng1@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7ZC0H
--------------------------------
Enable PBHA bit0 via FDT table at startup. PBHA bit 0 is currently needed initialized.
Here is an example to enable PBHA bit0 in FDT table:
cpus { arm,pbha-performance-only = <0x01000000 0x00000000 0x00000000 0x00000000>; }; chosen { linux,pbha-bit0 = [0/1]; };
Signed-off-by: Ma Wupeng mawupeng1@huawei.com --- arch/arm64/Kconfig | 6 ++++ arch/arm64/kernel/cpufeature.c | 3 ++ drivers/firmware/efi/libstub/fdt.c | 52 ++++++++++++++++++++++++++++++ drivers/soc/hisilicon/Makefile | 1 + drivers/soc/hisilicon/pbha.c | 42 ++++++++++++++++++++++++ include/linux/pbha.h | 30 +++++++++++++++++ 6 files changed, 134 insertions(+) create mode 100644 drivers/soc/hisilicon/pbha.c create mode 100644 include/linux/pbha.h
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 48bd8258bd34..e450ccac2664 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1704,6 +1704,12 @@ config ARM64_PBHA The behaviour of each PBHA bit is not defined. Say no unless you are very sure you want this
+ For PBHA_BIT0: It has the following features: + a) kernel pte entry will be set PBHA 59 bit during pagetable startup + b) Introduce VM_PBHA_BIT0 for feature use. + c) User pte entry will be set PBHA 59 bit for vma with VM_PBHA_BIT0. + d) Introduce /proc/<pid>/pbha_bit0 to update whole user task. + endmenu
menu "ARMv8.3 architectural features" diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index b7d7da84df98..97744503704d 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -74,6 +74,7 @@ #include <linux/cpu.h> #include <linux/init.h> #include <linux/libfdt.h> +#include <linux/pbha.h>
#include <asm/cpu.h> #include <asm/cpufeature.h> @@ -1755,6 +1756,8 @@ void __init early_pbha_init(void)
pbha_enabled = true;
+ early_pbha_bit0_init(); + unlock: spin_unlock(&pbha_dt_lock); } diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index d48b0de05b62..d212bd2ad418 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -9,6 +9,7 @@
#include <linux/efi.h> #include <linux/libfdt.h> +#include <linux/pbha.h> #include <asm/efi.h>
#include "efistub.h" @@ -27,6 +28,54 @@ static void fdt_update_cell_size(void *fdt) fdt_setprop_u32(fdt, offset, "#size-cells", EFI_DT_SIZE_CELLS_DEFAULT); }
+#ifdef CONFIG_ARM64_PBHA +static efi_status_t fdt_init_hbm_mode(void *fdt, int node) +{ + efi_guid_t oem_config_guid = EFI_OEMCONFIG_VARIABLE_GUID; + unsigned long size; + efi_status_t efi_status; + u8 hbm_mode; + int status; + u8 fdt_val32; + u8 arr[16] = { 0x1 }; + + efi_status = get_efi_var(L"HBMMode", &oem_config_guid, NULL, &size, + &hbm_mode); + if (efi_status != EFI_SUCCESS) + goto out; + + if (hbm_mode != HBM_MODE_CACHE) + goto out; + + fdt_val32 = 1; + status = fdt_setprop_var(fdt, node, "linux,pbha-bit0", fdt_val32); + if (status) + return EFI_LOAD_ERROR; + + node = fdt_subnode_offset(fdt, 0, "cpus"); + if (node < 0) { + node = fdt_add_subnode(fdt, 0, "cpus"); + if (node < 0) + return EFI_LOAD_ERROR; + } + + /* Current PBHA bit59 is need to enable PBHA bit0 mode. */ + status = fdt_setprop_var(fdt, node, "arm,pbha-performance-only", arr); + if (status) { + efi_err("PBHA: arm,pbha-performance-only failed\n"); + return EFI_LOAD_ERROR; + } + +out: + return EFI_SUCCESS; +} +#else +static inline efi_status_t fdt_init_hbm_mode(void *fdt, int node) +{ + return EFI_SUCCESS; +} +#endif + static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, void *fdt, int new_fdt_size, char *cmdline_ptr, u64 initrd_addr, u64 initrd_size) @@ -148,6 +197,9 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, } }
+ if (fdt_init_hbm_mode(fdt, node) != EFI_SUCCESS) + goto fdt_set_fail; + /* Shrink the FDT back to its minimum size: */ fdt_pack(fdt);
diff --git a/drivers/soc/hisilicon/Makefile b/drivers/soc/hisilicon/Makefile index cbc01ad5b8fd..e0f966d1ed6d 100644 --- a/drivers/soc/hisilicon/Makefile +++ b/drivers/soc/hisilicon/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_KUNPENG_HCCS) += kunpeng_hccs.o
obj-$(CONFIG_HISI_HBMDEV) += hisi_hbmdev.o obj-$(CONFIG_HISI_HBMCACHE) += hisi_hbmcache.o +obj-$(CONFIG_ARM64_PBHA) += pbha.o diff --git a/drivers/soc/hisilicon/pbha.c b/drivers/soc/hisilicon/pbha.c new file mode 100644 index 000000000000..95bf9de0e9e9 --- /dev/null +++ b/drivers/soc/hisilicon/pbha.c @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) Huawei Technologies Co., Ltd. 2023. All rights reserved. + */ + +#define pr_fmt(fmt) "pbha: " fmt + +#include <linux/init.h> +#include <linux/libfdt.h> +#include <linux/printk.h> +#include <linux/cpufeature.h> + +#include <asm/setup.h> + +#define HBM_MODE_CACHE 1 + +bool __ro_after_init pbha_bit0_enabled; + +void __init early_pbha_bit0_init(void) +{ + const u8 *prop; + void *fdt; + int node; + + /* Check whether PBHA is enabled or not. */ + if (!system_supports_pbha()) + return; + + fdt = get_early_fdt_ptr(); + if (!fdt) + return; + + node = fdt_path_offset(fdt, "/chosen"); + if (node < 0) + return; + + prop = fdt_getprop(fdt, node, "linux,pbha-bit0", NULL); + if (!prop) + return; + if (*prop == HBM_MODE_CACHE) + pbha_bit0_enabled = true; +} diff --git a/include/linux/pbha.h b/include/linux/pbha.h new file mode 100644 index 000000000000..45261d163b1b --- /dev/null +++ b/include/linux/pbha.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) Huawei Technologies Co., Ltd. 2023. All rights reserved. + */ +#ifndef __LINUX_PBHA_H +#define __LINUX_PBHA_H + +#include <linux/efi.h> +#include <linux/libfdt.h> + +#define EFI_OEMCONFIG_VARIABLE_GUID \ + EFI_GUID(0x21f3b3c5, 0x946d, 0x41c1, 0x83, 0x8c, 0x19, 0x4e, 0x48, \ + 0xaa, 0x41, 0xe2) + +#define HBM_MODE_MEMORY 0 +#define HBM_MODE_CACHE 1 + +#ifdef CONFIG_ARM64_PBHA +extern bool __ro_after_init pbha_bit0_enabled; +extern void __init early_pbha_bit0_init(void); + +static inline bool system_support_pbha_bit0(void) +{ + return pbha_bit0_enabled; +} +#else +static inline bool system_support_pbha_bit0(void) { return false; } +#endif + +#endif