mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-06 16:09:30 +00:00
Kernel: Abstract platform-specific serial port access from kprintf
kprintf should not really care about the hardware-specific details of each UART or serial port out there, so instead of using x86 specific instructions, let's ensure that we will compile only the relevant code for debug output for a targeted-specific platform.
This commit is contained in:
parent
d5ee03ef5b
commit
a02c9c9569
13
Kernel/Arch/DebugOutput.h
Normal file
13
Kernel/Arch/DebugOutput.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
void debug_output(char ch);
|
||||
|
||||
}
|
17
Kernel/Arch/aarch64/RPi/DebugOutput.cpp
Normal file
17
Kernel/Arch/aarch64/RPi/DebugOutput.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/DebugOutput.h>
|
||||
#include <Kernel/Arch/aarch64/RPi/UART.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
void debug_output(char ch)
|
||||
{
|
||||
RPi::UART::the().send(ch);
|
||||
}
|
||||
|
||||
}
|
13
Kernel/Arch/x86/common/BochsDebugOutput.h
Normal file
13
Kernel/Arch/x86/common/BochsDebugOutput.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
void bochs_debug_output(char ch);
|
||||
|
||||
}
|
48
Kernel/Arch/x86/common/DebugOutput.cpp
Normal file
48
Kernel/Arch/x86/common/DebugOutput.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Arch/DebugOutput.h>
|
||||
#include <Kernel/Arch/x86/IO.h>
|
||||
#include <Kernel/Arch/x86/common/BochsDebugOutput.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
static constexpr u16 serial_com1_io_port = 0x3F8;
|
||||
|
||||
void bochs_debug_output(char ch)
|
||||
{
|
||||
IO::out8(IO::BOCHS_DEBUG_PORT, ch);
|
||||
}
|
||||
|
||||
void debug_output(char ch)
|
||||
{
|
||||
static bool serial_ready = false;
|
||||
static bool was_cr = false;
|
||||
|
||||
if (!serial_ready) {
|
||||
IO::out8(serial_com1_io_port + 1, 0x00);
|
||||
IO::out8(serial_com1_io_port + 3, 0x80);
|
||||
IO::out8(serial_com1_io_port + 0, 0x02);
|
||||
IO::out8(serial_com1_io_port + 1, 0x00);
|
||||
IO::out8(serial_com1_io_port + 3, 0x03);
|
||||
IO::out8(serial_com1_io_port + 2, 0xC7);
|
||||
IO::out8(serial_com1_io_port + 4, 0x0B);
|
||||
|
||||
serial_ready = true;
|
||||
}
|
||||
|
||||
while ((IO::in8(serial_com1_io_port + 5) & 0x20) == 0)
|
||||
;
|
||||
|
||||
if (ch == '\n' && !was_cr)
|
||||
IO::out8(serial_com1_io_port, '\r');
|
||||
|
||||
IO::out8(serial_com1_io_port, ch);
|
||||
|
||||
was_cr = ch == '\r';
|
||||
}
|
||||
|
||||
}
|
|
@ -332,6 +332,7 @@ if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64")
|
|||
Arch/Processor.cpp
|
||||
|
||||
Arch/x86/common/CMOS.cpp
|
||||
Arch/x86/common/DebugOutput.cpp
|
||||
Arch/x86/common/Delay.cpp
|
||||
Arch/x86/common/I8042Reboot.cpp
|
||||
Arch/x86/common/RTC.cpp
|
||||
|
@ -437,6 +438,7 @@ if (NOT "${SERENITY_ARCH}" STREQUAL "aarch64")
|
|||
)
|
||||
else()
|
||||
set(RPI_SOURCES
|
||||
Arch/aarch64/RPi/DebugOutput.cpp
|
||||
Arch/aarch64/RPi/Framebuffer.cpp
|
||||
Arch/aarch64/RPi/GPIO.cpp
|
||||
Arch/aarch64/RPi/InterruptController.cpp
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
#include <AK/PrintfImplementation.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Arch/x86/IO.h>
|
||||
#include <Kernel/Arch/DebugOutput.h>
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
# include <Kernel/Arch/x86/common/BochsDebugOutput.h>
|
||||
#endif
|
||||
#include <Kernel/Devices/ConsoleDevice.h>
|
||||
#include <Kernel/Devices/DeviceManagement.h>
|
||||
#include <Kernel/Devices/PCISerialDevice.h>
|
||||
|
@ -43,39 +46,20 @@ static void serial_putch(char ch)
|
|||
if (PCISerialDevice::is_available())
|
||||
return PCISerialDevice::the().put_char(ch);
|
||||
|
||||
static bool serial_ready = false;
|
||||
static bool was_cr = false;
|
||||
|
||||
if (!serial_ready) {
|
||||
IO::out8(0x3F8 + 1, 0x00);
|
||||
IO::out8(0x3F8 + 3, 0x80);
|
||||
IO::out8(0x3F8 + 0, 0x02);
|
||||
IO::out8(0x3F8 + 1, 0x00);
|
||||
IO::out8(0x3F8 + 3, 0x03);
|
||||
IO::out8(0x3F8 + 2, 0xC7);
|
||||
IO::out8(0x3F8 + 4, 0x0B);
|
||||
|
||||
serial_ready = true;
|
||||
}
|
||||
|
||||
while ((IO::in8(0x3F8 + 5) & 0x20) == 0)
|
||||
;
|
||||
|
||||
if (ch == '\n' && !was_cr)
|
||||
IO::out8(0x3F8, '\r');
|
||||
|
||||
IO::out8(0x3F8, ch);
|
||||
|
||||
was_cr = ch == '\r';
|
||||
debug_output(ch);
|
||||
}
|
||||
|
||||
static void critical_console_out(char ch)
|
||||
{
|
||||
if (s_serial_debug_enabled)
|
||||
serial_putch(ch);
|
||||
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
// No need to output things to the real ConsoleDevice as no one is likely
|
||||
// to read it (because we are in a fatal situation, so only print things and halt)
|
||||
IO::out8(IO::BOCHS_DEBUG_PORT, ch);
|
||||
bochs_debug_output(ch);
|
||||
#endif
|
||||
|
||||
// We emit chars directly to the string. this is necessary in few cases,
|
||||
// especially when we want to avoid any memory allocations...
|
||||
if (GraphicsManagement::is_initialized() && GraphicsManagement::the().console()) {
|
||||
|
@ -95,7 +79,9 @@ static void console_out(char ch)
|
|||
if (DeviceManagement::the().is_console_device_attached()) {
|
||||
DeviceManagement::the().console_device().put_char(ch);
|
||||
} else {
|
||||
IO::out8(IO::BOCHS_DEBUG_PORT, ch);
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
bochs_debug_output(ch);
|
||||
#endif
|
||||
}
|
||||
if (ConsoleManagement::is_initialized()) {
|
||||
ConsoleManagement::the().debug_tty()->emit_char(ch);
|
||||
|
@ -153,7 +139,9 @@ static inline void internal_dbgputch(char ch)
|
|||
{
|
||||
if (s_serial_debug_enabled)
|
||||
serial_putch(ch);
|
||||
IO::out8(IO::BOCHS_DEBUG_PORT, ch);
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
bochs_debug_output(ch);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void dbgputstr(char const* characters, size_t length)
|
||||
|
|
Loading…
Reference in a new issue