The first three of these are cloned from Linux counterparts, and the last one adjusts behavior we would have needed for v4 already. 1: ACPI 5.0: Basic support for FADT version 5 2: ACPI 5.0: Implement hardware-reduced option 3: ACPICA: Update for larger ACPI 5 FADT size 4: ACPI: support v5 (reduced HW) sleep interface 5: x86: honor ACPI indicating absence of CMOS RTC 6: honor ACPI v4 FADT flags Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/drivers/acpi/tables/tbfadt.c
+++ b/xen/drivers/acpi/tables/tbfadt.c
@@ -222,12 +222,13 @@ void __init acpi_tb_create_local_fadt(st
 
 	/*
 	 * Check if the FADT is larger than the largest table that we expect
-	 * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue
+	 * (the ACPI 5.0 version). If so, truncate the table, and issue
 	 * a warning.
 	 */
 	if (length > sizeof(struct acpi_table_fadt)) {
 		ACPI_WARNING((AE_INFO,
-			      "FADT (revision %u) is longer than ACPI 2.0 version, truncating
length 0x%X to 0x%zX",
+			      "FADT (revision %u) is longer than ACPI 5.0 version,"
+			      " truncating length %u to %zu",
 			      table->revision, (unsigned)length,
 			      sizeof(struct acpi_table_fadt)));
 	}
--- a/xen/include/acpi/actbl.h
+++ b/xen/include/acpi/actbl.h
@@ -255,6 +255,8 @@ struct acpi_table_fadt {
 	struct acpi_generic_address xpm_timer_block;	/* 64-bit Extended Power Mgt
Timer Ctrl Reg Blk address */
 	struct acpi_generic_address xgpe0_block;	/* 64-bit Extended General Purpose
Event 0 Reg Blk address */
 	struct acpi_generic_address xgpe1_block;	/* 64-bit Extended General Purpose
Event 1 Reg Blk address */
+	struct acpi_generic_address sleep_control;	/* 64-bit Sleep Control register */
+	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register */
 };
 
 /* Masks for FADT Boot Architecture Flags (boot_flags) */
@@ -264,6 +266,7 @@ struct acpi_table_fadt {
 #define ACPI_FADT_NO_VGA            (1<<2)	/* 02: [V4] It is not safe to
probe for VGA hardware */
 #define ACPI_FADT_NO_MSI            (1<<3)	/* 03: [V4] Message Signaled
Interrupts (MSI) must not be enabled */
 #define ACPI_FADT_NO_ASPM           (1<<4)	/* 04: [V4] PCIe ASPM control
must not be enabled */
+#define ACPI_FADT_NO_CMOS_RTC       (1<<5)	/* 05: [V5] No CMOS real-time
clock present */
 
 #define FADT2_REVISION_ID               3
 
@@ -289,6 +292,8 @@ struct acpi_table_fadt {
 #define ACPI_FADT_REMOTE_POWER_ON   (1<<17)	/* 17: [V4] System is
compatible with remote power on (ACPI 3.0) */
 #define ACPI_FADT_APIC_CLUSTER      (1<<18)	/* 18: [V4] All local APICs
must use cluster model (ACPI 3.0) */
 #define ACPI_FADT_APIC_PHYSICAL     (1<<19)	/* 19: [V4] All local x_aPICs
must use physical dest mode (ACPI 3.0) */
+#define ACPI_FADT_HW_REDUCED        (1<<20)	/* 20: [V5] ACPI hardware is
not implemented (ACPI 5.0) */
+#define ACPI_FADT_LOW_POWER_S0      (1<<21)	/* 21: [V5] S0 power savings
are equal or better than S3 (ACPI 5.0) */
 
 /* Values for preferred_profile (Preferred Power Management Profiles) */
 
@@ -299,14 +304,16 @@ enum acpi_prefered_pm_profiles {
 	PM_WORKSTATION = 3,
 	PM_ENTERPRISE_SERVER = 4,
 	PM_SOHO_SERVER = 5,
-	PM_APPLIANCE_PC = 6
+	PM_APPLIANCE_PC = 6,
+	PM_PERFORMANCE_SERVER = 7,
+	PM_TABLET = 8
 };
 
 /* Reset to default packing */
 
 #pragma pack()
 
-#define ACPI_FADT_OFFSET(f)             (u8) ACPI_OFFSET (struct
acpi_table_fadt, f)
+#define ACPI_FADT_OFFSET(f)             (u16) ACPI_OFFSET (struct
acpi_table_fadt, f)
 
 /*
  * Get the remaining ACPI tables
@@ -324,12 +331,15 @@ enum acpi_prefered_pm_profiles {
  * FADT is the bottom line as to what the version really is.
  *
  * For reference, the values below are as follows:
- *     FADT V1  size: 0x74
- *     FADT V2  size: 0x84
- *     FADT V3+ size: 0xF4
+ *     FADT V1  size: 0x074
+ *     FADT V2  size: 0x084
+ *     FADT V3  size: 0x0F4
+ *     FADT V4  size: 0x0F4
+ *     FADT V5  size: 0x10C
  */
 #define ACPI_FADT_V1_SIZE       (u32) (ACPI_FADT_OFFSET (flags) + 4)
 #define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (reserved4[0]) + 3)
-#define ACPI_FADT_V3_SIZE       (u32) (sizeof (struct acpi_table_fadt))
+#define ACPI_FADT_V3_SIZE       (u32) (ACPI_FADT_OFFSET (sleep_control))
+#define ACPI_FADT_V5_SIZE       (u32) (sizeof (struct acpi_table_fadt))
 
 #endif				/* __ACTBL_H__ */
If HW-reduced flag is set in the FADT, do not attempt to access
or initialize any ACPI hardware, including SCI and global lock.
No FACS will be present.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Also adjust acpi_fadt_parse_sleep_info().
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/acpi/boot.c
+++ b/xen/arch/x86/acpi/boot.c
@@ -328,6 +328,9 @@ acpi_fadt_parse_sleep_info(struct acpi_t
 	struct acpi_table_facs *facs = NULL;
 	uint64_t facs_pa;
 
+	if (fadt->flags & ACPI_FADT_HW_REDUCED)
+		goto bad;
+
 	acpi_fadt_copy_address(pm1a_cnt, pm1a_control, pm1_control);
 	acpi_fadt_copy_address(pm1b_cnt, pm1b_control, pm1_control);
 	acpi_fadt_copy_address(pm1a_evt, pm1a_event, pm1_event);
@@ -351,6 +354,8 @@ acpi_fadt_parse_sleep_info(struct acpi_t
 		       fadt->facs, facs_pa);
 		facs_pa = (uint64_t)fadt->facs;
 	}
+	if (!facs_pa)
+		goto bad;
 
 	facs = (struct acpi_table_facs *)
 		__acpi_map_table(facs_pa, sizeof(struct acpi_table_facs));
--- a/xen/include/acpi/acglobal.h
+++ b/xen/include/acpi/acglobal.h
@@ -78,6 +78,13 @@ ACPI_EXTERN struct acpi_table_fadt acpi_
 ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
 ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
 
+/*
+ * ACPI 5.0 introduces the concept of a "reduced hardware platform",
meaning
+ * that the ACPI hardware is no longer required. A flag in the FADT indicates
+ * a reduced HW machine, and that flag is duplicated here for convenience.
+ */
+ACPI_EXTERN u8 acpi_gbl_reduced_hardware;
+
 /*****************************************************************************
  *
  * Miscellaneous globals
--- a/xen/drivers/acpi/tables/tbfadt.c
+++ b/xen/drivers/acpi/tables/tbfadt.c
@@ -197,8 +197,13 @@ void __init acpi_tb_parse_fadt(acpi_nati
 	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
 			      flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
 
-	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
-			      flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+	/* If Hardware Reduced flag is set, there is no FACS */
+
+	if (!acpi_gbl_reduced_hardware) {
+		acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.
+				      Xfacs, flags, ACPI_SIG_FACS,
+				      ACPI_TABLE_INDEX_FACS);
+	}
 }
 
 /*******************************************************************************
@@ -242,6 +247,13 @@ void __init acpi_tb_create_local_fadt(st
 	ACPI_MEMCPY(&acpi_gbl_FADT, table,
 		    ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
 
+	/* Take a copy of the Hardware Reduced flag */
+
+	acpi_gbl_reduced_hardware = FALSE;
+	if (acpi_gbl_FADT.flags & ACPI_FADT_HW_REDUCED) {
+		acpi_gbl_reduced_hardware = TRUE;
+	}
+
 	/*
 	 * 1) Convert the local copy of the FADT to the common internal format
 	 * 2) Validate some of the important values within the FADT
@@ -401,6 +413,12 @@ static void __init acpi_tb_validate_fadt
 	u8 length;
 	acpi_native_uint i;
 
+	/* If Hardware Reduced flag is set, we are all done */
+
+	if (acpi_gbl_reduced_hardware) {
+		return;
+	}
+
 	/* Examine all of the 64-bit extended address fields (X fields) */
 
 	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
FADT is now larger than 256 bytes, so all FADT offsets must be
changed from 8 bits to 16 bits.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/drivers/acpi/tables/tbfadt.c
+++ b/xen/drivers/acpi/tables/tbfadt.c
@@ -62,13 +62,14 @@ static void acpi_tb_validate_fadt(void);
 
 typedef struct acpi_fadt_info {
 	char *name;
-	u8 target;
-	u8 source;
-	u8 length;
+	u16 target;
+	u16 source;
+	u16 length;
 	u8 type;
 
 } acpi_fadt_info;
 
+#define ACPI_FADT_OPTIONAL          0
 #define ACPI_FADT_REQUIRED          1
 #define ACPI_FADT_SEPARATE_LENGTH   2
 
@@ -79,7 +80,7 @@ static struct acpi_fadt_info __initdata 
 
 	{"Pm1bEventBlock", ACPI_FADT_OFFSET(xpm1b_event_block),
 	 ACPI_FADT_OFFSET(pm1b_event_block),
-	 ACPI_FADT_OFFSET(pm1_event_length), 0},
+	 ACPI_FADT_OFFSET(pm1_event_length), ACPI_FADT_OPTIONAL},
 
 	{"Pm1aControlBlock", ACPI_FADT_OFFSET(xpm1a_control_block),
 	 ACPI_FADT_OFFSET(pm1a_control_block),
@@ -87,7 +88,7 @@ static struct acpi_fadt_info __initdata 
 
 	{"Pm1bControlBlock", ACPI_FADT_OFFSET(xpm1b_control_block),
 	 ACPI_FADT_OFFSET(pm1b_control_block),
-	 ACPI_FADT_OFFSET(pm1_control_length), 0},
+	 ACPI_FADT_OFFSET(pm1_control_length), ACPI_FADT_OPTIONAL},
 
 	{"Pm2ControlBlock", ACPI_FADT_OFFSET(xpm2_control_block),
 	 ACPI_FADT_OFFSET(pm2_control_block),
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
Jan Beulich
2013-Feb-21  13:00 UTC
[PATCH 4/6] ACPI: support v5 (reduced HW) sleep interface
Note that this also fixes a broken input check in acpi_enter_sleep()
(previously validating the sleep->pm1[ab]_cnt_val relationship based
on acpi_sinfo.pm1b_cnt_val, which however gets set only subsequently).
Also adjust a few minor issues with the pre-v5 handling in
acpi_fadt_parse_sleep_info().
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
A question is whether, rather than passing the raw values read from
_Sx to XENPF_enter_acpi_sleep, we should again have Dom0 pass the
values ready to be written into the registers - that would make things
consistent with the legacy case, but add further dependency of the
hypervisor on Dom0 behavior where it''s not really needed. I think that
it was a mistake for the original variant to have Dom0 pass massaged
values to the hypervisor.
--- a/xen/arch/x86/acpi/boot.c
+++ b/xen/arch/x86/acpi/boot.c
@@ -310,14 +310,15 @@ static int __init acpi_invalidate_bgrt(s
 
 #ifdef CONFIG_ACPI_SLEEP
 #define acpi_fadt_copy_address(dst, src, len) do {			\
-	if (fadt->header.revision >= FADT2_REVISION_ID)			\
+	if (fadt->header.revision >= FADT2_REVISION_ID &&		\
+	    fadt->header.length >= ACPI_FADT_V2_SIZE)			\
 		acpi_sinfo.dst##_blk = fadt->x##src##_block;		\
 	if (!acpi_sinfo.dst##_blk.address) {				\
 		acpi_sinfo.dst##_blk.address      = fadt->src##_block;	\
 		acpi_sinfo.dst##_blk.space_id     = ACPI_ADR_SPACE_SYSTEM_IO; \
 		acpi_sinfo.dst##_blk.bit_width    = fadt->len##_length << 3; \
 		acpi_sinfo.dst##_blk.bit_offset   = 0;			\
-		acpi_sinfo.dst##_blk.access_width = 0;			\
+		acpi_sinfo.dst##_blk.access_width = fadt->len##_length;	\
 	} \
 } while (0)
 
@@ -328,6 +329,41 @@ acpi_fadt_parse_sleep_info(struct acpi_t
 	struct acpi_table_facs *facs = NULL;
 	uint64_t facs_pa;
 
+	if (fadt->header.revision >= 5 &&
+	    fadt->header.length >= ACPI_FADT_V5_SIZE) {
+		acpi_sinfo.sleep_control = fadt->sleep_control;
+		acpi_sinfo.sleep_status = fadt->sleep_status;
+
+		printk(KERN_INFO PREFIX
+		       "v5 SLEEP INFO: control[%d:%"PRIx64"],"
+		       " status[%d:%"PRIx64"]\n",
+		       acpi_sinfo.sleep_control.space_id,
+		       acpi_sinfo.sleep_control.address,
+		       acpi_sinfo.sleep_status.space_id,
+		       acpi_sinfo.sleep_status.address);
+
+		if ((fadt->sleep_control.address &&
+		     (fadt->sleep_control.bit_offset ||
+		      fadt->sleep_control.bit_width !+		     
fadt->sleep_control.access_width * 8)) ||
+		    (fadt->sleep_status.address &&
+		     (fadt->sleep_status.bit_offset ||
+		      fadt->sleep_status.bit_width !+		     
fadt->sleep_status.access_width * 8))) {
+			printk(KERN_WARNING PREFIX
+			       "Invalid sleep control/status register data:"
+			       " %#x:%#x:%#x %#x:%#x:%#x\n",
+			       fadt->sleep_control.bit_offset,
+			       fadt->sleep_control.bit_width,
+			       fadt->sleep_control.access_width,
+			       fadt->sleep_status.bit_offset,
+			       fadt->sleep_status.bit_width,
+			       fadt->sleep_status.access_width);
+			fadt->sleep_control.address = 0;
+			fadt->sleep_status.address = 0;
+		}
+	}
+
 	if (fadt->flags & ACPI_FADT_HW_REDUCED)
 		goto bad;
 
@@ -337,7 +373,7 @@ acpi_fadt_parse_sleep_info(struct acpi_t
 	acpi_fadt_copy_address(pm1b_evt, pm1b_event, pm1_event);
 
 	printk(KERN_INFO PREFIX
-	       "ACPI SLEEP INFO:
pm1x_cnt[%"PRIx64",%"PRIx64"], "
+	       "SLEEP INFO: pm1x_cnt[%"PRIx64",%"PRIx64"],
"
 	       "pm1x_evt[%"PRIx64",%"PRIx64"]\n",
 	       acpi_sinfo.pm1a_cnt_blk.address,
 	       acpi_sinfo.pm1b_cnt_blk.address,
@@ -384,11 +420,14 @@ acpi_fadt_parse_sleep_info(struct acpi_t
 	acpi_sinfo.vector_width = 32;
 
 	printk(KERN_INFO PREFIX
-	       "                 wakeup_vec[%"PRIx64"],
vec_size[%x]\n",
+	       "            wakeup_vec[%"PRIx64"],
vec_size[%x]\n",
 	       acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width);
 	return;
 bad:
-	memset(&acpi_sinfo, 0, sizeof(acpi_sinfo));
+	memset(&acpi_sinfo, 0,
+	       offsetof(struct acpi_sleep_info, sleep_control));
+	memset(&acpi_sinfo.sleep_status + 1, 0,
+	       (long)(&acpi_sinfo + 1) - (long)(&acpi_sinfo.sleep_status +
1));
 }
 #endif
 
--- a/xen/arch/x86/acpi/power.c
+++ b/xen/arch/x86/acpi/power.c
@@ -239,23 +239,47 @@ static long enter_state_helper(void *dat
  */
 int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep)
 {
-    if ( !acpi_sinfo.pm1a_cnt_blk.address )
+    if ( sleep->flags & XENPF_ACPI_SLEEP_EXTENDED )
+    {
+        if ( !acpi_sinfo.sleep_control.address ||
+             !acpi_sinfo.sleep_status.address )
+            return -EPERM;
+
+        if ( sleep->flags & ~XENPF_ACPI_SLEEP_EXTENDED )
+            return -EINVAL;
+
+        if ( sleep->val_a > ACPI_SLEEP_TYPE_MAX ||
+             (sleep->val_b != ACPI_SLEEP_TYPE_INVALID &&
+              sleep->val_b > ACPI_SLEEP_TYPE_MAX) )
+            return -ERANGE;
+
+        acpi_sinfo.sleep_type_a = sleep->val_a;
+        acpi_sinfo.sleep_type_b = sleep->val_b;
+
+        acpi_sinfo.sleep_extended = 1;
+    }
+
+    else if ( !acpi_sinfo.pm1a_cnt_blk.address )
         return -EPERM;
 
     /* Sanity check */
-    if ( acpi_sinfo.pm1b_cnt_val &&
-         ((sleep->pm1a_cnt_val ^ sleep->pm1b_cnt_val) &
-          ACPI_BITMASK_SLEEP_ENABLE) )
+    else if ( sleep->val_b &&
+              ((sleep->val_a ^ sleep->val_b) &
ACPI_BITMASK_SLEEP_ENABLE) )
     {
         gdprintk(XENLOG_ERR, "Mismatched pm1a/pm1b setting.");
         return -EINVAL;
     }
 
-    if ( sleep->flags )
+    else if ( sleep->flags )
         return -EINVAL;
 
-    acpi_sinfo.pm1a_cnt_val = sleep->pm1a_cnt_val;
-    acpi_sinfo.pm1b_cnt_val = sleep->pm1b_cnt_val;
+    else
+    {
+        acpi_sinfo.pm1a_cnt_val = sleep->val_a;
+        acpi_sinfo.pm1b_cnt_val = sleep->val_b;
+        acpi_sinfo.sleep_extended = 0;
+    }
+
     acpi_sinfo.sleep_state = sleep->sleep_state;
 
     return continue_hypercall_on_cpu(0, enter_state_helper, &acpi_sinfo);
@@ -266,6 +290,13 @@ static int acpi_get_wake_status(void)
     uint32_t val;
     acpi_status status;
 
+    if ( acpi_sinfo.sleep_extended )
+    {
+        status = acpi_hw_register_read(ACPI_REGISTER_SLEEP_STATUS, &val);
+
+        return ACPI_FAILURE(status) ? 0 : val & ACPI_X_WAKE_STATUS;
+    }
+
     /* Wake status is the 15th bit of PM1 status register. (ACPI spec 3.0) */
     status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &val);
     if ( ACPI_FAILURE(status) )
@@ -335,19 +366,33 @@ acpi_status acpi_enter_sleep_state(u8 sl
 
     ACPI_FLUSH_CPU_CACHE();
 
-    status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, 
-                                    acpi_sinfo.pm1a_cnt_val);
-    if ( ACPI_FAILURE(status) )
-        return_ACPI_STATUS(AE_ERROR);
-
-    if ( acpi_sinfo.pm1b_cnt_blk.address )
+    if ( acpi_sinfo.sleep_extended )
     {
-        status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, 
-                                        acpi_sinfo.pm1b_cnt_val);
-        if ( ACPI_FAILURE(status) )
-            return_ACPI_STATUS(AE_ERROR);
+        /*
+         * Set the SLP_TYP and SLP_EN bits.
+         *
+         * Note: We only use the first value returned by the \_Sx method
+         * (acpi_sinfo.sleep_type_a) - As per ACPI specification.
+         */
+        u8 sleep_type_value +            ((acpi_sinfo.sleep_type_a <<
ACPI_X_SLEEP_TYPE_POSITION) &
+             ACPI_X_SLEEP_TYPE_MASK) | ACPI_X_SLEEP_ENABLE;
+
+        status = acpi_hw_register_write(ACPI_REGISTER_SLEEP_CONTROL,
+                                        sleep_type_value);
+    }
+    else
+    {
+        status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
+                                        acpi_sinfo.pm1a_cnt_val);
+        if ( !ACPI_FAILURE(status) && acpi_sinfo.pm1b_cnt_blk.address )
+            status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
+                                            acpi_sinfo.pm1b_cnt_val);
     }
 
+    if ( ACPI_FAILURE(status) )
+        return_ACPI_STATUS(AE_ERROR);
+
     /* Wait until we enter sleep state, and spin until we wake */
     while ( !acpi_get_wake_status() )
         continue;
--- a/xen/drivers/acpi/hwregs.c
+++ b/xen/drivers/acpi/hwregs.c
@@ -365,6 +365,14 @@ acpi_hw_register_read(u32 register_id, u
 		    acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
 		break;
 
+	case ACPI_REGISTER_SLEEP_STATUS:
+
+		status +		    acpi_hw_low_level_read(acpi_gbl_FADT.sleep_status.bit_width,
+					   &value1,
+					   &acpi_gbl_FADT.sleep_status);
+		break;
+
 	default:
 		ACPI_DEBUG_PRINT((AE_INFO, "Unknown Register ID: %X",
register_id));
 		status = AE_BAD_PARAMETER;
@@ -525,6 +533,14 @@ acpi_status acpi_hw_register_write(u32 r
 		    acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
 		break;
 
+	case ACPI_REGISTER_SLEEP_CONTROL:
+
+		status +		    acpi_hw_low_level_write(acpi_gbl_FADT.sleep_control.bit_width,
+					    value,
+					    &acpi_gbl_FADT.sleep_control);
+		break;
+
 	default:
 		status = AE_BAD_PARAMETER;
 		break;
--- a/xen/include/acpi/aclocal.h
+++ b/xen/include/acpi/aclocal.h
@@ -128,6 +128,8 @@ struct acpi_bit_register_info {
 #define ACPI_REGISTER_PM_TIMER                  0x07
 #define ACPI_REGISTER_PROCESSOR_BLOCK           0x08
 #define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x09
+#define ACPI_REGISTER_SLEEP_CONTROL             0x0a
+#define ACPI_REGISTER_SLEEP_STATUS              0x0b
 
 /* Masks used to access the bit_registers */
 
--- a/xen/include/acpi/actbl.h
+++ b/xen/include/acpi/actbl.h
@@ -309,6 +309,13 @@ enum acpi_prefered_pm_profiles {
 	PM_TABLET = 8
 };
 
+/* Values for sleep_status and sleep_control registers (V5 FADT) */
+
+#define ACPI_X_WAKE_STATUS          0x80
+#define ACPI_X_SLEEP_TYPE_MASK      0x1C
+#define ACPI_X_SLEEP_TYPE_POSITION  0x02
+#define ACPI_X_SLEEP_ENABLE         0x20
+
 /* Reset to default packing */
 
 #pragma pack()
--- a/xen/include/asm-x86/acpi.h
+++ b/xen/include/asm-x86/acpi.h
@@ -126,11 +126,20 @@ struct acpi_sleep_info {
     struct acpi_generic_address pm1b_cnt_blk;
     struct acpi_generic_address pm1a_evt_blk;
     struct acpi_generic_address pm1b_evt_blk;
-    uint16_t pm1a_cnt_val;
-    uint16_t pm1b_cnt_val;
+    struct acpi_generic_address sleep_control;
+    struct acpi_generic_address sleep_status;
+    union {
+        uint16_t pm1a_cnt_val;
+        uint8_t sleep_type_a;
+    };
+    union {
+        uint16_t pm1b_cnt_val;
+        uint8_t sleep_type_b;
+    };
     uint32_t sleep_state;
     uint64_t wakeup_vector;
     uint32_t vector_width;
+    bool_t sleep_extended;
 };
 
 #endif /* CONFIG_ACPI_SLEEP */
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -290,10 +290,16 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_firmware_i
 #define XENPF_enter_acpi_sleep    51
 struct xenpf_enter_acpi_sleep {
     /* IN variables */
+#if __XEN_INTERFACE_VERSION__ < 0x00040300
     uint16_t pm1a_cnt_val;      /* PM1a control value. */
     uint16_t pm1b_cnt_val;      /* PM1b control value. */
+#else
+    uint16_t val_a;             /* PM1a control / sleep type A. */
+    uint16_t val_b;             /* PM1b control / sleep type B. */
+#endif
     uint32_t sleep_state;       /* Which state to enter (Sn). */
-    uint32_t flags;             /* Must be zero. */
+#define XENPF_ACPI_SLEEP_EXTENDED 0x00000001
+    uint32_t flags;             /* XENPF_ACPI_SLEEP_*. */
 };
 typedef struct xenpf_enter_acpi_sleep xenpf_enter_acpi_sleep_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_enter_acpi_sleep_t);
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
Jan Beulich
2013-Feb-21  13:01 UTC
[PATCH 5/6] x86: honor ACPI indicating absence of CMOS RTC
On such systems we can boot through EFI only.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -754,6 +754,9 @@ static unsigned long get_cmos_time(void)
             return res;
     }
 
+    if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC) )
+        panic("System without CMOS RTC must be booted from EFI\n");
+
     spin_lock_irqsave(&rtc_lock, flags);
 
     /* read RTC exactly on falling edge of update flag */
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
- force use of physical APIC mode if indicated so (as we don''t support
  xAPIC cluster mode, the respective flag is taken to force physical
  mode too)
- don''t use MSI if indicated so (implies no IOMMU)
Both can be overridden on the command line, for the MSI case this at
once adds a new command line option allowing to turn off PCI MSI (IOMMU
and HPET are unaffected by this).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -639,6 +639,13 @@ limit is ignored by Xen.
 
 Specify if the MMConfig space should be enabled.
 
+### msi
+> `= <boolean>`
+
+> Default: `true`
+
+Force Xen to (not) use PCI-MSI, even if ACPI FADT says otherwise.
+
 ### mwait-idle
 > `= <boolean>`
 
--- a/xen/arch/x86/genapic/bigsmp.c
+++ b/xen/arch/x86/genapic/bigsmp.c
@@ -40,7 +40,14 @@ static struct dmi_system_id __initdata b
 
 static __init int probe_bigsmp(void)
 { 
-	if (!def_to_bigsmp)
+	/*
+	 * We don''t implement cluster mode, so force use of
+	 * physical mode in both cases.
+	 */
+	if (acpi_gbl_FADT.flags &
+	    (ACPI_FADT_APIC_CLUSTER | ACPI_FADT_APIC_PHYSICAL))
+		def_to_bigsmp = 1;
+	else if (!def_to_bigsmp)
 		dmi_check_system(bigsmp_dmi_table);
 	return def_to_bigsmp;
 } 
--- a/xen/arch/x86/genapic/x2apic.c
+++ b/xen/arch/x86/genapic/x2apic.c
@@ -30,9 +30,6 @@
 #include <xen/smp.h>
 #include <asm/mach-default/mach_mpparse.h>
 
-static bool_t __initdata x2apic_phys; /* By default we use logical cluster
mode. */
-boolean_param("x2apic_phys", x2apic_phys);
-
 static DEFINE_PER_CPU_READ_MOSTLY(u32, cpu_2_logical_apicid);
 static DEFINE_PER_CPU_READ_MOSTLY(cpumask_t *, cluster_cpus);
 static cpumask_t *cluster_cpus_spare;
@@ -223,8 +220,14 @@ static struct notifier_block x2apic_cpu_
    .notifier_call = update_clusterinfo
 };
 
+static s8 __initdata x2apic_phys = -1; /* By default we use logical cluster
mode. */
+boolean_param("x2apic_phys", x2apic_phys);
+
 const struct genapic *__init apic_x2apic_probe(void)
 {
+    if ( x2apic_phys < 0 )
+        x2apic_phys = !!(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL);
+
     if ( x2apic_phys )
         return &apic_x2apic_phys;
 
--- a/xen/arch/x86/hpet.c
+++ b/xen/arch/x86/hpet.c
@@ -381,6 +381,9 @@ static void __init hpet_fsb_cap_lookup(v
     u32 id;
     unsigned int i, num_chs;
 
+    if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) )
+        return;
+
     id = hpet_read32(HPET_ID);
 
     num_chs = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -32,6 +32,9 @@
 #include <xen/iommu.h>
 #include <xsm/xsm.h>
 
+static s8 __read_mostly use_msi = -1;
+boolean_param("msi", use_msi);
+
 /* bitmap indicate which fixed map is free */
 static DEFINE_SPINLOCK(msix_fixmap_lock);
 static DECLARE_BITMAP(msix_fixmap_pages, FIX_MSIX_MAX_PAGES);
@@ -994,6 +997,9 @@ int pci_prepare_msix(u16 seg, u8 bus, u8
     unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
                                            PCI_CAP_ID_MSIX);
 
+    if ( !use_msi )
+        return 0;
+
     if ( !pos )
         return -ENODEV;
 
@@ -1029,6 +1035,9 @@ int pci_enable_msi(struct msi_info *msi,
 {
     ASSERT(spin_is_locked(&pcidevs_lock));
 
+    if ( !use_msi )
+        return -EPERM;
+
     return  msi->table_base ? __pci_enable_msix(msi, desc) :
         __pci_enable_msi(msi, desc);
 }
@@ -1074,7 +1083,10 @@ int pci_restore_msi_state(struct pci_dev
 
     ASSERT(spin_is_locked(&pcidevs_lock));
 
-    if (!pdev)
+    if ( !use_msi )
+        return -EOPNOTSUPP;
+
+    if ( !pdev )
         return -EINVAL;
 
     ret = xsm_resource_setup_pci(XSM_PRIV, (pdev->seg << 16) |
(pdev->bus << 8) | pdev->devfn);
@@ -1133,7 +1145,7 @@ unsigned int pci_msix_get_table_len(stru
     func = PCI_FUNC(pdev->devfn);
 
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
-    if ( !pos )
+    if ( !pos || !use_msi )
         return 0;
 
     control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
@@ -1170,6 +1182,11 @@ static struct notifier_block msi_cpu_nfb
 
 void __init early_msi_init(void)
 {
+    if ( use_msi < 0 )
+        use_msi = !(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI);
+    if ( !use_msi )
+        return;
+
     register_cpu_notifier(&msi_cpu_nfb);
     if ( msi_cpu_callback(&msi_cpu_nfb, CPU_UP_PREPARE, NULL) &
          NOTIFY_STOP_MASK )
--- a/xen/drivers/passthrough/amd/iommu_acpi.c
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c
@@ -1094,5 +1094,8 @@ int __init amd_iommu_get_ivrs_dev_entrie
 
 int __init amd_iommu_update_ivrs_mapping_acpi(void)
 {
+    if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) )
+        return -EPERM;
+
     return acpi_table_parse(ACPI_SIG_IVRS, parse_ivrs_table);
 }
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -2115,6 +2115,12 @@ int __init intel_vtd_setup(void)
         goto error;
     }
 
+    if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) )
+    {
+        ret = -EPERM;
+        goto error;
+    }
+
     platform_quirks_init();
 
     /* We enable the following features only if they are supported by all VT-d
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
Jan Beulich
2013-Feb-21  13:03 UTC
Re: [PATCH 1/6] ACPI 5.0: Basic support for FADT version 5
>>> On 21.02.13 at 13:58, "Jan Beulich" <JBeulich@suse.com> wrote: > Signed-off-by: Bob Moore <robert.moore@intel.com> > Signed-off-by: Jan Beulich <jbeulich@suse.com>Patch now also attached, if needed by anyone. Jan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
On 21/02/2013 12:49, "Jan Beulich" <JBeulich@suse.com> wrote:> The first three of these are cloned from Linux counterparts, and the > last one adjusts behavior we would have needed for v4 already. > > 1: ACPI 5.0: Basic support for FADT version 5 > 2: ACPI 5.0: Implement hardware-reduced option > 3: ACPICA: Update for larger ACPI 5 FADT size > 4: ACPI: support v5 (reduced HW) sleep interface > 5: x86: honor ACPI indicating absence of CMOS RTC > 6: honor ACPI v4 FADT flags > > Signed-off-by: Jan Beulich <jbeulich@suse.com>Looks alright to me. Acked-by: Keir Fraser <keir@xen.org>> > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel