@@ -50,6 +50,7 @@
#include "qom/cpu.h"
#include "hw/nvram/fw_cfg.h"
#include "qemu/cutils.h"
+#include "trace.h"
/*****************************************************************************/
/* ICH9 LPC PCI to ISA bridge */
@@ -423,6 +424,29 @@ void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled)
/* APM */
+static void ich9_apm_broadcast_smi(void)
+{
+ CPUState *cs;
+
+ pause_all_vcpus();
+ cpu_synchronize_all_states();
+ CPU_FOREACH(cs) {
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ if (env->smbase == 0x30000 && env->eip == 0xfff0) {
+ CPUClass *k = CPU_GET_CLASS(cs);
+ uint64_t cpu_arch_id = k->get_arch_id(cs);
+
+ trace_ich9_apm_broadcast_smi_skip(cpu_arch_id);
+ continue;
+ }
+
+ cpu_interrupt(cs, CPU_INTERRUPT_SMI);
+ }
+ resume_all_vcpus();
+}
+
static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
{
ICH9LPCState *lpc = arg;
@@ -439,10 +463,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
if (lpc->smi_negotiated_features &
(UINT64_C(1) << ICH9_LPC_SMI_F_BROADCAST_BIT)) {
- CPUState *cs;
- CPU_FOREACH(cs) {
- cpu_interrupt(cs, CPU_INTERRUPT_SMI);
- }
+ ich9_apm_broadcast_smi();
} else {
cpu_interrupt(current_cpu, CPU_INTERRUPT_SMI);
}
@@ -7,3 +7,6 @@ pc87312_info_floppy(uint32_t base) "base 0x%x"
pc87312_info_ide(uint32_t base) "base 0x%x"
pc87312_info_parallel(uint32_t base, uint32_t irq) "base 0x%x, irq %u"
pc87312_info_serial(int n, uint32_t base, uint32_t irq) "id=%d, base 0x%x, irq %u"
+
+# hw/isa/lpc_ich9.c
+ich9_apm_broadcast_smi_skip(uint64_t cpu_arch_id) "cpu_arch_id=0x%"PRIx64