diff --git a/libcpu/aarch64/common/builtin_fdt_gcc.S b/libcpu/aarch64/common/builtin_fdt_gcc.S new file mode 100755 index 00000000000..289124ee6db --- /dev/null +++ b/libcpu/aarch64/common/builtin_fdt_gcc.S @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-08-24 GuEe-GUI first version + */ + +#include + + .data + + .align 8 + .globl rt_hw_builtin_fdt +rt_hw_builtin_fdt: +#ifdef RT_BUILTIN_FDT_PATH + .incbin RT_BUILTIN_FDT_PATH +#endif diff --git a/libcpu/aarch64/common/psci.c b/libcpu/aarch64/common/psci.c index 1f3d2e0595a..6a16016013c 100644 --- a/libcpu/aarch64/common/psci.c +++ b/libcpu/aarch64/common/psci.c @@ -22,6 +22,7 @@ #include #include #include +#include struct psci_ops { @@ -98,16 +99,9 @@ static rt_uint32_t psci_get_features(rt_uint32_t psci_func_id) /* PSCI CPU_ON */ static rt_uint32_t psci_cpu_on(rt_uint32_t func_id, int cpuid, rt_ubase_t entry_point) { - rt_uint32_t ret = -PSCI_RET_INVALID_PARAMETERS; - - if (cpuid < RT_CPUS_NR) - { - rt_ubase_t mpid = rt_cpu_mpidr_table[cpuid] & MPIDR_MASK; - - ret = (rt_uint32_t)psci_call(func_id, mpid, entry_point, 0); - } + rt_ubase_t mpid = rt_cpu_mpidr_table[cpuid] & MPIDR_MASK; - return ret; + return (rt_uint32_t)psci_call(func_id, mpid, entry_point, 0); } static rt_uint32_t psci_0_1_cpu_on(int cpuid, rt_ubase_t entry_point) @@ -211,7 +205,6 @@ void psci_system_reboot(void) { psci_call(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0); } - } #define PSCI_CALL_FN_RET(fn, ...) \ @@ -316,6 +309,16 @@ static rt_err_t psci_0_2_init(struct rt_ofw_node *np) _psci_ops.migrate = psci_0_2_migrate; _psci_ops.get_affinity_info = psci_affinity_info; _psci_ops.migrate_info_type = psci_migrate_info_type; + + if (!rt_dm_machine_shutdown) + { + rt_dm_machine_shutdown = psci_system_off; + } + + if (!rt_dm_machine_reset) + { + rt_dm_machine_reset = psci_system_reboot; + } } else { diff --git a/libcpu/aarch64/common/setup.c b/libcpu/aarch64/common/setup.c index d64dfc98119..21091791342 100644 --- a/libcpu/aarch64/common/setup.c +++ b/libcpu/aarch64/common/setup.c @@ -26,19 +26,16 @@ #include #include #include - -#define SIZE_KB 1024 -#define SIZE_MB (1024 * SIZE_KB) -#define SIZE_GB (1024 * SIZE_MB) +#include extern rt_ubase_t _start, _end; extern void _secondary_cpu_entry(void); +extern void rt_hw_builtin_fdt(); extern size_t MMUTable[]; extern void *system_vectors; static void *fdt_ptr = RT_NULL; static rt_size_t fdt_size = 0; -static rt_uint64_t initrd_ranges[3] = { }; #ifdef RT_USING_SMP extern struct cpu_ops_t cpu_psci_ops; @@ -64,11 +61,15 @@ static struct rt_ofw_node *cpu_np[RT_CPUS_NR] = { }; void rt_hw_fdt_install_early(void *fdt) { +#ifndef RT_USING_BUILTIN_FDT if (fdt != RT_NULL && !fdt_check_header(fdt)) { fdt_ptr = fdt; fdt_size = fdt_totalsize(fdt); } +#else + (void)fdt; +#endif } #ifdef RT_USING_HWTIMER @@ -169,8 +170,6 @@ rt_inline void cpu_info_init(void) cpu_np[i] = np; rt_cpu_mpidr_table[i] = hwid; - rt_ofw_data(np) = (void *)hwid; - for (int idx = 0; idx < RT_ARRAY_SIZE(cpu_ops); ++idx) { struct cpu_ops_t *ops = cpu_ops[idx]; @@ -199,8 +198,44 @@ rt_inline void cpu_info_init(void) #endif /* RT_USING_HWTIMER */ } +rt_inline rt_size_t string_to_size(const char *string, const char *who) +{ + char unit; + rt_size_t size; + const char *cp = string; + + size = atoi(cp); + + while (*cp >= '0' && *cp <= '9') + { + ++cp; + } + + unit = *cp & '_'; + + if (unit == 'M') + { + size *= SIZE_MB; + } + else if (unit == 'K') + { + size *= SIZE_KB; + } + else if (unit == 'G') + { + size *= SIZE_GB; + } + else + { + LOG_W("Unknown unit of '%c' in `%s`", unit, who); + } + + return size; +} + void rt_hw_common_setup(void) { + rt_uint64_t initrd_ranges[3]; rt_size_t kernel_start, kernel_end; rt_size_t heap_start, heap_end; rt_size_t init_page_start, init_page_end; @@ -213,9 +248,9 @@ void rt_hw_common_setup(void) system_vectors_init(); #ifdef RT_USING_SMART - rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xfffffffff0000000, 0x10000000, MMUTable, pv_off); + rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xffffffff00000000, 0x20000000, MMUTable, pv_off); #else - rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xffffd0000000, 0x10000000, MMUTable, 0); + rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xffffd0000000, 0x20000000, MMUTable, 0); #endif kernel_start = RT_ALIGN_DOWN((rt_size_t)rt_kmem_v2p((void *)&_start) - 64, ARCH_PAGE_SIZE); @@ -228,25 +263,36 @@ void rt_hw_common_setup(void) fdt_end = RT_ALIGN(fdt_start + fdt_size, ARCH_PAGE_SIZE); platform_mem_region.start = kernel_start; +#ifndef RT_USING_BUILTIN_FDT platform_mem_region.end = fdt_end; +#else + platform_mem_region.end = init_page_end; + (void)fdt_start; + (void)fdt_end; +#endif rt_memblock_reserve_memory("kernel", kernel_start, kernel_end, MEMBLOCK_NONE); rt_memblock_reserve_memory("memheap", heap_start, heap_end, MEMBLOCK_NONE); rt_memblock_reserve_memory("init-page", init_page_start, init_page_end, MEMBLOCK_NONE); +#ifndef RT_USING_BUILTIN_FDT rt_memblock_reserve_memory("fdt", fdt_start, fdt_end, MEMBLOCK_NONE); /* To virtual address */ fdt_ptr = (void *)(fdt_ptr - pv_off); #ifdef KERNEL_VADDR_START - if ((rt_ubase_t)fdt_ptr + fdt_size - KERNEL_VADDR_START > SIZE_GB) + if ((rt_ubase_t)fdt_ptr + fdt_size - KERNEL_VADDR_START > ARCH_EARLY_MAP_SIZE) { fdt_ptr = rt_ioremap_early(fdt_ptr + pv_off, fdt_size); RT_ASSERT(fdt_ptr != RT_NULL); } -#endif +#endif /* KERNEL_VADDR_START */ rt_memmove((void *)(fdt_start - pv_off), fdt_ptr, fdt_size); fdt_ptr = (void *)fdt_start - pv_off; +#else + fdt_ptr = &rt_hw_builtin_fdt; + fdt_size = fdt_totalsize(fdt_ptr); +#endif /* RT_USING_BUILTIN_FDT */ rt_system_heap_init((void *)(heap_start - pv_off), (void *)(heap_end - pv_off)); @@ -277,6 +323,46 @@ void rt_hw_common_setup(void) rt_fdt_scan_memory(); +#ifdef RT_USING_DMA + do { + const char *bootargs; + rt_ubase_t dma_pool_base; + rt_size_t cma_size = 0, coherent_pool_size = 0; + + if (!rt_fdt_bootargs_select("cma=", 0, &bootargs)) + { + cma_size = string_to_size(bootargs, "cma"); + } + + if (!rt_fdt_bootargs_select("coherent_pool=", 0, &bootargs)) + { + coherent_pool_size = string_to_size(bootargs, "coherent-pool"); + } + + if (cma_size <= coherent_pool_size) + { + if (cma_size || coherent_pool_size) + { + LOG_W("DMA pool %s=%u > %s=%u", + "CMA", cma_size, "coherent-pool", coherent_pool_size); + } + + cma_size = 8 * SIZE_MB; + coherent_pool_size = 2 * SIZE_MB; + } + + dma_pool_base = platform_mem_region.end; + rt_memblock_reserve_memory("dma-pool", + dma_pool_base, dma_pool_base + cma_size + coherent_pool_size, MEMBLOCK_NONE); + + if (rt_dma_pool_extract(cma_size, coherent_pool_size)) + { + LOG_E("Alloc DMA pool %s=%u, %s=%u fail", + "CMA", cma_size, "coherent-pool", coherent_pool_size); + } + } while (0); +#endif /* RT_USING_DMA */ + rt_memblock_setup_memory_environment(); rt_fdt_earlycon_kick(FDT_EARLYCON_KICK_UPDATE); diff --git a/libcpu/aarch64/common/trap.c b/libcpu/aarch64/common/trap.c index 6586091a937..424e29aacfe 100644 --- a/libcpu/aarch64/common/trap.c +++ b/libcpu/aarch64/common/trap.c @@ -394,5 +394,8 @@ void rt_hw_trap_serror(struct rt_hw_exp_stack *regs) #ifdef RT_USING_FINSH list_thread(); #endif + + struct rt_hw_backtrace_frame frame = {.fp = regs->x29, .pc = regs->pc}; + rt_backtrace_frame(rt_thread_self(), &frame); rt_hw_cpu_shutdown(); }