blob: 0c65f85bf526578c7a7951729d3ad69e63c32688 [file] [log] [blame]
Patrick Ventureaccc9172018-07-24 10:51:58 -07001/*
2 * Copyright 2017 Google Inc.
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
Patrick Venture54c3b532018-08-01 11:45:49 -070017#include <memory>
18
Patrick Ventureaccc9172018-07-24 10:51:58 -070019#include "host-ipmid/ipmid-api.h"
20#include "host-ipmid/oemrouter.hpp"
21
Patrick Venture3d1786b2018-08-01 11:19:24 -070022#include "flash-ipmi.hpp"
Patrick Venture54c3b532018-08-01 11:45:49 -070023#include "ipmi.hpp"
Patrick Venture3d1786b2018-08-01 11:19:24 -070024
Patrick Ventureaccc9172018-07-24 10:51:58 -070025/* TODO: Once OEM IPMI number placement is settled, point to that. */
26namespace oem
27{
28namespace google
29{
30constexpr int number = 11129;
31constexpr int flashOverBTCmd = 127;
32} // namespace google
33} // namespace oem
34
Patrick Venture54c3b532018-08-01 11:45:49 -070035/* We have one instance of the FlashUpdate object tracking commands. */
36std::unique_ptr<FlashUpdate> flashUpdateSingleton;
37
Patrick Ventureaccc9172018-07-24 10:51:58 -070038static ipmi_ret_t flashControl(ipmi_cmd_t cmd, const uint8_t* reqBuf,
39 uint8_t* replyCmdBuf, size_t* dataLen)
40{
Patrick Venture9a5a79a2018-08-03 17:23:57 -070041 size_t requestLength = (*dataLen);
42
Patrick Ventureaccc9172018-07-24 10:51:58 -070043 /* Verify it's at least as long as the shortest message. */
Patrick Venture9a5a79a2018-08-03 17:23:57 -070044 if (requestLength < 1)
Patrick Ventureaccc9172018-07-24 10:51:58 -070045 {
46 return IPMI_CC_INVALID;
47 }
48
Patrick Venturea53a7b32018-08-03 09:15:20 -070049 auto subCmd = static_cast<FlashSubCmds>(reqBuf[0]);
50
51 /* Validate the minimum request length for the command. */
Patrick Venture9a5a79a2018-08-03 17:23:57 -070052 if (!validateRequestLength(subCmd, requestLength))
Patrick Venturea53a7b32018-08-03 09:15:20 -070053 {
54 return IPMI_CC_INVALID;
55 }
Patrick Venture54c3b532018-08-01 11:45:49 -070056
Patrick Venture9a5a79a2018-08-03 17:23:57 -070057 auto handler = getCommandHandler(subCmd);
58 if (handler)
Patrick Venture54c3b532018-08-01 11:45:49 -070059 {
Patrick Venture9a5a79a2018-08-03 17:23:57 -070060 return handler(flashUpdateSingleton.get(), reqBuf, replyCmdBuf,
61 dataLen);
Patrick Venture54c3b532018-08-01 11:45:49 -070062 }
63
Patrick Ventureaccc9172018-07-24 10:51:58 -070064 return IPMI_CC_INVALID;
65}
66
67static ipmi_ret_t ipmiFlashControl(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
68 ipmi_request_t request,
69 ipmi_response_t response,
70 ipmi_data_len_t dataLen,
71 ipmi_context_t context)
72{
73 /* request_t, response_t are void*. ipmi_data_len_t is a size_t* */
74 auto reqBuf = static_cast<const uint8_t*>(request);
75 auto replyCmdBuf = static_cast<uint8_t*>(response);
76
77 return flashControl(cmd, reqBuf, replyCmdBuf, dataLen);
78}
79
80void setupGlobalOemFlashControl() __attribute__((constructor));
81
82void setupGlobalOemFlashControl()
83{
Patrick Venture54c3b532018-08-01 11:45:49 -070084 flashUpdateSingleton = std::make_unique<FlashUpdate>();
85
Patrick Ventureaccc9172018-07-24 10:51:58 -070086#ifdef ENABLE_GOOGLE
87 oem::Router* router = oem::mutableRouter();
88
89 fprintf(stderr, "Registering OEM:[%#08X], Cmd:[%#04X] for Flash Update\n",
90 oem::google::number, oem::google::flashOverBTCmd);
91
92 router->registerHandler(oem::google::number, oem::google::flashOverBTCmd,
93 flashControl);
94#endif
95
96 ipmi_register_callback(NETFUN_FIRMWARE, oem::google::flashOverBTCmd, NULL,
97 ipmiFlashControl, PRIVILEGE_USER);
98}