9#include "../microfmt.hpp"
10#include "../reloco.hpp"
28 explicit constexpr pl011_sink(uintptr_t base_addr,
bool translate_crlf =
true) noexcept
29 : base_(base_addr), translate_crlf_(translate_crlf) {}
35 volatile uint32_t *cr =
reinterpret_cast<volatile uint32_t *
>(base_ + 0x30);
36 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
38 *cr |= (1 << 0) | (1 << 8) | (1 << 9);
39 RELOCO_END_UNSAFE_BUFFER_USAGE;
46 return sink{
const_cast<void *
>(
static_cast<const void *
>(
this)), &pl011_sink::write_impl};
53 static void write_impl(
void *ctx, string_view str)
noexcept {
56 volatile uint32_t *dr =
reinterpret_cast<volatile uint32_t *
>(self->base_);
57 volatile uint32_t *fr =
reinterpret_cast<volatile uint32_t *
>(self->base_ + 0x18);
59 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
61 if (self->translate_crlf_ && c ==
'\n') {
62 wait_for_fifo_slot(fr);
63 *dr =
static_cast<uint32_t
>(
'\r');
66 wait_for_fifo_slot(fr);
67 *dr =
static_cast<uint32_t
>(c);
69 RELOCO_END_UNSAFE_BUFFER_USAGE;
72 static inline void wait_for_fifo_slot(
volatile uint32_t *fr_reg)
noexcept {
74 while ((*fr_reg & (1 << 5)) != 0) {
75#if defined(__aarch64__) || defined(__arm__)
76 __asm__
volatile(
"yield" :::
"memory");
Zero-allocation controller targeting the ARM PrimeCell PL011 UART.
Definition pl011_sink.hpp:21
constexpr pl011_sink(uintptr_t base_addr, bool translate_crlf=true) noexcept
Constructs a PL011 UART controller.
Definition pl011_sink.hpp:28
void enable() const noexcept
Optional hardware initialization helper.
Definition pl011_sink.hpp:34
constexpr sink as_sink() const noexcept
Returns a type-erased microfmt::sink view over this controller instance.
Definition pl011_sink.hpp:45
#define MICROFMT_API_CLASS
Definition compat.hpp:181
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46