diff options
Diffstat (limited to 'libcpu/aarch64/common/cpu.c')
| -rw-r--r-- | libcpu/aarch64/common/cpu.c | 211 |
1 files changed, 14 insertions, 197 deletions
diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 5dbb45af71..15b17629a3 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -7,37 +7,33 @@ * Date Author Notes * 2011-09-15 Bernard first version * 2019-07-28 zdzn add smp support + * 2023-02-21 GuEe-GUI mov cpu ofw init to setup */ #include <rthw.h> #include <rtthread.h> -#include <board.h> -#include "cp15.h" +#include <rtdevice.h> +#include <cpu.h> #define DBG_TAG "libcpu.aarch64.cpu" #define DBG_LVL DBG_INFO #include <rtdbg.h> -#include <string.h> -#include "cpu.h" -#include "psci_api.h" -void (*system_off)(void); #ifdef RT_USING_SMP -#ifdef RT_USING_FDT -#include "dtb_node.h" -struct dtb_node *_cpu_node[RT_CPUS_NR]; -#endif /* RT_USING_FDT */ - -#define MPIDR_AFF_MASK 0x000000FF00FFFFFFul #define REPORT_ERR(retval) LOG_E("got error code %d in %s(), %s:%d", (retval), __func__, __FILE__, __LINE__) #define CHECK_RETVAL(retval) if (retval) {REPORT_ERR(retval);} +#define cpuid_to_hwid(cpuid) \ + ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? rt_cpu_mpidr_early[cpuid] : ID_ERROR) +#define set_hwid(cpuid, hwid) \ + ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? (rt_cpu_mpidr_early[cpuid] = (hwid)) : ID_ERROR) +#define get_cpu_node(cpuid) \ + ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? _cpu_node[cpuid] : NULL) +#define set_cpu_node(cpuid, node) \ + ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? (_cpu_node[cpuid] = node) : NULL) -/** - * cpu_ops_tbl contains cpu_ops_t for each cpu kernel observed, - * given cpu logical id 'i', its cpu_ops_t is 'cpu_ops_tbl[i]' - */ +typedef rt_hw_spinlock_t arch_spinlock_t; struct cpu_ops_t *cpu_ops_tbl[RT_CPUS_NR]; #ifdef RT_USING_SMART @@ -59,8 +55,6 @@ rt_weak rt_uint64_t rt_cpu_mpidr_early[] = }; #endif /* RT_USING_SMART */ -typedef rt_hw_spinlock_t arch_spinlock_t; - static inline void arch_spin_lock(arch_spinlock_t *lock) { unsigned int tmp; @@ -138,115 +132,6 @@ static int _cpus_init_data_hardcoded(int num_cpus, rt_uint64_t *cpu_hw_ids, stru return 0; } -#ifdef RT_USING_FDT - -/** read ('size' * 4) bytes number from start, big-endian format */ -static rt_uint64_t _read_be_number(void *start, int size) -{ - rt_uint64_t buf = 0; - for (; size > 0; size--) - { - buf = (buf << 32) | fdt32_to_cpu(*(uint32_t *)start); - start = (uint32_t *)start + 1; - } - return buf; -} - -/** check device-type of the node, */ -static bool _node_is_cpu(struct dtb_node *node) -{ - char *device_type = dtb_node_get_dtb_node_property_value(node, "device_type", NULL); - if (device_type) - { - return !strcmp(device_type, "cpu"); - } - return false; -} - -static int _read_and_set_hwid(struct dtb_node *cpu, int *id_pool, int *pcpuid) -{ - // size/address_cells is number of elements in reg array - int size; - static int address_cells, size_cells; - if (!address_cells && !size_cells) - dtb_node_get_dtb_node_cells(cpu, &address_cells, &size_cells); - - void *id_start = dtb_node_get_dtb_node_property_value(cpu, "reg", &size); - rt_uint64_t mpid = _read_be_number(id_start, address_cells); - - *pcpuid = *id_pool; - *id_pool = *id_pool + 1; - set_hwid(*pcpuid, mpid); - - LOG_I("Using MPID 0x%lx as cpu %d", mpid, *pcpuid); - - // setting _cpu_node for cpu_init use - _cpu_node[*pcpuid] = cpu; - - return 0; -} - -static int _read_and_set_cpuops(struct dtb_node *cpu, int cpuid) -{ - char *method = dtb_node_get_dtb_node_property_value(cpu, "enable-method", NULL); - if (!method) - { - LOG_E("Cannot read method from cpu node"); - return -1; - } - - struct cpu_ops_t *cpu_ops; - if (!strcmp(method, cpu_ops_psci.method)) - { - cpu_ops = &cpu_ops_psci; - } - else if (!strcmp(method, cpu_ops_spin_tbl.method)) - { - cpu_ops = &cpu_ops_spin_tbl; - } - else - { - cpu_ops = RT_NULL; - LOG_E("Not supported cpu_ops: %s", method); - } - cpu_ops_tbl[cpuid] = cpu_ops; - - LOG_D("Using boot method [%s] for cpu %d", cpu_ops->method, cpuid); - return 0; -} - -static int _cpus_init_data_fdt() -{ - // cpuid_to_hwid and cpu_ops_tbl with fdt - void *root = get_dtb_node_head(); - int id_pool = 0; - int cpuid; - struct dtb_node *cpus = dtb_node_get_dtb_node_by_path(root, "/cpus"); - - // for each cpu node (device-type is cpu), read its mpid and set its cpuid_to_hwid - for_each_node_child(cpus) - { - if (!_node_is_cpu(cpus)) - { - continue; - } - - if (id_pool > RT_CPUS_NR) - { - LOG_W("Reading more cpus from FDT than RT_CPUS_NR" - "\n Parsing will not continue and only %d cpus will be used.", RT_CPUS_NR); - break; - } - - _read_and_set_hwid(cpus, &id_pool, &cpuid); - - _read_and_set_cpuops(cpus, cpuid); - } - return 0; -} - -#endif /* RT_USING_FDT */ - /** init cpu with hardcoded infomation or parsing from FDT */ static int _cpus_init(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]) { @@ -258,9 +143,6 @@ static int _cpus_init(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *c else { retval = -1; -#ifdef RT_USING_FDT - retval = _cpus_init_data_fdt(); -#endif } if (retval) @@ -278,7 +160,7 @@ static int _cpus_init(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *c if (cpu_ops_tbl[i] && cpu_ops_tbl[i]->cpu_init) { - retval = cpu_ops_tbl[i]->cpu_init(i); + retval = cpu_ops_tbl[i]->cpu_init(i, RT_NULL); CHECK_RETVAL(retval); } else @@ -290,30 +172,6 @@ static int _cpus_init(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *c return 0; } -static void _boot_secondary(void) -{ - for (int i = 1; i < RT_CPUS_NR; i++) - { - int retval = -0xbad0; // mark no support operation - if (cpu_ops_tbl[i] && cpu_ops_tbl[i]->cpu_boot) - retval = cpu_ops_tbl[i]->cpu_boot(i); - if (retval) - { - if (retval == -0xbad0) - LOG_E("No cpu_ops was probed for CPU %d. Try to configure it or use fdt", i); - else - LOG_E("Failed to boot secondary CPU %d, error code %d", i, retval); - } else { - LOG_I("Secondary CPU %d booted", i); - } - } -} - -rt_weak void rt_hw_secondary_cpu_up(void) -{ - _boot_secondary(); -} - /** * @brief boot cpu with hardcoded data * @@ -334,29 +192,6 @@ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_o return retval; } -#define CPU_INIT_USING_FDT 0,0,0 - -/** - * @brief Initialize cpu infomation from fdt - * - * @return int - */ -int rt_hw_cpu_init() -{ -#ifdef RT_USING_FDT - return _cpus_init(CPU_INIT_USING_FDT); -#else - LOG_E("CPU init failed since RT_USING_FDT was not defined"); - return -0xa; /* no fdt support */ -#endif /* RT_USING_FDT */ -} - -rt_weak void rt_hw_secondary_cpu_idle_exec(void) -{ - asm volatile("wfe" :: - : "memory", "cc"); -} - #endif /*RT_USING_SMP*/ /** @@ -369,24 +204,6 @@ const char *rt_hw_cpu_arch(void) return "aarch64"; } -/** shutdown CPU */ -void rt_hw_cpu_shutdown(void) -{ - rt_uint32_t level; - rt_kprintf("shutdown...\n"); - - if (system_off) - system_off(); - LOG_E("system shutdown failed"); - - level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } -} -MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_shutdown, shutdown, shutdown machine); - #ifdef RT_USING_CPU_FFS /** * This function finds the first bit set (beginning with the least significant bit) |
