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