Newer
Older
/*
* Copyright (C) 2013 Cloudius Systems, Ltd.
*
* This work is open source software, licensed under the terms of the
* BSD license as described in the LICENSE file in the top-level directory.
*/
IsaSerialConsole::IsaSerialConsole(sched::thread* poll_thread, const termios *tio)
: _irq(4, [=] { poll_thread->wake(); }), _tio(tio)
void IsaSerialConsole::write(const char *str, size_t len)
if ((*str == '\n') && (_tio->c_oflag & OPOST) && (_tio->c_oflag & ONLCR))
writeByte('\r');
writeByte(*str++);
bool IsaSerialConsole::input_ready()
{
u8 lsr = pci::inb(ioport + LSR_ADDRESS);
return (lsr & LSR_RECEIVE_DATA_READY);
}
char IsaSerialConsole::readch()
{
u8 lsr;
char letter;
do {
lsr = pci::inb(ioport + LSR_ADDRESS);
} while (!(lsr & (LSR_RECEIVE_DATA_READY | LSR_OVERRUN | LSR_PARITY_ERROR | LSR_FRAME_ERROR)));
letter = pci::inb(ioport);
return letter;
}
void IsaSerialConsole::writeByte(const char letter)
{
do {
lsr = pci::inb(ioport + LSR_ADDRESS);
} while (!(lsr & LSR_TRANSMIT_HOLD_EMPTY));
pci::outb(letter, ioport);
}
void IsaSerialConsole::reset() {
// Set the UART speed to to 115,200 bps, This is done by writing 1,0 to
// Divisor Latch registers, but to access these we need to temporarily
// set the Divisor Latch Access Bit (DLAB) on the LSR register, because
// the UART has fewer ports than registers...
lcr = pci::inb(ioport + LCR_ADDRESS);
pci::outb(lcr | LCR_DLAB, ioport + LCR_ADDRESS);
pci::outb(1, ioport + DLL_ADDRESS);
pci::outb(0, ioport + DLM_ADDRESS);
pci::outb(lcr & ~LCR_DLAB, ioport + LCR_ADDRESS);
// enable interrupts
pci::outb(1, ioport + IER_ADDRESS);