/*
 * SPAPR PHB emulation, RTAS interface to PCI config space, device tree nodes
 * for enumerated devices.
 *
 * Borrowed heavily from QEMU's spapr_pci.c,
 * Copyright (c) 2011 Alexey Kardashevskiy, IBM Corporation.
 * Copyright (c) 2011 David Gibson, IBM Corporation.
 *
 * Modifications copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include "spapr.h"
#include "spapr_pci.h"
#include "kvm/devices.h"
#include "kvm/fdt.h"
#include "kvm/util.h"
#include "kvm/of_pci.h"
#include "kvm/pci.h"

#include <linux/pci_regs.h>
#include <linux/byteorder.h>


/* #define DEBUG_PHB yes */
#ifdef DEBUG_PHB
#define phb_dprintf(fmt, ...)					\
	do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
#else
#define phb_dprintf(fmt, ...)			\
	do { } while (0)
#endif

static const uint32_t bars[] = {
	PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1,
	PCI_BASE_ADDRESS_2, PCI_BASE_ADDRESS_3,
	PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5
	/*, PCI_ROM_ADDRESS*/
};

#define PCI_NUM_REGIONS		7

static struct spapr_phb phb;

static void rtas_ibm_read_pci_config(struct kvm_cpu *vcpu,
				     uint32_t token, uint32_t nargs,
				     target_ulong args,
				     uint32_t nret, target_ulong rets)
{
	uint32_t val = 0;
	uint64_t buid = ((uint64_t)rtas_ld(vcpu->kvm, args, 1) << 32) | rtas_ld(vcpu->kvm, args, 2);
	union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
	struct pci_device_header *dev = pci__find_dev(addr.device_number);
	uint32_t size = rtas_ld(vcpu->kvm, args, 3);

	if (buid != phb.buid || !dev || (size > 4)) {
		phb_dprintf("- cfgRd buid 0x%lx cfg addr 0x%x size %d not found\n",
			    buid, addr.w, size);

		rtas_st(vcpu->kvm, rets, 0, -1);
		return;
	}
	pci__config_rd(vcpu->kvm, addr, &val, size);
	/* It appears this wants a byteswapped result... */
	switch (size) {
	case 4:
		val = le32_to_cpu(val);
		break;
	case 2:
		val = le16_to_cpu(val>>16);
		break;
	case 1:
		val = val >> 24;
		break;
	}
	phb_dprintf("- cfgRd buid 0x%lx addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
		    buid, addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
		    addr.register_number, val);

	rtas_st(vcpu->kvm, rets, 0, 0);
	rtas_st(vcpu->kvm, rets, 1, val);
}

static void rtas_read_pci_config(struct kvm_cpu *vcpu,
				 uint32_t token, uint32_t nargs,
				 target_ulong args,
				 uint32_t nret, target_ulong rets)
{
	uint32_t val;
	union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
	struct pci_device_header *dev = pci__find_dev(addr.device_number);
	uint32_t size = rtas_ld(vcpu->kvm, args, 1);

	if (!dev || (size > 4)) {
		rtas_st(vcpu->kvm, rets, 0, -1);
		return;
	}
	pci__config_rd(vcpu->kvm, addr, &val, size);
	switch (size) {
	case 4:
		val = le32_to_cpu(val);
		break;
	case 2:
		val = le16_to_cpu(val>>16); /* We're yuck-endian. */
		break;
	case 1:
		val = val >> 24;
		break;
	}
	phb_dprintf("- cfgRd addr 0x%x size %d, val 0x%x\n", addr.w, size, val);
	rtas_st(vcpu->kvm, rets, 0, 0);
	rtas_st(vcpu->kvm, rets, 1, val);
}

static void rtas_ibm_write_pci_config(struct kvm_cpu *vcpu,
				      uint32_t token, uint32_t nargs,
				      target_ulong args,
				      uint32_t nret, target_ulong rets)
{
	uint64_t buid = ((uint64_t)rtas_ld(vcpu->kvm, args, 1) << 32) | rtas_ld(vcpu->kvm, args, 2);
	union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
	struct pci_device_header *dev = pci__find_dev(addr.device_number);
	uint32_t size = rtas_ld(vcpu->kvm, args, 3);
	uint32_t val = rtas_ld(vcpu->kvm, args, 4);

	if (buid != phb.buid || !dev || (size > 4)) {
		phb_dprintf("- cfgWr buid 0x%lx cfg addr 0x%x/%d error (val 0x%x)\n",
			    buid, addr.w, size, val);

		rtas_st(vcpu->kvm, rets, 0, -1);
		return;
	}
	phb_dprintf("- cfgWr buid 0x%lx addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
		    buid, addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
		    addr.register_number, val);
	switch (size) {
	case 4:
		val = le32_to_cpu(val);
		break;
	case 2:
		val = le16_to_cpu(val) << 16;
		break;
	case 1:
		val = val >> 24;
		break;
	}
	pci__config_wr(vcpu->kvm, addr, &val, size);
	rtas_st(vcpu->kvm, rets, 0, 0);
}

static void rtas_write_pci_config(struct kvm_cpu *vcpu,
				  uint32_t token, uint32_t nargs,
				  target_ulong args,
				  uint32_t nret, target_ulong rets)
{
	union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
	struct pci_device_header *dev = pci__find_dev(addr.device_number);
	uint32_t size = rtas_ld(vcpu->kvm, args, 1);
	uint32_t val = rtas_ld(vcpu->kvm, args, 2);

	if (!dev || (size > 4)) {
		rtas_st(vcpu->kvm, rets, 0, -1);
		return;
	}

	phb_dprintf("- cfgWr addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
		    addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
		    addr.register_number, val);
	switch (size) {
	case 4:
		val = le32_to_cpu(val);
		break;
	case 2:
		val = le16_to_cpu(val) << 16;
		break;
	case 1:
		val = val >> 24;
		break;
	}
	pci__config_wr(vcpu->kvm, addr, &val, size);
	rtas_st(vcpu->kvm, rets, 0, 0);
}

void spapr_create_phb(struct kvm *kvm,
		      const char *busname, uint64_t buid,
		      uint64_t mem_win_addr, uint64_t mem_win_size,
		      uint64_t io_win_addr, uint64_t io_win_size)
{
	/*
	 * Since kvmtool doesn't really have any concept of buses etc.,
	 * there's nothing to register here.  Just register RTAS.
	 */
	spapr_rtas_register("read-pci-config", rtas_read_pci_config);
	spapr_rtas_register("write-pci-config", rtas_write_pci_config);
	spapr_rtas_register("ibm,read-pci-config", rtas_ibm_read_pci_config);
	spapr_rtas_register("ibm,write-pci-config", rtas_ibm_write_pci_config);

	phb.buid = buid;
	phb.mem_addr = mem_win_addr;
	phb.mem_size = mem_win_size;
	phb.io_addr  = io_win_addr;
	phb.io_size  = io_win_size;

	kvm->arch.phb = &phb;
}

static uint32_t bar_to_ss(unsigned long bar)
{
	if ((bar & PCI_BASE_ADDRESS_SPACE) ==
	    PCI_BASE_ADDRESS_SPACE_IO)
		return OF_PCI_SS_IO;
	else if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64)
		return OF_PCI_SS_M64;
	else
		return OF_PCI_SS_M32;
}

static unsigned long bar_to_addr(unsigned long bar)
{
	if ((bar & PCI_BASE_ADDRESS_SPACE) ==
	    PCI_BASE_ADDRESS_SPACE_IO)
		return bar & PCI_BASE_ADDRESS_IO_MASK;
	else
		return bar & PCI_BASE_ADDRESS_MEM_MASK;
}

int spapr_populate_pci_devices(struct kvm *kvm,
			       uint32_t xics_phandle,
			       void *fdt)
{
	int bus_off, node_off = 0, devid, fn, i, n, devices;
	struct device_header *dev_hdr;
	char nodename[256];
	struct of_pci_unit64_address {
		u32 phys_hi;
		u64 addr;
		u64 size;
	} __attribute((packed)) reg[PCI_NUM_REGIONS + 1], assigned_addresses[PCI_NUM_REGIONS];
	uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
	struct of_pci_ranges_entry ranges[] = {
		{
			{
				cpu_to_be32(of_pci_b_ss(1)),
				cpu_to_be32(0),
				cpu_to_be32(0),
			},
			cpu_to_be64(phb.io_addr),
			cpu_to_be64(phb.io_size),
		},
		{
			{
				cpu_to_be32(of_pci_b_ss(2)),
				cpu_to_be32(0),
				cpu_to_be32(0),
			},
			cpu_to_be64(phb.mem_addr),
			cpu_to_be64(phb.mem_size),
		},
	};
	uint64_t bus_reg[] = { cpu_to_be64(phb.buid), 0 };
	uint32_t interrupt_map_mask[] = {
		cpu_to_be32(of_pci_b_ddddd(-1)|of_pci_b_fff(-1)), 0x0, 0x0, 0x0};
	uint32_t interrupt_map[SPAPR_PCI_NUM_LSI][7];

	/* Start populating the FDT */
	sprintf(nodename, "pci@%" PRIx64, phb.buid);
	bus_off = fdt_add_subnode(fdt, 0, nodename);
	if (bus_off < 0) {
		die("error making bus subnode, %s\n", fdt_strerror(bus_off));
		return bus_off;
	}

	/* Write PHB properties */
	_FDT(fdt_setprop_string(fdt, bus_off, "device_type", "pci"));
	_FDT(fdt_setprop_string(fdt, bus_off, "compatible", "IBM,Logical_PHB"));
	_FDT(fdt_setprop_cell(fdt, bus_off, "#address-cells", 0x3));
	_FDT(fdt_setprop_cell(fdt, bus_off, "#size-cells", 0x2));
	_FDT(fdt_setprop_cell(fdt, bus_off, "#interrupt-cells", 0x1));
	_FDT(fdt_setprop(fdt, bus_off, "used-by-rtas", NULL, 0));
	_FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range)));
	_FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof(ranges)));
	_FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
	_FDT(fdt_setprop(fdt, bus_off, "interrupt-map-mask",
			 &interrupt_map_mask, sizeof(interrupt_map_mask)));

	/* Populate PCI devices and allocate IRQs */
	devices = 0;
	dev_hdr = device__first_dev(DEVICE_BUS_PCI);
	while (dev_hdr) {
		uint32_t *irqmap = interrupt_map[devices];
		struct pci_device_header *hdr = dev_hdr->data;

		if (!hdr)
			continue;

		devid = dev_hdr->dev_num;
		fn = 0; /* kvmtool doesn't yet do multifunction devices */

		sprintf(nodename, "pci@%u,%u", devid, fn);

		/* Allocate interrupt from the map */
		if (devid > SPAPR_PCI_NUM_LSI)	{
			die("Unexpected behaviour in spapr_populate_pci_devices,"
			    "wrong devid %u\n", devid);
		}
		irqmap[0] = cpu_to_be32(of_pci_b_ddddd(devid)|of_pci_b_fff(fn));
		irqmap[1] = 0;
		irqmap[2] = 0;
		irqmap[3] = 0;
		irqmap[4] = cpu_to_be32(xics_phandle);
		/*
		 * This is nasty; the PCI devs are set up such that their own
		 * header's irq_line indicates the direct XICS IRQ number to
		 * use.  There REALLY needs to be a hierarchical system in place
		 * to 'raise' an IRQ on the bridge which indexes/looks up which
		 * XICS IRQ to fire.
		 */
		irqmap[5] = cpu_to_be32(hdr->irq_line);
		irqmap[6] = cpu_to_be32(0x8);

		/* Add node to FDT */
		node_off = fdt_add_subnode(fdt, bus_off, nodename);
		if (node_off < 0) {
			die("error making node subnode, %s\n", fdt_strerror(bus_off));
			return node_off;
		}

		_FDT(fdt_setprop_cell(fdt, node_off, "vendor-id",
				      le16_to_cpu(hdr->vendor_id)));
		_FDT(fdt_setprop_cell(fdt, node_off, "device-id",
				      le16_to_cpu(hdr->device_id)));
		_FDT(fdt_setprop_cell(fdt, node_off, "revision-id",
				      hdr->revision_id));
		_FDT(fdt_setprop_cell(fdt, node_off, "class-code",
				      hdr->class[0] | (hdr->class[1] << 8) | (hdr->class[2] << 16)));
		_FDT(fdt_setprop_cell(fdt, node_off, "subsystem-id",
				      le16_to_cpu(hdr->subsys_id)));
		_FDT(fdt_setprop_cell(fdt, node_off, "subsystem-vendor-id",
				      le16_to_cpu(hdr->subsys_vendor_id)));

		/* Config space region comes first */
		reg[0].phys_hi = cpu_to_be32(
			of_pci_b_n(0) |
			of_pci_b_p(0) |
			of_pci_b_t(0) |
			of_pci_b_ss(OF_PCI_SS_CONFIG) |
			of_pci_b_bbbbbbbb(0) |
			of_pci_b_ddddd(devid) |
			of_pci_b_fff(fn));
		reg[0].addr = 0;
		reg[0].size = 0;

		n = 0;
		/* Six BARs, no ROM supported, addresses are 32bit */
		for (i = 0; i < 6; ++i) {
			if (0 == hdr->bar[i]) {
				continue;
			}

			reg[n+1].phys_hi = cpu_to_be32(
				of_pci_b_n(0) |
				of_pci_b_p(0) |
				of_pci_b_t(0) |
				of_pci_b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) |
				of_pci_b_bbbbbbbb(0) |
				of_pci_b_ddddd(devid) |
				of_pci_b_fff(fn) |
				of_pci_b_rrrrrrrr(bars[i]));
			reg[n+1].size = cpu_to_be64(pci__bar_size(hdr, i));
			reg[n+1].addr = 0;

			assigned_addresses[n].phys_hi = cpu_to_be32(
				of_pci_b_n(1) |
				of_pci_b_p(0) |
				of_pci_b_t(0) |
				of_pci_b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) |
				of_pci_b_bbbbbbbb(0) |
				of_pci_b_ddddd(devid) |
				of_pci_b_fff(fn) |
				of_pci_b_rrrrrrrr(bars[i]));

			/*
			 * Writing zeroes to assigned_addresses causes the guest kernel to
			 * reassign BARs
			 */
			assigned_addresses[n].addr = cpu_to_be64(bar_to_addr(le32_to_cpu(hdr->bar[i])));
			assigned_addresses[n].size = reg[n+1].size;

			++n;
		}
		_FDT(fdt_setprop(fdt, node_off, "reg", reg, sizeof(reg[0])*(n+1)));
		_FDT(fdt_setprop(fdt, node_off, "assigned-addresses",
				 assigned_addresses,
				 sizeof(assigned_addresses[0])*(n)));
		_FDT(fdt_setprop_cell(fdt, node_off, "interrupts",
				      hdr->irq_pin));

		/* We don't set ibm,dma-window property as we don't have an IOMMU. */

		++devices;
		dev_hdr = device__next_dev(dev_hdr);
	}

	/* Write interrupt map */
	_FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map,
			 devices * sizeof(interrupt_map[0])));

	return 0;
}
