rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
flash_int.cpp
Go to the documentation of this file.
1/**
2 *
3 * @file flash_int.c
4 * @brief Lower-level code for Kinetis related to internal flash memory
5 * @author andreika <prometheus.pcb@gmail.com>
6 */
7
8#include "pch.h"
9
10#if EFI_STORAGE_INT_FLASH
11
12#include "flash_int.h"
13#include "fsl_ftfx_flexnvm.h"
14#include <string.h>
15
16
17//#define KINETIS_FLASH_DEBUG
18
19typedef uint32_t flashdata_t;
20
21static bool wasInit = false;
22static bool isLocked = true;
23static bool isInitializing = false;
25
26static status_t initStatus = -1;
29static uint8_t protectValue = 0;
31
32static kinetis_clock_type_e savedClockType = KINETIS_DEFAULT_CLK;
33
34#ifdef KINETIS_FLASH_DEBUG
35void flashPrintStatus(void) {
36 debugLog("* flashInit status=%d\r\n", initStatus);
37 debugLog("* FLEXNVM_DflashGetProtection status=%d prot=%d\r\n", protectStatus, protectValue);
38 debugLog("* FLEXNVM_GetSecurityState status=%d security=0x%08x\r\n", securityStatus, sstate);
39
40 uint32_t dflashBlockBase = 0;
41 uint32_t dflashTotalSize = 0;
42 uint32_t dflashSectorSize = 0;
43
44 /* Get flash properties*/
48
49 debugLog("Data Flash Base Address: (0x%x)\r\n", dflashBlockBase);
50 debugLog("Data Flash Total Size:\t%d KB, Hex: (0x%x)\r\n", (dflashTotalSize / 1024), dflashTotalSize);
51 debugLog("Data Flash Sector Size:\t%d KB, Hex: (0x%x)\r\n", (dflashSectorSize / 1024), dflashSectorSize);
52}
53#endif /* KINETIS_FLASH_DEBUG */
54
55// should be called only from flashUnlock()
56static bool flashInit(void) {
57 isInitializing = true;
58
59 memset(&flashCfg, 0, sizeof(flashCfg));
63
64 wasInit = true;
65 isInitializing = false;
66
67#ifdef KINETIS_FLASH_DEBUG
69#endif /* KINETIS_FLASH_DEBUG */
70
72}
73
74bool flashUnlock(void) {
75// chSysUnconditionalLock();
76 // this is strictly non-reentrant function!
77 if (!isLocked) {
78// chSysUnconditionalUnlock();
79 return false; // already unlocked
80 }
81 isLocked = false;
82
84 // flash commands won't work in HSRUN clock mode
85 // we set a lower frequency clock
87
88 // before any flash access function, we should have called init() first (but not from init() itself)
89 if (!isInitializing && !wasInit) {
90 flashInit();
91 }
92
93 return true;
94}
95
96bool flashLock(void) {
97 // this is strictly non-reentrant function!
98 if (isLocked) {
99 return false; // already locked
100 }
101
102 // restore clock
104
105 isLocked = true;
106// chSysUnconditionalUnlock();
107
108 return true;
109}
110
111static int alignToWord(int v) {
112 return (v + FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT - 1) & ~(FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT - 1);
113}
114
115int intFlashErase(flashaddr_t address, size_t size) {
116 if (!flashUnlock())
117 return FLASH_RETURN_NO_PERMISSION;
118
119 flashaddr_t sizeAligned = alignToWord(size);
120 status_t status = FLEXNVM_DflashErase(&flashCfg, address, sizeAligned, kFTFx_ApiEraseKey);
121
122 flashLock();
123
124#ifdef KINETIS_FLASH_DEBUG
125 debugLog("* flashErase(addr=%08x siz=%d sizeAligned=%d)=%d\r\n", address, size, sizeAligned, status);
126#endif /* KINETIS_FLASH_DEBUG */
127
128 if (status == kStatus_FTFx_Success)
130 return -(int)status;
131}
132
133int intFlashWrite(flashaddr_t address, const char* buffer, size_t size) {
134 if (!flashUnlock())
135 return FLASH_RETURN_NO_PERMISSION;
136
137 //FLEXNVM_DflashSetProtection(&flashCfg, 0xff);
138
139 flashaddr_t sizeAligned = alignToWord(size);
140 status_t status = FLEXNVM_DflashProgram(&flashCfg, address, (uint8_t *)buffer, sizeAligned);
141
142 flashLock();
143
144#ifdef KINETIS_FLASH_DEBUG
145 debugLog("* flashWrite(addr=%08x siz=%d sizeAligned=%d)=%d\r\n", address, size, sizeAligned, status);
146#endif /* KINETIS_FLASH_DEBUG */
147
148 if (status == kStatus_FTFx_Success)
150 return -(int)status;
151}
152
153bool intFlashIsErased(flashaddr_t address, size_t size) {
154 /* Check for default set bits in the flash memory
155 * For efficiency, compare flashdata_t values as much as possible,
156 * then, fallback to byte per byte comparison. */
157 while (size >= sizeof(flashdata_t)) {
158 if (*(volatile flashdata_t*) address != (flashdata_t) (-1)) // flashdata_t being unsigned, -1 is 0xFF..FF
159 return false;
160 address += sizeof(flashdata_t);
161 size -= sizeof(flashdata_t);
162 }
163 while (size > 0) {
164 if (*(char*) address != 0xFF)
165 return false;
166 ++address;
167 --size;
168 }
169
170 return TRUE;
171}
172
173bool intFlashCompare(flashaddr_t address, const char* buffer, size_t size) {
174#if 0
175 uint32_t failAddr = 0, failDat = 0;
176 status_t status = FLEXNVM_DflashVerifyProgram(&flashCfg, address, size, (const uint8_t *)buffer,
177 kFTFx_MarginValueUser, &failAddr, &failDat);
178 return (status == kStatus_FTFx_Success);
179#endif
180 /* For efficiency, compare flashdata_t values as much as possible,
181 * then, fallback to byte per byte comparison. */
182 while (size >= sizeof(flashdata_t)) {
183 if (*(volatile flashdata_t*) address != *(flashdata_t*) buffer)
184 return FALSE;
185 address += sizeof(flashdata_t);
186 buffer += sizeof(flashdata_t);
187 size -= sizeof(flashdata_t);
188 }
189 while (size > 0) {
190 if (*(volatile char*) address != *buffer)
191 return FALSE;
192 ++address;
193 ++buffer;
194 --size;
195 }
196
197 return TRUE;
198}
199
200int intFlashRead(flashaddr_t source, char* destination, size_t size) {
201 memcpy(destination, (char*) source, size);
203}
204
205#endif /* EFI_STORAGE_INT_FLASH */
void ke1xf_clock_init(kinetis_clock_type_e ct)
This function executes the configuration of clocks.
kinetis_clock_type_e ke1xf_clock_get_current_type(void)
kinetis_clock_type_e
Kinetis Clock Type.
Definition clock_config.h:9
@ kinetis_clock_int_osc_run
bool flashUnlock(void)
Definition flash_int.cpp:33
bool flashLock(void)
Definition flash_int.cpp:37
return FLASH_RETURN_SUCCESS
Definition flash_int.cpp:80
int intFlashWrite(flashaddr_t address, const char *buffer, size_t size)
Copy data from a buffer to the flash memory.
Definition flash_int.cpp:83
static int alignToWord(int v)
Definition flash_int.cpp:43
bool intFlashIsErased(flashaddr_t address, size_t size)
Check if the size bytes of flash memory starting at address are erased.
Definition flash_int.cpp:89
int intFlashRead(flashaddr_t source, char *destination, size_t size)
Copy data from the flash memory to a destination.
int size_t size
Definition flash_int.cpp:51
bool intFlashCompare(flashaddr_t address, const char *buffer, size_t size)
Check if the data in buffer are identical to the one in flash memory.
uint32_t flashdata_t
Definition flash_int.cpp:20
int intFlashErase(flashaddr_t address, size_t size)
Erase the sectors containing the span of size bytes starting at address.
uintptr_t flashaddr_t
Address in the flash memory.
Definition flash_int.h:86
uint32_t flashdata_t
Definition flash_int.h:54
@ kStatus_FTFx_Success
@ kFTFx_ApiEraseKey
enum _ftfx_security_state ftfx_security_state_t
Enumeration for the three possible FTFx security states.
@ kFTFx_MarginValueUser
status_t FLEXNVM_DflashVerifyProgram(flexnvm_config_t *config, uint32_t start, uint32_t lengthInBytes, const uint8_t *expectedData, ftfx_margin_value_t margin, uint32_t *failedAddress, uint32_t *failedData)
Verifies programming of the desired flash area at a specified margin level.
status_t FLEXNVM_GetSecurityState(flexnvm_config_t *config, ftfx_security_state_t *state)
Returns the security state via the pointer passed into the function.
status_t FLEXNVM_DflashErase(flexnvm_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key)
Erases the Dflash sectors encompassed by parameters passed into function.
status_t FLEXNVM_DflashProgram(flexnvm_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
Programs flash with data at locations passed in through parameters.
status_t FLEXNVM_Init(flexnvm_config_t *config)
Initializes the global flash properties structure members.
status_t FLEXNVM_GetProperty(flexnvm_config_t *config, flexnvm_property_tag_t whichProperty, uint32_t *value)
Returns the desired flexnvm property.
status_t FLEXNVM_DflashGetProtection(flexnvm_config_t *config, uint8_t *protectStatus)
Gets the DFlash protection status.
@ kFLEXNVM_PropertyDflashSectorSize
@ kFLEXNVM_PropertyDflashTotalSize
@ kFLEXNVM_PropertyDflashBlockBaseAddr
int32_t status_t
Type used for all status and error return values.
Definition fsl_common.h:169
static bool isLocked
Definition flash_int.cpp:22
static flexnvm_config_t flashCfg
Definition flash_int.cpp:24
static bool wasInit
Definition flash_int.cpp:21
static status_t securityStatus
Definition flash_int.cpp:28
void flashPrintStatus(void)
Definition flash_int.cpp:35
static bool isInitializing
Definition flash_int.cpp:23
static status_t protectStatus
Definition flash_int.cpp:27
static uint8_t protectValue
Definition flash_int.cpp:29
static bool flashInit(void)
Definition flash_int.cpp:56
static status_t initStatus
Definition flash_int.cpp:26
static kinetis_clock_type_e savedClockType
Definition flash_int.cpp:32
static ftfx_security_state_t sstate
Definition flash_int.cpp:30
Flexnvm driver state information.
static BigBufferHandle buffer