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 ArchUARTSifive(addr_t base,int64 clock)11ArchUARTSifive::ArchUARTSifive(addr_t base, int64 clock) 12 : 13 DebugUART(base, clock) 14 { 15 } 16 17 ~ArchUARTSifive()18ArchUARTSifive::~ArchUARTSifive() 19 { 20 } 21 22 23 void InitEarly()24ArchUARTSifive::InitEarly() 25 { 26 //Regs()->ie = 0; 27 //Enable(); 28 } 29 30 31 void Init()32ArchUARTSifive::Init() 33 { 34 } 35 36 37 void InitPort(uint32 baud)38ArchUARTSifive::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 Enable()50ArchUARTSifive::Enable() 51 { 52 //Regs()->txctrl.enable = 1; 53 //Regs()->rxctrl.enable = 1; 54 DebugUART::Enable(); 55 } 56 57 58 void Disable()59ArchUARTSifive::Disable() 60 { 61 //Regs()->txctrl.enable = 0; 62 //Regs()->rxctrl.enable = 0; 63 DebugUART::Disable(); 64 } 65 66 67 int PutChar(char ch)68ArchUARTSifive::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 GetChar(bool wait)81ArchUARTSifive::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 FlushTx()93ArchUARTSifive::FlushTx() 94 { 95 } 96 97 98 void FlushRx()99ArchUARTSifive::FlushRx() 100 { 101 } 102 103 104 void Barrier()105ArchUARTSifive::Barrier() 106 { 107 asm volatile ("" : : : "memory"); 108 } 109 110 111 ArchUARTSifive* arch_get_uart_sifive(addr_t base,int64 clock)112arch_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