1 /*
2 * Copyright (c) 2019-2022 Arm Limited. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <string.h>
18 #include <stdint.h>
19 #include "Driver_Flash.h"
20 #include "platform_base_address.h"
21 #include "RTE_Device.h"
22 #include "flash_layout.h"
23 #include "cmsis_driver_config.h"
24
25 #ifndef ARG_UNUSED
26 #define ARG_UNUSED(arg) ((void)arg)
27 #endif
28
29 #define FLASH0_SIZE 0x00200000 /* 2 MB */
30 #define FLASH0_SECTOR_SIZE 0x00001000 /* 4 kB */
31 #define FLASH0_PAGE_SIZE 0x00001000 /* 4 kB */
32 #define FLASH0_PROGRAM_UNIT 0x1 /* Minimum write size */
33
34 /* Driver version */
35 #define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 1)
36 #define ARM_FLASH_DRV_ERASE_VALUE 0xFF
37
38 /*
39 * ARM FLASH device structure
40 */
41 struct arm_flash_dev_t {
42 const uint32_t memory_base; /*!< FLASH memory base address */
43 ARM_FLASH_INFO *data; /*!< FLASH data */
44 };
45
46 /* Flash Status */
47 static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
48
49 /* Driver Version */
50 static const ARM_DRIVER_VERSION DriverVersion = {
51 ARM_FLASH_API_VERSION,
52 ARM_FLASH_DRV_VERSION
53 };
54
55 /**
56 * Data width values for ARM_FLASH_CAPABILITIES::data_width
57 * \ref ARM_FLASH_CAPABILITIES
58 */
59 enum {
60 DATA_WIDTH_8BIT = 0u,
61 DATA_WIDTH_16BIT,
62 DATA_WIDTH_32BIT,
63 DATA_WIDTH_ENUM_SIZE
64 };
65
66 static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = {
67 sizeof(uint8_t),
68 sizeof(uint16_t),
69 sizeof(uint32_t),
70 };
71
72 /* Driver Capabilities */
73 static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
74 0, /* event_ready */
75 0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
76 1 /* erase_chip */
77 };
78
is_range_valid(struct arm_flash_dev_t * flash_dev,uint32_t offset)79 static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev,
80 uint32_t offset)
81 {
82 uint32_t flash_limit = 0;
83 int32_t rc = 0;
84
85 flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size)
86 - 1;
87
88 if (offset > flash_limit) {
89 rc = -1;
90 }
91 return rc;
92 }
93
is_write_aligned(struct arm_flash_dev_t * flash_dev,uint32_t param)94 static int32_t is_write_aligned(struct arm_flash_dev_t *flash_dev,
95 uint32_t param)
96 {
97 int32_t rc = 0;
98
99 if ((param % flash_dev->data->program_unit) != 0) {
100 rc = -1;
101 }
102 return rc;
103 }
104
is_sector_aligned(struct arm_flash_dev_t * flash_dev,uint32_t offset)105 static int32_t is_sector_aligned(struct arm_flash_dev_t *flash_dev,
106 uint32_t offset)
107 {
108 int32_t rc = 0;
109
110 if ((offset % flash_dev->data->sector_size) != 0) {
111 rc = -1;
112 }
113 return rc;
114 }
115
is_flash_ready_to_write(const uint8_t * start_addr,uint32_t cnt)116 static int32_t is_flash_ready_to_write(const uint8_t *start_addr, uint32_t cnt)
117 {
118 int32_t rc = 0;
119 uint32_t i;
120
121 for (i = 0; i < cnt; i++) {
122 if(start_addr[i] != ARM_FLASH_DRV_ERASE_VALUE) {
123 rc = -1;
124 break;
125 }
126 }
127
128 return rc;
129 }
130
131 #if (RTE_FLASH0)
132 static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
133 .sector_info = NULL, /* Uniform sector layout */
134 .sector_count = FLASH0_SIZE / FLASH0_SECTOR_SIZE,
135 .sector_size = FLASH0_SECTOR_SIZE,
136 .page_size = FLASH0_PAGE_SIZE,
137 .program_unit = FLASH0_PROGRAM_UNIT,
138 .erased_value = ARM_FLASH_DRV_ERASE_VALUE};
139
140 static struct arm_flash_dev_t ARM_FLASH0_DEV = {
141 #if (__DOMAIN_NS == 1)
142 .memory_base = MUSCA_S1_MRAM_NS_BASE,
143 #else
144 .memory_base = MUSCA_S1_MRAM_S_BASE,
145 #endif /* __DOMAIN_NS == 1 */
146 .data = &(ARM_FLASH0_DEV_DATA)};
147
148 struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV;
149
150 /*
151 * Functions
152 */
153
ARM_Flash_GetVersion(void)154 static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
155 {
156 return DriverVersion;
157 }
158
ARM_Flash_GetCapabilities(void)159 static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
160 {
161 return DriverCapabilities;
162 }
163
ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)164 static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
165 {
166 ARG_UNUSED(cb_event);
167
168 if (DriverCapabilities.data_width >= DATA_WIDTH_ENUM_SIZE) {
169 return ARM_DRIVER_ERROR;
170 }
171
172 /* Nothing to be done */
173 return ARM_DRIVER_OK;
174 }
175
ARM_Flash_Uninitialize(void)176 static int32_t ARM_Flash_Uninitialize(void)
177 {
178 /* Nothing to be done */
179 return ARM_DRIVER_OK;
180 }
181
ARM_Flash_PowerControl(ARM_POWER_STATE state)182 static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
183 {
184 switch (state) {
185 case ARM_POWER_FULL:
186 /* Nothing to be done */
187 return ARM_DRIVER_OK;
188 break;
189
190 case ARM_POWER_OFF:
191 case ARM_POWER_LOW:
192 default:
193 return ARM_DRIVER_ERROR_UNSUPPORTED;
194 }
195 }
196
ARM_Flash_ReadData(uint32_t addr,void * data,uint32_t cnt)197 static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
198 {
199 uint32_t start_addr = FLASH0_DEV->memory_base + addr;
200 int32_t rc = 0;
201
202 /* Conversion between data items and bytes */
203 cnt *= data_width_byte[DriverCapabilities.data_width];
204
205 /* Check flash memory boundaries */
206 rc = is_range_valid(FLASH0_DEV, addr + cnt);
207 if (rc != 0) {
208 return ARM_DRIVER_ERROR_PARAMETER;
209 }
210
211 /* Flash interface just emulated over MRAM, use memcpy */
212 memcpy(data, (void *)start_addr, cnt);
213 cnt /= data_width_byte[DriverCapabilities.data_width];
214 return cnt;
215 }
216
ARM_Flash_ProgramData(uint32_t addr,const void * data,uint32_t cnt)217 static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data,
218 uint32_t cnt)
219 {
220 uint32_t start_addr = FLASH0_DEV->memory_base + addr;
221 int32_t rc;
222 bool cache_is_used = false;
223 bool mram_fast_read_is_used = false;
224
225 /* Conversion between data items and bytes */
226 cnt *= data_width_byte[DriverCapabilities.data_width];
227
228 /* Check flash memory boundaries and alignment with minimal write size */
229 rc = is_range_valid(FLASH0_DEV, addr + cnt);
230 rc |= is_write_aligned(FLASH0_DEV, addr);
231 rc |= is_write_aligned(FLASH0_DEV, cnt);
232 if (rc != 0) {
233 return ARM_DRIVER_ERROR_PARAMETER;
234 }
235
236 /* Check if the flash area to write the data was erased previously */
237 rc = is_flash_ready_to_write((const uint8_t*)start_addr, cnt);
238 if (rc != 0) {
239 return ARM_DRIVER_ERROR;
240 }
241
242 /* Disable cache and invalidate before changing MRAM content */
243 if (arm_cache_is_enabled(&SSE_200_CACHE_DEV)) {
244 cache_is_used = true;
245 arm_cache_disable_blocking(&SSE_200_CACHE_DEV);
246 arm_cache_full_invalidate_blocking(&SSE_200_CACHE_DEV);
247 }
248
249 /* Disable mram fast read mode to avoid faults */
250 if (musca_s1_scc_mram_is_fast_read_enabled(&MUSCA_S1_SCC_DEV)) {
251 mram_fast_read_is_used = true;
252 musca_s1_scc_mram_fast_read_disable(&MUSCA_S1_SCC_DEV);
253 }
254
255 /* Flash interface just emulated over MRAM, use memcpy */
256 memcpy((void *)start_addr, data, cnt);
257
258 if (mram_fast_read_is_used) {
259 musca_s1_scc_mram_fast_read_enable(&MUSCA_S1_SCC_DEV);
260 }
261
262 if (cache_is_used) {
263 arm_cache_enable_blocking(&SSE_200_CACHE_DEV);
264 }
265
266 cnt /= data_width_byte[DriverCapabilities.data_width];
267 return cnt;
268 }
269
ARM_Flash_EraseSector(uint32_t addr)270 static int32_t ARM_Flash_EraseSector(uint32_t addr)
271 {
272 uint32_t start_addr = FLASH0_DEV->memory_base + addr;
273 uint32_t rc;
274 bool cache_is_used = false;
275 bool mram_fast_read_is_used = false;
276
277 rc = is_range_valid(FLASH0_DEV, addr);
278 rc |= is_sector_aligned(FLASH0_DEV, addr);
279 if (rc != 0) {
280 return ARM_DRIVER_ERROR_PARAMETER;
281 }
282
283 /* Disable cache and invalidate before changing MRAM content */
284 if (arm_cache_is_enabled(&SSE_200_CACHE_DEV)) {
285 cache_is_used = true;
286 arm_cache_disable_blocking(&SSE_200_CACHE_DEV);
287 arm_cache_full_invalidate_blocking(&SSE_200_CACHE_DEV);
288 }
289
290 /* Disable mram fast read mode to avoid faults */
291 if (musca_s1_scc_mram_is_fast_read_enabled(&MUSCA_S1_SCC_DEV)) {
292 mram_fast_read_is_used = true;
293 musca_s1_scc_mram_fast_read_disable(&MUSCA_S1_SCC_DEV);
294 }
295
296 /* Flash interface just emulated over MRAM, use memset */
297 memset((void *)start_addr,
298 FLASH0_DEV->data->erased_value,
299 FLASH0_DEV->data->sector_size);
300
301 if (mram_fast_read_is_used) {
302 musca_s1_scc_mram_fast_read_enable(&MUSCA_S1_SCC_DEV);
303 }
304
305 if (cache_is_used) {
306 arm_cache_enable_blocking(&SSE_200_CACHE_DEV);
307 }
308
309 return ARM_DRIVER_OK;
310 }
311
ARM_Flash_EraseChip(void)312 static int32_t ARM_Flash_EraseChip(void)
313 {
314 uint32_t i;
315 uint32_t addr = FLASH0_DEV->memory_base;
316 int32_t rc = ARM_DRIVER_ERROR_UNSUPPORTED;
317 bool cache_is_used = false;
318 bool mram_fast_read_is_used = false;
319
320 /* Disable cache and invalidate before changing MRAM content */
321 if (arm_cache_is_enabled(&SSE_200_CACHE_DEV)) {
322 cache_is_used = true;
323 arm_cache_disable_blocking(&SSE_200_CACHE_DEV);
324 arm_cache_full_invalidate_blocking(&SSE_200_CACHE_DEV);
325 }
326 /* Disable mram fast read mode to avoid faults */
327 if (musca_s1_scc_mram_is_fast_read_enabled(&MUSCA_S1_SCC_DEV)) {
328 mram_fast_read_is_used = true;
329 musca_s1_scc_mram_fast_read_disable(&MUSCA_S1_SCC_DEV);
330 }
331
332 /* Check driver capability erase_chip bit */
333 if (DriverCapabilities.erase_chip == 1) {
334 for (i = 0; i < FLASH0_DEV->data->sector_count; i++) {
335 /* Flash interface just emulated over MRAM, use memset */
336 memset((void *)addr,
337 FLASH0_DEV->data->erased_value,
338 FLASH0_DEV->data->sector_size);
339
340 addr += FLASH0_DEV->data->sector_size;
341 rc = ARM_DRIVER_OK;
342 }
343 }
344
345 if (mram_fast_read_is_used) {
346 musca_s1_scc_mram_fast_read_enable(&MUSCA_S1_SCC_DEV);
347 }
348
349 if (cache_is_used) {
350 arm_cache_enable_blocking(&SSE_200_CACHE_DEV);
351 }
352
353 return rc;
354 }
355
ARM_Flash_GetStatus(void)356 static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
357 {
358 return FlashStatus;
359 }
360
ARM_Flash_GetInfo(void)361 static ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
362 {
363 return FLASH0_DEV->data;
364 }
365
366 ARM_DRIVER_FLASH Driver_FLASH0 = {
367 ARM_Flash_GetVersion,
368 ARM_Flash_GetCapabilities,
369 ARM_Flash_Initialize,
370 ARM_Flash_Uninitialize,
371 ARM_Flash_PowerControl,
372 ARM_Flash_ReadData,
373 ARM_Flash_ProgramData,
374 ARM_Flash_EraseSector,
375 ARM_Flash_EraseChip,
376 ARM_Flash_GetStatus,
377 ARM_Flash_GetInfo
378 };
379 #endif /* RTE_FLASH0 */
380