All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH kvm-unit-tests 0/2] x86: get ACPI port addresses from FADT
@ 2015-08-21 19:54 Paolo Bonzini
  2015-08-21 19:54 ` [PATCH kvm-unit-tests 1/2] x86: add small library to find ACPI tables Paolo Bonzini
  2015-08-21 19:54 ` [PATCH kvm-unit-tests 2/2] x86: get ACPI port addresses from FADT Paolo Bonzini
  0 siblings, 2 replies; 3+ messages in thread
From: Paolo Bonzini @ 2015-08-21 19:54 UTC (permalink / raw)
  To: kvm

Recent versions of QEMU are placing the ACPI I/O ports starting at
0x600 instead of 0xb000.  This broke s3.flat and made vmexit.flat
test something else than PMTIMER; the latter matters because PMTIMER
is special in that it is not using the big QEMU lock.

Using the FADT to fetch the port addresses solves both problems.

Paolo

Paolo Bonzini (2):
  x86: add small library to find ACPI tables
  x86: get ACPI port addresses from FADT

 config/config-x86-common.mak |   1 +
 lib/x86/acpi.c               |  52 +++++++++++++++++
 lib/x86/acpi.h               | 104 ++++++++++++++++++++++++++++++++++
 x86/s3.c                     | 130 +++----------------------------------------
 x86/vmexit.c                 |   9 ++-
 5 files changed, 172 insertions(+), 124 deletions(-)
 create mode 100644 lib/x86/acpi.c
 create mode 100644 lib/x86/acpi.h

-- 
2.4.3


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH kvm-unit-tests 1/2] x86: add small library to find ACPI tables
  2015-08-21 19:54 [PATCH kvm-unit-tests 0/2] x86: get ACPI port addresses from FADT Paolo Bonzini
@ 2015-08-21 19:54 ` Paolo Bonzini
  2015-08-21 19:54 ` [PATCH kvm-unit-tests 2/2] x86: get ACPI port addresses from FADT Paolo Bonzini
  1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2015-08-21 19:54 UTC (permalink / raw)
  To: kvm

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 config/config-x86-common.mak |   1 +
 lib/x86/acpi.c               |  52 ++++++++++++++++++
 lib/x86/acpi.h               | 104 +++++++++++++++++++++++++++++++++++
 x86/s3.c                     | 127 ++-----------------------------------------
 4 files changed, 162 insertions(+), 122 deletions(-)
 create mode 100644 lib/x86/acpi.c
 create mode 100644 lib/x86/acpi.h

diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
index d45c9a8..869b5c7 100644
--- a/config/config-x86-common.mak
+++ b/config/config-x86-common.mak
@@ -11,6 +11,7 @@ cflatobjs += lib/x86/atomic.o
 cflatobjs += lib/x86/desc.o
 cflatobjs += lib/x86/isr.o
 cflatobjs += lib/x86/pci.o
+cflatobjs += lib/x86/acpi.o
 
 $(libcflat): LDFLAGS += -nostdlib
 $(libcflat): CFLAGS += -ffreestanding -I lib
diff --git a/lib/x86/acpi.c b/lib/x86/acpi.c
new file mode 100644
index 0000000..4373106
--- /dev/null
+++ b/lib/x86/acpi.c
@@ -0,0 +1,52 @@
+#include "libcflat.h"
+#include "acpi.h"
+
+void* find_acpi_table_addr(u32 sig)
+{
+    unsigned long addr;
+    struct rsdp_descriptor *rsdp;
+    struct rsdt_descriptor_rev1 *rsdt;
+    void *end;
+    int i;
+
+    /* FACS is special... */
+    if (sig == FACS_SIGNATURE) {
+        struct fadt_descriptor_rev1 *fadt;
+        fadt = find_acpi_table_addr(FACP_SIGNATURE);
+        if (!fadt) {
+            return NULL;
+        }
+        return (void*)(ulong)fadt->firmware_ctrl;
+    }
+
+    for(addr = 0xf0000; addr < 0x100000; addr += 16) {
+	rsdp = (void*)addr;
+	if (rsdp->signature == 0x2052545020445352LL)
+          break;
+    }
+    if (addr == 0x100000) {
+        printf("Can't find RSDP\n");
+        return 0;
+    }
+
+    if (sig == RSDP_SIGNATURE) {
+        return rsdp;
+    }
+
+    rsdt = (void*)(ulong)rsdp->rsdt_physical_address;
+    if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
+        return 0;
+
+    if (sig == RSDT_SIGNATURE) {
+        return rsdt;
+    }
+
+    end = (void*)rsdt + rsdt->length;
+    for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
+        struct acpi_table *t = (void*)(ulong)rsdt->table_offset_entry[i];
+        if (t && t->signature == sig) {
+            return t;
+        }
+    }
+   return NULL;
+}
diff --git a/lib/x86/acpi.h b/lib/x86/acpi.h
new file mode 100644
index 0000000..08aaf57
--- /dev/null
+++ b/lib/x86/acpi.h
@@ -0,0 +1,104 @@
+#ifndef KVM_ACPI_H
+#define KVM_ACPI_H 1
+
+#include "libcflat.h"
+
+#define ACPI_SIGNATURE(c1, c2, c3, c4) \
+	((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
+
+#define RSDP_SIGNATURE ACPI_SIGNATURE('R','S','D','P')
+#define RSDT_SIGNATURE ACPI_SIGNATURE('R','S','D','T')
+#define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
+#define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
+
+struct rsdp_descriptor {        /* Root System Descriptor Pointer */
+    u64 signature;              /* ACPI signature, contains "RSD PTR " */
+    u8  checksum;               /* To make sum of struct == 0 */
+    u8  oem_id [6];             /* OEM identification */
+    u8  revision;               /* Must be 0 for 1.0, 2 for 2.0 */
+    u32 rsdt_physical_address;  /* 32-bit physical address of RSDT */
+    u32 length;                 /* XSDT Length in bytes including hdr */
+    u64 xsdt_physical_address;  /* 64-bit physical address of XSDT */
+    u8  extended_checksum;      /* Checksum of entire table */
+    u8  reserved [3];           /* Reserved field must be 0 */
+};
+
+#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
+    u32 signature;          /* ACPI signature (4 ASCII characters) */ \
+    u32 length;                 /* Length of table, in bytes, including header */ \
+    u8  revision;               /* ACPI Specification minor version # */ \
+    u8  checksum;               /* To make sum of entire table == 0 */ \
+    u8  oem_id [6];             /* OEM identification */ \
+    u8  oem_table_id [8];       /* OEM table identification */ \
+    u32 oem_revision;           /* OEM revision number */ \
+    u8  asl_compiler_id [4];    /* ASL compiler vendor ID */ \
+    u32 asl_compiler_revision;  /* ASL compiler revision number */
+
+struct acpi_table {
+    ACPI_TABLE_HEADER_DEF
+    char data[0];
+};
+
+struct rsdt_descriptor_rev1 {
+    ACPI_TABLE_HEADER_DEF
+    u32 table_offset_entry[0];
+};
+
+struct fadt_descriptor_rev1
+{
+    ACPI_TABLE_HEADER_DEF     /* ACPI common table header */
+    u32 firmware_ctrl;          /* Physical address of FACS */
+    u32 dsdt;                   /* Physical address of DSDT */
+    u8  model;                  /* System Interrupt Model */
+    u8  reserved1;              /* Reserved */
+    u16 sci_int;                /* System vector of SCI interrupt */
+    u32 smi_cmd;                /* Port address of SMI command port */
+    u8  acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
+    u8  acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
+    u8  S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
+    u8  reserved2;              /* Reserved - must be zero */
+    u32 pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
+    u32 pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
+    u32 pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
+    u32 pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
+    u32 pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
+    u32 pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
+    u32 gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
+    u32 gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
+    u8  pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
+    u8  pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
+    u8  pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
+    u8  pm_tmr_len;             /* Byte Length of ports at pm_tm_blk */
+    u8  gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
+    u8  gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
+    u8  gpe1_base;              /* Offset in gpe model where gpe1 events start */
+    u8  reserved3;              /* Reserved */
+    u16 plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
+    u16 plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
+    u16 flush_size;             /* Size of area read to flush caches */
+    u16 flush_stride;           /* Stride used in flushing caches */
+    u8  duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
+    u8  duty_width;             /* Bit width of duty cycle field in p_cnt reg */
+    u8  day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
+    u8  mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
+    u8  century;                /* Index to century in RTC CMOS RAM */
+    u8  reserved4;              /* Reserved */
+    u8  reserved4a;             /* Reserved */
+    u8  reserved4b;             /* Reserved */
+};
+
+struct facs_descriptor_rev1
+{
+    u32 signature;           /* ACPI Signature */
+    u32 length;                 /* Length of structure, in bytes */
+    u32 hardware_signature;     /* Hardware configuration signature */
+    u32 firmware_waking_vector; /* ACPI OS waking vector */
+    u32 global_lock;            /* Global Lock */
+    u32 S4bios_f        : 1;    /* Indicates if S4BIOS support is present */
+    u32 reserved1       : 31;   /* Must be 0 */
+    u8  reserved3 [40];         /* Reserved - must be zero */
+};
+
+void* find_acpi_table_addr(u32 sig);
+
+#endif
diff --git a/x86/s3.c b/x86/s3.c
index d568aa7..72467a2 100644
--- a/x86/s3.c
+++ b/x86/s3.c
@@ -1,130 +1,13 @@
 #include "libcflat.h"
-
-struct rsdp_descriptor {        /* Root System Descriptor Pointer */
-    u64 signature;              /* ACPI signature, contains "RSD PTR " */
-    u8  checksum;               /* To make sum of struct == 0 */
-    u8  oem_id [6];             /* OEM identification */
-    u8  revision;               /* Must be 0 for 1.0, 2 for 2.0 */
-    u32 rsdt_physical_address;  /* 32-bit physical address of RSDT */
-    u32 length;                 /* XSDT Length in bytes including hdr */
-    u64 xsdt_physical_address;  /* 64-bit physical address of XSDT */
-    u8  extended_checksum;      /* Checksum of entire table */
-    u8  reserved [3];           /* Reserved field must be 0 */
-};
-
-#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
-    u32 signature;          /* ACPI signature (4 ASCII characters) */ \
-    u32 length;                 /* Length of table, in bytes, including header */ \
-    u8  revision;               /* ACPI Specification minor version # */ \
-    u8  checksum;               /* To make sum of entire table == 0 */ \
-    u8  oem_id [6];             /* OEM identification */ \
-    u8  oem_table_id [8];       /* OEM table identification */ \
-    u32 oem_revision;           /* OEM revision number */ \
-    u8  asl_compiler_id [4];    /* ASL compiler vendor ID */ \
-    u32 asl_compiler_revision;  /* ASL compiler revision number */
-
-#define RSDT_SIGNATURE 0x54445352
-struct rsdt_descriptor_rev1 {
-    ACPI_TABLE_HEADER_DEF
-    u32 table_offset_entry[0];
-};
-
-#define FACP_SIGNATURE 0x50434146 // FACP
-struct fadt_descriptor_rev1
-{
-    ACPI_TABLE_HEADER_DEF     /* ACPI common table header */
-    u32 firmware_ctrl;          /* Physical address of FACS */
-    u32 dsdt;                   /* Physical address of DSDT */
-    u8  model;                  /* System Interrupt Model */
-    u8  reserved1;              /* Reserved */
-    u16 sci_int;                /* System vector of SCI interrupt */
-    u32 smi_cmd;                /* Port address of SMI command port */
-    u8  acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
-    u8  acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
-    u8  S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
-    u8  reserved2;              /* Reserved - must be zero */
-    u32 pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
-    u32 pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
-    u32 pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
-    u32 pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
-    u32 pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
-    u32 pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
-    u32 gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
-    u32 gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
-    u8  pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
-    u8  pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
-    u8  pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
-    u8  pm_tmr_len;             /* Byte Length of ports at pm_tm_blk */
-    u8  gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
-    u8  gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
-    u8  gpe1_base;              /* Offset in gpe model where gpe1 events start */
-    u8  reserved3;              /* Reserved */
-    u16 plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
-    u16 plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
-    u16 flush_size;             /* Size of area read to flush caches */
-    u16 flush_stride;           /* Stride used in flushing caches */
-    u8  duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
-    u8  duty_width;             /* Bit width of duty cycle field in p_cnt reg */
-    u8  day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
-    u8  mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
-    u8  century;                /* Index to century in RTC CMOS RAM */
-    u8  reserved4;              /* Reserved */
-    u8  reserved4a;             /* Reserved */
-    u8  reserved4b;             /* Reserved */
-};
-
-#define FACS_SIGNATURE 0x53434146 // FACS
-struct facs_descriptor_rev1
-{
-    u32 signature;           /* ACPI Signature */
-    u32 length;                 /* Length of structure, in bytes */
-    u32 hardware_signature;     /* Hardware configuration signature */
-    u32 firmware_waking_vector; /* ACPI OS waking vector */
-    u32 global_lock;            /* Global Lock */
-    u32 S4bios_f        : 1;    /* Indicates if S4BIOS support is present */
-    u32 reserved1       : 31;   /* Must be 0 */
-    u8  resverved3 [40];        /* Reserved - must be zero */
-};
+#include "acpi.h"
 
 u32* find_resume_vector_addr(void)
 {
-    unsigned long addr;
-    struct rsdp_descriptor *rsdp;
-    struct rsdt_descriptor_rev1 *rsdt;
-    void *end;
-    int i;
-
-    for(addr = 0xf0000; addr < 0x100000; addr += 16) {
-	rsdp = (void*)addr;
-	if (rsdp->signature == 0x2052545020445352LL)
-          break;
-    }
-    if (addr == 0x100000) {
-        printf("Can't find RSDP\n");
-        return 0;
-    }
-
-    printf("RSDP is at %x\n", rsdp);
-    rsdt = (void*)(ulong)rsdp->rsdt_physical_address;
-    if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
+    struct facs_descriptor_rev1 *facs = find_acpi_table_addr(FACS_SIGNATURE);
+    if (!facs)
         return 0;
-
-    printf("RSDT is at %x\n", rsdt);
-
-    end = (void*)rsdt + rsdt->length;
-    for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
-        struct fadt_descriptor_rev1 *fadt = (void*)(ulong)rsdt->table_offset_entry[i];
-        struct facs_descriptor_rev1 *facs;
-        if (!fadt || fadt->signature != FACP_SIGNATURE)
-            continue;
-        printf("FADT is at %x\n", fadt);
-        facs = (void*)(ulong)fadt->firmware_ctrl;
-        if (!facs || facs->signature != FACS_SIGNATURE)
-            return 0;
-        printf("FACS is at %x\n", facs);
-        return &facs->firmware_waking_vector;
-    }
-   return 0;
+    printf("FACS is at %x\n", facs);
+    return &facs->firmware_waking_vector;
 }
 
 #define RTC_SECONDS_ALARM       1
-- 
2.4.3



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH kvm-unit-tests 2/2] x86: get ACPI port addresses from FADT
  2015-08-21 19:54 [PATCH kvm-unit-tests 0/2] x86: get ACPI port addresses from FADT Paolo Bonzini
  2015-08-21 19:54 ` [PATCH kvm-unit-tests 1/2] x86: add small library to find ACPI tables Paolo Bonzini
@ 2015-08-21 19:54 ` Paolo Bonzini
  1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2015-08-21 19:54 UTC (permalink / raw)
  To: kvm

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 x86/s3.c     | 5 +++--
 x86/vmexit.c | 9 ++++++++-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/x86/s3.c b/x86/s3.c
index 72467a2..8bf71da 100644
--- a/x86/s3.c
+++ b/x86/s3.c
@@ -1,5 +1,5 @@
 #include "libcflat.h"
-#include "acpi.h"
+#include "x86/acpi.h"
 
 u32* find_resume_vector_addr(void)
 {
@@ -40,6 +40,7 @@ extern char resume_start, resume_end;
 
 int main(int argc, char **argv)
 {
+	struct fadt_descriptor_rev1 *fadt = find_acpi_table_addr(FACP_SIGNATURE);
 	volatile u32 *resume_vector_ptr = find_resume_vector_addr();
 	char *addr, *resume_vec = (void*)0x1000;
 
@@ -60,7 +61,7 @@ int main(int argc, char **argv)
 	rtc_out(RTC_REG_B, rtc_in(RTC_REG_B) | REG_B_AIE);
 
 	*(volatile int*)0 = 0;
-	asm volatile("outw %0, %1" :: "a"((short)0x2400), "d"((short)0xb004):"memory");
+	asm volatile("outw %0, %1" :: "a"((short)0x2400), "d"((short)fadt->pm1a_cnt_blk):"memory");
 	while(1)
 		*(volatile int*)0 = 1;
 
diff --git a/x86/vmexit.c b/x86/vmexit.c
index 3bd0c81..1413454 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -5,6 +5,7 @@
 #include "x86/vm.h"
 #include "x86/desc.h"
 #include "x86/pci.h"
+#include "x86/acpi.h"
 
 struct test {
 	void (*func)(void);
@@ -104,9 +105,10 @@ static void ipi_halt(void)
 		;
 }
 
+int pm_tmr_blk;
 static void inl_pmtimer(void)
 {
-    inl(0xb008);
+    inl(pm_tmr_blk);
 }
 
 static void inl_nop_qemu(void)
@@ -406,6 +408,7 @@ bool test_wanted(struct test *test, char *wanted[], int nwanted)
 
 int main(int ac, char **av)
 {
+	struct fadt_descriptor_rev1 *fadt;
 	int i;
 	unsigned long membar = 0, base, offset;
 	void *m;
@@ -418,6 +421,10 @@ int main(int ac, char **av)
 	for (i = cpu_count(); i > 0; i--)
 		on_cpu(i-1, enable_nx, 0);
 
+	fadt = find_acpi_table_addr(FACP_SIGNATURE);
+	pm_tmr_blk = fadt->pm_tmr_blk;
+	printf("PM timer port is %x\n", pm_tmr_blk);
+
 	pcidev = pci_find_dev(0x1b36, 0x0005);
 	if (pcidev) {
 		for (i = 0; i < 2; i++) {
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-08-21 19:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-21 19:54 [PATCH kvm-unit-tests 0/2] x86: get ACPI port addresses from FADT Paolo Bonzini
2015-08-21 19:54 ` [PATCH kvm-unit-tests 1/2] x86: add small library to find ACPI tables Paolo Bonzini
2015-08-21 19:54 ` [PATCH kvm-unit-tests 2/2] x86: get ACPI port addresses from FADT Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.