mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
tboot: ACPI Generic Address Structure for tboot shutdown
New versions of tboot support ACPI GAS (Generic Address Structure) for handling sleep states. This required a change to the tboot_shared_t data structure that is not backwards compatible. This patch requires that new version makes use of GAS when invoking tboot on shutdown. Signed-off-by: Shane Wang <shane.wang@intel.com> Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>
This commit is contained in:
1 parent
a2e1511237
commit
4d41b00276
3 files changed
+84
-74
No files matched your search
+45
-40
@@ -129,20 +129,15 @@ static void acpi_sleep_prepare(u32 state)
|
||||
|
||||
wakeup_vector_va = __acpi_map_table(
|
||||
acpi_sinfo.wakeup_vector, sizeof(uint64_t));
|
||||
|
||||
/* TBoot will set resume vector itself (when it is safe to do so). */
|
||||
if ( tboot_in_measured_env() )
|
||||
return;
|
||||
|
||||
if ( acpi_sinfo.vector_width == 32 )
|
||||
{
|
||||
*(uint32_t *)wakeup_vector_va =
|
||||
tboot_in_measured_env() ?
|
||||
(uint32_t)g_tboot_shared->s3_tb_wakeup_entry :
|
||||
(uint32_t)bootsym_phys(wakeup_start);
|
||||
}
|
||||
*(uint32_t *)wakeup_vector_va = bootsym_phys(wakeup_start);
|
||||
else
|
||||
{
|
||||
*(uint64_t *)wakeup_vector_va =
|
||||
tboot_in_measured_env() ?
|
||||
(uint64_t)g_tboot_shared->s3_tb_wakeup_entry :
|
||||
(uint64_t)bootsym_phys(wakeup_start);
|
||||
}
|
||||
*(uint64_t *)wakeup_vector_va = bootsym_phys(wakeup_start);
|
||||
}
|
||||
|
||||
static void acpi_sleep_post(u32 state) {}
|
||||
@@ -279,37 +274,47 @@ static int acpi_get_wake_status(void)
|
||||
|
||||
static void tboot_sleep(u8 sleep_state)
|
||||
{
|
||||
uint32_t shutdown_type;
|
||||
uint32_t shutdown_type;
|
||||
|
||||
g_tboot_shared->acpi_sinfo.pm1a_cnt =
|
||||
(uint16_t)acpi_sinfo.pm1a_cnt_blk.address;
|
||||
g_tboot_shared->acpi_sinfo.pm1b_cnt =
|
||||
(uint16_t)acpi_sinfo.pm1b_cnt_blk.address;
|
||||
g_tboot_shared->acpi_sinfo.pm1a_evt =
|
||||
(uint16_t)acpi_sinfo.pm1a_evt_blk.address;
|
||||
g_tboot_shared->acpi_sinfo.pm1b_evt =
|
||||
(uint16_t)acpi_sinfo.pm1b_evt_blk.address;
|
||||
g_tboot_shared->acpi_sinfo.pm1a_cnt_val = acpi_sinfo.pm1a_cnt_val;
|
||||
g_tboot_shared->acpi_sinfo.pm1b_cnt_val = acpi_sinfo.pm1b_cnt_val;
|
||||
#define TB_COPY_GAS(tbg, g) \
|
||||
tbg.space_id = g.space_id; \
|
||||
tbg.bit_width = g.bit_width; \
|
||||
tbg.bit_offset = g.bit_offset; \
|
||||
tbg.access_width = g.access_width; \
|
||||
tbg.address = g.address;
|
||||
|
||||
switch ( sleep_state )
|
||||
{
|
||||
case ACPI_STATE_S3:
|
||||
shutdown_type = TB_SHUTDOWN_S3;
|
||||
g_tboot_shared->s3_k_wakeup_entry =
|
||||
(uint32_t)bootsym_phys(wakeup_start);
|
||||
break;
|
||||
case ACPI_STATE_S4:
|
||||
shutdown_type = TB_SHUTDOWN_S4;
|
||||
break;
|
||||
case ACPI_STATE_S5:
|
||||
shutdown_type = TB_SHUTDOWN_S5;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
/* sizes are not same (due to packing) so copy each one */
|
||||
TB_COPY_GAS(g_tboot_shared->acpi_sinfo.pm1a_cnt_blk,
|
||||
acpi_sinfo.pm1a_cnt_blk);
|
||||
TB_COPY_GAS(g_tboot_shared->acpi_sinfo.pm1b_cnt_blk,
|
||||
acpi_sinfo.pm1b_cnt_blk);
|
||||
TB_COPY_GAS(g_tboot_shared->acpi_sinfo.pm1a_evt_blk,
|
||||
acpi_sinfo.pm1a_evt_blk);
|
||||
TB_COPY_GAS(g_tboot_shared->acpi_sinfo.pm1b_evt_blk,
|
||||
acpi_sinfo.pm1b_evt_blk);
|
||||
g_tboot_shared->acpi_sinfo.pm1a_cnt_val = acpi_sinfo.pm1a_cnt_val;
|
||||
g_tboot_shared->acpi_sinfo.pm1b_cnt_val = acpi_sinfo.pm1b_cnt_val;
|
||||
g_tboot_shared->acpi_sinfo.wakeup_vector = acpi_sinfo.wakeup_vector;
|
||||
g_tboot_shared->acpi_sinfo.vector_width = acpi_sinfo.vector_width;
|
||||
g_tboot_shared->acpi_sinfo.kernel_s3_resume_vector =
|
||||
bootsym_phys(wakeup_start);
|
||||
|
||||
tboot_shutdown(shutdown_type);
|
||||
switch ( sleep_state )
|
||||
{
|
||||
case ACPI_STATE_S3:
|
||||
shutdown_type = TB_SHUTDOWN_S3;
|
||||
break;
|
||||
case ACPI_STATE_S4:
|
||||
shutdown_type = TB_SHUTDOWN_S4;
|
||||
break;
|
||||
case ACPI_STATE_S5:
|
||||
shutdown_type = TB_SHUTDOWN_S5;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
tboot_shutdown(shutdown_type);
|
||||
}
|
||||
|
||||
/* System is really put into sleep state by this stub */
|
||||
|
||||
+12
-19
@@ -30,23 +30,24 @@ void __init tboot_probe(void)
|
||||
/* Map and check for tboot UUID. */
|
||||
set_fixmap(FIX_TBOOT_SHARED_BASE, p_tboot_shared);
|
||||
tboot_shared = (tboot_shared_t *)fix_to_virt(FIX_TBOOT_SHARED_BASE);
|
||||
if ( tboot_shared == NULL )
|
||||
return;
|
||||
if ( memcmp(&tboot_shared_uuid, (uuid_t *)tboot_shared, sizeof(uuid_t)) )
|
||||
return;
|
||||
|
||||
/* new tboot_shared (w/ GAS support) is not backwards compatible */
|
||||
if ( tboot_shared->version < 3 ) {
|
||||
printk("unsupported version of tboot (%u)\n", tboot_shared->version);
|
||||
return;
|
||||
}
|
||||
|
||||
g_tboot_shared = tboot_shared;
|
||||
printk("TBOOT: found shared page at phys addr %lx:\n", p_tboot_shared);
|
||||
printk(" version: %d\n", tboot_shared->version);
|
||||
printk(" log_addr: 0x%08x\n", tboot_shared->log_addr);
|
||||
printk(" shutdown_entry: 0x%08x\n", tboot_shared->shutdown_entry);
|
||||
printk(" shutdown_type: %d\n", tboot_shared->shutdown_type);
|
||||
printk(" s3_tb_wakeup_entry: 0x%08x\n", tboot_shared->s3_tb_wakeup_entry);
|
||||
printk(" s3_k_wakeup_entry: 0x%08x\n", tboot_shared->s3_k_wakeup_entry);
|
||||
printk(" &acpi_sinfo: 0x%p\n", &tboot_shared->acpi_sinfo);
|
||||
if ( tboot_shared->version >= 0x02 )
|
||||
{
|
||||
printk(" tboot_base: 0x%08x\n", tboot_shared->tboot_base);
|
||||
printk(" tboot_size: 0x%x\n", tboot_shared->tboot_size);
|
||||
}
|
||||
printk(" tboot_base: 0x%08x\n", tboot_shared->tboot_base);
|
||||
printk(" tboot_size: 0x%x\n", tboot_shared->tboot_size);
|
||||
}
|
||||
|
||||
void tboot_shutdown(uint32_t shutdown_type)
|
||||
@@ -59,16 +60,8 @@ void tboot_shutdown(uint32_t shutdown_type)
|
||||
local_irq_disable();
|
||||
|
||||
/* Create identity map for tboot shutdown code. */
|
||||
if ( g_tboot_shared->version >= 0x02 )
|
||||
{
|
||||
map_base = PFN_DOWN(g_tboot_shared->tboot_base);
|
||||
map_size = PFN_UP(g_tboot_shared->tboot_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
map_base = 0;
|
||||
map_size = PFN_UP(0xa0000);
|
||||
}
|
||||
map_base = PFN_DOWN(g_tboot_shared->tboot_base);
|
||||
map_size = PFN_UP(g_tboot_shared->tboot_size);
|
||||
|
||||
err = map_pages_to_xen(map_base << PAGE_SHIFT, map_base, map_size,
|
||||
__PAGE_HYPERVISOR);
|
||||
|
||||
+27
-15
@@ -37,7 +37,11 @@
|
||||
#ifndef __TBOOT_H__
|
||||
#define __TBOOT_H__
|
||||
|
||||
typedef struct __attribute__ ((__packed__)) {
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__ ((packed))
|
||||
#endif
|
||||
|
||||
typedef struct __packed {
|
||||
uint32_t data1;
|
||||
uint16_t data2;
|
||||
uint16_t data3;
|
||||
@@ -47,28 +51,36 @@ typedef struct __attribute__ ((__packed__)) {
|
||||
|
||||
/* used to communicate between tboot and the launched kernel (i.e. Xen) */
|
||||
|
||||
typedef struct __attribute__ ((__packed__)) {
|
||||
uint16_t pm1a_cnt;
|
||||
uint16_t pm1b_cnt;
|
||||
uint16_t pm1a_evt;
|
||||
uint16_t pm1b_evt;
|
||||
/* GAS - Generic Address Structure (ACPI 2.0+) */
|
||||
typedef struct __packed {
|
||||
uint8_t space_id;
|
||||
uint8_t bit_width;
|
||||
uint8_t bit_offset;
|
||||
uint8_t access_width;
|
||||
uint64_t address;
|
||||
} tboot_acpi_generic_address_t;
|
||||
|
||||
typedef struct __packed {
|
||||
tboot_acpi_generic_address_t pm1a_cnt_blk;
|
||||
tboot_acpi_generic_address_t pm1b_cnt_blk;
|
||||
tboot_acpi_generic_address_t pm1a_evt_blk;
|
||||
tboot_acpi_generic_address_t pm1b_evt_blk;
|
||||
uint16_t pm1a_cnt_val;
|
||||
uint16_t pm1b_cnt_val;
|
||||
} tboot_acpi_sleep_info;
|
||||
uint64_t wakeup_vector;
|
||||
uint32_t vector_width;
|
||||
uint64_t kernel_s3_resume_vector;
|
||||
} tboot_acpi_sleep_info_t;
|
||||
|
||||
typedef struct __attribute__ ((__packed__)) {
|
||||
/* version 0x01+ fields: */
|
||||
typedef struct __packed {
|
||||
/* version 3+ fields: */
|
||||
uuid_t uuid; /* {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} */
|
||||
uint32_t version; /* Version number: 0x01, 0x02, ... */
|
||||
uint32_t version; /* Version number; currently supports 0.3 */
|
||||
uint32_t log_addr; /* physical addr of tb_log_t log */
|
||||
uint32_t shutdown_entry; /* entry point for tboot shutdown */
|
||||
uint32_t shutdown_type; /* type of shutdown (TB_SHUTDOWN_*) */
|
||||
uint32_t s3_tb_wakeup_entry;/* entry point for tboot s3 wake up */
|
||||
uint32_t s3_k_wakeup_entry; /* entry point for xen s3 wake up */
|
||||
tboot_acpi_sleep_info
|
||||
tboot_acpi_sleep_info_t
|
||||
acpi_sinfo; /* where kernel put acpi sleep info in Sx */
|
||||
uint8_t reserved[52]; /* this pad is for compat with old field */
|
||||
/* version 0x02+ fields: */
|
||||
uint32_t tboot_base; /* starting addr for tboot */
|
||||
uint32_t tboot_size; /* size of tboot */
|
||||
} tboot_shared_t;
|
||||
|
||||