summaryrefslogtreecommitdiff
path: root/EmulatorPkg/EmuBusDriverDxe
diff options
context:
space:
mode:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2011-06-28 16:47:23 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2011-06-28 16:47:23 +0000
commitbb89ec1a7ec2f8d35033df9e47b3604925da3bd3 (patch)
tree32d38e02ccab98dbac4c3014a12ac365775e8eb3 /EmulatorPkg/EmuBusDriverDxe
parentd3e0289ccf641481f2cbdcbb0d5868c393b7edbb (diff)
InOsEmuPkg: Rename package to EmulatorPkg & Sec to Host
* Rename InOsEmuPkg to EmulatorPkg * Rename Unix/Sec to Unix/Host Signed-off-by: jljusten Reviewed-by: andrewfish Reviewed-by: geekboy15a git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11918 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EmulatorPkg/EmuBusDriverDxe')
-rw-r--r--EmulatorPkg/EmuBusDriverDxe/ComponentName.c247
-rw-r--r--EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.c529
-rw-r--r--EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.h116
-rw-r--r--EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf63
4 files changed, 955 insertions, 0 deletions
diff --git a/EmulatorPkg/EmuBusDriverDxe/ComponentName.c b/EmulatorPkg/EmuBusDriverDxe/ComponentName.c
new file mode 100644
index 000000000..e8be214b3
--- /dev/null
+++ b/EmulatorPkg/EmuBusDriverDxe/ComponentName.c
@@ -0,0 +1,247 @@
+/** @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+**/
+
+#include "EmuBusDriverDxe.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+EmuBusDriverComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEmuBusDriverComponentName = {
+ EmuBusDriverComponentNameGetDriverName,
+ EmuBusDriverComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuBusDriverComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmuBusDriverComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmuBusDriverComponentNameGetControllerName,
+ "en"
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mEmuBusDriverNameTable[] = {
+ { "eng", L"Emu Bus Driver" },
+ { NULL , NULL }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBusDriverComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mEmuBusDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gEmuBusDriverComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBusDriverComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIo;
+ EMU_IO_DEVICE *Private;
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gEmuBusDriverBinding.DriverBindingHandle,
+ &gEmuThunkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // This is a bus driver, so ChildHandle can not be NULL.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEmuThunkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID**)&EmuIo,
+ gEmuBusDriverBinding.DriverBindingHandle,
+ ChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = EMU_IO_DEVICE_FROM_THIS (EmuIo);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gEmuBusDriverComponentName)
+ );
+}
diff --git a/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.c b/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.c
new file mode 100644
index 000000000..0430ec3dd
--- /dev/null
+++ b/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.c
@@ -0,0 +1,529 @@
+/** @file
+ Emu Bus driver
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#include "EmuBusDriverDxe.h"
+
+
+
+//
+// DriverBinding protocol global
+//
+EFI_DRIVER_BINDING_PROTOCOL gEmuBusDriverBinding = {
+ EmuBusDriverBindingSupported,
+ EmuBusDriverBindingStart,
+ EmuBusDriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EMU_THUNK_PROTOCOL *EmuThunk;
+
+ //
+ // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
+ // it is a legal Device Path Node for this bus driver's children.
+ //
+ if (RemainingDevicePath != NULL) {
+ //
+ // Check if RemainingDevicePath is the End of Device Path Node,
+ // if yes, go on checking other conditions
+ //
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ //
+ // If RemainingDevicePath isn't the End of Device Path Node,
+ // check its validation
+ //
+ if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
+ RemainingDevicePath->SubType != HW_VENDOR_DP ||
+ DevicePathNodeLength(RemainingDevicePath) != sizeof(EMU_VENDOR_DEVICE_PATH_NODE)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ (VOID **)&EmuThunk ,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ //
+ // Open the EFI Device Path protocol needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&ParentDevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+ //
+ // Close protocol, don't use device path protocol in the Support() function
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS InstallStatus;
+ EMU_THUNK_PROTOCOL *EmuThunk;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EMU_IO_DEVICE *EmuDevice;
+ EMU_BUS_DEVICE *EmuBusDevice;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ UINT16 ComponentName[512];
+ EMU_VENDOR_DEVICE_PATH_NODE *Node;
+ BOOLEAN CreateDevice;
+
+ InstallStatus = EFI_UNSUPPORTED;
+ Status = EFI_UNSUPPORTED;
+
+ //
+ // Grab the protocols we need
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&ParentDevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ (VOID **)&EmuThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ if (Status != EFI_ALREADY_STARTED) {
+ EmuBusDevice = AllocatePool (sizeof (EMU_BUS_DEVICE));
+ if (EmuBusDevice == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EmuBusDevice->Signature = EMU_BUS_DEVICE_SIGNATURE;
+ EmuBusDevice->ControllerNameTable = NULL;
+
+ AddUnicodeString2 (
+ "eng",
+ gEmuBusDriverComponentName.SupportedLanguages,
+ &EmuBusDevice->ControllerNameTable,
+ L"Emulator Bus Controller",
+ TRUE
+ );
+ AddUnicodeString2 (
+ "en",
+ gEmuBusDriverComponentName2.SupportedLanguages,
+ &EmuBusDevice->ControllerNameTable,
+ L"Emulator Bus Controller",
+ FALSE
+ );
+
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiCallerIdGuid, EmuBusDevice,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);
+ gBS->FreePool (EmuBusDevice);
+ return Status;
+ }
+ }
+
+
+ for (Status = EFI_SUCCESS, EmuIoThunk = NULL; !EFI_ERROR (Status); ) {
+ Status = EmuThunk->GetNextProtocol (TRUE, &EmuIoThunk);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ CreateDevice = TRUE;
+ if (RemainingDevicePath != NULL) {
+ CreateDevice = FALSE;
+ //
+ // Check if RemainingDevicePath is the End of Device Path Node,
+ // if yes, don't create any child device
+ //
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ //
+ // If RemainingDevicePath isn't the End of Device Path Node,
+ // check its validation
+ //
+ Node = (EMU_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
+ if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
+ Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
+ DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (EMU_VENDOR_DEVICE_PATH_NODE)
+ ) {
+ if (CompareGuid (&Node->VendorDevicePath.Guid, EmuIoThunk->Protocol) && Node->Instance == EmuIoThunk->Instance) {
+ CreateDevice = TRUE;
+ }
+ }
+ }
+ }
+
+ if (CreateDevice) {
+ //
+ // Allocate instance structure, and fill in parent information.
+ //
+ EmuDevice = AllocatePool (sizeof (EMU_IO_DEVICE));
+ if (EmuDevice == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EmuDevice->Handle = NULL;
+ EmuDevice->ControllerHandle = ControllerHandle;
+ EmuDevice->ParentDevicePath = ParentDevicePath;
+ CopyMem (&EmuDevice->EmuIoThunk, EmuIoThunk, sizeof (EMU_IO_THUNK_PROTOCOL));
+
+ EmuDevice->ControllerNameTable = NULL;
+
+ StrnCpy (ComponentName, EmuIoThunk->ConfigString, sizeof (ComponentName)/sizeof (CHAR16));
+
+ EmuDevice->DevicePath = EmuBusCreateDevicePath (
+ ParentDevicePath,
+ EmuIoThunk->Protocol,
+ EmuIoThunk->Instance
+ );
+ if (EmuDevice->DevicePath == NULL) {
+ gBS->FreePool (EmuDevice);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AddUnicodeString (
+ "eng",
+ gEmuBusDriverComponentName.SupportedLanguages,
+ &EmuDevice->ControllerNameTable,
+ ComponentName
+ );
+
+ EmuDevice->Signature = EMU_IO_DEVICE_SIGNATURE;
+
+ InstallStatus = gBS->InstallMultipleProtocolInterfaces (
+ &EmuDevice->Handle,
+ &gEfiDevicePathProtocolGuid, EmuDevice->DevicePath,
+ &gEmuIoThunkProtocolGuid, &EmuDevice->EmuIoThunk,
+ NULL
+ );
+ if (EFI_ERROR (InstallStatus)) {
+ FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
+ gBS->FreePool (EmuDevice);
+ } else {
+ //
+ // Open For Child Device
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ (VOID **)&EmuThunk ,
+ This->DriverBindingHandle,
+ EmuDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (!EFI_ERROR (Status)) {
+ InstallStatus = EFI_SUCCESS;
+ }
+ }
+ }
+ }
+
+ return InstallStatus;
+}
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ EMU_BUS_DEVICE *EmuBusDevice;
+ EMU_IO_DEVICE *EmuDevice;
+ EMU_THUNK_PROTOCOL *EmuThunk;
+
+ //
+ // Complete all outstanding transactions to Controller.
+ // Don't allow any new transaction to Controller to be started.
+ //
+
+ if (NumberOfChildren == 0) {
+ //
+ // Close the bus driver
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiCallerIdGuid,
+ (VOID **)&EmuBusDevice,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ ControllerHandle,
+ &gEfiCallerIdGuid, EmuBusDevice,
+ NULL
+ );
+
+ FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);
+
+ gBS->FreePool (EmuBusDevice);
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ return EFI_SUCCESS;
+ }
+
+ AllChildrenStopped = TRUE;
+
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[Index],
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ EmuDevice = EMU_IO_DEVICE_FROM_THIS (EmuIoThunk);
+
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ This->DriverBindingHandle,
+ EmuDevice->Handle
+ );
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ EmuDevice->Handle,
+ &gEfiDevicePathProtocolGuid, EmuDevice->DevicePath,
+ &gEmuIoThunkProtocolGuid, EmuDevice->EmuIoThunk,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ (VOID **) &EmuThunk ,
+ This->DriverBindingHandle,
+ EmuDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ //
+ // Close the child handle
+ //
+ FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
+ FreePool (EmuDevice);
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/*++
+
+Routine Description:
+ Create a device path node using Guid and InstanceNumber and append it to
+ the passed in RootDevicePath
+
+Arguments:
+ RootDevicePath - Root of the device path to return.
+
+ Guid - GUID to use in vendor device path node.
+
+ InstanceNumber - Instance number to use in the vendor device path. This
+ argument is needed to make sure each device path is unique.
+
+Returns:
+
+ EFI_DEVICE_PATH_PROTOCOL
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EmuBusCreateDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,
+ IN EFI_GUID *Guid,
+ IN UINT16 InstanceNumber
+ )
+{
+ EMU_VENDOR_DEVICE_PATH_NODE DevicePath;
+
+ DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;
+ DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;
+ SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (EMU_VENDOR_DEVICE_PATH_NODE));
+
+ //
+ // The GUID defines the Class
+ //
+ CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));
+
+ //
+ // Add an instance number so we can make sure there are no Device Path
+ // duplication.
+ //
+ DevicePath.Instance = InstanceNumber;
+
+ return AppendDevicePathNode (
+ RootDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath
+ );
+}
+
+
+
+/**
+ The user Entry Point for module EmuBusDriver. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeEmuBusDriver (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallAllDriverProtocols (
+ ImageHandle,
+ SystemTable,
+ &gEmuBusDriverBinding,
+ ImageHandle,
+ &gEmuBusDriverComponentName,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ return Status;
+}
+
+
+
+
diff --git a/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.h b/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.h
new file mode 100644
index 000000000..e5eee5625
--- /dev/null
+++ b/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.h
@@ -0,0 +1,116 @@
+/*++ @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EMU_BUS_DRIVER_H__
+#define __EMU_BUS_DRIVER_H__
+
+#include <PiDxe.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/EmuThunk.h>
+#include <Protocol/EmuIoThunk.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+
+extern EFI_DRIVER_BINDING_PROTOCOL gEmuBusDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gEmuBusDriverComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gEmuBusDriverComponentName2;
+
+
+//
+// Unix Bus Controller Structure
+//
+#define EMU_BUS_DEVICE_SIGNATURE SIGNATURE_32 ('L', 'X', 'B', 'D')
+
+typedef struct {
+ UINT64 Signature;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+} EMU_BUS_DEVICE;
+
+//
+// Unix Child Device Controller Structure
+//
+#define EMU_IO_DEVICE_SIGNATURE SIGNATURE_32 ('L', 'X', 'V', 'D')
+
+typedef struct {
+ UINT64 Signature;
+ EFI_HANDLE Handle;
+ EMU_IO_THUNK_PROTOCOL EmuIoThunk;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // Private data about the parent
+ //
+ EFI_HANDLE ControllerHandle;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+} EMU_IO_DEVICE;
+
+#define EMU_IO_DEVICE_FROM_THIS(a) \
+ CR(a, EMU_IO_DEVICE, EmuIoThunk, EMU_IO_DEVICE_SIGNATURE)
+
+
+
+//
+// Driver Binding Protocol function prototypes
+//
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ParentHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// Unix Bus Driver private worker functions
+//
+EFI_DEVICE_PATH_PROTOCOL *
+EmuBusCreateDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,
+ IN EFI_GUID *Guid,
+ IN UINT16 InstanceNumber
+ );
+
+
+#endif
diff --git a/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf b/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
new file mode 100644
index 000000000..44f2af0cf
--- /dev/null
+++ b/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
@@ -0,0 +1,63 @@
+## @file
+# Emu Bus driver
+#
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EmuBusDriver
+ FILE_GUID = 9842073D-95D9-9F49-BD3F-2E29525125DF
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeEmuBusDriver
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+# DRIVER_BINDING = gEmuBusDriverBinding
+# COMPONENT_NAME = gEmuBusDriverComponentName
+#
+
+[Sources]
+ ComponentName.c
+ EmuBusDriverDxe.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+
+[LibraryClasses]
+ DevicePathLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ PcdLib
+ UefiLib
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+
+
+[Protocols]
+ gEfiDevicePathProtocolGuid # PROTOCOL TO_START
+ gEmuThunkProtocolGuid # PROTOCOL TO_START
+ gEmuIoThunkProtocolGuid # PROTOCOL BY_START
+
+
+