[PATCH v2 0/1]: bootcount: zynqmp: Add bootcount API

From: Vasileios Amoiridis vasileios.amoiridis@cern.ch
Changes in v2:
1) Move to DM infrastructure 2) Appropriate initialization of *val pointer 3) Updated help message 4) Added config to the end of the Makefile 5) Updated the appropriate values in struct pmu_regs
--- v1: https://lore.kernel.org/u-boot/20241029185814.7937-1-vassilisamir@gmail.com/
Vasileios Amoiridis (1): drivers: bootcount: Add ZynqMP specific bootcount support
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
base-commit: 56accc56b9aab87ef4809ccc588e1257969cd271

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
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, +};

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-updat...
Hint: I prefer to use patman for this.
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" ...
- 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
- 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

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-updat...
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

On 11/5/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
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"
depends on ARCH_ZYNQMP
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>
Please read this. https://docs.u-boot.org/en/latest/develop/codingstyle.html#include-files
M
participants (3)
-
Heiko Schocher
-
Michal Simek
-
Vasileios Amoiridis