1
The following changes since commit 7e7eb9f852a46b51a71ae9d82590b2e4d28827ee:
1
target-arm queue: I have a lot more still in my to-review
2
queue, but my rule of thumb is when I get to 50 patches or
3
so to send out what I have.
2
4
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-01-28' into staging (2021-01-28 22:43:18 +0000)
5
thanks
6
-- PMM
7
8
The following changes since commit 9a7beaad3dbba982f7a461d676b55a5c3851d312:
9
10
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210304' into staging (2021-03-05 10:47:46 +0000)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210129
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210305
8
15
9
for you to fetch changes up to 11749122e1a86866591306d43603d2795a3dea1a:
16
for you to fetch changes up to 2c669ff88ec6733420a000103a2b8b9e93df4945:
10
17
11
hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS (2021-01-29 10:47:29 +0000)
18
hw/arm/mps2: Update old infocenter.arm.com URLs (2021-03-05 15:17:38 +0000)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
* sbsa-ref: remove cortex-a53 from list of supported cpus
15
* Implement ID_PFR2
22
* sbsa-ref: add 'max' to list of allowed cpus
16
* Conditionalize DBGDIDR
23
* target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
17
* rename xlnx-zcu102.canbusN properties
24
* npcm7xx: add EMC model
18
* provide powerdown/reset mechanism for secure firmware on 'virt' board
25
* xlnx-zynqmp: Remove obsolete 'has_rpu' property
19
* hw/misc: Fix arith overflow in NPCM7XX PWM module
26
* target/arm: Speed up aarch64 TBL/TBX
20
* target/arm: Replace magic value by MMU_DATA_LOAD definition
27
* virtio-mmio: improve virtio-mmio get_dev_path alog
21
* configure: fix preadv errors on Catalina macOS with new XCode
28
* target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
22
* Various configure and other cleanups in preparation for iOS support
29
* target/arm: Restrict v8M IDAU to TCG
23
* hvf: Add hypervisor entitlement to output binaries (needed for Big Sur)
30
* target/arm/cpu: Update coding style to make checkpatch.pl happy
24
* Implement pvpanic-pci device
31
* musicpal, tc6393xb, omap_lcdc, tcx: drop dead code for non-32-bit-RGB surfaces
25
* Convert the CMSDK timer devices to the Clock framework
32
* Add new board: mps3-an524
26
33
27
----------------------------------------------------------------
34
----------------------------------------------------------------
28
Alexander Graf (1):
35
Doug Evans (3):
29
hvf: Add hypervisor entitlement to output binaries
36
hw/net: Add npcm7xx emc model
37
hw/arm: Add npcm7xx emc model
38
tests/qtests: Add npcm7xx emc model test
30
39
31
Hao Wu (1):
40
Marcin Juszkiewicz (2):
32
hw/misc: Fix arith overflow in NPCM7XX PWM module
41
sbsa-ref: remove cortex-a53 from list of supported cpus
42
sbsa-ref: add 'max' to list of allowed cpus
33
43
34
Joelle van Dyne (7):
44
Peter Collingbourne (1):
35
configure: cross-compiling with empty cross_prefix
45
target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
36
osdep: build with non-working system() function
37
darwin: remove redundant dependency declaration
38
darwin: fix cross-compiling for Darwin
39
configure: cross compile should use x86_64 cpu_family
40
darwin: detect CoreAudio for build
41
darwin: remove 64-bit build detection on 32-bit OS
42
46
43
Maxim Uvarov (3):
47
Peter Maydell (34):
44
hw: gpio: implement gpio-pwr driver for qemu reset/poweroff
48
hw/arm/musicpal: Remove dead code for non-32-bit-RGB surfaces
45
arm-virt: refactor gpios creation
49
hw/display/tc6393xb: Remove dead code for handling non-32bpp surfaces
46
arm-virt: add secure pl061 for reset/power down
50
hw/display/tc6393xb: Expand out macros in template header
51
hw/display/tc6393xb: Inline tc6393xb_draw_graphic32() at its callsite
52
hw/display/omap_lcdc: Expand out macros in template header
53
hw/display/omap_lcdc: Drop broken bigendian ifdef
54
hw/display/omap_lcdc: Fix coding style issues in template header
55
hw/display/omap_lcdc: Inline template header into C file
56
hw/display/omap_lcdc: Delete unnecessary macro
57
hw/display/tcx: Drop unnecessary code for handling BGR format outputs
58
hw/arm/mps2-tz: Make SYSCLK frequency board-specific
59
hw/misc/mps2-scc: Support configurable number of OSCCLK values
60
hw/arm/mps2-tz: Correct the OSCCLK settings for mps2-an505 and mps2-an511
61
hw/arm/mps2-tz: Make the OSCCLK settings be configurable per-board
62
hw/misc/mps2-fpgaio: Make number of LEDs configurable by board
63
hw/misc/mps2-fpgaio: Support SWITCH register
64
hw/arm/mps2-tz: Make FPGAIO switch and LED config per-board
65
hw/arm/mps2-tz: Condition IRQ splitting on number of CPUs, not board type
66
hw/arm/mps2-tz: Make number of IRQs board-specific
67
hw/misc/mps2-scc: Implement CFG_REG5 and CFG_REG6 for MPS3 AN524
68
hw/arm/mps2-tz: Correct wrong interrupt numbers for DMA and SPI
69
hw/arm/mps2-tz: Allow PPCPortInfo structures to specify device interrupts
70
hw/arm/mps2-tz: Move device IRQ info to data structures
71
hw/arm/mps2-tz: Size the uart-irq-orgate based on the number of UARTs
72
hw/arm/mps2-tz: Allow boards to have different PPCInfo data
73
hw/arm/mps2-tz: Make RAM arrangement board-specific
74
hw/arm/mps2-tz: Set MachineClass default_ram info from RAMInfo data
75
hw/arm/mps2-tz: Support ROMs as well as RAMs
76
hw/arm/mps2-tz: Get armv7m_load_kernel() size argument from RAMInfo
77
hw/arm/mps2-tz: Add new mps3-an524 board
78
hw/arm/mps2-tz: Stub out USB controller for mps3-an524
79
hw/arm/mps2-tz: Provide PL031 RTC on mps3-an524
80
docs/system/arm/mps2.rst: Document the new mps3-an524 board
81
hw/arm/mps2: Update old infocenter.arm.com URLs
47
82
48
Mihai Carabas (4):
83
Philippe Mathieu-Daudé (4):
49
hw/misc/pvpanic: split-out generic and bus dependent code
84
hw/arm/xlnx-zynqmp: Remove obsolete 'has_rpu' property
50
hw/misc/pvpanic: add PCI interface support
85
hw/i2c/npcm7xx_smbus: Simplify npcm7xx_smbus_init()
51
pvpanic : update pvpanic spec document
86
target/arm: Restrict v8M IDAU to TCG
52
tests/qtest: add a test case for pvpanic-pci
87
target/arm/cpu: Update coding style to make checkpatch.pl happy
53
88
54
Paolo Bonzini (1):
89
Rebecca Cran (3):
55
arm: rename xlnx-zcu102.canbusN properties
90
target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
91
target/arm: Enable FEAT_SSBS for "max" AARCH64 CPU
92
target/arm: Set ID_PFR2.SSBS to 1 for "max" 32-bit CPU
56
93
57
Peter Maydell (26):
94
Richard Henderson (1):
58
configure: Move preadv check to meson.build
95
target/arm: Speed up aarch64 TBL/TBX
59
ptimer: Add new ptimer_set_period_from_clock() function
60
clock: Add new clock_has_source() function
61
tests: Add a simple test of the CMSDK APB timer
62
tests: Add a simple test of the CMSDK APB watchdog
63
tests: Add a simple test of the CMSDK APB dual timer
64
hw/timer/cmsdk-apb-timer: Rename CMSDKAPBTIMER struct to CMSDKAPBTimer
65
hw/timer/cmsdk-apb-timer: Add Clock input
66
hw/timer/cmsdk-apb-dualtimer: Add Clock input
67
hw/watchdog/cmsdk-apb-watchdog: Add Clock input
68
hw/arm/armsse: Rename "MAINCLK" property to "MAINCLK_FRQ"
69
hw/arm/armsse: Wire up clocks
70
hw/arm/mps2: Inline CMSDK_APB_TIMER creation
71
hw/arm/mps2: Create and connect SYSCLK Clock
72
hw/arm/mps2-tz: Create and connect ARMSSE Clocks
73
hw/arm/musca: Create and connect ARMSSE Clocks
74
hw/arm/stellaris: Convert SSYS to QOM device
75
hw/arm/stellaris: Create Clock input for watchdog
76
hw/timer/cmsdk-apb-timer: Convert to use Clock input
77
hw/timer/cmsdk-apb-dualtimer: Convert to use Clock input
78
hw/watchdog/cmsdk-apb-watchdog: Convert to use Clock input
79
tests/qtest/cmsdk-apb-watchdog-test: Test clock changes
80
hw/arm/armsse: Use Clock to set system_clock_scale
81
arm: Don't set freq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
82
arm: Remove frq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
83
hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS
84
96
85
Philippe Mathieu-Daudé (1):
97
schspa (1):
86
target/arm: Replace magic value by MMU_DATA_LOAD definition
98
virtio-mmio: improve virtio-mmio get_dev_path alog
87
99
88
Richard Henderson (2):
100
docs/system/arm/mps2.rst | 24 +-
89
target/arm: Implement ID_PFR2
101
docs/system/arm/nuvoton.rst | 3 +-
90
target/arm: Conditionalize DBGDIDR
102
hw/display/omap_lcd_template.h | 169 --------
103
hw/display/tc6393xb_template.h | 72 ----
104
include/hw/arm/armsse.h | 4 +-
105
include/hw/arm/npcm7xx.h | 2 +
106
include/hw/arm/xlnx-zynqmp.h | 2 -
107
include/hw/misc/armsse-cpuid.h | 2 +-
108
include/hw/misc/armsse-mhu.h | 2 +-
109
include/hw/misc/iotkit-secctl.h | 2 +-
110
include/hw/misc/iotkit-sysctl.h | 2 +-
111
include/hw/misc/iotkit-sysinfo.h | 2 +-
112
include/hw/misc/mps2-fpgaio.h | 8 +-
113
include/hw/misc/mps2-scc.h | 10 +-
114
include/hw/net/npcm7xx_emc.h | 286 +++++++++++++
115
include/ui/console.h | 10 -
116
target/arm/cpu.h | 15 +-
117
target/arm/helper-a64.h | 2 +-
118
target/arm/internals.h | 6 +
119
hw/arm/mps2-tz.c | 632 +++++++++++++++++++++++-----
120
hw/arm/mps2.c | 5 +
121
hw/arm/musicpal.c | 64 ++-
122
hw/arm/npcm7xx.c | 50 ++-
123
hw/arm/sbsa-ref.c | 2 +-
124
hw/arm/xlnx-zynqmp.c | 6 -
125
hw/display/omap_lcdc.c | 129 +++++-
126
hw/display/tc6393xb.c | 48 +--
127
hw/display/tcx.c | 31 +-
128
hw/i2c/npcm7xx_smbus.c | 1 -
129
hw/misc/armsse-cpuid.c | 2 +-
130
hw/misc/armsse-mhu.c | 2 +-
131
hw/misc/iotkit-sysctl.c | 2 +-
132
hw/misc/iotkit-sysinfo.c | 2 +-
133
hw/misc/mps2-fpgaio.c | 43 +-
134
hw/misc/mps2-scc.c | 93 ++++-
135
hw/net/npcm7xx_emc.c | 857 ++++++++++++++++++++++++++++++++++++++
136
hw/virtio/virtio-mmio.c | 13 +-
137
target/arm/cpu.c | 23 +-
138
target/arm/cpu64.c | 5 +
139
target/arm/cpu_tcg.c | 8 +
140
target/arm/helper-a64.c | 32 --
141
target/arm/helper.c | 39 +-
142
target/arm/mte_helper.c | 13 +-
143
target/arm/translate-a64.c | 70 +---
144
target/arm/vec_helper.c | 48 +++
145
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++++++++
146
hw/net/meson.build | 1 +
147
hw/net/trace-events | 17 +
148
tests/qtest/meson.build | 3 +-
149
49 files changed, 3098 insertions(+), 628 deletions(-)
150
delete mode 100644 hw/display/omap_lcd_template.h
151
delete mode 100644 hw/display/tc6393xb_template.h
152
create mode 100644 include/hw/net/npcm7xx_emc.h
153
create mode 100644 hw/net/npcm7xx_emc.c
154
create mode 100644 tests/qtest/npcm7xx_emc-test.c
91
155
92
docs/devel/clocks.rst | 16 +++
93
docs/specs/pci-ids.txt | 1 +
94
docs/specs/pvpanic.txt | 13 ++-
95
docs/system/arm/virt.rst | 2 +
96
configure | 78 ++++++++------
97
meson.build | 34 ++++++-
98
include/hw/arm/armsse.h | 14 ++-
99
include/hw/arm/virt.h | 2 +
100
include/hw/clock.h | 15 +++
101
include/hw/misc/pvpanic.h | 24 ++++-
102
include/hw/pci/pci.h | 1 +
103
include/hw/ptimer.h | 22 ++++
104
include/hw/timer/cmsdk-apb-dualtimer.h | 5 +-
105
include/hw/timer/cmsdk-apb-timer.h | 34 ++-----
106
include/hw/watchdog/cmsdk-apb-watchdog.h | 5 +-
107
include/qemu/osdep.h | 12 +++
108
include/qemu/typedefs.h | 1 +
109
target/arm/cpu.h | 1 +
110
hw/arm/armsse.c | 48 ++++++---
111
hw/arm/mps2-tz.c | 14 ++-
112
hw/arm/mps2.c | 28 ++++-
113
hw/arm/musca.c | 13 ++-
114
hw/arm/stellaris.c | 170 +++++++++++++++++++++++--------
115
hw/arm/virt.c | 111 ++++++++++++++++----
116
hw/arm/xlnx-zcu102.c | 4 +-
117
hw/core/ptimer.c | 34 +++++++
118
hw/gpio/gpio_pwr.c | 70 +++++++++++++
119
hw/misc/npcm7xx_pwm.c | 23 ++++-
120
hw/misc/pvpanic-isa.c | 94 +++++++++++++++++
121
hw/misc/pvpanic-pci.c | 94 +++++++++++++++++
122
hw/misc/pvpanic.c | 85 ++--------------
123
hw/timer/cmsdk-apb-dualtimer.c | 53 +++++++---
124
hw/timer/cmsdk-apb-timer.c | 55 +++++-----
125
hw/watchdog/cmsdk-apb-watchdog.c | 29 ++++--
126
target/arm/helper.c | 27 +++--
127
target/arm/kvm64.c | 2 +
128
tests/qtest/cmsdk-apb-dualtimer-test.c | 130 +++++++++++++++++++++++
129
tests/qtest/cmsdk-apb-timer-test.c | 75 ++++++++++++++
130
tests/qtest/cmsdk-apb-watchdog-test.c | 131 ++++++++++++++++++++++++
131
tests/qtest/npcm7xx_pwm-test.c | 4 +-
132
tests/qtest/pvpanic-pci-test.c | 94 +++++++++++++++++
133
tests/qtest/xlnx-can-test.c | 30 +++---
134
MAINTAINERS | 3 +
135
accel/hvf/entitlements.plist | 8 ++
136
hw/arm/Kconfig | 1 +
137
hw/gpio/Kconfig | 3 +
138
hw/gpio/meson.build | 1 +
139
hw/i386/Kconfig | 2 +-
140
hw/misc/Kconfig | 12 ++-
141
hw/misc/meson.build | 4 +-
142
scripts/entitlement.sh | 13 +++
143
tests/qtest/meson.build | 6 +-
144
52 files changed, 1432 insertions(+), 319 deletions(-)
145
create mode 100644 hw/gpio/gpio_pwr.c
146
create mode 100644 hw/misc/pvpanic-isa.c
147
create mode 100644 hw/misc/pvpanic-pci.c
148
create mode 100644 tests/qtest/cmsdk-apb-dualtimer-test.c
149
create mode 100644 tests/qtest/cmsdk-apb-timer-test.c
150
create mode 100644 tests/qtest/cmsdk-apb-watchdog-test.c
151
create mode 100644 tests/qtest/pvpanic-pci-test.c
152
create mode 100644 accel/hvf/entitlements.plist
153
create mode 100755 scripts/entitlement.sh
154
diff view generated by jsdifflib
1
From: Mihai Carabas <mihai.carabas@oracle.com>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Add a test case for pvpanic-pci device. The scenario is the same as pvpanic
3
Cortex-A53 supports 40bits of address space. sbsa-ref's memory starts
4
ISA device, but is using the PCI bus.
4
above this limit.
5
5
6
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Acked-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Acked-by: Leif Lindholm <leif@nuviainc.com>
9
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
9
Message-id: 20210216150122.3830863-2-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
tests/qtest/pvpanic-pci-test.c | 94 ++++++++++++++++++++++++++++++++++
12
hw/arm/sbsa-ref.c | 1 -
13
tests/qtest/meson.build | 1 +
13
1 file changed, 1 deletion(-)
14
2 files changed, 95 insertions(+)
15
create mode 100644 tests/qtest/pvpanic-pci-test.c
16
14
17
diff --git a/tests/qtest/pvpanic-pci-test.c b/tests/qtest/pvpanic-pci-test.c
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/tests/qtest/pvpanic-pci-test.c
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * QTest testcase for PV Panic PCI device
25
+ *
26
+ * Copyright (C) 2020 Oracle
27
+ *
28
+ * Authors:
29
+ * Mihai Carabas <mihai.carabas@oracle.com>
30
+ *
31
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
32
+ * See the COPYING file in the top-level directory.
33
+ *
34
+ */
35
+
36
+#include "qemu/osdep.h"
37
+#include "libqos/libqtest.h"
38
+#include "qapi/qmp/qdict.h"
39
+#include "libqos/pci.h"
40
+#include "libqos/pci-pc.h"
41
+#include "hw/pci/pci_regs.h"
42
+
43
+static void test_panic_nopause(void)
44
+{
45
+ uint8_t val;
46
+ QDict *response, *data;
47
+ QTestState *qts;
48
+ QPCIBus *pcibus;
49
+ QPCIDevice *dev;
50
+ QPCIBar bar;
51
+
52
+ qts = qtest_init("-device pvpanic-pci,addr=04.0 -action panic=none");
53
+ pcibus = qpci_new_pc(qts, NULL);
54
+ dev = qpci_device_find(pcibus, QPCI_DEVFN(0x4, 0x0));
55
+ qpci_device_enable(dev);
56
+ bar = qpci_iomap(dev, 0, NULL);
57
+
58
+ qpci_memread(dev, bar, 0, &val, sizeof(val));
59
+ g_assert_cmpuint(val, ==, 3);
60
+
61
+ val = 1;
62
+ qpci_memwrite(dev, bar, 0, &val, sizeof(val));
63
+
64
+ response = qtest_qmp_eventwait_ref(qts, "GUEST_PANICKED");
65
+ g_assert(qdict_haskey(response, "data"));
66
+ data = qdict_get_qdict(response, "data");
67
+ g_assert(qdict_haskey(data, "action"));
68
+ g_assert_cmpstr(qdict_get_str(data, "action"), ==, "run");
69
+ qobject_unref(response);
70
+
71
+ qtest_quit(qts);
72
+}
73
+
74
+static void test_panic(void)
75
+{
76
+ uint8_t val;
77
+ QDict *response, *data;
78
+ QTestState *qts;
79
+ QPCIBus *pcibus;
80
+ QPCIDevice *dev;
81
+ QPCIBar bar;
82
+
83
+ qts = qtest_init("-device pvpanic-pci,addr=04.0 -action panic=pause");
84
+ pcibus = qpci_new_pc(qts, NULL);
85
+ dev = qpci_device_find(pcibus, QPCI_DEVFN(0x4, 0x0));
86
+ qpci_device_enable(dev);
87
+ bar = qpci_iomap(dev, 0, NULL);
88
+
89
+ qpci_memread(dev, bar, 0, &val, sizeof(val));
90
+ g_assert_cmpuint(val, ==, 3);
91
+
92
+ val = 1;
93
+ qpci_memwrite(dev, bar, 0, &val, sizeof(val));
94
+
95
+ response = qtest_qmp_eventwait_ref(qts, "GUEST_PANICKED");
96
+ g_assert(qdict_haskey(response, "data"));
97
+ data = qdict_get_qdict(response, "data");
98
+ g_assert(qdict_haskey(data, "action"));
99
+ g_assert_cmpstr(qdict_get_str(data, "action"), ==, "pause");
100
+ qobject_unref(response);
101
+
102
+ qtest_quit(qts);
103
+}
104
+
105
+int main(int argc, char **argv)
106
+{
107
+ int ret;
108
+
109
+ g_test_init(&argc, &argv, NULL);
110
+ qtest_add_func("/pvpanic-pci/panic", test_panic);
111
+ qtest_add_func("/pvpanic-pci/panic-nopause", test_panic_nopause);
112
+
113
+ ret = g_test_run();
114
+
115
+ return ret;
116
+}
117
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
118
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
119
--- a/tests/qtest/meson.build
17
--- a/hw/arm/sbsa-ref.c
120
+++ b/tests/qtest/meson.build
18
+++ b/hw/arm/sbsa-ref.c
121
@@ -XXX,XX +XXX,XX @@ qtests_i386 = \
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
122
config_all_devices.has_key('CONFIG_ISA_IPMI_BT') ? ['ipmi-bt-test'] : []) + \
20
};
123
(config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \
21
124
(config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \
22
static const char * const valid_cpus[] = {
125
+ (config_all_devices.has_key('CONFIG_PVPANIC_PCI') ? ['pvpanic-pci-test'] : []) + \
23
- ARM_CPU_TYPE_NAME("cortex-a53"),
126
(config_all_devices.has_key('CONFIG_HDA') ? ['intel-hda-test'] : []) + \
24
ARM_CPU_TYPE_NAME("cortex-a57"),
127
(config_all_devices.has_key('CONFIG_I82801B11') ? ['i82801b11-test'] : []) + \
25
ARM_CPU_TYPE_NAME("cortex-a72"),
128
(config_all_devices.has_key('CONFIG_IOH3420') ? ['ioh3420-test'] : []) + \
26
};
129
--
27
--
130
2.20.1
28
2.20.1
131
29
132
30
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
In macOS 11, QEMU only gets access to Hypervisor.framework if it has the
3
Let add 'max' cpu while work goes on adding newer CPU types than
4
respective entitlement. Add an entitlement template and automatically self
4
Cortex-A72. This allows us to check SVE etc support.
5
sign and apply the entitlement in the build.
6
5
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
8
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
7
Acked-by: Leif Lindholm <leif@nuviainc.com>
9
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210216150122.3830863-3-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
meson.build | 29 +++++++++++++++++++++++++----
12
hw/arm/sbsa-ref.c | 1 +
13
accel/hvf/entitlements.plist | 8 ++++++++
13
1 file changed, 1 insertion(+)
14
scripts/entitlement.sh | 13 +++++++++++++
15
3 files changed, 46 insertions(+), 4 deletions(-)
16
create mode 100644 accel/hvf/entitlements.plist
17
create mode 100755 scripts/entitlement.sh
18
14
19
diff --git a/meson.build b/meson.build
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/meson.build
17
--- a/hw/arm/sbsa-ref.c
22
+++ b/meson.build
18
+++ b/hw/arm/sbsa-ref.c
23
@@ -XXX,XX +XXX,XX @@ foreach target : target_dirs
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
24
}]
20
static const char * const valid_cpus[] = {
25
endif
21
ARM_CPU_TYPE_NAME("cortex-a57"),
26
foreach exe: execs
22
ARM_CPU_TYPE_NAME("cortex-a72"),
27
- emulators += {exe['name']:
23
+ ARM_CPU_TYPE_NAME("max"),
28
- executable(exe['name'], exe['sources'],
24
};
29
- install: true,
25
30
+ exe_name = exe['name']
26
static bool cpu_type_valid(const char *cpu)
31
+ exe_sign = 'CONFIG_HVF' in config_target
32
+ if exe_sign
33
+ exe_name += '-unsigned'
34
+ endif
35
+
36
+ emulator = executable(exe_name, exe['sources'],
37
+ install: not exe_sign,
38
c_args: c_args,
39
dependencies: arch_deps + deps + exe['dependencies'],
40
objects: lib.extract_all_objects(recursive: true),
41
@@ -XXX,XX +XXX,XX @@ foreach target : target_dirs
42
link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
43
link_args: link_args,
44
gui_app: exe['gui'])
45
- }
46
+
47
+ if exe_sign
48
+ emulators += {exe['name'] : custom_target(exe['name'],
49
+ install: true,
50
+ install_dir: get_option('bindir'),
51
+ depends: emulator,
52
+ output: exe['name'],
53
+ command: [
54
+ meson.current_source_dir() / 'scripts/entitlement.sh',
55
+ meson.current_build_dir() / exe_name,
56
+ meson.current_build_dir() / exe['name'],
57
+ meson.current_source_dir() / 'accel/hvf/entitlements.plist'
58
+ ])
59
+ }
60
+ else
61
+ emulators += {exe['name']: emulator}
62
+ endif
63
64
if 'CONFIG_TRACE_SYSTEMTAP' in config_host
65
foreach stp: [
66
diff --git a/accel/hvf/entitlements.plist b/accel/hvf/entitlements.plist
67
new file mode 100644
68
index XXXXXXX..XXXXXXX
69
--- /dev/null
70
+++ b/accel/hvf/entitlements.plist
71
@@ -XXX,XX +XXX,XX @@
72
+<?xml version="1.0" encoding="UTF-8"?>
73
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
74
+<plist version="1.0">
75
+<dict>
76
+ <key>com.apple.security.hypervisor</key>
77
+ <true/>
78
+</dict>
79
+</plist>
80
diff --git a/scripts/entitlement.sh b/scripts/entitlement.sh
81
new file mode 100755
82
index XXXXXXX..XXXXXXX
83
--- /dev/null
84
+++ b/scripts/entitlement.sh
85
@@ -XXX,XX +XXX,XX @@
86
+#!/bin/sh -e
87
+#
88
+# Helper script for the build process to apply entitlements
89
+
90
+SRC="$1"
91
+DST="$2"
92
+ENTITLEMENT="$3"
93
+
94
+trap 'rm "$DST.tmp"' exit
95
+cp -af "$SRC" "$DST.tmp"
96
+codesign --entitlements "$ENTITLEMENT" --force -s - "$DST.tmp"
97
+mv "$DST.tmp" "$DST"
98
+trap '' exit
99
--
27
--
100
2.20.1
28
2.20.1
101
29
102
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
This was defined at some point before ARMv8.4, and will
3
Add support for FEAT_SSBS. SSBS (Speculative Store Bypass Safe) is an
4
shortly be used by new processor descriptions.
4
optional feature in ARMv8.0, and mandatory in ARMv8.5.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210120204400.1056582-1-richard.henderson@linaro.org
8
Message-id: 20210216224543.16142-2-rebecca@nuviainc.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/cpu.h | 1 +
11
target/arm/cpu.h | 15 ++++++++++++++-
12
target/arm/helper.c | 4 ++--
12
target/arm/internals.h | 6 ++++++
13
target/arm/kvm64.c | 2 ++
13
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
14
3 files changed, 5 insertions(+), 2 deletions(-)
14
target/arm/translate-a64.c | 12 ++++++++++++
15
4 files changed, 69 insertions(+), 1 deletion(-)
15
16
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
21
uint32_t id_mmfr4;
22
#define SCTLR_TE (1U << 30) /* AArch32 only */
22
uint32_t id_pfr0;
23
#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
23
uint32_t id_pfr1;
24
#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
24
+ uint32_t id_pfr2;
25
+#define SCTLR_DSSBS_32 (1U << 31) /* v8.5, AArch32 only */
25
uint32_t mvfr0;
26
#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
26
uint32_t mvfr1;
27
#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
27
uint32_t mvfr2;
28
#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
29
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
30
#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
31
#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
32
#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
33
-#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
34
+#define SCTLR_DSSBS_64 (1ULL << 44) /* v8.5, AArch64 only */
35
36
#define CPTR_TCPAC (1U << 31)
37
#define CPTR_TTA (1U << 20)
38
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
39
#define CPSR_IL (1U << 20)
40
#define CPSR_DIT (1U << 21)
41
#define CPSR_PAN (1U << 22)
42
+#define CPSR_SSBS (1U << 23)
43
#define CPSR_J (1U << 24)
44
#define CPSR_IT_0_1 (3U << 25)
45
#define CPSR_Q (1U << 27)
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
47
#define PSTATE_A (1U << 8)
48
#define PSTATE_D (1U << 9)
49
#define PSTATE_BTYPE (3U << 10)
50
+#define PSTATE_SSBS (1U << 12)
51
#define PSTATE_IL (1U << 20)
52
#define PSTATE_SS (1U << 21)
53
#define PSTATE_PAN (1U << 22)
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
55
return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
56
}
57
58
+static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
59
+{
60
+ return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
61
+}
62
+
63
/*
64
* 64-bit feature tests via id registers.
65
*/
66
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
67
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
68
}
69
70
+static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
71
+{
72
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
73
+}
74
+
75
/*
76
* Feature tests for "does this exist in either 32-bit or 64-bit?"
77
*/
78
diff --git a/target/arm/internals.h b/target/arm/internals.h
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/internals.h
81
+++ b/target/arm/internals.h
82
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
83
if (isar_feature_aa32_dit(id)) {
84
valid |= CPSR_DIT;
85
}
86
+ if (isar_feature_aa32_ssbs(id)) {
87
+ valid |= CPSR_SSBS;
88
+ }
89
90
return valid;
91
}
92
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
93
if (isar_feature_aa64_dit(id)) {
94
valid |= PSTATE_DIT;
95
}
96
+ if (isar_feature_aa64_ssbs(id)) {
97
+ valid |= PSTATE_SSBS;
98
+ }
99
if (isar_feature_aa64_mte(id)) {
100
valid |= PSTATE_TCO;
101
}
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
102
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
104
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
105
+++ b/target/arm/helper.c
106
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dit_reginfo = {
107
.readfn = aa64_dit_read, .writefn = aa64_dit_write
108
};
109
110
+static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
111
+{
112
+ return env->pstate & PSTATE_SSBS;
113
+}
114
+
115
+static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
116
+ uint64_t value)
117
+{
118
+ env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
119
+}
120
+
121
+static const ARMCPRegInfo ssbs_reginfo = {
122
+ .name = "SSBS", .state = ARM_CP_STATE_AA64,
123
+ .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
124
+ .type = ARM_CP_NO_RAW, .access = PL0_RW,
125
+ .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
126
+};
127
+
128
static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
129
const ARMCPRegInfo *ri,
130
bool isread)
32
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
33
.access = PL1_R, .type = ARM_CP_CONST,
132
if (cpu_isar_feature(aa64_dit, cpu)) {
34
.accessfn = access_aa64_tid3,
133
define_one_arm_cp_reg(cpu, &dit_reginfo);
35
.resetvalue = 0 },
134
}
36
- { .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
135
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
37
+ { .name = "ID_PFR2", .state = ARM_CP_STATE_BOTH,
136
+ define_one_arm_cp_reg(cpu, &ssbs_reginfo);
38
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
137
+ }
39
.access = PL1_R, .type = ARM_CP_CONST,
138
40
.accessfn = access_aa64_tid3,
139
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
41
- .resetvalue = 0 },
140
define_arm_cp_regs(cpu, vhe_reginfo);
42
+ .resetvalue = cpu->isar.id_pfr2 },
141
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
43
{ .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
142
env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
44
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
143
env->daif |= mask;
45
.access = PL1_R, .type = ARM_CP_CONST,
144
46
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
145
+ if (cpu_isar_feature(aa32_ssbs, env_archcpu(env))) {
146
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_32) {
147
+ env->uncached_cpsr |= CPSR_SSBS;
148
+ } else {
149
+ env->uncached_cpsr &= ~CPSR_SSBS;
150
+ }
151
+ }
152
+
153
if (new_mode == ARM_CPU_MODE_HYP) {
154
env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
155
env->elr_el[2] = env->regs[15];
156
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
157
new_mode |= PSTATE_TCO;
158
}
159
160
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
161
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_64) {
162
+ new_mode |= PSTATE_SSBS;
163
+ } else {
164
+ new_mode &= ~PSTATE_SSBS;
165
+ }
166
+ }
167
+
168
pstate_write(env, PSTATE_DAIF | new_mode);
169
env->aarch64 = 1;
170
aarch64_restore_sp(env, new_el);
171
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
47
index XXXXXXX..XXXXXXX 100644
172
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/kvm64.c
173
--- a/target/arm/translate-a64.c
49
+++ b/target/arm/kvm64.c
174
+++ b/target/arm/translate-a64.c
50
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
175
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
51
ARM64_SYS_REG(3, 0, 0, 1, 0));
176
tcg_temp_free_i32(t1);
52
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1,
177
break;
53
ARM64_SYS_REG(3, 0, 0, 1, 1));
178
54
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
179
+ case 0x19: /* SSBS */
55
+ ARM64_SYS_REG(3, 0, 0, 3, 4));
180
+ if (!dc_isar_feature(aa64_ssbs, s)) {
56
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
181
+ goto do_unallocated;
57
ARM64_SYS_REG(3, 0, 0, 1, 2));
182
+ }
58
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
183
+ if (crm & 1) {
184
+ set_pstate_bits(PSTATE_SSBS);
185
+ } else {
186
+ clear_pstate_bits(PSTATE_SSBS);
187
+ }
188
+ /* Don't need to rebuild hflags since SSBS is a nop */
189
+ break;
190
+
191
case 0x1a: /* DIT */
192
if (!dc_isar_feature(aa64_dit, s)) {
193
goto do_unallocated;
59
--
194
--
60
2.20.1
195
2.20.1
61
196
62
197
diff view generated by jsdifflib
1
From: Joelle van Dyne <j@getutm.app>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
On iOS there is no CoreAudio, so we should not assume Darwin always
3
Set ID_AA64PFR1_EL1.SSBS to 2 and ID_PFR2.SSBS to 1.
4
has it.
5
4
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210126012457.39046-11-j@getutm.app
7
Message-id: 20210216224543.16142-3-rebecca@nuviainc.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
configure | 35 +++++++++++++++++++++++++++++++++--
10
target/arm/cpu64.c | 5 +++++
12
1 file changed, 33 insertions(+), 2 deletions(-)
11
1 file changed, 5 insertions(+)
13
12
14
diff --git a/configure b/configure
13
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
15
index XXXXXXX..XXXXXXX 100755
14
index XXXXXXX..XXXXXXX 100644
16
--- a/configure
15
--- a/target/arm/cpu64.c
17
+++ b/configure
16
+++ b/target/arm/cpu64.c
18
@@ -XXX,XX +XXX,XX @@ fdt="auto"
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
19
netmap="no"
18
20
sdl="auto"
19
t = cpu->isar.id_aa64pfr1;
21
sdl_image="auto"
20
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
22
+coreaudio="auto"
21
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
23
virtiofsd="auto"
22
/*
24
virtfs="auto"
23
* Begin with full support for MTE. This will be downgraded to MTE=0
25
libudev="auto"
24
* during realize if the board provides no tag memory, much like
26
@@ -XXX,XX +XXX,XX @@ Darwin)
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
27
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
26
u = FIELD_DP32(u, ID_PFR0, DIT, 1);
28
QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
27
cpu->isar.id_pfr0 = u;
29
fi
28
30
- audio_drv_list="coreaudio try-sdl"
29
+ u = cpu->isar.id_pfr2;
31
+ audio_drv_list="try-coreaudio try-sdl"
30
+ u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
32
audio_possible_drivers="coreaudio sdl"
31
+ cpu->isar.id_pfr2 = u;
33
# Disable attempts to use ObjectiveC features in os/object.h since they
34
# won't work when we're compiling with gcc as a C compiler.
35
@@ -XXX,XX +XXX,XX @@ EOF
36
fi
37
fi
38
39
+##########################################
40
+# detect CoreAudio
41
+if test "$coreaudio" != "no" ; then
42
+ coreaudio_libs="-framework CoreAudio"
43
+ cat > $TMPC << EOF
44
+#include <CoreAudio/CoreAudio.h>
45
+int main(void)
46
+{
47
+ return (int)AudioGetCurrentHostTime();
48
+}
49
+EOF
50
+ if compile_prog "" "$coreaudio_libs" ; then
51
+ coreaudio=yes
52
+ else
53
+ coreaudio=no
54
+ fi
55
+fi
56
+
32
+
57
##########################################
33
u = cpu->isar.id_mmfr3;
58
# Sound support libraries probe
34
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
59
35
cpu->isar.id_mmfr3 = u;
60
@@ -XXX,XX +XXX,XX @@ for drv in $audio_drv_list; do
61
fi
62
;;
63
64
- coreaudio)
65
+ coreaudio | try-coreaudio)
66
+ if test "$coreaudio" = "no"; then
67
+ if test "$drv" = "try-coreaudio"; then
68
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-coreaudio//')
69
+ else
70
+ error_exit "$drv check failed" \
71
+ "Make sure to have the $drv is available."
72
+ fi
73
+ else
74
coreaudio_libs="-framework CoreAudio"
75
+ if test "$drv" = "try-coreaudio"; then
76
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-coreaudio/coreaudio/')
77
+ fi
78
+ fi
79
;;
80
81
dsound)
82
--
36
--
83
2.20.1
37
2.20.1
84
38
85
39
diff view generated by jsdifflib
1
From: Joelle van Dyne <j@getutm.app>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
Add objc to the Meson cross file as well as detection of Darwin.
3
Enable FEAT_SSBS for the "max" 32-bit CPU.
4
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210216224543.16142-4-rebecca@nuviainc.com
8
Message-id: 20210126012457.39046-8-j@getutm.app
8
[PMM: fix typo causing compilation failure]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
configure | 4 ++++
11
target/arm/cpu.c | 4 ++++
12
1 file changed, 4 insertions(+)
12
1 file changed, 4 insertions(+)
13
13
14
diff --git a/configure b/configure
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100755
15
index XXXXXXX..XXXXXXX 100644
16
--- a/configure
16
--- a/target/arm/cpu.c
17
+++ b/configure
17
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
18
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
19
echo "[binaries]" >> $cross
19
t = cpu->isar.id_pfr0;
20
echo "c = [$(meson_quote $cc)]" >> $cross
20
t = FIELD_DP32(t, ID_PFR0, DIT, 1);
21
test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
21
cpu->isar.id_pfr0 = t;
22
+test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross
22
+
23
echo "ar = [$(meson_quote $ar)]" >> $cross
23
+ t = cpu->isar.id_pfr2;
24
echo "nm = [$(meson_quote $nm)]" >> $cross
24
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
25
echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
25
+ cpu->isar.id_pfr2 = t;
26
@@ -XXX,XX +XXX,XX @@ if test "$cross_compile" = "yes"; then
26
}
27
if test "$linux" = "yes" ; then
27
#endif
28
echo "system = 'linux'" >> $cross
28
}
29
fi
30
+ if test "$darwin" = "yes" ; then
31
+ echo "system = 'darwin'" >> $cross
32
+ fi
33
case "$ARCH" in
34
i386|x86_64)
35
echo "cpu_family = 'x86'" >> $cross
36
--
29
--
37
2.20.1
30
2.20.1
38
31
39
32
diff view generated by jsdifflib
1
Add a simple test of the CMSDK watchdog, since we're about to do some
1
From: Doug Evans <dje@google.com>
2
refactoring of how it is clocked.
3
2
3
This is a 10/100 ethernet device that has several features.
4
Only the ones needed by the Linux driver have been implemented.
5
See npcm7xx_emc.c for a list of unimplemented features.
6
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
9
Signed-off-by: Doug Evans <dje@google.com>
10
Message-id: 20210218212453.831406-2-dje@google.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-5-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-5-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
12
---
12
tests/qtest/cmsdk-apb-watchdog-test.c | 79 +++++++++++++++++++++++++++
13
include/hw/net/npcm7xx_emc.h | 286 ++++++++++++
13
MAINTAINERS | 1 +
14
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++++++++++
14
tests/qtest/meson.build | 1 +
15
hw/net/meson.build | 1 +
15
3 files changed, 81 insertions(+)
16
hw/net/trace-events | 17 +
16
create mode 100644 tests/qtest/cmsdk-apb-watchdog-test.c
17
4 files changed, 1161 insertions(+)
18
create mode 100644 include/hw/net/npcm7xx_emc.h
19
create mode 100644 hw/net/npcm7xx_emc.c
17
20
18
diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c
21
diff --git a/include/hw/net/npcm7xx_emc.h b/include/hw/net/npcm7xx_emc.h
19
new file mode 100644
22
new file mode 100644
20
index XXXXXXX..XXXXXXX
23
index XXXXXXX..XXXXXXX
21
--- /dev/null
24
--- /dev/null
22
+++ b/tests/qtest/cmsdk-apb-watchdog-test.c
25
+++ b/include/hw/net/npcm7xx_emc.h
23
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
24
+/*
27
+/*
25
+ * QTest testcase for the CMSDK APB watchdog device
28
+ * Nuvoton NPCM7xx EMC Module
26
+ *
29
+ *
27
+ * Copyright (c) 2021 Linaro Limited
30
+ * Copyright 2020 Google LLC
28
+ *
31
+ *
29
+ * This program is free software; you can redistribute it and/or modify it
32
+ * This program is free software; you can redistribute it and/or modify it
30
+ * under the terms of the GNU General Public License as published by the
33
+ * under the terms of the GNU General Public License as published by the
31
+ * Free Software Foundation; either version 2 of the License, or
34
+ * Free Software Foundation; either version 2 of the License, or
32
+ * (at your option) any later version.
35
+ * (at your option) any later version.
...
...
35
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
39
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37
+ * for more details.
40
+ * for more details.
38
+ */
41
+ */
39
+
42
+
43
+#ifndef NPCM7XX_EMC_H
44
+#define NPCM7XX_EMC_H
45
+
46
+#include "hw/irq.h"
47
+#include "hw/sysbus.h"
48
+#include "net/net.h"
49
+
50
+/* 32-bit register indices. */
51
+enum NPCM7xxPWMRegister {
52
+ /* Control registers. */
53
+ REG_CAMCMR,
54
+ REG_CAMEN,
55
+
56
+ /* There are 16 CAMn[ML] registers. */
57
+ REG_CAMM_BASE,
58
+ REG_CAML_BASE,
59
+ REG_CAMML_LAST = 0x21,
60
+
61
+ REG_TXDLSA = 0x22,
62
+ REG_RXDLSA,
63
+ REG_MCMDR,
64
+ REG_MIID,
65
+ REG_MIIDA,
66
+ REG_FFTCR,
67
+ REG_TSDR,
68
+ REG_RSDR,
69
+ REG_DMARFC,
70
+ REG_MIEN,
71
+
72
+ /* Status registers. */
73
+ REG_MISTA,
74
+ REG_MGSTA,
75
+ REG_MPCNT,
76
+ REG_MRPC,
77
+ REG_MRPCC,
78
+ REG_MREPC,
79
+ REG_DMARFS,
80
+ REG_CTXDSA,
81
+ REG_CTXBSA,
82
+ REG_CRXDSA,
83
+ REG_CRXBSA,
84
+
85
+ NPCM7XX_NUM_EMC_REGS,
86
+};
87
+
88
+/* REG_CAMCMR fields */
89
+/* Enable CAM Compare */
90
+#define REG_CAMCMR_ECMP (1 << 4)
91
+/* Complement CAM Compare */
92
+#define REG_CAMCMR_CCAM (1 << 3)
93
+/* Accept Broadcast Packet */
94
+#define REG_CAMCMR_ABP (1 << 2)
95
+/* Accept Multicast Packet */
96
+#define REG_CAMCMR_AMP (1 << 1)
97
+/* Accept Unicast Packet */
98
+#define REG_CAMCMR_AUP (1 << 0)
99
+
100
+/* REG_MCMDR fields */
101
+/* Software Reset */
102
+#define REG_MCMDR_SWR (1 << 24)
103
+/* Internal Loopback Select */
104
+#define REG_MCMDR_LBK (1 << 21)
105
+/* Operation Mode Select */
106
+#define REG_MCMDR_OPMOD (1 << 20)
107
+/* Enable MDC Clock Generation */
108
+#define REG_MCMDR_ENMDC (1 << 19)
109
+/* Full-Duplex Mode Select */
110
+#define REG_MCMDR_FDUP (1 << 18)
111
+/* Enable SQE Checking */
112
+#define REG_MCMDR_ENSEQ (1 << 17)
113
+/* Send PAUSE Frame */
114
+#define REG_MCMDR_SDPZ (1 << 16)
115
+/* No Defer */
116
+#define REG_MCMDR_NDEF (1 << 9)
117
+/* Frame Transmission On */
118
+#define REG_MCMDR_TXON (1 << 8)
119
+/* Strip CRC Checksum */
120
+#define REG_MCMDR_SPCRC (1 << 5)
121
+/* Accept CRC Error Packet */
122
+#define REG_MCMDR_AEP (1 << 4)
123
+/* Accept Control Packet */
124
+#define REG_MCMDR_ACP (1 << 3)
125
+/* Accept Runt Packet */
126
+#define REG_MCMDR_ARP (1 << 2)
127
+/* Accept Long Packet */
128
+#define REG_MCMDR_ALP (1 << 1)
129
+/* Frame Reception On */
130
+#define REG_MCMDR_RXON (1 << 0)
131
+
132
+/* REG_MIEN fields */
133
+/* Enable Transmit Descriptor Unavailable Interrupt */
134
+#define REG_MIEN_ENTDU (1 << 23)
135
+/* Enable Transmit Completion Interrupt */
136
+#define REG_MIEN_ENTXCP (1 << 18)
137
+/* Enable Transmit Interrupt */
138
+#define REG_MIEN_ENTXINTR (1 << 16)
139
+/* Enable Receive Descriptor Unavailable Interrupt */
140
+#define REG_MIEN_ENRDU (1 << 10)
141
+/* Enable Receive Good Interrupt */
142
+#define REG_MIEN_ENRXGD (1 << 4)
143
+/* Enable Receive Interrupt */
144
+#define REG_MIEN_ENRXINTR (1 << 0)
145
+
146
+/* REG_MISTA fields */
147
+/* TODO: Add error fields and support simulated errors? */
148
+/* Transmit Bus Error Interrupt */
149
+#define REG_MISTA_TXBERR (1 << 24)
150
+/* Transmit Descriptor Unavailable Interrupt */
151
+#define REG_MISTA_TDU (1 << 23)
152
+/* Transmit Completion Interrupt */
153
+#define REG_MISTA_TXCP (1 << 18)
154
+/* Transmit Interrupt */
155
+#define REG_MISTA_TXINTR (1 << 16)
156
+/* Receive Bus Error Interrupt */
157
+#define REG_MISTA_RXBERR (1 << 11)
158
+/* Receive Descriptor Unavailable Interrupt */
159
+#define REG_MISTA_RDU (1 << 10)
160
+/* DMA Early Notification Interrupt */
161
+#define REG_MISTA_DENI (1 << 9)
162
+/* Maximum Frame Length Interrupt */
163
+#define REG_MISTA_DFOI (1 << 8)
164
+/* Receive Good Interrupt */
165
+#define REG_MISTA_RXGD (1 << 4)
166
+/* Packet Too Long Interrupt */
167
+#define REG_MISTA_PTLE (1 << 3)
168
+/* Receive Interrupt */
169
+#define REG_MISTA_RXINTR (1 << 0)
170
+
171
+/* REG_MGSTA fields */
172
+/* Transmission Halted */
173
+#define REG_MGSTA_TXHA (1 << 11)
174
+/* Receive Halted */
175
+#define REG_MGSTA_RXHA (1 << 11)
176
+
177
+/* REG_DMARFC fields */
178
+/* Maximum Receive Frame Length */
179
+#define REG_DMARFC_RXMS(word) extract32((word), 0, 16)
180
+
181
+/* REG MIIDA fields */
182
+/* Busy Bit */
183
+#define REG_MIIDA_BUSY (1 << 17)
184
+
185
+/* Transmit and receive descriptors */
186
+typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc;
187
+typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc;
188
+
189
+struct NPCM7xxEMCTxDesc {
190
+ uint32_t flags;
191
+ uint32_t txbsa;
192
+ uint32_t status_and_length;
193
+ uint32_t ntxdsa;
194
+};
195
+
196
+struct NPCM7xxEMCRxDesc {
197
+ uint32_t status_and_length;
198
+ uint32_t rxbsa;
199
+ uint32_t reserved;
200
+ uint32_t nrxdsa;
201
+};
202
+
203
+/* NPCM7xxEMCTxDesc.flags values */
204
+/* Owner: 0 = cpu, 1 = emc */
205
+#define TX_DESC_FLAG_OWNER_MASK (1 << 31)
206
+/* Transmit interrupt enable */
207
+#define TX_DESC_FLAG_INTEN (1 << 2)
208
+/* CRC append */
209
+#define TX_DESC_FLAG_CRCAPP (1 << 1)
210
+/* Padding enable */
211
+#define TX_DESC_FLAG_PADEN (1 << 0)
212
+
213
+/* NPCM7xxEMCTxDesc.status_and_length values */
214
+/* Collision count */
215
+#define TX_DESC_STATUS_CCNT_SHIFT 28
216
+#define TX_DESC_STATUS_CCNT_BITSIZE 4
217
+/* SQE error */
218
+#define TX_DESC_STATUS_SQE (1 << 26)
219
+/* Transmission paused */
220
+#define TX_DESC_STATUS_PAU (1 << 25)
221
+/* P transmission halted */
222
+#define TX_DESC_STATUS_TXHA (1 << 24)
223
+/* Late collision */
224
+#define TX_DESC_STATUS_LC (1 << 23)
225
+/* Transmission abort */
226
+#define TX_DESC_STATUS_TXABT (1 << 22)
227
+/* No carrier sense */
228
+#define TX_DESC_STATUS_NCS (1 << 21)
229
+/* Defer exceed */
230
+#define TX_DESC_STATUS_EXDEF (1 << 20)
231
+/* Transmission complete */
232
+#define TX_DESC_STATUS_TXCP (1 << 19)
233
+/* Transmission deferred */
234
+#define TX_DESC_STATUS_DEF (1 << 17)
235
+/* Transmit interrupt */
236
+#define TX_DESC_STATUS_TXINTR (1 << 16)
237
+
238
+#define TX_DESC_PKT_LEN(word) extract32((word), 0, 16)
239
+
240
+/* Transmit buffer start address */
241
+#define TX_DESC_TXBSA(word) ((uint32_t) (word) & ~3u)
242
+
243
+/* Next transmit descriptor start address */
244
+#define TX_DESC_NTXDSA(word) ((uint32_t) (word) & ~3u)
245
+
246
+/* NPCM7xxEMCRxDesc.status_and_length values */
247
+/* Owner: 0b00 = cpu, 0b01 = undefined, 0b10 = emc, 0b11 = undefined */
248
+#define RX_DESC_STATUS_OWNER_SHIFT 30
249
+#define RX_DESC_STATUS_OWNER_BITSIZE 2
250
+#define RX_DESC_STATUS_OWNER_MASK (3 << RX_DESC_STATUS_OWNER_SHIFT)
251
+/* Runt packet */
252
+#define RX_DESC_STATUS_RP (1 << 22)
253
+/* Alignment error */
254
+#define RX_DESC_STATUS_ALIE (1 << 21)
255
+/* Frame reception complete */
256
+#define RX_DESC_STATUS_RXGD (1 << 20)
257
+/* Packet too long */
258
+#define RX_DESC_STATUS_PTLE (1 << 19)
259
+/* CRC error */
260
+#define RX_DESC_STATUS_CRCE (1 << 17)
261
+/* Receive interrupt */
262
+#define RX_DESC_STATUS_RXINTR (1 << 16)
263
+
264
+#define RX_DESC_PKT_LEN(word) extract32((word), 0, 16)
265
+
266
+/* Receive buffer start address */
267
+#define RX_DESC_RXBSA(word) ((uint32_t) (word) & ~3u)
268
+
269
+/* Next receive descriptor start address */
270
+#define RX_DESC_NRXDSA(word) ((uint32_t) (word) & ~3u)
271
+
272
+/* Minimum packet length, when TX_DESC_FLAG_PADEN is set. */
273
+#define MIN_PACKET_LENGTH 64
274
+
275
+struct NPCM7xxEMCState {
276
+ /*< private >*/
277
+ SysBusDevice parent;
278
+ /*< public >*/
279
+
280
+ MemoryRegion iomem;
281
+
282
+ qemu_irq tx_irq;
283
+ qemu_irq rx_irq;
284
+
285
+ NICState *nic;
286
+ NICConf conf;
287
+
288
+ /* 0 or 1, for log messages */
289
+ uint8_t emc_num;
290
+
291
+ uint32_t regs[NPCM7XX_NUM_EMC_REGS];
292
+
293
+ /*
294
+ * tx is active. Set to true by TSDR and then switches off when out of
295
+ * descriptors. If the TXON bit in REG_MCMDR is off then this is off.
296
+ */
297
+ bool tx_active;
298
+
299
+ /*
300
+ * rx is active. Set to true by RSDR and then switches off when out of
301
+ * descriptors. If the RXON bit in REG_MCMDR is off then this is off.
302
+ */
303
+ bool rx_active;
304
+};
305
+
306
+typedef struct NPCM7xxEMCState NPCM7xxEMCState;
307
+
308
+#define TYPE_NPCM7XX_EMC "npcm7xx-emc"
309
+#define NPCM7XX_EMC(obj) \
310
+ OBJECT_CHECK(NPCM7xxEMCState, (obj), TYPE_NPCM7XX_EMC)
311
+
312
+#endif /* NPCM7XX_EMC_H */
313
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
314
new file mode 100644
315
index XXXXXXX..XXXXXXX
316
--- /dev/null
317
+++ b/hw/net/npcm7xx_emc.c
318
@@ -XXX,XX +XXX,XX @@
319
+/*
320
+ * Nuvoton NPCM7xx EMC Module
321
+ *
322
+ * Copyright 2020 Google LLC
323
+ *
324
+ * This program is free software; you can redistribute it and/or modify it
325
+ * under the terms of the GNU General Public License as published by the
326
+ * Free Software Foundation; either version 2 of the License, or
327
+ * (at your option) any later version.
328
+ *
329
+ * This program is distributed in the hope that it will be useful, but WITHOUT
330
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
331
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
332
+ * for more details.
333
+ *
334
+ * Unsupported/unimplemented features:
335
+ * - MCMDR.FDUP (full duplex) is ignored, half duplex is not supported
336
+ * - Only CAM0 is supported, CAM[1-15] are not
337
+ * - writes to CAMEN.[1-15] are ignored, these bits always read as zeroes
338
+ * - MII is not implemented, MIIDA.BUSY and MIID always return zero
339
+ * - MCMDR.LBK is not implemented
340
+ * - MCMDR.{OPMOD,ENSQE,AEP,ARP} are not supported
341
+ * - H/W FIFOs are not supported, MCMDR.FFTCR is ignored
342
+ * - MGSTA.SQE is not supported
343
+ * - pause and control frames are not implemented
344
+ * - MGSTA.CCNT is not supported
345
+ * - MPCNT, DMARFS are not implemented
346
+ */
347
+
40
+#include "qemu/osdep.h"
348
+#include "qemu/osdep.h"
41
+#include "libqtest-single.h"
349
+
350
+/* For crc32 */
351
+#include <zlib.h>
352
+
353
+#include "qemu-common.h"
354
+#include "hw/irq.h"
355
+#include "hw/qdev-clock.h"
356
+#include "hw/qdev-properties.h"
357
+#include "hw/net/npcm7xx_emc.h"
358
+#include "net/eth.h"
359
+#include "migration/vmstate.h"
360
+#include "qemu/bitops.h"
361
+#include "qemu/error-report.h"
362
+#include "qemu/log.h"
363
+#include "qemu/module.h"
364
+#include "qemu/units.h"
365
+#include "sysemu/dma.h"
366
+#include "trace.h"
367
+
368
+#define CRC_LENGTH 4
42
+
369
+
43
+/*
370
+/*
44
+ * lm3s811evb watchdog; at board startup this runs at 200MHz / 16 == 12.5MHz,
371
+ * The maximum size of a (layer 2) ethernet frame as defined by 802.3.
45
+ * which is 80ns per tick.
372
+ * 1518 = 6(dest macaddr) + 6(src macaddr) + 2(proto) + 4(crc) + 1500(payload)
373
+ * This does not include an additional 4 for the vlan field (802.1q).
46
+ */
374
+ */
47
+#define WDOG_BASE 0x40000000
375
+#define MAX_ETH_FRAME_SIZE 1518
48
+
376
+
49
+#define WDOGLOAD 0
377
+static const char *emc_reg_name(int regno)
50
+#define WDOGVALUE 4
378
+{
51
+#define WDOGCONTROL 8
379
+#define REG(name) case REG_ ## name: return #name;
52
+#define WDOGINTCLR 0xc
380
+ switch (regno) {
53
+#define WDOGRIS 0x10
381
+ REG(CAMCMR)
54
+#define WDOGMIS 0x14
382
+ REG(CAMEN)
55
+#define WDOGLOCK 0xc00
383
+ REG(TXDLSA)
56
+
384
+ REG(RXDLSA)
57
+static void test_watchdog(void)
385
+ REG(MCMDR)
58
+{
386
+ REG(MIID)
59
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
387
+ REG(MIIDA)
60
+
388
+ REG(FFTCR)
61
+ writel(WDOG_BASE + WDOGCONTROL, 1);
389
+ REG(TSDR)
62
+ writel(WDOG_BASE + WDOGLOAD, 1000);
390
+ REG(RSDR)
63
+
391
+ REG(DMARFC)
64
+ /* Step to just past the 500th tick */
392
+ REG(MIEN)
65
+ clock_step(500 * 80 + 1);
393
+ REG(MISTA)
66
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
394
+ REG(MGSTA)
67
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
395
+ REG(MPCNT)
68
+
396
+ REG(MRPC)
69
+ /* Just past the 1000th tick: timer should have fired */
397
+ REG(MRPCC)
70
+ clock_step(500 * 80);
398
+ REG(MREPC)
71
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
399
+ REG(DMARFS)
72
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 0);
400
+ REG(CTXDSA)
73
+
401
+ REG(CTXBSA)
74
+ /* VALUE reloads at following tick */
402
+ REG(CRXDSA)
75
+ clock_step(80);
403
+ REG(CRXBSA)
76
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
404
+ case REG_CAMM_BASE + 0: return "CAM0M";
77
+
405
+ case REG_CAML_BASE + 0: return "CAM0L";
78
+ /* Writing any value to WDOGINTCLR clears the interrupt and reloads */
406
+ case REG_CAMM_BASE + 2 ... REG_CAMML_LAST:
79
+ clock_step(500 * 80);
407
+ /* Only CAM0 is supported, fold the others into something simple. */
80
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
408
+ if (regno & 1) {
81
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
409
+ return "CAM<n>L";
82
+ writel(WDOG_BASE + WDOGINTCLR, 0);
410
+ } else {
83
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
411
+ return "CAM<n>M";
84
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
412
+ }
85
+}
413
+ default: return "UNKNOWN";
86
+
414
+ }
87
+int main(int argc, char **argv)
415
+#undef REG
88
+{
416
+}
89
+ int r;
417
+
90
+
418
+static void emc_reset(NPCM7xxEMCState *emc)
91
+ g_test_init(&argc, &argv, NULL);
419
+{
92
+
420
+ trace_npcm7xx_emc_reset(emc->emc_num);
93
+ qtest_start("-machine lm3s811evb");
421
+
94
+
422
+ memset(&emc->regs[0], 0, sizeof(emc->regs));
95
+ qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog);
423
+
96
+
424
+ /* These regs have non-zero reset values. */
97
+ r = g_test_run();
425
+ emc->regs[REG_TXDLSA] = 0xfffffffc;
98
+
426
+ emc->regs[REG_RXDLSA] = 0xfffffffc;
99
+ qtest_end();
427
+ emc->regs[REG_MIIDA] = 0x00900000;
100
+
428
+ emc->regs[REG_FFTCR] = 0x0101;
101
+ return r;
429
+ emc->regs[REG_DMARFC] = 0x0800;
102
+}
430
+ emc->regs[REG_MPCNT] = 0x7fff;
103
diff --git a/MAINTAINERS b/MAINTAINERS
431
+
432
+ emc->tx_active = false;
433
+ emc->rx_active = false;
434
+}
435
+
436
+static void npcm7xx_emc_reset(DeviceState *dev)
437
+{
438
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
439
+ emc_reset(emc);
440
+}
441
+
442
+static void emc_soft_reset(NPCM7xxEMCState *emc)
443
+{
444
+ /*
445
+ * The docs say at least MCMDR.{LBK,OPMOD} bits are not changed during a
446
+ * soft reset, but does not go into further detail. For now, KISS.
447
+ */
448
+ uint32_t mcmdr = emc->regs[REG_MCMDR];
449
+ emc_reset(emc);
450
+ emc->regs[REG_MCMDR] = mcmdr & (REG_MCMDR_LBK | REG_MCMDR_OPMOD);
451
+
452
+ qemu_set_irq(emc->tx_irq, 0);
453
+ qemu_set_irq(emc->rx_irq, 0);
454
+}
455
+
456
+static void emc_set_link(NetClientState *nc)
457
+{
458
+ /* Nothing to do yet. */
459
+}
460
+
461
+/* MISTA.TXINTR is the union of the individual bits with their enables. */
462
+static void emc_update_mista_txintr(NPCM7xxEMCState *emc)
463
+{
464
+ /* Only look at the bits we support. */
465
+ uint32_t mask = (REG_MISTA_TXBERR |
466
+ REG_MISTA_TDU |
467
+ REG_MISTA_TXCP);
468
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) {
469
+ emc->regs[REG_MISTA] |= REG_MISTA_TXINTR;
470
+ } else {
471
+ emc->regs[REG_MISTA] &= ~REG_MISTA_TXINTR;
472
+ }
473
+}
474
+
475
+/* MISTA.RXINTR is the union of the individual bits with their enables. */
476
+static void emc_update_mista_rxintr(NPCM7xxEMCState *emc)
477
+{
478
+ /* Only look at the bits we support. */
479
+ uint32_t mask = (REG_MISTA_RXBERR |
480
+ REG_MISTA_RDU |
481
+ REG_MISTA_RXGD);
482
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) {
483
+ emc->regs[REG_MISTA] |= REG_MISTA_RXINTR;
484
+ } else {
485
+ emc->regs[REG_MISTA] &= ~REG_MISTA_RXINTR;
486
+ }
487
+}
488
+
489
+/* N.B. emc_update_mista_txintr must have already been called. */
490
+static void emc_update_tx_irq(NPCM7xxEMCState *emc)
491
+{
492
+ int level = !!(emc->regs[REG_MISTA] &
493
+ emc->regs[REG_MIEN] &
494
+ REG_MISTA_TXINTR);
495
+ trace_npcm7xx_emc_update_tx_irq(level);
496
+ qemu_set_irq(emc->tx_irq, level);
497
+}
498
+
499
+/* N.B. emc_update_mista_rxintr must have already been called. */
500
+static void emc_update_rx_irq(NPCM7xxEMCState *emc)
501
+{
502
+ int level = !!(emc->regs[REG_MISTA] &
503
+ emc->regs[REG_MIEN] &
504
+ REG_MISTA_RXINTR);
505
+ trace_npcm7xx_emc_update_rx_irq(level);
506
+ qemu_set_irq(emc->rx_irq, level);
507
+}
508
+
509
+/* Update IRQ states due to changes in MIEN,MISTA. */
510
+static void emc_update_irq_from_reg_change(NPCM7xxEMCState *emc)
511
+{
512
+ emc_update_mista_txintr(emc);
513
+ emc_update_tx_irq(emc);
514
+
515
+ emc_update_mista_rxintr(emc);
516
+ emc_update_rx_irq(emc);
517
+}
518
+
519
+static int emc_read_tx_desc(dma_addr_t addr, NPCM7xxEMCTxDesc *desc)
520
+{
521
+ if (dma_memory_read(&address_space_memory, addr, desc, sizeof(*desc))) {
522
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
523
+ HWADDR_PRIx "\n", __func__, addr);
524
+ return -1;
525
+ }
526
+ desc->flags = le32_to_cpu(desc->flags);
527
+ desc->txbsa = le32_to_cpu(desc->txbsa);
528
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
529
+ desc->ntxdsa = le32_to_cpu(desc->ntxdsa);
530
+ return 0;
531
+}
532
+
533
+static int emc_write_tx_desc(const NPCM7xxEMCTxDesc *desc, dma_addr_t addr)
534
+{
535
+ NPCM7xxEMCTxDesc le_desc;
536
+
537
+ le_desc.flags = cpu_to_le32(desc->flags);
538
+ le_desc.txbsa = cpu_to_le32(desc->txbsa);
539
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
540
+ le_desc.ntxdsa = cpu_to_le32(desc->ntxdsa);
541
+ if (dma_memory_write(&address_space_memory, addr, &le_desc,
542
+ sizeof(le_desc))) {
543
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
544
+ HWADDR_PRIx "\n", __func__, addr);
545
+ return -1;
546
+ }
547
+ return 0;
548
+}
549
+
550
+static int emc_read_rx_desc(dma_addr_t addr, NPCM7xxEMCRxDesc *desc)
551
+{
552
+ if (dma_memory_read(&address_space_memory, addr, desc, sizeof(*desc))) {
553
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
554
+ HWADDR_PRIx "\n", __func__, addr);
555
+ return -1;
556
+ }
557
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
558
+ desc->rxbsa = le32_to_cpu(desc->rxbsa);
559
+ desc->reserved = le32_to_cpu(desc->reserved);
560
+ desc->nrxdsa = le32_to_cpu(desc->nrxdsa);
561
+ return 0;
562
+}
563
+
564
+static int emc_write_rx_desc(const NPCM7xxEMCRxDesc *desc, dma_addr_t addr)
565
+{
566
+ NPCM7xxEMCRxDesc le_desc;
567
+
568
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
569
+ le_desc.rxbsa = cpu_to_le32(desc->rxbsa);
570
+ le_desc.reserved = cpu_to_le32(desc->reserved);
571
+ le_desc.nrxdsa = cpu_to_le32(desc->nrxdsa);
572
+ if (dma_memory_write(&address_space_memory, addr, &le_desc,
573
+ sizeof(le_desc))) {
574
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
575
+ HWADDR_PRIx "\n", __func__, addr);
576
+ return -1;
577
+ }
578
+ return 0;
579
+}
580
+
581
+static void emc_set_mista(NPCM7xxEMCState *emc, uint32_t flags)
582
+{
583
+ trace_npcm7xx_emc_set_mista(flags);
584
+ emc->regs[REG_MISTA] |= flags;
585
+ if (extract32(flags, 16, 16)) {
586
+ emc_update_mista_txintr(emc);
587
+ }
588
+ if (extract32(flags, 0, 16)) {
589
+ emc_update_mista_rxintr(emc);
590
+ }
591
+}
592
+
593
+static void emc_halt_tx(NPCM7xxEMCState *emc, uint32_t mista_flag)
594
+{
595
+ emc->tx_active = false;
596
+ emc_set_mista(emc, mista_flag);
597
+}
598
+
599
+static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
600
+{
601
+ emc->rx_active = false;
602
+ emc_set_mista(emc, mista_flag);
603
+}
604
+
605
+static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
606
+ const NPCM7xxEMCTxDesc *tx_desc,
607
+ uint32_t desc_addr)
608
+{
609
+ /* Update the current descriptor, if only to reset the owner flag. */
610
+ if (emc_write_tx_desc(tx_desc, desc_addr)) {
611
+ /*
612
+ * We just read it so this shouldn't generally happen.
613
+ * Error already reported.
614
+ */
615
+ emc_set_mista(emc, REG_MISTA_TXBERR);
616
+ }
617
+ emc->regs[REG_CTXDSA] = TX_DESC_NTXDSA(tx_desc->ntxdsa);
618
+}
619
+
620
+static void emc_set_next_rx_descriptor(NPCM7xxEMCState *emc,
621
+ const NPCM7xxEMCRxDesc *rx_desc,
622
+ uint32_t desc_addr)
623
+{
624
+ /* Update the current descriptor, if only to reset the owner flag. */
625
+ if (emc_write_rx_desc(rx_desc, desc_addr)) {
626
+ /*
627
+ * We just read it so this shouldn't generally happen.
628
+ * Error already reported.
629
+ */
630
+ emc_set_mista(emc, REG_MISTA_RXBERR);
631
+ }
632
+ emc->regs[REG_CRXDSA] = RX_DESC_NRXDSA(rx_desc->nrxdsa);
633
+}
634
+
635
+static void emc_try_send_next_packet(NPCM7xxEMCState *emc)
636
+{
637
+ /* Working buffer for sending out packets. Most packets fit in this. */
638
+#define TX_BUFFER_SIZE 2048
639
+ uint8_t tx_send_buffer[TX_BUFFER_SIZE];
640
+ uint32_t desc_addr = TX_DESC_NTXDSA(emc->regs[REG_CTXDSA]);
641
+ NPCM7xxEMCTxDesc tx_desc;
642
+ uint32_t next_buf_addr, length;
643
+ uint8_t *buf;
644
+ g_autofree uint8_t *malloced_buf = NULL;
645
+
646
+ if (emc_read_tx_desc(desc_addr, &tx_desc)) {
647
+ /* Error reading descriptor, already reported. */
648
+ emc_halt_tx(emc, REG_MISTA_TXBERR);
649
+ emc_update_tx_irq(emc);
650
+ return;
651
+ }
652
+
653
+ /* Nothing we can do if we don't own the descriptor. */
654
+ if (!(tx_desc.flags & TX_DESC_FLAG_OWNER_MASK)) {
655
+ trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
656
+ emc_halt_tx(emc, REG_MISTA_TDU);
657
+ emc_update_tx_irq(emc);
658
+ return;
659
+ }
660
+
661
+ /* Give the descriptor back regardless of what happens. */
662
+ tx_desc.flags &= ~TX_DESC_FLAG_OWNER_MASK;
663
+ tx_desc.status_and_length &= 0xffff;
664
+
665
+ /*
666
+ * Despite the h/w documentation saying the tx buffer is word aligned,
667
+ * the linux driver does not word align the buffer. There is value in not
668
+ * aligning the buffer: See the description of NET_IP_ALIGN in linux
669
+ * kernel sources.
670
+ */
671
+ next_buf_addr = tx_desc.txbsa;
672
+ emc->regs[REG_CTXBSA] = next_buf_addr;
673
+ length = TX_DESC_PKT_LEN(tx_desc.status_and_length);
674
+ buf = &tx_send_buffer[0];
675
+
676
+ if (length > sizeof(tx_send_buffer)) {
677
+ malloced_buf = g_malloc(length);
678
+ buf = malloced_buf;
679
+ }
680
+
681
+ if (dma_memory_read(&address_space_memory, next_buf_addr, buf, length)) {
682
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read packet @ 0x%x\n",
683
+ __func__, next_buf_addr);
684
+ emc_set_mista(emc, REG_MISTA_TXBERR);
685
+ emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr);
686
+ emc_update_tx_irq(emc);
687
+ trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]);
688
+ return;
689
+ }
690
+
691
+ if ((tx_desc.flags & TX_DESC_FLAG_PADEN) && (length < MIN_PACKET_LENGTH)) {
692
+ memset(buf + length, 0, MIN_PACKET_LENGTH - length);
693
+ length = MIN_PACKET_LENGTH;
694
+ }
695
+
696
+ /* N.B. emc_receive can get called here. */
697
+ qemu_send_packet(qemu_get_queue(emc->nic), buf, length);
698
+ trace_npcm7xx_emc_sent_packet(length);
699
+
700
+ tx_desc.status_and_length |= TX_DESC_STATUS_TXCP;
701
+ if (tx_desc.flags & TX_DESC_FLAG_INTEN) {
702
+ emc_set_mista(emc, REG_MISTA_TXCP);
703
+ }
704
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_TXINTR) {
705
+ tx_desc.status_and_length |= TX_DESC_STATUS_TXINTR;
706
+ }
707
+
708
+ emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr);
709
+ emc_update_tx_irq(emc);
710
+ trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]);
711
+}
712
+
713
+static bool emc_can_receive(NetClientState *nc)
714
+{
715
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));
716
+
717
+ bool can_receive = emc->rx_active;
718
+ trace_npcm7xx_emc_can_receive(can_receive);
719
+ return can_receive;
720
+}
721
+
722
+/* If result is false then *fail_reason contains the reason. */
723
+static bool emc_receive_filter1(NPCM7xxEMCState *emc, const uint8_t *buf,
724
+ size_t len, const char **fail_reason)
725
+{
726
+ eth_pkt_types_e pkt_type = get_eth_packet_type(PKT_GET_ETH_HDR(buf));
727
+
728
+ switch (pkt_type) {
729
+ case ETH_PKT_BCAST:
730
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
731
+ return true;
732
+ } else {
733
+ *fail_reason = "Broadcast packet disabled";
734
+ return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_ABP);
735
+ }
736
+ case ETH_PKT_MCAST:
737
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
738
+ return true;
739
+ } else {
740
+ *fail_reason = "Multicast packet disabled";
741
+ return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_AMP);
742
+ }
743
+ case ETH_PKT_UCAST: {
744
+ bool matches;
745
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_AUP) {
746
+ return true;
747
+ }
748
+ matches = ((emc->regs[REG_CAMCMR] & REG_CAMCMR_ECMP) &&
749
+ /* We only support one CAM register, CAM0. */
750
+ (emc->regs[REG_CAMEN] & (1 << 0)) &&
751
+ memcmp(buf, emc->conf.macaddr.a, ETH_ALEN) == 0);
752
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
753
+ *fail_reason = "MACADDR matched, comparison complemented";
754
+ return !matches;
755
+ } else {
756
+ *fail_reason = "MACADDR didn't match";
757
+ return matches;
758
+ }
759
+ }
760
+ default:
761
+ g_assert_not_reached();
762
+ }
763
+}
764
+
765
+static bool emc_receive_filter(NPCM7xxEMCState *emc, const uint8_t *buf,
766
+ size_t len)
767
+{
768
+ const char *fail_reason = NULL;
769
+ bool ok = emc_receive_filter1(emc, buf, len, &fail_reason);
770
+ if (!ok) {
771
+ trace_npcm7xx_emc_packet_filtered_out(fail_reason);
772
+ }
773
+ return ok;
774
+}
775
+
776
+static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
777
+{
778
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));
779
+ const uint32_t len = len1;
780
+ size_t max_frame_len;
781
+ bool long_frame;
782
+ uint32_t desc_addr;
783
+ NPCM7xxEMCRxDesc rx_desc;
784
+ uint32_t crc;
785
+ uint8_t *crc_ptr;
786
+ uint32_t buf_addr;
787
+
788
+ trace_npcm7xx_emc_receiving_packet(len);
789
+
790
+ if (!emc_can_receive(nc)) {
791
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unexpected packet\n", __func__);
792
+ return -1;
793
+ }
794
+
795
+ if (len < ETH_HLEN ||
796
+ /* Defensive programming: drop unsupportable large packets. */
797
+ len > 0xffff - CRC_LENGTH) {
798
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Dropped frame of %u bytes\n",
799
+ __func__, len);
800
+ return len;
801
+ }
802
+
803
+ /*
804
+ * DENI is set if EMC received the Length/Type field of the incoming
805
+ * packet, so it will be set regardless of what happens next.
806
+ */
807
+ emc_set_mista(emc, REG_MISTA_DENI);
808
+
809
+ if (!emc_receive_filter(emc, buf, len)) {
810
+ emc_update_rx_irq(emc);
811
+ return len;
812
+ }
813
+
814
+ /* Huge frames (> DMARFC) are dropped. */
815
+ max_frame_len = REG_DMARFC_RXMS(emc->regs[REG_DMARFC]);
816
+ if (len + CRC_LENGTH > max_frame_len) {
817
+ trace_npcm7xx_emc_packet_dropped(len);
818
+ emc_set_mista(emc, REG_MISTA_DFOI);
819
+ emc_update_rx_irq(emc);
820
+ return len;
821
+ }
822
+
823
+ /*
824
+ * Long Frames (> MAX_ETH_FRAME_SIZE) are also dropped, unless MCMDR.ALP
825
+ * is set.
826
+ */
827
+ long_frame = false;
828
+ if (len + CRC_LENGTH > MAX_ETH_FRAME_SIZE) {
829
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_ALP) {
830
+ long_frame = true;
831
+ } else {
832
+ trace_npcm7xx_emc_packet_dropped(len);
833
+ emc_set_mista(emc, REG_MISTA_PTLE);
834
+ emc_update_rx_irq(emc);
835
+ return len;
836
+ }
837
+ }
838
+
839
+ desc_addr = RX_DESC_NRXDSA(emc->regs[REG_CRXDSA]);
840
+ if (emc_read_rx_desc(desc_addr, &rx_desc)) {
841
+ /* Error reading descriptor, already reported. */
842
+ emc_halt_rx(emc, REG_MISTA_RXBERR);
843
+ emc_update_rx_irq(emc);
844
+ return len;
845
+ }
846
+
847
+ /* Nothing we can do if we don't own the descriptor. */
848
+ if (!(rx_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK)) {
849
+ trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
850
+ emc_halt_rx(emc, REG_MISTA_RDU);
851
+ emc_update_rx_irq(emc);
852
+ return len;
853
+ }
854
+
855
+ crc = 0;
856
+ crc_ptr = (uint8_t *) &crc;
857
+ if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
858
+ crc = cpu_to_be32(crc32(~0, buf, len));
859
+ }
860
+
861
+ /* Give the descriptor back regardless of what happens. */
862
+ rx_desc.status_and_length &= ~RX_DESC_STATUS_OWNER_MASK;
863
+
864
+ buf_addr = rx_desc.rxbsa;
865
+ emc->regs[REG_CRXBSA] = buf_addr;
866
+ if (dma_memory_write(&address_space_memory, buf_addr, buf, len) ||
867
+ (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC) &&
868
+ dma_memory_write(&address_space_memory, buf_addr + len, crc_ptr,
869
+ 4))) {
870
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bus error writing packet\n",
871
+ __func__);
872
+ emc_set_mista(emc, REG_MISTA_RXBERR);
873
+ emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
874
+ emc_update_rx_irq(emc);
875
+ trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
876
+ return len;
877
+ }
878
+
879
+ trace_npcm7xx_emc_received_packet(len);
880
+
881
+ /* Note: We've already verified len+4 <= 0xffff. */
882
+ rx_desc.status_and_length = len;
883
+ if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
884
+ rx_desc.status_and_length += 4;
885
+ }
886
+ rx_desc.status_and_length |= RX_DESC_STATUS_RXGD;
887
+ emc_set_mista(emc, REG_MISTA_RXGD);
888
+
889
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_RXINTR) {
890
+ rx_desc.status_and_length |= RX_DESC_STATUS_RXINTR;
891
+ }
892
+ if (long_frame) {
893
+ rx_desc.status_and_length |= RX_DESC_STATUS_PTLE;
894
+ }
895
+
896
+ emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
897
+ emc_update_rx_irq(emc);
898
+ trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
899
+ return len;
900
+}
901
+
902
+static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
903
+{
904
+ if (emc_can_receive(qemu_get_queue(emc->nic))) {
905
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
906
+ }
907
+}
908
+
909
+static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
910
+{
911
+ NPCM7xxEMCState *emc = opaque;
912
+ uint32_t reg = offset / sizeof(uint32_t);
913
+ uint32_t result;
914
+
915
+ if (reg >= NPCM7XX_NUM_EMC_REGS) {
916
+ qemu_log_mask(LOG_GUEST_ERROR,
917
+ "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
918
+ __func__, offset);
919
+ return 0;
920
+ }
921
+
922
+ switch (reg) {
923
+ case REG_MIID:
924
+ /*
925
+ * We don't implement MII. For determinism, always return zero as
926
+ * writes record the last value written for debugging purposes.
927
+ */
928
+ qemu_log_mask(LOG_UNIMP, "%s: Read of MIID, returning 0\n", __func__);
929
+ result = 0;
930
+ break;
931
+ case REG_TSDR:
932
+ case REG_RSDR:
933
+ qemu_log_mask(LOG_GUEST_ERROR,
934
+ "%s: Read of write-only reg, %s/%d\n",
935
+ __func__, emc_reg_name(reg), reg);
936
+ return 0;
937
+ default:
938
+ result = emc->regs[reg];
939
+ break;
940
+ }
941
+
942
+ trace_npcm7xx_emc_reg_read(emc->emc_num, result, emc_reg_name(reg), reg);
943
+ return result;
944
+}
945
+
946
+static void npcm7xx_emc_write(void *opaque, hwaddr offset,
947
+ uint64_t v, unsigned size)
948
+{
949
+ NPCM7xxEMCState *emc = opaque;
950
+ uint32_t reg = offset / sizeof(uint32_t);
951
+ uint32_t value = v;
952
+
953
+ g_assert(size == sizeof(uint32_t));
954
+
955
+ if (reg >= NPCM7XX_NUM_EMC_REGS) {
956
+ qemu_log_mask(LOG_GUEST_ERROR,
957
+ "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
958
+ __func__, offset);
959
+ return;
960
+ }
961
+
962
+ trace_npcm7xx_emc_reg_write(emc->emc_num, emc_reg_name(reg), reg, value);
963
+
964
+ switch (reg) {
965
+ case REG_CAMCMR:
966
+ emc->regs[reg] = value;
967
+ break;
968
+ case REG_CAMEN:
969
+ /* Only CAM0 is supported, don't pretend otherwise. */
970
+ if (value & ~1) {
971
+ qemu_log_mask(LOG_GUEST_ERROR,
972
+ "%s: Only CAM0 is supported, cannot enable others"
973
+ ": 0x%x\n",
974
+ __func__, value);
975
+ }
976
+ emc->regs[reg] = value & 1;
977
+ break;
978
+ case REG_CAMM_BASE + 0:
979
+ emc->regs[reg] = value;
980
+ emc->conf.macaddr.a[0] = value >> 24;
981
+ emc->conf.macaddr.a[1] = value >> 16;
982
+ emc->conf.macaddr.a[2] = value >> 8;
983
+ emc->conf.macaddr.a[3] = value >> 0;
984
+ break;
985
+ case REG_CAML_BASE + 0:
986
+ emc->regs[reg] = value;
987
+ emc->conf.macaddr.a[4] = value >> 24;
988
+ emc->conf.macaddr.a[5] = value >> 16;
989
+ break;
990
+ case REG_MCMDR: {
991
+ uint32_t prev;
992
+ if (value & REG_MCMDR_SWR) {
993
+ emc_soft_reset(emc);
994
+ /* On h/w the reset happens over multiple cycles. For now KISS. */
995
+ break;
996
+ }
997
+ prev = emc->regs[reg];
998
+ emc->regs[reg] = value;
999
+ /* Update tx state. */
1000
+ if (!(prev & REG_MCMDR_TXON) &&
1001
+ (value & REG_MCMDR_TXON)) {
1002
+ emc->regs[REG_CTXDSA] = emc->regs[REG_TXDLSA];
1003
+ /*
1004
+ * Linux kernel turns TX on with CPU still holding descriptor,
1005
+ * which suggests we should wait for a write to TSDR before trying
1006
+ * to send a packet: so we don't send one here.
1007
+ */
1008
+ } else if ((prev & REG_MCMDR_TXON) &&
1009
+ !(value & REG_MCMDR_TXON)) {
1010
+ emc->regs[REG_MGSTA] |= REG_MGSTA_TXHA;
1011
+ }
1012
+ if (!(value & REG_MCMDR_TXON)) {
1013
+ emc_halt_tx(emc, 0);
1014
+ }
1015
+ /* Update rx state. */
1016
+ if (!(prev & REG_MCMDR_RXON) &&
1017
+ (value & REG_MCMDR_RXON)) {
1018
+ emc->regs[REG_CRXDSA] = emc->regs[REG_RXDLSA];
1019
+ } else if ((prev & REG_MCMDR_RXON) &&
1020
+ !(value & REG_MCMDR_RXON)) {
1021
+ emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
1022
+ }
1023
+ if (!(value & REG_MCMDR_RXON)) {
1024
+ emc_halt_rx(emc, 0);
1025
+ }
1026
+ break;
1027
+ }
1028
+ case REG_TXDLSA:
1029
+ case REG_RXDLSA:
1030
+ case REG_DMARFC:
1031
+ case REG_MIID:
1032
+ emc->regs[reg] = value;
1033
+ break;
1034
+ case REG_MIEN:
1035
+ emc->regs[reg] = value;
1036
+ emc_update_irq_from_reg_change(emc);
1037
+ break;
1038
+ case REG_MISTA:
1039
+ /* Clear the bits that have 1 in "value". */
1040
+ emc->regs[reg] &= ~value;
1041
+ emc_update_irq_from_reg_change(emc);
1042
+ break;
1043
+ case REG_MGSTA:
1044
+ /* Clear the bits that have 1 in "value". */
1045
+ emc->regs[reg] &= ~value;
1046
+ break;
1047
+ case REG_TSDR:
1048
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_TXON) {
1049
+ emc->tx_active = true;
1050
+ /* Keep trying to send packets until we run out. */
1051
+ while (emc->tx_active) {
1052
+ emc_try_send_next_packet(emc);
1053
+ }
1054
+ }
1055
+ break;
1056
+ case REG_RSDR:
1057
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
1058
+ emc->rx_active = true;
1059
+ emc_try_receive_next_packet(emc);
1060
+ }
1061
+ break;
1062
+ case REG_MIIDA:
1063
+ emc->regs[reg] = value & ~REG_MIIDA_BUSY;
1064
+ break;
1065
+ case REG_MRPC:
1066
+ case REG_MRPCC:
1067
+ case REG_MREPC:
1068
+ case REG_CTXDSA:
1069
+ case REG_CTXBSA:
1070
+ case REG_CRXDSA:
1071
+ case REG_CRXBSA:
1072
+ qemu_log_mask(LOG_GUEST_ERROR,
1073
+ "%s: Write to read-only reg %s/%d\n",
1074
+ __func__, emc_reg_name(reg), reg);
1075
+ break;
1076
+ default:
1077
+ qemu_log_mask(LOG_UNIMP, "%s: Write to unimplemented reg %s/%d\n",
1078
+ __func__, emc_reg_name(reg), reg);
1079
+ break;
1080
+ }
1081
+}
1082
+
1083
+static const struct MemoryRegionOps npcm7xx_emc_ops = {
1084
+ .read = npcm7xx_emc_read,
1085
+ .write = npcm7xx_emc_write,
1086
+ .endianness = DEVICE_LITTLE_ENDIAN,
1087
+ .valid = {
1088
+ .min_access_size = 4,
1089
+ .max_access_size = 4,
1090
+ .unaligned = false,
1091
+ },
1092
+};
1093
+
1094
+static void emc_cleanup(NetClientState *nc)
1095
+{
1096
+ /* Nothing to do yet. */
1097
+}
1098
+
1099
+static NetClientInfo net_npcm7xx_emc_info = {
1100
+ .type = NET_CLIENT_DRIVER_NIC,
1101
+ .size = sizeof(NICState),
1102
+ .can_receive = emc_can_receive,
1103
+ .receive = emc_receive,
1104
+ .cleanup = emc_cleanup,
1105
+ .link_status_changed = emc_set_link,
1106
+};
1107
+
1108
+static void npcm7xx_emc_realize(DeviceState *dev, Error **errp)
1109
+{
1110
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
1111
+ SysBusDevice *sbd = SYS_BUS_DEVICE(emc);
1112
+
1113
+ memory_region_init_io(&emc->iomem, OBJECT(emc), &npcm7xx_emc_ops, emc,
1114
+ TYPE_NPCM7XX_EMC, 4 * KiB);
1115
+ sysbus_init_mmio(sbd, &emc->iomem);
1116
+ sysbus_init_irq(sbd, &emc->tx_irq);
1117
+ sysbus_init_irq(sbd, &emc->rx_irq);
1118
+
1119
+ qemu_macaddr_default_if_unset(&emc->conf.macaddr);
1120
+ emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf,
1121
+ object_get_typename(OBJECT(dev)), dev->id, emc);
1122
+ qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a);
1123
+}
1124
+
1125
+static void npcm7xx_emc_unrealize(DeviceState *dev)
1126
+{
1127
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
1128
+
1129
+ qemu_del_nic(emc->nic);
1130
+}
1131
+
1132
+static const VMStateDescription vmstate_npcm7xx_emc = {
1133
+ .name = TYPE_NPCM7XX_EMC,
1134
+ .version_id = 0,
1135
+ .minimum_version_id = 0,
1136
+ .fields = (VMStateField[]) {
1137
+ VMSTATE_UINT8(emc_num, NPCM7xxEMCState),
1138
+ VMSTATE_UINT32_ARRAY(regs, NPCM7xxEMCState, NPCM7XX_NUM_EMC_REGS),
1139
+ VMSTATE_BOOL(tx_active, NPCM7xxEMCState),
1140
+ VMSTATE_BOOL(rx_active, NPCM7xxEMCState),
1141
+ VMSTATE_END_OF_LIST(),
1142
+ },
1143
+};
1144
+
1145
+static Property npcm7xx_emc_properties[] = {
1146
+ DEFINE_NIC_PROPERTIES(NPCM7xxEMCState, conf),
1147
+ DEFINE_PROP_END_OF_LIST(),
1148
+};
1149
+
1150
+static void npcm7xx_emc_class_init(ObjectClass *klass, void *data)
1151
+{
1152
+ DeviceClass *dc = DEVICE_CLASS(klass);
1153
+
1154
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
1155
+ dc->desc = "NPCM7xx EMC Controller";
1156
+ dc->realize = npcm7xx_emc_realize;
1157
+ dc->unrealize = npcm7xx_emc_unrealize;
1158
+ dc->reset = npcm7xx_emc_reset;
1159
+ dc->vmsd = &vmstate_npcm7xx_emc;
1160
+ device_class_set_props(dc, npcm7xx_emc_properties);
1161
+}
1162
+
1163
+static const TypeInfo npcm7xx_emc_info = {
1164
+ .name = TYPE_NPCM7XX_EMC,
1165
+ .parent = TYPE_SYS_BUS_DEVICE,
1166
+ .instance_size = sizeof(NPCM7xxEMCState),
1167
+ .class_init = npcm7xx_emc_class_init,
1168
+};
1169
+
1170
+static void npcm7xx_emc_register_type(void)
1171
+{
1172
+ type_register_static(&npcm7xx_emc_info);
1173
+}
1174
+
1175
+type_init(npcm7xx_emc_register_type)
1176
diff --git a/hw/net/meson.build b/hw/net/meson.build
104
index XXXXXXX..XXXXXXX 100644
1177
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
1178
--- a/hw/net/meson.build
106
+++ b/MAINTAINERS
1179
+++ b/hw/net/meson.build
107
@@ -XXX,XX +XXX,XX @@ F: hw/char/cmsdk-apb-uart.c
1180
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_I82596_COMMON', if_true: files('i82596.c'))
108
F: include/hw/char/cmsdk-apb-uart.h
1181
softmmu_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
109
F: hw/watchdog/cmsdk-apb-watchdog.c
1182
softmmu_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
110
F: include/hw/watchdog/cmsdk-apb-watchdog.h
1183
softmmu_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
111
+F: tests/qtest/cmsdk-apb-watchdog-test.c
1184
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
112
F: hw/misc/tz-ppc.c
1185
113
F: include/hw/misc/tz-ppc.h
1186
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
114
F: hw/misc/tz-mpc.c
1187
softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
115
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
1188
diff --git a/hw/net/trace-events b/hw/net/trace-events
116
index XXXXXXX..XXXXXXX 100644
1189
index XXXXXXX..XXXXXXX 100644
117
--- a/tests/qtest/meson.build
1190
--- a/hw/net/trace-events
118
+++ b/tests/qtest/meson.build
1191
+++ b/hw/net/trace-events
119
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
1192
@@ -XXX,XX +XXX,XX @@ imx_fec_receive_last(int last) "rx frame flags 0x%04x"
120
'npcm7xx_watchdog_timer-test']
1193
imx_enet_receive(size_t size) "len %zu"
121
qtests_arm = \
1194
imx_enet_receive_len(uint64_t addr, int len) "rx_bd 0x%"PRIx64" length %d"
122
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
1195
imx_enet_receive_last(int last) "rx frame flags 0x%04x"
123
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
1196
+
124
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
1197
+# npcm7xx_emc.c
125
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
1198
+npcm7xx_emc_reset(int emc_num) "Resetting emc%d"
126
['arm-cpu-features',
1199
+npcm7xx_emc_update_tx_irq(int level) "Setting tx irq to %d"
1200
+npcm7xx_emc_update_rx_irq(int level) "Setting rx irq to %d"
1201
+npcm7xx_emc_set_mista(uint32_t flags) "ORing 0x%x into MISTA"
1202
+npcm7xx_emc_cpu_owned_desc(uint32_t addr) "Can't process cpu-owned descriptor @0x%x"
1203
+npcm7xx_emc_sent_packet(uint32_t len) "Sent %u byte packet"
1204
+npcm7xx_emc_tx_done(uint32_t ctxdsa) "TX done, CTXDSA=0x%x"
1205
+npcm7xx_emc_can_receive(int can_receive) "Can receive: %d"
1206
+npcm7xx_emc_packet_filtered_out(const char* fail_reason) "Packet filtered out: %s"
1207
+npcm7xx_emc_packet_dropped(uint32_t len) "%u byte packet dropped"
1208
+npcm7xx_emc_receiving_packet(uint32_t len) "Receiving %u byte packet"
1209
+npcm7xx_emc_received_packet(uint32_t len) "Received %u byte packet"
1210
+npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x"
1211
+npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]"
1212
+npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x"
127
--
1213
--
128
2.20.1
1214
2.20.1
129
1215
130
1216
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
From: Doug Evans <dje@google.com>
2
2
3
Add secure pl061 for reset/power down machine from
3
This is a 10/100 ethernet device that has several features.
4
the secure world (Arm Trusted Firmware). Connect it
4
Only the ones needed by the Linux driver have been implemented.
5
with gpio-pwr driver.
5
See npcm7xx_emc.c for a list of unimplemented features.
6
6
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Andrew Jones <drjones@redhat.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
9
[PMM: Added mention of the new device to the documentation]
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Doug Evans <dje@google.com>
11
Message-id: 20210218212453.831406-3-dje@google.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
docs/system/arm/virt.rst | 2 ++
14
docs/system/arm/nuvoton.rst | 3 ++-
13
include/hw/arm/virt.h | 2 ++
15
include/hw/arm/npcm7xx.h | 2 ++
14
hw/arm/virt.c | 56 +++++++++++++++++++++++++++++++++++++++-
16
hw/arm/npcm7xx.c | 50 +++++++++++++++++++++++++++++++++++--
15
hw/arm/Kconfig | 1 +
17
3 files changed, 52 insertions(+), 3 deletions(-)
16
4 files changed, 60 insertions(+), 1 deletion(-)
17
18
18
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
19
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/system/arm/virt.rst
21
--- a/docs/system/arm/nuvoton.rst
21
+++ b/docs/system/arm/virt.rst
22
+++ b/docs/system/arm/nuvoton.rst
22
@@ -XXX,XX +XXX,XX @@ The virt board supports:
23
@@ -XXX,XX +XXX,XX @@ Supported devices
23
- Secure-World-only devices if the CPU has TrustZone:
24
* Analog to Digital Converter (ADC)
24
25
* Pulse Width Modulation (PWM)
25
- A second PL011 UART
26
* SMBus controller (SMBF)
26
+ - A second PL061 GPIO controller, with GPIO lines for triggering
27
+ * Ethernet controller (EMC)
27
+ a system reset or system poweroff
28
28
- A secure flash memory
29
Missing devices
29
- 16MB of secure RAM
30
---------------
30
31
@@ -XXX,XX +XXX,XX @@ Missing devices
31
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
32
* Shared memory (SHM)
33
* eSPI slave interface
34
35
- * Ethernet controllers (GMAC and EMC)
36
+ * Ethernet controller (GMAC)
37
* USB device (USBD)
38
* Peripheral SPI controller (PSPI)
39
* SD/MMC host
40
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
32
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/arm/virt.h
42
--- a/include/hw/arm/npcm7xx.h
34
+++ b/include/hw/arm/virt.h
43
+++ b/include/hw/arm/npcm7xx.h
35
@@ -XXX,XX +XXX,XX @@ enum {
44
@@ -XXX,XX +XXX,XX @@
36
VIRT_GPIO,
45
#include "hw/misc/npcm7xx_gcr.h"
37
VIRT_SECURE_UART,
46
#include "hw/misc/npcm7xx_pwm.h"
38
VIRT_SECURE_MEM,
47
#include "hw/misc/npcm7xx_rng.h"
39
+ VIRT_SECURE_GPIO,
48
+#include "hw/net/npcm7xx_emc.h"
40
VIRT_PCDIMM_ACPI,
49
#include "hw/nvram/npcm7xx_otp.h"
41
VIRT_ACPI_GED,
50
#include "hw/timer/npcm7xx_timer.h"
42
VIRT_NVDIMM_ACPI,
51
#include "hw/ssi/npcm7xx_fiu.h"
43
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
52
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
44
bool kvm_no_adjvtime;
53
EHCISysBusState ehci;
45
bool no_kvm_steal_time;
54
OHCISysBusState ohci;
46
bool acpi_expose_flash;
55
NPCM7xxFIUState fiu[2];
47
+ bool no_secure_gpio;
56
+ NPCM7xxEMCState emc[2];
57
} NPCM7xxState;
58
59
#define TYPE_NPCM7XX "npcm7xx"
60
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/npcm7xx.c
63
+++ b/hw/arm/npcm7xx.c
64
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
65
NPCM7XX_UART1_IRQ,
66
NPCM7XX_UART2_IRQ,
67
NPCM7XX_UART3_IRQ,
68
+ NPCM7XX_EMC1RX_IRQ = 15,
69
+ NPCM7XX_EMC1TX_IRQ,
70
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
71
NPCM7XX_TIMER1_IRQ,
72
NPCM7XX_TIMER2_IRQ,
73
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
74
NPCM7XX_SMBUS15_IRQ,
75
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
76
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
77
+ NPCM7XX_EMC2RX_IRQ = 114,
78
+ NPCM7XX_EMC2TX_IRQ,
79
NPCM7XX_GPIO0_IRQ = 116,
80
NPCM7XX_GPIO1_IRQ,
81
NPCM7XX_GPIO2_IRQ,
82
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_smbus_addr[] = {
83
0xf008f000,
48
};
84
};
49
85
50
struct VirtMachineState {
86
+/* Register base address for each EMC Module */
51
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
87
+static const hwaddr npcm7xx_emc_addr[] = {
52
index XXXXXXX..XXXXXXX 100644
88
+ 0xf0825000,
53
--- a/hw/arm/virt.c
89
+ 0xf0826000,
54
+++ b/hw/arm/virt.c
90
+};
55
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry base_memmap[] = {
56
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
57
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
58
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
59
+ [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
60
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
61
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
62
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
63
@@ -XXX,XX +XXX,XX @@ static void create_gpio_keys(const VirtMachineState *vms,
64
"gpios", phandle, 3, 0);
65
}
66
67
+#define SECURE_GPIO_POWEROFF 0
68
+#define SECURE_GPIO_RESET 1
69
+
91
+
70
+static void create_secure_gpio_pwr(const VirtMachineState *vms,
92
static const struct {
71
+ DeviceState *pl061_dev,
93
hwaddr regs_addr;
72
+ uint32_t phandle)
94
uint32_t unconnected_pins;
73
+{
95
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
74
+ DeviceState *gpio_pwr_dev;
96
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
98
}
75
+
99
+
76
+ /* gpio-pwr */
100
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
77
+ gpio_pwr_dev = sysbus_create_simple("gpio-pwr", -1, NULL);
101
+ object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
78
+
79
+ /* connect secure pl061 to gpio-pwr */
80
+ qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_RESET,
81
+ qdev_get_gpio_in_named(gpio_pwr_dev, "reset", 0));
82
+ qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_POWEROFF,
83
+ qdev_get_gpio_in_named(gpio_pwr_dev, "shutdown", 0));
84
+
85
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-poweroff");
86
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "compatible",
87
+ "gpio-poweroff");
88
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-poweroff",
89
+ "gpios", phandle, SECURE_GPIO_POWEROFF, 0);
90
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "status", "disabled");
91
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "secure-status",
92
+ "okay");
93
+
94
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-restart");
95
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "compatible",
96
+ "gpio-restart");
97
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-restart",
98
+ "gpios", phandle, SECURE_GPIO_RESET, 0);
99
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "status", "disabled");
100
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "secure-status",
101
+ "okay");
102
+}
103
+
104
static void create_gpio_devices(const VirtMachineState *vms, int gpio,
105
MemoryRegion *mem)
106
{
107
@@ -XXX,XX +XXX,XX @@ static void create_gpio_devices(const VirtMachineState *vms, int gpio,
108
qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk");
109
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
110
111
+ if (gpio != VIRT_GPIO) {
112
+ /* Mark as not usable by the normal world */
113
+ qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
114
+ qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
115
+ }
116
g_free(nodename);
117
118
/* Child gpio devices */
119
- create_gpio_keys(vms, pl061_dev, phandle);
120
+ if (gpio == VIRT_GPIO) {
121
+ create_gpio_keys(vms, pl061_dev, phandle);
122
+ } else {
123
+ create_secure_gpio_pwr(vms, pl061_dev, phandle);
124
+ }
102
+ }
125
}
103
}
126
104
127
static void create_virtio_devices(const VirtMachineState *vms)
105
static void npcm7xx_realize(DeviceState *dev, Error **errp)
128
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
106
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
129
create_gpio_devices(vms, VIRT_GPIO, sysmem);
107
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
130
}
108
}
131
109
132
+ if (vms->secure && !vmc->no_secure_gpio) {
110
+ /*
133
+ create_gpio_devices(vms, VIRT_SECURE_GPIO, secure_sysmem);
111
+ * EMC Modules. Cannot fail.
112
+ * The mapping of the device to its netdev backend works as follows:
113
+ * emc[i] = nd_table[i]
114
+ * This works around the inability to specify the netdev property for the
115
+ * emc device: it's not pluggable and thus the -device option can't be
116
+ * used.
117
+ */
118
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_emc_addr) != ARRAY_SIZE(s->emc));
119
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->emc) != 2);
120
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
121
+ s->emc[i].emc_num = i;
122
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->emc[i]);
123
+ if (nd_table[i].used) {
124
+ qemu_check_nic_model(&nd_table[i], TYPE_NPCM7XX_EMC);
125
+ qdev_set_nic_properties(DEVICE(sbd), &nd_table[i]);
126
+ }
127
+ /*
128
+ * The device exists regardless of whether it's connected to a QEMU
129
+ * netdev backend. So always instantiate it even if there is no
130
+ * backend.
131
+ */
132
+ sysbus_realize(sbd, &error_abort);
133
+ sysbus_mmio_map(sbd, 0, npcm7xx_emc_addr[i]);
134
+ int tx_irq = i == 0 ? NPCM7XX_EMC1TX_IRQ : NPCM7XX_EMC2TX_IRQ;
135
+ int rx_irq = i == 0 ? NPCM7XX_EMC1RX_IRQ : NPCM7XX_EMC2RX_IRQ;
136
+ /*
137
+ * N.B. The values for the second argument sysbus_connect_irq are
138
+ * chosen to match the registration order in npcm7xx_emc_realize.
139
+ */
140
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, tx_irq));
141
+ sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
134
+ }
142
+ }
135
+
143
+
136
/* connect powerdown request */
144
/*
137
vms->powerdown_notifier.notify = virt_powerdown_req;
145
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
138
qemu_register_powerdown_notifier(&vms->powerdown_notifier);
146
* specified, but this is a programming error.
139
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(6, 0)
147
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
140
148
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
141
static void virt_machine_5_2_options(MachineClass *mc)
149
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
142
{
150
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
143
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
151
- create_unimplemented_device("npcm7xx.emc1", 0xf0825000, 4 * KiB);
144
+
152
- create_unimplemented_device("npcm7xx.emc2", 0xf0826000, 4 * KiB);
145
virt_machine_6_0_options(mc);
153
create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
146
compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
154
create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
147
+ vmc->no_secure_gpio = true;
155
create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
148
}
149
DEFINE_VIRT_MACHINE(5, 2)
150
151
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
152
index XXXXXXX..XXXXXXX 100644
153
--- a/hw/arm/Kconfig
154
+++ b/hw/arm/Kconfig
155
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
156
select PL011 # UART
157
select PL031 # RTC
158
select PL061 # GPIO
159
+ select GPIO_PWR
160
select PLATFORM_BUS
161
select SMBIOS
162
select VIRTIO_MMIO
163
--
156
--
164
2.20.1
157
2.20.1
165
158
166
159
diff view generated by jsdifflib
1
Add a simple test of the CMSDK dual timer, since we're about to do
1
From: Doug Evans <dje@google.com>
2
some refactoring of how it is clocked.
3
2
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
4
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Doug Evans <dje@google.com>
7
Message-id: 20210218212453.831406-4-dje@google.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20210128114145.20536-6-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-6-peter.maydell@linaro.org
10
---
9
---
11
tests/qtest/cmsdk-apb-dualtimer-test.c | 130 +++++++++++++++++++++++++
10
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++
12
MAINTAINERS | 1 +
11
tests/qtest/meson.build | 3 +-
13
tests/qtest/meson.build | 1 +
12
2 files changed, 864 insertions(+), 1 deletion(-)
14
3 files changed, 132 insertions(+)
13
create mode 100644 tests/qtest/npcm7xx_emc-test.c
15
create mode 100644 tests/qtest/cmsdk-apb-dualtimer-test.c
16
14
17
diff --git a/tests/qtest/cmsdk-apb-dualtimer-test.c b/tests/qtest/cmsdk-apb-dualtimer-test.c
15
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
18
new file mode 100644
16
new file mode 100644
19
index XXXXXXX..XXXXXXX
17
index XXXXXXX..XXXXXXX
20
--- /dev/null
18
--- /dev/null
21
+++ b/tests/qtest/cmsdk-apb-dualtimer-test.c
19
+++ b/tests/qtest/npcm7xx_emc-test.c
22
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
23
+/*
21
+/*
24
+ * QTest testcase for the CMSDK APB dualtimer device
22
+ * QTests for Nuvoton NPCM7xx EMC Modules.
25
+ *
23
+ *
26
+ * Copyright (c) 2021 Linaro Limited
24
+ * Copyright 2020 Google LLC
27
+ *
25
+ *
28
+ * This program is free software; you can redistribute it and/or modify it
26
+ * This program is free software; you can redistribute it and/or modify it
29
+ * under the terms of the GNU General Public License as published by the
27
+ * under the terms of the GNU General Public License as published by the
30
+ * Free Software Foundation; either version 2 of the License, or
28
+ * Free Software Foundation; either version 2 of the License, or
31
+ * (at your option) any later version.
29
+ * (at your option) any later version.
...
...
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36
+ * for more details.
34
+ * for more details.
37
+ */
35
+ */
38
+
36
+
39
+#include "qemu/osdep.h"
37
+#include "qemu/osdep.h"
40
+#include "libqtest-single.h"
38
+#include "qemu-common.h"
41
+
39
+#include "libqos/libqos.h"
42
+/* IoTKit/ARMSSE dualtimer; driven at 25MHz in mps2-an385, so 40ns per tick */
40
+#include "qapi/qmp/qdict.h"
43
+#define TIMER_BASE 0x40002000
41
+#include "qapi/qmp/qnum.h"
44
+
42
+#include "qemu/bitops.h"
45
+#define TIMER1LOAD 0
43
+#include "qemu/iov.h"
46
+#define TIMER1VALUE 4
44
+
47
+#define TIMER1CONTROL 8
45
+/* Name of the emc device. */
48
+#define TIMER1INTCLR 0xc
46
+#define TYPE_NPCM7XX_EMC "npcm7xx-emc"
49
+#define TIMER1RIS 0x10
47
+
50
+#define TIMER1MIS 0x14
48
+/* Timeout for various operations, in seconds. */
51
+#define TIMER1BGLOAD 0x18
49
+#define TIMEOUT_SECONDS 10
52
+
50
+
53
+#define TIMER2LOAD 0x20
51
+/* Address in memory of the descriptor. */
54
+#define TIMER2VALUE 0x24
52
+#define DESC_ADDR (1 << 20) /* 1 MiB */
55
+#define TIMER2CONTROL 0x28
53
+
56
+#define TIMER2INTCLR 0x2c
54
+/* Address in memory of the data packet. */
57
+#define TIMER2RIS 0x30
55
+#define DATA_ADDR (DESC_ADDR + 4096)
58
+#define TIMER2MIS 0x34
56
+
59
+#define TIMER2BGLOAD 0x38
57
+#define CRC_LENGTH 4
60
+
58
+
61
+#define CTRL_ENABLE (1 << 7)
59
+#define NUM_TX_DESCRIPTORS 3
62
+#define CTRL_PERIODIC (1 << 6)
60
+#define NUM_RX_DESCRIPTORS 2
63
+#define CTRL_INTEN (1 << 5)
61
+
64
+#define CTRL_PRESCALE_1 (0 << 2)
62
+/* Size of tx,rx test buffers. */
65
+#define CTRL_PRESCALE_16 (1 << 2)
63
+#define TX_DATA_LEN 64
66
+#define CTRL_PRESCALE_256 (2 << 2)
64
+#define RX_DATA_LEN 64
67
+#define CTRL_32BIT (1 << 1)
65
+
68
+#define CTRL_ONESHOT (1 << 0)
66
+#define TX_STEP_COUNT 10000
69
+
67
+#define RX_STEP_COUNT 10000
70
+static void test_dualtimer(void)
68
+
71
+{
69
+/* 32-bit register indices. */
72
+ g_assert_true(readl(TIMER_BASE + TIMER1RIS) == 0);
70
+typedef enum NPCM7xxPWMRegister {
73
+
71
+ /* Control registers. */
74
+ /* Start timer: will fire after 40000 ns */
72
+ REG_CAMCMR,
75
+ writel(TIMER_BASE + TIMER1LOAD, 1000);
73
+ REG_CAMEN,
76
+ /* enable in free-running, wrapping, interrupt mode */
74
+
77
+ writel(TIMER_BASE + TIMER1CONTROL, CTRL_ENABLE | CTRL_INTEN);
75
+ /* There are 16 CAMn[ML] registers. */
78
+
76
+ REG_CAMM_BASE,
79
+ /* Step to just past the 500th tick and check VALUE */
77
+ REG_CAML_BASE,
80
+ clock_step(500 * 40 + 1);
78
+
81
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 0);
79
+ REG_TXDLSA = 0x22,
82
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 500);
80
+ REG_RXDLSA,
83
+
81
+ REG_MCMDR,
84
+ /* Just past the 1000th tick: timer should have fired */
82
+ REG_MIID,
85
+ clock_step(500 * 40);
83
+ REG_MIIDA,
86
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 1);
84
+ REG_FFTCR,
87
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0);
85
+ REG_TSDR,
86
+ REG_RSDR,
87
+ REG_DMARFC,
88
+ REG_MIEN,
89
+
90
+ /* Status registers. */
91
+ REG_MISTA,
92
+ REG_MGSTA,
93
+ REG_MPCNT,
94
+ REG_MRPC,
95
+ REG_MRPCC,
96
+ REG_MREPC,
97
+ REG_DMARFS,
98
+ REG_CTXDSA,
99
+ REG_CTXBSA,
100
+ REG_CRXDSA,
101
+ REG_CRXBSA,
102
+
103
+ NPCM7XX_NUM_EMC_REGS,
104
+} NPCM7xxPWMRegister;
105
+
106
+enum { NUM_CAMML_REGS = 16 };
107
+
108
+/* REG_CAMCMR fields */
109
+/* Enable CAM Compare */
110
+#define REG_CAMCMR_ECMP (1 << 4)
111
+/* Accept Unicast Packet */
112
+#define REG_CAMCMR_AUP (1 << 0)
113
+
114
+/* REG_MCMDR fields */
115
+/* Software Reset */
116
+#define REG_MCMDR_SWR (1 << 24)
117
+/* Frame Transmission On */
118
+#define REG_MCMDR_TXON (1 << 8)
119
+/* Accept Long Packet */
120
+#define REG_MCMDR_ALP (1 << 1)
121
+/* Frame Reception On */
122
+#define REG_MCMDR_RXON (1 << 0)
123
+
124
+/* REG_MIEN fields */
125
+/* Enable Transmit Completion Interrupt */
126
+#define REG_MIEN_ENTXCP (1 << 18)
127
+/* Enable Transmit Interrupt */
128
+#define REG_MIEN_ENTXINTR (1 << 16)
129
+/* Enable Receive Good Interrupt */
130
+#define REG_MIEN_ENRXGD (1 << 4)
131
+/* ENable Receive Interrupt */
132
+#define REG_MIEN_ENRXINTR (1 << 0)
133
+
134
+/* REG_MISTA fields */
135
+/* Transmit Bus Error Interrupt */
136
+#define REG_MISTA_TXBERR (1 << 24)
137
+/* Transmit Descriptor Unavailable Interrupt */
138
+#define REG_MISTA_TDU (1 << 23)
139
+/* Transmit Completion Interrupt */
140
+#define REG_MISTA_TXCP (1 << 18)
141
+/* Transmit Interrupt */
142
+#define REG_MISTA_TXINTR (1 << 16)
143
+/* Receive Bus Error Interrupt */
144
+#define REG_MISTA_RXBERR (1 << 11)
145
+/* Receive Descriptor Unavailable Interrupt */
146
+#define REG_MISTA_RDU (1 << 10)
147
+/* DMA Early Notification Interrupt */
148
+#define REG_MISTA_DENI (1 << 9)
149
+/* Maximum Frame Length Interrupt */
150
+#define REG_MISTA_DFOI (1 << 8)
151
+/* Receive Good Interrupt */
152
+#define REG_MISTA_RXGD (1 << 4)
153
+/* Packet Too Long Interrupt */
154
+#define REG_MISTA_PTLE (1 << 3)
155
+/* Receive Interrupt */
156
+#define REG_MISTA_RXINTR (1 << 0)
157
+
158
+typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc;
159
+typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc;
160
+
161
+struct NPCM7xxEMCTxDesc {
162
+ uint32_t flags;
163
+ uint32_t txbsa;
164
+ uint32_t status_and_length;
165
+ uint32_t ntxdsa;
166
+};
167
+
168
+struct NPCM7xxEMCRxDesc {
169
+ uint32_t status_and_length;
170
+ uint32_t rxbsa;
171
+ uint32_t reserved;
172
+ uint32_t nrxdsa;
173
+};
174
+
175
+/* NPCM7xxEMCTxDesc.flags values */
176
+/* Owner: 0 = cpu, 1 = emc */
177
+#define TX_DESC_FLAG_OWNER_MASK (1 << 31)
178
+/* Transmit interrupt enable */
179
+#define TX_DESC_FLAG_INTEN (1 << 2)
180
+
181
+/* NPCM7xxEMCTxDesc.status_and_length values */
182
+/* Transmission complete */
183
+#define TX_DESC_STATUS_TXCP (1 << 19)
184
+/* Transmit interrupt */
185
+#define TX_DESC_STATUS_TXINTR (1 << 16)
186
+
187
+/* NPCM7xxEMCRxDesc.status_and_length values */
188
+/* Owner: 0b00 = cpu, 0b10 = emc */
189
+#define RX_DESC_STATUS_OWNER_SHIFT 30
190
+#define RX_DESC_STATUS_OWNER_MASK 0xc0000000
191
+/* Frame Reception Complete */
192
+#define RX_DESC_STATUS_RXGD (1 << 20)
193
+/* Packet too long */
194
+#define RX_DESC_STATUS_PTLE (1 << 19)
195
+/* Receive Interrupt */
196
+#define RX_DESC_STATUS_RXINTR (1 << 16)
197
+
198
+#define RX_DESC_PKT_LEN(word) ((uint32_t) (word) & 0xffff)
199
+
200
+typedef struct EMCModule {
201
+ int rx_irq;
202
+ int tx_irq;
203
+ uint64_t base_addr;
204
+} EMCModule;
205
+
206
+typedef struct TestData {
207
+ const EMCModule *module;
208
+} TestData;
209
+
210
+static const EMCModule emc_module_list[] = {
211
+ {
212
+ .rx_irq = 15,
213
+ .tx_irq = 16,
214
+ .base_addr = 0xf0825000
215
+ },
216
+ {
217
+ .rx_irq = 114,
218
+ .tx_irq = 115,
219
+ .base_addr = 0xf0826000
220
+ }
221
+};
222
+
223
+/* Returns the index of the EMC module. */
224
+static int emc_module_index(const EMCModule *mod)
225
+{
226
+ ptrdiff_t diff = mod - emc_module_list;
227
+
228
+ g_assert_true(diff >= 0 && diff < ARRAY_SIZE(emc_module_list));
229
+
230
+ return diff;
231
+}
232
+
233
+static void packet_test_clear(void *sockets)
234
+{
235
+ int *test_sockets = sockets;
236
+
237
+ close(test_sockets[0]);
238
+ g_free(test_sockets);
239
+}
240
+
241
+static int *packet_test_init(int module_num, GString *cmd_line)
242
+{
243
+ int *test_sockets = g_new(int, 2);
244
+ int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets);
245
+ g_assert_cmpint(ret, != , -1);
88
+
246
+
89
+ /*
247
+ /*
90
+ * We are in free-running wrapping 16-bit mode, so on the following
248
+ * KISS and use -nic. We specify two nics (both emc{0,1}) because there's
91
+ * tick VALUE should have wrapped round to 0xffff.
249
+ * currently no way to specify only emc1: The driver implicitly relies on
250
+ * emc[i] == nd_table[i].
92
+ */
251
+ */
93
+ clock_step(40);
252
+ if (module_num == 0) {
94
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0xffff);
253
+ g_string_append_printf(cmd_line,
95
+
254
+ " -nic socket,fd=%d,model=" TYPE_NPCM7XX_EMC " "
96
+ /* Check that any write to INTCLR clears interrupt */
255
+ " -nic user,model=" TYPE_NPCM7XX_EMC " ",
97
+ writel(TIMER_BASE + TIMER1INTCLR, 1);
256
+ test_sockets[1]);
98
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 0);
257
+ } else {
99
+
258
+ g_string_append_printf(cmd_line,
100
+ /* Turn off the timer */
259
+ " -nic user,model=" TYPE_NPCM7XX_EMC " "
101
+ writel(TIMER_BASE + TIMER1CONTROL, 0);
260
+ " -nic socket,fd=%d,model=" TYPE_NPCM7XX_EMC " ",
102
+}
261
+ test_sockets[1]);
103
+
262
+ }
104
+static void test_prescale(void)
263
+
105
+{
264
+ g_test_queue_destroy(packet_test_clear, test_sockets);
106
+ g_assert_true(readl(TIMER_BASE + TIMER2RIS) == 0);
265
+ return test_sockets;
107
+
266
+}
108
+ /* Start timer: will fire after 40 * 256 * 1000 == 1024000 ns */
267
+
109
+ writel(TIMER_BASE + TIMER2LOAD, 1000);
268
+static uint32_t emc_read(QTestState *qts, const EMCModule *mod,
110
+ /* enable in periodic, wrapping, interrupt mode, prescale 256 */
269
+ NPCM7xxPWMRegister regno)
111
+ writel(TIMER_BASE + TIMER2CONTROL,
270
+{
112
+ CTRL_ENABLE | CTRL_INTEN | CTRL_PERIODIC | CTRL_PRESCALE_256);
271
+ return qtest_readl(qts, mod->base_addr + regno * sizeof(uint32_t));
113
+
272
+}
114
+ /* Step to just past the 500th tick and check VALUE */
273
+
115
+ clock_step(40 * 256 * 501);
274
+static void emc_write(QTestState *qts, const EMCModule *mod,
116
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 0);
275
+ NPCM7xxPWMRegister regno, uint32_t value)
117
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 500);
276
+{
118
+
277
+ qtest_writel(qts, mod->base_addr + regno * sizeof(uint32_t), value);
119
+ /* Just past the 1000th tick: timer should have fired */
278
+}
120
+ clock_step(40 * 256 * 500);
279
+
121
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 1);
280
+static void emc_read_tx_desc(QTestState *qts, uint32_t addr,
122
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 0);
281
+ NPCM7xxEMCTxDesc *desc)
123
+
282
+{
124
+ /* In periodic mode the tick VALUE now reloads */
283
+ qtest_memread(qts, addr, desc, sizeof(*desc));
125
+ clock_step(40 * 256);
284
+ desc->flags = le32_to_cpu(desc->flags);
126
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 1000);
285
+ desc->txbsa = le32_to_cpu(desc->txbsa);
127
+
286
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
128
+ /* Check that any write to INTCLR clears interrupt */
287
+ desc->ntxdsa = le32_to_cpu(desc->ntxdsa);
129
+ writel(TIMER_BASE + TIMER2INTCLR, 1);
288
+}
130
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 0);
289
+
131
+
290
+static void emc_write_tx_desc(QTestState *qts, const NPCM7xxEMCTxDesc *desc,
132
+ /* Turn off the timer */
291
+ uint32_t addr)
133
+ writel(TIMER_BASE + TIMER2CONTROL, 0);
292
+{
134
+}
293
+ NPCM7xxEMCTxDesc le_desc;
294
+
295
+ le_desc.flags = cpu_to_le32(desc->flags);
296
+ le_desc.txbsa = cpu_to_le32(desc->txbsa);
297
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
298
+ le_desc.ntxdsa = cpu_to_le32(desc->ntxdsa);
299
+ qtest_memwrite(qts, addr, &le_desc, sizeof(le_desc));
300
+}
301
+
302
+static void emc_read_rx_desc(QTestState *qts, uint32_t addr,
303
+ NPCM7xxEMCRxDesc *desc)
304
+{
305
+ qtest_memread(qts, addr, desc, sizeof(*desc));
306
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
307
+ desc->rxbsa = le32_to_cpu(desc->rxbsa);
308
+ desc->reserved = le32_to_cpu(desc->reserved);
309
+ desc->nrxdsa = le32_to_cpu(desc->nrxdsa);
310
+}
311
+
312
+static void emc_write_rx_desc(QTestState *qts, const NPCM7xxEMCRxDesc *desc,
313
+ uint32_t addr)
314
+{
315
+ NPCM7xxEMCRxDesc le_desc;
316
+
317
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
318
+ le_desc.rxbsa = cpu_to_le32(desc->rxbsa);
319
+ le_desc.reserved = cpu_to_le32(desc->reserved);
320
+ le_desc.nrxdsa = cpu_to_le32(desc->nrxdsa);
321
+ qtest_memwrite(qts, addr, &le_desc, sizeof(le_desc));
322
+}
323
+
324
+/*
325
+ * Reset the EMC module.
326
+ * The module must be reset before, e.g., TXDLSA,RXDLSA are changed.
327
+ */
328
+static bool emc_soft_reset(QTestState *qts, const EMCModule *mod)
329
+{
330
+ uint32_t val;
331
+ uint64_t end_time;
332
+
333
+ emc_write(qts, mod, REG_MCMDR, REG_MCMDR_SWR);
334
+
335
+ /*
336
+ * Wait for device to reset as the linux driver does.
337
+ * During reset the AHB reads 0 for all registers. So first wait for
338
+ * something that resets to non-zero, and then wait for SWR becoming 0.
339
+ */
340
+ end_time = g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
341
+
342
+ do {
343
+ qtest_clock_step(qts, 100);
344
+ val = emc_read(qts, mod, REG_FFTCR);
345
+ } while (val == 0 && g_get_monotonic_time() < end_time);
346
+ if (val != 0) {
347
+ do {
348
+ qtest_clock_step(qts, 100);
349
+ val = emc_read(qts, mod, REG_MCMDR);
350
+ if ((val & REG_MCMDR_SWR) == 0) {
351
+ /*
352
+ * N.B. The CAMs have been reset here, so macaddr matching of
353
+ * incoming packets will not work.
354
+ */
355
+ return true;
356
+ }
357
+ } while (g_get_monotonic_time() < end_time);
358
+ }
359
+
360
+ g_message("%s: Timeout expired", __func__);
361
+ return false;
362
+}
363
+
364
+/* Check emc registers are reset to default value. */
365
+static void test_init(gconstpointer test_data)
366
+{
367
+ const TestData *td = test_data;
368
+ const EMCModule *mod = td->module;
369
+ QTestState *qts = qtest_init("-machine quanta-gsj");
370
+ int i;
371
+
372
+#define CHECK_REG(regno, value) \
373
+ do { \
374
+ g_assert_cmphex(emc_read(qts, mod, (regno)), ==, (value)); \
375
+ } while (0)
376
+
377
+ CHECK_REG(REG_CAMCMR, 0);
378
+ CHECK_REG(REG_CAMEN, 0);
379
+ CHECK_REG(REG_TXDLSA, 0xfffffffc);
380
+ CHECK_REG(REG_RXDLSA, 0xfffffffc);
381
+ CHECK_REG(REG_MCMDR, 0);
382
+ CHECK_REG(REG_MIID, 0);
383
+ CHECK_REG(REG_MIIDA, 0x00900000);
384
+ CHECK_REG(REG_FFTCR, 0x0101);
385
+ CHECK_REG(REG_DMARFC, 0x0800);
386
+ CHECK_REG(REG_MIEN, 0);
387
+ CHECK_REG(REG_MISTA, 0);
388
+ CHECK_REG(REG_MGSTA, 0);
389
+ CHECK_REG(REG_MPCNT, 0x7fff);
390
+ CHECK_REG(REG_MRPC, 0);
391
+ CHECK_REG(REG_MRPCC, 0);
392
+ CHECK_REG(REG_MREPC, 0);
393
+ CHECK_REG(REG_DMARFS, 0);
394
+ CHECK_REG(REG_CTXDSA, 0);
395
+ CHECK_REG(REG_CTXBSA, 0);
396
+ CHECK_REG(REG_CRXDSA, 0);
397
+ CHECK_REG(REG_CRXBSA, 0);
398
+
399
+#undef CHECK_REG
400
+
401
+ for (i = 0; i < NUM_CAMML_REGS; ++i) {
402
+ g_assert_cmpuint(emc_read(qts, mod, REG_CAMM_BASE + i * 2), ==,
403
+ 0);
404
+ g_assert_cmpuint(emc_read(qts, mod, REG_CAML_BASE + i * 2), ==,
405
+ 0);
406
+ }
407
+
408
+ qtest_quit(qts);
409
+}
410
+
411
+static bool emc_wait_irq(QTestState *qts, const EMCModule *mod, int step,
412
+ bool is_tx)
413
+{
414
+ uint64_t end_time =
415
+ g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
416
+
417
+ do {
418
+ if (qtest_get_irq(qts, is_tx ? mod->tx_irq : mod->rx_irq)) {
419
+ return true;
420
+ }
421
+ qtest_clock_step(qts, step);
422
+ } while (g_get_monotonic_time() < end_time);
423
+
424
+ g_message("%s: Timeout expired", __func__);
425
+ return false;
426
+}
427
+
428
+static bool emc_wait_mista(QTestState *qts, const EMCModule *mod, int step,
429
+ uint32_t flag)
430
+{
431
+ uint64_t end_time =
432
+ g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
433
+
434
+ do {
435
+ uint32_t mista = emc_read(qts, mod, REG_MISTA);
436
+ if (mista & flag) {
437
+ return true;
438
+ }
439
+ qtest_clock_step(qts, step);
440
+ } while (g_get_monotonic_time() < end_time);
441
+
442
+ g_message("%s: Timeout expired", __func__);
443
+ return false;
444
+}
445
+
446
+static bool wait_socket_readable(int fd)
447
+{
448
+ fd_set read_fds;
449
+ struct timeval tv;
450
+ int rv;
451
+
452
+ FD_ZERO(&read_fds);
453
+ FD_SET(fd, &read_fds);
454
+ tv.tv_sec = TIMEOUT_SECONDS;
455
+ tv.tv_usec = 0;
456
+ rv = select(fd + 1, &read_fds, NULL, NULL, &tv);
457
+ if (rv == -1) {
458
+ perror("select");
459
+ } else if (rv == 0) {
460
+ g_message("%s: Timeout expired", __func__);
461
+ }
462
+ return rv == 1;
463
+}
464
+
465
+/* Initialize *desc (in host endian format). */
466
+static void init_tx_desc(NPCM7xxEMCTxDesc *desc, size_t count,
467
+ uint32_t desc_addr)
468
+{
469
+ g_assert(count >= 2);
470
+ memset(&desc[0], 0, sizeof(*desc) * count);
471
+ /* Leave the last one alone, owned by the cpu -> stops transmission. */
472
+ for (size_t i = 0; i < count - 1; ++i) {
473
+ desc[i].flags =
474
+ (TX_DESC_FLAG_OWNER_MASK | /* owner = 1: emc */
475
+ TX_DESC_FLAG_INTEN |
476
+ 0 | /* crc append = 0 */
477
+ 0 /* padding enable = 0 */);
478
+ desc[i].status_and_length =
479
+ (0 | /* collision count = 0 */
480
+ 0 | /* SQE = 0 */
481
+ 0 | /* PAU = 0 */
482
+ 0 | /* TXHA = 0 */
483
+ 0 | /* LC = 0 */
484
+ 0 | /* TXABT = 0 */
485
+ 0 | /* NCS = 0 */
486
+ 0 | /* EXDEF = 0 */
487
+ 0 | /* TXCP = 0 */
488
+ 0 | /* DEF = 0 */
489
+ 0 | /* TXINTR = 0 */
490
+ 0 /* length filled in later */);
491
+ desc[i].ntxdsa = desc_addr + (i + 1) * sizeof(*desc);
492
+ }
493
+}
494
+
495
+static void enable_tx(QTestState *qts, const EMCModule *mod,
496
+ const NPCM7xxEMCTxDesc *desc, size_t count,
497
+ uint32_t desc_addr, uint32_t mien_flags)
498
+{
499
+ /* Write the descriptors to guest memory. */
500
+ for (size_t i = 0; i < count; ++i) {
501
+ emc_write_tx_desc(qts, desc + i, desc_addr + i * sizeof(*desc));
502
+ }
503
+
504
+ /* Trigger sending the packet. */
505
+ /* The module must be reset before changing TXDLSA. */
506
+ g_assert(emc_soft_reset(qts, mod));
507
+ emc_write(qts, mod, REG_TXDLSA, desc_addr);
508
+ emc_write(qts, mod, REG_CTXDSA, ~0);
509
+ emc_write(qts, mod, REG_MIEN, REG_MIEN_ENTXCP | mien_flags);
510
+ {
511
+ uint32_t mcmdr = emc_read(qts, mod, REG_MCMDR);
512
+ mcmdr |= REG_MCMDR_TXON;
513
+ emc_write(qts, mod, REG_MCMDR, mcmdr);
514
+ }
515
+
516
+ /* Prod the device to send the packet. */
517
+ emc_write(qts, mod, REG_TSDR, 1);
518
+}
519
+
520
+static void emc_send_verify1(QTestState *qts, const EMCModule *mod, int fd,
521
+ bool with_irq, uint32_t desc_addr,
522
+ uint32_t next_desc_addr,
523
+ const char *test_data, int test_size)
524
+{
525
+ NPCM7xxEMCTxDesc result_desc;
526
+ uint32_t expected_mask, expected_value, recv_len;
527
+ int ret;
528
+ char buffer[TX_DATA_LEN];
529
+
530
+ g_assert(wait_socket_readable(fd));
531
+
532
+ /* Read the descriptor back. */
533
+ emc_read_tx_desc(qts, desc_addr, &result_desc);
534
+ /* Descriptor should be owned by cpu now. */
535
+ g_assert((result_desc.flags & TX_DESC_FLAG_OWNER_MASK) == 0);
536
+ /* Test the status bits, ignoring the length field. */
537
+ expected_mask = 0xffff << 16;
538
+ expected_value = TX_DESC_STATUS_TXCP;
539
+ if (with_irq) {
540
+ expected_value |= TX_DESC_STATUS_TXINTR;
541
+ }
542
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
543
+ expected_value);
544
+
545
+ /* Check data sent to the backend. */
546
+ recv_len = ~0;
547
+ ret = qemu_recv(fd, &recv_len, sizeof(recv_len), MSG_DONTWAIT);
548
+ g_assert_cmpint(ret, == , sizeof(recv_len));
549
+
550
+ g_assert(wait_socket_readable(fd));
551
+ memset(buffer, 0xff, sizeof(buffer));
552
+ ret = qemu_recv(fd, buffer, test_size, MSG_DONTWAIT);
553
+ g_assert_cmpmem(buffer, ret, test_data, test_size);
554
+}
555
+
556
+static void emc_send_verify(QTestState *qts, const EMCModule *mod, int fd,
557
+ bool with_irq)
558
+{
559
+ NPCM7xxEMCTxDesc desc[NUM_TX_DESCRIPTORS];
560
+ uint32_t desc_addr = DESC_ADDR;
561
+ static const char test1_data[] = "TEST1";
562
+ static const char test2_data[] = "Testing 1 2 3 ...";
563
+ uint32_t data1_addr = DATA_ADDR;
564
+ uint32_t data2_addr = data1_addr + sizeof(test1_data);
565
+ bool got_tdu;
566
+ uint32_t end_desc_addr;
567
+
568
+ /* Prepare test data buffer. */
569
+ qtest_memwrite(qts, data1_addr, test1_data, sizeof(test1_data));
570
+ qtest_memwrite(qts, data2_addr, test2_data, sizeof(test2_data));
571
+
572
+ init_tx_desc(&desc[0], NUM_TX_DESCRIPTORS, desc_addr);
573
+ desc[0].txbsa = data1_addr;
574
+ desc[0].status_and_length |= sizeof(test1_data);
575
+ desc[1].txbsa = data2_addr;
576
+ desc[1].status_and_length |= sizeof(test2_data);
577
+
578
+ enable_tx(qts, mod, &desc[0], NUM_TX_DESCRIPTORS, desc_addr,
579
+ with_irq ? REG_MIEN_ENTXINTR : 0);
580
+
581
+ /*
582
+ * It's problematic to observe the interrupt for each packet.
583
+ * Instead just wait until all the packets go out.
584
+ */
585
+ got_tdu = false;
586
+ while (!got_tdu) {
587
+ if (with_irq) {
588
+ g_assert_true(emc_wait_irq(qts, mod, TX_STEP_COUNT,
589
+ /*is_tx=*/true));
590
+ } else {
591
+ g_assert_true(emc_wait_mista(qts, mod, TX_STEP_COUNT,
592
+ REG_MISTA_TXINTR));
593
+ }
594
+ got_tdu = !!(emc_read(qts, mod, REG_MISTA) & REG_MISTA_TDU);
595
+ /* If we don't have TDU yet, reset the interrupt. */
596
+ if (!got_tdu) {
597
+ emc_write(qts, mod, REG_MISTA,
598
+ emc_read(qts, mod, REG_MISTA) & 0xffff0000);
599
+ }
600
+ }
601
+
602
+ end_desc_addr = desc_addr + 2 * sizeof(desc[0]);
603
+ g_assert_cmphex(emc_read(qts, mod, REG_CTXDSA), ==, end_desc_addr);
604
+ g_assert_cmphex(emc_read(qts, mod, REG_MISTA), ==,
605
+ REG_MISTA_TXCP | REG_MISTA_TXINTR | REG_MISTA_TDU);
606
+
607
+ emc_send_verify1(qts, mod, fd, with_irq,
608
+ desc_addr, end_desc_addr,
609
+ test1_data, sizeof(test1_data));
610
+ emc_send_verify1(qts, mod, fd, with_irq,
611
+ desc_addr + sizeof(desc[0]), end_desc_addr,
612
+ test2_data, sizeof(test2_data));
613
+}
614
+
615
+/* Initialize *desc (in host endian format). */
616
+static void init_rx_desc(NPCM7xxEMCRxDesc *desc, size_t count,
617
+ uint32_t desc_addr, uint32_t data_addr)
618
+{
619
+ g_assert_true(count >= 2);
620
+ memset(desc, 0, sizeof(*desc) * count);
621
+ desc[0].rxbsa = data_addr;
622
+ desc[0].status_and_length =
623
+ (0b10 << RX_DESC_STATUS_OWNER_SHIFT | /* owner = 10: emc */
624
+ 0 | /* RP = 0 */
625
+ 0 | /* ALIE = 0 */
626
+ 0 | /* RXGD = 0 */
627
+ 0 | /* PTLE = 0 */
628
+ 0 | /* CRCE = 0 */
629
+ 0 | /* RXINTR = 0 */
630
+ 0 /* length (filled in later) */);
631
+ /* Leave the last one alone, owned by the cpu -> stops transmission. */
632
+ desc[0].nrxdsa = desc_addr + sizeof(*desc);
633
+}
634
+
635
+static void enable_rx(QTestState *qts, const EMCModule *mod,
636
+ const NPCM7xxEMCRxDesc *desc, size_t count,
637
+ uint32_t desc_addr, uint32_t mien_flags,
638
+ uint32_t mcmdr_flags)
639
+{
640
+ /*
641
+ * Write the descriptor to guest memory.
642
+ * FWIW, IWBN if the docs said the buffer needs to be at least DMARFC
643
+ * bytes.
644
+ */
645
+ for (size_t i = 0; i < count; ++i) {
646
+ emc_write_rx_desc(qts, desc + i, desc_addr + i * sizeof(*desc));
647
+ }
648
+
649
+ /* Trigger receiving the packet. */
650
+ /* The module must be reset before changing RXDLSA. */
651
+ g_assert(emc_soft_reset(qts, mod));
652
+ emc_write(qts, mod, REG_RXDLSA, desc_addr);
653
+ emc_write(qts, mod, REG_MIEN, REG_MIEN_ENRXGD | mien_flags);
654
+
655
+ /*
656
+ * We don't know what the device's macaddr is, so just accept all
657
+ * unicast packets (AUP).
658
+ */
659
+ emc_write(qts, mod, REG_CAMCMR, REG_CAMCMR_AUP);
660
+ emc_write(qts, mod, REG_CAMEN, 1 << 0);
661
+ {
662
+ uint32_t mcmdr = emc_read(qts, mod, REG_MCMDR);
663
+ mcmdr |= REG_MCMDR_RXON | mcmdr_flags;
664
+ emc_write(qts, mod, REG_MCMDR, mcmdr);
665
+ }
666
+
667
+ /* Prod the device to accept a packet. */
668
+ emc_write(qts, mod, REG_RSDR, 1);
669
+}
670
+
671
+static void emc_recv_verify(QTestState *qts, const EMCModule *mod, int fd,
672
+ bool with_irq)
673
+{
674
+ NPCM7xxEMCRxDesc desc[NUM_RX_DESCRIPTORS];
675
+ uint32_t desc_addr = DESC_ADDR;
676
+ uint32_t data_addr = DATA_ADDR;
677
+ int ret;
678
+ uint32_t expected_mask, expected_value;
679
+ NPCM7xxEMCRxDesc result_desc;
680
+
681
+ /* Prepare test data buffer. */
682
+ const char test[RX_DATA_LEN] = "TEST";
683
+ int len = htonl(sizeof(test));
684
+ const struct iovec iov[] = {
685
+ {
686
+ .iov_base = &len,
687
+ .iov_len = sizeof(len),
688
+ },{
689
+ .iov_base = (char *) test,
690
+ .iov_len = sizeof(test),
691
+ },
692
+ };
693
+
694
+ /*
695
+ * Reset the device BEFORE sending a test packet, otherwise the packet
696
+ * may get swallowed by an active device of an earlier test.
697
+ */
698
+ init_rx_desc(&desc[0], NUM_RX_DESCRIPTORS, desc_addr, data_addr);
699
+ enable_rx(qts, mod, &desc[0], NUM_RX_DESCRIPTORS, desc_addr,
700
+ with_irq ? REG_MIEN_ENRXINTR : 0, 0);
701
+
702
+ /* Send test packet to device's socket. */
703
+ ret = iov_send(fd, iov, 2, 0, sizeof(len) + sizeof(test));
704
+ g_assert_cmpint(ret, == , sizeof(test) + sizeof(len));
705
+
706
+ /* Wait for RX interrupt. */
707
+ if (with_irq) {
708
+ g_assert_true(emc_wait_irq(qts, mod, RX_STEP_COUNT, /*is_tx=*/false));
709
+ } else {
710
+ g_assert_true(emc_wait_mista(qts, mod, RX_STEP_COUNT, REG_MISTA_RXGD));
711
+ }
712
+
713
+ g_assert_cmphex(emc_read(qts, mod, REG_CRXDSA), ==,
714
+ desc_addr + sizeof(desc[0]));
715
+
716
+ expected_mask = 0xffff;
717
+ expected_value = (REG_MISTA_DENI |
718
+ REG_MISTA_RXGD |
719
+ REG_MISTA_RXINTR);
720
+ g_assert_cmphex((emc_read(qts, mod, REG_MISTA) & expected_mask),
721
+ ==, expected_value);
722
+
723
+ /* Read the descriptor back. */
724
+ emc_read_rx_desc(qts, desc_addr, &result_desc);
725
+ /* Descriptor should be owned by cpu now. */
726
+ g_assert((result_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK) == 0);
727
+ /* Test the status bits, ignoring the length field. */
728
+ expected_mask = 0xffff << 16;
729
+ expected_value = RX_DESC_STATUS_RXGD;
730
+ if (with_irq) {
731
+ expected_value |= RX_DESC_STATUS_RXINTR;
732
+ }
733
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
734
+ expected_value);
735
+ g_assert_cmpint(RX_DESC_PKT_LEN(result_desc.status_and_length), ==,
736
+ RX_DATA_LEN + CRC_LENGTH);
737
+
738
+ {
739
+ char buffer[RX_DATA_LEN];
740
+ qtest_memread(qts, data_addr, buffer, sizeof(buffer));
741
+ g_assert_cmpstr(buffer, == , "TEST");
742
+ }
743
+}
744
+
745
+static void emc_test_ptle(QTestState *qts, const EMCModule *mod, int fd)
746
+{
747
+ NPCM7xxEMCRxDesc desc[NUM_RX_DESCRIPTORS];
748
+ uint32_t desc_addr = DESC_ADDR;
749
+ uint32_t data_addr = DATA_ADDR;
750
+ int ret;
751
+ NPCM7xxEMCRxDesc result_desc;
752
+ uint32_t expected_mask, expected_value;
753
+
754
+ /* Prepare test data buffer. */
755
+#define PTLE_DATA_LEN 1600
756
+ char test_data[PTLE_DATA_LEN];
757
+ int len = htonl(sizeof(test_data));
758
+ const struct iovec iov[] = {
759
+ {
760
+ .iov_base = &len,
761
+ .iov_len = sizeof(len),
762
+ },{
763
+ .iov_base = (char *) test_data,
764
+ .iov_len = sizeof(test_data),
765
+ },
766
+ };
767
+ memset(test_data, 42, sizeof(test_data));
768
+
769
+ /*
770
+ * Reset the device BEFORE sending a test packet, otherwise the packet
771
+ * may get swallowed by an active device of an earlier test.
772
+ */
773
+ init_rx_desc(&desc[0], NUM_RX_DESCRIPTORS, desc_addr, data_addr);
774
+ enable_rx(qts, mod, &desc[0], NUM_RX_DESCRIPTORS, desc_addr,
775
+ REG_MIEN_ENRXINTR, REG_MCMDR_ALP);
776
+
777
+ /* Send test packet to device's socket. */
778
+ ret = iov_send(fd, iov, 2, 0, sizeof(len) + sizeof(test_data));
779
+ g_assert_cmpint(ret, == , sizeof(test_data) + sizeof(len));
780
+
781
+ /* Wait for RX interrupt. */
782
+ g_assert_true(emc_wait_irq(qts, mod, RX_STEP_COUNT, /*is_tx=*/false));
783
+
784
+ /* Read the descriptor back. */
785
+ emc_read_rx_desc(qts, desc_addr, &result_desc);
786
+ /* Descriptor should be owned by cpu now. */
787
+ g_assert((result_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK) == 0);
788
+ /* Test the status bits, ignoring the length field. */
789
+ expected_mask = 0xffff << 16;
790
+ expected_value = (RX_DESC_STATUS_RXGD |
791
+ RX_DESC_STATUS_PTLE |
792
+ RX_DESC_STATUS_RXINTR);
793
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
794
+ expected_value);
795
+ g_assert_cmpint(RX_DESC_PKT_LEN(result_desc.status_and_length), ==,
796
+ PTLE_DATA_LEN + CRC_LENGTH);
797
+
798
+ {
799
+ char buffer[PTLE_DATA_LEN];
800
+ qtest_memread(qts, data_addr, buffer, sizeof(buffer));
801
+ g_assert(memcmp(buffer, test_data, PTLE_DATA_LEN) == 0);
802
+ }
803
+}
804
+
805
+static void test_tx(gconstpointer test_data)
806
+{
807
+ const TestData *td = test_data;
808
+ GString *cmd_line = g_string_new("-machine quanta-gsj");
809
+ int *test_sockets = packet_test_init(emc_module_index(td->module),
810
+ cmd_line);
811
+ QTestState *qts = qtest_init(cmd_line->str);
812
+
813
+ /*
814
+ * TODO: For pedantic correctness test_sockets[0] should be closed after
815
+ * the fork and before the exec, but that will require some harness
816
+ * improvements.
817
+ */
818
+ close(test_sockets[1]);
819
+ /* Defensive programming */
820
+ test_sockets[1] = -1;
821
+
822
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
823
+
824
+ emc_send_verify(qts, td->module, test_sockets[0], /*with_irq=*/false);
825
+ emc_send_verify(qts, td->module, test_sockets[0], /*with_irq=*/true);
826
+
827
+ qtest_quit(qts);
828
+}
829
+
830
+static void test_rx(gconstpointer test_data)
831
+{
832
+ const TestData *td = test_data;
833
+ GString *cmd_line = g_string_new("-machine quanta-gsj");
834
+ int *test_sockets = packet_test_init(emc_module_index(td->module),
835
+ cmd_line);
836
+ QTestState *qts = qtest_init(cmd_line->str);
837
+
838
+ /*
839
+ * TODO: For pedantic correctness test_sockets[0] should be closed after
840
+ * the fork and before the exec, but that will require some harness
841
+ * improvements.
842
+ */
843
+ close(test_sockets[1]);
844
+ /* Defensive programming */
845
+ test_sockets[1] = -1;
846
+
847
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
848
+
849
+ emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/false);
850
+ emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/true);
851
+ emc_test_ptle(qts, td->module, test_sockets[0]);
852
+
853
+ qtest_quit(qts);
854
+}
855
+
856
+static void emc_add_test(const char *name, const TestData* td,
857
+ GTestDataFunc fn)
858
+{
859
+ g_autofree char *full_name = g_strdup_printf(
860
+ "npcm7xx_emc/emc[%d]/%s", emc_module_index(td->module), name);
861
+ qtest_add_data_func(full_name, td, fn);
862
+}
863
+#define add_test(name, td) emc_add_test(#name, td, test_##name)
135
+
864
+
136
+int main(int argc, char **argv)
865
+int main(int argc, char **argv)
137
+{
866
+{
138
+ int r;
867
+ TestData test_data_list[ARRAY_SIZE(emc_module_list)];
139
+
868
+
140
+ g_test_init(&argc, &argv, NULL);
869
+ g_test_init(&argc, &argv, NULL);
141
+
870
+
142
+ qtest_start("-machine mps2-an385");
871
+ for (int i = 0; i < ARRAY_SIZE(emc_module_list); ++i) {
143
+
872
+ TestData *td = &test_data_list[i];
144
+ qtest_add_func("/cmsdk-apb-dualtimer/dualtimer", test_dualtimer);
873
+
145
+ qtest_add_func("/cmsdk-apb-dualtimer/prescale", test_prescale);
874
+ td->module = &emc_module_list[i];
146
+
875
+
147
+ r = g_test_run();
876
+ add_test(init, td);
148
+
877
+ add_test(tx, td);
149
+ qtest_end();
878
+ add_test(rx, td);
150
+
879
+ }
151
+ return r;
880
+
152
+}
881
+ return g_test_run();
153
diff --git a/MAINTAINERS b/MAINTAINERS
882
+}
154
index XXXXXXX..XXXXXXX 100644
155
--- a/MAINTAINERS
156
+++ b/MAINTAINERS
157
@@ -XXX,XX +XXX,XX @@ F: include/hw/timer/cmsdk-apb-timer.h
158
F: tests/qtest/cmsdk-apb-timer-test.c
159
F: hw/timer/cmsdk-apb-dualtimer.c
160
F: include/hw/timer/cmsdk-apb-dualtimer.h
161
+F: tests/qtest/cmsdk-apb-dualtimer-test.c
162
F: hw/char/cmsdk-apb-uart.c
163
F: include/hw/char/cmsdk-apb-uart.h
164
F: hw/watchdog/cmsdk-apb-watchdog.c
165
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
883
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
166
index XXXXXXX..XXXXXXX 100644
884
index XXXXXXX..XXXXXXX 100644
167
--- a/tests/qtest/meson.build
885
--- a/tests/qtest/meson.build
168
+++ b/tests/qtest/meson.build
886
+++ b/tests/qtest/meson.build
169
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
887
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
888
'npcm7xx_rng-test',
889
'npcm7xx_smbus-test',
170
'npcm7xx_timer-test',
890
'npcm7xx_timer-test',
171
'npcm7xx_watchdog_timer-test']
891
- 'npcm7xx_watchdog_timer-test']
892
+ 'npcm7xx_watchdog_timer-test'] + \
893
+ (slirp.found() ? ['npcm7xx_emc-test'] : [])
172
qtests_arm = \
894
qtests_arm = \
173
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
895
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
174
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
896
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
175
(config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
176
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
177
--
897
--
178
2.20.1
898
2.20.1
179
899
180
900
diff view generated by jsdifflib
1
From: Joelle van Dyne <j@getutm.app>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
A workaround added in early days of 64-bit OSX forced x86_64 if the
3
We hint the 'has_rpu' property is no longer required since commit
4
host machine had 64-bit support. This creates issues when cross-
4
6908ec448b4 ("xlnx-zynqmp: Properly support the smp command line
5
compiling for ARM64. Additionally, the user can always use --cpu=* to
5
option") which was released in QEMU v2.11.0.
6
manually set the host CPU and therefore this workaround should be
6
7
removed.
7
Beside, this device is marked 'user_creatable = false', so the
8
only thing that could be setting the property is the board code
9
that creates the device.
10
11
Since the property is not user-facing, we can remove it without
12
going through the deprecation process.
8
13
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Joelle van Dyne <j@getutm.app>
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210126012457.39046-12-j@getutm.app
16
Message-id: 20210219144350.1979905-1-f4bug@amsat.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
18
---
14
configure | 11 -----------
19
include/hw/arm/xlnx-zynqmp.h | 2 --
15
1 file changed, 11 deletions(-)
20
hw/arm/xlnx-zynqmp.c | 6 ------
21
2 files changed, 8 deletions(-)
16
22
17
diff --git a/configure b/configure
23
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
18
index XXXXXXX..XXXXXXX 100755
24
index XXXXXXX..XXXXXXX 100644
19
--- a/configure
25
--- a/include/hw/arm/xlnx-zynqmp.h
20
+++ b/configure
26
+++ b/include/hw/arm/xlnx-zynqmp.h
21
@@ -XXX,XX +XXX,XX @@ fi
27
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
22
# the correct CPU with the --cpu option.
28
bool secure;
23
case $targetos in
29
/* Has the ARM Virtualization extensions? */
24
Darwin)
30
bool virt;
25
- # on Leopard most of the system is 32-bit, so we have to ask the kernel if we can
31
- /* Has the RPU subsystem? */
26
- # run 64-bit userspace code.
32
- bool has_rpu;
27
- # If the user didn't specify a CPU explicitly and the kernel says this is
33
28
- # 64 bit hw, then assume x86_64. Otherwise fall through to the usual detection code.
34
/* CAN bus. */
29
- if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
35
CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
30
- cpu="x86_64"
36
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
31
- fi
37
index XXXXXXX..XXXXXXX 100644
32
HOST_DSOSUF=".dylib"
38
--- a/hw/arm/xlnx-zynqmp.c
33
;;
39
+++ b/hw/arm/xlnx-zynqmp.c
34
SunOS)
40
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
35
@@ -XXX,XX +XXX,XX @@ OpenBSD)
41
}
36
Darwin)
42
}
37
bsd="yes"
43
38
darwin="yes"
44
- if (s->has_rpu) {
39
- if [ "$cpu" = "x86_64" ] ; then
45
- info_report("The 'has_rpu' property is no longer required, to use the "
40
- QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
46
- "RPUs just use -smp 6.");
41
- QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
47
- }
42
- fi
48
-
43
audio_drv_list="try-coreaudio try-sdl"
49
xlnx_zynqmp_create_rpu(ms, s, boot_cpu, &err);
44
audio_possible_drivers="coreaudio sdl"
50
if (err) {
45
# Disable attempts to use ObjectiveC features in os/object.h since they
51
error_propagate(errp, err);
52
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
53
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
54
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
55
DEFINE_PROP_BOOL("virtualization", XlnxZynqMPState, virt, false),
56
- DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
57
DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
58
MemoryRegion *),
59
DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
46
--
60
--
47
2.20.1
61
2.20.1
48
62
49
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Only define the register if it exists for the cpu.
3
Always perform one call instead of two for 16-byte operands.
4
Use byte loads/stores directly into the vector register file
5
instead of extractions and deposits to a 64-bit local variable.
6
7
In order to easily receive pointers into the vector register file,
8
convert the helper to the gvec out-of-line signature. Move the
9
helper into vec_helper.c, where it can make use of H1 and clear_tail.
4
10
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210120031656.737646-1-richard.henderson@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20210224230532.276878-1-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
16
---
10
target/arm/helper.c | 21 +++++++++++++++------
17
target/arm/helper-a64.h | 2 +-
11
1 file changed, 15 insertions(+), 6 deletions(-)
18
target/arm/helper-a64.c | 32 ---------------------
12
19
target/arm/translate-a64.c | 58 +++++---------------------------------
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
target/arm/vec_helper.c | 48 +++++++++++++++++++++++++++++++
14
index XXXXXXX..XXXXXXX 100644
21
4 files changed, 56 insertions(+), 84 deletions(-)
15
--- a/target/arm/helper.c
22
16
+++ b/target/arm/helper.c
23
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
24
index XXXXXXX..XXXXXXX 100644
18
*/
25
--- a/target/arm/helper-a64.h
19
int i;
26
+++ b/target/arm/helper-a64.h
20
int wrps, brps, ctx_cmps;
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
21
- ARMCPRegInfo dbgdidr = {
28
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
22
- .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
29
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
23
- .access = PL0_R, .accessfn = access_tda,
30
DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr)
24
- .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
31
-DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32)
25
- };
32
+DEF_HELPER_FLAGS_4(simd_tblx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
DEF_HELPER_FLAGS_3(vfp_mulxs, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
34
DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
35
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
36
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/helper-a64.c
39
+++ b/target/arm/helper-a64.c
40
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp)
41
return float64_mul(a, b, fpst);
42
}
43
44
-uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
45
- uint32_t rn, uint32_t numregs)
46
-{
47
- /* Helper function for SIMD TBL and TBX. We have to do the table
48
- * lookup part for the 64 bits worth of indices we're passed in.
49
- * result is the initial results vector (either zeroes for TBL
50
- * or some guest values for TBX), rn the register number where
51
- * the table starts, and numregs the number of registers in the table.
52
- * We return the results of the lookups.
53
- */
54
- int shift;
55
-
56
- for (shift = 0; shift < 64; shift += 8) {
57
- int index = extract64(indices, shift, 8);
58
- if (index < 16 * numregs) {
59
- /* Convert index (a byte offset into the virtual table
60
- * which is a series of 128-bit vectors concatenated)
61
- * into the correct register element plus a bit offset
62
- * into that element, bearing in mind that the table
63
- * can wrap around from V31 to V0.
64
- */
65
- int elt = (rn * 2 + (index >> 3)) % 64;
66
- int bitidx = (index & 7) * 8;
67
- uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
68
- uint64_t val = extract64(q[elt & 1], bitidx, 8);
69
-
70
- result = deposit64(result, shift, 8, val);
71
- }
72
- }
73
- return result;
74
-}
75
-
76
/* 64bit/double versions of the neon float compare functions */
77
uint64_t HELPER(neon_ceq_f64)(float64 a, float64 b, void *fpstp)
78
{
79
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/translate-a64.c
82
+++ b/target/arm/translate-a64.c
83
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
84
int rm = extract32(insn, 16, 5);
85
int rn = extract32(insn, 5, 5);
86
int rd = extract32(insn, 0, 5);
87
- int is_tblx = extract32(insn, 12, 1);
88
- int len = extract32(insn, 13, 2);
89
- TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
90
- TCGv_i32 tcg_regno, tcg_numregs;
91
+ int is_tbx = extract32(insn, 12, 1);
92
+ int len = (extract32(insn, 13, 2) + 1) * 16;
93
94
if (op2 != 0) {
95
unallocated_encoding(s);
96
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
97
return;
98
}
99
100
- /* This does a table lookup: for every byte element in the input
101
- * we index into a table formed from up to four vector registers,
102
- * and then the output is the result of the lookups. Our helper
103
- * function does the lookup operation for a single 64 bit part of
104
- * the input.
105
- */
106
- tcg_resl = tcg_temp_new_i64();
107
- tcg_resh = NULL;
108
-
109
- if (is_tblx) {
110
- read_vec_element(s, tcg_resl, rd, 0, MO_64);
111
- } else {
112
- tcg_gen_movi_i64(tcg_resl, 0);
113
- }
114
-
115
- if (is_q) {
116
- tcg_resh = tcg_temp_new_i64();
117
- if (is_tblx) {
118
- read_vec_element(s, tcg_resh, rd, 1, MO_64);
119
- } else {
120
- tcg_gen_movi_i64(tcg_resh, 0);
121
- }
122
- }
123
-
124
- tcg_idx = tcg_temp_new_i64();
125
- tcg_regno = tcg_const_i32(rn);
126
- tcg_numregs = tcg_const_i32(len + 1);
127
- read_vec_element(s, tcg_idx, rm, 0, MO_64);
128
- gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
129
- tcg_regno, tcg_numregs);
130
- if (is_q) {
131
- read_vec_element(s, tcg_idx, rm, 1, MO_64);
132
- gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
133
- tcg_regno, tcg_numregs);
134
- }
135
- tcg_temp_free_i64(tcg_idx);
136
- tcg_temp_free_i32(tcg_regno);
137
- tcg_temp_free_i32(tcg_numregs);
138
-
139
- write_vec_element(s, tcg_resl, rd, 0, MO_64);
140
- tcg_temp_free_i64(tcg_resl);
141
-
142
- if (is_q) {
143
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
144
- tcg_temp_free_i64(tcg_resh);
145
- }
146
- clear_vec_high(s, is_q, rd);
147
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
148
+ vec_full_reg_offset(s, rm), cpu_env,
149
+ is_q ? 16 : 8, vec_full_reg_size(s),
150
+ (len << 6) | (is_tbx << 5) | rn,
151
+ gen_helper_simd_tblx);
152
}
153
154
/* ZIP/UZP/TRN
155
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/vec_helper.c
158
+++ b/target/arm/vec_helper.c
159
@@ -XXX,XX +XXX,XX @@ DO_VRINT_RMODE(gvec_vrint_rm_h, helper_rinth, uint16_t)
160
DO_VRINT_RMODE(gvec_vrint_rm_s, helper_rints, uint32_t)
161
162
#undef DO_VRINT_RMODE
163
+
164
+#ifdef TARGET_AARCH64
165
+void HELPER(simd_tblx)(void *vd, void *vm, void *venv, uint32_t desc)
166
+{
167
+ const uint8_t *indices = vm;
168
+ CPUARMState *env = venv;
169
+ size_t oprsz = simd_oprsz(desc);
170
+ uint32_t rn = extract32(desc, SIMD_DATA_SHIFT, 5);
171
+ bool is_tbx = extract32(desc, SIMD_DATA_SHIFT + 5, 1);
172
+ uint32_t table_len = desc >> (SIMD_DATA_SHIFT + 6);
173
+ union {
174
+ uint8_t b[16];
175
+ uint64_t d[2];
176
+ } result;
26
+
177
+
27
+ /*
178
+ /*
28
+ * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot
179
+ * We must construct the final result in a temp, lest the output
29
+ * use AArch32. Given that bit 15 is RES1, if the value is 0 then
180
+ * overlaps the input table. For TBL, begin with zero; for TBX,
30
+ * the register must not exist for this cpu.
181
+ * begin with the original register contents. Note that we always
182
+ * copy 16 bytes here to avoid an extra branch; clearing the high
183
+ * bits of the register for oprsz == 8 is handled below.
31
+ */
184
+ */
32
+ if (cpu->isar.dbgdidr != 0) {
185
+ if (is_tbx) {
33
+ ARMCPRegInfo dbgdidr = {
186
+ memcpy(&result, vd, 16);
34
+ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
187
+ } else {
35
+ .opc1 = 0, .opc2 = 0,
188
+ memset(&result, 0, 16);
36
+ .access = PL0_R, .accessfn = access_tda,
37
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
38
+ };
39
+ define_one_arm_cp_reg(cpu, &dbgdidr);
40
+ }
189
+ }
41
190
+
42
/* Note that all these register fields hold "number of Xs minus 1". */
191
+ for (size_t i = 0; i < oprsz; ++i) {
43
brps = arm_num_brps(cpu);
192
+ uint32_t index = indices[H1(i)];
44
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
193
+
45
194
+ if (index < table_len) {
46
assert(ctx_cmps <= brps);
195
+ /*
47
196
+ * Convert index (a byte offset into the virtual table
48
- define_one_arm_cp_reg(cpu, &dbgdidr);
197
+ * which is a series of 128-bit vectors concatenated)
49
define_arm_cp_regs(cpu, debug_cp_reginfo);
198
+ * into the correct register element, bearing in mind
50
199
+ * that the table can wrap around from V31 to V0.
51
if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
200
+ */
201
+ const uint8_t *table = (const uint8_t *)
202
+ aa64_vfp_qreg(env, (rn + (index >> 4)) % 32);
203
+ result.b[H1(i)] = table[H1(index % 16)];
204
+ }
205
+ }
206
+
207
+ memcpy(vd, &result, 16);
208
+ clear_tail(vd, oprsz, simd_maxsz(desc));
209
+}
210
+#endif
52
--
211
--
53
2.20.1
212
2.20.1
54
213
55
214
diff view generated by jsdifflib
1
From: Joelle van Dyne <j@getutm.app>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Meson will find CoreFoundation, IOKit, and Cocoa as needed.
3
The STATUS register will be reset to IDLE in
4
cnpcm7xx_smbus_enter_reset(), no need to preset
5
it in instance_init().
4
6
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
8
Reviewed-by: Hao Wu <wuhaotsh@google.com>
7
Message-id: 20210126012457.39046-7-j@getutm.app
9
Message-id: 20210228224813.312532-1-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
configure | 1 -
12
hw/i2c/npcm7xx_smbus.c | 1 -
11
1 file changed, 1 deletion(-)
13
1 file changed, 1 deletion(-)
12
14
13
diff --git a/configure b/configure
15
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
14
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100644
15
--- a/configure
17
--- a/hw/i2c/npcm7xx_smbus.c
16
+++ b/configure
18
+++ b/hw/i2c/npcm7xx_smbus.c
17
@@ -XXX,XX +XXX,XX @@ Darwin)
19
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_init(Object *obj)
18
fi
20
sysbus_init_mmio(sbd, &s->iomem);
19
audio_drv_list="coreaudio try-sdl"
21
20
audio_possible_drivers="coreaudio sdl"
22
s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
21
- QEMU_LDFLAGS="-framework CoreFoundation -framework IOKit $QEMU_LDFLAGS"
23
- s->status = NPCM7XX_SMBUS_STATUS_IDLE;
22
# Disable attempts to use ObjectiveC features in os/object.h since they
24
}
23
# won't work when we're compiling with gcc as a C compiler.
25
24
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
26
static const VMStateDescription vmstate_npcm7xx_smbus = {
25
--
27
--
26
2.20.1
28
2.20.1
27
29
28
30
diff view generated by jsdifflib
1
From: Joelle van Dyne <j@getutm.app>
1
From: schspa <schspa@gmail.com>
2
2
3
Build without error on hosts without a working system(). If system()
3
At the moment the following QEMU command line triggers an assertion
4
is called, return -1 with ENOSYS.
4
failure On xlnx-versal SOC:
5
qemu-system-aarch64 \
6
-machine xlnx-versal-virt -nographic -smp 2 -m 128 \
7
-fsdev local,id=shareid,path=${HOME}/work,security_model=none \
8
-device virtio-9p-device,fsdev=shareid,mount_tag=share \
9
-fsdev local,id=shareid1,path=${HOME}/Music,security_model=none \
10
-device virtio-9p-device,fsdev=shareid1,mount_tag=share1
5
11
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
12
qemu-system-aarch64: ../migration/savevm.c:860:
7
Message-id: 20210126012457.39046-6-j@getutm.app
13
vmstate_register_with_alias_id:
14
Assertion `!se->compat || se->instance_id == 0' failed.
15
16
This problem was fixed on arm virt platform in commit f58b39d2d5b
17
("virtio-mmio: format transport base address in BusClass.get_dev_path")
18
19
It works perfectly on arm virt platform. but there is still there on
20
xlnx-versal SOC.
21
22
The main difference between arm virt and xlnx-versal is they use
23
different way to create virtio-mmio qdev. on arm virt, it calls
24
sysbus_create_simple("virtio-mmio", base, pic[irq]); which will call
25
sysbus_mmio_map internally and assign base address to subsys device
26
mmio correctly. but xlnx-versal's implements won't do this.
27
28
However, xlnx-versal can't switch to sysbus_create_simple() to create
29
virtio-mmio device. It's because xlnx-versal's cpu use
30
VersalVirt.soc.fpd.apu.mr as it's memory. which is subregion of
31
system_memory. sysbus_create_simple will add virtio to system_memory,
32
which can't be accessed by cpu.
33
34
Besides, xlnx-versal can't add sysbus_mmio_map api call too, because
35
this will add memory region to system_memory, and it can't be added
36
to VersalVirt.soc.fpd.apu.mr again.
37
38
We can solve this by assign correct base address offset on dev_path.
39
40
This path was test on aarch64 virt & xlnx-versal platform.
41
42
Signed-off-by: schspa <schspa@gmail.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
45
---
11
meson.build | 1 +
46
hw/virtio/virtio-mmio.c | 13 +++++++------
12
include/qemu/osdep.h | 12 ++++++++++++
47
1 file changed, 7 insertions(+), 6 deletions(-)
13
2 files changed, 13 insertions(+)
14
48
15
diff --git a/meson.build b/meson.build
49
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
16
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
17
--- a/meson.build
51
--- a/hw/virtio/virtio-mmio.c
18
+++ b/meson.build
52
+++ b/hw/virtio/virtio-mmio.c
19
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
53
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
20
config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
54
BusState *virtio_mmio_bus;
21
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
55
VirtIOMMIOProxy *virtio_mmio_proxy;
22
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
56
char *proxy_path;
23
+config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
57
- SysBusDevice *proxy_sbd;
24
58
char *path;
25
config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
59
+ MemoryRegionSection section;
26
60
27
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
61
virtio_mmio_bus = qdev_get_parent_bus(dev);
28
index XXXXXXX..XXXXXXX 100644
62
virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
29
--- a/include/qemu/osdep.h
63
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
30
+++ b/include/qemu/osdep.h
64
}
31
@@ -XXX,XX +XXX,XX @@ static inline void qemu_thread_jit_write(void) {}
65
32
static inline void qemu_thread_jit_execute(void) {}
66
/* Otherwise, we append the base address of the transport. */
33
#endif
67
- proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
34
68
- assert(proxy_sbd->num_mmio == 1);
35
+/**
69
- assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
36
+ * Platforms which do not support system() return ENOSYS
70
+ section = memory_region_find(&virtio_mmio_proxy->iomem, 0, 0x200);
37
+ */
71
+ assert(section.mr);
38
+#ifndef HAVE_SYSTEM_FUNCTION
72
39
+#define system platform_does_not_support_system
73
if (proxy_path) {
40
+static inline int platform_does_not_support_system(const char *command)
74
path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
41
+{
75
- proxy_sbd->mmio[0].addr);
42
+ errno = ENOSYS;
76
+ section.offset_within_address_space);
43
+ return -1;
77
} else {
44
+}
78
path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
45
+#endif /* !HAVE_SYSTEM_FUNCTION */
79
- proxy_sbd->mmio[0].addr);
80
+ section.offset_within_address_space);
81
}
82
+ memory_region_unref(section.mr);
46
+
83
+
47
#endif
84
g_free(proxy_path);
85
return path;
86
}
48
--
87
--
49
2.20.1
88
2.20.1
50
89
51
90
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Peter Collingbourne <pcc@google.com>
2
2
3
Fix potential overflow problem when calculating pwm_duty.
3
Section D6.7 of the ARM ARM states:
4
1. Ensure p->cmr and p->cnr to be from [0,65535], according to the
5
hardware specification.
6
2. Changed duty to uint32_t. However, since MAX_DUTY * (p->cmr+1)
7
can excceed UINT32_MAX, we convert them to uint64_t in computation
8
and converted them back to uint32_t.
9
(duty is guaranteed to be <= MAX_DUTY so it won't overflow.)
10
4
11
Fixes: CID 1442342
5
For the purpose of determining Tag Check Fault handling, unprivileged
12
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
load and store instructions are treated as if executed at EL0 when
13
Reviewed-by: Doug Evans <dje@google.com>
7
executed at either:
14
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
- EL1, when the Effective value of PSTATE.UAO is 0.
15
Message-id: 20210127011142.2122790-1-wuhaotsh@google.com
9
- EL2, when both the Effective value of HCR_EL2.{E2H, TGE} is {1, 1}
10
and the Effective value of PSTATE.UAO is 0.
11
12
ARM has confirmed a defect in the pseudocode function
13
AArch64.TagCheckFault that makes it inconsistent with the above
14
wording. The remedy is to adjust references to PSTATE.EL in that
15
function to instead refer to AArch64.AccessUsesEL(acctype), so
16
that unprivileged instructions use SCTLR_EL1.TCF0 and TFSRE0_EL1.
17
The exception type for synchronous tag check faults remains unchanged.
18
19
This patch implements the described change by partially reverting
20
commits 50244cc76abc and cc97b0019bb5.
21
22
Signed-off-by: Peter Collingbourne <pcc@google.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20210219201820.2672077-1-pcc@google.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
27
---
19
hw/misc/npcm7xx_pwm.c | 23 +++++++++++++++++++----
28
target/arm/helper.c | 2 +-
20
tests/qtest/npcm7xx_pwm-test.c | 4 ++--
29
target/arm/mte_helper.c | 13 +++++++++----
21
2 files changed, 21 insertions(+), 6 deletions(-)
30
2 files changed, 10 insertions(+), 5 deletions(-)
22
31
23
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/misc/npcm7xx_pwm.c
34
--- a/target/arm/helper.c
26
+++ b/hw/misc/npcm7xx_pwm.c
35
+++ b/target/arm/helper.c
27
@@ -XXX,XX +XXX,XX @@ REG32(NPCM7XX_PWM_PWDR3, 0x50);
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
28
#define NPCM7XX_CH_INV BIT(2)
37
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
29
#define NPCM7XX_CH_MOD BIT(3)
38
&& tbid
30
39
&& !(env->pstate & PSTATE_TCO)
31
+#define NPCM7XX_MAX_CMR 65535
40
- && (sctlr & SCTLR_TCF)
32
+#define NPCM7XX_MAX_CNR 65535
41
+ && (sctlr & SCTLR_TCF0)
33
+
42
&& allocation_tag_access_enabled(env, 0, sctlr)) {
34
/* Offset of each PWM channel's prescaler in the PPR register. */
43
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
35
static const int npcm7xx_ppr_base[] = { 0, 0, 8, 8 };
36
/* Offset of each PWM channel's clock selector in the CSR register. */
37
@@ -XXX,XX +XXX,XX @@ static uint32_t npcm7xx_pwm_calculate_freq(NPCM7xxPWM *p)
38
39
static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
40
{
41
- uint64_t duty;
42
+ uint32_t duty;
43
44
if (p->running) {
45
if (p->cnr == 0) {
46
@@ -XXX,XX +XXX,XX @@ static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
47
} else if (p->cmr >= p->cnr) {
48
duty = NPCM7XX_PWM_MAX_DUTY;
49
} else {
50
- duty = NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
51
+ duty = (uint64_t)NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
52
}
44
}
53
} else {
45
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
54
duty = 0;
55
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
56
case A_NPCM7XX_PWM_CNR2:
57
case A_NPCM7XX_PWM_CNR3:
58
p = &s->pwm[npcm7xx_cnr_index(offset)];
59
- p->cnr = value;
60
+ if (value > NPCM7XX_MAX_CNR) {
61
+ qemu_log_mask(LOG_GUEST_ERROR,
62
+ "%s: invalid cnr value: %u", __func__, value);
63
+ p->cnr = NPCM7XX_MAX_CNR;
64
+ } else {
65
+ p->cnr = value;
66
+ }
67
npcm7xx_pwm_update_output(p);
68
break;
69
70
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
71
case A_NPCM7XX_PWM_CMR2:
72
case A_NPCM7XX_PWM_CMR3:
73
p = &s->pwm[npcm7xx_cmr_index(offset)];
74
- p->cmr = value;
75
+ if (value > NPCM7XX_MAX_CMR) {
76
+ qemu_log_mask(LOG_GUEST_ERROR,
77
+ "%s: invalid cmr value: %u", __func__, value);
78
+ p->cmr = NPCM7XX_MAX_CMR;
79
+ } else {
80
+ p->cmr = value;
81
+ }
82
npcm7xx_pwm_update_output(p);
83
break;
84
85
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
86
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
87
--- a/tests/qtest/npcm7xx_pwm-test.c
47
--- a/target/arm/mte_helper.c
88
+++ b/tests/qtest/npcm7xx_pwm-test.c
48
+++ b/target/arm/mte_helper.c
89
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_compute_freq(QTestState *qts, uint32_t ppr, uint32_t csr,
49
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
90
50
reg_el = regime_el(env, arm_mmu_idx);
91
static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
51
sctlr = env->cp15.sctlr_el[reg_el];
92
{
52
93
- uint64_t duty;
53
- el = arm_current_el(env);
94
+ uint32_t duty;
54
- if (el == 0) {
95
55
+ switch (arm_mmu_idx) {
96
if (cnr == 0) {
56
+ case ARMMMUIdx_E10_0:
97
/* PWM is stopped. */
57
+ case ARMMMUIdx_E20_0:
98
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
58
+ el = 0;
99
} else if (cmr >= cnr) {
59
tcf = extract64(sctlr, 38, 2);
100
duty = MAX_DUTY;
60
- } else {
101
} else {
61
+ break;
102
- duty = MAX_DUTY * (cmr + 1) / (cnr + 1);
62
+ default:
103
+ duty = (uint64_t)MAX_DUTY * (cmr + 1) / (cnr + 1);
63
+ el = reg_el;
64
tcf = extract64(sctlr, 40, 2);
104
}
65
}
105
66
106
if (inverted) {
67
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
68
env->exception.vaddress = dirty_ptr;
69
70
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
71
- syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
72
+ syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
73
+ is_write, 0x11);
74
raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
75
/* noreturn, but fall through to the assert anyway */
76
107
--
77
--
108
2.20.1
78
2.20.1
109
79
110
80
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Implement gpio-pwr driver to allow reboot and poweroff machine.
3
IDAU is specific to M-profile. KVM only supports A-profile.
4
This is simple driver with just 2 gpios lines. Current use case
4
Restrict this interface to TCG, as it is pointless (and
5
is to reboot and poweroff virt machine in secure mode. Secure
5
confusing) on a KVM-only build.
6
pl066 gpio chip is needed for that.
7
6
8
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210221222617.2579610-2-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/gpio/gpio_pwr.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
13
target/arm/cpu.c | 7 -------
14
hw/gpio/Kconfig | 3 ++
14
target/arm/cpu_tcg.c | 8 ++++++++
15
hw/gpio/meson.build | 1 +
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
3 files changed, 74 insertions(+)
17
create mode 100644 hw/gpio/gpio_pwr.c
18
16
19
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
new file mode 100644
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX
19
--- a/target/arm/cpu.c
22
--- /dev/null
20
+++ b/target/arm/cpu.c
23
+++ b/hw/gpio/gpio_pwr.c
21
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
22
.class_init = arm_cpu_class_init,
23
};
24
25
-static const TypeInfo idau_interface_type_info = {
26
- .name = TYPE_IDAU_INTERFACE,
27
- .parent = TYPE_INTERFACE,
28
- .class_size = sizeof(IDAUInterfaceClass),
29
-};
30
-
31
static void arm_cpu_register_types(void)
32
{
33
const size_t cpu_count = ARRAY_SIZE(arm_cpus);
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
35
if (cpu_count) {
36
size_t i;
37
38
- type_register_static(&idau_interface_type_info);
39
for (i = 0; i < cpu_count; ++i) {
40
arm_cpu_register(&arm_cpus[i]);
41
}
42
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/cpu_tcg.c
45
+++ b/target/arm/cpu_tcg.c
24
@@ -XXX,XX +XXX,XX @@
46
@@ -XXX,XX +XXX,XX @@
25
+/*
47
#include "hw/core/tcg-cpu-ops.h"
26
+ * GPIO qemu power controller
48
#endif /* CONFIG_TCG */
27
+ *
49
#include "internals.h"
28
+ * Copyright (c) 2020 Linaro Limited
50
+#include "target/arm/idau.h"
29
+ *
51
30
+ * Author: Maxim Uvarov <maxim.uvarov@linaro.org>
52
/* CPU models. These are not needed for the AArch64 linux-user build. */
31
+ *
53
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
32
+ * Virtual gpio driver which can be used on top of pl061
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
33
+ * to reboot and shutdown qemu virtual machine. One of use
55
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
34
+ * case is gpio driver for secure world application (ARM
56
};
35
+ * Trusted Firmware.).
57
36
+ *
58
+static const TypeInfo idau_interface_type_info = {
37
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
59
+ .name = TYPE_IDAU_INTERFACE,
38
+ * See the COPYING file in the top-level directory.
60
+ .parent = TYPE_INTERFACE,
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
61
+ .class_size = sizeof(IDAUInterfaceClass),
40
+ */
41
+
42
+/*
43
+ * QEMU interface:
44
+ * two named input GPIO lines:
45
+ * 'reset' : when asserted, trigger system reset
46
+ * 'shutdown' : when asserted, trigger system shutdown
47
+ */
48
+
49
+#include "qemu/osdep.h"
50
+#include "hw/sysbus.h"
51
+#include "sysemu/runstate.h"
52
+
53
+#define TYPE_GPIOPWR "gpio-pwr"
54
+OBJECT_DECLARE_SIMPLE_TYPE(GPIO_PWR_State, GPIOPWR)
55
+
56
+struct GPIO_PWR_State {
57
+ SysBusDevice parent_obj;
58
+};
62
+};
59
+
63
+
60
+static void gpio_pwr_reset(void *opaque, int n, int level)
64
static void arm_tcg_cpu_register_types(void)
61
+{
65
{
62
+ if (level) {
66
size_t i;
63
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
67
64
+ }
68
+ type_register_static(&idau_interface_type_info);
65
+}
69
for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
66
+
70
arm_cpu_register(&arm_tcg_cpus[i]);
67
+static void gpio_pwr_shutdown(void *opaque, int n, int level)
71
}
68
+{
69
+ if (level) {
70
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
71
+ }
72
+}
73
+
74
+static void gpio_pwr_init(Object *obj)
75
+{
76
+ DeviceState *dev = DEVICE(obj);
77
+
78
+ qdev_init_gpio_in_named(dev, gpio_pwr_reset, "reset", 1);
79
+ qdev_init_gpio_in_named(dev, gpio_pwr_shutdown, "shutdown", 1);
80
+}
81
+
82
+static const TypeInfo gpio_pwr_info = {
83
+ .name = TYPE_GPIOPWR,
84
+ .parent = TYPE_SYS_BUS_DEVICE,
85
+ .instance_size = sizeof(GPIO_PWR_State),
86
+ .instance_init = gpio_pwr_init,
87
+};
88
+
89
+static void gpio_pwr_register_types(void)
90
+{
91
+ type_register_static(&gpio_pwr_info);
92
+}
93
+
94
+type_init(gpio_pwr_register_types)
95
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
96
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/gpio/Kconfig
98
+++ b/hw/gpio/Kconfig
99
@@ -XXX,XX +XXX,XX @@ config PL061
100
config GPIO_KEY
101
bool
102
103
+config GPIO_PWR
104
+ bool
105
+
106
config SIFIVE_GPIO
107
bool
108
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/gpio/meson.build
111
+++ b/hw/gpio/meson.build
112
@@ -XXX,XX +XXX,XX @@
113
softmmu_ss.add(when: 'CONFIG_E500', if_true: files('mpc8xxx.c'))
114
softmmu_ss.add(when: 'CONFIG_GPIO_KEY', if_true: files('gpio_key.c'))
115
+softmmu_ss.add(when: 'CONFIG_GPIO_PWR', if_true: files('gpio_pwr.c'))
116
softmmu_ss.add(when: 'CONFIG_MAX7310', if_true: files('max7310.c'))
117
softmmu_ss.add(when: 'CONFIG_PL061', if_true: files('pl061.c'))
118
softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_gpio.c'))
119
--
72
--
120
2.20.1
73
2.20.1
121
74
122
75
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
cpu_get_phys_page_debug() uses 'DATA LOAD' MMU access type.
3
We will move this code in the next commit. Clean it up
4
first to avoid checkpatch.pl errors.
4
5
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210127232822.3530782-1-f4bug@amsat.org
7
Message-id: 20210221222617.2579610-3-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/helper.c | 2 +-
11
target/arm/cpu.c | 12 ++++++++----
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 8 insertions(+), 4 deletions(-)
12
13
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
--- a/target/arm/cpu.c
16
+++ b/target/arm/helper.c
17
+++ b/target/arm/cpu.c
17
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
18
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
18
19
}
19
*attrs = (MemTxAttrs) {};
20
20
21
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
21
- ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
22
- /* power_control should be set to maximum latency. Again,
22
+ ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &phys_addr,
23
+ /*
23
attrs, &prot, &page_size, &fi, &cacheattrs);
24
+ * power_control should be set to maximum latency. Again,
24
25
* default to 0 and set by private hook
25
if (ret) {
26
*/
27
{ .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
28
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
29
set_feature(&cpu->env, ARM_FEATURE_NEON);
30
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
31
set_feature(&cpu->env, ARM_FEATURE_EL3);
32
- /* Note that A9 supports the MP extensions even for
33
+ /*
34
+ * Note that A9 supports the MP extensions even for
35
* A9UP and single-core A9MP (which are both different
36
* and valid configurations; we don't model A9UP).
37
*/
38
@@ -XXX,XX +XXX,XX @@ static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
39
{
40
MachineState *ms = MACHINE(qdev_get_machine());
41
42
- /* Linux wants the number of processors from here.
43
+ /*
44
+ * Linux wants the number of processors from here.
45
* Might as well set the interrupt-controller bit too.
46
*/
47
return ((ms->smp.cpus - 1) << 24) | (1 << 23);
48
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
49
cpu->isar.id_mmfr1 = 0x40000000;
50
cpu->isar.id_mmfr2 = 0x01240000;
51
cpu->isar.id_mmfr3 = 0x02102211;
52
- /* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
53
+ /*
54
+ * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
55
* table 4-41 gives 0x02101110, which includes the arm div insns.
56
*/
57
cpu->isar.id_isar0 = 0x02101110;
26
--
58
--
27
2.20.1
59
2.20.1
28
60
29
61
diff view generated by jsdifflib
1
The ptimer API currently provides two methods for setting the period:
1
For a long time now the UI layer has guaranteed that the console
2
ptimer_set_period(), which takes a period in nanoseconds, and
2
surface is always 32 bits per pixel RGB. Remove the legacy dead
3
ptimer_set_freq(), which takes a frequency in Hz. Neither of these
3
code from the milkymist display device which was handling the
4
lines up nicely with the Clock API, because although both the Clock
4
possibility that the console surface was some other format.
5
and the ptimer track the frequency using a representation of whole
6
and fractional nanoseconds, conversion via either period-in-ns or
7
frequency-in-Hz will introduce a rounding error.
8
9
Add a new function ptimer_set_period_from_clock() which takes the
10
Clock object directly to avoid the rounding issues. This includes a
11
facility for the user to specify that there is a frequency divider
12
between the Clock proper and the timer, as some timer devices like
13
the CMSDK APB dualtimer need this.
14
15
To avoid having to drag in clock.h from ptimer.h we add the Clock
16
type to typedefs.h.
17
5
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215103215.4944-2-peter.maydell@linaro.org
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Message-id: 20210128114145.20536-2-peter.maydell@linaro.org
23
Message-id: 20210121190622.22000-2-peter.maydell@linaro.org
24
---
9
---
25
include/hw/ptimer.h | 22 ++++++++++++++++++++++
10
hw/arm/musicpal.c | 64 ++++++++++++++++++-----------------------------
26
include/qemu/typedefs.h | 1 +
11
1 file changed, 24 insertions(+), 40 deletions(-)
27
hw/core/ptimer.c | 34 ++++++++++++++++++++++++++++++++++
28
3 files changed, 57 insertions(+)
29
12
30
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
13
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
31
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
32
--- a/include/hw/ptimer.h
15
--- a/hw/arm/musicpal.c
33
+++ b/include/hw/ptimer.h
16
+++ b/hw/arm/musicpal.c
34
@@ -XXX,XX +XXX,XX @@ void ptimer_transaction_commit(ptimer_state *s);
17
@@ -XXX,XX +XXX,XX @@ static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
35
*/
36
void ptimer_set_period(ptimer_state *s, int64_t period);
37
38
+/**
39
+ * ptimer_set_period_from_clock - Set counter increment from a Clock
40
+ * @s: ptimer to configure
41
+ * @clk: pointer to Clock object to take period from
42
+ * @divisor: value to scale the clock frequency down by
43
+ *
44
+ * If the ptimer is being driven from a Clock, this is the preferred
45
+ * way to tell the ptimer about the period, because it avoids any
46
+ * possible rounding errors that might happen if the internal
47
+ * representation of the Clock period was converted to either a period
48
+ * in ns or a frequency in Hz.
49
+ *
50
+ * If the ptimer should run at the same frequency as the clock,
51
+ * pass 1 as the @divisor; if the ptimer should run at half the
52
+ * frequency, pass 2, and so on.
53
+ *
54
+ * This function will assert if it is called outside a
55
+ * ptimer_transaction_begin/commit block.
56
+ */
57
+void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clock,
58
+ unsigned int divisor);
59
+
60
/**
61
* ptimer_set_freq - Set counter frequency in Hz
62
* @s: ptimer to configure
63
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
64
index XXXXXXX..XXXXXXX 100644
65
--- a/include/qemu/typedefs.h
66
+++ b/include/qemu/typedefs.h
67
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDriverState BlockDriverState;
68
typedef struct BusClass BusClass;
69
typedef struct BusState BusState;
70
typedef struct Chardev Chardev;
71
+typedef struct Clock Clock;
72
typedef struct CompatProperty CompatProperty;
73
typedef struct CoMutex CoMutex;
74
typedef struct CPUAddressSpace CPUAddressSpace;
75
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/core/ptimer.c
78
+++ b/hw/core/ptimer.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "sysemu/qtest.h"
81
#include "block/aio.h"
82
#include "sysemu/cpus.h"
83
+#include "hw/clock.h"
84
85
#define DELTA_ADJUST 1
86
#define DELTA_NO_ADJUST -1
87
@@ -XXX,XX +XXX,XX @@ void ptimer_set_period(ptimer_state *s, int64_t period)
88
}
18
}
89
}
19
}
90
20
91
+/* Set counter increment interval from a Clock */
21
-#define SET_LCD_PIXEL(depth, type) \
92
+void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clk,
22
-static inline void glue(set_lcd_pixel, depth) \
93
+ unsigned int divisor)
23
- (musicpal_lcd_state *s, int x, int y, type col) \
24
-{ \
25
- int dx, dy; \
26
- DisplaySurface *surface = qemu_console_surface(s->con); \
27
- type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
28
-\
29
- for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
30
- for (dx = 0; dx < 3; dx++, pixel++) \
31
- *pixel = col; \
32
+static inline void set_lcd_pixel32(musicpal_lcd_state *s,
33
+ int x, int y, uint32_t col)
94
+{
34
+{
95
+ /*
35
+ int dx, dy;
96
+ * The raw clock period is a 64-bit value in units of 2^-32 ns;
36
+ DisplaySurface *surface = qemu_console_surface(s->con);
97
+ * put another way it's a 32.32 fixed-point ns value. Our internal
37
+ uint32_t *pixel =
98
+ * representation of the period is 64.32 fixed point ns, so
38
+ &((uint32_t *) surface_data(surface))[(y * 128 * 3 + x) * 3];
99
+ * the conversion is simple.
100
+ */
101
+ uint64_t raw_period = clock_get(clk);
102
+ uint64_t period_frac;
103
+
39
+
104
+ assert(s->in_transaction);
40
+ for (dy = 0; dy < 3; dy++, pixel += 127 * 3) {
105
+ s->delta = ptimer_get_count(s);
41
+ for (dx = 0; dx < 3; dx++, pixel++) {
106
+ s->period = extract64(raw_period, 32, 32);
42
+ *pixel = col;
107
+ period_frac = extract64(raw_period, 0, 32);
43
+ }
108
+ /*
109
+ * divisor specifies a possible frequency divisor between the
110
+ * clock and the timer, so it is a multiplier on the period.
111
+ * We do the multiply after splitting the raw period out into
112
+ * period and frac to avoid having to do a 32*64->96 multiply.
113
+ */
114
+ s->period *= divisor;
115
+ period_frac *= divisor;
116
+ s->period += extract64(period_frac, 32, 32);
117
+ s->period_frac = (uint32_t)period_frac;
118
+
119
+ if (s->enabled) {
120
+ s->need_reload = true;
121
+ }
44
+ }
122
+}
45
}
123
+
46
-SET_LCD_PIXEL(8, uint8_t)
124
/* Set counter frequency in Hz. */
47
-SET_LCD_PIXEL(16, uint16_t)
125
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
48
-SET_LCD_PIXEL(32, uint32_t)
49
50
static void lcd_refresh(void *opaque)
126
{
51
{
52
musicpal_lcd_state *s = opaque;
53
- DisplaySurface *surface = qemu_console_surface(s->con);
54
int x, y, col;
55
56
- switch (surface_bits_per_pixel(surface)) {
57
- case 0:
58
- return;
59
-#define LCD_REFRESH(depth, func) \
60
- case depth: \
61
- col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
62
- scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
63
- scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
64
- for (x = 0; x < 128; x++) { \
65
- for (y = 0; y < 64; y++) { \
66
- if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
67
- glue(set_lcd_pixel, depth)(s, x, y, col); \
68
- } else { \
69
- glue(set_lcd_pixel, depth)(s, x, y, 0); \
70
- } \
71
- } \
72
- } \
73
- break;
74
- LCD_REFRESH(8, rgb_to_pixel8)
75
- LCD_REFRESH(16, rgb_to_pixel16)
76
- LCD_REFRESH(32, (is_surface_bgr(surface) ?
77
- rgb_to_pixel32bgr : rgb_to_pixel32))
78
- default:
79
- hw_error("unsupported colour depth %i\n",
80
- surface_bits_per_pixel(surface));
81
+ col = rgb_to_pixel32(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff),
82
+ scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff),
83
+ scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff));
84
+ for (x = 0; x < 128; x++) {
85
+ for (y = 0; y < 64; y++) {
86
+ if (s->video_ram[x + (y / 8) * 128] & (1 << (y % 8))) {
87
+ set_lcd_pixel32(s, x, y, col);
88
+ } else {
89
+ set_lcd_pixel32(s, x, y, 0);
90
+ }
91
+ }
92
}
93
94
dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);
127
--
95
--
128
2.20.1
96
2.20.1
129
97
130
98
diff view generated by jsdifflib
1
From: Mihai Carabas <mihai.carabas@oracle.com>
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel RGB. Remove the legacy dead
3
code from the tc6393xb display device which was handling the
4
possibility that the console surface was some other format.
2
5
3
Add pvpanic PCI device support details in docs/specs/pvpanic.txt.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-3-peter.maydell@linaro.org
9
---
10
include/ui/console.h | 10 ----------
11
hw/display/tc6393xb.c | 33 +--------------------------------
12
2 files changed, 1 insertion(+), 42 deletions(-)
4
13
5
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
14
diff --git a/include/ui/console.h b/include/ui/console.h
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
docs/specs/pvpanic.txt | 13 ++++++++++++-
10
1 file changed, 12 insertions(+), 1 deletion(-)
11
12
diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/docs/specs/pvpanic.txt
16
--- a/include/ui/console.h
15
+++ b/docs/specs/pvpanic.txt
17
+++ b/include/ui/console.h
16
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ PixelFormat qemu_default_pixelformat(int bpp);
17
PVPANIC DEVICE
19
DisplaySurface *qemu_create_displaysurface(int width, int height);
18
==============
20
void qemu_free_displaysurface(DisplaySurface *surface);
19
21
20
-pvpanic device is a simulated ISA device, through which a guest panic
22
-static inline int is_surface_bgr(DisplaySurface *surface)
21
+pvpanic device is a simulated device, through which a guest panic
23
-{
22
event is sent to qemu, and a QMP event is generated. This allows
24
- if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
23
management apps (e.g. libvirt) to be notified and respond to the event.
25
- PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
24
26
- return 1;
25
@@ -XXX,XX +XXX,XX @@ The management app has the option of waiting for GUEST_PANICKED events,
27
- } else {
26
and/or polling for guest-panicked RunState, to learn when the pvpanic
28
- return 0;
27
device has fired a panic event.
29
- }
28
30
-}
29
+The pvpanic device can be implemented as an ISA device (using IOPORT) or as a
31
-
30
+PCI device.
32
static inline int is_buffer_shared(DisplaySurface *surface)
31
+
33
{
32
ISA Interface
34
return !(surface->flags & QEMU_ALLOCATED_FLAG);
33
-------------
35
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
34
36
index XXXXXXX..XXXXXXX 100644
35
@@ -XXX,XX +XXX,XX @@ bit 1: a guest panic has happened and will be handled by the guest;
37
--- a/hw/display/tc6393xb.c
36
the host should record it or report it, but should not affect
38
+++ b/hw/display/tc6393xb.c
37
the execution of the guest.
39
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
38
40
(uint32_t) addr, value & 0xff);
39
+PCI Interface
41
}
40
+-------------
42
41
+
43
-#define BITS 8
42
+The PCI interface is similar to the ISA interface except that it uses an MMIO
44
-#include "tc6393xb_template.h"
43
+address space provided by its BAR0, 1 byte long. Any machine with a PCI bus
45
-#define BITS 15
44
+can enable a pvpanic device by adding '-device pvpanic-pci' to the command
46
-#include "tc6393xb_template.h"
45
+line.
47
-#define BITS 16
46
+
48
-#include "tc6393xb_template.h"
47
ACPI Interface
49
-#define BITS 24
48
--------------
50
-#include "tc6393xb_template.h"
51
#define BITS 32
52
#include "tc6393xb_template.h"
53
54
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
55
{
56
- DisplaySurface *surface = qemu_console_surface(s->con);
57
-
58
- switch (surface_bits_per_pixel(surface)) {
59
- case 8:
60
- tc6393xb_draw_graphic8(s);
61
- break;
62
- case 15:
63
- tc6393xb_draw_graphic15(s);
64
- break;
65
- case 16:
66
- tc6393xb_draw_graphic16(s);
67
- break;
68
- case 24:
69
- tc6393xb_draw_graphic24(s);
70
- break;
71
- case 32:
72
- tc6393xb_draw_graphic32(s);
73
- break;
74
- default:
75
- printf("tc6393xb: unknown depth %d\n",
76
- surface_bits_per_pixel(surface));
77
- return;
78
- }
79
-
80
+ tc6393xb_draw_graphic32(s);
81
dpy_gfx_update_full(s->con);
82
}
49
83
50
--
84
--
51
2.20.1
85
2.20.1
52
86
53
87
diff view generated by jsdifflib
1
From: Joelle van Dyne <j@getutm.app>
1
Now the template header is included only for BITS==32, expand
2
out all the macros that depended on the BITS setting.
2
3
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Signed-off-by: Joelle van Dyne <j@getutm.app>
5
Message-id: 20210126012457.39046-9-j@getutm.app
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215103215.4944-4-peter.maydell@linaro.org
7
---
7
---
8
configure | 5 ++++-
8
hw/display/tc6393xb_template.h | 35 ++++------------------------------
9
1 file changed, 4 insertions(+), 1 deletion(-)
9
1 file changed, 4 insertions(+), 31 deletions(-)
10
10
11
diff --git a/configure b/configure
11
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
12
index XXXXXXX..XXXXXXX 100755
12
index XXXXXXX..XXXXXXX 100644
13
--- a/configure
13
--- a/hw/display/tc6393xb_template.h
14
+++ b/configure
14
+++ b/hw/display/tc6393xb_template.h
15
@@ -XXX,XX +XXX,XX @@ if test "$cross_compile" = "yes"; then
15
@@ -XXX,XX +XXX,XX @@
16
echo "system = 'darwin'" >> $cross
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
17
fi
17
*/
18
case "$ARCH" in
18
19
- i386|x86_64)
19
-#if BITS == 8
20
+ i386)
20
-# define SET_PIXEL(addr, color) (*(uint8_t *)addr = color)
21
echo "cpu_family = 'x86'" >> $cross
21
-#elif BITS == 15 || BITS == 16
22
;;
22
-# define SET_PIXEL(addr, color) (*(uint16_t *)addr = color)
23
+ x86_64)
23
-#elif BITS == 24
24
+ echo "cpu_family = 'x86_64'" >> $cross
24
-# define SET_PIXEL(addr, color) \
25
+ ;;
25
- do { \
26
ppc64le)
26
- addr[0] = color; \
27
echo "cpu_family = 'ppc64'" >> $cross
27
- addr[1] = (color) >> 8; \
28
;;
28
- addr[2] = (color) >> 16; \
29
- } while (0)
30
-#elif BITS == 32
31
-# define SET_PIXEL(addr, color) (*(uint32_t *)addr = color)
32
-#else
33
-# error unknown bit depth
34
-#endif
35
-
36
-
37
-static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
38
+static void tc6393xb_draw_graphic32(TC6393xbState *s)
39
{
40
DisplaySurface *surface = qemu_console_surface(s->con);
41
int i;
42
@@ -XXX,XX +XXX,XX @@ static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
43
data_buffer = s->vram_ptr;
44
data_display = surface_data(surface);
45
for(i = 0; i < s->scr_height; i++) {
46
-#if (BITS == 16)
47
- memcpy(data_display, data_buffer, s->scr_width * 2);
48
- data_buffer += s->scr_width;
49
- data_display += surface_stride(surface);
50
-#else
51
int j;
52
- for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) {
53
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
54
uint16_t color = *data_buffer;
55
- uint32_t dest_color = glue(rgb_to_pixel, BITS)(
56
+ uint32_t dest_color = rgb_to_pixel32(
57
((color & 0xf800) * 0x108) >> 11,
58
((color & 0x7e0) * 0x41) >> 9,
59
((color & 0x1f) * 0x21) >> 2
60
);
61
- SET_PIXEL(data_display, dest_color);
62
+ *(uint32_t *)data_display = dest_color;
63
}
64
-#endif
65
}
66
}
67
-
68
-#undef BITS
69
-#undef SET_PIXEL
29
--
70
--
30
2.20.1
71
2.20.1
31
72
32
73
diff view generated by jsdifflib
1
Switch the CMSDK APB watchdog device over to using its Clock input;
1
The function tc6393xb_draw_graphic32() is called in exactly one place,
2
the wdogclk_frq property is now ignored.
2
so just inline the function body at its callsite. This allows us to
3
drop the template header entirely.
4
5
The code move includes a single added space after 'for' to fix
6
the coding style.
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
11
Message-id: 20210215103215.4944-5-peter.maydell@linaro.org
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-21-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-21-peter.maydell@linaro.org
10
---
12
---
11
hw/watchdog/cmsdk-apb-watchdog.c | 18 ++++++++++++++----
13
hw/display/tc6393xb_template.h | 45 ----------------------------------
12
1 file changed, 14 insertions(+), 4 deletions(-)
14
hw/display/tc6393xb.c | 23 ++++++++++++++---
15
2 files changed, 19 insertions(+), 49 deletions(-)
16
delete mode 100644 hw/display/tc6393xb_template.h
13
17
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
18
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
19
deleted file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- a/hw/display/tc6393xb_template.h
22
+++ /dev/null
23
@@ -XXX,XX +XXX,XX @@
24
-/*
25
- * Toshiba TC6393XB I/O Controller.
26
- * Found in Sharp Zaurus SL-6000 (tosa) or some
27
- * Toshiba e-Series PDAs.
28
- *
29
- * FB support code. Based on G364 fb emulator
30
- *
31
- * Copyright (c) 2007 Hervé Poussineau
32
- *
33
- * This program is free software; you can redistribute it and/or
34
- * modify it under the terms of the GNU General Public License as
35
- * published by the Free Software Foundation; either version 2 of
36
- * the License, or (at your option) any later version.
37
- *
38
- * This program is distributed in the hope that it will be useful,
39
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
40
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41
- * GNU General Public License for more details.
42
- *
43
- * You should have received a copy of the GNU General Public License along
44
- * with this program; if not, see <http://www.gnu.org/licenses/>.
45
- */
46
-
47
-static void tc6393xb_draw_graphic32(TC6393xbState *s)
48
-{
49
- DisplaySurface *surface = qemu_console_surface(s->con);
50
- int i;
51
- uint16_t *data_buffer;
52
- uint8_t *data_display;
53
-
54
- data_buffer = s->vram_ptr;
55
- data_display = surface_data(surface);
56
- for(i = 0; i < s->scr_height; i++) {
57
- int j;
58
- for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
59
- uint16_t color = *data_buffer;
60
- uint32_t dest_color = rgb_to_pixel32(
61
- ((color & 0xf800) * 0x108) >> 11,
62
- ((color & 0x7e0) * 0x41) >> 9,
63
- ((color & 0x1f) * 0x21) >> 2
64
- );
65
- *(uint32_t *)data_display = dest_color;
66
- }
67
- }
68
-}
69
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
15
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
71
--- a/hw/display/tc6393xb.c
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
72
+++ b/hw/display/tc6393xb.c
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_reset(DeviceState *dev)
73
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
19
ptimer_transaction_commit(s->timer);
74
(uint32_t) addr, value & 0xff);
20
}
75
}
21
76
22
+static void cmsdk_apb_watchdog_clk_update(void *opaque)
77
-#define BITS 32
23
+{
78
-#include "tc6393xb_template.h"
24
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
79
-
80
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
81
{
82
- tc6393xb_draw_graphic32(s);
83
+ DisplaySurface *surface = qemu_console_surface(s->con);
84
+ int i;
85
+ uint16_t *data_buffer;
86
+ uint8_t *data_display;
25
+
87
+
26
+ ptimer_transaction_begin(s->timer);
88
+ data_buffer = s->vram_ptr;
27
+ ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
89
+ data_display = surface_data(surface);
28
+ ptimer_transaction_commit(s->timer);
90
+ for (i = 0; i < s->scr_height; i++) {
29
+}
91
+ int j;
30
+
92
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
31
static void cmsdk_apb_watchdog_init(Object *obj)
93
+ uint16_t color = *data_buffer;
32
{
94
+ uint32_t dest_color = rgb_to_pixel32(
33
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
95
+ ((color & 0xf800) * 0x108) >> 11,
34
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
96
+ ((color & 0x7e0) * 0x41) >> 9,
35
s, "cmsdk-apb-watchdog", 0x1000);
97
+ ((color & 0x1f) * 0x21) >> 2
36
sysbus_init_mmio(sbd, &s->iomem);
98
+ );
37
sysbus_init_irq(sbd, &s->wdogint);
99
+ *(uint32_t *)data_display = dest_color;
38
- s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK", NULL, NULL);
100
+ }
39
+ s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
101
+ }
40
+ cmsdk_apb_watchdog_clk_update, s);
102
dpy_gfx_update_full(s->con);
41
42
s->is_luminary = false;
43
s->id = cmsdk_apb_watchdog_id;
44
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
45
{
46
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
47
48
- if (s->wdogclk_frq == 0) {
49
+ if (!clock_has_source(s->wdogclk)) {
50
error_setg(errp,
51
- "CMSDK APB watchdog: wdogclk-frq property must be set");
52
+ "CMSDK APB watchdog: WDOGCLK clock must be connected");
53
return;
54
}
55
56
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
57
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
58
59
ptimer_transaction_begin(s->timer);
60
- ptimer_set_freq(s->timer, s->wdogclk_frq);
61
+ ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
62
ptimer_transaction_commit(s->timer);
63
}
103
}
64
104
65
--
105
--
66
2.20.1
106
2.20.1
67
107
68
108
diff view generated by jsdifflib
1
From: Mihai Carabas <mihai.carabas@oracle.com>
1
The omap_lcdc template header is already only included once, for
2
DEPTH==32, but it still has all the macro-driven parameterization
3
for other depths. Expand out all the macros in the header.
2
4
3
To ease the PCI device addition in next patches, split the code as follows:
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
- generic code (read/write/setup) is being kept in pvpanic.c
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
- ISA dependent code moved to pvpanic-isa.c
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215103215.4944-6-peter.maydell@linaro.org
9
---
10
hw/display/omap_lcd_template.h | 67 ++++++++++++++--------------------
11
1 file changed, 28 insertions(+), 39 deletions(-)
6
12
7
Also, rename:
13
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
8
- ISA_PVPANIC_DEVICE -> PVPANIC_ISA_DEVICE.
9
- TYPE_PVPANIC -> TYPE_PVPANIC_ISA.
10
- MemoryRegion io -> mr.
11
- pvpanic_ioport_* in pvpanic_*.
12
13
Update the build system with the new files and config structure.
14
15
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/misc/pvpanic.h | 23 +++++++++-
20
hw/misc/pvpanic-isa.c | 94 +++++++++++++++++++++++++++++++++++++++
21
hw/misc/pvpanic.c | 85 +++--------------------------------
22
hw/i386/Kconfig | 2 +-
23
hw/misc/Kconfig | 6 ++-
24
hw/misc/meson.build | 3 +-
25
tests/qtest/meson.build | 2 +-
26
7 files changed, 130 insertions(+), 85 deletions(-)
27
create mode 100644 hw/misc/pvpanic-isa.c
28
29
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
30
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/misc/pvpanic.h
15
--- a/hw/display/omap_lcd_template.h
32
+++ b/include/hw/misc/pvpanic.h
16
+++ b/hw/display/omap_lcd_template.h
33
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
34
18
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
#include "qom/object.h"
19
*/
36
20
37
-#define TYPE_PVPANIC "pvpanic"
21
-#if DEPTH == 32
38
+#define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
22
-# define BPP 4
39
23
-# define PIXEL_TYPE uint32_t
40
#define PVPANIC_IOPORT_PROP "ioport"
24
-#else
41
25
-# error unsupport depth
42
+/* The bit of supported pv event, TODO: include uapi header and remove this */
26
-#endif
43
+#define PVPANIC_F_PANICKED 0
27
-
44
+#define PVPANIC_F_CRASHLOADED 1
28
/*
45
+
29
* 2-bit colour
46
+/* The pv event value */
30
*/
47
+#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED)
31
-static void glue(draw_line2_, DEPTH)(void *opaque,
48
+#define PVPANIC_CRASHLOADED (1 << PVPANIC_F_CRASHLOADED)
32
- uint8_t *d, const uint8_t *s, int width, int deststep)
49
+
33
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
50
+/*
34
+ int width, int deststep)
51
+ * PVPanicState for any device type
52
+ */
53
+typedef struct PVPanicState PVPanicState;
54
+struct PVPanicState {
55
+ MemoryRegion mr;
56
+ uint8_t events;
57
+};
58
+
59
+void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size);
60
+
61
static inline uint16_t pvpanic_port(void)
62
{
35
{
63
- Object *o = object_resolve_path_type("", TYPE_PVPANIC, NULL);
36
uint16_t *pal = opaque;
64
+ Object *o = object_resolve_path_type("", TYPE_PVPANIC_ISA_DEVICE, NULL);
37
uint8_t v, r, g, b;
65
if (!o) {
38
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
66
return 0;
39
r = (pal[v & 3] >> 4) & 0xf0;
67
}
40
g = pal[v & 3] & 0xf0;
68
diff --git a/hw/misc/pvpanic-isa.c b/hw/misc/pvpanic-isa.c
41
b = (pal[v & 3] << 4) & 0xf0;
69
new file mode 100644
42
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
70
index XXXXXXX..XXXXXXX
43
- d += BPP;
71
--- /dev/null
44
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
72
+++ b/hw/misc/pvpanic-isa.c
45
+ d += 4;
73
@@ -XXX,XX +XXX,XX @@
46
v >>= 2;
74
+/*
47
r = (pal[v & 3] >> 4) & 0xf0;
75
+ * QEMU simulated pvpanic device.
48
g = pal[v & 3] & 0xf0;
76
+ *
49
b = (pal[v & 3] << 4) & 0xf0;
77
+ * Copyright Fujitsu, Corp. 2013
50
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
78
+ *
51
- d += BPP;
79
+ * Authors:
52
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
80
+ * Wen Congyang <wency@cn.fujitsu.com>
53
+ d += 4;
81
+ * Hu Tao <hutao@cn.fujitsu.com>
54
v >>= 2;
82
+ *
55
r = (pal[v & 3] >> 4) & 0xf0;
83
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
56
g = pal[v & 3] & 0xf0;
84
+ * See the COPYING file in the top-level directory.
57
b = (pal[v & 3] << 4) & 0xf0;
85
+ *
58
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
86
+ */
59
- d += BPP;
87
+
60
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
88
+#include "qemu/osdep.h"
61
+ d += 4;
89
+#include "qemu/log.h"
62
v >>= 2;
90
+#include "qemu/module.h"
63
r = (pal[v & 3] >> 4) & 0xf0;
91
+#include "sysemu/runstate.h"
64
g = pal[v & 3] & 0xf0;
92
+
65
b = (pal[v & 3] << 4) & 0xf0;
93
+#include "hw/nvram/fw_cfg.h"
66
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
94
+#include "hw/qdev-properties.h"
67
- d += BPP;
95
+#include "hw/misc/pvpanic.h"
68
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
96
+#include "qom/object.h"
69
+ d += 4;
97
+#include "hw/isa/isa.h"
70
s ++;
98
+
71
width -= 4;
99
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicISAState, PVPANIC_ISA_DEVICE)
72
} while (width > 0);
100
+
73
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
101
+/*
74
/*
102
+ * PVPanicISAState for ISA device and
75
* 4-bit colour
103
+ * use ioport.
76
*/
104
+ */
77
-static void glue(draw_line4_, DEPTH)(void *opaque,
105
+struct PVPanicISAState {
78
- uint8_t *d, const uint8_t *s, int width, int deststep)
106
+ ISADevice parent_obj;
79
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
107
+
80
+ int width, int deststep)
108
+ uint16_t ioport;
109
+ PVPanicState pvpanic;
110
+};
111
+
112
+static void pvpanic_isa_initfn(Object *obj)
113
+{
114
+ PVPanicISAState *s = PVPANIC_ISA_DEVICE(obj);
115
+
116
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), 1);
117
+}
118
+
119
+static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
120
+{
121
+ ISADevice *d = ISA_DEVICE(dev);
122
+ PVPanicISAState *s = PVPANIC_ISA_DEVICE(dev);
123
+ PVPanicState *ps = &s->pvpanic;
124
+ FWCfgState *fw_cfg = fw_cfg_find();
125
+ uint16_t *pvpanic_port;
126
+
127
+ if (!fw_cfg) {
128
+ return;
129
+ }
130
+
131
+ pvpanic_port = g_malloc(sizeof(*pvpanic_port));
132
+ *pvpanic_port = cpu_to_le16(s->ioport);
133
+ fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
134
+ sizeof(*pvpanic_port));
135
+
136
+ isa_register_ioport(d, &ps->mr, s->ioport);
137
+}
138
+
139
+static Property pvpanic_isa_properties[] = {
140
+ DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicISAState, ioport, 0x505),
141
+ DEFINE_PROP_UINT8("events", PVPanicISAState, pvpanic.events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
142
+ DEFINE_PROP_END_OF_LIST(),
143
+};
144
+
145
+static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
146
+{
147
+ DeviceClass *dc = DEVICE_CLASS(klass);
148
+
149
+ dc->realize = pvpanic_isa_realizefn;
150
+ device_class_set_props(dc, pvpanic_isa_properties);
151
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
152
+}
153
+
154
+static TypeInfo pvpanic_isa_info = {
155
+ .name = TYPE_PVPANIC_ISA_DEVICE,
156
+ .parent = TYPE_ISA_DEVICE,
157
+ .instance_size = sizeof(PVPanicISAState),
158
+ .instance_init = pvpanic_isa_initfn,
159
+ .class_init = pvpanic_isa_class_init,
160
+};
161
+
162
+static void pvpanic_register_types(void)
163
+{
164
+ type_register_static(&pvpanic_isa_info);
165
+}
166
+
167
+type_init(pvpanic_register_types)
168
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/hw/misc/pvpanic.c
171
+++ b/hw/misc/pvpanic.c
172
@@ -XXX,XX +XXX,XX @@
173
#include "hw/misc/pvpanic.h"
174
#include "qom/object.h"
175
176
-/* The bit of supported pv event, TODO: include uapi header and remove this */
177
-#define PVPANIC_F_PANICKED 0
178
-#define PVPANIC_F_CRASHLOADED 1
179
-
180
-/* The pv event value */
181
-#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED)
182
-#define PVPANIC_CRASHLOADED (1 << PVPANIC_F_CRASHLOADED)
183
-
184
-typedef struct PVPanicState PVPanicState;
185
-DECLARE_INSTANCE_CHECKER(PVPanicState, ISA_PVPANIC_DEVICE,
186
- TYPE_PVPANIC)
187
-
188
static void handle_event(int event)
189
{
81
{
190
static bool logged;
82
uint16_t *pal = opaque;
191
@@ -XXX,XX +XXX,XX @@ static void handle_event(int event)
83
uint8_t v, r, g, b;
192
}
84
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
85
r = (pal[v & 0xf] >> 4) & 0xf0;
86
g = pal[v & 0xf] & 0xf0;
87
b = (pal[v & 0xf] << 4) & 0xf0;
88
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
89
- d += BPP;
90
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
91
+ d += 4;
92
v >>= 4;
93
r = (pal[v & 0xf] >> 4) & 0xf0;
94
g = pal[v & 0xf] & 0xf0;
95
b = (pal[v & 0xf] << 4) & 0xf0;
96
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
97
- d += BPP;
98
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
99
+ d += 4;
100
s ++;
101
width -= 2;
102
} while (width > 0);
103
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
104
/*
105
* 8-bit colour
106
*/
107
-static void glue(draw_line8_, DEPTH)(void *opaque,
108
- uint8_t *d, const uint8_t *s, int width, int deststep)
109
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
110
+ int width, int deststep)
111
{
112
uint16_t *pal = opaque;
113
uint8_t v, r, g, b;
114
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line8_, DEPTH)(void *opaque,
115
r = (pal[v] >> 4) & 0xf0;
116
g = pal[v] & 0xf0;
117
b = (pal[v] << 4) & 0xf0;
118
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
119
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
120
s ++;
121
- d += BPP;
122
+ d += 4;
123
} while (-- width != 0);
193
}
124
}
194
125
195
-#include "hw/isa/isa.h"
126
/*
196
-
127
* 12-bit colour
197
-struct PVPanicState {
128
*/
198
- ISADevice parent_obj;
129
-static void glue(draw_line12_, DEPTH)(void *opaque,
199
-
130
- uint8_t *d, const uint8_t *s, int width, int deststep)
200
- MemoryRegion io;
131
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
201
- uint16_t ioport;
132
+ int width, int deststep)
202
- uint8_t events;
203
-};
204
-
205
/* return supported events on read */
206
-static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
207
+static uint64_t pvpanic_read(void *opaque, hwaddr addr, unsigned size)
208
{
133
{
209
PVPanicState *pvp = opaque;
134
uint16_t v;
210
return pvp->events;
135
uint8_t r, g, b;
136
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line12_, DEPTH)(void *opaque,
137
r = (v >> 4) & 0xf0;
138
g = v & 0xf0;
139
b = (v << 4) & 0xf0;
140
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
141
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
142
s += 2;
143
- d += BPP;
144
+ d += 4;
145
} while (-- width != 0);
211
}
146
}
212
147
213
-static void pvpanic_ioport_write(void *opaque, hwaddr addr, uint64_t val,
148
/*
214
+static void pvpanic_write(void *opaque, hwaddr addr, uint64_t val,
149
* 16-bit colour
215
unsigned size)
150
*/
151
-static void glue(draw_line16_, DEPTH)(void *opaque,
152
- uint8_t *d, const uint8_t *s, int width, int deststep)
153
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
154
+ int width, int deststep)
216
{
155
{
217
handle_event(val);
156
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
218
}
157
memcpy(d, s, width * 2);
219
158
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line16_, DEPTH)(void *opaque,
220
static const MemoryRegionOps pvpanic_ops = {
159
r = (v >> 8) & 0xf8;
221
- .read = pvpanic_ioport_read,
160
g = (v >> 3) & 0xfc;
222
- .write = pvpanic_ioport_write,
161
b = (v << 3) & 0xf8;
223
+ .read = pvpanic_read,
162
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
224
+ .write = pvpanic_write,
163
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
225
.impl = {
164
s += 2;
226
.min_access_size = 1,
165
- d += BPP;
227
.max_access_size = 1,
166
+ d += 4;
228
},
167
} while (-- width != 0);
229
};
168
#endif
230
231
-static void pvpanic_isa_initfn(Object *obj)
232
+void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size)
233
{
234
- PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
235
-
236
- memory_region_init_io(&s->io, OBJECT(s), &pvpanic_ops, s, "pvpanic", 1);
237
+ memory_region_init_io(&s->mr, OBJECT(dev), &pvpanic_ops, s, "pvpanic", size);
238
}
169
}
239
-
170
-
240
-static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
171
-#undef DEPTH
241
-{
172
-#undef BPP
242
- ISADevice *d = ISA_DEVICE(dev);
173
-#undef PIXEL_TYPE
243
- PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
244
- FWCfgState *fw_cfg = fw_cfg_find();
245
- uint16_t *pvpanic_port;
246
-
247
- if (!fw_cfg) {
248
- return;
249
- }
250
-
251
- pvpanic_port = g_malloc(sizeof(*pvpanic_port));
252
- *pvpanic_port = cpu_to_le16(s->ioport);
253
- fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
254
- sizeof(*pvpanic_port));
255
-
256
- isa_register_ioport(d, &s->io, s->ioport);
257
-}
258
-
259
-static Property pvpanic_isa_properties[] = {
260
- DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505),
261
- DEFINE_PROP_UINT8("events", PVPanicState, events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
262
- DEFINE_PROP_END_OF_LIST(),
263
-};
264
-
265
-static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
266
-{
267
- DeviceClass *dc = DEVICE_CLASS(klass);
268
-
269
- dc->realize = pvpanic_isa_realizefn;
270
- device_class_set_props(dc, pvpanic_isa_properties);
271
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
272
-}
273
-
274
-static TypeInfo pvpanic_isa_info = {
275
- .name = TYPE_PVPANIC,
276
- .parent = TYPE_ISA_DEVICE,
277
- .instance_size = sizeof(PVPanicState),
278
- .instance_init = pvpanic_isa_initfn,
279
- .class_init = pvpanic_isa_class_init,
280
-};
281
-
282
-static void pvpanic_register_types(void)
283
-{
284
- type_register_static(&pvpanic_isa_info);
285
-}
286
-
287
-type_init(pvpanic_register_types)
288
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
289
index XXXXXXX..XXXXXXX 100644
290
--- a/hw/i386/Kconfig
291
+++ b/hw/i386/Kconfig
292
@@ -XXX,XX +XXX,XX @@ config PC
293
imply ISA_DEBUG
294
imply PARALLEL
295
imply PCI_DEVICES
296
- imply PVPANIC
297
+ imply PVPANIC_ISA
298
imply QXL
299
imply SEV
300
imply SGA
301
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
302
index XXXXXXX..XXXXXXX 100644
303
--- a/hw/misc/Kconfig
304
+++ b/hw/misc/Kconfig
305
@@ -XXX,XX +XXX,XX @@ config IOTKIT_SYSCTL
306
config IOTKIT_SYSINFO
307
bool
308
309
-config PVPANIC
310
+config PVPANIC_COMMON
311
+ bool
312
+
313
+config PVPANIC_ISA
314
bool
315
depends on ISA_BUS
316
+ select PVPANIC_COMMON
317
318
config AUX
319
bool
320
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
321
index XXXXXXX..XXXXXXX 100644
322
--- a/hw/misc/meson.build
323
+++ b/hw/misc/meson.build
324
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
325
softmmu_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c'))
326
softmmu_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c'))
327
softmmu_ss.add(when: 'CONFIG_LED', if_true: files('led.c'))
328
+softmmu_ss.add(when: 'CONFIG_PVPANIC_COMMON', if_true: files('pvpanic.c'))
329
330
# ARM devices
331
softmmu_ss.add(when: 'CONFIG_PL310', if_true: files('arm_l2x0.c'))
332
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_IOTKIT_SYSINFO', if_true: files('iotkit-sysinfo.c')
333
softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
334
softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
335
336
-softmmu_ss.add(when: 'CONFIG_PVPANIC', if_true: files('pvpanic.c'))
337
+softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
338
softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
339
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_scu.c', 'aspeed_sdmc.c', 'aspeed_xdma.c'))
340
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
341
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
342
index XXXXXXX..XXXXXXX 100644
343
--- a/tests/qtest/meson.build
344
+++ b/tests/qtest/meson.build
345
@@ -XXX,XX +XXX,XX @@ qtests_i386 = \
346
(config_host.has_key('CONFIG_LINUX') and \
347
config_all_devices.has_key('CONFIG_ISA_IPMI_BT') ? ['ipmi-bt-test'] : []) + \
348
(config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \
349
- (config_all_devices.has_key('CONFIG_PVPANIC') ? ['pvpanic-test'] : []) + \
350
+ (config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \
351
(config_all_devices.has_key('CONFIG_HDA') ? ['intel-hda-test'] : []) + \
352
(config_all_devices.has_key('CONFIG_I82801B11') ? ['i82801b11-test'] : []) + \
353
(config_all_devices.has_key('CONFIG_IOH3420') ? ['ioh3420-test'] : []) + \
354
--
174
--
355
2.20.1
175
2.20.1
356
176
357
177
diff view generated by jsdifflib
New patch
1
The draw_line16_32() function in the omap_lcdc template header
2
includes an ifdef for the case where HOST_WORDS_BIGENDIAN matches
3
TARGET_WORDS_BIGENDIAN. This is trying to optimise for "source
4
bitmap and destination bitmap format match", but it is broken,
5
because in this function the formats don't match: the source is
6
16-bit colour and the destination is 32-bit colour, so a memcpy()
7
will produce corrupted graphics output. Drop the bogus ifdef.
1
8
9
This bug was introduced in commit ea644cf343129, when we dropped
10
support for DEPTH values other than 32 from the template header.
11
The old #if line was
12
#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
13
and this was mistakenly changed to
14
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
15
rather than deleting the #if as now having an always-false condition.
16
17
Fixes: ea644cf343129
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210215103215.4944-7-peter.maydell@linaro.org
22
---
23
hw/display/omap_lcd_template.h | 4 ----
24
1 file changed, 4 deletions(-)
25
26
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/display/omap_lcd_template.h
29
+++ b/hw/display/omap_lcd_template.h
30
@@ -XXX,XX +XXX,XX @@ static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
31
static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
32
int width, int deststep)
33
{
34
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
35
- memcpy(d, s, width * 2);
36
-#else
37
uint16_t v;
38
uint8_t r, g, b;
39
40
@@ -XXX,XX +XXX,XX @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
41
s += 2;
42
d += 4;
43
} while (-- width != 0);
44
-#endif
45
}
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
New patch
1
Fix some minor coding style issues in the template header,
2
so checkpatch doesn't complain when we move the code.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-8-peter.maydell@linaro.org
8
---
9
hw/display/omap_lcd_template.h | 6 +++---
10
1 file changed, 3 insertions(+), 3 deletions(-)
11
12
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/display/omap_lcd_template.h
15
+++ b/hw/display/omap_lcd_template.h
16
@@ -XXX,XX +XXX,XX @@ static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
17
b = (pal[v & 3] << 4) & 0xf0;
18
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
19
d += 4;
20
- s ++;
21
+ s++;
22
width -= 4;
23
} while (width > 0);
24
}
25
@@ -XXX,XX +XXX,XX @@ static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
26
b = (pal[v & 0xf] << 4) & 0xf0;
27
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
28
d += 4;
29
- s ++;
30
+ s++;
31
width -= 2;
32
} while (width > 0);
33
}
34
@@ -XXX,XX +XXX,XX @@ static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
35
g = pal[v] & 0xf0;
36
b = (pal[v] << 4) & 0xf0;
37
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
38
- s ++;
39
+ s++;
40
d += 4;
41
} while (-- width != 0);
42
}
43
--
44
2.20.1
45
46
diff view generated by jsdifflib
New patch
1
We only include the template header once, so just inline it into the
2
source file for the device.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-9-peter.maydell@linaro.org
8
---
9
hw/display/omap_lcd_template.h | 154 ---------------------------------
10
hw/display/omap_lcdc.c | 127 ++++++++++++++++++++++++++-
11
2 files changed, 125 insertions(+), 156 deletions(-)
12
delete mode 100644 hw/display/omap_lcd_template.h
13
14
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
15
deleted file mode 100644
16
index XXXXXXX..XXXXXXX
17
--- a/hw/display/omap_lcd_template.h
18
+++ /dev/null
19
@@ -XXX,XX +XXX,XX @@
20
-/*
21
- * QEMU OMAP LCD Emulator templates
22
- *
23
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
24
- *
25
- * Redistribution and use in source and binary forms, with or without
26
- * modification, are permitted provided that the following conditions
27
- * are met:
28
- *
29
- * 1. Redistributions of source code must retain the above copyright
30
- * notice, this list of conditions and the following disclaimer.
31
- * 2. Redistributions in binary form must reproduce the above copyright
32
- * notice, this list of conditions and the following disclaimer in
33
- * the documentation and/or other materials provided with the
34
- * distribution.
35
- *
36
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
37
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
38
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
40
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
42
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
43
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
- */
48
-
49
-/*
50
- * 2-bit colour
51
- */
52
-static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
53
- int width, int deststep)
54
-{
55
- uint16_t *pal = opaque;
56
- uint8_t v, r, g, b;
57
-
58
- do {
59
- v = ldub_p((void *) s);
60
- r = (pal[v & 3] >> 4) & 0xf0;
61
- g = pal[v & 3] & 0xf0;
62
- b = (pal[v & 3] << 4) & 0xf0;
63
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
64
- d += 4;
65
- v >>= 2;
66
- r = (pal[v & 3] >> 4) & 0xf0;
67
- g = pal[v & 3] & 0xf0;
68
- b = (pal[v & 3] << 4) & 0xf0;
69
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
70
- d += 4;
71
- v >>= 2;
72
- r = (pal[v & 3] >> 4) & 0xf0;
73
- g = pal[v & 3] & 0xf0;
74
- b = (pal[v & 3] << 4) & 0xf0;
75
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
76
- d += 4;
77
- v >>= 2;
78
- r = (pal[v & 3] >> 4) & 0xf0;
79
- g = pal[v & 3] & 0xf0;
80
- b = (pal[v & 3] << 4) & 0xf0;
81
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
82
- d += 4;
83
- s++;
84
- width -= 4;
85
- } while (width > 0);
86
-}
87
-
88
-/*
89
- * 4-bit colour
90
- */
91
-static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
92
- int width, int deststep)
93
-{
94
- uint16_t *pal = opaque;
95
- uint8_t v, r, g, b;
96
-
97
- do {
98
- v = ldub_p((void *) s);
99
- r = (pal[v & 0xf] >> 4) & 0xf0;
100
- g = pal[v & 0xf] & 0xf0;
101
- b = (pal[v & 0xf] << 4) & 0xf0;
102
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
103
- d += 4;
104
- v >>= 4;
105
- r = (pal[v & 0xf] >> 4) & 0xf0;
106
- g = pal[v & 0xf] & 0xf0;
107
- b = (pal[v & 0xf] << 4) & 0xf0;
108
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
109
- d += 4;
110
- s++;
111
- width -= 2;
112
- } while (width > 0);
113
-}
114
-
115
-/*
116
- * 8-bit colour
117
- */
118
-static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
119
- int width, int deststep)
120
-{
121
- uint16_t *pal = opaque;
122
- uint8_t v, r, g, b;
123
-
124
- do {
125
- v = ldub_p((void *) s);
126
- r = (pal[v] >> 4) & 0xf0;
127
- g = pal[v] & 0xf0;
128
- b = (pal[v] << 4) & 0xf0;
129
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
130
- s++;
131
- d += 4;
132
- } while (-- width != 0);
133
-}
134
-
135
-/*
136
- * 12-bit colour
137
- */
138
-static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
139
- int width, int deststep)
140
-{
141
- uint16_t v;
142
- uint8_t r, g, b;
143
-
144
- do {
145
- v = lduw_le_p((void *) s);
146
- r = (v >> 4) & 0xf0;
147
- g = v & 0xf0;
148
- b = (v << 4) & 0xf0;
149
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
150
- s += 2;
151
- d += 4;
152
- } while (-- width != 0);
153
-}
154
-
155
-/*
156
- * 16-bit colour
157
- */
158
-static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
159
- int width, int deststep)
160
-{
161
- uint16_t v;
162
- uint8_t r, g, b;
163
-
164
- do {
165
- v = lduw_le_p((void *) s);
166
- r = (v >> 8) & 0xf8;
167
- g = (v >> 3) & 0xfc;
168
- b = (v << 3) & 0xf8;
169
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
170
- s += 2;
171
- d += 4;
172
- } while (-- width != 0);
173
-}
174
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
175
index XXXXXXX..XXXXXXX 100644
176
--- a/hw/display/omap_lcdc.c
177
+++ b/hw/display/omap_lcdc.c
178
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
179
180
#define draw_line_func drawfn
181
182
-#define DEPTH 32
183
-#include "omap_lcd_template.h"
184
+/*
185
+ * 2-bit colour
186
+ */
187
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
188
+ int width, int deststep)
189
+{
190
+ uint16_t *pal = opaque;
191
+ uint8_t v, r, g, b;
192
+
193
+ do {
194
+ v = ldub_p((void *) s);
195
+ r = (pal[v & 3] >> 4) & 0xf0;
196
+ g = pal[v & 3] & 0xf0;
197
+ b = (pal[v & 3] << 4) & 0xf0;
198
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
199
+ d += 4;
200
+ v >>= 2;
201
+ r = (pal[v & 3] >> 4) & 0xf0;
202
+ g = pal[v & 3] & 0xf0;
203
+ b = (pal[v & 3] << 4) & 0xf0;
204
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
205
+ d += 4;
206
+ v >>= 2;
207
+ r = (pal[v & 3] >> 4) & 0xf0;
208
+ g = pal[v & 3] & 0xf0;
209
+ b = (pal[v & 3] << 4) & 0xf0;
210
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
211
+ d += 4;
212
+ v >>= 2;
213
+ r = (pal[v & 3] >> 4) & 0xf0;
214
+ g = pal[v & 3] & 0xf0;
215
+ b = (pal[v & 3] << 4) & 0xf0;
216
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
217
+ d += 4;
218
+ s++;
219
+ width -= 4;
220
+ } while (width > 0);
221
+}
222
+
223
+/*
224
+ * 4-bit colour
225
+ */
226
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
227
+ int width, int deststep)
228
+{
229
+ uint16_t *pal = opaque;
230
+ uint8_t v, r, g, b;
231
+
232
+ do {
233
+ v = ldub_p((void *) s);
234
+ r = (pal[v & 0xf] >> 4) & 0xf0;
235
+ g = pal[v & 0xf] & 0xf0;
236
+ b = (pal[v & 0xf] << 4) & 0xf0;
237
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
238
+ d += 4;
239
+ v >>= 4;
240
+ r = (pal[v & 0xf] >> 4) & 0xf0;
241
+ g = pal[v & 0xf] & 0xf0;
242
+ b = (pal[v & 0xf] << 4) & 0xf0;
243
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
244
+ d += 4;
245
+ s++;
246
+ width -= 2;
247
+ } while (width > 0);
248
+}
249
+
250
+/*
251
+ * 8-bit colour
252
+ */
253
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
254
+ int width, int deststep)
255
+{
256
+ uint16_t *pal = opaque;
257
+ uint8_t v, r, g, b;
258
+
259
+ do {
260
+ v = ldub_p((void *) s);
261
+ r = (pal[v] >> 4) & 0xf0;
262
+ g = pal[v] & 0xf0;
263
+ b = (pal[v] << 4) & 0xf0;
264
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
265
+ s++;
266
+ d += 4;
267
+ } while (-- width != 0);
268
+}
269
+
270
+/*
271
+ * 12-bit colour
272
+ */
273
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
274
+ int width, int deststep)
275
+{
276
+ uint16_t v;
277
+ uint8_t r, g, b;
278
+
279
+ do {
280
+ v = lduw_le_p((void *) s);
281
+ r = (v >> 4) & 0xf0;
282
+ g = v & 0xf0;
283
+ b = (v << 4) & 0xf0;
284
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
285
+ s += 2;
286
+ d += 4;
287
+ } while (-- width != 0);
288
+}
289
+
290
+/*
291
+ * 16-bit colour
292
+ */
293
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
294
+ int width, int deststep)
295
+{
296
+ uint16_t v;
297
+ uint8_t r, g, b;
298
+
299
+ do {
300
+ v = lduw_le_p((void *) s);
301
+ r = (v >> 8) & 0xf8;
302
+ g = (v >> 3) & 0xfc;
303
+ b = (v << 3) & 0xf8;
304
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
305
+ s += 2;
306
+ d += 4;
307
+ } while (-- width != 0);
308
+}
309
310
static void omap_update_display(void *opaque)
311
{
312
--
313
2.20.1
314
315
diff view generated by jsdifflib
1
As the first step in converting the CMSDK_APB_DUALTIMER device to the
1
The macro draw_line_func is used only once; just expand it.
2
Clock framework, add a Clock input. For the moment we do nothing
3
with this clock; we will change the behaviour from using the pclk-frq
4
property to using the Clock once all the users of this device have
5
been converted to wire up the Clock.
6
7
We take the opportunity to correct the name of the clock input to
8
match the hardware -- the dual timer names the clock which drives the
9
timers TIMCLK. (It does also have a 'pclk' input, which is used only
10
for the register and APB bus logic; on the SSE-200 these clocks are
11
both connected together.)
12
13
This is a migration compatibility break for machines mps2-an385,
14
mps2-an386, mps2-an500, mps2-an511, mps2-an505, mps2-an521, musca-a,
15
musca-b1.
16
2
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Message-id: 20210215103215.4944-10-peter.maydell@linaro.org
20
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210128114145.20536-9-peter.maydell@linaro.org
22
Message-id: 20210121190622.22000-9-peter.maydell@linaro.org
23
---
7
---
24
include/hw/timer/cmsdk-apb-dualtimer.h | 3 +++
8
hw/display/omap_lcdc.c | 4 +---
25
hw/timer/cmsdk-apb-dualtimer.c | 7 +++++--
9
1 file changed, 1 insertion(+), 3 deletions(-)
26
2 files changed, 8 insertions(+), 2 deletions(-)
27
10
28
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
11
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
29
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/timer/cmsdk-apb-dualtimer.h
13
--- a/hw/display/omap_lcdc.c
31
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
14
+++ b/hw/display/omap_lcdc.c
32
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
33
*
16
qemu_irq_lower(s->irq);
34
* QEMU interface:
35
* + QOM property "pclk-frq": frequency at which the timer is clocked
36
+ * + Clock input "TIMCLK": clock (for both timers)
37
* + sysbus MMIO region 0: the register bank
38
* + sysbus IRQ 0: combined timer interrupt TIMINTC
39
* + sysbus IRO 1: timer block 1 interrupt TIMINT1
40
@@ -XXX,XX +XXX,XX @@
41
42
#include "hw/sysbus.h"
43
#include "hw/ptimer.h"
44
+#include "hw/clock.h"
45
#include "qom/object.h"
46
47
#define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer"
48
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBDualTimer {
49
MemoryRegion iomem;
50
qemu_irq timerintc;
51
uint32_t pclk_frq;
52
+ Clock *timclk;
53
54
CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES];
55
uint32_t timeritcr;
56
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-dualtimer.c
59
+++ b/hw/timer/cmsdk-apb-dualtimer.c
60
@@ -XXX,XX +XXX,XX @@
61
#include "hw/irq.h"
62
#include "hw/qdev-properties.h"
63
#include "hw/registerfields.h"
64
+#include "hw/qdev-clock.h"
65
#include "hw/timer/cmsdk-apb-dualtimer.h"
66
#include "migration/vmstate.h"
67
68
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_init(Object *obj)
69
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
70
sysbus_init_irq(sbd, &s->timermod[i].timerint);
71
}
72
+ s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK", NULL, NULL);
73
}
17
}
74
18
75
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
19
-#define draw_line_func drawfn
76
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_dualtimermod_vmstate = {
20
-
77
21
/*
78
static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
22
* 2-bit colour
79
.name = "cmsdk-apb-dualtimer",
23
*/
80
- .version_id = 1,
24
@@ -XXX,XX +XXX,XX @@ static void omap_update_display(void *opaque)
81
- .minimum_version_id = 1,
25
{
82
+ .version_id = 2,
26
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
83
+ .minimum_version_id = 2,
27
DisplaySurface *surface;
84
.fields = (VMStateField[]) {
28
- draw_line_func draw_line;
85
+ VMSTATE_CLOCK(timclk, CMSDKAPBDualTimer),
29
+ drawfn draw_line;
86
VMSTATE_STRUCT_ARRAY(timermod, CMSDKAPBDualTimer,
30
int size, height, first, last;
87
CMSDK_APB_DUALTIMER_NUM_MODULES,
31
int width, linesize, step, bpp, frame_offset;
88
1, cmsdk_dualtimermod_vmstate,
32
hwaddr frame_base;
89
--
33
--
90
2.20.1
34
2.20.1
91
35
92
36
diff view generated by jsdifflib
1
From: Joelle van Dyne <j@getutm.app>
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel, RGB. The TCX code already
3
assumes 32bpp, but it still has some checks of is_surface_bgr()
4
in an attempt to support 32bpp BGR. is_surface_bgr() will always
5
return false for the qemu_console_surface(), unless the display
6
device itself has deliberately created an alternate-format
7
surface via a function like qemu_create_displaysurface_from().
2
8
3
The iOS toolchain does not use the host prefix naming convention. So we
9
Drop the never-used BGR-handling code, and assert that we have
4
need to enable cross-compile options while allowing the PREFIX to be
10
a 32-bit surface rather than just doing nothing if it isn't.
5
blank.
6
11
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Joelle van Dyne <j@getutm.app>
9
Message-id: 20210126012457.39046-3-j@getutm.app
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210215102149.20513-1-peter.maydell@linaro.org
11
---
16
---
12
configure | 6 ++++--
17
hw/display/tcx.c | 31 ++++++++-----------------------
13
1 file changed, 4 insertions(+), 2 deletions(-)
18
1 file changed, 8 insertions(+), 23 deletions(-)
14
19
15
diff --git a/configure b/configure
20
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
16
index XXXXXXX..XXXXXXX 100755
21
index XXXXXXX..XXXXXXX 100644
17
--- a/configure
22
--- a/hw/display/tcx.c
18
+++ b/configure
23
+++ b/hw/display/tcx.c
19
@@ -XXX,XX +XXX,XX @@ cpu=""
24
@@ -XXX,XX +XXX,XX @@ static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
20
iasl="iasl"
25
21
interp_prefix="/usr/gnemul/qemu-%M"
26
static void update_palette_entries(TCXState *s, int start, int end)
22
static="no"
27
{
23
+cross_compile="no"
28
- DisplaySurface *surface = qemu_console_surface(s->con);
24
cross_prefix=""
29
int i;
25
audio_drv_list=""
30
26
block_drv_rw_whitelist=""
31
for (i = start; i < end; i++) {
27
@@ -XXX,XX +XXX,XX @@ for opt do
32
- if (is_surface_bgr(surface)) {
28
optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
33
- s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
29
case "$opt" in
34
- } else {
30
--cross-prefix=*) cross_prefix="$optarg"
35
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
31
+ cross_compile="yes"
36
- }
32
;;
37
+ s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
33
--cc=*) CC="$optarg"
38
}
34
;;
39
tcx_set_dirty(s, 0, memory_region_size(&s->vram_mem));
35
@@ -XXX,XX +XXX,XX @@ $(echo Deprecated targets: $deprecated_targets_list | \
40
}
36
--target-list-exclude=LIST exclude a set of targets from the default target-list
41
@@ -XXX,XX +XXX,XX @@ static void tcx_draw_cursor32(TCXState *s1, uint8_t *d,
37
42
}
38
Advanced options (experts only):
43
39
- --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
44
/*
40
+ --cross-prefix=PREFIX use PREFIX for compile tools, PREFIX can be blank [$cross_prefix]
45
- XXX Could be much more optimal:
41
--cc=CC use C compiler CC [$cc]
46
- * detect if line/page/whole screen is in 24 bit mode
42
--iasl=IASL use ACPI compiler IASL [$iasl]
47
- * if destination is also BGR, use memcpy
43
--host-cc=CC use C compiler CC [$host_cc] for code run at
48
- */
44
@@ -XXX,XX +XXX,XX @@ if has $sdl2_config; then
49
+ * XXX Could be much more optimal:
45
fi
50
+ * detect if line/page/whole screen is in 24 bit mode
46
echo "strip = [$(meson_quote $strip)]" >> $cross
51
+ */
47
echo "windres = [$(meson_quote $windres)]" >> $cross
52
static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
48
-if test -n "$cross_prefix"; then
53
const uint8_t *s, int width,
49
+if test "$cross_compile" = "yes"; then
54
const uint32_t *cplane,
50
cross_arg="--cross-file config-meson.cross"
55
const uint32_t *s24)
51
echo "[host_machine]" >> $cross
56
{
52
if test "$mingw32" = "yes" ; then
57
- DisplaySurface *surface = qemu_console_surface(s1->con);
58
- int x, bgr, r, g, b;
59
+ int x, r, g, b;
60
uint8_t val, *p8;
61
uint32_t *p = (uint32_t *)d;
62
uint32_t dval;
63
- bgr = is_surface_bgr(surface);
64
for(x = 0; x < width; x++, s++, s24++) {
65
if (be32_to_cpu(*cplane) & 0x03000000) {
66
/* 24-bit direct, BGR order */
67
@@ -XXX,XX +XXX,XX @@ static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
68
b = *p8++;
69
g = *p8++;
70
r = *p8;
71
- if (bgr)
72
- dval = rgb_to_pixel32bgr(r, g, b);
73
- else
74
- dval = rgb_to_pixel32(r, g, b);
75
+ dval = rgb_to_pixel32(r, g, b);
76
} else {
77
/* 8-bit pseudocolor */
78
val = *s;
79
@@ -XXX,XX +XXX,XX @@ static void tcx_update_display(void *opaque)
80
int y, y_start, dd, ds;
81
uint8_t *d, *s;
82
83
- if (surface_bits_per_pixel(surface) != 32) {
84
- return;
85
- }
86
+ assert(surface_bits_per_pixel(surface) == 32);
87
88
page = 0;
89
y_start = -1;
90
@@ -XXX,XX +XXX,XX @@ static void tcx24_update_display(void *opaque)
91
uint8_t *d, *s;
92
uint32_t *cptr, *s24;
93
94
- if (surface_bits_per_pixel(surface) != 32) {
95
- return;
96
- }
97
+ assert(surface_bits_per_pixel(surface) == 32);
98
99
page = 0;
100
y_start = -1;
53
--
101
--
54
2.20.1
102
2.20.1
55
103
56
104
diff view generated by jsdifflib
1
Now no users are setting the frq properties on the CMSDK timer,
1
The AN524 has a different SYSCLK frequency from the AN505 and AN521;
2
dualtimer, watchdog or ARMSSE SoC devices, we can remove the
2
make the SYSCLK frequency a field in the MPS2TZMachineClass rather
3
properties and the struct fields that back them.
3
than a compile-time constant so we can support the AN524.
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215115138.20465-2-peter.maydell@linaro.org
9
Message-id: 20210128114145.20536-25-peter.maydell@linaro.org
10
Message-id: 20210121190622.22000-25-peter.maydell@linaro.org
11
---
9
---
12
include/hw/arm/armsse.h | 2 --
10
hw/arm/mps2-tz.c | 10 ++++++----
13
include/hw/timer/cmsdk-apb-dualtimer.h | 2 --
11
1 file changed, 6 insertions(+), 4 deletions(-)
14
include/hw/timer/cmsdk-apb-timer.h | 2 --
15
include/hw/watchdog/cmsdk-apb-watchdog.h | 2 --
16
hw/arm/armsse.c | 2 --
17
hw/timer/cmsdk-apb-dualtimer.c | 6 ------
18
hw/timer/cmsdk-apb-timer.c | 6 ------
19
hw/watchdog/cmsdk-apb-watchdog.c | 6 ------
20
8 files changed, 28 deletions(-)
21
12
22
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
23
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/armsse.h
15
--- a/hw/arm/mps2-tz.c
25
+++ b/include/hw/arm/armsse.h
16
+++ b/hw/arm/mps2-tz.c
26
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
27
* + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
18
MachineClass parent;
28
* + QOM property "memory" is a MemoryRegion containing the devices provided
19
MPS2TZFPGAType fpga_type;
29
* by the board model.
20
uint32_t scc_id;
30
- * + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
21
+ uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
31
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
22
const char *armsse_type;
32
* (In hardware, the SSE-200 permits the number of expansion interrupts
33
* for the two CPUs to be configured separately, but we restrict it to
34
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
35
/* Properties */
36
MemoryRegion *board_memory;
37
uint32_t exp_numirq;
38
- uint32_t mainclk_frq;
39
uint32_t sram_addr_width;
40
uint32_t init_svtor;
41
bool cpu_fpu[SSE_MAX_CPUS];
42
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/include/hw/timer/cmsdk-apb-dualtimer.h
45
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
46
@@ -XXX,XX +XXX,XX @@
47
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
48
*
49
* QEMU interface:
50
- * + QOM property "pclk-frq": frequency at which the timer is clocked
51
* + Clock input "TIMCLK": clock (for both timers)
52
* + sysbus MMIO region 0: the register bank
53
* + sysbus IRQ 0: combined timer interrupt TIMINTC
54
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBDualTimer {
55
/*< public >*/
56
MemoryRegion iomem;
57
qemu_irq timerintc;
58
- uint32_t pclk_frq;
59
Clock *timclk;
60
61
CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES];
62
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/hw/timer/cmsdk-apb-timer.h
65
+++ b/include/hw/timer/cmsdk-apb-timer.h
66
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
67
68
/*
69
* QEMU interface:
70
- * + QOM property "pclk-frq": frequency at which the timer is clocked
71
* + Clock input "pclk": clock for the timer
72
* + sysbus MMIO region 0: the register bank
73
* + sysbus IRQ 0: timer interrupt TIMERINT
74
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
75
/*< public >*/
76
MemoryRegion iomem;
77
qemu_irq timerint;
78
- uint32_t pclk_frq;
79
struct ptimer_state *timer;
80
Clock *pclk;
81
82
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
83
index XXXXXXX..XXXXXXX 100644
84
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
85
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
86
@@ -XXX,XX +XXX,XX @@
87
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
88
*
89
* QEMU interface:
90
- * + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
91
* + Clock input "WDOGCLK": clock for the watchdog's timer
92
* + sysbus MMIO region 0: the register bank
93
* + sysbus IRQ 0: watchdog interrupt
94
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBWatchdog {
95
/*< public >*/
96
MemoryRegion iomem;
97
qemu_irq wdogint;
98
- uint32_t wdogclk_frq;
99
bool is_luminary;
100
struct ptimer_state *timer;
101
Clock *wdogclk;
102
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/hw/arm/armsse.c
105
+++ b/hw/arm/armsse.c
106
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
107
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
108
MemoryRegion *),
109
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
110
- DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
111
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
112
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
113
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
114
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
115
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
116
MemoryRegion *),
117
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
118
- DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
119
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
120
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
121
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
122
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/timer/cmsdk-apb-dualtimer.c
125
+++ b/hw/timer/cmsdk-apb-dualtimer.c
126
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
127
}
128
};
23
};
129
24
130
-static Property cmsdk_apb_dualtimer_properties[] = {
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
131
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBDualTimer, pclk_frq, 0),
26
132
- DEFINE_PROP_END_OF_LIST(),
27
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
133
-};
28
134
-
29
-/* Main SYSCLK frequency in Hz */
135
static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
30
-#define SYSCLK_FRQ 20000000
31
/* Slow 32Khz S32KCLK frequency in Hz */
32
#define S32KCLK_FRQ (32 * 1000)
33
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
35
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
36
const char *name, hwaddr size)
136
{
37
{
137
DeviceClass *dc = DEVICE_CLASS(klass);
38
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
138
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
39
CMSDKAPBUART *uart = opaque;
139
dc->realize = cmsdk_apb_dualtimer_realize;
40
int i = uart - &mms->uart[0];
140
dc->vmsd = &cmsdk_apb_dualtimer_vmstate;
41
int rxirqno = i * 2;
141
dc->reset = cmsdk_apb_dualtimer_reset;
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
142
- device_class_set_props(dc, cmsdk_apb_dualtimer_properties);
43
44
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
45
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
46
- qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
47
+ qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
48
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
49
s = SYS_BUS_DEVICE(uart);
50
sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
51
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
52
53
/* These clocks don't need migration because they are fixed-frequency */
54
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
55
- clock_set_hz(mms->sysclk, SYSCLK_FRQ);
56
+ clock_set_hz(mms->sysclk, mmc->sysclk_frq);
57
mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
58
clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
59
60
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
61
mmc->fpga_type = FPGA_AN505;
62
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
63
mmc->scc_id = 0x41045050;
64
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
65
mmc->armsse_type = TYPE_IOTKIT;
143
}
66
}
144
67
145
static const TypeInfo cmsdk_apb_dualtimer_info = {
68
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
146
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
69
mmc->fpga_type = FPGA_AN521;
147
index XXXXXXX..XXXXXXX 100644
70
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
148
--- a/hw/timer/cmsdk-apb-timer.c
71
mmc->scc_id = 0x41045210;
149
+++ b/hw/timer/cmsdk-apb-timer.c
72
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
150
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_timer_vmstate = {
73
mmc->armsse_type = TYPE_SSE200;
151
}
152
};
153
154
-static Property cmsdk_apb_timer_properties[] = {
155
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTimer, pclk_frq, 0),
156
- DEFINE_PROP_END_OF_LIST(),
157
-};
158
-
159
static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
160
{
161
DeviceClass *dc = DEVICE_CLASS(klass);
162
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
163
dc->realize = cmsdk_apb_timer_realize;
164
dc->vmsd = &cmsdk_apb_timer_vmstate;
165
dc->reset = cmsdk_apb_timer_reset;
166
- device_class_set_props(dc, cmsdk_apb_timer_properties);
167
}
74
}
168
75
169
static const TypeInfo cmsdk_apb_timer_info = {
170
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/hw/watchdog/cmsdk-apb-watchdog.c
173
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
174
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
175
}
176
};
177
178
-static Property cmsdk_apb_watchdog_properties[] = {
179
- DEFINE_PROP_UINT32("wdogclk-frq", CMSDKAPBWatchdog, wdogclk_frq, 0),
180
- DEFINE_PROP_END_OF_LIST(),
181
-};
182
-
183
static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
184
{
185
DeviceClass *dc = DEVICE_CLASS(klass);
186
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
187
dc->realize = cmsdk_apb_watchdog_realize;
188
dc->vmsd = &cmsdk_apb_watchdog_vmstate;
189
dc->reset = cmsdk_apb_watchdog_reset;
190
- device_class_set_props(dc, cmsdk_apb_watchdog_properties);
191
}
192
193
static const TypeInfo cmsdk_apb_watchdog_info = {
194
--
76
--
195
2.20.1
77
2.20.1
196
78
197
79
diff view generated by jsdifflib
1
As the first step in converting the CMSDK_APB_TIMER device to the
1
Currently the MPS2 SCC device implements a fixed number of OSCCLK
2
Clock framework, add a Clock input. For the moment we do nothing
2
values (3). The variant of this device in the MPS3 AN524 board has 6
3
with this clock; we will change the behaviour from using the pclk-frq
3
OSCCLK values. Switch to using a PROP_ARRAY, which allows board code
4
property to using the Clock once all the users of this device have
4
to specify how large the OSCCLK array should be as well as its
5
been converted to wire up the Clock.
5
values.
6
6
7
Since the device doesn't already have a doc comment for its "QEMU
7
With a variable-length property array, the SCC no longer specifies
8
interface", we add one including the new Clock.
8
default values for the OSCCLKs, so we must set them explicitly in the
9
board code. This defaults are actually incorrect for the an521 and
10
an505; we will correct this bug in a following patch.
9
11
10
This is a migration compatibility break for machines mps2-an505,
12
This is a migration compatibility break for all the mps boards.
11
mps2-an521, musca-a, musca-b1.
12
13
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20210215115138.20465-3-peter.maydell@linaro.org
17
Message-id: 20210128114145.20536-8-peter.maydell@linaro.org
18
Message-id: 20210121190622.22000-8-peter.maydell@linaro.org
19
---
18
---
20
include/hw/timer/cmsdk-apb-timer.h | 9 +++++++++
19
include/hw/misc/mps2-scc.h | 7 +++----
21
hw/timer/cmsdk-apb-timer.c | 7 +++++--
20
hw/arm/mps2-tz.c | 5 +++++
22
2 files changed, 14 insertions(+), 2 deletions(-)
21
hw/arm/mps2.c | 5 +++++
22
hw/misc/mps2-scc.c | 24 +++++++++++++-----------
23
4 files changed, 26 insertions(+), 15 deletions(-)
23
24
24
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
25
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/timer/cmsdk-apb-timer.h
27
--- a/include/hw/misc/mps2-scc.h
27
+++ b/include/hw/timer/cmsdk-apb-timer.h
28
+++ b/include/hw/misc/mps2-scc.h
28
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
29
#include "hw/qdev-properties.h"
30
#define TYPE_MPS2_SCC "mps2-scc"
30
#include "hw/sysbus.h"
31
OBJECT_DECLARE_SIMPLE_TYPE(MPS2SCC, MPS2_SCC)
31
#include "hw/ptimer.h"
32
32
+#include "hw/clock.h"
33
-#define NUM_OSCCLK 3
33
#include "qom/object.h"
34
-
34
35
struct MPS2SCC {
35
#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
36
OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
37
38
+/*
39
+ * QEMU interface:
40
+ * + QOM property "pclk-frq": frequency at which the timer is clocked
41
+ * + Clock input "pclk": clock for the timer
42
+ * + sysbus MMIO region 0: the register bank
43
+ * + sysbus IRQ 0: timer interrupt TIMERINT
44
+ */
45
struct CMSDKAPBTimer {
46
/*< private >*/
36
/*< private >*/
47
SysBusDevice parent_obj;
37
SysBusDevice parent_obj;
48
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
38
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
49
qemu_irq timerint;
39
uint32_t dll;
50
uint32_t pclk_frq;
40
uint32_t aid;
51
struct ptimer_state *timer;
41
uint32_t id;
52
+ Clock *pclk;
42
- uint32_t oscclk[NUM_OSCCLK];
53
43
- uint32_t oscclk_reset[NUM_OSCCLK];
54
uint32_t ctrl;
44
+ uint32_t num_oscclk;
55
uint32_t value;
45
+ uint32_t *oscclk;
56
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
46
+ uint32_t *oscclk_reset;
47
};
48
49
#endif
50
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
57
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-timer.c
52
--- a/hw/arm/mps2-tz.c
59
+++ b/hw/timer/cmsdk-apb-timer.c
53
+++ b/hw/arm/mps2-tz.c
60
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
61
#include "hw/sysbus.h"
55
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
62
#include "hw/irq.h"
56
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
63
#include "hw/registerfields.h"
57
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
64
+#include "hw/qdev-clock.h"
58
+ /* This will need to be per-FPGA image eventually */
65
#include "hw/timer/cmsdk-apb-timer.h"
59
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
66
#include "migration/vmstate.h"
60
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
67
61
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
68
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
62
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
69
s, "cmsdk-apb-timer", 0x1000);
63
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
70
sysbus_init_mmio(sbd, &s->iomem);
64
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
71
sysbus_init_irq(sbd, &s->timerint);
72
+ s->pclk = qdev_init_clock_in(DEVICE(s), "pclk", NULL, NULL);
73
}
65
}
74
66
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
75
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
67
index XXXXXXX..XXXXXXX 100644
76
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
68
--- a/hw/arm/mps2.c
77
69
+++ b/hw/arm/mps2.c
78
static const VMStateDescription cmsdk_apb_timer_vmstate = {
70
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
79
.name = "cmsdk-apb-timer",
71
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
72
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
73
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
74
+ /* All these FPGA images have the same OSCCLK configuration */
75
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
76
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
77
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
78
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
79
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
80
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
81
object_initialize_child(OBJECT(mms), "fpgaio",
82
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/misc/mps2-scc.c
85
+++ b/hw/misc/mps2-scc.c
86
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
87
{
88
trace_mps2_scc_cfg_write(function, device, value);
89
90
- if (function != 1 || device >= NUM_OSCCLK) {
91
+ if (function != 1 || device >= s->num_oscclk) {
92
qemu_log_mask(LOG_GUEST_ERROR,
93
"MPS2 SCC config write: bad function %d device %d\n",
94
function, device);
95
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
96
static bool scc_cfg_read(MPS2SCC *s, unsigned function,
97
unsigned device, uint32_t *value)
98
{
99
- if (function != 1 || device >= NUM_OSCCLK) {
100
+ if (function != 1 || device >= s->num_oscclk) {
101
qemu_log_mask(LOG_GUEST_ERROR,
102
"MPS2 SCC config read: bad function %d device %d\n",
103
function, device);
104
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
105
s->cfgctrl = 0x100000;
106
s->cfgstat = 0;
107
s->dll = 0xffff0001;
108
- for (i = 0; i < NUM_OSCCLK; i++) {
109
+ for (i = 0; i < s->num_oscclk; i++) {
110
s->oscclk[i] = s->oscclk_reset[i];
111
}
112
for (i = 0; i < ARRAY_SIZE(s->led); i++) {
113
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
114
LED_COLOR_GREEN, name);
115
g_free(name);
116
}
117
+
118
+ s->oscclk = g_new0(uint32_t, s->num_oscclk);
119
}
120
121
static const VMStateDescription mps2_scc_vmstate = {
122
.name = "mps2-scc",
80
- .version_id = 1,
123
- .version_id = 1,
81
- .minimum_version_id = 1,
124
- .minimum_version_id = 1,
82
+ .version_id = 2,
125
+ .version_id = 2,
83
+ .minimum_version_id = 2,
126
+ .minimum_version_id = 2,
84
.fields = (VMStateField[]) {
127
.fields = (VMStateField[]) {
85
VMSTATE_PTIMER(timer, CMSDKAPBTimer),
128
VMSTATE_UINT32(cfg0, MPS2SCC),
86
+ VMSTATE_CLOCK(pclk, CMSDKAPBTimer),
129
VMSTATE_UINT32(cfg1, MPS2SCC),
87
VMSTATE_UINT32(ctrl, CMSDKAPBTimer),
130
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
88
VMSTATE_UINT32(value, CMSDKAPBTimer),
131
VMSTATE_UINT32(cfgctrl, MPS2SCC),
89
VMSTATE_UINT32(reload, CMSDKAPBTimer),
132
VMSTATE_UINT32(cfgstat, MPS2SCC),
133
VMSTATE_UINT32(dll, MPS2SCC),
134
- VMSTATE_UINT32_ARRAY(oscclk, MPS2SCC, NUM_OSCCLK),
135
+ VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
136
+ 0, vmstate_info_uint32, uint32_t),
137
VMSTATE_END_OF_LIST()
138
}
139
};
140
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
141
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
142
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
143
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
144
- /* These are the initial settings for the source clocks on the board.
145
+ /*
146
+ * These are the initial settings for the source clocks on the board.
147
* In hardware they can be configured via a config file read by the
148
* motherboard configuration controller to suit the FPGA image.
149
- * These default values are used by most of the standard FPGA images.
150
*/
151
- DEFINE_PROP_UINT32("oscclk0", MPS2SCC, oscclk_reset[0], 50000000),
152
- DEFINE_PROP_UINT32("oscclk1", MPS2SCC, oscclk_reset[1], 24576000),
153
- DEFINE_PROP_UINT32("oscclk2", MPS2SCC, oscclk_reset[2], 25000000),
154
+ DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
155
+ qdev_prop_uint32, uint32_t),
156
DEFINE_PROP_END_OF_LIST(),
157
};
158
90
--
159
--
91
2.20.1
160
2.20.1
92
161
93
162
diff view generated by jsdifflib
1
The old-style convenience function cmsdk_apb_timer_create() for
1
We were previously using the default OSCCLK settings, which are
2
creating CMSDK_APB_TIMER objects is used in only two places in
2
correct for the older MPS2 boards (mps2-an385, mps2-an386,
3
mps2.c. Most of the rest of the code in that file uses the new
3
mps2-an500, mps2-an511), but wrong for the mps2-an505 and mps2-511
4
"initialize in place" coding style.
4
implemented in mps2-tz.c. Now we're setting the values explicitly we
5
5
can fix them to be correct.
6
We want to connect up a Clock object which should be done between the
7
object creation and realization; rather than adding a Clock* argument
8
to the convenience function, convert the timer creation code in
9
mps2.c to the same style as is used already for the watchdog,
10
dualtimer and other devices, and delete the now-unused convenience
11
function.
12
6
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Luc Michel <luc@lmichel.fr>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210215115138.20465-4-peter.maydell@linaro.org
17
Message-id: 20210128114145.20536-13-peter.maydell@linaro.org
18
Message-id: 20210121190622.22000-13-peter.maydell@linaro.org
19
---
11
---
20
include/hw/timer/cmsdk-apb-timer.h | 21 ---------------------
12
hw/arm/mps2-tz.c | 4 ++--
21
hw/arm/mps2.c | 18 ++++++++++++++++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
22
2 files changed, 16 insertions(+), 23 deletions(-)
23
14
24
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/timer/cmsdk-apb-timer.h
17
--- a/hw/arm/mps2-tz.c
27
+++ b/include/hw/timer/cmsdk-apb-timer.h
18
+++ b/hw/arm/mps2-tz.c
28
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
19
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
29
uint32_t intstatus;
20
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
30
};
21
/* This will need to be per-FPGA image eventually */
31
22
qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
32
-/**
23
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
33
- * cmsdk_apb_timer_create - convenience function to create TYPE_CMSDK_APB_TIMER
24
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
34
- * @addr: location in system memory to map registers
25
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
35
- * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
26
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
36
- */
27
qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
37
-static inline DeviceState *cmsdk_apb_timer_create(hwaddr addr,
28
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
38
- qemu_irq timerint,
29
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
39
- uint32_t pclk_frq)
40
-{
41
- DeviceState *dev;
42
- SysBusDevice *s;
43
-
44
- dev = qdev_new(TYPE_CMSDK_APB_TIMER);
45
- s = SYS_BUS_DEVICE(dev);
46
- qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
47
- sysbus_realize_and_unref(s, &error_fatal);
48
- sysbus_mmio_map(s, 0, addr);
49
- sysbus_connect_irq(s, 0, timerint);
50
- return dev;
51
-}
52
-
53
#endif
54
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/mps2.c
57
+++ b/hw/arm/mps2.c
58
@@ -XXX,XX +XXX,XX @@ struct MPS2MachineState {
59
/* CMSDK APB subsystem */
60
CMSDKAPBDualTimer dualtimer;
61
CMSDKAPBWatchdog watchdog;
62
+ CMSDKAPBTimer timer[2];
63
};
64
65
#define TYPE_MPS2_MACHINE "mps2"
66
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
67
}
68
69
/* CMSDK APB subsystem */
70
- cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
71
- cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
72
+ for (i = 0; i < ARRAY_SIZE(mms->timer); i++) {
73
+ g_autofree char *name = g_strdup_printf("timer%d", i);
74
+ hwaddr base = 0x40000000 + i * 0x1000;
75
+ int irqno = 8 + i;
76
+ SysBusDevice *sbd;
77
+
78
+ object_initialize_child(OBJECT(mms), name, &mms->timer[i],
79
+ TYPE_CMSDK_APB_TIMER);
80
+ sbd = SYS_BUS_DEVICE(&mms->timer[i]);
81
+ qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
82
+ sysbus_realize_and_unref(sbd, &error_fatal);
83
+ sysbus_mmio_map(sbd, 0, base);
84
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
85
+ }
86
+
87
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
88
TYPE_CMSDK_APB_DUALTIMER);
89
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
90
--
30
--
91
2.20.1
31
2.20.1
92
32
93
33
diff view generated by jsdifflib
1
Switch the CMSDK APB timer device over to using its Clock input; the
1
The AN505 and AN511 happen to share the same OSCCLK values, but the
2
pclk-frq property is now ignored.
2
AN524 will have a different set (and more of them), so split the
3
settings out to be per-board.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215115138.20465-5-peter.maydell@linaro.org
8
Message-id: 20210128114145.20536-19-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-19-peter.maydell@linaro.org
10
---
9
---
11
hw/timer/cmsdk-apb-timer.c | 18 ++++++++++++++----
10
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
12
1 file changed, 14 insertions(+), 4 deletions(-)
11
1 file changed, 18 insertions(+), 5 deletions(-)
13
12
14
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/timer/cmsdk-apb-timer.c
15
--- a/hw/arm/mps2-tz.c
17
+++ b/hw/timer/cmsdk-apb-timer.c
16
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
19
ptimer_transaction_commit(s->timer);
18
MPS2TZFPGAType fpga_type;
19
uint32_t scc_id;
20
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
21
+ uint32_t len_oscclk;
22
+ const uint32_t *oscclk;
23
const char *armsse_type;
24
};
25
26
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
27
/* Slow 32Khz S32KCLK frequency in Hz */
28
#define S32KCLK_FRQ (32 * 1000)
29
30
+static const uint32_t an505_oscclk[] = {
31
+ 40000000,
32
+ 24580000,
33
+ 25000000,
34
+};
35
+
36
/* Create an alias of an entire original MemoryRegion @orig
37
* located at @base in the memory map.
38
*/
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
40
MPS2SCC *scc = opaque;
41
DeviceState *sccdev;
42
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
43
+ uint32_t i;
44
45
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
46
sccdev = DEVICE(scc);
47
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
48
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
49
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
50
- /* This will need to be per-FPGA image eventually */
51
- qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
52
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
53
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
54
- qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
55
+ qdev_prop_set_uint32(sccdev, "len-oscclk", mmc->len_oscclk);
56
+ for (i = 0; i < mmc->len_oscclk; i++) {
57
+ g_autofree char *propname = g_strdup_printf("oscclk[%u]", i);
58
+ qdev_prop_set_uint32(sccdev, propname, mmc->oscclk[i]);
59
+ }
60
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
61
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
20
}
62
}
21
63
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
22
+static void cmsdk_apb_timer_clk_update(void *opaque)
64
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
23
+{
65
mmc->scc_id = 0x41045050;
24
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
66
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
25
+
67
+ mmc->oscclk = an505_oscclk;
26
+ ptimer_transaction_begin(s->timer);
68
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
27
+ ptimer_set_period_from_clock(s->timer, s->pclk, 1);
69
mmc->armsse_type = TYPE_IOTKIT;
28
+ ptimer_transaction_commit(s->timer);
29
+}
30
+
31
static void cmsdk_apb_timer_init(Object *obj)
32
{
33
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
34
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
35
s, "cmsdk-apb-timer", 0x1000);
36
sysbus_init_mmio(sbd, &s->iomem);
37
sysbus_init_irq(sbd, &s->timerint);
38
- s->pclk = qdev_init_clock_in(DEVICE(s), "pclk", NULL, NULL);
39
+ s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
40
+ cmsdk_apb_timer_clk_update, s);
41
}
70
}
42
71
43
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
72
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
44
{
73
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
45
CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
74
mmc->scc_id = 0x41045210;
46
75
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
47
- if (s->pclk_frq == 0) {
76
+ mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
48
- error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
77
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
49
+ if (!clock_has_source(s->pclk)) {
78
mmc->armsse_type = TYPE_SSE200;
50
+ error_setg(errp, "CMSDK APB timer: pclk clock must be connected");
51
return;
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
55
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
56
57
ptimer_transaction_begin(s->timer);
58
- ptimer_set_freq(s->timer, s->pclk_frq);
59
+ ptimer_set_period_from_clock(s->timer, s->pclk, 1);
60
ptimer_transaction_commit(s->timer);
61
}
79
}
62
80
63
--
81
--
64
2.20.1
82
2.20.1
65
83
66
84
diff view generated by jsdifflib
1
The state struct for the CMSDK APB timer device doesn't follow our
1
The MPS2 board has 2 LEDs, but the MPS3 board has 10 LEDs. The
2
usual naming convention of camelcase -- "CMSDK" and "APB" are both
2
FPGAIO device is similar on both sets of boards, but the LED0
3
acronyms, but "TIMER" is not so should not be all-uppercase.
3
register has correspondingly more bits that have an effect. Add a
4
Globally rename the struct to "CMSDKAPBTimer" (bringing it into line
4
device property for number of LEDs.
5
with CMSDKAPBWatchdog and CMSDKAPBDualTimer; CMSDKAPBUART remains
6
as-is because "UART" is an acronym).
7
8
Commit created with:
9
perl -p -i -e 's/CMSDKAPBTIMER/CMSDKAPBTimer/g' hw/timer/cmsdk-apb-timer.c include/hw/arm/armsse.h include/hw/timer/cmsdk-apb-timer.h
10
5
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210215115138.20465-6-peter.maydell@linaro.org
15
Message-id: 20210128114145.20536-7-peter.maydell@linaro.org
16
Message-id: 20210121190622.22000-7-peter.maydell@linaro.org
17
---
10
---
18
include/hw/arm/armsse.h | 6 +++---
11
include/hw/misc/mps2-fpgaio.h | 5 ++++-
19
include/hw/timer/cmsdk-apb-timer.h | 4 ++--
12
hw/misc/mps2-fpgaio.c | 31 +++++++++++++++++++++++--------
20
hw/timer/cmsdk-apb-timer.c | 28 ++++++++++++++--------------
13
2 files changed, 27 insertions(+), 9 deletions(-)
21
3 files changed, 19 insertions(+), 19 deletions(-)
22
14
23
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
15
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/armsse.h
17
--- a/include/hw/misc/mps2-fpgaio.h
26
+++ b/include/hw/arm/armsse.h
18
+++ b/include/hw/misc/mps2-fpgaio.h
27
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
28
TZPPC apb_ppc0;
29
TZPPC apb_ppc1;
30
TZMPC mpc[IOTS_NUM_MPC];
31
- CMSDKAPBTIMER timer0;
32
- CMSDKAPBTIMER timer1;
33
- CMSDKAPBTIMER s32ktimer;
34
+ CMSDKAPBTimer timer0;
35
+ CMSDKAPBTimer timer1;
36
+ CMSDKAPBTimer s32ktimer;
37
qemu_or_irq ppc_irq_orgate;
38
SplitIRQ sec_resp_splitter;
39
SplitIRQ ppc_irq_splitter[NUM_PPCS];
40
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/timer/cmsdk-apb-timer.h
43
+++ b/include/hw/timer/cmsdk-apb-timer.h
44
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
45
#include "qom/object.h"
20
#define TYPE_MPS2_FPGAIO "mps2-fpgaio"
46
21
OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO)
47
#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
22
48
-OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTIMER, CMSDK_APB_TIMER)
23
+#define MPS2FPGAIO_MAX_LEDS 32
49
+OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
24
+
50
25
struct MPS2FPGAIO {
51
-struct CMSDKAPBTIMER {
52
+struct CMSDKAPBTimer {
53
/*< private >*/
26
/*< private >*/
54
SysBusDevice parent_obj;
27
SysBusDevice parent_obj;
55
28
56
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
29
/*< public >*/
30
MemoryRegion iomem;
31
- LEDState *led[2];
32
+ LEDState *led[MPS2FPGAIO_MAX_LEDS];
33
+ uint32_t num_leds;
34
35
uint32_t led0;
36
uint32_t prescale;
37
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
57
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-timer.c
39
--- a/hw/misc/mps2-fpgaio.c
59
+++ b/hw/timer/cmsdk-apb-timer.c
40
+++ b/hw/misc/mps2-fpgaio.c
60
@@ -XXX,XX +XXX,XX @@ static const int timer_id[] = {
41
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
61
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
42
62
};
43
switch (offset) {
63
44
case A_LED0:
64
-static void cmsdk_apb_timer_update(CMSDKAPBTIMER *s)
45
- s->led0 = value & 0x3;
65
+static void cmsdk_apb_timer_update(CMSDKAPBTimer *s)
46
- led_set_state(s->led[0], value & 0x01);
47
- led_set_state(s->led[1], value & 0x02);
48
+ if (s->num_leds != 0) {
49
+ uint32_t i;
50
+
51
+ s->led0 = value & MAKE_64BIT_MASK(0, s->num_leds);
52
+ for (i = 0; i < s->num_leds; i++) {
53
+ led_set_state(s->led[i], value & (1 << i));
54
+ }
55
+ }
56
break;
57
case A_PRESCALE:
58
resync_counter(s);
59
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_reset(DeviceState *dev)
60
s->pscntr = 0;
61
s->pscntr_sync_ticks = now;
62
63
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
64
+ for (size_t i = 0; i < s->num_leds; i++) {
65
device_cold_reset(DEVICE(s->led[i]));
66
}
67
}
68
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_init(Object *obj)
69
static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
66
{
70
{
67
qemu_set_irq(s->timerint, !!(s->intstatus & R_INTSTATUS_IRQ_MASK));
71
MPS2FPGAIO *s = MPS2_FPGAIO(dev);
72
+ uint32_t i;
73
74
- s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
75
- LED_COLOR_GREEN, "USERLED0");
76
- s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
77
- LED_COLOR_GREEN, "USERLED1");
78
+ if (s->num_leds > MPS2FPGAIO_MAX_LEDS) {
79
+ error_setg(errp, "num-leds cannot be greater than %d",
80
+ MPS2FPGAIO_MAX_LEDS);
81
+ return;
82
+ }
83
+
84
+ for (i = 0; i < s->num_leds; i++) {
85
+ g_autofree char *ledname = g_strdup_printf("USERLED%d", i);
86
+ s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
87
+ LED_COLOR_GREEN, ledname);
88
+ }
68
}
89
}
69
90
70
static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
91
static bool mps2_fpgaio_counters_needed(void *opaque)
71
{
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_fpgaio_vmstate = {
72
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
93
static Property mps2_fpgaio_properties[] = {
73
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
94
/* Frequency of the prescale counter */
74
uint64_t r;
95
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
75
96
+ /* Number of LEDs controlled by LED0 register */
76
switch (offset) {
97
+ DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
77
@@ -XXX,XX +XXX,XX @@ static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
78
static void cmsdk_apb_timer_write(void *opaque, hwaddr offset, uint64_t value,
79
unsigned size)
80
{
81
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
82
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
83
84
trace_cmsdk_apb_timer_write(offset, value, size);
85
86
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps cmsdk_apb_timer_ops = {
87
88
static void cmsdk_apb_timer_tick(void *opaque)
89
{
90
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
91
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
92
93
if (s->ctrl & R_CTRL_IRQEN_MASK) {
94
s->intstatus |= R_INTSTATUS_IRQ_MASK;
95
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_tick(void *opaque)
96
97
static void cmsdk_apb_timer_reset(DeviceState *dev)
98
{
99
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
100
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
101
102
trace_cmsdk_apb_timer_reset();
103
s->ctrl = 0;
104
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
105
static void cmsdk_apb_timer_init(Object *obj)
106
{
107
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
108
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(obj);
109
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(obj);
110
111
memory_region_init_io(&s->iomem, obj, &cmsdk_apb_timer_ops,
112
s, "cmsdk-apb-timer", 0x1000);
113
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
114
115
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
116
{
117
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
118
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
119
120
if (s->pclk_frq == 0) {
121
error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
122
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_timer_vmstate = {
123
.version_id = 1,
124
.minimum_version_id = 1,
125
.fields = (VMStateField[]) {
126
- VMSTATE_PTIMER(timer, CMSDKAPBTIMER),
127
- VMSTATE_UINT32(ctrl, CMSDKAPBTIMER),
128
- VMSTATE_UINT32(value, CMSDKAPBTIMER),
129
- VMSTATE_UINT32(reload, CMSDKAPBTIMER),
130
- VMSTATE_UINT32(intstatus, CMSDKAPBTIMER),
131
+ VMSTATE_PTIMER(timer, CMSDKAPBTimer),
132
+ VMSTATE_UINT32(ctrl, CMSDKAPBTimer),
133
+ VMSTATE_UINT32(value, CMSDKAPBTimer),
134
+ VMSTATE_UINT32(reload, CMSDKAPBTimer),
135
+ VMSTATE_UINT32(intstatus, CMSDKAPBTimer),
136
VMSTATE_END_OF_LIST()
137
}
138
};
139
140
static Property cmsdk_apb_timer_properties[] = {
141
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTIMER, pclk_frq, 0),
142
+ DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTimer, pclk_frq, 0),
143
DEFINE_PROP_END_OF_LIST(),
98
DEFINE_PROP_END_OF_LIST(),
144
};
99
};
145
100
146
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
147
static const TypeInfo cmsdk_apb_timer_info = {
148
.name = TYPE_CMSDK_APB_TIMER,
149
.parent = TYPE_SYS_BUS_DEVICE,
150
- .instance_size = sizeof(CMSDKAPBTIMER),
151
+ .instance_size = sizeof(CMSDKAPBTimer),
152
.instance_init = cmsdk_apb_timer_init,
153
.class_init = cmsdk_apb_timer_class_init,
154
};
155
--
101
--
156
2.20.1
102
2.20.1
157
103
158
104
diff view generated by jsdifflib
1
Create and connect the two clocks needed by the ARMSSE.
1
MPS3 boards have an extra SWITCH register in the FPGAIO block which
2
reports the value of some switches. Implement this, governed by a
3
property the board code can use to specify whether whether it exists.
2
4
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215115138.20465-7-peter.maydell@linaro.org
7
Message-id: 20210128114145.20536-16-peter.maydell@linaro.org
8
Message-id: 20210121190622.22000-16-peter.maydell@linaro.org
9
---
9
---
10
hw/arm/musca.c | 12 ++++++++++++
10
include/hw/misc/mps2-fpgaio.h | 1 +
11
1 file changed, 12 insertions(+)
11
hw/misc/mps2-fpgaio.c | 10 ++++++++++
12
2 files changed, 11 insertions(+)
12
13
13
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
14
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/musca.c
16
--- a/include/hw/misc/mps2-fpgaio.h
16
+++ b/hw/arm/musca.c
17
+++ b/include/hw/misc/mps2-fpgaio.h
17
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ struct MPS2FPGAIO {
18
#include "hw/misc/tz-ppc.h"
19
MemoryRegion iomem;
19
#include "hw/misc/unimp.h"
20
LEDState *led[MPS2FPGAIO_MAX_LEDS];
20
#include "hw/rtc/pl031.h"
21
uint32_t num_leds;
21
+#include "hw/qdev-clock.h"
22
+ bool has_switches;
22
#include "qom/object.h"
23
23
24
uint32_t led0;
24
#define MUSCA_NUMIRQ_MAX 96
25
uint32_t prescale;
25
@@ -XXX,XX +XXX,XX @@ struct MuscaMachineState {
26
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
26
UnimplementedDeviceState sdio;
27
index XXXXXXX..XXXXXXX 100644
27
UnimplementedDeviceState gpio;
28
--- a/hw/misc/mps2-fpgaio.c
28
UnimplementedDeviceState cryptoisland;
29
+++ b/hw/misc/mps2-fpgaio.c
29
+ Clock *sysclk;
30
@@ -XXX,XX +XXX,XX @@ REG32(CLK100HZ, 0x14)
30
+ Clock *s32kclk;
31
REG32(COUNTER, 0x18)
32
REG32(PRESCALE, 0x1c)
33
REG32(PSCNTR, 0x20)
34
+REG32(SWITCH, 0x28)
35
REG32(MISC, 0x4c)
36
37
static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int frq)
38
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
39
resync_counter(s);
40
r = s->pscntr;
41
break;
42
+ case A_SWITCH:
43
+ if (!s->has_switches) {
44
+ goto bad_offset;
45
+ }
46
+ /* User-togglable board switches. We don't model that, so report 0. */
47
+ r = 0;
48
+ break;
49
default:
50
+ bad_offset:
51
qemu_log_mask(LOG_GUEST_ERROR,
52
"MPS2 FPGAIO read: bad offset %x\n", (int) offset);
53
r = 0;
54
@@ -XXX,XX +XXX,XX @@ static Property mps2_fpgaio_properties[] = {
55
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
56
/* Number of LEDs controlled by LED0 register */
57
DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
58
+ DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
59
DEFINE_PROP_END_OF_LIST(),
31
};
60
};
32
61
33
#define TYPE_MUSCA_MACHINE "musca"
34
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MuscaMachineState, MuscaMachineClass, MUSCA_MACHINE)
35
* don't model that in our SSE-200 model yet.
36
*/
37
#define SYSCLK_FRQ 40000000
38
+/* Slow 32Khz S32KCLK frequency in Hz */
39
+#define S32KCLK_FRQ (32 * 1000)
40
41
static qemu_irq get_sse_irq_in(MuscaMachineState *mms, int irqno)
42
{
43
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
44
exit(1);
45
}
46
47
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
48
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
49
+ mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
50
+ clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
51
+
52
object_initialize_child(OBJECT(machine), "sse-200", &mms->sse,
53
TYPE_SSE200);
54
ssedev = DEVICE(&mms->sse);
55
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
56
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
57
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
58
qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
59
+ qdev_connect_clock_in(ssedev, "MAINCLK", mms->sysclk);
60
+ qdev_connect_clock_in(ssedev, "S32KCLK", mms->s32kclk);
61
/*
62
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
63
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
64
--
62
--
65
2.20.1
63
2.20.1
66
64
67
65
diff view generated by jsdifflib
1
Create a fixed-frequency Clock object to be the SYSCLK, and wire it
1
Set the FPGAIO num-leds and have-switches properties explicitly
2
up to the devices that require it.
2
per-board, rather than relying on the defaults. The AN505 and AN521
3
both have the same settings as the default values, but the AN524 will
4
be different.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210215115138.20465-8-peter.maydell@linaro.org
8
Message-id: 20210128114145.20536-14-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-14-peter.maydell@linaro.org
10
---
10
---
11
hw/arm/mps2.c | 9 +++++++++
11
hw/arm/mps2-tz.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
12
1 file changed, 9 insertions(+)
13
13
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2.c
16
--- a/hw/arm/mps2-tz.c
17
+++ b/hw/arm/mps2.c
17
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
19
#include "hw/net/lan9118.h"
19
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
20
#include "net/net.h"
20
uint32_t len_oscclk;
21
#include "hw/watchdog/cmsdk-apb-watchdog.h"
21
const uint32_t *oscclk;
22
+#include "hw/qdev-clock.h"
22
+ uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
23
#include "qom/object.h"
23
+ bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
24
24
const char *armsse_type;
25
typedef enum MPS2FPGAType {
26
@@ -XXX,XX +XXX,XX @@ struct MPS2MachineState {
27
CMSDKAPBDualTimer dualtimer;
28
CMSDKAPBWatchdog watchdog;
29
CMSDKAPBTimer timer[2];
30
+ Clock *sysclk;
31
};
25
};
32
26
33
#define TYPE_MPS2_MACHINE "mps2"
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
34
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
28
const char *name, hwaddr size)
35
exit(EXIT_FAILURE);
29
{
36
}
30
MPS2FPGAIO *fpgaio = opaque;
37
31
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
38
+ /* This clock doesn't need migration because it is fixed-frequency */
32
39
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
33
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
40
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
34
+ qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
41
+
35
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
42
/* The FPGA images have an odd combination of different RAMs,
36
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
43
* because in hardware they are different implementations and
37
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
44
* connected to different buses, giving varying performance/size
38
}
45
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
39
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
46
TYPE_CMSDK_APB_TIMER);
40
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
47
sbd = SYS_BUS_DEVICE(&mms->timer[i]);
41
mmc->oscclk = an505_oscclk;
48
qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
42
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
49
+ qdev_connect_clock_in(DEVICE(&mms->timer[i]), "pclk", mms->sysclk);
43
+ mmc->fpgaio_num_leds = 2;
50
sysbus_realize_and_unref(sbd, &error_fatal);
44
+ mmc->fpgaio_has_switches = false;
51
sysbus_mmio_map(sbd, 0, base);
45
mmc->armsse_type = TYPE_IOTKIT;
52
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
46
}
53
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
47
54
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
48
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
55
TYPE_CMSDK_APB_DUALTIMER);
49
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
56
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
50
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
57
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->sysclk);
51
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
58
sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
52
+ mmc->fpgaio_num_leds = 2;
59
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
53
+ mmc->fpgaio_has_switches = false;
60
qdev_get_gpio_in(armv7m, 10));
54
mmc->armsse_type = TYPE_SSE200;
61
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
55
}
62
object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
56
63
TYPE_CMSDK_APB_WATCHDOG);
64
qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
65
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->sysclk);
66
sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
67
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
68
qdev_get_gpio_in_named(armv7m, "NMI", 0));
69
--
57
--
70
2.20.1
58
2.20.1
71
59
72
60
diff view generated by jsdifflib
1
While we transition the ARMSSE code from integer properties
1
In the mps2-tz board code, we handle devices whose interrupt lines
2
specifying clock frequencies to Clock objects, we want to have the
2
must be wired to all CPUs by creating IRQ splitter devices for the
3
device provide both at once. We want the final name of the main
3
AN521, because it has 2 CPUs, but wiring the device IRQ directly to
4
input Clock to be "MAINCLK", following the hardware name.
4
the SSE/IoTKit input for the AN505, which has only 1 CPU.
5
Unfortunately creating an input Clock with a name X creates an
6
under-the-hood QOM property X; for "MAINCLK" this clashes with the
7
existing UINT32 property of that name.
8
5
9
Rename the UINT32 property to MAINCLK_FRQ so it can coexist with the
6
We can avoid making an explicit check on the board type constant by
10
MAINCLK Clock; once the transition is complete MAINCLK_FRQ will be
7
instead creating and using the IRQ splitters for any board with more
11
deleted.
8
than 1 CPU. This avoids having to add extra cases to the
12
9
conditionals every time we add new boards.
13
Commit created with:
14
perl -p -i -e 's/MAINCLK/MAINCLK_FRQ/g' hw/arm/{armsse,mps2-tz,musca}.c include/hw/arm/armsse.h
15
10
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210215115138.20465-9-peter.maydell@linaro.org
20
Message-id: 20210128114145.20536-11-peter.maydell@linaro.org
21
Message-id: 20210121190622.22000-11-peter.maydell@linaro.org
22
---
15
---
23
include/hw/arm/armsse.h | 2 +-
16
hw/arm/mps2-tz.c | 19 +++++++++----------
24
hw/arm/armsse.c | 6 +++---
17
1 file changed, 9 insertions(+), 10 deletions(-)
25
hw/arm/mps2-tz.c | 2 +-
26
hw/arm/musca.c | 2 +-
27
4 files changed, 6 insertions(+), 6 deletions(-)
28
18
29
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/arm/armsse.h
32
+++ b/include/hw/arm/armsse.h
33
@@ -XXX,XX +XXX,XX @@
34
* QEMU interface:
35
* + QOM property "memory" is a MemoryRegion containing the devices provided
36
* by the board model.
37
- * + QOM property "MAINCLK" is the frequency of the main system clock
38
+ * + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
39
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
40
* (In hardware, the SSE-200 permits the number of expansion interrupts
41
* for the two CPUs to be configured separately, but we restrict it to
42
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/armsse.c
45
+++ b/hw/arm/armsse.c
46
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
47
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
48
MemoryRegion *),
49
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
50
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
51
+ DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
52
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
53
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
54
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
55
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
56
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
57
MemoryRegion *),
58
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
59
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
60
+ DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
61
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
62
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
63
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
}
66
67
if (!s->mainclk_frq) {
68
- error_setg(errp, "MAINCLK property was not set");
69
+ error_setg(errp, "MAINCLK_FRQ property was not set");
70
return;
71
}
72
73
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
74
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/arm/mps2-tz.c
21
--- a/hw/arm/mps2-tz.c
76
+++ b/hw/arm/mps2-tz.c
22
+++ b/hw/arm/mps2-tz.c
23
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
24
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
25
{
26
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
27
- MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
28
+ MachineClass *mc = MACHINE_GET_CLASS(mms);
29
30
assert(irqno < MPS2TZ_NUMIRQ);
31
32
- switch (mmc->fpga_type) {
33
- case FPGA_AN505:
34
- return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
35
- case FPGA_AN521:
36
+ if (mc->max_cpus > 1) {
37
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
38
- default:
39
- g_assert_not_reached();
40
+ } else {
41
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
42
}
43
}
44
77
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
45
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
78
object_property_set_link(OBJECT(&mms->iotkit), "memory",
79
OBJECT(system_memory), &error_abort);
80
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
81
- qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
82
+ qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
83
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
46
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
84
47
85
/*
48
/*
86
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
49
- * The AN521 needs us to create splitters to feed the IRQ inputs
87
index XXXXXXX..XXXXXXX 100644
50
- * for each CPU in the SSE-200 from each device in the board.
88
--- a/hw/arm/musca.c
51
+ * If this board has more than one CPU, then we need to create splitters
89
+++ b/hw/arm/musca.c
52
+ * to feed the IRQ inputs for each CPU in the SSE from each device in the
90
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
53
+ * board. If there is only one CPU, we can just wire the device IRQ
91
qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
54
+ * directly to the SSE's IRQ input.
92
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
55
*/
93
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
56
- if (mmc->fpga_type == FPGA_AN521) {
94
- qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
57
+ if (mc->max_cpus > 1) {
95
+ qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
58
for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
96
/*
59
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
97
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
60
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
98
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
99
--
61
--
100
2.20.1
62
2.20.1
101
63
102
64
diff view generated by jsdifflib
1
Remove all the code that sets frequency properties on the CMSDK
1
The AN524 has more interrupt lines than the AN505 and AN521; make
2
timer, dualtimer and watchdog devices and on the ARMSSE SoC device:
2
numirq board-specific rather than a compile-time constant.
3
these properties are unused now that the devices rely on their Clock
3
4
inputs instead.
4
Since the difference is small (92 on the current boards and 95 on the
5
new one) we don't dynamically allocate the cpu_irq_splitter[] array
6
but leave it as a fixed length array whose size is the maximum needed
7
for any of the boards.
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20210215115138.20465-10-peter.maydell@linaro.org
10
Message-id: 20210128114145.20536-24-peter.maydell@linaro.org
11
Message-id: 20210121190622.22000-24-peter.maydell@linaro.org
12
---
13
---
13
hw/arm/armsse.c | 7 -------
14
hw/arm/mps2-tz.c | 15 ++++++++++-----
14
hw/arm/mps2-tz.c | 1 -
15
1 file changed, 10 insertions(+), 5 deletions(-)
15
hw/arm/mps2.c | 3 ---
16
hw/arm/musca.c | 1 -
17
hw/arm/stellaris.c | 3 ---
18
5 files changed, 15 deletions(-)
19
16
20
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/armsse.c
23
+++ b/hw/arm/armsse.c
24
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
25
* it to the appropriate PPC port; then we can realize the PPC and
26
* map its upstream ends to the right place in the container.
27
*/
28
- qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
29
qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
30
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
31
return;
32
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
33
object_property_set_link(OBJECT(&s->apb_ppc0), "port[0]", OBJECT(mr),
34
&error_abort);
35
36
- qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
37
qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
38
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
39
return;
40
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
41
object_property_set_link(OBJECT(&s->apb_ppc0), "port[1]", OBJECT(mr),
42
&error_abort);
43
44
- qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
45
qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
46
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
47
return;
48
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
49
/* Devices behind APB PPC1:
50
* 0x4002f000: S32K timer
51
*/
52
- qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
53
qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
54
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
55
return;
56
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
57
qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
58
qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
59
60
- qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
61
qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
62
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
63
return;
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
66
/* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
67
68
- qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
69
qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
70
if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
71
return;
72
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
73
armsse_get_common_irq_in(s, 1));
74
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
75
76
- qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
77
qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
78
if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
79
return;
80
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
81
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/mps2-tz.c
19
--- a/hw/arm/mps2-tz.c
83
+++ b/hw/arm/mps2-tz.c
20
+++ b/hw/arm/mps2-tz.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/qdev-clock.h"
23
#include "qom/object.h"
24
25
-#define MPS2TZ_NUMIRQ 92
26
+#define MPS2TZ_NUMIRQ_MAX 92
27
28
typedef enum MPS2TZFPGAType {
29
FPGA_AN505,
30
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
31
const uint32_t *oscclk;
32
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
33
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
34
+ int numirq; /* Number of external interrupts */
35
const char *armsse_type;
36
};
37
38
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
39
SplitIRQ sec_resp_splitter;
40
qemu_or_irq uart_irq_orgate;
41
DeviceState *lan9118;
42
- SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
43
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
44
Clock *sysclk;
45
Clock *s32kclk;
46
};
47
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
48
{
49
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
50
MachineClass *mc = MACHINE_GET_CLASS(mms);
51
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
52
53
- assert(irqno < MPS2TZ_NUMIRQ);
54
+ assert(irqno < mmc->numirq);
55
56
if (mc->max_cpus > 1) {
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
84
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
59
iotkitdev = DEVICE(&mms->iotkit);
85
object_property_set_link(OBJECT(&mms->iotkit), "memory",
60
object_property_set_link(OBJECT(&mms->iotkit), "memory",
86
OBJECT(system_memory), &error_abort);
61
OBJECT(system_memory), &error_abort);
87
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
62
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
88
- qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
63
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
89
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
64
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
90
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
65
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
91
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
66
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
92
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
67
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
93
index XXXXXXX..XXXXXXX 100644
68
* board. If there is only one CPU, we can just wire the device IRQ
94
--- a/hw/arm/mps2.c
69
* directly to the SSE's IRQ input.
95
+++ b/hw/arm/mps2.c
70
*/
96
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
71
+ assert(mmc->numirq <= MPS2TZ_NUMIRQ_MAX);
97
object_initialize_child(OBJECT(mms), name, &mms->timer[i],
72
if (mc->max_cpus > 1) {
98
TYPE_CMSDK_APB_TIMER);
73
- for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
99
sbd = SYS_BUS_DEVICE(&mms->timer[i]);
74
+ for (i = 0; i < mmc->numirq; i++) {
100
- qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
75
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
101
qdev_connect_clock_in(DEVICE(&mms->timer[i]), "pclk", mms->sysclk);
76
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
102
sysbus_realize_and_unref(sbd, &error_fatal);
77
103
sysbus_mmio_map(sbd, 0, base);
78
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
104
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
79
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
105
80
mmc->fpgaio_num_leds = 2;
106
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
81
mmc->fpgaio_has_switches = false;
107
TYPE_CMSDK_APB_DUALTIMER);
82
+ mmc->numirq = 92;
108
- qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
83
mmc->armsse_type = TYPE_IOTKIT;
109
qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->sysclk);
84
}
110
sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
85
111
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
86
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
112
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
87
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
113
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
88
mmc->fpgaio_num_leds = 2;
114
object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
89
mmc->fpgaio_has_switches = false;
115
TYPE_CMSDK_APB_WATCHDOG);
90
+ mmc->numirq = 92;
116
- qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
91
mmc->armsse_type = TYPE_SSE200;
117
qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->sysclk);
92
}
118
sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
119
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
120
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/musca.c
123
+++ b/hw/arm/musca.c
124
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
125
qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
126
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
127
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
128
- qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
129
qdev_connect_clock_in(ssedev, "MAINCLK", mms->sysclk);
130
qdev_connect_clock_in(ssedev, "S32KCLK", mms->s32kclk);
131
/*
132
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/stellaris.c
135
+++ b/hw/arm/stellaris.c
136
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
137
if (board->dc1 & (1 << 3)) { /* watchdog present */
138
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
139
140
- /* system_clock_scale is valid now */
141
- uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
142
- qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
143
qdev_connect_clock_in(dev, "WDOGCLK",
144
qdev_get_clock_out(ssys_dev, "SYSCLK"));
145
93
146
--
94
--
147
2.20.1
95
2.20.1
148
96
149
97
diff view generated by jsdifflib
1
Add a function for checking whether a clock has a source. This is
1
The AN524 version of the SCC interface has different behaviour for
2
useful for devices which have input clocks that must be wired up by
2
some of the CFG registers; implement it.
3
the board as it allows them to fail in realize rather than ploughing
3
4
on with a zero-period clock.
4
Each board in this family can have minor differences in the meaning
5
of the CFG registers, so rather than trying to specify all the
6
possible semantics via individual device properties, we make the
7
behaviour conditional on the part-number field of the SCC_ID register
8
which the board code already passes us.
9
10
For the AN524, the differences are:
11
* CFG3 is reserved rather than being board switches
12
* CFG5 is a new register ("ACLK Frequency in Hz")
13
* CFG6 is a new register ("Clock divider for BRAM")
14
15
We implement both of the new registers as reads-as-written.
5
16
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20210215115138.20465-11-peter.maydell@linaro.org
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210128114145.20536-3-peter.maydell@linaro.org
11
Message-id: 20210121190622.22000-3-peter.maydell@linaro.org
12
---
20
---
13
docs/devel/clocks.rst | 16 ++++++++++++++++
21
include/hw/misc/mps2-scc.h | 3 ++
14
include/hw/clock.h | 15 +++++++++++++++
22
hw/misc/mps2-scc.c | 71 ++++++++++++++++++++++++++++++++++++--
15
2 files changed, 31 insertions(+)
23
2 files changed, 72 insertions(+), 2 deletions(-)
16
24
17
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
18
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/devel/clocks.rst
27
--- a/include/hw/misc/mps2-scc.h
20
+++ b/docs/devel/clocks.rst
28
+++ b/include/hw/misc/mps2-scc.h
21
@@ -XXX,XX +XXX,XX @@ object during device instance init. For example:
29
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
22
/* set initial value to 10ns / 100MHz */
30
23
clock_set_ns(clk, 10);
31
uint32_t cfg0;
24
32
uint32_t cfg1;
25
+To enforce that the clock is wired up by the board code, you can
33
+ uint32_t cfg2;
26
+call ``clock_has_source()`` in your device's realize method:
34
uint32_t cfg4;
27
+
35
+ uint32_t cfg5;
28
+.. code-block:: c
36
+ uint32_t cfg6;
29
+
37
uint32_t cfgdata_rtn;
30
+ if (!clock_has_source(s->clk)) {
38
uint32_t cfgdata_out;
31
+ error_setg(errp, "MyDevice: clk input must be connected");
39
uint32_t cfgctrl;
32
+ return;
40
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
33
+ }
34
+
35
+Note that this only checks that the clock has been wired up; it is
36
+still possible that the output clock connected to it is disabled
37
+or has not yet been configured, in which case the period will be
38
+zero. You should use the clock callback to find out when the clock
39
+period changes.
40
+
41
Fetching clock frequency/period
42
-------------------------------
43
44
diff --git a/include/hw/clock.h b/include/hw/clock.h
45
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/clock.h
42
--- a/hw/misc/mps2-scc.c
47
+++ b/include/hw/clock.h
43
+++ b/hw/misc/mps2-scc.c
48
@@ -XXX,XX +XXX,XX @@ void clock_clear_callback(Clock *clk);
44
@@ -XXX,XX +XXX,XX @@
49
*/
45
50
void clock_set_source(Clock *clk, Clock *src);
46
REG32(CFG0, 0)
51
47
REG32(CFG1, 4)
52
+/**
48
+REG32(CFG2, 8)
53
+ * clock_has_source:
49
REG32(CFG3, 0xc)
54
+ * @clk: the clock
50
REG32(CFG4, 0x10)
55
+ *
51
+REG32(CFG5, 0x14)
56
+ * Returns true if the clock has a source clock connected to it.
52
+REG32(CFG6, 0x18)
57
+ * This is useful for devices which have input clocks which must
53
REG32(CFGDATA_RTN, 0xa0)
58
+ * be connected by the board/SoC code which creates them. The
54
REG32(CFGDATA_OUT, 0xa4)
59
+ * device code can use this to check in its realize method that
55
REG32(CFGCTRL, 0xa8)
60
+ * the clock has been connected.
56
@@ -XXX,XX +XXX,XX @@ REG32(DLL, 0x100)
61
+ */
57
REG32(AID, 0xFF8)
62
+static inline bool clock_has_source(const Clock *clk)
58
REG32(ID, 0xFFC)
59
60
+static int scc_partno(MPS2SCC *s)
63
+{
61
+{
64
+ return clk->source != NULL;
62
+ /* Return the partno field of the SCC_ID (0x524, 0x511, etc) */
63
+ return extract32(s->id, 4, 8);
65
+}
64
+}
66
+
65
+
67
/**
66
/* Handle a write via the SYS_CFG channel to the specified function/device.
68
* clock_set:
67
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
69
* @clk: the clock to initialize.
68
*/
69
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
70
case A_CFG1:
71
r = s->cfg1;
72
break;
73
+ case A_CFG2:
74
+ if (scc_partno(s) != 0x524) {
75
+ /* CFG2 reserved on other boards */
76
+ goto bad_offset;
77
+ }
78
+ r = s->cfg2;
79
+ break;
80
case A_CFG3:
81
+ if (scc_partno(s) == 0x524) {
82
+ /* CFG3 reserved on AN524 */
83
+ goto bad_offset;
84
+ }
85
/* These are user-settable DIP switches on the board. We don't
86
* model that, so just return zeroes.
87
*/
88
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
89
case A_CFG4:
90
r = s->cfg4;
91
break;
92
+ case A_CFG5:
93
+ if (scc_partno(s) != 0x524) {
94
+ /* CFG5 reserved on other boards */
95
+ goto bad_offset;
96
+ }
97
+ r = s->cfg5;
98
+ break;
99
+ case A_CFG6:
100
+ if (scc_partno(s) != 0x524) {
101
+ /* CFG6 reserved on other boards */
102
+ goto bad_offset;
103
+ }
104
+ r = s->cfg6;
105
+ break;
106
case A_CFGDATA_RTN:
107
r = s->cfgdata_rtn;
108
break;
109
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
110
r = s->id;
111
break;
112
default:
113
+ bad_offset:
114
qemu_log_mask(LOG_GUEST_ERROR,
115
"MPS2 SCC read: bad offset %x\n", (int) offset);
116
r = 0;
117
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
118
led_set_state(s->led[i], extract32(value, i, 1));
119
}
120
break;
121
+ case A_CFG2:
122
+ if (scc_partno(s) != 0x524) {
123
+ /* CFG2 reserved on other boards */
124
+ goto bad_offset;
125
+ }
126
+ /* AN524: QSPI Select signal */
127
+ s->cfg2 = value;
128
+ break;
129
+ case A_CFG5:
130
+ if (scc_partno(s) != 0x524) {
131
+ /* CFG5 reserved on other boards */
132
+ goto bad_offset;
133
+ }
134
+ /* AN524: ACLK frequency in Hz */
135
+ s->cfg5 = value;
136
+ break;
137
+ case A_CFG6:
138
+ if (scc_partno(s) != 0x524) {
139
+ /* CFG6 reserved on other boards */
140
+ goto bad_offset;
141
+ }
142
+ /* AN524: Clock divider for BRAM */
143
+ s->cfg6 = value;
144
+ break;
145
case A_CFGDATA_OUT:
146
s->cfgdata_out = value;
147
break;
148
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
149
s->dll = deposit32(s->dll, 24, 8, extract32(value, 24, 8));
150
break;
151
default:
152
+ bad_offset:
153
qemu_log_mask(LOG_GUEST_ERROR,
154
"MPS2 SCC write: bad offset 0x%x\n", (int) offset);
155
break;
156
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
157
trace_mps2_scc_reset();
158
s->cfg0 = 0;
159
s->cfg1 = 0;
160
+ s->cfg2 = 0;
161
+ s->cfg5 = 0;
162
+ s->cfg6 = 0;
163
s->cfgdata_rtn = 0;
164
s->cfgdata_out = 0;
165
s->cfgctrl = 0x100000;
166
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
167
168
static const VMStateDescription mps2_scc_vmstate = {
169
.name = "mps2-scc",
170
- .version_id = 2,
171
- .minimum_version_id = 2,
172
+ .version_id = 3,
173
+ .minimum_version_id = 3,
174
.fields = (VMStateField[]) {
175
VMSTATE_UINT32(cfg0, MPS2SCC),
176
VMSTATE_UINT32(cfg1, MPS2SCC),
177
+ VMSTATE_UINT32(cfg2, MPS2SCC),
178
+ /* cfg3, cfg4 are read-only so need not be migrated */
179
+ VMSTATE_UINT32(cfg5, MPS2SCC),
180
+ VMSTATE_UINT32(cfg6, MPS2SCC),
181
VMSTATE_UINT32(cfgdata_rtn, MPS2SCC),
182
VMSTATE_UINT32(cfgdata_out, MPS2SCC),
183
VMSTATE_UINT32(cfgctrl, MPS2SCC),
70
--
184
--
71
2.20.1
185
2.20.1
72
186
73
187
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
On the MPS2 boards, the first 32 interrupt lines are entirely
2
internal to the SSE; interrupt lines for devices outside the SSE
3
start at 32. In the application notes that document each FPGA image,
4
the interrupt wiring is documented from the point of view of the CPU,
5
so '0' is the first of the SSE's interrupts and the devices in the
6
FPGA image itself are '32' and up: so the UART 0 Receive interrupt is
7
32, the SPI #0 interrupt is 51, and so on.
2
8
3
The properties to attach a CANBUS object to the xlnx-zcu102 machine have
9
Within our implementation, because the external interrupts must be
4
a period in them. We want to use periods in properties for compound QAPI types,
10
connected to the EXP_IRQ[0...n] lines of the SSE object, we made the
5
and besides the "xlnx-zcu102." prefix is both unnecessary and different
11
get_sse_irq_in() function take an irqno whose values start at 0 for
6
from any other machine property name. Remove it.
12
the first FPGA device interrupt. In this numbering scheme the UART 0
13
Receive interrupt is 0, the SPI #0 interrupt is 19, and so on.
7
14
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
15
The result of these two different numbering schemes has been that
9
Message-id: 20210118162537.779542-1-pbonzini@redhat.com
16
half of the devices were wired up to the wrong IRQs: the UART IRQs
10
Reviewed-by: Vikram Garhwal <fnu.vikram@xilinx.com>
17
are wired up correctly, but the DMA and SPI devices were passing
18
start-at-32 values to get_sse_irq_in() and so being mis-connected.
19
20
Fix the bug by making get_sse_irq_in() take values specified with the
21
same scheme that the hardware manuals use, to avoid confusion.
22
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20210215115138.20465-12-peter.maydell@linaro.org
12
---
26
---
13
hw/arm/xlnx-zcu102.c | 4 ++--
27
hw/arm/mps2-tz.c | 24 +++++++++++++++++-------
14
tests/qtest/xlnx-can-test.c | 30 +++++++++++++++---------------
28
1 file changed, 17 insertions(+), 7 deletions(-)
15
2 files changed, 17 insertions(+), 17 deletions(-)
16
29
17
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
30
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/xlnx-zcu102.c
32
--- a/hw/arm/mps2-tz.c
20
+++ b/hw/arm/xlnx-zcu102.c
33
+++ b/hw/arm/mps2-tz.c
21
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
34
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
22
s->secure = false;
35
23
/* Default to virt (EL2) being disabled */
36
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
24
s->virt = false;
37
{
25
- object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
38
- /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
26
+ object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
39
+ /*
27
(Object **)&s->canbus[0],
40
+ * Return a qemu_irq which will signal IRQ n to all CPUs in the
28
object_property_allow_set_link,
41
+ * SSE. The irqno should be as the CPU sees it, so the first
29
0);
42
+ * external-to-the-SSE interrupt is 32.
30
43
+ */
31
- object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
44
MachineClass *mc = MACHINE_GET_CLASS(mms);
32
+ object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
45
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
33
(Object **)&s->canbus[1],
46
34
object_property_allow_set_link,
47
- assert(irqno < mmc->numirq);
35
0);
48
+ assert(irqno >= 32 && irqno < (mmc->numirq + 32));
36
diff --git a/tests/qtest/xlnx-can-test.c b/tests/qtest/xlnx-can-test.c
49
+
37
index XXXXXXX..XXXXXXX 100644
50
+ /*
38
--- a/tests/qtest/xlnx-can-test.c
51
+ * Convert from "CPU irq number" (as listed in the FPGA image
39
+++ b/tests/qtest/xlnx-can-test.c
52
+ * documentation) to the SSE external-interrupt number.
40
@@ -XXX,XX +XXX,XX @@ static void test_can_bus(void)
53
+ */
41
uint8_t can_timestamp = 1;
54
+ irqno -= 32;
42
55
43
QTestState *qts = qtest_init("-machine xlnx-zcu102"
56
if (mc->max_cpus > 1) {
44
- " -object can-bus,id=canbus0"
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
45
- " -machine xlnx-zcu102.canbus0=canbus0"
58
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
46
- " -machine xlnx-zcu102.canbus1=canbus0"
59
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
47
+ " -object can-bus,id=canbus"
60
CMSDKAPBUART *uart = opaque;
48
+ " -machine canbus0=canbus"
61
int i = uart - &mms->uart[0];
49
+ " -machine canbus1=canbus"
62
- int rxirqno = i * 2;
50
);
63
- int txirqno = i * 2 + 1;
51
64
- int combirqno = i + 10;
52
/* Configure the CAN0 and CAN1. */
65
+ int rxirqno = i * 2 + 32;
53
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
66
+ int txirqno = i * 2 + 33;
54
uint32_t status = 0;
67
+ int combirqno = i + 42;
55
68
SysBusDevice *s;
56
QTestState *qts = qtest_init("-machine xlnx-zcu102"
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
57
- " -object can-bus,id=canbus0"
70
58
- " -machine xlnx-zcu102.canbus0=canbus0"
71
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
59
- " -machine xlnx-zcu102.canbus1=canbus0"
72
60
+ " -object can-bus,id=canbus"
73
s = SYS_BUS_DEVICE(mms->lan9118);
61
+ " -machine canbus0=canbus"
74
sysbus_realize_and_unref(s, &error_fatal);
62
+ " -machine canbus1=canbus"
75
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
63
);
76
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
64
77
return sysbus_mmio_get_region(s, 0);
65
/* Configure the CAN0 in loopback mode. */
78
}
66
@@ -XXX,XX +XXX,XX @@ static void test_can_filter(void)
79
67
uint8_t can_timestamp = 1;
80
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
68
81
&error_fatal);
69
QTestState *qts = qtest_init("-machine xlnx-zcu102"
82
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
70
- " -object can-bus,id=canbus0"
83
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
71
- " -machine xlnx-zcu102.canbus0=canbus0"
84
- get_sse_irq_in(mms, 15));
72
- " -machine xlnx-zcu102.canbus1=canbus0"
85
+ get_sse_irq_in(mms, 47));
73
+ " -object can-bus,id=canbus"
86
74
+ " -machine canbus0=canbus"
87
/* Most of the devices in the FPGA are behind Peripheral Protection
75
+ " -machine canbus1=canbus"
88
* Controllers. The required order for initializing things is:
76
);
77
78
/* Configure the CAN0 and CAN1. */
79
@@ -XXX,XX +XXX,XX @@ static void test_can_sleepmode(void)
80
uint8_t can_timestamp = 1;
81
82
QTestState *qts = qtest_init("-machine xlnx-zcu102"
83
- " -object can-bus,id=canbus0"
84
- " -machine xlnx-zcu102.canbus0=canbus0"
85
- " -machine xlnx-zcu102.canbus1=canbus0"
86
+ " -object can-bus,id=canbus"
87
+ " -machine canbus0=canbus"
88
+ " -machine canbus1=canbus"
89
);
90
91
/* Configure the CAN0. */
92
@@ -XXX,XX +XXX,XX @@ static void test_can_snoopmode(void)
93
uint8_t can_timestamp = 1;
94
95
QTestState *qts = qtest_init("-machine xlnx-zcu102"
96
- " -object can-bus,id=canbus0"
97
- " -machine xlnx-zcu102.canbus0=canbus0"
98
- " -machine xlnx-zcu102.canbus1=canbus0"
99
+ " -object can-bus,id=canbus"
100
+ " -machine canbus0=canbus"
101
+ " -machine canbus1=canbus"
102
);
103
104
/* Configure the CAN0. */
105
--
89
--
106
2.20.1
90
2.20.1
107
91
108
92
diff view generated by jsdifflib
1
Create and connect the Clock input for the watchdog device on the
1
The mps2-tz code uses PPCPortInfo data structures to define what
2
Stellaris boards. Because the Stellaris boards model the ability to
2
devices are present and how they are wired up. Currently we use
3
change the clock rate by programming PLL registers, we have to create
3
these to specify device types and addresses, but hard-code the
4
an output Clock on the ssys_state device and wire it up to the
4
interrupt line wiring in each make_* helper function. This works for
5
watchdog.
5
the two boards we have at the moment, but the AN524 has some devices
6
with different interrupt assignments.
6
7
7
Note that the old comment on ssys_calculate_system_clock() got the
8
This commit adds the framework to allow PPCPortInfo structures to
8
units wrong -- system_clock_scale is in nanoseconds, not
9
specify interrupt numbers. We add an array of interrupt numbers to
9
milliseconds. Improve the commentary to clarify how we are
10
the PPCPortInfo struct, and pass it through to the make_* helpers.
10
calculating the period.
11
The following commit will change the make_* helpers over to using the
12
framework.
11
13
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20210215115138.20465-13-peter.maydell@linaro.org
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20210128114145.20536-18-peter.maydell@linaro.org
17
Message-id: 20210121190622.22000-18-peter.maydell@linaro.org
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
---
17
---
20
hw/arm/stellaris.c | 43 +++++++++++++++++++++++++++++++------------
18
hw/arm/mps2-tz.c | 36 ++++++++++++++++++++++++------------
21
1 file changed, 31 insertions(+), 12 deletions(-)
19
1 file changed, 24 insertions(+), 12 deletions(-)
22
20
23
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/stellaris.c
23
--- a/hw/arm/mps2-tz.c
26
+++ b/hw/arm/stellaris.c
24
+++ b/hw/arm/mps2-tz.c
27
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
28
#include "hw/watchdog/cmsdk-apb-watchdog.h"
26
* needs to be plugged into the downstream end of the PPC port.
29
#include "migration/vmstate.h"
27
*/
30
#include "hw/misc/unimp.h"
28
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
31
+#include "hw/qdev-clock.h"
29
- const char *name, hwaddr size);
32
#include "cpu.h"
30
+ const char *name, hwaddr size,
33
#include "qom/object.h"
31
+ const int *irqs);
34
32
35
@@ -XXX,XX +XXX,XX @@ struct ssys_state {
33
typedef struct PPCPortInfo {
36
uint32_t clkvclr;
34
const char *name;
37
uint32_t ldoarst;
35
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
38
qemu_irq irq;
36
void *opaque;
39
+ Clock *sysclk;
37
hwaddr addr;
40
/* Properties (all read-only registers) */
38
hwaddr size;
41
uint32_t user0;
39
+ int irqs[3]; /* currently no device needs more IRQ lines than this */
42
uint32_t user1;
40
} PPCPortInfo;
43
@@ -XXX,XX +XXX,XX @@ static bool ssys_use_rcc2(ssys_state *s)
41
42
typedef struct PPCInfo {
43
@@ -XXX,XX +XXX,XX @@ typedef struct PPCInfo {
44
} PPCInfo;
45
46
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
47
- void *opaque,
48
- const char *name, hwaddr size)
49
+ void *opaque,
50
+ const char *name, hwaddr size,
51
+ const int *irqs)
52
{
53
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
54
* and return a pointer to its MemoryRegion.
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
44
}
56
}
45
57
46
/*
58
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
47
- * Caculate the sys. clock period in ms.
59
- const char *name, hwaddr size)
48
+ * Calculate the system clock period. We only want to propagate
60
+ const char *name, hwaddr size,
49
+ * this change to the rest of the system if we're not being called
61
+ const int *irqs)
50
+ * from migration post-load.
51
*/
52
-static void ssys_calculate_system_clock(ssys_state *s)
53
+static void ssys_calculate_system_clock(ssys_state *s, bool propagate_clock)
54
{
62
{
55
+ /*
63
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
56
+ * SYSDIV field specifies divisor: 0 == /1, 1 == /2, etc. Input
64
CMSDKAPBUART *uart = opaque;
57
+ * clock is 200MHz, which is a period of 5 ns. Dividing the clock
65
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
58
+ * frequency by X is the same as multiplying the period by X.
59
+ */
60
if (ssys_use_rcc2(s)) {
61
system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
62
} else {
63
system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
64
}
65
+ clock_set_ns(s->sysclk, system_clock_scale);
66
+ if (propagate_clock) {
67
+ clock_propagate(s->sysclk);
68
+ }
69
}
66
}
70
67
71
static void ssys_write(void *opaque, hwaddr offset,
68
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
72
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
69
- const char *name, hwaddr size)
73
s->int_status |= (1 << 6);
70
+ const char *name, hwaddr size,
74
}
71
+ const int *irqs)
75
s->rcc = value;
76
- ssys_calculate_system_clock(s);
77
+ ssys_calculate_system_clock(s, true);
78
break;
79
case 0x070: /* RCC2 */
80
if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
81
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
82
s->int_status |= (1 << 6);
83
}
84
s->rcc2 = value;
85
- ssys_calculate_system_clock(s);
86
+ ssys_calculate_system_clock(s, true);
87
break;
88
case 0x100: /* RCGC0 */
89
s->rcgc[0] = value;
90
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_reset_hold(Object *obj)
91
{
72
{
92
ssys_state *s = STELLARIS_SYS(obj);
73
MPS2SCC *scc = opaque;
93
74
DeviceState *sccdev;
94
- ssys_calculate_system_clock(s);
75
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
95
+ /* OK to propagate clocks from the hold phase */
96
+ ssys_calculate_system_clock(s, true);
97
}
76
}
98
77
99
static void stellaris_sys_reset_exit(Object *obj)
78
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
100
@@ -XXX,XX +XXX,XX @@ static int stellaris_sys_post_load(void *opaque, int version_id)
79
- const char *name, hwaddr size)
80
+ const char *name, hwaddr size,
81
+ const int *irqs)
101
{
82
{
102
ssys_state *s = opaque;
83
MPS2FPGAIO *fpgaio = opaque;
103
84
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
104
- ssys_calculate_system_clock(s);
85
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
105
+ ssys_calculate_system_clock(s, false);
106
107
return 0;
108
}
86
}
109
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_sys = {
87
110
VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
88
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
111
VMSTATE_UINT32(clkvclr, ssys_state),
89
- const char *name, hwaddr size)
112
VMSTATE_UINT32(ldoarst, ssys_state),
90
+ const char *name, hwaddr size,
113
+ /* No field for sysclk -- handled in post-load instead */
91
+ const int *irqs)
114
VMSTATE_END_OF_LIST()
92
{
115
}
93
SysBusDevice *s;
116
};
94
NICInfo *nd = &nd_table[0];
117
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
95
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
118
memory_region_init_io(&s->iomem, obj, &ssys_ops, s, "ssys", 0x00001000);
119
sysbus_init_mmio(sbd, &s->iomem);
120
sysbus_init_irq(sbd, &s->irq);
121
+ s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
122
}
96
}
123
97
124
-static int stellaris_sys_init(uint32_t base, qemu_irq irq,
98
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
125
- stellaris_board_info * board,
99
- const char *name, hwaddr size)
126
- uint8_t *macaddr)
100
+ const char *name, hwaddr size,
127
+static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
101
+ const int *irqs)
128
+ stellaris_board_info *board,
129
+ uint8_t *macaddr)
130
{
102
{
131
DeviceState *dev = qdev_new(TYPE_STELLARIS_SYS);
103
TZMPC *mpc = opaque;
132
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
104
int i = mpc - &mms->ssram_mpc[0];
133
@@ -XXX,XX +XXX,XX @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
105
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
134
*/
135
device_cold_reset(dev);
136
137
- return 0;
138
+ return dev;
139
}
106
}
140
107
141
/* I2C controller. */
108
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
142
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
109
- const char *name, hwaddr size)
143
int flash_size;
110
+ const char *name, hwaddr size,
144
I2CBus *i2c;
111
+ const int *irqs)
145
DeviceState *dev;
112
{
146
+ DeviceState *ssys_dev;
113
PL080State *dma = opaque;
147
int i;
114
int i = dma - &mms->dma[0];
148
int j;
115
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
149
116
}
150
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
117
151
}
118
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
152
}
119
- const char *name, hwaddr size)
153
120
+ const char *name, hwaddr size,
154
- stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
121
+ const int *irqs)
155
- board, nd_table[0].macaddr.a);
122
{
156
+ ssys_dev = stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
123
/*
157
+ board, nd_table[0].macaddr.a);
124
* The AN505 has five PL022 SPI controllers.
158
125
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
159
126
}
160
if (board->dc1 & (1 << 3)) { /* watchdog present */
127
161
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
128
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
162
/* system_clock_scale is valid now */
129
- const char *name, hwaddr size)
163
uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
130
+ const char *name, hwaddr size,
164
qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
131
+ const int *irqs)
165
+ qdev_connect_clock_in(dev, "WDOGCLK",
132
{
166
+ qdev_get_clock_out(ssys_dev, "SYSCLK"));
133
ArmSbconI2CState *i2c = opaque;
167
134
SysBusDevice *s;
168
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
135
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
169
sysbus_mmio_map(SYS_BUS_DEVICE(dev),
136
continue;
137
}
138
139
- mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size);
140
+ mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size,
141
+ pinfo->irqs);
142
portname = g_strdup_printf("port[%d]", port);
143
object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
144
&error_fatal);
170
--
145
--
171
2.20.1
146
2.20.1
172
147
173
148
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
Move the specification of the IRQ information for the uart, ethernet,
2
dma and spi devices to the data structures. (The other devices
3
handled by the PPCPortInfo structures don't have any interrupt lines
4
we need to wire up.)
2
5
3
No functional change. Just refactor code to better
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
support secure and normal world gpios.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-14-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 52 +++++++++++++++++++++++-------------------------
11
1 file changed, 25 insertions(+), 27 deletions(-)
5
12
6
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
7
Reviewed-by: Andrew Jones <drjones@redhat.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/virt.c | 57 ++++++++++++++++++++++++++++++++-------------------
11
1 file changed, 36 insertions(+), 21 deletions(-)
12
13
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/virt.c
15
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/arm/virt.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
17
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
18
}
18
const char *name, hwaddr size,
19
const int *irqs)
20
{
21
+ /* The irq[] array is tx, rx, combined, in that order */
22
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
23
CMSDKAPBUART *uart = opaque;
24
int i = uart - &mms->uart[0];
25
- int rxirqno = i * 2 + 32;
26
- int txirqno = i * 2 + 33;
27
- int combirqno = i + 42;
28
SysBusDevice *s;
29
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
30
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
32
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
33
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
34
s = SYS_BUS_DEVICE(uart);
35
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
36
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
37
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
38
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
39
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
40
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
41
- sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
42
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
43
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
19
}
44
}
20
45
21
-static void create_gpio(const VirtMachineState *vms)
46
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
22
+static void create_gpio_keys(const VirtMachineState *vms,
47
23
+ DeviceState *pl061_dev,
48
s = SYS_BUS_DEVICE(mms->lan9118);
24
+ uint32_t phandle)
49
sysbus_realize_and_unref(s, &error_fatal);
25
+{
50
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
26
+ gpio_key_dev = sysbus_create_simple("gpio-key", -1,
51
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
27
+ qdev_get_gpio_in(pl061_dev, 3));
52
return sysbus_mmio_get_region(s, 0);
28
+
53
}
29
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-keys");
54
30
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys");
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
31
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0);
56
const char *name, hwaddr size,
32
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1);
57
const int *irqs)
33
+
34
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
35
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
36
+ "label", "GPIO Key Poweroff");
37
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
38
+ KEY_POWER);
39
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
40
+ "gpios", phandle, 3, 0);
41
+}
42
+
43
+static void create_gpio_devices(const VirtMachineState *vms, int gpio,
44
+ MemoryRegion *mem)
45
{
58
{
46
char *nodename;
59
+ /* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
47
DeviceState *pl061_dev;
60
PL080State *dma = opaque;
48
- hwaddr base = vms->memmap[VIRT_GPIO].base;
61
int i = dma - &mms->dma[0];
49
- hwaddr size = vms->memmap[VIRT_GPIO].size;
62
SysBusDevice *s;
50
- int irq = vms->irqmap[VIRT_GPIO];
63
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
51
+ hwaddr base = vms->memmap[gpio].base;
64
52
+ hwaddr size = vms->memmap[gpio].size;
65
s = SYS_BUS_DEVICE(dma);
53
+ int irq = vms->irqmap[gpio];
66
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
54
const char compat[] = "arm,pl061\0arm,primecell";
67
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
55
+ SysBusDevice *s;
68
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
56
69
- sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
57
- pl061_dev = sysbus_create_simple("pl061", base,
70
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
58
- qdev_get_gpio_in(vms->gic, irq));
71
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
59
+ pl061_dev = qdev_new("pl061");
72
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, irqs[2]));
60
+ s = SYS_BUS_DEVICE(pl061_dev);
73
61
+ sysbus_realize_and_unref(s, &error_fatal);
74
g_free(mscname);
62
+ memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
75
return sysbus_mmio_get_region(s, 0);
63
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
76
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
64
77
* lines are set via the "MISC" register in the MPS2 FPGAIO device.
65
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
78
*/
66
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
79
PL022State *spi = opaque;
67
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms)
80
- int i = spi - &mms->spi[0];
68
qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk");
81
SysBusDevice *s;
69
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
82
70
83
object_initialize_child(OBJECT(mms), name, spi, TYPE_PL022);
71
- gpio_key_dev = sysbus_create_simple("gpio-key", -1,
84
sysbus_realize(SYS_BUS_DEVICE(spi), &error_fatal);
72
- qdev_get_gpio_in(pl061_dev, 3));
85
s = SYS_BUS_DEVICE(spi);
73
- qemu_fdt_add_subnode(vms->fdt, "/gpio-keys");
86
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
74
- qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys");
87
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
75
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0);
88
return sysbus_mmio_get_region(s, 0);
76
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1);
77
-
78
- qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
79
- qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
80
- "label", "GPIO Key Poweroff");
81
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
82
- KEY_POWER);
83
- qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
84
- "gpios", phandle, 3, 0);
85
g_free(nodename);
86
+
87
+ /* Child gpio devices */
88
+ create_gpio_keys(vms, pl061_dev, phandle);
89
}
89
}
90
90
91
static void create_virtio_devices(const VirtMachineState *vms)
91
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
92
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
92
}, {
93
if (has_ged && aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) {
93
.name = "apb_ppcexp1",
94
vms->acpi_dev = create_acpi_ged(vms);
94
.ports = {
95
} else {
95
- { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
96
- create_gpio(vms);
96
- { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
97
+ create_gpio_devices(vms, VIRT_GPIO, sysmem);
97
- { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
98
}
98
- { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
99
99
- { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
100
/* connect powerdown request */
100
- { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
101
- { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
102
- { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
103
- { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
104
- { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
105
+ { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000, { 51 } },
106
+ { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000, { 52 } },
107
+ { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000, { 53 } },
108
+ { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000, { 54 } },
109
+ { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000, { 55 } },
110
+ { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000, { 32, 33, 42 } },
111
+ { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000, { 34, 35, 43 } },
112
+ { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
113
+ { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
114
+ { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
115
{ "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
116
{ "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
117
{ "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
118
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
119
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
120
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
121
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
122
- { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
123
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000, { 48 } },
124
},
125
}, {
126
.name = "ahb_ppcexp1",
127
.ports = {
128
- { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
129
- { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
130
- { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
131
- { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
132
+ { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000, { 58, 56, 57 } },
133
+ { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000, { 61, 59, 60 } },
134
+ { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000, { 64, 62, 63 } },
135
+ { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000, { 67, 65, 66 } },
136
},
137
},
138
};
101
--
139
--
102
2.20.1
140
2.20.1
103
141
104
142
diff view generated by jsdifflib
1
Move the preadv availability check to meson.build. This is what we
1
We create an OR gate to wire together the overflow IRQs for all the
2
want to be doing for host-OS-feature-checks anyway, but it also fixes
2
UARTs on the board; this has to have twice the number of inputs as
3
a problem with building for macOS with the most recent XCode SDK on a
3
there are UARTs, since each UART feeds it a TX overflow and an RX
4
Catalina host.
4
overflow interrupt line. Replace the hardcoded '10' with a
5
5
calculation based on the size of the uart[] array in the
6
On that configuration, 'preadv()' is provided as a weak symbol, so
6
MPS2TZMachineState. (We rely on OR gate inputs that are never wired
7
that programs can be built with optional support for it and make a
7
up or asserted being treated as always-zero.)
8
runtime availability check to see whether the preadv() they have is a
9
working one or one which they must not call because it will
10
runtime-assert. QEMU's configure test passes (unless you're building
11
with --enable-werror) because the test program using preadv()
12
compiles, but then QEMU crashes at runtime when preadv() is called,
13
with errors like:
14
15
dyld: lazy symbol binding failed: Symbol not found: _preadv
16
Referenced from: /Users/pm215/src/qemu/./build/x86/tests/test-replication
17
Expected in: /usr/lib/libSystem.B.dylib
18
19
dyld: Symbol not found: _preadv
20
Referenced from: /Users/pm215/src/qemu/./build/x86/tests/test-replication
21
Expected in: /usr/lib/libSystem.B.dylib
22
23
Meson's own function availability check has a special case for macOS
24
which adds '-Wl,-no_weak_imports' to the compiler flags, which forces
25
the test to require the real function, not the macOS-version-too-old
26
stub.
27
28
So this commit fixes the bug where macOS builds on Catalina currently
29
require --disable-werror.
30
8
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20210215115138.20465-15-peter.maydell@linaro.org
34
Message-id: 20210126155846.17109-1-peter.maydell@linaro.org
35
---
12
---
36
configure | 16 ----------------
13
hw/arm/mps2-tz.c | 11 ++++++++---
37
meson.build | 4 +++-
14
1 file changed, 8 insertions(+), 3 deletions(-)
38
2 files changed, 3 insertions(+), 17 deletions(-)
39
15
40
diff --git a/configure b/configure
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
41
index XXXXXXX..XXXXXXX 100755
42
--- a/configure
43
+++ b/configure
44
@@ -XXX,XX +XXX,XX @@ if compile_prog "" "" ; then
45
iovec=yes
46
fi
47
48
-##########################################
49
-# preadv probe
50
-cat > $TMPC <<EOF
51
-#include <sys/types.h>
52
-#include <sys/uio.h>
53
-#include <unistd.h>
54
-int main(void) { return preadv(0, 0, 0, 0); }
55
-EOF
56
-preadv=no
57
-if compile_prog "" "" ; then
58
- preadv=yes
59
-fi
60
-
61
##########################################
62
# fdt probe
63
64
@@ -XXX,XX +XXX,XX @@ fi
65
if test "$iovec" = "yes" ; then
66
echo "CONFIG_IOVEC=y" >> $config_host_mak
67
fi
68
-if test "$preadv" = "yes" ; then
69
- echo "CONFIG_PREADV=y" >> $config_host_mak
70
-fi
71
if test "$membarrier" = "yes" ; then
72
echo "CONFIG_MEMBARRIER=y" >> $config_host_mak
73
fi
74
diff --git a/meson.build b/meson.build
75
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
76
--- a/meson.build
18
--- a/hw/arm/mps2-tz.c
77
+++ b/meson.build
19
+++ b/hw/arm/mps2-tz.c
78
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
20
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
79
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
21
*/
80
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
22
memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
81
23
82
+config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
24
- /* The overflow IRQs for all UARTs are ORed together.
83
+
25
+ /*
84
ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
26
+ * The overflow IRQs for all UARTs are ORed together.
85
arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
27
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
86
strings = ['HOST_DSOSUF', 'CONFIG_IASL']
28
- * Create the OR gate for this.
87
@@ -XXX,XX +XXX,XX @@ summary_info += {'PIE': get_option('b_pie')}
29
+ * Create the OR gate for this: it has one input for the TX overflow
88
summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
30
+ * and one for the RX overflow for each UART we might have.
89
summary_info += {'malloc trim support': has_malloc_trim}
31
+ * (If the board has fewer than the maximum possible number of UARTs
90
summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
32
+ * those inputs are never wired up and are treated as always-zero.)
91
-summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
33
*/
92
+summary_info += {'preadv support': config_host_data.get('CONFIG_PREADV')}
34
object_initialize_child(OBJECT(mms), "uart-irq-orgate",
93
summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
35
&mms->uart_irq_orgate, TYPE_OR_IRQ);
94
summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
36
- object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines", 10,
95
summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
37
+ object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines",
38
+ 2 * ARRAY_SIZE(mms->uart),
39
&error_fatal);
40
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
41
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
96
--
42
--
97
2.20.1
43
2.20.1
98
44
99
45
diff view generated by jsdifflib
1
Switch the CMSDK APB dualtimer device over to using its Clock input;
1
The AN505 and AN521 have the same device layout, but the AN524 is
2
the pclk-frq property is now ignored.
2
somewhat different. Allow for more than one PPCInfo array, which can
3
be selected based on the board type.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215115138.20465-16-peter.maydell@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-20-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-20-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
8
---
12
hw/timer/cmsdk-apb-dualtimer.c | 42 ++++++++++++++++++++++++++++++----
9
hw/arm/mps2-tz.c | 16 ++++++++++++++--
13
1 file changed, 37 insertions(+), 5 deletions(-)
10
1 file changed, 14 insertions(+), 2 deletions(-)
14
11
15
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/timer/cmsdk-apb-dualtimer.c
14
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/timer/cmsdk-apb-dualtimer.c
15
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s)
16
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
20
qemu_set_irq(s->timerintc, timintc);
17
MemoryRegion *system_memory = get_system_memory();
21
}
18
DeviceState *iotkitdev;
22
19
DeviceState *dev_splitter;
23
+static int cmsdk_dualtimermod_divisor(CMSDKAPBDualTimerModule *m)
20
+ const PPCInfo *ppcs;
24
+{
21
+ int num_ppcs;
25
+ /* Return the divisor set by the current CONTROL.PRESCALE value */
22
int i;
26
+ switch (FIELD_EX32(m->control, CONTROL, PRESCALE)) {
23
27
+ case 0:
24
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
28
+ return 1;
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
29
+ case 1:
26
* + wire up the PPC's control lines to the IoTKit object
30
+ return 16;
27
*/
31
+ case 2:
28
32
+ case 3: /* UNDEFINED, we treat like 2 (and complained when it was set) */
29
- const PPCInfo ppcs[] = { {
33
+ return 256;
30
+ const PPCInfo an505_ppcs[] = { {
31
.name = "apb_ppcexp0",
32
.ports = {
33
{ "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
34
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
35
},
36
};
37
38
- for (i = 0; i < ARRAY_SIZE(ppcs); i++) {
39
+ switch (mmc->fpga_type) {
40
+ case FPGA_AN505:
41
+ case FPGA_AN521:
42
+ ppcs = an505_ppcs;
43
+ num_ppcs = ARRAY_SIZE(an505_ppcs);
44
+ break;
34
+ default:
45
+ default:
35
+ g_assert_not_reached();
46
+ g_assert_not_reached();
36
+ }
47
+ }
37
+}
38
+
48
+
39
static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
49
+ for (i = 0; i < num_ppcs; i++) {
40
uint32_t newctrl)
50
const PPCInfo *ppcinfo = &ppcs[i];
41
{
51
TZPPC *ppc = &mms->ppc[i];
42
@@ -XXX,XX +XXX,XX @@ static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
52
DeviceState *ppcdev;
43
default:
44
g_assert_not_reached();
45
}
46
- ptimer_set_freq(m->timer, m->parent->pclk_frq / divisor);
47
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk, divisor);
48
}
49
50
if (changed & R_CONTROL_MODE_MASK) {
51
@@ -XXX,XX +XXX,XX @@ static void cmsdk_dualtimermod_reset(CMSDKAPBDualTimerModule *m)
52
* limit must both be set to 0xffff, so we wrap at 16 bits.
53
*/
54
ptimer_set_limit(m->timer, 0xffff, 1);
55
- ptimer_set_freq(m->timer, m->parent->pclk_frq);
56
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk,
57
+ cmsdk_dualtimermod_divisor(m));
58
ptimer_transaction_commit(m->timer);
59
}
60
61
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
62
s->timeritop = 0;
63
}
64
65
+static void cmsdk_apb_dualtimer_clk_update(void *opaque)
66
+{
67
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
68
+ int i;
69
+
70
+ for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
71
+ CMSDKAPBDualTimerModule *m = &s->timermod[i];
72
+ ptimer_transaction_begin(m->timer);
73
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk,
74
+ cmsdk_dualtimermod_divisor(m));
75
+ ptimer_transaction_commit(m->timer);
76
+ }
77
+}
78
+
79
static void cmsdk_apb_dualtimer_init(Object *obj)
80
{
81
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
82
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_init(Object *obj)
83
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
84
sysbus_init_irq(sbd, &s->timermod[i].timerint);
85
}
86
- s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK", NULL, NULL);
87
+ s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
88
+ cmsdk_apb_dualtimer_clk_update, s);
89
}
90
91
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
92
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
93
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev);
94
int i;
95
96
- if (s->pclk_frq == 0) {
97
- error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
98
+ if (!clock_has_source(s->timclk)) {
99
+ error_setg(errp, "CMSDK APB dualtimer: TIMCLK clock must be connected");
100
return;
101
}
102
103
--
53
--
104
2.20.1
54
2.20.1
105
55
106
56
diff view generated by jsdifflib
1
From: Mihai Carabas <mihai.carabas@oracle.com>
1
The AN505 and AN521 have the same layout of RAM; the AN524 does not.
2
2
Replace the current hard-coding of where the RAM is and which parts
3
Add PCI interface support for PVPANIC device. Create a new file pvpanic-pci.c
3
of it are behind which MPCs with a data-driven approach.
4
where the PCI specific routines reside and update the build system with the new
4
5
files and config structure.
6
7
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
8
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
11
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>
7
Message-id: 20210215115138.20465-17-peter.maydell@linaro.org
12
---
8
---
13
docs/specs/pci-ids.txt | 1 +
9
hw/arm/mps2-tz.c | 175 +++++++++++++++++++++++++++++++++++++----------
14
include/hw/misc/pvpanic.h | 1 +
10
1 file changed, 138 insertions(+), 37 deletions(-)
15
include/hw/pci/pci.h | 1 +
11
16
hw/misc/pvpanic-pci.c | 94 +++++++++++++++++++++++++++++++++++++++
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
hw/misc/Kconfig | 6 +++
18
hw/misc/meson.build | 1 +
19
6 files changed, 104 insertions(+)
20
create mode 100644 hw/misc/pvpanic-pci.c
21
22
diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt
23
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
24
--- a/docs/specs/pci-ids.txt
14
--- a/hw/arm/mps2-tz.c
25
+++ b/docs/specs/pci-ids.txt
15
+++ b/hw/arm/mps2-tz.c
26
@@ -XXX,XX +XXX,XX @@ PCI devices (other than virtio):
27
1b36:000d PCI xhci usb host adapter
28
1b36:000f mdpy (mdev sample device), linux/samples/vfio-mdev/mdpy.c
29
1b36:0010 PCIe NVMe device (-device nvme)
30
+1b36:0011 PCI PVPanic device (-device pvpanic-pci)
31
32
All these devices are documented in docs/specs.
33
34
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/misc/pvpanic.h
37
+++ b/include/hw/misc/pvpanic.h
38
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
39
#include "qom/object.h"
17
#include "qom/object.h"
40
18
41
#define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
19
#define MPS2TZ_NUMIRQ_MAX 92
42
+#define TYPE_PVPANIC_PCI_DEVICE "pvpanic-pci"
20
+#define MPS2TZ_RAM_MAX 4
43
21
44
#define PVPANIC_IOPORT_PROP "ioport"
22
typedef enum MPS2TZFPGAType {
45
23
FPGA_AN505,
46
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
24
FPGA_AN521,
47
index XXXXXXX..XXXXXXX 100644
25
} MPS2TZFPGAType;
48
--- a/include/hw/pci/pci.h
26
49
+++ b/include/hw/pci/pci.h
50
@@ -XXX,XX +XXX,XX @@ extern bool pci_available;
51
#define PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE 0x000e
52
#define PCI_DEVICE_ID_REDHAT_MDPY 0x000f
53
#define PCI_DEVICE_ID_REDHAT_NVME 0x0010
54
+#define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011
55
#define PCI_DEVICE_ID_REDHAT_QXL 0x0100
56
57
#define FMT_PCIBUS PRIx64
58
diff --git a/hw/misc/pvpanic-pci.c b/hw/misc/pvpanic-pci.c
59
new file mode 100644
60
index XXXXXXX..XXXXXXX
61
--- /dev/null
62
+++ b/hw/misc/pvpanic-pci.c
63
@@ -XXX,XX +XXX,XX @@
64
+/*
27
+/*
65
+ * QEMU simulated PCI pvpanic device.
28
+ * Define the layout of RAM in a board, including which parts are
66
+ *
29
+ * behind which MPCs.
67
+ * Copyright (C) 2020 Oracle
30
+ * mrindex specifies the index into mms->ram[] to use for the backing RAM;
68
+ *
31
+ * -1 means "use the system RAM".
69
+ * Authors:
70
+ * Mihai Carabas <mihai.carabas@oracle.com>
71
+ *
72
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
73
+ * See the COPYING file in the top-level directory.
74
+ *
75
+ */
32
+ */
76
+
33
+typedef struct RAMInfo {
77
+#include "qemu/osdep.h"
34
+ const char *name;
78
+#include "qemu/log.h"
35
+ uint32_t base;
79
+#include "qemu/module.h"
36
+ uint32_t size;
80
+#include "sysemu/runstate.h"
37
+ int mpc; /* MPC number, -1 for "not behind an MPC" */
81
+
38
+ int mrindex;
82
+#include "hw/nvram/fw_cfg.h"
39
+ int flags;
83
+#include "hw/qdev-properties.h"
40
+} RAMInfo;
84
+#include "migration/vmstate.h"
85
+#include "hw/misc/pvpanic.h"
86
+#include "qom/object.h"
87
+#include "hw/pci/pci.h"
88
+
89
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicPCIState, PVPANIC_PCI_DEVICE)
90
+
41
+
91
+/*
42
+/*
92
+ * PVPanicPCIState for PCI device
43
+ * Flag values:
44
+ * IS_ALIAS: this RAM area is an alias to the upstream end of the
45
+ * MPC specified by its .mpc value
93
+ */
46
+ */
94
+typedef struct PVPanicPCIState {
47
+#define IS_ALIAS 1
95
+ PCIDevice dev;
48
+
96
+ PVPanicState pvpanic;
49
struct MPS2TZMachineClass {
97
+} PVPanicPCIState;
50
MachineClass parent;
98
+
51
MPS2TZFPGAType fpga_type;
99
+static const VMStateDescription vmstate_pvpanic_pci = {
52
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
100
+ .name = "pvpanic-pci",
53
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
101
+ .version_id = 1,
54
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
102
+ .minimum_version_id = 1,
55
int numirq; /* Number of external interrupts */
103
+ .fields = (VMStateField[]) {
56
+ const RAMInfo *raminfo;
104
+ VMSTATE_PCI_DEVICE(dev, PVPanicPCIState),
57
const char *armsse_type;
105
+ VMSTATE_END_OF_LIST()
58
};
59
60
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
61
MachineState parent;
62
63
ARMSSE iotkit;
64
- MemoryRegion ssram[3];
65
- MemoryRegion ssram1_m;
66
+ MemoryRegion ram[MPS2TZ_RAM_MAX];
67
MPS2SCC scc;
68
MPS2FPGAIO fpgaio;
69
TZPPC ppc[5];
70
- TZMPC ssram_mpc[3];
71
+ TZMPC mpc[3];
72
PL022State spi[5];
73
ArmSbconI2CState i2c[4];
74
UnimplementedDeviceState i2s_audio;
75
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
76
25000000,
77
};
78
79
+static const RAMInfo an505_raminfo[] = { {
80
+ .name = "ssram-0",
81
+ .base = 0x00000000,
82
+ .size = 0x00400000,
83
+ .mpc = 0,
84
+ .mrindex = 0,
85
+ }, {
86
+ .name = "ssram-1",
87
+ .base = 0x28000000,
88
+ .size = 0x00200000,
89
+ .mpc = 1,
90
+ .mrindex = 1,
91
+ }, {
92
+ .name = "ssram-2",
93
+ .base = 0x28200000,
94
+ .size = 0x00200000,
95
+ .mpc = 2,
96
+ .mrindex = 2,
97
+ }, {
98
+ .name = "ssram-0-alias",
99
+ .base = 0x00400000,
100
+ .size = 0x00400000,
101
+ .mpc = 0,
102
+ .mrindex = 3,
103
+ .flags = IS_ALIAS,
104
+ }, {
105
+ /* Use the largest bit of contiguous RAM as our "system memory" */
106
+ .name = "mps.ram",
107
+ .base = 0x80000000,
108
+ .size = 16 * MiB,
109
+ .mpc = -1,
110
+ .mrindex = -1,
111
+ }, {
112
+ .name = NULL,
113
+ },
114
+};
115
+
116
+static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
117
+{
118
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
119
+ const RAMInfo *p;
120
+
121
+ for (p = mmc->raminfo; p->name; p++) {
122
+ if (p->mpc == mpc && !(p->flags & IS_ALIAS)) {
123
+ return p;
124
+ }
106
+ }
125
+ }
107
+};
126
+ /* if raminfo array doesn't have an entry for each MPC this is a bug */
108
+
127
+ g_assert_not_reached();
109
+static void pvpanic_pci_realizefn(PCIDevice *dev, Error **errp)
128
+}
129
+
130
+static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
131
+ const RAMInfo *raminfo)
110
+{
132
+{
111
+ PVPanicPCIState *s = PVPANIC_PCI_DEVICE(dev);
133
+ /* Return an initialized MemoryRegion for the RAMInfo. */
112
+ PVPanicState *ps = &s->pvpanic;
134
+ MemoryRegion *ram;
113
+
135
+
114
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), 2);
136
+ if (raminfo->mrindex < 0) {
115
+
137
+ /* Means this RAMInfo is for QEMU's "system memory" */
116
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &ps->mr);
138
+ MachineState *machine = MACHINE(mms);
139
+ return machine->ram;
140
+ }
141
+
142
+ assert(raminfo->mrindex < MPS2TZ_RAM_MAX);
143
+ ram = &mms->ram[raminfo->mrindex];
144
+
145
+ memory_region_init_ram(ram, NULL, raminfo->name,
146
+ raminfo->size, &error_fatal);
147
+ return ram;
117
+}
148
+}
118
+
149
+
119
+static Property pvpanic_pci_properties[] = {
150
/* Create an alias of an entire original MemoryRegion @orig
120
+ DEFINE_PROP_UINT8("events", PVPanicPCIState, pvpanic.events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
151
* located at @base in the memory map.
121
+ DEFINE_PROP_END_OF_LIST(),
152
*/
122
+};
153
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
123
+
154
const int *irqs)
124
+static void pvpanic_pci_class_init(ObjectClass *klass, void *data)
155
{
156
TZMPC *mpc = opaque;
157
- int i = mpc - &mms->ssram_mpc[0];
158
- MemoryRegion *ssram = &mms->ssram[i];
159
+ int i = mpc - &mms->mpc[0];
160
MemoryRegion *upstream;
161
- char *mpcname = g_strdup_printf("%s-mpc", name);
162
- static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
163
- static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };
164
+ const RAMInfo *raminfo = find_raminfo_for_mpc(mms, i);
165
+ MemoryRegion *ram = mr_for_raminfo(mms, raminfo);
166
167
- memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
168
-
169
- object_initialize_child(OBJECT(mms), mpcname, mpc, TYPE_TZ_MPC);
170
- object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ssram),
171
+ object_initialize_child(OBJECT(mms), name, mpc, TYPE_TZ_MPC);
172
+ object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ram),
173
&error_fatal);
174
sysbus_realize(SYS_BUS_DEVICE(mpc), &error_fatal);
175
/* Map the upstream end of the MPC into system memory */
176
upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
177
- memory_region_add_subregion(get_system_memory(), rambase[i], upstream);
178
+ memory_region_add_subregion(get_system_memory(), raminfo->base, upstream);
179
/* and connect its interrupt to the IoTKit */
180
qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
181
qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
182
"mpcexp_status", i));
183
184
- /* The first SSRAM is a special case as it has an alias; accesses to
185
- * the alias region at 0x00400000 must also go to the MPC upstream.
186
- */
187
- if (i == 0) {
188
- make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", upstream, 0x00400000);
189
- }
190
-
191
- g_free(mpcname);
192
/* Return the register interface MR for our caller to map behind the PPC */
193
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
194
}
195
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
196
return sysbus_mmio_get_region(s, 0);
197
}
198
199
+static void create_non_mpc_ram(MPS2TZMachineState *mms)
125
+{
200
+{
126
+ DeviceClass *dc = DEVICE_CLASS(klass);
201
+ /*
127
+ PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
202
+ * Handle the RAMs which are either not behind MPCs or which are
128
+
203
+ * aliases to another MPC.
129
+ device_class_set_props(dc, pvpanic_pci_properties);
204
+ */
130
+
205
+ const RAMInfo *p;
131
+ pc->realize = pvpanic_pci_realizefn;
206
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
132
+ pc->vendor_id = PCI_VENDOR_ID_REDHAT;
207
+
133
+ pc->device_id = PCI_DEVICE_ID_REDHAT_PVPANIC;
208
+ for (p = mmc->raminfo; p->name; p++) {
134
+ pc->revision = 1;
209
+ if (p->flags & IS_ALIAS) {
135
+ pc->class_id = PCI_CLASS_SYSTEM_OTHER;
210
+ SysBusDevice *mpc_sbd = SYS_BUS_DEVICE(&mms->mpc[p->mpc]);
136
+ dc->vmsd = &vmstate_pvpanic_pci;
211
+ MemoryRegion *upstream = sysbus_mmio_get_region(mpc_sbd, 1);
137
+
212
+ make_ram_alias(&mms->ram[p->mrindex], p->name, upstream, p->base);
138
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
213
+ } else if (p->mpc == -1) {
214
+ /* RAM not behind an MPC */
215
+ MemoryRegion *mr = mr_for_raminfo(mms, p);
216
+ memory_region_add_subregion(get_system_memory(), p->base, mr);
217
+ }
218
+ }
139
+}
219
+}
140
+
220
+
141
+static TypeInfo pvpanic_pci_info = {
221
static void mps2tz_common_init(MachineState *machine)
142
+ .name = TYPE_PVPANIC_PCI_DEVICE,
222
{
143
+ .parent = TYPE_PCI_DEVICE,
223
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
144
+ .instance_size = sizeof(PVPanicPCIState),
224
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
145
+ .class_init = pvpanic_pci_class_init,
225
qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0,
146
+ .interfaces = (InterfaceInfo[]) {
226
qdev_get_gpio_in(dev_splitter, 0));
147
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
227
148
+ { }
228
- /* The IoTKit sets up much of the memory layout, including
149
+ }
229
+ /*
150
+};
230
+ * The IoTKit sets up much of the memory layout, including
151
+
231
* the aliases between secure and non-secure regions in the
152
+static void pvpanic_register_types(void)
232
- * address space. The FPGA itself contains:
153
+{
233
- *
154
+ type_register_static(&pvpanic_pci_info);
234
- * 0x00000000..0x003fffff SSRAM1
155
+}
235
- * 0x00400000..0x007fffff alias of SSRAM1
156
+
236
- * 0x28000000..0x283fffff 4MB SSRAM2 + SSRAM3
157
+type_init(pvpanic_register_types);
237
- * 0x40100000..0x4fffffff AHB Master Expansion 1 interface devices
158
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
238
- * 0x80000000..0x80ffffff 16MB PSRAM
159
index XXXXXXX..XXXXXXX 100644
239
- */
160
--- a/hw/misc/Kconfig
240
-
161
+++ b/hw/misc/Kconfig
241
- /* The FPGA images have an odd combination of different RAMs,
162
@@ -XXX,XX +XXX,XX @@ config IOTKIT_SYSINFO
242
+ * address space, and also most of the devices in the system.
163
config PVPANIC_COMMON
243
+ * The FPGA itself contains various RAMs and some additional devices.
164
bool
244
+ * The FPGA images have an odd combination of different RAMs,
165
245
* because in hardware they are different implementations and
166
+config PVPANIC_PCI
246
* connected to different buses, giving varying performance/size
167
+ bool
247
* tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
168
+ default y if PCI_DEVICES
248
- * call the 16MB our "system memory", as it's the largest lump.
169
+ depends on PCI
249
+ * call the largest lump our "system memory".
170
+ select PVPANIC_COMMON
250
*/
171
+
251
- memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
172
config PVPANIC_ISA
252
173
bool
253
/*
174
depends on ISA_BUS
254
* The overflow IRQs for all UARTs are ORed together.
175
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
255
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
176
index XXXXXXX..XXXXXXX 100644
256
const PPCInfo an505_ppcs[] = { {
177
--- a/hw/misc/meson.build
257
.name = "apb_ppcexp0",
178
+++ b/hw/misc/meson.build
258
.ports = {
179
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
259
- { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
180
softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
260
- { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
181
261
- { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
182
softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
262
+ { "ssram-0-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
183
+softmmu_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
263
+ { "ssram-1-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
184
softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
264
+ { "ssram-2-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
185
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_scu.c', 'aspeed_sdmc.c', 'aspeed_xdma.c'))
265
},
186
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
266
}, {
267
.name = "apb_ppcexp1",
268
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
269
270
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
271
272
+ create_non_mpc_ram(mms);
273
+
274
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
275
}
276
277
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
278
mmc->fpgaio_num_leds = 2;
279
mmc->fpgaio_has_switches = false;
280
mmc->numirq = 92;
281
+ mmc->raminfo = an505_raminfo;
282
mmc->armsse_type = TYPE_IOTKIT;
283
}
284
285
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
286
mmc->fpgaio_num_leds = 2;
287
mmc->fpgaio_has_switches = false;
288
mmc->numirq = 92;
289
+ mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
290
mmc->armsse_type = TYPE_SSE200;
291
}
292
187
--
293
--
188
2.20.1
294
2.20.1
189
295
190
296
diff view generated by jsdifflib
1
Convert the SSYS code in the Stellaris boards (which encapsulates the
1
Instead of hardcoding the MachineClass default_ram_size and
2
system registers) to a proper QOM device. This will provide us with
2
default_ram_id fields, set them on class creation by finding the
3
somewhere to put the output Clock whose frequency depends on the
3
entry in the RAMInfo array which is marked as being the QEMU system
4
setting of the PLL configuration registers.
4
RAM.
5
6
This is a migration compatibility break for lm3s811evb, lm3s6965evb.
7
8
We use 3-phase reset here because the Clock will need to propagate
9
its value in the hold phase.
10
11
For the moment we reset the device during the board creation so that
12
the system_clock_scale global gets set; this will be removed in a
13
subsequent commit.
14
5
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215115138.20465-18-peter.maydell@linaro.org
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20210128114145.20536-17-peter.maydell@linaro.org
20
Message-id: 20210121190622.22000-17-peter.maydell@linaro.org
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
---
9
---
23
hw/arm/stellaris.c | 132 ++++++++++++++++++++++++++++++++++++---------
10
hw/arm/mps2-tz.c | 24 ++++++++++++++++++++++--
24
1 file changed, 107 insertions(+), 25 deletions(-)
11
1 file changed, 22 insertions(+), 2 deletions(-)
25
12
26
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/stellaris.c
15
--- a/hw/arm/mps2-tz.c
29
+++ b/hw/arm/stellaris.c
16
+++ b/hw/arm/mps2-tz.c
30
@@ -XXX,XX +XXX,XX @@ static void stellaris_gptm_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
31
18
32
/* System controller. */
19
mc->init = mps2tz_common_init;
33
20
iic->check = mps2_tz_idau_check;
34
-typedef struct {
21
- mc->default_ram_size = 16 * MiB;
35
+#define TYPE_STELLARIS_SYS "stellaris-sys"
22
- mc->default_ram_id = "mps.ram";
36
+OBJECT_DECLARE_SIMPLE_TYPE(ssys_state, STELLARIS_SYS)
37
+
38
+struct ssys_state {
39
+ SysBusDevice parent_obj;
40
+
41
MemoryRegion iomem;
42
uint32_t pborctl;
43
uint32_t ldopctl;
44
@@ -XXX,XX +XXX,XX @@ typedef struct {
45
uint32_t dcgc[3];
46
uint32_t clkvclr;
47
uint32_t ldoarst;
48
+ qemu_irq irq;
49
+ /* Properties (all read-only registers) */
50
uint32_t user0;
51
uint32_t user1;
52
- qemu_irq irq;
53
- stellaris_board_info *board;
54
-} ssys_state;
55
+ uint32_t did0;
56
+ uint32_t did1;
57
+ uint32_t dc0;
58
+ uint32_t dc1;
59
+ uint32_t dc2;
60
+ uint32_t dc3;
61
+ uint32_t dc4;
62
+};
63
64
static void ssys_update(ssys_state *s)
65
{
66
@@ -XXX,XX +XXX,XX @@ static uint32_t pllcfg_fury[16] = {
67
68
static int ssys_board_class(const ssys_state *s)
69
{
70
- uint32_t did0 = s->board->did0;
71
+ uint32_t did0 = s->did0;
72
switch (did0 & DID0_VER_MASK) {
73
case DID0_VER_0:
74
return DID0_CLASS_SANDSTORM;
75
@@ -XXX,XX +XXX,XX @@ static uint64_t ssys_read(void *opaque, hwaddr offset,
76
77
switch (offset) {
78
case 0x000: /* DID0 */
79
- return s->board->did0;
80
+ return s->did0;
81
case 0x004: /* DID1 */
82
- return s->board->did1;
83
+ return s->did1;
84
case 0x008: /* DC0 */
85
- return s->board->dc0;
86
+ return s->dc0;
87
case 0x010: /* DC1 */
88
- return s->board->dc1;
89
+ return s->dc1;
90
case 0x014: /* DC2 */
91
- return s->board->dc2;
92
+ return s->dc2;
93
case 0x018: /* DC3 */
94
- return s->board->dc3;
95
+ return s->dc3;
96
case 0x01c: /* DC4 */
97
- return s->board->dc4;
98
+ return s->dc4;
99
case 0x030: /* PBORCTL */
100
return s->pborctl;
101
case 0x034: /* LDOPCTL */
102
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps ssys_ops = {
103
.endianness = DEVICE_NATIVE_ENDIAN,
104
};
105
106
-static void ssys_reset(void *opaque)
107
+static void stellaris_sys_reset_enter(Object *obj, ResetType type)
108
{
109
- ssys_state *s = (ssys_state *)opaque;
110
+ ssys_state *s = STELLARIS_SYS(obj);
111
112
s->pborctl = 0x7ffd;
113
s->rcc = 0x078e3ac0;
114
@@ -XXX,XX +XXX,XX @@ static void ssys_reset(void *opaque)
115
s->rcgc[0] = 1;
116
s->scgc[0] = 1;
117
s->dcgc[0] = 1;
118
+}
23
+}
119
+
24
+
120
+static void stellaris_sys_reset_hold(Object *obj)
25
+static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
121
+{
26
+{
122
+ ssys_state *s = STELLARIS_SYS(obj);
27
+ /*
28
+ * Set mc->default_ram_size and default_ram_id from the
29
+ * information in mmc->raminfo.
30
+ */
31
+ MachineClass *mc = MACHINE_CLASS(mmc);
32
+ const RAMInfo *p;
123
+
33
+
124
ssys_calculate_system_clock(s);
34
+ for (p = mmc->raminfo; p->name; p++) {
35
+ if (p->mrindex < 0) {
36
+ /* Found the entry for "system memory" */
37
+ mc->default_ram_size = p->size;
38
+ mc->default_ram_id = p->name;
39
+ return;
40
+ }
41
+ }
42
+ g_assert_not_reached();
125
}
43
}
126
44
127
+static void stellaris_sys_reset_exit(Object *obj)
45
static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
128
+{
46
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
129
+}
47
mmc->numirq = 92;
130
+
48
mmc->raminfo = an505_raminfo;
131
static int stellaris_sys_post_load(void *opaque, int version_id)
49
mmc->armsse_type = TYPE_IOTKIT;
132
{
50
+ mps2tz_set_default_ram_info(mmc);
133
ssys_state *s = opaque;
134
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_sys = {
135
}
136
};
137
138
+static Property stellaris_sys_properties[] = {
139
+ DEFINE_PROP_UINT32("user0", ssys_state, user0, 0),
140
+ DEFINE_PROP_UINT32("user1", ssys_state, user1, 0),
141
+ DEFINE_PROP_UINT32("did0", ssys_state, did0, 0),
142
+ DEFINE_PROP_UINT32("did1", ssys_state, did1, 0),
143
+ DEFINE_PROP_UINT32("dc0", ssys_state, dc0, 0),
144
+ DEFINE_PROP_UINT32("dc1", ssys_state, dc1, 0),
145
+ DEFINE_PROP_UINT32("dc2", ssys_state, dc2, 0),
146
+ DEFINE_PROP_UINT32("dc3", ssys_state, dc3, 0),
147
+ DEFINE_PROP_UINT32("dc4", ssys_state, dc4, 0),
148
+ DEFINE_PROP_END_OF_LIST()
149
+};
150
+
151
+static void stellaris_sys_instance_init(Object *obj)
152
+{
153
+ ssys_state *s = STELLARIS_SYS(obj);
154
+ SysBusDevice *sbd = SYS_BUS_DEVICE(s);
155
+
156
+ memory_region_init_io(&s->iomem, obj, &ssys_ops, s, "ssys", 0x00001000);
157
+ sysbus_init_mmio(sbd, &s->iomem);
158
+ sysbus_init_irq(sbd, &s->irq);
159
+}
160
+
161
static int stellaris_sys_init(uint32_t base, qemu_irq irq,
162
stellaris_board_info * board,
163
uint8_t *macaddr)
164
{
165
- ssys_state *s;
166
+ DeviceState *dev = qdev_new(TYPE_STELLARIS_SYS);
167
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
168
169
- s = g_new0(ssys_state, 1);
170
- s->irq = irq;
171
- s->board = board;
172
/* Most devices come preprogrammed with a MAC address in the user data. */
173
- s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
174
- s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
175
+ qdev_prop_set_uint32(dev, "user0",
176
+ macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16));
177
+ qdev_prop_set_uint32(dev, "user1",
178
+ macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16));
179
+ qdev_prop_set_uint32(dev, "did0", board->did0);
180
+ qdev_prop_set_uint32(dev, "did1", board->did1);
181
+ qdev_prop_set_uint32(dev, "dc0", board->dc0);
182
+ qdev_prop_set_uint32(dev, "dc1", board->dc1);
183
+ qdev_prop_set_uint32(dev, "dc2", board->dc2);
184
+ qdev_prop_set_uint32(dev, "dc3", board->dc3);
185
+ qdev_prop_set_uint32(dev, "dc4", board->dc4);
186
+
187
+ sysbus_realize_and_unref(sbd, &error_fatal);
188
+ sysbus_mmio_map(sbd, 0, base);
189
+ sysbus_connect_irq(sbd, 0, irq);
190
+
191
+ /*
192
+ * Normally we should not be resetting devices like this during
193
+ * board creation. For the moment we need to do so, because
194
+ * system_clock_scale will only get set when the STELLARIS_SYS
195
+ * device is reset, and we need its initial value to pass to
196
+ * the watchdog device. This hack can be removed once the
197
+ * watchdog has been converted to use a Clock input instead.
198
+ */
199
+ device_cold_reset(dev);
200
201
- memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
202
- memory_region_add_subregion(get_system_memory(), base, &s->iomem);
203
- ssys_reset(s);
204
- vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_stellaris_sys, s);
205
return 0;
206
}
51
}
207
52
208
-
53
static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
209
/* I2C controller. */
54
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
210
55
mmc->numirq = 92;
211
#define TYPE_STELLARIS_I2C "stellaris-i2c"
56
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
212
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_adc_info = {
57
mmc->armsse_type = TYPE_SSE200;
213
.class_init = stellaris_adc_class_init,
58
+ mps2tz_set_default_ram_info(mmc);
214
};
215
216
+static void stellaris_sys_class_init(ObjectClass *klass, void *data)
217
+{
218
+ DeviceClass *dc = DEVICE_CLASS(klass);
219
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
220
+
221
+ dc->vmsd = &vmstate_stellaris_sys;
222
+ rc->phases.enter = stellaris_sys_reset_enter;
223
+ rc->phases.hold = stellaris_sys_reset_hold;
224
+ rc->phases.exit = stellaris_sys_reset_exit;
225
+ device_class_set_props(dc, stellaris_sys_properties);
226
+}
227
+
228
+static const TypeInfo stellaris_sys_info = {
229
+ .name = TYPE_STELLARIS_SYS,
230
+ .parent = TYPE_SYS_BUS_DEVICE,
231
+ .instance_size = sizeof(ssys_state),
232
+ .instance_init = stellaris_sys_instance_init,
233
+ .class_init = stellaris_sys_class_init,
234
+};
235
+
236
static void stellaris_register_types(void)
237
{
238
type_register_static(&stellaris_i2c_info);
239
type_register_static(&stellaris_gptm_info);
240
type_register_static(&stellaris_adc_info);
241
+ type_register_static(&stellaris_sys_info);
242
}
59
}
243
60
244
type_init(stellaris_register_types)
61
static const TypeInfo mps2tz_info = {
245
--
62
--
246
2.20.1
63
2.20.1
247
64
248
65
diff view generated by jsdifflib
1
Now that the watchdog device uses its Clock input rather than being
1
The AN505 and AN521 don't have any read-only memory, but the AN524
2
passed the value of system_clock_scale at creation time, we can
2
does; add a flag to ROMInfo to mark a region as ROM.
3
remove the hack where we reset the STELLARIS_SYS at board creation
4
time to force it to set system_clock_scale. Instead it will be reset
5
at the usual point in startup and will inform the watchdog of the
6
clock frequency at that point.
7
3
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Luc Michel <luc@lmichel.fr>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210215115138.20465-19-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20210128114145.20536-26-peter.maydell@linaro.org
13
Message-id: 20210121190622.22000-26-peter.maydell@linaro.org
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
---
7
---
16
hw/arm/stellaris.c | 10 ----------
8
hw/arm/mps2-tz.c | 6 ++++++
17
1 file changed, 10 deletions(-)
9
1 file changed, 6 insertions(+)
18
10
19
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
11
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/stellaris.c
13
--- a/hw/arm/mps2-tz.c
22
+++ b/hw/arm/stellaris.c
14
+++ b/hw/arm/mps2-tz.c
23
@@ -XXX,XX +XXX,XX @@ static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
15
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
24
sysbus_mmio_map(sbd, 0, base);
16
* Flag values:
25
sysbus_connect_irq(sbd, 0, irq);
17
* IS_ALIAS: this RAM area is an alias to the upstream end of the
26
18
* MPC specified by its .mpc value
27
- /*
19
+ * IS_ROM: this RAM area is read-only
28
- * Normally we should not be resetting devices like this during
20
*/
29
- * board creation. For the moment we need to do so, because
21
#define IS_ALIAS 1
30
- * system_clock_scale will only get set when the STELLARIS_SYS
22
+#define IS_ROM 2
31
- * device is reset, and we need its initial value to pass to
23
32
- * the watchdog device. This hack can be removed once the
24
struct MPS2TZMachineClass {
33
- * watchdog has been converted to use a Clock input instead.
25
MachineClass parent;
34
- */
26
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
35
- device_cold_reset(dev);
27
if (raminfo->mrindex < 0) {
36
-
28
/* Means this RAMInfo is for QEMU's "system memory" */
37
return dev;
29
MachineState *machine = MACHINE(mms);
30
+ assert(!(raminfo->flags & IS_ROM));
31
return machine->ram;
32
}
33
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
35
36
memory_region_init_ram(ram, NULL, raminfo->name,
37
raminfo->size, &error_fatal);
38
+ if (raminfo->flags & IS_ROM) {
39
+ memory_region_set_readonly(ram, true);
40
+ }
41
return ram;
38
}
42
}
39
43
40
--
44
--
41
2.20.1
45
2.20.1
42
46
43
47
diff view generated by jsdifflib
1
Use the MAINCLK Clock input to set the system_clock_scale variable
1
The armv7m_load_kernel() function takes a mem_size argument which it
2
rather than using the mainclk_frq property.
2
expects to be the size of the memory region at guest address 0. (It
3
uses this argument only as a limit on how large a raw image file it
4
can load at address zero).
5
6
Instead of hardcoding this value, find the RAMInfo corresponding to
7
the 0 address and extract its size.
3
8
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
12
Message-id: 20210215115138.20465-20-peter.maydell@linaro.org
8
Message-id: 20210128114145.20536-23-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-23-peter.maydell@linaro.org
10
---
13
---
11
hw/arm/armsse.c | 24 +++++++++++++++++++-----
14
hw/arm/mps2-tz.c | 17 ++++++++++++++++-
12
1 file changed, 19 insertions(+), 5 deletions(-)
15
1 file changed, 16 insertions(+), 1 deletion(-)
13
16
14
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/armsse.c
19
--- a/hw/arm/mps2-tz.c
17
+++ b/hw/arm/armsse.c
20
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
21
@@ -XXX,XX +XXX,XX @@ static void create_non_mpc_ram(MPS2TZMachineState *mms)
19
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
22
}
20
}
23
}
21
24
22
+static void armsse_mainclk_update(void *opaque)
25
+static uint32_t boot_ram_size(MPS2TZMachineState *mms)
23
+{
26
+{
24
+ ARMSSE *s = ARM_SSE(opaque);
27
+ /* Return the size of the RAM block at guest address zero */
25
+ /*
28
+ const RAMInfo *p;
26
+ * Set system_clock_scale from our Clock input; this is what
29
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
27
+ * controls the tick rate of the CPU SysTick timer.
30
+
28
+ */
31
+ for (p = mmc->raminfo; p->name; p++) {
29
+ system_clock_scale = clock_ticks_to_ns(s->mainclk, 1);
32
+ if (p->base == 0) {
33
+ return p->size;
34
+ }
35
+ }
36
+ g_assert_not_reached();
30
+}
37
+}
31
+
38
+
32
static void armsse_init(Object *obj)
39
static void mps2tz_common_init(MachineState *machine)
33
{
40
{
34
ARMSSE *s = ARM_SSE(obj);
41
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
35
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
42
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
36
assert(info->sram_banks <= MAX_SRAM_BANKS);
43
37
assert(info->num_cpus <= SSE_MAX_CPUS);
44
create_non_mpc_ram(mms);
38
45
39
- s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL);
46
- armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
40
+ s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
47
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
41
+ armsse_mainclk_update, s);
48
+ boot_ram_size(mms));
42
s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
43
44
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
45
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
46
return;
47
}
48
49
- if (!s->mainclk_frq) {
50
- error_setg(errp, "MAINCLK_FRQ property was not set");
51
- return;
52
+ if (!clock_has_source(s->mainclk)) {
53
+ error_setg(errp, "MAINCLK clock was not connected");
54
+ }
55
+ if (!clock_has_source(s->s32kclk)) {
56
+ error_setg(errp, "S32KCLK clock was not connected");
57
}
58
59
assert(info->num_cpus <= SSE_MAX_CPUS);
60
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
61
*/
62
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
63
64
- system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
65
+ /* Set initial system_clock_scale from MAINCLK */
66
+ armsse_mainclk_update(s);
67
}
49
}
68
50
69
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
51
static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
70
--
52
--
71
2.20.1
53
2.20.1
72
54
73
55
diff view generated by jsdifflib
1
Create and connect the two clocks needed by the ARMSSE.
1
Add support for the mps3-an524 board; this is an SSE-200 based FPGA
2
image, like the existing mps2-an521. It has a usefully larger amount
3
of RAM, and a PL031 RTC, as well as some more minor differences.
4
5
In real hardware this image runs on a newer generation of the FPGA
6
board, the MPS3 rather than the older MPS2. Architecturally the two
7
boards are similar, so we implement the MPS3 boards in the mps2-tz.c
8
file as variations of the existing MPS2 boards.
2
9
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
12
Message-id: 20210215115138.20465-21-peter.maydell@linaro.org
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210128114145.20536-15-peter.maydell@linaro.org
8
Message-id: 20210121190622.22000-15-peter.maydell@linaro.org
9
---
13
---
10
hw/arm/mps2-tz.c | 13 +++++++++++++
14
hw/arm/mps2-tz.c | 139 +++++++++++++++++++++++++++++++++++++++++++++--
11
1 file changed, 13 insertions(+)
15
1 file changed, 135 insertions(+), 4 deletions(-)
12
16
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
19
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
20
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
18
#include "hw/net/lan9118.h"
22
* This source file covers the following FPGA images, for TrustZone cores:
19
#include "net/net.h"
23
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
20
#include "hw/core/split-irq.h"
24
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
21
+#include "hw/qdev-clock.h"
25
+ * "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
26
*
27
* Links to the TRM for the board itself and to the various Application
28
* Notes which document the FPGA images can be found here:
29
@@ -XXX,XX +XXX,XX @@
30
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
31
* Application Note AN521:
32
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
33
+ * Application Note AN524:
34
+ * https://developer.arm.com/documentation/dai0524/latest/
35
*
36
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
37
* (ARM ECM0601256) for the details of some of the device layout:
38
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
39
- * Similarly, the AN521 uses the SSE-200, and the SSE-200 TRM defines
40
+ * Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
41
* most of the device layout:
42
* http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
43
*
44
@@ -XXX,XX +XXX,XX @@
45
#include "hw/qdev-clock.h"
22
#include "qom/object.h"
46
#include "qom/object.h"
23
47
24
#define MPS2TZ_NUMIRQ 92
48
-#define MPS2TZ_NUMIRQ_MAX 92
49
+#define MPS2TZ_NUMIRQ_MAX 95
50
#define MPS2TZ_RAM_MAX 4
51
52
typedef enum MPS2TZFPGAType {
53
FPGA_AN505,
54
FPGA_AN521,
55
+ FPGA_AN524,
56
} MPS2TZFPGAType;
57
58
/*
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
59
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
60
TZPPC ppc[5];
61
TZMPC mpc[3];
62
PL022State spi[5];
63
- ArmSbconI2CState i2c[4];
64
+ ArmSbconI2CState i2c[5];
65
UnimplementedDeviceState i2s_audio;
66
UnimplementedDeviceState gpio[4];
67
UnimplementedDeviceState gfx;
68
+ UnimplementedDeviceState cldc;
69
+ UnimplementedDeviceState rtc;
70
PL080State dma[4];
71
TZMSC msc[4];
72
- CMSDKAPBUART uart[5];
73
+ CMSDKAPBUART uart[6];
74
SplitIRQ sec_resp_splitter;
26
qemu_or_irq uart_irq_orgate;
75
qemu_or_irq uart_irq_orgate;
27
DeviceState *lan9118;
76
DeviceState *lan9118;
28
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
77
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
29
+ Clock *sysclk;
78
#define TYPE_MPS2TZ_MACHINE "mps2tz"
30
+ Clock *s32kclk;
79
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
80
#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
81
+#define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
82
83
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
84
85
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
86
25000000,
31
};
87
};
32
88
33
#define TYPE_MPS2TZ_MACHINE "mps2tz"
89
+static const uint32_t an524_oscclk[] = {
34
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
90
+ 24000000,
35
91
+ 32000000,
36
/* Main SYSCLK frequency in Hz */
92
+ 50000000,
37
#define SYSCLK_FRQ 20000000
93
+ 50000000,
38
+/* Slow 32Khz S32KCLK frequency in Hz */
94
+ 24576000,
39
+#define S32KCLK_FRQ (32 * 1000)
95
+ 23750000,
40
96
+};
41
/* Create an alias of an entire original MemoryRegion @orig
97
+
42
* located at @base in the memory map.
98
static const RAMInfo an505_raminfo[] = { {
99
.name = "ssram-0",
100
.base = 0x00000000,
101
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
102
},
103
};
104
105
+static const RAMInfo an524_raminfo[] = { {
106
+ .name = "bram",
107
+ .base = 0x00000000,
108
+ .size = 512 * KiB,
109
+ .mpc = 0,
110
+ .mrindex = 0,
111
+ }, {
112
+ .name = "sram",
113
+ .base = 0x20000000,
114
+ .size = 32 * 4 * KiB,
115
+ .mpc = 1,
116
+ .mrindex = 1,
117
+ }, {
118
+ /* We don't model QSPI flash yet; for now expose it as simple ROM */
119
+ .name = "QSPI",
120
+ .base = 0x28000000,
121
+ .size = 8 * MiB,
122
+ .mpc = 1,
123
+ .mrindex = 2,
124
+ .flags = IS_ROM,
125
+ }, {
126
+ .name = "DDR",
127
+ .base = 0x60000000,
128
+ .size = 2 * GiB,
129
+ .mpc = 2,
130
+ .mrindex = -1,
131
+ }, {
132
+ .name = NULL,
133
+ },
134
+};
135
+
136
static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
137
{
138
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
43
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
139
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
44
exit(EXIT_FAILURE);
140
},
141
};
142
143
+ const PPCInfo an524_ppcs[] = { {
144
+ .name = "apb_ppcexp0",
145
+ .ports = {
146
+ { "bram-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
147
+ { "qspi-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
148
+ { "ddr-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
149
+ },
150
+ }, {
151
+ .name = "apb_ppcexp1",
152
+ .ports = {
153
+ { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000 },
154
+ { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000 },
155
+ { "spi0", make_spi, &mms->spi[0], 0x41202000, 0x1000, { 52 } },
156
+ { "spi1", make_spi, &mms->spi[1], 0x41203000, 0x1000, { 53 } },
157
+ { "spi2", make_spi, &mms->spi[2], 0x41204000, 0x1000, { 54 } },
158
+ { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000 },
159
+ { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000 },
160
+ { /* port 7 reserved */ },
161
+ { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000 },
162
+ },
163
+ }, {
164
+ .name = "apb_ppcexp2",
165
+ .ports = {
166
+ { "scc", make_scc, &mms->scc, 0x41300000, 0x1000 },
167
+ { "i2s-audio", make_unimp_dev, &mms->i2s_audio,
168
+ 0x41301000, 0x1000 },
169
+ { "fpgaio", make_fpgaio, &mms->fpgaio, 0x41302000, 0x1000 },
170
+ { "uart0", make_uart, &mms->uart[0], 0x41303000, 0x1000, { 32, 33, 42 } },
171
+ { "uart1", make_uart, &mms->uart[1], 0x41304000, 0x1000, { 34, 35, 43 } },
172
+ { "uart2", make_uart, &mms->uart[2], 0x41305000, 0x1000, { 36, 37, 44 } },
173
+ { "uart3", make_uart, &mms->uart[3], 0x41306000, 0x1000, { 38, 39, 45 } },
174
+ { "uart4", make_uart, &mms->uart[4], 0x41307000, 0x1000, { 40, 41, 46 } },
175
+ { "uart5", make_uart, &mms->uart[5], 0x41308000, 0x1000, { 124, 125, 126 } },
176
+
177
+ { /* port 9 reserved */ },
178
+ { "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
179
+ { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
180
+ },
181
+ }, {
182
+ .name = "ahb_ppcexp0",
183
+ .ports = {
184
+ { "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
185
+ { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
186
+ { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
187
+ { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
188
+ { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
189
+ },
190
+ },
191
+ };
192
+
193
switch (mmc->fpga_type) {
194
case FPGA_AN505:
195
case FPGA_AN521:
196
ppcs = an505_ppcs;
197
num_ppcs = ARRAY_SIZE(an505_ppcs);
198
break;
199
+ case FPGA_AN524:
200
+ ppcs = an524_ppcs;
201
+ num_ppcs = ARRAY_SIZE(an524_ppcs);
202
+ break;
203
default:
204
g_assert_not_reached();
45
}
205
}
46
206
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
47
+ /* These clocks don't need migration because they are fixed-frequency */
207
mps2tz_set_default_ram_info(mmc);
48
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
208
}
49
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
209
50
+ mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
210
+static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
51
+ clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
211
+{
52
+
212
+ MachineClass *mc = MACHINE_CLASS(oc);
53
object_initialize_child(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
213
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
54
mmc->armsse_type);
214
+
55
iotkitdev = DEVICE(&mms->iotkit);
215
+ mc->desc = "ARM MPS3 with AN524 FPGA image for dual Cortex-M33";
56
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
216
+ mc->default_cpus = 2;
57
OBJECT(system_memory), &error_abort);
217
+ mc->min_cpus = mc->default_cpus;
58
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
218
+ mc->max_cpus = mc->default_cpus;
59
qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
219
+ mmc->fpga_type = FPGA_AN524;
60
+ qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
220
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
61
+ qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
221
+ mmc->scc_id = 0x41045240;
62
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
222
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
63
223
+ mmc->oscclk = an524_oscclk;
64
/*
224
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
225
+ mmc->fpgaio_num_leds = 10;
226
+ mmc->fpgaio_has_switches = true;
227
+ mmc->numirq = 95;
228
+ mmc->raminfo = an524_raminfo;
229
+ mmc->armsse_type = TYPE_SSE200;
230
+ mps2tz_set_default_ram_info(mmc);
231
+}
232
+
233
static const TypeInfo mps2tz_info = {
234
.name = TYPE_MPS2TZ_MACHINE,
235
.parent = TYPE_MACHINE,
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an521_info = {
237
.class_init = mps2tz_an521_class_init,
238
};
239
240
+static const TypeInfo mps3tz_an524_info = {
241
+ .name = TYPE_MPS3TZ_AN524_MACHINE,
242
+ .parent = TYPE_MPS2TZ_MACHINE,
243
+ .class_init = mps3tz_an524_class_init,
244
+};
245
+
246
static void mps2tz_machine_init(void)
247
{
248
type_register_static(&mps2tz_info);
249
type_register_static(&mps2tz_an505_info);
250
type_register_static(&mps2tz_an521_info);
251
+ type_register_static(&mps3tz_an524_info);
252
}
253
254
type_init(mps2tz_machine_init);
65
--
255
--
66
2.20.1
256
2.20.1
67
257
68
258
diff view generated by jsdifflib
1
Now that the CMSDK APB watchdog uses its Clock input, it will
1
The AN524 has a USB controller (an ISP1763); we don't have a model of
2
correctly respond when the system clock frequency is changed using
2
it but we should provide a stub "unimplemented-device" for it. This
3
the RCC register on in the Stellaris board system registers. Test
3
is slightly complicated because the USB controller shares a PPC port
4
that when the RCC register is written it causes the watchdog timer to
4
with the ethernet controller.
5
change speed.
5
6
Implement a make_* function which provides creates a container
7
MemoryRegion with both the ethernet controller and an
8
unimplemented-device stub for the USB controller.
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc@lmichel.fr>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20210215115138.20465-22-peter.maydell@linaro.org
11
Message-id: 20210128114145.20536-22-peter.maydell@linaro.org
12
Message-id: 20210121190622.22000-22-peter.maydell@linaro.org
13
---
14
---
14
tests/qtest/cmsdk-apb-watchdog-test.c | 52 +++++++++++++++++++++++++++
15
hw/arm/mps2-tz.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
15
1 file changed, 52 insertions(+)
16
1 file changed, 47 insertions(+), 1 deletion(-)
16
17
17
diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c
18
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qtest/cmsdk-apb-watchdog-test.c
20
--- a/hw/arm/mps2-tz.c
20
+++ b/tests/qtest/cmsdk-apb-watchdog-test.c
21
+++ b/hw/arm/mps2-tz.c
21
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
22
*/
23
23
24
ARMSSE iotkit;
24
#include "qemu/osdep.h"
25
MemoryRegion ram[MPS2TZ_RAM_MAX];
25
+#include "qemu/bitops.h"
26
+ MemoryRegion eth_usb_container;
26
#include "libqtest-single.h"
27
28
/*
29
@@ -XXX,XX +XXX,XX @@
30
#define WDOGMIS 0x14
31
#define WDOGLOCK 0xc00
32
33
+#define SSYS_BASE 0x400fe000
34
+#define RCC 0x60
35
+#define SYSDIV_SHIFT 23
36
+#define SYSDIV_LENGTH 4
37
+
27
+
38
static void test_watchdog(void)
28
MPS2SCC scc;
39
{
29
MPS2FPGAIO fpgaio;
40
g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
30
TZPPC ppc[5];
41
@@ -XXX,XX +XXX,XX @@ static void test_watchdog(void)
31
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
42
g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
32
UnimplementedDeviceState gfx;
33
UnimplementedDeviceState cldc;
34
UnimplementedDeviceState rtc;
35
+ UnimplementedDeviceState usb;
36
PL080State dma[4];
37
TZMSC msc[4];
38
CMSDKAPBUART uart[6];
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
40
return sysbus_mmio_get_region(s, 0);
43
}
41
}
44
42
45
+static void test_clock_change(void)
43
+static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
44
+ const char *name, hwaddr size,
45
+ const int *irqs)
46
+{
46
+{
47
+ uint32_t rcc;
47
+ /*
48
+ * The AN524 makes the ethernet and USB share a PPC port.
49
+ * irqs[] is the ethernet IRQ.
50
+ */
51
+ SysBusDevice *s;
52
+ NICInfo *nd = &nd_table[0];
53
+
54
+ memory_region_init(&mms->eth_usb_container, OBJECT(mms),
55
+ "mps2-tz-eth-usb-container", 0x200000);
48
+
56
+
49
+ /*
57
+ /*
50
+ * Test that writing to the stellaris board's RCC register to
58
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
51
+ * change the system clock frequency causes the watchdog
59
+ * except that it doesn't support the checksum-offload feature.
52
+ * to change the speed it counts at.
53
+ */
60
+ */
54
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
61
+ qemu_check_nic_model(nd, "lan9118");
62
+ mms->lan9118 = qdev_new(TYPE_LAN9118);
63
+ qdev_set_nic_properties(mms->lan9118, nd);
55
+
64
+
56
+ writel(WDOG_BASE + WDOGCONTROL, 1);
65
+ s = SYS_BUS_DEVICE(mms->lan9118);
57
+ writel(WDOG_BASE + WDOGLOAD, 1000);
66
+ sysbus_realize_and_unref(s, &error_fatal);
67
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
58
+
68
+
59
+ /* Step to just past the 500th tick */
69
+ memory_region_add_subregion(&mms->eth_usb_container,
60
+ clock_step(80 * 500 + 1);
70
+ 0, sysbus_mmio_get_region(s, 0));
61
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
62
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
63
+
71
+
64
+ /* Rewrite RCC.SYSDIV from 16 to 8, so the clock is now 40ns per tick */
72
+ /* The USB OTG controller is an ISP1763; we don't have a model of it. */
65
+ rcc = readl(SSYS_BASE + RCC);
73
+ object_initialize_child(OBJECT(mms), "usb-otg",
66
+ g_assert_cmpuint(extract32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH), ==, 0xf);
74
+ &mms->usb, TYPE_UNIMPLEMENTED_DEVICE);
67
+ rcc = deposit32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH, 7);
75
+ qdev_prop_set_string(DEVICE(&mms->usb), "name", "usb-otg");
68
+ writel(SSYS_BASE + RCC, rcc);
76
+ qdev_prop_set_uint64(DEVICE(&mms->usb), "size", 0x100000);
77
+ s = SYS_BUS_DEVICE(&mms->usb);
78
+ sysbus_realize(s, &error_fatal);
69
+
79
+
70
+ /* Just past the 1000th tick: timer should have fired */
80
+ memory_region_add_subregion(&mms->eth_usb_container,
71
+ clock_step(40 * 500);
81
+ 0x100000, sysbus_mmio_get_region(s, 0));
72
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
73
+
82
+
74
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 0);
83
+ return &mms->eth_usb_container;
75
+
76
+ /* VALUE reloads at following tick */
77
+ clock_step(41);
78
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
79
+
80
+ /* Writing any value to WDOGINTCLR clears the interrupt and reloads */
81
+ clock_step(40 * 500);
82
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
83
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
84
+ writel(WDOG_BASE + WDOGINTCLR, 0);
85
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
86
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
87
+}
84
+}
88
+
85
+
89
int main(int argc, char **argv)
86
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
90
{
87
const char *name, hwaddr size,
91
int r;
88
const int *irqs)
92
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
89
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
93
qtest_start("-machine lm3s811evb");
90
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
94
91
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
95
qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog);
92
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
96
+ qtest_add_func("/cmsdk-apb-watchdog/watchdog_clock_change",
93
- { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
97
+ test_clock_change);
94
+ { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 48 } },
98
95
},
99
r = g_test_run();
96
},
100
97
};
101
--
98
--
102
2.20.1
99
2.20.1
103
100
104
101
diff view generated by jsdifflib
1
Add a simple test of the CMSDK APB timer, since we're about to do
1
The AN524 has a PL031 RTC, which we have a model of; provide it
2
some refactoring of how it is clocked.
2
rather than an unimplemented-device stub.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215115138.20465-23-peter.maydell@linaro.org
8
Message-id: 20210128114145.20536-4-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-4-peter.maydell@linaro.org
10
---
8
---
11
tests/qtest/cmsdk-apb-timer-test.c | 75 ++++++++++++++++++++++++++++++
9
hw/arm/mps2-tz.c | 22 ++++++++++++++++++++--
12
MAINTAINERS | 1 +
10
1 file changed, 20 insertions(+), 2 deletions(-)
13
tests/qtest/meson.build | 1 +
14
3 files changed, 77 insertions(+)
15
create mode 100644 tests/qtest/cmsdk-apb-timer-test.c
16
11
17
diff --git a/tests/qtest/cmsdk-apb-timer-test.c b/tests/qtest/cmsdk-apb-timer-test.c
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
new file mode 100644
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX
14
--- a/hw/arm/mps2-tz.c
20
--- /dev/null
15
+++ b/hw/arm/mps2-tz.c
21
+++ b/tests/qtest/cmsdk-apb-timer-test.c
22
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
23
+/*
17
#include "hw/misc/tz-msc.h"
24
+ * QTest testcase for the CMSDK APB timer device
18
#include "hw/arm/armsse.h"
25
+ *
19
#include "hw/dma/pl080.h"
26
+ * Copyright (c) 2021 Linaro Limited
20
+#include "hw/rtc/pl031.h"
27
+ *
21
#include "hw/ssi/pl022.h"
28
+ * This program is free software; you can redistribute it and/or modify it
22
#include "hw/i2c/arm_sbcon_i2c.h"
29
+ * under the terms of the GNU General Public License as published by the
23
#include "hw/net/lan9118.h"
30
+ * Free Software Foundation; either version 2 of the License, or
24
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
31
+ * (at your option) any later version.
25
UnimplementedDeviceState gpio[4];
32
+ *
26
UnimplementedDeviceState gfx;
33
+ * This program is distributed in the hope that it will be useful, but WITHOUT
27
UnimplementedDeviceState cldc;
34
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28
- UnimplementedDeviceState rtc;
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29
UnimplementedDeviceState usb;
36
+ * for more details.
30
+ PL031State rtc;
37
+ */
31
PL080State dma[4];
32
TZMSC msc[4];
33
CMSDKAPBUART uart[6];
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
35
return sysbus_mmio_get_region(s, 0);
36
}
37
38
+static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
39
+ const char *name, hwaddr size,
40
+ const int *irqs)
41
+{
42
+ PL031State *pl031 = opaque;
43
+ SysBusDevice *s;
38
+
44
+
39
+#include "qemu/osdep.h"
45
+ object_initialize_child(OBJECT(mms), name, pl031, TYPE_PL031);
40
+#include "libqtest-single.h"
46
+ s = SYS_BUS_DEVICE(pl031);
41
+
47
+ sysbus_realize(s, &error_fatal);
42
+/* IoTKit/ARMSSE-200 timer0; driven at 25MHz in mps2-an385, so 40ns per tick */
48
+ /*
43
+#define TIMER_BASE 0x40000000
49
+ * The board docs don't give an IRQ number for the PL031, so
44
+
50
+ * presumably it is not connected.
45
+#define CTRL 0
51
+ */
46
+#define VALUE 4
52
+ return sysbus_mmio_get_region(s, 0);
47
+#define RELOAD 8
48
+#define INTSTATUS 0xc
49
+
50
+static void test_timer(void)
51
+{
52
+ g_assert_true(readl(TIMER_BASE + INTSTATUS) == 0);
53
+
54
+ /* Start timer: will fire after 40 * 1000 == 40000 ns */
55
+ writel(TIMER_BASE + RELOAD, 1000);
56
+ writel(TIMER_BASE + CTRL, 9);
57
+
58
+ /* Step to just past the 500th tick and check VALUE */
59
+ clock_step(40 * 500 + 1);
60
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 0);
61
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 500);
62
+
63
+ /* Just past the 1000th tick: timer should have fired */
64
+ clock_step(40 * 500);
65
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 1);
66
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 0);
67
+
68
+ /* VALUE reloads at the following tick */
69
+ clock_step(40);
70
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 1000);
71
+
72
+ /* Check write-1-to-clear behaviour of INTSTATUS */
73
+ writel(TIMER_BASE + INTSTATUS, 0);
74
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 1);
75
+ writel(TIMER_BASE + INTSTATUS, 1);
76
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 0);
77
+
78
+ /* Turn off the timer */
79
+ writel(TIMER_BASE + CTRL, 0);
80
+}
53
+}
81
+
54
+
82
+int main(int argc, char **argv)
55
static void create_non_mpc_ram(MPS2TZMachineState *mms)
83
+{
56
{
84
+ int r;
57
/*
85
+
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
86
+ g_test_init(&argc, &argv, NULL);
59
87
+
60
{ /* port 9 reserved */ },
88
+ qtest_start("-machine mps2-an385");
61
{ "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
89
+
62
- { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
90
+ qtest_add_func("/cmsdk-apb-timer/timer", test_timer);
63
+ { "rtc", make_rtc, &mms->rtc, 0x4130b000, 0x1000 },
91
+
64
},
92
+ r = g_test_run();
65
}, {
93
+
66
.name = "ahb_ppcexp0",
94
+ qtest_end();
95
+
96
+ return r;
97
+}
98
diff --git a/MAINTAINERS b/MAINTAINERS
99
index XXXXXXX..XXXXXXX 100644
100
--- a/MAINTAINERS
101
+++ b/MAINTAINERS
102
@@ -XXX,XX +XXX,XX @@ F: include/hw/rtc/pl031.h
103
F: include/hw/arm/primecell.h
104
F: hw/timer/cmsdk-apb-timer.c
105
F: include/hw/timer/cmsdk-apb-timer.h
106
+F: tests/qtest/cmsdk-apb-timer-test.c
107
F: hw/timer/cmsdk-apb-dualtimer.c
108
F: include/hw/timer/cmsdk-apb-dualtimer.h
109
F: hw/char/cmsdk-apb-uart.c
110
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
111
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/qtest/meson.build
113
+++ b/tests/qtest/meson.build
114
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
115
'npcm7xx_timer-test',
116
'npcm7xx_watchdog_timer-test']
117
qtests_arm = \
118
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
119
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
120
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
121
['arm-cpu-features',
122
--
67
--
123
2.20.1
68
2.20.1
124
69
125
70
diff view generated by jsdifflib
1
As the first step in converting the CMSDK_APB_TIMER device to the
1
Add brief documentation of the new mps3-an524 board.
2
Clock framework, add a Clock input. For the moment we do nothing
3
with this clock; we will change the behaviour from using the
4
wdogclk-frq property to using the Clock once all the users of this
5
device have been converted to wire up the Clock.
6
7
This is a migration compatibility break for machines mps2-an385,
8
mps2-an386, mps2-an500, mps2-an511, mps2-an505, mps2-an521, musca-a,
9
musca-b1, lm3s811evb, lm3s6965evb.
10
2
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210215115138.20465-24-peter.maydell@linaro.org
15
Message-id: 20210128114145.20536-10-peter.maydell@linaro.org
16
Message-id: 20210121190622.22000-10-peter.maydell@linaro.org
17
---
7
---
18
include/hw/watchdog/cmsdk-apb-watchdog.h | 3 +++
8
docs/system/arm/mps2.rst | 24 ++++++++++++++++++------
19
hw/watchdog/cmsdk-apb-watchdog.c | 7 +++++--
9
1 file changed, 18 insertions(+), 6 deletions(-)
20
2 files changed, 8 insertions(+), 2 deletions(-)
21
10
22
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
23
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
13
--- a/docs/system/arm/mps2.rst
25
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
14
+++ b/docs/system/arm/mps2.rst
26
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
27
*
16
-Arm MPS2 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``)
28
* QEMU interface:
17
-================================================================================================================
29
* + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
30
+ * + Clock input "WDOGCLK": clock for the watchdog's timer
19
+=========================================================================================================================================
31
* + sysbus MMIO region 0: the register bank
20
32
* + sysbus IRQ 0: watchdog interrupt
21
These board models all use Arm M-profile CPUs.
33
*
22
34
@@ -XXX,XX +XXX,XX @@
23
-The Arm MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
35
24
-FPGA but is otherwise the same as the 2). Since the CPU itself
36
#include "hw/sysbus.h"
25
-and most of the devices are in the FPGA, the details of the board
37
#include "hw/ptimer.h"
26
-as seen by the guest depend significantly on the FPGA image.
38
+#include "hw/clock.h"
27
+The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
39
#include "qom/object.h"
28
+bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
40
29
+FPGA again, can handle 4GB of RAM and has a USB controller and QSPI flash).
41
#define TYPE_CMSDK_APB_WATCHDOG "cmsdk-apb-watchdog"
30
+
42
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBWatchdog {
31
+Since the CPU itself and most of the devices are in the FPGA, the
43
uint32_t wdogclk_frq;
32
+details of the board as seen by the guest depend significantly on the
44
bool is_luminary;
33
+FPGA image.
45
struct ptimer_state *timer;
34
46
+ Clock *wdogclk;
35
QEMU models the following FPGA images:
47
36
48
uint32_t control;
37
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
49
uint32_t intstatus;
38
Cortex-M3 'DesignStart' as documented in Arm Application Note AN511
50
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
39
``mps2-an521``
51
index XXXXXXX..XXXXXXX 100644
40
Dual Cortex-M33 as documented in Arm Application Note AN521
52
--- a/hw/watchdog/cmsdk-apb-watchdog.c
41
+``mps3-an524``
53
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
42
+ Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
54
@@ -XXX,XX +XXX,XX @@
43
55
#include "hw/irq.h"
44
Differences between QEMU and real hardware:
56
#include "hw/qdev-properties.h"
45
57
#include "hw/registerfields.h"
46
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
58
+#include "hw/qdev-clock.h"
47
block RAM is unimplemented (QEMU always maps this to ZBT SSRAM1, as
59
#include "hw/watchdog/cmsdk-apb-watchdog.h"
48
if zbt_boot_ctrl is always zero)
60
#include "migration/vmstate.h"
49
+- AN524 remapping of low memory to either BRAM or to QSPI flash is
61
50
+ unimplemented (QEMU always maps this to BRAM, ignoring the
62
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
51
+ SCC CFG_REG0 memory-remap bit)
63
s, "cmsdk-apb-watchdog", 0x1000);
52
- QEMU provides a LAN9118 ethernet rather than LAN9220; the only guest
64
sysbus_init_mmio(sbd, &s->iomem);
53
visible difference is that the LAN9118 doesn't support checksum
65
sysbus_init_irq(sbd, &s->wdogint);
54
offloading
66
+ s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK", NULL, NULL);
55
+- QEMU does not model the QSPI flash in MPS3 boards as real QSPI
67
56
+ flash, but only as simple ROM, so attempting to rewrite the flash
68
s->is_luminary = false;
57
+ from the guest will fail
69
s->id = cmsdk_apb_watchdog_id;
58
+- QEMU does not model the USB controller in MPS3 boards
70
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
71
72
static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
73
.name = "cmsdk-apb-watchdog",
74
- .version_id = 1,
75
- .minimum_version_id = 1,
76
+ .version_id = 2,
77
+ .minimum_version_id = 2,
78
.fields = (VMStateField[]) {
79
+ VMSTATE_CLOCK(wdogclk, CMSDKAPBWatchdog),
80
VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
81
VMSTATE_UINT32(control, CMSDKAPBWatchdog),
82
VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
83
--
59
--
84
2.20.1
60
2.20.1
85
61
86
62
diff view generated by jsdifflib
1
Create two input clocks on the ARMSSE devices, one for the normal
1
Update old infocenter.arm.com URLs to the equivalent developer.arm.com
2
MAINCLK, and one for the 32KHz S32KCLK, and wire these up to the
2
ones (the old URLs should redirect, but we might as well avoid the
3
appropriate devices. The old property-based clock frequency setting
3
redirection notice, and the new URLs are pleasantly shorter).
4
will remain in place until conversion is complete.
4
5
5
This commit covers the links to the MPS2 board TRM, the various
6
This is a migration compatibility break for machines mps2-an505,
6
Application Notes, the IoTKit and SSE-200 documents.
7
mps2-an521, musca-a, musca-b1.
8
7
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Luc Michel <luc@lmichel.fr>
10
Message-id: 20210215115138.20465-25-peter.maydell@linaro.org
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20210128114145.20536-12-peter.maydell@linaro.org
14
Message-id: 20210121190622.22000-12-peter.maydell@linaro.org
15
---
11
---
16
include/hw/arm/armsse.h | 6 ++++++
12
include/hw/arm/armsse.h | 4 ++--
17
hw/arm/armsse.c | 17 +++++++++++++++--
13
include/hw/misc/armsse-cpuid.h | 2 +-
18
2 files changed, 21 insertions(+), 2 deletions(-)
14
include/hw/misc/armsse-mhu.h | 2 +-
15
include/hw/misc/iotkit-secctl.h | 2 +-
16
include/hw/misc/iotkit-sysctl.h | 2 +-
17
include/hw/misc/iotkit-sysinfo.h | 2 +-
18
include/hw/misc/mps2-fpgaio.h | 2 +-
19
hw/arm/mps2-tz.c | 11 +++++------
20
hw/misc/armsse-cpuid.c | 2 +-
21
hw/misc/armsse-mhu.c | 2 +-
22
hw/misc/iotkit-sysctl.c | 2 +-
23
hw/misc/iotkit-sysinfo.c | 2 +-
24
hw/misc/mps2-fpgaio.c | 2 +-
25
hw/misc/mps2-scc.c | 2 +-
26
14 files changed, 19 insertions(+), 20 deletions(-)
19
27
20
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
28
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
21
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/armsse.h
30
--- a/include/hw/arm/armsse.h
23
+++ b/include/hw/arm/armsse.h
31
+++ b/include/hw/arm/armsse.h
24
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
25
* per-CPU identity and control register blocks
33
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
26
*
34
* SSE-200. Currently we model:
27
* QEMU interface:
35
* - the Arm IoT Kit which is documented in
28
+ * + Clock input "MAINCLK": clock for CPUs and most peripherals
36
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
29
+ * + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
37
+ * https://developer.arm.com/documentation/ecm0601256/latest
30
* + QOM property "memory" is a MemoryRegion containing the devices provided
38
* - the SSE-200 which is documented in
31
* by the board model.
39
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
32
* + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
40
+ * https://developer.arm.com/documentation/101104/latest/
33
@@ -XXX,XX +XXX,XX @@
41
*
34
#include "hw/misc/armsse-mhu.h"
42
* The IoTKit contains:
35
#include "hw/misc/unimp.h"
43
* a Cortex-M33
36
#include "hw/or-irq.h"
44
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
37
+#include "hw/clock.h"
45
index XXXXXXX..XXXXXXX 100644
38
#include "hw/core/split-irq.h"
46
--- a/include/hw/misc/armsse-cpuid.h
39
#include "hw/cpu/cluster.h"
47
+++ b/include/hw/misc/armsse-cpuid.h
40
#include "qom/object.h"
48
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
49
/*
42
50
* This is a model of the "CPU_IDENTITY" register block which is part of the
43
uint32_t nsccfg;
51
* Arm SSE-200 and documented in
44
52
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
45
+ Clock *mainclk;
53
+ * https://developer.arm.com/documentation/101104/latest/
46
+ Clock *s32kclk;
54
*
47
+
55
* QEMU interface:
48
/* Properties */
56
* + QOM property "CPUID": the value to use for the CPUID register
49
MemoryRegion *board_memory;
57
diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h
50
uint32_t exp_numirq;
58
index XXXXXXX..XXXXXXX 100644
51
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
59
--- a/include/hw/misc/armsse-mhu.h
52
index XXXXXXX..XXXXXXX 100644
60
+++ b/include/hw/misc/armsse-mhu.h
53
--- a/hw/arm/armsse.c
61
@@ -XXX,XX +XXX,XX @@
54
+++ b/hw/arm/armsse.c
62
/*
55
@@ -XXX,XX +XXX,XX @@
63
* This is a model of the Message Handling Unit (MHU) which is part of the
56
#include "hw/arm/armsse.h"
64
* Arm SSE-200 and documented in
57
#include "hw/arm/boot.h"
65
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
58
#include "hw/irq.h"
66
+ * https://developer.arm.com/documentation/101104/latest/
59
+#include "hw/qdev-clock.h"
67
*
60
68
* QEMU interface:
61
/* Format of the System Information block SYS_CONFIG register */
69
* + sysbus MMIO region 0: the system information register bank
62
typedef enum SysConfigFormat {
70
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
63
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
71
index XXXXXXX..XXXXXXX 100644
64
assert(info->sram_banks <= MAX_SRAM_BANKS);
72
--- a/include/hw/misc/iotkit-secctl.h
65
assert(info->num_cpus <= SSE_MAX_CPUS);
73
+++ b/include/hw/misc/iotkit-secctl.h
66
74
@@ -XXX,XX +XXX,XX @@
67
+ s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL);
75
68
+ s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
76
/* This is a model of the security controller which is part of the
69
+
77
* Arm IoT Kit and documented in
70
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
78
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
71
79
+ * https://developer.arm.com/documentation/ecm0601256/latest
72
for (i = 0; i < info->num_cpus; i++) {
80
*
73
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
81
* QEMU interface:
74
* map its upstream ends to the right place in the container.
82
* + sysbus MMIO region 0 is the "secure privilege control block" registers
75
*/
83
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
76
qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
84
index XXXXXXX..XXXXXXX 100644
77
+ qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
85
--- a/include/hw/misc/iotkit-sysctl.h
78
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
86
+++ b/include/hw/misc/iotkit-sysctl.h
79
return;
87
@@ -XXX,XX +XXX,XX @@
80
}
88
/*
81
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
89
* This is a model of the "system control element" which is part of the
82
&error_abort);
90
* Arm IoTKit and documented in
83
91
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
84
qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
92
+ * https://developer.arm.com/documentation/ecm0601256/latest
85
+ qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
93
* Specifically, it implements the "system information block" and
86
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
94
* "system control register" blocks.
87
return;
95
*
88
}
96
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
89
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
97
index XXXXXXX..XXXXXXX 100644
90
&error_abort);
98
--- a/include/hw/misc/iotkit-sysinfo.h
91
99
+++ b/include/hw/misc/iotkit-sysinfo.h
92
qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
100
@@ -XXX,XX +XXX,XX @@
93
+ qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
101
/*
94
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
102
* This is a model of the "system information block" which is part of the
95
return;
103
* Arm IoTKit and documented in
96
}
104
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
97
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
105
+ * https://developer.arm.com/documentation/ecm0601256/latest
98
* 0x4002f000: S32K timer
106
* QEMU interface:
99
*/
107
* + QOM property "SYS_VERSION": value to use for SYS_VERSION register
100
qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
108
* + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
101
+ qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
109
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
102
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
110
index XXXXXXX..XXXXXXX 100644
103
return;
111
--- a/include/hw/misc/mps2-fpgaio.h
104
}
112
+++ b/include/hw/misc/mps2-fpgaio.h
105
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
113
@@ -XXX,XX +XXX,XX @@
106
qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
114
/* This is a model of the FPGAIO register block in the AN505
107
115
* FPGA image for the MPS2 dev board; it is documented in the
108
qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
116
* application note:
109
+ qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
117
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
110
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
118
+ * https://developer.arm.com/documentation/dai0505/latest/
111
return;
119
*
112
}
120
* QEMU interface:
113
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
121
* + sysbus MMIO region 0: the register bank
114
/* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
122
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
115
123
index XXXXXXX..XXXXXXX 100644
116
qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
124
--- a/hw/arm/mps2-tz.c
117
+ qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
125
+++ b/hw/arm/mps2-tz.c
118
if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
126
@@ -XXX,XX +XXX,XX @@
119
return;
127
* https://developer.arm.com/products/system-design/development-boards/fpga-prototyping-boards/mps2
120
}
128
*
121
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
129
* Board TRM:
122
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
130
- * http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_06_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_06_en.pdf
123
131
+ * https://developer.arm.com/documentation/100112/latest/
124
qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
132
* Application Note AN505:
125
+ qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
133
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
126
if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
134
+ * https://developer.arm.com/documentation/dai0505/latest/
127
return;
135
* Application Note AN521:
128
}
136
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
129
@@ -XXX,XX +XXX,XX @@ static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
137
+ * https://developer.arm.com/documentation/dai0521/latest/
130
138
* Application Note AN524:
131
static const VMStateDescription armsse_vmstate = {
139
* https://developer.arm.com/documentation/dai0524/latest/
132
.name = "iotkit",
140
*
133
- .version_id = 1,
141
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
134
- .minimum_version_id = 1,
142
* (ARM ECM0601256) for the details of some of the device layout:
135
+ .version_id = 2,
143
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
136
+ .minimum_version_id = 2,
144
+ * https://developer.arm.com/documentation/ecm0601256/latest
137
.fields = (VMStateField[]) {
145
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
138
+ VMSTATE_CLOCK(mainclk, ARMSSE),
146
* most of the device layout:
139
+ VMSTATE_CLOCK(s32kclk, ARMSSE),
147
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
140
VMSTATE_UINT32(nsccfg, ARMSSE),
148
- *
141
VMSTATE_END_OF_LIST()
149
+ * https://developer.arm.com/documentation/101104/latest/
142
}
150
*/
151
152
#include "qemu/osdep.h"
153
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/misc/armsse-cpuid.c
156
+++ b/hw/misc/armsse-cpuid.c
157
@@ -XXX,XX +XXX,XX @@
158
/*
159
* This is a model of the "CPU_IDENTITY" register block which is part of the
160
* Arm SSE-200 and documented in
161
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
162
+ * https://developer.arm.com/documentation/101104/latest/
163
*
164
* It consists of one read-only CPUID register (set by QOM property), plus the
165
* usual ID registers.
166
diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/hw/misc/armsse-mhu.c
169
+++ b/hw/misc/armsse-mhu.c
170
@@ -XXX,XX +XXX,XX @@
171
/*
172
* This is a model of the Message Handling Unit (MHU) which is part of the
173
* Arm SSE-200 and documented in
174
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
175
+ * https://developer.arm.com/documentation/101104/latest/
176
*/
177
178
#include "qemu/osdep.h"
179
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
180
index XXXXXXX..XXXXXXX 100644
181
--- a/hw/misc/iotkit-sysctl.c
182
+++ b/hw/misc/iotkit-sysctl.c
183
@@ -XXX,XX +XXX,XX @@
184
/*
185
* This is a model of the "system control element" which is part of the
186
* Arm IoTKit and documented in
187
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
188
+ * https://developer.arm.com/documentation/ecm0601256/latest
189
* Specifically, it implements the "system control register" blocks.
190
*/
191
192
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/hw/misc/iotkit-sysinfo.c
195
+++ b/hw/misc/iotkit-sysinfo.c
196
@@ -XXX,XX +XXX,XX @@
197
/*
198
* This is a model of the "system information block" which is part of the
199
* Arm IoTKit and documented in
200
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
201
+ * https://developer.arm.com/documentation/ecm0601256/latest
202
* It consists of 2 read-only version/config registers, plus the
203
* usual ID registers.
204
*/
205
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/hw/misc/mps2-fpgaio.c
208
+++ b/hw/misc/mps2-fpgaio.c
209
@@ -XXX,XX +XXX,XX @@
210
/* This is a model of the "FPGA system control and I/O" block found
211
* in the AN505 FPGA image for the MPS2 devboard.
212
* It is documented in AN505:
213
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
214
+ * https://developer.arm.com/documentation/dai0505/latest/
215
*/
216
217
#include "qemu/osdep.h"
218
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/misc/mps2-scc.c
221
+++ b/hw/misc/mps2-scc.c
222
@@ -XXX,XX +XXX,XX @@
223
* found in the FPGA images of MPS2 development boards.
224
*
225
* Documentation of it can be found in the MPS2 TRM:
226
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100112_0100_03_en/index.html
227
+ * https://developer.arm.com/documentation/100112/latest/
228
* and also in the Application Notes documenting individual FPGA images.
229
*/
230
143
--
231
--
144
2.20.1
232
2.20.1
145
233
146
234
diff view generated by jsdifflib