blob: 28b6a86ff90199809f9e5fea7cbbc88d108acc51 [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
16#include <platform_pcie.h>
17
18void pcie_init(void)
19{
20 /* Create PCIe table and enumeration */
21 pcie_create_info_table();
22}
23
24/*
25 * @brief Returns the BDF Table pointer
26 *
27 * @param None
28 *
29 * @return BDF Table pointer
30 */
31pcie_device_bdf_table_t *get_pcie_bdf_table(void)
32{
33 return pcie_get_bdf_table();
34}
35
36int find_doe_device(uint32_t *bdf_ptr, uint32_t *cap_base_ptr)
37{
38 pcie_device_bdf_table_t *bdf_table_ptr = pcie_get_bdf_table();
39 uint32_t num_bdf = bdf_table_ptr->num_entries;
40
41 INFO("PCI BDF table entries: %u\n", num_bdf);
42
43 /* If no entries in BDF table return error */
44 if (num_bdf == 0) {
45 ERROR("No BDFs entries found\n");
46 return -ENODEV;
47 }
48
49 INFO("PCI BDF table 0x%lx\n", (uintptr_t)bdf_table_ptr);
50
51 while (num_bdf-- != 0) {
52 uint32_t bdf = bdf_table_ptr->device[num_bdf].bdf;
53 uint32_t status, doe_cap_base;
54
55 /* Check for DOE capability */
56 status = pcie_find_capability(bdf, PCIE_ECAP, DOE_CAP_ID, &doe_cap_base);
57 if (status == PCIE_SUCCESS) {
58 INFO("PCIe DOE capability: bdf 0x%x cap_base 0x%x\n", bdf, doe_cap_base);
59 *bdf_ptr = bdf;
60 *cap_base_ptr = doe_cap_base;
61 return 0;
62 }
63 }
64
65 ERROR("No PCIe DOE capability found\n");
66 return -ENODEV;
67}
68
69int get_spdm_version(uint32_t bdf, uint32_t doe_cap_base)
70{
71 uint32_t response[SPDM_GET_VERS_RESP_LEN], resp_len;
72 spdm_version_response_t *ver_resp;
73 spdm_version_number_t *ver_ptr;
74 uint8_t entry_count;
75 int ret;
76 const spdm_get_version_request_t ver_req = {
77 { SPDM_MESSAGE_VERSION, SPDM_GET_VERSION, }
78 };
79
80 ret = pcie_doe_send_req(DOE_HEADER_1, bdf, doe_cap_base,
81 (uint32_t *)&ver_req,
82 sizeof(spdm_get_version_request_t));
83 if (ret != 0) {
84 return ret;
85 }
86
87 ret = pcie_doe_recv_resp(bdf, doe_cap_base, response, &resp_len);
88 if (ret != 0) {
89 return ret;
90 }
91
92 ver_resp = (spdm_version_response_t *)response;
93
94 if (ver_resp->header.spdm_version != SPDM_MESSAGE_VERSION) {
95 ERROR("SPDM response v.%u doesn't match requested %u\n",
96 ver_resp->header.spdm_version,
97 SPDM_MESSAGE_VERSION);
98 return -EPROGMISMATCH;
99 }
100
101 if (ver_resp->header.request_response_code != SPDM_VERSION) {
102 ERROR("SPDM response code %u doesn't match expected %u\n",
103 ver_resp->header.request_response_code,
104 SPDM_VERSION);
105 return -EBADMSG;
106 }
107
108 entry_count = ver_resp->version_number_entry_count;
109 INFO("SPDM version entries: %u\n", entry_count);
110
111 ver_ptr = (spdm_version_number_t *)(
112 (uintptr_t)&ver_resp->version_number_entry_count +
113 sizeof(ver_resp->version_number_entry_count));
114
115 while (entry_count-- != 0) {
116 spdm_version_number_t ver = *ver_ptr++;
117
118 INFO("SPDM v%llu.%llu.%llu.%llu\n",
119 EXTRACT(SPDM_VER_MAJOR, ver),
120 EXTRACT(SPDM_VER_MINOR, ver),
121 EXTRACT(SPDM_VER_UPDATE, ver),
122 EXTRACT(SPDM_VER_ALPHA, ver));
123 }
124 return ret;
125}
126
127int doe_discovery(uint32_t bdf, uint32_t doe_cap_base)
128{
129 pcie_doe_disc_req_t request = { 0, };
130 pcie_doe_disc_resp_t response;
131 uint32_t resp_len;
132 int ret;
133
134 do {
135 ret = pcie_doe_send_req(DOE_HEADER_0, bdf, doe_cap_base,
136 (uint32_t *)&request,
137 sizeof(pcie_doe_disc_req_t));
138 if (ret != 0) {
139 return ret;
140 }
141
142 ret = pcie_doe_recv_resp(bdf, doe_cap_base,
143 (uint32_t *)&response, &resp_len);
144 if (ret != 0) {
145 return ret;
146 }
147
148 print_doe_disc(&response);
149 request.index = response.next_index;
150
151 } while (response.next_index != 0);
152
153 return 0;
154}