/*
 *  PS3 repository routines.
 *
 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
 *  Copyright 2006 Sony Corp.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <asm/lv1call.h>

#include "platform.h"

enum ps3_vendor_id {
	PS3_VENDOR_ID_NONE = 0,
	PS3_VENDOR_ID_SONY = 0x8000000000000000UL,
};

enum ps3_lpar_id {
	PS3_LPAR_ID_CURRENT = 0,
	PS3_LPAR_ID_PME = 1,
};

#define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__)
static void _dump_field(const char *hdr, u64 n, const char *func, int line)
{
#if defined(DEBUG)
	char s[16];
	const char *const in = (const char *)&n;
	unsigned int i;

	for (i = 0; i < 8; i++)
		s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.';
	s[i] = 0;

	pr_devel("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s);
#endif
}

#define dump_node_name(_a, _b, _c, _d, _e) \
	_dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__)
static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
	u64 n4, const char *func, int line)
{
	pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id);
	_dump_field("n1: ", n1, func, line);
	_dump_field("n2: ", n2, func, line);
	_dump_field("n3: ", n3, func, line);
	_dump_field("n4: ", n4, func, line);
}

#define dump_node(_a, _b, _c, _d, _e, _f, _g) \
	_dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
	u64 v1, u64 v2, const char *func, int line)
{
	pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id);
	_dump_field("n1: ", n1, func, line);
	_dump_field("n2: ", n2, func, line);
	_dump_field("n3: ", n3, func, line);
	_dump_field("n4: ", n4, func, line);
	pr_devel("%s:%d: v1: %016llx\n", func, line, v1);
	pr_devel("%s:%d: v2: %016llx\n", func, line, v2);
}

/**
 * make_first_field - Make the first field of a repository node name.
 * @text: Text portion of the field.
 * @index: Numeric index portion of the field.  Use zero for 'don't care'.
 *
 * This routine sets the vendor id to zero (non-vendor specific).
 * Returns field value.
 */

static u64 make_first_field(const char *text, u64 index)
{
	u64 n;

	strncpy((char *)&n, text, 8);
	return PS3_VENDOR_ID_NONE + (n >> 32) + index;
}

/**
 * make_field - Make subsequent fields of a repository node name.
 * @text: Text portion of the field.  Use "" for 'don't care'.
 * @index: Numeric index portion of the field.  Use zero for 'don't care'.
 *
 * Returns field value.
 */

static u64 make_field(const char *text, u64 index)
{
	u64 n;

	strncpy((char *)&n, text, 8);
	return n + index;
}

/**
 * read_node - Read a repository node from raw fields.
 * @n1: First field of node name.
 * @n2: Second field of node name.  Use zero for 'don't care'.
 * @n3: Third field of node name.  Use zero for 'don't care'.
 * @n4: Fourth field of node name.  Use zero for 'don't care'.
 * @v1: First repository value (high word).
 * @v2: Second repository value (low word).  Optional parameter, use zero
 *      for 'don't care'.
 */

static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
	u64 *_v1, u64 *_v2)
{
	int result;
	u64 v1;
	u64 v2;

	if (lpar_id == PS3_LPAR_ID_CURRENT) {
		u64 id;
		lv1_get_logical_partition_id(&id);
		lpar_id = id;
	}

	result = lv1_read_repository_node(lpar_id, n1, n2, n3, n4, &v1,
		&v2);

	if (result) {
		pr_warn("%s:%d: lv1_read_repository_node failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		dump_node_name(lpar_id, n1, n2, n3, n4);
		return -ENOENT;
	}

	dump_node(lpar_id, n1, n2, n3, n4, v1, v2);

	if (_v1)
		*_v1 = v1;
	if (_v2)
		*_v2 = v2;

	if (v1 && !_v1)
		pr_devel("%s:%d: warning: discarding non-zero v1: %016llx\n",
			__func__, __LINE__, v1);
	if (v2 && !_v2)
		pr_devel("%s:%d: warning: discarding non-zero v2: %016llx\n",
			__func__, __LINE__, v2);

	return 0;
}

int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
	u64 *value)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field(bus_str, 0),
		0, 0,
		value, NULL);
}

int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id)
{
	return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index),
			 make_field("id", 0), 0, 0, bus_id, NULL);
}

int ps3_repository_read_bus_type(unsigned int bus_index,
	enum ps3_bus_type *bus_type)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("type", 0),
		0, 0,
		&v1, NULL);
	*bus_type = v1;
	return result;
}

int ps3_repository_read_bus_num_dev(unsigned int bus_index,
	unsigned int *num_dev)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("num_dev", 0),
		0, 0,
		&v1, NULL);
	*num_dev = v1;
	return result;
}

int ps3_repository_read_dev_str(unsigned int bus_index,
	unsigned int dev_index, const char *dev_str, u64 *value)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field(dev_str, 0),
		0,
		value, NULL);
}

int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
	u64 *dev_id)
{
	return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index),
			 make_field("dev", dev_index), make_field("id", 0), 0,
			 dev_id, NULL);
}

int ps3_repository_read_dev_type(unsigned int bus_index,
	unsigned int dev_index, enum ps3_dev_type *dev_type)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field("type", 0),
		0,
		&v1, NULL);
	*dev_type = v1;
	return result;
}

int ps3_repository_read_dev_intr(unsigned int bus_index,
	unsigned int dev_index, unsigned int intr_index,
	enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id)
{
	int result;
	u64 v1 = 0;
	u64 v2 = 0;

	result = read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field("intr", intr_index),
		0,
		&v1, &v2);
	*intr_type = v1;
	*interrupt_id = v2;
	return result;
}

int ps3_repository_read_dev_reg_type(unsigned int bus_index,
	unsigned int dev_index, unsigned int reg_index,
	enum ps3_reg_type *reg_type)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field("reg", reg_index),
		make_field("type", 0),
		&v1, NULL);
	*reg_type = v1;
	return result;
}

int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
	unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, u64 *len)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field("reg", reg_index),
		make_field("data", 0),
		bus_addr, len);
}

int ps3_repository_read_dev_reg(unsigned int bus_index,
	unsigned int dev_index, unsigned int reg_index,
	enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len)
{
	int result = ps3_repository_read_dev_reg_type(bus_index, dev_index,
		reg_index, reg_type);
	return result ? result
		: ps3_repository_read_dev_reg_addr(bus_index, dev_index,
		reg_index, bus_addr, len);
}



int ps3_repository_find_device(struct ps3_repository_device *repo)
{
	int result;
	struct ps3_repository_device tmp = *repo;
	unsigned int num_dev;

	BUG_ON(repo->bus_index > 10);
	BUG_ON(repo->dev_index > 10);

	result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);

	if (result) {
		pr_devel("%s:%d read_bus_num_dev failed\n", __func__, __LINE__);
		return result;
	}

	pr_devel("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n",
		__func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
		num_dev);

	if (tmp.dev_index >= num_dev) {
		pr_devel("%s:%d: no device found\n", __func__, __LINE__);
		return -ENODEV;
	}

	result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
		&tmp.dev_type);

	if (result) {
		pr_devel("%s:%d read_dev_type failed\n", __func__, __LINE__);
		return result;
	}

	result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
		&tmp.dev_id);

	if (result) {
		pr_devel("%s:%d ps3_repository_read_dev_id failed\n", __func__,
		__LINE__);
		return result;
	}

	pr_devel("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n",
		__func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);

	*repo = tmp;
	return 0;
}

int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
				     u64 bus_id, u64 dev_id)
{
	int result = -ENODEV;
	struct ps3_repository_device tmp;
	unsigned int num_dev;

	pr_devel(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__,
		 bus_id, dev_id);

	for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) {
		result = ps3_repository_read_bus_id(tmp.bus_index,
						    &tmp.bus_id);
		if (result) {
			pr_devel("%s:%u read_bus_id(%u) failed\n", __func__,
				 __LINE__, tmp.bus_index);
			return result;
		}

		if (tmp.bus_id == bus_id)
			goto found_bus;

		pr_devel("%s:%u: skip, bus_id %llu\n", __func__, __LINE__,
			 tmp.bus_id);
	}
	pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__);
	return result;

found_bus:
	result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type);
	if (result) {
		pr_devel("%s:%u read_bus_type(%u) failed\n", __func__,
			 __LINE__, tmp.bus_index);
		return result;
	}

	result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
	if (result) {
		pr_devel("%s:%u read_bus_num_dev failed\n", __func__,
			 __LINE__);
		return result;
	}

	for (tmp.dev_index = 0; tmp.dev_index < num_dev; tmp.dev_index++) {
		result = ps3_repository_read_dev_id(tmp.bus_index,
						    tmp.dev_index,
						    &tmp.dev_id);
		if (result) {
			pr_devel("%s:%u read_dev_id(%u:%u) failed\n", __func__,
				 __LINE__, tmp.bus_index, tmp.dev_index);
			return result;
		}

		if (tmp.dev_id == dev_id)
			goto found_dev;

		pr_devel("%s:%u: skip, dev_id %llu\n", __func__, __LINE__,
			 tmp.dev_id);
	}
	pr_devel(" <- %s:%u: dev not found\n", __func__, __LINE__);
	return result;

found_dev:
	result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
					      &tmp.dev_type);
	if (result) {
		pr_devel("%s:%u read_dev_type failed\n", __func__, __LINE__);
		return result;
	}

	pr_devel(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n",
		 __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index,
		 tmp.dev_index, tmp.bus_id, tmp.dev_id);
	*repo = tmp;
	return 0;
}

int ps3_repository_find_devices(enum ps3_bus_type bus_type,
	int (*callback)(const struct ps3_repository_device *repo))
{
	int result = 0;
	struct ps3_repository_device repo;

	pr_devel(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);

	repo.bus_type = bus_type;
	result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
	if (result) {
		pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__);
		return result;
	}

	result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
	if (result) {
		pr_devel("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__,
			 repo.bus_index);
		return result;
	}

	for (repo.dev_index = 0; ; repo.dev_index++) {
		result = ps3_repository_find_device(&repo);
		if (result == -ENODEV) {
			result = 0;
			break;
		} else if (result)
			break;

		result = callback(&repo);
		if (result) {
			pr_devel("%s:%d: abort at callback\n", __func__,
				__LINE__);
			break;
		}
	}

	pr_devel(" <- %s:%d\n", __func__, __LINE__);
	return result;
}

int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
	unsigned int *bus_index)
{
	unsigned int i;
	enum ps3_bus_type type;
	int error;

	for (i = from; i < 10; i++) {
		error = ps3_repository_read_bus_type(i, &type);
		if (error) {
			pr_devel("%s:%d read_bus_type failed\n",
				__func__, __LINE__);
			*bus_index = UINT_MAX;
			return error;
		}
		if (type == bus_type) {
			*bus_index = i;
			return 0;
		}
	}
	*bus_index = UINT_MAX;
	return -ENODEV;
}

int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
	enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
{
	int result = 0;
	unsigned int res_index;

	pr_devel("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);

	*interrupt_id = UINT_MAX;

	for (res_index = 0; res_index < 10; res_index++) {
		enum ps3_interrupt_type t;
		unsigned int id;

		result = ps3_repository_read_dev_intr(repo->bus_index,
			repo->dev_index, res_index, &t, &id);

		if (result) {
			pr_devel("%s:%d read_dev_intr failed\n",
				__func__, __LINE__);
			return result;
		}

		if (t == intr_type) {
			*interrupt_id = id;
			break;
		}
	}

	if (res_index == 10)
		return -ENODEV;

	pr_devel("%s:%d: found intr_type %u at res_index %u\n",
		__func__, __LINE__, intr_type, res_index);

	return result;
}

int ps3_repository_find_reg(const struct ps3_repository_device *repo,
	enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
{
	int result = 0;
	unsigned int res_index;

	pr_devel("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);

	*bus_addr = *len = 0;

	for (res_index = 0; res_index < 10; res_index++) {
		enum ps3_reg_type t;
		u64 a;
		u64 l;

		result = ps3_repository_read_dev_reg(repo->bus_index,
			repo->dev_index, res_index, &t, &a, &l);

		if (result) {
			pr_devel("%s:%d read_dev_reg failed\n",
				__func__, __LINE__);
			return result;
		}

		if (t == reg_type) {
			*bus_addr = a;
			*len = l;
			break;
		}
	}

	if (res_index == 10)
		return -ENODEV;

	pr_devel("%s:%d: found reg_type %u at res_index %u\n",
		__func__, __LINE__, reg_type, res_index);

	return result;
}

int ps3_repository_read_stor_dev_port(unsigned int bus_index,
	unsigned int dev_index, u64 *port)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field("port", 0),
		0, port, NULL);
}

int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,
	unsigned int dev_index, u64 *blk_size)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field("blk_size", 0),
		0, blk_size, NULL);
}

int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,
	unsigned int dev_index, u64 *num_blocks)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field("n_blocks", 0),
		0, num_blocks, NULL);
}

int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,
	unsigned int dev_index, unsigned int *num_regions)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_PME,
		make_first_field("bus", bus_index),
		make_field("dev", dev_index),
		make_field("n_regs", 0),
		0, &v1, NULL);
	*num_regions = v1;
	return result;
}

int ps3_repository_read_stor_dev_region_id(unsigned int bus_index,
	unsigned int dev_index, unsigned int region_index,
	unsigned int *region_id)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_PME,
	    make_first_field("bus", bus_index),
	    make_field("dev", dev_index),
	    make_field("region", region_index),
	    make_field("id", 0),
	    &v1, NULL);
	*region_id = v1;
	return result;
}

int ps3_repository_read_stor_dev_region_size(unsigned int bus_index,
	unsigned int dev_index,	unsigned int region_index, u64 *region_size)
{
	return read_node(PS3_LPAR_ID_PME,
	    make_first_field("bus", bus_index),
	    make_field("dev", dev_index),
	    make_field("region", region_index),
	    make_field("size", 0),
	    region_size, NULL);
}

int ps3_repository_read_stor_dev_region_start(unsigned int bus_index,
	unsigned int dev_index, unsigned int region_index, u64 *region_start)
{
	return read_node(PS3_LPAR_ID_PME,
	    make_first_field("bus", bus_index),
	    make_field("dev", dev_index),
	    make_field("region", region_index),
	    make_field("start", 0),
	    region_start, NULL);
}

int ps3_repository_read_stor_dev_info(unsigned int bus_index,
	unsigned int dev_index, u64 *port, u64 *blk_size,
	u64 *num_blocks, unsigned int *num_regions)
{
	int result;

	result = ps3_repository_read_stor_dev_port(bus_index, dev_index, port);
	if (result)
	    return result;

	result = ps3_repository_read_stor_dev_blk_size(bus_index, dev_index,
		blk_size);
	if (result)
	    return result;

	result = ps3_repository_read_stor_dev_num_blocks(bus_index, dev_index,
		num_blocks);
	if (result)
	    return result;

	result = ps3_repository_read_stor_dev_num_regions(bus_index, dev_index,
		num_regions);
	return result;
}

int ps3_repository_read_stor_dev_region(unsigned int bus_index,
	unsigned int dev_index, unsigned int region_index,
	unsigned int *region_id, u64 *region_start, u64 *region_size)
{
	int result;

	result = ps3_repository_read_stor_dev_region_id(bus_index, dev_index,
		region_index, region_id);
	if (result)
	    return result;

	result = ps3_repository_read_stor_dev_region_start(bus_index, dev_index,
		region_index, region_start);
	if (result)
	    return result;

	result = ps3_repository_read_stor_dev_region_size(bus_index, dev_index,
		region_index, region_size);
	return result;
}

/**
 * ps3_repository_read_num_pu - Number of logical PU processors for this lpar.
 */

int ps3_repository_read_num_pu(u64 *num_pu)
{
	*num_pu = 0;
	return read_node(PS3_LPAR_ID_CURRENT,
			   make_first_field("bi", 0),
			   make_field("pun", 0),
			   0, 0,
			   num_pu, NULL);
}

/**
 * ps3_repository_read_pu_id - Read the logical PU id.
 * @pu_index: Zero based index.
 * @pu_id: The logical PU id.
 */

int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id)
{
	return read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("pu", pu_index),
		0, 0,
		pu_id, NULL);
}

int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
{
	return read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("pu", 0),
		ppe_id,
		make_field("rm_size", 0),
		rm_size, NULL);
}

int ps3_repository_read_region_total(u64 *region_total)
{
	return read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("rgntotal", 0),
		0, 0,
		region_total, NULL);
}

/**
 * ps3_repository_read_mm_info - Read mm info for single pu system.
 * @rm_base: Real mode memory base address.
 * @rm_size: Real mode memory size.
 * @region_total: Maximum memory region size.
 */

int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
{
	int result;
	u64 ppe_id;

	lv1_get_logical_ppe_id(&ppe_id);
	*rm_base = 0;
	result = ps3_repository_read_rm_size(ppe_id, rm_size);
	return result ? result
		: ps3_repository_read_region_total(region_total);
}

/**
 * ps3_repository_read_highmem_region_count - Read the number of highmem regions
 *
 * Bootloaders must arrange the repository nodes such that regions are indexed
 * with a region_index from 0 to region_count-1.
 */

int ps3_repository_read_highmem_region_count(unsigned int *region_count)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("highmem", 0),
		make_field("region", 0),
		make_field("count", 0),
		0,
		&v1, NULL);
	*region_count = v1;
	return result;
}


int ps3_repository_read_highmem_base(unsigned int region_index,
	u64 *highmem_base)
{
	return read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("highmem", 0),
		make_field("region", region_index),
		make_field("base", 0),
		0,
		highmem_base, NULL);
}

int ps3_repository_read_highmem_size(unsigned int region_index,
	u64 *highmem_size)
{
	return read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("highmem", 0),
		make_field("region", region_index),
		make_field("size", 0),
		0,
		highmem_size, NULL);
}

/**
 * ps3_repository_read_highmem_info - Read high memory region info
 * @region_index: Region index, {0,..,region_count-1}.
 * @highmem_base: High memory base address.
 * @highmem_size: High memory size.
 *
 * Bootloaders that preallocate highmem regions must place the
 * region info into the repository at these well known nodes.
 */

int ps3_repository_read_highmem_info(unsigned int region_index,
	u64 *highmem_base, u64 *highmem_size)
{
	int result;

	*highmem_base = 0;
	result = ps3_repository_read_highmem_base(region_index, highmem_base);
	return result ? result
		: ps3_repository_read_highmem_size(region_index, highmem_size);
}

/**
 * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
 * @num_spu: Number of physical spus.
 */

int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("spun", 0),
		0, 0,
		&v1, NULL);
	*num_spu_reserved = v1;
	return result;
}

/**
 * ps3_repository_read_num_spu_resource_id - Number of spu resource reservations.
 * @num_resource_id: Number of spu resource ids.
 */

int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("spursvn", 0),
		0, 0,
		&v1, NULL);
	*num_resource_id = v1;
	return result;
}

/**
 * ps3_repository_read_spu_resource_id - spu resource reservation id value.
 * @res_index: Resource reservation index.
 * @resource_type: Resource reservation type.
 * @resource_id: Resource reservation id.
 */

int ps3_repository_read_spu_resource_id(unsigned int res_index,
	enum ps3_spu_resource_type *resource_type, unsigned int *resource_id)
{
	int result;
	u64 v1 = 0;
	u64 v2 = 0;

	result = read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("spursv", 0),
		res_index,
		0,
		&v1, &v2);
	*resource_type = v1;
	*resource_id = v2;
	return result;
}

static int ps3_repository_read_boot_dat_address(u64 *address)
{
	return read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("boot_dat", 0),
		make_field("address", 0),
		0,
		address, NULL);
}

int ps3_repository_read_boot_dat_size(unsigned int *size)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("boot_dat", 0),
		make_field("size", 0),
		0,
		&v1, NULL);
	*size = v1;
	return result;
}

int ps3_repository_read_vuart_av_port(unsigned int *port)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("vir_uart", 0),
		make_field("port", 0),
		make_field("avset", 0),
		&v1, NULL);
	*port = v1;
	return result;
}

int ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("bi", 0),
		make_field("vir_uart", 0),
		make_field("port", 0),
		make_field("sysmgr", 0),
		&v1, NULL);
	*port = v1;
	return result;
}

/**
  * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
  * address: lpar address of cell_ext_os_area
  * @size: size of cell_ext_os_area
  */

int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
{
	int result;

	*size = 0;
	result = ps3_repository_read_boot_dat_address(lpar_addr);
	return result ? result
		: ps3_repository_read_boot_dat_size(size);
}

/**
 * ps3_repository_read_num_be - Number of physical BE processors in the system.
 */

int ps3_repository_read_num_be(unsigned int *num_be)
{
	int result;
	u64 v1 = 0;

	result = read_node(PS3_LPAR_ID_PME,
		make_first_field("ben", 0),
		0,
		0,
		0,
		&v1, NULL);
	*num_be = v1;
	return result;
}

/**
 * ps3_repository_read_be_node_id - Read the physical BE processor node id.
 * @be_index: Zero based index.
 * @node_id: The BE processor node id.
 */

int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("be", be_index),
		0,
		0,
		0,
		node_id, NULL);
}

/**
 * ps3_repository_read_be_id - Read the physical BE processor id.
 * @node_id: The BE processor node id.
 * @be_id: The BE processor id.
 */

int ps3_repository_read_be_id(u64 node_id, u64 *be_id)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("be", 0),
		node_id,
		0,
		0,
		be_id, NULL);
}

int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
{
	return read_node(PS3_LPAR_ID_PME,
		make_first_field("be", 0),
		node_id,
		make_field("clock", 0),
		0,
		tb_freq, NULL);
}

int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
{
	int result;
	u64 node_id;

	*tb_freq = 0;
	result = ps3_repository_read_be_node_id(be_index, &node_id);
	return result ? result
		: ps3_repository_read_tb_freq(node_id, tb_freq);
}

int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
	u64 *rights)
{
	int result;
	u64 node_id;

	*lpar = 0;
	*rights = 0;
	result = ps3_repository_read_be_node_id(be_index, &node_id);
	return result ? result
		: read_node(PS3_LPAR_ID_PME,
			    make_first_field("be", 0),
			    node_id,
			    make_field("lpm", 0),
			    make_field("priv", 0),
			    lpar, rights);
}

#if defined(CONFIG_PS3_REPOSITORY_WRITE)

static int create_node(u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2)
{
	int result;

	dump_node(0, n1, n2, n3, n4, v1, v2);

	result = lv1_create_repository_node(n1, n2, n3, n4, v1, v2);

	if (result) {
		pr_devel("%s:%d: lv1_create_repository_node failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return -ENOENT;
	}

	return 0;
}

static int delete_node(u64 n1, u64 n2, u64 n3, u64 n4)
{
	int result;

	dump_node(0, n1, n2, n3, n4, 0, 0);

	result = lv1_delete_repository_node(n1, n2, n3, n4);

	if (result) {
		pr_devel("%s:%d: lv1_delete_repository_node failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return -ENOENT;
	}

	return 0;
}

static int write_node(u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2)
{
	int result;

	result = create_node(n1, n2, n3, n4, v1, v2);

	if (!result)
		return 0;

	result = lv1_write_repository_node(n1, n2, n3, n4, v1, v2);

	if (result) {
		pr_devel("%s:%d: lv1_write_repository_node failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return -ENOENT;
	}

	return 0;
}

int ps3_repository_write_highmem_region_count(unsigned int region_count)
{
	int result;
	u64 v1 = (u64)region_count;

	result = write_node(
		make_first_field("highmem", 0),
		make_field("region", 0),
		make_field("count", 0),
		0,
		v1, 0);
	return result;
}

int ps3_repository_write_highmem_base(unsigned int region_index,
	u64 highmem_base)
{
	return write_node(
		make_first_field("highmem", 0),
		make_field("region", region_index),
		make_field("base", 0),
		0,
		highmem_base, 0);
}

int ps3_repository_write_highmem_size(unsigned int region_index,
	u64 highmem_size)
{
	return write_node(
		make_first_field("highmem", 0),
		make_field("region", region_index),
		make_field("size", 0),
		0,
		highmem_size, 0);
}

int ps3_repository_write_highmem_info(unsigned int region_index,
	u64 highmem_base, u64 highmem_size)
{
	int result;

	result = ps3_repository_write_highmem_base(region_index, highmem_base);
	return result ? result
		: ps3_repository_write_highmem_size(region_index, highmem_size);
}

static int ps3_repository_delete_highmem_base(unsigned int region_index)
{
	return delete_node(
		make_first_field("highmem", 0),
		make_field("region", region_index),
		make_field("base", 0),
		0);
}

static int ps3_repository_delete_highmem_size(unsigned int region_index)
{
	return delete_node(
		make_first_field("highmem", 0),
		make_field("region", region_index),
		make_field("size", 0),
		0);
}

int ps3_repository_delete_highmem_info(unsigned int region_index)
{
	int result;

	result = ps3_repository_delete_highmem_base(region_index);
	result += ps3_repository_delete_highmem_size(region_index);

	return result ? -1 : 0;
}

#endif /* defined(CONFIG_PS3_REPOSITORY_WRITE) */

#if defined(DEBUG)

int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
{
	int result = 0;
	unsigned int res_index;

	pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
		repo->bus_index, repo->dev_index);

	for (res_index = 0; res_index < 10; res_index++) {
		enum ps3_interrupt_type intr_type;
		unsigned int interrupt_id;

		result = ps3_repository_read_dev_intr(repo->bus_index,
			repo->dev_index, res_index, &intr_type, &interrupt_id);

		if (result) {
			if (result !=  LV1_NO_ENTRY)
				pr_devel("%s:%d ps3_repository_read_dev_intr"
					" (%u:%u) failed\n", __func__, __LINE__,
					repo->bus_index, repo->dev_index);
			break;
		}

		pr_devel("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
			__func__, __LINE__, repo->bus_index, repo->dev_index,
			intr_type, interrupt_id);
	}

	for (res_index = 0; res_index < 10; res_index++) {
		enum ps3_reg_type reg_type;
		u64 bus_addr;
		u64 len;

		result = ps3_repository_read_dev_reg(repo->bus_index,
			repo->dev_index, res_index, &reg_type, &bus_addr, &len);

		if (result) {
			if (result !=  LV1_NO_ENTRY)
				pr_devel("%s:%d ps3_repository_read_dev_reg"
					" (%u:%u) failed\n", __func__, __LINE__,
					repo->bus_index, repo->dev_index);
			break;
		}

		pr_devel("%s:%d (%u:%u) reg_type %u, bus_addr %llxh, len %llxh\n",
			__func__, __LINE__, repo->bus_index, repo->dev_index,
			reg_type, bus_addr, len);
	}

	pr_devel(" <- %s:%d\n", __func__, __LINE__);
	return result;
}

static int dump_stor_dev_info(struct ps3_repository_device *repo)
{
	int result = 0;
	unsigned int num_regions, region_index;
	u64 port, blk_size, num_blocks;

	pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
		repo->bus_index, repo->dev_index);

	result = ps3_repository_read_stor_dev_info(repo->bus_index,
		repo->dev_index, &port, &blk_size, &num_blocks, &num_regions);
	if (result) {
		pr_devel("%s:%d ps3_repository_read_stor_dev_info"
			" (%u:%u) failed\n", __func__, __LINE__,
			repo->bus_index, repo->dev_index);
		goto out;
	}

	pr_devel("%s:%d  (%u:%u): port %llu, blk_size %llu, num_blocks "
		 "%llu, num_regions %u\n",
		 __func__, __LINE__, repo->bus_index, repo->dev_index,
		port, blk_size, num_blocks, num_regions);

	for (region_index = 0; region_index < num_regions; region_index++) {
		unsigned int region_id;
		u64 region_start, region_size;

		result = ps3_repository_read_stor_dev_region(repo->bus_index,
			repo->dev_index, region_index, &region_id,
			&region_start, &region_size);
		if (result) {
			 pr_devel("%s:%d ps3_repository_read_stor_dev_region"
				  " (%u:%u) failed\n", __func__, __LINE__,
				  repo->bus_index, repo->dev_index);
			break;
		}

		pr_devel("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
			__func__, __LINE__, repo->bus_index, repo->dev_index,
			region_id, (unsigned long)region_start,
			(unsigned long)region_size);
	}

out:
	pr_devel(" <- %s:%d\n", __func__, __LINE__);
	return result;
}

static int dump_device_info(struct ps3_repository_device *repo,
	unsigned int num_dev)
{
	int result = 0;

	pr_devel(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index);

	for (repo->dev_index = 0; repo->dev_index < num_dev;
		repo->dev_index++) {

		result = ps3_repository_read_dev_type(repo->bus_index,
			repo->dev_index, &repo->dev_type);

		if (result) {
			pr_devel("%s:%d ps3_repository_read_dev_type"
				" (%u:%u) failed\n", __func__, __LINE__,
				repo->bus_index, repo->dev_index);
			break;
		}

		result = ps3_repository_read_dev_id(repo->bus_index,
			repo->dev_index, &repo->dev_id);

		if (result) {
			pr_devel("%s:%d ps3_repository_read_dev_id"
				" (%u:%u) failed\n", __func__, __LINE__,
				repo->bus_index, repo->dev_index);
			continue;
		}

		pr_devel("%s:%d  (%u:%u): dev_type %u, dev_id %lu\n", __func__,
			__LINE__, repo->bus_index, repo->dev_index,
			repo->dev_type, (unsigned long)repo->dev_id);

		ps3_repository_dump_resource_info(repo);

		if (repo->bus_type == PS3_BUS_TYPE_STORAGE)
			dump_stor_dev_info(repo);
	}

	pr_devel(" <- %s:%d\n", __func__, __LINE__);
	return result;
}

int ps3_repository_dump_bus_info(void)
{
	int result = 0;
	struct ps3_repository_device repo;

	pr_devel(" -> %s:%d\n", __func__, __LINE__);

	memset(&repo, 0, sizeof(repo));

	for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
		unsigned int num_dev;

		result = ps3_repository_read_bus_type(repo.bus_index,
			&repo.bus_type);

		if (result) {
			pr_devel("%s:%d read_bus_type(%u) failed\n",
				__func__, __LINE__, repo.bus_index);
			break;
		}

		result = ps3_repository_read_bus_id(repo.bus_index,
			&repo.bus_id);

		if (result) {
			pr_devel("%s:%d read_bus_id(%u) failed\n",
				__func__, __LINE__, repo.bus_index);
			continue;
		}

		if (repo.bus_index != repo.bus_id)
			pr_devel("%s:%d bus_index != bus_id\n",
				__func__, __LINE__);

		result = ps3_repository_read_bus_num_dev(repo.bus_index,
			&num_dev);

		if (result) {
			pr_devel("%s:%d read_bus_num_dev(%u) failed\n",
				__func__, __LINE__, repo.bus_index);
			continue;
		}

		pr_devel("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n",
			__func__, __LINE__, repo.bus_index, repo.bus_type,
			(unsigned long)repo.bus_id, num_dev);

		dump_device_info(&repo, num_dev);
	}

	pr_devel(" <- %s:%d\n", __func__, __LINE__);
	return result;
}

#endif /* defined(DEBUG) */
