Set TR and LDTR when entering protected mode
authorH. Peter Anvin <hpa@zytor.com>
Thu, 11 Oct 2007 21:47:23 +0000 (14:47 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 11 Oct 2007 21:47:23 +0000 (14:47 -0700)
Intel's VT daftly requires TR and LDTR to have valid protected-mode
values in order to kick in.  Thus, give it at least a valid chunk of
memory for the TR and a null selector for the LDTR.

bcopy32.inc
com32.inc

index 4eef874..7e3ac0f 100644 (file)
@@ -40,17 +40,22 @@ __bcopy_start:
 bcopy_gdt:     dw bcopy_gdt_size-1     ; Null descriptor - contains GDT
                dd bcopy_gdt            ; pointer for LGDT instruction
                dw 0
-               dd 0000ffffh            ; Code segment, use16, readable,
+               dd 0000ffffh            ; 08h Code segment, use16, readable,
                dd 00009b00h            ; present, dpl 0, cover 64K
-               dd 0000ffffh            ; Data segment, use16, read/write,
+               dd 0000ffffh            ; 10h Data segment, use16, read/write,
                dd 008f9300h            ; present, dpl 0, cover all 4G
-               dd 0000ffffh            ; Data segment, use16, read/write,
+               dd 0000ffffh            ; 18h Data segment, use16, read/write,
                dd 00009300h            ; present, dpl 0, cover 64K
-               ; The rest are used for COM32 only
-               dd 0000ffffh            ; Code segment, use32, readable,
+               ; The next two segments are used for COM32 only
+               dd 0000ffffh            ; 20h Code segment, use32, readable,
                dd 00cf9b00h            ; present, dpl 0, cover all 4G
-               dd 0000ffffh            ; Data segment, use32, read/write,
+               dd 0000ffffh            ; 28h Data segment, use32, read/write,
                dd 00cf9300h            ; present, dpl 0, cover all 4G
+               ; TSS segment to keep Intel VT happy.  Intel VT is
+               ; unhappy about anything that doesn't smell like a
+               ; full-blown 32-bit OS.
+               dw 104-1, DummyTSS      ; 30h 32-bit task state segment
+               dd 00008900h            ; present, dpl 0, 104 bytes @DummyTSS
 bcopy_gdt_size:        equ $-bcopy_gdt
 
 ;
@@ -100,11 +105,16 @@ bcopy:            push eax
                ; ss is NOT zero in general, so we have to preserve
                ; the value.
 
-               mov ax,18h              ; Real-mode-like segment
+               mov al,18h              ; Real-mode-like segment
                mov fs,ax
                mov gs,ax
                mov ss,ax
 
+               mov al,30h              ; Intel VT really doesn't want
+               ltr ax                  ; an invalid TR and LDTR, so give
+               xor ax,ax               ; it something that it can use...
+               lldt ax                 ; (sigh)
+
                cmp esi,-1
                je .bzero
 
@@ -535,4 +545,13 @@ A20Tries   resb 1                  ; Times until giving up on A20
 ; For the PM case, it is 9*5 = 45 bytes long; for the RM case it is
 ; 8*6 to set the GPRs, 6*5 to set the segment registers (including a dummy
 ; setting of CS), 5 bytes to set CS:IP, for a total of 83 bytes.
+;
 TrampolineBuf  resb 83                 ; Shuffle and boot trampoline
+
+;
+; Space for a dummy task state segment.  It should never be actually
+; accessed, but just in case it is, point to a chunk of memory not used
+; for anything real.
+;
+               alignb 4
+DummyTSS       resb 104
index fdf8434..fb302ae 100644 (file)
--- a/com32.inc
+++ b/com32.inc
@@ -94,12 +94,16 @@ com32_enter_pm:
                xor eax,eax             ; Available for future use...
                mov fs,eax
                mov gs,eax
+               lldt ax
 
                mov al,28h              ; Set up data segments
                mov es,eax
                mov ds,eax
                mov ss,eax
 
+               mov al,30h              ; Be nice to Intel's VT by
+               ltr ax                  ; giving it a valid TR
+
                mov esp,[PMESP]         ; Load protmode %esp if available
                jmp ebx                 ; Go to where we need to go