/** @file

Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:
  Paging.c

Abstract:

Revision History:

**/

#include "HobGeneration.h"
#include "VirtualMemory.h"

//
// Create 2M-page table
// PML4 (47:39)
// PDPTE (38:30)
// PDE (29:21)
//

#define EFI_2M_PAGE_BITS_NUM    21
#define EFI_MAX_ENTRY_BITS_NUM  9

#define EFI_PAGE_SIZE_4K        0x1000
#define EFI_PAGE_SIZE_2M        (1 << EFI_2M_PAGE_BITS_NUM)

#ifndef MIN
  #define MIN(a, b)               ((a) < (b) ? (a) : (b))
#endif
#define ENTRY_NUM(x)            ((UINTN)1 << (x))

UINT8 gPML4BitsNum;
UINT8 gPDPTEBitsNum;
UINT8 gPDEBitsNum;

UINTN gPageNum2M;
UINTN gPageNum4K;

VOID
EnableNullPointerProtection (
  UINT8                       *PageTable
  )
{
  X64_PAGE_TABLE_ENTRY_4K *PageTableEntry4KB;

  PageTableEntry4KB = (X64_PAGE_TABLE_ENTRY_4K *) (PageTable + gPageNum2M * EFI_PAGE_SIZE_4K);
  //
  // Fill in the Page Table entries
  // Mark 0~4K as not present
  //
  PageTableEntry4KB->Bits.Present = 0;

  return ;
}

VOID
X64Create4KPageTables (
  UINT8                       *PageTable
  )
/*++
Routine Description:
  Create 4K-Page-Table for the low 2M memory.
  This will change the previously created 2M-Page-Table-Entry.
--*/
{
  UINT64                                        PageAddress;
  UINTN                                         PTEIndex;
  X64_PAGE_DIRECTORY_ENTRY_4K                   *PageDirectoryEntry4KB;
  X64_PAGE_TABLE_ENTRY_4K                       *PageTableEntry4KB;

  //
  //  Page Table structure 4 level 4K.
  //
  //                   PageMapLevel4Entry        : bits 47-39
  //                   PageDirectoryPointerEntry : bits 38-30
  //  Page Table 4K  : PageDirectoryEntry4K      : bits 29-21
  //                   PageTableEntry            : bits 20-12
  //

  PageTableEntry4KB = (X64_PAGE_TABLE_ENTRY_4K *)(PageTable + gPageNum2M * EFI_PAGE_SIZE_4K);

  PageDirectoryEntry4KB = (X64_PAGE_DIRECTORY_ENTRY_4K *) (PageTable + 2 * EFI_PAGE_SIZE_4K);
  PageDirectoryEntry4KB->Uint64 = (UINT64)(UINTN)PageTableEntry4KB;
  PageDirectoryEntry4KB->Bits.ReadWrite = 1;
  PageDirectoryEntry4KB->Bits.Present = 1;
  PageDirectoryEntry4KB->Bits.MustBeZero = 0;

  for (PTEIndex = 0, PageAddress = 0; 
       PTEIndex < ENTRY_NUM (EFI_MAX_ENTRY_BITS_NUM); 
       PTEIndex++, PageTableEntry4KB++, PageAddress += EFI_PAGE_SIZE_4K
      ) {
    //
    // Fill in the Page Table entries
    //
    PageTableEntry4KB->Uint64 = (UINT64)PageAddress;
    PageTableEntry4KB->Bits.ReadWrite = 1;
    PageTableEntry4KB->Bits.Present = 1;
  }

  return ;
}

VOID
X64Create2MPageTables (
  UINT8 *PageTable
  )
{
  UINT64                                        PageAddress;
  UINT8                                         *TempPageTable;
  UINTN                                         PML4Index;
  UINTN                                         PDPTEIndex;
  UINTN                                         PDEIndex;
  X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K     *PageMapLevel4Entry;
  X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K     *PageDirectoryPointerEntry;
  X64_PAGE_TABLE_ENTRY_2M                       *PageDirectoryEntry2MB;

  TempPageTable = PageTable;
  PageAddress   = 0;

  //
  //  Page Table structure 3 level 2MB.
  //
  //                   PageMapLevel4Entry        : bits 47-39
  //                   PageDirectoryPointerEntry : bits 38-30
  //  Page Table 2MB : PageDirectoryEntry2M      : bits 29-21
  //

  PageMapLevel4Entry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)TempPageTable;

  for (PML4Index = 0; PML4Index < ENTRY_NUM (gPML4BitsNum); PML4Index++, PageMapLevel4Entry++) {
    //
    // Each PML4 entry points to a page of Page Directory Pointer entires.
    //  
    TempPageTable += EFI_PAGE_SIZE_4K;
    PageDirectoryPointerEntry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)TempPageTable;

    //
    // Make a PML4 Entry
    //
    PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)(TempPageTable);
    PageMapLevel4Entry->Bits.ReadWrite = 1;
    PageMapLevel4Entry->Bits.Present = 1;

    for (PDPTEIndex = 0; PDPTEIndex < ENTRY_NUM (gPDPTEBitsNum); PDPTEIndex++, PageDirectoryPointerEntry++) {
      //
      // Each Directory Pointer entries points to a page of Page Directory entires.
      //       
      TempPageTable += EFI_PAGE_SIZE_4K;
      PageDirectoryEntry2MB = (X64_PAGE_TABLE_ENTRY_2M *)TempPageTable;

      //
      // Fill in a Page Directory Pointer Entries
      //
      PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)(TempPageTable);
      PageDirectoryPointerEntry->Bits.ReadWrite = 1;
      PageDirectoryPointerEntry->Bits.Present = 1;

      for (PDEIndex = 0; PDEIndex < ENTRY_NUM (gPDEBitsNum); PDEIndex++, PageDirectoryEntry2MB++) {
        //
        // Fill in the Page Directory entries
        //
        PageDirectoryEntry2MB->Uint64 = (UINT64)PageAddress;
        PageDirectoryEntry2MB->Bits.ReadWrite = 1;
        PageDirectoryEntry2MB->Bits.Present = 1;
        PageDirectoryEntry2MB->Bits.MustBe1 = 1;

        PageAddress += EFI_PAGE_SIZE_2M;
      }
    }
  }

  return ;
}

VOID *
PreparePageTable (
  VOID  *PageNumberTop,
  UINT8 SizeOfMemorySpace
  )
/*++
Description:
  Generate pagetable below PageNumberTop, 
  and return the bottom address of pagetable for putting other things later.
--*/
{
  VOID  *PageNumberBase;

  SizeOfMemorySpace -= EFI_2M_PAGE_BITS_NUM;
  gPDEBitsNum        = (UINT8) MIN (SizeOfMemorySpace, EFI_MAX_ENTRY_BITS_NUM);
  SizeOfMemorySpace  = (UINT8) (SizeOfMemorySpace - gPDEBitsNum);
  gPDPTEBitsNum      = (UINT8) MIN (SizeOfMemorySpace, EFI_MAX_ENTRY_BITS_NUM);
  SizeOfMemorySpace  = (UINT8) (SizeOfMemorySpace - gPDPTEBitsNum);
  gPML4BitsNum       = SizeOfMemorySpace;
  if (gPML4BitsNum > EFI_MAX_ENTRY_BITS_NUM) {
    return NULL;
  }

  //
  // Suppose we have:
  // 2MPage:
  //   Entry:       PML4   ->     PDPTE     ->     PDE    -> Page
  //   EntryNum:     a              b               c
  // then
  //   Occupy4KPage: 1              a              a*b
  // 
  // 2M 4KPage:
  //   Entry:       PTE    ->     Page
  //   EntryNum:    512
  // then
  //   Occupy4KPage: 1
  //   

  gPageNum2M = 1 + ENTRY_NUM (gPML4BitsNum) + ENTRY_NUM (gPML4BitsNum + gPDPTEBitsNum);
  gPageNum4K = 1;


  PageNumberBase = (VOID *)((UINTN)PageNumberTop - (gPageNum2M + gPageNum4K) * EFI_PAGE_SIZE_4K);
  ZeroMem (PageNumberBase, (gPageNum2M + gPageNum4K) * EFI_PAGE_SIZE_4K);

  X64Create2MPageTables (PageNumberBase);
  X64Create4KPageTables (PageNumberBase);
  //
  // Not enable NULL Pointer Protection if using INTx call
  //
//  EnableNullPointerProtection (PageNumberBase);

  return PageNumberBase;
}
