Message ID | 20241105074917.546887-2-vassilisamir@gmail.com |
---|---|
State | New |
Headers | show |
Series | : bootcount: zynqmp: Add bootcount API | expand |
On Tue, Nov 05, 2024 at 09:36:45AM +0100, Heiko Schocher wrote: > Hello Amoiridis, > > On 05.11.24 08:49, Vasileios Amoiridis wrote: > > From: Vasileios Amoiridis <vasileios.amoiridis@cern.ch> > > > > Add native support of the bootcount mechanism in the ZynqMP by > > utilising internal PMU registers. The Persistent Global Storage > > Registers of the Platform Management Unit can keep their value > > during reboot cycles unless there is a POR reset, making them > > appropriate for the bootcount mechanism. > > > > Signed-off-by: Vasileios Amoiridis <vasileios.amoiridis@cern.ch> > > --- > > MAINTAINERS | 1 + > > arch/arm/mach-zynqmp/include/mach/hardware.h | 2 + > > drivers/bootcount/Kconfig | 6 +++ > > drivers/bootcount/Makefile | 1 + > > drivers/bootcount/bootcount_zynqmp.c | 47 ++++++++++++++++++++ > > 5 files changed, 57 insertions(+) > > create mode 100644 drivers/bootcount/bootcount_zynqmp.c > > Please add a history of changes you did, see: > > https://docs.u-boot.org/en/latest/develop/sending_patches.html#sending-updated-patch-versions > > Hint: I prefer to use patman for this. > Ah this got lost because of the rebase... In any case, a bit too late, v1 is here [1]. [1]: https://lore.kernel.org/u-boot/20241029185814.7937-1-vassilisamir@gmail.com/ > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 0399ed1dbf..bc27a514e8 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -860,6 +860,7 @@ M: Michal Simek <michal.simek@amd.com> > > S: Maintained > > T: git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git > > F: arch/arm/mach-zynqmp/ > > +F: drivers/bootcount/bootcount_zynqmp.c > > F: drivers/clk/clk_zynqmp.c > > F: driver/firmware/firmware-zynqmp.c > > F: drivers/fpga/zynqpl.c > > diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h > > index 49e449ebd6..3c372bd6dc 100644 > > --- a/arch/arm/mach-zynqmp/include/mach/hardware.h > > +++ b/arch/arm/mach-zynqmp/include/mach/hardware.h > > @@ -188,6 +188,8 @@ struct pmu_regs { > > u32 gen_storage4; /* 0x40 */ > > u32 reserved1[1]; > > u32 gen_storage6; /* 0x48 */ > > + u32 reserved2[3]; > > + u32 pers_gen_storage2; /* 0x58 */ > > }; > > #define pmu_base ((struct pmu_regs *)ZYNQMP_PMU_BASEADDR) > > diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig > > index fa6d8e7128..f91074d5b4 100644 > > --- a/drivers/bootcount/Kconfig > > +++ b/drivers/bootcount/Kconfig > > @@ -164,6 +164,12 @@ config DM_BOOTCOUNT_SYSCON > > Accessing the backend is done using the regmap interface. > > +config DM_BOOTCOUNT_ZYNQMP > > + bool "Support ZynqMP PMUFW as a backing store for bootcount" > > + help > > + Enable support for the bootcount API by utilising the Persistent > > + Global General Storage Register 2 of the PMU. > > + > > endmenu > > endif > > diff --git a/drivers/bootcount/Makefile b/drivers/bootcount/Makefile > > index 245f879633..0cf79e428d 100644 > > --- a/drivers/bootcount/Makefile > > +++ b/drivers/bootcount/Makefile > > @@ -16,3 +16,4 @@ obj-$(CONFIG_DM_BOOTCOUNT_I2C_EEPROM) += i2c-eeprom.o > > obj-$(CONFIG_DM_BOOTCOUNT_I2C) += bootcount_dm_i2c.o > > obj-$(CONFIG_DM_BOOTCOUNT_SPI_FLASH) += spi-flash.o > > obj-$(CONFIG_DM_BOOTCOUNT_SYSCON) += bootcount_syscon.o > > +obj-$(CONFIG_DM_BOOTCOUNT_ZYNQMP) += bootcount_zynqmp.o > > diff --git a/drivers/bootcount/bootcount_zynqmp.c b/drivers/bootcount/bootcount_zynqmp.c > > new file mode 100644 > > index 0000000000..060bbdbae9 > > --- /dev/null > > +++ b/drivers/bootcount/bootcount_zynqmp.c > > @@ -0,0 +1,47 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +// SPDX-FileCopyrightText: 2024 CERN (home.cern) > > + > > +#include <asm/arch/hardware.h> > > +#include <bootcount.h> > > +#include <dm.h> > > +#include <dm/platdata.h> > > +#include <stdio.h> > > +#include <zynqmp_firmware.h> > > + > > +static int bootcount_zynqmp_set(struct udevice *dev, const u32 val) > > +{ > > + int ret; > > + > > + ret = zynqmp_mmio_write((ulong)&pmu_base->pers_gen_storage2, 0xFF, val); > > + if (ret) > > + pr_info("%s mio write fail\n", __func__); > > Nitpick: I think you do not need "mio" ... > Even the read/write is redundant in my opinion since the name of the function is printed but in other cases (i.e drivers/clk/clk_zynqmp.c) I saw it used like this. > > + > > + return ret; > > +} > > + > > +static int bootcount_zynqmp_get(struct udevice *dev, u32 *val) > > +{ > > + int ret; > > + > > + *val = 0; > > + ret = zynqmp_mmio_read((ulong)&pmu_base->pers_gen_storage2, val); > > + if (ret) > > + pr_info("%s mio write fail\n", __func__); > > Here too... remove mio and s/write/read > Will fix that in v3, thanks! > > + > > + return ret; > > +} > > + > > +U_BOOT_DRVINFO(bootcount_zynqmp) = { > > + .name = "bootcount_zynqmp", > > +}; > > + > > +static const struct bootcount_ops bootcount_zynqmp_ops = { > > + .get = bootcount_zynqmp_get, > > + .set = bootcount_zynqmp_set, > > +}; > > + > > +U_BOOT_DRIVER(bootcount_zynqmp) = { > > + .name = "bootcount_zynqmp", > > + .id = UCLASS_BOOTCOUNT, > > + .ops = &bootcount_zynqmp_ops, > > +}; > > > > Thanks! Beside of the nitpicks > > Reviewed-by: Heiko Schocher <hs@denx.de> > > bye, > Heiko Thank you for your time! Cheers, Vasilis > -- > DENX Software Engineering GmbH, Managing Director: Erika Unter > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: hs@denx.de
diff --git a/MAINTAINERS b/MAINTAINERS index 0399ed1dbf..bc27a514e8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -860,6 +860,7 @@ M: Michal Simek <michal.simek@amd.com> S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git F: arch/arm/mach-zynqmp/ +F: drivers/bootcount/bootcount_zynqmp.c F: drivers/clk/clk_zynqmp.c F: driver/firmware/firmware-zynqmp.c F: drivers/fpga/zynqpl.c diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h index 49e449ebd6..3c372bd6dc 100644 --- a/arch/arm/mach-zynqmp/include/mach/hardware.h +++ b/arch/arm/mach-zynqmp/include/mach/hardware.h @@ -188,6 +188,8 @@ struct pmu_regs { u32 gen_storage4; /* 0x40 */ u32 reserved1[1]; u32 gen_storage6; /* 0x48 */ + u32 reserved2[3]; + u32 pers_gen_storage2; /* 0x58 */ }; #define pmu_base ((struct pmu_regs *)ZYNQMP_PMU_BASEADDR) diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig index fa6d8e7128..f91074d5b4 100644 --- a/drivers/bootcount/Kconfig +++ b/drivers/bootcount/Kconfig @@ -164,6 +164,12 @@ config DM_BOOTCOUNT_SYSCON Accessing the backend is done using the regmap interface. +config DM_BOOTCOUNT_ZYNQMP + bool "Support ZynqMP PMUFW as a backing store for bootcount" + help + Enable support for the bootcount API by utilising the Persistent + Global General Storage Register 2 of the PMU. + endmenu endif diff --git a/drivers/bootcount/Makefile b/drivers/bootcount/Makefile index 245f879633..0cf79e428d 100644 --- a/drivers/bootcount/Makefile +++ b/drivers/bootcount/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_DM_BOOTCOUNT_I2C_EEPROM) += i2c-eeprom.o obj-$(CONFIG_DM_BOOTCOUNT_I2C) += bootcount_dm_i2c.o obj-$(CONFIG_DM_BOOTCOUNT_SPI_FLASH) += spi-flash.o obj-$(CONFIG_DM_BOOTCOUNT_SYSCON) += bootcount_syscon.o +obj-$(CONFIG_DM_BOOTCOUNT_ZYNQMP) += bootcount_zynqmp.o diff --git a/drivers/bootcount/bootcount_zynqmp.c b/drivers/bootcount/bootcount_zynqmp.c new file mode 100644 index 0000000000..060bbdbae9 --- /dev/null +++ b/drivers/bootcount/bootcount_zynqmp.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +// SPDX-FileCopyrightText: 2024 CERN (home.cern) + +#include <asm/arch/hardware.h> +#include <bootcount.h> +#include <dm.h> +#include <dm/platdata.h> +#include <stdio.h> +#include <zynqmp_firmware.h> + +static int bootcount_zynqmp_set(struct udevice *dev, const u32 val) +{ + int ret; + + ret = zynqmp_mmio_write((ulong)&pmu_base->pers_gen_storage2, 0xFF, val); + if (ret) + pr_info("%s mio write fail\n", __func__); + + return ret; +} + +static int bootcount_zynqmp_get(struct udevice *dev, u32 *val) +{ + int ret; + + *val = 0; + ret = zynqmp_mmio_read((ulong)&pmu_base->pers_gen_storage2, val); + if (ret) + pr_info("%s mio write fail\n", __func__); + + return ret; +} + +U_BOOT_DRVINFO(bootcount_zynqmp) = { + .name = "bootcount_zynqmp", +}; + +static const struct bootcount_ops bootcount_zynqmp_ops = { + .get = bootcount_zynqmp_get, + .set = bootcount_zynqmp_set, +}; + +U_BOOT_DRIVER(bootcount_zynqmp) = { + .name = "bootcount_zynqmp", + .id = UCLASS_BOOTCOUNT, + .ops = &bootcount_zynqmp_ops, +};