GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,34 @@
#
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# indicate the reset vector address can be programmed
PROGRAMMABLE_RESET_ADDRESS := 1
MULTI_CONSOLE_API := 1
COLD_BOOT_SINGLE_CPU := 1
# Build flag to include AArch32 registers in cpu context save and restore during
# world switch. This flag must be set to 0 for AArch64-only platforms.
CTX_INCLUDE_AARCH32_REGS := 0
PLAT_XLAT_TABLES_DYNAMIC := 1
# enable this definition to print irq dump status in tf-a
GIC_DEBUG := 0
# Enable stack protector.
# Allowed values are "all", "strong", "default" and "none"
ENABLE_STACK_PROTECTOR := strong
# AMU, Kernel will access amuserenr_el0 if PE supported
# Firmware _must_ implement AMU support
ENABLE_AMU := 1
VENDOR_EXTEND_PUBEVENT_ENABLE := 1
# MTK define options
MTK_BL33_IS_64BIT := 0
MTK_ADAPTED := 1
# MTK module config
CONFIG_MTK_INTERRUPT := y
CONFIG_MTK_UART := y
# UART baudrate
UART_BAUDRATE := 921600
@@ -0,0 +1,15 @@
#
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# indicate the reset vector address can be programmed
PROGRAMMABLE_RESET_ADDRESS := 1
COLD_BOOT_SINGLE_CPU := 1
# Build flag to include AArch32 registers in cpu context save and restore during
# world switch. This flag must be set to 0 for AArch64-only platforms.
CTX_INCLUDE_AARCH32_REGS := 0
PLAT_XLAT_TABLES_DYNAMIC := 1
VENDOR_EXTEND_PUBEVENT_ENABLE := 1
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mt_lp_rm.h>
#include <stddef.h>
struct platform_mt_resource_manager {
unsigned int count;
struct mt_resource_manager *plat_rm;
};
static struct platform_mt_resource_manager plat_mt_rm;
int mt_lp_rm_register(struct mt_resource_manager *rm)
{
unsigned int i;
struct mt_resource_constraint *const *rc;
if ((rm == NULL) || (rm->consts == NULL) ||
(plat_mt_rm.plat_rm != NULL)) {
return MT_RM_STATUS_BAD;
}
for (i = 0U, rc = rm->consts; *rc != NULL; i++, rc++) {
if ((*rc)->init != NULL) {
(*rc)->init();
}
}
plat_mt_rm.plat_rm = rm;
plat_mt_rm.count = i;
return MT_RM_STATUS_OK;
}
int mt_lp_rm_reset_constraint(int idx, unsigned int cpuid, int stateid)
{
struct mt_resource_constraint const *rc = NULL;
if ((plat_mt_rm.plat_rm == NULL) || (idx < 0) ||
(idx >= plat_mt_rm.count)) {
return MT_RM_STATUS_BAD;
}
rc = plat_mt_rm.plat_rm->consts[idx];
if ((rc == NULL) || (rc->reset == NULL)) {
return MT_RM_STATUS_BAD;
}
return rc->reset(cpuid, stateid);
}
int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid,
int stateid, void *priv)
{
int i, res = MT_RM_STATUS_BAD;
struct mt_resource_constraint *const *rc;
struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
if ((rm == NULL) || (idx < 0) || (idx >= plat_mt_rm.count)) {
return res;
}
/* If subsys clk/mtcmos is on, add block-resource-off flag */
if (rm->update != NULL) {
res = rm->update(rm->consts, stateid, priv);
if (res != 0) {
return res;
}
}
for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
if (((*rc)->is_valid != NULL) &&
((*rc)->is_valid(cpuid, stateid))) {
if (((*rc)->run != NULL) &&
((*rc)->run(cpuid, stateid) == 0)) {
res = i;
break;
}
}
}
return res;
}
int mt_lp_rm_do_update(int stateid, int type, void const *p)
{
int res = MT_RM_STATUS_BAD;
struct mt_resource_constraint *const *rc;
struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
if (rm == NULL) {
return res;
}
for (rc = rm->consts; *rc != NULL; rc++) {
if ((*rc)->update != NULL) {
res = (*rc)->update(stateid, type, p);
if (res != MT_RM_STATUS_OK) {
break;
}
}
}
return res;
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef MT_LP_RM_H
#define MT_LP_RM_H
#include <stdbool.h>
#define MT_RM_STATUS_OK 0
#define MT_RM_STATUS_BAD -1
enum PLAT_MT_LPM_RC_TYPE {
PLAT_RC_UPDATE_CONDITION,
PLAT_RC_UPDATE_REMAIN_IRQS
};
struct mt_resource_constraint {
int level;
int (*init)(void);
bool (*is_valid)(unsigned int cpu, int stateid);
int (*update)(int stateid, int type, const void *p);
int (*run)(unsigned int cpu, int stateid);
int (*reset)(unsigned int cpu, int stateid);
unsigned int (*allow)(int stateid);
};
struct mt_resource_manager {
int (*update)(struct mt_resource_constraint **con,
int stateid, void *priv);
struct mt_resource_constraint **consts;
};
extern int mt_lp_rm_register(struct mt_resource_manager *rm);
extern int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid,
int stateid, void *priv);
extern int mt_lp_rm_reset_constraint(int constraint_id, unsigned int cpuid,
int stateid);
extern int mt_lp_rm_do_update(int stateid, int type, void const *p);
#endif /* MT_LP_RM_H */
@@ -0,0 +1,14 @@
#
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
LOCAL_DIR := $(call GET_LOCAL_DIR)
MODULE := lpm
LOCAL_SRCS-y := $(LOCAL_DIR)/mt_lp_rm.c
PLAT_INCLUDES += -I${LOCAL_DIR}
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
@@ -0,0 +1,175 @@
/*
* Copyright (c) 2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <arch.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/generic_delay_timer.h>
#if XLAT_TABLES_LIB_V2 && PLAT_XLAT_TABLES_DYNAMIC
#include <lib/xlat_tables/xlat_tables_v2.h>
#endif
#include <plat/common/platform.h>
#if COREBOOT
#include <common/desc_image_load.h>
#include <drivers/ti/uart/uart_16550.h>
#include <lib/coreboot.h>
#include <plat_params.h>
#endif
/* MTK headers */
#if MTK_SIP_KERNEL_BOOT_ENABLE
#include <cold_boot.h>
#endif
#include <lib/mtk_init/mtk_init.h>
#include <mtk_mmap_pool.h>
IMPORT_SYM(uintptr_t, __RW_START__, RW_START);
IMPORT_SYM(uintptr_t, __DATA_START__, DATA_START);
#if COREBOOT
static entry_point_info_t bl32_ep_info;
static entry_point_info_t bl33_ep_info;
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
* the security state specified. BL33 corresponds to the non-secure image type
* while BL32 corresponds to the secure image type. A NULL pointer is returned
* if the image does not exist.
******************************************************************************/
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
entry_point_info_t *next_image_info;
next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
assert(next_image_info->h.type == PARAM_EP);
/* None of the images on this platform can have 0x0 as the entrypoint */
if (next_image_info->pc) {
return next_image_info;
} else {
return NULL;
}
}
#else
#ifndef MTK_BL31_AS_BL2
static struct mtk_bl31_fw_config bl31_fw_config;
#else
struct mtk_bl31_fw_config bl31_fw_config;
#endif
/* In order to be accessed after MMU enable */
static struct mtk_bl_param_t bl_param_clone;
void *get_mtk_bl31_fw_config(int index)
{
void *arg = NULL;
switch (index) {
case BOOT_ARG_FROM_BL2:
arg = bl31_fw_config.from_bl2;
break;
case BOOT_ARG_SOC_FW_CONFIG:
arg = bl31_fw_config.soc_fw_config;
break;
case BOOT_ARG_HW_CONFIG:
arg = bl31_fw_config.hw_config;
break;
case BOOT_ARG_RESERVED:
arg = bl31_fw_config.reserved;
break;
default:
WARN("Fail to get boot arg, index:%d", index);
break;
}
return arg;
}
#endif
/*****************************************************************************
* Perform the very early platform specific architectural setup shared between
* ARM standard platforms. This only does basic initialization. Later
* architectural setup (bl31_arch_setup()) does not do anything platform
* specific.
******************************************************************************/
void bl31_early_platform_setup2(u_register_t from_bl2,
u_register_t soc_fw_config,
u_register_t hw_config, u_register_t plat_params_from_bl2)
{
#if COREBOOT
static console_t console;
params_early_setup(soc_fw_config);
if (coreboot_serial.type) {
console_16550_register(coreboot_serial.baseaddr,
coreboot_serial.input_hertz,
coreboot_serial.baud,
&console);
}
bl31_params_parse_helper(from_bl2, &bl32_ep_info, &bl33_ep_info);
#else
struct mtk_bl_param_t *p_mtk_bl_param = (struct mtk_bl_param_t *)from_bl2;
if (p_mtk_bl_param == NULL) {
ERROR("from_bl2 should not be NULL\n");
panic();
}
memcpy(&bl_param_clone, p_mtk_bl_param, sizeof(struct mtk_bl_param_t));
bl31_fw_config.from_bl2 = (void *)&bl_param_clone;
bl31_fw_config.soc_fw_config = (void *)soc_fw_config;
bl31_fw_config.hw_config = (void *)hw_config;
bl31_fw_config.reserved = (void *)plat_params_from_bl2;
#endif
INFO("MTK BL31 start\n");
/* Init delay function */
generic_delay_timer_init();
/* Initialize module initcall */
mtk_init_one_level(MTK_INIT_LVL_EARLY_PLAT);
}
void bl31_plat_arch_setup(void)
{
const mmap_region_t bl_regions[] = {
MAP_BL_RO,
MAP_BL_RW,
#if USE_COHERENT_MEM
MAP_BL_COHERENT_RAM,
#endif
{0},
};
mtk_xlat_init(bl_regions);
/* Initialize module initcall */
mtk_init_one_level(MTK_INIT_LVL_ARCH);
}
/*****************************************************************************
* Perform any BL31 platform setup common to ARM standard platforms
******************************************************************************/
void bl31_platform_setup(void)
{
mtk_init_one_level(MTK_INIT_LVL_PLAT_SETUP_0);
mtk_init_one_level(MTK_INIT_LVL_PLAT_SETUP_1);
}
/*******************************************************************************
* Operations before cold CPU leave BL31.
* Switch console to runtime state.
******************************************************************************/
void bl31_plat_runtime_setup(void)
{
mtk_init_one_level(MTK_INIT_LVL_PLAT_RUNTIME);
console_switch_state(CONSOLE_FLAG_RUNTIME);
}
unsigned int plat_get_syscnt_freq2(void)
{
return SYS_COUNTER_FREQ_IN_HZ;
}
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/arm/cci.h>
#include <drivers/console.h>
#include <lib/mmio.h>
#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables.h>
#include <plat/common/platform.h>
#include <services/arm_arch_svc.h>
#include <mtk_plat_common.h>
#include <mtk_sip_svc.h>
#include <plat_private.h>
void clean_top_32b_of_param(uint32_t smc_fid,
u_register_t *px1,
u_register_t *px2,
u_register_t *px3,
u_register_t *px4)
{
/* if parameters from SMC32. Clean top 32 bits */
if (GET_SMC_CC(smc_fid) == SMC_64) {
*px1 = *px1 & SMC32_PARAM_MASK;
*px2 = *px2 & SMC32_PARAM_MASK;
*px3 = *px3 & SMC32_PARAM_MASK;
*px4 = *px4 & SMC32_PARAM_MASK;
}
}
/*****************************************************************************
* plat_is_smccc_feature_available() - This function checks whether SMCCC
* feature is availabile for platform.
* @fid: SMCCC function id
*
* Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED
* otherwise.
*****************************************************************************/
int32_t plat_is_smccc_feature_available(u_register_t fid)
{
switch (fid) {
case SMCCC_ARCH_SOC_ID:
return SMC_ARCH_CALL_SUCCESS;
default:
return SMC_ARCH_CALL_NOT_SUPPORTED;
}
}
int32_t plat_get_soc_version(void)
{
uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_MTK_BKID, JEDEC_MTK_MFID);
return (int32_t)(manfid | (SOC_CHIP_ID & SOC_ID_IMPL_DEF_MASK));
}
int32_t plat_get_soc_revision(void)
{
return 0;
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef MTK_PLAT_COMMON_H
#define MTK_PLAT_COMMON_H
#include <stdint.h>
#include <common/bl_common.h>
#include <common/param_header.h>
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
#define SMC32_PARAM_MASK (0xFFFFFFFF)
#define JEDEC_MTK_BKID U(4)
#define JEDEC_MTK_MFID U(0x26)
struct mtk_bl31_params {
param_header_t h;
image_info_t *bl31_image_info;
entry_point_info_t *bl32_ep_info;
image_info_t *bl32_image_info;
entry_point_info_t *bl33_ep_info;
image_info_t *bl33_image_info;
};
/* Declarations for mtk_plat_common.c */
uint32_t plat_get_spsr_for_bl32_entry(void);
uint32_t plat_get_spsr_for_bl33_entry(void);
void clean_top_32b_of_param(uint32_t smc_fid, u_register_t *x1,
u_register_t *x2,
u_register_t *x3,
u_register_t *x4);
void bl31_prepare_kernel_entry(uint64_t k32_64);
void enable_ns_access_to_cpuectlr(void);
void boot_to_kernel(uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
uint64_t get_kernel_info_pc(void);
uint64_t get_kernel_info_r0(void);
uint64_t get_kernel_info_r1(void);
uint64_t get_kernel_info_r2(void);
extern struct atf_arg_t gteearg;
#endif /* MTK_PLAT_COMMON_H */
@@ -0,0 +1,129 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <drivers/console.h>
#include <lib/mmio.h>
#include <tools_share/uuid.h>
#include <mtk_plat_common.h>
#include <mtk_sip_svc.h>
#include <plat_sip_calls.h>
/* Mediatek SiP Service UUID */
DEFINE_SVC_UUID2(mtk_sip_svc_uid,
0xa42b58f7, 0x6242, 0x7d4d, 0x80, 0xe5,
0x8f, 0x95, 0x05, 0x00, 0x0f, 0x3d);
#pragma weak mediatek_plat_sip_handler
uintptr_t mediatek_plat_sip_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie,
void *handle,
u_register_t flags)
{
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
SMC_RET1(handle, SMC_UNK);
}
/*
* This function handles Mediatek defined SiP Calls */
uintptr_t mediatek_sip_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie,
void *handle,
u_register_t flags)
{
uint32_t ns;
/* if parameter is sent from SMC32. Clean top 32 bits */
clean_top_32b_of_param(smc_fid, &x1, &x2, &x3, &x4);
/* Determine which security state this SMC originated from */
ns = is_caller_non_secure(flags);
if (!ns) {
/* SiP SMC service secure world's call */
;
} else {
/* SiP SMC service normal world's call */
switch (smc_fid) {
#if MTK_SIP_SET_AUTHORIZED_SECURE_REG_ENABLE
case MTK_SIP_SET_AUTHORIZED_SECURE_REG: {
/* only use ret here */
uint64_t ret;
ret = mt_sip_set_authorized_sreg((uint32_t)x1,
(uint32_t)x2);
SMC_RET1(handle, ret);
}
#endif
#if MTK_SIP_KERNEL_BOOT_ENABLE
case MTK_SIP_KERNEL_BOOT_AARCH32:
boot_to_kernel(x1, x2, x3, x4);
SMC_RET0(handle);
#endif
default:
/* Do nothing in default case */
break;
}
}
return mediatek_plat_sip_handler(smc_fid, x1, x2, x3, x4,
cookie, handle, flags);
}
/*
* This function is responsible for handling all SiP calls from the NS world
*/
uintptr_t sip_smc_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie,
void *handle,
u_register_t flags)
{
switch (smc_fid) {
case SIP_SVC_CALL_COUNT:
/* Return the number of Mediatek SiP Service Calls. */
SMC_RET1(handle,
MTK_COMMON_SIP_NUM_CALLS + MTK_PLAT_SIP_NUM_CALLS);
case SIP_SVC_UID:
/* Return UID to the caller */
SMC_UUID_RET(handle, mtk_sip_svc_uid);
case SIP_SVC_VERSION:
/* Return the version of current implementation */
SMC_RET2(handle, MTK_SIP_SVC_VERSION_MAJOR,
MTK_SIP_SVC_VERSION_MINOR);
default:
return mediatek_sip_handler(smc_fid, x1, x2, x3, x4,
cookie, handle, flags);
}
}
/* Define a runtime service descriptor for fast SMC calls */
DECLARE_RT_SVC(
mediatek_sip_svc,
OEN_SIP_START,
OEN_SIP_END,
SMC_TYPE_FAST,
NULL,
sip_smc_handler
);
@@ -0,0 +1,235 @@
/*
* Copyright (c) 2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#if MTK_SIP_KERNEL_BOOT_ENABLE
#include <cold_boot.h>
#endif
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <lib/mtk_init/mtk_init.h>
#include <mtk_sip_svc.h>
#define SMC_HANDLER_DEBUG(...) VERBOSE(__VA_ARGS__)
#define SMC_HANDLER_DEBUG_NOT_IMP_MSG "%s[0x%x] smc handler not implemented\n"
#define SMC_HANDLER_DEBUG_START_MSG "%s[0x%x] smc handler start, smc desc. index:%d\n"
#define SMC_HANDLER_DEBUG_END_MSG "%s[0x%x] smc handler end\n"
/*
* These macros below are used to identify SIP calls from Kernel,
* Hypervisor, or 2ndBootloader
*/
#define SIP_FID_ORI_MASK (0xc000)
#define SIP_FID_ORI_SHIFT (14)
#define SIP_FID_KERNEL (0x0)
#define SIP_FID_KERNEL_VIA_GZ (0x1)
#define SIP_FID_GZ (0x2)
#define GET_SMC_ORI(_fid) (((_fid) & SIP_FID_ORI_MASK) >> SIP_FID_ORI_SHIFT)
#define GET_SMC_ORI_NUM(_fid) ((_fid) & ~(SIP_FID_ORI_MASK))
#define is_from_nsel2(_ori) (_ori == SIP_FID_GZ)
#define is_from_bl33(_ori) \
((_ori != SIP_FID_GZ) && (is_el1_2nd_bootloader() == 1))
#define is_from_nsel1(_ori) \
(((_ori == SIP_FID_KERNEL) || \
(_ori == SIP_FID_KERNEL_VIA_GZ)) && \
(is_el1_2nd_bootloader() == 0))
#define is_smc_forbidden(_ori) (_ori == SIP_FID_KERNEL_VIA_GZ)
#define MASK_32_BIT (0xffffffffU)
#define SMC_ID_EXPAND_AS_SMC_OPERATION(_smc_id, _smc_num) \
case _smc_id##_AARCH32: \
{ \
x1 = x1 & MASK_32_BIT; \
x2 = x2 & MASK_32_BIT; \
x3 = x3 & MASK_32_BIT; \
x4 = x4 & MASK_32_BIT; \
} \
case _smc_id##_AARCH64: \
{ \
if (_smc_id##_descriptor_index < 0) { \
SMC_HANDLER_DEBUG(SMC_HANDLER_DEBUG_NOT_IMP_MSG, #_smc_id, smc_id); \
break; \
} \
if (_smc_id##_descriptor_index >= smc_id_descriptor_max) { \
SMC_HANDLER_DEBUG("smc descriptor index[%d] exceed max[%d]\n", \
_smc_id##_descriptor_index, smc_id_descriptor_max); \
break; \
} \
SMC_HANDLER_DEBUG(SMC_HANDLER_DEBUG_START_MSG, #_smc_id, smc_id, \
_smc_id##_descriptor_index); \
ret = smc_handler_pool[_smc_id##_descriptor_index].smc_handler(x1,\
x2, x3, x4, handle, &smc_ret); \
SMC_HANDLER_DEBUG(SMC_HANDLER_DEBUG_END_MSG, #_smc_id, smc_id); \
break; \
}
#define SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX(_smc_id, _smc_num) \
short _smc_id##_descriptor_index __section("mtk_plat_ro") = -1;
MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX);
MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX);
IMPORT_SYM(uintptr_t, __MTK_SMC_POOL_START__, MTK_SMC_POOL_START);
IMPORT_SYM(uintptr_t, __MTK_SMC_POOL_END_UNALIGNED__, MTK_SMC_POOL_END_UNALIGNED);
static const struct smc_descriptor *smc_handler_pool;
static short smc_id_descriptor_max;
#if !MTK_SIP_KERNEL_BOOT_ENABLE
/*
* If there is no SMC request needs to be served in 2nd bootloader,
* disable the service path inherently.
*/
bool is_el1_2nd_bootloader(void)
{
return false;
}
#endif
static void print_smc_descriptor(const struct smc_descriptor pool[])
{
const struct smc_descriptor *p_smc_desc;
INFO("print smc descriptor pool\n");
for (p_smc_desc = &pool[0];
(char *)p_smc_desc < (char *)MTK_SMC_POOL_END_UNALIGNED;
p_smc_desc++) {
INFO("descriptor name:%s\n", p_smc_desc->smc_name);
INFO("descriptor index:%d\n", *p_smc_desc->smc_descriptor_index);
INFO("smc id 32:0x%x, smc id 64:0x%x\n",
p_smc_desc->smc_id_aarch32, p_smc_desc->smc_id_aarch64);
}
}
static int mtk_smc_handler_init(void)
{
const struct smc_descriptor *iter;
short index_cnt;
int ret = 0;
smc_handler_pool = (const struct smc_descriptor *)MTK_SMC_POOL_START;
/* Designate descriptor index point to smc_handler_pool */
for (index_cnt = 0, iter = &smc_handler_pool[0];
(char *)iter < (char *)MTK_SMC_POOL_END_UNALIGNED;
iter++, index_cnt++) {
if (index_cnt < 0) {
SMC_HANDLER_DEBUG("smc handler pool index overflow!\n");
ret = -EPERM;
assert(0);
break;
}
*(iter->smc_descriptor_index) = index_cnt;
}
smc_id_descriptor_max = index_cnt;
print_smc_descriptor(smc_handler_pool);
return ret;
}
MTK_EARLY_PLAT_INIT(mtk_smc_handler_init);
/* This function handles Mediatek defined SiP Calls from Bootloader */
static uintptr_t mtk_smc_handler_bl33(uint32_t smc_id,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie,
void *handle,
u_register_t flags)
{
uintptr_t ret = MTK_SIP_E_SUCCESS;
struct smccc_res smc_ret = {0};
switch (smc_id) {
MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_SMC_OPERATION);
default:
INFO("BL33 SMC ID:0x%x not supported\n", smc_id);
ret = SMC_UNK;
break;
}
SMC_RET4(handle, ret, smc_ret.a1, smc_ret.a2, smc_ret.a3);
}
/* This function handles Mediatek defined SiP Calls from Kernel */
static uintptr_t mtk_smc_handler_nsel1(uint32_t smc_id,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie,
void *handle,
u_register_t flags)
{
uintptr_t ret = MTK_SIP_E_SUCCESS;
struct smccc_res smc_ret = {0};
switch (smc_id) {
MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_SMC_OPERATION);
default:
INFO("NSEL1 SMC ID:0x%x not supported\n", smc_id);
ret = SMC_UNK;
break;
}
SMC_RET4(handle, ret, smc_ret.a1, smc_ret.a2, smc_ret.a3);
}
static uintptr_t mtk_smc_handler(uint32_t smc_id,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie,
void *handle,
u_register_t flags)
{
uintptr_t ret = SMC_UNK;
uint32_t ns;
uint32_t smc_ori;
uint32_t smc_num;
/* Get SMC Originator bit 14.15 */
smc_ori = GET_SMC_ORI(smc_id);
/* Get SMC Number. Clean bit 14.15 */
smc_num = GET_SMC_ORI_NUM(smc_id);
/* Determine which security state this SMC originated from */
ns = is_caller_non_secure(flags);
if (ns && is_smc_forbidden(smc_ori)) {
ERROR("%s: Forbidden SMC call (0x%x)\n", __func__, smc_id);
SMC_RET1(handle, ret);
}
if (!ns) {
/* SiP SMC service secure world's call */
INFO("Secure SMC ID:0x%x not supported\n", smc_id);
SMC_RET1(handle, ret);
}
if (is_from_bl33(smc_ori)) {
/* SiP SMC service secure bootloader's call */
return mtk_smc_handler_bl33(smc_num, x1, x2, x3, x4,
cookie, handle, flags);
} else if (is_from_nsel1(smc_ori)) {
/* SiP SMC service kernel's call */
return mtk_smc_handler_nsel1(smc_num, x1, x2, x3, x4,
cookie, handle, flags);
}
INFO("SMC ID:0x%x not supported\n", smc_id);
SMC_RET1(handle, ret);
}
/* Define a runtime service descriptor for fast SMC calls */
DECLARE_RT_SVC(
mtk_smc_handler,
OEN_SIP_START,
OEN_SIP_END,
SMC_TYPE_FAST,
NULL,
mtk_smc_handler
);
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/bl_aux_params/bl_aux_params.h>
#include <common/debug.h>
#include <plat_params.h>
#include <string.h>
static struct bl_aux_gpio_info rst_gpio;
struct bl_aux_gpio_info *plat_get_mtk_gpio_reset(void)
{
return &rst_gpio;
}
static bool mtk_aux_param_handler(struct bl_aux_param_header *param)
{
/* Store platform parameters for later processing if needed. */
switch (param->type) {
case BL_AUX_PARAM_MTK_RESET_GPIO:
rst_gpio = ((struct bl_aux_param_gpio *)param)->gpio;
return true;
}
return false;
}
void params_early_setup(u_register_t plat_param_from_bl2)
{
bl_aux_params_parse(plat_param_from_bl2, mtk_aux_param_handler);
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLAT_PARAMS_H
#define PLAT_PARAMS_H
#include <stdint.h>
#include <export/plat/mediatek/common/plat_params_exp.h>
struct bl_aux_gpio_info *plat_get_mtk_gpio_reset(void);
void params_early_setup(u_register_t plat_param_from_bl2);
#endif
@@ -0,0 +1,15 @@
#
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
LOCAL_DIR := $(call GET_LOCAL_DIR)
MODULE := mtk_common
LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_bl31_setup.c
LOCAL_SRCS-y += ${LOCAL_DIR}/mtk_smc_handlers.c
LOCAL_SRCS-$(MTK_SIP_KERNEL_BOOT_ENABLE) += ${LOCAL_DIR}/cold_boot.c
$(eval $(call MAKE_LOCALS,$(LOCAL_SRCS-y),$(MTK_BL)))