static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) { static u32 acpi_shutdown_map[ACPI_S_STATE_COUNT] = { /* S0,1,2: */ -1, -1, -1, /* S3: */ TB_SHUTDOWN_S3, /* S4: */ TB_SHUTDOWN_S4, /* S5: */ TB_SHUTDOWN_S5 }; if (!tboot_enabled()) return 0; tboot_copy_fadt(&acpi_gbl_FADT); tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control; tboot->acpi_sinfo.pm1b_cnt_val = pm1b_control; /* we always use the 32b wakeup vector */ tboot->acpi_sinfo.vector_width = 32; if (sleep_state >= ACPI_S_STATE_COUNT || acpi_shutdown_map[sleep_state] == -1) { pr_warning("unsupported sleep state 0x%x\n", sleep_state); return -1; } tboot_shutdown(acpi_shutdown_map[sleep_state]); return 0; }
void tboot_shutdown(u32 shutdown_type) { void (*shutdown)(void); if (!tboot_enabled()) return; /* * if we're being called before the 1:1 mapping is set up then just * return and let the normal shutdown happen; this should only be * due to very early panic() */ if (!tboot_pg_dir) return; /* if this is S3 then set regions to MAC */ if (shutdown_type == TB_SHUTDOWN_S3) if (tboot_setup_sleep()) return; tboot->shutdown_type = shutdown_type; switch_to_tboot_pt(); shutdown = (void(*)(void))(unsigned long)tboot->shutdown_entry; shutdown(); /* should not reach here */ while (1) halt(); }
static int tboot_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b) { if (!tboot_enabled()) return 0; pr_warning("tboot is not able to suspend on platforms with reduced hardware sleep (ACPIv5)"); return -ENODEV; }
static __init int tboot_late_init(void) { if (!tboot_enabled()) return 0; atomic_set(&ap_wfs_count, 0); register_hotcpu_notifier(&tboot_cpu_notifier); acpi_os_set_prepare_sleep(&tboot_sleep); return 0; }
int tboot_force_iommu(void) { if (!tboot_enabled()) return 0; if (no_iommu || swiotlb || dmar_disabled) pr_warning("Forcing Intel-IOMMU to enabled\n"); dmar_disabled = 0; #ifdef CONFIG_SWIOTLB swiotlb = 0; #endif no_iommu = 0; return 1; }
struct acpi_table_header *tboot_get_dmar_table(struct acpi_table_header *dmar_tbl) { void *heap_base, *heap_ptr, *config; if (!tboot_enabled()) return dmar_tbl; /* * ACPI tables may not be DMA protected by tboot, so use DMAR copy * SINIT saved in SinitMleData in TXT heap (which is DMA protected) */ /* map config space in order to get heap addr */ config = ioremap(TXT_PUB_CONFIG_REGS_BASE, NR_TXT_CONFIG_PAGES * PAGE_SIZE); if (!config) return NULL; /* now map TXT heap */ heap_base = ioremap(*(u64 *)(config + TXTCR_HEAP_BASE), *(u64 *)(config + TXTCR_HEAP_SIZE)); iounmap(config); if (!heap_base) return NULL; /* walk heap to SinitMleData */ /* skip BiosData */ heap_ptr = heap_base + *(u64 *)heap_base; /* skip OsMleData */ heap_ptr += *(u64 *)heap_ptr; /* skip OsSinitData */ heap_ptr += *(u64 *)heap_ptr; /* now points to SinitMleDataSize; set to SinitMleData */ heap_ptr += sizeof(u64); /* get addr of DMAR table */ dmar_tbl = (struct acpi_table_header *)(heap_ptr + ((struct sinit_mle_data *)heap_ptr)->vtd_dmars_off - sizeof(u64)); /* don't unmap heap because dmar.c needs access to this */ return dmar_tbl; }
static __init int tboot_late_init(void) { if (!tboot_enabled()) return 0; tboot_create_trampoline(); atomic_set(&ap_wfs_count, 0); cpuhp_setup_state(CPUHP_AP_X86_TBOOT_DYING, "AP_X86_TBOOT_DYING", NULL, tboot_dying_cpu); #ifdef CONFIG_DEBUG_FS debugfs_create_file("tboot_log", S_IRUSR, arch_debugfs_dir, NULL, &tboot_log_fops); #endif acpi_os_set_prepare_sleep(&tboot_sleep); acpi_os_set_prepare_extended_sleep(&tboot_extended_sleep); return 0; }
static __init int tboot_late_init(void) { if (!tboot_enabled()) return 0; tboot_create_trampoline(); atomic_set(&ap_wfs_count, 0); register_hotcpu_notifier(&tboot_cpu_notifier); #ifdef CONFIG_DEBUG_FS debugfs_create_file("tboot_log", S_IRUSR, arch_debugfs_dir, NULL, &tboot_log_fops); #endif acpi_os_set_prepare_sleep(&tboot_sleep); acpi_os_set_prepare_extended_sleep(&tboot_extended_sleep); return 0; }
void tboot_shutdown(u32 shutdown_type) { void (*shutdown)(void); if (!tboot_enabled()) return; /* if this is S3 then set regions to MAC */ if (shutdown_type == TB_SHUTDOWN_S3) if (tboot_setup_sleep()) return; tboot->shutdown_type = shutdown_type; switch_to_tboot_pt(); shutdown = (void(*)(void))(unsigned long)tboot->shutdown_entry; shutdown(); /* should not reach here */ while (1) halt(); }
static int tboot_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b) { if (!tboot_enabled()) return 0; pr_warning("tboot is not able to suspend on platforms w