Browse Source

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 <leon.chen@mediatek.com>
Change-Id: Icd7fe95372441db73c975ccb6ce77a6c529df1cc
pull/1988/head
Leon Chen 2 years ago
committed by Bo-Chen Chen
parent
commit
52035dee1a
  1. 5
      plat/mediatek/build_helpers/mtk_build_helpers.mk
  2. 2
      plat/mediatek/build_helpers/options.mk
  3. 58
      plat/mediatek/include/lib/mtk_init/mtk_init.h
  4. 22
      plat/mediatek/include/lib/mtk_init/mtk_init_def.h
  5. 58
      plat/mediatek/include/mtk_mmap_pool.h
  6. 30
      plat/mediatek/include/plat.ld.rodata.inc
  7. 39
      plat/mediatek/lib/mtk_init/mtk_init.c
  8. 55
      plat/mediatek/lib/mtk_init/mtk_mmap_init.c
  9. 14
      plat/mediatek/lib/mtk_init/rules.mk

5
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)

2
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))

58
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 <cdefs.h>
#include <lib/mtk_init/mtk_init_def.h>
#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 */

22
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 */

58
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 <cdefs.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
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 */

30
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 <lib/mtk_init/mtk_init.h>
. = 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 <vendor_pubsub_events.h>
*(mtk_plat_ro)
#endif /* PLAT_LD_RODATA_INC */

39
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 <common/debug.h>
#include <lib/utils_def.h>
#include <lib/mtk_init/mtk_init.h>
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);
}
}
}

55
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 <assert.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/console.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <mtk_mmap_pool.h>
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);
}

14
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)))
Loading…
Cancel
Save