
From: Gireesh Hiremath Gireesh.Hiremath@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@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@in.bosch.com wrote:
From: Gireesh Hiremath Gireesh.Hiremath@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@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@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(®->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, ®->kick0r); + writel(RTC_KICK1R_WE, ®->kick1r); + raw_bootcount_store(®->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(®->scratch2); + if ((val >> 24) != CONFIG_SYS_BOOTCOUNT_MAGIC) + return 0; + else + return val & 0x000000ff; +}