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