Software APIs
flash_ctrl.h
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_FLASH_CTRL_H_
5#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_FLASH_CTRL_H_
6
7#include <limits.h>
8
11#include "sw/device/lib/base/multibits.h"
12#include "sw/device/silicon_creator/lib/error.h"
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18/**
19 * A flash partition.
20 *
21 * Each `flash_ctrl_partition_t` enumeration constant is a bitfield with the
22 * following layout:
23 * - Bit 0: Data (0) or information (1) partition.
24 * - Bits 1-2: Information partition type [0, 2].
25 */
26typedef enum flash_ctrl_partition {
27 /**
28 * Data Partition.
29 */
30 kFlashCtrlPartitionData = 0,
31 /**
32 * Information partition of type 0.
33 *
34 * This partition has 10 pages.
35 */
36 kFlashCtrlPartitionInfo0 = (0 << 1) | 1,
37 /**
38 * Information partition of type 1.
39 *
40 * This partition has 1 page.
41 */
42 kFlashCtrlPartitionInfo1 = (1 << 1) | 1,
43 /**
44 * Information partition of type 2.
45 *
46 * This partition has 2 pages.
47 */
48 kFlashCtrlPartitionInfo2 = (2 << 1) | 1,
49} flash_ctrl_partition_t;
50
51/**
52 * Bit and field definitions to get partition and info partition type from a
53 * `flash_ctrl_partition_t`.
54 */
55#define FLASH_CTRL_PARTITION_BIT_IS_INFO 0
56#define FLASH_CTRL_PARTITION_FIELD_INFO_TYPE \
57 ((bitfield_field32_t){.mask = 0x3, .index = 1})
58
59/**
60 * Table of flash information pages.
61 *
62 * Columns: Name, bank index, page index.
63 * We use an X macro to faciliate writing enums, switch statements, and unit
64 * tests using the contants here. All information pages in this table are of
65 * type 0 since silicon creator code does not need to access information pages
66 * of other types.
67 */
68// clang-format off
69#define FLASH_CTRL_INFO_PAGES_DEFINE(X) \
70 /**
71 * Bank 0 information partition type 0 pages.
72 */ \
73 X(kFlashCtrlInfoPageFactoryId, 0, 0) \
74 X(kFlashCtrlInfoPageCreatorSecret, 0, 1) \
75 X(kFlashCtrlInfoPageOwnerSecret, 0, 2) \
76 X(kFlashCtrlInfoPageWaferAuthSecret, 0, 3) \
77 X(kFlashCtrlInfoPageAttestationKeySeeds, 0, 4) \
78 X(kFlashCtrlInfoPageOwnerReserved0, 0, 5) \
79 X(kFlashCtrlInfoPageOwnerReserved1, 0, 6) \
80 X(kFlashCtrlInfoPageOwnerReserved2, 0, 7) \
81 X(kFlashCtrlInfoPageOwnerReserved3, 0, 8) \
82 X(kFlashCtrlInfoPageFactoryCerts, 0, 9) \
83 /**
84 * Bank 1 information partition type 0 pages.
85 */ \
86 X(kFlashCtrlInfoPageBootData0, 1, 0) \
87 X(kFlashCtrlInfoPageBootData1, 1, 1) \
88 X(kFlashCtrlInfoPageOwnerSlot0, 1, 2) \
89 X(kFlashCtrlInfoPageOwnerSlot1, 1, 3) \
90 X(kFlashCtrlInfoPageCreatorReserved0, 1, 4) \
91 X(kFlashCtrlInfoPageOwnerReserved4, 1, 5) \
92 X(kFlashCtrlInfoPageOwnerReserved5, 1, 6) \
93 X(kFlashCtrlInfoPageOwnerReserved6, 1, 7) \
94 X(kFlashCtrlInfoPageOwnerReserved7, 1, 8) \
95 X(kFlashCtrlInfoPageDiceCerts, 1, 9) \
96// clang-format on
97
98/**
99 * A struct for storing base, config write-enable register, and config register
100 * addresses of an info page.
101 */
102typedef struct flash_ctrl_info_page {
103 /**
104 * Base address.
105 */
106 uint32_t base_addr;
107 /**
108 * Config write-enable register address (offset from register base).
109 */
111 /**
112 * Config register address (offset from register base).
113 */
114 uint32_t cfg_offset;
115} flash_ctrl_info_page_t;
116
117/**
118 * Helper macro for declaring an extern `flash_ctrl_info_page_t`.
119 * @param name_ Name of the enumeration constant.
120 * @param bank_ Bank of the info page.
121 * @param page_ Page of the info page.
122 */
123#define INFO_PAGE_STRUCT_DECL_(name_, bank_, page_) \
124 extern const flash_ctrl_info_page_t name_;
125
126/**
127 * Info pages.
128 */
129FLASH_CTRL_INFO_PAGES_DEFINE(INFO_PAGE_STRUCT_DECL_);
130
131#undef INFO_PAGE_STRUCT_DECL_
132
133/**
134 * Bitfields for `CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG` and
135 * `CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG` OTP items.
136 *
137 * Defined here to be able to use in tests.
138 */
139#define FLASH_CTRL_OTP_FIELD_SCRAMBLING \
140 (bitfield_field32_t){.mask = UINT8_MAX, .index = CHAR_BIT * 0}
141#define FLASH_CTRL_OTP_FIELD_ECC \
142 (bitfield_field32_t){.mask = UINT8_MAX, .index = CHAR_BIT * 1}
143#define FLASH_CTRL_OTP_FIELD_HE \
144 (bitfield_field32_t){.mask = UINT8_MAX, .index = CHAR_BIT * 2}
145
146/**
147 * Bitfields for `CREATOR_SW_CFG_FLASH_HW_INFO_CFG_OVERRIDE` OTP item.
148 *
149 * Defined here to be able to use in tests.
150 */
151#define FLASH_CTRL_OTP_FIELD_HW_INFO_CFG_OVERRIDE_SCRAMBLE_DIS \
152 (bitfield_field32_t){.mask = UINT8_MAX, .index = CHAR_BIT * 0}
153#define FLASH_CTRL_OTP_FIELD_HW_INFO_CFG_OVERRIDE_ECC_DIS \
154 (bitfield_field32_t){.mask = UINT8_MAX, .index = CHAR_BIT * 1}
155
156/**
157 * The following constants represent the expected number of sec_mmio
158 * register writes performed by functions in provided in this module. See
159 * `SEC_MMIO_WRITE_INCREMENT()` for more details.
160 *
161 * Example:
162 * ```
163 * flash_ctrl_init();
164 * SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInit);
165 * ```
166 */
167enum {
168 kFlashCtrlSecMmioCertInfoPagesOwnerRestrict = 5,
169 kFlashCtrlSecMmioDataDefaultCfgSet = 1,
170 kFlashCtrlSecMmioDataDefaultPermsSet = 1,
171 kFlashCtrlSecMmioExecSet = 1,
172 kFlashCtrlSecMmioInfoCfgSet = 1,
173 kFlashCtrlSecMmioInfoCfgLock = 1,
174 kFlashCtrlSecMmioInfoPageLockdown = 2,
175 kFlashCtrlSecMmioInfoPermsSet = 1,
176 kFlashCtrlSecMmioBankErasePermsSet = 1,
177 kFlashCtrlSecMmioInit = 3,
178 // 2 writes: MP_REGION_${region} and MP_REGION_CFG_${region}.
179 kFlashCtrlSecMmioDataRegionProtect = 2,
180 kFlashCtrlSecMmioDataRegionProtectLock = 1,
181};
182
183/**
184 * Value of a word in flash after erase.
185 */
186enum {
187 kFlashCtrlErasedWord = UINT32_MAX,
188};
189
190/**
191 * Kicks off the initialization of the flash controller.
192 *
193 * This must complete before flash can be accessed. The init status can be
194 * queried by calling `flash_ctrl_status_get()` and checking `init_wip`.
195 *
196 * The caller is responsible for calling
197 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInit)` when sec_mmio is being
198 * used to check expectations.
199 */
200void flash_ctrl_init(void);
201
202/**
203 * Permanently disable the flash controller.
204 */
205void flash_ctrl_disable(void);
207/**
208 * Status bits.
209 */
210typedef struct flash_ctrl_status {
211 /**
212 * Flash read FIFO full, software must consume data.
213 */
215 /**
216 * Flash read FIFO empty.
217 */
219 /**
220 * Flash program FIFO full, software must consume data.
221 */
223 /**
224 * Flash program FIFO empty.
225 */
227 /**
228 * Flash controller undergoing init.
229 */
230 bool init_wip;
231} flash_ctrl_status_t;
232
233/**
234 * Query the status registers on the flash controller.
235 *
236 * This function checks the various status bits as described in
237 * `flash_ctrl_status_t`.
238 *
239 * @param[out] status The current status of the flash controller.
240 */
241void flash_ctrl_status_get(flash_ctrl_status_t *status);
243/**
244 * Error code bits.
245 */
246typedef struct flash_ctrl_error_code {
247 /**
248 * Flash macro error occurred.
249 */
251 /**
252 * Shadow register update error.
253 */
255 /**
256 * Flash program type is unavailable.
257 */
258 bool prog_type_err;
259 /**
260 * Flash program window resolution error. Start and end of programming region
261 * are in different windows.
262 */
263 bool prog_win_err;
264 /**
265 * Flash programming error, could be an integrity error. Read the
266 * STD_FAULT_STATUS register.
267 */
268 bool prog_err;
269 /**
270 * Flash read error, could be an integrity error. Read the STD_FAULT_STATUS
271 * register.
272 */
273 bool rd_err;
274 /**
275 * Flash access permission error. Read the ERR_ADDR register for the faulting
276 * address.
277 */
278 bool mp_err;
279 /**
280 * Software has supplied an undefined flash operation.
281 */
282 bool op_err;
283} flash_ctrl_error_code_t;
284
285/**
286 * Query the error code register on the flash controller.
287 *
288 * This function checks the various error code bits as described in
289 * `flash_ctrl_error_code_t`.
290 *
291 * @param[out] error_code The current error code of the flash controller.
292 */
293void flash_ctrl_error_code_get(flash_ctrl_error_code_t *error_code);
294
295/**
296 * Reads data from the data partition.
297 *
298 * The flash controller will truncate to the closest, lower word aligned
299 * address. For example, if 0x13 is supplied, the controller will perform a read
300 * at address 0x10.
301 *
302 * @param addr Address to read from.
303 * @param word_count Number of bus words to read.
304 * @param[out] data Buffer to store the read data. Must be word aligned.
305 * @return Result of the operation.
306 */
308rom_error_t flash_ctrl_data_read(uint32_t addr, uint32_t word_count,
309 void *data);
310
311/**
312 * Reads data from an information page.
313 *
314 * The flash controller will truncate to the closest, lower word aligned
315 * address. For example, if 0x13 is supplied, the controller will start reading
316 * at address 0x10.
317 *
318 * @param info_page Information page to read from.
319 * @param offset Offset from the start of the page.
320 * @param word_count Number of bus words to read.
321 * @param[out] data Buffer to store the read data. Must be word aligned.
322 * @return Result of the operation.
323 */
325rom_error_t flash_ctrl_info_read(const flash_ctrl_info_page_t *info_page,
326 uint32_t offset, uint32_t word_count,
327 void *data);
328
329/**
330 * Reads data from an information page, returning all zeros if a read error code
331 * is encountered.
332 *
333 * The flash controller will truncate to the closest, lower word aligned
334 * address. For example, if 0x13 is supplied, the controller will start reading
335 * at address 0x10.
336 *
337 * @param info_page Information page to read from.
338 * @param offset Offset from the start of the page.
339 * @param word_count Number of bus words to read.
340 * @param[out] data Buffer to store the read data. Must be word aligned.
341 * @return Result of the operation.
342 */
344rom_error_t flash_ctrl_info_read_zeros_on_read_error(
345 const flash_ctrl_info_page_t *info_page, uint32_t offset,
346 uint32_t word_count, void *data);
347
348/**
349 * Writes data to the data partition.
350 *
351 * The flash controller will truncate to the closest, lower word aligned
352 * address. For example, if 0x13 is supplied, the controller will start writing
353 * at address 0x10.
354 *
355 * @param addr Address to write to.
356 * @param word_count Number of bus words to write.
357 * @param data Data to write. Must be word aligned.
358 * @return Result of the operation.
359 */
361rom_error_t flash_ctrl_data_write(uint32_t addr, uint32_t word_count,
362 const void *data);
363
364/**
365 * Writes data to an information page.
366 *
367 * The flash controller will truncate to the closest, lower word aligned
368 * address. For example, if 0x13 is supplied, the controller will start writing
369 * at address 0x10.
370 *
371 * @param info_page Information page to write to.
372 * @param offset Offset from the start of the page.
373 * @param word_count Number of bus words to write.
374 * @param data Data to write. Must be word aligned.
375 * @return Result of the operation.
376 */
378rom_error_t flash_ctrl_info_write(const flash_ctrl_info_page_t *info_page,
379 uint32_t offset, uint32_t word_count,
380 const void *data);
381
382/*
383 * Encoding generated with
384 * $ ./util/design/sparse-fsm-encode.py -d 5 -m 2 -n 32 \
385 * -s 2181785819 --language=c
386 *
387 * Minimum Hamming distance: 14
388 * Maximum Hamming distance: 14
389 * Minimum Hamming weight: 14
390 * Maximum Hamming weight: 18
391 */
392
393typedef enum flash_ctrl_erase_type {
394 /**
395 * Erase a page.
396 */
397 kFlashCtrlEraseTypePage = 0xaf0eab8b,
398 /**
399 * Erase a bank.
400 */
401 kFlashCtrlEraseTypeBank = 0x80329be9,
402} flash_ctrl_erase_type_t;
403
404/**
405 * Erases a data partition page or bank.
406 *
407 * The flash controller will truncate to the closest page boundary for page
408 * erase operations, and to the nearest bank aligned boundary for bank erase
409 * operations.
410 *
411 * @param addr Address that falls within the bank or page being deleted.
412 * @param erase_type Whether to erase a page or a bank.
413 * @return Result of the operation.
414 */
416rom_error_t flash_ctrl_data_erase(uint32_t addr,
417 flash_ctrl_erase_type_t erase_type);
418
419/**
420 * Verifies that a data partition page or bank was erased.
421 *
422 * @param addr Address that falls within the bank or page erased.
423 * @param erase_type Whether to verify a page or a bank.
424 * @return Result of the operation.
425 */
427rom_error_t flash_ctrl_data_erase_verify(uint32_t addr,
428 flash_ctrl_erase_type_t erase_type);
429
430/**
431 * Erases an information partition page or bank.
432 *
433 * @param info_page Information page to erase for page erases, or a page within
434 * the bank to erase for bank erases.
435 * @param erase_type Whether to erase a page or a bank.
436 * @return Result of the operation.
437 */
439rom_error_t flash_ctrl_info_erase(const flash_ctrl_info_page_t *info_page,
440 flash_ctrl_erase_type_t erase_type);
441
442/**
443 * A struct for specifying access permissions.
444 *
445 * flash_ctrl config registers use 4-bits for boolean values. Use
446 * `kMultiBitBool4True` to enable and `kMultiBitBool4False` to disable
447 * permissions.
449 * The bitfields in this stuct match up with the bitfields in the peripheral
450 * register.
451 */
452typedef struct flash_ctrl_perms {
453 uint32_t _pad0 : 4;
454 /**
455 * Read.
456 */
457 uint32_t read : 4;
458 /**
459 * Write.
460 */
461 uint32_t write : 4;
462 /**
463 * Erase.
464 */
465 uint32_t erase : 4;
466 uint32_t _pad1 : 16;
467} flash_ctrl_perms_t;
468OT_ASSERT_SIZE(flash_ctrl_perms_t, 4);
469
470/**
471 * Sets default access permissions for the data partition.
472 *
473 * A permission is enabled only if the corresponding field in `perms` is
474 * `kMultiBitBool4True`.
475 *
476 * The caller is responsible for calling
477 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioDataDefaultPermsSet)` when
478 * sec_mmio is being used to check expectations.
479 *
480 * @param perms New permissions.
481 */
482void flash_ctrl_data_default_perms_set(flash_ctrl_perms_t perms);
483
484/**
485 * Sets access permissions for an info page.
486 *
487 * A permission is enabled only if the corresponding field in `perms` is
488 * `kMultiBitBool4True`.
489 *
490 * * The caller is responsible for calling
491 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInfoPermsSet)` when sec_mmio is
492 * being used to check expectations.
493 *
494 * @param info_page An information page.
495 * @param perms New permissions.
496 */
497void flash_ctrl_info_perms_set(const flash_ctrl_info_page_t *info_page,
498 flash_ctrl_perms_t perms);
499
500/**
501 * A struct for flash configuration settings.
502 *
503 * flash_ctrl config registers use 4-bits for boolean values. Use
504 * `kMultiBitBool4True` to enable and `kMultiBitBool4False` to disable
505 * these settings.
507 * The bitfields in this stuct match up with the bitfields in the peripheral
508 * register.
509 */
510typedef struct flash_ctrl_cfg {
511 uint32_t _pad0 : 16;
512 /**
513 * Scrambling.
514 */
515 uint32_t scrambling : 4;
516 /**
517 * ECC.
518 */
519 uint32_t ecc : 4;
520 /**
521 * High endurance.
522 */
523 uint32_t he : 4;
524 uint32_t _pad1 : 4;
525} flash_ctrl_cfg_t;
526OT_ASSERT_SIZE(flash_ctrl_cfg_t, 4);
527
528/**
529 * Sets default configuration settings for the data partition.
530 *
531 * The caller is responsible for calling
532 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioDataDefaultCfgSet)` when sec_mmio
533 * is being used to check expectations.
534 *
535 * @param cfg New configuration settings.
536 */
537void flash_ctrl_data_default_cfg_set(flash_ctrl_cfg_t cfg);
538
539/**
540 * Reads the current default configuration settings for the data partition.
541 *
542 * @return Current configuration settings.
543 */
544flash_ctrl_cfg_t flash_ctrl_data_default_cfg_get(void);
545
546/**
547 * Reads the boot data info page configuration settings from OTP.
548 *
549 * @return Current OTP configuration settings.
550 */
551flash_ctrl_cfg_t flash_ctrl_boot_data_cfg_get(void);
552
553/**
554 * A type for flash_ctrl memory protection region indices.
555 */
556typedef uint32_t flash_ctrl_region_index_t;
557
558/**
559 * Configure memory protection for a region of pages.
560 *
561 * Based on the `region` parameter, this function overwrites the
562 * `MP_REGION_${region}` and `MP_REGION_CFG_${region}` registers. Calling this
563 * function invalidates previously-configured protections for `region`.
564 *
565 * @param region The index of the region to protect.
566 * @param page_offset The index of the first page in the region.
567 * @param num_pages The number of pages in the region.
568 * @param perms The read/write/erase permissions for this region.
569 * @param cfg Flash config values that are used to fill in some fields of the
570 * `MP_REGION_CFG_${region}` register.
571 * @param lock Lock the configuration for this region.
572 */
573void flash_ctrl_data_region_protect(flash_ctrl_region_index_t region,
574 uint32_t page_offset, uint32_t num_pages,
575 flash_ctrl_perms_t perms,
576 flash_ctrl_cfg_t cfg, hardened_bool_t lock);
577
578/**
579 * Sets configuration settings for an info page.
580 *
581 * The caller is responsible for calling
582 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInfoCfgSet)` when sec_mmio is
583 * being used to check expectations.
584 *
585 * @param info_page An information page.
586 * @param cfg New configuration settings.
587 */
588void flash_ctrl_info_cfg_set(const flash_ctrl_info_page_t *info_page,
589 flash_ctrl_cfg_t cfg);
590
591/**
592 * Write-locks configuration settings for an info page.
593 *
594 * The caller is responsible for calling
595 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInfoCfgLock)` when sec_mmio is
596 * being used to check expectations.
597 *
598 * @param info_page An information page.
599 * @param cfg New configuration settings.
600 */
601void flash_ctrl_info_cfg_lock(const flash_ctrl_info_page_t *info_page);
602
603/**
604 * Disables all access to an info page and locks its configuration until reset.
605 *
606 * Zeroes both the cfg register (clearing all permissions and configuration
607 * bits) and the cfg_wen register (preventing further writes to cfg).
608 *
609 * The caller is responsible for calling
610 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInfoPageLockdown)` when sec_mmio
611 * is being used to check expectations.
612 *
613 * @param info_page An information page.
614 */
615void flash_ctrl_info_page_lockdown(const flash_ctrl_info_page_t *info_page);
616
617/**
618 * Set bank erase permissions for both flash banks.
619 *
620 * The caller is responsible for calling
621 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioBankErasePermsSet)` when
622 * sec_mmio is being used to check expectations.
623 *
624 * @param enable Whether to enable bank erase.
625 */
626void flash_ctrl_bank_erase_perms_set(hardened_bool_t enable);
627
628/**
629 * Enable execution from flash.
630 *
631 * Note: a ePMP region must also be configured in order to execute code in
632 * flash.
633 *
634 * The caller is responsible for calling
635 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioExecSet)` when sec_mmio is being
636 * used to check expectations.
637 *
638 * @param exec_val Value to write to the `flash_ctrl.EXEC` register.
639 * `FLASH_CTRL_PARAM_EXEC_EN` will enable execution, all other values will
640 * disable execution.
641 */
642void flash_ctrl_exec_set(uint32_t exec_val);
643
644#ifdef __cplusplus
645}
646#endif
647
648#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_FLASH_CTRL_H_