// SPDX-License-Identifier: GPL-2.0
/* mdesc.c: Sun4V machine description handling.
 *
 * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
 */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/log2.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/memblock.h>
#include <linux/export.h>
#include <linux/refcount.h>

#include <asm/cpudata.h>
#include <asm/hypervisor.h>
#include <asm/mdesc.h>
#include <asm/prom.h>
#include <linux/uaccess.h>
#include <asm/oplib.h>
#include <asm/smp.h>
#include <asm/adi.h>

/* Unlike the OBP device tree, the machine description is a full-on
 * DAG.  An arbitrary number of ARCs are possible from one
 * node to other nodes and thus we can't use the OBP device_node
 * data structure to represent these nodes inside of the kernel.
 *
 * Actually, it isn't even a DAG, because there are back pointers
 * which create cycles in the graph.
 *
 * mdesc_hdr and mdesc_elem describe the layout of the data structure
 * we get from the Hypervisor.
 */
struct mdesc_hdr {
	u32	version; /* Transport version */
	u32	node_sz; /* node block size */
	u32	name_sz; /* name block size */
	u32	data_sz; /* data block size */
	char	data[];
} __attribute__((aligned(16)));

struct mdesc_elem {
	u8	tag;
#define MD_LIST_END	0x00
#define MD_NODE		0x4e
#define MD_NODE_END	0x45
#define MD_NOOP		0x20
#define MD_PROP_ARC	0x61
#define MD_PROP_VAL	0x76
#define MD_PROP_STR	0x73
#define MD_PROP_DATA	0x64
	u8	name_len;
	u16	resv;
	u32	name_offset;
	union {
		struct {
			u32	data_len;
			u32	data_offset;
		} data;
		u64	val;
	} d;
};

struct mdesc_mem_ops {
	struct mdesc_handle *(*alloc)(unsigned int mdesc_size);
	void (*free)(struct mdesc_handle *handle);
};

struct mdesc_handle {
	struct list_head	list;
	struct mdesc_mem_ops	*mops;
	void			*self_base;
	refcount_t		refcnt;
	unsigned int		handle_size;
	struct mdesc_hdr	mdesc;
};

typedef int (*mdesc_node_info_get_f)(struct mdesc_handle *, u64,
				     union md_node_info *);
typedef void (*mdesc_node_info_rel_f)(union md_node_info *);
typedef bool (*mdesc_node_match_f)(union md_node_info *, union md_node_info *);

struct md_node_ops {
	char			*name;
	mdesc_node_info_get_f	get_info;
	mdesc_node_info_rel_f	rel_info;
	mdesc_node_match_f	node_match;
};

static int get_vdev_port_node_info(struct mdesc_handle *md, u64 node,
				   union md_node_info *node_info);
static void rel_vdev_port_node_info(union md_node_info *node_info);
static bool vdev_port_node_match(union md_node_info *a_node_info,
				 union md_node_info *b_node_info);

static int get_ds_port_node_info(struct mdesc_handle *md, u64 node,
				 union md_node_info *node_info);
static void rel_ds_port_node_info(union md_node_info *node_info);
static bool ds_port_node_match(union md_node_info *a_node_info,
			       union md_node_info *b_node_info);

/* supported node types which can be registered */
static struct md_node_ops md_node_ops_table[] = {
	{"virtual-device-port", get_vdev_port_node_info,
	 rel_vdev_port_node_info, vdev_port_node_match},
	{"domain-services-port", get_ds_port_node_info,
	 rel_ds_port_node_info, ds_port_node_match},
	{NULL, NULL, NULL, NULL}
};

static void mdesc_get_node_ops(const char *node_name,
			       mdesc_node_info_get_f *get_info_f,
			       mdesc_node_info_rel_f *rel_info_f,
			       mdesc_node_match_f *match_f)
{
	int i;

	if (get_info_f)
		*get_info_f = NULL;

	if (rel_info_f)
		*rel_info_f = NULL;

	if (match_f)
		*match_f = NULL;

	if (!node_name)
		return;

	for (i = 0; md_node_ops_table[i].name != NULL; i++) {
		if (strcmp(md_node_ops_table[i].name, node_name) == 0) {
			if (get_info_f)
				*get_info_f = md_node_ops_table[i].get_info;

			if (rel_info_f)
				*rel_info_f = md_node_ops_table[i].rel_info;

			if (match_f)
				*match_f = md_node_ops_table[i].node_match;

			break;
		}
	}
}

static void mdesc_handle_init(struct mdesc_handle *hp,
			      unsigned int handle_size,
			      void *base)
{
	BUG_ON(((unsigned long)&hp->mdesc) & (16UL - 1));

	memset(hp, 0, handle_size);
	INIT_LIST_HEAD(&hp->list);
	hp->self_base = base;
	refcount_set(&hp->refcnt, 1);
	hp->handle_size = handle_size;
}

static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size)
{
	unsigned int handle_size, alloc_size;
	struct mdesc_handle *hp;
	unsigned long paddr;

	handle_size = (sizeof(struct mdesc_handle) -
		       sizeof(struct mdesc_hdr) +
		       mdesc_size);
	alloc_size = PAGE_ALIGN(handle_size);

	paddr = memblock_phys_alloc(alloc_size, PAGE_SIZE);

	hp = NULL;
	if (paddr) {
		hp = __va(paddr);
		mdesc_handle_init(hp, handle_size, hp);
	}
	return hp;
}

static void __init mdesc_memblock_free(struct mdesc_handle *hp)
{
	unsigned int alloc_size;

	BUG_ON(refcount_read(&hp->refcnt) != 0);
	BUG_ON(!list_empty(&hp->list));

	alloc_size = PAGE_ALIGN(hp->handle_size);
	memblock_free(hp, alloc_size);
}

static struct mdesc_mem_ops memblock_mdesc_ops = {
	.alloc = mdesc_memblock_alloc,
	.free  = mdesc_memblock_free,
};

static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size)
{
	unsigned int handle_size;
	struct mdesc_handle *hp;
	unsigned long addr;
	void *base;

	handle_size = (sizeof(struct mdesc_handle) -
		       sizeof(struct mdesc_hdr) +
		       mdesc_size);
	base = kmalloc(handle_size + 15, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
	if (!base)
		return NULL;

	addr = (unsigned long)base;
	addr = (addr + 15UL) & ~15UL;
	hp = (struct mdesc_handle *) addr;

	mdesc_handle_init(hp, handle_size, base);

	return hp;
}

static void mdesc_kfree(struct mdesc_handle *hp)
{
	BUG_ON(refcount_read(&hp->refcnt) != 0);
	BUG_ON(!list_empty(&hp->list));

	kfree(hp->self_base);
}

static struct mdesc_mem_ops kmalloc_mdesc_memops = {
	.alloc = mdesc_kmalloc,
	.free  = mdesc_kfree,
};

static struct mdesc_handle *mdesc_alloc(unsigned int mdesc_size,
					struct mdesc_mem_ops *mops)
{
	struct mdesc_handle *hp = mops->alloc(mdesc_size);

	if (hp)
		hp->mops = mops;

	return hp;
}

static void mdesc_free(struct mdesc_handle *hp)
{
	hp->mops->free(hp);
}

static struct mdesc_handle *cur_mdesc;
static LIST_HEAD(mdesc_zombie_list);
static DEFINE_SPINLOCK(mdesc_lock);

struct mdesc_handle *mdesc_grab(void)
{
	struct mdesc_handle *hp;
	unsigned long flags;

	spin_lock_irqsave(&mdesc_lock, flags);
	hp = cur_mdesc;
	if (hp)
		refcount_inc(&hp->refcnt);
	spin_unlock_irqrestore(&mdesc_lock, flags);

	return hp;
}
EXPORT_SYMBOL(mdesc_grab);

void mdesc_release(struct mdesc_handle *hp)
{
	unsigned long flags;

	spin_lock_irqsave(&mdesc_lock, flags);
	if (refcount_dec_and_test(&hp->refcnt)) {
		list_del_init(&hp->list);
		hp->mops->free(hp);
	}
	spin_unlock_irqrestore(&mdesc_lock, flags);
}
EXPORT_SYMBOL(mdesc_release);

static DEFINE_MUTEX(mdesc_mutex);
static struct mdesc_notifier_client *client_list;

void mdesc_register_notifier(struct mdesc_notifier_client *client)
{
	bool supported = false;
	u64 node;
	int i;

	mutex_lock(&mdesc_mutex);

	/* check to see if the node is supported for registration */
	for (i = 0; md_node_ops_table[i].name != NULL; i++) {
		if (strcmp(md_node_ops_table[i].name, client->node_name) == 0) {
			supported = true;
			break;
		}
	}

	if (!supported) {
		pr_err("MD: %s node not supported\n", client->node_name);
		mutex_unlock(&mdesc_mutex);
		return;
	}

	client->next = client_list;
	client_list = client;

	mdesc_for_each_node_by_name(cur_mdesc, node, client->node_name)
		client->add(cur_mdesc, node, client->node_name);

	mutex_unlock(&mdesc_mutex);
}

static const u64 *parent_cfg_handle(struct mdesc_handle *hp, u64 node)
{
	const u64 *id;
	u64 a;

	id = NULL;
	mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) {
		u64 target;

		target = mdesc_arc_target(hp, a);
		id = mdesc_get_property(hp, target,
					"cfg-handle", NULL);
		if (id)
			break;
	}

	return id;
}

static int get_vdev_port_node_info(struct mdesc_handle *md, u64 node,
				   union md_node_info *node_info)
{
	const u64 *parent_cfg_hdlp;
	const char *name;
	const u64 *idp;

	/*
	 * Virtual device nodes are distinguished by:
	 * 1. "id" property
	 * 2. "name" property
	 * 3. parent node "cfg-handle" property
	 */
	idp = mdesc_get_property(md, node, "id", NULL);
	name = mdesc_get_property(md, node, "name", NULL);
	parent_cfg_hdlp = parent_cfg_handle(md, node);

	if (!idp || !name || !parent_cfg_hdlp)
		return -1;

	node_info->vdev_port.id = *idp;
	node_info->vdev_port.name = kstrdup_const(name, GFP_KERNEL);
	if (!node_info->vdev_port.name)
		return -1;
	node_info->vdev_port.parent_cfg_hdl = *parent_cfg_hdlp;

	return 0;
}

static void rel_vdev_port_node_info(union md_node_info *node_info)
{
	if (node_info && node_info->vdev_port.name) {
		kfree_const(node_info->vdev_port.name);
		node_info->vdev_port.name = NULL;
	}
}

static bool vdev_port_node_match(union md_node_info *a_node_info,
				 union md_node_info *b_node_info)
{
	if (a_node_info->vdev_port.id != b_node_info->vdev_port.id)
		return false;

	if (a_node_info->vdev_port.parent_cfg_hdl !=
	    b_node_info->vdev_port.parent_cfg_hdl)
		return false;

	if (strncmp(a_node_info->vdev_port.name,
		    b_node_info->vdev_port.name, MDESC_MAX_STR_LEN) != 0)
		return false;

	return true;
}

static int get_ds_port_node_info(struct mdesc_handle *md, u64 node,
				 union md_node_info *node_info)
{
	const u64 *idp;

	/* DS port nodes use the "id" property to distinguish them */
	idp = mdesc_get_property(md, node, "id", NULL);
	if (!idp)
		return -1;

	node_info->ds_port.id = *idp;

	return 0;
}

static void rel_ds_port_node_info(union md_node_info *node_info)
{
}

static bool ds_port_node_match(union md_node_info *a_node_info,
			       union md_node_info *b_node_info)
{
	if (a_node_info->ds_port.id != b_node_info->ds_port.id)
		return false;

	return true;
}

/* Run 'func' on nodes which are in A but not in B.  */
static void invoke_on_missing(const char *name,
			      struct mdesc_handle *a,
			      struct mdesc_handle *b,
			      void (*func)(struct mdesc_handle *, u64,
					   const char *node_name))
{
	mdesc_node_info_get_f get_info_func;
	mdesc_node_info_rel_f rel_info_func;
	mdesc_node_match_f node_match_func;
	union md_node_info a_node_info;
	union md_node_info b_node_info;
	bool found;
	u64 a_node;
	u64 b_node;
	int rv;

	/*
	 * Find the get_info, rel_info and node_match ops for the given
	 * node name
	 */
	mdesc_get_node_ops(name, &get_info_func, &rel_info_func,
			   &node_match_func);

	/* If we didn't find a match, the node type is not supported */
	if (!get_info_func || !rel_info_func || !node_match_func) {
		pr_err("MD: %s node type is not supported\n", name);
		return;
	}

	mdesc_for_each_node_by_name(a, a_node, name) {
		found = false;

		rv = get_info_func(a, a_node, &a_node_info);
		if (rv != 0) {
			pr_err("MD: Cannot find 1 or more required match properties for %s node.\n",
			       name);
			continue;
		}

		/* Check each node in B for node matching a_node */
		mdesc_for_each_node_by_name(b, b_node, name) {
			rv = get_info_func(b, b_node, &b_node_info);
			if (rv != 0)
				continue;

			if (node_match_func(&a_node_info, &b_node_info)) {
				found = true;
				rel_info_func(&b_node_info);
				break;
			}

			rel_info_func(&b_node_info);
		}

		rel_info_func(&a_node_info);

		if (!found)
			func(a, a_node, name);
	}
}

static void notify_one(struct mdesc_notifier_client *p,
		       struct mdesc_handle *old_hp,
		       struct mdesc_handle *new_hp)
{
	invoke_on_missing(p->node_name, old_hp, new_hp, p->remove);
	invoke_on_missing(p->node_name, new_hp, old_hp, p->add);
}

static void mdesc_notify_clients(struct mdesc_handle *old_hp,
				 struct mdesc_handle *new_hp)
{
	struct mdesc_notifier_client *p = client_list;

	while (p) {
		notify_one(p, old_hp, new_hp);
		p = p->next;
	}
}

void mdesc_update(void)
{
	unsigned long len, real_len, status;
	struct mdesc_handle *hp, *orig_hp;
	unsigned long flags;

	mutex_lock(&mdesc_mutex);

	(void) sun4v_mach_desc(0UL, 0UL, &len);

	hp = mdesc_alloc(len, &kmalloc_mdesc_memops);
	if (!hp) {
		printk(KERN_ERR "MD: mdesc alloc fails\n");
		goto out;
	}

	status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len);
	if (status != HV_EOK || real_len > len) {
		printk(KERN_ERR "MD: mdesc reread fails with %lu\n",
		       status);
		refcount_dec(&hp->refcnt);
		mdesc_free(hp);
		goto out;
	}

	spin_lock_irqsave(&mdesc_lock, flags);
	orig_hp = cur_mdesc;
	cur_mdesc = hp;
	spin_unlock_irqrestore(&mdesc_lock, flags);

	mdesc_notify_clients(orig_hp, hp);

	spin_lock_irqsave(&mdesc_lock, flags);
	if (refcount_dec_and_test(&orig_hp->refcnt))
		mdesc_free(orig_hp);
	else
		list_add(&orig_hp->list, &mdesc_zombie_list);
	spin_unlock_irqrestore(&mdesc_lock, flags);

out:
	mutex_unlock(&mdesc_mutex);
}

u64 mdesc_get_node(struct mdesc_handle *hp, const char *node_name,
		   union md_node_info *node_info)
{
	mdesc_node_info_get_f get_info_func;
	mdesc_node_info_rel_f rel_info_func;
	mdesc_node_match_f node_match_func;
	union md_node_info hp_node_info;
	u64 hp_node;
	int rv;

	if (hp == NULL || node_name == NULL || node_info == NULL)
		return MDESC_NODE_NULL;

	/* Find the ops for the given node name */
	mdesc_get_node_ops(node_name, &get_info_func, &rel_info_func,
			   &node_match_func);

	/* If we didn't find ops for the given node name, it is not supported */
	if (!get_info_func || !rel_info_func || !node_match_func) {
		pr_err("MD: %s node is not supported\n", node_name);
		return -EINVAL;
	}

	mdesc_for_each_node_by_name(hp, hp_node, node_name) {
		rv = get_info_func(hp, hp_node, &hp_node_info);
		if (rv != 0)
			continue;

		if (node_match_func(node_info, &hp_node_info))
			break;

		rel_info_func(&hp_node_info);
	}

	rel_info_func(&hp_node_info);

	return hp_node;
}
EXPORT_SYMBOL(mdesc_get_node);

int mdesc_get_node_info(struct mdesc_handle *hp, u64 node,
			const char *node_name, union md_node_info *node_info)
{
	mdesc_node_info_get_f get_info_func;
	int rv;

	if (hp == NULL || node == MDESC_NODE_NULL ||
	    node_name == NULL || node_info == NULL)
		return -EINVAL;

	/* Find the get_info op for the given node name */
	mdesc_get_node_ops(node_name, &get_info_func, NULL, NULL);

	/* If we didn't find a get_info_func, the node name is not supported */
	if (get_info_func == NULL) {
		pr_err("MD: %s node is not supported\n", node_name);
		return -EINVAL;
	}

	rv = get_info_func(hp, node, node_info);
	if (rv != 0) {
		pr_err("MD: Cannot find 1 or more required match properties for %s node.\n",
		       node_name);
		return -1;
	}

	return 0;
}
EXPORT_SYMBOL(mdesc_get_node_info);

static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc)
{
	return (struct mdesc_elem *) mdesc->data;
}

static void *name_block(struct mdesc_hdr *mdesc)
{
	return ((void *) node_block(mdesc)) + mdesc->node_sz;
}

static void *data_block(struct mdesc_hdr *mdesc)
{
	return ((void *) name_block(mdesc)) + mdesc->name_sz;
}

u64 mdesc_node_by_name(struct mdesc_handle *hp,
		       u64 from_node, const char *name)
{
	struct mdesc_elem *ep = node_block(&hp->mdesc);
	const char *names = name_block(&hp->mdesc);
	u64 last_node = hp->mdesc.node_sz / 16;
	u64 ret;

	if (from_node == MDESC_NODE_NULL) {
		ret = from_node = 0;
	} else if (from_node >= last_node) {
		return MDESC_NODE_NULL;
	} else {
		ret = ep[from_node].d.val;
	}

	while (ret < last_node) {
		if (ep[ret].tag != MD_NODE)
			return MDESC_NODE_NULL;
		if (!strcmp(names + ep[ret].name_offset, name))
			break;
		ret = ep[ret].d.val;
	}
	if (ret >= last_node)
		ret = MDESC_NODE_NULL;
	return ret;
}
EXPORT_SYMBOL(mdesc_node_by_name);

const void *mdesc_get_property(struct mdesc_handle *hp, u64 node,
			       const char *name, int *lenp)
{
	const char *names = name_block(&hp->mdesc);
	u64 last_node = hp->mdesc.node_sz / 16;
	void *data = data_block(&hp->mdesc);
	struct mdesc_elem *ep;

	if (node == MDESC_NODE_NULL || node >= last_node)
		return NULL;

	ep = node_block(&hp->mdesc) + node;
	ep++;
	for (; ep->tag != MD_NODE_END; ep++) {
		void *val = NULL;
		int len = 0;

		switch (ep->tag) {
		case MD_PROP_VAL:
			val = &ep->d.val;
			len = 8;
			break;

		case MD_PROP_STR:
		case MD_PROP_DATA:
			val = data + ep->d.data.data_offset;
			len = ep->d.data.data_len;
			break;

		default:
			break;
		}
		if (!val)
			continue;

		if (!strcmp(names + ep->name_offset, name)) {
			if (lenp)
				*lenp = len;
			return val;
		}
	}

	return NULL;
}
EXPORT_SYMBOL(mdesc_get_property);

u64 mdesc_next_arc(struct mdesc_handle *hp, u64 from, const char *arc_type)
{
	struct mdesc_elem *ep, *base = node_block(&hp->mdesc);
	const char *names = name_block(&hp->mdesc);
	u64 last_node = hp->mdesc.node_sz / 16;

	if (from == MDESC_NODE_NULL || from >= last_node)
		return MDESC_NODE_NULL;

	ep = base + from;

	ep++;
	for (; ep->tag != MD_NODE_END; ep++) {
		if (ep->tag != MD_PROP_ARC)
			continue;

		if (strcmp(names + ep->name_offset, arc_type))
			continue;

		return ep - base;
	}

	return MDESC_NODE_NULL;
}
EXPORT_SYMBOL(mdesc_next_arc);

u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc)
{
	struct mdesc_elem *ep, *base = node_block(&hp->mdesc);

	ep = base + arc;

	return ep->d.val;
}
EXPORT_SYMBOL(mdesc_arc_target);

const char *mdesc_node_name(struct mdesc_handle *hp, u64 node)
{
	struct mdesc_elem *ep, *base = node_block(&hp->mdesc);
	const char *names = name_block(&hp->mdesc);
	u64 last_node = hp->mdesc.node_sz / 16;

	if (node == MDESC_NODE_NULL || node >= last_node)
		return NULL;

	ep = base + node;
	if (ep->tag != MD_NODE)
		return NULL;

	return names + ep->name_offset;
}
EXPORT_SYMBOL(mdesc_node_name);

static u64 max_cpus = 64;

static void __init report_platform_properties(void)
{
	struct mdesc_handle *hp = mdesc_grab();
	u64 pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform");
	const char *s;
	const u64 *v;

	if (pn == MDESC_NODE_NULL) {
		prom_printf("No platform node in machine-description.\n");
		prom_halt();
	}

	s = mdesc_get_property(hp, pn, "banner-name", NULL);
	printk("PLATFORM: banner-name [%s]\n", s);
	s = mdesc_get_property(hp, pn, "name", NULL);
	printk("PLATFORM: name [%s]\n", s);

	v = mdesc_get_property(hp, pn, "hostid", NULL);
	if (v)
		printk("PLATFORM: hostid [%08llx]\n", *v);
	v = mdesc_get_property(hp, pn, "serial#", NULL);
	if (v)
		printk("PLATFORM: serial# [%08llx]\n", *v);
	v = mdesc_get_property(hp, pn, "stick-frequency", NULL);
	printk("PLATFORM: stick-frequency [%08llx]\n", *v);
	v = mdesc_get_property(hp, pn, "mac-address", NULL);
	if (v)
		printk("PLATFORM: mac-address [%llx]\n", *v);
	v = mdesc_get_property(hp, pn, "watchdog-resolution", NULL);
	if (v)
		printk("PLATFORM: watchdog-resolution [%llu ms]\n", *v);
	v = mdesc_get_property(hp, pn, "watchdog-max-timeout", NULL);
	if (v)
		printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v);
	v = mdesc_get_property(hp, pn, "max-cpus", NULL);
	if (v) {
		max_cpus = *v;
		printk("PLATFORM: max-cpus [%llu]\n", max_cpus);
	}

#ifdef CONFIG_SMP
	{
		int max_cpu, i;

		if (v) {
			max_cpu = *v;
			if (max_cpu > NR_CPUS)
				max_cpu = NR_CPUS;
		} else {
			max_cpu = NR_CPUS;
		}
		for (i = 0; i < max_cpu; i++)
			set_cpu_possible(i, true);
	}
#endif

	mdesc_release(hp);
}

static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)
{
	const u64 *level = mdesc_get_property(hp, mp, "level", NULL);
	const u64 *size = mdesc_get_property(hp, mp, "size", NULL);
	const u64 *line_size = mdesc_get_property(hp, mp, "line-size", NULL);
	const char *type;
	int type_len;

	type = mdesc_get_property(hp, mp, "type", &type_len);

	switch (*level) {
	case 1:
		if (of_find_in_proplist(type, "instn", type_len)) {
			c->icache_size = *size;
			c->icache_line_size = *line_size;
		} else if (of_find_in_proplist(type, "data", type_len)) {
			c->dcache_size = *size;
			c->dcache_line_size = *line_size;
		}
		break;

	case 2:
		c->ecache_size = *size;
		c->ecache_line_size = *line_size;
		break;

	default:
		break;
	}

	if (*level == 1) {
		u64 a;

		mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
			u64 target = mdesc_arc_target(hp, a);
			const char *name = mdesc_node_name(hp, target);

			if (!strcmp(name, "cache"))
				fill_in_one_cache(c, hp, target);
		}
	}
}

static void find_back_node_value(struct mdesc_handle *hp, u64 node,
				 char *srch_val,
				 void (*func)(struct mdesc_handle *, u64, int),
				 u64 val, int depth)
{
	u64 arc;

	/* Since we have an estimate of recursion depth, do a sanity check. */
	if (depth == 0)
		return;

	mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) {
		u64 n = mdesc_arc_target(hp, arc);
		const char *name = mdesc_node_name(hp, n);

		if (!strcmp(srch_val, name))
			(*func)(hp, n, val);

		find_back_node_value(hp, n, srch_val, func, val, depth-1);
	}
}

static void __mark_core_id(struct mdesc_handle *hp, u64 node,
			   int core_id)
{
	const u64 *id = mdesc_get_property(hp, node, "id", NULL);

	if (*id < num_possible_cpus())
		cpu_data(*id).core_id = core_id;
}

static void __mark_max_cache_id(struct mdesc_handle *hp, u64 node,
				int max_cache_id)
{
	const u64 *id = mdesc_get_property(hp, node, "id", NULL);

	if (*id < num_possible_cpus()) {
		cpu_data(*id).max_cache_id = max_cache_id;

		/**
		 * On systems without explicit socket descriptions socket
		 * is max_cache_id
		 */
		cpu_data(*id).sock_id = max_cache_id;
	}
}

static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
			  int core_id)
{
	find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
}

static void mark_max_cache_ids(struct mdesc_handle *hp, u64 mp,
			       int max_cache_id)
{
	find_back_node_value(hp, mp, "cpu", __mark_max_cache_id,
			     max_cache_id, 10);
}

static void set_core_ids(struct mdesc_handle *hp)
{
	int idx;
	u64 mp;

	idx = 1;

	/* Identify unique cores by looking for cpus backpointed to by
	 * level 1 instruction caches.
	 */
	mdesc_for_each_node_by_name(hp, mp, "cache") {
		const u64 *level;
		const char *type;
		int len;

		level = mdesc_get_property(hp, mp, "level", NULL);
		if (*level != 1)
			continue;

		type = mdesc_get_property(hp, mp, "type", &len);
		if (!of_find_in_proplist(type, "instn", len))
			continue;

		mark_core_ids(hp, mp, idx);
		idx++;
	}
}

static int set_max_cache_ids_by_cache(struct mdesc_handle *hp, int level)
{
	u64 mp;
	int idx = 1;
	int fnd = 0;

	/**
	 * Identify unique highest level of shared cache by looking for cpus
	 * backpointed to by shared level N caches.
	 */
	mdesc_for_each_node_by_name(hp, mp, "cache") {
		const u64 *cur_lvl;

		cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
		if (*cur_lvl != level)
			continue;
		mark_max_cache_ids(hp, mp, idx);
		idx++;
		fnd = 1;
	}
	return fnd;
}

static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp)
{
	int idx = 1;

	mdesc_for_each_node_by_name(hp, mp, "socket") {
		u64 a;

		mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
			u64 t = mdesc_arc_target(hp, a);
			const char *name;
			const u64 *id;

			name = mdesc_node_name(hp, t);
			if (strcmp(name, "cpu"))
				continue;

			id = mdesc_get_property(hp, t, "id", NULL);
			if (*id < num_possible_cpus())
				cpu_data(*id).sock_id = idx;
		}
		idx++;
	}
}

static void set_sock_ids(struct mdesc_handle *hp)
{
	u64 mp;

	/**
	 * Find the highest level of shared cache which pre-T7 is also
	 * the socket.
	 */
	if (!set_max_cache_ids_by_cache(hp, 3))
		set_max_cache_ids_by_cache(hp, 2);

	/* If machine description exposes sockets data use it.*/
	mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
	if (mp != MDESC_NODE_NULL)
		set_sock_ids_by_socket(hp, mp);
}

static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
{
	u64 a;

	mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
		u64 t = mdesc_arc_target(hp, a);
		const char *name;
		const u64 *id;

		name = mdesc_node_name(hp, t);
		if (strcmp(name, "cpu"))
			continue;

		id = mdesc_get_property(hp, t, "id", NULL);
		if (*id < NR_CPUS)
			cpu_data(*id).proc_id = proc_id;
	}
}

static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
{
	int idx;
	u64 mp;

	idx = 0;
	mdesc_for_each_node_by_name(hp, mp, exec_unit_name) {
		const char *type;
		int len;

		type = mdesc_get_property(hp, mp, "type", &len);
		if (!of_find_in_proplist(type, "int", len) &&
		    !of_find_in_proplist(type, "integer", len))
			continue;

		mark_proc_ids(hp, mp, idx);
		idx++;
	}
}

static void set_proc_ids(struct mdesc_handle *hp)
{
	__set_proc_ids(hp, "exec_unit");
	__set_proc_ids(hp, "exec-unit");
}

static void get_one_mondo_bits(const u64 *p, unsigned int *mask,
			       unsigned long def, unsigned long max)
{
	u64 val;

	if (!p)
		goto use_default;
	val = *p;

	if (!val || val >= 64)
		goto use_default;

	if (val > max)
		val = max;

	*mask = ((1U << val) * 64U) - 1U;
	return;

use_default:
	*mask = ((1U << def) * 64U) - 1U;
}

static void get_mondo_data(struct mdesc_handle *hp, u64 mp,
			   struct trap_per_cpu *tb)
{
	static int printed;
	const u64 *val;

	val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL);
	get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2));

	val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL);
	get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8);

	val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL);
	get_one_mondo_bits(val, &tb->resum_qmask, 6, 7);

	val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL);
	get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2);
	if (!printed++) {
		pr_info("SUN4V: Mondo queue sizes "
			"[cpu(%u) dev(%u) r(%u) nr(%u)]\n",
			tb->cpu_mondo_qmask + 1,
			tb->dev_mondo_qmask + 1,
			tb->resum_qmask + 1,
			tb->nonresum_qmask + 1);
	}
}

static void *mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask)
{
	struct mdesc_handle *hp = mdesc_grab();
	void *ret = NULL;
	u64 mp;

	mdesc_for_each_node_by_name(hp, mp, "cpu") {
		const u64 *id = mdesc_get_property(hp, mp, "id", NULL);
		int cpuid = *id;

#ifdef CONFIG_SMP
		if (cpuid >= NR_CPUS) {
			printk(KERN_WARNING "Ignoring CPU %d which is "
			       ">= NR_CPUS (%d)\n",
			       cpuid, NR_CPUS);
			continue;
		}
		if (!cpumask_test_cpu(cpuid, mask))
			continue;
#endif

		ret = func(hp, mp, cpuid, arg);
		if (ret)
			goto out;
	}
out:
	mdesc_release(hp);
	return ret;
}

static void *record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid,
			    void *arg)
{
	ncpus_probed++;
#ifdef CONFIG_SMP
	set_cpu_present(cpuid, true);
#endif
	return NULL;
}

void mdesc_populate_present_mask(cpumask_t *mask)
{
	if (tlb_type != hypervisor)
		return;

	ncpus_probed = 0;
	mdesc_iterate_over_cpus(record_one_cpu, NULL, mask);
}

static void * __init check_one_pgsz(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg)
{
	const u64 *pgsz_prop = mdesc_get_property(hp, mp, "mmu-page-size-list", NULL);
	unsigned long *pgsz_mask = arg;
	u64 val;

	val = (HV_PGSZ_MASK_8K | HV_PGSZ_MASK_64K |
	       HV_PGSZ_MASK_512K | HV_PGSZ_MASK_4MB);
	if (pgsz_prop)
		val = *pgsz_prop;

	if (!*pgsz_mask)
		*pgsz_mask = val;
	else
		*pgsz_mask &= val;
	return NULL;
}

void __init mdesc_get_page_sizes(cpumask_t *mask, unsigned long *pgsz_mask)
{
	*pgsz_mask = 0;
	mdesc_iterate_over_cpus(check_one_pgsz, pgsz_mask, mask);
}

static void *fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid,
			     void *arg)
{
	const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL);
	struct trap_per_cpu *tb;
	cpuinfo_sparc *c;
	u64 a;

#ifndef CONFIG_SMP
	/* On uniprocessor we only want the values for the
	 * real physical cpu the kernel booted onto, however
	 * cpu_data() only has one entry at index 0.
	 */
	if (cpuid != real_hard_smp_processor_id())
		return NULL;
	cpuid = 0;
#endif

	c = &cpu_data(cpuid);
	c->clock_tick = *cfreq;

	tb = &trap_block[cpuid];
	get_mondo_data(hp, mp, tb);

	mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
		u64 j, t = mdesc_arc_target(hp, a);
		const char *t_name;

		t_name = mdesc_node_name(hp, t);
		if (!strcmp(t_name, "cache")) {
			fill_in_one_cache(c, hp, t);
			continue;
		}

		mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_FWD) {
			u64 n = mdesc_arc_target(hp, j);
			const char *n_name;

			n_name = mdesc_node_name(hp, n);
			if (!strcmp(n_name, "cache"))
				fill_in_one_cache(c, hp, n);
		}
	}

	c->core_id = 0;
	c->proc_id = -1;

	return NULL;
}

void mdesc_fill_in_cpu_data(cpumask_t *mask)
{
	struct mdesc_handle *hp;

	mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, mask);

	hp = mdesc_grab();

	set_core_ids(hp);
	set_proc_ids(hp);
	set_sock_ids(hp);

	mdesc_release(hp);

	smp_fill_in_sib_core_maps();
}

/* mdesc_open() - Grab a reference to mdesc_handle when /dev/mdesc is
 * opened. Hold this reference until /dev/mdesc is closed to ensure
 * mdesc data structure is not released underneath us. Store the
 * pointer to mdesc structure in private_data for read and seek to use
 */
static int mdesc_open(struct inode *inode, struct file *file)
{
	struct mdesc_handle *hp = mdesc_grab();

	if (!hp)
		return -ENODEV;

	file->private_data = hp;

	return 0;
}

static ssize_t mdesc_read(struct file *file, char __user *buf,
			  size_t len, loff_t *offp)
{
	struct mdesc_handle *hp = file->private_data;
	unsigned char *mdesc;
	int bytes_left, count = len;

	if (*offp >= hp->handle_size)
		return 0;

	bytes_left = hp->handle_size - *offp;
	if (count > bytes_left)
		count = bytes_left;

	mdesc = (unsigned char *)&hp->mdesc;
	mdesc += *offp;
	if (!copy_to_user(buf, mdesc, count)) {
		*offp += count;
		return count;
	} else {
		return -EFAULT;
	}
}

static loff_t mdesc_llseek(struct file *file, loff_t offset, int whence)
{
	struct mdesc_handle *hp = file->private_data;

	return no_seek_end_llseek_size(file, offset, whence, hp->handle_size);
}

/* mdesc_close() - /dev/mdesc is being closed, release the reference to
 * mdesc structure.
 */
static int mdesc_close(struct inode *inode, struct file *file)
{
	mdesc_release(file->private_data);
	return 0;
}

static const struct file_operations mdesc_fops = {
	.open    = mdesc_open,
	.read	 = mdesc_read,
	.llseek  = mdesc_llseek,
	.release = mdesc_close,
	.owner	 = THIS_MODULE,
};

static struct miscdevice mdesc_misc = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name	= "mdesc",
	.fops	= &mdesc_fops,
};

static int __init mdesc_misc_init(void)
{
	return misc_register(&mdesc_misc);
}

__initcall(mdesc_misc_init);

void __init sun4v_mdesc_init(void)
{
	struct mdesc_handle *hp;
	unsigned long len, real_len, status;

	(void) sun4v_mach_desc(0UL, 0UL, &len);

	printk("MDESC: Size is %lu bytes.\n", len);

	hp = mdesc_alloc(len, &memblock_mdesc_ops);
	if (hp == NULL) {
		prom_printf("MDESC: alloc of %lu bytes failed.\n", len);
		prom_halt();
	}

	status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len);
	if (status != HV_EOK || real_len > len) {
		prom_printf("sun4v_mach_desc fails, err(%lu), "
			    "len(%lu), real_len(%lu)\n",
			    status, len, real_len);
		mdesc_free(hp);
		prom_halt();
	}

	cur_mdesc = hp;

	mdesc_adi_init();
	report_platform_properties();
}
