/*
 * QEMU Ultrasparc Sabre PCI host (PBM)
 *
 * Copyright (c) 2006 Fabrice Bellard
 * Copyright (c) 2012,2013 Artyom Tarasenko
 * Copyright (c) 2018 Mark Cave-Ayland
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
#include "hw/qdev-properties.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h"
#include "hw/irq.h"
#include "hw/pci-bridge/simba.h"
#include "hw/pci-host/sabre.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "sysemu/runstate.h"
#include "trace.h"

/*
 * Chipset docs:
 * PBM: "UltraSPARC IIi User's Manual",
 * https://web.archive.org/web/20030403110020/http://www.sun.com/processors/manuals/805-0087.pdf
 */

#define PBM_PCI_IMR_MASK    0x7fffffff
#define PBM_PCI_IMR_ENABLED 0x80000000

#define POR          (1U << 31)
#define SOFT_POR     (1U << 30)
#define SOFT_XIR     (1U << 29)
#define BTN_POR      (1U << 28)
#define BTN_XIR      (1U << 27)
#define RESET_MASK   0xf8000000
#define RESET_WCMASK 0x98000000
#define RESET_WMASK  0x60000000

#define NO_IRQ_REQUEST (MAX_IVEC + 1)

static inline void sabre_set_request(SabreState *s, unsigned int irq_num)
{
    trace_sabre_set_request(irq_num);
    s->irq_request = irq_num;
    qemu_set_irq(s->ivec_irqs[irq_num], 1);
}

static inline void sabre_check_irqs(SabreState *s)
{
    unsigned int i;

    /* Previous request is not acknowledged, resubmit */
    if (s->irq_request != NO_IRQ_REQUEST) {
        sabre_set_request(s, s->irq_request);
        return;
    }
    /* no request pending */
    if (s->pci_irq_in == 0ULL) {
        return;
    }
    for (i = 0; i < 32; i++) {
        if (s->pci_irq_in & (1ULL << i)) {
            if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
                sabre_set_request(s, i);
                return;
            }
        }
    }
    for (i = 32; i < 64; i++) {
        if (s->pci_irq_in & (1ULL << i)) {
            if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
                sabre_set_request(s, i);
                break;
            }
        }
    }
}

static inline void sabre_clear_request(SabreState *s, unsigned int irq_num)
{
    trace_sabre_clear_request(irq_num);
    qemu_set_irq(s->ivec_irqs[irq_num], 0);
    s->irq_request = NO_IRQ_REQUEST;
}

static AddressSpace *sabre_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
{
    IOMMUState *is = opaque;

    return &is->iommu_as;
}

static const PCIIOMMUOps sabre_iommu_ops = {
    .get_address_space = sabre_pci_dma_iommu,
};

static void sabre_config_write(void *opaque, hwaddr addr,
                               uint64_t val, unsigned size)
{
    SabreState *s = opaque;

    trace_sabre_config_write(addr, val);

    switch (addr) {
    case 0x30 ... 0x4f: /* DMA error registers */
        /* XXX: not implemented yet */
        break;
    case 0xc00 ... 0xc3f: /* PCI interrupt control */
        if (addr & 4) {
            unsigned int ino = (addr & 0x3f) >> 3;
            s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
            s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
            if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
                sabre_clear_request(s, ino);
            }
            sabre_check_irqs(s);
        }
        break;
    case 0x1000 ... 0x107f: /* OBIO interrupt control */
        if (addr & 4) {
            unsigned int ino = ((addr & 0xff) >> 3);
            s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
            s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
            if ((s->irq_request == (ino | 0x20))
                 && !(val & ~PBM_PCI_IMR_MASK)) {
                sabre_clear_request(s, ino | 0x20);
            }
            sabre_check_irqs(s);
        }
        break;
    case 0x1400 ... 0x14ff: /* PCI interrupt clear */
        if (addr & 4) {
            unsigned int ino = (addr & 0xff) >> 5;
            if ((s->irq_request / 4)  == ino) {
                sabre_clear_request(s, s->irq_request);
                sabre_check_irqs(s);
            }
        }
        break;
    case 0x1800 ... 0x1860: /* OBIO interrupt clear */
        if (addr & 4) {
            unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
            if (s->irq_request == ino) {
                sabre_clear_request(s, ino);
                sabre_check_irqs(s);
            }
        }
        break;
    case 0x2000 ... 0x202f: /* PCI control */
        s->pci_control[(addr & 0x3f) >> 2] = val;
        break;
    case 0xf020 ... 0xf027: /* Reset control */
        if (addr & 4) {
            val &= RESET_MASK;
            s->reset_control &= ~(val & RESET_WCMASK);
            s->reset_control |= val & RESET_WMASK;
            if (val & SOFT_POR) {
                s->nr_resets = 0;
                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
            } else if (val & SOFT_XIR) {
                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
            }
        }
        break;
    case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
    case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
    case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
    case 0xf000 ... 0xf01f: /* FFB config, memory control */
        /* we don't care */
    default:
        break;
    }
}

static uint64_t sabre_config_read(void *opaque,
                                  hwaddr addr, unsigned size)
{
    SabreState *s = opaque;
    uint32_t val = 0;

    switch (addr) {
    case 0x30 ... 0x4f: /* DMA error registers */
        /* XXX: not implemented yet */
        break;
    case 0xc00 ... 0xc3f: /* PCI interrupt control */
        if (addr & 4) {
            val = s->pci_irq_map[(addr & 0x3f) >> 3];
        }
        break;
    case 0x1000 ... 0x107f: /* OBIO interrupt control */
        if (addr & 4) {
            val = s->obio_irq_map[(addr & 0xff) >> 3];
        }
        break;
    case 0x1080 ... 0x108f: /* PCI bus error */
        if (addr & 4) {
            val = s->pci_err_irq_map[(addr & 0xf) >> 3];
        }
        break;
    case 0x2000 ... 0x202f: /* PCI control */
        val = s->pci_control[(addr & 0x3f) >> 2];
        break;
    case 0xf020 ... 0xf027: /* Reset control */
        if (addr & 4) {
            val = s->reset_control;
        }
        break;
    case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
    case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
    case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
    case 0xf000 ... 0xf01f: /* FFB config, memory control */
        /* we don't care */
    default:
        break;
    }
    trace_sabre_config_read(addr, val);

    return val;
}

static const MemoryRegionOps sabre_config_ops = {
    .read = sabre_config_read,
    .write = sabre_config_write,
    .endianness = DEVICE_BIG_ENDIAN,
};

static void sabre_pci_config_write(void *opaque, hwaddr addr,
                                   uint64_t val, unsigned size)
{
    SabreState *s = opaque;
    PCIHostState *phb = PCI_HOST_BRIDGE(s);

    trace_sabre_pci_config_write(addr, val);
    pci_data_write(phb->bus, addr, val, size);
}

static uint64_t sabre_pci_config_read(void *opaque, hwaddr addr,
                                      unsigned size)
{
    uint32_t ret;
    SabreState *s = opaque;
    PCIHostState *phb = PCI_HOST_BRIDGE(s);

    ret = pci_data_read(phb->bus, addr, size);
    trace_sabre_pci_config_read(addr, ret);
    return ret;
}

/* The sabre host has an IRQ line for each IRQ line of each slot.  */
static int pci_sabre_map_irq(PCIDevice *pci_dev, int irq_num)
{
    /* Return the irq as swizzled by the PBM */
    return irq_num;
}

static int pci_simbaA_map_irq(PCIDevice *pci_dev, int irq_num)
{
    /* The on-board devices have fixed (legacy) OBIO intnos */
    switch (PCI_SLOT(pci_dev->devfn)) {
    case 1:
        /* Onboard NIC */
        return OBIO_NIC_IRQ;
    case 3:
        /* Onboard IDE */
        return OBIO_HDD_IRQ;
    default:
        /* Normal intno, fall through */
        break;
    }

    return ((PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
}

static int pci_simbaB_map_irq(PCIDevice *pci_dev, int irq_num)
{
    return (0x10 + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
}

static void pci_sabre_set_irq(void *opaque, int irq_num, int level)
{
    SabreState *s = opaque;

    trace_sabre_pci_set_irq(irq_num, level);

    /* PCI IRQ map onto the first 32 INO.  */
    if (irq_num < 32) {
        if (level) {
            s->pci_irq_in |= 1ULL << irq_num;
            if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
                sabre_set_request(s, irq_num);
            }
        } else {
            s->pci_irq_in &= ~(1ULL << irq_num);
        }
    } else {
        /* OBIO IRQ map onto the next 32 INO.  */
        if (level) {
            trace_sabre_pci_set_obio_irq(irq_num, level);
            s->pci_irq_in |= 1ULL << irq_num;
            if ((s->irq_request == NO_IRQ_REQUEST)
                && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
                sabre_set_request(s, irq_num);
            }
        } else {
            s->pci_irq_in &= ~(1ULL << irq_num);
        }
    }
}

static void sabre_reset(DeviceState *d)
{
    SabreState *s = SABRE(d);
    PCIDevice *pci_dev;
    unsigned int i;
    uint16_t cmd;

    for (i = 0; i < 8; i++) {
        s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
    }
    for (i = 0; i < 32; i++) {
        s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
    }

    s->irq_request = NO_IRQ_REQUEST;
    s->pci_irq_in = 0ULL;

    if (s->nr_resets++ == 0) {
        /* Power on reset */
        s->reset_control = POR;
    }

    /* As this is the busA PCI bridge which contains the on-board devices
     * attached to the ebus, ensure that we initially allow IO transactions
     * so that we get the early serial console until OpenBIOS can properly
     * configure the PCI bridge itself */
    pci_dev = PCI_DEVICE(s->bridgeA);
    cmd = pci_get_word(pci_dev->config + PCI_COMMAND);
    pci_set_word(pci_dev->config + PCI_COMMAND, cmd | PCI_COMMAND_IO);
    pci_bridge_update_mappings(PCI_BRIDGE(pci_dev));
}

static const MemoryRegionOps pci_config_ops = {
    .read = sabre_pci_config_read,
    .write = sabre_pci_config_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void sabre_realize(DeviceState *dev, Error **errp)
{
    SabreState *s = SABRE(dev);
    PCIHostState *phb = PCI_HOST_BRIDGE(dev);
    PCIDevice *pci_dev;

    memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
    memory_region_add_subregion(get_system_memory(), s->mem_base,
                                &s->pci_mmio);

    phb->bus = pci_register_root_bus(dev, "pci",
                                     pci_sabre_set_irq, pci_sabre_map_irq, s,
                                     &s->pci_mmio,
                                     &s->pci_ioport,
                                     0, 0x40, TYPE_PCI_BUS);

    pci_create_simple(phb->bus, 0, TYPE_SABRE_PCI_DEVICE);

    /* IOMMU */
    memory_region_add_subregion_overlap(&s->sabre_config, 0x200,
                    sysbus_mmio_get_region(SYS_BUS_DEVICE(s->iommu), 0), 1);
    pci_setup_iommu(phb->bus, &sabre_iommu_ops, s->iommu);

    /* APB secondary busses */
    pci_dev = pci_new_multifunction(PCI_DEVFN(1, 0), TYPE_SIMBA_PCI_BRIDGE);
    s->bridgeB = PCI_BRIDGE(pci_dev);
    pci_bridge_map_irq(s->bridgeB, "pciB", pci_simbaB_map_irq);
    pci_realize_and_unref(pci_dev, phb->bus, &error_fatal);

    pci_dev = pci_new_multifunction(PCI_DEVFN(1, 1), TYPE_SIMBA_PCI_BRIDGE);
    s->bridgeA = PCI_BRIDGE(pci_dev);
    pci_bridge_map_irq(s->bridgeA, "pciA", pci_simbaA_map_irq);
    pci_realize_and_unref(pci_dev, phb->bus, &error_fatal);
}

static void sabre_init(Object *obj)
{
    SabreState *s = SABRE(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    unsigned int i;

    for (i = 0; i < 8; i++) {
        s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
    }
    for (i = 0; i < 2; i++) {
        s->pci_err_irq_map[i] = (0x1f << 6) | 0x30;
    }
    for (i = 0; i < 32; i++) {
        s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
    }
    qdev_init_gpio_in_named(DEVICE(s), pci_sabre_set_irq, "pbm-irq", MAX_IVEC);
    qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
    s->irq_request = NO_IRQ_REQUEST;
    s->pci_irq_in = 0ULL;

    /* IOMMU */
    object_property_add_link(obj, "iommu", TYPE_SUN4U_IOMMU,
                             (Object **) &s->iommu,
                             qdev_prop_allow_set_link_before_realize,
                             0);

    /* sabre_config */
    memory_region_init_io(&s->sabre_config, OBJECT(s), &sabre_config_ops, s,
                          "sabre-config", 0x10000);
    /* at region 0 */
    sysbus_init_mmio(sbd, &s->sabre_config);

    memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
                          "sabre-pci-config", 0x1000000);
    /* at region 1 */
    sysbus_init_mmio(sbd, &s->pci_config);

    /* pci_ioport */
    memory_region_init(&s->pci_ioport, OBJECT(s), "sabre-pci-ioport",
                       0x1000000);

    /* at region 2 */
    sysbus_init_mmio(sbd, &s->pci_ioport);
}

static void sabre_pci_realize(PCIDevice *d, Error **errp)
{
    pci_set_word(d->config + PCI_COMMAND,
                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
    pci_set_word(d->config + PCI_STATUS,
                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
                 PCI_STATUS_DEVSEL_MEDIUM);
}

static void sabre_pci_class_init(ObjectClass *klass, void *data)
{
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    k->realize = sabre_pci_realize;
    k->vendor_id = PCI_VENDOR_ID_SUN;
    k->device_id = PCI_DEVICE_ID_SUN_SABRE;
    k->class_id = PCI_CLASS_BRIDGE_HOST;
    /*
     * PCI-facing part of the host bridge, not usable without the
     * host-facing part, which can't be device_add'ed, yet.
     */
    dc->user_creatable = false;
}

static const TypeInfo sabre_pci_info = {
    .name          = TYPE_SABRE_PCI_DEVICE,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(SabrePCIState),
    .class_init    = sabre_pci_class_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static char *sabre_ofw_unit_address(const SysBusDevice *dev)
{
    SabreState *s = SABRE(dev);

    return g_strdup_printf("%x,%x",
               (uint32_t)((s->special_base >> 32) & 0xffffffff),
               (uint32_t)(s->special_base & 0xffffffff));
}

static Property sabre_properties[] = {
    DEFINE_PROP_UINT64("special-base", SabreState, special_base, 0),
    DEFINE_PROP_UINT64("mem-base", SabreState, mem_base, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void sabre_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);

    dc->realize = sabre_realize;
    dc->reset = sabre_reset;
    device_class_set_props(dc, sabre_properties);
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    dc->fw_name = "pci";
    sbc->explicit_ofw_unit_address = sabre_ofw_unit_address;
}

static const TypeInfo sabre_info = {
    .name          = TYPE_SABRE,
    .parent        = TYPE_PCI_HOST_BRIDGE,
    .instance_size = sizeof(SabreState),
    .instance_init = sabre_init,
    .class_init    = sabre_class_init,
};

static void sabre_register_types(void)
{
    type_register_static(&sabre_info);
    type_register_static(&sabre_pci_info);
}

type_init(sabre_register_types)
