/* * Copyright (c) 2023-2024, ArtInChip Technology Co., Ltd * * SPDX-License-Identifier: Apache-2.0 * * Wu Dehuang */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef AICUPG_LOG_BUFFER_SUPPORT #include #endif extern size_t __heap_start; extern size_t __heap_end; extern int bl_upgmode_detect(enum boot_device bd); extern void aic_board_pinmux_init(void); extern void aic_board_sysclk_init(void); extern void stdio_set_uart(int id); extern int drv_dma_init(void); size_t config_ram_size = 0; #define MAX_HEAP_SIZE_IN_BOOT 0x800000 #ifdef AIC_BOOTLOADER_AXICFG_SUPPORT struct hal_axicfg_table axi_cfg_table[HAL_AXICFG_PORT_MAX] = { { .enable = AXICFG_CPU_EN, .priority = (u8)AIC_AXICFG_PORT_CPU_PRIO }, { .enable = AXICFG_AHB_EN, .priority = (u8)AIC_AXICFG_PORT_AHB_PRIO }, { .enable = AXICFG_DE_EN, .priority = (u8)AIC_AXICFG_PORT_DE_PRIO }, { .enable = AXICFG_GE_EN, .priority = (u8)AIC_AXICFG_PORT_GE_PRIO }, { .enable = AXICFG_VE_EN, .priority = (u8)AIC_AXICFG_PORT_VE_PRIO }, { .enable = AXICFG_DVP_EN, .priority = (u8)AIC_AXICFG_PORT_DVP_PRIO }, { .enable = AXICFG_CE_EN, .priority = (u8)AIC_AXICFG_PORT_CE_PRIO }, }; #endif static void aic_board_heap_init(enum boot_device bd) { size_t real_ram_size = 0; #if AIC_PSRAM_SIZE config_ram_size = AIC_PSRAM_SIZE; #elif AIC_DRAM_TOTAL_SIZE config_ram_size = AIC_DRAM_TOTAL_SIZE; #elif AIC_SRAM_TOTAL_SIZE config_ram_size = AIC_SRAM_TOTAL_SIZE; #elif AIC_SRAM_SIZE config_ram_size = AIC_SRAM_SIZE; #endif real_ram_size = aic_get_ram_size(); if (config_ram_size != real_ram_size) pr_warn("config ram size(0x%x) is not equal real ram size(0x%x)\n", (u32)config_ram_size, (u32)real_ram_size); heap_init(); } static int board_init(enum boot_device bd) { int cons_uart; /* target///board.c */ aic_board_sysclk_init(); aic_board_pinmux_init(); boot_time_trace("Clock and pinmux done"); #ifdef AIC_BOOTLOADER_AXICFG_SUPPORT for (int i = 0; i < HAL_AXICFG_PORT_MAX; i++) { if (axi_cfg_table[i].enable) { hal_axicfg_module_init(i, axi_cfg_table[i].priority); } } #endif cons_uart = AIC_BOOTLOADER_CONSOLE_UART; uart_init(cons_uart); stdio_set_uart(cons_uart); boot_time_trace("Console UART ready"); aic_board_heap_init(bd); boot_time_trace("Heap init done"); return 0; } void show_banner(void) { printf("\ntinySPL [Built on %s %s]\n", __DATE__, __TIME__); } int main(void) { enum boot_device bd; int ctrlc = -1, cont_boot; boot_time_trace("Enter main"); #ifdef AIC_SID_DRV hal_efuse_init(); #endif #ifdef AIC_SYSCFG_DRV hal_syscfg_probe(); #endif #ifdef AIC_DMA_DRV drv_dma_init(); #endif #ifdef AICUPG_LOG_BUFFER_SUPPORT log_buf_init(); #endif bd = aic_get_boot_device(); board_init(bd); show_banner(); boot_time_trace("Banner shown"); console_init(); console_set_usrname("aic"); ctrlc = console_get_ctrlc(); if (ctrlc < 0) { cont_boot = bl_upgmode_detect(bd); /* * Set bootcmd string to console, bootloader will check and run bootcmd * first in console_loop * * For the detail of boot command, please reference to cmd/ */ if (cont_boot) { switch (bd) { case BD_SDMC0: case BD_SDMC1: console_set_bootcmd("mmc_boot"); break; case BD_SPINOR: #ifdef AIC_BOOTLOADER_CMD_XIP_BOOT console_set_bootcmd("xip_boot"); #elif defined(AIC_BOOTLOADER_CMD_NOR_BOOT) console_set_bootcmd("nor_boot"); #endif break; case BD_SPINAND: console_set_bootcmd("nand_boot"); break; default: break; } } } /* * In the loop: * 1. Bootloader first will try to run the "bootcmd", to boot application * 2. If bootloader failure to boot application, it will stay in console * loop, user/developer can run built-in commands to do some jobs. */ console_loop(); while (1) { /* Should not run to here. */ }; return 0; }