mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
+15
-8
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user