cpu: Add support for ARM family

In order to detect the ARM family, the Processor Family (Offset 06h)
must contain the value of 0xFE. Then the family is located in
Processor Family 2 (Offset 28h) according to SMBIOS Spec. 3.0.0
and later.

The following ARM families have been added to the family list to
follow SMBIOS Spec. 3.1.1 and later.
 - ARMv7
 - ARMv8
 - ARM
 - StrongARM

Tested:
 - With ARM CPUs, both dbus and Redfish presented the processor's
   family from SMBIOS.

Signed-off-by: Charles Boyer <Charles.Boyer@fii-usa.com>
Change-Id: I21b80f34bfe76a2a2b6d78ee7aace54ded6abec4
diff --git a/include/cpu.hpp b/include/cpu.hpp
index 1f8fd9c..276e64a 100644
--- a/include/cpu.hpp
+++ b/include/cpu.hpp
@@ -76,7 +76,14 @@
     {0xdd, "Dual-Core Intel Xeon processor 7xxx Series"},
     {0xde, "Quad-Core Intel Xeon processor 7xxx Series"},
     {0xdf, "Multi-Core Intel Xeon processor 7xxx Series"},
-    {0xe0, "Multi-Core Intel Xeon processor 3400 Series"}
+    {0xe0, "Multi-Core Intel Xeon processor 3400 Series"},
+    {0xfe, "Processor Family 2 Indicator"}
+
+};
+
+// Definition follow smbios spec DSP0134 3.1.1
+static const std::map<uint16_t, const char*> family2Table = {
+    {0x100, "ARMv7"}, {0x101, "ARMv8"}, {0x118, "ARM"}, {0x119, "StrongARM"}
 
 };
 
@@ -165,7 +172,7 @@
 
     void socket(const uint8_t positionNum, const uint8_t structLen,
                 uint8_t* dataIn);
-    void family(const uint8_t value);
+    void family(const uint8_t family, const uint16_t family2);
     void manufacturer(const uint8_t positionNum, const uint8_t structLen,
                       uint8_t* dataIn);
     void serialNumber(const uint8_t positionNum, const uint8_t structLen,
diff --git a/src/cpu.cpp b/src/cpu.cpp
index a5f39ee..daab15b 100644
--- a/src/cpu.cpp
+++ b/src/cpu.cpp
@@ -34,13 +34,28 @@
     location::locationCode(result);
 }
 
-void Cpu::family(const uint8_t value)
+static constexpr uint8_t processorFamily2Indicator = 0xfe;
+void Cpu::family(const uint8_t family, const uint16_t family2)
 {
-    std::map<uint8_t, const char*>::const_iterator it = familyTable.find(value);
+    std::map<uint8_t, const char*>::const_iterator it =
+        familyTable.find(family);
     if (it == familyTable.end())
     {
         processor::family("Unknown Processor Family");
     }
+    else if (it->first == processorFamily2Indicator)
+    {
+        std::map<uint16_t, const char*>::const_iterator it2 =
+            family2Table.find(family2);
+        if (it2 == family2Table.end())
+        {
+            processor::family("Unknown Processor Family");
+        }
+        else
+        {
+            processor::family(it2->second);
+        }
+    }
     else
     {
         processor::family(it->second);
@@ -140,7 +155,7 @@
     present(true);
 
     // this class is for type CPU  //offset 5h
-    family(cpuInfo->family); // offset 6h
+    family(cpuInfo->family, cpuInfo->family2); // offset 6h and 28h
     manufacturer(cpuInfo->manufacturer, cpuInfo->length,
                  dataIn);                               // offset 7h
     id(cpuInfo->id);                                    // offset 8h