From patchwork Tue Aug 14 14:44:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 144175 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4450816ljj; Tue, 14 Aug 2018 07:44:40 -0700 (PDT) X-Google-Smtp-Source: AA+uWPx6tQMxfSSGOjuAVFMEs98i1HnAHrNeHnlIhS1jN+XoHilVeHC6Co7C1sViTeaW59Y7qFxj X-Received: by 2002:a19:290c:: with SMTP id p12-v6mr13628966lfp.124.1534257880694; Tue, 14 Aug 2018 07:44:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534257880; cv=none; d=google.com; s=arc-20160816; b=gp7sRAU82axKXly3VdX0Lc9XaHh2y3oy0WEYRWkldN18V8rlS7lJZtpv+Bdm1hJiRa oZcmsS6GUCVFYHjfAzudW8BLSScv+JE5f44dOCyh3TSVIY5MXLzR1WrSOEHSK8l516zi uC9umYWY8JR75K8QzP84wqEkPvJjmiT5v9CJ8+1mAh06c8KFwoIqWWM8OOjiEgxHJCYF KM89z20cBNIvZ+KnmxDoC6NAaEKLkBBQ5EcJtlyDBhNBjQRJ1eL84a3Yua2ITo5aiIBd NnnPH425a/pshq9LDWtISppM+fNIs2ryuU93tgEq5cA3oEtnPW2ldiBMOH1KeMtQhJXy QH/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=oA+ETRqUKv8A1rnzyZJJcNOAFd2qC35gMiQxFiIQ40U=; b=e9qXkear7XkxT1Ugca+5/I24PeH3pm5/Gbfq7rwacJ/+UJH9NgQ3IL1hbLKV/T5d0F +0C0Wsp5sNZy649MKGeC2ObfHMIgSJm+iB8EaVF1mFhWteYYsC+mOoP2cZBqxLe59mJW L8roqMEud6Jwr0Y5Bx93nfYpBM1J2a+R34S+pVoy2Vba3B+J2+i8VvtK0GC/QfczR5d3 TdOk4pDfKI/EU79Y8r31mPZewu3D7Nx/003rAYIYxPwAbRa4DFD5Adad2UFn85Gh3o3i tZlb/w8FyFuo0cIRo/qvI9oSpSlqBKjP5bonGhpNwCNQ7Rntp2CYNpRb2NztgFlsuv0w AMdg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id o18-v6si7034154lfd.168.2018.08.14.07.44.40 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 14 Aug 2018 07:44:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpaYp-0006yl-HY; Tue, 14 Aug 2018 15:44:39 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 1/8] hw/misc/bcm2835_fb: Move config fields to their own struct Date: Tue, 14 Aug 2018 15:44:29 +0100 Message-Id: <20180814144436.679-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814144436.679-1-peter.maydell@linaro.org> References: <20180814144436.679-1-peter.maydell@linaro.org> The handling of framebuffer properties in the bcm2835_property code is a bit clumsy, because for each of the many fb related properties we try to track the value we're about to set and whether we're going to be setting a value, and then we hand all the new values off to the framebuffer via a function which takes them all as separate arguments. It would be simpler if the property code could easily copy all the framebuffer's current settings, update them with the new specified values and then ask the framebuffer to switch to the new set. As the first part of this refactoring, pull all the fb config settings fields in BCM2835FBState out into their own struct. Signed-off-by: Peter Maydell --- include/hw/display/bcm2835_fb.h | 26 ++++++-- hw/display/bcm2835_fb.c | 114 +++++++++++++++++--------------- hw/misc/bcm2835_property.c | 28 ++++---- 3 files changed, 94 insertions(+), 74 deletions(-) -- 2.18.0 Reviewed-by: Richard Henderson diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index ae0a3807f2c..8485825ba5f 100644 --- a/include/hw/display/bcm2835_fb.h +++ b/include/hw/display/bcm2835_fb.h @@ -17,6 +17,20 @@ #define TYPE_BCM2835_FB "bcm2835-fb" #define BCM2835_FB(obj) OBJECT_CHECK(BCM2835FBState, (obj), TYPE_BCM2835_FB) +/* + * Configuration information about the fb which the guest can program + * via the mailbox property interface. + */ +typedef struct { + uint32_t xres, yres; + uint32_t xres_virtual, yres_virtual; + uint32_t xoffset, yoffset; + uint32_t bpp; + uint32_t base; + uint32_t pixo; + uint32_t alpha; +} BCM2835FBConfig; + typedef struct { /*< private >*/ SysBusDevice busdev; @@ -31,12 +45,12 @@ typedef struct { qemu_irq mbox_irq; bool lock, invalidate, pending; - uint32_t xres, yres; - uint32_t xres_virtual, yres_virtual; - uint32_t xoffset, yoffset; - uint32_t bpp; - uint32_t base, pitch, size; - uint32_t pixo, alpha; + + BCM2835FBConfig config; + + /* These are just cached values calculated from the config settings */ + uint32_t size; + uint32_t pitch; } BCM2835FBState; void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres, diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 3355f4c131b..0ffad49ab8f 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -52,7 +52,7 @@ static void draw_line_src16(void *opaque, uint8_t *dst, const uint8_t *src, int bpp = surface_bits_per_pixel(surface); while (width--) { - switch (s->bpp) { + switch (s->config.bpp) { case 8: /* lookup palette starting at video ram base * TODO: cache translation, rather than doing this each time! @@ -91,7 +91,7 @@ static void draw_line_src16(void *opaque, uint8_t *dst, const uint8_t *src, break; } - if (s->pixo == 0) { + if (s->config.pixo == 0) { /* swap to BGR pixel format */ uint8_t tmp = r; r = b; @@ -135,12 +135,12 @@ static void fb_update_display(void *opaque) int src_width = 0; int dest_width = 0; - if (s->lock || !s->xres) { + if (s->lock || !s->config.xres) { return; } - src_width = s->xres * (s->bpp >> 3); - dest_width = s->xres; + src_width = s->config.xres * (s->config.bpp >> 3); + dest_width = s->config.xres; switch (surface_bits_per_pixel(surface)) { case 0: @@ -165,16 +165,18 @@ static void fb_update_display(void *opaque) } if (s->invalidate) { - framebuffer_update_memory_section(&s->fbsection, s->dma_mr, s->base, - s->yres, src_width); + framebuffer_update_memory_section(&s->fbsection, s->dma_mr, + s->config.base, + s->config.yres, src_width); } - framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, + framebuffer_update_display(surface, &s->fbsection, + s->config.xres, s->config.yres, src_width, dest_width, 0, s->invalidate, draw_line_src16, s, &first, &last); if (first >= 0) { - dpy_gfx_update(s->con, 0, first, s->xres, last - first + 1); + dpy_gfx_update(s->con, 0, first, s->config.xres, last - first + 1); } s->invalidate = false; @@ -186,28 +188,28 @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) s->lock = true; - s->xres = ldl_le_phys(&s->dma_as, value); - s->yres = ldl_le_phys(&s->dma_as, value + 4); - s->xres_virtual = ldl_le_phys(&s->dma_as, value + 8); - s->yres_virtual = ldl_le_phys(&s->dma_as, value + 12); - s->bpp = ldl_le_phys(&s->dma_as, value + 20); - s->xoffset = ldl_le_phys(&s->dma_as, value + 24); - s->yoffset = ldl_le_phys(&s->dma_as, value + 28); + s->config.xres = ldl_le_phys(&s->dma_as, value); + s->config.yres = ldl_le_phys(&s->dma_as, value + 4); + s->config.xres_virtual = ldl_le_phys(&s->dma_as, value + 8); + s->config.yres_virtual = ldl_le_phys(&s->dma_as, value + 12); + s->config.bpp = ldl_le_phys(&s->dma_as, value + 20); + s->config.xoffset = ldl_le_phys(&s->dma_as, value + 24); + s->config.yoffset = ldl_le_phys(&s->dma_as, value + 28); - s->base = s->vcram_base | (value & 0xc0000000); - s->base += BCM2835_FB_OFFSET; + s->config.base = s->vcram_base | (value & 0xc0000000); + s->config.base += BCM2835_FB_OFFSET; /* TODO - Manage properly virtual resolution */ - s->pitch = s->xres * (s->bpp >> 3); - s->size = s->yres * s->pitch; + s->pitch = s->config.xres * (s->config.bpp >> 3); + s->size = s->config.yres * s->pitch; stl_le_phys(&s->dma_as, value + 16, s->pitch); - stl_le_phys(&s->dma_as, value + 32, s->base); + stl_le_phys(&s->dma_as, value + 32, s->config.base); stl_le_phys(&s->dma_as, value + 36, s->size); s->invalidate = true; - qemu_console_resize(s->con, s->xres, s->yres); + qemu_console_resize(s->con, s->config.xres, s->config.yres); s->lock = false; } @@ -219,34 +221,34 @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres, /* TODO: input validation! */ if (xres) { - s->xres = *xres; + s->config.xres = *xres; } if (yres) { - s->yres = *yres; + s->config.yres = *yres; } if (xoffset) { - s->xoffset = *xoffset; + s->config.xoffset = *xoffset; } if (yoffset) { - s->yoffset = *yoffset; + s->config.yoffset = *yoffset; } if (bpp) { - s->bpp = *bpp; + s->config.bpp = *bpp; } if (pixo) { - s->pixo = *pixo; + s->config.pixo = *pixo; } if (alpha) { - s->alpha = *alpha; + s->config.alpha = *alpha; } /* TODO - Manage properly virtual resolution */ - s->pitch = s->xres * (s->bpp >> 3); - s->size = s->yres * s->pitch; + s->pitch = s->config.xres * (s->config.bpp >> 3); + s->size = s->config.yres * s->pitch; s->invalidate = true; - qemu_console_resize(s->con, s->xres, s->yres); + qemu_console_resize(s->con, s->config.xres, s->config.yres); s->lock = false; } @@ -312,18 +314,18 @@ static const VMStateDescription vmstate_bcm2835_fb = { VMSTATE_BOOL(lock, BCM2835FBState), VMSTATE_BOOL(invalidate, BCM2835FBState), VMSTATE_BOOL(pending, BCM2835FBState), - VMSTATE_UINT32(xres, BCM2835FBState), - VMSTATE_UINT32(yres, BCM2835FBState), - VMSTATE_UINT32(xres_virtual, BCM2835FBState), - VMSTATE_UINT32(yres_virtual, BCM2835FBState), - VMSTATE_UINT32(xoffset, BCM2835FBState), - VMSTATE_UINT32(yoffset, BCM2835FBState), - VMSTATE_UINT32(bpp, BCM2835FBState), - VMSTATE_UINT32(base, BCM2835FBState), + VMSTATE_UINT32(config.xres, BCM2835FBState), + VMSTATE_UINT32(config.yres, BCM2835FBState), + VMSTATE_UINT32(config.xres_virtual, BCM2835FBState), + VMSTATE_UINT32(config.yres_virtual, BCM2835FBState), + VMSTATE_UINT32(config.xoffset, BCM2835FBState), + VMSTATE_UINT32(config.yoffset, BCM2835FBState), + VMSTATE_UINT32(config.bpp, BCM2835FBState), + VMSTATE_UINT32(config.base, BCM2835FBState), VMSTATE_UINT32(pitch, BCM2835FBState), VMSTATE_UINT32(size, BCM2835FBState), - VMSTATE_UINT32(pixo, BCM2835FBState), - VMSTATE_UINT32(alpha, BCM2835FBState), + VMSTATE_UINT32(config.pixo, BCM2835FBState), + VMSTATE_UINT32(config.alpha, BCM2835FBState), VMSTATE_END_OF_LIST() } }; @@ -349,13 +351,13 @@ static void bcm2835_fb_reset(DeviceState *dev) s->pending = false; - s->xres_virtual = s->xres; - s->yres_virtual = s->yres; - s->xoffset = 0; - s->yoffset = 0; - s->base = s->vcram_base + BCM2835_FB_OFFSET; - s->pitch = s->xres * (s->bpp >> 3); - s->size = s->yres * s->pitch; + s->config.xres_virtual = s->config.xres; + s->config.yres_virtual = s->config.yres; + s->config.xoffset = 0; + s->config.yoffset = 0; + s->config.base = s->vcram_base + BCM2835_FB_OFFSET; + s->pitch = s->config.xres * (s->config.bpp >> 3); + s->size = s->config.yres * s->pitch; s->invalidate = true; s->lock = false; @@ -385,18 +387,20 @@ static void bcm2835_fb_realize(DeviceState *dev, Error **errp) bcm2835_fb_reset(dev); s->con = graphic_console_init(dev, 0, &vgafb_ops, s); - qemu_console_resize(s->con, s->xres, s->yres); + qemu_console_resize(s->con, s->config.xres, s->config.yres); } static Property bcm2835_fb_props[] = { DEFINE_PROP_UINT32("vcram-base", BCM2835FBState, vcram_base, 0),/*required*/ DEFINE_PROP_UINT32("vcram-size", BCM2835FBState, vcram_size, DEFAULT_VCRAM_SIZE), - DEFINE_PROP_UINT32("xres", BCM2835FBState, xres, 640), - DEFINE_PROP_UINT32("yres", BCM2835FBState, yres, 480), - DEFINE_PROP_UINT32("bpp", BCM2835FBState, bpp, 16), - DEFINE_PROP_UINT32("pixo", BCM2835FBState, pixo, 1), /* 1=RGB, 0=BGR */ - DEFINE_PROP_UINT32("alpha", BCM2835FBState, alpha, 2), /* alpha ignored */ + DEFINE_PROP_UINT32("xres", BCM2835FBState, config.xres, 640), + DEFINE_PROP_UINT32("yres", BCM2835FBState, config.yres, 480), + DEFINE_PROP_UINT32("bpp", BCM2835FBState, config.bpp, 16), + DEFINE_PROP_UINT32("pixo", + BCM2835FBState, config.pixo, 1), /* 1=RGB, 0=BGR */ + DEFINE_PROP_UINT32("alpha", + BCM2835FBState, config.alpha, 2), /* alpha ignored */ DEFINE_PROP_END_OF_LIST() }; diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index 70eaafd325f..c79f358702d 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -141,10 +141,10 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) /* Frame buffer */ case 0x00040001: /* Allocate buffer */ - stl_le_phys(&s->dma_as, value + 12, s->fbdev->base); - tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres; - tmp_yres = newyres != NULL ? *newyres : s->fbdev->yres; - tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp; + stl_le_phys(&s->dma_as, value + 12, s->fbdev->config.base); + tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres; + tmp_yres = newyres != NULL ? *newyres : s->fbdev->config.yres; + tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp; stl_le_phys(&s->dma_as, value + 16, tmp_xres * tmp_yres * tmp_bpp / 8); resplen = 8; @@ -157,8 +157,8 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) break; case 0x00040003: /* Get display width/height */ case 0x00040004: - tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres; - tmp_yres = newyres != NULL ? *newyres : s->fbdev->yres; + tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres; + tmp_yres = newyres != NULL ? *newyres : s->fbdev->config.yres; stl_le_phys(&s->dma_as, value + 12, tmp_xres); stl_le_phys(&s->dma_as, value + 16, tmp_yres); resplen = 8; @@ -176,7 +176,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) resplen = 8; break; case 0x00040005: /* Get depth */ - tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp; + tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp; stl_le_phys(&s->dma_as, value + 12, tmp_bpp); resplen = 4; break; @@ -189,7 +189,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) resplen = 4; break; case 0x00040006: /* Get pixel order */ - tmp_pixo = newpixo != NULL ? *newpixo : s->fbdev->pixo; + tmp_pixo = newpixo != NULL ? *newpixo : s->fbdev->config.pixo; stl_le_phys(&s->dma_as, value + 12, tmp_pixo); resplen = 4; break; @@ -202,7 +202,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) resplen = 4; break; case 0x00040007: /* Get alpha */ - tmp_alpha = newalpha != NULL ? *newalpha : s->fbdev->alpha; + tmp_alpha = newalpha != NULL ? *newalpha : s->fbdev->config.alpha; stl_le_phys(&s->dma_as, value + 12, tmp_alpha); resplen = 4; break; @@ -215,14 +215,16 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) resplen = 4; break; case 0x00040008: /* Get pitch */ - tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres; - tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp; + tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres; + tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp; stl_le_phys(&s->dma_as, value + 12, tmp_xres * tmp_bpp / 8); resplen = 4; break; case 0x00040009: /* Get virtual offset */ - tmp_xoffset = newxoffset != NULL ? *newxoffset : s->fbdev->xoffset; - tmp_yoffset = newyoffset != NULL ? *newyoffset : s->fbdev->yoffset; + tmp_xoffset = newxoffset != NULL ? + *newxoffset : s->fbdev->config.xoffset; + tmp_yoffset = newyoffset != NULL ? + *newyoffset : s->fbdev->config.yoffset; stl_le_phys(&s->dma_as, value + 12, tmp_xoffset); stl_le_phys(&s->dma_as, value + 16, tmp_yoffset); resplen = 8; From patchwork Tue Aug 14 14:44:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 144176 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4450827ljj; Tue, 14 Aug 2018 07:44:41 -0700 (PDT) X-Google-Smtp-Source: AA+uWPw3OGeSSWFsDTkoHEkztwoXSq16575Bu5yMfgb9Hph9A+m1jbgrP2UbgH5lFr1xcUJa3u4M X-Received: by 2002:a5d:4acc:: with SMTP id y12-v6mr12801750wrs.132.1534257881092; Tue, 14 Aug 2018 07:44:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534257881; cv=none; d=google.com; s=arc-20160816; b=WreR7LjkfzFFcnzRZJoN4Wwc7TJlKpsxKCfLzE1hvVAqG2JUFIuMiXBBTX/1yvOP7X 62HEAngKC008yqGAbwuLLEZLgNuVzOpw0S59bYb9BJvMlBo1foEEZx7zEj27ROggmIQU Jf4eOO9KuRKF+BaZ2SRQ/ECzmRINhc9s0128nlNRTdu5vzlo1lESmqGbmPSwXoX9RsIl oBCs8xSp9Et75pPMWTSjAjmRaWxQvXqZwubJndwihZ8MDe3W/kPsoM+qneCXJaYHd2Yr IW5guExEFEJfmoYiFwZoSUEKE0FWYUNxNy2wRg/izOCbbUfjhiYqg6stn7DrkSOXcip1 3a/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=RXRtLs1isfZ/FLPN+Wg4DU5nbd0Xrp0RCYvKs05CIF4=; b=EEbBNrX8U3stBVfhSqzU2PirG+A9Vo3/56Vgx2H9hOShkJwIG0/hoFR8TzcciGvvCl HNqLsHUTDDm2LiU/i7cShFxsb1aYqXfJ6MwNa/9jlSwvD6iYbZUHusgj5Avzwk9iFrkP pqkqx3OrvEIM3U7gk+l5XFEVoqkbR1803wtFpYARzj6gRV+c8C98OJGHzvtHjyN6+Rcr AGHYfoPUgZVLPolrXdZmntfJtH1mgqD35PeqaIjHMMEGS+VyjIssBm97g3PubM9uFViK NN97EI5aGxb6iKUa7sr4T7160YduHpNYjK+C05UWFHvGPruOeCN9SyGyOXccz16UKSEi mltQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 35-v6si17891626wrq.89.2018.08.14.07.44.40 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 14 Aug 2018 07:44:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpaYq-0006z0-FZ; Tue, 14 Aug 2018 15:44:40 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 2/8] hw/misc/bcm2835_property: Track fb settings using BCM2835FBConfig Date: Tue, 14 Aug 2018 15:44:30 +0100 Message-Id: <20180814144436.679-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814144436.679-1-peter.maydell@linaro.org> References: <20180814144436.679-1-peter.maydell@linaro.org> Refactor the fb property setting code so that rather than using a set of pointers to local variables to track whether a config value has been updated in the current mbox and if so what its new value is, we just copy all the current settings of the fb at the start, and then update that copy as we go along, before asking the fb to switch to it at the end. Signed-off-by: Peter Maydell --- include/hw/display/bcm2835_fb.h | 4 +- hw/display/bcm2835_fb.c | 27 ++--------- hw/misc/bcm2835_property.c | 80 ++++++++++++++------------------- 3 files changed, 37 insertions(+), 74 deletions(-) -- 2.18.0 Reviewed-by: Richard Henderson diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index 8485825ba5f..b965698d28a 100644 --- a/include/hw/display/bcm2835_fb.h +++ b/include/hw/display/bcm2835_fb.h @@ -53,8 +53,6 @@ typedef struct { uint32_t pitch; } BCM2835FBState; -void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres, - uint32_t *xoffset, uint32_t *yoffset, uint32_t *bpp, - uint32_t *pixo, uint32_t *alpha); +void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig); #endif diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 0ffad49ab8f..8155de5d0b1 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -213,34 +213,13 @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) s->lock = false; } -void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres, - uint32_t *xoffset, uint32_t *yoffset, uint32_t *bpp, - uint32_t *pixo, uint32_t *alpha) +void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig) { s->lock = true; /* TODO: input validation! */ - if (xres) { - s->config.xres = *xres; - } - if (yres) { - s->config.yres = *yres; - } - if (xoffset) { - s->config.xoffset = *xoffset; - } - if (yoffset) { - s->config.yoffset = *yoffset; - } - if (bpp) { - s->config.bpp = *bpp; - } - if (pixo) { - s->config.pixo = *pixo; - } - if (alpha) { - s->config.alpha = *alpha; - } + + s->config = *newconfig; /* TODO - Manage properly virtual resolution */ diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index c79f358702d..df0645d1b84 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -21,11 +21,14 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) uint32_t tmp; int n; uint32_t offset, length, color; - uint32_t xres, yres, xoffset, yoffset, bpp, pixo, alpha; - uint32_t tmp_xres, tmp_yres, tmp_xoffset, tmp_yoffset; - uint32_t tmp_bpp, tmp_pixo, tmp_alpha; - uint32_t *newxres = NULL, *newyres = NULL, *newxoffset = NULL, - *newyoffset = NULL, *newbpp = NULL, *newpixo = NULL, *newalpha = NULL; + + /* + * Copy the current state of the framebuffer config; we will update + * this copy as we process tags and then ask the framebuffer to use + * it at the end. + */ + BCM2835FBConfig fbconfig = s->fbdev->config; + bool fbconfig_updated = false; value &= ~0xf; @@ -141,12 +144,9 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) /* Frame buffer */ case 0x00040001: /* Allocate buffer */ - stl_le_phys(&s->dma_as, value + 12, s->fbdev->config.base); - tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres; - tmp_yres = newyres != NULL ? *newyres : s->fbdev->config.yres; - tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp; + stl_le_phys(&s->dma_as, value + 12, fbconfig.base); stl_le_phys(&s->dma_as, value + 16, - tmp_xres * tmp_yres * tmp_bpp / 8); + fbconfig.xres * fbconfig.yres * fbconfig.bpp / 8); resplen = 8; break; case 0x00048001: /* Release buffer */ @@ -157,10 +157,8 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) break; case 0x00040003: /* Get display width/height */ case 0x00040004: - tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres; - tmp_yres = newyres != NULL ? *newyres : s->fbdev->config.yres; - stl_le_phys(&s->dma_as, value + 12, tmp_xres); - stl_le_phys(&s->dma_as, value + 16, tmp_yres); + stl_le_phys(&s->dma_as, value + 12, fbconfig.xres); + stl_le_phys(&s->dma_as, value + 16, fbconfig.yres); resplen = 8; break; case 0x00044003: /* Test display width/height */ @@ -169,74 +167,64 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) break; case 0x00048003: /* Set display width/height */ case 0x00048004: - xres = ldl_le_phys(&s->dma_as, value + 12); - newxres = &xres; - yres = ldl_le_phys(&s->dma_as, value + 16); - newyres = &yres; + fbconfig.xres = ldl_le_phys(&s->dma_as, value + 12); + fbconfig.yres = ldl_le_phys(&s->dma_as, value + 16); + fbconfig_updated = true; resplen = 8; break; case 0x00040005: /* Get depth */ - tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp; - stl_le_phys(&s->dma_as, value + 12, tmp_bpp); + stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp); resplen = 4; break; case 0x00044005: /* Test depth */ resplen = 4; break; case 0x00048005: /* Set depth */ - bpp = ldl_le_phys(&s->dma_as, value + 12); - newbpp = &bpp; + fbconfig.bpp = ldl_le_phys(&s->dma_as, value + 12); + fbconfig_updated = true; resplen = 4; break; case 0x00040006: /* Get pixel order */ - tmp_pixo = newpixo != NULL ? *newpixo : s->fbdev->config.pixo; - stl_le_phys(&s->dma_as, value + 12, tmp_pixo); + stl_le_phys(&s->dma_as, value + 12, fbconfig.pixo); resplen = 4; break; case 0x00044006: /* Test pixel order */ resplen = 4; break; case 0x00048006: /* Set pixel order */ - pixo = ldl_le_phys(&s->dma_as, value + 12); - newpixo = &pixo; + fbconfig.pixo = ldl_le_phys(&s->dma_as, value + 12); + fbconfig_updated = true; resplen = 4; break; case 0x00040007: /* Get alpha */ - tmp_alpha = newalpha != NULL ? *newalpha : s->fbdev->config.alpha; - stl_le_phys(&s->dma_as, value + 12, tmp_alpha); + stl_le_phys(&s->dma_as, value + 12, fbconfig.alpha); resplen = 4; break; case 0x00044007: /* Test pixel alpha */ resplen = 4; break; case 0x00048007: /* Set alpha */ - alpha = ldl_le_phys(&s->dma_as, value + 12); - newalpha = α + fbconfig.alpha = ldl_le_phys(&s->dma_as, value + 12); + fbconfig_updated = true; resplen = 4; break; case 0x00040008: /* Get pitch */ - tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres; - tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp; - stl_le_phys(&s->dma_as, value + 12, tmp_xres * tmp_bpp / 8); + stl_le_phys(&s->dma_as, value + 12, + fbconfig.xres * fbconfig.bpp / 8); resplen = 4; break; case 0x00040009: /* Get virtual offset */ - tmp_xoffset = newxoffset != NULL ? - *newxoffset : s->fbdev->config.xoffset; - tmp_yoffset = newyoffset != NULL ? - *newyoffset : s->fbdev->config.yoffset; - stl_le_phys(&s->dma_as, value + 12, tmp_xoffset); - stl_le_phys(&s->dma_as, value + 16, tmp_yoffset); + stl_le_phys(&s->dma_as, value + 12, fbconfig.xoffset); + stl_le_phys(&s->dma_as, value + 16, fbconfig.yoffset); resplen = 8; break; case 0x00044009: /* Test virtual offset */ resplen = 8; break; case 0x00048009: /* Set virtual offset */ - xoffset = ldl_le_phys(&s->dma_as, value + 12); - newxoffset = &xoffset; - yoffset = ldl_le_phys(&s->dma_as, value + 16); - newyoffset = &yoffset; + fbconfig.xoffset = ldl_le_phys(&s->dma_as, value + 12); + fbconfig.yoffset = ldl_le_phys(&s->dma_as, value + 16); + fbconfig_updated = true; resplen = 8; break; case 0x0004000a: /* Get/Test/Set overscan */ @@ -287,10 +275,8 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) } /* Reconfigure framebuffer if required */ - if (newxres || newyres || newxoffset || newyoffset || newbpp || newpixo - || newalpha) { - bcm2835_fb_reconfigure(s->fbdev, newxres, newyres, newxoffset, - newyoffset, newbpp, newpixo, newalpha); + if (fbconfig_updated) { + bcm2835_fb_reconfigure(s->fbdev, &fbconfig); } /* Buffer response code */ From patchwork Tue Aug 14 14:44:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 144177 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4450846ljj; Tue, 14 Aug 2018 07:44:42 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyvgzP2R1twqou9bgP1OZZfhvdLkeuNxxI+PmaGMVKjHDslck1DvPb/sI3avt4VCBbkCjiV X-Received: by 2002:adf:f148:: with SMTP id y8-v6mr14089372wro.134.1534257881941; Tue, 14 Aug 2018 07:44:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534257881; cv=none; d=google.com; s=arc-20160816; b=j1hACVDMbtWlK9pgI9XvmAt33nUss2OeKq/ADPcCUjjxoRt5d9v83jsjMNV7Z6YPwy rVe+nDnZp52MChTB4KnopKj0ulQmCghx3yU8gcZDEIfKmU8HgkbqSDH94NdDW2fdlXRa nlnoAPMMscRdRWGfNDSPNRpQODyUGgOrz8uoppBiE4RMxxXRXJWJadpZ0BshiwoGreG/ uuvdLHePM0DxuA5BqhKgxPOI104acLZNX6TMaIwJ1IRKtcga/nH+NgYECkwy812+zyub 642E+fQQPxxxSk7gQWvxUXKBcODkyewx0hdmaFC0dA+TP9fC1zUgR1S8mC+ygDshyEZV 9jAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=/TTtw87KR6Pwotwq7I+AirjS//9tpwmtyESSaJWIKxk=; b=UxmdNetklKjK/D8OjfQSWciIKjUax6Gpv7DekvfqZw02JlFsyOgX3nHSeQMqpThGvq l1TKupCYNrGBdrNnjRvBgepQxgqliM6mdvye206DZGgzyd+Q+m7Ii+HdiLBvGry4VUzV 8X6vg8xTZNa521emJmgba9i56B/FBw5zvtlxn8Oea8Wtx0Ae2TRT5C6a8VbHG6Yj+q+o esBeBpBkyLt1rMdYV02AEDoK/PZuKHqhfLm2mtnP5YXaHuGXoKk4WWGuzvHP22mPDnfD WKt+9M9SaFnY92OLGQPQqVetrD3fbNj1xYg4DrM1kSIkN3MQ/nmzO9V9yb5ixncoV8eM AE1g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id k9-v6si14622855wrl.87.2018.08.14.07.44.41 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 14 Aug 2018 07:44:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpaYr-0006zl-FQ; Tue, 14 Aug 2018 15:44:41 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 3/8] hw/display/bcm2835_fb: Drop unused size and pitch fields Date: Tue, 14 Aug 2018 15:44:31 +0100 Message-Id: <20180814144436.679-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814144436.679-1-peter.maydell@linaro.org> References: <20180814144436.679-1-peter.maydell@linaro.org> The BCM2835FBState struct has a 'pitch' field which is a cached copy of xres * (bpp >> 3), and a 'size' field which is a cached copy of pitch * yres. However we don't actually do anything with these fields; delete them. We retain the now-unused slots in the VMState struct for migration compatibility. Signed-off-by: Peter Maydell --- include/hw/display/bcm2835_fb.h | 4 ---- hw/display/bcm2835_fb.c | 19 ++++++++----------- 2 files changed, 8 insertions(+), 15 deletions(-) -- 2.18.0 Reviewed-by: Richard Henderson diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index b965698d28a..69cbf2d1fd9 100644 --- a/include/hw/display/bcm2835_fb.h +++ b/include/hw/display/bcm2835_fb.h @@ -47,10 +47,6 @@ typedef struct { bool lock, invalidate, pending; BCM2835FBConfig config; - - /* These are just cached values calculated from the config settings */ - uint32_t size; - uint32_t pitch; } BCM2835FBState; void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig); diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 8155de5d0b1..9faabf0d0b4 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -184,6 +184,9 @@ static void fb_update_display(void *opaque) static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) { + uint32_t pitch; + uint32_t size; + value &= ~0xf; s->lock = true; @@ -201,12 +204,12 @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) /* TODO - Manage properly virtual resolution */ - s->pitch = s->config.xres * (s->config.bpp >> 3); - s->size = s->config.yres * s->pitch; + pitch = s->config.xres * (s->config.bpp >> 3); + size = s->config.yres * pitch; - stl_le_phys(&s->dma_as, value + 16, s->pitch); + stl_le_phys(&s->dma_as, value + 16, pitch); stl_le_phys(&s->dma_as, value + 32, s->config.base); - stl_le_phys(&s->dma_as, value + 36, s->size); + stl_le_phys(&s->dma_as, value + 36, size); s->invalidate = true; qemu_console_resize(s->con, s->config.xres, s->config.yres); @@ -223,9 +226,6 @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig) /* TODO - Manage properly virtual resolution */ - s->pitch = s->config.xres * (s->config.bpp >> 3); - s->size = s->config.yres * s->pitch; - s->invalidate = true; qemu_console_resize(s->con, s->config.xres, s->config.yres); s->lock = false; @@ -301,8 +301,7 @@ static const VMStateDescription vmstate_bcm2835_fb = { VMSTATE_UINT32(config.yoffset, BCM2835FBState), VMSTATE_UINT32(config.bpp, BCM2835FBState), VMSTATE_UINT32(config.base, BCM2835FBState), - VMSTATE_UINT32(pitch, BCM2835FBState), - VMSTATE_UINT32(size, BCM2835FBState), + VMSTATE_UNUSED(8), /* Was pitch and size */ VMSTATE_UINT32(config.pixo, BCM2835FBState), VMSTATE_UINT32(config.alpha, BCM2835FBState), VMSTATE_END_OF_LIST() @@ -335,8 +334,6 @@ static void bcm2835_fb_reset(DeviceState *dev) s->config.xoffset = 0; s->config.yoffset = 0; s->config.base = s->vcram_base + BCM2835_FB_OFFSET; - s->pitch = s->config.xres * (s->config.bpp >> 3); - s->size = s->config.yres * s->pitch; s->invalidate = true; s->lock = false; From patchwork Tue Aug 14 14:44:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 144178 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4450865ljj; Tue, 14 Aug 2018 07:44:43 -0700 (PDT) X-Google-Smtp-Source: AA+uWPwZls+ChfLCP8JZM8q2gCIbr+UfKy1GIIBudZwyVnDVSs082biSYJqNBb65O2Wd6eykrnTD X-Received: by 2002:a5d:4542:: with SMTP id p2-v6mr13669935wrr.191.1534257882995; Tue, 14 Aug 2018 07:44:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534257882; cv=none; d=google.com; s=arc-20160816; b=GDzLbUUxb7bk8Ce7gWZMr1N4J0uv6+mRNBhWHWyTuw2DZ7tecTk0M3GLScJ0hKdt30 CyNu+bwrMDcioNP12QQwfbXMcEnhKfPJS99Sc23sGYZQ1OPlkAdWcoVZoiTd/7LapUby qqOOaGPC3sHPwDOskulGKS4M52QCp+HibcFfowpLZg4CmfXJhWwBvxYeWhWFKwvX8Mym +1wxh91GAa4mZVtbdttscfj/pR1ElPKGtTe00IXEmEI0TvDGBeYiFzttcO2m1w+xzQey yunJ1rsMZeEv6ValI8y9L7KJ44Wth/bH2y09KUnhBjQ9AoM+rASWYXylhmoil1YqUkpq pTdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=ciU2Co1/BZetVVurj7ZzAh2mRZuWYKajyImfIxqeNZo=; b=JxbCUBSLG4rEej2NsVExO2d+PXYxklyndGomxyzeILj7lcP+ypKhcUArksvMQ/S82J i1e+/jAfaJtJhMa1ZW/CRXQ6mDfoKhmXoVn1dVNvOvIAduqqwPMpGz+5AQ9qvuMd2OBq qzb66XCQlHgTenIdGfHUciRTyV1sk9pxJoBGEEJfPLQRWGeJKcxOdFlsAxc2MYuoxfaz kfaMwbeclqhO//8XRZDpUV+Lj8kBfcp3hnPXV5nYRq9u9LW2wKnjWmy5XVpVvJsOLFSL yfPnHJXCtdA+II6bKzLGnhXyU0tYVKB9+pLzfn4Ta8F/As82o+jGbQVTVe6eXNZSVaCT 6BzQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id v142-v6si9579137wmv.198.2018.08.14.07.44.42 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 14 Aug 2018 07:44:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpaYs-000703-GA; Tue, 14 Aug 2018 15:44:42 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 4/8] hw/display/bcm2835_fb: Reset resolution, etc correctly Date: Tue, 14 Aug 2018 15:44:32 +0100 Message-Id: <20180814144436.679-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814144436.679-1-peter.maydell@linaro.org> References: <20180814144436.679-1-peter.maydell@linaro.org> The bcm2835_fb's initial resolution and other parameters are set via QOM properties. We should reset to those initial values on device reset, which means we need to save the QOM property values somewhere that they are not overwritten by guest changes to the framebuffer configuration. Signed-off-by: Peter Maydell --- include/hw/display/bcm2835_fb.h | 1 + hw/display/bcm2835_fb.c | 27 +++++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) -- 2.18.0 Reviewed-by: Richard Henderson diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index 69cbf2d1fd9..374de546121 100644 --- a/include/hw/display/bcm2835_fb.h +++ b/include/hw/display/bcm2835_fb.h @@ -47,6 +47,7 @@ typedef struct { bool lock, invalidate, pending; BCM2835FBConfig config; + BCM2835FBConfig initial_config; } BCM2835FBState; void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig); diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 9faabf0d0b4..d95686c74c8 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -329,11 +329,7 @@ static void bcm2835_fb_reset(DeviceState *dev) s->pending = false; - s->config.xres_virtual = s->config.xres; - s->config.yres_virtual = s->config.yres; - s->config.xoffset = 0; - s->config.yoffset = 0; - s->config.base = s->vcram_base + BCM2835_FB_OFFSET; + s->config = s->initial_config; s->invalidate = true; s->lock = false; @@ -357,6 +353,13 @@ static void bcm2835_fb_realize(DeviceState *dev, Error **errp) return; } + /* Fill in the parts of initial_config that are not set by QOM properties */ + s->initial_config.xres_virtual = s->initial_config.xres; + s->initial_config.yres_virtual = s->initial_config.yres; + s->initial_config.xoffset = 0; + s->initial_config.yoffset = 0; + s->initial_config.base = s->vcram_base + BCM2835_FB_OFFSET; + s->dma_mr = MEMORY_REGION(obj); address_space_init(&s->dma_as, s->dma_mr, NULL); @@ -370,13 +373,13 @@ static Property bcm2835_fb_props[] = { DEFINE_PROP_UINT32("vcram-base", BCM2835FBState, vcram_base, 0),/*required*/ DEFINE_PROP_UINT32("vcram-size", BCM2835FBState, vcram_size, DEFAULT_VCRAM_SIZE), - DEFINE_PROP_UINT32("xres", BCM2835FBState, config.xres, 640), - DEFINE_PROP_UINT32("yres", BCM2835FBState, config.yres, 480), - DEFINE_PROP_UINT32("bpp", BCM2835FBState, config.bpp, 16), - DEFINE_PROP_UINT32("pixo", - BCM2835FBState, config.pixo, 1), /* 1=RGB, 0=BGR */ - DEFINE_PROP_UINT32("alpha", - BCM2835FBState, config.alpha, 2), /* alpha ignored */ + DEFINE_PROP_UINT32("xres", BCM2835FBState, initial_config.xres, 640), + DEFINE_PROP_UINT32("yres", BCM2835FBState, initial_config.yres, 480), + DEFINE_PROP_UINT32("bpp", BCM2835FBState, initial_config.bpp, 16), + DEFINE_PROP_UINT32("pixo", BCM2835FBState, + initial_config.pixo, 1), /* 1=RGB, 0=BGR */ + DEFINE_PROP_UINT32("alpha", BCM2835FBState, + initial_config.alpha, 2), /* alpha ignored */ DEFINE_PROP_END_OF_LIST() }; From patchwork Tue Aug 14 14:44:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 144179 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4450884ljj; Tue, 14 Aug 2018 07:44:44 -0700 (PDT) X-Google-Smtp-Source: AA+uWPww9AiQLn/inHdiYIQ6W7feBqB9i9y+tOZeZxpKxQRe/KQFG+zZndLtjFQZ+TpKlRDyAy1D X-Received: by 2002:a5d:494c:: with SMTP id r12-v6mr4616400wrs.66.1534257884075; Tue, 14 Aug 2018 07:44:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534257884; cv=none; d=google.com; s=arc-20160816; b=BJXpY1knChniO3N6mGdRGjnuvtK2Z3U6gNUjOy/++ogy2ANxXL2PD+OMyNeIXpOmjv aX6wVhkcSjvlxPiu2NSkdGGkpye9tA2Rm2s/oSUvoshVq770EnND+mY+u4tqJwzAuzsi nXq/LLLXdY06n3tyR/wgE7uo7a6VVX5zVLfW/qtpDrADuHGfm4KIL+jPQkOpUu25ikV4 MotvBKLp1ks4ZtszA9mXYUM30peU4a42Xgv717DWWmFujNoydSh4x/b/qEBcKGozfAE+ bzDN6OY45iX+6VXm4py0kK9qV71jN9eiPUyknNq0Z0aYjJ8Wa/1hMEv4VDQoNAgClEVk fIMg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=oN3MGkYdo1Vzd3Kl0F3+7Ar5cGYbBsVawLnTwr/nf7M=; b=JBBnspaSjD8Hy2Q+g/bXcfv3MXEdieoE1YfkEIaYJE8Ac3nPRFUwLzB3R07RKOLJvS vtmH3PEQxg5jXfNj6X2pErPuCq62aTPbdp6aa3+YreUyFafYjOgCK+FnZ1axmrP71Abz GKoJw0Ih8sjYaCS1Jh2/VBVyOAPkFSmGx1bsi12HG2muX9qeNuljb0IF+DG82GKOhfsT I0KycvMU74oKQvcmougk/G5Msz8CpqYDex67SIYAVSQ4rvsefUmW2As91nKYtGADMAIU SYvaWFuXR/vPYXnjsEO4OWtufxAGpV1FmqNqPtZcN9xdo/G7IUrgLuM9VtJuz2OUqR++ Se9g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id d184-v6si11710061wme.56.2018.08.14.07.44.43 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 14 Aug 2018 07:44:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpaYt-00070p-IR; Tue, 14 Aug 2018 15:44:43 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 5/8] hw/display/bcm2835_fb: Abstract out calculation of pitch, size Date: Tue, 14 Aug 2018 15:44:33 +0100 Message-Id: <20180814144436.679-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814144436.679-1-peter.maydell@linaro.org> References: <20180814144436.679-1-peter.maydell@linaro.org> Abstract out the calculation of the pitch and size of the framebuffer into functions that operate on the BCM2835FBConfig struct -- these are about to get a little more complicated when we add support for virtual and physical sizes differing. Signed-off-by: Peter Maydell --- include/hw/display/bcm2835_fb.h | 22 ++++++++++++++++++++++ hw/display/bcm2835_fb.c | 6 +++--- hw/misc/bcm2835_property.c | 4 ++-- 3 files changed, 27 insertions(+), 5 deletions(-) -- 2.18.0 Reviewed-by: Richard Henderson diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index 374de546121..95bcec7fe33 100644 --- a/include/hw/display/bcm2835_fb.h +++ b/include/hw/display/bcm2835_fb.h @@ -52,4 +52,26 @@ typedef struct { void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig); +/** + * bcm2835_fb_get_pitch: return number of bytes per line of the framebuffer + * @config: configuration info for the framebuffer + * + * Return the number of bytes per line of the framebuffer, ie the number + * that must be added to a pixel address to get the address of the pixel + * directly below it on screen. + */ +static inline uint32_t bcm2835_fb_get_pitch(BCM2835FBConfig *config) +{ + return config->xres * (config->bpp >> 3); +} + +/** + * bcm2835_fb_get_size: return total size of framebuffer in bytes + * @config: configuration info for the framebuffer + */ +static inline uint32_t bcm2835_fb_get_size(BCM2835FBConfig *config) +{ + return config->yres * bcm2835_fb_get_pitch(config); +} + #endif diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index d95686c74c8..a6c0a0cc942 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -139,7 +139,7 @@ static void fb_update_display(void *opaque) return; } - src_width = s->config.xres * (s->config.bpp >> 3); + src_width = bcm2835_fb_get_pitch(&s->config); dest_width = s->config.xres; switch (surface_bits_per_pixel(surface)) { @@ -204,8 +204,8 @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) /* TODO - Manage properly virtual resolution */ - pitch = s->config.xres * (s->config.bpp >> 3); - size = s->config.yres * pitch; + pitch = bcm2835_fb_get_pitch(&s->config); + size = bcm2835_fb_get_size(&s->config); stl_le_phys(&s->dma_as, value + 16, pitch); stl_le_phys(&s->dma_as, value + 32, s->config.base); diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index df0645d1b84..c8c4979bd26 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -146,7 +146,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) case 0x00040001: /* Allocate buffer */ stl_le_phys(&s->dma_as, value + 12, fbconfig.base); stl_le_phys(&s->dma_as, value + 16, - fbconfig.xres * fbconfig.yres * fbconfig.bpp / 8); + bcm2835_fb_get_size(&fbconfig)); resplen = 8; break; case 0x00048001: /* Release buffer */ @@ -210,7 +210,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) break; case 0x00040008: /* Get pitch */ stl_le_phys(&s->dma_as, value + 12, - fbconfig.xres * fbconfig.bpp / 8); + bcm2835_fb_get_pitch(&fbconfig)); resplen = 4; break; case 0x00040009: /* Get virtual offset */ From patchwork Tue Aug 14 14:44:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 144180 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4450902ljj; Tue, 14 Aug 2018 07:44:45 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyfip0Sjr5xkw3wspZERUI+SgM6OdXwMPbbzhGJBZQDPUQ/LXCURa7CCZInQQzEnVtA/zsc X-Received: by 2002:a5d:434c:: with SMTP id u12-v6mr13199863wrr.189.1534257885045; Tue, 14 Aug 2018 07:44:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534257885; cv=none; d=google.com; s=arc-20160816; b=yjI4KEajsEP5gAx+EiJDJ5OT2aPTHaCKLQeN2fTsnbXZZkdjNwu4JxZ8WfGauGNbKZ rXudwMwLoeCeiBeQIW34X2Ble1FZffwSFAX65RrlQYAfzboFAknax0NhWnSKaxt+/ClO eWcsChQ77Q7OvltDkmPpSzx9ofHYm7R9G37JtQ8QplaRY/gaoG6ZC43JFkOZMvoIoxeu snTMG+BG73Cp0GA2knL3tJ5ZVmVvWe5pDuZUTAG3yUAhsSMvpWXz/Mq0DyhSdhzA9u6z 9V/Tz0lq3UvGyp7glOIDpXTiXqLxJTrWPoYUodS8jrZMVS9/aW9vfOCpAhk5ovwqEBXv a1uw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=0/43Fy9PhYaWY6nIwV+513sXRmA+6FmsW4hAO2XFnaY=; b=DjzRQfxCliJ+0hDs4yGxIk2kBv4wEf/1Aa3y4cRMK/t+Mq2LJaG0E5+1LQt5LmHrpi 8dEzxpQBwjS0mZpUEYUCdcGqhK/jWBDdePZzADVpU754F97bvqOLALRIhvWchT44z8m5 uA+vnIp+gXPUI5MA9lZZq/rJWUzZpn5c6VHIkeCNjw533Fzyt8T/P2XvS0MRN6sn1w/Y cO+jTurF+9pxtMwrn+7RyX4LhcKFC6B2ocWYiwR8qGTkyDAWfqvQbYJ8u7UGB1wJnGc/ qA1zU9BKQvjNkVJdzt137OiMyZ6wS+5pAjgWhgxY9G4tcOjvZQY3F0e9vGwIrv1Xe74Y TWxg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id y4-v6si15994340wrd.181.2018.08.14.07.44.44 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 14 Aug 2018 07:44:45 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpaYu-000717-Hk; Tue, 14 Aug 2018 15:44:44 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 6/8] hw/display/bcm2835_fb: Fix handling of virtual framebuffer Date: Tue, 14 Aug 2018 15:44:34 +0100 Message-Id: <20180814144436.679-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814144436.679-1-peter.maydell@linaro.org> References: <20180814144436.679-1-peter.maydell@linaro.org> The raspi framebuffir in bcm2835_fb supports the definition of a virtual "viewport", which is smaller than the full physical framebuffer size and at an adjustable offset within it. Only the viewport area is sent to the screen. This allows the guest to do things like double buffering, or scrolling by adjusting the viewport origin. Currently QEMU doesn't implement this at all. Add support for this feature: * the property mailbox code needs to distinguish the virtual width/height from the physical width/height * the framebuffer code needs to do something with the virtual width/height/origin information Note that the wiki documentation on the semantics of the virtual and physical height and width has it the wrong way around -- the virtual size is the size of the allocated buffer, and the physical size is the size of the display, so the virtual size is always the same as or larger than the physical. If the viewport size is set smaller than the physical screen size, we ignore the viewport settings completely and just display the physical screen area. Signed-off-by: Peter Maydell --- include/hw/display/bcm2835_fb.h | 6 ++++-- hw/display/bcm2835_fb.c | 28 ++++++++++++++++++++++------ hw/misc/bcm2835_property.c | 21 +++++++++++++++------ 3 files changed, 41 insertions(+), 14 deletions(-) -- 2.18.0 Reviewed-by: Richard Henderson diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index 95bcec7fe33..d992c60c120 100644 --- a/include/hw/display/bcm2835_fb.h +++ b/include/hw/display/bcm2835_fb.h @@ -62,7 +62,8 @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig); */ static inline uint32_t bcm2835_fb_get_pitch(BCM2835FBConfig *config) { - return config->xres * (config->bpp >> 3); + uint32_t xres = MAX(config->xres, config->xres_virtual); + return xres * (config->bpp >> 3); } /** @@ -71,7 +72,8 @@ static inline uint32_t bcm2835_fb_get_pitch(BCM2835FBConfig *config) */ static inline uint32_t bcm2835_fb_get_size(BCM2835FBConfig *config) { - return config->yres * bcm2835_fb_get_pitch(config); + uint32_t yres = MAX(config->yres, config->yres_virtual); + return yres * bcm2835_fb_get_pitch(config); } #endif diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index a6c0a0cc942..76a10072b46 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -126,6 +126,18 @@ static void draw_line_src16(void *opaque, uint8_t *dst, const uint8_t *src, } } +static bool fb_use_offsets(BCM2835FBConfig *config) +{ + /* + * Return true if we should use the viewport offsets. + * Experimentally, the hardware seems to do this only if the + * viewport size is larger than the physical screen. (It doesn't + * prevent the guest setting this silly viewport setting, though...) + */ + return config->xres_virtual > config->xres && + config->yres_virtual > config->yres; +} + static void fb_update_display(void *opaque) { BCM2835FBState *s = opaque; @@ -134,12 +146,18 @@ static void fb_update_display(void *opaque) int last = 0; int src_width = 0; int dest_width = 0; + uint32_t xoff = 0, yoff = 0; if (s->lock || !s->config.xres) { return; } src_width = bcm2835_fb_get_pitch(&s->config); + if (fb_use_offsets(&s->config)) { + xoff = s->config.xoffset; + yoff = s->config.yoffset; + } + dest_width = s->config.xres; switch (surface_bits_per_pixel(surface)) { @@ -165,8 +183,9 @@ static void fb_update_display(void *opaque) } if (s->invalidate) { + hwaddr base = s->config.base + xoff + yoff * src_width; framebuffer_update_memory_section(&s->fbsection, s->dma_mr, - s->config.base, + base, s->config.yres, src_width); } @@ -176,7 +195,8 @@ static void fb_update_display(void *opaque) draw_line_src16, s, &first, &last); if (first >= 0) { - dpy_gfx_update(s->con, 0, first, s->config.xres, last - first + 1); + dpy_gfx_update(s->con, 0, first, s->config.xres, + last - first + 1); } s->invalidate = false; @@ -202,8 +222,6 @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) s->config.base = s->vcram_base | (value & 0xc0000000); s->config.base += BCM2835_FB_OFFSET; - /* TODO - Manage properly virtual resolution */ - pitch = bcm2835_fb_get_pitch(&s->config); size = bcm2835_fb_get_size(&s->config); @@ -224,8 +242,6 @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig) s->config = *newconfig; - /* TODO - Manage properly virtual resolution */ - s->invalidate = true; qemu_console_resize(s->con, s->config.xres, s->config.yres); s->lock = false; diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index c8c4979bd26..e3ab677891b 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -155,23 +155,32 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) case 0x00040002: /* Blank screen */ resplen = 4; break; - case 0x00040003: /* Get display width/height */ - case 0x00040004: + case 0x00040003: /* Get physical display width/height */ stl_le_phys(&s->dma_as, value + 12, fbconfig.xres); stl_le_phys(&s->dma_as, value + 16, fbconfig.yres); resplen = 8; break; - case 0x00044003: /* Test display width/height */ - case 0x00044004: + case 0x00040004: /* Get virtual display width/height */ + stl_le_phys(&s->dma_as, value + 12, fbconfig.xres_virtual); + stl_le_phys(&s->dma_as, value + 16, fbconfig.yres_virtual); resplen = 8; break; - case 0x00048003: /* Set display width/height */ - case 0x00048004: + case 0x00044003: /* Test physical display width/height */ + case 0x00044004: /* Test virtual display width/height */ + resplen = 8; + break; + case 0x00048003: /* Set physical display width/height */ fbconfig.xres = ldl_le_phys(&s->dma_as, value + 12); fbconfig.yres = ldl_le_phys(&s->dma_as, value + 16); fbconfig_updated = true; resplen = 8; break; + case 0x00048004: /* Set virtual display width/height */ + fbconfig.xres_virtual = ldl_le_phys(&s->dma_as, value + 12); + fbconfig.yres_virtual = ldl_le_phys(&s->dma_as, value + 16); + fbconfig_updated = true; + resplen = 8; + break; case 0x00040005: /* Get depth */ stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp); resplen = 4; From patchwork Tue Aug 14 14:44:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 144181 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4450926ljj; Tue, 14 Aug 2018 07:44:46 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyj/jAaBC7aq/Z+0NJrOMZvGa5tIAXdBFf1TceQTxfC0Mo7eRFkeZzMOZ2guYf3qD2St6oD X-Received: by 2002:a1c:6c03:: with SMTP id h3-v6mr10470826wmc.38.1534257886049; Tue, 14 Aug 2018 07:44:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534257886; cv=none; d=google.com; s=arc-20160816; b=mraPJ8r37OP8/fVio+hIqBLKE9I+A92q99/nTv3HQJWm8COQvR1AHOS9wej8WRPamL onUOzLHwrLntvS5IoSZAvxkdPeByp88DTf0DIc9TVNv9KskYrp/PJ9A+Uhbsy1I0rTqg K+7MLLPRI3j62ek9QKN/hf/ehtgvXHHFmMgrNwcWtrWpW+/O4O6qkMsMq+lAodOow/jj HAlX+jrjsicKrexPP8/gUMfYjlQouclu+0BlcmDjexQefuz8RhdQdLF4iRNKXF8UzDpr EAc8bIa97MEHPaSxSGzjUyXAIbBTC0ri6RbQ8xukS6qpJwPm+6rHc794VQgkAnk2qN3J e90w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=HJzEcUuMelrOgp0W/yse7R5pFuMoBHKJZ6WBYDOFTqQ=; b=CASD3DBRqVS6ClncWyfZO4G5KMTyMnoQw0WYuPZzBbUC3F5WXhfwA7FngZviXfDDaN RvlaCvh11ZnOIXw+nJYY46gHUHmRUOdFm6t+XW237/X+kzWy6+fblWp60K2phtE+8yPS ekTPggV1lcD7TEMGUUvuRTasJP0CtF8GqecbNbwQRTGZQfZbZ/mf9+2rgMM+zMYaZHps 0n9PE9qirBjDnEMCkBt1Tgt+gZkrmDsF1AekW/QaudoknYDiQ6JJX1lAVvLUAE5Zxjls HOGuGzlI/Wh3uRkHc37epf6yRuDc+L3BDtN+DzsUbw3eqcPE2Iz4aEmdg0CsMEpSP62Y pmOQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id f1-v6si16074856wrh.303.2018.08.14.07.44.45 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 14 Aug 2018 07:44:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpaYv-000720-Gv; Tue, 14 Aug 2018 15:44:45 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 7/8] hw/display/bcm2835_fb: Validate config settings Date: Tue, 14 Aug 2018 15:44:35 +0100 Message-Id: <20180814144436.679-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814144436.679-1-peter.maydell@linaro.org> References: <20180814144436.679-1-peter.maydell@linaro.org> Validate the config settings that the guest tries to set. The wiki page documentation is not really accurate here: generally rather than failing requests to set bad parameters, the hardware will just clip them to something sensible. Validate the most important parameters: sizes and the viewport offsets. This prevents the framebuffer code from trying to read out-of-range memory. In the property handling code, we validate the new parameters every time we encounter a tag that sets them. This means we validate the config multiple times if the request includes multiple config-setting tags, but the code would require significant restructuring to do a validation only once but still return the clipped settings for get-parameter tags and the buffer allocation tag. Validation of settings made via the older bcm2835_fb_mbox_push() function will be done in the next commit. Signed-off-by: Peter Maydell --- include/hw/display/bcm2835_fb.h | 8 +++++ hw/display/bcm2835_fb.c | 48 +++++++++++++++++++++++++++-- hw/misc/bcm2835_property.c | 54 ++++++++++++++++----------------- 3 files changed, 81 insertions(+), 29 deletions(-) -- 2.18.0 Reviewed-by: Richard Henderson diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index d992c60c120..228988ba056 100644 --- a/include/hw/display/bcm2835_fb.h +++ b/include/hw/display/bcm2835_fb.h @@ -76,4 +76,12 @@ static inline uint32_t bcm2835_fb_get_size(BCM2835FBConfig *config) return yres * bcm2835_fb_get_pitch(config); } +/** + * bcm2835_fb_validate_config: check provided config + * + * Validates the configuration information provided by the guest and + * adjusts it if necessary. + */ +void bcm2835_fb_validate_config(BCM2835FBConfig *config); + #endif diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 76a10072b46..3edb8b5cfcb 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -34,6 +34,13 @@ #define DEFAULT_VCRAM_SIZE 0x4000000 #define BCM2835_FB_OFFSET 0x00100000 +/* Maximum permitted framebuffer size; experimentally determined on an rpi2 */ +#define XRES_MAX 3840 +#define YRES_MAX 2560 +/* Framebuffer size used if guest requests zero size */ +#define XRES_SMALL 592 +#define YRES_SMALL 488 + static void fb_invalidate_display(void *opaque) { BCM2835FBState *s = BCM2835_FB(opaque); @@ -202,6 +209,45 @@ static void fb_update_display(void *opaque) s->invalidate = false; } +void bcm2835_fb_validate_config(BCM2835FBConfig *config) +{ + /* + * Validate the config, and clip any bogus values into range, + * as the hardware does. Note that fb_update_display() relies on + * this happening to prevent it from performing out-of-range + * accesses on redraw. + */ + config->xres = MIN(config->xres, XRES_MAX); + config->xres_virtual = MIN(config->xres_virtual, XRES_MAX); + config->yres = MIN(config->yres, YRES_MAX); + config->yres_virtual = MIN(config->yres_virtual, YRES_MAX); + + /* + * These are not minima: a 40x40 framebuffer will be accepted. + * They're only used as defaults if the guest asks for zero size. + */ + if (config->xres == 0) { + config->xres = XRES_SMALL; + } + if (config->yres == 0) { + config->yres = YRES_SMALL; + } + if (config->xres_virtual == 0) { + config->xres_virtual = config->xres; + } + if (config->yres_virtual == 0) { + config->yres_virtual = config->yres; + } + + if (fb_use_offsets(config)) { + /* Clip the offsets so the viewport is within the physical screen */ + config->xoffset = MIN(config->xoffset, + config->xres_virtual - config->xres); + config->yoffset = MIN(config->yoffset, + config->yres_virtual - config->yres); + } +} + static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) { uint32_t pitch; @@ -238,8 +284,6 @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig) { s->lock = true; - /* TODO: input validation! */ - s->config = *newconfig; s->invalidate = true; diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index e3ab677891b..145427ae0f8 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -155,16 +155,6 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) case 0x00040002: /* Blank screen */ resplen = 4; break; - case 0x00040003: /* Get physical display width/height */ - stl_le_phys(&s->dma_as, value + 12, fbconfig.xres); - stl_le_phys(&s->dma_as, value + 16, fbconfig.yres); - resplen = 8; - break; - case 0x00040004: /* Get virtual display width/height */ - stl_le_phys(&s->dma_as, value + 12, fbconfig.xres_virtual); - stl_le_phys(&s->dma_as, value + 16, fbconfig.yres_virtual); - resplen = 8; - break; case 0x00044003: /* Test physical display width/height */ case 0x00044004: /* Test virtual display width/height */ resplen = 8; @@ -172,29 +162,35 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) case 0x00048003: /* Set physical display width/height */ fbconfig.xres = ldl_le_phys(&s->dma_as, value + 12); fbconfig.yres = ldl_le_phys(&s->dma_as, value + 16); + bcm2835_fb_validate_config(&fbconfig); fbconfig_updated = true; + /* fall through */ + case 0x00040003: /* Get physical display width/height */ + stl_le_phys(&s->dma_as, value + 12, fbconfig.xres); + stl_le_phys(&s->dma_as, value + 16, fbconfig.yres); resplen = 8; break; case 0x00048004: /* Set virtual display width/height */ fbconfig.xres_virtual = ldl_le_phys(&s->dma_as, value + 12); fbconfig.yres_virtual = ldl_le_phys(&s->dma_as, value + 16); + bcm2835_fb_validate_config(&fbconfig); fbconfig_updated = true; + /* fall through */ + case 0x00040004: /* Get virtual display width/height */ + stl_le_phys(&s->dma_as, value + 12, fbconfig.xres_virtual); + stl_le_phys(&s->dma_as, value + 16, fbconfig.yres_virtual); resplen = 8; break; - case 0x00040005: /* Get depth */ - stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp); - resplen = 4; - break; case 0x00044005: /* Test depth */ resplen = 4; break; case 0x00048005: /* Set depth */ fbconfig.bpp = ldl_le_phys(&s->dma_as, value + 12); + bcm2835_fb_validate_config(&fbconfig); fbconfig_updated = true; - resplen = 4; - break; - case 0x00040006: /* Get pixel order */ - stl_le_phys(&s->dma_as, value + 12, fbconfig.pixo); + /* fall through */ + case 0x00040005: /* Get depth */ + stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp); resplen = 4; break; case 0x00044006: /* Test pixel order */ @@ -202,11 +198,11 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) break; case 0x00048006: /* Set pixel order */ fbconfig.pixo = ldl_le_phys(&s->dma_as, value + 12); + bcm2835_fb_validate_config(&fbconfig); fbconfig_updated = true; - resplen = 4; - break; - case 0x00040007: /* Get alpha */ - stl_le_phys(&s->dma_as, value + 12, fbconfig.alpha); + /* fall through */ + case 0x00040006: /* Get pixel order */ + stl_le_phys(&s->dma_as, value + 12, fbconfig.pixo); resplen = 4; break; case 0x00044007: /* Test pixel alpha */ @@ -214,7 +210,11 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) break; case 0x00048007: /* Set alpha */ fbconfig.alpha = ldl_le_phys(&s->dma_as, value + 12); + bcm2835_fb_validate_config(&fbconfig); fbconfig_updated = true; + /* fall through */ + case 0x00040007: /* Get alpha */ + stl_le_phys(&s->dma_as, value + 12, fbconfig.alpha); resplen = 4; break; case 0x00040008: /* Get pitch */ @@ -222,18 +222,18 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) bcm2835_fb_get_pitch(&fbconfig)); resplen = 4; break; - case 0x00040009: /* Get virtual offset */ - stl_le_phys(&s->dma_as, value + 12, fbconfig.xoffset); - stl_le_phys(&s->dma_as, value + 16, fbconfig.yoffset); - resplen = 8; - break; case 0x00044009: /* Test virtual offset */ resplen = 8; break; case 0x00048009: /* Set virtual offset */ fbconfig.xoffset = ldl_le_phys(&s->dma_as, value + 12); fbconfig.yoffset = ldl_le_phys(&s->dma_as, value + 16); + bcm2835_fb_validate_config(&fbconfig); fbconfig_updated = true; + /* fall through */ + case 0x00040009: /* Get virtual offset */ + stl_le_phys(&s->dma_as, value + 12, fbconfig.xoffset); + stl_le_phys(&s->dma_as, value + 16, fbconfig.yoffset); resplen = 8; break; case 0x0004000a: /* Get/Test/Set overscan */ From patchwork Tue Aug 14 14:44:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 144182 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4450939ljj; Tue, 14 Aug 2018 07:44:47 -0700 (PDT) X-Google-Smtp-Source: AA+uWPxnNJ15XSAwcAvJAi5hO/UEftK12rP29w8XViI7hmN5zdu89id5EPikJJhkHMRkePYJ+Bf1 X-Received: by 2002:a5d:44c6:: with SMTP id z6-v6mr13649078wrr.236.1534257886972; Tue, 14 Aug 2018 07:44:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534257886; cv=none; d=google.com; s=arc-20160816; b=tKotx5A0EJt3lwJ/VU6I2/nAVa5qXAOFU1L5uB1bzqIXtqhxB6/q2jar6Mn44Z+Ava J3RQf/+uYDBOuiCZtJ7ilFQe53Tl0wska5Iz7RaiLJcuvZ79LisBJLoiOENjnIRq6okX x5zgkxyRRYMk54Tq48G93IRxnRZh8/4nUIt7lleBSAOxU201IecSPpkwmNzs+wYlZ8RC tlsSwRSbX++4jwIqVb4dPrDerRG1Zg1xqkUjo1c2vH2KKQYKXnPPGxLsJ3CR5e/g6YeO TamL0FbIfRkURJNDOYRQnt/nPV/WjOy709T4pq0kkORpLW+vXeVh+0BNbH+RcK36kxUa S/Lw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=p0+JDqE/skbH6YQowtGNmT5gVp2iAdH2Eo04kLaRL5w=; b=Ls3dDElXhjcpXJ/7lHBXcsMh8WHkmgLK5U1f5vlbmyEpAhCh29cojv9ajNR0W2v7sX r9vyOcAd/e7/hUsc9poujAQy4CVWAi+5Wrf3TNiBlxzYbSpmWjtoifDG8SI9l+wNH8Cz jpl2eSijv9Du0NEzM7YlMs67sp8r5g9hd8A2DQaF5x1SkJXI0IuyFZ+gYLnX6niKREH3 p+N4r5xEyZNf2PnU1MNfJCFoWs8lI4nM2eYIk4yrPDWrSNv3hZzGf13W4cPgAFLqIYvf xJN4SgWeJhKJBegPwiWNpV8C+6oKB2Z/bu6IXtQ4vUDK+LEQgupS6EnmZtSJuXSb4BZG hAgg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 14-v6si17417332wrb.264.2018.08.14.07.44.46 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 14 Aug 2018 07:44:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpaYw-00072F-GQ; Tue, 14 Aug 2018 15:44:46 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 8/8] hw/display/bcm2835_fb: Validate bcm2835_fb_mbox_push() config Date: Tue, 14 Aug 2018 15:44:36 +0100 Message-Id: <20180814144436.679-9-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814144436.679-1-peter.maydell@linaro.org> References: <20180814144436.679-1-peter.maydell@linaro.org> Refactor bcm2835_fb_mbox_push() to work by calling bcm2835_fb_validate_config() and bcm2835_fb_reconfigure(), so that config set this way is also validated. Signed-off-by: Peter Maydell --- hw/display/bcm2835_fb.c | 63 ++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 32 deletions(-) -- 2.18.0 Reviewed-by: Richard Henderson diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 3edb8b5cfcb..d534d00a65f 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -248,38 +248,6 @@ void bcm2835_fb_validate_config(BCM2835FBConfig *config) } } -static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) -{ - uint32_t pitch; - uint32_t size; - - value &= ~0xf; - - s->lock = true; - - s->config.xres = ldl_le_phys(&s->dma_as, value); - s->config.yres = ldl_le_phys(&s->dma_as, value + 4); - s->config.xres_virtual = ldl_le_phys(&s->dma_as, value + 8); - s->config.yres_virtual = ldl_le_phys(&s->dma_as, value + 12); - s->config.bpp = ldl_le_phys(&s->dma_as, value + 20); - s->config.xoffset = ldl_le_phys(&s->dma_as, value + 24); - s->config.yoffset = ldl_le_phys(&s->dma_as, value + 28); - - s->config.base = s->vcram_base | (value & 0xc0000000); - s->config.base += BCM2835_FB_OFFSET; - - pitch = bcm2835_fb_get_pitch(&s->config); - size = bcm2835_fb_get_size(&s->config); - - stl_le_phys(&s->dma_as, value + 16, pitch); - stl_le_phys(&s->dma_as, value + 32, s->config.base); - stl_le_phys(&s->dma_as, value + 36, size); - - s->invalidate = true; - qemu_console_resize(s->con, s->config.xres, s->config.yres); - s->lock = false; -} - void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig) { s->lock = true; @@ -291,6 +259,37 @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig) s->lock = false; } +static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value) +{ + uint32_t pitch; + uint32_t size; + BCM2835FBConfig newconf; + + value &= ~0xf; + + newconf.xres = ldl_le_phys(&s->dma_as, value); + newconf.yres = ldl_le_phys(&s->dma_as, value + 4); + newconf.xres_virtual = ldl_le_phys(&s->dma_as, value + 8); + newconf.yres_virtual = ldl_le_phys(&s->dma_as, value + 12); + newconf.bpp = ldl_le_phys(&s->dma_as, value + 20); + newconf.xoffset = ldl_le_phys(&s->dma_as, value + 24); + newconf.yoffset = ldl_le_phys(&s->dma_as, value + 28); + + newconf.base = s->vcram_base | (value & 0xc0000000); + newconf.base += BCM2835_FB_OFFSET; + + bcm2835_fb_validate_config(&newconf); + + pitch = bcm2835_fb_get_pitch(&newconf); + size = bcm2835_fb_get_size(&newconf); + + stl_le_phys(&s->dma_as, value + 16, pitch); + stl_le_phys(&s->dma_as, value + 32, newconf.base); + stl_le_phys(&s->dma_as, value + 36, size); + + bcm2835_fb_reconfigure(s, &newconf); +} + static uint64_t bcm2835_fb_read(void *opaque, hwaddr offset, unsigned size) { BCM2835FBState *s = opaque;