X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fdev%2Fuart8250.cc;h=671d5505f8a956e1c465a575ff598fb9f0551a3f;hb=eae1e97fb002b44a9d8c46df2da1ddc1d0156ce4;hp=50307aad4e1235a49edb4e298616e5fd1ff5b057;hpb=4ad1b58fdd7cc9ba9704ae966a41c99fd0f1dbc9;p=gem5.git diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index 50307aad4..671d5505f 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -38,27 +38,28 @@ #include "base/inifile.hh" #include "base/str.hh" // for to_number #include "base/trace.hh" -#include "dev/simconsole.hh" -#include "dev/uart8250.hh" +#include "config/the_isa.hh" +#include "debug/Uart.hh" #include "dev/platform.hh" +#include "dev/terminal.hh" +#include "dev/uart8250.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" -#include "sim/builder.hh" using namespace std; using namespace TheISA; Uart8250::IntrEvent::IntrEvent(Uart8250 *u, int bit) - : Event(&mainEventQueue), uart(u) + : uart(u) { DPRINTF(Uart, "UART Interrupt Event Initilizing\n"); intrBit = bit; } const char * -Uart8250::IntrEvent::description() +Uart8250::IntrEvent::description() const { - return "uart interrupt delay event"; + return "uart interrupt delay"; } void @@ -68,7 +69,7 @@ Uart8250::IntrEvent::process() DPRINTF(Uart, "UART InterEvent, interrupting\n"); uart->platform->postConsoleInt(); uart->status |= intrBit; - uart->lastTxInt = curTick; + uart->lastTxInt = curTick(); } else DPRINTF(Uart, "UART InterEvent, not interrupting\n"); @@ -90,28 +91,26 @@ Uart8250::IntrEvent::process() void Uart8250::IntrEvent::scheduleIntr() { - static const Tick interval = (Tick)((Clock::Float::s / 2e9) * 450); + static const Tick interval = 225 * SimClock::Int::ns; DPRINTF(Uart, "Scheduling IER interrupt for %#x, at cycle %lld\n", intrBit, - curTick + interval); + curTick() + interval); if (!scheduled()) - schedule(curTick + interval); + uart->schedule(this, curTick() + interval); else - reschedule(curTick + interval); + uart->reschedule(this, curTick() + interval); } -Uart8250::Uart8250(Params *p) +Uart8250::Uart8250(const Params *p) : Uart(p), IER(0), DLAB(0), LCR(0), MCR(0), lastTxInt(0), txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT) { pioSize = 8; - } Tick Uart8250::read(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == 1); @@ -123,8 +122,8 @@ Uart8250::read(PacketPtr pkt) switch (daddr) { case 0x0: if (!(LCR & 0x80)) { // read byte - if (cons->dataAvailable()) - pkt->set(cons->in()); + if (term->dataAvailable()) + pkt->set(term->in()); else { pkt->set((uint8_t)0); // A limited amount of these are ok. @@ -133,7 +132,7 @@ Uart8250::read(PacketPtr pkt) status &= ~RX_INT; platform->clearConsoleInt(); - if (cons->dataAvailable() && (IER & UART_IER_RDI)) + if (term->dataAvailable() && (IER & UART_IER_RDI)) rxIntrEvent.scheduleIntr(); } else { // dll divisor latch ; @@ -163,12 +162,13 @@ Uart8250::read(PacketPtr pkt) pkt->set(LCR); break; case 0x4: // Modem Control Register (MCR) + pkt->set(MCR); break; case 0x5: // Line Status Register (LSR) uint8_t lsr; lsr = 0; // check if there are any bytes to be read - if (cons->dataAvailable()) + if (term->dataAvailable()) lsr = UART_LSR_DR; lsr |= UART_LSR_TEMT | UART_LSR_THRE; pkt->set(lsr); @@ -186,7 +186,7 @@ Uart8250::read(PacketPtr pkt) /* uint32_t d32 = *data; DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32); */ - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -194,7 +194,6 @@ Tick Uart8250::write(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == 1); @@ -205,7 +204,7 @@ Uart8250::write(PacketPtr pkt) switch (daddr) { case 0x0: if (!(LCR & 0x80)) { // write byte - cons->out(pkt->get()); + term->out(pkt->get()); platform->clearConsoleInt(); status &= ~TX_INT; if (UART_IER_THRI & IER) @@ -220,14 +219,13 @@ Uart8250::write(PacketPtr pkt) if (UART_IER_THRI & IER) { DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n"); - if (curTick - lastTxInt > - (Tick)((Clock::Float::s / 2e9) * 450)) { + if (curTick() - lastTxInt > 225 * SimClock::Int::ns) { DPRINTF(Uart, "-- Interrupting Immediately... %d,%d\n", - curTick, lastTxInt); + curTick(), lastTxInt); txIntrEvent.process(); } else { DPRINTF(Uart, "-- Delaying interrupt... %d,%d\n", - curTick, lastTxInt); + curTick(), lastTxInt); txIntrEvent.scheduleIntr(); } } @@ -235,19 +233,19 @@ Uart8250::write(PacketPtr pkt) { DPRINTF(Uart, "IER: IER_THRI cleared, descheduling TX intrrupt\n"); if (txIntrEvent.scheduled()) - txIntrEvent.deschedule(); + deschedule(txIntrEvent); if (status & TX_INT) platform->clearConsoleInt(); status &= ~TX_INT; } - if ((UART_IER_RDI & IER) && cons->dataAvailable()) { + if ((UART_IER_RDI & IER) && term->dataAvailable()) { DPRINTF(Uart, "IER: IER_RDI set, scheduling RX intrrupt\n"); rxIntrEvent.scheduleIntr(); } else { DPRINTF(Uart, "IER: IER_RDI cleared, descheduling RX intrrupt\n"); if (rxIntrEvent.scheduled()) - rxIntrEvent.deschedule(); + deschedule(rxIntrEvent); if (status & RX_INT) platform->clearConsoleInt(); status &= ~RX_INT; @@ -272,7 +270,7 @@ Uart8250::write(PacketPtr pkt) panic("Tried to access a UART port that doesn't exist\n"); break; } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -288,16 +286,14 @@ Uart8250::dataAvailable() } -void -Uart8250::addressRanges(AddrRangeList &range_list) +AddrRangeList +Uart8250::getAddrRanges() { - assert(pioSize != 0); - range_list.clear(); - range_list.push_back(RangeSize(pioAddr, pioSize)); + AddrRangeList ranges; + ranges.push_back(RangeSize(pioAddr, pioSize)); + return ranges; } - - void Uart8250::serialize(ostream &os) { @@ -333,42 +329,13 @@ Uart8250::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxintrwhen); UNSERIALIZE_SCALAR(txintrwhen); if (rxintrwhen != 0) - rxIntrEvent.schedule(rxintrwhen); + schedule(rxIntrEvent, rxintrwhen); if (txintrwhen != 0) - txIntrEvent.schedule(txintrwhen); + schedule(txIntrEvent, txintrwhen); } -BEGIN_DECLARE_SIM_OBJECT_PARAMS(Uart8250) - - Param pio_addr; - Param pio_latency; - SimObjectParam platform; - SimObjectParam sim_console; - SimObjectParam system; - -END_DECLARE_SIM_OBJECT_PARAMS(Uart8250) - -BEGIN_INIT_SIM_OBJECT_PARAMS(Uart8250) - - INIT_PARAM(pio_addr, "Device Address"), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), - INIT_PARAM(platform, "platform"), - INIT_PARAM(sim_console, "The Simulator Console"), - INIT_PARAM(system, "system object") - -END_INIT_SIM_OBJECT_PARAMS(Uart8250) - -CREATE_SIM_OBJECT(Uart8250) +Uart8250 * +Uart8250Params::create() { - Uart8250::Params *p = new Uart8250::Params; - p->name = getInstanceName(); - p->pio_addr = pio_addr; - p->pio_delay = pio_latency; - p->platform = platform; - p->cons = sim_console; - p->system = system; - return new Uart8250(p); + return new Uart8250(this); } - -REGISTER_SIM_OBJECT("Uart8250", Uart8250) -