From fe6567d5fddfb7501a352c5e080a9eecf7b89177 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 31 Mar 2015 14:10:22 +0200 Subject: hw/i386: add a separate region that tracks the SMRAME bit This region is exported at /machine/smram. It is "empty" if SMRAME=0 and points to SMRAM if SMRAME=1. The CPU will enable/disable it as it enters or exits SMRAM. While touching nearby code, the existing memory region setup was slightly inconsistent. The smram_region is *disabled* in order to open SMRAM (because the smram_region shows the low VRAM instead of the RAM at 0xa0000). Because SMRAM is closed at startup, the smram_region must be enabled when creating the i440fx or q35 devices. Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/hw/pci-host/q35.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/hw') diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 96d4cdc..4c9eacc 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -53,6 +53,7 @@ typedef struct MCHPCIState { MemoryRegion *address_space_io; PAMMemoryRegion pam_regions[13]; MemoryRegion smram_region; + MemoryRegion smram, low_smram; PcPciInfo pci_info; uint8_t smm_enabled; ram_addr_t below_4g_mem_size; -- cgit v1.1 From f809c605122df291bbb9004dc487bde0969134b5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 31 Mar 2015 14:12:25 +0200 Subject: target-i386: use memory API to implement SMRAM Remove cpu_smm_register and cpu_smm_update. Instead, each CPU address space gets an extra region which is an alias of /machine/smram. This extra region is enabled or disabled as the CPU enters/exits SMM. Signed-off-by: Paolo Bonzini --- include/hw/i386/pc.h | 1 - include/hw/pci-host/pam.h | 5 +---- include/hw/pci-host/q35.h | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'include/hw') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index bec6de1..86c5651 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -210,7 +210,6 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus); void pc_pci_device_init(PCIBus *pci_bus); typedef void (*cpu_set_smm_t)(int smm, void *arg); -void cpu_smm_register(cpu_set_smm_t callback, void *arg); void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name); diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h index 4d03e4b..80dd605 100644 --- a/include/hw/pci-host/pam.h +++ b/include/hw/pci-host/pam.h @@ -86,10 +86,7 @@ typedef struct PAMMemoryRegion { unsigned current; } PAMMemoryRegion; -void smram_update(MemoryRegion *smram_region, uint8_t smram, - uint8_t smm_enabled); -void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram, - MemoryRegion *smram_region); +void smram_update(MemoryRegion *smram_region, uint8_t smram); void init_pam(DeviceState *dev, MemoryRegion *ram, MemoryRegion *system, MemoryRegion *pci, PAMMemoryRegion *mem, uint32_t start, uint32_t size); void pam_update(PAMMemoryRegion *mem, int idx, uint8_t val); diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 4c9eacc..17adeaa 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -55,7 +55,6 @@ typedef struct MCHPCIState { MemoryRegion smram_region; MemoryRegion smram, low_smram; PcPciInfo pci_info; - uint8_t smm_enabled; ram_addr_t below_4g_mem_size; ram_addr_t above_4g_mem_size; uint64_t pci_hole64_size; -- cgit v1.1 From 3de70c0899db2712a5ae321093aa6173d6f76706 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 31 Mar 2015 14:14:28 +0200 Subject: hw/i386: remove smram_update It's easier to inline it now that most of its work is done by the CPU (rather than the chipset) through /machine/smram and the memory API. Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/hw/pci-host/pam.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/hw') diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h index 80dd605..6116c63 100644 --- a/include/hw/pci-host/pam.h +++ b/include/hw/pci-host/pam.h @@ -86,7 +86,6 @@ typedef struct PAMMemoryRegion { unsigned current; } PAMMemoryRegion; -void smram_update(MemoryRegion *smram_region, uint8_t smram); void init_pam(DeviceState *dev, MemoryRegion *ram, MemoryRegion *system, MemoryRegion *pci, PAMMemoryRegion *mem, uint32_t start, uint32_t size); void pam_update(PAMMemoryRegion *mem, int idx, uint8_t val); -- cgit v1.1 From 64130fa4a1514ae7a580b8d46290a11784770600 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 31 Mar 2015 17:13:01 +0200 Subject: q35: implement high SMRAM When H_SMRAME is 1, low memory at 0xa0000 is left alone by SMM, and instead the chipset maps the 0xa0000-0xbffff window at 0xfeda0000-0xfedbffff. This affects both the "non-SMM" view controlled by D_OPEN and the SMM view controlled by G_SMRAME, so add two new MemoryRegions and toggle the enabled/disabled state of all four in mch_update_smram. Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/hw/pci-host/q35.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'include/hw') diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 17adeaa..0fff6a2 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -52,8 +52,8 @@ typedef struct MCHPCIState { MemoryRegion *system_memory; MemoryRegion *address_space_io; PAMMemoryRegion pam_regions[13]; - MemoryRegion smram_region; - MemoryRegion smram, low_smram; + MemoryRegion smram_region, open_high_smram; + MemoryRegion smram, low_smram, high_smram; PcPciInfo pci_info; ram_addr_t below_4g_mem_size; ram_addr_t above_4g_mem_size; @@ -127,7 +127,7 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_PAM_MASK ((uint8_t)0x3) #define MCH_HOST_BRIDGE_SMRAM 0x9d -#define MCH_HOST_BRIDGE_SMRAM_SIZE 1 +#define MCH_HOST_BRIDGE_SMRAM_SIZE 2 #define MCH_HOST_BRIDGE_SMRAM_DEFAULT ((uint8_t)0x2) #define MCH_HOST_BRIDGE_SMRAM_D_OPEN ((uint8_t)(1 << 6)) #define MCH_HOST_BRIDGE_SMRAM_D_CLS ((uint8_t)(1 << 5)) @@ -141,11 +141,11 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END 0x100000 #define MCH_HOST_BRIDGE_ESMRAMC 0x9e -#define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 6)) -#define MCH_HOST_BRIDGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 5)) -#define MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 4)) -#define MCH_HOST_BRIDGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 3)) -#define MCH_HOST_BRIDGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 2)) +#define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 7)) +#define MCH_HOST_BRIDGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 6)) +#define MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 5)) +#define MCH_HOST_BRIDGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 4)) +#define MCH_HOST_BRIDGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 3)) #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK ((uint8_t)(0x3 << 1)) #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB ((uint8_t)(0x0 << 1)) #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1)) -- cgit v1.1 From 7744752402d11cebe4c1d4079dcd40d3145eb37b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 15 Apr 2015 16:43:24 +0200 Subject: q35: fix ESMRAMC default The cache bits in ESMRAMC are hardcoded to 1 (=disabled) according to the q35 mch specs. Add and use a define with this default. While being at it also update the SMRAM default to use the name (no code change, just makes things a bit more readable). Signed-off-by: Gerd Hoffmann Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/hw/pci-host/q35.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/hw') diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 0fff6a2..d3c7bbb 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -128,7 +128,6 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_SMRAM 0x9d #define MCH_HOST_BRIDGE_SMRAM_SIZE 2 -#define MCH_HOST_BRIDGE_SMRAM_DEFAULT ((uint8_t)0x2) #define MCH_HOST_BRIDGE_SMRAM_D_OPEN ((uint8_t)(1 << 6)) #define MCH_HOST_BRIDGE_SMRAM_D_CLS ((uint8_t)(1 << 5)) #define MCH_HOST_BRIDGE_SMRAM_D_LCK ((uint8_t)(1 << 4)) @@ -139,6 +138,8 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_SMRAM_C_END 0xc0000 #define MCH_HOST_BRIDGE_SMRAM_C_SIZE 0x20000 #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END 0x100000 +#define MCH_HOST_BRIDGE_SMRAM_DEFAULT \ + MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG #define MCH_HOST_BRIDGE_ESMRAMC 0x9e #define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 7)) @@ -151,6 +152,10 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1)) #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB ((uint8_t)(0x2 << 1)) #define MCH_HOST_BRIDGE_ESMRAMC_T_EN ((uint8_t)1) +#define MCH_HOST_BRIDGE_ESMRAMC_DEFAULT \ + (MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE | \ + MCH_HOST_BRIDGE_ESMRAMC_SM_L1 | \ + MCH_HOST_BRIDGE_ESMRAMC_SM_L2) /* D1:F0 PCIE* port*/ #define MCH_PCIE_DEV 1 -- cgit v1.1 From b66a67d7519cb7f980885af5391b1103c42e9b6d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 15 Apr 2015 16:48:12 +0200 Subject: q35: add config space wmask for SMRAM and ESMRAMC Not all bits in SMRAM and ESMRAMC can be changed by the guest. Add wmask defines accordingly and set them in mch_reset(). Signed-off-by: Gerd Hoffmann Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/hw/pci-host/q35.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/hw') diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index d3c7bbb..01b8492 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -140,6 +140,11 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END 0x100000 #define MCH_HOST_BRIDGE_SMRAM_DEFAULT \ MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG +#define MCH_HOST_BRIDGE_SMRAM_WMASK \ + (MCH_HOST_BRIDGE_SMRAM_D_OPEN | \ + MCH_HOST_BRIDGE_SMRAM_D_CLS | \ + MCH_HOST_BRIDGE_SMRAM_D_LCK | \ + MCH_HOST_BRIDGE_SMRAM_G_SMRAME) #define MCH_HOST_BRIDGE_ESMRAMC 0x9e #define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 7)) @@ -156,6 +161,10 @@ typedef struct Q35PCIHost { (MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE | \ MCH_HOST_BRIDGE_ESMRAMC_SM_L1 | \ MCH_HOST_BRIDGE_ESMRAMC_SM_L2) +#define MCH_HOST_BRIDGE_ESMRAMC_WMASK \ + (MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME | \ + MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK | \ + MCH_HOST_BRIDGE_ESMRAMC_T_EN) /* D1:F0 PCIE* port*/ #define MCH_PCIE_DEV 1 -- cgit v1.1 From 68c77acfb18d28933f17b1c2a842bd936ce7223b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 14 Apr 2015 14:03:22 +0200 Subject: q35: implement SMRAM.D_LCK Once the SMRAM.D_LCK bit has been set by the guest several bits in SMRAM and ESMRAMC become readonly until the next machine reset. Implement this by updating the wmask accordingly when the guest sets the lock bit. As the lock it itself is locked down too we don't need to worry about the guest clearing the lock bit. Signed-off-by: Gerd Hoffmann Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/hw/pci-host/q35.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/hw') diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 01b8492..113cbe8 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -145,6 +145,8 @@ typedef struct Q35PCIHost { MCH_HOST_BRIDGE_SMRAM_D_CLS | \ MCH_HOST_BRIDGE_SMRAM_D_LCK | \ MCH_HOST_BRIDGE_SMRAM_G_SMRAME) +#define MCH_HOST_BRIDGE_SMRAM_WMASK_LCK \ + MCH_HOST_BRIDGE_SMRAM_D_CLS #define MCH_HOST_BRIDGE_ESMRAMC 0x9e #define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 7)) @@ -165,6 +167,7 @@ typedef struct Q35PCIHost { (MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME | \ MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK | \ MCH_HOST_BRIDGE_ESMRAMC_T_EN) +#define MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK 0 /* D1:F0 PCIE* port*/ #define MCH_PCIE_DEV 1 -- cgit v1.1 From bafc90bdc594a4d04db846bd8712bdcec59678a8 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 20 Apr 2015 10:55:09 +0200 Subject: q35: implement TSEG TSEG provides larger amounts of SMRAM than the 128 KB available with legacy SMRAM and high SMRAM. Route access to tseg into nowhere when enabled, for both cpus and busmaster dma, and add tseg window to smram region, so cpus can access it in smm mode. Signed-off-by: Gerd Hoffmann Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/hw/pci-host/q35.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/hw') diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 113cbe8..dbe6dc0 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -54,6 +54,7 @@ typedef struct MCHPCIState { PAMMemoryRegion pam_regions[13]; MemoryRegion smram_region, open_high_smram; MemoryRegion smram, low_smram, high_smram; + MemoryRegion tseg_blackhole, tseg_window; PcPciInfo pci_info; ram_addr_t below_4g_mem_size; ram_addr_t above_4g_mem_size; -- cgit v1.1 From 11e66a15a084cb0820dba13f4ea3b15b0512fd39 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 6 May 2015 10:58:30 +0200 Subject: ich9: implement SMI_LOCK Add write mask for the smi enable register, so we can disable write access to certain bits. Open all bits on reset. Disable write access to GBL_SMI_EN when SMI_LOCK (in ich9 lpc pci config space) is set. Write access to SMI_LOCK itself is disabled too. Signed-off-by: Gerd Hoffmann Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/hw/acpi/ich9.h | 1 + include/hw/i386/ich9.h | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'include/hw') diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index c2d3dba..77cc65c 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 f4e522c..a2cc15c 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -152,6 +152,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 -- cgit v1.1