]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Sec/SecMain.c
Add initial version of Open Virtual Machine Firmware (OVMF) platform.
[mirror_edk2.git] / OvmfPkg / Sec / SecMain.c
1 /** @file
2 Main SEC phase code. Transitions to PEI.
3
4 Copyright (c) 2008 - 2009, Intel Corporation
5
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <PiPei.h>
17 #include <Library/BaseLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/PeiServicesLib.h>
21 #include <Ppi/TemporaryRamSupport.h>
22 #include <Library/PcdLib.h>
23
24 #include "SecMain.h"
25
26 EFI_STATUS
27 EFIAPI
28 TemporaryRamMigration (
29 IN CONST EFI_PEI_SERVICES **PeiServices,
30 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
31 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
32 IN UINTN CopySize
33 );
34
35 STATIC TEMPORARY_RAM_SUPPORT_PPI mTempRamSupportPpi = {
36 (TEMPORARY_RAM_MIGRATION) TemporaryRamMigration
37 };
38
39 STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
40 {
41 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
42 &gEfiTemporaryRamSupportPpiGuid,
43 &mTempRamSupportPpi
44 },
45 };
46
47
48 VOID
49 InitializeIdtPtr (
50 IN VOID* IdtPtr
51 )
52 {
53 IA32_DESCRIPTOR IdtDescriptor;
54
55 IdtDescriptor.Base = (UINTN)IdtPtr;
56 IdtDescriptor.Limit = (UINT16) 0;
57 AsmWriteIdtr (&IdtDescriptor);
58 }
59
60 VOID
61 EFIAPI
62 SecCoreStartupWithStack (
63 IN VOID *BootFirmwareVolumePtr,
64 IN VOID *SecCoreEntryPoint,
65 IN VOID *PeiCoreEntryPoint,
66 IN VOID *TopOfCurrentStack
67 )
68 {
69 EFI_SEC_PEI_HAND_OFF *SecCoreData;
70 UINT8 *BottomOfTempRam;
71 UINT8 *TopOfTempRam;
72 UINTN SizeOfTempRam;
73 VOID *IdtPtr;
74
75 DEBUG ((EFI_D_ERROR,
76 "SecCoreStartupWithStack(0x%x, 0x%x, 0x%x, 0x%x)\n",
77 (UINT32)(UINTN)BootFirmwareVolumePtr,
78 (UINT32)(UINTN)SecCoreEntryPoint,
79 (UINT32)(UINTN)PeiCoreEntryPoint,
80 (UINT32)(UINTN)TopOfCurrentStack));
81
82
83 BottomOfTempRam = (UINT8*)(UINTN) INITIAL_TOP_OF_STACK;
84 SizeOfTempRam = (UINTN) SIZE_64KB;
85 TopOfTempRam = BottomOfTempRam + SizeOfTempRam;
86
87 //
88 // |-------------|
89 // | SecCoreData | 4k
90 // |-------------|
91 // | Heap | 28k
92 // |-------------|
93 // | Stack | 32k
94 // |-------------| <---- INITIAL_TOP_OF_STACK
95 //
96
97 //
98 // Bind this information into the SEC hand-off state
99 //
100 SecCoreData = (EFI_SEC_PEI_HAND_OFF*)((UINTN) TopOfTempRam - SIZE_4KB);
101 SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
102
103 SecCoreData->BootFirmwareVolumeBase = (VOID*)(UINTN) PcdGet32 (PcdOvmfFlashFvRecoveryBase);
104 SecCoreData->BootFirmwareVolumeSize = PcdGet32 (PcdOvmfFlashFvRecoverySize);
105
106 SecCoreData->TemporaryRamBase = (VOID*) BottomOfTempRam;
107 SecCoreData->TemporaryRamSize = SizeOfTempRam;
108
109 SecCoreData->PeiTemporaryRamSize = 28 * SIZE_1KB;
110 SecCoreData->PeiTemporaryRamBase = (VOID*)((UINTN)SecCoreData - SecCoreData->PeiTemporaryRamSize);
111
112 SecCoreData->StackBase = SecCoreData->TemporaryRamBase;
113 SecCoreData->StackSize = (UINTN)SecCoreData->PeiTemporaryRamBase - (UINTN)SecCoreData->TemporaryRamBase;
114
115 //
116 // Initialize the IDT Pointer, since IA32 & X64 architectures
117 // use it to store the PEI Services pointer.
118 //
119 IdtPtr = (VOID*)((UINT8*)SecCoreData + sizeof (*SecCoreData) + sizeof (UINTN));
120 IdtPtr = ALIGN_POINTER(IdtPtr, 16);
121 InitializeIdtPtr (IdtPtr);
122
123 //
124 // Transfer control to the PEI Core
125 //
126 PeiSwitchStacks (
127 (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,
128 SecCoreData,
129 (VOID *) (UINTN) ((EFI_PEI_PPI_DESCRIPTOR *) &mPrivateDispatchTable),
130 NULL,
131 TopOfCurrentStack,
132 (VOID *)((UINTN)SecCoreData->StackBase + SecCoreData->StackSize)
133 );
134
135 //
136 // If we get here, then the PEI Core returned. This is an error
137 //
138 ASSERT (FALSE);
139 CpuDeadLoop ();
140 }
141
142 EFI_STATUS
143 EFIAPI
144 TemporaryRamMigration (
145 IN CONST EFI_PEI_SERVICES **PeiServices,
146 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
147 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
148 IN UINTN CopySize
149 )
150 {
151 DEBUG ((EFI_D_ERROR, "TemporaryRamMigration(0x%x, 0x%x, 0x%x)\n", (UINTN)TemporaryMemoryBase, (UINTN)PermanentMemoryBase, CopySize));
152
153 //
154 // Migrate the whole temporary memory to permenent memory.
155 //
156 CopyMem((VOID*)(UINTN)PermanentMemoryBase, (VOID*)(UINTN)TemporaryMemoryBase, CopySize);
157
158 //
159 // SecSwitchStack function must be invoked after the memory migration
160 // immediatly, also we need fixup the stack change caused by new call into
161 // permenent memory.
162 //
163 SecSwitchStack (
164 (UINTN) TemporaryMemoryBase,
165 (UINTN) PermanentMemoryBase,
166 CopySize
167 );
168
169 return EFI_SUCCESS;
170 }
171