Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging

# gpg: Signature made Wed 03 Feb 2016 20:29:54 GMT using RSA key ID AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"

* remotes/jnsnow/tags/ide-pull-request:
  dma: remove now useless DMA_* functions
  sb16: use IsaDma interface instead of global DMA_* functions
  gus: use IsaDma interface instead of global DMA_* functions
  cs4231a: use IsaDma interface instead of global DMA_* functions
  fdc: use IsaDma interface instead of global DMA_* functions
  sparc64: disable floppy DMA
  sparc: disable floppy DMA
  magnum: disable floppy DMA for now
  i8257: implement the IsaDma interface
  isa: add an ISA DMA interface, and store it within the ISA bus
  i8257: move state definition to new independent header
  i8257: QOM'ify
  i8257: add missing const
  i8257: make the DMA running method per controller
  i8257: rename functions to start with i8257_ prefix
  i8257: rename struct dma_regs to I8257Regs
  i8257: rename struct dma_cont to I8257State
  i8257: pass ISA bus to DMA_init() function
  i82374: device only existed as ISA device, so simplify device
  fdc: fix detection under Linux

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2016-02-04 12:50:43 +00:00
16 changed files with 473 additions and 318 deletions
+15 -8
View File
@@ -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);
}
+13 -7
View File
@@ -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;
+18 -5
View File
@@ -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);
+64 -17
View File
@@ -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) {
@@ -628,6 +644,7 @@ struct FDCtrl {
QEMUTimer *result_timer;
int dma_chann;
uint8_t phase;
IsaDma *dma;
/* Controller's identification */
uint8_t version;
/* HW */
@@ -1413,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;
@@ -1499,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,
@@ -1558,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)
@@ -1602,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 */
@@ -1617,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",
@@ -1635,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;
@@ -2425,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);
}
@@ -2448,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);
@@ -2476,6 +2521,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);
+19 -39
View File
@@ -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(isa_bus_from_device(ISA_DEVICE(dev)), 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)
+218 -179
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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);
+21
View File
@@ -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);
+1 -1
View File
@@ -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");
+3 -2
View File
@@ -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);
@@ -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);
+1 -1
View File
@@ -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");
+1 -23
View File
@@ -96,29 +96,7 @@ 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(int high_page_enable)
{
}
void DMA_register_channel (int nchan,
DMA_transfer_handler transfer_handler,
void *opaque)
void DMA_init(ISABus *bus, int high_page_enable)
{
}
+15 -24
View File
@@ -99,29 +99,7 @@ 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(int high_page_enable)
{
}
void DMA_register_channel (int nchan,
DMA_transfer_handler transfer_handler,
void *opaque)
void DMA_init(ISABus *bus, int high_page_enable)
{
}
@@ -816,6 +794,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 +831,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);
+42
View File
@@ -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 {
/* <private> */
ISADevice parent_obj;
/* <public> */
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
+40 -11
View File
@@ -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);
@@ -106,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);
void DMA_init(int high_page_enable);
void DMA_register_channel (int nchan,
DMA_transfer_handler transfer_handler,
void *opaque);
/* i8257.c */
void DMA_init(ISABus *bus, int high_page_enable);
#endif
+1
View File
@@ -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;