blob: d536df44350a6a8135a40eb37ad42d0d80d7ef04 [file] [log] [blame] [edit]
// 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 <zircon/assert.h>
#include <zircon/boot/image.h>
#include <string_view>
#include "uart.h"
namespace uart {
namespace null {
struct Driver {
struct config_type {};
Driver() = default;
Driver(const 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 {};
}
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) {}
// 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) {}
// Set the UART up to deliver interrupts. This is called after Init.
template <typename IoProvider>
void InitInterrupt(IoProvider& io) {}
// This tells the IoProvider what device resources to provide.
constexpr config_type config() const { return {}; }
// This tells the IoProvider whether this UartDriver wants PIO or MMIO.
constexpr uint16_t pio_size() 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> {
public:
BasicIoProvider(const null::Driver::config_type&, uint16_t) {}
private:
// Nothing should call this. The visibility will cause a compilation error.
auto io() { return nullptr; }
};
} // namespace uart
#endif // LIB_UART_NULL_H_