blob: 75f63b6afec47195c3a5e938627b5dd7fd44f438 [file] [log] [blame]
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <debug.h>
#include <pcie.h>
#include <pcie_doe.h>
#include <spdm.h>
/*
* @brief Returns the BDF Table pointer
*
* @param None
*
* @return BDF Table pointer
*/
pcie_device_bdf_table_t *get_pcie_bdf_table(void)
{
return pcie_get_bdf_table();
}
int get_spdm_version(uint32_t bdf, uint32_t doe_cap_base)
{
uint32_t response[SPDM_GET_VERS_RESP_LEN], resp_len;
spdm_version_response_t *ver_resp;
spdm_version_number_t *ver_ptr;
uint8_t entry_count;
int ret;
const spdm_get_version_request_t ver_req = {
{ SPDM_MESSAGE_VERSION, SPDM_GET_VERSION, }
};
ret = pcie_doe_send_req(DOE_HEADER_1, bdf, doe_cap_base,
(uint32_t *)&ver_req,
sizeof(spdm_get_version_request_t));
if (ret != 0) {
return ret;
}
ret = pcie_doe_recv_resp(bdf, doe_cap_base, response, &resp_len);
if (ret != 0) {
return ret;
}
ver_resp = (spdm_version_response_t *)response;
if (ver_resp->header.spdm_version != SPDM_MESSAGE_VERSION) {
ERROR("SPDM response v.%u doesn't match requested %u\n",
ver_resp->header.spdm_version,
SPDM_MESSAGE_VERSION);
return -EPROGMISMATCH;
}
if (ver_resp->header.request_response_code != SPDM_VERSION) {
ERROR("SPDM response code %u doesn't match expected %u\n",
ver_resp->header.request_response_code,
SPDM_VERSION);
return -EBADMSG;
}
entry_count = ver_resp->version_number_entry_count;
INFO("SPDM version entries: %u\n", entry_count);
ver_ptr = (spdm_version_number_t *)(
(uintptr_t)&ver_resp->version_number_entry_count +
sizeof(ver_resp->version_number_entry_count));
while (entry_count-- != 0) {
spdm_version_number_t ver __unused = *ver_ptr++;
INFO("SPDM v%llu.%llu.%llu.%llu\n",
EXTRACT(SPDM_VER_MAJOR, ver),
EXTRACT(SPDM_VER_MINOR, ver),
EXTRACT(SPDM_VER_UPDATE, ver),
EXTRACT(SPDM_VER_ALPHA, ver));
}
return ret;
}
int doe_discovery(uint32_t bdf, uint32_t doe_cap_base)
{
pcie_doe_disc_req_t request = { 0, };
pcie_doe_disc_resp_t response;
size_t resp_len;
int ret;
do {
ret = pcie_doe_communicate(DOE_HEADER_0, bdf, doe_cap_base,
(void *)&request, sizeof(pcie_doe_disc_req_t),
(void *)&response, &resp_len);
if (ret != 0) {
return ret;
}
print_doe_disc(&response);
request.index = response.next_index;
} while (response.next_index != 0);
return 0;
}