// 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 <linux/slab.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);
