| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *  QEMU model of the Milkymist VGA framebuffer. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-03-31 19:55:25 +02:00
										 |  |  |  *  Copyright (c) 2010-2012 Michael Walle <michael@walle.cc> | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							|  |  |  |  * version 2 of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Specification available at: | 
					
						
							| 
									
										
										
										
											2016-06-20 17:08:41 +01:00
										 |  |  |  *   http://milkymist.walle.cc/socdoc/vgafb.pdf
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 18:16:57 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/hw.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:51 +02:00
										 |  |  | #include "hw/qdev-properties.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/sysbus.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | #include "trace.h"
 | 
					
						
							| 
									
										
										
										
											2012-11-28 12:06:30 +01:00
										 |  |  | #include "ui/console.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-18 17:36:02 +01:00
										 |  |  | #include "framebuffer.h"
 | 
					
						
							| 
									
										
										
										
											2012-11-28 12:06:30 +01:00
										 |  |  | #include "ui/pixel_ops.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:20:00 +01:00
										 |  |  | #include "qemu/error-report.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:07 +02:00
										 |  |  | #include "qemu/module.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | #include "qom/object.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define BITS 8
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:45 +02:00
										 |  |  | #include "migration/vmstate.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-18 17:36:02 +01:00
										 |  |  | #include "milkymist-vgafb_template.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | #define BITS 15
 | 
					
						
							| 
									
										
										
										
											2013-03-18 17:36:02 +01:00
										 |  |  | #include "milkymist-vgafb_template.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | #define BITS 16
 | 
					
						
							| 
									
										
										
										
											2013-03-18 17:36:02 +01:00
										 |  |  | #include "milkymist-vgafb_template.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | #define BITS 24
 | 
					
						
							| 
									
										
										
										
											2013-03-18 17:36:02 +01:00
										 |  |  | #include "milkymist-vgafb_template.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | #define BITS 32
 | 
					
						
							| 
									
										
										
										
											2013-03-18 17:36:02 +01:00
										 |  |  | #include "milkymist-vgafb_template.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  |     R_CTRL = 0, | 
					
						
							|  |  |  |     R_HRES, | 
					
						
							|  |  |  |     R_HSYNC_START, | 
					
						
							|  |  |  |     R_HSYNC_END, | 
					
						
							|  |  |  |     R_HSCAN, | 
					
						
							|  |  |  |     R_VRES, | 
					
						
							|  |  |  |     R_VSYNC_START, | 
					
						
							|  |  |  |     R_VSYNC_END, | 
					
						
							|  |  |  |     R_VSCAN, | 
					
						
							|  |  |  |     R_BASEADDRESS, | 
					
						
							|  |  |  |     R_BASEADDRESS_ACT, | 
					
						
							|  |  |  |     R_BURST_COUNT, | 
					
						
							| 
									
										
										
										
											2012-03-31 19:55:25 +02:00
										 |  |  |     R_DDC, | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     R_SOURCE_CLOCK, | 
					
						
							|  |  |  |     R_MAX | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  |     CTRL_RESET = (1<<0), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-25 00:53:39 +02:00
										 |  |  | #define TYPE_MILKYMIST_VGAFB "milkymist-vgafb"
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(MilkymistVgafbState, MILKYMIST_VGAFB) | 
					
						
							| 
									
										
										
										
											2013-07-25 00:53:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | struct MilkymistVgafbState { | 
					
						
							| 
									
										
										
										
											2013-07-25 00:53:39 +02:00
										 |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:46 +02:00
										 |  |  |     MemoryRegion regs_region; | 
					
						
							| 
									
										
										
										
											2015-07-13 12:00:29 +02:00
										 |  |  |     MemoryRegionSection fbsection; | 
					
						
							| 
									
										
										
										
											2013-03-05 15:24:14 +01:00
										 |  |  |     QemuConsole *con; | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     int invalidate; | 
					
						
							|  |  |  |     uint32_t fb_offset; | 
					
						
							|  |  |  |     uint32_t fb_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t regs[R_MAX]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int vgafb_enabled(MilkymistVgafbState *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return !(s->regs[R_CTRL] & CTRL_RESET); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void vgafb_update_display(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MilkymistVgafbState *s = opaque; | 
					
						
							| 
									
										
										
										
											2013-07-25 00:53:39 +02:00
										 |  |  |     SysBusDevice *sbd; | 
					
						
							| 
									
										
										
										
											2013-03-05 15:24:14 +01:00
										 |  |  |     DisplaySurface *surface = qemu_console_surface(s->con); | 
					
						
							| 
									
										
										
										
											2015-07-13 12:00:29 +02:00
										 |  |  |     int src_width; | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     int first = 0; | 
					
						
							|  |  |  |     int last = 0; | 
					
						
							|  |  |  |     drawfn fn; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!vgafb_enabled(s)) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-25 00:53:39 +02:00
										 |  |  |     sbd = SYS_BUS_DEVICE(s); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     int dest_width = s->regs[R_HRES]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 15:24:14 +01:00
										 |  |  |     switch (surface_bits_per_pixel(surface)) { | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     case 0: | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     case 8: | 
					
						
							|  |  |  |         fn = draw_line_8; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 15: | 
					
						
							|  |  |  |         fn = draw_line_15; | 
					
						
							|  |  |  |         dest_width *= 2; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 16: | 
					
						
							|  |  |  |         fn = draw_line_16; | 
					
						
							|  |  |  |         dest_width *= 2; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 24: | 
					
						
							|  |  |  |         fn = draw_line_24; | 
					
						
							|  |  |  |         dest_width *= 3; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 32: | 
					
						
							|  |  |  |         fn = draw_line_32; | 
					
						
							|  |  |  |         dest_width *= 4; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         hw_error("milkymist_vgafb: bad color depth\n"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 12:00:29 +02:00
										 |  |  |     src_width = s->regs[R_HRES] * 2; | 
					
						
							|  |  |  |     if (s->invalidate) { | 
					
						
							|  |  |  |         framebuffer_update_memory_section(&s->fbsection, | 
					
						
							|  |  |  |                                           sysbus_address_space(sbd), | 
					
						
							|  |  |  |                                           s->regs[R_BASEADDRESS] + s->fb_offset, | 
					
						
							|  |  |  |                                           s->regs[R_VRES], src_width); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     framebuffer_update_display(surface, &s->fbsection, | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |                                s->regs[R_HRES], | 
					
						
							|  |  |  |                                s->regs[R_VRES], | 
					
						
							| 
									
										
										
										
											2015-07-13 12:00:29 +02:00
										 |  |  |                                src_width, | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |                                dest_width, | 
					
						
							|  |  |  |                                0, | 
					
						
							|  |  |  |                                s->invalidate, | 
					
						
							|  |  |  |                                fn, | 
					
						
							|  |  |  |                                NULL, | 
					
						
							|  |  |  |                                &first, &last); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (first >= 0) { | 
					
						
							| 
									
										
										
										
											2013-03-05 15:24:14 +01:00
										 |  |  |         dpy_gfx_update(s->con, 0, first, s->regs[R_HRES], last - first + 1); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     s->invalidate = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void vgafb_invalidate_display(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MilkymistVgafbState *s = opaque; | 
					
						
							|  |  |  |     s->invalidate = 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void vgafb_resize(MilkymistVgafbState *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!vgafb_enabled(s)) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 15:24:14 +01:00
										 |  |  |     qemu_console_resize(s->con, s->regs[R_HRES], s->regs[R_VRES]); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     s->invalidate = 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t vgafb_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:46 +02:00
										 |  |  |                            unsigned size) | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     MilkymistVgafbState *s = opaque; | 
					
						
							|  |  |  |     uint32_t r = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addr >>= 2; | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case R_CTRL: | 
					
						
							|  |  |  |     case R_HRES: | 
					
						
							|  |  |  |     case R_HSYNC_START: | 
					
						
							|  |  |  |     case R_HSYNC_END: | 
					
						
							|  |  |  |     case R_HSCAN: | 
					
						
							|  |  |  |     case R_VRES: | 
					
						
							|  |  |  |     case R_VSYNC_START: | 
					
						
							|  |  |  |     case R_VSYNC_END: | 
					
						
							|  |  |  |     case R_VSCAN: | 
					
						
							|  |  |  |     case R_BASEADDRESS: | 
					
						
							|  |  |  |     case R_BURST_COUNT: | 
					
						
							| 
									
										
										
										
											2012-03-31 19:55:25 +02:00
										 |  |  |     case R_DDC: | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     case R_SOURCE_CLOCK: | 
					
						
							|  |  |  |         r = s->regs[addr]; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |     case R_BASEADDRESS_ACT: | 
					
						
							|  |  |  |         r = s->regs[R_BASEADDRESS]; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         error_report("milkymist_vgafb: read access to unknown register 0x" | 
					
						
							|  |  |  |                 TARGET_FMT_plx, addr << 2); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trace_milkymist_vgafb_memory_read(addr << 2, r); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return r; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void vgafb_write(void *opaque, hwaddr addr, uint64_t value, | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:46 +02:00
										 |  |  |                         unsigned size) | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     MilkymistVgafbState *s = opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trace_milkymist_vgafb_memory_write(addr, value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addr >>= 2; | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case R_CTRL: | 
					
						
							| 
									
										
										
										
											2011-04-13 00:29:34 +02:00
										 |  |  |         s->regs[addr] = value; | 
					
						
							|  |  |  |         vgafb_resize(s); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     case R_HSYNC_START: | 
					
						
							|  |  |  |     case R_HSYNC_END: | 
					
						
							|  |  |  |     case R_HSCAN: | 
					
						
							|  |  |  |     case R_VSYNC_START: | 
					
						
							|  |  |  |     case R_VSYNC_END: | 
					
						
							|  |  |  |     case R_VSCAN: | 
					
						
							|  |  |  |     case R_BURST_COUNT: | 
					
						
							| 
									
										
										
										
											2012-03-31 19:55:25 +02:00
										 |  |  |     case R_DDC: | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     case R_SOURCE_CLOCK: | 
					
						
							|  |  |  |         s->regs[addr] = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case R_BASEADDRESS: | 
					
						
							|  |  |  |         if (value & 0x1f) { | 
					
						
							|  |  |  |             error_report("milkymist_vgafb: framebuffer base address have to " | 
					
						
							|  |  |  |                      "be 32 byte aligned"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         s->regs[addr] = value & s->fb_mask; | 
					
						
							|  |  |  |         s->invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case R_HRES: | 
					
						
							|  |  |  |     case R_VRES: | 
					
						
							|  |  |  |         s->regs[addr] = value; | 
					
						
							|  |  |  |         vgafb_resize(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case R_BASEADDRESS_ACT: | 
					
						
							|  |  |  |         error_report("milkymist_vgafb: write to read-only register 0x" | 
					
						
							|  |  |  |                 TARGET_FMT_plx, addr << 2); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         error_report("milkymist_vgafb: write access to unknown register 0x" | 
					
						
							|  |  |  |                 TARGET_FMT_plx, addr << 2); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:46 +02:00
										 |  |  | static const MemoryRegionOps vgafb_mmio_ops = { | 
					
						
							|  |  |  |     .read = vgafb_read, | 
					
						
							|  |  |  |     .write = vgafb_write, | 
					
						
							|  |  |  |     .valid = { | 
					
						
							|  |  |  |         .min_access_size = 4, | 
					
						
							|  |  |  |         .max_access_size = 4, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void milkymist_vgafb_reset(DeviceState *d) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-25 00:53:39 +02:00
										 |  |  |     MilkymistVgafbState *s = MILKYMIST_VGAFB(d); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < R_MAX; i++) { | 
					
						
							|  |  |  |         s->regs[i] = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* defaults */ | 
					
						
							|  |  |  |     s->regs[R_CTRL] = CTRL_RESET; | 
					
						
							|  |  |  |     s->regs[R_HRES] = 640; | 
					
						
							|  |  |  |     s->regs[R_VRES] = 480; | 
					
						
							|  |  |  |     s->regs[R_BASEADDRESS] = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 14:04:18 +01:00
										 |  |  | static const GraphicHwOps vgafb_ops = { | 
					
						
							|  |  |  |     .invalidate  = vgafb_invalidate_display, | 
					
						
							|  |  |  |     .gfx_update  = vgafb_update_display, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:34 +08:00
										 |  |  | static void milkymist_vgafb_init(Object *obj) | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:34 +08:00
										 |  |  |     MilkymistVgafbState *s = MILKYMIST_VGAFB(obj); | 
					
						
							|  |  |  |     SysBusDevice *dev = SYS_BUS_DEVICE(obj); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |     memory_region_init_io(&s->regs_region, OBJECT(s), &vgafb_mmio_ops, s, | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:46 +02:00
										 |  |  |             "milkymist-vgafb", R_MAX * 4); | 
					
						
							| 
									
										
										
										
											2011-11-27 11:38:10 +02:00
										 |  |  |     sysbus_init_mmio(dev, &s->regs_region); | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:34 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:34 +08:00
										 |  |  | static void milkymist_vgafb_realize(DeviceState *dev, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MilkymistVgafbState *s = MILKYMIST_VGAFB(dev); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:34 +08:00
										 |  |  |     s->con = graphic_console_init(dev, 0, &vgafb_ops, s); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int vgafb_post_load(void *opaque, int version_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     vgafb_invalidate_display(opaque); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const VMStateDescription vmstate_milkymist_vgafb = { | 
					
						
							|  |  |  |     .name = "milkymist-vgafb", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							|  |  |  |     .post_load = vgafb_post_load, | 
					
						
							| 
									
										
										
										
											2014-04-16 16:01:33 +02:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  |         VMSTATE_UINT32_ARRAY(regs, MilkymistVgafbState, R_MAX), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static Property milkymist_vgafb_properties[] = { | 
					
						
							|  |  |  |     DEFINE_PROP_UINT32("fb_offset", MilkymistVgafbState, fb_offset, 0x0), | 
					
						
							|  |  |  |     DEFINE_PROP_UINT32("fb_mask", MilkymistVgafbState, fb_mask, 0xffffffff), | 
					
						
							|  |  |  |     DEFINE_PROP_END_OF_LIST(), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void milkymist_vgafb_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     dc->reset = milkymist_vgafb_reset; | 
					
						
							|  |  |  |     dc->vmsd = &vmstate_milkymist_vgafb; | 
					
						
							| 
									
										
										
										
											2020-01-10 19:30:32 +04:00
										 |  |  |     device_class_set_props(dc, milkymist_vgafb_properties); | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:34 +08:00
										 |  |  |     dc->realize = milkymist_vgafb_realize; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo milkymist_vgafb_info = { | 
					
						
							| 
									
										
										
										
											2013-07-25 00:53:39 +02:00
										 |  |  |     .name          = TYPE_MILKYMIST_VGAFB, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(MilkymistVgafbState), | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:34 +08:00
										 |  |  |     .instance_init = milkymist_vgafb_init, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .class_init    = milkymist_vgafb_class_init, | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void milkymist_vgafb_register_types(void) | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     type_register_static(&milkymist_vgafb_info); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:42 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | type_init(milkymist_vgafb_register_types) |