summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Src/ArmCPUDetect.cpp
diff options
context:
space:
mode:
authorMatthew Parlane <parlane@gmail.com>2013-08-16 19:17:07 +1200
committerMatthew Parlane <parlane@gmail.com>2013-08-16 19:17:07 +1200
commit9de7611ff940d24551bc77a5e29b86911e3fa749 (patch)
tree7615ec4cfd3aaba63d96ef1cb3cc33fd0efa516a /Source/Core/Common/Src/ArmCPUDetect.cpp
parent417552b21e30aee3dc2b720d65c2cd757997a33e (diff)
parentbff2bc1288fa4309e1b2aef1486845ba01311100 (diff)
Merge branch 'master' into wii-network
Conflicts: CMakeLists.txt Source/Core/Core/Core.vcxproj Source/Core/DolphinWX/Dolphin.vcxproj Source/Core/DolphinWX/Dolphin.vcxproj.filters Source/Dolphin_2010.sln Source/VSProps/Dolphin.Win32.props Source/VSProps/Dolphin.x64.props
Diffstat (limited to 'Source/Core/Common/Src/ArmCPUDetect.cpp')
-rw-r--r--Source/Core/Common/Src/ArmCPUDetect.cpp57
1 files 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");