aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/arm/kvm.c8
-rw-r--r--target/i386/cpu.c8
-rw-r--r--target/i386/kvm.c151
-rw-r--r--target/i386/kvm_i386.h20
-rw-r--r--target/i386/machine.c10
-rw-r--r--target/i386/monitor.c1
-rw-r--r--target/i386/whp-dispatch.h4
-rw-r--r--target/i386/whpx-all.c85
-rw-r--r--target/mips/kvm.c2
-rw-r--r--target/ppc/kvm.c8
-rw-r--r--target/ppc/kvm_ppc.h4
-rw-r--r--target/s390x/cpu_models.c4
-rw-r--r--target/s390x/kvm.c2
-rw-r--r--target/sparc/TODO88
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