diff options
author | Tamas Ban <tamas.ban@arm.com> | 2018-02-01 09:11:26 +0000 |
---|---|---|
committer | Marc Moreno Berengue <marc.morenoberengue@arm.com> | 2018-05-17 10:22:37 +0100 |
commit | d3d2da40ff2b08e33cb190a2928b7717d24127d0 (patch) | |
tree | d0584587628f2ff520a616ce2d401faeb9c345a6 /platform | |
parent | a5668552f562091dc2e49b17bd43fee25c234ba0 (diff) | |
download | trusted-firmware-m-d3d2da40ff2b08e33cb190a2928b7717d24127d0.tar.gz |
Platform: implement CMSIS flash driver on MPS2
CMSIS compliant flash driver on MPS2:
-- There is no flash memory on MPS2. Code runs from SRAM.
-- Implement a CMSIS compliant flash driver which
emulates flash interface and behaviour over code SRAM.
-- Supported platforms: AN521 and AN519
Imported files from CMSIS_5:
-- platform/ext/driver/Driver_Flash.h; tag:5.2.0
Change-Id: I7903bf78abcc736c32732750ccc12ae8592805e4
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
Diffstat (limited to 'platform')
-rw-r--r-- | platform/ext/driver/Driver_Flash.h | 204 | ||||
-rw-r--r-- | platform/ext/target/mps2/an519/RTE_Device.h | 5 | ||||
-rw-r--r-- | platform/ext/target/mps2/an519/cmsis_drivers/Driver_Flash.c | 254 | ||||
-rw-r--r-- | platform/ext/target/mps2/an519/retarget/platform_retarget.h | 8 | ||||
-rw-r--r-- | platform/ext/target/mps2/an521/RTE_Device.h | 5 | ||||
-rw-r--r-- | platform/ext/target/mps2/an521/cmsis_drivers/Driver_Flash.c | 254 | ||||
-rw-r--r-- | platform/ext/target/mps2/an521/retarget/platform_retarget.h | 8 |
7 files changed, 738 insertions, 0 deletions
diff --git a/platform/ext/driver/Driver_Flash.h b/platform/ext/driver/Driver_Flash.h new file mode 100644 index 0000000000..287add1398 --- /dev/null +++ b/platform/ext/driver/Driver_Flash.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Date: 2. Feb 2017 + * $Revision: V2.1 + * + * Project: Flash Driver definitions + */ + +/* History: + * Version 2.1 + * ARM_FLASH_STATUS made volatile + * Version 2.0 + * Renamed driver NOR -> Flash (more generic) + * Non-blocking operation + * Added Events, Status and Capabilities + * Linked Flash information (GetInfo) + * Version 1.11 + * Changed prefix ARM_DRV -> ARM_DRIVER + * Version 1.10 + * Namespace prefix ARM_ added + * Version 1.00 + * Initial release + */ + +#ifndef DRIVER_FLASH_H_ +#define DRIVER_FLASH_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "Driver_Common.h" + +#define ARM_FLASH_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,1) /* API version */ + + +#define _ARM_Driver_Flash_(n) Driver_Flash##n +#define ARM_Driver_Flash_(n) _ARM_Driver_Flash_(n) + + +#define ARM_FLASH_SECTOR_INFO(addr,size) { (addr), (addr)+(size)-1 } + +/** +\brief Flash Sector information +*/ +typedef struct _ARM_FLASH_SECTOR { + uint32_t start; ///< Sector Start address + uint32_t end; ///< Sector End address (start+size-1) +} const ARM_FLASH_SECTOR; + +/** +\brief Flash information +*/ +typedef struct _ARM_FLASH_INFO { + ARM_FLASH_SECTOR *sector_info; ///< Sector layout information (NULL=Uniform sectors) + uint32_t sector_count; ///< Number of sectors + uint32_t sector_size; ///< Uniform sector size in bytes (0=sector_info used) + uint32_t page_size; ///< Optimal programming page size in bytes + uint32_t program_unit; ///< Smallest programmable unit in bytes + uint8_t erased_value; ///< Contents of erased memory (usually 0xFF) +} const ARM_FLASH_INFO; + + +/** +\brief Flash Status +*/ +typedef volatile struct _ARM_FLASH_STATUS { + uint32_t busy : 1; ///< Flash busy flag + uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation) + uint32_t reserved : 30; +} ARM_FLASH_STATUS; + + +/****** Flash Event *****/ +#define ARM_FLASH_EVENT_READY (1UL << 0) ///< Flash Ready +#define ARM_FLASH_EVENT_ERROR (1UL << 1) ///< Read/Program/Erase Error + + +// Function documentation +/** + \fn ARM_DRIVER_VERSION ARM_Flash_GetVersion (void) + \brief Get driver version. + \return \ref ARM_DRIVER_VERSION +*/ +/** + \fn ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities (void) + \brief Get driver capabilities. + \return \ref ARM_FLASH_CAPABILITIES +*/ +/** + \fn int32_t ARM_Flash_Initialize (ARM_Flash_SignalEvent_t cb_event) + \brief Initialize the Flash Interface. + \param[in] cb_event Pointer to \ref ARM_Flash_SignalEvent + \return \ref execution_status +*/ +/** + \fn int32_t ARM_Flash_Uninitialize (void) + \brief De-initialize the Flash Interface. + \return \ref execution_status +*/ +/** + \fn int32_t ARM_Flash_PowerControl (ARM_POWER_STATE state) + \brief Control the Flash interface power. + \param[in] state Power state + \return \ref execution_status +*/ +/** + \fn int32_t ARM_Flash_ReadData (uint32_t addr, void *data, uint32_t cnt) + \brief Read data from Flash. + \param[in] addr Data address. + \param[out] data Pointer to a buffer storing the data read from Flash. + \param[in] cnt Number of data items to read. + \return number of data items read or \ref execution_status +*/ +/** + \fn int32_t ARM_Flash_ProgramData (uint32_t addr, const void *data, uint32_t cnt) + \brief Program data to Flash. + \param[in] addr Data address. + \param[in] data Pointer to a buffer containing the data to be programmed to Flash. + \param[in] cnt Number of data items to program. + \return number of data items programmed or \ref execution_status +*/ +/** + \fn int32_t ARM_Flash_EraseSector (uint32_t addr) + \brief Erase Flash Sector. + \param[in] addr Sector address + \return \ref execution_status +*/ +/** + \fn int32_t ARM_Flash_EraseChip (void) + \brief Erase complete Flash. + Optional function for faster full chip erase. + \return \ref execution_status +*/ +/** + \fn ARM_FLASH_STATUS ARM_Flash_GetStatus (void) + \brief Get Flash status. + \return Flash status \ref ARM_FLASH_STATUS +*/ +/** + \fn ARM_FLASH_INFO * ARM_Flash_GetInfo (void) + \brief Get Flash information. + \return Pointer to Flash information \ref ARM_FLASH_INFO +*/ + +/** + \fn void ARM_Flash_SignalEvent (uint32_t event) + \brief Signal Flash event. + \param[in] event Event notification mask + \return none +*/ + +typedef void (*ARM_Flash_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_Flash_SignalEvent : Signal Flash Event. + + +/** +\brief Flash Driver Capabilities. +*/ +typedef struct _ARM_FLASH_CAPABILITIES { + uint32_t event_ready : 1; ///< Signal Flash Ready event + uint32_t data_width : 2; ///< Data width: 0=8-bit, 1=16-bit, 2=32-bit + uint32_t erase_chip : 1; ///< Supports EraseChip operation + uint32_t reserved : 28; ///< Reserved (must be zero) +} ARM_FLASH_CAPABILITIES; + + +/** +\brief Access structure of the Flash Driver +*/ +typedef struct _ARM_DRIVER_FLASH { + ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_Flash_GetVersion : Get driver version. + ARM_FLASH_CAPABILITIES (*GetCapabilities)(void); ///< Pointer to \ref ARM_Flash_GetCapabilities : Get driver capabilities. + int32_t (*Initialize) (ARM_Flash_SignalEvent_t cb_event); ///< Pointer to \ref ARM_Flash_Initialize : Initialize Flash Interface. + int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_Flash_Uninitialize : De-initialize Flash Interface. + int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_Flash_PowerControl : Control Flash Interface Power. + int32_t (*ReadData) (uint32_t addr, void *data, uint32_t cnt); ///< Pointer to \ref ARM_Flash_ReadData : Read data from Flash. + int32_t (*ProgramData) (uint32_t addr, const void *data, uint32_t cnt); ///< Pointer to \ref ARM_Flash_ProgramData : Program data to Flash. + int32_t (*EraseSector) (uint32_t addr); ///< Pointer to \ref ARM_Flash_EraseSector : Erase Flash Sector. + int32_t (*EraseChip) (void); ///< Pointer to \ref ARM_Flash_EraseChip : Erase complete Flash. + ARM_FLASH_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_Flash_GetStatus : Get Flash status. + ARM_FLASH_INFO * (*GetInfo) (void); ///< Pointer to \ref ARM_Flash_GetInfo : Get Flash information. +} const ARM_DRIVER_FLASH; + +#ifdef __cplusplus +} +#endif + +#endif /* DRIVER_FLASH_H_ */ diff --git a/platform/ext/target/mps2/an519/RTE_Device.h b/platform/ext/target/mps2/an519/RTE_Device.h index 860a49feab..3eef147e17 100644 --- a/platform/ext/target/mps2/an519/RTE_Device.h +++ b/platform/ext/target/mps2/an519/RTE_Device.h @@ -89,6 +89,11 @@ #define RTE_USART4 0 // </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART4] +// <e> FLASH (Flash Memory) [Driver_FLASH0] +// <i> Configuration settings for Driver_FLASH0 in component ::Drivers:FLASH +#define RTE_FLASH0 1 +// </e> FLASH (Flash Memory) [Driver_FLASH0] + // <e> MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] // <i> Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC #define RTE_ISRAM0_MPC 0 diff --git a/platform/ext/target/mps2/an519/cmsis_drivers/Driver_Flash.c b/platform/ext/target/mps2/an519/cmsis_drivers/Driver_Flash.c new file mode 100644 index 0000000000..fb6f448070 --- /dev/null +++ b/platform/ext/target/mps2/an519/cmsis_drivers/Driver_Flash.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2013-2018 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <stdint.h> +#include "Driver_Flash.h" +#include "platform_retarget.h" +#include "RTE_Device.h" + +#ifndef ARG_UNUSED +#define ARG_UNUSED(arg) ((void)arg) +#endif + +/* Driver version */ +#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) + +/* + * ARM FLASH device structure + * + * There is no real flash memory for code on MPS2 board. Instead a code SRAM is + * used for code storage: ZBT SSRAM1. This driver just emulates a flash + * interface and behaviour on top of the SRAM memory. + */ +struct arm_flash_dev_t { + const uint32_t memory_base; /*!< FLASH memory base address */ + ARM_FLASH_INFO *data; /*!< FLASH data */ +}; + +/* Flash Status */ +static ARM_FLASH_STATUS FlashStatus = {0, 0, 0}; + +/* Driver Version */ +static const ARM_DRIVER_VERSION DriverVersion = { + ARM_FLASH_API_VERSION, + ARM_FLASH_DRV_VERSION +}; + +/* Driver Capabilities */ +static const ARM_FLASH_CAPABILITIES DriverCapabilities = { + 0, /* event_ready */ + 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */ + 1 /* erase_chip */ +}; + +static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev, + uint32_t offset) +{ + uint32_t flash_limit = 0; + int32_t rc = 0; + + flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size) + - 1; + + if (offset > flash_limit) { + rc = -1; + } + return rc; +} + +static int32_t is_write_aligned(struct arm_flash_dev_t *flash_dev, + uint32_t param) +{ + int32_t rc = 0; + + if ((param % flash_dev->data->program_unit) != 0) { + rc = -1; + } + return rc; +} + +static int32_t is_sector_aligned(struct arm_flash_dev_t *flash_dev, + uint32_t offset) +{ + int32_t rc = 0; + + if ((offset % flash_dev->data->sector_size) != 0) { + rc = -1; + } + return rc; +} + +#if (RTE_FLASH0) +static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = { + .sector_info = NULL, /* Uniform sector layout */ + .sector_count = FLASH0_SIZE / FLASH0_SECTOR_SIZE, + .sector_size = FLASH0_SECTOR_SIZE, + .page_size = FLASH0_PAGE_SIZE, + .program_unit = FLASH0_PROGRAM_UNIT, + .erased_value = 0xFF}; + +static struct arm_flash_dev_t ARM_FLASH0_DEV = { +#if (__DOMAIN_NS == 1) + .memory_base = FLASH0_BASE_NS, +#else + .memory_base = FLASH0_BASE_S, +#endif /* __DOMAIN_NS == 1 */ + .data = &(ARM_FLASH0_DEV_DATA)}; + +struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV; + +/* + * Functions + */ + +static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void) +{ + return DriverVersion; +} + +static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void) +{ + return DriverCapabilities; +} + +static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event) +{ + ARG_UNUSED(cb_event); + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state) +{ + switch (state) { + case ARM_POWER_FULL: + /* Nothing to be done */ + return ARM_DRIVER_OK; + break; + + case ARM_POWER_OFF: + case ARM_POWER_LOW: + default: + return ARM_DRIVER_ERROR_UNSUPPORTED; + } +} + +static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + int32_t rc = 0; + + /* Check flash memory boundaries */ + rc = is_range_valid(FLASH0_DEV, addr + cnt); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Flash interface just emulated over SRAM, use memcpy */ + memcpy(data, (void *)start_addr, cnt); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, uint32_t cnt) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + int32_t rc = 0; + + /* Check flash memory boundaries and alignment with minimal write size */ + rc = is_range_valid(FLASH0_DEV, addr + cnt); + rc |= is_write_aligned(FLASH0_DEV, addr); + rc |= is_write_aligned(FLASH0_DEV, cnt); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Flash interface just emulated over SRAM, use memcpy */ + memcpy((void *)start_addr, data, cnt); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_EraseSector(uint32_t addr) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + uint32_t rc = 0; + + rc = is_range_valid(FLASH0_DEV, addr); + rc |= is_sector_aligned(FLASH0_DEV, addr); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Flash interface just emulated over SRAM, use memset */ + memset((void *)start_addr, + FLASH0_DEV->data->erased_value, + FLASH0_DEV->data->sector_size); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_EraseChip(void) +{ + uint32_t i; + uint32_t addr = FLASH0_DEV->memory_base; + int32_t rc = ARM_DRIVER_ERROR_UNSUPPORTED; + + /* Check driver capability erase_chip bit */ + if (DriverCapabilities.erase_chip == 1) { + for (i = 0; i < FLASH0_DEV->data->sector_count; i++) { + /* Flash interface just emulated over SRAM, use memset */ + memset((void *)addr, + FLASH0_DEV->data->erased_value, + FLASH0_DEV->data->sector_size); + + addr += FLASH0_DEV->data->sector_size; + rc = ARM_DRIVER_OK; + } + } + return rc; +} + +static ARM_FLASH_STATUS ARM_Flash_GetStatus(void) +{ + return FlashStatus; +} + +static ARM_FLASH_INFO * ARM_Flash_GetInfo(void) +{ + return FLASH0_DEV->data; +} + +ARM_DRIVER_FLASH Driver_FLASH0 = { + ARM_Flash_GetVersion, + ARM_Flash_GetCapabilities, + ARM_Flash_Initialize, + ARM_Flash_Uninitialize, + ARM_Flash_PowerControl, + ARM_Flash_ReadData, + ARM_Flash_ProgramData, + ARM_Flash_EraseSector, + ARM_Flash_EraseChip, + ARM_Flash_GetStatus, + ARM_Flash_GetInfo +}; +#endif /* RTE_FLASH0 */ diff --git a/platform/ext/target/mps2/an519/retarget/platform_retarget.h b/platform/ext/target/mps2/an519/retarget/platform_retarget.h index 60b30016a1..aeed37663f 100644 --- a/platform/ext/target/mps2/an519/retarget/platform_retarget.h +++ b/platform/ext/target/mps2/an519/retarget/platform_retarget.h @@ -110,4 +110,12 @@ #define MPC_CODE_SRAM3_RANGE_BASE_S 0x38200000 #define MPC_CODE_SRAM3_RANGE_LIMIT_S 0x383FFFFF +/* Flash memory emulated over external SSRAM memory */ +#define FLASH0_BASE_S 0x10000000 +#define FLASH0_BASE_NS 0x00000000 +#define FLASH0_SIZE 0x00400000 /* 4 MB */ +#define FLASH0_SECTOR_SIZE 0x00001000 /* 4 kB */ +#define FLASH0_PAGE_SIZE 0x00001000 /* 4 kB */ +#define FLASH0_PROGRAM_UNIT 0x1 /* Minimum write size */ + #endif /* __ARM_LTD_AN519_RETARGET_H__ */ diff --git a/platform/ext/target/mps2/an521/RTE_Device.h b/platform/ext/target/mps2/an521/RTE_Device.h index 860a49feab..3eef147e17 100644 --- a/platform/ext/target/mps2/an521/RTE_Device.h +++ b/platform/ext/target/mps2/an521/RTE_Device.h @@ -89,6 +89,11 @@ #define RTE_USART4 0 // </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART4] +// <e> FLASH (Flash Memory) [Driver_FLASH0] +// <i> Configuration settings for Driver_FLASH0 in component ::Drivers:FLASH +#define RTE_FLASH0 1 +// </e> FLASH (Flash Memory) [Driver_FLASH0] + // <e> MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] // <i> Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC #define RTE_ISRAM0_MPC 0 diff --git a/platform/ext/target/mps2/an521/cmsis_drivers/Driver_Flash.c b/platform/ext/target/mps2/an521/cmsis_drivers/Driver_Flash.c new file mode 100644 index 0000000000..fb6f448070 --- /dev/null +++ b/platform/ext/target/mps2/an521/cmsis_drivers/Driver_Flash.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2013-2018 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <stdint.h> +#include "Driver_Flash.h" +#include "platform_retarget.h" +#include "RTE_Device.h" + +#ifndef ARG_UNUSED +#define ARG_UNUSED(arg) ((void)arg) +#endif + +/* Driver version */ +#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) + +/* + * ARM FLASH device structure + * + * There is no real flash memory for code on MPS2 board. Instead a code SRAM is + * used for code storage: ZBT SSRAM1. This driver just emulates a flash + * interface and behaviour on top of the SRAM memory. + */ +struct arm_flash_dev_t { + const uint32_t memory_base; /*!< FLASH memory base address */ + ARM_FLASH_INFO *data; /*!< FLASH data */ +}; + +/* Flash Status */ +static ARM_FLASH_STATUS FlashStatus = {0, 0, 0}; + +/* Driver Version */ +static const ARM_DRIVER_VERSION DriverVersion = { + ARM_FLASH_API_VERSION, + ARM_FLASH_DRV_VERSION +}; + +/* Driver Capabilities */ +static const ARM_FLASH_CAPABILITIES DriverCapabilities = { + 0, /* event_ready */ + 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */ + 1 /* erase_chip */ +}; + +static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev, + uint32_t offset) +{ + uint32_t flash_limit = 0; + int32_t rc = 0; + + flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size) + - 1; + + if (offset > flash_limit) { + rc = -1; + } + return rc; +} + +static int32_t is_write_aligned(struct arm_flash_dev_t *flash_dev, + uint32_t param) +{ + int32_t rc = 0; + + if ((param % flash_dev->data->program_unit) != 0) { + rc = -1; + } + return rc; +} + +static int32_t is_sector_aligned(struct arm_flash_dev_t *flash_dev, + uint32_t offset) +{ + int32_t rc = 0; + + if ((offset % flash_dev->data->sector_size) != 0) { + rc = -1; + } + return rc; +} + +#if (RTE_FLASH0) +static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = { + .sector_info = NULL, /* Uniform sector layout */ + .sector_count = FLASH0_SIZE / FLASH0_SECTOR_SIZE, + .sector_size = FLASH0_SECTOR_SIZE, + .page_size = FLASH0_PAGE_SIZE, + .program_unit = FLASH0_PROGRAM_UNIT, + .erased_value = 0xFF}; + +static struct arm_flash_dev_t ARM_FLASH0_DEV = { +#if (__DOMAIN_NS == 1) + .memory_base = FLASH0_BASE_NS, +#else + .memory_base = FLASH0_BASE_S, +#endif /* __DOMAIN_NS == 1 */ + .data = &(ARM_FLASH0_DEV_DATA)}; + +struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV; + +/* + * Functions + */ + +static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void) +{ + return DriverVersion; +} + +static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void) +{ + return DriverCapabilities; +} + +static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event) +{ + ARG_UNUSED(cb_event); + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state) +{ + switch (state) { + case ARM_POWER_FULL: + /* Nothing to be done */ + return ARM_DRIVER_OK; + break; + + case ARM_POWER_OFF: + case ARM_POWER_LOW: + default: + return ARM_DRIVER_ERROR_UNSUPPORTED; + } +} + +static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + int32_t rc = 0; + + /* Check flash memory boundaries */ + rc = is_range_valid(FLASH0_DEV, addr + cnt); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Flash interface just emulated over SRAM, use memcpy */ + memcpy(data, (void *)start_addr, cnt); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, uint32_t cnt) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + int32_t rc = 0; + + /* Check flash memory boundaries and alignment with minimal write size */ + rc = is_range_valid(FLASH0_DEV, addr + cnt); + rc |= is_write_aligned(FLASH0_DEV, addr); + rc |= is_write_aligned(FLASH0_DEV, cnt); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Flash interface just emulated over SRAM, use memcpy */ + memcpy((void *)start_addr, data, cnt); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_EraseSector(uint32_t addr) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + uint32_t rc = 0; + + rc = is_range_valid(FLASH0_DEV, addr); + rc |= is_sector_aligned(FLASH0_DEV, addr); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Flash interface just emulated over SRAM, use memset */ + memset((void *)start_addr, + FLASH0_DEV->data->erased_value, + FLASH0_DEV->data->sector_size); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_EraseChip(void) +{ + uint32_t i; + uint32_t addr = FLASH0_DEV->memory_base; + int32_t rc = ARM_DRIVER_ERROR_UNSUPPORTED; + + /* Check driver capability erase_chip bit */ + if (DriverCapabilities.erase_chip == 1) { + for (i = 0; i < FLASH0_DEV->data->sector_count; i++) { + /* Flash interface just emulated over SRAM, use memset */ + memset((void *)addr, + FLASH0_DEV->data->erased_value, + FLASH0_DEV->data->sector_size); + + addr += FLASH0_DEV->data->sector_size; + rc = ARM_DRIVER_OK; + } + } + return rc; +} + +static ARM_FLASH_STATUS ARM_Flash_GetStatus(void) +{ + return FlashStatus; +} + +static ARM_FLASH_INFO * ARM_Flash_GetInfo(void) +{ + return FLASH0_DEV->data; +} + +ARM_DRIVER_FLASH Driver_FLASH0 = { + ARM_Flash_GetVersion, + ARM_Flash_GetCapabilities, + ARM_Flash_Initialize, + ARM_Flash_Uninitialize, + ARM_Flash_PowerControl, + ARM_Flash_ReadData, + ARM_Flash_ProgramData, + ARM_Flash_EraseSector, + ARM_Flash_EraseChip, + ARM_Flash_GetStatus, + ARM_Flash_GetInfo +}; +#endif /* RTE_FLASH0 */ diff --git a/platform/ext/target/mps2/an521/retarget/platform_retarget.h b/platform/ext/target/mps2/an521/retarget/platform_retarget.h index f62d50779f..9c93895fbf 100644 --- a/platform/ext/target/mps2/an521/retarget/platform_retarget.h +++ b/platform/ext/target/mps2/an521/retarget/platform_retarget.h @@ -132,4 +132,12 @@ #define MPC_CODE_SRAM3_RANGE_BASE_S 0x38200000 #define MPC_CODE_SRAM3_RANGE_LIMIT_S 0x383FFFFF +/* Flash memory emulated over external SSRAM memory */ +#define FLASH0_BASE_S 0x10000000 +#define FLASH0_BASE_NS 0x00000000 +#define FLASH0_SIZE 0x00400000 /* 4 MB */ +#define FLASH0_SECTOR_SIZE 0x00001000 /* 4 kB */ +#define FLASH0_PAGE_SIZE 0x00001000 /* 4 kB */ +#define FLASH0_PROGRAM_UNIT 0x1 /* Minimum write size */ + #endif /* __ARM_LTD_AN521_RETARGET_H__ */ |