/*
 * 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 "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 * 1024 * 1024);
        }
    }
}

/* 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 / (1024 * 1024);

    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]
                                                 * 1024 * 1024);
            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 %d MB",
                   s->ram_size / 1024 / 1024 - 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)
