1 /*
2  * Copyright 2023, NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef _FSL_ROMAPI_H_
9 #define _FSL_ROMAPI_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup romapi
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /* Component ID definition, used by tools. */
23 #ifndef FSL_COMPONENT_ID
24 #define FSL_COMPONENT_ID "platform.drivers.romapi"
25 #endif
26 
27 /*! @name Driver version */
28 /*@{*/
29 
30 /*! @brief romapi driver version 2.0.0. */
31 #define FSL_ROMAPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
32 /*@}*/
33 
34 /*!
35  * @name Flash status
36  * @{
37  */
38 /*! @brief Flash driver status group. */
39 #if defined(kStatusGroup_FlashDriver)
40 #define kStatusGroupGeneric     kStatusGroup_Generic
41 #define kStatusGroupFlashDriver kStatusGroup_FlashDriver
42 #elif defined(kStatusGroup_FLASHIAP)
43 #define kStatusGroupGeneric     kStatusGroup_Generic
44 #define kStatusGroupFlashDriver kStatusGroup_FLASH
45 #else
46 #define kStatusGroupGeneric     0
47 #define kStatusGroupFlashDriver 1
48 #endif
49 
50 /*! @brief Constructs a status code value from a group and a code number. */
51 #if !defined(MAKE_STATUS)
52 #define MAKE_STATUS(group, code) ((((group) * 100) + (code)))
53 #endif
54 
55 /*!
56  * @brief Flash driver status codes.
57  */
58 enum
59 {
60     kStatus_FLASH_Success         = MAKE_STATUS(kStatusGroupGeneric, 0),     /*!< API is executed successfully*/
61     kStatus_FLASH_InvalidArgument = MAKE_STATUS(kStatusGroupGeneric, 4),     /*!< Invalid argument*/
62     kStatus_FLASH_SizeError       = MAKE_STATUS(kStatusGroupFlashDriver, 0), /*!< Error size*/
63     kStatus_FLASH_AlignmentError =
64         MAKE_STATUS(kStatusGroupFlashDriver, 1), /*!< Parameter is not aligned with the specified baseline*/
65     kStatus_FLASH_AddressError = MAKE_STATUS(kStatusGroupFlashDriver, 2), /*!< Address is out of range */
66     kStatus_FLASH_AccessError =
67         MAKE_STATUS(kStatusGroupFlashDriver, 3), /*!< Invalid instruction codes and out-of bound addresses */
68     kStatus_FLASH_ProtectionViolation = MAKE_STATUS(
69         kStatusGroupFlashDriver, 4), /*!< The program/erase operation is requested to execute on protected areas */
70     kStatus_FLASH_CommandFailure =
71         MAKE_STATUS(kStatusGroupFlashDriver, 5), /*!< Run-time error during command execution. */
72     kStatus_FLASH_UnknownProperty = MAKE_STATUS(kStatusGroupFlashDriver, 6), /*!< Unknown property.*/
73     kStatus_FLASH_EraseKeyError   = MAKE_STATUS(kStatusGroupFlashDriver, 7)  /*!< API erase key is invalid.*/
74 };
75 /*@}*/
76 
77 /*!
78  * @brief Enumeration for various flash properties.
79  */
80 typedef enum _flash_property_tag
81 {
82     kFLASH_PropertyPflashSectorSize    = 0x00U, /*!< Pflash sector size property.*/
83     kFLASH_PropertyPflashTotalSize     = 0x01U, /*!< Pflash total size property.*/
84     kFLASH_PropertyPflashBlockSize     = 0x02U, /*!< Pflash block size property.*/
85     kFLASH_PropertyPflashBlockCount    = 0x03U, /*!< Pflash block count property.*/
86     kFLASH_PropertyPflashBlockBaseAddr = 0x04U, /*!< Pflash block base address property.*/
87     kFLASH_PropertyPflashPageSize      = 0x30U, /*!< Pflash page size property.*/
88     kFLASH_PropertyPflashSystemFreq    = 0x31U, /*!< System Frequency property.*/
89     kFLASH_PropertyFfrSectorSize       = 0x40U, /*!< FFR sector size property.*/
90     kFLASH_PropertyFfrTotalSize        = 0x41U, /*!< FFR total size property.*/
91     kFLASH_PropertyFfrBlockBaseAddr    = 0x42U, /*!< FFR block base address property.*/
92     kFLASH_PropertyFfrPageSize         = 0x43U, /*!< FFR page size property.*/
93 } flash_property_tag_t;
94 
95 /*! @brief Flash controller paramter config. */
96 typedef struct _flash_ffr_config
97 {
98     uint32_t ffrBlockBase;
99     uint32_t ffrTotalSize;
100     uint32_t ffrPageSize;
101     uint32_t sectorSize;
102     uint32_t cfpaPageVersion;
103     uint32_t cfpaPageOffset;
104 } flash_ffr_config_t;
105 
106 /*! @brief Flash driver state information.
107  *
108  * An instance of this structure is allocated by the user of the flash driver and
109  * passed into each of the driver APIs.
110  */
111 typedef struct _flash_config
112 {
113     uint32_t PFlashBlockBase;  /*!< A base address of the first PFlash block */
114     uint32_t PFlashTotalSize;  /*!< The size of the combined PFlash block. */
115     uint32_t PFlashBlockCount; /*!< A number of PFlash blocks. */
116     uint32_t PFlashPageSize;   /*!< The size in bytes of a page of PFlash. */
117     uint32_t PFlashSectorSize; /*!< The size in bytes of a sector of PFlash. */
118     flash_ffr_config_t ffrConfig;
119 } flash_config_t;
120 
121 /*! @brief Interface for the flash driver. */
122 typedef struct _flash_driver_interface
123 {
124     /* Flash driver */
125     status_t (*flash_init)(flash_config_t *config);
126     status_t (*flash_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key);
127     status_t (*flash_program_phrase)(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes);
128     status_t (*flash_program_page)(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes);
129     status_t (*flash_verify_program)(flash_config_t *config,
130                                      uint32_t start,
131                                      uint32_t lengthInBytes,
132                                      const uint8_t *expectedData,
133                                      uint32_t *failedAddress,
134                                      uint32_t *failedData);
135     status_t (*flash_verify_erase_phrase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
136     status_t (*flash_verify_erase_page)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
137     status_t (*flash_verify_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
138     status_t (*flash_get_property)(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value);
139     /* IFR driver */
140     status_t (*ifr_verify_erase_phrase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
141     status_t (*ifr_verify_erase_page)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
142     status_t (*ifr_verify_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
143     status_t (*flash_read)(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes);
144     /* version */
145     uint32_t version;
146 } flash_driver_interface_t;
147 
148 /*! @brief Constructs the four character code for the Flash driver API key. */
149 #if !defined(FOUR_CHAR_CODE)
150 #define FOUR_CHAR_CODE(a, b, c, d) (((d) << 24) | ((c) << 16) | ((b) << 8) | ((a)))
151 #endif
152 
153 /*!
154  * @brief Enumeration for Flash driver API keys.
155  *
156  * @note The resulting value is built with a byte order such that the string
157  * being readable in expected order when viewed in a hex editor, if the value
158  * is treated as a 32-bit little endian value.
159  */
160 enum _flash_driver_api_keys
161 {
162     kFLASH_ApiEraseKey = FOUR_CHAR_CODE('l', 'f', 'e', 'k') /*!< Key value used to validate all flash erase APIs.*/
163 };
164 
165 /*   API prototype fields definition.
166 | 31 : 24   |    23 : 20        |     19 : 16        |  15 : 12             |  11 : 8     |  7 : 0   |
167 |     Tag   |   Boot mode       | bootloader periphal|  Instance            |  Image Index| Reserved  |
168 |           |                   |                    |  Used For Boot mode 0|             |           |
169 |           | 0: Passive mode   | 0 - Auto detection |                      |             |           |
170 |           | 1: ISP mode       | 1 - USB-HID        |                      |             |           |
171 |           |                   | 2 - UART           |                      |             |           |
172 |           |                   | 3 - SPI            |                      |             |           |
173 |           |                   | 4 - I2C            |                      |             |           |
174 |           |                   | 5 - CAN            |                      |             |           |
175 */
176 typedef struct
177 {
178     union
179     {
180         struct
181         {
182             uint32_t reserved : 8;
183             uint32_t boot_image_index : 4;
184             uint32_t instance : 4;
185             uint32_t boot_interface : 4;
186             uint32_t mode : 4;
187             uint32_t tag : 8;
188         } B;
189         uint32_t U;
190     } option;
191 } user_app_boot_invoke_option_t;
192 
193 /*! @brief Root of the bootloader API tree.
194  *
195  *  An instance of this struct resides in read-only memory in the bootloader. It
196  *  provides a user application access to APIs exported by the bootloader.
197  *
198  */
199 typedef struct _bootloader_tree
200 {
201     void (*run_bootloader)(void *arg);            /*!< Function to start the bootloader executing. */
202     const flash_driver_interface_t *flash_driver; /*!< Internal Flash driver API. */
203     void (*jump)(void *arg);
204 } bootloader_tree_t;
205 
206 /** ROM API base address */
207 #define ROM_API_BASE (0x03003fe0u)
208 /** ROM API base pointer */
209 #define ROM_API ((bootloader_tree_t *)ROM_API_BASE)
210 /** FLASH API base pointer */
211 #define FLASH_API (ROM_API->flash_driver)
212 
213 /*!
214  * @name Flash API
215  * @{
216  */
217 
218 /*!
219  * @brief Initializes the global flash properties structure members
220  *
221  * This function checks and initializes the Flash module for the other Flash APIs.
222  *
223  * @param config Pointer to the storage for the driver runtime state.
224  *
225  */
FLASH_Init(flash_config_t * config)226 static inline status_t FLASH_Init(flash_config_t *config)
227 {
228     return FLASH_API->flash_init(config);
229 }
230 
231 /*!
232  * @brief Erases the flash sectors encompassed by parameters passed into function
233  *
234  * This function erases the appropriate number of flash sectors based on the
235  * desired start address and length.
236  *
237  * @param config The pointer to the storage for the driver runtime state.
238  * @param start The start address of the desired flash memory to be erased.
239  *              NOTE: The start address need to be 4 Bytes-aligned.
240  *
241  * @param lengthInBytes The length, given in bytes need be 4 Bytes-aligned.
242  *
243  * @param key The value used to validate all flash erase APIs.
244  *
245  */
FLASH_EraseSector(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,uint32_t key)246 static inline status_t FLASH_EraseSector(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key)
247 {
248     return FLASH_API->flash_erase_sector(config, start, lengthInBytes, key);
249 }
250 
251 /*!
252  * @brief Programs flash phrases with data at locations passed in through parameters
253  *
254  * This function programs the flash memory with the desired data for a given
255  * flash area as determined by the start address and the length.
256  *
257  * @param config A pointer to the storage for the driver runtime state.
258  * @param start The start address of the desired flash memory to be programmed. Must be
259  *              word-aligned.
260  * @param src A pointer to the source buffer of data that is to be programmed
261  *            into the flash.
262  * @param lengthInBytes The length, given in bytes (not words or long-words),
263  *                      to be programmed. Must be word-aligned.
264  *
265  */
FLASH_ProgramPhrase(flash_config_t * config,uint32_t start,uint8_t * src,uint32_t lengthInBytes)266 static inline status_t FLASH_ProgramPhrase(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
267 {
268     return FLASH_API->flash_program_phrase(config, start, src, lengthInBytes);
269 }
270 
271 /*!
272  * @brief Programs flash page with data at locations passed in through parameters
273  *
274  * This function programs the flash memory with the desired data for a given
275  * flash area as determined by the start address and the length.
276  *
277  * @param config A pointer to the storage for the driver runtime state.
278  * @param start The start address of the desired flash memory to be programmed. Must be
279  *              word-aligned.
280  * @param src A pointer to the source buffer of data that is to be programmed
281  *            into the flash.
282  * @param lengthInBytes The length, given in bytes (not words or long-words),
283  *                      to be programmed. Must be word-aligned.
284  *
285  */
FLASH_ProgramPage(flash_config_t * config,uint32_t start,uint8_t * src,uint32_t lengthInBytes)286 static inline status_t FLASH_ProgramPage(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
287 {
288     return FLASH_API->flash_program_page(config, start, src, lengthInBytes);
289 }
290 
291 /*!
292  * @brief Verifies programming of the desired flash area
293  *
294  * This function verifies the data programed in the flash memory using the
295  * Flash Program Check Command and compares it to the expected data for a given
296  * flash area as determined by the start address and length.
297  *
298  * @param config A pointer to the storage for the driver runtime state.
299  * @param start The start address of the desired flash memory to be verified. Must be word-aligned.
300  * @param lengthInBytes The length, given in bytes (not words or long-words),
301  *        to be verified. Must be word-aligned.
302  * @param expectedData A pointer to the expected data that is to be
303  *        verified against.
304  * @param failedAddress A pointer to the returned failing address.
305  * @param failedData A pointer to the returned failing data.  Some derivatives do
306  *        not include failed data as part of the FCCOBx registers.  In this
307  *        case, zeros are returned upon failure.
308  *
309  */
FLASH_VerifyProgram(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,const uint8_t * expectedData,uint32_t * failedAddress,uint32_t * failedData)310 static inline status_t FLASH_VerifyProgram(flash_config_t *config,
311                                            uint32_t start,
312                                            uint32_t lengthInBytes,
313                                            const uint8_t *expectedData,
314                                            uint32_t *failedAddress,
315                                            uint32_t *failedData)
316 {
317     return FLASH_API->flash_verify_program(config, start, lengthInBytes, expectedData, failedAddress, failedData);
318 }
319 
320 /*!
321  * @brief Verify that the flash phrases are erased
322  *
323  * This function checks the appropriate number of flash sectors based on
324  * the desired start address and length to check whether the flash is erased
325  *
326  * @param config A pointer to the storage for the driver runtime state.
327  * @param start The start address of the desired flash memory to be verified.
328  *        The start address does not need to be sector-aligned but must be word-aligned.
329  * @param lengthInBytes The length, given in bytes (not words or long-words),
330  *        to be verified. Must be word-aligned.
331  *
332  */
FLASH_VerifyErasePhrase(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)333 static inline status_t FLASH_VerifyErasePhrase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
334 {
335     return FLASH_API->flash_verify_erase_phrase(config, start, lengthInBytes);
336 }
337 
338 /*!
339  * @brief Verify that the flash pages are erased
340  *
341  * This function checks the appropriate number of flash sectors based on
342  * the desired start address and length to check whether the flash is erased
343  *
344  * @param config A pointer to the storage for the driver runtime state.
345  * @param start The start address of the desired flash memory to be verified.
346  *        The start address does not need to be sector-aligned but must be word-aligned.
347  * @param lengthInBytes The length, given in bytes (not words or long-words),
348  *        to be verified. Must be word-aligned.
349  *
350  */
FLASH_VerifyErasePage(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)351 static inline status_t FLASH_VerifyErasePage(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
352 {
353     return FLASH_API->flash_verify_erase_page(config, start, lengthInBytes);
354 }
355 
356 /*!
357  * @brief Verify that the flash sectors are erased
358  *
359  * This function checks the appropriate number of flash sectors based on
360  * the desired start address and length to check whether the flash is erased
361  *
362  * @param config A pointer to the storage for the driver runtime state.
363  * @param start The start address of the desired flash memory to be verified.
364  *        The start address does not need to be sector-aligned but must be word-aligned.
365  * @param lengthInBytes The length, given in bytes (not words or long-words),
366  *        to be verified. Must be word-aligned.
367  *
368  */
FLASH_VerifyEraseSector(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)369 static inline status_t FLASH_VerifyEraseSector(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
370 {
371     return FLASH_API->flash_verify_erase_sector(config, start, lengthInBytes);
372 }
373 
374 /*!
375  * @brief Returns the desired flash property
376  *
377  * @param config A pointer to the storage for the driver runtime state.
378  * @param whichProperty The desired property from the list of properties in
379  *        enum flash_property_tag_t
380  * @param value A pointer to the value returned for the desired flash property.
381  *
382  */
FLASH_GetProperty(flash_config_t * config,flash_property_tag_t whichProperty,uint32_t * value)383 static inline status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value)
384 {
385     return FLASH_API->flash_get_property(config, whichProperty, value);
386 }
387 
388 /*!
389  * @brief Verify that the IFR0 phrases are erased
390  *
391  * This function checks the appropriate number of flash sectors based on
392  * the desired start address and length to check whether the flash is erased
393  *
394  * @param config A pointer to the storage for the driver runtime state.
395  * @param start The start address of the desired flash memory to be verified.
396  *        The start address does not need to be sector-aligned but must be word-aligned.
397  * @param lengthInBytes The length, given in bytes (not words or long-words),
398  *        to be verified. Must be word-aligned.
399  *
400  */
IFR_VerifyErasePhrase(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)401 static inline status_t IFR_VerifyErasePhrase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
402 {
403     return FLASH_API->ifr_verify_erase_phrase(config, start, lengthInBytes);
404 }
405 
406 /*!
407  * @brief Verify that the IFR0 pages are erased
408  *
409  * This function checks the appropriate number of flash sectors based on
410  * the desired start address and length to check whether the flash is erased
411  *
412  * @param config A pointer to the storage for the driver runtime state.
413  * @param start The start address of the desired flash memory to be verified.
414  *        The start address does not need to be sector-aligned but must be word-aligned.
415  * @param lengthInBytes The length, given in bytes (not words or long-words),
416  *        to be verified. Must be word-aligned.
417  *
418  */
IFR_VerifyErasePage(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)419 static inline status_t IFR_VerifyErasePage(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
420 {
421     return FLASH_API->ifr_verify_erase_page(config, start, lengthInBytes);
422 }
423 
424 /*!
425  * @brief Verify that the IFR0 sectors are erased
426  *
427  * This function checks the appropriate number of flash sectors based on
428  * the desired start address and length to check whether the flash is erased
429  *
430  * @param config A pointer to the storage for the driver runtime state.
431  * @param start The start address of the desired flash memory to be verified.
432  *        The start address does not need to be sector-aligned but must be word-aligned.
433  * @param lengthInBytes The length, given in bytes (not words or long-words),
434  *        to be verified. Must be word-aligned.
435  *
436  */
IFR_VerifyEraseSector(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)437 static inline status_t IFR_VerifyEraseSector(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
438 {
439     return FLASH_API->ifr_verify_erase_sector(config, start, lengthInBytes);
440 }
441 
442 /*!
443  * @brief Reads flash at locations passed in through parameters
444  *
445  * This function read the flash memory from a given flash area as determined
446  * by the start address and the length.
447  *
448  * @param config A pointer to the storage for the driver runtime state.
449  * @param start The start address of the desired flash memory to be read.
450  * @param dest A pointer to the dest buffer of data that is to be read
451  *            from the flash.
452  * @param lengthInBytes The length, given in bytes (not words or long-words),
453  *                      to be read.
454  *
455  */
FLASH_Read(flash_config_t * config,uint32_t start,uint8_t * dest,uint32_t lengthInBytes)456 static inline status_t FLASH_Read(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes)
457 {
458     return FLASH_API->flash_read(config, start, dest, lengthInBytes);
459 }
460 
461 /*!
462  * @brief Get ROM API version.
463  *
464  * This function read the ROM API version.
465  *
466  */
ROMAPI_GetVersion(void)467 static inline uint32_t ROMAPI_GetVersion(void)
468 {
469     return FLASH_API->version;
470 }
471 
472 /*!
473  * @brief Run the Bootloader API  to force into the ISP mode base on the user arg
474  *
475  * @param arg Indicates API prototype fields definition.
476  *          Refer to the above #user_app_boot_invoke_option_t structure
477  */
ROMAPI_RunBootloader(void * arg)478 static inline void ROMAPI_RunBootloader(void *arg)
479 {
480     ROM_API->run_bootloader(arg);
481 }
482 
483 /*!
484  * @brief Get the UUID
485  *
486  * @param uuid UUID data array
487  *
488  */
ROMAPI_GetUUID(uint8_t * uuid)489 static inline void ROMAPI_GetUUID(uint8_t *uuid)
490 {
491 #define MCXA_UUID_ADDR (0x01100800U)
492 #define MCXA_UUID_SIZE (16U)
493 
494     uint8_t *p = (uint8_t *)MCXA_UUID_ADDR;
495     for (uint8_t i = 0; i < MCXA_UUID_SIZE; i++)
496     {
497         *uuid = *p;
498         uuid++;
499         p++;
500     }
501 }
502 
503 /* @} */
504 
505 /*! @} */
506 
507 #endif /* _FSL_RESET_H_ */
508