> On Jun 7, 2016, at 2:59 PM, Brett Stahlman <brettstahl...@gmail.com> wrote:
> 
> d'Oh! Mystery solved. Working through the `info registers' output you
> sent helped me see what was happening. The system I'm working with had
> a buggy printf: in particular, it was parsing but effectively throwing
> away the `l' in a %ld or %lx specifier, so my attempts to print GDT
> entries with %lx were giving misleading results. (Yes, I realize I
> should have been using EFI's Print routine - lesson learned...) I
> apologize for the confusion.
> 
> I appreciate all the pointers from you and Andrew. I feel I have a
> much better handle on all this now.
> 

Brett,

No worries. If you work on firmware long enough Heisenberg like uncertainty 
always seem to strike at some point. 

Thanks,

Andrew Fish 

> Thanks,
> Brett S.
> 
> 
> On Tue, Jun 7, 2016 at 11:15 AM, Laszlo Ersek <ler...@redhat.com> wrote:
>> On 06/07/16 17:35, Andrew Fish wrote:
>>> 
>>>> On Jun 7, 2016, at 8:31 AM, Brett Stahlman <brettstahl...@gmail.com> wrote:
>>>> 
>>>> Ah. I think I may have found the answer to at least part of my
>>>> question, but would appreciate if someone could confirm...
>>>> 
>>>> Section 2.3.4 of the UEFI spec states:
>>>> "Selectors are set to be flat and are otherwise not used."
>>>> 
>>>> Section 3.2.4 of the Intel processor spec (Vol. 3A 3-7) states:
>>>> "In 64-bit mode, segmentation is generally (but not completely)
>>>> disabled, creating a
>>>> flat 64-bit linear-address space... Note that the processor does not
>>>> perform segment limit checks at runtime in 64-bit mode."
>>>> 
>>>> So if I'm reading all this correctly... The value of the fields
>>>> governing the interpretation of the segment limits (e.g., L and D/B)
>>>> are "don't cares" in IA32e 64-bit mode. But what about fields not
>>>> directly related to limit checks: e.g., P (Present) flag, and DPL
>>>> (Descriptor Privilege Level)? Do their values not matter either?
>>>> 
>>> 
>>> Brett,
>>> 
>>> Yes you only need valid entries for segments that are used. If I'm 
>>> remembering correctly you can use the index in the segment registers to map 
>>> to the GDT entry.
>> 
>> Right, here's the output of the "info registers" QEMU monitor command,
>> while standing in the setup browser in OVMF:
>> 
>> RAX=00000000bfdbbcf0 RBX=00000000beafdc84 RCX=00000000bf645a98 
>> RDX=0000000000000000
>> RSI=00000000bff5d588 RDI=00000000bff99fb0 RBP=00000000bff5d350 
>> RSP=00000000bff5d328
>> R8 =0000000000000000 R9 =0000000000000001 R10=0000000000000064 
>> R11=0000000000000040
>> R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 
>> R15=0000000000000000
>> RIP=00000000bfdbbcf1 RFL=00000206 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=1
>> ES =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
>> CS =0038 0000000000000000 ffffffff 00a09b00 DPL=0 CS64 [-RA]
>> SS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
>> DS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
>> FS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
>> GS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
>> LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
>> TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
>> GDT=     00000000bfeea698 00000047
>> IDT=     00000000bf646018 00000fff
>> CR0=80000033 CR2=0000000000000000 CR3=00000000bfefc000 CR4=00000668
>> DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 
>> DR3=0000000000000000
>> DR6=00000000ffff0ff0 DR7=0000000000000400
>> EFER=0000000000000500
>> FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
>> FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
>> FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
>> FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
>> FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
>> XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
>> XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
>> XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
>> XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
>> XMM08=00000000000000000000000000000000 XMM09=00000000000000000000000000000000
>> XMM10=00000000000000000000000000000000 XMM11=00000000000000000000000000000000
>> XMM12=00000000000000000000000000000000 XMM13=00000000000000000000000000000000
>> XMM14=00000000000000000000000000000000 XMM15=00000000000000000000000000000000
>> 
>> CS points to offset 0x38 in the GDT, and the other segment registers
>> (data and stack) all point to the entry at offset 0x30.
>> 
>> * For the DXE Core, the GDT is set up in
>> "MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c":
>> 
>> //
>> // Global Descriptor Table (GDT)
>> //
>> GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT gGdtEntries[] = {
>> /* selector { Global Segment Descriptor                              } */
>> /* 0x00 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, 
>> //null descriptor
>> /* 0x08 */  {{0xffff, 0,  0,  0x2,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, 
>> //linear data segment descriptor
>> /* 0x10 */  {{0xffff, 0,  0,  0xf,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, 
>> //linear code segment descriptor
>> /* 0x18 */  {{0xffff, 0,  0,  0x3,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, 
>> //system data segment descriptor
>> /* 0x20 */  {{0xffff, 0,  0,  0xa,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, 
>> //system code segment descriptor
>> /* 0x28 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, 
>> //spare segment descriptor
>> /* 0x30 */  {{0xffff, 0,  0,  0x2,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, 
>> //system data segment descriptor
>> /* 0x38 */  {{0xffff, 0,  0,  0xa,  1,  0,  1,  0xf,  0,  1, 0,  1,  0}}, 
>> //system code segment descriptor
>> /* 0x40 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, 
>> //spare segment descriptor
>> };
>> 
>> * For the DXE phase, the GDT is set up by the CpuDxe driver, in its
>> entry point. It uses the GDT entries at offsets LINEAR_DATA64_SEL (0x30)
>> and LINEAR_CODE64_SEL (0x38) in the same vein; see
>> InitGlobalDescriptorTable() in "UefiCpuPkg/CpuDxe/CpuGdt.c". And, the
>> byte-limit (= limit in units * unit granularity) is never raised above
>> 4GB, I think.
>> 
>> I believe the settings from this driver are the ones visible in the
>> above "info registers" output.
>> 
>> * In SMM, the GDT is managed by UefiCpuPkg/PiSmmCpuDxeSmm, and it also
>> seems to store the GDT entry that describes the long mode code segment
>> at offset 0x38 (LONG_MODE_CS) in the GDT.
>> 
>> So 0x38 appears to be an edk2 convention for the offset of the
>> descriptor that describes the 64-bit code segment.
>> 
>> Related commit:
>> - https://github.com/tianocore/edk2/commit/0d4c1db81aab
>> 
>> Related emails preceding that commit:
>> - http://thread.gmane.org/gmane.comp.bios.edk2.devel/3509/focus=3568
>> - http://thread.gmane.org/gmane.comp.bios.edk2.devel/3509/focus=3605
>> - http://thread.gmane.org/gmane.comp.bios.edk2.devel/3571
>> 
>> Thanks
>> Laszlo
>> 
>>>> On Tue, Jun 7, 2016 at 8:46 AM, Brett Stahlman <brettstahl...@gmail.com> 
>>>> wrote:
>>>>> Just inside my 64-bit x64 EFI boot loader, I print out the contents of
>>>>> the GDT to see how it was initialized by the firmware. I've tried
>>>>> running the boot loader both in QEMU (OVMF) and VMware ESXi. In both
>>>>> cases, the first 5 descriptors after the leading null descriptor look
>>>>> like this:
>>>>> 
>>>>> 0x000000000000ffff
>>>>> 
>>>>> Note all the leading zeroes: in particular, flags such as D/B and L
>>>>> being clear seem to suggest a GDT that's inappropriate for 64-bit long
>>>>> mode. I've verified by looking at CR* registers and such that the
>>>>> firmware has indeed placed me in IA32e "long mode" with identity
>>>>> paging. This is what I would expect, in light of section 2.3.4 in the
>>>>> UEFI spec. But why does the GDT have all leading 0's?
>>>>> 
>>>>> Thanks,
>>>>> Brett S.
>>>> _______________________________________________
>>>> edk2-devel mailing list
>>>> edk2-devel@lists.01.org
>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>> 
>>> _______________________________________________
>>> edk2-devel mailing list
>>> edk2-devel@lists.01.org
>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>> 
>> 

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to