Yidi Lin has submitted this change. ( https://review.coreboot.org/c/coreboot/+/85665?usp=email )
Change subject: soc/mediatek: Add support for MediaTek firmware support package ......................................................................
soc/mediatek: Add support for MediaTek firmware support package
Starting from MT8196, MediaTek platform introudces a new blob named MediaTek firmware support package (mtk-fsp). The features of mtk-fsp include but not limit to, - Security settings, e.g: Device Access Proctection Control, Security Memory Protection Unit. - Initialization for advanced CPU frequency control.
This patch implements APIs for 1) Exchanging data between coreboot and mtk-fsp. 2) Loading and running the mtk-fsp blob at a specific bootstage.
BUG=b:373797027 TEST=emerge-rauru coreboot; Run mock blob and return from mock blob.
Change-Id: Idef3518f9763fe5f74adb459c137db164563e483 Signed-off-by: Yidi Lin yidilin@chromium.org Reviewed-on: https://review.coreboot.org/c/coreboot/+/85665 Reviewed-by: Yu-Ping Wu yupingso@google.com Tested-by: build bot (Jenkins) no-reply@coreboot.org --- A src/soc/mediatek/common/include/soc/mtk_fsp.h A src/soc/mediatek/common/include/soc/mtk_fsp_common.h A src/soc/mediatek/common/mtk_fsp.c M src/soc/mediatek/mt8196/Makefile.mk 4 files changed, 184 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Yu-Ping Wu: Looks good to me, approved
diff --git a/src/soc/mediatek/common/include/soc/mtk_fsp.h b/src/soc/mediatek/common/include/soc/mtk_fsp.h new file mode 100644 index 0000000..2e9095f --- /dev/null +++ b/src/soc/mediatek/common/include/soc/mtk_fsp.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTK_FSP_H__ +#define __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTK_FSP_H__ + +#include <soc/mtk_fsp_common.h> + +void mtk_fsp_init(enum fsp_phase phase); +enum cb_err mtk_fsp_add_param(enum fsp_param_type type, size_t param_size, + void *param); +enum cb_err mtk_fsp_load_and_run(void); + +#endif /* __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTK_FSP_H__ */ diff --git a/src/soc/mediatek/common/include/soc/mtk_fsp_common.h b/src/soc/mediatek/common/include/soc/mtk_fsp_common.h new file mode 100644 index 0000000..ea3d46f --- /dev/null +++ b/src/soc/mediatek/common/include/soc/mtk_fsp_common.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef __COMMON_INCLUDE_MTK_FSP_COMMON_H__ +#define __COMMON_INCLUDE_MTK_FSP_COMMON_H__ + +#include <stdarg.h> +#include <stdint.h> + +#define INTF_MAJOR_VER 1 +#define INTF_MINOR_VER 0 + +enum fsp_status { + FSP_STATUS_SUCCESS = 0, + FSP_STATUS_INVALID_VERSION, +}; + +enum fsp_phase { + ROMSTAGE_INIT = 0x30, + RAMSTAGE_MAINBOARD_INIT = 0x40, + RAMSTAGE_SOC_INIT = 0x50, +}; + +enum fsp_param_io { + FSP_PARAM_IO_INVALID = 0, + FSP_PARAM_IO_IN, + FSP_PARAM_IO_OUT, + FSP_PARAM_IO_INOUT, +}; + +#define FSP_PARAM_IO_ENCODE(x) ((uint32_t)(x) << 30) + +enum fsp_param_type { + FSP_PARAM_TYPE_INVALID = 0, + /* 0x40000000+ reserved for input type params */ + FSP_PARAM_TYPE_IN = FSP_PARAM_IO_ENCODE(FSP_PARAM_IO_IN), + + /* 0x80000000+ reserved for output type params */ + FSP_PARAM_TYPE_OUT = FSP_PARAM_IO_ENCODE(FSP_PARAM_IO_OUT), + + /* 0xC0000000+ reserved for the params that support both input and output */ + FSP_PARAM_TYPE_INOUT = FSP_PARAM_IO_ENCODE(FSP_PARAM_IO_INOUT), +}; + +struct mtk_fsp_intf { + uint8_t major_version; + uint8_t minor_version; + uint16_t header_size; + uint32_t phase; /* enum fsp_phase */ + int32_t status; /* enum fsp_status */ + uint16_t entry_size; + uint8_t num_entries; + uint8_t reserved; + int (*do_vprintf)(const char *fmt, va_list args); + struct mtk_fsp_param { + uint32_t param_type; + uint32_t param_size; + void *param; + } entries[]; +}; + +#endif /* __COMMON_INCLUDE_MTK_FSP_COMMON_H__ */ diff --git a/src/soc/mediatek/common/mtk_fsp.c b/src/soc/mediatek/common/mtk_fsp.c new file mode 100644 index 0000000..bc1b5d5 --- /dev/null +++ b/src/soc/mediatek/common/mtk_fsp.c @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cbfs.h> +#include <console/console.h> +#include <soc/mtk_fsp.h> + +#define MAX_PARAM_ENTRIES 32 +#define FSP_INTF_SIZE (sizeof(struct mtk_fsp_intf) + \ + sizeof(struct mtk_fsp_param) * MAX_PARAM_ENTRIES) + +static struct mtk_fsp_intf *intf; +static uint8_t fsp_intf_buf[FSP_INTF_SIZE] __aligned(8); + +static int vprintf_wrapper(const char *fmt, va_list args) +{ + return vprintk(BIOS_INFO, fmt, args); +} + +void mtk_fsp_init(enum fsp_phase phase) +{ + intf = (struct mtk_fsp_intf *)fsp_intf_buf; + intf->major_version = INTF_MAJOR_VER; + intf->minor_version = INTF_MINOR_VER; + intf->header_size = sizeof(struct mtk_fsp_intf); + intf->entry_size = sizeof(struct mtk_fsp_param); + intf->num_entries = 0; + intf->phase = phase; + intf->do_vprintf = vprintf_wrapper; +} + +enum cb_err mtk_fsp_add_param(enum fsp_param_type type, size_t param_size, + void *param) +{ + struct mtk_fsp_param *entry; + + if (!intf) { + printk(BIOS_ERR, "%s: intf is not initialized\n", __func__); + return CB_ERR; + } + + if (intf->num_entries == MAX_PARAM_ENTRIES) { + printk(BIOS_ERR, "%s: run out all entries\n", __func__); + return CB_ERR; + } + + entry = &intf->entries[intf->num_entries]; + + entry->param_type = type; + entry->param_size = param_size; + entry->param = param; + intf->num_entries++; + + return CB_SUCCESS; +} + +static void mtk_fsp_dump_intf(void) +{ + struct mtk_fsp_param *entry; + + if (!intf) { + printk(BIOS_ERR, "%s: intf is not initialized\n", __func__); + return; + } + + printk(BIOS_DEBUG, "%s: major version: %u, minor version: %u\n", + __func__, intf->major_version, intf->minor_version); + printk(BIOS_DEBUG, "%s: FSP phase: %u, status: %d\n", + __func__, intf->phase, intf->status); + printk(BIOS_DEBUG, "%-5s %-10s %-10s %s\n", "Param", "type", "size", "address"); + for (int i = 0; i < intf->num_entries; i++) { + entry = &intf->entries[i]; + printk(BIOS_DEBUG, "%-5u %-10u %-10u %p\n", + i, entry->param_type, entry->param_size, entry->param); + } +} + +static const char *mtk_fsp_file(void) +{ + return CONFIG_CBFS_PREFIX "/mtk_fsp_" ENV_STRING; +} + +enum cb_err mtk_fsp_load_and_run(void) +{ + struct prog fsp = PROG_INIT(PROG_REFCODE, mtk_fsp_file()); + + if (cbfs_prog_stage_load(&fsp)) { + printk(BIOS_ERR, "%s: CBFS load program failed\n", __func__); + return CB_ERR; + } + + if (!intf) { + printk(BIOS_ERR, "%s: intf is not initialized\n", __func__); + return CB_ERR; + } + + prog_set_arg(&fsp, intf); + prog_run(&fsp); + + if (intf->status != FSP_STATUS_SUCCESS) { + mtk_fsp_dump_intf(); + return CB_ERR; + } + + printk(BIOS_INFO, "%s: run %s at phase %#x done\n", + __func__, mtk_fsp_file(), intf->phase); + + return CB_SUCCESS; +} diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index a9ed31d..e09ea3a 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -34,6 +34,7 @@ romstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c romstage-y += ../common/mt6363.c mt6363.c romstage-y += ../common/mt6373.c mt6373.c +romstage-y += ../common/mtk_fsp.c romstage-y += mtk_pwrsel.c romstage-y += ../common/pmif_clk.c pmif_clk.c romstage-y += ../common/pmif.c pmif_init.c @@ -52,6 +53,7 @@ ramstage-y += ../common/mt6363.c mt6363.c ramstage-y += ../common/mt6363_sdmadc.c ramstage-y += ../common/mt6373.c mt6373.c +ramstage-y += ../common/mtk_fsp.c ramstage-y += soc.c ramstage-y += ../common/spm.c spm.c ramstage-y += ../common/sspm.c sspm_sram.c