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

Reply via email to