mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-23 21:15:14 +00:00
Kernel: Add and use accessors to read from Aarch64 CPU ID registers
Following registers accessors are updated and put in use: * ID_AA64ISAR0_EL1, Instruction Set Attribute Register 0 Accessors for following registers are added and put in use: * ID_AA64ISAR1_EL1, Instruction Set Attribute Register 1 * ID_AA64ISAR2_EL1, Instruction Set Attribute Register 2 * ID_AA64MMFR1_EL1, AArch64 Memory Model Feature Register 1 * ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2 * ID_AA64MMFR3_EL1, AArch64 Memory Model Feature Register 3 * ID_AA64MMFR4_EL1, AArch64 Memory Model Feature Register 4 * ID_AA64PFR0_EL1, AArch64 Processor Feature Register 0 * ID_AA64PFR1_EL1, AArch64 Processor Feature Register 1 * ID_AA64PFR2_EL1, AArch64 Processor Feature Register 2 * ID_AA64ZFR0_EL1, AArch64 SVE Feature ID register 0 * ID_AA64SMFR0_EL1, AArch64 SME Feature ID register 0 * ID_AA64DFR0_EL1, AArch64 Debug Feature Register 0 * ID_AA64DFR1_EL1, AArch64 Debug Feature Register 1 Additionally, there are few CPU features detected with * TCR_EL1, Translation Control Register but detection mechanism using it (for LPA/LPA2) is probably wrong as this is control register, not a id register, and needs further work. Finally, following registers are provided. Former one is already used, while latter is given for future use: * MIDR_EL1, Main ID Register * AIDR_EL1, Auxiliary ID Register
This commit is contained in:
parent
6979cf230e
commit
66c65f6e2c
Notes:
sideshowbarker
2024-07-19 16:58:32 +09:00
Author: https://github.com/konradekk Commit: https://github.com/SerenityOS/serenity/commit/66c65f6e2cd Pull-request: https://github.com/SerenityOS/serenity/pull/16781 Reviewed-by: https://github.com/ADKaster ✅ Reviewed-by: https://github.com/gmta
3 changed files with 861 additions and 7 deletions
|
@ -11,6 +11,457 @@ namespace Kernel {
|
|||
CPUFeature::Type detect_cpu_features()
|
||||
{
|
||||
auto features = CPUFeature::Type(0u);
|
||||
|
||||
auto instruction_set_attribute_register_0 = Aarch64::ID_AA64ISAR0_EL1::read();
|
||||
auto instruction_set_attribute_register_1 = Aarch64::ID_AA64ISAR1_EL1::read();
|
||||
auto instruction_set_attribute_register_2 = Aarch64::ID_AA64ISAR2_EL1::read();
|
||||
auto processor_feature_register_0 = Aarch64::ID_AA64PFR0_EL1::read();
|
||||
auto processor_feature_register_1 = Aarch64::ID_AA64PFR1_EL1::read();
|
||||
auto memory_model_feature_register_0 = Aarch64::ID_AA64MMFR0_EL1::read();
|
||||
auto memory_model_feature_register_1 = Aarch64::ID_AA64MMFR1_EL1::read();
|
||||
auto memory_model_feature_register_2 = Aarch64::ID_AA64MMFR2_EL1::read();
|
||||
auto memory_model_feature_register_3 = Aarch64::ID_AA64MMFR3_EL1::read();
|
||||
auto sme_feature_register_0 = Aarch64::ID_AA64SMFR0_EL1::read();
|
||||
auto sve_feature_register_0 = Aarch64::ID_AA64ZFR0_EL1::read();
|
||||
auto debug_feature_register_0 = Aarch64::ID_AA64DFR0_EL1::read();
|
||||
auto debug_feature_register_1 = Aarch64::ID_AA64DFR1_EL1::read();
|
||||
auto translation_control_register = Aarch64::TCR_EL1::read();
|
||||
|
||||
// positives
|
||||
if (instruction_set_attribute_register_0.AES == 0b0001)
|
||||
features |= CPUFeature::AES;
|
||||
if (instruction_set_attribute_register_0.AES == 0b0010)
|
||||
features |= CPUFeature::PMULL;
|
||||
if (instruction_set_attribute_register_0.SHA1 == 0b0001)
|
||||
features |= CPUFeature::SHA1;
|
||||
if (instruction_set_attribute_register_0.SHA2 == 0b0001)
|
||||
features |= CPUFeature::SHA256;
|
||||
if (instruction_set_attribute_register_0.SHA2 == 0b0010)
|
||||
features |= CPUFeature::SHA512;
|
||||
if (instruction_set_attribute_register_0.CRC32 == 0b0001)
|
||||
features |= CPUFeature::CRC32;
|
||||
if (instruction_set_attribute_register_0.Atomic == 0b0010)
|
||||
features |= CPUFeature::LSE;
|
||||
if (instruction_set_attribute_register_0.Atomic == 0b0011)
|
||||
features |= CPUFeature::LSE128;
|
||||
if (instruction_set_attribute_register_0.TME == 0b0001)
|
||||
// TODO: confirm that—missing in the spec
|
||||
features |= CPUFeature::TME;
|
||||
if (instruction_set_attribute_register_0.RDM == 0b0001)
|
||||
features |= CPUFeature::RDM;
|
||||
if (instruction_set_attribute_register_0.SHA3 == 0b0001)
|
||||
features |= CPUFeature::SHA3;
|
||||
if (instruction_set_attribute_register_0.SM3 == 0b0001)
|
||||
features |= CPUFeature::SM3;
|
||||
if (instruction_set_attribute_register_0.SM4 == 0b0001)
|
||||
// TODO: confirm that—unclear spec
|
||||
features |= CPUFeature::SM4;
|
||||
if (instruction_set_attribute_register_0.DP == 0b0001)
|
||||
features |= CPUFeature::DotProd;
|
||||
if (instruction_set_attribute_register_0.FHM == 0b0001)
|
||||
features |= CPUFeature::FHM;
|
||||
if (instruction_set_attribute_register_0.TS == 0b0001)
|
||||
features |= CPUFeature::FlagM;
|
||||
if (instruction_set_attribute_register_0.TS == 0b0010)
|
||||
features |= CPUFeature::FlagM2;
|
||||
if (instruction_set_attribute_register_0.TLB == 0b0001 || instruction_set_attribute_register_0.TLB == 0b0010)
|
||||
features |= CPUFeature::TLBIOS;
|
||||
if (instruction_set_attribute_register_0.TLB == 0b0010)
|
||||
features |= CPUFeature::TLBIRANGE;
|
||||
if (instruction_set_attribute_register_0.RNDR == 0b0001)
|
||||
features |= CPUFeature::RNG;
|
||||
if (instruction_set_attribute_register_1.DPB == 0b0001)
|
||||
features |= CPUFeature::DPB;
|
||||
if (instruction_set_attribute_register_1.DPB == 0b0010)
|
||||
features |= CPUFeature::DPB2;
|
||||
if (instruction_set_attribute_register_1.API == 0b0100 && instruction_set_attribute_register_1.APA == 0b0100 && instruction_set_attribute_register_2.APA3 == 0b0100)
|
||||
features |= CPUFeature::FPAC;
|
||||
if (instruction_set_attribute_register_1.API == 0b0101 && instruction_set_attribute_register_1.APA == 0b0101 && instruction_set_attribute_register_2.APA3 == 0b0101)
|
||||
features |= CPUFeature::FPACCOMBINE;
|
||||
if (instruction_set_attribute_register_1.API == 0b0001 && instruction_set_attribute_register_1.APA == 0b0001 && instruction_set_attribute_register_2.APA3 == 0b0001)
|
||||
features |= CPUFeature::PAuth;
|
||||
if (instruction_set_attribute_register_1.API == 0b0011 && instruction_set_attribute_register_1.APA == 0b0011 && instruction_set_attribute_register_2.APA3 == 0b0011)
|
||||
features |= CPUFeature::PAuth2;
|
||||
if (instruction_set_attribute_register_1.JSCVT == 0b0001)
|
||||
features |= CPUFeature::JSCVT;
|
||||
if (instruction_set_attribute_register_1.FCMA == 0b0001)
|
||||
features |= CPUFeature::FCMA;
|
||||
if (instruction_set_attribute_register_1.LRCPC == 0b0001)
|
||||
features |= CPUFeature::LRCPC;
|
||||
if (instruction_set_attribute_register_1.LRCPC == 0b0010)
|
||||
features |= CPUFeature::LRCPC2;
|
||||
if (instruction_set_attribute_register_1.LRCPC == 0b0011)
|
||||
features |= CPUFeature::LRCPC3;
|
||||
if (instruction_set_attribute_register_1.GPA == 0b0001 && instruction_set_attribute_register_1.APA != 0b0000)
|
||||
features |= CPUFeature::PACQARMA5;
|
||||
if (instruction_set_attribute_register_1.GPI == 0b0001 && instruction_set_attribute_register_1.API != 0b0000)
|
||||
features |= CPUFeature::PACIMP;
|
||||
if (instruction_set_attribute_register_1.FRINTTS == 0b0001)
|
||||
features |= CPUFeature::FRINTTS;
|
||||
if (instruction_set_attribute_register_1.SB == 0b0001)
|
||||
features |= CPUFeature::SB;
|
||||
if (instruction_set_attribute_register_1.SPECRES == 0b0001)
|
||||
features |= CPUFeature::SPECRES;
|
||||
if (instruction_set_attribute_register_1.SPECRES == 0b0010)
|
||||
features |= CPUFeature::SPECRES2;
|
||||
if (instruction_set_attribute_register_1.BF16 == 0b0001)
|
||||
features |= CPUFeature::BF16;
|
||||
if (instruction_set_attribute_register_1.BF16 == 0b0010)
|
||||
features |= CPUFeature::EBF16;
|
||||
if (instruction_set_attribute_register_1.DGH == 0b0001)
|
||||
features |= CPUFeature::DGH;
|
||||
if (instruction_set_attribute_register_1.I8MM == 0b0001)
|
||||
features |= CPUFeature::I8MM;
|
||||
if (instruction_set_attribute_register_1.XS == 0b0001)
|
||||
features |= CPUFeature::XS;
|
||||
if (instruction_set_attribute_register_1.LS64 == 0b0001)
|
||||
features |= CPUFeature::LS64;
|
||||
if (instruction_set_attribute_register_1.LS64 == 0b0010)
|
||||
features |= CPUFeature::LS64_V;
|
||||
if (instruction_set_attribute_register_1.LS64 == 0b0011)
|
||||
features |= CPUFeature::LS64_ACCDATA;
|
||||
if (instruction_set_attribute_register_2.WFxT == 0b0010)
|
||||
features |= CPUFeature::WFxT;
|
||||
if (instruction_set_attribute_register_2.RPRES == 0b0001)
|
||||
features |= CPUFeature::RPRES;
|
||||
if (instruction_set_attribute_register_2.GPA3 == 0b0001 && instruction_set_attribute_register_2.APA3 == 0b0000)
|
||||
features |= CPUFeature::PACQARMA3;
|
||||
if (instruction_set_attribute_register_2.MOPS == 0b0001)
|
||||
features |= CPUFeature::MOPS;
|
||||
if (instruction_set_attribute_register_2.BC == 0b0001)
|
||||
features |= CPUFeature::HBC;
|
||||
if (instruction_set_attribute_register_2.PAC_frac == 0b0001)
|
||||
features |= CPUFeature::CONSTPACFIELD;
|
||||
if (instruction_set_attribute_register_2.CLRBHB == 0b0001)
|
||||
features |= CPUFeature::CLRBHB;
|
||||
if (instruction_set_attribute_register_2.SYSREG_128 == 0b0001)
|
||||
features |= CPUFeature::SYSREG128;
|
||||
if (instruction_set_attribute_register_2.SYSINSTR_128 == 0b0001)
|
||||
features |= CPUFeature::SYSINSTR128;
|
||||
if (instruction_set_attribute_register_2.PRFMSLC == 0b0001)
|
||||
features |= CPUFeature::PRFMSLC;
|
||||
if (instruction_set_attribute_register_2.RPRFM == 0b0001)
|
||||
features |= CPUFeature::RPRFM;
|
||||
if (instruction_set_attribute_register_2.CSSC == 0b0001)
|
||||
features |= CPUFeature::CSSC;
|
||||
if (processor_feature_register_0.FP == 0b0001)
|
||||
features |= CPUFeature::FP16;
|
||||
if (processor_feature_register_0.AdvSIMD != 0b0000)
|
||||
features |= CPUFeature::AdvSIMD; // TODO/FIXME: not explicit?
|
||||
if (processor_feature_register_0.AdvSIMD == 0b0001)
|
||||
features |= CPUFeature::FP16;
|
||||
// TODO: GIC
|
||||
if (processor_feature_register_0.RAS == 0b0001)
|
||||
features |= CPUFeature::RAS;
|
||||
if (processor_feature_register_0.RAS == 0b0010)
|
||||
features |= CPUFeature::DoubleFault;
|
||||
if (processor_feature_register_0.RAS == 0b0010)
|
||||
features |= CPUFeature::RASv1p1;
|
||||
if (processor_feature_register_0.RAS == 0b0001 && processor_feature_register_1.RAS_frac == 0b0001)
|
||||
features |= CPUFeature::RASv1p1;
|
||||
if (processor_feature_register_0.RAS == 0b0011)
|
||||
features |= CPUFeature::RASv2;
|
||||
if (processor_feature_register_0.SVE == 0b0001)
|
||||
features |= CPUFeature::SVE;
|
||||
if (processor_feature_register_0.SEL2 == 0b0001)
|
||||
features |= CPUFeature::SEL2;
|
||||
// TODO: MPAM
|
||||
if (processor_feature_register_0.AMU == 0b0001)
|
||||
features |= CPUFeature::AMUv1;
|
||||
if (processor_feature_register_0.AMU == 0b0010)
|
||||
features |= CPUFeature::AMUv1p1;
|
||||
if (processor_feature_register_0.DIT == 0b0001)
|
||||
features |= CPUFeature::DIT;
|
||||
if (processor_feature_register_0.RME == 0b0001)
|
||||
features |= CPUFeature::RME;
|
||||
if (processor_feature_register_0.CSV2 == 0b0001)
|
||||
features |= CPUFeature::CSV2;
|
||||
if (processor_feature_register_0.CSV2 == 0b0010)
|
||||
features |= CPUFeature::CSV2_2;
|
||||
if (processor_feature_register_0.CSV2 == 0b0011)
|
||||
features |= CPUFeature::CSV2_3;
|
||||
if (processor_feature_register_0.CSV3 == 0b0001)
|
||||
features |= CPUFeature::CSV3;
|
||||
if (processor_feature_register_1.BT == 0b0001)
|
||||
features |= CPUFeature::BTI;
|
||||
if (processor_feature_register_1.SSBS == 0b0001)
|
||||
features |= CPUFeature::SSBS;
|
||||
if (processor_feature_register_1.SSBS == 0b0010)
|
||||
features |= CPUFeature::SSBS2;
|
||||
if (processor_feature_register_1.MTE == 0b0001)
|
||||
features |= CPUFeature::MTE;
|
||||
if (processor_feature_register_1.MTE == 0b0010)
|
||||
features |= CPUFeature::MTE2;
|
||||
if (processor_feature_register_1.MTE == 0b0011)
|
||||
features |= CPUFeature::MTE3;
|
||||
if (processor_feature_register_1.MTE >= 0b0010 && processor_feature_register_1.MTEX == 0b0001) {
|
||||
features |= CPUFeature::MTE4;
|
||||
features |= CPUFeature::MTE_CANONICAL_TAGS; // XXX: not really explicit in the spec
|
||||
features |= CPUFeature::MTE_NO_ADDRESS_TAGS; // XXX: not really explicit in the spec
|
||||
}
|
||||
if (processor_feature_register_1.MTE >= 0b0011 && processor_feature_register_1.MTE_frac == 0b0000)
|
||||
features |= CPUFeature::MTE_ASYM_FAULT; // XXX: not really explicit in the spec
|
||||
if (processor_feature_register_1.SME == 0b0010)
|
||||
features |= CPUFeature::SME2;
|
||||
if (processor_feature_register_1.RNDR_trap == 0b0001)
|
||||
features |= CPUFeature::RNG_TRAP;
|
||||
if (processor_feature_register_1.CSV2_frac == 0b0001)
|
||||
features |= CPUFeature::CSV2_1p1;
|
||||
if (processor_feature_register_1.CSV2_frac == 0b0010)
|
||||
features |= CPUFeature::CSV2_1p2;
|
||||
if (processor_feature_register_1.NMI == 0b0001)
|
||||
features |= CPUFeature::NMI;
|
||||
if (processor_feature_register_1.GCS == 0b0001)
|
||||
features |= CPUFeature::GCS;
|
||||
if (processor_feature_register_1.THE == 0b0001)
|
||||
features |= CPUFeature::THE;
|
||||
if (processor_feature_register_1.DF2 == 0b0001)
|
||||
features |= CPUFeature::DoubleFault2;
|
||||
if (processor_feature_register_1.PFAR == 0b0001)
|
||||
features |= CPUFeature::PFAR;
|
||||
if (memory_model_feature_register_0.PARange == 0b0110) {
|
||||
features |= translation_control_register.DS == 0b1 ? CPUFeature::LPA2 : CPUFeature::LPA;
|
||||
}
|
||||
if (memory_model_feature_register_0.PARange == 0b0111)
|
||||
features |= CPUFeature::D128;
|
||||
if (memory_model_feature_register_0.ExS == 0b0001)
|
||||
features |= CPUFeature::ExS;
|
||||
if (memory_model_feature_register_0.FGT == 0b0001)
|
||||
features |= CPUFeature::FGT;
|
||||
if (memory_model_feature_register_0.FGT == 0b0010)
|
||||
features |= CPUFeature::FGT2;
|
||||
if (memory_model_feature_register_0.ECV == 0b0001 || memory_model_feature_register_0.ECV == 0b0010)
|
||||
features |= CPUFeature::ECV;
|
||||
if (memory_model_feature_register_1.HAFDBS == 0b0001 || memory_model_feature_register_1.HAFDBS == 0b0010)
|
||||
features |= CPUFeature::HAFDBS;
|
||||
if (memory_model_feature_register_1.VMIDBits == 0b0010)
|
||||
features |= CPUFeature::VMID16;
|
||||
if (memory_model_feature_register_1.VH == 0b0011)
|
||||
features |= CPUFeature::HAFT;
|
||||
if (memory_model_feature_register_1.HPDS == 0b0010)
|
||||
features |= CPUFeature::HPDS2;
|
||||
if (memory_model_feature_register_1.LO == 0b0001)
|
||||
features |= CPUFeature::LOR;
|
||||
if (memory_model_feature_register_1.PAN == 0b0001)
|
||||
features |= CPUFeature::PAN;
|
||||
if (memory_model_feature_register_1.PAN == 0b0010)
|
||||
features |= CPUFeature::PAN2;
|
||||
if (memory_model_feature_register_1.PAN == 0b0011)
|
||||
features |= CPUFeature::PAN3;
|
||||
if (memory_model_feature_register_1.XNX == 0b0001)
|
||||
features |= CPUFeature::XNX;
|
||||
if (memory_model_feature_register_1.TWED == 0b0001)
|
||||
features |= CPUFeature::TWED;
|
||||
if (memory_model_feature_register_1.ETS == 0b0001)
|
||||
features |= CPUFeature::ETS;
|
||||
if (memory_model_feature_register_1.HCX == 0b0001)
|
||||
features |= CPUFeature::HCX;
|
||||
if (memory_model_feature_register_1.AFP == 0b0001)
|
||||
features |= CPUFeature::AFP;
|
||||
if (memory_model_feature_register_1.nTLBPA == 0b0001)
|
||||
features |= CPUFeature::nTLBPA;
|
||||
if (memory_model_feature_register_1.TIDCP1 == 0b0001)
|
||||
features |= CPUFeature::TIDCP1;
|
||||
if (memory_model_feature_register_1.CMOW == 0b0001)
|
||||
features |= CPUFeature::CMOW;
|
||||
if (memory_model_feature_register_1.ECBHB == 0b0001)
|
||||
features |= CPUFeature::ECBHB;
|
||||
if (memory_model_feature_register_2.CnP == 0b0001)
|
||||
features |= CPUFeature::TTCNP;
|
||||
if (memory_model_feature_register_2.UAO == 0b0001)
|
||||
features |= CPUFeature::UAO;
|
||||
if (memory_model_feature_register_2.LSM == 0b0001)
|
||||
features |= CPUFeature::LSMAOC;
|
||||
if (memory_model_feature_register_2.IESB == 0b0001)
|
||||
features |= CPUFeature::IESB;
|
||||
if (memory_model_feature_register_2.VARange == 0b0001)
|
||||
features |= CPUFeature::LVA;
|
||||
if (memory_model_feature_register_2.CCIDX == 0b0001)
|
||||
features |= CPUFeature::CCIDX;
|
||||
if (memory_model_feature_register_2.NV == 0b0001)
|
||||
features |= CPUFeature::NV;
|
||||
if (memory_model_feature_register_2.NV == 0b0010)
|
||||
features |= CPUFeature::NV2;
|
||||
if (memory_model_feature_register_2.ST == 0b0001)
|
||||
features |= CPUFeature::TTST;
|
||||
if (memory_model_feature_register_2.AT == 0b0001)
|
||||
features |= CPUFeature::LSE2;
|
||||
if (memory_model_feature_register_2.IDS == 0b0001)
|
||||
features |= CPUFeature::IDST;
|
||||
if (memory_model_feature_register_2.FWB == 0b0001)
|
||||
features |= CPUFeature::S2FWB;
|
||||
if (memory_model_feature_register_2.TTL == 0b0001)
|
||||
features |= CPUFeature::TTL;
|
||||
if (memory_model_feature_register_2.BBM == 0b0000 || memory_model_feature_register_2.BBM == 0b0001 || memory_model_feature_register_2.BBM == 0b0010)
|
||||
features |= CPUFeature::BBM;
|
||||
if (memory_model_feature_register_2.EVT == 0b0001 || memory_model_feature_register_2.EVT == 0b0010)
|
||||
features |= CPUFeature::EVT;
|
||||
if (memory_model_feature_register_2.E0PD == 0b0001) {
|
||||
features |= CPUFeature::E0PD;
|
||||
features |= CPUFeature::CSV3;
|
||||
}
|
||||
if (memory_model_feature_register_3.ADERR == 0b0010 && memory_model_feature_register_3.SDERR == 0b0010)
|
||||
features |= CPUFeature::ADERR;
|
||||
if (memory_model_feature_register_3.ANERR == 0b0010 && memory_model_feature_register_3.SNERR == 0b0010)
|
||||
features |= CPUFeature::ANERR;
|
||||
if (memory_model_feature_register_3.AIE == 0b0001)
|
||||
features |= CPUFeature::AIE;
|
||||
if (memory_model_feature_register_3.MEC == 0b0001)
|
||||
features |= CPUFeature::MEC;
|
||||
if (memory_model_feature_register_3.S1PIE == 0b0001)
|
||||
features |= CPUFeature::S1PIE;
|
||||
if (memory_model_feature_register_3.S2PIE == 0b0001)
|
||||
features |= CPUFeature::S2PIE;
|
||||
if (memory_model_feature_register_3.S1POE == 0b0001)
|
||||
features |= CPUFeature::S1POE;
|
||||
if (memory_model_feature_register_3.S2POE == 0b0001)
|
||||
features |= CPUFeature::S2POE;
|
||||
if (memory_model_feature_register_3.AIE == 0b0001)
|
||||
features |= CPUFeature::AIE;
|
||||
if (memory_model_feature_register_3.MEC == 0b0001)
|
||||
features |= CPUFeature::MEC;
|
||||
if (memory_model_feature_register_3.ANERR == 0b0010 && memory_model_feature_register_3.SNERR == 0b0010)
|
||||
features |= CPUFeature::ANERR;
|
||||
if (memory_model_feature_register_3.ADERR == 0b0001 && memory_model_feature_register_3.SDERR == 0b0000 && memory_model_feature_register_3.ANERR == 0b0010 && memory_model_feature_register_3.SNERR == 0b0010 && processor_feature_register_0.RAS == 0b0011)
|
||||
features |= CPUFeature::RASv2;
|
||||
if (memory_model_feature_register_3.ADERR == 0b0010 && memory_model_feature_register_3.SDERR == 0b0010)
|
||||
features |= CPUFeature::ADERR;
|
||||
if (memory_model_feature_register_3.ADERR == 0b0010 && memory_model_feature_register_3.SDERR == 0b0010)
|
||||
features |= CPUFeature::ADERR;
|
||||
if (translation_control_register.DS == 0b1) {
|
||||
features |= CPUFeature::LVA;
|
||||
}
|
||||
if (sme_feature_register_0.F16F16 == 0b1)
|
||||
features |= CPUFeature::SME_F16F16;
|
||||
if (sme_feature_register_0.F64F64 == 0b1)
|
||||
features |= CPUFeature::SME_F64F64;
|
||||
if (sme_feature_register_0.I16I64 == 0b1111)
|
||||
features |= CPUFeature::SME_I16I64;
|
||||
if (processor_feature_register_1.SME != 0b0000) {
|
||||
if (sme_feature_register_0.SMEver == 0b0000)
|
||||
features |= CPUFeature::SME;
|
||||
if (sme_feature_register_0.SMEver == 0b0001)
|
||||
features |= CPUFeature::SME2;
|
||||
if (sme_feature_register_0.SMEver == 0b0010)
|
||||
features |= CPUFeature::SME2p1;
|
||||
if (sme_feature_register_0.FA64 == 0b1)
|
||||
features |= CPUFeature::SME_FA64; // sve_feature_register_0.I8MM/SM4/SHA3/BitPerm/AES
|
||||
}
|
||||
if (sve_feature_register_0.SVEver == 0b0001 && processor_feature_register_1.SME == 0b0001)
|
||||
features |= CPUFeature::SME; // streaming sve mode only!
|
||||
if (sve_feature_register_0.SVEver == 0b0001)
|
||||
features |= CPUFeature::SVE2; // non-streaming sve mode only!
|
||||
if (sve_feature_register_0.SVEver == 0b0010)
|
||||
features |= CPUFeature::SVE2p1; // non-streaming sve mode only!
|
||||
if (sve_feature_register_0.AES == 0b0001)
|
||||
features |= CPUFeature::SVE_AES;
|
||||
if (sve_feature_register_0.AES == 0b0010)
|
||||
features |= CPUFeature::SVE_PMULL128;
|
||||
if (sve_feature_register_0.BitPerm == 0b0001)
|
||||
features |= CPUFeature::SVE_BitPerm;
|
||||
if (sve_feature_register_0.BF16 == 0b0001)
|
||||
features |= CPUFeature::BF16;
|
||||
if (sve_feature_register_0.BF16 == 0b0010)
|
||||
features |= CPUFeature::EBF16;
|
||||
if (sve_feature_register_0.B16B16 == 0b0001 && sme_feature_register_0.B16B16 == 0b1)
|
||||
features |= CPUFeature::B16B16;
|
||||
if (sve_feature_register_0.SHA3 == 0b0001)
|
||||
features |= CPUFeature::SVE_SHA3;
|
||||
if (sve_feature_register_0.SM4 == 0b0001)
|
||||
features |= CPUFeature::SVE_SM4;
|
||||
if (sve_feature_register_0.I8MM == 0b0001)
|
||||
features |= CPUFeature::I8MM;
|
||||
if (sve_feature_register_0.F32MM == 0b0001)
|
||||
features |= CPUFeature::F32MM;
|
||||
if (sve_feature_register_0.F64MM == 0b0001)
|
||||
features |= CPUFeature::F64MM;
|
||||
if (debug_feature_register_0.DebugVer == 0b1000)
|
||||
features |= CPUFeature::Debugv8p2;
|
||||
if (debug_feature_register_0.DebugVer == 0b1001)
|
||||
features |= CPUFeature::Debugv8p4;
|
||||
if (debug_feature_register_0.DebugVer == 0b1010)
|
||||
features |= CPUFeature::Debugv8p8;
|
||||
if (debug_feature_register_0.DebugVer == 0b0111 && memory_model_feature_register_1.VH == 0b0001)
|
||||
features |= CPUFeature::VHE;
|
||||
if (debug_feature_register_0.DebugVer == 0b1101)
|
||||
features |= CPUFeature::Debugv8p9;
|
||||
if (debug_feature_register_0.PMUVer == 0b0001)
|
||||
features |= CPUFeature::PMUv3;
|
||||
if (debug_feature_register_0.PMUVer == 0b0100)
|
||||
features |= CPUFeature::PMUv3p1;
|
||||
if (debug_feature_register_0.PMUVer == 0b0101)
|
||||
features |= CPUFeature::PMUv3p4;
|
||||
if (debug_feature_register_0.PMUVer == 0b0110)
|
||||
features |= CPUFeature::PMUv3p5;
|
||||
if (debug_feature_register_0.PMUVer == 0b0111)
|
||||
features |= CPUFeature::PMUv3p7;
|
||||
if (debug_feature_register_0.PMUVer == 0b1000)
|
||||
features |= CPUFeature::PMUv3p8;
|
||||
if (debug_feature_register_0.PMUVer == 0b1001)
|
||||
features |= CPUFeature::PMUv3p9;
|
||||
if (debug_feature_register_0.PMSS == 0b0001)
|
||||
features |= CPUFeature::PMUv3_SS;
|
||||
if (debug_feature_register_0.SEBEP == 0b0001)
|
||||
features |= CPUFeature::SEBEP;
|
||||
if (debug_feature_register_0.PMSVer == 0b0001)
|
||||
features |= CPUFeature::SPE;
|
||||
if (debug_feature_register_0.PMSVer == 0b0010)
|
||||
features |= CPUFeature::SPEv1p1;
|
||||
if (debug_feature_register_0.PMSVer == 0b0011)
|
||||
features |= CPUFeature::SPEv1p2;
|
||||
if (debug_feature_register_0.PMSVer == 0b0100)
|
||||
features |= CPUFeature::SPEv1p3;
|
||||
if (debug_feature_register_0.PMSVer == 0b0101)
|
||||
features |= CPUFeature::SPEv1p4;
|
||||
if (debug_feature_register_0.PMSVer == 0b0011)
|
||||
features |= CPUFeature::SPEv1p2;
|
||||
if (debug_feature_register_0.DoubleLock == 0b0000)
|
||||
features |= CPUFeature::DoubleLock;
|
||||
if (debug_feature_register_0.TraceFilt == 0b0001)
|
||||
features |= CPUFeature::TRF;
|
||||
if (debug_feature_register_0.TraceBuffer == 0b0001)
|
||||
features |= CPUFeature::TRBE;
|
||||
if (debug_feature_register_0.MTPMU == 0b0001)
|
||||
features |= CPUFeature::MTPMU; // TODO: has additional notes
|
||||
if (debug_feature_register_0.BRBE == 0b0001)
|
||||
features |= CPUFeature::BRBE;
|
||||
if (debug_feature_register_0.BRBE == 0b0010)
|
||||
features |= CPUFeature::BRBEv1p1;
|
||||
if (debug_feature_register_0.ExtTrcBuff == 0b0001 && features.has_flag(CPUFeature::TRBE)) // XXX: order-dependent!
|
||||
features |= CPUFeature::TRBE_EXT;
|
||||
if (debug_feature_register_0.HPMN0 == 0b0001)
|
||||
features |= CPUFeature::HPMN0;
|
||||
if (debug_feature_register_1.ABLE == 0b0001)
|
||||
features |= CPUFeature::ABLE;
|
||||
if (debug_feature_register_1.EBEP == 0b0001)
|
||||
features |= CPUFeature::EBEP;
|
||||
if (debug_feature_register_1.ITE == 0b0001)
|
||||
features |= CPUFeature::ITE;
|
||||
if (debug_feature_register_1.PMICNTR == 0b0001)
|
||||
features |= CPUFeature::PMUv3_ICNTR;
|
||||
if (debug_feature_register_1.SPMU == 0b0001)
|
||||
features |= CPUFeature::SPMU;
|
||||
if (debug_feature_register_1.ABLE == 0b0001)
|
||||
features |= CPUFeature::ABLE;
|
||||
if (debug_feature_register_1.EBEP == 0b0001)
|
||||
features |= CPUFeature::EBEP;
|
||||
if (debug_feature_register_1.ITE == 0b0001)
|
||||
features |= CPUFeature::ITE;
|
||||
if (debug_feature_register_1.PMICNTR == 0b0001)
|
||||
features |= CPUFeature::PMUv3_ICNTR;
|
||||
if (debug_feature_register_1.SPMU == 0b0001)
|
||||
features |= CPUFeature::SPMU;
|
||||
|
||||
// negatives
|
||||
if (sme_feature_register_0.B16B16 == 0b0000)
|
||||
features &= ~(CPUFeature::SVE2p1 | CPUFeature::SME2p1);
|
||||
if (sme_feature_register_0.F16F16 == 0b0)
|
||||
features &= ~CPUFeature::SME2p1;
|
||||
if (sve_feature_register_0.B16B16 == 0b0000)
|
||||
features &= ~(CPUFeature::SVE2p1 | CPUFeature::SME2p1);
|
||||
if (sve_feature_register_0.B16B16 == 0b0001 && sme_feature_register_0.B16B16 == 0b1)
|
||||
features |= CPUFeature::B16B16;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ AK_MAKE_ARBITRARY_SIZED_ENUM(CPUFeature, u256,
|
|||
TRBE = CPUFeature(1u) << 239u, // Trace Buffer Extension
|
||||
SME = CPUFeature(1u) << 240u, // Scalable Matrix Extension
|
||||
|
||||
__End = CPUFeature(1u) << 255u);
|
||||
__End = CPUFeature(1u) << 255u); // XXX — SENTINEL VALUE — XXX
|
||||
|
||||
CPUFeature::Type detect_cpu_features();
|
||||
StringView cpu_feature_to_name(CPUFeature::Type const&);
|
||||
|
|
|
@ -46,6 +46,154 @@ struct alignas(u64) ID_AA64ISAR0_EL1 {
|
|||
};
|
||||
static_assert(sizeof(ID_AA64ISAR0_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64ISAR1-EL1--AArch64-Instruction-Set-Attribute-Register-1
|
||||
// ID_AA64ISAR1_EL1, AArch64 Instruction Set Attribute Register 1
|
||||
struct alignas(u64) ID_AA64ISAR1_EL1 {
|
||||
int DPB : 4;
|
||||
int APA : 4;
|
||||
int API : 4;
|
||||
int JSCVT : 4;
|
||||
int FCMA : 4;
|
||||
int LRCPC : 4;
|
||||
int GPA : 4;
|
||||
int GPI : 4;
|
||||
int FRINTTS : 4;
|
||||
int SB : 4;
|
||||
int SPECRES : 4;
|
||||
int BF16 : 4;
|
||||
int DGH : 4;
|
||||
int I8MM : 4;
|
||||
int XS : 4;
|
||||
int LS64 : 4;
|
||||
|
||||
static inline ID_AA64ISAR1_EL1 read()
|
||||
{
|
||||
ID_AA64ISAR1_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], ID_AA64ISAR1_EL1"
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64ISAR1_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64ISAR2-EL1--AArch64-Instruction-Set-Attribute-Register-2
|
||||
// ID_AA64ISAR2_EL1, AArch64 Instruction Set Attribute Register 2
|
||||
struct alignas(u64) ID_AA64ISAR2_EL1 {
|
||||
int WFxT : 4;
|
||||
int RPRES : 4;
|
||||
int GPA3 : 4;
|
||||
int APA3 : 4;
|
||||
int MOPS : 4;
|
||||
int BC : 4;
|
||||
int PAC_frac : 4;
|
||||
int CLRBHB : 4;
|
||||
int SYSREG_128 : 4;
|
||||
int SYSINSTR_128 : 4;
|
||||
int PRFMSLC : 4;
|
||||
int : 4;
|
||||
int RPRFM : 4;
|
||||
int CSSC : 4;
|
||||
int : 8;
|
||||
|
||||
static inline ID_AA64ISAR2_EL1 read()
|
||||
{
|
||||
ID_AA64ISAR2_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], ID_AA64ISAR2_EL1"
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64ISAR2_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64PFR0-EL1--AArch64-Processor-Feature-Register-0
|
||||
// ID_AA64PFR0_EL1, AArch64 Processor Feature Register 0
|
||||
struct alignas(u64) ID_AA64PFR0_EL1 {
|
||||
int EL0 : 4;
|
||||
int EL1 : 4;
|
||||
int EL2 : 4;
|
||||
int EL3 : 4;
|
||||
int FP : 4;
|
||||
int AdvSIMD : 4;
|
||||
int GIC : 4;
|
||||
int RAS : 4;
|
||||
int SVE : 4;
|
||||
int SEL2 : 4;
|
||||
int MPAM : 4;
|
||||
int AMU : 4;
|
||||
int DIT : 4;
|
||||
int RME : 4;
|
||||
int CSV2 : 4;
|
||||
int CSV3 : 4;
|
||||
|
||||
static inline ID_AA64PFR0_EL1 read()
|
||||
{
|
||||
ID_AA64PFR0_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], ID_AA64PFR0_EL1"
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64PFR0_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64PFR1-EL1--AArch64-Processor-Feature-Register-1
|
||||
// ID_AA64PFR1_EL1, AArch64 Processor Feature Register 1
|
||||
struct alignas(u64) ID_AA64PFR1_EL1 {
|
||||
int BT : 4;
|
||||
int SSBS : 4;
|
||||
int MTE : 4;
|
||||
int RAS_frac : 4;
|
||||
int MPAM_frac : 4;
|
||||
int : 4;
|
||||
int SME : 4;
|
||||
int RNDR_trap : 4;
|
||||
int CSV2_frac : 4;
|
||||
int NMI : 4;
|
||||
int MTE_frac : 4;
|
||||
int GCS : 4;
|
||||
int THE : 4;
|
||||
int MTEX : 4;
|
||||
int DF2 : 4;
|
||||
int PFAR : 4;
|
||||
|
||||
static inline ID_AA64PFR1_EL1 read()
|
||||
{
|
||||
ID_AA64PFR1_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], ID_AA64PFR1_EL1"
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64PFR1_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64PFR2-EL1--AArch64-Processor-Feature-Register-2
|
||||
// ID_AA64PFR2_EL1, AArch64 Processor Feature Register 2
|
||||
struct alignas(u64) ID_AA64PFR2_EL1 {
|
||||
int MTEPERM : 4;
|
||||
int MTESTOREONLY : 4;
|
||||
int MTEFAR : 4;
|
||||
int : 20;
|
||||
int : 32;
|
||||
|
||||
static inline ID_AA64PFR2_EL1 read()
|
||||
{
|
||||
ID_AA64PFR2_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], s3_0_c0_c4_2" // encoded ID_AA64PFR2_EL1 register
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64PFR2_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0595/2021-12/AArch64-Registers/MPIDR-EL1--Multiprocessor-Affinity-Register?lang=en
|
||||
// MPIDR_EL1, Multiprocessor Affinity Register
|
||||
struct alignas(u64) MPIDR_EL1 {
|
||||
|
@ -71,8 +219,8 @@ struct alignas(u64) MPIDR_EL1 {
|
|||
};
|
||||
static_assert(sizeof(MPIDR_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/ID-AA64MMFR0-EL1--AArch64-Memory-Model-Feature-Register-0
|
||||
// Memory Model Feature Register 0
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64MMFR0-EL1--AArch64-Memory-Model-Feature-Register-0
|
||||
// ID_AA64MMFR0_EL1, AArch64 Memory Model Feature Register 0
|
||||
struct alignas(u64) ID_AA64MMFR0_EL1 {
|
||||
int PARange : 4;
|
||||
int ASIDBits : 4;
|
||||
|
@ -86,7 +234,7 @@ struct alignas(u64) ID_AA64MMFR0_EL1 {
|
|||
int TGran64_2 : 4;
|
||||
int TGran4_2 : 4;
|
||||
int ExS : 4;
|
||||
int RES0 : 8;
|
||||
int : 8;
|
||||
int FGT : 4;
|
||||
int ECV : 4;
|
||||
|
||||
|
@ -102,6 +250,244 @@ struct alignas(u64) ID_AA64MMFR0_EL1 {
|
|||
};
|
||||
static_assert(sizeof(ID_AA64MMFR0_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64MMFR1-EL1--AArch64-Memory-Model-Feature-Register-1
|
||||
// ID_AA64MMFR1_EL1, AArch64 Memory Model Feature Register 1
|
||||
struct alignas(u64) ID_AA64MMFR1_EL1 {
|
||||
int HAFDBS : 4;
|
||||
int VMIDBits : 4;
|
||||
int VH : 4;
|
||||
int HPDS : 4;
|
||||
int LO : 4;
|
||||
int PAN : 4;
|
||||
int SpecSEI : 4;
|
||||
int XNX : 4;
|
||||
int TWED : 4;
|
||||
int ETS : 4;
|
||||
int HCX : 4;
|
||||
int AFP : 4;
|
||||
int nTLBPA : 4;
|
||||
int TIDCP1 : 4;
|
||||
int CMOW : 4;
|
||||
int ECBHB : 4;
|
||||
|
||||
static inline ID_AA64MMFR1_EL1 read()
|
||||
{
|
||||
ID_AA64MMFR1_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], ID_AA64MMFR1_EL1"
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64MMFR1_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64MMFR2-EL1--AArch64-Memory-Model-Feature-Register-2
|
||||
// ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2
|
||||
struct alignas(u64) ID_AA64MMFR2_EL1 {
|
||||
int CnP : 4;
|
||||
int UAO : 4;
|
||||
int LSM : 4;
|
||||
int IESB : 4;
|
||||
int VARange : 4;
|
||||
int CCIDX : 4;
|
||||
int NV : 4;
|
||||
int ST : 4;
|
||||
int AT : 4;
|
||||
int IDS : 4;
|
||||
int FWB : 4;
|
||||
int : 4;
|
||||
int TTL : 4;
|
||||
int BBM : 4;
|
||||
int EVT : 4;
|
||||
int E0PD : 4;
|
||||
|
||||
static inline ID_AA64MMFR2_EL1 read()
|
||||
{
|
||||
ID_AA64MMFR2_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], ID_AA64MMFR2_EL1"
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64MMFR2_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64MMFR3-EL1--AArch64-Memory-Model-Feature-Register-3
|
||||
// ID_AA64MMFR3_EL1, AArch64 Memory Model Feature Register 3
|
||||
struct alignas(u64) ID_AA64MMFR3_EL1 {
|
||||
int TCRX : 4;
|
||||
int SCTLRX : 4;
|
||||
int S1PIE : 4;
|
||||
int S2PIE : 4;
|
||||
int S1POE : 4;
|
||||
int S2POE : 4;
|
||||
int AIE : 4;
|
||||
int MEC : 4;
|
||||
int D128 : 4;
|
||||
int D128_2 : 4;
|
||||
int SNERR : 4;
|
||||
int ANERR : 4;
|
||||
int : 4;
|
||||
int SDERR : 4;
|
||||
int ADERR : 4;
|
||||
int Spec_FPACC : 4;
|
||||
|
||||
static inline ID_AA64MMFR3_EL1 read()
|
||||
{
|
||||
ID_AA64MMFR3_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], s3_0_c0_c7_3" // encoded ID_AA64MMFR3_EL1 register
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64MMFR3_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64MMFR4-EL1--AArch64-Memory-Model-Feature-Register-4
|
||||
// ID_AA64MMFR4_EL1, AArch64 Memory Model Feature Register 4
|
||||
struct alignas(u64) ID_AA64MMFR4_EL1 {
|
||||
int : 4;
|
||||
int EIESB : 4;
|
||||
int : 24;
|
||||
int : 32;
|
||||
|
||||
static inline ID_AA64MMFR4_EL1 read()
|
||||
{
|
||||
ID_AA64MMFR4_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], s3_0_c0_c7_4" // encoded ID_AA64MMFR4_EL1 register
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64MMFR4_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64SMFR0-EL1--SME-Feature-ID-register-0
|
||||
// ID_AA64SMFR0_EL1, AArch64 SME Feature ID register 0
|
||||
struct alignas(u64) ID_AA64SMFR0_EL1 {
|
||||
int : 32;
|
||||
int F32F32 : 1;
|
||||
int BI32I32 : 1;
|
||||
int B16F32 : 1;
|
||||
int F16F32 : 1;
|
||||
int I8I32 : 4;
|
||||
int : 2;
|
||||
int F16F16 : 1;
|
||||
int B16B16 : 1;
|
||||
int I16I32 : 4;
|
||||
int F64F64 : 1;
|
||||
int : 3;
|
||||
int I16I64 : 4;
|
||||
int SMEver : 4;
|
||||
int : 3;
|
||||
int FA64 : 1;
|
||||
|
||||
static inline ID_AA64SMFR0_EL1 read()
|
||||
{
|
||||
ID_AA64SMFR0_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], s3_0_c0_c4_5" // encoded ID_AA64SMFR0_EL1 register
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64SMFR0_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64ZFR0-EL1--SVE-Feature-ID-register-0
|
||||
// ID_AA64ZFR0_EL1, AArch64 SVE Feature ID register 0
|
||||
struct alignas(u64) ID_AA64ZFR0_EL1 {
|
||||
int SVEver : 4;
|
||||
int AES : 4;
|
||||
int : 8;
|
||||
int BitPerm : 4;
|
||||
int BF16 : 4;
|
||||
int B16B16 : 4;
|
||||
int : 4;
|
||||
int SHA3 : 4;
|
||||
int : 4;
|
||||
int SM4 : 4;
|
||||
int I8MM : 4;
|
||||
int : 4;
|
||||
int F32MM : 4;
|
||||
int F64MM : 4;
|
||||
int : 4;
|
||||
|
||||
static inline ID_AA64ZFR0_EL1 read()
|
||||
{
|
||||
ID_AA64ZFR0_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], s3_0_c0_c4_4" // encoded ID_AA64ZFR0_EL1 register
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64ZFR0_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64DFR0-EL1--AArch64-Debug-Feature-Register-0
|
||||
// ID_AA64DFR0_EL1, AArch64 Debug Feature Register 0
|
||||
struct alignas(u64) ID_AA64DFR0_EL1 {
|
||||
int DebugVer : 4;
|
||||
int TraceVer : 4;
|
||||
int PMUVer : 4;
|
||||
int BRPs : 4;
|
||||
int PMSS : 4;
|
||||
int WRPs : 4;
|
||||
int SEBEP : 4;
|
||||
int CTX_CMPs : 4;
|
||||
int PMSVer : 4;
|
||||
int DoubleLock : 4;
|
||||
int TraceFilt : 4;
|
||||
int TraceBuffer : 4;
|
||||
int MTPMU : 4;
|
||||
int BRBE : 4;
|
||||
int ExtTrcBuff : 4;
|
||||
int HPMN0 : 4;
|
||||
|
||||
static inline ID_AA64DFR0_EL1 read()
|
||||
{
|
||||
ID_AA64DFR0_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], ID_AA64DFR0_EL1"
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64DFR0_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/ID-AA64DFR1-EL1--AArch64-Debug-Feature-Register-1
|
||||
// ID_AA64DFR1_EL1, AArch64 Debug Feature Register 1
|
||||
struct alignas(u64) ID_AA64DFR1_EL1 {
|
||||
int SYSPMUID : 8;
|
||||
int BRPs : 8;
|
||||
int WRPs : 8;
|
||||
int CTX_CMPs : 8;
|
||||
int SPMU : 4;
|
||||
int PMICNTR : 4;
|
||||
int ABLE : 4;
|
||||
int ITE : 4;
|
||||
int EBEP : 4;
|
||||
int : 4;
|
||||
int ABL_CMPs : 8;
|
||||
|
||||
static inline ID_AA64DFR1_EL1 read()
|
||||
{
|
||||
ID_AA64DFR1_EL1 feature_register;
|
||||
|
||||
asm("mrs %[value], ID_AA64DFR1_EL1"
|
||||
: [value] "=r"(feature_register));
|
||||
|
||||
return feature_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ID_AA64DFR1_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0595/2020-12/AArch64-Registers/CNTFRQ-EL0--Counter-timer-Frequency-register
|
||||
// CNTFRQ_EL0, Counter-timer Frequency register
|
||||
struct alignas(u64) CNTFRQ_EL0 {
|
||||
|
@ -323,16 +709,33 @@ struct alignas(u64) MIDR_EL1 {
|
|||
|
||||
static inline MIDR_EL1 read()
|
||||
{
|
||||
MIDR_EL1 affinity_register;
|
||||
MIDR_EL1 main_id_register;
|
||||
|
||||
asm("mrs %[value], MIDR_EL1"
|
||||
: [value] "=r"(affinity_register));
|
||||
: [value] "=r"(main_id_register));
|
||||
|
||||
return affinity_register;
|
||||
return main_id_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(MIDR_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0601/2022-09/AArch64-Registers/AIDR-EL1--Auxiliary-ID-Register?lang=en
|
||||
// AIDR_EL1, Auxiliary ID Register
|
||||
struct alignas(u64) AIDR_EL1 {
|
||||
u64 AIDR : 64;
|
||||
|
||||
static inline AIDR_EL1 read()
|
||||
{
|
||||
AIDR_EL1 auxiliary_id_register;
|
||||
|
||||
asm("mrs %[value], AIDR_EL1"
|
||||
: [value] "=r"(auxiliary_id_register));
|
||||
|
||||
return auxiliary_id_register;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(AIDR_EL1) == 8);
|
||||
|
||||
// https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/HCR-EL2--Hypervisor-Configuration-Register
|
||||
// Hypervisor Configuration Register
|
||||
struct alignas(u64) HCR_EL2 {
|
||||
|
|
Loading…
Add table
Reference in a new issue