uart8250.cc revision 13342
112239Sandreas.sandberg@arm.com/* 212239Sandreas.sandberg@arm.com * Copyright (c) 2005 The Regents of The University of Michigan 312239Sandreas.sandberg@arm.com * All rights reserved. 412239Sandreas.sandberg@arm.com * 512239Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 612239Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 712239Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 812239Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 912239Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1012239Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1112239Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1212239Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1312239Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 1412239Sandreas.sandberg@arm.com * this software without specific prior written permission. 1512239Sandreas.sandberg@arm.com * 1612239Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712239Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812239Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912239Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012239Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112239Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212239Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312239Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412239Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512239Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612239Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712239Sandreas.sandberg@arm.com * 2812239Sandreas.sandberg@arm.com * Authors: Ali Saidi 2912239Sandreas.sandberg@arm.com */ 3012239Sandreas.sandberg@arm.com 3112239Sandreas.sandberg@arm.com/** @file 3212239Sandreas.sandberg@arm.com * Implements a 8250 UART 3312239Sandreas.sandberg@arm.com */ 3412239Sandreas.sandberg@arm.com 3512239Sandreas.sandberg@arm.com#include "dev/serial/uart8250.hh" 3612239Sandreas.sandberg@arm.com 3712239Sandreas.sandberg@arm.com#include <string> 3812239Sandreas.sandberg@arm.com#include <vector> 3912239Sandreas.sandberg@arm.com 4012239Sandreas.sandberg@arm.com#include "base/inifile.hh" 4112239Sandreas.sandberg@arm.com#include "base/trace.hh" 4212239Sandreas.sandberg@arm.com#include "config/the_isa.hh" 4312239Sandreas.sandberg@arm.com#include "debug/Uart.hh" 4412239Sandreas.sandberg@arm.com#include "dev/platform.hh" 4512239Sandreas.sandberg@arm.com#include "mem/packet.hh" 4612239Sandreas.sandberg@arm.com#include "mem/packet_access.hh" 4712239Sandreas.sandberg@arm.com 4812239Sandreas.sandberg@arm.comusing namespace std; 4912239Sandreas.sandberg@arm.comusing namespace TheISA; 5012239Sandreas.sandberg@arm.com 5112239Sandreas.sandberg@arm.comvoid 5212239Sandreas.sandberg@arm.comUart8250::processIntrEvent(int intrBit) 5312239Sandreas.sandberg@arm.com{ 5412239Sandreas.sandberg@arm.com if (intrBit & IER) { 5512239Sandreas.sandberg@arm.com DPRINTF(Uart, "UART InterEvent, interrupting\n"); 5612239Sandreas.sandberg@arm.com platform->postConsoleInt(); 5712239Sandreas.sandberg@arm.com status |= intrBit; 5812239Sandreas.sandberg@arm.com lastTxInt = curTick(); 5912239Sandreas.sandberg@arm.com } 6012239Sandreas.sandberg@arm.com else 6112239Sandreas.sandberg@arm.com DPRINTF(Uart, "UART InterEvent, not interrupting\n"); 6212239Sandreas.sandberg@arm.com 6312239Sandreas.sandberg@arm.com} 6412239Sandreas.sandberg@arm.com 6512239Sandreas.sandberg@arm.com/* The linux serial driver (8250.c about line 1182) loops reading from 6612239Sandreas.sandberg@arm.com * the device until the device reports it has no more data to 6712239Sandreas.sandberg@arm.com * read. After a maximum of 255 iterations the code prints "serial8250 6812239Sandreas.sandberg@arm.com * too much work for irq X," and breaks out of the loop. Since the 6912239Sandreas.sandberg@arm.com * simulated system is so much slower than the actual system, if a 7012239Sandreas.sandberg@arm.com * user is typing on the keyboard it is very easy for them to provide 7112239Sandreas.sandberg@arm.com * input at a fast enough rate to not allow the loop to exit and thus 7212239Sandreas.sandberg@arm.com * the error to be printed. This magic number provides a delay between 7312239Sandreas.sandberg@arm.com * the time the UART receives a character to send to the simulated 7412239Sandreas.sandberg@arm.com * system and the time it actually notifies the system it has a 7512239Sandreas.sandberg@arm.com * character to send to alleviate this problem. --Ali 7612239Sandreas.sandberg@arm.com */ 7712239Sandreas.sandberg@arm.comvoid 7812239Sandreas.sandberg@arm.comUart8250::scheduleIntr(Event *event) 7912239Sandreas.sandberg@arm.com{ 8012239Sandreas.sandberg@arm.com static const Tick interval = 225 * SimClock::Int::ns; 8112239Sandreas.sandberg@arm.com DPRINTF(Uart, "Scheduling IER interrupt for %s, at cycle %lld\n", 8212239Sandreas.sandberg@arm.com event->name(), curTick() + interval); 8312239Sandreas.sandberg@arm.com if (!event->scheduled()) 8412239Sandreas.sandberg@arm.com schedule(event, curTick() + interval); 8512239Sandreas.sandberg@arm.com else 8612239Sandreas.sandberg@arm.com reschedule(event, curTick() + interval); 8712239Sandreas.sandberg@arm.com} 8812239Sandreas.sandberg@arm.com 8912239Sandreas.sandberg@arm.com 9012239Sandreas.sandberg@arm.comUart8250::Uart8250(const Params *p) 9112239Sandreas.sandberg@arm.com : Uart(p, 8), IER(0), DLAB(0), LCR(0), MCR(0), lastTxInt(0), 9212239Sandreas.sandberg@arm.com txIntrEvent([this]{ processIntrEvent(TX_INT); }, "TX"), 9312239Sandreas.sandberg@arm.com rxIntrEvent([this]{ processIntrEvent(RX_INT); }, "RX") 9412239Sandreas.sandberg@arm.com{ 9512239Sandreas.sandberg@arm.com} 9612239Sandreas.sandberg@arm.com 9712239Sandreas.sandberg@arm.comTick 9812239Sandreas.sandberg@arm.comUart8250::read(PacketPtr pkt) 9912239Sandreas.sandberg@arm.com{ 10012239Sandreas.sandberg@arm.com assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 10112239Sandreas.sandberg@arm.com assert(pkt->getSize() == 1); 10212239Sandreas.sandberg@arm.com 10312239Sandreas.sandberg@arm.com Addr daddr = pkt->getAddr() - pioAddr; 10412239Sandreas.sandberg@arm.com 10512239Sandreas.sandberg@arm.com DPRINTF(Uart, " read register %#x\n", daddr); 10612239Sandreas.sandberg@arm.com 10712239Sandreas.sandberg@arm.com switch (daddr) { 10812239Sandreas.sandberg@arm.com case 0x0: 10912239Sandreas.sandberg@arm.com if (!(LCR & 0x80)) { // read byte 11012239Sandreas.sandberg@arm.com if (device->dataAvailable()) 11113342Sgabeblack@google.com pkt->setRaw(device->readData()); 11212239Sandreas.sandberg@arm.com else { 11313342Sgabeblack@google.com pkt->setRaw((uint8_t)0); 11412239Sandreas.sandberg@arm.com // A limited amount of these are ok. 11512239Sandreas.sandberg@arm.com DPRINTF(Uart, "empty read of RX register\n"); 11612239Sandreas.sandberg@arm.com } 11712239Sandreas.sandberg@arm.com status &= ~RX_INT; 11812239Sandreas.sandberg@arm.com platform->clearConsoleInt(); 11912239Sandreas.sandberg@arm.com 12012239Sandreas.sandberg@arm.com if (device->dataAvailable() && (IER & UART_IER_RDI)) 12112239Sandreas.sandberg@arm.com scheduleIntr(&rxIntrEvent); 12212239Sandreas.sandberg@arm.com } else { // dll divisor latch 12312239Sandreas.sandberg@arm.com ; 12412239Sandreas.sandberg@arm.com } 12512239Sandreas.sandberg@arm.com break; 12612239Sandreas.sandberg@arm.com case 0x1: 12712239Sandreas.sandberg@arm.com if (!(LCR & 0x80)) { // Intr Enable Register(IER) 12813342Sgabeblack@google.com pkt->setRaw(IER); 12912239Sandreas.sandberg@arm.com } else { // DLM divisor latch MSB 13012239Sandreas.sandberg@arm.com ; 13112239Sandreas.sandberg@arm.com } 13212239Sandreas.sandberg@arm.com break; 13312239Sandreas.sandberg@arm.com case 0x2: // Intr Identification Register (IIR) 13412239Sandreas.sandberg@arm.com DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status); 13512239Sandreas.sandberg@arm.com 13612239Sandreas.sandberg@arm.com if (status & RX_INT) /* Rx data interrupt has a higher priority */ 13713342Sgabeblack@google.com pkt->setRaw(IIR_RXID); 13812239Sandreas.sandberg@arm.com else if (status & TX_INT) { 13913342Sgabeblack@google.com pkt->setRaw(IIR_TXID); 14012239Sandreas.sandberg@arm.com //Tx interrupts are cleared on IIR reads 14112239Sandreas.sandberg@arm.com status &= ~TX_INT; 14212239Sandreas.sandberg@arm.com } else 14313342Sgabeblack@google.com pkt->setRaw(IIR_NOPEND); 14412239Sandreas.sandberg@arm.com 14512239Sandreas.sandberg@arm.com break; 14612239Sandreas.sandberg@arm.com case 0x3: // Line Control Register (LCR) 14713342Sgabeblack@google.com pkt->setRaw(LCR); 14812239Sandreas.sandberg@arm.com break; 14912239Sandreas.sandberg@arm.com case 0x4: // Modem Control Register (MCR) 15013342Sgabeblack@google.com pkt->setRaw(MCR); 15112239Sandreas.sandberg@arm.com break; 15212239Sandreas.sandberg@arm.com case 0x5: // Line Status Register (LSR) 15312239Sandreas.sandberg@arm.com uint8_t lsr; 15412239Sandreas.sandberg@arm.com lsr = 0; 15512239Sandreas.sandberg@arm.com // check if there are any bytes to be read 15612239Sandreas.sandberg@arm.com if (device->dataAvailable()) 15712239Sandreas.sandberg@arm.com lsr = UART_LSR_DR; 15812239Sandreas.sandberg@arm.com lsr |= UART_LSR_TEMT | UART_LSR_THRE; 15913342Sgabeblack@google.com pkt->setRaw(lsr); 16012239Sandreas.sandberg@arm.com break; 16112239Sandreas.sandberg@arm.com case 0x6: // Modem Status Register (MSR) 16213342Sgabeblack@google.com pkt->setRaw((uint8_t)0); 16312239Sandreas.sandberg@arm.com break; 16412239Sandreas.sandberg@arm.com case 0x7: // Scratch Register (SCR) 16513342Sgabeblack@google.com pkt->setRaw((uint8_t)0); // doesn't exist with at 8250. 16612239Sandreas.sandberg@arm.com break; 16712239Sandreas.sandberg@arm.com default: 16812239Sandreas.sandberg@arm.com panic("Tried to access a UART port that doesn't exist\n"); 16912239Sandreas.sandberg@arm.com break; 17012239Sandreas.sandberg@arm.com } 17112239Sandreas.sandberg@arm.com/* uint32_t d32 = *data; 17212239Sandreas.sandberg@arm.com DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32); 17312239Sandreas.sandberg@arm.com*/ 17412239Sandreas.sandberg@arm.com pkt->makeAtomicResponse(); 17512239Sandreas.sandberg@arm.com return pioDelay; 17612239Sandreas.sandberg@arm.com} 17712239Sandreas.sandberg@arm.com 17812239Sandreas.sandberg@arm.comTick 17912239Sandreas.sandberg@arm.comUart8250::write(PacketPtr pkt) 18012239Sandreas.sandberg@arm.com{ 18112239Sandreas.sandberg@arm.com 18212239Sandreas.sandberg@arm.com assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 18312239Sandreas.sandberg@arm.com assert(pkt->getSize() == 1); 18412239Sandreas.sandberg@arm.com 18512239Sandreas.sandberg@arm.com Addr daddr = pkt->getAddr() - pioAddr; 18612239Sandreas.sandberg@arm.com 18713342Sgabeblack@google.com DPRINTF(Uart, " write register %#x value %#x\n", daddr, 18813342Sgabeblack@google.com pkt->getRaw<uint8_t>()); 18912239Sandreas.sandberg@arm.com 19012239Sandreas.sandberg@arm.com switch (daddr) { 19112239Sandreas.sandberg@arm.com case 0x0: 19212239Sandreas.sandberg@arm.com if (!(LCR & 0x80)) { // write byte 19313342Sgabeblack@google.com device->writeData(pkt->getRaw<uint8_t>()); 19412239Sandreas.sandberg@arm.com platform->clearConsoleInt(); 19512239Sandreas.sandberg@arm.com status &= ~TX_INT; 19612239Sandreas.sandberg@arm.com if (UART_IER_THRI & IER) 19712239Sandreas.sandberg@arm.com scheduleIntr(&txIntrEvent); 19812239Sandreas.sandberg@arm.com } else { // dll divisor latch 19912239Sandreas.sandberg@arm.com ; 20012239Sandreas.sandberg@arm.com } 20112239Sandreas.sandberg@arm.com break; 20212239Sandreas.sandberg@arm.com case 0x1: 20312239Sandreas.sandberg@arm.com if (!(LCR & 0x80)) { // Intr Enable Register(IER) 20413342Sgabeblack@google.com IER = pkt->getRaw<uint8_t>(); 20512239Sandreas.sandberg@arm.com if (UART_IER_THRI & IER) 20612239Sandreas.sandberg@arm.com { 20713342Sgabeblack@google.com DPRINTF(Uart, 20813342Sgabeblack@google.com "IER: IER_THRI set, scheduling TX intrrupt\n"); 20912239Sandreas.sandberg@arm.com if (curTick() - lastTxInt > 225 * SimClock::Int::ns) { 21012239Sandreas.sandberg@arm.com DPRINTF(Uart, "-- Interrupting Immediately... %d,%d\n", 21112239Sandreas.sandberg@arm.com curTick(), lastTxInt); 21212239Sandreas.sandberg@arm.com txIntrEvent.process(); 21312239Sandreas.sandberg@arm.com } else { 21412239Sandreas.sandberg@arm.com DPRINTF(Uart, "-- Delaying interrupt... %d,%d\n", 21512239Sandreas.sandberg@arm.com curTick(), lastTxInt); 21612239Sandreas.sandberg@arm.com scheduleIntr(&txIntrEvent); 21712239Sandreas.sandberg@arm.com } 21812239Sandreas.sandberg@arm.com } 21912239Sandreas.sandberg@arm.com else 22012239Sandreas.sandberg@arm.com { 22113342Sgabeblack@google.com DPRINTF(Uart, "IER: IER_THRI cleared, " 22213342Sgabeblack@google.com "descheduling TX intrrupt\n"); 22312239Sandreas.sandberg@arm.com if (txIntrEvent.scheduled()) 22412239Sandreas.sandberg@arm.com deschedule(txIntrEvent); 22512239Sandreas.sandberg@arm.com if (status & TX_INT) 22612239Sandreas.sandberg@arm.com platform->clearConsoleInt(); 22712239Sandreas.sandberg@arm.com status &= ~TX_INT; 22812239Sandreas.sandberg@arm.com } 22912239Sandreas.sandberg@arm.com 23012239Sandreas.sandberg@arm.com if ((UART_IER_RDI & IER) && device->dataAvailable()) { 23113342Sgabeblack@google.com DPRINTF(Uart, 23213342Sgabeblack@google.com "IER: IER_RDI set, scheduling RX intrrupt\n"); 23312239Sandreas.sandberg@arm.com scheduleIntr(&rxIntrEvent); 23412239Sandreas.sandberg@arm.com } else { 23513342Sgabeblack@google.com DPRINTF(Uart, "IER: IER_RDI cleared, " 23613342Sgabeblack@google.com "descheduling RX intrrupt\n"); 23712239Sandreas.sandberg@arm.com if (rxIntrEvent.scheduled()) 23812239Sandreas.sandberg@arm.com deschedule(rxIntrEvent); 23912239Sandreas.sandberg@arm.com if (status & RX_INT) 24012239Sandreas.sandberg@arm.com platform->clearConsoleInt(); 24112239Sandreas.sandberg@arm.com status &= ~RX_INT; 24212239Sandreas.sandberg@arm.com } 24312239Sandreas.sandberg@arm.com } else { // DLM divisor latch MSB 24412239Sandreas.sandberg@arm.com ; 24512239Sandreas.sandberg@arm.com } 24612239Sandreas.sandberg@arm.com break; 24712239Sandreas.sandberg@arm.com case 0x2: // FIFO Control Register (FCR) 24812239Sandreas.sandberg@arm.com break; 24912239Sandreas.sandberg@arm.com case 0x3: // Line Control Register (LCR) 25013342Sgabeblack@google.com LCR = pkt->getRaw<uint8_t>(); 25112239Sandreas.sandberg@arm.com break; 25212239Sandreas.sandberg@arm.com case 0x4: // Modem Control Register (MCR) 25313342Sgabeblack@google.com if (pkt->getRaw<uint8_t>() == (UART_MCR_LOOP | 0x0A)) 25412239Sandreas.sandberg@arm.com MCR = 0x9A; 25512239Sandreas.sandberg@arm.com break; 25612239Sandreas.sandberg@arm.com case 0x7: // Scratch Register (SCR) 25712239Sandreas.sandberg@arm.com // We are emulating a 8250 so we don't have a scratch reg 25812239Sandreas.sandberg@arm.com break; 25912239Sandreas.sandberg@arm.com default: 26012239Sandreas.sandberg@arm.com panic("Tried to access a UART port that doesn't exist\n"); 26112239Sandreas.sandberg@arm.com break; 26212239Sandreas.sandberg@arm.com } 26312239Sandreas.sandberg@arm.com pkt->makeAtomicResponse(); 26412239Sandreas.sandberg@arm.com return pioDelay; 26512239Sandreas.sandberg@arm.com} 26612239Sandreas.sandberg@arm.com 26712239Sandreas.sandberg@arm.comvoid 26812239Sandreas.sandberg@arm.comUart8250::dataAvailable() 26912239Sandreas.sandberg@arm.com{ 27012239Sandreas.sandberg@arm.com // if the kernel wants an interrupt when we have data 27112239Sandreas.sandberg@arm.com if (IER & UART_IER_RDI) 27212239Sandreas.sandberg@arm.com { 27312239Sandreas.sandberg@arm.com platform->postConsoleInt(); 27412239Sandreas.sandberg@arm.com status |= RX_INT; 27512239Sandreas.sandberg@arm.com } 27612239Sandreas.sandberg@arm.com 27712239Sandreas.sandberg@arm.com} 27812239Sandreas.sandberg@arm.com 27912239Sandreas.sandberg@arm.comAddrRangeList 28012239Sandreas.sandberg@arm.comUart8250::getAddrRanges() const 28112239Sandreas.sandberg@arm.com{ 28212239Sandreas.sandberg@arm.com AddrRangeList ranges; 28312239Sandreas.sandberg@arm.com ranges.push_back(RangeSize(pioAddr, pioSize)); 28412239Sandreas.sandberg@arm.com return ranges; 28512239Sandreas.sandberg@arm.com} 28612239Sandreas.sandberg@arm.com 28712239Sandreas.sandberg@arm.comvoid 28812239Sandreas.sandberg@arm.comUart8250::serialize(CheckpointOut &cp) const 28912239Sandreas.sandberg@arm.com{ 29012239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(status); 29112239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(IER); 29212239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(DLAB); 29312239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(LCR); 29412239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(MCR); 29512239Sandreas.sandberg@arm.com Tick rxintrwhen; 29612239Sandreas.sandberg@arm.com if (rxIntrEvent.scheduled()) 29712239Sandreas.sandberg@arm.com rxintrwhen = rxIntrEvent.when(); 29812239Sandreas.sandberg@arm.com else 29912239Sandreas.sandberg@arm.com rxintrwhen = 0; 30012239Sandreas.sandberg@arm.com Tick txintrwhen; 30112239Sandreas.sandberg@arm.com if (txIntrEvent.scheduled()) 30212239Sandreas.sandberg@arm.com txintrwhen = txIntrEvent.when(); 30312239Sandreas.sandberg@arm.com else 30412239Sandreas.sandberg@arm.com txintrwhen = 0; 30512239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(rxintrwhen); 30612239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(txintrwhen); 30712239Sandreas.sandberg@arm.com} 30812239Sandreas.sandberg@arm.com 30912239Sandreas.sandberg@arm.comvoid 31012239Sandreas.sandberg@arm.comUart8250::unserialize(CheckpointIn &cp) 31112239Sandreas.sandberg@arm.com{ 31212239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(status); 31312239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(IER); 31412239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(DLAB); 31512239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(LCR); 31612239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(MCR); 31712239Sandreas.sandberg@arm.com Tick rxintrwhen; 31812239Sandreas.sandberg@arm.com Tick txintrwhen; 31912239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(rxintrwhen); 32012239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(txintrwhen); 32112239Sandreas.sandberg@arm.com if (rxintrwhen != 0) 32212239Sandreas.sandberg@arm.com schedule(rxIntrEvent, rxintrwhen); 32312239Sandreas.sandberg@arm.com if (txintrwhen != 0) 32412239Sandreas.sandberg@arm.com schedule(txIntrEvent, txintrwhen); 32512239Sandreas.sandberg@arm.com} 32612239Sandreas.sandberg@arm.com 32712239Sandreas.sandberg@arm.comUart8250 * 32812239Sandreas.sandberg@arm.comUart8250Params::create() 32912239Sandreas.sandberg@arm.com{ 33012239Sandreas.sandberg@arm.com return new Uart8250(this); 33112239Sandreas.sandberg@arm.com} 332