dma/rc4030: convert to QOM

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
Hervé Poussineau 2015-06-03 22:45:41 +02:00 committed by Leon Alrae
parent 95c357bc46
commit d791d60f1c
3 changed files with 115 additions and 45 deletions

View File

@ -1,7 +1,7 @@
/* /*
* QEMU JAZZ RC4030 chipset * QEMU JAZZ RC4030 chipset
* *
* Copyright (c) 2007-2009 Herve Poussineau * Copyright (c) 2007-2013 Hervé 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
@ -24,6 +24,7 @@
#include "hw/hw.h" #include "hw/hw.h"
#include "hw/mips/mips.h" #include "hw/mips/mips.h"
#include "hw/sysbus.h"
#include "qemu/timer.h" #include "qemu/timer.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "trace.h" #include "trace.h"
@ -49,8 +50,14 @@ typedef struct dma_pagetable_entry {
#define DMA_FLAG_MEM_INTR 0x0200 #define DMA_FLAG_MEM_INTR 0x0200
#define DMA_FLAG_ADDR_INTR 0x0400 #define DMA_FLAG_ADDR_INTR 0x0400
#define TYPE_RC4030 "rc4030"
#define RC4030(obj) \
OBJECT_CHECK(rc4030State, (obj), TYPE_RC4030)
typedef struct rc4030State typedef struct rc4030State
{ {
SysBusDevice parent;
uint32_t config; /* 0x0000: RC4030 config register */ uint32_t config; /* 0x0000: RC4030 config register */
uint32_t revision; /* 0x0008: RC4030 Revision register */ uint32_t revision; /* 0x0008: RC4030 Revision register */
uint32_t invalid_address_register; /* 0x0010: Invalid Address register */ uint32_t invalid_address_register; /* 0x0010: Invalid Address register */
@ -317,7 +324,7 @@ static void rc4030_dma_tt_update(rc4030State *s, uint32_t new_tl_base,
} else { } else {
dma_tt_size = memory_region_size(&s->dma_tt); dma_tt_size = memory_region_size(&s->dma_tt);
} }
memory_region_init_alias(&s->dma_tt_alias, NULL, memory_region_init_alias(&s->dma_tt_alias, OBJECT(s),
"dma-table-alias", "dma-table-alias",
&s->dma_tt, 0, dma_tt_size); &s->dma_tt, 0, dma_tt_size);
dma_tl_contents = memory_region_get_ram_ptr(&s->dma_tt); dma_tl_contents = memory_region_get_ram_ptr(&s->dma_tt);
@ -332,7 +339,7 @@ static void rc4030_dma_tt_update(rc4030State *s, uint32_t new_tl_base,
&s->dma_tt_alias); &s->dma_tt_alias);
memory_region_transaction_commit(); memory_region_transaction_commit();
} else { } else {
memory_region_init(&s->dma_tt_alias, NULL, memory_region_init(&s->dma_tt_alias, OBJECT(s),
"dma-table-alias", 0); "dma-table-alias", 0);
} }
} }
@ -577,9 +584,9 @@ static const MemoryRegionOps jazzio_ops = {
.endianness = DEVICE_NATIVE_ENDIAN, .endianness = DEVICE_NATIVE_ENDIAN,
}; };
static void rc4030_reset(void *opaque) static void rc4030_reset(DeviceState *dev)
{ {
rc4030State *s = opaque; rc4030State *s = RC4030(dev);
int i; int i;
s->config = 0x410; /* some boards seem to accept 0x104 too */ s->config = 0x410; /* some boards seem to accept 0x104 too */
@ -733,46 +740,102 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n)
return s; return s;
} }
MemoryRegion *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, static void rc4030_initfn(Object *obj)
qemu_irq **irqs, rc4030_dma **dmas,
MemoryRegion *sysmem)
{ {
rc4030State *s; DeviceState *dev = DEVICE(obj);
rc4030State *s = RC4030(obj);
SysBusDevice *sysbus = SYS_BUS_DEVICE(obj);
qdev_init_gpio_in(dev, rc4030_irq_jazz_request, 16);
sysbus_init_irq(sysbus, &s->timer_irq);
sysbus_init_irq(sysbus, &s->jazz_bus_irq);
register_savevm(NULL, "rc4030", 0, 2, rc4030_save, rc4030_load, s);
sysbus_init_mmio(sysbus, &s->iomem_chipset);
sysbus_init_mmio(sysbus, &s->iomem_jazzio);
}
static void rc4030_realize(DeviceState *dev, Error **errp)
{
rc4030State *s = RC4030(dev);
Object *o = OBJECT(dev);
int i; int i;
s = g_malloc0(sizeof(rc4030State)); s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
rc4030_periodic_timer, s);
*irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
*dmas = rc4030_allocate_dmas(s, 4);
s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rc4030_periodic_timer, s);
s->timer_irq = timer;
s->jazz_bus_irq = jazz_bus;
qemu_register_reset(rc4030_reset, s);
register_savevm(NULL, "rc4030", 0, 2, rc4030_save, rc4030_load, s);
rc4030_reset(s);
memory_region_init_io(&s->iomem_chipset, NULL, &rc4030_ops, s, memory_region_init_io(&s->iomem_chipset, NULL, &rc4030_ops, s,
"rc4030.chipset", 0x300); "rc4030.chipset", 0x300);
memory_region_add_subregion(sysmem, 0x80000000, &s->iomem_chipset);
memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s, memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s,
"rc4030.jazzio", 0x00001000); "rc4030.jazzio", 0x00001000);
memory_region_add_subregion(sysmem, 0xf0000000, &s->iomem_jazzio);
memory_region_init_rom_device(&s->dma_tt, NULL, memory_region_init_rom_device(&s->dma_tt, o,
&rc4030_dma_tt_ops, s, "dma-table", &rc4030_dma_tt_ops, s, "dma-table",
MAX_TL_ENTRIES * sizeof(dma_pagetable_entry), MAX_TL_ENTRIES * sizeof(dma_pagetable_entry),
NULL); NULL);
memory_region_init(&s->dma_tt_alias, NULL, "dma-table-alias", 0); memory_region_init(&s->dma_tt_alias, o, "dma-table-alias", 0);
memory_region_init(&s->dma_mr, NULL, "dma", INT32_MAX); memory_region_init(&s->dma_mr, o, "dma", INT32_MAX);
for (i = 0; i < MAX_TL_ENTRIES; ++i) { for (i = 0; i < MAX_TL_ENTRIES; ++i) {
memory_region_init_alias(&s->dma_mrs[i], NULL, "dma-alias", memory_region_init_alias(&s->dma_mrs[i], o, "dma-alias",
get_system_memory(), 0, DMA_PAGESIZE); get_system_memory(), 0, DMA_PAGESIZE);
memory_region_set_enabled(&s->dma_mrs[i], false); memory_region_set_enabled(&s->dma_mrs[i], false);
memory_region_add_subregion(&s->dma_mr, i * DMA_PAGESIZE, memory_region_add_subregion(&s->dma_mr, i * DMA_PAGESIZE,
&s->dma_mrs[i]); &s->dma_mrs[i]);
} }
address_space_init(&s->dma_as, &s->dma_mr, "rc4030-dma"); address_space_init(&s->dma_as, &s->dma_mr, "rc4030-dma");
return &s->dma_mr; }
static void rc4030_unrealize(DeviceState *dev, Error **errp)
{
rc4030State *s = RC4030(dev);
int i;
timer_free(s->periodic_timer);
address_space_destroy(&s->dma_as);
object_unparent(OBJECT(&s->dma_tt));
object_unparent(OBJECT(&s->dma_tt_alias));
object_unparent(OBJECT(&s->dma_mr));
for (i = 0; i < MAX_TL_ENTRIES; ++i) {
memory_region_del_subregion(&s->dma_mr, &s->dma_mrs[i]);
object_unparent(OBJECT(&s->dma_mrs[i]));
}
}
static void rc4030_class_init(ObjectClass *klass, void *class_data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = rc4030_realize;
dc->unrealize = rc4030_unrealize;
dc->reset = rc4030_reset;
}
static const TypeInfo rc4030_info = {
.name = TYPE_RC4030,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(rc4030State),
.instance_init = rc4030_initfn,
.class_init = rc4030_class_init,
};
static void rc4030_register_types(void)
{
type_register_static(&rc4030_info);
}
type_init(rc4030_register_types)
DeviceState *rc4030_init(rc4030_dma **dmas, MemoryRegion **dma_mr)
{
DeviceState *dev;
dev = qdev_create(NULL, TYPE_RC4030);
qdev_init_nofail(dev);
*dmas = rc4030_allocate_dmas(dev, 4);
*dma_mr = &RC4030(dev)->dma_mr;
return dev;
} }

View File

@ -135,7 +135,7 @@ static void mips_jazz_init(MachineState *machine,
MIPSCPU *cpu; MIPSCPU *cpu;
CPUClass *cc; CPUClass *cc;
CPUMIPSState *env; CPUMIPSState *env;
qemu_irq *rc4030, *i8259; qemu_irq *i8259;
rc4030_dma *dmas; rc4030_dma *dmas;
MemoryRegion *rc4030_dma_mr; MemoryRegion *rc4030_dma_mr;
MemoryRegion *isa_mem = g_new(MemoryRegion, 1); MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
@ -144,7 +144,7 @@ static void mips_jazz_init(MachineState *machine,
MemoryRegion *i8042 = g_new(MemoryRegion, 1); MemoryRegion *i8042 = g_new(MemoryRegion, 1);
MemoryRegion *dma_dummy = g_new(MemoryRegion, 1); MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
NICInfo *nd; NICInfo *nd;
DeviceState *dev; DeviceState *dev, *rc4030;
SysBusDevice *sysbus; SysBusDevice *sysbus;
ISABus *isa_bus; ISABus *isa_bus;
ISADevice *pit; ISADevice *pit;
@ -213,8 +213,14 @@ static void mips_jazz_init(MachineState *machine,
cpu_mips_clock_init(env); cpu_mips_clock_init(env);
/* Chipset */ /* Chipset */
rc4030_dma_mr = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas, rc4030 = rc4030_init(&dmas, &rc4030_dma_mr);
address_space); sysbus = SYS_BUS_DEVICE(rc4030);
sysbus_connect_irq(sysbus, 0, env->irq[6]);
sysbus_connect_irq(sysbus, 1, env->irq[3]);
memory_region_add_subregion(address_space, 0x80000000,
sysbus_mmio_get_region(sysbus, 0));
memory_region_add_subregion(address_space, 0xf0000000,
sysbus_mmio_get_region(sysbus, 1));
memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000); memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000);
memory_region_add_subregion(address_space, 0x8000d000, dma_dummy); memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
@ -241,7 +247,7 @@ static void mips_jazz_init(MachineState *machine,
sysbus = SYS_BUS_DEVICE(dev); sysbus = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(sysbus, 0, 0x60080000); sysbus_mmio_map(sysbus, 0, 0x60080000);
sysbus_mmio_map(sysbus, 1, 0x40000000); sysbus_mmio_map(sysbus, 1, 0x40000000);
sysbus_connect_irq(sysbus, 0, rc4030[3]); sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 3));
{ {
/* Simple ROM, so user doesn't have to provide one */ /* Simple ROM, so user doesn't have to provide one */
MemoryRegion *rom_mr = g_new(MemoryRegion, 1); MemoryRegion *rom_mr = g_new(MemoryRegion, 1);
@ -267,8 +273,8 @@ static void mips_jazz_init(MachineState *machine,
if (!nd->model) if (!nd->model)
nd->model = g_strdup("dp83932"); nd->model = g_strdup("dp83932");
if (strcmp(nd->model, "dp83932") == 0) { if (strcmp(nd->model, "dp83932") == 0) {
dp83932_init(nd, 0x80001000, 2, get_system_memory(), rc4030[4], dp83932_init(nd, 0x80001000, 2, get_system_memory(),
rc4030_dma_mr); qdev_get_gpio_in(rc4030, 4), rc4030_dma_mr);
break; break;
} else if (is_help_option(nd->model)) { } else if (is_help_option(nd->model)) {
fprintf(stderr, "qemu: Supported NICs: dp83932\n"); fprintf(stderr, "qemu: Supported NICs: dp83932\n");
@ -282,7 +288,7 @@ static void mips_jazz_init(MachineState *machine,
/* SCSI adapter */ /* SCSI adapter */
esp_init(0x80002000, 0, esp_init(0x80002000, 0,
rc4030_dma_read, rc4030_dma_write, dmas[0], rc4030_dma_read, rc4030_dma_write, dmas[0],
rc4030[5], &esp_reset, &dma_enable); qdev_get_gpio_in(rc4030, 5), &esp_reset, &dma_enable);
/* Floppy */ /* Floppy */
if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) { if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) {
@ -292,7 +298,7 @@ static void mips_jazz_init(MachineState *machine,
for (n = 0; n < MAX_FD; n++) { for (n = 0; n < MAX_FD; n++) {
fds[n] = drive_get(IF_FLOPPY, 0, n); fds[n] = drive_get(IF_FLOPPY, 0, n);
} }
fdctrl_init_sysbus(rc4030[1], 0, 0x80003000, fds); fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), 0, 0x80003000, fds);
/* Real time clock */ /* Real time clock */
rtc_init(isa_bus, 1980, NULL); rtc_init(isa_bus, 1980, NULL);
@ -300,23 +306,26 @@ static void mips_jazz_init(MachineState *machine,
memory_region_add_subregion(address_space, 0x80004000, rtc); memory_region_add_subregion(address_space, 0x80004000, rtc);
/* Keyboard (i8042) */ /* Keyboard (i8042) */
i8042_mm_init(rc4030[6], rc4030[7], i8042, 0x1000, 0x1); i8042_mm_init(qdev_get_gpio_in(rc4030, 6), qdev_get_gpio_in(rc4030, 7),
i8042, 0x1000, 0x1);
memory_region_add_subregion(address_space, 0x80005000, i8042); memory_region_add_subregion(address_space, 0x80005000, i8042);
/* Serial ports */ /* Serial ports */
if (serial_hds[0]) { if (serial_hds[0]) {
serial_mm_init(address_space, 0x80006000, 0, rc4030[8], 8000000/16, serial_mm_init(address_space, 0x80006000, 0,
qdev_get_gpio_in(rc4030, 8), 8000000/16,
serial_hds[0], DEVICE_NATIVE_ENDIAN); serial_hds[0], DEVICE_NATIVE_ENDIAN);
} }
if (serial_hds[1]) { if (serial_hds[1]) {
serial_mm_init(address_space, 0x80007000, 0, rc4030[9], 8000000/16, serial_mm_init(address_space, 0x80007000, 0,
qdev_get_gpio_in(rc4030, 9), 8000000/16,
serial_hds[1], DEVICE_NATIVE_ENDIAN); serial_hds[1], DEVICE_NATIVE_ENDIAN);
} }
/* Parallel port */ /* Parallel port */
if (parallel_hds[0]) if (parallel_hds[0])
parallel_mm_init(address_space, 0x80008000, 0, rc4030[0], parallel_mm_init(address_space, 0x80008000, 0,
parallel_hds[0]); qdev_get_gpio_in(rc4030, 0), parallel_hds[0]);
/* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */ /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */

View File

@ -18,9 +18,7 @@ typedef struct rc4030DMAState *rc4030_dma;
void rc4030_dma_read(void *dma, uint8_t *buf, int len); void rc4030_dma_read(void *dma, uint8_t *buf, int len);
void rc4030_dma_write(void *dma, uint8_t *buf, int len); void rc4030_dma_write(void *dma, uint8_t *buf, int len);
MemoryRegion *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, DeviceState *rc4030_init(rc4030_dma **dmas, MemoryRegion **dma_mr);
qemu_irq **irqs, rc4030_dma **dmas,
MemoryRegion *sysmem);
/* dp8393x.c */ /* dp8393x.c */
void dp83932_init(NICInfo *nd, hwaddr base, int it_shift, void dp83932_init(NICInfo *nd, hwaddr base, int it_shift,