/*
 *  PS3 flash memory os area.
 *
 *  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 <linux/kernel.h>
#include <linux/io.h>
#include <linux/workqueue.h>
#include <linux/fs.h>
#include <linux/syscalls.h>
#include <linux/ctype.h>
#include <linux/lmb.h>
#include <linux/of.h>

#include <asm/prom.h>

#include "platform.h"

enum {
	OS_AREA_SEGMENT_SIZE = 0X200,
};

enum os_area_ldr_format {
	HEADER_LDR_FORMAT_RAW = 0,
	HEADER_LDR_FORMAT_GZIP = 1,
};

#define OS_AREA_HEADER_MAGIC_NUM "cell_ext_os_area"

/**
 * struct os_area_header - os area header segment.
 * @magic_num: Always 'cell_ext_os_area'.
 * @hdr_version: Header format version number.
 * @db_area_offset: Starting segment number of other os database area.
 * @ldr_area_offset: Starting segment number of bootloader image area.
 * @ldr_format: HEADER_LDR_FORMAT flag.
 * @ldr_size: Size of bootloader image in bytes.
 *
 * Note that the docs refer to area offsets.  These are offsets in units of
 * segments from the start of the os area (top of the header).  These are
 * better thought of as segment numbers.  The os area of the os area is
 * reserved for the os image.
 */

struct os_area_header {
	u8 magic_num[16];
	u32 hdr_version;
	u32 db_area_offset;
	u32 ldr_area_offset;
	u32 _reserved_1;
	u32 ldr_format;
	u32 ldr_size;
	u32 _reserved_2[6];
};

enum os_area_boot_flag {
	PARAM_BOOT_FLAG_GAME_OS = 0,
	PARAM_BOOT_FLAG_OTHER_OS = 1,
};

enum os_area_ctrl_button {
	PARAM_CTRL_BUTTON_O_IS_YES = 0,
	PARAM_CTRL_BUTTON_X_IS_YES = 1,
};

/**
 * struct os_area_params - os area params segment.
 * @boot_flag: User preference of operating system, PARAM_BOOT_FLAG flag.
 * @num_params: Number of params in this (params) segment.
 * @rtc_diff: Difference in seconds between 1970 and the ps3 rtc value.
 * @av_multi_out: User preference of AV output, PARAM_AV_MULTI_OUT flag.
 * @ctrl_button: User preference of controller button config, PARAM_CTRL_BUTTON
 *	flag.
 * @static_ip_addr: User preference of static IP address.
 * @network_mask: User preference of static network mask.
 * @default_gateway: User preference of static default gateway.
 * @dns_primary: User preference of static primary dns server.
 * @dns_secondary: User preference of static secondary dns server.
 *
 * The ps3 rtc maintains a read-only value that approximates seconds since
 * 2000-01-01 00:00:00 UTC.
 *
 * User preference of zero for static_ip_addr means use dhcp.
 */

struct os_area_params {
	u32 boot_flag;
	u32 _reserved_1[3];
	u32 num_params;
	u32 _reserved_2[3];
	/* param 0 */
	s64 rtc_diff;
	u8 av_multi_out;
	u8 ctrl_button;
	u8 _reserved_3[6];
	/* param 1 */
	u8 static_ip_addr[4];
	u8 network_mask[4];
	u8 default_gateway[4];
	u8 _reserved_4[4];
	/* param 2 */
	u8 dns_primary[4];
	u8 dns_secondary[4];
	u8 _reserved_5[8];
};

#define OS_AREA_DB_MAGIC_NUM "-db-"

/**
 * struct os_area_db - Shared flash memory database.
 * @magic_num: Always '-db-'.
 * @version: os_area_db format version number.
 * @index_64: byte offset of the database id index for 64 bit variables.
 * @count_64: number of usable 64 bit index entries
 * @index_32: byte offset of the database id index for 32 bit variables.
 * @count_32: number of usable 32 bit index entries
 * @index_16: byte offset of the database id index for 16 bit variables.
 * @count_16: number of usable 16 bit index entries
 *
 * Flash rom storage for exclusive use by guests running in the other os lpar.
 * The current system configuration allocates 1K (two segments) for other os
 * use.
 */

struct os_area_db {
	u8 magic_num[4];
	u16 version;
	u16 _reserved_1;
	u16 index_64;
	u16 count_64;
	u16 index_32;
	u16 count_32;
	u16 index_16;
	u16 count_16;
	u32 _reserved_2;
	u8 _db_data[1000];
};

/**
 * enum os_area_db_owner - Data owners.
 */

enum os_area_db_owner {
	OS_AREA_DB_OWNER_ANY = -1,
	OS_AREA_DB_OWNER_NONE = 0,
	OS_AREA_DB_OWNER_PROTOTYPE = 1,
	OS_AREA_DB_OWNER_LINUX = 2,
	OS_AREA_DB_OWNER_PETITBOOT = 3,
	OS_AREA_DB_OWNER_MAX = 32,
};

enum os_area_db_key {
	OS_AREA_DB_KEY_ANY = -1,
	OS_AREA_DB_KEY_NONE = 0,
	OS_AREA_DB_KEY_RTC_DIFF = 1,
	OS_AREA_DB_KEY_VIDEO_MODE = 2,
	OS_AREA_DB_KEY_MAX = 8,
};

struct os_area_db_id {
	int owner;
	int key;
};

static const struct os_area_db_id os_area_db_id_empty = {
	.owner = OS_AREA_DB_OWNER_NONE,
	.key = OS_AREA_DB_KEY_NONE
};

static const struct os_area_db_id os_area_db_id_any = {
	.owner = OS_AREA_DB_OWNER_ANY,
	.key = OS_AREA_DB_KEY_ANY
};

static const struct os_area_db_id os_area_db_id_rtc_diff = {
	.owner = OS_AREA_DB_OWNER_LINUX,
	.key = OS_AREA_DB_KEY_RTC_DIFF
};

static const struct os_area_db_id os_area_db_id_video_mode = {
	.owner = OS_AREA_DB_OWNER_LINUX,
	.key = OS_AREA_DB_KEY_VIDEO_MODE
};

#define SECONDS_FROM_1970_TO_2000 946684800LL

/**
 * struct saved_params - Static working copies of data from the PS3 'os area'.
 *
 * The order of preference we use for the rtc_diff source:
 *  1) The database value.
 *  2) The game os value.
 *  3) The number of seconds from 1970 to 2000.
 */

struct saved_params {
	unsigned int valid;
	s64 rtc_diff;
	unsigned int av_multi_out;
} static saved_params;

static struct property property_rtc_diff = {
	.name = "linux,rtc_diff",
	.length = sizeof(saved_params.rtc_diff),
	.value = &saved_params.rtc_diff,
};

static struct property property_av_multi_out = {
	.name = "linux,av_multi_out",
	.length = sizeof(saved_params.av_multi_out),
	.value = &saved_params.av_multi_out,
};

/**
 * os_area_set_property - Add or overwrite a saved_params value to the device tree.
 *
 * Overwrites an existing property.
 */

static void os_area_set_property(struct device_node *node,
	struct property *prop)
{
	int result;
	struct property *tmp = of_find_property(node, prop->name, NULL);

	if (tmp) {
		pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name);
		prom_remove_property(node, tmp);
	}

	result = prom_add_property(node, prop);

	if (result)
		pr_debug("%s:%d prom_set_property failed\n", __func__,
			__LINE__);
}

/**
 * os_area_get_property - Get a saved_params value from the device tree.
 *
 */

static void __init os_area_get_property(struct device_node *node,
	struct property *prop)
{
	const struct property *tmp = of_find_property(node, prop->name, NULL);

	if (tmp) {
		BUG_ON(prop->length != tmp->length);
		memcpy(prop->value, tmp->value, prop->length);
	} else
		pr_debug("%s:%d not found %s\n", __func__, __LINE__,
			prop->name);
}

static void dump_field(char *s, const u8 *field, int size_of_field)
{
#if defined(DEBUG)
	int i;

	for (i = 0; i < size_of_field; i++)
		s[i] = isprint(field[i]) ? field[i] : '.';
	s[i] = 0;
#endif
}

#define dump_header(_a) _dump_header(_a, __func__, __LINE__)
static void _dump_header(const struct os_area_header *h, const char *func,
	int line)
{
	char str[sizeof(h->magic_num) + 1];

	dump_field(str, h->magic_num, sizeof(h->magic_num));
	pr_debug("%s:%d: h.magic_num:       '%s'\n", func, line,
		str);
	pr_debug("%s:%d: h.hdr_version:     %u\n", func, line,
		h->hdr_version);
	pr_debug("%s:%d: h.db_area_offset:  %u\n", func, line,
		h->db_area_offset);
	pr_debug("%s:%d: h.ldr_area_offset: %u\n", func, line,
		h->ldr_area_offset);
	pr_debug("%s:%d: h.ldr_format:      %u\n", func, line,
		h->ldr_format);
	pr_debug("%s:%d: h.ldr_size:        %xh\n", func, line,
		h->ldr_size);
}

#define dump_params(_a) _dump_params(_a, __func__, __LINE__)
static void _dump_params(const struct os_area_params *p, const char *func,
	int line)
{
	pr_debug("%s:%d: p.boot_flag:       %u\n", func, line, p->boot_flag);
	pr_debug("%s:%d: p.num_params:      %u\n", func, line, p->num_params);
	pr_debug("%s:%d: p.rtc_diff         %ld\n", func, line, p->rtc_diff);
	pr_debug("%s:%d: p.av_multi_out     %u\n", func, line, p->av_multi_out);
	pr_debug("%s:%d: p.ctrl_button:     %u\n", func, line, p->ctrl_button);
	pr_debug("%s:%d: p.static_ip_addr:  %u.%u.%u.%u\n", func, line,
		p->static_ip_addr[0], p->static_ip_addr[1],
		p->static_ip_addr[2], p->static_ip_addr[3]);
	pr_debug("%s:%d: p.network_mask:    %u.%u.%u.%u\n", func, line,
		p->network_mask[0], p->network_mask[1],
		p->network_mask[2], p->network_mask[3]);
	pr_debug("%s:%d: p.default_gateway: %u.%u.%u.%u\n", func, line,
		p->default_gateway[0], p->default_gateway[1],
		p->default_gateway[2], p->default_gateway[3]);
	pr_debug("%s:%d: p.dns_primary:     %u.%u.%u.%u\n", func, line,
		p->dns_primary[0], p->dns_primary[1],
		p->dns_primary[2], p->dns_primary[3]);
	pr_debug("%s:%d: p.dns_secondary:   %u.%u.%u.%u\n", func, line,
		p->dns_secondary[0], p->dns_secondary[1],
		p->dns_secondary[2], p->dns_secondary[3]);
}

static int verify_header(const struct os_area_header *header)
{
	if (memcmp(header->magic_num, OS_AREA_HEADER_MAGIC_NUM,
		sizeof(header->magic_num))) {
		pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
		return -1;
	}

	if (header->hdr_version < 1) {
		pr_debug("%s:%d hdr_version failed\n", __func__, __LINE__);
		return -1;
	}

	if (header->db_area_offset > header->ldr_area_offset) {
		pr_debug("%s:%d offsets failed\n", __func__, __LINE__);
		return -1;
	}

	return 0;
}

static int db_verify(const struct os_area_db *db)
{
	if (memcmp(db->magic_num, OS_AREA_DB_MAGIC_NUM,
		sizeof(db->magic_num))) {
		pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
		return -1;
	}

	if (db->version != 1) {
		pr_debug("%s:%d version failed\n", __func__, __LINE__);
		return -1;
	}

	return 0;
}

struct db_index {
       uint8_t owner:5;
       uint8_t key:3;
};

struct db_iterator {
	const struct os_area_db *db;
	struct os_area_db_id match_id;
	struct db_index *idx;
	struct db_index *last_idx;
	union {
		uint64_t *value_64;
		uint32_t *value_32;
		uint16_t *value_16;
	};
};

static unsigned int db_align_up(unsigned int val, unsigned int size)
{
	return (val + (size - 1)) & (~(size - 1));
}

/**
 * db_for_each_64 - Iterator for 64 bit entries.
 *
 * A NULL value for id can be used to match all entries.
 * OS_AREA_DB_OWNER_ANY and OS_AREA_DB_KEY_ANY can be used to match all.
 */

static int db_for_each_64(const struct os_area_db *db,
	const struct os_area_db_id *match_id, struct db_iterator *i)
{
next:
	if (!i->db) {
		i->db = db;
		i->match_id = match_id ? *match_id : os_area_db_id_any;
		i->idx = (void *)db + db->index_64;
		i->last_idx = i->idx + db->count_64;
		i->value_64 = (void *)db + db->index_64
			+ db_align_up(db->count_64, 8);
	} else {
		i->idx++;
		i->value_64++;
	}

	if (i->idx >= i->last_idx) {
		pr_debug("%s:%d: reached end\n", __func__, __LINE__);
		return 0;
	}

	if (i->match_id.owner != OS_AREA_DB_OWNER_ANY
		&& i->match_id.owner != (int)i->idx->owner)
		goto next;
	if (i->match_id.key != OS_AREA_DB_KEY_ANY
		&& i->match_id.key != (int)i->idx->key)
		goto next;

	return 1;
}

static int db_delete_64(struct os_area_db *db, const struct os_area_db_id *id)
{
	struct db_iterator i;

	for (i.db = NULL; db_for_each_64(db, id, &i); ) {

		pr_debug("%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__,
			i.idx->owner, i.idx->key,
			(unsigned long long)*i.value_64);

		i.idx->owner = 0;
		i.idx->key = 0;
		*i.value_64 = 0;
	}
	return 0;
}

static int db_set_64(struct os_area_db *db, const struct os_area_db_id *id,
	uint64_t value)
{
	struct db_iterator i;

	pr_debug("%s:%d: (%d:%d) <= %llxh\n", __func__, __LINE__,
		id->owner, id->key, (unsigned long long)value);

	if (!id->owner || id->owner == OS_AREA_DB_OWNER_ANY
		|| id->key == OS_AREA_DB_KEY_ANY) {
		pr_debug("%s:%d: bad id: (%d:%d)\n", __func__,
			__LINE__, id->owner, id->key);
		return -1;
	}

	db_delete_64(db, id);

	i.db = NULL;
	if (db_for_each_64(db, &os_area_db_id_empty, &i)) {

		pr_debug("%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__,
			i.idx->owner, i.idx->key,
			(unsigned long long)*i.value_64);

		i.idx->owner = id->owner;
		i.idx->key = id->key;
		*i.value_64 = value;

		pr_debug("%s:%d: set (%d:%d) <= %llxh\n", __func__, __LINE__,
			i.idx->owner, i.idx->key,
			(unsigned long long)*i.value_64);
		return 0;
	}
	pr_debug("%s:%d: database full.\n",
		__func__, __LINE__);
	return -1;
}

static int db_get_64(const struct os_area_db *db,
	const struct os_area_db_id *id, uint64_t *value)
{
	struct db_iterator i;

	i.db = NULL;
	if (db_for_each_64(db, id, &i)) {
		*value = *i.value_64;
		pr_debug("%s:%d: found %lld\n", __func__, __LINE__,
				(long long int)*i.value_64);
		return 0;
	}
	pr_debug("%s:%d: not found\n", __func__, __LINE__);
	return -1;
}

static int db_get_rtc_diff(const struct os_area_db *db, int64_t *rtc_diff)
{
	return db_get_64(db, &os_area_db_id_rtc_diff, (uint64_t*)rtc_diff);
}

#define dump_db(a) _dump_db(a, __func__, __LINE__)
static void _dump_db(const struct os_area_db *db, const char *func,
	int line)
{
	char str[sizeof(db->magic_num) + 1];

	dump_field(str, db->magic_num, sizeof(db->magic_num));
	pr_debug("%s:%d: db.magic_num:      '%s'\n", func, line,
		str);
	pr_debug("%s:%d: db.version:         %u\n", func, line,
		db->version);
	pr_debug("%s:%d: db.index_64:        %u\n", func, line,
		db->index_64);
	pr_debug("%s:%d: db.count_64:        %u\n", func, line,
		db->count_64);
	pr_debug("%s:%d: db.index_32:        %u\n", func, line,
		db->index_32);
	pr_debug("%s:%d: db.count_32:        %u\n", func, line,
		db->count_32);
	pr_debug("%s:%d: db.index_16:        %u\n", func, line,
		db->index_16);
	pr_debug("%s:%d: db.count_16:        %u\n", func, line,
		db->count_16);
}

static void os_area_db_init(struct os_area_db *db)
{
	enum {
		HEADER_SIZE = offsetof(struct os_area_db, _db_data),
		INDEX_64_COUNT = 64,
		VALUES_64_COUNT = 57,
		INDEX_32_COUNT = 64,
		VALUES_32_COUNT = 57,
		INDEX_16_COUNT = 64,
		VALUES_16_COUNT = 57,
	};

	memset(db, 0, sizeof(struct os_area_db));

	memcpy(db->magic_num, OS_AREA_DB_MAGIC_NUM, sizeof(db->magic_num));
	db->version = 1;
	db->index_64 = HEADER_SIZE;
	db->count_64 = VALUES_64_COUNT;
	db->index_32 = HEADER_SIZE
			+ INDEX_64_COUNT * sizeof(struct db_index)
			+ VALUES_64_COUNT * sizeof(u64);
	db->count_32 = VALUES_32_COUNT;
	db->index_16 = HEADER_SIZE
			+ INDEX_64_COUNT * sizeof(struct db_index)
			+ VALUES_64_COUNT * sizeof(u64)
			+ INDEX_32_COUNT * sizeof(struct db_index)
			+ VALUES_32_COUNT * sizeof(u32);
	db->count_16 = VALUES_16_COUNT;

	/* Rules to check db layout. */

	BUILD_BUG_ON(sizeof(struct db_index) != 1);
	BUILD_BUG_ON(sizeof(struct os_area_db) != 2 * OS_AREA_SEGMENT_SIZE);
	BUILD_BUG_ON(INDEX_64_COUNT & 0x7);
	BUILD_BUG_ON(VALUES_64_COUNT > INDEX_64_COUNT);
	BUILD_BUG_ON(INDEX_32_COUNT & 0x7);
	BUILD_BUG_ON(VALUES_32_COUNT > INDEX_32_COUNT);
	BUILD_BUG_ON(INDEX_16_COUNT & 0x7);
	BUILD_BUG_ON(VALUES_16_COUNT > INDEX_16_COUNT);
	BUILD_BUG_ON(HEADER_SIZE
			+ INDEX_64_COUNT * sizeof(struct db_index)
			+ VALUES_64_COUNT * sizeof(u64)
			+ INDEX_32_COUNT * sizeof(struct db_index)
			+ VALUES_32_COUNT * sizeof(u32)
			+ INDEX_16_COUNT * sizeof(struct db_index)
			+ VALUES_16_COUNT * sizeof(u16)
			> sizeof(struct os_area_db));
}

/**
 * update_flash_db - Helper for os_area_queue_work_handler.
 *
 */

static void update_flash_db(void)
{
	int result;
	int file;
	off_t offset;
	ssize_t count;
	static const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE;
	const struct os_area_header *header;
	struct os_area_db* db;

	/* Read in header and db from flash. */

	file = sys_open("/dev/ps3flash", O_RDWR, 0);

	if (file < 0) {
		pr_debug("%s:%d sys_open failed\n", __func__, __LINE__);
		goto fail_open;
	}

	header = kmalloc(buf_len, GFP_KERNEL);

	if (!header) {
		pr_debug("%s:%d kmalloc failed\n", __func__, __LINE__);
		goto fail_malloc;
	}

	offset = sys_lseek(file, 0, SEEK_SET);

	if (offset != 0) {
		pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
		goto fail_header_seek;
	}

	count = sys_read(file, (char __user *)header, buf_len);

	result = count < OS_AREA_SEGMENT_SIZE || verify_header(header)
		|| count < header->db_area_offset * OS_AREA_SEGMENT_SIZE;

	if (result) {
		pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
		dump_header(header);
		goto fail_header;
	}

	/* Now got a good db offset and some maybe good db data. */

	db = (void*)header + header->db_area_offset * OS_AREA_SEGMENT_SIZE;

	result = db_verify(db);

	if (result) {
		printk(KERN_NOTICE "%s:%d: Verify of flash database failed, "
			"formatting.\n", __func__, __LINE__);
		dump_db(db);
		os_area_db_init(db);
	}

	/* Now got good db data. */

	db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff);

	offset = sys_lseek(file, header->db_area_offset * OS_AREA_SEGMENT_SIZE,
		SEEK_SET);

	if (offset != header->db_area_offset * OS_AREA_SEGMENT_SIZE) {
		pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
		goto fail_db_seek;
	}

	count = sys_write(file, (const char __user *)db,
		sizeof(struct os_area_db));

	if (count < sizeof(struct os_area_db)) {
		pr_debug("%s:%d sys_write failed\n", __func__, __LINE__);
	}

fail_db_seek:
fail_header:
fail_header_seek:
	kfree(header);
fail_malloc:
	sys_close(file);
fail_open:
	return;
}

/**
 * os_area_queue_work_handler - Asynchronous write handler.
 *
 * An asynchronous write for flash memory and the device tree.  Do not
 * call directly, use os_area_queue_work().
 */

static void os_area_queue_work_handler(struct work_struct *work)
{
	struct device_node *node;

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

	node = of_find_node_by_path("/");

	if (node) {
		os_area_set_property(node, &property_rtc_diff);
		of_node_put(node);
	} else
		pr_debug("%s:%d of_find_node_by_path failed\n",
			__func__, __LINE__);

#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
	update_flash_db();
#else
	printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n",
		__func__, __LINE__);
#endif
	pr_debug(" <- %s:%d\n", __func__, __LINE__);
}

static void os_area_queue_work(void)
{
	static DECLARE_WORK(q, os_area_queue_work_handler);

	wmb();
	schedule_work(&q);
}

/**
 * ps3_os_area_save_params - Copy data from os area mirror to @saved_params.
 *
 * For the convenience of the guest the HV makes a copy of the os area in
 * flash to a high address in the boot memory region and then puts that RAM
 * address and the byte count into the repository for retrieval by the guest.
 * We copy the data we want into a static variable and allow the memory setup
 * by the HV to be claimed by the lmb manager.
 *
 * The os area mirror will not be available to a second stage kernel, and
 * the header verify will fail.  In this case, the saved_params values will
 * be set from flash memory or the passed in device tree in ps3_os_area_init().
 */

void __init ps3_os_area_save_params(void)
{
	int result;
	u64 lpar_addr;
	unsigned int size;
	struct os_area_header *header;
	struct os_area_params *params;
	struct os_area_db *db;

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

	result = ps3_repository_read_boot_dat_info(&lpar_addr, &size);

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

	header = (struct os_area_header *)__va(lpar_addr);
	params = (struct os_area_params *)__va(lpar_addr
		+ OS_AREA_SEGMENT_SIZE);

	result = verify_header(header);

	if (result) {
		/* Second stage kernels exit here. */
		pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
		dump_header(header);
		return;
	}

	db = (struct os_area_db *)__va(lpar_addr
		+ header->db_area_offset * OS_AREA_SEGMENT_SIZE);

	dump_header(header);
	dump_params(params);
	dump_db(db);

	result = db_verify(db) || db_get_rtc_diff(db, &saved_params.rtc_diff);
	if (result)
		saved_params.rtc_diff = params->rtc_diff ? params->rtc_diff
			: SECONDS_FROM_1970_TO_2000;
	saved_params.av_multi_out = params->av_multi_out;
	saved_params.valid = 1;

	memset(header, 0, sizeof(*header));

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

/**
 * ps3_os_area_init - Setup os area device tree properties as needed.
 */

void __init ps3_os_area_init(void)
{
	struct device_node *node;

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

	node = of_find_node_by_path("/");

	if (!saved_params.valid && node) {
		/* Second stage kernels should have a dt entry. */
		os_area_get_property(node, &property_rtc_diff);
		os_area_get_property(node, &property_av_multi_out);
	}

	if(!saved_params.rtc_diff)
		saved_params.rtc_diff = SECONDS_FROM_1970_TO_2000;

	if (node) {
		os_area_set_property(node, &property_rtc_diff);
		os_area_set_property(node, &property_av_multi_out);
		of_node_put(node);
	} else
		pr_debug("%s:%d of_find_node_by_path failed\n",
			__func__, __LINE__);

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

/**
 * ps3_os_area_get_rtc_diff - Returns the rtc diff value.
 */

u64 ps3_os_area_get_rtc_diff(void)
{
	return saved_params.rtc_diff;
}

/**
 * ps3_os_area_set_rtc_diff - Set the rtc diff value.
 *
 * An asynchronous write is needed to support writing updates from
 * the timer interrupt context.
 */

void ps3_os_area_set_rtc_diff(u64 rtc_diff)
{
	if (saved_params.rtc_diff != rtc_diff) {
		saved_params.rtc_diff = rtc_diff;
		os_area_queue_work();
	}
}

/**
 * ps3_os_area_get_av_multi_out - Returns the default video mode.
 */

enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void)
{
    return saved_params.av_multi_out;
}
EXPORT_SYMBOL_GPL(ps3_os_area_get_av_multi_out);
