]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/EmuGopDxe/GopDriver.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmulatorPkg / EmuGopDxe / GopDriver.c
CommitLineData
949f388f 1/*++ @file\r
2\r
3Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
4Portions copyright (c) 2010,Apple Inc. All rights reserved.<BR>\r
e3ba31da 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
949f388f 6\r
7\r
8**/\r
9\r
10#include "Gop.h"\r
11\r
949f388f 12EFI_STATUS\r
13FreeNotifyList (\r
a550d468 14 IN OUT LIST_ENTRY *ListHead\r
949f388f 15 )\r
a550d468 16\r
949f388f 17/*++\r
18\r
19Routine Description:\r
20\r
21Arguments:\r
22\r
23 ListHead - The list head\r
24\r
25Returns:\r
26\r
27 EFI_SUCCESS - Free the notify list successfully\r
28 EFI_INVALID_PARAMETER - ListHead is invalid.\r
29\r
30**/\r
31{\r
a550d468 32 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NotifyNode;\r
949f388f 33\r
34 if (ListHead == NULL) {\r
35 return EFI_INVALID_PARAMETER;\r
36 }\r
a550d468 37\r
949f388f 38 while (!IsListEmpty (ListHead)) {\r
39 NotifyNode = CR (\r
d18d8a1d 40 ListHead->ForwardLink,\r
41 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,\r
42 NotifyEntry,\r
949f388f 43 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
44 );\r
45 RemoveEntryList (ListHead->ForwardLink);\r
46 gBS->FreePool (NotifyNode);\r
47 }\r
d18d8a1d 48\r
949f388f 49 return EFI_SUCCESS;\r
50}\r
51\r
949f388f 52/**\r
d18d8a1d 53 Tests to see if this driver supports a given controller. If a child device is provided,\r
949f388f 54 it further tests to see if this driver supports creating a handle for the specified child device.\r
55\r
d18d8a1d 56 This function checks to see if the driver specified by This supports the device specified by\r
57 ControllerHandle. Drivers will typically use the device path attached to\r
58 ControllerHandle and/or the services from the bus I/O abstraction attached to\r
59 ControllerHandle to determine if the driver supports ControllerHandle. This function\r
60 may be called many times during platform initialization. In order to reduce boot times, the tests\r
61 performed by this function must be very small, and take as little time as possible to execute. This\r
62 function must not change the state of any hardware devices, and this function must be aware that the\r
63 device specified by ControllerHandle may already be managed by the same driver or a\r
64 different driver. This function must match its calls to AllocatePages() with FreePages(),\r
65 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().\r
66 Because ControllerHandle may have been previously started by the same driver, if a protocol is\r
67 already in the opened state, then it must not be closed with CloseProtocol(). This is required\r
949f388f 68 to guarantee the state of ControllerHandle is not modified by this function.\r
69\r
70 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
d18d8a1d 71 @param[in] ControllerHandle The handle of the controller to test. This handle\r
72 must support a protocol interface that supplies\r
949f388f 73 an I/O abstraction to the driver.\r
d18d8a1d 74 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
75 parameter is ignored by device drivers, and is optional for bus\r
76 drivers. For bus drivers, if this parameter is not NULL, then\r
77 the bus driver must determine if the bus controller specified\r
78 by ControllerHandle and the child controller specified\r
79 by RemainingDevicePath are both supported by this\r
949f388f 80 bus driver.\r
81\r
82 @retval EFI_SUCCESS The device specified by ControllerHandle and\r
83 RemainingDevicePath is supported by the driver specified by This.\r
84 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
85 RemainingDevicePath is already being managed by the driver\r
86 specified by This.\r
87 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
88 RemainingDevicePath is already being managed by a different\r
89 driver or an application that requires exclusive access.\r
90 Currently not implemented.\r
91 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
92 RemainingDevicePath is not supported by the driver specified by This.\r
93**/\r
94EFI_STATUS\r
95EFIAPI\r
96EmuGopDriverBindingSupported (\r
a550d468
MK
97 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
98 IN EFI_HANDLE Handle,\r
99 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
949f388f 100 )\r
101{\r
a550d468
MK
102 EFI_STATUS Status;\r
103 EMU_IO_THUNK_PROTOCOL *EmuIoThunk;\r
949f388f 104\r
105 //\r
106 // Open the IO Abstraction(s) needed to perform the supported test\r
107 //\r
108 Status = gBS->OpenProtocol (\r
109 Handle,\r
110 &gEmuIoThunkProtocolGuid,\r
111 (VOID **)&EmuIoThunk,\r
112 This->DriverBindingHandle,\r
113 Handle,\r
114 EFI_OPEN_PROTOCOL_BY_DRIVER\r
115 );\r
116 if (EFI_ERROR (Status)) {\r
117 return Status;\r
118 }\r
119\r
120 Status = EmuGopSupported (EmuIoThunk);\r
121\r
122 //\r
123 // Close the I/O Abstraction(s) used to perform the supported test\r
124 //\r
125 gBS->CloseProtocol (\r
a550d468
MK
126 Handle,\r
127 &gEmuIoThunkProtocolGuid,\r
128 This->DriverBindingHandle,\r
129 Handle\r
130 );\r
949f388f 131\r
132 return Status;\r
133}\r
134\r
949f388f 135/**\r
136 Starts a device controller or a bus controller.\r
137\r
138 The Start() function is designed to be invoked from the EFI boot service ConnectController().\r
d18d8a1d 139 As a result, much of the error checking on the parameters to Start() has been moved into this\r
140 common boot service. It is legal to call Start() from other locations,\r
949f388f 141 but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
142 1. ControllerHandle must be a valid EFI_HANDLE.\r
143 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
144 EFI_DEVICE_PATH_PROTOCOL.\r
145 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
d18d8a1d 146 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.\r
949f388f 147\r
148 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
d18d8a1d 149 @param[in] ControllerHandle The handle of the controller to start. This handle\r
150 must support a protocol interface that supplies\r
949f388f 151 an I/O abstraction to the driver.\r
d18d8a1d 152 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
153 parameter is ignored by device drivers, and is optional for bus\r
154 drivers. For a bus driver, if this parameter is NULL, then handles\r
155 for all the children of Controller are created by this driver.\r
156 If this parameter is not NULL and the first Device Path Node is\r
157 not the End of Device Path Node, then only the handle for the\r
158 child device specified by the first Device Path Node of\r
949f388f 159 RemainingDevicePath is created by this driver.\r
d18d8a1d 160 If the first Device Path Node of RemainingDevicePath is\r
949f388f 161 the End of Device Path Node, no child handle is created by this\r
162 driver.\r
163\r
164 @retval EFI_SUCCESS The device was started.\r
165 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
166 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
167 @retval Others The driver failded to start the device.\r
168\r
169**/\r
170EFI_STATUS\r
171EFIAPI\r
172EmuGopDriverBindingStart (\r
a550d468
MK
173 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
174 IN EFI_HANDLE Handle,\r
175 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
949f388f 176 )\r
177{\r
a550d468
MK
178 EMU_IO_THUNK_PROTOCOL *EmuIoThunk;\r
179 EFI_STATUS Status;\r
180 GOP_PRIVATE_DATA *Private;\r
949f388f 181\r
182 //\r
183 // Grab the protocols we need\r
184 //\r
185 Status = gBS->OpenProtocol (\r
186 Handle,\r
187 &gEmuIoThunkProtocolGuid,\r
188 (VOID **)&EmuIoThunk,\r
189 This->DriverBindingHandle,\r
190 Handle,\r
191 EFI_OPEN_PROTOCOL_BY_DRIVER\r
192 );\r
193 if (EFI_ERROR (Status)) {\r
194 return EFI_UNSUPPORTED;\r
195 }\r
196\r
197 //\r
198 // Allocate Private context data for SGO inteface.\r
199 //\r
200 Private = NULL;\r
a550d468
MK
201 Status = gBS->AllocatePool (\r
202 EfiBootServicesData,\r
203 sizeof (GOP_PRIVATE_DATA),\r
204 (VOID **)&Private\r
205 );\r
949f388f 206 if (EFI_ERROR (Status)) {\r
207 goto Done;\r
208 }\r
a550d468 209\r
949f388f 210 //\r
211 // Set up context record\r
212 //\r
213 Private->Signature = GOP_PRIVATE_DATA_SIGNATURE;\r
214 Private->Handle = Handle;\r
215 Private->EmuIoThunk = EmuIoThunk;\r
216 Private->WindowName = EmuIoThunk->ConfigString;\r
217 Private->ControllerNameTable = NULL;\r
218\r
219 AddUnicodeString (\r
220 "eng",\r
221 gEmuGopComponentName.SupportedLanguages,\r
222 &Private->ControllerNameTable,\r
223 EmuIoThunk->ConfigString\r
224 );\r
225 AddUnicodeString2 (\r
226 "en",\r
227 gEmuGopComponentName2.SupportedLanguages,\r
228 &Private->ControllerNameTable,\r
229 EmuIoThunk->ConfigString,\r
230 FALSE\r
231 );\r
232\r
233 Status = EmuGopConstructor (Private);\r
234 if (EFI_ERROR (Status)) {\r
235 goto Done;\r
236 }\r
a550d468 237\r
949f388f 238 //\r
239 // Publish the Gop interface to the world\r
240 //\r
241 Status = gBS->InstallMultipleProtocolInterfaces (\r
242 &Private->Handle,\r
a550d468
MK
243 &gEfiGraphicsOutputProtocolGuid,\r
244 &Private->GraphicsOutput,\r
245 &gEfiSimpleTextInProtocolGuid,\r
246 &Private->SimpleTextIn,\r
247 &gEfiSimplePointerProtocolGuid,\r
248 &Private->SimplePointer,\r
249 &gEfiSimpleTextInputExProtocolGuid,\r
250 &Private->SimpleTextInEx,\r
949f388f 251 NULL\r
252 );\r
253\r
254Done:\r
255 if (EFI_ERROR (Status)) {\r
949f388f 256 gBS->CloseProtocol (\r
a550d468
MK
257 Handle,\r
258 &gEmuIoThunkProtocolGuid,\r
259 This->DriverBindingHandle,\r
260 Handle\r
261 );\r
949f388f 262\r
263 if (Private != NULL) {\r
264 //\r
265 // On Error Free back private data\r
266 //\r
267 if (Private->ControllerNameTable != NULL) {\r
268 FreeUnicodeStringTable (Private->ControllerNameTable);\r
269 }\r
a550d468 270\r
949f388f 271 if (Private->SimpleTextIn.WaitForKey != NULL) {\r
272 gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);\r
273 }\r
a550d468 274\r
949f388f 275 if (Private->SimpleTextInEx.WaitForKeyEx != NULL) {\r
276 gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);\r
277 }\r
a550d468 278\r
949f388f 279 FreeNotifyList (&Private->NotifyList);\r
280\r
281 gBS->FreePool (Private);\r
282 }\r
283 }\r
284\r
285 return Status;\r
286}\r
287\r
949f388f 288/**\r
289 Stops a device controller or a bus controller.\r
d18d8a1d 290\r
291 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().\r
292 As a result, much of the error checking on the parameters to Stop() has been moved\r
293 into this common boot service. It is legal to call Stop() from other locations,\r
949f388f 294 but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
295 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
296 same driver's Start() function.\r
297 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
298 EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
299 Start() function, and the Start() function must have called OpenProtocol() on\r
300 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
d18d8a1d 301\r
949f388f 302 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
d18d8a1d 303 @param[in] ControllerHandle A handle to the device being stopped. The handle must\r
304 support a bus specific I/O protocol for the driver\r
949f388f 305 to use to stop the device.\r
306 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
d18d8a1d 307 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
949f388f 308 if NumberOfChildren is 0.\r
309\r
310 @retval EFI_SUCCESS The device was stopped.\r
311 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
312\r
313**/\r
314EFI_STATUS\r
315EFIAPI\r
316EmuGopDriverBindingStop (\r
317 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
318 IN EFI_HANDLE Handle,\r
319 IN UINTN NumberOfChildren,\r
320 IN EFI_HANDLE *ChildHandleBuffer\r
321 )\r
322{\r
a550d468
MK
323 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
324 EFI_STATUS Status;\r
325 GOP_PRIVATE_DATA *Private;\r
949f388f 326\r
327 Status = gBS->OpenProtocol (\r
328 Handle,\r
329 &gEfiGraphicsOutputProtocolGuid,\r
330 (VOID **)&GraphicsOutput,\r
331 This->DriverBindingHandle,\r
332 Handle,\r
333 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
334 );\r
335 if (EFI_ERROR (Status)) {\r
336 //\r
337 // If the GOP interface does not exist the driver is not started\r
338 //\r
339 return EFI_NOT_STARTED;\r
340 }\r
341\r
342 //\r
343 // Get our private context information\r
344 //\r
345 Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput);\r
346\r
347 //\r
348 // Remove the SGO interface from the system\r
349 //\r
350 Status = gBS->UninstallMultipleProtocolInterfaces (\r
351 Private->Handle,\r
a550d468
MK
352 &gEfiGraphicsOutputProtocolGuid,\r
353 &Private->GraphicsOutput,\r
354 &gEfiSimpleTextInProtocolGuid,\r
355 &Private->SimpleTextIn,\r
356 &gEfiSimplePointerProtocolGuid,\r
357 &Private->SimplePointer,\r
358 &gEfiSimpleTextInputExProtocolGuid,\r
359 &Private->SimpleTextInEx,\r
949f388f 360 NULL\r
361 );\r
362 if (!EFI_ERROR (Status)) {\r
363 //\r
364 // Shutdown the hardware\r
365 //\r
366 Status = EmuGopDestructor (Private);\r
367 if (EFI_ERROR (Status)) {\r
368 return EFI_DEVICE_ERROR;\r
369 }\r
370\r
371 gBS->CloseProtocol (\r
a550d468
MK
372 Handle,\r
373 &gEmuIoThunkProtocolGuid,\r
374 This->DriverBindingHandle,\r
375 Handle\r
376 );\r
949f388f 377\r
378 //\r
379 // Free our instance data\r
380 //\r
381 FreeUnicodeStringTable (Private->ControllerNameTable);\r
d18d8a1d 382\r
949f388f 383 Status = gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);\r
384 ASSERT_EFI_ERROR (Status);\r
d18d8a1d 385\r
949f388f 386 Status = gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);\r
387 ASSERT_EFI_ERROR (Status);\r
d18d8a1d 388\r
949f388f 389 FreeNotifyList (&Private->NotifyList);\r
390\r
391 gBS->FreePool (Private);\r
949f388f 392 }\r
393\r
394 return Status;\r
395}\r
396\r
949f388f 397///\r
d18d8a1d 398/// This protocol provides the services required to determine if a driver supports a given controller.\r
949f388f 399/// If a controller is supported, then it also provides routines to start and stop the controller.\r
400///\r
a550d468 401EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding = {\r
949f388f 402 EmuGopDriverBindingSupported,\r
403 EmuGopDriverBindingStart,\r
404 EmuGopDriverBindingStop,\r
405 0xa,\r
406 NULL,\r
407 NULL\r
408};\r
409\r
949f388f 410/**\r
411 The user Entry Point for module EmuGop. The user code starts with this function.\r
412\r
d18d8a1d 413 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
949f388f 414 @param[in] SystemTable A pointer to the EFI System Table.\r
d18d8a1d 415\r
949f388f 416 @retval EFI_SUCCESS The entry point is executed successfully.\r
417 @retval other Some error occurs when executing this entry point.\r
418\r
419**/\r
420EFI_STATUS\r
421EFIAPI\r
422InitializeEmuGop (\r
a550d468
MK
423 IN EFI_HANDLE ImageHandle,\r
424 IN EFI_SYSTEM_TABLE *SystemTable\r
949f388f 425 )\r
426{\r
a550d468 427 EFI_STATUS Status;\r
949f388f 428\r
429 Status = EfiLibInstallDriverBindingComponentName2 (\r
430 ImageHandle,\r
431 SystemTable,\r
432 &gEmuGopDriverBinding,\r
433 ImageHandle,\r
434 &gEmuGopComponentName,\r
435 &gEmuGopComponentName2\r
436 );\r
437 ASSERT_EFI_ERROR (Status);\r
438\r
949f388f 439 return Status;\r
440}\r