From 820fdd4a3f74d2b622560be1c3e3224619a452b0 Mon Sep 17 00:00:00 2001 From: "Brian J. Nemec" Date: Fri, 21 Feb 2020 11:16:48 -0800 Subject: common/flash: Aligns persistent data to Flash Size Some platforms have allocated a region in the flash to store persistent data. Platforms with error correction code can require writes to occur in blocks. CONFIG_FLASH_WRITE_SIZE defines a valid block size for the platform. BUG=b:149870870 TEST=Verified that loading and saving persistent data functions on servoV4. TEST=Verified that the structure sizes are proportional to N * sizeof(alignment) TEST=Verified that the addresses are independent of alignment. TEST=Verified the alignment padding is not increasing object significantly. DUTs with the feature use under 16B typically. Change-Id: I54a5506f2179c98cc7383266598b9074c3521b8c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2068525 Tested-by: Brian Nemec Auto-Submit: Brian Nemec Reviewed-by: Patrick Georgi Commit-Queue: Patrick Georgi --- common/flash.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'common') diff --git a/common/flash.c b/common/flash.c index 295171730d..055064d029 100644 --- a/common/flash.c +++ b/common/flash.c @@ -51,6 +51,13 @@ #define PSTATE_VALID_SERIALNO BIT(1) #define PSTATE_VALID_MAC_ADDR BIT(2) +/* + * Error correction code operates on blocks equal to CONFIG_FLASH_WRITE_SIZE + * bytes so the persist_state must be a multiple of that length. To ensure this + * occurs, the aligned attribute has been set. Alignment has a side effect + * in that pointer arithmetic can't break alignment so it adds padding to the + * size of the structure to ensure that it is also a multiple of the alignment. + */ struct persist_state { uint8_t version; /* Version of this struct */ uint8_t flags; /* Lock flags (PERSIST_FLAG_*) */ @@ -62,15 +69,10 @@ struct persist_state { #ifdef CONFIG_MAC_ADDR_LEN uint8_t mac_addr[CONFIG_MAC_ADDR_LEN]; #endif /* CONFIG_MAC_ADDR_LEN */ -#if !defined(CONFIG_SERIALNO_LEN) && !defined(CONFIG_MAC_ADDR_LEN) - uint8_t padding[4 % CONFIG_FLASH_WRITE_SIZE]; -#endif -}; +} __aligned(CONFIG_FLASH_WRITE_SIZE); /* written with flash_physical_write, need to respect alignment constraints */ -#ifndef CHIP_FAMILY_STM32L /* STM32L1xx is somewhat lying to us */ BUILD_ASSERT(sizeof(struct persist_state) % CONFIG_FLASH_WRITE_SIZE == 0); -#endif BUILD_ASSERT(sizeof(struct persist_state) <= CONFIG_FW_PSTATE_SIZE); -- cgit v1.2.1