1 /** @file
2 
3 Copyright (c) 2006 - 2007, 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 
14   WinNtGopDriver.c
15 
16 Abstract:
17 
18   This file implements the UEFI Device Driver model requirements for GOP
19 
20   GOP is short hand for Graphics Output Protocol.
21 
22 
23 **/
24 #include "WinNtGop.h"
25 
26 EFI_STATUS
FreeNotifyList(IN OUT LIST_ENTRY * ListHead)27 FreeNotifyList (
28   IN OUT LIST_ENTRY           *ListHead
29   )
30 /*++
31 
32 Routine Description:
33 
34 Arguments:
35 
36   ListHead   - The list head
37 
38 Returns:
39 
40   EFI_SUCCESS           - Free the notify list successfully
41   EFI_INVALID_PARAMETER - ListHead is invalid.
42 
43 --*/
44 {
45   WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NotifyNode;
46 
47   if (ListHead == NULL) {
48     return EFI_INVALID_PARAMETER;
49   }
50   while (!IsListEmpty (ListHead)) {
51     NotifyNode = CR (
52                    ListHead->ForwardLink,
53                    WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
54                    NotifyEntry,
55                    WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
56                    );
57     RemoveEntryList (ListHead->ForwardLink);
58     gBS->FreePool (NotifyNode);
59   }
60 
61   return EFI_SUCCESS;
62 }
63 
64 EFI_DRIVER_BINDING_PROTOCOL gWinNtGopDriverBinding = {
65   WinNtGopDriverBindingSupported,
66   WinNtGopDriverBindingStart,
67   WinNtGopDriverBindingStop,
68   0xa,
69   NULL,
70   NULL
71 };
72 
73 /**
74   The user Entry Point for module WinNtGop. The user code starts with this function.
75 
76   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
77   @param[in] SystemTable    A pointer to the EFI System Table.
78 
79   @retval EFI_SUCCESS       The entry point is executed successfully.
80   @retval other             Some error occurs when executing this entry point.
81 
82 **/
83 EFI_STATUS
84 EFIAPI
InitializeWinNtGop(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)85 InitializeWinNtGop(
86   IN EFI_HANDLE           ImageHandle,
87   IN EFI_SYSTEM_TABLE     *SystemTable
88   )
89 {
90   EFI_STATUS              Status;
91 
92   //
93   // Install driver model protocol(s).
94   //
95   Status = EfiLibInstallDriverBindingComponentName2 (
96              ImageHandle,
97              SystemTable,
98              &gWinNtGopDriverBinding,
99              ImageHandle,
100              &gWinNtGopComponentName,
101              &gWinNtGopComponentName2
102              );
103   ASSERT_EFI_ERROR (Status);
104 
105 
106   return Status;
107 }
108 
109 /**
110 
111 
112   @return None
113 
114 **/
115 // TODO:    This - add argument and description to function comment
116 // TODO:    Handle - add argument and description to function comment
117 // TODO:    RemainingDevicePath - add argument and description to function comment
118 EFI_STATUS
119 EFIAPI
WinNtGopDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Handle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)120 WinNtGopDriverBindingSupported (
121   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
122   IN  EFI_HANDLE                      Handle,
123   IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
124   )
125 {
126   EFI_STATUS              Status;
127   EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;
128 
129   //
130   // Open the IO Abstraction(s) needed to perform the supported test
131   //
132   Status = gBS->OpenProtocol (
133                   Handle,
134                   &gEfiWinNtIoProtocolGuid,
135                   (VOID **) &WinNtIo,
136                   This->DriverBindingHandle,
137                   Handle,
138                   EFI_OPEN_PROTOCOL_BY_DRIVER
139                   );
140   if (EFI_ERROR (Status)) {
141     return Status;
142   }
143 
144   Status = WinNtGopSupported (WinNtIo);
145 
146   //
147   // Close the I/O Abstraction(s) used to perform the supported test
148   //
149   gBS->CloseProtocol (
150         Handle,
151         &gEfiWinNtIoProtocolGuid,
152         This->DriverBindingHandle,
153         Handle
154         );
155 
156   return Status;
157 }
158 
159 
160 /**
161 
162 
163   @return None
164 
165 **/
166 // TODO:    This - add argument and description to function comment
167 // TODO:    Handle - add argument and description to function comment
168 // TODO:    RemainingDevicePath - add argument and description to function comment
169 // TODO:    EFI_UNSUPPORTED - add return value to function comment
170 EFI_STATUS
171 EFIAPI
WinNtGopDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Handle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)172 WinNtGopDriverBindingStart (
173   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
174   IN  EFI_HANDLE                      Handle,
175   IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
176   )
177 {
178   EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;
179   EFI_STATUS              Status;
180   GOP_PRIVATE_DATA        *Private;
181 
182   //
183   // Grab the protocols we need
184   //
185   Status = gBS->OpenProtocol (
186                   Handle,
187                   &gEfiWinNtIoProtocolGuid,
188                   (VOID **) &WinNtIo,
189                   This->DriverBindingHandle,
190                   Handle,
191                   EFI_OPEN_PROTOCOL_BY_DRIVER
192                   );
193   if (EFI_ERROR (Status)) {
194     return EFI_UNSUPPORTED;
195   }
196 
197   //
198   // Allocate Private context data for SGO inteface.
199   //
200   Private = NULL;
201   Private = AllocatePool (sizeof (GOP_PRIVATE_DATA));
202   if (Private == NULL) {
203     Status = EFI_OUT_OF_RESOURCES;
204     goto Done;
205   }
206   //
207   // Set up context record
208   //
209   Private->Signature            = GOP_PRIVATE_DATA_SIGNATURE;
210   Private->Handle               = Handle;
211   Private->WinNtThunk           = WinNtIo->WinNtThunk;
212 
213   Private->ControllerNameTable  = NULL;
214 
215   AddUnicodeString2 (
216     "eng",
217     gWinNtGopComponentName.SupportedLanguages,
218     &Private->ControllerNameTable,
219     WinNtIo->EnvString,
220     TRUE
221     );
222   AddUnicodeString2 (
223     "en",
224     gWinNtGopComponentName2.SupportedLanguages,
225     &Private->ControllerNameTable,
226     WinNtIo->EnvString,
227     FALSE
228     );
229 
230 
231   Private->WindowName = WinNtIo->EnvString;
232 
233   Status              = WinNtGopConstructor (Private);
234   if (EFI_ERROR (Status)) {
235     goto Done;
236   }
237   //
238   // Publish the Gop interface to the world
239   //
240   Status = gBS->InstallMultipleProtocolInterfaces (
241                   &Private->Handle,
242                   &gEfiGraphicsOutputProtocolGuid,
243                   &Private->GraphicsOutput,
244                   &gEfiSimpleTextInProtocolGuid,
245                   &Private->SimpleTextIn,
246                   &gEfiSimpleTextInputExProtocolGuid,
247                   &Private->SimpleTextInEx,
248                   NULL
249                   );
250 
251 Done:
252   if (EFI_ERROR (Status)) {
253 
254     gBS->CloseProtocol (
255           Handle,
256           &gEfiWinNtIoProtocolGuid,
257           This->DriverBindingHandle,
258           Handle
259           );
260 
261     if (Private != NULL) {
262       //
263       // On Error Free back private data
264       //
265       if (Private->ControllerNameTable != NULL) {
266         FreeUnicodeStringTable (Private->ControllerNameTable);
267       }
268 
269       if (Private->SimpleTextIn.WaitForKey != NULL) {
270         gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
271       }
272       if (Private->SimpleTextInEx.WaitForKeyEx != NULL) {
273         gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);
274       }
275       FreeNotifyList (&Private->NotifyList);
276       FreePool (Private);
277     }
278   }
279 
280   return Status;
281 }
282 
283 
284 /**
285 
286 
287   @return None
288 
289 **/
290 // TODO:    This - add argument and description to function comment
291 // TODO:    Handle - add argument and description to function comment
292 // TODO:    NumberOfChildren - add argument and description to function comment
293 // TODO:    ChildHandleBuffer - add argument and description to function comment
294 // TODO:    EFI_NOT_STARTED - add return value to function comment
295 // TODO:    EFI_DEVICE_ERROR - add return value to function comment
296 EFI_STATUS
297 EFIAPI
WinNtGopDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Handle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)298 WinNtGopDriverBindingStop (
299   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
300   IN  EFI_HANDLE                   Handle,
301   IN  UINTN                        NumberOfChildren,
302   IN  EFI_HANDLE                   *ChildHandleBuffer
303   )
304 {
305   EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
306   EFI_STATUS                   Status;
307   GOP_PRIVATE_DATA             *Private;
308 
309   Status = gBS->OpenProtocol (
310                   Handle,
311                   &gEfiGraphicsOutputProtocolGuid,
312                   (VOID **) &GraphicsOutput,
313                   This->DriverBindingHandle,
314                   Handle,
315                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
316                   );
317   if (EFI_ERROR (Status)) {
318     //
319     // If the GOP interface does not exist the driver is not started
320     //
321     return EFI_NOT_STARTED;
322   }
323 
324   //
325   // Get our private context information
326   //
327   Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput);
328 
329   //
330   // Remove the SGO interface from the system
331   //
332   Status = gBS->UninstallMultipleProtocolInterfaces (
333                   Private->Handle,
334                   &gEfiGraphicsOutputProtocolGuid,
335                   &Private->GraphicsOutput,
336                   &gEfiSimpleTextInProtocolGuid,
337                   &Private->SimpleTextIn,
338                   &gEfiSimpleTextInputExProtocolGuid,
339                   &Private->SimpleTextInEx,
340                   NULL
341                   );
342   if (!EFI_ERROR (Status)) {
343     //
344     // Shutdown the hardware
345     //
346     Status = WinNtGopDestructor (Private);
347     if (EFI_ERROR (Status)) {
348       return EFI_DEVICE_ERROR;
349     }
350 
351     gBS->CloseProtocol (
352           Handle,
353           &gEfiWinNtIoProtocolGuid,
354           This->DriverBindingHandle,
355           Handle
356           );
357 
358     //
359     // Free our instance data
360     //
361     FreeUnicodeStringTable (Private->ControllerNameTable);
362     Status = gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
363     ASSERT_EFI_ERROR (Status);
364     Status = gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);
365     ASSERT_EFI_ERROR (Status);
366     FreeNotifyList (&Private->NotifyList);
367 
368     gBS->FreePool (Private);
369 
370   }
371 
372   return Status;
373 }
374 
375