mirror of https://github.com/xqemu/xqemu.git
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: Hervé Poussineau <hpoussin@reactos.org> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
63b9932dd0
commit
b39506e44d
159
hw/jazz_led.c
159
hw/jazz_led.c
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* QEMU JAZZ LED emulator.
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -22,123 +22,53 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hw.h"
|
|
||||||
#include "mips.h"
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "pixel_ops.h"
|
#include "pixel_ops.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "sysbus.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
REDRAW_NONE = 0, REDRAW_SEGMENTS = 1, REDRAW_BACKGROUND = 2,
|
REDRAW_NONE = 0, REDRAW_SEGMENTS = 1, REDRAW_BACKGROUND = 2,
|
||||||
} screen_state_t;
|
} screen_state_t;
|
||||||
|
|
||||||
typedef struct LedState {
|
typedef struct LedState {
|
||||||
|
SysBusDevice busdev;
|
||||||
MemoryRegion iomem;
|
MemoryRegion iomem;
|
||||||
uint8_t segments;
|
uint8_t segments;
|
||||||
DisplayState *ds;
|
DisplayState *ds;
|
||||||
screen_state_t state;
|
screen_state_t state;
|
||||||
} LedState;
|
} 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;
|
LedState *s = opaque;
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
|
|
||||||
switch (addr) {
|
val = s->segments;
|
||||||
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);
|
trace_jazz_led_read(addr, val);
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t led_readw(void *opaque, target_phys_addr_t addr)
|
static void jazz_led_write(void *opaque, target_phys_addr_t addr,
|
||||||
{
|
uint64_t val, unsigned int size)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
LedState *s = opaque;
|
LedState *s = opaque;
|
||||||
uint8_t new_val = val & 0xff;
|
uint8_t new_val = val & 0xff;
|
||||||
|
|
||||||
trace_jazz_led_write(addr, new_val);
|
trace_jazz_led_write(addr, new_val);
|
||||||
|
|
||||||
switch (addr) {
|
s->segments = new_val;
|
||||||
case 0:
|
s->state |= REDRAW_SEGMENTS;
|
||||||
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 = {
|
static const MemoryRegionOps led_ops = {
|
||||||
.old_mmio = {
|
.read = jazz_led_read,
|
||||||
.read = { led_readb, led_readw, led_readl, },
|
.write = jazz_led_write,
|
||||||
.write = { led_writeb, led_writew, led_writel, },
|
|
||||||
},
|
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.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);
|
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);
|
||||||
|
|
||||||
s = g_malloc0(sizeof(LedState));
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND;
|
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()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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_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,
|
s->ds = graphic_console_init(jazz_led_update_display,
|
||||||
jazz_led_invalidate_display,
|
jazz_led_invalidate_display,
|
||||||
jazz_led_screen_dump,
|
jazz_led_screen_dump,
|
||||||
jazz_led_text_update, s);
|
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);
|
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);
|
||||||
|
|
|
@ -10,9 +10,6 @@ PCIBus *gt64120_register(qemu_irq *pic);
|
||||||
/* bonito.c */
|
/* bonito.c */
|
||||||
PCIBus *bonito_init(qemu_irq *pic);
|
PCIBus *bonito_init(qemu_irq *pic);
|
||||||
|
|
||||||
/* jazz_led.c */
|
|
||||||
void jazz_led_init(MemoryRegion *address_space, target_phys_addr_t base);
|
|
||||||
|
|
||||||
/* rc4030.c */
|
/* rc4030.c */
|
||||||
typedef struct rc4030DMAState *rc4030_dma;
|
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);
|
void rc4030_dma_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len, int is_write);
|
||||||
|
|
|
@ -295,7 +295,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
|
||||||
sysbus_mmio_map(sysbus, 0, 0x80009000);
|
sysbus_mmio_map(sysbus, 0, 0x80009000);
|
||||||
|
|
||||||
/* LED indicator */
|
/* LED indicator */
|
||||||
jazz_led_init(address_space, 0x8000f000);
|
sysbus_create_simple("jazz-led", 0x8000f000, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
Loading…
Reference in New Issue