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