xref: /haiku/src/system/kernel/arch/riscv64/arch_uart_sifive.cpp (revision 1648ab5277eadd18ea2c1294a38141255fe01702)
1ec1174b4SX512 /*
2ec1174b4SX512  * Copyright 2021, Haiku, Inc. All rights reserved.
3ec1174b4SX512  * Distributed under the terms of the MIT License.
4ec1174b4SX512  */
5ec1174b4SX512 
6*1648ab52SAlexander von Gluck IV 
7ec1174b4SX512 #include <arch/riscv64/arch_uart_sifive.h>
8*1648ab52SAlexander von Gluck IV #include <new>
9ec1174b4SX512 
10ec1174b4SX512 
ArchUARTSifive(addr_t base,int64 clock)11ec1174b4SX512 ArchUARTSifive::ArchUARTSifive(addr_t base, int64 clock)
12ec1174b4SX512 	:
13ec1174b4SX512 	DebugUART(base, clock)
14ec1174b4SX512 {
15ec1174b4SX512 }
16ec1174b4SX512 
17ec1174b4SX512 
~ArchUARTSifive()18ec1174b4SX512 ArchUARTSifive::~ArchUARTSifive()
19ec1174b4SX512 {
20ec1174b4SX512 }
21ec1174b4SX512 
22ec1174b4SX512 
23ec1174b4SX512 void
InitEarly()24ec1174b4SX512 ArchUARTSifive::InitEarly()
25ec1174b4SX512 {
26ec1174b4SX512 	//Regs()->ie = 0;
27ec1174b4SX512 	//Enable();
28ec1174b4SX512 }
29ec1174b4SX512 
30ec1174b4SX512 
31ec1174b4SX512 void
Init()32ec1174b4SX512 ArchUARTSifive::Init()
33ec1174b4SX512 {
34ec1174b4SX512 }
35ec1174b4SX512 
36ec1174b4SX512 
37ec1174b4SX512 void
InitPort(uint32 baud)38ec1174b4SX512 ArchUARTSifive::InitPort(uint32 baud)
39ec1174b4SX512 {
40ec1174b4SX512 	uint64 quotient = (Clock() + baud - 1) / baud;
41ec1174b4SX512 
42ec1174b4SX512 	if (quotient == 0)
43ec1174b4SX512 		Regs()->div = 0;
44ec1174b4SX512 	else
45ec1174b4SX512 		Regs()->div = (uint32)(quotient - 1);
46ec1174b4SX512 }
47ec1174b4SX512 
48ec1174b4SX512 
49ec1174b4SX512 void
Enable()50ec1174b4SX512 ArchUARTSifive::Enable()
51ec1174b4SX512 {
52ec1174b4SX512 	//Regs()->txctrl.enable = 1;
53ec1174b4SX512 	//Regs()->rxctrl.enable = 1;
54ec1174b4SX512 	DebugUART::Enable();
55ec1174b4SX512 }
56ec1174b4SX512 
57ec1174b4SX512 
58ec1174b4SX512 void
Disable()59ec1174b4SX512 ArchUARTSifive::Disable()
60ec1174b4SX512 {
61ec1174b4SX512 	//Regs()->txctrl.enable = 0;
62ec1174b4SX512 	//Regs()->rxctrl.enable = 0;
63ec1174b4SX512 	DebugUART::Disable();
64ec1174b4SX512 }
65ec1174b4SX512 
66ec1174b4SX512 
67ec1174b4SX512 int
PutChar(char ch)68ec1174b4SX512 ArchUARTSifive::PutChar(char ch)
69ec1174b4SX512 {
70ec1174b4SX512 	// TODO: Needs to be more atomic?
71ec1174b4SX512 	// Character drop will happen if there is one space left
72ec1174b4SX512 	// in the FIFO and two harts race. atomic_fetch_or of
73ec1174b4SX512 	// register, retrying if isFull.
74ec1174b4SX512 	while (Regs()->txdata.isFull) {}
75ec1174b4SX512 	Regs()->txdata.val = ch;
76ec1174b4SX512 	return 0;
77ec1174b4SX512 }
78ec1174b4SX512 
79ec1174b4SX512 
80ec1174b4SX512 int
GetChar(bool wait)81ec1174b4SX512 ArchUARTSifive::GetChar(bool wait)
82ec1174b4SX512 {
83ec1174b4SX512 	UARTSifiveRegs::Rxdata data;
84ec1174b4SX512 	do {
85cb256af9SAlexander von Gluck IV 		data.val = Regs()->rxdata.val;
86ec1174b4SX512 	} while (!wait || data.isEmpty);
87ec1174b4SX512 
88ec1174b4SX512 	return data.isEmpty ? -1 : data.data;
89ec1174b4SX512 }
90ec1174b4SX512 
91ec1174b4SX512 
92ec1174b4SX512 void
FlushTx()93ec1174b4SX512 ArchUARTSifive::FlushTx()
94ec1174b4SX512 {
95ec1174b4SX512 }
96ec1174b4SX512 
97ec1174b4SX512 
98ec1174b4SX512 void
FlushRx()99ec1174b4SX512 ArchUARTSifive::FlushRx()
100ec1174b4SX512 {
101ec1174b4SX512 }
102ec1174b4SX512 
103ec1174b4SX512 
104ec1174b4SX512 void
Barrier()105ec1174b4SX512 ArchUARTSifive::Barrier()
106ec1174b4SX512 {
107ec1174b4SX512 	asm volatile ("" : : : "memory");
108ec1174b4SX512 }
109*1648ab52SAlexander von Gluck IV 
110*1648ab52SAlexander von Gluck IV 
111*1648ab52SAlexander von Gluck IV ArchUARTSifive*
arch_get_uart_sifive(addr_t base,int64 clock)112*1648ab52SAlexander von Gluck IV arch_get_uart_sifive(addr_t base, int64 clock)
113*1648ab52SAlexander von Gluck IV {
114*1648ab52SAlexander von Gluck IV 	static char buffer[sizeof(ArchUARTSifive)];
115*1648ab52SAlexander von Gluck IV 	ArchUARTSifive* uart = new(buffer) ArchUARTSifive(base, clock);
116*1648ab52SAlexander von Gluck IV 	return uart;
117*1648ab52SAlexander von Gluck IV }
118