From 9123f58bd5fdd57514b3d199308b98022685c251 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 16 Jul 2013 01:22:06 -0500 Subject: [PATCH] Check for IDIVA/IDIVT correctly. Cortex-A5 parts would have had this set since it supports VFPv4 but not IDIVA. Qualcomm Krait/Krait 300 still doesn't report in the kernel that it supports this. --- Source/Core/Common/Src/ArmCPUDetect.cpp | 57 +++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/Source/Core/Common/Src/ArmCPUDetect.cpp b/Source/Core/Common/Src/ArmCPUDetect.cpp index 33eee9f05e..ca277ade02 100644 --- a/Source/Core/Common/Src/ArmCPUDetect.cpp +++ b/Source/Core/Common/Src/ArmCPUDetect.cpp @@ -44,6 +44,56 @@ char *GetCPUString() } return cpu_string; } + +unsigned char GetCPUImplementer() +{ + const char marker[] = "CPU implementer\t: "; + char *implementer_string = 0; + unsigned char implementer = 0; + char buf[1024]; + + File::IOFile file(procfile, "r"); + auto const fp = file.GetHandle(); + if (!fp) + return 0; + + while (fgets(buf, sizeof(buf), fp)) + { + if (strncmp(buf, marker, sizeof(marker) - 1)) + continue; + implementer_string = buf + sizeof(marker) - 1; + implementer_string = strndup(implementer_string, strlen(implementer_string) - 1); // Strip the newline + sscanf(implementer_string, "0x%02hhx", &implementer); + break; + } + return implementer; +} + +unsigned short GetCPUPart() +{ + const char marker[] = "CPU part\t: "; + char *part_string = 0; + unsigned short part = 0; + char buf[1024]; + + File::IOFile file(procfile, "r"); + auto const fp = file.GetHandle(); + if (!fp) + return 0; + + while (fgets(buf, sizeof(buf), fp)) + { + if (strncmp(buf, marker, sizeof(marker) - 1)) + continue; + part_string = buf + sizeof(marker) - 1; + part_string = strndup(part_string, strlen(part_string) - 1); // Strip the newline + sscanf(part_string, "0x%03hx", &part); + break; + } + return part; + +} + bool CheckCPUFeature(const char *feature) { const char marker[] = "Features\t: "; @@ -123,10 +173,9 @@ void CPUInfo::Detect() bIDIVa = CheckCPUFeature("idiva"); bIDIVt = CheckCPUFeature("idivt"); - // On some buggy kernels(Qualcomm) they show that they support VFPv4 but not IDIVa - // All VFPv4 CPUs will support IDIVa - if (bVFPv4) - bIDIVa = bIDIVt = true; + // Qualcomm Krait supports IDIVA but it doesn't report it. Check for krait. + if (GetCPUImplementer() == 0x51 && GetCPUPart() == 0x6F) // Krait(300) is 0x6F, Scorpion is 0x4D + bIDIVa = bIDIVt = true; // These two are ARMv8 specific. bFP = CheckCPUFeature("fp");