pl111.cc revision 13230
12315SN/A/*
213953Sgiacomo.gabrielli@arm.com * Copyright (c) 2010-2012, 2015 ARM Limited
39920Syasuko.eckert@amd.com * All rights reserved
48733Sgeoffrey.blake@arm.com *
58733Sgeoffrey.blake@arm.com * The license below extends only to copyright in the software and shall
68733Sgeoffrey.blake@arm.com * not be construed as granting a license to any other intellectual
78733Sgeoffrey.blake@arm.com * property including but not limited to intellectual property relating
88733Sgeoffrey.blake@arm.com * to a hardware implementation of the functionality of the software
98733Sgeoffrey.blake@arm.com * licensed hereunder.  You may use the software subject to the license
108733Sgeoffrey.blake@arm.com * terms below provided that you ensure that this notice is replicated
118733Sgeoffrey.blake@arm.com * unmodified and in its entirety in all distributions of the software,
128733Sgeoffrey.blake@arm.com * modified or unmodified, in source code or in binary form.
138733Sgeoffrey.blake@arm.com *
148733Sgeoffrey.blake@arm.com * Redistribution and use in source and binary forms, with or without
152332SN/A * modification, are permitted provided that the following conditions are
162315SN/A * met: redistributions of source code must retain the above copyright
172315SN/A * notice, this list of conditions and the following disclaimer;
182315SN/A * redistributions in binary form must reproduce the above copyright
192315SN/A * notice, this list of conditions and the following disclaimer in the
202315SN/A * documentation and/or other materials provided with the distribution;
212315SN/A * neither the name of the copyright holders nor the names of its
222315SN/A * contributors may be used to endorse or promote products derived from
232315SN/A * this software without specific prior written permission.
242315SN/A *
252315SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262315SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272315SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282315SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292315SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302315SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312315SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322315SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332315SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342315SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352315SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362315SN/A *
372315SN/A * Authors: William Wang
382315SN/A *          Ali Saidi
392315SN/A */
402689Sktlim@umich.edu
412689Sktlim@umich.edu#include "dev/arm/pl111.hh"
422315SN/A
432315SN/A#include "base/output.hh"
442315SN/A#include "base/trace.hh"
452315SN/A#include "base/vnc/vncinput.hh"
462315SN/A#include "debug/PL111.hh"
472315SN/A#include "debug/Uart.hh"
488229Snate@binkert.org#include "dev/arm/amba_device.hh"
492315SN/A#include "dev/arm/base_gic.hh"
502315SN/A#include "mem/packet.hh"
512669Sktlim@umich.edu#include "mem/packet_access.hh"
522315SN/A#include "sim/system.hh"
532315SN/A
542315SN/A// clang complains about std::set being overloaded with Packet::set if
5510319SAndreas.Sandberg@ARM.com// we open up the entire namespace std
5612107SRekai.GonzalezAlberquilla@arm.comusing std::vector;
578229Snate@binkert.org
582683Sktlim@umich.edu// initialize clcd registers
592315SN/APl111::Pl111(const Params *p)
608733Sgeoffrey.blake@arm.com    : AmbaDmaDevice(p), lcdTiming0(0), lcdTiming1(0), lcdTiming2(0),
6111608Snikos.nikoleris@arm.com      lcdTiming3(0), lcdUpbase(0), lcdLpbase(0), lcdControl(0), lcdImsc(0),
628733Sgeoffrey.blake@arm.com      lcdRis(0), lcdMis(0),
632315SN/A      clcdCrsrCtrl(0), clcdCrsrConfig(0), clcdCrsrPalette0(0),
642315SN/A      clcdCrsrPalette1(0), clcdCrsrXY(0), clcdCrsrClip(0), clcdCrsrImsc(0),
6512406Sgabeblack@google.com      clcdCrsrIcr(0), clcdCrsrRis(0), clcdCrsrMis(0),
662315SN/A      pixelClock(p->pixel_clock),
672315SN/A      converter(PixelConverter::rgba8888_le), fb(LcdMaxWidth, LcdMaxHeight),
682680Sktlim@umich.edu      vnc(p->vnc), bmp(&fb), pic(NULL),
692669Sktlim@umich.edu      width(LcdMaxWidth), height(LcdMaxHeight),
702315SN/A      bytesPerPixel(4), startTime(0), startAddr(0), maxAddr(0), curAddr(0),
712350SN/A      waterMark(0), dmaPendingNum(0),
722350SN/A      readEvent([this]{ readFramebuffer(); }, name()),
732350SN/A      fillFifoEvent([this]{ fillFifo(); }, name()),
742350SN/A      dmaDoneEventAll(maxOutstandingDma, this),
752350SN/A      dmaDoneEventFree(maxOutstandingDma),
762350SN/A      intEvent([this]{ generateInterrupt(); }, name()),
772350SN/A      enableCapture(p->enable_capture)
782350SN/A{
792350SN/A    pioSize = 0xFFFF;
802350SN/A
812680Sktlim@umich.edu    dmaBuffer = new uint8_t[buffer_size];
822683Sktlim@umich.edu
832680Sktlim@umich.edu    memset(lcdPalette, 0, sizeof(lcdPalette));
842350SN/A    memset(cursorImage, 0, sizeof(cursorImage));
852680Sktlim@umich.edu    memset(dmaBuffer, 0, buffer_size);
862350SN/A
8710319SAndreas.Sandberg@ARM.com    for (int i = 0; i < maxOutstandingDma; ++i)
882315SN/A        dmaDoneEventFree[i] = &dmaDoneEventAll[i];
892315SN/A
902315SN/A    if (vnc)
9112109SRekai.GonzalezAlberquilla@arm.com        vnc->setFrameBuffer(&fb);
928832SAli.Saidi@ARM.com}
938832SAli.Saidi@ARM.com
948832SAli.Saidi@ARM.comPl111::~Pl111()
952315SN/A{
9611169Sandreas.hansson@arm.com    delete[] dmaBuffer;
972315SN/A}
985529Snate@binkert.org
992315SN/A// read registers and frame buffer
1002315SN/ATick
1012315SN/APl111::read(PacketPtr pkt)
1022315SN/A{
1032315SN/A    // use a temporary data since the LCD registers are read/written with
1049608Sandreas.hansson@arm.com    // different size operations
1052679Sktlim@umich.edu
1069608Sandreas.hansson@arm.com    uint32_t data = 0;
1072679Sktlim@umich.edu
10811169Sandreas.hansson@arm.com    assert(pkt->getAddr() >= pioAddr &&
1098887Sgeoffrey.blake@arm.com           pkt->getAddr() < pioAddr + pioSize);
1109176Sandreas.hansson@arm.com
1119176Sandreas.hansson@arm.com    Addr daddr = pkt->getAddr() - pioAddr;
1129176Sandreas.hansson@arm.com
1138887Sgeoffrey.blake@arm.com    DPRINTF(PL111, " read register %#x size=%d\n", daddr, pkt->getSize());
1148887Sgeoffrey.blake@arm.com
1158887Sgeoffrey.blake@arm.com    switch (daddr) {
11611169Sandreas.hansson@arm.com      case LcdTiming0:
1178887Sgeoffrey.blake@arm.com        data = lcdTiming0;
1189176Sandreas.hansson@arm.com        break;
1199176Sandreas.hansson@arm.com      case LcdTiming1:
1209176Sandreas.hansson@arm.com        data = lcdTiming1;
1218887Sgeoffrey.blake@arm.com        break;
1228887Sgeoffrey.blake@arm.com      case LcdTiming2:
1232679Sktlim@umich.edu        data = lcdTiming2;
1249176Sandreas.hansson@arm.com        break;
1259176Sandreas.hansson@arm.com      case LcdTiming3:
1269176Sandreas.hansson@arm.com        data = lcdTiming3;
1279176Sandreas.hansson@arm.com        break;
1289176Sandreas.hansson@arm.com      case LcdUpBase:
1299176Sandreas.hansson@arm.com        data = lcdUpbase;
1309608Sandreas.hansson@arm.com        break;
1319608Sandreas.hansson@arm.com      case LcdLpBase:
1322315SN/A        data = lcdLpbase;
1332680Sktlim@umich.edu        break;
1342315SN/A      case LcdControl:
13512406Sgabeblack@google.com        data = lcdControl;
13612406Sgabeblack@google.com        break;
1372315SN/A      case LcdImsc:
1382315SN/A        data = lcdImsc;
1392315SN/A        break;
1408733Sgeoffrey.blake@arm.com      case LcdRis:
1418733Sgeoffrey.blake@arm.com        data = lcdRis;
14212107SRekai.GonzalezAlberquilla@arm.com        break;
1432315SN/A      case LcdMis:
1442315SN/A        data = lcdMis;
1458733Sgeoffrey.blake@arm.com        break;
1462315SN/A      case LcdIcr:
1472315SN/A        panic("LCD register at offset %#x is Write-Only\n", daddr);
1482315SN/A        break;
1492315SN/A      case LcdUpCurr:
1502315SN/A        data = curAddr;
1512315SN/A        break;
1522315SN/A      case LcdLpCurr:
1539176Sandreas.hansson@arm.com        data = curAddr;
1549176Sandreas.hansson@arm.com        break;
1559176Sandreas.hansson@arm.com      case ClcdCrsrCtrl:
1569176Sandreas.hansson@arm.com        data = clcdCrsrCtrl;
1579176Sandreas.hansson@arm.com        break;
15812406Sgabeblack@google.com      case ClcdCrsrConfig:
15912406Sgabeblack@google.com        data = clcdCrsrConfig;
1608733Sgeoffrey.blake@arm.com        break;
16111169Sandreas.hansson@arm.com      case ClcdCrsrPalette0:
1628887Sgeoffrey.blake@arm.com        data = clcdCrsrPalette0;
1638887Sgeoffrey.blake@arm.com        break;
1648887Sgeoffrey.blake@arm.com      case ClcdCrsrPalette1:
1658887Sgeoffrey.blake@arm.com        data = clcdCrsrPalette1;
16611169Sandreas.hansson@arm.com        break;
1672315SN/A      case ClcdCrsrXY:
1682930Sktlim@umich.edu        data = clcdCrsrXY;
1692315SN/A        break;
1702315SN/A      case ClcdCrsrClip:
1712315SN/A        data = clcdCrsrClip;
1722315SN/A        break;
1732315SN/A      case ClcdCrsrImsc:
1742315SN/A        data = clcdCrsrImsc;
17511168Sandreas.hansson@arm.com        break;
17611168Sandreas.hansson@arm.com      case ClcdCrsrIcr:
1772315SN/A        panic("CLCD register at offset %#x is Write-Only\n", daddr);
1782315SN/A        break;
1792315SN/A      case ClcdCrsrRis:
1802315SN/A        data = clcdCrsrRis;
1812315SN/A        break;
1822315SN/A      case ClcdCrsrMis:
1832315SN/A        data = clcdCrsrMis;
1842315SN/A        break;
1852315SN/A      default:
1862315SN/A        if (readId(pkt, AMBA_ID, pioAddr)) {
1872315SN/A            // Hack for variable size accesses
1882315SN/A            data = pkt->getLE<uint32_t>();
18913557Sgabeblack@google.com            break;
19013557Sgabeblack@google.com        } else if (daddr >= CrsrImage && daddr <= 0xBFC) {
1912315SN/A            // CURSOR IMAGE
19212106SRekai.GonzalezAlberquilla@arm.com            int index;
19312106SRekai.GonzalezAlberquilla@arm.com            index = (daddr - CrsrImage) >> 2;
19412106SRekai.GonzalezAlberquilla@arm.com            data= cursorImage[index];
1952315SN/A            break;
1962315SN/A        } else if (daddr >= LcdPalette && daddr <= 0x3FC) {
19713557Sgabeblack@google.com            // LCD Palette
19813557Sgabeblack@google.com            int index;
1992669Sktlim@umich.edu            index = (daddr - LcdPalette) >> 2;
20012106SRekai.GonzalezAlberquilla@arm.com            data = lcdPalette[index];
20112106SRekai.GonzalezAlberquilla@arm.com            break;
20213611Sgabeblack@google.com        } else {
2032315SN/A            panic("Tried to read CLCD register at offset %#x that "
2042315SN/A                       "doesn't exist\n", daddr);
20512109SRekai.GonzalezAlberquilla@arm.com            break;
20612109SRekai.GonzalezAlberquilla@arm.com        }
20712109SRekai.GonzalezAlberquilla@arm.com    }
20813557Sgabeblack@google.com
20913557Sgabeblack@google.com    switch(pkt->getSize()) {
21012109SRekai.GonzalezAlberquilla@arm.com      case 1:
21112109SRekai.GonzalezAlberquilla@arm.com        pkt->setLE<uint8_t>(data);
21212109SRekai.GonzalezAlberquilla@arm.com        break;
21312109SRekai.GonzalezAlberquilla@arm.com      case 2:
21412109SRekai.GonzalezAlberquilla@arm.com        pkt->setLE<uint16_t>(data);
21512109SRekai.GonzalezAlberquilla@arm.com        break;
21612109SRekai.GonzalezAlberquilla@arm.com      case 4:
21712109SRekai.GonzalezAlberquilla@arm.com        pkt->setLE<uint32_t>(data);
21812109SRekai.GonzalezAlberquilla@arm.com        break;
21913557Sgabeblack@google.com      default:
22013557Sgabeblack@google.com        panic("CLCD controller read size too big?\n");
22112109SRekai.GonzalezAlberquilla@arm.com        break;
22212109SRekai.GonzalezAlberquilla@arm.com    }
22312109SRekai.GonzalezAlberquilla@arm.com
22412109SRekai.GonzalezAlberquilla@arm.com    pkt->makeAtomicResponse();
22512109SRekai.GonzalezAlberquilla@arm.com    return pioDelay;
22612109SRekai.GonzalezAlberquilla@arm.com}
22712109SRekai.GonzalezAlberquilla@arm.com
22812109SRekai.GonzalezAlberquilla@arm.com// write registers and frame buffer
22912109SRekai.GonzalezAlberquilla@arm.comTick
23012109SRekai.GonzalezAlberquilla@arm.comPl111::write(PacketPtr pkt)
23113557Sgabeblack@google.com{
23212109SRekai.GonzalezAlberquilla@arm.com    // use a temporary data since the LCD registers are read/written with
23312109SRekai.GonzalezAlberquilla@arm.com    // different size operations
23412109SRekai.GonzalezAlberquilla@arm.com    //
23512109SRekai.GonzalezAlberquilla@arm.com    uint32_t data = 0;
23612109SRekai.GonzalezAlberquilla@arm.com
23712109SRekai.GonzalezAlberquilla@arm.com    switch(pkt->getSize()) {
23812109SRekai.GonzalezAlberquilla@arm.com      case 1:
23912109SRekai.GonzalezAlberquilla@arm.com        data = pkt->getLE<uint8_t>();
24013557Sgabeblack@google.com        break;
24112109SRekai.GonzalezAlberquilla@arm.com      case 2:
24212109SRekai.GonzalezAlberquilla@arm.com        data = pkt->getLE<uint16_t>();
24312109SRekai.GonzalezAlberquilla@arm.com        break;
24412109SRekai.GonzalezAlberquilla@arm.com      case 4:
24512109SRekai.GonzalezAlberquilla@arm.com        data = pkt->getLE<uint32_t>();
24612109SRekai.GonzalezAlberquilla@arm.com        break;
24712109SRekai.GonzalezAlberquilla@arm.com      default:
24812109SRekai.GonzalezAlberquilla@arm.com        panic("PL111 CLCD controller write size too big?\n");
24913557Sgabeblack@google.com        break;
25012109SRekai.GonzalezAlberquilla@arm.com    }
25112109SRekai.GonzalezAlberquilla@arm.com
25212109SRekai.GonzalezAlberquilla@arm.com    assert(pkt->getAddr() >= pioAddr &&
25312109SRekai.GonzalezAlberquilla@arm.com           pkt->getAddr() < pioAddr + pioSize);
25412109SRekai.GonzalezAlberquilla@arm.com
25512109SRekai.GonzalezAlberquilla@arm.com    Addr daddr = pkt->getAddr() - pioAddr;
25612109SRekai.GonzalezAlberquilla@arm.com
25712109SRekai.GonzalezAlberquilla@arm.com    DPRINTF(PL111, " write register %#x value %#x size=%d\n", daddr,
25813557Sgabeblack@google.com            pkt->getLE<uint8_t>(), pkt->getSize());
25912109SRekai.GonzalezAlberquilla@arm.com
26012109SRekai.GonzalezAlberquilla@arm.com    switch (daddr) {
26112109SRekai.GonzalezAlberquilla@arm.com      case LcdTiming0:
26212109SRekai.GonzalezAlberquilla@arm.com        lcdTiming0 = data;
26312109SRekai.GonzalezAlberquilla@arm.com        // width = 16 * (PPL+1)
26412109SRekai.GonzalezAlberquilla@arm.com        width = (lcdTiming0.ppl + 1) << 4;
26512109SRekai.GonzalezAlberquilla@arm.com        break;
26612109SRekai.GonzalezAlberquilla@arm.com      case LcdTiming1:
26712109SRekai.GonzalezAlberquilla@arm.com        lcdTiming1 = data;
26812109SRekai.GonzalezAlberquilla@arm.com        // height = LPP + 1
26912109SRekai.GonzalezAlberquilla@arm.com        height = (lcdTiming1.lpp) + 1;
27012109SRekai.GonzalezAlberquilla@arm.com        break;
27112109SRekai.GonzalezAlberquilla@arm.com      case LcdTiming2:
27212109SRekai.GonzalezAlberquilla@arm.com        lcdTiming2 = data;
27312109SRekai.GonzalezAlberquilla@arm.com        break;
27412109SRekai.GonzalezAlberquilla@arm.com      case LcdTiming3:
27512109SRekai.GonzalezAlberquilla@arm.com        lcdTiming3 = data;
27612109SRekai.GonzalezAlberquilla@arm.com        break;
27712109SRekai.GonzalezAlberquilla@arm.com      case LcdUpBase:
27812109SRekai.GonzalezAlberquilla@arm.com        lcdUpbase = data;
27912109SRekai.GonzalezAlberquilla@arm.com        DPRINTF(PL111, "####### Upper panel base set to: %#x #######\n", lcdUpbase);
28012109SRekai.GonzalezAlberquilla@arm.com        break;
28112109SRekai.GonzalezAlberquilla@arm.com      case LcdLpBase:
28212109SRekai.GonzalezAlberquilla@arm.com        warn_once("LCD dual screen mode not supported\n");
28312109SRekai.GonzalezAlberquilla@arm.com        lcdLpbase = data;
28412109SRekai.GonzalezAlberquilla@arm.com        DPRINTF(PL111, "###### Lower panel base set to: %#x #######\n", lcdLpbase);
28512109SRekai.GonzalezAlberquilla@arm.com        break;
28612109SRekai.GonzalezAlberquilla@arm.com      case LcdControl:
28712109SRekai.GonzalezAlberquilla@arm.com        int old_lcdpwr;
28812109SRekai.GonzalezAlberquilla@arm.com        old_lcdpwr = lcdControl.lcdpwr;
28912109SRekai.GonzalezAlberquilla@arm.com        lcdControl = data;
29012109SRekai.GonzalezAlberquilla@arm.com
29112109SRekai.GonzalezAlberquilla@arm.com        DPRINTF(PL111, "LCD power is:%d\n", lcdControl.lcdpwr);
29212109SRekai.GonzalezAlberquilla@arm.com
29312109SRekai.GonzalezAlberquilla@arm.com        // LCD power enable
29412109SRekai.GonzalezAlberquilla@arm.com        if (lcdControl.lcdpwr && !old_lcdpwr) {
29512109SRekai.GonzalezAlberquilla@arm.com            updateVideoParams();
29612109SRekai.GonzalezAlberquilla@arm.com            DPRINTF(PL111, " lcd size: height %d width %d\n", height, width);
29712109SRekai.GonzalezAlberquilla@arm.com            waterMark = lcdControl.watermark ? 8 : 4;
29812109SRekai.GonzalezAlberquilla@arm.com            startDma();
29912109SRekai.GonzalezAlberquilla@arm.com        }
30013557Sgabeblack@google.com        break;
30113557Sgabeblack@google.com      case LcdImsc:
30212109SRekai.GonzalezAlberquilla@arm.com        lcdImsc = data;
30312109SRekai.GonzalezAlberquilla@arm.com        if (lcdImsc.vcomp)
30412109SRekai.GonzalezAlberquilla@arm.com            panic("Interrupting on vcomp not supported\n");
30512109SRekai.GonzalezAlberquilla@arm.com
30612109SRekai.GonzalezAlberquilla@arm.com        lcdMis = lcdImsc & lcdRis;
30713610Sgiacomo.gabrielli@arm.com
30813610Sgiacomo.gabrielli@arm.com        if (!lcdMis)
30913610Sgiacomo.gabrielli@arm.com            gic->clearInt(intNum);
31013610Sgiacomo.gabrielli@arm.com
31113610Sgiacomo.gabrielli@arm.com         break;
31213610Sgiacomo.gabrielli@arm.com      case LcdRis:
31313610Sgiacomo.gabrielli@arm.com        panic("LCD register at offset %#x is Read-Only\n", daddr);
31413610Sgiacomo.gabrielli@arm.com        break;
31513610Sgiacomo.gabrielli@arm.com      case LcdMis:
31613610Sgiacomo.gabrielli@arm.com        panic("LCD register at offset %#x is Read-Only\n", daddr);
31713610Sgiacomo.gabrielli@arm.com        break;
31813610Sgiacomo.gabrielli@arm.com      case LcdIcr:
31913610Sgiacomo.gabrielli@arm.com        lcdRis = lcdRis & ~data;
32013610Sgiacomo.gabrielli@arm.com        lcdMis = lcdImsc & lcdRis;
32113610Sgiacomo.gabrielli@arm.com
32213610Sgiacomo.gabrielli@arm.com        if (!lcdMis)
32313622Sgabeblack@google.com            gic->clearInt(intNum);
32413557Sgabeblack@google.com
3259920Syasuko.eckert@amd.com        break;
32612106SRekai.GonzalezAlberquilla@arm.com      case LcdUpCurr:
32712106SRekai.GonzalezAlberquilla@arm.com        panic("LCD register at offset %#x is Read-Only\n", daddr);
32812106SRekai.GonzalezAlberquilla@arm.com        break;
3299920Syasuko.eckert@amd.com      case LcdLpCurr:
3309920Syasuko.eckert@amd.com        panic("LCD register at offset %#x is Read-Only\n", daddr);
33112107SRekai.GonzalezAlberquilla@arm.com        break;
33213557Sgabeblack@google.com      case ClcdCrsrCtrl:
33313557Sgabeblack@google.com        clcdCrsrCtrl = data;
3348733Sgeoffrey.blake@arm.com        break;
33512107SRekai.GonzalezAlberquilla@arm.com      case ClcdCrsrConfig:
33613557Sgabeblack@google.com        clcdCrsrConfig = data;
3378733Sgeoffrey.blake@arm.com        break;
3388733Sgeoffrey.blake@arm.com      case ClcdCrsrPalette0:
33912109SRekai.GonzalezAlberquilla@arm.com        clcdCrsrPalette0 = data;
34013557Sgabeblack@google.com        break;
34113557Sgabeblack@google.com      case ClcdCrsrPalette1:
34212109SRekai.GonzalezAlberquilla@arm.com        clcdCrsrPalette1 = data;
34312109SRekai.GonzalezAlberquilla@arm.com        break;
34413557Sgabeblack@google.com      case ClcdCrsrXY:
34512109SRekai.GonzalezAlberquilla@arm.com        clcdCrsrXY = data;
34612109SRekai.GonzalezAlberquilla@arm.com        break;
34712109SRekai.GonzalezAlberquilla@arm.com      case ClcdCrsrClip:
34813557Sgabeblack@google.com        clcdCrsrClip = data;
34913557Sgabeblack@google.com        break;
35012109SRekai.GonzalezAlberquilla@arm.com      case ClcdCrsrImsc:
35112109SRekai.GonzalezAlberquilla@arm.com        clcdCrsrImsc = data;
35213557Sgabeblack@google.com        break;
35312109SRekai.GonzalezAlberquilla@arm.com      case ClcdCrsrIcr:
35412109SRekai.GonzalezAlberquilla@arm.com        clcdCrsrIcr = data;
35513610Sgiacomo.gabrielli@arm.com        break;
35613610Sgiacomo.gabrielli@arm.com      case ClcdCrsrRis:
35713610Sgiacomo.gabrielli@arm.com        panic("CLCD register at offset %#x is Read-Only\n", daddr);
35813610Sgiacomo.gabrielli@arm.com        break;
35913610Sgiacomo.gabrielli@arm.com      case ClcdCrsrMis:
36013610Sgiacomo.gabrielli@arm.com        panic("CLCD register at offset %#x is Read-Only\n", daddr);
36113610Sgiacomo.gabrielli@arm.com        break;
36213610Sgiacomo.gabrielli@arm.com      default:
36313557Sgabeblack@google.com        if (daddr >= CrsrImage && daddr <= 0xBFC) {
36413557Sgabeblack@google.com            // CURSOR IMAGE
3652315SN/A            int index;
36612106SRekai.GonzalezAlberquilla@arm.com            index = (daddr - CrsrImage) >> 2;
36712106SRekai.GonzalezAlberquilla@arm.com            cursorImage[index] = data;
36812106SRekai.GonzalezAlberquilla@arm.com            break;
36912107SRekai.GonzalezAlberquilla@arm.com        } else if (daddr >= LcdPalette && daddr <= 0x3FC) {
3702315SN/A            // LCD Palette
3712315SN/A            int index;
37213557Sgabeblack@google.com            index = (daddr - LcdPalette) >> 2;
37313557Sgabeblack@google.com            lcdPalette[index] = data;
3742315SN/A            break;
37512106SRekai.GonzalezAlberquilla@arm.com        } else {
37612106SRekai.GonzalezAlberquilla@arm.com            panic("Tried to write PL111 register at offset %#x that "
37713611Sgabeblack@google.com                       "doesn't exist\n", daddr);
37812107SRekai.GonzalezAlberquilla@arm.com            break;
3792315SN/A        }
3802315SN/A    }
38113557Sgabeblack@google.com
38213622Sgabeblack@google.com    pkt->makeAtomicResponse();
3839920Syasuko.eckert@amd.com    return pioDelay;
38412106SRekai.GonzalezAlberquilla@arm.com}
38512106SRekai.GonzalezAlberquilla@arm.com
38612106SRekai.GonzalezAlberquilla@arm.comPixelConverter
38712107SRekai.GonzalezAlberquilla@arm.comPl111::pixelConverter() const
3889920Syasuko.eckert@amd.com{
3899920Syasuko.eckert@amd.com    unsigned rw, gw, bw;
39013557Sgabeblack@google.com    unsigned offsets[3];
39113557Sgabeblack@google.com
39213557Sgabeblack@google.com    switch (lcdControl.lcdbpp) {
39312109SRekai.GonzalezAlberquilla@arm.com      case bpp24:
39412109SRekai.GonzalezAlberquilla@arm.com        rw = gw = bw = 8;
39512109SRekai.GonzalezAlberquilla@arm.com        offsets[0] = 0;
39612109SRekai.GonzalezAlberquilla@arm.com        offsets[1] = 8;
39712109SRekai.GonzalezAlberquilla@arm.com        offsets[2] = 16;
39812109SRekai.GonzalezAlberquilla@arm.com        break;
39912109SRekai.GonzalezAlberquilla@arm.com
40013557Sgabeblack@google.com      case bpp16m565:
40113557Sgabeblack@google.com        rw = 5;
40213557Sgabeblack@google.com        gw = 6;
40312109SRekai.GonzalezAlberquilla@arm.com        bw = 5;
40412109SRekai.GonzalezAlberquilla@arm.com        offsets[0] = 0;
40512109SRekai.GonzalezAlberquilla@arm.com        offsets[1] = 5;
40612109SRekai.GonzalezAlberquilla@arm.com        offsets[2] = 11;
40712109SRekai.GonzalezAlberquilla@arm.com        break;
40812109SRekai.GonzalezAlberquilla@arm.com
40912109SRekai.GonzalezAlberquilla@arm.com      default:
41013610Sgiacomo.gabrielli@arm.com        panic("Unimplemented video mode\n");
41113610Sgiacomo.gabrielli@arm.com    }
41213610Sgiacomo.gabrielli@arm.com
41313610Sgiacomo.gabrielli@arm.com    if (lcdControl.bgr) {
41413610Sgiacomo.gabrielli@arm.com        return PixelConverter(
41513610Sgiacomo.gabrielli@arm.com            bytesPerPixel,
41613610Sgiacomo.gabrielli@arm.com            offsets[2], offsets[1], offsets[0],
41713610Sgiacomo.gabrielli@arm.com            rw, gw, bw,
41813610Sgiacomo.gabrielli@arm.com            LittleEndianByteOrder);
41913429Srekai.gonzalezalberquilla@arm.com    } else {
42013429Srekai.gonzalezalberquilla@arm.com        return PixelConverter(
42113557Sgabeblack@google.com            bytesPerPixel,
42213557Sgabeblack@google.com            offsets[0], offsets[1], offsets[2],
4238733Sgeoffrey.blake@arm.com            rw, gw, bw,
4248733Sgeoffrey.blake@arm.com            LittleEndianByteOrder);
4258733Sgeoffrey.blake@arm.com    }
4262669Sktlim@umich.edu}
42713953Sgiacomo.gabrielli@arm.com
42813953Sgiacomo.gabrielli@arm.comvoid
42913953Sgiacomo.gabrielli@arm.comPl111::updateVideoParams()
43013953Sgiacomo.gabrielli@arm.com{
43113953Sgiacomo.gabrielli@arm.com    if (lcdControl.lcdbpp == bpp24) {
43213953Sgiacomo.gabrielli@arm.com        bytesPerPixel = 4;
43313953Sgiacomo.gabrielli@arm.com    } else if (lcdControl.lcdbpp == bpp16m565) {
43413953Sgiacomo.gabrielli@arm.com        bytesPerPixel = 2;
43513953Sgiacomo.gabrielli@arm.com    }
43613953Sgiacomo.gabrielli@arm.com
43713953Sgiacomo.gabrielli@arm.com    fb.resize(width, height);
43813953Sgiacomo.gabrielli@arm.com    converter = pixelConverter();
43911169Sandreas.hansson@arm.com
44013557Sgabeblack@google.com    // Workaround configuration bugs where multiple display
44113557Sgabeblack@google.com    // controllers are attached to the same VNC server by reattaching
4428733Sgeoffrey.blake@arm.com    // enabled devices. This isn't ideal, but works as long as only
4438733Sgeoffrey.blake@arm.com    // one display controller is active at a time.
4448733Sgeoffrey.blake@arm.com    if (lcdControl.lcdpwr && vnc)
4458733Sgeoffrey.blake@arm.com        vnc->setFrameBuffer(&fb);
4468733Sgeoffrey.blake@arm.com}
4478733Sgeoffrey.blake@arm.com
4488733Sgeoffrey.blake@arm.comvoid
4498733Sgeoffrey.blake@arm.comPl111::startDma()
4508733Sgeoffrey.blake@arm.com{
4512315SN/A    if (dmaPendingNum != 0 || readEvent.scheduled())
45213557Sgabeblack@google.com        return;
45313557Sgabeblack@google.com    readFramebuffer();
4544172Ssaidi@eecs.umich.edu}
4554172Ssaidi@eecs.umich.edu
4564172Ssaidi@eecs.umich.eduvoid
4574172Ssaidi@eecs.umich.eduPl111::readFramebuffer()
45813557Sgabeblack@google.com{
45913557Sgabeblack@google.com    // initialization for dma read from frame buffer to dma buffer
4602315SN/A    uint32_t length = height * width;
4612683Sktlim@umich.edu    if (startAddr != lcdUpbase)
4622315SN/A        startAddr = lcdUpbase;
4632315SN/A
46413557Sgabeblack@google.com    // Updating base address, interrupt if we're supposed to
46513582Sgabeblack@google.com    lcdRis.baseaddr = 1;
4662315SN/A    if (!intEvent.scheduled())
46713557Sgabeblack@google.com        schedule(intEvent, clockEdge());
46813557Sgabeblack@google.com
4694172Ssaidi@eecs.umich.edu    curAddr = 0;
4704172Ssaidi@eecs.umich.edu    startTime = curTick();
4712315SN/A
4722315SN/A    maxAddr = static_cast<Addr>(length * bytesPerPixel);
47313557Sgabeblack@google.com
47413582Sgabeblack@google.com    DPRINTF(PL111, " lcd frame buffer size of %d bytes \n", maxAddr);
4752315SN/A
47613557Sgabeblack@google.com    fillFifo();
47713557Sgabeblack@google.com}
4782315SN/A
4792683Sktlim@umich.eduvoid
4802315SN/APl111::fillFifo()
4812315SN/A{
48213557Sgabeblack@google.com    while ((dmaPendingNum < maxOutstandingDma) && (maxAddr >= curAddr + dmaSize )) {
48313557Sgabeblack@google.com        // concurrent dma reads need different dma done events
4848733Sgeoffrey.blake@arm.com        // due to assertion in scheduling state
48512106SRekai.GonzalezAlberquilla@arm.com        ++dmaPendingNum;
48612106SRekai.GonzalezAlberquilla@arm.com
48712106SRekai.GonzalezAlberquilla@arm.com        assert(!dmaDoneEventFree.empty());
4888733Sgeoffrey.blake@arm.com        DmaDoneEvent *event(dmaDoneEventFree.back());
4898733Sgeoffrey.blake@arm.com        dmaDoneEventFree.pop_back();
49013557Sgabeblack@google.com        assert(!event->scheduled());
49113582Sgabeblack@google.com
4928733Sgeoffrey.blake@arm.com        // We use a uncachable request here because the requests from the CPU
49312106SRekai.GonzalezAlberquilla@arm.com        // will be uncacheable as well. If we have uncacheable and cacheable
49412106SRekai.GonzalezAlberquilla@arm.com        // requests in the memory system for the same address it won't be
49512106SRekai.GonzalezAlberquilla@arm.com        // pleased
4968733Sgeoffrey.blake@arm.com        dmaPort.dmaAction(MemCmd::ReadReq, curAddr + startAddr, dmaSize,
4978888Sgeoffrey.blake@arm.com                          event, curAddr + dmaBuffer,
4988733Sgeoffrey.blake@arm.com                          0, Request::UNCACHEABLE);
4998733Sgeoffrey.blake@arm.com        curAddr += dmaSize;
50013557Sgabeblack@google.com    }
50113557Sgabeblack@google.com}
5028733Sgeoffrey.blake@arm.com
5038733Sgeoffrey.blake@arm.comvoid
5048733Sgeoffrey.blake@arm.comPl111::dmaDone()
5058733Sgeoffrey.blake@arm.com{
5062315SN/A    DPRINTF(PL111, "DMA Done\n");
50713557Sgabeblack@google.com
50813557Sgabeblack@google.com    Tick maxFrameTime = lcdTiming2.cpl * height * pixelClock;
5095358Sgblack@eecs.umich.edu
5105358Sgblack@eecs.umich.edu    --dmaPendingNum;
5115358Sgblack@eecs.umich.edu
5125358Sgblack@eecs.umich.edu    if (maxAddr == curAddr && !dmaPendingNum) {
5135358Sgblack@eecs.umich.edu        if ((curTick() - startTime) > maxFrameTime) {
51410529Smorr@cs.wisc.edu            warn("CLCD controller buffer underrun, took %d ticks when should"
51513557Sgabeblack@google.com                 " have taken %d\n", curTick() - startTime, maxFrameTime);
51611169Sandreas.hansson@arm.com            lcdRis.underflow = 1;
51711169Sandreas.hansson@arm.com            if (!intEvent.scheduled())
51811148Smitch.hayenga@arm.com                schedule(intEvent, clockEdge());
51911169Sandreas.hansson@arm.com        }
52011169Sandreas.hansson@arm.com
52110529Smorr@cs.wisc.edu        assert(!readEvent.scheduled());
52213557Sgabeblack@google.com        fb.copyIn(dmaBuffer, converter);
52313557Sgabeblack@google.com        if (vnc)
5245358Sgblack@eecs.umich.edu            vnc->setDirty();
5255358Sgblack@eecs.umich.edu
5265358Sgblack@eecs.umich.edu        if (enableCapture) {
5275358Sgblack@eecs.umich.edu            DPRINTF(PL111, "-- write out frame buffer into bmp\n");
52813557Sgabeblack@google.com
52913557Sgabeblack@google.com            if (!pic)
5305358Sgblack@eecs.umich.edu                pic = simout.create(csprintf("%s.framebuffer.bmp", sys->name()),
5315358Sgblack@eecs.umich.edu                                    true);
5325358Sgblack@eecs.umich.edu
5335358Sgblack@eecs.umich.edu            assert(pic);
53411169Sandreas.hansson@arm.com            pic->stream()->seekp(0);
53511608Snikos.nikoleris@arm.com            bmp.write(*pic->stream());
53613652Sqtt2@cornell.edu        }
53711608Snikos.nikoleris@arm.com
53811608Snikos.nikoleris@arm.com        // schedule the next read based on when the last frame started
5398733Sgeoffrey.blake@arm.com        // and the desired fps (i.e. maxFrameTime), we turn the
54013652Sqtt2@cornell.edu        // argument into a relative number of cycles in the future
54113652Sqtt2@cornell.edu        if (lcdControl.lcden)
54213652Sqtt2@cornell.edu            schedule(readEvent, clockEdge(ticksToCycles(startTime -
54313652Sqtt2@cornell.edu                                                        curTick() +
54413652Sqtt2@cornell.edu                                                        maxFrameTime)));
54513652Sqtt2@cornell.edu    }
54613557Sgabeblack@google.com
54713557Sgabeblack@google.com    if (dmaPendingNum > (maxOutstandingDma - waterMark))
54810319SAndreas.Sandberg@ARM.com        return;
54910319SAndreas.Sandberg@ARM.com
55010319SAndreas.Sandberg@ARM.com    if (!fillFifoEvent.scheduled())
55113557Sgabeblack@google.com        schedule(fillFifoEvent, clockEdge());
5528733Sgeoffrey.blake@arm.com}
5538733Sgeoffrey.blake@arm.com
55411168Sandreas.hansson@arm.comvoid
5552315SN/APl111::serialize(CheckpointOut &cp) const
5562332SN/A{
55711877Sbrandon.potter@amd.com    DPRINTF(PL111, "Serializing ARM PL111\n");
5582315SN/A
55913557Sgabeblack@google.com    uint32_t lcdTiming0_serial = lcdTiming0;
56013557Sgabeblack@google.com    SERIALIZE_SCALAR(lcdTiming0_serial);
5612315SN/A
5622315SN/A    uint32_t lcdTiming1_serial = lcdTiming1;
5632732Sktlim@umich.edu    SERIALIZE_SCALAR(lcdTiming1_serial);
5642315SN/A
5652732Sktlim@umich.edu    uint32_t lcdTiming2_serial = lcdTiming2;
56612749Sgiacomo.travaglini@arm.com    SERIALIZE_SCALAR(lcdTiming2_serial);
5678733Sgeoffrey.blake@arm.com
5682315SN/A    uint32_t lcdTiming3_serial = lcdTiming3;
5692732Sktlim@umich.edu    SERIALIZE_SCALAR(lcdTiming3_serial);
5702732Sktlim@umich.edu
57111169Sandreas.hansson@arm.com    SERIALIZE_SCALAR(lcdUpbase);
5722683Sktlim@umich.edu    SERIALIZE_SCALAR(lcdLpbase);
5732315SN/A
57412107SRekai.GonzalezAlberquilla@arm.com    uint32_t lcdControl_serial = lcdControl;
57512748Sgiacomo.travaglini@arm.com    SERIALIZE_SCALAR(lcdControl_serial);
5762679Sktlim@umich.edu
5772315SN/A    uint8_t lcdImsc_serial = lcdImsc;
5782315SN/A    SERIALIZE_SCALAR(lcdImsc_serial);
5792315SN/A
5808733Sgeoffrey.blake@arm.com    uint8_t lcdRis_serial = lcdRis;
5812315SN/A    SERIALIZE_SCALAR(lcdRis_serial);
5822354SN/A
5832732Sktlim@umich.edu    uint8_t lcdMis_serial = lcdMis;
5842315SN/A    SERIALIZE_SCALAR(lcdMis_serial);
5852315SN/A
5862315SN/A    SERIALIZE_ARRAY(lcdPalette, LcdPaletteSize);
5872315SN/A    SERIALIZE_ARRAY(cursorImage, CrsrImageSize);
5882350SN/A
5892350SN/A    SERIALIZE_SCALAR(clcdCrsrCtrl);
5902350SN/A    SERIALIZE_SCALAR(clcdCrsrConfig);
5912350SN/A    SERIALIZE_SCALAR(clcdCrsrPalette0);
5922350SN/A    SERIALIZE_SCALAR(clcdCrsrPalette1);
5932350SN/A    SERIALIZE_SCALAR(clcdCrsrXY);
5948733Sgeoffrey.blake@arm.com    SERIALIZE_SCALAR(clcdCrsrClip);
5952315SN/A
5962315SN/A    uint8_t clcdCrsrImsc_serial = clcdCrsrImsc;
5978733Sgeoffrey.blake@arm.com    SERIALIZE_SCALAR(clcdCrsrImsc_serial);
5988733Sgeoffrey.blake@arm.com
5998733Sgeoffrey.blake@arm.com    uint8_t clcdCrsrIcr_serial = clcdCrsrIcr;
6002315SN/A    SERIALIZE_SCALAR(clcdCrsrIcr_serial);
6012315SN/A
6029023Sgblack@eecs.umich.edu    uint8_t clcdCrsrRis_serial = clcdCrsrRis;
6032315SN/A    SERIALIZE_SCALAR(clcdCrsrRis_serial);
6042315SN/A
6052840Sktlim@umich.edu    uint8_t clcdCrsrMis_serial = clcdCrsrMis;
6062315SN/A    SERIALIZE_SCALAR(clcdCrsrMis_serial);
6072315SN/A
60810379Sandreas.hansson@arm.com    SERIALIZE_SCALAR(height);
6098733Sgeoffrey.blake@arm.com    SERIALIZE_SCALAR(width);
61013429Srekai.gonzalezalberquilla@arm.com    SERIALIZE_SCALAR(bytesPerPixel);
6112315SN/A
61213429Srekai.gonzalezalberquilla@arm.com    SERIALIZE_ARRAY(dmaBuffer, buffer_size);
61313429Srekai.gonzalezalberquilla@arm.com    SERIALIZE_SCALAR(startTime);
6142315SN/A    SERIALIZE_SCALAR(startAddr);
6152315SN/A    SERIALIZE_SCALAR(maxAddr);
61613429Srekai.gonzalezalberquilla@arm.com    SERIALIZE_SCALAR(curAddr);
61712107SRekai.GonzalezAlberquilla@arm.com    SERIALIZE_SCALAR(waterMark);
6188733Sgeoffrey.blake@arm.com    SERIALIZE_SCALAR(dmaPendingNum);
6192732Sktlim@umich.edu
6202732Sktlim@umich.edu    Tick int_event_time = 0;
62113429Srekai.gonzalezalberquilla@arm.com    Tick read_event_time = 0;
6222732Sktlim@umich.edu    Tick fill_fifo_event_time = 0;
6232360SN/A
6242732Sktlim@umich.edu    if (readEvent.scheduled())
6252360SN/A        read_event_time = readEvent.when();
6262354SN/A    if (fillFifoEvent.scheduled())
6272360SN/A        fill_fifo_event_time = fillFifoEvent.when();
6282732Sktlim@umich.edu    if (intEvent.scheduled())
6292732Sktlim@umich.edu        int_event_time = intEvent.when();
63013429Srekai.gonzalezalberquilla@arm.com
6312732Sktlim@umich.edu    SERIALIZE_SCALAR(read_event_time);
6322354SN/A    SERIALIZE_SCALAR(fill_fifo_event_time);
6332354SN/A    SERIALIZE_SCALAR(int_event_time);
6342354SN/A
6352354SN/A    vector<Tick> dma_done_event_tick;
6362315SN/A    dma_done_event_tick.resize(maxOutstandingDma);
6372315SN/A    for (int x = 0; x < maxOutstandingDma; x++) {
6382315SN/A        dma_done_event_tick[x] = dmaDoneEventAll[x].scheduled() ?
6392315SN/A            dmaDoneEventAll[x].when() : 0;
6402315SN/A    }
6412315SN/A    SERIALIZE_CONTAINER(dma_done_event_tick);
642}
643
644void
645Pl111::unserialize(CheckpointIn &cp)
646{
647    DPRINTF(PL111, "Unserializing ARM PL111\n");
648
649    uint32_t lcdTiming0_serial;
650    UNSERIALIZE_SCALAR(lcdTiming0_serial);
651    lcdTiming0 = lcdTiming0_serial;
652
653    uint32_t lcdTiming1_serial;
654    UNSERIALIZE_SCALAR(lcdTiming1_serial);
655    lcdTiming1 = lcdTiming1_serial;
656
657    uint32_t lcdTiming2_serial;
658    UNSERIALIZE_SCALAR(lcdTiming2_serial);
659    lcdTiming2 = lcdTiming2_serial;
660
661    uint32_t lcdTiming3_serial;
662    UNSERIALIZE_SCALAR(lcdTiming3_serial);
663    lcdTiming3 = lcdTiming3_serial;
664
665    UNSERIALIZE_SCALAR(lcdUpbase);
666    UNSERIALIZE_SCALAR(lcdLpbase);
667
668    uint32_t lcdControl_serial;
669    UNSERIALIZE_SCALAR(lcdControl_serial);
670    lcdControl = lcdControl_serial;
671
672    uint8_t lcdImsc_serial;
673    UNSERIALIZE_SCALAR(lcdImsc_serial);
674    lcdImsc = lcdImsc_serial;
675
676    uint8_t lcdRis_serial;
677    UNSERIALIZE_SCALAR(lcdRis_serial);
678    lcdRis = lcdRis_serial;
679
680    uint8_t lcdMis_serial;
681    UNSERIALIZE_SCALAR(lcdMis_serial);
682    lcdMis = lcdMis_serial;
683
684    UNSERIALIZE_ARRAY(lcdPalette, LcdPaletteSize);
685    UNSERIALIZE_ARRAY(cursorImage, CrsrImageSize);
686
687    UNSERIALIZE_SCALAR(clcdCrsrCtrl);
688    UNSERIALIZE_SCALAR(clcdCrsrConfig);
689    UNSERIALIZE_SCALAR(clcdCrsrPalette0);
690    UNSERIALIZE_SCALAR(clcdCrsrPalette1);
691    UNSERIALIZE_SCALAR(clcdCrsrXY);
692    UNSERIALIZE_SCALAR(clcdCrsrClip);
693
694    uint8_t clcdCrsrImsc_serial;
695    UNSERIALIZE_SCALAR(clcdCrsrImsc_serial);
696    clcdCrsrImsc = clcdCrsrImsc_serial;
697
698    uint8_t clcdCrsrIcr_serial;
699    UNSERIALIZE_SCALAR(clcdCrsrIcr_serial);
700    clcdCrsrIcr = clcdCrsrIcr_serial;
701
702    uint8_t clcdCrsrRis_serial;
703    UNSERIALIZE_SCALAR(clcdCrsrRis_serial);
704    clcdCrsrRis = clcdCrsrRis_serial;
705
706    uint8_t clcdCrsrMis_serial;
707    UNSERIALIZE_SCALAR(clcdCrsrMis_serial);
708    clcdCrsrMis = clcdCrsrMis_serial;
709
710    UNSERIALIZE_SCALAR(height);
711    UNSERIALIZE_SCALAR(width);
712    UNSERIALIZE_SCALAR(bytesPerPixel);
713
714    UNSERIALIZE_ARRAY(dmaBuffer, buffer_size);
715    UNSERIALIZE_SCALAR(startTime);
716    UNSERIALIZE_SCALAR(startAddr);
717    UNSERIALIZE_SCALAR(maxAddr);
718    UNSERIALIZE_SCALAR(curAddr);
719    UNSERIALIZE_SCALAR(waterMark);
720    UNSERIALIZE_SCALAR(dmaPendingNum);
721
722    Tick int_event_time = 0;
723    Tick read_event_time = 0;
724    Tick fill_fifo_event_time = 0;
725
726    UNSERIALIZE_SCALAR(read_event_time);
727    UNSERIALIZE_SCALAR(fill_fifo_event_time);
728    UNSERIALIZE_SCALAR(int_event_time);
729
730    if (int_event_time)
731        schedule(intEvent, int_event_time);
732    if (read_event_time)
733        schedule(readEvent, read_event_time);
734    if (fill_fifo_event_time)
735        schedule(fillFifoEvent, fill_fifo_event_time);
736
737    vector<Tick> dma_done_event_tick;
738    dma_done_event_tick.resize(maxOutstandingDma);
739    UNSERIALIZE_CONTAINER(dma_done_event_tick);
740    dmaDoneEventFree.clear();
741    for (int x = 0; x < maxOutstandingDma; x++) {
742        if (dma_done_event_tick[x])
743            schedule(dmaDoneEventAll[x], dma_done_event_tick[x]);
744        else
745            dmaDoneEventFree.push_back(&dmaDoneEventAll[x]);
746    }
747    assert(maxOutstandingDma - dmaDoneEventFree.size() == dmaPendingNum);
748
749    if (lcdControl.lcdpwr) {
750        updateVideoParams();
751        fb.copyIn(dmaBuffer, converter);
752        if (vnc)
753            vnc->setDirty();
754    }
755}
756
757void
758Pl111::generateInterrupt()
759{
760    DPRINTF(PL111, "Generate Interrupt: lcdImsc=0x%x lcdRis=0x%x lcdMis=0x%x\n",
761            (uint32_t)lcdImsc, (uint32_t)lcdRis, (uint32_t)lcdMis);
762    lcdMis = lcdImsc & lcdRis;
763
764    if (lcdMis.underflow || lcdMis.baseaddr || lcdMis.vcomp || lcdMis.ahbmaster) {
765        gic->sendInt(intNum);
766        DPRINTF(PL111, " -- Generated\n");
767    }
768}
769
770AddrRangeList
771Pl111::getAddrRanges() const
772{
773    AddrRangeList ranges;
774    ranges.push_back(RangeSize(pioAddr, pioSize));
775    return ranges;
776}
777
778Pl111 *
779Pl111Params::create()
780{
781    return new Pl111(this);
782}
783
784
785