This thing really needs a rework...

This commit is contained in:
StrikerX3 2018-12-09 19:58:09 -02:00
parent 84f6dd48bc
commit 8cf4830d0c
6 changed files with 29 additions and 10 deletions

View file

@ -194,11 +194,15 @@ void ATAChannel::WriteCommand(uint8_t value) {
auto dev = m_devs[devIndex];
// Check that there is no command in progress
// Use double-checked locking to avoid locking when there is no command (the common case)
if (m_currentCommand != nullptr) {
log_warning("ATAChannel::WriteCommand: Trying to run command while another command is in progress\n", value);
m_regs.status |= StError;
SetInterrupt(true);
return;
std::lock_guard<std::mutex> lk(m_commandMutex);
if (m_currentCommand != nullptr) {
log_warning("ATAChannel::WriteCommand: Trying to run command while another command is in progress\n", value);
m_regs.status |= StError;
SetInterrupt(true);
return;
}
}
// Check that the command has a factory associated with it
@ -209,7 +213,7 @@ void ATAChannel::WriteCommand(uint8_t value) {
return;
}
//log_spew("ATAChannel::WriteCommand: Processing command 0x%x for channel %d, device %d\n", cmd, m_channel, devIndex);
log_spew("ATAChannel::WriteCommand: Processing command 0x%x for channel %d, device %d\n", cmd, m_channel, devIndex);
// Instantiate the command
auto factory = kCmdFactories.at(cmd);
@ -238,9 +242,13 @@ DMATransferResult ATAChannel::ReadDMA(uint8_t *dstBuffer, uint32_t readLen) {
}
// Read data for the command and clear it if finished
std::lock_guard<std::mutex> lk(m_commandMutex);
m_currentCommand->ReadData(dstBuffer, readLen);
if (m_currentCommand->IsFinished()) {
log_spew("ATAChannel::ReadDMA: Finished processing command for channel %d\n", m_channel);
if (m_currentCommand == nullptr) {
log_spew("This thing broke :(\n", m_channel);
}
delete m_currentCommand;
m_currentCommand = nullptr;
return DMATransferEnd;
@ -258,9 +266,13 @@ DMATransferResult ATAChannel::WriteDMA(uint8_t *srcBuffer, uint32_t writeLen) {
}
// Write data for the command and clear it if finished
std::lock_guard<std::mutex> lk(m_commandMutex);
m_currentCommand->WriteData(srcBuffer, writeLen);
if (m_currentCommand->IsFinished()) {
log_spew("ATAChannel::WriteDMA: Finished processing command for channel %d\n", m_channel);
if (m_currentCommand == nullptr) {
log_spew("This thing broke :(\n", m_channel);
}
delete m_currentCommand;
m_currentCommand = nullptr;
return DMATransferEnd;
@ -271,7 +283,7 @@ DMATransferResult ATAChannel::WriteDMA(uint8_t *srcBuffer, uint32_t writeLen) {
void ATAChannel::SetInterrupt(bool asserted) {
if (asserted != m_interrupt && m_regs.AreInterruptsEnabled()) {
log_spew("ATAChannel::SetInterrupt: %s interrupt for channel %d\n", (asserted ? "asserting" : "negating"), m_channel);
//log_spew("ATAChannel::SetInterrupt: %s interrupt for channel %d\n", (asserted ? "asserting" : "negating"), m_channel);
m_interrupt = asserted;
for (auto it = m_intrHooks.begin(); it != m_intrHooks.end(); it++) {
(*it)->OnChange(asserted);

View file

@ -13,6 +13,8 @@
#include <cstdint>
#include <mutex>
#include "vixen/cpu.h"
#include "../basic/irq.h"
#include "../basic/interrupt.h"
@ -103,7 +105,9 @@ private:
// ----- State ------------------------------------------------------------
bool m_interrupt = false; // [5.2.9] INTRQ (Device Interrupt)
cmd::IATACommand *m_currentCommand;
std::mutex m_commandMutex;
// ----- Interrupt handling -----------------------------------------------

View file

@ -109,6 +109,7 @@ void PacketProtocolCommand::ReadData(uint8_t *value, uint32_t size) {
}
// Copy from buffer to value
// TODO: handle partial transfers
memcpy(value, m_packetDataBuffer + m_packetDataPos, size);
m_packetDataPos += size;
@ -148,6 +149,7 @@ void PacketProtocolCommand::WriteData(uint8_t *value, uint32_t size) {
}
else {
// Writing the data requested by the Packet command
// TODO: handle partial transfers
memcpy(m_packetDataBuffer + m_packetDataPos, value, size);
m_packetDataPos += size;
@ -379,6 +381,7 @@ void PacketProtocolCommand::HandleProtocolTail(bool hasError) {
m_regs.status |= StReady;
m_regs.status &= ~StBusy;
m_interrupt.Assert();
log_spew("PacketProtocolCommand::HandleProtocolTail: Packet command finished\n");
Finish();
}

View file

@ -166,7 +166,7 @@ bool BaseDVDDriveATADeviceDriver::ValidateCommand(PacketInformation& packetInfo)
packetInfo.transferSize = (uint32_t)B2L16(packetInfo.cdb.read10.length) * kDVDSectorSize;
return true;
case OpReadDVDStructure:
packetInfo.transferSize = B2L16(packetInfo.cdb.readDVDStructure.length);
packetInfo.transferSize = kDVDSectorSize;
return true;
default:
return true;

View file

@ -199,7 +199,7 @@ bool ImageDVDDriveATADeviceDriver::ProcessATAPIPacketDataRead(PacketInformation&
case OpReadDVDStructure:
{
ReadDVDStructureData *dvdData = reinterpret_cast<ReadDVDStructureData *>(packetDataBuffer);
memset(dvdData, 0, sizeof(ReadDVDStructureData));
memset(dvdData, 0, kDVDSectorSize);
switch (packetInfo.cdb.readDVDStructure.format) {
case DVDFmtPhysical:
L2B16(dvdData->dataLength, (uint16_t)sizeof(ReadDVDStructureData::physicalFormatInformation));
@ -218,7 +218,7 @@ bool ImageDVDDriveATADeviceDriver::ProcessATAPIPacketDataRead(PacketInformation&
L2B24(dvdData->physicalFormatInformation.layer0EndingSector, 0);
dvdData->physicalFormatInformation.burstCuttingArea = 0;
*packetDataSize = sizeof(ReadDVDStructureData);
*packetDataSize = kDVDSectorSize;
return true;
default:
log_debug("ImageDVDDriveATADeviceDriver::ProcessATAPIPacketDataRead: Unimplemented format 0x%x for READ DVD STRUCTURE\n", packetInfo.cdb.readDVDStructure.format);

View file

@ -76,7 +76,7 @@ private:
void OnChange(bool asserted) override {
if (asserted) {
m_channel.m_status |= StInterrupt;
log_spew("BM IDE channel %d: Interrupt asserted\n", m_channel.m_channel);
//log_spew("BM IDE channel %d: Interrupt asserted\n", m_channel.m_channel);
}
}