/*
 * Emulation of the ibm,plb-pcix PCI controller
 * This is found in some 440 SoCs e.g. the 460EX.
 *
 * Copyright (c) 2016-2018 BALATON Zoltan
 *
 * Derived from ppc4xx_pci.c and pci-host/ppce500.c
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "hw/irq.h"
#include "hw/ppc/ppc.h"
#include "hw/ppc/ppc4xx.h"
#include "hw/pci/pci_device.h"
#include "hw/pci/pci_host.h"
#include "trace.h"
#include "qom/object.h"

struct PLBOutMap {
    uint64_t la;
    uint64_t pcia;
    uint32_t sa;
    MemoryRegion mr;
};

struct PLBInMap {
    uint64_t sa;
    uint64_t la;
    MemoryRegion mr;
};

OBJECT_DECLARE_SIMPLE_TYPE(PPC440PCIXState, PPC440_PCIX_HOST)

#define PPC440_PCIX_NR_POMS 3
#define PPC440_PCIX_NR_PIMS 3

struct PPC440PCIXState {
    PCIHostState parent_obj;

    PCIDevice *dev;
    struct PLBOutMap pom[PPC440_PCIX_NR_POMS];
    struct PLBInMap pim[PPC440_PCIX_NR_PIMS];
    uint32_t sts;
    qemu_irq irq;
    AddressSpace bm_as;
    MemoryRegion bm;

    MemoryRegion container;
    MemoryRegion iomem;
    MemoryRegion busmem;
    MemoryRegion regs;
};

#define PPC440_REG_BASE     0x80000
#define PPC440_REG_SIZE     0xff

#define PCIC0_CFGADDR       0x0
#define PCIC0_CFGDATA       0x4

#define PCIX0_POM0LAL       0x68
#define PCIX0_POM0LAH       0x6c
#define PCIX0_POM0SA        0x70
#define PCIX0_POM0PCIAL     0x74
#define PCIX0_POM0PCIAH     0x78
#define PCIX0_POM1LAL       0x7c
#define PCIX0_POM1LAH       0x80
#define PCIX0_POM1SA        0x84
#define PCIX0_POM1PCIAL     0x88
#define PCIX0_POM1PCIAH     0x8c
#define PCIX0_POM2SA        0x90

#define PCIX0_PIM0SAL       0x98
#define PCIX0_PIM0LAL       0x9c
#define PCIX0_PIM0LAH       0xa0
#define PCIX0_PIM1SA        0xa4
#define PCIX0_PIM1LAL       0xa8
#define PCIX0_PIM1LAH       0xac
#define PCIX0_PIM2SAL       0xb0
#define PCIX0_PIM2LAL       0xb4
#define PCIX0_PIM2LAH       0xb8
#define PCIX0_PIM0SAH       0xf8
#define PCIX0_PIM2SAH       0xfc

#define PCIX0_STS           0xe0

#define PCI_ALL_SIZE        (PPC440_REG_BASE + PPC440_REG_SIZE)

static void ppc440_pcix_clear_region(MemoryRegion *parent,
                                     MemoryRegion *mem)
{
    if (memory_region_is_mapped(mem)) {
        memory_region_del_subregion(parent, mem);
        object_unparent(OBJECT(mem));
    }
}

/* DMA mapping */
static void ppc440_pcix_update_pim(PPC440PCIXState *s, int idx)
{
    MemoryRegion *mem = &s->pim[idx].mr;
    char *name;
    uint64_t size;

    /* Before we modify anything, unmap and destroy the region */
    ppc440_pcix_clear_region(&s->bm, mem);

    if (!(s->pim[idx].sa & 1)) {
        /* Not enabled, nothing to do */
        return;
    }

    name = g_strdup_printf("PCI Inbound Window %d", idx);
    size = ~(s->pim[idx].sa & ~7ULL) + 1;
    memory_region_init_alias(mem, OBJECT(s), name, get_system_memory(),
                             s->pim[idx].la, size);
    memory_region_add_subregion_overlap(&s->bm, 0, mem, -1);
    g_free(name);

    trace_ppc440_pcix_update_pim(idx, size, s->pim[idx].la);
}

/* BAR mapping */
static void ppc440_pcix_update_pom(PPC440PCIXState *s, int idx)
{
    MemoryRegion *mem = &s->pom[idx].mr;
    MemoryRegion *address_space_mem = get_system_memory();
    char *name;
    uint32_t size;

    /* Before we modify anything, unmap and destroy the region */
    ppc440_pcix_clear_region(address_space_mem, mem);

    if (!(s->pom[idx].sa & 1)) {
        /* Not enabled, nothing to do */
        return;
    }

    name = g_strdup_printf("PCI Outbound Window %d", idx);
    size = ~(s->pom[idx].sa & 0xfffffffe) + 1;
    if (!size) {
        size = 0xffffffff;
    }
    memory_region_init_alias(mem, OBJECT(s), name, &s->busmem,
                             s->pom[idx].pcia, size);
    memory_region_add_subregion(address_space_mem, s->pom[idx].la, mem);
    g_free(name);

    trace_ppc440_pcix_update_pom(idx, size, s->pom[idx].la, s->pom[idx].pcia);
}

static void ppc440_pcix_reg_write4(void *opaque, hwaddr addr,
                                   uint64_t val, unsigned size)
{
    struct PPC440PCIXState *s = opaque;

    trace_ppc440_pcix_reg_write(addr, val, size);
    switch (addr) {
    case PCI_VENDOR_ID ... PCI_MAX_LAT:
        stl_le_p(s->dev->config + addr, val);
        break;

    case PCIX0_POM0LAL:
        s->pom[0].la &= 0xffffffff00000000ULL;
        s->pom[0].la |= val;
        ppc440_pcix_update_pom(s, 0);
        break;
    case PCIX0_POM0LAH:
        s->pom[0].la &= 0xffffffffULL;
        s->pom[0].la |= val << 32;
        ppc440_pcix_update_pom(s, 0);
        break;
    case PCIX0_POM0SA:
        s->pom[0].sa = val;
        ppc440_pcix_update_pom(s, 0);
        break;
    case PCIX0_POM0PCIAL:
        s->pom[0].pcia &= 0xffffffff00000000ULL;
        s->pom[0].pcia |= val;
        ppc440_pcix_update_pom(s, 0);
        break;
    case PCIX0_POM0PCIAH:
        s->pom[0].pcia &= 0xffffffffULL;
        s->pom[0].pcia |= val << 32;
        ppc440_pcix_update_pom(s, 0);
        break;
    case PCIX0_POM1LAL:
        s->pom[1].la &= 0xffffffff00000000ULL;
        s->pom[1].la |= val;
        ppc440_pcix_update_pom(s, 1);
        break;
    case PCIX0_POM1LAH:
        s->pom[1].la &= 0xffffffffULL;
        s->pom[1].la |= val << 32;
        ppc440_pcix_update_pom(s, 1);
        break;
    case PCIX0_POM1SA:
        s->pom[1].sa = val;
        ppc440_pcix_update_pom(s, 1);
        break;
    case PCIX0_POM1PCIAL:
        s->pom[1].pcia &= 0xffffffff00000000ULL;
        s->pom[1].pcia |= val;
        ppc440_pcix_update_pom(s, 1);
        break;
    case PCIX0_POM1PCIAH:
        s->pom[1].pcia &= 0xffffffffULL;
        s->pom[1].pcia |= val << 32;
        ppc440_pcix_update_pom(s, 1);
        break;
    case PCIX0_POM2SA:
        s->pom[2].sa = val;
        break;

    case PCIX0_PIM0SAL:
        s->pim[0].sa &= 0xffffffff00000000ULL;
        s->pim[0].sa |= val;
        ppc440_pcix_update_pim(s, 0);
        break;
    case PCIX0_PIM0LAL:
        s->pim[0].la &= 0xffffffff00000000ULL;
        s->pim[0].la |= val;
        ppc440_pcix_update_pim(s, 0);
        break;
    case PCIX0_PIM0LAH:
        s->pim[0].la &= 0xffffffffULL;
        s->pim[0].la |= val << 32;
        ppc440_pcix_update_pim(s, 0);
        break;
    case PCIX0_PIM1SA:
        s->pim[1].sa = val;
        ppc440_pcix_update_pim(s, 1);
        break;
    case PCIX0_PIM1LAL:
        s->pim[1].la &= 0xffffffff00000000ULL;
        s->pim[1].la |= val;
        ppc440_pcix_update_pim(s, 1);
        break;
    case PCIX0_PIM1LAH:
        s->pim[1].la &= 0xffffffffULL;
        s->pim[1].la |= val << 32;
        ppc440_pcix_update_pim(s, 1);
        break;
    case PCIX0_PIM2SAL:
        s->pim[2].sa &= 0xffffffff00000000ULL;
        s->pim[2].sa |= val;
        ppc440_pcix_update_pim(s, 2);
        break;
    case PCIX0_PIM2LAL:
        s->pim[2].la &= 0xffffffff00000000ULL;
        s->pim[2].la |= val;
        ppc440_pcix_update_pim(s, 2);
        break;
    case PCIX0_PIM2LAH:
        s->pim[2].la &= 0xffffffffULL;
        s->pim[2].la |= val << 32;
        ppc440_pcix_update_pim(s, 2);
        break;

    case PCIX0_STS:
        s->sts = val;
        break;

    case PCIX0_PIM0SAH:
        s->pim[0].sa &= 0xffffffffULL;
        s->pim[0].sa |= val << 32;
        ppc440_pcix_update_pim(s, 0);
        break;
    case PCIX0_PIM2SAH:
        s->pim[2].sa &= 0xffffffffULL;
        s->pim[2].sa |= val << 32;
        ppc440_pcix_update_pim(s, 2);
        break;

    default:
        qemu_log_mask(LOG_UNIMP,
                      "%s: unhandled PCI internal register 0x%"HWADDR_PRIx"\n",
                      __func__, addr);
        break;
    }
}

static uint64_t ppc440_pcix_reg_read4(void *opaque, hwaddr addr,
                                     unsigned size)
{
    struct PPC440PCIXState *s = opaque;
    uint32_t val;

    switch (addr) {
    case PCI_VENDOR_ID ... PCI_MAX_LAT:
        val = ldl_le_p(s->dev->config + addr);
        break;

    case PCIX0_POM0LAL:
        val = s->pom[0].la;
        break;
    case PCIX0_POM0LAH:
        val = s->pom[0].la >> 32;
        break;
    case PCIX0_POM0SA:
        val = s->pom[0].sa;
        break;
    case PCIX0_POM0PCIAL:
        val = s->pom[0].pcia;
        break;
    case PCIX0_POM0PCIAH:
        val = s->pom[0].pcia >> 32;
        break;
    case PCIX0_POM1LAL:
        val = s->pom[1].la;
        break;
    case PCIX0_POM1LAH:
        val = s->pom[1].la >> 32;
        break;
    case PCIX0_POM1SA:
        val = s->pom[1].sa;
        break;
    case PCIX0_POM1PCIAL:
        val = s->pom[1].pcia;
        break;
    case PCIX0_POM1PCIAH:
        val = s->pom[1].pcia >> 32;
        break;
    case PCIX0_POM2SA:
        val = s->pom[2].sa;
        break;

    case PCIX0_PIM0SAL:
        val = s->pim[0].sa;
        break;
    case PCIX0_PIM0LAL:
        val = s->pim[0].la;
        break;
    case PCIX0_PIM0LAH:
        val = s->pim[0].la >> 32;
        break;
    case PCIX0_PIM1SA:
        val = s->pim[1].sa;
        break;
    case PCIX0_PIM1LAL:
        val = s->pim[1].la;
        break;
    case PCIX0_PIM1LAH:
        val = s->pim[1].la >> 32;
        break;
    case PCIX0_PIM2SAL:
        val = s->pim[2].sa;
        break;
    case PCIX0_PIM2LAL:
        val = s->pim[2].la;
        break;
    case PCIX0_PIM2LAH:
        val = s->pim[2].la >> 32;
        break;

    case PCIX0_STS:
        val = s->sts;
        break;

    case PCIX0_PIM0SAH:
        val = s->pim[0].sa  >> 32;
        break;
    case PCIX0_PIM2SAH:
        val = s->pim[2].sa  >> 32;
        break;

    default:
        qemu_log_mask(LOG_UNIMP,
                      "%s: invalid PCI internal register 0x%" HWADDR_PRIx "\n",
                      __func__, addr);
        val = 0;
    }

    trace_ppc440_pcix_reg_read(addr, val);
    return val;
}

static const MemoryRegionOps pci_reg_ops = {
    .read = ppc440_pcix_reg_read4,
    .write = ppc440_pcix_reg_write4,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void ppc440_pcix_reset(DeviceState *dev)
{
    struct PPC440PCIXState *s = PPC440_PCIX_HOST(dev);
    int i;

    for (i = 0; i < PPC440_PCIX_NR_POMS; i++) {
        ppc440_pcix_clear_region(get_system_memory(), &s->pom[i].mr);
    }
    for (i = 0; i < PPC440_PCIX_NR_PIMS; i++) {
        ppc440_pcix_clear_region(&s->bm, &s->pim[i].mr);
    }
    memset(s->pom, 0, sizeof(s->pom));
    memset(s->pim, 0, sizeof(s->pim));
    for (i = 0; i < PPC440_PCIX_NR_PIMS; i++) {
        s->pim[i].sa = 0xffffffff00000000ULL;
    }
    s->sts = 0;
}

/*
 * All four IRQ[ABCD] pins from all slots are tied to a single board
 * IRQ, so our mapping function here maps everything to IRQ 0.
 * The code in pci_change_irq_level() tracks the number of times
 * the mapped IRQ is asserted and deasserted, so if multiple devices
 * assert an IRQ at the same time the behaviour is correct.
 *
 * This may need further refactoring for boards that use multiple IRQ lines.
 */
static int ppc440_pcix_map_irq(PCIDevice *pci_dev, int irq_num)
{
    trace_ppc440_pcix_map_irq(pci_dev->devfn, irq_num, 0);
    return 0;
}

static void ppc440_pcix_set_irq(void *opaque, int irq_num, int level)
{
    qemu_irq *pci_irq = opaque;

    trace_ppc440_pcix_set_irq(irq_num);
    if (irq_num < 0) {
        error_report("%s: PCI irq %d", __func__, irq_num);
        return;
    }
    qemu_set_irq(*pci_irq, level);
}

static AddressSpace *ppc440_pcix_set_iommu(PCIBus *b, void *opaque, int devfn)
{
    PPC440PCIXState *s = opaque;

    return &s->bm_as;
}

static const PCIIOMMUOps ppc440_iommu_ops = {
    .get_address_space = ppc440_pcix_set_iommu,
};

/*
 * Some guests on sam460ex write all kinds of garbage here such as
 * missing enable bit and low bits set and still expect this to work
 * (apparently it does on real hardware because these boot there) so
 * we have to override these ops here and fix it up
 */
static void pci_host_config_write(void *opaque, hwaddr addr,
                                  uint64_t val, unsigned len)
{
    PCIHostState *s = opaque;

    if (addr != 0 || len != 4) {
        return;
    }
    s->config_reg = (val & 0xfffffffcULL) | (1UL << 31);
}

static uint64_t pci_host_config_read(void *opaque, hwaddr addr,
                                     unsigned len)
{
    PCIHostState *s = opaque;
    uint32_t val = s->config_reg;

    return val;
}

const MemoryRegionOps ppc440_pcix_host_conf_ops = {
    .read = pci_host_config_read,
    .write = pci_host_config_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void ppc440_pcix_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    PPC440PCIXState *s;
    PCIHostState *h;

    h = PCI_HOST_BRIDGE(dev);
    s = PPC440_PCIX_HOST(dev);

    sysbus_init_irq(sbd, &s->irq);
    memory_region_init(&s->busmem, OBJECT(dev), "pci-mem", UINT64_MAX);
    memory_region_init(&s->iomem, OBJECT(dev), "pci-io", 64 * KiB);
    h->bus = pci_register_root_bus(dev, NULL, ppc440_pcix_set_irq,
                         ppc440_pcix_map_irq, &s->irq, &s->busmem, &s->iomem,
                         PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS);

    s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0),
                               TYPE_PPC4xx_HOST_BRIDGE);

    memory_region_init(&s->bm, OBJECT(s), "bm-ppc440-pcix", UINT64_MAX);
    memory_region_add_subregion(&s->bm, 0x0, &s->busmem);
    address_space_init(&s->bm_as, &s->bm, "pci-bm");
    pci_setup_iommu(h->bus, &ppc440_iommu_ops, s);

    memory_region_init(&s->container, OBJECT(s), "pci-container", PCI_ALL_SIZE);
    memory_region_init_io(&h->conf_mem, OBJECT(s), &ppc440_pcix_host_conf_ops,
                          h, "pci-conf-idx", 4);
    memory_region_init_io(&h->data_mem, OBJECT(s), &pci_host_data_le_ops,
                          h, "pci-conf-data", 4);
    memory_region_init_io(&s->regs, OBJECT(s), &pci_reg_ops, s, "pci-reg",
                          PPC440_REG_SIZE);
    memory_region_add_subregion(&s->container, PCIC0_CFGADDR, &h->conf_mem);
    memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem);
    memory_region_add_subregion(&s->container, PPC440_REG_BASE, &s->regs);
    sysbus_init_mmio(sbd, &s->container);
    sysbus_init_mmio(sbd, &s->iomem);
}

static void ppc440_pcix_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = ppc440_pcix_realize;
    dc->reset = ppc440_pcix_reset;
}

static const TypeInfo ppc440_pcix_info = {
    .name          = TYPE_PPC440_PCIX_HOST,
    .parent        = TYPE_PCI_HOST_BRIDGE,
    .instance_size = sizeof(PPC440PCIXState),
    .class_init    = ppc440_pcix_class_init,
};

static void ppc440_pcix_register_types(void)
{
    type_register_static(&ppc440_pcix_info);
}

type_init(ppc440_pcix_register_types)
