Seek delay implemented for ATA/ATAPI DMA read commands

TODO: seek delay for write commands
This commit is contained in:
Volker Ruppert 2014-01-19 18:13:12 +00:00
parent cdf3facaf4
commit 7cb5729365
6 changed files with 60 additions and 13 deletions

View File

@ -1,4 +1,4 @@
Changes after 2.6.2 (updated Dec 16, 2013):
Changes after 2.6.2 (updated Jan 19, 2014):
- CPU
- Bugfixes for CPU emulation correctness (critical fixes for VMX, TBM/BMI and RDRAND instructions)
@ -13,9 +13,11 @@ Changes after 2.6.2 (updated Dec 16, 2013):
- Added disam for Bochs internal instruction representation, especially useful for instrumentation
- Updated definition of instrumentation callbacks, see description in
instrumentation.txt / Fixed instrumentation examples
- added capability to use the gui debugger output window as a log viewer
- General
- Increased max. device log prefix size to 6 and added / modified prefixes
- plugin version now uses the native DLL handling code for all Windows ports
- Configure and compile
- configure and compilation fixes for Cygwin and Visual Studio environment
@ -32,10 +34,11 @@ Changes after 2.6.2 (updated Dec 16, 2013):
- Added bochsrc option for the Voodoo Graphics emulation (experimental)
- I/O Devices
- Hard drive / CD-ROM
- seek delay implemented for ATA/ATAPI read commands
- portable ISO image file access now available on all platforms
- Networking
- slirp/vnet: all supported TFTP extension options implemented now
- CDROM
- portable ISO image file access now available on all platforms
- Sound
- SB16 / ES1370: added volume control support for wave output
- ES1370: added 'wavemode' support similar to the SB16
@ -53,6 +56,7 @@ Changes after 2.6.2 (updated Dec 16, 2013):
- RFB: set maximum resolution to 1280x1024 (same as vncsrv)
- RFB: don't wait for client connection on startup if timeout is set to 0
- Added mouse wheel support to the rfb, vncsrv and wx guis
- wx: added viewer window for the Bochs log output
- Tools
- bximage utility rewritten in C++ for image creation, conversion, resize

View File

@ -654,17 +654,30 @@ void bx_hard_drive_c::seek_timer()
controller->buffer_index = 0;
raise_interrupt(channel);
break;
case 0x25: // READ DMA EXT
case 0xC8: // READ DMA
controller->error_register = 0;
controller->status.busy = 0;
controller->status.drive_ready = 1;
controller->status.seek_complete = 1;
controller->status.drq = 1;
controller->status.corrected_data = 0;
DEV_ide_bmdma_start_transfer(channel);
break;
default:
BX_ERROR(("seek_timer(): command not implemented yet"));
BX_ERROR(("seek_timer(): ATA command 0x%02x not supported",
controller->current_command));
}
} else {
switch (BX_DRIVE(channel, device).atapi.command) {
case 0x28: // read (10)
case 0xa8: // read (12)
case 0xbe: // read cd
ready_to_send_atapi(channel);
break;
default:
BX_ERROR(("seek_timer(): ATAPI command not implemented yet"));
BX_ERROR(("seek_timer(): ATAPI command 0x%02x not supported",
BX_DRIVE(channel, device).atapi.command));
}
}
}
@ -1587,7 +1600,8 @@ void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
transfer_length * controller->buffer_size, 1);
BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
BX_SELECTED_DRIVE(channel).cdrom.next_lba = lba;
ready_to_send_atapi(channel);
bx_pc_system.activate_timer(
BX_DRIVE(channel,BX_SLAVE_SELECTED(channel)).seek_timer_index, 80000, 0);
break;
default:
BX_ERROR(("Read CD: unknown format"));
@ -2349,10 +2363,17 @@ void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
case 0xC8: // READ DMA
if (BX_SELECTED_IS_HD(channel) && BX_HD_THIS bmdma_present()) {
lba48_transform(controller, lba48);
controller->status.drive_ready = 1;
controller->status.seek_complete = 1;
controller->status.drq = 1;
controller->current_command = value;
controller->error_register = 0;
controller->status.busy = 1;
controller->status.drive_ready = 1;
controller->status.seek_complete = 0;
controller->status.drq = 0;
controller->status.corrected_data = 0;
bx_pc_system.activate_timer(
BX_DRIVE(channel,BX_SLAVE_SELECTED(channel)).seek_timer_index, 5000, 0);
DEV_ide_bmdma_start_transfer(channel);
} else {
BX_ERROR(("write cmd 0x%02x (READ DMA) not supported", value));
command_aborted(channel, value);
@ -3105,7 +3126,9 @@ bx_hard_drive_c::ready_to_send_atapi(Bit8u channel)
controller->status.drq = 1;
controller->status.err = 0;
if (!BX_SELECTED_CONTROLLER(channel).packet_dma) {
if (BX_SELECTED_CONTROLLER(channel).packet_dma) {
DEV_ide_bmdma_start_transfer(channel);
} else {
raise_interrupt(channel);
}
}
@ -3263,7 +3286,7 @@ bx_bool bx_hard_drive_c::bmdma_read_sector(Bit8u channel, Bit8u *buffer, Bit32u
}
} else {
BX_ERROR(("DMA read not active"));
command_aborted (channel, controller->current_command);
command_aborted(channel, controller->current_command);
return 0;
}
return 1;

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2013 The Bochs Project
// Copyright (C) 2001-2014 The Bochs Project
//
// I/O port handlers API Copyright (C) 2003 by Frank Cornelis
//
@ -277,6 +277,7 @@ public:
virtual bx_bool bmdma_present(void) {
return 0;
}
virtual void bmdma_start_transfer(Bit8u channel) {}
virtual void bmdma_set_irq(Bit8u channel) {}
};

View File

@ -127,6 +127,7 @@ void bx_pci_ide_c::reset(unsigned type)
BX_PIDE_THIS s.bmdma[i].prd_current = 0;
BX_PIDE_THIS s.bmdma[i].buffer_top = BX_PIDE_THIS s.bmdma[i].buffer;
BX_PIDE_THIS s.bmdma[i].buffer_idx = BX_PIDE_THIS s.bmdma[i].buffer;
BX_PIDE_THIS s.bmdma[i].data_ready = 0;
}
}
@ -154,6 +155,7 @@ void bx_pci_ide_c::register_state(void)
BX_PIDE_THIS param_save_handler, BX_PIDE_THIS param_restore_handler);
BXRS_PARAM_SPECIAL32(ctrl, buffer_idx,
BX_PIDE_THIS param_save_handler, BX_PIDE_THIS param_restore_handler);
BXRS_PARAM_BOOL(ctrl, data_ready, BX_PIDE_THIS s.bmdma[i].data_ready);
}
}
@ -215,6 +217,13 @@ bx_bool bx_pci_ide_c::bmdma_present(void)
return (BX_PIDE_THIS pci_base_address[4] > 0);
}
void bx_pci_ide_c::bmdma_start_transfer(Bit8u channel)
{
if (channel < 2) {
BX_PIDE_THIS s.bmdma[channel].data_ready = 1;
}
}
void bx_pci_ide_c::bmdma_set_irq(Bit8u channel)
{
if (channel < 2) {
@ -242,6 +251,11 @@ void bx_pci_ide_c::timer()
(BX_PIDE_THIS s.bmdma[channel].prd_current == 0)) {
return;
}
if (BX_PIDE_THIS s.bmdma[channel].cmd_rwcon &&
!BX_PIDE_THIS s.bmdma[channel].data_ready) {
bx_pc_system.activate_timer(BX_PIDE_THIS s.bmdma[channel].timer_index, 1000, 0);
return;
}
DEV_MEM_READ_PHYSICAL(BX_PIDE_THIS s.bmdma[channel].prd_current, 4, (Bit8u *)&prd.addr);
DEV_MEM_READ_PHYSICAL(BX_PIDE_THIS s.bmdma[channel].prd_current+4, 4, (Bit8u *)&prd.size);
size = prd.size & 0xfffe;
@ -385,6 +399,7 @@ void bx_pci_ide_c::write(Bit32u address, Bit32u value, unsigned io_len)
BX_PIDE_THIS s.bmdma[channel].prd_current = BX_PIDE_THIS s.bmdma[channel].dtpr;
BX_PIDE_THIS s.bmdma[channel].buffer_top = BX_PIDE_THIS s.bmdma[channel].buffer;
BX_PIDE_THIS s.bmdma[channel].buffer_idx = BX_PIDE_THIS s.bmdma[channel].buffer;
BX_PIDE_THIS s.bmdma[channel].data_ready = 0;
bx_pc_system.activate_timer(BX_PIDE_THIS s.bmdma[channel].timer_index, 1000, 0);
} else if (!(value & 0x01) && BX_PIDE_THIS s.bmdma[channel].cmd_ssbm) {
BX_PIDE_THIS s.bmdma[channel].cmd_ssbm = 0;

View File

@ -38,6 +38,7 @@ public:
virtual void init(void);
virtual void reset(unsigned type);
virtual bx_bool bmdma_present(void);
virtual void bmdma_start_transfer(Bit8u channel);
virtual void bmdma_set_irq(Bit8u channel);
virtual void register_state(void);
virtual void after_restore_state(void);
@ -68,6 +69,7 @@ private:
Bit8u *buffer;
Bit8u *buffer_top;
Bit8u *buffer_idx;
bx_bool data_ready;
} bmdma[2];
} s;

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2013 The Bochs Project
// Copyright (C) 2002-2014 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -232,6 +232,8 @@ extern "C" {
(bx_devices.pci_set_base_io(a,b,c,d,e,f,g,h))
#define DEV_ide_bmdma_present() bx_devices.pluginPciIdeController->bmdma_present()
#define DEV_ide_bmdma_set_irq(a) bx_devices.pluginPciIdeController->bmdma_set_irq(a)
#define DEV_ide_bmdma_start_transfer(a) \
bx_devices.pluginPciIdeController->bmdma_start_transfer(a)
#define DEV_acpi_generate_smi(a) bx_devices.pluginACPIController->generate_smi(a)
///////// Speaker macros