l4re-base-25.08.0

This commit is contained in:
2025-09-12 15:55:45 +02:00
commit d959eaab98
37938 changed files with 9382688 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
PKGDIR = ../..
L4DIR ?= $(PKGDIR)/../..
PKGNAME = drivers
include $(L4DIR)/mk/include.mk

View File

@@ -0,0 +1,118 @@
/*
* Copyright (C) 2008-2021 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
* Alexander Warg <alexander.warg@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_16550 : public Uart
{
protected:
enum Registers
{
TRB = 0x00, // Transmit/Receive Buffer (read/write)
BRD_LOW = 0x00, // Baud Rate Divisor LSB if bit 7 of LCR is set (read/write)
IER = 0x01, // Interrupt Enable Register (read/write)
BRD_HIGH = 0x01, // Baud Rate Divisor MSB if bit 7 of LCR is set (read/write)
IIR = 0x02, // Interrupt Identification Register (read only)
FCR = 0x02, // 16550 FIFO Control Register (write only)
LCR = 0x03, // Line Control Register (read/write)
MCR = 0x04, // Modem Control Register (read/write)
LSR = 0x05, // Line Status Register (read only)
MSR = 0x06, // Modem Status Register (read only)
SPR = 0x07, // Scratch Pad Register (read/write)
};
enum Register_value_iir
{
IIR_BUSY = 7,
};
enum Register_value_lsr
{
LSR_DR = 0x01, // Receiver data ready
LSR_THRE = 0x20, // Transmit hold register empty
LSR_TSRE = 0x40, // Transmitter empty
};
enum Init_values
{
#ifdef UART_16550_INIT_MCR
Init_mcr = UART_16550_INIT_MCR,
#else
Init_mcr = 0,
#endif
#ifdef UART_16550_INIT_IER
Init_ier = UART_16550_INIT_IER,
#else
Init_ier = 0,
#endif
#ifdef UART_16550_INIT_FCR
Init_fcr = UART_16550_INIT_FCR,
#else
Init_fcr = 0,
#endif
};
public:
enum
{
PAR_NONE = 0x00,
PAR_EVEN = 0x18,
PAR_ODD = 0x08,
DAT_5 = 0x00,
DAT_6 = 0x01,
DAT_7 = 0x02,
DAT_8 = 0x03,
STOP_1 = 0x00,
STOP_2 = 0x04,
MODE_8N1 = PAR_NONE | DAT_8 | STOP_1,
MODE_7E1 = PAR_EVEN | DAT_7 | STOP_1,
// these two values are to leave either mode
// or baud rate unchanged on a call to change_mode
MODE_NC = 0x1000000,
BAUD_NC = 0x1000000,
Base_rate_x86 = 115200,
Base_rate_pxa = 921600,
};
explicit Uart_16550(unsigned long base_rate, unsigned char init_flags = 0,
unsigned char ier_bits = Init_ier,
unsigned char mcr_bits = Init_mcr,
unsigned char fcr_bits = Init_fcr)
: _base_rate(base_rate), _init_flags(init_flags), _mcr_bits(mcr_bits),
_ier_bits(ier_bits), _fcr_bits(fcr_bits)
{}
bool startup(Io_register_block const *regs) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable = true) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
unsigned long _base_rate;
unsigned char _init_flags;
unsigned char _mcr_bits;
unsigned char _ier_bits;
unsigned char _fcr_bits;
};
} // namespace L4

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2015 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@l4re.org>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_16550.h"
namespace L4 {
class Uart_16550_dw : public Uart_16550
{
public:
explicit Uart_16550_dw(unsigned long base_rate)
: Uart_16550(base_rate)
{}
void irq_ack() override;
};
} // namespace L4

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2017, 2019, 2023-2024 Kernkonzept GmbH.
* Author(s): Georg Kotheimer <georg.kotheimer@kernkonzept.com>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
/**
* Driver for the Advanced Peripheral Bus (APB) UART from the Cortex-M System
* Design Kit (CMSDK).
*/
class Uart_apb : public Uart
{
public:
/** freq == 0 means unknown and don't change baud rate */
Uart_apb(unsigned freq) : _freq(freq) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
void set_rate(Baud_rate r);
unsigned _freq;
};
} // namespace L4

View File

@@ -0,0 +1,174 @@
/*
* Copyright (C) 2009-2012 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include <stddef.h>
#include <l4/drivers/io_regblock.h>
#include "poll_timeout_counter.h"
namespace L4 {
/**
* Uart driver abstraction.
*/
class Uart
{
protected:
unsigned _mode;
unsigned _rate;
Io_register_block const *_regs;
public:
void *operator new (size_t, void* a)
{ return a; }
public:
typedef unsigned Transfer_mode;
typedef unsigned Baud_rate;
Uart()
: _mode(~0U), _rate(~0U)
{}
/**
* Start the UART driver.
*
* \param regs IO register block of the UART.
* \retval true Startup succeeded.
* \retval false Startup failed.
*/
virtual bool startup(Io_register_block const *regs) = 0;
virtual ~Uart() {}
/**
* Terminate the UART driver. This includes disabling of interrupts.
*/
virtual void shutdown() = 0;
/**
* Set certain parameters of the UART.
*
* \param m UART mode. Depends on the hardware.
* \param r Baud rate.
* \retval true Mode setting succeeded (or was not performed at all).
* \retval false Mode setting failed for some reason.
*
* \note Some drivers don't perform any mode setting at all and just return
* true.
*/
virtual bool change_mode(Transfer_mode m, Baud_rate r) = 0;
/**
* Transmit a number of characters.
*
* \param s Buffer containing the characters.
* \param count Number of characters to transmit.
* \param blocking If true, wait until there is space in the transmit
* buffer and also wait until every character was
* successful transmitted. Otherwise do not wait.
* \return The number of successfully written characters.
*/
virtual int write(char const *s, unsigned long count,
bool blocking = true) const = 0;
/**
* Return the transfer mode.
*
* \return The transfer mode.
*/
Transfer_mode mode() const { return _mode; }
/**
* Return the baud rate.
*
* \return The baud rate.
*/
Baud_rate rate() const { return _rate; }
/**
* Enable the receive IRQ.
*
* \retval true The RX IRQ was successfully enabled / disabled.
* \retval false The RX IRQ couldn't be enabled / disabled. The
* driver does not support this operation.
*/
virtual bool enable_rx_irq(bool = true) { return false; }
/**
* Acknowledge a received interrupt.
*/
virtual void irq_ack() {}
/**
* Check if there is at least one character available for reading from the
* UART.
*
* \return 0 if there is no character available for reading, !=0 otherwise.
*/
virtual int char_avail() const = 0;
/**
* Read a character from the UART.
*
* \param blocking If true, wait until a character is available for
* reading. Otherwise do not wait and just return -1 if
* no character is available.
* \return The actual character read from the UART.
*/
virtual int get_char(bool blocking = true) const = 0;
protected:
/**
* Internal function transmitting each character one-after-another and
* finally waiting that the transmission did actually finish.
*
* \param s Buffer containing the characters.
* \param count The number of characters to transmit.
* \param blocking If true, wait until there is space in the transmit
* buffer and also wait until every character was
* successful transmitted. Otherwise do not wait.
* \return The number of successful written characters.
*/
template <typename Uart_driver, bool Timeout_guard = true>
int generic_write(char const *s, unsigned long count,
bool blocking = true) const
{
auto *self = static_cast<Uart_driver const*>(this);
unsigned long c;
for (c = 0; c < count; ++c)
{
if (!blocking && !self->tx_avail())
break;
if constexpr (Timeout_guard)
{
Poll_timeout_counter i(3000000);
while (i.test(!self->tx_avail()))
;
}
else
{
while (!self->tx_avail())
;
}
self->out_char(*s++);
}
if (blocking)
self->wait_tx_done();
return c;
}
};
} // namespace L4

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2013 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_cadence : public Uart
{
public:
explicit Uart_cadence(unsigned base_rate) : _base_rate(base_rate) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const {}
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool) override;
void irq_ack() override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
unsigned _base_rate;
};
} // namespace L4

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2009 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_dcc_v6 : public Uart
{
public:
explicit Uart_dcc_v6() {}
explicit Uart_dcc_v6(unsigned /*base_rate*/) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
unsigned get_status() const;
};
} // namespace l4

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2021-2022 Stephan Gerhold <stephan@gerhold.net>
* Copyright (C) 2022-2024 Kernkonzept GmbH.
* Author(s): Stephan Gerhold <stephan@gerhold.net>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_dm : public Uart
{
public:
explicit Uart_dm(unsigned /*base_rate*/) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable = true) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
};
} // namespace L4

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2009 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_dummy : public Uart
{
public:
explicit Uart_dummy() {}
explicit Uart_dummy(unsigned /*base_rate*/) {}
bool startup(Io_register_block const *) override { return true; }
void shutdown() override {}
bool change_mode(Transfer_mode, Baud_rate) override { return true; }
inline void out_char(char /*ch*/) const {}
int write(char const * /*str*/, unsigned long /*count*/,
bool /*blocking*/ = true) const override
{ return 0; }
int char_avail() const override { return false; }
int get_char(bool /*blocking*/ = true) const override { return 0; }
};
} // namespace L4

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2022-2024 Kernkonzept GmbH.
* Author(s): Stephan Gerhold <stephan.gerhold@kernkonzept.com>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_geni : public Uart
{
public:
explicit Uart_geni(unsigned /*base_rate*/) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable = true) override;
void irq_ack() override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
};
} // namespace L4

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2008-2009 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_imx : public Uart
{
public:
enum platform_type
{
Type_imx21,
Type_imx35,
Type_imx51,
Type_imx6,
Type_imx7,
Type_imx8,
};
explicit Uart_imx(enum platform_type type) : _type(type) {}
explicit Uart_imx(enum platform_type type, unsigned /*base_rate*/)
: _type(type) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable = true) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
enum platform_type _type;
};
class Uart_imx21 : public Uart_imx
{
public:
Uart_imx21() : Uart_imx(Type_imx21) {}
explicit Uart_imx21(unsigned base_rate) : Uart_imx(Type_imx21, base_rate) {}
};
class Uart_imx35 : public Uart_imx
{
public:
Uart_imx35() : Uart_imx(Type_imx35) {}
explicit Uart_imx35(unsigned base_rate) : Uart_imx(Type_imx35, base_rate) {}
};
class Uart_imx51 : public Uart_imx
{
public:
Uart_imx51() : Uart_imx(Type_imx51) {}
explicit Uart_imx51(unsigned base_rate) : Uart_imx(Type_imx51, base_rate) {}
};
class Uart_imx6 : public Uart_imx
{
public:
Uart_imx6() : Uart_imx(Type_imx6) {}
explicit Uart_imx6(unsigned base_rate) : Uart_imx(Type_imx6, base_rate) {}
void irq_ack() override;
};
class Uart_imx7 : public Uart_imx
{
public:
Uart_imx7() : Uart_imx(Type_imx7) {}
explicit Uart_imx7(unsigned base_rate) : Uart_imx(Type_imx7, base_rate) {}
};
class Uart_imx8 : public Uart_imx
{
public:
Uart_imx8() : Uart_imx(Type_imx8) {}
explicit Uart_imx8(unsigned base_rate) : Uart_imx(Type_imx8, base_rate) {}
};
} // namespace L4

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2011 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
* Björn Döbel <doebel@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_leon3 : public Uart
{
public:
explicit Uart_leon3() {}
explicit Uart_leon3(unsigned /*base_rate*/) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool = true) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
};
} // namespace L4

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2018 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@l4re.org>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_linflex : public Uart
{
public:
explicit Uart_linflex(unsigned) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable = true) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
void set_uartcr(bool fifo);
bool is_tx_fifo_enabled() const;
bool is_rx_fifo_enabled() const;
};
} // namespace L4

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2019, 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@l4re.org>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_lpuart : public Uart
{
public:
/** freq == 0 means unknown and don't change baud rate */
Uart_lpuart(unsigned freq = 0) : _freq(freq) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const {}
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable = true) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
unsigned _freq;
};
} // namespace L4

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2017, 2023-2024 Kernkonzept GmbH.
* Author(s) Adam Lackorzynski <adam@l4re.org>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_mvebu : public Uart
{
public:
explicit Uart_mvebu(unsigned baserate) : _baserate(baserate) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const {}
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable = true) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
unsigned _baserate;
};
} // namespace L4

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2009 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
#include <stdarg.h>
#include <string.h>
#include <l4/drivers/of.h>
namespace L4 {
class Uart_of : public Uart, public L4_drivers::Of
{
private:
ihandle_t _serial;
public:
Uart_of() : Of(), _serial(0) {}
explicit Uart_of(unsigned /*base_rate*/) : Of(), _serial(0) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
};
} // namespace L4

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2009 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s) Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_omap35x : public Uart
{
public:
explicit Uart_omap35x() {}
explicit Uart_omap35x(unsigned /*base_rate*/) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
};
} // namespace L4

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2009 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_pl011 : public Uart
{
public:
/** freq == 0 means unknown and don't change baud rate */
Uart_pl011(unsigned freq) : _freq(freq) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
void set_rate(Baud_rate r);
unsigned _freq;
};
} // namespace L4

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2009-2012 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_s3c : public Uart
{
protected:
enum Uart_type
{
Type_24xx, Type_64xx, Type_s5pv210,
};
Uart_type type() const { return _type; }
public:
explicit Uart_s3c(Uart_type type) : _type(type) {}
explicit Uart_s3c(Uart_type type, unsigned /*base_rate*/) : _type(type) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
void fifo_reset();
int char_avail() const override;
int get_char(bool blocking = true) const override;
protected:
virtual void ack_rx_irq() const = 0;
virtual void wait_for_empty_tx_fifo() const = 0;
virtual unsigned is_rx_fifo_non_empty() const = 0;
virtual unsigned is_tx_fifo_not_full() const = 0;
private:
Uart_type _type;
};
class Uart_s3c2410 : public Uart_s3c
{
public:
Uart_s3c2410() : Uart_s3c(Type_24xx) {}
explicit Uart_s3c2410(unsigned base_rate) : Uart_s3c(Type_24xx, base_rate) {}
protected:
void ack_rx_irq() const override {}
void wait_for_empty_tx_fifo() const override;
unsigned is_rx_fifo_non_empty() const override;
unsigned is_tx_fifo_not_full() const override;
void auto_flow_control(bool on);
};
class Uart_s3c64xx : public Uart_s3c
{
public:
Uart_s3c64xx() : Uart_s3c(Type_64xx) {}
explicit Uart_s3c64xx(unsigned base_rate) : Uart_s3c(Type_64xx, base_rate) {}
protected:
void ack_rx_irq() const override;
void wait_for_empty_tx_fifo() const override;
unsigned is_rx_fifo_non_empty() const override;
unsigned is_tx_fifo_not_full() const override;
};
class Uart_s5pv210 : public Uart_s3c
{
public:
Uart_s5pv210() : Uart_s3c(Type_s5pv210) {}
explicit Uart_s5pv210(unsigned base_rate) : Uart_s3c(Type_s5pv210, base_rate) {}
protected:
void ack_rx_irq() const override;
void wait_for_empty_tx_fifo() const override;
unsigned is_rx_fifo_non_empty() const override;
unsigned is_tx_fifo_not_full() const override;
};
} // namespace L4

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2008-2012 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
* Alexander Warg <alexander.warg@os.inf.tu-dresden.de>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_sa1000 : public Uart
{
public:
explicit Uart_sa1000() {}
explicit Uart_sa1000(unsigned /*base_rate*/) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
};
} // namespace L4

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2021, 2024 Kernkonzept GmbH.
* Author(s): Georg Kotheimer <georg.kotheimer@kernkonzept.com>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_sbi : public Uart
{
public:
Uart_sbi();
explicit Uart_sbi(unsigned /*base_rate*/) : Uart_sbi() {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const { return true; }
void wait_tx_done() const {}
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
mutable int _bufchar;
};
} // namespace L4

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2016 Technische Universität Dresden.
* Copyright (C) 2023-2024 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@l4re.org>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_sh : public Uart
{
public:
explicit Uart_sh() {}
explicit Uart_sh(unsigned /*base_rate*/) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const {}
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable = true) override;
void irq_ack() override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
};
} // namespace L4

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2021-2024 Kernkonzept GmbH.
* Author(s): Georg Kotheimer <georg.kotheimer@kernkonzept.com>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_sifive : public Uart
{
public:
Uart_sifive(unsigned freq) : _freq(freq), _bufchar(-1) {}
bool startup(Io_register_block const *) override;
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
bool enable_rx_irq(bool enable) override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
unsigned _freq;
mutable int _bufchar;
};
} // namespace L4

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2025 Kernkonzept GmbH.
* Author(s): Adam Lackorzynski <adam@l4re.org>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "uart_base.h"
namespace L4 {
class Uart_tegra_tcu : public Uart
{
public:
Uart_tegra_tcu() {}
Uart_tegra_tcu(unsigned long) {}
bool startup(Io_register_block const *tx_mbox) override;
void set_rx_mbox(Io_register_block const *rx_mbox);
void shutdown() override;
bool change_mode(Transfer_mode m, Baud_rate r) override;
int tx_avail() const;
void wait_tx_done() const {}
inline void out_char(char c) const;
int write(char const *s, unsigned long count,
bool blocking = true) const override;
int char_avail() const override;
int get_char(bool blocking = true) const override;
private:
mutable unsigned _current_rx_val = 0u;
Io_register_block const *_rx_mbox = nullptr;
};
} // namespace L4