// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2013-2018 IBM Corp. */

#ifndef pr_fmt
#define pr_fmt(fmt) "TPMREL: " fmt
#endif

#include <skiboot.h>
#include <device.h>

#include "spira.h"
#include "hdata.h"
#include "hdif.h"

static void tpmrel_add_firmware_event_log(const struct HDIF_common_hdr *hdif_hdr)
{
	const struct secureboot_tpm_info *stinfo;
	struct dt_node *xscom, *node;
	uint64_t addr;
	int count, i;
	unsigned int asize;

	/* Are the hdat values populated? */
	if (!HDIF_get_idata(hdif_hdr, TPMREL_IDATA_SECUREBOOT_TPM_INFO, &asize))
		return;
	if (asize < sizeof(struct HDIF_array_hdr)) {
		prlog(PR_ERR, "secureboot_tpm_info idata not populated\n");
		return;
	}

	count = HDIF_get_iarray_size(hdif_hdr, TPMREL_IDATA_SECUREBOOT_TPM_INFO);
	if (count > 1) {
		prlog(PR_ERR, "multiple TPM not supported, count=%d\n", count);
		return;
	}

	/*
	 * There can be multiple secureboot_tpm_info entries with each entry
	 * corresponding to a master processor that has a tpm device.
	 * This looks for the tpm node that supposedly exists under the xscom
	 * node associated with the respective chip_id.
	 */
	for (i = 0; i < count; i++) {

		stinfo = HDIF_get_iarray_item(hdif_hdr,
					      TPMREL_IDATA_SECUREBOOT_TPM_INFO,
					      i, NULL);

		/*
		 * If tpm is not present, hostboot creates an empty
		 * secureboot_tpm_info entry, but setting
		 * tpm_status=TPM_NOT_PRESENT
		 */
		if (stinfo->tpm_status == TPM_NOT_PRESENT)
			continue;

		xscom = find_xscom_for_chip(be32_to_cpu(stinfo->chip_id));
		if (xscom) {
			dt_for_each_node(xscom, node) {
				if (dt_has_node_property(node, "label", "tpm"))
					break;
			}

			if (node) {
				addr = (uint64_t) stinfo +
					be32_to_cpu(stinfo->srtm_log_offset);
				dt_add_property_u64s(node, "linux,sml-base", addr);
				dt_add_property_cells(node, "linux,sml-size",
						      be32_to_cpu(stinfo->srtm_log_size));

				if (stinfo->tpm_status == TPM_PRESENT_AND_NOT_FUNCTIONAL)
					dt_add_property_string(node, "status", "disabled");
			} else {
				/**
				 * @fwts-label HDATNoTpmForChipId
				 * @fwts-advice HDAT secureboot_tpm_info
				 * structure described a chip id, but no tpm
				 * node was found under that xscom chip id.
				 * This is most certainly a hostboot bug.
				 */
				prlog(PR_ERR, "TPM node not found for "
				      "chip_id=%d (HB bug)\n", stinfo->chip_id);
				continue;
			}
		} else {
			/**
			 * @fwts-label HDATBadChipIdForTPM
			 * @fwts-advice HDAT secureboot_tpm_info structure
			 * described a chip id, but the xscom node for the
			 * chip_id was not found.
			 * This is most certainly a firmware bug.
			 */
			prlog(PR_ERR, "xscom node not found for chip_id=%d\n",
			      stinfo->chip_id);
			continue;
		}
	}
}

static struct dt_node *get_hb_reserved_memory(const char *label)
{
	struct dt_node *node, *hb_reserved_mem;

	hb_reserved_mem = dt_find_by_path(dt_root, "/ibm,hostboot/reserved-memory");
	if (!hb_reserved_mem) {
		prlog(PR_DEBUG, "/ibm,hostboot/reserved-memory node not found\n");
		return NULL;
	}

	dt_for_each_node(hb_reserved_mem, node) {
		const char *prd_label;
		if (!dt_find_property(node, "ibm,prd-label"))
			continue;
		prd_label = dt_prop_get(node, "ibm,prd-label");
		if (!strcmp(prd_label, label))
			return node;
	}
	return NULL;
}

static struct {
	uint32_t type;
	const char *compat;
} cvc_services[] = {
	{ TPMREL_HV_SHA512, "ibm,cvc-sha512" },
	{ TPMREL_HV_VERIFY, "ibm,cvc-verify" },
};

static const char* cvc_service_map_compat(uint32_t type) {
	int i;
	for (i = 0; i < ARRAY_SIZE(cvc_services); i++) {
		if (cvc_services[i].type == type)
			return cvc_services[i].compat;
	}
	return NULL;
}

static void tpmrel_cvc_init(struct HDIF_common_hdr *hdif_hdr)
{
	struct dt_node *cvc_reserved_mem, *node, *parent;
	int count, i;
	unsigned int asize;

	/* Are the hdat values populated? */
	if (!HDIF_get_idata(hdif_hdr, TPMREL_IDATA_HASH_VERIF_OFFSETS, &asize))
		return;
	if (asize < sizeof(struct HDIF_array_hdr)) {
		prlog(PR_ERR, "hash_and_verification idata not populated\n");
		return;
	}

	node = dt_find_by_path(dt_root, "/ibm,secureboot");
	if (!node)
		return;

	cvc_reserved_mem = get_hb_reserved_memory("secure-crypt-algo-code");
	if (!cvc_reserved_mem) {
		/* Fallback to old style ibm,prd-label */
		cvc_reserved_mem = get_hb_reserved_memory("ibm,secure-crypt-algo-code");
		if (!cvc_reserved_mem) {
			prlog(PR_ERR, "CVC reserved memory not found\n");
			return;
		}
	}

	parent = dt_new(node, "ibm,cvc");
	assert(parent);
	dt_add_property_cells(parent, "#address-cells", 1);
	dt_add_property_cells(parent, "#size-cells", 0);
	dt_add_property_strings(parent, "compatible", "ibm,container-verification-code");
	dt_add_property_cells(parent, "memory-region", cvc_reserved_mem->phandle);

	/*
	 * Initialize each service provided by the container verification code
	 */
	count = HDIF_get_iarray_size(hdif_hdr, TPMREL_IDATA_HASH_VERIF_OFFSETS);
	if (count <= 0 ) {
		prlog(PR_ERR, "no CVC service found\n");
		return;
	}

	for (i = 0; i < count; i++) {
		const struct hash_and_verification *hv;
		uint32_t type, offset, version;
		const char *compat;

		hv = HDIF_get_iarray_item(hdif_hdr,
					  TPMREL_IDATA_HASH_VERIF_OFFSETS,
					  i, NULL);
		type = be32_to_cpu(hv->type);
		offset = be32_to_cpu(hv->offset);
		version = be32_to_cpu(hv->version);

		compat = cvc_service_map_compat(type);

		if (!compat) {
			prlog(PR_WARNING, "CVC service type 0x%x unknown\n", type);
			continue;
		}

		node = dt_new_addr(parent, "ibm,cvc-service", offset);
		dt_add_property_strings(node, "compatible", compat);
		dt_add_property_cells(node, "reg", offset);
		dt_add_property_cells(node, "version", version);
	}
}

void node_stb_parse(void)
{
	struct HDIF_common_hdr *hdif_hdr;

	hdif_hdr = get_hdif(&spira.ntuples.node_stb_data, "TPMREL");
	if (!hdif_hdr) {
		prlog(PR_DEBUG, "TPMREL data not found\n");
		return;
	}

	tpmrel_add_firmware_event_log(hdif_hdr);
	tpmrel_cvc_init(hdif_hdr);
}
