blob: 08fe635fb0f62aa659311b9f01feed76b098b1fb [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_UART_NULL_H_
#define LIB_UART_NULL_H_
// uart::null::Driver is a bit bucket.
// It also serves to demonstrate the API required by uart::KernelDriver.
#include <lib/zbi-format/zbi.h>
#include <zircon/assert.h>
#include <array>
#include <string_view>
#include "uart.h"
namespace devicetree {
class PropertyDecoder;
}
namespace uart {
namespace null {
struct Driver {
struct config_type {};
static constexpr std::array<std::string_view, 0> kDevicetreeBindings = {};
static constexpr std::string_view config_name() { return "none"; }
static constexpr IoRegisterType kIoType = IoRegisterType::kMmio8;
Driver() = default;
explicit Driver(const config_type& config) {}
constexpr bool operator==(const Driver& other) const { return true; }
constexpr bool operator!=(const Driver& other) const { return false; }
// API to (not) fill a ZBI item describing this UART.
constexpr uint32_t type() const { return 0; }
constexpr uint32_t extra() const { return 0; }
constexpr size_t size() const { return 0; }
void FillItem(void*) const { ZX_PANIC("should never be called"); }
// API to (not) match a ZBI item describing this UART.
static std::optional<Driver> MaybeCreate(const zbi_header_t&, const void*) { return {}; }
// API to match and reproduce configuration strings.
static std::optional<Driver> MaybeCreate(std::string_view string) {
if (string == "none") {
return Driver{};
}
return {};
}
static std::optional<Driver> MaybeCreate(const acpi_lite::AcpiDebugPortDescriptor& debug_port) {
return {};
}
// API to match devicetree node compatible list.
static bool MatchDevicetree(const devicetree::PropertyDecoder&) { return false; }
void Unparse(FILE* out) const { fprintf(out, "none"); }
// uart::KernelDriver UartDriver API
//
// Each method is a template parameterized by an IoProvider type for
// accessing the hardware registers so that real Driver types can be used
// with hwreg::Mock in tests independent of actual hardware access. The
// null Driver never uses the `io` arguments.
template <typename IoProvider>
void Init(IoProvider& io) {}
template <class IoProvider>
void SetLineControl(IoProvider& io, std::optional<DataBits> data_bits,
std::optional<Parity> parity, std::optional<StopBits> stop_bits) {}
// Return true if Write can make forward progress right now.
template <typename IoProvider>
bool TxReady(IoProvider& io) {
return true;
}
// This is called only when TxReady() has just returned true. Advance
// the iterator at least one and as many as is convenient but not past
// end, outputting each character before advancing.
template <typename IoProvider, typename It1, typename It2>
auto Write(IoProvider& io, bool, It1 it, const It2& end) {
return end;
}
// Poll for an incoming character and return one if there is one.
template <typename IoProvider>
std::optional<uint8_t> Read(IoProvider& io) {
return {};
}
// Enable transmit interrupts so Interrupt will be called when TxReady().
template <typename IoProvider>
void EnableTxInterrupt(IoProvider& io) {}
// Enable receive interrupts so Interrupt will be called when RxReady().
template <typename IoProvider>
void EnableRxInterrupt(IoProvider& io) {}
// Set the UART up to deliver interrupts. This is called after Init.
template <typename IoProvider, typename EnableInterruptCallback>
void InitInterrupt(IoProvider& io, EnableInterruptCallback&& enable_interrupt_callback) {}
template <typename IoProvider, typename Lock, typename Waiter, typename Tx, typename Rx>
void Interrupt(IoProvider&, Lock&, Waiter&, Tx&&, Rx&&) {}
// This tells the IoProvider what device resources to provide.
constexpr config_type config() const { return {}; }
constexpr size_t io_slots() const { return 0; }
};
} // namespace null
// Provide a specialization to do nothing with the lack of configuration info
// and provide no access to the lack of hardware.
template <>
class BasicIoProvider<null::Driver::config_type, IoRegisterType::kMmio8> {
public:
BasicIoProvider(const null::Driver::config_type&, size_t) {}
private:
// Nothing should call this. The visibility will cause a compilation error.
auto io() { return nullptr; }
};
} // namespace uart
#endif // LIB_UART_NULL_H_