* hw/i386: split isapc from PCI boards
* cpu-exec, accel: remove BQL usage for interrupt_request != 0 * memory, hpet, pmtimer: introduce BQL-free PIO/MMIO -----BEGIN PGP SIGNATURE----- iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmixiO4UHHBib256aW5p QHJlZGhhdC5jb20ACgkQv/vSX3jHroMTowf9EmIcSgFXrP8QR/rVQ+Z8+csR4md7 QDzQwoDHaP9F/J728AoT/nDwwlfiHRbcH8AQbzzMrsmMnqhaWCFWD5snGelzPJAo BPaOa4eYvwgssW1apfxGgzae71B3Hbx/sMYHdRcUvBnvS6cKEcOcgK8pANuZGzGQ uRquCMvk14WhnQV/NFqr2PmtmxXjdDNefdi1RfpaPDEt4VZsh4B3afU+I+L4LvIQ NOPh0PbDk+BLRt2fRPgdwF6KqS5ajPEzKnBlS0uxSXKxpLOLM/2SNDOGDDVUrAwV ILrnchZrpxHsHwBCjaBhKZDTTQUcH0HUrZhRJbUPsg5feHRs3KoaFJjmCQ== =RMLB -----END PGP SIGNATURE----- Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging * hw/i386: split isapc from PCI boards * cpu-exec, accel: remove BQL usage for interrupt_request != 0 * memory, hpet, pmtimer: introduce BQL-free PIO/MMIO # -----BEGIN PGP SIGNATURE----- # # iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmixiO4UHHBib256aW5p # QHJlZGhhdC5jb20ACgkQv/vSX3jHroMTowf9EmIcSgFXrP8QR/rVQ+Z8+csR4md7 # QDzQwoDHaP9F/J728AoT/nDwwlfiHRbcH8AQbzzMrsmMnqhaWCFWD5snGelzPJAo # BPaOa4eYvwgssW1apfxGgzae71B3Hbx/sMYHdRcUvBnvS6cKEcOcgK8pANuZGzGQ # uRquCMvk14WhnQV/NFqr2PmtmxXjdDNefdi1RfpaPDEt4VZsh4B3afU+I+L4LvIQ # NOPh0PbDk+BLRt2fRPgdwF6KqS5ajPEzKnBlS0uxSXKxpLOLM/2SNDOGDDVUrAwV # ILrnchZrpxHsHwBCjaBhKZDTTQUcH0HUrZhRJbUPsg5feHRs3KoaFJjmCQ== # =RMLB # -----END PGP SIGNATURE----- # gpg: Signature made Fri 29 Aug 2025 09:03:10 PM AEST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [unknown] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (28 commits) tcg: move interrupt caching and single step masking closer to user kvm: i386: irqchip: take BQL only if there is an interrupt hpet: make main counter read lock-less hpet: move out main counter read into a separate block hpet: switch to fine-grained device locking acpi: mark PMTIMER as unlocked memory: reintroduce BQL-free fine-grained PIO/MMIO add cpu_test_interrupt()/cpu_set_interrupt() helpers and use them tree wide user-exec: ensure interrupt_request is not used hw/i386/isapc.c: replace rom_memory with system_memory hw/i386/pc_piix.c: replace rom_memory with pci_memory hw/i386/pc_piix.c: remove unused headers after isapc machine split hw/i386: move isapc machine to separate isapc.c file hw/i386/pc_piix.c: assume pcmc->pci_enabled is always true in pc_init1() hw/i386/pc_piix.c: always initialise ISA IDE drives in pc_init_isa() hw/i386/pc_piix.c: remove pc_system_flash_cleanup_unused() from pc_init_isa() hw/i386/pc_piix.c: hardcode hole64_size to 0 in pc_init_isa() hw/i386/pc_piix.c: simplify RAM size logic in pc_init_isa() hw/i386/pc_piix.c: remove nvdimm initialisation from pc_init_isa() hw/i386/pc_piix.c: remove SGX initialisation from pc_init_isa() ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
91589bcd9f
44 changed files with 490 additions and 319 deletions
|
|
@ -778,24 +778,20 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
|
|||
*/
|
||||
qatomic_set_mb(&cpu->neg.icount_decr.u16.high, 0);
|
||||
|
||||
if (unlikely(qatomic_read(&cpu->interrupt_request))) {
|
||||
int interrupt_request;
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
assert(!cpu_test_interrupt(cpu, ~0));
|
||||
#else
|
||||
if (unlikely(cpu_test_interrupt(cpu, ~0))) {
|
||||
bql_lock();
|
||||
interrupt_request = cpu->interrupt_request;
|
||||
if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
|
||||
/* Mask out external interrupts for this step. */
|
||||
interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_DEBUG)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
|
||||
cpu->exception_index = EXCP_DEBUG;
|
||||
bql_unlock();
|
||||
return true;
|
||||
}
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (replay_mode == REPLAY_MODE_PLAY && !replay_has_interrupt()) {
|
||||
/* Do nothing */
|
||||
} else if (interrupt_request & CPU_INTERRUPT_HALT) {
|
||||
} else if (cpu_test_interrupt(cpu, CPU_INTERRUPT_HALT)) {
|
||||
replay_interrupt();
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
|
||||
cpu->halted = 1;
|
||||
|
|
@ -804,14 +800,20 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
|
|||
return true;
|
||||
} else {
|
||||
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
|
||||
int interrupt_request = cpu->interrupt_request;
|
||||
|
||||
if (interrupt_request & CPU_INTERRUPT_RESET) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_RESET)) {
|
||||
replay_interrupt();
|
||||
tcg_ops->cpu_exec_reset(cpu);
|
||||
bql_unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
|
||||
/* Mask out external interrupts for this step. */
|
||||
interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* The target hook has 3 exit conditions:
|
||||
* False when the interrupt isn't processed,
|
||||
|
|
@ -836,12 +838,8 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
|
|||
cpu->exception_index = -1;
|
||||
*last_tb = NULL;
|
||||
}
|
||||
/* The target hook may have updated the 'cpu->interrupt_request';
|
||||
* reload the 'interrupt_request' value */
|
||||
interrupt_request = cpu->interrupt_request;
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
if (interrupt_request & CPU_INTERRUPT_EXITTB) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_EXITTB)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
|
||||
/* ensure that no TB jump will be modified as
|
||||
the program flow was changed */
|
||||
|
|
@ -851,6 +849,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
|
|||
/* If we exit via cpu_loop_exit/longjmp it is reset in cpu_exec */
|
||||
bql_unlock();
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
/* Finally, check if we need to exit to the main loop. */
|
||||
if (unlikely(qatomic_read(&cpu->exit_request)) || icount_exit_request(cpu)) {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ static void tcg_cpu_reset_hold(CPUState *cpu)
|
|||
/* mask must never be zero, except for A20 change call */
|
||||
void tcg_handle_interrupt(CPUState *cpu, int mask)
|
||||
{
|
||||
cpu->interrupt_request |= mask;
|
||||
cpu_set_interrupt(cpu, mask);
|
||||
|
||||
/*
|
||||
* If called from iothread context, wake the target cpu in
|
||||
|
|
|
|||
|
|
@ -48,9 +48,7 @@ __thread uintptr_t helper_retaddr;
|
|||
|
||||
void cpu_interrupt(CPUState *cpu, int mask)
|
||||
{
|
||||
g_assert(bql_locked());
|
||||
cpu->interrupt_request |= mask;
|
||||
qatomic_set(&cpu->neg.icount_decr.u16.high, -1);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -547,6 +547,7 @@ void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
|
|||
ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar);
|
||||
memory_region_init_io(&ar->tmr.io, memory_region_owner(parent),
|
||||
&acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
|
||||
memory_region_enable_lockless_io(&ar->tmr.io);
|
||||
memory_region_add_subregion(parent, 8, &ar->tmr.io);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,9 +96,6 @@ config ISAPC
|
|||
select ISA_BUS
|
||||
select PC
|
||||
select IDE_ISA
|
||||
# FIXME: it is in the same file as i440fx, and does not compile
|
||||
# if separated
|
||||
depends on I440FX
|
||||
|
||||
config Q35
|
||||
bool
|
||||
|
|
|
|||
189
hw/i386/isapc.c
Normal file
189
hw/i386/isapc.c
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* QEMU PC System Emulator
|
||||
*
|
||||
* Copyright (c) 2003-2004 Fabrice Bellard
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "qemu/units.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/char/parallel-isa.h"
|
||||
#include "hw/dma/i8257.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "hw/ide/isa.h"
|
||||
#include "hw/ide/ide-bus.h"
|
||||
#include "system/kvm.h"
|
||||
#include "hw/i386/kvm/clock.h"
|
||||
#include "hw/xen/xen-x86.h"
|
||||
#include "system/xen.h"
|
||||
#include "hw/rtc/mc146818rtc.h"
|
||||
#include "target/i386/cpu.h"
|
||||
|
||||
static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
|
||||
static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
|
||||
static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
|
||||
|
||||
|
||||
static void pc_init_isa(MachineState *machine)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(machine);
|
||||
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
|
||||
X86MachineState *x86ms = X86_MACHINE(machine);
|
||||
MemoryRegion *system_memory = get_system_memory();
|
||||
MemoryRegion *system_io = get_system_io();
|
||||
ISABus *isa_bus;
|
||||
uint32_t irq;
|
||||
GSIState *gsi_state;
|
||||
MemoryRegion *ram_memory;
|
||||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* There is a small chance that someone unintentionally passes "-cpu max"
|
||||
* for the isapc machine, which will provide a much more modern 32-bit
|
||||
* CPU than would be expected for an ISA-era PC. If the "max" cpu type has
|
||||
* been specified, choose the "best" 32-bit cpu possible which we consider
|
||||
* be the pentium3 (deliberately choosing an Intel CPU given that the
|
||||
* default 486 CPU for the isapc machine is also an Intel CPU).
|
||||
*/
|
||||
if (!strcmp(machine->cpu_type, X86_CPU_TYPE_NAME("max"))) {
|
||||
machine->cpu_type = X86_CPU_TYPE_NAME("pentium3");
|
||||
warn_report("-cpu max is invalid for isapc machine, using pentium3");
|
||||
}
|
||||
|
||||
/*
|
||||
* Similarly if someone unintentionally passes "-cpu host" for the isapc
|
||||
* machine then display a warning and also switch to the "best" 32-bit
|
||||
* cpu possible which we consider to be the pentium3. This is because any
|
||||
* host CPU will already be modern than this, but it also ensures any
|
||||
* newer CPU flags/features are filtered out for older guests.
|
||||
*/
|
||||
if (!strcmp(machine->cpu_type, X86_CPU_TYPE_NAME("host"))) {
|
||||
machine->cpu_type = X86_CPU_TYPE_NAME("pentium3");
|
||||
warn_report("-cpu host is invalid for isapc machine, using pentium3");
|
||||
}
|
||||
|
||||
if (machine->ram_size > 3.5 * GiB) {
|
||||
error_report("Too much memory for this machine: %" PRId64 " MiB, "
|
||||
"maximum 3584 MiB", machine->ram_size / MiB);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no RAM split for the isapc machine
|
||||
*/
|
||||
if (xen_enabled()) {
|
||||
xen_hvm_init_pc(pcms, &ram_memory);
|
||||
} else {
|
||||
ram_memory = machine->ram;
|
||||
|
||||
pcms->max_ram_below_4g = 3.5 * GiB;
|
||||
x86ms->above_4g_mem_size = 0;
|
||||
x86ms->below_4g_mem_size = machine->ram_size;
|
||||
}
|
||||
|
||||
x86_cpus_init(x86ms, pcmc->default_cpu_version);
|
||||
|
||||
if (kvm_enabled()) {
|
||||
kvmclock_create(pcmc->kvmclock_create_always);
|
||||
}
|
||||
|
||||
/* allocate ram and load rom/bios */
|
||||
if (!xen_enabled()) {
|
||||
pc_memory_init(pcms, system_memory, system_memory, 0);
|
||||
} else {
|
||||
assert(machine->ram_size == x86ms->below_4g_mem_size +
|
||||
x86ms->above_4g_mem_size);
|
||||
|
||||
if (machine->kernel_filename != NULL) {
|
||||
/* For xen HVM direct kernel boot, load linux here */
|
||||
xen_load_linux(pcms);
|
||||
}
|
||||
}
|
||||
|
||||
gsi_state = pc_gsi_create(&x86ms->gsi, false);
|
||||
|
||||
isa_bus = isa_bus_new(NULL, system_memory, system_io,
|
||||
&error_abort);
|
||||
isa_bus_register_input_irqs(isa_bus, x86ms->gsi);
|
||||
|
||||
x86ms->rtc = isa_new(TYPE_MC146818_RTC);
|
||||
qdev_prop_set_int32(DEVICE(x86ms->rtc), "base_year", 2000);
|
||||
isa_realize_and_unref(x86ms->rtc, isa_bus, &error_fatal);
|
||||
irq = object_property_get_uint(OBJECT(x86ms->rtc), "irq",
|
||||
&error_fatal);
|
||||
isa_connect_gpio_out(ISA_DEVICE(x86ms->rtc), 0, irq);
|
||||
|
||||
i8257_dma_init(OBJECT(machine), isa_bus, 0);
|
||||
pcms->hpet_enabled = false;
|
||||
|
||||
if (x86ms->pic == ON_OFF_AUTO_ON || x86ms->pic == ON_OFF_AUTO_AUTO) {
|
||||
pc_i8259_create(isa_bus, gsi_state->i8259_irq);
|
||||
}
|
||||
|
||||
if (tcg_enabled()) {
|
||||
x86_register_ferr_irq(x86ms->gsi[13]);
|
||||
}
|
||||
|
||||
pc_vga_init(isa_bus, NULL);
|
||||
|
||||
/* init basic PC hardware */
|
||||
pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc,
|
||||
!MACHINE_CLASS(pcmc)->no_floppy, 0x4);
|
||||
|
||||
pc_nic_init(pcmc, isa_bus, NULL);
|
||||
|
||||
ide_drive_get(hd, ARRAY_SIZE(hd));
|
||||
for (i = 0; i < MAX_IDE_BUS; i++) {
|
||||
ISADevice *dev;
|
||||
char busname[] = "ide.0";
|
||||
dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
|
||||
ide_irq[i],
|
||||
hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
|
||||
/*
|
||||
* The ide bus name is ide.0 for the first bus and ide.1 for the
|
||||
* second one.
|
||||
*/
|
||||
busname[4] = '0' + i;
|
||||
pcms->idebus[i] = qdev_get_child_bus(DEVICE(dev), busname);
|
||||
}
|
||||
}
|
||||
|
||||
static void isapc_machine_options(MachineClass *m)
|
||||
{
|
||||
static const char * const valid_cpu_types[] = {
|
||||
X86_CPU_TYPE_NAME("486"),
|
||||
X86_CPU_TYPE_NAME("athlon"),
|
||||
X86_CPU_TYPE_NAME("kvm32"),
|
||||
X86_CPU_TYPE_NAME("pentium"),
|
||||
X86_CPU_TYPE_NAME("pentium2"),
|
||||
X86_CPU_TYPE_NAME("pentium3"),
|
||||
X86_CPU_TYPE_NAME("qemu32"),
|
||||
X86_CPU_TYPE_NAME("max"),
|
||||
X86_CPU_TYPE_NAME("host"),
|
||||
NULL
|
||||
};
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
|
||||
m->desc = "ISA-only PC";
|
||||
m->max_cpus = 1;
|
||||
m->option_rom_has_mr = true;
|
||||
m->rom_file_has_mr = false;
|
||||
pcmc->pci_enabled = false;
|
||||
pcmc->has_acpi_build = false;
|
||||
pcmc->smbios_defaults = false;
|
||||
pcmc->gigabyte_align = false;
|
||||
pcmc->smbios_legacy_mode = true;
|
||||
pcmc->has_reserved_memory = false;
|
||||
m->default_nic = "ne2k_isa";
|
||||
m->default_cpu_type = X86_CPU_TYPE_NAME("486");
|
||||
m->valid_cpu_types = valid_cpu_types;
|
||||
m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC);
|
||||
m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
|
||||
}
|
||||
|
||||
DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
|
||||
isapc_machine_options);
|
||||
|
|
@ -14,6 +14,7 @@ i386_ss.add(when: 'CONFIG_X86_IOMMU', if_true: files('x86-iommu.c'),
|
|||
i386_ss.add(when: 'CONFIG_AMD_IOMMU', if_true: files('amd_iommu.c'),
|
||||
if_false: files('amd_iommu-stub.c'))
|
||||
i386_ss.add(when: 'CONFIG_I440FX', if_true: files('pc_piix.c'))
|
||||
i386_ss.add(when: 'CONFIG_ISAPC', if_true: files('isapc.c'))
|
||||
i386_ss.add(when: 'CONFIG_MICROVM', if_true: files('x86-common.c', 'microvm.c', 'acpi-microvm.c', 'microvm-dt.c'))
|
||||
i386_ss.add(when: 'CONFIG_NITRO_ENCLAVE', if_true: files('nitro_enclave.c'))
|
||||
i386_ss.add(when: 'CONFIG_Q35', if_true: files('pc_q35.c'))
|
||||
|
|
|
|||
|
|
@ -27,20 +27,16 @@
|
|||
|
||||
#include "qemu/units.h"
|
||||
#include "hw/char/parallel-isa.h"
|
||||
#include "hw/dma/i8257.h"
|
||||
#include "hw/loader.h"
|
||||
#include "hw/i386/x86.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "hw/i386/apic.h"
|
||||
#include "hw/pci-host/i440fx.h"
|
||||
#include "hw/rtc/mc146818rtc.h"
|
||||
#include "hw/southbridge/piix.h"
|
||||
#include "hw/display/ramfb.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/pci/pci_ids.h"
|
||||
#include "hw/usb.h"
|
||||
#include "net/net.h"
|
||||
#include "hw/ide/isa.h"
|
||||
#include "hw/ide/pci.h"
|
||||
#include "hw/irq.h"
|
||||
#include "system/kvm.h"
|
||||
|
|
@ -72,12 +68,6 @@
|
|||
|
||||
#define XEN_IOAPIC_NUM_PIRQS 128ULL
|
||||
|
||||
#ifdef CONFIG_IDE_ISA
|
||||
static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
|
||||
static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
|
||||
static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
|
||||
#endif
|
||||
|
||||
static GlobalProperty pc_piix_compat_defaults[] = {
|
||||
{ TYPE_RAMFB_DEVICE, "use-legacy-x86-rom", "true" },
|
||||
{ TYPE_VFIO_PCI_NOHOTPLUG, "use-legacy-x86-rom", "true" },
|
||||
|
|
@ -123,9 +113,13 @@ static void pc_init1(MachineState *machine, const char *pci_type)
|
|||
GSIState *gsi_state;
|
||||
MemoryRegion *ram_memory;
|
||||
MemoryRegion *pci_memory = NULL;
|
||||
MemoryRegion *rom_memory = system_memory;
|
||||
ram_addr_t lowmem;
|
||||
uint64_t hole64_size = 0;
|
||||
PCIDevice *pci_dev;
|
||||
DeviceState *dev;
|
||||
size_t i;
|
||||
|
||||
assert(pcmc->pci_enabled);
|
||||
|
||||
/*
|
||||
* Calculate ram split, for memory below and above 4G. It's a bit
|
||||
|
|
@ -196,42 +190,39 @@ static void pc_init1(MachineState *machine, const char *pci_type)
|
|||
kvmclock_create(pcmc->kvmclock_create_always);
|
||||
}
|
||||
|
||||
if (pcmc->pci_enabled) {
|
||||
pci_memory = g_new(MemoryRegion, 1);
|
||||
memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
|
||||
rom_memory = pci_memory;
|
||||
pci_memory = g_new(MemoryRegion, 1);
|
||||
memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
|
||||
|
||||
phb = OBJECT(qdev_new(TYPE_I440FX_PCI_HOST_BRIDGE));
|
||||
object_property_add_child(OBJECT(machine), "i440fx", phb);
|
||||
object_property_set_link(phb, PCI_HOST_PROP_RAM_MEM,
|
||||
OBJECT(ram_memory), &error_fatal);
|
||||
object_property_set_link(phb, PCI_HOST_PROP_PCI_MEM,
|
||||
OBJECT(pci_memory), &error_fatal);
|
||||
object_property_set_link(phb, PCI_HOST_PROP_SYSTEM_MEM,
|
||||
OBJECT(system_memory), &error_fatal);
|
||||
object_property_set_link(phb, PCI_HOST_PROP_IO_MEM,
|
||||
OBJECT(system_io), &error_fatal);
|
||||
object_property_set_uint(phb, PCI_HOST_BELOW_4G_MEM_SIZE,
|
||||
x86ms->below_4g_mem_size, &error_fatal);
|
||||
object_property_set_uint(phb, PCI_HOST_ABOVE_4G_MEM_SIZE,
|
||||
x86ms->above_4g_mem_size, &error_fatal);
|
||||
object_property_set_str(phb, I440FX_HOST_PROP_PCI_TYPE, pci_type,
|
||||
&error_fatal);
|
||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(phb), &error_fatal);
|
||||
phb = OBJECT(qdev_new(TYPE_I440FX_PCI_HOST_BRIDGE));
|
||||
object_property_add_child(OBJECT(machine), "i440fx", phb);
|
||||
object_property_set_link(phb, PCI_HOST_PROP_RAM_MEM,
|
||||
OBJECT(ram_memory), &error_fatal);
|
||||
object_property_set_link(phb, PCI_HOST_PROP_PCI_MEM,
|
||||
OBJECT(pci_memory), &error_fatal);
|
||||
object_property_set_link(phb, PCI_HOST_PROP_SYSTEM_MEM,
|
||||
OBJECT(system_memory), &error_fatal);
|
||||
object_property_set_link(phb, PCI_HOST_PROP_IO_MEM,
|
||||
OBJECT(system_io), &error_fatal);
|
||||
object_property_set_uint(phb, PCI_HOST_BELOW_4G_MEM_SIZE,
|
||||
x86ms->below_4g_mem_size, &error_fatal);
|
||||
object_property_set_uint(phb, PCI_HOST_ABOVE_4G_MEM_SIZE,
|
||||
x86ms->above_4g_mem_size, &error_fatal);
|
||||
object_property_set_str(phb, I440FX_HOST_PROP_PCI_TYPE, pci_type,
|
||||
&error_fatal);
|
||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(phb), &error_fatal);
|
||||
|
||||
pcms->pcibus = PCI_BUS(qdev_get_child_bus(DEVICE(phb), "pci.0"));
|
||||
pci_bus_map_irqs(pcms->pcibus,
|
||||
xen_enabled() ? xen_pci_slot_get_pirq
|
||||
: pc_pci_slot_get_pirq);
|
||||
pcms->pcibus = PCI_BUS(qdev_get_child_bus(DEVICE(phb), "pci.0"));
|
||||
pci_bus_map_irqs(pcms->pcibus,
|
||||
xen_enabled() ? xen_pci_slot_get_pirq
|
||||
: pc_pci_slot_get_pirq);
|
||||
|
||||
hole64_size = object_property_get_uint(phb,
|
||||
PCI_HOST_PROP_PCI_HOLE64_SIZE,
|
||||
&error_abort);
|
||||
}
|
||||
hole64_size = object_property_get_uint(phb,
|
||||
PCI_HOST_PROP_PCI_HOLE64_SIZE,
|
||||
&error_abort);
|
||||
|
||||
/* allocate ram and load rom/bios */
|
||||
if (!xen_enabled()) {
|
||||
pc_memory_init(pcms, system_memory, rom_memory, hole64_size);
|
||||
pc_memory_init(pcms, system_memory, pci_memory, hole64_size);
|
||||
} else {
|
||||
assert(machine->ram_size == x86ms->below_4g_mem_size +
|
||||
x86ms->above_4g_mem_size);
|
||||
|
|
@ -243,72 +234,51 @@ static void pc_init1(MachineState *machine, const char *pci_type)
|
|||
}
|
||||
}
|
||||
|
||||
gsi_state = pc_gsi_create(&x86ms->gsi, pcmc->pci_enabled);
|
||||
gsi_state = pc_gsi_create(&x86ms->gsi, true);
|
||||
|
||||
if (pcmc->pci_enabled) {
|
||||
PCIDevice *pci_dev;
|
||||
DeviceState *dev;
|
||||
size_t i;
|
||||
|
||||
pci_dev = pci_new_multifunction(-1, pcms->south_bridge);
|
||||
object_property_set_bool(OBJECT(pci_dev), "has-usb",
|
||||
machine_usb(machine), &error_abort);
|
||||
object_property_set_bool(OBJECT(pci_dev), "has-acpi",
|
||||
x86_machine_is_acpi_enabled(x86ms),
|
||||
&error_abort);
|
||||
object_property_set_bool(OBJECT(pci_dev), "has-pic", false,
|
||||
&error_abort);
|
||||
object_property_set_bool(OBJECT(pci_dev), "has-pit", false,
|
||||
&error_abort);
|
||||
qdev_prop_set_uint32(DEVICE(pci_dev), "smb_io_base", 0xb100);
|
||||
object_property_set_bool(OBJECT(pci_dev), "smm-enabled",
|
||||
x86_machine_is_smm_enabled(x86ms),
|
||||
&error_abort);
|
||||
dev = DEVICE(pci_dev);
|
||||
for (i = 0; i < ISA_NUM_IRQS; i++) {
|
||||
qdev_connect_gpio_out_named(dev, "isa-irqs", i, x86ms->gsi[i]);
|
||||
}
|
||||
pci_realize_and_unref(pci_dev, pcms->pcibus, &error_fatal);
|
||||
|
||||
if (xen_enabled()) {
|
||||
pci_device_set_intx_routing_notifier(
|
||||
pci_dev, piix_intx_routing_notifier_xen);
|
||||
|
||||
/*
|
||||
* Xen supports additional interrupt routes from the PCI devices to
|
||||
* the IOAPIC: the four pins of each PCI device on the bus are also
|
||||
* connected to the IOAPIC directly.
|
||||
* These additional routes can be discovered through ACPI.
|
||||
*/
|
||||
pci_bus_irqs(pcms->pcibus, xen_intx_set_irq, pci_dev,
|
||||
XEN_IOAPIC_NUM_PIRQS);
|
||||
}
|
||||
|
||||
isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci_dev), "isa.0"));
|
||||
x86ms->rtc = ISA_DEVICE(object_resolve_path_component(OBJECT(pci_dev),
|
||||
"rtc"));
|
||||
piix4_pm = object_resolve_path_component(OBJECT(pci_dev), "pm");
|
||||
dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
|
||||
pci_ide_create_devs(PCI_DEVICE(dev));
|
||||
pcms->idebus[0] = qdev_get_child_bus(dev, "ide.0");
|
||||
pcms->idebus[1] = qdev_get_child_bus(dev, "ide.1");
|
||||
} else {
|
||||
uint32_t irq;
|
||||
|
||||
isa_bus = isa_bus_new(NULL, system_memory, system_io,
|
||||
&error_abort);
|
||||
isa_bus_register_input_irqs(isa_bus, x86ms->gsi);
|
||||
|
||||
x86ms->rtc = isa_new(TYPE_MC146818_RTC);
|
||||
qdev_prop_set_int32(DEVICE(x86ms->rtc), "base_year", 2000);
|
||||
isa_realize_and_unref(x86ms->rtc, isa_bus, &error_fatal);
|
||||
irq = object_property_get_uint(OBJECT(x86ms->rtc), "irq",
|
||||
&error_fatal);
|
||||
isa_connect_gpio_out(ISA_DEVICE(x86ms->rtc), 0, irq);
|
||||
|
||||
i8257_dma_init(OBJECT(machine), isa_bus, 0);
|
||||
pcms->hpet_enabled = false;
|
||||
pci_dev = pci_new_multifunction(-1, pcms->south_bridge);
|
||||
object_property_set_bool(OBJECT(pci_dev), "has-usb",
|
||||
machine_usb(machine), &error_abort);
|
||||
object_property_set_bool(OBJECT(pci_dev), "has-acpi",
|
||||
x86_machine_is_acpi_enabled(x86ms),
|
||||
&error_abort);
|
||||
object_property_set_bool(OBJECT(pci_dev), "has-pic", false,
|
||||
&error_abort);
|
||||
object_property_set_bool(OBJECT(pci_dev), "has-pit", false,
|
||||
&error_abort);
|
||||
qdev_prop_set_uint32(DEVICE(pci_dev), "smb_io_base", 0xb100);
|
||||
object_property_set_bool(OBJECT(pci_dev), "smm-enabled",
|
||||
x86_machine_is_smm_enabled(x86ms),
|
||||
&error_abort);
|
||||
dev = DEVICE(pci_dev);
|
||||
for (i = 0; i < ISA_NUM_IRQS; i++) {
|
||||
qdev_connect_gpio_out_named(dev, "isa-irqs", i, x86ms->gsi[i]);
|
||||
}
|
||||
pci_realize_and_unref(pci_dev, pcms->pcibus, &error_fatal);
|
||||
|
||||
if (xen_enabled()) {
|
||||
pci_device_set_intx_routing_notifier(
|
||||
pci_dev, piix_intx_routing_notifier_xen);
|
||||
|
||||
/*
|
||||
* Xen supports additional interrupt routes from the PCI devices to
|
||||
* the IOAPIC: the four pins of each PCI device on the bus are also
|
||||
* connected to the IOAPIC directly.
|
||||
* These additional routes can be discovered through ACPI.
|
||||
*/
|
||||
pci_bus_irqs(pcms->pcibus, xen_intx_set_irq, pci_dev,
|
||||
XEN_IOAPIC_NUM_PIRQS);
|
||||
}
|
||||
|
||||
isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci_dev), "isa.0"));
|
||||
x86ms->rtc = ISA_DEVICE(object_resolve_path_component(OBJECT(pci_dev),
|
||||
"rtc"));
|
||||
piix4_pm = object_resolve_path_component(OBJECT(pci_dev), "pm");
|
||||
dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
|
||||
pci_ide_create_devs(PCI_DEVICE(dev));
|
||||
pcms->idebus[0] = qdev_get_child_bus(dev, "ide.0");
|
||||
pcms->idebus[1] = qdev_get_child_bus(dev, "ide.1");
|
||||
|
||||
|
||||
if (x86ms->pic == ON_OFF_AUTO_ON || x86ms->pic == ON_OFF_AUTO_AUTO) {
|
||||
pc_i8259_create(isa_bus, gsi_state->i8259_irq);
|
||||
|
|
@ -322,7 +292,7 @@ static void pc_init1(MachineState *machine, const char *pci_type)
|
|||
x86_register_ferr_irq(x86ms->gsi[13]);
|
||||
}
|
||||
|
||||
pc_vga_init(isa_bus, pcmc->pci_enabled ? pcms->pcibus : NULL);
|
||||
pc_vga_init(isa_bus, pcms->pcibus);
|
||||
|
||||
/* init basic PC hardware */
|
||||
pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc,
|
||||
|
|
@ -330,28 +300,6 @@ static void pc_init1(MachineState *machine, const char *pci_type)
|
|||
|
||||
pc_nic_init(pcmc, isa_bus, pcms->pcibus);
|
||||
|
||||
#ifdef CONFIG_IDE_ISA
|
||||
if (!pcmc->pci_enabled) {
|
||||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||
int i;
|
||||
|
||||
ide_drive_get(hd, ARRAY_SIZE(hd));
|
||||
for (i = 0; i < MAX_IDE_BUS; i++) {
|
||||
ISADevice *dev;
|
||||
char busname[] = "ide.0";
|
||||
dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
|
||||
ide_irq[i],
|
||||
hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
|
||||
/*
|
||||
* The ide bus name is ide.0 for the first bus and ide.1 for the
|
||||
* second one.
|
||||
*/
|
||||
busname[4] = '0' + i;
|
||||
pcms->idebus[i] = qdev_get_child_bus(DEVICE(dev), busname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (piix4_pm) {
|
||||
smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
|
||||
|
||||
|
|
@ -433,22 +381,7 @@ static void pc_set_south_bridge(Object *obj, int value, Error **errp)
|
|||
pcms->south_bridge = PCSouthBridgeOption_lookup.array[value];
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ISAPC
|
||||
static void pc_init_isa(MachineState *machine)
|
||||
{
|
||||
pc_init1(machine, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
static void pc_xen_hvm_init_pci(MachineState *machine)
|
||||
{
|
||||
const char *pci_type = xen_igd_gfx_pt_enabled() ?
|
||||
TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
|
||||
|
||||
pc_init1(machine, pci_type);
|
||||
}
|
||||
|
||||
static void pc_xen_hvm_init(MachineState *machine)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(machine);
|
||||
|
|
@ -458,7 +391,10 @@ static void pc_xen_hvm_init(MachineState *machine)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
pc_xen_hvm_init_pci(machine);
|
||||
pc_init1(machine, xen_igd_gfx_pt_enabled()
|
||||
? TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE
|
||||
: TYPE_I440FX_PCI_DEVICE);
|
||||
|
||||
xen_igd_reserve_slot(pcms->pcibus);
|
||||
pci_create_simple(pcms->pcibus, -1, "xen-platform");
|
||||
}
|
||||
|
|
@ -812,30 +748,6 @@ static void pc_i440fx_machine_2_6_options(MachineClass *m)
|
|||
|
||||
DEFINE_I440FX_MACHINE(2, 6);
|
||||
|
||||
#ifdef CONFIG_ISAPC
|
||||
static void isapc_machine_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
m->desc = "ISA-only PC";
|
||||
m->max_cpus = 1;
|
||||
m->option_rom_has_mr = true;
|
||||
m->rom_file_has_mr = false;
|
||||
pcmc->pci_enabled = false;
|
||||
pcmc->has_acpi_build = false;
|
||||
pcmc->smbios_defaults = false;
|
||||
pcmc->gigabyte_align = false;
|
||||
pcmc->smbios_legacy_mode = true;
|
||||
pcmc->has_reserved_memory = false;
|
||||
m->default_nic = "ne2k_isa";
|
||||
m->default_cpu_type = X86_CPU_TYPE_NAME("486");
|
||||
m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC);
|
||||
m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
|
||||
}
|
||||
|
||||
DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
|
||||
isapc_machine_options);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
static void xenfv_machine_4_2_options(MachineClass *m)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ static void qemu_s390_flic_notify(uint32_t type)
|
|||
CPU_FOREACH(cs) {
|
||||
S390CPU *cpu = S390_CPU(cs);
|
||||
|
||||
cs->interrupt_request |= CPU_INTERRUPT_HARD;
|
||||
cpu_set_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
|
||||
/* ignore CPUs that are not sleeping */
|
||||
if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING &&
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ static void openrisc_timer_cb(void *opaque)
|
|||
CPUState *cs = CPU(cpu);
|
||||
|
||||
cpu->env.ttmr |= TTMR_IP;
|
||||
cs->interrupt_request |= CPU_INTERRUPT_TIMER;
|
||||
cpu_set_interrupt(cs, CPU_INTERRUPT_TIMER);
|
||||
}
|
||||
|
||||
switch (cpu->env.ttmr & TTMR_M) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include "hw/timer/i8254.h"
|
||||
#include "system/address-spaces.h"
|
||||
#include "qom/object.h"
|
||||
#include "qemu/lockable.h"
|
||||
#include "qemu/seqlock.h"
|
||||
#include "trace.h"
|
||||
|
||||
struct hpet_fw_config hpet_fw_cfg = {.count = UINT8_MAX};
|
||||
|
|
@ -69,9 +71,11 @@ struct HPETState {
|
|||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
QemuMutex lock;
|
||||
MemoryRegion iomem;
|
||||
uint64_t hpet_offset;
|
||||
bool hpet_offset_saved;
|
||||
QemuSeqLock state_version;
|
||||
qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
|
||||
uint32_t flags;
|
||||
uint8_t rtc_irq_level;
|
||||
|
|
@ -428,6 +432,25 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
|
|||
trace_hpet_ram_read(addr);
|
||||
addr &= ~4;
|
||||
|
||||
if (addr == HPET_COUNTER) {
|
||||
unsigned version;
|
||||
|
||||
/*
|
||||
* Write update is rare, so busywait here is unlikely to happen
|
||||
*/
|
||||
do {
|
||||
version = seqlock_read_begin(&s->state_version);
|
||||
if (unlikely(!hpet_enabled(s))) {
|
||||
cur_tick = s->hpet_counter;
|
||||
} else {
|
||||
cur_tick = hpet_get_ticks(s);
|
||||
}
|
||||
} while (seqlock_read_retry(&s->state_version, version));
|
||||
trace_hpet_ram_read_reading_counter(addr & 4, cur_tick);
|
||||
return cur_tick >> shift;
|
||||
}
|
||||
|
||||
QEMU_LOCK_GUARD(&s->lock);
|
||||
/*address range of all global regs*/
|
||||
if (addr <= 0xff) {
|
||||
switch (addr) {
|
||||
|
|
@ -435,14 +458,6 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
|
|||
return s->capability >> shift;
|
||||
case HPET_CFG:
|
||||
return s->config >> shift;
|
||||
case HPET_COUNTER:
|
||||
if (hpet_enabled(s)) {
|
||||
cur_tick = hpet_get_ticks(s);
|
||||
} else {
|
||||
cur_tick = s->hpet_counter;
|
||||
}
|
||||
trace_hpet_ram_read_reading_counter(addr & 4, cur_tick);
|
||||
return cur_tick >> shift;
|
||||
case HPET_STATUS:
|
||||
return s->isr >> shift;
|
||||
default:
|
||||
|
|
@ -482,6 +497,7 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
|
|||
int len = MIN(size * 8, 64 - shift);
|
||||
uint64_t old_val, new_val, cleared;
|
||||
|
||||
QEMU_LOCK_GUARD(&s->lock);
|
||||
trace_hpet_ram_write(addr, value);
|
||||
addr &= ~4;
|
||||
|
||||
|
|
@ -494,6 +510,7 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
|
|||
old_val = s->config;
|
||||
new_val = deposit64(old_val, shift, len, value);
|
||||
new_val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK);
|
||||
seqlock_write_begin(&s->state_version);
|
||||
s->config = new_val;
|
||||
if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
|
||||
/* Enable main counter and interrupt generation. */
|
||||
|
|
@ -512,6 +529,8 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
|
|||
hpet_del_timer(&s->timer[i]);
|
||||
}
|
||||
}
|
||||
seqlock_write_end(&s->state_version);
|
||||
|
||||
/* i8254 and RTC output pins are disabled
|
||||
* when HPET is in legacy mode */
|
||||
if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
|
||||
|
|
@ -679,8 +698,11 @@ static void hpet_init(Object *obj)
|
|||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
HPETState *s = HPET(obj);
|
||||
|
||||
qemu_mutex_init(&s->lock);
|
||||
seqlock_init(&s->state_version);
|
||||
/* HPET Area */
|
||||
memory_region_init_io(&s->iomem, obj, &hpet_ram_ops, s, "hpet", HPET_LEN);
|
||||
memory_region_enable_lockless_io(&s->iomem);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -423,6 +423,7 @@ struct qemu_work_item;
|
|||
* @created: Indicates whether the CPU thread has been successfully created.
|
||||
* @halt_cond: condition variable sleeping threads can wait on.
|
||||
* @interrupt_request: Indicates a pending interrupt request.
|
||||
* Only used by system emulation.
|
||||
* @halted: Nonzero if the CPU is in suspended state.
|
||||
* @stop: Indicates a pending stop request.
|
||||
* @stopped: Indicates the CPU has been artificially stopped.
|
||||
|
|
@ -942,6 +943,28 @@ CPUState *cpu_by_arch_id(int64_t id);
|
|||
|
||||
void cpu_interrupt(CPUState *cpu, int mask);
|
||||
|
||||
/**
|
||||
* cpu_test_interrupt:
|
||||
* @cpu: The CPU to check interrupt(s) on.
|
||||
* @mask: The interrupts to check.
|
||||
*
|
||||
* Checks if any of interrupts in @mask are pending on @cpu.
|
||||
*/
|
||||
static inline bool cpu_test_interrupt(CPUState *cpu, int mask)
|
||||
{
|
||||
return qatomic_load_acquire(&cpu->interrupt_request) & mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_set_interrupt:
|
||||
* @cpu: The CPU to set pending interrupt(s) on.
|
||||
* @mask: The interrupts to set.
|
||||
*
|
||||
* Sets interrupts in @mask as pending on @cpu. Unlike @cpu_interrupt,
|
||||
* this does not kick the vCPU.
|
||||
*/
|
||||
void cpu_set_interrupt(CPUState *cpu, int mask);
|
||||
|
||||
/**
|
||||
* cpu_set_pc:
|
||||
* @cpu: The CPU to set the program counter for.
|
||||
|
|
|
|||
|
|
@ -833,6 +833,7 @@ struct MemoryRegion {
|
|||
bool nonvolatile;
|
||||
bool rom_device;
|
||||
bool flush_coalesced_mmio;
|
||||
bool lockless_io;
|
||||
bool unmergeable;
|
||||
uint8_t dirty_log_mask;
|
||||
bool is_iommu;
|
||||
|
|
@ -2341,6 +2342,17 @@ void memory_region_set_flush_coalesced(MemoryRegion *mr);
|
|||
*/
|
||||
void memory_region_clear_flush_coalesced(MemoryRegion *mr);
|
||||
|
||||
/**
|
||||
* memory_region_enable_lockless_io: Enable lockless (BQL free) acceess.
|
||||
*
|
||||
* Enable BQL-free access for devices that are well prepared to handle
|
||||
* locking during I/O themselves: either by doing fine grained locking or
|
||||
* by providing lock-free I/O schemes.
|
||||
*
|
||||
* @mr: the memory region to be updated.
|
||||
*/
|
||||
void memory_region_enable_lockless_io(MemoryRegion *mr);
|
||||
|
||||
/**
|
||||
* memory_region_add_eventfd: Request an eventfd to be triggered when a word
|
||||
* is written to a location.
|
||||
|
|
|
|||
|
|
@ -254,9 +254,16 @@ int64_t cpus_get_elapsed_ticks(void)
|
|||
return cpu_get_ticks();
|
||||
}
|
||||
|
||||
void cpu_set_interrupt(CPUState *cpu, int mask)
|
||||
{
|
||||
/* Pairs with cpu_test_interrupt(). */
|
||||
qatomic_store_release(&cpu->interrupt_request,
|
||||
cpu->interrupt_request | mask);
|
||||
}
|
||||
|
||||
void generic_handle_interrupt(CPUState *cpu, int mask)
|
||||
{
|
||||
cpu->interrupt_request |= mask;
|
||||
cpu_set_interrupt(cpu, mask);
|
||||
|
||||
if (!qemu_cpu_is_self(cpu)) {
|
||||
qemu_cpu_kick(cpu);
|
||||
|
|
|
|||
|
|
@ -2546,6 +2546,21 @@ void memory_region_clear_flush_coalesced(MemoryRegion *mr)
|
|||
}
|
||||
}
|
||||
|
||||
void memory_region_enable_lockless_io(MemoryRegion *mr)
|
||||
{
|
||||
mr->lockless_io = true;
|
||||
/*
|
||||
* reentrancy_guard has per device scope, that when enabled
|
||||
* will effectively prevent concurrent access to device's IO
|
||||
* MemoryRegion(s) by not calling accessor callback.
|
||||
*
|
||||
* Turn it off for lock-less IO enabled devices, to allow
|
||||
* concurrent IO.
|
||||
* TODO: remove this when reentrancy_guard becomes per transaction.
|
||||
*/
|
||||
mr->disable_reentrancy_guard = true;
|
||||
}
|
||||
|
||||
void memory_region_add_eventfd(MemoryRegion *mr,
|
||||
hwaddr addr,
|
||||
unsigned size,
|
||||
|
|
|
|||
|
|
@ -2900,7 +2900,7 @@ bool prepare_mmio_access(MemoryRegion *mr)
|
|||
{
|
||||
bool release_lock = false;
|
||||
|
||||
if (!bql_locked()) {
|
||||
if (!bql_locked() && !mr->lockless_io) {
|
||||
bql_lock();
|
||||
release_lock = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,10 +86,10 @@ static bool alpha_cpu_has_work(CPUState *cs)
|
|||
assume that if a CPU really wants to stay asleep, it will mask
|
||||
interrupts at the chipset level, which will prevent these bits
|
||||
from being set in the first place. */
|
||||
return cs->interrupt_request & (CPU_INTERRUPT_HARD
|
||||
| CPU_INTERRUPT_TIMER
|
||||
| CPU_INTERRUPT_SMP
|
||||
| CPU_INTERRUPT_MCHK);
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD
|
||||
| CPU_INTERRUPT_TIMER
|
||||
| CPU_INTERRUPT_SMP
|
||||
| CPU_INTERRUPT_MCHK);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
|
|
|||
|
|
@ -142,11 +142,11 @@ static bool arm_cpu_has_work(CPUState *cs)
|
|||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
|
||||
return (cpu->power_state != PSCI_OFF)
|
||||
&& cs->interrupt_request &
|
||||
(CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
|
||||
| CPU_INTERRUPT_NMI | CPU_INTERRUPT_VINMI | CPU_INTERRUPT_VFNMI
|
||||
| CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR
|
||||
| CPU_INTERRUPT_EXITTB);
|
||||
&& cpu_test_interrupt(cs,
|
||||
CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
|
||||
| CPU_INTERRUPT_NMI | CPU_INTERRUPT_VINMI | CPU_INTERRUPT_VFNMI
|
||||
| CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR
|
||||
| CPU_INTERRUPT_EXITTB);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
|
@ -964,7 +964,7 @@ void arm_cpu_update_virq(ARMCPU *cpu)
|
|||
!(arm_hcrx_el2_eff(env) & HCRX_VINMI)) ||
|
||||
(env->irq_line_state & CPU_INTERRUPT_VIRQ);
|
||||
|
||||
if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VIRQ) != 0)) {
|
||||
if (new_state != cpu_test_interrupt(cs, CPU_INTERRUPT_VIRQ)) {
|
||||
if (new_state) {
|
||||
cpu_interrupt(cs, CPU_INTERRUPT_VIRQ);
|
||||
} else {
|
||||
|
|
@ -986,7 +986,7 @@ void arm_cpu_update_vfiq(ARMCPU *cpu)
|
|||
!(arm_hcrx_el2_eff(env) & HCRX_VFNMI)) ||
|
||||
(env->irq_line_state & CPU_INTERRUPT_VFIQ);
|
||||
|
||||
if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VFIQ) != 0)) {
|
||||
if (new_state != cpu_test_interrupt(cs, CPU_INTERRUPT_VFIQ)) {
|
||||
if (new_state) {
|
||||
cpu_interrupt(cs, CPU_INTERRUPT_VFIQ);
|
||||
} else {
|
||||
|
|
@ -1008,7 +1008,7 @@ void arm_cpu_update_vinmi(ARMCPU *cpu)
|
|||
(arm_hcrx_el2_eff(env) & HCRX_VINMI)) ||
|
||||
(env->irq_line_state & CPU_INTERRUPT_VINMI);
|
||||
|
||||
if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VINMI) != 0)) {
|
||||
if (new_state != cpu_test_interrupt(cs, CPU_INTERRUPT_VINMI)) {
|
||||
if (new_state) {
|
||||
cpu_interrupt(cs, CPU_INTERRUPT_VINMI);
|
||||
} else {
|
||||
|
|
@ -1028,7 +1028,7 @@ void arm_cpu_update_vfnmi(ARMCPU *cpu)
|
|||
bool new_state = (arm_hcr_el2_eff(env) & HCR_VF) &&
|
||||
(arm_hcrx_el2_eff(env) & HCRX_VFNMI);
|
||||
|
||||
if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VFNMI) != 0)) {
|
||||
if (new_state != cpu_test_interrupt(cs, CPU_INTERRUPT_VFNMI)) {
|
||||
if (new_state) {
|
||||
cpu_interrupt(cs, CPU_INTERRUPT_VFNMI);
|
||||
} else {
|
||||
|
|
@ -1047,7 +1047,7 @@ void arm_cpu_update_vserr(ARMCPU *cpu)
|
|||
|
||||
bool new_state = env->cp15.hcr_el2 & HCR_VSE;
|
||||
|
||||
if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VSERR) != 0)) {
|
||||
if (new_state != cpu_test_interrupt(cs, CPU_INTERRUPT_VSERR)) {
|
||||
if (new_state) {
|
||||
cpu_interrupt(cs, CPU_INTERRUPT_VSERR);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -839,40 +839,40 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
|||
uint64_t ret = 0;
|
||||
|
||||
if (hcr_el2 & HCR_IMO) {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_VIRQ)) {
|
||||
ret |= CPSR_I;
|
||||
}
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_VINMI) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_VINMI)) {
|
||||
ret |= ISR_IS;
|
||||
ret |= CPSR_I;
|
||||
}
|
||||
} else {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_HARD)) {
|
||||
ret |= CPSR_I;
|
||||
}
|
||||
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_NMI) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_NMI)) {
|
||||
ret |= ISR_IS;
|
||||
ret |= CPSR_I;
|
||||
}
|
||||
}
|
||||
|
||||
if (hcr_el2 & HCR_FMO) {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_VFIQ)) {
|
||||
ret |= CPSR_F;
|
||||
}
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_VFNMI) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_VFNMI)) {
|
||||
ret |= ISR_FS;
|
||||
ret |= CPSR_F;
|
||||
}
|
||||
} else {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_FIQ) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_FIQ)) {
|
||||
ret |= CPSR_F;
|
||||
}
|
||||
}
|
||||
|
||||
if (hcr_el2 & HCR_AMO) {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_VSERR) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_VSERR)) {
|
||||
ret |= CPSR_A;
|
||||
}
|
||||
}
|
||||
|
|
@ -9301,7 +9301,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
|
|||
arm_call_el_change_hook(cpu);
|
||||
|
||||
if (!kvm_enabled()) {
|
||||
cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
|
||||
cpu_set_interrupt(cs, CPU_INTERRUPT_EXITTB);
|
||||
}
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
|
|
|||
|
|
@ -1782,13 +1782,13 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
|
|||
|
||||
static int hvf_inject_interrupts(CPUState *cpu)
|
||||
{
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_FIQ) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_FIQ)) {
|
||||
trace_hvf_inject_fiq();
|
||||
hv_vcpu_set_pending_interrupt(cpu->accel->fd, HV_INTERRUPT_TYPE_FIQ,
|
||||
true);
|
||||
}
|
||||
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD)) {
|
||||
trace_hvf_inject_irq();
|
||||
hv_vcpu_set_pending_interrupt(cpu->accel->fd, HV_INTERRUPT_TYPE_IRQ,
|
||||
true);
|
||||
|
|
@ -1840,7 +1840,7 @@ static void hvf_wfi(CPUState *cpu)
|
|||
uint64_t nanos;
|
||||
uint32_t cntfrq;
|
||||
|
||||
if (cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIQ)) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIQ)) {
|
||||
/* Interrupt pending, no need to wait */
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ static vaddr avr_cpu_get_pc(CPUState *cs)
|
|||
|
||||
static bool avr_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return (cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_RESET))
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD | CPU_INTERRUPT_RESET)
|
||||
&& cpu_interrupts_enabled(cpu_env(cs));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ static void hppa_restore_state_to_opc(CPUState *cs,
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
static bool hppa_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
|
|
|||
|
|
@ -773,9 +773,9 @@ int hvf_vcpu_exec(CPUState *cpu)
|
|||
switch (exit_reason) {
|
||||
case EXIT_REASON_HLT: {
|
||||
macvm_set_rip(cpu, rip + ins_len);
|
||||
if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if (!(cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
|
||||
(env->eflags & IF_MASK))
|
||||
&& !(cpu->interrupt_request & CPU_INTERRUPT_NMI) &&
|
||||
&& !cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI) &&
|
||||
!(idtvec_info & VMCS_IDT_VEC_VALID)) {
|
||||
cpu->halted = 1;
|
||||
ret = EXCP_HLT;
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ bool hvf_inject_interrupts(CPUState *cs)
|
|||
};
|
||||
}
|
||||
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_NMI) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_NMI)) {
|
||||
if (!(env->hflags2 & HF2_NMI_MASK) && !(info & VMCS_INTR_VALID)) {
|
||||
cs->interrupt_request &= ~CPU_INTERRUPT_NMI;
|
||||
info = VMCS_INTR_VALID | VMCS_INTR_T_NMI | EXCP02_NMI;
|
||||
|
|
@ -406,7 +406,7 @@ bool hvf_inject_interrupts(CPUState *cs)
|
|||
}
|
||||
|
||||
if (!(env->hflags & HF_INHIBIT_IRQ_MASK) &&
|
||||
(cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
(env->eflags & IF_MASK) && !(info & VMCS_INTR_VALID)) {
|
||||
int line = cpu_get_pic_interrupt(env);
|
||||
cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
||||
|
|
@ -415,11 +415,10 @@ bool hvf_inject_interrupts(CPUState *cs)
|
|||
VMCS_INTR_VALID | VMCS_INTR_T_HWINTR);
|
||||
}
|
||||
}
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_HARD)) {
|
||||
vmx_set_int_window_exiting(cs);
|
||||
}
|
||||
return (cs->interrupt_request
|
||||
& (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR));
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR);
|
||||
}
|
||||
|
||||
int hvf_process_events(CPUState *cs)
|
||||
|
|
@ -432,25 +431,25 @@ int hvf_process_events(CPUState *cs)
|
|||
env->eflags = rreg(cs->accel->fd, HV_X86_RFLAGS);
|
||||
}
|
||||
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_INIT) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_INIT)) {
|
||||
cpu_synchronize_state(cs);
|
||||
do_cpu_init(cpu);
|
||||
}
|
||||
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_POLL) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_POLL)) {
|
||||
cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
|
||||
apic_poll_irq(cpu->apic_state);
|
||||
}
|
||||
if (((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if ((cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
(env->eflags & IF_MASK)) ||
|
||||
(cs->interrupt_request & CPU_INTERRUPT_NMI)) {
|
||||
cpu_test_interrupt(cs, CPU_INTERRUPT_NMI)) {
|
||||
cs->halted = 0;
|
||||
}
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_SIPI) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_SIPI)) {
|
||||
cpu_synchronize_state(cs);
|
||||
do_cpu_sipi(cpu);
|
||||
}
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_TPR) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_TPR)) {
|
||||
cs->interrupt_request &= ~CPU_INTERRUPT_TPR;
|
||||
cpu_synchronize_state(cs);
|
||||
apic_handle_tpr_access_report(cpu->apic_state, env->eip,
|
||||
|
|
|
|||
|
|
@ -5453,8 +5453,8 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
|
|||
int ret;
|
||||
|
||||
/* Inject NMI */
|
||||
if (cpu->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
|
||||
bql_lock();
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
|
||||
bql_unlock();
|
||||
|
|
@ -5465,7 +5465,7 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
|
|||
strerror(-ret));
|
||||
}
|
||||
}
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_SMI) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_SMI)) {
|
||||
bql_lock();
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
|
||||
bql_unlock();
|
||||
|
|
@ -5478,31 +5478,30 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
|
|||
}
|
||||
}
|
||||
|
||||
if (!kvm_pic_in_kernel()) {
|
||||
bql_lock();
|
||||
}
|
||||
|
||||
/* Force the VCPU out of its inner loop to process any INIT requests
|
||||
* or (for userspace APIC, but it is cheap to combine the checks here)
|
||||
* pending TPR access reports.
|
||||
*/
|
||||
if (cpu->interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
|
||||
if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) &&
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT) &&
|
||||
!(env->hflags & HF_SMM_MASK)) {
|
||||
cpu->exit_request = 1;
|
||||
qatomic_set(&cpu->exit_request, 1);
|
||||
}
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_TPR) {
|
||||
cpu->exit_request = 1;
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_TPR)) {
|
||||
qatomic_set(&cpu->exit_request, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!kvm_pic_in_kernel()) {
|
||||
/* Try to inject an interrupt if the guest can accept it */
|
||||
if (run->ready_for_interrupt_injection &&
|
||||
(cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
|
||||
(env->eflags & IF_MASK)) {
|
||||
int irq;
|
||||
|
||||
bql_lock();
|
||||
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
||||
irq = cpu_get_pic_interrupt(env);
|
||||
if (irq >= 0) {
|
||||
|
|
@ -5517,13 +5516,14 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
|
|||
strerror(-ret));
|
||||
}
|
||||
}
|
||||
bql_unlock();
|
||||
}
|
||||
|
||||
/* If we have an interrupt but the guest is not ready to receive an
|
||||
* interrupt, request an interrupt window exit. This will
|
||||
* cause a return to userspace as soon as the guest is ready to
|
||||
* receive interrupts. */
|
||||
if ((cpu->interrupt_request & CPU_INTERRUPT_HARD)) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD)) {
|
||||
run->request_interrupt_window = 1;
|
||||
} else {
|
||||
run->request_interrupt_window = 0;
|
||||
|
|
@ -5531,8 +5531,6 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
|
|||
|
||||
DPRINTF("setting tpr\n");
|
||||
run->cr8 = cpu_get_apic_tpr(x86_cpu->apic_state);
|
||||
|
||||
bql_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5595,7 +5593,7 @@ int kvm_arch_process_async_events(CPUState *cs)
|
|||
X86CPU *cpu = X86_CPU(cs);
|
||||
CPUX86State *env = &cpu->env;
|
||||
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_MCE) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_MCE)) {
|
||||
/* We must not raise CPU_INTERRUPT_MCE if it's not supported. */
|
||||
assert(env->mcg_cap);
|
||||
|
||||
|
|
@ -5618,7 +5616,7 @@ int kvm_arch_process_async_events(CPUState *cs)
|
|||
}
|
||||
}
|
||||
|
||||
if ((cs->interrupt_request & CPU_INTERRUPT_INIT) &&
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_INIT) &&
|
||||
!(env->hflags & HF_SMM_MASK)) {
|
||||
kvm_cpu_synchronize_state(cs);
|
||||
do_cpu_init(cpu);
|
||||
|
|
@ -5628,20 +5626,20 @@ int kvm_arch_process_async_events(CPUState *cs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_POLL) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_POLL)) {
|
||||
cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
|
||||
apic_poll_irq(cpu->apic_state);
|
||||
}
|
||||
if (((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if ((cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
(env->eflags & IF_MASK)) ||
|
||||
(cs->interrupt_request & CPU_INTERRUPT_NMI)) {
|
||||
cpu_test_interrupt(cs, CPU_INTERRUPT_NMI)) {
|
||||
cs->halted = 0;
|
||||
}
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_SIPI) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_SIPI)) {
|
||||
kvm_cpu_synchronize_state(cs);
|
||||
do_cpu_sipi(cpu);
|
||||
}
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_TPR) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_TPR)) {
|
||||
cs->interrupt_request &= ~CPU_INTERRUPT_TPR;
|
||||
kvm_cpu_synchronize_state(cs);
|
||||
apic_handle_tpr_access_report(cpu->apic_state, env->eip,
|
||||
|
|
@ -5656,9 +5654,9 @@ static int kvm_handle_halt(X86CPU *cpu)
|
|||
CPUState *cs = CPU(cpu);
|
||||
CPUX86State *env = &cpu->env;
|
||||
|
||||
if (!((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if (!(cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
(env->eflags & IF_MASK)) &&
|
||||
!(cs->interrupt_request & CPU_INTERRUPT_NMI)) {
|
||||
!cpu_test_interrupt(cs, CPU_INTERRUPT_NMI)) {
|
||||
cs->halted = 1;
|
||||
return EXCP_HLT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -413,11 +413,11 @@ nvmm_vcpu_pre_run(CPUState *cpu)
|
|||
* Force the VCPU out of its inner loop to process any INIT requests
|
||||
* or commit pending TPR access.
|
||||
*/
|
||||
if (cpu->interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
|
||||
cpu->exit_request = 1;
|
||||
}
|
||||
|
||||
if (!has_event && (cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
|
||||
if (!has_event && cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
|
||||
if (nvmm_can_take_nmi(cpu)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
|
||||
event->type = NVMM_VCPU_EVENT_INTR;
|
||||
|
|
@ -426,7 +426,7 @@ nvmm_vcpu_pre_run(CPUState *cpu)
|
|||
}
|
||||
}
|
||||
|
||||
if (!has_event && (cpu->interrupt_request & CPU_INTERRUPT_HARD)) {
|
||||
if (!has_event && cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD)) {
|
||||
if (nvmm_can_take_int(cpu)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
||||
event->type = NVMM_VCPU_EVENT_INTR;
|
||||
|
|
@ -436,7 +436,7 @@ nvmm_vcpu_pre_run(CPUState *cpu)
|
|||
}
|
||||
|
||||
/* Don't want SMIs. */
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_SMI) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_SMI)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
|
||||
}
|
||||
|
||||
|
|
@ -651,9 +651,9 @@ nvmm_handle_halted(struct nvmm_machine *mach, CPUState *cpu,
|
|||
|
||||
bql_lock();
|
||||
|
||||
if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if (!(cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
|
||||
(cpu_env(cpu)->eflags & IF_MASK)) &&
|
||||
!(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
|
||||
!cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
|
||||
cpu->exception_index = EXCP_HLT;
|
||||
cpu->halted = true;
|
||||
ret = 1;
|
||||
|
|
@ -691,25 +691,25 @@ nvmm_vcpu_loop(CPUState *cpu)
|
|||
* Some asynchronous events must be handled outside of the inner
|
||||
* VCPU loop. They are handled here.
|
||||
*/
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_INIT) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT)) {
|
||||
nvmm_cpu_synchronize_state(cpu);
|
||||
do_cpu_init(x86_cpu);
|
||||
/* set int/nmi windows back to the reset state */
|
||||
}
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_POLL)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
|
||||
apic_poll_irq(x86_cpu->apic_state);
|
||||
}
|
||||
if (((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if ((cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
|
||||
(env->eflags & IF_MASK)) ||
|
||||
(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
|
||||
cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
|
||||
cpu->halted = false;
|
||||
}
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_SIPI)) {
|
||||
nvmm_cpu_synchronize_state(cpu);
|
||||
do_cpu_sipi(x86_cpu);
|
||||
}
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_TPR) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_TPR)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_TPR;
|
||||
nvmm_cpu_synchronize_state(cpu);
|
||||
apic_handle_tpr_access_report(x86_cpu->apic_state, env->eip,
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ bool x86_cpu_exec_halt(CPUState *cpu)
|
|||
X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
CPUX86State *env = &x86_cpu->env;
|
||||
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_POLL)) {
|
||||
bql_lock();
|
||||
apic_poll_irq(x86_cpu->apic_state);
|
||||
cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
|
|||
env->hflags2 |= HF2_GIF_MASK;
|
||||
|
||||
if (ctl_has_irq(env)) {
|
||||
cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
|
||||
cpu_set_interrupt(cs, CPU_INTERRUPT_VIRQ);
|
||||
}
|
||||
|
||||
if (virtual_gif_set(env)) {
|
||||
|
|
|
|||
|
|
@ -1436,9 +1436,9 @@ static int whpx_handle_halt(CPUState *cpu)
|
|||
int ret = 0;
|
||||
|
||||
bql_lock();
|
||||
if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if (!(cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
|
||||
(cpu_env(cpu)->eflags & IF_MASK)) &&
|
||||
!(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
|
||||
!cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
|
||||
cpu->exception_index = EXCP_HLT;
|
||||
cpu->halted = true;
|
||||
ret = 1;
|
||||
|
|
@ -1469,15 +1469,15 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
|
|||
|
||||
/* Inject NMI */
|
||||
if (!vcpu->interruption_pending &&
|
||||
cpu->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
|
||||
cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
|
||||
vcpu->interruptable = false;
|
||||
new_int.InterruptionType = WHvX64PendingNmi;
|
||||
new_int.InterruptionPending = 1;
|
||||
new_int.InterruptionVector = 2;
|
||||
}
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_SMI) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_SMI)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
|
||||
}
|
||||
}
|
||||
|
|
@ -1486,12 +1486,12 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
|
|||
* Force the VCPU out of its inner loop to process any INIT requests or
|
||||
* commit pending TPR access.
|
||||
*/
|
||||
if (cpu->interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
|
||||
if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) &&
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT) &&
|
||||
!(env->hflags & HF_SMM_MASK)) {
|
||||
cpu->exit_request = 1;
|
||||
}
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_TPR) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_TPR)) {
|
||||
cpu->exit_request = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1501,7 +1501,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
|
|||
if (!vcpu->interruption_pending &&
|
||||
vcpu->interruptable && (env->eflags & IF_MASK)) {
|
||||
assert(!new_int.InterruptionPending);
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
||||
irq = cpu_get_pic_interrupt(env);
|
||||
if (irq >= 0) {
|
||||
|
|
@ -1519,7 +1519,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
|
|||
reg_count += 1;
|
||||
}
|
||||
} else if (vcpu->ready_for_pic_interrupt &&
|
||||
(cpu->interrupt_request & CPU_INTERRUPT_HARD)) {
|
||||
cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
||||
irq = cpu_get_pic_interrupt(env);
|
||||
if (irq >= 0) {
|
||||
|
|
@ -1546,7 +1546,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
|
|||
|
||||
/* Update the state of the interrupt delivery notification */
|
||||
if (!vcpu->window_registered &&
|
||||
cpu->interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD)) {
|
||||
reg_values[reg_count].DeliverabilityNotifications =
|
||||
(WHV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER) {
|
||||
.InterruptNotification = 1
|
||||
|
|
@ -1599,30 +1599,30 @@ static void whpx_vcpu_process_async_events(CPUState *cpu)
|
|||
CPUX86State *env = &x86_cpu->env;
|
||||
AccelCPUState *vcpu = cpu->accel;
|
||||
|
||||
if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) &&
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT) &&
|
||||
!(env->hflags & HF_SMM_MASK)) {
|
||||
whpx_cpu_synchronize_state(cpu);
|
||||
do_cpu_init(x86_cpu);
|
||||
vcpu->interruptable = true;
|
||||
}
|
||||
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_POLL)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
|
||||
apic_poll_irq(x86_cpu->apic_state);
|
||||
}
|
||||
|
||||
if (((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if ((cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
|
||||
(env->eflags & IF_MASK)) ||
|
||||
(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
|
||||
cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
|
||||
cpu->halted = false;
|
||||
}
|
||||
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_SIPI)) {
|
||||
whpx_cpu_synchronize_state(cpu);
|
||||
do_cpu_sipi(x86_cpu);
|
||||
}
|
||||
|
||||
if (cpu->interrupt_request & CPU_INTERRUPT_TPR) {
|
||||
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_TPR)) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_TPR;
|
||||
whpx_cpu_synchronize_state(cpu);
|
||||
apic_handle_tpr_access_report(x86_cpu->apic_state, env->eip,
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ static bool loongarch_cpu_has_work(CPUState *cs)
|
|||
{
|
||||
bool has_work = false;
|
||||
|
||||
if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
cpu_loongarch_hw_interrupts_pending(cpu_env(cs))) {
|
||||
has_work = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ static void m68k_restore_state_to_opc(CPUState *cs,
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
static bool m68k_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ static void mb_restore_state_to_opc(CPUState *cs,
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
static bool mb_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ static bool mips_cpu_has_work(CPUState *cs)
|
|||
* check for interrupts that can be taken. For pre-release 6 CPUs,
|
||||
* check for CP0 Config7 'Wait IE ignore' bit.
|
||||
*/
|
||||
if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
cpu_mips_hw_interrupts_pending(env)) {
|
||||
if (cpu_mips_hw_interrupts_enabled(env) ||
|
||||
(env->CP0_Config7 & (1 << CP0C7_WII)) ||
|
||||
|
|
@ -160,7 +160,7 @@ static bool mips_cpu_has_work(CPUState *cs)
|
|||
* The QEMU model will issue an _WAKE request whenever the CPUs
|
||||
* should be woken up.
|
||||
*/
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_WAKE) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_WAKE)) {
|
||||
has_work = true;
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ static bool mips_cpu_has_work(CPUState *cs)
|
|||
}
|
||||
/* MIPS Release 6 has the ability to halt the CPU. */
|
||||
if (env->CP0_Config5 & (1 << CP0C5_VP)) {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_WAKE) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_WAKE)) {
|
||||
has_work = true;
|
||||
}
|
||||
if (!mips_vp_active(env)) {
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
|
|||
|
||||
bql_lock();
|
||||
|
||||
if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
cpu_mips_io_interrupts_pending(cpu)) {
|
||||
intr.cpu = -1;
|
||||
intr.irq = 2;
|
||||
|
|
|
|||
|
|
@ -78,8 +78,7 @@ static void openrisc_restore_state_to_opc(CPUState *cs,
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
static bool openrisc_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return cs->interrupt_request & (CPU_INTERRUPT_HARD |
|
||||
CPU_INTERRUPT_TIMER);
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
|
|
|||
|
|
@ -7225,7 +7225,7 @@ static int ppc_cpu_mmu_index(CPUState *cs, bool ifetch)
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
static bool ppc_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
|
|
|||
|
|
@ -1354,7 +1354,7 @@ static int kvmppc_handle_halt(PowerPCCPU *cpu)
|
|||
CPUState *cs = CPU(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
if (!(cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
if (!cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
FIELD_EX64(env->msr, MSR, EE)) {
|
||||
cs->halted = 1;
|
||||
cs->exception_index = EXCP_HLT;
|
||||
|
|
|
|||
|
|
@ -75,8 +75,7 @@ static void rx_restore_state_to_opc(CPUState *cs,
|
|||
|
||||
static bool rx_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return cs->interrupt_request &
|
||||
(CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR);
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR);
|
||||
}
|
||||
|
||||
static int rx_cpu_mmu_index(CPUState *cs, bool ifunc)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte)
|
|||
void rx_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
CPURXState *env = cpu_env(cs);
|
||||
int do_irq = cs->interrupt_request & INT_FLAGS;
|
||||
int do_irq = cpu_test_interrupt(cs, INT_FLAGS);
|
||||
uint32_t save_psw;
|
||||
|
||||
env->in_sleep = 0;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ bool s390_cpu_has_work(CPUState *cs)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
|
||||
if (!cpu_test_interrupt(cs, CPU_INTERRUPT_HARD)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ static bool superh_io_recompile_replay_branch(CPUState *cs,
|
|||
|
||||
static bool superh_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr)
|
|||
void superh_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
CPUSH4State *env = cpu_env(cs);
|
||||
int do_irq = cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
int do_irq = cpu_test_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
int do_exp, irq_vector = cs->exception_index;
|
||||
|
||||
/* prioritize exceptions over interrupts */
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ static void sparc_restore_state_to_opc(CPUState *cs,
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
static bool sparc_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return (cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD) &&
|
||||
cpu_interrupts_enabled(cpu_env(cs));
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ void cpu_check_irqs(CPUSPARCState *env)
|
|||
* the next bit is (2 << psrpil).
|
||||
*/
|
||||
if (pil < (2 << env->psrpil)) {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
if (cpu_test_interrupt(cs, CPU_INTERRUPT_HARD)) {
|
||||
trace_sparc64_cpu_check_irqs_reset_irq(env->interrupt_index);
|
||||
env->interrupt_index = 0;
|
||||
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
|
|
@ -120,7 +120,7 @@ void cpu_check_irqs(CPUSPARCState *env)
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
} else if (cpu_test_interrupt(cs, CPU_INTERRUPT_HARD)) {
|
||||
trace_sparc64_cpu_check_irqs_disabled(pil, env->pil_in, env->softint,
|
||||
env->interrupt_index);
|
||||
env->interrupt_index = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue