From a2810d3cf8d852581ffada1b5167e5652f6362f3 Mon Sep 17 00:00:00 2001 From: Hendiadyoin1 Date: Tue, 12 Sep 2023 14:58:55 +0200 Subject: [PATCH] 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 --- Kernel/Arch/aarch64/RPi/Mailbox.cpp | 4 +-- Kernel/Arch/aarch64/RPi/MiniUART.cpp | 2 +- Kernel/Arch/aarch64/RPi/UART.cpp | 4 +-- Kernel/Arch/x86_64/DebugOutput.cpp | 3 +- Kernel/Arch/x86_64/Time/APICTimer.cpp | 2 +- Kernel/Devices/SerialDevice.cpp | 2 +- Kernel/Net/Intel/E1000ENetworkAdapter.cpp | 12 ++----- Kernel/Net/Intel/E1000NetworkAdapter.cpp | 4 +-- Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp | 34 ++++++++++---------- 9 files changed, 31 insertions(+), 36 deletions(-) diff --git a/Kernel/Arch/aarch64/RPi/Mailbox.cpp b/Kernel/Arch/aarch64/RPi/Mailbox.cpp index 87cdc22c59..9743ce2985 100644 --- a/Kernel/Arch/aarch64/RPi/Mailbox.cpp +++ b/Kernel/Arch/aarch64/RPi/Mailbox.cpp @@ -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. // 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) - ; + Processor::wait_check(); } static void wait_for_reply(MMIO& mmio) { while (mmio.read(MBOX_READ_STATUS) & MBOX_EMPTY) - ; + Processor::wait_check(); } bool Mailbox::send_queue(void* queue, u32 queue_size) const diff --git a/Kernel/Arch/aarch64/RPi/MiniUART.cpp b/Kernel/Arch/aarch64/RPi/MiniUART.cpp index f44cc4d167..812f7d9470 100644 --- a/Kernel/Arch/aarch64/RPi/MiniUART.cpp +++ b/Kernel/Arch/aarch64/RPi/MiniUART.cpp @@ -114,7 +114,7 @@ ErrorOr MiniUART::write(Kernel::OpenFileDescription& description, u64, K void MiniUART::put_char(u8 ch) { while ((m_registers->line_status & TransmitterEmpty) == 0) - ; + Processor::wait_check(); if (ch == '\n' && !m_last_put_char_was_carriage_return) m_registers->io_data = '\r'; diff --git a/Kernel/Arch/aarch64/RPi/UART.cpp b/Kernel/Arch/aarch64/RPi/UART.cpp index 70bc77e06d..9d8698d961 100644 --- a/Kernel/Arch/aarch64/RPi/UART.cpp +++ b/Kernel/Arch/aarch64/RPi/UART.cpp @@ -160,13 +160,13 @@ void UART::set_baud_rate(int baud_rate, int uart_frequency_in_hz) void UART::wait_until_we_can_send() { while (m_registers->flag & TransmitFifoFull) - ; + Processor::wait_check(); } void UART::wait_until_we_can_receive() { while (m_registers->flag & ReceiveFifoEmpty) - ; + Processor::wait_check(); } } diff --git a/Kernel/Arch/x86_64/DebugOutput.cpp b/Kernel/Arch/x86_64/DebugOutput.cpp index b2eef62296..7eca11c0a6 100644 --- a/Kernel/Arch/x86_64/DebugOutput.cpp +++ b/Kernel/Arch/x86_64/DebugOutput.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace Kernel { @@ -35,7 +36,7 @@ void debug_output(char ch) } while ((IO::in8(serial_com1_io_port + 5) & 0x20) == 0) - ; + Processor::wait_check(); if (ch == '\n' && !was_cr) IO::out8(serial_com1_io_port, '\r'); diff --git a/Kernel/Arch/x86_64/Time/APICTimer.cpp b/Kernel/Arch/x86_64/Time/APICTimer.cpp index 4ce20a9142..c911c5b59f 100644 --- a/Kernel/Arch/x86_64/Time/APICTimer.cpp +++ b/Kernel/Arch/x86_64/Time/APICTimer.cpp @@ -91,7 +91,7 @@ UNMAP_AFTER_INIT bool APICTimer::calibrate(HardwareTimerBase& calibration_source sti(); // Loop for about 100 ms while (state.calibration_ticks.load() <= state.ticks_in_100ms) - ; + Processor::wait_check(); cli(); // Restore timer callbacks diff --git a/Kernel/Devices/SerialDevice.cpp b/Kernel/Devices/SerialDevice.cpp index 1432b6fc7d..fce9fe6e36 100644 --- a/Kernel/Devices/SerialDevice.cpp +++ b/Kernel/Devices/SerialDevice.cpp @@ -66,7 +66,7 @@ ErrorOr SerialDevice::write(OpenFileDescription& description, u64, UserO void SerialDevice::put_char(char ch) { while ((get_line_status() & EmptyTransmitterHoldingRegister) == 0) - ; + Processor::wait_check(); if (ch == '\n' && !m_last_put_char_was_carriage_return) m_registers_io_window->write8(0, '\r'); diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp index 13f37af1c1..20d4d954f1 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp @@ -255,15 +255,9 @@ UNMAP_AFTER_INIT u32 E1000ENetworkAdapter::read_eeprom(u8 address) VERIFY(m_has_eeprom); u16 data = 0; u32 tmp = 0; - if (m_has_eeprom) { - out32(REG_EEPROM, ((u32)address << 2) | 1); - while (!((tmp = in32(REG_EEPROM)) & (1 << 1))) - ; - } else { - out32(REG_EEPROM, ((u32)address << 2) | 1); - while (!((tmp = in32(REG_EEPROM)) & (1 << 1))) - ; - } + out32(REG_EEPROM, ((u32)address << 2) | 1); + while (!((tmp = in32(REG_EEPROM)) & (1 << 1))) + Processor::wait_check(); data = (tmp >> 16) & 0xffff; return data; } diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.cpp b/Kernel/Net/Intel/E1000NetworkAdapter.cpp index 1f13e62255..135ce2edb7 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000NetworkAdapter.cpp @@ -294,11 +294,11 @@ UNMAP_AFTER_INIT u32 E1000NetworkAdapter::read_eeprom(u8 address) if (m_has_eeprom) { out32(REG_EEPROM, ((u32)address << 8) | 1); while (!((tmp = in32(REG_EEPROM)) & (1 << 4))) - ; + Processor::wait_check(); } else { out32(REG_EEPROM, ((u32)address << 2) | 1); while (!((tmp = in32(REG_EEPROM)) & (1 << 1))) - ; + Processor::wait_check(); } data = (tmp >> 16) & 0xffff; return data; diff --git a/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp b/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp index 7b078bfb4c..ab063b0c97 100644 --- a/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp +++ b/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp @@ -287,7 +287,7 @@ UNMAP_AFTER_INIT ErrorOr RTL8168NetworkAdapter::initialize(Badge RTL8168NetworkAdapter::initialize(Badge RTL8168NetworkAdapter::initialize(Badge RTL8168NetworkAdapter::initialize(Badge