/* Copyright 2015 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include <skiboot.h>
#include <device.h>
#include <console.h>
#include <chip.h>
#include <cpu.h>
#include <opal-api.h>
#include <opal-internal.h>
#include <time-utils.h>
#include <time.h>

#include "mambo.h"

static bool mambo_probe(void)
{
	if (!dt_find_by_path(dt_root, "/mambo"))
		return false;

	return true;
}

#define BD_INFO_SYNC		0
#define BD_INFO_STATUS		1
#define BD_INFO_BLKSZ		2
#define BD_INFO_DEVSZ		3
#define BD_INFO_CHANGE		4

#define BD_SECT_SZ		512

static inline int callthru_disk_read(int id, void *buf, unsigned long sect,
				     unsigned long nrsect)
{
	return callthru3(SIM_BOGUS_DISK_READ, (unsigned long)buf, sect,
			 (nrsect << 16) | id);
}

static inline int callthru_disk_write(int id, void *buf, unsigned long sect,
				      unsigned long nrsect)
{
	return callthru3(SIM_BOGUS_DISK_WRITE, (unsigned long)buf, sect,
			 (nrsect << 16) | id);
}

static inline unsigned long callthru_disk_info(int op, int id)
{
	return callthru2(SIM_BOGUS_DISK_INFO, (unsigned long)op,
			 (unsigned long)id);
}

extern unsigned long callthru_tcl(const char *str, int len);

unsigned long callthru_tcl(const char *str, int len)
{
	prlog(PR_DEBUG, "Sending TCL to Mambo, cmd: %s\n", str);
	return callthru2(SIM_CALL_TCL, (unsigned long)str, (unsigned long)len);
}

struct bogus_disk_info {
	unsigned long size;
	int id;
};

static int bogus_disk_read(struct blocklevel_device *bl, uint64_t pos, void *buf,
			  uint64_t len)
{
	struct bogus_disk_info *bdi = bl->priv;
	int rc, read_sectors = 0;
	char b[BD_SECT_SZ];

	if (len >= BD_SECT_SZ) {
		rc = callthru_disk_read(bdi->id, buf, pos/BD_SECT_SZ,
					  len/BD_SECT_SZ);
		if (rc)
			return rc;
		read_sectors = (len / BD_SECT_SZ);
	}

	if ((len % BD_SECT_SZ) == 0)
		return 0;

	/*
	 * Read any unaligned data into a temporaty buffer b, then copy
	 * to buf
	 */
	rc =  callthru_disk_read(bdi->id, b, (pos/BD_SECT_SZ) + read_sectors, 1);
	if (rc)
		return rc;
	memcpy(buf + (read_sectors * BD_SECT_SZ) , &b[pos % BD_SECT_SZ],
			len - (read_sectors * BD_SECT_SZ));
	return rc;
}

static int bogus_disk_write(struct blocklevel_device *bl, uint64_t pos,
			    const void *buf, uint64_t len)
{
	struct bogus_disk_info *bdi = bl->priv;

	if ((len % BD_SECT_SZ) != 0)
		return OPAL_PARAMETER;

	return callthru_disk_write(bdi->id, (void *)buf, pos/BD_SECT_SZ,
				   len/BD_SECT_SZ);

}

static int bogus_disk_erase(struct blocklevel_device *bl __unused,
			   uint64_t pos __unused, uint64_t len __unused)
{
	return 0; /* NOP */
}

static int bogus_disk_get_info(struct blocklevel_device *bl, const char **name,
			      uint64_t *total_size, uint32_t *erase_granule)
{
	struct bogus_disk_info *bdi = bl->priv;

	if (total_size)
		*total_size = bdi->size;

	if (erase_granule)
		*erase_granule = BD_SECT_SZ;

	if (name)
		*name = "mambobogus";

	return 0;
}

static void bogus_disk_flash_init(void)
{
	struct blocklevel_device *bl;
	struct bogus_disk_info *bdi;
	unsigned long id = 0, size;
	int rc;

	if (!chip_quirk(QUIRK_MAMBO_CALLOUTS))
		return;

	while (1) {

		rc = callthru_disk_info(BD_INFO_STATUS, id);
		if (rc < 0)
			return;

		size = callthru_disk_info(BD_INFO_DEVSZ, id) * 1024;
		prlog(PR_NOTICE, "mambo: Found bogus disk size: 0x%lx\n", size);

		bl = zalloc(sizeof(struct blocklevel_device));
		bdi = zalloc(sizeof(struct bogus_disk_info));
		if (!bl || !bdi) {
			free(bl);
			free(bdi);
			prerror("mambo: Failed to start bogus disk, ENOMEM\n");
			return;
		}

		bl->read = &bogus_disk_read;
		bl->write = &bogus_disk_write;
		bl->erase = &bogus_disk_erase;
		bl->get_info = &bogus_disk_get_info;
		bdi->id = id;
		bdi->size = size;
		bl->priv = bdi;
		bl->erase_mask = BD_SECT_SZ - 1;

		rc = flash_register(bl);
		if (rc)
			prerror("mambo: Failed to register bogus disk: %li\n",
				id);
		id++;
	}
}

static int64_t mambo_rtc_read(uint32_t *ymd, uint64_t *hmsm)
{
	int64_t mambo_time;
	struct tm t;
	time_t mt;

	if (!ymd || !hmsm)
		return OPAL_PARAMETER;

	mambo_time = callthru0(SIM_GET_TIME_CODE);
	mt = mambo_time >> 32;
	gmtime_r(&mt, &t);
	tm_to_datetime(&t, ymd, hmsm);

	return OPAL_SUCCESS;
}

static void mambo_rtc_init(void)
{
	struct dt_node *np = dt_new(opal_node, "rtc");
	dt_add_property_strings(np, "compatible", "ibm,opal-rtc");

	opal_register(OPAL_RTC_READ, mambo_rtc_read, 2);
}

static void mambo_system_reset_cpu(struct cpu_thread *cpu)
{
	uint32_t core_id;
	uint32_t thread_id;
	char tcl_cmd[50];

	core_id = pir_to_core_id(cpu->pir);
	thread_id = pir_to_thread_id(cpu->pir);

	snprintf(tcl_cmd, sizeof(tcl_cmd), "mysim cpu %i:%i interrupt SystemReset", core_id, thread_id);
	callthru_tcl(tcl_cmd, strlen(tcl_cmd));
}

#define SYS_RESET_ALL		-1
#define SYS_RESET_ALL_OTHERS	-2

static int64_t mambo_signal_system_reset(int32_t cpu_nr)
{
	struct cpu_thread *cpu;

	if (cpu_nr < 0) {
		if (cpu_nr < SYS_RESET_ALL_OTHERS)
			return OPAL_PARAMETER;

		for_each_cpu(cpu) {
			if (cpu == this_cpu())
				continue;
			mambo_system_reset_cpu(cpu);

		}
		if (cpu_nr == SYS_RESET_ALL)
			mambo_system_reset_cpu(this_cpu());

		return OPAL_SUCCESS;

	} else {
		cpu = find_cpu_by_server(cpu_nr);
		if (!cpu)
			return OPAL_PARAMETER;

		mambo_system_reset_cpu(cpu);
		return OPAL_SUCCESS;
	}
}

static void mambo_sreset_init(void)
{
	opal_register(OPAL_SIGNAL_SYSTEM_RESET, mambo_signal_system_reset, 1);
}

static void mambo_platform_init(void)
{
	mambo_sreset_init();
	mambo_rtc_init();
	bogus_disk_flash_init();
}

static int64_t mambo_cec_power_down(uint64_t request __unused)
{
	if (chip_quirk(QUIRK_MAMBO_CALLOUTS))
		callthru0(SIM_EXIT_CODE);

	return OPAL_UNSUPPORTED;
}

static void __attribute__((noreturn)) mambo_terminate(const char *msg __unused)
{
	if (chip_quirk(QUIRK_MAMBO_CALLOUTS))
		callthru0(SIM_EXIT_CODE);

	for (;;) ;
}

static int mambo_heartbeat_time(void)
{
	/*
	 * Mambo is slow and has no console input interrupt, so faster
	 * polling is needed to ensure its responsiveness.
	 */
	return 100;
}

DECLARE_PLATFORM(mambo) = {
	.name			= "Mambo",
	.probe			= mambo_probe,
	.init		= mambo_platform_init,
	.cec_power_down = mambo_cec_power_down,
	.terminate	= mambo_terminate,
	.start_preload_resource	= flash_start_preload_resource,
	.resource_loaded	= flash_resource_loaded,
	.heartbeat_time		= mambo_heartbeat_time,
	.nvram_info		= fake_nvram_info,
	.nvram_start_read	= fake_nvram_start_read,
	.nvram_write		= fake_nvram_write,
};
