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