Browse Source
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: Icd7fe95372441db73c975ccb6ce77a6c529df1ccpull/1988/head
Leon Chen
2 years ago
committed by
Bo-Chen Chen
9 changed files with 279 additions and 4 deletions
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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); |
|||
} |
|||
} |
|||
} |
@ -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); |
|||
} |
@ -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…
Reference in new issue