Volume 2 System Programming (794096), страница 91
Текст из файла (страница 91)
This causes the processor to set the EFER.LMA bit to 1.The instruction following the MOV CR0 that enables paging must be a branch, and both the MOVCR0 and the following branch instruction must be located in an identity-mapped page.14.6.2 Consistency ChecksThe processor performs long-mode consistency checks whenever software attempts to modify any ofthe control bits directly involved in activating long mode (EFER.LME, CR0.PG, and CR4.PAE). Ageneral-protection exception (#GP) occurs when a consistency check fails. Long-mode consistencychecks ensure that the processor does not enter an undefined mode or state that results in unpredictablebehavior.Long-mode consistency checks cause a general-protection exception (#GP) to occur if:Processor Initialization and Long Mode Activation357AMD64 Technology24593—Rev.
3.13—July 2007••An attempt is made to enable or disable long mode while paging is enabled.Long mode is enabled, and an attempt is made to enable paging before enabling physical-addressextensions (PAE).••Long mode is enabled, and an attempt is made to enable paging while CS.L=1.Long mode is active and an attempt is made to disable physical-address extensions (PAE).Table 14-5 summarizes the long-mode consistency checks made during control-bit transitions.Table 14-5. Long-Mode Consistency ChecksControl BitTransitionCheck0→1If (CR0.PG=1) then #GP(0)1→0If (CR0.PG=1) then #GP(0)CR0.PG0→1If ((EFER.LME=1) & (CR4.PAE=0) then #GP(0)If ((EFER.LME=1) & (CS.L=1)) then #GP(0)CR4.PAE1→0If (EFER.LMA=1) then #GP(0)EFER.LME14.6.3 Updating System Descriptor Table ReferencesImmediately after activating long mode, the system-descriptor-table registers (GDTR, LDTR, IDTR,TR) continue to reference legacy descriptor tables.
The tables referenced by these descriptors all residein the lower 4 Gbytes of virtual-address space. After activating long mode, 64-bit operating-systemsoftware should use the LGDT, LLDT, LIDT, and LTR instructions to load the system descriptor-tableregisters with references to the 64-bit versions of the descriptor tables. See “Descriptor Tables” onpage 71 for details on descriptor tables in long mode.Long mode requires 64-bit interrupt-gate descriptors to be stored in the interrupt-descriptor table(IDT). Software must not allow exceptions or interrupts to occur between the time long mode isactivated and the subsequent update of the interrupt-descriptor-table register (IDTR) that establishes areference to the 64-bit IDT.
This is because the IDTR continues to reference a 32-bit IDT immediatelyafter long mode is activated. If an interrupt or exception occurred before updating the IDTR, a legacy32-bit interrupt gate would be referenced and interpreted as a 64-bit interrupt gate, with unpredictableresults.External interrupts can be disabled using the CLI instruction. Non-maskable interrupts (NMI) andsystem-management interrupts (SMI) must be disabled using external hardware.
See “Long-ModeInterrupt Control Transfers” on page 239 for more information on long mode interrupts.14.6.4 Relocating Page-Translation TablesThe long-mode page-translation tables must be located in the first 4 Gbytes of physical-address spacebefore activating long mode. This is necessary because the MOV CR3 instruction used to initialize thepage-map level-4 base address must be executed in legacy mode before activating long mode. Becausethe MOV CR3 is executed in legacy mode, only the low 32 bits of the register are written, which limitsthe location of the page-map level-4 translation table to the low 4 Gbytes of memory.
Software can358Processor Initialization and Long Mode Activation24593—Rev. 3.13—July 2007AMD64 Technologyrelocate the page tables anywhere in physical memory, and re-initialize the CR3 register, after longmode is activated.14.7Leaving Long ModeTo return from long mode to legacy protected mode with paging enabled, software must deactivate anddisable long mode using the following sequence:1. Switch to compatibility mode and place the processor at the highest privilege level (CPL=0).2. Deactivate long mode by clearing CR0.PG to 0.
This causes the processor to clear the LMA bit to0. The MOV CR0 instruction used to disable paging must be located in an identity-mapped page.Once paging is disabled, the processor behaves as a standard 32-bit x86 processor.3. Load CR3 with the physical base-address of the legacy page tables.4. Disable long mode by clearing EFER.LME to 0.5.
Enable legacy page-translation by setting CR0.PG to 1. The instruction following the MOV CR0that enables paging must be a branch, and both the MOV CR0 and the following branchinstruction must be located in an identity-mapped page.14.8Long-Mode Initialization ExampleFollowing is sample code that outlines the steps required to place the processor in long mode.mydata segment para;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; This generic data-segment holds pseudo-descriptors used; by the LGDT and LIDT instructions.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Establish a temporary 32-bit GDT and IDT.;pGDT32 labelfword; Used by LGDT.dwgdt32_limit; GDT limit ...ddgdt32_base; and 32-bit GDT basepIDT32 labelfword; Used by LIDT.dwidt32_limit; IDT limit ...ddidt32_base; and 32-bit IDT base;; Establish a 64-bit GDT and IDT (64-bit linear base; address);pGDT64 labeltbyte; Used by LGDT.dwgdt64_limit; GDT limit ...dqgdt64_base; and 64-bit GDT basepIDT64 labeltbyte; Used by LIDT.Processor Initialization and Long Mode Activation359AMD64 Technology24593—Rev.
3.13—July 2007dwdqidt64_limit; IDT limit ...idt64_base; and 64-bit IDT basemydata ends; end of data segmentcode16 segment para use16 ; 16-bit code segment;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 16-bit code, real mode;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Initialize DS to point to the data segment containing; pGDT32 and PIDT32. Set up a real-mode stack pointer, SS:SP,; in case of interrupts and exceptions.;climovax, seg mydatamovds, axmovax, seg mystackmovss, axmovsp, esp0;; Use CPUID to determine if the processor supports long mode.
;movcpuidcmpjbemovcpuidbtjnc;;;;;;;;;;;;;;;;eax, 80000000h ;;eax, 80000000h ;no_long_mode;eax, 80000001h ;;edx, 29;no_long_mode;Extended-function 8000000h.Is largest extended functionany function > 80000000h?If not, no long mode.Extended-function 8000001h.Now EDX = extended-features flags.Test if long mode is supported.Exit if not supported.Load the 32-bit GDT before entering protected mode.This GDT must contain, at a minimum, the followingdescriptors:1) a CPL=0 16-bit code descriptor for this code segment.2) a CPL=0 32/64-bit code descriptor for the 64-bit code.3) a CPL=0 read/write data segment, usable as a stack(referenced by SS).Load the 32-bit IDT, in case any interrupts or exceptionsoccur after entering protected mode, but before enablinglong mode).Initialize the GDTR and IDTR to point to the temporary32-bit GDT and IDT, respectively.lgdtlidtds:[pGDT32]ds:[pIDT32];; Enable protected mode (CR0.PE=1).;360Processor Initialization and Long Mode Activation24593—Rev.
3.13—July 2007movmov;;;;;;AMD64 Technologyeax, 000000011hcr0, eaxExecute a far jump to turn protected mode on.code16_sel must point to the previously-established 16-bitcode descriptor located in the GDT (for the code currentlybeing executed).db0eah;Far jump...dwoffset now_in_prot;to offset...dwcode16_sel;in current code segment.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; At this point we are in 16-bit protected mode, but long; mode is still disabled.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;now_in_prot:;; Set up the protected-mode stack pointer, SS:ESP.; Stack_sel must point to the previously-established stack; descriptor (read/write data segment), located in the GDT.; Skip setting DS/ES/FS/GS, because we are jumping right to; 64-bit code.;movax, stack_selmovss, axmovesp, esp0;; Enable the 64-bit page-translation-table entries by; setting CR4.PAE=1 (this is _required_ before activating; long mode).
Paging is not enabled until after long mode; is enabled.;moveax, cr4btseax, 5movcr4, eax;; Create the long-mode page tables, and initialize the; 64-bit CR3 (page-table base address) to point to the base; of the PML4 page table. The PML4 page table must be located; below 4 Gbytes because only 32 bits of CR3 are loaded when; the processor is not in 64-bit mode.;moveax, pml4_base ; Pointer to PML4 table (<4GB).movcr3, eax; Initialize CR3 with PML4 base.;; Enable long mode (set EFER.LME=1).;movecx, 0c0000080h; EFER MSR number.rdmsr; Read EFER.btseax, 8; Set LME=1.Processor Initialization and Long Mode Activation361AMD64 Technology24593—Rev. 3.13—July 2007wrmsr; Write EFER.;; Enable paging to activate long mode (set CR0.PG=1);moveax, cr0; Read CR0.btseax, 31; Set PE=1.movcr0, eax; Write CR0.;; At this point, we are in 16-bit compatibility mode; ( LMA=1, CS.L=0, CS.D=0 ).; Now, jump to the 64-bit code segment.
The offset must be; equal to the linear address of the 64-bit entry point,; because 64-bit code is in an unsegmented address space.; The selector points to the 32/64-bit code selector in the; current GDT.;db066hdb0eahddstart64_lineardwcode64_selcode16ends; End of the 16-bit code segment;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Start of 64-bit code;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;code64 para use64start64:; At this point, we're using 64-bit code;; Point the 64-bit RSP register to the stack’s _linear_; address. There is no need to set SS here, because the SS; register is not used in 64-bit mode.;movrsp, stack0_linear;; This LGDT is only needed if the long-mode GDT is to be; located at a linear address above 4 Gbytes. If the long; mode GDT is located at a 32-bit linear address, putting; 64-bit descriptors in the GDT pointed to by [pGDT32] is; just fine.