From 52035dee1ae7b0f2f0d5f16c734ca7a5cea127b7 Mon Sep 17 00:00:00 2001 From: Leon Chen Date: Mon, 20 Jun 2022 10:25:35 +0800 Subject: [PATCH] feat(mediatek): introduce mtk init framework Provide six initcall levels for drivers/modules initialize HW controllers or runtime arguments during cold boot. The initcall level cold boot execution order: -MTK_EARLY_PLAT_INIT Call before MMU enabled. -MTK_ARCH_INIT MMU Enabled, arch related init(GiC init, interrupt type registration). -MTK_PLAT_SETUP_0_INIT MTK driver init level 0. -MTK_PLAT_SETUP_1_INIT MTK driver init level 1. -MTK_PLAT_RUNTIME_INIT MTK driver init. After this initcall, TF-A handovers to MTK 2nd bootloader. -MTK_PLAT_BL33_DEFER_INIT MTK 2nd bootloader traps to TF-A before handover to rich OS. This initcall executed in the trap handler(boot_to_kernel). Signed-off-by: Leon Chen Change-Id: Icd7fe95372441db73c975ccb6ce77a6c529df1cc --- .../build_helpers/mtk_build_helpers.mk | 5 +- plat/mediatek/build_helpers/options.mk | 2 +- plat/mediatek/include/lib/mtk_init/mtk_init.h | 58 +++++++++++++++++++ .../include/lib/mtk_init/mtk_init_def.h | 22 +++++++ plat/mediatek/include/mtk_mmap_pool.h | 58 +++++++++++++++++++ plat/mediatek/include/plat.ld.rodata.inc | 30 ++++++++++ plat/mediatek/lib/mtk_init/mtk_init.c | 39 +++++++++++++ plat/mediatek/lib/mtk_init/mtk_mmap_init.c | 55 ++++++++++++++++++ plat/mediatek/lib/mtk_init/rules.mk | 14 +++++ 9 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 plat/mediatek/include/lib/mtk_init/mtk_init.h create mode 100644 plat/mediatek/include/lib/mtk_init/mtk_init_def.h create mode 100644 plat/mediatek/include/mtk_mmap_pool.h create mode 100644 plat/mediatek/include/plat.ld.rodata.inc create mode 100644 plat/mediatek/lib/mtk_init/mtk_init.c create mode 100644 plat/mediatek/lib/mtk_init/mtk_mmap_init.c create mode 100644 plat/mediatek/lib/mtk_init/rules.mk diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk index 47d96faed..a5a4c3e36 100644 --- a/plat/mediatek/build_helpers/mtk_build_helpers.mk +++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk @@ -125,11 +125,10 @@ MTK_OPTIONS := $(MTK_PLAT)/build_helpers/options.mk MTK_COND_EVAL := $(MTK_PLAT)/build_helpers/conditional_eval_options.mk # Indicate which BL should be built in command line -ifeq (${NEED_BL31},yes) -MTK_BL := bl31 -endif ifeq (${NEED_BL32},yes) MTK_BL := bl32 +else +MTK_BL := bl31 endif # Include common, platform, board level config include $(MTK_COMMON_CFG) diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk index 394a605ee..eb579e5c1 100644 --- a/plat/mediatek/build_helpers/options.mk +++ b/plat/mediatek/build_helpers/options.mk @@ -6,7 +6,7 @@ # call add_defined_option to evaluate MTK defined value $(eval $(call add_defined_option,MTK_SIP_KERNEL_BOOT_ENABLE)) -$(eval $(call add_defined_option,PLAT_EXTRA_LD_SCRIPT)) +$(eval $(call add_defined_option,PLAT_EXTRA_RODATA_INCLUDES)) $(eval $(call add_defined_option,MTK_EXTRA_LINKERFILE)) $(eval $(call add_defined_option,MTK_BL31_AS_BL2)) $(eval $(call add_defined_option,MTK_BL33_IS_64BIT)) diff --git a/plat/mediatek/include/lib/mtk_init/mtk_init.h b/plat/mediatek/include/lib/mtk_init/mtk_init.h new file mode 100644 index 000000000..6f23a9b46 --- /dev/null +++ b/plat/mediatek/include/lib/mtk_init/mtk_init.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTK_INIT_H +#define MTK_INIT_H + +#include +#include + +#define INIT_CALL_EXPAND_AS_ENUMERATION(_section_enum, _section_name, _level) \ + _section_enum = _level, + +#define EXPAND_AS_LINK_SECTION(_section_enum, _section_name, _level) \ + __##_section_enum##_START__ = .; \ + KEEP(*(_section_name##_level)); + +#define EXPAND_AS_EXTERN(_section_enum, _section_name, _level) \ + extern struct initcall __##_section_enum##_START__[]; + +#define EXPAND_AS_SYMBOL_ARR(_section_enum, _section_name, _level) \ + __##_section_enum##_START__, + +#define DECLARE_MTK_INITCALL(_fn, _level) \ + const struct initcall _mtk_initcall_##_fn \ + __used \ + __aligned(sizeof(void *)) \ + __section(".mtk_plat_initcall_"#_level) \ + = { \ + .name = #_fn, \ + .fn = _fn \ + } + +/* initcall helpers */ +#define MTK_EARLY_PLAT_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 0) +#define MTK_ARCH_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 1) +#define MTK_PLAT_SETUP_0_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 2) +#define MTK_PLAT_SETUP_1_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 3) +#define MTK_PLAT_RUNTIME_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 4) +#define MTK_PLAT_BL33_DEFER_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 5) + +#ifndef __ASSEMBLER__ +struct initcall { + const char *name; + int (*fn)(void); +}; + +enum { + INIT_CALL_TABLE(INIT_CALL_EXPAND_AS_ENUMERATION) + MTK_INIT_LVL_MAX +}; + +void mtk_init_one_level(unsigned int level); +#endif + +#endif /* MTK_INIT_H */ diff --git a/plat/mediatek/include/lib/mtk_init/mtk_init_def.h b/plat/mediatek/include/lib/mtk_init/mtk_init_def.h new file mode 100644 index 000000000..8aae41d5c --- /dev/null +++ b/plat/mediatek/include/lib/mtk_init/mtk_init_def.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTK_INIT_DEF_H +#define MTK_INIT_DEF_H + +/* + * Define init call sections here. _func is for 2nd level expansion, init + * section enum, and init section name. + */ +#define INIT_CALL_TABLE(_func) \ + _func(MTK_INIT_LVL_EARLY_PLAT, .mtk_plat_initcall_, 0) \ + _func(MTK_INIT_LVL_ARCH, .mtk_plat_initcall_, 1) \ + _func(MTK_INIT_LVL_PLAT_SETUP_0, .mtk_plat_initcall_, 2) \ + _func(MTK_INIT_LVL_PLAT_SETUP_1, .mtk_plat_initcall_, 3) \ + _func(MTK_INIT_LVL_PLAT_RUNTIME, .mtk_plat_initcall_, 4) \ + _func(MTK_INIT_LVL_BL33_DEFER, .mtk_plat_initcall_, 5) + +#endif /* MTK_INIT_DEF_H */ diff --git a/plat/mediatek/include/mtk_mmap_pool.h b/plat/mediatek/include/mtk_mmap_pool.h new file mode 100644 index 000000000..99d1bff5c --- /dev/null +++ b/plat/mediatek/include/mtk_mmap_pool.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTK_MMAP_POOL_H +#define MTK_MMAP_POOL_H + +#include +#include + +struct mtk_mmap_descriptor { + const char *mmap_name; + const mmap_region_t *mmap_ptr; + const uint32_t mmap_size; +}; + +#define MTK_MMAP_SECTION \ + __used \ + __aligned(sizeof(void *)) \ + __section(".mtk_mmap_lists") + +#define DECLARE_MTK_MMAP_REGIONS(_mmap_array) \ + static const struct mtk_mmap_descriptor _mtk_mmap_descriptor_##_mmap_array \ + __used \ + __aligned(sizeof(void *)) \ + __section(".mtk_mmap_pool") \ + = { \ + .mmap_name = #_mmap_array, \ + .mmap_ptr = _mmap_array, \ + .mmap_size = ARRAY_SIZE(_mmap_array) \ + } + +#define MAP_BL_RW MAP_REGION_FLAT( \ + DATA_START, \ + BL_END - DATA_START, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#if SEPARATE_CODE_AND_RODATA +#define MAP_BL_RO \ + MAP_REGION_FLAT( \ + BL_CODE_BASE, \ + BL_CODE_END - BL_CODE_BASE, \ + MT_CODE | MT_SECURE), \ + MAP_REGION_FLAT( \ + BL_RO_DATA_BASE, \ + BL_RO_DATA_END - BL_RO_DATA_BASE, \ + MT_RO_DATA | MT_SECURE) +#else +#define MAP_BL_RO MAP_REGION_FLAT(BL_CODE_BASE, \ + BL_CODE_END - BL_CODE_BASE, \ + MT_CODE | MT_SECURE) +#endif + +void mtk_xlat_init(const mmap_region_t *bl_regions); + +#endif /* MTK_MMAP_POOL_H */ diff --git a/plat/mediatek/include/plat.ld.rodata.inc b/plat/mediatek/include/plat.ld.rodata.inc new file mode 100644 index 000000000..06ad49109 --- /dev/null +++ b/plat/mediatek/include/plat.ld.rodata.inc @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_LD_RODATA_INC +#define PLAT_LD_RODATA_INC + +#include + . = ALIGN(32); + INIT_CALL_TABLE(EXPAND_AS_LINK_SECTION); + __MTK_PLAT_INITCALL_END__ = .; + . = ALIGN(32); + __MTK_MMAP_POINTER_POOL_START__ = .; + KEEP(*(.mtk_mmap_pool)) + __MTK_MMAP_POINTER_POOL_END_UNALIGNED__ = .; + . = ALIGN(8); + __MTK_MMAP_POOL_START__ = .; + KEEP(*(.mtk_mmap_lists)) + __MTK_MMAP_POOL_END_UNALIGNED__ = .; + . = ALIGN(32); + __MTK_SMC_POOL_START__ = .; + KEEP(*(.mtk_smc_descriptor_pool)) + __MTK_SMC_POOL_END_UNALIGNED__ = .; + . = ALIGN(8); +#include + *(mtk_plat_ro) + +#endif /* PLAT_LD_RODATA_INC */ diff --git a/plat/mediatek/lib/mtk_init/mtk_init.c b/plat/mediatek/lib/mtk_init/mtk_init.c new file mode 100644 index 000000000..228965926 --- /dev/null +++ b/plat/mediatek/lib/mtk_init/mtk_init.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +INIT_CALL_TABLE(EXPAND_AS_EXTERN); +extern struct initcall __MTK_PLAT_INITCALL_END__[]; + +struct initcall *initcall_list[] = { + INIT_CALL_TABLE(EXPAND_AS_SYMBOL_ARR) + __MTK_PLAT_INITCALL_END__ +}; + +void mtk_init_one_level(uint32_t level) +{ + const struct initcall *entry; + int error; + + if (level >= MTK_INIT_LVL_MAX) { + ERROR("invalid level:%u\n", level); + panic(); + } + + INFO("init calling level:%u\n", level); + for (entry = initcall_list[level]; + (entry != NULL) && (entry < initcall_list[level + 1]); + entry++) { + INFO("calling %s\n", entry->name); + error = entry->fn(); + if (error != 0) { + ERROR("init %s fail, errno:%d\n", entry->name, error); + } + } +} diff --git a/plat/mediatek/lib/mtk_init/mtk_mmap_init.c b/plat/mediatek/lib/mtk_init/mtk_mmap_init.c new file mode 100644 index 000000000..e3dada01a --- /dev/null +++ b/plat/mediatek/lib/mtk_init/mtk_mmap_init.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +IMPORT_SYM(uintptr_t, __MTK_MMAP_POINTER_POOL_START__, MTK_MMAP_POINTER_POOL_START); +IMPORT_SYM(uintptr_t, __MTK_MMAP_POINTER_POOL_END_UNALIGNED__, MTK_MMAP_POINTER_POOL_END_UNALIGNED); +IMPORT_SYM(uintptr_t, __RW_START__, RW_START); +IMPORT_SYM(uintptr_t, __DATA_START__, DATA_START); + +#define MAP_MTK_SECTIONS MAP_REGION_FLAT(RW_START, \ + DATA_START - RW_START, \ + MT_MEMORY | MT_RO | MT_SECURE) + + +static void print_mmap(const mmap_region_t *regions) +{ + while (regions->size != 0U) { + VERBOSE("Region: 0x%lx - 0x%lx has attributes 0x%x\n", + regions->base_va, + regions->base_va + regions->size, + regions->attr); + regions++; + } +} + +void mtk_xlat_init(const mmap_region_t *bl_regions) +{ + struct mtk_mmap_descriptor *iter; + const mmap_region_t *regions = bl_regions; + + print_mmap(regions); + mmap_add(bl_regions); + if (MTK_MMAP_POINTER_POOL_START != MTK_MMAP_POINTER_POOL_END_UNALIGNED) { + for (iter = (struct mtk_mmap_descriptor *)MTK_MMAP_POINTER_POOL_START; + (char *)iter < (char *)MTK_MMAP_POINTER_POOL_END_UNALIGNED; + iter++) { + regions = iter->mmap_ptr; + INFO("mmap_name: %s\n", iter->mmap_name); + INFO("mmap_size: 0x%x\n", iter->mmap_size); + print_mmap(regions); + mmap_add(regions); + } + } + init_xlat_tables(); + enable_mmu_el3(0); +} diff --git a/plat/mediatek/lib/mtk_init/rules.mk b/plat/mediatek/lib/mtk_init/rules.mk new file mode 100644 index 000000000..cc6ca9569 --- /dev/null +++ b/plat/mediatek/lib/mtk_init/rules.mk @@ -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 := mtk_init + +LOCAL_SRCS-y := $(LOCAL_DIR)/mtk_init.c +LOCAL_SRCS-y += $(LOCAL_DIR)/mtk_mmap_init.c + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) -- 2.39.5