* Prevents us breaking a potentially working serial uart. Change-Id: I57bed42cfa571d3d961ee07f380c96b62c7f34d6 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8798 Reviewed-by: waddlesplash <[email protected]>
124 lines
1.7 KiB
C++
124 lines
1.7 KiB
C++
/*
|
|
* Copyright 2021, Haiku, Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
|
|
#include <arch/riscv64/arch_uart_sifive.h>
|
|
#include <new>
|
|
|
|
|
|
ArchUARTSifive::ArchUARTSifive(addr_t base, int64 clock)
|
|
:
|
|
DebugUART(base, clock)
|
|
{
|
|
}
|
|
|
|
|
|
ArchUARTSifive::~ArchUARTSifive()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
ArchUARTSifive::InitEarly()
|
|
{
|
|
//Regs()->ie = 0;
|
|
//Enable();
|
|
}
|
|
|
|
|
|
void
|
|
ArchUARTSifive::Init()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
ArchUARTSifive::InitPort(uint32 baud)
|
|
{
|
|
int64 clock = Clock();
|
|
|
|
// if we get an invalid clock for some reason, just accept the currently set baud.
|
|
if (clock < 0)
|
|
return;
|
|
|
|
uint64 quotient = (clock + baud - 1) / baud;
|
|
|
|
if (quotient == 0)
|
|
Regs()->div = 0;
|
|
else
|
|
Regs()->div = (uint32)(quotient - 1);
|
|
}
|
|
|
|
|
|
void
|
|
ArchUARTSifive::Enable()
|
|
{
|
|
//Regs()->txctrl.enable = 1;
|
|
//Regs()->rxctrl.enable = 1;
|
|
DebugUART::Enable();
|
|
}
|
|
|
|
|
|
void
|
|
ArchUARTSifive::Disable()
|
|
{
|
|
//Regs()->txctrl.enable = 0;
|
|
//Regs()->rxctrl.enable = 0;
|
|
DebugUART::Disable();
|
|
}
|
|
|
|
|
|
int
|
|
ArchUARTSifive::PutChar(char ch)
|
|
{
|
|
// TODO: Needs to be more atomic?
|
|
// Character drop will happen if there is one space left
|
|
// in the FIFO and two harts race. atomic_fetch_or of
|
|
// register, retrying if isFull.
|
|
while (Regs()->txdata.isFull) {}
|
|
Regs()->txdata.val = ch;
|
|
return 0;
|
|
}
|
|
|
|
|
|
int
|
|
ArchUARTSifive::GetChar(bool wait)
|
|
{
|
|
UARTSifiveRegs::Rxdata data;
|
|
do {
|
|
data.val = Regs()->rxdata.val;
|
|
} while (!wait || data.isEmpty);
|
|
|
|
return data.isEmpty ? -1 : data.data;
|
|
}
|
|
|
|
|
|
void
|
|
ArchUARTSifive::FlushTx()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
ArchUARTSifive::FlushRx()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
ArchUARTSifive::Barrier()
|
|
{
|
|
asm volatile ("" : : : "memory");
|
|
}
|
|
|
|
|
|
ArchUARTSifive*
|
|
arch_get_uart_sifive(addr_t base, int64 clock)
|
|
{
|
|
static char buffer[sizeof(ArchUARTSifive)];
|
|
ArchUARTSifive* uart = new(buffer) ArchUARTSifive(base, clock);
|
|
return uart;
|
|
}
|