hdlcd.hh (10905:a6ca6831e775) hdlcd.hh (11090:f37a6b82f98f)
1/*
2 * Copyright (c) 2010-2013, 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 21 unchanged lines hidden (view full) ---

30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Chris Emmons
1/*
2 * Copyright (c) 2010-2013, 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 21 unchanged lines hidden (view full) ---

30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Chris Emmons
38 * Andreas Sandberg
38 */
39
40
41/** @file
42 * Implementiation of the ARM HDLcd controller.
43 *
44 * This implementation aims to have sufficient detail such that underrun
45 * conditions are reasonable / behave similar to reality. There are two

--- 10 unchanged lines hidden (view full) ---

56 * condition is different than the real hardware; while the user will see
57 * artifacts (previous frame mixed with current frame), it is not the same
58 * behavior as real hardware which repeats the last pixel value for the rest
59 * of the current frame. This compromise was made to save on memory and
60 * complexity and assumes that it is not important to accurately model the
61 * content of an underrun frame.
62 *
63 * KNOWN ISSUES
39 */
40
41
42/** @file
43 * Implementiation of the ARM HDLcd controller.
44 *
45 * This implementation aims to have sufficient detail such that underrun
46 * conditions are reasonable / behave similar to reality. There are two

--- 10 unchanged lines hidden (view full) ---

57 * condition is different than the real hardware; while the user will see
58 * artifacts (previous frame mixed with current frame), it is not the same
59 * behavior as real hardware which repeats the last pixel value for the rest
60 * of the current frame. This compromise was made to save on memory and
61 * complexity and assumes that it is not important to accurately model the
62 * content of an underrun frame.
63 *
64 * KNOWN ISSUES
64 * 1. The default kernel driver used in testing sets the line count to one
65 * less than the expected 768. However, it also sets the v_count to 767.
66 * The controller specifies that 1 should be added to v_count but does not
67 * specify adding 1 to the line count. The driver is probably wrong.
68 * However, to sync these two numbers up, this model uses fb_line_count and
69 * fb_line_length rather than using v_data or h_data values to determine the
70 * width and height of the frame; those values are ignored.
71 * 2. The HDLcd is implemented here as an AmbaDmaDevice, but it doesn't have
72 * an AMBA ID as far as I know. That is the only bit of the AmbaDmaDevice
73 * interface that is irrelevant to it, so a fake AMBA ID is used for now.
74 * I didn't think inserting an extra layer of hierachy between AmbaDmaDevice
75 * and DmaDevice would be helpful to anyone else, but that may be the right
76 * answer.
77 * 3. The internal buffer size is either 1 or 2 KB depending on which
78 * specification is referenced for the different Versatile Express tiles.
79 * This implementation uses the larger 2 KB buffer by default.
65 * <ul>
66 * <li>The HDLcd is implemented here as an AmbaDmaDevice, but it
67 * doesn't have an AMBA ID as far as I know. That is the only
68 * bit of the AmbaDmaDevice interface that is irrelevant to it,
69 * so a fake AMBA ID is used for now. I didn't think inserting
70 * an extra layer of hierachy between AmbaDmaDevice and
71 * DmaDevice would be helpful to anyone else, but that may be
72 * the right answer.
73 * </ul>
80 */
81
82#ifndef __DEV_ARM_HDLCD_HH__
83#define __DEV_ARM_HDLCD_HH__
84
85#include <fstream>
86#include <memory>
87
88#include "base/bitmap.hh"
89#include "base/framebuffer.hh"
90#include "dev/arm/amba_device.hh"
74 */
75
76#ifndef __DEV_ARM_HDLCD_HH__
77#define __DEV_ARM_HDLCD_HH__
78
79#include <fstream>
80#include <memory>
81
82#include "base/bitmap.hh"
83#include "base/framebuffer.hh"
84#include "dev/arm/amba_device.hh"
91#include "params/HDLcd.hh"
85#include "dev/pixelpump.hh"
92#include "sim/serialize.hh"
93
94class VncInput;
86#include "sim/serialize.hh"
87
88class VncInput;
89struct HDLcdParams;
90class HDLcdPixelPump;
95
96class HDLcd: public AmbaDmaDevice
97{
91
92class HDLcd: public AmbaDmaDevice
93{
98 protected:
99 /** fake AMBA ID -- unused */
100 static const uint64_t AMBA_ID = ULL(0xb105f00d00141000);
94 public:
95 HDLcd(const HDLcdParams *p);
96 ~HDLcd();
101
97
98 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
99 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
100
101 void drainResume() M5_ATTR_OVERRIDE;
102
103 public: // IO device interface
104 Tick read(PacketPtr pkt) M5_ATTR_OVERRIDE;
105 Tick write(PacketPtr pkt) M5_ATTR_OVERRIDE;
106
107 AddrRangeList getAddrRanges() const M5_ATTR_OVERRIDE { return addrRanges; }
108
109 protected: // Parameters
110 VncInput *vnc;
111 const bool workaroundSwapRB;
112 const bool workaroundDmaLineCount;
113 const AddrRangeList addrRanges;
114 const bool enableCapture;
115 const Addr pixelBufferSize;
116
117 protected: // Register handling
102 /** ARM HDLcd register offsets */
103 enum RegisterOffset {
104 Version = 0x0000,
105 Int_RawStat = 0x0010,
106 Int_Clear = 0x0014,
107 Int_Mask = 0x0018,
108 Int_Status = 0x001C,
109 Fb_Base = 0x0100,

--- 9 unchanged lines hidden (view full) ---

119 H_Back_Porch = 0x0214,
120 H_Data = 0x0218,
121 H_Front_Porch = 0x021C,
122 Polarities = 0x0220,
123 Command = 0x0230,
124 Pixel_Format = 0x0240,
125 Red_Select = 0x0244,
126 Green_Select = 0x0248,
118 /** ARM HDLcd register offsets */
119 enum RegisterOffset {
120 Version = 0x0000,
121 Int_RawStat = 0x0010,
122 Int_Clear = 0x0014,
123 Int_Mask = 0x0018,
124 Int_Status = 0x001C,
125 Fb_Base = 0x0100,

--- 9 unchanged lines hidden (view full) ---

135 H_Back_Porch = 0x0214,
136 H_Data = 0x0218,
137 H_Front_Porch = 0x021C,
138 Polarities = 0x0220,
139 Command = 0x0230,
140 Pixel_Format = 0x0240,
141 Red_Select = 0x0244,
142 Green_Select = 0x0248,
127 Blue_Select = 0x024C };
143 Blue_Select = 0x024C,
144 };
128
129 /** Reset value for Bus_Options register */
145
146 /** Reset value for Bus_Options register */
130 static const size_t BUS_OPTIONS_RESETV = 0x408;
147 static constexpr size_t BUS_OPTIONS_RESETV = 0x408;
131
132 /** Reset value for Version register */
148
149 /** Reset value for Version register */
133 static const size_t VERSION_RESETV = 0x1CDC0000;
150 static constexpr size_t VERSION_RESETV = 0x1CDC0000;
134
151
135 /** max number of outstanding DMA requests possible */
136 static const size_t MAX_OUTSTANDING_DMA_REQ_CAPACITY = 16;
152 /** AXI port width in bytes */
153 static constexpr size_t AXI_PORT_WIDTH = 8;
137
138 /** max number of beats delivered in one dma burst */
154
155 /** max number of beats delivered in one dma burst */
139 static const size_t MAX_BURST_LEN = 16;
156 static constexpr size_t MAX_BURST_LEN = 16;
140
157
141 /** size of internal buffer in bytes */
142 static const size_t PIXEL_BUFFER_CAPACITY = 2048;
158 /** Maximum number of bytes per pixel */
159 static constexpr size_t MAX_PIXEL_SIZE = 4;
143
160
144 /** AXI port width in bytes */
145 static const size_t AXI_PORT_WIDTH = 8;
146
147 static const size_t MAX_BURST_SIZE = MAX_BURST_LEN * AXI_PORT_WIDTH;
148
149 /**
150 * @name RegisterFieldLayouts
151 * Bit layout declarations for multi-field registers.
152 */
153 /**@{*/
154 BitUnion32(VersionReg)
155 Bitfield<7,0> version_minor;
156 Bitfield<15,8> version_major;
157 Bitfield<31,16> product_id;
158 EndBitUnion(VersionReg)
159
161 /**
162 * @name RegisterFieldLayouts
163 * Bit layout declarations for multi-field registers.
164 */
165 /**@{*/
166 BitUnion32(VersionReg)
167 Bitfield<7,0> version_minor;
168 Bitfield<15,8> version_major;
169 Bitfield<31,16> product_id;
170 EndBitUnion(VersionReg)
171
160 BitUnion32(InterruptReg)
161 Bitfield<0> dma_end;
162 Bitfield<1> bus_error;
163 Bitfield<2> vsync;
164 Bitfield<3> underrun;
165 EndBitUnion(InterruptReg)
172 static constexpr uint32_t INT_DMA_END = (1UL << 0);
173 static constexpr uint32_t INT_BUS_ERROR = (1UL << 1);
174 static constexpr uint32_t INT_VSYNC = (1UL << 2);
175 static constexpr uint32_t INT_UNDERRUN = (1UL << 3);
166
167 BitUnion32(FbLineCountReg)
168 Bitfield<11,0> fb_line_count;
169 Bitfield<31,12> reserved_31_12;
170 EndBitUnion(FbLineCountReg)
171
172 BitUnion32(BusOptsReg)
173 Bitfield<4,0> burst_len;

--- 38 unchanged lines hidden (view full) ---

212 EndBitUnion(ColorSelectReg)
213 /**@}*/
214
215 /**
216 * @name HDLCDRegisters
217 * HDLCD register contents.
218 */
219 /**@{*/
176
177 BitUnion32(FbLineCountReg)
178 Bitfield<11,0> fb_line_count;
179 Bitfield<31,12> reserved_31_12;
180 EndBitUnion(FbLineCountReg)
181
182 BitUnion32(BusOptsReg)
183 Bitfield<4,0> burst_len;

--- 38 unchanged lines hidden (view full) ---

222 EndBitUnion(ColorSelectReg)
223 /**@}*/
224
225 /**
226 * @name HDLCDRegisters
227 * HDLCD register contents.
228 */
229 /**@{*/
220 VersionReg version; /**< Version register */
221 InterruptReg int_rawstat; /**< Interrupt raw status register */
222 InterruptReg int_clear; /**< Interrupt clear register */
223 InterruptReg int_mask; /**< Interrupt mask register */
224 InterruptReg int_status; /**< Interrupt status register */
230 const VersionReg version; /**< Version register */
231 uint32_t int_rawstat; /**< Interrupt raw status register */
232 uint32_t int_mask; /**< Interrupt mask register */
225 uint32_t fb_base; /**< Frame buffer base address register */
226 uint32_t fb_line_length; /**< Frame buffer Line length register */
227 FbLineCountReg fb_line_count; /**< Frame buffer Line count register */
233 uint32_t fb_base; /**< Frame buffer base address register */
234 uint32_t fb_line_length; /**< Frame buffer Line length register */
235 FbLineCountReg fb_line_count; /**< Frame buffer Line count register */
228 uint32_t fb_line_pitch; /**< Frame buffer Line pitch register */
236 int32_t fb_line_pitch; /**< Frame buffer Line pitch register */
229 BusOptsReg bus_options; /**< Bus options register */
230 TimingReg v_sync; /**< Vertical sync width register */
231 TimingReg v_back_porch; /**< Vertical back porch width register */
232 TimingReg v_data; /**< Vertical data width register */
233 TimingReg v_front_porch; /**< Vertical front porch width register */
234 TimingReg h_sync; /**< Horizontal sync width register */
235 TimingReg h_back_porch; /**< Horizontal back porch width register */
236 TimingReg h_data; /**< Horizontal data width register */
237 TimingReg h_front_porch; /**< Horizontal front porch width reg */
238 PolaritiesReg polarities; /**< Polarities register */
239 CommandReg command; /**< Command register */
240 PixelFormatReg pixel_format; /**< Pixel format register */
241 ColorSelectReg red_select; /**< Red color select register */
242 ColorSelectReg green_select; /**< Green color select register */
243 ColorSelectReg blue_select; /**< Blue color select register */
244 /** @} */
245
237 BusOptsReg bus_options; /**< Bus options register */
238 TimingReg v_sync; /**< Vertical sync width register */
239 TimingReg v_back_porch; /**< Vertical back porch width register */
240 TimingReg v_data; /**< Vertical data width register */
241 TimingReg v_front_porch; /**< Vertical front porch width register */
242 TimingReg h_sync; /**< Horizontal sync width register */
243 TimingReg h_back_porch; /**< Horizontal back porch width register */
244 TimingReg h_data; /**< Horizontal data width register */
245 TimingReg h_front_porch; /**< Horizontal front porch width reg */
246 PolaritiesReg polarities; /**< Polarities register */
247 CommandReg command; /**< Command register */
248 PixelFormatReg pixel_format; /**< Pixel format register */
249 ColorSelectReg red_select; /**< Red color select register */
250 ColorSelectReg green_select; /**< Green color select register */
251 ColorSelectReg blue_select; /**< Blue color select register */
252 /** @} */
253
246 /** Pixel clock period */
247 const Tick pixelClock;
254 uint32_t readReg(Addr offset);
255 void writeReg(Addr offset, uint32_t value);
248
256
249 FrameBuffer fb;
257 PixelConverter pixelConverter() const;
258 DisplayTimings displayTimings() const;
250
259
251 /** VNC server */
252 VncInput *vnc;
260 void createDmaEngine();
253
261
254 /** Helper to write out bitmaps */
255 Bitmap bmp;
262 void cmdEnable();
263 void cmdDisable();
256
264
257 /** Picture of what the current frame buffer looks like */
258 std::ostream *pic;
265 bool enabled() const { return command.enable; }
259
266
260 /**
261 * Event wrapper for dmaDone()
262 *
263 * This event call pushes its this pointer onto the freeDoneEvent vector
264 * and calls dmaDone() when triggered. While most of the time the burst
265 * length of a transaction will be the max burst length set by the driver,
266 * any trailing bytes must be handled with smaller lengths thus requiring
267 * the configurable burst length option.
268 */
269 class DmaDoneEvent : public Event
270 {
271 private:
272 /** Reference to HDLCD that issued the corresponding DMA transaction */
273 HDLcd &obj;
267 public: // Pixel pump callbacks
268 bool pxlNext(Pixel &p);
269 void pxlVSyncBegin();
270 void pxlVSyncEnd();
271 void pxlUnderrun();
272 void pxlFrameDone();
274
273
275 /** Transaction size */
276 size_t transSize;
277
278 public:
279 /**
280 * Constructor.
281 *
282 * @param _obj HDLCD that issued the corresponding DMA transaction
283 */
284 DmaDoneEvent(HDLcd *_obj)
285 : Event(), obj(*_obj), transSize(0) {}
286
287 /**
288 * Sets the size of this transaction.
289 *
290 * @param len size of the transaction in bytes
291 */
292 void setTransactionSize(size_t len) {
293 transSize = len;
294 }
295
296 /**
297 * Gets the size of this transaction.
298 *
299 * @return size of this transaction in bytes
300 */
301 size_t getTransactionSize() const {
302 return transSize;
303 }
304
305 void process() {
306 obj.dmaDone(this);
307 }
308
309 const std::string name() const {
310 return obj.name() + ".DmaDoneEvent";
311 }
312 };
313
314 /** Start time for frame buffer dma read */
315 Tick frameReadStartTime;
316
317 /** Starting address for the current frame */
318 Addr dmaStartAddr;
319
320 /** Next address the dma should read from */
321 Addr dmaCurAddr;
322
323 /** One byte past the address of the last byte the dma should read
324 * from */
325 Addr dmaMaxAddr;
326
327 /** Number of pending dma reads */
328 size_t dmaPendingNum;
329
330 /** Flag indicating whether current frame has underrun */
331 bool frameUnderrun;
332
333 /** HDLcd virtual display buffer */
334 std::vector<uint8_t> virtualDisplayBuffer;
335
336 /** Size of the pixel buffer */
337 size_t pixelBufferSize;
338
339 /** Index of the next pixel to render */
340 size_t pixelIndex;
341
342 /** Flag indicating whether video parameters need updating */
343 bool doUpdateParams;
344
345 /** Flag indicating whether a frame read / display is in progress */
346 bool frameUnderway;
347
274 protected: // Interrupt handling
348 /**
275 /**
349 * Number of bytes in flight from DMA that have not reached the pixel
350 * buffer yet
351 */
352 uint32_t dmaBytesInFlight;
353
354 /**
355 * Gets the number of oustanding DMA transactions allowed on the bus at a
356 * time.
276 * Assign new interrupt values and update interrupt signals
357 *
277 *
358 * @return gets the driver-specified number of outstanding DMA transactions
359 * from the hdlcd controller that are allowed on the bus at a time
360 */
361 inline uint16_t maxOutstandingDma() const {
362 return bus_options.max_outstanding;
363 }
364
365 /**
366 * Gets the number of bytes free in the pixel buffer.
278 * A new interrupt is scheduled signalled if the set of unmasked
279 * interrupts goes empty to non-empty. Conversely, if the set of
280 * unmasked interrupts goes from non-empty to empty, the interrupt
281 * signal is cleared.
367 *
282 *
368 * @return number of bytes free in the internal pixel buffer
283 * @param ints New <i>raw</i> interrupt status
284 * @param mask New interrupt mask
369 */
285 */
370 inline uint32_t bytesFreeInPixelBuffer() const {
371 return PIXEL_BUFFER_CAPACITY - (pixelBufferSize + dmaBytesInFlight);
372 }
286 void setInterrupts(uint32_t ints, uint32_t mask);
373
374 /**
287
288 /**
375 * Gets the number of beats-per-burst for bus transactions.
289 * Convenience function to update the interrupt mask
376 *
290 *
377 * @return number of beats-per-burst per HDLcd DMA transaction
291 * @see setInterrupts
292 * @param mask New interrupt mask
378 */
293 */
379 inline size_t dmaBurstLength() const {
380 assert(bus_options.burst_len <= MAX_BURST_LEN);
381 return bus_options.burst_len;
382 }
294 void intMask(uint32_t mask) { setInterrupts(int_rawstat, mask); }
383
384 /**
295
296 /**
385 * Gets the number of bytes per pixel.
297 * Convenience function to raise a new interrupt
386 *
298 *
387 * @return bytes per pixel
299 * @see setInterrupts
300 * @param ints Set of interrupts to raise
388 */
301 */
389 inline size_t bytesPerPixel() const {
390 return pixel_format.bytes_per_pixel + 1;
302 void intRaise(uint32_t ints) {
303 setInterrupts(int_rawstat | ints, int_mask);
391 }
392
393 /**
304 }
305
306 /**
394 * Gets frame buffer width.
307 * Convenience function to clear interrupts
395 *
308 *
396 * @return frame buffer width (pixels per line)
309 * @see setInterrupts
310 * @param ints Set of interrupts to clear
397 */
311 */
398 inline size_t width() const {
399 return fb_line_length / bytesPerPixel();
312 void intClear(uint32_t ints) {
313 setInterrupts(int_rawstat & ~ints, int_mask);
400 }
401
314 }
315
402 /**
403 * Gets frame buffer height.
404 *
405 * @return frame buffer height (lines per panel)
406 */
407 inline size_t height() const {
408 return fb_line_count.fb_line_count;
409 }
316 /** Masked interrupt status register */
317 const uint32_t intStatus() const { return int_rawstat & int_mask; }
410
318
411 inline size_t area() const { return height() * width(); }
319 protected: // Pixel output
320 class PixelPump : public BasePixelPump
321 {
322 public:
323 PixelPump(HDLcd &p, ClockDomain &pxl_clk, unsigned pixel_chunk)
324 : BasePixelPump(p, pxl_clk, pixel_chunk), parent(p) {}
412
325
413 /**
414 * Gets the total number of pixel clocks per display line.
415 *
416 * @return number of pixel clocks per display line including porch delays
417 * and horizontal sync time
418 */
419 inline uint64_t PClksPerLine() const {
420 return h_back_porch.val + 1 +
421 h_data.val + 1 +
422 h_front_porch.val + 1 +
423 h_sync.val + 1;
424 }
326 void dumpSettings();
425
327
426 /** Send updated parameters to the vnc server */
427 void updateVideoParams(bool unserializing);
328 protected:
329 bool nextPixel(Pixel &p) M5_ATTR_OVERRIDE { return parent.pxlNext(p); }
428
330
429 /** Generates an interrupt */
430 void generateInterrupt();
331 void onVSyncBegin() M5_ATTR_OVERRIDE { return parent.pxlVSyncBegin(); }
332 void onVSyncEnd() M5_ATTR_OVERRIDE { return parent.pxlVSyncEnd(); }
431
333
432 /** Start reading the next frame */
433 void startFrame();
334 void onUnderrun(unsigned x, unsigned y) M5_ATTR_OVERRIDE {
335 parent.pxlUnderrun();
336 }
434
337
435 /** End of frame reached */
436 void endFrame();
338 void onFrameDone() M5_ATTR_OVERRIDE { parent.pxlFrameDone(); }
437
339
438 /** Generate DMA read requests from frame buffer into pixel buffer */
439 void fillPixelBuffer();
340 protected:
341 HDLcd &parent;
342 };
440
343
441 /** DMA done event */
442 void dmaDone(DmaDoneEvent *event);
344 /** Helper to write out bitmaps */
345 Bitmap bmp;
443
346
444 /** Called when it is time to render a pixel */
445 void renderPixel();
347 /** Picture of what the current frame buffer looks like */
348 std::ostream *pic;
446
349
447 PixelConverter pixelConverter() const;
350 /** Cached pixel converter, set when the converter is enabled. */
351 PixelConverter conv;
448
352
449 /** Start of frame event */
450 EventWrapper<HDLcd, &HDLcd::startFrame> startFrameEvent;
353 PixelPump pixelPump;
451
354
452 /** End of frame event */
453 EventWrapper<HDLcd, &HDLcd::endFrame> endFrameEvent;
355 protected: // DMA handling
356 class DmaEngine : public DmaReadFifo
357 {
358 public:
359 DmaEngine(HDLcd &_parent, size_t size,
360 unsigned request_size, unsigned max_pending,
361 size_t line_size, ssize_t line_pitch, unsigned num_lines);
454
362
455 /** Pixel render event */
456 EventWrapper<HDLcd, &HDLcd::renderPixel> renderPixelEvent;
363 void startFrame(Addr fb_base);
364 void abortFrame();
365 void dumpSettings();
457
366
458 /** Fill fifo */
459 EventWrapper<HDLcd, &HDLcd::fillPixelBuffer> fillPixelBufferEvent;
367 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
368 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
460
369
461 /** Wrapper to create an event out of the interrupt */
462 EventWrapper<HDLcd, &HDLcd::generateInterrupt> intEvent;
370 protected:
371 void onEndOfBlock() M5_ATTR_OVERRIDE;
372 void onIdle() M5_ATTR_OVERRIDE;
463
373
464 /**@{*/
465 /**
466 * All pre-allocated DMA done events
467 *
468 * The HDLCD model preallocates maxOutstandingDma() number of
469 * DmaDoneEvents to avoid having to heap allocate every single
470 * event when it is needed. In order to keep track of which events
471 * are in flight and which are ready to be used, we use two
472 * different vectors. dmaDoneEventAll contains <i>all</i>
473 * DmaDoneEvents that the object may use, while dmaDoneEventFree
474 * contains a list of currently <i>unused</i> events. When an
475 * event needs to be scheduled, the last element of the
476 * dmaDoneEventFree is used and removed from the list. When an
477 * event fires, it is added to the end of the
478 * dmaEventFreeList. dmaDoneEventAll is never used except for in
479 * initialization and serialization.
480 */
481 std::vector<DmaDoneEvent> dmaDoneEventAll;
374 HDLcd &parent;
375 const size_t lineSize;
376 const ssize_t linePitch;
377 const unsigned numLines;
482
378
483 /** Unused DMA done events that are ready to be scheduled */
484 std::vector<DmaDoneEvent *> dmaDoneEventFree;
485 /**@}*/
379 Addr nextLineAddr;
380 Addr frameEnd;
381 };
486
382
487 bool enableCapture;
488
489 const bool workaround_swap_rb;
490
491 public:
492 typedef HDLcdParams Params;
493
494 const Params *
495 params() const
496 {
497 return dynamic_cast<const Params *>(_params);
498 }
499 HDLcd(const Params *p);
500 ~HDLcd();
501
502 virtual Tick read(PacketPtr pkt);
503 virtual Tick write(PacketPtr pkt);
504
505 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
506 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
507
508 /**
509 * Determine the address ranges that this device responds to.
510 *
511 * @return a list of non-overlapping address ranges
512 */
513 AddrRangeList getAddrRanges() const;
383 std::unique_ptr<DmaEngine> dmaEngine;
514};
515
516#endif
384};
385
386#endif