Commit b39506e4 authored by Hervé Poussineau's avatar Hervé Poussineau Committed by Anthony Liguori
Browse files

jazz-led: convert to QOM



Some simplifications in I/O functions are possible because
Jazz LED only registers one byte of I/O.

Signed-off-by: default avatarHervé Poussineau <hpoussin@reactos.org>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 63b9932d
Loading
Loading
Loading
Loading
+70 −89
Original line number Diff line number Diff line
/*
 * QEMU JAZZ LED emulator.
 *
 * Copyright (c) 2007 Hervé Poussineau
 * Copyright (c) 2007-2012 Herve Poussineau
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
@@ -22,123 +22,53 @@
 * THE SOFTWARE.
 */

#include "hw.h"
#include "mips.h"
#include "console.h"
#include "pixel_ops.h"
#include "trace.h"
#include "sysbus.h"

typedef enum {
    REDRAW_NONE = 0, REDRAW_SEGMENTS = 1, REDRAW_BACKGROUND = 2,
} screen_state_t;

typedef struct LedState {
    SysBusDevice busdev;
    MemoryRegion iomem;
    uint8_t segments;
    DisplayState *ds;
    screen_state_t state;
} LedState;

static uint32_t led_readb(void *opaque, target_phys_addr_t addr)
static uint64_t jazz_led_read(void *opaque, target_phys_addr_t addr,
                              unsigned int size)
{
    LedState *s = opaque;
    uint8_t val;

    switch (addr) {
        case 0:
    val = s->segments;
            break;
        default:
            error_report("invalid read at [" TARGET_FMT_plx "]\n", addr);
            val = 0;
    }

    trace_jazz_led_read(addr, val);

    return val;
}

static uint32_t led_readw(void *opaque, target_phys_addr_t addr)
{
    uint32_t v;
#ifdef TARGET_WORDS_BIGENDIAN
    v = led_readb(opaque, addr) << 8;
    v |= led_readb(opaque, addr + 1);
#else
    v = led_readb(opaque, addr);
    v |= led_readb(opaque, addr + 1) << 8;
#endif
    return v;
}

static uint32_t led_readl(void *opaque, target_phys_addr_t addr)
{
    uint32_t v;
#ifdef TARGET_WORDS_BIGENDIAN
    v = led_readb(opaque, addr) << 24;
    v |= led_readb(opaque, addr + 1) << 16;
    v |= led_readb(opaque, addr + 2) << 8;
    v |= led_readb(opaque, addr + 3);
#else
    v = led_readb(opaque, addr);
    v |= led_readb(opaque, addr + 1) << 8;
    v |= led_readb(opaque, addr + 2) << 16;
    v |= led_readb(opaque, addr + 3) << 24;
#endif
    return v;
}

static void led_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
static void jazz_led_write(void *opaque, target_phys_addr_t addr,
                           uint64_t val, unsigned int size)
{
    LedState *s = opaque;
    uint8_t new_val = val & 0xff;

    trace_jazz_led_write(addr, new_val);

    switch (addr) {
        case 0:
    s->segments = new_val;
    s->state |= REDRAW_SEGMENTS;
            break;
        default:
            error_report("invalid write of 0x%x at [" TARGET_FMT_plx "]\n",
                         new_val, addr);
            break;
    }
}

static void led_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
{
#ifdef TARGET_WORDS_BIGENDIAN
    led_writeb(opaque, addr, (val >> 8) & 0xff);
    led_writeb(opaque, addr + 1, val & 0xff);
#else
    led_writeb(opaque, addr, val & 0xff);
    led_writeb(opaque, addr + 1, (val >> 8) & 0xff);
#endif
}

static void led_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
{
#ifdef TARGET_WORDS_BIGENDIAN
    led_writeb(opaque, addr, (val >> 24) & 0xff);
    led_writeb(opaque, addr + 1, (val >> 16) & 0xff);
    led_writeb(opaque, addr + 2, (val >> 8) & 0xff);
    led_writeb(opaque, addr + 3, val & 0xff);
#else
    led_writeb(opaque, addr, val & 0xff);
    led_writeb(opaque, addr + 1, (val >> 8) & 0xff);
    led_writeb(opaque, addr + 2, (val >> 16) & 0xff);
    led_writeb(opaque, addr + 3, (val >> 24) & 0xff);
#endif
}

static const MemoryRegionOps led_ops = {
    .old_mmio = {
        .read = { led_readb, led_readw, led_readl, },
        .write = { led_writeb, led_writew, led_writel, },
    },
    .read = jazz_led_read,
    .write = jazz_led_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl.min_access_size = 1,
    .impl.max_access_size = 1,
};

/***********************************************************/
@@ -296,20 +226,71 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
    dpy_update(s->ds, 0, 0, 2, 1);
}

void jazz_led_init(MemoryRegion *address_space, target_phys_addr_t base)
static int jazz_led_post_load(void *opaque, int version_id)
{
    LedState *s;
    /* force refresh */
    jazz_led_invalidate_display(opaque);

    return 0;
}

    s = g_malloc0(sizeof(LedState));
static const VMStateDescription vmstate_jazz_led = {
    .name = "jazz-led",
    .version_id = 0,
    .minimum_version_id = 0,
    .minimum_version_id_old = 0,
    .post_load = jazz_led_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(segments, LedState),
        VMSTATE_END_OF_LIST()
    }
};

    s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND;
static int jazz_led_init(SysBusDevice *dev)
{
    LedState *s = FROM_SYSBUS(LedState, dev);

    memory_region_init_io(&s->iomem, &led_ops, s, "led", 1);
    memory_region_add_subregion(address_space, base, &s->iomem);
    sysbus_init_mmio(dev, &s->iomem);

    s->ds = graphic_console_init(jazz_led_update_display,
                                 jazz_led_invalidate_display,
                                 jazz_led_screen_dump,
                                 jazz_led_text_update, s);

    return 0;
}

static void jazz_led_reset(DeviceState *d)
{
    LedState *s = DO_UPCAST(LedState, busdev.qdev, d);

    s->segments = 0;
    s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND;
    qemu_console_resize(s->ds, 60, 80);
}

static void jazz_led_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = jazz_led_init;
    dc->desc = "Jazz LED display",
    dc->vmsd = &vmstate_jazz_led;
    dc->reset = jazz_led_reset;
}

static TypeInfo jazz_led_info = {
    .name          = "jazz-led",
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(LedState),
    .class_init    = jazz_led_class_init,
};

static void jazz_led_register(void)
{
    type_register_static(&jazz_led_info);
}

type_init(jazz_led_register);
+0 −3
Original line number Diff line number Diff line
@@ -10,9 +10,6 @@ PCIBus *gt64120_register(qemu_irq *pic);
/* bonito.c */
PCIBus *bonito_init(qemu_irq *pic);

/* jazz_led.c */
void jazz_led_init(MemoryRegion *address_space, target_phys_addr_t base);

/* rc4030.c */
typedef struct rc4030DMAState *rc4030_dma;
void rc4030_dma_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len, int is_write);
+1 −1
Original line number Diff line number Diff line
@@ -295,7 +295,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
    sysbus_mmio_map(sysbus, 0, 0x80009000);

    /* LED indicator */
    jazz_led_init(address_space, 0x8000f000);
    sysbus_create_simple("jazz-led", 0x8000f000, NULL);
}

static