[libcpu][aarch64] Update for DM

1. PSCI port to system power.
2. Support builtin fdt.
3. Update system aspace size.
4. Support DMA memory probe.
5. Fixup not backtrace in Serror for device bus fault.

Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
GuEe-GUI
2025-12-17 15:11:39 +08:00
committed by R b b666
parent d09135f76b
commit 77fbed5744
4 changed files with 133 additions and 21 deletions

View File

@@ -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 <rtconfig.h>
.data
.align 8
.globl rt_hw_builtin_fdt
rt_hw_builtin_fdt:
#ifdef RT_BUILTIN_FDT_PATH
.incbin RT_BUILTIN_FDT_PATH
#endif

View File

@@ -22,6 +22,7 @@
#include <drivers/ofw.h>
#include <drivers/platform.h>
#include <drivers/core/dm.h>
#include <drivers/core/power.h>
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;
rt_ubase_t mpid = rt_cpu_mpidr_table[cpuid] & MPIDR_MASK;
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);
}
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
{

View File

@@ -26,19 +26,16 @@
#include <gic.h>
#include <gicv3.h>
#include <mm_memblock.h>
#define SIZE_KB 1024
#define SIZE_MB (1024 * SIZE_KB)
#define SIZE_GB (1024 * SIZE_MB)
#include <dt-bindings/size.h>
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);

View File

@@ -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();
}