IDE: Fix reset handling
Problem: x86 systems could not survive a few system_resets. Clear most of IDE state when reset. Implement the missing reset handlers. Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
b55a37c981
commit
4a64356397
@ -193,8 +193,10 @@ static void cmd646_reset(void *opaque)
|
|||||||
PCIIDEState *d = opaque;
|
PCIIDEState *d = opaque;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++) {
|
||||||
ide_dma_cancel(&d->bmdma[i]);
|
ide_bus_reset(&d->bus[i]);
|
||||||
|
ide_dma_reset(&d->bmdma[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CMD646 PCI IDE controller */
|
/* CMD646 PCI IDE controller */
|
||||||
|
@ -2500,17 +2500,48 @@ static void ide_dummy_transfer_stop(IDEState *s)
|
|||||||
s->io_buffer[3] = 0xff;
|
s->io_buffer[3] = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ide_reset(IDEState *s)
|
static void ide_reset(IDEState *s)
|
||||||
{
|
{
|
||||||
IDEBus *bus = s->bus;
|
#ifdef DEBUG_IDE
|
||||||
|
printf("ide: reset\n");
|
||||||
|
#endif
|
||||||
if (s->is_cf)
|
if (s->is_cf)
|
||||||
s->mult_sectors = 0;
|
s->mult_sectors = 0;
|
||||||
else
|
else
|
||||||
s->mult_sectors = MAX_MULT_SECTORS;
|
s->mult_sectors = MAX_MULT_SECTORS;
|
||||||
bus->unit = s->unit;
|
/* ide regs */
|
||||||
|
s->feature = 0;
|
||||||
|
s->error = 0;
|
||||||
|
s->nsector = 0;
|
||||||
|
s->sector = 0;
|
||||||
|
s->lcyl = 0;
|
||||||
|
s->hcyl = 0;
|
||||||
|
|
||||||
|
/* lba48 */
|
||||||
|
s->hob_feature = 0;
|
||||||
|
s->hob_sector = 0;
|
||||||
|
s->hob_nsector = 0;
|
||||||
|
s->hob_lcyl = 0;
|
||||||
|
s->hob_hcyl = 0;
|
||||||
|
|
||||||
s->select = 0xa0;
|
s->select = 0xa0;
|
||||||
s->status = READY_STAT | SEEK_STAT;
|
s->status = READY_STAT | SEEK_STAT;
|
||||||
|
|
||||||
|
s->lba48 = 0;
|
||||||
|
|
||||||
|
/* ATAPI specific */
|
||||||
|
s->sense_key = 0;
|
||||||
|
s->asc = 0;
|
||||||
|
s->cdrom_changed = 0;
|
||||||
|
s->packet_transfer_size = 0;
|
||||||
|
s->elementary_transfer_size = 0;
|
||||||
|
s->io_buffer_index = 0;
|
||||||
|
s->cd_sector_size = 0;
|
||||||
|
s->atapi_dma = 0;
|
||||||
|
/* ATA DMA state */
|
||||||
|
s->io_buffer_size = 0;
|
||||||
|
s->req_nb_sectors = 0;
|
||||||
|
|
||||||
ide_set_signature(s);
|
ide_set_signature(s);
|
||||||
/* init the transfer handler so that 0xffff is returned on data
|
/* init the transfer handler so that 0xffff is returned on data
|
||||||
accesses */
|
accesses */
|
||||||
@ -2519,6 +2550,15 @@ void ide_reset(IDEState *s)
|
|||||||
s->media_changed = 0;
|
s->media_changed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ide_bus_reset(IDEBus *bus)
|
||||||
|
{
|
||||||
|
bus->unit = 0;
|
||||||
|
bus->cmd = 0;
|
||||||
|
ide_reset(&bus->ifs[0]);
|
||||||
|
ide_reset(&bus->ifs[1]);
|
||||||
|
ide_clear_hob(bus);
|
||||||
|
}
|
||||||
|
|
||||||
void ide_init_drive(IDEState *s, DriveInfo *dinfo)
|
void ide_init_drive(IDEState *s, DriveInfo *dinfo)
|
||||||
{
|
{
|
||||||
int cylinders, heads, secs;
|
int cylinders, heads, secs;
|
||||||
@ -2704,3 +2744,19 @@ void ide_dma_cancel(BMDMAState *bm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ide_dma_reset(BMDMAState *bm)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_IDE
|
||||||
|
printf("ide: dma_reset\n");
|
||||||
|
#endif
|
||||||
|
ide_dma_cancel(bm);
|
||||||
|
bm->cmd = 0;
|
||||||
|
bm->status = 0;
|
||||||
|
bm->addr = 0;
|
||||||
|
bm->cur_addr = 0;
|
||||||
|
bm->cur_prd_last = 0;
|
||||||
|
bm->cur_prd_addr = 0;
|
||||||
|
bm->cur_prd_len = 0;
|
||||||
|
bm->sector_num = 0;
|
||||||
|
bm->nsector = 0;
|
||||||
|
}
|
||||||
|
@ -525,13 +525,14 @@ extern const VMStateDescription vmstate_ide_drive;
|
|||||||
#define VMSTATE_IDE_DRIVES(_field, _state) \
|
#define VMSTATE_IDE_DRIVES(_field, _state) \
|
||||||
VMSTATE_STRUCT_ARRAY(_field, _state, 2, 3, vmstate_ide_drive, IDEState)
|
VMSTATE_STRUCT_ARRAY(_field, _state, 2, 3, vmstate_ide_drive, IDEState)
|
||||||
|
|
||||||
void ide_reset(IDEState *s);
|
void ide_bus_reset(IDEBus *bus);
|
||||||
int64_t ide_get_sector(IDEState *s);
|
int64_t ide_get_sector(IDEState *s);
|
||||||
void ide_set_sector(IDEState *s, int64_t sector_num);
|
void ide_set_sector(IDEState *s, int64_t sector_num);
|
||||||
|
|
||||||
void ide_dma_cancel(BMDMAState *bm);
|
void ide_dma_cancel(BMDMAState *bm);
|
||||||
void ide_dma_restart_cb(void *opaque, int running, int reason);
|
void ide_dma_restart_cb(void *opaque, int running, int reason);
|
||||||
void ide_dma_error(IDEState *s);
|
void ide_dma_error(IDEState *s);
|
||||||
|
void ide_dma_reset(BMDMAState *bm);
|
||||||
|
|
||||||
void ide_atapi_cmd_ok(IDEState *s);
|
void ide_atapi_cmd_ok(IDEState *s);
|
||||||
void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc);
|
void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc);
|
||||||
|
@ -44,6 +44,13 @@ typedef struct ISAIDEState {
|
|||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
} ISAIDEState;
|
} ISAIDEState;
|
||||||
|
|
||||||
|
static void isa_ide_reset(DeviceState *d)
|
||||||
|
{
|
||||||
|
ISAIDEState *s = container_of(d, ISAIDEState, dev.qdev);
|
||||||
|
|
||||||
|
ide_bus_reset(&s->bus);
|
||||||
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_ide_isa = {
|
static const VMStateDescription vmstate_ide_isa = {
|
||||||
.name = "isa-ide",
|
.name = "isa-ide",
|
||||||
.version_id = 3,
|
.version_id = 3,
|
||||||
@ -93,6 +100,7 @@ static ISADeviceInfo isa_ide_info = {
|
|||||||
.qdev.name = "isa-ide",
|
.qdev.name = "isa-ide",
|
||||||
.qdev.size = sizeof(ISAIDEState),
|
.qdev.size = sizeof(ISAIDEState),
|
||||||
.init = isa_ide_initfn,
|
.init = isa_ide_initfn,
|
||||||
|
.qdev.reset = isa_ide_reset,
|
||||||
.qdev.props = (Property[]) {
|
.qdev.props = (Property[]) {
|
||||||
DEFINE_PROP_HEX32("iobase", ISAIDEState, iobase, 0x1f0),
|
DEFINE_PROP_HEX32("iobase", ISAIDEState, iobase, 0x1f0),
|
||||||
DEFINE_PROP_HEX32("iobase2", ISAIDEState, iobase2, 0x3f6),
|
DEFINE_PROP_HEX32("iobase2", ISAIDEState, iobase2, 0x3f6),
|
||||||
|
@ -307,8 +307,7 @@ static void pmac_ide_reset(void *opaque)
|
|||||||
{
|
{
|
||||||
MACIOIDEState *d = opaque;
|
MACIOIDEState *d = opaque;
|
||||||
|
|
||||||
ide_reset(d->bus.ifs +0);
|
ide_bus_reset(&d->bus);
|
||||||
ide_reset(d->bus.ifs +1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hd_table must contain 4 block drivers */
|
/* hd_table must contain 4 block drivers */
|
||||||
|
@ -110,7 +110,7 @@ static void md_reset(MicroDriveState *s)
|
|||||||
s->pins = 0;
|
s->pins = 0;
|
||||||
s->cycle = 0;
|
s->cycle = 0;
|
||||||
s->ctrl = 0;
|
s->ctrl = 0;
|
||||||
ide_reset(s->bus.ifs);
|
ide_bus_reset(&s->bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t md_attr_read(void *opaque, uint32_t at)
|
static uint8_t md_attr_read(void *opaque, uint32_t at)
|
||||||
|
@ -41,6 +41,13 @@ typedef struct {
|
|||||||
int shift;
|
int shift;
|
||||||
} MMIOState;
|
} MMIOState;
|
||||||
|
|
||||||
|
static void mmio_ide_reset(void *opaque)
|
||||||
|
{
|
||||||
|
MMIOState *s = opaque;
|
||||||
|
|
||||||
|
ide_bus_reset(&s->bus);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
|
static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
MMIOState *s = opaque;
|
MMIOState *s = opaque;
|
||||||
@ -127,5 +134,6 @@ void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
|
|||||||
cpu_register_physical_memory(membase, 16 << shift, mem1);
|
cpu_register_physical_memory(membase, 16 << shift, mem1);
|
||||||
cpu_register_physical_memory(membase2, 2 << shift, mem2);
|
cpu_register_physical_memory(membase2, 2 << shift, mem2);
|
||||||
vmstate_register(0, &vmstate_ide_mmio, s);
|
vmstate_register(0, &vmstate_ide_mmio, s);
|
||||||
|
qemu_register_reset(mmio_ide_reset, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +101,10 @@ static void piix3_reset(void *opaque)
|
|||||||
uint8_t *pci_conf = d->dev.config;
|
uint8_t *pci_conf = d->dev.config;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++) {
|
||||||
ide_dma_cancel(&d->bmdma[i]);
|
ide_bus_reset(&d->bus[i]);
|
||||||
|
ide_dma_reset(&d->bmdma[i]);
|
||||||
|
}
|
||||||
|
|
||||||
pci_conf[0x04] = 0x00;
|
pci_conf[0x04] = 0x00;
|
||||||
pci_conf[0x05] = 0x00;
|
pci_conf[0x05] = 0x00;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user