2f625599e3b8b2247afd51c7d5d4a50670fa31f7
[reactos.git] / reactos / boot / environ / lib / firmware / efi / firmware.c
1 /*
2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/firmware/efi/firmware.c
5 * PURPOSE: Boot Library Firmware Initialization for EFI
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "bl.h"
12
13 /* DATA VARIABLES ************************************************************/
14
15 GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
16
17 PBL_FIRMWARE_DESCRIPTOR EfiFirmwareParameters;
18 BL_FIRMWARE_DESCRIPTOR EfiFirmwareData;
19 EFI_HANDLE EfiImageHandle;
20 EFI_SYSTEM_TABLE* EfiSystemTable;
21
22 EFI_SYSTEM_TABLE *EfiST;
23 EFI_BOOT_SERVICES *EfiBS;
24 EFI_RUNTIME_SERVICES *EfiRT;
25 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *EfiConOut;
26 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *EfiConIn;
27 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *EfiConInEx;
28
29 /* FUNCTIONS *****************************************************************/
30
31 NTSTATUS
32 EfiOpenProtocol (
33 _In_ EFI_HANDLE Handle,
34 _In_ EFI_GUID *Protocol,
35 _Out_ PVOID* Interface
36 )
37 {
38 EFI_STATUS EfiStatus;
39 NTSTATUS Status;
40 BL_ARCH_MODE OldMode;
41
42 /* Are we using virtual memory/ */
43 if (MmTranslationType != BlNone)
44 {
45 /* We need complex tracking to make this work */
46 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
47 Status = STATUS_NOT_SUPPORTED;
48 }
49 else
50 {
51 /* Are we in protected mode? */
52 OldMode = CurrentExecutionContext->Mode;
53 if (OldMode != BlRealMode)
54 {
55 /* FIXME: Not yet implemented */
56 return STATUS_NOT_IMPLEMENTED;
57 }
58
59 /* Are we on legacy 1.02? */
60 if (EfiST->FirmwareRevision == EFI_1_02_SYSTEM_TABLE_REVISION)
61 {
62 /* Make the legacy call */
63 EfiStatus = EfiBS->HandleProtocol(Handle, Protocol, Interface);
64 }
65 else
66 {
67 /* Use the UEFI version */
68 EfiStatus = EfiBS->OpenProtocol(Handle,
69 Protocol,
70 Interface,
71 EfiImageHandle,
72 NULL,
73 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
74
75 /* Switch back to protected mode if we came from there */
76 if (OldMode != BlRealMode)
77 {
78 BlpArchSwitchContext(OldMode);
79 }
80 }
81
82 /* Convert the error to an NTSTATUS */
83 Status = EfiGetNtStatusCode(EfiStatus);
84 }
85
86 /* Clear the interface on failure, and return the status */
87 if (!NT_SUCCESS(Status))
88 {
89 *Interface = NULL;
90 }
91
92 return Status;
93 }
94
95 NTSTATUS
96 EfiConInExSetState (
97 _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *ConInEx,
98 _In_ EFI_KEY_TOGGLE_STATE* KeyToggleState
99 )
100 {
101 BL_ARCH_MODE OldMode;
102 EFI_STATUS EfiStatus;
103
104 /* Are we in protected mode? */
105 OldMode = CurrentExecutionContext->Mode;
106 if (OldMode != BlRealMode)
107 {
108 /* FIXME: Not yet implemented */
109 return STATUS_NOT_IMPLEMENTED;
110 }
111
112 /* Make the EFI call */
113 EfiStatus = ConInEx->SetState(ConInEx, KeyToggleState);
114
115 /* Switch back to protected mode if we came from there */
116 if (OldMode != BlRealMode)
117 {
118 BlpArchSwitchContext(OldMode);
119 }
120
121 /* Convert the error to an NTSTATUS */
122 return EfiGetNtStatusCode(EfiStatus);
123 }
124
125 NTSTATUS
126 EfiSetWatchdogTimer (
127 VOID
128 )
129 {
130 BL_ARCH_MODE OldMode;
131 EFI_STATUS EfiStatus;
132
133 /* Are we in protected mode? */
134 OldMode = CurrentExecutionContext->Mode;
135 if (OldMode != BlRealMode)
136 {
137 /* FIXME: Not yet implemented */
138 return STATUS_NOT_IMPLEMENTED;
139 }
140
141 /* Make the EFI call */
142 EfiStatus = EfiBS->SetWatchdogTimer(0, 0, 0, NULL);
143
144 /* Switch back to protected mode if we came from there */
145 if (OldMode != BlRealMode)
146 {
147 BlpArchSwitchContext(OldMode);
148 }
149
150 /* Convert the error to an NTSTATUS */
151 return EfiGetNtStatusCode(EfiStatus);
152 }
153
154 NTSTATUS
155 BlpFwInitialize (
156 _In_ ULONG Phase,
157 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
158 )
159 {
160 NTSTATUS Status = STATUS_SUCCESS;
161 EFI_KEY_TOGGLE_STATE KeyToggleState;
162
163 /* Check if we have vaild firmware data */
164 if (!(FirmwareData) || !(FirmwareData->Version))
165 {
166 return STATUS_INVALID_PARAMETER;
167 }
168
169 /* Check which boot phase we're in */
170 if (Phase != 0)
171 {
172 /* Memory manager is ready, open the extended input protocol */
173 Status = EfiOpenProtocol(EfiST->ConsoleInHandle,
174 &EfiSimpleTextInputExProtocol,
175 (PVOID*)&EfiConInEx);
176 if (NT_SUCCESS(Status))
177 {
178 /* Set the initial key toggle state */
179 KeyToggleState = EFI_TOGGLE_STATE_VALID | 40;
180 EfiConInExSetState(EfiST->ConsoleInHandle, &KeyToggleState);
181 }
182
183 /* Setup the watchdog timer */
184 EfiSetWatchdogTimer();
185 }
186 else
187 {
188 /* Make a copy of the parameters */
189 EfiFirmwareParameters = &EfiFirmwareData;
190
191 /* Check which version we received */
192 if (FirmwareData->Version == 1)
193 {
194 /* FIXME: Not supported */
195 Status = STATUS_NOT_SUPPORTED;
196 }
197 else if (FirmwareData->Version >= 2)
198 {
199 /* Version 2 -- save the data */
200 EfiFirmwareData = *FirmwareData;
201 EfiSystemTable = FirmwareData->SystemTable;
202 EfiImageHandle = FirmwareData->ImageHandle;
203
204 /* Set the EDK-II style variables as well */
205 EfiST = EfiSystemTable;
206 EfiBS = EfiSystemTable->BootServices;
207 EfiRT = EfiSystemTable->RuntimeServices;
208 EfiConOut = EfiSystemTable->ConOut;
209 EfiConIn = EfiSystemTable->ConIn;
210 EfiConInEx = NULL;
211 }
212 else
213 {
214 /* Unknown version */
215 Status = STATUS_NOT_SUPPORTED;
216 }
217 }
218
219 /* Return the initialization state */
220 return Status;
221 }
222