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