1
target-arm queue: this clears out a bunch of patches I'd sent over
1
Nothing too exciting, but does include the last bits of v8.1M support work.
2
the last coupled of weeks that have now got reviewed. Mostly
3
this is MPS2 device support improvements, put there is also
4
more of the incremental work towards supporting AArch32 Hyp mode,
5
a floating point bugfix, and the raspi framebuffer viewport support.
6
2
7
thanks
8
-- PMM
3
-- PMM
9
4
10
The following changes since commit 5ccac548faf041ff5229a8e8342e3be14a34c8af:
5
The following changes since commit e79de63ab1bd1f6550e7b915e433bec1ad1a870a:
11
6
12
Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging (2018-08-23 17:35:48 +0100)
7
Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210107' into staging (2021-01-07 20:34:05 +0000)
13
8
14
are available in the Git repository at:
9
are available in the Git repository at:
15
10
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180824
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210108
17
12
18
for you to fetch changes up to 30a719e3cb5c5367f3651eba8fa935634bfee286:
13
for you to fetch changes up to c9f8511ea8d2b80723af0fea1f716d752c1b5208:
19
14
20
hw/arm/mps2: Fix ID register errors on AN511 and AN385 (2018-08-24 10:22:44 +0100)
15
docs/system: arm: Add sabrelite board description (2021-01-08 15:13:39 +0000)
21
16
22
----------------------------------------------------------------
17
----------------------------------------------------------------
23
target-arm queue:
18
target-arm queue:
24
* Fix rounding errors in scaling float-to-int and int-to-float operations
19
* intc/arm_gic: Fix gic_irq_signaling_enabled() for vCPUs
25
* Connect virtualization-related IRQs and memory regions of GICv2
20
* target/arm: Fix MTE0_ACTIVE
26
in boards that use Cortex-A7 or Cortex-A15
21
* target/arm: Implement v8.1M and Cortex-M55 model
27
* Support taking exceptions to AArch32 Hyp mode
22
* hw/arm/highbank: Drop dead KVM support code
28
* Clear CPSR.IL and CPSR.J on 32-bit exception entry
23
* util/qemu-timer: Make timer_free() imply timer_del()
29
(a minor bug fix that won't affect non-buggy guest code)
24
* various devices: Use ptimer_free() in finalize function
30
* mps2-an505: Implement various missing devices:
25
* docs/system: arm: Add sabrelite board description
31
dual timer, watchdogs, counters in the FPGAIO registers,
26
* sabrelite: Minor fixes to allow booting U-Boot
32
some missing ID/control registers, TrustZone Master Security
33
Controllers, PL081 DMA controllers, PL022 SPI controllers
34
* correct ID register values for mps2-an385, -an511, -an505
35
* fix some hardcoded tabs in untouched backwaters of the
36
target/arm codebase
37
* raspi: Refactor framebuffer property handling code and implement
38
support for the virtual framebuffer/viewport
39
27
40
----------------------------------------------------------------
28
----------------------------------------------------------------
41
Peter Maydell (48):
29
Andrew Jones (1):
42
hw/intc/arm_gic: Make per-cpu GICH memory regions 0x200 bytes large
30
hw/arm/virt: Remove virt machine state 'smp_cpus'
43
hw/arm/vexpress: Connect VIRQ and VFIQ
44
hw/arm/highbank: Connect VIRQ and VFIQ
45
hw/arm/fsl-imx6ul: Connect VIRQ and VFIQ
46
hw/arm/fsl-imx6ul: Connect VIRQ and VFIQ
47
hw/cpu/a15mpcore: If CPU has EL2, enable it on the GIC and wire it up
48
hw/arm/vexpress: Don't set info->secure_boot if CPU doesn't have EL3
49
hw/arm/vexpress: Add "virtualization" property controlling presence of EL2
50
target/arm: Implement RAZ/WI HACTLR2
51
target/arm: Implement AArch32 HCR and HCR2
52
target/arm: Factor out code for taking an AArch32 exception
53
target/arm: Implement support for taking exceptions to Hyp mode
54
target/arm: Clear CPSR.IL and CPSR.J on 32-bit exception entry
55
hw/arm/boot: AArch32 kernels should be started in Hyp mode if available
56
hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters
57
hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER
58
hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module
59
hw/arm/iotkit: Wire up the dualtimer
60
hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511
61
hw/arm/iotkit: Wire up the watchdogs
62
hw/arm/iotkit: Wire up the S32KTIMER
63
hw/misc/iotkit-sysctl: Implement IoTKit system control element
64
hw/misc/iotkit-sysinfo: Implement IoTKit system information block
65
hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks
66
hw/misc/tz-msc: Model TrustZone Master Security Controller
67
hw/misc/iotkit-secctl: Wire up registers for controlling MSCs
68
hw/arm/iotkit: Wire up the lines for MSCs
69
hw/arm/mps2-tz: Create PL081s and MSCs
70
hw/ssi/pl022: Allow use as embedded-struct device
71
hw/ssi/pl022: Set up reset function in class init
72
hw/ssi/pl022: Don't directly call vmstate_register()
73
hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init
74
hw/ssi/pl022: Correct wrong value for PL022_INT_RT
75
hw/ssi/pl022: Correct wrong DMACR and ICR handling
76
hw/arm/mps2-tz: Instantiate SPI controllers
77
hw/arm/mps2-tz: Fix MPS2 SCC config register values
78
target/arm: Untabify translate.c
79
target/arm: Untabify iwmmxt_helper.c
80
target/arm: Remove a handful of stray tabs
81
hw/misc/bcm2835_fb: Move config fields to their own struct
82
hw/misc/bcm2835_property: Track fb settings using BCM2835FBConfig
83
hw/display/bcm2835_fb: Drop unused size and pitch fields
84
hw/display/bcm2835_fb: Reset resolution, etc correctly
85
hw/display/bcm2835_fb: Abstract out calculation of pitch, size
86
hw/display/bcm2835_fb: Fix handling of virtual framebuffer
87
hw/display/bcm2835_fb: Validate config settings
88
hw/display/bcm2835_fb: Validate bcm2835_fb_mbox_push() config
89
hw/arm/mps2: Fix ID register errors on AN511 and AN385
90
31
91
Richard Henderson (4):
32
Bin Meng (4):
92
softfloat: Add scaling int-to-float routines
33
hw/misc: imx6_ccm: Update PMU_MISC0 reset value
93
softfloat: Add scaling float-to-int routines
34
hw/msic: imx6_ccm: Correct register value for silicon type
94
target/arm: Use the int-to-float-scale softfloat routines
35
hw/arm: sabrelite: Connect the Ethernet PHY at address 6
95
target/arm: Use the float-to-int-scale softfloat routines
36
docs/system: arm: Add sabrelite board description
96
37
97
hw/misc/Makefile.objs | 3 +
38
Edgar E. Iglesias (1):
98
hw/timer/Makefile.objs | 1 +
39
intc/arm_gic: Fix gic_irq_signaling_enabled() for vCPUs
99
include/fpu/softfloat.h | 169 +++++++---
100
include/hw/arm/iotkit.h | 25 +-
101
include/hw/display/bcm2835_fb.h | 59 +++-
102
include/hw/misc/iotkit-secctl.h | 14 +
103
include/hw/misc/iotkit-sysctl.h | 49 +++
104
include/hw/misc/iotkit-sysinfo.h | 37 +++
105
include/hw/misc/mps2-fpgaio.h | 10 +
106
include/hw/misc/tz-msc.h | 79 +++++
107
include/hw/ssi/pl022.h | 51 +++
108
include/hw/timer/cmsdk-apb-dualtimer.h | 72 ++++
109
target/arm/cpu.h | 16 +-
110
fpu/softfloat.c | 579 ++++++++++++++++++++++++++-------
111
hw/arm/boot.c | 11 +
112
hw/arm/fsl-imx6ul.c | 4 +
113
hw/arm/fsl-imx7.c | 4 +
114
hw/arm/highbank.c | 6 +
115
hw/arm/iotkit.c | 114 ++++++-
116
hw/arm/mps2-tz.c | 142 +++++++-
117
hw/arm/mps2.c | 17 +-
118
hw/arm/vexpress.c | 64 +++-
119
hw/cpu/a15mpcore.c | 31 +-
120
hw/display/bcm2835_fb.c | 218 ++++++++-----
121
hw/intc/arm_gic.c | 2 +-
122
hw/misc/bcm2835_property.c | 123 ++++---
123
hw/misc/iotkit-secctl.c | 73 ++++-
124
hw/misc/iotkit-sysctl.c | 261 +++++++++++++++
125
hw/misc/iotkit-sysinfo.c | 128 ++++++++
126
hw/misc/mps2-fpgaio.c | 146 ++++++++-
127
hw/misc/tz-msc.c | 308 ++++++++++++++++++
128
hw/ssi/pl022.c | 57 ++--
129
hw/timer/cmsdk-apb-dualtimer.c | 515 +++++++++++++++++++++++++++++
130
target/arm/arm-semi.c | 2 +-
131
target/arm/helper.c | 342 +++++++++++++------
132
target/arm/iwmmxt_helper.c | 234 ++++++-------
133
target/arm/translate.c | 122 +++----
134
MAINTAINERS | 10 +
135
default-configs/arm-softmmu.mak | 4 +
136
hw/misc/trace-events | 16 +
137
hw/timer/trace-events | 5 +
138
41 files changed, 3405 insertions(+), 718 deletions(-)
139
create mode 100644 include/hw/misc/iotkit-sysctl.h
140
create mode 100644 include/hw/misc/iotkit-sysinfo.h
141
create mode 100644 include/hw/misc/tz-msc.h
142
create mode 100644 include/hw/ssi/pl022.h
143
create mode 100644 include/hw/timer/cmsdk-apb-dualtimer.h
144
create mode 100644 hw/misc/iotkit-sysctl.c
145
create mode 100644 hw/misc/iotkit-sysinfo.c
146
create mode 100644 hw/misc/tz-msc.c
147
create mode 100644 hw/timer/cmsdk-apb-dualtimer.c
148
40
41
Gan Qixin (7):
42
digic-timer: Use ptimer_free() in the finalize function to avoid memleaks
43
allwinner-a10-pit: Use ptimer_free() in the finalize function to avoid memleaks
44
exynos4210_rtc: Use ptimer_free() in the finalize function to avoid memleaks
45
exynos4210_pwm: Use ptimer_free() in the finalize function to avoid memleaks
46
mss-timer: Use ptimer_free() in the finalize function to avoid memleaks
47
musicpal: Use ptimer_free() in the finalize function to avoid memleaks
48
exynos4210_mct: Use ptimer_free() in the finalize function to avoid memleaks
49
50
Peter Maydell (9):
51
hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN
52
target/arm: Correct store of FPSCR value via FPCXT_S
53
target/arm: Implement FPCXT_NS fp system register
54
target/arm: Implement Cortex-M55 model
55
hw/arm/highbank: Drop dead KVM support code
56
util/qemu-timer: Make timer_free() imply timer_del()
57
scripts/coccinelle: New script to remove unnecessary timer_del() calls
58
Remove superfluous timer_del() calls
59
target/arm: Remove timer_del()/timer_deinit() before timer_free()
60
61
Richard Henderson (1):
62
target/arm: Fix MTE0_ACTIVE
63
64
docs/system/arm/sabrelite.rst | 119 ++++++++++++++++++++++++++
65
docs/system/target-arm.rst | 1 +
66
scripts/coccinelle/timer-del-timer-free.cocci | 18 ++++
67
include/hw/arm/virt.h | 3 +-
68
include/qemu/timer.h | 24 +++---
69
block/iscsi.c | 2 -
70
block/nbd.c | 1 -
71
block/qcow2.c | 1 -
72
hw/arm/highbank.c | 14 +--
73
hw/arm/musicpal.c | 12 +++
74
hw/arm/sabrelite.c | 4 +
75
hw/arm/virt-acpi-build.c | 9 +-
76
hw/arm/virt.c | 21 +++--
77
hw/block/nvme.c | 2 -
78
hw/char/serial.c | 2 -
79
hw/char/virtio-serial-bus.c | 2 -
80
hw/ide/core.c | 1 -
81
hw/input/hid.c | 1 -
82
hw/intc/apic.c | 1 -
83
hw/intc/arm_gic.c | 4 +-
84
hw/intc/armv7m_nvic.c | 15 ++++
85
hw/intc/ioapic.c | 1 -
86
hw/ipmi/ipmi_bmc_extern.c | 1 -
87
hw/misc/imx6_ccm.c | 4 +-
88
hw/net/e1000.c | 3 -
89
hw/net/e1000e_core.c | 8 --
90
hw/net/pcnet-pci.c | 1 -
91
hw/net/rtl8139.c | 1 -
92
hw/net/spapr_llan.c | 1 -
93
hw/net/virtio-net.c | 2 -
94
hw/rtc/exynos4210_rtc.c | 9 ++
95
hw/s390x/s390-pci-inst.c | 1 -
96
hw/sd/sd.c | 1 -
97
hw/sd/sdhci.c | 2 -
98
hw/timer/allwinner-a10-pit.c | 11 +++
99
hw/timer/digic-timer.c | 8 ++
100
hw/timer/exynos4210_mct.c | 14 +++
101
hw/timer/exynos4210_pwm.c | 11 +++
102
hw/timer/mss-timer.c | 13 +++
103
hw/usb/dev-hub.c | 1 -
104
hw/usb/hcd-ehci.c | 1 -
105
hw/usb/hcd-ohci-pci.c | 1 -
106
hw/usb/hcd-uhci.c | 1 -
107
hw/usb/hcd-xhci.c | 1 -
108
hw/usb/redirect.c | 1 -
109
hw/vfio/display.c | 1 -
110
hw/virtio/vhost-vsock-common.c | 1 -
111
hw/virtio/virtio-balloon.c | 1 -
112
hw/virtio/virtio-rng.c | 1 -
113
hw/watchdog/wdt_diag288.c | 1 -
114
hw/watchdog/wdt_i6300esb.c | 1 -
115
migration/colo.c | 1 -
116
monitor/hmp-cmds.c | 1 -
117
net/announce.c | 1 -
118
net/colo-compare.c | 1 -
119
net/slirp.c | 1 -
120
replay/replay-debugging.c | 1 -
121
target/arm/cpu.c | 2 -
122
target/arm/cpu_tcg.c | 42 +++++++++
123
target/arm/helper.c | 2 +-
124
target/s390x/cpu.c | 2 -
125
ui/console.c | 1 -
126
ui/spice-core.c | 1 -
127
util/throttle.c | 1 -
128
target/arm/translate-vfp.c.inc | 114 ++++++++++++++++++++++--
129
65 files changed, 421 insertions(+), 111 deletions(-)
130
create mode 100644 docs/system/arm/sabrelite.rst
131
create mode 100644 scripts/coccinelle/timer-del-timer-free.cocci
132
diff view generated by jsdifflib
1
Reduce the size of the per-cpu GICH memory regions from 0x1000
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
to 0x200. The registers only cover 0x200 bytes, and the Cortex-A15
3
wants to map them at a spacing of 0x200 bytes apart. Having the
4
region be too large interferes with mapping them like that, so
5
reduce it.
6
2
3
Correct the indexing into s->cpu_ctlr for vCPUs.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20201214222154.3480243-2-edgar.iglesias@gmail.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20180821132811.17675-3-peter.maydell@linaro.org
10
---
10
---
11
hw/intc/arm_gic.c | 2 +-
11
hw/intc/arm_gic.c | 4 +++-
12
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 3 insertions(+), 1 deletion(-)
13
13
14
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
14
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gic.c
16
--- a/hw/intc/arm_gic.c
17
+++ b/hw/intc/arm_gic.c
17
+++ b/hw/intc/arm_gic.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static inline void gic_get_best_virq(GICState *s, int cpu,
19
for (i = 0; i < s->num_cpu; i++) {
19
static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool virt,
20
memory_region_init_io(&s->vifaceiomem[i + 1], OBJECT(s),
20
int group_mask)
21
&gic_viface_ops, &s->backref[i],
21
{
22
- "gic_viface", 0x1000);
22
+ int cpu_iface = virt ? (cpu + GIC_NCPU) : cpu;
23
+ "gic_viface", 0x200);
23
+
24
sysbus_init_mmio(sbd, &s->vifaceiomem[i + 1]);
24
if (!virt && !(s->ctlr & group_mask)) {
25
}
25
return false;
26
}
26
}
27
@@ -XXX,XX +XXX,XX @@ static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool virt,
28
return false;
29
}
30
31
- if (!(s->cpu_ctlr[cpu] & group_mask)) {
32
+ if (!(s->cpu_ctlr[cpu_iface] & group_mask)) {
33
return false;
34
}
35
27
--
36
--
28
2.18.0
37
2.20.1
29
38
30
39
diff view generated by jsdifflib
1
Factor out the code which changes the CPU state so as to
1
From: Andrew Jones <drjones@redhat.com>
2
actually take an exception to AArch32. We're going to want
3
to use this for handling exception entry to Hyp mode.
4
2
3
virt machine's 'smp_cpus' and machine->smp.cpus must always have the
4
same value. And, anywhere we have virt machine state we have machine
5
state. So let's remove the redundancy. Also, to make it easier to see
6
that machine->smp is the true source for "smp_cpus" and "max_cpus",
7
avoid passing them in function parameters, preferring instead to get
8
them from the state.
9
10
No functional change intended.
11
12
Signed-off-by: Andrew Jones <drjones@redhat.com>
13
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
14
Reviewed-by: Ying Fang <fangying1@huawei.com>
15
Message-id: 20201215174815.51520-1-drjones@redhat.com
16
[PMM: minor formatting tweak to smp_cpus variable declaration]
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20180820153020.21478-4-peter.maydell@linaro.org
10
---
18
---
11
target/arm/helper.c | 64 +++++++++++++++++++++++++++++----------------
19
include/hw/arm/virt.h | 3 +--
12
1 file changed, 41 insertions(+), 23 deletions(-)
20
hw/arm/virt-acpi-build.c | 9 +++++----
21
hw/arm/virt.c | 21 ++++++++++-----------
22
3 files changed, 16 insertions(+), 17 deletions(-)
13
23
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
26
--- a/include/hw/arm/virt.h
17
+++ b/target/arm/helper.c
27
+++ b/include/hw/arm/virt.h
18
@@ -XXX,XX +XXX,XX @@ void aarch64_sync_64_to_32(CPUARMState *env)
28
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
19
env->regs[15] = env->pc;
29
MemMapEntry *memmap;
30
char *pciehb_nodename;
31
const int *irqmap;
32
- int smp_cpus;
33
void *fdt;
34
int fdt_size;
35
uint32_t clock_phandle;
36
@@ -XXX,XX +XXX,XX @@ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
37
38
assert(vms->gic_version == VIRT_GIC_VERSION_3);
39
40
- return vms->smp_cpus > redist0_capacity ? 2 : 1;
41
+ return MACHINE(vms)->smp.cpus > redist0_capacity ? 2 : 1;
20
}
42
}
21
43
22
+static void take_aarch32_exception(CPUARMState *env, int new_mode,
44
#endif /* QEMU_ARM_VIRT_H */
23
+ uint32_t mask, uint32_t offset,
45
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
24
+ uint32_t newpc)
46
index XXXXXXX..XXXXXXX 100644
25
+{
47
--- a/hw/arm/virt-acpi-build.c
26
+ /* Change the CPU state so as to actually take the exception. */
48
+++ b/hw/arm/virt-acpi-build.c
27
+ switch_mode(env, new_mode);
49
@@ -XXX,XX +XXX,XX @@
28
+ /*
50
29
+ * For exceptions taken to AArch32 we must clear the SS bit in both
51
#define ACPI_BUILD_TABLE_SIZE 0x20000
30
+ * PSTATE and in the old-state value we save to SPSR_<mode>, so zero it now.
52
31
+ */
53
-static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
32
+ env->uncached_cpsr &= ~PSTATE_SS;
54
+static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
33
+ env->spsr = cpsr_read(env);
34
+ /* Clear IT bits. */
35
+ env->condexec_bits = 0;
36
+ /* Switch to the new mode, and to the correct instruction set. */
37
+ env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
38
+ /* Set new mode endianness */
39
+ env->uncached_cpsr &= ~CPSR_E;
40
+ if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
41
+ env->uncached_cpsr |= CPSR_E;
42
+ }
43
+ env->daif |= mask;
44
+
45
+ if (new_mode == ARM_CPU_MODE_HYP) {
46
+ env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
47
+ env->elr_el[2] = env->regs[15];
48
+ } else {
49
+ /*
50
+ * this is a lie, as there was no c1_sys on V4T/V5, but who cares
51
+ * and we should just guard the thumb mode on V4
52
+ */
53
+ if (arm_feature(env, ARM_FEATURE_V4T)) {
54
+ env->thumb =
55
+ (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;
56
+ }
57
+ env->regs[14] = env->regs[15] + offset;
58
+ }
59
+ env->regs[15] = newpc;
60
+}
61
+
62
static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
63
{
55
{
64
ARMCPU *cpu = ARM_CPU(cs);
56
+ MachineState *ms = MACHINE(vms);
65
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
57
uint16_t i;
66
env->cp15.scr_el3 &= ~SCR_NS;
58
59
- for (i = 0; i < smp_cpus; i++) {
60
+ for (i = 0; i < ms->smp.cpus; i++) {
61
Aml *dev = aml_device("C%.03X", i);
62
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
63
aml_append(dev, aml_name_decl("_UID", aml_int(i)));
64
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
65
gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
66
gicd->version = vms->gic_version;
67
68
- for (i = 0; i < vms->smp_cpus; i++) {
69
+ for (i = 0; i < MACHINE(vms)->smp.cpus; i++) {
70
AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
71
sizeof(*gicc));
72
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
73
@@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
74
* the RTC ACPI device at all when using UEFI.
75
*/
76
scope = aml_scope("\\_SB");
77
- acpi_dsdt_add_cpus(scope, vms->smp_cpus);
78
+ acpi_dsdt_add_cpus(scope, vms);
79
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
80
(irqmap[VIRT_UART] + ARM_SPI_BASE));
81
if (vmc->acpi_expose_flash) {
82
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/arm/virt.c
85
+++ b/hw/arm/virt.c
86
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
87
if (vms->gic_version == VIRT_GIC_VERSION_2) {
88
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
89
GIC_FDT_IRQ_PPI_CPU_WIDTH,
90
- (1 << vms->smp_cpus) - 1);
91
+ (1 << MACHINE(vms)->smp.cpus) - 1);
67
}
92
}
68
93
69
- switch_mode (env, new_mode);
94
qemu_fdt_add_subnode(vms->fdt, "/timer");
70
- /* For exceptions taken to AArch32 we must clear the SS bit in both
95
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
71
- * PSTATE and in the old-state value we save to SPSR_<mode>, so zero it now.
96
int cpu;
72
- */
97
int addr_cells = 1;
73
- env->uncached_cpsr &= ~PSTATE_SS;
98
const MachineState *ms = MACHINE(vms);
74
- env->spsr = cpsr_read(env);
99
+ int smp_cpus = ms->smp.cpus;
75
- /* Clear IT bits. */
100
76
- env->condexec_bits = 0;
101
/*
77
- /* Switch to the new mode, and to the correct instruction set. */
102
* From Documentation/devicetree/bindings/arm/cpus.txt
78
- env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
103
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
79
- /* Set new mode endianness */
104
* The simplest way to go is to examine affinity IDs of all our CPUs. If
80
- env->uncached_cpsr &= ~CPSR_E;
105
* at least one of them has Aff3 populated, we set #address-cells to 2.
81
- if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
106
*/
82
- env->uncached_cpsr |= CPSR_E;
107
- for (cpu = 0; cpu < vms->smp_cpus; cpu++) {
83
- }
108
+ for (cpu = 0; cpu < smp_cpus; cpu++) {
84
- env->daif |= mask;
109
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
85
- /* this is a lie, as the was no c1_sys on V4T/V5, but who cares
110
86
- * and we should just guard the thumb mode on V4 */
111
if (armcpu->mp_affinity & ARM_AFF3_MASK) {
87
- if (arm_feature(env, ARM_FEATURE_V4T)) {
112
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
88
- env->thumb = (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;
113
qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#address-cells", addr_cells);
89
- }
114
qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#size-cells", 0x0);
90
- env->regs[14] = env->regs[15] + offset;
115
91
- env->regs[15] = addr;
116
- for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) {
92
+ take_aarch32_exception(env, new_mode, mask, offset, addr);
117
+ for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
93
}
118
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
94
119
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
95
/* Handle exception entry to a target EL which is using AArch64 */
120
CPUState *cs = CPU(armcpu);
121
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
122
qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
123
armcpu->dtb_compatible);
124
125
- if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED
126
- && vms->smp_cpus > 1) {
127
+ if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED && smp_cpus > 1) {
128
qemu_fdt_setprop_string(vms->fdt, nodename,
129
"enable-method", "psci");
130
}
131
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
132
if (vms->gic_version == VIRT_GIC_VERSION_2) {
133
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
134
GIC_FDT_IRQ_PPI_CPU_WIDTH,
135
- (1 << vms->smp_cpus) - 1);
136
+ (1 << MACHINE(vms)->smp.cpus) - 1);
137
}
138
139
qemu_fdt_add_subnode(vms->fdt, "/pmu");
140
@@ -XXX,XX +XXX,XX @@ static void finalize_gic_version(VirtMachineState *vms)
141
* virt_cpu_post_init() must be called after the CPUs have
142
* been realized and the GIC has been created.
143
*/
144
-static void virt_cpu_post_init(VirtMachineState *vms, int max_cpus,
145
- MemoryRegion *sysmem)
146
+static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem)
147
{
148
+ int max_cpus = MACHINE(vms)->smp.max_cpus;
149
bool aarch64, pmu, steal_time;
150
CPUState *cpu;
151
152
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
153
exit(1);
154
}
155
156
- vms->smp_cpus = smp_cpus;
157
-
158
if (vms->virt && kvm_enabled()) {
159
error_report("mach-virt: KVM does not support providing "
160
"Virtualization extensions to the guest CPU");
161
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
162
create_fdt(vms);
163
164
possible_cpus = mc->possible_cpu_arch_ids(machine);
165
+ assert(possible_cpus->len == max_cpus);
166
for (n = 0; n < possible_cpus->len; n++) {
167
Object *cpuobj;
168
CPUState *cs;
169
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
170
171
create_gic(vms);
172
173
- virt_cpu_post_init(vms, possible_cpus->len, sysmem);
174
+ virt_cpu_post_init(vms, sysmem);
175
176
fdt_add_pmu_nodes(vms);
177
96
--
178
--
97
2.18.0
179
2.20.1
98
180
99
181
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In 50244cc76abc we updated mte_check_fail to match the ARM
4
pseudocode, using the correct EL to select the TCF field.
5
But we failed to update MTE0_ACTIVE the same way, which led
6
to g_assert_not_reached().
7
8
Cc: qemu-stable@nongnu.org
9
Buglink: https://bugs.launchpad.net/bugs/1907137
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180814002653.12828-5-richard.henderson@linaro.org
11
Message-id: 20201221204426.88514-1-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
14
---
8
target/arm/helper.c | 101 ++++++++++++++++++++++----------------------
15
target/arm/helper.c | 2 +-
9
1 file changed, 51 insertions(+), 50 deletions(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
10
17
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
20
--- a/target/arm/helper.c
14
+++ b/target/arm/helper.c
21
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
22
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
16
void *fpstp) \
23
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
17
{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); }
24
&& tbid
18
25
&& !(env->pstate & PSTATE_TCO)
19
-/* Notice that we want only input-denormal exception flags from the
26
- && (sctlr & SCTLR_TCF0)
20
- * scalbn operation: the other possible flags (overflow+inexact if
27
+ && (sctlr & SCTLR_TCF)
21
- * we overflow to infinity, output-denormal) aren't correct for the
28
&& allocation_tag_access_enabled(env, 0, sctlr)) {
22
- * complete scale-and-convert operation.
29
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
23
- */
30
}
24
-#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \
25
-uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \
26
- uint32_t shift, \
27
- void *fpstp) \
28
-{ \
29
- float_status *fpst = fpstp; \
30
- int old_exc_flags = get_float_exception_flags(fpst); \
31
- float##fsz tmp; \
32
- if (float##fsz##_is_any_nan(x)) { \
33
- float_raise(float_flag_invalid, fpst); \
34
- return 0; \
35
- } \
36
- tmp = float##fsz##_scalbn(x, shift, fpst); \
37
- old_exc_flags |= get_float_exception_flags(fpst) \
38
- & float_flag_input_denormal; \
39
- set_float_exception_flags(old_exc_flags, fpst); \
40
- return float##fsz##_to_##itype##round(tmp, fpst); \
41
+#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ROUND, suff) \
42
+uint##isz##_t HELPER(vfp_to##name##p##suff)(float##fsz x, uint32_t shift, \
43
+ void *fpst) \
44
+{ \
45
+ if (unlikely(float##fsz##_is_any_nan(x))) { \
46
+ float_raise(float_flag_invalid, fpst); \
47
+ return 0; \
48
+ } \
49
+ return float##fsz##_to_##itype##_scalbn(x, ROUND, shift, fpst); \
50
}
51
52
#define VFP_CONV_FIX(name, p, fsz, isz, itype) \
53
VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
54
-VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero) \
55
-VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, )
56
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
57
+ float_round_to_zero, _round_to_zero) \
58
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
59
+ get_float_rounding_mode(fpst), )
60
61
#define VFP_CONV_FIX_A64(name, p, fsz, isz, itype) \
62
VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
63
-VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, )
64
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
65
+ get_float_rounding_mode(fpst), )
66
67
VFP_CONV_FIX(sh, d, 64, 64, int16)
68
VFP_CONV_FIX(sl, d, 64, 64, int32)
69
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
70
return uint64_to_float16_scalbn(x, -shift, fpst);
71
}
72
73
-static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
74
-{
75
- if (unlikely(float16_is_any_nan(f))) {
76
- float_raise(float_flag_invalid, fpst);
77
- return 0;
78
- } else {
79
- int old_exc_flags = get_float_exception_flags(fpst);
80
- float64 ret;
81
-
82
- ret = float16_to_float64(f, true, fpst);
83
- ret = float64_scalbn(ret, shift, fpst);
84
- old_exc_flags |= get_float_exception_flags(fpst)
85
- & float_flag_input_denormal;
86
- set_float_exception_flags(old_exc_flags, fpst);
87
-
88
- return ret;
89
- }
90
-}
91
-
92
uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
93
{
94
- return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
95
+ if (unlikely(float16_is_any_nan(x))) {
96
+ float_raise(float_flag_invalid, fpst);
97
+ return 0;
98
+ }
99
+ return float16_to_int16_scalbn(x, get_float_rounding_mode(fpst),
100
+ shift, fpst);
101
}
102
103
uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
104
{
105
- return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
106
+ if (unlikely(float16_is_any_nan(x))) {
107
+ float_raise(float_flag_invalid, fpst);
108
+ return 0;
109
+ }
110
+ return float16_to_uint16_scalbn(x, get_float_rounding_mode(fpst),
111
+ shift, fpst);
112
}
113
114
uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
115
{
116
- return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
117
+ if (unlikely(float16_is_any_nan(x))) {
118
+ float_raise(float_flag_invalid, fpst);
119
+ return 0;
120
+ }
121
+ return float16_to_int32_scalbn(x, get_float_rounding_mode(fpst),
122
+ shift, fpst);
123
}
124
125
uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst)
126
{
127
- return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
128
+ if (unlikely(float16_is_any_nan(x))) {
129
+ float_raise(float_flag_invalid, fpst);
130
+ return 0;
131
+ }
132
+ return float16_to_uint32_scalbn(x, get_float_rounding_mode(fpst),
133
+ shift, fpst);
134
}
135
136
uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst)
137
{
138
- return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
139
+ if (unlikely(float16_is_any_nan(x))) {
140
+ float_raise(float_flag_invalid, fpst);
141
+ return 0;
142
+ }
143
+ return float16_to_int64_scalbn(x, get_float_rounding_mode(fpst),
144
+ shift, fpst);
145
}
146
147
uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst)
148
{
149
- return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
150
+ if (unlikely(float16_is_any_nan(x))) {
151
+ float_raise(float_flag_invalid, fpst);
152
+ return 0;
153
+ }
154
+ return float16_to_uint64_scalbn(x, get_float_rounding_mode(fpst),
155
+ shift, fpst);
156
}
157
158
/* Set the current fp rounding mode and return the old one.
159
--
31
--
160
2.18.0
32
2.20.1
161
33
162
34
diff view generated by jsdifflib
1
The handling of framebuffer properties in the bcm2835_property code
1
The CCR is a register most of whose bits are banked between security
2
is a bit clumsy, because for each of the many fb related properties
2
states but where BFHFNMIGN is not, and we keep it in the non-secure
3
we try to track the value we're about to set and whether we're going
3
entry of the v7m.ccr[] array. The logic which tries to handle this
4
to be setting a value, and then we hand all the new values off
4
bit fails to implement the "RAZ/WI from Nonsecure if AIRCR.BFHFNMINS
5
to the framebuffer via a function which takes them all as separate
5
is zero" requirement; correct the omission.
6
arguments. It would be simpler if the property code could easily
7
copy all the framebuffer's current settings, update them with
8
the new specified values and then ask the framebuffer to switch
9
to the new set.
10
11
As the first part of this refactoring, pull all the fb config
12
settings fields in BCM2835FBState out into their own struct.
13
6
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20180814144436.679-2-peter.maydell@linaro.org
9
Message-id: 20201210201433.26262-2-peter.maydell@linaro.org
17
---
10
---
18
include/hw/display/bcm2835_fb.h | 26 ++++++--
11
hw/intc/armv7m_nvic.c | 15 +++++++++++++++
19
hw/display/bcm2835_fb.c | 114 +++++++++++++++++---------------
12
1 file changed, 15 insertions(+)
20
hw/misc/bcm2835_property.c | 28 ++++----
21
3 files changed, 94 insertions(+), 74 deletions(-)
22
13
23
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/display/bcm2835_fb.h
16
--- a/hw/intc/armv7m_nvic.c
26
+++ b/include/hw/display/bcm2835_fb.h
17
+++ b/hw/intc/armv7m_nvic.c
27
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
28
#define TYPE_BCM2835_FB "bcm2835-fb"
19
*/
29
#define BCM2835_FB(obj) OBJECT_CHECK(BCM2835FBState, (obj), TYPE_BCM2835_FB)
20
val = cpu->env.v7m.ccr[attrs.secure];
30
21
val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
31
+/*
22
+ /* BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0 */
32
+ * Configuration information about the fb which the guest can program
23
+ if (!attrs.secure) {
33
+ * via the mailbox property interface.
24
+ if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
34
+ */
25
+ val &= ~R_V7M_CCR_BFHFNMIGN_MASK;
35
+typedef struct {
26
+ }
36
+ uint32_t xres, yres;
27
+ }
37
+ uint32_t xres_virtual, yres_virtual;
28
return val;
38
+ uint32_t xoffset, yoffset;
29
case 0xd24: /* System Handler Control and State (SHCSR) */
39
+ uint32_t bpp;
30
if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
40
+ uint32_t base;
31
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
41
+ uint32_t pixo;
32
(cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
42
+ uint32_t alpha;
33
| (value & R_V7M_CCR_BFHFNMIGN_MASK);
43
+} BCM2835FBConfig;
34
value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
44
+
35
+ } else {
45
typedef struct {
36
+ /*
46
/*< private >*/
37
+ * BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0, so
47
SysBusDevice busdev;
38
+ * preserve the state currently in the NS element of the array
48
@@ -XXX,XX +XXX,XX @@ typedef struct {
39
+ */
49
qemu_irq mbox_irq;
40
+ if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
50
41
+ value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
51
bool lock, invalidate, pending;
42
+ value |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
52
- uint32_t xres, yres;
43
+ }
53
- uint32_t xres_virtual, yres_virtual;
54
- uint32_t xoffset, yoffset;
55
- uint32_t bpp;
56
- uint32_t base, pitch, size;
57
- uint32_t pixo, alpha;
58
+
59
+ BCM2835FBConfig config;
60
+
61
+ /* These are just cached values calculated from the config settings */
62
+ uint32_t size;
63
+ uint32_t pitch;
64
} BCM2835FBState;
65
66
void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres,
67
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/display/bcm2835_fb.c
70
+++ b/hw/display/bcm2835_fb.c
71
@@ -XXX,XX +XXX,XX @@ static void draw_line_src16(void *opaque, uint8_t *dst, const uint8_t *src,
72
int bpp = surface_bits_per_pixel(surface);
73
74
while (width--) {
75
- switch (s->bpp) {
76
+ switch (s->config.bpp) {
77
case 8:
78
/* lookup palette starting at video ram base
79
* TODO: cache translation, rather than doing this each time!
80
@@ -XXX,XX +XXX,XX @@ static void draw_line_src16(void *opaque, uint8_t *dst, const uint8_t *src,
81
break;
82
}
44
}
83
45
84
- if (s->pixo == 0) {
46
cpu->env.v7m.ccr[attrs.secure] = value;
85
+ if (s->config.pixo == 0) {
86
/* swap to BGR pixel format */
87
uint8_t tmp = r;
88
r = b;
89
@@ -XXX,XX +XXX,XX @@ static void fb_update_display(void *opaque)
90
int src_width = 0;
91
int dest_width = 0;
92
93
- if (s->lock || !s->xres) {
94
+ if (s->lock || !s->config.xres) {
95
return;
96
}
97
98
- src_width = s->xres * (s->bpp >> 3);
99
- dest_width = s->xres;
100
+ src_width = s->config.xres * (s->config.bpp >> 3);
101
+ dest_width = s->config.xres;
102
103
switch (surface_bits_per_pixel(surface)) {
104
case 0:
105
@@ -XXX,XX +XXX,XX @@ static void fb_update_display(void *opaque)
106
}
107
108
if (s->invalidate) {
109
- framebuffer_update_memory_section(&s->fbsection, s->dma_mr, s->base,
110
- s->yres, src_width);
111
+ framebuffer_update_memory_section(&s->fbsection, s->dma_mr,
112
+ s->config.base,
113
+ s->config.yres, src_width);
114
}
115
116
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
117
+ framebuffer_update_display(surface, &s->fbsection,
118
+ s->config.xres, s->config.yres,
119
src_width, dest_width, 0, s->invalidate,
120
draw_line_src16, s, &first, &last);
121
122
if (first >= 0) {
123
- dpy_gfx_update(s->con, 0, first, s->xres, last - first + 1);
124
+ dpy_gfx_update(s->con, 0, first, s->config.xres, last - first + 1);
125
}
126
127
s->invalidate = false;
128
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
129
130
s->lock = true;
131
132
- s->xres = ldl_le_phys(&s->dma_as, value);
133
- s->yres = ldl_le_phys(&s->dma_as, value + 4);
134
- s->xres_virtual = ldl_le_phys(&s->dma_as, value + 8);
135
- s->yres_virtual = ldl_le_phys(&s->dma_as, value + 12);
136
- s->bpp = ldl_le_phys(&s->dma_as, value + 20);
137
- s->xoffset = ldl_le_phys(&s->dma_as, value + 24);
138
- s->yoffset = ldl_le_phys(&s->dma_as, value + 28);
139
+ s->config.xres = ldl_le_phys(&s->dma_as, value);
140
+ s->config.yres = ldl_le_phys(&s->dma_as, value + 4);
141
+ s->config.xres_virtual = ldl_le_phys(&s->dma_as, value + 8);
142
+ s->config.yres_virtual = ldl_le_phys(&s->dma_as, value + 12);
143
+ s->config.bpp = ldl_le_phys(&s->dma_as, value + 20);
144
+ s->config.xoffset = ldl_le_phys(&s->dma_as, value + 24);
145
+ s->config.yoffset = ldl_le_phys(&s->dma_as, value + 28);
146
147
- s->base = s->vcram_base | (value & 0xc0000000);
148
- s->base += BCM2835_FB_OFFSET;
149
+ s->config.base = s->vcram_base | (value & 0xc0000000);
150
+ s->config.base += BCM2835_FB_OFFSET;
151
152
/* TODO - Manage properly virtual resolution */
153
154
- s->pitch = s->xres * (s->bpp >> 3);
155
- s->size = s->yres * s->pitch;
156
+ s->pitch = s->config.xres * (s->config.bpp >> 3);
157
+ s->size = s->config.yres * s->pitch;
158
159
stl_le_phys(&s->dma_as, value + 16, s->pitch);
160
- stl_le_phys(&s->dma_as, value + 32, s->base);
161
+ stl_le_phys(&s->dma_as, value + 32, s->config.base);
162
stl_le_phys(&s->dma_as, value + 36, s->size);
163
164
s->invalidate = true;
165
- qemu_console_resize(s->con, s->xres, s->yres);
166
+ qemu_console_resize(s->con, s->config.xres, s->config.yres);
167
s->lock = false;
168
}
169
170
@@ -XXX,XX +XXX,XX @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres,
171
172
/* TODO: input validation! */
173
if (xres) {
174
- s->xres = *xres;
175
+ s->config.xres = *xres;
176
}
177
if (yres) {
178
- s->yres = *yres;
179
+ s->config.yres = *yres;
180
}
181
if (xoffset) {
182
- s->xoffset = *xoffset;
183
+ s->config.xoffset = *xoffset;
184
}
185
if (yoffset) {
186
- s->yoffset = *yoffset;
187
+ s->config.yoffset = *yoffset;
188
}
189
if (bpp) {
190
- s->bpp = *bpp;
191
+ s->config.bpp = *bpp;
192
}
193
if (pixo) {
194
- s->pixo = *pixo;
195
+ s->config.pixo = *pixo;
196
}
197
if (alpha) {
198
- s->alpha = *alpha;
199
+ s->config.alpha = *alpha;
200
}
201
202
/* TODO - Manage properly virtual resolution */
203
204
- s->pitch = s->xres * (s->bpp >> 3);
205
- s->size = s->yres * s->pitch;
206
+ s->pitch = s->config.xres * (s->config.bpp >> 3);
207
+ s->size = s->config.yres * s->pitch;
208
209
s->invalidate = true;
210
- qemu_console_resize(s->con, s->xres, s->yres);
211
+ qemu_console_resize(s->con, s->config.xres, s->config.yres);
212
s->lock = false;
213
}
214
215
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_bcm2835_fb = {
216
VMSTATE_BOOL(lock, BCM2835FBState),
217
VMSTATE_BOOL(invalidate, BCM2835FBState),
218
VMSTATE_BOOL(pending, BCM2835FBState),
219
- VMSTATE_UINT32(xres, BCM2835FBState),
220
- VMSTATE_UINT32(yres, BCM2835FBState),
221
- VMSTATE_UINT32(xres_virtual, BCM2835FBState),
222
- VMSTATE_UINT32(yres_virtual, BCM2835FBState),
223
- VMSTATE_UINT32(xoffset, BCM2835FBState),
224
- VMSTATE_UINT32(yoffset, BCM2835FBState),
225
- VMSTATE_UINT32(bpp, BCM2835FBState),
226
- VMSTATE_UINT32(base, BCM2835FBState),
227
+ VMSTATE_UINT32(config.xres, BCM2835FBState),
228
+ VMSTATE_UINT32(config.yres, BCM2835FBState),
229
+ VMSTATE_UINT32(config.xres_virtual, BCM2835FBState),
230
+ VMSTATE_UINT32(config.yres_virtual, BCM2835FBState),
231
+ VMSTATE_UINT32(config.xoffset, BCM2835FBState),
232
+ VMSTATE_UINT32(config.yoffset, BCM2835FBState),
233
+ VMSTATE_UINT32(config.bpp, BCM2835FBState),
234
+ VMSTATE_UINT32(config.base, BCM2835FBState),
235
VMSTATE_UINT32(pitch, BCM2835FBState),
236
VMSTATE_UINT32(size, BCM2835FBState),
237
- VMSTATE_UINT32(pixo, BCM2835FBState),
238
- VMSTATE_UINT32(alpha, BCM2835FBState),
239
+ VMSTATE_UINT32(config.pixo, BCM2835FBState),
240
+ VMSTATE_UINT32(config.alpha, BCM2835FBState),
241
VMSTATE_END_OF_LIST()
242
}
243
};
244
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_reset(DeviceState *dev)
245
246
s->pending = false;
247
248
- s->xres_virtual = s->xres;
249
- s->yres_virtual = s->yres;
250
- s->xoffset = 0;
251
- s->yoffset = 0;
252
- s->base = s->vcram_base + BCM2835_FB_OFFSET;
253
- s->pitch = s->xres * (s->bpp >> 3);
254
- s->size = s->yres * s->pitch;
255
+ s->config.xres_virtual = s->config.xres;
256
+ s->config.yres_virtual = s->config.yres;
257
+ s->config.xoffset = 0;
258
+ s->config.yoffset = 0;
259
+ s->config.base = s->vcram_base + BCM2835_FB_OFFSET;
260
+ s->pitch = s->config.xres * (s->config.bpp >> 3);
261
+ s->size = s->config.yres * s->pitch;
262
263
s->invalidate = true;
264
s->lock = false;
265
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_realize(DeviceState *dev, Error **errp)
266
bcm2835_fb_reset(dev);
267
268
s->con = graphic_console_init(dev, 0, &vgafb_ops, s);
269
- qemu_console_resize(s->con, s->xres, s->yres);
270
+ qemu_console_resize(s->con, s->config.xres, s->config.yres);
271
}
272
273
static Property bcm2835_fb_props[] = {
274
DEFINE_PROP_UINT32("vcram-base", BCM2835FBState, vcram_base, 0),/*required*/
275
DEFINE_PROP_UINT32("vcram-size", BCM2835FBState, vcram_size,
276
DEFAULT_VCRAM_SIZE),
277
- DEFINE_PROP_UINT32("xres", BCM2835FBState, xres, 640),
278
- DEFINE_PROP_UINT32("yres", BCM2835FBState, yres, 480),
279
- DEFINE_PROP_UINT32("bpp", BCM2835FBState, bpp, 16),
280
- DEFINE_PROP_UINT32("pixo", BCM2835FBState, pixo, 1), /* 1=RGB, 0=BGR */
281
- DEFINE_PROP_UINT32("alpha", BCM2835FBState, alpha, 2), /* alpha ignored */
282
+ DEFINE_PROP_UINT32("xres", BCM2835FBState, config.xres, 640),
283
+ DEFINE_PROP_UINT32("yres", BCM2835FBState, config.yres, 480),
284
+ DEFINE_PROP_UINT32("bpp", BCM2835FBState, config.bpp, 16),
285
+ DEFINE_PROP_UINT32("pixo",
286
+ BCM2835FBState, config.pixo, 1), /* 1=RGB, 0=BGR */
287
+ DEFINE_PROP_UINT32("alpha",
288
+ BCM2835FBState, config.alpha, 2), /* alpha ignored */
289
DEFINE_PROP_END_OF_LIST()
290
};
291
292
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
293
index XXXXXXX..XXXXXXX 100644
294
--- a/hw/misc/bcm2835_property.c
295
+++ b/hw/misc/bcm2835_property.c
296
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
297
/* Frame buffer */
298
299
case 0x00040001: /* Allocate buffer */
300
- stl_le_phys(&s->dma_as, value + 12, s->fbdev->base);
301
- tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres;
302
- tmp_yres = newyres != NULL ? *newyres : s->fbdev->yres;
303
- tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp;
304
+ stl_le_phys(&s->dma_as, value + 12, s->fbdev->config.base);
305
+ tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres;
306
+ tmp_yres = newyres != NULL ? *newyres : s->fbdev->config.yres;
307
+ tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp;
308
stl_le_phys(&s->dma_as, value + 16,
309
tmp_xres * tmp_yres * tmp_bpp / 8);
310
resplen = 8;
311
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
312
break;
313
case 0x00040003: /* Get display width/height */
314
case 0x00040004:
315
- tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres;
316
- tmp_yres = newyres != NULL ? *newyres : s->fbdev->yres;
317
+ tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres;
318
+ tmp_yres = newyres != NULL ? *newyres : s->fbdev->config.yres;
319
stl_le_phys(&s->dma_as, value + 12, tmp_xres);
320
stl_le_phys(&s->dma_as, value + 16, tmp_yres);
321
resplen = 8;
322
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
323
resplen = 8;
324
break;
325
case 0x00040005: /* Get depth */
326
- tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp;
327
+ tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp;
328
stl_le_phys(&s->dma_as, value + 12, tmp_bpp);
329
resplen = 4;
330
break;
331
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
332
resplen = 4;
333
break;
334
case 0x00040006: /* Get pixel order */
335
- tmp_pixo = newpixo != NULL ? *newpixo : s->fbdev->pixo;
336
+ tmp_pixo = newpixo != NULL ? *newpixo : s->fbdev->config.pixo;
337
stl_le_phys(&s->dma_as, value + 12, tmp_pixo);
338
resplen = 4;
339
break;
340
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
341
resplen = 4;
342
break;
343
case 0x00040007: /* Get alpha */
344
- tmp_alpha = newalpha != NULL ? *newalpha : s->fbdev->alpha;
345
+ tmp_alpha = newalpha != NULL ? *newalpha : s->fbdev->config.alpha;
346
stl_le_phys(&s->dma_as, value + 12, tmp_alpha);
347
resplen = 4;
348
break;
349
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
350
resplen = 4;
351
break;
352
case 0x00040008: /* Get pitch */
353
- tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres;
354
- tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp;
355
+ tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres;
356
+ tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp;
357
stl_le_phys(&s->dma_as, value + 12, tmp_xres * tmp_bpp / 8);
358
resplen = 4;
359
break;
360
case 0x00040009: /* Get virtual offset */
361
- tmp_xoffset = newxoffset != NULL ? *newxoffset : s->fbdev->xoffset;
362
- tmp_yoffset = newyoffset != NULL ? *newyoffset : s->fbdev->yoffset;
363
+ tmp_xoffset = newxoffset != NULL ?
364
+ *newxoffset : s->fbdev->config.xoffset;
365
+ tmp_yoffset = newyoffset != NULL ?
366
+ *newyoffset : s->fbdev->config.yoffset;
367
stl_le_phys(&s->dma_as, value + 12, tmp_xoffset);
368
stl_le_phys(&s->dma_as, value + 16, tmp_yoffset);
369
resplen = 8;
370
--
47
--
371
2.18.0
48
2.20.1
372
49
373
50
diff view generated by jsdifflib
1
Fix MPS2 SCC config register values for the mps2-an511
1
In commit 64f863baeedc8659 we implemented the v8.1M FPCXT_S register,
2
and mps2-an385 boards:
2
but we got the write behaviour wrong. On read, this register reads
3
* the SCC_AID bits [23:20] specify the FPGA build target board revision,
3
bits [27:0] of FPSCR plus the CONTROL.SFPA bit. On write, it doesn't
4
and the SCC_CFG4 register specifies the actual board revision, so
4
just write back those bits -- it writes a value to the whole FPSCR,
5
these should have matching values. Claim to be board revision C,
5
whose upper 4 bits are zeroes.
6
consistently -- we had the revision in the wrong part of SCC_AID.
6
7
* SCC_ID bits [15:4] should be the board number in hex, not decimal
7
We also incorrectly implemented the write-to-FPSCR as a simple store
8
to vfp.xregs; this skips the "update the softfloat flags" part of
9
the vfp_set_fpscr helper so the value would read back correctly but
10
not actually take effect.
11
12
Fix both of these things by doing a complete write to the FPSCR
13
using the helper function.
8
14
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180823175225.22612-1-peter.maydell@linaro.org
17
Message-id: 20201210201433.26262-3-peter.maydell@linaro.org
12
---
18
---
13
hw/arm/mps2.c | 6 +++---
19
target/arm/translate-vfp.c.inc | 12 ++++++------
14
1 file changed, 3 insertions(+), 3 deletions(-)
20
1 file changed, 6 insertions(+), 6 deletions(-)
15
21
16
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
22
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mps2.c
24
--- a/target/arm/translate-vfp.c.inc
19
+++ b/hw/arm/mps2.c
25
+++ b/target/arm/translate-vfp.c.inc
20
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
26
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
21
sccdev = DEVICE(&mms->scc);
27
}
22
qdev_set_parent_bus(sccdev, sysbus_get_default());
28
case ARM_VFP_FPCXT_S:
23
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
29
{
24
- qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
30
- TCGv_i32 sfpa, control, fpscr;
25
+ qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
31
- /* Set FPSCR[27:0] and CONTROL.SFPA from value */
26
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
32
+ TCGv_i32 sfpa, control;
27
object_property_set_bool(OBJECT(&mms->scc), true, "realized",
33
+ /*
28
&error_fatal);
34
+ * Set FPSCR and CONTROL.SFPA from value; the new FPSCR takes
29
@@ -XXX,XX +XXX,XX @@ static void mps2_an385_class_init(ObjectClass *oc, void *data)
35
+ * bits [27:0] from value and zeroes bits [31:28].
30
mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
36
+ */
31
mmc->fpga_type = FPGA_AN385;
37
tmp = loadfn(s, opaque);
32
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
38
sfpa = tcg_temp_new_i32();
33
- mmc->scc_id = 0x41040000 | (385 << 4);
39
tcg_gen_shri_i32(sfpa, tmp, 31);
34
+ mmc->scc_id = 0x41043850;
40
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
35
}
41
tcg_gen_deposit_i32(control, control, sfpa,
36
42
R_V7M_CONTROL_SFPA_SHIFT, 1);
37
static void mps2_an511_class_init(ObjectClass *oc, void *data)
43
store_cpu_field(control, v7m.control[M_REG_S]);
38
@@ -XXX,XX +XXX,XX @@ static void mps2_an511_class_init(ObjectClass *oc, void *data)
44
- fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
39
mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
45
- tcg_gen_andi_i32(fpscr, fpscr, FPCR_NZCV_MASK);
40
mmc->fpga_type = FPGA_AN511;
46
tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
41
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
47
- tcg_gen_or_i32(fpscr, fpscr, tmp);
42
- mmc->scc_id = 0x4104000 | (511 << 4);
48
- store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
43
+ mmc->scc_id = 0x41045110;
49
+ gen_helper_vfp_set_fpscr(cpu_env, tmp);
44
}
50
tcg_temp_free_i32(tmp);
45
51
tcg_temp_free_i32(sfpa);
46
static const TypeInfo mps2_info = {
52
break;
47
--
53
--
48
2.18.0
54
2.20.1
49
55
50
56
diff view generated by jsdifflib
1
Validate the config settings that the guest tries to set.
1
Implement the v8.1M FPCXT_NS floating-point system register. This is
2
2
a little more complicated than FPCXT_S, because it has specific
3
The wiki page documentation is not really accurate here:
3
handling for "current FP state is inactive", and it only wants to do
4
generally rather than failing requests to set bad parameters,
4
PreserveFPState(), not the full set of actions done by
5
the hardware will just clip them to something sensible.
5
ExecuteFPCheck() which vfp_access_check() implements.
6
7
Validate the most important parameters: sizes and
8
the viewport offsets. This prevents the framebuffer
9
code from trying to read out-of-range memory.
10
11
In the property handling code, we validate the new parameters every
12
time we encounter a tag that sets them. This means we validate the
13
config multiple times if the request includes multiple config-setting
14
tags, but the code would require significant restructuring to do a
15
validation only once but still return the clipped settings for
16
get-parameter tags and the buffer allocation tag.
17
18
Validation of settings made via the older bcm2835_fb_mbox_push()
19
function will be done in the next commit.
20
6
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20180814144436.679-8-peter.maydell@linaro.org
9
Message-id: 20201210201433.26262-4-peter.maydell@linaro.org
24
---
10
---
25
include/hw/display/bcm2835_fb.h | 8 +++++
11
target/arm/translate-vfp.c.inc | 102 ++++++++++++++++++++++++++++++++-
26
hw/display/bcm2835_fb.c | 48 +++++++++++++++++++++++++++--
12
1 file changed, 99 insertions(+), 3 deletions(-)
27
hw/misc/bcm2835_property.c | 54 ++++++++++++++++-----------------
28
3 files changed, 81 insertions(+), 29 deletions(-)
29
13
30
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
14
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
31
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
32
--- a/include/hw/display/bcm2835_fb.h
16
--- a/target/arm/translate-vfp.c.inc
33
+++ b/include/hw/display/bcm2835_fb.h
17
+++ b/target/arm/translate-vfp.c.inc
34
@@ -XXX,XX +XXX,XX @@ static inline uint32_t bcm2835_fb_get_size(BCM2835FBConfig *config)
18
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
35
return yres * bcm2835_fb_get_pitch(config);
19
}
20
break;
21
case ARM_VFP_FPCXT_S:
22
+ case ARM_VFP_FPCXT_NS:
23
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
24
return false;
25
}
26
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
27
return FPSysRegCheckFailed;
28
}
29
30
- if (!vfp_access_check(s)) {
31
+ /*
32
+ * FPCXT_NS is a special case: it has specific handling for
33
+ * "current FP state is inactive", and must do the PreserveFPState()
34
+ * but not the usual full set of actions done by ExecuteFPCheck().
35
+ * So we don't call vfp_access_check() and the callers must handle this.
36
+ */
37
+ if (regno != ARM_VFP_FPCXT_NS && !vfp_access_check(s)) {
38
return FPSysRegCheckDone;
39
}
40
-
41
return FPSysRegCheckContinue;
36
}
42
}
37
43
38
+/**
44
+static void gen_branch_fpInactive(DisasContext *s, TCGCond cond,
39
+ * bcm2835_fb_validate_config: check provided config
45
+ TCGLabel *label)
40
+ *
41
+ * Validates the configuration information provided by the guest and
42
+ * adjusts it if necessary.
43
+ */
44
+void bcm2835_fb_validate_config(BCM2835FBConfig *config);
45
+
46
#endif
47
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/display/bcm2835_fb.c
50
+++ b/hw/display/bcm2835_fb.c
51
@@ -XXX,XX +XXX,XX @@
52
#define DEFAULT_VCRAM_SIZE 0x4000000
53
#define BCM2835_FB_OFFSET 0x00100000
54
55
+/* Maximum permitted framebuffer size; experimentally determined on an rpi2 */
56
+#define XRES_MAX 3840
57
+#define YRES_MAX 2560
58
+/* Framebuffer size used if guest requests zero size */
59
+#define XRES_SMALL 592
60
+#define YRES_SMALL 488
61
+
62
static void fb_invalidate_display(void *opaque)
63
{
64
BCM2835FBState *s = BCM2835_FB(opaque);
65
@@ -XXX,XX +XXX,XX @@ static void fb_update_display(void *opaque)
66
s->invalidate = false;
67
}
68
69
+void bcm2835_fb_validate_config(BCM2835FBConfig *config)
70
+{
46
+{
71
+ /*
47
+ /*
72
+ * Validate the config, and clip any bogus values into range,
48
+ * FPCXT_NS is a special case: it has specific handling for
73
+ * as the hardware does. Note that fb_update_display() relies on
49
+ * "current FP state is inactive", and must do the PreserveFPState()
74
+ * this happening to prevent it from performing out-of-range
50
+ * but not the usual full set of actions done by ExecuteFPCheck().
75
+ * accesses on redraw.
51
+ * We don't have a TB flag that matches the fpInactive check, so we
52
+ * do it at runtime as we don't expect FPCXT_NS accesses to be frequent.
53
+ *
54
+ * Emit code that checks fpInactive and does a conditional
55
+ * branch to label based on it:
56
+ * if cond is TCG_COND_NE then branch if fpInactive != 0 (ie if inactive)
57
+ * if cond is TCG_COND_EQ then branch if fpInactive == 0 (ie if active)
76
+ */
58
+ */
77
+ config->xres = MIN(config->xres, XRES_MAX);
59
+ assert(cond == TCG_COND_EQ || cond == TCG_COND_NE);
78
+ config->xres_virtual = MIN(config->xres_virtual, XRES_MAX);
79
+ config->yres = MIN(config->yres, YRES_MAX);
80
+ config->yres_virtual = MIN(config->yres_virtual, YRES_MAX);
81
+
60
+
82
+ /*
61
+ /* fpInactive = FPCCR_NS.ASPEN == 1 && CONTROL.FPCA == 0 */
83
+ * These are not minima: a 40x40 framebuffer will be accepted.
62
+ TCGv_i32 aspen, fpca;
84
+ * They're only used as defaults if the guest asks for zero size.
63
+ aspen = load_cpu_field(v7m.fpccr[M_REG_NS]);
85
+ */
64
+ fpca = load_cpu_field(v7m.control[M_REG_S]);
86
+ if (config->xres == 0) {
65
+ tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
87
+ config->xres = XRES_SMALL;
66
+ tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
88
+ }
67
+ tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK);
89
+ if (config->yres == 0) {
68
+ tcg_gen_or_i32(fpca, fpca, aspen);
90
+ config->yres = YRES_SMALL;
69
+ tcg_gen_brcondi_i32(tcg_invert_cond(cond), fpca, 0, label);
91
+ }
70
+ tcg_temp_free_i32(aspen);
92
+ if (config->xres_virtual == 0) {
71
+ tcg_temp_free_i32(fpca);
93
+ config->xres_virtual = config->xres;
94
+ }
95
+ if (config->yres_virtual == 0) {
96
+ config->yres_virtual = config->yres;
97
+ }
98
+
99
+ if (fb_use_offsets(config)) {
100
+ /* Clip the offsets so the viewport is within the physical screen */
101
+ config->xoffset = MIN(config->xoffset,
102
+ config->xres_virtual - config->xres);
103
+ config->yoffset = MIN(config->yoffset,
104
+ config->yres_virtual - config->yres);
105
+ }
106
+}
72
+}
107
+
73
+
108
static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
74
static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
75
76
fp_sysreg_loadfn *loadfn,
77
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
109
{
78
{
110
uint32_t pitch;
79
/* Do a write to an M-profile floating point system register */
111
@@ -XXX,XX +XXX,XX @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig)
80
TCGv_i32 tmp;
81
+ TCGLabel *lab_end = NULL;
82
83
switch (fp_sysreg_checks(s, regno)) {
84
case FPSysRegCheckFailed:
85
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
86
tcg_temp_free_i32(tmp);
87
break;
88
}
89
+ case ARM_VFP_FPCXT_NS:
90
+ lab_end = gen_new_label();
91
+ /* fpInactive case: write is a NOP, so branch to end */
92
+ gen_branch_fpInactive(s, TCG_COND_NE, lab_end);
93
+ /* !fpInactive: PreserveFPState(), and reads same as FPCXT_S */
94
+ gen_preserve_fp_state(s);
95
+ /* fall through */
96
case ARM_VFP_FPCXT_S:
97
{
98
TCGv_i32 sfpa, control;
99
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
100
default:
101
g_assert_not_reached();
102
}
103
+ if (lab_end) {
104
+ gen_set_label(lab_end);
105
+ }
106
return true;
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
112
{
110
{
113
s->lock = true;
111
/* Do a read from an M-profile floating point system register */
114
112
TCGv_i32 tmp;
115
- /* TODO: input validation! */
113
+ TCGLabel *lab_end = NULL;
116
-
114
+ bool lookup_tb = false;
117
s->config = *newconfig;
115
118
116
switch (fp_sysreg_checks(s, regno)) {
119
s->invalidate = true;
117
case FPSysRegCheckFailed:
120
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
118
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
121
index XXXXXXX..XXXXXXX 100644
119
fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
122
--- a/hw/misc/bcm2835_property.c
120
gen_helper_vfp_set_fpscr(cpu_env, fpscr);
123
+++ b/hw/misc/bcm2835_property.c
121
tcg_temp_free_i32(fpscr);
124
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
122
- gen_lookup_tb(s);
125
case 0x00040002: /* Blank screen */
123
+ lookup_tb = true;
126
resplen = 4;
124
+ break;
127
break;
125
+ }
128
- case 0x00040003: /* Get physical display width/height */
126
+ case ARM_VFP_FPCXT_NS:
129
- stl_le_phys(&s->dma_as, value + 12, fbconfig.xres);
127
+ {
130
- stl_le_phys(&s->dma_as, value + 16, fbconfig.yres);
128
+ TCGv_i32 control, sfpa, fpscr, fpdscr, zero;
131
- resplen = 8;
129
+ TCGLabel *lab_active = gen_new_label();
132
- break;
130
+
133
- case 0x00040004: /* Get virtual display width/height */
131
+ lookup_tb = true;
134
- stl_le_phys(&s->dma_as, value + 12, fbconfig.xres_virtual);
132
+
135
- stl_le_phys(&s->dma_as, value + 16, fbconfig.yres_virtual);
133
+ gen_branch_fpInactive(s, TCG_COND_EQ, lab_active);
136
- resplen = 8;
134
+ /* fpInactive case: reads as FPDSCR_NS */
137
- break;
135
+ TCGv_i32 tmp = load_cpu_field(v7m.fpdscr[M_REG_NS]);
138
case 0x00044003: /* Test physical display width/height */
136
+ storefn(s, opaque, tmp);
139
case 0x00044004: /* Test virtual display width/height */
137
+ lab_end = gen_new_label();
140
resplen = 8;
138
+ tcg_gen_br(lab_end);
141
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
139
+
142
case 0x00048003: /* Set physical display width/height */
140
+ gen_set_label(lab_active);
143
fbconfig.xres = ldl_le_phys(&s->dma_as, value + 12);
141
+ /* !fpInactive: Reads the same as FPCXT_S, but side effects differ */
144
fbconfig.yres = ldl_le_phys(&s->dma_as, value + 16);
142
+ gen_preserve_fp_state(s);
145
+ bcm2835_fb_validate_config(&fbconfig);
143
+ tmp = tcg_temp_new_i32();
146
fbconfig_updated = true;
144
+ sfpa = tcg_temp_new_i32();
147
+ /* fall through */
145
+ fpscr = tcg_temp_new_i32();
148
+ case 0x00040003: /* Get physical display width/height */
146
+ gen_helper_vfp_get_fpscr(fpscr, cpu_env);
149
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.xres);
147
+ tcg_gen_andi_i32(tmp, fpscr, ~FPCR_NZCV_MASK);
150
+ stl_le_phys(&s->dma_as, value + 16, fbconfig.yres);
148
+ control = load_cpu_field(v7m.control[M_REG_S]);
151
resplen = 8;
149
+ tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
152
break;
150
+ tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
153
case 0x00048004: /* Set virtual display width/height */
151
+ tcg_gen_or_i32(tmp, tmp, sfpa);
154
fbconfig.xres_virtual = ldl_le_phys(&s->dma_as, value + 12);
152
+ tcg_temp_free_i32(control);
155
fbconfig.yres_virtual = ldl_le_phys(&s->dma_as, value + 16);
153
+ /* Store result before updating FPSCR, in case it faults */
156
+ bcm2835_fb_validate_config(&fbconfig);
154
+ storefn(s, opaque, tmp);
157
fbconfig_updated = true;
155
+ /* If SFPA is zero then set FPSCR from FPDSCR_NS */
158
+ /* fall through */
156
+ fpdscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
159
+ case 0x00040004: /* Get virtual display width/height */
157
+ zero = tcg_const_i32(0);
160
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.xres_virtual);
158
+ tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, zero, fpdscr, fpscr);
161
+ stl_le_phys(&s->dma_as, value + 16, fbconfig.yres_virtual);
159
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
162
resplen = 8;
160
+ tcg_temp_free_i32(zero);
163
break;
161
+ tcg_temp_free_i32(sfpa);
164
- case 0x00040005: /* Get depth */
162
+ tcg_temp_free_i32(fpdscr);
165
- stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp);
163
+ tcg_temp_free_i32(fpscr);
166
- resplen = 4;
164
break;
167
- break;
165
}
168
case 0x00044005: /* Test depth */
166
default:
169
resplen = 4;
167
g_assert_not_reached();
170
break;
168
}
171
case 0x00048005: /* Set depth */
169
+
172
fbconfig.bpp = ldl_le_phys(&s->dma_as, value + 12);
170
+ if (lab_end) {
173
+ bcm2835_fb_validate_config(&fbconfig);
171
+ gen_set_label(lab_end);
174
fbconfig_updated = true;
172
+ }
175
- resplen = 4;
173
+ if (lookup_tb) {
176
- break;
174
+ gen_lookup_tb(s);
177
- case 0x00040006: /* Get pixel order */
175
+ }
178
- stl_le_phys(&s->dma_as, value + 12, fbconfig.pixo);
176
return true;
179
+ /* fall through */
177
}
180
+ case 0x00040005: /* Get depth */
178
181
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp);
182
resplen = 4;
183
break;
184
case 0x00044006: /* Test pixel order */
185
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
186
break;
187
case 0x00048006: /* Set pixel order */
188
fbconfig.pixo = ldl_le_phys(&s->dma_as, value + 12);
189
+ bcm2835_fb_validate_config(&fbconfig);
190
fbconfig_updated = true;
191
- resplen = 4;
192
- break;
193
- case 0x00040007: /* Get alpha */
194
- stl_le_phys(&s->dma_as, value + 12, fbconfig.alpha);
195
+ /* fall through */
196
+ case 0x00040006: /* Get pixel order */
197
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.pixo);
198
resplen = 4;
199
break;
200
case 0x00044007: /* Test pixel alpha */
201
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
202
break;
203
case 0x00048007: /* Set alpha */
204
fbconfig.alpha = ldl_le_phys(&s->dma_as, value + 12);
205
+ bcm2835_fb_validate_config(&fbconfig);
206
fbconfig_updated = true;
207
+ /* fall through */
208
+ case 0x00040007: /* Get alpha */
209
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.alpha);
210
resplen = 4;
211
break;
212
case 0x00040008: /* Get pitch */
213
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
214
bcm2835_fb_get_pitch(&fbconfig));
215
resplen = 4;
216
break;
217
- case 0x00040009: /* Get virtual offset */
218
- stl_le_phys(&s->dma_as, value + 12, fbconfig.xoffset);
219
- stl_le_phys(&s->dma_as, value + 16, fbconfig.yoffset);
220
- resplen = 8;
221
- break;
222
case 0x00044009: /* Test virtual offset */
223
resplen = 8;
224
break;
225
case 0x00048009: /* Set virtual offset */
226
fbconfig.xoffset = ldl_le_phys(&s->dma_as, value + 12);
227
fbconfig.yoffset = ldl_le_phys(&s->dma_as, value + 16);
228
+ bcm2835_fb_validate_config(&fbconfig);
229
fbconfig_updated = true;
230
+ /* fall through */
231
+ case 0x00040009: /* Get virtual offset */
232
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.xoffset);
233
+ stl_le_phys(&s->dma_as, value + 16, fbconfig.yoffset);
234
resplen = 8;
235
break;
236
case 0x0004000a: /* Get/Test/Set overscan */
237
--
179
--
238
2.18.0
180
2.20.1
239
181
240
182
diff view generated by jsdifflib
1
Refactor bcm2835_fb_mbox_push() to work by calling
1
Now that we have implemented all the features needed by the v8.1M
2
bcm2835_fb_validate_config() and bcm2835_fb_reconfigure(),
2
architecture, we can add the model of the Cortex-M55. This is the
3
so that config set this way is also validated.
3
configuration without MVE support; we'll add MVE later.
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180814144436.679-9-peter.maydell@linaro.org
7
Message-id: 20201210201433.26262-5-peter.maydell@linaro.org
8
---
8
---
9
hw/display/bcm2835_fb.c | 63 ++++++++++++++++++++---------------------
9
target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 31 insertions(+), 32 deletions(-)
10
1 file changed, 42 insertions(+)
11
11
12
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
12
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/display/bcm2835_fb.c
14
--- a/target/arm/cpu_tcg.c
15
+++ b/hw/display/bcm2835_fb.c
15
+++ b/target/arm/cpu_tcg.c
16
@@ -XXX,XX +XXX,XX @@ void bcm2835_fb_validate_config(BCM2835FBConfig *config)
16
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
17
}
17
cpu->ctr = 0x8000c000;
18
}
18
}
19
19
20
-static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
20
+static void cortex_m55_initfn(Object *obj)
21
-{
22
- uint32_t pitch;
23
- uint32_t size;
24
-
25
- value &= ~0xf;
26
-
27
- s->lock = true;
28
-
29
- s->config.xres = ldl_le_phys(&s->dma_as, value);
30
- s->config.yres = ldl_le_phys(&s->dma_as, value + 4);
31
- s->config.xres_virtual = ldl_le_phys(&s->dma_as, value + 8);
32
- s->config.yres_virtual = ldl_le_phys(&s->dma_as, value + 12);
33
- s->config.bpp = ldl_le_phys(&s->dma_as, value + 20);
34
- s->config.xoffset = ldl_le_phys(&s->dma_as, value + 24);
35
- s->config.yoffset = ldl_le_phys(&s->dma_as, value + 28);
36
-
37
- s->config.base = s->vcram_base | (value & 0xc0000000);
38
- s->config.base += BCM2835_FB_OFFSET;
39
-
40
- pitch = bcm2835_fb_get_pitch(&s->config);
41
- size = bcm2835_fb_get_size(&s->config);
42
-
43
- stl_le_phys(&s->dma_as, value + 16, pitch);
44
- stl_le_phys(&s->dma_as, value + 32, s->config.base);
45
- stl_le_phys(&s->dma_as, value + 36, size);
46
-
47
- s->invalidate = true;
48
- qemu_console_resize(s->con, s->config.xres, s->config.yres);
49
- s->lock = false;
50
-}
51
-
52
void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig)
53
{
54
s->lock = true;
55
@@ -XXX,XX +XXX,XX @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig)
56
s->lock = false;
57
}
58
59
+static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
60
+{
21
+{
61
+ uint32_t pitch;
22
+ ARMCPU *cpu = ARM_CPU(obj);
62
+ uint32_t size;
63
+ BCM2835FBConfig newconf;
64
+
23
+
65
+ value &= ~0xf;
24
+ set_feature(&cpu->env, ARM_FEATURE_V8);
66
+
25
+ set_feature(&cpu->env, ARM_FEATURE_V8_1M);
67
+ newconf.xres = ldl_le_phys(&s->dma_as, value);
26
+ set_feature(&cpu->env, ARM_FEATURE_M);
68
+ newconf.yres = ldl_le_phys(&s->dma_as, value + 4);
27
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
69
+ newconf.xres_virtual = ldl_le_phys(&s->dma_as, value + 8);
28
+ set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
70
+ newconf.yres_virtual = ldl_le_phys(&s->dma_as, value + 12);
29
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
71
+ newconf.bpp = ldl_le_phys(&s->dma_as, value + 20);
30
+ cpu->midr = 0x410fd221; /* r0p1 */
72
+ newconf.xoffset = ldl_le_phys(&s->dma_as, value + 24);
31
+ cpu->revidr = 0;
73
+ newconf.yoffset = ldl_le_phys(&s->dma_as, value + 28);
32
+ cpu->pmsav7_dregion = 16;
74
+
33
+ cpu->sau_sregion = 8;
75
+ newconf.base = s->vcram_base | (value & 0xc0000000);
34
+ /*
76
+ newconf.base += BCM2835_FB_OFFSET;
35
+ * These are the MVFR* values for the FPU, no MVE configuration;
77
+
36
+ * we will update them later when we implement MVE
78
+ bcm2835_fb_validate_config(&newconf);
37
+ */
79
+
38
+ cpu->isar.mvfr0 = 0x10110221;
80
+ pitch = bcm2835_fb_get_pitch(&newconf);
39
+ cpu->isar.mvfr1 = 0x12100011;
81
+ size = bcm2835_fb_get_size(&newconf);
40
+ cpu->isar.mvfr2 = 0x00000040;
82
+
41
+ cpu->isar.id_pfr0 = 0x20000030;
83
+ stl_le_phys(&s->dma_as, value + 16, pitch);
42
+ cpu->isar.id_pfr1 = 0x00000230;
84
+ stl_le_phys(&s->dma_as, value + 32, newconf.base);
43
+ cpu->isar.id_dfr0 = 0x10200000;
85
+ stl_le_phys(&s->dma_as, value + 36, size);
44
+ cpu->id_afr0 = 0x00000000;
86
+
45
+ cpu->isar.id_mmfr0 = 0x00111040;
87
+ bcm2835_fb_reconfigure(s, &newconf);
46
+ cpu->isar.id_mmfr1 = 0x00000000;
47
+ cpu->isar.id_mmfr2 = 0x01000000;
48
+ cpu->isar.id_mmfr3 = 0x00000011;
49
+ cpu->isar.id_isar0 = 0x01103110;
50
+ cpu->isar.id_isar1 = 0x02212000;
51
+ cpu->isar.id_isar2 = 0x20232232;
52
+ cpu->isar.id_isar3 = 0x01111131;
53
+ cpu->isar.id_isar4 = 0x01310132;
54
+ cpu->isar.id_isar5 = 0x00000000;
55
+ cpu->isar.id_isar6 = 0x00000000;
56
+ cpu->clidr = 0x00000000; /* caches not implemented */
57
+ cpu->ctr = 0x8303c003;
88
+}
58
+}
89
+
59
+
90
static uint64_t bcm2835_fb_read(void *opaque, hwaddr offset, unsigned size)
60
static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
91
{
61
/* Dummy the TCM region regs for the moment */
92
BCM2835FBState *s = opaque;
62
{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
64
.class_init = arm_v7m_class_init },
65
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
66
.class_init = arm_v7m_class_init },
67
+ { .name = "cortex-m55", .initfn = cortex_m55_initfn,
68
+ .class_init = arm_v7m_class_init },
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
71
{ .name = "ti925t", .initfn = ti925t_initfn },
93
--
72
--
94
2.18.0
73
2.20.1
95
74
96
75
diff view generated by jsdifflib
1
Connect the VIRQ and VFIQ lines from the GIC to the CPU;
1
Support for running KVM on 32-bit Arm hosts was removed in commit
2
these exist always for both CPU and GIC whether the
2
82bf7ae84ce739e. You can still run a 32-bit guest on a 64-bit Arm
3
virtualization extensions are enabled or not, so we
3
host CPU, but because Arm KVM requires the host and guest CPU types
4
can just unconditionally connect them.
4
to match, it is not possible to run a guest that requires a Cortex-A9
5
or Cortex-A15 CPU there. That means that the code in the
6
highbank/midway board models to support KVM is no longer used, and we
7
can delete it.
5
8
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180821132811.17675-5-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20201215144215.28482-1-peter.maydell@linaro.org
9
---
13
---
10
hw/arm/highbank.c | 6 ++++++
14
hw/arm/highbank.c | 14 ++++----------
11
1 file changed, 6 insertions(+)
15
1 file changed, 4 insertions(+), 10 deletions(-)
12
16
13
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
17
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/highbank.c
19
--- a/hw/arm/highbank.c
16
+++ b/hw/arm/highbank.c
20
+++ b/hw/arm/highbank.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/arm/boot.h"
23
#include "hw/loader.h"
24
#include "net/net.h"
25
-#include "sysemu/kvm.h"
26
#include "sysemu/runstate.h"
27
#include "sysemu/sysemu.h"
28
#include "hw/boards.h"
29
@@ -XXX,XX +XXX,XX @@
30
#include "hw/cpu/a15mpcore.h"
31
#include "qemu/log.h"
32
#include "qom/object.h"
33
+#include "cpu.h"
34
35
#define SMP_BOOT_ADDR 0x100
36
#define SMP_BOOT_REG 0x40
17
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
37
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
18
int n;
38
highbank_binfo.loader_start = 0;
19
qemu_irq cpu_irq[4];
39
highbank_binfo.write_secondary_boot = hb_write_secondary;
20
qemu_irq cpu_fiq[4];
40
highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
21
+ qemu_irq cpu_virq[4];
41
- if (!kvm_enabled()) {
22
+ qemu_irq cpu_vfiq[4];
42
- highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
23
MemoryRegion *sysram;
43
- highbank_binfo.write_board_setup = hb_write_board_setup;
24
MemoryRegion *dram;
44
- highbank_binfo.secure_board_setup = true;
25
MemoryRegion *sysmem;
45
- } else {
26
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
46
- warn_report("cannot load built-in Monitor support "
27
object_property_set_bool(cpuobj, true, "realized", &error_fatal);
47
- "if KVM is enabled. Some guests (such as Linux) "
28
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
48
- "may not boot.");
29
cpu_fiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ);
49
- }
30
+ cpu_virq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_VIRQ);
50
+ highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
31
+ cpu_vfiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_VFIQ);
51
+ highbank_binfo.write_board_setup = hb_write_board_setup;
32
}
52
+ highbank_binfo.secure_board_setup = true;
33
53
34
sysmem = get_system_memory();
54
arm_load_kernel(ARM_CPU(first_cpu), machine, &highbank_binfo);
35
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
55
}
36
for (n = 0; n < smp_cpus; n++) {
37
sysbus_connect_irq(busdev, n, cpu_irq[n]);
38
sysbus_connect_irq(busdev, n + smp_cpus, cpu_fiq[n]);
39
+ sysbus_connect_irq(busdev, n + 2 * smp_cpus, cpu_virq[n]);
40
+ sysbus_connect_irq(busdev, n + 3 * smp_cpus, cpu_vfiq[n]);
41
}
42
43
for (n = 0; n < 128; n++) {
44
--
56
--
45
2.18.0
57
2.20.1
46
58
47
59
diff view generated by jsdifflib
1
Abstract out the calculation of the pitch and size of the
1
Currently timer_free() is a simple wrapper for g_free(). This means
2
framebuffer into functions that operate on the BCM2835FBConfig
2
that the timer being freed must not be currently active, as otherwise
3
struct -- these are about to get a little more complicated
3
QEMU might crash later when the active list is processed and still
4
when we add support for virtual and physical sizes differing.
4
has a pointer to freed memory on it. As a result almost all calls to
5
timer_free() are preceded by a timer_del() call, as can be seen in
6
the output of
7
git grep -B1 '\<timer_free\>'
8
9
This is unfortunate API design as it makes it easy to accidentally
10
misuse (by forgetting the timer_del()), and the correct use is
11
annoyingly verbose.
12
13
Make timer_free() imply a timer_del().
5
14
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180814144436.679-6-peter.maydell@linaro.org
18
Message-id: 20201215154107.3255-2-peter.maydell@linaro.org
9
---
19
---
10
include/hw/display/bcm2835_fb.h | 22 ++++++++++++++++++++++
20
include/qemu/timer.h | 24 +++++++++++++-----------
11
hw/display/bcm2835_fb.c | 6 +++---
21
1 file changed, 13 insertions(+), 11 deletions(-)
12
hw/misc/bcm2835_property.c | 4 ++--
13
3 files changed, 27 insertions(+), 5 deletions(-)
14
22
15
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
23
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/display/bcm2835_fb.h
25
--- a/include/qemu/timer.h
18
+++ b/include/hw/display/bcm2835_fb.h
26
+++ b/include/qemu/timer.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
27
@@ -XXX,XX +XXX,XX @@ static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
20
28
*/
21
void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig);
29
void timer_deinit(QEMUTimer *ts);
30
31
-/**
32
- * timer_free:
33
- * @ts: the timer
34
- *
35
- * Free a timer (it must not be on the active list)
36
- */
37
-static inline void timer_free(QEMUTimer *ts)
38
-{
39
- g_free(ts);
40
-}
41
-
42
/**
43
* timer_del:
44
* @ts: the timer
45
@@ -XXX,XX +XXX,XX @@ static inline void timer_free(QEMUTimer *ts)
46
*/
47
void timer_del(QEMUTimer *ts);
22
48
23
+/**
49
+/**
24
+ * bcm2835_fb_get_pitch: return number of bytes per line of the framebuffer
50
+ * timer_free:
25
+ * @config: configuration info for the framebuffer
51
+ * @ts: the timer
26
+ *
52
+ *
27
+ * Return the number of bytes per line of the framebuffer, ie the number
53
+ * Free a timer. This will call timer_del() for you to remove
28
+ * that must be added to a pixel address to get the address of the pixel
54
+ * the timer from the active list if it was still active.
29
+ * directly below it on screen.
30
+ */
55
+ */
31
+static inline uint32_t bcm2835_fb_get_pitch(BCM2835FBConfig *config)
56
+static inline void timer_free(QEMUTimer *ts)
32
+{
57
+{
33
+ return config->xres * (config->bpp >> 3);
58
+ timer_del(ts);
59
+ g_free(ts);
34
+}
60
+}
35
+
61
+
36
+/**
62
/**
37
+ * bcm2835_fb_get_size: return total size of framebuffer in bytes
63
* timer_mod_ns:
38
+ * @config: configuration info for the framebuffer
64
* @ts: the timer
39
+ */
40
+static inline uint32_t bcm2835_fb_get_size(BCM2835FBConfig *config)
41
+{
42
+ return config->yres * bcm2835_fb_get_pitch(config);
43
+}
44
+
45
#endif
46
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/display/bcm2835_fb.c
49
+++ b/hw/display/bcm2835_fb.c
50
@@ -XXX,XX +XXX,XX @@ static void fb_update_display(void *opaque)
51
return;
52
}
53
54
- src_width = s->config.xres * (s->config.bpp >> 3);
55
+ src_width = bcm2835_fb_get_pitch(&s->config);
56
dest_width = s->config.xres;
57
58
switch (surface_bits_per_pixel(surface)) {
59
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
60
61
/* TODO - Manage properly virtual resolution */
62
63
- pitch = s->config.xres * (s->config.bpp >> 3);
64
- size = s->config.yres * pitch;
65
+ pitch = bcm2835_fb_get_pitch(&s->config);
66
+ size = bcm2835_fb_get_size(&s->config);
67
68
stl_le_phys(&s->dma_as, value + 16, pitch);
69
stl_le_phys(&s->dma_as, value + 32, s->config.base);
70
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/misc/bcm2835_property.c
73
+++ b/hw/misc/bcm2835_property.c
74
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
75
case 0x00040001: /* Allocate buffer */
76
stl_le_phys(&s->dma_as, value + 12, fbconfig.base);
77
stl_le_phys(&s->dma_as, value + 16,
78
- fbconfig.xres * fbconfig.yres * fbconfig.bpp / 8);
79
+ bcm2835_fb_get_size(&fbconfig));
80
resplen = 8;
81
break;
82
case 0x00048001: /* Release buffer */
83
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
84
break;
85
case 0x00040008: /* Get pitch */
86
stl_le_phys(&s->dma_as, value + 12,
87
- fbconfig.xres * fbconfig.bpp / 8);
88
+ bcm2835_fb_get_pitch(&fbconfig));
89
resplen = 4;
90
break;
91
case 0x00040009: /* Get virtual offset */
92
--
65
--
93
2.18.0
66
2.20.1
94
67
95
68
diff view generated by jsdifflib
1
Create a new include file for the pl022's device struct,
1
Now that timer_free() implicitly calls timer_del(), sequences
2
type macros, etc, so that it can be instantiated using
2
timer_del(mytimer);
3
the "embedded struct" coding style.
3
timer_free(mytimer);
4
4
5
While we're adding the new file to MAINTAINERS, add
5
can be simplified to just
6
also the .c file, which was missing an entry.
6
timer_free(mytimer);
7
8
Add a Coccinelle script to do this transformation.
7
9
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
10
Message-id: 20180820141116.9118-16-peter.maydell@linaro.org
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20201215154107.3255-3-peter.maydell@linaro.org
12
---
15
---
13
include/hw/ssi/pl022.h | 51 ++++++++++++++++++++++++++++++++++++++++++
16
scripts/coccinelle/timer-del-timer-free.cocci | 18 ++++++++++++++++++
14
hw/ssi/pl022.c | 26 +--------------------
17
1 file changed, 18 insertions(+)
15
MAINTAINERS | 2 ++
18
create mode 100644 scripts/coccinelle/timer-del-timer-free.cocci
16
3 files changed, 54 insertions(+), 25 deletions(-)
17
create mode 100644 include/hw/ssi/pl022.h
18
19
19
diff --git a/include/hw/ssi/pl022.h b/include/hw/ssi/pl022.h
20
diff --git a/scripts/coccinelle/timer-del-timer-free.cocci b/scripts/coccinelle/timer-del-timer-free.cocci
20
new file mode 100644
21
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
--- /dev/null
23
+++ b/include/hw/ssi/pl022.h
24
+++ b/scripts/coccinelle/timer-del-timer-free.cocci
24
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
25
+/*
26
+// Remove superfluous timer_del() calls
26
+ * ARM PrimeCell PL022 Synchronous Serial Port
27
+//
27
+ *
28
+// Copyright Linaro Limited 2020
28
+ * Copyright (c) 2007 CodeSourcery.
29
+// This work is licensed under the terms of the GNU GPLv2 or later.
29
+ * Written by Paul Brook
30
+//
30
+ *
31
+// spatch --macro-file scripts/cocci-macro-file.h \
31
+ * This program is free software; you can redistribute it and/or modify
32
+// --sp-file scripts/coccinelle/timer-del-timer-free.cocci \
32
+ * it under the terms of the GNU General Public License version 2 or
33
+// --in-place --dir .
33
+ * (at your option) any later version.
34
+//
34
+ */
35
+// The timer_free() function now implicitly calls timer_del()
36
+// for you, so calls to timer_del() immediately before the
37
+// timer_free() of the same timer can be deleted.
35
+
38
+
36
+/* This is a model of the Arm PrimeCell PL022 synchronous serial port.
39
+@@
37
+ * The PL022 TRM is:
40
+expression T;
38
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0194h/DDI0194H_ssp_pl022_trm.pdf
41
+@@
39
+ *
42
+-timer_del(T);
40
+ * QEMU interface:
43
+ timer_free(T);
41
+ * + sysbus IRQ: SSPINTR combined interrupt line
42
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
43
+ */
44
+
45
+#ifndef HW_SSI_PL022_H
46
+#define HW_SSI_PL022_H
47
+
48
+#include "hw/sysbus.h"
49
+
50
+#define TYPE_PL022 "pl022"
51
+#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022)
52
+
53
+typedef struct PL022State {
54
+ SysBusDevice parent_obj;
55
+
56
+ MemoryRegion iomem;
57
+ uint32_t cr0;
58
+ uint32_t cr1;
59
+ uint32_t bitmask;
60
+ uint32_t sr;
61
+ uint32_t cpsr;
62
+ uint32_t is;
63
+ uint32_t im;
64
+ /* The FIFO head points to the next empty entry. */
65
+ int tx_fifo_head;
66
+ int rx_fifo_head;
67
+ int tx_fifo_len;
68
+ int rx_fifo_len;
69
+ uint16_t tx_fifo[8];
70
+ uint16_t rx_fifo[8];
71
+ qemu_irq irq;
72
+ SSIBus *ssi;
73
+} PL022State;
74
+
75
+#endif
76
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/ssi/pl022.c
79
+++ b/hw/ssi/pl022.c
80
@@ -XXX,XX +XXX,XX @@
81
82
#include "qemu/osdep.h"
83
#include "hw/sysbus.h"
84
+#include "hw/ssi/pl022.h"
85
#include "hw/ssi/ssi.h"
86
#include "qemu/log.h"
87
88
@@ -XXX,XX +XXX,XX @@ do { fprintf(stderr, "pl022: error: " fmt , ## __VA_ARGS__);} while (0)
89
#define PL022_INT_RX 0x04
90
#define PL022_INT_TX 0x08
91
92
-#define TYPE_PL022 "pl022"
93
-#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022)
94
-
95
-typedef struct PL022State {
96
- SysBusDevice parent_obj;
97
-
98
- MemoryRegion iomem;
99
- uint32_t cr0;
100
- uint32_t cr1;
101
- uint32_t bitmask;
102
- uint32_t sr;
103
- uint32_t cpsr;
104
- uint32_t is;
105
- uint32_t im;
106
- /* The FIFO head points to the next empty entry. */
107
- int tx_fifo_head;
108
- int rx_fifo_head;
109
- int tx_fifo_len;
110
- int rx_fifo_len;
111
- uint16_t tx_fifo[8];
112
- uint16_t rx_fifo[8];
113
- qemu_irq irq;
114
- SSIBus *ssi;
115
-} PL022State;
116
-
117
static const unsigned char pl022_id[8] =
118
{ 0x22, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
119
120
diff --git a/MAINTAINERS b/MAINTAINERS
121
index XXXXXXX..XXXXXXX 100644
122
--- a/MAINTAINERS
123
+++ b/MAINTAINERS
124
@@ -XXX,XX +XXX,XX @@ F: hw/gpio/pl061.c
125
F: hw/input/pl050.c
126
F: hw/intc/pl190.c
127
F: hw/sd/pl181.c
128
+F: hw/ssi/pl022.c
129
+F: include/hw/ssi/pl022.h
130
F: hw/timer/pl031.c
131
F: include/hw/arm/primecell.h
132
F: hw/timer/cmsdk-apb-timer.c
133
--
44
--
134
2.18.0
45
2.20.1
135
46
136
47
diff view generated by jsdifflib
1
The raspi framebuffir in bcm2835_fb supports the definition
1
This commit is the result of running the timer-del-timer-free.cocci
2
of a virtual "viewport", which is smaller than the full
2
script on the whole source tree.
3
physical framebuffer size and at an adjustable offset within
4
it. Only the viewport area is sent to the screen. This allows
5
the guest to do things like double buffering, or scrolling
6
by adjusting the viewport origin. Currently QEMU doesn't
7
implement this at all.
8
9
Add support for this feature:
10
* the property mailbox code needs to distinguish the
11
virtual width/height from the physical width/height
12
* the framebuffer code needs to do something with the
13
virtual width/height/origin information
14
15
Note that the wiki documentation on the semantics of the
16
virtual and physical height and width has it the wrong way
17
around -- the virtual size is the size of the allocated
18
buffer, and the physical size is the size of the display,
19
so the virtual size is always the same as or larger than
20
the physical.
21
22
If the viewport size is set smaller than the physical
23
screen size, we ignore the viewport settings completely
24
and just display the physical screen area.
25
3
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Corey Minyard <cminyard@mvista.com>
6
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Message-id: 20180814144436.679-7-peter.maydell@linaro.org
9
Message-id: 20201215154107.3255-4-peter.maydell@linaro.org
29
---
10
---
30
include/hw/display/bcm2835_fb.h | 6 ++++--
11
block/iscsi.c | 2 --
31
hw/display/bcm2835_fb.c | 28 ++++++++++++++++++++++------
12
block/nbd.c | 1 -
32
hw/misc/bcm2835_property.c | 21 +++++++++++++++------
13
block/qcow2.c | 1 -
33
3 files changed, 41 insertions(+), 14 deletions(-)
14
hw/block/nvme.c | 2 --
15
hw/char/serial.c | 2 --
16
hw/char/virtio-serial-bus.c | 2 --
17
hw/ide/core.c | 1 -
18
hw/input/hid.c | 1 -
19
hw/intc/apic.c | 1 -
20
hw/intc/ioapic.c | 1 -
21
hw/ipmi/ipmi_bmc_extern.c | 1 -
22
hw/net/e1000.c | 3 ---
23
hw/net/e1000e_core.c | 8 --------
24
hw/net/pcnet-pci.c | 1 -
25
hw/net/rtl8139.c | 1 -
26
hw/net/spapr_llan.c | 1 -
27
hw/net/virtio-net.c | 2 --
28
hw/s390x/s390-pci-inst.c | 1 -
29
hw/sd/sd.c | 1 -
30
hw/sd/sdhci.c | 2 --
31
hw/usb/dev-hub.c | 1 -
32
hw/usb/hcd-ehci.c | 1 -
33
hw/usb/hcd-ohci-pci.c | 1 -
34
hw/usb/hcd-uhci.c | 1 -
35
hw/usb/hcd-xhci.c | 1 -
36
hw/usb/redirect.c | 1 -
37
hw/vfio/display.c | 1 -
38
hw/virtio/vhost-vsock-common.c | 1 -
39
hw/virtio/virtio-balloon.c | 1 -
40
hw/virtio/virtio-rng.c | 1 -
41
hw/watchdog/wdt_diag288.c | 1 -
42
hw/watchdog/wdt_i6300esb.c | 1 -
43
migration/colo.c | 1 -
44
monitor/hmp-cmds.c | 1 -
45
net/announce.c | 1 -
46
net/colo-compare.c | 1 -
47
net/slirp.c | 1 -
48
replay/replay-debugging.c | 1 -
49
target/s390x/cpu.c | 2 --
50
ui/console.c | 1 -
51
ui/spice-core.c | 1 -
52
util/throttle.c | 1 -
53
42 files changed, 58 deletions(-)
34
54
35
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
55
diff --git a/block/iscsi.c b/block/iscsi.c
36
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/display/bcm2835_fb.h
57
--- a/block/iscsi.c
38
+++ b/include/hw/display/bcm2835_fb.h
58
+++ b/block/iscsi.c
39
@@ -XXX,XX +XXX,XX @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig);
59
@@ -XXX,XX +XXX,XX @@ static void iscsi_detach_aio_context(BlockDriverState *bs)
40
*/
60
iscsilun->events = 0;
41
static inline uint32_t bcm2835_fb_get_pitch(BCM2835FBConfig *config)
61
42
{
62
if (iscsilun->nop_timer) {
43
- return config->xres * (config->bpp >> 3);
63
- timer_del(iscsilun->nop_timer);
44
+ uint32_t xres = MAX(config->xres, config->xres_virtual);
64
timer_free(iscsilun->nop_timer);
45
+ return xres * (config->bpp >> 3);
65
iscsilun->nop_timer = NULL;
46
}
66
}
47
67
if (iscsilun->event_timer) {
48
/**
68
- timer_del(iscsilun->event_timer);
49
@@ -XXX,XX +XXX,XX @@ static inline uint32_t bcm2835_fb_get_pitch(BCM2835FBConfig *config)
69
timer_free(iscsilun->event_timer);
50
*/
70
iscsilun->event_timer = NULL;
51
static inline uint32_t bcm2835_fb_get_size(BCM2835FBConfig *config)
71
}
52
{
72
diff --git a/block/nbd.c b/block/nbd.c
53
- return config->yres * bcm2835_fb_get_pitch(config);
73
index XXXXXXX..XXXXXXX 100644
54
+ uint32_t yres = MAX(config->yres, config->yres_virtual);
74
--- a/block/nbd.c
55
+ return yres * bcm2835_fb_get_pitch(config);
75
+++ b/block/nbd.c
56
}
76
@@ -XXX,XX +XXX,XX @@ static void nbd_recv_coroutines_wake_all(BDRVNBDState *s)
57
77
static void reconnect_delay_timer_del(BDRVNBDState *s)
58
#endif
78
{
59
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
79
if (s->reconnect_delay_timer) {
60
index XXXXXXX..XXXXXXX 100644
80
- timer_del(s->reconnect_delay_timer);
61
--- a/hw/display/bcm2835_fb.c
81
timer_free(s->reconnect_delay_timer);
62
+++ b/hw/display/bcm2835_fb.c
82
s->reconnect_delay_timer = NULL;
63
@@ -XXX,XX +XXX,XX @@ static void draw_line_src16(void *opaque, uint8_t *dst, const uint8_t *src,
83
}
64
}
84
diff --git a/block/qcow2.c b/block/qcow2.c
65
}
85
index XXXXXXX..XXXXXXX 100644
66
86
--- a/block/qcow2.c
67
+static bool fb_use_offsets(BCM2835FBConfig *config)
87
+++ b/block/qcow2.c
68
+{
88
@@ -XXX,XX +XXX,XX @@ static void cache_clean_timer_del(BlockDriverState *bs)
69
+ /*
89
{
70
+ * Return true if we should use the viewport offsets.
90
BDRVQcow2State *s = bs->opaque;
71
+ * Experimentally, the hardware seems to do this only if the
91
if (s->cache_clean_timer) {
72
+ * viewport size is larger than the physical screen. (It doesn't
92
- timer_del(s->cache_clean_timer);
73
+ * prevent the guest setting this silly viewport setting, though...)
93
timer_free(s->cache_clean_timer);
74
+ */
94
s->cache_clean_timer = NULL;
75
+ return config->xres_virtual > config->xres &&
95
}
76
+ config->yres_virtual > config->yres;
96
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
77
+}
97
index XXXXXXX..XXXXXXX 100644
78
+
98
--- a/hw/block/nvme.c
79
static void fb_update_display(void *opaque)
99
+++ b/hw/block/nvme.c
80
{
100
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest *req)
81
BCM2835FBState *s = opaque;
101
static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n)
82
@@ -XXX,XX +XXX,XX @@ static void fb_update_display(void *opaque)
102
{
83
int last = 0;
103
n->sq[sq->sqid] = NULL;
84
int src_width = 0;
104
- timer_del(sq->timer);
85
int dest_width = 0;
105
timer_free(sq->timer);
86
+ uint32_t xoff = 0, yoff = 0;
106
g_free(sq->io_req);
87
107
if (sq->sqid) {
88
if (s->lock || !s->config.xres) {
108
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest *req)
109
static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n)
110
{
111
n->cq[cq->cqid] = NULL;
112
- timer_del(cq->timer);
113
timer_free(cq->timer);
114
msix_vector_unuse(&n->parent_obj, cq->vector);
115
if (cq->cqid) {
116
diff --git a/hw/char/serial.c b/hw/char/serial.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/char/serial.c
119
+++ b/hw/char/serial.c
120
@@ -XXX,XX +XXX,XX @@ static void serial_unrealize(DeviceState *dev)
121
122
qemu_chr_fe_deinit(&s->chr, false);
123
124
- timer_del(s->modem_status_poll);
125
timer_free(s->modem_status_poll);
126
127
- timer_del(s->fifo_timeout_timer);
128
timer_free(s->fifo_timeout_timer);
129
130
fifo8_destroy(&s->recv_fifo);
131
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/char/virtio-serial-bus.c
134
+++ b/hw/char/virtio-serial-bus.c
135
@@ -XXX,XX +XXX,XX @@ static void virtio_serial_post_load_timer_cb(void *opaque)
136
}
137
}
138
g_free(s->post_load->connected);
139
- timer_del(s->post_load->timer);
140
timer_free(s->post_load->timer);
141
g_free(s->post_load);
142
s->post_load = NULL;
143
@@ -XXX,XX +XXX,XX @@ static void virtio_serial_device_unrealize(DeviceState *dev)
144
g_free(vser->ports_map);
145
if (vser->post_load) {
146
g_free(vser->post_load->connected);
147
- timer_del(vser->post_load->timer);
148
timer_free(vser->post_load->timer);
149
g_free(vser->post_load);
150
}
151
diff --git a/hw/ide/core.c b/hw/ide/core.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/hw/ide/core.c
154
+++ b/hw/ide/core.c
155
@@ -XXX,XX +XXX,XX @@ void ide_init2(IDEBus *bus, qemu_irq irq)
156
157
void ide_exit(IDEState *s)
158
{
159
- timer_del(s->sector_write_timer);
160
timer_free(s->sector_write_timer);
161
qemu_vfree(s->smart_selftest_data);
162
qemu_vfree(s->io_buffer);
163
diff --git a/hw/input/hid.c b/hw/input/hid.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/hw/input/hid.c
166
+++ b/hw/input/hid.c
167
@@ -XXX,XX +XXX,XX @@ static void hid_idle_timer(void *opaque)
168
static void hid_del_idle_timer(HIDState *hs)
169
{
170
if (hs->idle_timer) {
171
- timer_del(hs->idle_timer);
172
timer_free(hs->idle_timer);
173
hs->idle_timer = NULL;
174
}
175
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
176
index XXXXXXX..XXXXXXX 100644
177
--- a/hw/intc/apic.c
178
+++ b/hw/intc/apic.c
179
@@ -XXX,XX +XXX,XX @@ static void apic_unrealize(DeviceState *dev)
180
{
181
APICCommonState *s = APIC(dev);
182
183
- timer_del(s->timer);
184
timer_free(s->timer);
185
local_apics[s->id] = NULL;
186
}
187
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/hw/intc/ioapic.c
190
+++ b/hw/intc/ioapic.c
191
@@ -XXX,XX +XXX,XX @@ static void ioapic_unrealize(DeviceState *dev)
192
{
193
IOAPICCommonState *s = IOAPIC_COMMON(dev);
194
195
- timer_del(s->delayed_ioapic_service_timer);
196
timer_free(s->delayed_ioapic_service_timer);
197
}
198
199
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/ipmi/ipmi_bmc_extern.c
202
+++ b/hw/ipmi/ipmi_bmc_extern.c
203
@@ -XXX,XX +XXX,XX @@ static void ipmi_bmc_extern_finalize(Object *obj)
204
{
205
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);
206
207
- timer_del(ibe->extern_timer);
208
timer_free(ibe->extern_timer);
209
}
210
211
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/hw/net/e1000.c
214
+++ b/hw/net/e1000.c
215
@@ -XXX,XX +XXX,XX @@ pci_e1000_uninit(PCIDevice *dev)
216
{
217
E1000State *d = E1000(dev);
218
219
- timer_del(d->autoneg_timer);
220
timer_free(d->autoneg_timer);
221
- timer_del(d->mit_timer);
222
timer_free(d->mit_timer);
223
- timer_del(d->flush_queue_timer);
224
timer_free(d->flush_queue_timer);
225
qemu_del_nic(d->nic);
226
}
227
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/hw/net/e1000e_core.c
230
+++ b/hw/net/e1000e_core.c
231
@@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_pci_unint(E1000ECore *core)
232
{
233
int i;
234
235
- timer_del(core->radv.timer);
236
timer_free(core->radv.timer);
237
- timer_del(core->rdtr.timer);
238
timer_free(core->rdtr.timer);
239
- timer_del(core->raid.timer);
240
timer_free(core->raid.timer);
241
242
- timer_del(core->tadv.timer);
243
timer_free(core->tadv.timer);
244
- timer_del(core->tidv.timer);
245
timer_free(core->tidv.timer);
246
247
- timer_del(core->itr.timer);
248
timer_free(core->itr.timer);
249
250
for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
251
- timer_del(core->eitr[i].timer);
252
timer_free(core->eitr[i].timer);
253
}
254
}
255
@@ -XXX,XX +XXX,XX @@ e1000e_core_pci_uninit(E1000ECore *core)
256
{
257
int i;
258
259
- timer_del(core->autoneg_timer);
260
timer_free(core->autoneg_timer);
261
262
e1000e_intrmgr_pci_unint(core);
263
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
264
index XXXXXXX..XXXXXXX 100644
265
--- a/hw/net/pcnet-pci.c
266
+++ b/hw/net/pcnet-pci.c
267
@@ -XXX,XX +XXX,XX @@ static void pci_pcnet_uninit(PCIDevice *dev)
268
PCIPCNetState *d = PCI_PCNET(dev);
269
270
qemu_free_irq(d->state.irq);
271
- timer_del(d->state.poll_timer);
272
timer_free(d->state.poll_timer);
273
qemu_del_nic(d->state.nic);
274
}
275
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
276
index XXXXXXX..XXXXXXX 100644
277
--- a/hw/net/rtl8139.c
278
+++ b/hw/net/rtl8139.c
279
@@ -XXX,XX +XXX,XX @@ static void pci_rtl8139_uninit(PCIDevice *dev)
280
281
g_free(s->cplus_txbuffer);
282
s->cplus_txbuffer = NULL;
283
- timer_del(s->timer);
284
timer_free(s->timer);
285
qemu_del_nic(s->nic);
286
}
287
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
288
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/net/spapr_llan.c
290
+++ b/hw/net/spapr_llan.c
291
@@ -XXX,XX +XXX,XX @@ static void spapr_vlan_instance_finalize(Object *obj)
292
}
293
294
if (dev->rxp_timer) {
295
- timer_del(dev->rxp_timer);
296
timer_free(dev->rxp_timer);
297
}
298
}
299
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
300
index XXXXXXX..XXXXXXX 100644
301
--- a/hw/net/virtio-net.c
302
+++ b/hw/net/virtio-net.c
303
@@ -XXX,XX +XXX,XX @@ static void virtio_net_rsc_cleanup(VirtIONet *n)
304
g_free(seg);
305
}
306
307
- timer_del(chain->drain_timer);
308
timer_free(chain->drain_timer);
309
QTAILQ_REMOVE(&n->rsc_chains, chain, next);
310
g_free(chain);
311
@@ -XXX,XX +XXX,XX @@ static void virtio_net_del_queue(VirtIONet *n, int index)
312
313
virtio_del_queue(vdev, index * 2);
314
if (q->tx_timer) {
315
- timer_del(q->tx_timer);
316
timer_free(q->tx_timer);
317
q->tx_timer = NULL;
318
} else {
319
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
320
index XXXXXXX..XXXXXXX 100644
321
--- a/hw/s390x/s390-pci-inst.c
322
+++ b/hw/s390x/s390-pci-inst.c
323
@@ -XXX,XX +XXX,XX @@ void pci_dereg_ioat(S390PCIIOMMU *iommu)
324
void fmb_timer_free(S390PCIBusDevice *pbdev)
325
{
326
if (pbdev->fmb_timer) {
327
- timer_del(pbdev->fmb_timer);
328
timer_free(pbdev->fmb_timer);
329
pbdev->fmb_timer = NULL;
330
}
331
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
332
index XXXXXXX..XXXXXXX 100644
333
--- a/hw/sd/sd.c
334
+++ b/hw/sd/sd.c
335
@@ -XXX,XX +XXX,XX @@ static void sd_instance_finalize(Object *obj)
336
{
337
SDState *sd = SD_CARD(obj);
338
339
- timer_del(sd->ocr_power_timer);
340
timer_free(sd->ocr_power_timer);
341
}
342
343
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
344
index XXXXXXX..XXXXXXX 100644
345
--- a/hw/sd/sdhci.c
346
+++ b/hw/sd/sdhci.c
347
@@ -XXX,XX +XXX,XX @@ void sdhci_initfn(SDHCIState *s)
348
349
void sdhci_uninitfn(SDHCIState *s)
350
{
351
- timer_del(s->insert_timer);
352
timer_free(s->insert_timer);
353
- timer_del(s->transfer_timer);
354
timer_free(s->transfer_timer);
355
356
g_free(s->fifo_buffer);
357
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
358
index XXXXXXX..XXXXXXX 100644
359
--- a/hw/usb/dev-hub.c
360
+++ b/hw/usb/dev-hub.c
361
@@ -XXX,XX +XXX,XX @@ static void usb_hub_unrealize(USBDevice *dev)
362
&s->ports[i].port);
363
}
364
365
- timer_del(s->port_timer);
366
timer_free(s->port_timer);
367
}
368
369
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
370
index XXXXXXX..XXXXXXX 100644
371
--- a/hw/usb/hcd-ehci.c
372
+++ b/hw/usb/hcd-ehci.c
373
@@ -XXX,XX +XXX,XX @@ void usb_ehci_unrealize(EHCIState *s, DeviceState *dev)
374
trace_usb_ehci_unrealize();
375
376
if (s->frame_timer) {
377
- timer_del(s->frame_timer);
378
timer_free(s->frame_timer);
379
s->frame_timer = NULL;
380
}
381
diff --git a/hw/usb/hcd-ohci-pci.c b/hw/usb/hcd-ohci-pci.c
382
index XXXXXXX..XXXXXXX 100644
383
--- a/hw/usb/hcd-ohci-pci.c
384
+++ b/hw/usb/hcd-ohci-pci.c
385
@@ -XXX,XX +XXX,XX @@ static void usb_ohci_exit(PCIDevice *dev)
386
usb_bus_release(&s->bus);
387
}
388
389
- timer_del(s->eof_timer);
390
timer_free(s->eof_timer);
391
}
392
393
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
394
index XXXXXXX..XXXXXXX 100644
395
--- a/hw/usb/hcd-uhci.c
396
+++ b/hw/usb/hcd-uhci.c
397
@@ -XXX,XX +XXX,XX @@ static void usb_uhci_exit(PCIDevice *dev)
398
trace_usb_uhci_exit();
399
400
if (s->frame_timer) {
401
- timer_del(s->frame_timer);
402
timer_free(s->frame_timer);
403
s->frame_timer = NULL;
404
}
405
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
406
index XXXXXXX..XXXXXXX 100644
407
--- a/hw/usb/hcd-xhci.c
408
+++ b/hw/usb/hcd-xhci.c
409
@@ -XXX,XX +XXX,XX @@ static void usb_xhci_unrealize(DeviceState *dev)
410
}
411
412
if (xhci->mfwrap_timer) {
413
- timer_del(xhci->mfwrap_timer);
414
timer_free(xhci->mfwrap_timer);
415
xhci->mfwrap_timer = NULL;
416
}
417
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
418
index XXXXXXX..XXXXXXX 100644
419
--- a/hw/usb/redirect.c
420
+++ b/hw/usb/redirect.c
421
@@ -XXX,XX +XXX,XX @@ static void usbredir_unrealize(USBDevice *udev)
422
qemu_bh_delete(dev->chardev_close_bh);
423
qemu_bh_delete(dev->device_reject_bh);
424
425
- timer_del(dev->attach_timer);
426
timer_free(dev->attach_timer);
427
428
usbredir_cleanup_device_queues(dev);
429
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
430
index XXXXXXX..XXXXXXX 100644
431
--- a/hw/vfio/display.c
432
+++ b/hw/vfio/display.c
433
@@ -XXX,XX +XXX,XX @@ static void vfio_display_edid_exit(VFIODisplay *dpy)
434
435
g_free(dpy->edid_regs);
436
g_free(dpy->edid_blob);
437
- timer_del(dpy->edid_link_timer);
438
timer_free(dpy->edid_link_timer);
439
}
440
441
diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/virtio/vhost-vsock-common.c
444
+++ b/hw/virtio/vhost-vsock-common.c
445
@@ -XXX,XX +XXX,XX @@ static void vhost_vsock_common_post_load_timer_cleanup(VHostVSockCommon *vvc)
89
return;
446
return;
90
}
447
}
91
448
92
src_width = bcm2835_fb_get_pitch(&s->config);
449
- timer_del(vvc->post_load_timer);
93
+ if (fb_use_offsets(&s->config)) {
450
timer_free(vvc->post_load_timer);
94
+ xoff = s->config.xoffset;
451
vvc->post_load_timer = NULL;
95
+ yoff = s->config.yoffset;
452
}
96
+ }
453
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
97
+
454
index XXXXXXX..XXXXXXX 100644
98
dest_width = s->config.xres;
455
--- a/hw/virtio/virtio-balloon.c
99
456
+++ b/hw/virtio/virtio-balloon.c
100
switch (surface_bits_per_pixel(surface)) {
457
@@ -XXX,XX +XXX,XX @@ static bool balloon_stats_enabled(const VirtIOBalloon *s)
101
@@ -XXX,XX +XXX,XX @@ static void fb_update_display(void *opaque)
458
static void balloon_stats_destroy_timer(VirtIOBalloon *s)
102
}
459
{
103
460
if (balloon_stats_enabled(s)) {
104
if (s->invalidate) {
461
- timer_del(s->stats_timer);
105
+ hwaddr base = s->config.base + xoff + yoff * src_width;
462
timer_free(s->stats_timer);
106
framebuffer_update_memory_section(&s->fbsection, s->dma_mr,
463
s->stats_timer = NULL;
107
- s->config.base,
464
s->stats_poll_interval = 0;
108
+ base,
465
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
109
s->config.yres, src_width);
466
index XXXXXXX..XXXXXXX 100644
110
}
467
--- a/hw/virtio/virtio-rng.c
111
468
+++ b/hw/virtio/virtio-rng.c
112
@@ -XXX,XX +XXX,XX @@ static void fb_update_display(void *opaque)
469
@@ -XXX,XX +XXX,XX @@ static void virtio_rng_device_unrealize(DeviceState *dev)
113
draw_line_src16, s, &first, &last);
470
VirtIORNG *vrng = VIRTIO_RNG(dev);
114
471
115
if (first >= 0) {
472
qemu_del_vm_change_state_handler(vrng->vmstate);
116
- dpy_gfx_update(s->con, 0, first, s->config.xres, last - first + 1);
473
- timer_del(vrng->rate_limit_timer);
117
+ dpy_gfx_update(s->con, 0, first, s->config.xres,
474
timer_free(vrng->rate_limit_timer);
118
+ last - first + 1);
475
virtio_del_queue(vdev, 0);
119
}
476
virtio_cleanup(vdev);
120
477
diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c
121
s->invalidate = false;
478
index XXXXXXX..XXXXXXX 100644
122
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
479
--- a/hw/watchdog/wdt_diag288.c
123
s->config.base = s->vcram_base | (value & 0xc0000000);
480
+++ b/hw/watchdog/wdt_diag288.c
124
s->config.base += BCM2835_FB_OFFSET;
481
@@ -XXX,XX +XXX,XX @@ static void wdt_diag288_unrealize(DeviceState *dev)
125
482
{
126
- /* TODO - Manage properly virtual resolution */
483
DIAG288State *diag288 = DIAG288(dev);
127
-
484
128
pitch = bcm2835_fb_get_pitch(&s->config);
485
- timer_del(diag288->timer);
129
size = bcm2835_fb_get_size(&s->config);
486
timer_free(diag288->timer);
130
487
}
131
@@ -XXX,XX +XXX,XX @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig)
488
132
489
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
133
s->config = *newconfig;
490
index XXXXXXX..XXXXXXX 100644
134
491
--- a/hw/watchdog/wdt_i6300esb.c
135
- /* TODO - Manage properly virtual resolution */
492
+++ b/hw/watchdog/wdt_i6300esb.c
136
-
493
@@ -XXX,XX +XXX,XX @@ static void i6300esb_exit(PCIDevice *dev)
137
s->invalidate = true;
494
{
138
qemu_console_resize(s->con, s->config.xres, s->config.yres);
495
I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
139
s->lock = false;
496
140
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
497
- timer_del(d->timer);
141
index XXXXXXX..XXXXXXX 100644
498
timer_free(d->timer);
142
--- a/hw/misc/bcm2835_property.c
499
}
143
+++ b/hw/misc/bcm2835_property.c
500
144
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
501
diff --git a/migration/colo.c b/migration/colo.c
145
case 0x00040002: /* Blank screen */
502
index XXXXXXX..XXXXXXX 100644
146
resplen = 4;
503
--- a/migration/colo.c
147
break;
504
+++ b/migration/colo.c
148
- case 0x00040003: /* Get display width/height */
505
@@ -XXX,XX +XXX,XX @@ out:
149
- case 0x00040004:
506
* error.
150
+ case 0x00040003: /* Get physical display width/height */
507
*/
151
stl_le_phys(&s->dma_as, value + 12, fbconfig.xres);
508
colo_compare_unregister_notifier(&packets_compare_notifier);
152
stl_le_phys(&s->dma_as, value + 16, fbconfig.yres);
509
- timer_del(s->colo_delay_timer);
153
resplen = 8;
510
timer_free(s->colo_delay_timer);
154
break;
511
qemu_event_destroy(&s->colo_checkpoint_event);
155
- case 0x00044003: /* Test display width/height */
512
156
- case 0x00044004:
513
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
157
+ case 0x00040004: /* Get virtual display width/height */
514
index XXXXXXX..XXXXXXX 100644
158
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.xres_virtual);
515
--- a/monitor/hmp-cmds.c
159
+ stl_le_phys(&s->dma_as, value + 16, fbconfig.yres_virtual);
516
+++ b/monitor/hmp-cmds.c
160
resplen = 8;
517
@@ -XXX,XX +XXX,XX @@ static void hmp_migrate_status_cb(void *opaque)
161
break;
518
error_report("%s", info->error_desc);
162
- case 0x00048003: /* Set display width/height */
519
}
163
- case 0x00048004:
520
monitor_resume(status->mon);
164
+ case 0x00044003: /* Test physical display width/height */
521
- timer_del(status->timer);
165
+ case 0x00044004: /* Test virtual display width/height */
522
timer_free(status->timer);
166
+ resplen = 8;
523
g_free(status);
167
+ break;
524
}
168
+ case 0x00048003: /* Set physical display width/height */
525
diff --git a/net/announce.c b/net/announce.c
169
fbconfig.xres = ldl_le_phys(&s->dma_as, value + 12);
526
index XXXXXXX..XXXXXXX 100644
170
fbconfig.yres = ldl_le_phys(&s->dma_as, value + 16);
527
--- a/net/announce.c
171
fbconfig_updated = true;
528
+++ b/net/announce.c
172
resplen = 8;
529
@@ -XXX,XX +XXX,XX @@ void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named)
173
break;
530
{
174
+ case 0x00048004: /* Set virtual display width/height */
531
bool free_timer = false;
175
+ fbconfig.xres_virtual = ldl_le_phys(&s->dma_as, value + 12);
532
if (timer->tm) {
176
+ fbconfig.yres_virtual = ldl_le_phys(&s->dma_as, value + 16);
533
- timer_del(timer->tm);
177
+ fbconfig_updated = true;
534
timer_free(timer->tm);
178
+ resplen = 8;
535
timer->tm = NULL;
179
+ break;
536
}
180
case 0x00040005: /* Get depth */
537
diff --git a/net/colo-compare.c b/net/colo-compare.c
181
stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp);
538
index XXXXXXX..XXXXXXX 100644
182
resplen = 4;
539
--- a/net/colo-compare.c
540
+++ b/net/colo-compare.c
541
@@ -XXX,XX +XXX,XX @@ static void colo_compare_timer_init(CompareState *s)
542
static void colo_compare_timer_del(CompareState *s)
543
{
544
if (s->packet_check_timer) {
545
- timer_del(s->packet_check_timer);
546
timer_free(s->packet_check_timer);
547
s->packet_check_timer = NULL;
548
}
549
diff --git a/net/slirp.c b/net/slirp.c
550
index XXXXXXX..XXXXXXX 100644
551
--- a/net/slirp.c
552
+++ b/net/slirp.c
553
@@ -XXX,XX +XXX,XX @@ static void *net_slirp_timer_new(SlirpTimerCb cb,
554
555
static void net_slirp_timer_free(void *timer, void *opaque)
556
{
557
- timer_del(timer);
558
timer_free(timer);
559
}
560
561
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
562
index XXXXXXX..XXXXXXX 100644
563
--- a/replay/replay-debugging.c
564
+++ b/replay/replay-debugging.c
565
@@ -XXX,XX +XXX,XX @@ static void replay_delete_break(void)
566
assert(replay_mutex_locked());
567
568
if (replay_break_timer) {
569
- timer_del(replay_break_timer);
570
timer_free(replay_break_timer);
571
replay_break_timer = NULL;
572
}
573
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
574
index XXXXXXX..XXXXXXX 100644
575
--- a/target/s390x/cpu.c
576
+++ b/target/s390x/cpu.c
577
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_finalize(Object *obj)
578
#if !defined(CONFIG_USER_ONLY)
579
S390CPU *cpu = S390_CPU(obj);
580
581
- timer_del(cpu->env.tod_timer);
582
timer_free(cpu->env.tod_timer);
583
- timer_del(cpu->env.cpu_timer);
584
timer_free(cpu->env.cpu_timer);
585
586
qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
587
diff --git a/ui/console.c b/ui/console.c
588
index XXXXXXX..XXXXXXX 100644
589
--- a/ui/console.c
590
+++ b/ui/console.c
591
@@ -XXX,XX +XXX,XX @@ static void gui_setup_refresh(DisplayState *ds)
592
timer_mod(ds->gui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
593
}
594
if (!need_timer && ds->gui_timer != NULL) {
595
- timer_del(ds->gui_timer);
596
timer_free(ds->gui_timer);
597
ds->gui_timer = NULL;
598
}
599
diff --git a/ui/spice-core.c b/ui/spice-core.c
600
index XXXXXXX..XXXXXXX 100644
601
--- a/ui/spice-core.c
602
+++ b/ui/spice-core.c
603
@@ -XXX,XX +XXX,XX @@ static void timer_cancel(SpiceTimer *timer)
604
605
static void timer_remove(SpiceTimer *timer)
606
{
607
- timer_del(timer->timer);
608
timer_free(timer->timer);
609
g_free(timer);
610
}
611
diff --git a/util/throttle.c b/util/throttle.c
612
index XXXXXXX..XXXXXXX 100644
613
--- a/util/throttle.c
614
+++ b/util/throttle.c
615
@@ -XXX,XX +XXX,XX @@ static void throttle_timer_destroy(QEMUTimer **timer)
616
{
617
assert(*timer != NULL);
618
619
- timer_del(*timer);
620
timer_free(*timer);
621
*timer = NULL;
622
}
183
--
623
--
184
2.18.0
624
2.20.1
185
625
186
626
diff view generated by jsdifflib
1
The bcm2835_fb's initial resolution and other parameters are set
1
The Arm CPU finalize function uses a sequence of timer_del(), timer_deinit(),
2
via QOM properties. We should reset to those initial values on
2
timer_free() to free the timer. The timer_deinit() step in this was always
3
device reset, which means we need to save the QOM property
3
unnecessary, and now the timer_del() is implied by timer_free(), so we can
4
values somewhere that they are not overwritten by guest
4
collapse this down to simply calling timer_free().
5
changes to the framebuffer configuration.
6
5
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180814144436.679-5-peter.maydell@linaro.org
9
Message-id: 20201215154107.3255-5-peter.maydell@linaro.org
10
---
10
---
11
include/hw/display/bcm2835_fb.h | 1 +
11
target/arm/cpu.c | 2 --
12
hw/display/bcm2835_fb.c | 27 +++++++++++++++------------
12
1 file changed, 2 deletions(-)
13
2 files changed, 16 insertions(+), 12 deletions(-)
14
13
15
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/display/bcm2835_fb.h
16
--- a/target/arm/cpu.c
18
+++ b/include/hw/display/bcm2835_fb.h
17
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_finalizefn(Object *obj)
20
bool lock, invalidate, pending;
21
22
BCM2835FBConfig config;
23
+ BCM2835FBConfig initial_config;
24
} BCM2835FBState;
25
26
void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig);
27
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/display/bcm2835_fb.c
30
+++ b/hw/display/bcm2835_fb.c
31
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_reset(DeviceState *dev)
32
33
s->pending = false;
34
35
- s->config.xres_virtual = s->config.xres;
36
- s->config.yres_virtual = s->config.yres;
37
- s->config.xoffset = 0;
38
- s->config.yoffset = 0;
39
- s->config.base = s->vcram_base + BCM2835_FB_OFFSET;
40
+ s->config = s->initial_config;
41
42
s->invalidate = true;
43
s->lock = false;
44
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_realize(DeviceState *dev, Error **errp)
45
return;
46
}
19
}
47
20
#ifndef CONFIG_USER_ONLY
48
+ /* Fill in the parts of initial_config that are not set by QOM properties */
21
if (cpu->pmu_timer) {
49
+ s->initial_config.xres_virtual = s->initial_config.xres;
22
- timer_del(cpu->pmu_timer);
50
+ s->initial_config.yres_virtual = s->initial_config.yres;
23
- timer_deinit(cpu->pmu_timer);
51
+ s->initial_config.xoffset = 0;
24
timer_free(cpu->pmu_timer);
52
+ s->initial_config.yoffset = 0;
25
}
53
+ s->initial_config.base = s->vcram_base + BCM2835_FB_OFFSET;
26
#endif
54
+
55
s->dma_mr = MEMORY_REGION(obj);
56
address_space_init(&s->dma_as, s->dma_mr, NULL);
57
58
@@ -XXX,XX +XXX,XX @@ static Property bcm2835_fb_props[] = {
59
DEFINE_PROP_UINT32("vcram-base", BCM2835FBState, vcram_base, 0),/*required*/
60
DEFINE_PROP_UINT32("vcram-size", BCM2835FBState, vcram_size,
61
DEFAULT_VCRAM_SIZE),
62
- DEFINE_PROP_UINT32("xres", BCM2835FBState, config.xres, 640),
63
- DEFINE_PROP_UINT32("yres", BCM2835FBState, config.yres, 480),
64
- DEFINE_PROP_UINT32("bpp", BCM2835FBState, config.bpp, 16),
65
- DEFINE_PROP_UINT32("pixo",
66
- BCM2835FBState, config.pixo, 1), /* 1=RGB, 0=BGR */
67
- DEFINE_PROP_UINT32("alpha",
68
- BCM2835FBState, config.alpha, 2), /* alpha ignored */
69
+ DEFINE_PROP_UINT32("xres", BCM2835FBState, initial_config.xres, 640),
70
+ DEFINE_PROP_UINT32("yres", BCM2835FBState, initial_config.yres, 480),
71
+ DEFINE_PROP_UINT32("bpp", BCM2835FBState, initial_config.bpp, 16),
72
+ DEFINE_PROP_UINT32("pixo", BCM2835FBState,
73
+ initial_config.pixo, 1), /* 1=RGB, 0=BGR */
74
+ DEFINE_PROP_UINT32("alpha", BCM2835FBState,
75
+ initial_config.alpha, 2), /* alpha ignored */
76
DEFINE_PROP_END_OF_LIST()
77
};
78
79
--
27
--
80
2.18.0
28
2.20.1
81
29
82
30
diff view generated by jsdifflib
1
The AN505 FPGA image includes four PL081 DMA controllers, each
1
From: Gan Qixin <ganqixin@huawei.com>
2
of which is gated by a Master Security Controller that allows
3
the guest to prevent a non-secure DMA controller from accessing
4
memory that is used by secure guest code. Create and wire
5
up these devices.
6
2
3
When running device-introspect-test, a memory leak occurred in the
4
digic_timer_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 288 byte(s) in 3 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf5b04084 in digic_timer_init /qemu/hw/timer/digic-timer.c:142
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
16
#6 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
17
#7 0xaaabf5b40e84 in digic_init /qemu/hw/arm/digic.c:46
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
22
#12 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20180820141116.9118-15-peter.maydell@linaro.org
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
---
28
---
12
hw/arm/mps2-tz.c | 100 +++++++++++++++++++++++++++++++++++++++++++----
29
hw/timer/digic-timer.c | 8 ++++++++
13
1 file changed, 93 insertions(+), 7 deletions(-)
30
1 file changed, 8 insertions(+)
14
31
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
32
diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c
16
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
34
--- a/hw/timer/digic-timer.c
18
+++ b/hw/arm/mps2-tz.c
35
+++ b/hw/timer/digic-timer.c
19
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@ static void digic_timer_init(Object *obj)
20
#include "hw/misc/mps2-scc.h"
37
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
21
#include "hw/misc/mps2-fpgaio.h"
22
#include "hw/misc/tz-mpc.h"
23
+#include "hw/misc/tz-msc.h"
24
#include "hw/arm/iotkit.h"
25
+#include "hw/dma/pl080.h"
26
#include "hw/devices.h"
27
#include "net/net.h"
28
#include "hw/core/split-irq.h"
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
30
UnimplementedDeviceState i2c[4];
31
UnimplementedDeviceState i2s_audio;
32
UnimplementedDeviceState gpio[4];
33
- UnimplementedDeviceState dma[4];
34
UnimplementedDeviceState gfx;
35
+ PL080State dma[4];
36
+ TZMSC msc[4];
37
CMSDKAPBUART uart[5];
38
SplitIRQ sec_resp_splitter;
39
qemu_or_irq uart_irq_orgate;
40
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
41
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
42
}
38
}
43
39
44
+static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
40
+static void digic_timer_finalize(Object *obj)
45
+ const char *name, hwaddr size)
46
+{
41
+{
47
+ PL080State *dma = opaque;
42
+ DigicTimerState *s = DIGIC_TIMER(obj);
48
+ int i = dma - &mms->dma[0];
49
+ SysBusDevice *s;
50
+ char *mscname = g_strdup_printf("%s-msc", name);
51
+ TZMSC *msc = &mms->msc[i];
52
+ DeviceState *iotkitdev = DEVICE(&mms->iotkit);
53
+ MemoryRegion *msc_upstream;
54
+ MemoryRegion *msc_downstream;
55
+
43
+
56
+ /*
44
+ ptimer_free(s->ptimer);
57
+ * Each DMA device is a PL081 whose transaction master interface
58
+ * is guarded by a Master Security Controller. The downstream end of
59
+ * the MSC connects to the IoTKit AHB Slave Expansion port, so the
60
+ * DMA devices can see all devices and memory that the CPU does.
61
+ */
62
+ sysbus_init_child_obj(OBJECT(mms), mscname, msc, sizeof(*msc), TYPE_TZ_MSC);
63
+ msc_downstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(&mms->iotkit), 0);
64
+ object_property_set_link(OBJECT(msc), OBJECT(msc_downstream),
65
+ "downstream", &error_fatal);
66
+ object_property_set_link(OBJECT(msc), OBJECT(mms),
67
+ "idau", &error_fatal);
68
+ object_property_set_bool(OBJECT(msc), true, "realized", &error_fatal);
69
+
70
+ qdev_connect_gpio_out_named(DEVICE(msc), "irq", 0,
71
+ qdev_get_gpio_in_named(iotkitdev,
72
+ "mscexp_status", i));
73
+ qdev_connect_gpio_out_named(iotkitdev, "mscexp_clear", i,
74
+ qdev_get_gpio_in_named(DEVICE(msc),
75
+ "irq_clear", 0));
76
+ qdev_connect_gpio_out_named(iotkitdev, "mscexp_ns", i,
77
+ qdev_get_gpio_in_named(DEVICE(msc),
78
+ "cfg_nonsec", 0));
79
+ qdev_connect_gpio_out(DEVICE(&mms->sec_resp_splitter),
80
+ ARRAY_SIZE(mms->ppc) + i,
81
+ qdev_get_gpio_in_named(DEVICE(msc),
82
+ "cfg_sec_resp", 0));
83
+ msc_upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(msc), 0);
84
+
85
+ sysbus_init_child_obj(OBJECT(mms), name, dma, sizeof(*dma), TYPE_PL081);
86
+ object_property_set_link(OBJECT(dma), OBJECT(msc_upstream),
87
+ "downstream", &error_fatal);
88
+ object_property_set_bool(OBJECT(dma), true, "realized", &error_fatal);
89
+
90
+ s = SYS_BUS_DEVICE(dma);
91
+ /* Wire up DMACINTR, DMACINTERR, DMACINTTC */
92
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
93
+ "EXP_IRQ", 58 + i * 3));
94
+ sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
95
+ "EXP_IRQ", 56 + i * 3));
96
+ sysbus_connect_irq(s, 2, qdev_get_gpio_in_named(iotkitdev,
97
+ "EXP_IRQ", 57 + i * 3));
98
+
99
+ return sysbus_mmio_get_region(s, 0);
100
+}
45
+}
101
+
46
+
102
static void mps2tz_common_init(MachineState *machine)
47
static void digic_timer_class_init(ObjectClass *klass, void *class_data)
103
{
48
{
104
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
49
DeviceClass *dc = DEVICE_CLASS(klass);
105
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
50
@@ -XXX,XX +XXX,XX @@ static const TypeInfo digic_timer_info = {
106
&error_fatal);
51
.parent = TYPE_SYS_BUS_DEVICE,
107
52
.instance_size = sizeof(DigicTimerState),
108
/* The sec_resp_cfg output from the IoTKit must be split into multiple
53
.instance_init = digic_timer_init,
109
- * lines, one for each of the PPCs we create here.
54
+ .instance_finalize = digic_timer_finalize,
110
+ * lines, one for each of the PPCs we create here, plus one per MSC.
55
.class_init = digic_timer_class_init,
111
*/
112
object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitter),
113
TYPE_SPLIT_IRQ);
114
object_property_add_child(OBJECT(machine), "sec-resp-splitter",
115
OBJECT(&mms->sec_resp_splitter), &error_abort);
116
- object_property_set_int(OBJECT(&mms->sec_resp_splitter), 5,
117
+ object_property_set_int(OBJECT(&mms->sec_resp_splitter),
118
+ ARRAY_SIZE(mms->ppc) + ARRAY_SIZE(mms->msc),
119
"num-lines", &error_fatal);
120
object_property_set_bool(OBJECT(&mms->sec_resp_splitter), true,
121
"realized", &error_fatal);
122
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
123
}, {
124
.name = "ahb_ppcexp1",
125
.ports = {
126
- { "dma0", make_unimp_dev, &mms->dma[0], 0x40110000, 0x1000 },
127
- { "dma1", make_unimp_dev, &mms->dma[1], 0x40111000, 0x1000 },
128
- { "dma2", make_unimp_dev, &mms->dma[2], 0x40112000, 0x1000 },
129
- { "dma3", make_unimp_dev, &mms->dma[3], 0x40113000, 0x1000 },
130
+ { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
131
+ { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
132
+ { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
133
+ { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
134
},
135
},
136
};
137
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
138
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
139
}
140
141
+static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
142
+ int *iregion, bool *exempt, bool *ns, bool *nsc)
143
+{
144
+ /*
145
+ * The MPS2 TZ FPGA images have IDAUs in them which are connected to
146
+ * the Master Security Controllers. Thes have the same logic as
147
+ * is used by the IoTKit for the IDAU connected to the CPU, except
148
+ * that MSCs don't care about the NSC attribute.
149
+ */
150
+ int region = extract32(address, 28, 4);
151
+
152
+ *ns = !(region & 1);
153
+ *nsc = false;
154
+ /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
155
+ *exempt = (address & 0xeff00000) == 0xe0000000;
156
+ *iregion = region;
157
+}
158
+
159
static void mps2tz_class_init(ObjectClass *oc, void *data)
160
{
161
MachineClass *mc = MACHINE_CLASS(oc);
162
+ IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
163
164
mc->init = mps2tz_common_init;
165
mc->max_cpus = 1;
166
+ iic->check = mps2_tz_idau_check;
167
}
168
169
static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
170
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_info = {
171
.instance_size = sizeof(MPS2TZMachineState),
172
.class_size = sizeof(MPS2TZMachineClass),
173
.class_init = mps2tz_class_init,
174
+ .interfaces = (InterfaceInfo[]) {
175
+ { TYPE_IDAU_INTERFACE },
176
+ { }
177
+ },
178
};
56
};
179
57
180
static const TypeInfo mps2tz_an505_info = {
181
--
58
--
182
2.18.0
59
2.20.1
183
60
184
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
When running device-introspect-test, a memory leak occurred in the a10_pit_init
4
Message-id: 20180814002653.12828-3-richard.henderson@linaro.org
4
function, so use ptimer_free() in the finalize function to avoid it.
5
6
ASAN shows memory leak stack:
7
8
Indirect leak of 288 byte(s) in 6 object(s) allocated from:
9
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
10
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
11
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
12
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
13
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
14
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
15
#6 0xaaabf57415e8 in a10_pit_init /qemu/hw/timer/allwinner-a10-pit.c:278
16
#7 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
17
#8 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
18
#9 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
19
#10 0xaaabf5b94680 in aw_a10_init /qemu/hw/arm/allwinner-a10.c:49
20
#11 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
21
#12 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
22
23
Reported-by: Euler Robot <euler.robot@huawei.com>
24
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
27
---
8
include/fpu/softfloat.h | 85 ++++++---
28
hw/timer/allwinner-a10-pit.c | 11 +++++++++++
9
fpu/softfloat.c | 391 ++++++++++++++++++++++++++++++++--------
29
1 file changed, 11 insertions(+)
10
2 files changed, 379 insertions(+), 97 deletions(-)
11
30
12
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
31
diff --git a/hw/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c
13
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
14
--- a/include/fpu/softfloat.h
33
--- a/hw/timer/allwinner-a10-pit.c
15
+++ b/include/fpu/softfloat.h
34
+++ b/hw/timer/allwinner-a10-pit.c
16
@@ -XXX,XX +XXX,XX @@ float128 uint64_to_float128(uint64_t, float_status *status);
35
@@ -XXX,XX +XXX,XX @@ static void a10_pit_init(Object *obj)
17
/*----------------------------------------------------------------------------
18
| Software half-precision conversion routines.
19
*----------------------------------------------------------------------------*/
20
+
21
float16 float32_to_float16(float32, bool ieee, float_status *status);
22
float32 float16_to_float32(float16, bool ieee, float_status *status);
23
float16 float64_to_float16(float64 a, bool ieee, float_status *status);
24
float64 float16_to_float64(float16 a, bool ieee, float_status *status);
25
+
26
+int16_t float16_to_int16_scalbn(float16, int, int, float_status *status);
27
+int32_t float16_to_int32_scalbn(float16, int, int, float_status *status);
28
+int64_t float16_to_int64_scalbn(float16, int, int, float_status *status);
29
+
30
int16_t float16_to_int16(float16, float_status *status);
31
-uint16_t float16_to_uint16(float16 a, float_status *status);
32
-int16_t float16_to_int16_round_to_zero(float16, float_status *status);
33
-uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status);
34
int32_t float16_to_int32(float16, float_status *status);
35
-uint32_t float16_to_uint32(float16 a, float_status *status);
36
-int32_t float16_to_int32_round_to_zero(float16, float_status *status);
37
-uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status);
38
int64_t float16_to_int64(float16, float_status *status);
39
-uint64_t float16_to_uint64(float16 a, float_status *status);
40
+
41
+int16_t float16_to_int16_round_to_zero(float16, float_status *status);
42
+int32_t float16_to_int32_round_to_zero(float16, float_status *status);
43
int64_t float16_to_int64_round_to_zero(float16, float_status *status);
44
+
45
+uint16_t float16_to_uint16_scalbn(float16 a, int, int, float_status *status);
46
+uint32_t float16_to_uint32_scalbn(float16 a, int, int, float_status *status);
47
+uint64_t float16_to_uint64_scalbn(float16 a, int, int, float_status *status);
48
+
49
+uint16_t float16_to_uint16(float16 a, float_status *status);
50
+uint32_t float16_to_uint32(float16 a, float_status *status);
51
+uint64_t float16_to_uint64(float16 a, float_status *status);
52
+
53
+uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status);
54
+uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status);
55
uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status);
56
57
/*----------------------------------------------------------------------------
58
@@ -XXX,XX +XXX,XX @@ float16 float16_default_nan(float_status *status);
59
/*----------------------------------------------------------------------------
60
| Software IEC/IEEE single-precision conversion routines.
61
*----------------------------------------------------------------------------*/
62
+
63
+int16_t float32_to_int16_scalbn(float32, int, int, float_status *status);
64
+int32_t float32_to_int32_scalbn(float32, int, int, float_status *status);
65
+int64_t float32_to_int64_scalbn(float32, int, int, float_status *status);
66
+
67
int16_t float32_to_int16(float32, float_status *status);
68
-uint16_t float32_to_uint16(float32, float_status *status);
69
-int16_t float32_to_int16_round_to_zero(float32, float_status *status);
70
-uint16_t float32_to_uint16_round_to_zero(float32, float_status *status);
71
int32_t float32_to_int32(float32, float_status *status);
72
-int32_t float32_to_int32_round_to_zero(float32, float_status *status);
73
-uint32_t float32_to_uint32(float32, float_status *status);
74
-uint32_t float32_to_uint32_round_to_zero(float32, float_status *status);
75
int64_t float32_to_int64(float32, float_status *status);
76
-uint64_t float32_to_uint64(float32, float_status *status);
77
-uint64_t float32_to_uint64_round_to_zero(float32, float_status *status);
78
+
79
+int16_t float32_to_int16_round_to_zero(float32, float_status *status);
80
+int32_t float32_to_int32_round_to_zero(float32, float_status *status);
81
int64_t float32_to_int64_round_to_zero(float32, float_status *status);
82
+
83
+uint16_t float32_to_uint16_scalbn(float32, int, int, float_status *status);
84
+uint32_t float32_to_uint32_scalbn(float32, int, int, float_status *status);
85
+uint64_t float32_to_uint64_scalbn(float32, int, int, float_status *status);
86
+
87
+uint16_t float32_to_uint16(float32, float_status *status);
88
+uint32_t float32_to_uint32(float32, float_status *status);
89
+uint64_t float32_to_uint64(float32, float_status *status);
90
+
91
+uint16_t float32_to_uint16_round_to_zero(float32, float_status *status);
92
+uint32_t float32_to_uint32_round_to_zero(float32, float_status *status);
93
+uint64_t float32_to_uint64_round_to_zero(float32, float_status *status);
94
+
95
float64 float32_to_float64(float32, float_status *status);
96
floatx80 float32_to_floatx80(float32, float_status *status);
97
float128 float32_to_float128(float32, float_status *status);
98
@@ -XXX,XX +XXX,XX @@ float32 float32_default_nan(float_status *status);
99
/*----------------------------------------------------------------------------
100
| Software IEC/IEEE double-precision conversion routines.
101
*----------------------------------------------------------------------------*/
102
+
103
+int16_t float64_to_int16_scalbn(float64, int, int, float_status *status);
104
+int32_t float64_to_int32_scalbn(float64, int, int, float_status *status);
105
+int64_t float64_to_int64_scalbn(float64, int, int, float_status *status);
106
+
107
int16_t float64_to_int16(float64, float_status *status);
108
-uint16_t float64_to_uint16(float64, float_status *status);
109
-int16_t float64_to_int16_round_to_zero(float64, float_status *status);
110
-uint16_t float64_to_uint16_round_to_zero(float64, float_status *status);
111
int32_t float64_to_int32(float64, float_status *status);
112
-int32_t float64_to_int32_round_to_zero(float64, float_status *status);
113
-uint32_t float64_to_uint32(float64, float_status *status);
114
-uint32_t float64_to_uint32_round_to_zero(float64, float_status *status);
115
int64_t float64_to_int64(float64, float_status *status);
116
+
117
+int16_t float64_to_int16_round_to_zero(float64, float_status *status);
118
+int32_t float64_to_int32_round_to_zero(float64, float_status *status);
119
int64_t float64_to_int64_round_to_zero(float64, float_status *status);
120
-uint64_t float64_to_uint64(float64 a, float_status *status);
121
-uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status);
122
+
123
+uint16_t float64_to_uint16_scalbn(float64, int, int, float_status *status);
124
+uint32_t float64_to_uint32_scalbn(float64, int, int, float_status *status);
125
+uint64_t float64_to_uint64_scalbn(float64, int, int, float_status *status);
126
+
127
+uint16_t float64_to_uint16(float64, float_status *status);
128
+uint32_t float64_to_uint32(float64, float_status *status);
129
+uint64_t float64_to_uint64(float64, float_status *status);
130
+
131
+uint16_t float64_to_uint16_round_to_zero(float64, float_status *status);
132
+uint32_t float64_to_uint32_round_to_zero(float64, float_status *status);
133
+uint64_t float64_to_uint64_round_to_zero(float64, float_status *status);
134
+
135
float32 float64_to_float32(float64, float_status *status);
136
floatx80 float64_to_floatx80(float64, float_status *status);
137
float128 float64_to_float128(float64, float_status *status);
138
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/fpu/softfloat.c
141
+++ b/fpu/softfloat.c
142
@@ -XXX,XX +XXX,XX @@ float32 float64_to_float32(float64 a, float_status *s)
143
* Arithmetic.
144
*/
145
146
-static FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *s)
147
+static FloatParts round_to_int(FloatParts a, int rmode,
148
+ int scale, float_status *s)
149
{
150
- if (is_nan(a.cls)) {
151
- return return_nan(a, s);
152
- }
153
-
154
switch (a.cls) {
155
+ case float_class_qnan:
156
+ case float_class_snan:
157
+ return return_nan(a, s);
158
+
159
case float_class_zero:
160
case float_class_inf:
161
- case float_class_qnan:
162
/* already "integral" */
163
break;
164
+
165
case float_class_normal:
166
+ scale = MIN(MAX(scale, -0x10000), 0x10000);
167
+ a.exp += scale;
168
+
169
if (a.exp >= DECOMPOSED_BINARY_POINT) {
170
/* already integral */
171
break;
172
@@ -XXX,XX +XXX,XX @@ static FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *s)
173
bool one;
174
/* all fractional */
175
s->float_exception_flags |= float_flag_inexact;
176
- switch (rounding_mode) {
177
+ switch (rmode) {
178
case float_round_nearest_even:
179
one = a.exp == -1 && a.frac > DECOMPOSED_IMPLICIT_BIT;
180
break;
181
@@ -XXX,XX +XXX,XX @@ static FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *s)
182
uint64_t rnd_mask = rnd_even_mask >> 1;
183
uint64_t inc;
184
185
- switch (rounding_mode) {
186
+ switch (rmode) {
187
case float_round_nearest_even:
188
inc = ((a.frac & rnd_even_mask) != frac_lsbm1 ? frac_lsbm1 : 0);
189
break;
190
@@ -XXX,XX +XXX,XX @@ static FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *s)
191
float16 float16_round_to_int(float16 a, float_status *s)
192
{
193
FloatParts pa = float16_unpack_canonical(a, s);
194
- FloatParts pr = round_to_int(pa, s->float_rounding_mode, s);
195
+ FloatParts pr = round_to_int(pa, s->float_rounding_mode, 0, s);
196
return float16_round_pack_canonical(pr, s);
197
}
198
199
float32 float32_round_to_int(float32 a, float_status *s)
200
{
201
FloatParts pa = float32_unpack_canonical(a, s);
202
- FloatParts pr = round_to_int(pa, s->float_rounding_mode, s);
203
+ FloatParts pr = round_to_int(pa, s->float_rounding_mode, 0, s);
204
return float32_round_pack_canonical(pr, s);
205
}
206
207
float64 float64_round_to_int(float64 a, float_status *s)
208
{
209
FloatParts pa = float64_unpack_canonical(a, s);
210
- FloatParts pr = round_to_int(pa, s->float_rounding_mode, s);
211
+ FloatParts pr = round_to_int(pa, s->float_rounding_mode, 0, s);
212
return float64_round_pack_canonical(pr, s);
213
}
214
215
float64 float64_trunc_to_int(float64 a, float_status *s)
216
{
217
FloatParts pa = float64_unpack_canonical(a, s);
218
- FloatParts pr = round_to_int(pa, float_round_to_zero, s);
219
+ FloatParts pr = round_to_int(pa, float_round_to_zero, 0, s);
220
return float64_round_pack_canonical(pr, s);
221
}
222
223
@@ -XXX,XX +XXX,XX @@ float64 float64_trunc_to_int(float64 a, float_status *s)
224
* is returned.
225
*/
226
227
-static int64_t round_to_int_and_pack(FloatParts in, int rmode,
228
+static int64_t round_to_int_and_pack(FloatParts in, int rmode, int scale,
229
int64_t min, int64_t max,
230
float_status *s)
231
{
232
uint64_t r;
233
int orig_flags = get_float_exception_flags(s);
234
- FloatParts p = round_to_int(in, rmode, s);
235
+ FloatParts p = round_to_int(in, rmode, scale, s);
236
237
switch (p.cls) {
238
case float_class_snan:
239
@@ -XXX,XX +XXX,XX @@ static int64_t round_to_int_and_pack(FloatParts in, int rmode,
240
}
36
}
241
}
37
}
242
38
243
-#define FLOAT_TO_INT(fsz, isz) \
39
+static void a10_pit_finalize(Object *obj)
244
-int ## isz ## _t float ## fsz ## _to_int ## isz(float ## fsz a, \
245
- float_status *s) \
246
-{ \
247
- FloatParts p = float ## fsz ## _unpack_canonical(a, s); \
248
- return round_to_int_and_pack(p, s->float_rounding_mode, \
249
- INT ## isz ## _MIN, INT ## isz ## _MAX,\
250
- s); \
251
-} \
252
- \
253
-int ## isz ## _t float ## fsz ## _to_int ## isz ## _round_to_zero \
254
- (float ## fsz a, float_status *s) \
255
-{ \
256
- FloatParts p = float ## fsz ## _unpack_canonical(a, s); \
257
- return round_to_int_and_pack(p, float_round_to_zero, \
258
- INT ## isz ## _MIN, INT ## isz ## _MAX,\
259
- s); \
260
+int16_t float16_to_int16_scalbn(float16 a, int rmode, int scale,
261
+ float_status *s)
262
+{
40
+{
263
+ return round_to_int_and_pack(float16_unpack_canonical(a, s),
41
+ AwA10PITState *s = AW_A10_PIT(obj);
264
+ rmode, scale, INT16_MIN, INT16_MAX, s);
42
+ int i;
265
}
43
+
266
44
+ for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
267
-FLOAT_TO_INT(16, 16)
45
+ ptimer_free(s->timer[i]);
268
-FLOAT_TO_INT(16, 32)
46
+ }
269
-FLOAT_TO_INT(16, 64)
270
+int32_t float16_to_int32_scalbn(float16 a, int rmode, int scale,
271
+ float_status *s)
272
+{
273
+ return round_to_int_and_pack(float16_unpack_canonical(a, s),
274
+ rmode, scale, INT32_MIN, INT32_MAX, s);
275
+}
276
277
-FLOAT_TO_INT(32, 16)
278
-FLOAT_TO_INT(32, 32)
279
-FLOAT_TO_INT(32, 64)
280
+int64_t float16_to_int64_scalbn(float16 a, int rmode, int scale,
281
+ float_status *s)
282
+{
283
+ return round_to_int_and_pack(float16_unpack_canonical(a, s),
284
+ rmode, scale, INT64_MIN, INT64_MAX, s);
285
+}
286
287
-FLOAT_TO_INT(64, 16)
288
-FLOAT_TO_INT(64, 32)
289
-FLOAT_TO_INT(64, 64)
290
+int16_t float32_to_int16_scalbn(float32 a, int rmode, int scale,
291
+ float_status *s)
292
+{
293
+ return round_to_int_and_pack(float32_unpack_canonical(a, s),
294
+ rmode, scale, INT16_MIN, INT16_MAX, s);
295
+}
296
297
-#undef FLOAT_TO_INT
298
+int32_t float32_to_int32_scalbn(float32 a, int rmode, int scale,
299
+ float_status *s)
300
+{
301
+ return round_to_int_and_pack(float32_unpack_canonical(a, s),
302
+ rmode, scale, INT32_MIN, INT32_MAX, s);
303
+}
47
+}
304
+
48
+
305
+int64_t float32_to_int64_scalbn(float32 a, int rmode, int scale,
49
static void a10_pit_class_init(ObjectClass *klass, void *data)
306
+ float_status *s)
307
+{
308
+ return round_to_int_and_pack(float32_unpack_canonical(a, s),
309
+ rmode, scale, INT64_MIN, INT64_MAX, s);
310
+}
311
+
312
+int16_t float64_to_int16_scalbn(float64 a, int rmode, int scale,
313
+ float_status *s)
314
+{
315
+ return round_to_int_and_pack(float64_unpack_canonical(a, s),
316
+ rmode, scale, INT16_MIN, INT16_MAX, s);
317
+}
318
+
319
+int32_t float64_to_int32_scalbn(float64 a, int rmode, int scale,
320
+ float_status *s)
321
+{
322
+ return round_to_int_and_pack(float64_unpack_canonical(a, s),
323
+ rmode, scale, INT32_MIN, INT32_MAX, s);
324
+}
325
+
326
+int64_t float64_to_int64_scalbn(float64 a, int rmode, int scale,
327
+ float_status *s)
328
+{
329
+ return round_to_int_and_pack(float64_unpack_canonical(a, s),
330
+ rmode, scale, INT64_MIN, INT64_MAX, s);
331
+}
332
+
333
+int16_t float16_to_int16(float16 a, float_status *s)
334
+{
335
+ return float16_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
336
+}
337
+
338
+int32_t float16_to_int32(float16 a, float_status *s)
339
+{
340
+ return float16_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
341
+}
342
+
343
+int64_t float16_to_int64(float16 a, float_status *s)
344
+{
345
+ return float16_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
346
+}
347
+
348
+int16_t float32_to_int16(float32 a, float_status *s)
349
+{
350
+ return float32_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
351
+}
352
+
353
+int32_t float32_to_int32(float32 a, float_status *s)
354
+{
355
+ return float32_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
356
+}
357
+
358
+int64_t float32_to_int64(float32 a, float_status *s)
359
+{
360
+ return float32_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
361
+}
362
+
363
+int16_t float64_to_int16(float64 a, float_status *s)
364
+{
365
+ return float64_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
366
+}
367
+
368
+int32_t float64_to_int32(float64 a, float_status *s)
369
+{
370
+ return float64_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
371
+}
372
+
373
+int64_t float64_to_int64(float64 a, float_status *s)
374
+{
375
+ return float64_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
376
+}
377
+
378
+int16_t float16_to_int16_round_to_zero(float16 a, float_status *s)
379
+{
380
+ return float16_to_int16_scalbn(a, float_round_to_zero, 0, s);
381
+}
382
+
383
+int32_t float16_to_int32_round_to_zero(float16 a, float_status *s)
384
+{
385
+ return float16_to_int32_scalbn(a, float_round_to_zero, 0, s);
386
+}
387
+
388
+int64_t float16_to_int64_round_to_zero(float16 a, float_status *s)
389
+{
390
+ return float16_to_int64_scalbn(a, float_round_to_zero, 0, s);
391
+}
392
+
393
+int16_t float32_to_int16_round_to_zero(float32 a, float_status *s)
394
+{
395
+ return float32_to_int16_scalbn(a, float_round_to_zero, 0, s);
396
+}
397
+
398
+int32_t float32_to_int32_round_to_zero(float32 a, float_status *s)
399
+{
400
+ return float32_to_int32_scalbn(a, float_round_to_zero, 0, s);
401
+}
402
+
403
+int64_t float32_to_int64_round_to_zero(float32 a, float_status *s)
404
+{
405
+ return float32_to_int64_scalbn(a, float_round_to_zero, 0, s);
406
+}
407
+
408
+int16_t float64_to_int16_round_to_zero(float64 a, float_status *s)
409
+{
410
+ return float64_to_int16_scalbn(a, float_round_to_zero, 0, s);
411
+}
412
+
413
+int32_t float64_to_int32_round_to_zero(float64 a, float_status *s)
414
+{
415
+ return float64_to_int32_scalbn(a, float_round_to_zero, 0, s);
416
+}
417
+
418
+int64_t float64_to_int64_round_to_zero(float64 a, float_status *s)
419
+{
420
+ return float64_to_int64_scalbn(a, float_round_to_zero, 0, s);
421
+}
422
423
/*
424
* Returns the result of converting the floating-point value `a' to
425
@@ -XXX,XX +XXX,XX @@ FLOAT_TO_INT(64, 64)
426
* flag.
427
*/
428
429
-static uint64_t round_to_uint_and_pack(FloatParts in, int rmode, uint64_t max,
430
- float_status *s)
431
+static uint64_t round_to_uint_and_pack(FloatParts in, int rmode, int scale,
432
+ uint64_t max, float_status *s)
433
{
50
{
434
int orig_flags = get_float_exception_flags(s);
51
DeviceClass *dc = DEVICE_CLASS(klass);
435
- FloatParts p = round_to_int(in, rmode, s);
52
@@ -XXX,XX +XXX,XX @@ static const TypeInfo a10_pit_info = {
436
+ FloatParts p = round_to_int(in, rmode, scale, s);
53
.parent = TYPE_SYS_BUS_DEVICE,
437
+ uint64_t r;
54
.instance_size = sizeof(AwA10PITState),
438
55
.instance_init = a10_pit_init,
439
switch (p.cls) {
56
+ .instance_finalize = a10_pit_finalize,
440
case float_class_snan:
57
.class_init = a10_pit_class_init,
441
@@ -XXX,XX +XXX,XX @@ static uint64_t round_to_uint_and_pack(FloatParts in, int rmode, uint64_t max,
58
};
442
case float_class_zero:
59
443
return 0;
444
case float_class_normal:
445
- {
446
- uint64_t r;
447
if (p.sign) {
448
s->float_exception_flags = orig_flags | float_flag_invalid;
449
return 0;
450
@@ -XXX,XX +XXX,XX @@ static uint64_t round_to_uint_and_pack(FloatParts in, int rmode, uint64_t max,
451
if (r > max) {
452
s->float_exception_flags = orig_flags | float_flag_invalid;
453
return max;
454
- } else {
455
- return r;
456
}
457
- }
458
+ return r;
459
default:
460
g_assert_not_reached();
461
}
462
}
463
464
-#define FLOAT_TO_UINT(fsz, isz) \
465
-uint ## isz ## _t float ## fsz ## _to_uint ## isz(float ## fsz a, \
466
- float_status *s) \
467
-{ \
468
- FloatParts p = float ## fsz ## _unpack_canonical(a, s); \
469
- return round_to_uint_and_pack(p, s->float_rounding_mode, \
470
- UINT ## isz ## _MAX, s); \
471
-} \
472
- \
473
-uint ## isz ## _t float ## fsz ## _to_uint ## isz ## _round_to_zero \
474
- (float ## fsz a, float_status *s) \
475
-{ \
476
- FloatParts p = float ## fsz ## _unpack_canonical(a, s); \
477
- return round_to_uint_and_pack(p, float_round_to_zero, \
478
- UINT ## isz ## _MAX, s); \
479
+uint16_t float16_to_uint16_scalbn(float16 a, int rmode, int scale,
480
+ float_status *s)
481
+{
482
+ return round_to_uint_and_pack(float16_unpack_canonical(a, s),
483
+ rmode, scale, UINT16_MAX, s);
484
}
485
486
-FLOAT_TO_UINT(16, 16)
487
-FLOAT_TO_UINT(16, 32)
488
-FLOAT_TO_UINT(16, 64)
489
+uint32_t float16_to_uint32_scalbn(float16 a, int rmode, int scale,
490
+ float_status *s)
491
+{
492
+ return round_to_uint_and_pack(float16_unpack_canonical(a, s),
493
+ rmode, scale, UINT32_MAX, s);
494
+}
495
496
-FLOAT_TO_UINT(32, 16)
497
-FLOAT_TO_UINT(32, 32)
498
-FLOAT_TO_UINT(32, 64)
499
+uint64_t float16_to_uint64_scalbn(float16 a, int rmode, int scale,
500
+ float_status *s)
501
+{
502
+ return round_to_uint_and_pack(float16_unpack_canonical(a, s),
503
+ rmode, scale, UINT64_MAX, s);
504
+}
505
506
-FLOAT_TO_UINT(64, 16)
507
-FLOAT_TO_UINT(64, 32)
508
-FLOAT_TO_UINT(64, 64)
509
+uint16_t float32_to_uint16_scalbn(float32 a, int rmode, int scale,
510
+ float_status *s)
511
+{
512
+ return round_to_uint_and_pack(float32_unpack_canonical(a, s),
513
+ rmode, scale, UINT16_MAX, s);
514
+}
515
516
-#undef FLOAT_TO_UINT
517
+uint32_t float32_to_uint32_scalbn(float32 a, int rmode, int scale,
518
+ float_status *s)
519
+{
520
+ return round_to_uint_and_pack(float32_unpack_canonical(a, s),
521
+ rmode, scale, UINT32_MAX, s);
522
+}
523
+
524
+uint64_t float32_to_uint64_scalbn(float32 a, int rmode, int scale,
525
+ float_status *s)
526
+{
527
+ return round_to_uint_and_pack(float32_unpack_canonical(a, s),
528
+ rmode, scale, UINT64_MAX, s);
529
+}
530
+
531
+uint16_t float64_to_uint16_scalbn(float64 a, int rmode, int scale,
532
+ float_status *s)
533
+{
534
+ return round_to_uint_and_pack(float64_unpack_canonical(a, s),
535
+ rmode, scale, UINT16_MAX, s);
536
+}
537
+
538
+uint32_t float64_to_uint32_scalbn(float64 a, int rmode, int scale,
539
+ float_status *s)
540
+{
541
+ return round_to_uint_and_pack(float64_unpack_canonical(a, s),
542
+ rmode, scale, UINT32_MAX, s);
543
+}
544
+
545
+uint64_t float64_to_uint64_scalbn(float64 a, int rmode, int scale,
546
+ float_status *s)
547
+{
548
+ return round_to_uint_and_pack(float64_unpack_canonical(a, s),
549
+ rmode, scale, UINT64_MAX, s);
550
+}
551
+
552
+uint16_t float16_to_uint16(float16 a, float_status *s)
553
+{
554
+ return float16_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
555
+}
556
+
557
+uint32_t float16_to_uint32(float16 a, float_status *s)
558
+{
559
+ return float16_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
560
+}
561
+
562
+uint64_t float16_to_uint64(float16 a, float_status *s)
563
+{
564
+ return float16_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
565
+}
566
+
567
+uint16_t float32_to_uint16(float32 a, float_status *s)
568
+{
569
+ return float32_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
570
+}
571
+
572
+uint32_t float32_to_uint32(float32 a, float_status *s)
573
+{
574
+ return float32_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
575
+}
576
+
577
+uint64_t float32_to_uint64(float32 a, float_status *s)
578
+{
579
+ return float32_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
580
+}
581
+
582
+uint16_t float64_to_uint16(float64 a, float_status *s)
583
+{
584
+ return float64_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
585
+}
586
+
587
+uint32_t float64_to_uint32(float64 a, float_status *s)
588
+{
589
+ return float64_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
590
+}
591
+
592
+uint64_t float64_to_uint64(float64 a, float_status *s)
593
+{
594
+ return float64_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
595
+}
596
+
597
+uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *s)
598
+{
599
+ return float16_to_uint16_scalbn(a, float_round_to_zero, 0, s);
600
+}
601
+
602
+uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *s)
603
+{
604
+ return float16_to_uint32_scalbn(a, float_round_to_zero, 0, s);
605
+}
606
+
607
+uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *s)
608
+{
609
+ return float16_to_uint64_scalbn(a, float_round_to_zero, 0, s);
610
+}
611
+
612
+uint16_t float32_to_uint16_round_to_zero(float32 a, float_status *s)
613
+{
614
+ return float32_to_uint16_scalbn(a, float_round_to_zero, 0, s);
615
+}
616
+
617
+uint32_t float32_to_uint32_round_to_zero(float32 a, float_status *s)
618
+{
619
+ return float32_to_uint32_scalbn(a, float_round_to_zero, 0, s);
620
+}
621
+
622
+uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *s)
623
+{
624
+ return float32_to_uint64_scalbn(a, float_round_to_zero, 0, s);
625
+}
626
+
627
+uint16_t float64_to_uint16_round_to_zero(float64 a, float_status *s)
628
+{
629
+ return float64_to_uint16_scalbn(a, float_round_to_zero, 0, s);
630
+}
631
+
632
+uint32_t float64_to_uint32_round_to_zero(float64 a, float_status *s)
633
+{
634
+ return float64_to_uint32_scalbn(a, float_round_to_zero, 0, s);
635
+}
636
+
637
+uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *s)
638
+{
639
+ return float64_to_uint64_scalbn(a, float_round_to_zero, 0, s);
640
+}
641
642
/*
643
* Integer to float conversions
644
--
60
--
645
2.18.0
61
2.20.1
646
62
647
63
diff view generated by jsdifflib
1
The MPS2 FPGAIO block includes some simple free-running counters.
1
From: Gan Qixin <ganqixin@huawei.com>
2
Implement these.
3
2
3
When running device-introspect-test, a memory leak occurred in the
4
exynos4210_rtc_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 96 byte(s) in 1 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf57b3934 in exynos4210_rtc_init /qemu/hw/rtc/exynos4210_rtc.c:567
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
16
#6 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
17
#7 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
18
#8 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
19
#9 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
20
#10 0xaaabf6552708 in aio_bh_poll /qemu/util/async.c:164
21
#11 0xaaabf655f19c in aio_dispatch /qemu/util/aio-posix.c:381
22
#12 0xaaabf65523f4 in aio_ctx_dispatch /qemu/util/async.c:306
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180820141116.9118-2-peter.maydell@linaro.org
7
---
28
---
8
include/hw/misc/mps2-fpgaio.h | 4 +++
29
hw/rtc/exynos4210_rtc.c | 9 +++++++++
9
hw/misc/mps2-fpgaio.c | 53 ++++++++++++++++++++++++++++++++++-
30
1 file changed, 9 insertions(+)
10
2 files changed, 56 insertions(+), 1 deletion(-)
11
31
12
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
32
diff --git a/hw/rtc/exynos4210_rtc.c b/hw/rtc/exynos4210_rtc.c
13
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/misc/mps2-fpgaio.h
34
--- a/hw/rtc/exynos4210_rtc.c
15
+++ b/include/hw/misc/mps2-fpgaio.h
35
+++ b/hw/rtc/exynos4210_rtc.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct {
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_rtc_init(Object *obj)
17
uint32_t misc;
37
sysbus_init_mmio(dev, &s->iomem);
18
38
}
19
uint32_t prescale_clk;
39
40
+static void exynos4210_rtc_finalize(Object *obj)
41
+{
42
+ Exynos4210RTCState *s = EXYNOS4210_RTC(obj);
20
+
43
+
21
+ /* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was zero */
44
+ ptimer_free(s->ptimer);
22
+ int64_t clk1hz_tick_offset;
45
+ ptimer_free(s->ptimer_1Hz);
23
+ int64_t clk100hz_tick_offset;
24
} MPS2FPGAIO;
25
26
#endif
27
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/misc/mps2-fpgaio.c
30
+++ b/hw/misc/mps2-fpgaio.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/sysbus.h"
33
#include "hw/registerfields.h"
34
#include "hw/misc/mps2-fpgaio.h"
35
+#include "qemu/timer.h"
36
37
REG32(LED0, 0)
38
REG32(BUTTON, 8)
39
@@ -XXX,XX +XXX,XX @@ REG32(PRESCALE, 0x1c)
40
REG32(PSCNTR, 0x20)
41
REG32(MISC, 0x4c)
42
43
+static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int frq)
44
+{
45
+ return muldiv64(now - tick_offset, frq, NANOSECONDS_PER_SECOND);
46
+}
46
+}
47
+
47
+
48
+static int64_t tickoff_from_counter(int64_t now, uint32_t count, int frq)
48
static void exynos4210_rtc_class_init(ObjectClass *klass, void *data)
49
+{
50
+ return now - muldiv64(count, NANOSECONDS_PER_SECOND, frq);
51
+}
52
+
53
static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
54
{
49
{
55
MPS2FPGAIO *s = MPS2_FPGAIO(opaque);
50
DeviceClass *dc = DEVICE_CLASS(klass);
56
uint64_t r;
51
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_rtc_info = {
57
+ int64_t now;
52
.parent = TYPE_SYS_BUS_DEVICE,
58
53
.instance_size = sizeof(Exynos4210RTCState),
59
switch (offset) {
54
.instance_init = exynos4210_rtc_init,
60
case A_LED0:
55
+ .instance_finalize = exynos4210_rtc_finalize,
61
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
56
.class_init = exynos4210_rtc_class_init,
62
r = s->misc;
63
break;
64
case A_CLK1HZ:
65
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
66
+ r = counter_from_tickoff(now, s->clk1hz_tick_offset, 1);
67
+ break;
68
case A_CLK100HZ:
69
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
70
+ r = counter_from_tickoff(now, s->clk100hz_tick_offset, 100);
71
+ break;
72
case A_COUNTER:
73
case A_PSCNTR:
74
- /* These are all upcounters of various frequencies. */
75
qemu_log_mask(LOG_UNIMP, "MPS2 FPGAIO: counters unimplemented\n");
76
r = 0;
77
break;
78
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
79
unsigned size)
80
{
81
MPS2FPGAIO *s = MPS2_FPGAIO(opaque);
82
+ int64_t now;
83
84
trace_mps2_fpgaio_write(offset, value, size);
85
86
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
87
"MPS2 FPGAIO: MISC control bits unimplemented\n");
88
s->misc = value;
89
break;
90
+ case A_CLK1HZ:
91
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
92
+ s->clk1hz_tick_offset = tickoff_from_counter(now, value, 1);
93
+ break;
94
+ case A_CLK100HZ:
95
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
96
+ s->clk100hz_tick_offset = tickoff_from_counter(now, value, 100);
97
+ break;
98
default:
99
qemu_log_mask(LOG_GUEST_ERROR,
100
"MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset);
101
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps mps2_fpgaio_ops = {
102
static void mps2_fpgaio_reset(DeviceState *dev)
103
{
104
MPS2FPGAIO *s = MPS2_FPGAIO(dev);
105
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
106
107
trace_mps2_fpgaio_reset();
108
s->led0 = 0;
109
s->prescale = 0;
110
s->misc = 0;
111
+ s->clk1hz_tick_offset = tickoff_from_counter(now, 0, 1);
112
+ s->clk100hz_tick_offset = tickoff_from_counter(now, 0, 100);
113
}
114
115
static void mps2_fpgaio_init(Object *obj)
116
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_init(Object *obj)
117
sysbus_init_mmio(sbd, &s->iomem);
118
}
119
120
+static bool mps2_fpgaio_counters_needed(void *opaque)
121
+{
122
+ /* Currently vmstate.c insists all subsections have a 'needed' function */
123
+ return true;
124
+}
125
+
126
+static const VMStateDescription mps2_fpgaio_counters_vmstate = {
127
+ .name = "mps2-fpgaio/counters",
128
+ .version_id = 1,
129
+ .minimum_version_id = 1,
130
+ .needed = mps2_fpgaio_counters_needed,
131
+ .fields = (VMStateField[]) {
132
+ VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO),
133
+ VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO),
134
+ VMSTATE_END_OF_LIST()
135
+ }
136
+};
137
+
138
static const VMStateDescription mps2_fpgaio_vmstate = {
139
.name = "mps2-fpgaio",
140
.version_id = 1,
141
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_fpgaio_vmstate = {
142
VMSTATE_UINT32(prescale, MPS2FPGAIO),
143
VMSTATE_UINT32(misc, MPS2FPGAIO),
144
VMSTATE_END_OF_LIST()
145
+ },
146
+ .subsections = (const VMStateDescription*[]) {
147
+ &mps2_fpgaio_counters_vmstate,
148
+ NULL
149
}
150
};
57
};
151
58
152
--
59
--
153
2.18.0
60
2.20.1
154
61
155
62
diff view generated by jsdifflib
1
The IoTKit does not have any Master Security Contollers itself,
1
From: Gan Qixin <ganqixin@huawei.com>
2
but it does provide registers in the secure privilege control
3
block which allow control of MSCs in the external system.
4
Add support for these registers.
5
2
3
When running device-introspect-test, a memory leak occurred in the
4
exynos4210_pwm_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 240 byte(s) in 5 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
13
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
14
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
15
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
16
#6 0xaaabf56a36cc in exynos4210_pwm_init /qemu/hw/timer/exynos4210_pwm.c:401
17
#7 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
18
#8 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
19
#9 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
20
#10 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
21
#11 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
22
#12 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180820141116.9118-13-peter.maydell@linaro.org
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
---
28
---
11
include/hw/misc/iotkit-secctl.h | 14 +++++++
29
hw/timer/exynos4210_pwm.c | 11 +++++++++++
12
hw/misc/iotkit-secctl.c | 73 +++++++++++++++++++++++++++++----
30
1 file changed, 11 insertions(+)
13
2 files changed, 79 insertions(+), 8 deletions(-)
14
31
15
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
32
diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c
16
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/iotkit-secctl.h
34
--- a/hw/timer/exynos4210_pwm.c
18
+++ b/include/hw/misc/iotkit-secctl.h
35
+++ b/hw/timer/exynos4210_pwm.c
19
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_init(Object *obj)
20
* + named GPIO output "sec_resp_cfg" indicating whether blocked accesses
37
sysbus_init_mmio(dev, &s->iomem);
21
* should RAZ/WI or bus error
22
* + named GPIO output "nsc_cfg" whose value tracks the NSCCFG register value
23
+ * + named GPIO output "msc_irq" for the combined IRQ line from the MSCs
24
* Controlling the 2 APB PPCs in the IoTKit:
25
* + named GPIO outputs apb_ppc0_nonsec[0..2] and apb_ppc1_nonsec
26
* + named GPIO outputs apb_ppc0_ap[0..2] and apb_ppc1_ap
27
@@ -XXX,XX +XXX,XX @@
28
* Controlling each of the 16 expansion MPCs which a system using the IoTKit
29
* might provide:
30
* + named GPIO inputs mpcexp_status[0..15]
31
+ * Controlling each of the 16 expansion MSCs which a system using the IoTKit
32
+ * might provide:
33
+ * + named GPIO inputs mscexp_status[0..15]
34
+ * + named GPIO outputs mscexp_clear[0..15]
35
+ * + named GPIO outputs mscexp_ns[0..15]
36
*/
37
38
#ifndef IOTKIT_SECCTL_H
39
@@ -XXX,XX +XXX,XX @@
40
#define IOTS_NUM_AHB_EXP_PPC 4
41
#define IOTS_NUM_EXP_MPC 16
42
#define IOTS_NUM_MPC 1
43
+#define IOTS_NUM_EXP_MSC 16
44
45
typedef struct IoTKitSecCtl IoTKitSecCtl;
46
47
@@ -XXX,XX +XXX,XX @@ struct IoTKitSecCtl {
48
uint32_t brginten;
49
uint32_t mpcintstatus;
50
51
+ uint32_t secmscintstat;
52
+ uint32_t secmscinten;
53
+ uint32_t nsmscexp;
54
+ qemu_irq mscexp_clear[IOTS_NUM_EXP_MSC];
55
+ qemu_irq mscexp_ns[IOTS_NUM_EXP_MSC];
56
+ qemu_irq msc_irq;
57
+
58
IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC];
59
IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC];
60
IoTKitSecCtlPPC ahbexp[IOTS_NUM_APB_EXP_PPC];
61
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/misc/iotkit-secctl.c
64
+++ b/hw/misc/iotkit-secctl.c
65
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
66
r = s->apbexp[offset_to_ppc_idx(offset)].sp;
67
break;
68
case A_SECMSCINTSTAT:
69
+ r = s->secmscintstat;
70
+ break;
71
case A_SECMSCINTEN:
72
+ r = s->secmscinten;
73
+ break;
74
case A_NSMSCEXP:
75
- qemu_log_mask(LOG_UNIMP,
76
- "IoTKit SecCtl S block read: "
77
- "unimplemented offset 0x%x\n", offset);
78
- r = 0;
79
+ r = s->nsmscexp;
80
break;
81
case A_PID4:
82
case A_PID5:
83
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
84
qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
85
}
38
}
86
39
87
+static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value)
40
+static void exynos4210_pwm_finalize(Object *obj)
88
+{
41
+{
42
+ Exynos4210PWMState *s = EXYNOS4210_PWM(obj);
89
+ int i;
43
+ int i;
90
+
44
+
91
+ for (i = 0; i < IOTS_NUM_EXP_MSC; i++) {
45
+ for (i = 0; i < EXYNOS4210_PWM_TIMERS_NUM; i++) {
92
+ qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1));
46
+ ptimer_free(s->timer[i].ptimer);
93
+ }
47
+ }
94
+}
48
+}
95
+
49
+
96
+static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s)
50
static void exynos4210_pwm_class_init(ObjectClass *klass, void *data)
97
+{
98
+ /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_EN */
99
+ bool level = s->secmscintstat & s->secmscinten;
100
+
101
+ qemu_set_irq(s->msc_irq, level);
102
+}
103
+
104
static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
105
uint64_t value,
106
unsigned size, MemTxAttrs attrs)
107
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
108
iotkit_secctl_ppc_sp_write(ppc, value);
109
break;
110
case A_SECMSCINTCLR:
111
+ iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value);
112
+ break;
113
case A_SECMSCINTEN:
114
- qemu_log_mask(LOG_UNIMP,
115
- "IoTKit SecCtl S block write: "
116
- "unimplemented offset 0x%x\n", offset);
117
+ s->secmscinten = value;
118
+ iotkit_secctl_update_msc_irq(s);
119
+ break;
120
+ case A_NSMSCEXP:
121
+ s->nsmscexp = value;
122
+ iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value);
123
break;
124
case A_SECMPCINTSTATUS:
125
case A_SECPPCINTSTAT:
126
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
127
case A_BRGINTSTAT:
128
case A_AHBNSPPC0:
129
case A_AHBSPPPC0:
130
- case A_NSMSCEXP:
131
case A_PID4:
132
case A_PID5:
133
case A_PID6:
134
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
135
s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level);
136
}
137
138
+static void iotkit_secctl_mscexp_status(void *opaque, int n, int level)
139
+{
140
+ IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
141
+
142
+ s->secmscintstat = deposit32(s->secmscintstat, n + 16, 1, !!level);
143
+ iotkit_secctl_update_msc_irq(s);
144
+}
145
+
146
static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
147
{
51
{
148
IoTKitSecCtlPPC *ppc = opaque;
52
DeviceClass *dc = DEVICE_CLASS(klass);
149
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_init(Object *obj)
53
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_pwm_info = {
150
qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
54
.parent = TYPE_SYS_BUS_DEVICE,
151
"mpcexp_status", IOTS_NUM_EXP_MPC);
55
.instance_size = sizeof(Exynos4210PWMState),
152
56
.instance_init = exynos4210_pwm_init,
153
+ qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status,
57
+ .instance_finalize = exynos4210_pwm_finalize,
154
+ "mscexp_status", IOTS_NUM_EXP_MSC);
58
.class_init = exynos4210_pwm_class_init,
155
+ qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear",
156
+ IOTS_NUM_EXP_MSC);
157
+ qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns",
158
+ IOTS_NUM_EXP_MSC);
159
+ qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1);
160
+
161
memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
162
s, "iotkit-secctl-s-regs", 0x1000);
163
memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
164
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = {
165
}
166
};
59
};
167
60
168
+static bool needed_always(void *opaque)
169
+{
170
+ return true;
171
+}
172
+
173
+static const VMStateDescription iotkit_secctl_msc_vmstate = {
174
+ .name = "iotkit-secctl/msc",
175
+ .version_id = 1,
176
+ .minimum_version_id = 1,
177
+ .needed = needed_always,
178
+ .fields = (VMStateField[]) {
179
+ VMSTATE_UINT32(secmscintstat, IoTKitSecCtl),
180
+ VMSTATE_UINT32(secmscinten, IoTKitSecCtl),
181
+ VMSTATE_UINT32(nsmscexp, IoTKitSecCtl),
182
+ VMSTATE_END_OF_LIST()
183
+ }
184
+};
185
+
186
static const VMStateDescription iotkit_secctl_vmstate = {
187
.name = "iotkit-secctl",
188
.version_id = 1,
189
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_secctl_vmstate = {
190
},
191
.subsections = (const VMStateDescription*[]) {
192
&iotkit_secctl_mpcintstatus_vmstate,
193
+ &iotkit_secctl_msc_vmstate,
194
NULL
195
},
196
};
197
--
61
--
198
2.18.0
62
2.20.1
199
63
200
64
diff view generated by jsdifflib
1
Add a "virtualization" property to the vexpress-a15 board,
1
From: Gan Qixin <ganqixin@huawei.com>
2
controlling presence of EL2. As with EL3, we default to
3
enabling it, but the user can disable it if they have an
4
older guest which can't cope with it being present.
5
2
3
When running device-introspect-test, a memory leak occurred in the
4
mss_timer_init function, so use ptimer_free() in the finalize function to avoid
5
it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 192 byte(s) in 2 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf58a0010 in mss_timer_init /qemu/hw/timer/mss-timer.c:235
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
16
#6 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
17
#7 0xaaabf5b8316c in m2sxxx_soc_initfn /qemu/hw/arm/msf2-soc.c:70
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
22
#12 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20180821132811.17675-10-peter.maydell@linaro.org
9
---
28
---
10
hw/arm/vexpress.c | 56 ++++++++++++++++++++++++++++++++++++++++++++---
29
hw/timer/mss-timer.c | 13 +++++++++++++
11
1 file changed, 53 insertions(+), 3 deletions(-)
30
1 file changed, 13 insertions(+)
12
31
13
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
32
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
14
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/vexpress.c
34
--- a/hw/timer/mss-timer.c
16
+++ b/hw/arm/vexpress.c
35
+++ b/hw/timer/mss-timer.c
17
@@ -XXX,XX +XXX,XX @@ typedef struct {
36
@@ -XXX,XX +XXX,XX @@ static void mss_timer_init(Object *obj)
18
typedef struct {
37
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &t->mmio);
19
MachineState parent;
20
bool secure;
21
+ bool virt;
22
} VexpressMachineState;
23
24
#define TYPE_VEXPRESS_MACHINE "vexpress"
25
@@ -XXX,XX +XXX,XX @@ struct VEDBoardInfo {
26
};
27
28
static void init_cpus(const char *cpu_type, const char *privdev,
29
- hwaddr periphbase, qemu_irq *pic, bool secure)
30
+ hwaddr periphbase, qemu_irq *pic, bool secure, bool virt)
31
{
32
DeviceState *dev;
33
SysBusDevice *busdev;
34
@@ -XXX,XX +XXX,XX @@ static void init_cpus(const char *cpu_type, const char *privdev,
35
if (!secure) {
36
object_property_set_bool(cpuobj, false, "has_el3", NULL);
37
}
38
+ if (!virt) {
39
+ if (object_property_find(cpuobj, "has_el2", NULL)) {
40
+ object_property_set_bool(cpuobj, false, "has_el2", NULL);
41
+ }
42
+ }
43
44
if (object_property_find(cpuobj, "reset-cbar", NULL)) {
45
object_property_set_int(cpuobj, periphbase,
46
@@ -XXX,XX +XXX,XX @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
47
memory_region_add_subregion(sysmem, 0x60000000, ram);
48
49
/* 0x1e000000 A9MPCore (SCU) private memory region */
50
- init_cpus(cpu_type, TYPE_A9MPCORE_PRIV, 0x1e000000, pic, vms->secure);
51
+ init_cpus(cpu_type, TYPE_A9MPCORE_PRIV, 0x1e000000, pic,
52
+ vms->secure, vms->virt);
53
54
/* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
55
56
@@ -XXX,XX +XXX,XX @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
57
memory_region_add_subregion(sysmem, 0x80000000, ram);
58
59
/* 0x2c000000 A15MPCore private memory region (GIC) */
60
- init_cpus(cpu_type, TYPE_A15MPCORE_PRIV, 0x2c000000, pic, vms->secure);
61
+ init_cpus(cpu_type, TYPE_A15MPCORE_PRIV, 0x2c000000, pic, vms->secure,
62
+ vms->virt);
63
64
/* A15 daughterboard peripherals: */
65
66
@@ -XXX,XX +XXX,XX @@ static void vexpress_set_secure(Object *obj, bool value, Error **errp)
67
vms->secure = value;
68
}
38
}
69
39
70
+static bool vexpress_get_virt(Object *obj, Error **errp)
40
+static void mss_timer_finalize(Object *obj)
71
+{
41
+{
72
+ VexpressMachineState *vms = VEXPRESS_MACHINE(obj);
42
+ MSSTimerState *t = MSS_TIMER(obj);
43
+ int i;
73
+
44
+
74
+ return vms->virt;
45
+ for (i = 0; i < NUM_TIMERS; i++) {
46
+ struct Msf2Timer *st = &t->timers[i];
47
+
48
+ ptimer_free(st->ptimer);
49
+ }
75
+}
50
+}
76
+
51
+
77
+static void vexpress_set_virt(Object *obj, bool value, Error **errp)
52
static const VMStateDescription vmstate_timers = {
78
+{
53
.name = "mss-timer-block",
79
+ VexpressMachineState *vms = VEXPRESS_MACHINE(obj);
54
.version_id = 1,
80
+
55
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mss_timer_info = {
81
+ vms->virt = value;
56
.parent = TYPE_SYS_BUS_DEVICE,
82
+}
57
.instance_size = sizeof(MSSTimerState),
83
+
58
.instance_init = mss_timer_init,
84
static void vexpress_instance_init(Object *obj)
59
+ .instance_finalize = mss_timer_finalize,
85
{
60
.class_init = mss_timer_class_init,
86
VexpressMachineState *vms = VEXPRESS_MACHINE(obj);
87
@@ -XXX,XX +XXX,XX @@ static void vexpress_instance_init(Object *obj)
88
NULL);
89
}
90
91
+static void vexpress_a15_instance_init(Object *obj)
92
+{
93
+ VexpressMachineState *vms = VEXPRESS_MACHINE(obj);
94
+
95
+ /*
96
+ * For the vexpress-a15, EL2 is by default enabled if EL3 is,
97
+ * but can also be specifically set to on or off.
98
+ */
99
+ vms->virt = true;
100
+ object_property_add_bool(obj, "virtualization", vexpress_get_virt,
101
+ vexpress_set_virt, NULL);
102
+ object_property_set_description(obj, "virtualization",
103
+ "Set on/off to enable/disable the ARM "
104
+ "Virtualization Extensions "
105
+ "(defaults to same as 'secure')",
106
+ NULL);
107
+}
108
+
109
+static void vexpress_a9_instance_init(Object *obj)
110
+{
111
+ VexpressMachineState *vms = VEXPRESS_MACHINE(obj);
112
+
113
+ /* The A9 doesn't have the virt extensions */
114
+ vms->virt = false;
115
+}
116
+
117
static void vexpress_class_init(ObjectClass *oc, void *data)
118
{
119
MachineClass *mc = MACHINE_CLASS(oc);
120
@@ -XXX,XX +XXX,XX @@ static const TypeInfo vexpress_a9_info = {
121
.name = TYPE_VEXPRESS_A9_MACHINE,
122
.parent = TYPE_VEXPRESS_MACHINE,
123
.class_init = vexpress_a9_class_init,
124
+ .instance_init = vexpress_a9_instance_init,
125
};
61
};
126
62
127
static const TypeInfo vexpress_a15_info = {
128
.name = TYPE_VEXPRESS_A15_MACHINE,
129
.parent = TYPE_VEXPRESS_MACHINE,
130
.class_init = vexpress_a15_class_init,
131
+ .instance_init = vexpress_a15_instance_init,
132
};
133
134
static void vexpress_machine_init(void)
135
--
63
--
136
2.18.0
64
2.20.1
137
65
138
66
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
When running device-introspect-test, a memory leak occurred in the
4
Message-id: 20180814002653.12828-4-richard.henderson@linaro.org
4
mv88w8618_pit_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 192 byte(s) in 4 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
13
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
14
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
15
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
16
#6 0xaaabf5bb2290 in mv88w8618_timer_init /qemu/hw/arm/musicpal.c:862
17
#7 0xaaabf5bb2290 in mv88w8618_pit_init /qemu/hw/arm/musicpal.c:954
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf5a95540 in qdev_device_help /qemu/softmmu/qdev-monitor.c:283
22
#12 0xaaabf5a96940 in qmp_device_add /qemu/softmmu/qdev-monitor.c:801
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
28
---
8
target/arm/helper.c | 29 +++++------------------------
29
hw/arm/musicpal.c | 12 ++++++++++++
9
1 file changed, 5 insertions(+), 24 deletions(-)
30
1 file changed, 12 insertions(+)
10
31
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
12
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
34
--- a/hw/arm/musicpal.c
14
+++ b/target/arm/helper.c
35
+++ b/hw/arm/musicpal.c
15
@@ -XXX,XX +XXX,XX @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
36
@@ -XXX,XX +XXX,XX @@ static void mv88w8618_pit_init(Object *obj)
16
#define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
37
sysbus_init_mmio(dev, &s->iomem);
17
float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
18
void *fpstp) \
19
-{ \
20
- float_status *fpst = fpstp; \
21
- float##fsz tmp; \
22
- tmp = itype##_to_##float##fsz(x, fpst); \
23
- return float##fsz##_scalbn(tmp, -(int)shift, fpst); \
24
-}
25
+{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); }
26
27
/* Notice that we want only input-denormal exception flags from the
28
* scalbn operation: the other possible flags (overflow+inexact if
29
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
30
#undef VFP_CONV_FLOAT_FIX_ROUND
31
#undef VFP_CONV_FIX_A64
32
33
-/* Conversion to/from f16 can overflow to infinity before/after scaling.
34
- * Therefore we convert to f64, scale, and then convert f64 to f16; or
35
- * vice versa for conversion to integer.
36
- *
37
- * For 16- and 32-bit integers, the conversion to f64 never rounds.
38
- * For 64-bit integers, any integer that would cause rounding will also
39
- * overflow to f16 infinity, so there is no double rounding problem.
40
- */
41
-
42
-static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
43
-{
44
- return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
45
-}
46
-
47
uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
48
{
49
- return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
50
+ return int32_to_float16_scalbn(x, -shift, fpst);
51
}
38
}
52
39
53
uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
40
+static void mv88w8618_pit_finalize(Object *obj)
54
{
41
+{
55
- return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
42
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
56
+ return uint32_to_float16_scalbn(x, -shift, fpst);
43
+ mv88w8618_pit_state *s = MV88W8618_PIT(dev);
57
}
44
+ int i;
58
45
+
59
uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
46
+ for (i = 0; i < 4; i++) {
60
{
47
+ ptimer_free(s->timer[i].ptimer);
61
- return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
48
+ }
62
+ return int64_to_float16_scalbn(x, -shift, fpst);
49
+}
63
}
50
+
64
51
static const VMStateDescription mv88w8618_timer_vmsd = {
65
uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
52
.name = "timer",
66
{
53
.version_id = 1,
67
- return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mv88w8618_pit_info = {
68
+ return uint64_to_float16_scalbn(x, -shift, fpst);
55
.parent = TYPE_SYS_BUS_DEVICE,
69
}
56
.instance_size = sizeof(mv88w8618_pit_state),
70
57
.instance_init = mv88w8618_pit_init,
71
static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
58
+ .instance_finalize = mv88w8618_pit_finalize,
59
.class_init = mv88w8618_pit_class_init,
60
};
61
72
--
62
--
73
2.18.0
63
2.20.1
74
64
75
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
When running device-introspect-test, a memory leak occurred in the
4
Message-id: 20180814002653.12828-2-richard.henderson@linaro.org
4
exynos4210_mct_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 96 byte(s) in 1 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf56b01a0 in exynos4210_mct_init /qemu/hw/timer/exynos4210_mct.c:1505
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
16
#6 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
17
#7 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
18
#8 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
19
#9 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
20
#10 0xaaabf6552708 in aio_bh_poll /qemu/util/async.c:164
21
#11 0xaaabf655f19c in aio_dispatch /qemu/util/aio-posix.c:381
22
#12 0xaaabf65523f4 in aio_ctx_dispatch /qemu/util/async.c:306
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
28
---
8
include/fpu/softfloat.h | 56 ++++++++----
29
hw/timer/exynos4210_mct.c | 14 ++++++++++++++
9
fpu/softfloat.c | 188 +++++++++++++++++++++++++++++-----------
30
1 file changed, 14 insertions(+)
10
2 files changed, 179 insertions(+), 65 deletions(-)
11
31
12
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
32
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
13
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
14
--- a/include/fpu/softfloat.h
34
--- a/hw/timer/exynos4210_mct.c
15
+++ b/include/fpu/softfloat.h
35
+++ b/hw/timer/exynos4210_mct.c
16
@@ -XXX,XX +XXX,XX @@ enum {
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_init(Object *obj)
17
/*----------------------------------------------------------------------------
37
sysbus_init_mmio(dev, &s->iomem);
18
| Software IEC/IEEE integer-to-floating-point conversion routines.
38
}
19
*----------------------------------------------------------------------------*/
39
40
+static void exynos4210_mct_finalize(Object *obj)
41
+{
42
+ int i;
43
+ Exynos4210MCTState *s = EXYNOS4210_MCT(obj);
20
+
44
+
21
+float16 int16_to_float16_scalbn(int16_t a, int, float_status *status);
45
+ ptimer_free(s->g_timer.ptimer_frc);
22
+float16 int32_to_float16_scalbn(int32_t a, int, float_status *status);
23
+float16 int64_to_float16_scalbn(int64_t a, int, float_status *status);
24
+float16 uint16_to_float16_scalbn(uint16_t a, int, float_status *status);
25
+float16 uint32_to_float16_scalbn(uint32_t a, int, float_status *status);
26
+float16 uint64_to_float16_scalbn(uint64_t a, int, float_status *status);
27
+
46
+
28
+float16 int16_to_float16(int16_t a, float_status *status);
47
+ for (i = 0; i < 2; i++) {
29
+float16 int32_to_float16(int32_t a, float_status *status);
48
+ ptimer_free(s->l_timer[i].tick_timer.ptimer_tick);
30
+float16 int64_to_float16(int64_t a, float_status *status);
49
+ ptimer_free(s->l_timer[i].ptimer_frc);
31
+float16 uint16_to_float16(uint16_t a, float_status *status);
50
+ }
32
+float16 uint32_to_float16(uint32_t a, float_status *status);
33
+float16 uint64_to_float16(uint64_t a, float_status *status);
34
+
35
+float32 int16_to_float32_scalbn(int16_t, int, float_status *status);
36
+float32 int32_to_float32_scalbn(int32_t, int, float_status *status);
37
+float32 int64_to_float32_scalbn(int64_t, int, float_status *status);
38
+float32 uint16_to_float32_scalbn(uint16_t, int, float_status *status);
39
+float32 uint32_to_float32_scalbn(uint32_t, int, float_status *status);
40
+float32 uint64_to_float32_scalbn(uint64_t, int, float_status *status);
41
+
42
float32 int16_to_float32(int16_t, float_status *status);
43
float32 int32_to_float32(int32_t, float_status *status);
44
-float64 int16_to_float64(int16_t, float_status *status);
45
-float64 int32_to_float64(int32_t, float_status *status);
46
+float32 int64_to_float32(int64_t, float_status *status);
47
float32 uint16_to_float32(uint16_t, float_status *status);
48
float32 uint32_to_float32(uint32_t, float_status *status);
49
+float32 uint64_to_float32(uint64_t, float_status *status);
50
+
51
+float64 int16_to_float64_scalbn(int16_t, int, float_status *status);
52
+float64 int32_to_float64_scalbn(int32_t, int, float_status *status);
53
+float64 int64_to_float64_scalbn(int64_t, int, float_status *status);
54
+float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status);
55
+float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status);
56
+float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status);
57
+
58
+float64 int16_to_float64(int16_t, float_status *status);
59
+float64 int32_to_float64(int32_t, float_status *status);
60
+float64 int64_to_float64(int64_t, float_status *status);
61
float64 uint16_to_float64(uint16_t, float_status *status);
62
float64 uint32_to_float64(uint32_t, float_status *status);
63
-floatx80 int32_to_floatx80(int32_t, float_status *status);
64
-float128 int32_to_float128(int32_t, float_status *status);
65
-float32 int64_to_float32(int64_t, float_status *status);
66
-float64 int64_to_float64(int64_t, float_status *status);
67
-floatx80 int64_to_floatx80(int64_t, float_status *status);
68
-float128 int64_to_float128(int64_t, float_status *status);
69
-float32 uint64_to_float32(uint64_t, float_status *status);
70
float64 uint64_to_float64(uint64_t, float_status *status);
71
+
72
+floatx80 int32_to_floatx80(int32_t, float_status *status);
73
+floatx80 int64_to_floatx80(int64_t, float_status *status);
74
+
75
+float128 int32_to_float128(int32_t, float_status *status);
76
+float128 int64_to_float128(int64_t, float_status *status);
77
float128 uint64_to_float128(uint64_t, float_status *status);
78
79
/*----------------------------------------------------------------------------
80
@@ -XXX,XX +XXX,XX @@ int64_t float16_to_int64(float16, float_status *status);
81
uint64_t float16_to_uint64(float16 a, float_status *status);
82
int64_t float16_to_int64_round_to_zero(float16, float_status *status);
83
uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status);
84
-float16 int16_to_float16(int16_t a, float_status *status);
85
-float16 int32_to_float16(int32_t a, float_status *status);
86
-float16 int64_to_float16(int64_t a, float_status *status);
87
-float16 uint16_to_float16(uint16_t a, float_status *status);
88
-float16 uint32_to_float16(uint32_t a, float_status *status);
89
-float16 uint64_to_float16(uint64_t a, float_status *status);
90
91
/*----------------------------------------------------------------------------
92
| Software half-precision operations.
93
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/fpu/softfloat.c
96
+++ b/fpu/softfloat.c
97
@@ -XXX,XX +XXX,XX @@ FLOAT_TO_UINT(64, 64)
98
* to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
99
*/
100
101
-static FloatParts int_to_float(int64_t a, float_status *status)
102
+static FloatParts int_to_float(int64_t a, int scale, float_status *status)
103
{
104
- FloatParts r = {};
105
+ FloatParts r = { .sign = false };
106
+
107
if (a == 0) {
108
r.cls = float_class_zero;
109
- r.sign = false;
110
- } else if (a == (1ULL << 63)) {
111
- r.cls = float_class_normal;
112
- r.sign = true;
113
- r.frac = DECOMPOSED_IMPLICIT_BIT;
114
- r.exp = 63;
115
} else {
116
- uint64_t f;
117
- if (a < 0) {
118
- f = -a;
119
- r.sign = true;
120
- } else {
121
- f = a;
122
- r.sign = false;
123
- }
124
- int shift = clz64(f) - 1;
125
+ uint64_t f = a;
126
+ int shift;
127
+
128
r.cls = float_class_normal;
129
- r.exp = (DECOMPOSED_BINARY_POINT - shift);
130
- r.frac = f << shift;
131
+ if (a < 0) {
132
+ f = -f;
133
+ r.sign = true;
134
+ }
135
+ shift = clz64(f) - 1;
136
+ scale = MIN(MAX(scale, -0x10000), 0x10000);
137
+
138
+ r.exp = DECOMPOSED_BINARY_POINT - shift + scale;
139
+ r.frac = (shift < 0 ? DECOMPOSED_IMPLICIT_BIT : f << shift);
140
}
141
142
return r;
143
}
144
145
+float16 int64_to_float16_scalbn(int64_t a, int scale, float_status *status)
146
+{
147
+ FloatParts pa = int_to_float(a, scale, status);
148
+ return float16_round_pack_canonical(pa, status);
149
+}
51
+}
150
+
52
+
151
+float16 int32_to_float16_scalbn(int32_t a, int scale, float_status *status)
53
static void exynos4210_mct_class_init(ObjectClass *klass, void *data)
152
+{
153
+ return int64_to_float16_scalbn(a, scale, status);
154
+}
155
+
156
+float16 int16_to_float16_scalbn(int16_t a, int scale, float_status *status)
157
+{
158
+ return int64_to_float16_scalbn(a, scale, status);
159
+}
160
+
161
float16 int64_to_float16(int64_t a, float_status *status)
162
{
54
{
163
- FloatParts pa = int_to_float(a, status);
55
DeviceClass *dc = DEVICE_CLASS(klass);
164
- return float16_round_pack_canonical(pa, status);
56
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_mct_info = {
165
+ return int64_to_float16_scalbn(a, 0, status);
57
.parent = TYPE_SYS_BUS_DEVICE,
166
}
58
.instance_size = sizeof(Exynos4210MCTState),
167
59
.instance_init = exynos4210_mct_init,
168
float16 int32_to_float16(int32_t a, float_status *status)
60
+ .instance_finalize = exynos4210_mct_finalize,
169
{
61
.class_init = exynos4210_mct_class_init,
170
- return int64_to_float16(a, status);
62
};
171
+ return int64_to_float16_scalbn(a, 0, status);
63
172
}
173
174
float16 int16_to_float16(int16_t a, float_status *status)
175
{
176
- return int64_to_float16(a, status);
177
+ return int64_to_float16_scalbn(a, 0, status);
178
+}
179
+
180
+float32 int64_to_float32_scalbn(int64_t a, int scale, float_status *status)
181
+{
182
+ FloatParts pa = int_to_float(a, scale, status);
183
+ return float32_round_pack_canonical(pa, status);
184
+}
185
+
186
+float32 int32_to_float32_scalbn(int32_t a, int scale, float_status *status)
187
+{
188
+ return int64_to_float32_scalbn(a, scale, status);
189
+}
190
+
191
+float32 int16_to_float32_scalbn(int16_t a, int scale, float_status *status)
192
+{
193
+ return int64_to_float32_scalbn(a, scale, status);
194
}
195
196
float32 int64_to_float32(int64_t a, float_status *status)
197
{
198
- FloatParts pa = int_to_float(a, status);
199
- return float32_round_pack_canonical(pa, status);
200
+ return int64_to_float32_scalbn(a, 0, status);
201
}
202
203
float32 int32_to_float32(int32_t a, float_status *status)
204
{
205
- return int64_to_float32(a, status);
206
+ return int64_to_float32_scalbn(a, 0, status);
207
}
208
209
float32 int16_to_float32(int16_t a, float_status *status)
210
{
211
- return int64_to_float32(a, status);
212
+ return int64_to_float32_scalbn(a, 0, status);
213
+}
214
+
215
+float64 int64_to_float64_scalbn(int64_t a, int scale, float_status *status)
216
+{
217
+ FloatParts pa = int_to_float(a, scale, status);
218
+ return float64_round_pack_canonical(pa, status);
219
+}
220
+
221
+float64 int32_to_float64_scalbn(int32_t a, int scale, float_status *status)
222
+{
223
+ return int64_to_float64_scalbn(a, scale, status);
224
+}
225
+
226
+float64 int16_to_float64_scalbn(int16_t a, int scale, float_status *status)
227
+{
228
+ return int64_to_float64_scalbn(a, scale, status);
229
}
230
231
float64 int64_to_float64(int64_t a, float_status *status)
232
{
233
- FloatParts pa = int_to_float(a, status);
234
- return float64_round_pack_canonical(pa, status);
235
+ return int64_to_float64_scalbn(a, 0, status);
236
}
237
238
float64 int32_to_float64(int32_t a, float_status *status)
239
{
240
- return int64_to_float64(a, status);
241
+ return int64_to_float64_scalbn(a, 0, status);
242
}
243
244
float64 int16_to_float64(int16_t a, float_status *status)
245
{
246
- return int64_to_float64(a, status);
247
+ return int64_to_float64_scalbn(a, 0, status);
248
}
249
250
251
@@ -XXX,XX +XXX,XX @@ float64 int16_to_float64(int16_t a, float_status *status)
252
* IEC/IEEE Standard for Binary Floating-Point Arithmetic.
253
*/
254
255
-static FloatParts uint_to_float(uint64_t a, float_status *status)
256
+static FloatParts uint_to_float(uint64_t a, int scale, float_status *status)
257
{
258
- FloatParts r = { .sign = false};
259
+ FloatParts r = { .sign = false };
260
261
if (a == 0) {
262
r.cls = float_class_zero;
263
} else {
264
- int spare_bits = clz64(a) - 1;
265
+ scale = MIN(MAX(scale, -0x10000), 0x10000);
266
r.cls = float_class_normal;
267
- r.exp = DECOMPOSED_BINARY_POINT - spare_bits;
268
- if (spare_bits < 0) {
269
- shift64RightJamming(a, -spare_bits, &a);
270
+ if ((int64_t)a < 0) {
271
+ r.exp = DECOMPOSED_BINARY_POINT + 1 + scale;
272
+ shift64RightJamming(a, 1, &a);
273
r.frac = a;
274
} else {
275
- r.frac = a << spare_bits;
276
+ int shift = clz64(a) - 1;
277
+ r.exp = DECOMPOSED_BINARY_POINT - shift + scale;
278
+ r.frac = a << shift;
279
}
280
}
281
282
return r;
283
}
284
285
+float16 uint64_to_float16_scalbn(uint64_t a, int scale, float_status *status)
286
+{
287
+ FloatParts pa = uint_to_float(a, scale, status);
288
+ return float16_round_pack_canonical(pa, status);
289
+}
290
+
291
+float16 uint32_to_float16_scalbn(uint32_t a, int scale, float_status *status)
292
+{
293
+ return uint64_to_float16_scalbn(a, scale, status);
294
+}
295
+
296
+float16 uint16_to_float16_scalbn(uint16_t a, int scale, float_status *status)
297
+{
298
+ return uint64_to_float16_scalbn(a, scale, status);
299
+}
300
+
301
float16 uint64_to_float16(uint64_t a, float_status *status)
302
{
303
- FloatParts pa = uint_to_float(a, status);
304
- return float16_round_pack_canonical(pa, status);
305
+ return uint64_to_float16_scalbn(a, 0, status);
306
}
307
308
float16 uint32_to_float16(uint32_t a, float_status *status)
309
{
310
- return uint64_to_float16(a, status);
311
+ return uint64_to_float16_scalbn(a, 0, status);
312
}
313
314
float16 uint16_to_float16(uint16_t a, float_status *status)
315
{
316
- return uint64_to_float16(a, status);
317
+ return uint64_to_float16_scalbn(a, 0, status);
318
+}
319
+
320
+float32 uint64_to_float32_scalbn(uint64_t a, int scale, float_status *status)
321
+{
322
+ FloatParts pa = uint_to_float(a, scale, status);
323
+ return float32_round_pack_canonical(pa, status);
324
+}
325
+
326
+float32 uint32_to_float32_scalbn(uint32_t a, int scale, float_status *status)
327
+{
328
+ return uint64_to_float32_scalbn(a, scale, status);
329
+}
330
+
331
+float32 uint16_to_float32_scalbn(uint16_t a, int scale, float_status *status)
332
+{
333
+ return uint64_to_float32_scalbn(a, scale, status);
334
}
335
336
float32 uint64_to_float32(uint64_t a, float_status *status)
337
{
338
- FloatParts pa = uint_to_float(a, status);
339
- return float32_round_pack_canonical(pa, status);
340
+ return uint64_to_float32_scalbn(a, 0, status);
341
}
342
343
float32 uint32_to_float32(uint32_t a, float_status *status)
344
{
345
- return uint64_to_float32(a, status);
346
+ return uint64_to_float32_scalbn(a, 0, status);
347
}
348
349
float32 uint16_to_float32(uint16_t a, float_status *status)
350
{
351
- return uint64_to_float32(a, status);
352
+ return uint64_to_float32_scalbn(a, 0, status);
353
+}
354
+
355
+float64 uint64_to_float64_scalbn(uint64_t a, int scale, float_status *status)
356
+{
357
+ FloatParts pa = uint_to_float(a, scale, status);
358
+ return float64_round_pack_canonical(pa, status);
359
+}
360
+
361
+float64 uint32_to_float64_scalbn(uint32_t a, int scale, float_status *status)
362
+{
363
+ return uint64_to_float64_scalbn(a, scale, status);
364
+}
365
+
366
+float64 uint16_to_float64_scalbn(uint16_t a, int scale, float_status *status)
367
+{
368
+ return uint64_to_float64_scalbn(a, scale, status);
369
}
370
371
float64 uint64_to_float64(uint64_t a, float_status *status)
372
{
373
- FloatParts pa = uint_to_float(a, status);
374
- return float64_round_pack_canonical(pa, status);
375
+ return uint64_to_float64_scalbn(a, 0, status);
376
}
377
378
float64 uint32_to_float64(uint32_t a, float_status *status)
379
{
380
- return uint64_to_float64(a, status);
381
+ return uint64_to_float64_scalbn(a, 0, status);
382
}
383
384
float64 uint16_to_float64(uint16_t a, float_status *status)
385
{
386
- return uint64_to_float64(a, status);
387
+ return uint64_to_float64_scalbn(a, 0, status);
388
}
389
390
/* Float Min/Max */
391
--
64
--
392
2.18.0
65
2.20.1
393
66
394
67
diff view generated by jsdifflib
Deleted patch
1
Connect the VIRQ and VFIQ lines from the GIC to the CPU;
2
these exist always for both CPU and GIC whether the
3
virtualization extensions are enabled or not, so we
4
can just unconditionally connect them.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20180821132811.17675-4-peter.maydell@linaro.org
9
---
10
hw/arm/vexpress.c | 4 ++++
11
1 file changed, 4 insertions(+)
12
13
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/vexpress.c
16
+++ b/hw/arm/vexpress.c
17
@@ -XXX,XX +XXX,XX @@ static void init_cpus(const char *cpu_type, const char *privdev,
18
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
19
sysbus_connect_irq(busdev, n + smp_cpus,
20
qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
21
+ sysbus_connect_irq(busdev, n + 2 * smp_cpus,
22
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
23
+ sysbus_connect_irq(busdev, n + 3 * smp_cpus,
24
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
25
}
26
}
27
28
--
29
2.18.0
30
31
diff view generated by jsdifflib
Deleted patch
1
Connect the VIRQ and VFIQ lines from the GIC to the CPU;
2
these exist always for both CPU and GIC whether the
3
virtualization extensions are enabled or not, so we
4
can just unconditionally connect them.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20180821132811.17675-6-peter.maydell@linaro.org
9
---
10
hw/arm/fsl-imx6ul.c | 4 ++++
11
1 file changed, 4 insertions(+)
12
13
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/fsl-imx6ul.c
16
+++ b/hw/arm/fsl-imx6ul.c
17
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
18
irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
19
sysbus_connect_irq(sbd, i, irq);
20
sysbus_connect_irq(sbd, i + smp_cpus, qdev_get_gpio_in(d, ARM_CPU_FIQ));
21
+ sysbus_connect_irq(sbd, i + 2 * smp_cpus,
22
+ qdev_get_gpio_in(d, ARM_CPU_VIRQ));
23
+ sysbus_connect_irq(sbd, i + 3 * smp_cpus,
24
+ qdev_get_gpio_in(d, ARM_CPU_VFIQ));
25
}
26
27
/*
28
--
29
2.18.0
30
31
diff view generated by jsdifflib
1
The PL022 interrupt registers have bits allocated as:
1
From: Bin Meng <bin.meng@windriver.com>
2
0: ROR (receive overrun)
3
1: RT (receive timeout)
4
2: RX (receive FIFO half full or less)
5
3: TX (transmit FIFO half full or less)
6
2
7
A cut and paste error meant we had the wrong value for
3
U-Boot expects PMU_MISC0 register bit 7 is set (see init_bandgap()
8
the PL022_INT_RT constant. This bug doesn't affect device
4
in arch/arm/mach-imx/mx6/soc.c) during boot. This bit indicates the
9
behaviour, because we don't implement the receive timeout
5
bandgap has stabilized.
10
feature and so never set that interrupt bit.
11
6
7
With this change, the latest upstream U-Boot (v2021.01-rc3) for imx6
8
sabrelite board (mx6qsabrelite_defconfig), with a slight change made
9
by switching CONFIG_OF_SEPARATE to CONFIG_OF_EMBED, boots to U-Boot
10
shell on QEMU with the following command:
11
12
$ qemu-system-arm -M sabrelite -smp 4 -m 1G -kernel u-boot \
13
-display none -serial null -serial stdio
14
15
Boot log below:
16
17
U-Boot 2021.01-rc3 (Dec 12 2020 - 17:40:02 +0800)
18
19
CPU: Freescale i.MX?? rev1.0 at 792 MHz
20
Reset cause: POR
21
Model: Freescale i.MX6 Quad SABRE Lite Board
22
Board: SABRE Lite
23
I2C: ready
24
DRAM: 1 GiB
25
force_idle_bus: sda=0 scl=0 sda.gp=0x5c scl.gp=0x55
26
force_idle_bus: failed to clear bus, sda=0 scl=0
27
force_idle_bus: sda=0 scl=0 sda.gp=0x6d scl.gp=0x6c
28
force_idle_bus: failed to clear bus, sda=0 scl=0
29
force_idle_bus: sda=0 scl=0 sda.gp=0xcb scl.gp=0x5
30
force_idle_bus: failed to clear bus, sda=0 scl=0
31
MMC: FSL_SDHC: 0, FSL_SDHC: 1
32
Loading Environment from MMC... *** Warning - No block device, using default environment
33
34
In: serial
35
Out: serial
36
Err: serial
37
Net: Board Net Initialization Failed
38
No ethernet found.
39
starting USB...
40
Bus usb@2184000: usb dr_mode not found
41
USB EHCI 1.00
42
Bus usb@2184200: USB EHCI 1.00
43
scanning bus usb@2184000 for devices... 1 USB Device(s) found
44
scanning bus usb@2184200 for devices... 1 USB Device(s) found
45
scanning usb for storage devices... 0 Storage Device(s) found
46
scanning usb for ethernet devices... 0 Ethernet Device(s) found
47
Hit any key to stop autoboot: 0
48
=>
49
50
Signed-off-by: Bin Meng <bin.meng@windriver.com>
51
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
52
Message-id: 20210106063504.10841-2-bmeng.cn@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
53
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20180820141116.9118-20-peter.maydell@linaro.org
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
---
54
---
16
hw/ssi/pl022.c | 2 +-
55
hw/misc/imx6_ccm.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
56
1 file changed, 1 insertion(+), 1 deletion(-)
18
57
19
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
58
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
20
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/ssi/pl022.c
60
--- a/hw/misc/imx6_ccm.c
22
+++ b/hw/ssi/pl022.c
61
+++ b/hw/misc/imx6_ccm.c
23
@@ -XXX,XX +XXX,XX @@ do { fprintf(stderr, "pl022: error: " fmt , ## __VA_ARGS__);} while (0)
62
@@ -XXX,XX +XXX,XX @@ static void imx6_ccm_reset(DeviceState *dev)
24
#define PL022_SR_BSY 0x10
63
s->analog[PMU_REG_3P0] = 0x00000F74;
25
64
s->analog[PMU_REG_2P5] = 0x00005071;
26
#define PL022_INT_ROR 0x01
65
s->analog[PMU_REG_CORE] = 0x00402010;
27
-#define PL022_INT_RT 0x04
66
- s->analog[PMU_MISC0] = 0x04000000;
28
+#define PL022_INT_RT 0x02
67
+ s->analog[PMU_MISC0] = 0x04000080;
29
#define PL022_INT_RX 0x04
68
s->analog[PMU_MISC1] = 0x00000000;
30
#define PL022_INT_TX 0x08
69
s->analog[PMU_MISC2] = 0x00272727;
31
70
32
--
71
--
33
2.18.0
72
2.20.1
34
73
35
74
diff view generated by jsdifflib
1
Use the DeviceState vmsd pointer rather than calling vmstate_register()
1
From: Bin Meng <bin.meng@windriver.com>
2
directly.
3
2
3
Currently when U-Boot boots, it prints "??" for i.MX processor:
4
5
CPU: Freescale i.MX?? rev1.0 at 792 MHz
6
7
The register that was used to determine the silicon type is
8
undocumented in the latest IMX6DQRM (Rev. 6, 05/2020), but we
9
can refer to get_cpu_rev() in arch/arm/mach-imx/mx6/soc.c in
10
the U-Boot source codes that USB_ANALOG_DIGPROG is used.
11
12
Update its reset value to indicate i.MX6Q.
13
14
Signed-off-by: Bin Meng <bin.meng@windriver.com>
15
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Message-id: 20210106063504.10841-3-bmeng.cn@gmail.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180820141116.9118-18-peter.maydell@linaro.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
18
---
8
hw/ssi/pl022.c | 2 +-
19
hw/misc/imx6_ccm.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
20
1 file changed, 1 insertion(+), 1 deletion(-)
10
21
11
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
22
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
12
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/ssi/pl022.c
24
--- a/hw/misc/imx6_ccm.c
14
+++ b/hw/ssi/pl022.c
25
+++ b/hw/misc/imx6_ccm.c
15
@@ -XXX,XX +XXX,XX @@ static int pl022_init(SysBusDevice *sbd)
26
@@ -XXX,XX +XXX,XX @@ static void imx6_ccm_reset(DeviceState *dev)
16
sysbus_init_mmio(sbd, &s->iomem);
27
s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x00000004;
17
sysbus_init_irq(sbd, &s->irq);
28
s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
18
s->ssi = ssi_create_bus(dev, "ssi");
29
s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
19
- vmstate_register(dev, -1, &vmstate_pl022, s);
30
- s->analog[USB_ANALOG_DIGPROG] = 0x00000000;
20
return 0;
31
+ s->analog[USB_ANALOG_DIGPROG] = 0x00630000;
21
}
32
22
33
/* all PLLs need to be locked */
23
@@ -XXX,XX +XXX,XX @@ static void pl022_class_init(ObjectClass *klass, void *data)
34
s->analog[CCM_ANALOG_PLL_ARM] |= CCM_ANALOG_PLL_LOCK;
24
25
sdc->init = pl022_init;
26
dc->reset = pl022_reset;
27
+ dc->vmsd = &vmstate_pl022;
28
}
29
30
static const TypeInfo pl022_info = {
31
--
35
--
32
2.18.0
36
2.20.1
33
37
34
38
diff view generated by jsdifflib
1
Connect the VIRQ and VFIQ lines from the GIC to the CPU;
1
From: Bin Meng <bin.meng@windriver.com>
2
these exist always for both CPU and GIC whether the
3
virtualization extensions are enabled or not, so we
4
can just unconditionally connect them.
5
2
3
At present, when booting U-Boot on QEMU sabrelite, we see:
4
5
Net: Board Net Initialization Failed
6
No ethernet found.
7
8
U-Boot scans PHY at address 4/5/6/7 (see board_eth_init() in the
9
U-Boot source: board/boundary/nitrogen6x/nitrogen6x.c). On the real
10
board, the Ethernet PHY is at address 6. Adjust this by updating the
11
"fec-phy-num" property of the fsl_imx6 SoC object.
12
13
With this change, U-Boot sees the PHY but complains MAC address:
14
15
Net: using phy at 6
16
FEC [PRIME]
17
Error: FEC address not set.
18
19
This is due to U-Boot tries to read the MAC address from the fuse,
20
which QEMU does not have any valid content filled in. However this
21
does not prevent the Ethernet from working in QEMU. We just need to
22
set up the MAC address later in the U-Boot command shell, by:
23
24
=> setenv ethaddr 00:11:22:33:44:55
25
26
Signed-off-by: Bin Meng <bin.meng@windriver.com>
27
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
28
Message-id: 20210106063504.10841-4-bmeng.cn@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20180821132811.17675-7-peter.maydell@linaro.org
9
---
30
---
10
hw/arm/fsl-imx7.c | 4 ++++
31
hw/arm/sabrelite.c | 4 ++++
11
1 file changed, 4 insertions(+)
32
1 file changed, 4 insertions(+)
12
33
13
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
34
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
14
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/fsl-imx7.c
36
--- a/hw/arm/sabrelite.c
16
+++ b/hw/arm/fsl-imx7.c
37
+++ b/hw/arm/sabrelite.c
17
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
38
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
18
sysbus_connect_irq(sbd, i, irq);
39
19
irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
40
s = FSL_IMX6(object_new(TYPE_FSL_IMX6));
20
sysbus_connect_irq(sbd, i + smp_cpus, irq);
41
object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
21
+ irq = qdev_get_gpio_in(d, ARM_CPU_VIRQ);
42
+
22
+ sysbus_connect_irq(sbd, i + 2 * smp_cpus, irq);
43
+ /* Ethernet PHY address is 6 */
23
+ irq = qdev_get_gpio_in(d, ARM_CPU_VFIQ);
44
+ object_property_set_int(OBJECT(s), "fec-phy-num", 6, &error_fatal);
24
+ sysbus_connect_irq(sbd, i + 3 * smp_cpus, irq);
45
+
25
}
46
qdev_realize(DEVICE(s), NULL, &error_fatal);
26
47
27
/*
48
memory_region_add_subregion(get_system_memory(), FSL_IMX6_MMDC_ADDR,
28
--
49
--
29
2.18.0
50
2.20.1
30
51
31
52
diff view generated by jsdifflib
Deleted patch
1
For the A15MPCore internal peripheral object, we handle GIC
2
security extensions support by checking whether the CPUs
3
have EL3 enabled; if so then we enable it also on the GIC.
4
Handle the virtualization extensions in the same way: if the
5
CPU has EL2 then enable it on the GIC and wire up the
6
virtualization-specific memory regions and the maintenance
7
interrupt.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Message-id: 20180821132811.17675-8-peter.maydell@linaro.org
12
---
13
hw/cpu/a15mpcore.c | 31 ++++++++++++++++++++++++++++---
14
1 file changed, 28 insertions(+), 3 deletions(-)
15
16
diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/cpu/a15mpcore.c
19
+++ b/hw/cpu/a15mpcore.c
20
@@ -XXX,XX +XXX,XX @@ static void a15mp_priv_realize(DeviceState *dev, Error **errp)
21
int i;
22
Error *err = NULL;
23
bool has_el3;
24
+ bool has_el2;
25
Object *cpuobj;
26
27
gicdev = DEVICE(&s->gic);
28
@@ -XXX,XX +XXX,XX @@ static void a15mp_priv_realize(DeviceState *dev, Error **errp)
29
has_el3 = object_property_find(cpuobj, "has_el3", NULL) &&
30
object_property_get_bool(cpuobj, "has_el3", &error_abort);
31
qdev_prop_set_bit(gicdev, "has-security-extensions", has_el3);
32
+ /* Similarly for virtualization support */
33
+ has_el2 = object_property_find(cpuobj, "has_el2", NULL) &&
34
+ object_property_get_bool(cpuobj, "has_el2", &error_abort);
35
+ qdev_prop_set_bit(gicdev, "has-virtualization-extensions", has_el2);
36
}
37
38
object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
39
@@ -XXX,XX +XXX,XX @@ static void a15mp_priv_realize(DeviceState *dev, Error **errp)
40
qdev_get_gpio_in(gicdev,
41
ppibase + timer_irq[irq]));
42
}
43
+ if (has_el2) {
44
+ /* Connect the GIC maintenance interrupt to PPI ID 25 */
45
+ sysbus_connect_irq(SYS_BUS_DEVICE(gicdev), i + 4 * s->num_cpu,
46
+ qdev_get_gpio_in(gicdev, ppibase + 25));
47
+ }
48
}
49
50
/* Memory map (addresses are offsets from PERIPHBASE):
51
* 0x0000-0x0fff -- reserved
52
* 0x1000-0x1fff -- GIC Distributor
53
* 0x2000-0x3fff -- GIC CPU interface
54
- * 0x4000-0x4fff -- GIC virtual interface control (not modelled)
55
- * 0x5000-0x5fff -- GIC virtual interface control (not modelled)
56
- * 0x6000-0x7fff -- GIC virtual CPU interface (not modelled)
57
+ * 0x4000-0x4fff -- GIC virtual interface control for this CPU
58
+ * 0x5000-0x51ff -- GIC virtual interface control for CPU 0
59
+ * 0x5200-0x53ff -- GIC virtual interface control for CPU 1
60
+ * 0x5400-0x55ff -- GIC virtual interface control for CPU 2
61
+ * 0x5600-0x57ff -- GIC virtual interface control for CPU 3
62
+ * 0x6000-0x7fff -- GIC virtual CPU interface
63
*/
64
memory_region_add_subregion(&s->container, 0x1000,
65
sysbus_mmio_get_region(busdev, 0));
66
memory_region_add_subregion(&s->container, 0x2000,
67
sysbus_mmio_get_region(busdev, 1));
68
+ if (has_el2) {
69
+ memory_region_add_subregion(&s->container, 0x4000,
70
+ sysbus_mmio_get_region(busdev, 2));
71
+ memory_region_add_subregion(&s->container, 0x6000,
72
+ sysbus_mmio_get_region(busdev, 3));
73
+ for (i = 0; i < s->num_cpu; i++) {
74
+ hwaddr base = 0x5000 + i * 0x200;
75
+ MemoryRegion *mr = sysbus_mmio_get_region(busdev,
76
+ 4 + s->num_cpu + i);
77
+ memory_region_add_subregion(&s->container, base, mr);
78
+ }
79
+ }
80
}
81
82
static Property a15mp_priv_properties[] = {
83
--
84
2.18.0
85
86
diff view generated by jsdifflib
Deleted patch
1
Don't request that the arm_load_kernel() code should boot in secure
2
state if the CPU doesn't have a secure state. Currently this
3
doesn't make a difference because the boot.c code only examines
4
the secure_boot flag in code guarded by an ARM_FEATURE_EL3 check,
5
but upcoming changes for supporting booting into Hyp mode will
6
change that.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20180821132811.17675-9-peter.maydell@linaro.org
11
---
12
hw/arm/vexpress.c | 4 ++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/vexpress.c
18
+++ b/hw/arm/vexpress.c
19
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
20
daughterboard->bootinfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
21
daughterboard->bootinfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
22
daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb;
23
- /* Indicate that when booting Linux we should be in secure state */
24
- daughterboard->bootinfo.secure_boot = true;
25
+ /* When booting Linux we should be in secure state if the CPU has one. */
26
+ daughterboard->bootinfo.secure_boot = vms->secure;
27
arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo);
28
}
29
30
--
31
2.18.0
32
33
diff view generated by jsdifflib
Deleted patch
1
The v8 AArch32 HACTLR2 register maps to bits [63:32] of ACTLR_EL2.
2
We implement ACTLR_EL2 as RAZ/WI, so make HACTLR2 also RAZ/WI.
3
(We put the regdef next to ACTLR_EL2 as a reminder in case we
4
ever make ACTLR_EL2 something other than RAZ/WI).
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20180820153020.21478-2-peter.maydell@linaro.org
11
---
12
target/arm/helper.c | 10 ++++++++++
13
1 file changed, 10 insertions(+)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
20
REGINFO_SENTINEL
21
};
22
define_arm_cp_regs(cpu, auxcr_reginfo);
23
+ if (arm_feature(env, ARM_FEATURE_V8)) {
24
+ /* HACTLR2 maps to ACTLR_EL2[63:32] and is not in ARMv7 */
25
+ ARMCPRegInfo hactlr2_reginfo = {
26
+ .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
27
+ .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
28
+ .access = PL2_RW, .type = ARM_CP_CONST,
29
+ .resetvalue = 0
30
+ };
31
+ define_one_arm_cp_reg(cpu, &hactlr2_reginfo);
32
+ }
33
}
34
35
if (arm_feature(env, ARM_FEATURE_CBAR)) {
36
--
37
2.18.0
38
39
diff view generated by jsdifflib
Deleted patch
1
The AArch32 HCR and HCR2 registers alias HCR_EL2
2
bits [31:0] and [63:32]; implement them.
3
1
4
Since HCR2 exists in ARMv8 but not ARMv7, we need new
5
regdef arrays for "we have EL3, not EL2, we're ARMv8"
6
and "we have EL2, we're ARMv8" to hold the definitions.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
12
Message-id: 20180820153020.21478-3-peter.maydell@linaro.org
13
---
14
target/arm/helper.c | 54 +++++++++++++++++++++++++++++++++++++++++----
15
1 file changed, 50 insertions(+), 4 deletions(-)
16
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
22
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
23
.access = PL2_RW,
24
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
25
- { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
26
+ { .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH,
27
.type = ARM_CP_NO_RAW,
28
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
29
.access = PL2_RW,
30
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
31
+ .type = ARM_CP_CONST, .resetvalue = 0 },
32
{ .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
33
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
34
.access = PL2_RW,
35
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
36
REGINFO_SENTINEL
37
};
38
39
+/* Ditto, but for registers which exist in ARMv8 but not v7 */
40
+static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
41
+ { .name = "HCR2", .state = ARM_CP_STATE_AA32,
42
+ .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
43
+ .access = PL2_RW,
44
+ .type = ARM_CP_CONST, .resetvalue = 0 },
45
+ REGINFO_SENTINEL
46
+};
47
+
48
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
49
{
50
ARMCPU *cpu = arm_env_get_cpu(env);
51
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
52
* HCR_PTW forbids certain page-table setups
53
* HCR_DC Disables stage1 and enables stage2 translation
54
*/
55
- if ((raw_read(env, ri) ^ value) & (HCR_VM | HCR_PTW | HCR_DC)) {
56
+ if ((env->cp15.hcr_el2 ^ value) & (HCR_VM | HCR_PTW | HCR_DC)) {
57
tlb_flush(CPU(cpu));
58
}
59
- raw_write(env, ri, value);
60
+ env->cp15.hcr_el2 = value;
61
+}
62
+
63
+static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
64
+ uint64_t value)
65
+{
66
+ /* Handle HCR2 write, i.e. write to high half of HCR_EL2 */
67
+ value = deposit64(env->cp15.hcr_el2, 32, 32, value);
68
+ hcr_write(env, NULL, value);
69
+}
70
+
71
+static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
72
+ uint64_t value)
73
+{
74
+ /* Handle HCR write, i.e. write to low half of HCR_EL2 */
75
+ value = deposit64(env->cp15.hcr_el2, 0, 32, value);
76
+ hcr_write(env, NULL, value);
77
}
78
79
static const ARMCPRegInfo el2_cp_reginfo[] = {
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
81
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
82
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
83
.writefn = hcr_write },
84
+ { .name = "HCR", .state = ARM_CP_STATE_AA32,
85
+ .type = ARM_CP_ALIAS,
86
+ .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
87
+ .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
88
+ .writefn = hcr_writelow },
89
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
90
.type = ARM_CP_ALIAS,
91
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
92
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
93
REGINFO_SENTINEL
94
};
95
96
+static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
97
+ { .name = "HCR2", .state = ARM_CP_STATE_AA32,
98
+ .type = ARM_CP_ALIAS,
99
+ .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
100
+ .access = PL2_RW,
101
+ .fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
102
+ .writefn = hcr_writehigh },
103
+ REGINFO_SENTINEL
104
+};
105
+
106
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
107
bool isread)
108
{
109
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
110
};
111
define_arm_cp_regs(cpu, vpidr_regs);
112
define_arm_cp_regs(cpu, el2_cp_reginfo);
113
+ if (arm_feature(env, ARM_FEATURE_V8)) {
114
+ define_arm_cp_regs(cpu, el2_v8_cp_reginfo);
115
+ }
116
/* RVBAR_EL2 is only implemented if EL2 is the highest EL */
117
if (!arm_feature(env, ARM_FEATURE_EL3)) {
118
ARMCPRegInfo rvbar = {
119
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
120
};
121
define_arm_cp_regs(cpu, vpidr_regs);
122
define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
123
+ if (arm_feature(env, ARM_FEATURE_V8)) {
124
+ define_arm_cp_regs(cpu, el3_no_el2_v8_cp_reginfo);
125
+ }
126
}
127
}
128
if (arm_feature(env, ARM_FEATURE_EL3)) {
129
--
130
2.18.0
131
132
diff view generated by jsdifflib
Deleted patch
1
Implement the necessary support code for taking exceptions
2
to Hyp mode in AArch32.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20180820153020.21478-5-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 82 +++++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 82 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
18
env->regs[15] = newpc;
19
}
20
21
+static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
22
+{
23
+ /*
24
+ * Handle exception entry to Hyp mode; this is sufficiently
25
+ * different to entry to other AArch32 modes that we handle it
26
+ * separately here.
27
+ *
28
+ * The vector table entry used is always the 0x14 Hyp mode entry point,
29
+ * unless this is an UNDEF/HVC/abort taken from Hyp to Hyp.
30
+ * The offset applied to the preferred return address is always zero
31
+ * (see DDI0487C.a section G1.12.3).
32
+ * PSTATE A/I/F masks are set based only on the SCR.EA/IRQ/FIQ values.
33
+ */
34
+ uint32_t addr, mask;
35
+ ARMCPU *cpu = ARM_CPU(cs);
36
+ CPUARMState *env = &cpu->env;
37
+
38
+ switch (cs->exception_index) {
39
+ case EXCP_UDEF:
40
+ addr = 0x04;
41
+ break;
42
+ case EXCP_SWI:
43
+ addr = 0x14;
44
+ break;
45
+ case EXCP_BKPT:
46
+ /* Fall through to prefetch abort. */
47
+ case EXCP_PREFETCH_ABORT:
48
+ env->cp15.ifar_s = env->exception.vaddress;
49
+ qemu_log_mask(CPU_LOG_INT, "...with HIFAR 0x%x\n",
50
+ (uint32_t)env->exception.vaddress);
51
+ addr = 0x0c;
52
+ break;
53
+ case EXCP_DATA_ABORT:
54
+ env->cp15.dfar_s = env->exception.vaddress;
55
+ qemu_log_mask(CPU_LOG_INT, "...with HDFAR 0x%x\n",
56
+ (uint32_t)env->exception.vaddress);
57
+ addr = 0x10;
58
+ break;
59
+ case EXCP_IRQ:
60
+ addr = 0x18;
61
+ break;
62
+ case EXCP_FIQ:
63
+ addr = 0x1c;
64
+ break;
65
+ case EXCP_HVC:
66
+ addr = 0x08;
67
+ break;
68
+ case EXCP_HYP_TRAP:
69
+ addr = 0x14;
70
+ default:
71
+ cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
72
+ }
73
+
74
+ if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
75
+ env->cp15.esr_el[2] = env->exception.syndrome;
76
+ }
77
+
78
+ if (arm_current_el(env) != 2 && addr < 0x14) {
79
+ addr = 0x14;
80
+ }
81
+
82
+ mask = 0;
83
+ if (!(env->cp15.scr_el3 & SCR_EA)) {
84
+ mask |= CPSR_A;
85
+ }
86
+ if (!(env->cp15.scr_el3 & SCR_IRQ)) {
87
+ mask |= CPSR_I;
88
+ }
89
+ if (!(env->cp15.scr_el3 & SCR_FIQ)) {
90
+ mask |= CPSR_F;
91
+ }
92
+
93
+ addr += env->cp15.hvbar;
94
+
95
+ take_aarch32_exception(env, ARM_CPU_MODE_HYP, mask, 0, addr);
96
+}
97
+
98
static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
99
{
100
ARMCPU *cpu = ARM_CPU(cs);
101
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
102
env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe);
103
}
104
105
+ if (env->exception.target_el == 2) {
106
+ arm_cpu_do_interrupt_aarch32_hyp(cs);
107
+ return;
108
+ }
109
+
110
/* TODO: Vectored interrupt controller. */
111
switch (cs->exception_index) {
112
case EXCP_UDEF:
113
--
114
2.18.0
115
116
diff view generated by jsdifflib
Deleted patch
1
On 32-bit exception entry, CPSR.J must always be set to 0
2
(see v7A Arm ARM DDI0406C.c B1.8.5). CPSR.IL must also
3
be cleared on 32-bit exception entry (see v8A Arm ARM
4
DDI0487C.a G1.10).
5
1
6
Clear these bits. (This fixes a bug which will never be noticed
7
by non-buggy guests.)
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
13
Message-id: 20180820153020.21478-6-peter.maydell@linaro.org
14
---
15
target/arm/helper.c | 2 ++
16
1 file changed, 2 insertions(+)
17
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
23
if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
24
env->uncached_cpsr |= CPSR_E;
25
}
26
+ /* J and IL must always be cleared for exception entry */
27
+ env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
28
env->daif |= mask;
29
30
if (new_mode == ARM_CPU_MODE_HYP) {
31
--
32
2.18.0
33
34
diff view generated by jsdifflib
Deleted patch
1
The kernel booting specification for an AArch32 kernel requires that
2
it is booted in Hyp mode if available; otherwise the kernel can't
3
enable KVM. We were incorrectly leaving the kernel in SVC mode.
4
If we're booting an AArch32 kernel in the Nonsecure state and Hyp
5
mode is available, start in it.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Message-id: 20180820153020.21478-7-peter.maydell@linaro.org
12
---
13
hw/arm/boot.c | 11 +++++++++++
14
1 file changed, 11 insertions(+)
15
16
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/boot.c
19
+++ b/hw/arm/boot.c
20
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
21
}
22
}
23
24
+ if (!env->aarch64 && !info->secure_boot &&
25
+ arm_feature(env, ARM_FEATURE_EL2)) {
26
+ /*
27
+ * This is an AArch32 boot not to Secure state, and
28
+ * we have Hyp mode available, so boot the kernel into
29
+ * Hyp mode. This is not how the CPU comes out of reset,
30
+ * so we need to manually put it there.
31
+ */
32
+ cpsr_write(env, ARM_CPU_MODE_HYP, CPSR_M, CPSRWriteRaw);
33
+ }
34
+
35
if (cs == first_cpu) {
36
AddressSpace *as = arm_boot_address_space(cpu, info);
37
38
--
39
2.18.0
40
41
diff view generated by jsdifflib
Deleted patch
1
In the MPS2 FPGAIO, PSCNTR is a free-running downcounter with
2
a reload value configured via the PRESCALE register, and
3
COUNTER counts up by 1 every time PSCNTR reaches zero.
4
Implement these counters.
5
1
6
We can just increment the counters migration subsection's
7
version ID because we only added it in the previous commit,
8
so no released QEMU versions will be using it.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20180820141116.9118-3-peter.maydell@linaro.org
14
---
15
include/hw/misc/mps2-fpgaio.h | 6 +++
16
hw/misc/mps2-fpgaio.c | 97 +++++++++++++++++++++++++++++++++--
17
2 files changed, 99 insertions(+), 4 deletions(-)
18
19
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/misc/mps2-fpgaio.h
22
+++ b/include/hw/misc/mps2-fpgaio.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
24
uint32_t prescale;
25
uint32_t misc;
26
27
+ /* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synced */
28
+ int64_t pscntr_sync_ticks;
29
+ /* Values of COUNTER and PSCNTR at time pscntr_sync_ticks */
30
+ uint32_t counter;
31
+ uint32_t pscntr;
32
+
33
uint32_t prescale_clk;
34
35
/* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was zero */
36
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/misc/mps2-fpgaio.c
39
+++ b/hw/misc/mps2-fpgaio.c
40
@@ -XXX,XX +XXX,XX @@ static int64_t tickoff_from_counter(int64_t now, uint32_t count, int frq)
41
return now - muldiv64(count, NANOSECONDS_PER_SECOND, frq);
42
}
43
44
+static void resync_counter(MPS2FPGAIO *s)
45
+{
46
+ /*
47
+ * Update s->counter and s->pscntr to their true current values
48
+ * by calculating how many times PSCNTR has ticked since the
49
+ * last time we did a resync.
50
+ */
51
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
52
+ int64_t elapsed = now - s->pscntr_sync_ticks;
53
+
54
+ /*
55
+ * Round elapsed down to a whole number of PSCNTR ticks, so we don't
56
+ * lose time if we do multiple resyncs in a single tick.
57
+ */
58
+ uint64_t ticks = muldiv64(elapsed, s->prescale_clk, NANOSECONDS_PER_SECOND);
59
+
60
+ /*
61
+ * Work out what PSCNTR and COUNTER have moved to. We assume that
62
+ * PSCNTR reloads from PRESCALE one tick-period after it hits zero,
63
+ * and that COUNTER increments at the same moment.
64
+ */
65
+ if (ticks == 0) {
66
+ /* We haven't ticked since the last time we were asked */
67
+ return;
68
+ } else if (ticks < s->pscntr) {
69
+ /* We haven't yet reached zero, just reduce the PSCNTR */
70
+ s->pscntr -= ticks;
71
+ } else {
72
+ if (s->prescale == 0) {
73
+ /*
74
+ * If the reload value is zero then the PSCNTR will stick
75
+ * at zero once it reaches it, and so we will increment
76
+ * COUNTER every tick after that.
77
+ */
78
+ s->counter += ticks - s->pscntr;
79
+ s->pscntr = 0;
80
+ } else {
81
+ /*
82
+ * This is the complicated bit. This ASCII art diagram gives an
83
+ * example with PRESCALE==5 PSCNTR==7:
84
+ *
85
+ * ticks 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
86
+ * PSCNTR 7 6 5 4 3 2 1 0 5 4 3 2 1 0 5
87
+ * cinc 1 2
88
+ * y 0 1 2 3 4 5 6 7 8 9 10 11 12
89
+ * x 0 1 2 3 4 5 0 1 2 3 4 5 0
90
+ *
91
+ * where x = y % (s->prescale + 1)
92
+ * and so PSCNTR = s->prescale - x
93
+ * and COUNTER is incremented by y / (s->prescale + 1)
94
+ *
95
+ * The case where PSCNTR < PRESCALE works out the same,
96
+ * though we must be careful to calculate y as 64-bit unsigned
97
+ * for all parts of the expression.
98
+ * y < 0 is not possible because that implies ticks < s->pscntr.
99
+ */
100
+ uint64_t y = ticks - s->pscntr + s->prescale;
101
+ s->pscntr = s->prescale - (y % (s->prescale + 1));
102
+ s->counter += y / (s->prescale + 1);
103
+ }
104
+ }
105
+
106
+ /*
107
+ * Only advance the sync time to the timestamp of the last PSCNTR tick,
108
+ * not all the way to 'now', so we don't lose time if we do multiple
109
+ * resyncs in a single tick.
110
+ */
111
+ s->pscntr_sync_ticks += muldiv64(ticks, NANOSECONDS_PER_SECOND,
112
+ s->prescale_clk);
113
+}
114
+
115
static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
116
{
117
MPS2FPGAIO *s = MPS2_FPGAIO(opaque);
118
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
119
r = counter_from_tickoff(now, s->clk100hz_tick_offset, 100);
120
break;
121
case A_COUNTER:
122
+ resync_counter(s);
123
+ r = s->counter;
124
+ break;
125
case A_PSCNTR:
126
- qemu_log_mask(LOG_UNIMP, "MPS2 FPGAIO: counters unimplemented\n");
127
- r = 0;
128
+ resync_counter(s);
129
+ r = s->pscntr;
130
break;
131
default:
132
qemu_log_mask(LOG_GUEST_ERROR,
133
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
134
s->led0 = value & 0x3;
135
break;
136
case A_PRESCALE:
137
+ resync_counter(s);
138
s->prescale = value;
139
break;
140
case A_MISC:
141
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
142
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
143
s->clk100hz_tick_offset = tickoff_from_counter(now, value, 100);
144
break;
145
+ case A_COUNTER:
146
+ resync_counter(s);
147
+ s->counter = value;
148
+ break;
149
+ case A_PSCNTR:
150
+ resync_counter(s);
151
+ s->pscntr = value;
152
+ break;
153
default:
154
qemu_log_mask(LOG_GUEST_ERROR,
155
"MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset);
156
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_reset(DeviceState *dev)
157
s->misc = 0;
158
s->clk1hz_tick_offset = tickoff_from_counter(now, 0, 1);
159
s->clk100hz_tick_offset = tickoff_from_counter(now, 0, 100);
160
+ s->counter = 0;
161
+ s->pscntr = 0;
162
+ s->pscntr_sync_ticks = now;
163
}
164
165
static void mps2_fpgaio_init(Object *obj)
166
@@ -XXX,XX +XXX,XX @@ static bool mps2_fpgaio_counters_needed(void *opaque)
167
168
static const VMStateDescription mps2_fpgaio_counters_vmstate = {
169
.name = "mps2-fpgaio/counters",
170
- .version_id = 1,
171
- .minimum_version_id = 1,
172
+ .version_id = 2,
173
+ .minimum_version_id = 2,
174
.needed = mps2_fpgaio_counters_needed,
175
.fields = (VMStateField[]) {
176
VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO),
177
VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO),
178
+ VMSTATE_UINT32(counter, MPS2FPGAIO),
179
+ VMSTATE_UINT32(pscntr, MPS2FPGAIO),
180
+ VMSTATE_INT64(pscntr_sync_ticks, MPS2FPGAIO),
181
VMSTATE_END_OF_LIST()
182
}
183
};
184
--
185
2.18.0
186
187
diff view generated by jsdifflib
1
The Arm Cortex-M System Design Kit includes a "dual-input timer module"
1
From: Bin Meng <bin.meng@windriver.com>
2
which combines two programmable down-counters. Implement a model
3
of this device.
4
2
3
This adds the target guide for SABRE Lite board, and documents how
4
to boot a Linux kernel and U-Boot bootloader.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20210106063504.10841-5-bmeng.cn@gmail.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180820141116.9118-4-peter.maydell@linaro.org
8
---
10
---
9
hw/timer/Makefile.objs | 1 +
11
docs/system/arm/sabrelite.rst | 119 ++++++++++++++++++++++++++++++++++
10
include/hw/timer/cmsdk-apb-dualtimer.h | 72 ++++
12
docs/system/target-arm.rst | 1 +
11
hw/timer/cmsdk-apb-dualtimer.c | 515 +++++++++++++++++++++++++
13
2 files changed, 120 insertions(+)
12
MAINTAINERS | 2 +
14
create mode 100644 docs/system/arm/sabrelite.rst
13
default-configs/arm-softmmu.mak | 1 +
14
hw/timer/trace-events | 5 +
15
6 files changed, 596 insertions(+)
16
create mode 100644 include/hw/timer/cmsdk-apb-dualtimer.h
17
create mode 100644 hw/timer/cmsdk-apb-dualtimer.c
18
15
19
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
16
diff --git a/docs/system/arm/sabrelite.rst b/docs/system/arm/sabrelite.rst
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/timer/Makefile.objs
22
+++ b/hw/timer/Makefile.objs
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
24
25
common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
26
common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
27
+common-obj-$(CONFIG_CMSDK_APB_DUALTIMER) += cmsdk-apb-dualtimer.o
28
common-obj-$(CONFIG_MSF2) += mss-timer.o
29
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
30
new file mode 100644
17
new file mode 100644
31
index XXXXXXX..XXXXXXX
18
index XXXXXXX..XXXXXXX
32
--- /dev/null
19
--- /dev/null
33
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
20
+++ b/docs/system/arm/sabrelite.rst
34
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
35
+/*
22
+Boundary Devices SABRE Lite (``sabrelite``)
36
+ * ARM CMSDK APB dual-timer emulation
23
+===========================================
37
+ *
38
+ * Copyright (c) 2018 Linaro Limited
39
+ * Written by Peter Maydell
40
+ *
41
+ * This program is free software; you can redistribute it and/or modify
42
+ * it under the terms of the GNU General Public License version 2 or
43
+ * (at your option) any later version.
44
+ */
45
+
24
+
46
+/*
25
+Boundary Devices SABRE Lite i.MX6 Development Board is a low-cost development
47
+ * This is a model of the "APB dual-input timer" which is part of the Cortex-M
26
+platform featuring the powerful Freescale / NXP Semiconductor's i.MX 6 Quad
48
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
27
+Applications Processor.
49
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
50
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
51
+ *
52
+ * QEMU interface:
53
+ * + QOM property "pclk-frq": frequency at which the timer is clocked
54
+ * + sysbus MMIO region 0: the register bank
55
+ * + sysbus IRQ 0: combined timer interrupt TIMINTC
56
+ * + sysbus IRO 1: timer block 1 interrupt TIMINT1
57
+ * + sysbus IRQ 2: timer block 2 interrupt TIMINT2
58
+ */
59
+
28
+
60
+#ifndef CMSDK_APB_DUALTIMER_H
29
+Supported devices
61
+#define CMSDK_APB_DUALTIMER_H
30
+-----------------
62
+
31
+
63
+#include "hw/sysbus.h"
32
+The SABRE Lite machine supports the following devices:
64
+#include "hw/ptimer.h"
65
+
33
+
66
+#define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer"
34
+ * Up to 4 Cortex A9 cores
67
+#define CMSDK_APB_DUALTIMER(obj) OBJECT_CHECK(CMSDKAPBDualTimer, (obj), \
35
+ * Generic Interrupt Controller
68
+ TYPE_CMSDK_APB_DUALTIMER)
36
+ * 1 Clock Controller Module
37
+ * 1 System Reset Controller
38
+ * 5 UARTs
39
+ * 2 EPIC timers
40
+ * 1 GPT timer
41
+ * 2 Watchdog timers
42
+ * 1 FEC Ethernet controller
43
+ * 3 I2C controllers
44
+ * 7 GPIO controllers
45
+ * 4 SDHC storage controllers
46
+ * 4 USB 2.0 host controllers
47
+ * 5 ECSPI controllers
48
+ * 1 SST 25VF016B flash
69
+
49
+
70
+typedef struct CMSDKAPBDualTimer CMSDKAPBDualTimer;
50
+Please note above list is a complete superset the QEMU SABRE Lite machine can
51
+support. For a normal use case, a device tree blob that represents a real world
52
+SABRE Lite board, only exposes a subset of devices to the guest software.
71
+
53
+
72
+/* One of the two identical timer modules in the dual-timer module */
54
+Boot options
73
+typedef struct CMSDKAPBDualTimerModule {
55
+------------
74
+ CMSDKAPBDualTimer *parent;
75
+ struct ptimer_state *timer;
76
+ qemu_irq timerint;
77
+ /*
78
+ * We must track the guest LOAD and VALUE register state by hand
79
+ * rather than leaving this state only in the ptimer limit/count,
80
+ * because if CONTROL.SIZE is 0 then only the low 16 bits of the
81
+ * counter actually counts, but the high half is still guest
82
+ * accessible.
83
+ */
84
+ uint32_t load;
85
+ uint32_t value;
86
+ uint32_t control;
87
+ uint32_t intstatus;
88
+} CMSDKAPBDualTimerModule;
89
+
56
+
90
+#define CMSDK_APB_DUALTIMER_NUM_MODULES 2
57
+The SABRE Lite machine can start using the standard -kernel functionality
58
+for loading a Linux kernel, U-Boot bootloader or ELF executable.
91
+
59
+
92
+struct CMSDKAPBDualTimer {
60
+Running Linux kernel
93
+ /*< private >*/
61
+--------------------
94
+ SysBusDevice parent_obj;
95
+
62
+
96
+ /*< public >*/
63
+Linux mainline v5.10 release is tested at the time of writing. To build a Linux
97
+ MemoryRegion iomem;
64
+mainline kernel that can be booted by the SABRE Lite machine, simply configure
98
+ qemu_irq timerintc;
65
+the kernel using the imx_v6_v7_defconfig configuration:
99
+ uint32_t pclk_frq;
100
+
66
+
101
+ CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES];
67
+.. code-block:: bash
102
+ uint32_t timeritcr;
103
+ uint32_t timeritop;
104
+};
105
+
68
+
106
+#endif
69
+ $ export ARCH=arm
107
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
70
+ $ export CROSS_COMPILE=arm-linux-gnueabihf-
108
new file mode 100644
71
+ $ make imx_v6_v7_defconfig
109
index XXXXXXX..XXXXXXX
72
+ $ make
110
--- /dev/null
111
+++ b/hw/timer/cmsdk-apb-dualtimer.c
112
@@ -XXX,XX +XXX,XX @@
113
+/*
114
+ * ARM CMSDK APB dual-timer emulation
115
+ *
116
+ * Copyright (c) 2018 Linaro Limited
117
+ * Written by Peter Maydell
118
+ *
119
+ * This program is free software; you can redistribute it and/or modify
120
+ * it under the terms of the GNU General Public License version 2 or
121
+ * (at your option) any later version.
122
+ */
123
+
73
+
124
+/*
74
+To boot the newly built Linux kernel in QEMU with the SABRE Lite machine, use:
125
+ * This is a model of the "APB dual-input timer" which is part of the Cortex-M
126
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
127
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
128
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
129
+ */
130
+
75
+
131
+#include "qemu/osdep.h"
76
+.. code-block:: bash
132
+#include "qemu/log.h"
133
+#include "trace.h"
134
+#include "qapi/error.h"
135
+#include "qemu/main-loop.h"
136
+#include "hw/sysbus.h"
137
+#include "hw/registerfields.h"
138
+#include "hw/timer/cmsdk-apb-dualtimer.h"
139
+
77
+
140
+REG32(TIMER1LOAD, 0x0)
78
+ $ qemu-system-arm -M sabrelite -smp 4 -m 1G \
141
+REG32(TIMER1VALUE, 0x4)
79
+ -display none -serial null -serial stdio \
142
+REG32(TIMER1CONTROL, 0x8)
80
+ -kernel arch/arm/boot/zImage \
143
+ FIELD(CONTROL, ONESHOT, 0, 1)
81
+ -dtb arch/arm/boot/dts/imx6q-sabrelite.dtb \
144
+ FIELD(CONTROL, SIZE, 1, 1)
82
+ -initrd /path/to/rootfs.ext4 \
145
+ FIELD(CONTROL, PRESCALE, 2, 2)
83
+ -append "root=/dev/ram"
146
+ FIELD(CONTROL, INTEN, 5, 1)
147
+ FIELD(CONTROL, MODE, 6, 1)
148
+ FIELD(CONTROL, ENABLE, 7, 1)
149
+#define R_CONTROL_VALID_MASK (R_CONTROL_ONESHOT_MASK | R_CONTROL_SIZE_MASK | \
150
+ R_CONTROL_PRESCALE_MASK | R_CONTROL_INTEN_MASK | \
151
+ R_CONTROL_MODE_MASK | R_CONTROL_ENABLE_MASK)
152
+REG32(TIMER1INTCLR, 0xc)
153
+REG32(TIMER1RIS, 0x10)
154
+REG32(TIMER1MIS, 0x14)
155
+REG32(TIMER1BGLOAD, 0x18)
156
+REG32(TIMER2LOAD, 0x20)
157
+REG32(TIMER2VALUE, 0x24)
158
+REG32(TIMER2CONTROL, 0x28)
159
+REG32(TIMER2INTCLR, 0x2c)
160
+REG32(TIMER2RIS, 0x30)
161
+REG32(TIMER2MIS, 0x34)
162
+REG32(TIMER2BGLOAD, 0x38)
163
+REG32(TIMERITCR, 0xf00)
164
+ FIELD(TIMERITCR, ENABLE, 0, 1)
165
+#define R_TIMERITCR_VALID_MASK R_TIMERITCR_ENABLE_MASK
166
+REG32(TIMERITOP, 0xf04)
167
+ FIELD(TIMERITOP, TIMINT1, 0, 1)
168
+ FIELD(TIMERITOP, TIMINT2, 1, 1)
169
+#define R_TIMERITOP_VALID_MASK (R_TIMERITOP_TIMINT1_MASK | \
170
+ R_TIMERITOP_TIMINT2_MASK)
171
+REG32(PID4, 0xfd0)
172
+REG32(PID5, 0xfd4)
173
+REG32(PID6, 0xfd8)
174
+REG32(PID7, 0xfdc)
175
+REG32(PID0, 0xfe0)
176
+REG32(PID1, 0xfe4)
177
+REG32(PID2, 0xfe8)
178
+REG32(PID3, 0xfec)
179
+REG32(CID0, 0xff0)
180
+REG32(CID1, 0xff4)
181
+REG32(CID2, 0xff8)
182
+REG32(CID3, 0xffc)
183
+
84
+
184
+/* PID/CID values */
85
+Running U-Boot
185
+static const int timer_id[] = {
86
+--------------
186
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
187
+ 0x23, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
188
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
189
+};
190
+
87
+
191
+static bool cmsdk_dualtimermod_intstatus(CMSDKAPBDualTimerModule *m)
88
+U-Boot mainline v2020.10 release is tested at the time of writing. To build a
192
+{
89
+U-Boot mainline bootloader that can be booted by the SABRE Lite machine, use
193
+ /* Return masked interrupt status for the timer module */
90
+the mx6qsabrelite_defconfig with similar commands as described above for Linux:
194
+ return m->intstatus && (m->control & R_CONTROL_INTEN_MASK);
195
+}
196
+
91
+
197
+static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s)
92
+.. code-block:: bash
198
+{
199
+ bool timint1, timint2, timintc;
200
+
93
+
201
+ if (s->timeritcr) {
94
+ $ export CROSS_COMPILE=arm-linux-gnueabihf-
202
+ /* Integration test mode: outputs driven directly from TIMERITOP bits */
95
+ $ make mx6qsabrelite_defconfig
203
+ timint1 = s->timeritop & R_TIMERITOP_TIMINT1_MASK;
204
+ timint2 = s->timeritop & R_TIMERITOP_TIMINT2_MASK;
205
+ } else {
206
+ timint1 = cmsdk_dualtimermod_intstatus(&s->timermod[0]);
207
+ timint2 = cmsdk_dualtimermod_intstatus(&s->timermod[1]);
208
+ }
209
+
96
+
210
+ timintc = timint1 || timint2;
97
+Note we need to adjust settings by:
211
+
98
+
212
+ qemu_set_irq(s->timermod[0].timerint, timint1);
99
+.. code-block:: bash
213
+ qemu_set_irq(s->timermod[1].timerint, timint2);
214
+ qemu_set_irq(s->timerintc, timintc);
215
+}
216
+
100
+
217
+static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
101
+ $ make menuconfig
218
+ uint32_t newctrl)
219
+{
220
+ /* Handle a write to the CONTROL register */
221
+ uint32_t changed;
222
+
102
+
223
+ newctrl &= R_CONTROL_VALID_MASK;
103
+then manually select the following configuration in U-Boot:
224
+
104
+
225
+ changed = m->control ^ newctrl;
105
+ Device Tree Control > Provider of DTB for DT Control > Embedded DTB
226
+
106
+
227
+ if (changed & ~newctrl & R_CONTROL_ENABLE_MASK) {
107
+To start U-Boot using the SABRE Lite machine, provide the u-boot binary to
228
+ /* ENABLE cleared, stop timer before any further changes */
108
+the -kernel argument, along with an SD card image with rootfs:
229
+ ptimer_stop(m->timer);
230
+ }
231
+
109
+
232
+ if (changed & R_CONTROL_PRESCALE_MASK) {
110
+.. code-block:: bash
233
+ int divisor;
234
+
111
+
235
+ switch (FIELD_EX32(newctrl, CONTROL, PRESCALE)) {
112
+ $ qemu-system-arm -M sabrelite -smp 4 -m 1G \
236
+ case 0:
113
+ -display none -serial null -serial stdio \
237
+ divisor = 1;
114
+ -kernel u-boot
238
+ break;
239
+ case 1:
240
+ divisor = 16;
241
+ break;
242
+ case 2:
243
+ divisor = 256;
244
+ break;
245
+ case 3:
246
+ /* UNDEFINED; complain, and arbitrarily treat like 2 */
247
+ qemu_log_mask(LOG_GUEST_ERROR,
248
+ "CMSDK APB dual-timer: CONTROL.PRESCALE==0b11"
249
+ " is undefined behaviour\n");
250
+ divisor = 256;
251
+ break;
252
+ default:
253
+ g_assert_not_reached();
254
+ }
255
+ ptimer_set_freq(m->timer, m->parent->pclk_frq / divisor);
256
+ }
257
+
115
+
258
+ if (changed & R_CONTROL_MODE_MASK) {
116
+The following example shows booting Linux kernel from dhcp, and uses the
259
+ uint32_t load;
117
+rootfs on an SD card. This requires some additional command line parameters
260
+ if (newctrl & R_CONTROL_MODE_MASK) {
118
+for QEMU:
261
+ /* Periodic: the limit is the LOAD register value */
262
+ load = m->load;
263
+ } else {
264
+ /* Free-running: counter wraps around */
265
+ load = ptimer_get_limit(m->timer);
266
+ if (!(m->control & R_CONTROL_SIZE_MASK)) {
267
+ load = deposit32(m->load, 0, 16, load);
268
+ }
269
+ m->load = load;
270
+ load = 0xffffffff;
271
+ }
272
+ if (!(m->control & R_CONTROL_SIZE_MASK)) {
273
+ load &= 0xffff;
274
+ }
275
+ ptimer_set_limit(m->timer, load, 0);
276
+ }
277
+
119
+
278
+ if (changed & R_CONTROL_SIZE_MASK) {
120
+.. code-block:: none
279
+ /* Timer switched between 16 and 32 bit count */
280
+ uint32_t value, load;
281
+
121
+
282
+ value = ptimer_get_count(m->timer);
122
+ -nic user,tftp=/path/to/kernel/zImage \
283
+ load = ptimer_get_limit(m->timer);
123
+ -drive file=sdcard.img,id=rootfs -device sd-card,drive=rootfs
284
+ if (newctrl & R_CONTROL_SIZE_MASK) {
285
+ /* 16 -> 32, top half of VALUE is in struct field */
286
+ value = deposit32(m->value, 0, 16, value);
287
+ } else {
288
+ /* 32 -> 16: save top half to struct field and truncate */
289
+ m->value = value;
290
+ value &= 0xffff;
291
+ }
292
+
124
+
293
+ if (newctrl & R_CONTROL_MODE_MASK) {
125
+The directory for the built-in TFTP server should also contain the device tree
294
+ /* Periodic, timer limit has LOAD value */
126
+blob of the SABRE Lite board. The sample SD card image was populated with the
295
+ if (newctrl & R_CONTROL_SIZE_MASK) {
127
+root file system with one single partition. You may adjust the kernel "root="
296
+ load = deposit32(m->load, 0, 16, load);
128
+boot parameter accordingly.
297
+ } else {
298
+ m->load = load;
299
+ load &= 0xffff;
300
+ }
301
+ } else {
302
+ /* Free-running, timer limit is set to give wraparound */
303
+ if (newctrl & R_CONTROL_SIZE_MASK) {
304
+ load = 0xffffffff;
305
+ } else {
306
+ load = 0xffff;
307
+ }
308
+ }
309
+ ptimer_set_count(m->timer, value);
310
+ ptimer_set_limit(m->timer, load, 0);
311
+ }
312
+
129
+
313
+ if (newctrl & R_CONTROL_ENABLE_MASK) {
130
+After U-Boot boots, type the following commands in the U-Boot command shell to
314
+ /*
131
+boot the Linux kernel:
315
+ * ENABLE is set; start the timer after all other changes.
316
+ * We start it even if the ENABLE bit didn't actually change,
317
+ * in case the timer was an expired one-shot timer that has
318
+ * now been changed into a free-running or periodic timer.
319
+ */
320
+ ptimer_run(m->timer, !!(newctrl & R_CONTROL_ONESHOT_MASK));
321
+ }
322
+
132
+
323
+ m->control = newctrl;
133
+.. code-block:: none
324
+}
325
+
134
+
326
+static uint64_t cmsdk_apb_dualtimer_read(void *opaque, hwaddr offset,
135
+ => setenv ethaddr 00:11:22:33:44:55
327
+ unsigned size)
136
+ => setenv bootfile zImage
328
+{
137
+ => dhcp
329
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
138
+ => tftpboot 14000000 imx6q-sabrelite.dtb
330
+ uint64_t r;
139
+ => setenv bootargs root=/dev/mmcblk3p1
331
+
140
+ => bootz 12000000 - 14000000
332
+ if (offset >= A_TIMERITCR) {
141
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
333
+ switch (offset) {
334
+ case A_TIMERITCR:
335
+ r = s->timeritcr;
336
+ break;
337
+ case A_PID4 ... A_CID3:
338
+ r = timer_id[(offset - A_PID4) / 4];
339
+ break;
340
+ default:
341
+ bad_offset:
342
+ qemu_log_mask(LOG_GUEST_ERROR,
343
+ "CMSDK APB dual-timer read: bad offset %x\n",
344
+ (int) offset);
345
+ r = 0;
346
+ break;
347
+ }
348
+ } else {
349
+ int timer = offset >> 5;
350
+ CMSDKAPBDualTimerModule *m;
351
+
352
+ if (timer >= ARRAY_SIZE(s->timermod)) {
353
+ goto bad_offset;
354
+ }
355
+
356
+ m = &s->timermod[timer];
357
+
358
+ switch (offset & 0x1F) {
359
+ case A_TIMER1LOAD:
360
+ case A_TIMER1BGLOAD:
361
+ if (m->control & R_CONTROL_MODE_MASK) {
362
+ /*
363
+ * Periodic: the ptimer limit is the LOAD register value, (or
364
+ * just the low 16 bits of it if the timer is in 16-bit mode)
365
+ */
366
+ r = ptimer_get_limit(m->timer);
367
+ if (!(m->control & R_CONTROL_SIZE_MASK)) {
368
+ r = deposit32(m->load, 0, 16, r);
369
+ }
370
+ } else {
371
+ /* Free-running: LOAD register value is just in m->load */
372
+ r = m->load;
373
+ }
374
+ break;
375
+ case A_TIMER1VALUE:
376
+ r = ptimer_get_count(m->timer);
377
+ if (!(m->control & R_CONTROL_SIZE_MASK)) {
378
+ r = deposit32(m->value, 0, 16, r);
379
+ }
380
+ break;
381
+ case A_TIMER1CONTROL:
382
+ r = m->control;
383
+ break;
384
+ case A_TIMER1RIS:
385
+ r = m->intstatus;
386
+ break;
387
+ case A_TIMER1MIS:
388
+ r = cmsdk_dualtimermod_intstatus(m);
389
+ break;
390
+ default:
391
+ goto bad_offset;
392
+ }
393
+ }
394
+
395
+ trace_cmsdk_apb_dualtimer_read(offset, r, size);
396
+ return r;
397
+}
398
+
399
+static void cmsdk_apb_dualtimer_write(void *opaque, hwaddr offset,
400
+ uint64_t value, unsigned size)
401
+{
402
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
403
+
404
+ trace_cmsdk_apb_dualtimer_write(offset, value, size);
405
+
406
+ if (offset >= A_TIMERITCR) {
407
+ switch (offset) {
408
+ case A_TIMERITCR:
409
+ s->timeritcr = value & R_TIMERITCR_VALID_MASK;
410
+ cmsdk_apb_dualtimer_update(s);
411
+ case A_TIMERITOP:
412
+ s->timeritop = value & R_TIMERITOP_VALID_MASK;
413
+ cmsdk_apb_dualtimer_update(s);
414
+ default:
415
+ bad_offset:
416
+ qemu_log_mask(LOG_GUEST_ERROR,
417
+ "CMSDK APB dual-timer write: bad offset %x\n",
418
+ (int) offset);
419
+ break;
420
+ }
421
+ } else {
422
+ int timer = offset >> 5;
423
+ CMSDKAPBDualTimerModule *m;
424
+
425
+ if (timer >= ARRAY_SIZE(s->timermod)) {
426
+ goto bad_offset;
427
+ }
428
+
429
+ m = &s->timermod[timer];
430
+
431
+ switch (offset & 0x1F) {
432
+ case A_TIMER1LOAD:
433
+ /* Set the limit, and immediately reload the count from it */
434
+ m->load = value;
435
+ m->value = value;
436
+ if (!(m->control & R_CONTROL_SIZE_MASK)) {
437
+ value &= 0xffff;
438
+ }
439
+ if (!(m->control & R_CONTROL_MODE_MASK)) {
440
+ /*
441
+ * In free-running mode this won't set the limit but will
442
+ * still change the current count value.
443
+ */
444
+ ptimer_set_count(m->timer, value);
445
+ } else {
446
+ if (!value) {
447
+ ptimer_stop(m->timer);
448
+ }
449
+ ptimer_set_limit(m->timer, value, 1);
450
+ if (value && (m->control & R_CONTROL_ENABLE_MASK)) {
451
+ /* Force possibly-expired oneshot timer to restart */
452
+ ptimer_run(m->timer, 1);
453
+ }
454
+ }
455
+ break;
456
+ case A_TIMER1BGLOAD:
457
+ /* Set the limit, but not the current count */
458
+ m->load = value;
459
+ if (!(m->control & R_CONTROL_MODE_MASK)) {
460
+ /* In free-running mode there is no limit */
461
+ break;
462
+ }
463
+ if (!(m->control & R_CONTROL_SIZE_MASK)) {
464
+ value &= 0xffff;
465
+ }
466
+ ptimer_set_limit(m->timer, value, 0);
467
+ break;
468
+ case A_TIMER1CONTROL:
469
+ cmsdk_dualtimermod_write_control(m, value);
470
+ cmsdk_apb_dualtimer_update(s);
471
+ break;
472
+ case A_TIMER1INTCLR:
473
+ m->intstatus = 0;
474
+ cmsdk_apb_dualtimer_update(s);
475
+ break;
476
+ default:
477
+ goto bad_offset;
478
+ }
479
+ }
480
+}
481
+
482
+static const MemoryRegionOps cmsdk_apb_dualtimer_ops = {
483
+ .read = cmsdk_apb_dualtimer_read,
484
+ .write = cmsdk_apb_dualtimer_write,
485
+ .endianness = DEVICE_LITTLE_ENDIAN,
486
+ /* byte/halfword accesses are just zero-padded on reads and writes */
487
+ .impl.min_access_size = 4,
488
+ .impl.max_access_size = 4,
489
+ .valid.min_access_size = 1,
490
+ .valid.max_access_size = 4,
491
+};
492
+
493
+static void cmsdk_dualtimermod_tick(void *opaque)
494
+{
495
+ CMSDKAPBDualTimerModule *m = opaque;
496
+
497
+ m->intstatus = 1;
498
+ cmsdk_apb_dualtimer_update(m->parent);
499
+}
500
+
501
+static void cmsdk_dualtimermod_reset(CMSDKAPBDualTimerModule *m)
502
+{
503
+ m->control = R_CONTROL_INTEN_MASK;
504
+ m->intstatus = 0;
505
+ m->load = 0;
506
+ m->value = 0xffffffff;
507
+ ptimer_stop(m->timer);
508
+ /*
509
+ * We start in free-running mode, with VALUE at 0xffffffff, and
510
+ * in 16-bit counter mode. This means that the ptimer count and
511
+ * limit must both be set to 0xffff, so we wrap at 16 bits.
512
+ */
513
+ ptimer_set_limit(m->timer, 0xffff, 1);
514
+ ptimer_set_freq(m->timer, m->parent->pclk_frq);
515
+}
516
+
517
+static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
518
+{
519
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev);
520
+ int i;
521
+
522
+ trace_cmsdk_apb_dualtimer_reset();
523
+
524
+ for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
525
+ cmsdk_dualtimermod_reset(&s->timermod[i]);
526
+ }
527
+ s->timeritcr = 0;
528
+ s->timeritop = 0;
529
+}
530
+
531
+static void cmsdk_apb_dualtimer_init(Object *obj)
532
+{
533
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
534
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(obj);
535
+ int i;
536
+
537
+ memory_region_init_io(&s->iomem, obj, &cmsdk_apb_dualtimer_ops,
538
+ s, "cmsdk-apb-dualtimer", 0x1000);
539
+ sysbus_init_mmio(sbd, &s->iomem);
540
+ sysbus_init_irq(sbd, &s->timerintc);
541
+
542
+ for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
543
+ sysbus_init_irq(sbd, &s->timermod[i].timerint);
544
+ }
545
+}
546
+
547
+static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
548
+{
549
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev);
550
+ int i;
551
+
552
+ if (s->pclk_frq == 0) {
553
+ error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
554
+ return;
555
+ }
556
+
557
+ for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
558
+ CMSDKAPBDualTimerModule *m = &s->timermod[i];
559
+ QEMUBH *bh = qemu_bh_new(cmsdk_dualtimermod_tick, m);
560
+
561
+ m->parent = s;
562
+ m->timer = ptimer_init(bh,
563
+ PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
564
+ PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
565
+ PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
566
+ PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
567
+ }
568
+}
569
+
570
+static const VMStateDescription cmsdk_dualtimermod_vmstate = {
571
+ .name = "cmsdk-apb-dualtimer-module",
572
+ .version_id = 1,
573
+ .minimum_version_id = 1,
574
+ .fields = (VMStateField[]) {
575
+ VMSTATE_PTIMER(timer, CMSDKAPBDualTimerModule),
576
+ VMSTATE_UINT32(load, CMSDKAPBDualTimerModule),
577
+ VMSTATE_UINT32(value, CMSDKAPBDualTimerModule),
578
+ VMSTATE_UINT32(control, CMSDKAPBDualTimerModule),
579
+ VMSTATE_UINT32(intstatus, CMSDKAPBDualTimerModule),
580
+ VMSTATE_END_OF_LIST()
581
+ }
582
+};
583
+
584
+static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
585
+ .name = "cmsdk-apb-dualtimer",
586
+ .version_id = 1,
587
+ .minimum_version_id = 1,
588
+ .fields = (VMStateField[]) {
589
+ VMSTATE_STRUCT_ARRAY(timermod, CMSDKAPBDualTimer,
590
+ CMSDK_APB_DUALTIMER_NUM_MODULES,
591
+ 1, cmsdk_dualtimermod_vmstate,
592
+ CMSDKAPBDualTimerModule),
593
+ VMSTATE_UINT32(timeritcr, CMSDKAPBDualTimer),
594
+ VMSTATE_UINT32(timeritop, CMSDKAPBDualTimer),
595
+ VMSTATE_END_OF_LIST()
596
+ }
597
+};
598
+
599
+static Property cmsdk_apb_dualtimer_properties[] = {
600
+ DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBDualTimer, pclk_frq, 0),
601
+ DEFINE_PROP_END_OF_LIST(),
602
+};
603
+
604
+static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
605
+{
606
+ DeviceClass *dc = DEVICE_CLASS(klass);
607
+
608
+ dc->realize = cmsdk_apb_dualtimer_realize;
609
+ dc->vmsd = &cmsdk_apb_dualtimer_vmstate;
610
+ dc->reset = cmsdk_apb_dualtimer_reset;
611
+ dc->props = cmsdk_apb_dualtimer_properties;
612
+}
613
+
614
+static const TypeInfo cmsdk_apb_dualtimer_info = {
615
+ .name = TYPE_CMSDK_APB_DUALTIMER,
616
+ .parent = TYPE_SYS_BUS_DEVICE,
617
+ .instance_size = sizeof(CMSDKAPBDualTimer),
618
+ .instance_init = cmsdk_apb_dualtimer_init,
619
+ .class_init = cmsdk_apb_dualtimer_class_init,
620
+};
621
+
622
+static void cmsdk_apb_dualtimer_register_types(void)
623
+{
624
+ type_register_static(&cmsdk_apb_dualtimer_info);
625
+}
626
+
627
+type_init(cmsdk_apb_dualtimer_register_types);
628
diff --git a/MAINTAINERS b/MAINTAINERS
629
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
630
--- a/MAINTAINERS
143
--- a/docs/system/target-arm.rst
631
+++ b/MAINTAINERS
144
+++ b/docs/system/target-arm.rst
632
@@ -XXX,XX +XXX,XX @@ F: hw/timer/pl031.c
145
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
633
F: include/hw/arm/primecell.h
146
arm/versatile
634
F: hw/timer/cmsdk-apb-timer.c
147
arm/vexpress
635
F: include/hw/timer/cmsdk-apb-timer.h
148
arm/aspeed
636
+F: hw/timer/cmsdk-apb-dualtimer.c
149
+ arm/sabrelite
637
+F: include/hw/timer/cmsdk-apb-dualtimer.h
150
arm/digic
638
F: hw/char/cmsdk-apb-uart.c
151
arm/musicpal
639
F: include/hw/char/cmsdk-apb-uart.h
152
arm/gumstix
640
F: hw/watchdog/cmsdk-apb-watchdog.c
641
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
642
index XXXXXXX..XXXXXXX 100644
643
--- a/default-configs/arm-softmmu.mak
644
+++ b/default-configs/arm-softmmu.mak
645
@@ -XXX,XX +XXX,XX @@ CONFIG_STM32F2XX_SPI=y
646
CONFIG_STM32F205_SOC=y
647
648
CONFIG_CMSDK_APB_TIMER=y
649
+CONFIG_CMSDK_APB_DUALTIMER=y
650
CONFIG_CMSDK_APB_UART=y
651
CONFIG_CMSDK_APB_WATCHDOG=y
652
653
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
654
index XXXXXXX..XXXXXXX 100644
655
--- a/hw/timer/trace-events
656
+++ b/hw/timer/trace-events
657
@@ -XXX,XX +XXX,XX @@ cmsdk_apb_timer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB t
658
cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
659
cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset"
660
661
+# hw/timer/cmsdk_apb_dualtimer.c
662
+cmsdk_apb_dualtimer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
663
+cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
664
+cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset"
665
+
666
# hw/timer/xlnx-zynqmp-rtc.c
667
xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d"
668
--
153
--
669
2.18.0
154
2.20.1
670
155
671
156
diff view generated by jsdifflib
Deleted patch
1
Now we have a model of the CMSDK dual timer, we can wire it
2
up in the IoTKit.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180820141116.9118-5-peter.maydell@linaro.org
8
---
9
include/hw/arm/iotkit.h | 3 ++-
10
hw/arm/iotkit.c | 8 +++++---
11
2 files changed, 7 insertions(+), 4 deletions(-)
12
13
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/iotkit.h
16
+++ b/include/hw/arm/iotkit.h
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/misc/tz-ppc.h"
19
#include "hw/misc/tz-mpc.h"
20
#include "hw/timer/cmsdk-apb-timer.h"
21
+#include "hw/timer/cmsdk-apb-dualtimer.h"
22
#include "hw/misc/unimp.h"
23
#include "hw/or-irq.h"
24
#include "hw/core/split-irq.h"
25
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
26
SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
27
qemu_or_irq mpc_irq_orgate;
28
29
- UnimplementedDeviceState dualtimer;
30
+ CMSDKAPBDualTimer dualtimer;
31
UnimplementedDeviceState s32ktimer;
32
33
MemoryRegion container;
34
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/iotkit.c
37
+++ b/hw/arm/iotkit.c
38
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
39
sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
40
TYPE_CMSDK_APB_TIMER);
41
sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
42
- TYPE_UNIMPLEMENTED_DEVICE);
43
+ TYPE_CMSDK_APB_DUALTIMER);
44
object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
45
sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
46
&error_abort, NULL);
47
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
48
return;
49
}
50
51
- qdev_prop_set_string(DEVICE(&s->dualtimer), "name", "Dual timer");
52
- qdev_prop_set_uint64(DEVICE(&s->dualtimer), "size", 0x1000);
53
+
54
+ qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
55
object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
56
if (err) {
57
error_propagate(errp, err);
58
return;
59
}
60
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
61
+ qdev_get_gpio_in(DEVICE(&s->armv7m), 5));
62
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
63
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
64
if (err) {
65
--
66
2.18.0
67
68
diff view generated by jsdifflib
Deleted patch
1
The MPS2 FPGA images for the Cortex-M3 (mps2-an385 and mps2-511)
2
both include a CMSDK dual-timer module. Wire this up.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180820141116.9118-6-peter.maydell@linaro.org
8
---
9
hw/arm/mps2.c | 11 +++++++++++
10
1 file changed, 11 insertions(+)
11
12
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2.c
15
+++ b/hw/arm/mps2.c
16
@@ -XXX,XX +XXX,XX @@
17
#include "hw/misc/unimp.h"
18
#include "hw/char/cmsdk-apb-uart.h"
19
#include "hw/timer/cmsdk-apb-timer.h"
20
+#include "hw/timer/cmsdk-apb-dualtimer.h"
21
#include "hw/misc/mps2-scc.h"
22
#include "hw/devices.h"
23
#include "net/net.h"
24
@@ -XXX,XX +XXX,XX @@ typedef struct {
25
MemoryRegion blockram_m3;
26
MemoryRegion sram;
27
MPS2SCC scc;
28
+ CMSDKAPBDualTimer dualtimer;
29
} MPS2MachineState;
30
31
#define TYPE_MPS2_MACHINE "mps2"
32
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
33
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
34
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
35
36
+ sysbus_init_child_obj(OBJECT(mms), "dualtimer", &mms->dualtimer,
37
+ sizeof(mms->dualtimer), TYPE_CMSDK_APB_DUALTIMER);
38
+ qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
39
+ object_property_set_bool(OBJECT(&mms->dualtimer), true, "realized",
40
+ &error_fatal);
41
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
42
+ qdev_get_gpio_in(armv7m, 10));
43
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
44
+
45
object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC);
46
sccdev = DEVICE(&mms->scc);
47
qdev_set_parent_bus(sccdev, sysbus_get_default());
48
--
49
2.18.0
50
51
diff view generated by jsdifflib
Deleted patch
1
The IoTKit includes three different instances of the
2
CMSDK APB watchdog; create and wire them up.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180820141116.9118-7-peter.maydell@linaro.org
8
---
9
include/hw/arm/iotkit.h | 6 +++++
10
hw/arm/iotkit.c | 58 ++++++++++++++++++++++++++++++++++++++---
11
2 files changed, 61 insertions(+), 3 deletions(-)
12
13
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/iotkit.h
16
+++ b/include/hw/arm/iotkit.h
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/misc/tz-mpc.h"
19
#include "hw/timer/cmsdk-apb-timer.h"
20
#include "hw/timer/cmsdk-apb-dualtimer.h"
21
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
22
#include "hw/misc/unimp.h"
23
#include "hw/or-irq.h"
24
#include "hw/core/split-irq.h"
25
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
26
SplitIRQ ppc_irq_splitter[NUM_PPCS];
27
SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
28
qemu_or_irq mpc_irq_orgate;
29
+ qemu_or_irq nmi_orgate;
30
31
CMSDKAPBDualTimer dualtimer;
32
UnimplementedDeviceState s32ktimer;
33
34
+ CMSDKAPBWatchdog s32kwatchdog;
35
+ CMSDKAPBWatchdog nswatchdog;
36
+ CMSDKAPBWatchdog swatchdog;
37
+
38
MemoryRegion container;
39
MemoryRegion alias1;
40
MemoryRegion alias2;
41
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/iotkit.c
44
+++ b/hw/arm/iotkit.c
45
@@ -XXX,XX +XXX,XX @@
46
#include "hw/misc/unimp.h"
47
#include "hw/arm/arm.h"
48
49
+/* Clock frequency in HZ of the 32KHz "slow clock" */
50
+#define S32KCLK (32 * 1000)
51
+
52
/* Create an alias region of @size bytes starting at @base
53
* which mirrors the memory starting at @orig.
54
*/
55
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
56
TYPE_CMSDK_APB_TIMER);
57
sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
58
TYPE_CMSDK_APB_DUALTIMER);
59
+ sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
60
+ sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG);
61
+ sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog,
62
+ sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
63
+ sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
64
+ sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
65
+ object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
66
+ sizeof(s->nmi_orgate), TYPE_OR_IRQ,
67
+ &error_abort, NULL);
68
object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
69
sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
70
&error_abort, NULL);
71
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
72
create_unimplemented_device("SYSINFO", 0x40020000, 0x1000);
73
74
create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000);
75
- create_unimplemented_device("S32KWATCHDOG", 0x5002e000, 0x1000);
76
+
77
+ /* This OR gate wires together outputs from the secure watchdogs to NMI */
78
+ object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
79
+ if (err) {
80
+ error_propagate(errp, err);
81
+ return;
82
+ }
83
+ object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
84
+ if (err) {
85
+ error_propagate(errp, err);
86
+ return;
87
+ }
88
+ qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
89
+ qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
90
+
91
+ qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
92
+ object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err);
93
+ if (err) {
94
+ error_propagate(errp, err);
95
+ return;
96
+ }
97
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
98
+ qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
99
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
100
101
/* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */
102
103
- create_unimplemented_device("NS watchdog", 0x40081000, 0x1000);
104
- create_unimplemented_device("S watchdog", 0x50081000, 0x1000);
105
+ qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
106
+ object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
107
+ if (err) {
108
+ error_propagate(errp, err);
109
+ return;
110
+ }
111
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
112
+ qdev_get_gpio_in(DEVICE(&s->armv7m), 1));
113
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
114
+
115
+ qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
116
+ object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err);
117
+ if (err) {
118
+ error_propagate(errp, err);
119
+ return;
120
+ }
121
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
122
+ qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
123
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
124
125
for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
126
Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
127
--
128
2.18.0
129
130
diff view generated by jsdifflib
Deleted patch
1
The IoTKit has a CMSDK timer device that runs on the S32KCLK.
2
Create this and wire it up.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180820141116.9118-8-peter.maydell@linaro.org
8
---
9
include/hw/arm/iotkit.h | 2 +-
10
hw/arm/iotkit.c | 9 +++++----
11
2 files changed, 6 insertions(+), 5 deletions(-)
12
13
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/iotkit.h
16
+++ b/include/hw/arm/iotkit.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
18
TZMPC mpc;
19
CMSDKAPBTIMER timer0;
20
CMSDKAPBTIMER timer1;
21
+ CMSDKAPBTIMER s32ktimer;
22
qemu_or_irq ppc_irq_orgate;
23
SplitIRQ sec_resp_splitter;
24
SplitIRQ ppc_irq_splitter[NUM_PPCS];
25
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
26
qemu_or_irq nmi_orgate;
27
28
CMSDKAPBDualTimer dualtimer;
29
- UnimplementedDeviceState s32ktimer;
30
31
CMSDKAPBWatchdog s32kwatchdog;
32
CMSDKAPBWatchdog nswatchdog;
33
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/iotkit.c
36
+++ b/hw/arm/iotkit.c
37
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
38
TYPE_CMSDK_APB_TIMER);
39
sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
40
TYPE_CMSDK_APB_TIMER);
41
+ sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
42
+ TYPE_CMSDK_APB_TIMER);
43
sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
44
TYPE_CMSDK_APB_DUALTIMER);
45
sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
46
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
47
TYPE_SPLIT_IRQ, &error_abort, NULL);
48
g_free(name);
49
}
50
- sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
51
- TYPE_UNIMPLEMENTED_DEVICE);
52
}
53
54
static void iotkit_exp_irq(void *opaque, int n, int level)
55
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
56
/* Devices behind APB PPC1:
57
* 0x4002f000: S32K timer
58
*/
59
- qdev_prop_set_string(DEVICE(&s->s32ktimer), "name", "S32KTIMER");
60
- qdev_prop_set_uint64(DEVICE(&s->s32ktimer), "size", 0x1000);
61
+ qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
62
object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
63
if (err) {
64
error_propagate(errp, err);
65
return;
66
}
67
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
68
+ qdev_get_gpio_in(DEVICE(&s->armv7m), 2));
69
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
70
object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
71
if (err) {
72
--
73
2.18.0
74
75
diff view generated by jsdifflib
Deleted patch
1
The Arm IoTKit includes a system control element which
2
provides a block of read-only ID registers and a block
3
of read-write control registers. Implement a minimal
4
version of this.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180820141116.9118-9-peter.maydell@linaro.org
9
---
10
hw/misc/Makefile.objs | 1 +
11
include/hw/misc/iotkit-sysctl.h | 49 ++++++
12
hw/misc/iotkit-sysctl.c | 261 ++++++++++++++++++++++++++++++++
13
MAINTAINERS | 2 +
14
default-configs/arm-softmmu.mak | 1 +
15
hw/misc/trace-events | 7 +
16
6 files changed, 321 insertions(+)
17
create mode 100644 include/hw/misc/iotkit-sysctl.h
18
create mode 100644 hw/misc/iotkit-sysctl.c
19
20
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/Makefile.objs
23
+++ b/hw/misc/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2_SCC) += mps2-scc.o
25
obj-$(CONFIG_TZ_MPC) += tz-mpc.o
26
obj-$(CONFIG_TZ_PPC) += tz-ppc.o
27
obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
28
+obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
29
30
obj-$(CONFIG_PVPANIC) += pvpanic.o
31
obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
32
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/misc/iotkit-sysctl.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * ARM IoTKit system control element
40
+ *
41
+ * Copyright (c) 2018 Linaro Limited
42
+ * Written by Peter Maydell
43
+ *
44
+ * This program is free software; you can redistribute it and/or modify
45
+ * it under the terms of the GNU General Public License version 2 or
46
+ * (at your option) any later version.
47
+ */
48
+
49
+/*
50
+ * This is a model of the "system control element" which is part of the
51
+ * Arm IoTKit and documented in
52
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
53
+ * Specifically, it implements the "system information block" and
54
+ * "system control register" blocks.
55
+ *
56
+ * QEMU interface:
57
+ * + sysbus MMIO region 0: the system information register bank
58
+ * + sysbus MMIO region 1: the system control register bank
59
+ */
60
+
61
+#ifndef HW_MISC_IOTKIT_SYSCTL_H
62
+#define HW_MISC_IOTKIT_SYSCTL_H
63
+
64
+#include "hw/sysbus.h"
65
+
66
+#define TYPE_IOTKIT_SYSCTL "iotkit-sysctl"
67
+#define IOTKIT_SYSCTL(obj) OBJECT_CHECK(IoTKitSysCtl, (obj), \
68
+ TYPE_IOTKIT_SYSCTL)
69
+
70
+typedef struct IoTKitSysCtl {
71
+ /*< private >*/
72
+ SysBusDevice parent_obj;
73
+
74
+ /*< public >*/
75
+ MemoryRegion iomem;
76
+
77
+ uint32_t secure_debug;
78
+ uint32_t reset_syndrome;
79
+ uint32_t reset_mask;
80
+ uint32_t gretreg;
81
+ uint32_t initsvrtor0;
82
+ uint32_t cpuwait;
83
+ uint32_t wicctrl;
84
+} IoTKitSysCtl;
85
+
86
+#endif
87
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
88
new file mode 100644
89
index XXXXXXX..XXXXXXX
90
--- /dev/null
91
+++ b/hw/misc/iotkit-sysctl.c
92
@@ -XXX,XX +XXX,XX @@
93
+/*
94
+ * ARM IoTKit system control element
95
+ *
96
+ * Copyright (c) 2018 Linaro Limited
97
+ * Written by Peter Maydell
98
+ *
99
+ * This program is free software; you can redistribute it and/or modify
100
+ * it under the terms of the GNU General Public License version 2 or
101
+ * (at your option) any later version.
102
+ */
103
+
104
+/*
105
+ * This is a model of the "system control element" which is part of the
106
+ * Arm IoTKit and documented in
107
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
108
+ * Specifically, it implements the "system control register" blocks.
109
+ */
110
+
111
+#include "qemu/osdep.h"
112
+#include "qemu/log.h"
113
+#include "trace.h"
114
+#include "qapi/error.h"
115
+#include "sysemu/sysemu.h"
116
+#include "hw/sysbus.h"
117
+#include "hw/registerfields.h"
118
+#include "hw/misc/iotkit-sysctl.h"
119
+
120
+REG32(SECDBGSTAT, 0x0)
121
+REG32(SECDBGSET, 0x4)
122
+REG32(SECDBGCLR, 0x8)
123
+REG32(RESET_SYNDROME, 0x100)
124
+REG32(RESET_MASK, 0x104)
125
+REG32(SWRESET, 0x108)
126
+ FIELD(SWRESET, SWRESETREQ, 9, 1)
127
+REG32(GRETREG, 0x10c)
128
+REG32(INITSVRTOR0, 0x110)
129
+REG32(CPUWAIT, 0x118)
130
+REG32(BUSWAIT, 0x11c)
131
+REG32(WICCTRL, 0x120)
132
+REG32(PID4, 0xfd0)
133
+REG32(PID5, 0xfd4)
134
+REG32(PID6, 0xfd8)
135
+REG32(PID7, 0xfdc)
136
+REG32(PID0, 0xfe0)
137
+REG32(PID1, 0xfe4)
138
+REG32(PID2, 0xfe8)
139
+REG32(PID3, 0xfec)
140
+REG32(CID0, 0xff0)
141
+REG32(CID1, 0xff4)
142
+REG32(CID2, 0xff8)
143
+REG32(CID3, 0xffc)
144
+
145
+/* PID/CID values */
146
+static const int sysctl_id[] = {
147
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
148
+ 0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
149
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
150
+};
151
+
152
+static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
153
+ unsigned size)
154
+{
155
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
156
+ uint64_t r;
157
+
158
+ switch (offset) {
159
+ case A_SECDBGSTAT:
160
+ r = s->secure_debug;
161
+ break;
162
+ case A_RESET_SYNDROME:
163
+ r = s->reset_syndrome;
164
+ break;
165
+ case A_RESET_MASK:
166
+ r = s->reset_mask;
167
+ break;
168
+ case A_GRETREG:
169
+ r = s->gretreg;
170
+ break;
171
+ case A_INITSVRTOR0:
172
+ r = s->initsvrtor0;
173
+ break;
174
+ case A_CPUWAIT:
175
+ r = s->cpuwait;
176
+ break;
177
+ case A_BUSWAIT:
178
+ /* In IoTKit BUSWAIT is reserved, R/O, zero */
179
+ r = 0;
180
+ break;
181
+ case A_WICCTRL:
182
+ r = s->wicctrl;
183
+ break;
184
+ case A_PID4 ... A_CID3:
185
+ r = sysctl_id[(offset - A_PID4) / 4];
186
+ break;
187
+ case A_SECDBGSET:
188
+ case A_SECDBGCLR:
189
+ case A_SWRESET:
190
+ qemu_log_mask(LOG_GUEST_ERROR,
191
+ "IoTKit SysCtl read: read of WO offset %x\n",
192
+ (int)offset);
193
+ r = 0;
194
+ break;
195
+ default:
196
+ qemu_log_mask(LOG_GUEST_ERROR,
197
+ "IoTKit SysCtl read: bad offset %x\n", (int)offset);
198
+ r = 0;
199
+ break;
200
+ }
201
+ trace_iotkit_sysctl_read(offset, r, size);
202
+ return r;
203
+}
204
+
205
+static void iotkit_sysctl_write(void *opaque, hwaddr offset,
206
+ uint64_t value, unsigned size)
207
+{
208
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
209
+
210
+ trace_iotkit_sysctl_write(offset, value, size);
211
+
212
+ /*
213
+ * Most of the state here has to do with control of reset and
214
+ * similar kinds of power up -- for instance the guest can ask
215
+ * what the reason for the last reset was, or forbid reset for
216
+ * some causes (like the non-secure watchdog). Most of this is
217
+ * not relevant to QEMU, which doesn't really model anything other
218
+ * than a full power-on reset.
219
+ * We just model the registers as reads-as-written.
220
+ */
221
+
222
+ switch (offset) {
223
+ case A_RESET_SYNDROME:
224
+ qemu_log_mask(LOG_UNIMP,
225
+ "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
226
+ s->reset_syndrome = value;
227
+ break;
228
+ case A_RESET_MASK:
229
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
230
+ s->reset_mask = value;
231
+ break;
232
+ case A_GRETREG:
233
+ /*
234
+ * General retention register, which is only reset by a power-on
235
+ * reset. Technically this implementation is complete, since
236
+ * QEMU only supports power-on resets...
237
+ */
238
+ s->gretreg = value;
239
+ break;
240
+ case A_INITSVRTOR0:
241
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVRTOR0 unimplemented\n");
242
+ s->initsvrtor0 = value;
243
+ break;
244
+ case A_CPUWAIT:
245
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n");
246
+ s->cpuwait = value;
247
+ break;
248
+ case A_WICCTRL:
249
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
250
+ s->wicctrl = value;
251
+ break;
252
+ case A_SECDBGSET:
253
+ /* write-1-to-set */
254
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
255
+ s->secure_debug |= value;
256
+ break;
257
+ case A_SECDBGCLR:
258
+ /* write-1-to-clear */
259
+ s->secure_debug &= ~value;
260
+ break;
261
+ case A_SWRESET:
262
+ /* One w/o bit to request a reset; all other bits reserved */
263
+ if (value & R_SWRESET_SWRESETREQ_MASK) {
264
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
265
+ }
266
+ break;
267
+ case A_BUSWAIT: /* In IoTKit BUSWAIT is reserved, R/O, zero */
268
+ case A_SECDBGSTAT:
269
+ case A_PID4 ... A_CID3:
270
+ qemu_log_mask(LOG_GUEST_ERROR,
271
+ "IoTKit SysCtl write: write of RO offset %x\n",
272
+ (int)offset);
273
+ break;
274
+ default:
275
+ qemu_log_mask(LOG_GUEST_ERROR,
276
+ "IoTKit SysCtl write: bad offset %x\n", (int)offset);
277
+ break;
278
+ }
279
+}
280
+
281
+static const MemoryRegionOps iotkit_sysctl_ops = {
282
+ .read = iotkit_sysctl_read,
283
+ .write = iotkit_sysctl_write,
284
+ .endianness = DEVICE_LITTLE_ENDIAN,
285
+ /* byte/halfword accesses are just zero-padded on reads and writes */
286
+ .impl.min_access_size = 4,
287
+ .impl.max_access_size = 4,
288
+ .valid.min_access_size = 1,
289
+ .valid.max_access_size = 4,
290
+};
291
+
292
+static void iotkit_sysctl_reset(DeviceState *dev)
293
+{
294
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
295
+
296
+ trace_iotkit_sysctl_reset();
297
+ s->secure_debug = 0;
298
+ s->reset_syndrome = 1;
299
+ s->reset_mask = 0;
300
+ s->gretreg = 0;
301
+ s->initsvrtor0 = 0x10000000;
302
+ s->cpuwait = 0;
303
+ s->wicctrl = 0;
304
+}
305
+
306
+static void iotkit_sysctl_init(Object *obj)
307
+{
308
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
309
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);
310
+
311
+ memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
312
+ s, "iotkit-sysctl", 0x1000);
313
+ sysbus_init_mmio(sbd, &s->iomem);
314
+}
315
+
316
+static const VMStateDescription iotkit_sysctl_vmstate = {
317
+ .name = "iotkit-sysctl",
318
+ .version_id = 1,
319
+ .minimum_version_id = 1,
320
+ .fields = (VMStateField[]) {
321
+ VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
322
+ VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
323
+ VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
324
+ VMSTATE_UINT32(gretreg, IoTKitSysCtl),
325
+ VMSTATE_UINT32(initsvrtor0, IoTKitSysCtl),
326
+ VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
327
+ VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
328
+ VMSTATE_END_OF_LIST()
329
+ }
330
+};
331
+
332
+static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
333
+{
334
+ DeviceClass *dc = DEVICE_CLASS(klass);
335
+
336
+ dc->vmsd = &iotkit_sysctl_vmstate;
337
+ dc->reset = iotkit_sysctl_reset;
338
+}
339
+
340
+static const TypeInfo iotkit_sysctl_info = {
341
+ .name = TYPE_IOTKIT_SYSCTL,
342
+ .parent = TYPE_SYS_BUS_DEVICE,
343
+ .instance_size = sizeof(IoTKitSysCtl),
344
+ .instance_init = iotkit_sysctl_init,
345
+ .class_init = iotkit_sysctl_class_init,
346
+};
347
+
348
+static void iotkit_sysctl_register_types(void)
349
+{
350
+ type_register_static(&iotkit_sysctl_info);
351
+}
352
+
353
+type_init(iotkit_sysctl_register_types);
354
diff --git a/MAINTAINERS b/MAINTAINERS
355
index XXXXXXX..XXXXXXX 100644
356
--- a/MAINTAINERS
357
+++ b/MAINTAINERS
358
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mps2-*.c
359
F: include/hw/misc/mps2-*.h
360
F: hw/arm/iotkit.c
361
F: include/hw/arm/iotkit.h
362
+F: hw/misc/iotkit-sysctl.c
363
+F: include/hw/misc/iotkit-sysctl.h
364
365
Musicpal
366
M: Jan Kiszka <jan.kiszka@web.de>
367
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
368
index XXXXXXX..XXXXXXX 100644
369
--- a/default-configs/arm-softmmu.mak
370
+++ b/default-configs/arm-softmmu.mak
371
@@ -XXX,XX +XXX,XX @@ CONFIG_TZ_MPC=y
372
CONFIG_TZ_PPC=y
373
CONFIG_IOTKIT=y
374
CONFIG_IOTKIT_SECCTL=y
375
+CONFIG_IOTKIT_SYSCTL=y
376
377
CONFIG_VERSATILE=y
378
CONFIG_VERSATILE_PCI=y
379
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
380
index XXXXXXX..XXXXXXX 100644
381
--- a/hw/misc/trace-events
382
+++ b/hw/misc/trace-events
383
@@ -XXX,XX +XXX,XX @@ ccm_freq(uint32_t freq) "freq = %d\n"
384
ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock = %d) = %d\n"
385
ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32 "\n"
386
ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32 "\n"
387
+
388
+# hw/misc/iotkit-sysctl.c
389
+iotkit_sysinfo_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysInfo read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
390
+iotkit_sysinfo_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysInfo write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
391
+iotkit_sysctl_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
392
+iotkit_sysctl_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
393
+iotkit_sysctl_reset(void) "IoTKit SysCtl: reset"
394
--
395
2.18.0
396
397
diff view generated by jsdifflib
Deleted patch
1
Implement the IoTKit system control element's system information
2
block; this is just a pair of read-only version/config registers,
3
plus the usual PID/CID ID registers.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180820141116.9118-10-peter.maydell@linaro.org
9
---
10
hw/misc/Makefile.objs | 1 +
11
include/hw/misc/iotkit-sysinfo.h | 37 +++++++++
12
hw/misc/iotkit-sysinfo.c | 128 +++++++++++++++++++++++++++++++
13
MAINTAINERS | 2 +
14
default-configs/arm-softmmu.mak | 1 +
15
5 files changed, 169 insertions(+)
16
create mode 100644 include/hw/misc/iotkit-sysinfo.h
17
create mode 100644 hw/misc/iotkit-sysinfo.c
18
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/Makefile.objs
22
+++ b/hw/misc/Makefile.objs
23
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_TZ_MPC) += tz-mpc.o
24
obj-$(CONFIG_TZ_PPC) += tz-ppc.o
25
obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
26
obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
27
+obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
28
29
obj-$(CONFIG_PVPANIC) += pvpanic.o
30
obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
31
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/misc/iotkit-sysinfo.h
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * ARM IoTKit system information block
39
+ *
40
+ * Copyright (c) 2018 Linaro Limited
41
+ * Written by Peter Maydell
42
+ *
43
+ * This program is free software; you can redistribute it and/or modify
44
+ * it under the terms of the GNU General Public License version 2 or
45
+ * (at your option) any later version.
46
+ */
47
+
48
+/*
49
+ * This is a model of the "system information block" which is part of the
50
+ * Arm IoTKit and documented in
51
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
52
+ * QEMU interface:
53
+ * + sysbus MMIO region 0: the system information register bank
54
+ */
55
+
56
+#ifndef HW_MISC_IOTKIT_SYSINFO_H
57
+#define HW_MISC_IOTKIT_SYSINFO_H
58
+
59
+#include "hw/sysbus.h"
60
+
61
+#define TYPE_IOTKIT_SYSINFO "iotkit-sysinfo"
62
+#define IOTKIT_SYSINFO(obj) OBJECT_CHECK(IoTKitSysInfo, (obj), \
63
+ TYPE_IOTKIT_SYSINFO)
64
+
65
+typedef struct IoTKitSysInfo {
66
+ /*< private >*/
67
+ SysBusDevice parent_obj;
68
+
69
+ /*< public >*/
70
+ MemoryRegion iomem;
71
+} IoTKitSysInfo;
72
+
73
+#endif
74
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
75
new file mode 100644
76
index XXXXXXX..XXXXXXX
77
--- /dev/null
78
+++ b/hw/misc/iotkit-sysinfo.c
79
@@ -XXX,XX +XXX,XX @@
80
+/*
81
+ * ARM IoTKit system information block
82
+ *
83
+ * Copyright (c) 2018 Linaro Limited
84
+ * Written by Peter Maydell
85
+ *
86
+ * This program is free software; you can redistribute it and/or modify
87
+ * it under the terms of the GNU General Public License version 2 or
88
+ * (at your option) any later version.
89
+ */
90
+
91
+/*
92
+ * This is a model of the "system information block" which is part of the
93
+ * Arm IoTKit and documented in
94
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
95
+ * It consists of 2 read-only version/config registers, plus the
96
+ * usual ID registers.
97
+ */
98
+
99
+#include "qemu/osdep.h"
100
+#include "qemu/log.h"
101
+#include "trace.h"
102
+#include "qapi/error.h"
103
+#include "sysemu/sysemu.h"
104
+#include "hw/sysbus.h"
105
+#include "hw/registerfields.h"
106
+#include "hw/misc/iotkit-sysinfo.h"
107
+
108
+REG32(SYS_VERSION, 0x0)
109
+REG32(SYS_CONFIG, 0x4)
110
+REG32(PID4, 0xfd0)
111
+REG32(PID5, 0xfd4)
112
+REG32(PID6, 0xfd8)
113
+REG32(PID7, 0xfdc)
114
+REG32(PID0, 0xfe0)
115
+REG32(PID1, 0xfe4)
116
+REG32(PID2, 0xfe8)
117
+REG32(PID3, 0xfec)
118
+REG32(CID0, 0xff0)
119
+REG32(CID1, 0xff4)
120
+REG32(CID2, 0xff8)
121
+REG32(CID3, 0xffc)
122
+
123
+/* PID/CID values */
124
+static const int sysinfo_id[] = {
125
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
126
+ 0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
127
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
128
+};
129
+
130
+static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
131
+ unsigned size)
132
+{
133
+ uint64_t r;
134
+
135
+ switch (offset) {
136
+ case A_SYS_VERSION:
137
+ r = 0x41743;
138
+ break;
139
+
140
+ case A_SYS_CONFIG:
141
+ r = 0x31;
142
+ break;
143
+ case A_PID4 ... A_CID3:
144
+ r = sysinfo_id[(offset - A_PID4) / 4];
145
+ break;
146
+ default:
147
+ qemu_log_mask(LOG_GUEST_ERROR,
148
+ "IoTKit SysInfo read: bad offset %x\n", (int)offset);
149
+ r = 0;
150
+ break;
151
+ }
152
+ trace_iotkit_sysinfo_read(offset, r, size);
153
+ return r;
154
+}
155
+
156
+static void iotkit_sysinfo_write(void *opaque, hwaddr offset,
157
+ uint64_t value, unsigned size)
158
+{
159
+ trace_iotkit_sysinfo_write(offset, value, size);
160
+
161
+ qemu_log_mask(LOG_GUEST_ERROR,
162
+ "IoTKit SysInfo: write to RO offset 0x%x\n", (int)offset);
163
+}
164
+
165
+static const MemoryRegionOps iotkit_sysinfo_ops = {
166
+ .read = iotkit_sysinfo_read,
167
+ .write = iotkit_sysinfo_write,
168
+ .endianness = DEVICE_LITTLE_ENDIAN,
169
+ /* byte/halfword accesses are just zero-padded on reads and writes */
170
+ .impl.min_access_size = 4,
171
+ .impl.max_access_size = 4,
172
+ .valid.min_access_size = 1,
173
+ .valid.max_access_size = 4,
174
+};
175
+
176
+static void iotkit_sysinfo_init(Object *obj)
177
+{
178
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
179
+ IoTKitSysInfo *s = IOTKIT_SYSINFO(obj);
180
+
181
+ memory_region_init_io(&s->iomem, obj, &iotkit_sysinfo_ops,
182
+ s, "iotkit-sysinfo", 0x1000);
183
+ sysbus_init_mmio(sbd, &s->iomem);
184
+}
185
+
186
+static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
187
+{
188
+ /*
189
+ * This device has no guest-modifiable state and so it
190
+ * does not need a reset function or VMState.
191
+ */
192
+}
193
+
194
+static const TypeInfo iotkit_sysinfo_info = {
195
+ .name = TYPE_IOTKIT_SYSINFO,
196
+ .parent = TYPE_SYS_BUS_DEVICE,
197
+ .instance_size = sizeof(IoTKitSysInfo),
198
+ .instance_init = iotkit_sysinfo_init,
199
+ .class_init = iotkit_sysinfo_class_init,
200
+};
201
+
202
+static void iotkit_sysinfo_register_types(void)
203
+{
204
+ type_register_static(&iotkit_sysinfo_info);
205
+}
206
+
207
+type_init(iotkit_sysinfo_register_types);
208
diff --git a/MAINTAINERS b/MAINTAINERS
209
index XXXXXXX..XXXXXXX 100644
210
--- a/MAINTAINERS
211
+++ b/MAINTAINERS
212
@@ -XXX,XX +XXX,XX @@ F: hw/arm/iotkit.c
213
F: include/hw/arm/iotkit.h
214
F: hw/misc/iotkit-sysctl.c
215
F: include/hw/misc/iotkit-sysctl.h
216
+F: hw/misc/iotkit-sysinfo.c
217
+F: include/hw/misc/iotkit-sysinfo.h
218
219
Musicpal
220
M: Jan Kiszka <jan.kiszka@web.de>
221
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
222
index XXXXXXX..XXXXXXX 100644
223
--- a/default-configs/arm-softmmu.mak
224
+++ b/default-configs/arm-softmmu.mak
225
@@ -XXX,XX +XXX,XX @@ CONFIG_TZ_PPC=y
226
CONFIG_IOTKIT=y
227
CONFIG_IOTKIT_SECCTL=y
228
CONFIG_IOTKIT_SYSCTL=y
229
+CONFIG_IOTKIT_SYSINFO=y
230
231
CONFIG_VERSATILE=y
232
CONFIG_VERSATILE_PCI=y
233
--
234
2.18.0
235
236
diff view generated by jsdifflib
Deleted patch
1
Wire up the system control element's register banks
2
(sysctl and sysinfo).
3
1
4
This is the last of the previously completely unimplemented
5
components in the IoTKit.
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180820141116.9118-11-peter.maydell@linaro.org
11
---
12
include/hw/arm/iotkit.h | 6 +++++-
13
hw/arm/iotkit.c | 26 ++++++++++++++++++--------
14
2 files changed, 23 insertions(+), 9 deletions(-)
15
16
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/iotkit.h
19
+++ b/include/hw/arm/iotkit.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/timer/cmsdk-apb-timer.h"
22
#include "hw/timer/cmsdk-apb-dualtimer.h"
23
#include "hw/watchdog/cmsdk-apb-watchdog.h"
24
-#include "hw/misc/unimp.h"
25
+#include "hw/misc/iotkit-sysctl.h"
26
+#include "hw/misc/iotkit-sysinfo.h"
27
#include "hw/or-irq.h"
28
#include "hw/core/split-irq.h"
29
30
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
31
CMSDKAPBWatchdog nswatchdog;
32
CMSDKAPBWatchdog swatchdog;
33
34
+ IoTKitSysCtl sysctl;
35
+ IoTKitSysCtl sysinfo;
36
+
37
MemoryRegion container;
38
MemoryRegion alias1;
39
MemoryRegion alias2;
40
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/iotkit.c
43
+++ b/hw/arm/iotkit.c
44
@@ -XXX,XX +XXX,XX @@
45
#include "hw/sysbus.h"
46
#include "hw/registerfields.h"
47
#include "hw/arm/iotkit.h"
48
-#include "hw/misc/unimp.h"
49
#include "hw/arm/arm.h"
50
51
/* Clock frequency in HZ of the 32KHz "slow clock" */
52
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
53
sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
54
sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
55
sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
56
+ sysbus_init_child_obj(obj, "iotkit-sysctl", &s->sysctl,
57
+ sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
58
+ sysbus_init_child_obj(obj, "iotkit-sysinfo", &s->sysinfo,
59
+ sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
60
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
61
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
62
&error_abort, NULL);
63
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
64
qdev_get_gpio_in_named(dev_apb_ppc1,
65
"cfg_sec_resp", 0));
66
67
- /* Using create_unimplemented_device() maps the stub into the
68
- * system address space rather than into our container, but the
69
- * overall effect to the guest is the same.
70
- */
71
- create_unimplemented_device("SYSINFO", 0x40020000, 0x1000);
72
-
73
- create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000);
74
+ object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
+ /* System information registers */
80
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
81
+ /* System control registers */
82
+ object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
83
+ if (err) {
84
+ error_propagate(errp, err);
85
+ return;
86
+ }
87
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
88
89
/* This OR gate wires together outputs from the secure watchdogs to NMI */
90
object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
91
--
92
2.18.0
93
94
diff view generated by jsdifflib
Deleted patch
1
Implement a model of the TrustZone Master Securtiy Controller,
2
as documented in the Arm CoreLink SIE-200 System IP for
3
Embedded TRM (DDI0571G):
4
https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g
5
1
6
The MSC is intended to sit in front of a device which can
7
be a bus master (eg a DMA controller) and programmably gate
8
its transactions. This allows a bus-mastering device to be
9
controlled by non-secure code but still restricted from
10
making accesses to addresses which are secure-only.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20180820141116.9118-12-peter.maydell@linaro.org
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
---
16
hw/misc/Makefile.objs | 1 +
17
include/hw/misc/tz-msc.h | 79 ++++++++
18
hw/misc/tz-msc.c | 308 ++++++++++++++++++++++++++++++++
19
MAINTAINERS | 2 +
20
default-configs/arm-softmmu.mak | 1 +
21
hw/misc/trace-events | 9 +
22
6 files changed, 400 insertions(+)
23
create mode 100644 include/hw/misc/tz-msc.h
24
create mode 100644 hw/misc/tz-msc.c
25
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/Makefile.objs
29
+++ b/hw/misc/Makefile.objs
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2_FPGAIO) += mps2-fpgaio.o
31
obj-$(CONFIG_MPS2_SCC) += mps2-scc.o
32
33
obj-$(CONFIG_TZ_MPC) += tz-mpc.o
34
+obj-$(CONFIG_TZ_MSC) += tz-msc.o
35
obj-$(CONFIG_TZ_PPC) += tz-ppc.o
36
obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
37
obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
38
diff --git a/include/hw/misc/tz-msc.h b/include/hw/misc/tz-msc.h
39
new file mode 100644
40
index XXXXXXX..XXXXXXX
41
--- /dev/null
42
+++ b/include/hw/misc/tz-msc.h
43
@@ -XXX,XX +XXX,XX @@
44
+/*
45
+ * ARM TrustZone master security controller emulation
46
+ *
47
+ * Copyright (c) 2018 Linaro Limited
48
+ * Written by Peter Maydell
49
+ *
50
+ * This program is free software; you can redistribute it and/or modify
51
+ * it under the terms of the GNU General Public License version 2 or
52
+ * (at your option) any later version.
53
+ */
54
+
55
+/*
56
+ * This is a model of the TrustZone master security controller (MSC).
57
+ * It is documented in the ARM CoreLink SIE-200 System IP for Embedded TRM
58
+ * (DDI 0571G):
59
+ * https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g
60
+ *
61
+ * The MSC sits in front of a device which can be a bus master (such as
62
+ * a DMA controller) and allows secure software to configure it to either
63
+ * pass through or reject transactions made by that bus master.
64
+ * Rejected transactions may be configured to either be aborted, or to
65
+ * behave as RAZ/WI. An interrupt can be signalled for a rejected transaction.
66
+ *
67
+ * The MSC has no register interface -- it is configured purely by a
68
+ * collection of input signals from other hardware in the system. Typically
69
+ * they are either hardwired or exposed in an ad-hoc register interface by
70
+ * the SoC that uses the MSC.
71
+ *
72
+ * We don't currently implement the irq_enable GPIO input, because on
73
+ * the MPS2 FPGA images it is always tied high, which is awkward to
74
+ * implement in QEMU.
75
+ *
76
+ * QEMU interface:
77
+ * + Named GPIO input "cfg_nonsec": set to 1 if the bus master should be
78
+ * treated as nonsecure, or 0 for secure
79
+ * + Named GPIO input "cfg_sec_resp": set to 1 if a rejected transaction should
80
+ * result in a transaction error, or 0 for the transaction to RAZ/WI
81
+ * + Named GPIO input "irq_clear": set to 1 to clear a pending interrupt
82
+ * + Named GPIO output "irq": set for a transaction-failed interrupt
83
+ * + Property "downstream": MemoryRegion defining where bus master transactions
84
+ * are made if they are not blocked
85
+ * + Property "idau": an object implementing IDAUInterface, which defines which
86
+ * addresses should be treated as secure and which as non-secure.
87
+ * This need not be the same IDAU as the one used by the CPU.
88
+ * + sysbus MMIO region 0: MemoryRegion defining the upstream end of the MSC;
89
+ * this should be passed to the bus master device as the region it should
90
+ * make memory transactions to
91
+ */
92
+
93
+#ifndef TZ_MSC_H
94
+#define TZ_MSC_H
95
+
96
+#include "hw/sysbus.h"
97
+#include "target/arm/idau.h"
98
+
99
+#define TYPE_TZ_MSC "tz-msc"
100
+#define TZ_MSC(obj) OBJECT_CHECK(TZMSC, (obj), TYPE_TZ_MSC)
101
+
102
+typedef struct TZMSC {
103
+ /*< private >*/
104
+ SysBusDevice parent_obj;
105
+
106
+ /*< public >*/
107
+
108
+ /* State: these just track the values of our input signals */
109
+ bool cfg_nonsec;
110
+ bool cfg_sec_resp;
111
+ bool irq_clear;
112
+ /* State: are we asserting irq ? */
113
+ bool irq_status;
114
+
115
+ qemu_irq irq;
116
+ MemoryRegion *downstream;
117
+ AddressSpace downstream_as;
118
+ MemoryRegion upstream;
119
+ IDAUInterface *idau;
120
+} TZMSC;
121
+
122
+#endif
123
diff --git a/hw/misc/tz-msc.c b/hw/misc/tz-msc.c
124
new file mode 100644
125
index XXXXXXX..XXXXXXX
126
--- /dev/null
127
+++ b/hw/misc/tz-msc.c
128
@@ -XXX,XX +XXX,XX @@
129
+/*
130
+ * ARM TrustZone master security controller emulation
131
+ *
132
+ * Copyright (c) 2018 Linaro Limited
133
+ * Written by Peter Maydell
134
+ *
135
+ * This program is free software; you can redistribute it and/or modify
136
+ * it under the terms of the GNU General Public License version 2 or
137
+ * (at your option) any later version.
138
+ */
139
+
140
+#include "qemu/osdep.h"
141
+#include "qemu/log.h"
142
+#include "qapi/error.h"
143
+#include "trace.h"
144
+#include "hw/sysbus.h"
145
+#include "hw/registerfields.h"
146
+#include "hw/misc/tz-msc.h"
147
+
148
+static void tz_msc_update_irq(TZMSC *s)
149
+{
150
+ bool level = s->irq_status;
151
+
152
+ trace_tz_msc_update_irq(level);
153
+ qemu_set_irq(s->irq, level);
154
+}
155
+
156
+static void tz_msc_cfg_nonsec(void *opaque, int n, int level)
157
+{
158
+ TZMSC *s = TZ_MSC(opaque);
159
+
160
+ trace_tz_msc_cfg_nonsec(level);
161
+ s->cfg_nonsec = level;
162
+}
163
+
164
+static void tz_msc_cfg_sec_resp(void *opaque, int n, int level)
165
+{
166
+ TZMSC *s = TZ_MSC(opaque);
167
+
168
+ trace_tz_msc_cfg_sec_resp(level);
169
+ s->cfg_sec_resp = level;
170
+}
171
+
172
+static void tz_msc_irq_clear(void *opaque, int n, int level)
173
+{
174
+ TZMSC *s = TZ_MSC(opaque);
175
+
176
+ trace_tz_msc_irq_clear(level);
177
+
178
+ s->irq_clear = level;
179
+ if (level) {
180
+ s->irq_status = false;
181
+ tz_msc_update_irq(s);
182
+ }
183
+}
184
+
185
+/* The MSC may either block a transaction by aborting it, block a
186
+ * transaction by making it RAZ/WI, allow it through with
187
+ * MemTxAttrs indicating a secure transaction, or allow it with
188
+ * MemTxAttrs indicating a non-secure transaction.
189
+ */
190
+typedef enum MSCAction {
191
+ MSCBlockAbort,
192
+ MSCBlockRAZWI,
193
+ MSCAllowSecure,
194
+ MSCAllowNonSecure,
195
+} MSCAction;
196
+
197
+static MSCAction tz_msc_check(TZMSC *s, hwaddr addr)
198
+{
199
+ /*
200
+ * Check whether to allow an access from the bus master, returning
201
+ * an MSCAction indicating the required behaviour. If the transaction
202
+ * is blocked, the caller must check cfg_sec_resp to determine
203
+ * whether to abort or RAZ/WI the transaction.
204
+ */
205
+ IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(s->idau);
206
+ IDAUInterface *ii = IDAU_INTERFACE(s->idau);
207
+ bool idau_exempt = false, idau_ns = true, idau_nsc = true;
208
+ int idau_region = IREGION_NOTVALID;
209
+
210
+ iic->check(ii, addr, &idau_region, &idau_exempt, &idau_ns, &idau_nsc);
211
+
212
+ if (idau_exempt) {
213
+ /*
214
+ * Uncheck region -- OK, transaction type depends on
215
+ * whether bus master is configured as Secure or NonSecure
216
+ */
217
+ return s->cfg_nonsec ? MSCAllowNonSecure : MSCAllowSecure;
218
+ }
219
+
220
+ if (idau_ns) {
221
+ /* NonSecure region -- always forward as NS transaction */
222
+ return MSCAllowNonSecure;
223
+ }
224
+
225
+ if (!s->cfg_nonsec) {
226
+ /* Access to Secure region by Secure bus master: OK */
227
+ return MSCAllowSecure;
228
+ }
229
+
230
+ /* Attempted access to Secure region by NS bus master: block */
231
+ trace_tz_msc_access_blocked(addr);
232
+ if (!s->cfg_sec_resp) {
233
+ return MSCBlockRAZWI;
234
+ }
235
+
236
+ /*
237
+ * The TRM isn't clear on behaviour if irq_clear is high when a
238
+ * transaction is blocked. We assume that the MSC behaves like the
239
+ * PPC, where holding irq_clear high suppresses the interrupt.
240
+ */
241
+ if (!s->irq_clear) {
242
+ s->irq_status = true;
243
+ tz_msc_update_irq(s);
244
+ }
245
+ return MSCBlockAbort;
246
+}
247
+
248
+static MemTxResult tz_msc_read(void *opaque, hwaddr addr, uint64_t *pdata,
249
+ unsigned size, MemTxAttrs attrs)
250
+{
251
+ TZMSC *s = opaque;
252
+ AddressSpace *as = &s->downstream_as;
253
+ uint64_t data;
254
+ MemTxResult res;
255
+
256
+ switch (tz_msc_check(s, addr)) {
257
+ case MSCBlockAbort:
258
+ return MEMTX_ERROR;
259
+ case MSCBlockRAZWI:
260
+ *pdata = 0;
261
+ return MEMTX_OK;
262
+ case MSCAllowSecure:
263
+ attrs.secure = 1;
264
+ attrs.unspecified = 0;
265
+ break;
266
+ case MSCAllowNonSecure:
267
+ attrs.secure = 0;
268
+ attrs.unspecified = 0;
269
+ break;
270
+ }
271
+
272
+ switch (size) {
273
+ case 1:
274
+ data = address_space_ldub(as, addr, attrs, &res);
275
+ break;
276
+ case 2:
277
+ data = address_space_lduw_le(as, addr, attrs, &res);
278
+ break;
279
+ case 4:
280
+ data = address_space_ldl_le(as, addr, attrs, &res);
281
+ break;
282
+ case 8:
283
+ data = address_space_ldq_le(as, addr, attrs, &res);
284
+ break;
285
+ default:
286
+ g_assert_not_reached();
287
+ }
288
+ *pdata = data;
289
+ return res;
290
+}
291
+
292
+static MemTxResult tz_msc_write(void *opaque, hwaddr addr, uint64_t val,
293
+ unsigned size, MemTxAttrs attrs)
294
+{
295
+ TZMSC *s = opaque;
296
+ AddressSpace *as = &s->downstream_as;
297
+ MemTxResult res;
298
+
299
+ switch (tz_msc_check(s, addr)) {
300
+ case MSCBlockAbort:
301
+ return MEMTX_ERROR;
302
+ case MSCBlockRAZWI:
303
+ return MEMTX_OK;
304
+ case MSCAllowSecure:
305
+ attrs.secure = 1;
306
+ attrs.unspecified = 0;
307
+ break;
308
+ case MSCAllowNonSecure:
309
+ attrs.secure = 0;
310
+ attrs.unspecified = 0;
311
+ break;
312
+ }
313
+
314
+ switch (size) {
315
+ case 1:
316
+ address_space_stb(as, addr, val, attrs, &res);
317
+ break;
318
+ case 2:
319
+ address_space_stw_le(as, addr, val, attrs, &res);
320
+ break;
321
+ case 4:
322
+ address_space_stl_le(as, addr, val, attrs, &res);
323
+ break;
324
+ case 8:
325
+ address_space_stq_le(as, addr, val, attrs, &res);
326
+ break;
327
+ default:
328
+ g_assert_not_reached();
329
+ }
330
+ return res;
331
+}
332
+
333
+static const MemoryRegionOps tz_msc_ops = {
334
+ .read_with_attrs = tz_msc_read,
335
+ .write_with_attrs = tz_msc_write,
336
+ .endianness = DEVICE_LITTLE_ENDIAN,
337
+};
338
+
339
+static void tz_msc_reset(DeviceState *dev)
340
+{
341
+ TZMSC *s = TZ_MSC(dev);
342
+
343
+ trace_tz_msc_reset();
344
+ s->cfg_sec_resp = false;
345
+ s->cfg_nonsec = false;
346
+ s->irq_clear = 0;
347
+ s->irq_status = 0;
348
+}
349
+
350
+static void tz_msc_init(Object *obj)
351
+{
352
+ DeviceState *dev = DEVICE(obj);
353
+ TZMSC *s = TZ_MSC(obj);
354
+
355
+ qdev_init_gpio_in_named(dev, tz_msc_cfg_nonsec, "cfg_nonsec", 1);
356
+ qdev_init_gpio_in_named(dev, tz_msc_cfg_sec_resp, "cfg_sec_resp", 1);
357
+ qdev_init_gpio_in_named(dev, tz_msc_irq_clear, "irq_clear", 1);
358
+ qdev_init_gpio_out_named(dev, &s->irq, "irq", 1);
359
+}
360
+
361
+static void tz_msc_realize(DeviceState *dev, Error **errp)
362
+{
363
+ Object *obj = OBJECT(dev);
364
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
365
+ TZMSC *s = TZ_MSC(dev);
366
+ const char *name = "tz-msc-downstream";
367
+ uint64_t size;
368
+
369
+ /*
370
+ * We can't create the upstream end of the port until realize,
371
+ * as we don't know the size of the MR used as the downstream until then.
372
+ * We insist on having a downstream, to avoid complicating the
373
+ * code with handling the "don't know how big this is" case. It's easy
374
+ * enough for the user to create an unimplemented_device as downstream
375
+ * if they have nothing else to plug into this.
376
+ */
377
+ if (!s->downstream) {
378
+ error_setg(errp, "MSC 'downstream' link not set");
379
+ return;
380
+ }
381
+ if (!s->idau) {
382
+ error_setg(errp, "MSC 'idau' link not set");
383
+ return;
384
+ }
385
+
386
+ size = memory_region_size(s->downstream);
387
+ address_space_init(&s->downstream_as, s->downstream, name);
388
+ memory_region_init_io(&s->upstream, obj, &tz_msc_ops, s, name, size);
389
+ sysbus_init_mmio(sbd, &s->upstream);
390
+}
391
+
392
+static const VMStateDescription tz_msc_vmstate = {
393
+ .name = "tz-msc",
394
+ .version_id = 1,
395
+ .minimum_version_id = 1,
396
+ .fields = (VMStateField[]) {
397
+ VMSTATE_BOOL(cfg_nonsec, TZMSC),
398
+ VMSTATE_BOOL(cfg_sec_resp, TZMSC),
399
+ VMSTATE_BOOL(irq_clear, TZMSC),
400
+ VMSTATE_BOOL(irq_status, TZMSC),
401
+ VMSTATE_END_OF_LIST()
402
+ }
403
+};
404
+
405
+static Property tz_msc_properties[] = {
406
+ DEFINE_PROP_LINK("downstream", TZMSC, downstream,
407
+ TYPE_MEMORY_REGION, MemoryRegion *),
408
+ DEFINE_PROP_LINK("idau", TZMSC, idau,
409
+ TYPE_IDAU_INTERFACE, IDAUInterface *),
410
+ DEFINE_PROP_END_OF_LIST(),
411
+};
412
+
413
+static void tz_msc_class_init(ObjectClass *klass, void *data)
414
+{
415
+ DeviceClass *dc = DEVICE_CLASS(klass);
416
+
417
+ dc->realize = tz_msc_realize;
418
+ dc->vmsd = &tz_msc_vmstate;
419
+ dc->reset = tz_msc_reset;
420
+ dc->props = tz_msc_properties;
421
+}
422
+
423
+static const TypeInfo tz_msc_info = {
424
+ .name = TYPE_TZ_MSC,
425
+ .parent = TYPE_SYS_BUS_DEVICE,
426
+ .instance_size = sizeof(TZMSC),
427
+ .instance_init = tz_msc_init,
428
+ .class_init = tz_msc_class_init,
429
+};
430
+
431
+static void tz_msc_register_types(void)
432
+{
433
+ type_register_static(&tz_msc_info);
434
+}
435
+
436
+type_init(tz_msc_register_types);
437
diff --git a/MAINTAINERS b/MAINTAINERS
438
index XXXXXXX..XXXXXXX 100644
439
--- a/MAINTAINERS
440
+++ b/MAINTAINERS
441
@@ -XXX,XX +XXX,XX @@ F: hw/misc/tz-ppc.c
442
F: include/hw/misc/tz-ppc.h
443
F: hw/misc/tz-mpc.c
444
F: include/hw/misc/tz-mpc.h
445
+F: hw/misc/tz-msc.c
446
+F: include/hw/misc/tz-msc.h
447
448
ARM cores
449
M: Peter Maydell <peter.maydell@linaro.org>
450
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
451
index XXXXXXX..XXXXXXX 100644
452
--- a/default-configs/arm-softmmu.mak
453
+++ b/default-configs/arm-softmmu.mak
454
@@ -XXX,XX +XXX,XX @@ CONFIG_MPS2_FPGAIO=y
455
CONFIG_MPS2_SCC=y
456
457
CONFIG_TZ_MPC=y
458
+CONFIG_TZ_MSC=y
459
CONFIG_TZ_PPC=y
460
CONFIG_IOTKIT=y
461
CONFIG_IOTKIT_SECCTL=y
462
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
463
index XXXXXXX..XXXXXXX 100644
464
--- a/hw/misc/trace-events
465
+++ b/hw/misc/trace-events
466
@@ -XXX,XX +XXX,XX @@ tz_mpc_mem_blocked_write(uint64_t addr, uint64_t data, unsigned size, bool secur
467
tz_mpc_translate(uint64_t addr, int flags, const char *idx, const char *res) "TZ MPC translate: addr 0x%" PRIx64 " flags 0x%x iommu_idx %s: %s"
468
tz_mpc_iommu_notify(uint64_t addr) "TZ MPC iommu: notifying UNMAP/MAP for 0x%" PRIx64
469
470
+# hw/misc/tz-msc.c
471
+tz_msc_reset(void) "TZ MSC: reset"
472
+tz_msc_cfg_nonsec(int level) "TZ MSC: cfg_nonsec = %d"
473
+tz_msc_cfg_sec_resp(int level) "TZ MSC: cfg_sec_resp = %d"
474
+tz_msc_irq_enable(int level) "TZ MSC: int_enable = %d"
475
+tz_msc_irq_clear(int level) "TZ MSC: int_clear = %d"
476
+tz_msc_update_irq(int level) "TZ MSC: setting irq line to %d"
477
+tz_msc_access_blocked(uint64_t offset) "TZ MSC: offset 0x%" PRIx64 " access blocked"
478
+
479
# hw/misc/tz-ppc.c
480
tz_ppc_reset(void) "TZ PPC: reset"
481
tz_ppc_cfg_nonsec(int n, int level) "TZ PPC: cfg_nonsec[%d] = %d"
482
--
483
2.18.0
484
485
diff view generated by jsdifflib
Deleted patch
1
The IoTKit doesn't have any MSCs itself but it does need
2
some wiring to connect the external signals from MSCs
3
in the outer board model up to the registers and the
4
NVIC IRQ line.
5
1
6
We also need to expose a MemoryRegion corresponding to
7
the AHB bus, so that MSCs in the outer board model can
8
use that as their downstream port. (In the FPGA this is
9
the "AHB Slave Expansion" ports shown in the block
10
diagram in the AN505 documentation.)
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20180820141116.9118-14-peter.maydell@linaro.org
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
---
17
include/hw/arm/iotkit.h | 8 ++++++++
18
hw/arm/iotkit.c | 15 +++++++++++++++
19
2 files changed, 23 insertions(+)
20
21
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/iotkit.h
24
+++ b/include/hw/arm/iotkit.h
25
@@ -XXX,XX +XXX,XX @@
26
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts
27
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts, which
28
* are wired to the NVIC lines 32 .. n+32
29
+ * + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows
30
+ * bus master devices in the board model to make transactions into
31
+ * all the devices and memory areas in the IoTKit
32
* Controlling up to 4 AHB expansion PPBs which a system using the IoTKit
33
* might provide:
34
* + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15]
35
@@ -XXX,XX +XXX,XX @@
36
* Controlling each of the 16 expansion MPCs which a system using the IoTKit
37
* might provide:
38
* + named GPIO inputs mpcexp_status[0..15]
39
+ * Controlling each of the 16 expansion MSCs which a system using the IoTKit
40
+ * might provide:
41
+ * + named GPIO inputs mscexp_status[0..15]
42
+ * + named GPIO outputs mscexp_clear[0..15]
43
+ * + named GPIO outputs mscexp_ns[0..15]
44
*/
45
46
#ifndef IOTKIT_H
47
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/iotkit.c
50
+++ b/hw/arm/iotkit.c
51
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
52
53
iotkit_forward_sec_resp_cfg(s);
54
55
+ /* Forward the MSC related signals */
56
+ qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
57
+ qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
58
+ qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
59
+ qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
60
+ qdev_get_gpio_in(DEVICE(&s->armv7m), 11));
61
+
62
+ /*
63
+ * Expose our container region to the board model; this corresponds
64
+ * to the AHB Slave Expansion ports which allow bus master devices
65
+ * (eg DMA controllers) in the board model to make transactions into
66
+ * devices in the IoTKit.
67
+ */
68
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
69
+
70
system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
71
}
72
73
--
74
2.18.0
75
76
diff view generated by jsdifflib
Deleted patch
1
Currently the PL022 calls pl022_reset() from its class init
2
function. Make it register a DeviceState reset method instead,
3
so that we reset the device on system reset.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20180820141116.9118-17-peter.maydell@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
hw/ssi/pl022.c | 7 +++++--
11
1 file changed, 5 insertions(+), 2 deletions(-)
12
13
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/ssi/pl022.c
16
+++ b/hw/ssi/pl022.c
17
@@ -XXX,XX +XXX,XX @@ static void pl022_write(void *opaque, hwaddr offset,
18
}
19
}
20
21
-static void pl022_reset(PL022State *s)
22
+static void pl022_reset(DeviceState *dev)
23
{
24
+ PL022State *s = PL022(dev);
25
+
26
s->rx_fifo_len = 0;
27
s->tx_fifo_len = 0;
28
s->im = 0;
29
@@ -XXX,XX +XXX,XX @@ static int pl022_init(SysBusDevice *sbd)
30
sysbus_init_mmio(sbd, &s->iomem);
31
sysbus_init_irq(sbd, &s->irq);
32
s->ssi = ssi_create_bus(dev, "ssi");
33
- pl022_reset(s);
34
vmstate_register(dev, -1, &vmstate_pl022, s);
35
return 0;
36
}
37
@@ -XXX,XX +XXX,XX @@ static int pl022_init(SysBusDevice *sbd)
38
static void pl022_class_init(ObjectClass *klass, void *data)
39
{
40
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
41
+ DeviceClass *dc = DEVICE_CLASS(klass);
42
43
sdc->init = pl022_init;
44
+ dc->reset = pl022_reset;
45
}
46
47
static const TypeInfo pl022_info = {
48
--
49
2.18.0
50
51
diff view generated by jsdifflib
Deleted patch
1
Move from the legacy SysBusDevice::init method to using
2
DeviceState::realize.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20180820141116.9118-19-peter.maydell@linaro.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
hw/ssi/pl022.c | 8 +++-----
10
1 file changed, 3 insertions(+), 5 deletions(-)
11
12
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/ssi/pl022.c
15
+++ b/hw/ssi/pl022.c
16
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl022 = {
17
}
18
};
19
20
-static int pl022_init(SysBusDevice *sbd)
21
+static void pl022_realize(DeviceState *dev, Error **errp)
22
{
23
- DeviceState *dev = DEVICE(sbd);
24
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
25
PL022State *s = PL022(dev);
26
27
memory_region_init_io(&s->iomem, OBJECT(s), &pl022_ops, s, "pl022", 0x1000);
28
sysbus_init_mmio(sbd, &s->iomem);
29
sysbus_init_irq(sbd, &s->irq);
30
s->ssi = ssi_create_bus(dev, "ssi");
31
- return 0;
32
}
33
34
static void pl022_class_init(ObjectClass *klass, void *data)
35
{
36
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
37
DeviceClass *dc = DEVICE_CLASS(klass);
38
39
- sdc->init = pl022_init;
40
dc->reset = pl022_reset;
41
dc->vmsd = &vmstate_pl022;
42
+ dc->realize = pl022_realize;
43
}
44
45
static const TypeInfo pl022_info = {
46
--
47
2.18.0
48
49
diff view generated by jsdifflib
Deleted patch
1
In the PL022, register offset 0x20 is the ICR, a write-only
2
interrupt-clear register. Register offset 0x24 is DMACR, the DMA
3
control register. We were incorrectly implementing (a stub version
4
of) DMACR at 0x20, and not implementing anything at 0x24. Fix this
5
bug.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20180820141116.9118-21-peter.maydell@linaro.org
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
hw/ssi/pl022.c | 12 ++++++++++--
12
1 file changed, 10 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/pl022.c
17
+++ b/hw/ssi/pl022.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pl022_read(void *opaque, hwaddr offset,
19
return s->is;
20
case 0x1c: /* MIS */
21
return s->im & s->is;
22
- case 0x20: /* DMACR */
23
+ case 0x24: /* DMACR */
24
/* Not implemented. */
25
return 0;
26
default:
27
@@ -XXX,XX +XXX,XX @@ static void pl022_write(void *opaque, hwaddr offset,
28
s->im = value;
29
pl022_update(s);
30
break;
31
- case 0x20: /* DMACR */
32
+ case 0x20: /* ICR */
33
+ /*
34
+ * write-1-to-clear: bit 0 clears ROR, bit 1 clears RT;
35
+ * RX and TX interrupts cannot be cleared this way.
36
+ */
37
+ value &= PL022_INT_ROR | PL022_INT_RT;
38
+ s->is &= ~value;
39
+ break;
40
+ case 0x24: /* DMACR */
41
if (value) {
42
qemu_log_mask(LOG_UNIMP, "pl022: DMA not implemented\n");
43
}
44
--
45
2.18.0
46
47
diff view generated by jsdifflib
Deleted patch
1
The SPI controllers in the MPS2 AN505 board are PL022s.
2
We have a model of the PL022, so create these devices.
3
1
4
We don't currently model the LCD controller that sits behind
5
one of the PL022s; the others are intended to control devices
6
that sit on the FPGA's general purpose SPI connector or
7
"shield" expansion connectors.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20180820141116.9118-22-peter.maydell@linaro.org
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
---
13
hw/arm/mps2-tz.c | 38 ++++++++++++++++++++++++++++++++------
14
1 file changed, 32 insertions(+), 6 deletions(-)
15
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mps2-tz.c
19
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/misc/tz-msc.h"
22
#include "hw/arm/iotkit.h"
23
#include "hw/dma/pl080.h"
24
+#include "hw/ssi/pl022.h"
25
#include "hw/devices.h"
26
#include "net/net.h"
27
#include "hw/core/split-irq.h"
28
@@ -XXX,XX +XXX,XX @@ typedef struct {
29
MPS2FPGAIO fpgaio;
30
TZPPC ppc[5];
31
TZMPC ssram_mpc[3];
32
- UnimplementedDeviceState spi[5];
33
+ PL022State spi[5];
34
UnimplementedDeviceState i2c[4];
35
UnimplementedDeviceState i2s_audio;
36
UnimplementedDeviceState gpio[4];
37
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
38
return sysbus_mmio_get_region(s, 0);
39
}
40
41
+static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
42
+ const char *name, hwaddr size)
43
+{
44
+ /*
45
+ * The AN505 has five PL022 SPI controllers.
46
+ * One of these should have the LCD controller behind it; the others
47
+ * are connected only to the FPGA's "general purpose SPI connector"
48
+ * or "shield" expansion connectors.
49
+ * Note that if we do implement devices behind SPI, the chip select
50
+ * lines are set via the "MISC" register in the MPS2 FPGAIO device.
51
+ */
52
+ PL022State *spi = opaque;
53
+ int i = spi - &mms->spi[0];
54
+ DeviceState *iotkitdev = DEVICE(&mms->iotkit);
55
+ SysBusDevice *s;
56
+
57
+ sysbus_init_child_obj(OBJECT(mms), name, spi, sizeof(mms->spi[0]),
58
+ TYPE_PL022);
59
+ object_property_set_bool(OBJECT(spi), true, "realized", &error_fatal);
60
+ s = SYS_BUS_DEVICE(spi);
61
+ sysbus_connect_irq(s, 0,
62
+ qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 51 + i));
63
+ return sysbus_mmio_get_region(s, 0);
64
+}
65
+
66
static void mps2tz_common_init(MachineState *machine)
67
{
68
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
69
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
70
}, {
71
.name = "apb_ppcexp1",
72
.ports = {
73
- { "spi0", make_unimp_dev, &mms->spi[0], 0x40205000, 0x1000 },
74
- { "spi1", make_unimp_dev, &mms->spi[1], 0x40206000, 0x1000 },
75
- { "spi2", make_unimp_dev, &mms->spi[2], 0x40209000, 0x1000 },
76
- { "spi3", make_unimp_dev, &mms->spi[3], 0x4020a000, 0x1000 },
77
- { "spi4", make_unimp_dev, &mms->spi[4], 0x4020b000, 0x1000 },
78
+ { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
79
+ { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
80
+ { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
81
+ { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
82
+ { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
83
{ "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
84
{ "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
85
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
86
--
87
2.18.0
88
89
diff view generated by jsdifflib
Deleted patch
1
Some of the config register values we were setting for the MPS2 SCC
2
weren't correct:
3
* the SCC_AID bits [23:20] specify the FPGA build target board revision,
4
and the SCC_CFG4 register specifies the actual board revision, so
5
these should have matching values. Claim to be board revision C,
6
consistently -- we had the revision in the wrong part of SCC_AID.
7
* SCC_ID bits [15:4] should be 0x505, not decimal 505
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20180820141116.9118-23-peter.maydell@linaro.org
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
---
13
hw/arm/mps2-tz.c | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mps2-tz.c
19
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
21
sccdev = DEVICE(scc);
22
qdev_set_parent_bus(sccdev, sysbus_get_default());
23
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
24
- qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
25
+ qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
26
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
27
object_property_set_bool(OBJECT(scc), true, "realized", &error_fatal);
28
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
29
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
30
mc->desc = "ARM MPS2 with AN505 FPGA image for Cortex-M33";
31
mmc->fpga_type = FPGA_AN505;
32
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
33
- mmc->scc_id = 0x41040000 | (505 << 4);
34
+ mmc->scc_id = 0x41045050;
35
}
36
37
static const TypeInfo mps2tz_info = {
38
--
39
2.18.0
40
41
diff view generated by jsdifflib
Deleted patch
1
Untabify the arm translate.c. This affects only some lines,
2
mostly comments, in the iwMMXt code. We've never touched
3
that code in years, so it's not going to get fixed up
4
by our "change when touched" process, and a bulk change
5
is not going to be too disruptive.
6
1
7
This commit was produced using Emacs "untabify"; it is
8
a whitespace-only change.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180821165215.29069-2-peter.maydell@linaro.org
12
---
13
target/arm/translate.c | 122 ++++++++++++++++++++---------------------
14
1 file changed, 61 insertions(+), 61 deletions(-)
15
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static inline void gen_mov_vreg_F0(int dp, int reg)
21
tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
22
}
23
24
-#define ARM_CP_RW_BIT    (1 << 20)
25
+#define ARM_CP_RW_BIT (1 << 20)
26
27
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
28
{
29
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
30
wrd = insn & 0xf;
31
rdlo = (insn >> 12) & 0xf;
32
rdhi = (insn >> 16) & 0xf;
33
- if (insn & ARM_CP_RW_BIT) {            /* TMRRC */
34
+ if (insn & ARM_CP_RW_BIT) { /* TMRRC */
35
iwmmxt_load_reg(cpu_V0, wrd);
36
tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
37
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
38
tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
39
- } else {                    /* TMCRR */
40
+ } else { /* TMCRR */
41
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
42
iwmmxt_store_reg(cpu_V0, wrd);
43
gen_op_iwmmxt_set_mup();
44
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
45
return 1;
46
}
47
if (insn & ARM_CP_RW_BIT) {
48
- if ((insn >> 28) == 0xf) {            /* WLDRW wCx */
49
+ if ((insn >> 28) == 0xf) { /* WLDRW wCx */
50
tmp = tcg_temp_new_i32();
51
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
52
iwmmxt_store_creg(wrd, tmp);
53
} else {
54
i = 1;
55
if (insn & (1 << 8)) {
56
- if (insn & (1 << 22)) {        /* WLDRD */
57
+ if (insn & (1 << 22)) { /* WLDRD */
58
gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
59
i = 0;
60
- } else {                /* WLDRW wRd */
61
+ } else { /* WLDRW wRd */
62
tmp = tcg_temp_new_i32();
63
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
64
}
65
} else {
66
tmp = tcg_temp_new_i32();
67
- if (insn & (1 << 22)) {        /* WLDRH */
68
+ if (insn & (1 << 22)) { /* WLDRH */
69
gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
70
- } else {                /* WLDRB */
71
+ } else { /* WLDRB */
72
gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
73
}
74
}
75
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
76
gen_op_iwmmxt_movq_wRn_M0(wrd);
77
}
78
} else {
79
- if ((insn >> 28) == 0xf) {            /* WSTRW wCx */
80
+ if ((insn >> 28) == 0xf) { /* WSTRW wCx */
81
tmp = iwmmxt_load_creg(wrd);
82
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
83
} else {
84
gen_op_iwmmxt_movq_M0_wRn(wrd);
85
tmp = tcg_temp_new_i32();
86
if (insn & (1 << 8)) {
87
- if (insn & (1 << 22)) {        /* WSTRD */
88
+ if (insn & (1 << 22)) { /* WSTRD */
89
gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
90
- } else {                /* WSTRW wRd */
91
+ } else { /* WSTRW wRd */
92
tcg_gen_extrl_i64_i32(tmp, cpu_M0);
93
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
94
}
95
} else {
96
- if (insn & (1 << 22)) {        /* WSTRH */
97
+ if (insn & (1 << 22)) { /* WSTRH */
98
tcg_gen_extrl_i64_i32(tmp, cpu_M0);
99
gen_aa32_st16(s, tmp, addr, get_mem_index(s));
100
- } else {                /* WSTRB */
101
+ } else { /* WSTRB */
102
tcg_gen_extrl_i64_i32(tmp, cpu_M0);
103
gen_aa32_st8(s, tmp, addr, get_mem_index(s));
104
}
105
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
106
return 1;
107
108
switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
109
- case 0x000:                        /* WOR */
110
+ case 0x000: /* WOR */
111
wrd = (insn >> 12) & 0xf;
112
rd0 = (insn >> 0) & 0xf;
113
rd1 = (insn >> 16) & 0xf;
114
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
115
gen_op_iwmmxt_set_mup();
116
gen_op_iwmmxt_set_cup();
117
break;
118
- case 0x011:                        /* TMCR */
119
+ case 0x011: /* TMCR */
120
if (insn & 0xf)
121
return 1;
122
rd = (insn >> 12) & 0xf;
123
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
124
return 1;
125
}
126
break;
127
- case 0x100:                        /* WXOR */
128
+ case 0x100: /* WXOR */
129
wrd = (insn >> 12) & 0xf;
130
rd0 = (insn >> 0) & 0xf;
131
rd1 = (insn >> 16) & 0xf;
132
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
133
gen_op_iwmmxt_set_mup();
134
gen_op_iwmmxt_set_cup();
135
break;
136
- case 0x111:                        /* TMRC */
137
+ case 0x111: /* TMRC */
138
if (insn & 0xf)
139
return 1;
140
rd = (insn >> 12) & 0xf;
141
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
142
tmp = iwmmxt_load_creg(wrd);
143
store_reg(s, rd, tmp);
144
break;
145
- case 0x300:                        /* WANDN */
146
+ case 0x300: /* WANDN */
147
wrd = (insn >> 12) & 0xf;
148
rd0 = (insn >> 0) & 0xf;
149
rd1 = (insn >> 16) & 0xf;
150
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
151
gen_op_iwmmxt_set_mup();
152
gen_op_iwmmxt_set_cup();
153
break;
154
- case 0x200:                        /* WAND */
155
+ case 0x200: /* WAND */
156
wrd = (insn >> 12) & 0xf;
157
rd0 = (insn >> 0) & 0xf;
158
rd1 = (insn >> 16) & 0xf;
159
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
160
gen_op_iwmmxt_set_mup();
161
gen_op_iwmmxt_set_cup();
162
break;
163
- case 0x810: case 0xa10:                /* WMADD */
164
+ case 0x810: case 0xa10: /* WMADD */
165
wrd = (insn >> 12) & 0xf;
166
rd0 = (insn >> 0) & 0xf;
167
rd1 = (insn >> 16) & 0xf;
168
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
169
gen_op_iwmmxt_movq_wRn_M0(wrd);
170
gen_op_iwmmxt_set_mup();
171
break;
172
- case 0x10e: case 0x50e: case 0x90e: case 0xd0e:    /* WUNPCKIL */
173
+ case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
174
wrd = (insn >> 12) & 0xf;
175
rd0 = (insn >> 16) & 0xf;
176
rd1 = (insn >> 0) & 0xf;
177
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
178
gen_op_iwmmxt_set_mup();
179
gen_op_iwmmxt_set_cup();
180
break;
181
- case 0x10c: case 0x50c: case 0x90c: case 0xd0c:    /* WUNPCKIH */
182
+ case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
183
wrd = (insn >> 12) & 0xf;
184
rd0 = (insn >> 16) & 0xf;
185
rd1 = (insn >> 0) & 0xf;
186
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
187
gen_op_iwmmxt_set_mup();
188
gen_op_iwmmxt_set_cup();
189
break;
190
- case 0x012: case 0x112: case 0x412: case 0x512:    /* WSAD */
191
+ case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
192
wrd = (insn >> 12) & 0xf;
193
rd0 = (insn >> 16) & 0xf;
194
rd1 = (insn >> 0) & 0xf;
195
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
196
gen_op_iwmmxt_movq_wRn_M0(wrd);
197
gen_op_iwmmxt_set_mup();
198
break;
199
- case 0x010: case 0x110: case 0x210: case 0x310:    /* WMUL */
200
+ case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
201
wrd = (insn >> 12) & 0xf;
202
rd0 = (insn >> 16) & 0xf;
203
rd1 = (insn >> 0) & 0xf;
204
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
205
gen_op_iwmmxt_movq_wRn_M0(wrd);
206
gen_op_iwmmxt_set_mup();
207
break;
208
- case 0x410: case 0x510: case 0x610: case 0x710:    /* WMAC */
209
+ case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
210
wrd = (insn >> 12) & 0xf;
211
rd0 = (insn >> 16) & 0xf;
212
rd1 = (insn >> 0) & 0xf;
213
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
214
gen_op_iwmmxt_movq_wRn_M0(wrd);
215
gen_op_iwmmxt_set_mup();
216
break;
217
- case 0x006: case 0x406: case 0x806: case 0xc06:    /* WCMPEQ */
218
+ case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
219
wrd = (insn >> 12) & 0xf;
220
rd0 = (insn >> 16) & 0xf;
221
rd1 = (insn >> 0) & 0xf;
222
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
223
gen_op_iwmmxt_set_mup();
224
gen_op_iwmmxt_set_cup();
225
break;
226
- case 0x800: case 0x900: case 0xc00: case 0xd00:    /* WAVG2 */
227
+ case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
228
wrd = (insn >> 12) & 0xf;
229
rd0 = (insn >> 16) & 0xf;
230
rd1 = (insn >> 0) & 0xf;
231
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
232
gen_op_iwmmxt_set_mup();
233
gen_op_iwmmxt_set_cup();
234
break;
235
- case 0x802: case 0x902: case 0xa02: case 0xb02:    /* WALIGNR */
236
+ case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
237
wrd = (insn >> 12) & 0xf;
238
rd0 = (insn >> 16) & 0xf;
239
rd1 = (insn >> 0) & 0xf;
240
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
241
gen_op_iwmmxt_movq_wRn_M0(wrd);
242
gen_op_iwmmxt_set_mup();
243
break;
244
- case 0x601: case 0x605: case 0x609: case 0x60d:    /* TINSR */
245
+ case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
246
if (((insn >> 6) & 3) == 3)
247
return 1;
248
rd = (insn >> 12) & 0xf;
249
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
250
gen_op_iwmmxt_movq_wRn_M0(wrd);
251
gen_op_iwmmxt_set_mup();
252
break;
253
- case 0x107: case 0x507: case 0x907: case 0xd07:    /* TEXTRM */
254
+ case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
255
rd = (insn >> 12) & 0xf;
256
wrd = (insn >> 16) & 0xf;
257
if (rd == 15 || ((insn >> 22) & 3) == 3)
258
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
259
}
260
store_reg(s, rd, tmp);
261
break;
262
- case 0x117: case 0x517: case 0x917: case 0xd17:    /* TEXTRC */
263
+ case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
264
if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
265
return 1;
266
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
267
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
268
gen_set_nzcv(tmp);
269
tcg_temp_free_i32(tmp);
270
break;
271
- case 0x401: case 0x405: case 0x409: case 0x40d:    /* TBCST */
272
+ case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
273
if (((insn >> 6) & 3) == 3)
274
return 1;
275
rd = (insn >> 12) & 0xf;
276
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
277
gen_op_iwmmxt_movq_wRn_M0(wrd);
278
gen_op_iwmmxt_set_mup();
279
break;
280
- case 0x113: case 0x513: case 0x913: case 0xd13:    /* TANDC */
281
+ case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
282
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
283
return 1;
284
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
285
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
286
tcg_temp_free_i32(tmp2);
287
tcg_temp_free_i32(tmp);
288
break;
289
- case 0x01c: case 0x41c: case 0x81c: case 0xc1c:    /* WACC */
290
+ case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
291
wrd = (insn >> 12) & 0xf;
292
rd0 = (insn >> 16) & 0xf;
293
gen_op_iwmmxt_movq_M0_wRn(rd0);
294
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
295
gen_op_iwmmxt_movq_wRn_M0(wrd);
296
gen_op_iwmmxt_set_mup();
297
break;
298
- case 0x115: case 0x515: case 0x915: case 0xd15:    /* TORC */
299
+ case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
300
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
301
return 1;
302
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
303
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
304
tcg_temp_free_i32(tmp2);
305
tcg_temp_free_i32(tmp);
306
break;
307
- case 0x103: case 0x503: case 0x903: case 0xd03:    /* TMOVMSK */
308
+ case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
309
rd = (insn >> 12) & 0xf;
310
rd0 = (insn >> 16) & 0xf;
311
if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
312
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
313
}
314
store_reg(s, rd, tmp);
315
break;
316
- case 0x106: case 0x306: case 0x506: case 0x706:    /* WCMPGT */
317
+ case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
318
case 0x906: case 0xb06: case 0xd06: case 0xf06:
319
wrd = (insn >> 12) & 0xf;
320
rd0 = (insn >> 16) & 0xf;
321
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
322
gen_op_iwmmxt_set_mup();
323
gen_op_iwmmxt_set_cup();
324
break;
325
- case 0x00e: case 0x20e: case 0x40e: case 0x60e:    /* WUNPCKEL */
326
+ case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
327
case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
328
wrd = (insn >> 12) & 0xf;
329
rd0 = (insn >> 16) & 0xf;
330
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
331
gen_op_iwmmxt_set_mup();
332
gen_op_iwmmxt_set_cup();
333
break;
334
- case 0x00c: case 0x20c: case 0x40c: case 0x60c:    /* WUNPCKEH */
335
+ case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
336
case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
337
wrd = (insn >> 12) & 0xf;
338
rd0 = (insn >> 16) & 0xf;
339
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
340
gen_op_iwmmxt_set_mup();
341
gen_op_iwmmxt_set_cup();
342
break;
343
- case 0x204: case 0x604: case 0xa04: case 0xe04:    /* WSRL */
344
+ case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
345
case 0x214: case 0x614: case 0xa14: case 0xe14:
346
if (((insn >> 22) & 3) == 0)
347
return 1;
348
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
349
gen_op_iwmmxt_set_mup();
350
gen_op_iwmmxt_set_cup();
351
break;
352
- case 0x004: case 0x404: case 0x804: case 0xc04:    /* WSRA */
353
+ case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
354
case 0x014: case 0x414: case 0x814: case 0xc14:
355
if (((insn >> 22) & 3) == 0)
356
return 1;
357
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
358
gen_op_iwmmxt_set_mup();
359
gen_op_iwmmxt_set_cup();
360
break;
361
- case 0x104: case 0x504: case 0x904: case 0xd04:    /* WSLL */
362
+ case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
363
case 0x114: case 0x514: case 0x914: case 0xd14:
364
if (((insn >> 22) & 3) == 0)
365
return 1;
366
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
367
gen_op_iwmmxt_set_mup();
368
gen_op_iwmmxt_set_cup();
369
break;
370
- case 0x304: case 0x704: case 0xb04: case 0xf04:    /* WROR */
371
+ case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
372
case 0x314: case 0x714: case 0xb14: case 0xf14:
373
if (((insn >> 22) & 3) == 0)
374
return 1;
375
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
376
gen_op_iwmmxt_set_mup();
377
gen_op_iwmmxt_set_cup();
378
break;
379
- case 0x116: case 0x316: case 0x516: case 0x716:    /* WMIN */
380
+ case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
381
case 0x916: case 0xb16: case 0xd16: case 0xf16:
382
wrd = (insn >> 12) & 0xf;
383
rd0 = (insn >> 16) & 0xf;
384
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
385
gen_op_iwmmxt_movq_wRn_M0(wrd);
386
gen_op_iwmmxt_set_mup();
387
break;
388
- case 0x016: case 0x216: case 0x416: case 0x616:    /* WMAX */
389
+ case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
390
case 0x816: case 0xa16: case 0xc16: case 0xe16:
391
wrd = (insn >> 12) & 0xf;
392
rd0 = (insn >> 16) & 0xf;
393
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
394
gen_op_iwmmxt_movq_wRn_M0(wrd);
395
gen_op_iwmmxt_set_mup();
396
break;
397
- case 0x002: case 0x102: case 0x202: case 0x302:    /* WALIGNI */
398
+ case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
399
case 0x402: case 0x502: case 0x602: case 0x702:
400
wrd = (insn >> 12) & 0xf;
401
rd0 = (insn >> 16) & 0xf;
402
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
403
gen_op_iwmmxt_movq_wRn_M0(wrd);
404
gen_op_iwmmxt_set_mup();
405
break;
406
- case 0x01a: case 0x11a: case 0x21a: case 0x31a:    /* WSUB */
407
+ case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
408
case 0x41a: case 0x51a: case 0x61a: case 0x71a:
409
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
410
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
411
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
412
gen_op_iwmmxt_set_mup();
413
gen_op_iwmmxt_set_cup();
414
break;
415
- case 0x01e: case 0x11e: case 0x21e: case 0x31e:    /* WSHUFH */
416
+ case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
417
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
418
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
419
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
420
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
421
gen_op_iwmmxt_set_mup();
422
gen_op_iwmmxt_set_cup();
423
break;
424
- case 0x018: case 0x118: case 0x218: case 0x318:    /* WADD */
425
+ case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
426
case 0x418: case 0x518: case 0x618: case 0x718:
427
case 0x818: case 0x918: case 0xa18: case 0xb18:
428
case 0xc18: case 0xd18: case 0xe18: case 0xf18:
429
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
430
gen_op_iwmmxt_set_mup();
431
gen_op_iwmmxt_set_cup();
432
break;
433
- case 0x008: case 0x108: case 0x208: case 0x308:    /* WPACK */
434
+ case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
435
case 0x408: case 0x508: case 0x608: case 0x708:
436
case 0x808: case 0x908: case 0xa08: case 0xb08:
437
case 0xc08: case 0xd08: case 0xe08: case 0xf08:
438
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
439
tmp = load_reg(s, rd0);
440
tmp2 = load_reg(s, rd1);
441
switch ((insn >> 16) & 0xf) {
442
- case 0x0:                    /* TMIA */
443
+ case 0x0: /* TMIA */
444
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
445
break;
446
- case 0x8:                    /* TMIAPH */
447
+ case 0x8: /* TMIAPH */
448
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
449
break;
450
- case 0xc: case 0xd: case 0xe: case 0xf:        /* TMIAxy */
451
+ case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
452
if (insn & (1 << 16))
453
tcg_gen_shri_i32(tmp, tmp, 16);
454
if (insn & (1 << 17))
455
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
456
tmp = load_reg(s, rd0);
457
tmp2 = load_reg(s, rd1);
458
switch ((insn >> 16) & 0xf) {
459
- case 0x0:                    /* MIA */
460
+ case 0x0: /* MIA */
461
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
462
break;
463
- case 0x8:                    /* MIAPH */
464
+ case 0x8: /* MIAPH */
465
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
466
break;
467
- case 0xc:                    /* MIABB */
468
- case 0xd:                    /* MIABT */
469
- case 0xe:                    /* MIATB */
470
- case 0xf:                    /* MIATT */
471
+ case 0xc: /* MIABB */
472
+ case 0xd: /* MIABT */
473
+ case 0xe: /* MIATB */
474
+ case 0xf: /* MIATT */
475
if (insn & (1 << 16))
476
tcg_gen_shri_i32(tmp, tmp, 16);
477
if (insn & (1 << 17))
478
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
479
if (acc != 0)
480
return 1;
481
482
- if (insn & ARM_CP_RW_BIT) {            /* MRA */
483
+ if (insn & ARM_CP_RW_BIT) { /* MRA */
484
iwmmxt_load_reg(cpu_V0, acc);
485
tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
486
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
487
tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
488
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
489
- } else {                    /* MAR */
490
+ } else { /* MAR */
491
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
492
iwmmxt_store_reg(cpu_V0, acc);
493
}
494
--
495
2.18.0
496
497
diff view generated by jsdifflib
Deleted patch
1
Untabify the arm iwmmxt_helper.c. This affects only the iwMMXt code.
2
We've never touched that code in years, so it's not going to get
3
fixed up by our "change when touched" process, and a bulk change is
4
not going to be too disruptive.
5
1
6
This commit was produced using Emacs "untabify" (plus one
7
by-hand removal of a space to fix a checkpatch nit); it is
8
a whitespace-only change.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180821165215.29069-3-peter.maydell@linaro.org
12
---
13
target/arm/iwmmxt_helper.c | 234 ++++++++++++++++++-------------------
14
1 file changed, 117 insertions(+), 117 deletions(-)
15
16
diff --git a/target/arm/iwmmxt_helper.c b/target/arm/iwmmxt_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/iwmmxt_helper.c
19
+++ b/target/arm/iwmmxt_helper.c
20
@@ -XXX,XX +XXX,XX @@
21
/* iwMMXt macros extracted from GNU gdb. */
22
23
/* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations. */
24
-#define SIMD8_SET( v, n, b)    ((v != 0) << ((((b) + 1) * 4) + (n)))
25
-#define SIMD16_SET(v, n, h)    ((v != 0) << ((((h) + 1) * 8) + (n)))
26
-#define SIMD32_SET(v, n, w)    ((v != 0) << ((((w) + 1) * 16) + (n)))
27
-#define SIMD64_SET(v, n)    ((v != 0) << (32 + (n)))
28
+#define SIMD8_SET(v, n, b) ((v != 0) << ((((b) + 1) * 4) + (n)))
29
+#define SIMD16_SET(v, n, h) ((v != 0) << ((((h) + 1) * 8) + (n)))
30
+#define SIMD32_SET(v, n, w) ((v != 0) << ((((w) + 1) * 16) + (n)))
31
+#define SIMD64_SET(v, n) ((v != 0) << (32 + (n)))
32
/* Flags to pass as "n" above. */
33
-#define SIMD_NBIT    -1
34
-#define SIMD_ZBIT    -2
35
-#define SIMD_CBIT    -3
36
-#define SIMD_VBIT    -4
37
+#define SIMD_NBIT -1
38
+#define SIMD_ZBIT -2
39
+#define SIMD_CBIT -3
40
+#define SIMD_VBIT -4
41
/* Various status bit macros. */
42
-#define NBIT8(x)    ((x) & 0x80)
43
-#define NBIT16(x)    ((x) & 0x8000)
44
-#define NBIT32(x)    ((x) & 0x80000000)
45
-#define NBIT64(x)    ((x) & 0x8000000000000000ULL)
46
-#define ZBIT8(x)    (((x) & 0xff) == 0)
47
-#define ZBIT16(x)    (((x) & 0xffff) == 0)
48
-#define ZBIT32(x)    (((x) & 0xffffffff) == 0)
49
-#define ZBIT64(x)    (x == 0)
50
+#define NBIT8(x) ((x) & 0x80)
51
+#define NBIT16(x) ((x) & 0x8000)
52
+#define NBIT32(x) ((x) & 0x80000000)
53
+#define NBIT64(x) ((x) & 0x8000000000000000ULL)
54
+#define ZBIT8(x) (((x) & 0xff) == 0)
55
+#define ZBIT16(x) (((x) & 0xffff) == 0)
56
+#define ZBIT32(x) (((x) & 0xffffffff) == 0)
57
+#define ZBIT64(x) (x == 0)
58
/* Sign extension macros. */
59
-#define EXTEND8H(a)    ((uint16_t) (int8_t) (a))
60
-#define EXTEND8(a)    ((uint32_t) (int8_t) (a))
61
-#define EXTEND16(a)    ((uint32_t) (int16_t) (a))
62
-#define EXTEND16S(a)    ((int32_t) (int16_t) (a))
63
-#define EXTEND32(a)    ((uint64_t) (int32_t) (a))
64
+#define EXTEND8H(a) ((uint16_t) (int8_t) (a))
65
+#define EXTEND8(a) ((uint32_t) (int8_t) (a))
66
+#define EXTEND16(a) ((uint32_t) (int16_t) (a))
67
+#define EXTEND16S(a) ((int32_t) (int16_t) (a))
68
+#define EXTEND32(a) ((uint64_t) (int32_t) (a))
69
70
uint64_t HELPER(iwmmxt_maddsq)(uint64_t a, uint64_t b)
71
{
72
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(iwmmxt_macuw)(uint64_t a, uint64_t b)
73
#define NZBIT64(x) \
74
SIMD64_SET(NBIT64(x), SIMD_NBIT) | \
75
SIMD64_SET(ZBIT64(x), SIMD_ZBIT)
76
-#define IWMMXT_OP_UNPACK(S, SH0, SH1, SH2, SH3)            \
77
+#define IWMMXT_OP_UNPACK(S, SH0, SH1, SH2, SH3) \
78
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, b)))(CPUARMState *env, \
79
uint64_t a, uint64_t b) \
80
-{                                \
81
- a =                             \
82
- (((a >> SH0) & 0xff) << 0) | (((b >> SH0) & 0xff) << 8) |    \
83
- (((a >> SH1) & 0xff) << 16) | (((b >> SH1) & 0xff) << 24) |    \
84
- (((a >> SH2) & 0xff) << 32) | (((b >> SH2) & 0xff) << 40) |    \
85
- (((a >> SH3) & 0xff) << 48) | (((b >> SH3) & 0xff) << 56);    \
86
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
87
- NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) |         \
88
- NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) |        \
89
- NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) |        \
90
- NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);        \
91
+{ \
92
+ a = \
93
+ (((a >> SH0) & 0xff) << 0) | (((b >> SH0) & 0xff) << 8) | \
94
+ (((a >> SH1) & 0xff) << 16) | (((b >> SH1) & 0xff) << 24) | \
95
+ (((a >> SH2) & 0xff) << 32) | (((b >> SH2) & 0xff) << 40) | \
96
+ (((a >> SH3) & 0xff) << 48) | (((b >> SH3) & 0xff) << 56); \
97
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
98
+ NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) | \
99
+ NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) | \
100
+ NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) | \
101
+ NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7); \
102
return a; \
103
-}                                \
104
+} \
105
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, w)))(CPUARMState *env, \
106
uint64_t a, uint64_t b) \
107
-{                                \
108
- a =                             \
109
- (((a >> SH0) & 0xffff) << 0) |                \
110
- (((b >> SH0) & 0xffff) << 16) |             \
111
- (((a >> SH2) & 0xffff) << 32) |             \
112
- (((b >> SH2) & 0xffff) << 48);                \
113
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
114
- NZBIT8(a >> 0, 0) | NZBIT8(a >> 16, 1) |        \
115
- NZBIT8(a >> 32, 2) | NZBIT8(a >> 48, 3);        \
116
+{ \
117
+ a = \
118
+ (((a >> SH0) & 0xffff) << 0) | \
119
+ (((b >> SH0) & 0xffff) << 16) | \
120
+ (((a >> SH2) & 0xffff) << 32) | \
121
+ (((b >> SH2) & 0xffff) << 48); \
122
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
123
+ NZBIT8(a >> 0, 0) | NZBIT8(a >> 16, 1) | \
124
+ NZBIT8(a >> 32, 2) | NZBIT8(a >> 48, 3); \
125
return a; \
126
-}                                \
127
+} \
128
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, l)))(CPUARMState *env, \
129
uint64_t a, uint64_t b) \
130
-{                                \
131
- a =                             \
132
- (((a >> SH0) & 0xffffffff) << 0) |            \
133
- (((b >> SH0) & 0xffffffff) << 32);            \
134
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
135
- NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);        \
136
+{ \
137
+ a = \
138
+ (((a >> SH0) & 0xffffffff) << 0) | \
139
+ (((b >> SH0) & 0xffffffff) << 32); \
140
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
141
+ NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1); \
142
return a; \
143
-}                                \
144
+} \
145
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ub)))(CPUARMState *env, \
146
uint64_t x) \
147
-{                                \
148
- x =                             \
149
- (((x >> SH0) & 0xff) << 0) |                \
150
- (((x >> SH1) & 0xff) << 16) |                \
151
- (((x >> SH2) & 0xff) << 32) |                \
152
- (((x >> SH3) & 0xff) << 48);                \
153
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
154
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |        \
155
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);        \
156
+{ \
157
+ x = \
158
+ (((x >> SH0) & 0xff) << 0) | \
159
+ (((x >> SH1) & 0xff) << 16) | \
160
+ (((x >> SH2) & 0xff) << 32) | \
161
+ (((x >> SH3) & 0xff) << 48); \
162
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
163
+ NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) | \
164
+ NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3); \
165
return x; \
166
-}                                \
167
+} \
168
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, uw)))(CPUARMState *env, \
169
uint64_t x) \
170
-{                                \
171
- x =                             \
172
- (((x >> SH0) & 0xffff) << 0) |                \
173
- (((x >> SH2) & 0xffff) << 32);                \
174
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
175
- NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);        \
176
+{ \
177
+ x = \
178
+ (((x >> SH0) & 0xffff) << 0) | \
179
+ (((x >> SH2) & 0xffff) << 32); \
180
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
181
+ NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1); \
182
return x; \
183
-}                                \
184
+} \
185
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ul)))(CPUARMState *env, \
186
uint64_t x) \
187
-{                                \
188
- x = (((x >> SH0) & 0xffffffff) << 0);            \
189
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0);    \
190
+{ \
191
+ x = (((x >> SH0) & 0xffffffff) << 0); \
192
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0); \
193
return x; \
194
-}                                \
195
+} \
196
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sb)))(CPUARMState *env, \
197
uint64_t x) \
198
-{                                \
199
- x =                             \
200
- ((uint64_t) EXTEND8H((x >> SH0) & 0xff) << 0) |     \
201
- ((uint64_t) EXTEND8H((x >> SH1) & 0xff) << 16) |    \
202
- ((uint64_t) EXTEND8H((x >> SH2) & 0xff) << 32) |    \
203
- ((uint64_t) EXTEND8H((x >> SH3) & 0xff) << 48);     \
204
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
205
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |        \
206
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);        \
207
+{ \
208
+ x = \
209
+ ((uint64_t) EXTEND8H((x >> SH0) & 0xff) << 0) | \
210
+ ((uint64_t) EXTEND8H((x >> SH1) & 0xff) << 16) | \
211
+ ((uint64_t) EXTEND8H((x >> SH2) & 0xff) << 32) | \
212
+ ((uint64_t) EXTEND8H((x >> SH3) & 0xff) << 48); \
213
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
214
+ NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) | \
215
+ NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3); \
216
return x; \
217
-}                                \
218
+} \
219
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sw)))(CPUARMState *env, \
220
uint64_t x) \
221
-{                                \
222
- x =                             \
223
- ((uint64_t) EXTEND16((x >> SH0) & 0xffff) << 0) |    \
224
- ((uint64_t) EXTEND16((x >> SH2) & 0xffff) << 32);    \
225
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
226
- NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);        \
227
+{ \
228
+ x = \
229
+ ((uint64_t) EXTEND16((x >> SH0) & 0xffff) << 0) | \
230
+ ((uint64_t) EXTEND16((x >> SH2) & 0xffff) << 32); \
231
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
232
+ NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1); \
233
return x; \
234
-}                                \
235
+} \
236
uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sl)))(CPUARMState *env, \
237
uint64_t x) \
238
-{                                \
239
- x = EXTEND32((x >> SH0) & 0xffffffff);            \
240
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0);    \
241
+{ \
242
+ x = EXTEND32((x >> SH0) & 0xffffffff); \
243
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0); \
244
return x; \
245
}
246
IWMMXT_OP_UNPACK(l, 0, 8, 16, 24)
247
IWMMXT_OP_UNPACK(h, 32, 40, 48, 56)
248
249
-#define IWMMXT_OP_CMP(SUFF, Tb, Tw, Tl, O)            \
250
+#define IWMMXT_OP_CMP(SUFF, Tb, Tw, Tl, O) \
251
uint64_t HELPER(glue(iwmmxt_, glue(SUFF, b)))(CPUARMState *env, \
252
uint64_t a, uint64_t b) \
253
-{                                \
254
- a =                             \
255
- CMP(0, Tb, O, 0xff) | CMP(8, Tb, O, 0xff) |        \
256
- CMP(16, Tb, O, 0xff) | CMP(24, Tb, O, 0xff) |        \
257
- CMP(32, Tb, O, 0xff) | CMP(40, Tb, O, 0xff) |        \
258
- CMP(48, Tb, O, 0xff) | CMP(56, Tb, O, 0xff);        \
259
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
260
- NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) |         \
261
- NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) |        \
262
- NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) |        \
263
- NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);        \
264
+{ \
265
+ a = \
266
+ CMP(0, Tb, O, 0xff) | CMP(8, Tb, O, 0xff) | \
267
+ CMP(16, Tb, O, 0xff) | CMP(24, Tb, O, 0xff) | \
268
+ CMP(32, Tb, O, 0xff) | CMP(40, Tb, O, 0xff) | \
269
+ CMP(48, Tb, O, 0xff) | CMP(56, Tb, O, 0xff); \
270
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
271
+ NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) | \
272
+ NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) | \
273
+ NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) | \
274
+ NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7); \
275
return a; \
276
-}                                \
277
+} \
278
uint64_t HELPER(glue(iwmmxt_, glue(SUFF, w)))(CPUARMState *env, \
279
uint64_t a, uint64_t b) \
280
-{                                \
281
- a = CMP(0, Tw, O, 0xffff) | CMP(16, Tw, O, 0xffff) |    \
282
- CMP(32, Tw, O, 0xffff) | CMP(48, Tw, O, 0xffff);    \
283
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
284
- NZBIT16(a >> 0, 0) | NZBIT16(a >> 16, 1) |        \
285
- NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3);        \
286
+{ \
287
+ a = CMP(0, Tw, O, 0xffff) | CMP(16, Tw, O, 0xffff) | \
288
+ CMP(32, Tw, O, 0xffff) | CMP(48, Tw, O, 0xffff); \
289
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
290
+ NZBIT16(a >> 0, 0) | NZBIT16(a >> 16, 1) | \
291
+ NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3); \
292
return a; \
293
-}                                \
294
+} \
295
uint64_t HELPER(glue(iwmmxt_, glue(SUFF, l)))(CPUARMState *env, \
296
uint64_t a, uint64_t b) \
297
-{                                \
298
- a = CMP(0, Tl, O, 0xffffffff) |                \
299
- CMP(32, Tl, O, 0xffffffff);                \
300
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =            \
301
- NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);        \
302
+{ \
303
+ a = CMP(0, Tl, O, 0xffffffff) | \
304
+ CMP(32, Tl, O, 0xffffffff); \
305
+ env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
306
+ NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1); \
307
return a; \
308
}
309
#define CMP(SHR, TYPE, OPER, MASK) ((((TYPE) ((a >> SHR) & MASK) OPER \
310
--
311
2.18.0
312
313
diff view generated by jsdifflib
Deleted patch
1
Following the bulk conversion of the iwMMXt code, there are
2
just a handful of hard coded tabs in target/arm; fix them.
3
This is a whitespace-only patch.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20180821165215.29069-4-peter.maydell@linaro.org
7
---
8
target/arm/cpu.h | 16 ++++++++--------
9
target/arm/arm-semi.c | 2 +-
10
2 files changed, 9 insertions(+), 9 deletions(-)
11
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ enum arm_cpu_mode {
17
#define ARM_VFP_FPINST2 10
18
19
/* iwMMXt coprocessor control registers. */
20
-#define ARM_IWMMXT_wCID        0
21
-#define ARM_IWMMXT_wCon        1
22
-#define ARM_IWMMXT_wCSSF    2
23
-#define ARM_IWMMXT_wCASF    3
24
-#define ARM_IWMMXT_wCGR0    8
25
-#define ARM_IWMMXT_wCGR1    9
26
-#define ARM_IWMMXT_wCGR2    10
27
-#define ARM_IWMMXT_wCGR3    11
28
+#define ARM_IWMMXT_wCID 0
29
+#define ARM_IWMMXT_wCon 1
30
+#define ARM_IWMMXT_wCSSF 2
31
+#define ARM_IWMMXT_wCASF 3
32
+#define ARM_IWMMXT_wCGR0 8
33
+#define ARM_IWMMXT_wCGR1 9
34
+#define ARM_IWMMXT_wCGR2 10
35
+#define ARM_IWMMXT_wCGR3 11
36
37
/* V7M CCR bits */
38
FIELD(V7M_CCR, NONBASETHRDENA, 0, 1)
39
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/arm-semi.c
42
+++ b/target/arm/arm-semi.c
43
@@ -XXX,XX +XXX,XX @@ static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
44
#ifdef CONFIG_USER_ONLY
45
ts->swi_errno = err;
46
#else
47
-    syscall_err = err;
48
+ syscall_err = err;
49
#endif
50
reg0 = ret;
51
} else {
52
--
53
2.18.0
54
55
diff view generated by jsdifflib
Deleted patch
1
Refactor the fb property setting code so that rather than
2
using a set of pointers to local variables to track
3
whether a config value has been updated in the current
4
mbox and if so what its new value is, we just copy
5
all the current settings of the fb at the start, and
6
then update that copy as we go along, before asking
7
the fb to switch to it at the end.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180814144436.679-3-peter.maydell@linaro.org
12
---
13
include/hw/display/bcm2835_fb.h | 4 +-
14
hw/display/bcm2835_fb.c | 27 ++---------
15
hw/misc/bcm2835_property.c | 80 ++++++++++++++-------------------
16
3 files changed, 37 insertions(+), 74 deletions(-)
17
18
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/display/bcm2835_fb.h
21
+++ b/include/hw/display/bcm2835_fb.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
uint32_t pitch;
24
} BCM2835FBState;
25
26
-void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres,
27
- uint32_t *xoffset, uint32_t *yoffset, uint32_t *bpp,
28
- uint32_t *pixo, uint32_t *alpha);
29
+void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig);
30
31
#endif
32
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/display/bcm2835_fb.c
35
+++ b/hw/display/bcm2835_fb.c
36
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
37
s->lock = false;
38
}
39
40
-void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres,
41
- uint32_t *xoffset, uint32_t *yoffset, uint32_t *bpp,
42
- uint32_t *pixo, uint32_t *alpha)
43
+void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig)
44
{
45
s->lock = true;
46
47
/* TODO: input validation! */
48
- if (xres) {
49
- s->config.xres = *xres;
50
- }
51
- if (yres) {
52
- s->config.yres = *yres;
53
- }
54
- if (xoffset) {
55
- s->config.xoffset = *xoffset;
56
- }
57
- if (yoffset) {
58
- s->config.yoffset = *yoffset;
59
- }
60
- if (bpp) {
61
- s->config.bpp = *bpp;
62
- }
63
- if (pixo) {
64
- s->config.pixo = *pixo;
65
- }
66
- if (alpha) {
67
- s->config.alpha = *alpha;
68
- }
69
+
70
+ s->config = *newconfig;
71
72
/* TODO - Manage properly virtual resolution */
73
74
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/misc/bcm2835_property.c
77
+++ b/hw/misc/bcm2835_property.c
78
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
79
uint32_t tmp;
80
int n;
81
uint32_t offset, length, color;
82
- uint32_t xres, yres, xoffset, yoffset, bpp, pixo, alpha;
83
- uint32_t tmp_xres, tmp_yres, tmp_xoffset, tmp_yoffset;
84
- uint32_t tmp_bpp, tmp_pixo, tmp_alpha;
85
- uint32_t *newxres = NULL, *newyres = NULL, *newxoffset = NULL,
86
- *newyoffset = NULL, *newbpp = NULL, *newpixo = NULL, *newalpha = NULL;
87
+
88
+ /*
89
+ * Copy the current state of the framebuffer config; we will update
90
+ * this copy as we process tags and then ask the framebuffer to use
91
+ * it at the end.
92
+ */
93
+ BCM2835FBConfig fbconfig = s->fbdev->config;
94
+ bool fbconfig_updated = false;
95
96
value &= ~0xf;
97
98
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
99
/* Frame buffer */
100
101
case 0x00040001: /* Allocate buffer */
102
- stl_le_phys(&s->dma_as, value + 12, s->fbdev->config.base);
103
- tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres;
104
- tmp_yres = newyres != NULL ? *newyres : s->fbdev->config.yres;
105
- tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp;
106
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.base);
107
stl_le_phys(&s->dma_as, value + 16,
108
- tmp_xres * tmp_yres * tmp_bpp / 8);
109
+ fbconfig.xres * fbconfig.yres * fbconfig.bpp / 8);
110
resplen = 8;
111
break;
112
case 0x00048001: /* Release buffer */
113
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
114
break;
115
case 0x00040003: /* Get display width/height */
116
case 0x00040004:
117
- tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres;
118
- tmp_yres = newyres != NULL ? *newyres : s->fbdev->config.yres;
119
- stl_le_phys(&s->dma_as, value + 12, tmp_xres);
120
- stl_le_phys(&s->dma_as, value + 16, tmp_yres);
121
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.xres);
122
+ stl_le_phys(&s->dma_as, value + 16, fbconfig.yres);
123
resplen = 8;
124
break;
125
case 0x00044003: /* Test display width/height */
126
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
127
break;
128
case 0x00048003: /* Set display width/height */
129
case 0x00048004:
130
- xres = ldl_le_phys(&s->dma_as, value + 12);
131
- newxres = &xres;
132
- yres = ldl_le_phys(&s->dma_as, value + 16);
133
- newyres = &yres;
134
+ fbconfig.xres = ldl_le_phys(&s->dma_as, value + 12);
135
+ fbconfig.yres = ldl_le_phys(&s->dma_as, value + 16);
136
+ fbconfig_updated = true;
137
resplen = 8;
138
break;
139
case 0x00040005: /* Get depth */
140
- tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp;
141
- stl_le_phys(&s->dma_as, value + 12, tmp_bpp);
142
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp);
143
resplen = 4;
144
break;
145
case 0x00044005: /* Test depth */
146
resplen = 4;
147
break;
148
case 0x00048005: /* Set depth */
149
- bpp = ldl_le_phys(&s->dma_as, value + 12);
150
- newbpp = &bpp;
151
+ fbconfig.bpp = ldl_le_phys(&s->dma_as, value + 12);
152
+ fbconfig_updated = true;
153
resplen = 4;
154
break;
155
case 0x00040006: /* Get pixel order */
156
- tmp_pixo = newpixo != NULL ? *newpixo : s->fbdev->config.pixo;
157
- stl_le_phys(&s->dma_as, value + 12, tmp_pixo);
158
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.pixo);
159
resplen = 4;
160
break;
161
case 0x00044006: /* Test pixel order */
162
resplen = 4;
163
break;
164
case 0x00048006: /* Set pixel order */
165
- pixo = ldl_le_phys(&s->dma_as, value + 12);
166
- newpixo = &pixo;
167
+ fbconfig.pixo = ldl_le_phys(&s->dma_as, value + 12);
168
+ fbconfig_updated = true;
169
resplen = 4;
170
break;
171
case 0x00040007: /* Get alpha */
172
- tmp_alpha = newalpha != NULL ? *newalpha : s->fbdev->config.alpha;
173
- stl_le_phys(&s->dma_as, value + 12, tmp_alpha);
174
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.alpha);
175
resplen = 4;
176
break;
177
case 0x00044007: /* Test pixel alpha */
178
resplen = 4;
179
break;
180
case 0x00048007: /* Set alpha */
181
- alpha = ldl_le_phys(&s->dma_as, value + 12);
182
- newalpha = &alpha;
183
+ fbconfig.alpha = ldl_le_phys(&s->dma_as, value + 12);
184
+ fbconfig_updated = true;
185
resplen = 4;
186
break;
187
case 0x00040008: /* Get pitch */
188
- tmp_xres = newxres != NULL ? *newxres : s->fbdev->config.xres;
189
- tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->config.bpp;
190
- stl_le_phys(&s->dma_as, value + 12, tmp_xres * tmp_bpp / 8);
191
+ stl_le_phys(&s->dma_as, value + 12,
192
+ fbconfig.xres * fbconfig.bpp / 8);
193
resplen = 4;
194
break;
195
case 0x00040009: /* Get virtual offset */
196
- tmp_xoffset = newxoffset != NULL ?
197
- *newxoffset : s->fbdev->config.xoffset;
198
- tmp_yoffset = newyoffset != NULL ?
199
- *newyoffset : s->fbdev->config.yoffset;
200
- stl_le_phys(&s->dma_as, value + 12, tmp_xoffset);
201
- stl_le_phys(&s->dma_as, value + 16, tmp_yoffset);
202
+ stl_le_phys(&s->dma_as, value + 12, fbconfig.xoffset);
203
+ stl_le_phys(&s->dma_as, value + 16, fbconfig.yoffset);
204
resplen = 8;
205
break;
206
case 0x00044009: /* Test virtual offset */
207
resplen = 8;
208
break;
209
case 0x00048009: /* Set virtual offset */
210
- xoffset = ldl_le_phys(&s->dma_as, value + 12);
211
- newxoffset = &xoffset;
212
- yoffset = ldl_le_phys(&s->dma_as, value + 16);
213
- newyoffset = &yoffset;
214
+ fbconfig.xoffset = ldl_le_phys(&s->dma_as, value + 12);
215
+ fbconfig.yoffset = ldl_le_phys(&s->dma_as, value + 16);
216
+ fbconfig_updated = true;
217
resplen = 8;
218
break;
219
case 0x0004000a: /* Get/Test/Set overscan */
220
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
221
}
222
223
/* Reconfigure framebuffer if required */
224
- if (newxres || newyres || newxoffset || newyoffset || newbpp || newpixo
225
- || newalpha) {
226
- bcm2835_fb_reconfigure(s->fbdev, newxres, newyres, newxoffset,
227
- newyoffset, newbpp, newpixo, newalpha);
228
+ if (fbconfig_updated) {
229
+ bcm2835_fb_reconfigure(s->fbdev, &fbconfig);
230
}
231
232
/* Buffer response code */
233
--
234
2.18.0
235
236
diff view generated by jsdifflib
Deleted patch
1
The BCM2835FBState struct has a 'pitch' field which is a
2
cached copy of xres * (bpp >> 3), and a 'size' field which is
3
a cached copy of pitch * yres. However we don't actually do
4
anything with these fields; delete them. We retain the
5
now-unused slots in the VMState struct for migration
6
compatibility.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180814144436.679-4-peter.maydell@linaro.org
11
---
12
include/hw/display/bcm2835_fb.h | 4 ----
13
hw/display/bcm2835_fb.c | 19 ++++++++-----------
14
2 files changed, 8 insertions(+), 15 deletions(-)
15
16
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/display/bcm2835_fb.h
19
+++ b/include/hw/display/bcm2835_fb.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct {
21
bool lock, invalidate, pending;
22
23
BCM2835FBConfig config;
24
-
25
- /* These are just cached values calculated from the config settings */
26
- uint32_t size;
27
- uint32_t pitch;
28
} BCM2835FBState;
29
30
void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig);
31
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/bcm2835_fb.c
34
+++ b/hw/display/bcm2835_fb.c
35
@@ -XXX,XX +XXX,XX @@ static void fb_update_display(void *opaque)
36
37
static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
38
{
39
+ uint32_t pitch;
40
+ uint32_t size;
41
+
42
value &= ~0xf;
43
44
s->lock = true;
45
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
46
47
/* TODO - Manage properly virtual resolution */
48
49
- s->pitch = s->config.xres * (s->config.bpp >> 3);
50
- s->size = s->config.yres * s->pitch;
51
+ pitch = s->config.xres * (s->config.bpp >> 3);
52
+ size = s->config.yres * pitch;
53
54
- stl_le_phys(&s->dma_as, value + 16, s->pitch);
55
+ stl_le_phys(&s->dma_as, value + 16, pitch);
56
stl_le_phys(&s->dma_as, value + 32, s->config.base);
57
- stl_le_phys(&s->dma_as, value + 36, s->size);
58
+ stl_le_phys(&s->dma_as, value + 36, size);
59
60
s->invalidate = true;
61
qemu_console_resize(s->con, s->config.xres, s->config.yres);
62
@@ -XXX,XX +XXX,XX @@ void bcm2835_fb_reconfigure(BCM2835FBState *s, BCM2835FBConfig *newconfig)
63
64
/* TODO - Manage properly virtual resolution */
65
66
- s->pitch = s->config.xres * (s->config.bpp >> 3);
67
- s->size = s->config.yres * s->pitch;
68
-
69
s->invalidate = true;
70
qemu_console_resize(s->con, s->config.xres, s->config.yres);
71
s->lock = false;
72
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_bcm2835_fb = {
73
VMSTATE_UINT32(config.yoffset, BCM2835FBState),
74
VMSTATE_UINT32(config.bpp, BCM2835FBState),
75
VMSTATE_UINT32(config.base, BCM2835FBState),
76
- VMSTATE_UINT32(pitch, BCM2835FBState),
77
- VMSTATE_UINT32(size, BCM2835FBState),
78
+ VMSTATE_UNUSED(8), /* Was pitch and size */
79
VMSTATE_UINT32(config.pixo, BCM2835FBState),
80
VMSTATE_UINT32(config.alpha, BCM2835FBState),
81
VMSTATE_END_OF_LIST()
82
@@ -XXX,XX +XXX,XX @@ static void bcm2835_fb_reset(DeviceState *dev)
83
s->config.xoffset = 0;
84
s->config.yoffset = 0;
85
s->config.base = s->vcram_base + BCM2835_FB_OFFSET;
86
- s->pitch = s->config.xres * (s->config.bpp >> 3);
87
- s->size = s->config.yres * s->pitch;
88
89
s->invalidate = true;
90
s->lock = false;
91
--
92
2.18.0
93
94
diff view generated by jsdifflib