================ @@ -93,6 +93,55 @@ DNBArchMachARM64::SoftwareBreakpointOpcode(nub_size_t byte_size) { uint32_t DNBArchMachARM64::GetCPUType() { return CPU_TYPE_ARM64; } +static std::once_flag g_cpu_has_sme_once; +bool DNBArchMachARM64::CPUHasSME() { + static bool g_has_sme = false; + std::call_once(g_cpu_has_sme_once, []() { + int ret = 0; + size_t size = sizeof(ret); + if (sysctlbyname("hw.optional.arm.FEAT_SME", &ret, &size, NULL, 0) != -1) + g_has_sme = ret == 1; + }); + return g_has_sme; +} + +static std::once_flag g_cpu_has_sme2_once; +bool DNBArchMachARM64::CPUHasSME2() { + static bool g_has_sme2 = false; + std::call_once(g_cpu_has_sme2_once, []() { + int ret = 0; + size_t size = sizeof(ret); + if (sysctlbyname("hw.optional.arm.FEAT_SME2", &ret, &size, NULL, 0) != -1) + g_has_sme2 = ret == 1; + }); + return g_has_sme2; +} + +static std::once_flag g_sme_max_svl_once; +unsigned int DNBArchMachARM64::GetSMEMaxSVL() { + static unsigned int g_sme_max_svl = 0; + std::call_once(g_sme_max_svl_once, []() { + if (CPUHasSME()) { + unsigned int ret = 0; + size_t size = sizeof(ret); + if (sysctlbyname("hw.optional.arm.sme_max_svl_b", &ret, &size, NULL, 0) != + -1) + g_sme_max_svl = ret; + else + g_sme_max_svl = get_svl_bytes(); + } + }); + return g_sme_max_svl; +} + +// This function can only be called on systems with hw.optional.arm.FEAT_SME +// It will return the maximum SVL length for this process. +uint16_t __attribute__((target("sme"))) DNBArchMachARM64::get_svl_bytes(void) { + uint64_t ret = 0; + asm volatile("rdsvl %[ret], #1" : [ret] "=r"(ret)); ---------------- jasonmolenda wrote:
Yes, when I added this there wasn't a way to get the maximum SVL but the kernel folks are adding `hw.optional.arm.sme_max_svl_b` sysctl. You could imagine a scenario where we have generations of cores with a 64 byte SVL max, and then there's a new core some day with 128 byte SVL and there are programs which are hardcoded to the old length; maybe a process would be launched with a 64 byte SVL max by default. It's possible to imagine debugserver having a lower max SVL than the inferior process which might have been launched with a "give me the actual full SVL" mode. I should probably remove this backup method of getting the max SVL. https://github.com/llvm/llvm-project/pull/119171 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits