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

Reply via email to