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