From 2abdfe24402907e7e8c103bdd4166f26b74200c2 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 24 Aug 2018 13:17:29 +0100 Subject: softfloat: Add scaling int-to-float routines Signed-off-by: Richard Henderson Message-id: 20180814002653.12828-2-richard.henderson@linaro.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- include/fpu/softfloat.h | 52 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 69f4dbc..038e375 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -190,22 +190,54 @@ enum { /*---------------------------------------------------------------------------- | Software IEC/IEEE integer-to-floating-point conversion routines. *----------------------------------------------------------------------------*/ + +float16 int16_to_float16_scalbn(int16_t a, int, float_status *status); +float16 int32_to_float16_scalbn(int32_t a, int, float_status *status); +float16 int64_to_float16_scalbn(int64_t a, int, float_status *status); +float16 uint16_to_float16_scalbn(uint16_t a, int, float_status *status); +float16 uint32_to_float16_scalbn(uint32_t a, int, float_status *status); +float16 uint64_to_float16_scalbn(uint64_t a, int, float_status *status); + +float16 int16_to_float16(int16_t a, float_status *status); +float16 int32_to_float16(int32_t a, float_status *status); +float16 int64_to_float16(int64_t a, float_status *status); +float16 uint16_to_float16(uint16_t a, float_status *status); +float16 uint32_to_float16(uint32_t a, float_status *status); +float16 uint64_to_float16(uint64_t a, float_status *status); + +float32 int16_to_float32_scalbn(int16_t, int, float_status *status); +float32 int32_to_float32_scalbn(int32_t, int, float_status *status); +float32 int64_to_float32_scalbn(int64_t, int, float_status *status); +float32 uint16_to_float32_scalbn(uint16_t, int, float_status *status); +float32 uint32_to_float32_scalbn(uint32_t, int, float_status *status); +float32 uint64_to_float32_scalbn(uint64_t, int, float_status *status); + float32 int16_to_float32(int16_t, float_status *status); float32 int32_to_float32(int32_t, float_status *status); -float64 int16_to_float64(int16_t, float_status *status); -float64 int32_to_float64(int32_t, float_status *status); +float32 int64_to_float32(int64_t, float_status *status); float32 uint16_to_float32(uint16_t, float_status *status); float32 uint32_to_float32(uint32_t, float_status *status); +float32 uint64_to_float32(uint64_t, float_status *status); + +float64 int16_to_float64_scalbn(int16_t, int, float_status *status); +float64 int32_to_float64_scalbn(int32_t, int, float_status *status); +float64 int64_to_float64_scalbn(int64_t, int, float_status *status); +float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status); +float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status); +float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status); + +float64 int16_to_float64(int16_t, float_status *status); +float64 int32_to_float64(int32_t, float_status *status); +float64 int64_to_float64(int64_t, float_status *status); float64 uint16_to_float64(uint16_t, float_status *status); float64 uint32_to_float64(uint32_t, float_status *status); +float64 uint64_to_float64(uint64_t, float_status *status); + floatx80 int32_to_floatx80(int32_t, float_status *status); -float128 int32_to_float128(int32_t, float_status *status); -float32 int64_to_float32(int64_t, float_status *status); -float64 int64_to_float64(int64_t, float_status *status); floatx80 int64_to_floatx80(int64_t, float_status *status); + +float128 int32_to_float128(int32_t, float_status *status); float128 int64_to_float128(int64_t, float_status *status); -float32 uint64_to_float32(uint64_t, float_status *status); -float64 uint64_to_float64(uint64_t, float_status *status); float128 uint64_to_float128(uint64_t, float_status *status); /*---------------------------------------------------------------------------- @@ -227,12 +259,6 @@ int64_t float16_to_int64(float16, float_status *status); uint64_t float16_to_uint64(float16 a, float_status *status); int64_t float16_to_int64_round_to_zero(float16, float_status *status); uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); -float16 int16_to_float16(int16_t a, float_status *status); -float16 int32_to_float16(int32_t a, float_status *status); -float16 int64_to_float16(int64_t a, float_status *status); -float16 uint16_to_float16(uint16_t a, float_status *status); -float16 uint32_to_float16(uint32_t a, float_status *status); -float16 uint64_to_float16(uint64_t a, float_status *status); /*---------------------------------------------------------------------------- | Software half-precision operations. -- cgit v1.1 From 2f6c74be593ec5219e54d7b4abd4e5a98d7f3efc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 24 Aug 2018 13:17:30 +0100 Subject: softfloat: Add scaling float-to-int routines Signed-off-by: Richard Henderson Message-id: 20180814002653.12828-3-richard.henderson@linaro.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- include/fpu/softfloat.h | 79 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 038e375..cc1b58b 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -243,21 +243,34 @@ float128 uint64_to_float128(uint64_t, float_status *status); /*---------------------------------------------------------------------------- | Software half-precision conversion routines. *----------------------------------------------------------------------------*/ + float16 float32_to_float16(float32, bool ieee, float_status *status); float32 float16_to_float32(float16, bool ieee, float_status *status); float16 float64_to_float16(float64 a, bool ieee, float_status *status); float64 float16_to_float64(float16 a, bool ieee, float_status *status); + +int16_t float16_to_int16_scalbn(float16, int, int, float_status *status); +int32_t float16_to_int32_scalbn(float16, int, int, float_status *status); +int64_t float16_to_int64_scalbn(float16, int, int, float_status *status); + int16_t float16_to_int16(float16, float_status *status); -uint16_t float16_to_uint16(float16 a, float_status *status); -int16_t float16_to_int16_round_to_zero(float16, float_status *status); -uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status); int32_t float16_to_int32(float16, float_status *status); -uint32_t float16_to_uint32(float16 a, float_status *status); -int32_t float16_to_int32_round_to_zero(float16, float_status *status); -uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status); int64_t float16_to_int64(float16, float_status *status); -uint64_t float16_to_uint64(float16 a, float_status *status); + +int16_t float16_to_int16_round_to_zero(float16, float_status *status); +int32_t float16_to_int32_round_to_zero(float16, float_status *status); int64_t float16_to_int64_round_to_zero(float16, float_status *status); + +uint16_t float16_to_uint16_scalbn(float16 a, int, int, float_status *status); +uint32_t float16_to_uint32_scalbn(float16 a, int, int, float_status *status); +uint64_t float16_to_uint64_scalbn(float16 a, int, int, float_status *status); + +uint16_t float16_to_uint16(float16 a, float_status *status); +uint32_t float16_to_uint32(float16 a, float_status *status); +uint64_t float16_to_uint64(float16 a, float_status *status); + +uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status); +uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status); uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); /*---------------------------------------------------------------------------- @@ -347,18 +360,31 @@ float16 float16_default_nan(float_status *status); /*---------------------------------------------------------------------------- | Software IEC/IEEE single-precision conversion routines. *----------------------------------------------------------------------------*/ + +int16_t float32_to_int16_scalbn(float32, int, int, float_status *status); +int32_t float32_to_int32_scalbn(float32, int, int, float_status *status); +int64_t float32_to_int64_scalbn(float32, int, int, float_status *status); + int16_t float32_to_int16(float32, float_status *status); -uint16_t float32_to_uint16(float32, float_status *status); -int16_t float32_to_int16_round_to_zero(float32, float_status *status); -uint16_t float32_to_uint16_round_to_zero(float32, float_status *status); int32_t float32_to_int32(float32, float_status *status); +int64_t float32_to_int64(float32, float_status *status); + +int16_t float32_to_int16_round_to_zero(float32, float_status *status); int32_t float32_to_int32_round_to_zero(float32, float_status *status); +int64_t float32_to_int64_round_to_zero(float32, float_status *status); + +uint16_t float32_to_uint16_scalbn(float32, int, int, float_status *status); +uint32_t float32_to_uint32_scalbn(float32, int, int, float_status *status); +uint64_t float32_to_uint64_scalbn(float32, int, int, float_status *status); + +uint16_t float32_to_uint16(float32, float_status *status); uint32_t float32_to_uint32(float32, float_status *status); -uint32_t float32_to_uint32_round_to_zero(float32, float_status *status); -int64_t float32_to_int64(float32, float_status *status); uint64_t float32_to_uint64(float32, float_status *status); + +uint16_t float32_to_uint16_round_to_zero(float32, float_status *status); +uint32_t float32_to_uint32_round_to_zero(float32, float_status *status); uint64_t float32_to_uint64_round_to_zero(float32, float_status *status); -int64_t float32_to_int64_round_to_zero(float32, float_status *status); + float64 float32_to_float64(float32, float_status *status); floatx80 float32_to_floatx80(float32, float_status *status); float128 float32_to_float128(float32, float_status *status); @@ -476,18 +502,31 @@ float32 float32_default_nan(float_status *status); /*---------------------------------------------------------------------------- | Software IEC/IEEE double-precision conversion routines. *----------------------------------------------------------------------------*/ + +int16_t float64_to_int16_scalbn(float64, int, int, float_status *status); +int32_t float64_to_int32_scalbn(float64, int, int, float_status *status); +int64_t float64_to_int64_scalbn(float64, int, int, float_status *status); + int16_t float64_to_int16(float64, float_status *status); -uint16_t float64_to_uint16(float64, float_status *status); -int16_t float64_to_int16_round_to_zero(float64, float_status *status); -uint16_t float64_to_uint16_round_to_zero(float64, float_status *status); int32_t float64_to_int32(float64, float_status *status); +int64_t float64_to_int64(float64, float_status *status); + +int16_t float64_to_int16_round_to_zero(float64, float_status *status); int32_t float64_to_int32_round_to_zero(float64, float_status *status); +int64_t float64_to_int64_round_to_zero(float64, float_status *status); + +uint16_t float64_to_uint16_scalbn(float64, int, int, float_status *status); +uint32_t float64_to_uint32_scalbn(float64, int, int, float_status *status); +uint64_t float64_to_uint64_scalbn(float64, int, int, float_status *status); + +uint16_t float64_to_uint16(float64, float_status *status); uint32_t float64_to_uint32(float64, float_status *status); +uint64_t float64_to_uint64(float64, float_status *status); + +uint16_t float64_to_uint16_round_to_zero(float64, float_status *status); uint32_t float64_to_uint32_round_to_zero(float64, float_status *status); -int64_t float64_to_int64(float64, float_status *status); -int64_t float64_to_int64_round_to_zero(float64, float_status *status); -uint64_t float64_to_uint64(float64 a, float_status *status); -uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status); +uint64_t float64_to_uint64_round_to_zero(float64, float_status *status); + float32 float64_to_float32(float64, float_status *status); floatx80 float64_to_floatx80(float64, float_status *status); float128 float64_to_float128(float64, float_status *status); -- cgit v1.1 From a1982f90a42b22f2858e7d8497ab7223cd49b65d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:40 +0100 Subject: hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters The MPS2 FPGAIO block includes some simple free-running counters. Implement these. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-2-peter.maydell@linaro.org --- include/hw/misc/mps2-fpgaio.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h index eedf17e..ec057d3 100644 --- a/include/hw/misc/mps2-fpgaio.h +++ b/include/hw/misc/mps2-fpgaio.h @@ -38,6 +38,10 @@ typedef struct { uint32_t misc; uint32_t prescale_clk; + + /* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was zero */ + int64_t clk1hz_tick_offset; + int64_t clk100hz_tick_offset; } MPS2FPGAIO; #endif -- cgit v1.1 From 93739075d28ce81ae06237b48084f26a377cdcad Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:40 +0100 Subject: hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER In the MPS2 FPGAIO, PSCNTR is a free-running downcounter with a reload value configured via the PRESCALE register, and COUNTER counts up by 1 every time PSCNTR reaches zero. Implement these counters. We can just increment the counters migration subsection's version ID because we only added it in the previous commit, so no released QEMU versions will be using it. Signed-off-by: Peter Maydell Reviewed-by: Alistair Francis Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-3-peter.maydell@linaro.org --- include/hw/misc/mps2-fpgaio.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h index ec057d3..69e265c 100644 --- a/include/hw/misc/mps2-fpgaio.h +++ b/include/hw/misc/mps2-fpgaio.h @@ -37,6 +37,12 @@ typedef struct { uint32_t prescale; uint32_t misc; + /* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synced */ + int64_t pscntr_sync_ticks; + /* Values of COUNTER and PSCNTR at time pscntr_sync_ticks */ + uint32_t counter; + uint32_t pscntr; + uint32_t prescale_clk; /* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was zero */ -- cgit v1.1 From 4f4c6206ca6eda478ec0377545ce26eb41090672 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:41 +0100 Subject: hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module The Arm Cortex-M System Design Kit includes a "dual-input timer module" which combines two programmable down-counters. Implement a model of this device. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-4-peter.maydell@linaro.org --- include/hw/timer/cmsdk-apb-dualtimer.h | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 include/hw/timer/cmsdk-apb-dualtimer.h (limited to 'include') diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h new file mode 100644 index 0000000..9843a9d --- /dev/null +++ b/include/hw/timer/cmsdk-apb-dualtimer.h @@ -0,0 +1,72 @@ +/* + * ARM CMSDK APB dual-timer emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "APB dual-input timer" which is part of the Cortex-M + * System Design Kit (CMSDK) and documented in the Cortex-M System + * Design Kit Technical Reference Manual (ARM DDI0479C): + * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit + * + * QEMU interface: + * + QOM property "pclk-frq": frequency at which the timer is clocked + * + sysbus MMIO region 0: the register bank + * + sysbus IRQ 0: combined timer interrupt TIMINTC + * + sysbus IRO 1: timer block 1 interrupt TIMINT1 + * + sysbus IRQ 2: timer block 2 interrupt TIMINT2 + */ + +#ifndef CMSDK_APB_DUALTIMER_H +#define CMSDK_APB_DUALTIMER_H + +#include "hw/sysbus.h" +#include "hw/ptimer.h" + +#define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer" +#define CMSDK_APB_DUALTIMER(obj) OBJECT_CHECK(CMSDKAPBDualTimer, (obj), \ + TYPE_CMSDK_APB_DUALTIMER) + +typedef struct CMSDKAPBDualTimer CMSDKAPBDualTimer; + +/* One of the two identical timer modules in the dual-timer module */ +typedef struct CMSDKAPBDualTimerModule { + CMSDKAPBDualTimer *parent; + struct ptimer_state *timer; + qemu_irq timerint; + /* + * We must track the guest LOAD and VALUE register state by hand + * rather than leaving this state only in the ptimer limit/count, + * because if CONTROL.SIZE is 0 then only the low 16 bits of the + * counter actually counts, but the high half is still guest + * accessible. + */ + uint32_t load; + uint32_t value; + uint32_t control; + uint32_t intstatus; +} CMSDKAPBDualTimerModule; + +#define CMSDK_APB_DUALTIMER_NUM_MODULES 2 + +struct CMSDKAPBDualTimer { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + qemu_irq timerintc; + uint32_t pclk_frq; + + CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES]; + uint32_t timeritcr; + uint32_t timeritop; +}; + +#endif -- cgit v1.1 From 017d069d20866ed50f3422ade69d6cb60ea7522b Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:41 +0100 Subject: hw/arm/iotkit: Wire up the dualtimer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now we have a model of the CMSDK dual timer, we can wire it up in the IoTKit. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-5-peter.maydell@linaro.org --- include/hw/arm/iotkit.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 2cddde5..3e6d806 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -56,6 +56,7 @@ #include "hw/misc/tz-ppc.h" #include "hw/misc/tz-mpc.h" #include "hw/timer/cmsdk-apb-timer.h" +#include "hw/timer/cmsdk-apb-dualtimer.h" #include "hw/misc/unimp.h" #include "hw/or-irq.h" #include "hw/core/split-irq.h" @@ -87,7 +88,7 @@ typedef struct IoTKit { SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; qemu_or_irq mpc_irq_orgate; - UnimplementedDeviceState dualtimer; + CMSDKAPBDualTimer dualtimer; UnimplementedDeviceState s32ktimer; MemoryRegion container; -- cgit v1.1 From d61e4e1ff721ff8ab611f8a81442f8af192c0961 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:42 +0100 Subject: hw/arm/iotkit: Wire up the watchdogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IoTKit includes three different instances of the CMSDK APB watchdog; create and wire them up. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-7-peter.maydell@linaro.org --- include/hw/arm/iotkit.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 3e6d806..776d049 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -57,6 +57,7 @@ #include "hw/misc/tz-mpc.h" #include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-dualtimer.h" +#include "hw/watchdog/cmsdk-apb-watchdog.h" #include "hw/misc/unimp.h" #include "hw/or-irq.h" #include "hw/core/split-irq.h" @@ -87,10 +88,15 @@ typedef struct IoTKit { SplitIRQ ppc_irq_splitter[NUM_PPCS]; SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; qemu_or_irq mpc_irq_orgate; + qemu_or_irq nmi_orgate; CMSDKAPBDualTimer dualtimer; UnimplementedDeviceState s32ktimer; + CMSDKAPBWatchdog s32kwatchdog; + CMSDKAPBWatchdog nswatchdog; + CMSDKAPBWatchdog swatchdog; + MemoryRegion container; MemoryRegion alias1; MemoryRegion alias2; -- cgit v1.1 From e2d203baba7bf202a64ee321c2754fe918ab909e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:42 +0100 Subject: hw/arm/iotkit: Wire up the S32KTIMER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IoTKit has a CMSDK timer device that runs on the S32KCLK. Create this and wire it up. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-8-peter.maydell@linaro.org --- include/hw/arm/iotkit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 776d049..0f5c510 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -83,6 +83,7 @@ typedef struct IoTKit { TZMPC mpc; CMSDKAPBTIMER timer0; CMSDKAPBTIMER timer1; + CMSDKAPBTIMER s32ktimer; qemu_or_irq ppc_irq_orgate; SplitIRQ sec_resp_splitter; SplitIRQ ppc_irq_splitter[NUM_PPCS]; @@ -91,7 +92,6 @@ typedef struct IoTKit { qemu_or_irq nmi_orgate; CMSDKAPBDualTimer dualtimer; - UnimplementedDeviceState s32ktimer; CMSDKAPBWatchdog s32kwatchdog; CMSDKAPBWatchdog nswatchdog; -- cgit v1.1 From 75750e4d43c9c62d26d2b218a1e8c2f8efdf16c4 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:42 +0100 Subject: hw/misc/iotkit-sysctl: Implement IoTKit system control element The Arm IoTKit includes a system control element which provides a block of read-only ID registers and a block of read-write control registers. Implement a minimal version of this. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-9-peter.maydell@linaro.org --- include/hw/misc/iotkit-sysctl.h | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 include/hw/misc/iotkit-sysctl.h (limited to 'include') diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h new file mode 100644 index 0000000..e36613c --- /dev/null +++ b/include/hw/misc/iotkit-sysctl.h @@ -0,0 +1,49 @@ +/* + * ARM IoTKit system control element + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "system control element" which is part of the + * Arm IoTKit and documented in + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html + * Specifically, it implements the "system information block" and + * "system control register" blocks. + * + * QEMU interface: + * + sysbus MMIO region 0: the system information register bank + * + sysbus MMIO region 1: the system control register bank + */ + +#ifndef HW_MISC_IOTKIT_SYSCTL_H +#define HW_MISC_IOTKIT_SYSCTL_H + +#include "hw/sysbus.h" + +#define TYPE_IOTKIT_SYSCTL "iotkit-sysctl" +#define IOTKIT_SYSCTL(obj) OBJECT_CHECK(IoTKitSysCtl, (obj), \ + TYPE_IOTKIT_SYSCTL) + +typedef struct IoTKitSysCtl { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + uint32_t secure_debug; + uint32_t reset_syndrome; + uint32_t reset_mask; + uint32_t gretreg; + uint32_t initsvrtor0; + uint32_t cpuwait; + uint32_t wicctrl; +} IoTKitSysCtl; + +#endif -- cgit v1.1 From c667a25b324d086c7ea8002dbedeb10929d3b9da Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:43 +0100 Subject: hw/misc/iotkit-sysinfo: Implement IoTKit system information block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the IoTKit system control element's system information block; this is just a pair of read-only version/config registers, plus the usual PID/CID ID registers. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-10-peter.maydell@linaro.org --- include/hw/misc/iotkit-sysinfo.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 include/hw/misc/iotkit-sysinfo.h (limited to 'include') diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h new file mode 100644 index 0000000..7b2e1a5 --- /dev/null +++ b/include/hw/misc/iotkit-sysinfo.h @@ -0,0 +1,37 @@ +/* + * ARM IoTKit system information block + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "system information block" which is part of the + * Arm IoTKit and documented in + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html + * QEMU interface: + * + sysbus MMIO region 0: the system information register bank + */ + +#ifndef HW_MISC_IOTKIT_SYSINFO_H +#define HW_MISC_IOTKIT_SYSINFO_H + +#include "hw/sysbus.h" + +#define TYPE_IOTKIT_SYSINFO "iotkit-sysinfo" +#define IOTKIT_SYSINFO(obj) OBJECT_CHECK(IoTKitSysInfo, (obj), \ + TYPE_IOTKIT_SYSINFO) + +typedef struct IoTKitSysInfo { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; +} IoTKitSysInfo; + +#endif -- cgit v1.1 From 06e65af39b451c6abe863986a9c60d69bde7718d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:43 +0100 Subject: hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire up the system control element's register banks (sysctl and sysinfo). This is the last of the previously completely unimplemented components in the IoTKit. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-11-peter.maydell@linaro.org --- include/hw/arm/iotkit.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 0f5c510..426dc32 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -58,7 +58,8 @@ #include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-dualtimer.h" #include "hw/watchdog/cmsdk-apb-watchdog.h" -#include "hw/misc/unimp.h" +#include "hw/misc/iotkit-sysctl.h" +#include "hw/misc/iotkit-sysinfo.h" #include "hw/or-irq.h" #include "hw/core/split-irq.h" @@ -97,6 +98,9 @@ typedef struct IoTKit { CMSDKAPBWatchdog nswatchdog; CMSDKAPBWatchdog swatchdog; + IoTKitSysCtl sysctl; + IoTKitSysCtl sysinfo; + MemoryRegion container; MemoryRegion alias1; MemoryRegion alias2; -- cgit v1.1 From 211e701d669e85f0e33ff6c4404a77519198f35e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:43 +0100 Subject: hw/misc/tz-msc: Model TrustZone Master Security Controller Implement a model of the TrustZone Master Securtiy Controller, as documented in the Arm CoreLink SIE-200 System IP for Embedded TRM (DDI0571G): https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g The MSC is intended to sit in front of a device which can be a bus master (eg a DMA controller) and programmably gate its transactions. This allows a bus-mastering device to be controlled by non-secure code but still restricted from making accesses to addresses which are secure-only. Signed-off-by: Peter Maydell Message-id: 20180820141116.9118-12-peter.maydell@linaro.org Reviewed-by: Richard Henderson --- include/hw/misc/tz-msc.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 include/hw/misc/tz-msc.h (limited to 'include') diff --git a/include/hw/misc/tz-msc.h b/include/hw/misc/tz-msc.h new file mode 100644 index 0000000..116b96a --- /dev/null +++ b/include/hw/misc/tz-msc.h @@ -0,0 +1,79 @@ +/* + * ARM TrustZone master security controller emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the TrustZone master security controller (MSC). + * It is documented in the ARM CoreLink SIE-200 System IP for Embedded TRM + * (DDI 0571G): + * https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g + * + * The MSC sits in front of a device which can be a bus master (such as + * a DMA controller) and allows secure software to configure it to either + * pass through or reject transactions made by that bus master. + * Rejected transactions may be configured to either be aborted, or to + * behave as RAZ/WI. An interrupt can be signalled for a rejected transaction. + * + * The MSC has no register interface -- it is configured purely by a + * collection of input signals from other hardware in the system. Typically + * they are either hardwired or exposed in an ad-hoc register interface by + * the SoC that uses the MSC. + * + * We don't currently implement the irq_enable GPIO input, because on + * the MPS2 FPGA images it is always tied high, which is awkward to + * implement in QEMU. + * + * QEMU interface: + * + Named GPIO input "cfg_nonsec": set to 1 if the bus master should be + * treated as nonsecure, or 0 for secure + * + Named GPIO input "cfg_sec_resp": set to 1 if a rejected transaction should + * result in a transaction error, or 0 for the transaction to RAZ/WI + * + Named GPIO input "irq_clear": set to 1 to clear a pending interrupt + * + Named GPIO output "irq": set for a transaction-failed interrupt + * + Property "downstream": MemoryRegion defining where bus master transactions + * are made if they are not blocked + * + Property "idau": an object implementing IDAUInterface, which defines which + * addresses should be treated as secure and which as non-secure. + * This need not be the same IDAU as the one used by the CPU. + * + sysbus MMIO region 0: MemoryRegion defining the upstream end of the MSC; + * this should be passed to the bus master device as the region it should + * make memory transactions to + */ + +#ifndef TZ_MSC_H +#define TZ_MSC_H + +#include "hw/sysbus.h" +#include "target/arm/idau.h" + +#define TYPE_TZ_MSC "tz-msc" +#define TZ_MSC(obj) OBJECT_CHECK(TZMSC, (obj), TYPE_TZ_MSC) + +typedef struct TZMSC { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + + /* State: these just track the values of our input signals */ + bool cfg_nonsec; + bool cfg_sec_resp; + bool irq_clear; + /* State: are we asserting irq ? */ + bool irq_status; + + qemu_irq irq; + MemoryRegion *downstream; + AddressSpace downstream_as; + MemoryRegion upstream; + IDAUInterface *idau; +} TZMSC; + +#endif -- cgit v1.1 From 81a75deb1a2363a7f920e8982af4dc8c8d98a0ed Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:44 +0100 Subject: hw/misc/iotkit-secctl: Wire up registers for controlling MSCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IoTKit does not have any Master Security Contollers itself, but it does provide registers in the secure privilege control block which allow control of MSCs in the external system. Add support for these registers. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-id: 20180820141116.9118-13-peter.maydell@linaro.org Reviewed-by: Richard Henderson --- include/hw/misc/iotkit-secctl.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h index 082c14c..1a193b3 100644 --- a/include/hw/misc/iotkit-secctl.h +++ b/include/hw/misc/iotkit-secctl.h @@ -19,6 +19,7 @@ * + named GPIO output "sec_resp_cfg" indicating whether blocked accesses * should RAZ/WI or bus error * + named GPIO output "nsc_cfg" whose value tracks the NSCCFG register value + * + named GPIO output "msc_irq" for the combined IRQ line from the MSCs * Controlling the 2 APB PPCs in the IoTKit: * + named GPIO outputs apb_ppc0_nonsec[0..2] and apb_ppc1_nonsec * + named GPIO outputs apb_ppc0_ap[0..2] and apb_ppc1_ap @@ -44,6 +45,11 @@ * Controlling each of the 16 expansion MPCs which a system using the IoTKit * might provide: * + named GPIO inputs mpcexp_status[0..15] + * Controlling each of the 16 expansion MSCs which a system using the IoTKit + * might provide: + * + named GPIO inputs mscexp_status[0..15] + * + named GPIO outputs mscexp_clear[0..15] + * + named GPIO outputs mscexp_ns[0..15] */ #ifndef IOTKIT_SECCTL_H @@ -62,6 +68,7 @@ #define IOTS_NUM_AHB_EXP_PPC 4 #define IOTS_NUM_EXP_MPC 16 #define IOTS_NUM_MPC 1 +#define IOTS_NUM_EXP_MSC 16 typedef struct IoTKitSecCtl IoTKitSecCtl; @@ -103,6 +110,13 @@ struct IoTKitSecCtl { uint32_t brginten; uint32_t mpcintstatus; + uint32_t secmscintstat; + uint32_t secmscinten; + uint32_t nsmscexp; + qemu_irq mscexp_clear[IOTS_NUM_EXP_MSC]; + qemu_irq mscexp_ns[IOTS_NUM_EXP_MSC]; + qemu_irq msc_irq; + IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC]; IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC]; IoTKitSecCtlPPC ahbexp[IOTS_NUM_APB_EXP_PPC]; -- cgit v1.1 From 132b475a73574d8c6a7fa678716f2eead1002939 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:44 +0100 Subject: hw/arm/iotkit: Wire up the lines for MSCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IoTKit doesn't have any MSCs itself but it does need some wiring to connect the external signals from MSCs in the outer board model up to the registers and the NVIC IRQ line. We also need to expose a MemoryRegion corresponding to the AHB bus, so that MSCs in the outer board model can use that as their downstream port. (In the FPGA this is the "AHB Slave Expansion" ports shown in the block diagram in the AN505 documentation.) Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-id: 20180820141116.9118-14-peter.maydell@linaro.org Reviewed-by: Richard Henderson --- include/hw/arm/iotkit.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 426dc32..3a8ee63 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -28,6 +28,9 @@ * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts, which * are wired to the NVIC lines 32 .. n+32 + * + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows + * bus master devices in the board model to make transactions into + * all the devices and memory areas in the IoTKit * Controlling up to 4 AHB expansion PPBs which a system using the IoTKit * might provide: * + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15] @@ -45,6 +48,11 @@ * Controlling each of the 16 expansion MPCs which a system using the IoTKit * might provide: * + named GPIO inputs mpcexp_status[0..15] + * Controlling each of the 16 expansion MSCs which a system using the IoTKit + * might provide: + * + named GPIO inputs mscexp_status[0..15] + * + named GPIO outputs mscexp_clear[0..15] + * + named GPIO outputs mscexp_ns[0..15] */ #ifndef IOTKIT_H -- cgit v1.1 From 1d52866f5a53feef036c2e8f9b3a6a30209d48a7 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:44 +0100 Subject: hw/ssi/pl022: Allow use as embedded-struct device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a new include file for the pl022's device struct, type macros, etc, so that it can be instantiated using the "embedded struct" coding style. While we're adding the new file to MAINTAINERS, add also the .c file, which was missing an entry. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-id: 20180820141116.9118-16-peter.maydell@linaro.org Reviewed-by: Richard Henderson --- include/hw/ssi/pl022.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 include/hw/ssi/pl022.h (limited to 'include') diff --git a/include/hw/ssi/pl022.h b/include/hw/ssi/pl022.h new file mode 100644 index 0000000..a080519 --- /dev/null +++ b/include/hw/ssi/pl022.h @@ -0,0 +1,51 @@ +/* + * ARM PrimeCell PL022 Synchronous Serial Port + * + * Copyright (c) 2007 CodeSourcery. + * Written by Paul Brook + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* This is a model of the Arm PrimeCell PL022 synchronous serial port. + * The PL022 TRM is: + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0194h/DDI0194H_ssp_pl022_trm.pdf + * + * QEMU interface: + * + sysbus IRQ: SSPINTR combined interrupt line + * + sysbus MMIO region 0: MemoryRegion for the device's registers + */ + +#ifndef HW_SSI_PL022_H +#define HW_SSI_PL022_H + +#include "hw/sysbus.h" + +#define TYPE_PL022 "pl022" +#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022) + +typedef struct PL022State { + SysBusDevice parent_obj; + + MemoryRegion iomem; + uint32_t cr0; + uint32_t cr1; + uint32_t bitmask; + uint32_t sr; + uint32_t cpsr; + uint32_t is; + uint32_t im; + /* The FIFO head points to the next empty entry. */ + int tx_fifo_head; + int rx_fifo_head; + int tx_fifo_len; + int rx_fifo_len; + uint16_t tx_fifo[8]; + uint16_t rx_fifo[8]; + qemu_irq irq; + SSIBus *ssi; +} PL022State; + +#endif -- cgit v1.1 From a02755ece0c0652480ed9d9f2f0355fdc3632fdb Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:48 +0100 Subject: hw/misc/bcm2835_fb: Move config fields to their own struct 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 Reviewed-by: Richard Henderson Message-id: 20180814144436.679-2-peter.maydell@linaro.org --- include/hw/display/bcm2835_fb.h | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index ae0a380..8485825 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, -- cgit v1.1 From 193100b571755023690787bcb1ebc91fcc03ed50 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:48 +0100 Subject: hw/misc/bcm2835_property: Track fb settings using BCM2835FBConfig 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 Reviewed-by: Richard Henderson Message-id: 20180814144436.679-3-peter.maydell@linaro.org --- include/hw/display/bcm2835_fb.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index 8485825..b965698 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 -- cgit v1.1 From ea662f7cc8685622f393cdb7f7b7d243797a8af5 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:49 +0100 Subject: hw/display/bcm2835_fb: Drop unused size and pitch fields 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 Reviewed-by: Richard Henderson Message-id: 20180814144436.679-4-peter.maydell@linaro.org --- include/hw/display/bcm2835_fb.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index b965698..69cbf2d 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); -- cgit v1.1 From 9e2938a0fdb6d85d79c9d97b1fe4e626925be9b5 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:49 +0100 Subject: hw/display/bcm2835_fb: Reset resolution, etc correctly 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 Reviewed-by: Richard Henderson Message-id: 20180814144436.679-5-peter.maydell@linaro.org --- include/hw/display/bcm2835_fb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index 69cbf2d..374de54 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); -- cgit v1.1 From 9a1f03f4ee207d58674fc76aecff546551c9da76 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:49 +0100 Subject: hw/display/bcm2835_fb: Abstract out calculation of pitch, size 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 Reviewed-by: Richard Henderson Message-id: 20180814144436.679-6-peter.maydell@linaro.org --- include/hw/display/bcm2835_fb.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include') diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index 374de54..95bcec7 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 -- cgit v1.1 From 01f18af98b04dc3f47c37a150ae342fafd7337df Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:49 +0100 Subject: hw/display/bcm2835_fb: Fix handling of virtual framebuffer 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 Reviewed-by: Richard Henderson Message-id: 20180814144436.679-7-peter.maydell@linaro.org --- include/hw/display/bcm2835_fb.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index 95bcec7..d992c60 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 -- cgit v1.1 From f8add62c0c8826ca0fa90e6e3a80b810f63fe1dd Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:50 +0100 Subject: hw/display/bcm2835_fb: Validate config settings 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 Reviewed-by: Richard Henderson Message-id: 20180814144436.679-8-peter.maydell@linaro.org --- include/hw/display/bcm2835_fb.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h index d992c60..228988b 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 -- cgit v1.1