From b39506e44d73a3564adf7237f2a716f1e569e5a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Fri, 17 Feb 2012 20:27:16 +0100 Subject: [PATCH] jazz-led: convert to QOM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some simplifications in I/O functions are possible because Jazz LED only registers one byte of I/O. Signed-off-by: Hervé Poussineau Signed-off-by: Anthony Liguori --- hw/jazz_led.c | 159 ++++++++++++++++++++++--------------------------- hw/mips.h | 3 - hw/mips_jazz.c | 2 +- 3 files changed, 71 insertions(+), 93 deletions(-) diff --git a/hw/jazz_led.c b/hw/jazz_led.c index 1af92684c7..5d8040be30 100644 --- a/hw/jazz_led.c +++ b/hw/jazz_led.c @@ -1,7 +1,7 @@ /* * 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; - } - + val = s->segments; 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 + s->segments = new_val; + s->state |= REDRAW_SEGMENTS; } 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); - 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_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); diff --git a/hw/mips.h b/hw/mips.h index 22156fce53..a7e6d4cc62 100644 --- a/hw/mips.h +++ b/hw/mips.h @@ -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); diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c index 65608dc644..2b4678e170 100644 --- a/hw/mips_jazz.c +++ b/hw/mips_jazz.c @@ -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