[PATCH v2 17/18] am335x, guardian: software update available status is stored in AM3352 RTC scracth register

Gireesh.Hiremath at in.bosch.com Gireesh.Hiremath at in.bosch.com
Thu Apr 22 15:31:51 CEST 2021


From: Gireesh Hiremath <Gireesh.Hiremath at in.bosch.com>

RTC second scratch register[32-bit]:
  -zero byte hold boot count value
  -first byte hold update available state
  -second byte hold version
  -third byte hold magic number

Signed-off-by: Gireesh Hiremath <Gireesh.Hiremath at in.bosch.com>

Gbp-Pq: Topic apertis/guardian
Gbp-Pq: Name am335x-guardian-software-update-available-status-is-store.patch
---
On 06/01/21 9:02 pm, Gireesh.Hiremath at in.bosch.com wrote:
> From: Gireesh Hiremath <Gireesh.Hiremath at in.bosch.com>
> 
> RTC second scratch register[32-bit]:
>   -zero byte hold boot count value
>   -first byte hold update available state
>   -second byte hold version
>   -third byte hold magic number
> 
> Signed-off-by: Gireesh Hiremath <Gireesh.Hiremath at in.bosch.com>
> 
> Gbp-Pq: Topic apertis/guardian
> Gbp-Pq: Name 
> am335x-guardian-software-update-available-status-is-store.patch

Hmm..not sure what this is..

Cover letter is not needed for a single patch btw.
> ---
>  configs/am335x_guardian_defconfig   |  1 +
>  drivers/bootcount/Kconfig           | 27 ++++++++++++--
>  drivers/bootcount/Makefile          |  1 +
>  drivers/bootcount/bootcount_nvmem.c | 57 
> +++++++++++++++++++++++++++++

Please split driver and defconfig changes.
Isn't it possible to re-use drivers/bootcount/bootcount_davinci.c?

Thanks and regards,
Lokesh

Hi Lokesh

Splited driver and defconfig changes.

We are using the update manager on an AM3352 where we have only the
RTC Scratch registers to store the data in. Unfortunately the
drivers/bootcount/bootcount_davinci.c is only handling the bootcount
itself and not dealing with update_available and version. The consequence
is that rollbacks could always happen, not just after an update.
This can e.g. be triggered if the user tries to start up the device
with a weak accu pack where the device bootloader might be executed and
then the battery dies off during Linux startup. Then bootcount would be
incremented, but not reset by the Linux process. If that happens several
times in a row, the device will roll back, even if the update was done
years ago. Other backends, like drivers/bootcount/bootcount_ext.c handle
this properly, by only incrementing boot count if update_available==1.
We thought of modifying bootcount_davinci.c but we concerned about
backwards compatibility and breakage of other user space update managers.
Therefore we think to introduce an alternative backend.

Thanks and regards,
Gireesh Hiremath

 drivers/bootcount/Kconfig           | 27 ++++++++++++--
 drivers/bootcount/Makefile          |  1 +
 drivers/bootcount/bootcount_nvmem.c | 57 +++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 3 deletions(-)
 create mode 100644 drivers/bootcount/bootcount_nvmem.c

diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig
index b5ccea0d9c..d543061233 100644
--- a/drivers/bootcount/Kconfig
+++ b/drivers/bootcount/Kconfig
@@ -42,6 +42,25 @@ config BOOTCOUNT_AM33XX
 	  This requires the RTC clocks, etc, to be enabled prior to use and
 	  not all boards with this IP block on it will have the RTC in use.
 
+config BOOTCOUNT_AM33XX_NVMEM
+	bool "Boot counter in AM33XX RTC IP block with upgrade_available flag"
+	depends on AM33XX
+        select SPL_AM33XX_ENABLE_RTC32K_OSC if AM33XX
+	help
+	  Add support for maintaining bootcount,upgrade_available,
+	  version and BOOTMAGIC in a AM33xx RTC IP block
+	  scratch register2.
+
+	  A bootcount driver for the RTC IP block found on many TI platforms.
+	  This requires the RTC clocks, etc, to be enabled prior to use and
+	  not all boards with this IP block on it will have the RTC in use.
+
+	  If there is upgrade in software then "upgrade_available" is 1,
+	  "bootcount" is incremented otherwise "upgrade_available" and
+	  "bootcount" is  always 0. So the Userspace Application must set
+	  the "upgrade_available" and "bootcount" variable to 0, if a boot
+	  was successfully.
+
 config BOOTCOUNT_ENV
 	bool "Boot counter in environment"
 	help
@@ -177,16 +196,18 @@ config SYS_BOOTCOUNT_EXT_NAME
 
 config SYS_BOOTCOUNT_ADDR
 	hex "RAM address used for reading and writing the boot counter"
-	default 0x44E3E000 if BOOTCOUNT_AM33XX
+	default 0x44E3E000 if BOOTCOUNT_AM33XX || BOOTCOUNT_AM33XX_NVMEM
 	default 0xE0115FF8 if ARCH_LS1043A || ARCH_LS1021A
 	depends on BOOTCOUNT_AM33XX || BOOTCOUNT_GENERIC || BOOTCOUNT_EXT || \
-		   BOOTCOUNT_I2C
+		   BOOTCOUNT_I2C || BOOTCOUNT_AM33XX_NVMEM
 	help
 	  Set the address used for reading and writing the boot counter.
 
 config SYS_BOOTCOUNT_MAGIC
 	hex "Magic value for the boot counter"
-	default 0xB001C041
+	default 0xB001C041 if BOOTCOUNT_AM33XX
+	default 0xB0 if BOOTCOUNT_AM33XX_NVMEM
+	depends on BOOTCOUNT_AM33XX || BOOTCOUNT_AM33XX_NVMEM
 	help
 	  Set the magic value used for the boot counter.
 
diff --git a/drivers/bootcount/Makefile b/drivers/bootcount/Makefile
index 51d860b00e..12658ffdce 100644
--- a/drivers/bootcount/Makefile
+++ b/drivers/bootcount/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_BOOTCOUNT_RAM)	+= bootcount_ram.o
 obj-$(CONFIG_BOOTCOUNT_ENV)	+= bootcount_env.o
 obj-$(CONFIG_BOOTCOUNT_I2C)	+= bootcount_i2c.o
 obj-$(CONFIG_BOOTCOUNT_EXT)	+= bootcount_ext.o
+obj-$(CONFIG_BOOTCOUNT_AM33XX_NVMEM)	+= bootcount_nvmem.o
 
 obj-$(CONFIG_DM_BOOTCOUNT)      += bootcount-uclass.o
 obj-$(CONFIG_DM_BOOTCOUNT_RTC)  += rtc.o
diff --git a/drivers/bootcount/bootcount_nvmem.c b/drivers/bootcount/bootcount_nvmem.c
new file mode 100644
index 0000000000..5f266d5ec8
--- /dev/null
+++ b/drivers/bootcount/bootcount_nvmem.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2011
+ * Heiko Schocher, DENX Software Engineering, hs at denx.de.
+ * (C) Copyright 2018 Robert Bosch Power Tools GmbH.
+ *
+ * A bootcount driver for the RTC IP block found on many TI platforms.
+ * This requires the RTC clocks, etc, to be enabled prior to use and
+ * not all boards with this IP block on it will have the RTC in use.
+ */
+
+#include <bootcount.h>
+#include <asm/davinci_rtc.h>
+
+#define	BC_VERSION	2
+
+void bootcount_store(ulong bootcount)
+{
+	u8 upgrade_available = 0;
+	ulong val = 0;
+	struct davinci_rtc *reg =
+		(struct davinci_rtc *)CONFIG_SYS_BOOTCOUNT_ADDR;
+
+	val = raw_bootcount_load(&reg->scratch2);
+	upgrade_available = (val >> 8) & 0x000000ff;
+
+	/* Only update bootcount during upgrade process */
+	if (!upgrade_available)
+		bootcount = 0;
+
+	val = (bootcount & 0x000000ff) |
+	      (upgrade_available << 8) |
+	      (BC_VERSION << 16) |
+	      (CONFIG_SYS_BOOTCOUNT_MAGIC << 24);
+
+	/*
+	 * write RTC kick registers to enable write
+	 * for RTC Scratch registers. Scratch register 2 is
+	 * used for bootcount value.
+	 */
+	writel(RTC_KICK0R_WE, &reg->kick0r);
+	writel(RTC_KICK1R_WE, &reg->kick1r);
+	raw_bootcount_store(&reg->scratch2, val);
+}
+
+ulong bootcount_load(void)
+{
+	unsigned long val = 0;
+	struct davinci_rtc *reg =
+		(struct davinci_rtc *)CONFIG_SYS_BOOTCOUNT_ADDR;
+
+	val = raw_bootcount_load(&reg->scratch2);
+	if ((val >> 24) != CONFIG_SYS_BOOTCOUNT_MAGIC)
+		return 0;
+	else
+		return val & 0x000000ff;
+}
-- 
2.20.1



More information about the U-Boot mailing list