blob: b27e2486ca799d5c08da082fb18e4588d0e113ea [file] [log] [blame]
Ben Pai44cee312020-03-16 15:24:46 +08001#include "config.h"
2
3#include "wistronoem.hpp"
4
5#include "smbus.hpp"
6
7#include <endian.h>
8#include <ipmid/api.h>
9#include <stdio.h>
10#include <string.h>
11#include <systemd/sd-bus.h>
12
13#include <fstream>
14#include <functional>
15#include <iostream>
16#include <ipmid-host/cmd.hpp>
17#include <memory>
18#include <sdbusplus/bus.hpp>
19#include <sdbusplus/exception.hpp>
20
21#include "i2c.h"
22
23#define SWITCH_SLAVE_ADDRESS 112 /* Hexadecimal value:0x70 */
24#define RISERF_SLAVE_ADDRESS 16 /* Hexadecimal value:0x10 */
25
26void register_detect_riserf() __attribute__((constructor));
Ben Paiba89a1e2020-11-06 17:00:33 +080027void register_switch_image() __attribute__((constructor));
Ben Pai44cee312020-03-16 15:24:46 +080028
29ipmi_ret_t ipmi_wistron_detect_riserf(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
30 ipmi_request_t request,
31 ipmi_response_t response,
32 ipmi_data_len_t data_len,
33 ipmi_context_t context)
34{
35 phosphor::smbus::Smbus smbus;
36
37 auto init_cp0 = smbus.smbusInit(9);
38 if (init_cp0 == initError)
39 {
40 std::cerr << "smbusInit fail!"
41 << "\n";
42 return false;
43 }
44 smbus.SetSmbusCmdByte(9, SWITCH_SLAVE_ADDRESS, 0, 8);
45 auto res_cp0 = smbus.GetSmbusCmdByte(9, RISERF_SLAVE_ADDRESS, command);
46
47 auto init_cp1 = smbus.smbusInit(10);
48 if (init_cp1 == initError)
49 {
50 std::cerr << "smbusInit fail!"
51 << "\n";
52 return false;
53 }
54 smbus.SetSmbusCmdByte(10, SWITCH_SLAVE_ADDRESS, 0, 8);
55 auto res_cp1 = smbus.GetSmbusCmdByte(10, RISERF_SLAVE_ADDRESS, command);
56
57 // CPU0 & CPU1 are not present.
58 if (res_cp0 < 0 && res_cp1 < 0)
59 {
60 *data_len = sizeof(a);
61 memcpy(response, &a, *data_len);
62 }
63
64 // CPU0 isn't present but CPU1 is present.
65 if (res_cp0 < 0 && res_cp1 >= 0)
66 {
67 *data_len = sizeof(b);
68 memcpy(response, &b, *data_len);
69 }
70
71 // CPU0 is present but CPU1 isn't present.
72 if (res_cp0 >= 0 && res_cp1 < 0)
73 {
74 *data_len = sizeof(c);
75 memcpy(response, &c, *data_len);
76 }
77
78 // CPU0 & CPU1 are present.
79 if (res_cp0 >= 0 && res_cp1 >= 0)
80 {
81 *data_len = sizeof(d);
82 memcpy(response, &d, *data_len);
83 }
84
85 smbus.smbusClose(9);
86 smbus.smbusClose(10);
87
88 return IPMI_CC_OK;
89}
Ben Paiba89a1e2020-11-06 17:00:33 +080090ipmi_ret_t ipmi_wistron_switch_image(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
91 ipmi_request_t request,
92 ipmi_response_t response,
93 ipmi_data_len_t data_len,
94 ipmi_context_t context)
95{
96 int rc = 0;
97 uint8_t *reqptr = (uint8_t *) request;
98
99 // Switch to backup flash.
100 if (reqptr[0] == 0)
101 {
102 system("gpioset gpiochip1 1=0");
103 }
104
105 // Switch to default flash.
106 else if (reqptr[0] == 1)
107 {
108 system("gpioset gpiochip1 1=1");
109 }
110
111 else
112 {
113 rc = -1;
114 }
115
116 if(rc != 0)
117 {
118 return IPMI_CC_PARM_OUT_OF_RANGE;
119 }
120
121 return IPMI_CC_OK;
122}
Ben Pai44cee312020-03-16 15:24:46 +0800123
124void register_detect_riserf()
125{
126 ipmi_register_callback(NETFUN_OEM, IPMI_CMD_DETECT_RISERF, NULL,
127 ipmi_wistron_detect_riserf, SYSTEM_INTERFACE);
128}
Ben Paiba89a1e2020-11-06 17:00:33 +0800129void register_switch_image()
130{
131 ipmi_register_callback(NETFUN_OEM, IPMI_CMD_SWITCH_BITTWARE_IMAGE, NULL,
132 ipmi_wistron_switch_image, SYSTEM_INTERFACE);
133}