Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 52 additions & 15 deletions src/arm/windows/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,26 @@ static struct core_info_by_chip_name get_core_info_from_midr(uint32_t midr, uint
return info;
}

/* https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers
CP 4000: MIDR_EL1
CP 4020: ID_AA64PFR0_EL1
CP 4021: ID_AA64PFR1_EL1
CP 4028: ID_AA64DFR0_EL1
CP 4029: ID_AA64DFR1_EL1
CP 402C: ID_AA64AFR0_EL1
CP 402D: ID_AA64AFR1_EL1
CP 4030: ID_AA64ISAR0_EL1
CP 4031: ID_AA64ISAR1_EL1
CP 4038: ID_AA64MMFR0_EL1
CP 4039: ID_AA64MMFR1_EL1
CP 403A: ID_AA64MMFR2_EL1
CP 4080: ?
CP 4081: ?
CP 4100: ?
CP 4510: ?
CP 5801: ?
*/

static struct woa_chip_info* get_system_info_from_registry(void) {
wchar_t* text_buffer = NULL;
LPCWSTR cpu0_subkey = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
Expand Down Expand Up @@ -195,21 +215,38 @@ static void set_cpuinfo_isa_fields(void) {
const bool dotprod = IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.dot = dotprod;

SYSTEM_INFO system_info;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This switch statement did nothing so I removed it

GetSystemInfo(&system_info);
switch (system_info.wProcessorLevel) {
case 0x803: // Kryo 385 Silver (Snapdragon 850)
cpuinfo_isa.fp16arith = dotprod;
cpuinfo_isa.rdm = dotprod;
break;
default:
// Assume that Dot Product support implies FP16
// arithmetics and RDM support. ARM manuals don't
// guarantee that, but it holds in practice.
cpuinfo_isa.fp16arith = dotprod;
cpuinfo_isa.rdm = dotprod;
break;
}
cpuinfo_isa.sve = IsProcessorFeaturePresent(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.sve2 = IsProcessorFeaturePresent(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.i8mm = IsProcessorFeaturePresent(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.jscvt = IsProcessorFeaturePresent(PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.fcma = IsProcessorFeaturePresent(PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE) != 0;
// FEAT_FP16 Implies FEAT_FHM in 8.4 https://developer.arm.com/documentation/109697/2025_09/Feature-descriptions/The-Armv8-4-architecture-extension?lang=en
cpuinfo_isa.fhm = IsProcessorFeaturePresent(PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.fp16arith = cpuinfo_isa.fhm;

cpuinfo_isa.sme = IsProcessorFeaturePresent(PF_ARM_SME_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.sme2 = IsProcessorFeaturePresent(PF_ARM_SME2_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.sme2p1 = IsProcessorFeaturePresent(PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.sme_b16b16 = IsProcessorFeaturePresent(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) != 0;
cpuinfo_isa.sme_f16f16 = IsProcessorFeaturePresent(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) != 0;

// TODO: There are no PF flags for these yet.
// - sme_i16i32
// - sme_bi32i32

cpuinfo_isa.bf16 = IsProcessorFeaturePresent(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) != 0;

// TODO: This is not available in the Windows SDK yet , so conservatively go with the lowest value (128 bits)
// https://developer.arm.com/documentation/101427/0102/Register-descriptions/Scalable-vector-extensions--SVE--registers/ZCR-EL1--SVE-Control-Register--EL1
cpuinfo_isa.svelen = cpuinfo_isa.sve ? 128 / 8 : 0; // This value is in bytes, see cpuinfo_get_max_arm_sve_length

// TODO : Fetch from feature registers when available
// cpuinfo_isa.smelen = 0;

// Assume that Dot Product support implies FP16
// arithmetics and RDM support. ARM manuals don't
// guarantee that, but it holds in practice.
cpuinfo_isa.rdm = dotprod;

/* Windows API reports all or nothing for cryptographic instructions. */
const bool crypto = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0;
Expand Down
62 changes: 62 additions & 0 deletions src/arm/windows/windows-arm-init.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,65 @@ struct woa_chip_info {
};

bool cpu_info_init_by_logical_sys_info(const struct woa_chip_info* chip_info, enum cpuinfo_vendor vendor);



#ifndef PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE
#define PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE (27)
#endif

#ifndef PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE
#define PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE (34)
#endif

#ifndef PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE
#define PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE (44)
#endif

#ifndef PF_ARM_SVE_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SVE_INSTRUCTIONS_AVAILABLE (46)
#endif

#ifndef PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE (47)
#endif

#ifndef PF_ARM_SME_BI32I32_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SME_BI32I32_INSTRUCTIONS_AVAILABLE (55)
#endif

#ifndef PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE
#define PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE (66)
#endif

#ifndef PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE
#define PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE (68)
#endif

#ifndef PF_ARM_SME_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SME_INSTRUCTIONS_AVAILABLE (70)
#endif

#ifndef PF_ARM_SME2_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SME2_INSTRUCTIONS_AVAILABLE (71)
#endif

#ifndef PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE (72)
#endif

#ifndef PF_ARM_SME2_2_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SME2_2_INSTRUCTIONS_AVAILABLE (73)
#endif

#ifndef PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE (83)
#endif

#ifndef PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE
#define PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE (84)
#endif

#ifndef PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE
#define PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE (67)
#endif
5 changes: 5 additions & 0 deletions tools/isa-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ int main(int argc, char** argv) {
printf("\tARM SVE 2: %s\n", cpuinfo_has_arm_sve2() ? "yes" : "no");
printf("\tARM SME: %s\n", cpuinfo_has_arm_sme() ? "yes" : "no");
printf("\tARM SME 2: %s\n", cpuinfo_has_arm_sme2() ? "yes" : "no");
printf("\tARM SME 2P1: %s\n", cpuinfo_has_arm_sme2p1() ? "yes" : "no");
printf("\tARM SME I16I32: %s\n", cpuinfo_has_arm_sme_i16i32() ? "yes" : "no");
printf("\tARM SME BI32I32: %s\n", cpuinfo_has_arm_sme_bi32i32() ? "yes" : "no");
printf("\tARM SME B16B16: %s\n", cpuinfo_has_arm_sme_b16b16() ? "yes" : "no");
printf("\tARM SME F16F16: %s\n", cpuinfo_has_arm_sme_f16f16() ? "yes" : "no");

printf("ARM SVE Capabilities:\n");
printf("\tSVE max length: %d\n", cpuinfo_get_max_arm_sve_length());
Expand Down