// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/*
 * Excuse me, you do work for me now?
 *
 * Copyright 2013-2019 IBM Corp.
 */

#include <skiboot.h>
#include <chip.h>
#include <cpu.h>
#include <fsp.h>
#include <interrupts.h>
#include <opal.h>
#include <io.h>
#include <cec.h>
#include <device.h>
#include <ccan/str/str.h>
#include <timer.h>
#include <sbe-p8.h>
#include <sbe-p9.h>
#include <xive.h>

/* ICP registers */
#define ICP_XIRR		0x4	/* 32-bit access */
#define ICP_CPPR		0x4	/* 8-bit access */
#define ICP_MFRR		0xc	/* 8-bit access */

static LIST_HEAD(irq_sources);
static LIST_HEAD(irq_sources2);
static struct lock irq_lock = LOCK_UNLOCKED;

void __register_irq_source(struct irq_source *is, bool secondary)
{
	struct irq_source *is1;
	struct list_head *list = secondary ? &irq_sources2 : &irq_sources;

	prlog(PR_DEBUG, "IRQ: Registering %04x..%04x ops @%p (data %p)%s\n",
	      is->start, is->end - 1, is->ops, is->data,
	      secondary ? " [secondary]" : "");

	lock(&irq_lock);
	list_for_each(list, is1, link) {
		if (is->end > is1->start && is->start < is1->end) {
			prerror("register IRQ source overlap !\n");
			prerror("  new: %x..%x old: %x..%x\n",
				is->start, is->end - 1,
				is1->start, is1->end - 1);
			assert(0);
		}
	}
	list_add_tail(list, &is->link);
	unlock(&irq_lock);
}

void register_irq_source(const struct irq_source_ops *ops, void *data,
			 uint32_t start, uint32_t count)
{
	struct irq_source *is;

	is = zalloc(sizeof(struct irq_source));
	assert(is);
	is->start = start;
	is->end = start + count;
	is->ops = ops;
	is->data = data;

	__register_irq_source(is, false);
}

void unregister_irq_source(uint32_t start, uint32_t count)
{
	struct irq_source *is;

	/* Note: We currently only unregister from the primary sources */
	lock(&irq_lock);
	list_for_each(&irq_sources, is, link) {
		if (start >= is->start && start < is->end) {
			if (start != is->start ||
			    count != (is->end - is->start)) {
				prerror("unregister IRQ source mismatch !\n");
				prerror("start:%x, count: %x match: %x..%x\n",
					start, count, is->start, is->end);
				assert(0);
			}
			list_del(&is->link);
			unlock(&irq_lock);
			/* XXX Add synchronize / RCU */
			free(is);
			return;
		}
	}
	unlock(&irq_lock);
	prerror("unregister IRQ source not found !\n");
	prerror("start:%x, count: %x\n", start, count);
	assert(0);
}

struct irq_source *irq_find_source(uint32_t isn)
{
	struct irq_source *is;

	lock(&irq_lock);
	/*
	 * XXX This really needs some kind of caching !
	 */
	list_for_each(&irq_sources, is, link) {
		if (isn >= is->start && isn < is->end) {
			unlock(&irq_lock);
			return is;
		}
	}
	list_for_each(&irq_sources2, is, link) {
		if (isn >= is->start && isn < is->end) {
			unlock(&irq_lock);
			return is;
		}
	}
	unlock(&irq_lock);

	return NULL;
}

void irq_for_each_source(void (*cb)(struct irq_source *, void *), void *data)
{
	struct irq_source *is;

	lock(&irq_lock);
	list_for_each(&irq_sources, is, link)
		cb(is, data);
	list_for_each(&irq_sources2, is, link)
		cb(is, data);
	unlock(&irq_lock);
}

/*
 * This takes a 6-bit chip id and returns a 20 bit value representing
 * the PSI interrupt. This includes all the fields above, ie, is a
 * global interrupt number.
 *
 * For P8, this returns the base of the 8-interrupts block for PSI
 */
uint32_t get_psi_interrupt(uint32_t chip_id)
{
	uint32_t irq;

	switch(proc_gen) {
	case proc_gen_p8:
		irq = p8_chip_irq_block_base(chip_id, P8_IRQ_BLOCK_MISC);
		irq += P8_IRQ_MISC_PSI_BASE;
		break;
	default:
		assert(false);
	};

	return irq;
}


struct dt_node *add_ics_node(void)
{
	struct dt_node *ics;
	bool has_xive;
	bool has_xive_only = proc_gen >= proc_gen_p10;

	if (has_xive_only)
		return NULL;

	ics = dt_new_addr(dt_root, "interrupt-controller", 0);
	if (!ics)
		return NULL;

	has_xive = proc_gen >= proc_gen_p9;

	dt_add_property_cells(ics, "reg", 0, 0, 0, 0);
	dt_add_property_strings(ics, "compatible",
				has_xive ? "ibm,opal-xive-vc" : "IBM,ppc-xics",
				"IBM,opal-xics");
	dt_add_property_cells(ics, "#address-cells", 0);
	dt_add_property_cells(ics, "#interrupt-cells", 2);
	dt_add_property_string(ics, "device_type",
			       "PowerPC-Interrupt-Source-Controller");
	dt_add_property(ics, "interrupt-controller", NULL, 0);

	return ics;
}

uint32_t get_ics_phandle(void)
{
	struct dt_node *i;
	bool has_xive_only = proc_gen >= proc_gen_p10;

	if (has_xive_only)
		return xive2_get_phandle();

	for (i = dt_first(dt_root); i; i = dt_next(dt_root, i)) {
		if (streq(i->name, "interrupt-controller@0")) {
			return i->phandle;
		}
	}
	abort();
}

void add_opal_interrupts(void)
{
	struct irq_source *is;
	unsigned int i, ns, tns = 0, count = 0;
	uint32_t isn;
	__be32 *irqs = NULL;
	char *names = NULL;

	lock(&irq_lock);
	list_for_each(&irq_sources, is, link) {
		/*
		 * Don't even consider sources that don't have an interrupts
		 * callback or don't have an attributes one.
		 */
		if (!is->ops->interrupt || !is->ops->attributes)
			continue;
		for (isn = is->start; isn < is->end; isn++) {
			uint64_t attr = is->ops->attributes(is, isn);
			uint32_t iflags;
			char *name;

			if (attr & IRQ_ATTR_TARGET_LINUX)
				continue;
			if (attr & IRQ_ATTR_TYPE_MSI)
				iflags = 0;
			else
				iflags = 1;
			name = is->ops->name ? is->ops->name(is, isn) : NULL;
			ns = name ? strlen(name) : 0;
			prlog(PR_DEBUG, "irq %x name: %s %s\n",
			      isn,
			      name ? name : "<null>",
			      iflags ? "[level]" : "[edge]");
			names = realloc(names, tns + ns + 1);
			if (name) {
				strcpy(names + tns, name);
				tns += (ns + 1);
				free(name);
			} else
				names[tns++] = 0;
			i = count++;
			irqs = realloc(irqs, 8 * count);
			irqs[i*2] = cpu_to_be32(isn);
			irqs[i*2+1] = cpu_to_be32(iflags);
		}
	}
	unlock(&irq_lock);

	/* First create the standard "interrupts" property and the
	 * corresponding names property
	 */
	dt_add_property_cells(opal_node, "interrupt-parent", get_ics_phandle());
	dt_add_property(opal_node, "interrupts", irqs, count * 8);
	dt_add_property(opal_node, "opal-interrupts-names", names, tns);
	dt_add_property(opal_node, "interrupt-names", names, tns);

	/* Now "reduce" it to the old style "opal-interrupts" property
	 * format by stripping out the flags. The "opal-interrupts"
	 * property has one cell per interrupt, it is not a standard
	 * "interrupt" property.
	 *
	 * Note: Even if empty, create it, otherwise some bogus error
	 * handling in Linux can cause problems.
	 */
	for (i = 1; i < count; i++)
		irqs[i] = irqs[i * 2];
	dt_add_property(opal_node, "opal-interrupts", irqs, count * 4);

	free(irqs);
	free(names);
}

/*
 * This is called at init time (and one fast reboot) to sanitize the
 * ICP. We set our priority to 0 to mask all interrupts and make sure
 * no IPI is on the way. This is also called on wakeup from nap
 */
void reset_cpu_icp(void)
{
	void *icp = this_cpu()->icp_regs;

	if (!icp)
		return;

	/* Dummy fetch */
	in_be32(icp + ICP_XIRR);

	/* Clear pending IPIs */
	out_8(icp + ICP_MFRR, 0xff);

	/* Set priority to max, ignore all incoming interrupts, EOI IPIs */
	out_be32(icp + ICP_XIRR, 2);
}

/* Used by the PSI code to send an EOI during reset. This will also
 * set the CPPR to 0 which should already be the case anyway
 */
void icp_send_eoi(uint32_t interrupt)
{
	void *icp = this_cpu()->icp_regs;

	if (!icp)
		return;

	/* Set priority to max, ignore all incoming interrupts */
	out_be32(icp + ICP_XIRR, interrupt & 0xffffff);
}

/* This is called before winkle or nap, we clear pending IPIs and
 * set our priority to 1 to mask all but the IPI.
 */
void icp_prep_for_pm(void)
{
	void *icp = this_cpu()->icp_regs;

	if (!icp)
		return;

	/* Clear pending IPIs */
	out_8(icp + ICP_MFRR, 0xff);

	/* Set priority to 1, ignore all incoming interrupts, EOI IPIs */
	out_be32(icp + ICP_XIRR, 0x01000002);
}

/* This is called to wakeup somebody from winkle */
void icp_kick_cpu(struct cpu_thread *cpu)
{
	void *icp = cpu->icp_regs;

	if (!icp)
		return;

	/* Send high priority IPI */
	out_8(icp + ICP_MFRR, 0);
}

/* Returns the number of chip ID bits used for interrupt numbers */
static uint32_t p8_chip_id_bits(uint32_t chip)
{
	struct proc_chip *proc_chip = get_chip(chip);

	assert(proc_chip);
	switch (proc_chip->type) {
	case PROC_CHIP_P8_MURANO:
	case PROC_CHIP_P8_VENICE:
		return 6;
		break;

	case PROC_CHIP_P8_NAPLES:
		return 5;
		break;

	default:
		/* This shouldn't be called on non-P8 based systems */
		assert(0);
		return 0;
		break;
	}
}

/* The chip id mask is the upper p8_chip_id_bits of the irq number */
static uint32_t chip_id_mask(uint32_t chip)
{
	uint32_t chip_id_bits = p8_chip_id_bits(chip);
	uint32_t chip_id_mask;

	chip_id_mask = ((1 << chip_id_bits) - 1);
	chip_id_mask <<= P8_IRQ_BITS - chip_id_bits;
	return chip_id_mask;
}

/* The block mask is what remains of the 19 bit irq number after
 * removing the upper 5 or 6 bits for the chip# and the lower 11 bits
 * for the number of bits per block. */
static uint32_t block_mask(uint32_t chip)
{
	uint32_t chip_id_bits = p8_chip_id_bits(chip);
	uint32_t irq_block_mask;

	irq_block_mask = P8_IRQ_BITS - chip_id_bits - P8_IVE_BITS;
	irq_block_mask = ((1 << irq_block_mask) - 1) << P8_IVE_BITS;
	return irq_block_mask;
}

uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block)
{
	uint32_t irq;

	assert(chip < (1 << p8_chip_id_bits(chip)));
	irq = SETFIELD(chip_id_mask(chip), 0, chip);
	irq = SETFIELD(block_mask(chip), irq, block);

	return irq;
}

uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb)
{
	assert(chip < (1 << p8_chip_id_bits(chip)));

	return p8_chip_irq_block_base(chip, phb + P8_IRQ_BLOCK_PHB_BASE);
}

uint32_t p8_irq_to_chip(uint32_t irq)
{
	/* This assumes we only have one type of cpu in a system,
	 * which should be ok. */
	return GETFIELD(chip_id_mask(this_cpu()->chip_id), irq);
}

uint32_t p8_irq_to_block(uint32_t irq)
{
	return GETFIELD(block_mask(this_cpu()->chip_id), irq);
}

uint32_t p8_irq_to_phb(uint32_t irq)
{
	return p8_irq_to_block(irq) - P8_IRQ_BLOCK_PHB_BASE;
}

bool __irq_source_eoi(struct irq_source *is, uint32_t isn)
{
	if (!is->ops->eoi)
		return false;

	is->ops->eoi(is, isn);
	return true;
}

bool irq_source_eoi(uint32_t isn)
{
	struct irq_source *is = irq_find_source(isn);

	if (!is)
		return false;

	return __irq_source_eoi(is, isn);
}

static int64_t opal_set_xive(uint32_t isn, uint16_t server, uint8_t priority)
{
	struct irq_source *is = irq_find_source(isn);

	if (!is || !is->ops->set_xive)
		return OPAL_PARAMETER;

	return is->ops->set_xive(is, isn, server, priority);
}
opal_call(OPAL_SET_XIVE, opal_set_xive, 3);

static int64_t opal_get_xive(uint32_t isn, __be16 *server, uint8_t *priority)
{
	struct irq_source *is = irq_find_source(isn);
	uint16_t s;
	int64_t ret;

	if (!opal_addr_valid(server))
		return OPAL_PARAMETER;

	if (!is || !is->ops->get_xive)
		return OPAL_PARAMETER;

	ret = is->ops->get_xive(is, isn, &s, priority);
	*server = cpu_to_be16(s);
	return ret;
}
opal_call(OPAL_GET_XIVE, opal_get_xive, 3);

static int64_t opal_handle_interrupt(uint32_t isn, __be64 *outstanding_event_mask)
{
	struct irq_source *is = irq_find_source(isn);
	int64_t rc = OPAL_SUCCESS;

	if (!opal_addr_valid(outstanding_event_mask))
		return OPAL_PARAMETER;

	/* No source ? return */
	if (!is || !is->ops->interrupt) {
		rc = OPAL_PARAMETER;
		goto bail;
	}

	/* Run it */
	is->ops->interrupt(is, isn);

	/* Check timers if SBE timer isn't working */
	if (!p8_sbe_timer_ok() && !p9_sbe_timer_ok())
		check_timers(true);

	/* Update output events */
 bail:
	if (outstanding_event_mask)
		*outstanding_event_mask = cpu_to_be64(opal_pending_events);

	return rc;
}
opal_call(OPAL_HANDLE_INTERRUPT, opal_handle_interrupt, 2);

void init_interrupts(void)
{
	struct dt_node *icp;
	const struct dt_property *sranges;
	struct cpu_thread *cpu;
	u32 base, count, i;
	u64 addr, size;

	dt_for_each_compatible(dt_root, icp, "ibm,ppc-xicp") {
		sranges = dt_require_property(icp,
					      "ibm,interrupt-server-ranges",
					      -1);
		base = dt_get_number(sranges->prop, 1);
		count = dt_get_number(sranges->prop + 4, 1);
		for (i = 0; i < count; i++) {
			addr = dt_get_address(icp, i, &size);
			cpu = find_cpu_by_server(base + i);
			if (cpu)
				cpu->icp_regs = (void *)addr;
		}
	}
}

