Hello T Michael Turney,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/32288
to review the following change.
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
qualcomm: Add QCLib interface support to common/
Change-Id: I38d086c379a3c2f54d1603a2fed5b33860f7f4d7 Signed-off-by: T Michael Turney mturney@codeaurora.org --- A src/soc/qualcomm/common/Kconfig A src/soc/qualcomm/common/include/soc/mmu_common.h A src/soc/qualcomm/common/include/soc/qclib_common.h A src/soc/qualcomm/common/include/soc/symbols_common.h A src/soc/qualcomm/common/mmu.c A src/soc/qualcomm/common/qclib.c 6 files changed, 402 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/88/32288/1
diff --git a/src/soc/qualcomm/common/Kconfig b/src/soc/qualcomm/common/Kconfig new file mode 100644 index 0000000..f3d1262 --- /dev/null +++ b/src/soc/qualcomm/common/Kconfig @@ -0,0 +1,5 @@ + +config QC_SDI_ENABLE + bool + default n + prompt "Debug Build: enable SDI" diff --git a/src/soc/qualcomm/common/include/soc/mmu_common.h b/src/soc/qualcomm/common/include/soc/mmu_common.h new file mode 100644 index 0000000..803c4f3 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/mmu_common.h @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_MMU_COMMON_H_ +#define _SOC_QUALCOMM_MMU_COMMON_H_ + +#include <commonlib/region.h> +#include <soc/symbols_common.h> + +#define CACHED_RAM (MA_MEM | MA_S | MA_RW) +#define UNCACHED_RAM (MA_MEM | MA_S | MA_RW | MA_MEM_NC) +#define DEV_MEM (MA_DEV | MA_S | MA_RW) + +static struct region * const ddr_region = (struct region *)_ddr_information; + +void soc_mmu_dram_config_post_dram_init(void); +void qc_mmu_dram_config_post_dram_init(void *ddr_base, size_t ddr_size); + +#endif // _SOC_QUALCOMM_MMU_COMMON_H_ diff --git a/src/soc/qualcomm/common/include/soc/qclib_common.h b/src/soc/qualcomm/common/include/soc/qclib_common.h new file mode 100644 index 0000000..08f9d4a --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/qclib_common.h @@ -0,0 +1,81 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_QCLIB_COMMON_H__ +#define _SOC_QUALCOMM_QCLIB_COMMON_H__ + +#include <fmap.h> + +/* coreboot & QCLib I/F definitions */ + +/* string field lengths */ +#define QCLIB_MAGIC_NUMBER_LENGTH 8 +#define QCLIB_FMAP_NAME_LENGTH 24 +#define QCLIB_TE_NAME_LENGTH 24 + +/* FMAP_REGION names */ +#define QCLIB_FR_DDR_TRAINING_DATA "RO_DDR_TRAINING" +#define QCLIB_FR_LIMITS_CFG_DATA "RO_LIMITS_CFG" + +/* TE_NAME (table entry name) */ +#define QCLIB_TE_DDR_INFORMATION "ddr_information" +#define QCLIB_TE_QCLIB_LOG_BUFFER "qclib_log_buffer" +#define QCLIB_TE_DCB_SETTINGS "dcb_settings" +#define QCLIB_TE_CDT_SETTINGS "cdt_settings" +#define QCLIB_TE_PMIC_SETTINGS "pmic_settings" +#define QCLIB_TE_DDR_TRAINING_DATA "ddr_training_data" +#define QCLIB_TE_LIMITS_CFG_DATA "limits_cfg_data" +#define QCLIB_TE_QCSDI "qcsdi" + +/* BA_BMASK_VALUES (blob_attributes bit mask values) */ +#define QCLIB_BA_SAVE_TO_STORAGE 0x00000001 + +struct qclib_cb_if_table_entry { + char name[QCLIB_TE_NAME_LENGTH]; /* 0x00 TE_NAME */ + uint64_t blob_address; /* 0x18 blob addr in SRAM */ + uint32_t size; /* 0x20 blob size in SRAM */ + uint32_t blob_attributes; /* 0x24 BA_BMASK_VALUES */ +}; + +/* GA_BMASK_VALUES (global_attributes bit mask values) */ +#define QCLIB_GA_ENABLE_UART_LOGGING 0x00000001 + +#define QCLIB_INTERFACE_VERSION 0x00000001 +#define QCLIB_MAX_NUMBER_OF_ENTRIES 16 + +#define QCLIB_MAGIC_NUMBER "QCLIB_CB" + +struct qclib_cb_if_table { + char magic[8]; /* 0x00 */ + uint32_t version; /* 0x08 */ + uint32_t num_entries; /* 0x0C */ + uint32_t max_entries; /* 0x10 */ + uint32_t global_attributes; /* 0x14 */ + uint64_t reserved; /* 0x18 */ + struct qclib_cb_if_table_entry + te[QCLIB_MAX_NUMBER_OF_ENTRIES]; /* 0x20 */ +}; + +extern struct qclib_cb_if_table qclib_cb_if_table; + +void add_if_table_entry(const char *, void *, uint32_t, uint32_t); +void write_ddr_information(struct qclib_cb_if_table_entry *); +void write_qclib_log_to_cbmemc(struct qclib_cb_if_table_entry *); +void write_table_entry(struct qclib_cb_if_table_entry *); +void dump_te_table(void); +void qclib_load_and_run(void); +void soc_blob_load(void); + +#endif // _SOC_QUALCOMM_QCLIB_COMMON_H_ diff --git a/src/soc/qualcomm/common/include/soc/symbols_common.h b/src/soc/qualcomm/common/include/soc/symbols_common.h new file mode 100644 index 0000000..ffa535c --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/symbols_common.h @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_SYMBOLS_COMMON_H_ +#define _SOC_QUALCOMM_SYMBOLS_COMMON_H_ + +#include <symbols.h> + +DECLARE_REGION(ddr_training); +DECLARE_REGION(qclib_serial_log); +DECLARE_REGION(ddr_information); + +#endif // _SOC_QUALCOMM_SYMBOLS_COMMON_H_ diff --git a/src/soc/qualcomm/common/mmu.c b/src/soc/qualcomm/common/mmu.c new file mode 100644 index 0000000..79d2eb7 --- /dev/null +++ b/src/soc/qualcomm/common/mmu.c @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/mmu.h> +#include <soc/mmu.h> +#include <soc/mmu_common.h> + +__weak void soc_mmu_dram_config_post_dram_init(void) { /* no-op */ } + +void qc_mmu_dram_config_post_dram_init(void *ddr_base, size_t ddr_size) +{ + mmu_config_range((void *)ddr_base, ddr_size, CACHED_RAM); + soc_mmu_dram_config_post_dram_init(); +} diff --git a/src/soc/qualcomm/common/qclib.c b/src/soc/qualcomm/common/qclib.c new file mode 100644 index 0000000..9feca05 --- /dev/null +++ b/src/soc/qualcomm/common/qclib.c @@ -0,0 +1,234 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/cbmem_console.h> +#include <cbmem.h> +#include <boardid.h> +#include <fmap.h> +#include <assert.h> +#include <arch/mmu.h> +#include <cbfs.h> +#include <console/console.h> +#include <soc/mmu.h> +#include <soc/mmu_common.h> +#include <soc/qclib_common.h> +#include <soc/symbols_common.h> + +#define QCLIB_NAME "/qclib" +#define QCSDI_NAME "/qcsdi" + +struct qclib_cb_if_table qclib_cb_if_table = { + .magic = QCLIB_MAGIC_NUMBER, + .version = QCLIB_INTERFACE_VERSION, + .num_entries = 0, + .max_entries = QCLIB_MAX_NUMBER_OF_ENTRIES, + .global_attributes = 0, + .reserved = 0, +}; + +void add_if_table_entry(const char *name, void *base, + uint32_t size, uint32_t attrs) +{ + struct qclib_cb_if_table_entry *te = + &qclib_cb_if_table.te[qclib_cb_if_table.num_entries++]; + assert(qclib_cb_if_table.num_entries <= qclib_cb_if_table.max_entries); + strncpy(te->name, name, sizeof(te->name)); + te->blob_address = (uintptr_t)base; + te->size = size; + te->blob_attributes = attrs; +} + +void write_ddr_information(struct qclib_cb_if_table_entry *te) +{ + uint64_t ddr_size; + + /* Save DDR info in SRAM region to share with ramstage */ + ddr_region->offset = te->blob_address; + ddr_size = te->size; + ddr_region->size = ddr_size * MiB; + + /* Use DDR info to configure MMU */ + qc_mmu_dram_config_post_dram_init((void *)ddr_region->offset, + (size_t)ddr_region->size); +} + +void write_qclib_log_to_cbmemc(struct qclib_cb_if_table_entry *te) +{ + int i; + char *ptr = (char *)te->blob_address; + + for (i = 0; i < te->size; i++) + cbmemc_tx_byte(*ptr++); +} + +void write_table_entry(struct qclib_cb_if_table_entry *te) +{ + printk(BIOS_INFO, "[%s]:[%s]\n", __func__, te->name); + + if (!strncmp(QCLIB_TE_DDR_INFORMATION, te->name, + sizeof(te->name))) { + + write_ddr_information(te); + + } else if (!strncmp(QCLIB_TE_DDR_TRAINING_DATA, te->name, + sizeof(te->name))) { + + assert(fmap_overwrite_area(QCLIB_FR_DDR_TRAINING_DATA, + (const void *)te->blob_address, te->size)); + + } else if (!strncmp(QCLIB_TE_LIMITS_CFG_DATA, te->name, + sizeof(te->name))) { + + assert(fmap_overwrite_area(QCLIB_FR_LIMITS_CFG_DATA, + (const void *)te->blob_address, te->size)); + + } else if (!strncmp(QCLIB_TE_QCLIB_LOG_BUFFER, te->name, + sizeof(te->name))) { + + write_qclib_log_to_cbmemc(te); + + } else { + + printk(BIOS_INFO, " not implemented\n"); + printk(BIOS_INFO, " blob_address[%llx]..size[%x]\n", + te->blob_address, te->size); + + } +} + +void dump_te_table(void) +{ + struct qclib_cb_if_table_entry *te; + int i; + + for (i = 0; i < qclib_cb_if_table.num_entries; i++) { + te = &qclib_cb_if_table.te[i]; + printk(BIOS_INFO, "[%s][%llx][%x][%x]\n", + te->name, te->blob_address, + te->size, te->blob_attributes); + } +} + +__weak void soc_blob_load(void) { /* no-op */ } + +void qclib_load_and_run(void) +{ + int (*doit)(void *param1, void *param2); + void *arg; + int i, ret_code; + size_t size; + struct mmu_context pre_qclib_mmu_context; + + /* print board Rev */ + printk(BIOS_INFO, "Board Rev(0x%x)\n", board_id()); + + /* zero ddr_information SRAM region, needs new data each boot */ + memset(ddr_region, 0, sizeof(struct region)); + + /* output area, QCLib copies console log buffer out */ + if (IS_ENABLED(CONFIG_CONSOLE_CBMEM)) + add_if_table_entry(QCLIB_TE_QCLIB_LOG_BUFFER, _qclib_serial_log, + REGION_SIZE(qclib_serial_log), 0); + + /* output area, QCLib fills in DDR details */ + add_if_table_entry(QCLIB_TE_DDR_INFORMATION, 0, 0, 0); + + /* Attempt to load DDR Training Blob */ + size = fmap_read_area(QCLIB_FR_DDR_TRAINING_DATA, _ddr_training, + REGION_SIZE(ddr_training)); + if (size < 0) + goto fail; + add_if_table_entry(QCLIB_TE_DDR_TRAINING_DATA, _ddr_training, size, 0); + + /* hook for SoC specific binary blob loads */ + soc_blob_load(); + + /* Enable QCLib serial output, based on Kconfig */ + if (IS_ENABLED(CONFIG_CONSOLE_SERIAL)) + qclib_cb_if_table.global_attributes = + QCLIB_GA_ENABLE_UART_LOGGING; + + if (IS_ENABLED(CONFIG_QC_SDI_ENABLE)) { + struct prog qcsdi = + PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX QCSDI_NAME); + + /* Attempt to load QCSDI elf */ + if (prog_locate(&qcsdi)) + goto fail; + + if (cbfs_prog_stage_load(&qcsdi)) + goto fail; + + add_if_table_entry(QCLIB_TE_QCSDI, qcsdi.entry, + prog_size(&qcsdi), 0); + printk(BIOS_INFO, "qcsdi.entry[%llx]\n", (uint64_t)qcsdi.entry); + } + + dump_te_table(); + + /* Attempt to load QCLib elf */ + struct prog qclib = + PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX QCLIB_NAME); + + if (prog_locate(&qclib)) + goto fail; + + if (cbfs_prog_stage_load(&qclib)) + goto fail; + + prog_set_entry(&qclib, qclib.entry, NULL); + + printk(BIOS_DEBUG, "\n\n\nQCLib is about to Initialize Private IP\n"); + printk(BIOS_DEBUG, "Global Attributes[%x]..Table Entries Count[%d]\n", + qclib_cb_if_table.global_attributes, + qclib_cb_if_table.num_entries); + printk(BIOS_DEBUG, "Jumping to QCLib code at %p(%p)\n", + prog_entry(&qclib), prog_entry_arg(&qclib)); + + doit = prog_entry(&qclib); + arg = prog_entry_arg(&qclib); + + /* back-up mmu context before disabling mmu and executing qclib */ + mmu_save_context(&pre_qclib_mmu_context); + /* disable mmu before jumping to qclib. mmu_disable also + flushes and invalidates caches before disabling mmu. */ + mmu_disable(); + + ret_code = doit(&qclib_cb_if_table, NULL); + + /* Before returning, QCLib flushes cache and disables mmu. + Explicitly disable mmu (flush, invalidate and disable mmu) + before re-enabling mmu with backed-up mmu context */ + mmu_disable(); + mmu_restore_context(&pre_qclib_mmu_context); + mmu_enable(); + + printk(BIOS_DEBUG, "QCLib completed\n\n\n"); + + /* step through I/F table, handling return values */ + for (i = 0; i < qclib_cb_if_table.num_entries; i++) + if (qclib_cb_if_table.te[i].blob_attributes & + QCLIB_BA_SAVE_TO_STORAGE) + write_table_entry(&qclib_cb_if_table.te[i]); + + /* confirm that we received valid ddr information from QCLib */ + assert((uintptr_t)_dram == region_offset(ddr_region) && + region_sz(ddr_region) >= (u8 *)cbmem_top() - _dram); + + return; + +fail: + die("Couldn't run QCLib.\n"); +}
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 1:
(8 comments)
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... File src/soc/qualcomm/common/include/soc/qclib_common.h:
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... PS1, Line 66: uint64_t reserved; /* 0x18 */ please, no space before tabs
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... PS1, Line 73: void add_if_table_entry(const char *, void *, uint32_t, uint32_t); function definition argument 'const char *' should also have an identifier name
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... PS1, Line 73: void add_if_table_entry(const char *, void *, uint32_t, uint32_t); function definition argument 'void *' should also have an identifier name
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... PS1, Line 73: void add_if_table_entry(const char *, void *, uint32_t, uint32_t); function definition argument 'uint32_t' should also have an identifier name
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... PS1, Line 73: void add_if_table_entry(const char *, void *, uint32_t, uint32_t); function definition argument 'uint32_t' should also have an identifier name
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... PS1, Line 74: void write_ddr_information(struct qclib_cb_if_table_entry *); function definition argument 'struct qclib_cb_if_table_entry *' should also have an identifier name
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... PS1, Line 75: void write_qclib_log_to_cbmemc(struct qclib_cb_if_table_entry *); function definition argument 'struct qclib_cb_if_table_entry *' should also have an identifier name
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/include/soc/... PS1, Line 76: void write_table_entry(struct qclib_cb_if_table_entry *); function definition argument 'struct qclib_cb_if_table_entry *' should also have an identifier name
Julius Werner has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/mmu.c File src/soc/qualcomm/common/mmu.c:
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/mmu.c@20 PS1, Line 20: __weak void soc_mmu_dram_config_post_dram_init(void) { /* no-op */ } Does any SoC we have for now actually need this? If not, let keep it out for now... we can always add hooks later as necessary.
mturney mturney has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/mmu.c File src/soc/qualcomm/common/mmu.c:
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/mmu.c@20 PS1, Line 20: __weak void soc_mmu_dram_config_post_dram_init(void) { /* no-op */ }
Does any SoC we have for now actually need this? If not, let keep it out for now... […]
Every SoC that initializes DRAM has this requirement. This has been slightly refactored in patch I'm working on now.
T Michael Turney has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 1:
(1 comment)
Next update 19.April.2019 should address all comments on this patch.
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/mmu.c File src/soc/qualcomm/common/mmu.c:
https://review.coreboot.org/#/c/32288/1/src/soc/qualcomm/common/mmu.c@20 PS1, Line 20: __weak void soc_mmu_dram_config_post_dram_init(void) { /* no-op */ }
Every SoC that initializes DRAM has this requirement. […]
Done
Hello T Michael Turney, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/32288
to look at the new patch set (#2).
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
qualcomm: Add QCLib interface support to common/
Change-Id: I38d086c379a3c2f54d1603a2fed5b33860f7f4d7 Signed-off-by: T Michael Turney mturney@codeaurora.org --- A src/soc/qualcomm/common/Kconfig A src/soc/qualcomm/common/include/soc/mmu_common.h A src/soc/qualcomm/common/include/soc/qclib_common.h A src/soc/qualcomm/common/include/soc/symbols_common.h A src/soc/qualcomm/common/mmu.c A src/soc/qualcomm/common/qclib.c 6 files changed, 392 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/88/32288/2
Julius Werner has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 2:
(8 comments)
Thanks, I think this is pretty much done... but please clean up all the Jenkins errors as well.
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/include/soc/... File src/soc/qualcomm/common/include/soc/mmu_common.h:
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/include/soc/... PS2, Line 31: // _SOC_QUALCOMM_MMU_COMMON_H_ Please always use /* C89 comments */ in coreboot.
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/include/soc/... File src/soc/qualcomm/common/include/soc/qclib_common.h:
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/include/soc/... PS2, Line 19: #include <fmap.h> nit: I think this is only needed in the .c file?
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c File src/soc/qualcomm/common/qclib.c:
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@140 PS2, Line 140: 0 nit: technically, this one should be NULL, not 0
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@151 PS2, Line 151: WARNING nit: anything that makes DDR init fail should probably at least be ERROR
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@157 PS2, Line 157: qclib_cb_if_table.global_attributes = nit: let's write this as |= just in case we add new code for other attributes above later
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@162 PS2, Line 162: nit: it's odd to have a tab here, is that intentional?
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@171 PS2, Line 171: qcsdi.entry nit: use prog_entry(&qcsdi) (below as well, and for &qclib)
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@215 PS2, Line 215: QCLIB_BA_SAVE_TO_STORAGE) nit: indent this continuation line one more tab so it's clearer to distinguish from the if-body below
T Michael Turney has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 2:
(9 comments)
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/include/soc/... File src/soc/qualcomm/common/include/soc/qclib_common.h:
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/include/soc/... PS2, Line 19: #include <fmap.h>
nit: I think this is only needed in the . […]
Ack
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c File src/soc/qualcomm/common/qclib.c:
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@136 PS2, Line 136: qclib_add_if_table_entry(QCLIB_TE_QCLIB_LOG_BUFFER, _qclib_serial_log,
line over 80 characters
Ack
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@140 PS2, Line 140: 0
nit: technically, this one should be NULL, not 0
Ack
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@147 PS2, Line 147: qclib_add_if_table_entry(QCLIB_TE_DDR_TRAINING_DATA, _ddr_training, size, 0);
line over 80 characters
Ack
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@151 PS2, Line 151: WARNING
nit: anything that makes DDR init fail should probably at least be ERROR
Ack
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@157 PS2, Line 157: qclib_cb_if_table.global_attributes =
nit: let's write this as |= just in case we add new code for other attributes above later
Ack
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@162 PS2, Line 162:
nit: it's odd to have a tab here, is that intentional?
Ack
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@171 PS2, Line 171: qcsdi.entry
nit: use prog_entry(&qcsdi) (below as well, and for &qclib)
Ack
https://review.coreboot.org/#/c/32288/2/src/soc/qualcomm/common/qclib.c@215 PS2, Line 215: QCLIB_BA_SAVE_TO_STORAGE)
nit: indent this continuation line one more tab so it's clearer to distinguish from the if-body belo […]
Ack
Hello T Michael Turney, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/32288
to look at the new patch set (#3).
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
qualcomm: Add QCLib interface support to common/
Change-Id: I38d086c379a3c2f54d1603a2fed5b33860f7f4d7 Signed-off-by: T Michael Turney mturney@codeaurora.org --- A src/soc/qualcomm/common/Kconfig A src/soc/qualcomm/common/include/soc/mmu_common.h A src/soc/qualcomm/common/include/soc/qclib_common.h A src/soc/qualcomm/common/include/soc/symbols_common.h A src/soc/qualcomm/common/mmu.c A src/soc/qualcomm/common/qclib.c 6 files changed, 393 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/88/32288/3
Julius Werner has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 4: Code-Review+2
Julius Werner has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 4: -Code-Review
(3 comments)
Sorry, found one more thing that's an actual bug.
https://review.coreboot.org/#/c/32288/4/src/soc/qualcomm/common/qclib.c File src/soc/qualcomm/common/qclib.c:
https://review.coreboot.org/#/c/32288/4/src/soc/qualcomm/common/qclib.c@30 PS4, Line 30: #define QCSDI_NAME "/qcsdi" nit: change these to be inline as well now?
https://review.coreboot.org/#/c/32288/4/src/soc/qualcomm/common/qclib.c@128 PS4, Line 128: size_t size; Oh, wait, actually, this is bad. This must be ssize_t. Otherwise all your < 0 checks are gonna have a bad time.
https://review.coreboot.org/#/c/32288/4/src/soc/qualcomm/common/qclib.c@175 PS4, Line 175: (uint64_t) nit: could just use %p and avoid the cast
T Michael Turney has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 4:
(3 comments)
https://review.coreboot.org/#/c/32288/4/src/soc/qualcomm/common/qclib.c File src/soc/qualcomm/common/qclib.c:
https://review.coreboot.org/#/c/32288/4/src/soc/qualcomm/common/qclib.c@30 PS4, Line 30: #define QCSDI_NAME "/qcsdi"
nit: change these to be inline as well now?
Ack
https://review.coreboot.org/#/c/32288/4/src/soc/qualcomm/common/qclib.c@128 PS4, Line 128: size_t size;
Oh, wait, actually, this is bad. This must be ssize_t. […]
Ack
https://review.coreboot.org/#/c/32288/4/src/soc/qualcomm/common/qclib.c@175 PS4, Line 175: (uint64_t)
nit: could just use %p and avoid the cast
Ack
Hello T Michael Turney, Julius Werner, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/32288
to look at the new patch set (#5).
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
qualcomm: Add QCLib interface support to common/
Change-Id: I38d086c379a3c2f54d1603a2fed5b33860f7f4d7 Signed-off-by: T Michael Turney mturney@codeaurora.org --- A src/soc/qualcomm/common/Kconfig A src/soc/qualcomm/common/include/soc/mmu_common.h A src/soc/qualcomm/common/include/soc/qclib_common.h A src/soc/qualcomm/common/include/soc/symbols_common.h A src/soc/qualcomm/common/mmu.c A src/soc/qualcomm/common/qclib.c 6 files changed, 390 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/88/32288/5
Julius Werner has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
Patch Set 5: Code-Review+2
Julius Werner has submitted this change and it was merged. ( https://review.coreboot.org/c/coreboot/+/32288 )
Change subject: qualcomm: Add QCLib interface support to common/ ......................................................................
qualcomm: Add QCLib interface support to common/
Change-Id: I38d086c379a3c2f54d1603a2fed5b33860f7f4d7 Signed-off-by: T Michael Turney mturney@codeaurora.org Reviewed-on: https://review.coreboot.org/c/coreboot/+/32288 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Julius Werner jwerner@chromium.org --- A src/soc/qualcomm/common/Kconfig A src/soc/qualcomm/common/include/soc/mmu_common.h A src/soc/qualcomm/common/include/soc/qclib_common.h A src/soc/qualcomm/common/include/soc/symbols_common.h A src/soc/qualcomm/common/mmu.c A src/soc/qualcomm/common/qclib.c 6 files changed, 390 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Julius Werner: Looks good to me, approved
diff --git a/src/soc/qualcomm/common/Kconfig b/src/soc/qualcomm/common/Kconfig new file mode 100644 index 0000000..f3d1262 --- /dev/null +++ b/src/soc/qualcomm/common/Kconfig @@ -0,0 +1,5 @@ + +config QC_SDI_ENABLE + bool + default n + prompt "Debug Build: enable SDI" diff --git a/src/soc/qualcomm/common/include/soc/mmu_common.h b/src/soc/qualcomm/common/include/soc/mmu_common.h new file mode 100644 index 0000000..ee78122 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/mmu_common.h @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_MMU_COMMON_H_ +#define _SOC_QUALCOMM_MMU_COMMON_H_ + +#include <commonlib/region.h> +#include <soc/symbols_common.h> + +#define CACHED_RAM (MA_MEM | MA_S | MA_RW) +#define UNCACHED_RAM (MA_MEM | MA_S | MA_RW | MA_MEM_NC) +#define DEV_MEM (MA_DEV | MA_S | MA_RW) + +static struct region * const ddr_region = (struct region *)_ddr_information; + +void soc_mmu_dram_config_post_dram_init(void); +void qc_mmu_dram_config_post_dram_init(void *ddr_base, size_t ddr_size); + +#endif /* _SOC_QUALCOMM_MMU_COMMON_H_ */ diff --git a/src/soc/qualcomm/common/include/soc/qclib_common.h b/src/soc/qualcomm/common/include/soc/qclib_common.h new file mode 100644 index 0000000..19ec083 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/qclib_common.h @@ -0,0 +1,76 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_QCLIB_COMMON_H__ +#define _SOC_QUALCOMM_QCLIB_COMMON_H__ + +/* coreboot & QCLib I/F definitions */ + +/* string field lengths */ +#define QCLIB_MAGIC_NUMBER_LENGTH 8 +#define QCLIB_FMAP_NAME_LENGTH 24 +#define QCLIB_TE_NAME_LENGTH 24 + +/* FMAP_REGION names */ +#define QCLIB_FR_DDR_TRAINING_DATA "RO_DDR_TRAINING" +#define QCLIB_FR_LIMITS_CFG_DATA "RO_LIMITS_CFG" + +/* TE_NAME (table entry name) */ +#define QCLIB_TE_DDR_INFORMATION "ddr_information" +#define QCLIB_TE_QCLIB_LOG_BUFFER "qclib_log_buffer" +#define QCLIB_TE_DCB_SETTINGS "dcb_settings" +#define QCLIB_TE_CDT_SETTINGS "cdt_settings" +#define QCLIB_TE_PMIC_SETTINGS "pmic_settings" +#define QCLIB_TE_DDR_TRAINING_DATA "ddr_training_data" +#define QCLIB_TE_LIMITS_CFG_DATA "limits_cfg_data" +#define QCLIB_TE_QCSDI "qcsdi" + +/* BA_BMASK_VALUES (blob_attributes bit mask values) */ +#define QCLIB_BA_SAVE_TO_STORAGE 0x00000001 + +struct qclib_cb_if_table_entry { + char name[QCLIB_TE_NAME_LENGTH]; /* 0x00 TE_NAME */ + uint64_t blob_address; /* 0x18 blob addr in SRAM */ + uint32_t size; /* 0x20 blob size in SRAM */ + uint32_t blob_attributes; /* 0x24 BA_BMASK_VALUES */ +}; + +/* GA_BMASK_VALUES (global_attributes bit mask values) */ +#define QCLIB_GA_ENABLE_UART_LOGGING 0x00000001 + +#define QCLIB_INTERFACE_VERSION 0x00000001 +#define QCLIB_MAX_NUMBER_OF_ENTRIES 16 + +#define QCLIB_MAGIC_NUMBER "QCLIB_CB" + +struct qclib_cb_if_table { + char magic[8]; /* 0x00 */ + uint32_t version; /* 0x08 */ + uint32_t num_entries; /* 0x0C */ + uint32_t max_entries; /* 0x10 */ + uint32_t global_attributes; /* 0x14 */ + uint64_t reserved; /* 0x18 */ + struct qclib_cb_if_table_entry + te[QCLIB_MAX_NUMBER_OF_ENTRIES]; /* 0x20 */ +}; + +extern struct qclib_cb_if_table qclib_cb_if_table; + +void qclib_add_if_table_entry(const char *name, void *base, + uint32_t size, uint32_t attrs); +void qclib_load_and_run(void); +int qclib_soc_blob_load(void); + +#endif // _SOC_QUALCOMM_QCLIB_COMMON_H_ diff --git a/src/soc/qualcomm/common/include/soc/symbols_common.h b/src/soc/qualcomm/common/include/soc/symbols_common.h new file mode 100644 index 0000000..ffa535c --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/symbols_common.h @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_SYMBOLS_COMMON_H_ +#define _SOC_QUALCOMM_SYMBOLS_COMMON_H_ + +#include <symbols.h> + +DECLARE_REGION(ddr_training); +DECLARE_REGION(qclib_serial_log); +DECLARE_REGION(ddr_information); + +#endif // _SOC_QUALCOMM_SYMBOLS_COMMON_H_ diff --git a/src/soc/qualcomm/common/mmu.c b/src/soc/qualcomm/common/mmu.c new file mode 100644 index 0000000..79d2eb7 --- /dev/null +++ b/src/soc/qualcomm/common/mmu.c @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/mmu.h> +#include <soc/mmu.h> +#include <soc/mmu_common.h> + +__weak void soc_mmu_dram_config_post_dram_init(void) { /* no-op */ } + +void qc_mmu_dram_config_post_dram_init(void *ddr_base, size_t ddr_size) +{ + mmu_config_range((void *)ddr_base, ddr_size, CACHED_RAM); + soc_mmu_dram_config_post_dram_init(); +} diff --git a/src/soc/qualcomm/common/qclib.c b/src/soc/qualcomm/common/qclib.c new file mode 100644 index 0000000..1fd79b5 --- /dev/null +++ b/src/soc/qualcomm/common/qclib.c @@ -0,0 +1,227 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/cbmem_console.h> +#include <cbmem.h> +#include <boardid.h> +#include <fmap.h> +#include <assert.h> +#include <arch/mmu.h> +#include <cbfs.h> +#include <console/console.h> +#include <soc/mmu.h> +#include <soc/mmu_common.h> +#include <soc/qclib_common.h> +#include <soc/symbols_common.h> + +struct qclib_cb_if_table qclib_cb_if_table = { + .magic = QCLIB_MAGIC_NUMBER, + .version = QCLIB_INTERFACE_VERSION, + .num_entries = 0, + .max_entries = QCLIB_MAX_NUMBER_OF_ENTRIES, + .global_attributes = 0, + .reserved = 0, +}; + +void qclib_add_if_table_entry(const char *name, void *base, + uint32_t size, uint32_t attrs) +{ + struct qclib_cb_if_table_entry *te = + &qclib_cb_if_table.te[qclib_cb_if_table.num_entries++]; + assert(qclib_cb_if_table.num_entries <= qclib_cb_if_table.max_entries); + strncpy(te->name, name, sizeof(te->name)); + te->blob_address = (uintptr_t)base; + te->size = size; + te->blob_attributes = attrs; +} + +static void write_ddr_information(struct qclib_cb_if_table_entry *te) +{ + uint64_t ddr_size; + + /* Save DDR info in SRAM region to share with ramstage */ + ddr_region->offset = te->blob_address; + ddr_size = te->size; + ddr_region->size = ddr_size * MiB; + + /* Use DDR info to configure MMU */ + qc_mmu_dram_config_post_dram_init((void *)ddr_region->offset, + (size_t)ddr_region->size); +} + +static void write_qclib_log_to_cbmemc(struct qclib_cb_if_table_entry *te) +{ + int i; + char *ptr = (char *)te->blob_address; + + for (i = 0; i < te->size; i++) + __cbmemc_tx_byte(*ptr++); +} + +static void write_table_entry(struct qclib_cb_if_table_entry *te) +{ + + if (!strncmp(QCLIB_TE_DDR_INFORMATION, te->name, + sizeof(te->name))) { + + write_ddr_information(te); + + } else if (!strncmp(QCLIB_TE_DDR_TRAINING_DATA, te->name, + sizeof(te->name))) { + + assert(fmap_overwrite_area(QCLIB_FR_DDR_TRAINING_DATA, + (const void *)te->blob_address, te->size)); + + } else if (!strncmp(QCLIB_TE_LIMITS_CFG_DATA, te->name, + sizeof(te->name))) { + + assert(fmap_overwrite_area(QCLIB_FR_LIMITS_CFG_DATA, + (const void *)te->blob_address, te->size)); + + } else if (!strncmp(QCLIB_TE_QCLIB_LOG_BUFFER, te->name, + sizeof(te->name))) { + + write_qclib_log_to_cbmemc(te); + + } else { + + printk(BIOS_WARNING, "%s write not implemented\n", te->name); + printk(BIOS_WARNING, " blob_address[%llx]..size[%x]\n", + te->blob_address, te->size); + + } +} + +static void dump_te_table(void) +{ + struct qclib_cb_if_table_entry *te; + int i; + + for (i = 0; i < qclib_cb_if_table.num_entries; i++) { + te = &qclib_cb_if_table.te[i]; + printk(BIOS_DEBUG, "[%s][%llx][%x][%x]\n", + te->name, te->blob_address, + te->size, te->blob_attributes); + } +} + +__weak int qclib_soc_blob_load(void) { return 0; } + +void qclib_load_and_run(void) +{ + int i; + ssize_t ssize; + struct mmu_context pre_qclib_mmu_context; + + /* zero ddr_information SRAM region, needs new data each boot */ + memset(ddr_region, 0, sizeof(struct region)); + + /* output area, QCLib copies console log buffer out */ + if (IS_ENABLED(CONFIG_CONSOLE_CBMEM)) + qclib_add_if_table_entry(QCLIB_TE_QCLIB_LOG_BUFFER, + _qclib_serial_log, + REGION_SIZE(qclib_serial_log), 0); + + /* output area, QCLib fills in DDR details */ + qclib_add_if_table_entry(QCLIB_TE_DDR_INFORMATION, NULL, 0, 0); + + /* Attempt to load DDR Training Blob */ + ssize = fmap_read_area(QCLIB_FR_DDR_TRAINING_DATA, _ddr_training, + REGION_SIZE(ddr_training)); + if (ssize < 0) + goto fail; + qclib_add_if_table_entry(QCLIB_TE_DDR_TRAINING_DATA, + _ddr_training, ssize, 0); + + /* hook for SoC specific binary blob loads */ + if (qclib_soc_blob_load()) { + printk(BIOS_ERR, "qclib_soc_blob_load failed\n"); + goto fail; + } + + /* Enable QCLib serial output, based on Kconfig */ + if (IS_ENABLED(CONFIG_CONSOLE_SERIAL)) + qclib_cb_if_table.global_attributes = + QCLIB_GA_ENABLE_UART_LOGGING; + + if (IS_ENABLED(CONFIG_QC_SDI_ENABLE)) { + struct prog qcsdi = + PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/qcsdi"); + + /* Attempt to load QCSDI elf */ + if (prog_locate(&qcsdi)) + goto fail; + + if (cbfs_prog_stage_load(&qcsdi)) + goto fail; + + qclib_add_if_table_entry(QCLIB_TE_QCSDI, prog_entry(&qcsdi), + prog_size(&qcsdi), 0); + printk(BIOS_INFO, "qcsdi.entry[%p]\n", qcsdi.entry); + } + + dump_te_table(); + + /* Attempt to load QCLib elf */ + struct prog qclib = + PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/qclib"); + + if (prog_locate(&qclib)) + goto fail; + + if (cbfs_prog_stage_load(&qclib)) + goto fail; + + prog_set_entry(&qclib, prog_entry(&qclib), &qclib_cb_if_table); + + printk(BIOS_DEBUG, "\n\n\nQCLib is about to Initialize DDR\n"); + printk(BIOS_DEBUG, "Global Attributes[%x]..Table Entries Count[%d]\n", + qclib_cb_if_table.global_attributes, + qclib_cb_if_table.num_entries); + printk(BIOS_DEBUG, "Jumping to QCLib code at %p(%p)\n", + prog_entry(&qclib), prog_entry_arg(&qclib)); + + /* back-up mmu context before disabling mmu and executing qclib */ + mmu_save_context(&pre_qclib_mmu_context); + /* disable mmu before jumping to qclib. mmu_disable also + flushes and invalidates caches before disabling mmu. */ + mmu_disable(); + + prog_run(&qclib); + + /* Before returning, QCLib flushes cache and disables mmu. + Explicitly disable mmu (flush, invalidate and disable mmu) + before re-enabling mmu with backed-up mmu context */ + mmu_disable(); + mmu_restore_context(&pre_qclib_mmu_context); + mmu_enable(); + + /* step through I/F table, handling return values */ + for (i = 0; i < qclib_cb_if_table.num_entries; i++) + if (qclib_cb_if_table.te[i].blob_attributes & + QCLIB_BA_SAVE_TO_STORAGE) + write_table_entry(&qclib_cb_if_table.te[i]); + + /* confirm that we received valid ddr information from QCLib */ + assert((uintptr_t)_dram == region_offset(ddr_region) && + region_sz(ddr_region) >= (u8 *)cbmem_top() - _dram); + + printk(BIOS_DEBUG, "QCLib completed\n\n\n"); + + return; + +fail: + die("Couldn't run QCLib.\n"); +}