mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-19 02:54:24 +00:00
Extend FIP io driver to support multiple FIP devices
Platform can define MAX_NUM_FIP_DEVICES in platform_def.h to define the number of FIP io devices. The FIP driver doesn't support muliple open file. So only one single file can be open at a time across multiple FIP devices. For any FIP device, an image should be loaded fully before moving on to the next image. Signed-off-by: Ruchika Gupta <ruchika.gupta@nxp.com>
This commit is contained in:
parent
f790cc0a9c
commit
d4d598e92f
1 changed files with 114 additions and 10 deletions
|
@ -19,6 +19,10 @@
|
|||
#include <utils.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#ifndef MAX_FIP_DEVICES
|
||||
#define MAX_FIP_DEVICES 1
|
||||
#endif
|
||||
|
||||
/* Useful for printing UUIDs when debugging.*/
|
||||
#define PRINT_UUID2(x) \
|
||||
"%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", \
|
||||
|
@ -32,11 +36,33 @@ typedef struct {
|
|||
fip_toc_entry_t entry;
|
||||
} file_state_t;
|
||||
|
||||
/*
|
||||
* Maintain dev_spec per FIP Device
|
||||
* TODO - Add backend handles and file state
|
||||
* per FIP device here once backends like io_memmap
|
||||
* can support multiple open files
|
||||
*/
|
||||
typedef struct {
|
||||
uintptr_t dev_spec;
|
||||
} fip_dev_state_t;
|
||||
|
||||
static const uuid_t uuid_null = { {0} };
|
||||
/*
|
||||
* Only one file can be open across all FIP device
|
||||
* as backends like io_memmap don't support
|
||||
* multiple open files. The file state and
|
||||
* backend handle should be maintained per FIP device
|
||||
* if the same support is available in the backend
|
||||
*/
|
||||
static file_state_t current_file = {0};
|
||||
static uintptr_t backend_dev_handle;
|
||||
static uintptr_t backend_image_spec;
|
||||
|
||||
static fip_dev_state_t state_pool[MAX_FIP_DEVICES];
|
||||
static io_dev_info_t dev_info_pool[MAX_FIP_DEVICES];
|
||||
|
||||
/* Track number of allocated fip devices */
|
||||
static unsigned int fip_dev_count;
|
||||
|
||||
/* Firmware Image Package driver functions */
|
||||
static int fip_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
|
||||
|
@ -92,20 +118,94 @@ static const io_dev_funcs_t fip_dev_funcs = {
|
|||
.dev_close = fip_dev_close,
|
||||
};
|
||||
|
||||
/* Locate a file state in the pool, specified by address */
|
||||
static int find_first_fip_state(const uintptr_t dev_spec,
|
||||
unsigned int *index_out)
|
||||
{
|
||||
int result = -ENOENT;
|
||||
unsigned int index;
|
||||
|
||||
/* No state associated with this device so structure can be const */
|
||||
static const io_dev_info_t fip_dev_info = {
|
||||
.funcs = &fip_dev_funcs,
|
||||
.info = (uintptr_t)NULL
|
||||
};
|
||||
for (index = 0; index < (unsigned int)MAX_FIP_DEVICES; ++index) {
|
||||
/* dev_spec is used as identifier since it's unique */
|
||||
if (state_pool[index].dev_spec == dev_spec) {
|
||||
result = 0;
|
||||
*index_out = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Open a connection to the FIP device */
|
||||
static int fip_dev_open(const uintptr_t dev_spec __unused,
|
||||
/* Allocate a device info from the pool and return a pointer to it */
|
||||
static int allocate_dev_info(io_dev_info_t **dev_info)
|
||||
{
|
||||
int result = -ENOMEM;
|
||||
|
||||
assert(dev_info != NULL);
|
||||
|
||||
if (fip_dev_count < (unsigned int)MAX_FIP_DEVICES) {
|
||||
unsigned int index = 0;
|
||||
|
||||
result = find_first_fip_state(0, &index);
|
||||
assert(result == 0);
|
||||
/* initialize dev_info */
|
||||
dev_info_pool[index].funcs = &fip_dev_funcs;
|
||||
dev_info_pool[index].info =
|
||||
(uintptr_t)&state_pool[index];
|
||||
*dev_info = &dev_info_pool[index];
|
||||
++fip_dev_count;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Release a device info to the pool */
|
||||
static int free_dev_info(io_dev_info_t *dev_info)
|
||||
{
|
||||
int result;
|
||||
unsigned int index = 0;
|
||||
fip_dev_state_t *state;
|
||||
|
||||
assert(dev_info != NULL);
|
||||
|
||||
state = (fip_dev_state_t *)dev_info->info;
|
||||
result = find_first_fip_state(state->dev_spec, &index);
|
||||
if (result == 0) {
|
||||
/* free if device info is valid */
|
||||
zeromem(state, sizeof(fip_dev_state_t));
|
||||
--fip_dev_count;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiple FIP devices can be opened depending on the value of
|
||||
* MAX_FIP_DEVICES. Given that there is only one backend, only a
|
||||
* single file can be open at a time by any FIP device.
|
||||
*/
|
||||
static int fip_dev_open(const uintptr_t dev_spec,
|
||||
io_dev_info_t **dev_info)
|
||||
{
|
||||
int result;
|
||||
io_dev_info_t *info;
|
||||
fip_dev_state_t *state;
|
||||
|
||||
assert(dev_info != NULL);
|
||||
*dev_info = (io_dev_info_t *)&fip_dev_info; /* cast away const */
|
||||
#if MAX_FIP_DEVICES > 1
|
||||
assert(dev_spec != (uintptr_t)NULL);
|
||||
#endif
|
||||
|
||||
result = allocate_dev_info(&info);
|
||||
if (result != 0)
|
||||
return -ENOMEM;
|
||||
|
||||
state = (fip_dev_state_t *)info->info;
|
||||
|
||||
state->dev_spec = dev_spec;
|
||||
|
||||
*dev_info = info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -165,7 +265,7 @@ static int fip_dev_close(io_dev_info_t *dev_info)
|
|||
backend_dev_handle = (uintptr_t)NULL;
|
||||
backend_image_spec = (uintptr_t)NULL;
|
||||
|
||||
return 0;
|
||||
return free_dev_info(dev_info);
|
||||
}
|
||||
|
||||
|
||||
|
@ -341,7 +441,11 @@ int register_io_dev_fip(const io_dev_connector_t **dev_con)
|
|||
int result;
|
||||
assert(dev_con != NULL);
|
||||
|
||||
result = io_register_device(&fip_dev_info);
|
||||
/*
|
||||
* Since dev_info isn't really used in io_register_device, always
|
||||
* use the same device info at here instead.
|
||||
*/
|
||||
result = io_register_device(&dev_info_pool[0]);
|
||||
if (result == 0)
|
||||
*dev_con = &fip_dev_connector;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue