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

#include <cpu.h>
#include <device.h>
#include <vpd.h>
#include <ccan/str/str.h>
#include <libfdt/libfdt.h>
#include <mem_region.h>
#include <types.h>
#include <inttypes.h>
#include <processor.h>

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

struct HDIF_ram_area_id {
	__be16 id;
#define RAM_AREA_INSTALLED	0x8000
#define RAM_AREA_FUNCTIONAL	0x4000
	__be16 flags;
	__be32 dimm_id;
	__be32 speed;
} __packed;

struct HDIF_ram_area_size {
	__be32 reserved1;
	__be32 mb;
} __packed;

struct HDIF_ms_area_address_range {
	__be64 start;
	__be64 end;
	__be32 chip;
	__be32 mirror_attr;
	__be64 mirror_start;
	__be32 controller_id;
	__be32 phys_attr;
} __packed;
#define PHYS_ATTR_TYPE_MASK 	0xff000000
#define   PHYS_ATTR_TYPE_STD		0
#define   PHYS_ATTR_TYPE_NVDIMM		1
#define   PHYS_ATTR_TYPE_MRAM		2
#define   PHYS_ATTR_TYPE_PCM		3

#define PHYS_ATTR_STATUS_MASK 	0x00ff0000
/*
 * The values here are mutually exclusive. I have no idea why anyone
 * decided encoding these are flags rather than sequential numbers was
 * a good idea, but here we are.
 */
#define   PHYS_ATTR_STATUS_CANT_SAVE 	0x01
#define   PHYS_ATTR_STATUS_SAVE_FAILED	0x02
#define   PHYS_ATTR_STATUS_SAVED	0x04
#define   PHYS_ATTR_STATUS_NOT_SAVED	0x08
#define   PHYS_ATTR_STATUS_MEM_INVALID	0xff

/* Memory Controller ID for Nimbus P9 systems */
#define MS_CONTROLLER_MCBIST_ID(id)	GETFIELD(PPC_BITMASK32(0, 1), id)
#define MS_CONTROLLER_MCS_ID(id)	GETFIELD(PPC_BITMASK32(4, 7), id)
#define MS_CONTROLLER_MCA_ID(id)	GETFIELD(PPC_BITMASK32(8, 15), id)

/* Memory Controller ID for P9 AXONE systems */
#define MS_CONTROLLER_MC_ID(id)		GETFIELD(PPC_BITMASK32(0, 1), id)
#define MS_CONTROLLER_MI_ID(id)		GETFIELD(PPC_BITMASK32(4, 7), id)
#define MS_CONTROLLER_MCC_ID(id)	GETFIELD(PPC_BITMASK32(8, 15), id)
#define MS_CONTROLLER_OMI_ID(id)	GETFIELD(PPC_BITMASK32(16, 31), id)

struct HDIF_ms_area_id {
	__be16 id;
#define MS_PTYPE_RISER_CARD	0x8000
#define MS_PTYPE_MEM_CARD	0x4000
#define MS_PTYPE_CEC_FRU	0x2000
#define MS_PTYPE_HYBRID_CARD	0x1000
	__be16 parent_type;
#define MS_AREA_INSTALLED	0x8000
#define MS_AREA_FUNCTIONAL	0x4000
#define MS_AREA_SHARED		0x2000
	__be16 flags;
	__be16 share_id;
} __packed;


// FIXME: it should be 9, current HDATs are broken
#define MSAREA_IDATA_MMIO_IDX 8
struct HDIF_ms_area_ocmb_mmio {
	__be64 range_start;
	__be64 range_end;
	__be32 controller_id;
	__be32 proc_chip_id;
	__be64 hbrt_id;
#define OCMB_SCOM_8BYTE_ACCESS	PPC_BIT(0)
#define OCMB_SCOM_4BYTE_ACCESS	PPC_BIT(1)
	__be64 flags;
} __packed;

static void append_chip_id(struct dt_node *mem, u32 id)
{
	struct dt_property *prop;
	size_t len, i;

	prop = __dt_find_property(mem, "ibm,chip-id");
	if (!prop)
		return;
	len = prop->len >> 2;

	/* Check if it exists already */
	for (i = 0; i < len; i++) {
		if (dt_property_get_cell(prop, i) == id)
			return;
	}

	/* Add it to the list */
	dt_resize_property(&prop, (len + 1) << 2);
	dt_property_set_cell(prop, len, id);
}

static void update_status(struct dt_node *mem, uint32_t status)
{
	switch (status) {
	case PHYS_ATTR_STATUS_CANT_SAVE:
		if (!dt_find_property(mem, "save-trigged-unarmed"))
			dt_add_property(mem, "save-trigger-unarmed", NULL, 0);
		break;

	case PHYS_ATTR_STATUS_SAVE_FAILED:
		if (!dt_find_property(mem, "save-failed"))
			dt_add_property(mem, "save-failed", NULL, 0);

		break;

	case PHYS_ATTR_STATUS_MEM_INVALID:
		if (dt_find_property(mem, "save-trigged-unarmed"))
			dt_add_property_string(mem, "status",
				"disabled-memory-invalid");
		break;
	}
}

static bool add_address_range(struct dt_node *root,
			      const struct HDIF_ms_area_id *id,
			      const struct HDIF_ms_area_address_range *arange,
			      uint32_t mem_type, uint32_t mem_status)
{
	const char *compat = NULL, *dev_type = NULL, *name = NULL;
	struct dt_node *mem;
	u32 chip_id;
	u64 reg[2];

	chip_id = pcid_to_chip_id(be32_to_cpu(arange->chip));

	prlog(PR_DEBUG, "  Range: 0x%016llx..0x%016llx "
	      "on Chip 0x%x mattr: 0x%x pattr: 0x%x status:0x%x\n",
	      (long long)be64_to_cpu(arange->start),
	      (long long)be64_to_cpu(arange->end),
	      chip_id, be32_to_cpu(arange->mirror_attr),
	      mem_type, mem_status);

	/* reg contains start and length */
	reg[0] = cleanup_addr(be64_to_cpu(arange->start));
	reg[1] = cleanup_addr(be64_to_cpu(arange->end)) - reg[0];

	switch (mem_type) {
	case PHYS_ATTR_TYPE_STD:
		name = "memory";
		dev_type = "memory";
		break;

	case PHYS_ATTR_TYPE_NVDIMM:
	case PHYS_ATTR_TYPE_MRAM:
	case PHYS_ATTR_TYPE_PCM:
		/* fall through */
		name = "nvdimm";
		compat = "pmem-region";
		break;

	/*
	 * Future memory types could be volatile or non-volatile. Bail if don't
	 * recognise the type so we don't end up trashing data accidently.
	 */
	default:
		return false;
	}

	if (be16_to_cpu(id->flags) & MS_AREA_SHARED) {
		mem = dt_find_by_name_addr(dt_root, name, reg[0]);
		if (mem) {
			append_chip_id(mem, chip_id);
			if (mem_type == PHYS_ATTR_TYPE_NVDIMM)
				update_status(mem, mem_status);
			return true;
		}
	}

	mem = dt_new_addr(root, name, reg[0]);
	if (compat)
		dt_add_property_string(mem, "compatible", compat);
	if (dev_type)
		dt_add_property_string(mem, "device_type", dev_type);

	/* add in the nvdimm backup status flags */
	if (mem_type == PHYS_ATTR_TYPE_NVDIMM)
		update_status(mem, mem_status);

	/* common properties */

	dt_add_property_u64s(mem, "reg", reg[0], reg[1]);
	dt_add_property_cells(mem, "ibm,chip-id", chip_id);
	return true;
}

static u32 add_chip_id_to_ram_area(const struct HDIF_common_hdr *msarea,
				    struct dt_node *ram_area)
{
	const struct HDIF_array_hdr *arr;
	const struct HDIF_ms_area_address_range *arange;
	unsigned int size;
	u32 chip_id;

	/* Safe to assume pointers are valid here. */
	arr = HDIF_get_idata(msarea, 4, &size);
	arange = (void *)arr + be32_to_cpu(arr->offset);
	chip_id = pcid_to_chip_id(be32_to_cpu(arange->chip));
	dt_add_property_cells(ram_area, "ibm,chip-id", chip_id);

	return chip_id;
}

static void add_bus_freq_to_ram_area(struct dt_node *ram_node, u32 chip_id)
{
	const struct sppcia_cpu_timebase *timebase;
	bool got_pcia = false;
	const void *pcia;
	u64 freq;
	u32 size;

	pcia = get_hdif(&spira.ntuples.pcia, SPPCIA_HDIF_SIG);
	if (!pcia) {
		prlog(PR_WARNING, "HDAT: Failed to add memory bus frequency "
		      "as PCIA does not exist\n");
		return;
	}

	for_each_pcia(pcia) {
		const struct sppcia_core_unique *id;

		id = HDIF_get_idata(pcia, SPPCIA_IDATA_CORE_UNIQUE, &size);
		if (!id || size < sizeof(*id)) {
			prlog(PR_WARNING, "HDAT: Bad id size %u @ %p\n", size, id);
			return;
		}

		if (chip_id == pcid_to_chip_id(be32_to_cpu(id->proc_chip_id))) {
			got_pcia = true;
			break;
		}
	}

	if (got_pcia == false)
		return;

	timebase = HDIF_get_idata(pcia, SPPCIA_IDATA_TIMEBASE, &size);
	if (!timebase || size < sizeof(*timebase)) {
		/**
		 * @fwts-label HDATBadTimebaseSize
		 * @fwts-advice HDAT described an invalid size for timebase,
		 * which means there's a disagreement between HDAT and OPAL.
		 * This is most certainly a firmware bug.
		 */
		prlog(PR_ERR, "HDAT: Bad timebase size %u @ %p\n", size,
		      timebase);
		return;
	}

	freq = ((u64)be32_to_cpu(timebase->memory_bus_frequency)) * 1000000ul;
	dt_add_property_u64(ram_node, "ibm,memory-bus-frequency", freq);
}

static void add_size_to_ram_area(struct dt_node *ram_node,
				 const struct HDIF_common_hdr *ramarea)
{
	char	str[16];
	const struct HDIF_ram_area_size *ram_area_sz;

	/* DIMM size */
	ram_area_sz = HDIF_get_idata(ramarea, 3, NULL);
	if (!CHECK_SPPTR(ram_area_sz))
		return;

	memset(str, 0, 16);
	snprintf(str, 16, "%d", be32_to_cpu(ram_area_sz->mb));
	dt_add_property_string(ram_node, "size", str);
}

static void vpd_add_ram_area(const struct HDIF_common_hdr *msarea)
{
	unsigned int i;
	unsigned int ram_sz;
	const struct HDIF_common_hdr *ramarea;
	const struct HDIF_child_ptr *ramptr;
	const struct HDIF_ram_area_id *ram_id;
	struct dt_node *ram_node;
	u32 chip_id;
	const void *vpd_blob;

	ramptr = HDIF_child_arr(msarea, 0);
	if (!CHECK_SPPTR(ramptr)) {
		prerror("MS AREA: No RAM area at %p\n", msarea);
		return;
	}

	for (i = 0; i < be32_to_cpu(ramptr->count); i++) {
		ramarea = HDIF_child(msarea, ramptr, i, "RAM   ");
		if (!CHECK_SPPTR(ramarea))
			continue;

		ram_id = HDIF_get_idata(ramarea, 2, &ram_sz);
		if (!CHECK_SPPTR(ram_id))
			continue;

		/* Don't add VPD for non-existent RAM */
		if (!(be16_to_cpu(ram_id->flags) & RAM_AREA_INSTALLED))
			continue;

		ram_node = dt_add_vpd_node(ramarea, 0, 1);
		if (!ram_node)
			continue;

		chip_id = add_chip_id_to_ram_area(msarea, ram_node);
		add_bus_freq_to_ram_area(ram_node, chip_id);

		if (ram_sz >= offsetof(struct HDIF_ram_area_id, speed)) {
			dt_add_property_cells(ram_node, "frequency",
					      be32_to_cpu(ram_id->speed)*1000000);
		}

		vpd_blob = HDIF_get_idata(ramarea, 1, &ram_sz);

		/* DIMM size */
		add_size_to_ram_area(ram_node, ramarea);
		/*
		 * For direct-attached memory we have a DDR "Serial
		 * Presence Detection" blob rather than an IBM keyword
		 * blob.
		 */
		if (!vpd_valid(vpd_blob, ram_sz))
			dt_add_property(ram_node, "spd", vpd_blob, ram_sz);
	}
}

static void vpd_parse_spd(struct dt_node *dimm, const char *spd, u32 size)
{
	__be16 *vendor;
	__be32 *sn;

	/* SPD is too small */
	if (size < 512) {
		prlog(PR_WARNING, "MSVPD: Invalid SPD size. "
		      "Expected 512 bytes, got %d\n", size);
		return;
	}

	/* Supports DDR4 format pasing only */
	if (spd[0x2] < 0xc) {
		prlog(PR_WARNING,
		      "MSVPD: SPD format (%x) not supported\n", spd[0x2]);
		return;
	}

	dt_add_property_string(dimm, "device_type", "memory-dimm-ddr4");

	/* DRAM device type */
	dt_add_property_cells(dimm, "memory-id", spd[0x2]);

	/* Module revision code */
	dt_add_property_cells(dimm, "product-version", spd[0x15d]);

	/* Serial number */
	sn = (__be32 *)&spd[0x145];
	dt_add_property_cells(dimm, "serial-number", be32_to_cpu(*sn));

	/* Part number */
	dt_add_property_nstr(dimm, "part-number", &spd[0x149], 20);

	/* Module manufacturer ID */
	vendor = (__be16 *)&spd[0x140];
	dt_add_property_cells(dimm, "manufacturer-id", be16_to_cpu(*vendor));
}

static void add_dimm_info(struct dt_node *parent,
			      const struct HDIF_common_hdr *msarea)
{
	unsigned int i, size;
	const struct HDIF_child_ptr *ramptr;
	const struct HDIF_common_hdr *ramarea;
	const struct spira_fru_id *fru_id;
	const struct HDIF_ram_area_id *ram_id;
	const struct HDIF_ram_area_size *ram_area_sz;
	struct dt_node *dimm;
	const void *vpd_blob;

	ramptr = HDIF_child_arr(msarea, 0);
	if (!CHECK_SPPTR(ramptr)) {
		prerror("MS AREA: No RAM area at %p\n", msarea);
		return;
	}

	for (i = 0; i < be32_to_cpu(ramptr->count); i++) {
		ramarea = HDIF_child(msarea, ramptr, i, "RAM   ");
		if (!CHECK_SPPTR(ramarea))
			continue;

		fru_id = HDIF_get_idata(ramarea, 0, NULL);
		if (!fru_id)
			continue;

		/* Use Resource ID to add dimm node */
		dimm = dt_find_by_name_addr(parent, "dimm",
					    be16_to_cpu(fru_id->rsrc_id));
		if (dimm)
			continue;
		dimm= dt_new_addr(parent, "dimm", be16_to_cpu(fru_id->rsrc_id));
		assert(dimm);
		dt_add_property_cells(dimm, "reg", be16_to_cpu(fru_id->rsrc_id));

		/* Add location code */
		slca_vpd_add_loc_code(dimm, be16_to_cpu(fru_id->slca_index));

		/* DIMM size */
		ram_area_sz = HDIF_get_idata(ramarea, 3, NULL);
		if (!CHECK_SPPTR(ram_area_sz))
			continue;
		dt_add_property_cells(dimm, "size", be32_to_cpu(ram_area_sz->mb));

		/* DIMM state */
		ram_id = HDIF_get_idata(ramarea, 2, NULL);
		if (!CHECK_SPPTR(ram_id))
			continue;

		if ((be16_to_cpu(ram_id->flags) & RAM_AREA_INSTALLED) &&
		    (be16_to_cpu(ram_id->flags) & RAM_AREA_FUNCTIONAL))
			dt_add_property_string(dimm, "status", "okay");
		else
			dt_add_property_string(dimm, "status", "disabled");

		vpd_blob = HDIF_get_idata(ramarea, 1, &size);
		if (!CHECK_SPPTR(vpd_blob))
			continue;
		if (vpd_valid(vpd_blob, size))
			vpd_data_parse(dimm, vpd_blob, size);
		else
			vpd_parse_spd(dimm, vpd_blob, size);
	}
}

static inline void dt_add_mem_reg_property(struct dt_node *node, u64 addr)
{
	dt_add_property_cells(node, "#address-cells", 1);
	dt_add_property_cells(node, "#size-cells", 0);
	dt_add_property_cells(node, "reg", addr);
}

static void add_memory_controller_p9n(const struct HDIF_common_hdr *msarea,
				  const struct HDIF_ms_area_address_range *arange)
{
	uint32_t chip_id;
	uint32_t controller_id, mcbist_id, mcs_id, mca_id;
	struct dt_node *xscom, *mcbist, *mcs, *mca;

	chip_id = pcid_to_chip_id(be32_to_cpu(arange->chip));
	controller_id = be32_to_cpu(arange->controller_id);
	xscom = find_xscom_for_chip(chip_id);
	if (!xscom) {
		prlog(PR_WARNING,
		      "MS AREA: Can't find XSCOM for chip %d\n", chip_id);
		return;
	}

	mcbist_id = MS_CONTROLLER_MCBIST_ID(controller_id);
	mcbist = dt_find_by_name_addr(xscom, "mcbist", mcbist_id);
	if (!mcbist) {
		mcbist = dt_new_addr(xscom, "mcbist", mcbist_id);
		assert(mcbist);
		dt_add_property_cells(mcbist, "#address-cells", 1);
		dt_add_property_cells(mcbist, "#size-cells", 0);
		dt_add_property_cells(mcbist, "reg", mcbist_id, 0);
	}

	mcs_id = MS_CONTROLLER_MCS_ID(controller_id);
	mcs = dt_find_by_name_addr(mcbist, "mcs", mcs_id);
	if (!mcs) {
		mcs = dt_new_addr(mcbist, "mcs", mcs_id);
		assert(mcs);
		dt_add_mem_reg_property(mcs, mcs_id);
	}

	mca_id = MS_CONTROLLER_MCA_ID(controller_id);
	mca = dt_find_by_name_addr(mcs, "mca", mca_id);
	if (!mca) {
		mca = dt_new_addr(mcs, "mca", mca_id);
		assert(mca);
		dt_add_mem_reg_property(mca, mca_id);
	}

	add_dimm_info(mca, msarea);
}

static void add_memory_buffer_mmio(const struct HDIF_common_hdr *msarea)
{
	const struct HDIF_ms_area_ocmb_mmio *mmio;
	uint64_t min_addr = ~0ull, hbrt_id = 0;
	const struct HDIF_array_hdr *array;
	unsigned int i, count, ranges = 0;
	struct dt_node *membuf;
	beint64_t *reg, *flags;

	if (PVR_TYPE(mfspr(SPR_PVR)) != PVR_TYPE_P9P)
		return;

	if (be16_to_cpu(msarea->version) < 0x50) {
		prlog(PR_WARNING, "MS AREA: Inconsistent MSAREA version %x for P9P system",
			be16_to_cpu(msarea->version));
		return;
	}

	array = HDIF_get_iarray(msarea, MSAREA_IDATA_MMIO_IDX, &count);
	if (!array || count <= 0) {
		prerror("MS AREA: No OCMB MMIO array at MS Area %p\n", msarea);
		return;
	}

	reg = zalloc(count * 2 * sizeof(*reg));
	flags = zalloc(count * sizeof(*flags));

	/* grab the hbrt id from the first range. */
	HDIF_iarray_for_each(array, i, mmio) {
		hbrt_id = be64_to_cpu(mmio->hbrt_id);
		break;
	}

	prlog(PR_DEBUG, "Adding memory buffer MMIO ranges for %"PRIx64"\n",
	      hbrt_id);

	HDIF_iarray_for_each(array, i, mmio) {
		uint64_t start, end;

		if (hbrt_id != be64_to_cpu(mmio->hbrt_id)) {
			prerror("HBRT ID mismatch!\n");
			continue;
		}

		start = cleanup_addr(be64_to_cpu(mmio->range_start));
		end   = cleanup_addr(be64_to_cpu(mmio->range_end));
		if (start < min_addr)
			min_addr = start;

		prlog(PR_DEBUG, "  %"PRIx64" - [%016"PRIx64"-%016"PRIx64")\n",
			hbrt_id, start, end);

		reg[2 * ranges    ] = cpu_to_be64(start);
		reg[2 * ranges + 1] = cpu_to_be64(end - start + 1);
		flags[ranges] = mmio->flags; /* both are BE */
		ranges++;
	}

	membuf = dt_find_by_name_addr(dt_root, "memory-buffer", min_addr);
	if (membuf) {
		prerror("attempted to duplicate %s\n", membuf->name);
		goto out;
	}

	membuf = dt_new_addr(dt_root, "memory-buffer", min_addr);
	assert(membuf);

	dt_add_property_string(membuf, "compatible", "ibm,explorer");
	dt_add_property_cells(membuf, "ibm,chip-id", hbrt_id);

	/*
	 * FIXME: We should probably be sorting the address ranges based
	 * on the starting address.
	 */
	dt_add_property(membuf, "reg",   reg,   sizeof(*reg) * 2 * ranges);
	dt_add_property(membuf, "flags", flags, sizeof(*flags)   * ranges);

out:
	free(flags);
	free(reg);
}

static void add_memory_controller(const struct HDIF_common_hdr *msarea,
				  const struct HDIF_ms_area_address_range *arange)
{
	const uint32_t version = PVR_TYPE(mfspr(SPR_PVR));
	/*
	 * Memory hierarchy may change between processor version. Presently
	 * it's only creating memory hierarchy for P9 (Nimbus) and P9P (Axone).
	 */

	if (version == PVR_TYPE_P9)
		return add_memory_controller_p9n(msarea, arange);
	else if (version == PVR_TYPE_P9P)
		return; //return add_memory_controller_p9p(msarea, arange);
	else
		return;
}

static void get_msareas(struct dt_node *root,
			const struct HDIF_common_hdr *ms_vpd)
{
	unsigned int i;
	const struct HDIF_child_ptr *msptr;

	/* First childptr refers to msareas. */
	msptr = HDIF_child_arr(ms_vpd, MSVPD_CHILD_MS_AREAS);
	if (!CHECK_SPPTR(msptr)) {
		prerror("MS VPD: no children at %p\n", ms_vpd);
		return;
	}

	for (i = 0; i < be32_to_cpu(msptr->count); i++) {
		const struct HDIF_common_hdr *msarea;
		const struct HDIF_array_hdr *arr;
		const struct HDIF_ms_area_address_range *arange;
		const struct HDIF_ms_area_id *id;
		const void *fruid;
		unsigned int size, j, offset;
		u16 flags;

		msarea = HDIF_child(ms_vpd, msptr, i, "MSAREA");
		if (!CHECK_SPPTR(msarea))
			return;

		id = HDIF_get_idata(msarea, 2, &size);
		if (!CHECK_SPPTR(id))
			return;
		if (size < sizeof(*id)) {
			prerror("MS VPD: %p msarea #%i id size too small!\n",
				ms_vpd, i);
			return;
		}

		flags = be16_to_cpu(id->flags);
		prlog(PR_DEBUG, "MS VPD: %p, area %i: %s %s %s\n",
		       ms_vpd, i,
		       flags & MS_AREA_INSTALLED ?
		       "installed" : "not installed",
		       flags & MS_AREA_FUNCTIONAL ?
		       "functional" : "not functional",
		       flags & MS_AREA_SHARED ?
		       "shared" : "not shared");

		if ((flags & (MS_AREA_INSTALLED|MS_AREA_FUNCTIONAL))
		    != (MS_AREA_INSTALLED|MS_AREA_FUNCTIONAL))
			continue;

		arr = HDIF_get_idata(msarea, 4, &size);
		if (!CHECK_SPPTR(arr))
			continue;

		if (size < sizeof(*arr)) {
			prerror("MS VPD: %p msarea #%i arr size too small!\n",
				ms_vpd, i);
			return;
		}

		offset = offsetof(struct HDIF_ms_area_address_range, mirror_start);
		if (be32_to_cpu(arr->eactsz) < offset) {
			prerror("MS VPD: %p msarea #%i arange size too small!\n",
				ms_vpd, i);
			return;
		}

		fruid = HDIF_get_idata(msarea, 0, &size);
		if (!CHECK_SPPTR(fruid))
			return;

		/* Add Raiser card VPD */
		if (be16_to_cpu(id->parent_type) & MS_PTYPE_RISER_CARD)
			dt_add_vpd_node(msarea, 0, 1);

		/* Add RAM Area VPD */
		vpd_add_ram_area(msarea);

		add_memory_buffer_mmio(msarea);

		/* This offset is from the arr, not the header! */
		arange = (void *)arr + be32_to_cpu(arr->offset);
		for (j = 0; j < be32_to_cpu(arr->ecnt); j++) {
			uint32_t type = 0, status = 0;

			/*
			 * Check that the required fields are present in this
			 * version of the HDAT structure.
			 */
			offset = offsetof(struct HDIF_ms_area_address_range, controller_id);
			if (be32_to_cpu(arr->eactsz) >= offset)
				add_memory_controller(msarea, arange);

			offset = offsetof(struct HDIF_ms_area_address_range, phys_attr);
			if (be32_to_cpu(arr->eactsz) >= offset) {
				uint32_t attr = be32_to_cpu(arange->phys_attr);

				type = GETFIELD(PHYS_ATTR_TYPE_MASK, attr);
				status = GETFIELD(PHYS_ATTR_STATUS_MASK, attr);
			}

			if (!add_address_range(root, id, arange, type, status))
				prerror("Unable to use memory range %d from MSAREA %d\n", j, i);

			arange = (void *)arange + be32_to_cpu(arr->esize);
		}
	}
}

static struct dt_node *dt_hb_reserves;

static struct dt_node *add_hb_reserve_node(const char *name, u64 start, u64 end)
{
	/* label size + "ibm," + NULL */
	char node_name[HB_RESERVE_MEM_LABEL_SIZE + 5] = { 0 };
	struct dt_node *node, *hb;

	if (!dt_hb_reserves) {
		hb = dt_new_check(dt_root, "ibm,hostboot");
		dt_add_property_cells(hb, "#size-cells", 2);
		dt_add_property_cells(hb, "#address-cells", 2);

		dt_hb_reserves = dt_new_check(hb, "reserved-memory");
		dt_add_property(dt_hb_reserves, "ranges", NULL, 0);
		dt_add_property_cells(dt_hb_reserves, "#size-cells", 2);
		dt_add_property_cells(dt_hb_reserves, "#address-cells", 2);
	}

	/* Add "ibm," to reserved node name */
	if (strncasecmp(name, "ibm", 3))
		snprintf(node_name, 5, "ibm,");
	strcat(node_name, name);

	node = dt_new_addr(dt_hb_reserves, node_name, start);
	if (!node) {
		prerror("Unable to create node for %s@%llx\n",
			node_name, (unsigned long long) start);
		return NULL;
	}

	dt_add_property_u64s(node, "reg", start, end - start + 1);

	return node;
}

static void get_hb_reserved_mem(struct HDIF_common_hdr *ms_vpd)
{
	const struct msvpd_hb_reserved_mem *hb_resv_mem;
	u64 start_addr, end_addr, label_size;
	struct dt_node *node;
	int count, i;
	char label[HB_RESERVE_MEM_LABEL_SIZE + 1];

	/*
	 * XXX: Reservation names only exist on P9 and on P7/8 we get the
	 *      reserved ranges through the hostboot mini-FDT instead.
	 */
	if (proc_gen < proc_gen_p9)
		return;

	count = HDIF_get_iarray_size(ms_vpd, MSVPD_IDATA_HB_RESERVED_MEM);
	if (count <= 0) {
		prerror("MS VPD: No hostboot reserved memory found\n");
		return;
	}

	for (i = 0; i < count; i++) {
		hb_resv_mem = HDIF_get_iarray_item(ms_vpd,
						   MSVPD_IDATA_HB_RESERVED_MEM,
						   i, NULL);
		if (!CHECK_SPPTR(hb_resv_mem))
			continue;

		label_size = be32_to_cpu(hb_resv_mem->label_size);
		start_addr = be64_to_cpu(hb_resv_mem->start_addr);
		end_addr = be64_to_cpu(hb_resv_mem->end_addr);

		/* Zero length regions are a normal, but should be ignored */
		if (start_addr - end_addr == 0) {
			prlog(PR_DEBUG, "MEM: Ignoring zero length range\n");
			continue;
		}

		/*
		 * Workaround broken HDAT reserve regions which are
		 * bigger than 512MB
		 */
		if ((end_addr - start_addr) > 0x20000000) {
			prlog(PR_ERR, "MEM: Ignoring Bad HDAT reserve: too big\n");
			continue;
		}

		/* remove the HRMOR bypass bit */
		start_addr &= ~HRMOR_BIT;
		end_addr &= ~HRMOR_BIT;
		if (label_size > HB_RESERVE_MEM_LABEL_SIZE)
			label_size = HB_RESERVE_MEM_LABEL_SIZE;

		memset(label, 0, HB_RESERVE_MEM_LABEL_SIZE + 1);
		memcpy(label, hb_resv_mem->label, label_size);
		label[label_size] = '\0';

		/* Unnamed reservations are always broken. Ignore them. */
		if (strlen(label) == 0)
			continue;

		prlog(PR_DEBUG, "MEM: Reserve '%s' %#" PRIx64 "-%#" PRIx64 " (type/inst=0x%08x)\n",
		      label, start_addr, end_addr, be32_to_cpu(hb_resv_mem->type_instance));

		node = add_hb_reserve_node(label, start_addr, end_addr);
		if (!node) {
			prerror("unable to add node?\n");
			continue;
		}

		/* the three low bytes of type_instance is the instance data */
		dt_add_property_cells(node, "ibm,prd-instance",
			(be32_to_cpu(hb_resv_mem->type_instance) & 0xffffff));

		/*
		 * Most reservations are used by HBRT itself so we should leave
		 * the label as-is. The exception is hbrt-code-image which is
		 * used by opal-prd to locate the HBRT image. Older versions
		 * of opal-prd expect this to be "ibm,hbrt-code-image" so make
		 * sure the prefix is there.
		 */
		if (!strcmp(label, "hbrt-code-image"))
			strcpy(label, "ibm,hbrt-code-image");
		dt_add_property_string(node, "ibm,prd-label", label);
	}
}

static void parse_trace_reservations(struct HDIF_common_hdr *ms_vpd)
{
	unsigned int size;
	int count, i;

	/*
	 * The trace arrays are only setup when hostboot is explicitly
	 * configured to enable them. We need to check and gracefully handle
	 * when they're not present.
	 */

	if (!HDIF_get_idata(ms_vpd, MSVPD_IDATA_TRACE_AREAS, &size) || !size) {
		prlog(PR_DEBUG, "MS VPD: No trace areas found\n");
		return;
	}

	count = HDIF_get_iarray_size(ms_vpd, MSVPD_IDATA_TRACE_AREAS);
	if (count <= 0) {
		prlog(PR_DEBUG, "MS VPD: No trace areas found\n");
		return;
	}

	prlog(PR_INFO, "MS VPD: Found %d trace areas\n", count);

	for (i = 0; i < count; i++) {
		const struct msvpd_trace *trace_area;
		struct dt_node *node;
		u64 start, end;

		trace_area = HDIF_get_iarray_item(ms_vpd,
				MSVPD_IDATA_TRACE_AREAS, i, &size);

		if (!trace_area)
			return; /* shouldn't happen */

		start = be64_to_cpu(trace_area->start) & ~HRMOR_BIT;
		end = be64_to_cpu(trace_area->end) & ~HRMOR_BIT;

		prlog(PR_INFO,
			"MS VPD: Trace area: 0x%.16"PRIx64"-0x%.16"PRIx64"\n",
			start, end);

		node = add_hb_reserve_node("trace-area", start, end);
		if (!node) {
			prerror("MEM: Unable to reserve trace area %p-%p\n",
				(void *) start, (void *) end);
			continue;
		}

		dt_add_property(node, "no-map", NULL, 0);
	}
}

static bool __memory_parse(struct dt_node *root)
{
	struct HDIF_common_hdr *ms_vpd;
	const struct msvpd_ms_addr_config *msac;
	const struct msvpd_total_config_ms *tcms;
	unsigned int size;

	ms_vpd = get_hdif(&spira.ntuples.ms_vpd, MSVPD_HDIF_SIG);
	if (!ms_vpd) {
		prerror("MS VPD: invalid\n");
		op_display(OP_FATAL, OP_MOD_MEM, 0x0000);
		return false;
	}
	if (be32_to_cpu(spira.ntuples.ms_vpd.act_len) < sizeof(*ms_vpd)) {
		prerror("MS VPD: invalid size %u\n",
			be32_to_cpu(spira.ntuples.ms_vpd.act_len));
		op_display(OP_FATAL, OP_MOD_MEM, 0x0001);
		return false;
	}

	prlog(PR_DEBUG, "MS VPD: is at %p\n", ms_vpd);

	msac = HDIF_get_idata(ms_vpd, MSVPD_IDATA_MS_ADDR_CONFIG, &size);
	if (!CHECK_SPPTR(msac) || size < sizeof(*msac)) {
		prerror("MS VPD: bad msac size %u @ %p\n", size, msac);
		op_display(OP_FATAL, OP_MOD_MEM, 0x0002);
		return false;
	}
	prlog(PR_DEBUG, "MS VPD: MSAC is at %p\n", msac);

	dt_add_property_u64(dt_root, DT_PRIVATE "maxmem",
			    be64_to_cpu(msac->max_configured_ms_address));

	tcms = HDIF_get_idata(ms_vpd, MSVPD_IDATA_TOTAL_CONFIG_MS, &size);
	if (!CHECK_SPPTR(tcms) || size < sizeof(*tcms)) {
		prerror("MS VPD: Bad tcms size %u @ %p\n", size, tcms);
		op_display(OP_FATAL, OP_MOD_MEM, 0x0003);
		return false;
	}
	prlog(PR_DEBUG, "MS VPD: TCMS is at %p\n", tcms);

	prlog(PR_DEBUG, "MS VPD: Maximum configured address: 0x%llx\n",
	      (long long)be64_to_cpu(msac->max_configured_ms_address));
	prlog(PR_DEBUG, "MS VPD: Maximum possible address: 0x%llx\n",
	      (long long)be64_to_cpu(msac->max_possible_ms_address));

	get_msareas(root, ms_vpd);

	get_hb_reserved_mem(ms_vpd);

	parse_trace_reservations(ms_vpd);

	prlog(PR_INFO, "MS VPD: Total MB of RAM: 0x%llx\n",
	       (long long)be64_to_cpu(tcms->total_in_mb));

	return true;
}

void memory_parse(void)
{
	if (!__memory_parse(dt_root)) {
		prerror("MS VPD: Failed memory init !\n");
		abort();
	}
}

