/*
 * QEMU PowerPC 405 evaluation boards emulation
 *
 * Copyright (c) 2007 Jocelyn Mayer
 *
 * 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 "qemu/units.h"
#include "qapi/error.h"
#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/ppc/ppc.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "ppc405.h"
#include "hw/rtc/m48t59.h"
#include "hw/block/flash.h"
#include "sysemu/qtest.h"
#include "sysemu/reset.h"
#include "sysemu/block-backend.h"
#include "hw/boards.h"
#include "qemu/error-report.h"
#include "hw/loader.h"
#include "qemu/cutils.h"
#include "elf.h"

#define BIOS_FILENAME "ppc405_rom.bin"
#define BIOS_SIZE (2 * MiB)

#define KERNEL_LOAD_ADDR 0x01000000
#define INITRD_LOAD_ADDR 0x01800000

#define PPC405EP_SDRAM_BASE 0x00000000
#define PPC405EP_SRAM_BASE  0xFFF00000
#define PPC405EP_SRAM_SIZE  (512 * KiB)

#define USE_FLASH_BIOS

#define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE);

struct Ppc405MachineState {
    /* Private */
    MachineState parent_obj;
    /* Public */

    Ppc405SoCState soc;
};

/* CPU reset handler when booting directly from a loaded kernel */
static struct boot_info {
    uint32_t entry;
    uint32_t bdloc;
    uint32_t initrd_base;
    uint32_t initrd_size;
    uint32_t cmdline_base;
    uint32_t cmdline_size;
} boot_info;

static void main_cpu_reset(void *opaque)
{
    PowerPCCPU *cpu = opaque;
    CPUPPCState *env = &cpu->env;
    struct boot_info *bi = env->load_info;

    cpu_reset(CPU(cpu));

    /* stack: top of sram */
    env->gpr[1] = PPC405EP_SRAM_BASE + PPC405EP_SRAM_SIZE - 8;

    /* Tune our boot state */
    env->gpr[3] = bi->bdloc;
    env->gpr[4] = bi->initrd_base;
    env->gpr[5] = bi->initrd_base + bi->initrd_size;
    env->gpr[6] = bi->cmdline_base;
    env->gpr[7] = bi->cmdline_size;

    env->nip = bi->entry;
}

/* Bootinfo as set-up by u-boot */
typedef struct {
    uint32_t bi_memstart;
    uint32_t bi_memsize;
    uint32_t bi_flashstart;
    uint32_t bi_flashsize;
    uint32_t bi_flashoffset; /* 0x10 */
    uint32_t bi_sramstart;
    uint32_t bi_sramsize;
    uint32_t bi_bootflags;
    uint32_t bi_ipaddr; /* 0x20 */
    uint8_t  bi_enetaddr[6];
    uint16_t bi_ethspeed;
    uint32_t bi_intfreq;
    uint32_t bi_busfreq; /* 0x30 */
    uint32_t bi_baudrate;
    uint8_t  bi_s_version[4];
    uint8_t  bi_r_version[32];
    uint32_t bi_procfreq;
    uint32_t bi_plb_busfreq;
    uint32_t bi_pci_busfreq;
    uint8_t  bi_pci_enetaddr[6];
    uint8_t  bi_pci_enetaddr2[6]; /* PPC405EP specific */
    uint32_t bi_opbfreq;
    uint32_t bi_iic_fast[2];
} ppc4xx_bd_info_t;

static void ppc405_set_default_bootinfo(ppc4xx_bd_info_t *bd,
                                        ram_addr_t ram_size)
{
        memset(bd, 0, sizeof(*bd));

        bd->bi_memstart = PPC405EP_SDRAM_BASE;
        bd->bi_memsize = ram_size;
        bd->bi_sramstart = PPC405EP_SRAM_BASE;
        bd->bi_sramsize = PPC405EP_SRAM_SIZE;
        bd->bi_bootflags = 0;
        bd->bi_intfreq = 133333333;
        bd->bi_busfreq = 33333333;
        bd->bi_baudrate = 115200;
        bd->bi_s_version[0] = 'Q';
        bd->bi_s_version[1] = 'M';
        bd->bi_s_version[2] = 'U';
        bd->bi_s_version[3] = '\0';
        bd->bi_r_version[0] = 'Q';
        bd->bi_r_version[1] = 'E';
        bd->bi_r_version[2] = 'M';
        bd->bi_r_version[3] = 'U';
        bd->bi_r_version[4] = '\0';
        bd->bi_procfreq = 133333333;
        bd->bi_plb_busfreq = 33333333;
        bd->bi_pci_busfreq = 33333333;
        bd->bi_opbfreq = 33333333;
}

static ram_addr_t __ppc405_set_bootinfo(CPUPPCState *env, ppc4xx_bd_info_t *bd)
{
    CPUState *cs = env_cpu(env);
    ram_addr_t bdloc;
    int i, n;

    /* We put the bd structure at the top of memory */
    if (bd->bi_memsize >= 0x01000000UL) {
        bdloc = 0x01000000UL - sizeof(ppc4xx_bd_info_t);
    } else {
        bdloc = bd->bi_memsize - sizeof(ppc4xx_bd_info_t);
    }
    stl_be_phys(cs->as, bdloc + 0x00, bd->bi_memstart);
    stl_be_phys(cs->as, bdloc + 0x04, bd->bi_memsize);
    stl_be_phys(cs->as, bdloc + 0x08, bd->bi_flashstart);
    stl_be_phys(cs->as, bdloc + 0x0C, bd->bi_flashsize);
    stl_be_phys(cs->as, bdloc + 0x10, bd->bi_flashoffset);
    stl_be_phys(cs->as, bdloc + 0x14, bd->bi_sramstart);
    stl_be_phys(cs->as, bdloc + 0x18, bd->bi_sramsize);
    stl_be_phys(cs->as, bdloc + 0x1C, bd->bi_bootflags);
    stl_be_phys(cs->as, bdloc + 0x20, bd->bi_ipaddr);
    for (i = 0; i < 6; i++) {
        stb_phys(cs->as, bdloc + 0x24 + i, bd->bi_enetaddr[i]);
    }
    stw_be_phys(cs->as, bdloc + 0x2A, bd->bi_ethspeed);
    stl_be_phys(cs->as, bdloc + 0x2C, bd->bi_intfreq);
    stl_be_phys(cs->as, bdloc + 0x30, bd->bi_busfreq);
    stl_be_phys(cs->as, bdloc + 0x34, bd->bi_baudrate);
    for (i = 0; i < 4; i++) {
        stb_phys(cs->as, bdloc + 0x38 + i, bd->bi_s_version[i]);
    }
    for (i = 0; i < 32; i++) {
        stb_phys(cs->as, bdloc + 0x3C + i, bd->bi_r_version[i]);
    }
    stl_be_phys(cs->as, bdloc + 0x5C, bd->bi_procfreq);
    stl_be_phys(cs->as, bdloc + 0x60, bd->bi_plb_busfreq);
    stl_be_phys(cs->as, bdloc + 0x64, bd->bi_pci_busfreq);
    for (i = 0; i < 6; i++) {
        stb_phys(cs->as, bdloc + 0x68 + i, bd->bi_pci_enetaddr[i]);
    }
    n = 0x70; /* includes 2 bytes hole */
    for (i = 0; i < 6; i++) {
        stb_phys(cs->as, bdloc + n++, bd->bi_pci_enetaddr2[i]);
    }
    stl_be_phys(cs->as, bdloc + n, bd->bi_opbfreq);
    n += 4;
    for (i = 0; i < 2; i++) {
        stl_be_phys(cs->as, bdloc + n, bd->bi_iic_fast[i]);
        n += 4;
    }

    return bdloc;
}

static ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size)
{
    ppc4xx_bd_info_t bd;

    memset(&bd, 0, sizeof(bd));

    ppc405_set_default_bootinfo(&bd, ram_size);

    return __ppc405_set_bootinfo(env, &bd);
}

static void boot_from_kernel(MachineState *machine, PowerPCCPU *cpu)
{
    CPUPPCState *env = &cpu->env;
    hwaddr boot_entry;
    hwaddr kernel_base;
    int kernel_size;
    hwaddr initrd_base;
    int initrd_size;
    ram_addr_t bdloc;
    int len;

    bdloc = ppc405_set_bootinfo(env, machine->ram_size);
    boot_info.bdloc = bdloc;

    kernel_size = load_elf(machine->kernel_filename, NULL, NULL, NULL,
                           &boot_entry, &kernel_base, NULL, NULL,
                           1, PPC_ELF_MACHINE, 0, 0);
    if (kernel_size < 0) {
        error_report("Could not load kernel '%s' : %s",
                     machine->kernel_filename, load_elf_strerror(kernel_size));
        exit(1);
    }
    boot_info.entry = boot_entry;

    /* load initrd */
    if (machine->initrd_filename) {
        initrd_base = INITRD_LOAD_ADDR;
        initrd_size = load_image_targphys(machine->initrd_filename, initrd_base,
                                          machine->ram_size - initrd_base);
        if (initrd_size < 0) {
            error_report("could not load initial ram disk '%s'",
                         machine->initrd_filename);
            exit(1);
        }

        boot_info.initrd_base = initrd_base;
        boot_info.initrd_size = initrd_size;
    }

    if (machine->kernel_cmdline) {
        len = strlen(machine->kernel_cmdline);
        bdloc -= ((len + 255) & ~255);
        cpu_physical_memory_write(bdloc, machine->kernel_cmdline, len + 1);
        boot_info.cmdline_base = bdloc;
        boot_info.cmdline_size = bdloc + len;
    }

    /* Install our custom reset handler to start from Linux */
    qemu_register_reset(main_cpu_reset, cpu);
    env->load_info = &boot_info;
}

static void ppc405_init(MachineState *machine)
{
    Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
    const char *kernel_filename = machine->kernel_filename;
    MemoryRegion *sysmem = get_system_memory();

    object_initialize_child(OBJECT(machine), "soc", &ppc405->soc,
                            TYPE_PPC405_SOC);
    object_property_set_link(OBJECT(&ppc405->soc), "dram",
                             OBJECT(machine->ram), &error_abort);
    object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", 33333333,
                             &error_abort);
    qdev_realize(DEVICE(&ppc405->soc), NULL, &error_fatal);

    /* allocate and load BIOS */
    if (machine->firmware) {
        MemoryRegion *bios = g_new(MemoryRegion, 1);
        g_autofree char *filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
                                                   machine->firmware);
        long bios_size;

        memory_region_init_rom(bios, NULL, "ef405ep.bios", BIOS_SIZE,
                               &error_fatal);

        if (!filename) {
            error_report("Could not find firmware '%s'", machine->firmware);
            exit(1);
        }

        bios_size = load_image_size(filename,
                                    memory_region_get_ram_ptr(bios),
                                    BIOS_SIZE);
        if (bios_size < 0) {
            error_report("Could not load PowerPC BIOS '%s'", machine->firmware);
            exit(1);
        }

        bios_size = (bios_size + 0xfff) & ~0xfff;
        memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
    }

    /* Load kernel and initrd using U-Boot images */
    if (kernel_filename && machine->firmware) {
        target_ulong kernel_base, initrd_base;
        long kernel_size, initrd_size;

        kernel_base = KERNEL_LOAD_ADDR;
        kernel_size = load_image_targphys(kernel_filename, kernel_base,
                                          machine->ram_size - kernel_base);
        if (kernel_size < 0) {
            error_report("could not load kernel '%s'", kernel_filename);
            exit(1);
        }

        /* load initrd */
        if (machine->initrd_filename) {
            initrd_base = INITRD_LOAD_ADDR;
            initrd_size = load_image_targphys(machine->initrd_filename,
                                              initrd_base,
                                              machine->ram_size - initrd_base);
            if (initrd_size < 0) {
                error_report("could not load initial ram disk '%s'",
                             machine->initrd_filename);
                exit(1);
            }
        }

    /* Load ELF kernel and rootfs.cpio */
    } else if (kernel_filename && !machine->firmware) {
        ppc4xx_sdram_ddr_enable(&ppc405->soc.sdram);
        boot_from_kernel(machine, &ppc405->soc.cpu);
    }
}

static void ppc405_machine_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);

    mc->desc = "PPC405 generic machine";
    mc->init = ppc405_init;
    mc->default_ram_size = 128 * MiB;
    mc->default_ram_id = "ppc405.ram";
    mc->deprecation_reason = "machine is old and unmaintained";
}

static const TypeInfo ppc405_machine_type = {
    .name = TYPE_PPC405_MACHINE,
    .parent = TYPE_MACHINE,
    .instance_size = sizeof(Ppc405MachineState),
    .class_init = ppc405_machine_class_init,
    .abstract = true,
};

/*****************************************************************************/
/* PPC405EP reference board (IBM) */
/*
 * Standalone board with:
 * - PowerPC 405EP CPU
 * - SDRAM (0x00000000)
 * - Flash (0xFFF80000)
 * - SRAM  (0xFFF00000)
 * - NVRAM (0xF0000000)
 * - FPGA  (0xF0300000)
 */

#define PPC405EP_NVRAM_BASE 0xF0000000
#define PPC405EP_FPGA_BASE  0xF0300000
#define PPC405EP_FLASH_BASE 0xFFF80000

#define TYPE_REF405EP_FPGA "ref405ep-fpga"
OBJECT_DECLARE_SIMPLE_TYPE(Ref405epFpgaState, REF405EP_FPGA);
struct Ref405epFpgaState {
    SysBusDevice parent_obj;

    MemoryRegion iomem;

    uint8_t reg0;
    uint8_t reg1;
};

static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr addr, unsigned size)
{
    Ref405epFpgaState *fpga = opaque;
    uint32_t ret;

    switch (addr) {
    case 0x0:
        ret = fpga->reg0;
        break;
    case 0x1:
        ret = fpga->reg1;
        break;
    default:
        ret = 0;
        break;
    }

    return ret;
}

static void ref405ep_fpga_writeb(void *opaque, hwaddr addr, uint64_t value,
                                 unsigned size)
{
    Ref405epFpgaState *fpga = opaque;

    switch (addr) {
    case 0x0:
        /* Read only */
        break;
    case 0x1:
        fpga->reg1 = value;
        break;
    default:
        break;
    }
}

static const MemoryRegionOps ref405ep_fpga_ops = {
    .read = ref405ep_fpga_readb,
    .write = ref405ep_fpga_writeb,
    .impl.min_access_size = 1,
    .impl.max_access_size = 1,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .endianness = DEVICE_BIG_ENDIAN,
};

static void ref405ep_fpga_reset(DeviceState *dev)
{
    Ref405epFpgaState *fpga = REF405EP_FPGA(dev);

    fpga->reg0 = 0x00;
    fpga->reg1 = 0x0F;
}

static void ref405ep_fpga_realize(DeviceState *dev, Error **errp)
{
    Ref405epFpgaState *s = REF405EP_FPGA(dev);

    memory_region_init_io(&s->iomem, OBJECT(s), &ref405ep_fpga_ops, s,
                          "fpga", 0x00000100);
    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
}

static void ref405ep_fpga_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->realize = ref405ep_fpga_realize;
    device_class_set_legacy_reset(dc, ref405ep_fpga_reset);
    /* Reason: only works as part of a ppc405 board */
    dc->user_creatable = false;
}

static const TypeInfo ref405ep_fpga_type = {
    .name = TYPE_REF405EP_FPGA,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(Ref405epFpgaState),
    .class_init = ref405ep_fpga_class_init,
};

static void ref405ep_init(MachineState *machine)
{
    DeviceState *dev;
    SysBusDevice *s;
    MemoryRegion *sram = g_new(MemoryRegion, 1);

    ppc405_init(machine);

    /* allocate SRAM */
    memory_region_init_ram(sram, NULL, "ref405ep.sram", PPC405EP_SRAM_SIZE,
                           &error_fatal);
    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE, sram);

    /* Register FPGA */
    dev = qdev_new(TYPE_REF405EP_FPGA);
    object_property_add_child(OBJECT(machine), "fpga", OBJECT(dev));
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, PPC405EP_FPGA_BASE);

    /* Register NVRAM */
    dev = qdev_new("sysbus-m48t08");
    qdev_prop_set_int32(dev, "base-year", 1968);
    s = SYS_BUS_DEVICE(dev);
    sysbus_realize_and_unref(s, &error_fatal);
    sysbus_mmio_map(s, 0, PPC405EP_NVRAM_BASE);
}

static void ref405ep_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);

    mc->desc = "ref405ep";
    mc->init = ref405ep_init;
}

static const TypeInfo ref405ep_type = {
    .name = MACHINE_TYPE_NAME("ref405ep"),
    .parent = TYPE_PPC405_MACHINE,
    .class_init = ref405ep_class_init,
};

static void ppc405_machine_init(void)
{
    type_register_static(&ppc405_machine_type);
    type_register_static(&ref405ep_type);
    type_register_static(&ref405ep_fpga_type);
}

type_init(ppc405_machine_init)
