| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  QEMU model of the Milkymist texture mapping unit. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Copyright (c) 2010 Michael Walle <michael@walle.cc> | 
					
						
							|  |  |  |  *  Copyright (c) 2010 Sebastien Bourdeauducq | 
					
						
							|  |  |  |  *                       <sebastien.bourdeauducq@lekernel.net> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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/tmu2.pdf
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 18:16:57 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:42 +02:00
										 |  |  | #include "hw/irq.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/sysbus.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:45 +02:00
										 |  |  | #include "migration/vmstate.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | #include "trace.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-01 12:18:31 +01:00
										 |  |  | #include "qapi/error.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"
 | 
					
						
							| 
									
										
										
										
											2016-06-21 12:11:51 +02:00
										 |  |  | #include "qapi/error.h"
 | 
					
						
							| 
									
										
										
										
											2019-01-30 13:00:05 +01:00
										 |  |  | #include "hw/display/milkymist_tmu2.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <X11/Xlib.h>
 | 
					
						
							| 
									
										
										
										
											2015-10-27 02:45:48 +09:00
										 |  |  | #include <epoxy/gl.h>
 | 
					
						
							|  |  |  | #include <epoxy/glx.h>
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | #include "qom/object.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  |     R_CTL = 0, | 
					
						
							|  |  |  |     R_HMESHLAST, | 
					
						
							|  |  |  |     R_VMESHLAST, | 
					
						
							|  |  |  |     R_BRIGHTNESS, | 
					
						
							|  |  |  |     R_CHROMAKEY, | 
					
						
							|  |  |  |     R_VERTICESADDR, | 
					
						
							|  |  |  |     R_TEXFBUF, | 
					
						
							|  |  |  |     R_TEXHRES, | 
					
						
							|  |  |  |     R_TEXVRES, | 
					
						
							|  |  |  |     R_TEXHMASK, | 
					
						
							|  |  |  |     R_TEXVMASK, | 
					
						
							|  |  |  |     R_DSTFBUF, | 
					
						
							|  |  |  |     R_DSTHRES, | 
					
						
							|  |  |  |     R_DSTVRES, | 
					
						
							|  |  |  |     R_DSTHOFFSET, | 
					
						
							|  |  |  |     R_DSTVOFFSET, | 
					
						
							|  |  |  |     R_DSTSQUAREW, | 
					
						
							|  |  |  |     R_DSTSQUAREH, | 
					
						
							|  |  |  |     R_ALPHA, | 
					
						
							|  |  |  |     R_MAX | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  |     CTL_START_BUSY  = (1<<0), | 
					
						
							|  |  |  |     CTL_CHROMAKEY   = (1<<1), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  |     MAX_BRIGHTNESS = 63, | 
					
						
							|  |  |  |     MAX_ALPHA      = 63, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  |     MESH_MAXSIZE = 128, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct vertex { | 
					
						
							|  |  |  |     int x; | 
					
						
							|  |  |  |     int y; | 
					
						
							| 
									
										
										
										
											2011-08-31 12:38:01 +02:00
										 |  |  | } QEMU_PACKED; | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-25 00:48:23 +02:00
										 |  |  | #define TYPE_MILKYMIST_TMU2 "milkymist-tmu2"
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(MilkymistTMU2State, MILKYMIST_TMU2) | 
					
						
							| 
									
										
										
										
											2013-07-25 00:48:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | struct MilkymistTMU2State { | 
					
						
							| 
									
										
										
										
											2013-07-25 00:48:23 +02:00
										 |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:44 +02:00
										 |  |  |     MemoryRegion regs_region; | 
					
						
							| 
									
										
										
										
											2016-12-07 16:20:22 +03:00
										 |  |  |     Chardev *chr; | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     qemu_irq irq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t regs[R_MAX]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Display *dpy; | 
					
						
							|  |  |  |     GLXFBConfig glx_fb_config; | 
					
						
							|  |  |  |     GLXContext glx_context; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const int glx_fbconfig_attr[] = { | 
					
						
							|  |  |  |     GLX_GREEN_SIZE, 5, | 
					
						
							|  |  |  |     GLX_GREEN_SIZE, 6, | 
					
						
							|  |  |  |     GLX_BLUE_SIZE, 5, | 
					
						
							|  |  |  |     None | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int tmu2_glx_init(MilkymistTMU2State *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     GLXFBConfig *configs; | 
					
						
							|  |  |  |     int nelements; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->dpy = XOpenDisplay(NULL); /* FIXME: call XCloseDisplay() */ | 
					
						
							|  |  |  |     if (s->dpy == NULL) { | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     configs = glXChooseFBConfig(s->dpy, 0, glx_fbconfig_attr, &nelements); | 
					
						
							|  |  |  |     if (configs == NULL) { | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->glx_fb_config = *configs; | 
					
						
							|  |  |  |     XFree(configs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* FIXME: call glXDestroyContext() */ | 
					
						
							|  |  |  |     s->glx_context = glXCreateNewContext(s->dpy, s->glx_fb_config, | 
					
						
							|  |  |  |             GLX_RGBA_TYPE, NULL, 1); | 
					
						
							|  |  |  |     if (s->glx_context == NULL) { | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void tmu2_gl_map(struct vertex *mesh, int texhres, int texvres, | 
					
						
							|  |  |  |         int hmeshlast, int vmeshlast, int ho, int vo, int sw, int sh) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int x, y; | 
					
						
							|  |  |  |     int x0, y0, x1, y1; | 
					
						
							|  |  |  |     int u0, v0, u1, v1, u2, v2, u3, v3; | 
					
						
							|  |  |  |     double xscale = 1.0 / ((double)(64 * texhres)); | 
					
						
							|  |  |  |     double yscale = 1.0 / ((double)(64 * texvres)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glLoadIdentity(); | 
					
						
							|  |  |  |     glTranslatef(ho, vo, 0); | 
					
						
							|  |  |  |     glEnable(GL_TEXTURE_2D); | 
					
						
							|  |  |  |     glBegin(GL_QUADS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (y = 0; y < vmeshlast; y++) { | 
					
						
							|  |  |  |         y0 = y * sh; | 
					
						
							|  |  |  |         y1 = y0 + sh; | 
					
						
							|  |  |  |         for (x = 0; x < hmeshlast; x++) { | 
					
						
							|  |  |  |             x0 = x * sw; | 
					
						
							|  |  |  |             x1 = x0 + sw; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             u0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].x); | 
					
						
							|  |  |  |             v0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].y); | 
					
						
							|  |  |  |             u1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].x); | 
					
						
							|  |  |  |             v1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].y); | 
					
						
							|  |  |  |             u2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].x); | 
					
						
							|  |  |  |             v2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].y); | 
					
						
							|  |  |  |             u3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].x); | 
					
						
							|  |  |  |             v3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             glTexCoord2d(((double)u0) * xscale, ((double)v0) * yscale); | 
					
						
							|  |  |  |             glVertex3i(x0, y0, 0); | 
					
						
							|  |  |  |             glTexCoord2d(((double)u1) * xscale, ((double)v1) * yscale); | 
					
						
							|  |  |  |             glVertex3i(x1, y0, 0); | 
					
						
							|  |  |  |             glTexCoord2d(((double)u2) * xscale, ((double)v2) * yscale); | 
					
						
							|  |  |  |             glVertex3i(x1, y1, 0); | 
					
						
							|  |  |  |             glTexCoord2d(((double)u3) * xscale, ((double)v3) * yscale); | 
					
						
							|  |  |  |             glVertex3i(x0, y1, 0); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glEnd(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void tmu2_start(MilkymistTMU2State *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int pbuffer_attrib[6] = { | 
					
						
							|  |  |  |         GLX_PBUFFER_WIDTH, | 
					
						
							|  |  |  |         0, | 
					
						
							|  |  |  |         GLX_PBUFFER_HEIGHT, | 
					
						
							|  |  |  |         0, | 
					
						
							|  |  |  |         GLX_PRESERVED_CONTENTS, | 
					
						
							|  |  |  |         True | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GLXPbuffer pbuffer; | 
					
						
							|  |  |  |     GLuint texture; | 
					
						
							|  |  |  |     void *fb; | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |     hwaddr fb_len; | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     void *mesh; | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |     hwaddr mesh_len; | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     float m; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trace_milkymist_tmu2_start(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Create and set up a suitable OpenGL context */ | 
					
						
							|  |  |  |     pbuffer_attrib[1] = s->regs[R_DSTHRES]; | 
					
						
							|  |  |  |     pbuffer_attrib[3] = s->regs[R_DSTVRES]; | 
					
						
							|  |  |  |     pbuffer = glXCreatePbuffer(s->dpy, s->glx_fb_config, pbuffer_attrib); | 
					
						
							|  |  |  |     glXMakeContextCurrent(s->dpy, pbuffer, pbuffer, s->glx_context); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Fixup endianness. TODO: would it work on BE hosts? */ | 
					
						
							|  |  |  |     glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); | 
					
						
							|  |  |  |     glPixelStorei(GL_PACK_SWAP_BYTES, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Row alignment */ | 
					
						
							|  |  |  |     glPixelStorei(GL_UNPACK_ALIGNMENT, 2); | 
					
						
							|  |  |  |     glPixelStorei(GL_PACK_ALIGNMENT, 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Read the QEMU source framebuffer into an OpenGL texture */ | 
					
						
							|  |  |  |     glGenTextures(1, &texture); | 
					
						
							|  |  |  |     glBindTexture(GL_TEXTURE_2D, texture); | 
					
						
							| 
									
										
										
										
											2016-10-13 00:35:07 +02:00
										 |  |  |     fb_len = 2ULL * s->regs[R_TEXHRES] * s->regs[R_TEXVRES]; | 
					
						
							| 
									
										
										
										
											2020-02-19 20:20:42 +01:00
										 |  |  |     fb = cpu_physical_memory_map(s->regs[R_TEXFBUF], &fb_len, false); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     if (fb == NULL) { | 
					
						
							|  |  |  |         glDeleteTextures(1, &texture); | 
					
						
							|  |  |  |         glXMakeContextCurrent(s->dpy, None, None, NULL); | 
					
						
							|  |  |  |         glXDestroyPbuffer(s->dpy, pbuffer); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     glTexImage2D(GL_TEXTURE_2D, 0, 3, s->regs[R_TEXHRES], s->regs[R_TEXVRES], | 
					
						
							|  |  |  |             0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb); | 
					
						
							|  |  |  |     cpu_physical_memory_unmap(fb, fb_len, 0, fb_len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set up texturing options */ | 
					
						
							|  |  |  |     /* WARNING:
 | 
					
						
							|  |  |  |      * Many cases of TMU2 masking are not supported by OpenGL. | 
					
						
							|  |  |  |      * We only implement the most common ones: | 
					
						
							|  |  |  |      *  - full bilinear filtering vs. nearest texel | 
					
						
							|  |  |  |      *  - texture clamping vs. texture wrapping | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if ((s->regs[R_TEXHMASK] & 0x3f) > 0x20) { | 
					
						
							|  |  |  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 
					
						
							|  |  |  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((s->regs[R_TEXHMASK] >> 6) & s->regs[R_TEXHRES]) { | 
					
						
							|  |  |  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((s->regs[R_TEXVMASK] >> 6) & s->regs[R_TEXVRES]) { | 
					
						
							|  |  |  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Translucency and decay */ | 
					
						
							|  |  |  |     glEnable(GL_BLEND); | 
					
						
							|  |  |  |     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 
					
						
							|  |  |  |     m = (float)(s->regs[R_BRIGHTNESS] + 1) / 64.0f; | 
					
						
							|  |  |  |     glColor4f(m, m, m, (float)(s->regs[R_ALPHA] + 1) / 64.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Read the QEMU dest. framebuffer into the OpenGL framebuffer */ | 
					
						
							| 
									
										
										
										
											2017-01-06 17:45:14 +00:00
										 |  |  |     fb_len = 2ULL * s->regs[R_DSTHRES] * s->regs[R_DSTVRES]; | 
					
						
							| 
									
										
										
										
											2020-02-19 20:20:42 +01:00
										 |  |  |     fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, false); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     if (fb == NULL) { | 
					
						
							|  |  |  |         glDeleteTextures(1, &texture); | 
					
						
							|  |  |  |         glXMakeContextCurrent(s->dpy, None, None, NULL); | 
					
						
							|  |  |  |         glXDestroyPbuffer(s->dpy, pbuffer); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glDrawPixels(s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB, | 
					
						
							|  |  |  |             GL_UNSIGNED_SHORT_5_6_5, fb); | 
					
						
							|  |  |  |     cpu_physical_memory_unmap(fb, fb_len, 0, fb_len); | 
					
						
							|  |  |  |     glViewport(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES]); | 
					
						
							|  |  |  |     glMatrixMode(GL_PROJECTION); | 
					
						
							|  |  |  |     glLoadIdentity(); | 
					
						
							|  |  |  |     glOrtho(0.0, s->regs[R_DSTHRES], 0.0, s->regs[R_DSTVRES], -1.0, 1.0); | 
					
						
							|  |  |  |     glMatrixMode(GL_MODELVIEW); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Map the texture */ | 
					
						
							|  |  |  |     mesh_len = MESH_MAXSIZE*MESH_MAXSIZE*sizeof(struct vertex); | 
					
						
							| 
									
										
										
										
											2020-02-19 20:20:42 +01:00
										 |  |  |     mesh = cpu_physical_memory_map(s->regs[R_VERTICESADDR], &mesh_len, false); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     if (mesh == NULL) { | 
					
						
							|  |  |  |         glDeleteTextures(1, &texture); | 
					
						
							|  |  |  |         glXMakeContextCurrent(s->dpy, None, None, NULL); | 
					
						
							|  |  |  |         glXDestroyPbuffer(s->dpy, pbuffer); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tmu2_gl_map((struct vertex *)mesh, | 
					
						
							|  |  |  |         s->regs[R_TEXHRES], s->regs[R_TEXVRES], | 
					
						
							|  |  |  |         s->regs[R_HMESHLAST], s->regs[R_VMESHLAST], | 
					
						
							|  |  |  |         s->regs[R_DSTHOFFSET], s->regs[R_DSTVOFFSET], | 
					
						
							|  |  |  |         s->regs[R_DSTSQUAREW], s->regs[R_DSTSQUAREH]); | 
					
						
							|  |  |  |     cpu_physical_memory_unmap(mesh, mesh_len, 0, mesh_len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Write back the OpenGL framebuffer to the QEMU framebuffer */ | 
					
						
							| 
									
										
										
										
											2017-02-16 17:26:48 +00:00
										 |  |  |     fb_len = 2ULL * s->regs[R_DSTHRES] * s->regs[R_DSTVRES]; | 
					
						
							| 
									
										
										
										
											2020-02-19 20:20:42 +01:00
										 |  |  |     fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, true); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     if (fb == NULL) { | 
					
						
							|  |  |  |         glDeleteTextures(1, &texture); | 
					
						
							|  |  |  |         glXMakeContextCurrent(s->dpy, None, None, NULL); | 
					
						
							|  |  |  |         glXDestroyPbuffer(s->dpy, pbuffer); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glReadPixels(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB, | 
					
						
							|  |  |  |             GL_UNSIGNED_SHORT_5_6_5, fb); | 
					
						
							|  |  |  |     cpu_physical_memory_unmap(fb, fb_len, 1, fb_len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Free OpenGL allocs */ | 
					
						
							|  |  |  |     glDeleteTextures(1, &texture); | 
					
						
							|  |  |  |     glXMakeContextCurrent(s->dpy, None, None, NULL); | 
					
						
							|  |  |  |     glXDestroyPbuffer(s->dpy, pbuffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->regs[R_CTL] &= ~CTL_START_BUSY; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trace_milkymist_tmu2_pulse_irq(); | 
					
						
							|  |  |  |     qemu_irq_pulse(s->irq); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t tmu2_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:44 +02:00
										 |  |  |                           unsigned size) | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     MilkymistTMU2State *s = opaque; | 
					
						
							|  |  |  |     uint32_t r = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addr >>= 2; | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case R_CTL: | 
					
						
							|  |  |  |     case R_HMESHLAST: | 
					
						
							|  |  |  |     case R_VMESHLAST: | 
					
						
							|  |  |  |     case R_BRIGHTNESS: | 
					
						
							|  |  |  |     case R_CHROMAKEY: | 
					
						
							|  |  |  |     case R_VERTICESADDR: | 
					
						
							|  |  |  |     case R_TEXFBUF: | 
					
						
							|  |  |  |     case R_TEXHRES: | 
					
						
							|  |  |  |     case R_TEXVRES: | 
					
						
							|  |  |  |     case R_TEXHMASK: | 
					
						
							|  |  |  |     case R_TEXVMASK: | 
					
						
							|  |  |  |     case R_DSTFBUF: | 
					
						
							|  |  |  |     case R_DSTHRES: | 
					
						
							|  |  |  |     case R_DSTVRES: | 
					
						
							|  |  |  |     case R_DSTHOFFSET: | 
					
						
							|  |  |  |     case R_DSTVOFFSET: | 
					
						
							|  |  |  |     case R_DSTSQUAREW: | 
					
						
							|  |  |  |     case R_DSTSQUAREH: | 
					
						
							|  |  |  |     case R_ALPHA: | 
					
						
							|  |  |  |         r = s->regs[addr]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         error_report("milkymist_tmu2: read access to unknown register 0x" | 
					
						
							|  |  |  |                 TARGET_FMT_plx, addr << 2); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trace_milkymist_tmu2_memory_read(addr << 2, r); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return r; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void tmu2_check_registers(MilkymistTMU2State *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (s->regs[R_BRIGHTNESS] > MAX_BRIGHTNESS) { | 
					
						
							| 
									
										
										
										
											2011-06-22 14:03:54 +02:00
										 |  |  |         error_report("milkymist_tmu2: max brightness is %d", MAX_BRIGHTNESS); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->regs[R_ALPHA] > MAX_ALPHA) { | 
					
						
							| 
									
										
										
										
											2011-06-22 14:03:54 +02:00
										 |  |  |         error_report("milkymist_tmu2: max alpha is %d", MAX_ALPHA); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->regs[R_VERTICESADDR] & 0x07) { | 
					
						
							|  |  |  |         error_report("milkymist_tmu2: vertex mesh address has to be 64-bit " | 
					
						
							| 
									
										
										
										
											2011-06-22 14:03:54 +02:00
										 |  |  |                 "aligned"); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->regs[R_TEXFBUF] & 0x01) { | 
					
						
							|  |  |  |         error_report("milkymist_tmu2: texture buffer address has to be " | 
					
						
							| 
									
										
										
										
											2011-06-22 14:03:54 +02:00
										 |  |  |                 "16-bit aligned"); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void tmu2_write(void *opaque, hwaddr addr, uint64_t value, | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:44 +02:00
										 |  |  |                        unsigned size) | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     MilkymistTMU2State *s = opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trace_milkymist_tmu2_memory_write(addr, value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addr >>= 2; | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case R_CTL: | 
					
						
							|  |  |  |         s->regs[addr] = value; | 
					
						
							|  |  |  |         if (value & CTL_START_BUSY) { | 
					
						
							|  |  |  |             tmu2_start(s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case R_BRIGHTNESS: | 
					
						
							|  |  |  |     case R_HMESHLAST: | 
					
						
							|  |  |  |     case R_VMESHLAST: | 
					
						
							|  |  |  |     case R_CHROMAKEY: | 
					
						
							|  |  |  |     case R_VERTICESADDR: | 
					
						
							|  |  |  |     case R_TEXFBUF: | 
					
						
							|  |  |  |     case R_TEXHRES: | 
					
						
							|  |  |  |     case R_TEXVRES: | 
					
						
							|  |  |  |     case R_TEXHMASK: | 
					
						
							|  |  |  |     case R_TEXVMASK: | 
					
						
							|  |  |  |     case R_DSTFBUF: | 
					
						
							|  |  |  |     case R_DSTHRES: | 
					
						
							|  |  |  |     case R_DSTVRES: | 
					
						
							|  |  |  |     case R_DSTHOFFSET: | 
					
						
							|  |  |  |     case R_DSTVOFFSET: | 
					
						
							|  |  |  |     case R_DSTSQUAREW: | 
					
						
							|  |  |  |     case R_DSTSQUAREH: | 
					
						
							|  |  |  |     case R_ALPHA: | 
					
						
							|  |  |  |         s->regs[addr] = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         error_report("milkymist_tmu2: write access to unknown register 0x" | 
					
						
							|  |  |  |                 TARGET_FMT_plx, addr << 2); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tmu2_check_registers(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:44 +02:00
										 |  |  | static const MemoryRegionOps tmu2_mmio_ops = { | 
					
						
							|  |  |  |     .read = tmu2_read, | 
					
						
							|  |  |  |     .write = tmu2_write, | 
					
						
							|  |  |  |     .valid = { | 
					
						
							|  |  |  |         .min_access_size = 4, | 
					
						
							|  |  |  |         .max_access_size = 4, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void milkymist_tmu2_reset(DeviceState *d) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-25 00:48:23 +02:00
										 |  |  |     MilkymistTMU2State *s = MILKYMIST_TMU2(d); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < R_MAX; i++) { | 
					
						
							|  |  |  |         s->regs[i] = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:33 +08:00
										 |  |  | static void milkymist_tmu2_init(Object *obj) | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:33 +08:00
										 |  |  |     MilkymistTMU2State *s = MILKYMIST_TMU2(obj); | 
					
						
							|  |  |  |     SysBusDevice *dev = SYS_BUS_DEVICE(obj); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     sysbus_init_irq(dev, &s->irq); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:33 +08:00
										 |  |  |     memory_region_init_io(&s->regs_region, obj, &tmu2_mmio_ops, s, | 
					
						
							| 
									
										
										
										
											2011-08-31 16:48:44 +02:00
										 |  |  |             "milkymist-tmu2", R_MAX * 4); | 
					
						
							| 
									
										
										
										
											2011-11-27 11:38:10 +02:00
										 |  |  |     sysbus_init_mmio(dev, &s->regs_region); | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:33 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:33 +08:00
										 |  |  | static void milkymist_tmu2_realize(DeviceState *dev, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MilkymistTMU2State *s = MILKYMIST_TMU2(dev); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tmu2_glx_init(s)) { | 
					
						
							|  |  |  |         error_setg(errp, "tmu2_glx_init failed"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const VMStateDescription vmstate_milkymist_tmu2 = { | 
					
						
							|  |  |  |     .name = "milkymist-tmu2", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							| 
									
										
										
										
											2014-04-16 16:01:33 +02:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  |         VMSTATE_UINT32_ARRAY(regs, MilkymistTMU2State, R_MAX), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static void milkymist_tmu2_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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:33 +08:00
										 |  |  |     dc->realize = milkymist_tmu2_realize; | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     dc->reset = milkymist_tmu2_reset; | 
					
						
							|  |  |  |     dc->vmsd = &vmstate_milkymist_tmu2; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo milkymist_tmu2_info = { | 
					
						
							| 
									
										
										
										
											2013-07-25 00:48:23 +02:00
										 |  |  |     .name          = TYPE_MILKYMIST_TMU2, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(MilkymistTMU2State), | 
					
						
							| 
									
										
										
										
											2016-05-06 18:59:33 +08:00
										 |  |  |     .instance_init = milkymist_tmu2_init, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .class_init    = milkymist_tmu2_class_init, | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void milkymist_tmu2_register_types(void) | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     type_register_static(&milkymist_tmu2_info); | 
					
						
							| 
									
										
										
										
											2011-03-07 23:32:40 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | type_init(milkymist_tmu2_register_types) | 
					
						
							| 
									
										
										
										
											2019-01-30 13:00:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | DeviceState *milkymist_tmu2_create(hwaddr base, qemu_irq irq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     DeviceState *dev; | 
					
						
							|  |  |  |     Display *d; | 
					
						
							|  |  |  |     GLXFBConfig *configs; | 
					
						
							|  |  |  |     int nelements; | 
					
						
							|  |  |  |     int ver_major, ver_minor; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* check that GLX will work */ | 
					
						
							|  |  |  |     d = XOpenDisplay(NULL); | 
					
						
							|  |  |  |     if (d == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!glXQueryVersion(d, &ver_major, &ver_minor)) { | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * Yeah, sometimes getting the GLX version can fail. | 
					
						
							|  |  |  |          * Isn't X beautiful? | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         XCloseDisplay(d); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((ver_major < 1) || ((ver_major == 1) && (ver_minor < 3))) { | 
					
						
							|  |  |  |         printf("Your GLX version is %d.%d," | 
					
						
							|  |  |  |           "but TMU emulation needs at least 1.3. TMU disabled.\n", | 
					
						
							|  |  |  |           ver_major, ver_minor); | 
					
						
							|  |  |  |         XCloseDisplay(d); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     configs = glXChooseFBConfig(d, 0, glx_fbconfig_attr, &nelements); | 
					
						
							|  |  |  |     if (configs == NULL) { | 
					
						
							|  |  |  |         XCloseDisplay(d); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     XFree(configs); | 
					
						
							|  |  |  |     XCloseDisplay(d); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion.  More to come in
this series.
Coccinelle script:
    @ depends on !(file in "hw/arm/highbank.c")@
    expression bus, type_name, dev, expr;
    @@
    -    dev = qdev_create(bus, type_name);
    +    dev = qdev_new(type_name);
         ... when != dev = expr
    -    qdev_init_nofail(dev);
    +    qdev_realize_and_unref(dev, bus, &error_fatal);
    @@
    expression bus, type_name, dev, expr;
    identifier DOWN;
    @@
    -    dev = DOWN(qdev_create(bus, type_name));
    +    dev = DOWN(qdev_new(type_name));
         ... when != dev = expr
    -    qdev_init_nofail(DEVICE(dev));
    +    qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
    @@
    expression bus, type_name, expr;
    identifier dev;
    @@
    -    DeviceState *dev = qdev_create(bus, type_name);
    +    DeviceState *dev = qdev_new(type_name);
         ... when != dev = expr
    -    qdev_init_nofail(dev);
    +    qdev_realize_and_unref(dev, bus, &error_fatal);
    @@
    expression bus, type_name, dev, expr, errp;
    symbol true;
    @@
    -    dev = qdev_create(bus, type_name);
    +    dev = qdev_new(type_name);
         ... when != dev = expr
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize_and_unref(dev, bus, errp);
    @@
    expression bus, type_name, expr, errp;
    identifier dev;
    symbol true;
    @@
    -    DeviceState *dev = qdev_create(bus, type_name);
    +    DeviceState *dev = qdev_new(type_name);
         ... when != dev = expr
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name.  Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
											
										 
											2020-06-10 07:31:58 +02:00
										 |  |  |     dev = qdev_new(TYPE_MILKYMIST_TMU2); | 
					
						
							| 
									
										
											  
											
												sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
    @@
    expression dev, errp;
    @@
    -    qdev_realize(DEVICE(dev), NULL, errp);
    +    sysbus_realize(SYS_BUS_DEVICE(dev), errp);
    @@
    expression sysbus_dev, dev, errp;
    @@
    +    sysbus_dev = SYS_BUS_DEVICE(dev);
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(sysbus_dev, errp);
    -    sysbus_dev = SYS_BUS_DEVICE(dev);
    @@
    expression sysbus_dev, dev, errp;
    expression expr;
    @@
         sysbus_dev = SYS_BUS_DEVICE(dev);
         ... when != dev = expr;
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(sysbus_dev, errp);
    @@
    expression dev, errp;
    @@
    -    qdev_realize_and_unref(DEVICE(dev), NULL, errp);
    +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
    @@
    expression dev, errp;
    @@
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
											
										 
											2020-06-10 07:32:34 +02:00
										 |  |  |     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 
					
						
							| 
									
										
										
										
											2019-01-30 13:00:05 +01:00
										 |  |  |     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); | 
					
						
							|  |  |  |     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return dev; | 
					
						
							|  |  |  | } |