...
...
31
hosts only because ParavirtualizedGraphics.framework is a black box
31
hosts only because ParavirtualizedGraphics.framework is a black box
32
implementing most of the logic behind the apple-gfx device.)
32
implementing most of the logic behind the apple-gfx device.)
33
* PCI devices use legacy IRQs, not MSI/MSI-X. As far as I can tell,
33
* PCI devices use legacy IRQs, not MSI/MSI-X. As far as I can tell,
34
we'd need to include the GICv3 ITS, but it's unclear to me what
34
we'd need to include the GICv3 ITS, but it's unclear to me what
35
exactly needs wiring up.
35
exactly needs wiring up.
36
* Due to lack of MSI(-X), event delivery from USB devices to the guest
36
* Due to a quirk (bug?) in the macOS XHCI driver when MSI-X is not
37
macOS isn't working correctly. My current conclusion is that the
37
available, correct functioning of the USB controller (and thus
38
OS's XHCI driver simply was never designed to work with legacy IRQs.
38
keyboard/tablet) requires a small workaround in the XHCI controller
39
The upshot is that keyboard and mouse/tablet input is very laggy.
39
device. This is part of another patch series:
40
The solution would be to implement MSI(-X) support or figure out how
40
https://patchew.org/QEMU/20241208191646.64857-1-phil@philjordan.eu/
41
to make hcd-xhci-sysbus work with the macOS guest, if at all possible.
42
(EHCI and UHCI/OHCI controllers are not an option as the VMAPPLE
43
guest kernel does not include drivers for these.)
44
* The guest OS must first be provisioned using Virtualization.framework;
41
* The guest OS must first be provisioned using Virtualization.framework;
45
the disk images can subsequently be used in Qemu. (See docs.)
42
the disk images can subsequently be used in Qemu. (See docs.)
46
43
47
The apple-gfx device can be used independently from the vmapple machine
44
The apple-gfx device can be used independently from the vmapple machine
48
type, at least in the PCI variant. It mainly targets x86-64 macOS guests
45
type, at least in the PCI variant. It mainly targets x86-64 macOS guests
...
...
69
CPU-based drawing. For maximum efficiency, the Metal texture
66
CPU-based drawing. For maximum efficiency, the Metal texture
70
containing the guest framebuffer could be drawn directly to
67
containing the guest framebuffer could be drawn directly to
71
a Metal view in the host window, staying on the GPU. (Similar
68
a Metal view in the host window, staying on the GPU. (Similar
72
to the OpenGL/virgl render path on other platforms.)
69
to the OpenGL/virgl render path on other platforms.)
73
70
74
My part of this work has been sponsored by Sauce Labs Inc.
71
Some of my part of this work has been sponsored by Sauce Labs Inc.
75
72
76
---
73
---
77
74
78
v2 -> v3:
75
v2 -> v3:
79
76
...
...
157
* 10/15 (vmapple/aes): Coding style tweaks.
154
* 10/15 (vmapple/aes): Coding style tweaks.
158
* 12/15 (vmapple/cfg): Changed error messages for overrun of properties with
155
* 12/15 (vmapple/cfg): Changed error messages for overrun of properties with
159
fixed-length strings to be more useful to users than developers.
156
fixed-length strings to be more useful to users than developers.
160
* 15/15 (vmapple machine type): Tiny error handling fix, un-inlined function
157
* 15/15 (vmapple machine type): Tiny error handling fix, un-inlined function
161
158
159
v7 -> v8:
160
161
* 02/15 (apple-gfx): Naming and type use improvements, fixes for a bug and a
162
leak.
163
* 04/15 (apple-gfx display mode property): Type use improvement
164
* 10/15 (vmapple/aes): Guest error logging tweaks.
165
* 11/15 (vmapple/bdif): Replaced uses of cpu_physical_memory_read with
166
dma_memory_read, and a g_free call with g_autofree.
167
* 12/15 (vmapple/cfg): Macro hygiene fix: consistently enclosing arguments in
168
parens.
169
* 15/15 (vmapple machine type): Use less verbose pattern for defining uuid
170
property.
171
172
v8 -> v9:
173
174
* 01/16 (ui & main loop): Set qemu_main to NULL for GTK UI as well.
175
* 02/16 (apple-gfx): Pass device pointer to graphic_console_init(), various
176
     non-functional changes.
177
* 03/16 (apple-gfx-pci): Fixup of changed common call, whitespace and comment
178
formatting tweaks.
179
* 04/16 (apple-gfx display modes): Re-ordered type definitions so we can drop
180
a 'struct' keyword.
181
* 10/16 (vmapple/aes): Replaced a use of cpu_physical_memory_write with
182
dma_memory_write, minor style tweak.
183
* 11/16 (vmapple/bdif): Replaced uses of cpu_physical_memory_write with
184
dma_memory_write.
185
* 13/16 (vmapple/virtio-blk): Correctly specify class_size for
186
VMAppleVirtIOBlkClass.
187
* 15/16 (vmapple machine type): Documentation improvements, fixed variable
188
name and struct field used during pvpanic device creation.
189
* 16/16 (NEW/RFC vmapple/virtio-blk): Proposed change to replace type hierarchy
190
with a variant property. This seems cleaner and less confusing than the
191
original approach to me, but I'm not sure if it warrants creation of a new
192
QAPI enum and property type definition.
193
194
v9 -> v10:
195
196
* 01/15 (ui & main loop): Added comments to qemu_main declaration and GTK.
197
* 02/15 (apple-gfx): Reworked the way frame rendering code is threaded to use
198
BHs for sections requiring BQL.
199
* 02/15 (apple-gfx): Fixed ./configure error on non-macOS platforms.
200
* 10/15 (vmapple/aes): Code style and comment improvements.
201
* 12/15 (vmapple/cfg): Slightly tidier error reporting for overlong property
202
values.
203
* 13/15 (vmapple/virtio-blk): Folded v9 patch 16/16 into this one, changing
204
the device type design to provide a single device type with a variant
205
     property instead of 2 different subtypes for aux and root volumes.
206
* 15/15 (vmapple machine type): Documentation fixup for changed virtio-blk
207
device type; small improvements to shell commands in documentation;
208
improved propagation of errors during cfg device instantiation.
209
210
v10 -> v11:
211
212
* 01/15 (ui & main loop): Simplified main.c, better comments & commit message
213
* 02/15 (apple-gfx): Give each PV display instance a unique serial number.
214
* 02 & 03/15 (apple-gfx, -pci): Formatting/style tweaks
215
* 15/15 (vmapple machine type): Improvements to shell code in docs
216
217
v11 -> v12:
218
219
* 01/15 (ui & main loop): More precise wording of code comments.
220
* 02/15 (apple-gfx): Fixed memory management regressions introduced in v10;
221
improved error handling; various more conmetic code adjustments
222
* 09/15 (GPEX): Fixed uses of deleted GPEX_NUM_IRQS constant that have been
223
added to QEMU since this patch was originally written.
224
225
v12 -> v13
226
227
* 15/15 (vmapple machine type): Bumped the machine type version from 9.2
228
to 10.0.
229
* All patches in the series now have been positively reviewed and received
230
corresponding reviewed-by tags.
162
231
163
Alexander Graf (9):
232
Alexander Graf (9):
164
hw: Add vmapple subdir
233
hw: Add vmapple subdir
165
hw/misc/pvpanic: Add MMIO interface
234
hw/misc/pvpanic: Add MMIO interface
166
hvf: arm: Ignore writes to CNTP_CTL_EL0
235
hvf: arm: Ignore writes to CNTP_CTL_EL0
...
...
178
hw/display/apple-gfx: Adds PCI implementation
247
hw/display/apple-gfx: Adds PCI implementation
179
hw/display/apple-gfx: Adds configurable mode list
248
hw/display/apple-gfx: Adds configurable mode list
180
MAINTAINERS: Add myself as maintainer for apple-gfx, reviewer for HVF
249
MAINTAINERS: Add myself as maintainer for apple-gfx, reviewer for HVF
181
hw/block/virtio-blk: Replaces request free function with g_free
250
hw/block/virtio-blk: Replaces request free function with g_free
182
251
183
MAINTAINERS | 15 +
252
MAINTAINERS | 15 +
184
contrib/vmapple/uuid.sh | 9 +
253
contrib/vmapple/uuid.sh | 9 +
185
docs/system/arm/vmapple.rst | 60 +++
254
docs/system/arm/vmapple.rst | 63 ++
186
docs/system/target-arm.rst | 1 +
255
docs/system/target-arm.rst | 1 +
187
hw/Kconfig | 1 +
256
hw/Kconfig | 1 +
188
hw/arm/sbsa-ref.c | 2 +-
257
hw/arm/sbsa-ref.c | 2 +-
189
hw/arm/virt.c | 2 +-
258
hw/arm/virt.c | 2 +-
190
hw/block/virtio-blk.c | 58 ++-
259
hw/block/virtio-blk.c | 58 +-
191
hw/display/Kconfig | 13 +
260
hw/core/qdev-properties-system.c | 8 +
192
hw/display/apple-gfx-mmio.m | 289 +++++++++++
261
hw/display/Kconfig | 13 +
193
hw/display/apple-gfx-pci.m | 155 ++++++
262
hw/display/apple-gfx-mmio.m | 289 +++++++++
194
hw/display/apple-gfx.h | 77 +++
263
hw/display/apple-gfx-pci.m | 157 +++++
195
hw/display/apple-gfx.m | 868 +++++++++++++++++++++++++++++++++
264
hw/display/apple-gfx.h | 77 +++
196
hw/display/meson.build | 5 +
265
hw/display/apple-gfx.m | 880 ++++++++++++++++++++++++++++
197
hw/display/trace-events | 30 ++
266
hw/display/meson.build | 7 +
198
hw/i386/microvm.c | 2 +-
267
hw/display/trace-events | 30 +
199
hw/loongarch/virt.c | 2 +-
268
hw/i386/microvm.c | 2 +-
200
hw/meson.build | 1 +
269
hw/loongarch/virt.c | 12 +-
201
hw/mips/loongson3_virt.c | 2 +-
270
hw/meson.build | 1 +
202
hw/misc/Kconfig | 4 +
271
hw/mips/loongson3_virt.c | 2 +-
203
hw/misc/meson.build | 1 +
272
hw/misc/Kconfig | 4 +
204
hw/misc/pvpanic-mmio.c | 61 +++
273
hw/misc/meson.build | 1 +
205
hw/openrisc/virt.c | 12 +-
274
hw/misc/pvpanic-mmio.c | 61 ++
206
hw/pci-host/gpex.c | 43 +-
275
hw/openrisc/virt.c | 12 +-
207
hw/riscv/virt.c | 12 +-
276
hw/pci-host/gpex.c | 43 +-
208
hw/vmapple/Kconfig | 32 ++
277
hw/riscv/virt.c | 12 +-
209
hw/vmapple/aes.c | 578 ++++++++++++++++++++++
278
hw/vmapple/Kconfig | 32 +
210
hw/vmapple/bdif.c | 261 ++++++++++
279
hw/vmapple/aes.c | 581 ++++++++++++++++++
211
hw/vmapple/cfg.c | 196 ++++++++
280
hw/vmapple/bdif.c | 275 +++++++++
212
hw/vmapple/meson.build | 5 +
281
hw/vmapple/cfg.c | 196 +++++++
213
hw/vmapple/trace-events | 21 +
282
hw/vmapple/meson.build | 5 +
214
hw/vmapple/trace.h | 1 +
283
hw/vmapple/trace-events | 21 +
215
hw/vmapple/virtio-blk.c | 226 +++++++++
284
hw/vmapple/trace.h | 1 +
216
hw/vmapple/vmapple.c | 659 +++++++++++++++++++++++++
285
hw/vmapple/virtio-blk.c | 205 +++++++
217
hw/xtensa/virt.c | 2 +-
286
hw/vmapple/vmapple.c | 646 ++++++++++++++++++++
218
include/hw/misc/pvpanic.h | 1 +
287
hw/xen/xen-pvh-common.c | 2 +-
219
include/hw/pci-host/gpex.h | 7 +-
288
hw/xtensa/virt.c | 2 +-
220
include/hw/pci/pci_ids.h | 1 +
289
include/hw/misc/pvpanic.h | 1 +
221
include/hw/virtio/virtio-blk.h | 11 +-
290
include/hw/pci-host/gpex.h | 7 +-
222
include/hw/vmapple/vmapple.h | 25 +
291
include/hw/pci/pci_ids.h | 1 +
223
include/qemu-main.h | 3 +-
292
include/hw/qdev-properties-system.h | 5 +
224
include/qemu/cutils.h | 15 +
293
include/hw/virtio/virtio-blk.h | 11 +-
225
include/qemu/typedefs.h | 1 +
294
include/hw/vmapple/vmapple.h | 23 +
226
meson.build | 5 +
295
include/qemu-main.h | 14 +-
227
system/main.c | 50 +-
296
include/qemu/cutils.h | 15 +
228
target/arm/hvf/hvf.c | 9 +
297
meson.build | 5 +
229
ui/cocoa.m | 54 +-
298
qapi/virtio.json | 14 +
230
ui/sdl2.c | 4 +
299
system/main.c | 37 +-
231
util/hexdump.c | 18 +
300
target/arm/hvf/hvf.c | 9 +
232
49 files changed, 3804 insertions(+), 106 deletions(-)
301
ui/cocoa.m | 54 +-
302
ui/gtk.c | 4 +
303
ui/sdl2.c | 4 +
304
util/hexdump.c | 18 +
305
53 files changed, 3840 insertions(+), 110 deletions(-)
233
create mode 100755 contrib/vmapple/uuid.sh
306
create mode 100755 contrib/vmapple/uuid.sh
234
create mode 100644 docs/system/arm/vmapple.rst
307
create mode 100644 docs/system/arm/vmapple.rst
235
create mode 100644 hw/display/apple-gfx-mmio.m
308
create mode 100644 hw/display/apple-gfx-mmio.m
236
create mode 100644 hw/display/apple-gfx-pci.m
309
create mode 100644 hw/display/apple-gfx-pci.m
237
create mode 100644 hw/display/apple-gfx.h
310
create mode 100644 hw/display/apple-gfx.h
...
...
247
create mode 100644 hw/vmapple/virtio-blk.c
320
create mode 100644 hw/vmapple/virtio-blk.c
248
create mode 100644 hw/vmapple/vmapple.c
321
create mode 100644 hw/vmapple/vmapple.c
249
create mode 100644 include/hw/vmapple/vmapple.h
322
create mode 100644 include/hw/vmapple/vmapple.h
250
323
251
--
324
--
252
2.39.3 (Apple Git-145)
325
2.39.5 (Apple Git-154)
253
326
254
327
diff view generated by jsdifflib
...
...
33
* The Cocoa UI sets qemu_main to a function which runs the
33
* The Cocoa UI sets qemu_main to a function which runs the
34
NSApplication event handling runloop, as is usual for a Cocoa app.
34
NSApplication event handling runloop, as is usual for a Cocoa app.
35
* The SDL UI overrides the qemu_main function to NULL, thus
35
* The SDL UI overrides the qemu_main function to NULL, thus
36
specifying that Qemu's main loop must run on the main
36
specifying that Qemu's main loop must run on the main
37
thread.
37
thread.
38
* The GTK UI also overrides the qemu_main function to NULL.
38
* For other UIs, or in the absence of UIs, the platform's default
39
* For other UIs, or in the absence of UIs, the platform's default
39
behaviour is followed.
40
behaviour is followed.
40
41
41
This means that on macOS, the platform's runloop events are always
42
This means that on macOS, the platform's runloop events are always
42
handled, regardless of chosen UI. The new PV graphics device will
43
handled, regardless of chosen UI. The new PV graphics device will
43
thus work in all configurations. There is no functional change on other
44
thus work in all configurations. There is no functional change on other
44
operating systems.
45
operating systems.
45
46
47
Implementing this via a global function pointer variable is a bit
48
ugly, but it's probably worth investigating the existing UI thread rule
49
violations in the SDL (e.g. #2537) and GTK+ back-ends. Fixing those
50
issues might precipitate requirements similar but not identical to those
51
of the Cocoa UI; hopefully we'll see some kind of pattern emerge, which
52
can then be used as a basis for an overhaul. (In fact, it may turn
53
out to be simplest to split the UI/native platform event thread from the
54
QEMU main event loop on all platforms, with any UI or even none at all.)
55
46
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
56
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
47
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
57
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
58
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
48
---
59
---
49
60
50
v5:
61
v5:
51
62
52
* Simplified the way of setting/clearing the main loop by going back
63
* Simplified the way of setting/clearing the main loop by going back
...
...
58
* Folded function qemu_run_default_main_on_new_thread's code into
69
* Folded function qemu_run_default_main_on_new_thread's code into
59
main()
70
main()
60
* Removed whitespace changes left over on lines near code removed
71
* Removed whitespace changes left over on lines near code removed
61
between v4 and v5
72
between v4 and v5
62
73
63
include/qemu-main.h | 3 +--
74
v9:
64
include/qemu/typedefs.h | 1 +
75
65
system/main.c | 50 ++++++++++++++++++++++++++++++++++----
76
* Set qemu_main to NULL for GTK UI as well.
66
ui/cocoa.m | 54 ++++++++++-------------------------------
77
67
ui/sdl2.c | 4 +++
78
v10:
68
5 files changed, 64 insertions(+), 48 deletions(-)
79
80
* Added comments clarifying the functionality and purpose of qemu_main.
81
82
v11:
83
84
* Removed the qemu_main_fn typedef again.
85
* Consolidation of main, qemu_default_main, and call_qemu_default_main
86
so that the latter has been eliminated altogether.
87
* Reinstated the #include <SDL.h> directive, added comment saying
88
why it's needed.
89
* Improved the comment on the qemu_main global variable.
90
* Expanded the commit message.
91
92
v12:
93
94
* More precise wording of code comments.
95
96
include/qemu-main.h | 14 +++++++++++-
97
system/main.c | 37 +++++++++++++++++++++++++++----
98
ui/cocoa.m | 54 +++++++++++----------------------------------
99
ui/gtk.c | 4 ++++
100
ui/sdl2.c | 4 ++++
101
5 files changed, 67 insertions(+), 46 deletions(-)
69
102
70
diff --git a/include/qemu-main.h b/include/qemu-main.h
103
diff --git a/include/qemu-main.h b/include/qemu-main.h
71
index XXXXXXX..XXXXXXX 100644
104
index XXXXXXX..XXXXXXX 100644
72
--- a/include/qemu-main.h
105
--- a/include/qemu-main.h
73
+++ b/include/qemu-main.h
106
+++ b/include/qemu-main.h
74
@@ -XXX,XX +XXX,XX @@
107
@@ -XXX,XX +XXX,XX @@
75
#ifndef QEMU_MAIN_H
108
#ifndef QEMU_MAIN_H
76
#define QEMU_MAIN_H
109
#define QEMU_MAIN_H
77
110
78
-int qemu_default_main(void);
111
-int qemu_default_main(void);
79
-extern int (*qemu_main)(void);
112
+/*
80
+extern qemu_main_fn qemu_main;
113
+ * The function to run on the main (initial) thread of the process.
114
+ * NULL means QEMU's main event loop.
115
+ * When non-NULL, QEMU's main event loop will run on a purposely created
116
+ * thread, after which the provided function pointer will be invoked on
117
+ * the initial thread.
118
+ * This is useful on platforms which treat the main thread as special
119
+ * (macOS/Darwin) and/or require all UI API calls to occur from the main
120
+ * thread. Those platforms can initialise it to a specific function,
121
+ * while UI implementations may reset it to NULL during their init if they
122
+ * will handle system and UI events on the main thread via QEMU's own main
123
+ * event loop.
124
+ */
125
extern int (*qemu_main)(void);
81
126
82
#endif /* QEMU_MAIN_H */
127
#endif /* QEMU_MAIN_H */
83
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
84
index XXXXXXX..XXXXXXX 100644
85
--- a/include/qemu/typedefs.h
86
+++ b/include/qemu/typedefs.h
87
@@ -XXX,XX +XXX,XX @@ typedef struct IRQState *qemu_irq;
88
* Function types
89
*/
90
typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
91
+typedef int (*qemu_main_fn)(void);
92
93
#endif /* QEMU_TYPEDEFS_H */
94
diff --git a/system/main.c b/system/main.c
128
diff --git a/system/main.c b/system/main.c
95
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
96
--- a/system/main.c
130
--- a/system/main.c
97
+++ b/system/main.c
131
+++ b/system/main.c
98
@@ -XXX,XX +XXX,XX @@
132
@@ -XXX,XX +XXX,XX @@
99
133
100
#include "qemu/osdep.h"
134
#include "qemu/osdep.h"
101
#include "qemu-main.h"
135
#include "qemu-main.h"
102
+#include "qemu/main-loop.h"
136
+#include "qemu/main-loop.h"
103
#include "sysemu/sysemu.h"
137
#include "sysemu/sysemu.h"
104
138
105
-#ifdef CONFIG_SDL
139
#ifdef CONFIG_SDL
106
-#include <SDL.h>
140
+/*
141
+ * SDL insists on wrapping the main() function with its own implementation on
142
+ * some platforms; it does so via a macro that renames our main function, so
143
+ * <SDL.h> must be #included here even with no SDL code called from this file.
144
+ */
145
#include <SDL.h>
146
#endif
147
148
-int qemu_default_main(void)
107
+#ifdef CONFIG_DARWIN
149
+#ifdef CONFIG_DARWIN
108
+#include <CoreFoundation/CoreFoundation.h>
150
+#include <CoreFoundation/CoreFoundation.h>
109
#endif
151
+#endif
110
152
+
111
-int qemu_default_main(void)
153
+static void *qemu_default_main(void *opaque)
112
+static int qemu_default_main(void)
113
{
154
{
114
int status;
155
int status;
115
156
116
@@ -XXX,XX +XXX,XX @@ int qemu_default_main(void)
157
+ bql_lock();
117
return status;
158
status = qemu_main_loop();
118
}
159
qemu_cleanup(status);
160
+ bql_unlock();
161
162
- return status;
163
+ exit(status);
164
}
119
165
120
-int (*qemu_main)(void) = qemu_default_main;
166
-int (*qemu_main)(void) = qemu_default_main;
121
+/*
167
+int (*qemu_main)(void);
122
+ * Various macOS system libraries, including the Cocoa UI and anything using
123
+ * libdispatch, such as ParavirtualizedGraphics.framework, requires that the
124
+ * main runloop, on the main (initial) thread be running or at least regularly
125
+ * polled for events. A special mode is therefore supported, where the QEMU
126
+ * main loop runs on a separate thread and the main thread handles the
127
+ * CF/Cocoa runloop.
128
+ */
129
+
130
+static void *call_qemu_default_main(void *opaque)
131
+{
132
+ int status;
133
+
134
+ bql_lock();
135
+ status = qemu_default_main();
136
+ bql_unlock();
137
+
138
+ exit(status);
139
+}
140
+
168
+
141
+#ifdef CONFIG_DARWIN
169
+#ifdef CONFIG_DARWIN
142
+static int os_darwin_cfrunloop_main(void)
170
+static int os_darwin_cfrunloop_main(void)
143
+{
171
+{
144
+ CFRunLoopRun();
172
+ CFRunLoopRun();
145
+ abort();
173
+ g_assert_not_reached();
146
+}
174
+}
147
+
175
+int (*qemu_main)(void) = os_darwin_cfrunloop_main;
148
+qemu_main_fn qemu_main = os_darwin_cfrunloop_main;
149
+#else
150
+qemu_main_fn qemu_main;
151
+#endif
176
+#endif
152
177
153
int main(int argc, char **argv)
178
int main(int argc, char **argv)
154
{
179
{
155
+ QemuThread main_loop_thread;
156
+
157
qemu_init(argc, argv);
180
qemu_init(argc, argv);
158
- return qemu_main();
181
- return qemu_main();
182
+ bql_unlock();
159
+ if (qemu_main) {
183
+ if (qemu_main) {
184
+ QemuThread main_loop_thread;
160
+ qemu_thread_create(&main_loop_thread, "qemu_main",
185
+ qemu_thread_create(&main_loop_thread, "qemu_main",
161
+ call_qemu_default_main, NULL, QEMU_THREAD_DETACHED);
186
+ qemu_default_main, NULL, QEMU_THREAD_DETACHED);
162
+ bql_unlock();
163
+ return qemu_main();
187
+ return qemu_main();
164
+ } else {
188
+ } else {
165
+ qemu_default_main();
189
+ qemu_default_main(NULL);
166
+ }
190
+ }
167
}
191
}
168
diff --git a/ui/cocoa.m b/ui/cocoa.m
192
diff --git a/ui/cocoa.m b/ui/cocoa.m
169
index XXXXXXX..XXXXXXX 100644
193
index XXXXXXX..XXXXXXX 100644
170
--- a/ui/cocoa.m
194
--- a/ui/cocoa.m
...
...
272
+ */
296
+ */
273
+ qemu_main = cocoa_main;
297
+ qemu_main = cocoa_main;
274
}
298
}
275
299
276
static QemuDisplay qemu_display_cocoa = {
300
static QemuDisplay qemu_display_cocoa = {
301
diff --git a/ui/gtk.c b/ui/gtk.c
302
index XXXXXXX..XXXXXXX 100644
303
--- a/ui/gtk.c
304
+++ b/ui/gtk.c
305
@@ -XXX,XX +XXX,XX @@
306
#include "qemu/cutils.h"
307
#include "qemu/error-report.h"
308
#include "qemu/main-loop.h"
309
+#include "qemu-main.h"
310
311
#include "ui/console.h"
312
#include "ui/gtk.h"
313
@@ -XXX,XX +XXX,XX @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
314
#ifdef CONFIG_GTK_CLIPBOARD
315
gd_clipboard_init(s);
316
#endif /* CONFIG_GTK_CLIPBOARD */
317
+
318
+ /* GTK's event polling must happen on the main thread. */
319
+ qemu_main = NULL;
320
}
321
322
static void early_gtk_display_init(DisplayOptions *opts)
277
diff --git a/ui/sdl2.c b/ui/sdl2.c
323
diff --git a/ui/sdl2.c b/ui/sdl2.c
278
index XXXXXXX..XXXXXXX 100644
324
index XXXXXXX..XXXXXXX 100644
279
--- a/ui/sdl2.c
325
--- a/ui/sdl2.c
280
+++ b/ui/sdl2.c
326
+++ b/ui/sdl2.c
281
@@ -XXX,XX +XXX,XX @@
327
@@ -XXX,XX +XXX,XX @@
...
...
295
+ qemu_main = NULL;
341
+ qemu_main = NULL;
296
}
342
}
297
343
298
static QemuDisplay qemu_display_sdl2 = {
344
static QemuDisplay qemu_display_sdl2 = {
299
--
345
--
300
2.39.3 (Apple Git-145)
346
2.39.5 (Apple Git-154)
diff view generated by jsdifflib
...
...
29
similarly never acquiring the BQL in a callback from PVG. Different strategies
29
similarly never acquiring the BQL in a callback from PVG. Different strategies
30
have been used (libdispatch, blocking and non-blocking BHs, RCU, etc.)
30
have been used (libdispatch, blocking and non-blocking BHs, RCU, etc.)
31
depending on the specific requirements at each framework entry and exit point.
31
depending on the specific requirements at each framework entry and exit point.
32
32
33
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
33
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
34
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
35
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
34
---
36
---
35
37
36
v2:
38
v2:
37
39
38
* Cherry-pick/rebase conflict fixes
40
* Cherry-pick/rebase conflict fixes
...
...
117
v7:
119
v7:
118
120
119
* Use g_ptr_array_find() helper function
121
* Use g_ptr_array_find() helper function
120
* Error handling coding style tweak
122
* Error handling coding style tweak
121
123
124
v8:
125
126
* Renamed apple_gfx_host_address_for_gpa_range() to
127
apple_gfx_host_ptr_for_gpa_range(), and made it return a void* instead of
128
uintptr_t. Fixed up callers and related code.
129
* Some adjustments to types used.
130
* Variable naming tweaks for better clarity.
131
* Fixed leak in unlikely realize error case.
132
* Fixed typo in unmap call.
133
* Don't bother with dummy argument for g_ptr_array_find(), NULL works too.
134
135
v9:
136
137
* Pass device pointer to graphic_console_init().
138
* Slightly re-ordered initialisation code.
139
* Simplified error handling during realize().
140
* Simplified code without functional changes, adjusted code & comment
141
formatting.
142
143
v10:
144
145
* Reworked the way frame rendering code is threaded to use BHs for sections
146
requiring BQL.
147
* Fix for ./configure error on non-macOS platforms.
148
* Code formatting tweaks.
149
150
v11:
151
152
* Generate unique display serial number for each apple-gfx device instance.
153
* Dropped redundant local variable initialisation.
154
155
v12:
156
157
* Removed 2 redundant variable initialisations.
158
* Removed dedicated rendering dispatch_queue, use global queue instead.
159
* Fixed an object leak regression introduced in v10. Solved by placing
160
@autoreleasepool blocks around the relevant Objective-C code in the BH
161
functions replacing the dispatch_async tasks. (dispatch_async implicitly
162
cleaned up autoreleased objects.)
163
* Fixed missing retain/release of command buffers when handing off to a
164
non-BH thread. (Problem masked at runtime by above leak.)
165
* Better handling of render command encoding errors.
166
* Re-arranged positions of static variables in the file.
167
122
hw/display/Kconfig | 9 +
168
hw/display/Kconfig | 9 +
123
hw/display/apple-gfx-mmio.m | 281 +++++++++++++
169
hw/display/apple-gfx-mmio.m | 281 +++++++++++++
124
hw/display/apple-gfx.h | 65 +++
170
hw/display/apple-gfx.h | 66 +++
125
hw/display/apple-gfx.m | 770 ++++++++++++++++++++++++++++++++++++
171
hw/display/apple-gfx.m | 783 ++++++++++++++++++++++++++++++++++++
126
hw/display/meson.build | 4 +
172
hw/display/meson.build | 6 +
127
hw/display/trace-events | 28 ++
173
hw/display/trace-events | 28 ++
128
meson.build | 4 +
174
meson.build | 4 +
129
7 files changed, 1161 insertions(+)
175
7 files changed, 1177 insertions(+)
130
create mode 100644 hw/display/apple-gfx-mmio.m
176
create mode 100644 hw/display/apple-gfx-mmio.m
131
create mode 100644 hw/display/apple-gfx.h
177
create mode 100644 hw/display/apple-gfx.h
132
create mode 100644 hw/display/apple-gfx.m
178
create mode 100644 hw/display/apple-gfx.m
133
179
134
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
180
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
...
...
302
+}
348
+}
303
+
349
+
304
+static void *apple_gfx_mmio_map_surface_memory(uint64_t guest_physical_address,
350
+static void *apple_gfx_mmio_map_surface_memory(uint64_t guest_physical_address,
305
+ uint64_t length, bool read_only)
351
+ uint64_t length, bool read_only)
306
+{
352
+{
307
+ mach_vm_address_t mem;
353
+ void *mem;
308
+ MemoryRegion *region = NULL;
354
+ MemoryRegion *region = NULL;
309
+
355
+
310
+ RCU_READ_LOCK_GUARD();
356
+ RCU_READ_LOCK_GUARD();
311
+ mem = apple_gfx_host_address_for_gpa_range(guest_physical_address,
357
+ mem = apple_gfx_host_ptr_for_gpa_range(guest_physical_address,
312
+ length, read_only, &region);
358
+ length, read_only, &region);
313
+
359
+ if (mem) {
314
+ if (mem != 0) {
315
+ memory_region_ref(region);
360
+ memory_region_ref(region);
316
+ }
361
+ }
317
+
362
+ return mem;
318
+ return (void *)mem;
363
+}
319
+}
364
+
320
+
365
+static bool apple_gfx_mmio_unmap_surface_memory(void *ptr)
321
+static bool apple_gfx_mmio_unmap_surface_memory(void *virtual_address)
322
+{
366
+{
323
+ MemoryRegion *region;
367
+ MemoryRegion *region;
324
+ ram_addr_t offset = 0;
368
+ ram_addr_t offset = 0;
325
+
369
+
326
+ RCU_READ_LOCK_GUARD();
370
+ RCU_READ_LOCK_GUARD();
327
+ region = memory_region_from_host(virtual_address, &offset);
371
+ region = memory_region_from_host(ptr, &offset);
328
+ if (!region) {
372
+ if (!region) {
329
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: memory at %p to be unmapped not "
373
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: memory at %p to be unmapped not "
330
+ "found.\n",
374
+ "found.\n",
331
+ __func__,
375
+ __func__, ptr);
332
+ virtual_address);
333
+ return false;
376
+ return false;
334
+ }
377
+ }
335
+
378
+
336
+ trace_apple_gfx_iosfc_unmap_memory_region(virtual_address, region);
379
+ trace_apple_gfx_iosfc_unmap_memory_region(ptr, region);
337
+ memory_region_unref(region);
380
+ memory_region_unref(region);
338
+ return true;
381
+ return true;
339
+}
382
+}
340
+
383
+
341
+static PGIOSurfaceHostDevice *apple_gfx_prepare_iosurface_host_device(
384
+static PGIOSurfaceHostDevice *apple_gfx_prepare_iosurface_host_device(
342
+ AppleGFXMMIOState *s)
385
+ AppleGFXMMIOState *s)
343
+{
386
+{
344
+ PGIOSurfaceHostDeviceDescriptor *iosfc_desc =
387
+ PGIOSurfaceHostDeviceDescriptor *iosfc_desc =
345
+ [PGIOSurfaceHostDeviceDescriptor new];
388
+ [PGIOSurfaceHostDeviceDescriptor new];
346
+ PGIOSurfaceHostDevice *iosfc_host_dev = nil;
389
+ PGIOSurfaceHostDevice *iosfc_host_dev;
347
+
390
+
348
+ iosfc_desc.mapMemory =
391
+ iosfc_desc.mapMemory =
349
+ ^bool(uint64_t phys, uint64_t len, bool ro, void **va, void *e, void *f) {
392
+ ^bool(uint64_t phys, uint64_t len, bool ro, void **va, void *e, void *f) {
350
+ *va = apple_gfx_mmio_map_surface_memory(phys, len, ro);
393
+ *va = apple_gfx_mmio_map_surface_memory(phys, len, ro);
351
+
394
+
...
...
354
+ return *va != NULL;
397
+ return *va != NULL;
355
+ };
398
+ };
356
+
399
+
357
+ iosfc_desc.unmapMemory =
400
+ iosfc_desc.unmapMemory =
358
+ ^bool(void *va, void *b, void *c, void *d, void *e, void *f) {
401
+ ^bool(void *va, void *b, void *c, void *d, void *e, void *f) {
359
+ return apple_gfx_mmio_unmap_surface_memory(s);
402
+ return apple_gfx_mmio_unmap_surface_memory(va);
360
+ };
403
+ };
361
+
404
+
362
+ iosfc_desc.raiseInterrupt = ^bool(uint32_t vector) {
405
+ iosfc_desc.raiseInterrupt = ^bool(uint32_t vector) {
363
+ trace_apple_gfx_iosfc_raise_irq(vector);
406
+ trace_apple_gfx_iosfc_raise_irq(vector);
364
+ aio_bh_schedule_oneshot(qemu_get_aio_context(),
407
+ aio_bh_schedule_oneshot(qemu_get_aio_context(),
...
...
385
+ };
428
+ };
386
+
429
+
387
+ desc.usingIOSurfaceMapper = true;
430
+ desc.usingIOSurfaceMapper = true;
388
+ s->pgiosfc = apple_gfx_prepare_iosurface_host_device(s);
431
+ s->pgiosfc = apple_gfx_prepare_iosurface_host_device(s);
389
+
432
+
390
+ apple_gfx_common_realize(&s->common, desc, errp);
433
+ if (!apple_gfx_common_realize(&s->common, dev, desc, errp)) {
434
+ [s->pgiosfc release];
435
+ s->pgiosfc = nil;
436
+ }
391
+
437
+
392
+ [desc release];
438
+ [desc release];
393
+ desc = nil;
439
+ desc = nil;
394
+ }
440
+ }
395
+}
441
+}
...
...
476
+ id<PGDevice> pgdev;
522
+ id<PGDevice> pgdev;
477
+ id<PGDisplay> pgdisp;
523
+ id<PGDisplay> pgdisp;
478
+ QemuConsole *con;
524
+ QemuConsole *con;
479
+ id<MTLDevice> mtl;
525
+ id<MTLDevice> mtl;
480
+ id<MTLCommandQueue> mtl_queue;
526
+ id<MTLCommandQueue> mtl_queue;
481
+ dispatch_queue_t render_queue;
482
+
527
+
483
+ /* List `tasks` is protected by task_mutex */
528
+ /* List `tasks` is protected by task_mutex */
484
+ QemuMutex task_mutex;
529
+ QemuMutex task_mutex;
485
+ PGTaskList tasks;
530
+ PGTaskList tasks;
486
+
531
+
487
+ /* Mutable state (BQL protected) */
532
+ /* Mutable state (BQL protected) */
488
+ QEMUCursor *cursor;
533
+ QEMUCursor *cursor;
489
+ DisplaySurface *surface;
534
+ DisplaySurface *surface;
490
+ id<MTLTexture> texture;
535
+ id<MTLTexture> texture;
491
+ int32_t pending_frames; /* # guest frames in the rendering pipeline */
536
+ int8_t pending_frames; /* # guest frames in the rendering pipeline */
492
+ bool gfx_update_requested; /* QEMU display system wants a new frame */
537
+ bool gfx_update_requested; /* QEMU display system wants a new frame */
493
+ bool new_frame_ready; /* Guest has rendered a frame, ready to be used */
538
+ bool new_frame_ready; /* Guest has rendered a frame, ready to be used */
494
+ bool using_managed_texture_storage;
539
+ bool using_managed_texture_storage;
540
+ uint32_t rendering_frame_width;
541
+ uint32_t rendering_frame_height;
495
+
542
+
496
+ /* Mutable state (atomic) */
543
+ /* Mutable state (atomic) */
497
+ bool cursor_show;
544
+ bool cursor_show;
498
+} AppleGFXState;
545
+} AppleGFXState;
499
+
546
+
500
+void apple_gfx_common_init(Object *obj, AppleGFXState *s, const char* obj_name);
547
+void apple_gfx_common_init(Object *obj, AppleGFXState *s, const char* obj_name);
501
+void apple_gfx_common_realize(AppleGFXState *s, PGDeviceDescriptor *desc,
548
+bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev,
502
+ Error **errp);
549
+ PGDeviceDescriptor *desc, Error **errp);
503
+uintptr_t apple_gfx_host_address_for_gpa_range(uint64_t guest_physical,
550
+void *apple_gfx_host_ptr_for_gpa_range(uint64_t guest_physical,
504
+ uint64_t length, bool read_only,
551
+ uint64_t length, bool read_only,
505
+ MemoryRegion **mapping_in_region);
552
+ MemoryRegion **mapping_in_region);
506
+
553
+
507
+#endif
554
+#endif
508
+
555
+
509
diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m
556
diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m
510
new file mode 100644
557
new file mode 100644
...
...
547
+
594
+
548
+static const PGDisplayCoord_t apple_gfx_modes[] = {
595
+static const PGDisplayCoord_t apple_gfx_modes[] = {
549
+ { .x = 1440, .y = 1080 },
596
+ { .x = 1440, .y = 1080 },
550
+ { .x = 1280, .y = 1024 },
597
+ { .x = 1280, .y = 1024 },
551
+};
598
+};
599
+
600
+static Error *apple_gfx_mig_blocker;
601
+static uint32_t next_pgdisplay_serial_num = 1;
602
+
603
+static dispatch_queue_t get_background_queue(void)
604
+{
605
+ return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
606
+}
552
+
607
+
553
+/* ------ PGTask and task operations: new/destroy/map/unmap ------ */
608
+/* ------ PGTask and task operations: new/destroy/map/unmap ------ */
554
+
609
+
555
+/*
610
+/*
556
+ * This implements the type declared in <ParavirtualizedGraphics/PGDevice.h>
611
+ * This implements the type declared in <ParavirtualizedGraphics/PGDevice.h>
...
...
582
+ * Protected by AppleGFXState's task_mutex.
637
+ * Protected by AppleGFXState's task_mutex.
583
+ */
638
+ */
584
+ GPtrArray *mapped_regions;
639
+ GPtrArray *mapped_regions;
585
+};
640
+};
586
+
641
+
587
+static Error *apple_gfx_mig_blocker;
588
+
589
+static PGTask_t *apple_gfx_new_task(AppleGFXState *s, uint64_t len)
642
+static PGTask_t *apple_gfx_new_task(AppleGFXState *s, uint64_t len)
590
+{
643
+{
591
+ mach_vm_address_t task_mem;
644
+ mach_vm_address_t task_mem;
592
+ PGTask_t *task;
645
+ PGTask_t *task;
593
+ kern_return_t r;
646
+ kern_return_t r;
...
...
626
+ QEMU_LOCK_GUARD(&s->task_mutex);
679
+ QEMU_LOCK_GUARD(&s->task_mutex);
627
+ QTAILQ_REMOVE(&s->tasks, task, node);
680
+ QTAILQ_REMOVE(&s->tasks, task, node);
628
+ g_free(task);
681
+ g_free(task);
629
+}
682
+}
630
+
683
+
631
+uintptr_t apple_gfx_host_address_for_gpa_range(uint64_t guest_physical,
684
+void *apple_gfx_host_ptr_for_gpa_range(uint64_t guest_physical,
632
+ uint64_t length, bool read_only,
685
+ uint64_t length, bool read_only,
633
+ MemoryRegion **mapping_in_region)
686
+ MemoryRegion **mapping_in_region)
634
+{
687
+{
635
+ MemoryRegion *ram_region;
688
+ MemoryRegion *ram_region;
636
+ uintptr_t host_address;
689
+ char *host_ptr;
637
+ hwaddr ram_region_offset = 0;
690
+ hwaddr ram_region_offset = 0;
638
+ hwaddr ram_region_length = length;
691
+ hwaddr ram_region_length = length;
639
+
692
+
640
+ ram_region = address_space_translate(&address_space_memory,
693
+ ram_region = address_space_translate(&address_space_memory,
641
+ guest_physical,
694
+ guest_physical,
642
+ &ram_region_offset,
695
+ &ram_region_offset,
643
+ &ram_region_length, !read_only,
696
+ &ram_region_length, !read_only,
644
+ MEMTXATTRS_UNSPECIFIED);
697
+ MEMTXATTRS_UNSPECIFIED);
645
+
698
+
646
+ if (!ram_region || ram_region_length < length ||
699
+ if (!ram_region || ram_region_length < length ||
647
+ !memory_access_is_direct(ram_region, !read_only)) {
700
+ !memory_access_is_direct(ram_region, !read_only)) {
648
+ return 0;
701
+ return NULL;
649
+ }
702
+ }
650
+
703
+
651
+ host_address = (uintptr_t)memory_region_get_ram_ptr(ram_region);
704
+ host_ptr = memory_region_get_ram_ptr(ram_region);
652
+ if (host_address == 0) {
705
+ if (!host_ptr) {
653
+ return 0;
706
+ return NULL;
654
+ }
707
+ }
655
+ host_address += ram_region_offset;
708
+ host_ptr += ram_region_offset;
656
+ *mapping_in_region = ram_region;
709
+ *mapping_in_region = ram_region;
657
+ return host_address;
710
+ return host_ptr;
658
+}
659
+
660
+/* Returns false if the region is already in the array */
661
+static bool add_new_region(GPtrArray *regions, MemoryRegion *region)
662
+{
663
+ guint found_index;
664
+
665
+ if (g_ptr_array_find(regions, region, &found_index)) {
666
+ return false;
667
+ }
668
+
669
+ g_ptr_array_add(regions, region);
670
+ return true;
671
+}
711
+}
672
+
712
+
673
+static bool apple_gfx_task_map_memory(AppleGFXState *s, PGTask_t *task,
713
+static bool apple_gfx_task_map_memory(AppleGFXState *s, PGTask_t *task,
674
+ uint64_t virtual_offset,
714
+ uint64_t virtual_offset,
675
+ PGPhysicalMemoryRange_t *ranges,
715
+ PGPhysicalMemoryRange_t *ranges,
676
+ uint32_t range_count, bool read_only)
716
+ uint32_t range_count, bool read_only)
677
+{
717
+{
678
+ kern_return_t r;
718
+ kern_return_t r;
679
+ mach_vm_address_t target, source;
719
+ void *source_ptr;
720
+ mach_vm_address_t target;
680
+ vm_prot_t cur_protection, max_protection;
721
+ vm_prot_t cur_protection, max_protection;
681
+ bool success = true;
722
+ bool success = true;
682
+ MemoryRegion *region;
723
+ MemoryRegion *region;
683
+
724
+
684
+ RCU_READ_LOCK_GUARD();
725
+ RCU_READ_LOCK_GUARD();
...
...
693
+
734
+
694
+ trace_apple_gfx_map_memory_range(i, range->physicalAddress,
735
+ trace_apple_gfx_map_memory_range(i, range->physicalAddress,
695
+ range->physicalLength);
736
+ range->physicalLength);
696
+
737
+
697
+ region = NULL;
738
+ region = NULL;
698
+ source = apple_gfx_host_address_for_gpa_range(range->physicalAddress,
739
+ source_ptr = apple_gfx_host_ptr_for_gpa_range(range->physicalAddress,
699
+ range->physicalLength,
740
+ range->physicalLength,
700
+ read_only, &region);
741
+ read_only, &region);
701
+ if (source == 0) {
742
+ if (!source_ptr) {
702
+ success = false;
743
+ success = false;
703
+ continue;
744
+ continue;
704
+ }
745
+ }
705
+
746
+
706
+ if (add_new_region(task->mapped_regions, region)) {
747
+ if (!g_ptr_array_find(task->mapped_regions, region, NULL)) {
748
+ g_ptr_array_add(task->mapped_regions, region);
707
+ memory_region_ref(region);
749
+ memory_region_ref(region);
708
+ }
750
+ }
709
+
751
+
710
+ cur_protection = 0;
752
+ cur_protection = 0;
711
+ max_protection = 0;
753
+ max_protection = 0;
712
+ // Map guest RAM at range->physicalAddress into PG task memory range
754
+ /* Map guest RAM at range->physicalAddress into PG task memory range */
713
+ r = mach_vm_remap(mach_task_self(),
755
+ r = mach_vm_remap(mach_task_self(),
714
+ &target, range->physicalLength, vm_page_size - 1,
756
+ &target, range->physicalLength, vm_page_size - 1,
715
+ VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
757
+ VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
716
+ mach_task_self(),
758
+ mach_task_self(), (mach_vm_address_t)source_ptr,
717
+ source, false /* shared mapping, no copy */,
759
+ false /* shared mapping, no copy */,
718
+ &cur_protection, &max_protection,
760
+ &cur_protection, &max_protection,
719
+ VM_INHERIT_COPY);
761
+ VM_INHERIT_COPY);
720
+ trace_apple_gfx_remap(r, source, target);
762
+ trace_apple_gfx_remap(r, source_ptr, target);
721
+ g_assert(r == KERN_SUCCESS);
763
+ g_assert(r == KERN_SUCCESS);
722
+ }
764
+ }
723
+
765
+
724
+ return success;
766
+ return success;
725
+}
767
+}
...
...
742
+ g_assert(r == KERN_SUCCESS);
784
+ g_assert(r == KERN_SUCCESS);
743
+}
785
+}
744
+
786
+
745
+/* ------ Rendering and frame management ------ */
787
+/* ------ Rendering and frame management ------ */
746
+
788
+
747
+static void apple_gfx_render_frame_completed(AppleGFXState *s,
789
+static void apple_gfx_render_frame_completed_bh(void *opaque);
748
+ uint32_t width, uint32_t height);
790
+
749
+
791
+static void apple_gfx_render_new_frame(AppleGFXState *s)
750
+static void apple_gfx_render_new_frame_bql_unlock(AppleGFXState *s)
792
+{
751
+{
752
+ BOOL r;
753
+ bool managed_texture = s->using_managed_texture_storage;
793
+ bool managed_texture = s->using_managed_texture_storage;
754
+ uint32_t width = surface_width(s->surface);
794
+ uint32_t width = surface_width(s->surface);
755
+ uint32_t height = surface_height(s->surface);
795
+ uint32_t height = surface_height(s->surface);
756
+ MTLRegion region = MTLRegionMake2D(0, 0, width, height);
796
+ MTLRegion region = MTLRegionMake2D(0, 0, width, height);
757
+ id<MTLCommandBuffer> command_buffer = [s->mtl_queue commandBuffer];
797
+ id<MTLCommandBuffer> command_buffer = [s->mtl_queue commandBuffer];
758
+ id<MTLTexture> texture = s->texture;
798
+ id<MTLTexture> texture = s->texture;
759
+
799
+
760
+ assert(bql_locked());
800
+ assert(bql_locked());
761
+ [texture retain];
801
+ [texture retain];
762
+
802
+ [command_buffer retain];
763
+ bql_unlock();
803
+
764
+
804
+ s->rendering_frame_width = width;
765
+ /* This is not safe to call from the BQL due to PVG-internal locks causing
805
+ s->rendering_frame_height = height;
766
+ * deadlocks. */
806
+
767
+ r = [s->pgdisp encodeCurrentFrameToCommandBuffer:command_buffer
807
+ dispatch_async(get_background_queue(), ^{
768
+ texture:texture
808
+ /*
769
+ region:region];
809
+ * This is not safe to call from the BQL/BH due to PVG-internal locks
770
+ if (!r) {
810
+ * causing deadlocks.
811
+ */
812
+ bool r = [s->pgdisp encodeCurrentFrameToCommandBuffer:command_buffer
813
+ texture:texture
814
+ region:region];
815
+ if (!r) {
816
+ [texture release];
817
+ [command_buffer release];
818
+ qemu_log_mask(LOG_GUEST_ERROR,
819
+ "%s: encodeCurrentFrameToCommandBuffer:texture:region: "
820
+ "failed\n", __func__);
821
+ bql_lock();
822
+ --s->pending_frames;
823
+ if (s->pending_frames > 0) {
824
+ apple_gfx_render_new_frame(s);
825
+ }
826
+ bql_unlock();
827
+ return;
828
+ }
829
+
830
+ if (managed_texture) {
831
+ /* "Managed" textures exist in both VRAM and RAM and must be synced. */
832
+ id<MTLBlitCommandEncoder> blit = [command_buffer blitCommandEncoder];
833
+ [blit synchronizeResource:texture];
834
+ [blit endEncoding];
835
+ }
771
+ [texture release];
836
+ [texture release];
772
+ bql_lock();
837
+ [command_buffer addCompletedHandler:
773
+ --s->pending_frames;
838
+ ^(id<MTLCommandBuffer> cb)
774
+ bql_unlock();
839
+ {
775
+ qemu_log_mask(LOG_GUEST_ERROR,
840
+ aio_bh_schedule_oneshot(qemu_get_aio_context(),
776
+ "%s: encodeCurrentFrameToCommandBuffer:texture:region: "
841
+ apple_gfx_render_frame_completed_bh, s);
777
+ "failed\n", __func__);
842
+ }];
778
+ return;
843
+ [command_buffer commit];
779
+ }
844
+ [command_buffer release];
780
+
845
+ });
781
+ if (managed_texture) {
782
+ /* "Managed" textures exist in both VRAM and RAM and must be synced. */
783
+ id<MTLBlitCommandEncoder> blit = [command_buffer blitCommandEncoder];
784
+ [blit synchronizeResource:texture];
785
+ [blit endEncoding];
786
+ }
787
+ [texture release];
788
+ [command_buffer addCompletedHandler:
789
+ ^(id<MTLCommandBuffer> cb)
790
+ {
791
+ dispatch_async(s->render_queue, ^{
792
+ apple_gfx_render_frame_completed(s, width, height);
793
+ });
794
+ }];
795
+ [command_buffer commit];
796
+}
846
+}
797
+
847
+
798
+static void copy_mtl_texture_to_surface_mem(id<MTLTexture> texture, void *vram)
848
+static void copy_mtl_texture_to_surface_mem(id<MTLTexture> texture, void *vram)
799
+{
849
+{
800
+ /* TODO: Skip this entirely on a pure Metal or headless/guest-only
850
+ /*
851
+ * TODO: Skip this entirely on a pure Metal or headless/guest-only
801
+ * rendering path, else use a blit command encoder? Needs careful
852
+ * rendering path, else use a blit command encoder? Needs careful
802
+ * (double?) buffering design. */
853
+ * (double?) buffering design.
854
+ */
803
+ size_t width = texture.width, height = texture.height;
855
+ size_t width = texture.width, height = texture.height;
804
+ MTLRegion region = MTLRegionMake2D(0, 0, width, height);
856
+ MTLRegion region = MTLRegionMake2D(0, 0, width, height);
805
+ [texture getBytes:vram
857
+ [texture getBytes:vram
806
+ bytesPerRow:(width * 4)
858
+ bytesPerRow:(width * 4)
807
+ bytesPerImage:(width * height * 4)
859
+ bytesPerImage:(width * height * 4)
808
+ fromRegion:region
860
+ fromRegion:region
809
+ mipmapLevel:0
861
+ mipmapLevel:0
810
+ slice:0];
862
+ slice:0];
811
+}
863
+}
812
+
864
+
813
+static void apple_gfx_render_frame_completed(AppleGFXState *s,
865
+static void apple_gfx_render_frame_completed_bh(void *opaque)
814
+ uint32_t width, uint32_t height)
866
+{
815
+{
867
+ AppleGFXState *s = opaque;
816
+ bql_lock();
868
+
817
+ --s->pending_frames;
869
+ @autoreleasepool {
818
+ assert(s->pending_frames >= 0);
870
+ --s->pending_frames;
819
+
871
+ assert(s->pending_frames >= 0);
820
+ /* Only update display if mode hasn't changed since we started rendering. */
872
+
821
+ if (width == surface_width(s->surface) &&
873
+ /* Only update display if mode hasn't changed since we started rendering. */
822
+ height == surface_height(s->surface)) {
874
+ if (s->rendering_frame_width == surface_width(s->surface) &&
823
+ copy_mtl_texture_to_surface_mem(s->texture, surface_data(s->surface));
875
+ s->rendering_frame_height == surface_height(s->surface)) {
824
+ if (s->gfx_update_requested) {
876
+ copy_mtl_texture_to_surface_mem(s->texture, surface_data(s->surface));
825
+ s->gfx_update_requested = false;
877
+ if (s->gfx_update_requested) {
826
+ dpy_gfx_update_full(s->con);
878
+ s->gfx_update_requested = false;
827
+ graphic_hw_update_done(s->con);
879
+ dpy_gfx_update_full(s->con);
828
+ s->new_frame_ready = false;
880
+ graphic_hw_update_done(s->con);
829
+ } else {
881
+ s->new_frame_ready = false;
830
+ s->new_frame_ready = true;
882
+ } else {
883
+ s->new_frame_ready = true;
884
+ }
831
+ }
885
+ }
832
+ }
886
+ if (s->pending_frames > 0) {
833
+ if (s->pending_frames > 0) {
887
+ apple_gfx_render_new_frame(s);
834
+ apple_gfx_render_new_frame_bql_unlock(s);
888
+ }
835
+ } else {
836
+ bql_unlock();
837
+ }
889
+ }
838
+}
890
+}
839
+
891
+
840
+static void apple_gfx_fb_update_display(void *opaque)
892
+static void apple_gfx_fb_update_display(void *opaque)
841
+{
893
+{
...
...
881
+ width:width
933
+ width:width
882
+ height:height
934
+ height:height
883
+ mipmapped:NO];
935
+ mipmapped:NO];
884
+ textureDescriptor.usage = s->pgdisp.minimumTextureUsage;
936
+ textureDescriptor.usage = s->pgdisp.minimumTextureUsage;
885
+ s->texture = [s->mtl newTextureWithDescriptor:textureDescriptor];
937
+ s->texture = [s->mtl newTextureWithDescriptor:textureDescriptor];
886
+ }
938
+ s->using_managed_texture_storage =
887
+
939
+ (s->texture.storageMode == MTLStorageModeManaged);
888
+ s->using_managed_texture_storage =
940
+ }
889
+ (s->texture.storageMode == MTLStorageModeManaged);
941
+
890
+ dpy_gfx_replace_surface(s->con, s->surface);
942
+ dpy_gfx_replace_surface(s->con, s->surface);
891
+}
943
+}
892
+
944
+
893
+static void update_cursor(AppleGFXState *s)
945
+static void update_cursor(AppleGFXState *s)
894
+{
946
+{
...
...
934
+
986
+
935
+ uint32_t *dest_px = s->cursor->data;
987
+ uint32_t *dest_px = s->cursor->data;
936
+
988
+
937
+ for (size_t y = 0; y < height; ++y) {
989
+ for (size_t y = 0; y < height; ++y) {
938
+ for (size_t x = 0; x < width; ++x) {
990
+ for (size_t x = 0; x < width; ++x) {
939
+ /* NSBitmapImageRep's red & blue channels are swapped
991
+ /*
940
+ * compared to QEMUCursor's. */
992
+ * NSBitmapImageRep's red & blue channels are swapped
993
+ * compared to QEMUCursor's.
994
+ */
941
+ *dest_px =
995
+ *dest_px =
942
+ (px_data[0] << 16u) |
996
+ (px_data[0] << 16u) |
943
+ (px_data[1] << 8u) |
997
+ (px_data[1] << 8u) |
944
+ (px_data[2] << 0u) |
998
+ (px_data[2] << 0u) |
945
+ (px_data[3] << 24u);
999
+ (px_data[3] << 24u);
...
...
995
+ qemu_sem_destroy(&job.sem);
1049
+ qemu_sem_destroy(&job.sem);
996
+ return job.success;
1050
+ return job.success;
997
+}
1051
+}
998
+
1052
+
999
+/* ------ Memory-mapped device I/O operations ------ */
1053
+/* ------ Memory-mapped device I/O operations ------ */
1000
+
1001
+static dispatch_queue_t get_background_queue(void)
1002
+{
1003
+ return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1004
+}
1005
+
1054
+
1006
+typedef struct AppleGFXIOJob {
1055
+typedef struct AppleGFXIOJob {
1007
+ AppleGFXState *state;
1056
+ AppleGFXState *state;
1008
+ uint64_t offset;
1057
+ uint64_t offset;
1009
+ uint64_t value;
1058
+ uint64_t value;
...
...
1139
+ void * _Nonnull dst) {
1188
+ void * _Nonnull dst) {
1140
+ return apple_gfx_read_memory(s, physical_address, length, dst);
1189
+ return apple_gfx_read_memory(s, physical_address, length, dst);
1141
+ };
1190
+ };
1142
+}
1191
+}
1143
+
1192
+
1193
+static void new_frame_handler_bh(void *opaque)
1194
+{
1195
+ AppleGFXState *s = opaque;
1196
+
1197
+ /* Drop frames if guest gets too far ahead. */
1198
+ if (s->pending_frames >= 2) {
1199
+ return;
1200
+ }
1201
+ ++s->pending_frames;
1202
+ if (s->pending_frames > 1) {
1203
+ return;
1204
+ }
1205
+
1206
+ @autoreleasepool {
1207
+ apple_gfx_render_new_frame(s);
1208
+ }
1209
+}
1210
+
1144
+static PGDisplayDescriptor *apple_gfx_prepare_display_descriptor(AppleGFXState *s)
1211
+static PGDisplayDescriptor *apple_gfx_prepare_display_descriptor(AppleGFXState *s)
1145
+{
1212
+{
1146
+ PGDisplayDescriptor *disp_desc = [PGDisplayDescriptor new];
1213
+ PGDisplayDescriptor *disp_desc = [PGDisplayDescriptor new];
1147
+
1214
+
1148
+ disp_desc.name = @"QEMU display";
1215
+ disp_desc.name = @"QEMU display";
1149
+ disp_desc.sizeInMillimeters = NSMakeSize(400., 300.); /* A 20" display */
1216
+ disp_desc.sizeInMillimeters = NSMakeSize(400., 300.); /* A 20" display */
1150
+ disp_desc.queue = dispatch_get_main_queue();
1217
+ disp_desc.queue = dispatch_get_main_queue();
1151
+ disp_desc.newFrameEventHandler = ^(void) {
1218
+ disp_desc.newFrameEventHandler = ^(void) {
1152
+ trace_apple_gfx_new_frame();
1219
+ trace_apple_gfx_new_frame();
1153
+ dispatch_async(s->render_queue, ^{
1220
+ aio_bh_schedule_oneshot(qemu_get_aio_context(), new_frame_handler_bh, s);
1154
+ /* Drop frames if we get too far ahead. */
1155
+ bql_lock();
1156
+ if (s->pending_frames >= 2) {
1157
+ bql_unlock();
1158
+ return;
1159
+ }
1160
+ ++s->pending_frames;
1161
+ if (s->pending_frames > 1) {
1162
+ bql_unlock();
1163
+ return;
1164
+ }
1165
+ @autoreleasepool {
1166
+ apple_gfx_render_new_frame_bql_unlock(s);
1167
+ }
1168
+ });
1169
+ };
1221
+ };
1170
+ disp_desc.modeChangeHandler = ^(PGDisplayCoord_t sizeInPixels,
1222
+ disp_desc.modeChangeHandler = ^(PGDisplayCoord_t sizeInPixels,
1171
+ OSType pixelFormat) {
1223
+ OSType pixelFormat) {
1172
+ trace_apple_gfx_mode_change(sizeInPixels.x, sizeInPixels.y);
1224
+ trace_apple_gfx_mode_change(sizeInPixels.x, sizeInPixels.y);
1173
+
1225
+
...
...
1200
+}
1252
+}
1201
+
1253
+
1202
+static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void)
1254
+static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void)
1203
+{
1255
+{
1204
+ PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)];
1256
+ PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)];
1205
+ NSArray<PGDisplayMode*>* mode_array = nil;
1257
+ NSArray<PGDisplayMode*>* mode_array;
1206
+ int i;
1258
+ int i;
1207
+
1259
+
1208
+ for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) {
1260
+ for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) {
1209
+ modes[i] =
1261
+ modes[i] =
1210
+ [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.];
1262
+ [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.];
...
...
1244
+ [devs release];
1296
+ [devs release];
1245
+
1297
+
1246
+ return dev;
1298
+ return dev;
1247
+}
1299
+}
1248
+
1300
+
1249
+void apple_gfx_common_realize(AppleGFXState *s, PGDeviceDescriptor *desc,
1301
+bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev,
1250
+ Error **errp)
1302
+ PGDeviceDescriptor *desc, Error **errp)
1251
+{
1303
+{
1252
+ PGDisplayDescriptor *disp_desc = nil;
1304
+ PGDisplayDescriptor *disp_desc;
1253
+
1305
+
1254
+ if (apple_gfx_mig_blocker == NULL) {
1306
+ if (apple_gfx_mig_blocker == NULL) {
1255
+ error_setg(&apple_gfx_mig_blocker,
1307
+ error_setg(&apple_gfx_mig_blocker,
1256
+ "Migration state blocked by apple-gfx display device");
1308
+ "Migration state blocked by apple-gfx display device");
1257
+ if (migrate_add_blocker(&apple_gfx_mig_blocker, errp) < 0) {
1309
+ if (migrate_add_blocker(&apple_gfx_mig_blocker, errp) < 0) {
1258
+ return;
1310
+ return false;
1259
+ }
1311
+ }
1260
+ }
1312
+ }
1261
+
1313
+
1262
+ qemu_mutex_init(&s->task_mutex);
1314
+ qemu_mutex_init(&s->task_mutex);
1263
+ QTAILQ_INIT(&s->tasks);
1315
+ QTAILQ_INIT(&s->tasks);
1264
+ s->render_queue = dispatch_queue_create("apple-gfx.render",
1265
+ DISPATCH_QUEUE_SERIAL);
1266
+ s->mtl = copy_suitable_metal_device();
1316
+ s->mtl = copy_suitable_metal_device();
1267
+ s->mtl_queue = [s->mtl newCommandQueue];
1317
+ s->mtl_queue = [s->mtl newCommandQueue];
1268
+
1318
+
1269
+ desc.device = s->mtl;
1319
+ desc.device = s->mtl;
1270
+
1320
+
1271
+ apple_gfx_register_task_mapping_handlers(s, desc);
1321
+ apple_gfx_register_task_mapping_handlers(s, desc);
1272
+
1322
+
1323
+ s->cursor_show = true;
1324
+
1273
+ s->pgdev = PGNewDeviceWithDescriptor(desc);
1325
+ s->pgdev = PGNewDeviceWithDescriptor(desc);
1274
+
1326
+
1275
+ disp_desc = apple_gfx_prepare_display_descriptor(s);
1327
+ disp_desc = apple_gfx_prepare_display_descriptor(s);
1328
+ /*
1329
+ * Although the framework does, this integration currently does not support
1330
+ * multiple virtual displays connected to a single PV graphics device.
1331
+ * It is however possible to create
1332
+ * more than one instance of the device, each with one display. The macOS
1333
+ * guest will ignore these displays if they share the same serial number,
1334
+ * so ensure each instance gets a unique one.
1335
+ */
1276
+ s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc
1336
+ s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc
1277
+ port:0 serialNum:1234];
1337
+ port:0
1338
+ serialNum:next_pgdisplay_serial_num++];
1278
+ [disp_desc release];
1339
+ [disp_desc release];
1279
+ s->pgdisp.modeList = apple_gfx_prepare_display_mode_array();
1340
+ s->pgdisp.modeList = apple_gfx_prepare_display_mode_array();
1280
+
1341
+
1281
+ s->con = graphic_console_init(NULL, 0, &apple_gfx_fb_ops, s);
1342
+ s->con = graphic_console_init(dev, 0, &apple_gfx_fb_ops, s);
1282
+
1343
+ return true;
1283
+ qatomic_set(&s->cursor_show, true);
1284
+}
1344
+}
1285
diff --git a/hw/display/meson.build b/hw/display/meson.build
1345
diff --git a/hw/display/meson.build b/hw/display/meson.build
1286
index XXXXXXX..XXXXXXX 100644
1346
index XXXXXXX..XXXXXXX 100644
1287
--- a/hw/display/meson.build
1347
--- a/hw/display/meson.build
1288
+++ b/hw/display/meson.build
1348
+++ b/hw/display/meson.build
1289
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c'))
1349
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c'))
1290
1350
1291
system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', 'ati_dbg.c'), pixman])
1351
system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', 'ati_dbg.c'), pixman])
1292
1352
1293
+system_ss.add(when: 'CONFIG_MAC_PVG', if_true: [files('apple-gfx.m'), pvg, metal])
1353
+if host_os == 'darwin'
1294
+if cpu == 'aarch64'
1354
+ system_ss.add(when: 'CONFIG_MAC_PVG', if_true: [files('apple-gfx.m'), pvg, metal])
1295
+ system_ss.add(when: 'CONFIG_MAC_PVG_MMIO', if_true: [files('apple-gfx-mmio.m'), pvg, metal])
1355
+ if cpu == 'aarch64'
1356
+ system_ss.add(when: 'CONFIG_MAC_PVG_MMIO', if_true: [files('apple-gfx-mmio.m'), pvg, metal])
1357
+ endif
1296
+endif
1358
+endif
1297
1359
1298
if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
1360
if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
1299
virtio_gpu_ss = ss.source_set()
1361
virtio_gpu_ss = ss.source_set()
1300
diff --git a/hw/display/trace-events b/hw/display/trace-events
1362
diff --git a/hw/display/trace-events b/hw/display/trace-events
...
...
1311
+apple_gfx_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
1373
+apple_gfx_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
1312
+apple_gfx_create_task(uint32_t vm_size, void *va) "vm_size=0x%x base_addr=%p"
1374
+apple_gfx_create_task(uint32_t vm_size, void *va) "vm_size=0x%x base_addr=%p"
1313
+apple_gfx_destroy_task(void *task, unsigned int num_mapped_regions) "task=%p, task->mapped_regions->len=%u"
1375
+apple_gfx_destroy_task(void *task, unsigned int num_mapped_regions) "task=%p, task->mapped_regions->len=%u"
1314
+apple_gfx_map_memory(void *task, uint32_t range_count, uint64_t virtual_offset, uint32_t read_only) "task=%p range_count=0x%x virtual_offset=0x%"PRIx64" read_only=%d"
1376
+apple_gfx_map_memory(void *task, uint32_t range_count, uint64_t virtual_offset, uint32_t read_only) "task=%p range_count=0x%x virtual_offset=0x%"PRIx64" read_only=%d"
1315
+apple_gfx_map_memory_range(uint32_t i, uint64_t phys_addr, uint64_t phys_len) "[%d] phys_addr=0x%"PRIx64" phys_len=0x%"PRIx64
1377
+apple_gfx_map_memory_range(uint32_t i, uint64_t phys_addr, uint64_t phys_len) "[%d] phys_addr=0x%"PRIx64" phys_len=0x%"PRIx64
1316
+apple_gfx_remap(uint64_t retval, uint64_t source, uint64_t target) "retval=%"PRId64" source=0x%"PRIx64" target=0x%"PRIx64
1378
+apple_gfx_remap(uint64_t retval, void *source_ptr, uint64_t target) "retval=%"PRId64" source=%p target=0x%"PRIx64
1317
+apple_gfx_unmap_memory(void *task, uint64_t virtual_offset, uint64_t length) "task=%p virtual_offset=0x%"PRIx64" length=0x%"PRIx64
1379
+apple_gfx_unmap_memory(void *task, uint64_t virtual_offset, uint64_t length) "task=%p virtual_offset=0x%"PRIx64" length=0x%"PRIx64
1318
+apple_gfx_read_memory(uint64_t phys_address, uint64_t length, void *dst) "phys_addr=0x%"PRIx64" length=0x%"PRIx64" dest=%p"
1380
+apple_gfx_read_memory(uint64_t phys_address, uint64_t length, void *dst) "phys_addr=0x%"PRIx64" length=0x%"PRIx64" dest=%p"
1319
+apple_gfx_raise_irq(uint32_t vector) "vector=0x%x"
1381
+apple_gfx_raise_irq(uint32_t vector) "vector=0x%x"
1320
+apple_gfx_new_frame(void) ""
1382
+apple_gfx_new_frame(void) ""
1321
+apple_gfx_mode_change(uint64_t x, uint64_t y) "x=%"PRId64" y=%"PRId64
1383
+apple_gfx_mode_change(uint64_t x, uint64_t y) "x=%"PRId64" y=%"PRId64
...
...
1339
+++ b/meson.build
1401
+++ b/meson.build
1340
@@ -XXX,XX +XXX,XX @@ socket = []
1402
@@ -XXX,XX +XXX,XX @@ socket = []
1341
version_res = []
1403
version_res = []
1342
coref = []
1404
coref = []
1343
iokit = []
1405
iokit = []
1344
+pvg = []
1406
+pvg = not_found
1345
+metal = []
1407
+metal = []
1346
emulator_link_args = []
1408
emulator_link_args = []
1347
midl = not_found
1409
midl = not_found
1348
widl = not_found
1410
widl = not_found
1349
@@ -XXX,XX +XXX,XX @@ elif host_os == 'darwin'
1411
@@ -XXX,XX +XXX,XX @@ elif host_os == 'darwin'
...
...
1354
+ metal = dependency('appleframeworks', modules: 'Metal')
1416
+ metal = dependency('appleframeworks', modules: 'Metal')
1355
elif host_os == 'sunos'
1417
elif host_os == 'sunos'
1356
socket = [cc.find_library('socket'),
1418
socket = [cc.find_library('socket'),
1357
cc.find_library('nsl'),
1419
cc.find_library('nsl'),
1358
--
1420
--
1359
2.39.3 (Apple Git-145)
1421
2.39.5 (Apple Git-154)
1360
1422
1361
1423
diff view generated by jsdifflib
1
This change wires up the PCI variant of the paravirtualised
1
This change wires up the PCI variant of the paravirtualised
2
graphics device, mainly useful for x86-64 macOS guests, implemented
2
graphics device, mainly useful for x86-64 macOS guests, implemented
3
by macOS's ParavirtualizedGraphics.framework. It builds on code
3
by macOS's ParavirtualizedGraphics.framework. It builds on code
4
shared with the vmapple/mmio variant of the PVG device.
4
shared with the vmapple/mmio variant of the PVG device.
5
5
6
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
6
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
7
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
---
8
---
8
9
9
v4:
10
v4:
10
11
11
* Threading improvements analogous to those in common apple-gfx code
12
* Threading improvements analogous to those in common apple-gfx code
...
...
18
19
19
v6:
20
v6:
20
21
21
* Removed an unused function parameter.
22
* Removed an unused function parameter.
22
23
24
v9:
25
26
* Fixup of changed common call.
27
* Whitespace and comment formatting tweaks.
28
29
v11:
30
31
* Comment formatting fix.
32
23
hw/display/Kconfig | 4 +
33
hw/display/Kconfig | 4 +
24
hw/display/apple-gfx-pci.m | 148 +++++++++++++++++++++++++++++++++++++
34
hw/display/apple-gfx-pci.m | 150 +++++++++++++++++++++++++++++++++++++
25
hw/display/meson.build | 1 +
35
hw/display/meson.build | 1 +
26
3 files changed, 153 insertions(+)
36
3 files changed, 155 insertions(+)
27
create mode 100644 hw/display/apple-gfx-pci.m
37
create mode 100644 hw/display/apple-gfx-pci.m
28
38
29
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
39
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
30
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/display/Kconfig
41
--- a/hw/display/Kconfig
...
...
86
+static void apple_gfx_pci_init(Object *obj)
96
+static void apple_gfx_pci_init(Object *obj)
87
+{
97
+{
88
+ AppleGFXPCIState *s = APPLE_GFX_PCI(obj);
98
+ AppleGFXPCIState *s = APPLE_GFX_PCI(obj);
89
+
99
+
90
+ if (!apple_gfx_pci_option_rom_path) {
100
+ if (!apple_gfx_pci_option_rom_path) {
91
+ /* The following is done on device not class init to avoid running
101
+ /*
92
+ * ObjC code before fork() in -daemonize mode. */
102
+ * The following is done on device not class init to avoid running
103
+ * ObjC code before fork() in -daemonize mode.
104
+ */
93
+ PCIDeviceClass *pci = PCI_DEVICE_CLASS(object_get_class(obj));
105
+ PCIDeviceClass *pci = PCI_DEVICE_CLASS(object_get_class(obj));
94
+ apple_gfx_init_option_rom_path();
106
+ apple_gfx_init_option_rom_path();
95
+ pci->romfile = apple_gfx_pci_option_rom_path;
107
+ pci->romfile = apple_gfx_pci_option_rom_path;
96
+ }
108
+ }
97
+
109
+
...
...
133
+ pci_register_bar(dev, PG_PCI_BAR_MMIO,
145
+ pci_register_bar(dev, PG_PCI_BAR_MMIO,
134
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &s->common.iomem_gfx);
146
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &s->common.iomem_gfx);
135
+
147
+
136
+ ret = msi_init(dev, 0x0 /* config offset; 0 = find space */,
148
+ ret = msi_init(dev, 0x0 /* config offset; 0 = find space */,
137
+ PG_PCI_MAX_MSI_VECTORS, true /* msi64bit */,
149
+ PG_PCI_MAX_MSI_VECTORS, true /* msi64bit */,
138
+ false /*msi_per_vector_mask*/, errp);
150
+ false /* msi_per_vector_mask */, errp);
139
+ if (ret != 0) {
151
+ if (ret != 0) {
140
+ return;
152
+ return;
141
+ }
153
+ }
142
+
154
+
143
+ @autoreleasepool {
155
+ @autoreleasepool {
144
+ PGDeviceDescriptor *desc = [PGDeviceDescriptor new];
156
+ PGDeviceDescriptor *desc = [PGDeviceDescriptor new];
145
+ desc.raiseInterrupt = ^(uint32_t vector) {
157
+ desc.raiseInterrupt = ^(uint32_t vector) {
146
+ apple_gfx_pci_interrupt(dev, vector);
158
+ apple_gfx_pci_interrupt(dev, vector);
147
+ };
159
+ };
148
+
160
+
149
+ apple_gfx_common_realize(&s->common, desc, errp);
161
+ apple_gfx_common_realize(&s->common, DEVICE(dev), desc, errp);
150
+ [desc release];
162
+ [desc release];
151
+ desc = nil;
163
+ desc = nil;
152
+ }
164
+ }
153
+}
165
+}
154
+
166
+
...
...
172
+ pci->vendor_id = PG_PCI_VENDOR_ID;
184
+ pci->vendor_id = PG_PCI_VENDOR_ID;
173
+ pci->device_id = PG_PCI_DEVICE_ID;
185
+ pci->device_id = PG_PCI_DEVICE_ID;
174
+ pci->class_id = PCI_CLASS_DISPLAY_OTHER;
186
+ pci->class_id = PCI_CLASS_DISPLAY_OTHER;
175
+ pci->realize = apple_gfx_pci_realize;
187
+ pci->realize = apple_gfx_pci_realize;
176
+
188
+
177
+ // TODO: Property for setting mode list
189
+ /* TODO: Property for setting mode list */
178
+}
190
+}
179
+
191
+
180
+static TypeInfo apple_gfx_pci_types[] = {
192
+static TypeInfo apple_gfx_pci_types[] = {
181
+ {
193
+ {
182
+ .name = TYPE_APPLE_GFX_PCI,
194
+ .name = TYPE_APPLE_GFX_PCI,
...
...
194
+
206
+
195
diff --git a/hw/display/meson.build b/hw/display/meson.build
207
diff --git a/hw/display/meson.build b/hw/display/meson.build
196
index XXXXXXX..XXXXXXX 100644
208
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/display/meson.build
209
--- a/hw/display/meson.build
198
+++ b/hw/display/meson.build
210
+++ b/hw/display/meson.build
199
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_MAC_PVG', if_true: [files('apple-gfx.m'), pv
211
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_ATI_VGA', if_true: [files('ati.c', 'ati_2d.c', 'ati_
200
if cpu == 'aarch64'
212
201
system_ss.add(when: 'CONFIG_MAC_PVG_MMIO', if_true: [files('apple-gfx-mmio.m'), pvg, metal])
213
if host_os == 'darwin'
202
endif
214
system_ss.add(when: 'CONFIG_MAC_PVG', if_true: [files('apple-gfx.m'), pvg, metal])
203
+system_ss.add(when: 'CONFIG_MAC_PVG_PCI', if_true: [files('apple-gfx-pci.m'), pvg, metal])
215
+ system_ss.add(when: 'CONFIG_MAC_PVG_PCI', if_true: [files('apple-gfx-pci.m'), pvg, metal])
204
216
if cpu == 'aarch64'
205
if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
217
system_ss.add(when: 'CONFIG_MAC_PVG_MMIO', if_true: [files('apple-gfx-mmio.m'), pvg, metal])
206
virtio_gpu_ss = ss.source_set()
218
endif
207
--
219
--
208
2.39.3 (Apple Git-145)
220
2.39.5 (Apple Git-154)
209
221
210
222
diff view generated by jsdifflib
...
...
6
less awkward to use, for example:
6
less awkward to use, for example:
7
7
8
-device '{"driver":"apple-gfx-pci", "display-modes":["1920x1080@60", "3840x2160@60"]}'
8
-device '{"driver":"apple-gfx-pci", "display-modes":["1920x1080@60", "3840x2160@60"]}'
9
9
10
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
10
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
11
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
12
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
---
13
---
12
14
13
v4:
15
v4:
14
16
15
* Switched to the native array property type, which recently gained
17
* Switched to the native array property type, which recently gained
...
...
29
31
30
v7:
32
v7:
31
33
32
* Simplified error handling in property parsing
34
* Simplified error handling in property parsing
33
35
36
v8:
37
38
* More consistent integer variable types.
39
40
v9:
41
42
* Re-ordered type definitions so we can drop a 'struct' keyword.
43
34
hw/display/apple-gfx-mmio.m | 8 +++
44
hw/display/apple-gfx-mmio.m | 8 +++
35
hw/display/apple-gfx-pci.m | 9 ++-
45
hw/display/apple-gfx-pci.m | 9 ++-
36
hw/display/apple-gfx.h | 12 ++++
46
hw/display/apple-gfx.h | 11 +++
37
hw/display/apple-gfx.m | 136 +++++++++++++++++++++++++++++++-----
47
hw/display/apple-gfx.m | 135 +++++++++++++++++++++++++++++++-----
38
hw/display/trace-events | 2 +
48
hw/display/trace-events | 2 +
39
5 files changed, 147 insertions(+), 20 deletions(-)
49
5 files changed, 145 insertions(+), 20 deletions(-)
40
50
41
diff --git a/hw/display/apple-gfx-mmio.m b/hw/display/apple-gfx-mmio.m
51
diff --git a/hw/display/apple-gfx-mmio.m b/hw/display/apple-gfx-mmio.m
42
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/display/apple-gfx-mmio.m
53
--- a/hw/display/apple-gfx-mmio.m
44
+++ b/hw/display/apple-gfx-mmio.m
54
+++ b/hw/display/apple-gfx-mmio.m
...
...
84
DeviceClass *dc = DEVICE_CLASS(klass);
94
DeviceClass *dc = DEVICE_CLASS(klass);
85
@@ -XXX,XX +XXX,XX @@ static void apple_gfx_pci_class_init(ObjectClass *klass, void *data)
95
@@ -XXX,XX +XXX,XX @@ static void apple_gfx_pci_class_init(ObjectClass *klass, void *data)
86
pci->class_id = PCI_CLASS_DISPLAY_OTHER;
96
pci->class_id = PCI_CLASS_DISPLAY_OTHER;
87
pci->realize = apple_gfx_pci_realize;
97
pci->realize = apple_gfx_pci_realize;
88
98
89
- // TODO: Property for setting mode list
99
- /* TODO: Property for setting mode list */
90
+ device_class_set_props(dc, apple_gfx_pci_properties);
100
+ device_class_set_props(dc, apple_gfx_pci_properties);
91
}
101
}
92
102
93
static TypeInfo apple_gfx_pci_types[] = {
103
static TypeInfo apple_gfx_pci_types[] = {
94
diff --git a/hw/display/apple-gfx.h b/hw/display/apple-gfx.h
104
diff --git a/hw/display/apple-gfx.h b/hw/display/apple-gfx.h
...
...
104
114
105
@class PGDeviceDescriptor;
115
@class PGDeviceDescriptor;
106
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@
107
117
108
typedef QTAILQ_HEAD(, PGTask_s) PGTaskList;
118
typedef QTAILQ_HEAD(, PGTask_s) PGTaskList;
109
110
+struct AppleGFXDisplayMode;
111
typedef struct AppleGFXState {
112
/* Initialised on init/realize() */
113
MemoryRegion iomem_gfx;
114
@@ -XXX,XX +XXX,XX @@ typedef struct AppleGFXState {
115
id<MTLDevice> mtl;
116
id<MTLCommandQueue> mtl_queue;
117
dispatch_queue_t render_queue;
118
+ struct AppleGFXDisplayMode *display_modes;
119
+ uint32_t num_display_modes;
120
121
/* List `tasks` is protected by task_mutex */
122
QemuMutex task_mutex;
123
@@ -XXX,XX +XXX,XX @@ typedef struct AppleGFXState {
124
bool cursor_show;
125
} AppleGFXState;
126
119
127
+typedef struct AppleGFXDisplayMode {
120
+typedef struct AppleGFXDisplayMode {
128
+ uint16_t width_px;
121
+ uint16_t width_px;
129
+ uint16_t height_px;
122
+ uint16_t height_px;
130
+ uint16_t refresh_rate_hz;
123
+ uint16_t refresh_rate_hz;
131
+} AppleGFXDisplayMode;
124
+} AppleGFXDisplayMode;
132
+
125
+
133
void apple_gfx_common_init(Object *obj, AppleGFXState *s, const char* obj_name);
126
typedef struct AppleGFXState {
134
void apple_gfx_common_realize(AppleGFXState *s, PGDeviceDescriptor *desc,
127
/* Initialised on init/realize() */
135
Error **errp);
128
MemoryRegion iomem_gfx;
136
@@ -XXX,XX +XXX,XX @@ uintptr_t apple_gfx_host_address_for_gpa_range(uint64_t guest_physical,
129
@@ -XXX,XX +XXX,XX @@ typedef struct AppleGFXState {
137
uint64_t length, bool read_only,
130
QemuConsole *con;
138
MemoryRegion **mapping_in_region);
131
id<MTLDevice> mtl;
132
id<MTLCommandQueue> mtl_queue;
133
+ AppleGFXDisplayMode *display_modes;
134
+ uint32_t num_display_modes;
135
136
/* List `tasks` is protected by task_mutex */
137
QemuMutex task_mutex;
138
@@ -XXX,XX +XXX,XX @@ void *apple_gfx_host_ptr_for_gpa_range(uint64_t guest_physical,
139
uint64_t length, bool read_only,
140
MemoryRegion **mapping_in_region);
139
141
140
+extern const PropertyInfo qdev_prop_display_mode;
142
+extern const PropertyInfo qdev_prop_display_mode;
141
+
143
+
142
#endif
144
#endif
143
145
...
...
156
+ { 1920, 1080, 60 },
158
+ { 1920, 1080, 60 },
157
+ { 1440, 1080, 60 },
159
+ { 1440, 1080, 60 },
158
+ { 1280, 1024, 60 },
160
+ { 1280, 1024, 60 },
159
};
161
};
160
162
161
/* ------ PGTask and task operations: new/destroy/map/unmap ------ */
163
static Error *apple_gfx_mig_blocker;
162
@@ -XXX,XX +XXX,XX @@ static void apple_gfx_register_task_mapping_handlers(AppleGFXState *s,
164
@@ -XXX,XX +XXX,XX @@ static void new_frame_handler_bh(void *opaque)
163
return disp_desc;
165
return disp_desc;
164
}
166
}
165
167
166
-static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void)
168
-static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void)
167
+static NSArray<PGDisplayMode *> *apple_gfx_create_display_mode_array(
169
+static NSArray<PGDisplayMode *> *apple_gfx_create_display_mode_array(
168
+ const AppleGFXDisplayMode display_modes[], uint32_t display_mode_count)
170
+ const AppleGFXDisplayMode display_modes[], uint32_t display_mode_count)
169
{
171
{
170
- PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)];
172
- PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)];
171
- NSArray<PGDisplayMode*>* mode_array = nil;
173
- NSArray<PGDisplayMode*>* mode_array;
172
- int i;
174
- int i;
173
-
175
-
174
- for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) {
176
- for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) {
175
- modes[i] =
177
- modes[i] =
176
- [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.];
178
- [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.];
...
...
197
+ [mode_array addObject:mode_obj];
199
+ [mode_array addObject:mode_obj];
198
+ [mode_obj release];
200
+ [mode_obj release];
199
}
201
}
200
202
201
return mode_array;
203
return mode_array;
202
@@ -XXX,XX +XXX,XX @@ void apple_gfx_common_realize(AppleGFXState *s, PGDeviceDescriptor *desc,
204
@@ -XXX,XX +XXX,XX @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev,
203
Error **errp)
205
PGDeviceDescriptor *desc, Error **errp)
204
{
206
{
205
PGDisplayDescriptor *disp_desc = nil;
207
PGDisplayDescriptor *disp_desc;
206
+ const AppleGFXDisplayMode *display_modes = apple_gfx_default_modes;
208
+ const AppleGFXDisplayMode *display_modes = apple_gfx_default_modes;
207
+ int num_display_modes = ARRAY_SIZE(apple_gfx_default_modes);
209
+ uint32_t num_display_modes = ARRAY_SIZE(apple_gfx_default_modes);
208
+ NSArray<PGDisplayMode *> *mode_array;
210
+ NSArray<PGDisplayMode *> *mode_array;
209
211
210
if (apple_gfx_mig_blocker == NULL) {
212
if (apple_gfx_mig_blocker == NULL) {
211
error_setg(&apple_gfx_mig_blocker,
213
error_setg(&apple_gfx_mig_blocker,
212
@@ -XXX,XX +XXX,XX @@ void apple_gfx_common_realize(AppleGFXState *s, PGDeviceDescriptor *desc,
214
@@ -XXX,XX +XXX,XX @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev,
213
s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc
215
port:0
214
port:0 serialNum:1234];
216
serialNum:next_pgdisplay_serial_num++];
215
[disp_desc release];
217
[disp_desc release];
216
- s->pgdisp.modeList = apple_gfx_prepare_display_mode_array();
218
- s->pgdisp.modeList = apple_gfx_prepare_display_mode_array();
217
+
219
+
218
+ if (s->display_modes != NULL && s->num_display_modes > 0) {
220
+ if (s->display_modes != NULL && s->num_display_modes > 0) {
219
+ trace_apple_gfx_common_realize_modes_property(s->num_display_modes);
221
+ trace_apple_gfx_common_realize_modes_property(s->num_display_modes);
...
...
222
+ }
224
+ }
223
+ s->pgdisp.modeList = mode_array =
225
+ s->pgdisp.modeList = mode_array =
224
+ apple_gfx_create_display_mode_array(display_modes, num_display_modes);
226
+ apple_gfx_create_display_mode_array(display_modes, num_display_modes);
225
+ [mode_array release];
227
+ [mode_array release];
226
228
227
s->con = graphic_console_init(NULL, 0, &apple_gfx_fb_ops, s);
229
s->con = graphic_console_init(dev, 0, &apple_gfx_fb_ops, s);
228
230
return true;
229
qatomic_set(&s->cursor_show, true);
230
}
231
}
231
+
232
+
232
+/* ------ Display mode list device property ------ */
233
+/* ------ Display mode list device property ------ */
233
+
234
+
234
+static void apple_gfx_get_display_mode(Object *obj, Visitor *v,
235
+static void apple_gfx_get_display_mode(Object *obj, Visitor *v,
...
...
259
+ const char *endptr;
260
+ const char *endptr;
260
+ g_autofree char *str = NULL;
261
+ g_autofree char *str = NULL;
261
+ int ret;
262
+ int ret;
262
+ int val;
263
+ int val;
263
+
264
+
264
+ visit_type_str(v, name, &str, errp);
265
+ if (!visit_type_str(v, name, &str, errp)) {
265
+ if (*errp) {
266
+ return;
266
+ return;
267
+ }
267
+ }
268
+
268
+
269
+ endptr = str;
269
+ endptr = str;
270
+
270
+
...
...
324
+apple_gfx_display_mode(uint32_t mode_idx, uint16_t width_px, uint16_t height_px) "mode %2"PRIu32": %4"PRIu16"x%4"PRIu16
324
+apple_gfx_display_mode(uint32_t mode_idx, uint16_t width_px, uint16_t height_px) "mode %2"PRIu32": %4"PRIu16"x%4"PRIu16
325
325
326
# apple-gfx-mmio.m
326
# apple-gfx-mmio.m
327
apple_gfx_mmio_iosfc_read(uint64_t offset, uint64_t res) "offset=0x%"PRIx64" res=0x%"PRIx64
327
apple_gfx_mmio_iosfc_read(uint64_t offset, uint64_t res) "offset=0x%"PRIx64" res=0x%"PRIx64
328
--
328
--
329
2.39.3 (Apple Git-145)
329
2.39.5 (Apple Git-154)
diff view generated by jsdifflib
...
...
9
apple-gfx should be relatively minor and manageable in my spare time
9
apple-gfx should be relatively minor and manageable in my spare time
10
beyond that. I may have to remove myself from more general HVF duties
10
beyond that. I may have to remove myself from more general HVF duties
11
once the contract runs out if it's more than I can manage.
11
once the contract runs out if it's more than I can manage.
12
12
13
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
13
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
14
Reviewed-by: Roman Bolshakov <rbolshakov@ddn.com>
14
---
15
---
15
MAINTAINERS | 7 +++++++
16
MAINTAINERS | 7 +++++++
16
1 file changed, 7 insertions(+)
17
1 file changed, 7 insertions(+)
17
18
18
diff --git a/MAINTAINERS b/MAINTAINERS
19
diff --git a/MAINTAINERS b/MAINTAINERS
...
...
46
+
47
+
47
PIIX4 South Bridge (i82371AB)
48
PIIX4 South Bridge (i82371AB)
48
M: Hervé Poussineau <hpoussin@reactos.org>
49
M: Hervé Poussineau <hpoussin@reactos.org>
49
M: Philippe Mathieu-Daudé <philmd@linaro.org>
50
M: Philippe Mathieu-Daudé <philmd@linaro.org>
50
--
51
--
51
2.39.3 (Apple Git-145)
52
2.39.5 (Apple Git-154)
52
53
53
54
diff view generated by jsdifflib
...
...
5
a single target directory.
5
a single target directory.
6
6
7
Signed-off-by: Alexander Graf <graf@amazon.com>
7
Signed-off-by: Alexander Graf <graf@amazon.com>
8
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
8
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
9
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
---
11
---
11
MAINTAINERS | 7 +++++++
12
MAINTAINERS | 7 +++++++
12
hw/Kconfig | 1 +
13
hw/Kconfig | 1 +
13
hw/meson.build | 1 +
14
hw/meson.build | 1 +
14
hw/vmapple/Kconfig | 1 +
15
hw/vmapple/Kconfig | 1 +
...
...
100
+ 'hw/vmapple',
101
+ 'hw/vmapple',
101
'hw/watchdog',
102
'hw/watchdog',
102
'hw/xen',
103
'hw/xen',
103
'hw/gpio',
104
'hw/gpio',
104
--
105
--
105
2.39.3 (Apple Git-145)
106
2.39.5 (Apple Git-154)
diff view generated by jsdifflib
...
...
6
Signed-off-by: Alexander Graf <graf@amazon.com>
6
Signed-off-by: Alexander Graf <graf@amazon.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
9
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
10
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
---
12
---
12
13
13
v3:
14
v3:
14
* Rebased on upstream, updated a header path
15
* Rebased on upstream, updated a header path
15
16
...
...
125
+#define TYPE_PVPANIC_MMIO_DEVICE "pvpanic-mmio"
126
+#define TYPE_PVPANIC_MMIO_DEVICE "pvpanic-mmio"
126
127
127
#define PVPANIC_IOPORT_PROP "ioport"
128
#define PVPANIC_IOPORT_PROP "ioport"
128
129
129
--
130
--
130
2.39.3 (Apple Git-145)
131
2.39.5 (Apple Git-154)
131
132
132
133
diff view generated by jsdifflib
...
...
5
a full physical timer emulation, so let's just ignore those writes.
5
a full physical timer emulation, so let's just ignore those writes.
6
6
7
Signed-off-by: Alexander Graf <graf@amazon.com>
7
Signed-off-by: Alexander Graf <graf@amazon.com>
8
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
8
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
9
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
---
11
---
11
target/arm/hvf/hvf.c | 9 +++++++++
12
target/arm/hvf/hvf.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
13
1 file changed, 9 insertions(+)
13
14
14
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
15
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
...
...
44
+ return 0;
45
+ return 0;
45
case SYSREG_OSDLR_EL1:
46
case SYSREG_OSDLR_EL1:
46
/* Dummy register */
47
/* Dummy register */
47
return 0;
48
return 0;
48
--
49
--
49
2.39.3 (Apple Git-145)
50
2.39.5 (Apple Git-154)
diff view generated by jsdifflib
...
...
7
In this mode, GPEX will export more IRQ lines, one for each device.
7
In this mode, GPEX will export more IRQ lines, one for each device.
8
8
9
Signed-off-by: Alexander Graf <graf@amazon.com>
9
Signed-off-by: Alexander Graf <graf@amazon.com>
10
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
10
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
11
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
12
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
12
---
13
---
13
14
14
v4:
15
v4:
15
16
16
* Turned pair of IRQ arrays into array of structs.
17
* Turned pair of IRQ arrays into array of structs.
17
* Simplified swizzling logic selection.
18
* Simplified swizzling logic selection.
19
20
v12:
21
22
* Fixed uses of deleted GPEX_NUM_IRQS constant that have been
23
added to QEMU since this patch was originally written.
18
24
19
hw/arm/sbsa-ref.c | 2 +-
25
hw/arm/sbsa-ref.c | 2 +-
20
hw/arm/virt.c | 2 +-
26
hw/arm/virt.c | 2 +-
21
hw/i386/microvm.c | 2 +-
27
hw/i386/microvm.c | 2 +-
22
hw/loongarch/virt.c | 2 +-
28
hw/loongarch/virt.c | 12 +++++------
23
hw/mips/loongson3_virt.c | 2 +-
29
hw/mips/loongson3_virt.c | 2 +-
24
hw/openrisc/virt.c | 12 +++++------
30
hw/openrisc/virt.c | 12 +++++------
25
hw/pci-host/gpex.c | 43 ++++++++++++++++++++++++++++++--------
31
hw/pci-host/gpex.c | 43 ++++++++++++++++++++++++++++++--------
26
hw/riscv/virt.c | 12 +++++------
32
hw/riscv/virt.c | 12 +++++------
33
hw/xen/xen-pvh-common.c | 2 +-
27
hw/xtensa/virt.c | 2 +-
34
hw/xtensa/virt.c | 2 +-
28
include/hw/pci-host/gpex.h | 7 +++----
35
include/hw/pci-host/gpex.h | 7 +++----
29
10 files changed, 55 insertions(+), 31 deletions(-)
36
11 files changed, 61 insertions(+), 37 deletions(-)
30
37
31
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
38
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
32
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/sbsa-ref.c
40
--- a/hw/arm/sbsa-ref.c
34
+++ b/hw/arm/sbsa-ref.c
41
+++ b/hw/arm/sbsa-ref.c
...
...
69
}
76
}
70
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
77
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
71
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/loongarch/virt.c
79
--- a/hw/loongarch/virt.c
73
+++ b/hw/loongarch/virt.c
80
+++ b/hw/loongarch/virt.c
81
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms,
82
{
83
int pin, dev;
84
uint32_t irq_map_stride = 0;
85
- uint32_t full_irq_map[GPEX_NUM_IRQS *GPEX_NUM_IRQS * 10] = {};
86
+ uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS * 10] = {};
87
uint32_t *irq_map = full_irq_map;
88
const MachineState *ms = MACHINE(lvms);
89
90
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms,
91
* to wrap to any number of devices.
92
*/
93
94
- for (dev = 0; dev < GPEX_NUM_IRQS; dev++) {
95
+ for (dev = 0; dev < PCI_NUM_PINS; dev++) {
96
int devfn = dev * 0x8;
97
98
- for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
99
- int irq_nr = 16 + ((pin + PCI_SLOT(devfn)) % GPEX_NUM_IRQS);
100
+ for (pin = 0; pin < PCI_NUM_PINS; pin++) {
101
+ int irq_nr = 16 + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS);
102
int i = 0;
103
104
/* Fill PCI address cells */
105
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms,
106
107
108
qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map,
109
- GPEX_NUM_IRQS * GPEX_NUM_IRQS *
110
+ PCI_NUM_PINS * PCI_NUM_PINS *
111
irq_map_stride * sizeof(uint32_t));
112
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupt-map-mask",
113
0x1800, 0, 0, 0x7);
74
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
114
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
75
memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE,
115
memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE,
76
pio_alias);
116
pio_alias);
77
117
78
- for (i = 0; i < GPEX_NUM_IRQS; i++) {
118
- for (i = 0; i < GPEX_NUM_IRQS; i++) {
...
...
303
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, pio_base);
343
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, pio_base);
304
344
305
- for (i = 0; i < GPEX_NUM_IRQS; i++) {
345
- for (i = 0; i < GPEX_NUM_IRQS; i++) {
306
+ for (i = 0; i < PCI_NUM_PINS; i++) {
346
+ for (i = 0; i < PCI_NUM_PINS; i++) {
307
irq = qdev_get_gpio_in(irqchip, PCIE_IRQ + i);
347
irq = qdev_get_gpio_in(irqchip, PCIE_IRQ + i);
348
349
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
350
diff --git a/hw/xen/xen-pvh-common.c b/hw/xen/xen-pvh-common.c
351
index XXXXXXX..XXXXXXX 100644
352
--- a/hw/xen/xen-pvh-common.c
353
+++ b/hw/xen/xen-pvh-common.c
354
@@ -XXX,XX +XXX,XX @@ static inline void xenpvh_gpex_init(XenPVHMachineState *s,
355
*/
356
assert(xpc->set_pci_intx_irq);
357
358
- for (i = 0; i < GPEX_NUM_IRQS; i++) {
359
+ for (i = 0; i < PCI_NUM_PINS; i++) {
360
qemu_irq irq = qemu_allocate_irq(xpc->set_pci_intx_irq, s, i);
308
361
309
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
362
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
310
diff --git a/hw/xtensa/virt.c b/hw/xtensa/virt.c
363
diff --git a/hw/xtensa/virt.c b/hw/xtensa/virt.c
311
index XXXXXXX..XXXXXXX 100644
364
index XXXXXXX..XXXXXXX 100644
312
--- a/hw/xtensa/virt.c
365
--- a/hw/xtensa/virt.c
...
...
351
+ uint8_t num_irqs;
404
+ uint8_t num_irqs;
352
405
353
bool allow_unmapped_accesses;
406
bool allow_unmapped_accesses;
354
407
355
--
408
--
356
2.39.3 (Apple Git-145)
409
2.39.5 (Apple Git-154)
diff view generated by jsdifflib
...
...
6
6
7
Add device emulation for this device model.
7
Add device emulation for this device model.
8
8
9
Signed-off-by: Alexander Graf <graf@amazon.com>
9
Signed-off-by: Alexander Graf <graf@amazon.com>
10
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
10
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
11
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
12
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
---
13
---
12
14
13
v3:
15
v3:
14
16
15
* Rebased on latest upstream and fixed minor breakages.
17
* Rebased on latest upstream and fixed minor breakages.
...
...
28
30
29
v7:
31
v7:
30
32
31
* Coding style tweaks.
33
* Coding style tweaks.
32
34
35
v8:
36
37
* Further improved logging of guest errors.
38
39
v9:
40
41
* Replaced a use of cpu_physical_memory_write with dma_memory_write.
42
* Dropped unnecessary use of ternary operator for bool -> 0/1.
43
44
v10:
45
46
* Code style and comment improvements.
47
33
hw/vmapple/Kconfig | 2 +
48
hw/vmapple/Kconfig | 2 +
34
hw/vmapple/aes.c | 578 +++++++++++++++++++++++++++++++++++
49
hw/vmapple/aes.c | 581 +++++++++++++++++++++++++++++++++++
35
hw/vmapple/meson.build | 1 +
50
hw/vmapple/meson.build | 1 +
36
hw/vmapple/trace-events | 14 +
51
hw/vmapple/trace-events | 14 +
37
include/hw/vmapple/vmapple.h | 17 ++
52
include/hw/vmapple/vmapple.h | 17 +
38
include/qemu/cutils.h | 15 +
53
include/qemu/cutils.h | 15 +
39
util/hexdump.c | 18 ++
54
util/hexdump.c | 18 ++
40
7 files changed, 645 insertions(+)
55
7 files changed, 648 insertions(+)
41
create mode 100644 hw/vmapple/aes.c
56
create mode 100644 hw/vmapple/aes.c
42
create mode 100644 include/hw/vmapple/vmapple.h
57
create mode 100644 include/hw/vmapple/vmapple.h
43
58
44
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
59
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
45
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
...
...
243
+ s->fifo[s->fifo_idx++] = val;
258
+ s->fifo[s->fifo_idx++] = val;
244
+}
259
+}
245
+
260
+
246
+static bool has_payload(AESState *s, uint32_t elems)
261
+static bool has_payload(AESState *s, uint32_t elems)
247
+{
262
+{
248
+ return s->fifo_idx >= (elems + 1);
263
+ return s->fifo_idx >= elems + 1;
249
+}
264
+}
250
+
265
+
251
+static bool cmd_key(AESState *s)
266
+static bool cmd_key(AESState *s)
252
+{
267
+{
253
+ uint32_t cmd = s->fifo[0];
268
+ uint32_t cmd = s->fifo[0];
...
...
346
+ return false;
361
+ return false;
347
+ }
362
+ }
348
+
363
+
349
+ if (ctxt_key >= ARRAY_SIZE(s->key) ||
364
+ if (ctxt_key >= ARRAY_SIZE(s->key) ||
350
+ ctxt_iv >= ARRAY_SIZE(s->iv)) {
365
+ ctxt_iv >= ARRAY_SIZE(s->iv)) {
351
+ /* Invalid input */
352
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid key or iv\n", __func__);
366
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid key or iv\n", __func__);
353
+ return false;
367
+ return false;
354
+ }
368
+ }
355
+
369
+
356
+ src = g_byte_array_sized_new(len);
370
+ src = g_byte_array_sized_new(len);
...
...
424
+static bool cmd_store_iv(AESState *s)
438
+static bool cmd_store_iv(AESState *s)
425
+{
439
+{
426
+ uint32_t cmd = s->fifo[0];
440
+ uint32_t cmd = s->fifo[0];
427
+ uint32_t ctxt = (cmd & CMD_IV_CONTEXT_MASK) >> CMD_IV_CONTEXT_SHIFT;
441
+ uint32_t ctxt = (cmd & CMD_IV_CONTEXT_MASK) >> CMD_IV_CONTEXT_SHIFT;
428
+ uint64_t addr = s->fifo[1];
442
+ uint64_t addr = s->fifo[1];
443
+ MemTxResult dma_result;
429
+
444
+
430
+ if (!has_payload(s, 1)) {
445
+ if (!has_payload(s, 1)) {
431
+ /* wait for payload */
432
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
446
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
433
+ return false;
447
+ return false;
434
+ }
448
+ }
435
+
449
+
436
+ if (ctxt >= ARRAY_SIZE(s->iv)) {
450
+ if (ctxt >= ARRAY_SIZE(s->iv)) {
437
+ /* Invalid context selected */
451
+ qemu_log_mask(LOG_GUEST_ERROR,
452
+ "%s: Invalid context. ctxt = %u, allowed: 0..%zu\n",
453
+ __func__, ctxt, ARRAY_SIZE(s->iv) - 1);
438
+ return false;
454
+ return false;
439
+ }
455
+ }
440
+
456
+
441
+ addr |= ((uint64_t)cmd << 32) & 0xff00000000ULL;
457
+ addr |= ((uint64_t)cmd << 32) & 0xff00000000ULL;
442
+ cpu_physical_memory_write(addr, &s->iv[ctxt].iv, sizeof(s->iv[ctxt].iv));
458
+ dma_result = dma_memory_write(&address_space_memory, addr,
459
+ &s->iv[ctxt].iv, sizeof(s->iv[ctxt].iv),
460
+ MEMTXATTRS_UNSPECIFIED);
443
+
461
+
444
+ trace_aes_cmd_store_iv(ctxt, addr, s->iv[ctxt].iv[0], s->iv[ctxt].iv[1],
462
+ trace_aes_cmd_store_iv(ctxt, addr, s->iv[ctxt].iv[0], s->iv[ctxt].iv[1],
445
+ s->iv[ctxt].iv[2], s->iv[ctxt].iv[3]);
463
+ s->iv[ctxt].iv[2], s->iv[ctxt].iv[3]);
446
+
464
+
447
+ return true;
465
+ return dma_result == MEMTX_OK;
448
+}
466
+}
449
+
467
+
450
+static bool cmd_flag(AESState *s)
468
+static bool cmd_flag(AESState *s)
451
+{
469
+{
452
+ uint32_t cmd = s->fifo[0];
470
+ uint32_t cmd = s->fifo[0];
...
...
496
+
514
+
497
+ if (success) {
515
+ if (success) {
498
+ s->fifo_idx = 0;
516
+ s->fifo_idx = 0;
499
+ }
517
+ }
500
+
518
+
501
+ trace_aes_fifo_process(cmd, success ? 1 : 0);
519
+ trace_aes_fifo_process(cmd, success);
502
+}
520
+}
503
+
521
+
504
+static void aes1_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
522
+static void aes1_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
505
+{
523
+{
506
+ AESState *s = opaque;
524
+ AESState *s = opaque;
...
...
652
+aes_cmd_key_select_new(uint32_t ctx, uint32_t key_len, const char *direction, const char *cipher) "[%d] Selecting new key size=%d to %scrypt with %s"
670
+aes_cmd_key_select_new(uint32_t ctx, uint32_t key_len, const char *direction, const char *cipher) "[%d] Selecting new key size=%d to %scrypt with %s"
653
+aes_cmd_iv(uint32_t ctx, uint32_t iv0, uint32_t iv1, uint32_t iv2, uint32_t iv3) "[%d] 0x%08x 0x%08x 0x%08x 0x%08x"
671
+aes_cmd_iv(uint32_t ctx, uint32_t iv0, uint32_t iv1, uint32_t iv2, uint32_t iv3) "[%d] 0x%08x 0x%08x 0x%08x 0x%08x"
654
+aes_cmd_data(uint32_t key, uint32_t iv, uint64_t src, uint64_t dst, uint32_t len) "[key=%d iv=%d] src=0x%"PRIx64" dst=0x%"PRIx64" len=0x%x"
672
+aes_cmd_data(uint32_t key, uint32_t iv, uint64_t src, uint64_t dst, uint32_t len) "[key=%d iv=%d] src=0x%"PRIx64" dst=0x%"PRIx64" len=0x%x"
655
+aes_cmd_store_iv(uint32_t ctx, uint64_t addr, uint32_t iv0, uint32_t iv1, uint32_t iv2, uint32_t iv3) "[%d] addr=0x%"PRIx64"x -> 0x%08x 0x%08x 0x%08x 0x%08x"
673
+aes_cmd_store_iv(uint32_t ctx, uint64_t addr, uint32_t iv0, uint32_t iv1, uint32_t iv2, uint32_t iv3) "[%d] addr=0x%"PRIx64"x -> 0x%08x 0x%08x 0x%08x 0x%08x"
656
+aes_cmd_flag(uint32_t raise, uint32_t flag_info) "raise=%d flag_info=0x%x"
674
+aes_cmd_flag(uint32_t raise, uint32_t flag_info) "raise=%d flag_info=0x%x"
657
+aes_fifo_process(uint32_t cmd, uint32_t success) "cmd=%d success=%d"
675
+aes_fifo_process(uint32_t cmd, bool success) "cmd=%d success=%d"
658
+aes_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
676
+aes_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
659
+aes_2_read(uint64_t offset, uint64_t res) "offset=0x%"PRIx64" res=0x%"PRIx64
677
+aes_2_read(uint64_t offset, uint64_t res) "offset=0x%"PRIx64" res=0x%"PRIx64
660
+aes_2_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
678
+aes_2_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
661
+aes_dump_data(const char *desc, const char *hex) "%s%s"
679
+aes_dump_data(const char *desc, const char *hex) "%s%s"
662
+
680
+
...
...
739
+ *(buffer++) = hexdump_nibble(val & 0xf);
757
+ *(buffer++) = hexdump_nibble(val & 0xf);
740
+ }
758
+ }
741
+ *buffer = '\0';
759
+ *buffer = '\0';
742
+}
760
+}
743
--
761
--
744
2.39.3 (Apple Git-145)
762
2.39.5 (Apple Git-154)
745
763
746
764
diff view generated by jsdifflib
...
...
8
understanding. I left out any USB OTG parts; they're only needed for
8
understanding. I left out any USB OTG parts; they're only needed for
9
guest recovery and I don't understand the protocol yet.
9
guest recovery and I don't understand the protocol yet.
10
10
11
Signed-off-by: Alexander Graf <graf@amazon.com>
11
Signed-off-by: Alexander Graf <graf@amazon.com>
12
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
12
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
13
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
14
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
13
---
15
---
14
16
15
v4:
17
v4:
16
18
17
* Moved most header code to .c, rest to vmapple.h
19
* Moved most header code to .c, rest to vmapple.h
18
* Better compliance with coding, naming, and formatting conventions.
20
* Better compliance with coding, naming, and formatting conventions.
19
21
22
v8:
23
24
* Replaced uses of cpu_physical_memory_read with dma_memory_read.
25
* Replaced an instance of g_free with g_autofree.
26
27
v9:
28
29
* Replaced uses of cpu_physical_memory_write with dma_memory_write.
30
20
hw/vmapple/Kconfig | 3 +
31
hw/vmapple/Kconfig | 3 +
21
hw/vmapple/bdif.c | 261 +++++++++++++++++++++++++++++++++++
32
hw/vmapple/bdif.c | 275 +++++++++++++++++++++++++++++++++++
22
hw/vmapple/meson.build | 1 +
33
hw/vmapple/meson.build | 1 +
23
hw/vmapple/trace-events | 5 +
34
hw/vmapple/trace-events | 5 +
24
include/hw/vmapple/vmapple.h | 2 +
35
include/hw/vmapple/vmapple.h | 2 +
25
5 files changed, 272 insertions(+)
36
5 files changed, 286 insertions(+)
26
create mode 100644 hw/vmapple/bdif.c
37
create mode 100644 hw/vmapple/bdif.c
27
38
28
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
39
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
29
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/vmapple/Kconfig
41
--- a/hw/vmapple/Kconfig
...
...
61
+#include "hw/vmapple/vmapple.h"
72
+#include "hw/vmapple/vmapple.h"
62
+#include "hw/sysbus.h"
73
+#include "hw/sysbus.h"
63
+#include "hw/block/block.h"
74
+#include "hw/block/block.h"
64
+#include "qapi/error.h"
75
+#include "qapi/error.h"
65
+#include "sysemu/block-backend.h"
76
+#include "sysemu/block-backend.h"
77
+#include "sysemu/dma.h"
66
+
78
+
67
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleBdifState, VMAPPLE_BDIF)
79
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleBdifState, VMAPPLE_BDIF)
68
+
80
+
69
+struct VMAppleBdifState {
81
+struct VMAppleBdifState {
70
+ SysBusDevice parent_obj;
82
+ SysBusDevice parent_obj;
...
...
175
+ le2cpu_reqcmd(&req->sector);
187
+ le2cpu_reqcmd(&req->sector);
176
+ le2cpu_reqcmd(&req->data);
188
+ le2cpu_reqcmd(&req->data);
177
+ le2cpu_reqcmd(&req->retval);
189
+ le2cpu_reqcmd(&req->retval);
178
+}
190
+}
179
+
191
+
180
+static void vblk_cmd(uint64_t devid, BlockBackend *blk, uint64_t value,
192
+static void vblk_cmd(uint64_t devid, BlockBackend *blk, uint64_t gp_addr,
181
+ uint64_t static_off)
193
+ uint64_t static_off)
182
+{
194
+{
183
+ VblkReq req;
195
+ VblkReq req;
184
+ VblkSector sector;
196
+ VblkSector sector;
185
+ uint64_t off = 0;
197
+ uint64_t off = 0;
186
+ char *buf = NULL;
198
+ g_autofree char *buf = NULL;
187
+ uint8_t ret = VBLK_RET_FAILED;
199
+ uint8_t ret = VBLK_RET_FAILED;
188
+ int r;
200
+ int r;
189
+
201
+ MemTxResult dma_result;
190
+ cpu_physical_memory_read(value, &req, sizeof(req));
202
+
203
+ dma_result = dma_memory_read(&address_space_memory, gp_addr,
204
+ &req, sizeof(req), MEMTXATTRS_UNSPECIFIED);
205
+ if (dma_result != MEMTX_OK) {
206
+ goto out;
207
+ }
208
+
191
+ le2cpu_req(&req);
209
+ le2cpu_req(&req);
192
+
210
+
193
+ if (req.sector.len != sizeof(sector)) {
211
+ if (req.sector.len != sizeof(sector)) {
194
+ ret = VBLK_RET_FAILED;
195
+ goto out;
212
+ goto out;
196
+ }
213
+ }
197
+
214
+
198
+ /* Read the vblk command */
215
+ /* Read the vblk command */
199
+ cpu_physical_memory_read(req.sector.addr, &sector, sizeof(sector));
216
+ dma_result = dma_memory_read(&address_space_memory, req.sector.addr,
217
+ &sector, sizeof(sector),
218
+ MEMTXATTRS_UNSPECIFIED);
219
+ if (dma_result != MEMTX_OK) {
220
+ goto out;
221
+ }
200
+ le2cpu_sector(&sector);
222
+ le2cpu_sector(&sector);
201
+
223
+
202
+ off = sector.sector * 512ULL + static_off;
224
+ off = sector.sector * 512ULL + static_off;
203
+
225
+
204
+ /* Sanity check that we're not allocating bogus sizes */
226
+ /* Sanity check that we're not allocating bogus sizes */
...
...
213
+ trace_bdif_vblk_read(devid == DEVID_AUX ? "aux" : "root",
235
+ trace_bdif_vblk_read(devid == DEVID_AUX ? "aux" : "root",
214
+ req.data.addr, off, req.data.len, r);
236
+ req.data.addr, off, req.data.len, r);
215
+ if (r < 0) {
237
+ if (r < 0) {
216
+ goto out;
238
+ goto out;
217
+ }
239
+ }
218
+ cpu_physical_memory_write(req.data.addr, buf, req.data.len);
240
+ dma_result = dma_memory_write(&address_space_memory, req.data.addr, buf,
219
+ ret = VBLK_RET_SUCCESS;
241
+ req.data.len, MEMTXATTRS_UNSPECIFIED);
242
+ if (dma_result == MEMTX_OK) {
243
+ ret = VBLK_RET_SUCCESS;
244
+ }
220
+ break;
245
+ break;
221
+ case VBLK_DATA_FLAGS_WRITE:
246
+ case VBLK_DATA_FLAGS_WRITE:
222
+ /* Not needed, iBoot only reads */
247
+ /* Not needed, iBoot only reads */
223
+ break;
248
+ break;
224
+ default:
249
+ default:
225
+ break;
250
+ break;
226
+ }
251
+ }
227
+
252
+
228
+out:
253
+out:
229
+ g_free(buf);
254
+ dma_memory_write(&address_space_memory, req.retval.addr, &ret, 1,
230
+ cpu_physical_memory_write(req.retval.addr, &ret, 1);
255
+ MEMTXATTRS_UNSPECIFIED);
231
+}
256
+}
232
+
257
+
233
+static void bdif_write(void *opaque, hwaddr offset,
258
+static void bdif_write(void *opaque, hwaddr offset,
234
+ uint64_t value, unsigned size)
259
+ uint64_t value, unsigned size)
235
+{
260
+{
...
...
333
358
334
+#define TYPE_VMAPPLE_BDIF "vmapple-bdif"
359
+#define TYPE_VMAPPLE_BDIF "vmapple-bdif"
335
+
360
+
336
#endif /* HW_VMAPPLE_VMAPPLE_H */
361
#endif /* HW_VMAPPLE_VMAPPLE_H */
337
--
362
--
338
2.39.3 (Apple Git-145)
363
2.39.5 (Apple Git-154)
339
364
340
365
diff view generated by jsdifflib
...
...
8
then map at the fixed location in the address space. That way, we can
8
then map at the fixed location in the address space. That way, we can
9
influence and annotate all configuration fields easily.
9
influence and annotate all configuration fields easily.
10
10
11
Signed-off-by: Alexander Graf <graf@amazon.com>
11
Signed-off-by: Alexander Graf <graf@amazon.com>
12
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
12
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
13
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
14
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
13
---
15
---
14
16
15
v3:
17
v3:
16
18
17
* Replaced legacy device reset method with Resettable method
19
* Replaced legacy device reset method with Resettable method
...
...
28
30
29
v7:
31
v7:
30
32
31
* Changed error messages for overrun of properties with
33
* Changed error messages for overrun of properties with
32
fixed-length strings to be more useful to users than developers.
34
fixed-length strings to be more useful to users than developers.
35
36
v8:
37
38
* Consistent parenthesising of macro arguments for better safety.
39
40
v10:
41
42
* Slightly tidier error reporting for overlong property values.
33
43
34
hw/vmapple/Kconfig | 3 +
44
hw/vmapple/Kconfig | 3 +
35
hw/vmapple/cfg.c | 196 +++++++++++++++++++++++++++++++++++
45
hw/vmapple/cfg.c | 196 +++++++++++++++++++++++++++++++++++
36
hw/vmapple/meson.build | 1 +
46
hw/vmapple/meson.build | 1 +
37
include/hw/vmapple/vmapple.h | 2 +
47
include/hw/vmapple/vmapple.h | 2 +
...
...
135
+static bool set_fixlen_property_or_error(char *restrict dst,
145
+static bool set_fixlen_property_or_error(char *restrict dst,
136
+ const char *restrict src,
146
+ const char *restrict src,
137
+ size_t dst_size, Error **errp,
147
+ size_t dst_size, Error **errp,
138
+ const char *property_name)
148
+ const char *property_name)
139
+{
149
+{
150
+ ERRP_GUARD();
140
+ size_t len;
151
+ size_t len;
141
+
152
+
142
+ len = g_strlcpy(dst, src, dst_size);
153
+ len = g_strlcpy(dst, src, dst_size);
143
+ if (len < dst_size) { /* len does not count nul terminator */
154
+ if (len < dst_size) { /* len does not count nul terminator */
144
+ return true;
155
+ return true;
145
+ }
156
+ }
146
+
157
+
147
+ error_setg(errp,
158
+ error_setg(errp, "Provided value too long for property '%s'", property_name);
148
+ "Failed to set property '%s' on VMApple 'cfg' device: length "
159
+ error_append_hint(errp, "length (%zu) exceeds maximum of %zu\n",
149
+ "(%zu) exceeds maximum of %zu",
160
+ len, dst_size - 1);
150
+ property_name, len, dst_size - 1);
151
+ return false;
161
+ return false;
152
+}
162
+}
153
+
163
+
154
+#define set_fixlen_property_or_return(dst_array, src, errp, property_name) \
164
+#define set_fixlen_property_or_return(dst_array, src, errp, property_name) \
155
+ do { \
165
+ do { \
156
+ if (!set_fixlen_property_or_error((dst_array), (src), \
166
+ if (!set_fixlen_property_or_error((dst_array), (src), \
157
+ ARRAY_SIZE(dst_array), \
167
+ ARRAY_SIZE(dst_array), \
158
+ (errp), property_name)) { \
168
+ (errp), (property_name))) { \
159
+ return; \
169
+ return; \
160
+ } \
170
+ } \
161
+ } while (0)
171
+ } while (0)
162
+
172
+
163
+static void vmapple_cfg_realize(DeviceState *dev, Error **errp)
173
+static void vmapple_cfg_realize(DeviceState *dev, Error **errp)
...
...
269
279
270
+#define TYPE_VMAPPLE_CFG "vmapple-cfg"
280
+#define TYPE_VMAPPLE_CFG "vmapple-cfg"
271
+
281
+
272
#endif /* HW_VMAPPLE_VMAPPLE_H */
282
#endif /* HW_VMAPPLE_VMAPPLE_H */
273
--
283
--
274
2.39.3 (Apple Git-145)
284
2.39.5 (Apple Git-154)
275
285
276
286
diff view generated by jsdifflib
...
...
8
This patch first creates a mechanism for virtio-blk downstream classes to
8
This patch first creates a mechanism for virtio-blk downstream classes to
9
handle unknown commands. It then creates such a downstream class and a new
9
handle unknown commands. It then creates such a downstream class and a new
10
vmapple-virtio-blk-pci class which support the additional apple type config
10
vmapple-virtio-blk-pci class which support the additional apple type config
11
identifier as well as the barrier command.
11
identifier as well as the barrier command.
12
12
13
It then exposes 2 subclasses from that that we can use to expose root and
13
The 'aux' or 'root' device type are selected using the 'variant' property.
14
aux virtio-blk devices: "vmapple-virtio-root" and "vmapple-virtio-aux".
15
14
16
Signed-off-by: Alexander Graf <graf@amazon.com>
15
Signed-off-by: Alexander Graf <graf@amazon.com>
17
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
16
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
18
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
17
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
18
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
19
---
19
---
20
20
21
v4:
21
v4:
22
22
23
* Use recommended object type declaration pattern.
23
* Use recommended object type declaration pattern.
...
...
27
v5:
27
v5:
28
28
29
* Corrected handling of potentially unaligned writes to virtio config area.
29
* Corrected handling of potentially unaligned writes to virtio config area.
30
* Simplified passing through device variant type to subobject.
30
* Simplified passing through device variant type to subobject.
31
31
32
hw/block/virtio-blk.c | 19 ++-
32
v9:
33
hw/vmapple/Kconfig | 3 +
33
34
hw/vmapple/meson.build | 1 +
34
* Correctly specify class_size for VMAppleVirtIOBlkClass
35
hw/vmapple/virtio-blk.c | 226 +++++++++++++++++++++++++++++++++
35
36
include/hw/pci/pci_ids.h | 1 +
36
v10:
37
include/hw/virtio/virtio-blk.h | 12 +-
37
38
include/hw/vmapple/vmapple.h | 4 +
38
* Folded v9 patch 16/16 into this one, changing the device type design to
39
7 files changed, 261 insertions(+), 5 deletions(-)
39
provide a single device type with a variant property instead of 2 different
40
subtypes for aux and root volumes.
41
* Tidied up error reporting for the variant property.
42
43
hw/block/virtio-blk.c | 19 ++-
44
hw/core/qdev-properties-system.c | 8 ++
45
hw/vmapple/Kconfig | 3 +
46
hw/vmapple/meson.build | 1 +
47
hw/vmapple/virtio-blk.c | 205 ++++++++++++++++++++++++++++
48
include/hw/pci/pci_ids.h | 1 +
49
include/hw/qdev-properties-system.h | 5 +
50
include/hw/virtio/virtio-blk.h | 12 +-
51
include/hw/vmapple/vmapple.h | 2 +
52
qapi/virtio.json | 14 ++
53
10 files changed, 265 insertions(+), 5 deletions(-)
40
create mode 100644 hw/vmapple/virtio-blk.c
54
create mode 100644 hw/vmapple/virtio-blk.c
41
55
42
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
56
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
43
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/block/virtio-blk.c
58
--- a/hw/block/virtio-blk.c
...
...
85
.class_init = virtio_blk_class_init,
99
.class_init = virtio_blk_class_init,
86
+ .class_size = sizeof(VirtIOBlkClass),
100
+ .class_size = sizeof(VirtIOBlkClass),
87
};
101
};
88
102
89
static void virtio_register_types(void)
103
static void virtio_register_types(void)
104
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/core/qdev-properties-system.c
107
+++ b/hw/core/qdev-properties-system.c
108
@@ -XXX,XX +XXX,XX @@ const PropertyInfo qdev_prop_iothread_vq_mapping_list = {
109
.set = set_iothread_vq_mapping_list,
110
.release = release_iothread_vq_mapping_list,
111
};
112
+
113
+const PropertyInfo qdev_prop_vmapple_virtio_blk_variant = {
114
+ .name = "VMAppleVirtioBlkVariant",
115
+ .enum_table = &VMAppleVirtioBlkVariant_lookup,
116
+ .get = qdev_propinfo_get_enum,
117
+ .set = qdev_propinfo_set_enum,
118
+ .set_default_value = qdev_propinfo_set_default_value_enum,
119
+};
90
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
120
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
91
index XXXXXXX..XXXXXXX 100644
121
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/vmapple/Kconfig
122
--- a/hw/vmapple/Kconfig
93
+++ b/hw/vmapple/Kconfig
123
+++ b/hw/vmapple/Kconfig
94
@@ -XXX,XX +XXX,XX @@ config VMAPPLE_BDIF
124
@@ -XXX,XX +XXX,XX @@ config VMAPPLE_BDIF
...
...
137
+#include "qemu/bswap.h"
167
+#include "qemu/bswap.h"
138
+#include "qemu/log.h"
168
+#include "qemu/log.h"
139
+#include "qemu/module.h"
169
+#include "qemu/module.h"
140
+#include "qapi/error.h"
170
+#include "qapi/error.h"
141
+
171
+
172
+#define TYPE_VMAPPLE_VIRTIO_BLK "vmapple-virtio-blk"
142
+OBJECT_DECLARE_TYPE(VMAppleVirtIOBlk, VMAppleVirtIOBlkClass, VMAPPLE_VIRTIO_BLK)
173
+OBJECT_DECLARE_TYPE(VMAppleVirtIOBlk, VMAppleVirtIOBlkClass, VMAPPLE_VIRTIO_BLK)
143
+
174
+
144
+typedef struct VMAppleVirtIOBlkClass {
175
+typedef struct VMAppleVirtIOBlkClass {
145
+ VirtIOBlkClass parent;
176
+ VirtIOBlkClass parent;
146
+
177
+
...
...
154
+} VMAppleVirtIOBlk;
185
+} VMAppleVirtIOBlk;
155
+
186
+
156
+/*
187
+/*
157
+ * vmapple-virtio-blk-pci: This extends VirtioPCIProxy.
188
+ * vmapple-virtio-blk-pci: This extends VirtioPCIProxy.
158
+ */
189
+ */
159
+#define TYPE_VMAPPLE_VIRTIO_BLK_PCI "vmapple-virtio-blk-pci-base"
160
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleVirtIOBlkPCI, VMAPPLE_VIRTIO_BLK_PCI)
190
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleVirtIOBlkPCI, VMAPPLE_VIRTIO_BLK_PCI)
161
+
191
+
162
+#define VIRTIO_BLK_T_APPLE_BARRIER 0x10000
192
+#define VIRTIO_BLK_T_APPLE_BARRIER 0x10000
163
+
164
+#define VIRTIO_APPLE_TYPE_ROOT 1
165
+#define VIRTIO_APPLE_TYPE_AUX 2
166
+
193
+
167
+static bool vmapple_virtio_blk_handle_unknown_request(VirtIOBlockReq *req,
194
+static bool vmapple_virtio_blk_handle_unknown_request(VirtIOBlockReq *req,
168
+ MultiReqBuffer *mrb,
195
+ MultiReqBuffer *mrb,
169
+ uint32_t type)
196
+ uint32_t type)
170
+{
197
+{
...
...
213
+
240
+
214
+static const TypeInfo vmapple_virtio_blk_info = {
241
+static const TypeInfo vmapple_virtio_blk_info = {
215
+ .name = TYPE_VMAPPLE_VIRTIO_BLK,
242
+ .name = TYPE_VMAPPLE_VIRTIO_BLK,
216
+ .parent = TYPE_VIRTIO_BLK,
243
+ .parent = TYPE_VIRTIO_BLK,
217
+ .instance_size = sizeof(VMAppleVirtIOBlk),
244
+ .instance_size = sizeof(VMAppleVirtIOBlk),
245
+ .class_size = sizeof(VMAppleVirtIOBlkClass),
218
+ .class_init = vmapple_virtio_blk_class_init,
246
+ .class_init = vmapple_virtio_blk_class_init,
219
+};
247
+};
220
+
248
+
221
+/* PCI Devices */
249
+/* PCI Devices */
222
+
250
+
223
+struct VMAppleVirtIOBlkPCI {
251
+struct VMAppleVirtIOBlkPCI {
224
+ VirtIOPCIProxy parent_obj;
252
+ VirtIOPCIProxy parent_obj;
225
+ VMAppleVirtIOBlk vdev;
253
+ VMAppleVirtIOBlk vdev;
226
+ uint32_t apple_type;
254
+ VMAppleVirtioBlkVariant variant;
227
+};
255
+};
228
+
256
+
229
+
257
+
230
+static Property vmapple_virtio_blk_pci_properties[] = {
258
+static Property vmapple_virtio_blk_pci_properties[] = {
231
+ DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
259
+ DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
232
+ DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
260
+ DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
233
+ VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
261
+ VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
234
+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
262
+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
235
+ DEV_NVECTORS_UNSPECIFIED),
263
+ DEV_NVECTORS_UNSPECIFIED),
264
+ DEFINE_PROP_VMAPPLE_VIRTIO_BLK_VARIANT("variant", VMAppleVirtIOBlkPCI, variant,
265
+ VM_APPLE_VIRTIO_BLK_VARIANT_UNSPECIFIED),
236
+ DEFINE_PROP_END_OF_LIST(),
266
+ DEFINE_PROP_END_OF_LIST(),
237
+};
267
+};
238
+
268
+
239
+static void vmapple_virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
269
+static void vmapple_virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
240
+{
270
+{
271
+ ERRP_GUARD();
241
+ VMAppleVirtIOBlkPCI *dev = VMAPPLE_VIRTIO_BLK_PCI(vpci_dev);
272
+ VMAppleVirtIOBlkPCI *dev = VMAPPLE_VIRTIO_BLK_PCI(vpci_dev);
242
+ DeviceState *vdev = DEVICE(&dev->vdev);
273
+ DeviceState *vdev = DEVICE(&dev->vdev);
243
+ VirtIOBlkConf *conf = &dev->vdev.parent_obj.conf;
274
+ VirtIOBlkConf *conf = &dev->vdev.parent_obj.conf;
275
+
276
+ if (dev->variant == VM_APPLE_VIRTIO_BLK_VARIANT_UNSPECIFIED) {
277
+ error_setg(errp, "vmapple virtio block device variant unspecified");
278
+ error_append_hint(errp,
279
+ "Variant property must be set to 'aux' or 'root'.\n"
280
+ "Use a regular virtio-blk-pci device instead when "
281
+ "neither is applicaple.\n");
282
+ return;
283
+ }
244
+
284
+
245
+ if (conf->num_queues == VIRTIO_BLK_AUTO_NUM_QUEUES) {
285
+ if (conf->num_queues == VIRTIO_BLK_AUTO_NUM_QUEUES) {
246
+ conf->num_queues = virtio_pci_optimal_num_queues(0);
286
+ conf->num_queues = virtio_pci_optimal_num_queues(0);
247
+ }
287
+ }
248
+
288
+
...
...
255
+ * Let's just expose the feature so the rest of the virtio-blk logic
295
+ * Let's just expose the feature so the rest of the virtio-blk logic
256
+ * allocates enough space for us. The guest will ignore zones anyway.
296
+ * allocates enough space for us. The guest will ignore zones anyway.
257
+ */
297
+ */
258
+ virtio_add_feature(&dev->vdev.parent_obj.host_features, VIRTIO_BLK_F_ZONED);
298
+ virtio_add_feature(&dev->vdev.parent_obj.host_features, VIRTIO_BLK_F_ZONED);
259
+ /* Propagate the apple type down to the virtio-blk device */
299
+ /* Propagate the apple type down to the virtio-blk device */
260
+ dev->vdev.apple_type = dev->apple_type;
300
+ dev->vdev.apple_type = dev->variant;
261
+ /* and spawn the virtio-blk device */
301
+ /* and spawn the virtio-blk device */
262
+ qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
302
+ qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
263
+
303
+
264
+ /*
304
+ /*
265
+ * The virtio-pci machinery adjusts its vendor/device ID based on whether
305
+ * The virtio-pci machinery adjusts its vendor/device ID based on whether
...
...
293
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
333
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
294
+ TYPE_VMAPPLE_VIRTIO_BLK);
334
+ TYPE_VMAPPLE_VIRTIO_BLK);
295
+}
335
+}
296
+
336
+
297
+static const VirtioPCIDeviceTypeInfo vmapple_virtio_blk_pci_info = {
337
+static const VirtioPCIDeviceTypeInfo vmapple_virtio_blk_pci_info = {
298
+ .base_name = TYPE_VMAPPLE_VIRTIO_BLK_PCI,
338
+ .generic_name = TYPE_VMAPPLE_VIRTIO_BLK_PCI,
299
+ .generic_name = "vmapple-virtio-blk-pci",
300
+ .instance_size = sizeof(VMAppleVirtIOBlkPCI),
339
+ .instance_size = sizeof(VMAppleVirtIOBlkPCI),
301
+ .instance_init = vmapple_virtio_blk_pci_instance_init,
340
+ .instance_init = vmapple_virtio_blk_pci_instance_init,
302
+ .class_init = vmapple_virtio_blk_pci_class_init,
341
+ .class_init = vmapple_virtio_blk_pci_class_init,
303
+};
342
+};
304
+
343
+
305
+static void vmapple_virtio_root_instance_init(Object *obj)
306
+{
307
+ VMAppleVirtIOBlkPCI *dev = VMAPPLE_VIRTIO_BLK_PCI(obj);
308
+
309
+ dev->apple_type = VIRTIO_APPLE_TYPE_ROOT;
310
+}
311
+
312
+static const TypeInfo vmapple_virtio_root_info = {
313
+ .name = TYPE_VMAPPLE_VIRTIO_ROOT,
314
+ .parent = "vmapple-virtio-blk-pci",
315
+ .instance_size = sizeof(VMAppleVirtIOBlkPCI),
316
+ .instance_init = vmapple_virtio_root_instance_init,
317
+};
318
+
319
+static void vmapple_virtio_aux_instance_init(Object *obj)
320
+{
321
+ VMAppleVirtIOBlkPCI *dev = VMAPPLE_VIRTIO_BLK_PCI(obj);
322
+
323
+ dev->apple_type = VIRTIO_APPLE_TYPE_AUX;
324
+}
325
+
326
+static const TypeInfo vmapple_virtio_aux_info = {
327
+ .name = TYPE_VMAPPLE_VIRTIO_AUX,
328
+ .parent = "vmapple-virtio-blk-pci",
329
+ .instance_size = sizeof(VMAppleVirtIOBlkPCI),
330
+ .instance_init = vmapple_virtio_aux_instance_init,
331
+};
332
+
333
+static void vmapple_virtio_blk_register_types(void)
344
+static void vmapple_virtio_blk_register_types(void)
334
+{
345
+{
335
+ type_register_static(&vmapple_virtio_blk_info);
346
+ type_register_static(&vmapple_virtio_blk_info);
336
+ virtio_pci_types_register(&vmapple_virtio_blk_pci_info);
347
+ virtio_pci_types_register(&vmapple_virtio_blk_pci_info);
337
+ type_register_static(&vmapple_virtio_root_info);
338
+ type_register_static(&vmapple_virtio_aux_info);
339
+}
348
+}
340
+
349
+
341
+type_init(vmapple_virtio_blk_register_types)
350
+type_init(vmapple_virtio_blk_register_types)
342
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
351
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
343
index XXXXXXX..XXXXXXX 100644
352
index XXXXXXX..XXXXXXX 100644
...
...
349
#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021
358
#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021
350
+#define PCI_DEVICE_ID_APPLE_VIRTIO_BLK 0x1a00
359
+#define PCI_DEVICE_ID_APPLE_VIRTIO_BLK 0x1a00
351
360
352
#define PCI_VENDOR_ID_SUN 0x108e
361
#define PCI_VENDOR_ID_SUN 0x108e
353
#define PCI_DEVICE_ID_SUN_EBUS 0x1000
362
#define PCI_DEVICE_ID_SUN_EBUS 0x1000
363
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
364
index XXXXXXX..XXXXXXX 100644
365
--- a/include/hw/qdev-properties-system.h
366
+++ b/include/hw/qdev-properties-system.h
367
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_pcie_link_speed;
368
extern const PropertyInfo qdev_prop_pcie_link_width;
369
extern const PropertyInfo qdev_prop_cpus390entitlement;
370
extern const PropertyInfo qdev_prop_iothread_vq_mapping_list;
371
+extern const PropertyInfo qdev_prop_vmapple_virtio_blk_variant;
372
373
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
374
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
375
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_iothread_vq_mapping_list;
376
DEFINE_PROP(_name, _state, _field, qdev_prop_iothread_vq_mapping_list, \
377
IOThreadVirtQueueMappingList *)
378
379
+#define DEFINE_PROP_VMAPPLE_VIRTIO_BLK_VARIANT(_n, _s, _f, _d) \
380
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_vmapple_virtio_blk_variant, \
381
+ VMAppleVirtioBlkVariant)
382
+
383
#endif
354
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
384
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
355
index XXXXXXX..XXXXXXX 100644
385
index XXXXXXX..XXXXXXX 100644
356
--- a/include/hw/virtio/virtio-blk.h
386
--- a/include/hw/virtio/virtio-blk.h
357
+++ b/include/hw/virtio/virtio-blk.h
387
+++ b/include/hw/virtio/virtio-blk.h
358
@@ -XXX,XX +XXX,XX @@
388
@@ -XXX,XX +XXX,XX @@
...
...
387
+++ b/include/hw/vmapple/vmapple.h
417
+++ b/include/hw/vmapple/vmapple.h
388
@@ -XXX,XX +XXX,XX @@
418
@@ -XXX,XX +XXX,XX @@
389
419
390
#define TYPE_VMAPPLE_CFG "vmapple-cfg"
420
#define TYPE_VMAPPLE_CFG "vmapple-cfg"
391
421
392
+#define TYPE_VMAPPLE_VIRTIO_BLK "vmapple-virtio-blk"
422
+#define TYPE_VMAPPLE_VIRTIO_BLK_PCI "vmapple-virtio-blk-pci"
393
+#define TYPE_VMAPPLE_VIRTIO_ROOT "vmapple-virtio-root"
394
+#define TYPE_VMAPPLE_VIRTIO_AUX "vmapple-virtio-aux"
395
+
423
+
396
#endif /* HW_VMAPPLE_VMAPPLE_H */
424
#endif /* HW_VMAPPLE_VMAPPLE_H */
425
diff --git a/qapi/virtio.json b/qapi/virtio.json
426
index XXXXXXX..XXXXXXX 100644
427
--- a/qapi/virtio.json
428
+++ b/qapi/virtio.json
429
@@ -XXX,XX +XXX,XX @@
430
##
431
{ 'enum': 'GranuleMode',
432
'data': [ '4k', '8k', '16k', '64k', 'host' ] }
433
+
434
+##
435
+# @VMAppleVirtioBlkVariant:
436
+#
437
+# @unspecified: The default, not a valid setting.
438
+#
439
+# @root: Block device holding the root volume
440
+#
441
+# @aux: Block device holding auxiliary data required for boot
442
+#
443
+# Since: 9.2
444
+##
445
+{ 'enum': 'VMAppleVirtioBlkVariant',
446
+ 'data': [ 'unspecified', 'root', 'aux' ] }
397
--
447
--
398
2.39.3 (Apple Git-145)
448
2.39.5 (Apple Git-154)
399
449
400
450
diff view generated by jsdifflib
1
The virtio_blk_free_request() function has been a 1-liner forwarding
1
The virtio_blk_free_request() function has been a 1-liner forwarding
2
to g_free() for a while now. We may as well call g_free on the request
2
to g_free() for a while now. We may as well call g_free on the request
3
pointer directly.
3
pointer directly.
4
4
5
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
5
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
6
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
---
8
---
8
hw/block/virtio-blk.c | 43 +++++++++++++++-------------------
9
hw/block/virtio-blk.c | 43 +++++++++++++++-------------------
9
hw/vmapple/virtio-blk.c | 2 +-
10
hw/vmapple/virtio-blk.c | 2 +-
10
include/hw/virtio/virtio-blk.h | 1 -
11
include/hw/virtio/virtio-blk.h | 1 -
11
3 files changed, 20 insertions(+), 26 deletions(-)
12
3 files changed, 20 insertions(+), 26 deletions(-)
...
...
221
-void virtio_blk_free_request(VirtIOBlockReq *req);
222
-void virtio_blk_free_request(VirtIOBlockReq *req);
222
void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status);
223
void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status);
223
224
224
#endif
225
#endif
225
--
226
--
226
2.39.3 (Apple Git-145)
227
2.39.5 (Apple Git-154)
diff view generated by jsdifflib
...
...
15
$ qemu-system-aarch64 -accel hvf -M vmapple,uuid=0x1234 -m 4G \
15
$ qemu-system-aarch64 -accel hvf -M vmapple,uuid=0x1234 -m 4G \
16
-bios /System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPBooter.vmapple2.bin
16
-bios /System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPBooter.vmapple2.bin
17
-drive file=aux,if=pflash,format=raw \
17
-drive file=aux,if=pflash,format=raw \
18
-drive file=root,if=pflash,format=raw \
18
-drive file=root,if=pflash,format=raw \
19
-drive file=aux,if=none,id=aux,format=raw \
19
-drive file=aux,if=none,id=aux,format=raw \
20
-device vmapple-virtio-aux,drive=aux \
20
-device vmapple-virtio-blk-pci,variant=aux,drive=aux \
21
-drive file=root,if=none,id=root,format=raw \
21
-drive file=root,if=none,id=root,format=raw \
22
-device vmapple-virtio-root,drive=root
22
-device vmapple-virtio-blk-pci,variant=root,drive=root
23
23
24
With all these in place, you should be able to see macOS booting
24
With all these in place, you should be able to see macOS booting
25
successfully.
25
successfully.
26
26
27
Known issues:
27
Known issues:
28
- Keyboard and mouse/tablet input is laggy. The reason for this is
28
- Keyboard and mouse/tablet input is laggy. The reason is a quirk/bug
29
either that macOS's XHCI driver is broken when the device/platform
29
in macOS's XHCI driver when using pin-based interrupts instead of
30
does not support MSI/MSI-X, or there's some unfortunate interplay
30
MSI-X. A workaround is in the works.
31
with Qemu's XHCI implementation in this scenario.
32
- Currently only macOS 12 guests are supported. The boot process for
31
- Currently only macOS 12 guests are supported. The boot process for
33
13+ will need further investigation and adjustment.
32
13+ will need further investigation and adjustment.
34
33
35
Signed-off-by: Alexander Graf <graf@amazon.com>
34
Signed-off-by: Alexander Graf <graf@amazon.com>
36
Co-authored-by: Phil Dennis-Jordan <phil@philjordan.eu>
35
Co-authored-by: Phil Dennis-Jordan <phil@philjordan.eu>
37
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
36
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
37
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
38
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
38
---
39
---
40
39
v3:
41
v3:
40
* Rebased on latest upstream, updated affinity and NIC creation
42
* Rebased on latest upstream, updated affinity and NIC creation
41
API usage
43
API usage
42
* Included Apple-variant virtio-blk in build dependency
44
* Included Apple-variant virtio-blk in build dependency
43
* Updated API usage for setting 'redist-region-count' array-typed property on GIC.
45
* Updated API usage for setting 'redist-region-count' array-typed property on GIC.
44
* Switched from virtio HID devices (for which macOS 12 does not contain
46
* Switched from virtio HID devices (for which macOS 12 does not contain
45
drivers) to an XHCI USB controller and USB HID devices.
47
drivers) to an XHCI USB controller and USB HID devices.
46
48
...
...
60
file for it rather than quoting its code in documentation.
62
file for it rather than quoting its code in documentation.
61
63
62
v7:
64
v7:
63
* Tiny error handling fix, un-inlined function.
65
* Tiny error handling fix, un-inlined function.
64
66
67
v8:
68
* Use object_property_add_uint64_ptr rather than defining custom UUID
69
property get/set functions.
70
71
v9:
72
* Documentation improvements
73
* Fixed variable name and struct field used during pvpanic device creation.
74
75
v10:
76
* Documentation fixup for changed virtio-blk device type.
77
* Small improvements to shell commands in documentation.
78
* Improved propagation of errors during cfg device instantiation.
79
80
v11:
81
* Quoted more strings in the documentation's shell script code.
82
83
v13:
84
* Bumped the machine type version from 9.2 to 10.0.
85
65
MAINTAINERS | 1 +
86
MAINTAINERS | 1 +
66
contrib/vmapple/uuid.sh | 9 +
87
contrib/vmapple/uuid.sh | 9 +
67
docs/system/arm/vmapple.rst | 60 ++++
88
docs/system/arm/vmapple.rst | 63 ++++
68
docs/system/target-arm.rst | 1 +
89
docs/system/target-arm.rst | 1 +
69
hw/vmapple/Kconfig | 20 ++
90
hw/vmapple/Kconfig | 20 ++
70
hw/vmapple/meson.build | 1 +
91
hw/vmapple/meson.build | 1 +
71
hw/vmapple/vmapple.c | 659 ++++++++++++++++++++++++++++++++++++
92
hw/vmapple/vmapple.c | 646 ++++++++++++++++++++++++++++++++++++
72
7 files changed, 751 insertions(+)
93
7 files changed, 741 insertions(+)
73
create mode 100755 contrib/vmapple/uuid.sh
94
create mode 100755 contrib/vmapple/uuid.sh
74
create mode 100644 docs/system/arm/vmapple.rst
95
create mode 100644 docs/system/arm/vmapple.rst
75
create mode 100644 hw/vmapple/vmapple.c
96
create mode 100644 hw/vmapple/vmapple.c
76
97
77
diff --git a/MAINTAINERS b/MAINTAINERS
98
diff --git a/MAINTAINERS b/MAINTAINERS
...
...
119
+
140
+
120
+To run the vmapple machine model, you need to
141
+To run the vmapple machine model, you need to
121
+
142
+
122
+ * Run on Apple Silicon
143
+ * Run on Apple Silicon
123
+ * Run on macOS 12.0 or above
144
+ * Run on macOS 12.0 or above
124
+ * Have an already installed copy of a Virtualization.Framework macOS 12 virtual machine. I will
145
+ * Have an already installed copy of a Virtualization.Framework macOS 12 virtual
125
+ assume that you installed it using the macosvm CLI.
146
+ machine. Note that newer versions than 12.x are currently NOT supported on
147
+ the guest side. I will assume that you installed it using the
148
+ `macosvm <https://github.com/s-u/macosvm>` CLI.
126
+
149
+
127
+First, we need to extract the UUID from the virtual machine that you installed. You can do this
150
+First, we need to extract the UUID from the virtual machine that you installed. You can do this
128
+by running the shell script in contrib/vmapple/uuid.sh on the macosvm.json file.
151
+by running the shell script in contrib/vmapple/uuid.sh on the macosvm.json file.
129
+
152
+
130
+.. code-block:: bash
153
+.. code-block:: bash
...
...
147
+to get better interactive access into the target system:
170
+to get better interactive access into the target system:
148
+
171
+
149
+.. code-block:: bash
172
+.. code-block:: bash
150
+ :caption: Example execution command line
173
+ :caption: Example execution command line
151
+
174
+
152
+ $ UUID=$(uuid.sh macosvm.json)
175
+ $ UUID="$(contrib/vmapple/uuid.sh 'macosvm.json')"
153
+ $ AVPBOOTER=/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin
176
+ $ AVPBOOTER="/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin"
154
+ $ AUX=aux.img.trimmed
177
+ $ AUX="aux.img.trimmed"
155
+ $ DISK=disk.img
178
+ $ DISK="disk.img"
156
+ $ qemu-system-aarch64 \
179
+ $ qemu-system-aarch64 \
157
+ -serial mon:stdio \
180
+ -serial mon:stdio \
158
+ -m 4G \
181
+ -m 4G \
159
+ -accel hvf \
182
+ -accel hvf \
160
+ -M vmapple,uuid=$UUID \
183
+ -M vmapple,uuid="$UUID" \
161
+ -bios $AVPBOOTER \
184
+ -bios "$AVPBOOTER" \
162
+ -drive file="$AUX",if=pflash,format=raw \
185
+ -drive file="$AUX",if=pflash,format=raw \
163
+ -drive file="$DISK",if=pflash,format=raw \
186
+ -drive file="$DISK",if=pflash,format=raw \
164
+ -drive file="$AUX",if=none,id=aux,format=raw \
187
+ -drive file="$AUX",if=none,id=aux,format=raw \
165
+ -drive file="$DISK",if=none,id=root,format=raw \
188
+ -drive file="$DISK",if=none,id=root,format=raw \
166
+ -device vmapple-virtio-aux,drive=aux \
189
+ -device vmapple-virtio-blk-pci,variant=aux,drive=aux \
167
+ -device vmapple-virtio-root,drive=root \
190
+ -device vmapple-virtio-blk-pci,variant=root,drive=root \
168
+ -net user,ipv6=off,hostfwd=tcp::2222-:22,hostfwd=tcp::5901-:5900 \
191
+ -netdev user,id=net0,ipv6=off,hostfwd=tcp::2222-:22,hostfwd=tcp::5901-:5900 \
169
+ -net nic,model=virtio-net-pci \
192
+ -device virtio-net-pci,netdev=net0
193
+
170
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
194
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
171
index XXXXXXX..XXXXXXX 100644
195
index XXXXXXX..XXXXXXX 100644
172
--- a/docs/system/target-arm.rst
196
--- a/docs/system/target-arm.rst
173
+++ b/docs/system/target-arm.rst
197
+++ b/docs/system/target-arm.rst
174
@@ -XXX,XX +XXX,XX @@ Board-specific documentation
198
@@ -XXX,XX +XXX,XX @@ Board-specific documentation
...
...
290
+ struct arm_boot_info bootinfo;
314
+ struct arm_boot_info bootinfo;
291
+ MemMapEntry *memmap;
315
+ MemMapEntry *memmap;
292
+ const int *irqmap;
316
+ const int *irqmap;
293
+ DeviceState *gic;
317
+ DeviceState *gic;
294
+ DeviceState *cfg;
318
+ DeviceState *cfg;
319
+ DeviceState *pvpanic;
295
+ Notifier powerdown_notifier;
320
+ Notifier powerdown_notifier;
296
+ PCIBus *bus;
321
+ PCIBus *bus;
297
+ MemoryRegion fw_mr;
322
+ MemoryRegion fw_mr;
298
+ MemoryRegion ecam_alias;
323
+ MemoryRegion ecam_alias;
299
+ uint64_t uuid;
324
+ uint64_t uuid;
...
...
421
+ sysbus_realize_and_unref(bdif_sb, &error_fatal);
446
+ sysbus_realize_and_unref(bdif_sb, &error_fatal);
422
+}
447
+}
423
+
448
+
424
+static void create_pvpanic(VMAppleMachineState *vms, MemoryRegion *mem)
449
+static void create_pvpanic(VMAppleMachineState *vms, MemoryRegion *mem)
425
+{
450
+{
426
+ SysBusDevice *cfg;
451
+ SysBusDevice *pvpanic;
427
+
452
+
428
+ vms->cfg = qdev_new(TYPE_PVPANIC_MMIO_DEVICE);
453
+ vms->pvpanic = qdev_new(TYPE_PVPANIC_MMIO_DEVICE);
429
+ cfg = SYS_BUS_DEVICE(vms->cfg);
454
+ pvpanic = SYS_BUS_DEVICE(vms->pvpanic);
430
+ sysbus_mmio_map(cfg, 0, vms->memmap[VMAPPLE_PVPANIC].base);
455
+ sysbus_mmio_map(pvpanic, 0, vms->memmap[VMAPPLE_PVPANIC].base);
431
+
456
+
432
+ sysbus_realize_and_unref(cfg, &error_fatal);
457
+ sysbus_realize_and_unref(pvpanic, &error_fatal);
433
+}
458
+}
434
+
459
+
435
+static void create_cfg(VMAppleMachineState *vms, MemoryRegion *mem)
460
+static bool create_cfg(VMAppleMachineState *vms, MemoryRegion *mem,
436
+{
461
+ Error **errp)
462
+{
463
+ ERRP_GUARD();
437
+ SysBusDevice *cfg;
464
+ SysBusDevice *cfg;
438
+ MachineState *machine = MACHINE(vms);
465
+ MachineState *machine = MACHINE(vms);
439
+ uint32_t rnd = 1;
466
+ uint32_t rnd = 1;
440
+
467
+
441
+ vms->cfg = qdev_new(TYPE_VMAPPLE_CFG);
468
+ vms->cfg = qdev_new(TYPE_VMAPPLE_CFG);
...
...
447
+ qdev_prop_set_uint32(vms->cfg, "nr-cpus", machine->smp.cpus);
474
+ qdev_prop_set_uint32(vms->cfg, "nr-cpus", machine->smp.cpus);
448
+ qdev_prop_set_uint64(vms->cfg, "ecid", vms->uuid);
475
+ qdev_prop_set_uint64(vms->cfg, "ecid", vms->uuid);
449
+ qdev_prop_set_uint64(vms->cfg, "ram-size", machine->ram_size);
476
+ qdev_prop_set_uint64(vms->cfg, "ram-size", machine->ram_size);
450
+ qdev_prop_set_uint32(vms->cfg, "rnd", rnd);
477
+ qdev_prop_set_uint32(vms->cfg, "rnd", rnd);
451
+
478
+
452
+ sysbus_realize_and_unref(cfg, &error_fatal);
479
+ if (!sysbus_realize_and_unref(cfg, errp)) {
480
+ error_prepend(errp, "Error creating vmapple cfg device: ");
481
+ return false;
482
+ }
483
+
484
+ return true;
453
+}
485
+}
454
+
486
+
455
+static void create_gfx(VMAppleMachineState *vms, MemoryRegion *mem)
487
+static void create_gfx(VMAppleMachineState *vms, MemoryRegion *mem)
456
+{
488
+{
457
+ int irq_gfx = vms->irqmap[VMAPPLE_APV_GFX];
489
+ int irq_gfx = vms->irqmap[VMAPPLE_APV_GFX];
...
...
751
+ create_pcie(vms);
783
+ create_pcie(vms);
752
+
784
+
753
+ create_gpio_devices(vms, VMAPPLE_GPIO, sysmem);
785
+ create_gpio_devices(vms, VMAPPLE_GPIO, sysmem);
754
+
786
+
755
+ vmapple_firmware_init(vms, sysmem);
787
+ vmapple_firmware_init(vms, sysmem);
756
+ create_cfg(vms, sysmem);
788
+ create_cfg(vms, sysmem, &error_fatal);
757
+
789
+
758
+ /* connect powerdown request */
790
+ /* connect powerdown request */
759
+ vms->powerdown_notifier.notify = vmapple_powerdown_req;
791
+ vms->powerdown_notifier.notify = vmapple_powerdown_req;
760
+ qemu_register_powerdown_notifier(&vms->powerdown_notifier);
792
+ qemu_register_powerdown_notifier(&vms->powerdown_notifier);
761
+
793
+
...
...
804
+ arm_build_mp_affinity(n, GICV3_TARGETLIST_BITS);
836
+ arm_build_mp_affinity(n, GICV3_TARGETLIST_BITS);
805
+ ms->possible_cpus->cpus[n].props.has_thread_id = true;
837
+ ms->possible_cpus->cpus[n].props.has_thread_id = true;
806
+ ms->possible_cpus->cpus[n].props.thread_id = n;
838
+ ms->possible_cpus->cpus[n].props.thread_id = n;
807
+ }
839
+ }
808
+ return ms->possible_cpus;
840
+ return ms->possible_cpus;
809
+}
810
+
811
+static void vmapple_get_uuid(Object *obj, Visitor *v, const char *name,
812
+ void *opaque, Error **errp)
813
+{
814
+ VMAppleMachineState *vms = VMAPPLE_MACHINE(obj);
815
+
816
+ visit_type_uint64(v, name, &vms->uuid, errp);
817
+}
818
+
819
+static void vmapple_set_uuid(Object *obj, Visitor *v, const char *name,
820
+ void *opaque, Error **errp)
821
+{
822
+ VMAppleMachineState *vms = VMAPPLE_MACHINE(obj);
823
+ Error *error = NULL;
824
+
825
+ visit_type_uint64(v, name, &vms->uuid, &error);
826
+ if (error) {
827
+ error_propagate(errp, error);
828
+ return;
829
+ }
830
+}
841
+}
831
+
842
+
832
+static void vmapple_machine_class_init(ObjectClass *oc, void *data)
843
+static void vmapple_machine_class_init(ObjectClass *oc, void *data)
833
+{
844
+{
834
+ MachineClass *mc = MACHINE_CLASS(oc);
845
+ MachineClass *mc = MACHINE_CLASS(oc);
...
...
845
+ mc->get_default_cpu_node_id = vmapple_get_default_cpu_node_id;
856
+ mc->get_default_cpu_node_id = vmapple_get_default_cpu_node_id;
846
+ mc->default_ram_id = "mach-vmapple.ram";
857
+ mc->default_ram_id = "mach-vmapple.ram";
847
+
858
+
848
+ object_register_sugar_prop(TYPE_VIRTIO_PCI, "disable-legacy",
859
+ object_register_sugar_prop(TYPE_VIRTIO_PCI, "disable-legacy",
849
+ "on", true);
860
+ "on", true);
850
+
851
+ object_class_property_add(oc, "uuid", "uint64", vmapple_get_uuid,
852
+ vmapple_set_uuid, NULL, NULL);
853
+ object_class_property_set_description(oc, "uuid", "Machine UUID (SDOM)");
854
+}
861
+}
855
+
862
+
856
+static void vmapple_instance_init(Object *obj)
863
+static void vmapple_instance_init(Object *obj)
857
+{
864
+{
858
+ VMAppleMachineState *vms = VMAPPLE_MACHINE(obj);
865
+ VMAppleMachineState *vms = VMAPPLE_MACHINE(obj);
859
+
866
+
860
+ vms->irqmap = irqmap;
867
+ vms->irqmap = irqmap;
868
+
869
+ object_property_add_uint64_ptr(obj, "uuid", &vms->uuid,
870
+ OBJ_PROP_FLAG_READWRITE);
871
+ object_property_set_description(obj, "uuid", "Machine UUID (SDOM)");
861
+}
872
+}
862
+
873
+
863
+static const TypeInfo vmapple_machine_info = {
874
+static const TypeInfo vmapple_machine_info = {
864
+ .name = TYPE_VMAPPLE_MACHINE,
875
+ .name = TYPE_VMAPPLE_MACHINE,
865
+ .parent = TYPE_MACHINE,
876
+ .parent = TYPE_MACHINE,
...
...
874
+{
885
+{
875
+ type_register_static(&vmapple_machine_info);
886
+ type_register_static(&vmapple_machine_info);
876
+}
887
+}
877
+type_init(machvmapple_machine_init);
888
+type_init(machvmapple_machine_init);
878
+
889
+
879
+static void vmapple_machine_9_2_options(MachineClass *mc)
890
+static void vmapple_machine_10_0_options(MachineClass *mc)
880
+{
891
+{
881
+}
892
+}
882
+DEFINE_VMAPPLE_MACHINE_AS_LATEST(9, 2)
893
+DEFINE_VMAPPLE_MACHINE_AS_LATEST(10, 0)
883
+
894
+
884
--
895
--
885
2.39.3 (Apple Git-145)
896
2.39.5 (Apple Git-154)
886
897
887
898
diff view generated by jsdifflib