From ef4eab7b4c1bc948a46c660c122a0baba8cc8d7c Mon Sep 17 00:00:00 2001 From: kangkaiping Date: Tue, 5 Aug 2025 17:12:06 +0800 Subject: [PATCH] code update 2025_08_05 --- arch/armv8/common/fpsci.c | 19 +++++++++++++-- arch/armv8/common/fpsci.h | 8 ++++-- doc/ChangeLog.md | 20 +++++++++++++++ example/system/arch/armv8/psci/README.md | 12 +++++++-- .../armv8/psci/figs/get_cpu_type_and_id.png | Bin 0 -> 17130 bytes .../armv8/psci/psci_test/build/amp_packed.c | 0 .../arch/armv8/psci/psci_test/inc/psci_test.h | 9 ++++--- .../system/arch/armv8/psci/psci_test/main.c | 2 +- .../arch/armv8/psci/psci_test/sdkconfig | 2 ++ .../arch/armv8/psci/psci_test/sdkconfig.h | 2 ++ .../arch/armv8/psci/psci_test/src/cmd_psci.c | 14 +++++++++-- .../arch/armv8/psci/psci_test/src/psci_test.c | 23 ++++++++++++++++-- third-party/libmetal/src.mk | 9 ------- third-party/openamp/include.mk | 1 + .../lib/include/openamp/remoteproc_virtio.h | 3 +-- .../openamp/{ports => lib}/version_def.h | 4 +-- .../machine/phytium/platform_info.c | 4 +-- 17 files changed, 102 insertions(+), 30 deletions(-) create mode 100644 example/system/arch/armv8/psci/figs/get_cpu_type_and_id.png delete mode 100644 example/system/arch/armv8/psci/psci_test/build/amp_packed.c rename third-party/openamp/{ports => lib}/version_def.h (94%) diff --git a/arch/armv8/common/fpsci.c b/arch/armv8/common/fpsci.c index 004f5b769..cb819bcf5 100644 --- a/arch/armv8/common/fpsci.c +++ b/arch/armv8/common/fpsci.c @@ -16,13 +16,14 @@ * * FilePath: fpsci.c * Created Date: 2023-06-21 10:36:53 - * Last Modified: 2024-11-22 15:30:25 + * Last Modified: 2025-08-05 10:49:55 * Description: This file is for * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 huanghe 2023-06-21 first release + * 1.1 kangkaiping 2025-08-04 add get cpuinfo */ @@ -30,7 +31,6 @@ #include "fsmcc.h" /* 根据你的平台和编译环境来确定这个路径 */ #include "fpsci.h" #include "fassert.h" -#include "fcompiler.h" #include "fdebug.h" #include "fcpu_info.h" @@ -43,6 +43,9 @@ /* 定义PSCI 函数值 */ #define FPSCI_0_2_FN32_BASE 0x84000000 #define FPSCI_0_2_FN64_BASE 0xC4000000 +#define FPSCI_SIP_FN64_BASE 0xC2000000 +#define FPSCI_CPU_VERSION (FPSCI_SIP_FN64_BASE + 0x002) + #define FPSCI_VERSION (FPSCI_0_2_FN32_BASE + 0x000) #define FPSCI_FEATURES (FPSCI_0_2_FN32_BASE + 0x00a) #define FPSCI_CPU_SUSPEND_AARCH32 (FPSCI_0_2_FN32_BASE + 0x001) @@ -60,6 +63,7 @@ #define FPSCI_SYSTEM_RESET (FPSCI_0_2_FN32_BASE + 0x009) #define FPSCI_SYSTEM_SUSPEND (FPSCI_0_2_FN32_BASE + 0x00E) + /* 定义每个PSCI函数ID的位标记 */ #define FPSCI_PSCI_VERSION_BIT (1 << 0) #define FPSCI_PSCI_FEATURES_BIT (1 << 1) @@ -118,6 +122,17 @@ int FPsciFeatures(u32 psci_fid) { return res.a0 == FPSCI_SUCCESS ? 1 : 0; } + +#if defined(FAARCH64_USE) +int FPsciCpuVersion(struct FSmcccRes *res,u32 cpu_index) +{ + + FASSERT((*f_psci_invoke)); + (*f_psci_invoke)(FPSCI_CPU_VERSION, cpu_index, 0, 0, 0, 0, 0, 0, res); + return res->a0 == FPSCI_SUCCESS ? 1 : 0; +} +#endif + /** * @name: FPsciCpuSuspend * @msg: Suspend execution on a particular CPU. diff --git a/arch/armv8/common/fpsci.h b/arch/armv8/common/fpsci.h index 2dbac4646..738dead31 100644 --- a/arch/armv8/common/fpsci.h +++ b/arch/armv8/common/fpsci.h @@ -16,7 +16,7 @@ * * FilePath: fpsci.h * Created Date: 2023-06-21 16:13:14 - * Last Modified: 2023-06-27 15:33:23 + * Last Modified: 2025-08-05 10:49:01 * Description: This file is for * * Modify History: @@ -33,7 +33,8 @@ extern "C" { #endif #include "ftypes.h" - +#include "fsmcc.h" +#include "fcompiler.h" /* 版本掩码 */ #define FPSCI_VERSION_MASK 0x0000FFFF @@ -84,6 +85,9 @@ void FPsciSystemReset(u32 reset_type) ; int FPsciFeatures(u32 psci_fid) ; int FPsciCpuOff(void) ; int FPsciCpuMaskOn(s32 cpu_id_mask, uintptr bootaddr) ; +#if defined(FAARCH64_USE) +int FPsciCpuVersion(struct FSmcccRes *res,u32 cpu_index) ; +#endif #ifdef __cplusplus } #endif diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index d2e9ce1be..a5efdde57 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -1,3 +1,12 @@ +# Phytium Standalone SDK 2025-07-31 ChangeLog + +Change Log since 2025-07-28 + +## third-party + +- move version.h to third-party/openamp/lib +- VIRTIO_CACHED_RSC_TABLE is deprecated, delete it + # Phytium Standalone SDK 2025-07-28 ChangeLog Change Log since 2025-07-28 @@ -5,6 +14,17 @@ Change Log since 2025-07-28 ## arch - add barrier to solve the gicv3 issue +# Phytium Standalone SDK 2025-07-25 ChangeLog + +Change Log since 2025-07-25 + +## driver + +- modify add psci get cpuid ability + +## example + +- modify add psci_test.c cmd for psci cpu_version # Phytium Standalone SDK 2025-07-21 ChangeLog diff --git a/example/system/arch/armv8/psci/README.md b/example/system/arch/armv8/psci/README.md index 1fbedb300..a94ab6192 100644 --- a/example/system/arch/armv8/psci/README.md +++ b/example/system/arch/armv8/psci/README.md @@ -7,7 +7,7 @@ ``介绍例程的用途,使用场景,相关基本概念,描述用户可以使用例程完成哪些工作 `
` -本例程主要演示了PSCI 初始化特性以及CPU hotplug 的功能 +本例程主要演示了PSCI 初始化特性以及CPU hotplug, 获取CPU相关信息(只支持AARCH64)的功能 本例程一共包含了两个工程目录,分别如下所示: @@ -97,6 +97,13 @@ bootelf -p f0000000 ![master_slave_test](figs/master_slave_test.png) +```c + psci cpu_version +``` + +- 此命令用于获取cpu的类型号及ID值 + +![psci_feature](figs/get_cpu_type_and_id.png) ## 3. 如何解决问题 (Q&A) @@ -107,4 +114,5 @@ bootelf -p f0000000 > ``记录例程的重大修改记录,标明修改发生的版本号 `
` - 2023-06-27 :v1.0.0 初始化项目 -- 2024-06-27 :v1.1.0 整改多核启动方式,优化代码结构 \ No newline at end of file +- 2024-06-27 :v1.1.0 整改多核启动方式,优化代码结构 +- 2025-08-05 : 添加读CPU信息,只支持aarch64 \ No newline at end of file diff --git a/example/system/arch/armv8/psci/figs/get_cpu_type_and_id.png b/example/system/arch/armv8/psci/figs/get_cpu_type_and_id.png new file mode 100644 index 0000000000000000000000000000000000000000..f02e65d61b0ba50e9763c3cf2303d6d10281c8b1 GIT binary patch literal 17130 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 kkdWU`{`Y|YbsbH(@ciuY1K#qjOyZ+T^6GNsPhY