/*
 * QEMU RS/6000 memory controller
 *
 * Copyright (c) 2017 Hervé Poussineau
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * 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/units.h"
#include "hw/isa/isa.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "exec/address-spaces.h"
#include "qapi/error.h"
#include "trace.h"
#include "qom/object.h"

#define TYPE_RS6000MC "rs6000-mc"
OBJECT_DECLARE_SIMPLE_TYPE(RS6000MCState, RS6000MC)

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;
};

/* 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(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';
            if (!memory_region_init_ram(&s->simm[socket], OBJECT(dev), name,
                                        s->simm_size[socket] * MiB, errp)) {
                return;
            }
            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 = (const 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;
    device_class_set_props(dc, 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)
