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.com
5012239Sandreas.sandberg@arm.comvoid
5112239Sandreas.sandberg@arm.comUart8250::processIntrEvent(int intrBit)
5212239Sandreas.sandberg@arm.com{
5312239Sandreas.sandberg@arm.com    if (intrBit & IER) {
5412239Sandreas.sandberg@arm.com       DPRINTF(Uart, "UART InterEvent, interrupting\n");
5512239Sandreas.sandberg@arm.com       platform->postConsoleInt();
5612239Sandreas.sandberg@arm.com       status |= intrBit;
5712239Sandreas.sandberg@arm.com       lastTxInt = curTick();
5812239Sandreas.sandberg@arm.com    }
5912239Sandreas.sandberg@arm.com    else
6012239Sandreas.sandberg@arm.com       DPRINTF(Uart, "UART InterEvent, not interrupting\n");
6112239Sandreas.sandberg@arm.com
6212239Sandreas.sandberg@arm.com}
6312239Sandreas.sandberg@arm.com
6412239Sandreas.sandberg@arm.com/* The linux serial driver (8250.c about line 1182) loops reading from
6512239Sandreas.sandberg@arm.com * the device until the device reports it has no more data to
6612239Sandreas.sandberg@arm.com * read. After a maximum of 255 iterations the code prints "serial8250
6712239Sandreas.sandberg@arm.com * too much work for irq X," and breaks out of the loop. Since the
6812239Sandreas.sandberg@arm.com * simulated system is so much slower than the actual system, if a
6912239Sandreas.sandberg@arm.com * user is typing on the keyboard it is very easy for them to provide
7012239Sandreas.sandberg@arm.com * input at a fast enough rate to not allow the loop to exit and thus
7112239Sandreas.sandberg@arm.com * the error to be printed. This magic number provides a delay between
7212239Sandreas.sandberg@arm.com * the time the UART receives a character to send to the simulated
7312239Sandreas.sandberg@arm.com * system and the time it actually notifies the system it has a
7412239Sandreas.sandberg@arm.com * character to send to alleviate this problem. --Ali
7512239Sandreas.sandberg@arm.com */
7612239Sandreas.sandberg@arm.comvoid
7712239Sandreas.sandberg@arm.comUart8250::scheduleIntr(Event *event)
7812239Sandreas.sandberg@arm.com{
7912239Sandreas.sandberg@arm.com    static const Tick interval = 225 * SimClock::Int::ns;
8012239Sandreas.sandberg@arm.com    DPRINTF(Uart, "Scheduling IER interrupt for %s, at cycle %lld\n",
8112239Sandreas.sandberg@arm.com            event->name(), curTick() + interval);
8212239Sandreas.sandberg@arm.com    if (!event->scheduled())
8312239Sandreas.sandberg@arm.com        schedule(event, curTick() + interval);
8412239Sandreas.sandberg@arm.com    else
8512239Sandreas.sandberg@arm.com        reschedule(event, curTick() + interval);
8612239Sandreas.sandberg@arm.com}
8712239Sandreas.sandberg@arm.com
8812239Sandreas.sandberg@arm.com
8912239Sandreas.sandberg@arm.comUart8250::Uart8250(const Params *p)
9012239Sandreas.sandberg@arm.com    : Uart(p, 8), IER(0), DLAB(0), LCR(0), MCR(0), lastTxInt(0),
9112239Sandreas.sandberg@arm.com      txIntrEvent([this]{ processIntrEvent(TX_INT); }, "TX"),
9212239Sandreas.sandberg@arm.com      rxIntrEvent([this]{ processIntrEvent(RX_INT); }, "RX")
9312239Sandreas.sandberg@arm.com{
9412239Sandreas.sandberg@arm.com}
9512239Sandreas.sandberg@arm.com
9612239Sandreas.sandberg@arm.comTick
9712239Sandreas.sandberg@arm.comUart8250::read(PacketPtr pkt)
9812239Sandreas.sandberg@arm.com{
9912239Sandreas.sandberg@arm.com    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
10012239Sandreas.sandberg@arm.com    assert(pkt->getSize() == 1);
10112239Sandreas.sandberg@arm.com
10212239Sandreas.sandberg@arm.com    Addr daddr = pkt->getAddr() - pioAddr;
10312239Sandreas.sandberg@arm.com
10412239Sandreas.sandberg@arm.com    DPRINTF(Uart, " read register %#x\n", daddr);
10512239Sandreas.sandberg@arm.com
10612239Sandreas.sandberg@arm.com    switch (daddr) {
10712239Sandreas.sandberg@arm.com        case 0x0:
10812239Sandreas.sandberg@arm.com            if (!(LCR & 0x80)) { // read byte
10912239Sandreas.sandberg@arm.com                if (device->dataAvailable())
11013342Sgabeblack@google.com                    pkt->setRaw(device->readData());
11112239Sandreas.sandberg@arm.com                else {
11213342Sgabeblack@google.com                    pkt->setRaw((uint8_t)0);
11312239Sandreas.sandberg@arm.com                    // A limited amount of these are ok.
11412239Sandreas.sandberg@arm.com                    DPRINTF(Uart, "empty read of RX register\n");
11512239Sandreas.sandberg@arm.com                }
11612239Sandreas.sandberg@arm.com                status &= ~RX_INT;
11712239Sandreas.sandberg@arm.com                platform->clearConsoleInt();
11812239Sandreas.sandberg@arm.com
11912239Sandreas.sandberg@arm.com                if (device->dataAvailable() && (IER & UART_IER_RDI))
12012239Sandreas.sandberg@arm.com                    scheduleIntr(&rxIntrEvent);
12112239Sandreas.sandberg@arm.com            } else { // dll divisor latch
12212239Sandreas.sandberg@arm.com               ;
12312239Sandreas.sandberg@arm.com            }
12412239Sandreas.sandberg@arm.com            break;
12512239Sandreas.sandberg@arm.com        case 0x1:
12612239Sandreas.sandberg@arm.com            if (!(LCR & 0x80)) { // Intr Enable Register(IER)
12713342Sgabeblack@google.com                pkt->setRaw(IER);
12812239Sandreas.sandberg@arm.com            } else { // DLM divisor latch MSB
12912239Sandreas.sandberg@arm.com                ;
13012239Sandreas.sandberg@arm.com            }
13112239Sandreas.sandberg@arm.com            break;
13212239Sandreas.sandberg@arm.com        case 0x2: // Intr Identification Register (IIR)
13312239Sandreas.sandberg@arm.com            DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
13412239Sandreas.sandberg@arm.com
13512239Sandreas.sandberg@arm.com            if (status & RX_INT) /* Rx data interrupt has a higher priority */
13613342Sgabeblack@google.com                pkt->setRaw(IIR_RXID);
13712239Sandreas.sandberg@arm.com            else if (status & TX_INT) {
13813342Sgabeblack@google.com                pkt->setRaw(IIR_TXID);
13912239Sandreas.sandberg@arm.com                //Tx interrupts are cleared on IIR reads
14012239Sandreas.sandberg@arm.com                status &= ~TX_INT;
14112239Sandreas.sandberg@arm.com            } else
14213342Sgabeblack@google.com                pkt->setRaw(IIR_NOPEND);
14312239Sandreas.sandberg@arm.com
14412239Sandreas.sandberg@arm.com            break;
14512239Sandreas.sandberg@arm.com        case 0x3: // Line Control Register (LCR)
14613342Sgabeblack@google.com            pkt->setRaw(LCR);
14712239Sandreas.sandberg@arm.com            break;
14812239Sandreas.sandberg@arm.com        case 0x4: // Modem Control Register (MCR)
14913342Sgabeblack@google.com            pkt->setRaw(MCR);
15012239Sandreas.sandberg@arm.com            break;
15112239Sandreas.sandberg@arm.com        case 0x5: // Line Status Register (LSR)
15212239Sandreas.sandberg@arm.com            uint8_t lsr;
15312239Sandreas.sandberg@arm.com            lsr = 0;
15412239Sandreas.sandberg@arm.com            // check if there are any bytes to be read
15512239Sandreas.sandberg@arm.com            if (device->dataAvailable())
15612239Sandreas.sandberg@arm.com                lsr = UART_LSR_DR;
15712239Sandreas.sandberg@arm.com            lsr |= UART_LSR_TEMT | UART_LSR_THRE;
15813342Sgabeblack@google.com            pkt->setRaw(lsr);
15912239Sandreas.sandberg@arm.com            break;
16012239Sandreas.sandberg@arm.com        case 0x6: // Modem Status Register (MSR)
16113342Sgabeblack@google.com            pkt->setRaw((uint8_t)0);
16212239Sandreas.sandberg@arm.com            break;
16312239Sandreas.sandberg@arm.com        case 0x7: // Scratch Register (SCR)
16413342Sgabeblack@google.com            pkt->setRaw((uint8_t)0); // doesn't exist with at 8250.
16512239Sandreas.sandberg@arm.com            break;
16612239Sandreas.sandberg@arm.com        default:
16712239Sandreas.sandberg@arm.com            panic("Tried to access a UART port that doesn't exist\n");
16812239Sandreas.sandberg@arm.com            break;
16912239Sandreas.sandberg@arm.com    }
17012239Sandreas.sandberg@arm.com/*    uint32_t d32 = *data;
17112239Sandreas.sandberg@arm.com    DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32);
17212239Sandreas.sandberg@arm.com*/
17312239Sandreas.sandberg@arm.com    pkt->makeAtomicResponse();
17412239Sandreas.sandberg@arm.com    return pioDelay;
17512239Sandreas.sandberg@arm.com}
17612239Sandreas.sandberg@arm.com
17712239Sandreas.sandberg@arm.comTick
17812239Sandreas.sandberg@arm.comUart8250::write(PacketPtr pkt)
17912239Sandreas.sandberg@arm.com{
18012239Sandreas.sandberg@arm.com
18112239Sandreas.sandberg@arm.com    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
18212239Sandreas.sandberg@arm.com    assert(pkt->getSize() == 1);
18312239Sandreas.sandberg@arm.com
18412239Sandreas.sandberg@arm.com    Addr daddr = pkt->getAddr() - pioAddr;
18512239Sandreas.sandberg@arm.com
18613342Sgabeblack@google.com    DPRINTF(Uart, " write register %#x value %#x\n", daddr,
18713342Sgabeblack@google.com            pkt->getRaw<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
19213342Sgabeblack@google.com                device->writeData(pkt->getRaw<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)
20313342Sgabeblack@google.com                IER = pkt->getRaw<uint8_t>();
20412239Sandreas.sandberg@arm.com                if (UART_IER_THRI & IER)
20512239Sandreas.sandberg@arm.com                {
20613342Sgabeblack@google.com                    DPRINTF(Uart,
20713342Sgabeblack@google.com                            "IER: IER_THRI set, scheduling TX intrrupt\n");
20812239Sandreas.sandberg@arm.com                    if (curTick() - lastTxInt > 225 * SimClock::Int::ns) {
20912239Sandreas.sandberg@arm.com                        DPRINTF(Uart, "-- Interrupting Immediately... %d,%d\n",
21012239Sandreas.sandberg@arm.com                                curTick(), lastTxInt);
21112239Sandreas.sandberg@arm.com                        txIntrEvent.process();
21212239Sandreas.sandberg@arm.com                    } else {
21312239Sandreas.sandberg@arm.com                        DPRINTF(Uart, "-- Delaying interrupt... %d,%d\n",
21412239Sandreas.sandberg@arm.com                                curTick(), lastTxInt);
21512239Sandreas.sandberg@arm.com                        scheduleIntr(&txIntrEvent);
21612239Sandreas.sandberg@arm.com                    }
21712239Sandreas.sandberg@arm.com                }
21812239Sandreas.sandberg@arm.com                else
21912239Sandreas.sandberg@arm.com                {
22013342Sgabeblack@google.com                    DPRINTF(Uart, "IER: IER_THRI cleared, "
22113342Sgabeblack@google.com                            "descheduling TX intrrupt\n");
22212239Sandreas.sandberg@arm.com                    if (txIntrEvent.scheduled())
22312239Sandreas.sandberg@arm.com                        deschedule(txIntrEvent);
22412239Sandreas.sandberg@arm.com                    if (status & TX_INT)
22512239Sandreas.sandberg@arm.com                        platform->clearConsoleInt();
22612239Sandreas.sandberg@arm.com                    status &= ~TX_INT;
22712239Sandreas.sandberg@arm.com                }
22812239Sandreas.sandberg@arm.com
22912239Sandreas.sandberg@arm.com                if ((UART_IER_RDI & IER) && device->dataAvailable()) {
23013342Sgabeblack@google.com                    DPRINTF(Uart,
23113342Sgabeblack@google.com                            "IER: IER_RDI set, scheduling RX intrrupt\n");
23212239Sandreas.sandberg@arm.com                    scheduleIntr(&rxIntrEvent);
23312239Sandreas.sandberg@arm.com                } else {
23413342Sgabeblack@google.com                    DPRINTF(Uart, "IER: IER_RDI cleared, "
23513342Sgabeblack@google.com                            "descheduling RX intrrupt\n");
23612239Sandreas.sandberg@arm.com                    if (rxIntrEvent.scheduled())
23712239Sandreas.sandberg@arm.com                        deschedule(rxIntrEvent);
23812239Sandreas.sandberg@arm.com                    if (status & RX_INT)
23912239Sandreas.sandberg@arm.com                        platform->clearConsoleInt();
24012239Sandreas.sandberg@arm.com                    status &= ~RX_INT;
24112239Sandreas.sandberg@arm.com                }
24212239Sandreas.sandberg@arm.com             } else { // DLM divisor latch MSB
24312239Sandreas.sandberg@arm.com                ;
24412239Sandreas.sandberg@arm.com            }
24512239Sandreas.sandberg@arm.com            break;
24612239Sandreas.sandberg@arm.com        case 0x2: // FIFO Control Register (FCR)
24712239Sandreas.sandberg@arm.com            break;
24812239Sandreas.sandberg@arm.com        case 0x3: // Line Control Register (LCR)
24913342Sgabeblack@google.com            LCR = pkt->getRaw<uint8_t>();
25012239Sandreas.sandberg@arm.com            break;
25112239Sandreas.sandberg@arm.com        case 0x4: // Modem Control Register (MCR)
25213342Sgabeblack@google.com            if (pkt->getRaw<uint8_t>() == (UART_MCR_LOOP | 0x0A))
25312239Sandreas.sandberg@arm.com                    MCR = 0x9A;
25412239Sandreas.sandberg@arm.com            break;
25512239Sandreas.sandberg@arm.com        case 0x7: // Scratch Register (SCR)
25612239Sandreas.sandberg@arm.com            // We are emulating a 8250 so we don't have a scratch reg
25712239Sandreas.sandberg@arm.com            break;
25812239Sandreas.sandberg@arm.com        default:
25912239Sandreas.sandberg@arm.com            panic("Tried to access a UART port that doesn't exist\n");
26012239Sandreas.sandberg@arm.com            break;
26112239Sandreas.sandberg@arm.com    }
26212239Sandreas.sandberg@arm.com    pkt->makeAtomicResponse();
26312239Sandreas.sandberg@arm.com    return pioDelay;
26412239Sandreas.sandberg@arm.com}
26512239Sandreas.sandberg@arm.com
26612239Sandreas.sandberg@arm.comvoid
26712239Sandreas.sandberg@arm.comUart8250::dataAvailable()
26812239Sandreas.sandberg@arm.com{
26912239Sandreas.sandberg@arm.com    // if the kernel wants an interrupt when we have data
27012239Sandreas.sandberg@arm.com    if (IER & UART_IER_RDI)
27112239Sandreas.sandberg@arm.com    {
27212239Sandreas.sandberg@arm.com        platform->postConsoleInt();
27312239Sandreas.sandberg@arm.com        status |= RX_INT;
27412239Sandreas.sandberg@arm.com    }
27512239Sandreas.sandberg@arm.com
27612239Sandreas.sandberg@arm.com}
27712239Sandreas.sandberg@arm.com
27812239Sandreas.sandberg@arm.comAddrRangeList
27912239Sandreas.sandberg@arm.comUart8250::getAddrRanges() const
28012239Sandreas.sandberg@arm.com{
28112239Sandreas.sandberg@arm.com    AddrRangeList ranges;
28212239Sandreas.sandberg@arm.com    ranges.push_back(RangeSize(pioAddr, pioSize));
28312239Sandreas.sandberg@arm.com    return ranges;
28412239Sandreas.sandberg@arm.com}
28512239Sandreas.sandberg@arm.com
28612239Sandreas.sandberg@arm.comvoid
28712239Sandreas.sandberg@arm.comUart8250::serialize(CheckpointOut &cp) const
28812239Sandreas.sandberg@arm.com{
28912239Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(status);
29012239Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(IER);
29112239Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(DLAB);
29212239Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(LCR);
29312239Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(MCR);
29412239Sandreas.sandberg@arm.com    Tick rxintrwhen;
29512239Sandreas.sandberg@arm.com    if (rxIntrEvent.scheduled())
29612239Sandreas.sandberg@arm.com        rxintrwhen = rxIntrEvent.when();
29712239Sandreas.sandberg@arm.com    else
29812239Sandreas.sandberg@arm.com        rxintrwhen = 0;
29912239Sandreas.sandberg@arm.com    Tick txintrwhen;
30012239Sandreas.sandberg@arm.com    if (txIntrEvent.scheduled())
30112239Sandreas.sandberg@arm.com        txintrwhen = txIntrEvent.when();
30212239Sandreas.sandberg@arm.com    else
30312239Sandreas.sandberg@arm.com        txintrwhen = 0;
30412239Sandreas.sandberg@arm.com     SERIALIZE_SCALAR(rxintrwhen);
30512239Sandreas.sandberg@arm.com     SERIALIZE_SCALAR(txintrwhen);
30612239Sandreas.sandberg@arm.com}
30712239Sandreas.sandberg@arm.com
30812239Sandreas.sandberg@arm.comvoid
30912239Sandreas.sandberg@arm.comUart8250::unserialize(CheckpointIn &cp)
31012239Sandreas.sandberg@arm.com{
31112239Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(status);
31212239Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(IER);
31312239Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(DLAB);
31412239Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(LCR);
31512239Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(MCR);
31612239Sandreas.sandberg@arm.com    Tick rxintrwhen;
31712239Sandreas.sandberg@arm.com    Tick txintrwhen;
31812239Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(rxintrwhen);
31912239Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(txintrwhen);
32012239Sandreas.sandberg@arm.com    if (rxintrwhen != 0)
32112239Sandreas.sandberg@arm.com        schedule(rxIntrEvent, rxintrwhen);
32212239Sandreas.sandberg@arm.com    if (txintrwhen != 0)
32312239Sandreas.sandberg@arm.com        schedule(txIntrEvent, txintrwhen);
32412239Sandreas.sandberg@arm.com}
32512239Sandreas.sandberg@arm.com
32612239Sandreas.sandberg@arm.comUart8250 *
32712239Sandreas.sandberg@arm.comUart8250Params::create()
32812239Sandreas.sandberg@arm.com{
32912239Sandreas.sandberg@arm.com    return new Uart8250(this);
33012239Sandreas.sandberg@arm.com}
331