diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c index 30d0ef4103..d86abe239b 100644 --- a/arch/arm/mach-rockchip/spl.c +++ b/arch/arm/mach-rockchip/spl.c @@ -305,11 +305,84 @@ void spl_hang_reset(void) #endif } +#ifdef CONFIG_SPL_FIT_ROLLBACK_PROTECT +int fit_read_otp_rollback_index(uint32_t fit_index, uint32_t *otp_index) +{ + int ret = 0; + + *otp_index = 0; +#if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V2) + struct udevice *dev; + u32 index, i, otp_version; + u32 bit_count; + + dev = misc_otp_get_device(OTP_S); + if (!dev) + return -ENODEV; + + otp_version = 0; + for (i = 0; i < OTP_UBOOT_ROLLBACK_WORDS; i++) { + if (misc_otp_read(dev, 4 * + (OTP_UBOOT_ROLLBACK_OFFSET + i), + &index, + 4)) { + printf("Can't read rollback index\n"); + return -EIO; + } + bit_count = fls(index); + otp_version += bit_count; + } + *otp_index = otp_version; +#endif + + return ret; +} + +static int fit_write_otp_rollback_index(u32 fit_index) +{ +#if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V2) + struct udevice *dev; + u32 index, i, otp_index; + + if (!fit_index || fit_index > OTP_UBOOT_ROLLBACK_WORDS * 32) + return -EINVAL; + + dev = misc_otp_get_device(OTP_S); + if (!dev) + return -ENODEV; + + if (fit_read_otp_rollback_index(fit_index, &otp_index)) + return -EIO; + + if (otp_index < fit_index) { + /* Write new SW version to otp */ + for (i = 0; i < OTP_UBOOT_ROLLBACK_WORDS; i++) { + /* convert to base-1 representation */ + index = 0xffffffff >> (OTP_ALL_ONES_NUM_BITS - + min(fit_index, (u32)OTP_ALL_ONES_NUM_BITS)); + fit_index -= min(fit_index, + (u32)OTP_ALL_ONES_NUM_BITS); + if (index) { + if (misc_otp_write(dev, 4 * + (OTP_UBOOT_ROLLBACK_OFFSET + i), + &index, + 4)) { + printf("Can't write rollback index\n"); + return -EIO; + } + } + } + } +#endif + + return 0; +} +#endif + int spl_board_prepare_for_jump(struct spl_image_info *spl_image) { -#if CONFIG_SPL_FIT_ROLLBACK_PROTECT - /* TODO */ - printf("spl fit: rollback protect not implement\n"); +#ifdef CONFIG_SPL_FIT_ROLLBACK_PROTECT + return fit_write_otp_rollback_index(gd->rollback_index); #endif return 0; } diff --git a/include/configs/rv1126_common.h b/include/configs/rv1126_common.h index 1b1a833d16..9f942afdaa 100644 --- a/include/configs/rv1126_common.h +++ b/include/configs/rv1126_common.h @@ -36,6 +36,11 @@ #define GICD_BASE 0xfeff1000 #define GICC_BASE 0xfeff2000 +/* secure boot otp rollback */ +#define OTP_UBOOT_ROLLBACK_OFFSET 0x1A /* word address */ +#define OTP_UBOOT_ROLLBACK_WORDS 2 /* 64 bits, 2 words */ +#define OTP_ALL_ONES_NUM_BITS 32 + /* MMC/SD IP block */ #define CONFIG_BOUNCE_BUFFER