From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40298) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YpvAM-0000Ml-EB for qemu-devel@nongnu.org; Wed, 06 May 2015 04:58:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YpvAI-0004jp-DA for qemu-devel@nongnu.org; Wed, 06 May 2015 04:58:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48300) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YpvAI-0004jd-6X for qemu-devel@nongnu.org; Wed, 06 May 2015 04:58:50 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id E2CE38EFC7 for ; Wed, 6 May 2015 08:58:48 +0000 (UTC) From: Gerd Hoffmann Date: Wed, 6 May 2015 10:58:30 +0200 Message-Id: <1430902710-13609-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH] ich9: implement SMI_LOCK List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, lersek@redhat.com, Gerd Hoffmann , "Michael S. Tsirkin" Signed-off-by: Gerd Hoffmann --- hw/acpi/ich9.c | 4 +++- hw/isa/lpc_ich9.c | 19 +++++++++++++++++++ include/hw/acpi/ich9.h | 1 + include/hw/i386/ich9.h | 6 ++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index eefd8b0..86deb2b 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -94,7 +94,8 @@ static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val, ICH9LPCPMRegs *pm = opaque; switch (addr) { case 0: - pm->smi_en = val; + pm->smi_en &= ~pm->smi_en_wmask; + pm->smi_en |= (val & pm->smi_en_wmask); break; } } @@ -198,6 +199,7 @@ static void pm_reset(void *opaque) * support SMM mode. */ pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN; } + pm->smi_en_wmask = ~0; acpi_update_sci(&pm->acpi_regs, pm->irq); } diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 3e30273..ac0e63e 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -410,12 +410,28 @@ static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old) } } +/* config:GEN_PMCON* */ +static void +ich9_lpc_pmcon_update(ICH9LPCState *lpc) +{ + uint16_t gen_pmcon_1 = pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_1); + uint16_t wmask; + + if (gen_pmcon_1 & ICH9_LPC_GEN_PMCON_1_SMI_LOCK) { + wmask = pci_get_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1); + wmask &= ~ICH9_LPC_GEN_PMCON_1_SMI_LOCK; + pci_set_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1, wmask); + lpc->pm.smi_en_wmask &= ~1; + } +} + static int ich9_lpc_post_load(void *opaque, int version_id) { ICH9LPCState *lpc = opaque; ich9_lpc_pmbase_update(lpc); ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RBCA_EN */); + ich9_lpc_pmcon_update(lpc); return 0; } @@ -438,6 +454,9 @@ static void ich9_lpc_config_write(PCIDevice *d, if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) { pci_bus_fire_intx_routing_notifier(lpc->d.bus); } + if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) { + ich9_lpc_pmcon_update(lpc); + } } static void ich9_lpc_reset(DeviceState *qdev) diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index f03f7c2..ac24bbe 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -39,6 +39,7 @@ typedef struct ICH9LPCPMRegs { MemoryRegion io_smi; uint32_t smi_en; + uint32_t smi_en_wmask; uint32_t smi_sts; qemu_irq irq; /* SCI */ diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index 874c131..0c973bb 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -154,6 +154,12 @@ Object *ich9_lpc_find(void); #define ICH9_LPC_PIRQ_ROUT_MASK Q35_MASK(8, 3, 0) #define ICH9_LPC_PIRQ_ROUT_DEFAULT 0x80 +#define ICH9_LPC_GEN_PMCON_1 0xa0 +#define ICH9_LPC_GEN_PMCON_1_SMI_LOCK (1 << 4) +#define ICH9_LPC_GEN_PMCON_2 0xa2 +#define ICH9_LPC_GEN_PMCON_3 0xa4 +#define ICH9_LPC_GEN_PMCON_LOCK 0xa6 + #define ICH9_LPC_RCBA 0xf0 #define ICH9_LPC_RCBA_BA_MASK Q35_MASK(32, 31, 14) #define ICH9_LPC_RCBA_EN 0x1 -- 1.8.3.1