Bladeren bron

x86, suspend, acpi: correct and add comments about Big Real Mode

Explain that we set up the descriptors for Big Real Mode, and why we
do so.  In particular, one system that is known to fail without it is
the Lenovo X61.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
H. Peter Anvin 17 jaren geleden
bovenliggende
commit
065cb3dfe2
1 gewijzigde bestanden met toevoegingen van 11 en 2 verwijderingen
  1. 11 2
      arch/x86/kernel/acpi/sleep.c

+ 11 - 2
arch/x86/kernel/acpi/sleep.c

@@ -60,16 +60,25 @@ int acpi_save_state_mem(void)
 	header->video_mode = saved_video_mode;
 	header->video_mode = saved_video_mode;
 
 
 	header->wakeup_jmp_seg = acpi_wakeup_address >> 4;
 	header->wakeup_jmp_seg = acpi_wakeup_address >> 4;
+
+	/*
+	 * Set up the wakeup GDT.  We set these up as Big Real Mode,
+	 * that is, with limits set to 4 GB.  At least the Lenovo
+	 * Thinkpad X61 is known to need this for the video BIOS
+	 * initialization quirk to work; this is likely to also
+	 * be the case for other laptops or integrated video devices.
+	 */
+
 	/* GDT[0]: GDT self-pointer */
 	/* GDT[0]: GDT self-pointer */
 	header->wakeup_gdt[0] =
 	header->wakeup_gdt[0] =
 		(u64)(sizeof(header->wakeup_gdt) - 1) +
 		(u64)(sizeof(header->wakeup_gdt) - 1) +
 		((u64)(acpi_wakeup_address +
 		((u64)(acpi_wakeup_address +
 			((char *)&header->wakeup_gdt - (char *)acpi_realmode))
 			((char *)&header->wakeup_gdt - (char *)acpi_realmode))
 				<< 16);
 				<< 16);
-	/* GDT[1]: real-mode-like code segment */
+	/* GDT[1]: big real mode-like code segment */
 	header->wakeup_gdt[1] =
 	header->wakeup_gdt[1] =
 		GDT_ENTRY(0x809b, acpi_wakeup_address, 0xfffff);
 		GDT_ENTRY(0x809b, acpi_wakeup_address, 0xfffff);
-	/* GDT[2]: real-mode-like data segment */
+	/* GDT[2]: big real mode-like data segment */
 	header->wakeup_gdt[2] =
 	header->wakeup_gdt[2] =
 		GDT_ENTRY(0x8093, acpi_wakeup_address, 0xfffff);
 		GDT_ENTRY(0x8093, acpi_wakeup_address, 0xfffff);