Check in following modules,

DxeIpl
ConPlatform
ConSplitter
GraphicsConsole
Terminal
DevicePath

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3069 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
xgu3
2007-07-05 07:05:28 +00:00
parent 8a7f0c4c6b
commit 95276127e3
63 changed files with 23601 additions and 7 deletions

View File

@@ -0,0 +1,136 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. 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:
DxeLoadFunc.c
Abstract:
Ia32-specifc functionality for DxeLoad.
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include "DxeIpl.h"
#include "VirtualMemory.h"
//
// 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
};
//
// IA32 Gdt register
//
GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR gGdt = {
sizeof (gGdtEntries) - 1,
(UINTN) gGdtEntries
};
VOID
HandOffToDxeCore (
IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
IN EFI_PEI_HOB_POINTERS HobList,
IN EFI_PEI_PPI_DESCRIPTOR *EndOfPeiSignal
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS BaseOfStack;
EFI_PHYSICAL_ADDRESS TopOfStack;
UINTN PageTables;
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
ASSERT_EFI_ERROR (Status);
if (FeaturePcdGet(PcdDxeIplSwitchToLongMode)) {
//
// Compute the top of the stack we were allocated, which is used to load X64 dxe core.
// Pre-allocate a 32 bytes which confroms to x64 calling convention.
//
// The first four parameters to a function are passed in rcx, rdx, r8 and r9.
// Any further parameters are pushed on the stack. Furthermore, space (4 * 8bytes) for the
// register parameters is reserved on the stack, in case the called function
// wants to spill them; this is important if the function is variadic.
//
TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;
//
// X64 Calling Conventions requires that the stack must be aligned to 16 bytes
//
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, 16);
//
// Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA
// memory, it may be corrupted when copying FV to high-end memory
//
AsmWriteGdtr (&gGdt);
//
// Create page table and save PageMapLevel4 to CR3
//
PageTables = CreateIdentityMappingPageTables ();
//
// End of PEI phase singal
//
Status = PeiServicesInstallPpi (EndOfPeiSignal);
ASSERT_EFI_ERROR (Status);
AsmWriteCr3 (PageTables);
//
// Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
// Call x64 drivers passing in single argument, a pointer to the HOBs.
//
AsmEnablePaging64 (
SYS_CODE64_SEL,
DxeCoreEntryPoint,
(EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw),
0,
TopOfStack
);
} else {
//
// Compute the top of the stack we were allocated. Pre-allocate a UINTN
// for safety.
//
TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT;
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
//
// End of PEI phase singal
//
Status = PeiServicesInstallPpi (EndOfPeiSignal);
ASSERT_EFI_ERROR (Status);
SwitchStack (
(SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
HobList.Raw,
NULL,
(VOID *) (UINTN) TopOfStack
);
}
}

View File

@@ -0,0 +1,117 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. 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:
ImageRead.c
Abstract:
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include "DxeIpl.h"
EFI_STATUS
EFIAPI
PeiImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINTN *ReadSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
Arguments:
FileHandle - The handle to the PE/COFF file
FileOffset - The offset, in bytes, into the file to read
ReadSize - The number of bytes to read from the file starting at FileOffset
Buffer - A pointer to the buffer to read the data into.
Returns:
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
--*/
{
UINT8 *Destination32;
UINT8 *Source32;
UINTN Length;
Destination32 = Buffer;
Source32 = (UINT8 *) ((UINTN) FileHandle + FileOffset);
//
// This function assumes 32-bit alignment to increase performance
//
// ASSERT (ALIGN_POINTER (Destination32, sizeof (UINT32)) == Destination32);
// ASSERT (ALIGN_POINTER (Source32, sizeof (UINT32)) == Source32);
Length = *ReadSize;
while (Length--) {
*(Destination32++) = *(Source32++);
}
return EFI_SUCCESS;
}
EFI_STATUS
GetImageReadFunction (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
/*++
Routine Description:
Support routine to return the PE32 Image Reader.
If the PeiImageRead() function is less than a page
in legnth. If the function is more than a page the DXE IPL will crash!!!!
Arguments:
ImageContext - The context of the image being loaded
Returns:
EFI_SUCCESS - If Image function location is found
--*/
{
VOID *MemoryBuffer;
if (gInMemory) {
ImageContext->ImageRead = PeiImageRead;
return EFI_SUCCESS;
}
//
// BugBug; This code assumes PeiImageRead() is less than a page in size!
// Allocate a page so we can shaddow the read function from FLASH into
// memory to increase performance.
//
MemoryBuffer = AllocateCopyPool (0x400, (VOID *)(UINTN) PeiImageRead);
ASSERT (MemoryBuffer != NULL);
ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,173 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. 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:
VirtualMemory.c
Abstract:
x64 Virtual Memory Management Services in the form of an IA-32 driver.
Used to establish a 1:1 Virtual to Physical Mapping that is required to
enter Long Mode (x64 64-bit mode).
While we make a 1:1 mapping (identity mapping) for all physical pages
we still need to use the MTRR's to ensure that the cachability attirbutes
for all memory regions is correct.
The basic idea is to use 2MB page table entries where ever possible. If
more granularity of cachability is required then 4K page tables are used.
References:
1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel
2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include "VirtualMemory.h"
UINTN
CreateIdentityMappingPageTables (
VOID
)
/*++
Routine Description:
Allocates and fills in the Page Directory and Page Table Entries to
establish a 1:1 Virtual to Physical mapping.
Arguments:
NumberOfProcessorPhysicalAddressBits - Number of processor address bits to use.
Limits the number of page table entries
to the physical address space.
Returns:
EFI_SUCCESS The 1:1 Virtual to Physical identity mapping was created
--*/
{
UINT8 PhysicalAddressBits;
EFI_PHYSICAL_ADDRESS PageAddress;
UINTN IndexOfPml4Entries;
UINTN IndexOfPdpEntries;
UINTN IndexOfPageDirectoryEntries;
UINTN NumberOfPml4EntriesNeeded;
UINTN NumberOfPdpEntriesNeeded;
PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
PAGE_TABLE_ENTRY *PageDirectoryEntry;
UINTN TotalPagesNum;
UINTN BigPageAddress;
VOID *Hob;
//
// Get physical address bits supported from CPU HOB.
//
PhysicalAddressBits = 36;
Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
if (Hob != NULL) {
PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
}
//
// Calculate the table entries needed.
//
if (PhysicalAddressBits <= 39 ) {
NumberOfPml4EntriesNeeded = 1;
NumberOfPdpEntriesNeeded = 1 << (PhysicalAddressBits - 30);
} else {
NumberOfPml4EntriesNeeded = 1 << (PhysicalAddressBits - 39);
NumberOfPdpEntriesNeeded = 512;
}
//
// Pre-allocate big pages to avoid later allocations.
//
TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
BigPageAddress = (UINTN) AllocatePages (TotalPagesNum);
ASSERT (BigPageAddress != 0);
//
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
//
PageMap = (VOID *) BigPageAddress;
BigPageAddress += EFI_PAGE_SIZE;
PageMapLevel4Entry = PageMap;
PageAddress = 0;
for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
//
// Each PML4 entry points to a page of Page Directory Pointer entires.
// So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
//
PageDirectoryPointerEntry = (VOID *) BigPageAddress;
BigPageAddress += EFI_PAGE_SIZE;
//
// Make a PML4 Entry
//
PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;
PageMapLevel4Entry->Bits.ReadWrite = 1;
PageMapLevel4Entry->Bits.Present = 1;
for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
//
// Each Directory Pointer entries points to a page of Page Directory entires.
// So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
//
PageDirectoryEntry = (VOID *) BigPageAddress;
BigPageAddress += EFI_PAGE_SIZE;
//
// Fill in a Page Directory Pointer Entries
//
PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry;
PageDirectoryPointerEntry->Bits.ReadWrite = 1;
PageDirectoryPointerEntry->Bits.Present = 1;
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += 0x200000) {
//
// Fill in the Page Directory entries
//
PageDirectoryEntry->Uint64 = (UINT64)PageAddress;
PageDirectoryEntry->Bits.ReadWrite = 1;
PageDirectoryEntry->Bits.Present = 1;
PageDirectoryEntry->Bits.MustBe1 = 1;
}
}
}
//
// For the PML4 entries we are not using fill in a null entry.
// For now we just copy the first entry.
//
for (; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Entry++) {
CopyMem (
PageMapLevel4Entry,
PageMap,
sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
);
}
return (UINTN)PageMap; // FIXME
}

View File

@@ -0,0 +1,112 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. 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:
VirtualMemory.h
Abstract:
x64 Long Mode Virtual Memory Management Definitions
References:
1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel
2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
4) AMD64 Architecture Programmer's Manual Volume 2: System Programming
--*/
#ifndef _VIRTUAL_MEMORY_H_
#define _VIRTUAL_MEMORY_H_
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#define SYS_CODE64_SEL 0x38
#pragma pack(1)
typedef union {
struct {
UINT32 LimitLow : 16;
UINT32 BaseLow : 16;
UINT32 BaseMid : 8;
UINT32 Type : 4;
UINT32 System : 1;
UINT32 Dpl : 2;
UINT32 Present : 1;
UINT32 LimitHigh : 4;
UINT32 Software : 1;
UINT32 Reserved : 1;
UINT32 DefaultSize : 1;
UINT32 Granularity : 1;
UINT32 BaseHigh : 8;
} Bits;
UINT64 Uint64;
} IA32_GDT;
//
// Page-Map Level-4 Offset (PML4) and
// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
//
typedef union {
struct {
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
UINT64 Reserved:1; // Reserved
UINT64 MustBeZero:2; // Must Be Zero
UINT64 Available:3; // Available for use by system software
UINT64 PageTableBaseAddress:40; // Page Table Base Address
UINT64 AvabilableHigh:11; // Available for use by system software
UINT64 Nx:1; // No Execute bit
} Bits;
UINT64 Uint64;
} PAGE_MAP_AND_DIRECTORY_POINTER;
//
// Page Table Entry 2MB
//
typedef union {
struct {
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page
UINT64 MustBe1:1; // Must be 1
UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
UINT64 Available:3; // Available for use by system software
UINT64 PAT:1; //
UINT64 MustBeZero:8; // Must be zero;
UINT64 PageTableBaseAddress:31; // Page Table Base Address
UINT64 AvabilableHigh:11; // Available for use by system software
UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
} Bits;
UINT64 Uint64;
} PAGE_TABLE_ENTRY;
#pragma pack()
UINTN
CreateIdentityMappingPageTables (
VOID
)
;
#endif