blob: dade4ed592b397d5004239e4a8156bf3746ab345 [file] [log] [blame]
Willy Tu6c71b0f2021-10-10 13:34:41 -07001// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "config.h"
16
17#include "pcie_bifurcation.hpp"
18
19#include "commands.hpp"
20#include "errors.hpp"
21#include "handler.hpp"
22
23#include <fmt/format.h>
24
25#include <ipmid/api-types.hpp>
Patrick Williams444b5ea2023-05-19 13:56:42 -050026
Willy Tu6c71b0f2021-10-10 13:34:41 -070027#include <span>
28#include <vector>
29
30namespace google
31{
32namespace ipmi
33{
34
35namespace
36{
37#ifndef MAX_IPMI_BUFFER
38#define MAX_IPMI_BUFFER 64
39#endif
40} // namespace
41
42struct PcieBifurcationRequest
43{
44 uint8_t pcieIndex;
45} __attribute__((packed));
46
47Resp pcieBifurcation(std::span<const uint8_t> data, HandlerInterface* handler)
48{
49 if (data.size() < sizeof(struct PcieBifurcationRequest))
50 {
51 fmt::print(stderr, "Invalid command length: {}\n",
52 static_cast<uint32_t>(data.size()));
53 return ::ipmi::responseReqDataLenInvalid();
54 }
55
56 auto bifurcation = handler->pcieBifurcation(/*index=*/data[0]);
57
58 int length = sizeof(struct PcieBifurcationReply) + bifurcation.size();
59
60 if (length > MAX_IPMI_BUFFER)
61 {
62 std::fprintf(stderr, "Response would overflow response buffer\n");
63 return ::ipmi::responseInvalidCommand();
64 }
65
66 std::vector<std::uint8_t> reply;
67 reply.reserve(bifurcation.size() + sizeof(struct PcieBifurcationReply));
68 reply.emplace_back(bifurcation.size()); /* bifurcationLength */
69 reply.insert(reply.end(), bifurcation.begin(),
Willy Tu1209ccc2023-05-19 00:49:51 -070070 bifurcation.end()); /* bifurcation */
Willy Tu6c71b0f2021-10-10 13:34:41 -070071
72 return ::ipmi::responseSuccess(SysOEMCommands::SysPCIeSlotBifurcation,
73 reply);
74}
75} // namespace ipmi
76} // namespace google