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