/* Copyright 2013-2018 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <inttypes.h>
#include <device.h>
#include "spira.h"
#include <cpu.h>
#include <vpd.h>
#include <interrupts.h>
#include <ccan/str/str.h>
#include <chip.h>
#include <fsp-mdst-table.h>
#include <fsp-attn.h>
#include <fsp-leds.h>

#include "hdata.h"
#include "hostservices.h"

/* Processor Initialization structure, contains
 * the initial NIA and MSR values for the entry
 * point
 *
 * Note: It appears to be ignoring the entry point
 *       and always going to 0x180
 */

static int cpu_type;

__section(".procin.data") struct proc_init_data proc_init_data = {
	.hdr = HDIF_SIMPLE_HDR("PROCIN", 1, struct proc_init_data),
	.regs_ptr = HDIF_IDATA_PTR(offsetof(struct proc_init_data, regs), 0x10),
	.regs = {
		.nia = CPU_TO_BE64(0x180),
		.msr = CPU_TO_BE64(0x9000000000000000ULL), /* SF | HV */
	},
};

__section(".cpuctrl.data") struct sp_addr_table cpu_ctl_spat_area;
__section(".cpuctrl.data") struct sp_attn_area cpu_ctl_sp_attn_area1;
__section(".cpuctrl.data") struct sp_attn_area cpu_ctl_sp_attn_area2;
__section(".cpuctrl.data") struct hsr_data_area cpu_ctl_hsr_area;

__section(".cpuctrl.data") struct cpu_ctl_init_data cpu_ctl_init_data = {
	.hdr = HDIF_SIMPLE_HDR(CPU_CTL_HDIF_SIG, 2, struct cpu_ctl_init_data),
	.cpu_ctl = HDIF_IDATA_PTR(offsetof(struct cpu_ctl_init_data, cpu_ctl_lt), sizeof(struct cpu_ctl_legacy_table)),
#if !defined(TEST)
	.cpu_ctl_lt = {
		.spat = {
			.addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_spat_area) + SKIBOOT_BASE),
			.size = CPU_TO_BE64(sizeof(struct sp_addr_table)),
		},
		.sp_attn_area1 = {
			.addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_sp_attn_area1) + SKIBOOT_BASE),
			.size = CPU_TO_BE64(sizeof(struct sp_attn_area)),
		},
		.sp_attn_area2 = {
			.addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_sp_attn_area2) + SKIBOOT_BASE),
			.size = CPU_TO_BE64(sizeof(struct sp_attn_area)),
		},
		.hsr_area = {
			.addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_hsr_area) + SKIBOOT_BASE),
			.size = CPU_TO_BE64(sizeof(struct hsr_data_area)),
		},
	},
#endif
};

/* Populate MDST table
 *
 * Note that we only pass sapphire console buffer here so that we can
 * capture early failure logs. Later dump component (fsp_dump_mdst_init)
 * creates new table with all the memory sections we are interested and
 * sends updated table to FSP via MBOX.
 *
 * To help the FSP distinguishing between TCE tokens and actual physical
 * addresses, we set the top bit to 1 on physical addresses
 */

__section(".mdst.data") struct dump_mdst_table init_mdst_table[2] = {
	{
		.addr = CPU_TO_BE64(INMEM_CON_START | HRMOR_BIT),
		.type = CPU_TO_BE32(DUMP_REGION_CONSOLE),
		.size = CPU_TO_BE32(INMEM_CON_LEN),
	},
	{
		.addr = CPU_TO_BE64(HBRT_CON_START | HRMOR_BIT),
		.type = CPU_TO_BE32(DUMP_REGION_HBRT_LOG),
		.size = CPU_TO_BE32(HBRT_CON_LEN),
	},
};

/* SP Interface Root Array, aka SPIRA */
__section(".spira.data") struct spira spira = {
	.hdr = HDIF_SIMPLE_HDR("SPIRA ", SPIRA_VERSION, struct spira),
	.ntuples_ptr = HDIF_IDATA_PTR(offsetof(struct spira, ntuples),
				      sizeof(struct spira_ntuples)),
	.ntuples = {
		.array_hdr = {
			.offset		= CPU_TO_BE32(HDIF_ARRAY_OFFSET),
			.ecnt		= CPU_TO_BE32(SPIRA_NTUPLES_COUNT),
			.esize
				= CPU_TO_BE32(sizeof(struct spira_ntuple)),
			.eactsz		= CPU_TO_BE32(0x18),
		},
		/* We only populate some n-tuples */
		.proc_init = {
			.addr  		= CPU_TO_BE64(PROCIN_OFF),
			.alloc_cnt	= CPU_TO_BE16(1),
			.act_cnt	= CPU_TO_BE16(1),
			.alloc_len
			= CPU_TO_BE32(sizeof(struct proc_init_data)),
		},
		.heap = {
			.addr		= CPU_TO_BE64(SPIRA_HEAP_BASE),
			.alloc_cnt	= CPU_TO_BE16(1),
			.alloc_len	= CPU_TO_BE32(SPIRA_HEAP_SIZE),
		},
		.mdump_src = {
			.addr		= CPU_TO_BE64(MDST_TABLE_OFF),
			.alloc_cnt	= CPU_TO_BE16(ARRAY_SIZE(init_mdst_table)),
			.act_cnt	= CPU_TO_BE16(ARRAY_SIZE(init_mdst_table)),
			.alloc_len	=
				CPU_TO_BE32(sizeof(init_mdst_table)),
		},
#if !defined(TEST)
		.cpu_ctrl = {
			.addr		= CPU_TO_BE64((unsigned long)&cpu_ctl_init_data),
			.alloc_cnt	= CPU_TO_BE16(1),
			.act_cnt	= CPU_TO_BE16(1),
			.alloc_len	=
					CPU_TO_BE32(sizeof(cpu_ctl_init_data)),
		},
#endif
	},
};

/* The Hypervisor SPIRA-H Structure */
__section(".spirah.data") struct spirah spirah = {
	.hdr = HDIF_SIMPLE_HDR(SPIRAH_HDIF_SIG, SPIRAH_VERSION, struct spirah),
	.ntuples_ptr = HDIF_IDATA_PTR(offsetof(struct spirah, ntuples),
				      sizeof(struct spirah_ntuples)),
	.ntuples = {
		.array_hdr = {
			.offset		= CPU_TO_BE32(HDIF_ARRAY_OFFSET),
			.ecnt		= CPU_TO_BE32(SPIRAH_NTUPLES_COUNT),
			.esize
				= CPU_TO_BE32(sizeof(struct spira_ntuple)),
			.eactsz		= CPU_TO_BE32(0x18),
		},
		/* Host Data Areas */
		.hs_data_area = {
			.addr		= CPU_TO_BE64(SPIRA_HEAP_BASE),
			.alloc_cnt	= CPU_TO_BE16(1),
			.alloc_len	= CPU_TO_BE32(SPIRA_HEAP_SIZE),
		},
		/* We only populate some n-tuples */
		.proc_init = {
			.addr		= CPU_TO_BE64(PROCIN_OFF),
			.alloc_cnt	= CPU_TO_BE16(1),
			.act_cnt	= CPU_TO_BE16(1),
			.alloc_len
			= CPU_TO_BE32(sizeof(struct proc_init_data)),
		},
#if !defined(TEST)
		.cpu_ctrl = {
			.addr		= CPU_TO_BE64((unsigned long)&cpu_ctl_init_data),
			.alloc_cnt	= CPU_TO_BE16(1),
			.act_cnt	= CPU_TO_BE16(1),
			.alloc_len	=
					CPU_TO_BE32(sizeof(cpu_ctl_init_data)),
		},
#endif
		.mdump_src = {
			.addr		= CPU_TO_BE64(MDST_TABLE_OFF),
			.alloc_cnt	= CPU_TO_BE16(ARRAY_SIZE(init_mdst_table)),
			.act_cnt	= CPU_TO_BE16(ARRAY_SIZE(init_mdst_table)),
			.alloc_len	=
				CPU_TO_BE32(sizeof(init_mdst_table)),
		},
	},
};

/* The service processor SPIRA-S structure */
struct spiras *spiras;

/* Overridden for testing. */
#ifndef spira_check_ptr
bool spira_check_ptr(const void *ptr, const char *file, unsigned int line)
{
	if (!ptr)
		return false;
	if (((unsigned long)ptr) >= SPIRA_HEAP_BASE &&
	    ((unsigned long)ptr) < (SPIRA_HEAP_BASE + SPIRA_HEAP_SIZE))
		return true;

	prerror("SPIRA: Bad pointer %p at %s line %d\n", ptr, file, line);
	return false;
}
#endif

struct HDIF_common_hdr *__get_hdif(struct spira_ntuple *n, const char id[],
				   const char *file, int line)
{
	struct HDIF_common_hdr *h = ntuple_addr(n);
	if (!spira_check_ptr(h, file, line))
		return NULL;

	if (!HDIF_check(h, id)) {
		prerror("SPIRA: bad tuple %p: expected %s at %s line %d\n",
			h, id, file, line);
		return NULL;
	}
	return h;
}

static struct dt_node *add_xscom_node(uint64_t base, uint32_t hw_id,
				      uint32_t proc_chip_id)
{
	struct dt_node *node;
	uint64_t addr, size;
	uint64_t freq;

	switch (proc_gen) {
	case proc_gen_p7:
	case proc_gen_p8:
		/* On P7 and P8 all the chip SCOMs share single region */
		addr = base | ((uint64_t)hw_id << PPC_BITLSHIFT(28));
		break;
	case proc_gen_p9:
	default:
		/* On P9 we need to put the chip ID in the natural powerbus
		 * position.
		 */
		addr = base | (((uint64_t)hw_id) << 42);
		break;
	};

	size = (u64)1 << PPC_BITLSHIFT(28);

	prlog(PR_INFO, "XSCOM: Found HW ID 0x%x (PCID 0x%x) @ 0x%llx\n",
	       hw_id, proc_chip_id, (long long)addr);

	node = dt_new_addr(dt_root, "xscom", addr);
	if (!node)
		return NULL;

	dt_add_property_cells(node, "ibm,chip-id", hw_id);
	dt_add_property_cells(node, "ibm,proc-chip-id", proc_chip_id);
	dt_add_property_cells(node, "#address-cells", 1);
	dt_add_property_cells(node, "#size-cells", 1);
	dt_add_property(node, "scom-controller", NULL, 0);

	switch(proc_gen) {
	case proc_gen_p7:
		dt_add_property_strings(node, "compatible",
					"ibm,xscom", "ibm,power7-xscom");
		break;
	case proc_gen_p8:
		dt_add_property_strings(node, "compatible",
					"ibm,xscom", "ibm,power8-xscom");
		break;
	case proc_gen_p9:
		dt_add_property_strings(node, "compatible",
					"ibm,xscom", "ibm,power9-xscom");
		break;
	default:
		dt_add_property_strings(node, "compatible", "ibm,xscom");
	}
	dt_add_property_u64s(node, "reg", addr, size);

	/* Derive bus frquency */
	freq = dt_prop_get_u64_def(dt_root, "nest-frequency", 0);
	freq /= 4;
	if (freq)
		dt_add_property_u64(node, "bus-frequency", freq);

	return node;
}

/*
 * Given a xscom@ node this will return a pointer into the SPPCRD
 * structure corresponding to that node
 */
#define GET_HDIF_HDR -1
static const void *xscom_to_pcrd(struct dt_node *xscom, int idata_index)
{
	struct spira_ntuple *t = &spira.ntuples.proc_chip;
	const struct HDIF_common_hdr *hdif;
	const void *idata;
	unsigned int size;
	uint32_t i;
	void *base;

	i = dt_prop_get_u32_def(xscom, DT_PRIVATE "sppcrd-index", 0xffffffff);
	if (i == 0xffffffff)
		return NULL;

	base = get_hdif(t, "SPPCRD");
	assert(base);
	assert(i < be16_to_cpu(t->act_cnt));

	hdif = base + i * be32_to_cpu(t->alloc_len);
	assert(hdif);

	if (idata_index == GET_HDIF_HDR)
		return hdif;

	idata = HDIF_get_idata(hdif, idata_index, &size);
	if (!idata || !size)
		return NULL;

	return idata;
}

struct dt_node *find_xscom_for_chip(uint32_t chip_id)
{
	struct dt_node *node;
	uint32_t id;

	dt_for_each_compatible(dt_root, node, "ibm,xscom") {
		id = dt_get_chip_id(node);
		if (id == chip_id)
			return node;
	}

	return NULL;
}

static void add_psihb_node(struct dt_node *np)
{
	u32 psi_scom, psi_slen;
	const char *psi_comp;

	/*
	 * We add a few things under XSCOM that aren't added
	 * by any other HDAT path
	 */

	/* PSI host bridge */
	switch(proc_gen) {
	case proc_gen_p7:
		psi_scom = 0x2010c00;
		psi_slen = 0x10;
		psi_comp = "ibm,power7-psihb-x";
		break;
	case proc_gen_p8:
		psi_scom = 0x2010900;
		psi_slen = 0x20;
		psi_comp = "ibm,power8-psihb-x";
		break;
	case proc_gen_p9:
		psi_scom = 0x5012900;
		psi_slen = 0x100;
		psi_comp = "ibm,power9-psihb-x";
		break;
	default:
		psi_comp = NULL;
	}
	if (psi_comp) {
		struct dt_node *psi_np;

		psi_np = dt_new_addr(np, "psihb", psi_scom);
		if (!psi_np)
			return;

		dt_add_property_cells(psi_np, "reg", psi_scom, psi_slen);
		dt_add_property_strings(psi_np, "compatible", psi_comp,
					"ibm,psihb-x");
	}
}

static void add_xive_node(struct dt_node *np)
{
	struct dt_node *xive = dt_new_addr(np, "xive", 0x5013000);

	dt_add_property_cells(xive, "reg", 0x5013000, 0x300);
	dt_add_property_string(xive, "compatible", "ibm,power9-xive-x");

	/* HACK: required for simics */
	dt_add_property(xive, "force-assign-bars", NULL, 0);
}

/*
 * SCOM Base Address from P9 SCOM Assignment spreadsheet
 */
#define VAS_SCOM_BASE_ADDR		0x03011800

static void add_vas_node(struct dt_node *np, int idx)
{
	struct  dt_node *vas = dt_new_addr(np, "vas", VAS_SCOM_BASE_ADDR);

	dt_add_property_cells(vas, "reg", VAS_SCOM_BASE_ADDR, 0x300);
	dt_add_property_string(vas, "compatible", "ibm,power9-vas-x");
	dt_add_property_cells(vas, "ibm,vas-id", idx);
}

static void add_ecid_data(const struct HDIF_common_hdr *hdr,
			  struct dt_node *xscom)
{
	char wafer_id[11];
	uint8_t tmp;
	int i;
	uint32_t size = 0;
	struct sppcrd_ecid *ecid;
	const struct HDIF_array_hdr *ec_hdr;

	ec_hdr = HDIF_get_idata(hdr, SPPCRD_IDATA_EC_LEVEL, &size);
	if (!ec_hdr || !size)
		return;

	ecid = (void *)ec_hdr + be32_to_cpu(ec_hdr->offset);
	dt_add_property_u64s(xscom, "ecid", be64_to_cpu(ecid->low),
			     be64_to_cpu(ecid->high));

	/*
	 * bits 4:63 of ECID data contains wafter ID data (ten 6 bit fields
	 * each containing a code).
	 */
	for (i = 0; i < 10; i++) {
		tmp = (u8)((be64_to_cpu(ecid->low) >> (i * 6)) & 0x3f);
		if (tmp <= 9)
			wafer_id[9 - i] = tmp + '0';
		else if (tmp >= 0xA && tmp <= 0x23)
			wafer_id[9 - i] = tmp + '0' + 7;
		else if (tmp == 0x3D)
			wafer_id[9 - i] = '-';
		else if (tmp == 0x3E)
			wafer_id[9 - i] = '.';
		else if (tmp == 0x3F)
			wafer_id[9 - i] = ' ';
		else /* Unknown code */
			wafer_id[9 - i] = tmp + '0';
	}
	wafer_id[10] = '\0';
	dt_add_property_nstr(xscom, "wafer-id", wafer_id, 10);

	dt_add_property_cells(xscom, "wafer-location",
			      (u32)((be64_to_cpu(ecid->high) >> 56) & 0xff),
			      (u32)((be64_to_cpu(ecid->high) >> 48) & 0xff));
}

static void add_xscom_add_pcia_assoc(struct dt_node *np, uint32_t pcid)
{
	const struct HDIF_common_hdr *hdr;
	u32 size;


	/*
	 * The SPPCRD doesn't contain all the affinity data, we have
	 * to dig it out of a core. I assume this is so that node
	 * affinity can be different for groups of cores within the
	 * chip, but for now we are going to ignore that
	 */
	hdr = get_hdif(&spira.ntuples.pcia, SPPCIA_HDIF_SIG);
	if (!hdr)
		return;

	for_each_pcia(hdr) {
		const struct sppcia_core_unique *id;

		id = HDIF_get_idata(hdr, SPPCIA_IDATA_CORE_UNIQUE, &size);
		if (!id || size < sizeof(*id))
			continue;

		if (be32_to_cpu(id->proc_chip_id) != pcid)
			continue;

		dt_add_property_cells(np, "ibm,ccm-node-id",
				      be32_to_cpu(id->ccm_node_id));
		dt_add_property_cells(np, "ibm,hw-card-id",
				      be32_to_cpu(id->hw_card_id));
		dt_add_property_cells(np, "ibm,hw-module-id",
				      be32_to_cpu(id->hw_module_id));
		if (!dt_find_property(np, "ibm,dbob-id"))
			dt_add_property_cells(np, "ibm,dbob-id",
				  be32_to_cpu(id->drawer_book_octant_blade_id));
		if (proc_gen < proc_gen_p9) {
			dt_add_property_cells(np, "ibm,mem-interleave-scope",
			          be32_to_cpu(id->memory_interleaving_scope));
		}
		return;
	}
}

static bool add_xscom_sppcrd(uint64_t xscom_base)
{
	const struct HDIF_common_hdr *hdif;
	unsigned int i, vpd_sz;
	const void *vpd;
	struct dt_node *np, *vpd_node;

	for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
			    SPPCRD_HDIF_SIG) {
		const struct sppcrd_chip_info *cinfo;
		const struct spira_fru_id *fru_id = NULL;
		unsigned int csize;
		u32 ve, version;

		cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, &csize);
		if (!CHECK_SPPTR(cinfo)) {
			prerror("XSCOM: Bad ChipID data %d\n", i);
			continue;
		}

		ve = be32_to_cpu(cinfo->verif_exist_flags) & CHIP_VERIFY_MASK;
		ve >>= CHIP_VERIFY_SHIFT;
		if (ve == CHIP_VERIFY_NOT_INSTALLED ||
		    ve == CHIP_VERIFY_UNUSABLE)
			continue;

		/* Create the XSCOM node */
		np = add_xscom_node(xscom_base,
				    be32_to_cpu(cinfo->xscom_id),
				    be32_to_cpu(cinfo->proc_chip_id));
		if (!np)
			continue;


		dt_add_property_cells(np, DT_PRIVATE "sppcrd-index", i);

		version = be16_to_cpu(hdif->version);

		/* Version 0A has additional OCC related stuff */
		if (version >= 0x000a) {
			if (!dt_find_property(np, "ibm,dbob-id"))
				dt_add_property_cells(np, "ibm,dbob-id",
					be32_to_cpu(cinfo->dbob_id));
			dt_add_property_cells(np, "ibm,occ-functional-state",
					      be32_to_cpu(cinfo->occ_state));
		}

		/* Add chip VPD */
		vpd_node = dt_add_vpd_node(hdif, SPPCRD_IDATA_FRU_ID,
					   SPPCRD_IDATA_KW_VPD);
		if (vpd_node)
			dt_add_property_cells(vpd_node, "ibm,chip-id",
					      be32_to_cpu(cinfo->xscom_id));

		fru_id = HDIF_get_idata(hdif, SPPCRD_IDATA_FRU_ID, NULL);
		if (fru_id)
			slca_vpd_add_loc_code(np, be16_to_cpu(fru_id->slca_index));

		/* Add module VPD on version A and later */
		if (version >= 0x000a) {
			vpd = HDIF_get_idata(hdif, SPPCRD_IDATA_MODULE_VPD,
					     &vpd_sz);
			if (CHECK_SPPTR(vpd)) {
				dt_add_property(np, "ibm,module-vpd", vpd,
						vpd_sz);
				vpd_data_parse(np, vpd, vpd_sz);
				if (vpd_node)
					dt_add_proc_vendor(vpd_node, vpd, vpd_sz);
			}
		}

		/*
		 * Extract additional associativity information from
		 * the core data. Pick one core on that chip
		 */
		add_xscom_add_pcia_assoc(np, be32_to_cpu(cinfo->proc_chip_id));

		/* Add PSI Host bridge */
		add_psihb_node(np);

		if (proc_gen >= proc_gen_p9) {
			add_xive_node(np);
			parse_i2c_devs(hdif, SPPCRD_IDATA_HOST_I2C, np);
			add_vas_node(np, i);
			add_ecid_data(hdif, np);

			if (be32_to_cpu(cinfo->verif_exist_flags) & CHIP_VERIFY_MASTER_PROC)
				dt_add_property(np, "primary", NULL, 0);
		}

		/*
		 * Add sw checkstop scom address (ibm,sw-checkstop-fir)
		 *
		 * The latest HDAT versions have sw checkstop scom address
		 * info.  But not sure from which version onwards (at least
		 * HDAT spec do not mention that explicitly). Hence use the
		 * sppcrd struct size returned by HDIF_get_idata to figure out
		 * whether it contains sw checkstop scom address info. Also
		 * check if sw_xstop_fir_scom address is non-zero.
		 */
		if ((csize >= (offsetof(struct sppcrd_chip_info,
					sw_xstop_fir_bitpos) + 1)) &&
						cinfo->sw_xstop_fir_scom) {
			__be32 fir_bit = cinfo->sw_xstop_fir_bitpos;

			if (!dt_find_property(dt_root, "ibm,sw-checkstop-fir"))
				dt_add_property_cells(dt_root,
					"ibm,sw-checkstop-fir",
					be32_to_cpu(cinfo->sw_xstop_fir_scom),
					be32_to_cpu(fir_bit));
		}
	}

	return i > 0;
}

static void add_xscom_sppaca(uint64_t xscom_base)
{
	const struct HDIF_common_hdr *hdif;
	unsigned int i;
	struct dt_node *np, *vpd_node;

	for_each_ntuple_idx(&spira.ntuples.paca, hdif, i, PACA_HDIF_SIG) {
		const struct sppaca_cpu_id *id;
		unsigned int chip_id, size;
		int ve;

		/* We only suport old style PACA on P7 ! */
		assert(proc_gen == proc_gen_p7);

		id = HDIF_get_idata(hdif, SPPACA_IDATA_CPU_ID, &size);

		if (!CHECK_SPPTR(id)) {
			prerror("XSCOM: Bad processor data %d\n", i);
			continue;
		}

		ve = be32_to_cpu(id->verify_exists_flags) & CPU_ID_VERIFY_MASK;
		ve >>= CPU_ID_VERIFY_SHIFT;
		if (ve == CPU_ID_VERIFY_NOT_INSTALLED ||
		    ve == CPU_ID_VERIFY_UNUSABLE)
			continue;

		/* Convert to HW chip ID */
		chip_id = P7_PIR2GCID(be32_to_cpu(id->pir));

		/* do we already have an XSCOM for this chip? */
		if (find_xscom_for_chip(chip_id))
			continue;

		/* Create the XSCOM node */
		np = add_xscom_node(xscom_base, chip_id,
				    be32_to_cpu(id->processor_chip_id));
		if (!np)
			continue;

		/* Add chip VPD */
		vpd_node = dt_add_vpd_node(hdif, SPPACA_IDATA_FRU_ID,
					   SPPACA_IDATA_KW_VPD);
		if (vpd_node)
			dt_add_property_cells(vpd_node, "ibm,chip-id", chip_id);

		/* Add chip associativity data */
		dt_add_property_cells(np, "ibm,ccm-node-id",
				      be32_to_cpu(id->ccm_node_id));
		if (size > SPIRA_CPU_ID_MIN_SIZE) {
			dt_add_property_cells(np, "ibm,hw-card-id",
					      be32_to_cpu(id->hw_card_id));
			dt_add_property_cells(np, "ibm,hw-module-id",
					  be32_to_cpu(id->hardware_module_id));
			if (!dt_find_property(np, "ibm,dbob-id"))
				dt_add_property_cells(np, "ibm,dbob-id",
				  be32_to_cpu(id->drawer_book_octant_blade_id));
			dt_add_property_cells(np, "ibm,mem-interleave-scope",
				 be32_to_cpu(id->memory_interleaving_scope));
		}

		/* Add PSI Host bridge */
		add_psihb_node(np);
	}
}

static void add_xscom(void)
{
	const void *ms_vpd;
	const struct msvpd_pmover_bsr_synchro *pmbs;
	unsigned int size;
	uint64_t xscom_base;

	ms_vpd = get_hdif(&spira.ntuples.ms_vpd, MSVPD_HDIF_SIG);
	if (!ms_vpd) {
		prerror("XSCOM: Can't find MS VPD\n");
		return;
	}

	pmbs = HDIF_get_idata(ms_vpd, MSVPD_IDATA_PMOVER_SYNCHRO, &size);
	if (!CHECK_SPPTR(pmbs) || size < sizeof(*pmbs)) {
		prerror("XSCOM: absent or bad PMBS size %u @ %p\n", size, pmbs);
		return;
	}

	if (!(be32_to_cpu(pmbs->flags) & MSVPD_PMS_FLAG_XSCOMBASE_VALID)) {
		prerror("XSCOM: No XSCOM base in PMBS, using default\n");
		return;
	}

	xscom_base = be64_to_cpu(pmbs->xscom_addr);

	/* Some FSP (on P7) give me a crap base address for XSCOM (it has
	 * spurious bits set as far as I can tell). Since only 5 bits 18:22 can
	 * be programmed in hardware, let's isolate these. This seems to give
	 * me the right value on VPL1
	 */
	if (cpu_type == PVR_TYPE_P7)
		xscom_base &= 0x80003e0000000000ul;

	/* Get rid of the top bits */
	xscom_base = cleanup_addr(xscom_base);

	/* First, try the new proc_chip ntuples for chip data */
	if (add_xscom_sppcrd(xscom_base))
		return;

	/* Otherwise, check the old-style PACA, looking for unique chips */
	add_xscom_sppaca(xscom_base);
}

static void add_chiptod_node(unsigned int chip_id, int flags)
{
	struct dt_node *node, *xscom_node;
	const char *compat_str;
	uint32_t addr, len;

	if ((flags & CHIPTOD_ID_FLAGS_STATUS_MASK) !=
			CHIPTOD_ID_FLAGS_STATUS_OK)
		return;

	xscom_node = find_xscom_for_chip(chip_id);
	if (!xscom_node) {
		prerror("CHIPTOD: No xscom for chiptod %d?\n", chip_id);
		return;
	}

	addr = 0x40000;
	len = 0x34;

	switch(proc_gen) {
	case proc_gen_p7:
		compat_str = "ibm,power7-chiptod";
		break;
	case proc_gen_p8:
		compat_str = "ibm,power8-chiptod";
		break;
	case proc_gen_p9:
		compat_str = "ibm,power9-chiptod";
		break;
	default:
		return;
	}

	prlog(PR_DEBUG, "CHIPTOD: Found on chip 0x%x %s\n", chip_id,
	      (flags & CHIPTOD_ID_FLAGS_PRIMARY) ? "[primary]" :
	      ((flags & CHIPTOD_ID_FLAGS_SECONDARY) ? "[secondary]" : ""));

	node = dt_new_addr(xscom_node, "chiptod", addr);
	if (!node)
		return;

	dt_add_property_cells(node, "reg", addr, len);
	dt_add_property_strings(node, "compatible", "ibm,power-chiptod",
			       compat_str);

	if (flags & CHIPTOD_ID_FLAGS_PRIMARY)
		dt_add_property(node, "primary", NULL, 0);
	if (flags & CHIPTOD_ID_FLAGS_SECONDARY)
		dt_add_property(node, "secondary", NULL, 0);
}

static bool add_chiptod_old(void)
{
	const void *hdif;
	unsigned int i;
	bool found = false;

	/*
	 * Locate chiptod ID structures in SPIRA
	 */
	if (!get_hdif(&spira.ntuples.chip_tod, "TOD   "))
		return found;

	for_each_ntuple_idx(&spira.ntuples.chip_tod, hdif, i, "TOD   ") {
		const struct chiptod_chipid *id;

		id = HDIF_get_idata(hdif, CHIPTOD_IDATA_CHIPID, NULL);
		if (!CHECK_SPPTR(id)) {
			prerror("CHIPTOD: Bad ChipID data %d\n", i);
			continue;
		}

		add_chiptod_node(pcid_to_chip_id(be32_to_cpu(id->chip_id)),
				 be32_to_cpu(id->flags));
		found = true;
	}
	return found;
}

static bool add_chiptod_new(void)
{
	const void *hdif;
	unsigned int i;
	bool found = false;

	/*
	 * Locate Proc Chip ID structures in SPIRA
	 */
	if (!get_hdif(&spira.ntuples.proc_chip, SPPCRD_HDIF_SIG))
		return found;

	for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
			    SPPCRD_HDIF_SIG) {
		const struct sppcrd_chip_info *cinfo;
		const struct sppcrd_chip_tod *tinfo;
		unsigned int size;
		u32 ve, flags;

		cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
		if (!CHECK_SPPTR(cinfo)) {
			prerror("CHIPTOD: Bad ChipID data %d\n", i);
			continue;
		}

		ve = be32_to_cpu(cinfo->verif_exist_flags) & CHIP_VERIFY_MASK;
		ve >>= CHIP_VERIFY_SHIFT;
		if (ve == CHIP_VERIFY_NOT_INSTALLED ||
		    ve == CHIP_VERIFY_UNUSABLE)
			continue;

		tinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_TOD, &size);
		if (!CHECK_SPPTR(tinfo)) {
			prerror("CHIPTOD: Bad TOD data %d\n", i);
			continue;
		}

		flags = be32_to_cpu(tinfo->flags);

		/* The FSP may strip the chiptod info from HDAT; if we find
		 * a zero-ed out entry, assume that the chiptod is
		 * present, but we don't have any primary/secondary info. In
		 * this case, pick chip zero as the master.
		 */
		if (!size) {
			flags = CHIPTOD_ID_FLAGS_STATUS_OK;
			if (be32_to_cpu(cinfo->xscom_id) == 0x0)
				flags |= CHIPTOD_ID_FLAGS_PRIMARY;
		}

		add_chiptod_node(be32_to_cpu(cinfo->xscom_id), flags);
		found = true;
	}
	return found;
}

static void add_nx_node(u32 gcid)
{
	struct dt_node *nx;
	u32 addr;
	u32 size;
	struct dt_node *xscom;

	xscom = find_xscom_for_chip(gcid);
	if (xscom == NULL) {
		prerror("NX%d: did not found xscom node.\n", gcid);
		return;
	}

	/*
	 * The NX register space is relatively self contained on P7+ but
	 * a bit more messy on P8. However it's all contained within the
	 * PB chiplet port 1 so we'll stick to that in the "reg" property
	 * and let the NX "driver" deal with the details.
	 */
	addr = 0x2010000;
	size = 0x0004000;

	nx = dt_new_addr(xscom, "nx", addr);
	if (!nx)
		return;

	switch (proc_gen) {
	case proc_gen_p7:
		dt_add_property_strings(nx, "compatible", "ibm,power-nx",
					"ibm,power7-nx");
		break;
	case proc_gen_p8:
		dt_add_property_strings(nx, "compatible", "ibm,power-nx",
					"ibm,power8-nx");
		break;
	case proc_gen_p9:
		/* POWER9 NX is not software compatible with P7/P8 NX */
		dt_add_property_strings(nx, "compatible", "ibm,power9-nx");
		break;
	default:
		return;
	}

	dt_add_property_cells(nx, "reg", addr, size);
}

static void add_nx(void)
{
	unsigned int i;
	void *hdif;

	for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
			SPPCRD_HDIF_SIG) {
		const struct sppcrd_chip_info *cinfo;
		u32 ve;

		cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
		if (!CHECK_SPPTR(cinfo)) {
			prerror("NX: Bad ChipID data %d\n", i);
			continue;
		}

		ve = be32_to_cpu(cinfo->verif_exist_flags) & CHIP_VERIFY_MASK;
		ve >>= CHIP_VERIFY_SHIFT;
		if (ve == CHIP_VERIFY_NOT_INSTALLED ||
				ve == CHIP_VERIFY_UNUSABLE)
			continue;

		if (cinfo->nx_state)
			add_nx_node(be32_to_cpu(cinfo->xscom_id));
	}
}

static void add_nmmu(void)
{
	struct dt_node *xscom, *nmmu;

	/* Nest MMU only exists on POWER9 */
	if (proc_gen != proc_gen_p9)
		return;

	dt_for_each_compatible(dt_root, xscom, "ibm,xscom") {
		nmmu = dt_new_addr(xscom, "nmmu", 0x5012c40);
		dt_add_property_strings(nmmu, "compatible", "ibm,power9-nest-mmu");
		dt_add_property_cells(nmmu, "reg", 0x5012c40, 0x20);
	}
}

static void dt_init_secureboot_node(const struct iplparams_sysparams *sysparams)
{
	struct dt_node *node;
	u16 sys_sec_setting;
	u16 hw_key_hash_size;

	node = dt_new(dt_root, "ibm,secureboot");
	assert(node);

	dt_add_property_string(node, "compatible", "ibm,secureboot-v2");

	sys_sec_setting = be16_to_cpu(sysparams->sys_sec_setting);
	if (sys_sec_setting & SEC_CONTAINER_SIG_CHECKING)
		dt_add_property(node, "secure-enabled", NULL, 0);
	if (sys_sec_setting & SEC_HASHES_EXTENDED_TO_TPM)
		dt_add_property(node, "trusted-enabled", NULL, 0);

	hw_key_hash_size = be16_to_cpu(sysparams->hw_key_hash_size);

	/* Prevent hw-key-hash buffer overflow by truncating hw-key-hash-size if
	 * it is bigger than the hw-key-hash buffer.
	 * Secure boot will be enforced later in skiboot, if the hw-key-hash-size
	 * was not supposed to be SYSPARAMS_HW_KEY_HASH_MAX.
	 */
	if (hw_key_hash_size > SYSPARAMS_HW_KEY_HASH_MAX) {
		prlog(PR_ERR, "IPLPARAMS: hw-key-hash-size=%d too big, "
		      "truncating to %d\n", hw_key_hash_size,
		      SYSPARAMS_HW_KEY_HASH_MAX);
		hw_key_hash_size = SYSPARAMS_HW_KEY_HASH_MAX;
	}

	dt_add_property(node, "hw-key-hash", sysparams->hw_key_hash,
			hw_key_hash_size);
	dt_add_property_cells(node, "hw-key-hash-size", hw_key_hash_size);
}

static void add_iplparams_sys_params(const void *iplp, struct dt_node *node)
{
	const struct iplparams_sysparams *p;
	const struct HDIF_common_hdr *hdif = iplp;
	u16 version = be16_to_cpu(hdif->version);
	const char *vendor = NULL;
	u32 sys_attributes;

	p = HDIF_get_idata(iplp, IPLPARAMS_SYSPARAMS, NULL);
	if (!CHECK_SPPTR(p)) {
		prerror("IPLPARAMS: No SYS Parameters\n");
		/* Create a generic compatible property */
		dt_add_property_string(dt_root, "compatible", "ibm,powernv");
		return;
	}

	node = dt_new(node, "sys-params");
	assert(node);
	dt_add_property_cells(node, "#address-cells", 0);
	dt_add_property_cells(node, "#size-cells", 0);

	dt_add_property_nstr(node, "ibm,sys-model", p->sys_model, 4);

	/*
	 * Compatible has up to three entries:
	 *	"ibm,powernv", the system family and system type.
	 *
	 * On P9 and above the family and type strings come from the HDAT
	 * directly. On P8 we find it from the system ID numbers.
	 */
	if (proc_gen >= proc_gen_p9) {
		dt_add_property_strings(dt_root, "compatible", "ibm,powernv",
					p->sys_family_str, p->sys_type_str);

		prlog(PR_INFO, "IPLPARAMS: v0x70 Platform family/type: %s/%s\n",
		      p->sys_family_str, p->sys_type_str);
	} else {
		u32 sys_type = be32_to_cpu(p->system_type);
		const char *sys_family;

		switch (sys_type >> 28) {
		case 0:
			sys_family = "ibm,squadrons";
			break;
		case 1:
			sys_family = "ibm,eclipz";
			break;
		case 2:
			sys_family = "ibm,apollo";
			break;
		case 3:
			sys_family = "ibm,firenze";
			break;
		default:
			sys_family = NULL;
			prerror("IPLPARAMS: Unknown system family\n");
			break;
		}

		dt_add_property_strings(dt_root, "compatible", "ibm,powernv",
					sys_family);
		prlog(PR_INFO,
		      "IPLPARAMS: Legacy platform family: %s"
		      " (sys_type=0x%08x)\n", sys_family, sys_type);
	}

	/* Grab nest frequency when available */
	if (version >= 0x005b) {
		u64 freq = be32_to_cpu(p->nest_freq_mhz);

		freq *= 1000000;
		dt_add_property_u64(dt_root, "nest-frequency", freq);
	}

	if (version >= 0x5f)
		vendor = p->sys_vendor;

	/* Workaround a bug where we have NULL vendor */
	if (!vendor || vendor[0] == '\0')
		vendor = "IBM";

	dt_add_property_string(dt_root, "vendor", vendor);

	sys_attributes = be32_to_cpu(p->sys_attributes);
	if (sys_attributes & SYS_ATTR_RISK_LEVEL)
		dt_add_property(node, "elevated-risk-level", NULL, 0);

	if (version >= 0x60 && proc_gen >= proc_gen_p9)
		dt_init_secureboot_node(p);
}

static void add_iplparams_ipl_params(const void *iplp, struct dt_node *node)
{
	const struct iplparams_iplparams *p;
	struct dt_node *led_node;

	p = HDIF_get_idata(iplp, IPLPARAMS_IPLPARAMS, NULL);
	if (!CHECK_SPPTR(p)) {
		prerror("IPLPARAMS: No IPL Parameters\n");
		return;
	}

	node = dt_new(node, "ipl-params");
	assert(node);
	dt_add_property_cells(node, "#address-cells", 0);
	dt_add_property_cells(node, "#size-cells", 0);

	/* On an ASM initiated factory reset, this bit will be set
	 * and the FSP expects the firmware to reset the PCI bus
	 * numbers and respond with a Power Down (CE,4D,02) message
	 */
	if (be32_to_cpu(p->other_attrib) & IPLPARAMS_OATTR_RST_PCI_BUSNO)
		dt_add_property_cells(node, "pci-busno-reset-ipl", 1);
	dt_add_property_strings(node, "cec-ipl-side",
				(p->ipl_side & IPLPARAMS_CEC_FW_IPL_SIDE_TEMP) ?
				"temp" : "perm");
	if (proc_gen >= proc_gen_p9) {
		dt_add_property_strings(node, "sp-ipl-side",
					(p->ipl_side & IPLPARAMS_FSP_FW_IPL_SIDE_TEMP) ?
					"temp" : "perm");
	} else {
		dt_add_property_strings(node, "fsp-ipl-side",
					(p->ipl_side & IPLPARAMS_FSP_FW_IPL_SIDE_TEMP) ?
					"temp" : "perm");
	}
	dt_add_property_cells(node, "os-ipl-mode", p->os_ipl_mode);
	dt_add_property_strings(node, "cec-major-type",
				p->cec_ipl_maj_type ? "hot" : "cold");

	/* Add LED type info under '/ibm,opal/led' node */
	led_node = dt_find_by_path(opal_node, DT_PROPERTY_LED_NODE);
	assert(led_node);

	if (be32_to_cpu(p->other_attrib) & IPLPARAMS_OATRR_LIGHT_PATH)
		dt_add_property_strings(led_node, DT_PROPERTY_LED_MODE,
					LED_MODE_LIGHT_PATH);
	else
		dt_add_property_strings(led_node, DT_PROPERTY_LED_MODE,
					LED_MODE_GUIDING_LIGHT);
}

static void add_iplparams_serials(const void *iplp, struct dt_node *node)
{
	const struct iplparms_serial *ipser;
	struct dt_node *ser_node;
	int count, i;

	count = HDIF_get_iarray_size(iplp, IPLPARMS_IDATA_SERIAL);
	if (count <= 0)
		return;
	prlog(PR_INFO, "IPLPARAMS: %d serial ports in array\n", count);

	node = dt_new(node, "fsp-serial");
	assert(node);
	dt_add_property_cells(node, "#address-cells", 1);
	dt_add_property_cells(node, "#size-cells", 0);

	for (i = 0; i < count; i++) {
		u16 rsrc_id;
		ipser = HDIF_get_iarray_item(iplp, IPLPARMS_IDATA_SERIAL,
					     i, NULL);
		if (!CHECK_SPPTR(ipser))
			continue;
		rsrc_id = be16_to_cpu(ipser->rsrc_id);
		prlog(PR_INFO, "IPLPARAMS: Serial %d rsrc: %04x loc: %s\n",
		      i, rsrc_id, ipser->loc_code);
		ser_node = dt_new_addr(node, "serial", rsrc_id);
		if (!ser_node)
			continue;

		dt_add_property_cells(ser_node, "reg", rsrc_id);
		dt_add_property_nstr(ser_node, "ibm,loc-code",
				     ipser->loc_code, LOC_CODE_SIZE);
		dt_add_property_string(ser_node, "compatible",
				       "ibm,fsp-serial");
		/* XXX handle CALLHOME flag ? */
	}
}

/*
 * Check for platform dump, if present populate DT
 */
static void add_iplparams_platform_dump(const void *iplp, struct dt_node *node)
{
	const struct iplparams_dump *ipl_dump;

	ipl_dump = HDIF_get_idata(iplp, IPLPARAMS_PLATFORM_DUMP, NULL);
	if (!CHECK_SPPTR(ipl_dump))
		return;

	node = dt_new(node, "platform-dump");
	assert(node);

	if (be32_to_cpu(ipl_dump->dump_id)) {
		dt_add_property_cells(node, "dump-id",
				      be32_to_cpu(ipl_dump->dump_id));
		dt_add_property_u64(node, "total-size",
				    be64_to_cpu(ipl_dump->act_dump_sz));
		dt_add_property_u64(node, "hw-dump-size",
				    be32_to_cpu(ipl_dump->act_hw_dump_sz));
		dt_add_property_cells(node, "plog-id",
				      be32_to_cpu(ipl_dump->plid));
	}
}

static void add_iplparams_features(const struct HDIF_common_hdr *iplp)
{
	const struct iplparams_feature *feature;
	const struct HDIF_array_hdr *array;
	struct dt_node *fw_features;
	unsigned int count, i;
	char name[65];

	array = HDIF_get_iarray(iplp, IPLPARAMS_FEATURES, &count);
	if (!array || !count)
		return;

	opal_node = dt_new_check(dt_root, "ibm,opal");
	fw_features = dt_new(opal_node, "fw-features");
	if (!fw_features)
		return;

	HDIF_iarray_for_each(array, i, feature) {
		struct dt_node *n;
		uint64_t flags;

		/* the name field isn't necessarily null terminated */
		BUILD_ASSERT(sizeof(name) > sizeof(feature->name));
		strncpy(name, feature->name, sizeof(name)-1);
		name[sizeof(name)-1] = '\0';
		flags = be64_to_cpu(feature->flags);

		prlog(PR_DEBUG, "IPLPARAMS: FW feature %s = %016"PRIx64"\n",
				name, flags);

		/* get rid of tm-suspend-mode-enabled being disabled */
		if (strcmp(name, "tm-suspend-mode-enabled") == 0)
			strcpy(name, "tm-suspend-mode");

		n = dt_new(fw_features, name);

		/*
		 * This is a bit overkill, but we'll want seperate properties
		 * for each flag bit(s).
		 */
		if (flags & PPC_BIT(0))
			dt_add_property(n, "enabled", NULL, 0);
		else
			dt_add_property(n, "disabled", NULL, 0);
	}
}

static void add_iplparams(void)
{
	struct dt_node *iplp_node;
	const void *ipl_parms;

	ipl_parms = get_hdif(&spira.ntuples.ipl_parms, "IPLPMS");
	if (!ipl_parms) {
		prerror("IPLPARAMS: Cannot find IPL Parms in SPIRA\n");
		return;
	}

	iplp_node = dt_new(dt_root, "ipl-params");
	assert(iplp_node);
	dt_add_property_cells(iplp_node, "#address-cells", 0);
	dt_add_property_cells(iplp_node, "#size-cells", 0);

	add_iplparams_sys_params(ipl_parms, iplp_node);
	add_iplparams_ipl_params(ipl_parms, iplp_node);
	add_iplparams_serials(ipl_parms, iplp_node);
	add_iplparams_platform_dump(ipl_parms, iplp_node);
	add_iplparams_features(ipl_parms);
}

/* Various structure contain a "proc_chip_id" which is an arbitrary
 * numbering used by HDAT to reference chips, which doesn't correspond
 * to the HW IDs. We want to use the HW IDs everywhere in the DT so
 * we convert using this.
 *
 * Note: On P7, the HW ID is the XSCOM "GCID" including the T bit which
 * is *different* from the chip ID portion of the interrupt server#
 * (or PIR). See the explanations in chip.h
 */
uint32_t pcid_to_chip_id(uint32_t proc_chip_id)
{
	unsigned int i;
	const void *hdif;

	/* First, try the proc_chip ntuples for chip data */
	for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
			    SPPCRD_HDIF_SIG) {
		const struct sppcrd_chip_info *cinfo;

		cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO,
						NULL);
		if (!CHECK_SPPTR(cinfo)) {
			prerror("XSCOM: Bad ChipID data %d\n", i);
			continue;
		}
		if (proc_chip_id == be32_to_cpu(cinfo->proc_chip_id))
			return be32_to_cpu(cinfo->xscom_id);
	}

	/* Otherwise, check the old-style PACA, looking for unique chips */
	for_each_ntuple_idx(&spira.ntuples.paca, hdif, i, PACA_HDIF_SIG) {
		const struct sppaca_cpu_id *id;

		/* We only suport old style PACA on P7 ! */
		assert(proc_gen == proc_gen_p7);

		id = HDIF_get_idata(hdif, SPPACA_IDATA_CPU_ID, NULL);

		if (!CHECK_SPPTR(id)) {
			prerror("XSCOM: Bad processor data %d\n", i);
			continue;
		}

		if (proc_chip_id == be32_to_cpu(id->processor_chip_id))
			return P7_PIR2GCID(be32_to_cpu(id->pir));
	}

	/* Not found, what to do ? Assert ? For now return a number
	 * guaranteed to not exist
	 */
	return (uint32_t)-1;
}

/* Create '/ibm,opal/led' node */
static void dt_init_led_node(void)
{
	struct dt_node *led_node;

	/* Create /ibm,opal node, if its not created already */
	if (!opal_node) {
		opal_node = dt_new(dt_root, "ibm,opal");
		assert(opal_node);
	}

	/* Crete LED parent node */
	led_node = dt_new(opal_node, DT_PROPERTY_LED_NODE);
	assert(led_node);
}

static void hostservices_parse(void)
{
	struct HDIF_common_hdr *hs_hdr;
	const void *dt_blob;
	unsigned int size;
	unsigned int ntuples_size;

	/* Deprecated on P9 */
	if (proc_gen >= proc_gen_p9)
		return;

	ntuples_size = sizeof(struct HDIF_array_hdr) + 
		be32_to_cpu(spira.ntuples.array_hdr.ecnt) *
		sizeof(struct spira_ntuple);

	if (offsetof(struct spira_ntuples, hs_data) >= ntuples_size) {
		prerror("SPIRA: No host services data found\n");
		return;
	}

	hs_hdr = get_hdif(&spira.ntuples.hs_data, HSERV_HDIF_SIG);
	if (!hs_hdr) {
		prerror("SPIRA: No host services data found\n");
		return;
	}

	dt_blob = HDIF_get_idata(hs_hdr, 0, &size);
	if (!dt_blob) {
		prerror("SPIRA: No host services idata found\n");
		return;
	}
	hservices_from_hdat(dt_blob, size);
}

static void add_stop_levels(void)
{
	struct spira_ntuple *t = &spira.ntuples.proc_chip;
	struct HDIF_common_hdr *hdif;
	u32 stop_levels = ~0;
	bool valid = false;
	int i;

	if (proc_gen < proc_gen_p9)
		return;

	/*
	 * OPAL only exports a single set of flags to indicate the supported
	 * STOP modes while the HDAT descibes the support top levels *per chip*
	 * We parse the list of chips to find a common set of STOP levels to
	 * export.
	 */
	for_each_ntuple_idx(t, hdif, i, SPPCRD_HDIF_SIG) {
		unsigned int size;
		const struct sppcrd_chip_info *cinfo =
			HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, &size);
		u32 ve, chip_levels;

		if (!cinfo)
			continue;

		/*
		 * If the chip info field is too small then assume we have no
		 * STOP level information.
		 */
		if (size < 0x44) {
			stop_levels = 0;
			break;
		}

		ve = be32_to_cpu(cinfo->verif_exist_flags) & CPU_ID_VERIFY_MASK;
		ve >>= CPU_ID_VERIFY_SHIFT;
		if (ve == CHIP_VERIFY_NOT_INSTALLED ||
		    ve == CHIP_VERIFY_UNUSABLE)
			continue;

		chip_levels = be32_to_cpu(cinfo->stop_levels);

		prlog(PR_INSANE, "CHIP[%x] supported STOP mask 0x%.8x\n",
			be32_to_cpu(cinfo->proc_chip_id), chip_levels);

		stop_levels &= chip_levels;
		valid = true;
	}

	if (!valid)
		stop_levels = 0;

	dt_add_property_cells(dt_new_check(opal_node, "power-mgt"),
		"ibm,enabled-stop-levels", stop_levels);
}

#define NPU_BASE 0x5011000
#define NPU_SIZE 0x2c
#define NPU_INDIRECT0	0x8000000009010c3fULL
#define NPU_INDIRECT1	0x800000000c010c3fULL

static void add_npu(struct dt_node *xscom, const struct HDIF_array_hdr *links,
			int npu_index, int phb_index)
{
	const struct sppcrd_smp_link *link;
	struct dt_node *npu;
	int group_target[6]; /* Tracks the PCI slot targeted each link group */
	int group_count = 0;
	int link_count = 0;
	uint32_t size, chip_id;
	int i;

	size = be32_to_cpu(links->esize);
	chip_id = dt_get_chip_id(xscom);

	memset(group_target, 0, sizeof(group_target));

	npu = dt_new_addr(xscom, "npu", NPU_BASE);
	dt_add_property_cells(npu, "reg", NPU_BASE, NPU_SIZE);
	dt_add_property_cells(npu, "#size-cells", 0);
	dt_add_property_cells(npu, "#address-cells", 1);

	dt_add_property_strings(npu, "compatible", "ibm,power9-npu");
	dt_add_property_cells(npu, "ibm,phb-index", phb_index);
	dt_add_property_cells(npu, "ibm,npu-index", npu_index);

	HDIF_iarray_for_each(links, i, link) {
		uint16_t slot_id = be16_to_cpu(link->pci_slot_idx);
		uint32_t link_id = be32_to_cpu(link->link_id);
		uint64_t speed = 0, nvlink_speed = 0;
		struct dt_node *node;

		/* only add a link node if this link is targeted at at device */
		if (be32_to_cpu(link->usage) != SMP_LINK_USE_DEVICE)
			continue;

		/*
		 * XXX: The link_id that we get from HDAT is essentially an
		 * arbitrary ID number so we can't use it as the reg for the
		 * link node.
		 *
		 * a) There's a 1-1 mapping between entries in the SMP link
		 *    structure and the NPU links.
		 *
		 * b) The SMP link array contains them in ascending order.
		 *
		 * We have some assurances that b) is correct, but if we get
		 * broken link numbering it's something to watch for.
		 *
		 * If we every have actual A-Bus (SMP) link info in here
		 * this is going to break.
		 */

		prlog(PR_DEBUG, "NPU: %04x:%d: Link (%d) targets slot %u\n",
			chip_id, link_count, link_count, slot_id);

		if (link_count >= 6) {
			prerror("NPU: %04x:%d: Ignoring extra link (max 6)\n",
				chip_id, link_count);
			break;
		}

		node = dt_new_addr(npu, "link", link_count);
		if (!node) {
			prerror("NPU: %04x:%d: Creating link node failed\n",
				chip_id, link_count);
			continue;
		}

		dt_add_property_string(node, "compatible", "ibm,npu-link");
		dt_add_property_cells(node, "reg", link_count);
		dt_add_property_cells(node, "ibm,npu-link-index", link_count);
		dt_add_property_cells(node, "ibm,workbook-link-id", link_id);

		dt_add_property_u64s(node, "ibm,npu-phy",
				link_count < 3 ? NPU_INDIRECT0 : NPU_INDIRECT1);
		dt_add_property_cells(node, "ibm,npu-lane-mask",
				be32_to_cpu(link->lane_mask));
		dt_add_property_cells(node, "ibm,npu-brick-id",
				be32_to_cpu(link->brick_id));

		link_count++;

		/*
		 * Add the group details if this is an NVlink.
		 *
		 * TODO: Cable card stuff.
		 */
		if (slot_id) {
			struct dt_node *slot;
			const char *name;
			int group;

			/*
			 * Search the existing groups for one targeting
			 * this PCI slot
			 */
			for (group = 0; group < group_count; group++)
				if (group_target[group] == slot_id)
					break;

			/* no group, make a new one */
			if (group == group_count) {
				group_target[group] = slot_id;
				group_count++;
			}

			dt_add_property_cells(node, "ibm,npu-group-id", group);

			slot = find_slot_entry_node(dt_root, slot_id);
			if (!slot) {
				prerror("NPU: %04x:%d: Unable find node for targeted PCIe slot\n",
					chip_id, link_count - 1);
				continue;
			}

			/*
			 * The slot_id points to a node that indicates that
			 * this GPU should appear under the slot. Grab the
			 * slot-label from the parent node that represents
			 * the actual slot.
			 */
			name = dt_prop_get_def(slot->parent, "ibm,slot-label",
						(char *)"<SLOT NAME MISSING>");

			prlog(PR_DEBUG, "NPU: %04x:%d: Target slot %s\n",
				chip_id, link_count - 1, name);

			dt_add_property_string(node, "ibm,slot-label", name);
			dt_add_property_cells(node, "ibm,pcie-slot",
					slot->phandle);
		}

		/* Newer fields which might not be populated */
		if (size <= 0x24)
			continue;

		switch (link->link_speed) {
			case 0: /* 20Gbps */
				speed = 20000000000ul;
				nvlink_speed = 0x3;
				break;
			case 1: /* 25Gbps */
				speed = 25000000000ul;
				nvlink_speed = 0x9;
				break;
			case 2: /* 25.78125 Gbps */
				nvlink_speed =  0x8;
				speed = 25781250000ul;
				break;
		}

		/* ibm,link-speed is in bps and nvidia,link-speed is ~magic~ */
		dt_add_property_u64s(node, "ibm,link-speed", speed);
		dt_add_property_cells(node, "nvidia,link-speed", nvlink_speed);

		dt_add_property_cells(node, DT_PRIVATE "occ-flag-pos",
				PPC_BIT(link->occ_flag_bit));
	}

	dt_add_property_cells(npu, "ibm,npu-links", link_count);
}

static void add_npus(void)
{
	struct dt_node *xscom;
	int phb_index = 7; /* Start counting from 7, for no reason */
	int npu_index = 0;

	if (proc_gen < proc_gen_p9)
		return;

	dt_for_each_compatible(dt_root, xscom, "ibm,xscom") {
		const struct HDIF_array_hdr *links;

		links = xscom_to_pcrd(xscom, SPPCRD_IDATA_SMP_LINK);
		if (!links) {
			prerror("NPU: Unable to find matching SPPCRD for %s\n",
				xscom->name);
			continue;
		}

		/* should never happen, but stranger things have */
		if (!dt_find_by_name(dt_root, "ibm,pcie-slots")) {
			prerror("PCIe slot information missing, can't add npu");
			continue;
		}

		/* some hostboots will give us an empty array */
		if (be32_to_cpu(links->ecnt))
			add_npu(xscom, links, npu_index++, phb_index++);
	}
}

/*
 * Legacy SPIRA is being deprecated and we have new SPIRA-H/S structures.
 * But on older system (p7?) we will continue to get legacy SPIRA.
 *
 * SPIRA-S is initialized and provided by FSP. We use SPIRA-S signature
 * to identify supported format. Also if required adjust spira pointer.
 */
static void fixup_spira(void)
{
#if !defined(TEST)
	spiras = (struct spiras *)CPU_TO_BE64(SPIRA_HEAP_BASE);
#endif

	/* Validate SPIRA-S signature */
	if (!spiras)
		return;
	if (!HDIF_check(&spiras->hdr, SPIRAS_HDIF_SIG))
		return;

	prlog(PR_NOTICE, "SPIRA-S found.\n");

	spira.ntuples.sp_subsys = spiras->ntuples.sp_subsys;
	spira.ntuples.ipl_parms = spiras->ntuples.ipl_parms;
	spira.ntuples.nt_enclosure_vpd = spiras->ntuples.nt_enclosure_vpd;
	spira.ntuples.slca = spiras->ntuples.slca;
	spira.ntuples.backplane_vpd = spiras->ntuples.backplane_vpd;
	spira.ntuples.system_vpd = spiras->ntuples.system_vpd;
	spira.ntuples.proc_init = spirah.ntuples.proc_init;
	spira.ntuples.clock_vpd = spiras->ntuples.clock_vpd;
	spira.ntuples.anchor_vpd = spiras->ntuples.anchor_vpd;
	spira.ntuples.op_panel_vpd = spiras->ntuples.op_panel_vpd;
	spira.ntuples.misc_cec_fru_vpd = spiras->ntuples.misc_cec_fru_vpd;
	spira.ntuples.ms_vpd = spiras->ntuples.ms_vpd;
	spira.ntuples.cec_iohub_fru = spiras->ntuples.cec_iohub_fru;
	spira.ntuples.cpu_ctrl = spirah.ntuples.cpu_ctrl;
	spira.ntuples.mdump_src = spirah.ntuples.mdump_src;
	spira.ntuples.mdump_dst = spirah.ntuples.mdump_dst;
	spira.ntuples.mdump_res  = spirah.ntuples.mdump_res;
	spira.ntuples.pcia = spiras->ntuples.pcia;
	spira.ntuples.proc_chip = spiras->ntuples.proc_chip;
	spira.ntuples.hs_data = spiras->ntuples.hs_data;
	spira.ntuples.ipmi_sensor = spiras->ntuples.ipmi_sensor;
	spira.ntuples.node_stb_data = spiras->ntuples.node_stb_data;
}

int parse_hdat(bool is_opal)
{
	cpu_type = PVR_TYPE(mfspr(SPR_PVR));

	prlog(PR_DEBUG, "Parsing HDAT...\n");

	fixup_spira();

	/*
	 * Basic DT root stuff
	 */
	dt_add_property_cells(dt_root, "#address-cells", 2);
	dt_add_property_cells(dt_root, "#size-cells", 2);

	if (proc_gen < proc_gen_p9)
		dt_add_property_string(dt_root, "lid-type", is_opal ? "opal" : "phyp");

	/* Add any BMCs and enable the LPC UART */
	bmc_parse();

	/* Create and populate /vpd node */
	dt_init_vpd_node();

	/* Create /ibm,opal/led node */
	dt_init_led_node();

	/* Parse SPPACA and/or PCIA */
	if (!pcia_parse())
		if (paca_parse() < 0)
			return -1;

	/* IPL params */
	add_iplparams();

	/* Add XSCOM node (must be before chiptod, IO and FSP) */
	add_xscom();

	/* Parse MS VPD */
	memory_parse();

	/* Add any FSPs */
	fsp_parse();

	/* Add ChipTOD's */
	if (!add_chiptod_old() && !add_chiptod_new())
		prerror("CHIPTOD: No ChipTOD found !\n");

	/* Add NX */
	add_nx();

	/* Add nest mmu */
	add_nmmu();

	/* Add IO HUBs and/or PHBs */
	io_parse();

	/* Add NPU nodes */
	if (proc_gen >= proc_gen_p9)
		add_npus();

	/* Parse VPD */
	vpd_parse();

	/* Host services information. */
 	hostservices_parse();

	/* Parse System Attention Indicator inforamtion */
	slca_dt_add_sai_node();

	add_stop_levels();

	/* Parse node secure and trusted boot data */
	if (proc_gen >= proc_gen_p9)
		node_stb_parse();

	prlog(PR_DEBUG, "Parsing HDAT...done\n");

	return 0;
}
