// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Dynamic reconfiguration memory support
 *
 * Copyright 2017 IBM Corporation
 */

#define pr_fmt(fmt) "drmem: " fmt

#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/memblock.h>
#include <asm/prom.h>
#include <asm/drmem.h>

static int n_root_addr_cells, n_root_size_cells;

static struct drmem_lmb_info __drmem_info;
struct drmem_lmb_info *drmem_info = &__drmem_info;
static bool in_drmem_update;

u64 drmem_lmb_memory_max(void)
{
	struct drmem_lmb *last_lmb;

	last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1];
	return last_lmb->base_addr + drmem_lmb_size();
}

static u32 drmem_lmb_flags(struct drmem_lmb *lmb)
{
	/*
	 * Return the value of the lmb flags field minus the reserved
	 * bit used internally for hotplug processing.
	 */
	return lmb->flags & ~DRMEM_LMB_RESERVED;
}

static struct property *clone_property(struct property *prop, u32 prop_sz)
{
	struct property *new_prop;

	new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
	if (!new_prop)
		return NULL;

	new_prop->name = kstrdup(prop->name, GFP_KERNEL);
	new_prop->value = kzalloc(prop_sz, GFP_KERNEL);
	if (!new_prop->name || !new_prop->value) {
		kfree(new_prop->name);
		kfree(new_prop->value);
		kfree(new_prop);
		return NULL;
	}

	new_prop->length = prop_sz;
#if defined(CONFIG_OF_DYNAMIC)
	of_property_set_flag(new_prop, OF_DYNAMIC);
#endif
	return new_prop;
}

static int drmem_update_dt_v1(struct device_node *memory,
			      struct property *prop)
{
	struct property *new_prop;
	struct of_drconf_cell_v1 *dr_cell;
	struct drmem_lmb *lmb;
	u32 *p;

	new_prop = clone_property(prop, prop->length);
	if (!new_prop)
		return -1;

	p = new_prop->value;
	*p++ = cpu_to_be32(drmem_info->n_lmbs);

	dr_cell = (struct of_drconf_cell_v1 *)p;

	for_each_drmem_lmb(lmb) {
		dr_cell->base_addr = cpu_to_be64(lmb->base_addr);
		dr_cell->drc_index = cpu_to_be32(lmb->drc_index);
		dr_cell->aa_index = cpu_to_be32(lmb->aa_index);
		dr_cell->flags = cpu_to_be32(drmem_lmb_flags(lmb));

		dr_cell++;
	}

	of_update_property(memory, new_prop);
	return 0;
}

static void init_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
				struct drmem_lmb *lmb)
{
	dr_cell->base_addr = cpu_to_be64(lmb->base_addr);
	dr_cell->drc_index = cpu_to_be32(lmb->drc_index);
	dr_cell->aa_index = cpu_to_be32(lmb->aa_index);
	dr_cell->flags = cpu_to_be32(drmem_lmb_flags(lmb));
}

static int drmem_update_dt_v2(struct device_node *memory,
			      struct property *prop)
{
	struct property *new_prop;
	struct of_drconf_cell_v2 *dr_cell;
	struct drmem_lmb *lmb, *prev_lmb;
	u32 lmb_sets, prop_sz, seq_lmbs;
	u32 *p;

	/* First pass, determine how many LMB sets are needed. */
	lmb_sets = 0;
	prev_lmb = NULL;
	for_each_drmem_lmb(lmb) {
		if (!prev_lmb) {
			prev_lmb = lmb;
			lmb_sets++;
			continue;
		}

		if (prev_lmb->aa_index != lmb->aa_index ||
		    drmem_lmb_flags(prev_lmb) != drmem_lmb_flags(lmb))
			lmb_sets++;

		prev_lmb = lmb;
	}

	prop_sz = lmb_sets * sizeof(*dr_cell) + sizeof(__be32);
	new_prop = clone_property(prop, prop_sz);
	if (!new_prop)
		return -1;

	p = new_prop->value;
	*p++ = cpu_to_be32(lmb_sets);

	dr_cell = (struct of_drconf_cell_v2 *)p;

	/* Second pass, populate the LMB set data */
	prev_lmb = NULL;
	seq_lmbs = 0;
	for_each_drmem_lmb(lmb) {
		if (prev_lmb == NULL) {
			/* Start of first LMB set */
			prev_lmb = lmb;
			init_drconf_v2_cell(dr_cell, lmb);
			seq_lmbs++;
			continue;
		}

		if (prev_lmb->aa_index != lmb->aa_index ||
		    drmem_lmb_flags(prev_lmb) != drmem_lmb_flags(lmb)) {
			/* end of one set, start of another */
			dr_cell->seq_lmbs = cpu_to_be32(seq_lmbs);
			dr_cell++;

			init_drconf_v2_cell(dr_cell, lmb);
			seq_lmbs = 1;
		} else {
			seq_lmbs++;
		}

		prev_lmb = lmb;
	}

	/* close out last LMB set */
	dr_cell->seq_lmbs = cpu_to_be32(seq_lmbs);
	of_update_property(memory, new_prop);
	return 0;
}

int drmem_update_dt(void)
{
	struct device_node *memory;
	struct property *prop;
	int rc = -1;

	memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
	if (!memory)
		return -1;

	/*
	 * Set in_drmem_update to prevent the notifier callback to process the
	 * DT property back since the change is coming from the LMB tree.
	 */
	in_drmem_update = true;
	prop = of_find_property(memory, "ibm,dynamic-memory", NULL);
	if (prop) {
		rc = drmem_update_dt_v1(memory, prop);
	} else {
		prop = of_find_property(memory, "ibm,dynamic-memory-v2", NULL);
		if (prop)
			rc = drmem_update_dt_v2(memory, prop);
	}
	in_drmem_update = false;

	of_node_put(memory);
	return rc;
}

static void read_drconf_v1_cell(struct drmem_lmb *lmb,
				       const __be32 **prop)
{
	const __be32 *p = *prop;

	lmb->base_addr = of_read_number(p, n_root_addr_cells);
	p += n_root_addr_cells;
	lmb->drc_index = of_read_number(p++, 1);

	p++; /* skip reserved field */

	lmb->aa_index = of_read_number(p++, 1);
	lmb->flags = of_read_number(p++, 1);

	*prop = p;
}

static int
__walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm, void *data,
		     int (*func)(struct drmem_lmb *, const __be32 **, void *))
{
	struct drmem_lmb lmb;
	u32 i, n_lmbs;
	int ret = 0;

	n_lmbs = of_read_number(prop++, 1);
	for (i = 0; i < n_lmbs; i++) {
		read_drconf_v1_cell(&lmb, &prop);
		ret = func(&lmb, &usm, data);
		if (ret)
			break;
	}

	return ret;
}

static void read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
				       const __be32 **prop)
{
	const __be32 *p = *prop;

	dr_cell->seq_lmbs = of_read_number(p++, 1);
	dr_cell->base_addr = of_read_number(p, n_root_addr_cells);
	p += n_root_addr_cells;
	dr_cell->drc_index = of_read_number(p++, 1);
	dr_cell->aa_index = of_read_number(p++, 1);
	dr_cell->flags = of_read_number(p++, 1);

	*prop = p;
}

static int
__walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm, void *data,
		     int (*func)(struct drmem_lmb *, const __be32 **, void *))
{
	struct of_drconf_cell_v2 dr_cell;
	struct drmem_lmb lmb;
	u32 i, j, lmb_sets;
	int ret = 0;

	lmb_sets = of_read_number(prop++, 1);
	for (i = 0; i < lmb_sets; i++) {
		read_drconf_v2_cell(&dr_cell, &prop);

		for (j = 0; j < dr_cell.seq_lmbs; j++) {
			lmb.base_addr = dr_cell.base_addr;
			dr_cell.base_addr += drmem_lmb_size();

			lmb.drc_index = dr_cell.drc_index;
			dr_cell.drc_index++;

			lmb.aa_index = dr_cell.aa_index;
			lmb.flags = dr_cell.flags;

			ret = func(&lmb, &usm, data);
			if (ret)
				break;
		}
	}

	return ret;
}

#ifdef CONFIG_PPC_PSERIES
int __init walk_drmem_lmbs_early(unsigned long node, void *data,
		int (*func)(struct drmem_lmb *, const __be32 **, void *))
{
	const __be32 *prop, *usm;
	int len, ret = -ENODEV;

	prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len);
	if (!prop || len < dt_root_size_cells * sizeof(__be32))
		return ret;

	/* Get the address & size cells */
	n_root_addr_cells = dt_root_addr_cells;
	n_root_size_cells = dt_root_size_cells;

	drmem_info->lmb_size = dt_mem_next_cell(dt_root_size_cells, &prop);

	usm = of_get_flat_dt_prop(node, "linux,drconf-usable-memory", &len);

	prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &len);
	if (prop) {
		ret = __walk_drmem_v1_lmbs(prop, usm, data, func);
	} else {
		prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory-v2",
					   &len);
		if (prop)
			ret = __walk_drmem_v2_lmbs(prop, usm, data, func);
	}

	memblock_dump_all();
	return ret;
}

/*
 * Update the LMB associativity index.
 */
static int update_lmb(struct drmem_lmb *updated_lmb,
		      __maybe_unused const __be32 **usm,
		      __maybe_unused void *data)
{
	struct drmem_lmb *lmb;

	for_each_drmem_lmb(lmb) {
		if (lmb->drc_index != updated_lmb->drc_index)
			continue;

		lmb->aa_index = updated_lmb->aa_index;
		break;
	}
	return 0;
}

/*
 * Update the LMB associativity index.
 *
 * This needs to be called when the hypervisor is updating the
 * dynamic-reconfiguration-memory node property.
 */
void drmem_update_lmbs(struct property *prop)
{
	/*
	 * Don't update the LMBs if triggered by the update done in
	 * drmem_update_dt(), the LMB values have been used to the update the DT
	 * property in that case.
	 */
	if (in_drmem_update)
		return;
	if (!strcmp(prop->name, "ibm,dynamic-memory"))
		__walk_drmem_v1_lmbs(prop->value, NULL, NULL, update_lmb);
	else if (!strcmp(prop->name, "ibm,dynamic-memory-v2"))
		__walk_drmem_v2_lmbs(prop->value, NULL, NULL, update_lmb);
}
#endif

static int init_drmem_lmb_size(struct device_node *dn)
{
	const __be32 *prop;
	int len;

	if (drmem_info->lmb_size)
		return 0;

	prop = of_get_property(dn, "ibm,lmb-size", &len);
	if (!prop || len < n_root_size_cells * sizeof(__be32)) {
		pr_info("Could not determine LMB size\n");
		return -1;
	}

	drmem_info->lmb_size = of_read_number(prop, n_root_size_cells);
	return 0;
}

/*
 * Returns the property linux,drconf-usable-memory if
 * it exists (the property exists only in kexec/kdump kernels,
 * added by kexec-tools)
 */
static const __be32 *of_get_usable_memory(struct device_node *dn)
{
	const __be32 *prop;
	u32 len;

	prop = of_get_property(dn, "linux,drconf-usable-memory", &len);
	if (!prop || len < sizeof(unsigned int))
		return NULL;

	return prop;
}

int walk_drmem_lmbs(struct device_node *dn, void *data,
		    int (*func)(struct drmem_lmb *, const __be32 **, void *))
{
	const __be32 *prop, *usm;
	int ret = -ENODEV;

	if (!of_root)
		return ret;

	/* Get the address & size cells */
	of_node_get(of_root);
	n_root_addr_cells = of_n_addr_cells(of_root);
	n_root_size_cells = of_n_size_cells(of_root);
	of_node_put(of_root);

	if (init_drmem_lmb_size(dn))
		return ret;

	usm = of_get_usable_memory(dn);

	prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
	if (prop) {
		ret = __walk_drmem_v1_lmbs(prop, usm, data, func);
	} else {
		prop = of_get_property(dn, "ibm,dynamic-memory-v2", NULL);
		if (prop)
			ret = __walk_drmem_v2_lmbs(prop, usm, data, func);
	}

	return ret;
}

static void __init init_drmem_v1_lmbs(const __be32 *prop)
{
	struct drmem_lmb *lmb;

	drmem_info->n_lmbs = of_read_number(prop++, 1);
	if (drmem_info->n_lmbs == 0)
		return;

	drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
				   GFP_KERNEL);
	if (!drmem_info->lmbs)
		return;

	for_each_drmem_lmb(lmb)
		read_drconf_v1_cell(lmb, &prop);
}

static void __init init_drmem_v2_lmbs(const __be32 *prop)
{
	struct drmem_lmb *lmb;
	struct of_drconf_cell_v2 dr_cell;
	const __be32 *p;
	u32 i, j, lmb_sets;
	int lmb_index;

	lmb_sets = of_read_number(prop++, 1);
	if (lmb_sets == 0)
		return;

	/* first pass, calculate the number of LMBs */
	p = prop;
	for (i = 0; i < lmb_sets; i++) {
		read_drconf_v2_cell(&dr_cell, &p);
		drmem_info->n_lmbs += dr_cell.seq_lmbs;
	}

	drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
				   GFP_KERNEL);
	if (!drmem_info->lmbs)
		return;

	/* second pass, read in the LMB information */
	lmb_index = 0;
	p = prop;

	for (i = 0; i < lmb_sets; i++) {
		read_drconf_v2_cell(&dr_cell, &p);

		for (j = 0; j < dr_cell.seq_lmbs; j++) {
			lmb = &drmem_info->lmbs[lmb_index++];

			lmb->base_addr = dr_cell.base_addr;
			dr_cell.base_addr += drmem_info->lmb_size;

			lmb->drc_index = dr_cell.drc_index;
			dr_cell.drc_index++;

			lmb->aa_index = dr_cell.aa_index;
			lmb->flags = dr_cell.flags;
		}
	}
}

static int __init drmem_init(void)
{
	struct device_node *dn;
	const __be32 *prop;

	dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
	if (!dn) {
		pr_info("No dynamic reconfiguration memory found\n");
		return 0;
	}

	if (init_drmem_lmb_size(dn)) {
		of_node_put(dn);
		return 0;
	}

	prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
	if (prop) {
		init_drmem_v1_lmbs(prop);
	} else {
		prop = of_get_property(dn, "ibm,dynamic-memory-v2", NULL);
		if (prop)
			init_drmem_v2_lmbs(prop);
	}

	of_node_put(dn);
	return 0;
}
late_initcall(drmem_init);
