blob: 5a99da2d05c9a9cf60c580ece230421eeb424075 [file] [log] [blame]
Jason M. Billsa92735d2020-09-24 15:49:26 -07001/*
2// Copyright (c) 2021 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17#include <systemd/sd-journal.h>
18
19#include <error_monitors/base_monitor.hpp>
20#include <gpiod.hpp>
21#include <host_error_monitor.hpp>
22#include <sdbusplus/asio/object_server.hpp>
23
24#include <iostream>
25
26namespace host_error_monitor::cpu_mismatch_monitor
27{
28static constexpr bool debug = false;
29
30class CPUMismatchMonitor : public host_error_monitor::base_monitor::BaseMonitor
31{
32 size_t cpuNum;
33 gpiod::line cpuMismatchLine;
34
35 void cpuMismatchLog()
36 {
37 sd_journal_send("MESSAGE=HostError: CPU %d mismatch", cpuNum,
38 "PRIORITY=%i", LOG_ERR, "REDFISH_MESSAGE_ID=%s",
39 "OpenBMC.0.1.CPUMismatch", "REDFISH_MESSAGE_ARGS=%d",
40 cpuNum, NULL);
41 }
42
43 bool requestCPUMismatchInput()
44 {
45 // Find the GPIO line
46 cpuMismatchLine = gpiod::find_line(signalName);
47 if (!cpuMismatchLine)
48 {
49 std::cerr << "Failed to find the " << signalName << " line.\n";
50 return false;
51 }
52
53 // Request GPIO input
54 try
55 {
56 cpuMismatchLine.request(
57 {"host-error-monitor", gpiod::line_request::DIRECTION_INPUT});
58 }
59 catch (std::exception&)
60 {
61 std::cerr << "Failed to request " << signalName << " input\n";
62 return false;
63 }
64
65 return true;
66 }
67
68 bool cpuMismatchAsserted()
69 {
70 if constexpr (debug)
71 {
72 std::cerr << "Checking " << signalName << " state\n";
73 }
74
75 return (cpuMismatchLine.get_value() == 1);
76 }
77
78 void cpuMismatchAssertHandler()
79 {
80 std::cerr << signalName << " asserted\n";
81 cpuMismatchLog();
82 }
83
84 void checkCPUMismatch()
85 {
86 if (cpuMismatchAsserted())
87 {
88 cpuMismatchAssertHandler();
89 }
90 }
91
92 public:
93 CPUMismatchMonitor(boost::asio::io_service& io,
94 std::shared_ptr<sdbusplus::asio::connection> conn,
95 const std::string& signalName, const size_t cpuNum) :
96 BaseMonitor(io, conn, signalName),
97 cpuNum(cpuNum)
98 {
99 // Request GPIO input
100 if (!requestCPUMismatchInput())
101 {
102 return;
103 }
104 checkCPUMismatch();
105 valid = true;
106 }
107
108 void hostOn() override
109 {
110 checkCPUMismatch();
111 }
112};
113} // namespace host_error_monitor::cpu_mismatch_monitor