blob: 911fbd0d6783cbb883dc19f008cf423479ad41e9 [file] [log] [blame]
AlexeiFedorov9f2de632024-09-10 11:48:22 +01001/*
2 * Copyright (c) 2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <errno.h>
8#include <stdbool.h>
9#include <stdlib.h>
10
11#include <debug.h>
12#include <pcie.h>
13#include <pcie_doe.h>
14#include <spdm.h>
15
AlexeiFedorov9f2de632024-09-10 11:48:22 +010016void pcie_init(void)
17{
Soby Mathew2c2810f2024-11-15 17:11:24 +000018 static bool is_init;
19
AlexeiFedorov9f2de632024-09-10 11:48:22 +010020 /* Create PCIe table and enumeration */
Soby Mathew2c2810f2024-11-15 17:11:24 +000021 if (!is_init) {
22 pcie_create_info_table();
23 is_init = true;
24 }
AlexeiFedorov9f2de632024-09-10 11:48:22 +010025}
26
27/*
28 * @brief Returns the BDF Table pointer
29 *
30 * @param None
31 *
32 * @return BDF Table pointer
33 */
34pcie_device_bdf_table_t *get_pcie_bdf_table(void)
35{
36 return pcie_get_bdf_table();
37}
38
39int find_doe_device(uint32_t *bdf_ptr, uint32_t *cap_base_ptr)
40{
41 pcie_device_bdf_table_t *bdf_table_ptr = pcie_get_bdf_table();
42 uint32_t num_bdf = bdf_table_ptr->num_entries;
43
44 INFO("PCI BDF table entries: %u\n", num_bdf);
45
46 /* If no entries in BDF table return error */
47 if (num_bdf == 0) {
48 ERROR("No BDFs entries found\n");
49 return -ENODEV;
50 }
51
52 INFO("PCI BDF table 0x%lx\n", (uintptr_t)bdf_table_ptr);
53
54 while (num_bdf-- != 0) {
55 uint32_t bdf = bdf_table_ptr->device[num_bdf].bdf;
56 uint32_t status, doe_cap_base;
57
58 /* Check for DOE capability */
59 status = pcie_find_capability(bdf, PCIE_ECAP, DOE_CAP_ID, &doe_cap_base);
60 if (status == PCIE_SUCCESS) {
61 INFO("PCIe DOE capability: bdf 0x%x cap_base 0x%x\n", bdf, doe_cap_base);
62 *bdf_ptr = bdf;
63 *cap_base_ptr = doe_cap_base;
64 return 0;
65 }
66 }
67
68 ERROR("No PCIe DOE capability found\n");
69 return -ENODEV;
70}
71
72int get_spdm_version(uint32_t bdf, uint32_t doe_cap_base)
73{
74 uint32_t response[SPDM_GET_VERS_RESP_LEN], resp_len;
75 spdm_version_response_t *ver_resp;
76 spdm_version_number_t *ver_ptr;
77 uint8_t entry_count;
78 int ret;
79 const spdm_get_version_request_t ver_req = {
80 { SPDM_MESSAGE_VERSION, SPDM_GET_VERSION, }
81 };
82
83 ret = pcie_doe_send_req(DOE_HEADER_1, bdf, doe_cap_base,
84 (uint32_t *)&ver_req,
85 sizeof(spdm_get_version_request_t));
86 if (ret != 0) {
87 return ret;
88 }
89
90 ret = pcie_doe_recv_resp(bdf, doe_cap_base, response, &resp_len);
91 if (ret != 0) {
92 return ret;
93 }
94
95 ver_resp = (spdm_version_response_t *)response;
96
97 if (ver_resp->header.spdm_version != SPDM_MESSAGE_VERSION) {
98 ERROR("SPDM response v.%u doesn't match requested %u\n",
99 ver_resp->header.spdm_version,
100 SPDM_MESSAGE_VERSION);
101 return -EPROGMISMATCH;
102 }
103
104 if (ver_resp->header.request_response_code != SPDM_VERSION) {
105 ERROR("SPDM response code %u doesn't match expected %u\n",
106 ver_resp->header.request_response_code,
107 SPDM_VERSION);
108 return -EBADMSG;
109 }
110
111 entry_count = ver_resp->version_number_entry_count;
112 INFO("SPDM version entries: %u\n", entry_count);
113
114 ver_ptr = (spdm_version_number_t *)(
115 (uintptr_t)&ver_resp->version_number_entry_count +
116 sizeof(ver_resp->version_number_entry_count));
117
118 while (entry_count-- != 0) {
Soby Mathew2c2810f2024-11-15 17:11:24 +0000119 spdm_version_number_t ver __unused = *ver_ptr++;
AlexeiFedorov9f2de632024-09-10 11:48:22 +0100120
121 INFO("SPDM v%llu.%llu.%llu.%llu\n",
122 EXTRACT(SPDM_VER_MAJOR, ver),
123 EXTRACT(SPDM_VER_MINOR, ver),
124 EXTRACT(SPDM_VER_UPDATE, ver),
125 EXTRACT(SPDM_VER_ALPHA, ver));
126 }
127 return ret;
128}
129
130int doe_discovery(uint32_t bdf, uint32_t doe_cap_base)
131{
132 pcie_doe_disc_req_t request = { 0, };
133 pcie_doe_disc_resp_t response;
134 uint32_t resp_len;
135 int ret;
136
137 do {
138 ret = pcie_doe_send_req(DOE_HEADER_0, bdf, doe_cap_base,
139 (uint32_t *)&request,
140 sizeof(pcie_doe_disc_req_t));
141 if (ret != 0) {
142 return ret;
143 }
144
145 ret = pcie_doe_recv_resp(bdf, doe_cap_base,
146 (uint32_t *)&response, &resp_len);
147 if (ret != 0) {
148 return ret;
149 }
150
151 print_doe_disc(&response);
152 request.index = response.next_index;
153
154 } while (response.next_index != 0);
155
156 return 0;
157}