/*
 * Hypervisor-assisted dump
 *
 * Linas Vepstas, Manish Ahuja 2008
 * Copyright 2008 IBM 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; either version
 *      2 of the License, or (at your option) any later version.
 *
 */

#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/mm.h>
#include <linux/of.h>
#include <linux/pfn.h>
#include <linux/swap.h>
#include <linux/sysfs.h>

#include <asm/page.h>
#include <asm/phyp_dump.h>
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/rtas.h>

/* Variables, used to communicate data between early boot and late boot */
static struct phyp_dump phyp_dump_vars;
struct phyp_dump *phyp_dump_info = &phyp_dump_vars;

static int ibm_configure_kernel_dump;
/* ------------------------------------------------- */
/* RTAS interfaces to declare the dump regions */

struct dump_section {
	u32 dump_flags;
	u16 source_type;
	u16 error_flags;
	u64 source_address;
	u64 source_length;
	u64 length_copied;
	u64 destination_address;
};

struct phyp_dump_header {
	u32 version;
	u16 num_of_sections;
	u16 status;

	u32 first_offset_section;
	u32 dump_disk_section;
	u64 block_num_dd;
	u64 num_of_blocks_dd;
	u32 offset_dd;
	u32 maxtime_to_auto;
	/* No dump disk path string used */

	struct dump_section cpu_data;
	struct dump_section hpte_data;
	struct dump_section kernel_data;
};

/* The dump header *must be* in low memory, so .bss it */
static struct phyp_dump_header phdr;

#define NUM_DUMP_SECTIONS	3
#define DUMP_HEADER_VERSION	0x1
#define DUMP_REQUEST_FLAG	0x1
#define DUMP_SOURCE_CPU		0x0001
#define DUMP_SOURCE_HPTE	0x0002
#define DUMP_SOURCE_RMO		0x0011
#define DUMP_ERROR_FLAG		0x2000
#define DUMP_TRIGGERED		0x4000
#define DUMP_PERFORMED		0x8000


/**
 * init_dump_header() - initialize the header declaring a dump
 * Returns: length of dump save area.
 *
 * When the hypervisor saves crashed state, it needs to put
 * it somewhere. The dump header tells the hypervisor where
 * the data can be saved.
 */
static unsigned long init_dump_header(struct phyp_dump_header *ph)
{
	unsigned long addr_offset = 0;

	/* Set up the dump header */
	ph->version = DUMP_HEADER_VERSION;
	ph->num_of_sections = NUM_DUMP_SECTIONS;
	ph->status = 0;

	ph->first_offset_section =
		(u32)offsetof(struct phyp_dump_header, cpu_data);
	ph->dump_disk_section = 0;
	ph->block_num_dd = 0;
	ph->num_of_blocks_dd = 0;
	ph->offset_dd = 0;

	ph->maxtime_to_auto = 0; /* disabled */

	/* The first two sections are mandatory */
	ph->cpu_data.dump_flags = DUMP_REQUEST_FLAG;
	ph->cpu_data.source_type = DUMP_SOURCE_CPU;
	ph->cpu_data.source_address = 0;
	ph->cpu_data.source_length = phyp_dump_info->cpu_state_size;
	ph->cpu_data.destination_address = addr_offset;
	addr_offset += phyp_dump_info->cpu_state_size;

	ph->hpte_data.dump_flags = DUMP_REQUEST_FLAG;
	ph->hpte_data.source_type = DUMP_SOURCE_HPTE;
	ph->hpte_data.source_address = 0;
	ph->hpte_data.source_length = phyp_dump_info->hpte_region_size;
	ph->hpte_data.destination_address = addr_offset;
	addr_offset += phyp_dump_info->hpte_region_size;

	/* This section describes the low kernel region */
	ph->kernel_data.dump_flags = DUMP_REQUEST_FLAG;
	ph->kernel_data.source_type = DUMP_SOURCE_RMO;
	ph->kernel_data.source_address = PHYP_DUMP_RMR_START;
	ph->kernel_data.source_length = PHYP_DUMP_RMR_END;
	ph->kernel_data.destination_address = addr_offset;
	addr_offset += ph->kernel_data.source_length;

	return addr_offset;
}

static void print_dump_header(const struct phyp_dump_header *ph)
{
#ifdef DEBUG
	if (ph == NULL)
		return;

	printk(KERN_INFO "dump header:\n");
	/* setup some ph->sections required */
	printk(KERN_INFO "version = %d\n", ph->version);
	printk(KERN_INFO "Sections = %d\n", ph->num_of_sections);
	printk(KERN_INFO "Status = 0x%x\n", ph->status);

	/* No ph->disk, so all should be set to 0 */
	printk(KERN_INFO "Offset to first section 0x%x\n",
		ph->first_offset_section);
	printk(KERN_INFO "dump disk sections should be zero\n");
	printk(KERN_INFO "dump disk section = %d\n", ph->dump_disk_section);
	printk(KERN_INFO "block num = %lld\n", ph->block_num_dd);
	printk(KERN_INFO "number of blocks = %lld\n", ph->num_of_blocks_dd);
	printk(KERN_INFO "dump disk offset = %d\n", ph->offset_dd);
	printk(KERN_INFO "Max auto time= %d\n", ph->maxtime_to_auto);

	/*set cpu state and hpte states as well scratch pad area */
	printk(KERN_INFO " CPU AREA\n");
	printk(KERN_INFO "cpu dump_flags =%d\n", ph->cpu_data.dump_flags);
	printk(KERN_INFO "cpu source_type =%d\n", ph->cpu_data.source_type);
	printk(KERN_INFO "cpu error_flags =%d\n", ph->cpu_data.error_flags);
	printk(KERN_INFO "cpu source_address =%llx\n",
		ph->cpu_data.source_address);
	printk(KERN_INFO "cpu source_length =%llx\n",
		ph->cpu_data.source_length);
	printk(KERN_INFO "cpu length_copied =%llx\n",
		ph->cpu_data.length_copied);

	printk(KERN_INFO " HPTE AREA\n");
	printk(KERN_INFO "HPTE dump_flags =%d\n", ph->hpte_data.dump_flags);
	printk(KERN_INFO "HPTE source_type =%d\n", ph->hpte_data.source_type);
	printk(KERN_INFO "HPTE error_flags =%d\n", ph->hpte_data.error_flags);
	printk(KERN_INFO "HPTE source_address =%llx\n",
		ph->hpte_data.source_address);
	printk(KERN_INFO "HPTE source_length =%llx\n",
		ph->hpte_data.source_length);
	printk(KERN_INFO "HPTE length_copied =%llx\n",
		ph->hpte_data.length_copied);

	printk(KERN_INFO " SRSD AREA\n");
	printk(KERN_INFO "SRSD dump_flags =%d\n", ph->kernel_data.dump_flags);
	printk(KERN_INFO "SRSD source_type =%d\n", ph->kernel_data.source_type);
	printk(KERN_INFO "SRSD error_flags =%d\n", ph->kernel_data.error_flags);
	printk(KERN_INFO "SRSD source_address =%llx\n",
		ph->kernel_data.source_address);
	printk(KERN_INFO "SRSD source_length =%llx\n",
		ph->kernel_data.source_length);
	printk(KERN_INFO "SRSD length_copied =%llx\n",
		ph->kernel_data.length_copied);
#endif
}

static ssize_t show_phyp_dump_active(struct kobject *kobj,
			struct kobj_attribute *attr, char *buf)
{

	/* create filesystem entry so kdump is phyp-dump aware */
	return sprintf(buf, "%lx\n", phyp_dump_info->phyp_dump_at_boot);
}

static struct kobj_attribute pdl = __ATTR(phyp_dump_active, 0600,
					show_phyp_dump_active,
					NULL);

static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
{
	int rc;

	/* Add addr value if not initialized before */
	if (ph->cpu_data.destination_address == 0) {
		ph->cpu_data.destination_address += addr;
		ph->hpte_data.destination_address += addr;
		ph->kernel_data.destination_address += addr;
	}

	/* ToDo Invalidate kdump and free memory range. */

	do {
		rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
				1, ph, sizeof(struct phyp_dump_header));
	} while (rtas_busy_delay(rc));

	if (rc) {
		printk(KERN_ERR "phyp-dump: unexpected error (%d) on "
						"register\n", rc);
		print_dump_header(ph);
		return;
	}

	rc = sysfs_create_file(kernel_kobj, &pdl.attr);
	if (rc)
		printk(KERN_ERR "phyp-dump: unable to create sysfs"
				" file (%d)\n", rc);
}

static
void invalidate_last_dump(struct phyp_dump_header *ph, unsigned long addr)
{
	int rc;

	/* Add addr value if not initialized before */
	if (ph->cpu_data.destination_address == 0) {
		ph->cpu_data.destination_address += addr;
		ph->hpte_data.destination_address += addr;
		ph->kernel_data.destination_address += addr;
	}

	do {
		rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
				2, ph, sizeof(struct phyp_dump_header));
	} while (rtas_busy_delay(rc));

	if (rc) {
		printk(KERN_ERR "phyp-dump: unexpected error (%d) "
						"on invalidate\n", rc);
		print_dump_header(ph);
	}
}

/* ------------------------------------------------- */
/**
 * release_memory_range -- release memory previously lmb_reserved
 * @start_pfn: starting physical frame number
 * @nr_pages: number of pages to free.
 *
 * This routine will release memory that had been previously
 * lmb_reserved in early boot. The released memory becomes
 * available for genreal use.
 */
static void release_memory_range(unsigned long start_pfn,
			unsigned long nr_pages)
{
	struct page *rpage;
	unsigned long end_pfn;
	long i;

	end_pfn = start_pfn + nr_pages;

	for (i = start_pfn; i <= end_pfn; i++) {
		rpage = pfn_to_page(i);
		if (PageReserved(rpage)) {
			ClearPageReserved(rpage);
			init_page_count(rpage);
			__free_page(rpage);
			totalram_pages++;
		}
	}
}

/**
 * track_freed_range -- Counts the range being freed.
 * Once the counter goes to zero, it re-registers dump for
 * future use.
 */
static void
track_freed_range(unsigned long addr, unsigned long length)
{
	static unsigned long scratch_area_size, reserved_area_size;

	if (addr < phyp_dump_info->init_reserve_start)
		return;

	if ((addr >= phyp_dump_info->init_reserve_start) &&
	    (addr <= phyp_dump_info->init_reserve_start +
	     phyp_dump_info->init_reserve_size))
		reserved_area_size += length;

	if ((addr >= phyp_dump_info->reserved_scratch_addr) &&
	    (addr <= phyp_dump_info->reserved_scratch_addr +
	     phyp_dump_info->reserved_scratch_size))
		scratch_area_size += length;

	if ((reserved_area_size == phyp_dump_info->init_reserve_size) &&
	    (scratch_area_size == phyp_dump_info->reserved_scratch_size)) {

		invalidate_last_dump(&phdr,
				phyp_dump_info->reserved_scratch_addr);
		register_dump_area(&phdr,
				phyp_dump_info->reserved_scratch_addr);
	}
}

/* ------------------------------------------------- */
/**
 * sysfs_release_region -- sysfs interface to release memory range.
 *
 * Usage:
 *   "echo <start addr> <length> > /sys/kernel/release_region"
 *
 * Example:
 *   "echo 0x40000000 0x10000000 > /sys/kernel/release_region"
 *
 * will release 256MB starting at 1GB.
 */
static ssize_t store_release_region(struct kobject *kobj,
				struct kobj_attribute *attr,
				const char *buf, size_t count)
{
	unsigned long start_addr, length, end_addr;
	unsigned long start_pfn, nr_pages;
	ssize_t ret;

	ret = sscanf(buf, "%lx %lx", &start_addr, &length);
	if (ret != 2)
		return -EINVAL;

	track_freed_range(start_addr, length);

	/* Range-check - don't free any reserved memory that
	 * wasn't reserved for phyp-dump */
	if (start_addr < phyp_dump_info->init_reserve_start)
		start_addr = phyp_dump_info->init_reserve_start;

	end_addr = phyp_dump_info->init_reserve_start +
			phyp_dump_info->init_reserve_size;
	if (start_addr+length > end_addr)
		length = end_addr - start_addr;

	/* Release the region of memory assed in by user */
	start_pfn = PFN_DOWN(start_addr);
	nr_pages = PFN_DOWN(length);
	release_memory_range(start_pfn, nr_pages);

	return count;
}

static ssize_t show_release_region(struct kobject *kobj,
			struct kobj_attribute *attr, char *buf)
{
	u64 second_addr_range;

	/* total reserved size - start of scratch area */
	second_addr_range = phyp_dump_info->init_reserve_size -
				phyp_dump_info->reserved_scratch_size;
	return sprintf(buf, "CPU:0x%llx-0x%llx: HPTE:0x%llx-0x%llx:"
			    " DUMP:0x%llx-0x%llx, 0x%lx-0x%llx:\n",
		phdr.cpu_data.destination_address,
		phdr.cpu_data.length_copied,
		phdr.hpte_data.destination_address,
		phdr.hpte_data.length_copied,
		phdr.kernel_data.destination_address,
		phdr.kernel_data.length_copied,
		phyp_dump_info->init_reserve_start,
		second_addr_range);
}

static struct kobj_attribute rr = __ATTR(release_region, 0600,
					show_release_region,
					store_release_region);

static int __init phyp_dump_setup(void)
{
	struct device_node *rtas;
	const struct phyp_dump_header *dump_header = NULL;
	unsigned long dump_area_start;
	unsigned long dump_area_length;
	int header_len = 0;
	int rc;

	/* If no memory was reserved in early boot, there is nothing to do */
	if (phyp_dump_info->init_reserve_size == 0)
		return 0;

	/* Return if phyp dump not supported */
	if (!phyp_dump_info->phyp_dump_configured)
		return -ENOSYS;

	/* Is there dump data waiting for us? If there isn't,
	 * then register a new dump area, and release all of
	 * the rest of the reserved ram.
	 *
	 * The /rtas/ibm,kernel-dump rtas node is present only
	 * if there is dump data waiting for us.
	 */
	rtas = of_find_node_by_path("/rtas");
	if (rtas) {
		dump_header = of_get_property(rtas, "ibm,kernel-dump",
						&header_len);
		of_node_put(rtas);
	}

	ibm_configure_kernel_dump = rtas_token("ibm,configure-kernel-dump");

	print_dump_header(dump_header);
	dump_area_length = init_dump_header(&phdr);
	/* align down */
	dump_area_start = phyp_dump_info->init_reserve_start & PAGE_MASK;

	if (dump_header == NULL) {
		register_dump_area(&phdr, dump_area_start);
		return 0;
	}

	/* re-register the dump area, if old dump was invalid */
	if ((dump_header) && (dump_header->status & DUMP_ERROR_FLAG)) {
		invalidate_last_dump(&phdr, dump_area_start);
		register_dump_area(&phdr, dump_area_start);
		return 0;
	}

	if (dump_header) {
		phyp_dump_info->reserved_scratch_addr =
				dump_header->cpu_data.destination_address;
		phyp_dump_info->reserved_scratch_size =
				dump_header->cpu_data.source_length +
				dump_header->hpte_data.source_length +
				dump_header->kernel_data.source_length;
	}

	/* Should we create a dump_subsys, analogous to s390/ipl.c ? */
	rc = sysfs_create_file(kernel_kobj, &rr.attr);
	if (rc)
		printk(KERN_ERR "phyp-dump: unable to create sysfs file (%d)\n",
									rc);

	/* ToDo: re-register the dump area, for next time. */
	return 0;
}
machine_subsys_initcall(pseries, phyp_dump_setup);

int __init early_init_dt_scan_phyp_dump(unsigned long node,
		const char *uname, int depth, void *data)
{
	const unsigned int *sizes;

	phyp_dump_info->phyp_dump_configured = 0;
	phyp_dump_info->phyp_dump_is_active = 0;

	if (depth != 1 || strcmp(uname, "rtas") != 0)
		return 0;

	if (of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL))
		phyp_dump_info->phyp_dump_configured++;

	if (of_get_flat_dt_prop(node, "ibm,dump-kernel", NULL))
		phyp_dump_info->phyp_dump_is_active++;

	sizes = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
				    NULL);
	if (!sizes)
		return 0;

	if (sizes[0] == 1)
		phyp_dump_info->cpu_state_size = *((unsigned long *)&sizes[1]);

	if (sizes[3] == 2)
		phyp_dump_info->hpte_region_size =
						*((unsigned long *)&sizes[4]);
	return 1;
}

/* Look for phyp_dump= cmdline option */
static int __init early_phyp_dump_enabled(char *p)
{
	phyp_dump_info->phyp_dump_at_boot = 1;

        if (!p)
                return 0;

        if (strncmp(p, "1", 1) == 0)
		phyp_dump_info->phyp_dump_at_boot = 1;
        else if (strncmp(p, "0", 1) == 0)
		phyp_dump_info->phyp_dump_at_boot = 0;

        return 0;
}
early_param("phyp_dump", early_phyp_dump_enabled);

/* Look for phyp_dump_reserve_size= cmdline option */
static int __init early_phyp_dump_reserve_size(char *p)
{
        if (p)
		phyp_dump_info->reserve_bootvar = memparse(p, &p);

        return 0;
}
early_param("phyp_dump_reserve_size", early_phyp_dump_reserve_size);
