mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-06 16:09:30 +00:00
Kernel: Move IO delay code to x86 architecture subdirectory
Many code patterns and hardware procedures rely on reliable delay in the microseconds granularity, and since they are using such delays which are valid cases, but should not rely on x86 specific code, we allow to determine in compile time the proper platform-specific code to use to invoke such delays.
This commit is contained in:
parent
cac72259d0
commit
84fbab6803
15
Kernel/Arch/Delay.h
Normal file
15
Kernel/Arch/Delay.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Types.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
void microseconds_delay(u32 microseconds);
|
||||||
|
|
||||||
|
}
|
17
Kernel/Arch/x86/common/Delay.cpp
Normal file
17
Kernel/Arch/x86/common/Delay.cpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
|
#include <Kernel/Arch/x86/IO.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
void microseconds_delay(u32 microseconds)
|
||||||
|
{
|
||||||
|
IO::delay(microseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Platform.h>
|
#include <AK/Platform.h>
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Bus/PCI/API.h>
|
#include <Kernel/Bus/PCI/API.h>
|
||||||
#include <Kernel/Bus/USB/UHCI/UHCIController.h>
|
#include <Kernel/Bus/USB/UHCI/UHCIController.h>
|
||||||
#include <Kernel/Bus/USB/USBRequest.h>
|
#include <Kernel/Bus/USB/USBRequest.h>
|
||||||
|
@ -633,7 +634,7 @@ void UHCIController::reset_port(u8 port)
|
||||||
// Wait at least 50 ms for the port to reset.
|
// Wait at least 50 ms for the port to reset.
|
||||||
// This is T DRSTR in the USB 2.0 Specification Page 186 Table 7-13.
|
// This is T DRSTR in the USB 2.0 Specification Page 186 Table 7-13.
|
||||||
constexpr u16 reset_delay = 50 * 1000;
|
constexpr u16 reset_delay = 50 * 1000;
|
||||||
IO::delay(reset_delay);
|
microseconds_delay(reset_delay);
|
||||||
|
|
||||||
port_data &= ~UHCI_PORTSC_PORT_RESET;
|
port_data &= ~UHCI_PORTSC_PORT_RESET;
|
||||||
if (port == 0)
|
if (port == 0)
|
||||||
|
@ -644,7 +645,7 @@ void UHCIController::reset_port(u8 port)
|
||||||
// Wait 10 ms for the port to recover.
|
// Wait 10 ms for the port to recover.
|
||||||
// This is T RSTRCY in the USB 2.0 Specification Page 188 Table 7-14.
|
// This is T RSTRCY in the USB 2.0 Specification Page 188 Table 7-14.
|
||||||
constexpr u16 reset_recovery_delay = 10 * 1000;
|
constexpr u16 reset_recovery_delay = 10 * 1000;
|
||||||
IO::delay(reset_recovery_delay);
|
microseconds_delay(reset_recovery_delay);
|
||||||
|
|
||||||
port_data = port == 0 ? read_portsc1() : read_portsc2();
|
port_data = port == 0 ? read_portsc1() : read_portsc2();
|
||||||
port_data |= UHCI_PORTSC_PORT_ENABLED;
|
port_data |= UHCI_PORTSC_PORT_ENABLED;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/x86/IO.h>
|
||||||
#include <Kernel/Bus/USB/USBClasses.h>
|
#include <Kernel/Bus/USB/USBClasses.h>
|
||||||
#include <Kernel/Bus/USB/USBController.h>
|
#include <Kernel/Bus/USB/USBController.h>
|
||||||
|
@ -83,7 +84,7 @@ ErrorOr<void> Hub::enumerate_and_power_on_hub()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the ports to power up. power_on_to_power_good_time is in units of 2 ms and we want in us, so multiply by 2000.
|
// Wait for the ports to power up. power_on_to_power_good_time is in units of 2 ms and we want in us, so multiply by 2000.
|
||||||
IO::delay(descriptor.power_on_to_power_good_time * 2000);
|
microseconds_delay(descriptor.power_on_to_power_good_time * 2000);
|
||||||
|
|
||||||
memcpy(&m_hub_descriptor, &descriptor, sizeof(USBHubDescriptor));
|
memcpy(&m_hub_descriptor, &descriptor, sizeof(USBHubDescriptor));
|
||||||
|
|
||||||
|
@ -171,7 +172,7 @@ void Hub::check_for_port_updates()
|
||||||
|
|
||||||
// FIXME: Timeout
|
// FIXME: Timeout
|
||||||
while (debounce_timer < debounce_interval) {
|
while (debounce_timer < debounce_interval) {
|
||||||
IO::delay(debounce_disconnect_check_interval);
|
microseconds_delay(debounce_disconnect_check_interval);
|
||||||
debounce_timer += debounce_disconnect_check_interval;
|
debounce_timer += debounce_disconnect_check_interval;
|
||||||
|
|
||||||
if (auto result = get_port_status(port_number, port_status); result.is_error()) {
|
if (auto result = get_port_status(port_number, port_status); result.is_error()) {
|
||||||
|
@ -203,7 +204,7 @@ void Hub::check_for_port_updates()
|
||||||
// Wait at least 10 ms for the port to reset.
|
// Wait at least 10 ms for the port to reset.
|
||||||
// This is T DRST in the USB 2.0 Specification Page 186 Table 7-13.
|
// This is T DRST in the USB 2.0 Specification Page 186 Table 7-13.
|
||||||
constexpr u16 reset_delay = 10 * 1000;
|
constexpr u16 reset_delay = 10 * 1000;
|
||||||
IO::delay(reset_delay);
|
microseconds_delay(reset_delay);
|
||||||
|
|
||||||
if (auto result = get_port_status(port_number, port_status); result.is_error()) {
|
if (auto result = get_port_status(port_number, port_status); result.is_error()) {
|
||||||
dbgln("USB Hub: Error occurred when getting status while resetting port {}: {}.", port_number, result.error());
|
dbgln("USB Hub: Error occurred when getting status while resetting port {}: {}.", port_number, result.error());
|
||||||
|
@ -224,7 +225,7 @@ void Hub::check_for_port_updates()
|
||||||
// Wait 10 ms for the port to recover.
|
// Wait 10 ms for the port to recover.
|
||||||
// This is T RSTRCY in the USB 2.0 Specification Page 188 Table 7-14.
|
// This is T RSTRCY in the USB 2.0 Specification Page 188 Table 7-14.
|
||||||
constexpr u16 reset_recovery_delay = 10 * 1000;
|
constexpr u16 reset_recovery_delay = 10 * 1000;
|
||||||
IO::delay(reset_recovery_delay);
|
microseconds_delay(reset_recovery_delay);
|
||||||
|
|
||||||
dbgln_if(USB_DEBUG, "USB Hub: Reset complete!");
|
dbgln_if(USB_DEBUG, "USB Hub: Reset complete!");
|
||||||
|
|
||||||
|
|
|
@ -333,6 +333,7 @@ if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64")
|
||||||
${KERNEL_SOURCES}
|
${KERNEL_SOURCES}
|
||||||
Arch/Processor.cpp
|
Arch/Processor.cpp
|
||||||
|
|
||||||
|
Arch/x86/common/Delay.cpp
|
||||||
Arch/x86/common/I8042Reboot.cpp
|
Arch/x86/common/I8042Reboot.cpp
|
||||||
Arch/x86/common/ScopedCritical.cpp
|
Arch/x86/common/ScopedCritical.cpp
|
||||||
Arch/x86/common/SmapDisabler.cpp
|
Arch/x86/common/SmapDisabler.cpp
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Devices/Audio/AC97.h>
|
#include <Kernel/Devices/Audio/AC97.h>
|
||||||
#include <Kernel/Devices/DeviceManagement.h>
|
#include <Kernel/Devices/DeviceManagement.h>
|
||||||
#include <Kernel/Memory/AnonymousVMObject.h>
|
#include <Kernel/Memory/AnonymousVMObject.h>
|
||||||
|
@ -291,7 +292,7 @@ void AC97::AC97Channel::reset()
|
||||||
control_register.out(AudioControlRegisterFlag::ResetRegisters);
|
control_register.out(AudioControlRegisterFlag::ResetRegisters);
|
||||||
|
|
||||||
while ((control_register.in<u8>() & AudioControlRegisterFlag::ResetRegisters) > 0)
|
while ((control_register.in<u8>() & AudioControlRegisterFlag::ResetRegisters) > 0)
|
||||||
IO::delay(50);
|
microseconds_delay(50);
|
||||||
|
|
||||||
m_dma_running.with([](auto& dma_running) {
|
m_dma_running.with([](auto& dma_running) {
|
||||||
dma_running = false;
|
dma_running = false;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/x86/IO.h>
|
||||||
#include <Kernel/Devices/HID/I8042Controller.h>
|
#include <Kernel/Devices/HID/I8042Controller.h>
|
||||||
#include <Kernel/Devices/HID/PS2KeyboardDevice.h>
|
#include <Kernel/Devices/HID/PS2KeyboardDevice.h>
|
||||||
|
@ -71,7 +72,7 @@ UNMAP_AFTER_INIT bool I8042Controller::check_existence_via_probing(Badge<HIDMana
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Note: Wait 500 microseconds in case the controller couldn't respond
|
// Note: Wait 500 microseconds in case the controller couldn't respond
|
||||||
IO::delay(500);
|
microseconds_delay(500);
|
||||||
}
|
}
|
||||||
if (!successful_self_test) {
|
if (!successful_self_test) {
|
||||||
dbgln("I8042: Trying to probe for existence of controller failed");
|
dbgln("I8042: Trying to probe for existence of controller failed");
|
||||||
|
@ -246,7 +247,7 @@ ErrorOr<void> I8042Controller::drain_output_buffer()
|
||||||
return {};
|
return {};
|
||||||
IO::in8(I8042Port::Buffer);
|
IO::in8(I8042Port::Buffer);
|
||||||
|
|
||||||
IO::delay(100);
|
microseconds_delay(100);
|
||||||
}
|
}
|
||||||
return Error::from_errno(EBUSY);
|
return Error::from_errno(EBUSY);
|
||||||
}
|
}
|
||||||
|
@ -332,14 +333,14 @@ ErrorOr<void> I8042Controller::prepare_for_input(HIDDevice::Type device)
|
||||||
for (int attempt = 0; attempt < 1000; attempt++) {
|
for (int attempt = 0; attempt < 1000; attempt++) {
|
||||||
u8 status = IO::in8(I8042Port::Status);
|
u8 status = IO::in8(I8042Port::Status);
|
||||||
if (!(status & I8042StatusFlag::OutputBuffer)) {
|
if (!(status & I8042StatusFlag::OutputBuffer)) {
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (device == HIDDevice::Type::Unknown)
|
if (device == HIDDevice::Type::Unknown)
|
||||||
return {};
|
return {};
|
||||||
if ((status & I8042StatusFlag::SecondPS2PortOutputBuffer) == second_port_flag)
|
if ((status & I8042StatusFlag::SecondPS2PortOutputBuffer) == second_port_flag)
|
||||||
return {};
|
return {};
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
}
|
}
|
||||||
return Error::from_errno(EBUSY);
|
return Error::from_errno(EBUSY);
|
||||||
}
|
}
|
||||||
|
@ -351,7 +352,7 @@ ErrorOr<void> I8042Controller::prepare_for_output()
|
||||||
u8 status = IO::in8(I8042Port::Status);
|
u8 status = IO::in8(I8042Port::Status);
|
||||||
if (!(status & I8042StatusFlag::InputBuffer))
|
if (!(status & I8042StatusFlag::InputBuffer))
|
||||||
return {};
|
return {};
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
}
|
}
|
||||||
return Error::from_errno(EBUSY);
|
return Error::from_errno(EBUSY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Singleton.h>
|
#include <AK/Singleton.h>
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/x86/IO.h>
|
||||||
#include <Kernel/Bus/PCI/API.h>
|
#include <Kernel/Bus/PCI/API.h>
|
||||||
#include <Kernel/Bus/PCI/IDs.h>
|
#include <Kernel/Bus/PCI/IDs.h>
|
||||||
|
@ -46,7 +47,7 @@ void GraphicsManagement::disable_vga_emulation_access_permanently()
|
||||||
IO::out8(0x3c4, 1);
|
IO::out8(0x3c4, 1);
|
||||||
u8 sr1 = IO::in8(0x3c5);
|
u8 sr1 = IO::in8(0x3c5);
|
||||||
IO::out8(0x3c5, sr1 | 1 << 5);
|
IO::out8(0x3c5, sr1 | 1 << 5);
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
m_vga_access_is_disabled = true;
|
m_vga_access_is_disabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Bus/PCI/API.h>
|
#include <Kernel/Bus/PCI/API.h>
|
||||||
#include <Kernel/Debug.h>
|
#include <Kernel/Debug.h>
|
||||||
#include <Kernel/Devices/DeviceManagement.h>
|
#include <Kernel/Devices/DeviceManagement.h>
|
||||||
|
@ -371,7 +371,7 @@ bool IntelNativeDisplayConnector::gmbus_wait_for(IntelGraphics::GMBusStatus desi
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
milliseconds_passed++;
|
milliseconds_passed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,7 @@ void IntelNativeDisplayConnector::set_display_timings(Graphics::Modesetting cons
|
||||||
dbgln_if(INTEL_GRAPHICS_DEBUG, "sourceSize - {}, {}", (modesetting.vertical.active - 1), (modesetting.horizontal.active - 1));
|
dbgln_if(INTEL_GRAPHICS_DEBUG, "sourceSize - {}, {}", (modesetting.vertical.active - 1), (modesetting.horizontal.active - 1));
|
||||||
write_to_register(IntelGraphics::RegisterIndex::PipeASource, (modesetting.vertical.active - 1) | (modesetting.horizontal.active - 1) << 16);
|
write_to_register(IntelGraphics::RegisterIndex::PipeASource, (modesetting.vertical.active - 1) | (modesetting.horizontal.active - 1) << 16);
|
||||||
|
|
||||||
IO::delay(200);
|
microseconds_delay(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IntelNativeDisplayConnector::wait_for_enabled_pipe_a(size_t milliseconds_timeout) const
|
bool IntelNativeDisplayConnector::wait_for_enabled_pipe_a(size_t milliseconds_timeout) const
|
||||||
|
@ -553,7 +553,7 @@ bool IntelNativeDisplayConnector::wait_for_enabled_pipe_a(size_t milliseconds_ti
|
||||||
while (current_time < milliseconds_timeout) {
|
while (current_time < milliseconds_timeout) {
|
||||||
if (pipe_a_enabled())
|
if (pipe_a_enabled())
|
||||||
return true;
|
return true;
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
current_time++;
|
current_time++;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -564,7 +564,7 @@ bool IntelNativeDisplayConnector::wait_for_disabled_pipe_a(size_t milliseconds_t
|
||||||
while (current_time < milliseconds_timeout) {
|
while (current_time < milliseconds_timeout) {
|
||||||
if (!pipe_a_enabled())
|
if (!pipe_a_enabled())
|
||||||
return true;
|
return true;
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
current_time++;
|
current_time++;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -576,7 +576,7 @@ bool IntelNativeDisplayConnector::wait_for_disabled_pipe_b(size_t milliseconds_t
|
||||||
while (current_time < milliseconds_timeout) {
|
while (current_time < milliseconds_timeout) {
|
||||||
if (!pipe_b_enabled())
|
if (!pipe_b_enabled())
|
||||||
return true;
|
return true;
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
current_time++;
|
current_time++;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -662,14 +662,14 @@ void IntelNativeDisplayConnector::enable_dpll_without_vga(IntelGraphics::PLLSett
|
||||||
|
|
||||||
set_dpll_registers(settings);
|
set_dpll_registers(settings);
|
||||||
|
|
||||||
IO::delay(200);
|
microseconds_delay(200);
|
||||||
|
|
||||||
write_to_register(IntelGraphics::RegisterIndex::DPLLControlA, (6 << 9) | (settings.p1) << 16 | (1 << 26) | (1 << 28) | (1 << 31));
|
write_to_register(IntelGraphics::RegisterIndex::DPLLControlA, (6 << 9) | (settings.p1) << 16 | (1 << 26) | (1 << 28) | (1 << 31));
|
||||||
write_to_register(IntelGraphics::RegisterIndex::DPLLMultiplierA, (dac_multiplier - 1) | ((dac_multiplier - 1) << 8));
|
write_to_register(IntelGraphics::RegisterIndex::DPLLMultiplierA, (dac_multiplier - 1) | ((dac_multiplier - 1) << 8));
|
||||||
|
|
||||||
// The specification says we should wait (at least) about 150 microseconds
|
// The specification says we should wait (at least) about 150 microseconds
|
||||||
// after enabling the DPLL to allow the clock to stabilize
|
// after enabling the DPLL to allow the clock to stabilize
|
||||||
IO::delay(200);
|
microseconds_delay(200);
|
||||||
VERIFY(read_from_register(IntelGraphics::RegisterIndex::DPLLControlA) & (1 << 31));
|
VERIFY(read_from_register(IntelGraphics::RegisterIndex::DPLLControlA) & (1 << 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <AK/Memory.h>
|
#include <AK/Memory.h>
|
||||||
#include <AK/Singleton.h>
|
#include <AK/Singleton.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Arch/x86/MSR.h>
|
#include <Kernel/Arch/x86/MSR.h>
|
||||||
#include <Kernel/Arch/x86/ProcessorInfo.h>
|
#include <Kernel/Arch/x86/ProcessorInfo.h>
|
||||||
#include <Kernel/Debug.h>
|
#include <Kernel/Debug.h>
|
||||||
|
@ -186,7 +186,7 @@ void APIC::set_siv(u32 offset, u8 interrupt)
|
||||||
void APIC::wait_for_pending_icr()
|
void APIC::wait_for_pending_icr()
|
||||||
{
|
{
|
||||||
while ((read_register(APIC_REG_ICR_LOW) & APIC_ICR_DELIVERY_PENDING) != 0) {
|
while ((read_register(APIC_REG_ICR_LOW) & APIC_ICR_DELIVERY_PENDING) != 0) {
|
||||||
IO::delay(200);
|
microseconds_delay(200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,13 +409,13 @@ UNMAP_AFTER_INIT void APIC::do_boot_aps()
|
||||||
// INIT
|
// INIT
|
||||||
write_icr({ 0, 0, ICRReg::INIT, ICRReg::Physical, ICRReg::Assert, ICRReg::TriggerMode::Edge, ICRReg::AllExcludingSelf });
|
write_icr({ 0, 0, ICRReg::INIT, ICRReg::Physical, ICRReg::Assert, ICRReg::TriggerMode::Edge, ICRReg::AllExcludingSelf });
|
||||||
|
|
||||||
IO::delay(10 * 1000);
|
microseconds_delay(10 * 1000);
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
// SIPI
|
// SIPI
|
||||||
write_icr({ 0x08, 0, ICRReg::StartUp, ICRReg::Physical, ICRReg::Assert, ICRReg::TriggerMode::Edge, ICRReg::AllExcludingSelf }); // start execution at P8000
|
write_icr({ 0x08, 0, ICRReg::StartUp, ICRReg::Physical, ICRReg::Assert, ICRReg::TriggerMode::Edge, ICRReg::AllExcludingSelf }); // start execution at P8000
|
||||||
|
|
||||||
IO::delay(200);
|
microseconds_delay(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now wait until the ap_cpu_init_pending variable dropped to 0, which means all APs are initialized and no longer need these special mappings
|
// Now wait until the ap_cpu_init_pending variable dropped to 0, which means all APs are initialized and no longer need these special mappings
|
||||||
|
@ -423,7 +423,7 @@ UNMAP_AFTER_INIT void APIC::do_boot_aps()
|
||||||
dbgln_if(APIC_DEBUG, "APIC: Waiting for {} AP(s) to finish initialization...", aps_to_enable);
|
dbgln_if(APIC_DEBUG, "APIC: Waiting for {} AP(s) to finish initialization...", aps_to_enable);
|
||||||
do {
|
do {
|
||||||
// Wait a little bit
|
// Wait a little bit
|
||||||
IO::delay(200);
|
microseconds_delay(200);
|
||||||
} while (m_apic_ap_count.load(AK::MemoryOrder::memory_order_consume) != aps_to_enable);
|
} while (m_apic_ap_count.load(AK::MemoryOrder::memory_order_consume) != aps_to_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ UNMAP_AFTER_INIT void APIC::init_finished(u32 cpu)
|
||||||
// we don't want APs to trigger IPIs (e.g. through MM) while the BSP
|
// we don't want APs to trigger IPIs (e.g. through MM) while the BSP
|
||||||
// is unable to process them
|
// is unable to process them
|
||||||
while (!m_apic_ap_continue.load(AK::MemoryOrder::memory_order_consume)) {
|
while (!m_apic_ap_continue.load(AK::MemoryOrder::memory_order_consume)) {
|
||||||
IO::delay(200);
|
microseconds_delay(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgln_if(APIC_DEBUG, "APIC: CPU #{} continues, all others are initialized", cpu);
|
dbgln_if(APIC_DEBUG, "APIC: CPU #{} continues, all others are initialized", cpu);
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/Format.h>
|
||||||
#include <AK/Time.h>
|
#include <AK/Time.h>
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/CMOS.h>
|
#include <Kernel/CMOS.h>
|
||||||
#include <Kernel/RTC.h>
|
#include <Kernel/RTC.h>
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ static bool try_to_read_registers(unsigned& year, unsigned& month, unsigned& day
|
||||||
update_in_progress_ended_successfully = true;
|
update_in_progress_ended_successfully = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
time_passed_in_milliseconds++;
|
time_passed_in_milliseconds++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <AK/BuiltinWrappers.h>
|
#include <AK/BuiltinWrappers.h>
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Bus/PCI/API.h>
|
#include <Kernel/Bus/PCI/API.h>
|
||||||
#include <Kernel/CommandLine.h>
|
#include <Kernel/CommandLine.h>
|
||||||
#include <Kernel/Library/LockRefPtr.h>
|
#include <Kernel/Library/LockRefPtr.h>
|
||||||
|
@ -42,7 +43,7 @@ bool AHCIController::reset()
|
||||||
return false;
|
return false;
|
||||||
if (!(hba().control_regs.ghc & 1))
|
if (!(hba().control_regs.ghc & 1))
|
||||||
break;
|
break;
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
retry++;
|
retry++;
|
||||||
}
|
}
|
||||||
// Note: Turn on AHCI HBA and Global HBA Interrupts.
|
// Note: Turn on AHCI HBA and Global HBA Interrupts.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
// please look at Documentation/Kernel/AHCILocking.md
|
// please look at Documentation/Kernel/AHCILocking.md
|
||||||
|
|
||||||
#include <AK/Atomic.h>
|
#include <AK/Atomic.h>
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Locking/Spinlock.h>
|
#include <Kernel/Locking/Spinlock.h>
|
||||||
#include <Kernel/Memory/MemoryManager.h>
|
#include <Kernel/Memory/MemoryManager.h>
|
||||||
#include <Kernel/Memory/ScatterGatherList.h>
|
#include <Kernel/Memory/ScatterGatherList.h>
|
||||||
|
@ -552,7 +553,7 @@ bool AHCIPort::spin_until_ready() const
|
||||||
size_t spin = 0;
|
size_t spin = 0;
|
||||||
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Spinning until ready.", representative_port_index());
|
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Spinning until ready.", representative_port_index());
|
||||||
while ((m_port_registers.tfd & (ATA_SR_BSY | ATA_SR_DRQ)) && spin <= 100) {
|
while ((m_port_registers.tfd & (ATA_SR_BSY | ATA_SR_DRQ)) && spin <= 100) {
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
spin++;
|
spin++;
|
||||||
}
|
}
|
||||||
if (spin == 100) {
|
if (spin == 100) {
|
||||||
|
@ -719,7 +720,7 @@ bool AHCIPort::identify_device()
|
||||||
success = true;
|
success = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
IO::delay(1000); // delay with 1 milliseconds
|
microseconds_delay(1000); // delay with 1 milliseconds
|
||||||
time_elapsed++;
|
time_elapsed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,7 +740,7 @@ void AHCIPort::wait_until_condition_met_or_timeout(size_t delay_in_microseconds,
|
||||||
while (retry < retries) {
|
while (retry < retries) {
|
||||||
if (condition_being_met())
|
if (condition_being_met())
|
||||||
break;
|
break;
|
||||||
IO::delay(delay_in_microseconds);
|
microseconds_delay(delay_in_microseconds);
|
||||||
retry++;
|
retry++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -852,7 +853,7 @@ bool AHCIPort::initiate_sata_reset()
|
||||||
full_memory_barrier();
|
full_memory_barrier();
|
||||||
set_interface_state(AHCI::DeviceDetectionInitialization::PerformInterfaceInitializationSequence);
|
set_interface_state(AHCI::DeviceDetectionInitialization::PerformInterfaceInitializationSequence);
|
||||||
// The AHCI specification says to wait now a 1 millisecond
|
// The AHCI specification says to wait now a 1 millisecond
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
full_memory_barrier();
|
full_memory_barrier();
|
||||||
set_interface_state(AHCI::DeviceDetectionInitialization::NoActionRequested);
|
set_interface_state(AHCI::DeviceDetectionInitialization::NoActionRequested);
|
||||||
full_memory_barrier();
|
full_memory_barrier();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Storage/ATA/ATADiskDevice.h>
|
#include <Kernel/Storage/ATA/ATADiskDevice.h>
|
||||||
#include <Kernel/Storage/ATA/ATAPort.h>
|
#include <Kernel/Storage/ATA/ATAPort.h>
|
||||||
#include <Kernel/Storage/ATA/Definitions.h>
|
#include <Kernel/Storage/ATA/Definitions.h>
|
||||||
|
@ -499,7 +499,7 @@ ErrorOr<void> ATAPort::execute_polled_command(TransactionDirection direction, LB
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
milliseconds_elapsed++;
|
milliseconds_elapsed++;
|
||||||
}
|
}
|
||||||
if (milliseconds_elapsed > completion_timeout_in_milliseconds) {
|
if (milliseconds_elapsed > completion_timeout_in_milliseconds) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/Singleton.h>
|
#include <AK/Singleton.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/x86/IO.h>
|
||||||
#include <Kernel/Bus/PCI/API.h>
|
#include <Kernel/Bus/PCI/API.h>
|
||||||
#include <Kernel/Memory/MemoryManager.h>
|
#include <Kernel/Memory/MemoryManager.h>
|
||||||
|
@ -44,13 +45,13 @@ StringView IDEChannel::channel_type_string() const
|
||||||
|
|
||||||
bool IDEChannel::select_device_and_wait_until_not_busy(DeviceType device_type, size_t milliseconds_timeout)
|
bool IDEChannel::select_device_and_wait_until_not_busy(DeviceType device_type, size_t milliseconds_timeout)
|
||||||
{
|
{
|
||||||
IO::delay(20);
|
microseconds_delay(20);
|
||||||
u8 slave = device_type == DeviceType::Slave;
|
u8 slave = device_type == DeviceType::Slave;
|
||||||
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(0xA0 | (slave << 4)); // First, we need to select the drive itself
|
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(0xA0 | (slave << 4)); // First, we need to select the drive itself
|
||||||
IO::delay(20);
|
microseconds_delay(20);
|
||||||
size_t time_elapsed = 0;
|
size_t time_elapsed = 0;
|
||||||
while (m_io_group.control_base().in<u8>() & ATA_SR_BSY && time_elapsed <= milliseconds_timeout) {
|
while (m_io_group.control_base().in<u8>() & ATA_SR_BSY && time_elapsed <= milliseconds_timeout) {
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
time_elapsed++;
|
time_elapsed++;
|
||||||
}
|
}
|
||||||
return time_elapsed <= milliseconds_timeout;
|
return time_elapsed <= milliseconds_timeout;
|
||||||
|
@ -63,10 +64,10 @@ ErrorOr<void> IDEChannel::port_phy_reset()
|
||||||
// reset the channel
|
// reset the channel
|
||||||
u8 device_control = m_io_group.control_base().in<u8>();
|
u8 device_control = m_io_group.control_base().in<u8>();
|
||||||
// Wait 30 milliseconds
|
// Wait 30 milliseconds
|
||||||
IO::delay(30000);
|
microseconds_delay(30000);
|
||||||
m_io_group.control_base().out<u8>(device_control | (1 << 2));
|
m_io_group.control_base().out<u8>(device_control | (1 << 2));
|
||||||
// Wait 30 milliseconds
|
// Wait 30 milliseconds
|
||||||
IO::delay(30000);
|
microseconds_delay(30000);
|
||||||
m_io_group.control_base().out<u8>(device_control);
|
m_io_group.control_base().out<u8>(device_control);
|
||||||
// Wait up to 30 seconds before failing
|
// Wait up to 30 seconds before failing
|
||||||
if (!select_device_and_wait_until_not_busy(DeviceType::Master, 30000)) {
|
if (!select_device_and_wait_until_not_busy(DeviceType::Master, 30000)) {
|
||||||
|
@ -220,7 +221,7 @@ ErrorOr<void> IDEChannel::wait_if_busy_until_timeout(size_t timeout_in_milliseco
|
||||||
{
|
{
|
||||||
size_t time_elapsed = 0;
|
size_t time_elapsed = 0;
|
||||||
while (m_io_group.control_base().in<u8>() & ATA_SR_BSY && time_elapsed <= timeout_in_milliseconds) {
|
while (m_io_group.control_base().in<u8>() & ATA_SR_BSY && time_elapsed <= timeout_in_milliseconds) {
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
time_elapsed++;
|
time_elapsed++;
|
||||||
}
|
}
|
||||||
if (time_elapsed <= timeout_in_milliseconds)
|
if (time_elapsed <= timeout_in_milliseconds)
|
||||||
|
@ -249,7 +250,7 @@ ErrorOr<void> IDEChannel::load_taskfile_into_registers(ATAPort::TaskFile const&
|
||||||
// Note: Preserve the selected drive, always use LBA addressing
|
// Note: Preserve the selected drive, always use LBA addressing
|
||||||
auto driver_register = ((m_io_group.io_base().offset(ATA_REG_HDDEVSEL).in<u8>() & (1 << 4)) | (head | (1 << 5) | (1 << 6)));
|
auto driver_register = ((m_io_group.io_base().offset(ATA_REG_HDDEVSEL).in<u8>() & (1 << 4)) | (head | (1 << 5) | (1 << 6)));
|
||||||
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(driver_register);
|
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(driver_register);
|
||||||
IO::delay(50);
|
microseconds_delay(50);
|
||||||
|
|
||||||
if (lba_mode == LBAMode::FortyEightBit) {
|
if (lba_mode == LBAMode::FortyEightBit) {
|
||||||
m_io_group.io_base().offset(ATA_REG_SECCOUNT1).out<u8>((task_file.count >> 8) & 0xFF);
|
m_io_group.io_base().offset(ATA_REG_SECCOUNT1).out<u8>((task_file.count >> 8) & 0xFF);
|
||||||
|
@ -272,7 +273,7 @@ ErrorOr<void> IDEChannel::load_taskfile_into_registers(ATAPort::TaskFile const&
|
||||||
auto status = m_io_group.control_base().in<u8>();
|
auto status = m_io_group.control_base().in<u8>();
|
||||||
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY))
|
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY))
|
||||||
break;
|
break;
|
||||||
IO::delay(1000);
|
microseconds_delay(1000);
|
||||||
time_elapsed++;
|
time_elapsed++;
|
||||||
}
|
}
|
||||||
m_io_group.io_base().offset(ATA_REG_COMMAND).out<u8>(task_file.command);
|
m_io_group.io_base().offset(ATA_REG_COMMAND).out<u8>(task_file.command);
|
||||||
|
@ -284,9 +285,9 @@ ErrorOr<void> IDEChannel::device_select(size_t device_index)
|
||||||
VERIFY(m_lock.is_locked());
|
VERIFY(m_lock.is_locked());
|
||||||
if (device_index > 1)
|
if (device_index > 1)
|
||||||
return Error::from_errno(EINVAL);
|
return Error::from_errno(EINVAL);
|
||||||
IO::delay(20);
|
microseconds_delay(20);
|
||||||
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(0xA0 | ((device_index) << 4));
|
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(0xA0 | ((device_index) << 4));
|
||||||
IO::delay(20);
|
microseconds_delay(20);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,8 @@
|
||||||
|
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Arch/SafeMem.h>
|
#include <Kernel/Arch/SafeMem.h>
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
|
||||||
#include <Kernel/Arch/x86/Processor.h>
|
|
||||||
#include <Kernel/Bus/PCI/API.h>
|
#include <Kernel/Bus/PCI/API.h>
|
||||||
#include <Kernel/CommandLine.h>
|
#include <Kernel/CommandLine.h>
|
||||||
#include <Kernel/Devices/Device.h>
|
#include <Kernel/Devices/Device.h>
|
||||||
|
@ -77,7 +76,7 @@ bool NVMeController::wait_for_ready(bool expected_ready_bit_value)
|
||||||
|
|
||||||
u32 expected_rdy = expected_ready_bit_value ? 1 : 0;
|
u32 expected_rdy = expected_ready_bit_value ? 1 : 0;
|
||||||
while (((m_controller_regs->csts >> CSTS_RDY_BIT) & 0x1) != expected_rdy) {
|
while (((m_controller_regs->csts >> CSTS_RDY_BIT) & 0x1) != expected_rdy) {
|
||||||
IO::delay(one_ms_io_delay);
|
microseconds_delay(one_ms_io_delay);
|
||||||
|
|
||||||
if (--wait_iterations == 0) {
|
if (--wait_iterations == 0) {
|
||||||
if (((m_controller_regs->csts >> CSTS_RDY_BIT) & 0x1) != expected_rdy) {
|
if (((m_controller_regs->csts >> CSTS_RDY_BIT) & 0x1) != expected_rdy) {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Devices/BlockDevice.h>
|
#include <Kernel/Devices/BlockDevice.h>
|
||||||
#include <Kernel/Storage/NVMe/NVMeDefinitions.h>
|
#include <Kernel/Storage/NVMe/NVMeDefinitions.h>
|
||||||
#include <Kernel/Storage/NVMe/NVMePollQueue.h>
|
#include <Kernel/Storage/NVMe/NVMePollQueue.h>
|
||||||
|
@ -20,7 +20,7 @@ void NVMePollQueue::submit_sqe(NVMeSubmission& sub)
|
||||||
NVMeQueue::submit_sqe(sub);
|
NVMeQueue::submit_sqe(sub);
|
||||||
SpinlockLocker lock_cq(m_cq_lock);
|
SpinlockLocker lock_cq(m_cq_lock);
|
||||||
while (!process_cq()) {
|
while (!process_cq()) {
|
||||||
IO::delay(1);
|
microseconds_delay(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/StdLib.h>
|
#include <Kernel/StdLib.h>
|
||||||
#include <Kernel/Storage/NVMe/NVMeController.h>
|
#include <Kernel/Storage/NVMe/NVMeController.h>
|
||||||
#include <Kernel/Storage/NVMe/NVMeInterruptQueue.h>
|
#include <Kernel/Storage/NVMe/NVMeInterruptQueue.h>
|
||||||
|
@ -126,7 +126,7 @@ u16 NVMeQueue::submit_sync_sqe(NVMeSubmission& sub)
|
||||||
index = m_qdepth - 1;
|
index = m_qdepth - 1;
|
||||||
}
|
}
|
||||||
cqe_cid = m_cqe_array[index].command_id;
|
cqe_cid = m_cqe_array[index].command_id;
|
||||||
IO::delay(1);
|
microseconds_delay(1);
|
||||||
} while (cid != cqe_cid);
|
} while (cid != cqe_cid);
|
||||||
|
|
||||||
auto status = CQ_STATUS_FIELD(m_cqe_array[m_cq_head].status);
|
auto status = CQ_STATUS_FIELD(m_cqe_array[m_cq_head].status);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/CommandLine.h>
|
#include <Kernel/CommandLine.h>
|
||||||
#include <Kernel/Debug.h>
|
#include <Kernel/Debug.h>
|
||||||
#include <Kernel/Devices/DeviceManagement.h>
|
#include <Kernel/Devices/DeviceManagement.h>
|
||||||
|
@ -327,7 +328,7 @@ void VirtualConsole::beep()
|
||||||
if (!kernel_command_line().is_pc_speaker_enabled())
|
if (!kernel_command_line().is_pc_speaker_enabled())
|
||||||
return;
|
return;
|
||||||
PCSpeaker::tone_on(440);
|
PCSpeaker::tone_on(440);
|
||||||
IO::delay(10000);
|
microseconds_delay(10000);
|
||||||
PCSpeaker::tone_off();
|
PCSpeaker::tone_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue