diff --git a/Configuration/QEMUConstant.swift b/Configuration/QEMUConstant.swift index 0664f2d3..e31a8762 100644 --- a/Configuration/QEMUConstant.swift +++ b/Configuration/QEMUConstant.swift @@ -390,3 +390,51 @@ enum QEMUPackageFileName: String { case debugLog = "debug.log" case efiVariables = "efi_vars.fd" } + +// MARK: Supported features + +extension QEMUArchitecture { + var hasAgentSupport: Bool { + switch self { + case .sparc, .sparc64: return false + default: return true + } + } + + var hasSharingSupport: Bool { + switch self { + case .sparc, .sparc64: return false + default: return true + } + } + + var hasUsbSupport: Bool { + switch self { + case .s390x: return false + case .sparc, .sparc64: return false + default: return true + } + } + + var hasHypervisorSupport: Bool { + guard jb_has_hypervisor() else { + return false + } + #if arch(arm64) + return self == .aarch64 + #elseif arch(x86_64) + return self == .x86_64 + #else + return false + #endif + } +} + +extension QEMUTarget { + var hasUsbSupport: Bool { + switch self.rawValue { + case "isapc": return false + default: return true + } + } +} diff --git a/Configuration/UTMQemuConfiguration+Arguments.swift b/Configuration/UTMQemuConfiguration+Arguments.swift index a33b552a..ca8dbb9a 100644 --- a/Configuration/UTMQemuConfiguration+Arguments.swift +++ b/Configuration/UTMQemuConfiguration+Arguments.swift @@ -269,38 +269,12 @@ import Foundation #endif } - private var isHypervisorSupported: Bool { - guard jb_has_hypervisor() else { - return false - } - #if arch(arm64) - return system.architecture == .aarch64 - #elseif arch(x86_64) - return system.architecture == .x86_64 - #else - return false - #endif - } - private var isHypervisorUsed: Bool { - isHypervisorSupported && qemu.hasHypervisor - } - - private var isUsbSupported: Bool { - if system.target.rawValue == QEMUTarget_x86_64.isapc.rawValue { - return false - } - if system.architecture == .s390x { - return false - } - if system.architecture == .sparc || system.architecture == .sparc64 { - return false - } - return true + system.architecture.hasHypervisorSupport && qemu.hasHypervisor } private var isUsbUsed: Bool { - isUsbSupported && input.usbBusSupport != .disabled + system.architecture.hasUsbSupport && system.target.hasUsbSupport && input.usbBusSupport != .disabled } @QEMUArgumentBuilder private var machineArguments: [QEMUArgument] { @@ -721,8 +695,15 @@ import Foundation } } + private var isAgentUsed: Bool { + guard system.architecture.hasAgentSupport else { + return false + } + return sharing.hasClipboardSharing || sharing.directoryShareMode == .webdav || displays.contains(where: { $0.isDynamicResolution }) + } + @QEMUArgumentBuilder private var sharingArguments: [QEMUArgument] { - if sharing.hasClipboardSharing || sharing.directoryShareMode == .webdav || displays.contains(where: { $0.isDynamicResolution }) { + if isAgentUsed { f("-device") f("virtio-serial") f("-device") @@ -736,7 +717,7 @@ import Foundation f("spiceport,name=org.spice-space.webdav.0,id=charchannel1") } } - if sharing.directoryShareMode == .virtfs, let url = sharing.directoryShareUrl { + if system.architecture.hasSharingSupport && sharing.directoryShareMode == .virtfs, let url = sharing.directoryShareUrl { f("-fsdev") "local" "id=virtfs0" diff --git a/Configuration/UTMQemuConfigurationDisplay.swift b/Configuration/UTMQemuConfigurationDisplay.swift index 17335d70..cad8e0ef 100644 --- a/Configuration/UTMQemuConfigurationDisplay.swift +++ b/Configuration/UTMQemuConfigurationDisplay.swift @@ -76,6 +76,9 @@ struct UTMQemuConfigurationDisplay: Codable, Identifiable { extension UTMQemuConfigurationDisplay { init?(forArchitecture architecture: QEMUArchitecture, target: any QEMUTarget) { self.init() + if !architecture.hasAgentSupport { + isDynamicResolution = false + } let rawTarget = target.rawValue if rawTarget.hasPrefix("pc") || rawTarget.hasPrefix("q35") { hardware = QEMUDisplayDevice_x86_64.virtio_vga diff --git a/Configuration/UTMQemuConfigurationInput.swift b/Configuration/UTMQemuConfigurationInput.swift index efc4ee0f..6378e60a 100644 --- a/Configuration/UTMQemuConfigurationInput.swift +++ b/Configuration/UTMQemuConfigurationInput.swift @@ -57,12 +57,12 @@ extension UTMQemuConfigurationInput { init(forArchitecture architecture: QEMUArchitecture, target: any QEMUTarget) { self.init() let rawTarget = target.rawValue - if rawTarget.hasPrefix("pc") || rawTarget.hasPrefix("q35") { + if !architecture.hasUsbSupport || !target.hasUsbSupport { + usbBusSupport = .disabled + } else if rawTarget.hasPrefix("pc") || rawTarget.hasPrefix("q35") { usbBusSupport = .usb3_0 } else if (architecture == .arm || architecture == .aarch64) && (rawTarget.hasPrefix("virt-") || rawTarget == "virt") { usbBusSupport = .usb3_0 - } else if rawTarget == "isapc" { - usbBusSupport = .disabled } } } diff --git a/Configuration/UTMQemuConfigurationQEMU.swift b/Configuration/UTMQemuConfigurationQEMU.swift index 58774b73..c0982e17 100644 --- a/Configuration/UTMQemuConfigurationQEMU.swift +++ b/Configuration/UTMQemuConfigurationQEMU.swift @@ -122,15 +122,7 @@ extension UTMQemuConfigurationQEMU { hasUefiBoot = true hasRNGDevice = true } - #if arch(arm64) - if architecture == .aarch64 { - hasHypervisor = jb_has_hypervisor() - } - #elseif arch(x86_64) - if architecture == .x86_64 { - hasHypervisor = jb_has_hypervisor() - } - #endif + hasHypervisor = architecture.hasHypervisorSupport } } diff --git a/Configuration/UTMQemuConfigurationSharing.swift b/Configuration/UTMQemuConfigurationSharing.swift index 6a92025d..6ac3d94f 100644 --- a/Configuration/UTMQemuConfigurationSharing.swift +++ b/Configuration/UTMQemuConfigurationSharing.swift @@ -60,6 +60,13 @@ extension UTMQemuConfigurationSharing { init(forArchitecture architecture: QEMUArchitecture, target: any QEMUTarget) { self.init() let rawTarget = target.rawValue + if !architecture.hasAgentSupport { + hasClipboardSharing = false + } + if !architecture.hasSharingSupport { + directoryShareMode = .none + } + // overrides for specific configurations if rawTarget.hasPrefix("pc") || rawTarget.hasPrefix("q35") { directoryShareMode = .webdav hasClipboardSharing = true