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