1
First arm pullreq of 5.0!
1
The following changes since commit b7c359c748a2e3ccb97a184b9739feb2cd48de2f:
2
2
3
The following changes since commit 084a398bf8aa7634738e6c6c0103236ee1b3b72f:
3
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.0-pull-request' into staging (2020-01-23 14:38:43 +0000)
4
5
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-12-13 18:14:07 +0000)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191216-1
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200123
10
8
11
for you to fetch changes up to f80741d107673f162e3b097fc76a1590036cc9d1:
9
for you to fetch changes up to 53c75ad8e72dc3a5102de7ed21e4990969cb0a19:
12
10
13
target/arm: ensure we use current exception state after SCR update (2019-12-16 10:52:58 +0000)
11
hw/arm/exynos4210: Connect serial port DMA busy signals with pl330 (2020-01-23 15:22:42 +0000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
target-arm queue:
14
target-arm queue:
17
* Add support for Cortex-M7 CPU
15
* fix bug in PAuth emulation
18
* exynos4210_gic: Suppress gcc9 format-truncation warnings
16
* add PMU to Cortex-R5, Cortex-R5F
19
* aspeed: Various minor bug fixes and improvements
17
* qemu-nbd: Convert documentation to rST
20
* aspeed: Add support for the tacoma-bmc board
18
* qemu-block-drivers: Convert documentation to rST
21
* Honour HCR_EL32.TID1 and .TID2 trapping requirements
19
* Fix Exynos4210 UART DMA support
22
* Handle trapping to EL2 of AArch32 VMRS instructions
20
* Various minor code cleanups
23
* Handle AArch32 CP15 trapping via HSTR_EL2
24
* Add support for missing Jazelle system registers
25
* arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on
26
* Add support for DC CVAP & DC CVADP instructions
27
* Fix assertion when SCR.NS is changed in Secure-SVC &c
28
* enable SHPC native hot plug in arm ACPI
29
21
30
----------------------------------------------------------------
22
----------------------------------------------------------------
31
Alex Bennée (1):
23
Andrew Jones (1):
32
target/arm: ensure we use current exception state after SCR update
24
target/arm/arch_dump: Add SVE notes
33
25
34
Beata Michalska (4):
26
Clement Deschamps (1):
35
tcg: cputlb: Add probe_read
27
target/arm: add PMU feature to cortex-r5 and cortex-r5f
36
Memory: Enable writeback for given memory region
37
migration: ram: Switch to ram block writeback
38
target/arm: Add support for DC CVAP & DC CVADP ins
39
28
40
Christophe Lyon (1):
29
Guenter Roeck (8):
41
target/arm: Add support for cortex-m7 CPU
30
dma/pl330: Convert to support tracing
31
hw/core/or-irq: Increase limit of or-lines to 48
32
hw/arm/exynos4210: Fix DMA initialization
33
hw/char/exynos4210_uart: Convert to support tracing
34
hw/char/exynos4210_uart: Implement post_load function
35
hw/char/exynos4210_uart: Implement Rx FIFO level triggers and timeouts
36
hw/char/exynos4210_uart: Add receive DMA support
37
hw/arm/exynos4210: Connect serial port DMA busy signals with pl330
42
38
43
Cédric Le Goater (12):
39
Keqian Zhu (2):
44
aspeed/i2c: Add support for pool buffer transfers
40
hw/acpi: Remove extra indent in ACPI GED hotplug cb
45
aspeed/i2c: Check SRAM enablement on AST2500
41
hw/arm: Use helper function to trigger hotplug handler plug
46
aspeed: Add a DRAM memory region at the SoC level
47
aspeed/i2c: Add support for DMA transfers
48
aspeed/i2c: Add trace events
49
aspeed/smc: Restore default AHB window mapping at reset
50
aspeed/smc: Do not map disabled segment on the AST2600
51
aspeed/smc: Add AST2600 timings registers
52
aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass
53
aspeed: Add support for the tacoma-bmc board
54
aspeed: Change the "scu" property definition
55
aspeed: Change the "nic" property definition
56
42
57
David Gibson (1):
43
Peter Maydell (3):
58
exynos4210_gic: Suppress gcc9 format-truncation warnings
44
qemu-nbd: Convert invocation documentation to rST
45
docs: Create stub system manual
46
qemu-block-drivers: Convert to rST
59
47
60
Heyi Guo (2):
48
Philippe Mathieu-Daudé (1):
61
hw/arm/acpi: simplify AML bit and/or statement
49
hw/misc/stm32f4xx_syscfg: Fix copy/paste error
62
hw/arm/acpi: enable SHPC native hot plug
63
50
64
Joel Stanley (4):
51
Richard Henderson (3):
65
aspeed/sdmc: Make ast2600 default 1G
52
tests/tcg/aarch64: Fix compilation parameters for pauth-%
66
aspeed/scu: Fix W1C behavior
53
tests/tcg/aarch64: Add pauth-3
67
watchdog/aspeed: Improve watchdog timeout message
54
tests/tcg/aarch64: Add pauth-4
68
watchdog/aspeed: Fix AST2600 frequency behaviour
69
55
70
Marc Zyngier (5):
56
Vincent Dehors (1):
71
target/arm: Honor HCR_EL2.TID2 trapping requirements
57
target/arm: Fix PAuth sbox functions
72
target/arm: Honor HCR_EL2.TID1 trapping requirements
73
target/arm: Handle trapping to EL2 of AArch32 VMRS instructions
74
target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
75
target/arm: Add support for missing Jazelle system registers
76
58
77
Niek Linnenbank (1):
59
Makefile | 37 +-
78
arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on()
60
tests/tcg/aarch64/Makefile.softmmu-target | 5 +-
61
tests/tcg/aarch64/Makefile.target | 3 +-
62
include/elf.h | 1 +
63
include/hw/arm/exynos4210.h | 4 +
64
include/hw/or-irq.h | 2 +-
65
target/arm/cpu.h | 25 +
66
hw/acpi/generic_event_device.c | 2 +-
67
hw/arm/exynos4210.c | 77 ++-
68
hw/arm/virt.c | 6 +-
69
hw/char/exynos4210_uart.c | 245 +++++---
70
hw/dma/pl330.c | 88 +--
71
hw/misc/stm32f4xx_syscfg.c | 2 +-
72
target/arm/arch_dump.c | 124 +++-
73
target/arm/cpu.c | 1 +
74
target/arm/kvm64.c | 24 -
75
target/arm/pauth_helper.c | 4 +-
76
tests/tcg/aarch64/pauth-1.c | 2 -
77
tests/tcg/aarch64/pauth-2.c | 2 -
78
tests/tcg/aarch64/pauth-4.c | 25 +
79
tests/tcg/aarch64/system/pauth-3.c | 40 ++
80
MAINTAINERS | 1 +
81
docs/index.html.in | 1 +
82
docs/interop/conf.py | 4 +-
83
docs/interop/index.rst | 1 +
84
docs/interop/qemu-nbd.rst | 263 ++++++++
85
docs/interop/qemu-option-trace.rst.inc | 30 +
86
docs/qemu-block-drivers.texi | 889 ---------------------------
87
docs/system/conf.py | 22 +
88
docs/system/index.rst | 17 +
89
docs/system/qemu-block-drivers.rst | 985 ++++++++++++++++++++++++++++++
90
hw/char/trace-events | 20 +
91
hw/dma/trace-events | 24 +
92
qemu-doc.texi | 18 -
93
qemu-nbd.texi | 214 -------
94
qemu-option-trace.texi | 4 +
95
qemu-options.hx | 2 +-
96
37 files changed, 1897 insertions(+), 1317 deletions(-)
97
create mode 100644 tests/tcg/aarch64/pauth-4.c
98
create mode 100644 tests/tcg/aarch64/system/pauth-3.c
99
create mode 100644 docs/interop/qemu-nbd.rst
100
create mode 100644 docs/interop/qemu-option-trace.rst.inc
101
delete mode 100644 docs/qemu-block-drivers.texi
102
create mode 100644 docs/system/conf.py
103
create mode 100644 docs/system/index.rst
104
create mode 100644 docs/system/qemu-block-drivers.rst
105
delete mode 100644 qemu-nbd.texi
79
106
80
PanNengyuan (1):
81
gpio: fix memory leak in aspeed_gpio_init()
82
83
Philippe Mathieu-Daudé (2):
84
hw/arm/sbsa-ref: Simplify by moving the gic in the machine state
85
hw/arm/virt: Simplify by moving the gic in the machine state
86
87
include/exec/exec-all.h | 6 +
88
include/exec/memory.h | 6 +
89
include/exec/ram_addr.h | 8 +
90
include/hw/arm/aspeed.h | 24 +--
91
include/hw/arm/aspeed_soc.h | 1 +
92
include/hw/arm/virt.h | 1 +
93
include/hw/i2c/aspeed_i2c.h | 16 ++
94
include/hw/ssi/aspeed_smc.h | 1 +
95
include/hw/watchdog/wdt_aspeed.h | 1 +
96
include/qemu/cutils.h | 1 +
97
target/arm/cpu.h | 20 +-
98
target/arm/helper.h | 3 +
99
target/arm/translate.h | 2 +
100
exec.c | 36 ++++
101
hw/arm/aspeed.c | 271 +++++++++++++----------
102
hw/arm/aspeed_ast2600.c | 25 ++-
103
hw/arm/aspeed_soc.c | 22 +-
104
hw/arm/sbsa-ref.c | 86 ++++----
105
hw/arm/virt-acpi-build.c | 21 +-
106
hw/arm/virt.c | 109 +++++-----
107
hw/gpio/aspeed_gpio.c | 1 +
108
hw/i2c/aspeed_i2c.c | 439 +++++++++++++++++++++++++++++++++++---
109
hw/intc/exynos4210_gic.c | 9 +-
110
hw/misc/aspeed_scu.c | 19 +-
111
hw/misc/aspeed_sdmc.c | 6 +-
112
hw/net/ftgmac100.c | 19 +-
113
hw/ssi/aspeed_smc.c | 63 ++++--
114
hw/timer/aspeed_timer.c | 17 +-
115
hw/watchdog/wdt_aspeed.c | 41 ++--
116
linux-user/elfload.c | 2 +
117
memory.c | 12 ++
118
migration/ram.c | 5 +-
119
target/arm/arm-powerctl.c | 3 +
120
target/arm/cpu.c | 33 +++
121
target/arm/cpu64.c | 1 +
122
target/arm/helper.c | 170 ++++++++++++++-
123
target/arm/op_helper.c | 22 ++
124
target/arm/translate-vfp.inc.c | 20 +-
125
target/arm/translate.c | 9 +-
126
target/arm/vfp_helper.c | 29 +++
127
util/cutils.c | 38 ++++
128
hw/i2c/trace-events | 9 +
129
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
130
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
131
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
132
45 files changed, 1273 insertions(+), 354 deletions(-)
133
diff view generated by jsdifflib
1
From: Christophe Lyon <christophe.lyon@linaro.org>
1
From: Clement Deschamps <clement.deschamps@greensocs.com>
2
2
3
This is derived from cortex-m4 description, adding DP support and FPv5
3
The PMU is not optional on cortex-r5 and cortex-r5f (see
4
instructions with the corresponding flags in isar and mvfr2.
4
the "Features" chapter of the Technical Reference Manual).
5
5
6
Checked that it could successfully execute
6
Signed-off-by: Clement Deschamps <clement.deschamps@greensocs.com>
7
vrinta.f32 s15, s15
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
while cortex-m4 emulation rejects it with "illegal instruction".
8
Message-id: 20200114105918.2366370-1-clement.deschamps@greensocs.com
9
10
Signed-off-by: Christophe Lyon <christophe.lyon@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20191025090841.10299-1-christophe.lyon@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++++++
11
target/arm/cpu.c | 1 +
17
1 file changed, 33 insertions(+)
12
1 file changed, 1 insertion(+)
18
13
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
24
cpu->isar.id_isar6 = 0x00000000;
19
set_feature(&cpu->env, ARM_FEATURE_V7);
25
}
20
set_feature(&cpu->env, ARM_FEATURE_V7MP);
26
21
set_feature(&cpu->env, ARM_FEATURE_PMSA);
27
+static void cortex_m7_initfn(Object *obj)
22
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
28
+{
23
cpu->midr = 0x411fc153; /* r1p3 */
29
+ ARMCPU *cpu = ARM_CPU(obj);
24
cpu->id_pfr0 = 0x0131;
30
+
25
cpu->id_pfr1 = 0x001;
31
+ set_feature(&cpu->env, ARM_FEATURE_V7);
32
+ set_feature(&cpu->env, ARM_FEATURE_M);
33
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
34
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
35
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
36
+ cpu->midr = 0x411fc272; /* r1p2 */
37
+ cpu->pmsav7_dregion = 8;
38
+ cpu->isar.mvfr0 = 0x10110221;
39
+ cpu->isar.mvfr1 = 0x12000011;
40
+ cpu->isar.mvfr2 = 0x00000040;
41
+ cpu->id_pfr0 = 0x00000030;
42
+ cpu->id_pfr1 = 0x00000200;
43
+ cpu->id_dfr0 = 0x00100000;
44
+ cpu->id_afr0 = 0x00000000;
45
+ cpu->id_mmfr0 = 0x00100030;
46
+ cpu->id_mmfr1 = 0x00000000;
47
+ cpu->id_mmfr2 = 0x01000000;
48
+ cpu->id_mmfr3 = 0x00000000;
49
+ cpu->isar.id_isar0 = 0x01101110;
50
+ cpu->isar.id_isar1 = 0x02112000;
51
+ cpu->isar.id_isar2 = 0x20232231;
52
+ cpu->isar.id_isar3 = 0x01111131;
53
+ cpu->isar.id_isar4 = 0x01310132;
54
+ cpu->isar.id_isar5 = 0x00000000;
55
+ cpu->isar.id_isar6 = 0x00000000;
56
+}
57
+
58
static void cortex_m33_initfn(Object *obj)
59
{
60
ARMCPU *cpu = ARM_CPU(obj);
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
62
.class_init = arm_v7m_class_init },
63
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
64
.class_init = arm_v7m_class_init },
65
+ { .name = "cortex-m7", .initfn = cortex_m7_initfn,
66
+ .class_init = arm_v7m_class_init },
67
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
68
.class_init = arm_v7m_class_init },
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
--
26
--
71
2.20.1
27
2.20.1
72
28
73
29
diff view generated by jsdifflib
Deleted patch
1
From: David Gibson <david@gibson.dropbear.id.au>
2
1
3
exynos4210_gic_realize() prints the number of cpus into some temporary
4
buffers, but it only allows 3 bytes space for it. That's plenty:
5
existing machines will only ever set this value to EXYNOS4210_NCPUS
6
(2). But the compiler can't always figure that out, so some[*] gcc9
7
versions emit -Wformat-truncation warnings.
8
9
We can fix that by hinting the constraint to the compiler with a
10
suitably placed assert().
11
12
[*] The bizarre thing here, is that I've long gotten these warnings
13
compiling in a 32-bit x86 container as host - Fedora 30 with
14
gcc-9.2.1-1.fc30.i686 - but it compiles just fine on my normal
15
x86_64 host - Fedora 30 with and gcc-9.2.1-1.fc30.x86_64.
16
17
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
[PMM: deleted stray blank line]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/intc/exynos4210_gic.c | 9 ++++++++-
24
1 file changed, 8 insertions(+), 1 deletion(-)
25
26
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/exynos4210_gic.c
29
+++ b/hw/intc/exynos4210_gic.c
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
31
char cpu_alias_name[sizeof(cpu_prefix) + 3];
32
char dist_alias_name[sizeof(cpu_prefix) + 3];
33
SysBusDevice *gicbusdev;
34
+ uint32_t n = s->num_cpu;
35
uint32_t i;
36
37
s->gic = qdev_create(NULL, "arm_gic");
38
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
39
memory_region_init(&s->dist_container, obj, "exynos4210-dist-container",
40
EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);
41
42
- for (i = 0; i < s->num_cpu; i++) {
43
+ /*
44
+ * This clues in gcc that our on-stack buffers do, in fact have
45
+ * enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
46
+ * doesn't figure this out, otherwise and gives spurious warnings.
47
+ */
48
+ assert(n <= EXYNOS4210_NCPUS);
49
+ for (i = 0; i < n; i++) {
50
/* Map CPU interface per SMP Core */
51
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
52
memory_region_init_alias(&s->cpu_alias[i], obj,
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Vincent Dehors <vincent.dehors@smile.fr>
2
2
3
This change ensures that the FPU can be accessed in Non-Secure mode
3
In the PAC computation, sbox was applied over wrong bits.
4
when the CPU core is reset using the arm_set_cpu_on() function call.
4
As this is a 4-bit sbox, bit index should be incremented by 4 instead of 16.
5
The NSACR.{CP11,CP10} bits define the exception level required to
6
access the FPU in Non-Secure mode. Without these bits set, the CPU
7
will give an undefined exception trap on the first FPU access for the
8
secondary cores under Linux.
9
5
10
This is necessary because in this power-control codepath QEMU
6
Test vector from QARMA paper (https://eprint.iacr.org/2016/444.pdf) was
11
is effectively emulating a bit of EL3 firmware, and has to set
7
used to verify one computation of the pauth_computepac() function which
12
the CPU up as the EL3 firmware would.
8
uses sbox2.
13
9
14
Fixes: fc1120a7f5
10
Launchpad: https://bugs.launchpad.net/bugs/1859713
15
Cc: qemu-stable@nongnu.org
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
12
Signed-off-by: Vincent DEHORS <vincent.dehors@smile.fr>
17
[PMM: added clarifying para to commit message]
13
Signed-off-by: Adrien GRASSEIN <adrien.grassein@smile.fr>
14
Message-id: 20200116230809.19078-2-richard.henderson@linaro.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
17
---
21
target/arm/arm-powerctl.c | 3 +++
18
target/arm/pauth_helper.c | 4 ++--
22
1 file changed, 3 insertions(+)
19
1 file changed, 2 insertions(+), 2 deletions(-)
23
20
24
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
21
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/arm-powerctl.c
23
--- a/target/arm/pauth_helper.c
27
+++ b/target/arm/arm-powerctl.c
24
+++ b/target/arm/pauth_helper.c
28
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
25
@@ -XXX,XX +XXX,XX @@ static uint64_t pac_sub(uint64_t i)
29
/* Processor is not in secure mode */
26
uint64_t o = 0;
30
target_cpu->env.cp15.scr_el3 |= SCR_NS;
27
int b;
31
28
32
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
29
- for (b = 0; b < 64; b += 16) {
33
+ target_cpu->env.cp15.nsacr |= 3 << 10;
30
+ for (b = 0; b < 64; b += 4) {
34
+
31
o |= (uint64_t)sub[(i >> b) & 0xf] << b;
35
/*
32
}
36
* If QEMU is providing the equivalent of EL3 firmware, then we need
33
return o;
37
* to make sure a CPU targeting EL2 comes out of reset with a
34
@@ -XXX,XX +XXX,XX @@ static uint64_t pac_inv_sub(uint64_t i)
35
uint64_t o = 0;
36
int b;
37
38
- for (b = 0; b < 64; b += 16) {
39
+ for (b = 0; b < 64; b += 4) {
40
o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b;
41
}
42
return o;
38
--
43
--
39
2.20.1
44
2.20.1
40
45
41
46
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
A write to the SCR can change the effective EL by droppping the system
3
We were incorrectly requiring ARMv8.4 support for the pauth
4
from secure to non-secure mode. However if we use a cached current_el
4
tests, but Pointer Authentication is an ARMv8.3 extension.
5
from before the change we'll rebuild the flags incorrectly. To fix
5
Further, hiding the required architecture within asm() is
6
this we introduce the ARM_CP_NEWEL CP flag to indicate the new EL
6
not correct.
7
should be used when recomputing the flags.
8
7
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Correct the architecture version requested, and specify it
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
in the cflags of the (cross-) compiler rather than in the asm.
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
12
Message-id: 20191212114734.6962-1-alex.bennee@linaro.org
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Cc: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Message-Id: <20191209143723.6368-1-alex.bennee@linaro.org>
13
Message-id: 20200116230809.19078-3-richard.henderson@linaro.org
15
Cc: qemu-stable@nongnu.org
14
[PMM: tweaked commit message]
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
16
---
18
target/arm/cpu.h | 8 ++++++--
17
tests/tcg/aarch64/Makefile.target | 1 +
19
target/arm/helper.h | 1 +
18
tests/tcg/aarch64/pauth-1.c | 2 --
20
target/arm/helper.c | 14 +++++++++++++-
19
tests/tcg/aarch64/pauth-2.c | 2 --
21
target/arm/translate.c | 6 +++++-
20
3 files changed, 1 insertion(+), 4 deletions(-)
22
4 files changed, 25 insertions(+), 4 deletions(-)
23
21
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
25
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.h
24
--- a/tests/tcg/aarch64/Makefile.target
27
+++ b/target/arm/cpu.h
25
+++ b/tests/tcg/aarch64/Makefile.target
28
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
26
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
29
* RAISES_EXC is for when the read or write hook might raise an exception;
27
# Pauth Tests
30
* the generated code will synchronize the CPU state before calling the hook
28
AARCH64_TESTS += pauth-1 pauth-2
31
* so that it is safe for the hook to call raise_exception().
29
run-pauth-%: QEMU_OPTS += -cpu max
32
+ * NEWEL is for writes to registers that might change the exception
30
+pauth-%: CFLAGS += -march=armv8.3-a
33
+ * level - typically on older ARM chips. For those cases we need to
31
34
+ * re-read the new el when recomputing the translation flags.
32
# Semihosting smoke test for linux-user
35
*/
33
AARCH64_TESTS += semihosting
36
#define ARM_CP_SPECIAL 0x0001
34
diff --git a/tests/tcg/aarch64/pauth-1.c b/tests/tcg/aarch64/pauth-1.c
37
#define ARM_CP_CONST 0x0002
38
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
39
#define ARM_CP_SVE 0x2000
40
#define ARM_CP_NO_GDB 0x4000
41
#define ARM_CP_RAISES_EXC 0x8000
42
+#define ARM_CP_NEWEL 0x10000
43
/* Used only as a terminator for ARMCPRegInfo lists */
44
-#define ARM_CP_SENTINEL 0xffff
45
+#define ARM_CP_SENTINEL 0xfffff
46
/* Mask of only the flag bits in a type field */
47
-#define ARM_CP_FLAG_MASK 0xf0ff
48
+#define ARM_CP_FLAG_MASK 0x1f0ff
49
50
/* Valid values for ARMCPRegInfo state field, indicating which of
51
* the AArch32 and AArch64 execution states this register is visible in.
52
diff --git a/target/arm/helper.h b/target/arm/helper.h
53
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.h
36
--- a/tests/tcg/aarch64/pauth-1.c
55
+++ b/target/arm/helper.h
37
+++ b/tests/tcg/aarch64/pauth-1.c
56
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_user_reg, i32, env, i32)
38
@@ -XXX,XX +XXX,XX @@
57
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
39
#include <sys/prctl.h>
58
40
#include <stdio.h>
59
DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
41
60
+DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, void, env)
42
-asm(".arch armv8.4-a");
61
DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
43
-
62
DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
44
#ifndef PR_PAC_RESET_KEYS
63
45
#define PR_PAC_RESET_KEYS 54
64
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
#define PR_PAC_APDAKEY (1 << 2)
47
diff --git a/tests/tcg/aarch64/pauth-2.c b/tests/tcg/aarch64/pauth-2.c
65
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/helper.c
49
--- a/tests/tcg/aarch64/pauth-2.c
67
+++ b/target/arm/helper.c
50
+++ b/tests/tcg/aarch64/pauth-2.c
68
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
51
@@ -XXX,XX +XXX,XX @@
69
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
52
#include <stdint.h>
70
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
53
#include <assert.h>
71
.resetvalue = 0, .writefn = scr_write },
54
72
- { .name = "SCR", .type = ARM_CP_ALIAS,
55
-asm(".arch armv8.4-a");
73
+ { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
56
-
74
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
57
void do_test(uint64_t value)
75
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
76
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
77
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
78
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
79
}
80
81
+/*
82
+ * If we have triggered a EL state change we can't rely on the
83
+ * translator having passed it too us, we need to recompute.
84
+ */
85
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
86
+{
87
+ int el = arm_current_el(env);
88
+ int fp_el = fp_exception_el(env, el);
89
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
90
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
91
+}
92
+
93
void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
94
{
58
{
95
int fp_el = fp_exception_el(env, el);
59
uint64_t salt1, salt2;
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
101
if (arm_dc_feature(s, ARM_FEATURE_M)) {
102
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
103
} else {
104
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
105
+ if (ri->type & ARM_CP_NEWEL) {
106
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
107
+ } else {
108
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
109
+ }
110
}
111
tcg_temp_free_i32(tcg_el);
112
/*
113
--
60
--
114
2.20.1
61
2.20.1
115
62
116
63
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
ARMv8.2 introduced support for Data Cache Clean instructions
3
This is the test vector from the QARMA paper, run through PACGA.
4
to PoP (point-of-persistence) - DC CVAP and PoDP (point-of-deep-persistence)
5
- DV CVADP. Both specify conceptual points in a memory system where all writes
6
that are to reach them are considered persistent.
7
The support provided considers both to be actually the same so there is no
8
distinction between the two. If none is available (there is no backing store
9
for given memory) both will result in Data Cache Clean up to the point of
10
coherency. Otherwise sync for the specified range shall be performed.
11
4
12
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
5
Suggested-by: Vincent Dehors <vincent.dehors@smile.fr>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191121000843.24844-5-beata.michalska@linaro.org
7
Message-id: 20200116230809.19078-4-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
9
---
17
target/arm/cpu.h | 10 ++++++++
10
tests/tcg/aarch64/Makefile.softmmu-target | 5 ++-
18
linux-user/elfload.c | 2 ++
11
tests/tcg/aarch64/system/pauth-3.c | 40 +++++++++++++++++++++++
19
target/arm/cpu64.c | 1 +
12
2 files changed, 44 insertions(+), 1 deletion(-)
20
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
13
create mode 100644 tests/tcg/aarch64/system/pauth-3.c
21
4 files changed, 69 insertions(+)
22
14
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
17
--- a/tests/tcg/aarch64/Makefile.softmmu-target
26
+++ b/target/arm/cpu.h
18
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ run-memory-replay: memory-replay run-memory-record
28
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
20
          $(QEMU_OPTS) memory, \
29
}
21
     "$< on $(TARGET_NAME)")
30
22
31
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
23
-EXTRA_TESTS+=memory-record memory-replay
24
+run-pauth-3: pauth-3
25
+pauth-3: CFLAGS += -march=armv8.3-a
26
+
27
+EXTRA_TESTS+=memory-record memory-replay pauth-3
28
diff --git a/tests/tcg/aarch64/system/pauth-3.c b/tests/tcg/aarch64/system/pauth-3.c
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/tests/tcg/aarch64/system/pauth-3.c
33
@@ -XXX,XX +XXX,XX @@
34
+#include <inttypes.h>
35
+#include <minilib.h>
36
+
37
+int main()
32
+{
38
+{
33
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
39
+ /*
34
+}
40
+ * Test vector from QARMA paper (https://eprint.iacr.org/2016/444.pdf)
41
+ * to verify one computation of the pauth_computepac() function,
42
+ * which uses sbox2.
43
+ *
44
+ * Use PACGA, because it returns the most bits from ComputePAC.
45
+ * We still only get the most significant 32-bits of the result.
46
+ */
35
+
47
+
36
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
48
+ static const uint64_t d[5] = {
37
+{
49
+ 0xfb623599da6e8127ull,
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
50
+ 0x477d469dec0b8762ull,
39
+}
51
+ 0x84be85ce9804e94bull,
52
+ 0xec2802d4e0a488e9ull,
53
+ 0xc003b93999b33765ull & 0xffffffff00000000ull
54
+ };
55
+ uint64_t r;
40
+
56
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
57
+ asm("msr apgakeyhi_el1, %[w0]\n\t"
42
{
58
+ "msr apgakeylo_el1, %[k0]\n\t"
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
59
+ "pacga %[r], %[P], %[T]"
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
60
+ : [r] "=r"(r)
45
index XXXXXXX..XXXXXXX 100644
61
+ : [P] "r" (d[0]),
46
--- a/linux-user/elfload.c
62
+ [T] "r" (d[1]),
47
+++ b/linux-user/elfload.c
63
+ [w0] "r" (d[2]),
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
64
+ [k0] "r" (d[3]));
49
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
50
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
51
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
52
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
53
54
return hwcaps;
55
}
56
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
57
ARMCPU *cpu = ARM_CPU(thread_cpu);
58
uint32_t hwcaps = 0;
59
60
+ GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
61
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
62
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
63
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
cpu->isar.id_aa64isar0 = t;
70
71
t = cpu->isar.id_aa64isar1;
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
74
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
75
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
76
diff --git a/target/arm/helper.c b/target/arm/helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/helper.c
79
+++ b/target/arm/helper.c
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
81
.access = PL0_R, .readfn = rndr_readfn },
82
REGINFO_SENTINEL
83
};
84
+
65
+
85
+#ifndef CONFIG_USER_ONLY
66
+ if (r == d[4]) {
86
+static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
67
+ ml_printf("OK\n");
87
+ uint64_t value)
68
+ return 0;
88
+{
69
+ } else {
89
+ ARMCPU *cpu = env_archcpu(env);
70
+ ml_printf("FAIL: %lx != %lx\n", r, d[4]);
90
+ /* CTR_EL0 System register -> DminLine, bits [19:16] */
71
+ return 1;
91
+ uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
92
+ uint64_t vaddr_in = (uint64_t) value;
93
+ uint64_t vaddr = vaddr_in & ~(dline_size - 1);
94
+ void *haddr;
95
+ int mem_idx = cpu_mmu_index(env, false);
96
+
97
+ /* This won't be crossing page boundaries */
98
+ haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
99
+ if (haddr) {
100
+
101
+ ram_addr_t offset;
102
+ MemoryRegion *mr;
103
+
104
+ /* RCU lock is already being held */
105
+ mr = memory_region_from_host(haddr, &offset);
106
+
107
+ if (mr) {
108
+ memory_region_do_writeback(mr, offset, dline_size);
109
+ }
110
+ }
72
+ }
111
+}
73
+}
112
+
113
+static const ARMCPRegInfo dcpop_reg[] = {
114
+ { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
115
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
116
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
117
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
118
+ REGINFO_SENTINEL
119
+};
120
+
121
+static const ARMCPRegInfo dcpodp_reg[] = {
122
+ { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
123
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
124
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
125
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
126
+ REGINFO_SENTINEL
127
+};
128
+#endif /*CONFIG_USER_ONLY*/
129
+
130
#endif
131
132
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
133
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
134
if (cpu_isar_feature(aa64_rndr, cpu)) {
135
define_arm_cp_regs(cpu, rndr_reginfo);
136
}
137
+#ifndef CONFIG_USER_ONLY
138
+ /* Data Cache clean instructions up to PoP */
139
+ if (cpu_isar_feature(aa64_dcpop, cpu)) {
140
+ define_one_arm_cp_reg(cpu, dcpop_reg);
141
+
142
+ if (cpu_isar_feature(aa64_dcpodp, cpu)) {
143
+ define_one_arm_cp_reg(cpu, dcpodp_reg);
144
+ }
145
+ }
146
+#endif /*CONFIG_USER_ONLY*/
147
#endif
148
149
/*
150
--
74
--
151
2.20.1
75
2.20.1
152
76
153
77
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
After the introduction of generic PCIe root port and PCIe-PCI bridge,
3
Perform the set of operations and test described in LP 1859713.
4
we will also have SHPC controller on ARM, so just enable SHPC native
5
hot plug.
6
4
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
5
Suggested-by: Adrien GRASSEIN <adrien.grassein@smile.fr>
8
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
7
Message-id: 20200116230809.19078-5-richard.henderson@linaro.org
10
Cc: Peter Maydell <peter.maydell@linaro.org>
8
[PMM: fixed hard-coded tabs]
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
12
Cc: Igor Mammedov <imammedo@redhat.com>
13
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-3-guoheyi@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
hw/arm/virt-acpi-build.c | 7 ++++++-
11
tests/tcg/aarch64/Makefile.target | 2 +-
20
tests/data/acpi/virt/DSDT | Bin 18462 -> 18462 bytes
12
tests/tcg/aarch64/pauth-4.c | 25 +++++++++++++++++++++++++
21
tests/data/acpi/virt/DSDT.memhp | Bin 19799 -> 19799 bytes
13
2 files changed, 26 insertions(+), 1 deletion(-)
22
tests/data/acpi/virt/DSDT.numamem | Bin 18462 -> 18462 bytes
14
create mode 100644 tests/tcg/aarch64/pauth-4.c
23
4 files changed, 6 insertions(+), 1 deletion(-)
24
15
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
16
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
18
--- a/tests/tcg/aarch64/Makefile.target
28
+++ b/hw/arm/virt-acpi-build.c
19
+++ b/tests/tcg/aarch64/Makefile.target
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
20
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
21
    $(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref)
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
22
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
23
# Pauth Tests
33
- aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
24
-AARCH64_TESTS += pauth-1 pauth-2
25
+AARCH64_TESTS += pauth-1 pauth-2 pauth-4
26
run-pauth-%: QEMU_OPTS += -cpu max
27
pauth-%: CFLAGS += -march=armv8.3-a
28
29
diff --git a/tests/tcg/aarch64/pauth-4.c b/tests/tcg/aarch64/pauth-4.c
30
new file mode 100644
31
index XXXXXXX..XXXXXXX
32
--- /dev/null
33
+++ b/tests/tcg/aarch64/pauth-4.c
34
@@ -XXX,XX +XXX,XX @@
35
+#include <stdint.h>
36
+#include <assert.h>
34
+
37
+
35
+ /*
38
+int main()
36
+ * Allow OS control for all 5 features:
39
+{
37
+ * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
40
+ uintptr_t x, y;
38
+ */
41
+
39
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
42
+ asm("mov %0, lr\n\t"
40
aml_name("CTRL")));
43
+ "pacia %0, sp\n\t" /* sigill if pauth not supported */
41
44
+ "eor %0, %0, #4\n\t" /* corrupt single bit */
42
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
45
+ "mov %1, %0\n\t"
43
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
46
+ "autia %1, sp\n\t" /* validate corrupted pointer */
44
index XXXXXXX..XXXXXXX 100644
47
+ "xpaci %0\n\t" /* strip pac from corrupted pointer */
45
GIT binary patch
48
+ : "=r"(x), "=r"(y));
46
delta 28
49
+
47
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
50
+ /*
48
51
+ * Once stripped, the corrupted pointer is of the form 0x0000...wxyz.
49
delta 28
52
+ * We expect the autia to indicate failure, producing a pointer of the
50
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
53
+ * form 0x000e....wxyz. Use xpaci and != for the test, rather than
51
54
+ * extracting explicit bits from the top, because the location of the
52
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
55
+ * error code "e" depends on the configuration of virtual memory.
53
index XXXXXXX..XXXXXXX 100644
56
+ */
54
GIT binary patch
57
+ assert(x != y);
55
delta 28
58
+ return 0;
56
kcmcaUi}Cs_MlP3NmymE@1_mbija=*8809zbbeqQp0Eq|*2mk;8
59
+}
57
58
delta 28
59
kcmcaUi}Cs_MlP3NmymE@1_ma@ja=*87-cu_beqQp0ErX{2mk;8
60
61
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
62
index XXXXXXX..XXXXXXX 100644
63
GIT binary patch
64
delta 28
65
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
66
67
delta 28
68
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
69
70
--
60
--
71
2.20.1
61
2.20.1
72
62
73
63
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: Keqian Zhu <zhukeqian1@huawei.com>
2
2
3
The last argument of AML bit and/or statement is the target variable,
3
There is extra indent in ACPI GED hotplug cb that should be
4
so we don't need to use a NULL target and then an additional store
4
deleted.
5
operation; using just aml_and() or aml_or() statement is enough.
6
5
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
8
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
12
Cc: Igor Mammedov <imammedo@redhat.com>
13
Suggested-by: Igor Mammedov <imammedo@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
6
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
7
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
16
Message-id: 20191209063719.23086-2-guoheyi@huawei.com
8
Message-id: 20200120012755.44581-2-zhukeqian1@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
hw/arm/virt-acpi-build.c | 16 ++++++++--------
11
hw/acpi/generic_event_device.c | 2 +-
20
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
12
1 file changed, 1 insertion(+), 1 deletion(-)
21
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
22
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
23
4 files changed, 8 insertions(+), 8 deletions(-)
24
13
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
14
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
16
--- a/hw/acpi/generic_event_device.c
28
+++ b/hw/arm/virt-acpi-build.c
17
+++ b/hw/acpi/generic_event_device.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
18
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
19
AcpiGedState *s = ACPI_GED(hotplug_dev);
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
20
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
21
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
33
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
22
- acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
34
- aml_name("CTRL")));
23
+ acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
35
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
24
} else {
36
+ aml_name("CTRL")));
25
error_setg(errp, "virt: device plug request for unsupported device"
37
26
" type: %s", object_get_typename(OBJECT(dev)));
38
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
39
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL),
40
- aml_name("CDW1")));
41
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
42
+ aml_name("CDW1")));
43
aml_append(ifctx, ifctx1);
44
45
ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL"))));
46
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x10), NULL),
47
- aml_name("CDW1")));
48
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
49
+ aml_name("CDW1")));
50
aml_append(ifctx, ifctx1);
51
52
aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
53
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
54
aml_append(method, ifctx);
55
56
elsectx = aml_else();
57
- aml_append(elsectx, aml_store(aml_or(aml_name("CDW1"), aml_int(4), NULL),
58
- aml_name("CDW1")));
59
+ aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
60
+ aml_name("CDW1")));
61
aml_append(elsectx, aml_return(aml_arg(3)));
62
aml_append(method, elsectx);
63
aml_append(dev, method);
64
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
65
index XXXXXXX..XXXXXXX 100644
66
GIT binary patch
67
delta 133
68
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
69
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
70
MAmS{W8QoPG0j8@bzW@LL
71
72
delta 141
73
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
74
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
75
R$zCV`m0@An{L@X95dZ+BD!u>!
76
77
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
78
index XXXXXXX..XXXXXXX 100644
79
GIT binary patch
80
delta 132
81
zcmcaVi}Cs_MlP3NmymE@1_ma@iCof*O&is^IGH-{Zr;SX-A2HTGu}VgnWZb6!PzC;
82
zaDm6<N;gaQYUhw3A1+xCxj<mj<V?m|kR%reSc%xA$w1l|Bnc4~00|d>_#p8m*$ep~
83
L;w+mP-Q(B*s{AMU
84
85
delta 140
86
zcmcaUi}C&}MlP3Nmymd01_maViCof*T^rT9IGGynZQjJW-A2HVGu}VgnWZb6!PzC;
87
zaDm_CN;gaYf@<fGARjJS1`xGCXwu|N#)4XqJQoK<nZ%^YK&~-J8Y&?GmM8#;fMk|r
88
QFBE{vurO@?=@!QZ00dYn_y7O^
89
90
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
91
index XXXXXXX..XXXXXXX 100644
92
GIT binary patch
93
delta 133
94
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
95
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
96
MAmS{W8QoPG0j8@bzW@LL
97
98
delta 141
99
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
100
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
101
R$zCV`m0@An{L@X95dZ+BD!u>!
102
103
--
27
--
104
2.20.1
28
2.20.1
105
29
106
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Keqian Zhu <zhukeqian1@huawei.com>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
We can use existing helper function to trigger hotplug handler
4
an array of qemu_irq and passing it around, directly call
4
plug, which makes code clearer.
5
qdev_get_gpio_in() on the gic field.
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
9
Message-id: 20191209090306.20433-1-philmd@redhat.com
8
Message-id: 20200120012755.44581-3-zhukeqian1@huawei.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/arm/virt.h | 1 +
11
hw/arm/virt.c | 6 +++---
14
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
12
1 file changed, 3 insertions(+), 3 deletions(-)
15
2 files changed, 55 insertions(+), 55 deletions(-)
16
13
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
20
+++ b/include/hw/arm/virt.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
uint32_t iommu_phandle;
23
int psci_conduit;
24
hwaddr highest_gpa;
25
+ DeviceState *gic;
26
DeviceState *acpi_dev;
27
Notifier powerdown_notifier;
28
} VirtMachineState;
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
30
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/virt.c
16
--- a/hw/arm/virt.c
32
+++ b/hw/arm/virt.c
17
+++ b/hw/arm/virt.c
33
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
18
@@ -XXX,XX +XXX,XX @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
19
static void virt_memory_plug(HotplugHandler *hotplug_dev,
20
DeviceState *dev, Error **errp)
21
{
22
- HotplugHandlerClass *hhc;
23
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
24
Error *local_err = NULL;
25
26
@@ -XXX,XX +XXX,XX @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
27
goto out;
34
}
28
}
29
30
- hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
31
- hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);
32
+ hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev),
33
+ dev, &error_abort);
34
+
35
out:
36
error_propagate(errp, local_err);
35
}
37
}
36
37
-static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
38
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
39
{
40
DeviceState *dev;
41
MachineState *ms = MACHINE(vms);
42
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
43
44
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
45
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
46
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
48
49
qdev_init_nofail(dev);
50
51
return dev;
52
}
53
54
-static void create_its(VirtMachineState *vms, DeviceState *gicdev)
55
+static void create_its(VirtMachineState *vms)
56
{
57
const char *itsclass = its_class_name();
58
DeviceState *dev;
59
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
60
61
dev = qdev_create(NULL, itsclass);
62
63
- object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3",
64
+ object_property_set_link(OBJECT(dev), OBJECT(vms->gic), "parent-gicv3",
65
&error_abort);
66
qdev_init_nofail(dev);
67
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
68
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
69
fdt_add_its_gic_node(vms);
70
}
71
72
-static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
73
+static void create_v2m(VirtMachineState *vms)
74
{
75
int i;
76
int irq = vms->irqmap[VIRT_GIC_V2M];
77
@@ -XXX,XX +XXX,XX @@ static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
78
qdev_init_nofail(dev);
79
80
for (i = 0; i < NUM_GICV2M_SPIS; i++) {
81
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
82
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
83
+ qdev_get_gpio_in(vms->gic, irq + i));
84
}
85
86
fdt_add_v2m_gic_node(vms);
87
}
88
89
-static void create_gic(VirtMachineState *vms, qemu_irq *pic)
90
+static void create_gic(VirtMachineState *vms)
91
{
92
MachineState *ms = MACHINE(vms);
93
/* We create a standalone GIC */
94
- DeviceState *gicdev;
95
SysBusDevice *gicbusdev;
96
const char *gictype;
97
int type = vms->gic_version, i;
98
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
99
100
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
101
102
- gicdev = qdev_create(NULL, gictype);
103
- qdev_prop_set_uint32(gicdev, "revision", type);
104
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
105
+ vms->gic = qdev_create(NULL, gictype);
106
+ qdev_prop_set_uint32(vms->gic, "revision", type);
107
+ qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
108
/* Note that the num-irq property counts both internal and external
109
* interrupts; there are always 32 of the former (mandated by GIC spec).
110
*/
111
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
112
+ qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
113
if (!kvm_irqchip_in_kernel()) {
114
- qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure);
115
+ qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure);
116
}
117
118
if (type == 3) {
119
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
120
121
nb_redist_regions = virt_gicv3_redist_region_count(vms);
122
123
- qdev_prop_set_uint32(gicdev, "len-redist-region-count",
124
+ qdev_prop_set_uint32(vms->gic, "len-redist-region-count",
125
nb_redist_regions);
126
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
127
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
128
129
if (nb_redist_regions == 2) {
130
uint32_t redist1_capacity =
131
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
132
133
- qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
134
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
135
MIN(smp_cpus - redist0_count, redist1_capacity));
136
}
137
} else {
138
if (!kvm_irqchip_in_kernel()) {
139
- qdev_prop_set_bit(gicdev, "has-virtualization-extensions",
140
+ qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
141
vms->virt);
142
}
143
}
144
- qdev_init_nofail(gicdev);
145
- gicbusdev = SYS_BUS_DEVICE(gicdev);
146
+ qdev_init_nofail(vms->gic);
147
+ gicbusdev = SYS_BUS_DEVICE(vms->gic);
148
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
149
if (type == 3) {
150
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
151
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
152
153
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
154
qdev_connect_gpio_out(cpudev, irq,
155
- qdev_get_gpio_in(gicdev,
156
+ qdev_get_gpio_in(vms->gic,
157
ppibase + timer_irq[irq]));
158
}
159
160
if (type == 3) {
161
- qemu_irq irq = qdev_get_gpio_in(gicdev,
162
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
163
ppibase + ARCH_GIC_MAINT_IRQ);
164
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
165
0, irq);
166
} else if (vms->virt) {
167
- qemu_irq irq = qdev_get_gpio_in(gicdev,
168
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
169
ppibase + ARCH_GIC_MAINT_IRQ);
170
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
171
}
172
173
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
174
- qdev_get_gpio_in(gicdev, ppibase
175
+ qdev_get_gpio_in(vms->gic, ppibase
176
+ VIRTUAL_PMU_IRQ));
177
178
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
180
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
181
}
182
183
- for (i = 0; i < NUM_IRQS; i++) {
184
- pic[i] = qdev_get_gpio_in(gicdev, i);
185
- }
186
-
187
fdt_add_gic_node(vms);
188
189
if (type == 3 && vms->its) {
190
- create_its(vms, gicdev);
191
+ create_its(vms);
192
} else if (type == 2) {
193
- create_v2m(vms, pic);
194
+ create_v2m(vms);
195
}
196
}
197
198
-static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
199
+static void create_uart(const VirtMachineState *vms, int uart,
200
MemoryRegion *mem, Chardev *chr)
201
{
202
char *nodename;
203
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
204
qdev_init_nofail(dev);
205
memory_region_add_subregion(mem, base,
206
sysbus_mmio_get_region(s, 0));
207
- sysbus_connect_irq(s, 0, pic[irq]);
208
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
209
210
nodename = g_strdup_printf("/pl011@%" PRIx64, base);
211
qemu_fdt_add_subnode(vms->fdt, nodename);
212
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
213
g_free(nodename);
214
}
215
216
-static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
217
+static void create_rtc(const VirtMachineState *vms)
218
{
219
char *nodename;
220
hwaddr base = vms->memmap[VIRT_RTC].base;
221
@@ -XXX,XX +XXX,XX @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
222
int irq = vms->irqmap[VIRT_RTC];
223
const char compat[] = "arm,pl031\0arm,primecell";
224
225
- sysbus_create_simple("pl031", base, pic[irq]);
226
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
227
228
nodename = g_strdup_printf("/pl031@%" PRIx64, base);
229
qemu_fdt_add_subnode(vms->fdt, nodename);
230
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
231
}
232
}
233
234
-static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
235
+static void create_gpio(const VirtMachineState *vms)
236
{
237
char *nodename;
238
DeviceState *pl061_dev;
239
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
240
int irq = vms->irqmap[VIRT_GPIO];
241
const char compat[] = "arm,pl061\0arm,primecell";
242
243
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
244
+ pl061_dev = sysbus_create_simple("pl061", base,
245
+ qdev_get_gpio_in(vms->gic, irq));
246
247
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
248
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
249
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
250
g_free(nodename);
251
}
252
253
-static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
254
+static void create_virtio_devices(const VirtMachineState *vms)
255
{
256
int i;
257
hwaddr size = vms->memmap[VIRT_MMIO].size;
258
@@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
259
int irq = vms->irqmap[VIRT_MMIO] + i;
260
hwaddr base = vms->memmap[VIRT_MMIO].base + i * size;
261
262
- sysbus_create_simple("virtio-mmio", base, pic[irq]);
263
+ sysbus_create_simple("virtio-mmio", base,
264
+ qdev_get_gpio_in(vms->gic, irq));
265
}
266
267
/* We add dtb nodes in reverse order so that they appear in the finished
268
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(const VirtMachineState *vms,
269
0x7 /* PCI irq */);
270
}
271
272
-static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
273
+static void create_smmu(const VirtMachineState *vms,
274
PCIBus *bus)
275
{
276
char *node;
277
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
278
qdev_init_nofail(dev);
279
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
280
for (i = 0; i < NUM_SMMU_IRQS; i++) {
281
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
282
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
283
+ qdev_get_gpio_in(vms->gic, irq + i));
284
}
285
286
node = g_strdup_printf("/smmuv3@%" PRIx64, base);
287
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
288
g_free(node);
289
}
290
291
-static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
292
+static void create_pcie(VirtMachineState *vms)
293
{
294
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
295
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
296
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
297
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
298
299
for (i = 0; i < GPEX_NUM_IRQS; i++) {
300
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
301
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
302
+ qdev_get_gpio_in(vms->gic, irq + i));
303
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
304
}
305
306
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
307
if (vms->iommu) {
308
vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
309
310
- create_smmu(vms, pic, pci->bus);
311
+ create_smmu(vms, pci->bus);
312
313
qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
314
0x0, vms->iommu_phandle, 0x0, 0x10000);
315
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
316
g_free(nodename);
317
}
318
319
-static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
320
+static void create_platform_bus(VirtMachineState *vms)
321
{
322
DeviceState *dev;
323
SysBusDevice *s;
324
@@ -XXX,XX +XXX,XX @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
325
326
s = SYS_BUS_DEVICE(dev);
327
for (i = 0; i < PLATFORM_BUS_NUM_IRQS; i++) {
328
- int irqn = vms->irqmap[VIRT_PLATFORM_BUS] + i;
329
- sysbus_connect_irq(s, i, pic[irqn]);
330
+ int irq = vms->irqmap[VIRT_PLATFORM_BUS] + i;
331
+ sysbus_connect_irq(s, i, qdev_get_gpio_in(vms->gic, irq));
332
}
333
334
memory_region_add_subregion(sysmem,
335
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
336
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
337
MachineClass *mc = MACHINE_GET_CLASS(machine);
338
const CPUArchIdList *possible_cpus;
339
- qemu_irq pic[NUM_IRQS];
340
MemoryRegion *sysmem = get_system_memory();
341
MemoryRegion *secure_sysmem = NULL;
342
int n, virt_max_cpus;
343
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
344
345
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
346
347
- create_gic(vms, pic);
348
+ create_gic(vms);
349
350
fdt_add_pmu_nodes(vms);
351
352
- create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0));
353
+ create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
354
355
if (vms->secure) {
356
create_secure_ram(vms, secure_sysmem);
357
- create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
358
+ create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
359
}
360
361
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
362
363
- create_rtc(vms, pic);
364
+ create_rtc(vms);
365
366
- create_pcie(vms, pic);
367
+ create_pcie(vms);
368
369
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
370
- vms->acpi_dev = create_acpi_ged(vms, pic);
371
+ vms->acpi_dev = create_acpi_ged(vms);
372
} else {
373
- create_gpio(vms, pic);
374
+ create_gpio(vms);
375
}
376
377
/* connect powerdown request */
378
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
379
* (which will be automatically plugged in to the transports). If
380
* no backend is created the transport will just sit harmlessly idle.
381
*/
382
- create_virtio_devices(vms, pic);
383
+ create_virtio_devices(vms);
384
385
vms->fw_cfg = create_fw_cfg(vms, &address_space_memory);
386
rom_set_fw(vms->fw_cfg);
387
388
- create_platform_bus(vms, pic);
389
+ create_platform_bus(vms);
390
391
vms->bootinfo.ram_size = machine->ram_size;
392
vms->bootinfo.nb_cpus = smp_cpus;
393
--
38
--
394
2.20.1
39
2.20.1
395
40
396
41
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
The qemu-nbd documentation is currently in qemu-nbd.texi in Texinfo
2
2
format, which we present to the user as:
3
Switch to ram block writeback for pmem migration.
3
* a qemu-nbd manpage
4
4
* a section of the main qemu-doc HTML documentation
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Convert the documentation to rST format, and present it to the user as:
7
* a qemu-nbd manpage
8
* part of the interop/ Sphinx manual
9
10
This follows the same pattern as commit 27a296fce982 did for the
11
qemu-ga manpage.
12
13
All the content of the old manpage is retained, except that I have
14
dropped the "This is free software; see the source for copying
15
conditions. There is NO warranty..." text that was in the old AUTHOR
16
section; Sphinx's manpage builder doesn't expect that much text in
17
the AUTHOR section, and since none of our other manpages have it it
18
seems easiest to delete it rather than try to figure out where else
19
in the manpage to put it.
20
21
The only other textual change is that I have had to give the
22
--nocache option its own description ("Equivalent to --cache=none")
23
because Sphinx doesn't have an equivalent of using item/itemx
24
to share a description between two options.
25
26
Some minor aspects of the formatting have changed, to suit what is
27
easiest for Sphinx to output. (The most notable is that Sphinx
28
option section option syntax doesn't support '--option foo=bar'
29
with bar underlined rather than bold, so we have to switch to
30
'--option foo=BAR' instead.)
31
32
The contents of qemu-option-trace.texi are now duplicated in
33
docs/interop/qemu-option-trace.rst.inc, until such time as we complete
34
the conversion of the other files which use it; since it has had only
35
3 changes in 3 years, this shouldn't be too awkward a burden.
36
(We use .rst.inc because if this file fragment has a .rst extension
37
then Sphinx complains about not seeing it in a toctree.)
38
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
40
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
41
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Message-id: 20191121000843.24844-4-beata.michalska@linaro.org
42
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
44
Message-id: 20200116141511.16849-2-peter.maydell@linaro.org
11
---
45
---
12
migration/ram.c | 5 +----
46
Makefile | 16 +-
13
1 file changed, 1 insertion(+), 4 deletions(-)
47
MAINTAINERS | 1 +
14
48
docs/interop/conf.py | 4 +-
15
diff --git a/migration/ram.c b/migration/ram.c
49
docs/interop/index.rst | 1 +
50
docs/interop/qemu-nbd.rst | 263 +++++++++++++++++++++++++
51
docs/interop/qemu-option-trace.rst.inc | 30 +++
52
qemu-doc.texi | 6 -
53
qemu-nbd.texi | 214 --------------------
54
qemu-option-trace.texi | 4 +
55
9 files changed, 313 insertions(+), 226 deletions(-)
56
create mode 100644 docs/interop/qemu-nbd.rst
57
create mode 100644 docs/interop/qemu-option-trace.rst.inc
58
delete mode 100644 qemu-nbd.texi
59
60
diff --git a/Makefile b/Makefile
16
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
17
--- a/migration/ram.c
62
--- a/Makefile
18
+++ b/migration/ram.c
63
+++ b/Makefile
64
@@ -XXX,XX +XXX,XX @@ MANUAL_BUILDDIR := docs
65
endif
66
67
ifdef BUILD_DOCS
68
-DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 $(MANUAL_BUILDDIR)/interop/qemu-ga.8
69
+DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1
70
+DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-nbd.8
71
+DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-ga.8
72
DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
73
DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
74
DOCS+=docs/qemu-block-drivers.7
75
@@ -XXX,XX +XXX,XX @@ ifdef CONFIG_POSIX
76
ifeq ($(CONFIG_TOOLS),y)
77
    $(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
78
    $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
79
-    $(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
80
+    $(INSTALL_DATA) $(MANUAL_BUILDDIR)/interop/qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
81
endif
82
ifdef CONFIG_TRACE_SYSTEMTAP
83
    $(INSTALL_DATA) scripts/qemu-trace-stap.1 "$(DESTDIR)$(mandir)/man1"
84
@@ -XXX,XX +XXX,XX @@ sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index
85
# a single doctree: https://github.com/sphinx-doc/sphinx/issues/2946
86
build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" sphinx-build $(if $(V),,-q) -W -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
87
# We assume all RST files in the manual's directory are used in it
88
-manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
89
+manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) \
90
+ $(wildcard $(SRC_PATH)/docs/$1/*.rst.inc) \
91
+ $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
92
93
$(MANUAL_BUILDDIR)/devel/index.html: $(call manual-deps,devel)
94
    $(call build-manual,devel,html)
95
@@ -XXX,XX +XXX,XX @@ $(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
96
$(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
97
    $(call build-manual,interop,man)
98
99
+$(MANUAL_BUILDDIR)/interop/qemu-nbd.8: $(call manual-deps,interop)
100
+    $(call build-manual,interop,man)
101
+
102
$(MANUAL_BUILDDIR)/index.html: $(SRC_PATH)/docs/index.html.in qemu-version.h
103
    @mkdir -p "$(MANUAL_BUILDDIR)"
104
    $(call quiet-command, sed "s|@@VERSION@@|${VERSION}|g" $< >$@, \
105
@@ -XXX,XX +XXX,XX @@ qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
106
qemu.1: qemu-option-trace.texi
107
qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
108
fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
109
-qemu-nbd.8: qemu-nbd.texi qemu-option-trace.texi
110
docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
111
docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
112
scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi
113
@@ -XXX,XX +XXX,XX @@ pdf: qemu-doc.pdf docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
114
txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
115
116
qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
117
-    qemu-img.texi qemu-nbd.texi qemu-options.texi \
118
+    qemu-img.texi qemu-options.texi \
119
    qemu-tech.texi qemu-option-trace.texi \
120
    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi \
121
    qemu-monitor-info.texi docs/qemu-block-drivers.texi \
122
diff --git a/MAINTAINERS b/MAINTAINERS
123
index XXXXXXX..XXXXXXX 100644
124
--- a/MAINTAINERS
125
+++ b/MAINTAINERS
126
@@ -XXX,XX +XXX,XX @@ F: include/block/nbd*
127
F: qemu-nbd.*
128
F: blockdev-nbd.c
129
F: docs/interop/nbd.txt
130
+F: docs/interop/qemu-nbd.rst
131
T: git https://repo.or.cz/qemu/ericb.git nbd
132
133
NFS
134
diff --git a/docs/interop/conf.py b/docs/interop/conf.py
135
index XXXXXXX..XXXXXXX 100644
136
--- a/docs/interop/conf.py
137
+++ b/docs/interop/conf.py
138
@@ -XXX,XX +XXX,XX @@ html_theme_options['description'] = u'System Emulation Management and Interopera
139
# (source start file, name, description, authors, manual section).
140
man_pages = [
141
('qemu-ga', 'qemu-ga', u'QEMU Guest Agent',
142
- ['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8)
143
+ ['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8),
144
+ ('qemu-nbd', 'qemu-nbd', u'QEMU Disk Network Block Device Server',
145
+ ['Anthony Liguori <anthony@codemonkey.ws>'], 8)
146
]
147
diff --git a/docs/interop/index.rst b/docs/interop/index.rst
148
index XXXXXXX..XXXXXXX 100644
149
--- a/docs/interop/index.rst
150
+++ b/docs/interop/index.rst
151
@@ -XXX,XX +XXX,XX @@ Contents:
152
live-block-operations
153
pr-helper
154
qemu-ga
155
+ qemu-nbd
156
vhost-user
157
vhost-user-gpu
158
diff --git a/docs/interop/qemu-nbd.rst b/docs/interop/qemu-nbd.rst
159
new file mode 100644
160
index XXXXXXX..XXXXXXX
161
--- /dev/null
162
+++ b/docs/interop/qemu-nbd.rst
19
@@ -XXX,XX +XXX,XX @@
163
@@ -XXX,XX +XXX,XX @@
20
#include "qemu/bitops.h"
164
+QEMU Disk Network Block Device Server
21
#include "qemu/bitmap.h"
165
+=====================================
22
#include "qemu/main-loop.h"
166
+
23
-#include "qemu/pmem.h"
167
+Synopsis
24
#include "xbzrle.h"
168
+--------
25
#include "ram.h"
169
+
26
#include "migration.h"
170
+**qemu-nbd** [*OPTION*]... *filename*
27
@@ -XXX,XX +XXX,XX @@ static int ram_load_cleanup(void *opaque)
171
+
28
RAMBlock *rb;
172
+**qemu-nbd** -L [*OPTION*]...
29
173
+
30
RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
174
+**qemu-nbd** -d *dev*
31
- if (ramblock_is_pmem(rb)) {
175
+
32
- pmem_persist(rb->host, rb->used_length);
176
+Description
33
- }
177
+-----------
34
+ qemu_ram_block_writeback(rb);
178
+
35
}
179
+Export a QEMU disk image using the NBD protocol.
36
180
+
37
xbzrle_load_cleanup();
181
+Other uses:
182
+
183
+- Bind a /dev/nbdX block device to a QEMU server (on Linux).
184
+- As a client to query exports of a remote NBD server.
185
+
186
+Options
187
+-------
188
+
189
+.. program:: qemu-nbd
190
+
191
+*filename* is a disk image filename, or a set of block
192
+driver options if ``--image-opts`` is specified.
193
+
194
+*dev* is an NBD device.
195
+
196
+.. option:: --object type,id=ID,...props...
197
+
198
+ Define a new instance of the *type* object class identified by *ID*.
199
+ See the :manpage:`qemu(1)` manual page for full details of the properties
200
+ supported. The common object types that it makes sense to define are the
201
+ ``secret`` object, which is used to supply passwords and/or encryption
202
+ keys, and the ``tls-creds`` object, which is used to supply TLS
203
+ credentials for the qemu-nbd server or client.
204
+
205
+.. option:: -p, --port=PORT
206
+
207
+ TCP port to listen on as a server, or connect to as a client
208
+ (default ``10809``).
209
+
210
+.. option:: -o, --offset=OFFSET
211
+
212
+ The offset into the image.
213
+
214
+.. option:: -b, --bind=IFACE
215
+
216
+ The interface to bind to as a server, or connect to as a client
217
+ (default ``0.0.0.0``).
218
+
219
+.. option:: -k, --socket=PATH
220
+
221
+ Use a unix socket with path *PATH*.
222
+
223
+.. option:: --image-opts
224
+
225
+ Treat *filename* as a set of image options, instead of a plain
226
+ filename. If this flag is specified, the ``-f`` flag should
227
+ not be used, instead the :option:`format=` option should be set.
228
+
229
+.. option:: -f, --format=FMT
230
+
231
+ Force the use of the block driver for format *FMT* instead of
232
+ auto-detecting.
233
+
234
+.. option:: -r, --read-only
235
+
236
+ Export the disk as read-only.
237
+
238
+.. option:: -P, --partition=NUM
239
+
240
+ Deprecated: Only expose MBR partition *NUM*. Understands physical
241
+ partitions 1-4 and logical partition 5. New code should instead use
242
+ :option:`--image-opts` with the raw driver wrapping a subset of the
243
+ original image.
244
+
245
+.. option:: -B, --bitmap=NAME
246
+
247
+ If *filename* has a qcow2 persistent bitmap *NAME*, expose
248
+ that bitmap via the ``qemu:dirty-bitmap:NAME`` context
249
+ accessible through NBD_OPT_SET_META_CONTEXT.
250
+
251
+.. option:: -s, --snapshot
252
+
253
+ Use *filename* as an external snapshot, create a temporary
254
+ file with ``backing_file=``\ *filename*, redirect the write to
255
+ the temporary one.
256
+
257
+.. option:: -l, --load-snapshot=SNAPSHOT_PARAM
258
+
259
+ Load an internal snapshot inside *filename* and export it
260
+ as an read-only device, SNAPSHOT_PARAM format is
261
+ ``snapshot.id=[ID],snapshot.name=[NAME]`` or ``[ID_OR_NAME]``
262
+
263
+.. option:: --cache=CACHE
264
+
265
+ The cache mode to be used with the file. See the documentation of
266
+ the emulator's ``-drive cache=...`` option for allowed values.
267
+
268
+.. option:: -n, --nocache
269
+
270
+ Equivalent to :option:`--cache=none`.
271
+
272
+.. option:: --aio=AIO
273
+
274
+ Set the asynchronous I/O mode between ``threads`` (the default)
275
+ and ``native`` (Linux only).
276
+
277
+.. option:: --discard=DISCARD
278
+
279
+ Control whether ``discard`` (also known as ``trim`` or ``unmap``)
280
+ requests are ignored or passed to the filesystem. *DISCARD* is one of
281
+ ``ignore`` (or ``off``), ``unmap`` (or ``on``). The default is
282
+ ``ignore``.
283
+
284
+.. option:: --detect-zeroes=DETECT_ZEROES
285
+
286
+ Control the automatic conversion of plain zero writes by the OS to
287
+ driver-specific optimized zero write commands. *DETECT_ZEROES* is one of
288
+ ``off``, ``on``, or ``unmap``. ``unmap``
289
+ converts a zero write to an unmap operation and can only be used if
290
+ *DISCARD* is set to ``unmap``. The default is ``off``.
291
+
292
+.. option:: -c, --connect=DEV
293
+
294
+ Connect *filename* to NBD device *DEV* (Linux only).
295
+
296
+.. option:: -d, --disconnect
297
+
298
+ Disconnect the device *DEV* (Linux only).
299
+
300
+.. option:: -e, --shared=NUM
301
+
302
+ Allow up to *NUM* clients to share the device (default
303
+ ``1``). Safe for readers, but for now, consistency is not
304
+ guaranteed between multiple writers.
305
+
306
+.. option:: -t, --persistent
307
+
308
+ Don't exit on the last connection.
309
+
310
+.. option:: -x, --export-name=NAME
311
+
312
+ Set the NBD volume export name (default of a zero-length string).
313
+
314
+.. option:: -D, --description=DESCRIPTION
315
+
316
+ Set the NBD volume export description, as a human-readable
317
+ string.
318
+
319
+.. option:: -L, --list
320
+
321
+ Connect as a client and list all details about the exports exposed by
322
+ a remote NBD server. This enables list mode, and is incompatible
323
+ with options that change behavior related to a specific export (such as
324
+ :option:`--export-name`, :option:`--offset`, ...).
325
+
326
+.. option:: --tls-creds=ID
327
+
328
+ Enable mandatory TLS encryption for the server by setting the ID
329
+ of the TLS credentials object previously created with the --object
330
+ option; or provide the credentials needed for connecting as a client
331
+ in list mode.
332
+
333
+.. option:: --fork
334
+
335
+ Fork off the server process and exit the parent once the server is running.
336
+
337
+.. option:: --pid-file=PATH
338
+
339
+ Store the server's process ID in the given file.
340
+
341
+.. option:: --tls-authz=ID
342
+
343
+ Specify the ID of a qauthz object previously created with the
344
+ :option:`--object` option. This will be used to authorize connecting users
345
+ against their x509 distinguished name.
346
+
347
+.. option:: -v, --verbose
348
+
349
+ Display extra debugging information.
350
+
351
+.. option:: -h, --help
352
+
353
+ Display this help and exit.
354
+
355
+.. option:: -V, --version
356
+
357
+ Display version information and exit.
358
+
359
+.. option:: -T, --trace [[enable=]PATTERN][,events=FILE][,file=FILE]
360
+
361
+ .. include:: qemu-option-trace.rst.inc
362
+
363
+Examples
364
+--------
365
+
366
+Start a server listening on port 10809 that exposes only the
367
+guest-visible contents of a qcow2 file, with no TLS encryption, and
368
+with the default export name (an empty string). The command is
369
+one-shot, and will block until the first successful client
370
+disconnects:
371
+
372
+::
373
+
374
+ qemu-nbd -f qcow2 file.qcow2
375
+
376
+Start a long-running server listening with encryption on port 10810,
377
+and whitelist clients with a specific X.509 certificate to connect to
378
+a 1 megabyte subset of a raw file, using the export name 'subset':
379
+
380
+::
381
+
382
+ qemu-nbd \
383
+ --object tls-creds-x509,id=tls0,endpoint=server,dir=/path/to/qemutls \
384
+ --object 'authz-simple,id=auth0,identity=CN=laptop.example.com,,\
385
+ O=Example Org,,L=London,,ST=London,,C=GB' \
386
+ --tls-creds tls0 --tls-authz auth0 \
387
+ -t -x subset -p 10810 \
388
+ --image-opts driver=raw,offset=1M,size=1M,file.driver=file,file.filename=file.raw
389
+
390
+Serve a read-only copy of just the first MBR partition of a guest
391
+image over a Unix socket with as many as 5 simultaneous readers, with
392
+a persistent process forked as a daemon:
393
+
394
+::
395
+
396
+ qemu-nbd --fork --persistent --shared=5 --socket=/path/to/sock \
397
+ --partition=1 --read-only --format=qcow2 file.qcow2
398
+
399
+Expose the guest-visible contents of a qcow2 file via a block device
400
+/dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for
401
+partitions found within), then disconnect the device when done.
402
+Access to bind qemu-nbd to an /dev/nbd device generally requires root
403
+privileges, and may also require the execution of ``modprobe nbd``
404
+to enable the kernel NBD client module. *CAUTION*: Do not use
405
+this method to mount filesystems from an untrusted guest image - a
406
+malicious guest may have prepared the image to attempt to trigger
407
+kernel bugs in partition probing or file system mounting.
408
+
409
+::
410
+
411
+ qemu-nbd -c /dev/nbd0 -f qcow2 file.qcow2
412
+ qemu-nbd -d /dev/nbd0
413
+
414
+Query a remote server to see details about what export(s) it is
415
+serving on port 10809, and authenticating via PSK:
416
+
417
+::
418
+
419
+ qemu-nbd \
420
+ --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=eblake,endpoint=client \
421
+ --tls-creds tls0 -L -b remote.example.com
422
+
423
+See also
424
+--------
425
+
426
+:manpage:`qemu(1)`, :manpage:`qemu-img(1)`
427
diff --git a/docs/interop/qemu-option-trace.rst.inc b/docs/interop/qemu-option-trace.rst.inc
428
new file mode 100644
429
index XXXXXXX..XXXXXXX
430
--- /dev/null
431
+++ b/docs/interop/qemu-option-trace.rst.inc
432
@@ -XXX,XX +XXX,XX @@
433
+..
434
+ The contents of this file must be kept in sync with qemu-option-trace.texi
435
+ until all the users of the texi file have been converted to rst and
436
+ the texi file can be removed.
437
+
438
+Specify tracing options.
439
+
440
+.. option:: [enable=]PATTERN
441
+
442
+ Immediately enable events matching *PATTERN*
443
+ (either event name or a globbing pattern). This option is only
444
+ available if QEMU has been compiled with the ``simple``, ``log``
445
+ or ``ftrace`` tracing backend. To specify multiple events or patterns,
446
+ specify the :option:`-trace` option multiple times.
447
+
448
+ Use :option:`-trace help` to print a list of names of trace points.
449
+
450
+.. option:: events=FILE
451
+
452
+ Immediately enable events listed in *FILE*.
453
+ The file must contain one event name (as listed in the ``trace-events-all``
454
+ file) per line; globbing patterns are accepted too. This option is only
455
+ available if QEMU has been compiled with the ``simple``, ``log`` or
456
+ ``ftrace`` tracing backend.
457
+
458
+.. option:: file=FILE
459
+
460
+ Log output traces to *FILE*.
461
+ This option is only available if QEMU has been compiled with
462
+ the ``simple`` tracing backend.
463
diff --git a/qemu-doc.texi b/qemu-doc.texi
464
index XXXXXXX..XXXXXXX 100644
465
--- a/qemu-doc.texi
466
+++ b/qemu-doc.texi
467
@@ -XXX,XX +XXX,XX @@ encrypted disk images.
468
* disk_images_snapshot_mode:: Snapshot mode
469
* vm_snapshots:: VM snapshots
470
* qemu_img_invocation:: qemu-img Invocation
471
-* qemu_nbd_invocation:: qemu-nbd Invocation
472
* disk_images_formats:: Disk image file formats
473
* host_drives:: Using host drives
474
* disk_images_fat_images:: Virtual FAT disk images
475
@@ -XXX,XX +XXX,XX @@ state is not saved or restored properly (in particular USB).
476
477
@include qemu-img.texi
478
479
-@node qemu_nbd_invocation
480
-@subsection @code{qemu-nbd} Invocation
481
-
482
-@include qemu-nbd.texi
483
-
484
@include docs/qemu-block-drivers.texi
485
486
@node pcsys_network
487
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
488
deleted file mode 100644
489
index XXXXXXX..XXXXXXX
490
--- a/qemu-nbd.texi
491
+++ /dev/null
492
@@ -XXX,XX +XXX,XX @@
493
-@example
494
-@c man begin SYNOPSIS
495
-@command{qemu-nbd} [OPTION]... @var{filename}
496
-
497
-@command{qemu-nbd} @option{-L} [OPTION]...
498
-
499
-@command{qemu-nbd} @option{-d} @var{dev}
500
-@c man end
501
-@end example
502
-
503
-@c man begin DESCRIPTION
504
-
505
-Export a QEMU disk image using the NBD protocol.
506
-
507
-Other uses:
508
-@itemize
509
-@item
510
-Bind a /dev/nbdX block device to a QEMU server (on Linux).
511
-@item
512
-As a client to query exports of a remote NBD server.
513
-@end itemize
514
-
515
-@c man end
516
-
517
-@c man begin OPTIONS
518
-@var{filename} is a disk image filename, or a set of block
519
-driver options if @option{--image-opts} is specified.
520
-
521
-@var{dev} is an NBD device.
522
-
523
-@table @option
524
-@item --object type,id=@var{id},...props...
525
-Define a new instance of the @var{type} object class identified by @var{id}.
526
-See the @code{qemu(1)} manual page for full details of the properties
527
-supported. The common object types that it makes sense to define are the
528
-@code{secret} object, which is used to supply passwords and/or encryption
529
-keys, and the @code{tls-creds} object, which is used to supply TLS
530
-credentials for the qemu-nbd server or client.
531
-@item -p, --port=@var{port}
532
-The TCP port to listen on as a server, or connect to as a client
533
-(default @samp{10809}).
534
-@item -o, --offset=@var{offset}
535
-The offset into the image.
536
-@item -b, --bind=@var{iface}
537
-The interface to bind to as a server, or connect to as a client
538
-(default @samp{0.0.0.0}).
539
-@item -k, --socket=@var{path}
540
-Use a unix socket with path @var{path}.
541
-@item --image-opts
542
-Treat @var{filename} as a set of image options, instead of a plain
543
-filename. If this flag is specified, the @var{-f} flag should
544
-not be used, instead the '@code{format=}' option should be set.
545
-@item -f, --format=@var{fmt}
546
-Force the use of the block driver for format @var{fmt} instead of
547
-auto-detecting.
548
-@item -r, --read-only
549
-Export the disk as read-only.
550
-@item -P, --partition=@var{num}
551
-Deprecated: Only expose MBR partition @var{num}. Understands physical
552
-partitions 1-4 and logical partition 5. New code should instead use
553
-@option{--image-opts} with the raw driver wrapping a subset of the
554
-original image.
555
-@item -B, --bitmap=@var{name}
556
-If @var{filename} has a qcow2 persistent bitmap @var{name}, expose
557
-that bitmap via the ``qemu:dirty-bitmap:@var{name}'' context
558
-accessible through NBD_OPT_SET_META_CONTEXT.
559
-@item -s, --snapshot
560
-Use @var{filename} as an external snapshot, create a temporary
561
-file with backing_file=@var{filename}, redirect the write to
562
-the temporary one.
563
-@item -l, --load-snapshot=@var{snapshot_param}
564
-Load an internal snapshot inside @var{filename} and export it
565
-as an read-only device, @var{snapshot_param} format is
566
-'snapshot.id=[ID],snapshot.name=[NAME]' or '[ID_OR_NAME]'
567
-@item -n, --nocache
568
-@itemx --cache=@var{cache}
569
-The cache mode to be used with the file. See the documentation of
570
-the emulator's @code{-drive cache=...} option for allowed values.
571
-@item --aio=@var{aio}
572
-Set the asynchronous I/O mode between @samp{threads} (the default)
573
-and @samp{native} (Linux only).
574
-@item --discard=@var{discard}
575
-Control whether @dfn{discard} (also known as @dfn{trim} or @dfn{unmap})
576
-requests are ignored or passed to the filesystem. @var{discard} is one of
577
-@samp{ignore} (or @samp{off}), @samp{unmap} (or @samp{on}). The default is
578
-@samp{ignore}.
579
-@item --detect-zeroes=@var{detect-zeroes}
580
-Control the automatic conversion of plain zero writes by the OS to
581
-driver-specific optimized zero write commands. @var{detect-zeroes} is one of
582
-@samp{off}, @samp{on} or @samp{unmap}. @samp{unmap}
583
-converts a zero write to an unmap operation and can only be used if
584
-@var{discard} is set to @samp{unmap}. The default is @samp{off}.
585
-@item -c, --connect=@var{dev}
586
-Connect @var{filename} to NBD device @var{dev} (Linux only).
587
-@item -d, --disconnect
588
-Disconnect the device @var{dev} (Linux only).
589
-@item -e, --shared=@var{num}
590
-Allow up to @var{num} clients to share the device (default
591
-@samp{1}). Safe for readers, but for now, consistency is not
592
-guaranteed between multiple writers.
593
-@item -t, --persistent
594
-Don't exit on the last connection.
595
-@item -x, --export-name=@var{name}
596
-Set the NBD volume export name (default of a zero-length string).
597
-@item -D, --description=@var{description}
598
-Set the NBD volume export description, as a human-readable
599
-string.
600
-@item -L, --list
601
-Connect as a client and list all details about the exports exposed by
602
-a remote NBD server. This enables list mode, and is incompatible
603
-with options that change behavior related to a specific export (such as
604
-@option{--export-name}, @option{--offset}, ...).
605
-@item --tls-creds=ID
606
-Enable mandatory TLS encryption for the server by setting the ID
607
-of the TLS credentials object previously created with the --object
608
-option; or provide the credentials needed for connecting as a client
609
-in list mode.
610
-@item --fork
611
-Fork off the server process and exit the parent once the server is running.
612
-@item --pid-file=PATH
613
-Store the server's process ID in the given file.
614
-@item --tls-authz=ID
615
-Specify the ID of a qauthz object previously created with the
616
---object option. This will be used to authorize connecting users
617
-against their x509 distinguished name.
618
-@item -v, --verbose
619
-Display extra debugging information.
620
-@item -h, --help
621
-Display this help and exit.
622
-@item -V, --version
623
-Display version information and exit.
624
-@item -T, --trace [[enable=]@var{pattern}][,events=@var{file}][,file=@var{file}]
625
-@findex --trace
626
-@include qemu-option-trace.texi
627
-@end table
628
-
629
-@c man end
630
-
631
-@c man begin EXAMPLES
632
-Start a server listening on port 10809 that exposes only the
633
-guest-visible contents of a qcow2 file, with no TLS encryption, and
634
-with the default export name (an empty string). The command is
635
-one-shot, and will block until the first successful client
636
-disconnects:
637
-
638
-@example
639
-qemu-nbd -f qcow2 file.qcow2
640
-@end example
641
-
642
-Start a long-running server listening with encryption on port 10810,
643
-and whitelist clients with a specific X.509 certificate to connect to
644
-a 1 megabyte subset of a raw file, using the export name 'subset':
645
-
646
-@example
647
-qemu-nbd \
648
- --object tls-creds-x509,id=tls0,endpoint=server,dir=/path/to/qemutls \
649
- --object 'authz-simple,id=auth0,identity=CN=laptop.example.com,,\
650
- O=Example Org,,L=London,,ST=London,,C=GB' \
651
- --tls-creds tls0 --tls-authz auth0 \
652
- -t -x subset -p 10810 \
653
- --image-opts driver=raw,offset=1M,size=1M,file.driver=file,file.filename=file.raw
654
-@end example
655
-
656
-Serve a read-only copy of just the first MBR partition of a guest
657
-image over a Unix socket with as many as 5 simultaneous readers, with
658
-a persistent process forked as a daemon:
659
-
660
-@example
661
-qemu-nbd --fork --persistent --shared=5 --socket=/path/to/sock \
662
- --partition=1 --read-only --format=qcow2 file.qcow2
663
-@end example
664
-
665
-Expose the guest-visible contents of a qcow2 file via a block device
666
-/dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for
667
-partitions found within), then disconnect the device when done.
668
-Access to bind qemu-nbd to an /dev/nbd device generally requires root
669
-privileges, and may also require the execution of @code{modprobe nbd}
670
-to enable the kernel NBD client module. @emph{CAUTION}: Do not use
671
-this method to mount filesystems from an untrusted guest image - a
672
-malicious guest may have prepared the image to attempt to trigger
673
-kernel bugs in partition probing or file system mounting.
674
-
675
-@example
676
-qemu-nbd -c /dev/nbd0 -f qcow2 file.qcow2
677
-qemu-nbd -d /dev/nbd0
678
-@end example
679
-
680
-Query a remote server to see details about what export(s) it is
681
-serving on port 10809, and authenticating via PSK:
682
-
683
-@example
684
-qemu-nbd \
685
- --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=eblake,endpoint=client \
686
- --tls-creds tls0 -L -b remote.example.com
687
-@end example
688
-
689
-@c man end
690
-
691
-@ignore
692
-
693
-@setfilename qemu-nbd
694
-@settitle QEMU Disk Network Block Device Server
695
-
696
-@c man begin AUTHOR
697
-Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>.
698
-This is free software; see the source for copying conditions. There is NO
699
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
700
-@c man end
701
-
702
-@c man begin SEEALSO
703
-qemu(1), qemu-img(1)
704
-@c man end
705
-
706
-@end ignore
707
diff --git a/qemu-option-trace.texi b/qemu-option-trace.texi
708
index XXXXXXX..XXXXXXX 100644
709
--- a/qemu-option-trace.texi
710
+++ b/qemu-option-trace.texi
711
@@ -XXX,XX +XXX,XX @@
712
+@c The contents of this file must be kept in sync with qemu-option-trace.rst.inc
713
+@c until all the users of the texi file have been converted to rst and
714
+@c the texi file can be removed.
715
+
716
Specify tracing options.
717
718
@table @option
38
--
719
--
39
2.20.1
720
2.20.1
40
721
41
722
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
We want a user-facing manual which contains system emulation
2
documentation. Create an empty one which we can populate.
2
3
3
Add an option to trigger memory writeback to sync given memory region
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
with the corresponding backing store, case one is available.
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
This extends the support for persistent memory, allowing syncing on-demand.
6
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Message-id: 20200116141511.16849-3-peter.maydell@linaro.org
8
---
9
Makefile | 10 +++++++++-
10
docs/index.html.in | 1 +
11
docs/system/conf.py | 15 +++++++++++++++
12
docs/system/index.rst | 16 ++++++++++++++++
13
4 files changed, 41 insertions(+), 1 deletion(-)
14
create mode 100644 docs/system/conf.py
15
create mode 100644 docs/system/index.rst
6
16
7
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
17
diff --git a/Makefile b/Makefile
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191121000843.24844-3-beata.michalska@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/exec/memory.h | 6 ++++++
13
include/exec/ram_addr.h | 8 ++++++++
14
include/qemu/cutils.h | 1 +
15
exec.c | 36 ++++++++++++++++++++++++++++++++++++
16
memory.c | 12 ++++++++++++
17
util/cutils.c | 38 ++++++++++++++++++++++++++++++++++++++
18
6 files changed, 101 insertions(+)
19
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
19
--- a/Makefile
23
+++ b/include/exec/memory.h
20
+++ b/Makefile
24
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
21
@@ -XXX,XX +XXX,XX @@ distclean: clean
25
*/
22
    $(call clean-manual,devel)
26
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
23
    $(call clean-manual,interop)
27
Error **errp);
24
    $(call clean-manual,specs)
28
+/**
25
+    $(call clean-manual,system)
29
+ * memory_region_do_writeback: Trigger writeback for selected address range
26
    for d in $(TARGET_DIRS); do \
30
+ * [addr, addr + size]
27
    rm -rf $$d || exit 1 ; \
31
+ *
28
done
32
+ */
29
@@ -XXX,XX +XXX,XX @@ endef
33
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
30
install-sphinxdocs: sphinxdocs
34
31
    $(call install-manual,interop)
35
/**
32
    $(call install-manual,specs)
36
* memory_region_set_log: Turn dirty logging on or off for a region.
33
+    $(call install-manual,system)
37
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
34
35
install-doc: $(DOCS) install-sphinxdocs
36
    $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
37
@@ -XXX,XX +XXX,XX @@ docs/version.texi: $(SRC_PATH)/VERSION config-host.mak
38
# and handles "don't rebuild things unless necessary" itself.
39
# The '.doctrees' files are cached information to speed this up.
40
.PHONY: sphinxdocs
41
-sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index.html $(MANUAL_BUILDDIR)/specs/index.html
42
+sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html \
43
+ $(MANUAL_BUILDDIR)/interop/index.html \
44
+ $(MANUAL_BUILDDIR)/specs/index.html \
45
+ $(MANUAL_BUILDDIR)/system/index.html
46
47
# Canned command to build a single manual
48
# Arguments: $1 = manual name, $2 = Sphinx builder ('html' or 'man')
49
@@ -XXX,XX +XXX,XX @@ $(MANUAL_BUILDDIR)/interop/index.html: $(call manual-deps,interop)
50
$(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
51
    $(call build-manual,specs,html)
52
53
+$(MANUAL_BUILDDIR)/system/index.html: $(call manual-deps,system)
54
+    $(call build-manual,system,html)
55
+
56
$(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
57
    $(call build-manual,interop,man)
58
59
diff --git a/docs/index.html.in b/docs/index.html.in
38
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/ram_addr.h
61
--- a/docs/index.html.in
40
+++ b/include/exec/ram_addr.h
62
+++ b/docs/index.html.in
41
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
63
@@ -XXX,XX +XXX,XX @@
42
64
<li><a href="qemu-ga-ref.html">Guest Agent Protocol Reference</a></li>
43
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
65
<li><a href="interop/index.html">System Emulation Management and Interoperability Guide</a></li>
44
66
<li><a href="specs/index.html">System Emulation Guest Hardware Specifications</a></li>
45
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
67
+ <li><a href="system/index.html">System Emulation User's Guide</a></li>
68
</ul>
69
</body>
70
</html>
71
diff --git a/docs/system/conf.py b/docs/system/conf.py
72
new file mode 100644
73
index XXXXXXX..XXXXXXX
74
--- /dev/null
75
+++ b/docs/system/conf.py
76
@@ -XXX,XX +XXX,XX @@
77
+# -*- coding: utf-8 -*-
78
+#
79
+# QEMU documentation build configuration file for the 'system' manual.
80
+#
81
+# This includes the top level conf file and then makes any necessary tweaks.
82
+import sys
83
+import os
46
+
84
+
47
+/* Clear whole block of mem */
85
+qemu_docdir = os.path.abspath("..")
48
+static inline void qemu_ram_block_writeback(RAMBlock *block)
86
+parent_config = os.path.join(qemu_docdir, "conf.py")
49
+{
87
+exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
50
+ qemu_ram_writeback(block, 0, block->used_length);
51
+}
52
+
88
+
53
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
89
+# This slightly misuses the 'description', but is the best way to get
54
#define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
90
+# the manual title to appear in the sidebar.
55
91
+html_theme_options['description'] = u'System Emulation User''s Guide'
56
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
92
diff --git a/docs/system/index.rst b/docs/system/index.rst
57
index XXXXXXX..XXXXXXX 100644
93
new file mode 100644
58
--- a/include/qemu/cutils.h
94
index XXXXXXX..XXXXXXX
59
+++ b/include/qemu/cutils.h
95
--- /dev/null
60
@@ -XXX,XX +XXX,XX @@ const char *qemu_strchrnul(const char *s, int c);
96
+++ b/docs/system/index.rst
61
#endif
62
time_t mktimegm(struct tm *tm);
63
int qemu_fdatasync(int fd);
64
+int qemu_msync(void *addr, size_t length, int fd);
65
int fcntl_setfl(int fd, int flag);
66
int qemu_parse_fd(const char *param);
67
int qemu_strtoi(const char *nptr, const char **endptr, int base,
68
diff --git a/exec.c b/exec.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/exec.c
71
+++ b/exec.c
72
@@ -XXX,XX +XXX,XX @@
97
@@ -XXX,XX +XXX,XX @@
73
#include "exec/ram_addr.h"
98
+.. This is the top level page for the 'system' manual.
74
#include "exec/log.h"
75
76
+#include "qemu/pmem.h"
77
+
99
+
78
#include "migration/vmstate.h"
79
80
#include "qemu/range.h"
81
@@ -XXX,XX +XXX,XX @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
82
return 0;
83
}
84
85
+/*
86
+ * Trigger sync on the given ram block for range [start, start + length]
87
+ * with the backing store if one is available.
88
+ * Otherwise no-op.
89
+ * @Note: this is supposed to be a synchronous op.
90
+ */
91
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length)
92
+{
93
+ void *addr = ramblock_ptr(block, start);
94
+
100
+
95
+ /* The requested range should fit in within the block range */
101
+QEMU System Emulation User's Guide
96
+ g_assert((start + length) <= block->used_length);
102
+==================================
97
+
103
+
98
+#ifdef CONFIG_LIBPMEM
104
+This manual is the overall guide for users using QEMU
99
+ /* The lack of support for pmem should not block the sync */
105
+for full system emulation (as opposed to user-mode emulation).
100
+ if (ramblock_is_pmem(block)) {
106
+This includes working with hypervisors such as KVM, Xen, Hax
101
+ pmem_persist(addr, length);
107
+or Hypervisor.Framework.
102
+ return;
103
+ }
104
+#endif
105
+ if (block->fd >= 0) {
106
+ /**
107
+ * Case there is no support for PMEM or the memory has not been
108
+ * specified as persistent (or is not one) - use the msync.
109
+ * Less optimal but still achieves the same goal
110
+ */
111
+ if (qemu_msync(addr, length, block->fd)) {
112
+ warn_report("%s: failed to sync memory range: start: "
113
+ RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
114
+ __func__, start, length);
115
+ }
116
+ }
117
+}
118
+
108
+
119
/* Called with ram_list.mutex held */
109
+Contents:
120
static void dirty_memory_extend(ram_addr_t old_ram_size,
121
ram_addr_t new_ram_size)
122
diff --git a/memory.c b/memory.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/memory.c
125
+++ b/memory.c
126
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
127
qemu_ram_resize(mr->ram_block, newsize, errp);
128
}
129
130
+
110
+
131
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
111
+.. toctree::
132
+{
112
+ :maxdepth: 2
133
+ /*
134
+ * Might be extended case needed to cover
135
+ * different types of memory regions
136
+ */
137
+ if (mr->ram_block && mr->dirty_log_mask) {
138
+ qemu_ram_writeback(mr->ram_block, addr, size);
139
+ }
140
+}
141
+
113
+
142
/*
143
* Call proper memory listeners about the change on the newly
144
* added/removed CoalescedMemoryRange.
145
diff --git a/util/cutils.c b/util/cutils.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/util/cutils.c
148
+++ b/util/cutils.c
149
@@ -XXX,XX +XXX,XX @@ int qemu_fdatasync(int fd)
150
#endif
151
}
152
153
+/**
154
+ * Sync changes made to the memory mapped file back to the backing
155
+ * storage. For POSIX compliant systems this will fallback
156
+ * to regular msync call. Otherwise it will trigger whole file sync
157
+ * (including the metadata case there is no support to skip that otherwise)
158
+ *
159
+ * @addr - start of the memory area to be synced
160
+ * @length - length of the are to be synced
161
+ * @fd - file descriptor for the file to be synced
162
+ * (mandatory only for POSIX non-compliant systems)
163
+ */
164
+int qemu_msync(void *addr, size_t length, int fd)
165
+{
166
+#ifdef CONFIG_POSIX
167
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
168
+
169
+ /**
170
+ * There are no strict reqs as per the length of mapping
171
+ * to be synced. Still the length needs to follow the address
172
+ * alignment changes. Additionally - round the size to the multiple
173
+ * of PAGE_SIZE
174
+ */
175
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
176
+ length = (length + ~align_mask) & align_mask;
177
+
178
+ addr = (void *)((uintptr_t)addr & align_mask);
179
+
180
+ return msync(addr, length, MS_SYNC);
181
+#else /* CONFIG_POSIX */
182
+ /**
183
+ * Perform the sync based on the file descriptor
184
+ * The sync range will most probably be wider than the one
185
+ * requested - but it will still get the job done
186
+ */
187
+ return qemu_fdatasync(fd);
188
+#endif /* CONFIG_POSIX */
189
+}
190
+
191
#ifndef _WIN32
192
/* Sets a specific flag */
193
int fcntl_setfl(int fd, int flag)
194
--
114
--
195
2.20.1
115
2.20.1
196
116
197
117
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
The qemu-block-drivers documentation is currently in
2
docs/qemu-block-drivers.texi in Texinfo format, which we present
3
to the user as:
4
* a qemu-block-drivers manpage
5
* a section of the main qemu-doc HTML documentation
2
6
3
Add probe_read alongside the write probing equivalent.
7
Convert the documentation to rST format, and present it to
8
the user as:
9
* a qemu-block-drivers manpage
10
* part of the system/ Sphinx manual
4
11
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
12
This follows the same pattern we've done for qemu-ga and qemu-nbd.
13
14
We have to drop a cross-reference from the documentation of the
15
-cdrom option back to the qemu-block-drivers documentation, since
16
they're no longer within the same texinfo document.
17
18
As noted in a comment, the manpage output is slightly compromised
19
due to limitations in Sphinx. In an ideal world, the HTML output
20
would have the various headings like 'Disk image file formats'
21
as top-level section headings (which then appear in the overall
22
system manual's table-of-contents), and it would not have the
23
section headings which make sense only for the manpage like
24
'synopsis', 'description', and 'see also'. Unfortunately, the
25
mechanism Sphinx provides for restricting pieces of documentation
26
is limited to the point of being flawed: the 'only::' directive
27
is implemented as a filter that is applied at a very late stage
28
in the document processing pipeline, rather than as an early
29
equivalent of an #ifdef. This means that Sphinx's process of
30
identifying which section heading markup styles are which levels
31
of heading gets confused if the 'only::' directive contains
32
section headings which would affect the heading-level of a
33
later heading. I have opted to prioritise making the HTML format
34
look better, with the compromise being that in the manpage
35
the 'Disk image file formats' &c headings are top-level headings
36
rather than being sub-headings under the traditional 'Description'
37
top-level section title.
38
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
40
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
41
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20191121000843.24844-2-beata.michalska@linaro.org
42
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Message-id: 20200116141511.16849-4-peter.maydell@linaro.org
10
---
44
---
11
include/exec/exec-all.h | 6 ++++++
45
Makefile | 11 +-
12
1 file changed, 6 insertions(+)
46
docs/qemu-block-drivers.texi | 889 --------------------------
47
docs/system/conf.py | 7 +
48
docs/system/index.rst | 1 +
49
docs/system/qemu-block-drivers.rst | 985 +++++++++++++++++++++++++++++
50
qemu-doc.texi | 12 -
51
qemu-options.hx | 2 +-
52
7 files changed, 1000 insertions(+), 907 deletions(-)
53
delete mode 100644 docs/qemu-block-drivers.texi
54
create mode 100644 docs/system/qemu-block-drivers.rst
13
55
14
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
56
diff --git a/Makefile b/Makefile
15
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/exec-all.h
58
--- a/Makefile
17
+++ b/include/exec/exec-all.h
59
+++ b/Makefile
18
@@ -XXX,XX +XXX,XX @@ static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
60
@@ -XXX,XX +XXX,XX @@ ifdef BUILD_DOCS
19
return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
61
DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1
20
}
62
DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-nbd.8
21
63
DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-ga.8
22
+static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
64
+DOCS+=$(MANUAL_BUILDDIR)/system/qemu-block-drivers.7
23
+ int mmu_idx, uintptr_t retaddr)
65
DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
24
+{
66
DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
25
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
67
-DOCS+=docs/qemu-block-drivers.7
26
+}
68
DOCS+=docs/qemu-cpu-models.7
27
+
69
DOCS+=$(MANUAL_BUILDDIR)/index.html
28
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
70
ifdef CONFIG_VIRTFS
29
71
@@ -XXX,XX +XXX,XX @@ distclean: clean
30
/* Estimated block size for TB allocation. */
72
    rm -f docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
73
    rm -f docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
74
    rm -f docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
75
-    rm -f docs/qemu-block-drivers.7
76
    rm -f docs/qemu-cpu-models.7
77
    rm -rf .doctrees
78
    $(call clean-manual,devel)
79
@@ -XXX,XX +XXX,XX @@ ifdef CONFIG_POSIX
80
    $(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
81
    $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man7"
82
    $(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
83
-    $(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
84
+    $(INSTALL_DATA) $(MANUAL_BUILDDIR)/system/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
85
    $(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7"
86
ifeq ($(CONFIG_TOOLS),y)
87
    $(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
88
@@ -XXX,XX +XXX,XX @@ $(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
89
$(MANUAL_BUILDDIR)/interop/qemu-nbd.8: $(call manual-deps,interop)
90
    $(call build-manual,interop,man)
91
92
+$(MANUAL_BUILDDIR)/system/qemu-block-drivers.7: $(call manual-deps,system)
93
+    $(call build-manual,system,man)
94
+
95
$(MANUAL_BUILDDIR)/index.html: $(SRC_PATH)/docs/index.html.in qemu-version.h
96
    @mkdir -p "$(MANUAL_BUILDDIR)"
97
    $(call quiet-command, sed "s|@@VERSION@@|${VERSION}|g" $< >$@, \
98
@@ -XXX,XX +XXX,XX @@ qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
99
qemu.1: qemu-option-trace.texi
100
qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
101
fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
102
-docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
103
docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
104
scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi
105
106
@@ -XXX,XX +XXX,XX @@ qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
107
    qemu-img.texi qemu-options.texi \
108
    qemu-tech.texi qemu-option-trace.texi \
109
    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi \
110
-    qemu-monitor-info.texi docs/qemu-block-drivers.texi \
111
+    qemu-monitor-info.texi \
112
    docs/qemu-cpu-models.texi docs/security.texi
113
114
docs/interop/qemu-ga-ref.dvi docs/interop/qemu-ga-ref.html \
115
diff --git a/docs/qemu-block-drivers.texi b/docs/qemu-block-drivers.texi
116
deleted file mode 100644
117
index XXXXXXX..XXXXXXX
118
--- a/docs/qemu-block-drivers.texi
119
+++ /dev/null
120
@@ -XXX,XX +XXX,XX @@
121
-@c man begin SYNOPSIS
122
-QEMU block driver reference manual
123
-@c man end
124
-
125
-@set qemu_system qemu-system-x86_64
126
-
127
-@c man begin DESCRIPTION
128
-
129
-@node disk_images_formats
130
-@subsection Disk image file formats
131
-
132
-QEMU supports many image file formats that can be used with VMs as well as with
133
-any of the tools (like @code{qemu-img}). This includes the preferred formats
134
-raw and qcow2 as well as formats that are supported for compatibility with
135
-older QEMU versions or other hypervisors.
136
-
137
-Depending on the image format, different options can be passed to
138
-@code{qemu-img create} and @code{qemu-img convert} using the @code{-o} option.
139
-This section describes each format and the options that are supported for it.
140
-
141
-@table @option
142
-@item raw
143
-
144
-Raw disk image format. This format has the advantage of
145
-being simple and easily exportable to all other emulators. If your
146
-file system supports @emph{holes} (for example in ext2 or ext3 on
147
-Linux or NTFS on Windows), then only the written sectors will reserve
148
-space. Use @code{qemu-img info} to know the real size used by the
149
-image or @code{ls -ls} on Unix/Linux.
150
-
151
-Supported options:
152
-@table @code
153
-@item preallocation
154
-Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
155
-@code{falloc} mode preallocates space for image by calling posix_fallocate().
156
-@code{full} mode preallocates space for image by writing data to underlying
157
-storage. This data may or may not be zero, depending on the storage location.
158
-@end table
159
-
160
-@item qcow2
161
-QEMU image format, the most versatile format. Use it to have smaller
162
-images (useful if your filesystem does not supports holes, for example
163
-on Windows), zlib based compression and support of multiple VM
164
-snapshots.
165
-
166
-Supported options:
167
-@table @code
168
-@item compat
169
-Determines the qcow2 version to use. @code{compat=0.10} uses the
170
-traditional image format that can be read by any QEMU since 0.10.
171
-@code{compat=1.1} enables image format extensions that only QEMU 1.1 and
172
-newer understand (this is the default). Amongst others, this includes
173
-zero clusters, which allow efficient copy-on-read for sparse images.
174
-
175
-@item backing_file
176
-File name of a base image (see @option{create} subcommand)
177
-@item backing_fmt
178
-Image format of the base image
179
-@item encryption
180
-This option is deprecated and equivalent to @code{encrypt.format=aes}
181
-
182
-@item encrypt.format
183
-
184
-If this is set to @code{luks}, it requests that the qcow2 payload (not
185
-qcow2 header) be encrypted using the LUKS format. The passphrase to
186
-use to unlock the LUKS key slot is given by the @code{encrypt.key-secret}
187
-parameter. LUKS encryption parameters can be tuned with the other
188
-@code{encrypt.*} parameters.
189
-
190
-If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
191
-The encryption key is given by the @code{encrypt.key-secret} parameter.
192
-This encryption format is considered to be flawed by modern cryptography
193
-standards, suffering from a number of design problems:
194
-
195
-@itemize @minus
196
-@item The AES-CBC cipher is used with predictable initialization vectors based
197
-on the sector number. This makes it vulnerable to chosen plaintext attacks
198
-which can reveal the existence of encrypted data.
199
-@item The user passphrase is directly used as the encryption key. A poorly
200
-chosen or short passphrase will compromise the security of the encryption.
201
-@item In the event of the passphrase being compromised there is no way to
202
-change the passphrase to protect data in any qcow images. The files must
203
-be cloned, using a different encryption passphrase in the new file. The
204
-original file must then be securely erased using a program like shred,
205
-though even this is ineffective with many modern storage technologies.
206
-@end itemize
207
-
208
-The use of this is no longer supported in system emulators. Support only
209
-remains in the command line utilities, for the purposes of data liberation
210
-and interoperability with old versions of QEMU. The @code{luks} format
211
-should be used instead.
212
-
213
-@item encrypt.key-secret
214
-
215
-Provides the ID of a @code{secret} object that contains the passphrase
216
-(@code{encrypt.format=luks}) or encryption key (@code{encrypt.format=aes}).
217
-
218
-@item encrypt.cipher-alg
219
-
220
-Name of the cipher algorithm and key length. Currently defaults
221
-to @code{aes-256}. Only used when @code{encrypt.format=luks}.
222
-
223
-@item encrypt.cipher-mode
224
-
225
-Name of the encryption mode to use. Currently defaults to @code{xts}.
226
-Only used when @code{encrypt.format=luks}.
227
-
228
-@item encrypt.ivgen-alg
229
-
230
-Name of the initialization vector generator algorithm. Currently defaults
231
-to @code{plain64}. Only used when @code{encrypt.format=luks}.
232
-
233
-@item encrypt.ivgen-hash-alg
234
-
235
-Name of the hash algorithm to use with the initialization vector generator
236
-(if required). Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
237
-
238
-@item encrypt.hash-alg
239
-
240
-Name of the hash algorithm to use for PBKDF algorithm
241
-Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
242
-
243
-@item encrypt.iter-time
244
-
245
-Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
246
-Defaults to @code{2000}. Only used when @code{encrypt.format=luks}.
247
-
248
-@item cluster_size
249
-Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
250
-sizes can improve the image file size whereas larger cluster sizes generally
251
-provide better performance.
252
-
253
-@item preallocation
254
-Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{falloc},
255
-@code{full}). An image with preallocated metadata is initially larger but can
256
-improve performance when the image needs to grow. @code{falloc} and @code{full}
257
-preallocations are like the same options of @code{raw} format, but sets up
258
-metadata also.
259
-
260
-@item lazy_refcounts
261
-If this option is set to @code{on}, reference count updates are postponed with
262
-the goal of avoiding metadata I/O and improving performance. This is
263
-particularly interesting with @option{cache=writethrough} which doesn't batch
264
-metadata updates. The tradeoff is that after a host crash, the reference count
265
-tables must be rebuilt, i.e. on the next open an (automatic) @code{qemu-img
266
-check -r all} is required, which may take some time.
267
-
268
-This option can only be enabled if @code{compat=1.1} is specified.
269
-
270
-@item nocow
271
-If this option is set to @code{on}, it will turn off COW of the file. It's only
272
-valid on btrfs, no effect on other file systems.
273
-
274
-Btrfs has low performance when hosting a VM image file, even more when the guest
275
-on the VM also using btrfs as file system. Turning off COW is a way to mitigate
276
-this bad performance. Generally there are two ways to turn off COW on btrfs:
277
-a) Disable it by mounting with nodatacow, then all newly created files will be
278
-NOCOW. b) For an empty file, add the NOCOW file attribute. That's what this option
279
-does.
280
-
281
-Note: this option is only valid to new or empty files. If there is an existing
282
-file which is COW and has data blocks already, it couldn't be changed to NOCOW
283
-by setting @code{nocow=on}. One can issue @code{lsattr filename} to check if
284
-the NOCOW flag is set or not (Capital 'C' is NOCOW flag).
285
-
286
-@end table
287
-
288
-@item qed
289
-Old QEMU image format with support for backing files and compact image files
290
-(when your filesystem or transport medium does not support holes).
291
-
292
-When converting QED images to qcow2, you might want to consider using the
293
-@code{lazy_refcounts=on} option to get a more QED-like behaviour.
294
-
295
-Supported options:
296
-@table @code
297
-@item backing_file
298
-File name of a base image (see @option{create} subcommand).
299
-@item backing_fmt
300
-Image file format of backing file (optional). Useful if the format cannot be
301
-autodetected because it has no header, like some vhd/vpc files.
302
-@item cluster_size
303
-Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
304
-cluster sizes can improve the image file size whereas larger cluster sizes
305
-generally provide better performance.
306
-@item table_size
307
-Changes the number of clusters per L1/L2 table (must be power-of-2 between 1
308
-and 16). There is normally no need to change this value but this option can be
309
-used for performance benchmarking.
310
-@end table
311
-
312
-@item qcow
313
-Old QEMU image format with support for backing files, compact image files,
314
-encryption and compression.
315
-
316
-Supported options:
317
-@table @code
318
-@item backing_file
319
-File name of a base image (see @option{create} subcommand)
320
-@item encryption
321
-This option is deprecated and equivalent to @code{encrypt.format=aes}
322
-
323
-@item encrypt.format
324
-If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
325
-The encryption key is given by the @code{encrypt.key-secret} parameter.
326
-This encryption format is considered to be flawed by modern cryptography
327
-standards, suffering from a number of design problems enumerated previously
328
-against the @code{qcow2} image format.
329
-
330
-The use of this is no longer supported in system emulators. Support only
331
-remains in the command line utilities, for the purposes of data liberation
332
-and interoperability with old versions of QEMU.
333
-
334
-Users requiring native encryption should use the @code{qcow2} format
335
-instead with @code{encrypt.format=luks}.
336
-
337
-@item encrypt.key-secret
338
-
339
-Provides the ID of a @code{secret} object that contains the encryption
340
-key (@code{encrypt.format=aes}).
341
-
342
-@end table
343
-
344
-@item luks
345
-
346
-LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
347
-
348
-Supported options:
349
-@table @code
350
-
351
-@item key-secret
352
-
353
-Provides the ID of a @code{secret} object that contains the passphrase.
354
-
355
-@item cipher-alg
356
-
357
-Name of the cipher algorithm and key length. Currently defaults
358
-to @code{aes-256}.
359
-
360
-@item cipher-mode
361
-
362
-Name of the encryption mode to use. Currently defaults to @code{xts}.
363
-
364
-@item ivgen-alg
365
-
366
-Name of the initialization vector generator algorithm. Currently defaults
367
-to @code{plain64}.
368
-
369
-@item ivgen-hash-alg
370
-
371
-Name of the hash algorithm to use with the initialization vector generator
372
-(if required). Defaults to @code{sha256}.
373
-
374
-@item hash-alg
375
-
376
-Name of the hash algorithm to use for PBKDF algorithm
377
-Defaults to @code{sha256}.
378
-
379
-@item iter-time
380
-
381
-Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
382
-Defaults to @code{2000}.
383
-
384
-@end table
385
-
386
-@item vdi
387
-VirtualBox 1.1 compatible image format.
388
-Supported options:
389
-@table @code
390
-@item static
391
-If this option is set to @code{on}, the image is created with metadata
392
-preallocation.
393
-@end table
394
-
395
-@item vmdk
396
-VMware 3 and 4 compatible image format.
397
-
398
-Supported options:
399
-@table @code
400
-@item backing_file
401
-File name of a base image (see @option{create} subcommand).
402
-@item compat6
403
-Create a VMDK version 6 image (instead of version 4)
404
-@item hwversion
405
-Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
406
-if hwversion is specified.
407
-@item subformat
408
-Specifies which VMDK subformat to use. Valid options are
409
-@code{monolithicSparse} (default),
410
-@code{monolithicFlat},
411
-@code{twoGbMaxExtentSparse},
412
-@code{twoGbMaxExtentFlat} and
413
-@code{streamOptimized}.
414
-@end table
415
-
416
-@item vpc
417
-VirtualPC compatible image format (VHD).
418
-Supported options:
419
-@table @code
420
-@item subformat
421
-Specifies which VHD subformat to use. Valid options are
422
-@code{dynamic} (default) and @code{fixed}.
423
-@end table
424
-
425
-@item VHDX
426
-Hyper-V compatible image format (VHDX).
427
-Supported options:
428
-@table @code
429
-@item subformat
430
-Specifies which VHDX subformat to use. Valid options are
431
-@code{dynamic} (default) and @code{fixed}.
432
-@item block_state_zero
433
-Force use of payload blocks of type 'ZERO'. Can be set to @code{on} (default)
434
-or @code{off}. When set to @code{off}, new blocks will be created as
435
-@code{PAYLOAD_BLOCK_NOT_PRESENT}, which means parsers are free to return
436
-arbitrary data for those blocks. Do not set to @code{off} when using
437
-@code{qemu-img convert} with @code{subformat=dynamic}.
438
-@item block_size
439
-Block size; min 1 MB, max 256 MB. 0 means auto-calculate based on image size.
440
-@item log_size
441
-Log size; min 1 MB.
442
-@end table
443
-@end table
444
-
445
-@subsubsection Read-only formats
446
-More disk image file formats are supported in a read-only mode.
447
-@table @option
448
-@item bochs
449
-Bochs images of @code{growing} type.
450
-@item cloop
451
-Linux Compressed Loop image, useful only to reuse directly compressed
452
-CD-ROM images present for example in the Knoppix CD-ROMs.
453
-@item dmg
454
-Apple disk image.
455
-@item parallels
456
-Parallels disk image format.
457
-@end table
458
-
459
-
460
-@node host_drives
461
-@subsection Using host drives
462
-
463
-In addition to disk image files, QEMU can directly access host
464
-devices. We describe here the usage for QEMU version >= 0.8.3.
465
-
466
-@subsubsection Linux
467
-
468
-On Linux, you can directly use the host device filename instead of a
469
-disk image filename provided you have enough privileges to access
470
-it. For example, use @file{/dev/cdrom} to access to the CDROM.
471
-
472
-@table @code
473
-@item CD
474
-You can specify a CDROM device even if no CDROM is loaded. QEMU has
475
-specific code to detect CDROM insertion or removal. CDROM ejection by
476
-the guest OS is supported. Currently only data CDs are supported.
477
-@item Floppy
478
-You can specify a floppy device even if no floppy is loaded. Floppy
479
-removal is currently not detected accurately (if you change floppy
480
-without doing floppy access while the floppy is not loaded, the guest
481
-OS will think that the same floppy is loaded).
482
-Use of the host's floppy device is deprecated, and support for it will
483
-be removed in a future release.
484
-@item Hard disks
485
-Hard disks can be used. Normally you must specify the whole disk
486
-(@file{/dev/hdb} instead of @file{/dev/hdb1}) so that the guest OS can
487
-see it as a partitioned disk. WARNING: unless you know what you do, it
488
-is better to only make READ-ONLY accesses to the hard disk otherwise
489
-you may corrupt your host data (use the @option{-snapshot} command
490
-line option or modify the device permissions accordingly).
491
-@end table
492
-
493
-@subsubsection Windows
494
-
495
-@table @code
496
-@item CD
497
-The preferred syntax is the drive letter (e.g. @file{d:}). The
498
-alternate syntax @file{\\.\d:} is supported. @file{/dev/cdrom} is
499
-supported as an alias to the first CDROM drive.
500
-
501
-Currently there is no specific code to handle removable media, so it
502
-is better to use the @code{change} or @code{eject} monitor commands to
503
-change or eject media.
504
-@item Hard disks
505
-Hard disks can be used with the syntax: @file{\\.\PhysicalDrive@var{N}}
506
-where @var{N} is the drive number (0 is the first hard disk).
507
-
508
-WARNING: unless you know what you do, it is better to only make
509
-READ-ONLY accesses to the hard disk otherwise you may corrupt your
510
-host data (use the @option{-snapshot} command line so that the
511
-modifications are written in a temporary file).
512
-@end table
513
-
514
-
515
-@subsubsection Mac OS X
516
-
517
-@file{/dev/cdrom} is an alias to the first CDROM.
518
-
519
-Currently there is no specific code to handle removable media, so it
520
-is better to use the @code{change} or @code{eject} monitor commands to
521
-change or eject media.
522
-
523
-@node disk_images_fat_images
524
-@subsection Virtual FAT disk images
525
-
526
-QEMU can automatically create a virtual FAT disk image from a
527
-directory tree. In order to use it, just type:
528
-
529
-@example
530
-@value{qemu_system} linux.img -hdb fat:/my_directory
531
-@end example
532
-
533
-Then you access access to all the files in the @file{/my_directory}
534
-directory without having to copy them in a disk image or to export
535
-them via SAMBA or NFS. The default access is @emph{read-only}.
536
-
537
-Floppies can be emulated with the @code{:floppy:} option:
538
-
539
-@example
540
-@value{qemu_system} linux.img -fda fat:floppy:/my_directory
541
-@end example
542
-
543
-A read/write support is available for testing (beta stage) with the
544
-@code{:rw:} option:
545
-
546
-@example
547
-@value{qemu_system} linux.img -fda fat:floppy:rw:/my_directory
548
-@end example
549
-
550
-What you should @emph{never} do:
551
-@itemize
552
-@item use non-ASCII filenames ;
553
-@item use "-snapshot" together with ":rw:" ;
554
-@item expect it to work when loadvm'ing ;
555
-@item write to the FAT directory on the host system while accessing it with the guest system.
556
-@end itemize
557
-
558
-@node disk_images_nbd
559
-@subsection NBD access
560
-
561
-QEMU can access directly to block device exported using the Network Block Device
562
-protocol.
563
-
564
-@example
565
-@value{qemu_system} linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
566
-@end example
567
-
568
-If the NBD server is located on the same host, you can use an unix socket instead
569
-of an inet socket:
570
-
571
-@example
572
-@value{qemu_system} linux.img -hdb nbd+unix://?socket=/tmp/my_socket
573
-@end example
574
-
575
-In this case, the block device must be exported using qemu-nbd:
576
-
577
-@example
578
-qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
579
-@end example
580
-
581
-The use of qemu-nbd allows sharing of a disk between several guests:
582
-@example
583
-qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
584
-@end example
585
-
586
-@noindent
587
-and then you can use it with two guests:
588
-@example
589
-@value{qemu_system} linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
590
-@value{qemu_system} linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
591
-@end example
592
-
593
-If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
594
-own embedded NBD server), you must specify an export name in the URI:
595
-@example
596
-@value{qemu_system} -cdrom nbd://localhost/debian-500-ppc-netinst
597
-@value{qemu_system} -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
598
-@end example
599
-
600
-The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is
601
-also available. Here are some example of the older syntax:
602
-@example
603
-@value{qemu_system} linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
604
-@value{qemu_system} linux2.img -hdb nbd:unix:/tmp/my_socket
605
-@value{qemu_system} -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
606
-@end example
607
-
608
-@node disk_images_sheepdog
609
-@subsection Sheepdog disk images
610
-
611
-Sheepdog is a distributed storage system for QEMU. It provides highly
612
-available block level storage volumes that can be attached to
613
-QEMU-based virtual machines.
614
-
615
-You can create a Sheepdog disk image with the command:
616
-@example
617
-qemu-img create sheepdog:///@var{image} @var{size}
618
-@end example
619
-where @var{image} is the Sheepdog image name and @var{size} is its
620
-size.
621
-
622
-To import the existing @var{filename} to Sheepdog, you can use a
623
-convert command.
624
-@example
625
-qemu-img convert @var{filename} sheepdog:///@var{image}
626
-@end example
627
-
628
-You can boot from the Sheepdog disk image with the command:
629
-@example
630
-@value{qemu_system} sheepdog:///@var{image}
631
-@end example
632
-
633
-You can also create a snapshot of the Sheepdog image like qcow2.
634
-@example
635
-qemu-img snapshot -c @var{tag} sheepdog:///@var{image}
636
-@end example
637
-where @var{tag} is a tag name of the newly created snapshot.
638
-
639
-To boot from the Sheepdog snapshot, specify the tag name of the
640
-snapshot.
641
-@example
642
-@value{qemu_system} sheepdog:///@var{image}#@var{tag}
643
-@end example
644
-
645
-You can create a cloned image from the existing snapshot.
646
-@example
647
-qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image}
648
-@end example
649
-where @var{base} is an image name of the source snapshot and @var{tag}
650
-is its tag name.
651
-
652
-You can use an unix socket instead of an inet socket:
653
-
654
-@example
655
-@value{qemu_system} sheepdog+unix:///@var{image}?socket=@var{path}
656
-@end example
657
-
658
-If the Sheepdog daemon doesn't run on the local host, you need to
659
-specify one of the Sheepdog servers to connect to.
660
-@example
661
-qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
662
-@value{qemu_system} sheepdog://@var{hostname}:@var{port}/@var{image}
663
-@end example
664
-
665
-@node disk_images_iscsi
666
-@subsection iSCSI LUNs
667
-
668
-iSCSI is a popular protocol used to access SCSI devices across a computer
669
-network.
670
-
671
-There are two different ways iSCSI devices can be used by QEMU.
672
-
673
-The first method is to mount the iSCSI LUN on the host, and make it appear as
674
-any other ordinary SCSI device on the host and then to access this device as a
675
-/dev/sd device from QEMU. How to do this differs between host OSes.
676
-
677
-The second method involves using the iSCSI initiator that is built into
678
-QEMU. This provides a mechanism that works the same way regardless of which
679
-host OS you are running QEMU on. This section will describe this second method
680
-of using iSCSI together with QEMU.
681
-
682
-In QEMU, iSCSI devices are described using special iSCSI URLs
683
-
684
-@example
685
-URL syntax:
686
-iscsi://[<username>[%<password>]@@]<host>[:<port>]/<target-iqn-name>/<lun>
687
-@end example
688
-
689
-Username and password are optional and only used if your target is set up
690
-using CHAP authentication for access control.
691
-Alternatively the username and password can also be set via environment
692
-variables to have these not show up in the process list
693
-
694
-@example
695
-export LIBISCSI_CHAP_USERNAME=<username>
696
-export LIBISCSI_CHAP_PASSWORD=<password>
697
-iscsi://<host>/<target-iqn-name>/<lun>
698
-@end example
699
-
700
-Various session related parameters can be set via special options, either
701
-in a configuration file provided via '-readconfig' or directly on the
702
-command line.
703
-
704
-If the initiator-name is not specified qemu will use a default name
705
-of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
706
-virtual machine. If the UUID is not specified qemu will use
707
-'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
708
-virtual machine.
709
-
710
-@example
711
-Setting a specific initiator name to use when logging in to the target
712
--iscsi initiator-name=iqn.qemu.test:my-initiator
713
-@end example
714
-
715
-@example
716
-Controlling which type of header digest to negotiate with the target
717
--iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
718
-@end example
719
-
720
-These can also be set via a configuration file
721
-@example
722
-[iscsi]
723
- user = "CHAP username"
724
- password = "CHAP password"
725
- initiator-name = "iqn.qemu.test:my-initiator"
726
- # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
727
- header-digest = "CRC32C"
728
-@end example
729
-
730
-
731
-Setting the target name allows different options for different targets
732
-@example
733
-[iscsi "iqn.target.name"]
734
- user = "CHAP username"
735
- password = "CHAP password"
736
- initiator-name = "iqn.qemu.test:my-initiator"
737
- # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
738
- header-digest = "CRC32C"
739
-@end example
740
-
741
-
742
-Howto use a configuration file to set iSCSI configuration options:
743
-@example
744
-cat >iscsi.conf <<EOF
745
-[iscsi]
746
- user = "me"
747
- password = "my password"
748
- initiator-name = "iqn.qemu.test:my-initiator"
749
- header-digest = "CRC32C"
750
-EOF
751
-
752
-@value{qemu_system} -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
753
- -readconfig iscsi.conf
754
-@end example
755
-
756
-
757
-How to set up a simple iSCSI target on loopback and access it via QEMU:
758
-@example
759
-This example shows how to set up an iSCSI target with one CDROM and one DISK
760
-using the Linux STGT software target. This target is available on Red Hat based
761
-systems as the package 'scsi-target-utils'.
762
-
763
-tgtd --iscsi portal=127.0.0.1:3260
764
-tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
765
-tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \
766
- -b /IMAGES/disk.img --device-type=disk
767
-tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \
768
- -b /IMAGES/cd.iso --device-type=cd
769
-tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
770
-
771
-@value{qemu_system} -iscsi initiator-name=iqn.qemu.test:my-initiator \
772
- -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
773
- -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
774
-@end example
775
-
776
-@node disk_images_gluster
777
-@subsection GlusterFS disk images
778
-
779
-GlusterFS is a user space distributed file system.
780
-
781
-You can boot from the GlusterFS disk image with the command:
782
-@example
783
-URI:
784
-@value{qemu_system} -drive file=gluster[+@var{type}]://[@var{host}[:@var{port}]]/@var{volume}/@var{path}
785
- [?socket=...][,file.debug=9][,file.logfile=...]
786
-
787
-JSON:
788
-@value{qemu_system} 'json:@{"driver":"qcow2",
789
- "file":@{"driver":"gluster",
790
- "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
791
- "server":[@{"type":"tcp","host":"...","port":"..."@},
792
- @{"type":"unix","socket":"..."@}]@}@}'
793
-@end example
794
-
795
-@var{gluster} is the protocol.
796
-
797
-@var{type} specifies the transport type used to connect to gluster
798
-management daemon (glusterd). Valid transport types are
799
-tcp and unix. In the URI form, if a transport type isn't specified,
800
-then tcp type is assumed.
801
-
802
-@var{host} specifies the server where the volume file specification for
803
-the given volume resides. This can be either a hostname or an ipv4 address.
804
-If transport type is unix, then @var{host} field should not be specified.
805
-Instead @var{socket} field needs to be populated with the path to unix domain
806
-socket.
807
-
808
-@var{port} is the port number on which glusterd is listening. This is optional
809
-and if not specified, it defaults to port 24007. If the transport type is unix,
810
-then @var{port} should not be specified.
811
-
812
-@var{volume} is the name of the gluster volume which contains the disk image.
813
-
814
-@var{path} is the path to the actual disk image that resides on gluster volume.
815
-
816
-@var{debug} is the logging level of the gluster protocol driver. Debug levels
817
-are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
818
-The default level is 4. The current logging levels defined in the gluster source
819
-are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
820
-6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
821
-
822
-@var{logfile} is a commandline option to mention log file path which helps in
823
-logging to the specified file and also help in persisting the gfapi logs. The
824
-default is stderr.
825
-
826
-
827
-
828
-
829
-You can create a GlusterFS disk image with the command:
830
-@example
831
-qemu-img create gluster://@var{host}/@var{volume}/@var{path} @var{size}
832
-@end example
833
-
834
-Examples
835
-@example
836
-@value{qemu_system} -drive file=gluster://1.2.3.4/testvol/a.img
837
-@value{qemu_system} -drive file=gluster+tcp://1.2.3.4/testvol/a.img
838
-@value{qemu_system} -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
839
-@value{qemu_system} -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
840
-@value{qemu_system} -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
841
-@value{qemu_system} -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
842
-@value{qemu_system} -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
843
-@value{qemu_system} -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
844
-@value{qemu_system} -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
845
-@value{qemu_system} 'json:@{"driver":"qcow2",
846
- "file":@{"driver":"gluster",
847
- "volume":"testvol","path":"a.img",
848
- "debug":9,"logfile":"/var/log/qemu-gluster.log",
849
- "server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
850
- @{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
851
-@value{qemu_system} -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
852
- file.debug=9,file.logfile=/var/log/qemu-gluster.log,
853
- file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
854
- file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
855
-@end example
856
-
857
-@node disk_images_ssh
858
-@subsection Secure Shell (ssh) disk images
859
-
860
-You can access disk images located on a remote ssh server
861
-by using the ssh protocol:
862
-
863
-@example
864
-@value{qemu_system} -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
865
-@end example
866
-
867
-Alternative syntax using properties:
868
-
869
-@example
870
-@value{qemu_system} -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
871
-@end example
872
-
873
-@var{ssh} is the protocol.
874
-
875
-@var{user} is the remote user. If not specified, then the local
876
-username is tried.
877
-
878
-@var{server} specifies the remote ssh server. Any ssh server can be
879
-used, but it must implement the sftp-server protocol. Most Unix/Linux
880
-systems should work without requiring any extra configuration.
881
-
882
-@var{port} is the port number on which sshd is listening. By default
883
-the standard ssh port (22) is used.
884
-
885
-@var{path} is the path to the disk image.
886
-
887
-The optional @var{host_key_check} parameter controls how the remote
888
-host's key is checked. The default is @code{yes} which means to use
889
-the local @file{.ssh/known_hosts} file. Setting this to @code{no}
890
-turns off known-hosts checking. Or you can check that the host key
891
-matches a specific fingerprint:
892
-@code{host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8}
893
-(@code{sha1:} can also be used as a prefix, but note that OpenSSH
894
-tools only use MD5 to print fingerprints).
895
-
896
-Currently authentication must be done using ssh-agent. Other
897
-authentication methods may be supported in future.
898
-
899
-Note: Many ssh servers do not support an @code{fsync}-style operation.
900
-The ssh driver cannot guarantee that disk flush requests are
901
-obeyed, and this causes a risk of disk corruption if the remote
902
-server or network goes down during writes. The driver will
903
-print a warning when @code{fsync} is not supported:
904
-
905
-warning: ssh server @code{ssh.example.com:22} does not support fsync
906
-
907
-With sufficiently new versions of libssh and OpenSSH, @code{fsync} is
908
-supported.
909
-
910
-@node disk_images_nvme
911
-@subsection NVMe disk images
912
-
913
-NVM Express (NVMe) storage controllers can be accessed directly by a userspace
914
-driver in QEMU. This bypasses the host kernel file system and block layers
915
-while retaining QEMU block layer functionalities, such as block jobs, I/O
916
-throttling, image formats, etc. Disk I/O performance is typically higher than
917
-with @code{-drive file=/dev/sda} using either thread pool or linux-aio.
918
-
919
-The controller will be exclusively used by the QEMU process once started. To be
920
-able to share storage between multiple VMs and other applications on the host,
921
-please use the file based protocols.
922
-
923
-Before starting QEMU, bind the host NVMe controller to the host vfio-pci
924
-driver. For example:
925
-
926
-@example
927
-# modprobe vfio-pci
928
-# lspci -n -s 0000:06:0d.0
929
-06:0d.0 0401: 1102:0002 (rev 08)
930
-# echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
931
-# echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
932
-
933
-# @value{qemu_system} -drive file=nvme://@var{host}:@var{bus}:@var{slot}.@var{func}/@var{namespace}
934
-@end example
935
-
936
-Alternative syntax using properties:
937
-
938
-@example
939
-@value{qemu_system} -drive file.driver=nvme,file.device=@var{host}:@var{bus}:@var{slot}.@var{func},file.namespace=@var{namespace}
940
-@end example
941
-
942
-@var{host}:@var{bus}:@var{slot}.@var{func} is the NVMe controller's PCI device
943
-address on the host.
944
-
945
-@var{namespace} is the NVMe namespace number, starting from 1.
946
-
947
-@node disk_image_locking
948
-@subsection Disk image file locking
949
-
950
-By default, QEMU tries to protect image files from unexpected concurrent
951
-access, as long as it's supported by the block protocol driver and host
952
-operating system. If multiple QEMU processes (including QEMU emulators and
953
-utilities) try to open the same image with conflicting accessing modes, all but
954
-the first one will get an error.
955
-
956
-This feature is currently supported by the file protocol on Linux with the Open
957
-File Descriptor (OFD) locking API, and can be configured to fall back to POSIX
958
-locking if the POSIX host doesn't support Linux OFD locking.
959
-
960
-To explicitly enable image locking, specify "locking=on" in the file protocol
961
-driver options. If OFD locking is not possible, a warning will be printed and
962
-the POSIX locking API will be used. In this case there is a risk that the lock
963
-will get silently lost when doing hot plugging and block jobs, due to the
964
-shortcomings of the POSIX locking API.
965
-
966
-QEMU transparently handles lock handover during shared storage migration. For
967
-shared virtual disk images between multiple VMs, the "share-rw" device option
968
-should be used.
969
-
970
-By default, the guest has exclusive write access to its disk image. If the
971
-guest can safely share the disk image with other writers the @code{-device
972
-...,share-rw=on} parameter can be used. This is only safe if the guest is
973
-running software, such as a cluster file system, that coordinates disk accesses
974
-to avoid corruption.
975
-
976
-Note that share-rw=on only declares the guest's ability to share the disk.
977
-Some QEMU features, such as image file formats, require exclusive write access
978
-to the disk image and this is unaffected by the share-rw=on option.
979
-
980
-Alternatively, locking can be fully disabled by "locking=off" block device
981
-option. In the command line, the option is usually in the form of
982
-"file.locking=off" as the protocol driver is normally placed as a "file" child
983
-under a format driver. For example:
984
-
985
-@code{-blockdev driver=qcow2,file.filename=/path/to/image,file.locking=off,file.driver=file}
986
-
987
-To check if image locking is active, check the output of the "lslocks" command
988
-on host and see if there are locks held by the QEMU process on the image file.
989
-More than one byte could be locked by the QEMU instance, each byte of which
990
-reflects a particular permission that is acquired or protected by the running
991
-block driver.
992
-
993
-@c man end
994
-
995
-@ignore
996
-
997
-@setfilename qemu-block-drivers
998
-@settitle QEMU block drivers reference
999
-
1000
-@c man begin SEEALSO
1001
-The HTML documentation of QEMU for more precise information and Linux
1002
-user mode emulator invocation.
1003
-@c man end
1004
-
1005
-@c man begin AUTHOR
1006
-Fabrice Bellard and the QEMU Project developers
1007
-@c man end
1008
-
1009
-@end ignore
1010
diff --git a/docs/system/conf.py b/docs/system/conf.py
1011
index XXXXXXX..XXXXXXX 100644
1012
--- a/docs/system/conf.py
1013
+++ b/docs/system/conf.py
1014
@@ -XXX,XX +XXX,XX @@ exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
1015
# This slightly misuses the 'description', but is the best way to get
1016
# the manual title to appear in the sidebar.
1017
html_theme_options['description'] = u'System Emulation User''s Guide'
1018
+# One entry per manual page. List of tuples
1019
+# (source start file, name, description, authors, manual section).
1020
+man_pages = [
1021
+ ('qemu-block-drivers', 'qemu-block-drivers',
1022
+ u'QEMU block drivers reference',
1023
+ ['Fabrice Bellard and the QEMU Project developers'], 7)
1024
+]
1025
diff --git a/docs/system/index.rst b/docs/system/index.rst
1026
index XXXXXXX..XXXXXXX 100644
1027
--- a/docs/system/index.rst
1028
+++ b/docs/system/index.rst
1029
@@ -XXX,XX +XXX,XX @@ Contents:
1030
.. toctree::
1031
:maxdepth: 2
1032
1033
+ qemu-block-drivers
1034
diff --git a/docs/system/qemu-block-drivers.rst b/docs/system/qemu-block-drivers.rst
1035
new file mode 100644
1036
index XXXXXXX..XXXXXXX
1037
--- /dev/null
1038
+++ b/docs/system/qemu-block-drivers.rst
1039
@@ -XXX,XX +XXX,XX @@
1040
+QEMU block drivers reference
1041
+============================
1042
+
1043
+.. |qemu_system| replace:: qemu-system-x86_64
1044
+
1045
+..
1046
+ We put the 'Synopsis' and 'See also' sections into the manpage, but not
1047
+ the HTML. This makes the HTML docs read better and means the ToC in
1048
+ the index has a more useful set of entries. Ideally, the section
1049
+ headings 'Disk image file formats' would be top-level headings for
1050
+ the HTML, but sub-headings of the conventional manpage 'Description'
1051
+ header for the manpage. Unfortunately, due to deficiencies in
1052
+ the Sphinx 'only' directive, this isn't possible: they must be headers
1053
+ at the same level as 'Synopsis' and 'See also', otherwise Sphinx's
1054
+ identification of which header underline style is which gets confused.
1055
+
1056
+.. only:: man
1057
+
1058
+ Synopsis
1059
+ --------
1060
+
1061
+ QEMU block driver reference manual
1062
+
1063
+Disk image file formats
1064
+-----------------------
1065
+
1066
+QEMU supports many image file formats that can be used with VMs as well as with
1067
+any of the tools (like ``qemu-img``). This includes the preferred formats
1068
+raw and qcow2 as well as formats that are supported for compatibility with
1069
+older QEMU versions or other hypervisors.
1070
+
1071
+Depending on the image format, different options can be passed to
1072
+``qemu-img create`` and ``qemu-img convert`` using the ``-o`` option.
1073
+This section describes each format and the options that are supported for it.
1074
+
1075
+.. program:: image-formats
1076
+.. option:: raw
1077
+
1078
+ Raw disk image format. This format has the advantage of
1079
+ being simple and easily exportable to all other emulators. If your
1080
+ file system supports *holes* (for example in ext2 or ext3 on
1081
+ Linux or NTFS on Windows), then only the written sectors will reserve
1082
+ space. Use ``qemu-img info`` to know the real size used by the
1083
+ image or ``ls -ls`` on Unix/Linux.
1084
+
1085
+ Supported options:
1086
+
1087
+ .. program:: raw
1088
+ .. option:: preallocation
1089
+
1090
+ Preallocation mode (allowed values: ``off``, ``falloc``,
1091
+ ``full``). ``falloc`` mode preallocates space for image by
1092
+ calling ``posix_fallocate()``. ``full`` mode preallocates space
1093
+ for image by writing data to underlying storage. This data may or
1094
+ may not be zero, depending on the storage location.
1095
+
1096
+.. program:: image-formats
1097
+.. option:: qcow2
1098
+
1099
+ QEMU image format, the most versatile format. Use it to have smaller
1100
+ images (useful if your filesystem does not supports holes, for example
1101
+ on Windows), zlib based compression and support of multiple VM
1102
+ snapshots.
1103
+
1104
+ Supported options:
1105
+
1106
+ .. program:: qcow2
1107
+ .. option:: compat
1108
+
1109
+ Determines the qcow2 version to use. ``compat=0.10`` uses the
1110
+ traditional image format that can be read by any QEMU since 0.10.
1111
+ ``compat=1.1`` enables image format extensions that only QEMU 1.1 and
1112
+ newer understand (this is the default). Amongst others, this includes
1113
+ zero clusters, which allow efficient copy-on-read for sparse images.
1114
+
1115
+ .. option:: backing_file
1116
+
1117
+ File name of a base image (see ``create`` subcommand)
1118
+
1119
+ .. option:: backing_fmt
1120
+
1121
+ Image format of the base image
1122
+
1123
+ .. option:: encryption
1124
+
1125
+ This option is deprecated and equivalent to ``encrypt.format=aes``
1126
+
1127
+ .. option:: encrypt.format
1128
+
1129
+ If this is set to ``luks``, it requests that the qcow2 payload (not
1130
+ qcow2 header) be encrypted using the LUKS format. The passphrase to
1131
+ use to unlock the LUKS key slot is given by the ``encrypt.key-secret``
1132
+ parameter. LUKS encryption parameters can be tuned with the other
1133
+ ``encrypt.*`` parameters.
1134
+
1135
+ If this is set to ``aes``, the image is encrypted with 128-bit AES-CBC.
1136
+ The encryption key is given by the ``encrypt.key-secret`` parameter.
1137
+ This encryption format is considered to be flawed by modern cryptography
1138
+ standards, suffering from a number of design problems:
1139
+
1140
+ - The AES-CBC cipher is used with predictable initialization vectors based
1141
+ on the sector number. This makes it vulnerable to chosen plaintext attacks
1142
+ which can reveal the existence of encrypted data.
1143
+ - The user passphrase is directly used as the encryption key. A poorly
1144
+ chosen or short passphrase will compromise the security of the encryption.
1145
+ - In the event of the passphrase being compromised there is no way to
1146
+ change the passphrase to protect data in any qcow images. The files must
1147
+ be cloned, using a different encryption passphrase in the new file. The
1148
+ original file must then be securely erased using a program like shred,
1149
+ though even this is ineffective with many modern storage technologies.
1150
+
1151
+ The use of this is no longer supported in system emulators. Support only
1152
+ remains in the command line utilities, for the purposes of data liberation
1153
+ and interoperability with old versions of QEMU. The ``luks`` format
1154
+ should be used instead.
1155
+
1156
+ .. option:: encrypt.key-secret
1157
+
1158
+ Provides the ID of a ``secret`` object that contains the passphrase
1159
+ (``encrypt.format=luks``) or encryption key (``encrypt.format=aes``).
1160
+
1161
+ .. option:: encrypt.cipher-alg
1162
+
1163
+ Name of the cipher algorithm and key length. Currently defaults
1164
+ to ``aes-256``. Only used when ``encrypt.format=luks``.
1165
+
1166
+ .. option:: encrypt.cipher-mode
1167
+
1168
+ Name of the encryption mode to use. Currently defaults to ``xts``.
1169
+ Only used when ``encrypt.format=luks``.
1170
+
1171
+ .. option:: encrypt.ivgen-alg
1172
+
1173
+ Name of the initialization vector generator algorithm. Currently defaults
1174
+ to ``plain64``. Only used when ``encrypt.format=luks``.
1175
+
1176
+ .. option:: encrypt.ivgen-hash-alg
1177
+
1178
+ Name of the hash algorithm to use with the initialization vector generator
1179
+ (if required). Defaults to ``sha256``. Only used when ``encrypt.format=luks``.
1180
+
1181
+ .. option:: encrypt.hash-alg
1182
+
1183
+ Name of the hash algorithm to use for PBKDF algorithm
1184
+ Defaults to ``sha256``. Only used when ``encrypt.format=luks``.
1185
+
1186
+ .. option:: encrypt.iter-time
1187
+
1188
+ Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
1189
+ Defaults to ``2000``. Only used when ``encrypt.format=luks``.
1190
+
1191
+ .. option:: cluster_size
1192
+
1193
+ Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
1194
+ sizes can improve the image file size whereas larger cluster sizes generally
1195
+ provide better performance.
1196
+
1197
+ .. option:: preallocation
1198
+
1199
+ Preallocation mode (allowed values: ``off``, ``metadata``, ``falloc``,
1200
+ ``full``). An image with preallocated metadata is initially larger but can
1201
+ improve performance when the image needs to grow. ``falloc`` and ``full``
1202
+ preallocations are like the same options of ``raw`` format, but sets up
1203
+ metadata also.
1204
+
1205
+ .. option:: lazy_refcounts
1206
+
1207
+ If this option is set to ``on``, reference count updates are postponed with
1208
+ the goal of avoiding metadata I/O and improving performance. This is
1209
+ particularly interesting with :option:`cache=writethrough` which doesn't batch
1210
+ metadata updates. The tradeoff is that after a host crash, the reference count
1211
+ tables must be rebuilt, i.e. on the next open an (automatic) ``qemu-img
1212
+ check -r all`` is required, which may take some time.
1213
+
1214
+ This option can only be enabled if ``compat=1.1`` is specified.
1215
+
1216
+ .. option:: nocow
1217
+
1218
+ If this option is set to ``on``, it will turn off COW of the file. It's only
1219
+ valid on btrfs, no effect on other file systems.
1220
+
1221
+ Btrfs has low performance when hosting a VM image file, even more
1222
+ when the guest on the VM also using btrfs as file system. Turning off
1223
+ COW is a way to mitigate this bad performance. Generally there are two
1224
+ ways to turn off COW on btrfs:
1225
+
1226
+ - Disable it by mounting with nodatacow, then all newly created files
1227
+ will be NOCOW.
1228
+ - For an empty file, add the NOCOW file attribute. That's what this
1229
+ option does.
1230
+
1231
+ Note: this option is only valid to new or empty files. If there is
1232
+ an existing file which is COW and has data blocks already, it couldn't
1233
+ be changed to NOCOW by setting ``nocow=on``. One can issue ``lsattr
1234
+ filename`` to check if the NOCOW flag is set or not (Capital 'C' is
1235
+ NOCOW flag).
1236
+
1237
+.. program:: image-formats
1238
+.. option:: qed
1239
+
1240
+ Old QEMU image format with support for backing files and compact image files
1241
+ (when your filesystem or transport medium does not support holes).
1242
+
1243
+ When converting QED images to qcow2, you might want to consider using the
1244
+ ``lazy_refcounts=on`` option to get a more QED-like behaviour.
1245
+
1246
+ Supported options:
1247
+
1248
+ .. program:: qed
1249
+ .. option:: backing_file
1250
+
1251
+ File name of a base image (see ``create`` subcommand).
1252
+
1253
+ .. option:: backing_fmt
1254
+
1255
+ Image file format of backing file (optional). Useful if the format cannot be
1256
+ autodetected because it has no header, like some vhd/vpc files.
1257
+
1258
+ .. option:: cluster_size
1259
+
1260
+ Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
1261
+ cluster sizes can improve the image file size whereas larger cluster sizes
1262
+ generally provide better performance.
1263
+
1264
+ .. option:: table_size
1265
+
1266
+ Changes the number of clusters per L1/L2 table (must be
1267
+ power-of-2 between 1 and 16). There is normally no need to
1268
+ change this value but this option can between used for
1269
+ performance benchmarking.
1270
+
1271
+.. program:: image-formats
1272
+.. option:: qcow
1273
+
1274
+ Old QEMU image format with support for backing files, compact image files,
1275
+ encryption and compression.
1276
+
1277
+ Supported options:
1278
+
1279
+ .. program:: qcow
1280
+ .. option:: backing_file
1281
+
1282
+ File name of a base image (see ``create`` subcommand)
1283
+
1284
+ .. option:: encryption
1285
+
1286
+ This option is deprecated and equivalent to ``encrypt.format=aes``
1287
+
1288
+ .. option:: encrypt.format
1289
+
1290
+ If this is set to ``aes``, the image is encrypted with 128-bit AES-CBC.
1291
+ The encryption key is given by the ``encrypt.key-secret`` parameter.
1292
+ This encryption format is considered to be flawed by modern cryptography
1293
+ standards, suffering from a number of design problems enumerated previously
1294
+ against the ``qcow2`` image format.
1295
+
1296
+ The use of this is no longer supported in system emulators. Support only
1297
+ remains in the command line utilities, for the purposes of data liberation
1298
+ and interoperability with old versions of QEMU.
1299
+
1300
+ Users requiring native encryption should use the ``qcow2`` format
1301
+ instead with ``encrypt.format=luks``.
1302
+
1303
+ .. option:: encrypt.key-secret
1304
+
1305
+ Provides the ID of a ``secret`` object that contains the encryption
1306
+ key (``encrypt.format=aes``).
1307
+
1308
+.. program:: image-formats
1309
+.. option:: luks
1310
+
1311
+ LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
1312
+
1313
+ Supported options:
1314
+
1315
+ .. program:: luks
1316
+ .. option:: key-secret
1317
+
1318
+ Provides the ID of a ``secret`` object that contains the passphrase.
1319
+
1320
+ .. option:: cipher-alg
1321
+
1322
+ Name of the cipher algorithm and key length. Currently defaults
1323
+ to ``aes-256``.
1324
+
1325
+ .. option:: cipher-mode
1326
+
1327
+ Name of the encryption mode to use. Currently defaults to ``xts``.
1328
+
1329
+ .. option:: ivgen-alg
1330
+
1331
+ Name of the initialization vector generator algorithm. Currently defaults
1332
+ to ``plain64``.
1333
+
1334
+ .. option:: ivgen-hash-alg
1335
+
1336
+ Name of the hash algorithm to use with the initialization vector generator
1337
+ (if required). Defaults to ``sha256``.
1338
+
1339
+ .. option:: hash-alg
1340
+
1341
+ Name of the hash algorithm to use for PBKDF algorithm
1342
+ Defaults to ``sha256``.
1343
+
1344
+ .. option:: iter-time
1345
+
1346
+ Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
1347
+ Defaults to ``2000``.
1348
+
1349
+.. program:: image-formats
1350
+.. option:: vdi
1351
+
1352
+ VirtualBox 1.1 compatible image format.
1353
+
1354
+ Supported options:
1355
+
1356
+ .. program:: vdi
1357
+ .. option:: static
1358
+
1359
+ If this option is set to ``on``, the image is created with metadata
1360
+ preallocation.
1361
+
1362
+.. program:: image-formats
1363
+.. option:: vmdk
1364
+
1365
+ VMware 3 and 4 compatible image format.
1366
+
1367
+ Supported options:
1368
+
1369
+ .. program: vmdk
1370
+ .. option:: backing_file
1371
+
1372
+ File name of a base image (see ``create`` subcommand).
1373
+
1374
+ .. option:: compat6
1375
+
1376
+ Create a VMDK version 6 image (instead of version 4)
1377
+
1378
+ .. option:: hwversion
1379
+
1380
+ Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
1381
+ if hwversion is specified.
1382
+
1383
+ .. option:: subformat
1384
+
1385
+ Specifies which VMDK subformat to use. Valid options are
1386
+ ``monolithicSparse`` (default),
1387
+ ``monolithicFlat``,
1388
+ ``twoGbMaxExtentSparse``,
1389
+ ``twoGbMaxExtentFlat`` and
1390
+ ``streamOptimized``.
1391
+
1392
+.. program:: image-formats
1393
+.. option:: vpc
1394
+
1395
+ VirtualPC compatible image format (VHD).
1396
+
1397
+ Supported options:
1398
+
1399
+ .. program:: vpc
1400
+ .. option:: subformat
1401
+
1402
+ Specifies which VHD subformat to use. Valid options are
1403
+ ``dynamic`` (default) and ``fixed``.
1404
+
1405
+.. program:: image-formats
1406
+.. option:: VHDX
1407
+
1408
+ Hyper-V compatible image format (VHDX).
1409
+
1410
+ Supported options:
1411
+
1412
+ .. program:: VHDX
1413
+ .. option:: subformat
1414
+
1415
+ Specifies which VHDX subformat to use. Valid options are
1416
+ ``dynamic`` (default) and ``fixed``.
1417
+
1418
+ .. option:: block_state_zero
1419
+
1420
+ Force use of payload blocks of type 'ZERO'. Can be set to ``on`` (default)
1421
+ or ``off``. When set to ``off``, new blocks will be created as
1422
+ ``PAYLOAD_BLOCK_NOT_PRESENT``, which means parsers are free to return
1423
+ arbitrary data for those blocks. Do not set to ``off`` when using
1424
+ ``qemu-img convert`` with ``subformat=dynamic``.
1425
+
1426
+ .. option:: block_size
1427
+
1428
+ Block size; min 1 MB, max 256 MB. 0 means auto-calculate based on
1429
+ image size.
1430
+
1431
+ .. option:: log_size
1432
+
1433
+ Log size; min 1 MB.
1434
+
1435
+Read-only formats
1436
+-----------------
1437
+
1438
+More disk image file formats are supported in a read-only mode.
1439
+
1440
+.. program:: image-formats
1441
+.. option:: bochs
1442
+
1443
+ Bochs images of ``growing`` type.
1444
+
1445
+.. program:: image-formats
1446
+.. option:: cloop
1447
+
1448
+ Linux Compressed Loop image, useful only to reuse directly compressed
1449
+ CD-ROM images present for example in the Knoppix CD-ROMs.
1450
+
1451
+.. program:: image-formats
1452
+.. option:: dmg
1453
+
1454
+ Apple disk image.
1455
+
1456
+.. program:: image-formats
1457
+.. option:: parallels
1458
+
1459
+ Parallels disk image format.
1460
+
1461
+Using host drives
1462
+-----------------
1463
+
1464
+In addition to disk image files, QEMU can directly access host
1465
+devices. We describe here the usage for QEMU version >= 0.8.3.
1466
+
1467
+Linux
1468
+'''''
1469
+
1470
+On Linux, you can directly use the host device filename instead of a
1471
+disk image filename provided you have enough privileges to access
1472
+it. For example, use ``/dev/cdrom`` to access to the CDROM.
1473
+
1474
+CD
1475
+ You can specify a CDROM device even if no CDROM is loaded. QEMU has
1476
+ specific code to detect CDROM insertion or removal. CDROM ejection by
1477
+ the guest OS is supported. Currently only data CDs are supported.
1478
+
1479
+Floppy
1480
+ You can specify a floppy device even if no floppy is loaded. Floppy
1481
+ removal is currently not detected accurately (if you change floppy
1482
+ without doing floppy access while the floppy is not loaded, the guest
1483
+ OS will think that the same floppy is loaded).
1484
+ Use of the host's floppy device is deprecated, and support for it will
1485
+ be removed in a future release.
1486
+
1487
+Hard disks
1488
+ Hard disks can be used. Normally you must specify the whole disk
1489
+ (``/dev/hdb`` instead of ``/dev/hdb1``) so that the guest OS can
1490
+ see it as a partitioned disk. WARNING: unless you know what you do, it
1491
+ is better to only make READ-ONLY accesses to the hard disk otherwise
1492
+ you may corrupt your host data (use the ``-snapshot`` command
1493
+ line option or modify the device permissions accordingly).
1494
+
1495
+Windows
1496
+'''''''
1497
+
1498
+CD
1499
+ The preferred syntax is the drive letter (e.g. ``d:``). The
1500
+ alternate syntax ``\\.\d:`` is supported. ``/dev/cdrom`` is
1501
+ supported as an alias to the first CDROM drive.
1502
+
1503
+ Currently there is no specific code to handle removable media, so it
1504
+ is better to use the ``change`` or ``eject`` monitor commands to
1505
+ change or eject media.
1506
+
1507
+Hard disks
1508
+ Hard disks can be used with the syntax: ``\\.\PhysicalDriveN``
1509
+ where *N* is the drive number (0 is the first hard disk).
1510
+
1511
+ WARNING: unless you know what you do, it is better to only make
1512
+ READ-ONLY accesses to the hard disk otherwise you may corrupt your
1513
+ host data (use the ``-snapshot`` command line so that the
1514
+ modifications are written in a temporary file).
1515
+
1516
+Mac OS X
1517
+''''''''
1518
+
1519
+``/dev/cdrom`` is an alias to the first CDROM.
1520
+
1521
+Currently there is no specific code to handle removable media, so it
1522
+is better to use the ``change`` or ``eject`` monitor commands to
1523
+change or eject media.
1524
+
1525
+Virtual FAT disk images
1526
+-----------------------
1527
+
1528
+QEMU can automatically create a virtual FAT disk image from a
1529
+directory tree. In order to use it, just type:
1530
+
1531
+.. parsed-literal::
1532
+
1533
+ |qemu_system| linux.img -hdb fat:/my_directory
1534
+
1535
+Then you access access to all the files in the ``/my_directory``
1536
+directory without having to copy them in a disk image or to export
1537
+them via SAMBA or NFS. The default access is *read-only*.
1538
+
1539
+Floppies can be emulated with the ``:floppy:`` option:
1540
+
1541
+.. parsed-literal::
1542
+
1543
+ |qemu_system| linux.img -fda fat:floppy:/my_directory
1544
+
1545
+A read/write support is available for testing (beta stage) with the
1546
+``:rw:`` option:
1547
+
1548
+.. parsed-literal::
1549
+
1550
+ |qemu_system| linux.img -fda fat:floppy:rw:/my_directory
1551
+
1552
+What you should *never* do:
1553
+
1554
+- use non-ASCII filenames
1555
+- use "-snapshot" together with ":rw:"
1556
+- expect it to work when loadvm'ing
1557
+- write to the FAT directory on the host system while accessing it with the guest system
1558
+
1559
+NBD access
1560
+----------
1561
+
1562
+QEMU can access directly to block device exported using the Network Block Device
1563
+protocol.
1564
+
1565
+.. parsed-literal::
1566
+
1567
+ |qemu_system| linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
1568
+
1569
+If the NBD server is located on the same host, you can use an unix socket instead
1570
+of an inet socket:
1571
+
1572
+.. parsed-literal::
1573
+
1574
+ |qemu_system| linux.img -hdb nbd+unix://?socket=/tmp/my_socket
1575
+
1576
+In this case, the block device must be exported using qemu-nbd:
1577
+
1578
+.. parsed-literal::
1579
+
1580
+ qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
1581
+
1582
+The use of qemu-nbd allows sharing of a disk between several guests:
1583
+
1584
+.. parsed-literal::
1585
+
1586
+ qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
1587
+
1588
+and then you can use it with two guests:
1589
+
1590
+.. parsed-literal::
1591
+
1592
+ |qemu_system| linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
1593
+ |qemu_system| linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
1594
+
1595
+If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
1596
+own embedded NBD server), you must specify an export name in the URI:
1597
+
1598
+.. parsed-literal::
1599
+
1600
+ |qemu_system| -cdrom nbd://localhost/debian-500-ppc-netinst
1601
+ |qemu_system| -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
1602
+
1603
+The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is
1604
+also available. Here are some example of the older syntax:
1605
+
1606
+.. parsed-literal::
1607
+
1608
+ |qemu_system| linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
1609
+ |qemu_system| linux2.img -hdb nbd:unix:/tmp/my_socket
1610
+ |qemu_system| -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
1611
+
1612
+
1613
+
1614
+Sheepdog disk images
1615
+--------------------
1616
+
1617
+Sheepdog is a distributed storage system for QEMU. It provides highly
1618
+available block level storage volumes that can be attached to
1619
+QEMU-based virtual machines.
1620
+
1621
+You can create a Sheepdog disk image with the command:
1622
+
1623
+.. parsed-literal::
1624
+
1625
+ qemu-img create sheepdog:///IMAGE SIZE
1626
+
1627
+where *IMAGE* is the Sheepdog image name and *SIZE* is its
1628
+size.
1629
+
1630
+To import the existing *FILENAME* to Sheepdog, you can use a
1631
+convert command.
1632
+
1633
+.. parsed-literal::
1634
+
1635
+ qemu-img convert FILENAME sheepdog:///IMAGE
1636
+
1637
+You can boot from the Sheepdog disk image with the command:
1638
+
1639
+.. parsed-literal::
1640
+
1641
+ |qemu_system| sheepdog:///IMAGE
1642
+
1643
+You can also create a snapshot of the Sheepdog image like qcow2.
1644
+
1645
+.. parsed-literal::
1646
+
1647
+ qemu-img snapshot -c TAG sheepdog:///IMAGE
1648
+
1649
+where *TAG* is a tag name of the newly created snapshot.
1650
+
1651
+To boot from the Sheepdog snapshot, specify the tag name of the
1652
+snapshot.
1653
+
1654
+.. parsed-literal::
1655
+
1656
+ |qemu_system| sheepdog:///IMAGE#TAG
1657
+
1658
+You can create a cloned image from the existing snapshot.
1659
+
1660
+.. parsed-literal::
1661
+
1662
+ qemu-img create -b sheepdog:///BASE#TAG sheepdog:///IMAGE
1663
+
1664
+where *BASE* is an image name of the source snapshot and *TAG*
1665
+is its tag name.
1666
+
1667
+You can use an unix socket instead of an inet socket:
1668
+
1669
+.. parsed-literal::
1670
+
1671
+ |qemu_system| sheepdog+unix:///IMAGE?socket=PATH
1672
+
1673
+If the Sheepdog daemon doesn't run on the local host, you need to
1674
+specify one of the Sheepdog servers to connect to.
1675
+
1676
+.. parsed-literal::
1677
+
1678
+ qemu-img create sheepdog://HOSTNAME:PORT/IMAGE SIZE
1679
+ |qemu_system| sheepdog://HOSTNAME:PORT/IMAGE
1680
+
1681
+iSCSI LUNs
1682
+----------
1683
+
1684
+iSCSI is a popular protocol used to access SCSI devices across a computer
1685
+network.
1686
+
1687
+There are two different ways iSCSI devices can be used by QEMU.
1688
+
1689
+The first method is to mount the iSCSI LUN on the host, and make it appear as
1690
+any other ordinary SCSI device on the host and then to access this device as a
1691
+/dev/sd device from QEMU. How to do this differs between host OSes.
1692
+
1693
+The second method involves using the iSCSI initiator that is built into
1694
+QEMU. This provides a mechanism that works the same way regardless of which
1695
+host OS you are running QEMU on. This section will describe this second method
1696
+of using iSCSI together with QEMU.
1697
+
1698
+In QEMU, iSCSI devices are described using special iSCSI URLs. URL syntax:
1699
+
1700
+::
1701
+
1702
+ iscsi://[<username>[%<password>]@]<host>[:<port>]/<target-iqn-name>/<lun>
1703
+
1704
+Username and password are optional and only used if your target is set up
1705
+using CHAP authentication for access control.
1706
+Alternatively the username and password can also be set via environment
1707
+variables to have these not show up in the process list:
1708
+
1709
+::
1710
+
1711
+ export LIBISCSI_CHAP_USERNAME=<username>
1712
+ export LIBISCSI_CHAP_PASSWORD=<password>
1713
+ iscsi://<host>/<target-iqn-name>/<lun>
1714
+
1715
+Various session related parameters can be set via special options, either
1716
+in a configuration file provided via '-readconfig' or directly on the
1717
+command line.
1718
+
1719
+If the initiator-name is not specified qemu will use a default name
1720
+of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
1721
+virtual machine. If the UUID is not specified qemu will use
1722
+'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
1723
+virtual machine.
1724
+
1725
+Setting a specific initiator name to use when logging in to the target:
1726
+
1727
+::
1728
+
1729
+ -iscsi initiator-name=iqn.qemu.test:my-initiator
1730
+
1731
+Controlling which type of header digest to negotiate with the target:
1732
+
1733
+::
1734
+
1735
+ -iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
1736
+
1737
+These can also be set via a configuration file:
1738
+
1739
+::
1740
+
1741
+ [iscsi]
1742
+ user = "CHAP username"
1743
+ password = "CHAP password"
1744
+ initiator-name = "iqn.qemu.test:my-initiator"
1745
+ # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
1746
+ header-digest = "CRC32C"
1747
+
1748
+Setting the target name allows different options for different targets:
1749
+
1750
+::
1751
+
1752
+ [iscsi "iqn.target.name"]
1753
+ user = "CHAP username"
1754
+ password = "CHAP password"
1755
+ initiator-name = "iqn.qemu.test:my-initiator"
1756
+ # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
1757
+ header-digest = "CRC32C"
1758
+
1759
+How to use a configuration file to set iSCSI configuration options:
1760
+
1761
+.. parsed-literal::
1762
+
1763
+ cat >iscsi.conf <<EOF
1764
+ [iscsi]
1765
+ user = "me"
1766
+ password = "my password"
1767
+ initiator-name = "iqn.qemu.test:my-initiator"
1768
+ header-digest = "CRC32C"
1769
+ EOF
1770
+
1771
+ |qemu_system| -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \\
1772
+ -readconfig iscsi.conf
1773
+
1774
+How to set up a simple iSCSI target on loopback and access it via QEMU:
1775
+this example shows how to set up an iSCSI target with one CDROM and one DISK
1776
+using the Linux STGT software target. This target is available on Red Hat based
1777
+systems as the package 'scsi-target-utils'.
1778
+
1779
+.. parsed-literal::
1780
+
1781
+ tgtd --iscsi portal=127.0.0.1:3260
1782
+ tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
1783
+ tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \\
1784
+ -b /IMAGES/disk.img --device-type=disk
1785
+ tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \\
1786
+ -b /IMAGES/cd.iso --device-type=cd
1787
+ tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
1788
+
1789
+ |qemu_system| -iscsi initiator-name=iqn.qemu.test:my-initiator \\
1790
+ -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \\
1791
+ -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
1792
+
1793
+GlusterFS disk images
1794
+---------------------
1795
+
1796
+GlusterFS is a user space distributed file system.
1797
+
1798
+You can boot from the GlusterFS disk image with the command:
1799
+
1800
+URI:
1801
+
1802
+.. parsed-literal::
1803
+
1804
+ |qemu_system| -drive file=gluster[+TYPE]://[HOST}[:PORT]]/VOLUME/PATH
1805
+ [?socket=...][,file.debug=9][,file.logfile=...]
1806
+
1807
+JSON:
1808
+
1809
+.. parsed-literal::
1810
+
1811
+ |qemu_system| 'json:{"driver":"qcow2",
1812
+ "file":{"driver":"gluster",
1813
+ "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
1814
+ "server":[{"type":"tcp","host":"...","port":"..."},
1815
+ {"type":"unix","socket":"..."}]}}'
1816
+
1817
+*gluster* is the protocol.
1818
+
1819
+*TYPE* specifies the transport type used to connect to gluster
1820
+management daemon (glusterd). Valid transport types are
1821
+tcp and unix. In the URI form, if a transport type isn't specified,
1822
+then tcp type is assumed.
1823
+
1824
+*HOST* specifies the server where the volume file specification for
1825
+the given volume resides. This can be either a hostname or an ipv4 address.
1826
+If transport type is unix, then *HOST* field should not be specified.
1827
+Instead *socket* field needs to be populated with the path to unix domain
1828
+socket.
1829
+
1830
+*PORT* is the port number on which glusterd is listening. This is optional
1831
+and if not specified, it defaults to port 24007. If the transport type is unix,
1832
+then *PORT* should not be specified.
1833
+
1834
+*VOLUME* is the name of the gluster volume which contains the disk image.
1835
+
1836
+*PATH* is the path to the actual disk image that resides on gluster volume.
1837
+
1838
+*debug* is the logging level of the gluster protocol driver. Debug levels
1839
+are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
1840
+The default level is 4. The current logging levels defined in the gluster source
1841
+are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
1842
+6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
1843
+
1844
+*logfile* is a commandline option to mention log file path which helps in
1845
+logging to the specified file and also help in persisting the gfapi logs. The
1846
+default is stderr.
1847
+
1848
+You can create a GlusterFS disk image with the command:
1849
+
1850
+.. parsed-literal::
1851
+
1852
+ qemu-img create gluster://HOST/VOLUME/PATH SIZE
1853
+
1854
+Examples
1855
+
1856
+.. parsed-literal::
1857
+
1858
+ |qemu_system| -drive file=gluster://1.2.3.4/testvol/a.img
1859
+ |qemu_system| -drive file=gluster+tcp://1.2.3.4/testvol/a.img
1860
+ |qemu_system| -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
1861
+ |qemu_system| -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
1862
+ |qemu_system| -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
1863
+ |qemu_system| -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
1864
+ |qemu_system| -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
1865
+ |qemu_system| -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
1866
+ |qemu_system| -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
1867
+ |qemu_system| 'json:{"driver":"qcow2",
1868
+ "file":{"driver":"gluster",
1869
+ "volume":"testvol","path":"a.img",
1870
+ "debug":9,"logfile":"/var/log/qemu-gluster.log",
1871
+ "server":[{"type":"tcp","host":"1.2.3.4","port":24007},
1872
+ {"type":"unix","socket":"/var/run/glusterd.socket"}]}}'
1873
+ |qemu_system| -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
1874
+ file.debug=9,file.logfile=/var/log/qemu-gluster.log,
1875
+ file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
1876
+ file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
1877
+
1878
+Secure Shell (ssh) disk images
1879
+------------------------------
1880
+
1881
+You can access disk images located on a remote ssh server
1882
+by using the ssh protocol:
1883
+
1884
+.. parsed-literal::
1885
+
1886
+ |qemu_system| -drive file=ssh://[USER@]SERVER[:PORT]/PATH[?host_key_check=HOST_KEY_CHECK]
1887
+
1888
+Alternative syntax using properties:
1889
+
1890
+.. parsed-literal::
1891
+
1892
+ |qemu_system| -drive file.driver=ssh[,file.user=USER],file.host=SERVER[,file.port=PORT],file.path=PATH[,file.host_key_check=HOST_KEY_CHECK]
1893
+
1894
+*ssh* is the protocol.
1895
+
1896
+*USER* is the remote user. If not specified, then the local
1897
+username is tried.
1898
+
1899
+*SERVER* specifies the remote ssh server. Any ssh server can be
1900
+used, but it must implement the sftp-server protocol. Most Unix/Linux
1901
+systems should work without requiring any extra configuration.
1902
+
1903
+*PORT* is the port number on which sshd is listening. By default
1904
+the standard ssh port (22) is used.
1905
+
1906
+*PATH* is the path to the disk image.
1907
+
1908
+The optional *HOST_KEY_CHECK* parameter controls how the remote
1909
+host's key is checked. The default is ``yes`` which means to use
1910
+the local ``.ssh/known_hosts`` file. Setting this to ``no``
1911
+turns off known-hosts checking. Or you can check that the host key
1912
+matches a specific fingerprint:
1913
+``host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8``
1914
+(``sha1:`` can also be used as a prefix, but note that OpenSSH
1915
+tools only use MD5 to print fingerprints).
1916
+
1917
+Currently authentication must be done using ssh-agent. Other
1918
+authentication methods may be supported in future.
1919
+
1920
+Note: Many ssh servers do not support an ``fsync``-style operation.
1921
+The ssh driver cannot guarantee that disk flush requests are
1922
+obeyed, and this causes a risk of disk corruption if the remote
1923
+server or network goes down during writes. The driver will
1924
+print a warning when ``fsync`` is not supported:
1925
+
1926
+::
1927
+
1928
+ warning: ssh server ssh.example.com:22 does not support fsync
1929
+
1930
+With sufficiently new versions of libssh and OpenSSH, ``fsync`` is
1931
+supported.
1932
+
1933
+NVMe disk images
1934
+----------------
1935
+
1936
+NVM Express (NVMe) storage controllers can be accessed directly by a userspace
1937
+driver in QEMU. This bypasses the host kernel file system and block layers
1938
+while retaining QEMU block layer functionalities, such as block jobs, I/O
1939
+throttling, image formats, etc. Disk I/O performance is typically higher than
1940
+with ``-drive file=/dev/sda`` using either thread pool or linux-aio.
1941
+
1942
+The controller will be exclusively used by the QEMU process once started. To be
1943
+able to share storage between multiple VMs and other applications on the host,
1944
+please use the file based protocols.
1945
+
1946
+Before starting QEMU, bind the host NVMe controller to the host vfio-pci
1947
+driver. For example:
1948
+
1949
+.. parsed-literal::
1950
+
1951
+ # modprobe vfio-pci
1952
+ # lspci -n -s 0000:06:0d.0
1953
+ 06:0d.0 0401: 1102:0002 (rev 08)
1954
+ # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
1955
+ # echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
1956
+
1957
+ # |qemu_system| -drive file=nvme://HOST:BUS:SLOT.FUNC/NAMESPACE
1958
+
1959
+Alternative syntax using properties:
1960
+
1961
+.. parsed-literal::
1962
+
1963
+ |qemu_system| -drive file.driver=nvme,file.device=HOST:BUS:SLOT.FUNC,file.namespace=NAMESPACE
1964
+
1965
+*HOST*:*BUS*:*SLOT*.\ *FUNC* is the NVMe controller's PCI device
1966
+address on the host.
1967
+
1968
+*NAMESPACE* is the NVMe namespace number, starting from 1.
1969
+
1970
+Disk image file locking
1971
+-----------------------
1972
+
1973
+By default, QEMU tries to protect image files from unexpected concurrent
1974
+access, as long as it's supported by the block protocol driver and host
1975
+operating system. If multiple QEMU processes (including QEMU emulators and
1976
+utilities) try to open the same image with conflicting accessing modes, all but
1977
+the first one will get an error.
1978
+
1979
+This feature is currently supported by the file protocol on Linux with the Open
1980
+File Descriptor (OFD) locking API, and can be configured to fall back to POSIX
1981
+locking if the POSIX host doesn't support Linux OFD locking.
1982
+
1983
+To explicitly enable image locking, specify "locking=on" in the file protocol
1984
+driver options. If OFD locking is not possible, a warning will be printed and
1985
+the POSIX locking API will be used. In this case there is a risk that the lock
1986
+will get silently lost when doing hot plugging and block jobs, due to the
1987
+shortcomings of the POSIX locking API.
1988
+
1989
+QEMU transparently handles lock handover during shared storage migration. For
1990
+shared virtual disk images between multiple VMs, the "share-rw" device option
1991
+should be used.
1992
+
1993
+By default, the guest has exclusive write access to its disk image. If the
1994
+guest can safely share the disk image with other writers the
1995
+``-device ...,share-rw=on`` parameter can be used. This is only safe if
1996
+the guest is running software, such as a cluster file system, that
1997
+coordinates disk accesses to avoid corruption.
1998
+
1999
+Note that share-rw=on only declares the guest's ability to share the disk.
2000
+Some QEMU features, such as image file formats, require exclusive write access
2001
+to the disk image and this is unaffected by the share-rw=on option.
2002
+
2003
+Alternatively, locking can be fully disabled by "locking=off" block device
2004
+option. In the command line, the option is usually in the form of
2005
+"file.locking=off" as the protocol driver is normally placed as a "file" child
2006
+under a format driver. For example:
2007
+
2008
+::
2009
+
2010
+ -blockdev driver=qcow2,file.filename=/path/to/image,file.locking=off,file.driver=file
2011
+
2012
+To check if image locking is active, check the output of the "lslocks" command
2013
+on host and see if there are locks held by the QEMU process on the image file.
2014
+More than one byte could be locked by the QEMU instance, each byte of which
2015
+reflects a particular permission that is acquired or protected by the running
2016
+block driver.
2017
+
2018
+.. only:: man
2019
+
2020
+ See also
2021
+ --------
2022
+
2023
+ The HTML documentation of QEMU for more precise information and Linux
2024
+ user mode emulator invocation.
2025
diff --git a/qemu-doc.texi b/qemu-doc.texi
2026
index XXXXXXX..XXXXXXX 100644
2027
--- a/qemu-doc.texi
2028
+++ b/qemu-doc.texi
2029
@@ -XXX,XX +XXX,XX @@ encrypted disk images.
2030
* disk_images_snapshot_mode:: Snapshot mode
2031
* vm_snapshots:: VM snapshots
2032
* qemu_img_invocation:: qemu-img Invocation
2033
-* disk_images_formats:: Disk image file formats
2034
-* host_drives:: Using host drives
2035
-* disk_images_fat_images:: Virtual FAT disk images
2036
-* disk_images_nbd:: NBD access
2037
-* disk_images_sheepdog:: Sheepdog disk images
2038
-* disk_images_iscsi:: iSCSI LUNs
2039
-* disk_images_gluster:: GlusterFS disk images
2040
-* disk_images_ssh:: Secure Shell (ssh) disk images
2041
-* disk_images_nvme:: NVMe userspace driver
2042
-* disk_image_locking:: Disk image file locking
2043
@end menu
2044
2045
@node disk_images_quickstart
2046
@@ -XXX,XX +XXX,XX @@ state is not saved or restored properly (in particular USB).
2047
2048
@include qemu-img.texi
2049
2050
-@include docs/qemu-block-drivers.texi
2051
-
2052
@node pcsys_network
2053
@section Network emulation
2054
2055
diff --git a/qemu-options.hx b/qemu-options.hx
2056
index XXXXXXX..XXXXXXX 100644
2057
--- a/qemu-options.hx
2058
+++ b/qemu-options.hx
2059
@@ -XXX,XX +XXX,XX @@ STEXI
2060
@findex -cdrom
2061
Use @var{file} as CD-ROM image (you cannot use @option{-hdc} and
2062
@option{-cdrom} at the same time). You can use the host CD-ROM by
2063
-using @file{/dev/cdrom} as filename (@pxref{host_drives}).
2064
+using @file{/dev/cdrom} as filename.
2065
ETEXI
2066
2067
DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
31
--
2068
--
32
2.20.1
2069
2.20.1
33
2070
34
2071
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
HSTR_EL2 offers a way to trap ranges of CP15 system register
3
When dumping a guest with dump-guest-memory also dump the SVE
4
accesses to EL2, and it looks like this register is completely
4
registers if they are in use.
5
ignored by QEMU.
5
6
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
To avoid adding extra .accessfn filters all over the place (which
8
would have a direct performance impact), let's add a new TB flag
9
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
10
a context where this trap has a chance to apply, and only generate
11
the extra access check if the hypervisor is actively using this feature.
12
13
Tested with a hand-crafted KVM guest accessing CBAR.
14
15
Signed-off-by: Marc Zyngier <maz@kernel.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20191201122018.25808-5-maz@kernel.org
8
Message-id: 20200120101832.18781-1-drjones@redhat.com
18
[PMM: use is_a64(); fix comment syntax]
9
[PMM: fixed checkpatch nits]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
11
---
21
target/arm/cpu.h | 2 ++
12
include/elf.h | 1 +
22
target/arm/translate.h | 2 ++
13
target/arm/cpu.h | 25 +++++++++
23
target/arm/helper.c | 6 ++++++
14
target/arm/arch_dump.c | 124 ++++++++++++++++++++++++++++++++++++++++-
24
target/arm/op_helper.c | 22 ++++++++++++++++++++++
15
target/arm/kvm64.c | 24 --------
25
target/arm/translate.c | 3 ++-
16
4 files changed, 148 insertions(+), 26 deletions(-)
26
5 files changed, 34 insertions(+), 1 deletion(-)
17
27
18
diff --git a/include/elf.h b/include/elf.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/elf.h
21
+++ b/include/elf.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct elf64_shdr {
23
#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
24
#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
25
#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
26
+#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension regs */
27
28
/*
29
* Physical entry point into the kernel.
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
32
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
33
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
34
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
33
FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
35
void aarch64_sve_change_el(CPUARMState *env, int old_el,
34
FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
36
int new_el, bool el0_a64);
35
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
37
void aarch64_add_sve_properties(Object *obj);
36
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 17, 1)
38
+
37
+
39
+/*
38
/* For M profile only, set if FPCCR.LSPACT is set */
40
+ * SVE registers are encoded in KVM's memory in an endianness-invariant format.
39
FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */
41
+ * The byte at offset i from the start of the in-memory representation contains
40
/* For M profile only, set if we must create a new FP context */
42
+ * the bits [(7 + 8 * i) : (8 * i)] of the register value. As this means the
41
diff --git a/target/arm/translate.h b/target/arm/translate.h
43
+ * lowest offsets are stored in the lowest memory addresses, then that nearly
42
index XXXXXXX..XXXXXXX 100644
44
+ * matches QEMU's representation, which is to use an array of host-endian
43
--- a/target/arm/translate.h
45
+ * uint64_t's, where the lower offsets are at the lower indices. To complete
44
+++ b/target/arm/translate.h
46
+ * the translation we just need to byte swap the uint64_t's on big-endian hosts.
45
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
47
+ */
46
bool pauth_active;
48
+static inline uint64_t *sve_bswap64(uint64_t *dst, uint64_t *src, int nr)
47
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
49
+{
48
bool bt;
50
+#ifdef HOST_WORDS_BIGENDIAN
49
+ /* True if any CP15 access is trapped by HSTR_EL2 */
51
+ int i;
50
+ bool hstr_active;
52
+
51
/*
53
+ for (i = 0; i < nr; ++i) {
52
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
54
+ dst[i] = bswap64(src[i]);
53
* < 0, set by the current instruction.
55
+ }
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
56
+
55
index XXXXXXX..XXXXXXX 100644
57
+ return dst;
56
--- a/target/arm/helper.c
58
+#else
57
+++ b/target/arm/helper.c
59
+ return src;
58
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
60
+#endif
59
if (arm_el_is_aa64(env, 1)) {
61
+}
60
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
62
+
63
#else
64
static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
65
static inline void aarch64_sve_change_el(CPUARMState *env, int o,
66
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/arch_dump.c
69
+++ b/target/arm/arch_dump.c
70
@@ -XXX,XX +XXX,XX @@ struct aarch64_user_vfp_state {
71
72
QEMU_BUILD_BUG_ON(sizeof(struct aarch64_user_vfp_state) != 528);
73
74
+/* struct user_sve_header from arch/arm64/include/uapi/asm/ptrace.h */
75
+struct aarch64_user_sve_header {
76
+ uint32_t size;
77
+ uint32_t max_size;
78
+ uint16_t vl;
79
+ uint16_t max_vl;
80
+ uint16_t flags;
81
+ uint16_t reserved;
82
+} QEMU_PACKED;
83
+
84
struct aarch64_note {
85
Elf64_Nhdr hdr;
86
char name[8]; /* align_up(sizeof("CORE"), 4) */
87
union {
88
struct aarch64_elf_prstatus prstatus;
89
struct aarch64_user_vfp_state vfp;
90
+ struct aarch64_user_sve_header sve;
91
};
92
} QEMU_PACKED;
93
94
@@ -XXX,XX +XXX,XX @@ struct aarch64_note {
95
(AARCH64_NOTE_HEADER_SIZE + sizeof(struct aarch64_elf_prstatus))
96
#define AARCH64_PRFPREG_NOTE_SIZE \
97
(AARCH64_NOTE_HEADER_SIZE + sizeof(struct aarch64_user_vfp_state))
98
+#define AARCH64_SVE_NOTE_SIZE(env) \
99
+ (AARCH64_NOTE_HEADER_SIZE + sve_size(env))
100
101
static void aarch64_note_init(struct aarch64_note *note, DumpState *s,
102
const char *name, Elf64_Word namesz,
103
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
104
return 0;
105
}
106
107
+#ifdef TARGET_AARCH64
108
+static off_t sve_zreg_offset(uint32_t vq, int n)
109
+{
110
+ off_t off = sizeof(struct aarch64_user_sve_header);
111
+ return ROUND_UP(off, 16) + vq * 16 * n;
112
+}
113
+
114
+static off_t sve_preg_offset(uint32_t vq, int n)
115
+{
116
+ return sve_zreg_offset(vq, 32) + vq * 16 / 8 * n;
117
+}
118
+
119
+static off_t sve_fpsr_offset(uint32_t vq)
120
+{
121
+ off_t off = sve_preg_offset(vq, 17);
122
+ return ROUND_UP(off, 16);
123
+}
124
+
125
+static off_t sve_fpcr_offset(uint32_t vq)
126
+{
127
+ return sve_fpsr_offset(vq) + sizeof(uint32_t);
128
+}
129
+
130
+static uint32_t sve_current_vq(CPUARMState *env)
131
+{
132
+ return sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
133
+}
134
+
135
+static size_t sve_size_vq(uint32_t vq)
136
+{
137
+ off_t off = sve_fpcr_offset(vq) + sizeof(uint32_t);
138
+ return ROUND_UP(off, 16);
139
+}
140
+
141
+static size_t sve_size(CPUARMState *env)
142
+{
143
+ return sve_size_vq(sve_current_vq(env));
144
+}
145
+
146
+static int aarch64_write_elf64_sve(WriteCoreDumpFunction f,
147
+ CPUARMState *env, int cpuid,
148
+ DumpState *s)
149
+{
150
+ struct aarch64_note *note;
151
+ ARMCPU *cpu = env_archcpu(env);
152
+ uint32_t vq = sve_current_vq(env);
153
+ uint64_t tmp[ARM_MAX_VQ * 2], *r;
154
+ uint32_t fpr;
155
+ uint8_t *buf;
156
+ int ret, i;
157
+
158
+ note = g_malloc0(AARCH64_SVE_NOTE_SIZE(env));
159
+ buf = (uint8_t *)&note->sve;
160
+
161
+ aarch64_note_init(note, s, "LINUX", 6, NT_ARM_SVE, sve_size_vq(vq));
162
+
163
+ note->sve.size = cpu_to_dump32(s, sve_size_vq(vq));
164
+ note->sve.max_size = cpu_to_dump32(s, sve_size_vq(cpu->sve_max_vq));
165
+ note->sve.vl = cpu_to_dump16(s, vq * 16);
166
+ note->sve.max_vl = cpu_to_dump16(s, cpu->sve_max_vq * 16);
167
+ note->sve.flags = cpu_to_dump16(s, 1);
168
+
169
+ for (i = 0; i < 32; ++i) {
170
+ r = sve_bswap64(tmp, &env->vfp.zregs[i].d[0], vq * 2);
171
+ memcpy(&buf[sve_zreg_offset(vq, i)], r, vq * 16);
172
+ }
173
+
174
+ for (i = 0; i < 17; ++i) {
175
+ r = sve_bswap64(tmp, r = &env->vfp.pregs[i].p[0],
176
+ DIV_ROUND_UP(vq * 2, 8));
177
+ memcpy(&buf[sve_preg_offset(vq, i)], r, vq * 16 / 8);
178
+ }
179
+
180
+ fpr = cpu_to_dump32(s, vfp_get_fpsr(env));
181
+ memcpy(&buf[sve_fpsr_offset(vq)], &fpr, sizeof(uint32_t));
182
+
183
+ fpr = cpu_to_dump32(s, vfp_get_fpcr(env));
184
+ memcpy(&buf[sve_fpcr_offset(vq)], &fpr, sizeof(uint32_t));
185
+
186
+ ret = f(note, AARCH64_SVE_NOTE_SIZE(env), s);
187
+ g_free(note);
188
+
189
+ if (ret < 0) {
190
+ return -1;
191
+ }
192
+
193
+ return 0;
194
+}
195
+#endif
196
+
197
int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
198
int cpuid, void *opaque)
199
{
200
struct aarch64_note note;
201
- CPUARMState *env = &ARM_CPU(cs)->env;
202
+ ARMCPU *cpu = ARM_CPU(cs);
203
+ CPUARMState *env = &cpu->env;
204
DumpState *s = opaque;
205
uint64_t pstate, sp;
206
int ret, i;
207
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
208
return -1;
61
}
209
}
62
+
210
63
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
211
- return aarch64_write_elf64_prfpreg(f, env, cpuid, s);
64
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
212
+ ret = aarch64_write_elf64_prfpreg(f, env, cpuid, s);
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
213
+ if (ret) {
66
+ }
214
+ return ret;
67
+
215
+ }
68
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
216
+
217
+#ifdef TARGET_AARCH64
218
+ if (cpu_isar_feature(aa64_sve, cpu)) {
219
+ ret = aarch64_write_elf64_sve(f, env, cpuid, s);
220
+ }
221
+#endif
222
+
223
+ return ret;
69
}
224
}
70
225
71
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
226
/* struct pt_regs from arch/arm/include/asm/ptrace.h */
72
index XXXXXXX..XXXXXXX 100644
227
@@ -XXX,XX +XXX,XX @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
73
--- a/target/arm/op_helper.c
228
if (class == ELFCLASS64) {
74
+++ b/target/arm/op_helper.c
229
note_size = AARCH64_PRSTATUS_NOTE_SIZE;
75
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
230
note_size += AARCH64_PRFPREG_NOTE_SIZE;
76
raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
231
+#ifdef TARGET_AARCH64
77
}
232
+ if (cpu_isar_feature(aa64_sve, cpu)) {
78
233
+ note_size += AARCH64_SVE_NOTE_SIZE(env);
79
+ /*
80
+ * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
81
+ * to sysregs non accessible at EL0 to have UNDEF-ed already.
82
+ */
83
+ if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
84
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
85
+ uint32_t mask = 1 << ri->crn;
86
+
87
+ if (ri->type & ARM_CP_64BIT) {
88
+ mask = 1 << ri->crm;
89
+ }
234
+ }
90
+
235
+#endif
91
+ /* T4 and T14 are RES0 */
236
} else {
92
+ mask &= ~((1 << 4) | (1 << 14));
237
note_size = ARM_PRSTATUS_NOTE_SIZE;
93
+
238
if (arm_feature(env, ARM_FEATURE_VFP)) {
94
+ if (env->cp15.hstr_el2 & mask) {
239
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
95
+ target_el = 2;
240
index XXXXXXX..XXXXXXX 100644
96
+ goto exept;
241
--- a/target/arm/kvm64.c
97
+ }
242
+++ b/target/arm/kvm64.c
98
+ }
243
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_fpsimd(CPUState *cs)
99
+
244
return 0;
100
if (!ri->accessfn) {
101
return;
102
}
103
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
104
g_assert_not_reached();
105
}
106
107
+exept:
108
raise_exception(env, EXCP_UDEF, syndrome, target_el);
109
}
245
}
110
246
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
247
-/*
112
index XXXXXXX..XXXXXXX 100644
248
- * SVE registers are encoded in KVM's memory in an endianness-invariant format.
113
--- a/target/arm/translate.c
249
- * The byte at offset i from the start of the in-memory representation contains
114
+++ b/target/arm/translate.c
250
- * the bits [(7 + 8 * i) : (8 * i)] of the register value. As this means the
115
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
251
- * lowest offsets are stored in the lowest memory addresses, then that nearly
116
return 1;
252
- * matches QEMU's representation, which is to use an array of host-endian
117
}
253
- * uint64_t's, where the lower offsets are at the lower indices. To complete
118
254
- * the translation we just need to byte swap the uint64_t's on big-endian hosts.
119
- if (ri->accessfn ||
255
- */
120
+ if (s->hstr_active || ri->accessfn ||
256
-static uint64_t *sve_bswap64(uint64_t *dst, uint64_t *src, int nr)
121
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
257
-{
122
/* Emit code to perform further access permissions checks at
258
-#ifdef HOST_WORDS_BIGENDIAN
123
* runtime; this may result in an exception.
259
- int i;
124
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
260
-
125
!arm_el_is_aa64(env, 3);
261
- for (i = 0; i < nr; ++i) {
126
dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
262
- dst[i] = bswap64(src[i]);
127
dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
263
- }
128
+ dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
264
-
129
dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
265
- return dst;
130
condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
266
-#else
131
dc->condexec_mask = (condexec & 0xf) << 1;
267
- return src;
268
-#endif
269
-}
270
-
271
/*
272
* KVM SVE registers come in slices where ZREGs have a slice size of 2048 bits
273
* and PREGS and the FFR have a slice size of 256 bits. However we simply hard
132
--
274
--
133
2.20.1
275
2.20.1
134
276
135
277
diff view generated by jsdifflib
1
From: PanNengyuan <pannengyuan@huawei.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Address Sanitizer shows memory leak in hw/gpio/aspeed_gpio.c:875
3
Missed in 870c034da0b, hopefully reported by Coverity.
4
4
5
Reported-by: Euler Robot <euler.robot@huawei.com>
5
Fixes: Coverity CID 1412793 (Incorrect expression)
6
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Thomas Huth <thuth@redhat.com>
9
Message-id: 20191119141211.25716-16-clg@kaod.org
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20200121213853.9601-1-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
hw/gpio/aspeed_gpio.c | 1 +
13
hw/misc/stm32f4xx_syscfg.c | 2 +-
13
1 file changed, 1 insertion(+)
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
15
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
16
diff --git a/hw/misc/stm32f4xx_syscfg.c b/hw/misc/stm32f4xx_syscfg.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/gpio/aspeed_gpio.c
18
--- a/hw/misc/stm32f4xx_syscfg.c
18
+++ b/hw/gpio/aspeed_gpio.c
19
+++ b/hw/misc/stm32f4xx_syscfg.c
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void stm32f4xx_syscfg_set_irq(void *opaque, int irq, int level)
20
pin_idx % GPIOS_PER_GROUP);
21
STM32F4xxSyscfgState *s = opaque;
21
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
22
int icrreg = irq / 4;
22
aspeed_gpio_set_pin, NULL, NULL, NULL);
23
int startbit = (irq & 3) * 4;
23
+ g_free(name);
24
- uint8_t config = config = irq / 16;
24
}
25
+ uint8_t config = irq / 16;
25
}
26
27
trace_stm32f4xx_syscfg_set_irq(irq / 16, irq % 16, level);
26
28
27
--
29
--
28
2.20.1
30
2.20.1
29
31
30
32
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
HCR_EL2.TID1 mandates that access from EL1 to REVIDR_EL1, AIDR_EL1
3
Replace debug logging code with tracing.
4
(and their 32bit equivalents) as well as TCMTR, TLBTR are trapped
4
5
to EL2. QEMU ignores it, making it harder for a hypervisor to
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
virtualize the HW (though to be fair, no known hypervisor actually
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
cares).
7
Message-id: 20200123052540.6132-2-linux@roeck-us.net
8
9
Do the right thing by trapping to EL2 if HCR_EL2.TID1 is set.
10
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-3-maz@kernel.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
9
---
17
target/arm/helper.c | 36 ++++++++++++++++++++++++++++++++----
10
hw/dma/pl330.c | 88 ++++++++++++++++++++++++---------------------
18
1 file changed, 32 insertions(+), 4 deletions(-)
11
hw/dma/trace-events | 24 +++++++++++++
19
12
2 files changed, 72 insertions(+), 40 deletions(-)
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
14
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
16
--- a/hw/dma/pl330.c
23
+++ b/target/arm/helper.c
17
+++ b/hw/dma/pl330.c
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
18
@@ -XXX,XX +XXX,XX @@
19
#include "sysemu/dma.h"
20
#include "qemu/log.h"
21
#include "qemu/module.h"
22
+#include "trace.h"
23
24
#ifndef PL330_ERR_DEBUG
25
#define PL330_ERR_DEBUG 0
26
#endif
27
28
-#define DB_PRINT_L(lvl, fmt, args...) do {\
29
- if (PL330_ERR_DEBUG >= lvl) {\
30
- fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
31
- } \
32
-} while (0)
33
-
34
-#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
35
-
36
#define PL330_PERIPH_NUM 32
37
#define PL330_MAX_BURST_LEN 128
38
#define PL330_INSN_MAXSIZE 6
39
@@ -XXX,XX +XXX,XX @@ typedef struct PL330InsnDesc {
40
void (*exec)(PL330Chan *, uint8_t opcode, uint8_t *args, int len);
41
} PL330InsnDesc;
42
43
+static void pl330_hexdump(uint8_t *buf, size_t size)
44
+{
45
+ unsigned int b, i, len;
46
+ char tmpbuf[80];
47
+
48
+ for (b = 0; b < size; b += 16) {
49
+ len = size - b;
50
+ if (len > 16) {
51
+ len = 16;
52
+ }
53
+ tmpbuf[0] = '\0';
54
+ for (i = 0; i < len; i++) {
55
+ if ((i % 4) == 0) {
56
+ strcat(tmpbuf, " ");
57
+ }
58
+ sprintf(tmpbuf + strlen(tmpbuf), " %02x", buf[b + i]);
59
+ }
60
+ trace_pl330_hexdump(b, tmpbuf);
61
+ }
62
+}
63
64
/* MFIFO Implementation
65
*
66
@@ -XXX,XX +XXX,XX @@ static inline void pl330_queue_remove_tagged(PL330Queue *s, uint8_t tag)
67
68
static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
69
{
70
- DB_PRINT("ch: %p, flags: %" PRIx32 "\n", ch, flags);
71
+ trace_pl330_fault(ch, flags);
72
ch->fault_type |= flags;
73
if (ch->state == pl330_chan_fault) {
74
return;
75
@@ -XXX,XX +XXX,XX @@ static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
76
ch->state = pl330_chan_fault;
77
ch->parent->num_faulting++;
78
if (ch->parent->num_faulting == 1) {
79
- DB_PRINT("abort interrupt raised\n");
80
+ trace_pl330_fault_abort();
81
qemu_irq_raise(ch->parent->irq_abort);
82
}
83
}
84
@@ -XXX,XX +XXX,XX @@ static void pl330_dmaend(PL330Chan *ch, uint8_t opcode,
85
return;
86
}
87
}
88
- DB_PRINT("DMA ending!\n");
89
+ trace_pl330_dmaend();
90
pl330_fifo_tagged_remove(&s->fifo, ch->tag);
91
pl330_queue_remove_tagged(&s->read_queue, ch->tag);
92
pl330_queue_remove_tagged(&s->write_queue, ch->tag);
93
@@ -XXX,XX +XXX,XX @@ static void pl330_dmago(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
94
uint32_t pc;
95
PL330Chan *s;
96
97
- DB_PRINT("\n");
98
+ trace_pl330_dmago();
99
100
if (!ch->is_manager) {
101
pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
102
@@ -XXX,XX +XXX,XX @@ static void pl330_dmald(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
103
ch->stall = pl330_queue_put_insn(&ch->parent->read_queue, ch->src,
104
size, num, inc, 0, ch->tag);
105
if (!ch->stall) {
106
- DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32
107
- " num:%" PRId32 " %c\n",
108
- ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
109
+ trace_pl330_dmald(ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
110
ch->src += inc ? size * num - (ch->src & (size - 1)) : 0;
111
}
112
}
113
@@ -XXX,XX +XXX,XX @@ static void pl330_dmakill(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
114
ch->fault_type = 0;
115
ch->parent->num_faulting--;
116
if (ch->parent->num_faulting == 0) {
117
- DB_PRINT("abort interrupt lowered\n");
118
+ trace_pl330_dmakill();
119
qemu_irq_lower(ch->parent->irq_abort);
120
}
121
}
122
@@ -XXX,XX +XXX,XX @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
123
uint8_t bs = opcode & 3;
124
uint8_t lc = (opcode & 4) >> 2;
125
126
+ trace_pl330_dmalpend(nf, bs, lc, ch->lc[lc], ch->request_flag);
127
+
128
if (bs == 2) {
129
pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
130
return;
131
@@ -XXX,XX +XXX,XX @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
132
if (nf) {
133
ch->lc[lc]--;
134
}
135
- DB_PRINT("loop reiteration\n");
136
+ trace_pl330_dmalpiter();
137
ch->pc -= args[0];
138
ch->pc -= len + 1;
139
/* "ch->pc -= args[0] + len + 1" is incorrect when args[0] == 256 */
140
} else {
141
- DB_PRINT("loop fallthrough\n");
142
+ trace_pl330_dmalpfallthrough();
143
}
144
}
145
146
@@ -XXX,XX +XXX,XX @@ static void pl330_dmasev(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
147
}
148
if (ch->parent->inten & (1 << ev_id)) {
149
ch->parent->int_status |= (1 << ev_id);
150
- DB_PRINT("event interrupt raised %" PRId8 "\n", ev_id);
151
+ trace_pl330_dmasev_evirq(ev_id);
152
qemu_irq_raise(ch->parent->irq[ev_id]);
153
}
154
- DB_PRINT("event raised %" PRId8 "\n", ev_id);
155
+ trace_pl330_dmasev_event(ev_id);
156
ch->parent->ev_status |= (1 << ev_id);
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static void pl330_dmast(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
160
ch->stall = pl330_queue_put_insn(&ch->parent->write_queue, ch->dst,
161
size, num, inc, 0, ch->tag);
162
if (!ch->stall) {
163
- DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32
164
- " num:%" PRId32 " %c\n",
165
- ch->tag, ch->dst, size, num, inc ? 'Y' : 'N');
166
+ trace_pl330_dmast(ch->tag, ch->dst, size, num, inc ? 'Y' : 'N');
167
ch->dst += inc ? size * num - (ch->dst & (size - 1)) : 0;
168
}
169
}
170
@@ -XXX,XX +XXX,XX @@ static void pl330_dmawfe(PL330Chan *ch, uint8_t opcode,
171
}
172
}
173
ch->parent->ev_status &= ~(1 << ev_id);
174
- DB_PRINT("event lowered %" PRIx8 "\n", ev_id);
175
+ trace_pl330_dmawfe(ev_id);
176
} else {
177
ch->stall = 1;
178
}
179
@@ -XXX,XX +XXX,XX @@ static int pl330_chan_exec(PL330Chan *ch)
180
ch->stall = 0;
181
insn = pl330_fetch_insn(ch);
182
if (!insn) {
183
- DB_PRINT("pl330 undefined instruction\n");
184
+ trace_pl330_chan_exec_undef();
185
pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
186
return 0;
187
}
188
@@ -XXX,XX +XXX,XX @@ static int pl330_exec_cycle(PL330Chan *channel)
189
int len = q->len - (q->addr & (q->len - 1));
190
191
dma_memory_read(&address_space_memory, q->addr, buf, len);
192
- if (PL330_ERR_DEBUG > 1) {
193
- DB_PRINT("PL330 read from memory @%08" PRIx32 " (size = %08x):\n",
194
- q->addr, len);
195
- qemu_hexdump((char *)buf, stderr, "", len);
196
+ trace_pl330_exec_cycle(q->addr, len);
197
+ if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
198
+ pl330_hexdump(buf, len);
199
}
200
fifo_res = pl330_fifo_push(&s->fifo, buf, len, q->tag);
201
if (fifo_res == PL330_FIFO_OK) {
202
@@ -XXX,XX +XXX,XX @@ static int pl330_exec_cycle(PL330Chan *channel)
203
}
204
if (fifo_res == PL330_FIFO_OK || q->z) {
205
dma_memory_write(&address_space_memory, q->addr, buf, len);
206
- if (PL330_ERR_DEBUG > 1) {
207
- DB_PRINT("PL330 read from memory @%08" PRIx32
208
- " (size = %08x):\n", q->addr, len);
209
- qemu_hexdump((char *)buf, stderr, "", len);
210
+ trace_pl330_exec_cycle(q->addr, len);
211
+ if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
212
+ pl330_hexdump(buf, len);
213
}
214
if (q->inc) {
215
q->addr += len;
216
@@ -XXX,XX +XXX,XX @@ static int pl330_exec_channel(PL330Chan *channel)
217
218
static inline void pl330_exec(PL330State *s)
219
{
220
- DB_PRINT("\n");
221
int i, insr_exec;
222
+ trace_pl330_exec();
223
do {
224
insr_exec = pl330_exec_channel(&s->manager);
225
226
@@ -XXX,XX +XXX,XX @@ static void pl330_debug_exec(PL330State *s)
227
args[2] = (s->dbg[1] >> 8) & 0xff;
228
args[3] = (s->dbg[1] >> 16) & 0xff;
229
args[4] = (s->dbg[1] >> 24) & 0xff;
230
- DB_PRINT("chan id: %" PRIx8 "\n", chan_id);
231
+ trace_pl330_debug_exec(chan_id);
232
if (s->dbg[0] & 1) {
233
ch = &s->chan[chan_id];
234
} else {
235
@@ -XXX,XX +XXX,XX @@ static void pl330_debug_exec(PL330State *s)
236
ch->fault_type |= PL330_FAULT_DBG_INSTR;
237
}
238
if (ch->stall) {
239
+ trace_pl330_debug_exec_stall();
240
qemu_log_mask(LOG_UNIMP, "pl330: stall of debug instruction not "
241
"implemented\n");
242
}
243
@@ -XXX,XX +XXX,XX @@ static void pl330_iomem_write(void *opaque, hwaddr offset,
244
PL330State *s = (PL330State *) opaque;
245
int i;
246
247
- DB_PRINT("addr: %08x data: %08x\n", (unsigned)offset, (unsigned)value);
248
+ trace_pl330_iomem_write((unsigned)offset, (unsigned)value);
249
250
switch (offset) {
251
case PL330_REG_INTEN:
252
@@ -XXX,XX +XXX,XX @@ static void pl330_iomem_write(void *opaque, hwaddr offset,
253
case PL330_REG_INTCLR:
254
for (i = 0; i < s->num_events; i++) {
255
if (s->int_status & s->inten & value & (1 << i)) {
256
- DB_PRINT("event interrupt lowered %d\n", i);
257
+ trace_pl330_iomem_write_clr(i);
258
qemu_irq_lower(s->irq[i]);
259
}
260
}
261
@@ -XXX,XX +XXX,XX @@ static void pl330_iomem_write(void *opaque, hwaddr offset,
262
}
263
break;
264
case PL330_REG_DBGINST0:
265
- DB_PRINT("s->dbg[0] = %08x\n", (unsigned)value);
266
s->dbg[0] = value;
267
break;
268
case PL330_REG_DBGINST1:
269
- DB_PRINT("s->dbg[1] = %08x\n", (unsigned)value);
270
s->dbg[1] = value;
271
break;
272
default:
273
@@ -XXX,XX +XXX,XX @@ static uint64_t pl330_iomem_read(void *opaque, hwaddr offset,
274
unsigned size)
275
{
276
uint32_t ret = pl330_iomem_read_imp(opaque, offset);
277
- DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", offset, ret);
278
+ trace_pl330_iomem_read((uint32_t)offset, ret);
25
return ret;
279
return ret;
26
}
280
}
27
281
28
+static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
282
diff --git a/hw/dma/trace-events b/hw/dma/trace-events
29
+ bool isread)
283
index XXXXXXX..XXXXXXX 100644
30
+{
284
--- a/hw/dma/trace-events
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
285
+++ b/hw/dma/trace-events
32
+ return CP_ACCESS_TRAP_EL2;
286
@@ -XXX,XX +XXX,XX @@ sparc32_dma_enable_lower(void) "Lower DMA enable"
33
+ }
287
288
# i8257.c
289
i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d"
34
+
290
+
35
+ return CP_ACCESS_OK;
291
+# pl330.c
36
+}
292
+pl330_fault(void *ptr, uint32_t flags) "ch: %p, flags: 0x%"PRIx32
37
+
293
+pl330_fault_abort(void) "abort interrupt raised"
38
+static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
294
+pl330_dmaend(void) "DMA ending"
39
+ bool isread)
295
+pl330_dmago(void) "DMA run"
40
+{
296
+pl330_dmald(uint32_t chan, uint32_t addr, uint32_t size, uint32_t num, uint32_t ch) "channel:%"PRId8" address:0x%08"PRIx32" size:0x%"PRIx32" num:%"PRId32"%c"
41
+ if (arm_feature(env, ARM_FEATURE_V8)) {
297
+pl330_dmakill(void) "abort interrupt lowered"
42
+ return access_aa64_tid1(env, ri, isread);
298
+pl330_dmalpend(uint8_t nf, uint8_t bs, uint8_t lc, uint8_t ch, uint8_t flag) "nf=0x%02x bs=0x%02x lc=0x%02x ch=0x%02x flag=0x%02x"
43
+ }
299
+pl330_dmalpiter(void) "loop reiteration"
44
+
300
+pl330_dmalpfallthrough(void) "loop fallthrough"
45
+ return CP_ACCESS_OK;
301
+pl330_dmasev_evirq(uint8_t ev_id) "event interrupt raised %"PRId8
46
+}
302
+pl330_dmasev_event(uint8_t ev_id) "event raised %"PRId8
47
+
303
+pl330_dmast(uint32_t chn, uint32_t addr, uint32_t sz, uint32_t num, uint32_t c) "channel:%"PRId8" address:0x%08"PRIx32" size:0x%"PRIx32" num:%"PRId32" %c"
48
static const ARMCPRegInfo v7_cp_reginfo[] = {
304
+pl330_dmawfe(uint8_t ev_id) "event lowered 0x%"PRIx8
49
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
305
+pl330_chan_exec_undef(void) "undefined instruction"
50
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
306
+pl330_exec_cycle(uint32_t addr, uint32_t size) "PL330 read from memory @0x%08"PRIx32" (size = 0x%08"PRIx32")"
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
307
+pl330_hexdump(uint32_t offset, char *str) " 0x%04"PRIx32":%s"
52
*/
308
+pl330_exec(void) "pl330_exec"
53
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
309
+pl330_debug_exec(uint8_t ch) "chan id: 0x%"PRIx8
54
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
310
+pl330_debug_exec_stall(void) "stall of debug instruction not implemented"
55
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
311
+pl330_iomem_write(uint32_t offset, uint32_t value) "addr: 0x%08"PRIx32" data: 0x%08"PRIx32
56
+ .access = PL1_R, .type = ARM_CP_CONST,
312
+pl330_iomem_write_clr(int i) "event interrupt lowered %d"
57
+ .accessfn = access_aa64_tid1,
313
+pl330_iomem_read(uint32_t addr, uint32_t data) "addr: 0x%08"PRIx32" data: 0x%08"PRIx32
58
+ .resetvalue = 0 },
59
/* Auxiliary fault status registers: these also are IMPDEF, and we
60
* choose to RAZ/WI for all cores.
61
*/
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
63
.access = PL1_R, .resetvalue = cpu->midr },
64
{ .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
65
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
66
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
67
+ .access = PL1_R,
68
+ .accessfn = access_aa64_tid1,
69
+ .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
70
REGINFO_SENTINEL
71
};
72
ARMCPRegInfo id_cp_reginfo[] = {
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
/* TCMTR and TLBTR exist in v8 but have no 64-bit versions */
75
{ .name = "TCMTR",
76
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
77
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ .access = PL1_R,
79
+ .accessfn = access_aa32_tid1,
80
+ .type = ARM_CP_CONST, .resetvalue = 0 },
81
REGINFO_SENTINEL
82
};
83
/* TLBTR is specific to VMSA */
84
ARMCPRegInfo id_tlbtr_reginfo = {
85
.name = "TLBTR",
86
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
87
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0,
88
+ .access = PL1_R,
89
+ .accessfn = access_aa32_tid1,
90
+ .type = ARM_CP_CONST, .resetvalue = 0,
91
};
92
/* MPUIR is specific to PMSA V6+ */
93
ARMCPRegInfo id_mpuir_reginfo = {
94
--
314
--
95
2.20.1
315
2.20.1
96
316
97
317
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Currently, we link the DRAM memory region to the FMC model (for DMAs)
3
Exynos DMA requires up to 33 interrupt lines (32 event interrupts
4
through a property alias at the SoC level. The I2C model will need a
4
plus abort interrupt), which all need to be wired together. Increase
5
similar region for DMA support, add a DRAM region property at the SoC
5
the maximum number of or-irq lines to 48 to support this configuration.
6
level for both model to use.
7
6
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20200123052540.6132-3-linux@roeck-us.net
10
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-4-clg@kaod.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
include/hw/arm/aspeed_soc.h | 1 +
12
include/hw/or-irq.h | 2 +-
16
hw/arm/aspeed_ast2600.c | 7 +++++--
13
1 file changed, 1 insertion(+), 1 deletion(-)
17
hw/arm/aspeed_soc.c | 9 +++++++--
18
3 files changed, 13 insertions(+), 4 deletions(-)
19
14
20
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
15
diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/aspeed_soc.h
17
--- a/include/hw/or-irq.h
23
+++ b/include/hw/arm/aspeed_soc.h
18
+++ b/include/hw/or-irq.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
19
@@ -XXX,XX +XXX,XX @@
25
ARMCPU cpu[ASPEED_CPUS_NUM];
20
/* This can safely be increased if necessary without breaking
26
uint32_t num_cpus;
21
* migration compatibility (as long as it remains greater than 15).
27
A15MPPrivState a7mpcore;
22
*/
28
+ MemoryRegion *dram_mr;
23
-#define MAX_OR_LINES 32
29
MemoryRegion sram;
24
+#define MAX_OR_LINES 48
30
AspeedVICState vic;
25
31
AspeedRtcState rtc;
26
typedef struct OrIRQState qemu_or_irq;
32
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/aspeed_ast2600.c
35
+++ b/hw/arm/aspeed_ast2600.c
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
typename);
38
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
39
&error_abort);
40
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
41
- &error_abort);
42
43
for (i = 0; i < sc->spis_num; i++) {
44
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
}
47
48
/* FMC, The number of CS is set at the board level */
49
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
50
+ if (err) {
51
+ error_propagate(errp, err);
52
+ return;
53
+ }
54
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
55
"sdram-base", &err);
56
if (err) {
57
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/aspeed_soc.c
60
+++ b/hw/arm/aspeed_soc.c
61
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
62
typename);
63
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
64
&error_abort);
65
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
66
- &error_abort);
67
68
for (i = 0; i < sc->spis_num; i++) {
69
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
70
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
71
aspeed_soc_get_irq(s, ASPEED_I2C));
72
73
/* FMC, The number of CS is set at the board level */
74
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
80
"sdram-base", &err);
81
if (err) {
82
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
83
}
84
static Property aspeed_soc_properties[] = {
85
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
86
+ DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
87
+ MemoryRegion *),
88
DEFINE_PROP_END_OF_LIST(),
89
};
90
27
91
--
28
--
92
2.20.1
29
2.20.1
93
30
94
31
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
The Aspeed I2C controller can operate in different transfer modes :
3
First parameter to exynos4210_get_irq() is not the SPI port number,
4
but the interrupt group number. Interrupt groups are 20 for mdma
5
and 21 for pdma. Interrupts are not inverted. Controllers support 32
6
events (pdma) or 31 events (mdma). Events must all be routed to a single
7
interrupt line. Set other parameters as documented in Exynos4210 datasheet,
8
section 8 (DMA controller).
4
9
5
- Byte Buffer mode, using a dedicated register to transfer a
10
Fixes: 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210")
6
byte. This is what the model supports today.
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
12
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
- Pool Buffer mode, using an internal SRAM to transfer multiple
13
Message-id: 20200123052540.6132-4-linux@roeck-us.net
9
bytes in the same command sequence.
10
11
Each SoC has different SRAM characteristics. On the AST2400, 2048
12
bytes of SRAM are available at offset 0x800 of the controller AHB
13
window. The pool buffer can be configured from 1 to 256 bytes per bus.
14
15
On the AST2500, the SRAM is at offset 0x200 and the pool buffer is of
16
16 bytes per bus.
17
18
On the AST2600, the SRAM is at offset 0xC00 and the pool buffer is of
19
32 bytes per bus. It can be splitted in two for TX and RX but the
20
current model does not add support for it as it it unused by known
21
drivers.
22
23
Signed-off-by: Cédric Le Goater <clg@kaod.org>
24
Reviewed-by: Joel Stanley <joel@jms.id.au>
25
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
26
Signed-off-by: Cédric Le Goater <clg@kaod.org>
27
Message-id: 20191119141211.25716-2-clg@kaod.org
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
15
---
30
include/hw/i2c/aspeed_i2c.h | 8 ++
16
include/hw/arm/exynos4210.h | 4 +++
31
hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++----
17
hw/arm/exynos4210.c | 51 +++++++++++++++++++++++++++++++------
32
2 files changed, 186 insertions(+), 19 deletions(-)
18
2 files changed, 47 insertions(+), 8 deletions(-)
33
19
34
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
20
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
35
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/i2c/aspeed_i2c.h
22
--- a/include/hw/arm/exynos4210.h
37
+++ b/include/hw/i2c/aspeed_i2c.h
23
+++ b/include/hw/arm/exynos4210.h
38
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
39
OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
25
#ifndef EXYNOS4210_H
40
26
#define EXYNOS4210_H
41
#define ASPEED_I2C_NR_BUSSES 16
27
42
+#define ASPEED_I2C_MAX_POOL_SIZE 0x800
28
+#include "hw/or-irq.h"
43
29
#include "hw/sysbus.h"
44
struct AspeedI2CState;
30
#include "target/arm/cpu-qom.h"
45
31
46
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
32
@@ -XXX,XX +XXX,XX @@
47
uint32_t intr_status;
33
48
uint32_t cmd;
34
#define EXYNOS4210_I2C_NUMBER 9
49
uint32_t buf;
35
50
+ uint32_t pool_ctrl;
36
+#define EXYNOS4210_NUM_DMA 3
51
} AspeedI2CBus;
52
53
typedef struct AspeedI2CState {
54
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
55
qemu_irq irq;
56
57
uint32_t intr_status;
58
+ MemoryRegion pool_iomem;
59
+ uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
60
61
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
62
} AspeedI2CState;
63
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
64
uint8_t reg_size;
65
uint8_t gap;
66
qemu_irq (*bus_get_irq)(AspeedI2CBus *);
67
+
37
+
68
+ uint64_t pool_size;
38
typedef struct Exynos4210Irq {
69
+ hwaddr pool_base;
39
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
70
+ uint8_t *(*bus_pool_base)(AspeedI2CBus *);
40
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
71
} AspeedI2CClass;
41
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210State {
72
42
MemoryRegion boot_secondary;
73
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
43
MemoryRegion bootreg_mem;
74
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
44
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
45
+ qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
46
} Exynos4210State;
47
48
#define TYPE_EXYNOS4210_SOC "exynos4210"
49
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
75
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/i2c/aspeed_i2c.c
51
--- a/hw/arm/exynos4210.c
77
+++ b/hw/i2c/aspeed_i2c.c
52
+++ b/hw/arm/exynos4210.c
78
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_calc_affinity(int cpu)
79
/* I2C Device (Bus) Register */
54
return (0x9 << ARM_AFF1_SHIFT) | cpu;
80
81
#define I2CD_FUN_CTRL_REG 0x00 /* I2CD Function Control */
82
-#define I2CD_BUFF_SEL_MASK (0x7 << 20)
83
-#define I2CD_BUFF_SEL(x) (x << 20)
84
+#define I2CD_POOL_PAGE_SEL(x) (((x) >> 20) & 0x7) /* AST2400 */
85
#define I2CD_M_SDA_LOCK_EN (0x1 << 16)
86
#define I2CD_MULTI_MASTER_DIS (0x1 << 15)
87
#define I2CD_M_SCL_DRIVE_EN (0x1 << 14)
88
@@ -XXX,XX +XXX,XX @@
89
#define I2CD_SCL_O_OUT_DIR (0x1 << 12)
90
#define I2CD_BUS_RECOVER_CMD_EN (0x1 << 11)
91
#define I2CD_S_ALT_EN (0x1 << 10)
92
-#define I2CD_RX_DMA_ENABLE (0x1 << 9)
93
-#define I2CD_TX_DMA_ENABLE (0x1 << 8)
94
95
/* Command Bit */
96
+#define I2CD_RX_DMA_ENABLE (0x1 << 9)
97
+#define I2CD_TX_DMA_ENABLE (0x1 << 8)
98
+#define I2CD_RX_BUFF_ENABLE (0x1 << 7)
99
+#define I2CD_TX_BUFF_ENABLE (0x1 << 6)
100
#define I2CD_M_STOP_CMD (0x1 << 5)
101
#define I2CD_M_S_RX_CMD_LAST (0x1 << 4)
102
#define I2CD_M_RX_CMD (0x1 << 3)
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_M_START_CMD (0x1)
105
106
#define I2CD_DEV_ADDR_REG 0x18 /* Slave Device Address */
107
-#define I2CD_BUF_CTRL_REG 0x1c /* Pool Buffer Control */
108
+#define I2CD_POOL_CTRL_REG 0x1c /* Pool Buffer Control */
109
+#define I2CD_POOL_RX_COUNT(x) (((x) >> 24) & 0xff)
110
+#define I2CD_POOL_RX_SIZE(x) ((((x) >> 16) & 0xff) + 1)
111
+#define I2CD_POOL_TX_COUNT(x) ((((x) >> 8) & 0xff) + 1)
112
+#define I2CD_POOL_OFFSET(x) (((x) & 0x3f) << 2) /* AST2400 */
113
#define I2CD_BYTE_BUF_REG 0x20 /* Transmit/Receive Byte Buffer */
114
#define I2CD_BYTE_BUF_TX_SHIFT 0
115
#define I2CD_BYTE_BUF_TX_MASK 0xff
116
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
117
return bus->intr_ctrl;
118
case I2CD_INTR_STS_REG:
119
return bus->intr_status;
120
+ case I2CD_POOL_CTRL_REG:
121
+ return bus->pool_ctrl;
122
case I2CD_BYTE_BUF_REG:
123
return bus->buf;
124
case I2CD_CMD_REG:
125
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
126
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
127
}
55
}
128
56
129
+static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
57
-static void pl330_create(uint32_t base, qemu_irq irq, int nreq)
58
+static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
59
+ int nreq, int nevents, int width)
60
{
61
SysBusDevice *busdev;
62
DeviceState *dev;
63
+ int i;
64
65
dev = qdev_create(NULL, "pl330");
66
+ qdev_prop_set_uint8(dev, "num_events", nevents);
67
+ qdev_prop_set_uint8(dev, "num_chnls", 8);
68
qdev_prop_set_uint8(dev, "num_periph_req", nreq);
69
+
70
+ qdev_prop_set_uint8(dev, "wr_cap", 4);
71
+ qdev_prop_set_uint8(dev, "wr_q_dep", 8);
72
+ qdev_prop_set_uint8(dev, "rd_cap", 4);
73
+ qdev_prop_set_uint8(dev, "rd_q_dep", 8);
74
+ qdev_prop_set_uint8(dev, "data_width", width);
75
+ qdev_prop_set_uint16(dev, "data_buffer_dep", width);
76
qdev_init_nofail(dev);
77
busdev = SYS_BUS_DEVICE(dev);
78
sysbus_mmio_map(busdev, 0, base);
79
- sysbus_connect_irq(busdev, 0, irq);
80
+
81
+ object_property_set_int(OBJECT(orgate), nevents + 1, "num-lines",
82
+ &error_abort);
83
+ object_property_set_bool(OBJECT(orgate), true, "realized", &error_abort);
84
+
85
+ for (i = 0; i < nevents + 1; i++) {
86
+ sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
87
+ }
88
+ qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
89
}
90
91
static void exynos4210_realize(DeviceState *socdev, Error **errp)
92
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
93
s->irq_table[exynos4210_get_irq(28, 3)]);
94
95
/*** DMA controllers ***/
96
- pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
97
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(35, 1)]), 32);
98
- pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
99
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(36, 1)]), 32);
100
- pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
101
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(34, 1)]), 1);
102
+ pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0],
103
+ s->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32);
104
+ pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1],
105
+ s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32);
106
+ pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2],
107
+ s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64);
108
+}
109
+
110
+static void exynos4210_init(Object *obj)
130
+{
111
+{
131
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
112
+ Exynos4210State *s = EXYNOS4210_SOC(obj);
132
+ int ret = -1;
133
+ int i;
113
+ int i;
134
+
114
+
135
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
115
+ for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
136
+ for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
116
+ char *name = g_strdup_printf("pl330-irq-orgate%d", i);
137
+ uint8_t *pool_base = aic->bus_pool_base(bus);
117
+ qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
138
+
118
+
139
+ ret = i2c_send(bus->bus, pool_base[i]);
119
+ object_initialize_child(obj, name, orgate, sizeof(*orgate),
140
+ if (ret) {
120
+ TYPE_OR_IRQ, &error_abort, NULL);
141
+ break;
121
+ g_free(name);
142
+ }
143
+ }
144
+ bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
145
+ } else {
146
+ ret = i2c_send(bus->bus, bus->buf);
147
+ }
122
+ }
148
+
149
+ return ret;
150
+}
151
+
152
+static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
153
+{
154
+ AspeedI2CState *s = bus->controller;
155
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
156
+ uint8_t data;
157
+ int i;
158
+
159
+ if (bus->cmd & I2CD_RX_BUFF_ENABLE) {
160
+ uint8_t *pool_base = aic->bus_pool_base(bus);
161
+
162
+ for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
163
+ pool_base[i] = i2c_recv(bus->bus);
164
+ }
165
+
166
+ /* Update RX count */
167
+ bus->pool_ctrl &= ~(0xff << 24);
168
+ bus->pool_ctrl |= (i & 0xff) << 24;
169
+ bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
170
+ } else {
171
+ data = i2c_recv(bus->bus);
172
+ bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
173
+ }
174
+}
175
+
176
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
177
{
178
- uint8_t ret;
179
-
180
aspeed_i2c_set_state(bus, I2CD_MRXD);
181
- ret = i2c_recv(bus->bus);
182
+ aspeed_i2c_bus_recv(bus);
183
bus->intr_status |= I2CD_INTR_RX_DONE;
184
- bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
185
if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
186
i2c_nack(bus->bus);
187
}
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
189
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
190
}
123
}
191
124
192
+static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
125
static void exynos4210_class_init(ObjectClass *klass, void *data)
193
+{
126
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_info = {
194
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
127
.name = TYPE_EXYNOS4210_SOC,
195
+
128
.parent = TYPE_SYS_BUS_DEVICE,
196
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
129
.instance_size = sizeof(Exynos4210State),
197
+ uint8_t *pool_base = aic->bus_pool_base(bus);
130
+ .instance_init = exynos4210_init,
198
+
131
.class_init = exynos4210_class_init,
199
+ return pool_base[0];
200
+ } else {
201
+ return bus->buf;
202
+ }
203
+}
204
+
205
/*
206
* The state machine needs some refinement. It is only used to track
207
* invalid STOP commands for the moment.
208
*/
209
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
210
{
211
+ uint8_t pool_start = 0;
212
+
213
bus->cmd &= ~0xFFFF;
214
bus->cmd |= value & 0xFFFF;
215
216
if (bus->cmd & I2CD_M_START_CMD) {
217
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
218
I2CD_MSTARTR : I2CD_MSTART;
219
+ uint8_t addr;
220
221
aspeed_i2c_set_state(bus, state);
222
223
- if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
224
- extract32(bus->buf, 0, 1))) {
225
+ addr = aspeed_i2c_get_addr(bus);
226
+
227
+ if (i2c_start_transfer(bus->bus, extract32(addr, 1, 7),
228
+ extract32(addr, 0, 1))) {
229
bus->intr_status |= I2CD_INTR_TX_NAK;
230
} else {
231
bus->intr_status |= I2CD_INTR_TX_ACK;
232
}
233
234
- /* START command is also a TX command, as the slave address is
235
- * sent on the bus */
236
- bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD);
237
+ bus->cmd &= ~I2CD_M_START_CMD;
238
+
239
+ /*
240
+ * The START command is also a TX command, as the slave
241
+ * address is sent on the bus. Drop the TX flag if nothing
242
+ * else needs to be sent in this sequence.
243
+ */
244
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
245
+ if (I2CD_POOL_TX_COUNT(bus->pool_ctrl) == 1) {
246
+ bus->cmd &= ~I2CD_M_TX_CMD;
247
+ } else {
248
+ /*
249
+ * Increase the start index in the TX pool buffer to
250
+ * skip the address byte.
251
+ */
252
+ pool_start++;
253
+ }
254
+ } else {
255
+ bus->cmd &= ~I2CD_M_TX_CMD;
256
+ }
257
258
/* No slave found */
259
if (!i2c_bus_busy(bus->bus)) {
260
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
261
262
if (bus->cmd & I2CD_M_TX_CMD) {
263
aspeed_i2c_set_state(bus, I2CD_MTXD);
264
- if (i2c_send(bus->bus, bus->buf)) {
265
+ if (aspeed_i2c_bus_send(bus, pool_start)) {
266
bus->intr_status |= (I2CD_INTR_TX_NAK);
267
i2c_end_transfer(bus->bus);
268
} else {
269
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
270
qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
271
__func__);
272
break;
273
+ case I2CD_POOL_CTRL_REG:
274
+ bus->pool_ctrl &= ~0xffffff;
275
+ bus->pool_ctrl |= (value & 0xffffff);
276
+ break;
277
+
278
case I2CD_BYTE_BUF_REG:
279
bus->buf = (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_SHIFT;
280
break;
281
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_ctrl_ops = {
282
.endianness = DEVICE_LITTLE_ENDIAN,
283
};
132
};
284
133
285
+static uint64_t aspeed_i2c_pool_read(void *opaque, hwaddr offset,
286
+ unsigned size)
287
+{
288
+ AspeedI2CState *s = opaque;
289
+ uint64_t ret = 0;
290
+ int i;
291
+
292
+ for (i = 0; i < size; i++) {
293
+ ret |= (uint64_t) s->pool[offset + i] << (8 * i);
294
+ }
295
+
296
+ return ret;
297
+}
298
+
299
+static void aspeed_i2c_pool_write(void *opaque, hwaddr offset,
300
+ uint64_t value, unsigned size)
301
+{
302
+ AspeedI2CState *s = opaque;
303
+ int i;
304
+
305
+ for (i = 0; i < size; i++) {
306
+ s->pool[offset + i] = (value >> (8 * i)) & 0xFF;
307
+ }
308
+}
309
+
310
+static const MemoryRegionOps aspeed_i2c_pool_ops = {
311
+ .read = aspeed_i2c_pool_read,
312
+ .write = aspeed_i2c_pool_write,
313
+ .endianness = DEVICE_LITTLE_ENDIAN,
314
+ .valid = {
315
+ .min_access_size = 1,
316
+ .max_access_size = 4,
317
+ },
318
+};
319
+
320
static const VMStateDescription aspeed_i2c_bus_vmstate = {
321
.name = TYPE_ASPEED_I2C,
322
- .version_id = 1,
323
- .minimum_version_id = 1,
324
+ .version_id = 2,
325
+ .minimum_version_id = 2,
326
.fields = (VMStateField[]) {
327
VMSTATE_UINT8(id, AspeedI2CBus),
328
VMSTATE_UINT32(ctrl, AspeedI2CBus),
329
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
330
VMSTATE_UINT32(intr_status, AspeedI2CBus),
331
VMSTATE_UINT32(cmd, AspeedI2CBus),
332
VMSTATE_UINT32(buf, AspeedI2CBus),
333
+ VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
334
VMSTATE_END_OF_LIST()
335
}
336
};
337
338
static const VMStateDescription aspeed_i2c_vmstate = {
339
.name = TYPE_ASPEED_I2C,
340
- .version_id = 1,
341
- .minimum_version_id = 1,
342
+ .version_id = 2,
343
+ .minimum_version_id = 2,
344
.fields = (VMStateField[]) {
345
VMSTATE_UINT32(intr_status, AspeedI2CState),
346
VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
347
ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmstate,
348
AspeedI2CBus),
349
+ VMSTATE_UINT8_ARRAY(pool, AspeedI2CState, ASPEED_I2C_MAX_POOL_SIZE),
350
VMSTATE_END_OF_LIST()
351
}
352
};
353
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
354
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
355
&s->busses[i].mr);
356
}
357
+
358
+ memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
359
+ "aspeed.i2c-pool", aic->pool_size);
360
+ memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
361
}
362
363
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
364
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
365
return bus->controller->irq;
366
}
367
368
+static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus)
369
+{
370
+ uint8_t *pool_page =
371
+ &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100];
372
+
373
+ return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)];
374
+}
375
+
376
static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
377
{
378
DeviceClass *dc = DEVICE_CLASS(klass);
379
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
380
aic->reg_size = 0x40;
381
aic->gap = 7;
382
aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq;
383
+ aic->pool_size = 0x800;
384
+ aic->pool_base = 0x800;
385
+ aic->bus_pool_base = aspeed_2400_i2c_bus_pool_base;
386
}
387
388
static const TypeInfo aspeed_2400_i2c_info = {
389
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus)
390
return bus->controller->irq;
391
}
392
393
+static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus)
394
+{
395
+ return &bus->controller->pool[bus->id * 0x10];
396
+}
397
+
398
static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
399
{
400
DeviceClass *dc = DEVICE_CLASS(klass);
401
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
402
aic->reg_size = 0x40;
403
aic->gap = 7;
404
aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq;
405
+ aic->pool_size = 0x100;
406
+ aic->pool_base = 0x200;
407
+ aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
408
}
409
410
static const TypeInfo aspeed_2500_i2c_info = {
411
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
412
return bus->irq;
413
}
414
415
+static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus)
416
+{
417
+ return &bus->controller->pool[bus->id * 0x20];
418
+}
419
+
420
static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
421
{
422
DeviceClass *dc = DEVICE_CLASS(klass);
423
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
424
aic->reg_size = 0x80;
425
aic->gap = -1; /* no gap */
426
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
427
+ aic->pool_size = 0x200;
428
+ aic->pool_base = 0xC00;
429
+ aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
430
}
431
432
static const TypeInfo aspeed_2600_i2c_info = {
433
--
134
--
434
2.20.1
135
2.20.1
435
136
436
137
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The SRAM must be enabled before using the Buffer Pool mode or the DMA
4
mode. This is not required on other SoCs.
5
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20191119141211.25716-3-clg@kaod.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/i2c/aspeed_i2c.h | 3 +++
14
hw/i2c/aspeed_i2c.c | 37 +++++++++++++++++++++++++++++++++++++
15
2 files changed, 40 insertions(+)
16
17
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/i2c/aspeed_i2c.h
20
+++ b/include/hw/i2c/aspeed_i2c.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
22
qemu_irq irq;
23
24
uint32_t intr_status;
25
+ uint32_t ctrl_global;
26
MemoryRegion pool_iomem;
27
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
28
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
30
uint64_t pool_size;
31
hwaddr pool_base;
32
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
33
+ bool check_sram;
34
+
35
} AspeedI2CClass;
36
37
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
38
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/i2c/aspeed_i2c.c
41
+++ b/hw/i2c/aspeed_i2c.c
42
@@ -XXX,XX +XXX,XX @@
43
#define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */
44
#define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target
45
Assignment */
46
+#define I2C_CTRL_GLOBAL 0x0C /* Global Control Register */
47
+#define I2C_CTRL_SRAM_EN BIT(0)
48
49
/* I2C Device (Bus) Register */
50
51
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
52
}
53
}
54
55
+static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
56
+{
57
+ AspeedI2CState *s = bus->controller;
58
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
59
+
60
+ if (!aic->check_sram) {
61
+ return true;
62
+ }
63
+
64
+ /*
65
+ * AST2500: SRAM must be enabled before using the Buffer Pool or
66
+ * DMA mode.
67
+ */
68
+ if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) &&
69
+ (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE |
70
+ I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) {
71
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func__);
72
+ return false;
73
+ }
74
+
75
+ return true;
76
+}
77
+
78
/*
79
* The state machine needs some refinement. It is only used to track
80
* invalid STOP commands for the moment.
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
82
bus->cmd &= ~0xFFFF;
83
bus->cmd |= value & 0xFFFF;
84
85
+ if (!aspeed_i2c_check_sram(bus)) {
86
+ return;
87
+ }
88
+
89
if (bus->cmd & I2CD_M_START_CMD) {
90
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
91
I2CD_MSTARTR : I2CD_MSTART;
92
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
93
switch (offset) {
94
case I2C_CTRL_STATUS:
95
return s->intr_status;
96
+ case I2C_CTRL_GLOBAL:
97
+ return s->ctrl_global;
98
default:
99
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
100
__func__, offset);
101
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
102
static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset,
103
uint64_t value, unsigned size)
104
{
105
+ AspeedI2CState *s = opaque;
106
+
107
switch (offset) {
108
+ case I2C_CTRL_GLOBAL:
109
+ s->ctrl_global = value;
110
+ break;
111
case I2C_CTRL_STATUS:
112
default:
113
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
114
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
115
aic->pool_size = 0x100;
116
aic->pool_base = 0x200;
117
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
118
+ aic->check_sram = true;
119
}
120
121
static const TypeInfo aspeed_2500_i2c_info = {
122
--
123
2.20.1
124
125
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
3
Replace debug code with tracing to aid debugging.
4
Reviewed-by: Joel Stanley <joel@jms.id.au>
4
5
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Message-id: 20200123052540.6132-5-linux@roeck-us.net
8
Message-id: 20191119141211.25716-6-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++-------
10
hw/char/exynos4210_uart.c | 96 ++++++++++++---------------------------
12
hw/i2c/trace-events | 9 +++++
11
hw/char/trace-events | 17 +++++++
13
2 files changed, 89 insertions(+), 13 deletions(-)
12
2 files changed, 47 insertions(+), 66 deletions(-)
14
13
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
14
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/aspeed_i2c.c
16
--- a/hw/char/exynos4210_uart.c
18
+++ b/hw/i2c/aspeed_i2c.c
17
+++ b/hw/char/exynos4210_uart.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
20
#include "hw/i2c/aspeed_i2c.h"
21
#include "hw/irq.h"
19
#include "hw/irq.h"
22
#include "hw/qdev-properties.h"
20
#include "hw/qdev-properties.h"
21
22
-#undef DEBUG_UART
23
-#undef DEBUG_UART_EXTEND
24
-#undef DEBUG_IRQ
25
-#undef DEBUG_Rx_DATA
26
-#undef DEBUG_Tx_DATA
27
-
28
-#define DEBUG_UART 0
29
-#define DEBUG_UART_EXTEND 0
30
-#define DEBUG_IRQ 0
31
-#define DEBUG_Rx_DATA 0
32
-#define DEBUG_Tx_DATA 0
33
-
34
-#if DEBUG_UART
35
-#define PRINT_DEBUG(fmt, args...) \
36
- do { \
37
- fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
38
- } while (0)
39
-
40
-#if DEBUG_UART_EXTEND
41
-#define PRINT_DEBUG_EXTEND(fmt, args...) \
42
- do { \
43
- fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
44
- } while (0)
45
-#else
46
-#define PRINT_DEBUG_EXTEND(fmt, args...) \
47
- do {} while (0)
48
-#endif /* EXTEND */
49
-
50
-#else
51
-#define PRINT_DEBUG(fmt, args...) \
52
- do {} while (0)
53
-#define PRINT_DEBUG_EXTEND(fmt, args...) \
54
- do {} while (0)
55
-#endif
56
-
57
-#define PRINT_ERROR(fmt, args...) \
58
- do { \
59
- fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
60
- } while (0)
23
+#include "trace.h"
61
+#include "trace.h"
24
62
25
/* I2C Global Register */
63
/*
26
64
* Offsets for UART registers relative to SFR base address
27
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
65
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210UartState {
66
} Exynos4210UartState;
67
68
69
-#if DEBUG_UART
70
-/* Used only for debugging inside PRINT_DEBUG_... macros */
71
+/* Used only for tracing */
72
static const char *exynos4210_uart_regname(hwaddr offset)
28
{
73
{
29
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
74
30
75
@@ -XXX,XX +XXX,XX @@ static const char *exynos4210_uart_regname(hwaddr offset)
31
+ trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status,
76
32
+ bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "",
77
return NULL;
33
+ bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "",
78
}
34
+ bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "",
79
-#endif
35
+ bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "",
80
36
+ bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : "");
81
82
static void fifo_store(Exynos4210UartFIFO *q, uint8_t ch)
83
@@ -XXX,XX +XXX,XX @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState
84
break;
85
default:
86
level = 0;
87
- PRINT_ERROR("Wrong UART channel number: %d\n", s->channel);
88
+ trace_exynos_uart_channel_error(s->channel);
89
}
90
91
return level;
92
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
93
94
if (s->reg[I_(UINTP)]) {
95
qemu_irq_raise(s->irq);
96
-
97
-#if DEBUG_IRQ
98
- fprintf(stderr, "UART%d: IRQ has been raised: %08x\n",
99
- s->channel, s->reg[I_(UINTP)]);
100
-#endif
101
-
102
+ trace_exynos_uart_irq_raised(s->channel, s->reg[I_(UINTP)]);
103
} else {
104
qemu_irq_lower(s->irq);
105
+ trace_exynos_uart_irq_lowered(s->channel);
106
}
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
110
111
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
112
113
- PRINT_DEBUG("UART%d: speed: %d, parity: %c, data: %d, stop: %d\n",
114
+ trace_exynos_uart_update_params(
115
s->channel, speed, parity, data_bits, stop_bits);
116
}
117
118
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
119
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
120
uint8_t ch;
121
122
- PRINT_DEBUG_EXTEND("UART%d: <0x%04x> %s <- 0x%08llx\n", s->channel,
123
- offset, exynos4210_uart_regname(offset), (long long unsigned int)val);
124
+ trace_exynos_uart_write(s->channel, offset,
125
+ exynos4210_uart_regname(offset), val);
126
127
switch (offset) {
128
case ULCON:
129
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
130
if (val & UFCON_Rx_FIFO_RESET) {
131
fifo_reset(&s->rx);
132
s->reg[I_(UFCON)] &= ~UFCON_Rx_FIFO_RESET;
133
- PRINT_DEBUG("UART%d: Rx FIFO Reset\n", s->channel);
134
+ trace_exynos_uart_rx_fifo_reset(s->channel);
135
}
136
if (val & UFCON_Tx_FIFO_RESET) {
137
fifo_reset(&s->tx);
138
s->reg[I_(UFCON)] &= ~UFCON_Tx_FIFO_RESET;
139
- PRINT_DEBUG("UART%d: Tx FIFO Reset\n", s->channel);
140
+ trace_exynos_uart_tx_fifo_reset(s->channel);
141
}
142
break;
143
144
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
145
/* XXX this blocks entire thread. Rewrite to use
146
* qemu_chr_fe_write and background I/O callbacks */
147
qemu_chr_fe_write_all(&s->chr, &ch, 1);
148
-#if DEBUG_Tx_DATA
149
- fprintf(stderr, "%c", ch);
150
-#endif
151
+ trace_exynos_uart_tx(s->channel, ch);
152
s->reg[I_(UTRSTAT)] |= UTRSTAT_TRANSMITTER_EMPTY |
153
UTRSTAT_Tx_BUFFER_EMPTY;
154
s->reg[I_(UINTSP)] |= UINTSP_TXD;
155
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
156
case UINTP:
157
s->reg[I_(UINTP)] &= ~val;
158
s->reg[I_(UINTSP)] &= ~val;
159
- PRINT_DEBUG("UART%d: UINTP [%04x] have been cleared: %08x\n",
160
- s->channel, offset, s->reg[I_(UINTP)]);
161
+ trace_exynos_uart_intclr(s->channel, s->reg[I_(UINTP)]);
162
exynos4210_uart_update_irq(s);
163
break;
164
case UTRSTAT:
165
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
166
case UFSTAT:
167
case UMSTAT:
168
case URXH:
169
- PRINT_DEBUG("UART%d: Trying to write into RO register: %s [%04x]\n",
170
+ trace_exynos_uart_ro_write(
171
s->channel, exynos4210_uart_regname(offset), offset);
172
break;
173
case UINTSP:
174
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
175
case UERSTAT: /* Read Only */
176
res = s->reg[I_(UERSTAT)];
177
s->reg[I_(UERSTAT)] = 0;
178
+ trace_exynos_uart_read(s->channel, offset,
179
+ exynos4210_uart_regname(offset), res);
180
return res;
181
case UFSTAT: /* Read Only */
182
s->reg[I_(UFSTAT)] = fifo_elements_number(&s->rx) & 0xff;
183
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
184
s->reg[I_(UFSTAT)] |= UFSTAT_Rx_FIFO_FULL;
185
s->reg[I_(UFSTAT)] &= ~0xff;
186
}
187
+ trace_exynos_uart_read(s->channel, offset,
188
+ exynos4210_uart_regname(offset),
189
+ s->reg[I_(UFSTAT)]);
190
return s->reg[I_(UFSTAT)];
191
case URXH:
192
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
193
if (fifo_elements_number(&s->rx)) {
194
res = fifo_retrieve(&s->rx);
195
-#if DEBUG_Rx_DATA
196
- fprintf(stderr, "%c", res);
197
-#endif
198
+ trace_exynos_uart_rx(s->channel, res);
199
if (!fifo_elements_number(&s->rx)) {
200
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
201
} else {
202
s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
203
}
204
} else {
205
+ trace_exynos_uart_rx_error(s->channel);
206
s->reg[I_(UINTSP)] |= UINTSP_ERROR;
207
exynos4210_uart_update_irq(s);
208
res = 0;
209
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
210
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
211
res = s->reg[I_(URXH)];
212
}
213
+ trace_exynos_uart_read(s->channel, offset,
214
+ exynos4210_uart_regname(offset), res);
215
return res;
216
case UTXH:
217
- PRINT_DEBUG("UART%d: Trying to read from WO register: %s [%04x]\n",
218
- s->channel, exynos4210_uart_regname(offset), offset);
219
+ trace_exynos_uart_wo_read(s->channel, exynos4210_uart_regname(offset),
220
+ offset);
221
break;
222
default:
223
+ trace_exynos_uart_read(s->channel, offset,
224
+ exynos4210_uart_regname(offset),
225
+ s->reg[I_(offset)]);
226
return s->reg[I_(offset)];
227
}
228
229
+ trace_exynos_uart_read(s->channel, offset, exynos4210_uart_regname(offset),
230
+ 0);
231
return 0;
232
}
233
234
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_reset(DeviceState *dev)
235
fifo_reset(&s->rx);
236
fifo_reset(&s->tx);
237
238
- PRINT_DEBUG("UART%d: Rx FIFO size: %d\n", s->channel, s->rx.size);
239
+ trace_exynos_uart_rxsize(s->channel, s->rx.size);
240
}
241
242
static const VMStateDescription vmstate_exynos4210_uart_fifo = {
243
diff --git a/hw/char/trace-events b/hw/char/trace-events
244
index XXXXXXX..XXXXXXX 100644
245
--- a/hw/char/trace-events
246
+++ b/hw/char/trace-events
247
@@ -XXX,XX +XXX,XX @@ cmsdk_apb_uart_set_params(int speed) "CMSDK APB UART: params set to %d 8N1"
248
# nrf51_uart.c
249
nrf51_uart_read(uint64_t addr, uint64_t r, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u"
250
nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u"
37
+
251
+
38
bus->intr_status &= bus->intr_ctrl;
252
+# exynos4210_uart.c
39
if (bus->intr_status) {
253
+exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32
40
bus->controller->intr_status |= 1 << bus->id;
254
+exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered"
41
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
255
+exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d"
42
{
256
+exynos_uart_write(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s <- 0x%" PRIx64
43
AspeedI2CBus *bus = opaque;
257
+exynos_uart_read(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s -> 0x%" PRIx64
44
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
258
+exynos_uart_rx_fifo_reset(uint32_t channel) "UART%d: Rx FIFO Reset"
45
+ uint64_t value = -1;
259
+exynos_uart_tx_fifo_reset(uint32_t channel) "UART%d: Tx FIFO Reset"
46
260
+exynos_uart_tx(uint32_t channel, uint8_t ch) "UART%d: Tx 0x%02"PRIx32
47
switch (offset) {
261
+exynos_uart_intclr(uint32_t channel, uint32_t reg) "UART%d: interrupts cleared: 0x%08"PRIx32
48
case I2CD_FUN_CTRL_REG:
262
+exynos_uart_ro_write(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to write into RO register: %s [0x%04"PRIx32"]"
49
- return bus->ctrl;
263
+exynos_uart_rx(uint32_t channel, uint8_t ch) "UART%d: Rx 0x%02"PRIx32
50
+ value = bus->ctrl;
264
+exynos_uart_rx_error(uint32_t channel) "UART%d: Rx error"
51
+ break;
265
+exynos_uart_wo_read(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to read from WO register: %s [0x%04"PRIx32"]"
52
case I2CD_AC_TIMING_REG1:
266
+exynos_uart_rxsize(uint32_t channel, uint32_t size) "UART%d: Rx FIFO size: %d"
53
- return bus->timing[0];
267
+exynos_uart_channel_error(uint32_t channel) "Wrong UART channel number: %d"
54
+ value = bus->timing[0];
55
+ break;
56
case I2CD_AC_TIMING_REG2:
57
- return bus->timing[1];
58
+ value = bus->timing[1];
59
+ break;
60
case I2CD_INTR_CTRL_REG:
61
- return bus->intr_ctrl;
62
+ value = bus->intr_ctrl;
63
+ break;
64
case I2CD_INTR_STS_REG:
65
- return bus->intr_status;
66
+ value = bus->intr_status;
67
+ break;
68
case I2CD_POOL_CTRL_REG:
69
- return bus->pool_ctrl;
70
+ value = bus->pool_ctrl;
71
+ break;
72
case I2CD_BYTE_BUF_REG:
73
- return bus->buf;
74
+ value = bus->buf;
75
+ break;
76
case I2CD_CMD_REG:
77
- return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
78
+ value = bus->cmd | (i2c_bus_busy(bus->bus) << 16);
79
+ break;
80
case I2CD_DMA_ADDR:
81
if (!aic->has_dma) {
82
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
83
- return -1;
84
+ break;
85
}
86
- return bus->dma_addr;
87
+ value = bus->dma_addr;
88
+ break;
89
case I2CD_DMA_LEN:
90
if (!aic->has_dma) {
91
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
92
- return -1;
93
+ break;
94
}
95
- return bus->dma_len;
96
+ value = bus->dma_len;
97
+ break;
98
+
99
default:
100
qemu_log_mask(LOG_GUEST_ERROR,
101
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
102
- return -1;
103
+ value = -1;
104
+ break;
105
}
106
+
107
+ trace_aspeed_i2c_bus_read(bus->id, offset, size, value);
108
+ return value;
109
}
110
111
static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state)
112
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
113
for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
114
uint8_t *pool_base = aic->bus_pool_base(bus);
115
116
+ trace_aspeed_i2c_bus_send("BUF", i + 1,
117
+ I2CD_POOL_TX_COUNT(bus->pool_ctrl),
118
+ pool_base[i]);
119
ret = i2c_send(bus->bus, pool_base[i]);
120
if (ret) {
121
break;
122
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
123
while (bus->dma_len) {
124
uint8_t data;
125
aspeed_i2c_dma_read(bus, &data);
126
+ trace_aspeed_i2c_bus_send("DMA", bus->dma_len, bus->dma_len, data);
127
ret = i2c_send(bus->bus, data);
128
if (ret) {
129
break;
130
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
131
}
132
bus->cmd &= ~I2CD_TX_DMA_ENABLE;
133
} else {
134
+ trace_aspeed_i2c_bus_send("BYTE", pool_start, 1, bus->buf);
135
ret = i2c_send(bus->bus, bus->buf);
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
139
140
for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
141
pool_base[i] = i2c_recv(bus->bus);
142
+ trace_aspeed_i2c_bus_recv("BUF", i + 1,
143
+ I2CD_POOL_RX_SIZE(bus->pool_ctrl),
144
+ pool_base[i]);
145
}
146
147
/* Update RX count */
148
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
149
MemTxResult result;
150
151
data = i2c_recv(bus->bus);
152
+ trace_aspeed_i2c_bus_recv("DMA", bus->dma_len, bus->dma_len, data);
153
result = address_space_write(&s->dram_as, bus->dma_addr,
154
MEMTXATTRS_UNSPECIFIED, &data, 1);
155
if (result != MEMTX_OK) {
156
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
157
bus->cmd &= ~I2CD_RX_DMA_ENABLE;
158
} else {
159
data = i2c_recv(bus->bus);
160
+ trace_aspeed_i2c_bus_recv("BYTE", 1, 1, bus->buf);
161
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
162
}
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
165
return true;
166
}
167
168
+static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
169
+{
170
+ g_autofree char *cmd_flags;
171
+ uint32_t count;
172
+
173
+ if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) {
174
+ count = I2CD_POOL_TX_COUNT(bus->pool_ctrl);
175
+ } else if (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_RX_DMA_ENABLE)) {
176
+ count = bus->dma_len;
177
+ } else { /* BYTE mode */
178
+ count = 1;
179
+ }
180
+
181
+ cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s",
182
+ bus->cmd & I2CD_M_START_CMD ? "start|" : "",
183
+ bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "",
184
+ bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" : "",
185
+ bus->cmd & I2CD_RX_BUFF_ENABLE ? "rxbuf|" : "",
186
+ bus->cmd & I2CD_TX_BUFF_ENABLE ? "txbuf|" : "",
187
+ bus->cmd & I2CD_M_TX_CMD ? "tx|" : "",
188
+ bus->cmd & I2CD_M_RX_CMD ? "rx|" : "",
189
+ bus->cmd & I2CD_M_S_RX_CMD_LAST ? "last|" : "",
190
+ bus->cmd & I2CD_M_STOP_CMD ? "stop" : "");
191
+
192
+ trace_aspeed_i2c_bus_cmd(bus->cmd, cmd_flags, count, bus->intr_status);
193
+}
194
+
195
/*
196
* The state machine needs some refinement. It is only used to track
197
* invalid STOP commands for the moment.
198
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
199
return;
200
}
201
202
+ if (trace_event_get_state_backends(TRACE_ASPEED_I2C_BUS_CMD)) {
203
+ aspeed_i2c_bus_cmd_dump(bus);
204
+ }
205
+
206
if (bus->cmd & I2CD_M_START_CMD) {
207
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
208
I2CD_MSTARTR : I2CD_MSTART;
209
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
210
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
211
bool handle_rx;
212
213
+ trace_aspeed_i2c_bus_write(bus->id, offset, size, value);
214
+
215
switch (offset) {
216
case I2CD_FUN_CTRL_REG:
217
if (value & I2CD_SLAVE_EN) {
218
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/i2c/trace-events
221
+++ b/hw/i2c/trace-events
222
@@ -XXX,XX +XXX,XX @@
223
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
224
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
225
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
226
+
227
+# aspeed_i2c.c
228
+
229
+aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x"
230
+aspeed_i2c_bus_raise_interrupt(uint32_t intr_status, const char *str1, const char *str2, const char *str3, const char *str4, const char *str5) "handled intr=0x%x %s%s%s%s%s"
231
+aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
232
+aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
233
+aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x"
234
+aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x"
235
--
268
--
236
2.20.1
269
2.20.1
237
270
238
271
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA
3
After restoring a VM, serial parameters need to be updated to reflect
4
transfers to and from DRAM.
4
restored register values. Implement a post_load function to handle this
5
situation.
5
6
6
A pair of registers defines the buffer address and the length of the
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
DMA transfer. The address should be aligned on 4 bytes and the maximum
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
length should not exceed 4K. The receive or transmit DMA transfer can
9
Message-id: 20200123052540.6132-6-linux@roeck-us.net
9
then be initiated with specific bits in the Command/Status register of
10
the controller.
11
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
Reviewed-by: Joel Stanley <joel@jms.id.au>
14
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
16
Message-id: 20191119141211.25716-5-clg@kaod.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
11
---
19
include/hw/i2c/aspeed_i2c.h | 5 ++
12
hw/char/exynos4210_uart.c | 10 ++++++++++
20
hw/arm/aspeed_ast2600.c | 5 ++
13
1 file changed, 10 insertions(+)
21
hw/arm/aspeed_soc.c | 5 ++
22
hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++-
23
4 files changed, 138 insertions(+), 3 deletions(-)
24
14
25
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
15
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/i2c/aspeed_i2c.h
17
--- a/hw/char/exynos4210_uart.c
28
+++ b/include/hw/i2c/aspeed_i2c.h
18
+++ b/hw/char/exynos4210_uart.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
19
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_reset(DeviceState *dev)
30
uint32_t cmd;
20
trace_exynos_uart_rxsize(s->channel, s->rx.size);
31
uint32_t buf;
32
uint32_t pool_ctrl;
33
+ uint32_t dma_addr;
34
+ uint32_t dma_len;
35
} AspeedI2CBus;
36
37
typedef struct AspeedI2CState {
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
39
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
40
41
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
42
+ MemoryRegion *dram_mr;
43
+ AddressSpace dram_as;
44
} AspeedI2CState;
45
46
#define ASPEED_I2C_CLASS(klass) \
47
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
48
hwaddr pool_base;
49
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
50
bool check_sram;
51
+ bool has_dma;
52
53
} AspeedI2CClass;
54
55
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/aspeed_ast2600.c
58
+++ b/hw/arm/aspeed_ast2600.c
59
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
60
}
61
62
/* I2C */
63
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
64
+ if (err) {
65
+ error_propagate(errp, err);
66
+ return;
67
+ }
68
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
69
if (err) {
70
error_propagate(errp, err);
71
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/arm/aspeed_soc.c
74
+++ b/hw/arm/aspeed_soc.c
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
76
}
77
78
/* I2C */
79
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
80
+ if (err) {
81
+ error_propagate(errp, err);
82
+ return;
83
+ }
84
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
85
if (err) {
86
error_propagate(errp, err);
87
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/i2c/aspeed_i2c.c
90
+++ b/hw/i2c/aspeed_i2c.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "migration/vmstate.h"
93
#include "qemu/log.h"
94
#include "qemu/module.h"
95
+#include "qemu/error-report.h"
96
+#include "qapi/error.h"
97
#include "hw/i2c/aspeed_i2c.h"
98
#include "hw/irq.h"
99
+#include "hw/qdev-properties.h"
100
101
/* I2C Global Register */
102
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_BYTE_BUF_TX_MASK 0xff
105
#define I2CD_BYTE_BUF_RX_SHIFT 8
106
#define I2CD_BYTE_BUF_RX_MASK 0xff
107
-
108
+#define I2CD_DMA_ADDR 0x24 /* DMA Buffer Address */
109
+#define I2CD_DMA_LEN 0x28 /* DMA Transfer Length < 4KB */
110
111
static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus)
112
{
113
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
114
unsigned size)
115
{
116
AspeedI2CBus *bus = opaque;
117
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
118
119
switch (offset) {
120
case I2CD_FUN_CTRL_REG:
121
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
122
return bus->buf;
123
case I2CD_CMD_REG:
124
return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
125
+ case I2CD_DMA_ADDR:
126
+ if (!aic->has_dma) {
127
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
128
+ return -1;
129
+ }
130
+ return bus->dma_addr;
131
+ case I2CD_DMA_LEN:
132
+ if (!aic->has_dma) {
133
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
134
+ return -1;
135
+ }
136
+ return bus->dma_len;
137
default:
138
qemu_log_mask(LOG_GUEST_ERROR,
139
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
140
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
141
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
142
}
21
}
143
22
144
+static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
23
+static int exynos4210_uart_post_load(void *opaque, int version_id)
145
+{
24
+{
146
+ MemTxResult result;
25
+ Exynos4210UartState *s = (Exynos4210UartState *)opaque;
147
+ AspeedI2CState *s = bus->controller;
148
+
26
+
149
+ result = address_space_read(&s->dram_as, bus->dma_addr,
27
+ exynos4210_uart_update_parameters(s);
150
+ MEMTXATTRS_UNSPECIFIED, data, 1);
151
+ if (result != MEMTX_OK) {
152
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
153
+ __func__, bus->dma_addr);
154
+ return -1;
155
+ }
156
+
28
+
157
+ bus->dma_addr++;
158
+ bus->dma_len--;
159
+ return 0;
29
+ return 0;
160
+}
30
+}
161
+
31
+
162
static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
32
static const VMStateDescription vmstate_exynos4210_uart_fifo = {
163
{
33
.name = "exynos4210.uart.fifo",
164
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
34
.version_id = 1,
165
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
35
.minimum_version_id = 1,
166
}
36
+ .post_load = exynos4210_uart_post_load,
167
}
168
bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
169
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
170
+ while (bus->dma_len) {
171
+ uint8_t data;
172
+ aspeed_i2c_dma_read(bus, &data);
173
+ ret = i2c_send(bus->bus, data);
174
+ if (ret) {
175
+ break;
176
+ }
177
+ }
178
+ bus->cmd &= ~I2CD_TX_DMA_ENABLE;
179
} else {
180
ret = i2c_send(bus->bus, bus->buf);
181
}
182
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
183
bus->pool_ctrl &= ~(0xff << 24);
184
bus->pool_ctrl |= (i & 0xff) << 24;
185
bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
186
+ } else if (bus->cmd & I2CD_RX_DMA_ENABLE) {
187
+ uint8_t data;
188
+
189
+ while (bus->dma_len) {
190
+ MemTxResult result;
191
+
192
+ data = i2c_recv(bus->bus);
193
+ result = address_space_write(&s->dram_as, bus->dma_addr,
194
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
195
+ if (result != MEMTX_OK) {
196
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
197
+ __func__, bus->dma_addr);
198
+ return;
199
+ }
200
+ bus->dma_addr++;
201
+ bus->dma_len--;
202
+ }
203
+ bus->cmd &= ~I2CD_RX_DMA_ENABLE;
204
} else {
205
data = i2c_recv(bus->bus);
206
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
207
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
208
uint8_t *pool_base = aic->bus_pool_base(bus);
209
210
return pool_base[0];
211
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
212
+ uint8_t data;
213
+
214
+ aspeed_i2c_dma_read(bus, &data);
215
+ return data;
216
} else {
217
return bus->buf;
218
}
219
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
220
*/
221
pool_start++;
222
}
223
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
224
+ if (bus->dma_len == 0) {
225
+ bus->cmd &= ~I2CD_M_TX_CMD;
226
+ }
227
} else {
228
bus->cmd &= ~I2CD_M_TX_CMD;
229
}
230
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
231
break;
232
}
233
234
+ if (!aic->has_dma &&
235
+ value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) {
236
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
237
+ break;
238
+ }
239
+
240
aspeed_i2c_bus_handle_cmd(bus, value);
241
aspeed_i2c_bus_raise_interrupt(bus);
242
break;
243
+ case I2CD_DMA_ADDR:
244
+ if (!aic->has_dma) {
245
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
246
+ break;
247
+ }
248
+
249
+ bus->dma_addr = value & 0xfffffffc;
250
+ break;
251
+
252
+ case I2CD_DMA_LEN:
253
+ if (!aic->has_dma) {
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
255
+ break;
256
+ }
257
+
258
+ bus->dma_len = value & 0xfff;
259
+ if (!bus->dma_len) {
260
+ qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__);
261
+ }
262
+ break;
263
264
default:
265
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
266
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_pool_ops = {
267
268
static const VMStateDescription aspeed_i2c_bus_vmstate = {
269
.name = TYPE_ASPEED_I2C,
270
- .version_id = 2,
271
- .minimum_version_id = 2,
272
+ .version_id = 3,
273
+ .minimum_version_id = 3,
274
.fields = (VMStateField[]) {
37
.fields = (VMStateField[]) {
275
VMSTATE_UINT8(id, AspeedI2CBus),
38
VMSTATE_UINT32(sp, Exynos4210UartFIFO),
276
VMSTATE_UINT32(ctrl, AspeedI2CBus),
39
VMSTATE_UINT32(rp, Exynos4210UartFIFO),
277
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
278
VMSTATE_UINT32(cmd, AspeedI2CBus),
279
VMSTATE_UINT32(buf, AspeedI2CBus),
280
VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
281
+ VMSTATE_UINT32(dma_addr, AspeedI2CBus),
282
+ VMSTATE_UINT32(dma_len, AspeedI2CBus),
283
VMSTATE_END_OF_LIST()
284
}
285
};
286
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_reset(DeviceState *dev)
287
s->busses[i].intr_status = 0;
288
s->busses[i].cmd = 0;
289
s->busses[i].buf = 0;
290
+ s->busses[i].dma_addr = 0;
291
+ s->busses[i].dma_len = 0;
292
i2c_end_transfer(s->busses[i].bus);
293
}
294
}
295
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
296
memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
297
"aspeed.i2c-pool", aic->pool_size);
298
memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
299
+
300
+ if (aic->has_dma) {
301
+ if (!s->dram_mr) {
302
+ error_setg(errp, TYPE_ASPEED_I2C ": 'dram' link not set");
303
+ return;
304
+ }
305
+
306
+ address_space_init(&s->dram_as, s->dram_mr, "dma-dram");
307
+ }
308
}
309
310
+static Property aspeed_i2c_properties[] = {
311
+ DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr,
312
+ TYPE_MEMORY_REGION, MemoryRegion *),
313
+ DEFINE_PROP_END_OF_LIST(),
314
+};
315
+
316
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
317
{
318
DeviceClass *dc = DEVICE_CLASS(klass);
319
320
dc->vmsd = &aspeed_i2c_vmstate;
321
dc->reset = aspeed_i2c_reset;
322
+ dc->props = aspeed_i2c_properties;
323
dc->realize = aspeed_i2c_realize;
324
dc->desc = "Aspeed I2C Controller";
325
}
326
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
327
aic->pool_base = 0x200;
328
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
329
aic->check_sram = true;
330
+ aic->has_dma = true;
331
}
332
333
static const TypeInfo aspeed_2500_i2c_info = {
334
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
335
aic->pool_size = 0x200;
336
aic->pool_base = 0xC00;
337
aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
338
+ aic->has_dma = true;
339
}
340
341
static const TypeInfo aspeed_2600_i2c_info = {
342
--
40
--
343
2.20.1
41
2.20.1
344
42
345
43
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
Most boards have this much.
4
5
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-7-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/aspeed_sdmc.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_sdmc.c
18
+++ b/hw/misc/aspeed_sdmc.c
19
@@ -XXX,XX +XXX,XX @@ static int ast2600_rambits(AspeedSDMCState *s)
20
}
21
22
/* use a common default */
23
- warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
24
+ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M",
25
s->ram_size);
26
- s->ram_size = 512 << 20;
27
- return ASPEED_SDMC_AST2600_512MB;
28
+ s->ram_size = 1024 << 20;
29
+ return ASPEED_SDMC_AST2600_1024MB;
30
}
31
32
static void aspeed_sdmc_reset(DeviceState *dev)
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This models the clock write one to clear registers, and fixes up some
4
incorrect behavior in all of the write to clear registers.
5
6
There was also a typo in one of the register definitions.
7
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-8-clg@kaod.org
13
[clg: checkpatch.pl fixes ]
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/misc/aspeed_scu.c | 19 ++++++++++++++-----
18
1 file changed, 14 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/aspeed_scu.c
23
+++ b/hw/misc/aspeed_scu.c
24
@@ -XXX,XX +XXX,XX @@
25
#define AST2600_CLK_STOP_CTRL TO_REG(0x80)
26
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
27
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
28
-#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94)
29
+#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94)
30
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
31
#define AST2600_HPLL_PARAM TO_REG(0x200)
32
#define AST2600_HPLL_EXT TO_REG(0x204)
33
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset,
34
return s->regs[reg];
35
}
36
37
-static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
38
- unsigned size)
39
+static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
40
+ uint64_t data64, unsigned size)
41
{
42
AspeedSCUState *s = ASPEED_SCU(opaque);
43
int reg = TO_REG(offset);
44
+ /* Truncate here so bitwise operations below behave as expected */
45
+ uint32_t data = data64;
46
47
if (reg >= ASPEED_AST2600_SCU_NR_REGS) {
48
qemu_log_mask(LOG_GUEST_ERROR,
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
50
/* fall through */
51
case AST2600_SYS_RST_CTRL:
52
case AST2600_SYS_RST_CTRL2:
53
+ case AST2600_CLK_STOP_CTRL:
54
+ case AST2600_CLK_STOP_CTRL2:
55
/* W1S (Write 1 to set) registers */
56
s->regs[reg] |= data;
57
return;
58
case AST2600_SYS_RST_CTRL_CLR:
59
case AST2600_SYS_RST_CTRL2_CLR:
60
+ case AST2600_CLK_STOP_CTRL_CLR:
61
+ case AST2600_CLK_STOP_CTRL2_CLR:
62
case AST2600_HW_STRAP1_CLR:
63
case AST2600_HW_STRAP2_CLR:
64
- /* W1C (Write 1 to clear) registers */
65
- s->regs[reg] &= ~data;
66
+ /*
67
+ * W1C (Write 1 to clear) registers are offset by one address from
68
+ * the data register
69
+ */
70
+ s->regs[reg - 1] &= ~data;
71
return;
72
73
case AST2600_RNG_DATA:
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
Users benefit from knowing which watchdog timer has expired. The address
4
of the watchdog's registers unambiguously indicates which has expired,
5
so log that.
6
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-9-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/watchdog/wdt_aspeed.c | 3 ++-
15
1 file changed, 2 insertions(+), 1 deletion(-)
16
17
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/watchdog/wdt_aspeed.c
20
+++ b/hw/watchdog/wdt_aspeed.c
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_timer_expired(void *dev)
22
return;
23
}
24
25
- qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
26
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
27
+ s->iomem.addr);
28
watchdog_perform_action();
29
timer_del(s->timer);
30
}
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
The segments can be disabled on the AST2600 (zero register value).
3
The driver already implements a receive FIFO, but it does not
4
CS0 is open by default but not the other CS. This is closing the
4
handle receive FIFO trigger levels and timeout. Implement the
5
access to the flash device in user mode and forbids scanning.
5
missing functionality.
6
6
7
In the model, check the segment size and disable the associated region
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
when the value is zero.
8
Message-id: 20200123052540.6132-7-linux@roeck-us.net
9
10
Fixes: bcaa8ddd081c ("aspeed/smc: Add AST2600 support")
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-12-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
---
11
---
17
hw/ssi/aspeed_smc.c | 16 +++++++++++-----
12
hw/char/exynos4210_uart.c | 117 ++++++++++++++++++++++++++++++--------
18
1 file changed, 11 insertions(+), 5 deletions(-)
13
hw/char/trace-events | 3 +-
19
14
2 files changed, 94 insertions(+), 26 deletions(-)
20
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
15
16
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/ssi/aspeed_smc.c
18
--- a/hw/char/exynos4210_uart.c
23
+++ b/hw/ssi/aspeed_smc.c
19
+++ b/hw/char/exynos4210_uart.c
24
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
20
@@ -XXX,XX +XXX,XX @@
25
uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
21
#include "migration/vmstate.h"
26
uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
22
#include "qemu/error-report.h"
27
23
#include "qemu/module.h"
28
- seg->addr = s->ctrl->flash_window_base + start_offset;
24
+#include "qemu/timer.h"
29
- seg->size = end_offset + MiB - start_offset;
25
#include "chardev/char-fe.h"
30
+ if (reg) {
26
#include "chardev/char-serial.h"
31
+ seg->addr = s->ctrl->flash_window_base + start_offset;
27
32
+ seg->size = end_offset + MiB - start_offset;
28
@@ -XXX,XX +XXX,XX @@ static const Exynos4210UartReg exynos4210_uart_regs[] = {
29
#define ULCON_STOP_BIT_SHIFT 1
30
31
/* UART Tx/Rx Status */
32
+#define UTRSTAT_Rx_TIMEOUT 0x8
33
#define UTRSTAT_TRANSMITTER_EMPTY 0x4
34
#define UTRSTAT_Tx_BUFFER_EMPTY 0x2
35
#define UTRSTAT_Rx_BUFFER_DATA_READY 0x1
36
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210UartState {
37
Exynos4210UartFIFO rx;
38
Exynos4210UartFIFO tx;
39
40
+ QEMUTimer *fifo_timeout_timer;
41
+ uint64_t wordtime; /* word time in ns */
42
+
43
CharBackend chr;
44
qemu_irq irq;
45
46
@@ -XXX,XX +XXX,XX @@ static void fifo_reset(Exynos4210UartFIFO *q)
47
q->rp = 0;
48
}
49
50
-static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s)
51
+static uint32_t exynos4210_uart_FIFO_trigger_level(uint32_t channel,
52
+ uint32_t reg)
53
{
54
- uint32_t level = 0;
55
- uint32_t reg;
56
+ uint32_t level;
57
58
- reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
59
- UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
60
-
61
- switch (s->channel) {
62
+ switch (channel) {
63
case 0:
64
level = reg * 32;
65
break;
66
@@ -XXX,XX +XXX,XX @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState
67
break;
68
default:
69
level = 0;
70
- trace_exynos_uart_channel_error(s->channel);
71
+ trace_exynos_uart_channel_error(channel);
72
+ break;
73
}
74
-
75
return level;
76
}
77
78
+static uint32_t
79
+exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s)
80
+{
81
+ uint32_t reg;
82
+
83
+ reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
84
+ UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
85
+
86
+ return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
87
+}
88
+
89
+static uint32_t
90
+exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s)
91
+{
92
+ uint32_t reg;
93
+
94
+ reg = ((s->reg[I_(UFCON)] & UFCON_Rx_FIFO_TRIGGER_LEVEL) >>
95
+ UFCON_Rx_FIFO_TRIGGER_LEVEL_SHIFT) + 1;
96
+
97
+ return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
98
+}
99
+
100
static void exynos4210_uart_update_irq(Exynos4210UartState *s)
101
{
102
/*
103
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
104
* transmit FIFO is smaller than the trigger level.
105
*/
106
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
107
-
108
uint32_t count = (s->reg[I_(UFSTAT)] & UFSTAT_Tx_FIFO_COUNT) >>
109
UFSTAT_Tx_FIFO_COUNT_SHIFT;
110
111
if (count <= exynos4210_uart_Tx_FIFO_trigger_level(s)) {
112
s->reg[I_(UINTSP)] |= UINTSP_TXD;
113
}
114
+
115
+ /*
116
+ * Rx interrupt if trigger level is reached or if rx timeout
117
+ * interrupt is disabled and there is data in the receive buffer
118
+ */
119
+ count = fifo_elements_number(&s->rx);
120
+ if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
121
+ count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
122
+ s->reg[I_(UINTSP)] |= UINTSP_RXD;
123
+ timer_del(s->fifo_timeout_timer);
124
+ }
125
+ } else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
126
+ s->reg[I_(UINTSP)] |= UINTSP_RXD;
127
}
128
129
s->reg[I_(UINTP)] = s->reg[I_(UINTSP)] & ~s->reg[I_(UINTM)];
130
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
131
}
132
}
133
134
+static void exynos4210_uart_timeout_int(void *opaque)
135
+{
136
+ Exynos4210UartState *s = opaque;
137
+
138
+ trace_exynos_uart_rx_timeout(s->channel, s->reg[I_(UTRSTAT)],
139
+ s->reg[I_(UINTSP)]);
140
+
141
+ if ((s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) ||
142
+ (s->reg[I_(UCON)] & (1 << 11))) {
143
+ s->reg[I_(UINTSP)] |= UINTSP_RXD;
144
+ s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
145
+ exynos4210_uart_update_irq(s);
146
+ }
147
+}
148
+
149
static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
150
{
151
int speed, parity, data_bits, stop_bits;
152
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
153
ssp.data_bits = data_bits;
154
ssp.stop_bits = stop_bits;
155
156
+ s->wordtime = NANOSECONDS_PER_SECOND * (data_bits + stop_bits + 1) / speed;
157
+
158
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
159
160
trace_exynos_uart_update_params(
161
- s->channel, speed, parity, data_bits, stop_bits);
162
+ s->channel, speed, parity, data_bits, stop_bits, s->wordtime);
163
+}
164
+
165
+static void exynos4210_uart_rx_timeout_set(Exynos4210UartState *s)
166
+{
167
+ if (s->reg[I_(UCON)] & 0x80) {
168
+ uint32_t timeout = ((s->reg[I_(UCON)] >> 12) & 0x0f) * s->wordtime;
169
+
170
+ timer_mod(s->fifo_timeout_timer,
171
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
33
+ } else {
172
+ } else {
34
+ seg->addr = s->ctrl->flash_window_base;
173
+ timer_del(s->fifo_timeout_timer);
35
+ seg->size = 0;
36
+ }
174
+ }
37
}
175
}
38
176
39
static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
177
static void exynos4210_uart_write(void *opaque, hwaddr offset,
40
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
178
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
41
memory_region_transaction_begin();
179
exynos4210_uart_update_irq(s);
42
memory_region_set_size(&fl->mmio, seg.size);
180
break;
43
memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
181
case UTRSTAT:
44
- memory_region_set_enabled(&fl->mmio, true);
182
+ if (val & UTRSTAT_Rx_TIMEOUT) {
45
+ memory_region_set_enabled(&fl->mmio, !!seg.size);
183
+ s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_TIMEOUT;
46
memory_region_transaction_commit();
184
+ }
47
185
+ break;
48
s->regs[R_SEG_ADDR0 + cs] = regval;
186
case UERSTAT:
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
187
case UFSTAT:
50
}
188
case UMSTAT:
51
189
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
52
/* Keep the segment in the overall flash window */
190
break;
53
- if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
191
}
54
- seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
192
}
55
+ if (seg.size &&
193
+
56
+ (seg.addr + seg.size <= s->ctrl->flash_window_base ||
194
static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
57
+ seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
195
unsigned size)
58
qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
196
{
59
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
197
@@ -XXX,XX +XXX,XX @@ static int exynos4210_uart_can_receive(void *opaque)
60
s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
198
return fifo_empty_elements_number(&s->rx);
199
}
200
201
-
202
static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size)
203
{
204
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
205
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size)
206
207
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
208
if (fifo_empty_elements_number(&s->rx) < size) {
209
- for (i = 0; i < fifo_empty_elements_number(&s->rx); i++) {
210
- fifo_store(&s->rx, buf[i]);
211
- }
212
+ size = fifo_empty_elements_number(&s->rx);
213
s->reg[I_(UINTSP)] |= UINTSP_ERROR;
214
- s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
215
- } else {
216
- for (i = 0; i < size; i++) {
217
- fifo_store(&s->rx, buf[i]);
218
- }
219
- s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
220
}
221
- /* XXX: Around here we maybe should check Rx trigger level */
222
- s->reg[I_(UINTSP)] |= UINTSP_RXD;
223
+ for (i = 0; i < size; i++) {
224
+ fifo_store(&s->rx, buf[i]);
225
+ }
226
+ exynos4210_uart_rx_timeout_set(s);
227
} else {
228
s->reg[I_(URXH)] = buf[0];
229
- s->reg[I_(UINTSP)] |= UINTSP_RXD;
230
- s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
231
}
232
+ s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
233
234
exynos4210_uart_update_irq(s);
235
}
236
@@ -XXX,XX +XXX,XX @@ static int exynos4210_uart_post_load(void *opaque, int version_id)
237
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
238
239
exynos4210_uart_update_parameters(s);
240
+ exynos4210_uart_rx_timeout_set(s);
241
242
return 0;
243
}
244
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_init(Object *obj)
245
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
246
Exynos4210UartState *s = EXYNOS4210_UART(dev);
247
248
+ s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
249
+ exynos4210_uart_timeout_int, s);
250
+ s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600;
251
+
252
/* memory mapping */
253
memory_region_init_io(&s->iomem, obj, &exynos4210_uart_ops, s,
254
"exynos4210.uart", EXYNOS4210_UART_REGS_MEM_SIZE);
255
diff --git a/hw/char/trace-events b/hw/char/trace-events
256
index XXXXXXX..XXXXXXX 100644
257
--- a/hw/char/trace-events
258
+++ b/hw/char/trace-events
259
@@ -XXX,XX +XXX,XX @@ nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PR
260
# exynos4210_uart.c
261
exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32
262
exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered"
263
-exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d"
264
+exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop, uint64_t wordtime) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d wordtime: %"PRId64"ns"
265
exynos_uart_write(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s <- 0x%" PRIx64
266
exynos_uart_read(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s -> 0x%" PRIx64
267
exynos_uart_rx_fifo_reset(uint32_t channel) "UART%d: Rx FIFO Reset"
268
@@ -XXX,XX +XXX,XX @@ exynos_uart_rx_error(uint32_t channel) "UART%d: Rx error"
269
exynos_uart_wo_read(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to read from WO register: %s [0x%04"PRIx32"]"
270
exynos_uart_rxsize(uint32_t channel, uint32_t size) "UART%d: Rx FIFO size: %d"
271
exynos_uart_channel_error(uint32_t channel) "Wrong UART channel number: %d"
272
+exynos_uart_rx_timeout(uint32_t channel, uint32_t stat, uint32_t intsp) "UART%d: Rx timeout stat=0x%x intsp=0x%x"
61
--
273
--
62
2.20.1
274
2.20.1
63
275
64
276
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
The AST2600 control register sneakily changed the meaning of bit 4
3
To support receive DMA, we need to inform the DMA controller if receive data
4
without anyone noticing. It no longer controls the 1MHz vs APB clock
4
is available. Otherwise the DMA controller keeps requesting data, causing
5
select, and instead always runs at 1MHz.
5
receive errors.
6
6
7
The AST2500 was always 1MHz too, but it retained bit 4, making it read
7
Implement this using an interrupt line. The instantiating code then needs
8
only. We can model both using the same fixed 1MHz calculation.
8
to connect the interrupt with the matching DMA controller GPIO pin.
9
9
10
Fixes: 6b2b2a703cad ("hw: wdt_aspeed: Add AST2600 support")
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
11
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20200123052540.6132-8-linux@roeck-us.net
13
Signed-off-by: Joel Stanley <joel@jms.id.au>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Message-id: 20191119141211.25716-10-clg@kaod.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
14
---
18
include/hw/watchdog/wdt_aspeed.h | 1 +
15
hw/char/exynos4210_uart.c | 24 ++++++++++++++++++++++++
19
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
16
hw/char/trace-events | 2 ++
20
2 files changed, 18 insertions(+), 4 deletions(-)
17
2 files changed, 26 insertions(+)
21
18
22
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
19
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
23
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/wdt_aspeed.h
21
--- a/hw/char/exynos4210_uart.c
25
+++ b/include/hw/watchdog/wdt_aspeed.h
22
+++ b/hw/char/exynos4210_uart.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTClass {
23
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210UartState {
27
uint32_t ext_pulse_width_mask;
24
28
uint32_t reset_ctrl_reg;
25
CharBackend chr;
29
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
26
qemu_irq irq;
30
+ void (*wdt_reload)(AspeedWDTState *s);
27
+ qemu_irq dmairq;
31
} AspeedWDTClass;
28
32
29
uint32_t channel;
33
#endif /* WDT_ASPEED_H */
30
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
31
@@ -XXX,XX +XXX,XX @@ exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s)
35
index XXXXXXX..XXXXXXX 100644
32
return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
36
--- a/hw/watchdog/wdt_aspeed.c
37
+++ b/hw/watchdog/wdt_aspeed.c
38
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
39
40
}
33
}
41
34
42
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
35
+/*
43
+static void aspeed_wdt_reload(AspeedWDTState *s)
36
+ * Update Rx DMA busy signal if Rx DMA is enabled. For simplicity,
44
{
37
+ * mark DMA as busy if DMA is enabled and the receive buffer is empty.
45
uint64_t reload;
38
+ */
46
39
+static void exynos4210_uart_update_dmabusy(Exynos4210UartState *s)
47
- if (pclk) {
48
+ if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
49
reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
50
s->pclk_freq);
51
} else {
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
53
}
54
}
55
56
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
57
+{
40
+{
58
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
41
+ bool rx_dma_enabled = (s->reg[I_(UCON)] & 0x03) == 0x02;
42
+ uint32_t count = fifo_elements_number(&s->rx);
59
+
43
+
60
+ if (aspeed_wdt_is_enabled(s)) {
44
+ if (rx_dma_enabled && !count) {
61
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
45
+ qemu_irq_raise(s->dmairq);
46
+ trace_exynos_uart_dmabusy(s->channel);
47
+ } else {
48
+ qemu_irq_lower(s->dmairq);
49
+ trace_exynos_uart_dmaready(s->channel);
62
+ }
50
+ }
63
+}
51
+}
64
+
52
+
65
+
53
static void exynos4210_uart_update_irq(Exynos4210UartState *s)
66
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
67
unsigned size)
68
{
54
{
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
55
/*
70
case WDT_RESTART:
56
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
71
if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
57
count = fifo_elements_number(&s->rx);
72
s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
58
if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
73
- aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK));
59
count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
74
+ awc->wdt_reload(s);
60
+ exynos4210_uart_update_dmabusy(s);
61
s->reg[I_(UINTSP)] |= UINTSP_RXD;
62
timer_del(s->fifo_timeout_timer);
75
}
63
}
76
break;
64
} else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
77
case WDT_CTRL:
65
+ exynos4210_uart_update_dmabusy(s);
78
if (enable && !aspeed_wdt_is_enabled(s)) {
66
s->reg[I_(UINTSP)] |= UINTSP_RXD;
79
s->regs[WDT_CTRL] = data;
67
}
80
- aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
68
81
+ awc->wdt_reload(s);
69
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_timeout_int(void *opaque)
82
} else if (!enable && aspeed_wdt_is_enabled(s)) {
70
(s->reg[I_(UCON)] & (1 << 11))) {
83
s->regs[WDT_CTRL] = data;
71
s->reg[I_(UINTSP)] |= UINTSP_RXD;
84
timer_del(s->timer);
72
s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
73
+ exynos4210_uart_update_dmabusy(s);
86
awc->offset = 0x20;
74
exynos4210_uart_update_irq(s);
87
awc->ext_pulse_width_mask = 0xff;
75
}
88
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
89
+ awc->wdt_reload = aspeed_wdt_reload;
90
}
76
}
91
77
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
92
static const TypeInfo aspeed_2400_wdt_info = {
78
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
79
res = s->reg[I_(URXH)];
94
awc->ext_pulse_width_mask = 0xfffff;
80
}
95
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
81
+ exynos4210_uart_update_dmabusy(s);
96
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
82
trace_exynos_uart_read(s->channel, offset,
97
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
83
exynos4210_uart_regname(offset), res);
84
return res;
85
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_init(Object *obj)
86
sysbus_init_mmio(dev, &s->iomem);
87
88
sysbus_init_irq(dev, &s->irq);
89
+ sysbus_init_irq(dev, &s->dmairq);
98
}
90
}
99
91
100
static const TypeInfo aspeed_2500_wdt_info = {
92
static void exynos4210_uart_realize(DeviceState *dev, Error **errp)
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
93
diff --git a/hw/char/trace-events b/hw/char/trace-events
102
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
94
index XXXXXXX..XXXXXXX 100644
103
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
95
--- a/hw/char/trace-events
104
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
96
+++ b/hw/char/trace-events
105
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
97
@@ -XXX,XX +XXX,XX @@ nrf51_uart_read(uint64_t addr, uint64_t r, unsigned int size) "addr 0x%" PRIx64
106
}
98
nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u"
107
99
108
static const TypeInfo aspeed_2600_wdt_info = {
100
# exynos4210_uart.c
101
+exynos_uart_dmabusy(uint32_t channel) "UART%d: DMA busy (Rx buffer empty)"
102
+exynos_uart_dmaready(uint32_t channel) "UART%d: DMA ready"
103
exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32
104
exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered"
105
exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop, uint64_t wordtime) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d wordtime: %"PRId64"ns"
109
--
106
--
110
2.20.1
107
2.20.1
111
108
112
109
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The current model only restores the Segment Register values but leaves
4
the previous CS mapping behind. Introduce a helper setting the
5
register value and mapping the region at the requested address. Use
6
this helper when a Segment register is set and at reset.
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-11-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/ssi/aspeed_smc.c | 32 +++++++++++++++++++++-----------
15
1 file changed, 21 insertions(+), 11 deletions(-)
16
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/ssi/aspeed_smc.c
20
+++ b/hw/ssi/aspeed_smc.c
21
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
22
return false;
23
}
24
25
+static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
26
+ uint64_t regval)
27
+{
28
+ AspeedSMCFlash *fl = &s->flashes[cs];
29
+ AspeedSegments seg;
30
+
31
+ s->ctrl->reg_to_segment(s, regval, &seg);
32
+
33
+ memory_region_transaction_begin();
34
+ memory_region_set_size(&fl->mmio, seg.size);
35
+ memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
36
+ memory_region_set_enabled(&fl->mmio, true);
37
+ memory_region_transaction_commit();
38
+
39
+ s->regs[R_SEG_ADDR0 + cs] = regval;
40
+}
41
+
42
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
43
uint64_t new)
44
{
45
- AspeedSMCFlash *fl = &s->flashes[cs];
46
AspeedSegments seg;
47
48
s->ctrl->reg_to_segment(s, new, &seg);
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
50
aspeed_smc_flash_overlap(s, &seg, cs);
51
52
/* All should be fine now to move the region */
53
- memory_region_transaction_begin();
54
- memory_region_set_size(&fl->mmio, seg.size);
55
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
56
- memory_region_set_enabled(&fl->mmio, true);
57
- memory_region_transaction_commit();
58
-
59
- s->regs[R_SEG_ADDR0 + cs] = new;
60
+ aspeed_smc_flash_set_segment_region(s, cs, new);
61
}
62
63
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
65
qemu_set_irq(s->cs_lines[i], true);
66
}
67
68
- /* setup default segment register values for all */
69
+ /* setup the default segment register values and regions for all */
70
for (i = 0; i < s->ctrl->max_slaves; ++i) {
71
- s->regs[R_SEG_ADDR0 + i] =
72
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
73
+ aspeed_smc_flash_set_segment_region(s, i,
74
+ s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
75
}
76
77
/* HW strapping flash type for the AST2600 controllers */
78
--
79
2.20.1
80
81
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
Each CS has its own Read Timing Compensation Register on newer SoCs.
4
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20191119141211.25716-13-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/ssi/aspeed_smc.h | 1 +
12
hw/ssi/aspeed_smc.c | 17 ++++++++++++++---
13
2 files changed, 15 insertions(+), 3 deletions(-)
14
15
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/aspeed_smc.h
18
+++ b/include/hw/ssi/aspeed_smc.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCController {
20
uint8_t r_ce_ctrl;
21
uint8_t r_ctrl0;
22
uint8_t r_timings;
23
+ uint8_t nregs_timings;
24
uint8_t conf_enable_w0;
25
uint8_t max_slaves;
26
const AspeedSegments *segments;
27
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/ssi/aspeed_smc.c
30
+++ b/hw/ssi/aspeed_smc.c
31
@@ -XXX,XX +XXX,XX @@
32
/* Checksum Calculation Result */
33
#define R_DMA_CHECKSUM (0x90 / 4)
34
35
-/* Misc Control Register #2 */
36
+/* Read Timing Compensation Register */
37
#define R_TIMINGS (0x94 / 4)
38
39
/* SPI controller registers and bits (AST2400) */
40
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
41
.r_ce_ctrl = R_CE_CTRL,
42
.r_ctrl0 = R_CTRL0,
43
.r_timings = R_TIMINGS,
44
+ .nregs_timings = 1,
45
.conf_enable_w0 = CONF_ENABLE_W0,
46
.max_slaves = 5,
47
.segments = aspeed_segments_legacy,
48
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
49
.r_ce_ctrl = R_CE_CTRL,
50
.r_ctrl0 = R_CTRL0,
51
.r_timings = R_TIMINGS,
52
+ .nregs_timings = 1,
53
.conf_enable_w0 = CONF_ENABLE_W0,
54
.max_slaves = 5,
55
.segments = aspeed_segments_fmc,
56
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
57
.r_ce_ctrl = 0xff,
58
.r_ctrl0 = R_SPI_CTRL0,
59
.r_timings = R_SPI_TIMINGS,
60
+ .nregs_timings = 1,
61
.conf_enable_w0 = SPI_CONF_ENABLE_W0,
62
.max_slaves = 1,
63
.segments = aspeed_segments_spi,
64
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
65
.r_ce_ctrl = R_CE_CTRL,
66
.r_ctrl0 = R_CTRL0,
67
.r_timings = R_TIMINGS,
68
+ .nregs_timings = 1,
69
.conf_enable_w0 = CONF_ENABLE_W0,
70
.max_slaves = 3,
71
.segments = aspeed_segments_ast2500_fmc,
72
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
73
.r_ce_ctrl = R_CE_CTRL,
74
.r_ctrl0 = R_CTRL0,
75
.r_timings = R_TIMINGS,
76
+ .nregs_timings = 1,
77
.conf_enable_w0 = CONF_ENABLE_W0,
78
.max_slaves = 2,
79
.segments = aspeed_segments_ast2500_spi1,
80
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
81
.r_ce_ctrl = R_CE_CTRL,
82
.r_ctrl0 = R_CTRL0,
83
.r_timings = R_TIMINGS,
84
+ .nregs_timings = 1,
85
.conf_enable_w0 = CONF_ENABLE_W0,
86
.max_slaves = 2,
87
.segments = aspeed_segments_ast2500_spi2,
88
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
89
.r_ce_ctrl = R_CE_CTRL,
90
.r_ctrl0 = R_CTRL0,
91
.r_timings = R_TIMINGS,
92
+ .nregs_timings = 1,
93
.conf_enable_w0 = CONF_ENABLE_W0,
94
.max_slaves = 3,
95
.segments = aspeed_segments_ast2600_fmc,
96
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
97
.r_ce_ctrl = R_CE_CTRL,
98
.r_ctrl0 = R_CTRL0,
99
.r_timings = R_TIMINGS,
100
+ .nregs_timings = 2,
101
.conf_enable_w0 = CONF_ENABLE_W0,
102
.max_slaves = 2,
103
.segments = aspeed_segments_ast2600_spi1,
104
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
105
.r_ce_ctrl = R_CE_CTRL,
106
.r_ctrl0 = R_CTRL0,
107
.r_timings = R_TIMINGS,
108
+ .nregs_timings = 3,
109
.conf_enable_w0 = CONF_ENABLE_W0,
110
.max_slaves = 3,
111
.segments = aspeed_segments_ast2600_spi2,
112
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
113
addr >>= 2;
114
115
if (addr == s->r_conf ||
116
- addr == s->r_timings ||
117
+ (addr >= s->r_timings &&
118
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
119
addr == s->r_ce_ctrl ||
120
addr == R_INTR_CTRL ||
121
addr == R_DUMMY_DATA ||
122
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
123
addr >>= 2;
124
125
if (addr == s->r_conf ||
126
- addr == s->r_timings ||
127
+ (addr >= s->r_timings &&
128
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
129
addr == s->r_ce_ctrl) {
130
s->regs[addr] = value;
131
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
132
--
133
2.20.1
134
135
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
AspeedBoardConfig is a redundant way to define class attributes and it
4
complexifies the machine definition and initialization.
5
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-14-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/aspeed.h | 24 ++--
13
hw/arm/aspeed.c | 243 ++++++++++++++++++++++------------------
14
2 files changed, 143 insertions(+), 124 deletions(-)
15
16
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed.h
19
+++ b/include/hw/arm/aspeed.h
20
@@ -XXX,XX +XXX,XX @@
21
22
typedef struct AspeedBoardState AspeedBoardState;
23
24
-typedef struct AspeedBoardConfig {
25
- const char *name;
26
- const char *desc;
27
- const char *soc_name;
28
- uint32_t hw_strap1;
29
- uint32_t hw_strap2;
30
- const char *fmc_model;
31
- const char *spi_model;
32
- uint32_t num_cs;
33
- void (*i2c_init)(AspeedBoardState *bmc);
34
- uint32_t ram;
35
-} AspeedBoardConfig;
36
-
37
#define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed")
38
#define ASPEED_MACHINE(obj) \
39
OBJECT_CHECK(AspeedMachine, (obj), TYPE_ASPEED_MACHINE)
40
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedMachine {
41
42
typedef struct AspeedMachineClass {
43
MachineClass parent_obj;
44
- const AspeedBoardConfig *board;
45
+
46
+ const char *name;
47
+ const char *desc;
48
+ const char *soc_name;
49
+ uint32_t hw_strap1;
50
+ uint32_t hw_strap2;
51
+ const char *fmc_model;
52
+ const char *spi_model;
53
+ uint32_t num_cs;
54
+ void (*i2c_init)(AspeedBoardState *bmc);
55
} AspeedMachineClass;
56
57
58
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/aspeed.c
61
+++ b/hw/arm/aspeed.c
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
63
}
64
}
65
66
-static void aspeed_board_init(MachineState *machine,
67
- const AspeedBoardConfig *cfg)
68
+static void aspeed_machine_init(MachineState *machine)
69
{
70
AspeedBoardState *bmc;
71
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
72
AspeedSoCClass *sc;
73
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
74
ram_addr_t max_ram_size;
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
76
UINT32_MAX);
77
78
object_initialize_child(OBJECT(machine), "soc", &bmc->soc,
79
- (sizeof(bmc->soc)), cfg->soc_name, &error_abort,
80
+ (sizeof(bmc->soc)), amc->soc_name, &error_abort,
81
NULL);
82
83
sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
84
85
object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size",
86
&error_abort);
87
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
88
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap1, "hw-strap1",
89
&error_abort);
90
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap2, "hw-strap2",
91
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap2, "hw-strap2",
92
&error_abort);
93
- object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
94
+ object_property_set_int(OBJECT(&bmc->soc), amc->num_cs, "num-cs",
95
&error_abort);
96
object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
97
&error_abort);
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
99
"max_ram", max_ram_size - ram_size);
100
memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram);
101
102
- aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
103
- aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
104
+ aspeed_board_init_flashes(&bmc->soc.fmc, amc->fmc_model, &error_abort);
105
+ aspeed_board_init_flashes(&bmc->soc.spi[0], amc->spi_model, &error_abort);
106
107
/* Install first FMC flash content as a boot rom. */
108
if (drive0) {
109
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
110
aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM];
111
aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
112
113
- if (cfg->i2c_init) {
114
- cfg->i2c_init(bmc);
115
+ if (amc->i2c_init) {
116
+ amc->i2c_init(bmc);
117
}
118
119
for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
120
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
121
0x60);
122
}
123
124
-static void aspeed_machine_init(MachineState *machine)
125
-{
126
- AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
127
-
128
- aspeed_board_init(machine, amc->board);
129
-}
130
-
131
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
132
{
133
MachineClass *mc = MACHINE_CLASS(oc);
134
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
135
- const AspeedBoardConfig *board = data;
136
137
- mc->desc = board->desc;
138
mc->init = aspeed_machine_init;
139
mc->max_cpus = ASPEED_CPUS_NUM;
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->no_parallel = 1;
143
- if (board->ram) {
144
- mc->default_ram_size = board->ram;
145
- }
146
- amc->board = board;
147
}
148
149
-static const TypeInfo aspeed_machine_type = {
150
- .name = TYPE_ASPEED_MACHINE,
151
- .parent = TYPE_MACHINE,
152
- .instance_size = sizeof(AspeedMachine),
153
- .class_size = sizeof(AspeedMachineClass),
154
- .abstract = true,
155
-};
156
-
157
-static const AspeedBoardConfig aspeed_boards[] = {
158
- {
159
- .name = MACHINE_TYPE_NAME("palmetto-bmc"),
160
- .desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)",
161
- .soc_name = "ast2400-a1",
162
- .hw_strap1 = PALMETTO_BMC_HW_STRAP1,
163
- .fmc_model = "n25q256a",
164
- .spi_model = "mx25l25635e",
165
- .num_cs = 1,
166
- .i2c_init = palmetto_bmc_i2c_init,
167
- .ram = 256 * MiB,
168
- }, {
169
- .name = MACHINE_TYPE_NAME("ast2500-evb"),
170
- .desc = "Aspeed AST2500 EVB (ARM1176)",
171
- .soc_name = "ast2500-a1",
172
- .hw_strap1 = AST2500_EVB_HW_STRAP1,
173
- .fmc_model = "w25q256",
174
- .spi_model = "mx25l25635e",
175
- .num_cs = 1,
176
- .i2c_init = ast2500_evb_i2c_init,
177
- .ram = 512 * MiB,
178
- }, {
179
- .name = MACHINE_TYPE_NAME("romulus-bmc"),
180
- .desc = "OpenPOWER Romulus BMC (ARM1176)",
181
- .soc_name = "ast2500-a1",
182
- .hw_strap1 = ROMULUS_BMC_HW_STRAP1,
183
- .fmc_model = "n25q256a",
184
- .spi_model = "mx66l1g45g",
185
- .num_cs = 2,
186
- .i2c_init = romulus_bmc_i2c_init,
187
- .ram = 512 * MiB,
188
- }, {
189
- .name = MACHINE_TYPE_NAME("swift-bmc"),
190
- .desc = "OpenPOWER Swift BMC (ARM1176)",
191
- .soc_name = "ast2500-a1",
192
- .hw_strap1 = SWIFT_BMC_HW_STRAP1,
193
- .fmc_model = "mx66l1g45g",
194
- .spi_model = "mx66l1g45g",
195
- .num_cs = 2,
196
- .i2c_init = swift_bmc_i2c_init,
197
- .ram = 512 * MiB,
198
- }, {
199
- .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
200
- .desc = "OpenPOWER Witherspoon BMC (ARM1176)",
201
- .soc_name = "ast2500-a1",
202
- .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1,
203
- .fmc_model = "mx25l25635e",
204
- .spi_model = "mx66l1g45g",
205
- .num_cs = 2,
206
- .i2c_init = witherspoon_bmc_i2c_init,
207
- .ram = 512 * MiB,
208
- }, {
209
- .name = MACHINE_TYPE_NAME("ast2600-evb"),
210
- .desc = "Aspeed AST2600 EVB (Cortex A7)",
211
- .soc_name = "ast2600-a0",
212
- .hw_strap1 = AST2600_EVB_HW_STRAP1,
213
- .hw_strap2 = AST2600_EVB_HW_STRAP2,
214
- .fmc_model = "w25q512jv",
215
- .spi_model = "mx66u51235f",
216
- .num_cs = 1,
217
- .i2c_init = ast2600_evb_i2c_init,
218
- .ram = 1 * GiB,
219
- },
220
-};
221
-
222
-static void aspeed_machine_types(void)
223
+static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
224
{
225
- int i;
226
+ MachineClass *mc = MACHINE_CLASS(oc);
227
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
228
229
- type_register_static(&aspeed_machine_type);
230
- for (i = 0; i < ARRAY_SIZE(aspeed_boards); ++i) {
231
- TypeInfo ti = {
232
- .name = aspeed_boards[i].name,
233
- .parent = TYPE_ASPEED_MACHINE,
234
- .class_init = aspeed_machine_class_init,
235
- .class_data = (void *)&aspeed_boards[i],
236
- };
237
- type_register(&ti);
238
+ mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
239
+ amc->soc_name = "ast2400-a1";
240
+ amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1;
241
+ amc->fmc_model = "n25q256a";
242
+ amc->spi_model = "mx25l25635e";
243
+ amc->num_cs = 1;
244
+ amc->i2c_init = palmetto_bmc_i2c_init;
245
+ mc->default_ram_size = 256 * MiB;
246
+};
247
+
248
+static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
249
+{
250
+ MachineClass *mc = MACHINE_CLASS(oc);
251
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
252
+
253
+ mc->desc = "Aspeed AST2500 EVB (ARM1176)";
254
+ amc->soc_name = "ast2500-a1";
255
+ amc->hw_strap1 = AST2500_EVB_HW_STRAP1;
256
+ amc->fmc_model = "w25q256";
257
+ amc->spi_model = "mx25l25635e";
258
+ amc->num_cs = 1;
259
+ amc->i2c_init = ast2500_evb_i2c_init;
260
+ mc->default_ram_size = 512 * MiB;
261
+};
262
+
263
+static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data)
264
+{
265
+ MachineClass *mc = MACHINE_CLASS(oc);
266
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
267
+
268
+ mc->desc = "OpenPOWER Romulus BMC (ARM1176)";
269
+ amc->soc_name = "ast2500-a1";
270
+ amc->hw_strap1 = ROMULUS_BMC_HW_STRAP1;
271
+ amc->fmc_model = "n25q256a";
272
+ amc->spi_model = "mx66l1g45g";
273
+ amc->num_cs = 2;
274
+ amc->i2c_init = romulus_bmc_i2c_init;
275
+ mc->default_ram_size = 512 * MiB;
276
+};
277
+
278
+static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
279
+{
280
+ MachineClass *mc = MACHINE_CLASS(oc);
281
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
282
+
283
+ mc->desc = "OpenPOWER Swift BMC (ARM1176)";
284
+ amc->soc_name = "ast2500-a1";
285
+ amc->hw_strap1 = SWIFT_BMC_HW_STRAP1;
286
+ amc->fmc_model = "mx66l1g45g";
287
+ amc->spi_model = "mx66l1g45g";
288
+ amc->num_cs = 2;
289
+ amc->i2c_init = swift_bmc_i2c_init;
290
+ mc->default_ram_size = 512 * MiB;
291
+};
292
+
293
+static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
294
+{
295
+ MachineClass *mc = MACHINE_CLASS(oc);
296
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
297
+
298
+ mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)";
299
+ amc->soc_name = "ast2500-a1";
300
+ amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1;
301
+ amc->fmc_model = "mx25l25635e";
302
+ amc->spi_model = "mx66l1g45g";
303
+ amc->num_cs = 2;
304
+ amc->i2c_init = witherspoon_bmc_i2c_init;
305
+ mc->default_ram_size = 512 * MiB;
306
+};
307
+
308
+static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
309
+{
310
+ MachineClass *mc = MACHINE_CLASS(oc);
311
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
312
+
313
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
314
+ amc->soc_name = "ast2600-a0";
315
+ amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
316
+ amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
317
+ amc->fmc_model = "w25q512jv";
318
+ amc->spi_model = "mx66u51235f";
319
+ amc->num_cs = 1;
320
+ amc->i2c_init = ast2600_evb_i2c_init;
321
+ mc->default_ram_size = 1 * GiB;
322
+};
323
+
324
+static const TypeInfo aspeed_machine_types[] = {
325
+ {
326
+ .name = MACHINE_TYPE_NAME("palmetto-bmc"),
327
+ .parent = TYPE_ASPEED_MACHINE,
328
+ .class_init = aspeed_machine_palmetto_class_init,
329
+ }, {
330
+ .name = MACHINE_TYPE_NAME("ast2500-evb"),
331
+ .parent = TYPE_ASPEED_MACHINE,
332
+ .class_init = aspeed_machine_ast2500_evb_class_init,
333
+ }, {
334
+ .name = MACHINE_TYPE_NAME("romulus-bmc"),
335
+ .parent = TYPE_ASPEED_MACHINE,
336
+ .class_init = aspeed_machine_romulus_class_init,
337
+ }, {
338
+ .name = MACHINE_TYPE_NAME("swift-bmc"),
339
+ .parent = TYPE_ASPEED_MACHINE,
340
+ .class_init = aspeed_machine_swift_class_init,
341
+ }, {
342
+ .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
343
+ .parent = TYPE_ASPEED_MACHINE,
344
+ .class_init = aspeed_machine_witherspoon_class_init,
345
+ }, {
346
+ .name = MACHINE_TYPE_NAME("ast2600-evb"),
347
+ .parent = TYPE_ASPEED_MACHINE,
348
+ .class_init = aspeed_machine_ast2600_evb_class_init,
349
+ }, {
350
+ .name = TYPE_ASPEED_MACHINE,
351
+ .parent = TYPE_MACHINE,
352
+ .instance_size = sizeof(AspeedMachine),
353
+ .class_size = sizeof(AspeedMachineClass),
354
+ .class_init = aspeed_machine_class_init,
355
+ .abstract = true,
356
}
357
-}
358
+};
359
360
-type_init(aspeed_machine_types)
361
+DEFINE_TYPES(aspeed_machine_types)
362
--
363
2.20.1
364
365
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The Tacoma BMC board is replacement board for the BMC of the OpenPOWER
4
Witherspoon system. It uses a AST2600 SoC instead of a AST2500 and the
5
I2C layout is the same as it controls the same main board. Used for HW
6
bringup.
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-15-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/aspeed.c | 28 ++++++++++++++++++++++++++++
15
1 file changed, 28 insertions(+)
16
17
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/aspeed.c
20
+++ b/hw/arm/aspeed.c
21
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
22
#define AST2600_EVB_HW_STRAP1 0x000000C0
23
#define AST2600_EVB_HW_STRAP2 0x00000003
24
25
+/* Tacoma hardware value */
26
+#define TACOMA_BMC_HW_STRAP1 0x00000000
27
+#define TACOMA_BMC_HW_STRAP2 0x00000000
28
+
29
/*
30
* The max ram region is for firmwares that scan the address space
31
* with load/store to guess how much RAM the SoC has.
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
33
AspeedSoCState *soc = &bmc->soc;
34
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
35
36
+ /* Bus 3: TODO bmp280@77 */
37
+ /* Bus 3: TODO max31785@52 */
38
+ /* Bus 3: TODO dps310@76 */
39
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
40
0x60);
41
42
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
43
eeprom_buf);
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
45
0x60);
46
+ /* Bus 11: TODO ucd90160@64 */
47
}
48
49
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
50
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
51
mc->default_ram_size = 1 * GiB;
52
};
53
54
+static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
55
+{
56
+ MachineClass *mc = MACHINE_CLASS(oc);
57
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
58
+
59
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
60
+ amc->soc_name = "ast2600-a0";
61
+ amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
62
+ amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
63
+ amc->fmc_model = "mx66l1g45g";
64
+ amc->spi_model = "mx66l1g45g";
65
+ amc->num_cs = 2;
66
+ amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */
67
+ mc->default_ram_size = 1 * GiB;
68
+};
69
+
70
static const TypeInfo aspeed_machine_types[] = {
71
{
72
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
73
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
74
.name = MACHINE_TYPE_NAME("ast2600-evb"),
75
.parent = TYPE_ASPEED_MACHINE,
76
.class_init = aspeed_machine_ast2600_evb_class_init,
77
+ }, {
78
+ .name = MACHINE_TYPE_NAME("tacoma-bmc"),
79
+ .parent = TYPE_ASPEED_MACHINE,
80
+ .class_init = aspeed_machine_tacoma_class_init,
81
}, {
82
.name = TYPE_ASPEED_MACHINE,
83
.parent = TYPE_MACHINE,
84
--
85
2.20.1
86
87
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The Aspeed Watchdog and Timer models have a link pointing to the SCU
4
controller model of the machine.
5
6
Change the "scu" property definition so that it explicitly sets the
7
pointer. The property isn't optional : not being able to set the link
8
is a bug and QEMU should rather abort than exit in this case.
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-17-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/aspeed_ast2600.c | 8 ++++----
18
hw/arm/aspeed_soc.c | 8 ++++----
19
hw/timer/aspeed_timer.c | 17 +++++++++--------
20
hw/watchdog/wdt_aspeed.c | 17 ++++++++---------
21
4 files changed, 25 insertions(+), 25 deletions(-)
22
23
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/aspeed_ast2600.c
26
+++ b/hw/arm/aspeed_ast2600.c
27
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
28
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
29
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
30
sizeof(s->timerctrl), typename);
31
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
32
- OBJECT(&s->scu), &error_abort);
33
34
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
35
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
38
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
39
sizeof(s->wdt[i]), typename);
40
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
41
- OBJECT(&s->scu), &error_abort);
42
}
43
44
for (i = 0; i < sc->macs_num; i++) {
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
aspeed_soc_get_irq(s, ASPEED_RTC));
47
48
/* Timer */
49
+ object_property_set_link(OBJECT(&s->timerctrl),
50
+ OBJECT(&s->scu), "scu", &error_abort);
51
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
52
if (err) {
53
error_propagate(errp, err);
54
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
55
for (i = 0; i < sc->wdts_num; i++) {
56
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
57
58
+ object_property_set_link(OBJECT(&s->wdt[i]),
59
+ OBJECT(&s->scu), "scu", &error_abort);
60
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
61
if (err) {
62
error_propagate(errp, err);
63
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/aspeed_soc.c
66
+++ b/hw/arm/aspeed_soc.c
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
68
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
69
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
70
sizeof(s->timerctrl), typename);
71
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
72
- OBJECT(&s->scu), &error_abort);
73
74
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
75
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
76
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
77
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
78
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
79
sizeof(s->wdt[i]), typename);
80
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
81
- OBJECT(&s->scu), &error_abort);
82
}
83
84
for (i = 0; i < sc->macs_num; i++) {
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
86
aspeed_soc_get_irq(s, ASPEED_RTC));
87
88
/* Timer */
89
+ object_property_set_link(OBJECT(&s->timerctrl),
90
+ OBJECT(&s->scu), "scu", &error_abort);
91
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
92
if (err) {
93
error_propagate(errp, err);
94
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
95
for (i = 0; i < sc->wdts_num; i++) {
96
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
97
98
+ object_property_set_link(OBJECT(&s->wdt[i]),
99
+ OBJECT(&s->scu), "scu", &error_abort);
100
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
101
if (err) {
102
error_propagate(errp, err);
103
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/timer/aspeed_timer.c
106
+++ b/hw/timer/aspeed_timer.c
107
@@ -XXX,XX +XXX,XX @@
108
#include "qemu/timer.h"
109
#include "qemu/log.h"
110
#include "qemu/module.h"
111
+#include "hw/qdev-properties.h"
112
#include "trace.h"
113
114
#define TIMER_NR_REGS 4
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
116
int i;
117
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
118
AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
119
- Object *obj;
120
- Error *err = NULL;
121
122
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
123
- if (!obj) {
124
- error_propagate_prepend(errp, err, "required link 'scu' not found: ");
125
- return;
126
- }
127
- s->scu = ASPEED_SCU(obj);
128
+ assert(s->scu);
129
130
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
131
aspeed_init_one_timer(s, i);
132
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_timer_state = {
133
}
134
};
135
136
+static Property aspeed_timer_properties[] = {
137
+ DEFINE_PROP_LINK("scu", AspeedTimerCtrlState, scu, TYPE_ASPEED_SCU,
138
+ AspeedSCUState *),
139
+ DEFINE_PROP_END_OF_LIST(),
140
+};
141
+
142
static void timer_class_init(ObjectClass *klass, void *data)
143
{
144
DeviceClass *dc = DEVICE_CLASS(klass);
145
@@ -XXX,XX +XXX,XX @@ static void timer_class_init(ObjectClass *klass, void *data)
146
dc->reset = aspeed_timer_reset;
147
dc->desc = "ASPEED Timer";
148
dc->vmsd = &vmstate_aspeed_timer_state;
149
+ dc->props = aspeed_timer_properties;
150
}
151
152
static const TypeInfo aspeed_timer_info = {
153
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/watchdog/wdt_aspeed.c
156
+++ b/hw/watchdog/wdt_aspeed.c
157
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
158
{
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
160
AspeedWDTState *s = ASPEED_WDT(dev);
161
- Error *err = NULL;
162
- Object *obj;
163
164
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
165
- if (!obj) {
166
- error_propagate(errp, err);
167
- error_prepend(errp, "required link 'scu' not found: ");
168
- return;
169
- }
170
- s->scu = ASPEED_SCU(obj);
171
+ assert(s->scu);
172
173
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
174
175
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
176
sysbus_init_mmio(sbd, &s->iomem);
177
}
178
179
+static Property aspeed_wdt_properties[] = {
180
+ DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
181
+ AspeedSCUState *),
182
+ DEFINE_PROP_END_OF_LIST(),
183
+};
184
+
185
static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
186
{
187
DeviceClass *dc = DEVICE_CLASS(klass);
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
189
dc->reset = aspeed_wdt_reset;
190
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
191
dc->vmsd = &vmstate_aspeed_wdt;
192
+ dc->props = aspeed_wdt_properties;
193
}
194
195
static const TypeInfo aspeed_wdt_info = {
196
--
197
2.20.1
198
199
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The Aspeed MII model has a link pointing to its associated FTGMAC100
4
NIC in the machine.
5
6
Change the "nic" property definition so that it explicitly sets the
7
pointer. The property isn't optional : not being able to set the link
8
is a bug and QEMU should rather abort than exit in this case.
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-18-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/aspeed_ast2600.c | 5 ++---
18
hw/net/ftgmac100.c | 19 +++++++++----------
19
2 files changed, 11 insertions(+), 13 deletions(-)
20
21
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/aspeed_ast2600.c
24
+++ b/hw/arm/aspeed_ast2600.c
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
26
27
sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]),
28
TYPE_ASPEED_MII);
29
- object_property_add_const_link(OBJECT(&s->mii[i]), "nic",
30
- OBJECT(&s->ftgmac100[i]),
31
- &error_abort);
32
}
33
34
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
35
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
36
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
37
aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
38
39
+ object_property_set_link(OBJECT(&s->mii[i]), OBJECT(&s->ftgmac100[i]),
40
+ "nic", &error_abort);
41
object_property_set_bool(OBJECT(&s->mii[i]), true, "realized",
42
&err);
43
if (err) {
44
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/net/ftgmac100.c
47
+++ b/hw/net/ftgmac100.c
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_realize(DeviceState *dev, Error **errp)
49
{
50
AspeedMiiState *s = ASPEED_MII(dev);
51
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
52
- Object *obj;
53
- Error *local_err = NULL;
54
55
- obj = object_property_get_link(OBJECT(dev), "nic", &local_err);
56
- if (!obj) {
57
- error_propagate(errp, local_err);
58
- error_prepend(errp, "required link 'nic' not found: ");
59
- return;
60
- }
61
-
62
- s->nic = FTGMAC100(obj);
63
+ assert(s->nic);
64
65
memory_region_init_io(&s->iomem, OBJECT(dev), &aspeed_mii_ops, s,
66
TYPE_ASPEED_MII, 0x8);
67
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_mii = {
68
VMSTATE_END_OF_LIST()
69
}
70
};
71
+
72
+static Property aspeed_mii_properties[] = {
73
+ DEFINE_PROP_LINK("nic", AspeedMiiState, nic, TYPE_FTGMAC100,
74
+ FTGMAC100State *),
75
+ DEFINE_PROP_END_OF_LIST(),
76
+};
77
+
78
static void aspeed_mii_class_init(ObjectClass *klass, void *data)
79
{
80
DeviceClass *dc = DEVICE_CLASS(klass);
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_class_init(ObjectClass *klass, void *data)
82
dc->reset = aspeed_mii_reset;
83
dc->realize = aspeed_mii_realize;
84
dc->desc = "Aspeed MII controller";
85
+ dc->props = aspeed_mii_properties;
86
}
87
88
static const TypeInfo aspeed_mii_info = {
89
--
90
2.20.1
91
92
diff view generated by jsdifflib
Deleted patch
1
From: Marc Zyngier <maz@kernel.org>
2
1
3
HCR_EL2.TID2 mandates that access from EL1 to CTR_EL0, CCSIDR_EL1,
4
CCSIDR2_EL1, CLIDR_EL1, CSSELR_EL1 are trapped to EL2, and QEMU
5
completely ignores it, making it impossible for hypervisors to
6
virtualize the cache hierarchy.
7
8
Do the right thing by trapping to EL2 if HCR_EL2.TID2 is set.
9
10
Signed-off-by: Marc Zyngier <maz@kernel.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20191201122018.25808-2-maz@kernel.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
17
1 file changed, 27 insertions(+), 4 deletions(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
24
raw_write(env, ri, value);
25
}
26
27
+static CPAccessResult access_aa64_tid2(CPUARMState *env,
28
+ const ARMCPRegInfo *ri,
29
+ bool isread)
30
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
34
+
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
39
{
40
ARMCPU *cpu = env_archcpu(env);
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
42
.writefn = pmintenclr_write },
43
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
44
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
45
- .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
46
+ .access = PL1_R,
47
+ .accessfn = access_aa64_tid2,
48
+ .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
49
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
51
- .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
52
+ .access = PL1_RW,
53
+ .accessfn = access_aa64_tid2,
54
+ .writefn = csselr_write, .resetvalue = 0,
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
56
offsetof(CPUARMState, cp15.csselr_ns) } },
57
/* Auxiliary ID register: this actually has an IMPDEF value but for now
58
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
59
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
60
return CP_ACCESS_TRAP;
61
}
62
+
63
+ if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
64
+ return CP_ACCESS_TRAP_EL2;
65
+ }
66
+
67
return CP_ACCESS_OK;
68
}
69
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
71
ARMCPRegInfo clidr = {
72
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
73
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
74
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
75
+ .access = PL1_R, .type = ARM_CP_CONST,
76
+ .accessfn = access_aa64_tid2,
77
+ .resetvalue = cpu->clidr
78
};
79
define_one_arm_cp_reg(cpu, &clidr);
80
define_arm_cp_regs(cpu, v7_cp_reginfo);
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
82
/* These are common to v8 and pre-v8 */
83
{ .name = "CTR",
84
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
85
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
86
+ .access = PL1_R, .accessfn = ctr_el0_access,
87
+ .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
88
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
89
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
90
.access = PL0_R, .accessfn = ctr_el0_access,
91
--
92
2.20.1
93
94
diff view generated by jsdifflib
Deleted patch
1
From: Marc Zyngier <maz@kernel.org>
2
1
3
HCR_EL2.TID3 requires that AArch32 reads of MVFR[012] are trapped to
4
EL2, and HCR_EL2.TID0 does the same for reads of FPSID.
5
In order to handle this, introduce a new TCG helper function that
6
checks for these control bits before executing the VMRC instruction.
7
8
Tested with a hacked-up version of KVM/arm64 that sets the control
9
bits for 32bit guests.
10
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-4-maz@kernel.org
15
[PMM: move helper declaration to helper.h; make it
16
TCG_CALL_NO_WG]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
target/arm/helper.h | 2 ++
20
target/arm/translate-vfp.inc.c | 20 ++++++++++++++++----
21
target/arm/vfp_helper.c | 29 +++++++++++++++++++++++++++++
22
3 files changed, 47 insertions(+), 4 deletions(-)
23
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
27
+++ b/target/arm/helper.h
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
29
DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
30
DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
31
32
+DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
33
+
34
/* neon_helper.c */
35
DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
36
DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
37
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-vfp.inc.c
40
+++ b/target/arm/translate-vfp.inc.c
41
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
42
if (a->l) {
43
/* VMRS, move VFP special register to gp register */
44
switch (a->reg) {
45
- case ARM_VFP_FPSID:
46
- case ARM_VFP_FPEXC:
47
- case ARM_VFP_FPINST:
48
- case ARM_VFP_FPINST2:
49
case ARM_VFP_MVFR0:
50
case ARM_VFP_MVFR1:
51
case ARM_VFP_MVFR2:
52
+ case ARM_VFP_FPSID:
53
+ if (s->current_el == 1) {
54
+ TCGv_i32 tcg_reg, tcg_rt;
55
+
56
+ gen_set_condexec(s);
57
+ gen_set_pc_im(s, s->pc_curr);
58
+ tcg_reg = tcg_const_i32(a->reg);
59
+ tcg_rt = tcg_const_i32(a->rt);
60
+ gen_helper_check_hcr_el2_trap(cpu_env, tcg_rt, tcg_reg);
61
+ tcg_temp_free_i32(tcg_reg);
62
+ tcg_temp_free_i32(tcg_rt);
63
+ }
64
+ /* fall through */
65
+ case ARM_VFP_FPEXC:
66
+ case ARM_VFP_FPINST:
67
+ case ARM_VFP_FPINST2:
68
tmp = load_cpu_field(vfp.xregs[a->reg]);
69
break;
70
case ARM_VFP_FPSCR:
71
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/vfp_helper.c
74
+++ b/target/arm/vfp_helper.c
75
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frint64_d)(float64 f, void *fpst)
76
return frint_d(f, fpst, 64);
77
}
78
79
+void HELPER(check_hcr_el2_trap)(CPUARMState *env, uint32_t rt, uint32_t reg)
80
+{
81
+ uint32_t syndrome;
82
+
83
+ switch (reg) {
84
+ case ARM_VFP_MVFR0:
85
+ case ARM_VFP_MVFR1:
86
+ case ARM_VFP_MVFR2:
87
+ if (!(arm_hcr_el2_eff(env) & HCR_TID3)) {
88
+ return;
89
+ }
90
+ break;
91
+ case ARM_VFP_FPSID:
92
+ if (!(arm_hcr_el2_eff(env) & HCR_TID0)) {
93
+ return;
94
+ }
95
+ break;
96
+ default:
97
+ g_assert_not_reached();
98
+ }
99
+
100
+ syndrome = ((EC_FPIDTRAP << ARM_EL_EC_SHIFT)
101
+ | ARM_EL_IL
102
+ | (1 << 24) | (0xe << 20) | (7 << 14)
103
+ | (reg << 10) | (rt << 5) | 1);
104
+
105
+ raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
106
+}
107
+
108
#endif
109
--
110
2.20.1
111
112
diff view generated by jsdifflib
Deleted patch
1
From: Marc Zyngier <maz@kernel.org>
2
1
3
QEMU lacks the minimum Jazelle implementation that is required
4
by the architecture (everything is RAZ or RAZ/WI). Add it
5
together with the HCR_EL2.TID0 trapping that goes with it.
6
7
Signed-off-by: Marc Zyngier <maz@kernel.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20191201122018.25808-6-maz@kernel.org
11
[PMM: moved ARMCPRegInfo array to file scope, marked it
12
'static global', moved new condition down in
13
register_cp_regs_for_features() to go with other feature
14
things rather than up with the v6/v7/v8 stuff]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.c | 27 +++++++++++++++++++++++++++
18
1 file changed, 27 insertions(+)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
25
return CP_ACCESS_OK;
26
}
27
28
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
29
+ bool isread)
30
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
34
+
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
+static const ARMCPRegInfo jazelle_regs[] = {
39
+ { .name = "JIDR",
40
+ .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
41
+ .access = PL1_R, .accessfn = access_jazelle,
42
+ .type = ARM_CP_CONST, .resetvalue = 0 },
43
+ { .name = "JOSCR",
44
+ .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
45
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
46
+ { .name = "JMCR",
47
+ .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
48
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
+ REGINFO_SENTINEL
50
+};
51
+
52
void register_cp_regs_for_features(ARMCPU *cpu)
53
{
54
/* Register all the coprocessor registers based on feature bits */
55
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
56
if (arm_feature(env, ARM_FEATURE_LPAE)) {
57
define_arm_cp_regs(cpu, lpae_cp_reginfo);
58
}
59
+ if (cpu_isar_feature(jazelle, cpu)) {
60
+ define_arm_cp_regs(cpu, jazelle_regs);
61
+ }
62
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
63
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
64
* be read-only (ie write causes UNDEF exception).
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
The Exynos4210 serial driver uses an interrupt line to signal if receive
4
an array of qemu_irq and passing it around, directly call
4
data is available. Connect that interrupt with the DMA controller's
5
qdev_get_gpio_in() on the gic field.
5
'peripheral busy' gpio pin to stop the DMA if there is no more receive
6
data available. Without this patch, receive DMA runs wild and fills the
7
entire receive DMA buffer with invalid data.
6
8
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20191206162303.30338-1-philmd@redhat.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
11
Message-id: 20200123052540.6132-9-linux@roeck-us.net
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/arm/sbsa-ref.c | 86 +++++++++++++++++++++++------------------------
14
hw/arm/exynos4210.c | 42 +++++++++++++++++++++++++++++-------------
13
1 file changed, 42 insertions(+), 44 deletions(-)
15
1 file changed, 29 insertions(+), 13 deletions(-)
14
16
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
17
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
19
--- a/hw/arm/exynos4210.c
18
+++ b/hw/arm/sbsa-ref.c
20
+++ b/hw/arm/exynos4210.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
21
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_calc_affinity(int cpu)
20
void *fdt;
22
return (0x9 << ARM_AFF1_SHIFT) | cpu;
21
int fdt_size;
22
int psci_conduit;
23
+ DeviceState *gic;
24
PFlashCFI01 *flash[2];
25
} SBSAMachineState;
26
27
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
28
memory_region_add_subregion(secure_sysmem, base, secram);
29
}
23
}
30
24
31
-static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
25
-static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
32
+static void create_gic(SBSAMachineState *sms)
26
- int nreq, int nevents, int width)
27
+static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
28
+ qemu_irq irq, int nreq, int nevents, int width)
33
{
29
{
34
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
30
SysBusDevice *busdev;
35
- DeviceState *gicdev;
31
DeviceState *dev;
36
SysBusDevice *gicbusdev;
32
@@ -XXX,XX +XXX,XX @@ static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
37
const char *gictype;
33
sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
38
uint32_t redist0_capacity, redist0_count;
39
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
40
41
gictype = gicv3_class_name();
42
43
- gicdev = qdev_create(NULL, gictype);
44
- qdev_prop_set_uint32(gicdev, "revision", 3);
45
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
46
+ sms->gic = qdev_create(NULL, gictype);
47
+ qdev_prop_set_uint32(sms->gic, "revision", 3);
48
+ qdev_prop_set_uint32(sms->gic, "num-cpu", smp_cpus);
49
/*
50
* Note that the num-irq property counts both internal and external
51
* interrupts; there are always 32 of the former (mandated by GIC spec).
52
*/
53
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
54
- qdev_prop_set_bit(gicdev, "has-security-extensions", true);
55
+ qdev_prop_set_uint32(sms->gic, "num-irq", NUM_IRQS + 32);
56
+ qdev_prop_set_bit(sms->gic, "has-security-extensions", true);
57
58
redist0_capacity =
59
sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
60
redist0_count = MIN(smp_cpus, redist0_capacity);
61
62
- qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
63
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
64
+ qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
65
+ qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
66
67
- qdev_init_nofail(gicdev);
68
- gicbusdev = SYS_BUS_DEVICE(gicdev);
69
+ qdev_init_nofail(sms->gic);
70
+ gicbusdev = SYS_BUS_DEVICE(sms->gic);
71
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
72
sysbus_mmio_map(gicbusdev, 1, sbsa_ref_memmap[SBSA_GIC_REDIST].base);
73
74
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
75
76
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
77
qdev_connect_gpio_out(cpudev, irq,
78
- qdev_get_gpio_in(gicdev,
79
+ qdev_get_gpio_in(sms->gic,
80
ppibase + timer_irq[irq]));
81
}
82
83
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
84
- qdev_get_gpio_in(gicdev, ppibase
85
+ qdev_get_gpio_in(sms->gic, ppibase
86
+ ARCH_GIC_MAINT_IRQ));
87
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
88
- qdev_get_gpio_in(gicdev, ppibase
89
+ qdev_get_gpio_in(sms->gic, ppibase
90
+ VIRTUAL_PMU_IRQ));
91
92
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
93
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
94
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
95
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
96
}
34
}
97
-
35
qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
98
- for (i = 0; i < NUM_IRQS; i++) {
36
+ return dev;
99
- pic[i] = qdev_get_gpio_in(gicdev, i);
100
- }
101
}
37
}
102
38
103
-static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
39
static void exynos4210_realize(DeviceState *socdev, Error **errp)
104
+static void create_uart(const SBSAMachineState *sms, int uart,
40
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
MemoryRegion *mem, Chardev *chr)
41
MemoryRegion *system_mem = get_system_memory();
106
{
42
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
107
hwaddr base = sbsa_ref_memmap[uart].base;
43
SysBusDevice *busdev;
108
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
44
- DeviceState *dev;
109
qdev_init_nofail(dev);
45
+ DeviceState *dev, *uart[4], *pl330[3];
110
memory_region_add_subregion(mem, base,
46
int i, n;
111
sysbus_mmio_get_region(s, 0));
47
112
- sysbus_connect_irq(s, 0, pic[irq]);
48
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
113
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(sms->gic, irq));
49
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
50
51
52
/*** UARTs ***/
53
- exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
54
+ uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
55
EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
56
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
57
58
- exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
59
+ uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
60
EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
61
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
62
63
- exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
64
+ uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
65
EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
66
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
67
68
- exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
69
+ uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
70
EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
71
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
72
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
74
s->irq_table[exynos4210_get_irq(28, 3)]);
75
76
/*** DMA controllers ***/
77
- pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0],
78
- s->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32);
79
- pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1],
80
- s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32);
81
- pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2],
82
- s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64);
83
+ pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
84
+ &s->pl330_irq_orgate[0],
85
+ s->irq_table[exynos4210_get_irq(21, 0)],
86
+ 32, 32, 32);
87
+ pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
88
+ &s->pl330_irq_orgate[1],
89
+ s->irq_table[exynos4210_get_irq(21, 1)],
90
+ 32, 32, 32);
91
+ pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
92
+ &s->pl330_irq_orgate[2],
93
+ s->irq_table[exynos4210_get_irq(20, 1)],
94
+ 1, 31, 64);
95
+
96
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
97
+ qdev_get_gpio_in(pl330[0], 15));
98
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1,
99
+ qdev_get_gpio_in(pl330[1], 15));
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1,
101
+ qdev_get_gpio_in(pl330[0], 17));
102
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1,
103
+ qdev_get_gpio_in(pl330[1], 17));
114
}
104
}
115
105
116
-static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
106
static void exynos4210_init(Object *obj)
117
+static void create_rtc(const SBSAMachineState *sms)
118
{
119
hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
120
int irq = sbsa_ref_irqmap[SBSA_RTC];
121
122
- sysbus_create_simple("pl031", base, pic[irq]);
123
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(sms->gic, irq));
124
}
125
126
static DeviceState *gpio_key_dev;
127
@@ -XXX,XX +XXX,XX @@ static Notifier sbsa_ref_powerdown_notifier = {
128
.notify = sbsa_ref_powerdown_req
129
};
130
131
-static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
132
+static void create_gpio(const SBSAMachineState *sms)
133
{
134
DeviceState *pl061_dev;
135
hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
136
int irq = sbsa_ref_irqmap[SBSA_GPIO];
137
138
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
139
+ pl061_dev = sysbus_create_simple("pl061", base,
140
+ qdev_get_gpio_in(sms->gic, irq));
141
142
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
143
qdev_get_gpio_in(pl061_dev, 3));
144
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
145
qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
146
}
147
148
-static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
149
+static void create_ahci(const SBSAMachineState *sms)
150
{
151
hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
152
int irq = sbsa_ref_irqmap[SBSA_AHCI];
153
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
154
qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
155
qdev_init_nofail(dev);
156
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
157
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
158
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
159
160
sysahci = SYSBUS_AHCI(dev);
161
ahci = &sysahci->ahci;
162
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
163
}
164
}
165
166
-static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
167
+static void create_ehci(const SBSAMachineState *sms)
168
{
169
hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
170
int irq = sbsa_ref_irqmap[SBSA_EHCI];
171
172
- sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
173
+ sysbus_create_simple("platform-ehci-usb", base,
174
+ qdev_get_gpio_in(sms->gic, irq));
175
}
176
177
-static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
178
- PCIBus *bus)
179
+static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
180
{
181
hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
182
int irq = sbsa_ref_irqmap[SBSA_SMMU];
183
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
184
qdev_init_nofail(dev);
185
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
186
for (i = 0; i < NUM_SMMU_IRQS; i++) {
187
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
188
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
189
+ qdev_get_gpio_in(sms->gic, irq + 1));
190
}
191
}
192
193
-static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
194
+static void create_pcie(SBSAMachineState *sms)
195
{
196
hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
197
hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
198
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
199
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
200
201
for (i = 0; i < GPEX_NUM_IRQS; i++) {
202
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
203
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
204
+ qdev_get_gpio_in(sms->gic, irq + 1));
205
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
206
}
207
208
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
209
210
pci_create_simple(pci->bus, -1, "VGA");
211
212
- create_smmu(sms, pic, pci->bus);
213
+ create_smmu(sms, pci->bus);
214
}
215
216
static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
217
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
218
bool firmware_loaded;
219
const CPUArchIdList *possible_cpus;
220
int n, sbsa_max_cpus;
221
- qemu_irq pic[NUM_IRQS];
222
223
if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
224
error_report("sbsa-ref: CPU type other than the built-in "
225
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
226
227
create_secure_ram(sms, secure_sysmem);
228
229
- create_gic(sms, pic);
230
+ create_gic(sms);
231
232
- create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
233
- create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
234
+ create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
235
+ create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
236
/* Second secure UART for RAS and MM from EL0 */
237
- create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
238
+ create_uart(sms, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
239
240
- create_rtc(sms, pic);
241
+ create_rtc(sms);
242
243
- create_gpio(sms, pic);
244
+ create_gpio(sms);
245
246
- create_ahci(sms, pic);
247
+ create_ahci(sms);
248
249
- create_ehci(sms, pic);
250
+ create_ehci(sms);
251
252
- create_pcie(sms, pic);
253
+ create_pcie(sms);
254
255
sms->bootinfo.ram_size = machine->ram_size;
256
sms->bootinfo.nb_cpus = smp_cpus;
257
--
107
--
258
2.20.1
108
2.20.1
259
109
260
110
diff view generated by jsdifflib