[PATCH 09/10] cpu: microblaze: add driver for CPU

Michal Simek michal.simek at xilinx.com
Fri Apr 22 16:18:25 CEST 2022



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 at 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 at 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 at 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


More information about the U-Boot mailing list