1 /** @file
2 
3 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 Module Name:
13   DxeInit.c
14 
15 Abstract:
16 
17 Revision 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 --------------------------------------------------------
32 0x0
33         IVT
34 0x400
35         BDA
36 0x500
37 
38 0x7C00
39         BootSector
40 0x10000
41         EfiLdr (relocate by efiXX.COM)
42 0x15000
43         Efivar.bin (Load by StartXX.COM)
44 0x20000
45         StartXX.COM (E820 table, Temporary GDT, Temporary IDT)
46 0x21000
47         EfiXX.COM (Temporary Interrupt Handler)
48 0x22000
49         EfiLdr.efi + DxeIpl.Z + DxeMain.Z + BFV.Z
50 0x86000
51         MemoryFreeUnder1M (For legacy driver DMA)
52 0x90000
53         Temporary 4G PageTable for X64 (6 page)
54 0x9F800
55         EBDA
56 0xA0000
57         VGA
58 0xC0000
59         OPROM
60 0xE0000
61         FIRMEWARE
62 0x100000 (1M)
63         Temporary Stack (1M)
64 0x200000
65 
66 MemoryAbove1MB.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 
96 0x100000000 (4G)
97 
98 MemoryFreeAbove4G.Physicalstart <--------------------------------------------------+
99                                                                                    |
100                                                                                    |
101                                                                   MemoryFreeAbove4GB.ResourceLength
102                                                                                    |
103                                                                                    |
104                                 <--------------------------------------------------+
105 */
106 
107 VOID
108 EnterDxeMain (
109   IN VOID *StackTop,
110   IN VOID *DxeCoreEntryPoint,
111   IN VOID *Hob,
112   IN VOID *PageTable
113   );
114 
115 VOID
DxeInit(IN EFILDRHANDOFF * Handoff)116 DxeInit (
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 
125 Arguments:
126 
127 
128 Returns:
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 = %p, Length = %x\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, (UINTN) 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 
270 EFI_STATUS
271 EFIAPI
_ModuleEntryPoint(IN EFILDRHANDOFF * Handoff)272 _ModuleEntryPoint (
273   IN EFILDRHANDOFF  *Handoff
274   )
275 {
276   DxeInit(Handoff);
277   return EFI_SUCCESS;
278 }
279