AlexeiFedorov | 9f2de63 | 2024-09-10 11:48:22 +0100 | [diff] [blame] | 1 | /* |
| 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 | |
AlexeiFedorov | 9f2de63 | 2024-09-10 11:48:22 +0100 | [diff] [blame] | 16 | /* |
| 17 | * @brief Returns the BDF Table pointer |
| 18 | * |
| 19 | * @param None |
| 20 | * |
| 21 | * @return BDF Table pointer |
| 22 | */ |
| 23 | pcie_device_bdf_table_t *get_pcie_bdf_table(void) |
| 24 | { |
| 25 | return pcie_get_bdf_table(); |
| 26 | } |
| 27 | |
AlexeiFedorov | 9f2de63 | 2024-09-10 11:48:22 +0100 | [diff] [blame] | 28 | int get_spdm_version(uint32_t bdf, uint32_t doe_cap_base) |
| 29 | { |
| 30 | uint32_t response[SPDM_GET_VERS_RESP_LEN], resp_len; |
| 31 | spdm_version_response_t *ver_resp; |
| 32 | spdm_version_number_t *ver_ptr; |
| 33 | uint8_t entry_count; |
| 34 | int ret; |
| 35 | const spdm_get_version_request_t ver_req = { |
| 36 | { SPDM_MESSAGE_VERSION, SPDM_GET_VERSION, } |
| 37 | }; |
| 38 | |
| 39 | ret = pcie_doe_send_req(DOE_HEADER_1, bdf, doe_cap_base, |
| 40 | (uint32_t *)&ver_req, |
| 41 | sizeof(spdm_get_version_request_t)); |
| 42 | if (ret != 0) { |
| 43 | return ret; |
| 44 | } |
| 45 | |
| 46 | ret = pcie_doe_recv_resp(bdf, doe_cap_base, response, &resp_len); |
| 47 | if (ret != 0) { |
| 48 | return ret; |
| 49 | } |
| 50 | |
| 51 | ver_resp = (spdm_version_response_t *)response; |
| 52 | |
| 53 | if (ver_resp->header.spdm_version != SPDM_MESSAGE_VERSION) { |
| 54 | ERROR("SPDM response v.%u doesn't match requested %u\n", |
| 55 | ver_resp->header.spdm_version, |
| 56 | SPDM_MESSAGE_VERSION); |
| 57 | return -EPROGMISMATCH; |
| 58 | } |
| 59 | |
| 60 | if (ver_resp->header.request_response_code != SPDM_VERSION) { |
| 61 | ERROR("SPDM response code %u doesn't match expected %u\n", |
| 62 | ver_resp->header.request_response_code, |
| 63 | SPDM_VERSION); |
| 64 | return -EBADMSG; |
| 65 | } |
| 66 | |
| 67 | entry_count = ver_resp->version_number_entry_count; |
| 68 | INFO("SPDM version entries: %u\n", entry_count); |
| 69 | |
| 70 | ver_ptr = (spdm_version_number_t *)( |
| 71 | (uintptr_t)&ver_resp->version_number_entry_count + |
| 72 | sizeof(ver_resp->version_number_entry_count)); |
| 73 | |
| 74 | while (entry_count-- != 0) { |
Soby Mathew | 2c2810f | 2024-11-15 17:11:24 +0000 | [diff] [blame] | 75 | spdm_version_number_t ver __unused = *ver_ptr++; |
AlexeiFedorov | 9f2de63 | 2024-09-10 11:48:22 +0100 | [diff] [blame] | 76 | |
| 77 | INFO("SPDM v%llu.%llu.%llu.%llu\n", |
| 78 | EXTRACT(SPDM_VER_MAJOR, ver), |
| 79 | EXTRACT(SPDM_VER_MINOR, ver), |
| 80 | EXTRACT(SPDM_VER_UPDATE, ver), |
| 81 | EXTRACT(SPDM_VER_ALPHA, ver)); |
| 82 | } |
| 83 | return ret; |
| 84 | } |
| 85 | |
| 86 | int doe_discovery(uint32_t bdf, uint32_t doe_cap_base) |
| 87 | { |
| 88 | pcie_doe_disc_req_t request = { 0, }; |
| 89 | pcie_doe_disc_resp_t response; |
Soby Mathew | 5929bfe | 2024-11-28 12:28:00 +0000 | [diff] [blame] | 90 | size_t resp_len; |
AlexeiFedorov | 9f2de63 | 2024-09-10 11:48:22 +0100 | [diff] [blame] | 91 | int ret; |
| 92 | |
| 93 | do { |
Soby Mathew | 5929bfe | 2024-11-28 12:28:00 +0000 | [diff] [blame] | 94 | ret = pcie_doe_communicate(DOE_HEADER_0, bdf, doe_cap_base, |
| 95 | (void *)&request, sizeof(pcie_doe_disc_req_t), |
| 96 | (void *)&response, &resp_len); |
AlexeiFedorov | 9f2de63 | 2024-09-10 11:48:22 +0100 | [diff] [blame] | 97 | |
AlexeiFedorov | 9f2de63 | 2024-09-10 11:48:22 +0100 | [diff] [blame] | 98 | if (ret != 0) { |
| 99 | return ret; |
| 100 | } |
| 101 | |
| 102 | print_doe_disc(&response); |
| 103 | request.index = response.next_index; |
| 104 | |
| 105 | } while (response.next_index != 0); |
| 106 | |
| 107 | return 0; |
| 108 | } |