diff --git a/headers/private/kernel/arch/arm64/arch_uart_samsung.h b/headers/private/kernel/arch/arm64/arch_uart_samsung.h new file mode 100644 index 0000000000..673b366ba6 --- /dev/null +++ b/headers/private/kernel/arch/arm64/arch_uart_samsung.h @@ -0,0 +1,41 @@ +/* + * Copyright 2026 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Sam Roberts, sam@smrobtzz.dev + */ +#ifndef __DEV_UART_SAMSUNG_H +#define __DEV_UART_SAMSUNG_H + + +#include + + +#define UART_KIND_SAMSUNG "samsung" + + +class ArchUARTSamsung : public DebugUART { +public: + ArchUARTSamsung(addr_t base, int64 clock); + ~ArchUARTSamsung(); + + + void InitPort(uint32 baud); + + void Enable(); + void Disable(); + + int PutChar(char c); + int GetChar(bool wait); + + void FlushTx(); + void FlushRx(); + +private: + void Out32(int reg, uint32 data); + uint32 In32(int reg); +}; + + +#endif diff --git a/src/system/boot/arch/arm64/Jamfile b/src/system/boot/arch/arm64/Jamfile index 1f3cd45fda..314d77fa1b 100644 --- a/src/system/boot/arch/arm64/Jamfile +++ b/src/system/boot/arch/arm64/Jamfile @@ -5,6 +5,7 @@ local platform ; local kernelArchSources = arch_elf.cpp arch_uart_linflex.cpp + arch_uart_samsung.cpp ; local kernelArchReusableSources = diff --git a/src/system/boot/platform/efi/dtb.cpp b/src/system/boot/platform/efi/dtb.cpp index 235da52ad6..ad90255290 100644 --- a/src/system/boot/platform/efi/dtb.cpp +++ b/src/system/boot/platform/efi/dtb.cpp @@ -20,6 +20,7 @@ #elif defined(__aarch64__) # include # include +# include #endif @@ -83,6 +84,7 @@ const struct supported_uarts { { "arm,pl011", UART_KIND_PL011, &get_uart }, { "fsl,s32-linflexuart", UART_KIND_LINFLEX, &get_uart }, { "brcm,bcm2835-aux-uart", UART_KIND_8250, &get_uart }, + { "apple,s5l-uart", UART_KIND_SAMSUNG, &get_uart }, #endif }; diff --git a/src/system/kernel/arch/arm64/arch_uart_samsung.cpp b/src/system/kernel/arch/arm64/arch_uart_samsung.cpp new file mode 100644 index 0000000000..27c38e7331 --- /dev/null +++ b/src/system/kernel/arch/arm64/arch_uart_samsung.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2026 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Sam Roberts, sam@smrobtzz.dev + */ + +#include +#include + + +#define ULCON 0x00 // Line control +#define UCON 0x04 // Control +#define UFCON 0x08 // FIFO control +#define UTRSTAT 0x10 // Transmit status +#define UFSTAT 0x18 // FIFO status +#define UTXH 0x20 // Transmit holding +#define URXH 0x24 // Receive holding +#define UBRDIV 0x28 // Baud rate divider + +#define UCON_TXTHRESH_ENA (1 << 13) // Transmit threshold enable +#define UCON_RXTHRESH_ENA (1 << 12) // Receive threshold enable +#define UCON_RXTO_ENA (1 << 9) // Receive timeout enable +#define UCON_TXMODE (3 << 2) // Transmit mode +#define UCON_RXMODE (3 << 0) // Receive mode + +#define UCON_MODE_OFF 0 +#define UCON_MODE_IRQ 1 + +#define UTRSTAT_RXTO (1 << 9) // Receive timeout status +#define UTRSTAT_TXTHRESH (1 << 5) // Transmit threshold status +#define UTRSTAT_RXTHRESH (1 << 4) // Receive threshold status +#define UTRSTAT_TXE (1 << 2) // Transmit empty status +#define UTRSTAT_TXBE (1 << 1) // Transmit buffer empty status +#define UTRSTAT_RXD (1 << 0) // Receive data status + +#define UFSTAT_TXFULL (1 << 9) // Transmit FIFO full status +#define UFSTAT_RXFULL (1 << 8) // Receive FIFO full status +#define UFSTAT_TXCNT (15 << 4) // Transmit FIFO count +#define UFSTAT_RXCNT (15 << 0) // Receive FIFO count + + +ArchUARTSamsung::ArchUARTSamsung(addr_t base, int64 clock) + : + DebugUART(base, clock) +{ +} + + +ArchUARTSamsung::~ArchUARTSamsung() +{ +} + + +void +ArchUARTSamsung::Out32(int reg, uint32 data) +{ + *(volatile uint32*)(Base() + reg) = data; +} + + +uint32 +ArchUARTSamsung::In32(int reg) +{ + return *(volatile uint32*)(Base() + reg); +} + + +void +ArchUARTSamsung::InitPort(uint32 baud) +{ + uint32 ucon = In32(UCON); + // Disable TX and RX IRQ + Out32(UCON, ucon & !(UCON_RXMODE | UCON_TXMODE)); +} + + +void +ArchUARTSamsung::Enable() +{ + DebugUART::Enable(); +} + +void +ArchUARTSamsung::Disable() +{ + DebugUART::Disable(); +} + + +int +ArchUARTSamsung::PutChar(char c) +{ + if (Enabled()) { + while ((In32(UFSTAT) & UFSTAT_TXFULL) != 0) + ; + + Out32(UTXH, c); + return 0; + } + + return -1; +} + + +int +ArchUARTSamsung::GetChar(bool wait) +{ + if (Enabled()) { + while (wait && ((In32(UFSTAT) & UFSTAT_RXCNT) == 0)) + ; + + if ((In32(UFSTAT) & UFSTAT_RXCNT) == 0) + return -1; + + return In32(URXH); + } + + return -1; +} + + +void +ArchUARTSamsung::FlushTx() +{ +} + + +void +ArchUARTSamsung::FlushRx() +{ +}