From 9df16c5937f68654fb2b67f932319c375f8e4e45 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Tue, 31 May 2022 21:14:34 +0300 Subject: [PATCH] microblaze: add support for handling PVR data Add helper code for PVR (Processor Version Register) data handling. It will be used by the UCLASS_CPU driver to populate cpuinfo fields at runtime. Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220531181435.3473549-13-ovpanait@gmail.com Signed-off-by: Michal Simek --- arch/microblaze/cpu/Makefile | 1 + arch/microblaze/cpu/pvr.c | 41 ++++++++++++++ arch/microblaze/include/asm/pvr.h | 75 +++++++++++++++++++++++++ board/xilinx/microblaze-generic/Kconfig | 8 +++ 4 files changed, 125 insertions(+) create mode 100644 arch/microblaze/cpu/pvr.c create mode 100644 arch/microblaze/include/asm/pvr.h diff --git a/arch/microblaze/cpu/Makefile b/arch/microblaze/cpu/Makefile index 78d7f83597..ea65a0976e 100644 --- a/arch/microblaze/cpu/Makefile +++ b/arch/microblaze/cpu/Makefile @@ -7,4 +7,5 @@ extra-y = start.o obj-y = irq.o obj-y += interrupts.o cache.o exception.o timer.o cpuinfo.o obj-$(CONFIG_STATIC_RELA) += relocate.o +obj-$(CONFIG_XILINX_MICROBLAZE0_PVR) += pvr.o obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/microblaze/cpu/pvr.c b/arch/microblaze/cpu/pvr.c new file mode 100644 index 0000000000..23c0f912d4 --- /dev/null +++ b/arch/microblaze/cpu/pvr.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022, Ovidiu Panait + */ +#include +#include +#include + +int microblaze_cpu_has_pvr_full(void) +{ + u32 msr, pvr0; + + MFS(msr, rmsr); + if (!(msr & PVR_MSR_BIT)) + return 0; + + get_pvr(0, pvr0); + debug("%s: pvr0 is 0x%08x\n", __func__, pvr0); + + if (!(pvr0 & PVR0_PVR_FULL_MASK)) + return 0; + + return 1; +} + +void microblaze_get_all_pvrs(u32 pvr[PVR_FULL_COUNT]) +{ + get_pvr(0, pvr[0]); + get_pvr(1, pvr[1]); + get_pvr(2, pvr[2]); + get_pvr(3, pvr[3]); + get_pvr(4, pvr[4]); + get_pvr(5, pvr[5]); + get_pvr(6, pvr[6]); + get_pvr(7, pvr[7]); + get_pvr(8, pvr[8]); + get_pvr(9, pvr[9]); + get_pvr(10, pvr[10]); + get_pvr(11, pvr[11]); + get_pvr(12, pvr[12]); +} diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h new file mode 100644 index 0000000000..bfe159af79 --- /dev/null +++ b/arch/microblaze/include/asm/pvr.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2022, Ovidiu Panait + */ + +#ifndef __ASM_MICROBLAZE_PVR_H +#define __ASM_MICROBLAZE_PVR_H + +#include + +#define PVR_FULL_COUNT 13 /* PVR0 - PVR12 */ + +#define __get_pvr(val, reg) \ + __asm__ __volatile__ ("mfs %0," #reg : "=r" (val) :: "memory") +#define get_pvr(pvrid, val) \ + __get_pvr(val, rpvr ## pvrid) + +#define PVR_MSR_BIT 0x00000400 + +/* PVR0 masks */ +#define PVR0_PVR_FULL_MASK 0x80000000 +#define PVR0_VERSION_MASK 0x0000FF00 + +/* PVR4 masks - ICache configs */ +#define PVR4_ICACHE_LINE_LEN_MASK 0x00E00000 /* ICLL */ +#define PVR4_ICACHE_BYTE_SIZE_MASK 0x001F0000 /* ICBS */ + +/* PVR5 masks - DCache configs */ +#define PVR5_DCACHE_LINE_LEN_MASK 0x00E00000 /* DCLL */ +#define PVR5_DCACHE_BYTE_SIZE_MASK 0x001F0000 /* DCBS */ + +/* PVR10 masks - FPGA family */ +#define PVR10_TARGET_FAMILY_MASK 0xFF000000 + +/* PVR11 masks - MMU */ +#define PVR11_USE_MMU 0xC0000000 + +/* PVR access macros */ +#define PVR_VERSION(pvr) \ + ((pvr[0] & PVR0_VERSION_MASK) >> 8) + +#define PVR_ICACHE_LINE_LEN(pvr) \ + ((1 << ((pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21)) << 2) +#define PVR_ICACHE_BYTE_SIZE(pvr) \ + (1 << ((pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16)) + +#define PVR_DCACHE_LINE_LEN(pvr) \ + ((1 << ((pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21)) << 2) +#define PVR_DCACHE_BYTE_SIZE(pvr) \ + (1 << ((pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16)) + +#define PVR_USE_MMU(pvr) \ + ((pvr[11] & PVR11_USE_MMU) >> 30) + +#define PVR_TARGET_FAMILY(pvr) \ + ((pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24) + +/** + * microblaze_cpu_has_pvr_full() - Check for full PVR support + * + * Check MSR register for PVR support and, if applicable, check the PVR0 + * register for full PVR support. + * + * Return: 1 if there is full PVR support, 0 otherwise. + */ +int microblaze_cpu_has_pvr_full(void); + +/** + * microblaze_get_all_pvrs() - Copy PVR0-PVR12 to destination array + * + * @pvr: destination array of size PVR_FULL_COUNT + */ +void microblaze_get_all_pvrs(u32 pvr[PVR_FULL_COUNT]); + +#endif /* __ASM_MICROBLAZE_PVR_H */ diff --git a/board/xilinx/microblaze-generic/Kconfig b/board/xilinx/microblaze-generic/Kconfig index 90f79cfb94..dd5eacef52 100644 --- a/board/xilinx/microblaze-generic/Kconfig +++ b/board/xilinx/microblaze-generic/Kconfig @@ -109,4 +109,12 @@ config XILINX_MICROBLAZE0_ICACHE_SIZE the device tree, or when the instruction cache is flushed very early in the boot process, before device tree is available. +config XILINX_MICROBLAZE0_PVR + bool "MicroBlaze PVR support" + help + Enables helper functions and macros needed to manipulate PVR + (Processor Version Register) data. Currently, only the microblaze + UCLASS_CPU driver makes use of this feature to retrieve CPU info at + runtime. + endif -- 2.39.5