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