1 /* 2 * Copyright (c) 2015-2020, ARM Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include <drivers/io/io_driver.h> 9 #include <drivers/io/io_fip.h> 10 #include <drivers/io/io_memmap.h> 11 #include <drivers/io/io_storage.h> 12 #include <lib/utils.h> 13 14 #include <plat/arm/common/arm_fconf_getter.h> 15 #include <plat/arm/common/arm_fconf_io_storage.h> 16 #include <plat/arm/common/plat_arm.h> 17 #include <plat/common/platform.h> 18 #include <platform_def.h> 19 20 /* IO devices */ 21 static const io_dev_connector_t *fip_dev_con; 22 uintptr_t fip_dev_handle; 23 static const io_dev_connector_t *memmap_dev_con; 24 uintptr_t memmap_dev_handle; 25 26 /* Weak definitions may be overridden in specific ARM standard platform */ 27 #pragma weak plat_arm_io_setup 28 #pragma weak plat_arm_get_alt_image_source 29 30 int open_fip(const uintptr_t spec) 31 { 32 int result; 33 uintptr_t local_image_handle; 34 35 /* See if a Firmware Image Package is available */ 36 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 37 if (result == 0) { 38 result = io_open(fip_dev_handle, spec, &local_image_handle); 39 if (result == 0) { 40 VERBOSE("Using FIP\n"); 41 io_close(local_image_handle); 42 } 43 } 44 return result; 45 } 46 47 int open_memmap(const uintptr_t spec) 48 { 49 int result; 50 uintptr_t local_image_handle; 51 52 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 53 if (result == 0) { 54 result = io_open(memmap_dev_handle, spec, &local_image_handle); 55 if (result == 0) { 56 VERBOSE("Using Memmap\n"); 57 io_close(local_image_handle); 58 } 59 } 60 return result; 61 } 62 63 int arm_io_setup(void) 64 { 65 int io_result; 66 67 io_result = register_io_dev_fip(&fip_dev_con); 68 if (io_result < 0) { 69 return io_result; 70 } 71 72 io_result = register_io_dev_memmap(&memmap_dev_con); 73 if (io_result < 0) { 74 return io_result; 75 } 76 77 /* Open connections to devices and cache the handles */ 78 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 79 &fip_dev_handle); 80 if (io_result < 0) { 81 return io_result; 82 } 83 84 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 85 &memmap_dev_handle); 86 87 return io_result; 88 } 89 90 void plat_arm_io_setup(void) 91 { 92 int err; 93 94 err = arm_io_setup(); 95 if (err < 0) { 96 panic(); 97 } 98 } 99 100 int plat_arm_get_alt_image_source( 101 unsigned int image_id __unused, 102 uintptr_t *dev_handle __unused, 103 uintptr_t *image_spec __unused) 104 { 105 /* By default do not try an alternative */ 106 return -ENOENT; 107 } 108 109 /* Return an IO device handle and specification which can be used to access 110 * an image. Use this to enforce platform load policy */ 111 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 112 uintptr_t *image_spec) 113 { 114 int result; 115 const struct plat_io_policy *policy; 116 117 policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); 118 result = policy->check(policy->image_spec); 119 if (result == 0) { 120 *image_spec = policy->image_spec; 121 *dev_handle = *(policy->dev_handle); 122 } else { 123 VERBOSE("Trying alternative IO\n"); 124 result = plat_arm_get_alt_image_source(image_id, dev_handle, 125 image_spec); 126 } 127 128 return result; 129 } 130 131 /* 132 * See if a Firmware Image Package is available, 133 * by checking if TOC is valid or not. 134 */ 135 bool arm_io_is_toc_valid(void) 136 { 137 return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); 138 } 139