Skip to content

Commit cdbb369

Browse files
MarkusLassilarlubos
authored andcommitted
tfm: Include bl_storage.c
Add bl_storage.c to TF-M to reduce complexity on bl_storage.h. Signed-off-by: Markus Lassila <[email protected]>
1 parent f59ca21 commit cdbb369

File tree

3 files changed

+220
-214
lines changed

3 files changed

+220
-214
lines changed

include/bl_storage.h

Lines changed: 9 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,6 @@ struct counter_collection {
102102
struct monotonic_counter counters[1];
103103
};
104104

105-
NRFX_STATIC_INLINE uint32_t bl_storage_word_read(uint32_t address);
106-
NRFX_STATIC_INLINE uint32_t bl_storage_word_write(uint32_t address, uint32_t value);
107-
NRFX_STATIC_INLINE counter_t bl_storage_counter_get(uint32_t address);
108-
NRFX_STATIC_INLINE void bl_storage_counter_set(uint32_t address, counter_t value);
109-
110-
const struct monotonic_counter *get_counter_struct(uint16_t description);
111-
int get_counter(uint16_t counter_desc, counter_t *counter_value, const counter_t **free_slot);
112-
113105
/** The first data structure in the bootloader storage. It has unknown length
114106
* since 'key_data' is repeated. This data structure is immediately followed by
115107
* struct counter_collection.
@@ -242,136 +234,6 @@ enum lcs {
242234
BL_STORAGE_LCS_DECOMMISSIONED = 4,
243235
};
244236

245-
/**
246-
* Copies @p src into @p dst. Reads from @p src are done 32 bits at a
247-
* time. Writes to @p dst are done a byte at a time.
248-
*
249-
* @param[out] dst destination buffer.
250-
* @param[in] src source buffer in OTP. Must be 4-byte-aligned.
251-
* @param[in] size number of *bytes* in src to copy into dst. Must be divisible by 4.
252-
*/
253-
NRFX_STATIC_INLINE void otp_copy32(uint8_t *restrict dst, uint32_t volatile * restrict src,
254-
size_t size)
255-
{
256-
for (int i = 0; i < size / 4; i++) {
257-
/* OTP is in UICR */
258-
uint32_t val = bl_storage_word_read((uint32_t)(src + i));
259-
260-
for (int j = 0; j < 4; j++) {
261-
dst[i * 4 + j] = (val >> 8 * j) & 0xFF;
262-
}
263-
}
264-
}
265-
/**
266-
* Read the implementation id from OTP and copy it into a given buffer.
267-
*
268-
* @param[out] buf Buffer that has at least BL_STORAGE_IMPLEMENTATION_ID_SIZE bytes
269-
*/
270-
NRFX_STATIC_INLINE void read_implementation_id_from_otp(uint8_t *buf)
271-
{
272-
if (buf == NULL) {
273-
return;
274-
}
275-
276-
otp_copy32(buf, (uint32_t *)&BL_STORAGE->implementation_id,
277-
BL_STORAGE_IMPLEMENTATION_ID_SIZE);
278-
}
279-
280-
/* The OTP is 0xFFFF when erased and, like all flash, can only flip
281-
* bits from 0 to 1 when erasing. By setting all bits to zero we
282-
* enforce the correct transitioning of LCS until a full erase of the
283-
* device.
284-
*/
285-
#define STATE_ENTERED 0x0000
286-
#define STATE_NOT_ENTERED 0xFFFF
287-
288-
/* The bl_storage functions below are static inline in the header file
289-
* so that TF-M (that does not include bl_storage.c) can also have
290-
* access to them.
291-
* This is a temporary solution until TF-M has access to NSIB functions.
292-
*/
293-
294-
#if defined(CONFIG_NRFX_RRAMC)
295-
NRFX_STATIC_INLINE uint32_t index_from_address(uint32_t address)
296-
{
297-
return ((address - (uint32_t)BL_STORAGE)/sizeof(uint32_t));
298-
}
299-
#endif
300-
301-
NRFX_STATIC_INLINE counter_t bl_storage_counter_get(uint32_t address)
302-
{
303-
#if defined(CONFIG_NRFX_NVMC)
304-
return ~nrfx_nvmc_otp_halfword_read(address);
305-
#elif defined(CONFIG_NRFX_RRAMC)
306-
return ~nrfx_rramc_otp_word_read(index_from_address(address));
307-
#endif
308-
}
309-
310-
NRFX_STATIC_INLINE void bl_storage_counter_set(uint32_t address, counter_t value)
311-
{
312-
#if defined(CONFIG_NRFX_NVMC)
313-
nrfx_nvmc_halfword_write((uint32_t)address, ~value);
314-
#elif defined(CONFIG_NRFX_RRAMC)
315-
nrfx_rramc_otp_word_write(index_from_address((uint32_t)address), ~value);
316-
#endif
317-
}
318-
319-
NRFX_STATIC_INLINE uint32_t bl_storage_word_read(uint32_t address)
320-
{
321-
#if defined(CONFIG_NRFX_NVMC)
322-
return nrfx_nvmc_uicr_word_read((uint32_t *)address);
323-
#elif defined(CONFIG_NRFX_RRAMC)
324-
return nrfx_rramc_word_read(address);
325-
#endif
326-
}
327-
328-
NRFX_STATIC_INLINE uint32_t bl_storage_word_write(uint32_t address, uint32_t value)
329-
{
330-
#if defined(CONFIG_NRFX_NVMC)
331-
nrfx_nvmc_word_write(address, value);
332-
return 0;
333-
#elif defined(CONFIG_NRFX_RRAMC)
334-
nrfx_rramc_word_write(address, value);
335-
return 0;
336-
#endif
337-
}
338-
339-
NRFX_STATIC_INLINE uint16_t bl_storage_otp_halfword_read(uint32_t address)
340-
{
341-
uint16_t halfword;
342-
#if defined(CONFIG_NRFX_NVMC)
343-
halfword = nrfx_nvmc_otp_halfword_read(address);
344-
#elif defined(CONFIG_NRFX_RRAMC)
345-
uint32_t word = nrfx_rramc_otp_word_read(index_from_address(address));
346-
347-
if (!(address & 0x3)) {
348-
halfword = (uint16_t)(word & 0x0000FFFF); /* C truncates the upper bits */
349-
} else {
350-
halfword = (uint16_t)(word >> 16); /* Shift the upper half down */
351-
}
352-
#endif
353-
return halfword;
354-
}
355-
356-
NRFX_STATIC_INLINE lcs_data_t bl_storage_lcs_get(uint32_t address)
357-
{
358-
#if defined(CONFIG_NRFX_NVMC)
359-
return nrfx_nvmc_otp_halfword_read(address);
360-
#elif defined(CONFIG_NRFX_RRAMC)
361-
return nrfx_rramc_otp_word_read(index_from_address(address));
362-
#endif
363-
}
364-
365-
NRFX_STATIC_INLINE int bl_storage_lcs_set(uint32_t address, lcs_data_t state)
366-
{
367-
#if defined(CONFIG_NRFX_NVMC)
368-
nrfx_nvmc_halfword_write(address, state);
369-
#elif defined(CONFIG_NRFX_RRAMC)
370-
bl_storage_word_write(address, state);
371-
#endif
372-
return 0;
373-
}
374-
375237
/**
376238
* @brief Read the current life cycle state the device is in from OTP,
377239
*
@@ -380,41 +242,7 @@ NRFX_STATIC_INLINE int bl_storage_lcs_set(uint32_t address, lcs_data_t state)
380242
* @retval 0 The LCS read was successful.
381243
* @retval -EREADLCS Error on reading from OTP or invalid OTP content.
382244
*/
383-
NRFX_STATIC_INLINE int read_life_cycle_state(enum lcs *lcs)
384-
{
385-
if (lcs == NULL) {
386-
return -EINVAL;
387-
}
388-
389-
lcs_data_t provisioning = bl_storage_lcs_get(
390-
(uint32_t) &BL_STORAGE->lcs.provisioning);
391-
lcs_data_t secure = bl_storage_lcs_get((uint32_t) &BL_STORAGE->lcs.secure);
392-
lcs_data_t decommissioned = bl_storage_lcs_get(
393-
(uint32_t) &BL_STORAGE->lcs.decommissioned);
394-
395-
if (provisioning == STATE_NOT_ENTERED
396-
&& secure == STATE_NOT_ENTERED
397-
&& decommissioned == STATE_NOT_ENTERED) {
398-
*lcs = BL_STORAGE_LCS_ASSEMBLY;
399-
} else if (provisioning == STATE_ENTERED
400-
&& secure == STATE_NOT_ENTERED
401-
&& decommissioned == STATE_NOT_ENTERED) {
402-
*lcs = BL_STORAGE_LCS_PROVISIONING;
403-
} else if (provisioning == STATE_ENTERED
404-
&& secure == STATE_ENTERED
405-
&& decommissioned == STATE_NOT_ENTERED) {
406-
*lcs = BL_STORAGE_LCS_SECURED;
407-
} else if (provisioning == STATE_ENTERED
408-
&& secure == STATE_ENTERED
409-
&& decommissioned == STATE_ENTERED) {
410-
*lcs = BL_STORAGE_LCS_DECOMMISSIONED;
411-
} else {
412-
/* To reach this the OTP must be corrupted or reading failed */
413-
return -EREADLCS;
414-
}
415-
416-
return 0;
417-
}
245+
int read_life_cycle_state(enum lcs *lcs);
418246

419247
/**
420248
* @brief Update the life cycle state in OTP.
@@ -426,46 +254,14 @@ NRFX_STATIC_INLINE int read_life_cycle_state(enum lcs *lcs)
426254
* @retval -EREADLCS Reading the current state failed.
427255
* @retval -EINVALIDLCS Invalid next state.
428256
*/
429-
NRFX_STATIC_INLINE int update_life_cycle_state(enum lcs next_lcs)
430-
{
431-
int err;
432-
enum lcs current_lcs = 0;
433-
434-
if (next_lcs == BL_STORAGE_LCS_UNKNOWN) {
435-
return -EINVALIDLCS;
436-
}
437-
438-
err = read_life_cycle_state(&current_lcs);
439-
if (err != 0) {
440-
return err;
441-
}
442-
443-
if (next_lcs < current_lcs) {
444-
/* Is is only possible to transition into a higher state */
445-
return -EINVALIDLCS;
446-
}
447-
448-
if (next_lcs == current_lcs) {
449-
/* The same LCS is a valid argument, but nothing to do so return success */
450-
return 0;
451-
}
452-
453-
/* As the device starts in ASSEMBLY, it is not possible to write it */
454-
if (current_lcs == BL_STORAGE_LCS_ASSEMBLY && next_lcs == BL_STORAGE_LCS_PROVISIONING) {
455-
return bl_storage_lcs_set((uint32_t)&BL_STORAGE->lcs.provisioning, STATE_ENTERED);
456-
}
457-
458-
if (current_lcs == BL_STORAGE_LCS_PROVISIONING && next_lcs == BL_STORAGE_LCS_SECURED) {
459-
return bl_storage_lcs_set((uint32_t)&BL_STORAGE->lcs.secure, STATE_ENTERED);
460-
}
461-
462-
if (current_lcs == BL_STORAGE_LCS_SECURED && next_lcs == BL_STORAGE_LCS_DECOMMISSIONED) {
463-
return bl_storage_lcs_set((uint32_t)&BL_STORAGE->lcs.decommissioned, STATE_ENTERED);
464-
}
465-
466-
/* This will be the case if any invalid transition is tried */
467-
return -EINVALIDLCS;
468-
}
257+
int update_life_cycle_state(enum lcs next_lcs);
258+
259+
/**
260+
* Read the implementation id from OTP and copy it into a given buffer.
261+
*
262+
* @param[out] buf Buffer that has at least BL_STORAGE_IMPLEMENTATION_ID_SIZE bytes
263+
*/
264+
void read_implementation_id_from_otp(uint8_t *buf);
469265

470266
/** @} */
471267

modules/trusted-firmware-m/tfm_boards/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ target_sources(platform_s
4242
PRIVATE
4343
common/tfm_hal_platform.c
4444
$<$<OR:$<BOOL:${TFM_PARTITION_INITIAL_ATTESTATION}>,$<BOOL:${NRF_PROVISIONING}>>:${CMAKE_CURRENT_SOURCE_DIR}/common/attest_hal.c>
45+
$<$<OR:$<BOOL:${TFM_PARTITION_INITIAL_ATTESTATION}>,$<BOOL:${NRF_PROVISIONING}>>:${ZEPHYR_NRF_MODULE_DIR}/subsys/bootloader/bl_storage/bl_storage.c>
4546
common/assert.c
4647
$<$<NOT:$<BOOL:${PLATFORM_DEFAULT_OTP}>>:${CMAKE_CURRENT_SOURCE_DIR}/common/dummy_otp.c>
4748
$<$<NOT:$<BOOL:${PLATFORM_DEFAULT_SYSTEM_RESET_HALT}>>:${CMAKE_CURRENT_SOURCE_DIR}/common/tfm_hal_reset_halt.c>

0 commit comments

Comments
 (0)