Cihula, Joseph
2009-Jan-29 08:55 UTC
[Xen-devel] [PATCH v2] txt: 2/5 - 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> diff -r ecb74962f6f4 -r 9ba8aecc3a15 xen/arch/x86/acpi/power.c --- a/xen/arch/x86/acpi/power.c Wed Jan 28 21:56:22 2009 -0800 +++ b/xen/arch/x86/acpi/power.c Wed Jan 28 22:09:02 2009 -0800 @@ -129,19 +129,13 @@ static void acpi_sleep_prepare(u32 state wakeup_vector_va = __acpi_map_table( acpi_sinfo.wakeup_vector, sizeof(uint64_t)); - 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); - } - 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); + + /* tboot will set resume vector itself (when it is safe to do so) */ + if ( !tboot_in_measured_env() ) { + if ( acpi_sinfo.vector_width == 32 ) + *(uint32_t *)wakeup_vector_va = (uint32_t)bootsym_phys(wakeup_start); + else + *(uint64_t *)wakeup_vector_va = (uint64_t)bootsym_phys(wakeup_start); } } @@ -279,37 +273,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 */ diff -r ecb74962f6f4 -r 9ba8aecc3a15 xen/arch/x86/tboot.c --- a/xen/arch/x86/tboot.c Wed Jan 28 21:56:22 2009 -0800 +++ b/xen/arch/x86/tboot.c Wed Jan 28 22:09:02 2009 -0800 @@ -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_ty 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); diff -r ecb74962f6f4 -r 9ba8aecc3a15 xen/include/asm-x86/tboot.h --- a/xen/include/asm-x86/tboot.h Wed Jan 28 21:56:22 2009 -0800 +++ b/xen/include/asm-x86/tboot.h Wed Jan 28 22:09:02 2009 -0800 @@ -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; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel