changeset 1a9ecb4fe05e in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=1a9ecb4fe05e
description:
merged with 62e1504b9c64
diffstat:
src/dev/arm/RealView.py | 18 +-
src/dev/arm/hdlcd.cc | 1159 +++++++++++++-----------------
src/dev/arm/hdlcd.hh | 467 ++++-------
util/cpt_upgraders/arm-hdlcd-upgrade.py | 109 ++
4 files changed, 786 insertions(+), 967 deletions(-)
diffs (truncated from 2009 to 300 lines):
diff -r 8049ffff6d68 -r 1a9ecb4fe05e src/dev/arm/RealView.py
--- a/src/dev/arm/RealView.py Sat Sep 12 16:16:17 2015 -0500
+++ b/src/dev/arm/RealView.py Sat Sep 12 16:23:47 2015 -0500
@@ -54,6 +54,7 @@
from SimpleMemory import SimpleMemory
from Gic import *
from EnergyCtrl import EnergyCtrl
+from ClockDomain import SrcClockDomain
class AmbaPioDevice(BasicPioDevice):
type = 'AmbaPioDevice'
@@ -218,23 +219,23 @@
amba_id = 0x00141111
enable_capture = Param.Bool(True, "capture frame to
system.framebuffer.bmp")
-
class HDLcd(AmbaDmaDevice):
type = 'HDLcd'
cxx_header = "dev/arm/hdlcd.hh"
- # For reference, 1024x768MR-16@60 ~= 56 MHz
- # 1920x1080MR-16@60 ~= 137 MHz
- # 3840x2160MR-16@60 ~= 533 MHz
- # Match against the resolution selected in the Linux DTS/DTB file.
- pixel_clock = Param.Clock('137MHz', "Clock frequency of the pixel clock "
- "(i.e. PXLREFCLK / OSCCLK 5")
vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
"display")
amba_id = 0x00141000
workaround_swap_rb = Param.Bool(True, "Workaround incorrect color "
"selector order in some kernels")
+ workaround_dma_line_count = Param.Bool(True, "Workaround incorrect "
+ "DMA line count (off by 1)")
enable_capture = Param.Bool(True, "capture frame to
system.framebuffer.bmp")
+ pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
+
+ pxl_clk = Param.ClockDomain("Pixel clock source")
+ pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
+
class RealView(Platform):
type = 'RealView'
cxx_header = "dev/arm/realview.hh"
@@ -518,7 +519,8 @@
timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000,
clock0='1MHz', clock1='1MHz')
timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000,
clock0='1MHz', clock1='1MHz')
clcd = Pl111(pio_addr=0x1c1f0000, int_num=46)
- hdlcd = HDLcd(pio_addr=0x2b000000, int_num=117)
+ hdlcd = HDLcd(pxl_clk=realview_io.osc_pxl,
+ pio_addr=0x2b000000, int_num=117)
kmi0 = Pl050(pio_addr=0x1c060000, int_num=44)
kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True)
vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
diff -r 8049ffff6d68 -r 1a9ecb4fe05e src/dev/arm/hdlcd.cc
--- a/src/dev/arm/hdlcd.cc Sat Sep 12 16:16:17 2015 -0500
+++ b/src/dev/arm/hdlcd.cc Sat Sep 12 16:23:47 2015 -0500
@@ -35,6 +35,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Chris Emmons
+ * Andreas Sandberg
*/
#include "dev/arm/hdlcd.hh"
@@ -42,145 +43,187 @@
#include "base/vnc/vncinput.hh"
#include "base/output.hh"
#include "base/trace.hh"
+#include "debug/Checkpoint.hh"
#include "debug/HDLcd.hh"
-#include "debug/Uart.hh"
#include "dev/arm/amba_device.hh"
#include "dev/arm/base_gic.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
+#include "params/HDLcd.hh"
#include "sim/system.hh"
using std::vector;
// initialize hdlcd registers
-HDLcd::HDLcd(const Params *p)
- : AmbaDmaDevice(p), version(VERSION_RESETV),
- int_rawstat(0), int_clear(0), int_mask(0), int_status(0),
+HDLcd::HDLcd(const HDLcdParams *p)
+ : AmbaDmaDevice(p, 0xFFFF),
+ // Parameters
+ vnc(p->vnc),
+ workaroundSwapRB(p->workaround_swap_rb),
+ workaroundDmaLineCount(p->workaround_dma_line_count),
+ addrRanges{RangeSize(pioAddr, pioSize)},
+ enableCapture(p->enable_capture),
+ pixelBufferSize(p->pixel_buffer_size),
+
+ // Registers
+ version(VERSION_RESETV),
+ int_rawstat(0), int_mask(0),
+
fb_base(0), fb_line_length(0), fb_line_count(0), fb_line_pitch(0),
bus_options(BUS_OPTIONS_RESETV),
+
v_sync(0), v_back_porch(0), v_data(0), v_front_porch(0),
h_sync(0), h_back_porch(0), h_data(0), h_front_porch(0),
- polarities(0), command(0), pixel_format(0),
+ polarities(0),
+
+ command(0),
+
+ pixel_format(0),
red_select(0), green_select(0), blue_select(0),
- pixelClock(p->pixel_clock),
- fb(0, 0), vnc(p->vnc), bmp(&fb), pic(NULL),
- frameReadStartTime(0),
- dmaStartAddr(0), dmaCurAddr(0), dmaMaxAddr(0), dmaPendingNum(0),
- frameUnderrun(false), pixelBufferSize(0),
- pixelIndex(0), doUpdateParams(false), frameUnderway(false),
- dmaBytesInFlight(0),
- startFrameEvent(this), endFrameEvent(this), renderPixelEvent(this),
- fillPixelBufferEvent(this), intEvent(this),
- dmaDoneEventAll(MAX_OUTSTANDING_DMA_REQ_CAPACITY, this),
- dmaDoneEventFree(MAX_OUTSTANDING_DMA_REQ_CAPACITY),
- enableCapture(p->enable_capture),
- workaround_swap_rb(p->workaround_swap_rb)
+
+ // Other
+ bmp(&pixelPump.fb), pic(NULL), conv(PixelConverter::rgba8888_le),
+ pixelPump(*this, *p->pxl_clk, p->pixel_chunk)
{
- pioSize = 0xFFFF;
-
- for (int i = 0; i < MAX_OUTSTANDING_DMA_REQ_CAPACITY; ++i)
- dmaDoneEventFree[i] = &dmaDoneEventAll[i];
-
if (vnc)
- vnc->setFrameBuffer(&fb);
+ vnc->setFrameBuffer(&pixelPump.fb);
}
HDLcd::~HDLcd()
{
}
+void
+HDLcd::regStats()
+{
+ using namespace Stats;
+
+ stats.underruns
+ .name(name() + ".underruns")
+ .desc("number of buffer underruns")
+ .flags(nozero)
+ ;
+}
+
+void
+HDLcd::serialize(CheckpointOut &cp) const
+{
+ DPRINTF(Checkpoint, "Serializing ARM HDLCD\n");
+
+ SERIALIZE_SCALAR(int_rawstat);
+ SERIALIZE_SCALAR(int_mask);
+
+ SERIALIZE_SCALAR(fb_base);
+ SERIALIZE_SCALAR(fb_line_length);
+ SERIALIZE_SCALAR(fb_line_count);
+ SERIALIZE_SCALAR(fb_line_pitch);
+ SERIALIZE_SCALAR(bus_options);
+
+ SERIALIZE_SCALAR(v_sync);
+ SERIALIZE_SCALAR(v_back_porch);
+ SERIALIZE_SCALAR(v_data);
+ SERIALIZE_SCALAR(v_front_porch);
+
+ SERIALIZE_SCALAR(h_sync);
+ SERIALIZE_SCALAR(h_back_porch);
+ SERIALIZE_SCALAR(h_data);
+ SERIALIZE_SCALAR(h_front_porch);
+
+ SERIALIZE_SCALAR(polarities);
+
+ SERIALIZE_SCALAR(command);
+ SERIALIZE_SCALAR(pixel_format);
+ SERIALIZE_SCALAR(red_select);
+ SERIALIZE_SCALAR(green_select);
+ SERIALIZE_SCALAR(blue_select);
+
+ SERIALIZE_OBJ(pixelPump);
+ if (enabled())
+ dmaEngine->serializeSection(cp, "dmaEngine");
+}
+
+void
+HDLcd::unserialize(CheckpointIn &cp)
+{
+ DPRINTF(Checkpoint, "Unserializing ARM HDLCD\n");
+
+ UNSERIALIZE_SCALAR(int_rawstat);
+ UNSERIALIZE_SCALAR(int_mask);
+
+ UNSERIALIZE_SCALAR(fb_base);
+ UNSERIALIZE_SCALAR(fb_line_length);
+ UNSERIALIZE_SCALAR(fb_line_count);
+ UNSERIALIZE_SCALAR(fb_line_pitch);
+ UNSERIALIZE_SCALAR(bus_options);
+
+ UNSERIALIZE_SCALAR(v_sync);
+ UNSERIALIZE_SCALAR(v_back_porch);
+ UNSERIALIZE_SCALAR(v_data);
+ UNSERIALIZE_SCALAR(v_front_porch);
+
+ UNSERIALIZE_SCALAR(h_sync);
+ UNSERIALIZE_SCALAR(h_back_porch);
+ UNSERIALIZE_SCALAR(h_data);
+ UNSERIALIZE_SCALAR(h_front_porch);
+
+ UNSERIALIZE_SCALAR(polarities);
+
+ UNSERIALIZE_SCALAR(command);
+ UNSERIALIZE_SCALAR(pixel_format);
+ UNSERIALIZE_SCALAR(red_select);
+ UNSERIALIZE_SCALAR(green_select);
+ UNSERIALIZE_SCALAR(blue_select);
+
+ {
+ // Try to unserialize the pixel pump. It might not exist if
+ // we're unserializing an old checkpoint.
+ ScopedCheckpointSection sec(cp, "pixelPump");
+ if (cp.sectionExists(Serializable::currentSection()))
+ pixelPump.unserialize(cp);
+ }
+
+ if (enabled()) {
+ // Create the DMA engine and read its state from the
+ // checkpoint. We don't need to worry about the pixel pump as
+ // it is a proper SimObject.
+ createDmaEngine();
+ dmaEngine->unserializeSection(cp, "dmaEngine");
+
+ conv = pixelConverter();
+ }
+}
+
+void
+HDLcd::drainResume()
+{
+ AmbaDmaDevice::drainResume();
+
+ // We restored from an old checkpoint without a pixel pump, start
+ // an new refresh. This typically happens when restoring from old
+ // checkpoints.
+ if (enabled() && !pixelPump.active())
+ pixelPump.start(displayTimings());
+
+ // We restored from a checkpoint and need to update the VNC server
+ if (pixelPump.active() && vnc)
+ vnc->setDirty();
+}
+
// read registers and frame buffer
Tick
HDLcd::read(PacketPtr pkt)
{
- uint32_t data = 0;
- const Addr daddr = pkt->getAddr() - pioAddr;
+ assert(pkt->getAddr() >= pioAddr &&
+ pkt->getAddr() < pioAddr + pioSize);
- DPRINTF(HDLcd, "read register BASE+0x%04x size=%d\n", daddr,
- pkt->getSize());
+ const Addr daddr(pkt->getAddr() - pioAddr);
+ panic_if(pkt->getSize() != 4,
+ "Unhandled read size (address: 0x.4x, size: %u)",
+ daddr, pkt->getSize());
- assert(pkt->getAddr() >= pioAddr &&
- pkt->getAddr() < pioAddr + pioSize &&
- pkt->getSize() == 4);
-
- switch (daddr) {
- case Version:
- data = version;
- break;
- case Int_RawStat:
- data = int_rawstat;
- break;
- case Int_Clear:
- panic("HDLCD INT_CLEAR register is Write-Only\n");
- break;
- case Int_Mask:
- data = int_mask;
- break;
- case Int_Status:
- data = int_status;
- break;
- case Fb_Base:
- data = fb_base;
- break;
- case Fb_Line_Length:
- data = fb_line_length;
- break;
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev