From fd9bdbd3459e5b9d51534f0747049bc5b6145e07 Mon Sep 17 00:00:00 2001 From: John Snow Date: Wed, 3 Feb 2016 11:28:55 -0500 Subject: [PATCH 01/20] fdc: fix detection under Linux Accidentally, I removed a "feature" where empty drives had geometry values applied to them, which allows seek on empty drives to work "by accident," as QEMU actually tries to disallow that. Seeks on empty drives should work, though, but the easiest thing is to restore the misfeature where empty drives have non-zero geometries applied. Document the hack accordingly. [Maintainer edit] This fix corrects a regression introduced in d5d47efc, where pick_geometry was modified such that it would not operate on empty drives, and as a result if there is no diskette inserted, QEMU no longer populates it with geometry bounds. As a result, seek fails when QEMU denies to move the current track, but reports success anyway. This can confuse the guest, leading to kernel panics in the guest. Signed-off-by: John Snow Reviewed-by: Eric Blake Message-id: 1454106932-17236-1-git-send-email-jsnow@redhat.com --- hw/block/fdc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 818e8a4072..9ef899d91f 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -179,6 +179,21 @@ typedef struct FDrive { static FloppyDriveType get_fallback_drive_type(FDrive *drv); +/* Hack: FD_SEEK is expected to work on empty drives. However, QEMU + * currently goes through some pains to keep seeks within the bounds + * established by last_sect and max_track. Correcting this is difficult, + * as refactoring FDC code tends to expose nasty bugs in the Linux kernel. + * + * For now: allow empty drives to have large bounds so we can seek around, + * with the understanding that when a diskette is inserted, the bounds will + * properly tighten to match the geometry of that inserted medium. + */ +static void fd_empty_seek_hack(FDrive *drv) +{ + drv->last_sect = 0xFF; + drv->max_track = 0xFF; +} + static void fd_init(FDrive *drv) { /* Drive */ @@ -394,6 +409,7 @@ static void fd_revalidate(FDrive *drv) if (!blk_is_inserted(drv->blk)) { FLOPPY_DPRINTF("No disk in drive\n"); drv->disk = FLOPPY_DRIVE_TYPE_NONE; + fd_empty_seek_hack(drv); } else if (!drv->media_validated) { rc = pick_geometry(drv); if (rc) { From 449ae7eca922c7bb65730cab60f6c8a23cc47cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:55 -0500 Subject: [PATCH 02/20] i82374: device only existed as ISA device, so simplify device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge ISAi82374State fields into parent structure I82374State. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-2-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i82374.c | 58 ++++++++++++++++--------------------------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c index 869721d848..031a3f566d 100644 --- a/hw/dma/i82374.c +++ b/hw/dma/i82374.c @@ -25,6 +25,9 @@ #include "qemu/osdep.h" #include "hw/isa/isa.h" +#define TYPE_I82374 "i82374" +#define I82374(obj) OBJECT_CHECK(I82374State, (obj), TYPE_I82374) + //#define DEBUG_I82374 #ifdef DEBUG_I82374 @@ -38,6 +41,9 @@ do {} while (0) do { fprintf(stderr, "i82374 ERROR: " fmt , ## __VA_ARGS__); } while (0) typedef struct I82374State { + ISADevice parent_obj; + + uint32_t iobase; uint8_t commands[8]; PortioList port_list; } I82374State; @@ -99,32 +105,6 @@ static uint32_t i82374_read_descriptor(void *opaque, uint32_t nport) return val; } -static void i82374_realize(I82374State *s, Error **errp) -{ - DMA_init(1); - memset(s->commands, 0, sizeof(s->commands)); -} - -#define TYPE_I82374 "i82374" -#define I82374(obj) OBJECT_CHECK(ISAi82374State, (obj), TYPE_I82374) - -typedef struct ISAi82374State { - ISADevice parent_obj; - - uint32_t iobase; - I82374State state; -} ISAi82374State; - -static const VMStateDescription vmstate_isa_i82374 = { - .name = "isa-i82374", - .version_id = 0, - .minimum_version_id = 0, - .fields = (VMStateField[]) { - VMSTATE_STRUCT(state, ISAi82374State, 0, vmstate_i82374, I82374State), - VMSTATE_END_OF_LIST() - }, -}; - static const MemoryRegionPortio i82374_portio_list[] = { { 0x0A, 1, 1, .read = i82374_read_isr, }, { 0x10, 8, 1, .write = i82374_write_command, }, @@ -134,21 +114,21 @@ static const MemoryRegionPortio i82374_portio_list[] = { PORTIO_END_OF_LIST(), }; -static void i82374_isa_realize(DeviceState *dev, Error **errp) +static void i82374_realize(DeviceState *dev, Error **errp) { - ISAi82374State *isa = I82374(dev); - I82374State *s = &isa->state; + I82374State *s = I82374(dev); - portio_list_init(&s->port_list, OBJECT(isa), i82374_portio_list, s, + portio_list_init(&s->port_list, OBJECT(s), i82374_portio_list, s, "i82374"); - portio_list_add(&s->port_list, isa_address_space_io(&isa->parent_obj), - isa->iobase); + portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj), + s->iobase); - i82374_realize(s, errp); + DMA_init(1); + memset(s->commands, 0, sizeof(s->commands)); } static Property i82374_properties[] = { - DEFINE_PROP_UINT32("iobase", ISAi82374State, iobase, 0x400), + DEFINE_PROP_UINT32("iobase", I82374State, iobase, 0x400), DEFINE_PROP_END_OF_LIST() }; @@ -156,21 +136,21 @@ static void i82374_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->realize = i82374_isa_realize; - dc->vmsd = &vmstate_isa_i82374; + dc->realize = i82374_realize; + dc->vmsd = &vmstate_i82374; dc->props = i82374_properties; } -static const TypeInfo i82374_isa_info = { +static const TypeInfo i82374_info = { .name = TYPE_I82374, .parent = TYPE_ISA_DEVICE, - .instance_size = sizeof(ISAi82374State), + .instance_size = sizeof(I82374State), .class_init = i82374_class_init, }; static void i82374_register_types(void) { - type_register_static(&i82374_isa_info); + type_register_static(&i82374_info); } type_init(i82374_register_types) From 57146941924a4189b14cbc1c87478b2ffef31943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:55 -0500 Subject: [PATCH 03/20] i8257: pass ISA bus to DMA_init() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i8257 DMA controller exists on one ISA bus, so let's specify it at initialization. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-3-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i82374.c | 2 +- hw/dma/i8257.c | 2 +- hw/i386/pc.c | 2 +- hw/mips/mips_fulong2e.c | 2 +- hw/mips/mips_jazz.c | 2 +- hw/mips/mips_malta.c | 2 +- hw/sparc/sun4m.c | 2 +- hw/sparc64/sun4u.c | 2 +- include/hw/isa/isa.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c index 031a3f566d..6c0f975df0 100644 --- a/hw/dma/i82374.c +++ b/hw/dma/i82374.c @@ -123,7 +123,7 @@ static void i82374_realize(DeviceState *dev, Error **errp) portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj), s->iobase); - DMA_init(1); + DMA_init(isa_bus_from_device(ISA_DEVICE(dev)), 1); memset(s->commands, 0, sizeof(s->commands)); } diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index 1ff6c4da71..bb6945a2c5 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -589,7 +589,7 @@ static const VMStateDescription vmstate_dma = { } }; -void DMA_init(int high_page_enable) +void DMA_init(ISABus *bus, int high_page_enable) { dma_init2(&dma_controllers[0], 0x00, 0, 0x80, high_page_enable ? 0x480 : -1); dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, high_page_enable ? 0x488 : -1); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 942ac0659a..b28bac4b66 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1542,7 +1542,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, port92 = isa_create_simple(isa_bus, "port92"); port92_init(port92, &a20_line[1]); - DMA_init(0); + DMA_init(isa_bus, 0); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index 6748d89478..184c404454 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -366,7 +366,7 @@ static void mips_fulong2e_init(MachineState *machine) /* init other devices */ pit = pit_init(isa_bus, 0x40, 0, NULL); - DMA_init(0); + DMA_init(isa_bus, 0); /* Super I/O */ isa_create_simple(isa_bus, "i8042"); diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 62527fdbe8..a199b9d18a 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -225,7 +225,7 @@ static void mips_jazz_init(MachineState *machine, /* ISA devices */ i8259 = i8259_init(isa_bus, env->irq[4]); isa_bus_irqs(isa_bus, i8259); - DMA_init(0); + DMA_init(isa_bus, 0); pit = pit_init(isa_bus, 0x40, 0, NULL); pcspk_init(isa_bus, pit); diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index c5da83fde8..c04aa2b8cc 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1166,7 +1166,7 @@ void mips_malta_init(MachineState *machine) smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size); g_free(smbus_eeprom_buf); pit = pit_init(isa_bus, 0x40, 0, NULL); - DMA_init(0); + DMA_init(isa_bus, 0); /* Super I/O */ isa_create_simple(isa_bus, "i8042"); diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 1fcec4478f..9c078d5639 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -112,7 +112,7 @@ void DMA_hold_DREQ (int nchan) {} void DMA_release_DREQ (int nchan) {} void DMA_schedule(void) {} -void DMA_init(int high_page_enable) +void DMA_init(ISABus *bus, int high_page_enable) { } diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 124c376897..d356717c08 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -115,7 +115,7 @@ void DMA_hold_DREQ (int nchan) {} void DMA_release_DREQ (int nchan) {} void DMA_schedule(void) {} -void DMA_init(int high_page_enable) +void DMA_init(ISABus *bus, int high_page_enable) { } diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index de3cd3d38a..4af87303a4 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -113,7 +113,7 @@ int DMA_write_memory (int nchan, void *buf, int pos, int size); void DMA_hold_DREQ (int nchan); void DMA_release_DREQ (int nchan); void DMA_schedule(void); -void DMA_init(int high_page_enable); +void DMA_init(ISABus *bus, int high_page_enable); void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, void *opaque); From 6a128b133014be70413b702eecc8ba85a79c2144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:55 -0500 Subject: [PATCH 04/20] i8257: rename struct dma_cont to I8257State MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-4-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index bb6945a2c5..e560a2f74b 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -53,7 +53,7 @@ struct dma_regs { #define ADDR 0 #define COUNT 1 -static struct dma_cont { +typedef struct I8257State { uint8_t status; uint8_t command; uint8_t mask; @@ -62,7 +62,9 @@ static struct dma_cont { struct dma_regs regs[4]; MemoryRegion channel_io; MemoryRegion cont_io; -} dma_controllers[2]; +} I8257State; + +static I8257State dma_controllers[2]; enum { CMD_MEMORY_TO_MEMORY = 0x01, @@ -85,7 +87,7 @@ static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0}; static void write_page (void *opaque, uint32_t nport, uint32_t data) { - struct dma_cont *d = opaque; + I8257State *d = opaque; int ichan; ichan = channels[nport & 7]; @@ -98,7 +100,7 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data) static void write_pageh (void *opaque, uint32_t nport, uint32_t data) { - struct dma_cont *d = opaque; + I8257State *d = opaque; int ichan; ichan = channels[nport & 7]; @@ -111,7 +113,7 @@ static void write_pageh (void *opaque, uint32_t nport, uint32_t data) static uint32_t read_page (void *opaque, uint32_t nport) { - struct dma_cont *d = opaque; + I8257State *d = opaque; int ichan; ichan = channels[nport & 7]; @@ -124,7 +126,7 @@ static uint32_t read_page (void *opaque, uint32_t nport) static uint32_t read_pageh (void *opaque, uint32_t nport) { - struct dma_cont *d = opaque; + I8257State *d = opaque; int ichan; ichan = channels[nport & 7]; @@ -135,7 +137,7 @@ static uint32_t read_pageh (void *opaque, uint32_t nport) return d->regs[ichan].pageh; } -static inline void init_chan (struct dma_cont *d, int ichan) +static inline void init_chan(I8257State *d, int ichan) { struct dma_regs *r; @@ -144,7 +146,7 @@ static inline void init_chan (struct dma_cont *d, int ichan) r->now[COUNT] = 0; } -static inline int getff (struct dma_cont *d) +static inline int getff(I8257State *d) { int ff; @@ -155,7 +157,7 @@ static inline int getff (struct dma_cont *d) static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size) { - struct dma_cont *d = opaque; + I8257State *d = opaque; int ichan, nreg, iport, ff, val, dir; struct dma_regs *r; @@ -178,7 +180,7 @@ static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size) static void write_chan(void *opaque, hwaddr nport, uint64_t data, unsigned size) { - struct dma_cont *d = opaque; + I8257State *d = opaque; int iport, ichan, nreg; struct dma_regs *r; @@ -197,7 +199,7 @@ static void write_chan(void *opaque, hwaddr nport, uint64_t data, static void write_cont(void *opaque, hwaddr nport, uint64_t data, unsigned size) { - struct dma_cont *d = opaque; + I8257State *d = opaque; int iport, ichan = 0; iport = (nport >> d->dshift) & 0x0f; @@ -285,7 +287,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data, static uint64_t read_cont(void *opaque, hwaddr nport, unsigned size) { - struct dma_cont *d = opaque; + I8257State *d = opaque; int iport, val; iport = (nport >> d->dshift) & 0x0f; @@ -362,7 +364,7 @@ static bool dma_bh_scheduled; static void DMA_run (void) { - struct dma_cont *d; + I8257State *d; int icont, ichan; int rearm = 0; static int running = 0; @@ -474,7 +476,7 @@ void DMA_schedule(void) static void dma_reset(void *opaque) { - struct dma_cont *d = opaque; + I8257State *d = opaque; write_cont(d, (0x05 << d->dshift), 0, 1); } @@ -520,7 +522,7 @@ static const MemoryRegionOps cont_io_ops = { }; /* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */ -static void dma_init2(struct dma_cont *d, int base, int dshift, +static void dma_init2(I8257State *d, int base, int dshift, int page_base, int pageh_base) { int i; @@ -580,11 +582,12 @@ static const VMStateDescription vmstate_dma = { .minimum_version_id = 1, .post_load = dma_post_load, .fields = (VMStateField[]) { - VMSTATE_UINT8(command, struct dma_cont), - VMSTATE_UINT8(mask, struct dma_cont), - VMSTATE_UINT8(flip_flop, struct dma_cont), - VMSTATE_INT32(dshift, struct dma_cont), - VMSTATE_STRUCT_ARRAY(regs, struct dma_cont, 4, 1, vmstate_dma_regs, struct dma_regs), + VMSTATE_UINT8(command, I8257State), + VMSTATE_UINT8(mask, I8257State), + VMSTATE_UINT8(flip_flop, I8257State), + VMSTATE_INT32(dshift, I8257State), + VMSTATE_STRUCT_ARRAY(regs, I8257State, 4, 1, vmstate_dma_regs, + struct dma_regs), VMSTATE_END_OF_LIST() } }; From 0eee6d6262435685a7a225b19e3580dfc0ab07f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:55 -0500 Subject: [PATCH 05/20] i8257: rename struct dma_regs to I8257Regs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-5-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index e560a2f74b..bf43977e6f 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -38,7 +38,7 @@ #define ldebug(...) #endif -struct dma_regs { +typedef struct I8257Regs { int now[2]; uint16_t base[2]; uint8_t mode; @@ -48,7 +48,7 @@ struct dma_regs { uint8_t eop; DMA_transfer_handler transfer_handler; void *opaque; -}; +} I8257Regs; #define ADDR 0 #define COUNT 1 @@ -59,7 +59,7 @@ typedef struct I8257State { uint8_t mask; uint8_t flip_flop; int dshift; - struct dma_regs regs[4]; + I8257Regs regs[4]; MemoryRegion channel_io; MemoryRegion cont_io; } I8257State; @@ -139,7 +139,7 @@ static uint32_t read_pageh (void *opaque, uint32_t nport) static inline void init_chan(I8257State *d, int ichan) { - struct dma_regs *r; + I8257Regs *r; r = d->regs + ichan; r->now[ADDR] = r->base[ADDR] << d->dshift; @@ -159,7 +159,7 @@ static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size) { I8257State *d = opaque; int ichan, nreg, iport, ff, val, dir; - struct dma_regs *r; + I8257Regs *r; iport = (nport >> d->dshift) & 0x0f; ichan = iport >> 1; @@ -182,7 +182,7 @@ static void write_chan(void *opaque, hwaddr nport, uint64_t data, { I8257State *d = opaque; int iport, ichan, nreg; - struct dma_regs *r; + I8257Regs *r; iport = (nport >> d->dshift) & 0x0f; ichan = iport >> 1; @@ -338,7 +338,7 @@ void DMA_release_DREQ (int nchan) static void channel_run (int ncont, int ichan) { int n; - struct dma_regs *r = &dma_controllers[ncont].regs[ichan]; + I8257Regs *r = &dma_controllers[ncont].regs[ichan]; #ifdef DEBUG_DMA int dir, opmode; @@ -409,7 +409,7 @@ void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, void *opaque) { - struct dma_regs *r; + I8257Regs *r; int ichan, ncont; ncont = nchan > 3; @@ -422,7 +422,7 @@ void DMA_register_channel (int nchan, int DMA_read_memory (int nchan, void *buf, int pos, int len) { - struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; + I8257Regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; if (r->mode & 0x20) { @@ -444,7 +444,7 @@ int DMA_read_memory (int nchan, void *buf, int pos, int len) int DMA_write_memory (int nchan, void *buf, int pos, int len) { - struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; + I8257Regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; if (r->mode & 0x20) { @@ -553,18 +553,18 @@ static void dma_init2(I8257State *d, int base, int dshift, } } -static const VMStateDescription vmstate_dma_regs = { +static const VMStateDescription vmstate_i8257_regs = { .name = "dma_regs", .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_INT32_ARRAY(now, struct dma_regs, 2), - VMSTATE_UINT16_ARRAY(base, struct dma_regs, 2), - VMSTATE_UINT8(mode, struct dma_regs), - VMSTATE_UINT8(page, struct dma_regs), - VMSTATE_UINT8(pageh, struct dma_regs), - VMSTATE_UINT8(dack, struct dma_regs), - VMSTATE_UINT8(eop, struct dma_regs), + VMSTATE_INT32_ARRAY(now, I8257Regs, 2), + VMSTATE_UINT16_ARRAY(base, I8257Regs, 2), + VMSTATE_UINT8(mode, I8257Regs), + VMSTATE_UINT8(page, I8257Regs), + VMSTATE_UINT8(pageh, I8257Regs), + VMSTATE_UINT8(dack, I8257Regs), + VMSTATE_UINT8(eop, I8257Regs), VMSTATE_END_OF_LIST() } }; @@ -586,8 +586,8 @@ static const VMStateDescription vmstate_dma = { VMSTATE_UINT8(mask, I8257State), VMSTATE_UINT8(flip_flop, I8257State), VMSTATE_INT32(dshift, I8257State), - VMSTATE_STRUCT_ARRAY(regs, I8257State, 4, 1, vmstate_dma_regs, - struct dma_regs), + VMSTATE_STRUCT_ARRAY(regs, I8257State, 4, 1, vmstate_i8257_regs, + I8257Regs), VMSTATE_END_OF_LIST() } }; From 74c47de010d6ffb1980ef67b5e381ba8324e19e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:56 -0500 Subject: [PATCH 06/20] i8257: rename functions to start with i8257_ prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-6-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 91 +++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index bf43977e6f..e4262bec26 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -81,11 +81,11 @@ enum { }; -static void DMA_run (void); +static void i8257_dma_run(void); static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0}; -static void write_page (void *opaque, uint32_t nport, uint32_t data) +static void i8257_write_page(void *opaque, uint32_t nport, uint32_t data) { I8257State *d = opaque; int ichan; @@ -98,7 +98,7 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data) d->regs[ichan].page = data; } -static void write_pageh (void *opaque, uint32_t nport, uint32_t data) +static void i8257_write_pageh(void *opaque, uint32_t nport, uint32_t data) { I8257State *d = opaque; int ichan; @@ -111,7 +111,7 @@ static void write_pageh (void *opaque, uint32_t nport, uint32_t data) d->regs[ichan].pageh = data; } -static uint32_t read_page (void *opaque, uint32_t nport) +static uint32_t i8257_read_page(void *opaque, uint32_t nport) { I8257State *d = opaque; int ichan; @@ -124,7 +124,7 @@ static uint32_t read_page (void *opaque, uint32_t nport) return d->regs[ichan].page; } -static uint32_t read_pageh (void *opaque, uint32_t nport) +static uint32_t i8257_read_pageh(void *opaque, uint32_t nport) { I8257State *d = opaque; int ichan; @@ -137,7 +137,7 @@ static uint32_t read_pageh (void *opaque, uint32_t nport) return d->regs[ichan].pageh; } -static inline void init_chan(I8257State *d, int ichan) +static inline void i8257_init_chan(I8257State *d, int ichan) { I8257Regs *r; @@ -146,7 +146,7 @@ static inline void init_chan(I8257State *d, int ichan) r->now[COUNT] = 0; } -static inline int getff(I8257State *d) +static inline int i8257_getff(I8257State *d) { int ff; @@ -155,7 +155,7 @@ static inline int getff(I8257State *d) return ff; } -static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size) +static uint64_t i8257_read_chan(void *opaque, hwaddr nport, unsigned size) { I8257State *d = opaque; int ichan, nreg, iport, ff, val, dir; @@ -167,7 +167,7 @@ static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size) r = d->regs + ichan; dir = ((r->mode >> 5) & 1) ? -1 : 1; - ff = getff (d); + ff = i8257_getff(d); if (nreg) val = (r->base[COUNT] << d->dshift) - r->now[COUNT]; else @@ -177,8 +177,8 @@ static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size) return (val >> (d->dshift + (ff << 3))) & 0xff; } -static void write_chan(void *opaque, hwaddr nport, uint64_t data, - unsigned size) +static void i8257_write_chan(void *opaque, hwaddr nport, uint64_t data, + unsigned int size) { I8257State *d = opaque; int iport, ichan, nreg; @@ -188,16 +188,16 @@ static void write_chan(void *opaque, hwaddr nport, uint64_t data, ichan = iport >> 1; nreg = iport & 1; r = d->regs + ichan; - if (getff (d)) { + if (i8257_getff(d)) { r->base[nreg] = (r->base[nreg] & 0xff) | ((data << 8) & 0xff00); - init_chan (d, ichan); + i8257_init_chan(d, ichan); } else { r->base[nreg] = (r->base[nreg] & 0xff00) | (data & 0xff); } } -static void write_cont(void *opaque, hwaddr nport, uint64_t data, - unsigned size) +static void i8257_write_cont(void *opaque, hwaddr nport, uint64_t data, + unsigned int size) { I8257State *d = opaque; int iport, ichan = 0; @@ -221,7 +221,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data, d->status &= ~(1 << (ichan + 4)); } d->status &= ~(1 << ichan); - DMA_run(); + i8257_dma_run(); break; case 0x02: /* single mask */ @@ -229,7 +229,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data, d->mask |= 1 << (data & 3); else d->mask &= ~(1 << (data & 3)); - DMA_run(); + i8257_dma_run(); break; case 0x03: /* mode */ @@ -264,12 +264,12 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data, case 0x06: /* clear mask for all channels */ d->mask = 0; - DMA_run(); + i8257_dma_run(); break; case 0x07: /* write mask for all channels */ d->mask = data; - DMA_run(); + i8257_dma_run(); break; default: @@ -285,7 +285,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data, #endif } -static uint64_t read_cont(void *opaque, hwaddr nport, unsigned size) +static uint64_t i8257_read_cont(void *opaque, hwaddr nport, unsigned size) { I8257State *d = opaque; int iport, val; @@ -321,7 +321,7 @@ void DMA_hold_DREQ (int nchan) ichan = nchan & 3; linfo ("held cont=%d chan=%d\n", ncont, ichan); dma_controllers[ncont].status |= 1 << (ichan + 4); - DMA_run(); + i8257_dma_run(); } void DMA_release_DREQ (int nchan) @@ -332,10 +332,10 @@ void DMA_release_DREQ (int nchan) ichan = nchan & 3; linfo ("released cont=%d chan=%d\n", ncont, ichan); dma_controllers[ncont].status &= ~(1 << (ichan + 4)); - DMA_run(); + i8257_dma_run(); } -static void channel_run (int ncont, int ichan) +static void i8257_channel_run(int ncont, int ichan) { int n; I8257Regs *r = &dma_controllers[ncont].regs[ichan]; @@ -362,7 +362,7 @@ static void channel_run (int ncont, int ichan) static QEMUBH *dma_bh; static bool dma_bh_scheduled; -static void DMA_run (void) +static void i8257_dma_run(void) { I8257State *d; int icont, ichan; @@ -385,7 +385,7 @@ static void DMA_run (void) mask = 1 << ichan; if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4)))) { - channel_run (icont, ichan); + i8257_channel_run(icont, ichan); rearm = 1; } } @@ -399,10 +399,10 @@ out: } } -static void DMA_run_bh(void *unused) +static void i8257_dma_run_bh(void *unused) { dma_bh_scheduled = false; - DMA_run(); + i8257_dma_run(); } void DMA_register_channel (int nchan, @@ -474,13 +474,14 @@ void DMA_schedule(void) } } -static void dma_reset(void *opaque) +static void i8257_reset(void *opaque) { I8257State *d = opaque; - write_cont(d, (0x05 << d->dshift), 0, 1); + i8257_write_cont(d, (0x05 << d->dshift), 0, 1); } -static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len) +static int i8257_phony_handler(void *opaque, int nchan, int dma_pos, + int dma_len) { trace_i8257_unregistered_dma(nchan, dma_pos, dma_len); return dma_pos; @@ -488,8 +489,8 @@ static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len) static const MemoryRegionOps channel_io_ops = { - .read = read_chan, - .write = write_chan, + .read = i8257_read_chan, + .write = i8257_write_chan, .endianness = DEVICE_NATIVE_ENDIAN, .impl = { .min_access_size = 1, @@ -499,21 +500,21 @@ static const MemoryRegionOps channel_io_ops = { /* IOport from page_base */ static const MemoryRegionPortio page_portio_list[] = { - { 0x01, 3, 1, .write = write_page, .read = read_page, }, - { 0x07, 1, 1, .write = write_page, .read = read_page, }, + { 0x01, 3, 1, .write = i8257_write_page, .read = i8257_read_page, }, + { 0x07, 1, 1, .write = i8257_write_page, .read = i8257_read_page, }, PORTIO_END_OF_LIST(), }; /* IOport from pageh_base */ static const MemoryRegionPortio pageh_portio_list[] = { - { 0x01, 3, 1, .write = write_pageh, .read = read_pageh, }, - { 0x07, 3, 1, .write = write_pageh, .read = read_pageh, }, + { 0x01, 3, 1, .write = i8257_write_pageh, .read = i8257_read_pageh, }, + { 0x07, 3, 1, .write = i8257_write_pageh, .read = i8257_read_pageh, }, PORTIO_END_OF_LIST(), }; static const MemoryRegionOps cont_io_ops = { - .read = read_cont, - .write = write_cont, + .read = i8257_read_cont, + .write = i8257_write_cont, .endianness = DEVICE_NATIVE_ENDIAN, .impl = { .min_access_size = 1, @@ -546,10 +547,10 @@ static void dma_init2(I8257State *d, int base, int dshift, memory_region_add_subregion(isa_address_space_io(NULL), base + (8 << d->dshift), &d->cont_io); - qemu_register_reset(dma_reset, d); - dma_reset(d); + qemu_register_reset(i8257_reset, d); + i8257_reset(d); for (i = 0; i < ARRAY_SIZE (d->regs); ++i) { - d->regs[i].transfer_handler = dma_phony_handler; + d->regs[i].transfer_handler = i8257_phony_handler; } } @@ -569,9 +570,9 @@ static const VMStateDescription vmstate_i8257_regs = { } }; -static int dma_post_load(void *opaque, int version_id) +static int i8257_post_load(void *opaque, int version_id) { - DMA_run(); + i8257_dma_run(); return 0; } @@ -580,7 +581,7 @@ static const VMStateDescription vmstate_dma = { .name = "dma", .version_id = 1, .minimum_version_id = 1, - .post_load = dma_post_load, + .post_load = i8257_post_load, .fields = (VMStateField[]) { VMSTATE_UINT8(command, I8257State), VMSTATE_UINT8(mask, I8257State), @@ -599,5 +600,5 @@ void DMA_init(ISABus *bus, int high_page_enable) vmstate_register (NULL, 0, &vmstate_dma, &dma_controllers[0]); vmstate_register (NULL, 1, &vmstate_dma, &dma_controllers[1]); - dma_bh = qemu_bh_new(DMA_run_bh, NULL); + dma_bh = qemu_bh_new(i8257_dma_run_bh, NULL); } From b9ebd28c629717386b02a8cc9c175f488f604d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:56 -0500 Subject: [PATCH 07/20] i8257: make the DMA running method per controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes some static/global variables, and we're now running only the required controller (master or slave) Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-7-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 75 +++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index e4262bec26..e577ed46c9 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -62,6 +62,10 @@ typedef struct I8257State { I8257Regs regs[4]; MemoryRegion channel_io; MemoryRegion cont_io; + + QEMUBH *dma_bh; + bool dma_bh_scheduled; + int running; } I8257State; static I8257State dma_controllers[2]; @@ -81,7 +85,7 @@ enum { }; -static void i8257_dma_run(void); +static void i8257_dma_run(void *opaque); static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0}; @@ -221,7 +225,7 @@ static void i8257_write_cont(void *opaque, hwaddr nport, uint64_t data, d->status &= ~(1 << (ichan + 4)); } d->status &= ~(1 << ichan); - i8257_dma_run(); + i8257_dma_run(d); break; case 0x02: /* single mask */ @@ -229,7 +233,7 @@ static void i8257_write_cont(void *opaque, hwaddr nport, uint64_t data, d->mask |= 1 << (data & 3); else d->mask &= ~(1 << (data & 3)); - i8257_dma_run(); + i8257_dma_run(d); break; case 0x03: /* mode */ @@ -264,12 +268,12 @@ static void i8257_write_cont(void *opaque, hwaddr nport, uint64_t data, case 0x06: /* clear mask for all channels */ d->mask = 0; - i8257_dma_run(); + i8257_dma_run(d); break; case 0x07: /* write mask for all channels */ d->mask = data; - i8257_dma_run(); + i8257_dma_run(d); break; default: @@ -321,7 +325,7 @@ void DMA_hold_DREQ (int nchan) ichan = nchan & 3; linfo ("held cont=%d chan=%d\n", ncont, ichan); dma_controllers[ncont].status |= 1 << (ichan + 4); - i8257_dma_run(); + i8257_dma_run(&dma_controllers[ncont]); } void DMA_release_DREQ (int nchan) @@ -332,13 +336,14 @@ void DMA_release_DREQ (int nchan) ichan = nchan & 3; linfo ("released cont=%d chan=%d\n", ncont, ichan); dma_controllers[ncont].status &= ~(1 << (ichan + 4)); - i8257_dma_run(); + i8257_dma_run(&dma_controllers[ncont]); } -static void i8257_channel_run(int ncont, int ichan) +static void i8257_channel_run(I8257State *d, int ichan) { + int ncont = d->dshift; int n; - I8257Regs *r = &dma_controllers[ncont].regs[ichan]; + I8257Regs *r = &d->regs[ichan]; #ifdef DEBUG_DMA int dir, opmode; @@ -359,52 +364,38 @@ static void i8257_channel_run(int ncont, int ichan) ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont); } -static QEMUBH *dma_bh; -static bool dma_bh_scheduled; - -static void i8257_dma_run(void) +static void i8257_dma_run(void *opaque) { - I8257State *d; - int icont, ichan; + I8257State *d = opaque; + int ichan; int rearm = 0; - static int running = 0; - if (running) { + if (d->running) { rearm = 1; goto out; } else { - running = 1; + d->running = 1; } - d = dma_controllers; + for (ichan = 0; ichan < 4; ichan++) { + int mask; - for (icont = 0; icont < 2; icont++, d++) { - for (ichan = 0; ichan < 4; ichan++) { - int mask; + mask = 1 << ichan; - mask = 1 << ichan; - - if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4)))) { - i8257_channel_run(icont, ichan); - rearm = 1; - } + if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4)))) { + i8257_channel_run(d, ichan); + rearm = 1; } } - running = 0; + d->running = 0; out: if (rearm) { - qemu_bh_schedule_idle(dma_bh); - dma_bh_scheduled = true; + qemu_bh_schedule_idle(d->dma_bh); + d->dma_bh_scheduled = true; } } -static void i8257_dma_run_bh(void *unused) -{ - dma_bh_scheduled = false; - i8257_dma_run(); -} - void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, void *opaque) @@ -469,7 +460,8 @@ int DMA_write_memory (int nchan, void *buf, int pos, int len) */ void DMA_schedule(void) { - if (dma_bh_scheduled) { + if (dma_controllers[0].dma_bh_scheduled || + dma_controllers[1].dma_bh_scheduled) { qemu_notify_event(); } } @@ -552,6 +544,8 @@ static void dma_init2(I8257State *d, int base, int dshift, for (i = 0; i < ARRAY_SIZE (d->regs); ++i) { d->regs[i].transfer_handler = i8257_phony_handler; } + + d->dma_bh = qemu_bh_new(i8257_dma_run, d); } static const VMStateDescription vmstate_i8257_regs = { @@ -572,7 +566,8 @@ static const VMStateDescription vmstate_i8257_regs = { static int i8257_post_load(void *opaque, int version_id) { - i8257_dma_run(); + I8257State *d = opaque; + i8257_dma_run(d); return 0; } @@ -599,6 +594,4 @@ void DMA_init(ISABus *bus, int high_page_enable) dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, high_page_enable ? 0x488 : -1); vmstate_register (NULL, 0, &vmstate_dma, &dma_controllers[0]); vmstate_register (NULL, 1, &vmstate_dma, &dma_controllers[1]); - - dma_bh = qemu_bh_new(i8257_dma_run_bh, NULL); } From 8d3c4c81f36f966d53923db23021487d903eee9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:56 -0500 Subject: [PATCH 08/20] i8257: add missing const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-8-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index e577ed46c9..0e5ebc14c8 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -87,7 +87,7 @@ enum { static void i8257_dma_run(void *opaque); -static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0}; +static const int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0}; static void i8257_write_page(void *opaque, uint32_t nport, uint32_t data) { From 340e19ebf2103317206b6910cd065bdbdea0d2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:56 -0500 Subject: [PATCH 09/20] i8257: QOM'ify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-9-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 160 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 53 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index 0e5ebc14c8..bd6bcb5af0 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -27,6 +27,10 @@ #include "qemu/main-loop.h" #include "trace.h" +#define TYPE_I8257 "i8257" +#define I8257(obj) \ + OBJECT_CHECK(I8257State, (obj), TYPE_I8257) + /* #define DEBUG_DMA */ #define dolog(...) fprintf (stderr, "dma: " __VA_ARGS__) @@ -54,11 +58,17 @@ typedef struct I8257Regs { #define COUNT 1 typedef struct I8257State { + ISADevice parent_obj; + + int32_t base; + int32_t page_base; + int32_t pageh_base; + int32_t dshift; + uint8_t status; uint8_t command; uint8_t mask; uint8_t flip_flop; - int dshift; I8257Regs regs[4]; MemoryRegion channel_io; MemoryRegion cont_io; @@ -68,7 +78,7 @@ typedef struct I8257State { int running; } I8257State; -static I8257State dma_controllers[2]; +static I8257State *dma_controllers[2]; enum { CMD_MEMORY_TO_MEMORY = 0x01, @@ -314,7 +324,7 @@ static uint64_t i8257_read_cont(void *opaque, hwaddr nport, unsigned size) int DMA_get_channel_mode (int nchan) { - return dma_controllers[nchan > 3].regs[nchan & 3].mode; + return dma_controllers[nchan > 3]->regs[nchan & 3].mode; } void DMA_hold_DREQ (int nchan) @@ -324,8 +334,8 @@ void DMA_hold_DREQ (int nchan) ncont = nchan > 3; ichan = nchan & 3; linfo ("held cont=%d chan=%d\n", ncont, ichan); - dma_controllers[ncont].status |= 1 << (ichan + 4); - i8257_dma_run(&dma_controllers[ncont]); + dma_controllers[ncont]->status |= 1 << (ichan + 4); + i8257_dma_run(dma_controllers[ncont]); } void DMA_release_DREQ (int nchan) @@ -335,8 +345,8 @@ void DMA_release_DREQ (int nchan) ncont = nchan > 3; ichan = nchan & 3; linfo ("released cont=%d chan=%d\n", ncont, ichan); - dma_controllers[ncont].status &= ~(1 << (ichan + 4)); - i8257_dma_run(&dma_controllers[ncont]); + dma_controllers[ncont]->status &= ~(1 << (ichan + 4)); + i8257_dma_run(dma_controllers[ncont]); } static void i8257_channel_run(I8257State *d, int ichan) @@ -406,14 +416,14 @@ void DMA_register_channel (int nchan, ncont = nchan > 3; ichan = nchan & 3; - r = dma_controllers[ncont].regs + ichan; + r = dma_controllers[ncont]->regs + ichan; r->transfer_handler = transfer_handler; r->opaque = opaque; } int DMA_read_memory (int nchan, void *buf, int pos, int len) { - I8257Regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; + I8257Regs *r = &dma_controllers[nchan > 3]->regs[nchan & 3]; hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; if (r->mode & 0x20) { @@ -435,7 +445,7 @@ int DMA_read_memory (int nchan, void *buf, int pos, int len) int DMA_write_memory (int nchan, void *buf, int pos, int len) { - I8257Regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; + I8257Regs *r = &dma_controllers[nchan > 3]->regs[nchan & 3]; hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; if (r->mode & 0x20) { @@ -460,15 +470,15 @@ int DMA_write_memory (int nchan, void *buf, int pos, int len) */ void DMA_schedule(void) { - if (dma_controllers[0].dma_bh_scheduled || - dma_controllers[1].dma_bh_scheduled) { + if (dma_controllers[0]->dma_bh_scheduled || + dma_controllers[1]->dma_bh_scheduled) { qemu_notify_event(); } } -static void i8257_reset(void *opaque) +static void i8257_reset(DeviceState *dev) { - I8257State *d = opaque; + I8257State *d = I8257(dev); i8257_write_cont(d, (0x05 << d->dshift), 0, 1); } @@ -514,40 +524,6 @@ static const MemoryRegionOps cont_io_ops = { }, }; -/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */ -static void dma_init2(I8257State *d, int base, int dshift, - int page_base, int pageh_base) -{ - int i; - - d->dshift = dshift; - - memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d, - "dma-chan", 8 << d->dshift); - memory_region_add_subregion(isa_address_space_io(NULL), - base, &d->channel_io); - - isa_register_portio_list(NULL, page_base, page_portio_list, d, - "dma-page"); - if (pageh_base >= 0) { - isa_register_portio_list(NULL, pageh_base, pageh_portio_list, d, - "dma-pageh"); - } - - memory_region_init_io(&d->cont_io, NULL, &cont_io_ops, d, "dma-cont", - 8 << d->dshift); - memory_region_add_subregion(isa_address_space_io(NULL), - base + (8 << d->dshift), &d->cont_io); - - qemu_register_reset(i8257_reset, d); - i8257_reset(d); - for (i = 0; i < ARRAY_SIZE (d->regs); ++i) { - d->regs[i].transfer_handler = i8257_phony_handler; - } - - d->dma_bh = qemu_bh_new(i8257_dma_run, d); -} - static const VMStateDescription vmstate_i8257_regs = { .name = "dma_regs", .version_id = 1, @@ -572,7 +548,7 @@ static int i8257_post_load(void *opaque, int version_id) return 0; } -static const VMStateDescription vmstate_dma = { +static const VMStateDescription vmstate_i8257 = { .name = "dma", .version_id = 1, .minimum_version_id = 1, @@ -588,10 +564,88 @@ static const VMStateDescription vmstate_dma = { } }; +static void i8257_realize(DeviceState *dev, Error **errp) +{ + ISADevice *isa = ISA_DEVICE(dev); + I8257State *d = I8257(dev); + int i; + + memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d, + "dma-chan", 8 << d->dshift); + memory_region_add_subregion(isa_address_space_io(isa), + d->base, &d->channel_io); + + isa_register_portio_list(isa, d->page_base, page_portio_list, d, + "dma-page"); + if (d->pageh_base >= 0) { + isa_register_portio_list(isa, d->pageh_base, pageh_portio_list, d, + "dma-pageh"); + } + + memory_region_init_io(&d->cont_io, OBJECT(isa), &cont_io_ops, d, + "dma-cont", 8 << d->dshift); + memory_region_add_subregion(isa_address_space_io(isa), + d->base + (8 << d->dshift), &d->cont_io); + + for (i = 0; i < ARRAY_SIZE(d->regs); ++i) { + d->regs[i].transfer_handler = i8257_phony_handler; + } + + d->dma_bh = qemu_bh_new(i8257_dma_run, d); +} + +static Property i8257_properties[] = { + DEFINE_PROP_INT32("base", I8257State, base, 0x00), + DEFINE_PROP_INT32("page-base", I8257State, page_base, 0x80), + DEFINE_PROP_INT32("pageh-base", I8257State, pageh_base, 0x480), + DEFINE_PROP_INT32("dshift", I8257State, dshift, 0), + DEFINE_PROP_END_OF_LIST() +}; + +static void i8257_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = i8257_realize; + dc->reset = i8257_reset; + dc->vmsd = &vmstate_i8257; + dc->props = i8257_properties; +} + +static const TypeInfo i8257_info = { + .name = TYPE_I8257, + .parent = TYPE_ISA_DEVICE, + .instance_size = sizeof(I8257State), + .class_init = i8257_class_init, +}; + +static void i8257_register_types(void) +{ + type_register_static(&i8257_info); +} + +type_init(i8257_register_types) + void DMA_init(ISABus *bus, int high_page_enable) { - dma_init2(&dma_controllers[0], 0x00, 0, 0x80, high_page_enable ? 0x480 : -1); - dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, high_page_enable ? 0x488 : -1); - vmstate_register (NULL, 0, &vmstate_dma, &dma_controllers[0]); - vmstate_register (NULL, 1, &vmstate_dma, &dma_controllers[1]); + ISADevice *isa1, *isa2; + DeviceState *d; + + isa1 = isa_create(bus, TYPE_I8257); + d = DEVICE(isa1); + qdev_prop_set_int32(d, "base", 0x00); + qdev_prop_set_int32(d, "page-base", 0x80); + qdev_prop_set_int32(d, "pageh-base", high_page_enable ? 0x480 : -1); + qdev_prop_set_int32(d, "dshift", 0); + qdev_init_nofail(d); + dma_controllers[0] = I8257(d); + + isa2 = isa_create(bus, TYPE_I8257); + d = DEVICE(isa2); + qdev_prop_set_int32(d, "base", 0xc0); + qdev_prop_set_int32(d, "page-base", 0x88); + qdev_prop_set_int32(d, "pageh-base", high_page_enable ? 0x488 : -1); + qdev_prop_set_int32(d, "dshift", 1); + qdev_init_nofail(d); + dma_controllers[1] = I8257(d); } From f5f19ee2e448a8442f1974ca1a0b8864486ed25b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:56 -0500 Subject: [PATCH 10/20] i8257: move state definition to new independent header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will now be able to embed the i8257 interrupt controller in another object. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-10-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 35 +---------------------------------- include/hw/isa/i8257.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 34 deletions(-) create mode 100644 include/hw/isa/i8257.h diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index bd6bcb5af0..35ca8a4e4b 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -24,10 +24,10 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/isa/isa.h" +#include "hw/isa/i8257.h" #include "qemu/main-loop.h" #include "trace.h" -#define TYPE_I8257 "i8257" #define I8257(obj) \ OBJECT_CHECK(I8257State, (obj), TYPE_I8257) @@ -42,42 +42,9 @@ #define ldebug(...) #endif -typedef struct I8257Regs { - int now[2]; - uint16_t base[2]; - uint8_t mode; - uint8_t page; - uint8_t pageh; - uint8_t dack; - uint8_t eop; - DMA_transfer_handler transfer_handler; - void *opaque; -} I8257Regs; - #define ADDR 0 #define COUNT 1 -typedef struct I8257State { - ISADevice parent_obj; - - int32_t base; - int32_t page_base; - int32_t pageh_base; - int32_t dshift; - - uint8_t status; - uint8_t command; - uint8_t mask; - uint8_t flip_flop; - I8257Regs regs[4]; - MemoryRegion channel_io; - MemoryRegion cont_io; - - QEMUBH *dma_bh; - bool dma_bh_scheduled; - int running; -} I8257State; - static I8257State *dma_controllers[2]; enum { diff --git a/include/hw/isa/i8257.h b/include/hw/isa/i8257.h new file mode 100644 index 0000000000..8d34ed17b7 --- /dev/null +++ b/include/hw/isa/i8257.h @@ -0,0 +1,42 @@ +#ifndef HW_I8257_H +#define HW_I8257_H + +#define TYPE_I8257 "i8257" + +typedef struct I8257Regs { + int now[2]; + uint16_t base[2]; + uint8_t mode; + uint8_t page; + uint8_t pageh; + uint8_t dack; + uint8_t eop; + DMA_transfer_handler transfer_handler; + void *opaque; +} I8257Regs; + +typedef struct I8257State { + /* */ + ISADevice parent_obj; + + /* */ + int32_t base; + int32_t page_base; + int32_t pageh_base; + int32_t dshift; + + uint8_t status; + uint8_t command; + uint8_t mask; + uint8_t flip_flop; + I8257Regs regs[4]; + MemoryRegion channel_io; + MemoryRegion cont_io; + + QEMUBH *dma_bh; + bool dma_bh_scheduled; + int running; +} I8257State; + +#endif + From 5484f30b2c48ba526f922e6b10e7ab3566c0b8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:57 -0500 Subject: [PATCH 11/20] isa: add an ISA DMA interface, and store it within the ISA bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will permit to deprecate global DMA_*() functions. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-11-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/isa/isa-bus.c | 21 +++++++++++++++++++++ include/hw/isa/isa.h | 38 ++++++++++++++++++++++++++++++++++++++ include/qemu/typedefs.h | 1 + 3 files changed, 60 insertions(+) diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c index b487cb1839..c3b7388529 100644 --- a/hw/isa/isa-bus.c +++ b/hw/isa/isa-bus.c @@ -37,6 +37,12 @@ static void isa_bus_class_init(ObjectClass *klass, void *data) k->get_fw_dev_path = isabus_get_fw_dev_path; } +static const TypeInfo isa_dma_info = { + .name = TYPE_ISADMA, + .parent = TYPE_INTERFACE, + .class_size = sizeof(IsaDmaClass), +}; + static const TypeInfo isa_bus_info = { .name = TYPE_ISA_BUS, .parent = TYPE_BUS, @@ -90,6 +96,20 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq) dev->nirqs++; } +void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16) +{ + assert(bus && dma8 && dma16); + assert(!bus->dma[0] && !bus->dma[1]); + bus->dma[0] = dma8; + bus->dma[1] = dma16; +} + +IsaDma *isa_get_dma(ISABus *bus, int nchan) +{ + assert(bus); + return bus->dma[nchan > 3 ? 1 : 0]; +} + static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport) { if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) { @@ -223,6 +243,7 @@ static const TypeInfo isa_device_type_info = { static void isabus_register_types(void) { + type_register_static(&isa_dma_info); type_register_static(&isa_bus_info); type_register_static(&isabus_bridge_info); type_register_static(&isa_device_type_info); diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index 4af87303a4..8de439c597 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -34,6 +34,41 @@ static inline uint16_t applesmc_port(void) return 0; } +#define TYPE_ISADMA "isa-dma" + +#define ISADMA_CLASS(klass) \ + OBJECT_CLASS_CHECK(IsaDmaClass, (klass), TYPE_ISADMA) +#define ISADMA_GET_CLASS(obj) \ + OBJECT_GET_CLASS(IsaDmaClass, (obj), TYPE_ISADMA) +#define ISADMA(obj) \ + INTERFACE_CHECK(IsaDma, (obj), TYPE_ISADMA) + +struct IsaDma { + Object parent; +}; + +typedef enum { + ISADMA_TRANSFER_VERIFY, + ISADMA_TRANSFER_READ, + ISADMA_TRANSFER_WRITE, + ISADMA_TRANSFER_ILLEGAL, +} IsaDmaTransferMode; + +typedef struct IsaDmaClass { + InterfaceClass parent; + + IsaDmaTransferMode (*get_transfer_mode)(IsaDma *obj, int nchan); + bool (*has_autoinitialization)(IsaDma *obj, int nchan); + int (*read_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len); + int (*write_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len); + void (*hold_DREQ)(IsaDma *obj, int nchan); + void (*release_DREQ)(IsaDma *obj, int nchan); + void (*schedule)(IsaDma *obj); + void (*register_channel)(IsaDma *obj, int nchan, + DMA_transfer_handler transfer_handler, + void *opaque); +} IsaDmaClass; + typedef struct ISADeviceClass { DeviceClass parent_class; } ISADeviceClass; @@ -46,6 +81,7 @@ struct ISABus { MemoryRegion *address_space; MemoryRegion *address_space_io; qemu_irq *irqs; + IsaDma *dma[2]; }; struct ISADevice { @@ -63,6 +99,8 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space, void isa_bus_irqs(ISABus *bus, qemu_irq *irqs); qemu_irq isa_get_irq(ISADevice *dev, int isairq); void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq); +void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16); +IsaDma *isa_get_dma(ISABus *bus, int nchan); MemoryRegion *isa_address_space(ISADevice *dev); MemoryRegion *isa_address_space_io(ISADevice *dev); ISADevice *isa_create(ISABus *bus, const char *name); diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 78fe6e86e3..6ed91b4968 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -33,6 +33,7 @@ typedef struct I2CBus I2CBus; typedef struct I2SCodec I2SCodec; typedef struct ISABus ISABus; typedef struct ISADevice ISADevice; +typedef struct IsaDma IsaDma; typedef struct LoadStateEntry LoadStateEntry; typedef struct MACAddr MACAddr; typedef struct MachineClass MachineClass; From 16ffe3636006b6805e403860c54bf9c2071c6e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:57 -0500 Subject: [PATCH 12/20] i8257: implement the IsaDma interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite the global DMA_*() functions to use the IsaDma interface. Note that these functions will be deleted in a few commits. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-12-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 152 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 119 insertions(+), 33 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index 35ca8a4e4b..c413c9a38b 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -45,8 +45,6 @@ #define ADDR 0 #define COUNT 1 -static I8257State *dma_controllers[2]; - enum { CMD_MEMORY_TO_MEMORY = 0x01, CMD_FIXED_ADDRESS = 0x02, @@ -289,31 +287,36 @@ static uint64_t i8257_read_cont(void *opaque, hwaddr nport, unsigned size) return val; } -int DMA_get_channel_mode (int nchan) +static IsaDmaTransferMode i8257_dma_get_transfer_mode(IsaDma *obj, int nchan) { - return dma_controllers[nchan > 3]->regs[nchan & 3].mode; + I8257State *d = I8257(obj); + return (d->regs[nchan & 3].mode >> 2) & 3; } -void DMA_hold_DREQ (int nchan) +static bool i8257_dma_has_autoinitialization(IsaDma *obj, int nchan) { - int ncont, ichan; - - ncont = nchan > 3; - ichan = nchan & 3; - linfo ("held cont=%d chan=%d\n", ncont, ichan); - dma_controllers[ncont]->status |= 1 << (ichan + 4); - i8257_dma_run(dma_controllers[ncont]); + I8257State *d = I8257(obj); + return (d->regs[nchan & 3].mode >> 4) & 1; } -void DMA_release_DREQ (int nchan) +static void i8257_dma_hold_DREQ(IsaDma *obj, int nchan) { - int ncont, ichan; + I8257State *d = I8257(obj); + int ichan; - ncont = nchan > 3; ichan = nchan & 3; - linfo ("released cont=%d chan=%d\n", ncont, ichan); - dma_controllers[ncont]->status &= ~(1 << (ichan + 4)); - i8257_dma_run(dma_controllers[ncont]); + d->status |= 1 << (ichan + 4); + i8257_dma_run(d); +} + +static void i8257_dma_release_DREQ(IsaDma *obj, int nchan) +{ + I8257State *d = I8257(obj); + int ichan; + + ichan = nchan & 3; + d->status &= ~(1 << (ichan + 4)); + i8257_dma_run(d); } static void i8257_channel_run(I8257State *d, int ichan) @@ -373,24 +376,26 @@ out: } } -void DMA_register_channel (int nchan, - DMA_transfer_handler transfer_handler, - void *opaque) +static void i8257_dma_register_channel(IsaDma *obj, int nchan, + DMA_transfer_handler transfer_handler, + void *opaque) { + I8257State *d = I8257(obj); I8257Regs *r; - int ichan, ncont; + int ichan; - ncont = nchan > 3; ichan = nchan & 3; - r = dma_controllers[ncont]->regs + ichan; + r = d->regs + ichan; r->transfer_handler = transfer_handler; r->opaque = opaque; } -int DMA_read_memory (int nchan, void *buf, int pos, int len) +static int i8257_dma_read_memory(IsaDma *obj, int nchan, void *buf, int pos, + int len) { - I8257Regs *r = &dma_controllers[nchan > 3]->regs[nchan & 3]; + I8257State *d = I8257(obj); + I8257Regs *r = &d->regs[nchan & 3]; hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; if (r->mode & 0x20) { @@ -410,9 +415,11 @@ int DMA_read_memory (int nchan, void *buf, int pos, int len) return len; } -int DMA_write_memory (int nchan, void *buf, int pos, int len) +static int i8257_dma_write_memory(IsaDma *obj, int nchan, void *buf, int pos, + int len) { - I8257Regs *r = &dma_controllers[nchan > 3]->regs[nchan & 3]; + I8257State *s = I8257(obj); + I8257Regs *r = &s->regs[nchan & 3]; hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; if (r->mode & 0x20) { @@ -435,10 +442,10 @@ int DMA_write_memory (int nchan, void *buf, int pos, int len) /* request the emulator to transfer a new DMA memory block ASAP (even * if the idle bottom half would not have exited the iothread yet). */ -void DMA_schedule(void) +static void i8257_dma_schedule(IsaDma *obj) { - if (dma_controllers[0]->dma_bh_scheduled || - dma_controllers[1]->dma_bh_scheduled) { + I8257State *d = I8257(obj); + if (d->dma_bh_scheduled) { qemu_notify_event(); } } @@ -572,11 +579,85 @@ static Property i8257_properties[] = { static void i8257_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + IsaDmaClass *idc = ISADMA_CLASS(klass); dc->realize = i8257_realize; dc->reset = i8257_reset; dc->vmsd = &vmstate_i8257; dc->props = i8257_properties; + + idc->get_transfer_mode = i8257_dma_get_transfer_mode; + idc->has_autoinitialization = i8257_dma_has_autoinitialization; + idc->read_memory = i8257_dma_read_memory; + idc->write_memory = i8257_dma_write_memory; + idc->hold_DREQ = i8257_dma_hold_DREQ; + idc->release_DREQ = i8257_dma_release_DREQ; + idc->schedule = i8257_dma_schedule; + idc->register_channel = i8257_dma_register_channel; +} + +static ISABus *i8257_bus; + +int DMA_get_channel_mode(int nchan) +{ + IsaDma *dma = isa_get_dma(i8257_bus, nchan); + IsaDmaClass *k = ISADMA_GET_CLASS(dma); + uint8_t res = 0; + + res |= k->has_autoinitialization(dma, nchan) ? 0 : 0x10; + res |= k->get_transfer_mode(dma, nchan) << 2; + + return res; +} + +int DMA_read_memory(int nchan, void *buf, int pos, int size) +{ + IsaDma *dma = isa_get_dma(i8257_bus, nchan); + IsaDmaClass *k = ISADMA_GET_CLASS(dma); + return k->read_memory(dma, nchan, buf, pos, size); +} + +int DMA_write_memory(int nchan, void *buf, int pos, int size) +{ + IsaDma *dma = isa_get_dma(i8257_bus, nchan); + IsaDmaClass *k = ISADMA_GET_CLASS(dma); + return k->write_memory(dma, nchan, buf, pos, size); +} + +void DMA_hold_DREQ(int nchan) +{ + IsaDma *dma = isa_get_dma(i8257_bus, nchan); + IsaDmaClass *k = ISADMA_GET_CLASS(dma); + k->hold_DREQ(dma, nchan); +} + +void DMA_release_DREQ(int nchan) +{ + IsaDma *dma = isa_get_dma(i8257_bus, nchan); + IsaDmaClass *k = ISADMA_GET_CLASS(dma); + k->release_DREQ(dma, nchan); +} + +void DMA_schedule(void) +{ + IsaDma *dma; + IsaDmaClass *k; + int i; + + for (i = 0; i < 2; i++) { + dma = isa_get_dma(i8257_bus, i << 2); + k = ISADMA_GET_CLASS(dma); + k->schedule(dma); + } +} + +void DMA_register_channel(int nchan, + DMA_transfer_handler transfer_handler, + void *opaque) +{ + IsaDma *dma = isa_get_dma(i8257_bus, nchan); + IsaDmaClass *k = ISADMA_GET_CLASS(dma); + k->register_channel(dma, nchan, transfer_handler, opaque); } static const TypeInfo i8257_info = { @@ -584,6 +665,10 @@ static const TypeInfo i8257_info = { .parent = TYPE_ISA_DEVICE, .instance_size = sizeof(I8257State), .class_init = i8257_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_ISADMA }, + { } + } }; static void i8257_register_types(void) @@ -605,7 +690,6 @@ void DMA_init(ISABus *bus, int high_page_enable) qdev_prop_set_int32(d, "pageh-base", high_page_enable ? 0x480 : -1); qdev_prop_set_int32(d, "dshift", 0); qdev_init_nofail(d); - dma_controllers[0] = I8257(d); isa2 = isa_create(bus, TYPE_I8257); d = DEVICE(isa2); @@ -614,5 +698,7 @@ void DMA_init(ISABus *bus, int high_page_enable) qdev_prop_set_int32(d, "pageh-base", high_page_enable ? 0x488 : -1); qdev_prop_set_int32(d, "dshift", 1); qdev_init_nofail(d); - dma_controllers[1] = I8257(d); + + isa_bus_dma(bus, ISADMA(isa1), ISADMA(isa2)); + i8257_bus = bus; } From 020e29869924ede58ef6d8723cad4df9af307af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:57 -0500 Subject: [PATCH 13/20] magnum: disable floppy DMA for now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Floppy uses the DMA controller in rc4030 chipset, and not the i8259 from the ISA bus. It's better to disable DMA than to call the wrong DMA controller. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-13-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/mips/mips_jazz.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index a199b9d18a..d6d8058602 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -297,7 +297,8 @@ static void mips_jazz_init(MachineState *machine, for (n = 0; n < MAX_FD; n++) { fds[n] = drive_get(IF_FLOPPY, 0, n); } - fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), 0, 0x80003000, fds); + /* FIXME: we should enable DMA with a custom IsaDma device */ + fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), -1, 0x80003000, fds); /* Real time clock */ rtc_init(isa_bus, 1980, NULL); From dd446051b797f72d6293c26bde2db16fddc42d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:57 -0500 Subject: [PATCH 14/20] sparc: disable floppy DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All functions relative to DMA (DMA_*() functions) are stubs on sparc platform. Disable the DMA in the floppy controller, instead of calling these stubs. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-14-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/block/fdc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 9ef899d91f..40abeef615 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -2492,6 +2492,8 @@ static void sun4m_fdc_initfn(Object *obj) FDCtrlSysBus *sys = SYSBUS_FDC(obj); FDCtrl *fdctrl = &sys->state; + fdctrl->dma_chann = -1; + memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops, fdctrl, "fdctrl", 0x08); sysbus_init_mmio(sbd, &fdctrl->iomem); From c3ae40e12cd7a41d2620ca2b771f6e167c0632d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:57 -0500 Subject: [PATCH 15/20] sparc64: disable floppy DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All functions relative to DMA (DMA_*() functions) are stubs on sparc64 platform. Disable the DMA of the floppy controller, instead of calling these stubs. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-15-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/sparc64/sun4u.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index d356717c08..371f5bcbf9 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -816,6 +816,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, qemu_irq *ivec_irqs, *pbm_irqs; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; + DeviceState *dev; FWCfgState *fw_cfg; /* init CPUs */ @@ -852,10 +853,22 @@ static void sun4uv_init(MemoryRegion *address_space_mem, pci_cmd646_ide_init(pci_bus, hd, 1); isa_create_simple(isa_bus, "i8042"); + + /* Floppy */ for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } - fdctrl_init_isa(isa_bus, fd); + dev = DEVICE(isa_create(isa_bus, TYPE_ISA_FDC)); + if (fd[0]) { + qdev_prop_set_drive(dev, "driveA", blk_by_legacy_dinfo(fd[0]), + &error_abort); + } + if (fd[1]) { + qdev_prop_set_drive(dev, "driveB", blk_by_legacy_dinfo(fd[1]), + &error_abort); + } + qdev_prop_set_uint32(dev, "dma", -1); + qdev_init_nofail(dev); /* Map NVRAM into I/O (ebus) space */ nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59); From c8a35f1cf0f25653be588603c012070d4bdb756a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:58 -0500 Subject: [PATCH 16/20] fdc: use IsaDma interface instead of global DMA_* functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-16-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/block/fdc.c | 63 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 40abeef615..a6f22ef200 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -644,6 +644,7 @@ struct FDCtrl { QEMUTimer *result_timer; int dma_chann; uint8_t phase; + IsaDma *dma; /* Controller's identification */ uint8_t version; /* HW */ @@ -1429,7 +1430,8 @@ static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t status0, fdctrl->fifo[6] = FD_SECTOR_SC; fdctrl->data_dir = FD_DIR_READ; if (!(fdctrl->msr & FD_MSR_NONDMA)) { - DMA_release_DREQ(fdctrl->dma_chann); + IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma); + k->release_DREQ(fdctrl->dma, fdctrl->dma_chann); } fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO; fdctrl->msr &= ~FD_MSR_NONDMA; @@ -1515,27 +1517,43 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction) } fdctrl->eot = fdctrl->fifo[6]; if (fdctrl->dor & FD_DOR_DMAEN) { - int dma_mode; + IsaDmaTransferMode dma_mode; + IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma); + bool dma_mode_ok; /* DMA transfer are enabled. Check if DMA channel is well programmed */ - dma_mode = DMA_get_channel_mode(fdctrl->dma_chann); - dma_mode = (dma_mode >> 2) & 3; + dma_mode = k->get_transfer_mode(fdctrl->dma, fdctrl->dma_chann); FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n", dma_mode, direction, (128 << fdctrl->fifo[5]) * (cur_drv->last_sect - ks + 1), fdctrl->data_len); - if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL || - direction == FD_DIR_SCANH) && dma_mode == 0) || - (direction == FD_DIR_WRITE && dma_mode == 2) || - (direction == FD_DIR_READ && dma_mode == 1) || - (direction == FD_DIR_VERIFY)) { + switch (direction) { + case FD_DIR_SCANE: + case FD_DIR_SCANL: + case FD_DIR_SCANH: + dma_mode_ok = (dma_mode == ISADMA_TRANSFER_VERIFY); + break; + case FD_DIR_WRITE: + dma_mode_ok = (dma_mode == ISADMA_TRANSFER_WRITE); + break; + case FD_DIR_READ: + dma_mode_ok = (dma_mode == ISADMA_TRANSFER_READ); + break; + case FD_DIR_VERIFY: + dma_mode_ok = true; + break; + default: + dma_mode_ok = false; + break; + } + if (dma_mode_ok) { /* No access is allowed until DMA transfer has completed */ fdctrl->msr &= ~FD_MSR_RQM; if (direction != FD_DIR_VERIFY) { /* Now, we just have to wait for the DMA controller to * recall us... */ - DMA_hold_DREQ(fdctrl->dma_chann); - DMA_schedule(); + k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann); + k->schedule(fdctrl->dma); } else { /* Start transfer */ fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0, @@ -1574,12 +1592,14 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, FDrive *cur_drv; int len, start_pos, rel_pos; uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00; + IsaDmaClass *k; fdctrl = opaque; if (fdctrl->msr & FD_MSR_RQM) { FLOPPY_DPRINTF("Not in DMA transfer mode !\n"); return 0; } + k = ISADMA_GET_CLASS(fdctrl->dma); cur_drv = get_cur_drv(fdctrl); if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL || fdctrl->data_dir == FD_DIR_SCANH) @@ -1618,8 +1638,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, switch (fdctrl->data_dir) { case FD_DIR_READ: /* READ commands */ - DMA_write_memory (nchan, fdctrl->fifo + rel_pos, - fdctrl->data_pos, len); + k->write_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos, + fdctrl->data_pos, len); break; case FD_DIR_WRITE: /* WRITE commands */ @@ -1633,8 +1653,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, goto transfer_error; } - DMA_read_memory (nchan, fdctrl->fifo + rel_pos, - fdctrl->data_pos, len); + k->read_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos, + fdctrl->data_pos, len); if (blk_write(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { FLOPPY_DPRINTF("error writing sector %d\n", @@ -1651,7 +1671,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, { uint8_t tmpbuf[FD_SECTOR_LEN]; int ret; - DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len); + k->read_memory(fdctrl->dma, nchan, tmpbuf, fdctrl->data_pos, + len); ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len); if (ret == 0) { status2 = FD_SR2_SEH; @@ -2441,7 +2462,11 @@ static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp) fdctrl->num_floppies = MAX_FD; if (fdctrl->dma_chann != -1) { - DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl); + IsaDmaClass *k; + assert(fdctrl->dma); + k = ISADMA_GET_CLASS(fdctrl->dma); + k->register_channel(fdctrl->dma, fdctrl->dma_chann, + &fdctrl_transfer_handler, fdctrl); } fdctrl_connect_drives(fdctrl, errp); } @@ -2464,6 +2489,10 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp) isa_init_irq(isadev, &fdctrl->irq, isa->irq); fdctrl->dma_chann = isa->dma; + if (fdctrl->dma_chann != -1) { + fdctrl->dma = isa_get_dma(isa_bus_from_device(isadev), isa->dma); + assert(fdctrl->dma); + } qdev_set_legacy_instance_id(dev, isa->iobase, 2); fdctrl_realize_common(fdctrl, &err); From 2d0110913356b34229d7232e8e1ce93ad9b3da67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:58 -0500 Subject: [PATCH 17/20] cs4231a: use IsaDma interface instead of global DMA_* functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-17-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/audio/cs4231a.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c index b0c7c93e21..3ecd0582bf 100644 --- a/hw/audio/cs4231a.c +++ b/hw/audio/cs4231a.c @@ -70,6 +70,7 @@ typedef struct CSState { uint32_t irq; uint32_t dma; uint32_t port; + IsaDma *isa_dma; int shift; int dma_running; int audio_free; @@ -265,6 +266,7 @@ static void cs_reset_voices (CSState *s, uint32_t val) { int xtal; struct audsettings as; + IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); #ifdef DEBUG_XLAW if (val == 0 || val == 32) @@ -328,7 +330,7 @@ static void cs_reset_voices (CSState *s, uint32_t val) if (s->dregs[Interface_Configuration] & PEN) { if (!s->dma_running) { - DMA_hold_DREQ (s->dma); + k->hold_DREQ(s->isa_dma, s->dma); AUD_set_active_out (s->voice, 1); s->transferred = 0; } @@ -336,7 +338,7 @@ static void cs_reset_voices (CSState *s, uint32_t val) } else { if (s->dma_running) { - DMA_release_DREQ (s->dma); + k->release_DREQ(s->isa_dma, s->dma); AUD_set_active_out (s->voice, 0); } s->dma_running = 0; @@ -345,7 +347,7 @@ static void cs_reset_voices (CSState *s, uint32_t val) error: if (s->dma_running) { - DMA_release_DREQ (s->dma); + k->release_DREQ(s->isa_dma, s->dma); AUD_set_active_out (s->voice, 0); } } @@ -453,7 +455,8 @@ static void cs_write (void *opaque, hwaddr addr, } else { if (s->dma_running) { - DMA_release_DREQ (s->dma); + IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); + k->release_DREQ(s->isa_dma, s->dma); AUD_set_active_out (s->voice, 0); s->dma_running = 0; } @@ -518,6 +521,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos, { int temp, net; uint8_t tmpbuf[4096]; + IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); temp = len; net = 0; @@ -532,7 +536,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos, to_copy = sizeof (tmpbuf); } - copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy); + copied = k->read_memory(s->isa_dma, nchan, tmpbuf, dma_pos, to_copy); if (s->tab) { int i; int16_t linbuf[4096]; @@ -600,7 +604,8 @@ static int cs4231a_pre_load (void *opaque) CSState *s = opaque; if (s->dma_running) { - DMA_release_DREQ (s->dma); + IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); + k->release_DREQ(s->isa_dma, s->dma); AUD_set_active_out (s->voice, 0); } s->dma_running = 0; @@ -656,13 +661,15 @@ static void cs4231a_realizefn (DeviceState *dev, Error **errp) { ISADevice *d = ISA_DEVICE (dev); CSState *s = CS4231A (dev); + IsaDmaClass *k; isa_init_irq (d, &s->pic, s->irq); + s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->dma); + k = ISADMA_GET_CLASS(s->isa_dma); + k->register_channel(s->isa_dma, s->dma, cs_dma_read, s); isa_register_ioport (d, &s->ioports, s->port); - DMA_register_channel (s->dma, cs_dma_read, s); - AUD_register_card ("cs4231a", &s->card); } From 467be5f2f0176592288460787ca28704f6493db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:58 -0500 Subject: [PATCH 18/20] gus: use IsaDma interface instead of global DMA_* functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-18-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/audio/gus.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/hw/audio/gus.c b/hw/audio/gus.c index 47c0fcfb4c..b416a54909 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -58,6 +58,7 @@ typedef struct GUSState { SWVoiceOut *voice; int64_t last_ticks; qemu_irq pic; + IsaDma *isa_dma; } GUSState; static uint32_t gus_readb(void *opaque, uint32_t nport) @@ -168,34 +169,36 @@ void GUS_irqclear (GUSEmuState *emu, int hwirq) #endif } -void GUS_dmarequest (GUSEmuState *der) +void GUS_dmarequest (GUSEmuState *emu) { - /* GUSState *s = (GUSState *) der; */ + GUSState *s = emu->opaque; + IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); ldebug ("dma request %d\n", der->gusdma); - DMA_hold_DREQ (der->gusdma); + k->hold_DREQ(s->isa_dma, s->emu.gusdma); } static int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len) { GUSState *s = opaque; + IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); char tmpbuf[4096]; int pos = dma_pos, mode, left = dma_len - dma_pos; ldebug ("read DMA %#x %d\n", dma_pos, dma_len); - mode = DMA_get_channel_mode (s->emu.gusdma); + mode = k->has_autoinitialization(s->isa_dma, s->emu.gusdma); while (left) { int to_copy = audio_MIN ((size_t) left, sizeof (tmpbuf)); int copied; ldebug ("left=%d to_copy=%d pos=%d\n", left, to_copy, pos); - copied = DMA_read_memory (nchan, tmpbuf, pos, to_copy); + copied = k->read_memory(s->isa_dma, nchan, tmpbuf, pos, to_copy); gus_dma_transferdata (&s->emu, tmpbuf, copied, left == copied); left -= copied; pos += copied; } if (((mode >> 4) & 1) == 0) { - DMA_release_DREQ (s->emu.gusdma); + k->release_DREQ(s->isa_dma, s->emu.gusdma); } return dma_len; } @@ -232,6 +235,7 @@ static void gus_realizefn (DeviceState *dev, Error **errp) { ISADevice *d = ISA_DEVICE(dev); GUSState *s = GUS (dev); + IsaDmaClass *k; struct audsettings as; AUD_register_card ("gus", &s->card); @@ -264,7 +268,9 @@ static void gus_realizefn (DeviceState *dev, Error **errp) isa_register_portio_list (d, (s->port + 0x100) & 0xf00, gus_portio_list2, s, "gus"); - DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s); + s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma); + k = ISADMA_GET_CLASS(s->isa_dma); + k->register_channel(s->isa_dma, s->emu.gusdma, GUS_read_DMA, s); s->emu.himemaddr = s->himem; s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32; s->emu.opaque = s; From f203c16ea28cfbe53f4b5523117539468d29a67a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:58 -0500 Subject: [PATCH 19/20] sb16: use IsaDma interface instead of global DMA_* functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-19-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/audio/sb16.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 3b2dcfdad9..6f8816cf64 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -56,6 +56,8 @@ typedef struct SB16State { uint32_t hdma; uint32_t port; uint32_t ver; + IsaDma *isa_dma; + IsaDma *isa_hdma; int in_index; int out_data_len; @@ -166,16 +168,18 @@ static void speaker (SB16State *s, int on) static void control (SB16State *s, int hold) { int dma = s->use_hdma ? s->hdma : s->dma; + IsaDma *isa_dma = s->use_hdma ? s->isa_hdma : s->isa_dma; + IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma); s->dma_running = hold; ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma); if (hold) { - DMA_hold_DREQ (dma); + k->hold_DREQ(isa_dma, dma); AUD_set_active_out (s->voice, 1); } else { - DMA_release_DREQ (dma); + k->release_DREQ(isa_dma, dma); AUD_set_active_out (s->voice, 0); } } @@ -1137,6 +1141,8 @@ static uint32_t mixer_read(void *opaque, uint32_t nport) static int write_audio (SB16State *s, int nchan, int dma_pos, int dma_len, int len) { + IsaDma *isa_dma = nchan == s->dma ? s->isa_dma : s->isa_hdma; + IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma); int temp, net; uint8_t tmpbuf[4096]; @@ -1153,7 +1159,7 @@ static int write_audio (SB16State *s, int nchan, int dma_pos, to_copy = sizeof (tmpbuf); } - copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy); + copied = k->read_memory(isa_dma, nchan, tmpbuf, dma_pos, to_copy); copied = AUD_write (s->voice, tmpbuf, copied); temp -= copied; @@ -1355,6 +1361,7 @@ static void sb16_realizefn (DeviceState *dev, Error **errp) { ISADevice *isadev = ISA_DEVICE (dev); SB16State *s = SB16 (dev); + IsaDmaClass *k; isa_init_irq (isadev, &s->pic, s->irq); @@ -1373,8 +1380,14 @@ static void sb16_realizefn (DeviceState *dev, Error **errp) isa_register_portio_list (isadev, s->port, sb16_ioport_list, s, "sb16"); - DMA_register_channel (s->hdma, SB_read_DMA, s); - DMA_register_channel (s->dma, SB_read_DMA, s); + s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma); + k = ISADMA_GET_CLASS(s->isa_hdma); + k->register_channel(s->isa_hdma, s->hdma, SB_read_DMA, s); + + s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma); + k = ISADMA_GET_CLASS(s->isa_dma); + k->register_channel(s->isa_dma, s->dma, SB_read_DMA, s); + s->can_write = 1; AUD_register_card ("sb16", &s->card); From ba0a71022ca704eadcad4bffa92678d7c723729d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 3 Feb 2016 11:28:58 -0500 Subject: [PATCH 20/20] dma: remove now useless DMA_* functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep only DMA_init function as a wrapper around DMA controllers creation. Signed-off-by: Hervé Poussineau Message-id: 1453843944-26833-20-git-send-email-hpoussin@reactos.org Signed-off-by: John Snow --- hw/dma/i8257.c | 65 -------------------------------------------- hw/sparc/sun4m.c | 22 --------------- hw/sparc64/sun4u.c | 22 --------------- include/hw/isa/isa.h | 11 +------- 4 files changed, 1 insertion(+), 119 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index c413c9a38b..5a52707ae2 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -596,70 +596,6 @@ static void i8257_class_init(ObjectClass *klass, void *data) idc->register_channel = i8257_dma_register_channel; } -static ISABus *i8257_bus; - -int DMA_get_channel_mode(int nchan) -{ - IsaDma *dma = isa_get_dma(i8257_bus, nchan); - IsaDmaClass *k = ISADMA_GET_CLASS(dma); - uint8_t res = 0; - - res |= k->has_autoinitialization(dma, nchan) ? 0 : 0x10; - res |= k->get_transfer_mode(dma, nchan) << 2; - - return res; -} - -int DMA_read_memory(int nchan, void *buf, int pos, int size) -{ - IsaDma *dma = isa_get_dma(i8257_bus, nchan); - IsaDmaClass *k = ISADMA_GET_CLASS(dma); - return k->read_memory(dma, nchan, buf, pos, size); -} - -int DMA_write_memory(int nchan, void *buf, int pos, int size) -{ - IsaDma *dma = isa_get_dma(i8257_bus, nchan); - IsaDmaClass *k = ISADMA_GET_CLASS(dma); - return k->write_memory(dma, nchan, buf, pos, size); -} - -void DMA_hold_DREQ(int nchan) -{ - IsaDma *dma = isa_get_dma(i8257_bus, nchan); - IsaDmaClass *k = ISADMA_GET_CLASS(dma); - k->hold_DREQ(dma, nchan); -} - -void DMA_release_DREQ(int nchan) -{ - IsaDma *dma = isa_get_dma(i8257_bus, nchan); - IsaDmaClass *k = ISADMA_GET_CLASS(dma); - k->release_DREQ(dma, nchan); -} - -void DMA_schedule(void) -{ - IsaDma *dma; - IsaDmaClass *k; - int i; - - for (i = 0; i < 2; i++) { - dma = isa_get_dma(i8257_bus, i << 2); - k = ISADMA_GET_CLASS(dma); - k->schedule(dma); - } -} - -void DMA_register_channel(int nchan, - DMA_transfer_handler transfer_handler, - void *opaque) -{ - IsaDma *dma = isa_get_dma(i8257_bus, nchan); - IsaDmaClass *k = ISADMA_GET_CLASS(dma); - k->register_channel(dma, nchan, transfer_handler, opaque); -} - static const TypeInfo i8257_info = { .name = TYPE_I8257, .parent = TYPE_ISA_DEVICE, @@ -700,5 +636,4 @@ void DMA_init(ISABus *bus, int high_page_enable) qdev_init_nofail(d); isa_bus_dma(bus, ISADMA(isa1), ISADMA(isa2)); - i8257_bus = bus; } diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 9c078d5639..20dc341710 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -96,32 +96,10 @@ struct sun4m_hwdef { uint8_t nvram_machine_id; }; -int DMA_get_channel_mode (int nchan) -{ - return 0; -} -int DMA_read_memory (int nchan, void *buf, int pos, int size) -{ - return 0; -} -int DMA_write_memory (int nchan, void *buf, int pos, int size) -{ - return 0; -} -void DMA_hold_DREQ (int nchan) {} -void DMA_release_DREQ (int nchan) {} -void DMA_schedule(void) {} - void DMA_init(ISABus *bus, int high_page_enable) { } -void DMA_register_channel (int nchan, - DMA_transfer_handler transfer_handler, - void *opaque) -{ -} - static void fw_cfg_boot_set(void *opaque, const char *boot_device, Error **errp) { diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 371f5bcbf9..add1e752f3 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -99,32 +99,10 @@ typedef struct EbusState { MemoryRegion bar1; } EbusState; -int DMA_get_channel_mode (int nchan) -{ - return 0; -} -int DMA_read_memory (int nchan, void *buf, int pos, int size) -{ - return 0; -} -int DMA_write_memory (int nchan, void *buf, int pos, int size) -{ - return 0; -} -void DMA_hold_DREQ (int nchan) {} -void DMA_release_DREQ (int nchan) {} -void DMA_schedule(void) {} - void DMA_init(ISABus *bus, int high_page_enable) { } -void DMA_register_channel (int nchan, - DMA_transfer_handler transfer_handler, - void *opaque) -{ -} - static void fw_cfg_boot_set(void *opaque, const char *boot_device, Error **errp) { diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index 8de439c597..0bbe21cd48 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -144,15 +144,6 @@ static inline ISABus *isa_bus_from_device(ISADevice *d) return ISA_BUS(qdev_get_parent_bus(DEVICE(d))); } -/* dma.c */ -int DMA_get_channel_mode (int nchan); -int DMA_read_memory (int nchan, void *buf, int pos, int size); -int DMA_write_memory (int nchan, void *buf, int pos, int size); -void DMA_hold_DREQ (int nchan); -void DMA_release_DREQ (int nchan); -void DMA_schedule(void); +/* i8257.c */ void DMA_init(ISABus *bus, int high_page_enable); -void DMA_register_channel (int nchan, - DMA_transfer_handler transfer_handler, - void *opaque); #endif