/* * Copyright 2018-2020 NXP * * SPDX-License-Identifier: BSD-3-Clause * */ #include #include #include #include #include #include #include #include #include #include "ddr_io_storage.h" #include "plat_common.h" #include "platform_def.h" /* TBD - Move these defined to the platform_def.h file. * Keeping them for reference here */ extern uintptr_t backend_dev_handle; static uint32_t ddr_fip; static uintptr_t ddr_fip_dev_handle; static io_block_spec_t ddr_fip_block_spec = { .offset = PLAT_DDR_FIP_OFFSET, .length = PLAT_DDR_FIP_MAX_SIZE }; static const io_uuid_spec_t ddr_imem_udimm_1d_uuid_spec = { .uuid = UUID_DDR_IMEM_UDIMM_1D, }; static const io_uuid_spec_t ddr_imem_udimm_2d_uuid_spec = { .uuid = UUID_DDR_IMEM_UDIMM_2D, }; static const io_uuid_spec_t ddr_dmem_udimm_1d_uuid_spec = { .uuid = UUID_DDR_DMEM_UDIMM_1D, }; static const io_uuid_spec_t ddr_dmem_udimm_2d_uuid_spec = { .uuid = UUID_DDR_DMEM_UDIMM_2D, }; static const io_uuid_spec_t ddr_imem_rdimm_1d_uuid_spec = { .uuid = UUID_DDR_IMEM_RDIMM_1D, }; static const io_uuid_spec_t ddr_imem_rdimm_2d_uuid_spec = { .uuid = UUID_DDR_IMEM_RDIMM_2D, }; static const io_uuid_spec_t ddr_dmem_rdimm_1d_uuid_spec = { .uuid = UUID_DDR_DMEM_RDIMM_1D, }; static const io_uuid_spec_t ddr_dmem_rdimm_2d_uuid_spec = { .uuid = UUID_DDR_DMEM_RDIMM_2D, }; #if TRUSTED_BOARD_BOOT static const io_uuid_spec_t ddr_fw_key_cert_uuid_spec = { .uuid = UUID_DDR_FW_KEY_CERT, }; static const io_uuid_spec_t ddr_udimm_fw_cert_uuid_spec = { .uuid = UUID_DDR_UDIMM_FW_CONTENT_CERT, }; static const io_uuid_spec_t ddr_rdimm_fw_cert_uuid_spec = { .uuid = UUID_DDR_RDIMM_FW_CONTENT_CERT, }; #endif static int open_ddr_fip(const uintptr_t spec); struct plat_io_policy { uintptr_t *dev_handle; uintptr_t image_spec; int (*check)(const uintptr_t spec); }; /* By default, ARM platforms load images from the FIP */ static const struct plat_io_policy ddr_policies[] = { [DDR_FIP_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &backend_dev_handle, (uintptr_t)&ddr_fip_block_spec, NULL }, [DDR_IMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_imem_udimm_1d_uuid_spec, open_ddr_fip }, [DDR_IMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_imem_udimm_2d_uuid_spec, open_ddr_fip }, [DDR_DMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_dmem_udimm_1d_uuid_spec, open_ddr_fip }, [DDR_DMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_dmem_udimm_2d_uuid_spec, open_ddr_fip }, [DDR_IMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_imem_rdimm_1d_uuid_spec, open_ddr_fip }, [DDR_IMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_imem_rdimm_2d_uuid_spec, open_ddr_fip }, [DDR_DMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_dmem_rdimm_1d_uuid_spec, open_ddr_fip }, [DDR_DMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_dmem_rdimm_2d_uuid_spec, open_ddr_fip }, #if TRUSTED_BOARD_BOOT [DDR_FW_KEY_CERT_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_fw_key_cert_uuid_spec, open_ddr_fip }, [DDR_UDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_udimm_fw_cert_uuid_spec, open_ddr_fip }, [DDR_RDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = { &ddr_fip_dev_handle, (uintptr_t)&ddr_rdimm_fw_cert_uuid_spec, open_ddr_fip }, #endif }; static int open_ddr_fip(const uintptr_t spec) { int result; uintptr_t local_image_handle; /* See if a Firmware Image Package is available */ result = io_dev_init(ddr_fip_dev_handle, (uintptr_t)DDR_FIP_IMAGE_ID); if (result == 0) { result = io_open(ddr_fip_dev_handle, spec, &local_image_handle); if (result == 0) { VERBOSE("Using FIP\n"); io_close(local_image_handle); } } return result; } /* The image can be one of the DDR PHY images, which can be sleected via DDR * policies */ int plat_get_ddr_fip_image_source(unsigned int image_id, uintptr_t *dev_handle, uintptr_t *image_spec, int (*check)(const uintptr_t spec)) { int result = -1; const struct plat_io_policy *policy; if (image_id >= (DDR_FIP_IMAGE_ID + ARRAY_SIZE(ddr_policies))) { return result; } policy = &ddr_policies[image_id - DDR_FIP_IMAGE_ID]; if (image_id == DDR_FIP_IMAGE_ID) { result = check(policy->image_spec); } else { result = policy->check(policy->image_spec); } if (result == 0) { *image_spec = policy->image_spec; *dev_handle = *(policy->dev_handle); } return result; } int ddr_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev) { int io_result; size_t ddr_fip_offset = PLAT_DDR_FIP_OFFSET; /* Open connections to ddr fip and cache the handles */ io_result = io_dev_open(fip_dev_con, (uintptr_t)&ddr_fip, &ddr_fip_dev_handle); assert(io_result == 0); switch (boot_dev) { #if QSPI_BOOT case BOOT_DEVICE_QSPI: ddr_fip_offset += NXP_QSPI_FLASH_ADDR; break; #endif #if NOR_BOOT case BOOT_DEVICE_IFC_NOR: ddr_fip_offset += NXP_NOR_FLASH_ADDR; break; #endif #if FLEXSPI_NOR_BOOT case BOOT_DEVICE_FLEXSPI_NOR: ddr_fip_offset += NXP_FLEXSPI_FLASH_ADDR; break; #endif default: break; } ddr_fip_block_spec.offset = ddr_fip_offset; return io_result; }