For the iretq versions of CpuAsm, you have to use SS. I don't see anywhere in the patch that you have guaranteed that SS has the correct selector for the GDT that was just loaded prior to the call to SetCodeSelector. Since in this case selector 0x0008 happens to be the same in the original and new GDTs, you don't see an error. But, that should probably be fixed.
BTW, I vote for the iretq versions of SetCodeSelector, obviously. Thanks, Garrett Kirkendall -----Original Message----- From: Konstantin Filatov [mailto:kfila...@parallels.com] Sent: Thursday, January 17, 2013 5:17 AM To: edk2-devel@lists.sourceforge.net Subject: Re: [edk2] Make the upper memory usable. Hello, this patch for CpuDxe has been developed further, so now I send an actual version of it. I still think it will useful for all you. Best regards, Konstantin Filatov Really this is a patch set, and I didn't merge it into a large patch applicable to the actual edk2-source. I have a reason for it. In this way this patch set will easier to understand, and it will scrutinized surely before a commit. The beginning of this patch set. fixed SetCodeSelector --- CpuDxe/X64/CpuAsm.S +++ CpuDxe/X64/CpuAsm.S @@ -51,13 +51,13 @@ ASM_PFX(InitializeExternalVectorTablePtr): #------------------------------------------------------------------------------ ASM_GLOBAL ASM_PFX(SetCodeSelector) ASM_PFX(SetCodeSelector): - subq $0x10, %rsp + subq $0x14, %rsp leaq L_setCodeSelectorLongJump(%rip), %rax movq %rax, (%rsp) - movw %cx, 4(%rsp) - .byte 0xFF, 0x2C, 0x24 # jmp (%rsp) note:fword jmp + movw %cx, 8(%rsp) + .byte 0x48, 0xFF, 0x2C, 0x24 # REX.W jmp (%rsp) note:fword jmp L_setCodeSelectorLongJump: - addq $0x10, %rsp + addq $0x14, %rsp ret #------------------------------------------------------------------------------ -- fixed a bug in CpuDxe in EFI IA32_DESCRIPTOR can have 64bit field Base regardless the name. --- CpuDxe/CpuDxe.c +++ CpuDxe/CpuDxe.c @@ -1192,7 +1192,7 @@ InitInterruptDescriptorTable ( // IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16); IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16); - IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1)); + IdtPtr->Base = (UINTN)(VOID*) gIdtTable; IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1); AsmWriteIdtr (IdtPtr); -- --- CpuDxe/CpuGdt.c +++ CpuDxe/CpuGdt.c @@ -194,7 +194,7 @@ InitGlobalDescriptorTable ( // // Write GDT register // - gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt; + gdtPtr.Base = (UINTN)(VOID*) gdt; gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1); AsmWriteGdtr (&gdtPtr); -- refactoring RestoreInterrupt...() in EFI --- CpuDxe/CpuDxe.c +++ CpuDxe/CpuDxe.c @@ -1110,13 +1110,9 @@ RestoreInterruptDescriptorTableHandlerAddress ( IN UINTN Index ) { - if (Index < mOrigIdtEntryCount) { - gIdtTable[Index].Bits.OffsetLow = mOrigIdtEntry[Index].Bits.OffsetLow; - gIdtTable[Index].Bits.OffsetHigh = mOrigIdtEntry[Index].Bits.OffsetHigh; -#if defined (MDE_CPU_X64) - gIdtTable[Index].Bits.OffsetUpper = mOrigIdtEntry[Index].Bits.OffsetUpper; -#endif - } + if (Index >= mOrigIdtEntryCount) + return; + CopyMem(gIdtTable + Index, mOrigIdtEntry + Index, sizeof(gIdtTable[Index])); } /** -- Fixed setting exception routines vector in EFI for on x64. --- CpuDxe/X64/CpuAsm.S +++ CpuDxe/X64/CpuAsm.S @@ -38,8 +38,8 @@ ExternalVectorTablePtr: ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr) ASM_PFX(InitializeExternalVectorTablePtr): - lea ExternalVectorTablePtr(%rip), %rax # save vector number - mov %rcx, (%rax) + leaq ExternalVectorTablePtr(%rip), %rax # save vector number + movq %rcx, (%rax) ret @@ -249,7 +249,7 @@ CommonInterruptEntry_al_0000: #; call into exception handler movq 8(%rbp), %rcx leaq ExternalVectorTablePtr(%rip), %rax - movl (%eax), %eax + movq (%rax), %rax movq (%rax,%rcx,8), %rax orq %rax, %rax # NULL? -- ported patch "fixed SetCodeSel() in EFI for x64" to MASM to allow build of EFI on Win32. --- CpuDxe/X64/CpuAsm.asm +++ CpuDxe/X64/CpuAsm.asm @@ -44,13 +44,19 @@ InitializeExternalVectorTablePtr ENDP ; ); ;------------------------------------------------------------------------------ SetCodeSelector PROC PUBLIC - sub rsp, 0x10 + sub rsp, 0x14 lea rax, setCodeSelectorLongJump mov [rsp], rax - mov [rsp+4], cx + mov [rsp+8], cx + ;* I'm not sure how to encode this. We need to jmp [esp], where in esp there is + ;* w16(selector):q64(address). + ;* in gcc version this is encoded as 48 ff 2c 24 [ rex.W ljmpq *(%esp) ] + ;* but in VC jmp qword ptr [rsp] generates code ff 24 24 [ jmpq *(%esp) ] + ;* so I've just inserted db 0x48 to emit REX.W and get original 48 ff 2c 24 + db 0x48 ; emit REX.W jmp fword ptr [rsp] setCodeSelectorLongJump: - add rsp, 0x10 + add rsp, 0x14 ret SetCodeSelector ENDP -- On AMD x64 JMP FAR cannot use 64-bit offset (see 24594, p. 137) and so cannot jump to code which is out of 32-bit space. Using IRETQ fixes this limitation. --- CpuDxe/X64/CpuAsm.S +++ CpuDxe/X64/CpuAsm.S @@ -51,13 +51,20 @@ ASM_PFX(InitializeExternalVectorTablePtr): #------------------------------------------------------------------------------ ASM_GLOBAL ASM_PFX(SetCodeSelector) ASM_PFX(SetCodeSelector): - subq $0x14, %rsp - leaq L_setCodeSelectorLongJump(%rip), %rax - movq %rax, (%rsp) - movw %cx, 8(%rsp) - .byte 0x48, 0xFF, 0x2C, 0x24 # REX.W jmp (%rsp) note:fword jmp + movq %ss, %rax + pushq %rax + movq %rsp, %rax + addq $8, %rax + pushq %rax + leaq L_setCodeSelectorLongJump(%rip), %rax + andq $0xffff, %rcx + pushfq + pushq %rcx + pushq %rax + # iretq is used, because this method of changing 32-bit code selector to 64-bit + # will work correctly on both Intel and AMD. + iretq L_setCodeSelectorLongJump: - addq $0x14, %rsp ret #------------------------------------------------------------------------------ -- --- CpuDxe/X64/CpuAsm.asm +++ CpuDxe/X64/CpuAsm.asm @@ -44,19 +44,20 @@ InitializeExternalVectorTablePtr ENDP ; ); ;------------------------------------------------------------------------------ SetCodeSelector PROC PUBLIC - sub rsp, 0x14 + mov rax, ss + push rax + mov rax, rsp + add rax, 8 + push rax lea rax, setCodeSelectorLongJump - mov [rsp], rax - mov [rsp+8], cx - ;* I'm not sure how to encode this. We need to jmp [esp], where in esp there is - ;* w16(selector):q64(address). - ;* in gcc version this is encoded as 48 ff 2c 24 [ rex.W ljmpq *(%esp) ] - ;* but in VC jmp qword ptr [rsp] generates code ff 24 24 [ jmpq *(%esp) ] - ;* so I've just inserted db 0x48 to emit REX.W and get original 48 ff 2c 24 - db 0x48 ; emit REX.W - jmp fword ptr [rsp] + and rcx, 0xffff + pushfq + push rcx + push rax + ; iretq is used, because this method of changing 32-bit code selector to 64-bit + ; will work correctly on both Intel and AMD. + iretq setCodeSelectorLongJump: - add rsp, 0x14 ret SetCodeSelector ENDP -- The end of this patch set. On 11/14/2012 02:40 PM, Konstantin Filatov wrote: > Hello, > > In order to make the upper memory usable, it has to be "tested". This > patch works for me and seems useful for TianoCore. > > This patch resolves a problem of 4gb limit. > > Best regards, > Konstantin Filatov > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Konstantin Filatov <kfila...@parallels.com> > > Index: UefiCpuPkg/CpuDxe/X64/CpuAsm.S > =================================================================== > --- UefiCpuPkg/CpuDxe/X64/CpuAsm.S (revision 13937) > +++ UefiCpuPkg/CpuDxe/X64/CpuAsm.S (working copy) > @@ -45,13 +45,13 @@ > > #--------------------------------------------------------------------- > --------- > > ASM_GLOBAL ASM_PFX(SetCodeSelector) > ASM_PFX(SetCodeSelector): > - subq $0x10, %rsp > + subq $0x14, %rsp > leaq L_setCodeSelectorLongJump(%rip), %rax > movq %rax, (%rsp) > - movw %cx, 4(%rsp) > - .byte 0xFF, 0x2C, 0x24 # jmp (%rsp) note:fword jmp > + movw %cx, 8(%rsp) > + .byte 0x48, 0xFF, 0x2C, 0x24 # REX.W jmp (%rsp) note:fword jmp > L_setCodeSelectorLongJump: > - addq $0x10, %rsp > + addq $0x14, %rsp > ret > > > #--------------------------------------------------------------------- > --------- > > Index: UefiCpuPkg/CpuDxe/CpuGdt.c > =================================================================== > --- UefiCpuPkg/CpuDxe/CpuGdt.c (revision 13937) > +++ UefiCpuPkg/CpuDxe/CpuGdt.c (working copy) > @@ -187,7 +187,7 @@ > // > // Write GDT register > // > - gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt; > + gdtPtr.Base = (UINTN)(VOID*) gdt; > gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1); > AsmWriteGdtr (&gdtPtr); > > Index: UefiCpuPkg/CpuDxe/CpuDxe.c > =================================================================== > --- UefiCpuPkg/CpuDxe/CpuDxe.c (revision 13937) > +++ UefiCpuPkg/CpuDxe/CpuDxe.c (working copy) > @@ -1184,7 +1184,7 @@ > // > IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16); > IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16); > - IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1)); > + IdtPtr->Base = (UINTN)(VOID*) gIdtTable; > IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1); > > AsmWriteIdtr (IdtPtr); > Index: OvmfPkg/PlatformPei/MemDetect.c > =================================================================== > --- OvmfPkg/PlatformPei/MemDetect.c (revision 13937) > +++ OvmfPkg/PlatformPei/MemDetect.c (working copy) > @@ -136,7 +136,7 @@ > MtrrSetMemoryAttribute (0, BASE_512KB + BASE_128KB, > CacheWriteBack); > > if (UpperMemorySize != 0) { > - AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize); > + AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize); > > MtrrSetMemoryAttribute (BASE_4GB, UpperMemorySize, CacheWriteBack); > } > ------------------------------------------------------------------------------ Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnmore_122712 _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel ------------------------------------------------------------------------------ Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnmore_122712 _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel