/*
 *  arch/s390/kernel/early.c
 *
 *    Copyright IBM Corp. 2007
 *    Author(s): Hongjie Yang <hongjie@us.ibm.com>,
 *		 Heiko Carstens <heiko.carstens@de.ibm.com>
 */

#include <linux/init.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/lockdep.h>
#include <linux/module.h>
#include <linux/pfn.h>
#include <linux/uaccess.h>
#include <asm/ipl.h>
#include <asm/lowcore.h>
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/cpcmd.h>
#include <asm/sclp.h>

/*
 * Create a Kernel NSS if the SAVESYS= parameter is defined
 */
#define DEFSYS_CMD_SIZE		96
#define SAVESYS_CMD_SIZE	32

char kernel_nss_name[NSS_NAME_SIZE + 1];

#ifdef CONFIG_SHARED_KERNEL
static noinline __init void create_kernel_nss(void)
{
	unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size;
#ifdef CONFIG_BLK_DEV_INITRD
	unsigned int sinitrd_pfn, einitrd_pfn;
#endif
	int response;
	char *savesys_ptr;
	char upper_command_line[COMMAND_LINE_SIZE];
	char defsys_cmd[DEFSYS_CMD_SIZE];
	char savesys_cmd[SAVESYS_CMD_SIZE];

	/* Do nothing if we are not running under VM */
	if (!MACHINE_IS_VM)
		return;

	/* Convert COMMAND_LINE to upper case */
	for (i = 0; i < strlen(COMMAND_LINE); i++)
		upper_command_line[i] = toupper(COMMAND_LINE[i]);

	savesys_ptr = strstr(upper_command_line, "SAVESYS=");

	if (!savesys_ptr)
		return;

	savesys_ptr += 8;    /* Point to the beginning of the NSS name */
	for (i = 0; i < NSS_NAME_SIZE; i++) {
		if (savesys_ptr[i] == ' ' || savesys_ptr[i] == '\0')
			break;
		kernel_nss_name[i] = savesys_ptr[i];
	}

	stext_pfn = PFN_DOWN(__pa(&_stext));
	eshared_pfn = PFN_DOWN(__pa(&_eshared));
	end_pfn = PFN_UP(__pa(&_end));
	min_size = end_pfn << 2;

	sprintf(defsys_cmd, "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X",
		kernel_nss_name, stext_pfn - 1, stext_pfn, eshared_pfn - 1,
		eshared_pfn, end_pfn);

#ifdef CONFIG_BLK_DEV_INITRD
	if (INITRD_START && INITRD_SIZE) {
		sinitrd_pfn = PFN_DOWN(__pa(INITRD_START));
		einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE));
		min_size = einitrd_pfn << 2;
		sprintf(defsys_cmd, "%s EW %.5X-%.5X", defsys_cmd,
		sinitrd_pfn, einitrd_pfn);
	}
#endif

	sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK", defsys_cmd, min_size);
	sprintf(savesys_cmd, "SAVESYS %s \n IPL %s",
		kernel_nss_name, kernel_nss_name);

	__cpcmd(defsys_cmd, NULL, 0, &response);

	if (response != 0)
		return;

	__cpcmd(savesys_cmd, NULL, 0, &response);

	if (response != strlen(savesys_cmd))
		return;

	ipl_flags = IPL_NSS_VALID;
}

#else /* CONFIG_SHARED_KERNEL */

static inline void create_kernel_nss(void) { }

#endif /* CONFIG_SHARED_KERNEL */

/*
 * Clear bss memory
 */
static noinline __init void clear_bss_section(void)
{
	memset(__bss_start, 0, __bss_stop - __bss_start);
}

/*
 * Initialize storage key for kernel pages
 */
static noinline __init void init_kernel_storage_key(void)
{
	unsigned long end_pfn, init_pfn;

	end_pfn = PFN_UP(__pa(&_end));

	for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++)
		page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
}

static noinline __init void detect_machine_type(void)
{
	struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;

	get_cpu_id(&S390_lowcore.cpu_data.cpu_id);

	/* Running under z/VM ? */
	if (cpuinfo->cpu_id.version == 0xff)
		machine_flags |= 1;

	/* Running on a P/390 ? */
	if (cpuinfo->cpu_id.machine == 0x7490)
		machine_flags |= 4;
}

#ifdef CONFIG_64BIT
static noinline __init int memory_fast_detect(void)
{
	unsigned long val0 = 0;
	unsigned long val1 = 0xc;
	int ret = -ENOSYS;

	if (ipl_flags & IPL_NSS_VALID)
		return -ENOSYS;

	asm volatile(
		"	diag	%1,%2,0x260\n"
		"0:	lhi	%0,0\n"
		"1:\n"
		EX_TABLE(0b,1b)
		: "+d" (ret), "+d" (val0), "+d" (val1) : : "cc");

	if (ret || val0 != val1)
		return -ENOSYS;

	memory_chunk[0].size = val0 + 1;
	return 0;
}
#else
static inline int memory_fast_detect(void)
{
	return -ENOSYS;
}
#endif

#define ADDR2G	(1UL << 31)

static noinline __init unsigned long sclp_memory_detect(void)
{
	struct sclp_readinfo_sccb *sccb;
	unsigned long long memsize;

	sccb = &s390_readinfo_sccb;

	if (sccb->header.response_code != 0x10)
		return 0;

	if (sccb->rnsize)
		memsize = sccb->rnsize << 20;
	else
		memsize = sccb->rnsize2 << 20;
	if (sccb->rnmax)
		memsize *= sccb->rnmax;
	else
		memsize *= sccb->rnmax2;
#ifndef CONFIG_64BIT
	/*
	 * Can't deal with more than 2G in 31 bit addressing mode, so
	 * limit the value in order to avoid strange side effects.
	 */
	if (memsize > ADDR2G)
		memsize = ADDR2G;
#endif
	return (unsigned long) memsize;
}

static inline __init unsigned long __tprot(unsigned long addr)
{
	int cc = -1;

	asm volatile(
		"	tprot	0(%1),0\n"
		"0:	ipm	%0\n"
		"	srl	%0,28\n"
		"1:\n"
		EX_TABLE(0b,1b)
		: "+d" (cc) : "a" (addr) : "cc");
	return (unsigned long)cc;
}

/* Checking memory in 128KB increments. */
#define CHUNK_INCR	(1UL << 17)

static noinline __init void find_memory_chunks(unsigned long memsize)
{
	unsigned long addr = 0, old_addr = 0;
	unsigned long old_cc = CHUNK_READ_WRITE;
	unsigned long cc;
	int chunk = 0;

	while (chunk < MEMORY_CHUNKS) {
		cc = __tprot(addr);
		while (cc == old_cc) {
			addr += CHUNK_INCR;
			cc = __tprot(addr);
#ifndef CONFIG_64BIT
			if (addr == ADDR2G)
				break;
#endif
		}

		if (old_addr != addr &&
		    (old_cc == CHUNK_READ_WRITE || old_cc == CHUNK_READ_ONLY)) {
			memory_chunk[chunk].addr = old_addr;
			memory_chunk[chunk].size = addr - old_addr;
			memory_chunk[chunk].type = old_cc;
			chunk++;
		}

		old_addr = addr;
		old_cc = cc;

#ifndef CONFIG_64BIT
		if (addr == ADDR2G)
			break;
#endif
		/*
		 * Finish memory detection at the first hole, unless
		 * - we reached the hsa -> skip it.
		 * - we know there must be more.
		 */
		if (cc == -1UL && !memsize && old_addr != ADDR2G)
			break;
		if (memsize && addr >= memsize)
			break;
	}
}

static __init void early_pgm_check_handler(void)
{
	unsigned long addr;
	const struct exception_table_entry *fixup;

	addr = S390_lowcore.program_old_psw.addr;
	fixup = search_exception_tables(addr & PSW_ADDR_INSN);
	if (!fixup)
		disabled_wait(0);
	S390_lowcore.program_old_psw.addr = fixup->fixup | PSW_ADDR_AMODE;
}

static noinline __init void setup_lowcore_early(void)
{
	psw_t psw;

	psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
	psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_ext_handler;
	S390_lowcore.external_new_psw = psw;
	psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
	S390_lowcore.program_new_psw = psw;
	s390_base_pgm_handler_fn = early_pgm_check_handler;
}

/*
 * Save ipl parameters, clear bss memory, initialize storage keys
 * and create a kernel NSS at startup if the SAVESYS= parm is defined
 */
void __init startup_init(void)
{
	unsigned long memsize;

	ipl_save_parameters();
	clear_bss_section();
	init_kernel_storage_key();
	lockdep_init();
	lockdep_off();
	detect_machine_type();
	create_kernel_nss();
	sort_main_extable();
	setup_lowcore_early();
	sclp_readinfo_early();
	memsize = sclp_memory_detect();
	if (memory_fast_detect() < 0)
		find_memory_chunks(memsize);
	lockdep_on();
}
