1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _HARDWARE_FLASH_H
8 #define _HARDWARE_FLASH_H
9 
10 #include "pico.h"
11 
12 /** \file flash.h
13  *  \defgroup hardware_flash hardware_flash
14  *
15  * \brief Low level flash programming and erase API
16  *
17  * Note these functions are *unsafe* if you are using both cores, and the other
18  * is executing from flash concurrently with the operation. In this case, you
19  * must perform your own synchronisation to make sure that no XIP accesses take
20  * place during flash programming. One option is to use the
21  * \ref multicore_lockout functions.
22  *
23  * Likewise they are *unsafe* if you have interrupt handlers or an interrupt
24  * vector table in flash, so you must disable interrupts before calling in
25  * this case.
26  *
27  * If PICO_NO_FLASH=1 is not defined (i.e. if the program is built to run from
28  * flash) then these functions will make a static copy of the second stage
29  * bootloader in SRAM, and use this to reenter execute-in-place mode after
30  * programming or erasing flash, so that they can safely be called from
31  * flash-resident code.
32  *
33  * \subsection flash_example Example
34  * \include flash_program.c
35  */
36 
37 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_FLASH, Enable/disable assertions in the hardware_flash module, type=bool, default=0, group=hardware_flash
38 #ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_FLASH
39 #ifdef PARAM_ASSERTIONS_ENABLED_FLASH // backwards compatibility with SDK < 2.0.0
40 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_FLASH PARAM_ASSERTIONS_ENABLED_FLASH
41 #else
42 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_FLASH 0
43 #endif
44 #endif
45 #define FLASH_PAGE_SIZE (1u << 8)
46 #define FLASH_SECTOR_SIZE (1u << 12)
47 #define FLASH_BLOCK_SIZE (1u << 16)
48 
49 #ifndef FLASH_UNIQUE_ID_SIZE_BYTES
50 #define FLASH_UNIQUE_ID_SIZE_BYTES 8
51 #endif
52 
53 // PICO_CONFIG: PICO_FLASH_SIZE_BYTES, size of primary flash in bytes, type=int, default=Usually provided via board header, group=hardware_flash
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 /*! \brief  Erase areas of flash
60  *  \ingroup hardware_flash
61  *
62  * \param flash_offs Offset into flash, in bytes, to start the erase. Must be aligned to a 4096-byte flash sector.
63  * \param count Number of bytes to be erased. Must be a multiple of 4096 bytes (one sector).
64  *
65  * @note Erasing a flash sector sets all the bits in all the pages in that sector to one.
66  * You can then "program" flash pages in the sector to turn some of the bits to zero.
67  * Once a bit is set to zero it can only be changed back to one by erasing the whole sector again.
68  */
69 void flash_range_erase(uint32_t flash_offs, size_t count);
70 
71 /*! \brief  Program flash
72  *  \ingroup hardware_flash
73  *
74  * \param flash_offs Flash address of the first byte to be programmed. Must be aligned to a 256-byte flash page.
75  * \param data Pointer to the data to program into flash
76  * \param count Number of bytes to program. Must be a multiple of 256 bytes (one page).
77  *
78  * @note: Programming a flash page effectively changes some of the bits from one to zero.
79  * The only way to change a zero bit back to one is to "erase" the whole sector that the page resides in.
80  * So you may need to make sure you have called flash_range_erase before calling flash_range_program.
81  */
82 
83 void flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count);
84 
85 /*! \brief Get flash unique 64 bit identifier
86  *  \ingroup hardware_flash
87  *
88  * Use a standard 4Bh RUID instruction to retrieve the 64 bit unique
89  * identifier from a flash device attached to the QSPI interface. Since there
90  * is a 1:1 association between the MCU and this flash, this also serves as a
91  * unique identifier for the board.
92  *
93  *  \param id_out Pointer to an 8-byte buffer to which the ID will be written
94  */
95 void flash_get_unique_id(uint8_t *id_out);
96 
97 /*! \brief Execute bidirectional flash command
98  *  \ingroup hardware_flash
99  *
100  * Low-level function to execute a serial command on a flash device attached
101  * to the QSPI interface. Bytes are simultaneously transmitted and received
102  * from txbuf and to rxbuf. Therefore, both buffers must be the same length,
103  * count, which is the length of the overall transaction. This is useful for
104  * reading metadata from the flash chip, such as device ID or SFDP
105  * parameters.
106  *
107  * The XIP cache is flushed following each command, in case flash state
108  * has been modified. Like other hardware_flash functions, the flash is not
109  * accessible for execute-in-place transfers whilst the command is in
110  * progress, so entering a flash-resident interrupt handler or executing flash
111  * code on the second core concurrently will be fatal. To avoid these pitfalls
112  * it is recommended that this function only be used to extract flash metadata
113  * during startup, before the main application begins to run: see the
114  * implementation of pico_get_unique_id() for an example of this.
115  *
116  *  \param txbuf Pointer to a byte buffer which will be transmitted to the flash
117  *  \param rxbuf Pointer to a byte buffer where data received from the flash will be written. txbuf and rxbuf may be the same buffer.
118  *  \param count Length in bytes of txbuf and of rxbuf
119  */
120 void flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count);
121 
122 void flash_flush_cache(void);
123 
124 #if !PICO_RP2040
125 typedef enum {
126     FLASH_DEVINFO_SIZE_NONE = 0x0,
127     FLASH_DEVINFO_SIZE_8K = 0x1,
128     FLASH_DEVINFO_SIZE_16K = 0x2,
129     FLASH_DEVINFO_SIZE_32K = 0x3,
130     FLASH_DEVINFO_SIZE_64K = 0x4,
131     FLASH_DEVINFO_SIZE_128K = 0x5,
132     FLASH_DEVINFO_SIZE_256K = 0x6,
133     FLASH_DEVINFO_SIZE_512K = 0x7,
134     FLASH_DEVINFO_SIZE_1M = 0x8,
135     FLASH_DEVINFO_SIZE_2M = 0x9,
136     FLASH_DEVINFO_SIZE_4M = 0xa,
137     FLASH_DEVINFO_SIZE_8M = 0xb,
138     FLASH_DEVINFO_SIZE_16M = 0xc,
139     FLASH_DEVINFO_SIZE_MAX = 0xc
140 } flash_devinfo_size_t;
141 
142 /*! \brief Convert a flash/PSRAM size enum to an integer size in bytes
143  *  \ingroup hardware_flash
144  */
flash_devinfo_size_to_bytes(flash_devinfo_size_t size)145 static inline uint32_t flash_devinfo_size_to_bytes(flash_devinfo_size_t size) {
146     if (size == FLASH_DEVINFO_SIZE_NONE) {
147         return 0;
148     } else {
149         return 4096u << (uint)size;
150     }
151 }
152 
153 /*! \brief Convert an integer flash/PSRAM size in bytes to a size enum, as
154   !  stored in OTP and used by the ROM.
155  *  \ingroup hardware_flash
156  */
flash_devinfo_bytes_to_size(uint32_t bytes)157 static inline flash_devinfo_size_t flash_devinfo_bytes_to_size(uint32_t bytes) {
158     // Must be zero or a power of two
159     valid_params_if(HARDWARE_FLASH, (bytes & (bytes - 1)) == 0u);
160     uint sectors = bytes / 4096u;
161     if (sectors <= 1u) {
162         return FLASH_DEVINFO_SIZE_NONE;
163     } else {
164         return (flash_devinfo_size_t) __builtin_ctz(sectors);
165     }
166 }
167 
168 /*! \brief Get the size of the QSPI device attached to chip select cs, according to FLASH_DEVINFO
169  *  \ingroup hardware_flash
170  *
171  * \param cs Chip select index: 0 is QMI chip select 0 (QSPI CS pin), 1 is QMI chip select 1.
172  *
173  * The bootrom reads the FLASH_DEVINFO OTP data entry from OTP into boot RAM during startup. This
174  * contains basic information about the flash device which can be queried without communicating
175  * with the external device.(There are several methods to determine the size of a QSPI device over
176  * QSPI, but none are universally supported.)
177  *
178  * Since the FLASH_DEVINFO information is stored in boot RAM at runtime, it can be updated. Updates
179  * made in this way persist until the next reboot. The ROM uses this device information to control
180  * some low-level flash API behaviour, such as issuing an XIP exit sequence to CS 1 if its size is
181  * nonzero.
182  *
183  * If the macro PICO_FLASH_SIZE_BYTES is specified, this overrides the value for chip select 0. This
184  * can be specified in a board header if a board is always equipped with the same size of flash.
185  */
186 flash_devinfo_size_t flash_devinfo_get_cs_size(uint cs);
187 
188 /*! \brief Update the size of the QSPI device attached to chip select cs in the runtime copy
189  *         of FLASH_DEVINFO.
190  *
191  *  \ingroup hardware_flash
192  *
193  * \param cs Chip select index: 0 is QMI chip select 0 (QSPI CS pin), 1 is QMI chip select 1.
194  *
195  * \param size The size of the attached device, or FLASH_DEVINFO_SIZE_NONE if there is none on this
196  *  chip select.
197  *
198  * The bootrom maintains a copy in boot RAM of the FLASH_DEVINFO information read from OTP during
199  * startup. This function updates that copy to reflect runtime information about the sizes of
200  * attached QSPI devices.
201  *
202  * This controls the behaviour of some ROM flash APIs, such as bounds checking addresses for
203  * erase/programming in the checked_flash_op() API, or issuing an XIP exit sequence to CS 1 in
204  * flash_exit_xip() if the size is nonzero.
205  */
206 void flash_devinfo_set_cs_size(uint cs, flash_devinfo_size_t size);
207 
208 /*! \brief Check whether all attached devices support D8h block erase with 64k size, according to
209  *         FLASH_DEVINFO.
210  *
211  *  \ingroup hardware_flash
212  *
213  * This controls whether checked_flash_op() ROM API uses D8h 64k block erase where possible, for
214  * faster erase times. If not, this ROM API always uses 20h 4k sector erase.
215  *
216  * The bootrom loads this flag from the OTP FLASH_DEVINFO data entry during startup, and stores it
217  * in boot RAM. You can update the boot RAM copy based on runtime knowledge of the attached QSPI
218  * devices.
219  */
220 bool flash_devinfo_get_d8h_erase_supported(void);
221 
222 /*! \brief Specify whether all attached devices support D8h block erase with 64k size, in the
223  *         runtime copy of FLASH_DEVINFO
224  *
225  *  \ingroup hardware_flash
226  *
227  * This function updates the boot RAM copy of OTP FLASH_DEVINFO. The flag passed here is visible to
228  * ROM APIs, and is also returned in the next call to flash_devinfo_get_d8h_erase_supported()
229  */
230 void flash_devinfo_set_d8h_erase_supported(bool supported);
231 
232 /*! \brief Check the GPIO allocated for each chip select, according to FLASH_DEVINFO
233  *  \ingroup hardware_flash
234  *
235  * \param cs Chip select index (only the value 1 is supported on RP2350)
236  */
237 uint flash_devinfo_get_cs_gpio(uint cs);
238 
239 /*! \brief Update the GPIO allocated for each chip select in the runtime copy of FLASH_DEVINFO
240  *  \ingroup hardware_flash
241  *
242  * \param cs Chip select index (only the value 1 is supported on RP2350)
243  *
244  * \param gpio GPIO index (must be less than NUM_BANK0_GPIOS)
245  */
246 void flash_devinfo_set_cs_gpio(uint cs, uint gpio);
247 
248 #endif // !PICO_RP2040
249 
250 #ifdef __cplusplus
251 }
252 #endif
253 
254 #endif
255