blob: 8560ba29b945b3ede8d6bec2616e85595830b4d0 [file] [log] [blame]
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "asset.hpp"
#include "google3/ec_commands.h"
#include "message_util.hpp"
#include <stdplus/print.hpp>
#include <stdplus/raw.hpp>
#include <xyz/openbmc_project/Control/Hoth/error.hpp>
#include <format>
#include <span>
#include <string>
#include <unordered_map>
#include <variant>
#include <vector>
namespace google
{
namespace hoth
{
using sdbusplus::error::xyz::openbmc_project::control::hoth::ResponseFailure;
using internal::EC_RES_SUCCESS;
using internal::HostCommand;
using internal::RspHeader;
namespace
{
constexpr std::string_view kFieldUnknown = "unknown";
constexpr std::string_view kProductNameH1B1P = "H1B1P";
constexpr std::string_view kProductNameH1B2P = "H1B2P";
constexpr std::string_view kProductNameH1D2P = "H1D2P";
constexpr std::string_view kPartNumberH1B1P = "07133954";
constexpr std::string_view kPartNumberH1B2P = "07138244";
constexpr std::string_view kPartNumberH1D2P = "G660-00438-01";
constexpr std::string kManufacturer = "Google";
constexpr std::string kModel = "Titan";
constexpr uint8_t kCryptaMiscCommand = 3;
constexpr uint8_t kCryptaMiscGetCryptaInfoCommand = 0;
std::string_view GetRevisionName(uint16_t hardware_category)
{
switch (hardware_category)
{
case CRYPTA_HW_CAT_HOTH_B1:
return kProductNameH1B1P;
case CRYPTA_HW_CAT_HOTH_B2:
return kProductNameH1B2P;
case CRYPTA_HW_CAT_HOTH_D2:
return kProductNameH1D2P;
default:
return kFieldUnknown;
}
}
std::string_view GetPartNumber(uint16_t hardware_category)
{
switch (hardware_category)
{
case CRYPTA_HW_CAT_HOTH_B1:
return kPartNumberH1B1P;
case CRYPTA_HW_CAT_HOTH_B2:
return kPartNumberH1B2P;
case CRYPTA_HW_CAT_HOTH_D2:
return kPartNumberH1D2P;
default:
return kFieldUnknown;
}
}
std::string GetSerialNumber(const crypta_command_info_hoth_id& hoth_id)
{
return std::format("{}-{:#16x}",
static_cast<uint16_t>(hoth_id.hardware_category),
static_cast<uint64_t>(hoth_id.hardware_id));
}
} // namespace
static ec_response_crypta_info getCryptaInfo(HostCommand* hostCmd)
{
struct ec_request_crypta_info request;
request.major_command = kCryptaMiscCommand;
request.minor_command = kCryptaMiscGetCryptaInfoCommand;
request.param_count = 0;
std::vector<uint8_t> buf = hostCmd->sendCommand(
EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_CRYPTA, 0, &request,
sizeof(request));
// Extract the response header out when returning the span
std::span<const uint8_t> output = buf;
auto& rsp = stdplus::raw::extractRef<RspHeader>(output);
if (rsp.result != EC_RES_SUCCESS)
{
stdplus::print(
stderr,
"Asset Crypta command received a bad response from Hoth {:#x}\n",
static_cast<uint8_t>(rsp.result));
throw ResponseFailure();
}
return stdplus::raw::copyFrom<ec_response_crypta_info>(output);
}
Asset::Asset(sdbusplus::bus::bus& bus, const std::string& objPath,
const std::string& boardPath, HostCommand* hostCmd) :
AssetAssociationObject(bus, objPath.c_str(),
AssetAssociationObject::action::defer_emit),
hostCmd(hostCmd)
{
ec_response_crypta_info response = getCryptaInfo(Asset::hostCmd);
crypta_command_info_hoth_id hoth_id =
response.crypta_info.crypta_id.hoth_id;
/* Set Crypta Properties */
partNumber(std::string(GetPartNumber(hoth_id.hardware_category)), true);
subModel(std::string(GetRevisionName(hoth_id.hardware_category)), true);
serialNumber(GetSerialNumber(hoth_id), true);
manufacturer(kManufacturer, true);
model(kModel, true);
/* Set association with chassis/board object that contains the hoth */
associations({std::make_tuple("chassis", "assembly", boardPath)}, true);
AssetAssociationObject::emit_object_added();
}
} // namespace hoth
} // namespace google