[Skiboot] [PATCH 08/14] core/pldm: Update or create terminus locator in the given repo
Christophe Lombard
clombard at linux.vnet.ibm.com
Tue Apr 19 23:46:27 AEST 2022
The Terminus Locator PDR forms the association between a TID and PLDM
Terminus Handle for a terminus.
This patch allows to add terminus locator record in the repository.
If a record matches with the Host TID, we activate the current terminus
locator record, otherwise a new record is created.
Signed-off-by: Christophe Lombard <clombard at linux.vnet.ibm.com>
---
core/pldm/pldm-platform-requests.c | 121 +++++++++++++++++++++++++++++
include/pldm.h | 5 ++
2 files changed, 126 insertions(+)
diff --git a/core/pldm/pldm-platform-requests.c b/core/pldm/pldm-platform-requests.c
index 34ec1335..20715685 100644
--- a/core/pldm/pldm-platform-requests.c
+++ b/core/pldm/pldm-platform-requests.c
@@ -14,6 +14,8 @@
#include "pldm.h"
#define NO_MORE_PDR_HANDLES 0
+#define PDR_AUTO_CALCULATE_RECORD_HANDLE 0
+static bool PDR_IS_NOT_REMOTE;
static pldm_pdr *repo;
static bool pdr_ready;
@@ -54,6 +56,92 @@ int pldm_platform_pdr_find_record(uint32_t record_handle,
return OPAL_SUCCESS;
}
+/*
+ * The Terminus Locator PDR forms the association between a TID and
+ * PLDM Terminus Handle for a terminus.
+ */
+static void generate_terminus_locator_pdr(struct pldm_terminus_locator_pdr *pdr)
+{
+ uint8_t DEFAULT_CONTAINER_ID = 0;
+ struct pldm_terminus_locator_type_mctp_eid *locator_value;
+
+ pdr->hdr.record_handle = 0; /* record_handle will be generated for us */
+ pdr->hdr.version = 1;
+ pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
+ pdr->hdr.record_change_num = 0;
+ pdr->hdr.length = htole16(sizeof(struct pldm_terminus_locator_pdr) -
+ sizeof(struct pldm_pdr_hdr));
+ pdr->terminus_handle = htole16(HOST_TID);
+ pdr->validity = PLDM_TL_PDR_VALID;
+ pdr->tid = HOST_TID;
+ pdr->container_id = DEFAULT_CONTAINER_ID;
+ pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
+ pdr->terminus_locator_value_size = sizeof(struct pldm_terminus_locator_type_mctp_eid);
+ locator_value = (struct pldm_terminus_locator_type_mctp_eid *)pdr->terminus_locator_value;
+ locator_value->eid = HOST_EID;
+}
+
+/*
+ * Add terminus locator record in the repository.
+ */
+static uint32_t add_terminus_locator_pdr(pldm_pdr *repo)
+{
+ struct pldm_terminus_locator_pdr pdr;
+ uint32_t record_handle, size;
+
+ /* New terminus locator record */
+ generate_terminus_locator_pdr(&pdr);
+
+ size = sizeof(struct pldm_terminus_locator_pdr) +
+ sizeof(struct pldm_terminus_locator_type_mctp_eid);
+
+ record_handle = pldm_pdr_add(repo,
+ (const uint8_t *)(&pdr),
+ size,
+ PDR_AUTO_CALCULATE_RECORD_HANDLE,
+ PDR_IS_NOT_REMOTE);
+
+ prlog(PR_DEBUG, "Add terminus locator pdr (record handle: %d)\n", record_handle);
+ return record_handle;
+}
+
+/*
+ * Search the matching record and return the terminus locator record.
+ * PDR type = PLDM_TERMINUS_LOCATOR_PDR
+ */
+static struct pldm_terminus_locator_pdr *find_terminus_locator_pdr(pldm_pdr *repo)
+{
+ struct pldm_terminus_locator_pdr *terminus_locator_pdr = NULL;
+ const pldm_pdr_record *record = NULL;
+ uint16_t terminus_handle;
+ uint8_t *outData = NULL;
+ uint32_t size;
+
+ do {
+ /* Find (first) PDR record by PLDM_STATE_EFFECTER_PDR type
+ * if record not NULL, then search will begin from this
+ * record's next record
+ */
+ record = pldm_pdr_find_record_by_type(
+ repo, /* PDR repo handle */
+ PLDM_TERMINUS_LOCATOR_PDR,
+ record, /* PDR record handle */
+ &outData, &size);
+
+ if (record) {
+ terminus_locator_pdr = (struct pldm_terminus_locator_pdr *)outData;
+
+ terminus_handle = le16_to_cpu(terminus_locator_pdr->terminus_handle);
+
+ if (terminus_handle == HOST_TID)
+ return terminus_locator_pdr;
+ }
+
+ } while (record);
+
+ return NULL;
+}
+
static int send_repository_changed_event(uint32_t num_changed_pdrs,
uint32_t *record_handle)
{
@@ -170,6 +258,39 @@ static int send_repository_changed_event(uint32_t num_changed_pdrs,
return OPAL_SUCCESS;
}
+/*
+ * Update or create terminus locator in the given repo.
+ */
+int pldm_platform_terminus_locator_pdr(void)
+{
+ struct pldm_terminus_locator_pdr *terminus_locator_pdr;
+ uint32_t record_handle;
+ int rc;
+
+ /* find current terminus locator record */
+ terminus_locator_pdr = find_terminus_locator_pdr(repo);
+
+ if (terminus_locator_pdr) {
+ /* activate the current terminus locator record */
+ terminus_locator_pdr->validity = PLDM_TL_PDR_VALID;
+ record_handle = le32_to_cpu(terminus_locator_pdr->hdr.record_handle);
+ } else {
+ /* create a terminus locator record */
+ record_handle = add_terminus_locator_pdr(repo);
+ }
+
+ /* Tell BMC that this PDR has changed */
+ prlog(PR_DEBUG, "%s - Tell BMC that this PDR has changed (record handle: %d)\n",
+ __func__, record_handle);
+
+ rc = send_repository_changed_event(1, &record_handle);
+ if (rc)
+ prlog(PR_ERR, "%s - Failed to update terminux locator PRD\n",
+ __func__);
+
+ return rc;
+}
+
/*
* Search the matching record and return the effecter id.
* PDR type = PLDM_STATE_EFFECTER_PDR
diff --git a/include/pldm.h b/include/pldm.h
index 01af9a33..e2904c41 100644
--- a/include/pldm.h
+++ b/include/pldm.h
@@ -17,6 +17,11 @@ int pldm_mctp_init(void);
*/
void pldm_mctp_exit(void);
+/**
+ * Update or create terminus locator in the given repo
+ */
+int pldm_platform_terminus_locator_pdr(void);
+
/**
* Send a system chassis Off-Soft Graceful request
*/
--
2.35.1
More information about the Skiboot
mailing list