uart8250.cc revision 12239
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()) 11112239Sandreas.sandberg@arm.com pkt->set(device->readData()); 11212239Sandreas.sandberg@arm.com else { 11312239Sandreas.sandberg@arm.com pkt->set((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) 12812239Sandreas.sandberg@arm.com pkt->set(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 */ 13712239Sandreas.sandberg@arm.com pkt->set(IIR_RXID); 13812239Sandreas.sandberg@arm.com else if (status & TX_INT) { 13912239Sandreas.sandberg@arm.com pkt->set(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 14312239Sandreas.sandberg@arm.com pkt->set(IIR_NOPEND); 14412239Sandreas.sandberg@arm.com 14512239Sandreas.sandberg@arm.com break; 14612239Sandreas.sandberg@arm.com case 0x3: // Line Control Register (LCR) 14712239Sandreas.sandberg@arm.com pkt->set(LCR); 14812239Sandreas.sandberg@arm.com break; 14912239Sandreas.sandberg@arm.com case 0x4: // Modem Control Register (MCR) 15012239Sandreas.sandberg@arm.com pkt->set(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; 15912239Sandreas.sandberg@arm.com pkt->set(lsr); 16012239Sandreas.sandberg@arm.com break; 16112239Sandreas.sandberg@arm.com case 0x6: // Modem Status Register (MSR) 16212239Sandreas.sandberg@arm.com pkt->set((uint8_t)0); 16312239Sandreas.sandberg@arm.com break; 16412239Sandreas.sandberg@arm.com case 0x7: // Scratch Register (SCR) 16512239Sandreas.sandberg@arm.com pkt->set((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 18712239Sandreas.sandberg@arm.com DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt->get<uint8_t>()); 18812239Sandreas.sandberg@arm.com 18912239Sandreas.sandberg@arm.com switch (daddr) { 19012239Sandreas.sandberg@arm.com case 0x0: 19112239Sandreas.sandberg@arm.com if (!(LCR & 0x80)) { // write byte 19212239Sandreas.sandberg@arm.com device->writeData(pkt->get<uint8_t>()); 19312239Sandreas.sandberg@arm.com platform->clearConsoleInt(); 19412239Sandreas.sandberg@arm.com status &= ~TX_INT; 19512239Sandreas.sandberg@arm.com if (UART_IER_THRI & IER) 19612239Sandreas.sandberg@arm.com scheduleIntr(&txIntrEvent); 19712239Sandreas.sandberg@arm.com } else { // dll divisor latch 19812239Sandreas.sandberg@arm.com ; 19912239Sandreas.sandberg@arm.com } 20012239Sandreas.sandberg@arm.com break; 20112239Sandreas.sandberg@arm.com case 0x1: 20212239Sandreas.sandberg@arm.com if (!(LCR & 0x80)) { // Intr Enable Register(IER) 20312239Sandreas.sandberg@arm.com IER = pkt->get<uint8_t>(); 20412239Sandreas.sandberg@arm.com if (UART_IER_THRI & IER) 20512239Sandreas.sandberg@arm.com { 20612239Sandreas.sandberg@arm.com DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n"); 20712239Sandreas.sandberg@arm.com if (curTick() - lastTxInt > 225 * SimClock::Int::ns) { 20812239Sandreas.sandberg@arm.com DPRINTF(Uart, "-- Interrupting Immediately... %d,%d\n", 20912239Sandreas.sandberg@arm.com curTick(), lastTxInt); 21012239Sandreas.sandberg@arm.com txIntrEvent.process(); 21112239Sandreas.sandberg@arm.com } else { 21212239Sandreas.sandberg@arm.com DPRINTF(Uart, "-- Delaying interrupt... %d,%d\n", 21312239Sandreas.sandberg@arm.com curTick(), lastTxInt); 21412239Sandreas.sandberg@arm.com scheduleIntr(&txIntrEvent); 21512239Sandreas.sandberg@arm.com } 21612239Sandreas.sandberg@arm.com } 21712239Sandreas.sandberg@arm.com else 21812239Sandreas.sandberg@arm.com { 21912239Sandreas.sandberg@arm.com DPRINTF(Uart, "IER: IER_THRI cleared, descheduling TX intrrupt\n"); 22012239Sandreas.sandberg@arm.com if (txIntrEvent.scheduled()) 22112239Sandreas.sandberg@arm.com deschedule(txIntrEvent); 22212239Sandreas.sandberg@arm.com if (status & TX_INT) 22312239Sandreas.sandberg@arm.com platform->clearConsoleInt(); 22412239Sandreas.sandberg@arm.com status &= ~TX_INT; 22512239Sandreas.sandberg@arm.com } 22612239Sandreas.sandberg@arm.com 22712239Sandreas.sandberg@arm.com if ((UART_IER_RDI & IER) && device->dataAvailable()) { 22812239Sandreas.sandberg@arm.com DPRINTF(Uart, "IER: IER_RDI set, scheduling RX intrrupt\n"); 22912239Sandreas.sandberg@arm.com scheduleIntr(&rxIntrEvent); 23012239Sandreas.sandberg@arm.com } else { 23112239Sandreas.sandberg@arm.com DPRINTF(Uart, "IER: IER_RDI cleared, descheduling RX intrrupt\n"); 23212239Sandreas.sandberg@arm.com if (rxIntrEvent.scheduled()) 23312239Sandreas.sandberg@arm.com deschedule(rxIntrEvent); 23412239Sandreas.sandberg@arm.com if (status & RX_INT) 23512239Sandreas.sandberg@arm.com platform->clearConsoleInt(); 23612239Sandreas.sandberg@arm.com status &= ~RX_INT; 23712239Sandreas.sandberg@arm.com } 23812239Sandreas.sandberg@arm.com } else { // DLM divisor latch MSB 23912239Sandreas.sandberg@arm.com ; 24012239Sandreas.sandberg@arm.com } 24112239Sandreas.sandberg@arm.com break; 24212239Sandreas.sandberg@arm.com case 0x2: // FIFO Control Register (FCR) 24312239Sandreas.sandberg@arm.com break; 24412239Sandreas.sandberg@arm.com case 0x3: // Line Control Register (LCR) 24512239Sandreas.sandberg@arm.com LCR = pkt->get<uint8_t>(); 24612239Sandreas.sandberg@arm.com break; 24712239Sandreas.sandberg@arm.com case 0x4: // Modem Control Register (MCR) 24812239Sandreas.sandberg@arm.com if (pkt->get<uint8_t>() == (UART_MCR_LOOP | 0x0A)) 24912239Sandreas.sandberg@arm.com MCR = 0x9A; 25012239Sandreas.sandberg@arm.com break; 25112239Sandreas.sandberg@arm.com case 0x7: // Scratch Register (SCR) 25212239Sandreas.sandberg@arm.com // We are emulating a 8250 so we don't have a scratch reg 25312239Sandreas.sandberg@arm.com break; 25412239Sandreas.sandberg@arm.com default: 25512239Sandreas.sandberg@arm.com panic("Tried to access a UART port that doesn't exist\n"); 25612239Sandreas.sandberg@arm.com break; 25712239Sandreas.sandberg@arm.com } 25812239Sandreas.sandberg@arm.com pkt->makeAtomicResponse(); 25912239Sandreas.sandberg@arm.com return pioDelay; 26012239Sandreas.sandberg@arm.com} 26112239Sandreas.sandberg@arm.com 26212239Sandreas.sandberg@arm.comvoid 26312239Sandreas.sandberg@arm.comUart8250::dataAvailable() 26412239Sandreas.sandberg@arm.com{ 26512239Sandreas.sandberg@arm.com // if the kernel wants an interrupt when we have data 26612239Sandreas.sandberg@arm.com if (IER & UART_IER_RDI) 26712239Sandreas.sandberg@arm.com { 26812239Sandreas.sandberg@arm.com platform->postConsoleInt(); 26912239Sandreas.sandberg@arm.com status |= RX_INT; 27012239Sandreas.sandberg@arm.com } 27112239Sandreas.sandberg@arm.com 27212239Sandreas.sandberg@arm.com} 27312239Sandreas.sandberg@arm.com 27412239Sandreas.sandberg@arm.comAddrRangeList 27512239Sandreas.sandberg@arm.comUart8250::getAddrRanges() const 27612239Sandreas.sandberg@arm.com{ 27712239Sandreas.sandberg@arm.com AddrRangeList ranges; 27812239Sandreas.sandberg@arm.com ranges.push_back(RangeSize(pioAddr, pioSize)); 27912239Sandreas.sandberg@arm.com return ranges; 28012239Sandreas.sandberg@arm.com} 28112239Sandreas.sandberg@arm.com 28212239Sandreas.sandberg@arm.comvoid 28312239Sandreas.sandberg@arm.comUart8250::serialize(CheckpointOut &cp) const 28412239Sandreas.sandberg@arm.com{ 28512239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(status); 28612239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(IER); 28712239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(DLAB); 28812239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(LCR); 28912239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(MCR); 29012239Sandreas.sandberg@arm.com Tick rxintrwhen; 29112239Sandreas.sandberg@arm.com if (rxIntrEvent.scheduled()) 29212239Sandreas.sandberg@arm.com rxintrwhen = rxIntrEvent.when(); 29312239Sandreas.sandberg@arm.com else 29412239Sandreas.sandberg@arm.com rxintrwhen = 0; 29512239Sandreas.sandberg@arm.com Tick txintrwhen; 29612239Sandreas.sandberg@arm.com if (txIntrEvent.scheduled()) 29712239Sandreas.sandberg@arm.com txintrwhen = txIntrEvent.when(); 29812239Sandreas.sandberg@arm.com else 29912239Sandreas.sandberg@arm.com txintrwhen = 0; 30012239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(rxintrwhen); 30112239Sandreas.sandberg@arm.com SERIALIZE_SCALAR(txintrwhen); 30212239Sandreas.sandberg@arm.com} 30312239Sandreas.sandberg@arm.com 30412239Sandreas.sandberg@arm.comvoid 30512239Sandreas.sandberg@arm.comUart8250::unserialize(CheckpointIn &cp) 30612239Sandreas.sandberg@arm.com{ 30712239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(status); 30812239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(IER); 30912239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(DLAB); 31012239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(LCR); 31112239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(MCR); 31212239Sandreas.sandberg@arm.com Tick rxintrwhen; 31312239Sandreas.sandberg@arm.com Tick txintrwhen; 31412239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(rxintrwhen); 31512239Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(txintrwhen); 31612239Sandreas.sandberg@arm.com if (rxintrwhen != 0) 31712239Sandreas.sandberg@arm.com schedule(rxIntrEvent, rxintrwhen); 31812239Sandreas.sandberg@arm.com if (txintrwhen != 0) 31912239Sandreas.sandberg@arm.com schedule(txIntrEvent, txintrwhen); 32012239Sandreas.sandberg@arm.com} 32112239Sandreas.sandberg@arm.com 32212239Sandreas.sandberg@arm.comUart8250 * 32312239Sandreas.sandberg@arm.comUart8250Params::create() 32412239Sandreas.sandberg@arm.com{ 32512239Sandreas.sandberg@arm.com return new Uart8250(this); 32612239Sandreas.sandberg@arm.com} 327