#include <vector>
#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
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");
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)
- : Uart(p), IER(0), DLAB(0), LCR(0), MCR(0), lastTxInt(0),
+Uart8250::Uart8250(const Params *p)
+ : Uart(p, 8), 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);
Addr daddr = pkt->getAddr() - pioAddr;
- pkt->allocate();
DPRINTF(Uart, " read register %#x\n", daddr);
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.
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
;
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);
/* uint32_t d32 = *data;
DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32);
*/
- pkt->result = Packet::Success;
+ pkt->makeAtomicResponse();
return pioDelay;
}
Uart8250::write(PacketPtr pkt)
{
- assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
assert(pkt->getSize() == 1);
switch (daddr) {
case 0x0:
if (!(LCR & 0x80)) { // write byte
- cons->out(pkt->get<uint8_t>());
+ term->out(pkt->get<uint8_t>());
platform->clearConsoleInt();
status &= ~TX_INT;
if (UART_IER_THRI & IER)
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();
}
}
{
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;
panic("Tried to access a UART port that doesn't exist\n");
break;
}
- pkt->result = Packet::Success;
+ pkt->makeAtomicResponse();
return pioDelay;
}
}
-void
-Uart8250::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+Uart8250::getAddrRanges() const
{
- 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)
{
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<Addr> pio_addr;
- Param<Tick> pio_latency;
- SimObjectParam<Platform *> platform;
- SimObjectParam<SimConsole *> sim_console;
- SimObjectParam<System *> 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)
-