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