1 /* 2 * Copyright (C) 2018 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 #include <assert.h> 9 #include <string.h> 10 11 #include <platform_def.h> 12 13 #include <common/bl_common.h> 14 #include <common/debug.h> 15 #include <drivers/io/io_driver.h> 16 #include <drivers/io/io_fip.h> 17 #include <drivers/io/io_memmap.h> 18 #include <drivers/io/io_storage.h> 19 #include <tools_share/firmware_image_package.h> 20 21 /* IO devices */ 22 static const io_dev_connector_t *fip_dev_con; 23 static uintptr_t fip_dev_handle; 24 static const io_dev_connector_t *memmap_dev_con; 25 static uintptr_t memmap_dev_handle; 26 27 static const io_block_spec_t fip_block_spec = { 28 .offset = PLAT_MARVELL_FIP_BASE, 29 .length = PLAT_MARVELL_FIP_MAX_SIZE 30 }; 31 32 static const io_uuid_spec_t bl2_uuid_spec = { 33 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 34 }; 35 36 static const io_uuid_spec_t scp_bl2_uuid_spec = { 37 .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 38 }; 39 40 static const io_uuid_spec_t bl31_uuid_spec = { 41 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 42 }; 43 static const io_uuid_spec_t bl32_uuid_spec = { 44 .uuid = UUID_SECURE_PAYLOAD_BL32, 45 }; 46 47 static const io_uuid_spec_t bl32_extra1_uuid_spec = { 48 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 49 }; 50 51 static const io_uuid_spec_t bl32_extra2_uuid_spec = { 52 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 53 }; 54 55 static const io_uuid_spec_t bl33_uuid_spec = { 56 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 57 }; 58 59 static int open_fip(const uintptr_t spec); 60 static int open_memmap(const uintptr_t spec); 61 62 struct plat_io_policy { 63 uintptr_t *dev_handle; 64 uintptr_t image_spec; 65 int (*check)(const uintptr_t spec); 66 }; 67 68 /* By default, Marvell platforms load images from the FIP */ 69 static const struct plat_io_policy policies[] = { 70 [FIP_IMAGE_ID] = { 71 &memmap_dev_handle, 72 (uintptr_t)&fip_block_spec, 73 open_memmap 74 }, 75 [BL2_IMAGE_ID] = { 76 &fip_dev_handle, 77 (uintptr_t)&bl2_uuid_spec, 78 open_fip 79 }, 80 [SCP_BL2_IMAGE_ID] = { 81 &fip_dev_handle, 82 (uintptr_t)&scp_bl2_uuid_spec, 83 open_fip 84 }, 85 [BL31_IMAGE_ID] = { 86 &fip_dev_handle, 87 (uintptr_t)&bl31_uuid_spec, 88 open_fip 89 }, 90 [BL32_IMAGE_ID] = { 91 &fip_dev_handle, 92 (uintptr_t)&bl32_uuid_spec, 93 open_fip 94 }, 95 [BL32_EXTRA1_IMAGE_ID] = { 96 &fip_dev_handle, 97 (uintptr_t)&bl32_extra1_uuid_spec, 98 open_fip 99 }, 100 [BL32_EXTRA2_IMAGE_ID] = { 101 &fip_dev_handle, 102 (uintptr_t)&bl32_extra2_uuid_spec, 103 open_fip 104 }, 105 [BL33_IMAGE_ID] = { 106 &fip_dev_handle, 107 (uintptr_t)&bl33_uuid_spec, 108 open_fip 109 }, 110 }; 111 112 113 /* Weak definitions may be overridden in specific ARM standard platform */ 114 #pragma weak plat_marvell_io_setup 115 #pragma weak plat_marvell_get_alt_image_source 116 117 118 static int open_fip(const uintptr_t spec) 119 { 120 int result; 121 uintptr_t local_image_handle; 122 123 /* See if a Firmware Image Package is available */ 124 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 125 if (result == 0) { 126 result = io_open(fip_dev_handle, spec, &local_image_handle); 127 if (result == 0) { 128 VERBOSE("Using FIP\n"); 129 io_close(local_image_handle); 130 } 131 } 132 return result; 133 } 134 135 136 static int open_memmap(const uintptr_t spec) 137 { 138 int result; 139 uintptr_t local_image_handle; 140 141 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 142 if (result == 0) { 143 result = io_open(memmap_dev_handle, spec, &local_image_handle); 144 if (result == 0) { 145 VERBOSE("Using Memmap\n"); 146 io_close(local_image_handle); 147 } 148 } 149 return result; 150 } 151 152 153 void marvell_io_setup(void) 154 { 155 int io_result; 156 157 io_result = register_io_dev_fip(&fip_dev_con); 158 assert(io_result == 0); 159 160 io_result = register_io_dev_memmap(&memmap_dev_con); 161 assert(io_result == 0); 162 163 /* Open connections to devices and cache the handles */ 164 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 165 &fip_dev_handle); 166 assert(io_result == 0); 167 168 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 169 &memmap_dev_handle); 170 assert(io_result == 0); 171 172 /* Ignore improbable errors in release builds */ 173 (void)io_result; 174 } 175 176 void plat_marvell_io_setup(void) 177 { 178 marvell_io_setup(); 179 } 180 181 int plat_marvell_get_alt_image_source( 182 unsigned int image_id __attribute__((unused)), 183 uintptr_t *dev_handle __attribute__((unused)), 184 uintptr_t *image_spec __attribute__((unused))) 185 { 186 /* By default do not try an alternative */ 187 return -ENOENT; 188 } 189 190 /* 191 * Return an IO device handle and specification which can be used to access 192 * an image. Use this to enforce platform load policy 193 */ 194 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 195 uintptr_t *image_spec) 196 { 197 int result; 198 const struct plat_io_policy *policy; 199 200 assert(image_id < ARRAY_SIZE(policies)); 201 202 policy = &policies[image_id]; 203 result = policy->check(policy->image_spec); 204 if (result == 0) { 205 *image_spec = policy->image_spec; 206 *dev_handle = *(policy->dev_handle); 207 } else { 208 VERBOSE("Trying alternative IO\n"); 209 result = plat_marvell_get_alt_image_source(image_id, dev_handle, 210 image_spec); 211 } 212 213 return result; 214 } 215 216 /* 217 * See if a Firmware Image Package is available, 218 * by checking if TOC is valid or not. 219 */ 220 int marvell_io_is_toc_valid(void) 221 { 222 int result; 223 224 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 225 226 return result == 0; 227 } 228