From 6482bad2134c337906571ae1097a51b1f2b7da1b Mon Sep 17 00:00:00 2001 From: "Dr.-Ing. Patrick Siegl" Date: Tue, 18 Jun 2019 12:53:08 +0200 Subject: [PATCH] Added RPI zero with its features HALF, THUMB, FASTMULT, EDSP, JAVA and TLS (#75) --- include/cpuinfo_arm.h | 12 +++++++ include/internal/hwcaps.h | 6 ++++ src/cpuinfo_arm.c | 36 ++++++++++++++++++++ test/cpuinfo_arm_test.cc | 70 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+) diff --git a/include/cpuinfo_arm.h b/include/cpuinfo_arm.h index 76a49ef..8389082 100644 --- a/include/cpuinfo_arm.h +++ b/include/cpuinfo_arm.h @@ -21,11 +21,17 @@ CPU_FEATURES_START_CPP_NAMESPACE typedef struct { + int half : 1; // Half-word loads and stores + int thumb : 1; // Thumb (16-bit instruction set) + int fastmult : 1; // 32x32->64-bit multiplication int vfp : 1; // Vector Floating Point. + int edsp : 1; // DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above) + int java : 1; // Jazelle (Java bytecode accelerator) int iwmmxt : 1; // Intel Wireless MMX Technology. int neon : 1; // Advanced SIMD. int vfpv3 : 1; // VFP version 3 int vfpv3d16 : 1; // VFP version 3 with 16 D-registers + int tls : 1; // TLS register int vfpv4 : 1; // VFP version 4 with fast context switching int idiva : 1; // SDIV and UDIV hardware division in ARM mode. int idivt : 1; // SDIV and UDIV hardware division in Thumb mode. @@ -59,11 +65,17 @@ uint32_t GetArmCpuId(const ArmInfo* const info); // Introspection functions typedef enum { + ARM_HALF, + ARM_THUMB, + ARM_FASTMULT, ARM_VFP, + ARM_EDSP, + ARM_JAVA, ARM_IWMMXT, ARM_NEON, ARM_VFPV3, ARM_VFPV3D16, + ARM_TLS, ARM_VFPV4, ARM_IDIVA, ARM_IDIVT, diff --git a/include/internal/hwcaps.h b/include/internal/hwcaps.h index cb38e29..222ea71 100644 --- a/include/internal/hwcaps.h +++ b/include/internal/hwcaps.h @@ -35,11 +35,17 @@ CPU_FEATURES_START_CPP_NAMESPACE #define AARCH64_HWCAP_CRC32 (1UL << 7) // http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h +#define ARM_HWCAP_HALF (1UL << 1) +#define ARM_HWCAP_THUMB (1UL << 2) +#define ARM_HWCAP_FAST_MULT (1UL << 4) #define ARM_HWCAP_VFP (1UL << 6) +#define ARM_HWCAP_EDSP (1UL << 7) +#define ARM_HWCAP_JAVA (1UL << 8) #define ARM_HWCAP_IWMMXT (1UL << 9) #define ARM_HWCAP_NEON (1UL << 12) #define ARM_HWCAP_VFPV3 (1UL << 13) #define ARM_HWCAP_VFPV3D16 (1UL << 14) +#define ARM_HWCAP_TLS (1UL << 15) #define ARM_HWCAP_VFPV4 (1UL << 16) #define ARM_HWCAP_IDIVA (1UL << 17) #define ARM_HWCAP_IDIVT (1UL << 18) diff --git a/src/cpuinfo_arm.c b/src/cpuinfo_arm.c index afbb9f1..eb27298 100644 --- a/src/cpuinfo_arm.c +++ b/src/cpuinfo_arm.c @@ -23,11 +23,17 @@ #include +DECLARE_SETTER(ArmFeatures, half) +DECLARE_SETTER(ArmFeatures, thumb) +DECLARE_SETTER(ArmFeatures, fastmult) DECLARE_SETTER(ArmFeatures, vfp) +DECLARE_SETTER(ArmFeatures, edsp) +DECLARE_SETTER(ArmFeatures, java) DECLARE_SETTER(ArmFeatures, iwmmxt) DECLARE_SETTER(ArmFeatures, neon) DECLARE_SETTER(ArmFeatures, vfpv3) DECLARE_SETTER(ArmFeatures, vfpv3d16) +DECLARE_SETTER(ArmFeatures, tls) DECLARE_SETTER(ArmFeatures, vfpv4) DECLARE_SETTER(ArmFeatures, idiva) DECLARE_SETTER(ArmFeatures, idivt) @@ -38,11 +44,17 @@ DECLARE_SETTER(ArmFeatures, sha2) DECLARE_SETTER(ArmFeatures, crc32) static const CapabilityConfig kConfigs[] = { + {{ARM_HWCAP_HALF, 0}, "half", &set_half}, // + {{ARM_HWCAP_THUMB, 0}, "thumb", &set_thumb}, // + {{ARM_HWCAP_FAST_MULT, 0}, "fastmult", &set_fastmult}, // {{ARM_HWCAP_VFP, 0}, "vfp", &set_vfp}, // + {{ARM_HWCAP_EDSP, 0}, "edsp", &set_edsp}, // + {{ARM_HWCAP_JAVA, 0}, "java", &set_java}, // {{ARM_HWCAP_IWMMXT, 0}, "iwmmxt", &set_iwmmxt}, // {{ARM_HWCAP_NEON, 0}, "neon", &set_neon}, // {{ARM_HWCAP_VFPV3, 0}, "vfpv3", &set_vfpv3}, // {{ARM_HWCAP_VFPV3D16, 0}, "vfpv3d16", &set_vfpv3d16}, // + {{ARM_HWCAP_TLS, 0}, "tls", &set_tls}, // {{ARM_HWCAP_VFPV4, 0}, "vfpv4", &set_vfpv4}, // {{ARM_HWCAP_IDIVA, 0}, "idiva", &set_idiva}, // {{ARM_HWCAP_IDIVT, 0}, "idivt", &set_idivt}, // @@ -192,8 +204,18 @@ ArmInfo GetArmInfo(void) { int GetArmFeaturesEnumValue(const ArmFeatures* features, ArmFeaturesEnum value) { switch (value) { + case ARM_HALF: + return features->half; + case ARM_THUMB: + return features->thumb; + case ARM_FASTMULT: + return features->fastmult; case ARM_VFP: return features->vfp; + case ARM_EDSP: + return features->edsp; + case ARM_JAVA: + return features->java; case ARM_IWMMXT: return features->iwmmxt; case ARM_NEON: @@ -202,6 +224,8 @@ int GetArmFeaturesEnumValue(const ArmFeatures* features, return features->vfpv3; case ARM_VFPV3D16: return features->vfpv3d16; + case ARM_TLS: + return features->tls; case ARM_VFPV4: return features->vfpv4; case ARM_IDIVA: @@ -226,8 +250,18 @@ int GetArmFeaturesEnumValue(const ArmFeatures* features, const char* GetArmFeaturesEnumName(ArmFeaturesEnum value) { switch (value) { + case ARM_HALF: + return "half"; + case ARM_THUMB: + return "thumb"; + case ARM_FASTMULT: + return "fastmult"; case ARM_VFP: return "vfp"; + case ARM_EDSP: + return "edsp"; + case ARM_JAVA: + return "java"; case ARM_IWMMXT: return "iwmmxt"; case ARM_NEON: @@ -236,6 +270,8 @@ const char* GetArmFeaturesEnumName(ArmFeaturesEnum value) { return "vfpv3"; case ARM_VFPV3D16: return "vfpv3d16"; + case ARM_TLS: + return "tls"; case ARM_VFPV4: return "vfpv4"; case ARM_IDIVA: diff --git a/test/cpuinfo_arm_test.cc b/test/cpuinfo_arm_test.cc index 34c7551..811434c 100644 --- a/test/cpuinfo_arm_test.cc +++ b/test/cpuinfo_arm_test.cc @@ -62,11 +62,17 @@ CPU revision : 3)"); EXPECT_EQ(info.revision, 3); EXPECT_EQ(info.architecture, 7); + EXPECT_TRUE(info.features.half); + EXPECT_TRUE(info.features.thumb); + EXPECT_TRUE(info.features.fastmult); EXPECT_TRUE(info.features.vfp); + EXPECT_TRUE(info.features.edsp); + EXPECT_FALSE(info.features.java); EXPECT_FALSE(info.features.iwmmxt); EXPECT_TRUE(info.features.neon); EXPECT_TRUE(info.features.vfpv3); EXPECT_FALSE(info.features.vfpv3d16); + EXPECT_TRUE(info.features.tls); EXPECT_TRUE(info.features.vfpv4); EXPECT_TRUE(info.features.idiva); EXPECT_TRUE(info.features.idivt); @@ -77,6 +83,50 @@ CPU revision : 3)"); EXPECT_FALSE(info.features.crc32); } +TEST(CpuinfoArmTest, RaspberryPiZero) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", R"(processor : 0 +model name : ARMv6-compatible processor rev 7 (v6l) +BogoMIPS : 697.95 +Features : half thumb fastmult vfp edsp java tls +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xb76 +CPU revision : 7 + +Hardware : BCM2835 +Revision : 9000c1 +Serial : 000000006cd946f3)"); + const auto info = GetArmInfo(); + EXPECT_EQ(info.implementer, 0x41); + EXPECT_EQ(info.variant, 0x0); + EXPECT_EQ(info.part, 0xb76); + EXPECT_EQ(info.revision, 7); + EXPECT_EQ(info.architecture, 7); + + EXPECT_TRUE(info.features.half); + EXPECT_TRUE(info.features.thumb); + EXPECT_TRUE(info.features.fastmult); + EXPECT_TRUE(info.features.vfp); + EXPECT_TRUE(info.features.edsp); + EXPECT_TRUE(info.features.java); + EXPECT_FALSE(info.features.iwmmxt); + EXPECT_FALSE(info.features.neon); + EXPECT_FALSE(info.features.vfpv3); + EXPECT_FALSE(info.features.vfpv3d16); + EXPECT_TRUE(info.features.tls); + EXPECT_FALSE(info.features.vfpv4); + EXPECT_FALSE(info.features.idiva); + EXPECT_FALSE(info.features.idivt); + EXPECT_FALSE(info.features.aes); + EXPECT_FALSE(info.features.pmull); + EXPECT_FALSE(info.features.sha1); + EXPECT_FALSE(info.features.sha2); + EXPECT_FALSE(info.features.crc32); +} + // http://code.google.com/p/android/issues/detail?id=10812 TEST(CpuinfoArmTest, InvalidArmv7) { DisableHardwareCapabilities(); @@ -96,6 +146,26 @@ Revision : 0020 Serial : 33323613546d00ec )"); const auto info = GetArmInfo(); EXPECT_EQ(info.architecture, 6); + + EXPECT_TRUE(info.features.half); + EXPECT_TRUE(info.features.thumb); + EXPECT_TRUE(info.features.fastmult); + EXPECT_TRUE(info.features.vfp); + EXPECT_TRUE(info.features.edsp); + EXPECT_TRUE(info.features.java); + EXPECT_FALSE(info.features.iwmmxt); + EXPECT_FALSE(info.features.neon); + EXPECT_FALSE(info.features.vfpv3); + EXPECT_FALSE(info.features.vfpv3d16); + EXPECT_FALSE(info.features.tls); + EXPECT_FALSE(info.features.vfpv4); + EXPECT_FALSE(info.features.idiva); + EXPECT_FALSE(info.features.idivt); + EXPECT_FALSE(info.features.aes); + EXPECT_FALSE(info.features.pmull); + EXPECT_FALSE(info.features.sha1); + EXPECT_FALSE(info.features.sha2); + EXPECT_FALSE(info.features.crc32); } // https://crbug.com/341598.