5#include "sw/device/silicon_creator/lib/nvm_ctrl.h"
13#include "sw/device/silicon_creator/lib/drivers/rram_ctrl.h"
15#include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
31 kNvmInfoPagesPerBank = 10,
32 kNvmWireFormatBankCount = 2,
40static const rram_ctrl_info_page_t *
const kPageTable[] = {
41 [kNvmInfoPageFactoryId] = &kRramCtrlInfoPageFactoryId,
42 [kNvmInfoPageCreatorSecret] = &kRramCtrlInfoPageCreatorSecret,
43 [kNvmInfoPageOwnerSecret] = &kRramCtrlInfoPageOwnerSecret,
44 [kNvmInfoPageWaferAuthSecret] = &kRramCtrlInfoPageWaferAuthSecret,
45 [kNvmInfoPageAttestationKeySeeds] = &kRramCtrlInfoPageAttestationKeySeeds,
46 [kNvmInfoPageOwnerReserved0] = &kRramCtrlInfoPageOwnerReserved0,
47 [kNvmInfoPageOwnerReserved1] = &kRramCtrlInfoPageOwnerReserved1,
48 [kNvmInfoPageOwnerReserved2] = &kRramCtrlInfoPageOwnerReserved2,
49 [kNvmInfoPageOwnerReserved3] = &kRramCtrlInfoPageOwnerReserved3,
50 [kNvmInfoPageFactoryCerts] = &kRramCtrlInfoPageFactoryCerts,
51 [kNvmInfoPageBootData0] = &kRramCtrlInfoPageBootData0,
52 [kNvmInfoPageBootData1] = &kRramCtrlInfoPageBootData1,
53 [kNvmInfoPageOwnerSlot0] = &kRramCtrlInfoPageOwnerSlot0,
54 [kNvmInfoPageOwnerSlot1] = &kRramCtrlInfoPageOwnerSlot1,
55 [kNvmInfoPageCreatorReserved0] = &kRramCtrlInfoPageCreatorReserved0,
56 [kNvmInfoPageOwnerReserved4] = &kRramCtrlInfoPageOwnerReserved4,
57 [kNvmInfoPageOwnerReserved5] = &kRramCtrlInfoPageOwnerReserved5,
58 [kNvmInfoPageOwnerReserved6] = &kRramCtrlInfoPageOwnerReserved6,
59 [kNvmInfoPageOwnerReserved7] = &kRramCtrlInfoPageOwnerReserved7,
60 [kNvmInfoPageDiceCerts] = &kRramCtrlInfoPageDiceCerts,
63static const flash_ctrl_info_page_t *
const kPageTable[] = {
64 [kNvmInfoPageFactoryId] = &kFlashCtrlInfoPageFactoryId,
65 [kNvmInfoPageCreatorSecret] = &kFlashCtrlInfoPageCreatorSecret,
66 [kNvmInfoPageOwnerSecret] = &kFlashCtrlInfoPageOwnerSecret,
67 [kNvmInfoPageWaferAuthSecret] = &kFlashCtrlInfoPageWaferAuthSecret,
68 [kNvmInfoPageAttestationKeySeeds] = &kFlashCtrlInfoPageAttestationKeySeeds,
69 [kNvmInfoPageOwnerReserved0] = &kFlashCtrlInfoPageOwnerReserved0,
70 [kNvmInfoPageOwnerReserved1] = &kFlashCtrlInfoPageOwnerReserved1,
71 [kNvmInfoPageOwnerReserved2] = &kFlashCtrlInfoPageOwnerReserved2,
72 [kNvmInfoPageOwnerReserved3] = &kFlashCtrlInfoPageOwnerReserved3,
73 [kNvmInfoPageFactoryCerts] = &kFlashCtrlInfoPageFactoryCerts,
74 [kNvmInfoPageBootData0] = &kFlashCtrlInfoPageBootData0,
75 [kNvmInfoPageBootData1] = &kFlashCtrlInfoPageBootData1,
76 [kNvmInfoPageOwnerSlot0] = &kFlashCtrlInfoPageOwnerSlot0,
77 [kNvmInfoPageOwnerSlot1] = &kFlashCtrlInfoPageOwnerSlot1,
78 [kNvmInfoPageCreatorReserved0] = &kFlashCtrlInfoPageCreatorReserved0,
79 [kNvmInfoPageOwnerReserved4] = &kFlashCtrlInfoPageOwnerReserved4,
80 [kNvmInfoPageOwnerReserved5] = &kFlashCtrlInfoPageOwnerReserved5,
81 [kNvmInfoPageOwnerReserved6] = &kFlashCtrlInfoPageOwnerReserved6,
82 [kNvmInfoPageOwnerReserved7] = &kFlashCtrlInfoPageOwnerReserved7,
83 [kNvmInfoPageDiceCerts] = &kFlashCtrlInfoPageDiceCerts,
89static_assert(
ARRAYSIZE(kPageTable) <= 2 * kNvmInfoPagesPerBank,
90 "More named pages than the wire format supports");
97static const rram_ctrl_info_page_t *page_ptr(nvm_info_page_t page) {
98 HARDENED_CHECK_LT((uint32_t)page,
ARRAYSIZE(kPageTable));
99 return kPageTable[(uint32_t)page];
102const rram_ctrl_info_page_t *nvm_ctrl_rram_page_info(nvm_info_page_t page) {
103 return page_ptr(page);
106static rram_ctrl_perms_t perms_to_rram(nvm_page_perms_t p) {
107 return (rram_ctrl_perms_t){
108 .read = (uint32_t)p.read,
109 .write = (uint32_t)p.write,
113static rram_ctrl_cfg_t cfg_to_rram(nvm_page_cfg_t c) {
114 return (rram_ctrl_cfg_t){
115 .scrambling = (uint32_t)c.scrambling,
116 .ecc = (uint32_t)c.ecc,
120static nvm_page_cfg_t cfg_from_rram(rram_ctrl_cfg_t c) {
121 return (nvm_page_cfg_t){
124 .he = kMultiBitBool4False,
129static const flash_ctrl_info_page_t *page_ptr(nvm_info_page_t page) {
130 HARDENED_CHECK_LT((uint32_t)page,
ARRAYSIZE(kPageTable));
131 return kPageTable[(uint32_t)page];
134static flash_ctrl_perms_t perms_to_flash(nvm_page_perms_t p) {
135 return (flash_ctrl_perms_t){
136 .read = (uint32_t)p.read,
137 .write = (uint32_t)p.write,
138 .erase = (uint32_t)p.erase,
142static flash_ctrl_cfg_t cfg_to_flash(nvm_page_cfg_t c) {
143 return (flash_ctrl_cfg_t){
144 .scrambling = (uint32_t)c.scrambling,
145 .ecc = (uint32_t)c.ecc,
146 .he = (uint32_t)c.he,
150static nvm_page_cfg_t cfg_from_flash(flash_ctrl_cfg_t c) {
151 return (nvm_page_cfg_t){
152 .scrambling = c.scrambling,
163const nvm_page_perms_t kNvmPagePermsReadWrite = {.read = kMultiBitBool4True,
164 .write = kMultiBitBool4True,
165 .erase = kMultiBitBool4True};
166const nvm_page_perms_t kNvmPagePermsReadOnly = {.read = kMultiBitBool4True,
167 .write = kMultiBitBool4False,
168 .erase = kMultiBitBool4False};
169const nvm_page_perms_t kNvmPagePermsNone = {.read = kMultiBitBool4False,
170 .write = kMultiBitBool4False,
171 .erase = kMultiBitBool4False};
172const nvm_page_perms_t kNvmPagePermsErase = {.read = kMultiBitBool4False,
173 .write = kMultiBitBool4False,
174 .erase = kMultiBitBool4True};
176const nvm_page_cfg_t kNvmPageCfgScrambled = {.scrambling = kMultiBitBool4True,
177 .ecc = kMultiBitBool4True,
178 .he = kMultiBitBool4False};
179const nvm_page_cfg_t kNvmPageCfgPlain = {.scrambling = kMultiBitBool4False,
180 .ecc = kMultiBitBool4True,
181 .he = kMultiBitBool4False};
182const nvm_page_cfg_t kNvmPageCfgRaw = {.scrambling = kMultiBitBool4False,
183 .ecc = kMultiBitBool4False,
184 .he = kMultiBitBool4False};
186const nvm_page_cfg_t kNvmCertInfoPageCfg = {.scrambling = kMultiBitBool4True,
187 .ecc = kMultiBitBool4True,
188 .he = kMultiBitBool4False};
189const nvm_page_perms_t kNvmCertInfoPageCreatorAccess = {
190 .read = kMultiBitBool4True,
191 .write = kMultiBitBool4True,
192 .erase = kMultiBitBool4True};
193const nvm_page_perms_t kNvmCertInfoPageOwnerAccess = {
194 .read = kMultiBitBool4True,
195 .write = kMultiBitBool4False,
196 .erase = kMultiBitBool4False};
202rom_error_t nvm_ctrl_info_page_lookup(uint8_t bank, uint8_t page,
203 nvm_info_page_t *out) {
204 if ((uint32_t)bank >= (uint32_t)kNvmWireFormatBankCount ||
205 (uint32_t)page >= (uint32_t)kNvmInfoPagesPerBank) {
206 return kErrorNvmCtrlInvalidInfoPage;
208 *out = (nvm_info_page_t)(bank * kNvmInfoPagesPerBank + page);
212static const nvm_info_page_t kNvmPagesNoOwnerAccess[] = {
213 kNvmInfoPageFactoryId, kNvmInfoPageCreatorSecret,
214 kNvmInfoPageOwnerSecret, kNvmInfoPageWaferAuthSecret,
215 kNvmInfoPageBootData0, kNvmInfoPageBootData1,
216 kNvmInfoPageCreatorReserved0,
220 kNvmPagesNoOwnerAccessCount =
ARRAYSIZE(kNvmPagesNoOwnerAccess),
235void nvm_ctrl_init(
void) {
241 rram_ctrl_data_default_perms_set((rram_ctrl_perms_t){
242 .read = kMultiBitBool4True,
243 .write = kMultiBitBool4False,
252 rram_ctrl_data_region_protect(
253 kRramCtrlEmulRegionB, kRramCtrlEmulPageBaseB,
254 kRramCtrlEmulPageEndB - kRramCtrlOtpPageCount - kRramCtrlEmulPageBaseB,
256 .read = kMultiBitBool4True,
257 .write = kMultiBitBool4True,
263 rram_ctrl_data_region_protect(kRramCtrlEmulRegionA, kRramCtrlEmulPageBaseA,
264 kRramCtrlEmulPageEndA - kRramCtrlEmulPageBaseA,
266 .read = kMultiBitBool4True,
267 .write = kMultiBitBool4True,
269 rram_ctrl_data_default_cfg_get(),
276void nvm_ctrl_disable(
void) { rram_ctrl_disable(); }
278rom_error_t nvm_ctrl_data_read(uint32_t addr, uint32_t word_count,
void *data) {
279 return rram_ctrl_data_read(addr, word_count, data);
282rom_error_t nvm_ctrl_data_write(uint32_t addr, uint32_t word_count,
284 return rram_ctrl_data_write(addr, word_count, data);
287rom_error_t nvm_ctrl_data_erase(uint32_t addr) {
298 static_assert(kNvmErasedWord == UINT32_MAX,
299 "memset(..., 0xff, ...) below assumes an all-ones erased "
301 enum { kPageWords = NVM_BYTES_PER_PAGE /
sizeof(uint32_t) };
302 uint32_t erased[kPageWords];
303 memset(erased, 0xff,
sizeof(erased));
304 return rram_ctrl_data_write(addr, kPageWords, erased);
307rom_error_t nvm_ctrl_data_erase_verify(uint32_t addr) {
312rom_error_t nvm_ctrl_chip_erase(
void) {
324 rram_ctrl_data_default_perms_set((rram_ctrl_perms_t){
325 .read = kMultiBitBool4True,
326 .write = kMultiBitBool4True,
331 rom_error_t err = kErrorOk;
332 for (uint32_t addr = 0; addr < NVM_SLOT_B_END_BYTES;
333 addr += NVM_BYTES_PER_PAGE) {
334 if (addr >= NVM_SLOT_A_END_BYTES && addr < NVM_SLOT_B_START_BYTES) {
337 rom_error_t page_err = nvm_ctrl_data_erase(addr);
338 if (err == kErrorOk) {
342 rram_ctrl_data_default_perms_set((rram_ctrl_perms_t){
343 .read = kMultiBitBool4False,
344 .write = kMultiBitBool4False,
349rom_error_t nvm_ctrl_chip_erase_verify(
void) {
return kErrorOk; }
351rom_error_t nvm_ctrl_bootstrap_page_program(uint32_t addr,
size_t byte_count,
354 kProgPageSize = NVM_PROG_PAGE_SIZE,
355 kProgPageMask = kProgPageSize - 1,
359 size_t word_misalignment = byte_count & (NVM_BYTES_PER_WORD - 1);
360 if (word_misalignment > 0) {
361 size_t pad = NVM_BYTES_PER_WORD - word_misalignment;
362 for (
size_t i = 0; i < pad; ++i) {
363 data[byte_count++] = 0xff;
366 size_t rem_word_count = byte_count /
sizeof(uint32_t);
372 rram_ctrl_data_default_perms_set((rram_ctrl_perms_t){
373 .read = kMultiBitBool4True,
374 .write = kMultiBitBool4True,
381 rom_error_t err_0 = kErrorOk;
382 size_t prog_page_misalignment = addr & kProgPageMask;
383 if (prog_page_misalignment > 0) {
385 (kProgPageSize - prog_page_misalignment) /
sizeof(uint32_t);
386 if (word_count > rem_word_count) {
387 word_count = rem_word_count;
389 err_0 = rram_ctrl_data_write(addr, (uint32_t)word_count, data);
390 rem_word_count -= word_count;
391 data += word_count *
sizeof(uint32_t);
392 addr &= ~(uint32_t)kProgPageMask;
394 rom_error_t err_1 = kErrorOk;
395 if (rem_word_count > 0) {
396 err_1 = rram_ctrl_data_write(addr, (uint32_t)rem_word_count, data);
398 rram_ctrl_data_default_perms_set((rram_ctrl_perms_t){
399 .read = kMultiBitBool4False,
400 .write = kMultiBitBool4False,
402 HARDENED_RETURN_IF_ERROR(err_0);
406rom_error_t nvm_ctrl_bootstrap_sector_erase(uint32_t addr) {
411 enum { kSectorSizeBytes = 4096 };
412 addr &= ~(uint32_t)(kSectorSizeBytes - 1);
413 rram_ctrl_data_default_perms_set((rram_ctrl_perms_t){
414 .read = kMultiBitBool4True,
415 .write = kMultiBitBool4True,
420 rom_error_t err = kErrorOk;
421 for (uint32_t offset = 0; offset < kSectorSizeBytes;
422 offset += NVM_BYTES_PER_PAGE) {
423 rom_error_t page_err = nvm_ctrl_data_erase(addr + offset);
424 if (err == kErrorOk) {
428 rram_ctrl_data_default_perms_set((rram_ctrl_perms_t){
429 .read = kMultiBitBool4False,
430 .write = kMultiBitBool4False,
435rom_error_t nvm_ctrl_info_read(nvm_info_page_t page, uint32_t offset,
436 uint32_t word_count,
void *data) {
437 const rram_ctrl_info_page_t *p = page_ptr(page);
439 return rram_ctrl_data_read(p->
page_id * NVM_BYTES_PER_PAGE + offset,
442 return rram_ctrl_info_read(p, offset, word_count, data);
445rom_error_t nvm_ctrl_info_read_zeros_on_read_error(nvm_info_page_t page,
449 const rram_ctrl_info_page_t *p = page_ptr(page);
453 return rram_ctrl_data_read(p->
page_id * NVM_BYTES_PER_PAGE + offset,
456 return rram_ctrl_info_read_zeros_on_read_error(p, offset, word_count, data);
459rom_error_t nvm_ctrl_info_write(nvm_info_page_t page, uint32_t offset,
460 uint32_t word_count,
const void *data) {
461 const rram_ctrl_info_page_t *p = page_ptr(page);
463 return rram_ctrl_data_write(p->
page_id * NVM_BYTES_PER_PAGE + offset,
466 return rram_ctrl_info_write(p, offset, word_count, data);
469rom_error_t nvm_ctrl_info_erase(nvm_info_page_t page) {
474 static_assert(kNvmErasedWord == UINT32_MAX,
475 "memset(..., 0xff, ...) below assumes an all-ones erased "
477 const rram_ctrl_info_page_t *p = page_ptr(page);
478 enum { kPageWords = NVM_BYTES_PER_PAGE /
sizeof(uint32_t) };
479 uint32_t erased[kPageWords];
480 memset(erased, 0xff,
sizeof(erased));
485 for (uint32_t i = 0; i < p->
num_pages; ++i) {
486 HARDENED_RETURN_IF_ERROR(rram_ctrl_data_write(
487 (p->
page_id + i) * NVM_BYTES_PER_PAGE, kPageWords, erased));
493 for (uint32_t i = 0; i < p->
num_pages; ++i) {
494 HARDENED_RETURN_IF_ERROR(
495 rram_ctrl_info_write(p, i * NVM_BYTES_PER_PAGE, kPageWords, erased));
500void nvm_ctrl_data_default_perms_set(nvm_page_perms_t perms) {
501 rram_ctrl_data_default_perms_set(perms_to_rram(perms));
518void nvm_ctrl_info_perms_set(nvm_info_page_t page, nvm_page_perms_t perms) {
519 const rram_ctrl_info_page_t *p = page_ptr(page);
523 rram_ctrl_info_perms_set(p, perms_to_rram(perms));
526void nvm_ctrl_data_default_cfg_set(nvm_page_cfg_t cfg) {
527 rram_ctrl_data_default_cfg_set(cfg_to_rram(cfg));
530nvm_page_cfg_t nvm_ctrl_data_default_cfg_get(
void) {
531 return cfg_from_rram(rram_ctrl_data_default_cfg_get());
534nvm_page_cfg_t nvm_ctrl_boot_data_cfg_get(
void) {
535 return cfg_from_rram(rram_ctrl_boot_data_cfg_get());
539void nvm_ctrl_info_cfg_set(nvm_info_page_t page, nvm_page_cfg_t cfg) {
540 const rram_ctrl_info_page_t *p = page_ptr(page);
544 rram_ctrl_info_cfg_set(p, cfg_to_rram(cfg));
548void nvm_ctrl_info_cfg_lock(nvm_info_page_t page) {
549 const rram_ctrl_info_page_t *p = page_ptr(page);
553 rram_ctrl_info_cfg_lock(p);
556void nvm_ctrl_data_region_protect(uint32_t region, uint32_t page_offset,
557 uint32_t num_pages, nvm_page_perms_t perms,
559 rram_ctrl_data_region_protect(region, page_offset, num_pages,
560 perms_to_rram(perms), cfg_to_rram(cfg), lock);
568void nvm_ctrl_exec_set(uint32_t exec_val) { rram_ctrl_exec_set(exec_val); }
570void nvm_ctrl_creator_info_pages_lockdown(
void) {
574 size_t i = 0, r = kNvmPagesNoOwnerAccessCount - 1;
575 for (; launder32(i) < kNvmPagesNoOwnerAccessCount &&
576 launder32(r) < kNvmPagesNoOwnerAccessCount;
578 const rram_ctrl_info_page_t *p = page_ptr(kNvmPagesNoOwnerAccess[i]);
592 rram_ctrl_info_page_lockdown(p);
601void nvm_ctrl_init(
void) { flash_ctrl_init(); }
603void nvm_ctrl_disable(
void) { flash_ctrl_disable(); }
605rom_error_t nvm_ctrl_data_read(uint32_t addr, uint32_t word_count,
void *data) {
606 return flash_ctrl_data_read(addr, word_count, data);
609rom_error_t nvm_ctrl_data_write(uint32_t addr, uint32_t word_count,
611 return flash_ctrl_data_write(addr, word_count, data);
614rom_error_t nvm_ctrl_data_erase(uint32_t addr) {
615 return flash_ctrl_data_erase(addr, kFlashCtrlEraseTypePage);
618rom_error_t nvm_ctrl_data_erase_verify(uint32_t addr) {
619 return flash_ctrl_data_erase_verify(addr, kFlashCtrlEraseTypePage);
622rom_error_t nvm_ctrl_chip_erase(
void) {
624 rom_error_t err_0 = flash_ctrl_data_erase(0, kFlashCtrlEraseTypeBank);
625 rom_error_t err_1 = flash_ctrl_data_erase(FLASH_CTRL_PARAM_BYTES_PER_BANK,
626 kFlashCtrlEraseTypeBank);
628 HARDENED_RETURN_IF_ERROR(err_0);
632rom_error_t nvm_ctrl_chip_erase_verify(
void) {
633 rom_error_t err_0 = flash_ctrl_data_erase_verify(0, kFlashCtrlEraseTypeBank);
634 rom_error_t err_1 = flash_ctrl_data_erase_verify(
635 FLASH_CTRL_PARAM_BYTES_PER_BANK, kFlashCtrlEraseTypeBank);
636 HARDENED_RETURN_IF_ERROR(err_0);
640rom_error_t nvm_ctrl_bootstrap_page_program(uint32_t addr,
size_t byte_count,
642 static_assert((FLASH_CTRL_PARAM_BYTES_PER_WORD &
643 (FLASH_CTRL_PARAM_BYTES_PER_WORD - 1)) == 0,
644 "Bytes per NVM word must be a power of two.");
646 kWordMask = FLASH_CTRL_PARAM_BYTES_PER_WORD - 1,
647 kProgPageSize = NVM_PROG_PAGE_SIZE,
648 kProgPageMask = kProgPageSize - 1,
652 size_t word_misalignment = byte_count & kWordMask;
653 if (word_misalignment > 0) {
654 size_t pad = FLASH_CTRL_PARAM_BYTES_PER_WORD - word_misalignment;
655 for (
size_t i = 0; i < pad; ++i) {
656 data[byte_count++] = 0xff;
659 size_t rem_word_count = byte_count /
sizeof(uint32_t);
661 flash_ctrl_data_default_perms_set((flash_ctrl_perms_t){
662 .read = kMultiBitBool4False,
663 .write = kMultiBitBool4True,
664 .erase = kMultiBitBool4False,
669 rom_error_t err_0 = kErrorOk;
670 size_t prog_page_misalignment = addr & kProgPageMask;
671 if (prog_page_misalignment > 0) {
673 (kProgPageSize - prog_page_misalignment) /
sizeof(uint32_t);
674 if (word_count > rem_word_count) {
675 word_count = rem_word_count;
677 err_0 = flash_ctrl_data_write(addr, word_count, data);
678 rem_word_count -= word_count;
679 data += word_count *
sizeof(uint32_t);
680 addr &= ~(uint32_t)kProgPageMask;
682 rom_error_t err_1 = kErrorOk;
683 if (rem_word_count > 0) {
684 err_1 = flash_ctrl_data_write(addr, rem_word_count, data);
686 flash_ctrl_data_default_perms_set((flash_ctrl_perms_t){
687 .read = kMultiBitBool4False,
688 .write = kMultiBitBool4False,
689 .erase = kMultiBitBool4False,
691 HARDENED_RETURN_IF_ERROR(err_0);
695rom_error_t nvm_ctrl_bootstrap_sector_erase(uint32_t addr) {
696 static_assert(FLASH_CTRL_PARAM_BYTES_PER_PAGE == 2048,
697 "Page size must be 2 KiB");
698 enum { kSectorAddrMask = ~UINT32_C(4096) + 1 };
699 addr &= kSectorAddrMask;
700 flash_ctrl_data_default_perms_set((flash_ctrl_perms_t){
701 .read = kMultiBitBool4False,
702 .write = kMultiBitBool4False,
703 .erase = kMultiBitBool4True,
705 rom_error_t err_0 = flash_ctrl_data_erase(addr, kFlashCtrlEraseTypePage);
706 rom_error_t err_1 = flash_ctrl_data_erase(
707 addr + FLASH_CTRL_PARAM_BYTES_PER_PAGE, kFlashCtrlEraseTypePage);
708 flash_ctrl_data_default_perms_set((flash_ctrl_perms_t){
709 .read = kMultiBitBool4False,
710 .write = kMultiBitBool4False,
711 .erase = kMultiBitBool4False,
713 HARDENED_RETURN_IF_ERROR(err_0);
717rom_error_t nvm_ctrl_info_read(nvm_info_page_t page, uint32_t offset,
718 uint32_t word_count,
void *data) {
719 return flash_ctrl_info_read(page_ptr(page), offset, word_count, data);
722rom_error_t nvm_ctrl_info_read_zeros_on_read_error(nvm_info_page_t page,
726 return flash_ctrl_info_read_zeros_on_read_error(page_ptr(page), offset,
730rom_error_t nvm_ctrl_info_write(nvm_info_page_t page, uint32_t offset,
731 uint32_t word_count,
const void *data) {
732 return flash_ctrl_info_write(page_ptr(page), offset, word_count, data);
735rom_error_t nvm_ctrl_info_erase(nvm_info_page_t page) {
736 return flash_ctrl_info_erase(page_ptr(page), kFlashCtrlEraseTypePage);
739void nvm_ctrl_data_default_perms_set(nvm_page_perms_t perms) {
740 flash_ctrl_data_default_perms_set(perms_to_flash(perms));
743void nvm_ctrl_info_perms_set(nvm_info_page_t page, nvm_page_perms_t perms) {
744 flash_ctrl_info_perms_set(page_ptr(page), perms_to_flash(perms));
747void nvm_ctrl_data_default_cfg_set(nvm_page_cfg_t cfg) {
748 flash_ctrl_data_default_cfg_set(cfg_to_flash(cfg));
751nvm_page_cfg_t nvm_ctrl_data_default_cfg_get(
void) {
752 return cfg_from_flash(flash_ctrl_data_default_cfg_get());
755nvm_page_cfg_t nvm_ctrl_boot_data_cfg_get(
void) {
756 return cfg_from_flash(flash_ctrl_boot_data_cfg_get());
759void nvm_ctrl_info_cfg_set(nvm_info_page_t page, nvm_page_cfg_t cfg) {
760 flash_ctrl_info_cfg_set(page_ptr(page), cfg_to_flash(cfg));
763void nvm_ctrl_info_cfg_lock(nvm_info_page_t page) {
764 flash_ctrl_info_cfg_lock(page_ptr(page));
767void nvm_ctrl_data_region_protect(uint32_t region, uint32_t page_offset,
768 uint32_t num_pages, nvm_page_perms_t perms,
770 flash_ctrl_data_region_protect(region, page_offset, num_pages,
771 perms_to_flash(perms), cfg_to_flash(cfg),
776 flash_ctrl_bank_erase_perms_set(enable);
779void nvm_ctrl_exec_set(uint32_t exec_val) { flash_ctrl_exec_set(exec_val); }
781void nvm_ctrl_creator_info_pages_lockdown(
void) {
783 2 * kNvmPagesNoOwnerAccessCount);
784 size_t i = 0, r = kNvmPagesNoOwnerAccessCount - 1;
785 for (; launder32(i) < kNvmPagesNoOwnerAccessCount &&
786 launder32(r) < kNvmPagesNoOwnerAccessCount;
788 flash_ctrl_info_page_lockdown(page_ptr(kNvmPagesNoOwnerAccess[i]));
796void nvm_ctrl_cert_info_page_creator_cfg(nvm_info_page_t page) {
798 nvm_ctrl_info_cfg_set(page, kNvmCertInfoPageCfg);
799 nvm_ctrl_info_perms_set(page, kNvmCertInfoPageCreatorAccess);
802void nvm_ctrl_cert_info_page_owner_restrict(nvm_info_page_t page) {
804 nvm_ctrl_info_perms_set(page, kNvmCertInfoPageOwnerAccess);
805 nvm_ctrl_info_cfg_lock(page);