/*
 * GRLIB AHB APB PNP
 *
 *  Copyright (C) 2019 AdaCore
 *
 *  Developed by :
 *  Frederic Konrad   <frederic.konrad@adacore.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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/log.h"
#include "hw/sysbus.h"
#include "hw/misc/grlib_ahb_apb_pnp.h"
#include "trace.h"

#define GRLIB_PNP_VENDOR_SHIFT (24)
#define GRLIB_PNP_VENDOR_SIZE   (8)
#define GRLIB_PNP_DEV_SHIFT    (12)
#define GRLIB_PNP_DEV_SIZE     (12)
#define GRLIB_PNP_VER_SHIFT     (5)
#define GRLIB_PNP_VER_SIZE      (5)
#define GRLIB_PNP_IRQ_SHIFT     (0)
#define GRLIB_PNP_IRQ_SIZE      (5)
#define GRLIB_PNP_ADDR_SHIFT   (20)
#define GRLIB_PNP_ADDR_SIZE    (12)
#define GRLIB_PNP_MASK_SHIFT    (4)
#define GRLIB_PNP_MASK_SIZE    (12)

#define GRLIB_AHB_DEV_ADDR_SHIFT   (20)
#define GRLIB_AHB_DEV_ADDR_SIZE    (12)
#define GRLIB_AHB_ENTRY_SIZE       (0x20)
#define GRLIB_AHB_MAX_DEV          (64)
#define GRLIB_AHB_SLAVE_OFFSET     (0x800)

#define GRLIB_APB_DEV_ADDR_SHIFT   (8)
#define GRLIB_APB_DEV_ADDR_SIZE    (12)
#define GRLIB_APB_ENTRY_SIZE       (0x08)
#define GRLIB_APB_MAX_DEV          (512)

#define GRLIB_PNP_MAX_REGS         (0x1000)

typedef struct AHBPnp {
    SysBusDevice parent_obj;
    MemoryRegion iomem;

    uint32_t regs[GRLIB_PNP_MAX_REGS >> 2];
    uint8_t master_count;
    uint8_t slave_count;
} AHBPnp;

void grlib_ahb_pnp_add_entry(AHBPnp *dev, uint32_t address, uint32_t mask,
                             uint8_t vendor, uint16_t device, int slave,
                             int type)
{
    unsigned int reg_start;

    /*
     * AHB entries look like this:
     *
     * 31 -------- 23 -------- 11 ----- 9 -------- 4 --- 0
     *  | VENDOR ID | DEVICE ID | IRQ ? | VERSION  | IRQ |
     *  --------------------------------------------------
     *  |                      USER                      |
     *  --------------------------------------------------
     *  |                      USER                      |
     *  --------------------------------------------------
     *  |                      USER                      |
     *  --------------------------------------------------
     *  |                      USER                      |
     *  --------------------------------------------------
     * 31 ----------- 20 --- 15 ----------------- 3 ---- 0
     *  | ADDR[31..12] | 00PC |        MASK       | TYPE |
     *  --------------------------------------------------
     * 31 ----------- 20 --- 15 ----------------- 3 ---- 0
     *  | ADDR[31..12] | 00PC |        MASK       | TYPE |
     *  --------------------------------------------------
     * 31 ----------- 20 --- 15 ----------------- 3 ---- 0
     *  | ADDR[31..12] | 00PC |        MASK       | TYPE |
     *  --------------------------------------------------
     * 31 ----------- 20 --- 15 ----------------- 3 ---- 0
     *  | ADDR[31..12] | 00PC |        MASK       | TYPE |
     *  --------------------------------------------------
     */

    if (slave) {
        assert(dev->slave_count < GRLIB_AHB_MAX_DEV);
        reg_start = (GRLIB_AHB_SLAVE_OFFSET
                  + (dev->slave_count * GRLIB_AHB_ENTRY_SIZE)) >> 2;
        dev->slave_count++;
    } else {
        assert(dev->master_count < GRLIB_AHB_MAX_DEV);
        reg_start = (dev->master_count * GRLIB_AHB_ENTRY_SIZE) >> 2;
        dev->master_count++;
    }

    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_VENDOR_SHIFT,
                                     GRLIB_PNP_VENDOR_SIZE,
                                     vendor);
    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_DEV_SHIFT,
                                     GRLIB_PNP_DEV_SIZE,
                                     device);
    reg_start += 4;
    /* AHB Memory Space */
    dev->regs[reg_start] = type;
    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_ADDR_SHIFT,
                                     GRLIB_PNP_ADDR_SIZE,
                                     extract32(address,
                                               GRLIB_AHB_DEV_ADDR_SHIFT,
                                               GRLIB_AHB_DEV_ADDR_SIZE));
    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_MASK_SHIFT,
                                     GRLIB_PNP_MASK_SIZE,
                                     mask);
}

static uint64_t grlib_ahb_pnp_read(void *opaque, hwaddr offset, unsigned size)
{
    AHBPnp *ahb_pnp = GRLIB_AHB_PNP(opaque);
    uint32_t val;

    val = ahb_pnp->regs[offset >> 2];
    trace_grlib_ahb_pnp_read(offset, val);

    return val;
}

static void grlib_ahb_pnp_write(void *opaque, hwaddr addr,
                                uint64_t val, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__);
}

static const MemoryRegionOps grlib_ahb_pnp_ops = {
    .read       = grlib_ahb_pnp_read,
    .write      = grlib_ahb_pnp_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void grlib_ahb_pnp_realize(DeviceState *dev, Error **errp)
{
    AHBPnp *ahb_pnp = GRLIB_AHB_PNP(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    memory_region_init_io(&ahb_pnp->iomem, OBJECT(dev), &grlib_ahb_pnp_ops,
                          ahb_pnp, TYPE_GRLIB_AHB_PNP, GRLIB_PNP_MAX_REGS);
    sysbus_init_mmio(sbd, &ahb_pnp->iomem);
}

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

    dc->realize = grlib_ahb_pnp_realize;
}

static const TypeInfo grlib_ahb_pnp_info = {
    .name          = TYPE_GRLIB_AHB_PNP,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(AHBPnp),
    .class_init    = grlib_ahb_pnp_class_init,
};

/* APBPnp */

typedef struct APBPnp {
    SysBusDevice parent_obj;
    MemoryRegion iomem;

    uint32_t regs[GRLIB_PNP_MAX_REGS >> 2];
    uint32_t entry_count;
} APBPnp;

void grlib_apb_pnp_add_entry(APBPnp *dev, uint32_t address, uint32_t mask,
                             uint8_t vendor, uint16_t device, uint8_t version,
                             uint8_t irq, int type)
{
    unsigned int reg_start;

    /*
     * APB entries look like this:
     *
     * 31 -------- 23 -------- 11 ----- 9 ------- 4 --- 0
     *  | VENDOR ID | DEVICE ID | IRQ ? | VERSION | IRQ |
     *
     * 31 ---------- 20 --- 15 ----------------- 3 ---- 0
     *  | ADDR[20..8] | 0000 |        MASK       | TYPE |
     */

    assert(dev->entry_count < GRLIB_APB_MAX_DEV);
    reg_start = (dev->entry_count * GRLIB_APB_ENTRY_SIZE) >> 2;
    dev->entry_count++;

    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_VENDOR_SHIFT,
                                     GRLIB_PNP_VENDOR_SIZE,
                                     vendor);
    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_DEV_SHIFT,
                                     GRLIB_PNP_DEV_SIZE,
                                     device);
    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_VER_SHIFT,
                                     GRLIB_PNP_VER_SIZE,
                                     version);
    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_IRQ_SHIFT,
                                     GRLIB_PNP_IRQ_SIZE,
                                     irq);
    reg_start += 1;
    dev->regs[reg_start] = type;
    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_ADDR_SHIFT,
                                     GRLIB_PNP_ADDR_SIZE,
                                     extract32(address,
                                               GRLIB_APB_DEV_ADDR_SHIFT,
                                               GRLIB_APB_DEV_ADDR_SIZE));
    dev->regs[reg_start] = deposit32(dev->regs[reg_start],
                                     GRLIB_PNP_MASK_SHIFT,
                                     GRLIB_PNP_MASK_SIZE,
                                     mask);
}

static uint64_t grlib_apb_pnp_read(void *opaque, hwaddr offset, unsigned size)
{
    APBPnp *apb_pnp = GRLIB_APB_PNP(opaque);
    uint32_t val;

    val = apb_pnp->regs[offset >> 2];
    trace_grlib_apb_pnp_read(offset, val);

    return val;
}

static void grlib_apb_pnp_write(void *opaque, hwaddr addr,
                                uint64_t val, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__);
}

static const MemoryRegionOps grlib_apb_pnp_ops = {
    .read       = grlib_apb_pnp_read,
    .write      = grlib_apb_pnp_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void grlib_apb_pnp_realize(DeviceState *dev, Error **errp)
{
    APBPnp *apb_pnp = GRLIB_APB_PNP(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    memory_region_init_io(&apb_pnp->iomem, OBJECT(dev), &grlib_apb_pnp_ops,
                          apb_pnp, TYPE_GRLIB_APB_PNP, GRLIB_PNP_MAX_REGS);
    sysbus_init_mmio(sbd, &apb_pnp->iomem);
}

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

    dc->realize = grlib_apb_pnp_realize;
}

static const TypeInfo grlib_apb_pnp_info = {
    .name          = TYPE_GRLIB_APB_PNP,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(APBPnp),
    .class_init    = grlib_apb_pnp_class_init,
};

static void grlib_ahb_apb_pnp_register_types(void)
{
    type_register_static(&grlib_ahb_pnp_info);
    type_register_static(&grlib_apb_pnp_info);
}

type_init(grlib_ahb_apb_pnp_register_types)
