/*
 * LED, Switch and Debug control registers for ARM Integrator Boards
 *
 * This is currently a stub for this functionality but at least
 * ensures something other than unassigned_mem_read() handles access
 * to this area.
 *
 * The real h/w is described at:
 *  http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html
 *
 * Copyright (c) 2013 Alex Bennée <alex@bennee.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "hw/hw.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
#include "hw/misc/arm_integrator_debug.h"

#define INTEGRATOR_DEBUG(obj) \
    OBJECT_CHECK(IntegratorDebugState, (obj), TYPE_INTEGRATOR_DEBUG)

typedef struct {
    SysBusDevice parent_obj;

    MemoryRegion iomem;
} IntegratorDebugState;

static uint64_t intdbg_control_read(void *opaque, hwaddr offset,
                                    unsigned size)
{
    switch (offset >> 2) {
    case 0: /* ALPHA */
    case 1: /* LEDS */
    case 2: /* SWITCHES */
        qemu_log_mask(LOG_UNIMP,
                      "%s: returning zero from %" HWADDR_PRIx ":%u\n",
                      __func__, offset, size);
        return 0;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad offset %" HWADDR_PRIx,
                      __func__, offset);
        return 0;
    }
}

static void intdbg_control_write(void *opaque, hwaddr offset,
                                 uint64_t value, unsigned size)
{
    switch (offset >> 2) {
    case 1: /* ALPHA */
    case 2: /* LEDS */
    case 3: /* SWITCHES */
        /* Nothing interesting implemented yet.  */
        qemu_log_mask(LOG_UNIMP,
                      "%s: ignoring write of %" PRIu64
                      " to %" HWADDR_PRIx ":%u\n",
                      __func__, value, offset, size);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: write of %" PRIu64
                      " to bad offset %" HWADDR_PRIx "\n",
                      __func__, value, offset);
    }
}

static const MemoryRegionOps intdbg_control_ops = {
    .read = intdbg_control_read,
    .write = intdbg_control_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void intdbg_control_init(Object *obj)
{
    SysBusDevice *sd = SYS_BUS_DEVICE(obj);
    IntegratorDebugState *s = INTEGRATOR_DEBUG(obj);

    memory_region_init_io(&s->iomem, NULL, &intdbg_control_ops,
                          NULL, "dbg-leds", 0x1000000);
    sysbus_init_mmio(sd, &s->iomem);
}

static const TypeInfo intdbg_info = {
    .name          = TYPE_INTEGRATOR_DEBUG,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IntegratorDebugState),
    .instance_init = intdbg_control_init,
};

static void intdbg_register_types(void)
{
    type_register_static(&intdbg_info);
}

type_init(intdbg_register_types)
