1*4f2b9848SAndre Przywara /* 2*4f2b9848SAndre Przywara * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3*4f2b9848SAndre Przywara * 4*4f2b9848SAndre Przywara * SPDX-License-Identifier: BSD-3-Clause 5*4f2b9848SAndre Przywara */ 6*4f2b9848SAndre Przywara 7*4f2b9848SAndre Przywara #include <assert.h> 8*4f2b9848SAndre Przywara #include <string.h> 9*4f2b9848SAndre Przywara 10*4f2b9848SAndre Przywara #include <platform_def.h> 11*4f2b9848SAndre Przywara 12*4f2b9848SAndre Przywara #include <common/bl_common.h> 13*4f2b9848SAndre Przywara #include <common/debug.h> 14*4f2b9848SAndre Przywara #include <drivers/io/io_driver.h> 15*4f2b9848SAndre Przywara #include <drivers/io/io_fip.h> 16*4f2b9848SAndre Przywara #include <drivers/io/io_memmap.h> 17*4f2b9848SAndre Przywara #include <tools_share/firmware_image_package.h> 18*4f2b9848SAndre Przywara 19*4f2b9848SAndre Przywara /* Semihosting filenames */ 20*4f2b9848SAndre Przywara #define BL2_IMAGE_NAME "bl2.bin" 21*4f2b9848SAndre Przywara #define BL31_IMAGE_NAME "bl31.bin" 22*4f2b9848SAndre Przywara #define BL32_IMAGE_NAME "bl32.bin" 23*4f2b9848SAndre Przywara #define BL33_IMAGE_NAME "bl33.bin" 24*4f2b9848SAndre Przywara 25*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT 26*4f2b9848SAndre Przywara #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" 27*4f2b9848SAndre Przywara #define TRUSTED_KEY_CERT_NAME "trusted_key.crt" 28*4f2b9848SAndre Przywara #define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" 29*4f2b9848SAndre Przywara #define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" 30*4f2b9848SAndre Przywara #define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" 31*4f2b9848SAndre Przywara #define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" 32*4f2b9848SAndre Przywara #define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" 33*4f2b9848SAndre Przywara #define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" 34*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */ 35*4f2b9848SAndre Przywara 36*4f2b9848SAndre Przywara /* IO devices */ 37*4f2b9848SAndre Przywara static const io_dev_connector_t *fip_dev_con; 38*4f2b9848SAndre Przywara static uintptr_t fip_dev_handle; 39*4f2b9848SAndre Przywara static const io_dev_connector_t *memmap_dev_con; 40*4f2b9848SAndre Przywara static uintptr_t memmap_dev_handle; 41*4f2b9848SAndre Przywara 42*4f2b9848SAndre Przywara static const io_block_spec_t fip_block_spec = { 43*4f2b9848SAndre Przywara .offset = PLAT_RPI3_FIP_BASE, 44*4f2b9848SAndre Przywara .length = PLAT_RPI3_FIP_MAX_SIZE 45*4f2b9848SAndre Przywara }; 46*4f2b9848SAndre Przywara 47*4f2b9848SAndre Przywara static const io_uuid_spec_t bl2_uuid_spec = { 48*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 49*4f2b9848SAndre Przywara }; 50*4f2b9848SAndre Przywara 51*4f2b9848SAndre Przywara static const io_uuid_spec_t bl31_uuid_spec = { 52*4f2b9848SAndre Przywara .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 53*4f2b9848SAndre Przywara }; 54*4f2b9848SAndre Przywara 55*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_uuid_spec = { 56*4f2b9848SAndre Przywara .uuid = UUID_SECURE_PAYLOAD_BL32, 57*4f2b9848SAndre Przywara }; 58*4f2b9848SAndre Przywara 59*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_extra1_uuid_spec = { 60*4f2b9848SAndre Przywara .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 61*4f2b9848SAndre Przywara }; 62*4f2b9848SAndre Przywara 63*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_extra2_uuid_spec = { 64*4f2b9848SAndre Przywara .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 65*4f2b9848SAndre Przywara }; 66*4f2b9848SAndre Przywara 67*4f2b9848SAndre Przywara static const io_uuid_spec_t bl33_uuid_spec = { 68*4f2b9848SAndre Przywara .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 69*4f2b9848SAndre Przywara }; 70*4f2b9848SAndre Przywara 71*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT 72*4f2b9848SAndre Przywara static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 73*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_BOOT_FW_CERT, 74*4f2b9848SAndre Przywara }; 75*4f2b9848SAndre Przywara 76*4f2b9848SAndre Przywara static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 77*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_KEY_CERT, 78*4f2b9848SAndre Przywara }; 79*4f2b9848SAndre Przywara 80*4f2b9848SAndre Przywara static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 81*4f2b9848SAndre Przywara .uuid = UUID_SOC_FW_KEY_CERT, 82*4f2b9848SAndre Przywara }; 83*4f2b9848SAndre Przywara 84*4f2b9848SAndre Przywara static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 85*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 86*4f2b9848SAndre Przywara }; 87*4f2b9848SAndre Przywara 88*4f2b9848SAndre Przywara static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 89*4f2b9848SAndre Przywara .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 90*4f2b9848SAndre Przywara }; 91*4f2b9848SAndre Przywara 92*4f2b9848SAndre Przywara static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 93*4f2b9848SAndre Przywara .uuid = UUID_SOC_FW_CONTENT_CERT, 94*4f2b9848SAndre Przywara }; 95*4f2b9848SAndre Przywara 96*4f2b9848SAndre Przywara static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 97*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 98*4f2b9848SAndre Przywara }; 99*4f2b9848SAndre Przywara 100*4f2b9848SAndre Przywara static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 101*4f2b9848SAndre Przywara .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 102*4f2b9848SAndre Przywara }; 103*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */ 104*4f2b9848SAndre Przywara 105*4f2b9848SAndre Przywara static int open_fip(const uintptr_t spec); 106*4f2b9848SAndre Przywara static int open_memmap(const uintptr_t spec); 107*4f2b9848SAndre Przywara 108*4f2b9848SAndre Przywara struct plat_io_policy { 109*4f2b9848SAndre Przywara uintptr_t *dev_handle; 110*4f2b9848SAndre Przywara uintptr_t image_spec; 111*4f2b9848SAndre Przywara int (*check)(const uintptr_t spec); 112*4f2b9848SAndre Przywara }; 113*4f2b9848SAndre Przywara 114*4f2b9848SAndre Przywara /* By default, load images from the FIP */ 115*4f2b9848SAndre Przywara static const struct plat_io_policy policies[] = { 116*4f2b9848SAndre Przywara [FIP_IMAGE_ID] = { 117*4f2b9848SAndre Przywara &memmap_dev_handle, 118*4f2b9848SAndre Przywara (uintptr_t)&fip_block_spec, 119*4f2b9848SAndre Przywara open_memmap 120*4f2b9848SAndre Przywara }, 121*4f2b9848SAndre Przywara [BL2_IMAGE_ID] = { 122*4f2b9848SAndre Przywara &fip_dev_handle, 123*4f2b9848SAndre Przywara (uintptr_t)&bl2_uuid_spec, 124*4f2b9848SAndre Przywara open_fip 125*4f2b9848SAndre Przywara }, 126*4f2b9848SAndre Przywara [BL31_IMAGE_ID] = { 127*4f2b9848SAndre Przywara &fip_dev_handle, 128*4f2b9848SAndre Przywara (uintptr_t)&bl31_uuid_spec, 129*4f2b9848SAndre Przywara open_fip 130*4f2b9848SAndre Przywara }, 131*4f2b9848SAndre Przywara [BL32_IMAGE_ID] = { 132*4f2b9848SAndre Przywara &fip_dev_handle, 133*4f2b9848SAndre Przywara (uintptr_t)&bl32_uuid_spec, 134*4f2b9848SAndre Przywara open_fip 135*4f2b9848SAndre Przywara }, 136*4f2b9848SAndre Przywara [BL32_EXTRA1_IMAGE_ID] = { 137*4f2b9848SAndre Przywara &fip_dev_handle, 138*4f2b9848SAndre Przywara (uintptr_t)&bl32_extra1_uuid_spec, 139*4f2b9848SAndre Przywara open_fip 140*4f2b9848SAndre Przywara }, 141*4f2b9848SAndre Przywara [BL32_EXTRA2_IMAGE_ID] = { 142*4f2b9848SAndre Przywara &fip_dev_handle, 143*4f2b9848SAndre Przywara (uintptr_t)&bl32_extra2_uuid_spec, 144*4f2b9848SAndre Przywara open_fip 145*4f2b9848SAndre Przywara }, 146*4f2b9848SAndre Przywara [BL33_IMAGE_ID] = { 147*4f2b9848SAndre Przywara &fip_dev_handle, 148*4f2b9848SAndre Przywara (uintptr_t)&bl33_uuid_spec, 149*4f2b9848SAndre Przywara open_fip 150*4f2b9848SAndre Przywara }, 151*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT 152*4f2b9848SAndre Przywara [TRUSTED_BOOT_FW_CERT_ID] = { 153*4f2b9848SAndre Przywara &fip_dev_handle, 154*4f2b9848SAndre Przywara (uintptr_t)&tb_fw_cert_uuid_spec, 155*4f2b9848SAndre Przywara open_fip 156*4f2b9848SAndre Przywara }, 157*4f2b9848SAndre Przywara [TRUSTED_KEY_CERT_ID] = { 158*4f2b9848SAndre Przywara &fip_dev_handle, 159*4f2b9848SAndre Przywara (uintptr_t)&trusted_key_cert_uuid_spec, 160*4f2b9848SAndre Przywara open_fip 161*4f2b9848SAndre Przywara }, 162*4f2b9848SAndre Przywara [SOC_FW_KEY_CERT_ID] = { 163*4f2b9848SAndre Przywara &fip_dev_handle, 164*4f2b9848SAndre Przywara (uintptr_t)&soc_fw_key_cert_uuid_spec, 165*4f2b9848SAndre Przywara open_fip 166*4f2b9848SAndre Przywara }, 167*4f2b9848SAndre Przywara [TRUSTED_OS_FW_KEY_CERT_ID] = { 168*4f2b9848SAndre Przywara &fip_dev_handle, 169*4f2b9848SAndre Przywara (uintptr_t)&tos_fw_key_cert_uuid_spec, 170*4f2b9848SAndre Przywara open_fip 171*4f2b9848SAndre Przywara }, 172*4f2b9848SAndre Przywara [NON_TRUSTED_FW_KEY_CERT_ID] = { 173*4f2b9848SAndre Przywara &fip_dev_handle, 174*4f2b9848SAndre Przywara (uintptr_t)&nt_fw_key_cert_uuid_spec, 175*4f2b9848SAndre Przywara open_fip 176*4f2b9848SAndre Przywara }, 177*4f2b9848SAndre Przywara [SOC_FW_CONTENT_CERT_ID] = { 178*4f2b9848SAndre Przywara &fip_dev_handle, 179*4f2b9848SAndre Przywara (uintptr_t)&soc_fw_cert_uuid_spec, 180*4f2b9848SAndre Przywara open_fip 181*4f2b9848SAndre Przywara }, 182*4f2b9848SAndre Przywara [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 183*4f2b9848SAndre Przywara &fip_dev_handle, 184*4f2b9848SAndre Przywara (uintptr_t)&tos_fw_cert_uuid_spec, 185*4f2b9848SAndre Przywara open_fip 186*4f2b9848SAndre Przywara }, 187*4f2b9848SAndre Przywara [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 188*4f2b9848SAndre Przywara &fip_dev_handle, 189*4f2b9848SAndre Przywara (uintptr_t)&nt_fw_cert_uuid_spec, 190*4f2b9848SAndre Przywara open_fip 191*4f2b9848SAndre Przywara }, 192*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */ 193*4f2b9848SAndre Przywara }; 194*4f2b9848SAndre Przywara 195*4f2b9848SAndre Przywara static int open_fip(const uintptr_t spec) 196*4f2b9848SAndre Przywara { 197*4f2b9848SAndre Przywara int result; 198*4f2b9848SAndre Przywara uintptr_t local_image_handle; 199*4f2b9848SAndre Przywara 200*4f2b9848SAndre Przywara /* See if a Firmware Image Package is available */ 201*4f2b9848SAndre Przywara result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 202*4f2b9848SAndre Przywara if (result == 0) { 203*4f2b9848SAndre Przywara result = io_open(fip_dev_handle, spec, &local_image_handle); 204*4f2b9848SAndre Przywara if (result == 0) { 205*4f2b9848SAndre Przywara VERBOSE("Using FIP\n"); 206*4f2b9848SAndre Przywara io_close(local_image_handle); 207*4f2b9848SAndre Przywara } 208*4f2b9848SAndre Przywara } 209*4f2b9848SAndre Przywara return result; 210*4f2b9848SAndre Przywara } 211*4f2b9848SAndre Przywara 212*4f2b9848SAndre Przywara static int open_memmap(const uintptr_t spec) 213*4f2b9848SAndre Przywara { 214*4f2b9848SAndre Przywara int result; 215*4f2b9848SAndre Przywara uintptr_t local_image_handle; 216*4f2b9848SAndre Przywara 217*4f2b9848SAndre Przywara result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 218*4f2b9848SAndre Przywara if (result == 0) { 219*4f2b9848SAndre Przywara result = io_open(memmap_dev_handle, spec, &local_image_handle); 220*4f2b9848SAndre Przywara if (result == 0) { 221*4f2b9848SAndre Przywara VERBOSE("Using Memmap\n"); 222*4f2b9848SAndre Przywara io_close(local_image_handle); 223*4f2b9848SAndre Przywara } 224*4f2b9848SAndre Przywara } 225*4f2b9848SAndre Przywara return result; 226*4f2b9848SAndre Przywara } 227*4f2b9848SAndre Przywara 228*4f2b9848SAndre Przywara void plat_rpi3_io_setup(void) 229*4f2b9848SAndre Przywara { 230*4f2b9848SAndre Przywara int io_result; 231*4f2b9848SAndre Przywara 232*4f2b9848SAndre Przywara io_result = register_io_dev_fip(&fip_dev_con); 233*4f2b9848SAndre Przywara assert(io_result == 0); 234*4f2b9848SAndre Przywara 235*4f2b9848SAndre Przywara io_result = register_io_dev_memmap(&memmap_dev_con); 236*4f2b9848SAndre Przywara assert(io_result == 0); 237*4f2b9848SAndre Przywara 238*4f2b9848SAndre Przywara /* Open connections to devices and cache the handles */ 239*4f2b9848SAndre Przywara io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 240*4f2b9848SAndre Przywara &fip_dev_handle); 241*4f2b9848SAndre Przywara assert(io_result == 0); 242*4f2b9848SAndre Przywara 243*4f2b9848SAndre Przywara io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 244*4f2b9848SAndre Przywara &memmap_dev_handle); 245*4f2b9848SAndre Przywara assert(io_result == 0); 246*4f2b9848SAndre Przywara 247*4f2b9848SAndre Przywara /* Ignore improbable errors in release builds */ 248*4f2b9848SAndre Przywara (void)io_result; 249*4f2b9848SAndre Przywara } 250*4f2b9848SAndre Przywara 251*4f2b9848SAndre Przywara /* 252*4f2b9848SAndre Przywara * Return an IO device handle and specification which can be used to access 253*4f2b9848SAndre Przywara * an image. Use this to enforce platform load policy 254*4f2b9848SAndre Przywara */ 255*4f2b9848SAndre Przywara int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 256*4f2b9848SAndre Przywara uintptr_t *image_spec) 257*4f2b9848SAndre Przywara { 258*4f2b9848SAndre Przywara int result; 259*4f2b9848SAndre Przywara const struct plat_io_policy *policy; 260*4f2b9848SAndre Przywara 261*4f2b9848SAndre Przywara assert(image_id < ARRAY_SIZE(policies)); 262*4f2b9848SAndre Przywara 263*4f2b9848SAndre Przywara policy = &policies[image_id]; 264*4f2b9848SAndre Przywara result = policy->check(policy->image_spec); 265*4f2b9848SAndre Przywara if (result == 0) { 266*4f2b9848SAndre Przywara *image_spec = policy->image_spec; 267*4f2b9848SAndre Przywara *dev_handle = *(policy->dev_handle); 268*4f2b9848SAndre Przywara } 269*4f2b9848SAndre Przywara 270*4f2b9848SAndre Przywara return result; 271*4f2b9848SAndre Przywara } 272