Add Memory Therm trip event handler

Added cpu1MemtripHandler() & cpu2MemtripHandler() handlers for
CPU1_MEM_THERM_EVENT and CPU2_MEM_THERM_EVENT Gpio pins respectively

Tested:
CPU1_MEM_THERM_EVENT:
1. Heated CPU1 DIMM with heat gun till memory thermal trip event occur.
2. CPU1 memory thermal trip event occurred and event logs logged in Redfish
3. Verified the event log generated on Redfish
Redfish URI:
GET: https://<BMC IP>/redfish/v1/Systems/system/LogServices/EventLog
               /Entries
{
      "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry",
      "@odata.id": "/redfish/v1/Systems/system/LogServices/EventLog/
                    Entries/506",
      "@odata.type": "#LogEntry.v1_4_0.LogEntry",
      "Created": "1970-01-01T00:08:26+00:00",
      "EntryType": "Event",
      "Id": "506",
      "Message": "Memory ThermTrip asserted: CPU 1.",
      "MessageArgs": [
        "CPU 1"
      ],
      "MessageId": "OpenBMC.0.1.MemoryThermTrip",
      "Name": "System Event Log Entry",
      "Severity": "Critical"
}
CPU2_MEM_THERM_EVENT:
1. Heated CPU2 DIMM with heat gun till memory thermal trip event occur.
2. CPU2 memory thermal trip event occurred and event logs logged in Redfish
3. Verified the event log generated on Redfish
Redfish URI:
GET: https://<BMC IP>/redfish/v1/Systems/system/LogServices/EventLog
               /Entries
{
      "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry",
      "@odata.id": "/redfish/v1/Systems/system/LogServices/EventLog/
                    Entries/506_2",
      "@odata.type": "#LogEntry.v1_4_0.LogEntry",
      "Created": "1970-01-01T00:08:26+00:00",
      "EntryType": "Event",
      "Id": "506_2",
      "Message": "Memory ThermTrip asserted: CPU 2.",
      "MessageArgs": [
        "CPU 2"
      ],
      "MessageId": "OpenBMC.0.1.MemoryThermTrip",
      "Name": "System Event Log Entry",
      "Severity": "Critical"
}

Change-Id: I2dc3dafd034c4452b9410823f1aa3fd01660f092
Signed-off-by: jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
Signed-off-by: Chalapathi <chalapathix.venkataramashetty@intel.com>
diff --git a/src/host_error_monitor.cpp b/src/host_error_monitor.cpp
index 0172ca2..f24925d 100644
--- a/src/host_error_monitor.cpp
+++ b/src/host_error_monitor.cpp
@@ -83,6 +83,13 @@
 //----------------------------------
 static gpiod::line pchThermtripLine;
 static boost::asio::posix::stream_descriptor pchThermtripEvent(io);
+//----------------------------------
+// CPU_MEM_THERM_EVENT function related definition
+//----------------------------------
+static gpiod::line cpu1MemtripLine;
+static boost::asio::posix::stream_descriptor cpu1MemtripEvent(io);
+static gpiod::line cpu2MemtripLine;
+static boost::asio::posix::stream_descriptor cpu2MemtripEvent(io);
 
 static void cpuIERRLog()
 {
@@ -154,6 +161,17 @@
                     cpuNum, NULL);
 }
 
+static void memThermTripLog(const int cpuNum)
+{
+    std::string cpuNumber = "CPU " + std::to_string(cpuNum);
+    std::string msg = cpuNumber + " Memory Thermal trip.";
+
+    sd_journal_send("MESSAGE=HostError: %s", msg.c_str(), "PRIORITY=%i",
+                    LOG_ERR, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.MemoryThermTrip", "REDFISH_MESSAGE_ARGS=%s",
+                    cpuNumber.c_str(), NULL);
+}
+
 static void cpuVRHotLog(const std::string& vr)
 {
     std::string msg = vr + " Voltage Regulator Overheated.";
@@ -742,6 +760,32 @@
         });
 }
 
+static void cpu1MemtripHandler()
+{
+    if (!hostOff)
+    {
+        gpiod::line_event gpioLineEvent = cpu1MemtripLine.event_read();
+
+        bool cpu1Memtrip =
+            gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE;
+        if (cpu1Memtrip)
+        {
+            memThermTripLog(1);
+        }
+    }
+    cpu1MemtripEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "CPU 1 Memory Thermaltrip handler error: "
+                          << ec.message() << "\n";
+                return;
+            }
+            cpu1MemtripHandler();
+        });
+}
+
 static void cpu2ThermtripAssertHandler()
 {
     if (cpu2FIVRFaultLine.get_value() == 0)
@@ -780,6 +824,32 @@
         });
 }
 
+static void cpu2MemtripHandler()
+{
+    if (!hostOff)
+    {
+        gpiod::line_event gpioLineEvent = cpu2MemtripLine.event_read();
+
+        bool cpu2Memtrip =
+            gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE;
+        if (cpu2Memtrip)
+        {
+            memThermTripLog(2);
+        }
+    }
+    cpu2MemtripEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "CPU 2 Memory Thermaltrip handler error: "
+                          << ec.message() << "\n";
+                return;
+            }
+            cpu2MemtripHandler();
+        });
+}
+
 static void cpu1VRHotAssertHandler()
 {
     cpuVRHotLog("CPU 1");
@@ -1344,6 +1414,18 @@
         cpu2ThermtripAssertHandler();
     }
 
+    // Handle CPU1_MEM_THERM_EVENT (CPU1 DIMM Thermal trip) if it's asserted now
+    if (cpu1MemtripLine.get_value() == 0)
+    {
+        memThermTripLog(1);
+    }
+
+    // Handle CPU2_MEM_THERM_EVENT (CPU2 DIMM Thermal trip) if it's asserted now
+    if (cpu2MemtripLine.get_value() == 0)
+    {
+        memThermTripLog(2);
+    }
+
     // Handle CPU1_VRHOT if it's asserted now
     if (cpu1VRHotLine.get_value() == 0)
     {
@@ -1565,6 +1647,24 @@
         return -1;
     }
 
+    // Request CPU1_MEM_THERM_EVENT GPIO events
+    if (!host_error_monitor::requestGPIOEvents(
+            "CPU1_MEM_THERM_EVENT", host_error_monitor::cpu1MemtripHandler,
+            host_error_monitor::cpu1MemtripLine,
+            host_error_monitor::cpu1MemtripEvent))
+    {
+        return -1;
+    }
+
+    // Request CPU2_MEM_THERM_EVENT GPIO events
+    if (!host_error_monitor::requestGPIOEvents(
+            "CPU2_MEM_THERM_EVENT", host_error_monitor::cpu2MemtripHandler,
+            host_error_monitor::cpu2MemtripLine,
+            host_error_monitor::cpu2MemtripEvent))
+    {
+        return -1;
+    }
+
     host_error_monitor::io.run();
 
     return 0;