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 kFlashCtrlSecMmioDataRegionProtect = 1,
179 kFlashCtrlSecMmioDataRegionProtectLock = 1,
180};
181
182/**
183 * Value of a word in flash after erase.
184 */
185enum {
186 kFlashCtrlErasedWord = UINT32_MAX,
187};
188
189/**
190 * Kicks off the initialization of the flash controller.
191 *
192 * This must complete before flash can be accessed. The init status can be
193 * queried by calling `flash_ctrl_status_get()` and checking `init_wip`.
194 *
195 * The caller is responsible for calling
196 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInit)` when sec_mmio is being
197 * used to check expectations.
198 */
199void flash_ctrl_init(void);
200
201/**
202 * Permanently disable the flash controller.
203 */
204void flash_ctrl_disable(void);
206/**
207 * Status bits.
208 */
209typedef struct flash_ctrl_status {
210 /**
211 * Flash read FIFO full, software must consume data.
212 */
214 /**
215 * Flash read FIFO empty.
216 */
218 /**
219 * Flash program FIFO full, software must consume data.
220 */
222 /**
223 * Flash program FIFO empty.
224 */
226 /**
227 * Flash controller undergoing init.
228 */
229 bool init_wip;
230} flash_ctrl_status_t;
231
232/**
233 * Query the status registers on the flash controller.
234 *
235 * This function checks the various status bits as described in
236 * `flash_ctrl_status_t`.
237 *
238 * @param[out] status The current status of the flash controller.
239 */
240void flash_ctrl_status_get(flash_ctrl_status_t *status);
242/**
243 * Error code bits.
244 */
245typedef struct flash_ctrl_error_code {
246 /**
247 * Flash macro error occurred.
248 */
250 /**
251 * Shadow register update error.
252 */
254 /**
255 * Flash program type is unavailable.
256 */
257 bool prog_type_err;
258 /**
259 * Flash program window resolution error. Start and end of programming region
260 * are in different windows.
261 */
262 bool prog_win_err;
263 /**
264 * Flash programming error, could be an integrity error. Read the
265 * STD_FAULT_STATUS register.
266 */
267 bool prog_err;
268 /**
269 * Flash read error, could be an integrity error. Read the STD_FAULT_STATUS
270 * register.
271 */
272 bool rd_err;
273 /**
274 * Flash access permission error. Read the ERR_ADDR register for the faulting
275 * address.
276 */
277 bool mp_err;
278 /**
279 * Software has supplied an undefined flash operation.
280 */
281 bool op_err;
282} flash_ctrl_error_code_t;
283
284/**
285 * Query the error code register on the flash controller.
286 *
287 * This function checks the various error code bits as described in
288 * `flash_ctrl_error_code_t`.
289 *
290 * @param[out] error_code The current error code of the flash controller.
291 */
292void flash_ctrl_error_code_get(flash_ctrl_error_code_t *error_code);
293
294/**
295 * Reads data from the data partition.
296 *
297 * The flash controller will truncate to the closest, lower word aligned
298 * address. For example, if 0x13 is supplied, the controller will perform a read
299 * at address 0x10.
300 *
301 * @param addr Address to read from.
302 * @param word_count Number of bus words to read.
303 * @param[out] data Buffer to store the read data. Must be word aligned.
304 * @return Result of the operation.
305 */
307rom_error_t flash_ctrl_data_read(uint32_t addr, uint32_t word_count,
308 void *data);
309
310/**
311 * Reads data from an information page.
312 *
313 * The flash controller will truncate to the closest, lower word aligned
314 * address. For example, if 0x13 is supplied, the controller will start reading
315 * at address 0x10.
316 *
317 * @param info_page Information page to read from.
318 * @param offset Offset from the start of the page.
319 * @param word_count Number of bus words to read.
320 * @param[out] data Buffer to store the read data. Must be word aligned.
321 * @return Result of the operation.
322 */
324rom_error_t flash_ctrl_info_read(const flash_ctrl_info_page_t *info_page,
325 uint32_t offset, uint32_t word_count,
326 void *data);
327
328/**
329 * Reads data from an information page, returning all zeros if a read error code
330 * is encountered.
331 *
332 * The flash controller will truncate to the closest, lower word aligned
333 * address. For example, if 0x13 is supplied, the controller will start reading
334 * at address 0x10.
335 *
336 * @param info_page Information page to read from.
337 * @param offset Offset from the start of the page.
338 * @param word_count Number of bus words to read.
339 * @param[out] data Buffer to store the read data. Must be word aligned.
340 * @return Result of the operation.
341 */
343rom_error_t flash_ctrl_info_read_zeros_on_read_error(
344 const flash_ctrl_info_page_t *info_page, uint32_t offset,
345 uint32_t word_count, void *data);
346
347/**
348 * Writes data to the data partition.
349 *
350 * The flash controller will truncate to the closest, lower word aligned
351 * address. For example, if 0x13 is supplied, the controller will start writing
352 * at address 0x10.
353 *
354 * @param addr Address to write to.
355 * @param word_count Number of bus words to write.
356 * @param data Data to write. Must be word aligned.
357 * @return Result of the operation.
358 */
360rom_error_t flash_ctrl_data_write(uint32_t addr, uint32_t word_count,
361 const void *data);
362
363/**
364 * Writes data to an information page.
365 *
366 * The flash controller will truncate to the closest, lower word aligned
367 * address. For example, if 0x13 is supplied, the controller will start writing
368 * at address 0x10.
369 *
370 * @param info_page Information page to write to.
371 * @param offset Offset from the start of the page.
372 * @param word_count Number of bus words to write.
373 * @param data Data to write. Must be word aligned.
374 * @return Result of the operation.
375 */
377rom_error_t flash_ctrl_info_write(const flash_ctrl_info_page_t *info_page,
378 uint32_t offset, uint32_t word_count,
379 const void *data);
380
381/*
382 * Encoding generated with
383 * $ ./util/design/sparse-fsm-encode.py -d 5 -m 2 -n 32 \
384 * -s 2181785819 --language=c
385 *
386 * Minimum Hamming distance: 14
387 * Maximum Hamming distance: 14
388 * Minimum Hamming weight: 14
389 * Maximum Hamming weight: 18
390 */
391
392typedef enum flash_ctrl_erase_type {
393 /**
394 * Erase a page.
395 */
396 kFlashCtrlEraseTypePage = 0xaf0eab8b,
397 /**
398 * Erase a bank.
399 */
400 kFlashCtrlEraseTypeBank = 0x80329be9,
401} flash_ctrl_erase_type_t;
402
403/**
404 * Erases a data partition page or bank.
405 *
406 * The flash controller will truncate to the closest page boundary for page
407 * erase operations, and to the nearest bank aligned boundary for bank erase
408 * operations.
409 *
410 * @param addr Address that falls within the bank or page being deleted.
411 * @param erase_type Whether to erase a page or a bank.
412 * @return Result of the operation.
413 */
415rom_error_t flash_ctrl_data_erase(uint32_t addr,
416 flash_ctrl_erase_type_t erase_type);
417
418/**
419 * Verifies that a data partition page or bank was erased.
420 *
421 * @param addr Address that falls within the bank or page erased.
422 * @param erase_type Whether to verify a page or a bank.
423 * @return Result of the operation.
424 */
426rom_error_t flash_ctrl_data_erase_verify(uint32_t addr,
427 flash_ctrl_erase_type_t erase_type);
428
429/**
430 * Erases an information partition page or bank.
431 *
432 * @param info_page Information page to erase for page erases, or a page within
433 * the bank to erase for bank erases.
434 * @param erase_type Whether to erase a page or a bank.
435 * @return Result of the operation.
436 */
438rom_error_t flash_ctrl_info_erase(const flash_ctrl_info_page_t *info_page,
439 flash_ctrl_erase_type_t erase_type);
440
441/**
442 * A struct for specifying access permissions.
443 *
444 * flash_ctrl config registers use 4-bits for boolean values. Use
445 * `kMultiBitBool4True` to enable and `kMultiBitBool4False` to disable
446 * permissions.
448 * The bitfields in this stuct match up with the bitfields in the peripheral
449 * register.
450 */
451typedef struct flash_ctrl_perms {
452 uint32_t _pad0 : 4;
453 /**
454 * Read.
455 */
456 uint32_t read : 4;
457 /**
458 * Write.
459 */
460 uint32_t write : 4;
461 /**
462 * Erase.
463 */
464 uint32_t erase : 4;
465 uint32_t _pad1 : 16;
466} flash_ctrl_perms_t;
467OT_ASSERT_SIZE(flash_ctrl_perms_t, 4);
468
469/**
470 * Sets default access permissions for the data partition.
471 *
472 * A permission is enabled only if the corresponding field in `perms` is
473 * `kMultiBitBool4True`.
474 *
475 * The caller is responsible for calling
476 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioDataDefaultPermsSet)` when
477 * sec_mmio is being used to check expectations.
478 *
479 * @param perms New permissions.
480 */
481void flash_ctrl_data_default_perms_set(flash_ctrl_perms_t perms);
482
483/**
484 * Sets access permissions for an info page.
485 *
486 * A permission is enabled only if the corresponding field in `perms` is
487 * `kMultiBitBool4True`.
488 *
489 * * The caller is responsible for calling
490 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInfoPermsSet)` when sec_mmio is
491 * being used to check expectations.
492 *
493 * @param info_page An information page.
494 * @param perms New permissions.
495 */
496void flash_ctrl_info_perms_set(const flash_ctrl_info_page_t *info_page,
497 flash_ctrl_perms_t perms);
498
499/**
500 * A struct for flash configuration settings.
501 *
502 * flash_ctrl config registers use 4-bits for boolean values. Use
503 * `kMultiBitBool4True` to enable and `kMultiBitBool4False` to disable
504 * these settings.
506 * The bitfields in this stuct match up with the bitfields in the peripheral
507 * register.
508 */
509typedef struct flash_ctrl_cfg {
510 uint32_t _pad0 : 16;
511 /**
512 * Scrambling.
513 */
514 uint32_t scrambling : 4;
515 /**
516 * ECC.
517 */
518 uint32_t ecc : 4;
519 /**
520 * High endurance.
521 */
522 uint32_t he : 4;
523 uint32_t _pad1 : 4;
524} flash_ctrl_cfg_t;
525OT_ASSERT_SIZE(flash_ctrl_cfg_t, 4);
526
527/**
528 * Sets default configuration settings for the data partition.
529 *
530 * The caller is responsible for calling
531 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioDataDefaultCfgSet)` when sec_mmio
532 * is being used to check expectations.
533 *
534 * @param cfg New configuration settings.
535 */
536void flash_ctrl_data_default_cfg_set(flash_ctrl_cfg_t cfg);
537
538/**
539 * Reads the current default configuration settings for the data partition.
540 *
541 * @return Current configuration settings.
542 */
543flash_ctrl_cfg_t flash_ctrl_data_default_cfg_get(void);
544
545/**
546 * Reads the boot data info page configuration settings from OTP.
547 *
548 * @return Current OTP configuration settings.
549 */
550flash_ctrl_cfg_t flash_ctrl_boot_data_cfg_get(void);
551
552/**
553 * A type for flash_ctrl memory protection region indices.
554 */
555typedef uint32_t flash_ctrl_region_index_t;
556
557/**
558 * Configure memory protection for a region of pages.
559 *
560 * Based on the `region` parameter, this function overwrites the
561 * `MP_REGION_${region}` and `MP_REGION_CFG_${region}` registers. Calling this
562 * function invalidates previously-configured protections for `region`.
563 *
564 * @param region The index of the region to protect.
565 * @param page_offset The index of the first page in the region.
566 * @param num_pages The number of pages in the region.
567 * @param perms The read/write/erase permissions for this region.
568 * @param cfg Flash config values that are used to fill in some fields of the
569 * `MP_REGION_CFG_${region}` register.
570 * @param lock Lock the configuration for this region.
571 */
572void flash_ctrl_data_region_protect(flash_ctrl_region_index_t region,
573 uint32_t page_offset, uint32_t num_pages,
574 flash_ctrl_perms_t perms,
575 flash_ctrl_cfg_t cfg, hardened_bool_t lock);
576
577/**
578 * Sets configuration settings for an info page.
579 *
580 * The caller is responsible for calling
581 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInfoCfgSet)` when sec_mmio is
582 * being used to check expectations.
583 *
584 * @param info_page An information page.
585 * @param cfg New configuration settings.
586 */
587void flash_ctrl_info_cfg_set(const flash_ctrl_info_page_t *info_page,
588 flash_ctrl_cfg_t cfg);
589
590/**
591 * Write-locks configuration settings for an info page.
592 *
593 * The caller is responsible for calling
594 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInfoCfgLock)` when sec_mmio is
595 * being used to check expectations.
596 *
597 * @param info_page An information page.
598 * @param cfg New configuration settings.
599 */
600void flash_ctrl_info_cfg_lock(const flash_ctrl_info_page_t *info_page);
601
602/**
603 * Disables all access to an info page and locks its configuration until reset.
604 *
605 * Zeroes both the cfg register (clearing all permissions and configuration
606 * bits) and the cfg_wen register (preventing further writes to cfg).
607 *
608 * The caller is responsible for calling
609 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioInfoLockdown)` when sec_mmio is
610 * being used to check expectations.
611 *
612 * @param info_page An information page.
613 */
614void flash_ctrl_info_page_lockdown(const flash_ctrl_info_page_t *info_page);
615
616/**
617 * Set bank erase permissions for both flash banks.
618 *
619 * The caller is responsible for calling
620 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioBankErasePermsSet)` when
621 * sec_mmio is being used to check expectations.
622 *
623 * @param enable Whether to enable bank erase.
624 */
625void flash_ctrl_bank_erase_perms_set(hardened_bool_t enable);
626
627/**
628 * Enable execution from flash.
629 *
630 * Note: a ePMP region must also be configured in order to execute code in
631 * flash.
632 *
633 * The caller is responsible for calling
634 * `SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioExecSet)` when sec_mmio is being
635 * used to check expectations.
636 *
637 * @param exec_val Value to write to the `flash_ctrl.EXEC` register.
638 * `FLASH_CTRL_PARAM_EXEC_EN` will enable execution, all other values will
639 * disable execution.
640 */
641void flash_ctrl_exec_set(uint32_t exec_val);
642
643#ifdef __cplusplus
644}
645#endif
646
647#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_FLASH_CTRL_H_