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 static const io_uuid_spec_t bl33_uuid_spec = { 47 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 48 }; 49 50 static int open_fip(const uintptr_t spec); 51 static int open_memmap(const uintptr_t spec); 52 53 struct plat_io_policy { 54 uintptr_t *dev_handle; 55 uintptr_t image_spec; 56 int (*check)(const uintptr_t spec); 57 }; 58 59 /* By default, Marvell platforms load images from the FIP */ 60 static const struct plat_io_policy policies[] = { 61 [FIP_IMAGE_ID] = { 62 &memmap_dev_handle, 63 (uintptr_t)&fip_block_spec, 64 open_memmap 65 }, 66 [BL2_IMAGE_ID] = { 67 &fip_dev_handle, 68 (uintptr_t)&bl2_uuid_spec, 69 open_fip 70 }, 71 [SCP_BL2_IMAGE_ID] = { 72 &fip_dev_handle, 73 (uintptr_t)&scp_bl2_uuid_spec, 74 open_fip 75 }, 76 [BL31_IMAGE_ID] = { 77 &fip_dev_handle, 78 (uintptr_t)&bl31_uuid_spec, 79 open_fip 80 }, 81 [BL32_IMAGE_ID] = { 82 &fip_dev_handle, 83 (uintptr_t)&bl32_uuid_spec, 84 open_fip 85 }, 86 [BL33_IMAGE_ID] = { 87 &fip_dev_handle, 88 (uintptr_t)&bl33_uuid_spec, 89 open_fip 90 }, 91 }; 92 93 94 /* Weak definitions may be overridden in specific ARM standard platform */ 95 #pragma weak plat_marvell_io_setup 96 #pragma weak plat_marvell_get_alt_image_source 97 98 99 static int open_fip(const uintptr_t spec) 100 { 101 int result; 102 uintptr_t local_image_handle; 103 104 /* See if a Firmware Image Package is available */ 105 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 106 if (result == 0) { 107 result = io_open(fip_dev_handle, spec, &local_image_handle); 108 if (result == 0) { 109 VERBOSE("Using FIP\n"); 110 io_close(local_image_handle); 111 } 112 } 113 return result; 114 } 115 116 117 static int open_memmap(const uintptr_t spec) 118 { 119 int result; 120 uintptr_t local_image_handle; 121 122 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 123 if (result == 0) { 124 result = io_open(memmap_dev_handle, spec, &local_image_handle); 125 if (result == 0) { 126 VERBOSE("Using Memmap\n"); 127 io_close(local_image_handle); 128 } 129 } 130 return result; 131 } 132 133 134 void marvell_io_setup(void) 135 { 136 int io_result; 137 138 io_result = register_io_dev_fip(&fip_dev_con); 139 assert(io_result == 0); 140 141 io_result = register_io_dev_memmap(&memmap_dev_con); 142 assert(io_result == 0); 143 144 /* Open connections to devices and cache the handles */ 145 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 146 &fip_dev_handle); 147 assert(io_result == 0); 148 149 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 150 &memmap_dev_handle); 151 assert(io_result == 0); 152 153 /* Ignore improbable errors in release builds */ 154 (void)io_result; 155 } 156 157 void plat_marvell_io_setup(void) 158 { 159 marvell_io_setup(); 160 } 161 162 int plat_marvell_get_alt_image_source( 163 unsigned int image_id __attribute__((unused)), 164 uintptr_t *dev_handle __attribute__((unused)), 165 uintptr_t *image_spec __attribute__((unused))) 166 { 167 /* By default do not try an alternative */ 168 return -ENOENT; 169 } 170 171 /* 172 * Return an IO device handle and specification which can be used to access 173 * an image. Use this to enforce platform load policy 174 */ 175 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 176 uintptr_t *image_spec) 177 { 178 int result; 179 const struct plat_io_policy *policy; 180 181 assert(image_id < ARRAY_SIZE(policies)); 182 183 policy = &policies[image_id]; 184 result = policy->check(policy->image_spec); 185 if (result == 0) { 186 *image_spec = policy->image_spec; 187 *dev_handle = *(policy->dev_handle); 188 } else { 189 VERBOSE("Trying alternative IO\n"); 190 result = plat_marvell_get_alt_image_source(image_id, dev_handle, 191 image_spec); 192 } 193 194 return result; 195 } 196 197 /* 198 * See if a Firmware Image Package is available, 199 * by checking if TOC is valid or not. 200 */ 201 int marvell_io_is_toc_valid(void) 202 { 203 int result; 204 205 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 206 207 return result == 0; 208 } 209