blob: 72e7ca137ad50184025791b5208840be1e932670 [file] [log] [blame]
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stdbool.h>
#include "target.h"
#include "bl2_util.h"
#include "flash_map/flash_map.h"
#include "flash_map_backend/flash_map_backend.h"
#include "bootutil/bootutil_log.h"
#include "Driver_Flash.h"
/* Flash device name must be specified by target */
extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
static const struct flash_area flash_map[] = {
{
.fa_id = FLASH_AREA_0_ID,
.fa_device_id = FLASH_DEVICE_ID,
.fa_off = FLASH_AREA_0_OFFSET,
.fa_size = FLASH_AREA_0_SIZE,
},
{
.fa_id = FLASH_AREA_2_ID,
.fa_device_id = FLASH_DEVICE_ID,
.fa_off = FLASH_AREA_2_OFFSET,
.fa_size = FLASH_AREA_2_SIZE,
},
#if (MCUBOOT_IMAGE_NUMBER == 2)
{
.fa_id = FLASH_AREA_1_ID,
.fa_device_id = FLASH_DEVICE_ID,
.fa_off = FLASH_AREA_1_OFFSET,
.fa_size = FLASH_AREA_1_SIZE,
},
{
.fa_id = FLASH_AREA_3_ID,
.fa_device_id = FLASH_DEVICE_ID,
.fa_off = FLASH_AREA_3_OFFSET,
.fa_size = FLASH_AREA_3_SIZE,
},
#endif
{
.fa_id = FLASH_AREA_SCRATCH_ID,
.fa_device_id = FLASH_DEVICE_ID,
.fa_off = FLASH_AREA_SCRATCH_OFFSET,
.fa_size = FLASH_AREA_SCRATCH_SIZE,
},
};
static const int flash_map_entry_num = ARRAY_SIZE(flash_map);
/*
* `open` a flash area. The `area` in this case is not the individual
* sectors, but describes the particular flash area in question.
*/
int flash_area_open(uint8_t id, const struct flash_area **area)
{
int i;
BOOT_LOG_DBG("area %d", id);
for (i = 0; i < flash_map_entry_num; i++) {
if (id == flash_map[i].fa_id) {
break;
}
}
if (i == flash_map_entry_num) {
return -1;
}
*area = &flash_map[i];
return 0;
}
void flash_area_close(const struct flash_area *area)
{
/* Nothing to do. */
}
int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
uint32_t len)
{
BOOT_LOG_DBG("read area=%d, off=%#x, len=%#x", area->fa_id, off, len);
return FLASH_DEV_NAME.ReadData(area->fa_off + off, dst, len);
}
int flash_area_write(const struct flash_area *area, uint32_t off,
const void *src, uint32_t len)
{
BOOT_LOG_DBG("write area=%d, off=%#x, len=%#x", area->fa_id, off, len);
return FLASH_DEV_NAME.ProgramData(area->fa_off + off, src, len);
}
int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
{
ARM_FLASH_INFO *flash_info;
uint32_t deleted_len = 0;
int32_t rc = 0;
BOOT_LOG_DBG("erase area=%d, off=%#x, len=%#x", area->fa_id, off, len);
flash_info = FLASH_DEV_NAME.GetInfo();
if (flash_info->sector_info == NULL) {
/* Uniform sector layout */
while (deleted_len < len) {
rc = FLASH_DEV_NAME.EraseSector(area->fa_off + off);
if (rc != 0) {
break;
}
deleted_len += flash_info->sector_size;
off += flash_info->sector_size;
}
} else {
/* Inhomogeneous sector layout, explicitly defined
* Currently not supported.
*/
}
return rc;
}
uint32_t flash_area_align(const struct flash_area *area)
{
ARM_FLASH_INFO *flash_info;
flash_info = FLASH_DEV_NAME.GetInfo();
return flash_info->program_unit;
}