1 /*
2 * Copyright 2017-2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_romapi.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "driver.romapi"
17 #endif
18
19 typedef status_t (*clearCacheCommand_t)(uint32_t instance);
20
21 /*!
22 * @brief Structure of version property.
23 *
24 * @ingroup bl_core
25 */
26 typedef union _standard_version
27 {
28 struct
29 {
30 uint8_t bugfix; /*!< bugfix version [7:0] */
31 uint8_t minor; /*!< minor version [15:8] */
32 uint8_t major; /*!< major version [23:16] */
33 char name; /*!< name [31:24] */
34 };
35 uint32_t version; /*!< combined version numbers */
36
37 #if defined(__cplusplus)
StandardVersion()38 StandardVersion() : version(0)
39 {
40 }
StandardVersion(uint32_t version)41 StandardVersion(uint32_t version) : version(version)
42 {
43 }
44 #endif
45 } standard_version_t;
46
47 /*!
48 * @brief Interface for the ROM FLEXSPI NOR flash driver.
49 */
50 typedef struct
51 {
52 uint32_t version;
53 status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
54 status_t (*page_program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dst_addr, const uint32_t *src);
55 status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
56 status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
57 status_t (*read)(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);
58 void (*clear_cache)(uint32_t instance);
59 status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
60 status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);
61 status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
62 status_t (*erase_sector)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
63 status_t (*erase_block)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
64 const uint32_t reserved0; /*!< Reserved */
65 status_t (*wait_busy)(uint32_t instance, flexspi_nor_config_t *config, bool isParallelMode, uint32_t address);
66 const uint32_t reserved1[2]; /*!< Reserved */
67 } flexspi_nor_driver_interface_t;
68
69 /*!
70 * @brief Root of the bootloader api tree.
71 *
72 * An instance of this struct resides in read-only memory in the bootloader. It
73 * provides a user application access to APIs exported by the bootloader.
74 *
75 * @note The order of existing fields must not be changed.
76 */
77 typedef struct
78 {
79 void (*runBootloader)(void *arg); /*!< Function to start the bootloader executing.*/
80 standard_version_t version; /*!< Bootloader version number.*/
81 const char *copyright; /*!< Copyright string.*/
82 const flexspi_nor_driver_interface_t *flexSpiNorDriver; /*!< FlexSPI NOR FLASH Driver API.*/
83 const uint32_t reserved[8]; /*!< Reserved */
84 } bootloader_api_entry_t;
85
86 /*******************************************************************************
87 * Variables
88 ******************************************************************************/
89 #if defined(FSL_FEATURE_BOOT_ROM_HAS_ROMAPI) && FSL_FEATURE_BOOT_ROM_HAS_ROMAPI
90
91 #define g_bootloaderTree ((bootloader_api_entry_t *)*(uint32_t *)0x0021001cU)
92
93 /*******************************************************************************
94 * ROM FLEXSPI NOR driver
95 ******************************************************************************/
96
97 #if defined(FSL_ROM_HAS_RUNBOOTLOADER_API) && FSL_ROM_HAS_RUNBOOTLOADER_API
98 /*!
99 * @brief Enter Bootloader.
100 *
101 * @param arg A pointer to the storage for the bootloader param.
102 * refer to System Boot Chapter in device reference manual for details.
103 */
ROM_RunBootloader(void * arg)104 void ROM_RunBootloader(void *arg)
105 {
106 g_bootloaderTree->runBootloader(arg);
107 }
108 #endif /* FSL_ROM_HAS_RUNBOOTLOADER_API */
109
110 #if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_GET_CONFIG) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_GET_CONFIG
111 /*! @brief Get FLEXSPI NOR Configuration Block based on specified option. */
ROM_FLEXSPI_NorFlash_GetConfig(uint32_t instance,flexspi_nor_config_t * config,serial_nor_config_option_t * option)112 status_t ROM_FLEXSPI_NorFlash_GetConfig(uint32_t instance,
113 flexspi_nor_config_t *config,
114 serial_nor_config_option_t *option)
115 {
116 return g_bootloaderTree->flexSpiNorDriver->get_config(instance, config, option);
117 }
118 #endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_GET_CONFIG */
119
120 /*!
121 * @brief Initialize Serial NOR devices via FLEXSPI.
122 *
123 * @param instance storage the instance of FLEXSPI.
124 * @param config A pointer to the storage for the driver runtime state.
125 */
ROM_FLEXSPI_NorFlash_Init(uint32_t instance,flexspi_nor_config_t * config)126 status_t ROM_FLEXSPI_NorFlash_Init(uint32_t instance, flexspi_nor_config_t *config)
127 {
128 return g_bootloaderTree->flexSpiNorDriver->init(instance, config);
129 }
130
131 /*!
132 * @brief Program data to Serial NOR via FLEXSPI.
133 *
134 * @param instance storage the instance of FLEXSPI.
135 * @param config A pointer to the storage for the driver runtime state.
136 * @param dst_addr A pointer to the desired flash memory to be programmed.
137 * @param src A pointer to the source buffer of data that is to be programmed
138 * into the NOR flash.
139 */
ROM_FLEXSPI_NorFlash_ProgramPage(uint32_t instance,flexspi_nor_config_t * config,uint32_t dst_addr,const uint32_t * src)140 status_t ROM_FLEXSPI_NorFlash_ProgramPage(uint32_t instance,
141 flexspi_nor_config_t *config,
142 uint32_t dst_addr,
143 const uint32_t *src)
144 {
145 return g_bootloaderTree->flexSpiNorDriver->page_program(instance, config, dst_addr, src);
146 }
147
148 #if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_READ) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_READ
149 /*!
150 * @brief Read data from Serial NOR
151 *
152 * @param instance storage the instance of FLEXSPI.
153 * @param config A pointer to the storage for the driver runtime state.
154 * @param dst A pointer to the dest buffer of data that is to be read from the NOR flash.
155 * @param lengthInBytes The length, given in bytes to be read.
156 */
ROM_FLEXSPI_NorFlash_Read(uint32_t instance,flexspi_nor_config_t * config,uint32_t * dst,uint32_t start,uint32_t lengthInBytes)157 status_t ROM_FLEXSPI_NorFlash_Read(
158 uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t lengthInBytes)
159 {
160 return g_bootloaderTree->flexSpiNorDriver->read(instance, config, dst, start, lengthInBytes);
161 }
162 #endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_READ */
163
164 /*!
165 * @brief Erase Flash Region specified by address and length.
166 *
167 * @param instance storage the index of FLEXSPI.
168 * @param config A pointer to the storage for the driver runtime state.
169 * @param start The start address of the desired NOR flash memory to be erased.
170 * @param length The length, given in bytes to be erased.
171 */
ROM_FLEXSPI_NorFlash_Erase(uint32_t instance,flexspi_nor_config_t * config,uint32_t start,uint32_t length)172 status_t ROM_FLEXSPI_NorFlash_Erase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length)
173 {
174 return g_bootloaderTree->flexSpiNorDriver->erase(instance, config, start, length);
175 }
176
177 #if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR
178 /*!
179 * @brief Erase one sector specified by address.
180 *
181 * @param instance storage the index of FLEXSPI.
182 * @param config A pointer to the storage for the driver runtime state.
183 * @param start The start address of the desired NOR flash memory to be erased.
184 */
ROM_FLEXSPI_NorFlash_EraseSector(uint32_t instance,flexspi_nor_config_t * config,uint32_t start)185 status_t ROM_FLEXSPI_NorFlash_EraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t start)
186 {
187 return g_bootloaderTree->flexSpiNorDriver->erase_sector(instance, config, start);
188 }
189 #endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR */
190
191 #if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_BLOCK) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_BLOCK
192 /*!
193 * @brief Erase one block specified by address.
194 *
195 * @param instance storage the index of FLEXSPI.
196 * @param config A pointer to the storage for the driver runtime state.
197 * @param start The start address of the desired NOR flash memory to be erased.
198 */
ROM_FLEXSPI_NorFlash_EraseBlock(uint32_t instance,flexspi_nor_config_t * config,uint32_t start)199 status_t ROM_FLEXSPI_NorFlash_EraseBlock(uint32_t instance, flexspi_nor_config_t *config, uint32_t start)
200 {
201 return g_bootloaderTree->flexSpiNorDriver->erase_block(instance, config, start);
202 }
203 #endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_BLOCK */
204
205 #if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL
206 /*! @brief Erase all the Serial NOR devices connected on FLEXSPI. */
ROM_FLEXSPI_NorFlash_EraseAll(uint32_t instance,flexspi_nor_config_t * config)207 status_t ROM_FLEXSPI_NorFlash_EraseAll(uint32_t instance, flexspi_nor_config_t *config)
208 {
209 return g_bootloaderTree->flexSpiNorDriver->erase_all(instance, config);
210 }
211 #endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL */
212
213 #if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER
214 /*! @brief FLEXSPI command */
ROM_FLEXSPI_NorFlash_CommandXfer(uint32_t instance,flexspi_xfer_t * xfer)215 status_t ROM_FLEXSPI_NorFlash_CommandXfer(uint32_t instance, flexspi_xfer_t *xfer)
216 {
217 return g_bootloaderTree->flexSpiNorDriver->xfer(instance, xfer);
218 }
219 #endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER */
220
221 #if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT
222 /*! @brief Configure FLEXSPI Lookup table. */
ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t instance,uint32_t seqIndex,const uint32_t * lutBase,uint32_t seqNumber)223 status_t ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t instance,
224 uint32_t seqIndex,
225 const uint32_t *lutBase,
226 uint32_t seqNumber)
227 {
228 return g_bootloaderTree->flexSpiNorDriver->update_lut(instance, seqIndex, lutBase, seqNumber);
229 }
230 #endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT */
231
232 /*! @brief Software reset for the FLEXSPI logic. */
ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance)233 void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance)
234 {
235 uint32_t clearCacheFunctionAddress = 0x0021a3b7U;
236 clearCacheCommand_t clearCacheCommand;
237 MISRA_CAST(clearCacheCommand_t, clearCacheCommand, uint32_t, clearCacheFunctionAddress);
238 (void)clearCacheCommand(instance);
239 }
240
241 /*! @brief Wait until device is idle*/
ROM_FLEXSPI_NorFlash_WaitBusy(uint32_t instance,flexspi_nor_config_t * config,bool isParallelMode,uint32_t address)242 status_t ROM_FLEXSPI_NorFlash_WaitBusy(uint32_t instance,
243 flexspi_nor_config_t *config,
244 bool isParallelMode,
245 uint32_t address)
246 {
247 return g_bootloaderTree->flexSpiNorDriver->wait_busy(instance, config, isParallelMode, address);
248 }
249
250 #endif /* FSL_FEATURE_BOOT_ROM_HAS_ROMAPI */
251