mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 13:17:36 +00:00
Kernel: Ensure that we receive IRQs in PIO mode when IOAPIC is enabled
The IOAPIC manual states that "Interrupt Mask-R/W. When this bit is 1, the interrupt signal is masked. Edge-sensitive interrupts signaled on a masked interrupt pin are ignored." - Therefore we have to ensure that we disable interrupts globally with cli(), but also to ensure that we invoke enable_irq() before sending the hardware command that generates an IRQ almost immediately.
This commit is contained in:
parent
4c0ec846a8
commit
d6318f2cc6
1 changed files with 9 additions and 2 deletions
|
@ -183,6 +183,8 @@ void PATAChannel::wait_for_irq()
|
||||||
|
|
||||||
void PATAChannel::handle_irq(const RegisterState&)
|
void PATAChannel::handle_irq(const RegisterState&)
|
||||||
{
|
{
|
||||||
|
// FIXME: We might get random interrupts due to malfunctioning hardware, so we should check that we actually requested something to happen.
|
||||||
|
|
||||||
u8 status = m_io_base.offset(ATA_REG_STATUS).in<u8>();
|
u8 status = m_io_base.offset(ATA_REG_STATUS).in<u8>();
|
||||||
if (status & ATA_SR_ERR) {
|
if (status & ATA_SR_ERR) {
|
||||||
print_ide_status(status);
|
print_ide_status(status);
|
||||||
|
@ -443,6 +445,7 @@ bool PATAChannel::ata_read_sectors(u32 lba, u16 count, u8* outbuf, bool slave_re
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepare_for_irq();
|
||||||
m_io_base.offset(ATA_REG_COMMAND).out<u8>(ATA_CMD_READ_PIO);
|
m_io_base.offset(ATA_REG_COMMAND).out<u8>(ATA_CMD_READ_PIO);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
@ -458,10 +461,15 @@ bool PATAChannel::ata_read_sectors(u32 lba, u16 count, u8* outbuf, bool slave_re
|
||||||
#ifdef PATA_DEBUG
|
#ifdef PATA_DEBUG
|
||||||
dbg() << "PATAChannel: Retrieving 512 bytes (part " << i << ") (status=" << String::format("%b", status) << "), outbuf=(" << buffer << ")...";
|
dbg() << "PATAChannel: Retrieving 512 bytes (part " << i << ") (status=" << String::format("%b", status) << "), outbuf=(" << buffer << ")...";
|
||||||
#endif
|
#endif
|
||||||
|
prepare_for_irq();
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
buffer[i] = IO::in16(m_io_base.offset(ATA_REG_DATA).get());
|
buffer[i] = IO::in16(m_io_base.offset(ATA_REG_DATA).get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sti();
|
||||||
|
disable_irq();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,12 +515,11 @@ bool PATAChannel::ata_write_sectors(u32 start_sector, u16 count, const u8* inbuf
|
||||||
#ifdef PATA_DEBUG
|
#ifdef PATA_DEBUG
|
||||||
dbg() << "PATAChannel: Writing 512 bytes (part " << i << ") (status=" << String::format("%b", status) << "), inbuf=(" << (inbuf + (512 * i)) << ")...";
|
dbg() << "PATAChannel: Writing 512 bytes (part " << i << ") (status=" << String::format("%b", status) << "), inbuf=(" << (inbuf + (512 * i)) << ")...";
|
||||||
#endif
|
#endif
|
||||||
|
prepare_for_irq();
|
||||||
auto* buffer = (u16*)(const_cast<u8*>(inbuf) + i * 512);
|
auto* buffer = (u16*)(const_cast<u8*>(inbuf) + i * 512);
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
IO::out16(m_io_base.offset(ATA_REG_DATA).get(), buffer[i]);
|
IO::out16(m_io_base.offset(ATA_REG_DATA).get(), buffer[i]);
|
||||||
}
|
}
|
||||||
prepare_for_irq();
|
|
||||||
wait_for_irq();
|
wait_for_irq();
|
||||||
status = m_io_base.offset(ATA_REG_STATUS).in<u8>();
|
status = m_io_base.offset(ATA_REG_STATUS).in<u8>();
|
||||||
ASSERT(!(status & ATA_SR_BSY));
|
ASSERT(!(status & ATA_SR_BSY));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue