...
...
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
73
---
76
74
77
v2 -> v3:
75
v2 -> v3:
78
76
79
* Merged the apple-gfx and vmapple patchsets.
77
* Merged the apple-gfx and vmapple patchsets.
80
* Squashed a bunch of later apple-gfx patches into the main one.
78
* Squashed a bunch of later apple-gfx patches into the main one.
...
...
169
* 12/15 (vmapple/cfg): Macro hygiene fix: consistently enclosing arguments in
167
* 12/15 (vmapple/cfg): Macro hygiene fix: consistently enclosing arguments in
170
parens.
168
parens.
171
* 15/15 (vmapple machine type): Use less verbose pattern for defining uuid
169
* 15/15 (vmapple machine type): Use less verbose pattern for defining uuid
172
property.
170
property.
173
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.
231
174
Alexander Graf (9):
232
Alexander Graf (9):
175
hw: Add vmapple subdir
233
hw: Add vmapple subdir
176
hw/misc/pvpanic: Add MMIO interface
234
hw/misc/pvpanic: Add MMIO interface
177
hvf: arm: Ignore writes to CNTP_CTL_EL0
235
hvf: arm: Ignore writes to CNTP_CTL_EL0
178
gpex: Allow more than 4 legacy IRQs
236
gpex: Allow more than 4 legacy IRQs
...
...
189
hw/display/apple-gfx: Adds PCI implementation
247
hw/display/apple-gfx: Adds PCI implementation
190
hw/display/apple-gfx: Adds configurable mode list
248
hw/display/apple-gfx: Adds configurable mode list
191
MAINTAINERS: Add myself as maintainer for apple-gfx, reviewer for HVF
249
MAINTAINERS: Add myself as maintainer for apple-gfx, reviewer for HVF
192
hw/block/virtio-blk: Replaces request free function with g_free
250
hw/block/virtio-blk: Replaces request free function with g_free
193
251
194
MAINTAINERS | 15 +
252
MAINTAINERS | 15 +
195
contrib/vmapple/uuid.sh | 9 +
253
contrib/vmapple/uuid.sh | 9 +
196
docs/system/arm/vmapple.rst | 60 +++
254
docs/system/arm/vmapple.rst | 63 ++
197
docs/system/target-arm.rst | 1 +
255
docs/system/target-arm.rst | 1 +
198
hw/Kconfig | 1 +
256
hw/Kconfig | 1 +
199
hw/arm/sbsa-ref.c | 2 +-
257
hw/arm/sbsa-ref.c | 2 +-
200
hw/arm/virt.c | 2 +-
258
hw/arm/virt.c | 2 +-
201
hw/block/virtio-blk.c | 58 ++-
259
hw/block/virtio-blk.c | 58 +-
202
hw/display/Kconfig | 13 +
260
hw/core/qdev-properties-system.c | 8 +
203
hw/display/apple-gfx-mmio.m | 290 +++++++++++
261
hw/display/Kconfig | 13 +
204
hw/display/apple-gfx-pci.m | 155 ++++++
262
hw/display/apple-gfx-mmio.m | 289 +++++++++
205
hw/display/apple-gfx.h | 77 +++
263
hw/display/apple-gfx-pci.m | 157 +++++
206
hw/display/apple-gfx.m | 867 +++++++++++++++++++++++++++++++++
264
hw/display/apple-gfx.h | 77 +++
207
hw/display/meson.build | 5 +
265
hw/display/apple-gfx.m | 880 ++++++++++++++++++++++++++++
208
hw/display/trace-events | 30 ++
266
hw/display/meson.build | 7 +
209
hw/i386/microvm.c | 2 +-
267
hw/display/trace-events | 30 +
210
hw/loongarch/virt.c | 2 +-
268
hw/i386/microvm.c | 2 +-
211
hw/meson.build | 1 +
269
hw/loongarch/virt.c | 12 +-
212
hw/mips/loongson3_virt.c | 2 +-
270
hw/meson.build | 1 +
213
hw/misc/Kconfig | 4 +
271
hw/mips/loongson3_virt.c | 2 +-
214
hw/misc/meson.build | 1 +
272
hw/misc/Kconfig | 4 +
215
hw/misc/pvpanic-mmio.c | 61 +++
273
hw/misc/meson.build | 1 +
216
hw/openrisc/virt.c | 12 +-
274
hw/misc/pvpanic-mmio.c | 61 ++
217
hw/pci-host/gpex.c | 43 +-
275
hw/openrisc/virt.c | 12 +-
218
hw/riscv/virt.c | 12 +-
276
hw/pci-host/gpex.c | 43 +-
219
hw/vmapple/Kconfig | 32 ++
277
hw/riscv/virt.c | 12 +-
220
hw/vmapple/aes.c | 579 ++++++++++++++++++++++
278
hw/vmapple/Kconfig | 32 +
221
hw/vmapple/bdif.c | 271 +++++++++++
279
hw/vmapple/aes.c | 581 ++++++++++++++++++
222
hw/vmapple/cfg.c | 196 ++++++++
280
hw/vmapple/bdif.c | 275 +++++++++
223
hw/vmapple/meson.build | 5 +
281
hw/vmapple/cfg.c | 196 +++++++
224
hw/vmapple/trace-events | 21 +
282
hw/vmapple/meson.build | 5 +
225
hw/vmapple/trace.h | 1 +
283
hw/vmapple/trace-events | 21 +
226
hw/vmapple/virtio-blk.c | 226 +++++++++
284
hw/vmapple/trace.h | 1 +
227
hw/vmapple/vmapple.c | 638 ++++++++++++++++++++++++
285
hw/vmapple/virtio-blk.c | 205 +++++++
228
hw/xtensa/virt.c | 2 +-
286
hw/vmapple/vmapple.c | 646 ++++++++++++++++++++
229
include/hw/misc/pvpanic.h | 1 +
287
hw/xen/xen-pvh-common.c | 2 +-
230
include/hw/pci-host/gpex.h | 7 +-
288
hw/xtensa/virt.c | 2 +-
231
include/hw/pci/pci_ids.h | 1 +
289
include/hw/misc/pvpanic.h | 1 +
232
include/hw/virtio/virtio-blk.h | 11 +-
290
include/hw/pci-host/gpex.h | 7 +-
233
include/hw/vmapple/vmapple.h | 25 +
291
include/hw/pci/pci_ids.h | 1 +
234
include/qemu-main.h | 3 +-
292
include/hw/qdev-properties-system.h | 5 +
235
include/qemu/cutils.h | 15 +
293
include/hw/virtio/virtio-blk.h | 11 +-
236
include/qemu/typedefs.h | 1 +
294
include/hw/vmapple/vmapple.h | 23 +
237
meson.build | 5 +
295
include/qemu-main.h | 14 +-
238
system/main.c | 50 +-
296
include/qemu/cutils.h | 15 +
239
target/arm/hvf/hvf.c | 9 +
297
meson.build | 5 +
240
ui/cocoa.m | 54 +-
298
qapi/virtio.json | 14 +
241
ui/sdl2.c | 4 +
299
system/main.c | 37 +-
242
util/hexdump.c | 18 +
300
target/arm/hvf/hvf.c | 9 +
243
49 files changed, 3794 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(-)
244
create mode 100755 contrib/vmapple/uuid.sh
306
create mode 100755 contrib/vmapple/uuid.sh
245
create mode 100644 docs/system/arm/vmapple.rst
307
create mode 100644 docs/system/arm/vmapple.rst
246
create mode 100644 hw/display/apple-gfx-mmio.m
308
create mode 100644 hw/display/apple-gfx-mmio.m
247
create mode 100644 hw/display/apple-gfx-pci.m
309
create mode 100644 hw/display/apple-gfx-pci.m
248
create mode 100644 hw/display/apple-gfx.h
310
create mode 100644 hw/display/apple-gfx.h
...
...
258
create mode 100644 hw/vmapple/virtio-blk.c
320
create mode 100644 hw/vmapple/virtio-blk.c
259
create mode 100644 hw/vmapple/vmapple.c
321
create mode 100644 hw/vmapple/vmapple.c
260
create mode 100644 include/hw/vmapple/vmapple.h
322
create mode 100644 include/hw/vmapple/vmapple.h
261
323
262
--
324
--
263
2.39.3 (Apple Git-145)
325
2.39.5 (Apple Git-154)
264
326
265
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
...
...
128
* Variable naming tweaks for better clarity.
130
* Variable naming tweaks for better clarity.
129
* Fixed leak in unlikely realize error case.
131
* Fixed leak in unlikely realize error case.
130
* Fixed typo in unmap call.
132
* Fixed typo in unmap call.
131
* Don't bother with dummy argument for g_ptr_array_find(), NULL works too.
133
* Don't bother with dummy argument for g_ptr_array_find(), NULL works too.
132
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
133
hw/display/Kconfig | 9 +
168
hw/display/Kconfig | 9 +
134
hw/display/apple-gfx-mmio.m | 282 +++++++++++++
169
hw/display/apple-gfx-mmio.m | 281 +++++++++++++
135
hw/display/apple-gfx.h | 65 +++
170
hw/display/apple-gfx.h | 66 +++
136
hw/display/apple-gfx.m | 769 ++++++++++++++++++++++++++++++++++++
171
hw/display/apple-gfx.m | 783 ++++++++++++++++++++++++++++++++++++
137
hw/display/meson.build | 4 +
172
hw/display/meson.build | 6 +
138
hw/display/trace-events | 28 ++
173
hw/display/trace-events | 28 ++
139
meson.build | 4 +
174
meson.build | 4 +
140
7 files changed, 1161 insertions(+)
175
7 files changed, 1177 insertions(+)
141
create mode 100644 hw/display/apple-gfx-mmio.m
176
create mode 100644 hw/display/apple-gfx-mmio.m
142
create mode 100644 hw/display/apple-gfx.h
177
create mode 100644 hw/display/apple-gfx.h
143
create mode 100644 hw/display/apple-gfx.m
178
create mode 100644 hw/display/apple-gfx.m
144
179
145
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
180
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
...
...
349
+static PGIOSurfaceHostDevice *apple_gfx_prepare_iosurface_host_device(
384
+static PGIOSurfaceHostDevice *apple_gfx_prepare_iosurface_host_device(
350
+ AppleGFXMMIOState *s)
385
+ AppleGFXMMIOState *s)
351
+{
386
+{
352
+ PGIOSurfaceHostDeviceDescriptor *iosfc_desc =
387
+ PGIOSurfaceHostDeviceDescriptor *iosfc_desc =
353
+ [PGIOSurfaceHostDeviceDescriptor new];
388
+ [PGIOSurfaceHostDeviceDescriptor new];
354
+ PGIOSurfaceHostDevice *iosfc_host_dev = nil;
389
+ PGIOSurfaceHostDevice *iosfc_host_dev;
355
+
390
+
356
+ iosfc_desc.mapMemory =
391
+ iosfc_desc.mapMemory =
357
+ ^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) {
358
+ *va = apple_gfx_mmio_map_surface_memory(phys, len, ro);
393
+ *va = apple_gfx_mmio_map_surface_memory(phys, len, ro);
359
+
394
+
...
...
393
+ };
428
+ };
394
+
429
+
395
+ desc.usingIOSurfaceMapper = true;
430
+ desc.usingIOSurfaceMapper = true;
396
+ s->pgiosfc = apple_gfx_prepare_iosurface_host_device(s);
431
+ s->pgiosfc = apple_gfx_prepare_iosurface_host_device(s);
397
+
432
+
398
+ apple_gfx_common_realize(&s->common, desc, errp);
433
+ if (!apple_gfx_common_realize(&s->common, dev, desc, errp)) {
399
+ if (*errp) {
400
+ [s->pgiosfc release];
434
+ [s->pgiosfc release];
401
+ s->pgiosfc = nil;
435
+ s->pgiosfc = nil;
402
+ }
436
+ }
403
+
437
+
404
+ [desc release];
438
+ [desc release];
...
...
488
+ id<PGDevice> pgdev;
522
+ id<PGDevice> pgdev;
489
+ id<PGDisplay> pgdisp;
523
+ id<PGDisplay> pgdisp;
490
+ QemuConsole *con;
524
+ QemuConsole *con;
491
+ id<MTLDevice> mtl;
525
+ id<MTLDevice> mtl;
492
+ id<MTLCommandQueue> mtl_queue;
526
+ id<MTLCommandQueue> mtl_queue;
493
+ dispatch_queue_t render_queue;
494
+
527
+
495
+ /* List `tasks` is protected by task_mutex */
528
+ /* List `tasks` is protected by task_mutex */
496
+ QemuMutex task_mutex;
529
+ QemuMutex task_mutex;
497
+ PGTaskList tasks;
530
+ PGTaskList tasks;
498
+
531
+
...
...
502
+ id<MTLTexture> texture;
535
+ id<MTLTexture> texture;
503
+ int8_t pending_frames; /* # guest frames in the rendering pipeline */
536
+ int8_t pending_frames; /* # guest frames in the rendering pipeline */
504
+ bool gfx_update_requested; /* QEMU display system wants a new frame */
537
+ bool gfx_update_requested; /* QEMU display system wants a new frame */
505
+ 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 */
506
+ bool using_managed_texture_storage;
539
+ bool using_managed_texture_storage;
540
+ uint32_t rendering_frame_width;
541
+ uint32_t rendering_frame_height;
507
+
542
+
508
+ /* Mutable state (atomic) */
543
+ /* Mutable state (atomic) */
509
+ bool cursor_show;
544
+ bool cursor_show;
510
+} AppleGFXState;
545
+} AppleGFXState;
511
+
546
+
512
+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);
513
+void apple_gfx_common_realize(AppleGFXState *s, PGDeviceDescriptor *desc,
548
+bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev,
514
+ Error **errp);
549
+ PGDeviceDescriptor *desc, Error **errp);
515
+void *apple_gfx_host_ptr_for_gpa_range(uint64_t guest_physical,
550
+void *apple_gfx_host_ptr_for_gpa_range(uint64_t guest_physical,
516
+ uint64_t length, bool read_only,
551
+ uint64_t length, bool read_only,
517
+ MemoryRegion **mapping_in_region);
552
+ MemoryRegion **mapping_in_region);
518
+
553
+
519
+#endif
554
+#endif
...
...
559
+
594
+
560
+static const PGDisplayCoord_t apple_gfx_modes[] = {
595
+static const PGDisplayCoord_t apple_gfx_modes[] = {
561
+ { .x = 1440, .y = 1080 },
596
+ { .x = 1440, .y = 1080 },
562
+ { .x = 1280, .y = 1024 },
597
+ { .x = 1280, .y = 1024 },
563
+};
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
+}
564
+
607
+
565
+/* ------ PGTask and task operations: new/destroy/map/unmap ------ */
608
+/* ------ PGTask and task operations: new/destroy/map/unmap ------ */
566
+
609
+
567
+/*
610
+/*
568
+ * This implements the type declared in <ParavirtualizedGraphics/PGDevice.h>
611
+ * This implements the type declared in <ParavirtualizedGraphics/PGDevice.h>
...
...
594
+ * Protected by AppleGFXState's task_mutex.
637
+ * Protected by AppleGFXState's task_mutex.
595
+ */
638
+ */
596
+ GPtrArray *mapped_regions;
639
+ GPtrArray *mapped_regions;
597
+};
640
+};
598
+
641
+
599
+static Error *apple_gfx_mig_blocker;
600
+
601
+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)
602
+{
643
+{
603
+ mach_vm_address_t task_mem;
644
+ mach_vm_address_t task_mem;
604
+ PGTask_t *task;
645
+ PGTask_t *task;
605
+ kern_return_t r;
646
+ kern_return_t r;
...
...
665
+ return NULL;
706
+ return NULL;
666
+ }
707
+ }
667
+ host_ptr += ram_region_offset;
708
+ host_ptr += ram_region_offset;
668
+ *mapping_in_region = ram_region;
709
+ *mapping_in_region = ram_region;
669
+ return host_ptr;
710
+ return host_ptr;
670
+}
671
+
672
+/* Returns false if the region is already in the array */
673
+static bool add_new_region(GPtrArray *regions, MemoryRegion *region)
674
+{
675
+ if (g_ptr_array_find(regions, region, NULL)) {
676
+ return false;
677
+ }
678
+
679
+ g_ptr_array_add(regions, region);
680
+ return true;
681
+}
711
+}
682
+
712
+
683
+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,
684
+ uint64_t virtual_offset,
714
+ uint64_t virtual_offset,
685
+ PGPhysicalMemoryRange_t *ranges,
715
+ PGPhysicalMemoryRange_t *ranges,
...
...
712
+ if (!source_ptr) {
742
+ if (!source_ptr) {
713
+ success = false;
743
+ success = false;
714
+ continue;
744
+ continue;
715
+ }
745
+ }
716
+
746
+
717
+ 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);
718
+ memory_region_ref(region);
749
+ memory_region_ref(region);
719
+ }
750
+ }
720
+
751
+
721
+ cur_protection = 0;
752
+ cur_protection = 0;
722
+ max_protection = 0;
753
+ max_protection = 0;
...
...
753
+ g_assert(r == KERN_SUCCESS);
784
+ g_assert(r == KERN_SUCCESS);
754
+}
785
+}
755
+
786
+
756
+/* ------ Rendering and frame management ------ */
787
+/* ------ Rendering and frame management ------ */
757
+
788
+
758
+static void apple_gfx_render_frame_completed(AppleGFXState *s,
789
+static void apple_gfx_render_frame_completed_bh(void *opaque);
759
+ uint32_t width, uint32_t height);
790
+
760
+
791
+static void apple_gfx_render_new_frame(AppleGFXState *s)
761
+static void apple_gfx_render_new_frame_bql_unlock(AppleGFXState *s)
792
+{
762
+{
763
+ BOOL r;
764
+ bool managed_texture = s->using_managed_texture_storage;
793
+ bool managed_texture = s->using_managed_texture_storage;
765
+ uint32_t width = surface_width(s->surface);
794
+ uint32_t width = surface_width(s->surface);
766
+ uint32_t height = surface_height(s->surface);
795
+ uint32_t height = surface_height(s->surface);
767
+ MTLRegion region = MTLRegionMake2D(0, 0, width, height);
796
+ MTLRegion region = MTLRegionMake2D(0, 0, width, height);
768
+ id<MTLCommandBuffer> command_buffer = [s->mtl_queue commandBuffer];
797
+ id<MTLCommandBuffer> command_buffer = [s->mtl_queue commandBuffer];
769
+ id<MTLTexture> texture = s->texture;
798
+ id<MTLTexture> texture = s->texture;
770
+
799
+
771
+ assert(bql_locked());
800
+ assert(bql_locked());
772
+ [texture retain];
801
+ [texture retain];
773
+
802
+ [command_buffer retain];
774
+ bql_unlock();
803
+
775
+
804
+ s->rendering_frame_width = width;
776
+ /* This is not safe to call from the BQL due to PVG-internal locks causing
805
+ s->rendering_frame_height = height;
777
+ * deadlocks. */
806
+
778
+ r = [s->pgdisp encodeCurrentFrameToCommandBuffer:command_buffer
807
+ dispatch_async(get_background_queue(), ^{
779
+ texture:texture
808
+ /*
780
+ region:region];
809
+ * This is not safe to call from the BQL/BH due to PVG-internal locks
781
+ 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
+ }
782
+ [texture release];
836
+ [texture release];
783
+ bql_lock();
837
+ [command_buffer addCompletedHandler:
784
+ --s->pending_frames;
838
+ ^(id<MTLCommandBuffer> cb)
785
+ bql_unlock();
839
+ {
786
+ qemu_log_mask(LOG_GUEST_ERROR,
840
+ aio_bh_schedule_oneshot(qemu_get_aio_context(),
787
+ "%s: encodeCurrentFrameToCommandBuffer:texture:region: "
841
+ apple_gfx_render_frame_completed_bh, s);
788
+ "failed\n", __func__);
842
+ }];
789
+ return;
843
+ [command_buffer commit];
790
+ }
844
+ [command_buffer release];
791
+
845
+ });
792
+ if (managed_texture) {
793
+ /* "Managed" textures exist in both VRAM and RAM and must be synced. */
794
+ id<MTLBlitCommandEncoder> blit = [command_buffer blitCommandEncoder];
795
+ [blit synchronizeResource:texture];
796
+ [blit endEncoding];
797
+ }
798
+ [texture release];
799
+ [command_buffer addCompletedHandler:
800
+ ^(id<MTLCommandBuffer> cb)
801
+ {
802
+ dispatch_async(s->render_queue, ^{
803
+ apple_gfx_render_frame_completed(s, width, height);
804
+ });
805
+ }];
806
+ [command_buffer commit];
807
+}
846
+}
808
+
847
+
809
+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)
810
+{
849
+{
811
+ /* 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
812
+ * rendering path, else use a blit command encoder? Needs careful
852
+ * rendering path, else use a blit command encoder? Needs careful
813
+ * (double?) buffering design. */
853
+ * (double?) buffering design.
854
+ */
814
+ size_t width = texture.width, height = texture.height;
855
+ size_t width = texture.width, height = texture.height;
815
+ MTLRegion region = MTLRegionMake2D(0, 0, width, height);
856
+ MTLRegion region = MTLRegionMake2D(0, 0, width, height);
816
+ [texture getBytes:vram
857
+ [texture getBytes:vram
817
+ bytesPerRow:(width * 4)
858
+ bytesPerRow:(width * 4)
818
+ bytesPerImage:(width * height * 4)
859
+ bytesPerImage:(width * height * 4)
819
+ fromRegion:region
860
+ fromRegion:region
820
+ mipmapLevel:0
861
+ mipmapLevel:0
821
+ slice:0];
862
+ slice:0];
822
+}
863
+}
823
+
864
+
824
+static void apple_gfx_render_frame_completed(AppleGFXState *s,
865
+static void apple_gfx_render_frame_completed_bh(void *opaque)
825
+ uint32_t width, uint32_t height)
866
+{
826
+{
867
+ AppleGFXState *s = opaque;
827
+ bql_lock();
868
+
828
+ --s->pending_frames;
869
+ @autoreleasepool {
829
+ assert(s->pending_frames >= 0);
870
+ --s->pending_frames;
830
+
871
+ assert(s->pending_frames >= 0);
831
+ /* Only update display if mode hasn't changed since we started rendering. */
872
+
832
+ if (width == surface_width(s->surface) &&
873
+ /* Only update display if mode hasn't changed since we started rendering. */
833
+ height == surface_height(s->surface)) {
874
+ if (s->rendering_frame_width == surface_width(s->surface) &&
834
+ copy_mtl_texture_to_surface_mem(s->texture, surface_data(s->surface));
875
+ s->rendering_frame_height == surface_height(s->surface)) {
835
+ if (s->gfx_update_requested) {
876
+ copy_mtl_texture_to_surface_mem(s->texture, surface_data(s->surface));
836
+ s->gfx_update_requested = false;
877
+ if (s->gfx_update_requested) {
837
+ dpy_gfx_update_full(s->con);
878
+ s->gfx_update_requested = false;
838
+ graphic_hw_update_done(s->con);
879
+ dpy_gfx_update_full(s->con);
839
+ s->new_frame_ready = false;
880
+ graphic_hw_update_done(s->con);
840
+ } else {
881
+ s->new_frame_ready = false;
841
+ s->new_frame_ready = true;
882
+ } else {
883
+ s->new_frame_ready = true;
884
+ }
842
+ }
885
+ }
843
+ }
886
+ if (s->pending_frames > 0) {
844
+ if (s->pending_frames > 0) {
887
+ apple_gfx_render_new_frame(s);
845
+ apple_gfx_render_new_frame_bql_unlock(s);
888
+ }
846
+ } else {
847
+ bql_unlock();
848
+ }
889
+ }
849
+}
890
+}
850
+
891
+
851
+static void apple_gfx_fb_update_display(void *opaque)
892
+static void apple_gfx_fb_update_display(void *opaque)
852
+{
893
+{
...
...
892
+ width:width
933
+ width:width
893
+ height:height
934
+ height:height
894
+ mipmapped:NO];
935
+ mipmapped:NO];
895
+ textureDescriptor.usage = s->pgdisp.minimumTextureUsage;
936
+ textureDescriptor.usage = s->pgdisp.minimumTextureUsage;
896
+ s->texture = [s->mtl newTextureWithDescriptor:textureDescriptor];
937
+ s->texture = [s->mtl newTextureWithDescriptor:textureDescriptor];
897
+ }
938
+ s->using_managed_texture_storage =
898
+
939
+ (s->texture.storageMode == MTLStorageModeManaged);
899
+ s->using_managed_texture_storage =
940
+ }
900
+ (s->texture.storageMode == MTLStorageModeManaged);
941
+
901
+ dpy_gfx_replace_surface(s->con, s->surface);
942
+ dpy_gfx_replace_surface(s->con, s->surface);
902
+}
943
+}
903
+
944
+
904
+static void update_cursor(AppleGFXState *s)
945
+static void update_cursor(AppleGFXState *s)
905
+{
946
+{
...
...
945
+
986
+
946
+ uint32_t *dest_px = s->cursor->data;
987
+ uint32_t *dest_px = s->cursor->data;
947
+
988
+
948
+ for (size_t y = 0; y < height; ++y) {
989
+ for (size_t y = 0; y < height; ++y) {
949
+ for (size_t x = 0; x < width; ++x) {
990
+ for (size_t x = 0; x < width; ++x) {
950
+ /* NSBitmapImageRep's red & blue channels are swapped
991
+ /*
951
+ * compared to QEMUCursor's. */
992
+ * NSBitmapImageRep's red & blue channels are swapped
993
+ * compared to QEMUCursor's.
994
+ */
952
+ *dest_px =
995
+ *dest_px =
953
+ (px_data[0] << 16u) |
996
+ (px_data[0] << 16u) |
954
+ (px_data[1] << 8u) |
997
+ (px_data[1] << 8u) |
955
+ (px_data[2] << 0u) |
998
+ (px_data[2] << 0u) |
956
+ (px_data[3] << 24u);
999
+ (px_data[3] << 24u);
...
...
1006
+ qemu_sem_destroy(&job.sem);
1049
+ qemu_sem_destroy(&job.sem);
1007
+ return job.success;
1050
+ return job.success;
1008
+}
1051
+}
1009
+
1052
+
1010
+/* ------ Memory-mapped device I/O operations ------ */
1053
+/* ------ Memory-mapped device I/O operations ------ */
1011
+
1012
+static dispatch_queue_t get_background_queue(void)
1013
+{
1014
+ return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1015
+}
1016
+
1054
+
1017
+typedef struct AppleGFXIOJob {
1055
+typedef struct AppleGFXIOJob {
1018
+ AppleGFXState *state;
1056
+ AppleGFXState *state;
1019
+ uint64_t offset;
1057
+ uint64_t offset;
1020
+ uint64_t value;
1058
+ uint64_t value;
...
...
1150
+ void * _Nonnull dst) {
1188
+ void * _Nonnull dst) {
1151
+ return apple_gfx_read_memory(s, physical_address, length, dst);
1189
+ return apple_gfx_read_memory(s, physical_address, length, dst);
1152
+ };
1190
+ };
1153
+}
1191
+}
1154
+
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
+
1155
+static PGDisplayDescriptor *apple_gfx_prepare_display_descriptor(AppleGFXState *s)
1211
+static PGDisplayDescriptor *apple_gfx_prepare_display_descriptor(AppleGFXState *s)
1156
+{
1212
+{
1157
+ PGDisplayDescriptor *disp_desc = [PGDisplayDescriptor new];
1213
+ PGDisplayDescriptor *disp_desc = [PGDisplayDescriptor new];
1158
+
1214
+
1159
+ disp_desc.name = @"QEMU display";
1215
+ disp_desc.name = @"QEMU display";
1160
+ disp_desc.sizeInMillimeters = NSMakeSize(400., 300.); /* A 20" display */
1216
+ disp_desc.sizeInMillimeters = NSMakeSize(400., 300.); /* A 20" display */
1161
+ disp_desc.queue = dispatch_get_main_queue();
1217
+ disp_desc.queue = dispatch_get_main_queue();
1162
+ disp_desc.newFrameEventHandler = ^(void) {
1218
+ disp_desc.newFrameEventHandler = ^(void) {
1163
+ trace_apple_gfx_new_frame();
1219
+ trace_apple_gfx_new_frame();
1164
+ dispatch_async(s->render_queue, ^{
1220
+ aio_bh_schedule_oneshot(qemu_get_aio_context(), new_frame_handler_bh, s);
1165
+ /* Drop frames if we get too far ahead. */
1166
+ bql_lock();
1167
+ if (s->pending_frames >= 2) {
1168
+ bql_unlock();
1169
+ return;
1170
+ }
1171
+ ++s->pending_frames;
1172
+ if (s->pending_frames > 1) {
1173
+ bql_unlock();
1174
+ return;
1175
+ }
1176
+ @autoreleasepool {
1177
+ apple_gfx_render_new_frame_bql_unlock(s);
1178
+ }
1179
+ });
1180
+ };
1221
+ };
1181
+ disp_desc.modeChangeHandler = ^(PGDisplayCoord_t sizeInPixels,
1222
+ disp_desc.modeChangeHandler = ^(PGDisplayCoord_t sizeInPixels,
1182
+ OSType pixelFormat) {
1223
+ OSType pixelFormat) {
1183
+ trace_apple_gfx_mode_change(sizeInPixels.x, sizeInPixels.y);
1224
+ trace_apple_gfx_mode_change(sizeInPixels.x, sizeInPixels.y);
1184
+
1225
+
...
...
1211
+}
1252
+}
1212
+
1253
+
1213
+static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void)
1254
+static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void)
1214
+{
1255
+{
1215
+ PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)];
1256
+ PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)];
1216
+ NSArray<PGDisplayMode*>* mode_array = nil;
1257
+ NSArray<PGDisplayMode*>* mode_array;
1217
+ int i;
1258
+ int i;
1218
+
1259
+
1219
+ for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) {
1260
+ for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) {
1220
+ modes[i] =
1261
+ modes[i] =
1221
+ [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.];
1262
+ [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.];
...
...
1255
+ [devs release];
1296
+ [devs release];
1256
+
1297
+
1257
+ return dev;
1298
+ return dev;
1258
+}
1299
+}
1259
+
1300
+
1260
+void apple_gfx_common_realize(AppleGFXState *s, PGDeviceDescriptor *desc,
1301
+bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev,
1261
+ Error **errp)
1302
+ PGDeviceDescriptor *desc, Error **errp)
1262
+{
1303
+{
1263
+ PGDisplayDescriptor *disp_desc = nil;
1304
+ PGDisplayDescriptor *disp_desc;
1264
+
1305
+
1265
+ if (apple_gfx_mig_blocker == NULL) {
1306
+ if (apple_gfx_mig_blocker == NULL) {
1266
+ error_setg(&apple_gfx_mig_blocker,
1307
+ error_setg(&apple_gfx_mig_blocker,
1267
+ "Migration state blocked by apple-gfx display device");
1308
+ "Migration state blocked by apple-gfx display device");
1268
+ if (migrate_add_blocker(&apple_gfx_mig_blocker, errp) < 0) {
1309
+ if (migrate_add_blocker(&apple_gfx_mig_blocker, errp) < 0) {
1269
+ return;
1310
+ return false;
1270
+ }
1311
+ }
1271
+ }
1312
+ }
1272
+
1313
+
1273
+ qemu_mutex_init(&s->task_mutex);
1314
+ qemu_mutex_init(&s->task_mutex);
1274
+ QTAILQ_INIT(&s->tasks);
1315
+ QTAILQ_INIT(&s->tasks);
1275
+ s->render_queue = dispatch_queue_create("apple-gfx.render",
1276
+ DISPATCH_QUEUE_SERIAL);
1277
+ s->mtl = copy_suitable_metal_device();
1316
+ s->mtl = copy_suitable_metal_device();
1278
+ s->mtl_queue = [s->mtl newCommandQueue];
1317
+ s->mtl_queue = [s->mtl newCommandQueue];
1279
+
1318
+
1280
+ desc.device = s->mtl;
1319
+ desc.device = s->mtl;
1281
+
1320
+
1282
+ apple_gfx_register_task_mapping_handlers(s, desc);
1321
+ apple_gfx_register_task_mapping_handlers(s, desc);
1283
+
1322
+
1323
+ s->cursor_show = true;
1324
+
1284
+ s->pgdev = PGNewDeviceWithDescriptor(desc);
1325
+ s->pgdev = PGNewDeviceWithDescriptor(desc);
1285
+
1326
+
1286
+ 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
+ */
1287
+ s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc
1336
+ s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc
1288
+ port:0 serialNum:1234];
1337
+ port:0
1338
+ serialNum:next_pgdisplay_serial_num++];
1289
+ [disp_desc release];
1339
+ [disp_desc release];
1290
+ s->pgdisp.modeList = apple_gfx_prepare_display_mode_array();
1340
+ s->pgdisp.modeList = apple_gfx_prepare_display_mode_array();
1291
+
1341
+
1292
+ 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);
1293
+
1343
+ return true;
1294
+ qatomic_set(&s->cursor_show, true);
1295
+}
1344
+}
1296
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
1297
index XXXXXXX..XXXXXXX 100644
1346
index XXXXXXX..XXXXXXX 100644
1298
--- a/hw/display/meson.build
1347
--- a/hw/display/meson.build
1299
+++ b/hw/display/meson.build
1348
+++ b/hw/display/meson.build
1300
@@ -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'))
1301
1350
1302
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])
1303
1352
1304
+system_ss.add(when: 'CONFIG_MAC_PVG', if_true: [files('apple-gfx.m'), pvg, metal])
1353
+if host_os == 'darwin'
1305
+if cpu == 'aarch64'
1354
+ system_ss.add(when: 'CONFIG_MAC_PVG', if_true: [files('apple-gfx.m'), pvg, metal])
1306
+ 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
1307
+endif
1358
+endif
1308
1359
1309
if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
1360
if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
1310
virtio_gpu_ss = ss.source_set()
1361
virtio_gpu_ss = ss.source_set()
1311
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
...
...
1350
+++ b/meson.build
1401
+++ b/meson.build
1351
@@ -XXX,XX +XXX,XX @@ socket = []
1402
@@ -XXX,XX +XXX,XX @@ socket = []
1352
version_res = []
1403
version_res = []
1353
coref = []
1404
coref = []
1354
iokit = []
1405
iokit = []
1355
+pvg = []
1406
+pvg = not_found
1356
+metal = []
1407
+metal = []
1357
emulator_link_args = []
1408
emulator_link_args = []
1358
midl = not_found
1409
midl = not_found
1359
widl = not_found
1410
widl = not_found
1360
@@ -XXX,XX +XXX,XX @@ elif host_os == 'darwin'
1411
@@ -XXX,XX +XXX,XX @@ elif host_os == 'darwin'
...
...
1365
+ metal = dependency('appleframeworks', modules: 'Metal')
1416
+ metal = dependency('appleframeworks', modules: 'Metal')
1366
elif host_os == 'sunos'
1417
elif host_os == 'sunos'
1367
socket = [cc.find_library('socket'),
1418
socket = [cc.find_library('socket'),
1368
cc.find_library('nsl'),
1419
cc.find_library('nsl'),
1369
--
1420
--
1370
2.39.3 (Apple Git-145)
1421
2.39.5 (Apple Git-154)
1371
1422
1372
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
...
...
33
35
34
v8:
36
v8:
35
37
36
* More consistent integer variable types.
38
* More consistent integer variable types.
37
39
40
v9:
41
42
* Re-ordered type definitions so we can drop a 'struct' keyword.
43
38
hw/display/apple-gfx-mmio.m | 8 +++
44
hw/display/apple-gfx-mmio.m | 8 +++
39
hw/display/apple-gfx-pci.m | 9 ++-
45
hw/display/apple-gfx-pci.m | 9 ++-
40
hw/display/apple-gfx.h | 12 ++++
46
hw/display/apple-gfx.h | 11 +++
41
hw/display/apple-gfx.m | 136 +++++++++++++++++++++++++++++++-----
47
hw/display/apple-gfx.m | 135 +++++++++++++++++++++++++++++++-----
42
hw/display/trace-events | 2 +
48
hw/display/trace-events | 2 +
43
5 files changed, 147 insertions(+), 20 deletions(-)
49
5 files changed, 145 insertions(+), 20 deletions(-)
44
50
45
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
46
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/display/apple-gfx-mmio.m
53
--- a/hw/display/apple-gfx-mmio.m
48
+++ b/hw/display/apple-gfx-mmio.m
54
+++ b/hw/display/apple-gfx-mmio.m
...
...
88
DeviceClass *dc = DEVICE_CLASS(klass);
94
DeviceClass *dc = DEVICE_CLASS(klass);
89
@@ -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)
90
pci->class_id = PCI_CLASS_DISPLAY_OTHER;
96
pci->class_id = PCI_CLASS_DISPLAY_OTHER;
91
pci->realize = apple_gfx_pci_realize;
97
pci->realize = apple_gfx_pci_realize;
92
98
93
- // TODO: Property for setting mode list
99
- /* TODO: Property for setting mode list */
94
+ device_class_set_props(dc, apple_gfx_pci_properties);
100
+ device_class_set_props(dc, apple_gfx_pci_properties);
95
}
101
}
96
102
97
static TypeInfo apple_gfx_pci_types[] = {
103
static TypeInfo apple_gfx_pci_types[] = {
98
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
...
...
108
114
109
@class PGDeviceDescriptor;
115
@class PGDeviceDescriptor;
110
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@
111
117
112
typedef QTAILQ_HEAD(, PGTask_s) PGTaskList;
118
typedef QTAILQ_HEAD(, PGTask_s) PGTaskList;
113
114
+struct AppleGFXDisplayMode;
115
typedef struct AppleGFXState {
116
/* Initialised on init/realize() */
117
MemoryRegion iomem_gfx;
118
@@ -XXX,XX +XXX,XX @@ typedef struct AppleGFXState {
119
id<MTLDevice> mtl;
120
id<MTLCommandQueue> mtl_queue;
121
dispatch_queue_t render_queue;
122
+ struct AppleGFXDisplayMode *display_modes;
123
+ uint32_t num_display_modes;
124
125
/* List `tasks` is protected by task_mutex */
126
QemuMutex task_mutex;
127
@@ -XXX,XX +XXX,XX @@ typedef struct AppleGFXState {
128
bool cursor_show;
129
} AppleGFXState;
130
119
131
+typedef struct AppleGFXDisplayMode {
120
+typedef struct AppleGFXDisplayMode {
132
+ uint16_t width_px;
121
+ uint16_t width_px;
133
+ uint16_t height_px;
122
+ uint16_t height_px;
134
+ uint16_t refresh_rate_hz;
123
+ uint16_t refresh_rate_hz;
135
+} AppleGFXDisplayMode;
124
+} AppleGFXDisplayMode;
136
+
125
+
137
void apple_gfx_common_init(Object *obj, AppleGFXState *s, const char* obj_name);
126
typedef struct AppleGFXState {
138
void apple_gfx_common_realize(AppleGFXState *s, PGDeviceDescriptor *desc,
127
/* Initialised on init/realize() */
139
Error **errp);
128
MemoryRegion iomem_gfx;
140
@@ -XXX,XX +XXX,XX @@ void* apple_gfx_host_ptr_for_gpa_range(uint64_t guest_physical,
129
@@ -XXX,XX +XXX,XX @@ typedef struct AppleGFXState {
130
QemuConsole *con;
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,
141
uint64_t length, bool read_only,
139
uint64_t length, bool read_only,
142
MemoryRegion **mapping_in_region);
140
MemoryRegion **mapping_in_region);
143
141
144
+extern const PropertyInfo qdev_prop_display_mode;
142
+extern const PropertyInfo qdev_prop_display_mode;
145
+
143
+
...
...
160
+ { 1920, 1080, 60 },
158
+ { 1920, 1080, 60 },
161
+ { 1440, 1080, 60 },
159
+ { 1440, 1080, 60 },
162
+ { 1280, 1024, 60 },
160
+ { 1280, 1024, 60 },
163
};
161
};
164
162
165
/* ------ PGTask and task operations: new/destroy/map/unmap ------ */
163
static Error *apple_gfx_mig_blocker;
166
@@ -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)
167
return disp_desc;
165
return disp_desc;
168
}
166
}
169
167
170
-static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void)
168
-static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void)
171
+static NSArray<PGDisplayMode *> *apple_gfx_create_display_mode_array(
169
+static NSArray<PGDisplayMode *> *apple_gfx_create_display_mode_array(
172
+ const AppleGFXDisplayMode display_modes[], uint32_t display_mode_count)
170
+ const AppleGFXDisplayMode display_modes[], uint32_t display_mode_count)
173
{
171
{
174
- PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)];
172
- PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)];
175
- NSArray<PGDisplayMode*>* mode_array = nil;
173
- NSArray<PGDisplayMode*>* mode_array;
176
- int i;
174
- int i;
177
-
175
-
178
- for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) {
176
- for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) {
179
- modes[i] =
177
- modes[i] =
180
- [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.];
178
- [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.];
...
...
201
+ [mode_array addObject:mode_obj];
199
+ [mode_array addObject:mode_obj];
202
+ [mode_obj release];
200
+ [mode_obj release];
203
}
201
}
204
202
205
return mode_array;
203
return mode_array;
206
@@ -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,
207
Error **errp)
205
PGDeviceDescriptor *desc, Error **errp)
208
{
206
{
209
PGDisplayDescriptor *disp_desc = nil;
207
PGDisplayDescriptor *disp_desc;
210
+ const AppleGFXDisplayMode *display_modes = apple_gfx_default_modes;
208
+ const AppleGFXDisplayMode *display_modes = apple_gfx_default_modes;
211
+ uint32_t num_display_modes = ARRAY_SIZE(apple_gfx_default_modes);
209
+ uint32_t num_display_modes = ARRAY_SIZE(apple_gfx_default_modes);
212
+ NSArray<PGDisplayMode *> *mode_array;
210
+ NSArray<PGDisplayMode *> *mode_array;
213
211
214
if (apple_gfx_mig_blocker == NULL) {
212
if (apple_gfx_mig_blocker == NULL) {
215
error_setg(&apple_gfx_mig_blocker,
213
error_setg(&apple_gfx_mig_blocker,
216
@@ -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,
217
s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc
215
port:0
218
port:0 serialNum:1234];
216
serialNum:next_pgdisplay_serial_num++];
219
[disp_desc release];
217
[disp_desc release];
220
- s->pgdisp.modeList = apple_gfx_prepare_display_mode_array();
218
- s->pgdisp.modeList = apple_gfx_prepare_display_mode_array();
221
+
219
+
222
+ if (s->display_modes != NULL && s->num_display_modes > 0) {
220
+ if (s->display_modes != NULL && s->num_display_modes > 0) {
223
+ trace_apple_gfx_common_realize_modes_property(s->num_display_modes);
221
+ trace_apple_gfx_common_realize_modes_property(s->num_display_modes);
...
...
226
+ }
224
+ }
227
+ s->pgdisp.modeList = mode_array =
225
+ s->pgdisp.modeList = mode_array =
228
+ apple_gfx_create_display_mode_array(display_modes, num_display_modes);
226
+ apple_gfx_create_display_mode_array(display_modes, num_display_modes);
229
+ [mode_array release];
227
+ [mode_array release];
230
228
231
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);
232
230
return true;
233
qatomic_set(&s->cursor_show, true);
234
}
231
}
235
+
232
+
236
+/* ------ Display mode list device property ------ */
233
+/* ------ Display mode list device property ------ */
237
+
234
+
238
+static void apple_gfx_get_display_mode(Object *obj, Visitor *v,
235
+static void apple_gfx_get_display_mode(Object *obj, Visitor *v,
...
...
263
+ const char *endptr;
260
+ const char *endptr;
264
+ g_autofree char *str = NULL;
261
+ g_autofree char *str = NULL;
265
+ int ret;
262
+ int ret;
266
+ int val;
263
+ int val;
267
+
264
+
268
+ visit_type_str(v, name, &str, errp);
265
+ if (!visit_type_str(v, name, &str, errp)) {
269
+ if (*errp) {
270
+ return;
266
+ return;
271
+ }
267
+ }
272
+
268
+
273
+ endptr = str;
269
+ endptr = str;
274
+
270
+
...
...
328
+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
329
325
330
# apple-gfx-mmio.m
326
# apple-gfx-mmio.m
331
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
332
--
328
--
333
2.39.3 (Apple Git-145)
329
2.39.5 (Apple Git-154)
diff view generated by jsdifflib
...
...
47
+
47
+
48
PIIX4 South Bridge (i82371AB)
48
PIIX4 South Bridge (i82371AB)
49
M: Hervé Poussineau <hpoussin@reactos.org>
49
M: Hervé Poussineau <hpoussin@reactos.org>
50
M: Philippe Mathieu-Daudé <philmd@linaro.org>
50
M: Philippe Mathieu-Daudé <philmd@linaro.org>
51
--
51
--
52
2.39.3 (Apple Git-145)
52
2.39.5 (Apple Git-154)
53
53
54
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.
...
...
32
34
33
v8:
35
v8:
34
36
35
* Further improved logging of guest errors.
37
* Further improved logging of guest errors.
36
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
37
hw/vmapple/Kconfig | 2 +
48
hw/vmapple/Kconfig | 2 +
38
hw/vmapple/aes.c | 579 +++++++++++++++++++++++++++++++++++
49
hw/vmapple/aes.c | 581 +++++++++++++++++++++++++++++++++++
39
hw/vmapple/meson.build | 1 +
50
hw/vmapple/meson.build | 1 +
40
hw/vmapple/trace-events | 14 +
51
hw/vmapple/trace-events | 14 +
41
include/hw/vmapple/vmapple.h | 17 +
52
include/hw/vmapple/vmapple.h | 17 +
42
include/qemu/cutils.h | 15 +
53
include/qemu/cutils.h | 15 +
43
util/hexdump.c | 18 ++
54
util/hexdump.c | 18 ++
44
7 files changed, 646 insertions(+)
55
7 files changed, 648 insertions(+)
45
create mode 100644 hw/vmapple/aes.c
56
create mode 100644 hw/vmapple/aes.c
46
create mode 100644 include/hw/vmapple/vmapple.h
57
create mode 100644 include/hw/vmapple/vmapple.h
47
58
48
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
59
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
49
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
...
...
247
+ s->fifo[s->fifo_idx++] = val;
258
+ s->fifo[s->fifo_idx++] = val;
248
+}
259
+}
249
+
260
+
250
+static bool has_payload(AESState *s, uint32_t elems)
261
+static bool has_payload(AESState *s, uint32_t elems)
251
+{
262
+{
252
+ return s->fifo_idx >= (elems + 1);
263
+ return s->fifo_idx >= elems + 1;
253
+}
264
+}
254
+
265
+
255
+static bool cmd_key(AESState *s)
266
+static bool cmd_key(AESState *s)
256
+{
267
+{
257
+ uint32_t cmd = s->fifo[0];
268
+ uint32_t cmd = s->fifo[0];
...
...
350
+ return false;
361
+ return false;
351
+ }
362
+ }
352
+
363
+
353
+ if (ctxt_key >= ARRAY_SIZE(s->key) ||
364
+ if (ctxt_key >= ARRAY_SIZE(s->key) ||
354
+ ctxt_iv >= ARRAY_SIZE(s->iv)) {
365
+ ctxt_iv >= ARRAY_SIZE(s->iv)) {
355
+ /* Invalid input */
356
+ 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__);
357
+ return false;
367
+ return false;
358
+ }
368
+ }
359
+
369
+
360
+ src = g_byte_array_sized_new(len);
370
+ src = g_byte_array_sized_new(len);
...
...
428
+static bool cmd_store_iv(AESState *s)
438
+static bool cmd_store_iv(AESState *s)
429
+{
439
+{
430
+ uint32_t cmd = s->fifo[0];
440
+ uint32_t cmd = s->fifo[0];
431
+ 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;
432
+ uint64_t addr = s->fifo[1];
442
+ uint64_t addr = s->fifo[1];
443
+ MemTxResult dma_result;
433
+
444
+
434
+ if (!has_payload(s, 1)) {
445
+ if (!has_payload(s, 1)) {
435
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
446
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
436
+ return false;
447
+ return false;
437
+ }
448
+ }
...
...
442
+ __func__, ctxt, ARRAY_SIZE(s->iv) - 1);
453
+ __func__, ctxt, ARRAY_SIZE(s->iv) - 1);
443
+ return false;
454
+ return false;
444
+ }
455
+ }
445
+
456
+
446
+ addr |= ((uint64_t)cmd << 32) & 0xff00000000ULL;
457
+ addr |= ((uint64_t)cmd << 32) & 0xff00000000ULL;
447
+ 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);
448
+
461
+
449
+ 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],
450
+ s->iv[ctxt].iv[2], s->iv[ctxt].iv[3]);
463
+ s->iv[ctxt].iv[2], s->iv[ctxt].iv[3]);
451
+
464
+
452
+ return true;
465
+ return dma_result == MEMTX_OK;
453
+}
466
+}
454
+
467
+
455
+static bool cmd_flag(AESState *s)
468
+static bool cmd_flag(AESState *s)
456
+{
469
+{
457
+ uint32_t cmd = s->fifo[0];
470
+ uint32_t cmd = s->fifo[0];
...
...
501
+
514
+
502
+ if (success) {
515
+ if (success) {
503
+ s->fifo_idx = 0;
516
+ s->fifo_idx = 0;
504
+ }
517
+ }
505
+
518
+
506
+ trace_aes_fifo_process(cmd, success ? 1 : 0);
519
+ trace_aes_fifo_process(cmd, success);
507
+}
520
+}
508
+
521
+
509
+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)
510
+{
523
+{
511
+ AESState *s = opaque;
524
+ AESState *s = opaque;
...
...
657
+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"
658
+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"
659
+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"
660
+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"
661
+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"
662
+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"
663
+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
664
+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
665
+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
666
+aes_dump_data(const char *desc, const char *hex) "%s%s"
679
+aes_dump_data(const char *desc, const char *hex) "%s%s"
667
+
680
+
...
...
744
+ *(buffer++) = hexdump_nibble(val & 0xf);
757
+ *(buffer++) = hexdump_nibble(val & 0xf);
745
+ }
758
+ }
746
+ *buffer = '\0';
759
+ *buffer = '\0';
747
+}
760
+}
748
--
761
--
749
2.39.3 (Apple Git-145)
762
2.39.5 (Apple Git-154)
750
763
751
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
...
...
20
v8:
22
v8:
21
23
22
* Replaced uses of cpu_physical_memory_read with dma_memory_read.
24
* Replaced uses of cpu_physical_memory_read with dma_memory_read.
23
* Replaced an instance of g_free with g_autofree.
25
* Replaced an instance of g_free with g_autofree.
24
26
27
v9:
28
29
* Replaced uses of cpu_physical_memory_write with dma_memory_write.
30
25
hw/vmapple/Kconfig | 3 +
31
hw/vmapple/Kconfig | 3 +
26
hw/vmapple/bdif.c | 271 +++++++++++++++++++++++++++++++++++
32
hw/vmapple/bdif.c | 275 +++++++++++++++++++++++++++++++++++
27
hw/vmapple/meson.build | 1 +
33
hw/vmapple/meson.build | 1 +
28
hw/vmapple/trace-events | 5 +
34
hw/vmapple/trace-events | 5 +
29
include/hw/vmapple/vmapple.h | 2 +
35
include/hw/vmapple/vmapple.h | 2 +
30
5 files changed, 282 insertions(+)
36
5 files changed, 286 insertions(+)
31
create mode 100644 hw/vmapple/bdif.c
37
create mode 100644 hw/vmapple/bdif.c
32
38
33
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
39
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
34
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/vmapple/Kconfig
41
--- a/hw/vmapple/Kconfig
...
...
229
+ trace_bdif_vblk_read(devid == DEVID_AUX ? "aux" : "root",
235
+ trace_bdif_vblk_read(devid == DEVID_AUX ? "aux" : "root",
230
+ req.data.addr, off, req.data.len, r);
236
+ req.data.addr, off, req.data.len, r);
231
+ if (r < 0) {
237
+ if (r < 0) {
232
+ goto out;
238
+ goto out;
233
+ }
239
+ }
234
+ cpu_physical_memory_write(req.data.addr, buf, req.data.len);
240
+ dma_result = dma_memory_write(&address_space_memory, req.data.addr, buf,
235
+ ret = VBLK_RET_SUCCESS;
241
+ req.data.len, MEMTXATTRS_UNSPECIFIED);
242
+ if (dma_result == MEMTX_OK) {
243
+ ret = VBLK_RET_SUCCESS;
244
+ }
236
+ break;
245
+ break;
237
+ case VBLK_DATA_FLAGS_WRITE:
246
+ case VBLK_DATA_FLAGS_WRITE:
238
+ /* Not needed, iBoot only reads */
247
+ /* Not needed, iBoot only reads */
239
+ break;
248
+ break;
240
+ default:
249
+ default:
241
+ break;
250
+ break;
242
+ }
251
+ }
243
+
252
+
244
+out:
253
+out:
245
+ cpu_physical_memory_write(req.retval.addr, &ret, 1);
254
+ dma_memory_write(&address_space_memory, req.retval.addr, &ret, 1,
255
+ MEMTXATTRS_UNSPECIFIED);
246
+}
256
+}
247
+
257
+
248
+static void bdif_write(void *opaque, hwaddr offset,
258
+static void bdif_write(void *opaque, hwaddr offset,
249
+ uint64_t value, unsigned size)
259
+ uint64_t value, unsigned size)
250
+{
260
+{
...
...
348
358
349
+#define TYPE_VMAPPLE_BDIF "vmapple-bdif"
359
+#define TYPE_VMAPPLE_BDIF "vmapple-bdif"
350
+
360
+
351
#endif /* HW_VMAPPLE_VMAPPLE_H */
361
#endif /* HW_VMAPPLE_VMAPPLE_H */
352
--
362
--
353
2.39.3 (Apple Git-145)
363
2.39.5 (Apple Git-154)
354
364
355
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
...
...
32
fixed-length strings to be more useful to users than developers.
34
fixed-length strings to be more useful to users than developers.
33
35
34
v8:
36
v8:
35
37
36
* Consistent parenthesising of macro arguments for better safety.
38
* Consistent parenthesising of macro arguments for better safety.
39
40
v10:
41
42
* Slightly tidier error reporting for overlong property values.
37
43
38
hw/vmapple/Kconfig | 3 +
44
hw/vmapple/Kconfig | 3 +
39
hw/vmapple/cfg.c | 196 +++++++++++++++++++++++++++++++++++
45
hw/vmapple/cfg.c | 196 +++++++++++++++++++++++++++++++++++
40
hw/vmapple/meson.build | 1 +
46
hw/vmapple/meson.build | 1 +
41
include/hw/vmapple/vmapple.h | 2 +
47
include/hw/vmapple/vmapple.h | 2 +
...
...
139
+static bool set_fixlen_property_or_error(char *restrict dst,
145
+static bool set_fixlen_property_or_error(char *restrict dst,
140
+ const char *restrict src,
146
+ const char *restrict src,
141
+ size_t dst_size, Error **errp,
147
+ size_t dst_size, Error **errp,
142
+ const char *property_name)
148
+ const char *property_name)
143
+{
149
+{
150
+ ERRP_GUARD();
144
+ size_t len;
151
+ size_t len;
145
+
152
+
146
+ len = g_strlcpy(dst, src, dst_size);
153
+ len = g_strlcpy(dst, src, dst_size);
147
+ if (len < dst_size) { /* len does not count nul terminator */
154
+ if (len < dst_size) { /* len does not count nul terminator */
148
+ return true;
155
+ return true;
149
+ }
156
+ }
150
+
157
+
151
+ error_setg(errp,
158
+ error_setg(errp, "Provided value too long for property '%s'", property_name);
152
+ "Failed to set property '%s' on VMApple 'cfg' device: length "
159
+ error_append_hint(errp, "length (%zu) exceeds maximum of %zu\n",
153
+ "(%zu) exceeds maximum of %zu",
160
+ len, dst_size - 1);
154
+ property_name, len, dst_size - 1);
155
+ return false;
161
+ return false;
156
+}
162
+}
157
+
163
+
158
+#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) \
159
+ do { \
165
+ do { \
...
...
273
279
274
+#define TYPE_VMAPPLE_CFG "vmapple-cfg"
280
+#define TYPE_VMAPPLE_CFG "vmapple-cfg"
275
+
281
+
276
#endif /* HW_VMAPPLE_VMAPPLE_H */
282
#endif /* HW_VMAPPLE_VMAPPLE_H */
277
--
283
--
278
2.39.3 (Apple Git-145)
284
2.39.5 (Apple Git-154)
279
285
280
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
---
39
40
40
v3:
41
v3:
41
* Rebased on latest upstream, updated affinity and NIC creation
42
* Rebased on latest upstream, updated affinity and NIC creation
42
API usage
43
API usage
43
* Included Apple-variant virtio-blk in build dependency
44
* Included Apple-variant virtio-blk in build dependency
44
* Updated API usage for setting 'redist-region-count' array-typed property
45
* Updated API usage for setting 'redist-region-count' array-typed property on GIC.
45
on GIC.
46
* 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
47
drivers) to an XHCI USB controller and USB HID devices.
47
drivers) to an XHCI USB controller and USB HID devices.
48
48
49
v4:
49
v4:
50
* Fixups for v4 changes to the other patches in the set.
50
* Fixups for v4 changes to the other patches in the set.
...
...
66
66
67
v8:
67
v8:
68
* Use object_property_add_uint64_ptr rather than defining custom UUID
68
* Use object_property_add_uint64_ptr rather than defining custom UUID
69
property get/set functions.
69
property get/set functions.
70
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
71
MAINTAINERS | 1 +
86
MAINTAINERS | 1 +
72
contrib/vmapple/uuid.sh | 9 +
87
contrib/vmapple/uuid.sh | 9 +
73
docs/system/arm/vmapple.rst | 60 ++++
88
docs/system/arm/vmapple.rst | 63 ++++
74
docs/system/target-arm.rst | 1 +
89
docs/system/target-arm.rst | 1 +
75
hw/vmapple/Kconfig | 20 ++
90
hw/vmapple/Kconfig | 20 ++
76
hw/vmapple/meson.build | 1 +
91
hw/vmapple/meson.build | 1 +
77
hw/vmapple/vmapple.c | 638 ++++++++++++++++++++++++++++++++++++
92
hw/vmapple/vmapple.c | 646 ++++++++++++++++++++++++++++++++++++
78
7 files changed, 730 insertions(+)
93
7 files changed, 741 insertions(+)
79
create mode 100755 contrib/vmapple/uuid.sh
94
create mode 100755 contrib/vmapple/uuid.sh
80
create mode 100644 docs/system/arm/vmapple.rst
95
create mode 100644 docs/system/arm/vmapple.rst
81
create mode 100644 hw/vmapple/vmapple.c
96
create mode 100644 hw/vmapple/vmapple.c
82
97
83
diff --git a/MAINTAINERS b/MAINTAINERS
98
diff --git a/MAINTAINERS b/MAINTAINERS
...
...
125
+
140
+
126
+To run the vmapple machine model, you need to
141
+To run the vmapple machine model, you need to
127
+
142
+
128
+ * Run on Apple Silicon
143
+ * Run on Apple Silicon
129
+ * Run on macOS 12.0 or above
144
+ * Run on macOS 12.0 or above
130
+ * 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
131
+ 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.
132
+
149
+
133
+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
134
+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.
135
+
152
+
136
+.. code-block:: bash
153
+.. code-block:: bash
...
...
153
+to get better interactive access into the target system:
170
+to get better interactive access into the target system:
154
+
171
+
155
+.. code-block:: bash
172
+.. code-block:: bash
156
+ :caption: Example execution command line
173
+ :caption: Example execution command line
157
+
174
+
158
+ $ UUID=$(uuid.sh macosvm.json)
175
+ $ UUID="$(contrib/vmapple/uuid.sh 'macosvm.json')"
159
+ $ AVPBOOTER=/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin
176
+ $ AVPBOOTER="/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin"
160
+ $ AUX=aux.img.trimmed
177
+ $ AUX="aux.img.trimmed"
161
+ $ DISK=disk.img
178
+ $ DISK="disk.img"
162
+ $ qemu-system-aarch64 \
179
+ $ qemu-system-aarch64 \
163
+ -serial mon:stdio \
180
+ -serial mon:stdio \
164
+ -m 4G \
181
+ -m 4G \
165
+ -accel hvf \
182
+ -accel hvf \
166
+ -M vmapple,uuid=$UUID \
183
+ -M vmapple,uuid="$UUID" \
167
+ -bios $AVPBOOTER \
184
+ -bios "$AVPBOOTER" \
168
+ -drive file="$AUX",if=pflash,format=raw \
185
+ -drive file="$AUX",if=pflash,format=raw \
169
+ -drive file="$DISK",if=pflash,format=raw \
186
+ -drive file="$DISK",if=pflash,format=raw \
170
+ -drive file="$AUX",if=none,id=aux,format=raw \
187
+ -drive file="$AUX",if=none,id=aux,format=raw \
171
+ -drive file="$DISK",if=none,id=root,format=raw \
188
+ -drive file="$DISK",if=none,id=root,format=raw \
172
+ -device vmapple-virtio-aux,drive=aux \
189
+ -device vmapple-virtio-blk-pci,variant=aux,drive=aux \
173
+ -device vmapple-virtio-root,drive=root \
190
+ -device vmapple-virtio-blk-pci,variant=root,drive=root \
174
+ -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 \
175
+ -net nic,model=virtio-net-pci \
192
+ -device virtio-net-pci,netdev=net0
193
+
176
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
177
index XXXXXXX..XXXXXXX 100644
195
index XXXXXXX..XXXXXXX 100644
178
--- a/docs/system/target-arm.rst
196
--- a/docs/system/target-arm.rst
179
+++ b/docs/system/target-arm.rst
197
+++ b/docs/system/target-arm.rst
180
@@ -XXX,XX +XXX,XX @@ Board-specific documentation
198
@@ -XXX,XX +XXX,XX @@ Board-specific documentation
...
...
296
+ struct arm_boot_info bootinfo;
314
+ struct arm_boot_info bootinfo;
297
+ MemMapEntry *memmap;
315
+ MemMapEntry *memmap;
298
+ const int *irqmap;
316
+ const int *irqmap;
299
+ DeviceState *gic;
317
+ DeviceState *gic;
300
+ DeviceState *cfg;
318
+ DeviceState *cfg;
319
+ DeviceState *pvpanic;
301
+ Notifier powerdown_notifier;
320
+ Notifier powerdown_notifier;
302
+ PCIBus *bus;
321
+ PCIBus *bus;
303
+ MemoryRegion fw_mr;
322
+ MemoryRegion fw_mr;
304
+ MemoryRegion ecam_alias;
323
+ MemoryRegion ecam_alias;
305
+ uint64_t uuid;
324
+ uint64_t uuid;
...
...
427
+ sysbus_realize_and_unref(bdif_sb, &error_fatal);
446
+ sysbus_realize_and_unref(bdif_sb, &error_fatal);
428
+}
447
+}
429
+
448
+
430
+static void create_pvpanic(VMAppleMachineState *vms, MemoryRegion *mem)
449
+static void create_pvpanic(VMAppleMachineState *vms, MemoryRegion *mem)
431
+{
450
+{
432
+ SysBusDevice *cfg;
451
+ SysBusDevice *pvpanic;
433
+
452
+
434
+ vms->cfg = qdev_new(TYPE_PVPANIC_MMIO_DEVICE);
453
+ vms->pvpanic = qdev_new(TYPE_PVPANIC_MMIO_DEVICE);
435
+ cfg = SYS_BUS_DEVICE(vms->cfg);
454
+ pvpanic = SYS_BUS_DEVICE(vms->pvpanic);
436
+ sysbus_mmio_map(cfg, 0, vms->memmap[VMAPPLE_PVPANIC].base);
455
+ sysbus_mmio_map(pvpanic, 0, vms->memmap[VMAPPLE_PVPANIC].base);
437
+
456
+
438
+ sysbus_realize_and_unref(cfg, &error_fatal);
457
+ sysbus_realize_and_unref(pvpanic, &error_fatal);
439
+}
458
+}
440
+
459
+
441
+static void create_cfg(VMAppleMachineState *vms, MemoryRegion *mem)
460
+static bool create_cfg(VMAppleMachineState *vms, MemoryRegion *mem,
442
+{
461
+ Error **errp)
462
+{
463
+ ERRP_GUARD();
443
+ SysBusDevice *cfg;
464
+ SysBusDevice *cfg;
444
+ MachineState *machine = MACHINE(vms);
465
+ MachineState *machine = MACHINE(vms);
445
+ uint32_t rnd = 1;
466
+ uint32_t rnd = 1;
446
+
467
+
447
+ vms->cfg = qdev_new(TYPE_VMAPPLE_CFG);
468
+ vms->cfg = qdev_new(TYPE_VMAPPLE_CFG);
...
...
453
+ qdev_prop_set_uint32(vms->cfg, "nr-cpus", machine->smp.cpus);
474
+ qdev_prop_set_uint32(vms->cfg, "nr-cpus", machine->smp.cpus);
454
+ qdev_prop_set_uint64(vms->cfg, "ecid", vms->uuid);
475
+ qdev_prop_set_uint64(vms->cfg, "ecid", vms->uuid);
455
+ qdev_prop_set_uint64(vms->cfg, "ram-size", machine->ram_size);
476
+ qdev_prop_set_uint64(vms->cfg, "ram-size", machine->ram_size);
456
+ qdev_prop_set_uint32(vms->cfg, "rnd", rnd);
477
+ qdev_prop_set_uint32(vms->cfg, "rnd", rnd);
457
+
478
+
458
+ 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;
459
+}
485
+}
460
+
486
+
461
+static void create_gfx(VMAppleMachineState *vms, MemoryRegion *mem)
487
+static void create_gfx(VMAppleMachineState *vms, MemoryRegion *mem)
462
+{
488
+{
463
+ int irq_gfx = vms->irqmap[VMAPPLE_APV_GFX];
489
+ int irq_gfx = vms->irqmap[VMAPPLE_APV_GFX];
...
...
757
+ create_pcie(vms);
783
+ create_pcie(vms);
758
+
784
+
759
+ create_gpio_devices(vms, VMAPPLE_GPIO, sysmem);
785
+ create_gpio_devices(vms, VMAPPLE_GPIO, sysmem);
760
+
786
+
761
+ vmapple_firmware_init(vms, sysmem);
787
+ vmapple_firmware_init(vms, sysmem);
762
+ create_cfg(vms, sysmem);
788
+ create_cfg(vms, sysmem, &error_fatal);
763
+
789
+
764
+ /* connect powerdown request */
790
+ /* connect powerdown request */
765
+ vms->powerdown_notifier.notify = vmapple_powerdown_req;
791
+ vms->powerdown_notifier.notify = vmapple_powerdown_req;
766
+ qemu_register_powerdown_notifier(&vms->powerdown_notifier);
792
+ qemu_register_powerdown_notifier(&vms->powerdown_notifier);
767
+
793
+
...
...
859
+{
885
+{
860
+ type_register_static(&vmapple_machine_info);
886
+ type_register_static(&vmapple_machine_info);
861
+}
887
+}
862
+type_init(machvmapple_machine_init);
888
+type_init(machvmapple_machine_init);
863
+
889
+
864
+static void vmapple_machine_9_2_options(MachineClass *mc)
890
+static void vmapple_machine_10_0_options(MachineClass *mc)
865
+{
891
+{
866
+}
892
+}
867
+DEFINE_VMAPPLE_MACHINE_AS_LATEST(9, 2)
893
+DEFINE_VMAPPLE_MACHINE_AS_LATEST(10, 0)
868
+
894
+
869
--
895
--
870
2.39.3 (Apple Git-145)
896
2.39.5 (Apple Git-154)
871
897
872
898
diff view generated by jsdifflib