// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *
 * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
 * Author: Fuxin Zhang, zhangfx@lemote.com
 * Copyright (C) 2009 Lemote, Inc.
 * Author: Zhangjin Wu, wuzhangjin@gmail.com
 */
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kexec.h>
#include <linux/pm.h>
#include <linux/reboot.h>
#include <linux/slab.h>

#include <asm/bootinfo.h>
#include <asm/idle.h>
#include <asm/reboot.h>
#include <asm/bug.h>

#include <loongson.h>
#include <boot_param.h>

static int firmware_restart(struct sys_off_data *unusedd)
{

	void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr;

	fw_restart();
	return NOTIFY_DONE;
}

static int firmware_poweroff(struct sys_off_data *unused)
{
	void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr;

	fw_poweroff();
	return NOTIFY_DONE;
}

#ifdef CONFIG_KEXEC_CORE

/* 0X80000000~0X80200000 is safe */
#define MAX_ARGS	64
#define KEXEC_CTRL_CODE	0xFFFFFFFF80100000UL
#define KEXEC_ARGV_ADDR	0xFFFFFFFF80108000UL
#define KEXEC_ARGV_SIZE	COMMAND_LINE_SIZE
#define KEXEC_ENVP_SIZE	4800

static int kexec_argc;
static int kdump_argc;
static void *kexec_argv;
static void *kdump_argv;
static void *kexec_envp;

static int loongson_kexec_prepare(struct kimage *image)
{
	int i, argc = 0;
	unsigned int *argv;
	char *str, *ptr, *bootloader = "kexec";

	/* argv at offset 0, argv[] at offset KEXEC_ARGV_SIZE/2 */
	if (image->type == KEXEC_TYPE_DEFAULT)
		argv = (unsigned int *)kexec_argv;
	else
		argv = (unsigned int *)kdump_argv;

	argv[argc++] = (unsigned int)(KEXEC_ARGV_ADDR + KEXEC_ARGV_SIZE/2);

	for (i = 0; i < image->nr_segments; i++) {
		if (!strncmp(bootloader, (char *)image->segment[i].buf,
				strlen(bootloader))) {
			/*
			 * convert command line string to array
			 * of parameters (as bootloader does).
			 */
			int offt;
			str = (char *)argv + KEXEC_ARGV_SIZE/2;
			memcpy(str, image->segment[i].buf, KEXEC_ARGV_SIZE/2);
			ptr = strchr(str, ' ');

			while (ptr && (argc < MAX_ARGS)) {
				*ptr = '\0';
				if (ptr[1] != ' ') {
					offt = (int)(ptr - str + 1);
					argv[argc] = KEXEC_ARGV_ADDR + KEXEC_ARGV_SIZE/2 + offt;
					argc++;
				}
				ptr = strchr(ptr + 1, ' ');
			}
			break;
		}
	}

	if (image->type == KEXEC_TYPE_DEFAULT)
		kexec_argc = argc;
	else
		kdump_argc = argc;

	/* kexec/kdump need a safe page to save reboot_code_buffer */
	image->control_code_page = virt_to_page((void *)KEXEC_CTRL_CODE);

	return 0;
}

static void loongson_kexec_shutdown(void)
{
#ifdef CONFIG_SMP
	int cpu;

	/* All CPUs go to reboot_code_buffer */
	for_each_possible_cpu(cpu)
		if (!cpu_online(cpu))
			cpu_device_up(get_cpu_device(cpu));

	secondary_kexec_args[0] = TO_UNCAC(0x3ff01000);
#endif
	kexec_args[0] = kexec_argc;
	kexec_args[1] = fw_arg1;
	kexec_args[2] = fw_arg2;
	memcpy((void *)fw_arg1, kexec_argv, KEXEC_ARGV_SIZE);
	memcpy((void *)fw_arg2, kexec_envp, KEXEC_ENVP_SIZE);
}

static void loongson_crash_shutdown(struct pt_regs *regs)
{
	default_machine_crash_shutdown(regs);
	kexec_args[0] = kdump_argc;
	kexec_args[1] = fw_arg1;
	kexec_args[2] = fw_arg2;
#ifdef CONFIG_SMP
	secondary_kexec_args[0] = TO_UNCAC(0x3ff01000);
#endif
	memcpy((void *)fw_arg1, kdump_argv, KEXEC_ARGV_SIZE);
	memcpy((void *)fw_arg2, kexec_envp, KEXEC_ENVP_SIZE);
}

#endif

static int __init mips_reboot_setup(void)
{
	if (loongson_sysconf.restart_addr) {
		register_sys_off_handler(SYS_OFF_MODE_RESTART,
				 SYS_OFF_PRIO_FIRMWARE,
				 firmware_restart, NULL);
	}

	if (loongson_sysconf.poweroff_addr) {
		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
				 SYS_OFF_PRIO_FIRMWARE,
				 firmware_poweroff, NULL);
	}

#ifdef CONFIG_KEXEC_CORE
	kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
	if (WARN_ON(!kexec_argv))
		return -ENOMEM;

	kdump_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
	if (WARN_ON(!kdump_argv))
		return -ENOMEM;

	kexec_envp = kmalloc(KEXEC_ENVP_SIZE, GFP_KERNEL);
	if (WARN_ON(!kexec_envp))
		return -ENOMEM;

	fw_arg1 = KEXEC_ARGV_ADDR;
	memcpy(kexec_envp, (void *)fw_arg2, KEXEC_ENVP_SIZE);

	_machine_kexec_prepare = loongson_kexec_prepare;
	_machine_kexec_shutdown = loongson_kexec_shutdown;
	_machine_crash_shutdown = loongson_crash_shutdown;
#endif

	return 0;
}

arch_initcall(mips_reboot_setup);
