2 * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
9 #include <common/debug.h>
10 #include <drivers/io/io_driver.h>
11 #include <drivers/io/io_storage.h>
13 #include "io_common.h"
14 #include "io_private.h"
15 #include "io_memdrv.h"
18 extern void rcar_dma_exec(uintptr_t dst
, uint32_t src
, uint32_t len
);
20 static int32_t memdrv_dev_open(const uintptr_t dev
__attribute__ ((unused
)),
21 io_dev_info_t
**dev_info
);
22 static int32_t memdrv_dev_close(io_dev_info_t
*dev_info
);
24 /* As we need to be able to keep state for seek, only one file can be open
25 * at a time. Make this a structure and point to the entity->info. When we
26 * can malloc memory we can change this to support more open files.
34 static file_state_t current_file
= { 0 };
36 static io_type_t
device_type_memdrv(void)
38 return IO_TYPE_MEMMAP
;
41 static int32_t memdrv_block_open(io_dev_info_t
*dev_info
, const uintptr_t spec
,
44 const io_drv_spec_t
*block_spec
= (io_drv_spec_t
*) spec
;
46 /* Since we need to track open state for seek() we only allow one open
47 * spec at a time. When we have dynamic memory we can malloc and set
50 if (current_file
.in_use
)
51 return IO_RESOURCES_EXHAUSTED
;
53 /* File cursor offset for seek and incremental reads etc. */
54 current_file
.base
= block_spec
->offset
;
55 current_file
.file_pos
= 0;
56 current_file
.in_use
= 1;
58 entity
->info
= (uintptr_t) ¤t_file
;
63 static int32_t memdrv_block_seek(io_entity_t
*entity
, int32_t mode
,
66 if (mode
!= IO_SEEK_SET
)
69 ((file_state_t
*) entity
->info
)->file_pos
= offset
;
74 static int32_t memdrv_block_read(io_entity_t
*entity
, uintptr_t buffer
,
75 size_t length
, size_t *cnt
)
79 fp
= (file_state_t
*) entity
->info
;
81 NOTICE("BL2: dst=0x%lx src=0x%lx len=%ld(0x%lx)\n",
82 buffer
, fp
->base
+ fp
->file_pos
, length
, length
);
84 if (FLASH_MEMORY_SIZE
< fp
->file_pos
+ length
) {
85 ERROR("BL2: check load image (source address)\n");
89 rcar_dma_exec(buffer
, fp
->base
+ fp
->file_pos
, length
);
90 fp
->file_pos
+= length
;
96 static int32_t memdrv_block_close(io_entity_t
*entity
)
100 memset((void *)¤t_file
, 0, sizeof(current_file
));
105 static const io_dev_funcs_t memdrv_dev_funcs
= {
106 .type
= &device_type_memdrv
,
107 .open
= &memdrv_block_open
,
108 .seek
= &memdrv_block_seek
,
110 .read
= &memdrv_block_read
,
112 .close
= &memdrv_block_close
,
114 .dev_close
= &memdrv_dev_close
,
117 static const io_dev_info_t memdrv_dev_info
= {
118 .funcs
= &memdrv_dev_funcs
,
122 static const io_dev_connector_t memdrv_dev_connector
= {
123 .dev_open
= &memdrv_dev_open
126 static int32_t memdrv_dev_open(const uintptr_t dev
__attribute__ ((unused
)),
127 io_dev_info_t
**dev_info
)
129 *dev_info
= (io_dev_info_t
*) &memdrv_dev_info
;
134 static int32_t memdrv_dev_close(io_dev_info_t
*dev_info
)
139 int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t
**dev_con
)
143 result
= io_register_device(&memdrv_dev_info
);
144 if (result
== IO_SUCCESS
)
145 *dev_con
= &memdrv_dev_connector
;