155 lines
3.5 KiB
155 lines
3.5 KiB
/*
|
|
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include <common/debug.h>
|
|
#include <drivers/io/io_driver.h>
|
|
#include <drivers/io/io_storage.h>
|
|
|
|
#include "io_common.h"
|
|
#include "io_memdrv.h"
|
|
#include "io_private.h"
|
|
#include "rcar_def.h"
|
|
|
|
extern void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len);
|
|
|
|
static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)),
|
|
io_dev_info_t **dev_info);
|
|
static int32_t memdrv_dev_close(io_dev_info_t *dev_info);
|
|
|
|
/*
|
|
* As we need to be able to keep state for seek, only one file can be open
|
|
* at a time. Make this a structure and point to the entity->info. When we
|
|
* can malloc memory we can change this to support more open files.
|
|
*/
|
|
typedef struct {
|
|
uint32_t in_use;
|
|
uintptr_t base;
|
|
signed long long file_pos;
|
|
} file_state_t;
|
|
|
|
static file_state_t current_file = { 0 };
|
|
|
|
static io_type_t device_type_memdrv(void)
|
|
{
|
|
return IO_TYPE_MEMMAP;
|
|
}
|
|
|
|
static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
|
|
io_entity_t *entity)
|
|
{
|
|
const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec;
|
|
|
|
/*
|
|
* Since we need to track open state for seek() we only allow one open
|
|
* spec at a time. When we have dynamic memory we can malloc and set
|
|
* entity->info.
|
|
*/
|
|
if (current_file.in_use != 0U) {
|
|
return IO_RESOURCES_EXHAUSTED;
|
|
}
|
|
|
|
/* File cursor offset for seek and incremental reads etc. */
|
|
current_file.base = block_spec->offset;
|
|
current_file.file_pos = 0;
|
|
current_file.in_use = 1;
|
|
|
|
entity->info = (uintptr_t) ¤t_file;
|
|
|
|
return IO_SUCCESS;
|
|
}
|
|
|
|
static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode,
|
|
signed long long offset)
|
|
{
|
|
if (mode != IO_SEEK_SET) {
|
|
return IO_FAIL;
|
|
}
|
|
|
|
((file_state_t *) entity->info)->file_pos = offset;
|
|
|
|
return IO_SUCCESS;
|
|
}
|
|
|
|
static int32_t memdrv_block_read(io_entity_t *entity, uintptr_t buffer,
|
|
size_t length, size_t *cnt)
|
|
{
|
|
file_state_t *fp;
|
|
|
|
fp = (file_state_t *) entity->info;
|
|
|
|
NOTICE("BL2: dst=0x%lx src=0x%llx len=%ld(0x%lx)\n",
|
|
buffer, (unsigned long long)fp->base +
|
|
(unsigned long long)fp->file_pos, length, length);
|
|
|
|
if (FLASH_MEMORY_SIZE < (fp->file_pos + (signed long long)length)) {
|
|
ERROR("BL2: check load image (source address)\n");
|
|
return IO_FAIL;
|
|
}
|
|
|
|
rcar_dma_exec(buffer, fp->base + (uintptr_t)fp->file_pos, length);
|
|
fp->file_pos += (signed long long)length;
|
|
*cnt = length;
|
|
|
|
return IO_SUCCESS;
|
|
}
|
|
|
|
static int32_t memdrv_block_close(io_entity_t *entity)
|
|
{
|
|
entity->info = 0U;
|
|
|
|
memset((void *)¤t_file, 0, sizeof(current_file));
|
|
|
|
return IO_SUCCESS;
|
|
}
|
|
|
|
static const io_dev_funcs_t memdrv_dev_funcs = {
|
|
.type = &device_type_memdrv,
|
|
.open = &memdrv_block_open,
|
|
.seek = &memdrv_block_seek,
|
|
.size = NULL,
|
|
.read = &memdrv_block_read,
|
|
.write = NULL,
|
|
.close = &memdrv_block_close,
|
|
.dev_init = NULL,
|
|
.dev_close = &memdrv_dev_close,
|
|
};
|
|
|
|
static const io_dev_info_t memdrv_dev_info = {
|
|
.funcs = &memdrv_dev_funcs,
|
|
.info = 0,
|
|
};
|
|
|
|
static const io_dev_connector_t memdrv_dev_connector = {
|
|
.dev_open = &memdrv_dev_open
|
|
};
|
|
|
|
static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)),
|
|
io_dev_info_t **dev_info)
|
|
{
|
|
*dev_info = (io_dev_info_t *) &memdrv_dev_info;
|
|
|
|
return IO_SUCCESS;
|
|
}
|
|
|
|
static int32_t memdrv_dev_close(io_dev_info_t *dev_info)
|
|
{
|
|
return IO_SUCCESS;
|
|
}
|
|
|
|
int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **dev_con)
|
|
{
|
|
int32_t result;
|
|
|
|
result = io_register_device(&memdrv_dev_info);
|
|
if (result == IO_SUCCESS) {
|
|
*dev_con = &memdrv_dev_connector;
|
|
}
|
|
|
|
return result;
|
|
}
|