1949f388f5fa361e3be374f59edc09b92296abe03andrewfish/*++ @file
2949f388f5fa361e3be374f59edc09b92296abe03andrewfish
3949f388f5fa361e3be374f59edc09b92296abe03andrewfishCopyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4949f388f5fa361e3be374f59edc09b92296abe03andrewfishPortions copyright (c) 2010,Apple Inc. All rights reserved.<BR>
5d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljustenThis program and the accompanying materials
6d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljustenare licensed and made available under the terms and conditions of the BSD License
7d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljustenwhich accompanies this distribution.  The full text of the license may be found at
8d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljustenhttp://opensource.org/licenses/bsd-license.php
9d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten
10d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljustenTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljustenWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12949f388f5fa361e3be374f59edc09b92296abe03andrewfish
13949f388f5fa361e3be374f59edc09b92296abe03andrewfish
14949f388f5fa361e3be374f59edc09b92296abe03andrewfish**/
15949f388f5fa361e3be374f59edc09b92296abe03andrewfish
16949f388f5fa361e3be374f59edc09b92296abe03andrewfish#include "Gop.h"
17949f388f5fa361e3be374f59edc09b92296abe03andrewfish
18949f388f5fa361e3be374f59edc09b92296abe03andrewfish
19949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFI_STATUS
20949f388f5fa361e3be374f59edc09b92296abe03andrewfishFreeNotifyList (
21949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN OUT LIST_ENTRY           *ListHead
22949f388f5fa361e3be374f59edc09b92296abe03andrewfish  )
23949f388f5fa361e3be374f59edc09b92296abe03andrewfish/*++
24949f388f5fa361e3be374f59edc09b92296abe03andrewfish
25949f388f5fa361e3be374f59edc09b92296abe03andrewfishRoutine Description:
26949f388f5fa361e3be374f59edc09b92296abe03andrewfish
27949f388f5fa361e3be374f59edc09b92296abe03andrewfishArguments:
28949f388f5fa361e3be374f59edc09b92296abe03andrewfish
29949f388f5fa361e3be374f59edc09b92296abe03andrewfish  ListHead   - The list head
30949f388f5fa361e3be374f59edc09b92296abe03andrewfish
31949f388f5fa361e3be374f59edc09b92296abe03andrewfishReturns:
32949f388f5fa361e3be374f59edc09b92296abe03andrewfish
33949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EFI_SUCCESS           - Free the notify list successfully
34949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EFI_INVALID_PARAMETER - ListHead is invalid.
35949f388f5fa361e3be374f59edc09b92296abe03andrewfish
36949f388f5fa361e3be374f59edc09b92296abe03andrewfish**/
37949f388f5fa361e3be374f59edc09b92296abe03andrewfish{
38949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NotifyNode;
39949f388f5fa361e3be374f59edc09b92296abe03andrewfish
40949f388f5fa361e3be374f59edc09b92296abe03andrewfish  if (ListHead == NULL) {
41949f388f5fa361e3be374f59edc09b92296abe03andrewfish    return EFI_INVALID_PARAMETER;
42949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
43949f388f5fa361e3be374f59edc09b92296abe03andrewfish  while (!IsListEmpty (ListHead)) {
44949f388f5fa361e3be374f59edc09b92296abe03andrewfish    NotifyNode = CR (
45d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                   ListHead->ForwardLink,
46d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                   EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
47d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                   NotifyEntry,
48949f388f5fa361e3be374f59edc09b92296abe03andrewfish                   EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
49949f388f5fa361e3be374f59edc09b92296abe03andrewfish                   );
50949f388f5fa361e3be374f59edc09b92296abe03andrewfish    RemoveEntryList (ListHead->ForwardLink);
51949f388f5fa361e3be374f59edc09b92296abe03andrewfish    gBS->FreePool (NotifyNode);
52949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
53d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten
54949f388f5fa361e3be374f59edc09b92296abe03andrewfish  return EFI_SUCCESS;
55949f388f5fa361e3be374f59edc09b92296abe03andrewfish}
56949f388f5fa361e3be374f59edc09b92296abe03andrewfish
57949f388f5fa361e3be374f59edc09b92296abe03andrewfish
58949f388f5fa361e3be374f59edc09b92296abe03andrewfish/**
59d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  Tests to see if this driver supports a given controller. If a child device is provided,
60949f388f5fa361e3be374f59edc09b92296abe03andrewfish  it further tests to see if this driver supports creating a handle for the specified child device.
61949f388f5fa361e3be374f59edc09b92296abe03andrewfish
62d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  This function checks to see if the driver specified by This supports the device specified by
63d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  ControllerHandle. Drivers will typically use the device path attached to
64d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  ControllerHandle and/or the services from the bus I/O abstraction attached to
65d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  ControllerHandle to determine if the driver supports ControllerHandle. This function
66d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  may be called many times during platform initialization. In order to reduce boot times, the tests
67d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  performed by this function must be very small, and take as little time as possible to execute. This
68d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  function must not change the state of any hardware devices, and this function must be aware that the
69d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  device specified by ControllerHandle may already be managed by the same driver or a
70d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  different driver. This function must match its calls to AllocatePages() with FreePages(),
71d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
72d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  Because ControllerHandle may have been previously started by the same driver, if a protocol is
73d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  already in the opened state, then it must not be closed with CloseProtocol(). This is required
74949f388f5fa361e3be374f59edc09b92296abe03andrewfish  to guarantee the state of ControllerHandle is not modified by this function.
75949f388f5fa361e3be374f59edc09b92296abe03andrewfish
76949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
77d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  @param[in]  ControllerHandle     The handle of the controller to test. This handle
78d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   must support a protocol interface that supplies
79949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   an I/O abstraction to the driver.
80d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
81d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   parameter is ignored by device drivers, and is optional for bus
82d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   drivers. For bus drivers, if this parameter is not NULL, then
83d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   the bus driver must determine if the bus controller specified
84d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   by ControllerHandle and the child controller specified
85d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   by RemainingDevicePath are both supported by this
86949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   bus driver.
87949f388f5fa361e3be374f59edc09b92296abe03andrewfish
88949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_SUCCESS              The device specified by ControllerHandle and
89949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   RemainingDevicePath is supported by the driver specified by This.
90949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
91949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   RemainingDevicePath is already being managed by the driver
92949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   specified by This.
93949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
94949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   RemainingDevicePath is already being managed by a different
95949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   driver or an application that requires exclusive access.
96949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   Currently not implemented.
97949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
98949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   RemainingDevicePath is not supported by the driver specified by This.
99949f388f5fa361e3be374f59edc09b92296abe03andrewfish**/
100949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFI_STATUS
101949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFIAPI
102949f388f5fa361e3be374f59edc09b92296abe03andrewfishEmuGopDriverBindingSupported (
103949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
104949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_HANDLE                      Handle,
105949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
106949f388f5fa361e3be374f59edc09b92296abe03andrewfish  )
107949f388f5fa361e3be374f59edc09b92296abe03andrewfish{
108949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EFI_STATUS              Status;
109949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EMU_IO_THUNK_PROTOCOL   *EmuIoThunk;
110949f388f5fa361e3be374f59edc09b92296abe03andrewfish
111949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
112949f388f5fa361e3be374f59edc09b92296abe03andrewfish  // Open the IO Abstraction(s) needed to perform the supported test
113949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
114949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = gBS->OpenProtocol (
115949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  Handle,
116949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEmuIoThunkProtocolGuid,
117949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  (VOID **)&EmuIoThunk,
118949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  This->DriverBindingHandle,
119949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  Handle,
120949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  EFI_OPEN_PROTOCOL_BY_DRIVER
121949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  );
122949f388f5fa361e3be374f59edc09b92296abe03andrewfish  if (EFI_ERROR (Status)) {
123949f388f5fa361e3be374f59edc09b92296abe03andrewfish    return Status;
124949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
125949f388f5fa361e3be374f59edc09b92296abe03andrewfish
126949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = EmuGopSupported (EmuIoThunk);
127949f388f5fa361e3be374f59edc09b92296abe03andrewfish
128949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
129949f388f5fa361e3be374f59edc09b92296abe03andrewfish  // Close the I/O Abstraction(s) used to perform the supported test
130949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
131949f388f5fa361e3be374f59edc09b92296abe03andrewfish  gBS->CloseProtocol (
132949f388f5fa361e3be374f59edc09b92296abe03andrewfish        Handle,
133949f388f5fa361e3be374f59edc09b92296abe03andrewfish        &gEmuIoThunkProtocolGuid,
134949f388f5fa361e3be374f59edc09b92296abe03andrewfish        This->DriverBindingHandle,
135949f388f5fa361e3be374f59edc09b92296abe03andrewfish        Handle
136949f388f5fa361e3be374f59edc09b92296abe03andrewfish        );
137949f388f5fa361e3be374f59edc09b92296abe03andrewfish
138949f388f5fa361e3be374f59edc09b92296abe03andrewfish  return Status;
139949f388f5fa361e3be374f59edc09b92296abe03andrewfish}
140949f388f5fa361e3be374f59edc09b92296abe03andrewfish
141949f388f5fa361e3be374f59edc09b92296abe03andrewfish
142949f388f5fa361e3be374f59edc09b92296abe03andrewfish/**
143949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Starts a device controller or a bus controller.
144949f388f5fa361e3be374f59edc09b92296abe03andrewfish
145949f388f5fa361e3be374f59edc09b92296abe03andrewfish  The Start() function is designed to be invoked from the EFI boot service ConnectController().
146d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  As a result, much of the error checking on the parameters to Start() has been moved into this
147d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  common boot service. It is legal to call Start() from other locations,
148949f388f5fa361e3be374f59edc09b92296abe03andrewfish  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
149949f388f5fa361e3be374f59edc09b92296abe03andrewfish  1. ControllerHandle must be a valid EFI_HANDLE.
150949f388f5fa361e3be374f59edc09b92296abe03andrewfish  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
151949f388f5fa361e3be374f59edc09b92296abe03andrewfish     EFI_DEVICE_PATH_PROTOCOL.
152949f388f5fa361e3be374f59edc09b92296abe03andrewfish  3. Prior to calling Start(), the Supported() function for the driver specified by This must
153d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
154949f388f5fa361e3be374f59edc09b92296abe03andrewfish
155949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
156d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  @param[in]  ControllerHandle     The handle of the controller to start. This handle
157d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   must support a protocol interface that supplies
158949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   an I/O abstraction to the driver.
159d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
160d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   parameter is ignored by device drivers, and is optional for bus
161d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   drivers. For a bus driver, if this parameter is NULL, then handles
162d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   for all the children of Controller are created by this driver.
163d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   If this parameter is not NULL and the first Device Path Node is
164d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   not the End of Device Path Node, then only the handle for the
165d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   child device specified by the first Device Path Node of
166949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   RemainingDevicePath is created by this driver.
167d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                   If the first Device Path Node of RemainingDevicePath is
168949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   the End of Device Path Node, no child handle is created by this
169949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                   driver.
170949f388f5fa361e3be374f59edc09b92296abe03andrewfish
171949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_SUCCESS              The device was started.
172949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
173949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
174949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval Others                   The driver failded to start the device.
175949f388f5fa361e3be374f59edc09b92296abe03andrewfish
176949f388f5fa361e3be374f59edc09b92296abe03andrewfish**/
177949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFI_STATUS
178949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFIAPI
179949f388f5fa361e3be374f59edc09b92296abe03andrewfishEmuGopDriverBindingStart (
180949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
181949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_HANDLE                      Handle,
182949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
183949f388f5fa361e3be374f59edc09b92296abe03andrewfish  )
184949f388f5fa361e3be374f59edc09b92296abe03andrewfish{
185949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EMU_IO_THUNK_PROTOCOL   *EmuIoThunk;
186949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EFI_STATUS              Status;
187949f388f5fa361e3be374f59edc09b92296abe03andrewfish  GOP_PRIVATE_DATA        *Private;
188949f388f5fa361e3be374f59edc09b92296abe03andrewfish
189949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
190949f388f5fa361e3be374f59edc09b92296abe03andrewfish  // Grab the protocols we need
191949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
192949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = gBS->OpenProtocol (
193949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  Handle,
194949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEmuIoThunkProtocolGuid,
195949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  (VOID **)&EmuIoThunk,
196949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  This->DriverBindingHandle,
197949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  Handle,
198949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  EFI_OPEN_PROTOCOL_BY_DRIVER
199949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  );
200949f388f5fa361e3be374f59edc09b92296abe03andrewfish  if (EFI_ERROR (Status)) {
201949f388f5fa361e3be374f59edc09b92296abe03andrewfish    return EFI_UNSUPPORTED;
202949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
203949f388f5fa361e3be374f59edc09b92296abe03andrewfish
204949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
205949f388f5fa361e3be374f59edc09b92296abe03andrewfish  // Allocate Private context data for SGO inteface.
206949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
207949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Private = NULL;
208949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = gBS->AllocatePool (
209949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  EfiBootServicesData,
210949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  sizeof (GOP_PRIVATE_DATA),
211949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  (VOID **)&Private
212949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  );
213949f388f5fa361e3be374f59edc09b92296abe03andrewfish  if (EFI_ERROR (Status)) {
214949f388f5fa361e3be374f59edc09b92296abe03andrewfish    goto Done;
215949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
216949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
217949f388f5fa361e3be374f59edc09b92296abe03andrewfish  // Set up context record
218949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
219949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Private->Signature           = GOP_PRIVATE_DATA_SIGNATURE;
220949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Private->Handle              = Handle;
221949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Private->EmuIoThunk          = EmuIoThunk;
222949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Private->WindowName          = EmuIoThunk->ConfigString;
223949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Private->ControllerNameTable = NULL;
224949f388f5fa361e3be374f59edc09b92296abe03andrewfish
225949f388f5fa361e3be374f59edc09b92296abe03andrewfish  AddUnicodeString (
226949f388f5fa361e3be374f59edc09b92296abe03andrewfish    "eng",
227949f388f5fa361e3be374f59edc09b92296abe03andrewfish    gEmuGopComponentName.SupportedLanguages,
228949f388f5fa361e3be374f59edc09b92296abe03andrewfish    &Private->ControllerNameTable,
229949f388f5fa361e3be374f59edc09b92296abe03andrewfish    EmuIoThunk->ConfigString
230949f388f5fa361e3be374f59edc09b92296abe03andrewfish    );
231949f388f5fa361e3be374f59edc09b92296abe03andrewfish  AddUnicodeString2 (
232949f388f5fa361e3be374f59edc09b92296abe03andrewfish    "en",
233949f388f5fa361e3be374f59edc09b92296abe03andrewfish    gEmuGopComponentName2.SupportedLanguages,
234949f388f5fa361e3be374f59edc09b92296abe03andrewfish    &Private->ControllerNameTable,
235949f388f5fa361e3be374f59edc09b92296abe03andrewfish    EmuIoThunk->ConfigString,
236949f388f5fa361e3be374f59edc09b92296abe03andrewfish    FALSE
237949f388f5fa361e3be374f59edc09b92296abe03andrewfish    );
238949f388f5fa361e3be374f59edc09b92296abe03andrewfish
239949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = EmuGopConstructor (Private);
240949f388f5fa361e3be374f59edc09b92296abe03andrewfish  if (EFI_ERROR (Status)) {
241949f388f5fa361e3be374f59edc09b92296abe03andrewfish    goto Done;
242949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
243949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
244949f388f5fa361e3be374f59edc09b92296abe03andrewfish  // Publish the Gop interface to the world
245949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
246949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = gBS->InstallMultipleProtocolInterfaces (
247949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &Private->Handle,
248949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiGraphicsOutputProtocolGuid,    &Private->GraphicsOutput,
249949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiSimpleTextInProtocolGuid,      &Private->SimpleTextIn,
250949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiSimplePointerProtocolGuid,     &Private->SimplePointer,
251949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiSimpleTextInputExProtocolGuid, &Private->SimpleTextInEx,
252949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  NULL
253949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  );
254949f388f5fa361e3be374f59edc09b92296abe03andrewfish
255949f388f5fa361e3be374f59edc09b92296abe03andrewfishDone:
256949f388f5fa361e3be374f59edc09b92296abe03andrewfish  if (EFI_ERROR (Status)) {
257949f388f5fa361e3be374f59edc09b92296abe03andrewfish
258949f388f5fa361e3be374f59edc09b92296abe03andrewfish    gBS->CloseProtocol (
259949f388f5fa361e3be374f59edc09b92296abe03andrewfish          Handle,
260949f388f5fa361e3be374f59edc09b92296abe03andrewfish          &gEmuIoThunkProtocolGuid,
261949f388f5fa361e3be374f59edc09b92296abe03andrewfish          This->DriverBindingHandle,
262949f388f5fa361e3be374f59edc09b92296abe03andrewfish          Handle
263949f388f5fa361e3be374f59edc09b92296abe03andrewfish          );
264949f388f5fa361e3be374f59edc09b92296abe03andrewfish
265949f388f5fa361e3be374f59edc09b92296abe03andrewfish    if (Private != NULL) {
266949f388f5fa361e3be374f59edc09b92296abe03andrewfish      //
267949f388f5fa361e3be374f59edc09b92296abe03andrewfish      // On Error Free back private data
268949f388f5fa361e3be374f59edc09b92296abe03andrewfish      //
269949f388f5fa361e3be374f59edc09b92296abe03andrewfish      if (Private->ControllerNameTable != NULL) {
270949f388f5fa361e3be374f59edc09b92296abe03andrewfish        FreeUnicodeStringTable (Private->ControllerNameTable);
271949f388f5fa361e3be374f59edc09b92296abe03andrewfish      }
272949f388f5fa361e3be374f59edc09b92296abe03andrewfish      if (Private->SimpleTextIn.WaitForKey != NULL) {
273949f388f5fa361e3be374f59edc09b92296abe03andrewfish        gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
274949f388f5fa361e3be374f59edc09b92296abe03andrewfish      }
275949f388f5fa361e3be374f59edc09b92296abe03andrewfish      if (Private->SimpleTextInEx.WaitForKeyEx != NULL) {
276949f388f5fa361e3be374f59edc09b92296abe03andrewfish        gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);
277949f388f5fa361e3be374f59edc09b92296abe03andrewfish      }
278949f388f5fa361e3be374f59edc09b92296abe03andrewfish      FreeNotifyList (&Private->NotifyList);
279949f388f5fa361e3be374f59edc09b92296abe03andrewfish
280949f388f5fa361e3be374f59edc09b92296abe03andrewfish      gBS->FreePool (Private);
281949f388f5fa361e3be374f59edc09b92296abe03andrewfish    }
282949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
283949f388f5fa361e3be374f59edc09b92296abe03andrewfish
284949f388f5fa361e3be374f59edc09b92296abe03andrewfish  return Status;
285949f388f5fa361e3be374f59edc09b92296abe03andrewfish}
286949f388f5fa361e3be374f59edc09b92296abe03andrewfish
287949f388f5fa361e3be374f59edc09b92296abe03andrewfish
288949f388f5fa361e3be374f59edc09b92296abe03andrewfish
289949f388f5fa361e3be374f59edc09b92296abe03andrewfish/**
290949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Stops a device controller or a bus controller.
291d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten
292d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
293d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  As a result, much of the error checking on the parameters to Stop() has been moved
294d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  into this common boot service. It is legal to call Stop() from other locations,
295949f388f5fa361e3be374f59edc09b92296abe03andrewfish  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
296949f388f5fa361e3be374f59edc09b92296abe03andrewfish  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
297949f388f5fa361e3be374f59edc09b92296abe03andrewfish     same driver's Start() function.
298949f388f5fa361e3be374f59edc09b92296abe03andrewfish  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
299949f388f5fa361e3be374f59edc09b92296abe03andrewfish     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
300949f388f5fa361e3be374f59edc09b92296abe03andrewfish     Start() function, and the Start() function must have called OpenProtocol() on
301949f388f5fa361e3be374f59edc09b92296abe03andrewfish     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
302d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten
303949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
304d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
305d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten                                support a bus specific I/O protocol for the driver
306949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                to use to stop the device.
307949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
308d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
309949f388f5fa361e3be374f59edc09b92296abe03andrewfish                                if NumberOfChildren is 0.
310949f388f5fa361e3be374f59edc09b92296abe03andrewfish
311949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_SUCCESS           The device was stopped.
312949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
313949f388f5fa361e3be374f59edc09b92296abe03andrewfish
314949f388f5fa361e3be374f59edc09b92296abe03andrewfish**/
315949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFI_STATUS
316949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFIAPI
317949f388f5fa361e3be374f59edc09b92296abe03andrewfishEmuGopDriverBindingStop (
318949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
319949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_HANDLE                   Handle,
320949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  UINTN                        NumberOfChildren,
321949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN  EFI_HANDLE                   *ChildHandleBuffer
322949f388f5fa361e3be374f59edc09b92296abe03andrewfish  )
323949f388f5fa361e3be374f59edc09b92296abe03andrewfish{
324949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
325949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EFI_STATUS                   Status;
326949f388f5fa361e3be374f59edc09b92296abe03andrewfish  GOP_PRIVATE_DATA             *Private;
327949f388f5fa361e3be374f59edc09b92296abe03andrewfish
328949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = gBS->OpenProtocol (
329949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  Handle,
330949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiGraphicsOutputProtocolGuid,
331949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  (VOID **)&GraphicsOutput,
332949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  This->DriverBindingHandle,
333949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  Handle,
334949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
335949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  );
336949f388f5fa361e3be374f59edc09b92296abe03andrewfish  if (EFI_ERROR (Status)) {
337949f388f5fa361e3be374f59edc09b92296abe03andrewfish    //
338949f388f5fa361e3be374f59edc09b92296abe03andrewfish    // If the GOP interface does not exist the driver is not started
339949f388f5fa361e3be374f59edc09b92296abe03andrewfish    //
340949f388f5fa361e3be374f59edc09b92296abe03andrewfish    return EFI_NOT_STARTED;
341949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
342949f388f5fa361e3be374f59edc09b92296abe03andrewfish
343949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
344949f388f5fa361e3be374f59edc09b92296abe03andrewfish  // Get our private context information
345949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
346949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput);
347949f388f5fa361e3be374f59edc09b92296abe03andrewfish
348949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
349949f388f5fa361e3be374f59edc09b92296abe03andrewfish  // Remove the SGO interface from the system
350949f388f5fa361e3be374f59edc09b92296abe03andrewfish  //
351949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = gBS->UninstallMultipleProtocolInterfaces (
352949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  Private->Handle,
353949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiGraphicsOutputProtocolGuid,    &Private->GraphicsOutput,
354949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiSimpleTextInProtocolGuid,      &Private->SimpleTextIn,
355949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiSimplePointerProtocolGuid,     &Private->SimplePointer,
356949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  &gEfiSimpleTextInputExProtocolGuid, &Private->SimpleTextInEx,
357949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  NULL
358949f388f5fa361e3be374f59edc09b92296abe03andrewfish                  );
359949f388f5fa361e3be374f59edc09b92296abe03andrewfish  if (!EFI_ERROR (Status)) {
360949f388f5fa361e3be374f59edc09b92296abe03andrewfish    //
361949f388f5fa361e3be374f59edc09b92296abe03andrewfish    // Shutdown the hardware
362949f388f5fa361e3be374f59edc09b92296abe03andrewfish    //
363949f388f5fa361e3be374f59edc09b92296abe03andrewfish    Status = EmuGopDestructor (Private);
364949f388f5fa361e3be374f59edc09b92296abe03andrewfish    if (EFI_ERROR (Status)) {
365949f388f5fa361e3be374f59edc09b92296abe03andrewfish      return EFI_DEVICE_ERROR;
366949f388f5fa361e3be374f59edc09b92296abe03andrewfish    }
367949f388f5fa361e3be374f59edc09b92296abe03andrewfish
368949f388f5fa361e3be374f59edc09b92296abe03andrewfish    gBS->CloseProtocol (
369949f388f5fa361e3be374f59edc09b92296abe03andrewfish          Handle,
370949f388f5fa361e3be374f59edc09b92296abe03andrewfish          &gEmuIoThunkProtocolGuid,
371949f388f5fa361e3be374f59edc09b92296abe03andrewfish          This->DriverBindingHandle,
372949f388f5fa361e3be374f59edc09b92296abe03andrewfish          Handle
373949f388f5fa361e3be374f59edc09b92296abe03andrewfish          );
374949f388f5fa361e3be374f59edc09b92296abe03andrewfish
375949f388f5fa361e3be374f59edc09b92296abe03andrewfish    //
376949f388f5fa361e3be374f59edc09b92296abe03andrewfish    // Free our instance data
377949f388f5fa361e3be374f59edc09b92296abe03andrewfish    //
378949f388f5fa361e3be374f59edc09b92296abe03andrewfish    FreeUnicodeStringTable (Private->ControllerNameTable);
379d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten
380949f388f5fa361e3be374f59edc09b92296abe03andrewfish    Status = gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
381949f388f5fa361e3be374f59edc09b92296abe03andrewfish    ASSERT_EFI_ERROR (Status);
382d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten
383949f388f5fa361e3be374f59edc09b92296abe03andrewfish    Status = gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);
384949f388f5fa361e3be374f59edc09b92296abe03andrewfish    ASSERT_EFI_ERROR (Status);
385d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten
386949f388f5fa361e3be374f59edc09b92296abe03andrewfish    FreeNotifyList (&Private->NotifyList);
387949f388f5fa361e3be374f59edc09b92296abe03andrewfish
388949f388f5fa361e3be374f59edc09b92296abe03andrewfish    gBS->FreePool (Private);
389949f388f5fa361e3be374f59edc09b92296abe03andrewfish
390949f388f5fa361e3be374f59edc09b92296abe03andrewfish  }
391949f388f5fa361e3be374f59edc09b92296abe03andrewfish
392949f388f5fa361e3be374f59edc09b92296abe03andrewfish  return Status;
393949f388f5fa361e3be374f59edc09b92296abe03andrewfish}
394949f388f5fa361e3be374f59edc09b92296abe03andrewfish
395949f388f5fa361e3be374f59edc09b92296abe03andrewfish
396949f388f5fa361e3be374f59edc09b92296abe03andrewfish///
397d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten/// This protocol provides the services required to determine if a driver supports a given controller.
398949f388f5fa361e3be374f59edc09b92296abe03andrewfish/// If a controller is supported, then it also provides routines to start and stop the controller.
399949f388f5fa361e3be374f59edc09b92296abe03andrewfish///
400949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding = {
401949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EmuGopDriverBindingSupported,
402949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EmuGopDriverBindingStart,
403949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EmuGopDriverBindingStop,
404949f388f5fa361e3be374f59edc09b92296abe03andrewfish  0xa,
405949f388f5fa361e3be374f59edc09b92296abe03andrewfish  NULL,
406949f388f5fa361e3be374f59edc09b92296abe03andrewfish  NULL
407949f388f5fa361e3be374f59edc09b92296abe03andrewfish};
408949f388f5fa361e3be374f59edc09b92296abe03andrewfish
409949f388f5fa361e3be374f59edc09b92296abe03andrewfish
410949f388f5fa361e3be374f59edc09b92296abe03andrewfish
411949f388f5fa361e3be374f59edc09b92296abe03andrewfish/**
412949f388f5fa361e3be374f59edc09b92296abe03andrewfish  The user Entry Point for module EmuGop. The user code starts with this function.
413949f388f5fa361e3be374f59edc09b92296abe03andrewfish
414d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
415949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @param[in] SystemTable    A pointer to the EFI System Table.
416d18d8a1d0e370f8ce6ccc2725f4170586d457e53jljusten
417949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval EFI_SUCCESS       The entry point is executed successfully.
418949f388f5fa361e3be374f59edc09b92296abe03andrewfish  @retval other             Some error occurs when executing this entry point.
419949f388f5fa361e3be374f59edc09b92296abe03andrewfish
420949f388f5fa361e3be374f59edc09b92296abe03andrewfish**/
421949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFI_STATUS
422949f388f5fa361e3be374f59edc09b92296abe03andrewfishEFIAPI
423949f388f5fa361e3be374f59edc09b92296abe03andrewfishInitializeEmuGop (
424949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN EFI_HANDLE           ImageHandle,
425949f388f5fa361e3be374f59edc09b92296abe03andrewfish  IN EFI_SYSTEM_TABLE     *SystemTable
426949f388f5fa361e3be374f59edc09b92296abe03andrewfish  )
427949f388f5fa361e3be374f59edc09b92296abe03andrewfish{
428949f388f5fa361e3be374f59edc09b92296abe03andrewfish  EFI_STATUS              Status;
429949f388f5fa361e3be374f59edc09b92296abe03andrewfish
430949f388f5fa361e3be374f59edc09b92296abe03andrewfish  Status = EfiLibInstallDriverBindingComponentName2 (
431949f388f5fa361e3be374f59edc09b92296abe03andrewfish             ImageHandle,
432949f388f5fa361e3be374f59edc09b92296abe03andrewfish             SystemTable,
433949f388f5fa361e3be374f59edc09b92296abe03andrewfish             &gEmuGopDriverBinding,
434949f388f5fa361e3be374f59edc09b92296abe03andrewfish             ImageHandle,
435949f388f5fa361e3be374f59edc09b92296abe03andrewfish             &gEmuGopComponentName,
436949f388f5fa361e3be374f59edc09b92296abe03andrewfish             &gEmuGopComponentName2
437949f388f5fa361e3be374f59edc09b92296abe03andrewfish             );
438949f388f5fa361e3be374f59edc09b92296abe03andrewfish  ASSERT_EFI_ERROR (Status);
439949f388f5fa361e3be374f59edc09b92296abe03andrewfish
440949f388f5fa361e3be374f59edc09b92296abe03andrewfish
441949f388f5fa361e3be374f59edc09b92296abe03andrewfish  return Status;
442949f388f5fa361e3be374f59edc09b92296abe03andrewfish}
443949f388f5fa361e3be374f59edc09b92296abe03andrewfish
444