... | ... | ||
---|---|---|---|
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 |
... | ... | ||
208 | property instead of 2 different subtypes for aux and root volumes. | 205 | property instead of 2 different subtypes for aux and root volumes. |
209 | * 15/15 (vmapple machine type): Documentation fixup for changed virtio-blk | 206 | * 15/15 (vmapple machine type): Documentation fixup for changed virtio-blk |
210 | device type; small improvements to shell commands in documentation; | 207 | device type; small improvements to shell commands in documentation; |
211 | improved propagation of errors during cfg device instantiation. | 208 | improved propagation of errors during cfg device instantiation. |
212 | 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. | ||
213 | 231 | ||
214 | Alexander Graf (9): | 232 | Alexander Graf (9): |
215 | hw: Add vmapple subdir | 233 | hw: Add vmapple subdir |
216 | hw/misc/pvpanic: Add MMIO interface | 234 | hw/misc/pvpanic: Add MMIO interface |
217 | hvf: arm: Ignore writes to CNTP_CTL_EL0 | 235 | hvf: arm: Ignore writes to CNTP_CTL_EL0 |
... | ... | ||
239 | hw/arm/sbsa-ref.c | 2 +- | 257 | hw/arm/sbsa-ref.c | 2 +- |
240 | hw/arm/virt.c | 2 +- | 258 | hw/arm/virt.c | 2 +- |
241 | hw/block/virtio-blk.c | 58 +- | 259 | hw/block/virtio-blk.c | 58 +- |
242 | hw/core/qdev-properties-system.c | 8 + | 260 | hw/core/qdev-properties-system.c | 8 + |
243 | hw/display/Kconfig | 13 + | 261 | hw/display/Kconfig | 13 + |
244 | hw/display/apple-gfx-mmio.m | 289 ++++++++++ | 262 | hw/display/apple-gfx-mmio.m | 289 +++++++++ |
245 | hw/display/apple-gfx-pci.m | 157 +++++ | 263 | hw/display/apple-gfx-pci.m | 157 +++++ |
246 | hw/display/apple-gfx.h | 78 +++ | 264 | hw/display/apple-gfx.h | 77 +++ |
247 | hw/display/apple-gfx.m | 862 ++++++++++++++++++++++++++++ | 265 | hw/display/apple-gfx.m | 880 ++++++++++++++++++++++++++++ |
248 | hw/display/meson.build | 7 + | 266 | hw/display/meson.build | 7 + |
249 | hw/display/trace-events | 30 + | 267 | hw/display/trace-events | 30 + |
250 | hw/i386/microvm.c | 2 +- | 268 | hw/i386/microvm.c | 2 +- |
251 | hw/loongarch/virt.c | 2 +- | 269 | hw/loongarch/virt.c | 12 +- |
252 | hw/meson.build | 1 + | 270 | hw/meson.build | 1 + |
253 | hw/mips/loongson3_virt.c | 2 +- | 271 | hw/mips/loongson3_virt.c | 2 +- |
254 | hw/misc/Kconfig | 4 + | 272 | hw/misc/Kconfig | 4 + |
255 | hw/misc/meson.build | 1 + | 273 | hw/misc/meson.build | 1 + |
256 | hw/misc/pvpanic-mmio.c | 61 ++ | 274 | hw/misc/pvpanic-mmio.c | 61 ++ |
257 | hw/openrisc/virt.c | 12 +- | 275 | hw/openrisc/virt.c | 12 +- |
258 | hw/pci-host/gpex.c | 43 +- | 276 | hw/pci-host/gpex.c | 43 +- |
259 | hw/riscv/virt.c | 12 +- | 277 | hw/riscv/virt.c | 12 +- |
260 | hw/vmapple/Kconfig | 32 ++ | 278 | hw/vmapple/Kconfig | 32 + |
261 | hw/vmapple/aes.c | 581 +++++++++++++++++++ | 279 | hw/vmapple/aes.c | 581 ++++++++++++++++++ |
262 | hw/vmapple/bdif.c | 275 +++++++++ | 280 | hw/vmapple/bdif.c | 275 +++++++++ |
263 | hw/vmapple/cfg.c | 196 +++++++ | 281 | hw/vmapple/cfg.c | 196 +++++++ |
264 | hw/vmapple/meson.build | 5 + | 282 | hw/vmapple/meson.build | 5 + |
265 | hw/vmapple/trace-events | 21 + | 283 | hw/vmapple/trace-events | 21 + |
266 | hw/vmapple/trace.h | 1 + | 284 | hw/vmapple/trace.h | 1 + |
267 | hw/vmapple/virtio-blk.c | 205 +++++++ | 285 | hw/vmapple/virtio-blk.c | 205 +++++++ |
268 | hw/vmapple/vmapple.c | 646 +++++++++++++++++++++ | 286 | hw/vmapple/vmapple.c | 646 ++++++++++++++++++++ |
287 | hw/xen/xen-pvh-common.c | 2 +- | ||
269 | hw/xtensa/virt.c | 2 +- | 288 | hw/xtensa/virt.c | 2 +- |
270 | include/hw/misc/pvpanic.h | 1 + | 289 | include/hw/misc/pvpanic.h | 1 + |
271 | include/hw/pci-host/gpex.h | 7 +- | 290 | include/hw/pci-host/gpex.h | 7 +- |
272 | include/hw/pci/pci_ids.h | 1 + | 291 | include/hw/pci/pci_ids.h | 1 + |
273 | include/hw/qdev-properties-system.h | 5 + | 292 | include/hw/qdev-properties-system.h | 5 + |
274 | include/hw/virtio/virtio-blk.h | 11 +- | 293 | include/hw/virtio/virtio-blk.h | 11 +- |
275 | include/hw/vmapple/vmapple.h | 23 + | 294 | include/hw/vmapple/vmapple.h | 23 + |
276 | include/qemu-main.h | 21 +- | 295 | include/qemu-main.h | 14 +- |
277 | include/qemu/cutils.h | 15 + | 296 | include/qemu/cutils.h | 15 + |
278 | include/qemu/typedefs.h | 1 + | ||
279 | meson.build | 5 + | 297 | meson.build | 5 + |
280 | qapi/virtio.json | 14 + | 298 | qapi/virtio.json | 14 + |
281 | system/main.c | 50 +- | 299 | system/main.c | 37 +- |
282 | target/arm/hvf/hvf.c | 9 + | 300 | target/arm/hvf/hvf.c | 9 + |
283 | ui/cocoa.m | 54 +- | 301 | ui/cocoa.m | 54 +- |
284 | ui/gtk.c | 8 + | 302 | ui/gtk.c | 4 + |
285 | ui/sdl2.c | 4 + | 303 | ui/sdl2.c | 4 + |
286 | util/hexdump.c | 18 + | 304 | util/hexdump.c | 18 + |
287 | 53 files changed, 3840 insertions(+), 106 deletions(-) | 305 | 53 files changed, 3840 insertions(+), 110 deletions(-) |
288 | create mode 100755 contrib/vmapple/uuid.sh | 306 | create mode 100755 contrib/vmapple/uuid.sh |
289 | create mode 100644 docs/system/arm/vmapple.rst | 307 | create mode 100644 docs/system/arm/vmapple.rst |
290 | create mode 100644 hw/display/apple-gfx-mmio.m | 308 | create mode 100644 hw/display/apple-gfx-mmio.m |
291 | create mode 100644 hw/display/apple-gfx-pci.m | 309 | create mode 100644 hw/display/apple-gfx-pci.m |
292 | create mode 100644 hw/display/apple-gfx.h | 310 | create mode 100644 hw/display/apple-gfx.h |
... | ... | ||
302 | create mode 100644 hw/vmapple/virtio-blk.c | 320 | create mode 100644 hw/vmapple/virtio-blk.c |
303 | create mode 100644 hw/vmapple/vmapple.c | 321 | create mode 100644 hw/vmapple/vmapple.c |
304 | create mode 100644 include/hw/vmapple/vmapple.h | 322 | create mode 100644 include/hw/vmapple/vmapple.h |
305 | 323 | ||
306 | -- | 324 | -- |
307 | 2.39.3 (Apple Git-145) | 325 | 2.39.5 (Apple Git-154) |
308 | 326 | ||
309 | 327 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
42 | 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 |
43 | handled, regardless of chosen UI. The new PV graphics device will | 43 | handled, regardless of chosen UI. The new PV graphics device will |
44 | 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 |
45 | operating systems. | 45 | operating systems. |
46 | 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 | |||
47 | Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu> | 56 | Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu> |
48 | 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> | ||
49 | --- | 59 | --- |
50 | 60 | ||
51 | v5: | 61 | v5: |
52 | 62 | ||
53 | * 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 |
... | ... | ||
67 | 77 | ||
68 | v10: | 78 | v10: |
69 | 79 | ||
70 | * Added comments clarifying the functionality and purpose of qemu_main. | 80 | * Added comments clarifying the functionality and purpose of qemu_main. |
71 | 81 | ||
72 | include/qemu-main.h | 21 ++++++++++++++-- | 82 | v11: |
73 | include/qemu/typedefs.h | 1 + | 83 | |
74 | system/main.c | 50 ++++++++++++++++++++++++++++++++++---- | 84 | * Removed the qemu_main_fn typedef again. |
75 | ui/cocoa.m | 54 ++++++++++------------------------------- | 85 | * Consolidation of main, qemu_default_main, and call_qemu_default_main |
76 | ui/gtk.c | 8 ++++++ | 86 | so that the latter has been eliminated altogether. |
77 | ui/sdl2.c | 4 +++ | 87 | * Reinstated the #include <SDL.h> directive, added comment saying |
78 | 6 files changed, 90 insertions(+), 48 deletions(-) | 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(-) | ||
79 | 102 | ||
80 | 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 |
81 | index XXXXXXX..XXXXXXX 100644 | 104 | index XXXXXXX..XXXXXXX 100644 |
82 | --- a/include/qemu-main.h | 105 | --- a/include/qemu-main.h |
83 | +++ b/include/qemu-main.h | 106 | +++ b/include/qemu-main.h |
84 | @@ -XXX,XX +XXX,XX @@ | 107 | @@ -XXX,XX +XXX,XX @@ |
85 | #ifndef QEMU_MAIN_H | 108 | #ifndef QEMU_MAIN_H |
86 | #define QEMU_MAIN_H | 109 | #define QEMU_MAIN_H |
87 | 110 | ||
88 | -int qemu_default_main(void); | 111 | -int qemu_default_main(void); |
89 | -extern int (*qemu_main)(void); | ||
90 | +/* | 112 | +/* |
91 | + * The function to run on the main (initial) thread of the process. | 113 | + * The function to run on the main (initial) thread of the process. |
92 | + * NULL means QEMU's main event loop. | 114 | + * NULL means QEMU's main event loop. |
93 | + * When non-NULL, QEMU's main event loop will run on a purposely created | 115 | + * When non-NULL, QEMU's main event loop will run on a purposely created |
94 | + * thread, after which the provided function pointer will be invoked on | 116 | + * thread, after which the provided function pointer will be invoked on |
95 | + * the initial thread. | 117 | + * the initial thread. |
96 | + * This is useful on platforms which treat the main thread as special | 118 | + * This is useful on platforms which treat the main thread as special |
97 | + * (macOS/Darwin) and/or require all UI API calls to occur from a | 119 | + * (macOS/Darwin) and/or require all UI API calls to occur from the main |
98 | + * specific thread. | 120 | + * thread. Those platforms can initialise it to a specific function, |
99 | + * Implementing this via a global function pointer variable is a bit | 121 | + * while UI implementations may reset it to NULL during their init if they |
100 | + * ugly, but it's probably worth investigating the existing UI thread rule | 122 | + * will handle system and UI events on the main thread via QEMU's own main |
101 | + * violations in the SDL (e.g. #2537) and GTK+ back-ends. Fixing those | 123 | + * event loop. |
102 | + * issues might precipitate requirements similar but not identical to those | ||
103 | + * of the Cocoa UI; hopefully we'll see some kind of pattern emerge, which | ||
104 | + * can then be used as a basis for an overhaul. (In fact, it may turn | ||
105 | + * out to be simplest to split the UI/native platform event thread from the | ||
106 | + * QEMU main event loop on all platforms, with any UI or even none at all.) | ||
107 | + */ | 124 | + */ |
108 | +extern qemu_main_fn qemu_main; | 125 | extern int (*qemu_main)(void); |
109 | 126 | ||
110 | #endif /* QEMU_MAIN_H */ | 127 | #endif /* QEMU_MAIN_H */ |
111 | diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h | ||
112 | index XXXXXXX..XXXXXXX 100644 | ||
113 | --- a/include/qemu/typedefs.h | ||
114 | +++ b/include/qemu/typedefs.h | ||
115 | @@ -XXX,XX +XXX,XX @@ typedef struct IRQState *qemu_irq; | ||
116 | * Function types | ||
117 | */ | ||
118 | typedef void (*qemu_irq_handler)(void *opaque, int n, int level); | ||
119 | +typedef int (*qemu_main_fn)(void); | ||
120 | |||
121 | #endif /* QEMU_TYPEDEFS_H */ | ||
122 | diff --git a/system/main.c b/system/main.c | 128 | diff --git a/system/main.c b/system/main.c |
123 | index XXXXXXX..XXXXXXX 100644 | 129 | index XXXXXXX..XXXXXXX 100644 |
124 | --- a/system/main.c | 130 | --- a/system/main.c |
125 | +++ b/system/main.c | 131 | +++ b/system/main.c |
126 | @@ -XXX,XX +XXX,XX @@ | 132 | @@ -XXX,XX +XXX,XX @@ |
127 | 133 | ||
128 | #include "qemu/osdep.h" | 134 | #include "qemu/osdep.h" |
129 | #include "qemu-main.h" | 135 | #include "qemu-main.h" |
130 | +#include "qemu/main-loop.h" | 136 | +#include "qemu/main-loop.h" |
131 | #include "sysemu/sysemu.h" | 137 | #include "sysemu/sysemu.h" |
132 | 138 | ||
133 | -#ifdef CONFIG_SDL | 139 | #ifdef CONFIG_SDL |
134 | -#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) | ||
135 | +#ifdef CONFIG_DARWIN | 149 | +#ifdef CONFIG_DARWIN |
136 | +#include <CoreFoundation/CoreFoundation.h> | 150 | +#include <CoreFoundation/CoreFoundation.h> |
137 | #endif | 151 | +#endif |
138 | 152 | + | |
139 | -int qemu_default_main(void) | 153 | +static void *qemu_default_main(void *opaque) |
140 | +static int qemu_default_main(void) | ||
141 | { | 154 | { |
142 | int status; | 155 | int status; |
143 | 156 | ||
144 | @@ -XXX,XX +XXX,XX @@ int qemu_default_main(void) | 157 | + bql_lock(); |
145 | return status; | 158 | status = qemu_main_loop(); |
146 | } | 159 | qemu_cleanup(status); |
160 | + bql_unlock(); | ||
161 | |||
162 | - return status; | ||
163 | + exit(status); | ||
164 | } | ||
147 | 165 | ||
148 | -int (*qemu_main)(void) = qemu_default_main; | 166 | -int (*qemu_main)(void) = qemu_default_main; |
149 | +/* | 167 | +int (*qemu_main)(void); |
150 | + * Various macOS system libraries, including the Cocoa UI and anything using | ||
151 | + * libdispatch, such as ParavirtualizedGraphics.framework, requires that the | ||
152 | + * main runloop, on the main (initial) thread be running or at least regularly | ||
153 | + * polled for events. A special mode is therefore supported, where the QEMU | ||
154 | + * main loop runs on a separate thread and the main thread handles the | ||
155 | + * CF/Cocoa runloop. | ||
156 | + */ | ||
157 | + | ||
158 | +static void *call_qemu_default_main(void *opaque) | ||
159 | +{ | ||
160 | + int status; | ||
161 | + | ||
162 | + bql_lock(); | ||
163 | + status = qemu_default_main(); | ||
164 | + bql_unlock(); | ||
165 | + | ||
166 | + exit(status); | ||
167 | +} | ||
168 | + | 168 | + |
169 | +#ifdef CONFIG_DARWIN | 169 | +#ifdef CONFIG_DARWIN |
170 | +static int os_darwin_cfrunloop_main(void) | 170 | +static int os_darwin_cfrunloop_main(void) |
171 | +{ | 171 | +{ |
172 | + CFRunLoopRun(); | 172 | + CFRunLoopRun(); |
173 | + abort(); | 173 | + g_assert_not_reached(); |
174 | +} | 174 | +} |
175 | + | 175 | +int (*qemu_main)(void) = os_darwin_cfrunloop_main; |
176 | +qemu_main_fn qemu_main = os_darwin_cfrunloop_main; | ||
177 | +#else | ||
178 | +qemu_main_fn qemu_main; | ||
179 | +#endif | 176 | +#endif |
180 | 177 | ||
181 | int main(int argc, char **argv) | 178 | int main(int argc, char **argv) |
182 | { | 179 | { |
183 | + QemuThread main_loop_thread; | ||
184 | + | ||
185 | qemu_init(argc, argv); | 180 | qemu_init(argc, argv); |
186 | - return qemu_main(); | 181 | - return qemu_main(); |
182 | + bql_unlock(); | ||
187 | + if (qemu_main) { | 183 | + if (qemu_main) { |
184 | + QemuThread main_loop_thread; | ||
188 | + qemu_thread_create(&main_loop_thread, "qemu_main", | 185 | + qemu_thread_create(&main_loop_thread, "qemu_main", |
189 | + call_qemu_default_main, NULL, QEMU_THREAD_DETACHED); | 186 | + qemu_default_main, NULL, QEMU_THREAD_DETACHED); |
190 | + bql_unlock(); | ||
191 | + return qemu_main(); | 187 | + return qemu_main(); |
192 | + } else { | 188 | + } else { |
193 | + qemu_default_main(); | 189 | + qemu_default_main(NULL); |
194 | + } | 190 | + } |
195 | } | 191 | } |
196 | diff --git a/ui/cocoa.m b/ui/cocoa.m | 192 | diff --git a/ui/cocoa.m b/ui/cocoa.m |
197 | index XXXXXXX..XXXXXXX 100644 | 193 | index XXXXXXX..XXXXXXX 100644 |
198 | --- a/ui/cocoa.m | 194 | --- a/ui/cocoa.m |
... | ... | ||
317 | @@ -XXX,XX +XXX,XX @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts) | 313 | @@ -XXX,XX +XXX,XX @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts) |
318 | #ifdef CONFIG_GTK_CLIPBOARD | 314 | #ifdef CONFIG_GTK_CLIPBOARD |
319 | gd_clipboard_init(s); | 315 | gd_clipboard_init(s); |
320 | #endif /* CONFIG_GTK_CLIPBOARD */ | 316 | #endif /* CONFIG_GTK_CLIPBOARD */ |
321 | + | 317 | + |
322 | + /* | 318 | + /* GTK's event polling must happen on the main thread. */ |
323 | + * GTK+ calls must happen on the main thread at least on some platforms, | ||
324 | + * and on macOS the main runloop is polled via GTK+'s event handling. | ||
325 | + * Don't allow QEMU's event loop to be moved off the main thread. | ||
326 | + */ | ||
327 | + qemu_main = NULL; | 319 | + qemu_main = NULL; |
328 | } | 320 | } |
329 | 321 | ||
330 | static void early_gtk_display_init(DisplayOptions *opts) | 322 | static void early_gtk_display_init(DisplayOptions *opts) |
331 | diff --git a/ui/sdl2.c b/ui/sdl2.c | 323 | diff --git a/ui/sdl2.c b/ui/sdl2.c |
... | ... | ||
349 | + qemu_main = NULL; | 341 | + qemu_main = NULL; |
350 | } | 342 | } |
351 | 343 | ||
352 | static QemuDisplay qemu_display_sdl2 = { | 344 | static QemuDisplay qemu_display_sdl2 = { |
353 | -- | 345 | -- |
354 | 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 |
... | ... | ||
143 | * Reworked the way frame rendering code is threaded to use BHs for sections | 145 | * Reworked the way frame rendering code is threaded to use BHs for sections |
144 | requiring BQL. | 146 | requiring BQL. |
145 | * Fix for ./configure error on non-macOS platforms. | 147 | * Fix for ./configure error on non-macOS platforms. |
146 | * Code formatting tweaks. | 148 | * Code formatting tweaks. |
147 | 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 | |||
148 | hw/display/Kconfig | 9 + | 168 | hw/display/Kconfig | 9 + |
149 | hw/display/apple-gfx-mmio.m | 281 +++++++++++++ | 169 | hw/display/apple-gfx-mmio.m | 281 +++++++++++++ |
150 | hw/display/apple-gfx.h | 67 ++++ | 170 | hw/display/apple-gfx.h | 66 +++ |
151 | hw/display/apple-gfx.m | 765 ++++++++++++++++++++++++++++++++++++ | 171 | hw/display/apple-gfx.m | 783 ++++++++++++++++++++++++++++++++++++ |
152 | hw/display/meson.build | 6 + | 172 | hw/display/meson.build | 6 + |
153 | hw/display/trace-events | 28 ++ | 173 | hw/display/trace-events | 28 ++ |
154 | meson.build | 4 + | 174 | meson.build | 4 + |
155 | 7 files changed, 1160 insertions(+) | 175 | 7 files changed, 1177 insertions(+) |
156 | create mode 100644 hw/display/apple-gfx-mmio.m | 176 | create mode 100644 hw/display/apple-gfx-mmio.m |
157 | create mode 100644 hw/display/apple-gfx.h | 177 | create mode 100644 hw/display/apple-gfx.h |
158 | create mode 100644 hw/display/apple-gfx.m | 178 | create mode 100644 hw/display/apple-gfx.m |
159 | 179 | ||
160 | diff --git a/hw/display/Kconfig b/hw/display/Kconfig | 180 | diff --git a/hw/display/Kconfig b/hw/display/Kconfig |
... | ... | ||
364 | +static PGIOSurfaceHostDevice *apple_gfx_prepare_iosurface_host_device( | 384 | +static PGIOSurfaceHostDevice *apple_gfx_prepare_iosurface_host_device( |
365 | + AppleGFXMMIOState *s) | 385 | + AppleGFXMMIOState *s) |
366 | +{ | 386 | +{ |
367 | + PGIOSurfaceHostDeviceDescriptor *iosfc_desc = | 387 | + PGIOSurfaceHostDeviceDescriptor *iosfc_desc = |
368 | + [PGIOSurfaceHostDeviceDescriptor new]; | 388 | + [PGIOSurfaceHostDeviceDescriptor new]; |
369 | + PGIOSurfaceHostDevice *iosfc_host_dev = nil; | 389 | + PGIOSurfaceHostDevice *iosfc_host_dev; |
370 | + | 390 | + |
371 | + iosfc_desc.mapMemory = | 391 | + iosfc_desc.mapMemory = |
372 | + ^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) { |
373 | + *va = apple_gfx_mmio_map_surface_memory(phys, len, ro); | 393 | + *va = apple_gfx_mmio_map_surface_memory(phys, len, ro); |
374 | + | 394 | + |
... | ... | ||
502 | + id<PGDevice> pgdev; | 522 | + id<PGDevice> pgdev; |
503 | + id<PGDisplay> pgdisp; | 523 | + id<PGDisplay> pgdisp; |
504 | + QemuConsole *con; | 524 | + QemuConsole *con; |
505 | + id<MTLDevice> mtl; | 525 | + id<MTLDevice> mtl; |
506 | + id<MTLCommandQueue> mtl_queue; | 526 | + id<MTLCommandQueue> mtl_queue; |
507 | + dispatch_queue_t render_queue; | ||
508 | + | 527 | + |
509 | + /* List `tasks` is protected by task_mutex */ | 528 | + /* List `tasks` is protected by task_mutex */ |
510 | + QemuMutex task_mutex; | 529 | + QemuMutex task_mutex; |
511 | + PGTaskList tasks; | 530 | + PGTaskList tasks; |
512 | + | 531 | + |
... | ... | ||
575 | + | 594 | + |
576 | +static const PGDisplayCoord_t apple_gfx_modes[] = { | 595 | +static const PGDisplayCoord_t apple_gfx_modes[] = { |
577 | + { .x = 1440, .y = 1080 }, | 596 | + { .x = 1440, .y = 1080 }, |
578 | + { .x = 1280, .y = 1024 }, | 597 | + { .x = 1280, .y = 1024 }, |
579 | +}; | 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 | +} | ||
580 | + | 607 | + |
581 | +/* ------ PGTask and task operations: new/destroy/map/unmap ------ */ | 608 | +/* ------ PGTask and task operations: new/destroy/map/unmap ------ */ |
582 | + | 609 | + |
583 | +/* | 610 | +/* |
584 | + * This implements the type declared in <ParavirtualizedGraphics/PGDevice.h> | 611 | + * This implements the type declared in <ParavirtualizedGraphics/PGDevice.h> |
... | ... | ||
610 | + * Protected by AppleGFXState's task_mutex. | 637 | + * Protected by AppleGFXState's task_mutex. |
611 | + */ | 638 | + */ |
612 | + GPtrArray *mapped_regions; | 639 | + GPtrArray *mapped_regions; |
613 | +}; | 640 | +}; |
614 | + | 641 | + |
615 | +static Error *apple_gfx_mig_blocker; | ||
616 | + | ||
617 | +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) |
618 | +{ | 643 | +{ |
619 | + mach_vm_address_t task_mem; | 644 | + mach_vm_address_t task_mem; |
620 | + PGTask_t *task; | 645 | + PGTask_t *task; |
621 | + kern_return_t r; | 646 | + kern_return_t r; |
... | ... | ||
772 | + id<MTLCommandBuffer> command_buffer = [s->mtl_queue commandBuffer]; | 797 | + id<MTLCommandBuffer> command_buffer = [s->mtl_queue commandBuffer]; |
773 | + id<MTLTexture> texture = s->texture; | 798 | + id<MTLTexture> texture = s->texture; |
774 | + | 799 | + |
775 | + assert(bql_locked()); | 800 | + assert(bql_locked()); |
776 | + [texture retain]; | 801 | + [texture retain]; |
802 | + [command_buffer retain]; | ||
777 | + | 803 | + |
778 | + s->rendering_frame_width = width; | 804 | + s->rendering_frame_width = width; |
779 | + s->rendering_frame_height = height; | 805 | + s->rendering_frame_height = height; |
780 | + | 806 | + |
781 | + dispatch_async(s->render_queue, ^{ | 807 | + dispatch_async(get_background_queue(), ^{ |
782 | + /* | 808 | + /* |
783 | + * This is not safe to call from the BQL due to PVG-internal locks | 809 | + * This is not safe to call from the BQL/BH due to PVG-internal locks |
784 | + * causing deadlocks. | 810 | + * causing deadlocks. |
785 | + */ | 811 | + */ |
786 | + bool r = [s->pgdisp encodeCurrentFrameToCommandBuffer:command_buffer | 812 | + bool r = [s->pgdisp encodeCurrentFrameToCommandBuffer:command_buffer |
787 | + texture:texture | 813 | + texture:texture |
788 | + region:region]; | 814 | + region:region]; |
789 | + if (!r) { | 815 | + if (!r) { |
790 | + [texture release]; | 816 | + [texture release]; |
791 | + bql_lock(); | 817 | + [command_buffer release]; |
792 | + --s->pending_frames; | ||
793 | + bql_unlock(); | ||
794 | + qemu_log_mask(LOG_GUEST_ERROR, | 818 | + qemu_log_mask(LOG_GUEST_ERROR, |
795 | + "%s: encodeCurrentFrameToCommandBuffer:texture:region: " | 819 | + "%s: encodeCurrentFrameToCommandBuffer:texture:region: " |
796 | + "failed\n", __func__); | 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(); | ||
797 | + return; | 827 | + return; |
798 | + } | 828 | + } |
799 | + | 829 | + |
800 | + if (managed_texture) { | 830 | + if (managed_texture) { |
801 | + /* "Managed" textures exist in both VRAM and RAM and must be synced. */ | 831 | + /* "Managed" textures exist in both VRAM and RAM and must be synced. */ |
... | ... | ||
807 | + [command_buffer addCompletedHandler: | 837 | + [command_buffer addCompletedHandler: |
808 | + ^(id<MTLCommandBuffer> cb) | 838 | + ^(id<MTLCommandBuffer> cb) |
809 | + { | 839 | + { |
810 | + aio_bh_schedule_oneshot(qemu_get_aio_context(), | 840 | + aio_bh_schedule_oneshot(qemu_get_aio_context(), |
811 | + apple_gfx_render_frame_completed_bh, s); | 841 | + apple_gfx_render_frame_completed_bh, s); |
812 | + | ||
813 | + }]; | 842 | + }]; |
814 | + [command_buffer commit]; | 843 | + [command_buffer commit]; |
844 | + [command_buffer release]; | ||
815 | + }); | 845 | + }); |
816 | +} | 846 | +} |
817 | + | 847 | + |
818 | +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) |
819 | +{ | 849 | +{ |
... | ... | ||
834 | + | 864 | + |
835 | +static void apple_gfx_render_frame_completed_bh(void *opaque) | 865 | +static void apple_gfx_render_frame_completed_bh(void *opaque) |
836 | +{ | 866 | +{ |
837 | + AppleGFXState *s = opaque; | 867 | + AppleGFXState *s = opaque; |
838 | + | 868 | + |
839 | + --s->pending_frames; | 869 | + @autoreleasepool { |
840 | + assert(s->pending_frames >= 0); | 870 | + --s->pending_frames; |
841 | + | 871 | + assert(s->pending_frames >= 0); |
842 | + /* Only update display if mode hasn't changed since we started rendering. */ | 872 | + |
843 | + if (s->rendering_frame_width == surface_width(s->surface) && | 873 | + /* Only update display if mode hasn't changed since we started rendering. */ |
844 | + s->rendering_frame_height == surface_height(s->surface)) { | 874 | + if (s->rendering_frame_width == surface_width(s->surface) && |
845 | + copy_mtl_texture_to_surface_mem(s->texture, surface_data(s->surface)); | 875 | + s->rendering_frame_height == surface_height(s->surface)) { |
846 | + if (s->gfx_update_requested) { | 876 | + copy_mtl_texture_to_surface_mem(s->texture, surface_data(s->surface)); |
847 | + s->gfx_update_requested = false; | 877 | + if (s->gfx_update_requested) { |
848 | + dpy_gfx_update_full(s->con); | 878 | + s->gfx_update_requested = false; |
849 | + graphic_hw_update_done(s->con); | 879 | + dpy_gfx_update_full(s->con); |
850 | + s->new_frame_ready = false; | 880 | + graphic_hw_update_done(s->con); |
851 | + } else { | 881 | + s->new_frame_ready = false; |
852 | + s->new_frame_ready = true; | 882 | + } else { |
883 | + s->new_frame_ready = true; | ||
884 | + } | ||
853 | + } | 885 | + } |
854 | + } | 886 | + if (s->pending_frames > 0) { |
855 | + if (s->pending_frames > 0) { | 887 | + apple_gfx_render_new_frame(s); |
856 | + apple_gfx_render_new_frame(s); | 888 | + } |
857 | + } | 889 | + } |
858 | +} | 890 | +} |
859 | + | 891 | + |
860 | +static void apple_gfx_fb_update_display(void *opaque) | 892 | +static void apple_gfx_fb_update_display(void *opaque) |
861 | +{ | 893 | +{ |
... | ... | ||
901 | + width:width | 933 | + width:width |
902 | + height:height | 934 | + height:height |
903 | + mipmapped:NO]; | 935 | + mipmapped:NO]; |
904 | + textureDescriptor.usage = s->pgdisp.minimumTextureUsage; | 936 | + textureDescriptor.usage = s->pgdisp.minimumTextureUsage; |
905 | + s->texture = [s->mtl newTextureWithDescriptor:textureDescriptor]; | 937 | + s->texture = [s->mtl newTextureWithDescriptor:textureDescriptor]; |
906 | + } | 938 | + s->using_managed_texture_storage = |
907 | + | 939 | + (s->texture.storageMode == MTLStorageModeManaged); |
908 | + s->using_managed_texture_storage = | 940 | + } |
909 | + (s->texture.storageMode == MTLStorageModeManaged); | 941 | + |
910 | + dpy_gfx_replace_surface(s->con, s->surface); | 942 | + dpy_gfx_replace_surface(s->con, s->surface); |
911 | +} | 943 | +} |
912 | + | 944 | + |
913 | +static void update_cursor(AppleGFXState *s) | 945 | +static void update_cursor(AppleGFXState *s) |
914 | +{ | 946 | +{ |
... | ... | ||
1018 | + return job.success; | 1050 | + return job.success; |
1019 | +} | 1051 | +} |
1020 | + | 1052 | + |
1021 | +/* ------ Memory-mapped device I/O operations ------ */ | 1053 | +/* ------ Memory-mapped device I/O operations ------ */ |
1022 | + | 1054 | + |
1023 | +static dispatch_queue_t get_background_queue(void) | ||
1024 | +{ | ||
1025 | + return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); | ||
1026 | +} | ||
1027 | + | ||
1028 | +typedef struct AppleGFXIOJob { | 1055 | +typedef struct AppleGFXIOJob { |
1029 | + AppleGFXState *state; | 1056 | + AppleGFXState *state; |
1030 | + uint64_t offset; | 1057 | + uint64_t offset; |
1031 | + uint64_t value; | 1058 | + uint64_t value; |
1032 | + bool completed; | 1059 | + bool completed; |
... | ... | ||
1165 | + | 1192 | + |
1166 | +static void new_frame_handler_bh(void *opaque) | 1193 | +static void new_frame_handler_bh(void *opaque) |
1167 | +{ | 1194 | +{ |
1168 | + AppleGFXState *s = opaque; | 1195 | + AppleGFXState *s = opaque; |
1169 | + | 1196 | + |
1170 | + /* Drop frames if we get too far ahead. */ | 1197 | + /* Drop frames if guest gets too far ahead. */ |
1171 | + if (s->pending_frames >= 2) { | 1198 | + if (s->pending_frames >= 2) { |
1172 | + return; | 1199 | + return; |
1173 | + } | 1200 | + } |
1174 | + ++s->pending_frames; | 1201 | + ++s->pending_frames; |
1175 | + if (s->pending_frames > 1) { | 1202 | + if (s->pending_frames > 1) { |
1176 | + return; | 1203 | + return; |
1177 | + } | 1204 | + } |
1178 | + apple_gfx_render_new_frame(s); | 1205 | + |
1206 | + @autoreleasepool { | ||
1207 | + apple_gfx_render_new_frame(s); | ||
1208 | + } | ||
1179 | +} | 1209 | +} |
1180 | + | 1210 | + |
1181 | +static PGDisplayDescriptor *apple_gfx_prepare_display_descriptor(AppleGFXState *s) | 1211 | +static PGDisplayDescriptor *apple_gfx_prepare_display_descriptor(AppleGFXState *s) |
1182 | +{ | 1212 | +{ |
1183 | + PGDisplayDescriptor *disp_desc = [PGDisplayDescriptor new]; | 1213 | + PGDisplayDescriptor *disp_desc = [PGDisplayDescriptor new]; |
... | ... | ||
1222 | +} | 1252 | +} |
1223 | + | 1253 | + |
1224 | +static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void) | 1254 | +static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void) |
1225 | +{ | 1255 | +{ |
1226 | + PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)]; | 1256 | + PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)]; |
1227 | + NSArray<PGDisplayMode*>* mode_array = nil; | 1257 | + NSArray<PGDisplayMode*>* mode_array; |
1228 | + int i; | 1258 | + int i; |
1229 | + | 1259 | + |
1230 | + for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) { | 1260 | + for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) { |
1231 | + modes[i] = | 1261 | + modes[i] = |
1232 | + [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.]; | 1262 | + [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.]; |
... | ... | ||
1269 | +} | 1299 | +} |
1270 | + | 1300 | + |
1271 | +bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev, | 1301 | +bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev, |
1272 | + PGDeviceDescriptor *desc, Error **errp) | 1302 | + PGDeviceDescriptor *desc, Error **errp) |
1273 | +{ | 1303 | +{ |
1274 | + PGDisplayDescriptor *disp_desc = nil; | 1304 | + PGDisplayDescriptor *disp_desc; |
1275 | + | 1305 | + |
1276 | + if (apple_gfx_mig_blocker == NULL) { | 1306 | + if (apple_gfx_mig_blocker == NULL) { |
1277 | + error_setg(&apple_gfx_mig_blocker, | 1307 | + error_setg(&apple_gfx_mig_blocker, |
1278 | + "Migration state blocked by apple-gfx display device"); | 1308 | + "Migration state blocked by apple-gfx display device"); |
1279 | + if (migrate_add_blocker(&apple_gfx_mig_blocker, errp) < 0) { | 1309 | + if (migrate_add_blocker(&apple_gfx_mig_blocker, errp) < 0) { |
1280 | + return false; | 1310 | + return false; |
1281 | + } | 1311 | + } |
1282 | + } | 1312 | + } |
1283 | + | 1313 | + |
1284 | + qemu_mutex_init(&s->task_mutex); | 1314 | + qemu_mutex_init(&s->task_mutex); |
1285 | + QTAILQ_INIT(&s->tasks); | 1315 | + QTAILQ_INIT(&s->tasks); |
1286 | + s->render_queue = dispatch_queue_create("apple-gfx.render", | ||
1287 | + DISPATCH_QUEUE_SERIAL); | ||
1288 | + s->mtl = copy_suitable_metal_device(); | 1316 | + s->mtl = copy_suitable_metal_device(); |
1289 | + s->mtl_queue = [s->mtl newCommandQueue]; | 1317 | + s->mtl_queue = [s->mtl newCommandQueue]; |
1290 | + | 1318 | + |
1291 | + desc.device = s->mtl; | 1319 | + desc.device = s->mtl; |
1292 | + | 1320 | + |
... | ... | ||
1295 | + s->cursor_show = true; | 1323 | + s->cursor_show = true; |
1296 | + | 1324 | + |
1297 | + s->pgdev = PGNewDeviceWithDescriptor(desc); | 1325 | + s->pgdev = PGNewDeviceWithDescriptor(desc); |
1298 | + | 1326 | + |
1299 | + 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 | + */ | ||
1300 | + s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc | 1336 | + s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc |
1301 | + port:0 serialNum:1234]; | 1337 | + port:0 |
1338 | + serialNum:next_pgdisplay_serial_num++]; | ||
1302 | + [disp_desc release]; | 1339 | + [disp_desc release]; |
1303 | + s->pgdisp.modeList = apple_gfx_prepare_display_mode_array(); | 1340 | + s->pgdisp.modeList = apple_gfx_prepare_display_mode_array(); |
1304 | + | 1341 | + |
1305 | + s->con = graphic_console_init(dev, 0, &apple_gfx_fb_ops, s); | 1342 | + s->con = graphic_console_init(dev, 0, &apple_gfx_fb_ops, s); |
1306 | + return true; | 1343 | + return true; |
... | ... | ||
1379 | + metal = dependency('appleframeworks', modules: 'Metal') | 1416 | + metal = dependency('appleframeworks', modules: 'Metal') |
1380 | elif host_os == 'sunos' | 1417 | elif host_os == 'sunos' |
1381 | socket = [cc.find_library('socket'), | 1418 | socket = [cc.find_library('socket'), |
1382 | cc.find_library('nsl'), | 1419 | cc.find_library('nsl'), |
1383 | -- | 1420 | -- |
1384 | 2.39.3 (Apple Git-145) | 1421 | 2.39.5 (Apple Git-154) |
1385 | 1422 | ||
1386 | 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 |
... | ... | ||
22 | 23 | ||
23 | v9: | 24 | v9: |
24 | 25 | ||
25 | * Fixup of changed common call. | 26 | * Fixup of changed common call. |
26 | * Whitespace and comment formatting tweaks. | 27 | * Whitespace and comment formatting tweaks. |
28 | |||
29 | v11: | ||
30 | |||
31 | * Comment formatting fix. | ||
27 | 32 | ||
28 | hw/display/Kconfig | 4 + | 33 | hw/display/Kconfig | 4 + |
29 | hw/display/apple-gfx-pci.m | 150 +++++++++++++++++++++++++++++++++++++ | 34 | hw/display/apple-gfx-pci.m | 150 +++++++++++++++++++++++++++++++++++++ |
30 | hw/display/meson.build | 1 + | 35 | hw/display/meson.build | 1 + |
31 | 3 files changed, 155 insertions(+) | 36 | 3 files changed, 155 insertions(+) |
... | ... | ||
179 | + pci->vendor_id = PG_PCI_VENDOR_ID; | 184 | + pci->vendor_id = PG_PCI_VENDOR_ID; |
180 | + pci->device_id = PG_PCI_DEVICE_ID; | 185 | + pci->device_id = PG_PCI_DEVICE_ID; |
181 | + pci->class_id = PCI_CLASS_DISPLAY_OTHER; | 186 | + pci->class_id = PCI_CLASS_DISPLAY_OTHER; |
182 | + pci->realize = apple_gfx_pci_realize; | 187 | + pci->realize = apple_gfx_pci_realize; |
183 | + | 188 | + |
184 | + // TODO: Property for setting mode list | 189 | + /* TODO: Property for setting mode list */ |
185 | +} | 190 | +} |
186 | + | 191 | + |
187 | +static TypeInfo apple_gfx_pci_types[] = { | 192 | +static TypeInfo apple_gfx_pci_types[] = { |
188 | + { | 193 | + { |
189 | + .name = TYPE_APPLE_GFX_PCI, | 194 | + .name = TYPE_APPLE_GFX_PCI, |
... | ... | ||
210 | + 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]) |
211 | if cpu == 'aarch64' | 216 | if cpu == 'aarch64' |
212 | system_ss.add(when: 'CONFIG_MAC_PVG_MMIO', if_true: [files('apple-gfx-mmio.m'), pvg, metal]) | 217 | system_ss.add(when: 'CONFIG_MAC_PVG_MMIO', if_true: [files('apple-gfx-mmio.m'), pvg, metal]) |
213 | endif | 218 | endif |
214 | -- | 219 | -- |
215 | 2.39.3 (Apple Git-145) | 220 | 2.39.5 (Apple Git-154) |
216 | 221 | ||
217 | 222 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
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> | 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 | * Switched to the native array property type, which recently gained | 17 | * Switched to the native array property type, which recently gained |
... | ... | ||
93 | DeviceClass *dc = DEVICE_CLASS(klass); | 94 | DeviceClass *dc = DEVICE_CLASS(klass); |
94 | @@ -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) |
95 | pci->class_id = PCI_CLASS_DISPLAY_OTHER; | 96 | pci->class_id = PCI_CLASS_DISPLAY_OTHER; |
96 | pci->realize = apple_gfx_pci_realize; | 97 | pci->realize = apple_gfx_pci_realize; |
97 | 98 | ||
98 | - // TODO: Property for setting mode list | 99 | - /* TODO: Property for setting mode list */ |
99 | + device_class_set_props(dc, apple_gfx_pci_properties); | 100 | + device_class_set_props(dc, apple_gfx_pci_properties); |
100 | } | 101 | } |
101 | 102 | ||
102 | static TypeInfo apple_gfx_pci_types[] = { | 103 | static TypeInfo apple_gfx_pci_types[] = { |
103 | 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 |
... | ... | ||
124 | + | 125 | + |
125 | typedef struct AppleGFXState { | 126 | typedef struct AppleGFXState { |
126 | /* Initialised on init/realize() */ | 127 | /* Initialised on init/realize() */ |
127 | MemoryRegion iomem_gfx; | 128 | MemoryRegion iomem_gfx; |
128 | @@ -XXX,XX +XXX,XX @@ typedef struct AppleGFXState { | 129 | @@ -XXX,XX +XXX,XX @@ typedef struct AppleGFXState { |
130 | QemuConsole *con; | ||
129 | id<MTLDevice> mtl; | 131 | id<MTLDevice> mtl; |
130 | id<MTLCommandQueue> mtl_queue; | 132 | id<MTLCommandQueue> mtl_queue; |
131 | dispatch_queue_t render_queue; | ||
132 | + AppleGFXDisplayMode *display_modes; | 133 | + AppleGFXDisplayMode *display_modes; |
133 | + uint32_t num_display_modes; | 134 | + uint32_t num_display_modes; |
134 | 135 | ||
135 | /* List `tasks` is protected by task_mutex */ | 136 | /* List `tasks` is protected by task_mutex */ |
136 | QemuMutex task_mutex; | 137 | QemuMutex task_mutex; |
... | ... | ||
157 | + { 1920, 1080, 60 }, | 158 | + { 1920, 1080, 60 }, |
158 | + { 1440, 1080, 60 }, | 159 | + { 1440, 1080, 60 }, |
159 | + { 1280, 1024, 60 }, | 160 | + { 1280, 1024, 60 }, |
160 | }; | 161 | }; |
161 | 162 | ||
162 | /* ------ PGTask and task operations: new/destroy/map/unmap ------ */ | 163 | static Error *apple_gfx_mig_blocker; |
163 | @@ -XXX,XX +XXX,XX @@ static void new_frame_handler_bh(void *opaque) | 164 | @@ -XXX,XX +XXX,XX @@ static void new_frame_handler_bh(void *opaque) |
164 | return disp_desc; | 165 | return disp_desc; |
165 | } | 166 | } |
166 | 167 | ||
167 | -static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void) | 168 | -static NSArray<PGDisplayMode*>* apple_gfx_prepare_display_mode_array(void) |
168 | +static NSArray<PGDisplayMode *> *apple_gfx_create_display_mode_array( | 169 | +static NSArray<PGDisplayMode *> *apple_gfx_create_display_mode_array( |
169 | + const AppleGFXDisplayMode display_modes[], uint32_t display_mode_count) | 170 | + const AppleGFXDisplayMode display_modes[], uint32_t display_mode_count) |
170 | { | 171 | { |
171 | - PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)]; | 172 | - PGDisplayMode *modes[ARRAY_SIZE(apple_gfx_modes)]; |
172 | - NSArray<PGDisplayMode*>* mode_array = nil; | 173 | - NSArray<PGDisplayMode*>* mode_array; |
173 | - int i; | 174 | - int i; |
174 | - | 175 | - |
175 | - for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) { | 176 | - for (i = 0; i < ARRAY_SIZE(apple_gfx_modes); i++) { |
176 | - modes[i] = | 177 | - modes[i] = |
177 | - [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.]; | 178 | - [[PGDisplayMode alloc] initWithSizeInPixels:apple_gfx_modes[i] refreshRateInHz:60.]; |
... | ... | ||
201 | 202 | ||
202 | return mode_array; | 203 | return mode_array; |
203 | @@ -XXX,XX +XXX,XX @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev, | 204 | @@ -XXX,XX +XXX,XX @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev, |
204 | PGDeviceDescriptor *desc, Error **errp) | 205 | PGDeviceDescriptor *desc, Error **errp) |
205 | { | 206 | { |
206 | PGDisplayDescriptor *disp_desc = nil; | 207 | PGDisplayDescriptor *disp_desc; |
207 | + const AppleGFXDisplayMode *display_modes = apple_gfx_default_modes; | 208 | + const AppleGFXDisplayMode *display_modes = apple_gfx_default_modes; |
208 | + uint32_t num_display_modes = ARRAY_SIZE(apple_gfx_default_modes); | 209 | + uint32_t num_display_modes = ARRAY_SIZE(apple_gfx_default_modes); |
209 | + NSArray<PGDisplayMode *> *mode_array; | 210 | + NSArray<PGDisplayMode *> *mode_array; |
210 | 211 | ||
211 | if (apple_gfx_mig_blocker == NULL) { | 212 | if (apple_gfx_mig_blocker == NULL) { |
212 | error_setg(&apple_gfx_mig_blocker, | 213 | error_setg(&apple_gfx_mig_blocker, |
213 | @@ -XXX,XX +XXX,XX @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev, | 214 | @@ -XXX,XX +XXX,XX @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev, |
214 | s->pgdisp = [s->pgdev newDisplayWithDescriptor:disp_desc | 215 | port:0 |
215 | port:0 serialNum:1234]; | 216 | serialNum:next_pgdisplay_serial_num++]; |
216 | [disp_desc release]; | 217 | [disp_desc release]; |
217 | - s->pgdisp.modeList = apple_gfx_prepare_display_mode_array(); | 218 | - s->pgdisp.modeList = apple_gfx_prepare_display_mode_array(); |
218 | + | 219 | + |
219 | + if (s->display_modes != NULL && s->num_display_modes > 0) { | 220 | + if (s->display_modes != NULL && s->num_display_modes > 0) { |
220 | + trace_apple_gfx_common_realize_modes_property(s->num_display_modes); | 221 | + trace_apple_gfx_common_realize_modes_property(s->num_display_modes); |
... | ... | ||
323 | +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 |
324 | 325 | ||
325 | # apple-gfx-mmio.m | 326 | # apple-gfx-mmio.m |
326 | 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 |
327 | -- | 328 | -- |
328 | 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. |
... | ... | ||
755 | + *(buffer++) = hexdump_nibble(val & 0xf); | 757 | + *(buffer++) = hexdump_nibble(val & 0xf); |
756 | + } | 758 | + } |
757 | + *buffer = '\0'; | 759 | + *buffer = '\0'; |
758 | +} | 760 | +} |
759 | -- | 761 | -- |
760 | 2.39.3 (Apple Git-145) | 762 | 2.39.5 (Apple Git-154) |
761 | 763 | ||
762 | 764 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
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> | 13 | Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com> |
14 | Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
14 | --- | 15 | --- |
15 | 16 | ||
16 | v4: | 17 | v4: |
17 | 18 | ||
18 | * Moved most header code to .c, rest to vmapple.h | 19 | * Moved most header code to .c, rest to vmapple.h |
... | ... | ||
357 | 358 | ||
358 | +#define TYPE_VMAPPLE_BDIF "vmapple-bdif" | 359 | +#define TYPE_VMAPPLE_BDIF "vmapple-bdif" |
359 | + | 360 | + |
360 | #endif /* HW_VMAPPLE_VMAPPLE_H */ | 361 | #endif /* HW_VMAPPLE_VMAPPLE_H */ |
361 | -- | 362 | -- |
362 | 2.39.3 (Apple Git-145) | 363 | 2.39.5 (Apple Git-154) |
363 | 364 | ||
364 | 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 |
... | ... | ||
277 | 279 | ||
278 | +#define TYPE_VMAPPLE_CFG "vmapple-cfg" | 280 | +#define TYPE_VMAPPLE_CFG "vmapple-cfg" |
279 | + | 281 | + |
280 | #endif /* HW_VMAPPLE_VMAPPLE_H */ | 282 | #endif /* HW_VMAPPLE_VMAPPLE_H */ |
281 | -- | 283 | -- |
282 | 2.39.3 (Apple Git-145) | 284 | 2.39.5 (Apple Git-154) |
283 | 285 | ||
284 | 286 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
13 | The 'aux' or 'root' device type are selected using the 'variant' property. | 13 | The 'aux' or 'root' device type are selected using the 'variant' property. |
14 | 14 | ||
15 | Signed-off-by: Alexander Graf <graf@amazon.com> | 15 | Signed-off-by: Alexander Graf <graf@amazon.com> |
16 | Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu> | 16 | Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu> |
17 | 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> | ||
18 | --- | 19 | --- |
19 | 20 | ||
20 | v4: | 21 | v4: |
21 | 22 | ||
22 | * Use recommended object type declaration pattern. | 23 | * Use recommended object type declaration pattern. |
... | ... | ||
442 | +# Since: 9.2 | 443 | +# Since: 9.2 |
443 | +## | 444 | +## |
444 | +{ 'enum': 'VMAppleVirtioBlkVariant', | 445 | +{ 'enum': 'VMAppleVirtioBlkVariant', |
445 | + 'data': [ 'unspecified', 'root', 'aux' ] } | 446 | + 'data': [ 'unspecified', 'root', 'aux' ] } |
446 | -- | 447 | -- |
447 | 2.39.3 (Apple Git-145) | 448 | 2.39.5 (Apple Git-154) |
448 | 449 | ||
449 | 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 |
... | ... | ||
73 | 74 | ||
74 | v10: | 75 | v10: |
75 | * Documentation fixup for changed virtio-blk device type. | 76 | * Documentation fixup for changed virtio-blk device type. |
76 | * Small improvements to shell commands in documentation. | 77 | * Small improvements to shell commands in documentation. |
77 | * Improved propagation of errors during cfg device instantiation. | 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. | ||
78 | 85 | ||
79 | MAINTAINERS | 1 + | 86 | MAINTAINERS | 1 + |
80 | contrib/vmapple/uuid.sh | 9 + | 87 | contrib/vmapple/uuid.sh | 9 + |
81 | docs/system/arm/vmapple.rst | 63 ++++ | 88 | docs/system/arm/vmapple.rst | 63 ++++ |
82 | docs/system/target-arm.rst | 1 + | 89 | docs/system/target-arm.rst | 1 + |
... | ... | ||
163 | +to get better interactive access into the target system: | 170 | +to get better interactive access into the target system: |
164 | + | 171 | + |
165 | +.. code-block:: bash | 172 | +.. code-block:: bash |
166 | + :caption: Example execution command line | 173 | + :caption: Example execution command line |
167 | + | 174 | + |
168 | + $ UUID=$(contrib/vmapple/uuid.sh macosvm.json) | 175 | + $ UUID="$(contrib/vmapple/uuid.sh 'macosvm.json')" |
169 | + $ AVPBOOTER=/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin | 176 | + $ AVPBOOTER="/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin" |
170 | + $ AUX="aux.img.trimmed" | 177 | + $ AUX="aux.img.trimmed" |
171 | + $ DISK=disk.img | 178 | + $ DISK="disk.img" |
172 | + $ qemu-system-aarch64 \ | 179 | + $ qemu-system-aarch64 \ |
173 | + -serial mon:stdio \ | 180 | + -serial mon:stdio \ |
174 | + -m 4G \ | 181 | + -m 4G \ |
175 | + -accel hvf \ | 182 | + -accel hvf \ |
176 | + -M vmapple,uuid="$UUID" \ | 183 | + -M vmapple,uuid="$UUID" \ |
... | ... | ||
878 | +{ | 885 | +{ |
879 | + type_register_static(&vmapple_machine_info); | 886 | + type_register_static(&vmapple_machine_info); |
880 | +} | 887 | +} |
881 | +type_init(machvmapple_machine_init); | 888 | +type_init(machvmapple_machine_init); |
882 | + | 889 | + |
883 | +static void vmapple_machine_9_2_options(MachineClass *mc) | 890 | +static void vmapple_machine_10_0_options(MachineClass *mc) |
884 | +{ | 891 | +{ |
885 | +} | 892 | +} |
886 | +DEFINE_VMAPPLE_MACHINE_AS_LATEST(9, 2) | 893 | +DEFINE_VMAPPLE_MACHINE_AS_LATEST(10, 0) |
887 | + | 894 | + |
888 | -- | 895 | -- |
889 | 2.39.3 (Apple Git-145) | 896 | 2.39.5 (Apple Git-154) |
890 | 897 | ||
891 | 898 | diff view generated by jsdifflib |