/*
 * Motorola ColdFire MCF5208 SoC emulation.
 *
 * Copyright (c) 2007 CodeSourcery.
 *
 * This code is licensed under the GPL
 */
#include "hw.h"
#include "mcf.h"
#include "qemu-timer.h"
#include "ptimer.h"
#include "sysemu.h"
#include "net.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
#include "exec-memory.h"

#define SYS_FREQ 66000000

#define PCSR_EN         0x0001
#define PCSR_RLD        0x0002
#define PCSR_PIF        0x0004
#define PCSR_PIE        0x0008
#define PCSR_OVW        0x0010
#define PCSR_DBG        0x0020
#define PCSR_DOZE       0x0040
#define PCSR_PRE_SHIFT  8
#define PCSR_PRE_MASK   0x0f00

typedef struct {
    MemoryRegion iomem;
    qemu_irq irq;
    ptimer_state *timer;
    uint16_t pcsr;
    uint16_t pmr;
    uint16_t pcntr;
} m5208_timer_state;

static void m5208_timer_update(m5208_timer_state *s)
{
    if ((s->pcsr & (PCSR_PIE | PCSR_PIF)) == (PCSR_PIE | PCSR_PIF))
        qemu_irq_raise(s->irq);
    else
        qemu_irq_lower(s->irq);
}

static void m5208_timer_write(void *opaque, hwaddr offset,
                              uint64_t value, unsigned size)
{
    m5208_timer_state *s = (m5208_timer_state *)opaque;
    int prescale;
    int limit;
    switch (offset) {
    case 0:
        /* The PIF bit is set-to-clear.  */
        if (value & PCSR_PIF) {
            s->pcsr &= ~PCSR_PIF;
            value &= ~PCSR_PIF;
        }
        /* Avoid frobbing the timer if we're just twiddling IRQ bits. */
        if (((s->pcsr ^ value) & ~PCSR_PIE) == 0) {
            s->pcsr = value;
            m5208_timer_update(s);
            return;
        }

        if (s->pcsr & PCSR_EN)
            ptimer_stop(s->timer);

        s->pcsr = value;

        prescale = 1 << ((s->pcsr & PCSR_PRE_MASK) >> PCSR_PRE_SHIFT);
        ptimer_set_freq(s->timer, (SYS_FREQ / 2) / prescale);
        if (s->pcsr & PCSR_RLD)
            limit = s->pmr;
        else
            limit = 0xffff;
        ptimer_set_limit(s->timer, limit, 0);

        if (s->pcsr & PCSR_EN)
            ptimer_run(s->timer, 0);
        break;
    case 2:
        s->pmr = value;
        s->pcsr &= ~PCSR_PIF;
        if ((s->pcsr & PCSR_RLD) == 0) {
            if (s->pcsr & PCSR_OVW)
                ptimer_set_count(s->timer, value);
        } else {
            ptimer_set_limit(s->timer, value, s->pcsr & PCSR_OVW);
        }
        break;
    case 4:
        break;
    default:
        hw_error("m5208_timer_write: Bad offset 0x%x\n", (int)offset);
        break;
    }
    m5208_timer_update(s);
}

static void m5208_timer_trigger(void *opaque)
{
    m5208_timer_state *s = (m5208_timer_state *)opaque;
    s->pcsr |= PCSR_PIF;
    m5208_timer_update(s);
}

static uint64_t m5208_timer_read(void *opaque, hwaddr addr,
                                 unsigned size)
{
    m5208_timer_state *s = (m5208_timer_state *)opaque;
    switch (addr) {
    case 0:
        return s->pcsr;
    case 2:
        return s->pmr;
    case 4:
        return ptimer_get_count(s->timer);
    default:
        hw_error("m5208_timer_read: Bad offset 0x%x\n", (int)addr);
        return 0;
    }
}

static const MemoryRegionOps m5208_timer_ops = {
    .read = m5208_timer_read,
    .write = m5208_timer_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static uint64_t m5208_sys_read(void *opaque, hwaddr addr,
                               unsigned size)
{
    switch (addr) {
    case 0x110: /* SDCS0 */
        {
            int n;
            for (n = 0; n < 32; n++) {
                if (ram_size < (2u << n))
                    break;
            }
            return (n - 1)  | 0x40000000;
        }
    case 0x114: /* SDCS1 */
        return 0;

    default:
        hw_error("m5208_sys_read: Bad offset 0x%x\n", (int)addr);
        return 0;
    }
}

static void m5208_sys_write(void *opaque, hwaddr addr,
                            uint64_t value, unsigned size)
{
    hw_error("m5208_sys_write: Bad offset 0x%x\n", (int)addr);
}

static const MemoryRegionOps m5208_sys_ops = {
    .read = m5208_sys_read,
    .write = m5208_sys_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
{
    MemoryRegion *iomem = g_new(MemoryRegion, 1);
    m5208_timer_state *s;
    QEMUBH *bh;
    int i;

    /* SDRAMC.  */
    memory_region_init_io(iomem, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
    memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
    /* Timers.  */
    for (i = 0; i < 2; i++) {
        s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
        bh = qemu_bh_new(m5208_timer_trigger, s);
        s->timer = ptimer_init(bh);
        memory_region_init_io(&s->iomem, &m5208_timer_ops, s,
                              "m5208-timer", 0x00004000);
        memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
                                    &s->iomem);
        s->irq = pic[4 + i];
    }
}

static void mcf5208evb_init(QEMUMachineInitArgs *args)
{
    ram_addr_t ram_size = args->ram_size;
    const char *cpu_model = args->cpu_model;
    const char *kernel_filename = args->kernel_filename;
    CPUM68KState *env;
    int kernel_size;
    uint64_t elf_entry;
    hwaddr entry;
    qemu_irq *pic;
    MemoryRegion *address_space_mem = get_system_memory();
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *sram = g_new(MemoryRegion, 1);

    if (!cpu_model)
        cpu_model = "m5208";
    env = cpu_init(cpu_model);
    if (!env) {
        fprintf(stderr, "Unable to find m68k CPU definition\n");
        exit(1);
    }

    /* Initialize CPU registers.  */
    env->vbr = 0;
    /* TODO: Configure BARs.  */

    /* DRAM at 0x40000000 */
    memory_region_init_ram(ram, "mcf5208.ram", ram_size);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(address_space_mem, 0x40000000, ram);

    /* Internal SRAM.  */
    memory_region_init_ram(sram, "mcf5208.sram", 16384);
    vmstate_register_ram_global(sram);
    memory_region_add_subregion(address_space_mem, 0x80000000, sram);

    /* Internal peripherals.  */
    pic = mcf_intc_init(address_space_mem, 0xfc048000, env);

    mcf_uart_mm_init(address_space_mem, 0xfc060000, pic[26], serial_hds[0]);
    mcf_uart_mm_init(address_space_mem, 0xfc064000, pic[27], serial_hds[1]);
    mcf_uart_mm_init(address_space_mem, 0xfc068000, pic[28], serial_hds[2]);

    mcf5208_sys_init(address_space_mem, pic);

    if (nb_nics > 1) {
        fprintf(stderr, "Too many NICs\n");
        exit(1);
    }
    if (nd_table[0].used)
        mcf_fec_init(address_space_mem, &nd_table[0],
                     0xfc030000, pic + 36);

    /*  0xfc000000 SCM.  */
    /*  0xfc004000 XBS.  */
    /*  0xfc008000 FlexBus CS.  */
    /* 0xfc030000 FEC.  */
    /*  0xfc040000 SCM + Power management.  */
    /*  0xfc044000 eDMA.  */
    /* 0xfc048000 INTC.  */
    /*  0xfc058000 I2C.  */
    /*  0xfc05c000 QSPI.  */
    /* 0xfc060000 UART0.  */
    /* 0xfc064000 UART0.  */
    /* 0xfc068000 UART0.  */
    /*  0xfc070000 DMA timers.  */
    /* 0xfc080000 PIT0.  */
    /* 0xfc084000 PIT1.  */
    /*  0xfc088000 EPORT.  */
    /*  0xfc08c000 Watchdog.  */
    /*  0xfc090000 clock module.  */
    /*  0xfc0a0000 CCM + reset.  */
    /*  0xfc0a4000 GPIO.  */
    /* 0xfc0a8000 SDRAM controller.  */

    /* Load kernel.  */
    if (!kernel_filename) {
        fprintf(stderr, "Kernel image must be specified\n");
        exit(1);
    }

    kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
                           NULL, NULL, 1, ELF_MACHINE, 0);
    entry = elf_entry;
    if (kernel_size < 0) {
        kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
    }
    if (kernel_size < 0) {
        kernel_size = load_image_targphys(kernel_filename, 0x40000000,
                                          ram_size);
        entry = 0x40000000;
    }
    if (kernel_size < 0) {
        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
        exit(1);
    }

    env->pc = entry;
}

static QEMUMachine mcf5208evb_machine = {
    .name = "mcf5208evb",
    .desc = "MCF5206EVB",
    .init = mcf5208evb_init,
    .is_default = 1,
};

static void mcf5208evb_machine_init(void)
{
    qemu_register_machine(&mcf5208evb_machine);
}

machine_init(mcf5208evb_machine_init);
