OS_Bootup

本文解释了电脑开机引导过程,从按下电源键到操作系统显示的详细步骤,包括BIOS自检、Bootloader加载操作系统和不同操作系统的差异。对PC/智能手机工作原理感兴趣的读者不容错过。

添加链接描述
“引导"的意思是"引导加载”。如果用简单的话来说,它的意思是"从头开始启动"。在实际应用中,这是一系列从打开电源到操作系统屏幕的步骤(过程)。对于大多数用户来说,他们可能对这个过程中并不感兴趣。他们只是认为这是使用电脑时必须等待的一段漫长/无聊的时间。然而,如果你对PC(或智能手机)的工作原理感兴趣,这个过程将是你需要理解的最重要的步骤之一。

同样地,如果你将术语"引导序列"应用于智能手机,它是在你打开设备后发生的步骤(过程),直到你看到如图所示的屏幕。

如果你更详细地回顾开机后的过程,你可能会看到几个中间步骤,如下所示。仅根据两个关键屏幕描述整个过程,而不深入了解其中的细节,可以描述如下。

步骤(A):按下电源开关键。

步骤(B):刚按下电源开关键后,你会看到PC上的各种LED开始闪烁,听到硬盘旋转,并看到一个类似于(B)的屏幕。这被称为BIOS屏幕。根据你的PC使用的BIOS类型,你会看到不同类型的BIOS屏幕。

步骤(C):在BIOS完成任务后,你会看到一个操作系统的启动画面(在这个例子中是Windows 7)。在这个阶段,后台正在发生很多事情。

步骤(D):最后你将看到操作系统的第一个屏幕(在某些情况下,你会在这一步骤看到登录窗口)。

了解引导序列通常意味着了解步骤(B)和(C)发生了什么。完全理解这个过程需要多年的努力工作,但对于那些对这个过程中发生的事情感到好奇的人或者希望从事与操作系统开发或编程相关的工作的人来说,尽可能多地了解这个过程是至关重要的。不要试图一夜之间了解一切,否则只会让你筋疲力尽。

除非你更换硬件(PC本身),否则你会看到相同的BIOS屏幕;但是,如果你使用不同的操作系统,你会在步骤(C)和(D)中看到不同的屏幕。步骤(C)中发生的进程也会因你使用的操作系统而异。以下是一个使用Ubuntu的例子。

现在让我们更深入地了解一下在启动过程中发生了什么。这是大多数PC /笔记本电脑发生的典型序列。这个序列在智能手机或其他系统(例如嵌入式系统)中会有所不同。

  1. 开机
  2. BIOS(基本输入输出系统)程序启动(如果你更感兴趣,请参阅BIOS页面)
  3. BIOS执行POST(加电自检)
  4. BIOS读取硬盘的特定扇区(通常是第一个扇区),并将其加载到主存储器中。(这是一个名为Bootloader的非常小的程序)
  5. Bootloader程序执行一个非常简短的任务,然后将操作系统代码加载到主存储器中,操作系统执行所有用户所需的程序(主要是设备驱动程序)。

如果你使用不同的操作系统,步骤(4)和(5)中发生的进程会有所不同。例如,参考我发布的Linux引导序列。

// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2010 * Texas Instruments, <www.ti.com> * * Aneesh V <aneesh@ti.com> */ #include <common.h> #include <bloblist.h> #include <binman_sym.h> #include <bootstage.h> #include <dm.h> #include <handoff.h> #include <hang.h> #include <init.h> #include <irq_func.h> #include <log.h> #include <mapmem.h> #include <serial.h> #include <spl.h> #include <asm/global_data.h> #include <asm/u-boot.h> #include <nand.h> #include <fat.h> #include <u-boot/crc.h> #include <version.h> #include <image.h> #include <malloc.h> #include <mapmem.h> #include <dm/root.h> #include <linux/compiler.h> #include <fdt_support.h> #include <bootcount.h> #include <wdt.h> DECLARE_GLOBAL_DATA_PTR; #ifndef CONFIG_SYS_UBOOT_START #define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE #endif #ifndef CONFIG_SYS_MONITOR_LEN /* Unknown U-Boot size, let's assume it will not be more than 200 KB */ #define CONFIG_SYS_MONITOR_LEN (200 * 1024) #endif u32 *boot_params_ptr = NULL; /* See spl.h for information about this */ binman_sym_declare(ulong, u_boot_any, image_pos); binman_sym_declare(ulong, u_boot_any, size); #ifdef CONFIG_TPL binman_sym_declare(ulong, spl, image_pos); binman_sym_declare(ulong, spl, size); #endif /* Define board data structure */ static struct bd_info bdata __attribute__ ((section(".data"))); #if CONFIG_IS_ENABLED(BOOTSTAGE) /* * Board-specific Platform code can reimplement show_boot_progress () if needed */ __weak void show_boot_progress(int val) {} #endif #if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) || \ defined(CONFIG_SPL_ATF) /* weak, default platform-specific function to initialize dram banks */ __weak int dram_init_banksize(void) { return 0; } #endif /* * Default function to determine if u-boot or the OS should * be started. This implementation always returns 1. * * Please implement your own board specific funcion to do this. * * RETURN * 0 to not start u-boot * positive if u-boot should start */ #ifdef CONFIG_SPL_OS_BOOT __weak int spl_start_uboot(void) { puts(SPL_TPL_PROMPT "Please implement spl_start_uboot() for your board\n"); puts(SPL_TPL_PROMPT "Direct Linux boot not active!\n"); return 1; } /* * Weak default function for arch specific zImage check. Return zero * and fill start and end address if image is recognized. */ int __weak bootz_setup(ulong image, ulong *start, ulong *end) { return 1; } #endif /* Weak default function for arch/board-specific fixups to the spl_image_info */ void __weak spl_perform_fixups(struct spl_image_info *spl_image) { } void spl_fixup_fdt(void *fdt_blob) { #if defined(CONFIG_SPL_OF_LIBFDT) int err; if (!fdt_blob) return; err = fdt_check_header(fdt_blob); if (err < 0) { printf("fdt_root: %s\n", fdt_strerror(err)); return; } /* fixup the memory dt node */ err = fdt_shrink_to_minimum(fdt_blob, 0); if (err == 0) { printf(SPL_TPL_PROMPT "fdt_shrink_to_minimum err - %d\n", err); return; } err = arch_fixup_fdt(fdt_blob); if (err) { printf(SPL_TPL_PROMPT "arch_fixup_fdt err - %d\n", err); return; } #endif } ulong spl_get_image_pos(void) { return spl_phase() == PHASE_TPL ? binman_sym(ulong, spl, image_pos) : binman_sym(ulong, u_boot_any, image_pos); } ulong spl_get_image_size(void) { return spl_phase() == PHASE_TPL ? binman_sym(ulong, spl, size) : binman_sym(ulong, u_boot_any, size); } ulong spl_get_image_text_base(void) { return spl_phase() == PHASE_TPL ? CONFIG_SPL_TEXT_BASE : CONFIG_SYS_TEXT_BASE; } /* * Weak default function for board specific cleanup/preparation before * Linux boot. Some boards/platforms might not need it, so just provide * an empty stub here. */ __weak void spl_board_prepare_for_linux(void) { /* Nothing to do! */ } __weak void spl_board_prepare_for_optee(void *fdt) { } __weak void spl_board_prepare_for_boot(void) { /* Nothing to do! */ } __weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) { return map_sysmem(CONFIG_SYS_TEXT_BASE + offset, 0); } void spl_set_header_raw_uboot(struct spl_image_info *spl_image) { ulong u_boot_pos = binman_sym(ulong, u_boot_any, image_pos); spl_image->size = CONFIG_SYS_MONITOR_LEN; /* * Binman error cases: address of the end of the previous region or the * start of the image's entry area (usually 0) if there is no previous * region. */ if (u_boot_pos && u_boot_pos != BINMAN_SYM_MISSING) { /* Binman does not support separated entry addresses */ spl_image->entry_point = u_boot_pos; spl_image->load_addr = u_boot_pos; } else { spl_image->entry_point = CONFIG_SYS_UBOOT_START; spl_image->load_addr = CONFIG_SYS_TEXT_BASE; } spl_image->os = IH_OS_U_BOOT; spl_image->name = "U-Boot"; } #if CONFIG_IS_ENABLED(LOAD_FIT_FULL) /* Parse and load full fitImage in SPL */ static int spl_load_fit_image(struct spl_image_info *spl_image, const struct image_header *header) { bootm_headers_t images; const char *fit_uname_config = NULL; uintptr_t fdt_hack; const char *uname; ulong fw_data = 0, dt_data = 0, img_data = 0; ulong fw_len = 0, dt_len = 0, img_len = 0; int idx, conf_noffset; int ret; #ifdef CONFIG_SPL_FIT_SIGNATURE images.verify = 1; #endif ret = fit_image_load(&images, (ulong)header, NULL, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_STANDALONE, -1, FIT_LOAD_OPTIONAL, &fw_data, &fw_len); if (ret >= 0) { printf("DEPRECATED: 'standalone = ' property."); printf("Please use either 'firmware =' or 'kernel ='\n"); } else { ret = fit_image_load(&images, (ulong)header, NULL, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL, &fw_data, &fw_len); } if (ret < 0) { ret = fit_image_load(&images, (ulong)header, NULL, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_KERNEL, -1, FIT_LOAD_OPTIONAL, &fw_data, &fw_len); } if (ret < 0) return ret; spl_image->size = fw_len; spl_image->entry_point = fw_data; spl_image->load_addr = fw_data; if (fit_image_get_os(header, ret, &spl_image->os)) spl_image->os = IH_OS_INVALID; spl_image->name = genimg_get_os_name(spl_image->os); debug(SPL_TPL_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n", spl_image->name, spl_image->load_addr, spl_image->size); #ifdef CONFIG_SPL_FIT_SIGNATURE images.verify = 1; #endif ret = fit_image_load(&images, (ulong)header, NULL, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_FLATDT, -1, FIT_LOAD_OPTIONAL, &dt_data, &dt_len); if (ret >= 0) { spl_image->fdt_addr = (void *)dt_data; if (spl_image->os == IH_OS_U_BOOT) { /* HACK: U-boot expects FDT at a specific address */ fdt_hack = spl_image->load_addr + spl_image->size; fdt_hack = (fdt_hack + 3) & ~3; debug("Relocating FDT to %p\n", spl_image->fdt_addr); memcpy((void *)fdt_hack, spl_image->fdt_addr, dt_len); } } conf_noffset = fit_conf_get_node((const void *)header, fit_uname_config); if (conf_noffset <= 0) return 0; for (idx = 0; uname = fdt_stringlist_get((const void *)header, conf_noffset, FIT_LOADABLE_PROP, idx, NULL), uname; idx++) { #ifdef CONFIG_SPL_FIT_SIGNATURE images.verify = 1; #endif ret = fit_image_load(&images, (ulong)header, &uname, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1, FIT_LOAD_OPTIONAL_NON_ZERO, &img_data, &img_len); if (ret < 0) return ret; } return 0; } #endif __weak int spl_parse_board_header(struct spl_image_info *spl_image, const void *image_header, size_t size) { return -EINVAL; } __weak int spl_parse_legacy_header(struct spl_image_info *spl_image, const struct image_header *header) { /* LEGACY image not supported */ debug("Legacy boot image support not enabled, proceeding to other boot methods\n"); return -EINVAL; } int spl_parse_image_header(struct spl_image_info *spl_image, const struct image_header *header) { #if CONFIG_IS_ENABLED(LOAD_FIT_FULL) int ret = spl_load_fit_image(spl_image, header); if (!ret) return ret; #endif if (image_get_magic(header) == IH_MAGIC) { int ret; ret = spl_parse_legacy_header(spl_image, header); if (ret) return ret; } else { #ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE /* * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the * code which loads images in SPL cannot guarantee that * absolutely all read errors will be reported. * An example is the LPC32XX MLC NAND driver, which * will consider that a completely unreadable NAND block * is bad, and thus should be skipped silently. */ panic("** no mkimage signature but raw image not supported"); #endif #ifdef CONFIG_SPL_OS_BOOT ulong start, end; if (!bootz_setup((ulong)header, &start, &end)) { spl_image->name = "Linux"; spl_image->os = IH_OS_LINUX; spl_image->load_addr = CONFIG_SYS_LOAD_ADDR; spl_image->entry_point = CONFIG_SYS_LOAD_ADDR; spl_image->size = end - start; debug(SPL_TPL_PROMPT "payload zImage, load addr: 0x%lx size: %d\n", spl_image->load_addr, spl_image->size); return 0; } #endif if (!spl_parse_board_header(spl_image, (const void *)header, sizeof(*header))) return 0; #ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT /* Signature not found - assume u-boot.bin */ debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); spl_set_header_raw_uboot(spl_image); #else /* RAW image not supported, proceed to other boot methods. */ debug("Raw boot image support not enabled, proceeding to other boot methods\n"); return -EINVAL; #endif } return 0; } __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { typedef void __noreturn (*image_entry_noargs_t)(void); image_entry_noargs_t image_entry = (image_entry_noargs_t)spl_image->entry_point; debug("image entry point: 0x%lx\n", spl_image->entry_point); image_entry(); } #if CONFIG_IS_ENABLED(HANDOFF) /** * Set up the SPL hand-off information * * This is initially empty (zero) but can be written by */ static int setup_spl_handoff(void) { struct spl_handoff *ho; ho = bloblist_ensure(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff)); if (!ho) return -ENOENT; return 0; } __weak int handoff_arch_save(struct spl_handoff *ho) { return 0; } static int write_spl_handoff(void) { struct spl_handoff *ho; int ret; ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff)); if (!ho) return -ENOENT; handoff_save_dram(ho); ret = handoff_arch_save(ho); if (ret) return ret; debug(SPL_TPL_PROMPT "Wrote SPL handoff\n"); return 0; } #else static inline int setup_spl_handoff(void) { return 0; } static inline int write_spl_handoff(void) { return 0; } #endif /* HANDOFF */ /** * get_bootstage_id() - Get the bootstage ID to emit * * @start: true if this is for starting SPL, false for ending it * @return bootstage ID to use */ static enum bootstage_id get_bootstage_id(bool start) { enum u_boot_phase phase = spl_phase(); if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL) return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL; else return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL; } static int spl_common_init(bool setup_malloc) { int ret; #if CONFIG_VAL(SYS_MALLOC_F_LEN) if (setup_malloc) { #ifdef CONFIG_MALLOC_F_ADDR gd->malloc_base = CONFIG_MALLOC_F_ADDR; #endif gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN); gd->malloc_ptr = 0; } #endif ret = bootstage_init(u_boot_first_phase()); if (ret) { debug("%s: Failed to set up bootstage: ret=%d\n", __func__, ret); return ret; } #ifdef CONFIG_BOOTSTAGE_STASH if (!u_boot_first_phase()) { const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR, CONFIG_BOOTSTAGE_STASH_SIZE); ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE); if (ret) debug("%s: Failed to unstash bootstage: ret=%d\n", __func__, ret); } #endif /* CONFIG_BOOTSTAGE_STASH */ bootstage_mark_name(get_bootstage_id(true), spl_phase_name(spl_phase())); #if CONFIG_IS_ENABLED(LOG) ret = log_init(); if (ret) { debug("%s: Failed to set up logging\n", __func__); return ret; } #endif if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = fdtdec_setup(); if (ret) { debug("fdtdec_setup() returned error %d\n", ret); return ret; } } if (CONFIG_IS_ENABLED(DM)) { bootstage_start(BOOTSTAGE_ID_ACCUM_DM_SPL, spl_phase() == PHASE_TPL ? "dm tpl" : "dm_spl"); /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_SPL); if (ret) { debug("dm_init_and_scan() returned error %d\n", ret); return ret; } } return 0; } void spl_set_bd(void) { /* * NOTE: On some platforms (e.g. x86) bdata may be in flash and not * writeable. */ if (!gd->bd) gd->bd = &bdata; } int spl_early_init(void) { int ret; debug("%s\n", __func__); ret = spl_common_init(true); if (ret) return ret; gd->flags |= GD_FLG_SPL_EARLY_INIT; return 0; } int spl_init(void) { int ret; bool setup_malloc = !(IS_ENABLED(CONFIG_SPL_STACK_R) && IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIMPLE)); debug("%s\n", __func__); if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) { ret = spl_common_init(setup_malloc); if (ret) return ret; } gd->flags |= GD_FLG_SPL_INIT; return 0; } #ifndef BOOT_DEVICE_NONE #define BOOT_DEVICE_NONE 0xdeadbeef #endif __weak void board_boot_order(u32 *spl_boot_list) { spl_boot_list[0] = spl_boot_device(); } static struct spl_image_loader *spl_ll_find_loader(uint boot_device) { struct spl_image_loader *drv = ll_entry_start(struct spl_image_loader, spl_image_loader); const int n_ents = ll_entry_count(struct spl_image_loader, spl_image_loader); struct spl_image_loader *entry; for (entry = drv; entry != drv + n_ents; entry++) { if (boot_device == entry->boot_device) return entry; } /* Not found */ return NULL; } static int spl_load_image(struct spl_image_info *spl_image, struct spl_image_loader *loader) { int ret; struct spl_boot_device bootdev; bootdev.boot_device = loader->boot_device; bootdev.boot_device_name = NULL; ret = loader->load_image(spl_image, &bootdev); #ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK if (!ret && spl_image->dcrc_length) { /* check data crc */ ulong dcrc = crc32_wd(0, (unsigned char *)spl_image->dcrc_data, spl_image->dcrc_length, CHUNKSZ_CRC32); if (dcrc != spl_image->dcrc) { puts("SPL: Image data CRC check failed!\n"); ret = -EINVAL; } } #endif return ret; } /** * boot_from_devices() - Try loading a booting U-Boot from a list of devices * * @spl_image: Place to put the image details if successful * @spl_boot_list: List of boot devices to try * @count: Number of elements in spl_boot_list * @return 0 if OK, -ENODEV if there were no boot devices * if CONFIG_SHOW_ERRORS is enabled, returns -ENXIO if there were * devices but none worked */ static int boot_from_devices(struct spl_image_info *spl_image, u32 spl_boot_list[], int count) { int ret = -ENODEV; int i; for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) { struct spl_image_loader *loader; int bootdev = spl_boot_list[i]; if (CONFIG_IS_ENABLED(SHOW_ERRORS)) ret = -ENXIO; loader = spl_ll_find_loader(bootdev); if (CONFIG_IS_ENABLED(SERIAL_SUPPORT) && CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) && !IS_ENABLED(CONFIG_SILENT_CONSOLE)) { if (loader) printf("Trying to boot from %s\n", spl_loader_name(loader)); else if (CONFIG_IS_ENABLED(SHOW_ERRORS)) printf(SPL_TPL_PROMPT "Unsupported Boot Device %d\n", bootdev); else puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n"); } if (loader && !spl_load_image(spl_image, loader)) { spl_image->boot_device = bootdev; return 0; } } return ret; } #if defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F) void board_init_f(ulong dummy) { if (CONFIG_IS_ENABLED(OF_CONTROL)) { int ret; ret = spl_early_init(); if (ret) { debug("spl_early_init() failed: %d\n", ret); hang(); } } preloader_console_init(); } #endif void board_init_r(gd_t *dummy1, ulong dummy2) { u32 spl_boot_list[] = { BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, }; struct spl_image_info spl_image; int ret; debug(">>" SPL_TPL_PROMPT "board_init_r()\n"); spl_set_bd(); #if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); gd->flags |= GD_FLG_FULL_MALLOC_INIT; #endif if (!(gd->flags & GD_FLG_SPL_INIT)) { if (spl_init()) hang(); } #if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6) /* * timer_init() does not exist on PPC systems. The timer is initialized * and enabled (decrementer) in interrupt_init() here. */ timer_init(); #endif if (CONFIG_IS_ENABLED(BLOBLIST)) { ret = bloblist_init(); if (ret) { debug("%s: Failed to set up bloblist: ret=%d\n", __func__, ret); puts(SPL_TPL_PROMPT "Cannot set up bloblist\n"); hang(); } } if (CONFIG_IS_ENABLED(HANDOFF)) { int ret; ret = setup_spl_handoff(); if (ret) { puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n"); hang(); } } #if CONFIG_IS_ENABLED(BOARD_INIT) spl_board_init(); #endif #if defined(CONFIG_SPL_WATCHDOG) && CONFIG_IS_ENABLED(WDT) initr_watchdog(); #endif if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) || IS_ENABLED(CONFIG_SPL_ATF)) dram_init_banksize(); bootcount_inc(); memset(&spl_image, '\0', sizeof(spl_image)); #ifdef CONFIG_SYS_SPL_ARGS_ADDR spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; #endif spl_image.boot_device = BOOT_DEVICE_NONE; board_boot_order(spl_boot_list); ret = boot_from_devices(&spl_image, spl_boot_list, ARRAY_SIZE(spl_boot_list)); if (ret) { if (CONFIG_IS_ENABLED(SHOW_ERRORS) && CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT)) printf(SPL_TPL_PROMPT "failed to boot from all boot devices (err=%d)\n", ret); else puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n"); hang(); } spl_perform_fixups(&spl_image); if (CONFIG_IS_ENABLED(HANDOFF)) { ret = write_spl_handoff(); if (ret) printf(SPL_TPL_PROMPT "SPL hand-off write failed (err=%d)\n", ret); } if (CONFIG_IS_ENABLED(BLOBLIST)) { ret = bloblist_finish(); if (ret) printf("Warning: Failed to finish bloblist (ret=%d)\n", ret); } #ifdef CONFIG_CPU_V7M spl_image.entry_point |= 0x1; #endif switch (spl_image.os) { case IH_OS_U_BOOT: debug("Jumping to %s...\n", spl_phase_name(spl_next_phase())); break; #if CONFIG_IS_ENABLED(ATF) case IH_OS_ARM_TRUSTED_FIRMWARE: debug("Jumping to U-Boot via ARM Trusted Firmware\n"); spl_fixup_fdt(spl_image.fdt_addr); spl_invoke_atf(&spl_image); break; #endif #if CONFIG_IS_ENABLED(OPTEE) case IH_OS_TEE: debug("Jumping to U-Boot via OP-TEE\n"); spl_board_prepare_for_optee(spl_image.fdt_addr); spl_optee_entry(NULL, NULL, spl_image.fdt_addr, (void *)spl_image.entry_point); break; #endif #if CONFIG_IS_ENABLED(OPENSBI) case IH_OS_OPENSBI: debug("Jumping to U-Boot via RISC-V OpenSBI\n"); spl_invoke_opensbi(&spl_image); break; #endif #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); #if defined(CONFIG_SYS_SPL_ARGS_ADDR) spl_fixup_fdt((void *)CONFIG_SYS_SPL_ARGS_ADDR); #endif spl_board_prepare_for_linux(); jump_to_image_linux(&spl_image); #endif default: debug("Unsupported OS image.. Jumping nevertheless..\n"); } #if CONFIG_VAL(SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) debug("SPL malloc() used 0x%lx bytes (%ld KB)\n", gd->malloc_ptr, gd->malloc_ptr / 1024); #endif bootstage_mark_name(get_bootstage_id(false), "end phase"); #ifdef CONFIG_BOOTSTAGE_STASH ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, CONFIG_BOOTSTAGE_STASH_SIZE); if (ret) debug("Failed to stash bootstage: err=%d\n", ret); #endif spl_board_prepare_for_boot(); jump_to_image_no_args(&spl_image); } /* * This requires UART clocks to be enabled. In order for this to work the * caller must ensure that the gd pointer is valid. */ void preloader_console_init(void) { #ifdef CONFIG_SPL_SERIAL_SUPPORT gd->baudrate = CONFIG_BAUDRATE; serial_init(); /* serial communications setup */ gd->have_console = 1; #if CONFIG_IS_ENABLED(BANNER_PRINT) puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - " U_BOOT_TIME " " U_BOOT_TZ ")\n"); #endif #ifdef CONFIG_SPL_DISPLAY_PRINT spl_display_print(); #endif #endif } /** * This function is called before the stack is changed from initial stack to * relocated stack. It tries to dump the stack size used */ __weak void spl_relocate_stack_check(void) { #if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE) ulong init_sp = gd->start_addr_sp; ulong stack_bottom = init_sp - CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); u8 *ptr = (u8 *)stack_bottom; ulong i; for (i = 0; i < CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); i++) { if (*ptr != CONFIG_VAL(SYS_STACK_F_CHECK_BYTE)) break; ptr++; } printf("SPL initial stack usage: %lu bytes\n", CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - i); #endif } /** * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution * * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM * for the main board_init_r() execution. This is typically because we need * more stack space for things like the MMC sub-system. * * This function calculates the stack position, copies the global_data into * place, sets the new gd (except for ARM, for which setting GD within a C * function may not always work) and returns the new stack position. The * caller is responsible for setting up the sp register and, in the case * of ARM, setting up gd. * * All of this is done using the same layout and alignments as done in * board_init_f_init_reserve() / board_init_f_alloc_reserve(). * * @return new stack location, or 0 to use the same stack */ ulong spl_relocate_stack_gd(void) { #ifdef CONFIG_SPL_STACK_R gd_t *new_gd; ulong ptr = CONFIG_SPL_STACK_R_ADDR; if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)) spl_relocate_stack_check(); #if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_VAL(SYS_MALLOC_F_LEN) if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) { debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n", gd->malloc_ptr, gd->malloc_ptr / 1024); ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN; gd->malloc_base = ptr; gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN; gd->malloc_ptr = 0; } #endif /* Get stack position: use 8-byte alignment for ABI compliance */ ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16); new_gd = (gd_t *)ptr; memcpy(new_gd, (void *)gd, sizeof(gd_t)); #if CONFIG_IS_ENABLED(DM) dm_fixup_for_gd_move(new_gd); #endif #if !defined(CONFIG_ARM) && !defined(CONFIG_RISCV) gd = new_gd; #endif return ptr; #else return 0; #endif } #if defined(CONFIG_BOOTCOUNT_LIMIT) && \ ((!defined(CONFIG_TPL_BUILD) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT)) || \ (defined(CONFIG_TPL_BUILD) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT))) void bootcount_store(ulong a) { } ulong bootcount_load(void) { return 0; } #endif
11-11
xref: /MT6769_15.0.0_release/vnd/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6768/platform.c HomeAnnotateLine# Scopes# Navigate#Raw Download current directory 1 /* Copyright Statement: 2 * 3 * This software/firmware and related documentation ("MediaTek Software") are 4 * protected under relevant copyright laws. The information contained herein 5 * is confidential and proprietary to MediaTek Inc. and/or its licensors. 6 * Without the prior written permission of MediaTek inc. and/or its licensors, 7 * any reproduction, modification, use or disclosure of MediaTek Software, 8 * and information contained herein, in whole or in part, shall be strictly prohibited. 9 */ 10 /* MediaTek Inc. (C) 2015. All rights reserved. 11 * 12 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES 13 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") 14 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON 15 * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. 18 * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE 19 * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR 20 * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH 21 * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES 22 * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES 23 * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK 24 * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR 25 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND 26 * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, 27 * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, 28 * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO 29 * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 30 */ 31 32 #include <debug.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <video.h> 36 #include <dev/uart.h> 37 #include <arch/arm.h> 38 #include <arch/arm/mmu.h> 39 #include <arch/ops.h> 40 #include <target/board.h> 41 #include <platform/mt_reg_base.h> 42 #include <platform/mt_disp_drv.h> 43 #include <platform/disp_drv.h> 44 #include <platform/boot_mode.h> 45 #include <platform/mt_logo.h> 46 #include <platform/partition.h> 47 #include <env.h> 48 #include <platform/mt_gpio.h> 49 #include <platform/mt_pmic.h> 50 #include <platform/mt_pmic_dlpt.h> 51 #include <platform/mt_pmic_wrap_init.h> 52 #include <platform/mt_i2c.h> 53 #include <spi_slave.h> 54 #include <platform/mtk_key.h> 55 #include <platform/mtk_smi.h> 56 #include <platform/mt_rtc.h> 57 #include <platform/mt_leds.h> 58 #include <platform/upmu_common.h> 59 #include <mtk_wdt.h> 60 #include <platform/disp_drv_platform.h> 61 #include <platform/verified_boot.h> 62 #include <platform/sec_devinfo.h> 63 #include <plinfo.h> // for plinfo_get_brom_header_block_size() 64 #include <libfdt.h> 65 #include <mt_gic.h> // for platform_init_interrupts() 66 #include <mt_boot.h> // for bldr_load_dtb() 67 #include <mtk_dcm.h> // for mt_dcm_init() 68 #include <fpga_boot_argument.h> 69 #include <profiling.h> 70 #include <assert.h> 71 #include <platform/mt_gpt.h> // for get_timer() 72 #include <sec_export.h> 73 #include "memory_layout.h" 74 #include "load_vfy_boot.h" 75 #include <fdt_op.h> 76 #include <verified_boot_common.h> 77 #include <platform/mtk_charger_intf.h> 78 #include <rsc.h> 79 #ifdef MTK_SMC_ID_MGMT 80 #include "mtk_secure_api.h" 81 #endif 82 #include "mtk_dcm.h" //for mt_dcm_init() 83 #ifdef MTK_EMMC_SUPPORT 84 #include "mmc_rpmb.h" 85 #endif 86 87 #define DEVAPC_TURN_ON 1 88 89 //like@BSP.Storage.EMMC, 2022/11/25 add for getting emmc health info 90 #include "emmc_health_info.h" 91 //like@BSP.Storage.Emmc, 2022/11/25 add for emmc fw upgrade 92 #include "emmc_upgrade.h" 93 #ifdef MTK_UFS_SUPPORT 94 //like@BSP.Storage.UFS, 2022/11/25 add for emmc/ufs compatible 95 #include "ufs_upgrade.h" 96 #endif 97 #if defined(MTK_VPU_SUPPORT) 98 #include <platform/mt_vpu.h> 99 #endif 100 101 #ifdef MTK_AB_OTA_UPDATER 102 #include "bootctrl.h" 103 #endif 104 105 #if defined(MTK_SECURITY_SW_SUPPORT) 106 #include "oemkey.h" 107 #endif 108 #ifdef MTK_UFS_SUPPORT 109 #include "ufs_aio_interface.h" 110 #endif 111 112 #ifdef MTK_CHARGER_NEW_ARCH 113 #include <mtk_charger.h> 114 #include <mtk_battery.h> 115 #endif 116 #include "show_animation_common.h" 117 118 #ifdef MTK_SECURITY_SW_SUPPORT 119 extern u8 g_oemkey[OEM_PUBK_SZ]; 120 #endif 121 122 #ifdef LK_DL_CHECK 123 /*block if check dl fail*/ 124 #undef LK_DL_CHECK_BLOCK_LEVEL 125 #endif 126 127 #ifdef OPLUS_FEATURE_CHG_BASIC 128 #define VIB_BOOT_THRESHOLD_MV 3200 129 #define VIB_DURATION 300 130 #endif 131 132 extern void platform_early_init_timer(); 133 extern void jump_da(u32 addr, u32 arg1, u32 arg2); 134 extern int i2c_hw_init(void); 135 extern int mboot_common_load_logo(unsigned long logo_addr, char* filename); 136 extern int sec_func_init(u64 pl_start_addr); 137 extern int sec_usbdl_enabled (void); 138 extern unsigned int crypto_hw_engine_disable(void); 139 extern void mtk_wdt_disable(void); 140 extern void platform_deinit_interrupts(void); 141 extern int mmc_get_dl_info(void); 142 extern int mmc_legacy_init(int); 143 extern void platform_clear_all_on_mux(void); 144 extern unsigned int crypto_hw_engine_disable(void); 145 #ifdef MTK_AEE_PLATFORM_DEBUG_SUPPORT 146 extern void latch_lastbus_init(void); 147 #endif 148 149 #ifdef MTK_BATLOWV_NO_PANEL_ON_EARLY 150 extern kal_bool is_low_battery(kal_int32 val); 151 extern int hw_charging_get_charger_type(void); 152 #endif 153 154 #ifdef MTK_LK_REGISTER_WDT 155 extern void lk_register_wdt_callback(void); 156 #endif 157 158 void platform_uninit(void); 159 void config_shared_SRAM_size(void); 160 extern int dev_info_nr_cpu(void); 161 extern void mt_pll_turn_off(void); 162 163 struct mmu_initial_mapping mmu_initial_mappings[] = { 164 165 { 166 .phys = (uint64_t)0, 167 .virt = (uint32_t)0, 168 .size = 0x40000000, 169 .flags = MMU_MEMORY_TYPE_STRONGLY_ORDERED | MMU_MEMORY_AP_P_RW_U_NA, 170 .name = "mcusys" 171 }, 172 { 173 .phys = (uint64_t)MEMBASE, 174 .virt = (uint32_t)MEMBASE, 175 .size = ROUNDUP(MEMSIZE, SECTION_SIZE), 176 .flags = MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA, 177 .name = "ram" 178 }, 179 { 180 .phys = (uint64_t)SCRATCH_ADDR, 181 .virt = (uint32_t)SCRATCH_ADDR, 182 .size = SCRATCH_SIZE, 183 .flags = MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA, 184 .name = "download" 185 }, 186 /* null entry to terminate the list */ 187 { 0 } 188 }; 189 190 BOOT_ARGUMENT *g_boot_arg; 191 BOOT_ARGUMENT boot_addr; 192 int g_nr_bank; 193 BI_DRAM bi_dram[MAX_NR_BANK]; 194 unsigned int g_fb_base; 195 unsigned int g_fb_size; 196 static int g_dram_init_ret; 197 static unsigned int bootarg_addr; 198 static unsigned int bootarg_size; 199 extern unsigned int logo_lk_t; 200 extern unsigned int boot_time; 201 unsigned int m_sec_usb_dl; 202 unsigned int m_sec_boot; 203 unsigned char m_seccfg_ac_en; 204 205 int dram_init(void) 206 { 207 unsigned int i; 208 struct boot_tag *tags; 209 210 /* Get parameters from pre-loader. Get as early as possible 211 * The address of BOOT_ARGUMENT_LOCATION will be used by Linux later 212 * So copy the parameters from BOOT_ARGUMENT_LOCATION to LK's memory region 213 */ 214 g_boot_arg = &boot_addr; 215 bootarg_addr = (unsigned int)((unsigned int *)BOOT_ARGUMENT_LOCATION); 216 bootarg_size = 0; 217 218 fpga_set_boot_argument((BOOT_ARGUMENT*)bootarg_addr); 219 220 if (*(unsigned int *)BOOT_ARGUMENT_LOCATION == BOOT_ARGUMENT_MAGIC) { 221 memcpy(g_boot_arg, (void*)BOOT_ARGUMENT_LOCATION, sizeof(BOOT_ARGUMENT)); 222 bootarg_size = sizeof(BOOT_ARGUMENT); 223 } else { 224 g_boot_arg->maggic_number = BOOT_ARGUMENT_MAGIC; 225 for (tags = (void *)BOOT_ARGUMENT_LOCATION; tags->hdr.size; tags = boot_tag_next(tags)) { 226 switch (tags->hdr.tag) { 227 case BOOT_TAG_BOOT_REASON: 228 g_boot_arg->boot_reason = tags->u.boot_reason.boot_reason; 229 break; 230 case BOOT_TAG_BOOT_MODE: 231 g_boot_arg->boot_mode = tags->u.boot_mode.boot_mode; 232 break; 233 case BOOT_TAG_META_COM: 234 g_boot_arg->meta_com_type = tags->u.meta_com.meta_com_type; 235 g_boot_arg->meta_com_id = tags->u.meta_com.meta_com_id; 236 g_boot_arg->meta_uart_port = tags->u.meta_com.meta_uart_port; 237 g_boot_arg->meta_log_disable = tags->u.meta_com.meta_log_disable; 238 g_boot_arg->fast_meta_gpio = tags->u.meta_com.fast_meta_gpio; 239 break; 240 case BOOT_TAG_LOG_COM: 241 g_boot_arg->log_port = tags->u.log_com.log_port; 242 g_boot_arg->log_baudrate = tags->u.log_com.log_baudrate; 243 g_boot_arg->log_enable = tags->u.log_com.log_enable; 244 g_boot_arg->log_dynamic_switch = tags->u.log_com.log_dynamic_switch; 245 break; 246 case BOOT_TAG_MEM: 247 g_boot_arg->dram_rank_num = tags->u.mem.dram_rank_num; 248 for (i = 0; i < tags->u.mem.dram_rank_num; i++) { 249 g_boot_arg->dram_rank_size[i] = tags->u.mem.dram_rank_size[i]; 250 } 251 g_boot_arg->mblock_info = tags->u.mem.mblock_info; 252 g_boot_arg->orig_dram_info = tags->u.mem.orig_dram_info; 253 g_boot_arg->lca_reserved_mem = tags->u.mem.lca_reserved_mem; 254 g_boot_arg->tee_reserved_mem = tags->u.mem.tee_reserved_mem; 255 break; 256 case BOOT_TAG_MD_INFO: 257 for (i = 0; i < 4; i++) { 258 g_boot_arg->md_type[i] = tags->u.md_info.md_type[i]; 259 } 260 break; 261 case BOOT_TAG_BOOT_TIME: 262 g_boot_arg->boot_time = tags->u.boot_time.boot_time; 263 break; 264 case BOOT_TAG_DA_INFO: 265 memcpy(&g_boot_arg->da_info, &tags->u.da_info.da_info, sizeof(da_info_t)); 266 break; 267 case BOOT_TAG_SEC_INFO: 268 memcpy(&g_boot_arg->sec_limit, &tags->u.sec_info.sec_limit, sizeof(SEC_LIMIT)); 269 break; 270 case BOOT_TAG_PART_NUM: 271 g_boot_arg->part_num = tags->u.part_num.part_num; 272 break; 273 case BOOT_TAG_PART_INFO: 274 g_boot_arg->part_info = tags->u.part_info.part_info; /* only copy the pointer but the contains*/ 275 break; 276 case BOOT_TAG_EFLAG: 277 g_boot_arg->e_flag = tags->u.eflag.e_flag; 278 break; 279 case BOOT_TAG_DDR_RESERVE: 280 g_boot_arg->ddr_reserve_enable = tags->u.ddr_reserve.ddr_reserve_enable; 281 g_boot_arg->ddr_reserve_success = tags->u.ddr_reserve.ddr_reserve_success; 282 g_boot_arg->ddr_reserve_ready = tags->u.ddr_reserve.ddr_reserve_ready; 283 break; 284 case BOOT_TAG_DRAM_BUF: 285 g_boot_arg->dram_buf_size = tags->u.dram_buf.dram_buf_size; 286 break; 287 case BOOT_TAG_SRAM_INFO: 288 g_boot_arg->non_secure_sram_addr = tags->u.sram_info.non_secure_sram_addr; 289 g_boot_arg->non_secure_sram_size = tags->u.sram_info.non_secure_sram_size; 290 break; 291 case BOOT_TAG_PLAT_DBG_INFO: 292 g_boot_arg->plat_dbg_info_max = tags->u.plat_dbg_info.info_max; 293 if (g_boot_arg->plat_dbg_info_max > INFO_TYPE_MAX) 294 g_boot_arg->plat_dbg_info_max = INFO_TYPE_MAX; 295 for (i = 0; i < g_boot_arg->plat_dbg_info_max; i++) { 296 g_boot_arg->plat_dbg_info[i].key = tags->u.plat_dbg_info.info[i].key; 297 g_boot_arg->plat_dbg_info[i].base = tags->u.plat_dbg_info.info[i].base; 298 g_boot_arg->plat_dbg_info[i].size = tags->u.plat_dbg_info.info[i].size; 299 } 300 break; 301 case BOOT_TAG_PTP: 302 memcpy(&g_boot_arg->ptp_volt_info, &tags->u.ptp_volt.ptp_volt_info, sizeof(ptp_info_t)); 303 break; 304 case BOOT_TAG_EMI_INFO: 305 memcpy(&(g_boot_arg->emi_info), &(tags->u.emi_info), sizeof(emi_info_t)); 306 break; 307 case BOOT_TAG_IMGVER_INFO: 308 g_boot_arg->pl_imgver_status = tags->u.imgver_info.pl_imgver_status; 309 break; 310 case BOOT_TAG_MAX_CPUS: 311 g_boot_arg->max_cpus = tags->u.max_cpus.max_cpus; 312 break; 313 case BOOT_TAG_BAT_INFO: 314 g_boot_arg->boot_voltage = tags->u.bat_info.boot_voltage; 315 g_boot_arg->shutdown_time= tags->u.bat_info.shutdown_time; 316 break; 317 //#ifdef OPLUS_FEATURE_OEM_OCDT 318 case BOOT_TAG_OPLUSPROJECT_INFO: 319 g_boot_arg->nProject = tags->u.oplusproject_info.nProject; 320 g_boot_arg->nModem = tags->u.oplusproject_info.nModem; 321 g_boot_arg->nOperator = tags->u.oplusproject_info.nOperator; 322 g_boot_arg->nPCBVersion = tags->u.oplusproject_info.nPCBVersion; 323 g_boot_arg->nDownloadStatus =tags->u.oplusproject_info.nDownloadStatus; 324 g_boot_arg->nENGVersion = tags->u.oplusproject_info.nENGVersion; 325 g_boot_arg->isConfidential =tags->u.oplusproject_info.isConfidential; 326 break; 327 //#endif OPLUS_FEATURE_OEM_OCDT 328 case BOOT_TAG_RAM_CONSOLE_INFO: 329 g_boot_arg->ram_console_sram_addr = tags->u.ram_console_info.sram_addr; 330 g_boot_arg->ram_console_sram_size = tags->u.ram_console_info.sram_size; 331 g_boot_arg->ram_console_def_type = tags->u.ram_console_info.def_type; 332 g_boot_arg->ram_console_memory_info_offset = tags->u.ram_console_info.memory_info_offset; 333 break; 334 case BOOT_TAG_CHR_INFO: 335 g_boot_arg->charger_type = tags->u.chr_info.charger_type; 336 break; 337 #if WITH_GZ_MD_SHAREMEM 338 case BOOT_TAG_GZ_PARAM: 339 g_boot_arg->gz_md_shm_pa = tags->u.gz_param.modemMteeShareMemPA; 340 g_boot_arg->gz_md_shm_sz = tags->u.gz_param.modemMteeShareMemSize; 341 break; 342 #endif 343 case BOOT_TAG_SOC_ID: 344 memcpy(g_boot_arg->socid, tags->u.socid.id, SOC_ID_LEN); 345 break; 346 //#ifdef OPLUS_FEATURE_OEM_OCDT 347 case BOOT_TAG_OPLUSCDT_INFO: 348 g_boot_arg->nVersion = tags->u.opluscdt_info.nVersion; 349 g_boot_arg->nProject_newcdt = tags->u.opluscdt_info.nProject; 350 g_boot_arg->nDtsi = tags->u.opluscdt_info.nDtsi; 351 g_boot_arg->nAudio = tags->u.opluscdt_info.nAudio; 352 for (i = 0; i < FEATURE_COUNT; i++) { 353 g_boot_arg->nFeature[i] = tags->u.opluscdt_info.nFeature[i]; 354 } 355 g_boot_arg->newcdt = tags->u.opluscdt_info.newcdt; 356 g_boot_arg->nDownloadStatus_newcdt =tags->u.opluscdt_info.nDownloadStatus; 357 g_boot_arg->eng_version = tags->u.opluscdt_info.eng_version; 358 g_boot_arg->is_confidential = tags->u.opluscdt_info.is_confidential; 359 break; 360 //#endif OPLUS_FEATURE_OEM_OCDT 361 case BOOT_TAG_ROM_INFO: 362 m_sec_usb_dl = tags->u.rom_info.m_sec_usb_dl; 363 m_sec_boot = tags->u.rom_info.m_sec_boot; 364 m_seccfg_ac_en = tags->u.rom_info.m_seccfg_ac_en; 365 break; 366 default: 367 break; 368 } 369 bootarg_size += tags->hdr.size; 370 } 371 } 372 fpga_copy_boot_argument(g_boot_arg); 373 374 g_nr_bank = g_boot_arg->dram_rank_num; 375 376 if (g_nr_bank == 0 || g_nr_bank > MAX_NR_BANK) { 377 g_dram_init_ret = -1; 378 //dprintf(CRITICAL, "[LK ERROR] DRAM bank number is not correct!!!"); 379 //while (1) ; 380 return -1; 381 } 382 383 return 0; 384 } 385 386 unsigned int platform_get_bootarg_addr(void) 387 { 388 return bootarg_addr; 389 } 390 391 unsigned int platform_get_bootarg_size(void) 392 { 393 return bootarg_size; 394 } 395 396 /******************************************************* 397 * Routine: memory_size 398 * Description: return DRAM size to LCM driver 399 ******************************************************/ 400 u32 ddr_enable_4gb(void) 401 { 402 u32 status; 403 #define INFRA_MISC (INFRACFG_AO_BASE + 0x0F00) 404 #define INFRA_4GB_EN (1 << 13) 405 #define PERI_MISC (PERICFG_BASE + 0x0208) 406 #define PERI_4GB_EN (1 << 15) 407 408 status = ((DRV_Reg32(INFRA_MISC) & INFRA_4GB_EN) && (DRV_Reg32(PERI_MISC) & PERI_4GB_EN)) ? 1 : 0; 409 dprintf(CRITICAL, "%s() status=%u\n", __func__, status); 410 411 return status; 412 } 413 414 u64 physical_memory_size(void) 415 { 416 int i; 417 unsigned long long size = 0; 418 419 for (i = 0; i < (int)(g_boot_arg->orig_dram_info.rank_num); i++) { 420 size += g_boot_arg->orig_dram_info.rank_info[i].size; 421 } 422 423 return size; 424 } 425 426 u32 memory_size(void) 427 { 428 unsigned long long size = physical_memory_size(); 429 430 while (((unsigned long long)DRAM_PHY_ADDR + size) > 0x100000000ULL) { 431 size -= (unsigned long long)(1024*1024*1024); 432 } 433 434 return (unsigned int)size; 435 } 436 437 void sw_env() 438 { 439 //#ifdef OPLUS_BUG_STABILITY 440 /* Fuchun.Liao@BSP.CHG.Basic 2019/11/11 add for new cdt download info */ 441 u32 nDownloadStatus = 0; 442 //#endif /* OPLUS_BUG_STABILITY */ 443 #ifdef LK_DL_CHECK 444 #if defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_SUPPORT) 445 int dl_status = 0; 446 dl_status = mmc_get_dl_info(); 447 dprintf(INFO, "mt65xx_sw_env--dl_status: %d\n", dl_status); 448 if (dl_status != 0) { 449 video_printf("=> TOOL DL image Fail!\n"); 450 dprintf(CRITICAL, "TOOL DL image Fail\n"); 451 #ifdef LK_DL_CHECK_BLOCK_LEVEL 452 dprintf(CRITICAL, "uboot is blocking by dl info\n"); 453 while (1) ; 454 #endif 455 } 456 #endif 457 #endif 458 459 460 //#ifdef OPLUS_BUG_STABILITY 461 /* MingQiang.Guo@PSW.BSP.bootloader.bootflow, 2017/11/18, Add for check download over flag*/ 462 if (is_new_cdt()) { 463 nDownloadStatus = g_boot_arg->nDownloadStatus_newcdt; 464 } else { 465 nDownloadStatus = g_boot_arg->nDownloadStatus; 466 } 467 if (nDownloadStatus == BOOT_TAG_DOWNLOAD_OVER) { 468 dprintf(CRITICAL, "=> [oppo]Tool Download ok! 0x%x\n",g_boot_arg->nDownloadStatus); 469 } else if (nDownloadStatus == BOOT_TAG_DOWNLOAD_FAIL){ 470 video_printf("=> Download not completed! Please press volume+ and power key 10s to power off.\ 471 Then download again. Otherwise will block here 60S until shutdown automatically.\ 472 error code: 0x%x\n", nDownloadStatus); 473 dprintf(CRITICAL, "=> Download not completed! Please press volume+ and power key 10s to power off.\ 474 Then download again. Otherwise will block here 60S until shutdown automatically.\ 475 error code: 0x%x\n", nDownloadStatus); 476 mtk_wdt_disable(); 477 mdelay(60000); 478 mt_power_off(); 479 } 480 //#endif/*OPLUS_BUG_STABILITY*/ 481 482 #ifndef MACH_FPGA_NO_DISPLAY 483 #ifndef USER_BUILD 484 switch (g_boot_mode) { 485 case META_BOOT: 486 video_printf(" => META MODE\n"); 487 break; 488 case FACTORY_BOOT: 489 video_printf(" => FACTORY MODE\n"); 490 break; 491 case RECOVERY_BOOT: 492 video_printf(" => RECOVERY MODE\n"); 493 break; 494 case SW_REBOOT: 495 //video_printf(" => SW RESET\n"); 496 break; 497 case NORMAL_BOOT: 498 //if(g_boot_arg->boot_reason != BR_RTC && get_env("hibboot") != NULL && atoi(get_env("hibboot")) == 1) 499 if (get_env("hibboot") != NULL && atoi(get_env("hibboot")) == 1) 500 video_printf(" => HIBERNATION BOOT\n"); 501 else 502 video_printf(" => NORMAL BOOT\n"); 503 break; 504 case ADVMETA_BOOT: 505 video_printf(" => ADVANCED META MODE\n"); 506 break; 507 case ATE_FACTORY_BOOT: 508 video_printf(" => ATE FACTORY MODE\n"); 509 break; 510 #ifdef MTK_KERNEL_POWER_OFF_CHARGING 511 case KERNEL_POWER_OFF_CHARGING_BOOT: 512 video_printf(" => POWER OFF CHARGING MODE\n"); 513 break; 514 case LOW_POWER_OFF_CHARGING_BOOT: 515 video_printf(" => LOW POWER OFF CHARGING MODE\n"); 516 break; 517 #endif 518 case ALARM_BOOT: 519 video_printf(" => ALARM BOOT\n"); 520 break; 521 case FASTBOOT: 522 video_printf(" => FASTBOOT mode...\n"); 523 break; 524 default: 525 video_printf(" => UNKNOWN BOOT\n"); 526 } 527 return; 528 #endif 529 530 #ifdef USER_BUILD 531 /* it's ok to display META MODE since it already verfied by preloader */ 532 if (g_boot_mode == META_BOOT) 533 video_printf(" => META MODE\n"); 534 if (g_boot_mode == FASTBOOT) 535 video_printf(" => FASTBOOT mode...\n"); 536 #ifdef OPLUS_FEATURE_OEM_BOOT_MODE 537 if (g_boot_mode == FACTORY_BOOT) 538 video_printf(" => FACTORY mode...\n"); 539 if (g_boot_mode == RECOVERY_BOOT) 540 video_printf(" => RECOVERY mode...\n"); 541 #endif 542 return; 543 #endif 544 #endif /* MACH_FPGA_NO_DISPLAY */ 545 } 546 547 extern uint64_t ld_tt_l1[4]; 548 void platform_init_mmu(void) 549 { 550 /* configure available RAM banks */ 551 dram_init(); 552 /* Long-descriptor translation with lpae enable */ 553 arm_mmu_lpae_init(); 554 555 struct mmu_initial_mapping *m = mmu_initial_mappings; 556 557 for (uint i = 0; i < countof(mmu_initial_mappings); i++, m++) { 558 arch_mmu_map(m->phys, m->virt, m->flags, m->size); 559 } 560 561 arch_enable_mmu(); //enable mmu after setup page table to avoid cpu prefetch which may bring on emi violation 562 } 563 564 565 /****************************************************************************** 566 ******************************************************************************/ 567 void init_storage(void) 568 { 569 PROFILING_START("NAND/EMMC init"); 570 571 #if defined(MTK_EMMC_SUPPORT) 572 mmc_legacy_init(1); 573 #elif defined(MTK_UFS_SUPPORT) 574 ufs_lk_init(); 575 #else 576 #ifndef MACH_FPGA 577 nand_init(); 578 nand_driver_test(); 579 #endif // MACH_FPGA 580 #endif // MTK_EMMC_SUPPORT 581 582 #if defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_SUPPORT) 583 init_rpmb_sharemem(); 584 #endif 585 586 PROFILING_END(); /* NAND/EMMC init */ 587 } 588 589 590 /****************************************************************************** 591 ******************************************************************************/ 592 void platform_early_init(void) 593 { 594 PROFILING_START("platform_early_init"); 595 #ifdef MTK_LK_REGISTER_WDT 596 lk_register_wdt_callback(); 597 #endif 598 599 /* initialize the uart */ 600 uart_init_early(); 601 602 PROFILING_START("Devinfo Init"); 603 init_devinfo_data(); 604 PROFILING_END(); 605 606 platform_init_interrupts(); 607 #ifndef MTK_POL_DEPRECATED 608 #ifdef MTK_SYSIRQ_INIT_LK 609 mt_irq_sysirq_init(); 610 #endif 611 #endif 612 platform_early_init_timer(); 613 614 #if !defined(USE_DTB_NO_DWS) && !defined(MACH_FPGA) 615 mt_gpio_set_default(); 616 #endif // !defined(USE_DTB_NO_DWS) && !defined(MACH_FPGA) 617 618 dprintf(SPEW, "bootarg_addr: 0x%x, bootarg_size: 0x%x\n", platform_get_bootarg_addr(), platform_get_bootarg_size()); 619 620 if (g_dram_init_ret < 0) { 621 dprintf(CRITICAL, "[LK ERROR] DRAM bank number is not correct!!!\n"); 622 while (1) ; 623 } 624 625 //i2c_v1_init(); 626 PROFILING_START("WDT Init"); 627 mtk_wdt_init(); 628 PROFILING_END(); 629 630 //i2c init 631 i2c_hw_init(); 632 633 #ifdef MACH_FPGA 634 mtk_timer_init(); // GPT4 will be initialized at PL after 635 mtk_wdt_disable(); // WDT will be triggered when uncompressing linux image on FPGA 636 #endif 637 pwrap_init_lk(); 638 639 #if !defined(MACH_FPGA) && !defined(NO_PMIC) 640 PROFILING_START("pmic_init"); 641 pmic_init(); 642 PROFILING_END(); 643 #endif // !defined(MACH_FPGA) && !defined(NO_PMIC) 644 PROFILING_END(); /* platform_early_init */ 645 } 646 647 extern void mt65xx_bat_init(void); 648 extern bool mtk_bat_allow_backlight_enable(void); 649 #if defined (MTK_KERNEL_POWER_OFF_CHARGING) 650 651 int kernel_charging_boot(void) 652 { 653 if ((g_boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT || g_boot_mode == LOW_POWER_OFF_CHARGING_BOOT) && upmu_is_chr_det() == KAL_TRUE) { 654 dprintf(INFO,"[%s] Kernel Power Off Charging with Charger/Usb \n", __func__); 655 return 1; 656 } else if ((g_boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT || g_boot_mode == LOW_POWER_OFF_CHARGING_BOOT) && upmu_is_chr_det() == KAL_FALSE) { 657 dprintf(INFO,"[%s] Kernel Power Off Charging without Charger/Usb \n", __func__); 658 return -1; 659 } else 660 return 0; 661 } 662 #endif 663 664 static void lk_vb_init(void) 665 { 666 #ifdef MTK_SECURITY_SW_SUPPORT 667 u64 pl_start_addr = 0; 668 #ifdef MTK_VER_SIMPLE_TEST 669 u32 ret = 0; 670 ret = sec_mtk_internal_ver_test(MTK_VER_SIMPLE_TEST); 671 if (ret) 672 assert(0); 673 #endif 674 675 #ifdef MTK_OTP_FRAMEWORK_V2 676 enable_anti_rollback_v2_framework(); 677 #endif 678 679 plinfo_get_brom_header_block_size(&pl_start_addr); 680 681 PROFILING_START("Security init"); 682 /* initialize security library */ 683 sec_func_init(pl_start_addr); 684 seclib_set_oemkey(g_oemkey, OEM_PUBK_SZ); 685 PROFILING_END(); 686 #endif 687 } 688 689 static void lk_vb_vfy_logo(void) 690 { 691 #ifdef MTK_SECURITY_SW_SUPPORT 692 /* bypass logo vfy in fast meta mode */ 693 if(g_boot_mode == META_BOOT) 694 return; 695 696 PROFILING_START("logo verify"); 697 /*Verify logo before use it*/ 698 if (0 != img_auth_stor("logo", "logo", 0x0)) 699 assert(0); 700 701 PROFILING_END(); 702 #endif 703 } 704 705 //#ifdef OPLUS_FEATURE_SECURITY_COMMON 706 int32_t mtk_set_boot_info_to_rpmb() 707 { 708 int32_t ret = 0; 709 uint32_t sboot_state = 1; 710 int32_t lock_state = 1; 711 int32_t isunlocked = 0; 712 713 ret = get_sboot_state(&sboot_state); 714 if (ret) { 715 sboot_state = 1; //set default:secureboot on:1; off:0 716 } 717 718 if (sboot_state == 1) { 719 cmdline_append("mtkboot.sbootstate=on"); 720 } 721 722 ret = sec_query_device_lock(&lock_state); 723 if (ret) { 724 lock_state = 1; //set default:device lock:1 ; unlock:0 725 } 726 727 if (lock_state == 0) 728 isunlocked = 1; 729 730 dprintf(CRITICAL, "sboot_state is %d, lock_state is %d, isunlocked is %d \n", sboot_state, lock_state, isunlocked); 731 ret = set_boot_info_to_rpmb((bool)sboot_state, isunlocked); 732 if (ret) { 733 dprintf(CRITICAL, "%s set boot info to rpmb fail !!!\n", __func__); 734 } 735 736 return ret; 737 } 738 //#endif /* OPLUS_FEATURE_SECURITY_COMMON */ 739 740 void platform_init(void) 741 { 742 bool backlight_on = false; 743 int logo_size; 744 //like@BSP.Storage.UFS, 2022/11/25 add for emmc/UFS compatible 745 part_dev_t *dev; 746 747 #ifdef OPLUS_FEATURE_CHG_BASIC 748 int boot_vbat; 749 int chr_vol = 0; 750 751 /* 5 doesn't mean anything in this function */ 752 boot_vbat = get_bat_volt(5); 753 #endif /*OPLUS_FEATURE_CHG_BASIC*/ 754 755 PROFILING_START("platform_init"); 756 dprintf(CRITICAL, "platform_init()\n"); 757 758 init_storage(); 759 lk_vb_init(); 760 //like@BSP.Storage.UFS, 2022/11/25 add for emmc/ufs compatible 761 dev = mt_part_get_device(); 762 763 extern void dummy_ap_entry(void)__attribute__((weak)); /* This is empty function for normal load */ 764 if (dummy_ap_entry) 765 dummy_ap_entry(); 766 767 #ifdef MTK_AB_OTA_UPDATER 768 /* get A/B system parameter before load dtb from boot image */ 769 get_AB_OTA_param(); 770 #endif 771 /* 772 * RSC initialize. It must be done before load device tree. 773 * rsc_init will ectract DTBO index, which will be used in device 774 * tree overlay, from PARA partition 775 */ 776 rsc_init(); 777 778 /* The device tree should be loaded as early as possible. */ 779 load_device_tree(); 780 781 #if defined(USE_DTB_NO_DWS) && !defined(MACH_FPGA) 782 mt_gpio_set_default(); 783 #endif // defined(USE_DTB_NO_DWS) && !defined(MACH_FPGA) 784 bdg_tx_pull_6382_reset_pin(); 785 786 clk_buf_disp_ctrl(true); 787 /* spi slave driver probe */ 788 spi_slave_probe(); 789 #ifdef MT6768_REF_DEV 790 mdelay(5); 791 bdg_tx_pull_6382_reset_pin(); 792 #endif 793 794 #ifdef OPLUS_FEATURE_CHG_BASIC 795 struct mtk_charger_info *primary_mchr = NULL; 796 mtk_charger_init(); 797 primary_mchr = mtk_charger_get_by_name("primary_charger"); 798 if (!primary_mchr) { 799 dprintf(CRITICAL, "%s: get primary charger failed\n", __func__); 800 } else { 801 dprintf(CRITICAL, "%s: get primary charger OK\n", __func__); 802 mtk_charger_set_ichg(primary_mchr, 300); 803 mtk_charger_set_aicr(primary_mchr, 1000); 804 mtk_charger_enable_charging(primary_mchr, KAL_TRUE); 805 } 806 #endif /*OPLUS_FEATURE_CHG_BASIC*/ 807 808 #ifndef MACH_FPGA 809 PROFILING_START("led init"); 810 leds_init(); 811 PROFILING_END(); 812 #endif // MACH_FPGA 813 814 #ifdef MTK_KERNEL_POWER_OFF_CHARGING 815 if ((g_boot_arg->boot_reason == BR_USB) && (upmu_is_chr_det() == KAL_FALSE)) { 816 dprintf(INFO, "[%s] Unplugged Charger/Usb between Pre-loader and Uboot in Kernel Charging Mode, Power Off \n", __func__); 817 mt_power_off(); 818 } 819 #endif // MTK_KERNEL_POWER_OFF_CHARGING 820 821 #ifndef MACH_FPGA_NO_DISPLAY 822 PROFILING_START("ENV init"); 823 env_init(); 824 print_env(); 825 PROFILING_END(); 826 if (g_boot_arg->boot_mode == NORMAL_BOOT) 827 { 828 if (dev->blkdev->type == BOOTDEV_SDMMC) 829 cmd_oem_getemmcinfo(); 830 #ifdef MTK_UFS_SUPPORT 831 else if(dev->blkdev->type == BOOTDEV_UFS) 832 { 833 if(!cmd_oem_get_ufs_info()) 834 dprintf(CRITICAL, "fail to get ufs info\n"); 835 } 836 #endif 837 } 838 if (dev->blkdev->type == BOOTDEV_SDMMC) 839 { 840 int ret = 0; 841 unsigned long vendor_argu = 0; 842 unsigned char *fw_buff_addr = NULL; 843 struct mmc_card *mmc_card; 844 mmc_card=mmc_get_card(0); 845 if (mmc_card->cid.manfid == MICRON_VENDOR_MANFID) 846 { 847 cmdline_append("emmc_max_chunck_size=262144");//256kB 848 } 849 else 850 cmdline_append("emmc_max_chunck_size=4194304");//4MB 851 if (g_boot_arg->boot_mode == NORMAL_BOOT) 852 { 853 fw_buff_addr = malloc(512*1024);//szie for max FW length 854 if (fw_buff_addr) 855 { 856 if (mmc_card->cid.manfid == HYNIX_VENDOR_MANFID)//hynix specific 2D & 3D nand emcp 857 { 858 vendor_argu = HYNIX_FFU_ARG; 859 } 860 else if (mmc_card->cid.manfid == SUMSUNG_VENDOR_MANFID) 861 { 862 vendor_argu = SUMSUNG_FFU_ARG; 863 } 864 else if (mmc_card->cid.manfid == MICRON_VENDOR_MANFID)//micron specific emcp 865 { 866 vendor_argu = MICRON_FFU_ARG; // currentlly micron emcp is not in use 867 } 868 else if (mmc_card->cid.manfid == YMTC_VENDOR_MANFID)//micron specific emcp 869 { 870 dprintf(CRITICAL, "Emmc prod_name:%s\n", mmc_card->cid.prod_name); 871 if (!strcmp(mmc_card->cid.prod_name, "Y0S064") || !strcmp(mmc_card->cid.prod_name, "Y0S128") || !strcmp(mmc_card->cid.prod_name, "Y0S256") 872 || !strcmp(mmc_card->cid.prod_name, "Y1Y128") || !strcmp(mmc_card->cid.prod_name, "Y1Y256")) { 873 vendor_argu = YMTC_FFU_ARG_NEW; 874 } else { 875 vendor_argu = YMTC_FFU_ARG; 876 } 877 } 878 else if ((mmc_card->cid.manfid == FORESEE_VENDOR_MANFID) && (mmc_card->cid.bin == FORESEE_VENDOR_BIN)) 879 { 880 vendor_argu = FORESEE_FFU_ARG; 881 } 882 else if (mmc_card->cid.manfid == HG_VENDOR_MANFID) 883 { 884 vendor_argu = HG_FFU_ARG; 885 } 886 else if (mmc_card->cid.manfid == BIWIN_VENDOR_MANFID) 887 { 888 vendor_argu = BIWIN_FFU_ARG; 889 } 890 else 891 { 892 dprintf(CRITICAL, "Unknown manfid emcp.\n"); 893 } 894 dprintf(CRITICAL, "Emmc check upgrade start vendor_argu=0x%08x\n",vendor_argu); 895 if ((need_upgrade_emmc_fimware(0, fw_buff_addr) || need_upgrade_emmc_fimware(1024*1024, fw_buff_addr))) 896 { 897 dprintf(CRITICAL, "Start emmc firmware upgrade flow\n"); 898 ret = emmc_firmware_upgrade_flow(vendor_argu, fw_buff_addr); 899 dprintf(CRITICAL, "%s::Reboot device\n",__func__); 900 if(mtk_rgu_mode_check(MTK_WDT_NONRST2_BOOT_SILENCE)){ 901 mtk_rgu_mode_set(1,MTK_WDT_NONRST2_BOOT_SILENCE); 902 } 903 if(mtk_rgu_mode_check(MTK_WDT_NONRST2_BOOT_SAU)){ 904 mtk_rgu_mode_set(1,MTK_WDT_NONRST2_BOOT_SAU); 905 } 906 mmc_legacy_init(1); 907 mtk_arch_reset(1); 908 } 909 dprintf(CRITICAL, "Emmc check upgrade end\n"); 910 free(fw_buff_addr); 911 } 912 else 913 dprintf(CRITICAL, "malloc fail for emmc fw upgrade.\n"); 914 } 915 } 916 #ifdef MTK_UFS_SUPPORT 917 else if(dev->blkdev->type == BOOTDEV_UFS) 918 { 919 if (g_boot_arg->boot_mode == NORMAL_BOOT) 920 { 921 uint8_t *fw_buff_align; 922 unsigned char *fw_buff = malloc(FIRMWARE_LENGTH_MAX +BUF_ALIGN_8); 923 if(fw_buff) 924 { 925 fw_buff_align = UFS_PALIGN(fw_buff, BUF_ALIGN_8); 926 if (need_upgrade_ufs_firmware(fw_buff_align)) 927 { 928 dprintf(CRITICAL, "Start emmc firmware upgrade flow\n"); 929 if (ufs_firmware_update(fw_buff_align) == 0) 930 dprintf(CRITICAL, "ufs FW upgrade success.\n"); 931 dprintf(CRITICAL, "%s::Reboot device\n",__func__); 932 ufs_lk_init(); 933 mtk_arch_full_reset(); 934 } 935 } 936 else 937 dprintf(CRITICAL, "malloc fail for ufs fw upgrade.\n"); 938 free(fw_buff); 939 } 940 } 941 #endif 942 943 PROFILING_START("disp init"); 944 /* initialize the frame buffet information */ 945 g_fb_size = mt_disp_get_vram_size(); 946 g_fb_base = mblock_reserve_ext(&g_boot_arg->mblock_info, g_fb_size, 0x10000, 0x80000000, 0, "framebuffer"); 947 if (!g_fb_base) { 948 dprintf(CRITICAL, "reserve framebuffer failed\n"); 949 } 950 951 dprintf(CRITICAL, "FB base = 0x%x, FB size = 0x%x (%d)\n", g_fb_base, g_fb_size, g_fb_size); 952 953 #ifndef MACH_FPGA 954 #ifdef MTK_SMI_SUPPORT 955 /* write SMI non on-the-fly register before DISP init */ 956 smi_apply_register_setting(); 957 #endif 958 #endif 959 960 mt_disp_init((void *)g_fb_base); 961 PROFILING_END(); 962 963 PROFILING_START("vedio init"); 964 drv_video_init(); 965 PROFILING_END(); 966 #endif /* MACH_FPGA_NO_DISPLAY */ 967 968 /*for kpd pmic mode setting*/ 969 set_kpd_pmic_mode(); 970 971 #ifndef MACH_FPGA 972 PROFILING_START("boot mode select"); 973 974 #if !defined(NO_BOOT_MODE_SEL) 975 boot_mode_select(); 976 #endif 977 978 PROFILING_START("wdt_check_exception"); 979 wdt_check_exception(); 980 PROFILING_END(); 981 982 #ifdef MTK_USB2JTAG_SUPPORT 983 if (g_boot_mode != FASTBOOT) { 984 extern void usb2jtag_init(void); 985 usb2jtag_init(); 986 } 987 #endif 988 989 #ifdef MTK_AEE_PLATFORM_DEBUG_SUPPORT 990 /* init lastbus: MUST call after kedump (in boot_mode_select) */ 991 latch_lastbus_init(); 992 #endif 993 994 PROFILING_END(); /* boot mode select */ 995 #endif /*MACH_FPGA */ 996 997 lk_vb_vfy_logo(); 998 999 #ifdef OPLUS_FEATURE_CHG_BASIC 1000 if(g_boot_mode == OPPO_SAU_BOOT || g_boot_mode == SILENCE_BOOT){ 1001 dprintf(CRITICAL,"silence or sau boot do nothing\r\n"); 1002 //silence and sau boot do nothing 1003 } else { 1004 if (boot_vbat >= VIB_BOOT_THRESHOLD_MV) { 1005 platform_vib_timed_enable(VIB_DURATION); 1006 } else { 1007 dprintf(CRITICAL, "boot vbatt is lower than 3200mV, do not vibration0.\n"); 1008 } 1009 } 1010 #endif /* OPLUS_FEATURE_CHG_BASIC */ 1011 1012 #ifndef MACH_FPGA_NO_DISPLAY 1013 /* fast meta mode */ 1014 if(g_boot_mode != META_BOOT){ 1015 PROFILING_START("load_logo"); 1016 logo_size = mboot_common_load_logo((unsigned long)mt_get_logo_db_addr_pa(), "logo"); 1017 assert(logo_size <= LK_LOGO_MAX_SIZE); 1018 PROFILING_END(); 1019 } else 1020 /* Indicate logo lib that logo partition is not loaded */ 1021 enable_logo(0); 1022 #endif // MACH_FPGA_NO_DISPLAY 1023 1024 /*Show download logo & message on screen */ 1025 if (g_boot_arg->boot_mode == DOWNLOAD_BOOT) { 1026 dprintf(CRITICAL, "[LK] boot mode is DOWNLOAD_BOOT\n"); 1027 1028 #ifndef MACH_FPGA_NO_DISPLAY 1029 PROFILING_START("show logo"); 1030 mt_disp_show_boot_logo(); 1031 PROFILING_END(); 1032 #endif 1033 video_printf(" => Downloading...\n"); 1034 dprintf(CRITICAL, "enable backlight after show bootlogo! \n"); 1035 #ifndef MACH_FPGA 1036 PROFILING_START("backlight"); 1037 mt65xx_backlight_on(); 1038 PROFILING_END(); 1039 #endif 1040 #ifndef MACH_FPGA_NO_DISPLAY 1041 /* pwm need display sof */ 1042 PROFILING_START("disp update"); 1043 mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); 1044 PROFILING_END(); 1045 #endif 1046 logo_lk_t = ((unsigned int)get_timer(boot_time)); 1047 PROFILING_START("disable wdt, l2, cache, mmu"); 1048 mtk_wdt_disable(); //Disable wdt before jump to DA 1049 platform_uninit(); 1050 #ifdef HAVE_CACHE_PL310 1051 l2_disable(); 1052 #endif 1053 arch_disable_cache(UCACHE); 1054 arch_disable_mmu(); 1055 #ifdef ENABLE_L2_SHARING 1056 config_shared_SRAM_size(); 1057 #endif 1058 PROFILING_END(); 1059 jump_da(g_boot_arg->da_info.addr, g_boot_arg->da_info.arg1, g_boot_arg->da_info.arg2); 1060 } 1061 #ifdef MTK_KERNEL_POWER_OFF_CHARGING 1062 else if (g_boot_mode != META_BOOT && 1063 g_boot_mode != ALARM_BOOT && 1064 g_boot_mode != FASTBOOT && 1065 g_boot_mode != KERNEL_POWER_OFF_CHARGING_BOOT && 1066 g_boot_mode != LOW_POWER_OFF_CHARGING_BOOT && 1067 mtk_bat_allow_backlight_enable()) { 1068 #ifndef MACH_FPGA_NO_DISPLAY 1069 #ifdef OPLUS_FEATURE_CHG_BASIC 1070 boot_vbat = get_bat_volt(5); 1071 //if(boot_vbat > BATTERY_LOWVOL_THRESOLD) { 1072 PROFILING_START("show logo"); 1073 mt_disp_show_boot_logo(); 1074 PROFILING_END(); 1075 //} 1076 #endif /* OPLUS_FEATURE_CHG_BASIC */ 1077 #endif // MACH_FPGA_NO_DISPLAY 1078 #ifndef MACH_FPGA 1079 PROFILING_START("backlight"); 1080 mt65xx_backlight_on(); 1081 PROFILING_END(); /* backlight */ 1082 #endif 1083 #ifndef MACH_FPGA_NO_DISPLAY 1084 /* pwm need display sof */ 1085 PROFILING_START("disp update"); 1086 mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); 1087 PROFILING_END(); 1088 #endif 1089 backlight_on = true; 1090 dprintf(INFO, "backlight enabled before battery init\n"); 1091 logo_lk_t = ((unsigned int)get_timer(boot_time)); 1092 } 1093 #endif // MTK_KERNEL_POWER_OFF_CHARGING 1094 1095 PROFILING_START("battery init"); 1096 #ifndef MACH_FPGA 1097 #if !defined(NO_PLL_TURN_OFF) 1098 mt_pll_turn_off(); 1099 #endif // !defined(NO_PLL_TURN_OFF) 1100 #if !defined(NO_DCM) 1101 if (mt_dcm_init()) 1102 dprintf(CRITICAL, "mt_dcm_init fail\n"); 1103 #endif // !defined(NO_DCM) 1104 1105 #if !defined(NO_BAT_INIT) 1106 #ifdef MTK_CHARGER_NEW_ARCH 1107 PROFILING_START("charger init"); 1108 mtk_charger_init(); 1109 PROFILING_END(); /* charger init */ 1110 1111 PROFILING_START("DLPT init"); 1112 pmic_dlpt_init(); 1113 PROFILING_END(); /* dlpt init */ 1114 1115 PROFILING_START("check sw_ocv"); 1116 check_sw_ocv(); 1117 PROFILING_END(); /* battery check sw_ocv */ 1118 1119 PROFILING_START("charger start"); 1120 mtk_charger_start(); 1121 PROFILING_END(); /* charger start */ 1122 1123 PROFILING_START(" DLPT get imix"); 1124 get_dlpt_imix_r(); 1125 PROFILING_END(); /* DLPT get imix */ 1126 1127 #else 1128 mt65xx_bat_init(); 1129 #endif // MTK_CHARGER_NEW_ARCH 1130 #endif // !defined(NO_BAT_INIT) 1131 #endif // MACH_FPGA 1132 PROFILING_END(); /* battery init */ 1133 1134 #ifndef CFG_POWER_CHARGING 1135 PROFILING_START("RTC boot check Init"); 1136 /* NOTE: if define CFG_POWER_CHARGING, will rtc_boot_check() in mt65xx_bat_init() */ 1137 rtc_boot_check(false); 1138 PROFILING_END(); 1139 #endif // CFG_POWER_CHARGING 1140 1141 #ifdef MTK_KERNEL_POWER_OFF_CHARGING 1142 if (kernel_charging_boot() == 1) { 1143 PROFILING_START("show logo"); 1144 #ifdef MTK_BATLOWV_NO_PANEL_ON_EARLY 1145 CHARGER_TYPE CHR_Type_num = CHARGER_UNKNOWN; 1146 CHR_Type_num = hw_charging_get_charger_type(); 1147 if ((g_boot_mode != LOW_POWER_OFF_CHARGING_BOOT) || 1148 ((CHR_Type_num != STANDARD_HOST) && (CHR_Type_num != NONSTANDARD_CHARGER))) { 1149 #endif // MTK_BATLOWV_NO_PANEL_ON_EARLY 1150 mt_disp_power(TRUE); 1151 #ifndef OPLUS_FEATURE_CHG_BASIC 1152 #ifndef MACH_FPGA_NO_DISPLAY 1153 mt_disp_show_low_battery(); 1154 #endif 1155 mt65xx_leds_brightness_set(6, 110); 1156 #endif /*OPLUS_FEATURE_CHG_BASIC*/ 1157 1158 #ifndef MACH_FPGA_NO_DISPLAY 1159 /* pwm need display sof */ 1160 PROFILING_START("display update"); 1161 mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); 1162 PROFILING_END(); 1163 #endif 1164 backlight_on = true; 1165 #ifdef MTK_BATLOWV_NO_PANEL_ON_EARLY 1166 } 1167 #endif 1168 PROFILING_END(); 1169 } 1170 #endif // MTK_KERNEL_POWER_OFF_CHARGING 1171 1172 #ifdef MTK_BATLOWV_NO_PANEL_ON_EARLY 1173 if (!is_low_battery(0)) { 1174 #endif 1175 /* 1176 * Update LCM with framebuffer before 1177 * turning on backlight to avoid LCM noise if there is 1178 * no any logo showed on screen before. 1179 */ 1180 if (!backlight_on) { 1181 logo_lk_t = ((unsigned int)get_timer(boot_time)); 1182 #ifndef MACH_FPGA_NO_DISPLAY 1183 PROFILING_START("display update"); 1184 mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); 1185 PROFILING_END(); 1186 #endif 1187 #ifndef MACH_FPGA 1188 PROFILING_START("backlight"); 1189 mt65xx_backlight_on(); 1190 PROFILING_END(); /* backlight */ 1191 #endif 1192 } 1193 #ifdef MTK_BATLOWV_NO_PANEL_ON_EARLY 1194 } 1195 #endif 1196 //#ifdef OPLUS_FEATURE_SECURITY_COMMON 1197 //#Shupeng.Zhou@BSP.Secure.Basic, 2020/11/18, add for FBE key aquire permission 1198 mtk_set_boot_info_to_rpmb(); 1199 //#endif /* OPLUS_FEATURE_SECURITY_COMMON */ 1200 #ifndef MACH_FPGA 1201 PROFILING_START("sw_env"); 1202 sw_env(); 1203 PROFILING_END(); 1204 #endif 1205 PROFILING_END(); /* platform_init */ 1206 } 1207 1208 void platform_uninit(void) 1209 { 1210 #ifndef MACH_FPGA 1211 leds_deinit(); 1212 platform_clear_all_on_mux(); 1213 #endif 1214 platform_deinit_interrupts(); 1215 return; 1216 } 1217 1218 #ifdef ENABLE_L2_SHARING 1219 #define ADDR_CA7L_CACHE_CONFIG_MP(x) (CA7MCUCFG_BASE + 0x200 * x) 1220 #define L2C_SIZE_CFG_OFFSET 8 1221 #define L2C_SHARE_EN_OFFSET 12 1222 /* 4'b1111: 2048KB(not support) 1223 * 4'b0111: 1024KB(not support) 1224 * 4'b0011: 512KB 1225 * 4'b0001: 256KB 1226 * 4'b0000: 128KB (not support) 1227 */ 1228 1229 int is_l2_need_config(void) 1230 { 1231 volatile unsigned int cache_cfg, addr; 1232 1233 addr = ADDR_CA7L_CACHE_CONFIG_MP(0); 1234 cache_cfg = DRV_Reg32(addr); 1235 cache_cfg = cache_cfg >> L2C_SIZE_CFG_OFFSET; 1236 1237 /* only read 256KB need to be config.*/ 1238 if ((cache_cfg &(0x7)) == 0x1) { 1239 return 1; 1240 } 1241 return 0; 1242 } 1243 1244 void cluster_l2_share_enable(int cluster) 1245 { 1246 volatile unsigned int cache_cfg, addr; 1247 1248 addr = ADDR_CA7L_CACHE_CONFIG_MP(cluster); 1249 /* set L2C size to 256KB */ 1250 cache_cfg = DRV_Reg32(addr); 1251 cache_cfg &= (~0x7) << L2C_SIZE_CFG_OFFSET; 1252 cache_cfg |= 0x1 << L2C_SIZE_CFG_OFFSET; 1253 1254 /* enable L2C_share_en. Sram only for other to use*/ 1255 cache_cfg |= (0x1 << L2C_SHARE_EN_OFFSET); 1256 DRV_WriteReg32(addr, cache_cfg); 1257 } 1258 1259 void cluster_l2_share_disable(int cluster) 1260 { 1261 volatile unsigned int cache_cfg, addr; 1262 1263 addr = ADDR_CA7L_CACHE_CONFIG_MP(cluster); 1264 /* set L2C size to 512KB */ 1265 cache_cfg = DRV_Reg32(addr); 1266 cache_cfg &= (~0x7) << L2C_SIZE_CFG_OFFSET; 1267 cache_cfg |= 0x3 << L2C_SIZE_CFG_OFFSET; 1268 DRV_WriteReg32(addr, cache_cfg); 1269 1270 /* disable L2C_share_en. Sram only for cpu to use*/ 1271 cache_cfg &= ~(0x1 << L2C_SHARE_EN_OFFSET); 1272 DRV_WriteReg32(addr, cache_cfg); 1273 } 1274 1275 /* config L2 cache and sram to its size */ 1276 void config_L2_size(void) 1277 { 1278 int cluster; 1279 1280 if (is_l2_need_config()) { 1281 /* 1282 * Becuase mcu config is protected. 1283 * only can write in secutity mode 1284 */ 1285 1286 if (dev_info_nr_cpu() == 6) { 1287 cluster_l2_share_disable(0); 1288 cluster_l2_share_enable(1); 1289 } 1290 1291 else { 1292 for (cluster = 0; cluster < 2; cluster++) { 1293 cluster_l2_share_disable(cluster); 1294 } 1295 } 1296 } 1297 } 1298 1299 /* config SRAM back from L2 cache for DA relocation */ 1300 void config_shared_SRAM_size(void) 1301 { 1302 int cluster; 1303 1304 if (is_l2_need_config()) { 1305 /* 1306 * Becuase mcu config is protected. 1307 * only can write in secutity mode 1308 */ 1309 1310 for (cluster = 0; cluster < 2; cluster++) { 1311 cluster_l2_share_enable(cluster); 1312 } 1313 } 1314 } 1315 #endif 1316 1317 1318 void platform_sec_post_init(void) 1319 { 1320 unsigned int ret = 0; 1321 ret = crypto_hw_engine_disable(); 1322 if (ret) { 1323 dprintf(CRITICAL, "[SEC] crypto engine HW disable fail\n"); 1324 } 1325 /* Lock Device APC in LK */ 1326 dprintf(CRITICAL, "[DEVAPC] sec_post_init\n"); 1327 1328 #if DEVAPC_TURN_ON 1329 dprintf(CRITICAL, "[DEVAPC] platform_sec_post_init - SMC call to ATF from LK\n"); 1330 #ifdef MTK_SMC_ID_MGMT 1331 mt_secure_call(MTK_SIP_LK_DAPC_INIT, 0, 0, 0, 0); 1332 #else 1333 mt_secure_call(0x82000101, 0, 0, 0); 1334 #endif 1335 #endif 1336 1337 } 1338 1339 u32 get_devinfo_with_index(u32 index) 1340 { 1341 return internal_get_devinfo_with_index(index); 1342 } 1343 1344 int platform_skip_hibernation(void) 1345 { 1346 switch (g_boot_arg->boot_reason) { 1347 #if 0 // let schedule power on to go hiberantion bootup process 1348 case BR_RTC: 1349 #endif 1350 case BR_WDT: 1351 case BR_WDT_BY_PASS_PWK: 1352 case BR_WDT_SW: 1353 case BR_WDT_HW: 1354 return 1; 1355 } 1356 1357 return 0; 1358 } 1359 1360 int is_meta_log_disable(void) 1361 { 1362 return g_boot_arg->meta_log_disable; 1363 } 1364 1365 served by {OpenGrok Last Index Update: Thu Aug 07 23:03:58 CST 2025这里面有哪个文件会修改boot_mode
最新发布
11-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值