mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:12:43 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									cbaa3465a8
								
							
						
					
					
						commit
						a2810d3cf8
					
				
					 9 changed files with 31 additions and 36 deletions
				
			
		|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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'); | ||||||
|  |  | ||||||
|  | @ -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
 | ||||||
|  |  | ||||||
|  | @ -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'); | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Hendiadyoin1
						Hendiadyoin1