[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