From a24fa3c032ebf4ae9e513699a697dda0f130b16d Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Mon, 15 Aug 2022 17:07:49 +0800 Subject: [PATCH 01/17] =?UTF-8?q?[libcpu/aarch64]=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=9F=BA=E6=9C=ACpsci=E5=8D=8F=E8=AE=AE=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/psci.c | 252 +++++++++++++++++++++++++++++++ libcpu/aarch64/common/psci.h | 103 +++++++++++++ libcpu/aarch64/common/psci_api.h | 31 ++++ libcpu/aarch64/common/smccc.S | 25 +++ libcpu/aarch64/common/smccc.h | 45 ++++++ 5 files changed, 456 insertions(+) create mode 100644 libcpu/aarch64/common/psci.c create mode 100644 libcpu/aarch64/common/psci.h create mode 100644 libcpu/aarch64/common/psci_api.h create mode 100644 libcpu/aarch64/common/smccc.S create mode 100644 libcpu/aarch64/common/smccc.h diff --git a/libcpu/aarch64/common/psci.c b/libcpu/aarch64/common/psci.c new file mode 100644 index 0000000000..772596e249 --- /dev/null +++ b/libcpu/aarch64/common/psci.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#include +#include +#include +#include +#include +#include "psci.h" +#include "psci_api.h" +#include "smccc.h" + +#define DBG_TAG "libcpu.aarch64.psci" +#define DBG_LVL DBG_INFO +#include + +/** template for creating 4 PSCI ops: SUSPEND, OFF, ON, MIGRATE */ +#define COMMON_PSCI_OPS_TEMPLATE(VER, SUSPEND, OFF, ON, MIGRATE) \ + static int psci_##VER##_cpu_suspend(uint32_t state, unsigned long entry_point) \ + { \ + return psci_call((SUSPEND), state, entry_point, 0); \ + } \ + static int psci_##VER##_cpu_off(uint32_t state) \ + { \ + return psci_call((OFF), state, 0, 0); \ + } \ + static int psci_##VER##_cpu_on(unsigned long cpuid, unsigned long entry_point) \ + { \ + return psci_call((ON), cpuid, entry_point, 0); \ + } \ + static int psci_##VER##_migrate(unsigned long cpuid) \ + { \ + return psci_call((MIGRATE), cpuid, 0, 0); \ + } + +#ifdef RT_USING_FDT +#include "dtb_node.h" + +struct psci_operations psci_ops; + +#if __SIZE_WIDTH__ == 64 +#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN64_##name +#else +#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN_##name +#endif + +/** + * SMCCC can use either smc or hvc method + * smccc_call will be init to proper interface when psci_init() was executed + */ +static void (*smccc_call)(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + unsigned long a6, unsigned long a7, struct arm_smccc_res_t *res, + struct arm_smccc_quirk_t *quirk); + +static rt_uint32_t psci_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3) +{ + struct arm_smccc_res_t res; + smccc_call(a0, a1, a2, a3, 0, 0, 0, 0, &res, (void *)0); + return res.a0; +} + +static int _psci_probe_version(char *version, int *major, int *minor); +static int _psci_init_with_version(int major, int minor); + +static struct dtb_node *psci_node; + +/** + * init psci operations. + * using device tree to probe version and psci-method, + * setup psci ops for future use + */ +int psci_init() +{ + void *root = get_dtb_node_head(); + psci_node = dtb_node_get_dtb_node_by_path(root, "/psci"); + if (!psci_node) + { + return -1; + } + char *compatible = dtb_node_get_dtb_node_property_value(psci_node, "compatible", NULL); + char *method = dtb_node_get_dtb_node_property_value(psci_node, "method", NULL); + int ver_major, ver_minor; + int retval = 0; + + // setup psci-method + if (!strcmp("hvc", method)) + { + smccc_call = arm_smccc_hvc; + } + else if (!strcmp("smc", method)) + { + smccc_call = arm_smccc_smc; + } + else + { + LOG_E("Unknown PSCI method: %s", method); + return -1; + } + + retval = _psci_probe_version(compatible, &ver_major, &ver_minor); + if (retval != 0) + return retval; + + // init psci_ops with specified psci version + retval = _psci_init_with_version(ver_major, ver_minor); + + return retval; +} + +/* function id of PSCI v0.1 should be probed in FDT, they are implementation defined value */ +static rt_uint32_t cpu_suspend_0_1; +static rt_uint32_t cpu_off_0_1; +static rt_uint32_t cpu_on_0_1; +static rt_uint32_t migrate_0_1; + +#ifdef RT_USING_FDT +/* basic operations TEMPLATE for API since 0.1 version */ +COMMON_PSCI_OPS_TEMPLATE(0_1, cpu_suspend_0_1, cpu_off_0_1, cpu_on_0_1, migrate_0_1); + +/* used for v0.1 only, rely on FDT to probe function id */ +#define PROBE_AND_SET(FUNC_NAME) \ + do \ + { \ + int num_of_elem; \ + funcid = \ + dtb_node_get_dtb_node_property_value(psci_node, #FUNC_NAME, &num_of_elem); \ + if (num_of_elem != 4 || funcid == 0 || *funcid == 0) \ + { \ + LOG_E("Failed to probe " #FUNC_NAME " in FDT"); \ + } \ + else \ + { \ + FUNC_NAME##_0_1 = (rt_uint32_t)fdt32_to_cpu(*funcid); \ + psci_ops.FUNC_NAME = psci_0_1_##FUNC_NAME; \ + } \ + } while (0) + +static int psci_0_1_init() +{ +#ifdef RT_USING_FDT + // reading function id from fdt + rt_uint32_t *funcid; + PROBE_AND_SET(cpu_suspend); + PROBE_AND_SET(cpu_off); + PROBE_AND_SET(cpu_on); + PROBE_AND_SET(migrate); + return 0; +#else + return -1; +#endif +} + +#endif /* RT_USING_FDT */ + +COMMON_PSCI_OPS_TEMPLATE(0_2, PSCI_FN_NATIVE(0_2, CPU_SUSPEND), PSCI_0_2_FN_CPU_OFF, PSCI_FN_NATIVE(0_2, CPU_ON), PSCI_FN_NATIVE(0_2, MIGRATE)); + +static rt_uint32_t psci_0_2_get_version(void) +{ + return psci_call(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0); +} + +static void psci_0_2_set_basic_ops() +{ + psci_ops = (struct psci_operations){ + .get_version = psci_0_2_get_version, + + // followings API are v0.1 compatible + .cpu_suspend = psci_0_2_cpu_suspend, + .cpu_off = psci_0_2_cpu_off, + .cpu_on = psci_0_2_cpu_on, + .migrate = psci_0_2_migrate, + }; +} + +static int psci_0_2_init() +{ + psci_0_2_set_basic_ops(); + + // TODO init other version 0.2 features... + return 0; +} + +static int psci_1_0_init() +{ + psci_0_2_init(); + + // TODO init other version 1.0 features... + return 0; +} + +/* probe psci version from fdt or SMC call */ +static int _psci_probe_version(char *version, int *major, int *minor) +{ + int retval = 0; + // if strcmp compatible 'arm,psci-0.1' + if (!strcmp(version, "arm,psci")) + { + *major = 0; + *minor = 1; + } + else if (!strncmp(version, "arm,psci-", 8)) + { + // since psci-0.2, using psci call to probe version + rt_uint32_t ret = psci_0_2_get_version(); + *major = PSCI_VERSION_MAJOR(ret); + *minor = PSCI_VERSION_MINOR(ret); + } + else + { + LOG_E("[%s] was not a proper PSCI version", version); + retval = -1; + } + LOG_I("Using PSCI v%d.%d", *major, *minor); + return retval; +} + +/* init psci ops with version info */ +static int _psci_init_with_version(int major, int minor) +{ + int retval = -0xbeef; // mark unsupported + if (major == 0) + { + // for v0.1, psci function id was provided fdt + if (minor == 1) + { + retval = psci_0_1_init(); + } + else if (minor == 2) + { + retval = psci_0_2_init(); + } + } + else if (major == 1) + { + // psci_1_0_init is a base setup for version after v1.0 + retval = psci_1_0_init(); + } + + if (retval == -0xbeef) + { + LOG_E("PSCI init with incompatible version %d.%d", major, minor); + } + return retval; +} + +#endif /* RT_USING_FDT */ \ No newline at end of file diff --git a/libcpu/aarch64/common/psci.h b/libcpu/aarch64/common/psci.h new file mode 100644 index 0000000000..3cce66211f --- /dev/null +++ b/libcpu/aarch64/common/psci.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __PSCI_H__ +#define __PSCI_H__ + +/** + * PSCI protocol content + * For PSCI v0.1, only return values below are protocol defined + */ + +/* PSCI v0.2 interface */ +#define PSCI_0_2_FN_BASE 0x84000000 +#define PSCI_0_2_FN(n) (PSCI_0_2_FN_BASE + (n)) +#define PSCI_0_2_64BIT 0x40000000 +#define PSCI_0_2_FN64_BASE (PSCI_0_2_FN_BASE + PSCI_0_2_64BIT) +#define PSCI_0_2_FN64(n) (PSCI_0_2_FN64_BASE + (n)) + +#define PSCI_0_2_FN_PSCI_VERSION PSCI_0_2_FN(0) +#define PSCI_0_2_FN_CPU_SUSPEND PSCI_0_2_FN(1) +#define PSCI_0_2_FN_CPU_OFF PSCI_0_2_FN(2) +#define PSCI_0_2_FN_CPU_ON PSCI_0_2_FN(3) +#define PSCI_0_2_FN_AFFINITY_INFO PSCI_0_2_FN(4) +#define PSCI_0_2_FN_MIGRATE PSCI_0_2_FN(5) +#define PSCI_0_2_FN_MIGRATE_INFO_TYPE PSCI_0_2_FN(6) +#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU PSCI_0_2_FN(7) +#define PSCI_0_2_FN_SYSTEM_OFF PSCI_0_2_FN(8) +#define PSCI_0_2_FN_SYSTEM_RESET PSCI_0_2_FN(9) + +#define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1) +#define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3) +#define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4) +#define PSCI_0_2_FN64_MIGRATE (5) +#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) + +#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) +#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) +#define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) +#define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) + +#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) +#define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) + +/* PSCI v0.2 power state encoding for CPU_SUSPEND function */ +#define PSCI_0_2_POWER_STATE_ID_MASK 0xffff +#define PSCI_0_2_POWER_STATE_ID_SHIFT 0 +#define PSCI_0_2_POWER_STATE_TYPE_SHIFT 16 +#define PSCI_0_2_POWER_STATE_TYPE_MASK (0x1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT) +#define PSCI_0_2_POWER_STATE_AFFL_SHIFT 24 +#define PSCI_0_2_POWER_STATE_AFFL_MASK (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) + +/* PSCI extended power state encoding for CPU_SUSPEND function */ +#define PSCI_1_0_EXT_POWER_STATE_ID_MASK 0xfffffff +#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT 0 +#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT 30 +#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT) + +/* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ +#define PSCI_0_2_AFFINITY_LEVEL_ON 0 +#define PSCI_0_2_AFFINITY_LEVEL_OFF 1 +#define PSCI_0_2_AFFINITY_LEVEL_ON_PENDING 2 + +/* PSCI v0.2 multicore support in Trusted OS returned by MIGRATE_INFO_TYPE */ +#define PSCI_0_2_TOS_UP_MIGRATE 0 +#define PSCI_0_2_TOS_UP_NO_MIGRATE 1 +#define PSCI_0_2_TOS_MP 2 + +/* PSCI version decoding (independent of PSCI version) */ +#define PSCI_VERSION_MAJOR_SHIFT 16 +#define PSCI_VERSION_MINOR_MASK ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1) +#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK +#define PSCI_VERSION_MAJOR(ver) (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) +#define PSCI_VERSION_MINOR(ver) ((ver) & PSCI_VERSION_MINOR_MASK) +#define PSCI_VERSION(maj, min) \ + ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \ + ((min) & PSCI_VERSION_MINOR_MASK)) + +/* PSCI features decoding (>=1.0) */ +#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1 +#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT) + +#define PSCI_1_0_OS_INITIATED BIT(0) +#define PSCI_1_0_SUSPEND_MODE_PC 0 +#define PSCI_1_0_SUSPEND_MODE_OSI 1 + +/* PSCI return values (inclusive of all PSCI versions) */ +#define PSCI_RET_SUCCESS 0 +#define PSCI_RET_NOT_SUPPORTED -1 +#define PSCI_RET_INVALID_PARAMS -2 +#define PSCI_RET_DENIED -3 +#define PSCI_RET_ALREADY_ON -4 +#define PSCI_RET_ON_PENDING -5 +#define PSCI_RET_INTERNAL_FAILURE -6 +#define PSCI_RET_NOT_PRESENT -7 +#define PSCI_RET_DISABLED -8 +#define PSCI_RET_INVALID_ADDRESS -9 + +#endif /*__PSCI_H__*/ diff --git a/libcpu/aarch64/common/psci_api.h b/libcpu/aarch64/common/psci_api.h new file mode 100644 index 0000000000..78ff04a575 --- /dev/null +++ b/libcpu/aarch64/common/psci_api.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __PSCI_API_H__ +#define __PSCI_API_H__ + +#include +#include +#include +#include "psci_api.h" + +/** generic psci ops supported v0.1 v0.2 v1.0 v1.1 */ +struct psci_operations +{ + uint32_t (*get_version)(void); + int32_t (*cpu_suspend)(uint32_t state, unsigned long entry_point); + int32_t (*cpu_off)(uint32_t state); + int32_t (*cpu_on)(unsigned long cpuid, unsigned long entry_point); + int32_t (*migrate)(unsigned long cpuid); +}; + +extern struct psci_operations psci_ops; + +extern int psci_init(void); + +#endif // __PSCI_API_H__ diff --git a/libcpu/aarch64/common/smccc.S b/libcpu/aarch64/common/smccc.S new file mode 100644 index 0000000000..c6e0402fd1 --- /dev/null +++ b/libcpu/aarch64/common/smccc.S @@ -0,0 +1,25 @@ + +/** + * SMCCC v0.2 + * ARM DEN0028E chapter 2.6 + */ + .macro SMCCC instr + stp x29, x30, [sp, #-16]! + mov x29, sp + \instr #0 + // store in arm_smccc_res + ldr x4, [sp, #16] + stp x0, x1, [x4, #0] + stp x2, x3, [x4, #16] +1: + ldp x29, x30, [sp], #16 + ret + .endm + +.global arm_smccc_smc +arm_smccc_smc: + SMCCC smc + +.global arm_smccc_hvc +arm_smccc_hvc: + SMCCC hvc diff --git a/libcpu/aarch64/common/smccc.h b/libcpu/aarch64/common/smccc.h new file mode 100644 index 0000000000..3b2283ac50 --- /dev/null +++ b/libcpu/aarch64/common/smccc.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __SMCCC_H__ +#define __SMCCC_H__ + +/** + * result from SMC/HVC call + * ARM DEN0028E chapter 5, + */ +typedef struct arm_smccc_res_t +{ + unsigned long a0; + // reserved for ARM SMC and HVC Fast Call services + unsigned long a1; + unsigned long a2; + unsigned long a3; +} arm_smccc_res_t; + +/** + * quirk is a structure contains vendor specified information, + * it just a placeholder currently + */ +struct arm_smccc_quirk_t +{ +}; + +/* smccc version 0.2 */ + +void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + unsigned long a6, unsigned long a7, struct arm_smccc_res_t *res, + struct arm_smccc_quirk_t *quirk); + +void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + unsigned long a6, unsigned long a7, struct arm_smccc_res_t *res, + struct arm_smccc_quirk_t *quirk); + +#endif /* __SMCCC_H__ */ -- Gitee From 1796a0813c48accb95d53b6b1487747681d5e8a1 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Mon, 15 Aug 2022 18:21:30 +0800 Subject: [PATCH 02/17] =?UTF-8?q?[libcpu/aarch64]=20=E5=A2=9E=E5=8A=A0cpu?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E5=8F=8APSCI=E5=92=8CSpin-table=E7=9A=84CPU?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu.c | 249 +++++++++++++++++++++++++ libcpu/aarch64/common/cpu.h | 37 ++++ libcpu/aarch64/common/cpu_psci.c | 57 ++++++ libcpu/aarch64/common/cpu_spin_table.c | 60 ++++++ libcpu/aarch64/common/entry_point.h | 13 ++ libcpu/aarch64/common/psci.c | 15 +- 6 files changed, 426 insertions(+), 5 deletions(-) create mode 100644 libcpu/aarch64/common/cpu.h create mode 100644 libcpu/aarch64/common/cpu_psci.c create mode 100644 libcpu/aarch64/common/cpu_spin_table.c create mode 100644 libcpu/aarch64/common/entry_point.h diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 2467c96773..56caecc1ea 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -14,6 +14,12 @@ #include #include "cp15.h" +#define DBG_TAG "libcpu.aarch64.cpu" +#define DBG_LVL DBG_INFO +#include +#include +#include "cpu.h" + #ifdef RT_USING_SMP void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock) { @@ -62,8 +68,245 @@ void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) : "r"(lock->tickets.owner + 1) : "memory"); } + +#ifdef RT_CPUS_NR +#define ID_ERROR __INT64_MAX__ + +/** + * 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]' + */ +struct cpu_ops_t *cpu_ops_tbl[RT_CPUS_NR]; + +// _id_to_mpidr is a table translate logical id to mpid, which is a 64-bit value +rt_uint64_t rt_cpu_mpidr_early[RT_CPUS_NR] RT_WEAK = {[0 ... RT_CPUS_NR - 1] = ID_ERROR}; + +#ifdef RT_USING_FDT +#include "dtb_node.h" +struct dtb_node *_cpu_node[RT_CPUS_NR]; +#endif /* RT_USING_FDT */ + +#else // RT_CPUS_NR not define +#error "RT_CPUS_NR not define" +#endif /* RT_CPUS_NR */ + +#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);} + +static int _cpus_init_data_hardcoded(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]) +{ + // load in cpu_hw_ids in cpuid_to_hwid, + // cpu_ops to cpu_ops_tbl + if (num_cpus > RT_CPUS_NR) + { + LOG_W("num_cpus (%d) greater than RT_CPUS_NR (%d)\n", num_cpus, RT_CPUS_NR); + num_cpus = RT_CPUS_NR; + } + + for (int i = 0; i < num_cpus; i++) + { + cpuid_to_hwid(i) = cpu_hw_ids[i]; + cpu_ops_tbl[i] = cpu_ops[i]; + } + 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++); + 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 = *pcpuid + 1; + rt_cpu_mpidr_early[*pcpuid] = mpid; + + 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; + 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; + } + + _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[]) +{ + int retval; + + // first setup cpu_ops_tbl and cpuid_to_hwid + if (num_cpus > 0) + retval = _cpus_init_data_hardcoded(num_cpus, cpu_hw_ids, cpu_ops); + else + { + retval = -1; +#ifdef RT_USING_FDT + retval = _cpus_init_data_fdt(); +#endif + } + + if (retval) + return retval; + + // using cpuid_to_hwid and cpu_ops_tbl to call method_init and cpu_init + for (int i = 0; i < RT_CPUS_NR; i++) + { + if (cpuid_to_hwid(i) == ID_ERROR) + { + LOG_E("Failed to find hardware id of CPU %d", i); + continue; + } + + if (cpu_ops_tbl[i]->cpu_init) + { + retval = cpu_ops_tbl[i]->cpu_init(i); + CHECK_RETVAL(retval); + } + else + { + LOG_E("No cpu_init() supported in cpu %d", cpuid_to_hwid(i)); + } + } + 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) + { + 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 + * + * @param num_cpus number of cpus + * @param cpu_hw_ids each element represents a hwid of cpu[i] + * @param cpu_ops each element represents a pointer to cpu_ops of cpu[i] + * @return int 0 on success, + */ +int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]) +{ + int retval = 0; + if (num_cpus < 1 || !cpu_hw_ids || !cpu_ops) + return -1; + + retval = _cpus_init(num_cpus, cpu_hw_ids, cpu_ops); + CHECK_RETVAL(retval); + + if (!retval) + _boot_secondary(); + return retval; +} + #endif /*RT_USING_SMP*/ +#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 */ +} + /** * @addtogroup ARM CPU */ @@ -82,4 +325,10 @@ void rt_hw_cpu_shutdown() } } +RT_WEAK void rt_hw_secondary_cpu_idle_exec(void) +{ + asm volatile("wfe" :: + : "memory", "cc"); +} + /*@}*/ diff --git a/libcpu/aarch64/common/cpu.h b/libcpu/aarch64/common/cpu.h new file mode 100644 index 0000000000..95c26c5ec5 --- /dev/null +++ b/libcpu/aarch64/common/cpu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __RT_HW_CPU_H__ +#define __RT_HW_CPU_H__ + +#include +#include +#include + +struct cpu_ops_t { + const char *method; + int (*cpu_init)(rt_uint32_t id); + int (*cpu_boot)(rt_uint32_t id); + void (*cpu_shutdown)(void); +}; + +extern rt_uint64_t rt_cpu_mpidr_early[]; + +#define cpuid_to_hwid(cpuid) rt_cpu_mpidr_early[cpuid] + +extern void rt_hw_cpu_shutdown(void); + +extern int rt_hw_cpu_init(); + +extern int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]); + +extern struct cpu_ops_t cpu_ops_psci; + +extern struct cpu_ops_t cpu_ops_spin_tbl; + +#endif /* __RT_HW_CPU_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/cpu_psci.c b/libcpu/aarch64/common/cpu_psci.c new file mode 100644 index 0000000000..ea4488c296 --- /dev/null +++ b/libcpu/aarch64/common/cpu_psci.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#include +#include +#include + +#define DBG_TAG "libcpu.aarch64.cpu_psci" +#define DBG_LVL DBG_INFO +#include + +#include "cpu.h" +#include "errno.h" +#include "psci.h" +#include "psci_api.h" +#include "entry_point.h" + +int (*_psci_init)(void) = psci_init; + +static int __call_method_init() +{ + int (*init)(void) = _psci_init; + _psci_init = RT_NULL; + + return init(); +} + +/** return 0 on success, otherwise failed */ +#define _call_method_init() ((_psci_init) ? __call_method_init() : 0); + +static int cpu_psci_cpu_init(rt_uint32_t cpuid) +{ + // init psci only once + return _call_method_init(); +} + +static int cpu_psci_cpu_boot(rt_uint32_t cpuid) +{ + rt_uint64_t secondary_entry_pa = (rt_uint64_t)_secondary_cpu_entry + PV_OFFSET; + if (!psci_ops.cpu_on) { + LOG_E("Uninitialized psci operation"); + return -1; + } + return psci_ops.cpu_on(cpuid_to_hwid(cpuid), secondary_entry_pa); +} + +struct cpu_ops_t cpu_ops_psci = { + .method = "psci", + .cpu_boot = cpu_psci_cpu_boot, + .cpu_init = cpu_psci_cpu_init, + .cpu_shutdown = RT_NULL +}; diff --git a/libcpu/aarch64/common/cpu_spin_table.c b/libcpu/aarch64/common/cpu_spin_table.c new file mode 100644 index 0000000000..89b5880d75 --- /dev/null +++ b/libcpu/aarch64/common/cpu_spin_table.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#include +#include +#include +#include "cpu.h" + +#ifdef RT_USING_FDT +#include +#include "entry_point.h" + +#define get_cpu_node(cpuid) _cpu_node[cpuid] +extern struct dtb_node *_cpu_node[]; + +static rt_uint64_t cpu_release_addr[RT_CPUS_NR]; + +static int spin_table_cpu_init(rt_uint32_t cpuid) +{ + struct dtb_node *cpu = get_cpu_node(cpuid); + if (!cpu) + return -1; + + int size; + rt_uint64_t head = (rt_uint64_t)dtb_node_get_dtb_node_property_value(cpu, "cpu-release-addr", &size); + + cpu_release_addr[cpuid] = fdt64_to_cpu(head); + + return 0; +} + +static int spin_table_cpu_boot(rt_uint32_t cpuid) +{ + rt_uint64_t secondary_entry_pa = (rt_uint64_t)_secondary_cpu_entry + PV_OFFSET; + // map release_addr to addressable place + void *rel_va = rt_ioremap((void *)cpu_release_addr[cpuid], sizeof(cpu_release_addr[0])); + + if (!rel_va) + return -1; + + __asm__ volatile ("str %0, [%1]"::"rZ"(secondary_entry_pa), "r"(rel_va)); + __asm__ volatile ("dsb sy"); + __asm__ volatile ("sev"); + rt_iounmap(rel_va); + return 0; +} +#endif /* RT_USING_FDT */ + +struct cpu_ops_t cpu_ops_spin_tbl = { + .method = "spin-table", +#ifdef RT_USING_FDT + .cpu_init = spin_table_cpu_init, + .cpu_boot = spin_table_cpu_boot, +#endif +}; diff --git a/libcpu/aarch64/common/entry_point.h b/libcpu/aarch64/common/entry_point.h new file mode 100644 index 0000000000..fc3e6c061f --- /dev/null +++ b/libcpu/aarch64/common/entry_point.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __ENTRY_POINT_H__ +#define __ENTRY_POINT_H__ + +extern void _secondary_cpu_entry(void); +#endif /* __ENTRY_POINT_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/psci.c b/libcpu/aarch64/common/psci.c index 772596e249..0fda377c38 100644 --- a/libcpu/aarch64/common/psci.c +++ b/libcpu/aarch64/common/psci.c @@ -70,10 +70,15 @@ static int _psci_init_with_version(int major, int minor); static struct dtb_node *psci_node; +static int psci_ver_major; +static int psci_ver_minor; + /** - * init psci operations. + * @brief init psci operations. * using device tree to probe version and psci-method, * setup psci ops for future use + * + * @return int 0 on success */ int psci_init() { @@ -85,7 +90,7 @@ int psci_init() } char *compatible = dtb_node_get_dtb_node_property_value(psci_node, "compatible", NULL); char *method = dtb_node_get_dtb_node_property_value(psci_node, "method", NULL); - int ver_major, ver_minor; + int retval = 0; // setup psci-method @@ -103,12 +108,12 @@ int psci_init() return -1; } - retval = _psci_probe_version(compatible, &ver_major, &ver_minor); + retval = _psci_probe_version(compatible, &psci_ver_major, &psci_ver_minor); if (retval != 0) return retval; // init psci_ops with specified psci version - retval = _psci_init_with_version(ver_major, ver_minor); + retval = _psci_init_with_version(psci_ver_major, psci_ver_minor); return retval; } @@ -168,7 +173,7 @@ static rt_uint32_t psci_0_2_get_version(void) static void psci_0_2_set_basic_ops() { psci_ops = (struct psci_operations){ - .get_version = psci_0_2_get_version, + .get_version = psci_0_2_get_version, // followings API are v0.1 compatible .cpu_suspend = psci_0_2_cpu_suspend, -- Gitee From 4e84d902da7312cc0c6eedde5f59554142c57b26 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Mon, 15 Aug 2022 18:24:49 +0800 Subject: [PATCH 03/17] =?UTF-8?q?=E6=B6=88=E9=99=A4=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=97=B6=E9=9A=90=E5=BC=8F=E5=A3=B0=E6=98=8E=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84WARNING=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/rtc/rtc.c | 1 + libcpu/aarch64/common/mmu.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/components/drivers/rtc/rtc.c b/components/drivers/rtc/rtc.c index f8e8a43690..08a08c496f 100644 --- a/components/drivers/rtc/rtc.c +++ b/components/drivers/rtc/rtc.c @@ -17,6 +17,7 @@ #include #include +#include /* Using NTP auto sync RTC time */ #ifdef RTC_SYNC_USING_NTP diff --git a/libcpu/aarch64/common/mmu.h b/libcpu/aarch64/common/mmu.h index 81bba3a43e..2d4a00413e 100644 --- a/libcpu/aarch64/common/mmu.h +++ b/libcpu/aarch64/common/mmu.h @@ -135,4 +135,6 @@ void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr); void rt_mm_lock(void); void rt_mm_unlock(void); +void kernel_mmu_switch(unsigned long tbl); + #endif -- Gitee From 7d3afda7a4e7a566d64dbe7513fc58c351c38564 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Mon, 15 Aug 2022 18:31:17 +0800 Subject: [PATCH 04/17] =?UTF-8?q?[bsp/qemu-virt64-aarch64]=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0smp=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/qemu-virt64-aarch64/drivers/board.c | 18 +++++++++- bsp/qemu-virt64-aarch64/drivers/board.h | 4 ++- bsp/qemu-virt64-aarch64/drivers/drv_uart.c | 1 - .../drivers/secondary_cpu.c | 36 +++++++++++++++++++ bsp/qemu-virt64-aarch64/qemu.sh | 2 +- bsp/qemu-virt64-aarch64/rtconfig.h | 5 +++ 6 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c diff --git a/bsp/qemu-virt64-aarch64/drivers/board.c b/bsp/qemu-virt64-aarch64/drivers/board.c index 4bd5e1d2b6..28fc7f2365 100644 --- a/bsp/qemu-virt64-aarch64/drivers/board.c +++ b/bsp/qemu-virt64-aarch64/drivers/board.c @@ -20,6 +20,12 @@ #endif #include "board.h" +#ifdef RT_USING_FDT +#include "interrupt.h" +#include "dtb_node.h" +#include +#endif + #ifdef RT_USING_USERSPACE struct mem_desc platform_mem_desc[] = { {KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM} @@ -74,9 +80,19 @@ void rt_hw_board_init(void) /* initialize system heap */ rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); - rt_components_board_init(); + /* support debug feature before components init */ + rt_hw_uart_init(); rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#ifdef RT_USING_FDT + // TODO 0x44000000 should be replace by a variable + void * fdt_start = (void *)0x44000000 - PV_OFFSET; + device_tree_setup(fdt_start); + rt_hw_cpu_init(); +#endif + + rt_components_board_init(); + rt_thread_idle_sethook(idle_wfi); #ifdef RT_USING_SMP diff --git a/bsp/qemu-virt64-aarch64/drivers/board.h b/bsp/qemu-virt64-aarch64/drivers/board.h index ef7ae4c7dd..4f27cc37ac 100644 --- a/bsp/qemu-virt64-aarch64/drivers/board.h +++ b/bsp/qemu-virt64-aarch64/drivers/board.h @@ -21,7 +21,7 @@ extern unsigned char __bss_end; #ifdef RT_USING_USERSPACE #define HEAP_END (rt_size_t)(KERNEL_VADDR_START + 64 * 1024 * 1024) -#define PAGE_START HEAP_END +#define PAGE_START HEAP_END + 1 * 1024 * 1024 #define PAGE_END ((rt_size_t)KERNEL_VADDR_START + 128 * 1024 * 1024) #else #define HEAP_END ((void *)HEAP_BEGIN + 64 * 1024 * 1024) @@ -29,4 +29,6 @@ extern unsigned char __bss_end; void rt_hw_board_init(void); +int rt_hw_uart_init(void); + #endif diff --git a/bsp/qemu-virt64-aarch64/drivers/drv_uart.c b/bsp/qemu-virt64-aarch64/drivers/drv_uart.c index 804d3afc99..57d9b653eb 100644 --- a/bsp/qemu-virt64-aarch64/drivers/drv_uart.c +++ b/bsp/qemu-virt64-aarch64/drivers/drv_uart.c @@ -141,4 +141,3 @@ int rt_hw_uart_init(void) return 0; } -INIT_BOARD_EXPORT(rt_hw_uart_init); diff --git a/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c b/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c new file mode 100644 index 0000000000..e37477b3f4 --- /dev/null +++ b/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#include +#include +#include +#include "gic.h" +#include "interrupt.h" +#include "mmu.h" + +#ifdef RT_USING_SMP + +extern unsigned long MMUTable[]; + +void rt_hw_secondary_cpu_bsp_start(void) +{ + rt_hw_spin_lock(&_cpus_lock); + + kernel_mmu_switch((unsigned long)MMUTable); + + // interrupt init + rt_hw_vector_init(); + + arm_gic_cpu_init(0, 0); + + // rt_hw_timers_init(); + + rt_system_scheduler_start(); +} + +#endif // SMP \ No newline at end of file diff --git a/bsp/qemu-virt64-aarch64/qemu.sh b/bsp/qemu-virt64-aarch64/qemu.sh index 40eeabc551..1130c5429b 100755 --- a/bsp/qemu-virt64-aarch64/qemu.sh +++ b/bsp/qemu-virt64-aarch64/qemu.sh @@ -1,7 +1,7 @@ if [ ! -f "sd.bin" ]; then dd if=/dev/zero of=sd.bin bs=1024 count=65536 fi -qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -nographic \ +qemu-system-aarch64 -M virt,gic-version=2,virtualization=on,secure=on -cpu cortex-a53 -smp 4 -kernel rtthread.bin -nographic -drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \ -netdev user,id=net0 -device virtio-net-device,netdev=net0,bus=virtio-mmio-bus.1 \ -device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0 diff --git a/bsp/qemu-virt64-aarch64/rtconfig.h b/bsp/qemu-virt64-aarch64/rtconfig.h index 8c5a491a7b..376a553445 100644 --- a/bsp/qemu-virt64-aarch64/rtconfig.h +++ b/bsp/qemu-virt64-aarch64/rtconfig.h @@ -8,6 +8,8 @@ #define RT_NAME_MAX 16 #define RT_USING_SMART +#define RT_USING_SMP +#define RT_CPUS_NR 4 #define RT_ALIGN_SIZE 4 #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 @@ -17,6 +19,7 @@ #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 #define IDLE_THREAD_STACK_SIZE 8192 +#define SYSTEM_THREAD_STACK_SIZE 8192 #define RT_USING_TIMER_SOFT #define RT_TIMER_THREAD_PRIO 4 #define RT_TIMER_THREAD_STACK_SIZE 8192 @@ -119,6 +122,8 @@ #define RT_SERIAL_RB_BUFSZ 256 #define RT_USING_TTY #define RT_USING_PIN +#define RT_USING_FDT +#define RT_USING_FDTLIB #define RT_USING_RTC #define RT_USING_VIRTIO #define RT_USING_VIRTIO10 -- Gitee From 162fc7b8fa55a83faa0713bc60f423e7565fa905 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 11:28:42 +0800 Subject: [PATCH 05/17] =?UTF-8?q?[libcpu/aarch64/cpu.c]=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF=EF=BC=9B=20?= =?UTF-8?q?=E5=9C=A8=E8=8E=B7=E5=8F=96cpuid=E4=B8=8A=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E6=A3=80=E6=9F=A5=EF=BC=9B=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=8E=B7=E5=8F=96fdt=20cpu=20node=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu.c | 21 ++++++++++++++------- libcpu/aarch64/common/cpu.h | 10 +++++++++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 56caecc1ea..cab3dbd29e 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -70,8 +70,6 @@ void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) } #ifdef RT_CPUS_NR -#define ID_ERROR __INT64_MAX__ - /** * 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]' @@ -106,7 +104,7 @@ static int _cpus_init_data_hardcoded(int num_cpus, rt_uint64_t *cpu_hw_ids, stru for (int i = 0; i < num_cpus; i++) { - cpuid_to_hwid(i) = cpu_hw_ids[i]; + rt_cpu_mpidr_early[i] = cpu_hw_ids[i]; cpu_ops_tbl[i] = cpu_ops[i]; } return 0; @@ -146,9 +144,14 @@ static int _read_and_set_hwid(struct dtb_node *cpu, int *id_pool, int *pcpuid) rt_uint64_t mpid = _read_be_number(id_start, address_cells); *pcpuid = *id_pool; - *id_pool = *pcpuid + 1; + *id_pool = *id_pool + 1; rt_cpu_mpidr_early[*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; } @@ -176,6 +179,8 @@ static int _read_and_set_cpuops(struct dtb_node *cpu, int cpuid) LOG_E("Not supported cpu_ops: %s", method); } cpu_ops_tbl[cpuid] = cpu_ops; + + LOG_I("Using boot method [%s] for cpu %d", cpu_ops->method, cpuid); return 0; } @@ -224,7 +229,8 @@ static int _cpus_init(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *c return retval; // using cpuid_to_hwid and cpu_ops_tbl to call method_init and cpu_init - for (int i = 0; i < RT_CPUS_NR; i++) + // assuming that cpuid 0 has already init + for (int i = 1; i < RT_CPUS_NR; i++) { if (cpuid_to_hwid(i) == ID_ERROR) { @@ -232,14 +238,15 @@ static int _cpus_init(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *c continue; } - if (cpu_ops_tbl[i]->cpu_init) + if (cpu_ops_tbl[i] && cpu_ops_tbl[i]->cpu_init) { retval = cpu_ops_tbl[i]->cpu_init(i); CHECK_RETVAL(retval); } else { - LOG_E("No cpu_init() supported in cpu %d", cpuid_to_hwid(i)); + LOG_E("Failed to find cpu_init for cpu %d with cpu_ops[%p], cpu_ops->cpu_init[%p]" + , cpuid_to_hwid(i), cpu_ops_tbl[i], cpu_ops_tbl[i] ? cpu_ops_tbl[i]->cpu_init : NULL); } } return 0; diff --git a/libcpu/aarch64/common/cpu.h b/libcpu/aarch64/common/cpu.h index 95c26c5ec5..6b37cf7869 100644 --- a/libcpu/aarch64/common/cpu.h +++ b/libcpu/aarch64/common/cpu.h @@ -20,9 +20,17 @@ struct cpu_ops_t { void (*cpu_shutdown)(void); }; +/** + * Identifier to mark a wrong CPU MPID. + * All elements in rt_cpu_mpidr_early[] should be initialized with this value + */ +#define ID_ERROR __INT64_MAX__ + extern rt_uint64_t rt_cpu_mpidr_early[]; +extern struct dtb_node *_cpu_node[]; -#define cpuid_to_hwid(cpuid) rt_cpu_mpidr_early[cpuid] +#define cpuid_to_hwid(cpuid) ((cpuid >= 0) && (cpuid < RT_CPUS_NR) ? rt_cpu_mpidr_early[cpuid] : ID_ERROR) +#define get_cpu_node(cpuid) ((cpuid >= 0) && (cpuid < RT_CPUS_NR) ? _cpu_node[cpuid] : 0) extern void rt_hw_cpu_shutdown(void); -- Gitee From 2442b5a4c9324c74376268552734b40520777988 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 11:29:02 +0800 Subject: [PATCH 06/17] =?UTF-8?q?[libcpu/aarch64/cpu.c]=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dspin=5Ftable=E4=B8=AD=E8=A7=A3=E6=9E=90release=20addre?= =?UTF-8?q?ss=E7=9A=84=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu_spin_table.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/libcpu/aarch64/common/cpu_spin_table.c b/libcpu/aarch64/common/cpu_spin_table.c index 89b5880d75..d52fb56e2a 100644 --- a/libcpu/aarch64/common/cpu_spin_table.c +++ b/libcpu/aarch64/common/cpu_spin_table.c @@ -11,26 +11,27 @@ #include #include "cpu.h" +#define DBG_TAG "libcpu.aarch64.cpu_spin_table" +#define DBG_LVL DBG_INFO +#include + #ifdef RT_USING_FDT #include #include "entry_point.h" -#define get_cpu_node(cpuid) _cpu_node[cpuid] -extern struct dtb_node *_cpu_node[]; - static rt_uint64_t cpu_release_addr[RT_CPUS_NR]; static int spin_table_cpu_init(rt_uint32_t cpuid) { struct dtb_node *cpu = get_cpu_node(cpuid); if (!cpu) - return -1; - - int size; - rt_uint64_t head = (rt_uint64_t)dtb_node_get_dtb_node_property_value(cpu, "cpu-release-addr", &size); + return -1; /* uninitialized cpu node in fdt */ - cpu_release_addr[cpuid] = fdt64_to_cpu(head); + int size; + rt_uint64_t *phead = (rt_uint64_t*)dtb_node_get_dtb_node_property_value(cpu, "cpu-release-addr", &size); + cpu_release_addr[cpuid] = fdt64_to_cpu(*phead); + LOG_I("Using release address 0x%p for CPU %d", cpu_release_addr[cpuid], cpuid); return 0; } @@ -41,11 +42,14 @@ static int spin_table_cpu_boot(rt_uint32_t cpuid) void *rel_va = rt_ioremap((void *)cpu_release_addr[cpuid], sizeof(cpu_release_addr[0])); if (!rel_va) + { + LOG_E("IO remap failing"); return -1; + } - __asm__ volatile ("str %0, [%1]"::"rZ"(secondary_entry_pa), "r"(rel_va)); - __asm__ volatile ("dsb sy"); - __asm__ volatile ("sev"); + __asm__ volatile("str %0, [%1]" ::"rZ"(secondary_entry_pa), "r"(rel_va)); + __asm__ volatile("dsb sy"); + __asm__ volatile("sev"); rt_iounmap(rel_va); return 0; } -- Gitee From 453ca057fe34400160f7db3f166c156b60c558ef Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 14:03:55 +0800 Subject: [PATCH 07/17] =?UTF-8?q?[libcpu/aarch64/cpu.c]=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E8=A7=A3=E6=9E=90=E8=AE=BE=E5=A4=87=E6=A0=91=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E8=BE=B9=E9=99=85=E6=A3=80=E6=9F=A5=EF=BC=9B=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=B8=A6=E6=9C=89=E8=BE=B9=E9=99=85=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E7=9A=84=E6=96=B9=E5=BC=8F=E8=AE=BF=E9=97=AE=E5=86=85?= =?UTF-8?q?=E9=83=A8=E6=95=B0=E7=BB=84=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu.c | 13 ++++++++++--- libcpu/aarch64/common/cpu.h | 6 ++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index cab3dbd29e..244f11f5f7 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -104,7 +104,7 @@ static int _cpus_init_data_hardcoded(int num_cpus, rt_uint64_t *cpu_hw_ids, stru for (int i = 0; i < num_cpus; i++) { - rt_cpu_mpidr_early[i] = cpu_hw_ids[i]; + set_hwid(i, cpu_hw_ids[i]); cpu_ops_tbl[i] = cpu_ops[i]; } return 0; @@ -145,7 +145,7 @@ static int _read_and_set_hwid(struct dtb_node *cpu, int *id_pool, int *pcpuid) *pcpuid = *id_pool; *id_pool = *id_pool + 1; - rt_cpu_mpidr_early[*pcpuid] = mpid; + set_hwid(*pcpuid, mpid); LOG_I("Using MPID 0x%lx as cpu %d", mpid, *pcpuid); @@ -200,6 +200,13 @@ static int _cpus_init_data_fdt() 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); @@ -261,7 +268,7 @@ static void _boot_secondary(void) retval = cpu_ops_tbl[i]->cpu_boot(i); if (retval) { - LOG_E("Failed to boot secondary CPU %d , error code %d", i, retval); + LOG_E("Failed to boot secondary CPU %d, error code %d", i, retval); } else { LOG_I("Secondary CPU %d booted", i); } diff --git a/libcpu/aarch64/common/cpu.h b/libcpu/aarch64/common/cpu.h index 6b37cf7869..3a77f883d8 100644 --- a/libcpu/aarch64/common/cpu.h +++ b/libcpu/aarch64/common/cpu.h @@ -29,8 +29,10 @@ struct cpu_ops_t { extern rt_uint64_t rt_cpu_mpidr_early[]; extern struct dtb_node *_cpu_node[]; -#define cpuid_to_hwid(cpuid) ((cpuid >= 0) && (cpuid < RT_CPUS_NR) ? rt_cpu_mpidr_early[cpuid] : ID_ERROR) -#define get_cpu_node(cpuid) ((cpuid >= 0) && (cpuid < RT_CPUS_NR) ? _cpu_node[cpuid] : 0) +#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) extern void rt_hw_cpu_shutdown(void); -- Gitee From 53bf7b98dc6dce31f841ea4e54597bfb766ec60d Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 14:21:41 +0800 Subject: [PATCH 08/17] =?UTF-8?q?[libcpu/aarch64]=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF=E7=9A=84LOG=E7=AD=89?= =?UTF-8?q?=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu.c | 2 +- libcpu/aarch64/common/cpu.h | 23 ++++++++++++++--------- libcpu/aarch64/common/cpu_spin_table.c | 2 +- libcpu/aarch64/common/psci.c | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 244f11f5f7..d55431ad8e 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -180,7 +180,7 @@ static int _read_and_set_cpuops(struct dtb_node *cpu, int cpuid) } cpu_ops_tbl[cpuid] = cpu_ops; - LOG_I("Using boot method [%s] for cpu %d", cpu_ops->method, cpuid); + LOG_D("Using boot method [%s] for cpu %d", cpu_ops->method, cpuid); return 0; } diff --git a/libcpu/aarch64/common/cpu.h b/libcpu/aarch64/common/cpu.h index 3a77f883d8..ba5336570a 100644 --- a/libcpu/aarch64/common/cpu.h +++ b/libcpu/aarch64/common/cpu.h @@ -6,33 +6,38 @@ * Change Logs: * Date Author Notes */ -#ifndef __RT_HW_CPU_H__ -#define __RT_HW_CPU_H__ +#ifndef __RT_HW_CPU_H__ +#define __RT_HW_CPU_H__ #include #include #include -struct cpu_ops_t { +struct cpu_ops_t +{ const char *method; int (*cpu_init)(rt_uint32_t id); int (*cpu_boot)(rt_uint32_t id); void (*cpu_shutdown)(void); }; -/** +/** * Identifier to mark a wrong CPU MPID. - * All elements in rt_cpu_mpidr_early[] should be initialized with this value + * All elements in rt_cpu_mpidr_early[] should be initialized with this value */ #define ID_ERROR __INT64_MAX__ extern rt_uint64_t rt_cpu_mpidr_early[]; extern struct dtb_node *_cpu_node[]; -#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) +#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) extern void rt_hw_cpu_shutdown(void); diff --git a/libcpu/aarch64/common/cpu_spin_table.c b/libcpu/aarch64/common/cpu_spin_table.c index d52fb56e2a..637d728251 100644 --- a/libcpu/aarch64/common/cpu_spin_table.c +++ b/libcpu/aarch64/common/cpu_spin_table.c @@ -31,7 +31,7 @@ static int spin_table_cpu_init(rt_uint32_t cpuid) rt_uint64_t *phead = (rt_uint64_t*)dtb_node_get_dtb_node_property_value(cpu, "cpu-release-addr", &size); cpu_release_addr[cpuid] = fdt64_to_cpu(*phead); - LOG_I("Using release address 0x%p for CPU %d", cpu_release_addr[cpuid], cpuid); + LOG_D("Using release address 0x%p for CPU %d", cpu_release_addr[cpuid], cpuid); return 0; } diff --git a/libcpu/aarch64/common/psci.c b/libcpu/aarch64/common/psci.c index 0fda377c38..2633651b0f 100644 --- a/libcpu/aarch64/common/psci.c +++ b/libcpu/aarch64/common/psci.c @@ -221,7 +221,7 @@ static int _psci_probe_version(char *version, int *major, int *minor) LOG_E("[%s] was not a proper PSCI version", version); retval = -1; } - LOG_I("Using PSCI v%d.%d", *major, *minor); + LOG_D("Using PSCI v%d.%d", *major, *minor); return retval; } -- Gitee From 8e595860708ebfe1a5d6fcb3348f6926c5b50925 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 14:38:23 +0800 Subject: [PATCH 09/17] =?UTF-8?q?[libcpu/aarch64]=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=9D=9ESMP=E7=8E=AF=E5=A2=83=E4=B8=8B=E5=AF=B9rt=5Fhw=5Fcpu?= =?UTF-8?q?=5Finit()=E7=9A=84=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/qemu-virt64-aarch64/drivers/board.c | 2 +- libcpu/aarch64/common/cpu.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bsp/qemu-virt64-aarch64/drivers/board.c b/bsp/qemu-virt64-aarch64/drivers/board.c index 28fc7f2365..9096b6b380 100644 --- a/bsp/qemu-virt64-aarch64/drivers/board.c +++ b/bsp/qemu-virt64-aarch64/drivers/board.c @@ -84,7 +84,7 @@ void rt_hw_board_init(void) rt_hw_uart_init(); rt_console_set_device(RT_CONSOLE_DEVICE_NAME); -#ifdef RT_USING_FDT +#if defined(RT_USING_FDT) && defined(RT_USING_SMP) // TODO 0x44000000 should be replace by a variable void * fdt_start = (void *)0x44000000 - PV_OFFSET; device_tree_setup(fdt_start); diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index d55431ad8e..5664b6acca 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -302,8 +302,6 @@ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_o return retval; } -#endif /*RT_USING_SMP*/ - #define CPU_INIT_USING_FDT 0,0,0 /** @@ -321,6 +319,8 @@ int rt_hw_cpu_init() #endif /* RT_USING_FDT */ } +#endif /*RT_USING_SMP*/ + /** * @addtogroup ARM CPU */ -- Gitee From 60d76ab5b56e41a55ffa442f403cd58b9d60d4c8 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 14:44:28 +0800 Subject: [PATCH 10/17] =?UTF-8?q?[libcpu/aarch64]=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 5664b6acca..8d731e7c30 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -69,7 +69,6 @@ void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) : "memory"); } -#ifdef RT_CPUS_NR /** * 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]' @@ -84,10 +83,6 @@ rt_uint64_t rt_cpu_mpidr_early[RT_CPUS_NR] RT_WEAK = {[0 ... RT_CPUS_NR - 1] = I struct dtb_node *_cpu_node[RT_CPUS_NR]; #endif /* RT_USING_FDT */ -#else // RT_CPUS_NR not define -#error "RT_CPUS_NR not define" -#endif /* RT_CPUS_NR */ - #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);} -- Gitee From 87d3e4c1f8bc30feb045c7447ed15d1426f951a0 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 15:17:53 +0800 Subject: [PATCH 11/17] =?UTF-8?q?[libcpu/aarch64]=20=E6=B6=88=E9=99=A4?= =?UTF-8?q?=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E6=9D=A1=E4=BB=B6=E7=BC=96?= =?UTF-8?q?=E8=AF=91=EF=BC=9B=20=E5=A2=9E=E5=8A=A0rt=5Fhw=5Fsecondary=5Fcp?= =?UTF-8?q?u=5Fidle=5Fexec=E7=9A=84=E6=9D=A1=E4=BB=B6=E7=BC=96=E8=AF=91?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu.c | 13 +++++++------ libcpu/aarch64/common/cpu.h | 2 ++ libcpu/aarch64/common/psci.c | 7 ------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 8d731e7c30..11db043ba8 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -314,6 +314,13 @@ int rt_hw_cpu_init() #endif /* RT_USING_FDT */ } +RT_WEAK void rt_hw_secondary_cpu_idle_exec(void) +{ + asm volatile("wfe" :: + : "memory", "cc"); +} + + #endif /*RT_USING_SMP*/ /** @@ -334,10 +341,4 @@ void rt_hw_cpu_shutdown() } } -RT_WEAK void rt_hw_secondary_cpu_idle_exec(void) -{ - asm volatile("wfe" :: - : "memory", "cc"); -} - /*@}*/ diff --git a/libcpu/aarch64/common/cpu.h b/libcpu/aarch64/common/cpu.h index ba5336570a..670d34a865 100644 --- a/libcpu/aarch64/common/cpu.h +++ b/libcpu/aarch64/common/cpu.h @@ -45,6 +45,8 @@ extern int rt_hw_cpu_init(); extern int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]); +extern void rt_hw_secondary_cpu_idle_exec(void); + extern struct cpu_ops_t cpu_ops_psci; extern struct cpu_ops_t cpu_ops_spin_tbl; diff --git a/libcpu/aarch64/common/psci.c b/libcpu/aarch64/common/psci.c index 2633651b0f..4269efb4e9 100644 --- a/libcpu/aarch64/common/psci.c +++ b/libcpu/aarch64/common/psci.c @@ -124,7 +124,6 @@ static rt_uint32_t cpu_off_0_1; static rt_uint32_t cpu_on_0_1; static rt_uint32_t migrate_0_1; -#ifdef RT_USING_FDT /* basic operations TEMPLATE for API since 0.1 version */ COMMON_PSCI_OPS_TEMPLATE(0_1, cpu_suspend_0_1, cpu_off_0_1, cpu_on_0_1, migrate_0_1); @@ -148,7 +147,6 @@ COMMON_PSCI_OPS_TEMPLATE(0_1, cpu_suspend_0_1, cpu_off_0_1, cpu_on_0_1, migrate_ static int psci_0_1_init() { -#ifdef RT_USING_FDT // reading function id from fdt rt_uint32_t *funcid; PROBE_AND_SET(cpu_suspend); @@ -156,13 +154,8 @@ static int psci_0_1_init() PROBE_AND_SET(cpu_on); PROBE_AND_SET(migrate); return 0; -#else - return -1; -#endif } -#endif /* RT_USING_FDT */ - COMMON_PSCI_OPS_TEMPLATE(0_2, PSCI_FN_NATIVE(0_2, CPU_SUSPEND), PSCI_0_2_FN_CPU_OFF, PSCI_FN_NATIVE(0_2, CPU_ON), PSCI_FN_NATIVE(0_2, MIGRATE)); static rt_uint32_t psci_0_2_get_version(void) -- Gitee From 9f74991abecd941ecf1d6b0a17021a9167f6aafe Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 15:24:45 +0800 Subject: [PATCH 12/17] =?UTF-8?q?[bsp/qemu-virt64-aarch64]=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c b/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c index e37477b3f4..c9602c6432 100644 --- a/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c +++ b/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c @@ -28,7 +28,7 @@ void rt_hw_secondary_cpu_bsp_start(void) arm_gic_cpu_init(0, 0); - // rt_hw_timers_init(); + // local timer init rt_system_scheduler_start(); } -- Gitee From 2aee6b7f890fecd4ed0eb3b6a0123f403a81412b Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 16 Aug 2022 16:23:56 +0800 Subject: [PATCH 13/17] =?UTF-8?q?[libcpu/aarch64]=20=5Fpsci=5Finit?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0static=E9=99=90=E5=AE=9A=E7=AC=A6=EF=BC=9B=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BC=A9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu.h | 2 +- libcpu/aarch64/common/cpu_psci.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libcpu/aarch64/common/cpu.h b/libcpu/aarch64/common/cpu.h index 670d34a865..2bc3d0dc36 100644 --- a/libcpu/aarch64/common/cpu.h +++ b/libcpu/aarch64/common/cpu.h @@ -18,7 +18,7 @@ struct cpu_ops_t const char *method; int (*cpu_init)(rt_uint32_t id); int (*cpu_boot)(rt_uint32_t id); - void (*cpu_shutdown)(void); + void (*cpu_shutdown)(void); }; /** diff --git a/libcpu/aarch64/common/cpu_psci.c b/libcpu/aarch64/common/cpu_psci.c index ea4488c296..d103dac0a1 100644 --- a/libcpu/aarch64/common/cpu_psci.c +++ b/libcpu/aarch64/common/cpu_psci.c @@ -20,7 +20,7 @@ #include "psci_api.h" #include "entry_point.h" -int (*_psci_init)(void) = psci_init; +static int (*_psci_init)(void) = psci_init; static int __call_method_init() { -- Gitee From 14b7271791446ff5d545e39ee5807f1c1f6e6b11 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Wed, 17 Aug 2022 10:50:56 +0800 Subject: [PATCH 14/17] =?UTF-8?q?[libcpu/aarch64]=20=E4=BF=AE=E6=94=B9V2P?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E5=BC=8F=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu_ops_common.h | 21 +++++++++++++++++++++ libcpu/aarch64/common/cpu_psci.c | 4 ++-- libcpu/aarch64/common/cpu_spin_table.c | 4 ++-- 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 libcpu/aarch64/common/cpu_ops_common.h diff --git a/libcpu/aarch64/common/cpu_ops_common.h b/libcpu/aarch64/common/cpu_ops_common.h new file mode 100644 index 0000000000..304901fe91 --- /dev/null +++ b/libcpu/aarch64/common/cpu_ops_common.h @@ -0,0 +1,21 @@ +#ifndef __CPU_OPS_COMMON_H__ +#define __CPU_OPS_COMMON_H__ + +#include +#include +#include +#include "entry_point.h" + +static inline rt_uint64_t get_secondary_entry_pa(void) +{ + rt_uint64_t secondary_entry_pa = (rt_uint64_t)rt_hw_mmu_v2p(&mmu_info, _secondary_cpu_entry); + + if (!secondary_entry_pa) + { + LOG_E("Failed to translate 'secondary_entry_pa' to physical address"); + return -1; + } + return secondary_entry_pa; +} + +#endif /* __CPU_OPS_COMMON_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/cpu_psci.c b/libcpu/aarch64/common/cpu_psci.c index d103dac0a1..44a53c7c29 100644 --- a/libcpu/aarch64/common/cpu_psci.c +++ b/libcpu/aarch64/common/cpu_psci.c @@ -13,12 +13,12 @@ #define DBG_TAG "libcpu.aarch64.cpu_psci" #define DBG_LVL DBG_INFO #include +#include "cpu_ops_common.h" #include "cpu.h" #include "errno.h" #include "psci.h" #include "psci_api.h" -#include "entry_point.h" static int (*_psci_init)(void) = psci_init; @@ -41,7 +41,7 @@ static int cpu_psci_cpu_init(rt_uint32_t cpuid) static int cpu_psci_cpu_boot(rt_uint32_t cpuid) { - rt_uint64_t secondary_entry_pa = (rt_uint64_t)_secondary_cpu_entry + PV_OFFSET; + rt_uint64_t secondary_entry_pa = get_secondary_entry_pa(); if (!psci_ops.cpu_on) { LOG_E("Uninitialized psci operation"); return -1; diff --git a/libcpu/aarch64/common/cpu_spin_table.c b/libcpu/aarch64/common/cpu_spin_table.c index 637d728251..6dcdee3c89 100644 --- a/libcpu/aarch64/common/cpu_spin_table.c +++ b/libcpu/aarch64/common/cpu_spin_table.c @@ -14,10 +14,10 @@ #define DBG_TAG "libcpu.aarch64.cpu_spin_table" #define DBG_LVL DBG_INFO #include +#include "cpu_ops_common.h" #ifdef RT_USING_FDT #include -#include "entry_point.h" static rt_uint64_t cpu_release_addr[RT_CPUS_NR]; @@ -37,7 +37,7 @@ static int spin_table_cpu_init(rt_uint32_t cpuid) static int spin_table_cpu_boot(rt_uint32_t cpuid) { - rt_uint64_t secondary_entry_pa = (rt_uint64_t)_secondary_cpu_entry + PV_OFFSET; + rt_uint64_t secondary_entry_pa = get_secondary_entry_pa(); // map release_addr to addressable place void *rel_va = rt_ioremap((void *)cpu_release_addr[cpuid], sizeof(cpu_release_addr[0])); -- Gitee From c45380e8543b91a8f7a0e332fd506934518ecf34 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Wed, 17 Aug 2022 10:52:26 +0800 Subject: [PATCH 15/17] =?UTF-8?q?[libcpu/aarch64]=20mmu.c=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0mmu=5Finfo=E5=A3=B0=E6=98=8E=EF=BC=9B=20psci=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E4=BD=93=E8=B0=83=E6=95=B4=E4=B8=BApsci=5Fops=5Ft?= =?UTF-8?q?=EF=BC=9B=20=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9D=83=E5=A4=B4?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/mmu.h | 2 ++ libcpu/aarch64/common/psci.c | 4 ++-- libcpu/aarch64/common/psci_api.h | 4 ++-- libcpu/aarch64/common/smccc.S | 9 ++++++++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libcpu/aarch64/common/mmu.h b/libcpu/aarch64/common/mmu.h index 2d4a00413e..abd8191f1d 100644 --- a/libcpu/aarch64/common/mmu.h +++ b/libcpu/aarch64/common/mmu.h @@ -137,4 +137,6 @@ void rt_mm_unlock(void); void kernel_mmu_switch(unsigned long tbl); +extern rt_mmu_info mmu_info; + #endif diff --git a/libcpu/aarch64/common/psci.c b/libcpu/aarch64/common/psci.c index 4269efb4e9..8fc23a673f 100644 --- a/libcpu/aarch64/common/psci.c +++ b/libcpu/aarch64/common/psci.c @@ -41,7 +41,7 @@ #ifdef RT_USING_FDT #include "dtb_node.h" -struct psci_operations psci_ops; +struct psci_ops_t psci_ops; #if __SIZE_WIDTH__ == 64 #define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN64_##name @@ -165,7 +165,7 @@ static rt_uint32_t psci_0_2_get_version(void) static void psci_0_2_set_basic_ops() { - psci_ops = (struct psci_operations){ + psci_ops = (struct psci_ops_t){ .get_version = psci_0_2_get_version, // followings API are v0.1 compatible diff --git a/libcpu/aarch64/common/psci_api.h b/libcpu/aarch64/common/psci_api.h index 78ff04a575..8c939f3abc 100644 --- a/libcpu/aarch64/common/psci_api.h +++ b/libcpu/aarch64/common/psci_api.h @@ -15,7 +15,7 @@ #include "psci_api.h" /** generic psci ops supported v0.1 v0.2 v1.0 v1.1 */ -struct psci_operations +struct psci_ops_t { uint32_t (*get_version)(void); int32_t (*cpu_suspend)(uint32_t state, unsigned long entry_point); @@ -24,7 +24,7 @@ struct psci_operations int32_t (*migrate)(unsigned long cpuid); }; -extern struct psci_operations psci_ops; +extern struct psci_ops_t psci_ops; extern int psci_init(void); diff --git a/libcpu/aarch64/common/smccc.S b/libcpu/aarch64/common/smccc.S index c6e0402fd1..6428bc988b 100644 --- a/libcpu/aarch64/common/smccc.S +++ b/libcpu/aarch64/common/smccc.S @@ -1,4 +1,11 @@ - +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ /** * SMCCC v0.2 * ARM DEN0028E chapter 2.6 -- Gitee From 442f10c6bc0b393d936ad765b7aab897a9f34063 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Wed, 17 Aug 2022 10:57:15 +0800 Subject: [PATCH 16/17] =?UTF-8?q?[libcpu/aarch64]=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E8=8E=B7=E5=8F=96secondary=5Fentry=E7=89=A9=E7=90=86=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E7=9A=84=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu_ops_common.h | 2 +- libcpu/aarch64/common/cpu_psci.c | 4 ++++ libcpu/aarch64/common/cpu_spin_table.c | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libcpu/aarch64/common/cpu_ops_common.h b/libcpu/aarch64/common/cpu_ops_common.h index 304901fe91..3ac0a363c3 100644 --- a/libcpu/aarch64/common/cpu_ops_common.h +++ b/libcpu/aarch64/common/cpu_ops_common.h @@ -13,7 +13,7 @@ static inline rt_uint64_t get_secondary_entry_pa(void) if (!secondary_entry_pa) { LOG_E("Failed to translate 'secondary_entry_pa' to physical address"); - return -1; + return 0; } return secondary_entry_pa; } diff --git a/libcpu/aarch64/common/cpu_psci.c b/libcpu/aarch64/common/cpu_psci.c index 44a53c7c29..8bdfcc95c3 100644 --- a/libcpu/aarch64/common/cpu_psci.c +++ b/libcpu/aarch64/common/cpu_psci.c @@ -42,6 +42,10 @@ static int cpu_psci_cpu_init(rt_uint32_t cpuid) static int cpu_psci_cpu_boot(rt_uint32_t cpuid) { rt_uint64_t secondary_entry_pa = get_secondary_entry_pa(); + + if (!secondary_entry_pa) + return -1; + if (!psci_ops.cpu_on) { LOG_E("Uninitialized psci operation"); return -1; diff --git a/libcpu/aarch64/common/cpu_spin_table.c b/libcpu/aarch64/common/cpu_spin_table.c index 6dcdee3c89..26ddb58fed 100644 --- a/libcpu/aarch64/common/cpu_spin_table.c +++ b/libcpu/aarch64/common/cpu_spin_table.c @@ -38,6 +38,9 @@ static int spin_table_cpu_init(rt_uint32_t cpuid) static int spin_table_cpu_boot(rt_uint32_t cpuid) { rt_uint64_t secondary_entry_pa = get_secondary_entry_pa(); + if (!secondary_entry_pa) + return -1; + // map release_addr to addressable place void *rel_va = rt_ioremap((void *)cpu_release_addr[cpuid], sizeof(cpu_release_addr[0])); -- Gitee From c34a0ccca5b2054fc3f7fe3c0a7060b22248efb2 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Wed, 17 Aug 2022 15:09:05 +0800 Subject: [PATCH 17/17] =?UTF-8?q?[libcpu/aarch46]=20=E6=9B=B4=E6=AD=A3?= =?UTF-8?q?=E4=B8=8D=E4=BD=BF=E7=94=A8FDT=E4=B8=8B=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/aarch64/common/cpu.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 11db043ba8..724da69353 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -26,7 +26,7 @@ void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock) lock->slock = 0; } -#define TICKET_SHIFT 16 +#define TICKET_SHIFT 16 void rt_hw_spin_lock(rt_hw_spinlock_t *lock) { unsigned int tmp; @@ -277,11 +277,11 @@ RT_WEAK void rt_hw_secondary_cpu_up(void) /** * @brief boot cpu with hardcoded data - * + * * @param num_cpus number of cpus * @param cpu_hw_ids each element represents a hwid of cpu[i] * @param cpu_ops each element represents a pointer to cpu_ops of cpu[i] - * @return int 0 on success, + * @return int 0 on success, */ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]) { @@ -292,8 +292,6 @@ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_o retval = _cpus_init(num_cpus, cpu_hw_ids, cpu_ops); CHECK_RETVAL(retval); - if (!retval) - _boot_secondary(); return retval; } @@ -301,8 +299,8 @@ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_o /** * @brief Initialize cpu infomation from fdt - * - * @return int + * + * @return int */ int rt_hw_cpu_init() { @@ -320,7 +318,6 @@ RT_WEAK void rt_hw_secondary_cpu_idle_exec(void) : "memory", "cc"); } - #endif /*RT_USING_SMP*/ /** -- Gitee