/*
 * QEMU RS/6000 memory controller
 *
 * Copyright (c) 2017 Hervé Poussineau
 *
 * 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) version 3 or 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/units.h"
#include "hw/isa/isa.h"
#include "exec/address-spaces.h"
#include "hw/boards.h"
#include "qapi/error.h"
#include "trace.h"

#define TYPE_RS6000MC "rs6000-mc"
#define RS6000MC_DEVICE(obj) \
    OBJECT_CHECK(RS6000MCState, (obj), TYPE_RS6000MC)

typedef struct RS6000MCState {
    ISADevice parent_obj;
    /* see US patent 5,684,979 for details (expired 2001-11-04) */
    uint32_t ram_size;
    bool autoconfigure;
    MemoryRegion simm[6];
    unsigned int simm_size[6];
    uint32_t end_address[8];
    uint8_t port0820_index;
    PortioList portio;
} RS6000MCState;

/* P0RT 0803 -- SIMM ID Register (32/8 MB) (Read Only) */

static uint32_t rs6000mc_port0803_read(void *opaque, uint32_t addr)
{
    RS6000MCState *s = opaque;
    uint32_t val = 0;
    int socket;

    /* (1 << socket) indicates 32 MB SIMM at given socket */
    for (socket = 0; socket < 6; socket++) {
        if (s->simm_size[socket] == 32) {
            val |= (1 << socket);
        }
    }

    trace_rs6000mc_id_read(addr, val);
    return val;
}

/* PORT 0804 -- SIMM Presence Register (Read Only) */

static uint32_t rs6000mc_port0804_read(void *opaque, uint32_t addr)
{
    RS6000MCState *s = opaque;
    uint32_t val = 0xff;
    int socket;

    /* (1 << socket) indicates SIMM absence at given socket */
    for (socket = 0; socket < 6; socket++) {
        if (s->simm_size[socket]) {
            val &= ~(1 << socket);
        }
    }
    s->port0820_index = 0;

    trace_rs6000mc_presence_read(addr, val);
    return val;
}

/* Memory Controller Size Programming Register */

static uint32_t rs6000mc_port0820_read(void *opaque, uint32_t addr)
{
    RS6000MCState *s = opaque;
    uint32_t val = s->end_address[s->port0820_index] & 0x1f;
    s->port0820_index = (s->port0820_index + 1) & 7;
    trace_rs6000mc_size_read(addr, val);
    return val;
}

static void rs6000mc_port0820_write(void *opaque, uint32_t addr, uint32_t val)
{
    RS6000MCState *s = opaque;
    uint8_t socket = val >> 5;
    uint32_t end_address = val & 0x1f;

    trace_rs6000mc_size_write(addr, val);
    s->end_address[socket] = end_address;
    if (socket > 0 && socket < 7) {
        if (s->simm_size[socket - 1]) {
            uint32_t size;
            uint32_t start_address = 0;
            if (socket > 1) {
                start_address = s->end_address[socket - 1];
            }

            size = end_address - start_address;
            memory_region_set_enabled(&s->simm[socket - 1], size != 0);
            memory_region_set_address(&s->simm[socket - 1],
                                      start_address * 8 * MiB);
        }
    }
}

/* Read Memory Parity Error */

enum {
    PORT0841_NO_ERROR_DETECTED = 0x01,
};

static uint32_t rs6000mc_port0841_read(void *opaque, uint32_t addr)
{
    uint32_t val = PORT0841_NO_ERROR_DETECTED;
    trace_rs6000mc_parity_read(addr, val);
    return val;
}

static const MemoryRegionPortio rs6000mc_port_list[] = {
    { 0x803, 1, 1, .read = rs6000mc_port0803_read },
    { 0x804, 1, 1, .read = rs6000mc_port0804_read },
    { 0x820, 1, 1, .read = rs6000mc_port0820_read,
                   .write = rs6000mc_port0820_write, },
    { 0x841, 1, 1, .read = rs6000mc_port0841_read },
    PORTIO_END_OF_LIST()
};

static void rs6000mc_realize(DeviceState *dev, Error **errp)
{
    RS6000MCState *s = RS6000MC_DEVICE(dev);
    int socket = 0;
    unsigned int ram_size = s->ram_size / MiB;

    while (socket < 6) {
        if (ram_size >= 64) {
            s->simm_size[socket] = 32;
            s->simm_size[socket + 1] = 32;
            ram_size -= 64;
        } else if (ram_size >= 16) {
            s->simm_size[socket] = 8;
            s->simm_size[socket + 1] = 8;
            ram_size -= 16;
        } else {
            /* Not enough memory */
            break;
        }
        socket += 2;
    }

    for (socket = 0; socket < 6; socket++) {
        if (s->simm_size[socket]) {
            char name[] = "simm.?";
            name[5] = socket + '0';
            memory_region_allocate_system_memory(&s->simm[socket], OBJECT(dev),
                                                 name,
                                                 s->simm_size[socket] * MiB);
            memory_region_add_subregion_overlap(get_system_memory(), 0,
                                                &s->simm[socket], socket);
        }
    }
    if (ram_size) {
        /* unable to push all requested RAM in SIMMs */
        error_setg(errp, "RAM size incompatible with this board. "
                   "Try again with something else, like %" PRId64 " MB",
                   s->ram_size / MiB - ram_size);
        return;
    }

    if (s->autoconfigure) {
        uint32_t start_address = 0;
        for (socket = 0; socket < 6; socket++) {
            if (s->simm_size[socket]) {
                memory_region_set_enabled(&s->simm[socket], true);
                memory_region_set_address(&s->simm[socket], start_address);
                start_address += memory_region_size(&s->simm[socket]);
            }
        }
    }

    isa_register_portio_list(ISA_DEVICE(dev), &s->portio, 0x0,
                             rs6000mc_port_list, s, "rs6000mc");
}

static const VMStateDescription vmstate_rs6000mc = {
    .name = "rs6000-mc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(port0820_index, RS6000MCState),
        VMSTATE_END_OF_LIST()
    },
};

static Property rs6000mc_properties[] = {
    DEFINE_PROP_UINT32("ram-size", RS6000MCState, ram_size, 0),
    DEFINE_PROP_BOOL("auto-configure", RS6000MCState, autoconfigure, true),
    DEFINE_PROP_END_OF_LIST()
};

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

    dc->realize = rs6000mc_realize;
    dc->vmsd = &vmstate_rs6000mc;
    dc->props = rs6000mc_properties;
}

static const TypeInfo rs6000mc_info = {
    .name          = TYPE_RS6000MC,
    .parent        = TYPE_ISA_DEVICE,
    .instance_size = sizeof(RS6000MCState),
    .class_init    = rs6000mc_class_initfn,
};

static void rs6000mc_types(void)
{
    type_register_static(&rs6000mc_info);
}

type_init(rs6000mc_types)
