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