diff options
Diffstat (limited to 'plat/arm/common/arm_fconf_io_storage.c')
-rw-r--r-- | plat/arm/common/arm_fconf_io_storage.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c new file mode 100644 index 0000000000..341622a0bb --- /dev/null +++ b/plat/arm/common/arm_fconf_io_storage.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2015-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/debug.h> +#include <drivers/io/io_driver.h> +#include <drivers/io/io_fip.h> +#include <drivers/io/io_memmap.h> +#include <drivers/io/io_storage.h> +#include <lib/utils.h> +#include <tools_share/firmware_image_package.h> + +#include <plat/arm/common/arm_fconf_getter.h> +#include <plat/arm/common/arm_fconf_io_storage.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +/* IO devices */ +static const io_dev_connector_t *fip_dev_con; +uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +uintptr_t memmap_dev_handle; + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak plat_arm_io_setup +#pragma weak plat_arm_get_alt_image_source + +int open_fip(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + if (result == 0) { + result = io_open(fip_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using FIP\n"); + io_close(local_image_handle); + } + } + return result; +} + +int open_memmap(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using Memmap\n"); + io_close(local_image_handle); + } + } + return result; +} + +int arm_io_setup(void) +{ + int io_result; + + io_result = register_io_dev_fip(&fip_dev_con); + if (io_result < 0) { + return io_result; + } + + io_result = register_io_dev_memmap(&memmap_dev_con); + if (io_result < 0) { + return io_result; + } + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + if (io_result < 0) { + return io_result; + } + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + + return io_result; +} + +void plat_arm_io_setup(void) +{ + int err; + + err = arm_io_setup(); + if (err < 0) { + panic(); + } +} + +int plat_arm_get_alt_image_source( + unsigned int image_id __unused, + uintptr_t *dev_handle __unused, + uintptr_t *image_spec __unused) +{ + /* By default do not try an alternative */ + return -ENOENT; +} + +/* Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy */ +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result; + const struct plat_io_policy *policy; + + assert(image_id < MAX_NUMBER_IDS); + + policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); + result = policy->check(policy->image_spec); + if (result == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } else { + VERBOSE("Trying alternative IO\n"); + result = plat_arm_get_alt_image_source(image_id, dev_handle, + image_spec); + } + + return result; +} + +/* + * See if a Firmware Image Package is available, + * by checking if TOC is valid or not. + */ +bool arm_io_is_toc_valid(void) +{ + return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); +} |