Kernel: Use Processor::wait_check in loops waiting for HW to respond

This gives the processor the hint that it is in a hot loop and allows us
to do other work in between
This commit is contained in:
Hendiadyoin1 2023-09-12 14:58:55 +02:00 committed by Andrew Kaster
parent cbaa3465a8
commit a2810d3cf8
9 changed files with 31 additions and 36 deletions

View file

@ -64,13 +64,13 @@ static void wait_until_we_can_write(MMIO& mmio)
// Since nothing else writes to the mailbox, this wait is mostly cargo-culted. // Since nothing else writes to the mailbox, this wait is mostly cargo-culted.
// Most baremetal tutorials on the internet query MBOX_READ_STATUS here, which I think is incorrect and only works because this wait really isn't needed. // Most baremetal tutorials on the internet query MBOX_READ_STATUS here, which I think is incorrect and only works because this wait really isn't needed.
while (mmio.read(MBOX_WRITE_STATUS) & MBOX_FULL) while (mmio.read(MBOX_WRITE_STATUS) & MBOX_FULL)
; Processor::wait_check();
} }
static void wait_for_reply(MMIO& mmio) static void wait_for_reply(MMIO& mmio)
{ {
while (mmio.read(MBOX_READ_STATUS) & MBOX_EMPTY) while (mmio.read(MBOX_READ_STATUS) & MBOX_EMPTY)
; Processor::wait_check();
} }
bool Mailbox::send_queue(void* queue, u32 queue_size) const bool Mailbox::send_queue(void* queue, u32 queue_size) const

View file

@ -114,7 +114,7 @@ ErrorOr<size_t> MiniUART::write(Kernel::OpenFileDescription& description, u64, K
void MiniUART::put_char(u8 ch) void MiniUART::put_char(u8 ch)
{ {
while ((m_registers->line_status & TransmitterEmpty) == 0) while ((m_registers->line_status & TransmitterEmpty) == 0)
; Processor::wait_check();
if (ch == '\n' && !m_last_put_char_was_carriage_return) if (ch == '\n' && !m_last_put_char_was_carriage_return)
m_registers->io_data = '\r'; m_registers->io_data = '\r';

View file

@ -160,13 +160,13 @@ void UART::set_baud_rate(int baud_rate, int uart_frequency_in_hz)
void UART::wait_until_we_can_send() void UART::wait_until_we_can_send()
{ {
while (m_registers->flag & TransmitFifoFull) while (m_registers->flag & TransmitFifoFull)
; Processor::wait_check();
} }
void UART::wait_until_we_can_receive() void UART::wait_until_we_can_receive()
{ {
while (m_registers->flag & ReceiveFifoEmpty) while (m_registers->flag & ReceiveFifoEmpty)
; Processor::wait_check();
} }
} }

View file

@ -7,6 +7,7 @@
#include <Kernel/Arch/DebugOutput.h> #include <Kernel/Arch/DebugOutput.h>
#include <Kernel/Arch/x86_64/BochsDebugOutput.h> #include <Kernel/Arch/x86_64/BochsDebugOutput.h>
#include <Kernel/Arch/x86_64/IO.h> #include <Kernel/Arch/x86_64/IO.h>
#include <Kernel/Arch/x86_64/Processor.h>
namespace Kernel { namespace Kernel {
@ -35,7 +36,7 @@ void debug_output(char ch)
} }
while ((IO::in8(serial_com1_io_port + 5) & 0x20) == 0) while ((IO::in8(serial_com1_io_port + 5) & 0x20) == 0)
; Processor::wait_check();
if (ch == '\n' && !was_cr) if (ch == '\n' && !was_cr)
IO::out8(serial_com1_io_port, '\r'); IO::out8(serial_com1_io_port, '\r');

View file

@ -91,7 +91,7 @@ UNMAP_AFTER_INIT bool APICTimer::calibrate(HardwareTimerBase& calibration_source
sti(); sti();
// Loop for about 100 ms // Loop for about 100 ms
while (state.calibration_ticks.load() <= state.ticks_in_100ms) while (state.calibration_ticks.load() <= state.ticks_in_100ms)
; Processor::wait_check();
cli(); cli();
// Restore timer callbacks // Restore timer callbacks

View file

@ -66,7 +66,7 @@ ErrorOr<size_t> SerialDevice::write(OpenFileDescription& description, u64, UserO
void SerialDevice::put_char(char ch) void SerialDevice::put_char(char ch)
{ {
while ((get_line_status() & EmptyTransmitterHoldingRegister) == 0) while ((get_line_status() & EmptyTransmitterHoldingRegister) == 0)
; Processor::wait_check();
if (ch == '\n' && !m_last_put_char_was_carriage_return) if (ch == '\n' && !m_last_put_char_was_carriage_return)
m_registers_io_window->write8(0, '\r'); m_registers_io_window->write8(0, '\r');

View file

@ -255,15 +255,9 @@ UNMAP_AFTER_INIT u32 E1000ENetworkAdapter::read_eeprom(u8 address)
VERIFY(m_has_eeprom); VERIFY(m_has_eeprom);
u16 data = 0; u16 data = 0;
u32 tmp = 0; u32 tmp = 0;
if (m_has_eeprom) { out32(REG_EEPROM, ((u32)address << 2) | 1);
out32(REG_EEPROM, ((u32)address << 2) | 1); while (!((tmp = in32(REG_EEPROM)) & (1 << 1)))
while (!((tmp = in32(REG_EEPROM)) & (1 << 1))) Processor::wait_check();
;
} else {
out32(REG_EEPROM, ((u32)address << 2) | 1);
while (!((tmp = in32(REG_EEPROM)) & (1 << 1)))
;
}
data = (tmp >> 16) & 0xffff; data = (tmp >> 16) & 0xffff;
return data; return data;
} }

View file

@ -294,11 +294,11 @@ UNMAP_AFTER_INIT u32 E1000NetworkAdapter::read_eeprom(u8 address)
if (m_has_eeprom) { if (m_has_eeprom) {
out32(REG_EEPROM, ((u32)address << 8) | 1); out32(REG_EEPROM, ((u32)address << 8) | 1);
while (!((tmp = in32(REG_EEPROM)) & (1 << 4))) while (!((tmp = in32(REG_EEPROM)) & (1 << 4)))
; Processor::wait_check();
} else { } else {
out32(REG_EEPROM, ((u32)address << 2) | 1); out32(REG_EEPROM, ((u32)address << 2) | 1);
while (!((tmp = in32(REG_EEPROM)) & (1 << 1))) while (!((tmp = in32(REG_EEPROM)) & (1 << 1)))
; Processor::wait_check();
} }
data = (tmp >> 16) & 0xffff; data = (tmp >> 16) & 0xffff;
return data; return data;

View file

@ -287,7 +287,7 @@ UNMAP_AFTER_INIT ErrorOr<void> RTL8168NetworkAdapter::initialize(Badge<Networkin
out8(REG_IBCR2, in8(REG_IBCR2) & ~1); out8(REG_IBCR2, in8(REG_IBCR2) & ~1);
while ((in32(REG_IBISR0) & 0x2) != 0) while ((in32(REG_IBISR0) & 0x2) != 0)
; Processor::wait_check();
out8(REG_IBISR0, in8(REG_IBISR0) | 0x20); out8(REG_IBISR0, in8(REG_IBISR0) | 0x20);
out8(REG_IBCR0, in8(REG_IBCR0) & ~1); out8(REG_IBCR0, in8(REG_IBCR0) & ~1);
@ -299,10 +299,10 @@ UNMAP_AFTER_INIT ErrorOr<void> RTL8168NetworkAdapter::initialize(Badge<Networkin
out32(REG_MISC, in32(REG_MISC) | MISC_RXDV_GATE_ENABLE); out32(REG_MISC, in32(REG_MISC) | MISC_RXDV_GATE_ENABLE);
while ((in32(REG_TXCFG) & TXCFG_EMPTY) == 0) while ((in32(REG_TXCFG) & TXCFG_EMPTY) == 0)
; Processor::wait_check();
while ((in32(REG_MCU) & (MCU_RX_EMPTY | MCU_TX_EMPTY)) == 0) while ((in32(REG_MCU) & (MCU_RX_EMPTY | MCU_TX_EMPTY)) == 0)
; Processor::wait_check();
out8(REG_COMMAND, in8(REG_COMMAND) & ~(COMMAND_RX_ENABLE | COMMAND_TX_ENABLE)); out8(REG_COMMAND, in8(REG_COMMAND) & ~(COMMAND_RX_ENABLE | COMMAND_TX_ENABLE));
out8(REG_MCU, in8(REG_MCU) & ~MCU_NOW_IS_OOB); out8(REG_MCU, in8(REG_MCU) & ~MCU_NOW_IS_OOB);
@ -313,7 +313,7 @@ UNMAP_AFTER_INIT ErrorOr<void> RTL8168NetworkAdapter::initialize(Badge<Networkin
ocp_out(0xe8de, data); ocp_out(0xe8de, data);
while ((in32(REG_MCU) & MCU_LINK_LIST_READY) == 0) while ((in32(REG_MCU) & MCU_LINK_LIST_READY) == 0)
; Processor::wait_check();
// vendor magic values ??? // vendor magic values ???
data = ocp_in(0xe8de); data = ocp_in(0xe8de);
@ -321,7 +321,7 @@ UNMAP_AFTER_INIT ErrorOr<void> RTL8168NetworkAdapter::initialize(Badge<Networkin
ocp_out(0xe8de, data); ocp_out(0xe8de, data);
while ((in32(REG_MCU) & MCU_LINK_LIST_READY) == 0) while ((in32(REG_MCU) & MCU_LINK_LIST_READY) == 0)
; Processor::wait_check();
} }
// software reset // software reset
@ -365,7 +365,7 @@ void RTL8168NetworkAdapter::startup()
// software reset phy // software reset phy
phy_out(PHY_REG_BMCR, phy_in(PHY_REG_BMCR) | BMCR_RESET); phy_out(PHY_REG_BMCR, phy_in(PHY_REG_BMCR) | BMCR_RESET);
while ((phy_in(PHY_REG_BMCR) & BMCR_RESET) != 0) while ((phy_in(PHY_REG_BMCR) & BMCR_RESET) != 0)
; Processor::wait_check();
set_phy_speed(); set_phy_speed();
@ -1181,7 +1181,7 @@ void RTL8168NetworkAdapter::reset()
{ {
out8(REG_COMMAND, COMMAND_RESET); out8(REG_COMMAND, COMMAND_RESET);
while ((in8(REG_COMMAND) & COMMAND_RESET) != 0) while ((in8(REG_COMMAND) & COMMAND_RESET) != 0)
; Processor::wait_check();
} }
UNMAP_AFTER_INIT void RTL8168NetworkAdapter::read_mac_address() UNMAP_AFTER_INIT void RTL8168NetworkAdapter::read_mac_address()
@ -1315,7 +1315,7 @@ void RTL8168NetworkAdapter::phy_out(u8 address, u16 data)
VERIFY((address & 0xE0) == 0); // register address is only 5 bit VERIFY((address & 0xE0) == 0); // register address is only 5 bit
out32(REG_PHYACCESS, PHY_FLAG | (address & 0x1F) << 16 | (data & 0xFFFF)); out32(REG_PHYACCESS, PHY_FLAG | (address & 0x1F) << 16 | (data & 0xFFFF));
while ((in32(REG_PHYACCESS) & PHY_FLAG) != 0) while ((in32(REG_PHYACCESS) & PHY_FLAG) != 0)
; Processor::wait_check();
} }
} }
@ -1334,7 +1334,7 @@ u16 RTL8168NetworkAdapter::phy_in(u8 address)
VERIFY((address & 0xE0) == 0); // register address is only 5 bit VERIFY((address & 0xE0) == 0); // register address is only 5 bit
out32(REG_PHYACCESS, (address & 0x1F) << 16); out32(REG_PHYACCESS, (address & 0x1F) << 16);
while ((in32(REG_PHYACCESS) & PHY_FLAG) == 0) while ((in32(REG_PHYACCESS) & PHY_FLAG) == 0)
; Processor::wait_check();
return in32(REG_PHYACCESS) & 0xFFFF; return in32(REG_PHYACCESS) & 0xFFFF;
} }
} }
@ -1357,7 +1357,7 @@ void RTL8168NetworkAdapter::extended_phy_out(u8 address, u16 data)
VERIFY((address & 0xE0) == 0); // register address is only 5 bit VERIFY((address & 0xE0) == 0); // register address is only 5 bit
out32(REG_EPHYACCESS, EPHY_FLAG | (address & 0x1F) << 16 | (data & 0xFFFF)); out32(REG_EPHYACCESS, EPHY_FLAG | (address & 0x1F) << 16 | (data & 0xFFFF));
while ((in32(REG_EPHYACCESS) & EPHY_FLAG) != 0) while ((in32(REG_EPHYACCESS) & EPHY_FLAG) != 0)
; Processor::wait_check();
} }
u16 RTL8168NetworkAdapter::extended_phy_in(u8 address) u16 RTL8168NetworkAdapter::extended_phy_in(u8 address)
@ -1365,7 +1365,7 @@ u16 RTL8168NetworkAdapter::extended_phy_in(u8 address)
VERIFY((address & 0xE0) == 0); // register address is only 5 bit VERIFY((address & 0xE0) == 0); // register address is only 5 bit
out32(REG_EPHYACCESS, (address & 0x1F) << 16); out32(REG_EPHYACCESS, (address & 0x1F) << 16);
while ((in32(REG_EPHYACCESS) & EPHY_FLAG) == 0) while ((in32(REG_EPHYACCESS) & EPHY_FLAG) == 0)
; Processor::wait_check();
return in32(REG_EPHYACCESS) & 0xFFFF; return in32(REG_EPHYACCESS) & 0xFFFF;
} }
@ -1382,14 +1382,14 @@ void RTL8168NetworkAdapter::eri_out(u32 address, u32 mask, u32 data, u32 type)
out32(REG_ERI_DATA, data); out32(REG_ERI_DATA, data);
out32(REG_ERI_ADDR, ERI_FLAG | type | mask | address); out32(REG_ERI_ADDR, ERI_FLAG | type | mask | address);
while ((in32(REG_ERI_ADDR) & ERI_FLAG) != 0) while ((in32(REG_ERI_ADDR) & ERI_FLAG) != 0)
; Processor::wait_check();
} }
u32 RTL8168NetworkAdapter::eri_in(u32 address, u32 type) u32 RTL8168NetworkAdapter::eri_in(u32 address, u32 type)
{ {
out32(REG_ERI_ADDR, type | ERI_MASK_1111 | address); out32(REG_ERI_ADDR, type | ERI_MASK_1111 | address);
while ((in32(REG_ERI_ADDR) & ERI_FLAG) == 0) while ((in32(REG_ERI_ADDR) & ERI_FLAG) == 0)
; Processor::wait_check();
return in32(REG_ERI_DATA); return in32(REG_ERI_DATA);
} }
@ -1418,7 +1418,7 @@ void RTL8168NetworkAdapter::csi_out(u32 address, u32 data)
} }
out32(REG_CSI_ADDR, CSI_FLAG | (address & 0xFFF) | modifier); out32(REG_CSI_ADDR, CSI_FLAG | (address & 0xFFF) | modifier);
while ((in32(REG_CSI_ADDR) & CSI_FLAG) != 0) while ((in32(REG_CSI_ADDR) & CSI_FLAG) != 0)
; Processor::wait_check();
} }
u32 RTL8168NetworkAdapter::csi_in(u32 address) u32 RTL8168NetworkAdapter::csi_in(u32 address)
@ -1432,7 +1432,7 @@ u32 RTL8168NetworkAdapter::csi_in(u32 address)
} }
out32(REG_CSI_ADDR, (address & 0xFFF) | modifier); out32(REG_CSI_ADDR, (address & 0xFFF) | modifier);
while ((in32(REG_CSI_ADDR) & CSI_FLAG) == 0) while ((in32(REG_CSI_ADDR) & CSI_FLAG) == 0)
; Processor::wait_check();
return in32(REG_CSI_DATA) & 0xFFFF; return in32(REG_CSI_DATA) & 0xFFFF;
} }
@ -1460,7 +1460,7 @@ void RTL8168NetworkAdapter::ocp_phy_out(u32 address, u32 data)
VERIFY((address & 0xFFFF0001) == 0); VERIFY((address & 0xFFFF0001) == 0);
out32(REG_GPHY_OCP, OCP_FLAG | (address << 15) | data); out32(REG_GPHY_OCP, OCP_FLAG | (address << 15) | data);
while ((in32(REG_GPHY_OCP) & OCP_FLAG) != 0) while ((in32(REG_GPHY_OCP) & OCP_FLAG) != 0)
; Processor::wait_check();
} }
u16 RTL8168NetworkAdapter::ocp_phy_in(u32 address) u16 RTL8168NetworkAdapter::ocp_phy_in(u32 address)
@ -1468,7 +1468,7 @@ u16 RTL8168NetworkAdapter::ocp_phy_in(u32 address)
VERIFY((address & 0xFFFF0001) == 0); VERIFY((address & 0xFFFF0001) == 0);
out32(REG_GPHY_OCP, address << 15); out32(REG_GPHY_OCP, address << 15);
while ((in32(REG_GPHY_OCP) & OCP_FLAG) == 0) while ((in32(REG_GPHY_OCP) & OCP_FLAG) == 0)
; Processor::wait_check();
return in32(REG_GPHY_OCP) & 0xFFFF; return in32(REG_GPHY_OCP) & 0xFFFF;
} }