1/** @file
2
3Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution.  The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13  DxeInit.c
14
15Abstract:
16
17Revision History:
18
19**/
20
21#include "DxeIpl.h"
22
23#include "LegacyTable.h"
24#include "HobGeneration.h"
25#include "PpisNeededByDxeCore.h"
26#include "Debug.h"
27
28/*
29--------------------------------------------------------
30 Memory Map: (XX=32,64)
31--------------------------------------------------------
320x0
33        IVT
340x400
35        BDA
360x500
37
380x7C00
39        BootSector
400x10000
41        EfiLdr (relocate by efiXX.COM)
420x15000
43        Efivar.bin (Load by StartXX.COM)
440x20000
45        StartXX.COM (E820 table, Temporary GDT, Temporary IDT)
460x21000
47        EfiXX.COM (Temporary Interrupt Handler)
480x22000
49        EfiLdr.efi + DxeIpl.Z + DxeMain.Z + BFV.Z
500x86000
51        MemoryFreeUnder1M (For legacy driver DMA)
520x90000
53        Temporary 4G PageTable for X64 (6 page)
540x9F800
55        EBDA
560xA0000
57        VGA
580xC0000
59        OPROM
600xE0000
61        FIRMEWARE
620x100000 (1M)
63        Temporary Stack (1M)
640x200000
65
66MemoryAbove1MB.PhysicalStart <-----------------------------------------------------+
67        ...                                                                        |
68        ...                                                                        |
69                        <- Phit.EfiMemoryBottom -------------------+               |
70        HOB                                                        |               |
71                        <- Phit.EfiFreeMemoryBottom                |               |
72                                                                   |     MemoryFreeAbove1MB.ResourceLength
73                        <- Phit.EfiFreeMemoryTop ------+           |               |
74        MemoryDescriptor (For ACPINVS, ACPIReclaim)    |    4M = CONSUMED_MEMORY   |
75                                                       |           |               |
76        Permament 4G PageTable for IA32 or      MemoryAllocation   |               |
77        Permament 64G PageTable for X64                |           |               |
78                        <------------------------------+           |               |
79        Permament Stack (0x20 Pages = 128K)                        |               |
80                        <- Phit.EfiMemoryTop ----------+-----------+---------------+
81        NvFV (64K)                                                                 |
82                                                                                 MMIO
83        FtwFV (128K)                                                               |
84                        <----------------------------------------------------------+<---------+
85        DxeCore                                                                    |          |
86                                                                                DxeCore       |
87        DxeIpl                                                                     |   Allocated in EfiLdr
88                        <----------------------------------------------------------+          |
89        BFV                                                                      MMIO         |
90                        <- Top of Free Memory reported by E820 --------------------+<---------+
91        ACPINVS        or
92        ACPIReclaim    or
93        Reserved
94                        <- Memory Top on RealMemory
95
960x100000000 (4G)
97
98MemoryFreeAbove4G.Physicalstart <--------------------------------------------------+
99                                                                                   |
100                                                                                   |
101                                                                  MemoryFreeAbove4GB.ResourceLength
102                                                                                   |
103                                                                                   |
104                                <--------------------------------------------------+
105*/
106
107VOID
108EnterDxeMain (
109  IN VOID *StackTop,
110  IN VOID *DxeCoreEntryPoint,
111  IN VOID *Hob,
112  IN VOID *PageTable
113  );
114
115VOID
116DxeInit (
117  IN EFILDRHANDOFF  *Handoff
118  )
119/*++
120
121  Routine Description:
122
123    This is the entry point after this code has been loaded into memory.
124
125Arguments:
126
127
128Returns:
129
130    Calls into EFI Firmware
131
132--*/
133{
134  VOID                  *StackTop;
135  VOID                  *StackBottom;
136  VOID                  *PageTableBase;
137  VOID                  *MemoryTopOnDescriptor;
138  VOID                  *MemoryDescriptor;
139  VOID                  *NvStorageBase;
140  EFILDRHANDOFF         HandoffCopy;
141
142  CopyMem ((VOID*) &HandoffCopy, (VOID*) Handoff, sizeof (EFILDRHANDOFF));
143  Handoff = &HandoffCopy;
144
145  ClearScreen();
146
147  PrintString (
148    "Enter DxeIpl ...\n"
149    "Handoff:\n"
150    "Handoff.BfvBase = %p, BfvLength = %x\n"
151    "Handoff.DxeIplImageBase = %p, DxeIplImageSize = %x\n"
152    "Handoff.DxeCoreImageBase = %p, DxeCoreImageSize = %x\n",
153    Handoff->BfvBase, Handoff->BfvSize,
154    Handoff->DxeIplImageBase, Handoff->DxeIplImageSize,
155    Handoff->DxeCoreImageBase, Handoff->DxeCoreImageSize
156    );
157
158  //
159  // Hob Generation Guild line:
160  //   * Don't report FV as physical memory
161  //   * MemoryAllocation Hob should only cover physical memory
162  //   * Use ResourceDescriptor Hob to report physical memory or Firmware Device and they shouldn't be overlapped
163  PrintString ("Prepare Cpu HOB information ...\n");
164  PrepareHobCpu ();
165
166  //
167  // 1. BFV
168  //
169  PrintString ("Prepare BFV HOB information ...\n");
170  PrepareHobBfv (Handoff->BfvBase, Handoff->BfvSize);
171
172  //
173  // 2. Updates Memory information, and get the top free address under 4GB
174  //
175  PrintString ("Prepare Memory HOB information ...\n");
176  MemoryTopOnDescriptor = PrepareHobMemory (Handoff->MemDescCount, Handoff->MemDesc);
177
178  //
179  // 3. Put [NV], [Stack], [PageTable], [MemDesc], [HOB] just below the [top free address under 4GB]
180  //
181
182  //   3.1 NV data
183  PrintString ("Prepare NV Storage information ...\n");
184  NvStorageBase = PrepareHobNvStorage (MemoryTopOnDescriptor);
185  PrintString ("NV Storage Base = %p\n", NvStorageBase);
186  //   3.2 Stack
187  StackTop = NvStorageBase;
188  StackBottom = PrepareHobStack (StackTop);
189  PrintString ("Stack Top=0x%x, Stack Bottom=0x%x\n", StackTop, StackBottom);
190  //   3.3 Page Table
191  PageTableBase = PreparePageTable (StackBottom, gHob->Cpu.SizeOfMemorySpace);
192  //   3.4 MemDesc (will be used in PlatformBds)
193  MemoryDescriptor = PrepareHobMemoryDescriptor (PageTableBase, Handoff->MemDescCount, Handoff->MemDesc);
194  //   3.5 Copy the Hob itself to EfiMemoryBottom, and update the PHIT Hob
195  PrepareHobPhit (StackTop, MemoryDescriptor);
196
197  //
198  // 4. Register the memory occupied by DxeCore and DxeIpl together as DxeCore
199  //
200  PrintString ("Prepare DxeCore memory Hob ...\n");
201  PrepareHobDxeCore (
202    Handoff->DxeCoreEntryPoint,
203    (EFI_PHYSICAL_ADDRESS)(UINTN)Handoff->DxeCoreImageBase,
204    (UINTN)Handoff->DxeIplImageBase + (UINTN)Handoff->DxeIplImageSize - (UINTN)Handoff->DxeCoreImageBase
205    );
206
207  PrepareHobLegacyTable (gHob);
208
209  PreparePpisNeededByDxeCore (gHob);
210
211  CompleteHobGeneration ();
212
213  //
214  // Print Hob Info
215  //
216  ClearScreen();
217  PrintString (
218    "HobStart = %p\n"
219    "Memory Top = %lx, Bottom = %lx\n"
220    "Free Memory Top = %lx, Bottom = %lx\n"
221    "NvStorageFvb = %lx, Length = %lx\n"
222    "BfvResource = %lx, Length = %lx\n"
223    "NvStorageFvResource = %lx, Length = %lx\n"
224    "NvStorage = %lx, Length = %lx\n"
225    "NvFtwFvResource = %lx, Length = %lx\n"
226    "NvFtwWorking = %lx, Length = %lx\n"
227    "NvFtwSpare = %lx, Length = %lx\n"
228    "Stack = %lx, StackLength = %lx\n"
229    "PageTable = %p\n"
230    "MemoryFreeUnder1MB = %lx, MemoryFreeUnder1MBLength = %lx\n"
231    "MemoryAbove1MB = %lx, MemoryAbove1MBLength = %lx\n"
232    "MemoryAbove4GB = %lx, MemoryAbove4GBLength = %lx\n"
233    "DxeCore = %lx, DxeCoreLength = %lx\n"
234    "MemoryAllocation = %lx, MemoryLength = %lx\n"
235    "$",
236    gHob,
237    gHob->Phit.EfiMemoryTop, gHob->Phit.EfiMemoryBottom,
238    gHob->Phit.EfiFreeMemoryTop, gHob->Phit.EfiFreeMemoryBottom,
239    gHob->NvStorageFvb.FvbInfo.Entries[0].Base, gHob->NvFtwFvb.FvbInfo.Entries[0].Length,
240    gHob->BfvResource.PhysicalStart, gHob->BfvResource.ResourceLength,
241    gHob->NvStorageFvResource.PhysicalStart, gHob->NvStorageFvResource.ResourceLength,
242    gHob->NvStorage.FvbInfo.Entries[0].Base, gHob->NvStorage.FvbInfo.Entries[0].Length,
243    gHob->NvFtwFvResource.PhysicalStart, gHob->NvFtwFvResource.ResourceLength,
244    gHob->NvFtwWorking.FvbInfo.Entries[0].Base, gHob->NvFtwWorking.FvbInfo.Entries[0].Length,
245    gHob->NvFtwSpare.FvbInfo.Entries[0].Base, gHob->NvFtwSpare.FvbInfo.Entries[0].Length,
246    gHob->Stack.AllocDescriptor.MemoryBaseAddress, gHob->Stack.AllocDescriptor.MemoryLength,
247    PageTableBase,
248    gHob->MemoryFreeUnder1MB.PhysicalStart, gHob->MemoryFreeUnder1MB.ResourceLength,
249    gHob->MemoryAbove1MB.PhysicalStart, gHob->MemoryAbove1MB.ResourceLength,
250    gHob->MemoryAbove4GB.PhysicalStart, gHob->MemoryAbove4GB.ResourceLength,
251    gHob->DxeCore.MemoryAllocationHeader.MemoryBaseAddress, gHob->DxeCore.MemoryAllocationHeader.MemoryLength,
252    gHob->MemoryAllocation.AllocDescriptor.MemoryBaseAddress, gHob->MemoryAllocation.AllocDescriptor.MemoryLength
253    );
254
255  ClearScreen();
256  PrintString (
257    "\n\n\n\n\n\n\n\n\n\n"
258    "                         WELCOME TO EFI WORLD!\n"
259    );
260
261  EnterDxeMain (StackTop, Handoff->DxeCoreEntryPoint, gHob, PageTableBase);
262  PrintString ("Fail to enter DXE main!\n");
263
264  //
265  // Should never get here
266  //
267  CpuDeadLoop ();
268}
269
270EFI_STATUS
271EFIAPI
272_ModuleEntryPoint (
273  IN EFILDRHANDOFF  *Handoff
274  )
275{
276  DxeInit(Handoff);
277  return EFI_SUCCESS;
278}
279