148ab3904SJassi Brar /* 248ab3904SJassi Brar * Copyright (c) 2022, Socionext Inc. All rights reserved. 348ab3904SJassi Brar * 448ab3904SJassi Brar * SPDX-License-Identifier: BSD-3-Clause 548ab3904SJassi Brar */ 648ab3904SJassi Brar 748ab3904SJassi Brar #include <assert.h> 848ab3904SJassi Brar #include <errno.h> 948ab3904SJassi Brar #include <stdint.h> 1048ab3904SJassi Brar 1148ab3904SJassi Brar #include <drivers/io/io_block.h> 1248ab3904SJassi Brar #include <drivers/io/io_driver.h> 1348ab3904SJassi Brar #include <drivers/io/io_fip.h> 1448ab3904SJassi Brar #include <drivers/io/io_memmap.h> 1548ab3904SJassi Brar #include <lib/mmio.h> 1648ab3904SJassi Brar #include <lib/utils_def.h> 1748ab3904SJassi Brar #include <lib/xlat_tables/xlat_tables_v2.h> 1848ab3904SJassi Brar #include <tools_share/firmware_image_package.h> 1948ab3904SJassi Brar 2048ab3904SJassi Brar #include <platform_def.h> 2148ab3904SJassi Brar #include <sq_common.h> 2248ab3904SJassi Brar 2348ab3904SJassi Brar static const io_dev_connector_t *sq_fip_dev_con; 2448ab3904SJassi Brar static uintptr_t sq_fip_dev_handle; 2548ab3904SJassi Brar 2648ab3904SJassi Brar static const io_dev_connector_t *sq_backend_dev_con; 2748ab3904SJassi Brar static uintptr_t sq_backend_dev_handle; 2848ab3904SJassi Brar 2948ab3904SJassi Brar static io_block_spec_t sq_fip_spec = { 3048ab3904SJassi Brar .offset = PLAT_SQ_FIP_IOBASE, /* FIP Image is at 5MB offset on memory-mapped NOR flash */ 3148ab3904SJassi Brar .length = PLAT_SQ_FIP_MAXSIZE, /* Expected maximum FIP image size */ 3248ab3904SJassi Brar }; 3348ab3904SJassi Brar 3448ab3904SJassi Brar static const io_uuid_spec_t sq_bl2_spec = { 3548ab3904SJassi Brar .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 3648ab3904SJassi Brar }; 3748ab3904SJassi Brar 3848ab3904SJassi Brar static const io_uuid_spec_t sq_bl31_spec = { 3948ab3904SJassi Brar .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 4048ab3904SJassi Brar }; 4148ab3904SJassi Brar 4248ab3904SJassi Brar static const io_uuid_spec_t sq_bl32_spec = { 4348ab3904SJassi Brar .uuid = UUID_SECURE_PAYLOAD_BL32, 4448ab3904SJassi Brar }; 4548ab3904SJassi Brar 4648ab3904SJassi Brar static const io_uuid_spec_t sq_bl33_spec = { 4748ab3904SJassi Brar .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 4848ab3904SJassi Brar }; 4948ab3904SJassi Brar 50*19aaeea0SJassi Brar #if TRUSTED_BOARD_BOOT 51*19aaeea0SJassi Brar static const io_uuid_spec_t sq_tb_fw_cert_spec = { 52*19aaeea0SJassi Brar .uuid = UUID_TRUSTED_BOOT_FW_CERT, 53*19aaeea0SJassi Brar }; 54*19aaeea0SJassi Brar 55*19aaeea0SJassi Brar static const io_uuid_spec_t sq_trusted_key_cert_spec = { 56*19aaeea0SJassi Brar .uuid = UUID_TRUSTED_KEY_CERT, 57*19aaeea0SJassi Brar }; 58*19aaeea0SJassi Brar 59*19aaeea0SJassi Brar static const io_uuid_spec_t sq_soc_fw_key_cert_spec = { 60*19aaeea0SJassi Brar .uuid = UUID_SOC_FW_KEY_CERT, 61*19aaeea0SJassi Brar }; 62*19aaeea0SJassi Brar 63*19aaeea0SJassi Brar static const io_uuid_spec_t sq_tos_fw_key_cert_spec = { 64*19aaeea0SJassi Brar .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 65*19aaeea0SJassi Brar }; 66*19aaeea0SJassi Brar 67*19aaeea0SJassi Brar static const io_uuid_spec_t sq_nt_fw_key_cert_spec = { 68*19aaeea0SJassi Brar .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 69*19aaeea0SJassi Brar }; 70*19aaeea0SJassi Brar 71*19aaeea0SJassi Brar static const io_uuid_spec_t sq_soc_fw_cert_spec = { 72*19aaeea0SJassi Brar .uuid = UUID_SOC_FW_CONTENT_CERT, 73*19aaeea0SJassi Brar }; 74*19aaeea0SJassi Brar 75*19aaeea0SJassi Brar static const io_uuid_spec_t sq_tos_fw_cert_spec = { 76*19aaeea0SJassi Brar .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 77*19aaeea0SJassi Brar }; 78*19aaeea0SJassi Brar 79*19aaeea0SJassi Brar static const io_uuid_spec_t sq_nt_fw_cert_spec = { 80*19aaeea0SJassi Brar .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 81*19aaeea0SJassi Brar }; 82*19aaeea0SJassi Brar #endif /* TRUSTED_BOARD_BOOT */ 83*19aaeea0SJassi Brar 8448ab3904SJassi Brar struct sq_io_policy { 8548ab3904SJassi Brar uintptr_t *dev_handle; 8648ab3904SJassi Brar uintptr_t image_spec; 8748ab3904SJassi Brar uintptr_t init_params; 8848ab3904SJassi Brar }; 8948ab3904SJassi Brar 9048ab3904SJassi Brar static const struct sq_io_policy sq_io_policies[] = { 9148ab3904SJassi Brar [FIP_IMAGE_ID] = { 9248ab3904SJassi Brar .dev_handle = &sq_backend_dev_handle, 9348ab3904SJassi Brar .image_spec = (uintptr_t)&sq_fip_spec, 9448ab3904SJassi Brar }, 9548ab3904SJassi Brar [BL2_IMAGE_ID] = { 9648ab3904SJassi Brar .dev_handle = &sq_fip_dev_handle, 9748ab3904SJassi Brar .image_spec = (uintptr_t)&sq_bl2_spec, 9848ab3904SJassi Brar .init_params = FIP_IMAGE_ID, 9948ab3904SJassi Brar }, 10048ab3904SJassi Brar [BL31_IMAGE_ID] = { 10148ab3904SJassi Brar .dev_handle = &sq_fip_dev_handle, 10248ab3904SJassi Brar .image_spec = (uintptr_t)&sq_bl31_spec, 10348ab3904SJassi Brar .init_params = FIP_IMAGE_ID, 10448ab3904SJassi Brar }, 10548ab3904SJassi Brar [BL32_IMAGE_ID] = { 10648ab3904SJassi Brar .dev_handle = &sq_fip_dev_handle, 10748ab3904SJassi Brar .image_spec = (uintptr_t)&sq_bl32_spec, 10848ab3904SJassi Brar .init_params = FIP_IMAGE_ID, 10948ab3904SJassi Brar }, 11048ab3904SJassi Brar [BL33_IMAGE_ID] = { 11148ab3904SJassi Brar .dev_handle = &sq_fip_dev_handle, 11248ab3904SJassi Brar .image_spec = (uintptr_t)&sq_bl33_spec, 11348ab3904SJassi Brar .init_params = FIP_IMAGE_ID, 11448ab3904SJassi Brar }, 115*19aaeea0SJassi Brar #if TRUSTED_BOARD_BOOT 116*19aaeea0SJassi Brar [TRUSTED_BOOT_FW_CERT_ID] = { 117*19aaeea0SJassi Brar .dev_handle = &sq_fip_dev_handle, 118*19aaeea0SJassi Brar .image_spec = (uintptr_t)&sq_tb_fw_cert_spec, 119*19aaeea0SJassi Brar .init_params = FIP_IMAGE_ID, 120*19aaeea0SJassi Brar }, 121*19aaeea0SJassi Brar [TRUSTED_KEY_CERT_ID] = { 122*19aaeea0SJassi Brar .dev_handle = &sq_fip_dev_handle, 123*19aaeea0SJassi Brar .image_spec = (uintptr_t)&sq_trusted_key_cert_spec, 124*19aaeea0SJassi Brar .init_params = FIP_IMAGE_ID, 125*19aaeea0SJassi Brar }, 126*19aaeea0SJassi Brar [SOC_FW_KEY_CERT_ID] = { 127*19aaeea0SJassi Brar .dev_handle = &sq_fip_dev_handle, 128*19aaeea0SJassi Brar .image_spec = (uintptr_t)&sq_soc_fw_key_cert_spec, 129*19aaeea0SJassi Brar .init_params = FIP_IMAGE_ID, 130*19aaeea0SJassi Brar }, 131*19aaeea0SJassi Brar [TRUSTED_OS_FW_KEY_CERT_ID] = { 132*19aaeea0SJassi Brar .dev_handle = &sq_fip_dev_handle, 133*19aaeea0SJassi Brar .image_spec = (uintptr_t)&sq_tos_fw_key_cert_spec, 134*19aaeea0SJassi Brar .init_params = FIP_IMAGE_ID, 135*19aaeea0SJassi Brar }, 136*19aaeea0SJassi Brar [NON_TRUSTED_FW_KEY_CERT_ID] = { 137*19aaeea0SJassi Brar .dev_handle = &sq_fip_dev_handle, 138*19aaeea0SJassi Brar .image_spec = (uintptr_t)&sq_nt_fw_key_cert_spec, 139*19aaeea0SJassi Brar .init_params = FIP_IMAGE_ID, 140*19aaeea0SJassi Brar }, 141*19aaeea0SJassi Brar [SOC_FW_CONTENT_CERT_ID] = { 142*19aaeea0SJassi Brar .dev_handle = &sq_fip_dev_handle, 143*19aaeea0SJassi Brar .image_spec = (uintptr_t)&sq_soc_fw_cert_spec, 144*19aaeea0SJassi Brar .init_params = FIP_IMAGE_ID, 145*19aaeea0SJassi Brar }, 146*19aaeea0SJassi Brar [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 147*19aaeea0SJassi Brar .dev_handle = &sq_fip_dev_handle, 148*19aaeea0SJassi Brar .image_spec = (uintptr_t)&sq_tos_fw_cert_spec, 149*19aaeea0SJassi Brar .init_params = FIP_IMAGE_ID, 150*19aaeea0SJassi Brar }, 151*19aaeea0SJassi Brar [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 152*19aaeea0SJassi Brar .dev_handle = &sq_fip_dev_handle, 153*19aaeea0SJassi Brar .image_spec = (uintptr_t)&sq_nt_fw_cert_spec, 154*19aaeea0SJassi Brar .init_params = FIP_IMAGE_ID, 155*19aaeea0SJassi Brar }, 156*19aaeea0SJassi Brar #endif 15748ab3904SJassi Brar }; 15848ab3904SJassi Brar 15948ab3904SJassi Brar static int sq_io_memmap_setup(void) 16048ab3904SJassi Brar { 16148ab3904SJassi Brar int ret; 16248ab3904SJassi Brar 16348ab3904SJassi Brar ret = mmap_add_dynamic_region(sq_fip_spec.offset, sq_fip_spec.offset, 16448ab3904SJassi Brar sq_fip_spec.length, MT_RO_DATA | MT_SECURE); 16548ab3904SJassi Brar if (ret) { 16648ab3904SJassi Brar return ret; 16748ab3904SJassi Brar } 16848ab3904SJassi Brar 16948ab3904SJassi Brar ret = register_io_dev_memmap(&sq_backend_dev_con); 17048ab3904SJassi Brar if (ret) { 17148ab3904SJassi Brar return ret; 17248ab3904SJassi Brar } 17348ab3904SJassi Brar 17448ab3904SJassi Brar return io_dev_open(sq_backend_dev_con, 0, &sq_backend_dev_handle); 17548ab3904SJassi Brar } 17648ab3904SJassi Brar 17748ab3904SJassi Brar static int sq_io_fip_setup(void) 17848ab3904SJassi Brar { 17948ab3904SJassi Brar int ret; 18048ab3904SJassi Brar 18148ab3904SJassi Brar ret = register_io_dev_fip(&sq_fip_dev_con); 18248ab3904SJassi Brar if (ret) { 18348ab3904SJassi Brar return ret; 18448ab3904SJassi Brar } 18548ab3904SJassi Brar 18648ab3904SJassi Brar return io_dev_open(sq_fip_dev_con, 0, &sq_fip_dev_handle); 18748ab3904SJassi Brar } 18848ab3904SJassi Brar 18948ab3904SJassi Brar int sq_io_setup(void) 19048ab3904SJassi Brar { 19148ab3904SJassi Brar int ret; 19248ab3904SJassi Brar 19348ab3904SJassi Brar ret = sq_io_memmap_setup(); 19448ab3904SJassi Brar if (ret) { 19548ab3904SJassi Brar return ret; 19648ab3904SJassi Brar } 19748ab3904SJassi Brar 19848ab3904SJassi Brar ret = sq_io_fip_setup(); 19948ab3904SJassi Brar if (ret) { 20048ab3904SJassi Brar return ret; 20148ab3904SJassi Brar } 20248ab3904SJassi Brar 20348ab3904SJassi Brar return 0; 20448ab3904SJassi Brar } 20548ab3904SJassi Brar 20648ab3904SJassi Brar int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 20748ab3904SJassi Brar uintptr_t *image_spec) 20848ab3904SJassi Brar { 20948ab3904SJassi Brar uintptr_t init_params; 21048ab3904SJassi Brar 21148ab3904SJassi Brar assert(image_id < ARRAY_SIZE(sq_io_policies)); 21248ab3904SJassi Brar 21348ab3904SJassi Brar *dev_handle = *sq_io_policies[image_id].dev_handle; 21448ab3904SJassi Brar *image_spec = sq_io_policies[image_id].image_spec; 21548ab3904SJassi Brar init_params = sq_io_policies[image_id].init_params; 21648ab3904SJassi Brar 21748ab3904SJassi Brar return io_dev_init(*dev_handle, init_params); 21848ab3904SJassi Brar } 219