
On 4/11/22 18:26, Ovidiu Panait wrote:
Add a basic CPU driver that retrieves information about the microblaze CPU core. At this time, only data related to instruction/data caches is extracted from fdt.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com
arch/microblaze/include/asm/cache.h | 5 + arch/microblaze/include/asm/microblaze_cpu.h | 53 +++++++++ drivers/cpu/Kconfig | 6 + drivers/cpu/Makefile | 1 + drivers/cpu/microblaze_cpu.c | 109 +++++++++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 arch/microblaze/include/asm/microblaze_cpu.h create mode 100644 drivers/cpu/microblaze_cpu.c
diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h index c39b66dd7d..58ec69603e 100644 --- a/arch/microblaze/include/asm/cache.h +++ b/arch/microblaze/include/asm/cache.h @@ -23,4 +23,9 @@ */ void flush_cache_all(void);
+enum cache_type {
- DCACHE,
- ICACHE
+};
- #endif /* __MICROBLAZE_CACHE_H__ */
diff --git a/arch/microblaze/include/asm/microblaze_cpu.h b/arch/microblaze/include/asm/microblaze_cpu.h new file mode 100644 index 0000000000..8aad966e54 --- /dev/null +++ b/arch/microblaze/include/asm/microblaze_cpu.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2022, Ovidiu Panait ovpanait@gmail.com
- */
+#ifndef __MICROBLAZE_CPU_H +#define __MICROBLAZE_CPU_H
+#include <asm/cache.h>
+/**
- struct microblaze_cpu_plat - Platform data for microblaze processor core.
- @icache_size: Size of instruction cache memory in bytes.
- @icache_line_length: Instruction cache line length in bytes.
- @dcache_size: Size of data cache memory in bytes.
- @dcache_line_length: Data cache line length in bytes.
- */
+struct microblaze_cpu_plat {
- u32 icache_size;
- u32 icache_line_length;
- u32 dcache_size;
- u32 dcache_line_length;
+};
You should use this structure earlier as I mentioned. And I would also align it with linux and call this file cpuinfo.h
+/**
- microblaze_cpu_get_cacheline_size() - Get the cache line size
- Returns the cache line size in bytes for the cache memory type specified in
- @type (dcache or icache). Probes the first UCLASS CPU device via
- uclass_get_device() if not already active.
- @type: Cache type (dcache or icache)
- Return:
= 0 if OK, -ENODEV if there is an error getting cpu device data- */
+int microblaze_cpu_get_cacheline_size(enum cache_type type);
+/**
- microblaze_cpu_get_cache_size() - Get the cache size
- Returns the cache size in bytes for the cache memory type specified in @type
- (dcache or icache). Probes the first UCLASS CPU device via
- uclass_get_device() if not already active.
- @type: Cache type (dcache or icache)
- Return:
= 0 if OK, -ENODEV if there is an error getting cpu device data- */
+int microblaze_cpu_get_cache_size(enum cache_type type);
+#endif /* __MICROBLAZE_CPU_H */ diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig index 3d5729f6dc..c4b124da3f 100644 --- a/drivers/cpu/Kconfig +++ b/drivers/cpu/Kconfig @@ -19,3 +19,9 @@ config CPU_RISCV depends on CPU && RISCV help Support CPU cores for RISC-V architecture.
+config CPU_MICROBLAZE
- bool "Enable Microblaze CPU driver"
- depends on CPU && MICROBLAZE
- help
Support CPU cores for Microblaze architecture.
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile index c8532637ca..20884b1795 100644 --- a/drivers/cpu/Makefile +++ b/drivers/cpu/Makefile @@ -11,4 +11,5 @@ obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o obj-$(CONFIG_ARCH_AT91) += at91_cpu.o obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o +obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o obj-$(CONFIG_SANDBOX) += cpu_sandbox.o diff --git a/drivers/cpu/microblaze_cpu.c b/drivers/cpu/microblaze_cpu.c new file mode 100644 index 0000000000..823ac5671e --- /dev/null +++ b/drivers/cpu/microblaze_cpu.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2022, Ovidiu Panait ovpanait@gmail.com
- */
+#include <dm.h> +#include <asm/microblaze_cpu.h>
+static struct microblaze_cpu_plat *get_cpu0_plat(void) +{
- struct udevice *dev;
- if (uclass_get_device(UCLASS_CPU, 0, &dev) == 0)
return dev_get_plat(dev);
- return NULL;
+}
+int microblaze_cpu_get_cacheline_size(enum cache_type type) +{
- struct microblaze_cpu_plat *plat = get_cpu0_plat();
- if (!plat)
return -ENODEV;
- if (type == DCACHE)
return plat->dcache_line_length;
- return plat->icache_line_length;
+}
+int microblaze_cpu_get_cache_size(enum cache_type type) +{
- struct microblaze_cpu_plat *plat = get_cpu0_plat();
- if (!plat)
return -ENODEV;
- if (type == DCACHE)
return plat->dcache_size;
- return plat->icache_size;
+}
First of all these should be for icache and dcache. But I don't think you actually need this. Just fill that structure in previous patches and if this driver is loaded you can rewrite that values based on information from DT.
You can actually introduce in probe reading PVR register and fill that value based on it. IIRC in the linux kernel I am comparing that values to check if actual DT fits with system where u-boot is running at. If something doesn't match you can just show a message.
+static int microblaze_cpu_of_to_plat(struct udevice *dev) +{
- struct microblaze_cpu_plat *plat = dev_get_plat(dev);
- plat->icache_size = dev_read_u32_default(dev, "i-cache-size", 0);
- plat->icache_line_length = dev_read_u32_default(dev,
"xlnx,icache-line-len", 0);
- plat->icache_line_length <<= 2;
use i-cache-line-size and you don't need to do any shift.
- plat->dcache_size = dev_read_u32_default(dev, "d-cache-size", 0);
- plat->dcache_line_length = dev_read_u32_default(dev,
"xlnx,dcache-line-len", 0);
- plat->dcache_line_length <<= 2;
d-cache-line-size here.
- return 0;
+}
+static const struct udevice_id microblaze_cpu_ids[] = {
- { .compatible = "xlnx,microblaze-11.0" },
- { .compatible = "xlnx,microblaze-10.0" },
- { .compatible = "xlnx,microblaze-9.0.6" },
- { .compatible = "xlnx,microblaze-9.0.5" },
- { .compatible = "xlnx,microblaze-9.0.4" },
- { .compatible = "xlnx,microblaze-9.0.3" },
- { .compatible = "xlnx,microblaze-9.0.2" },
- { .compatible = "xlnx,microblaze-9.0.1" },
- { .compatible = "xlnx,microblaze-9.0.0" },
https://docs.xilinx.com/v/u/en-US/ug984-vivado-microblaze-ref They were 9.6 etc - it means all zeros should be removed.
MicroBlaze release version code Release Specific 0x19 = v8.40.b 0x1B = v9.0 0x1D = v9.1 0x1F = v9.2 0x20 = v9.3 0x21 = v9.4 0x22 = v9.5 0x23 = v9.6 0x24 = v10.0 0x25 = v11.0
- { .compatible = "xlnx,microblaze-8.50.c" },
- { .compatible = "xlnx,microblaze-8.50.b" },
- { .compatible = "xlnx,microblaze-8.50.a" },
- { .compatible = "xlnx,microblaze-8.40.b" },
- { .compatible = "xlnx,microblaze-8.40.a" },
- { .compatible = "xlnx,microblaze-8.30.a" },
- { .compatible = "xlnx,microblaze-8.20.b" },
- { .compatible = "xlnx,microblaze-8.20.a" },
- { .compatible = "xlnx,microblaze-8.10.a" },
- { .compatible = "xlnx,microblaze-8.00.b" },
- { .compatible = "xlnx,microblaze-8.00.a" },
- { .compatible = "xlnx,microblaze-7.30.b" },
- { .compatible = "xlnx,microblaze-7.30.a" },
- { .compatible = "xlnx,microblaze-7.20.d" },
- { .compatible = "xlnx,microblaze-7.20.c" },
- { .compatible = "xlnx,microblaze-7.20.b" },
- { .compatible = "xlnx,microblaze-7.20.a" },
- { .compatible = "xlnx,microblaze-7.10.d" },
- { .compatible = "xlnx,microblaze-7.10.c" },
- { .compatible = "xlnx,microblaze-7.10.b" },
- { .compatible = "xlnx,microblaze-7.10.a" },
- { .compatible = "xlnx,microblaze-7.00.b" },
- { .compatible = "xlnx,microblaze-7.00.a" },
- { .compatible = "xlnx,microblaze-6.00.b" },
- { .compatible = "xlnx,microblaze-6.00.a" },
- { .compatible = "xlnx,microblaze-5.00.c" },
- { .compatible = "xlnx,microblaze-5.00.b" },
- { .compatible = "xlnx,microblaze-5.00.a" },
- { }
+};
+U_BOOT_DRIVER(microblaze_cpu) = {
- .name = "microblaze_cpu",
- .id = UCLASS_CPU,
- .of_match = microblaze_cpu_ids,
- .of_to_plat = microblaze_cpu_of_to_plat,
- .plat_auto = sizeof(struct microblaze_cpu_plat),
- .flags = DM_FLAG_PRE_RELOC,
+};
Based on my look at cpu uclass I think it will be good to provide also ops and provide description and info about cpu itself that would be possible to enable CPU command.
M