diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/kvm.c | 8 | ||||
-rw-r--r-- | target/i386/cpu.c | 8 | ||||
-rw-r--r-- | target/i386/kvm.c | 151 | ||||
-rw-r--r-- | target/i386/kvm_i386.h | 20 | ||||
-rw-r--r-- | target/i386/machine.c | 10 | ||||
-rw-r--r-- | target/i386/monitor.c | 1 | ||||
-rw-r--r-- | target/i386/whp-dispatch.h | 4 | ||||
-rw-r--r-- | target/i386/whpx-all.c | 85 | ||||
-rw-r--r-- | target/mips/kvm.c | 2 | ||||
-rw-r--r-- | target/ppc/kvm.c | 8 | ||||
-rw-r--r-- | target/ppc/kvm_ppc.h | 4 | ||||
-rw-r--r-- | target/s390x/cpu_models.c | 4 | ||||
-rw-r--r-- | target/s390x/kvm.c | 2 | ||||
-rw-r--r-- | target/sparc/TODO | 88 |
14 files changed, 90 insertions, 305 deletions
diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 5b82cef..b87b59a 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -741,11 +741,11 @@ void kvm_arch_init_irq_routing(KVMState *s) { } -int kvm_arch_irqchip_create(MachineState *ms, KVMState *s) +int kvm_arch_irqchip_create(KVMState *s) { - if (machine_kernel_irqchip_split(ms)) { - perror("-machine kernel_irqchip=split is not supported on ARM."); - exit(1); + if (kvm_kernel_irqchip_split()) { + perror("-machine kernel_irqchip=split is not supported on ARM."); + exit(1); } /* If we can create the VGIC using the newer device control API, we diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 0a9ac65..e1eb9f4 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -4695,7 +4695,7 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc, return; } - xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc)))); + xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc))); x86_cpu_expand_features(xc, &err); if (err) { @@ -4763,7 +4763,7 @@ static GSList *get_sorted_cpu_model_list(void) static char *x86_cpu_class_get_model_id(X86CPUClass *xc) { - Object *obj = object_new(object_class_get_name(OBJECT_CLASS(xc))); + Object *obj = object_new_with_class(OBJECT_CLASS(xc)); char *r = object_property_get_str(obj, "model-id", &error_abort); object_unref(obj); return r; @@ -5141,7 +5141,7 @@ static X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error **errp) goto out; } - xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc)))); + xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc))); if (props) { object_apply_props(OBJECT(xc), props, &err); if (err) { @@ -5983,7 +5983,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) APICCommonState *apic; ObjectClass *apic_class = OBJECT_CLASS(apic_get_class()); - cpu->apic_state = DEVICE(object_new(object_class_get_name(apic_class))); + cpu->apic_state = DEVICE(object_new_with_class(apic_class)); object_property_add_child(OBJECT(cpu), "lapic", OBJECT(cpu->apic_state), &error_abort); diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 1d10046..0b51190 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -35,7 +35,7 @@ #include "qemu/main-loop.h" #include "qemu/config-file.h" #include "qemu/error-report.h" -#include "hw/i386/pc.h" +#include "hw/i386/x86.h" #include "hw/i386/apic.h" #include "hw/i386/apic_internal.h" #include "hw/i386/apic-msidef.h" @@ -2163,7 +2163,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } qemu_register_reset(kvm_unpoison_all, NULL); - shadow_mem = machine_kvm_shadow_mem(ms); + shadow_mem = object_property_get_int(OBJECT(s), "kvm-shadow-mem", &error_abort); if (shadow_mem != -1) { shadow_mem /= 4096; ret = kvm_vm_ioctl(s, KVM_SET_NR_MMU_PAGES, shadow_mem); @@ -2173,8 +2173,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } if (kvm_check_extension(s, KVM_CAP_X86_SMM) && - object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE) && - pc_machine_is_smm_enabled(PC_MACHINE(ms))) { + x86_machine_is_smm_enabled(X86_MACHINE(ms))) { smram_machine_done.notify = register_smram_listener; qemu_add_machine_init_done_notifier(&smram_machine_done); } @@ -4494,10 +4493,10 @@ void kvm_arch_init_irq_routing(KVMState *s) } } -int kvm_arch_irqchip_create(MachineState *ms, KVMState *s) +int kvm_arch_irqchip_create(KVMState *s) { int ret; - if (machine_kernel_irqchip_split(ms)) { + if (kvm_kernel_irqchip_split()) { ret = kvm_vm_enable_cap(s, KVM_CAP_SPLIT_IRQCHIP, 0, 24); if (ret) { error_report("Could not enable split irqchip mode: %s", @@ -4513,146 +4512,6 @@ int kvm_arch_irqchip_create(MachineState *ms, KVMState *s) } } -/* Classic KVM device assignment interface. Will remain x86 only. */ -int kvm_device_pci_assign(KVMState *s, PCIHostDeviceAddress *dev_addr, - uint32_t flags, uint32_t *dev_id) -{ - struct kvm_assigned_pci_dev dev_data = { - .segnr = dev_addr->domain, - .busnr = dev_addr->bus, - .devfn = PCI_DEVFN(dev_addr->slot, dev_addr->function), - .flags = flags, - }; - int ret; - - dev_data.assigned_dev_id = - (dev_addr->domain << 16) | (dev_addr->bus << 8) | dev_data.devfn; - - ret = kvm_vm_ioctl(s, KVM_ASSIGN_PCI_DEVICE, &dev_data); - if (ret < 0) { - return ret; - } - - *dev_id = dev_data.assigned_dev_id; - - return 0; -} - -int kvm_device_pci_deassign(KVMState *s, uint32_t dev_id) -{ - struct kvm_assigned_pci_dev dev_data = { - .assigned_dev_id = dev_id, - }; - - return kvm_vm_ioctl(s, KVM_DEASSIGN_PCI_DEVICE, &dev_data); -} - -static int kvm_assign_irq_internal(KVMState *s, uint32_t dev_id, - uint32_t irq_type, uint32_t guest_irq) -{ - struct kvm_assigned_irq assigned_irq = { - .assigned_dev_id = dev_id, - .guest_irq = guest_irq, - .flags = irq_type, - }; - - if (kvm_check_extension(s, KVM_CAP_ASSIGN_DEV_IRQ)) { - return kvm_vm_ioctl(s, KVM_ASSIGN_DEV_IRQ, &assigned_irq); - } else { - return kvm_vm_ioctl(s, KVM_ASSIGN_IRQ, &assigned_irq); - } -} - -int kvm_device_intx_assign(KVMState *s, uint32_t dev_id, bool use_host_msi, - uint32_t guest_irq) -{ - uint32_t irq_type = KVM_DEV_IRQ_GUEST_INTX | - (use_host_msi ? KVM_DEV_IRQ_HOST_MSI : KVM_DEV_IRQ_HOST_INTX); - - return kvm_assign_irq_internal(s, dev_id, irq_type, guest_irq); -} - -int kvm_device_intx_set_mask(KVMState *s, uint32_t dev_id, bool masked) -{ - struct kvm_assigned_pci_dev dev_data = { - .assigned_dev_id = dev_id, - .flags = masked ? KVM_DEV_ASSIGN_MASK_INTX : 0, - }; - - return kvm_vm_ioctl(s, KVM_ASSIGN_SET_INTX_MASK, &dev_data); -} - -static int kvm_deassign_irq_internal(KVMState *s, uint32_t dev_id, - uint32_t type) -{ - struct kvm_assigned_irq assigned_irq = { - .assigned_dev_id = dev_id, - .flags = type, - }; - - return kvm_vm_ioctl(s, KVM_DEASSIGN_DEV_IRQ, &assigned_irq); -} - -int kvm_device_intx_deassign(KVMState *s, uint32_t dev_id, bool use_host_msi) -{ - return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_INTX | - (use_host_msi ? KVM_DEV_IRQ_HOST_MSI : KVM_DEV_IRQ_HOST_INTX)); -} - -int kvm_device_msi_assign(KVMState *s, uint32_t dev_id, int virq) -{ - return kvm_assign_irq_internal(s, dev_id, KVM_DEV_IRQ_HOST_MSI | - KVM_DEV_IRQ_GUEST_MSI, virq); -} - -int kvm_device_msi_deassign(KVMState *s, uint32_t dev_id) -{ - return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSI | - KVM_DEV_IRQ_HOST_MSI); -} - -bool kvm_device_msix_supported(KVMState *s) -{ - /* The kernel lacks a corresponding KVM_CAP, so we probe by calling - * KVM_ASSIGN_SET_MSIX_NR with an invalid parameter. */ - return kvm_vm_ioctl(s, KVM_ASSIGN_SET_MSIX_NR, NULL) == -EFAULT; -} - -int kvm_device_msix_init_vectors(KVMState *s, uint32_t dev_id, - uint32_t nr_vectors) -{ - struct kvm_assigned_msix_nr msix_nr = { - .assigned_dev_id = dev_id, - .entry_nr = nr_vectors, - }; - - return kvm_vm_ioctl(s, KVM_ASSIGN_SET_MSIX_NR, &msix_nr); -} - -int kvm_device_msix_set_vector(KVMState *s, uint32_t dev_id, uint32_t vector, - int virq) -{ - struct kvm_assigned_msix_entry msix_entry = { - .assigned_dev_id = dev_id, - .gsi = virq, - .entry = vector, - }; - - return kvm_vm_ioctl(s, KVM_ASSIGN_SET_MSIX_ENTRY, &msix_entry); -} - -int kvm_device_msix_assign(KVMState *s, uint32_t dev_id) -{ - return kvm_assign_irq_internal(s, dev_id, KVM_DEV_IRQ_HOST_MSIX | - KVM_DEV_IRQ_GUEST_MSIX, 0); -} - -int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id) -{ - return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSIX | - KVM_DEV_IRQ_HOST_MSIX); -} - int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, uint64_t address, uint32_t data, PCIDevice *dev) { diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h index 06fe06b..7d0242f 100644 --- a/target/i386/kvm_i386.h +++ b/target/i386/kvm_i386.h @@ -40,26 +40,6 @@ void kvm_synchronize_all_tsc(void); void kvm_arch_reset_vcpu(X86CPU *cs); void kvm_arch_do_init_vcpu(X86CPU *cs); -int kvm_device_pci_assign(KVMState *s, PCIHostDeviceAddress *dev_addr, - uint32_t flags, uint32_t *dev_id); -int kvm_device_pci_deassign(KVMState *s, uint32_t dev_id); - -int kvm_device_intx_assign(KVMState *s, uint32_t dev_id, - bool use_host_msi, uint32_t guest_irq); -int kvm_device_intx_set_mask(KVMState *s, uint32_t dev_id, bool masked); -int kvm_device_intx_deassign(KVMState *s, uint32_t dev_id, bool use_host_msi); - -int kvm_device_msi_assign(KVMState *s, uint32_t dev_id, int virq); -int kvm_device_msi_deassign(KVMState *s, uint32_t dev_id); - -bool kvm_device_msix_supported(KVMState *s); -int kvm_device_msix_init_vectors(KVMState *s, uint32_t dev_id, - uint32_t nr_vectors); -int kvm_device_msix_set_vector(KVMState *s, uint32_t dev_id, uint32_t vector, - int virq); -int kvm_device_msix_assign(KVMState *s, uint32_t dev_id); -int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id); - void kvm_put_apicbase(X86CPU *cpu, uint64_t value); bool kvm_enable_x2apic(void); diff --git a/target/i386/machine.c b/target/i386/machine.c index 2699eed..0c96531 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -1,10 +1,10 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/exec-all.h" -#include "hw/i386/pc.h" #include "hw/isa/isa.h" #include "migration/cpu.h" #include "hyperv.h" +#include "hw/i386/x86.h" #include "kvm_i386.h" #include "sysemu/kvm.h" @@ -261,7 +261,7 @@ static int cpu_pre_save(void *opaque) * intercepted anymore. * * Furthermore, when a L2 exception is intercepted by L1 - * hypervisor, it's exception payload (CR2/DR6 on #PF/#DB) + * hypervisor, its exception payload (CR2/DR6 on #PF/#DB) * should not be set yet in the respective vCPU register. * Thus, in case an exception is pending, it is * important to save the exception payload seperately. @@ -271,9 +271,9 @@ static int cpu_pre_save(void *opaque) * distinguish between a pending and injected exception * and we don't need to store seperately the exception payload. * - * In order to preserve better backwards-compatabile migration, + * In order to preserve better backwards-compatible migration, * convert a pending exception to an injected exception in - * case it is not important to distingiush between them + * case it is not important to distinguish between them * as described above. */ if (env->exception_pending && !(env->hflags & HF_GUEST_MASK)) { @@ -415,7 +415,7 @@ static bool exception_info_needed(void *opaque) /* * It is important to save exception-info only in case - * we need to distingiush between a pending and injected + * we need to distinguish between a pending and injected * exception. Which is only required in case there is a * pending exception and vCPU is running L2. * For more info, refer to comment in cpu_pre_save(). diff --git a/target/i386/monitor.c b/target/i386/monitor.c index 9fb4d64..27ebfa3 100644 --- a/target/i386/monitor.c +++ b/target/i386/monitor.c @@ -28,7 +28,6 @@ #include "monitor/hmp-target.h" #include "monitor/hmp.h" #include "qapi/qmp/qdict.h" -#include "hw/i386/pc.h" #include "sysemu/kvm.h" #include "sysemu/sev.h" #include "qapi/error.h" diff --git a/target/i386/whp-dispatch.h b/target/i386/whp-dispatch.h index 23791fb..87d049c 100644 --- a/target/i386/whp-dispatch.h +++ b/target/i386/whp-dispatch.h @@ -50,5 +50,9 @@ extern struct WHPDispatch whp_dispatch; bool init_whp_dispatch(void); +typedef enum WHPFunctionList { + WINHV_PLATFORM_FNS_DEFAULT, + WINHV_EMULATION_FNS_DEFAULT, +} WHPFunctionList; #endif /* WHP_DISPATCH_H */ diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index def0c28..3ed2aa1 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -1356,6 +1356,58 @@ static void whpx_handle_interrupt(CPUState *cpu, int mask) } /* + * Load the functions from the given library, using the given handle. If a + * handle is provided, it is used, otherwise the library is opened. The + * handle will be updated on return with the opened one. + */ +static bool load_whp_dispatch_fns(HMODULE *handle, + WHPFunctionList function_list) +{ + HMODULE hLib = *handle; + + #define WINHV_PLATFORM_DLL "WinHvPlatform.dll" + #define WINHV_EMULATION_DLL "WinHvEmulation.dll" + #define WHP_LOAD_FIELD(return_type, function_name, signature) \ + whp_dispatch.function_name = \ + (function_name ## _t)GetProcAddress(hLib, #function_name); \ + if (!whp_dispatch.function_name) { \ + error_report("Could not load function %s", #function_name); \ + goto error; \ + } \ + + #define WHP_LOAD_LIB(lib_name, handle_lib) \ + if (!handle_lib) { \ + handle_lib = LoadLibrary(lib_name); \ + if (!handle_lib) { \ + error_report("Could not load library %s.", lib_name); \ + goto error; \ + } \ + } \ + + switch (function_list) { + case WINHV_PLATFORM_FNS_DEFAULT: + WHP_LOAD_LIB(WINHV_PLATFORM_DLL, hLib) + LIST_WINHVPLATFORM_FUNCTIONS(WHP_LOAD_FIELD) + break; + + case WINHV_EMULATION_FNS_DEFAULT: + WHP_LOAD_LIB(WINHV_EMULATION_DLL, hLib) + LIST_WINHVEMULATION_FUNCTIONS(WHP_LOAD_FIELD) + break; + } + + *handle = hLib; + return true; + +error: + if (hLib) { + FreeLibrary(hLib); + } + + return false; +} + +/* * Partition support */ @@ -1490,51 +1542,30 @@ static void whpx_type_init(void) bool init_whp_dispatch(void) { - const char *lib_name; - HMODULE hLib; - if (whp_dispatch_initialized) { return true; } - #define WHP_LOAD_FIELD(return_type, function_name, signature) \ - whp_dispatch.function_name = \ - (function_name ## _t)GetProcAddress(hLib, #function_name); \ - if (!whp_dispatch.function_name) { \ - error_report("Could not load function %s from library %s.", \ - #function_name, lib_name); \ - goto error; \ - } \ - - lib_name = "WinHvPlatform.dll"; - hWinHvPlatform = LoadLibrary(lib_name); - if (!hWinHvPlatform) { - error_report("Could not load library %s.", lib_name); + if (!load_whp_dispatch_fns(&hWinHvPlatform, WINHV_PLATFORM_FNS_DEFAULT)) { goto error; } - hLib = hWinHvPlatform; - LIST_WINHVPLATFORM_FUNCTIONS(WHP_LOAD_FIELD) - lib_name = "WinHvEmulation.dll"; - hWinHvEmulation = LoadLibrary(lib_name); - if (!hWinHvEmulation) { - error_report("Could not load library %s.", lib_name); + if (!load_whp_dispatch_fns(&hWinHvEmulation, WINHV_EMULATION_FNS_DEFAULT)) { goto error; } - hLib = hWinHvEmulation; - LIST_WINHVEMULATION_FUNCTIONS(WHP_LOAD_FIELD) whp_dispatch_initialized = true; - return true; - - error: + return true; +error: if (hWinHvPlatform) { FreeLibrary(hWinHvPlatform); } + if (hWinHvEmulation) { FreeLibrary(hWinHvEmulation); } + return false; } diff --git a/target/mips/kvm.c b/target/mips/kvm.c index 578bc14..de3e26e 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -57,7 +57,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) return 0; } -int kvm_arch_irqchip_create(MachineState *ms, KVMState *s) +int kvm_arch_irqchip_create(KVMState *s) { return 0; } diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 7406d18..d1c334f 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -152,7 +152,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) return 0; } -int kvm_arch_irqchip_create(MachineState *ms, KVMState *s) +int kvm_arch_irqchip_create(KVMState *s) { return 0; } @@ -2076,7 +2076,7 @@ int kvmppc_set_smt_threads(int smt) return ret; } -void kvmppc_error_append_smt_possible_hint(Error **errp_in) +void kvmppc_error_append_smt_possible_hint(Error *const *errp) { int i; GString *g; @@ -2091,10 +2091,10 @@ void kvmppc_error_append_smt_possible_hint(Error **errp_in) } } s = g_string_free(g, false); - error_append_hint(errp_in, "%s.\n", s); + error_append_hint(errp, "%s.\n", s); g_free(s); } else { - error_append_hint(errp_in, + error_append_hint(errp, "This KVM seems to be too old to support VSMT.\n"); } } diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 47b08a4..f22daab 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -28,7 +28,7 @@ void kvmppc_set_papr(PowerPCCPU *cpu); int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr); void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy); int kvmppc_smt_threads(void); -void kvmppc_error_append_smt_possible_hint(Error **errp_in); +void kvmppc_error_append_smt_possible_hint(Error *const *errp); int kvmppc_set_smt_threads(int smt); int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits); int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits); @@ -164,7 +164,7 @@ static inline int kvmppc_smt_threads(void) return 1; } -static inline void kvmppc_error_append_smt_possible_hint(Error **errp_in) +static inline void kvmppc_error_append_smt_possible_hint(Error *const *errp) { return; } diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 547bab8..7c32180 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -440,7 +440,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) if (cpu_list_data->model) { Object *obj; S390CPU *sc; - obj = object_new(object_class_get_name(klass)); + obj = object_new_with_class(klass); sc = S390_CPU(obj); if (sc->model) { info->has_unavailable_features = true; @@ -498,7 +498,7 @@ static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, error_setg(errp, "The CPU definition '%s' requires KVM", info->name); return; } - obj = object_new(object_class_get_name(oc)); + obj = object_new_with_class(oc); cpu = S390_CPU(obj); if (!cpu->model) { diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index ad6e38c..15260ae 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -374,7 +374,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) return 0; } -int kvm_arch_irqchip_create(MachineState *ms, KVMState *s) +int kvm_arch_irqchip_create(KVMState *s) { return 0; } diff --git a/target/sparc/TODO b/target/sparc/TODO deleted file mode 100644 index b8c727e..0000000 --- a/target/sparc/TODO +++ /dev/null @@ -1,88 +0,0 @@ -TODO-list: - -CPU common: -- Unimplemented features/bugs: - - Delay slot handling may fail sometimes (branch end of page, delay - slot next page) - - Atomical instructions - - CPU features should match real CPUs (also ASI selection) -- Optimizations/improvements: - - Condition code/branch handling like x86, also for FPU? - - Remove remaining explicit alignment checks - - Global register for regwptr, so that windowed registers can be - accessed directly - - Improve Sparc32plus addressing - - NPC/PC static optimisations (use JUMP_TB when possible)? (Is this - obsolete?) - - Synthetic instructions - - MMU model dependent on CPU model - - Select ASI helper at translation time (on V9 only if known) - - KQemu/KVM support for VM only - - Hardware breakpoint/watchpoint support - - Cache emulation mode - - Reverse-endian pages - - Faster FPU emulation - - Busy loop detection - -Sparc32 CPUs: -- Unimplemented features/bugs: - - Sun4/Sun4c MMUs - - Some V8 ASIs - -Sparc64 CPUs: -- Unimplemented features/bugs: - - Interrupt handling - - Secondary address space, other MMU functions - - Many V9/UA2005/UA2007 ASIs - - Rest of V9 instructions, missing VIS instructions - - IG/MG/AG vs. UA2007 globals - - Full hypervisor support - - SMP/CMT - - Sun4v CPUs - -Sun4: -- To be added - -Sun4c: -- A lot of unimplemented features -- Maybe split from Sun4m - -Sun4m: -- Unimplemented features/bugs: - - Hardware devices do not match real boards - - Floppy does not work - - CS4231: merge with cs4231a, add DMA - - Add cg6, bwtwo - - Arbitrary resolution support - - PCI for MicroSparc-IIe - - JavaStation machines - - SBus slot probing, FCode ROM support - - SMP probing support - - Interrupt routing does not match real HW - - SuSE 7.3 keyboard sometimes unresponsive - - Gentoo 2004.1 SMP does not work - - SS600MP ledma -> lebuffer - - Type 5 keyboard - - Less fixed hardware choices - - DBRI audio (Am7930) - - BPP parallel - - Diagnostic switch - - ESP PIO mode - -Sun4d: -- A lot of unimplemented features: - - SBI - - IO-unit -- Maybe split from Sun4m - -Sun4u: -- Unimplemented features/bugs: - - Interrupt controller - - PCI/IOMMU support (Simba, JIO, Tomatillo, Psycho, Schizo, Safari...) - - SMP - - Happy Meal Ethernet, flash, I2C, GPIO - - A lot of real machine types - -Sun4v: -- A lot of unimplemented features - - A lot of real machine types |