/* 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(const char *image_name, uintptr_t *dev_handle,
			  uintptr_t *image_spec)
{
	int result = IO_FAIL;
	const struct plat_io_policy *policy;

	if ((image_name != NULL) && (dev_handle != NULL) &&
	    (image_spec != NULL)) {
		policy = policies;
		while (policy->image_name != NULL) {
			if (strcmp(policy->image_name, image_name) == 0) {
				result = policy->check(policy->image_spec);
				if (result == IO_SUCCESS) {
					*image_spec = policy->image_spec;
					*dev_handle = *(policy->dev_handle);
					break;
				} else {
					result = open_semihosting(
							policy->image_spec);
					if (result == IO_SUCCESS) {
						*dev_handle = sh_dev_handle;
						*image_spec =
							policy->image_spec;
					}
				}
			}
			policy++;
		}
	} else {
		result = IO_FAIL;
	}
	return result;
}
/*
 * FVP provides semihosting as an alternative to load images
 */
int plat_arm_get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
				  uintptr_t *image_spec)
{
	int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
	if (result == 0) {
		*dev_handle = sh_dev_handle;
		*image_spec = (uintptr_t)&sh_file_spec[image_id];
	}

	return result;
}
/* Try to load BL33 from Firmware Image Package in FLASH first. If there is no
 * FIP in FLASH or it is broken, try to load the file from semi-hosting.
 */
static int fvp_bl33_policy(io_dev_handle *dev_handle, void **image_spec)
{
    int result = IO_FAIL;
    void *local_image_spec = &bl33_file_spec;

    INFO("Loading BL33 (Normal world firmware)\n");
    /* FIP first then fall back to semi-hosting */
    result = open_fip(local_image_spec);
    if (result == IO_SUCCESS) {
        *dev_handle = fip_dev_handle;
        *(io_file_spec **)image_spec = local_image_spec;
    } else {
        result = open_semihosting(local_image_spec);
        if (result == IO_SUCCESS) {
            *dev_handle = sh_dev_handle;
            *(io_file_spec **)image_spec = local_image_spec;
        }
    }
    return result;
}