| /* SPDX-License-Identifier: GPL-2.0-only */ |
| |
| #include <arch/cache.h> |
| #include <device/mmio.h> |
| #include <cbfs.h> |
| #include <console/console.h> |
| #include <string.h> |
| #include <program_loading.h> |
| #include <soc/iomap.h> |
| #include <soc/soc_services.h> |
| |
| #include "mbn_header.h" |
| |
| struct cdt_info { |
| uint32_t size; /* size of the whole table */ |
| uint8_t *cdt_ptr; /* pointer to CDT */ |
| }; |
| |
| static void *load_ipq_blob(const char *file_name) |
| { |
| struct mbn_header *blob_mbn; |
| void *blob_dest; |
| size_t blob_size; |
| |
| blob_mbn = cbfs_map(file_name, &blob_size); |
| if (!blob_mbn) |
| return NULL; |
| |
| /* some sanity checks on the headers */ |
| if ((blob_mbn->mbn_version != 3) || |
| (blob_mbn->mbn_total_size > blob_size)) |
| return NULL; |
| |
| blob_dest = (void *)blob_mbn->mbn_destination; |
| |
| if (blob_mbn->mbn_destination) { |
| /* Copy the blob to the appropriate memory location. */ |
| memcpy(blob_dest, blob_mbn + 1, blob_mbn->mbn_total_size); |
| cache_sync_instructions(); |
| return blob_dest; |
| } |
| |
| return blob_mbn; |
| } |
| |
| #define DDR_VERSION() ((const char *)"private build") |
| #define MAX_DDR_VERSION_SIZE 48 |
| |
| typedef struct { |
| uint64_t entry_point; /* Write only for Core Boot */ |
| uint32_t elf_class; |
| } sys_debug_qsee_info_type_t; |
| |
| typedef struct { |
| sys_debug_qsee_info_type_t *qsee_info; |
| uint64_t sdi_entry; /* Read only for Core Boot */ |
| } sbl_rw_ret_info_t; |
| |
| sbl_rw_ret_info_t *sbl_rw_ret_info; |
| |
| int initialize_dram(void) |
| { |
| struct mbn_header *cdt; |
| struct cdt_info cdt_header; |
| uint32_t sw_entry; |
| /* |
| * FIXME: Hard coding the address. Have to somehow get it |
| * automatically |
| */ |
| void *tzbsp = (uint8_t *)0x87e80000; |
| |
| sbl_rw_ret_info_t (*(*ddr_init_function)(struct cdt_info *cdt_header)); |
| |
| cdt = load_ipq_blob(CONFIG_CDT_MBN); |
| ddr_init_function = load_ipq_blob(CONFIG_DDR_MBN); |
| |
| if (!cdt || !ddr_init_function) { |
| printk(BIOS_ERR, "cdt: %p, ddr_init_function: %p\n", |
| cdt, ddr_init_function); |
| die("could not find DDR initialization blobs\n"); |
| } |
| |
| cdt_header.size = cdt->mbn_total_size; |
| cdt_header.cdt_ptr = (uint8_t *)(cdt + 1); |
| |
| sbl_rw_ret_info = ddr_init_function(&cdt_header); |
| if (sbl_rw_ret_info == NULL) |
| die("Fail to Initialize DDR\n"); |
| |
| /* |
| * Once DDR initializer finished, its version can be found at a fixed |
| * address in SRAM. |
| */ |
| printk(BIOS_INFO, "DDR version %.*s initialized\n", |
| MAX_DDR_VERSION_SIZE, DDR_VERSION()); |
| |
| printk(BIOS_INFO, "SDI Entry: 0x%llx\n", sbl_rw_ret_info->sdi_entry); |
| sw_entry = read32(TCSR_RESET_DEBUG_SW_ENTRY) & 0x1; |
| sw_entry |= (sbl_rw_ret_info->sdi_entry & ~0x1); |
| write32(TCSR_RESET_DEBUG_SW_ENTRY, sw_entry); |
| sbl_rw_ret_info->qsee_info->entry_point = (uint32_t)tzbsp; |
| |
| return 0; |
| } |
| |
| void start_tzbsp(void) |
| { |
| void *tzbsp = load_ipq_blob(CONFIG_TZ_MBN); |
| |
| if (!tzbsp) |
| die("could not find or map TZBSP\n"); |
| |
| printk(BIOS_INFO, "Starting TZBSP\n"); |
| |
| tz_init_wrapper(0, 0, tzbsp); |
| |
| } |