summaryrefslogtreecommitdiff
path: root/EdkUnixPkg/Dxe/UnixThunk/Bus
diff options
context:
space:
mode:
authortgingold <tgingold@6f19259b-4bc3-4df7-8a09-765794883524>2007-01-06 14:59:06 +0000
committertgingold <tgingold@6f19259b-4bc3-4df7-8a09-765794883524>2007-01-06 14:59:06 +0000
commitc9093a06e72ef16d2f3bd7ce0a2b9a172e9d048c (patch)
tree02dfc93be892697bf02f040b6c8429cecc8370ce /EdkUnixPkg/Dxe/UnixThunk/Bus
parent8ba7afaf2e9c682a5d17760e6dd5463b3a2b2d67 (diff)
downloadedk2-platforms-c9093a06e72ef16d2f3bd7ce0a2b9a172e9d048c.tar.xz
Unix version of EFI emulator
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2182 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkUnixPkg/Dxe/UnixThunk/Bus')
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/ComponentName.c187
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/DriverConfiguration.c338
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/DriverDiagnostics.c187
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.c1287
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.h207
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.msa91
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ComponentName.c187
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Console/Console.c310
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Console/Console.h513
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ConsoleIn.c246
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ConsoleOut.c635
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Console/UnixConsole.msa86
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/ComponentName.c193
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.c2106
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.h582
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.msa94
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/ComponentName.c187
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUga.h289
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUga.msa101
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaDriver.c296
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaInput.c221
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaScreen.c446
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/ComponentName.c187
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c717
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.h297
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa171
26 files changed, 10161 insertions, 0 deletions
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/ComponentName.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/ComponentName.c
new file mode 100644
index 0000000000..fd4b75e46f
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/ComponentName.c
@@ -0,0 +1,187 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+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.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "UnixBlockIo.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+UnixBlockIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoComponentNameGetControllerName (
+ 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
+//
+EFI_COMPONENT_NAME_PROTOCOL gUnixBlockIoComponentName = {
+ UnixBlockIoComponentNameGetDriverName,
+ UnixBlockIoComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mUnixBlockIoDriverNameTable[] = {
+ { "eng", L"Unix Block I/O Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that 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.
+ DriverName - 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.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gUnixBlockIoComponentName.SupportedLanguages,
+ mUnixBlockIoDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - 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.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that 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.
+ ControllerName - 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.
+
+ Returns:
+ 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.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ UNIX_BLOCK_IO_PRIVATE *Private;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ (void *)&BlockIo,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo);
+
+ return LookupUnicodeString (
+ Language,
+ gUnixBlockIoComponentName.SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName
+ );
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/DriverConfiguration.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/DriverConfiguration.c
new file mode 100644
index 0000000000..d06b5fba4d
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/DriverConfiguration.c
@@ -0,0 +1,338 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+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.
+
+Module Name:
+
+ DriverConfiguration.c
+
+Abstract:
+
+--*/
+
+#include "UnixBlockIo.h"
+
+//
+// EFI Driver Configuration Functions
+//
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverConfigurationSetOptions (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired
+ );
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverConfigurationOptionsValid (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverConfigurationForceDefaults (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN UINT32 DefaultType,
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired
+ );
+
+//
+// EFI Driver Configuration Protocol
+//
+EFI_DRIVER_CONFIGURATION_PROTOCOL gUnixBlockIoDriverConfiguration = {
+ UnixBlockIoDriverConfigurationSetOptions,
+ UnixBlockIoDriverConfigurationOptionsValid,
+ UnixBlockIoDriverConfigurationForceDefaults,
+ LANGUAGESUPPORTED
+};
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverConfigurationSetOptions (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired
+ )
+/*++
+
+ Routine Description:
+ Allows the user to set controller specific options for a controller that a
+ driver is currently managing.
+
+ Arguments:
+ This - A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.
+ ControllerHandle - The handle of the controller to set options on.
+ ChildHandle - The handle of the child controller to set options on. This
+ is an optional parameter that may be NULL. It will be NULL
+ for device drivers, and for a bus drivers that wish to set
+ options for the bus controller. It will not be NULL for a
+ bus driver that wishes to set options for one of its child
+ controllers.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the user interface that should be
+ presented to the user, 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.
+ ActionRequired - A pointer to the action that the calling agent is required
+ to perform when this function returns. See "Related
+ Definitions" for a list of the actions that the calling
+ agent is required to perform prior to accessing
+ ControllerHandle again.
+
+ Returns:
+ EFI_SUCCESS - The driver specified by This successfully set the
+ configuration options for the controller specified
+ by ControllerHandle..
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ActionRequired is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support setting
+ configuration options for the controller specified by
+ ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+ EFI_DEVICE_ERROR - A device error occurred while attempt to set the
+ configuration options for the controller specified
+ by ControllerHandle and ChildHandle.
+ EFI_OUT_RESOURCES - There are not enough resources available to set the
+ configuration options for the controller specified
+ by ControllerHandle and ChildHandle.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ CHAR8 *SupportedLanguage;
+
+ SupportedLanguage = This->SupportedLanguages;
+
+ Status = EFI_UNSUPPORTED;
+ while (*SupportedLanguage != 0) {
+ if (AsciiStrnCmp (Language, SupportedLanguage, 3)) {
+ Status = EFI_SUCCESS;
+ }
+
+ SupportedLanguage += 3;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (ActionRequired == NULL || ControllerHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Validate controller handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ (void *)&BlockIo,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ return Status;
+ } else if (Status != EFI_ALREADY_STARTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ActionRequired = EfiDriverConfigurationActionNone;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverConfigurationOptionsValid (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Tests to see if a controller's current configuration options are valid.
+
+ Arguments:
+ This - A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance.
+ ControllerHandle - The handle of the controller to test if it's current
+ configuration options are valid.
+ ChildHandle - The handle of the child controller to test if it's current
+ configuration options are valid. 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 test the configuration options for the bus controller.
+ It will not be NULL for a bus driver that wishes to test
+ configuration options for one of its child controllers.
+
+ Returns:
+ EFI_SUCCESS - The controller specified by ControllerHandle and
+ ChildHandle that is being managed by the driver
+ specified by This has a valid set of configuration
+ options.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_UNSUPPORTED - The driver specified by This is not currently
+ managing the controller specified by ControllerHandle
+ and ChildHandle.
+ EFI_DEVICE_ERROR - The controller specified by ControllerHandle and
+ ChildHandle that is being managed by the driver
+ specified by This has an invalid set of configuration
+ options.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (ControllerHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Validate controller handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ (void *)&BlockIo,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ return Status;
+ } else if (Status != EFI_ALREADY_STARTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverConfigurationForceDefaults (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN UINT32 DefaultType,
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired
+ )
+/*++
+
+ Routine Description:
+ Forces a driver to set the default configuration options for a controller.
+
+ Arguments:
+ This - A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.
+ ControllerHandle - The handle of the controller to force default configuration options on.
+ ChildHandle - The handle of the child controller to force default configuration options on 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 force default configuration options for the bus controller. It will not be NULL for a bus driver that wishes to force default configuration options for one of its child controllers.
+ DefaultType - The type of default configuration options to force on the controller specified by ControllerHandle and ChildHandle. See Table 9-1 for legal values. A DefaultType of 0x00000000 must be supported by this protocol.
+ ActionRequired - A pointer to the action that the calling agent is required to perform when this function returns. See "Related Definitions" in Section 9.1for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again.
+
+ Returns:
+ EFI_SUCCESS - The driver specified by This successfully forced the default configuration options on the controller specified by ControllerHandle and ChildHandle.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ActionRequired is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support forcing the default configuration options on the controller specified by ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the configuration type specified by DefaultType.
+ EFI_DEVICE_ERROR - A device error occurred while attempt to force the default configuration options on the controller specified by ControllerHandle and ChildHandle.
+ EFI_OUT_RESOURCES - There are not enough resources available to force the default configuration options on the controller specified by ControllerHandle and ChildHandle.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (ActionRequired == NULL || ControllerHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Validate controller handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ (void *)&BlockIo,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ return Status;
+ } else if (Status != EFI_ALREADY_STARTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ActionRequired = EfiDriverConfigurationActionNone;
+ return EFI_SUCCESS;
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/DriverDiagnostics.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/DriverDiagnostics.c
new file mode 100644
index 0000000000..0e9a32c66a
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/DriverDiagnostics.c
@@ -0,0 +1,187 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+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.
+
+Module Name:
+
+ DriverDiagnostics.c
+
+Abstract:
+
+--*/
+
+#include "UnixBlockIo.h"
+
+//
+// EFI Driver Diagnostics Functions
+//
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverDiagnosticsRunDiagnostics (
+ IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,
+ IN CHAR8 *Language,
+ OUT EFI_GUID **ErrorType,
+ OUT UINTN *BufferSize,
+ OUT CHAR16 **Buffer
+ );
+
+//
+// EFI Driver Diagnostics Protocol
+//
+EFI_DRIVER_DIAGNOSTICS_PROTOCOL gUnixBlockIoDriverDiagnostics = {
+ UnixBlockIoDriverDiagnosticsRunDiagnostics,
+ LANGUAGESUPPORTED
+};
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverDiagnosticsRunDiagnostics (
+ IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,
+ IN CHAR8 *Language,
+ OUT EFI_GUID **ErrorType,
+ OUT UINTN *BufferSize,
+ OUT CHAR16 **Buffer
+ )
+/*++
+
+ Routine Description:
+ Runs diagnostics on a controller.
+
+ Arguments:
+ This - A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL instance.
+ ControllerHandle - The handle of the controller to run diagnostics on.
+ ChildHandle - The handle of the child controller to run diagnostics on
+ 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 run diagnostics on the bus
+ controller. It will not be NULL for a bus driver that
+ wishes to run diagnostics on one of its child controllers.
+ DiagnosticType - Indicates type of diagnostics to perform on the controller
+ specified by ControllerHandle and ChildHandle. See
+ "Related Definitions" for the list of supported types.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language in which the optional
+ error message should be returned in Buffer, 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.
+ ErrorType - A GUID that defines the format of the data returned in
+ Buffer.
+ BufferSize - The size, in bytes, of the data returned in Buffer.
+ Buffer - A buffer that contains a Null-terminated Unicode string
+ plus some additional data whose format is defined by
+ ErrorType. Buffer is allocated by this function with
+ AllocatePool(), and it is the caller's responsibility
+ to free it with a call to FreePool().
+
+ Returns:
+ EFI_SUCCESS - The controller specified by ControllerHandle and
+ ChildHandle passed the diagnostic.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ErrorType is NULL.
+ EFI_INVALID_PARAMETER - BufferType is NULL.
+ EFI_INVALID_PARAMETER - Buffer is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support
+ running diagnostics for the controller specified
+ by ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ type of diagnostic specified by DiagnosticType.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+ EFI_OUT_OF_RESOURCES - There are not enough resources available to complete
+ the diagnostics.
+ EFI_OUT_OF_RESOURCES - There are not enough resources available to return
+ the status information in ErrorType, BufferSize,
+ and Buffer.
+ EFI_DEVICE_ERROR - The controller specified by ControllerHandle and
+ ChildHandle did not pass the diagnostic.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ CHAR8 *SupportedLanguage;
+
+ if (Language == NULL ||
+ ErrorType == NULL ||
+ Buffer == NULL ||
+ ControllerHandle == NULL ||
+ BufferSize == NULL) {
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SupportedLanguage = This->SupportedLanguages;
+
+ Status = EFI_UNSUPPORTED;
+ while (*SupportedLanguage != 0) {
+ if (AsciiStrnCmp (Language, SupportedLanguage, 3)) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ SupportedLanguage += 3;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *ErrorType = NULL;
+ *BufferSize = 0;
+ if (DiagnosticType != EfiDriverDiagnosticTypeStandard) {
+ *ErrorType = &gEfiBlockIoProtocolGuid;
+ *BufferSize = 0x60;
+ gBS->AllocatePool (EfiBootServicesData, (UINTN) (*BufferSize),
+ (void *)Buffer);
+ CopyMem (*Buffer, L"Unix Block I/O Driver Diagnostics Failed\n", *BufferSize);
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Validate controller handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ (void *)&BlockIo,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ gUnixBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ return Status;
+ } else if (Status != EFI_ALREADY_STARTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.c
new file mode 100644
index 0000000000..ca4a5f2ff8
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.c
@@ -0,0 +1,1287 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+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.
+
+Module Name:
+
+ UnixBlockIo.c
+
+Abstract:
+
+ Produce block IO abstractions for real devices on your PC using Win32 APIs.
+ The configuration of what devices to mount or emulate comes from NT
+ environment variables. The variables must be visible to the Microsoft*
+ Developer Studio for them to work.
+
+ <F>ixed - Fixed disk like a hard drive.
+ <R>emovable - Removable media like a floppy or CD-ROM.
+ Read <O>nly - Write protected device.
+ Read <W>rite - Read write device.
+ <block count> - Decimal number of blocks a device supports.
+ <block size> - Decimal number of bytes per block.
+
+ NT envirnonment variable contents. '<' and '>' are not part of the variable,
+ they are just used to make this help more readable. There should be no
+ spaces between the ';'. Extra spaces will break the variable. A '!' is
+ used to seperate multiple devices in a variable.
+
+ EFI_UNIX_VIRTUAL_DISKS =
+ <F | R><O | W>;<block count>;<block size>[!...]
+
+ EFI_UNIX_PHYSICAL_DISKS =
+ <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
+
+ Virtual Disks: These devices use a file to emulate a hard disk or removable
+ media device.
+
+ Thus a 20 MB emulated hard drive would look like:
+ EFI_UNIX_VIRTUAL_DISKS=FW;40960;512
+
+ A 1.44MB emulated floppy with a block size of 1024 would look like:
+ EFI_UNIX_VIRTUAL_DISKS=RW;1440;1024
+
+ Physical Disks: These devices use NT to open a real device in your system
+
+ Thus a 120 MB floppy would look like:
+ EFI_UNIX_PHYSICAL_DISKS=B:RW;245760;512
+
+ Thus a standard CD-ROM floppy would look like:
+ EFI_UNIX_PHYSICAL_DISKS=Z:RO;307200;2048
+
+
+ * Other names and brands may be claimed as the property of others.
+
+--*/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include "UnixBlockIo.h"
+
+//
+// Block IO protocol member functions
+//
+STATIC
+EFI_STATUS
+EFIAPI
+UnixBlockIoReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ MediaId - TODO: add argument description
+ Lba - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixBlockIoWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ MediaId - TODO: add argument description
+ Lba - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixBlockIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixBlockIoResetBlock (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ExtendedVerification - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+//
+// Private Worker functions
+//
+STATIC
+EFI_STATUS
+UnixBlockIoCreateMapping (
+ IN EFI_UNIX_IO_PROTOCOL *UnixIo,
+ IN EFI_HANDLE EfiDeviceHandle,
+ IN CHAR16 *Filename,
+ IN BOOLEAN ReadOnly,
+ IN BOOLEAN RemovableMedia,
+ IN UINTN NumberOfBlocks,
+ IN UINTN BlockSize
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ UnixIo - TODO: add argument description
+ EfiDeviceHandle - TODO: add argument description
+ Filename - TODO: add argument description
+ ReadOnly - TODO: add argument description
+ RemovableMedia - TODO: add argument description
+ NumberOfBlocks - TODO: add argument description
+ BlockSize - TODO: add argument description
+ DeviceType - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+UnixBlockIoReadWriteCommon (
+ IN UNIX_BLOCK_IO_PRIVATE *Private,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer,
+ IN CHAR8 *CallerName
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+ MediaId - TODO: add argument description
+ Lba - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+ CallerName - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+UnixBlockIoError (
+ IN UNIX_BLOCK_IO_PRIVATE *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+UnixBlockIoOpenDevice (
+ UNIX_BLOCK_IO_PRIVATE *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+CHAR16 *
+GetNextElementPastTerminator (
+ IN CHAR16 *EnvironmentVariable,
+ IN CHAR16 Terminator
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ EnvironmentVariable - TODO: add argument description
+ Terminator - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+EFI_DRIVER_BINDING_PROTOCOL gUnixBlockIoDriverBinding = {
+ UnixBlockIoDriverBindingSupported,
+ UnixBlockIoDriverBindingStart,
+ UnixBlockIoDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Handle - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID **)&UnixIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure the UnixThunkProtocol is valid
+ //
+ Status = EFI_UNSUPPORTED;
+ if (UnixIo->UnixThunk->Signature == EFI_UNIX_THUNK_PROTOCOL_SIGNATURE) {
+
+ //
+ // Check the GUID to see if this is a handle type the driver supports
+ //
+ if (CompareGuid (UnixIo->TypeGuid, &gEfiUnixVirtualDisksGuid) ) {
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Handle - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ CHAR16 Buffer[FILENAME_BUFFER_SIZE];
+ CHAR16 *Str;
+ BOOLEAN RemovableMedia;
+ BOOLEAN WriteProtected;
+ UINTN NumberOfBlocks;
+ UINTN BlockSize;
+ INTN i;
+
+ //
+ // Grab the protocols we need
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (void *)&UnixIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Set DiskType
+ //
+ if (!CompareGuid (UnixIo->TypeGuid, &gEfiUnixVirtualDisksGuid)) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ Status = EFI_NOT_FOUND;
+ // Extract filename.
+ Str = UnixIo->EnvString;
+ i = 0;
+ while (*Str && *Str != ':')
+ Buffer[i++] = *Str++;
+ Buffer[i] = 0;
+ if (*Str != ':') {
+ goto Done;
+ }
+
+ Str++;
+
+ RemovableMedia = FALSE;
+ WriteProtected = TRUE;
+ NumberOfBlocks = 0;
+ BlockSize = 512;
+ do {
+ if (*Str == 'R' || *Str == 'F') {
+ RemovableMedia = (BOOLEAN) (*Str == 'R');
+ Str++;
+ }
+ if (*Str == 'O' || *Str == 'W') {
+ WriteProtected = (BOOLEAN) (*Str == 'O');
+ Str++;
+ }
+ if (*Str == 0)
+ break;
+ if (*Str != ';')
+ goto Done;
+ Str++;
+
+ NumberOfBlocks = Atoi (Str);
+ Str = GetNextElementPastTerminator (Str, ';');
+ if (NumberOfBlocks == 0)
+ break;
+
+ BlockSize = Atoi (Str);
+ if (BlockSize != 0)
+ Str = GetNextElementPastTerminator (Str, ';');
+ } while (0);
+
+ //
+ // If we get here the variable is valid so do the work.
+ //
+ Status = UnixBlockIoCreateMapping (
+ UnixIo,
+ Handle,
+ Buffer,
+ WriteProtected,
+ RemovableMedia,
+ NumberOfBlocks,
+ BlockSize
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ EFI_UNSUPPORTED - TODO: Add description for return value
+
+--*/
+{
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status;
+ UNIX_BLOCK_IO_PRIVATE *Private;
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiBlockIoProtocolGuid,
+ (void *)&BlockIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo);
+
+ //
+ // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.
+ // We could pass in our image handle or FLAG our open to be closed via
+ // Unistall (== to saying any CloseProtocol will close our open)
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Private->EfiHandle,
+ &gEfiBlockIoProtocolGuid,
+ &Private->BlockIo,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+
+ Status = gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ //
+ // Shut down our device
+ //
+ Private->UnixThunk->Close (Private->fd);
+
+ //
+ // Free our instance data
+ //
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+ gBS->FreePool (Private);
+ }
+
+ return Status;
+}
+
+STATIC
+CHAR16 *
+GetNextElementPastTerminator (
+ IN CHAR16 *EnvironmentVariable,
+ IN CHAR16 Terminator
+ )
+/*++
+
+Routine Description:
+
+ Worker function to parse environment variables.
+
+Arguments:
+ EnvironmentVariable - Envirnment variable to parse.
+
+ Terminator - Terminator to parse for.
+
+Returns:
+
+ Pointer to next eliment past the first occurence of Terminator or the '\0'
+ at the end of the string.
+
+--*/
+{
+ CHAR16 *Ptr;
+
+ for (Ptr = EnvironmentVariable; *Ptr != '\0'; Ptr++) {
+ if (*Ptr == Terminator) {
+ Ptr++;
+ break;
+ }
+ }
+
+ return Ptr;
+}
+
+STATIC
+EFI_STATUS
+UnixBlockIoCreateMapping (
+ IN EFI_UNIX_IO_PROTOCOL *UnixIo,
+ IN EFI_HANDLE EfiDeviceHandle,
+ IN CHAR16 *Filename,
+ IN BOOLEAN ReadOnly,
+ IN BOOLEAN RemovableMedia,
+ IN UINTN NumberOfBlocks,
+ IN UINTN BlockSize
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ UnixIo - TODO: add argument description
+ EfiDeviceHandle - TODO: add argument description
+ Filename - TODO: add argument description
+ ReadOnly - TODO: add argument description
+ RemovableMedia - TODO: add argument description
+ NumberOfBlocks - TODO: add argument description
+ BlockSize - TODO: add argument description
+ DeviceType - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ UNIX_BLOCK_IO_PRIVATE *Private;
+ UINTN Index;
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (UNIX_BLOCK_IO_PRIVATE),
+ (void *)&Private
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ EfiInitializeLock (&Private->Lock, EFI_TPL_NOTIFY);
+
+ Private->UnixThunk = UnixIo->UnixThunk;
+
+ Private->Signature = UNIX_BLOCK_IO_PRIVATE_SIGNATURE;
+ Private->LastBlock = NumberOfBlocks - 1;
+ Private->BlockSize = BlockSize;
+
+ for (Index = 0; Filename[Index] != 0; Index++) {
+ Private->Filename[Index] = Filename[Index];
+ }
+
+ Private->Filename[Index] = 0;
+
+ Private->Mode = (ReadOnly ? O_RDONLY : O_RDWR);
+
+ Private->NumberOfBlocks = NumberOfBlocks;
+ Private->fd = -1;
+
+ Private->ControllerNameTable = NULL;
+
+ AddUnicodeString (
+ "eng",
+ gUnixBlockIoComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ Filename
+ );
+
+ BlockIo = &Private->BlockIo;
+ BlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;
+ BlockIo->Media = &Private->Media;
+ BlockIo->Media->BlockSize = Private->BlockSize;
+ BlockIo->Media->LastBlock = Private->NumberOfBlocks - 1;
+ BlockIo->Media->MediaId = 0;;
+
+ BlockIo->Reset = UnixBlockIoResetBlock;
+ BlockIo->ReadBlocks = UnixBlockIoReadBlocks;
+ BlockIo->WriteBlocks = UnixBlockIoWriteBlocks;
+ BlockIo->FlushBlocks = UnixBlockIoFlushBlocks;
+
+ BlockIo->Media->ReadOnly = ReadOnly;
+ BlockIo->Media->RemovableMedia = RemovableMedia;
+ BlockIo->Media->LogicalPartition = FALSE;
+ BlockIo->Media->MediaPresent = TRUE;
+ BlockIo->Media->WriteCaching = FALSE;
+
+ BlockIo->Media->IoAlign = 1;
+
+ Private->EfiHandle = EfiDeviceHandle;
+ Status = UnixBlockIoOpenDevice (Private);
+ if (!EFI_ERROR (Status)) {
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->EfiHandle,
+ &gEfiBlockIoProtocolGuid,
+ &Private->BlockIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+ gBS->FreePool (Private);
+ }
+
+ DEBUG ((EFI_D_INIT, "BlockDevice added: %s\n", Filename));
+ }
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+UnixBlockIoOpenDevice (
+ UNIX_BLOCK_IO_PRIVATE *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT64 FileSize;
+ UINT64 EndOfFile;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ BlockIo = &Private->BlockIo;
+ EfiAcquireLock (&Private->Lock);
+
+ //
+ // If the device is already opened, close it
+ //
+ if (Private->fd >= 0) {
+ BlockIo->Reset (BlockIo, FALSE);
+ }
+
+ //
+ // Open the device
+ //
+ Private->fd = Private->UnixThunk->Open
+ (Private->Filename, Private->Mode, 0644);
+
+ if (Private->fd < 0) {
+ DEBUG ((EFI_D_INFO, "PlOpenBlock: Could not open %s\n",
+ Private->Filename));
+ BlockIo->Media->MediaPresent = FALSE;
+ Status = EFI_NO_MEDIA;
+ goto Done;
+ }
+
+ if (!BlockIo->Media->MediaPresent) {
+ //
+ // BugBug: try to emulate if a CD appears - notify drivers to check it out
+ //
+ BlockIo->Media->MediaPresent = TRUE;
+ EfiReleaseLock (&Private->Lock);
+ EfiAcquireLock (&Private->Lock);
+ }
+
+ //
+ // get the size of the file
+ //
+ Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END);
+
+ if (EFI_ERROR (Status)) {
+ FileSize = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize);
+ DEBUG ((EFI_D_ERROR, "PlOpenBlock: Could not get filesize of %s\n", Private->Filename));
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ if (Private->NumberOfBlocks == 0) {
+ Private->NumberOfBlocks = DivU64x32 (FileSize, Private->BlockSize);
+ }
+
+ EndOfFile = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize);
+
+ if (FileSize != EndOfFile) {
+ //
+ // file is not the proper size, change it
+ //
+ DEBUG ((EFI_D_INIT, "PlOpenBlock: Initializing block device: %a\n", Private->Filename));
+
+ //
+ // first set it to 0
+ //
+ Private->UnixThunk->FTruncate (Private->fd, 0);
+
+ //
+ // then set it to the needed file size (OS will zero fill it)
+ //
+ Private->UnixThunk->FTruncate (Private->fd, EndOfFile);
+ }
+
+ DEBUG ((EFI_D_INIT, "%HPlOpenBlock: opened %s%N\n", Private->Filename));
+ Status = EFI_SUCCESS;
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (Private->fd >= 0) {
+ BlockIo->Reset (BlockIo, FALSE);
+ }
+ }
+
+ EfiReleaseLock (&Private->Lock);
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+UnixBlockIoError (
+ IN UNIX_BLOCK_IO_PRIVATE *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ return EFI_DEVICE_ERROR;
+
+#if 0
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status;
+ BOOLEAN ReinstallBlockIoFlag;
+
+
+ BlockIo = &Private->BlockIo;
+
+ switch (Private->UnixThunk->GetLastError ()) {
+
+ case ERROR_NOT_READY:
+ Status = EFI_NO_MEDIA;
+ BlockIo->Media->ReadOnly = FALSE;
+ BlockIo->Media->MediaPresent = FALSE;
+ ReinstallBlockIoFlag = FALSE;
+ break;
+
+ case ERROR_WRONG_DISK:
+ BlockIo->Media->ReadOnly = FALSE;
+ BlockIo->Media->MediaPresent = TRUE;
+ BlockIo->Media->MediaId += 1;
+ ReinstallBlockIoFlag = TRUE;
+ Status = EFI_MEDIA_CHANGED;
+ break;
+
+ case ERROR_WRITE_PROTECT:
+ BlockIo->Media->ReadOnly = TRUE;
+ ReinstallBlockIoFlag = FALSE;
+ Status = EFI_WRITE_PROTECTED;
+ break;
+
+ default:
+ ReinstallBlockIoFlag = FALSE;
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ if (ReinstallBlockIoFlag) {
+ BlockIo->Reset (BlockIo, FALSE);
+
+ gBS->ReinstallProtocolInterface (
+ Private->EfiHandle,
+ &gEfiBlockIoProtocolGuid,
+ BlockIo,
+ BlockIo
+ );
+ }
+
+ return Status;
+#endif
+}
+
+STATIC
+EFI_STATUS
+UnixBlockIoReadWriteCommon (
+ IN UNIX_BLOCK_IO_PRIVATE *Private,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer,
+ IN CHAR8 *CallerName
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+ MediaId - TODO: add argument description
+ Lba - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+ CallerName - TODO: add argument description
+
+Returns:
+
+ EFI_NO_MEDIA - TODO: Add description for return value
+ EFI_MEDIA_CHANGED - TODO: Add description for return value
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN BlockSize;
+ UINT64 LastBlock;
+ INT64 DistanceToMove;
+ UINT64 DistanceMoved;
+
+ if (Private->fd < 0) {
+ Status = UnixBlockIoOpenDevice (Private);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ if (!Private->Media.MediaPresent) {
+ DEBUG ((EFI_D_INIT, "%s: No Media\n", CallerName));
+ return EFI_NO_MEDIA;
+ }
+
+ if (Private->Media.MediaId != MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if ((UINT32) Buffer % Private->Media.IoAlign != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Verify buffer size
+ //
+ BlockSize = Private->BlockSize;
+ if (BufferSize == 0) {
+ DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName));
+ return EFI_SUCCESS;
+ }
+
+ if ((BufferSize % BlockSize) != 0) {
+ DEBUG ((EFI_D_INIT, "%s: Invalid read size\n", CallerName));
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ LastBlock = Lba + (BufferSize / BlockSize) - 1;
+ if (LastBlock > Private->LastBlock) {
+ DEBUG ((EFI_D_INIT, "ReadBlocks: Attempted to read off end of device\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Seek to End of File
+ //
+ DistanceToMove = MultU64x32 (Lba, BlockSize);
+ Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, SEEK_SET);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n"));
+ return UnixBlockIoError (Private);
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixBlockIoReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+ Routine Description:
+ Read BufferSize bytes from Lba into Buffer.
+
+ Arguments:
+ This - Protocol instance pointer.
+ MediaId - Id of the media, changes every time the media is replaced.
+ Lba - The starting Logical Block Address to read from
+ BufferSize - Size of Buffer, must be a multiple of device block size.
+ Buffer - Buffer containing read data
+
+ Returns:
+ EFI_SUCCESS - The data was read correctly from the device.
+ EFI_DEVICE_ERROR - The device reported an error while performing the read.
+ EFI_NO_MEDIA - There is no media in the device.
+ EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
+ EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
+ device.
+ EFI_INVALID_PARAMETER - The read request contains device addresses that are not
+ valid for the device.
+
+--*/
+{
+ UNIX_BLOCK_IO_PRIVATE *Private;
+ ssize_t len;
+ EFI_STATUS Status;
+
+ Private = UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = UnixBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "UnixReadBlocks");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ len = Private->UnixThunk->Read (Private->fd, Buffer, BufferSize);
+ if (len != BufferSize) {
+ DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed.\n"));
+ return UnixBlockIoError (Private);
+ }
+
+ //
+ // If we wrote then media is present.
+ //
+ This->Media->MediaPresent = TRUE;
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixBlockIoWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+ Routine Description:
+ Write BufferSize bytes from Lba into Buffer.
+
+ Arguments:
+ This - Protocol instance pointer.
+ MediaId - Id of the media, changes every time the media is replaced.
+ Lba - The starting Logical Block Address to read from
+ BufferSize - Size of Buffer, must be a multiple of device block size.
+ Buffer - Buffer containing read data
+
+ Returns:
+ EFI_SUCCESS - The data was written correctly to the device.
+ EFI_WRITE_PROTECTED - The device can not be written to.
+ EFI_DEVICE_ERROR - The device reported an error while performing the write.
+ EFI_NO_MEDIA - There is no media in the device.
+ EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
+ EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
+ device.
+ EFI_INVALID_PARAMETER - The write request contains a LBA that is not
+ valid for the device.
+
+--*/
+{
+ UNIX_BLOCK_IO_PRIVATE *Private;
+ ssize_t len;
+ EFI_STATUS Status;
+
+ Private = UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = UnixBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "UnixWriteBlocks");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ len = Private->UnixThunk->Write (Private->fd, Buffer, BufferSize);
+ if (len != BufferSize) {
+ DEBUG ((EFI_D_INIT, "ReadBlocks: WriteFile failed.\n"));
+ return UnixBlockIoError (Private);
+ }
+
+ //
+ // If the write succeeded, we are not write protected and media is present.
+ //
+ This->Media->MediaPresent = TRUE;
+ This->Media->ReadOnly = FALSE;
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixBlockIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+/*++
+
+ Routine Description:
+ Flush the Block Device.
+
+ Arguments:
+ This - Protocol instance pointer.
+
+ Returns:
+ EFI_SUCCESS - All outstanding data was written to the device
+ EFI_DEVICE_ERROR - The device reported an error while writting back the data
+ EFI_NO_MEDIA - There is no media in the device.
+
+--*/
+{
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixBlockIoResetBlock (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+ Routine Description:
+ Reset the Block Device.
+
+ Arguments:
+ This - Protocol instance pointer.
+ ExtendedVerification - Driver may perform diagnostics on reset.
+
+ Returns:
+ EFI_SUCCESS - The device was reset.
+ EFI_DEVICE_ERROR - The device is not functioning properly and could
+ not be reset.
+
+--*/
+{
+ UNIX_BLOCK_IO_PRIVATE *Private;
+
+ Private = UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ if (Private->fd >= 0) {
+ Private->UnixThunk->Close (Private->fd);
+ Private->fd = -1;
+ }
+
+ return EFI_SUCCESS;
+}
+
+UINTN
+Atoi (
+ CHAR16 *String
+ )
+/*++
+
+Routine Description:
+
+ Convert a unicode string to a UINTN
+
+Arguments:
+
+ String - Unicode string.
+
+Returns:
+
+ UINTN of the number represented by String.
+
+--*/
+{
+ UINTN Number;
+ CHAR16 *Str;
+
+ //
+ // skip preceeding white space
+ //
+ Str = String;
+ while ((*Str) && (*Str == ' ')) {
+ Str++;
+ }
+ //
+ // Convert ot a Number
+ //
+ Number = 0;
+ while (*Str != '\0') {
+ if ((*Str >= '0') && (*Str <= '9')) {
+ Number = (Number * 10) +*Str - '0';
+ } else {
+ break;
+ }
+
+ Str++;
+ }
+
+ return Number;
+}
+
+EFI_STATUS
+SetFilePointer64 (
+ IN UNIX_BLOCK_IO_PRIVATE *Private,
+ IN INT64 DistanceToMove,
+ OUT UINT64 *NewFilePointer,
+ IN INTN MoveMethod
+ )
+/*++
+
+This function extends the capability of SetFilePointer to accept 64 bit parameters
+
+--*/
+// TODO: function comment is missing 'Routine Description:'
+// TODO: function comment is missing 'Arguments:'
+// TODO: function comment is missing 'Returns:'
+// TODO: Private - add argument and description to function comment
+// TODO: DistanceToMove - add argument and description to function comment
+// TODO: NewFilePointer - add argument and description to function comment
+// TODO: MoveMethod - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ off_t res;
+
+ res = Private->UnixThunk->Lseek(Private->fd, DistanceToMove, MoveMethod);
+ if (res == -1) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ if (NewFilePointer != NULL) {
+ *NewFilePointer = res;
+ }
+
+ return Status;
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.h b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.h
new file mode 100644
index 0000000000..70d8571c3c
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.h
@@ -0,0 +1,207 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+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.
+
+Module Name:
+
+ UnixBlockIo.h
+
+Abstract:
+
+ Produce block IO abstractions for real devices on your PC using Win32 APIs.
+ The configuration of what devices to mount or emulate comes from NT
+ environment variables. The variables must be visible to the Microsoft*
+ Developer Studio for them to work.
+
+ * Other names and brands may be claimed as the property of others.
+
+--*/
+
+#ifndef _UNIX_BLOCK_IO_H_
+#define _UNIX_BLOCK_IO_H_
+
+#define FILENAME_BUFFER_SIZE 80
+
+//
+// Language supported for driverconfiguration protocol
+//
+#define LANGUAGESUPPORTED "eng"
+
+#define UNIX_BLOCK_IO_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('L', 'X', 'b', 'k')
+typedef struct {
+ UINTN Signature;
+
+ EFI_LOCK Lock;
+
+ char Filename[FILENAME_BUFFER_SIZE];
+ UINTN ReadMode;
+ UINTN Mode;
+
+ int fd;
+
+ UINT64 LastBlock;
+ UINTN BlockSize;
+ UINT64 NumberOfBlocks;
+
+ EFI_HANDLE EfiHandle;
+ EFI_BLOCK_IO_PROTOCOL BlockIo;
+ EFI_BLOCK_IO_MEDIA Media;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+
+} UNIX_BLOCK_IO_PRIVATE;
+
+#define UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, UNIX_BLOCK_IO_PRIVATE, BlockIo, UNIX_BLOCK_IO_PRIVATE_SIGNATURE)
+
+#define LIST_BUFFER_SIZE 512
+
+//
+// Block I/O Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gUnixBlockIoDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUnixBlockIoComponentName;
+extern EFI_DRIVER_CONFIGURATION_PROTOCOL gUnixBlockIoDriverConfiguration;
+extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL gUnixBlockIoDriverDiagnostics;
+
+//
+// EFI Driver Binding Functions
+//
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixBlockIoDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+SetFilePointer64 (
+ IN UNIX_BLOCK_IO_PRIVATE *Private,
+ IN INT64 DistanceToMove,
+ OUT UINT64 *NewFilePointer,
+ IN INT32 MoveMethod
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+ DistanceToMove - TODO: add argument description
+ NewFilePointer - TODO: add argument description
+ MoveMethod - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+UINTN
+Atoi (
+ CHAR16 *String
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ String - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.msa b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.msa
new file mode 100644
index 0000000000..49334904b0
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.msa
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+ <MsaHeader>
+ <ModuleName>UnixBlockIo</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>f3085888-8985-11db-9c93-0040d02b1835</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Block Io driver</Abstract>
+ <Description>
+ Produce block IO abstractions for real devices on your PC using Unix APIs.
+ The configuration of what devices to mount or emulate comes from
+ environment variables.
+ </Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>UnixBlockIo</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>UnixBlockIo.h</Filename>
+ <Filename>UnixBlockIo.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ <Filename>DriverConfiguration.c</Filename>
+ <Filename>DriverDiagnostics.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ <Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiUnixIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixVirtualDisksGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiUnixPhysicalDisksGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gUnixBlockIoDriverBinding</DriverBinding>
+ <ComponentName>gUnixBlockIoComponentName</ComponentName>
+ <DriverDiag>gUnixBlockIoDriverDiagnostics</DriverDiag>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ComponentName.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ComponentName.c
new file mode 100644
index 0000000000..abfb328f60
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ComponentName.c
@@ -0,0 +1,187 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+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.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "Console.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+UnixConsoleComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+UnixConsoleComponentNameGetControllerName (
+ 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
+//
+EFI_COMPONENT_NAME_PROTOCOL gUnixConsoleComponentName = {
+ UnixConsoleComponentNameGetDriverName,
+ UnixConsoleComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mUnixConsoleDriverNameTable[] = {
+ { "eng", L"Unix Text Console Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+UnixConsoleComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that 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.
+ DriverName - 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.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gUnixConsoleComponentName.SupportedLanguages,
+ mUnixConsoleDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UnixConsoleComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - 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.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that 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.
+ ControllerName - 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.
+
+ Returns:
+ 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.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOut;
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get out context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ (void *)&SimpleTextOut,
+ gUnixConsoleDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (SimpleTextOut);
+
+ return LookupUnicodeString (
+ Language,
+ gUnixConsoleComponentName.SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName
+ );
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/Console.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/Console.c
new file mode 100644
index 0000000000..cd4870d502
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/Console.c
@@ -0,0 +1,310 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+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.
+
+Module Name:
+
+ Console.c
+
+Abstract:
+
+ Console based on Win32 APIs.
+
+--*/
+
+#include "Console.h"
+
+EFI_STATUS
+EFIAPI
+UnixConsoleDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+UnixConsoleDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+UnixConsoleDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+EFI_DRIVER_BINDING_PROTOCOL gUnixConsoleDriverBinding = {
+ UnixConsoleDriverBindingSupported,
+ UnixConsoleDriverBindingStart,
+ UnixConsoleDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+EFI_STATUS
+EFIAPI
+UnixConsoleDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Handle - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (void *)&UnixIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure that the Unix Thunk Protocol is valid
+ //
+ Status = EFI_UNSUPPORTED;
+ if (UnixIo->UnixThunk->Signature == EFI_UNIX_THUNK_PROTOCOL_SIGNATURE) {
+
+ //
+ // Check the GUID to see if this is a handle type the driver supports
+ //
+ if (CompareGuid (UnixIo->TypeGuid, &gEfiUnixConsoleGuid)) {
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixConsoleDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Handle - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ //
+ // Grab the IO abstraction we need to get any work done
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (void *)&UnixIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (UNIX_SIMPLE_TEXT_PRIVATE_DATA),
+ (void *)&Private
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ ZeroMem (Private, sizeof (UNIX_SIMPLE_TEXT_PRIVATE_DATA));
+
+ Private->Signature = UNIX_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE;
+ Private->Handle = Handle;
+ Private->UnixIo = UnixIo;
+ Private->UnixThunk = UnixIo->UnixThunk;
+
+ UnixSimpleTextOutOpenWindow (Private);
+ UnixSimpleTextInAttachToWindow (Private);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiSimpleTextOutProtocolGuid,
+ &Private->SimpleTextOut,
+ &gEfiSimpleTextInProtocolGuid,
+ &Private->SimpleTextIn,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+Done:
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+ if (Private != NULL) {
+
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+#if 0
+ if (Private->NtOutHandle != NULL) {
+ Private->UnixThunk->CloseHandle (Private->NtOutHandle);
+ }
+#endif
+
+ if (Private->SimpleTextIn.WaitForKey != NULL) {
+ gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
+ }
+
+ gBS->FreePool (Private);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixConsoleDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ EFI_UNSUPPORTED - TODO: Add description for return value
+
+--*/
+{
+ EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOut;
+ EFI_STATUS Status;
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ //
+ // Kick people off our interface???
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiSimpleTextOutProtocolGuid,
+ (void *)&SimpleTextOut,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (SimpleTextOut);
+
+ ASSERT (Private->Handle == Handle);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Handle,
+ &gEfiSimpleTextOutProtocolGuid,
+ &Private->SimpleTextOut,
+ &gEfiSimpleTextInProtocolGuid,
+ &Private->SimpleTextIn,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Shut down our device
+ //
+ Status = gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ Status = gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
+ ASSERT_EFI_ERROR (Status);
+
+#if 0
+ Private->UnixThunk->CloseHandle (Private->NtOutHandle);
+#endif
+ //
+ // DO NOT close Private->NtInHandle. It points to StdIn and not
+ // the Private->NtOutHandle is StdIn and should not be closed!
+ //
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+ gBS->FreePool (Private);
+ }
+
+ return Status;
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/Console.h b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/Console.h
new file mode 100644
index 0000000000..3f0b4eb6c8
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/Console.h
@@ -0,0 +1,513 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+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.
+
+Module Name:
+
+ Console.h
+
+Abstract:
+
+ Console based on Win32 APIs.
+
+ This file attaches a SimpleTextIn protocol to a previously open window.
+
+ The constructor for this protocol depends on an open window. Currently
+ the SimpleTextOut protocol creates a window when it's constructor is called.
+ Thus this code must run after the constructor for the SimpleTextOut
+ protocol
+
+--*/
+
+#ifndef _CONSOLE_H_
+#define _CONSOLE_H_
+
+#define UNIX_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE \
+ EFI_SIGNATURE_32('U','X','s','c')
+
+typedef struct {
+ UINT64 Signature;
+
+ EFI_HANDLE Handle;
+
+ EFI_SIMPLE_TEXT_OUT_PROTOCOL SimpleTextOut;
+ EFI_SIMPLE_TEXT_OUTPUT_MODE SimpleTextOutMode;
+
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+
+ //
+ // SimpleTextOut Private Data including Win32 types.
+ //
+ // HANDLE NtOutHandle;
+ // HANDLE NtInHandle;
+
+ //COORD MaxScreenSize;
+ //COORD Position;
+ //WORD Attribute;
+ BOOLEAN CursorEnable;
+
+ EFI_SIMPLE_TEXT_IN_PROTOCOL SimpleTextIn;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+} UNIX_SIMPLE_TEXT_PRIVATE_DATA;
+
+#define UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, UNIX_SIMPLE_TEXT_PRIVATE_DATA, SimpleTextOut, UNIX_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE)
+
+#define UNIX_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, UNIX_SIMPLE_TEXT_PRIVATE_DATA, SimpleTextIn, UNIX_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE)
+
+//
+// Console Globale Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gUnixConsoleDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUnixConsoleComponentName;
+
+typedef struct {
+ UINTN ColumnsX;
+ UINTN RowsY;
+} UNIX_SIMPLE_TEXT_OUT_MODE;
+
+#if 0
+//
+// Simple Text Out protocol member functions
+//
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutReset (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ExtendedVerification - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutOutputString (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN CHAR16 *String
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ String - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutTestString (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN CHAR16 *String
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ String - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutQueryMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber,
+ OUT UINTN *Columns,
+ OUT UINTN *Rows
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ModeNumber - TODO: add argument description
+ Columns - TODO: add argument description
+ Rows - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutSetMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ModeNumber - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutSetAttribute (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Attribute
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Attribute - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutClearScreen (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutSetCursorPosition (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Column - TODO: add argument description
+ Row - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutEnableCursor (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN BOOLEAN Enable
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Enable - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
+//
+// Simple Text Out constructor and destructor.
+//
+EFI_STATUS
+UnixSimpleTextOutOpenWindow (
+ IN OUT UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+UnixSimpleTextOutCloseWindow (
+ IN OUT UNIX_SIMPLE_TEXT_PRIVATE_DATA *Console
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Console - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#if 0
+//
+// Simple Text In protocol member functions.
+//
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextInReset (
+ IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ExtendedVerification - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextInReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Key - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+STATIC
+VOID
+EFIAPI
+UnixSimpleTextInWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Event - TODO: add argument description
+ Context - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
+//
+// Simple Text In constructor
+//
+EFI_STATUS
+UnixSimpleTextInAttachToWindow (
+ IN UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+//
+// Main Entry Point
+//
+EFI_STATUS
+EFIAPI
+InitializeUnixConsole (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ImageHandle - TODO: add argument description
+ SystemTable - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+AppendDevicePathInstanceToVar (
+ IN CHAR16 *VariableName,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ VariableName - TODO: add argument description
+ DevicePathInstance - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ConsoleIn.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ConsoleIn.c
new file mode 100644
index 0000000000..ff70a5fd8e
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ConsoleIn.c
@@ -0,0 +1,246 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+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.
+
+Module Name:
+
+ ConsoleIn.c
+
+Abstract:
+
+ Console based on Win32 APIs.
+
+ This file attaches a SimpleTextIn protocol to a previously open window.
+
+ The constructor for this protocol depends on an open window. Currently
+ the SimpleTextOut protocol creates a window when it's constructor is called.
+ Thus this code must run after the constructor for the SimpleTextOut
+ protocol
+
+--*/
+
+#include "Console.h"
+#include <sys/poll.h>
+
+//
+// Private worker functions
+//
+STATIC
+EFI_STATUS
+UnixSimpleTextInCheckKey (
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private
+ );
+
+EFI_STATUS
+EFIAPI
+UnixSimpleTextInReset (
+ IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ExtendedVerification - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ Private = UNIX_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS (This);
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+UnixConvertInputRecordToEfiKey (
+ IN char c,
+ OUT EFI_INPUT_KEY *Key
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ InputRecord - TODO: add argument description
+ Key - TODO: add argument description
+
+Returns:
+
+ EFI_NOT_READY - TODO: Add description for return value
+ EFI_NOT_READY - TODO: Add description for return value
+ EFI_NOT_READY - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ Key->ScanCode = 0;
+ if (c == '\n')
+ c = '\r';
+ Key->UnicodeChar = c;
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextInReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Key - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_NOT_READY - TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+ char c;
+
+ Private = UNIX_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = UnixSimpleTextInCheckKey (Private);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Private->UnixThunk->Read (0, &c, 1) != 1)
+ return EFI_NOT_READY;
+ Status = UnixConvertInputRecordToEfiKey (c, Key);
+
+ return Status;
+}
+
+STATIC
+VOID
+EFIAPI
+UnixSimpleTextInWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Event - TODO: add argument description
+ Context - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+
+ Private = (UNIX_SIMPLE_TEXT_PRIVATE_DATA *) Context;
+ Status = UnixSimpleTextInCheckKey (Private);
+ if (!EFI_ERROR (Status)) {
+ gBS->SignalEvent (Event);
+ }
+}
+
+STATIC
+EFI_STATUS
+UnixSimpleTextInCheckKey (
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ struct pollfd pfd;
+
+ pfd.fd = 0;
+ pfd.events = POLLIN;
+ if (Private->UnixThunk->Poll (&pfd, 1, 0) <= 0) {
+ return EFI_NOT_READY;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UnixSimpleTextInAttachToWindow (
+ IN UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Private->SimpleTextIn.Reset = UnixSimpleTextInReset;
+ Private->SimpleTextIn.ReadKeyStroke = UnixSimpleTextInReadKeyStroke;
+
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UnixSimpleTextInWaitForKey,
+ Private,
+ &Private->SimpleTextIn.WaitForKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ConsoleOut.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ConsoleOut.c
new file mode 100644
index 0000000000..bd9d4e29fe
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/ConsoleOut.c
@@ -0,0 +1,635 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+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.
+
+Module Name:
+
+ ConsoleOut.c
+
+Abstract:
+
+ Console based on Win32 APIs.
+
+ This file creates an Win32 window and attaches a SimpleTextOut protocol.
+
+--*/
+
+#include "Console.h"
+//
+// Private worker functions.
+//
+
+#if 0
+STATIC
+VOID
+UnixSimpleTextOutScrollScreen (
+ IN OUT UNIX_SIMPLE_TEXT_PRIVATE_DATA *Console
+ );
+
+#endif
+STATIC
+VOID
+UnixSimpleTextOutPutChar (
+ IN OUT UNIX_SIMPLE_TEXT_PRIVATE_DATA *Console,
+ IN CHAR16 Char
+ );
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutSetAttribute (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Attribute
+ );
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutSetMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ );
+
+//
+// Modeule Global for Simple Text Out Mode.
+//
+#define MAX_SIMPLE_TEXT_OUT_MODE \
+ (sizeof(mUnixSimpleTextOutSupportedModes)/sizeof(UNIX_SIMPLE_TEXT_OUT_MODE))
+
+STATIC UNIX_SIMPLE_TEXT_OUT_MODE mUnixSimpleTextOutSupportedModes[] = {
+ { 80, 25 },
+#if 0
+ { 80, 50 },
+ { 80, 43 },
+ { 100, 100 },
+ { 100, 999 }
+#endif
+};
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutReset (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ExtendedVerification - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+
+ UnixSimpleTextOutSetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
+
+ UnixSimpleTextOutSetMode (This, 0);
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutOutputString (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN CHAR16 *String
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ String - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+ CHAR16 *Str;
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+
+ for (Str = String; *Str != '\0'; Str++) {
+ switch (*Str) {
+#if 0
+ case '\n':
+ if (Private->Position.Y == (Private->MaxScreenSize.Y - 1)) {
+ UnixSimpleTextOutScrollScreen (Private);
+ }
+
+ if (Private->Position.Y < (Private->MaxScreenSize.Y - 1)) {
+ Private->Position.Y++;
+ This->Mode->CursorRow++;
+ }
+ break;
+
+ case '\r':
+ Private->Position.X = 0;
+ This->Mode->CursorColumn = 0;
+ break;
+
+ case '\b':
+ if (Private->Position.X > 0) {
+ Private->Position.X--;
+ This->Mode->CursorColumn--;
+ }
+ break;
+
+#endif
+ default:
+ UnixSimpleTextOutPutChar (Private, *Str);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+UnixSimpleTextOutPutChar (
+ IN OUT UNIX_SIMPLE_TEXT_PRIVATE_DATA *Console,
+ IN CHAR16 Char
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Console - TODO: add argument description
+ Char - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ char c = Char;
+ Console->UnixThunk->Write (1, &c, 1);
+}
+
+#if 0
+STATIC
+VOID
+UnixSimpleTextOutScrollScreen (
+ IN OUT UNIX_SIMPLE_TEXT_PRIVATE_DATA *Console
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Console - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+}
+#endif
+
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutTestString (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN CHAR16 *String
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ String - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+
+ //
+ // BugBug: The correct answer would be a function of what code pages
+ // are currently loaded? For now we will just return success.
+ //
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutQueryMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber,
+ OUT UINTN *Columns,
+ OUT UINTN *Rows
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ModeNumber - TODO: add argument description
+ Columns - TODO: add argument description
+ Rows - TODO: add argument description
+
+Returns:
+
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+
+ if (ModeNumber > MAX_SIMPLE_TEXT_OUT_MODE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Columns = mUnixSimpleTextOutSupportedModes[ModeNumber].ColumnsX;
+ *Rows = mUnixSimpleTextOutSupportedModes[ModeNumber].RowsY;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutSetMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ModeNumber - TODO: add argument description
+
+Returns:
+
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+
+ if (ModeNumber > MAX_SIMPLE_TEXT_OUT_MODE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ This->Mode->Mode = (INT32) ModeNumber;
+
+ This->EnableCursor (This, TRUE);
+ This->ClearScreen (This);
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutSetAttribute (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Attribute
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Attribute - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+
+#if 0
+ Private->Attribute = (WORD) Attribute;
+#endif
+ This->Mode->Attribute = (INT32) Attribute;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutClearScreen (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+ // DWORD ConsoleWindow;
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+
+ This->SetCursorPosition (This, 0, 0);
+ Private->UnixThunk->Write (1, "\e[2J", 4);
+
+
+#if 0
+ Private->UnixThunk->FillConsoleOutputCharacter (
+ Private->NtOutHandle,
+ ' ',
+ Private->MaxScreenSize.X * Private->MaxScreenSize.Y,
+ Private->Possition,
+ &ConsoleWindow
+ );
+ Private->UnixThunk->FillConsoleOutputAttribute (
+ Private->NtOutHandle,
+ Private->Attribute,
+ Private->MaxScreenSize.X * Private->MaxScreenSize.Y,
+ Private->Possition,
+ &ConsoleWindow
+ );
+#endif
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutSetCursorPosition (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Column - TODO: add argument description
+ Row - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ char buf[12];
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+
+#if 0
+ Private->Position.X = (WORD) Column;
+#endif
+ This->Mode->CursorColumn = (INT32) Column;
+
+#if 0
+ Private->Position.Y = (WORD) Row;
+#endif
+ This->Mode->CursorRow = (INT32) Row;
+#if 0
+ Private->UnixThunk->SetConsoleCursorPosition (Private->NtOutHandle, Private->Possition);
+#endif
+
+ buf[0] = '\e';
+ buf[1] = '[';
+ buf[2] = '0' + ((Row / 100) % 10);
+ buf[3] = '0' + ((Row / 10) % 10);
+ buf[4] = '0' + ((Row / 1) % 10);
+ buf[5] = ';';
+ buf[6] = '0' + ((Column / 100) % 10);
+ buf[7] = '0' + ((Column / 10) % 10);
+ buf[8] = '0' + ((Column / 1) % 10);
+ buf[9] = 'H';
+ Private->UnixThunk->Write (1, buf, 10);
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixSimpleTextOutEnableCursor (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN BOOLEAN Enable
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Enable - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private;
+#if 0
+ CONSOLE_CURSOR_INFO Info;
+#endif
+
+ Private = UNIX_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);
+ Private->CursorEnable = Enable;
+ This->Mode->CursorVisible = Enable;
+
+#if 0
+ Private->UnixThunk->GetConsoleCursorInfo (Private->NtOutHandle, &Info);
+ Info.bVisible = Enable;
+ Private->UnixThunk->SetConsoleCursorInfo (Private->NtOutHandle, &Info);
+#endif
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UnixSimpleTextOutOpenWindow (
+ IN OUT UNIX_SIMPLE_TEXT_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOut;
+ CHAR16 *WindowName;
+
+ //WindowName = Private->UnixIo->EnvString;
+#if 0
+ Private->Attribute = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+ if (*WindowName == '?') {
+ Private->Attribute = BACKGROUND_RED | FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
+ WindowName = L"EFI Emulator Error Console";
+ }
+#endif
+ WindowName = L"EFI Emulator Error Console";
+
+ AddUnicodeString (
+ "eng",
+ gUnixConsoleComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ WindowName
+ );
+
+ //
+ // Fill in protocol member functions
+ //
+ SimpleTextOut = &Private->SimpleTextOut;
+ SimpleTextOut->Reset = UnixSimpleTextOutReset;
+ SimpleTextOut->OutputString = UnixSimpleTextOutOutputString;
+ SimpleTextOut->TestString = UnixSimpleTextOutTestString;
+ SimpleTextOut->QueryMode = UnixSimpleTextOutQueryMode;
+ SimpleTextOut->SetMode = UnixSimpleTextOutSetMode;
+ SimpleTextOut->SetAttribute = UnixSimpleTextOutSetAttribute;
+ SimpleTextOut->ClearScreen = UnixSimpleTextOutClearScreen;
+ SimpleTextOut->SetCursorPosition = UnixSimpleTextOutSetCursorPosition;
+ SimpleTextOut->EnableCursor = UnixSimpleTextOutEnableCursor;
+
+ //
+ // Initialize SimpleTextOut protocol mode structure
+ //
+ SimpleTextOut->Mode = &Private->SimpleTextOutMode;
+ SimpleTextOut->Mode->MaxMode = MAX_SIMPLE_TEXT_OUT_MODE;
+ SimpleTextOut->Mode->Attribute = 0; //FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+
+#if 0
+ //
+ // Open the window an initialize it!
+ //
+ Private->NtOutHandle = Private->UnixThunk->CreateConsoleScreenBuffer (
+ GENERIC_WRITE | GENERIC_READ,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ NULL,
+ CONSOLE_TEXTMODE_BUFFER,
+ NULL
+ );
+ Private->UnixThunk->SetConsoleTitle (WindowName);
+#endif
+
+ return SimpleTextOut->SetMode (SimpleTextOut, 0);
+}
+
+EFI_STATUS
+UnixSimpleTextOutCloseWindow (
+ IN OUT UNIX_SIMPLE_TEXT_PRIVATE_DATA *Console
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Console - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+#if 0
+ Console->UnixThunk->CloseHandle (Console->NtOutHandle);
+#endif
+ return EFI_SUCCESS;
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/UnixConsole.msa b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/UnixConsole.msa
new file mode 100644
index 0000000000..839eed7d13
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Console/UnixConsole.msa
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+ <MsaHeader>
+ <ModuleName>UnixConsole</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>f314a8cc-8985-11db-9f69-0040d02b1835</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Console Dxe driver</Abstract>
+ <Description>Simulate console with Unix API</Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>UnixConsole</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>Console.h</Filename>
+ <Filename>Console.c</Filename>
+ <Filename>ConsoleIn.c</Filename>
+ <Filename>ConsoleOut.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ <Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiUnixIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiSimpleTextOutProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiSimpleTextInProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixConsoleGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gUnixConsoleDriverBinding</DriverBinding>
+ <ComponentName>gUnixConsoleComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/ComponentName.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/ComponentName.c
new file mode 100644
index 0000000000..0db3b1c358
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/ComponentName.c
@@ -0,0 +1,193 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "UnixSimpleFileSystem.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemComponentNameGetControllerName (
+ 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
+//
+EFI_COMPONENT_NAME_PROTOCOL gUnixSimpleFileSystemComponentName = {
+ UnixSimpleFileSystemComponentNameGetDriverName,
+ UnixSimpleFileSystemComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mUnixSimpleFileSystemDriverNameTable[] = {
+ {
+ "eng",
+ L"Unix Simple File System Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that 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.
+ DriverName - 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.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gUnixSimpleFileSystemComponentName.SupportedLanguages,
+ mUnixSimpleFileSystemDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - 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.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that 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.
+ ControllerName - 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.
+
+ Returns:
+ 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.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &SimpleFileSystem,
+ gUnixSimpleFileSystemDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);
+
+ return LookupUnicodeString (
+ Language,
+ gUnixSimpleFileSystemComponentName.SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName
+ );
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.c
new file mode 100644
index 0000000000..a1b5b32010
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.c
@@ -0,0 +1,2106 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ UnixSimpleFileSystem.c
+
+Abstract:
+
+ Produce Simple File System abstractions for directories on your PC using Win32 APIs.
+ The configuration of what devices to mount or emulate comes from NT
+ environment variables. The variables must be visible to the Microsoft*
+ Developer Studio for them to work.
+
+ * Other names and brands may be claimed as the property of others.
+
+--*/
+
+#include "UnixSimpleFileSystem.h"
+
+EFI_DRIVER_BINDING_PROTOCOL gUnixSimpleFileSystemDriverBinding = {
+ UnixSimpleFileSystemDriverBindingSupported,
+ UnixSimpleFileSystemDriverBindingStart,
+ UnixSimpleFileSystemDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+
+CHAR16 *
+EfiStrChr (
+ IN CHAR16 *Str,
+ IN CHAR16 Chr
+ )
+/*++
+
+Routine Description:
+
+ Locate the first occurance of a character in a string.
+
+Arguments:
+
+ Str - Pointer to NULL terminated unicode string.
+ Chr - Character to locate.
+
+Returns:
+
+ If Str is NULL, then NULL is returned.
+ If Chr is not contained in Str, then NULL is returned.
+ If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.
+
+--*/
+{
+ if (Str == NULL) {
+ return Str;
+ }
+
+ while (*Str != '\0' && *Str != Chr) {
+ ++Str;
+ }
+
+ return (*Str == Chr) ? Str : NULL;
+}
+
+BOOLEAN
+IsZero (
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Buffer - TODO: add argument description
+ Length - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ if (Buffer == NULL || Length == 0) {
+ return FALSE;
+ }
+
+ if (*(UINT8 *) Buffer != 0) {
+ return FALSE;
+ }
+
+ if (Length > 1) {
+ if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+VOID
+CutPrefix (
+ IN CHAR8 *Str,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Str - TODO: add argument description
+ Count - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ CHAR8 *Pointer;
+
+ if (AsciiStrLen (Str) < Count) {
+ ASSERT (0);
+ }
+
+ for (Pointer = Str; *(Pointer + Count); Pointer++) {
+ *Pointer = *(Pointer + Count);
+ }
+
+ *Pointer = *(Pointer + Count);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ Check to see if the driver supports a given controller.
+
+Arguments:
+
+ This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
+
+ ControllerHandle - EFI handle of the controller to test.
+
+ RemainingDevicePath - Pointer to remaining portion of a device path.
+
+Returns:
+
+ EFI_SUCCESS - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver
+ specified by This.
+
+ EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
+ the driver specified by This.
+
+ EFI_ACCESS_DENIED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
+ a different driver or an application that requires exclusive access.
+
+ EFI_UNSUPPORTED - The device specified by ControllerHandle and RemainingDevicePath is not supported by the
+ driver specified by This.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID **)&UnixIo,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure GUID is for a File System handle.
+ //
+ Status = EFI_UNSUPPORTED;
+ if (CompareGuid (UnixIo->TypeGuid, &gEfiUnixFileSystemGuid)) {
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ Starts a device controller or a bus controller.
+
+Arguments:
+
+ This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
+
+ ControllerHandle - EFI handle of the controller to start.
+
+ RemainingDevicePath - Pointer to remaining portion of a device path.
+
+Returns:
+
+ EFI_SUCCESS - The device or bus controller has been started.
+
+ EFI_DEVICE_ERROR - The device could not be started due to a device failure.
+
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
+ INTN i;
+
+ Private = NULL;
+
+ //
+ // Open the IO Abstraction(s) needed
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID **)&UnixIo,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Validate GUID
+ //
+ if (!CompareGuid (UnixIo->TypeGuid, &gEfiUnixFileSystemGuid)) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (UNIX_SIMPLE_FILE_SYSTEM_PRIVATE),
+ (VOID **)&Private
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Private->Signature = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
+ Private->UnixThunk = UnixIo->UnixThunk;
+ Private->FilePath = NULL;
+ Private->VolumeLabel = NULL;
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ StrLen (UnixIo->EnvString) + 1,
+ (VOID **)&Private->FilePath
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ for (i = 0; UnixIo->EnvString[i] != 0; i++)
+ Private->FilePath[i] = UnixIo->EnvString[i];
+ Private->FilePath[i] = 0;
+
+ Private->VolumeLabel = NULL;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ StrSize (L"EFI_EMULATED"),
+ (VOID **)&Private->VolumeLabel
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ StrCpy (Private->VolumeLabel, L"EFI_EMULATED");
+
+ Private->SimpleFileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
+ Private->SimpleFileSystem.OpenVolume = UnixSimpleFileSystemOpenVolume;
+
+ Private->ControllerNameTable = NULL;
+
+ AddUnicodeString (
+ "eng",
+ gUnixSimpleFileSystemComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ UnixIo->EnvString
+ );
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &Private->SimpleFileSystem,
+ NULL
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+
+ if (Private != NULL) {
+
+ if (Private->VolumeLabel != NULL)
+ gBS->FreePool (Private->VolumeLabel);
+ if (Private->FilePath != NULL)
+ gBS->FreePool (Private->FilePath);
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+ gBS->FreePool (Private);
+ }
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
+
+ ControllerHandle - A handle to the device to be stopped.
+
+ NumberOfChildren - The number of child device handles in ChildHandleBuffer.
+
+ ChildHandleBuffer - An array of child device handles to be freed.
+
+Returns:
+
+ EFI_SUCCESS - The device has been stopped.
+
+ EFI_DEVICE_ERROR - The device could not be stopped due to a device failure.
+
+--*/
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID **)&SimpleFileSystem,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);
+
+ //
+ // Uninstall the Simple File System Protocol from ControllerHandle
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &Private->SimpleFileSystem,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Free our instance data
+ //
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+ gBS->FreePool (Private);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemOpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE **Root
+ )
+/*++
+
+Routine Description:
+
+ Open the root directory on a volume.
+
+Arguments:
+
+ This - A pointer to the volume to open.
+
+ Root - A pointer to storage for the returned opened file handle of the root directory.
+
+Returns:
+
+ EFI_SUCCESS - The volume was opened.
+
+ EFI_UNSUPPORTED - The volume does not support the requested file system type.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
+
+ EFI_ACCESS_DENIED - The service denied access to the file.
+
+ EFI_OUT_OF_RESOURCES - The file volume could not be opened due to lack of resources.
+
+ EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ EFI_STATUS Status;
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+
+ if (This == NULL || Root == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);
+
+ PrivateFile = NULL;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (UNIX_EFI_FILE_PRIVATE),
+ (VOID **)&PrivateFile
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ PrivateFile->FileName = NULL;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ AsciiStrSize (Private->FilePath),
+ (VOID **)&PrivateFile->FileName
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ AsciiStrCpy (PrivateFile->FileName, Private->FilePath);
+ PrivateFile->Signature = UNIX_EFI_FILE_PRIVATE_SIGNATURE;
+ PrivateFile->UnixThunk = Private->UnixThunk;
+ PrivateFile->SimpleFileSystem = This;
+ PrivateFile->IsRootDirectory = TRUE;
+ PrivateFile->IsDirectoryPath = TRUE;
+ PrivateFile->IsOpenedByRead = TRUE;
+ PrivateFile->EfiFile.Revision = EFI_FILE_HANDLE_REVISION;
+ PrivateFile->EfiFile.Open = UnixSimpleFileSystemOpen;
+ PrivateFile->EfiFile.Close = UnixSimpleFileSystemClose;
+ PrivateFile->EfiFile.Delete = UnixSimpleFileSystemDelete;
+ PrivateFile->EfiFile.Read = UnixSimpleFileSystemRead;
+ PrivateFile->EfiFile.Write = UnixSimpleFileSystemWrite;
+ PrivateFile->EfiFile.GetPosition = UnixSimpleFileSystemGetPosition;
+ PrivateFile->EfiFile.SetPosition = UnixSimpleFileSystemSetPosition;
+ PrivateFile->EfiFile.GetInfo = UnixSimpleFileSystemGetInfo;
+ PrivateFile->EfiFile.SetInfo = UnixSimpleFileSystemSetInfo;
+ PrivateFile->EfiFile.Flush = UnixSimpleFileSystemFlush;
+ PrivateFile->fd = -1;
+ PrivateFile->Dir = NULL;
+ PrivateFile->Dirent = NULL;
+
+ *Root = &PrivateFile->EfiFile;
+
+ PrivateFile->Dir = PrivateFile->UnixThunk->OpenDir(PrivateFile->FileName);
+
+ if (PrivateFile->Dir == NULL) {
+ Status = EFI_ACCESS_DENIED;
+ }
+ else {
+ Status = EFI_SUCCESS;
+ }
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (PrivateFile) {
+ if (PrivateFile->FileName) {
+ gBS->FreePool (PrivateFile->FileName);
+ }
+
+ gBS->FreePool (PrivateFile);
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemOpen (
+ IN EFI_FILE *This,
+ OUT EFI_FILE **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Open a file relative to the source file location.
+
+Arguments:
+
+ This - A pointer to the source file location.
+
+ NewHandle - Pointer to storage for the new file handle.
+
+ FileName - Pointer to the file name to be opened.
+
+ OpenMode - File open mode information.
+
+ Attributes - File creation attributes.
+
+Returns:
+
+ EFI_SUCCESS - The file was opened.
+
+ EFI_NOT_FOUND - The file could not be found in the volume.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
+
+ EFI_WRITE_PROTECTED - The volume or file is write protected.
+
+ EFI_ACCESS_DENIED - The service denied access to the file.
+
+ EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
+
+ EFI_VOLUME_FULL - There is not enough space left to create the new file.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ EFI_FILE *Root;
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+ UNIX_EFI_FILE_PRIVATE *NewPrivateFile;
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;
+ EFI_STATUS Status;
+ CHAR16 *Src;
+ char *Dst;
+ CHAR8 *RealFileName;
+ CHAR16 *TempFileName;
+ char *ParseFileName;
+ char *GuardPointer;
+ CHAR8 TempChar;
+ UINTN Count;
+ BOOLEAN TrailingDash;
+ BOOLEAN LoopFinish;
+ UINTN InfoSize;
+ EFI_FILE_INFO *Info;
+
+ TrailingDash = FALSE;
+
+ //
+ // Check for obvious invalid parameters.
+ //
+ if (This == NULL || NewHandle == NULL || FileName == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (OpenMode) {
+ case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
+ if (Attributes &~EFI_FILE_VALID_ATTR) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Attributes & EFI_FILE_READ_ONLY) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // fall through
+ //
+ case EFI_FILE_MODE_READ:
+ case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //
+ //
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+ PrivateRoot = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
+ NewPrivateFile = NULL;
+
+ //
+ // BUGBUG: assume an open of root
+ // if current location, return current data
+ //
+ if (StrCmp (FileName, L"\\") == 0
+ || (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) {
+ //
+ // BUGBUG: assume an open root
+ //
+OpenRoot:
+ Status = UnixSimpleFileSystemOpenVolume (PrivateFile->SimpleFileSystem, &Root);
+ NewPrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root);
+ goto Done;
+ }
+
+ if (FileName[StrLen (FileName) - 1] == L'\\') {
+ TrailingDash = TRUE;
+ FileName[StrLen (FileName) - 1] = 0;
+ }
+
+ //
+ // Attempt to open the file
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (UNIX_EFI_FILE_PRIVATE),
+ (VOID **)&NewPrivateFile
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ CopyMem (NewPrivateFile, PrivateFile, sizeof (UNIX_EFI_FILE_PRIVATE));
+
+ NewPrivateFile->FileName = NULL;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ AsciiStrSize (PrivateFile->FileName) + 1 + StrLen (FileName) + 1,
+ (VOID **)&NewPrivateFile->FileName
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ if (*FileName == L'\\') {
+ AsciiStrCpy (NewPrivateFile->FileName, PrivateRoot->FilePath);
+ // Skip first '\'.
+ Src = FileName + 1;
+ } else {
+ AsciiStrCpy (NewPrivateFile->FileName, PrivateFile->FileName);
+ Src = FileName;
+ }
+ Dst = NewPrivateFile->FileName + AsciiStrLen(NewPrivateFile->FileName);
+ GuardPointer = NewPrivateFile->FileName + AsciiStrLen(PrivateRoot->FilePath);
+ *Dst++ = '/';
+ // Convert unicode to ascii and '\' to '/'
+ while (*Src) {
+ if (*Src == '\\')
+ *Dst++ = '/';
+ else
+ *Dst++ = *Src;
+ Src++;
+ }
+ *Dst = 0;
+
+
+ //
+ // Get rid of . and .., except leading . or ..
+ //
+
+ //
+ // GuardPointer protect simplefilesystem root path not be destroyed
+ //
+
+ LoopFinish = FALSE;
+
+ while (!LoopFinish) {
+
+ LoopFinish = TRUE;
+
+ for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {
+ if (*ParseFileName == '.' &&
+ (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == '/') &&
+ *(ParseFileName - 1) == '/'
+ ) {
+
+ //
+ // cut /.
+ //
+ CutPrefix (ParseFileName - 1, 2);
+ LoopFinish = FALSE;
+ break;
+ }
+
+ if (*ParseFileName == '.' &&
+ *(ParseFileName + 1) == '.' &&
+ (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == '/') &&
+ *(ParseFileName - 1) == '/'
+ ) {
+
+ ParseFileName--;
+ Count = 3;
+
+ while (ParseFileName != GuardPointer) {
+ ParseFileName--;
+ Count++;
+ if (*ParseFileName == '/') {
+ break;
+ }
+ }
+
+ //
+ // cut /.. and its left directory
+ //
+ CutPrefix (ParseFileName, Count);
+ LoopFinish = FALSE;
+ break;
+ }
+ }
+ }
+
+ if (AsciiStrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {
+ NewPrivateFile->IsRootDirectory = TRUE;
+ gBS->FreePool (NewPrivateFile->FileName);
+ gBS->FreePool (NewPrivateFile);
+ goto OpenRoot;
+ }
+
+ RealFileName = NewPrivateFile->FileName + AsciiStrLen(NewPrivateFile->FileName) - 1;
+ while (RealFileName > NewPrivateFile->FileName && *RealFileName != '/')
+ RealFileName--;
+
+ TempChar = *(RealFileName - 1);
+ *(RealFileName - 1) = 0;
+
+ *(RealFileName - 1) = TempChar;
+
+
+
+ //
+ // Test whether file or directory
+ //
+ NewPrivateFile->IsRootDirectory = FALSE;
+ NewPrivateFile->fd = -1;
+ NewPrivateFile->Dir = NULL;
+ if (OpenMode & EFI_FILE_MODE_CREATE) {
+ if (Attributes & EFI_FILE_DIRECTORY) {
+ NewPrivateFile->IsDirectoryPath = TRUE;
+ } else {
+ NewPrivateFile->IsDirectoryPath = FALSE;
+ }
+ } else {
+ struct stat finfo;
+ int res = NewPrivateFile->UnixThunk->Stat (NewPrivateFile->FileName, &finfo);
+ if (res == 0 && S_ISDIR(finfo.st_mode))
+ NewPrivateFile->IsDirectoryPath = TRUE;
+ else
+ NewPrivateFile->IsDirectoryPath = FALSE;
+ }
+
+ if (OpenMode & EFI_FILE_MODE_WRITE) {
+ NewPrivateFile->IsOpenedByRead = FALSE;
+ } else {
+ NewPrivateFile->IsOpenedByRead = TRUE;
+ }
+
+ Status = EFI_SUCCESS;
+
+ //
+ // deal with directory
+ //
+ if (NewPrivateFile->IsDirectoryPath) {
+
+ if ((OpenMode & EFI_FILE_MODE_CREATE)) {
+ //
+ // Create a directory
+ //
+ if (NewPrivateFile->UnixThunk->MkDir (NewPrivateFile->FileName, 0777) != 0) {
+ INTN LastError;
+
+ LastError = PrivateFile->UnixThunk->GetErrno ();
+ if (LastError != EEXIST) {
+ gBS->FreePool (TempFileName);
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ }
+ }
+
+ NewPrivateFile->Dir = NewPrivateFile->UnixThunk->OpenDir
+ (NewPrivateFile->FileName);
+
+ if (NewPrivateFile->Dir == NULL) {
+ if (PrivateFile->UnixThunk->GetErrno () == EACCES) {
+ Status = EFI_ACCESS_DENIED;
+ } else {
+ Status = EFI_NOT_FOUND;
+ }
+
+ goto Done;
+ }
+
+ } else {
+ //
+ // deal with file
+ //
+ NewPrivateFile->fd = NewPrivateFile->UnixThunk->Open
+ (NewPrivateFile->FileName,
+ ((OpenMode & EFI_FILE_MODE_CREATE) ? O_CREAT : 0)
+ | (NewPrivateFile->IsOpenedByRead ? O_RDONLY : O_RDWR),
+ 0666);
+ if (NewPrivateFile->fd < 0) {
+ if (PrivateFile->UnixThunk->GetErrno () == ENOENT) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ Status = EFI_ACCESS_DENIED;
+ }
+ }
+ }
+
+ if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) {
+ //
+ // Set the attribute
+ //
+ InfoSize = 0;
+ Info = NULL;
+
+ Status = UnixSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);
+
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ InfoSize,
+ (VOID **)&Info
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = UnixSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Info->Attribute = Attributes;
+
+ UnixSimpleFileSystemSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);
+ }
+
+Done: ;
+ if (TrailingDash) {
+ FileName[StrLen (FileName) + 1] = 0;
+ FileName[StrLen (FileName)] = L'\\';
+ }
+
+ if (EFI_ERROR (Status)) {
+ if (NewPrivateFile) {
+ if (NewPrivateFile->FileName) {
+ gBS->FreePool (NewPrivateFile->FileName);
+ }
+
+ gBS->FreePool (NewPrivateFile);
+ }
+ } else {
+ *NewHandle = &NewPrivateFile->EfiFile;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemClose (
+ IN EFI_FILE *This
+ )
+/*++
+
+Routine Description:
+
+ Close the specified file handle.
+
+Arguments:
+
+ This - Pointer to a returned opened file handle.
+
+Returns:
+
+ EFI_SUCCESS - The file handle has been closed.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ if (PrivateFile->fd >= 0) {
+ PrivateFile->UnixThunk->Close (PrivateFile->fd);
+ }
+ if (PrivateFile->Dir != NULL) {
+ PrivateFile->UnixThunk->CloseDir (PrivateFile->Dir);
+ }
+
+ PrivateFile->fd = -1;
+ PrivateFile->Dir = NULL;
+
+ if (PrivateFile->FileName) {
+ gBS->FreePool (PrivateFile->FileName);
+ }
+
+ gBS->FreePool (PrivateFile);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemDelete (
+ IN EFI_FILE *This
+ )
+/*++
+
+Routine Description:
+
+ Close and delete a file.
+
+Arguments:
+
+ This - Pointer to a returned opened file handle.
+
+Returns:
+
+ EFI_SUCCESS - The file handle was closed and deleted.
+
+ EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ EFI_STATUS Status;
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = EFI_WARN_DELETE_FAILURE;
+
+ if (PrivateFile->IsDirectoryPath) {
+ if (PrivateFile->Dir != NULL) {
+ PrivateFile->UnixThunk->CloseDir (PrivateFile->Dir);
+ PrivateFile->Dir = NULL;
+ }
+
+ if (PrivateFile->UnixThunk->RmDir (PrivateFile->FileName) == 0) {
+ Status = EFI_SUCCESS;
+ }
+ } else {
+ PrivateFile->UnixThunk->Close (PrivateFile->fd);
+ PrivateFile->fd = -1;
+
+ if (!PrivateFile->IsOpenedByRead) {
+ if (!PrivateFile->UnixThunk->UnLink (PrivateFile->FileName)) {
+ Status = EFI_SUCCESS;
+ }
+ }
+ }
+
+ gBS->FreePool (PrivateFile->FileName);
+ gBS->FreePool (PrivateFile);
+
+ return Status;
+}
+
+STATIC
+VOID
+UnixSystemTimeToEfiTime (
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk,
+ IN time_t SystemTime,
+ OUT EFI_TIME *Time
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SystemTime - TODO: add argument description
+ TimeZone - TODO: add argument description
+ Time - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ struct tm *tm;
+ tm = UnixThunk->GmTime (&SystemTime);
+ Time->Year = tm->tm_year;
+ Time->Month = tm->tm_mon;
+ Time->Day = tm->tm_mday;
+ Time->Hour = tm->tm_hour;
+ Time->Minute = tm->tm_min;
+ Time->Second = tm->tm_sec;
+ Time->Nanosecond = 0;
+
+ Time->TimeZone = UnixThunk->GetTimeZone ();
+
+ if (UnixThunk->GetDayLight ()) {
+ Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;
+ }
+}
+
+STATIC
+EFI_STATUS
+UnixSimpleFileSystemFileInfo (
+ UNIX_EFI_FILE_PRIVATE *PrivateFile,
+ IN CHAR8 *FileName,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PrivateFile - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN NameSize;
+ UINTN ResultSize;
+ EFI_FILE_INFO *Info;
+ CHAR8 *RealFileName;
+ CHAR8 *TempPointer;
+ CHAR16 *BufferFileName;
+ struct stat buf;
+
+ if (FileName != NULL) {
+ RealFileName = FileName;
+ }
+ else if (PrivateFile->IsRootDirectory) {
+ RealFileName = "";
+ } else {
+ RealFileName = PrivateFile->FileName;
+ }
+
+ TempPointer = RealFileName;
+ while (*TempPointer) {
+ if (*TempPointer == '/') {
+ RealFileName = TempPointer + 1;
+ }
+
+ TempPointer++;
+ }
+
+ Size = SIZE_OF_EFI_FILE_INFO;
+ NameSize = AsciiStrSize (RealFileName) * 2;
+ ResultSize = Size + NameSize;
+
+ if (*BufferSize < ResultSize) {
+ *BufferSize = ResultSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ if (PrivateFile->UnixThunk->Stat (
+ FileName == NULL ? PrivateFile->FileName : FileName,
+ &buf) < 0)
+ return EFI_DEVICE_ERROR;
+
+ Status = EFI_SUCCESS;
+
+ Info = Buffer;
+ ZeroMem (Info, ResultSize);
+
+ Info->Size = ResultSize;
+ Info->FileSize = buf.st_size;
+ Info->PhysicalSize = MultU64x32 (buf.st_blocks, buf.st_blksize);
+
+ UnixSystemTimeToEfiTime (PrivateFile->UnixThunk, buf.st_ctime, &Info->CreateTime);
+ UnixSystemTimeToEfiTime (PrivateFile->UnixThunk, buf.st_atime, &Info->LastAccessTime);
+ UnixSystemTimeToEfiTime (PrivateFile->UnixThunk, buf.st_mtime, &Info->ModificationTime);
+
+ if (!(buf.st_mode & S_IWUSR)) {
+ Info->Attribute |= EFI_FILE_READ_ONLY;
+ }
+
+ if (S_ISDIR(buf.st_mode)) {
+ Info->Attribute |= EFI_FILE_DIRECTORY;
+ }
+
+
+ BufferFileName = (CHAR16 *)((CHAR8 *) Buffer + Size);
+ while (*RealFileName)
+ *BufferFileName++ = *RealFileName++;
+ *BufferFileName = 0;
+
+ *BufferSize = ResultSize;
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemRead (
+ IN EFI_FILE *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Read data from a file.
+
+Arguments:
+
+ This - Pointer to a returned open file handle.
+
+ BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
+
+ Buffer - Pointer to the first byte of the read Buffer.
+
+Returns:
+
+ EFI_SUCCESS - The data was read.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
+
+ EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
+ *BufferSize has been updated with the size needed to complete the request.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_STATUS Status;
+ INTN Res;
+ UINTN Size;
+ UINTN NameSize;
+ UINTN ResultSize;
+ CHAR8 *FullFileName;
+
+ if (This == NULL || BufferSize == NULL || Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ if (!PrivateFile->IsDirectoryPath) {
+
+ if (PrivateFile->fd < 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Res = PrivateFile->UnixThunk->Read (
+ PrivateFile->fd,
+ Buffer,
+ *BufferSize);
+ if (Res < 0)
+ return EFI_DEVICE_ERROR;
+ *BufferSize = Res;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Read on a directory.
+ //
+ if (PrivateFile->Dir == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (PrivateFile->Dirent == NULL) {
+ PrivateFile->Dirent = PrivateFile->UnixThunk->ReadDir (PrivateFile->Dir);
+ if (PrivateFile->Dirent == NULL) {
+ *BufferSize = 0;
+ return EFI_SUCCESS;
+ }
+ }
+
+ Size = SIZE_OF_EFI_FILE_INFO;
+ NameSize = AsciiStrLen (PrivateFile->Dirent->d_name) + 1;
+ ResultSize = Size + 2 * NameSize;
+
+ if (*BufferSize < ResultSize) {
+ *BufferSize = ResultSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ Status = EFI_SUCCESS;
+
+ *BufferSize = ResultSize;
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ AsciiStrLen(PrivateFile->FileName) + 1 + NameSize,
+ (VOID **)&FullFileName
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ AsciiStrCpy(FullFileName, PrivateFile->FileName);
+ AsciiStrCat(FullFileName, "/");
+ AsciiStrCat(FullFileName, PrivateFile->Dirent->d_name);
+ Status = UnixSimpleFileSystemFileInfo (PrivateFile,
+ FullFileName,
+ BufferSize,
+ Buffer);
+ gBS->FreePool (FullFileName);
+
+ PrivateFile->Dirent = NULL;
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemWrite (
+ IN EFI_FILE *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Write data to a file.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
+ of data written to the file.
+
+ Buffer - Pointer to the first by of data in the buffer to write to the file.
+
+Returns:
+
+ EFI_SUCCESS - The data was written to the file.
+
+ EFI_UNSUPPORTED - Writes to an open directory are not supported.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
+
+ EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
+
+ EFI_ACCESS_DENIED - The file was opened read-only.
+
+ EFI_VOLUME_FULL - The volume is full.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+ UINTN Res;
+
+ if (This == NULL || BufferSize == NULL || Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ if (PrivateFile->fd < 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (PrivateFile->IsDirectoryPath) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (PrivateFile->IsOpenedByRead) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ Res = PrivateFile->UnixThunk->Write (
+ PrivateFile->fd,
+ Buffer,
+ *BufferSize);
+ if (Res == (UINTN)-1)
+ return EFI_DEVICE_ERROR;
+ *BufferSize = Res;
+ return EFI_SUCCESS;
+
+ //
+ // bugbug: need to access windows error reporting
+ //
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemSetPosition (
+ IN EFI_FILE *This,
+ IN UINT64 Position
+ )
+/*++
+
+Routine Description:
+
+ Set a file's current position.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ Position - The byte position from the start of the file to set.
+
+Returns:
+
+ EFI_SUCCESS - The file position has been changed.
+
+ EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ EFI_STATUS Status;
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+ UINT64 Pos;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ if (PrivateFile->IsDirectoryPath) {
+ if (Position != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (PrivateFile->Dir == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+ PrivateFile->UnixThunk->RewindDir (PrivateFile->Dir);
+ return EFI_SUCCESS;
+ } else {
+ if (Position == (UINT64) -1) {
+ Pos = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, 0, SEEK_END);
+ } else {
+ Pos = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, Position, SEEK_SET);
+ }
+ Status = (Pos == (UINT64) -1) ? EFI_DEVICE_ERROR : EFI_SUCCESS;
+
+ return Status;
+ }
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemGetPosition (
+ IN EFI_FILE *This,
+ OUT UINT64 *Position
+ )
+/*++
+
+Routine Description:
+
+ Get a file's current position.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ Position - Pointer to storage for the current position.
+
+Returns:
+
+ EFI_SUCCESS - The file position has been reported.
+
+ EFI_UNSUPPORTED - Not valid for directories.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+
+ if (This == NULL || Position == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ if (PrivateFile->IsDirectoryPath) {
+ return EFI_UNSUPPORTED;
+ } else {
+ *Position = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, 0, SEEK_CUR);
+ return (*Position == (UINT64) -1) ? EFI_DEVICE_ERROR : EFI_SUCCESS;
+ }
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemGetInfo (
+ IN EFI_FILE *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Return information about a file or volume.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ InformationType - GUID describing the type of information to be returned.
+
+ BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
+ information buffer.
+
+ Buffer - Pointer to the first byte of the information buffer.
+
+Returns:
+
+ EFI_SUCCESS - The requested information has been written into the buffer.
+
+ EFI_UNSUPPORTED - The InformationType is not known.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
+
+ EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
+ been updated with the size needed to complete the requested operation.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ EFI_STATUS Status;
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer;
+ INTN UnixStatus;
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;
+ struct statfs buf;
+
+ if (This == NULL || InformationType == NULL || BufferSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+ PrivateRoot = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
+
+ Status = EFI_UNSUPPORTED;
+
+ if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+ Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, BufferSize, Buffer);
+ }
+ else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+ if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {
+ *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ UnixStatus = PrivateFile->UnixThunk->StatFs (PrivateFile->FileName, &buf);
+ if (UnixStatus < 0)
+ return EFI_DEVICE_ERROR;
+
+ FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *) Buffer;
+ FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
+ FileSystemInfoBuffer->ReadOnly = FALSE;
+
+ //
+ // Succeeded
+ //
+ FileSystemInfoBuffer->VolumeSize = MultU64x32 (buf.f_blocks, buf.f_bsize);
+ FileSystemInfoBuffer->FreeSpace = MultU64x32 (buf.f_bavail, buf.f_bsize);
+ FileSystemInfoBuffer->BlockSize = buf.f_bsize;
+
+
+ StrCpy ((CHAR16 *) FileSystemInfoBuffer->VolumeLabel, PrivateRoot->VolumeLabel);
+ *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
+ Status = EFI_SUCCESS;
+ }
+
+ else if (CompareGuid (InformationType,
+ &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+ if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) {
+ *BufferSize = StrSize (PrivateRoot->VolumeLabel);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ StrCpy ((CHAR16 *) Buffer, PrivateRoot->VolumeLabel);
+ *BufferSize = StrSize (PrivateRoot->VolumeLabel);
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemSetInfo (
+ IN EFI_FILE *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Set information about a file or volume.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ InformationType - GUID identifying the type of information to set.
+
+ BufferSize - Number of bytes of data in the information buffer.
+
+ Buffer - Pointer to the first byte of data in the information buffer.
+
+Returns:
+
+ EFI_SUCCESS - The file or volume information has been updated.
+
+ EFI_UNSUPPORTED - The information identifier is not recognised.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
+
+ EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
+
+ EFI_ACCESS_DENIED - The file was opened read-only.
+
+ EFI_VOLUME_FULL - The volume is full.
+
+ EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_FILE_INFO *OldFileInfo;
+ EFI_FILE_INFO *NewFileInfo;
+ EFI_STATUS Status;
+ UINTN OldInfoSize;
+ mode_t NewAttr;
+ struct stat OldAttr;
+ CHAR8 *OldFileName;
+ CHAR8 *NewFileName;
+ CHAR8 *CharPointer;
+ BOOLEAN AttrChangeFlag;
+ BOOLEAN NameChangeFlag;
+ BOOLEAN SizeChangeFlag;
+ BOOLEAN TimeChangeFlag;
+ struct tm NewLastAccessSystemTime;
+ struct tm NewLastWriteSystemTime;
+ EFI_FILE_SYSTEM_INFO *NewFileSystemInfo;
+ CHAR8 *AsciiFilePtr;
+ CHAR16 *UnicodeFilePtr;
+ INTN UnixStatus;
+
+ //
+ // Check for invalid parameters.
+ //
+ if (This == NULL || InformationType == NULL || BufferSize == 0 || Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialise locals.
+ //
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+ PrivateRoot = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
+
+ Status = EFI_UNSUPPORTED;
+ OldFileInfo = NewFileInfo = NULL;
+ OldFileName = NewFileName = NULL;
+ AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE;
+
+ //
+ // Set file system information.
+ //
+ if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+ if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;
+
+ gBS->FreePool (PrivateRoot->VolumeLabel);
+
+ PrivateRoot->VolumeLabel = NULL;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ StrSize (NewFileSystemInfo->VolumeLabel),
+ (VOID **)&PrivateRoot->VolumeLabel
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ StrCpy (PrivateRoot->VolumeLabel, NewFileSystemInfo->VolumeLabel);
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Set volume label information.
+ //
+ if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+ if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ StrCpy (PrivateRoot->VolumeLabel, (CHAR16 *) Buffer);
+
+ return EFI_SUCCESS;
+ }
+
+ if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (BufferSize < SIZE_OF_EFI_FILE_INFO) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //
+ // Set file/directory information.
+ //
+
+ //
+ // Check for invalid set file information parameters.
+ //
+ NewFileInfo = (EFI_FILE_INFO *) Buffer;
+
+ if (NewFileInfo->Size <= sizeof (EFI_FILE_INFO) ||
+ (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||
+ (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF)
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // bugbug: - This is not safe. We need something like EfiStrMaxSize()
+ // that would have an additional parameter that would be the size
+ // of the string array just in case there are no NULL characters in
+ // the string array.
+ //
+ //
+ // Get current file information so we can determine what kind
+ // of change request this is.
+ //
+ OldInfoSize = 0;
+ Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, NULL);
+
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ Status = gBS->AllocatePool (EfiBootServicesData, OldInfoSize,
+ (VOID **)&OldFileInfo);
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, OldFileInfo);
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ AsciiStrSize (PrivateFile->FileName),
+ (VOID **)&OldFileName
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ AsciiStrCpy (OldFileName, PrivateFile->FileName);
+
+ //
+ // Make full pathname from new filename and rootpath.
+ //
+ if (NewFileInfo->FileName[0] == '\\') {
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ AsciiStrLen (PrivateRoot->FilePath) + 1 + StrLen (NewFileInfo->FileName) + 1,
+ (VOID **)&NewFileName
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ AsciiStrCpy (NewFileName, PrivateRoot->FilePath);
+ AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName);
+ UnicodeFilePtr = NewFileInfo->FileName + 1;
+ *AsciiFilePtr++ ='/';
+ } else {
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ AsciiStrLen (PrivateFile->FileName) + 1 + StrLen (NewFileInfo->FileName) + 1,
+ (VOID **)&NewFileName
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ AsciiStrCpy (NewFileName, PrivateRoot->FilePath);
+ AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName);
+ while (AsciiFilePtr > NewFileName && AsciiFilePtr[-1] != '/') {
+ AsciiFilePtr--;
+ }
+ UnicodeFilePtr = NewFileInfo->FileName;
+ }
+ // Convert to ascii.
+ while (*UnicodeFilePtr) {
+ *AsciiFilePtr++ = *UnicodeFilePtr++;
+ }
+ *AsciiFilePtr = 0;
+
+
+ //
+ // Is there an attribute change request?
+ //
+ if (NewFileInfo->Attribute != OldFileInfo->Attribute) {
+ if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ AttrChangeFlag = TRUE;
+ }
+
+ //
+ // Is there a name change request?
+ // bugbug: - Need EfiStrCaseCmp()
+ //
+ if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) {
+ NameChangeFlag = TRUE;
+ }
+
+ //
+ // Is there a size change request?
+ //
+ if (NewFileInfo->FileSize != OldFileInfo->FileSize) {
+ SizeChangeFlag = TRUE;
+ }
+
+ //
+ // Is there a time stamp change request?
+ //
+ if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) &&
+ CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME))
+ ) {
+ TimeChangeFlag = TRUE;
+ } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) &&
+ CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME))
+ ) {
+ TimeChangeFlag = TRUE;
+ } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) &&
+ CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME))
+ ) {
+ TimeChangeFlag = TRUE;
+ }
+
+ //
+ // All done if there are no change requests being made.
+ //
+ if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ //
+ // Set file or directory information.
+ //
+ if (PrivateFile->UnixThunk->Stat (OldFileName, &OldAttr) != 0) {
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ //
+ // Name change.
+ //
+ if (NameChangeFlag) {
+ //
+ // Close the handles first
+ //
+ if (PrivateFile->IsOpenedByRead) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+
+ for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) {
+ }
+
+ if (*CharPointer != 0) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+
+ UnixStatus = PrivateFile->UnixThunk->Rename (OldFileName, NewFileName);
+
+ if (UnixStatus == 0) {
+ //
+ // modify file name
+ //
+ gBS->FreePool (PrivateFile->FileName);
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ AsciiStrSize (NewFileName),
+ (VOID **)&PrivateFile->FileName
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ AsciiStrCpy (PrivateFile->FileName, NewFileName);
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+ }
+
+ //
+ // Size change
+ //
+ if (SizeChangeFlag) {
+ if (PrivateFile->IsDirectoryPath) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+
+ if (PrivateFile->UnixThunk->FTruncate (PrivateFile->fd, NewFileInfo->FileSize) != 0) {
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ }
+
+ //
+ // Time change
+ //
+ if (TimeChangeFlag) {
+ struct utimbuf utime;
+
+ NewLastAccessSystemTime.tm_year = NewFileInfo->LastAccessTime.Year;
+ NewLastAccessSystemTime.tm_mon = NewFileInfo->LastAccessTime.Month;
+ NewLastAccessSystemTime.tm_mday = NewFileInfo->LastAccessTime.Day;
+ NewLastAccessSystemTime.tm_hour = NewFileInfo->LastAccessTime.Hour;
+ NewLastAccessSystemTime.tm_min = NewFileInfo->LastAccessTime.Minute;
+ NewLastAccessSystemTime.tm_sec = NewFileInfo->LastAccessTime.Second;
+ NewLastAccessSystemTime.tm_isdst = 0;
+
+ utime.actime = PrivateFile->UnixThunk->MkTime (&NewLastAccessSystemTime);
+
+ NewLastWriteSystemTime.tm_year = NewFileInfo->ModificationTime.Year;
+ NewLastWriteSystemTime.tm_mon = NewFileInfo->ModificationTime.Month;
+ NewLastWriteSystemTime.tm_mday = NewFileInfo->ModificationTime.Day;
+ NewLastWriteSystemTime.tm_hour = NewFileInfo->ModificationTime.Hour;
+ NewLastWriteSystemTime.tm_min = NewFileInfo->ModificationTime.Minute;
+ NewLastWriteSystemTime.tm_sec = NewFileInfo->ModificationTime.Second;
+ NewLastWriteSystemTime.tm_isdst = 0;
+
+ utime.modtime = PrivateFile->UnixThunk->MkTime (&NewLastWriteSystemTime);
+
+ if (utime.actime == (time_t)-1 || utime.modtime == (time_t)-1) {
+ goto Done;
+ }
+
+ if (PrivateFile->UnixThunk->UTime (PrivateFile->FileName, &utime) == -1) {
+ goto Done;
+ }
+ }
+
+ //
+ // No matter about AttrChangeFlag, Attribute must be set.
+ // Because operation before may cause attribute change.
+ //
+ NewAttr = OldAttr.st_mode;
+
+ if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {
+ NewAttr &= ~(S_IRUSR | S_IRGRP | S_IROTH);
+ } else {
+ NewAttr |= S_IRUSR;
+ }
+
+ UnixStatus = PrivateFile->UnixThunk->Chmod (NewFileName, NewAttr);
+
+ if (UnixStatus != 0) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+Done:
+ if (OldFileInfo != NULL) {
+ gBS->FreePool (OldFileInfo);
+ }
+
+ if (OldFileName != NULL) {
+ gBS->FreePool (OldFileName);
+ }
+
+ if (NewFileName != NULL) {
+ gBS->FreePool (NewFileName);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemFlush (
+ IN EFI_FILE *This
+ )
+/*++
+
+Routine Description:
+
+ Flush all modified data to the media.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+Returns:
+
+ EFI_SUCCESS - The data has been flushed.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
+
+ EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
+
+ EFI_ACCESS_DENIED - The file was opened read-only.
+
+ EFI_VOLUME_FULL - The volume is full.
+
+--*/
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ UNIX_EFI_FILE_PRIVATE *PrivateFile;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+
+ if (PrivateFile->IsDirectoryPath) {
+ return EFI_SUCCESS;
+ }
+
+ if (PrivateFile->IsOpenedByRead) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ if (PrivateFile->fd < 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return PrivateFile->UnixThunk->FSync (PrivateFile->fd) == 0 ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+
+ //
+ // bugbug: - Use Windows error reporting.
+ //
+}
+
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.h b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.h
new file mode 100644
index 0000000000..aa1f135cb1
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.h
@@ -0,0 +1,582 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ UnixSimpleFileSystem.h
+
+Abstract:
+
+ Produce Simple File System abstractions for a directory on your PC using Unix APIs.
+ The configuration of what devices to mount or emulate comes from
+ environment variables.
+
+--*/
+
+#ifndef _UNIX_SIMPLE_FILE_SYSTEM_H_
+#define _UNIX_SIMPLE_FILE_SYSTEM_H_
+
+
+
+#define UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('L', 'X', 'f', 's')
+
+typedef struct {
+ UINTN Signature;
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem;
+ CHAR8 *FilePath;
+ CHAR16 *VolumeLabel;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+} UNIX_SIMPLE_FILE_SYSTEM_PRIVATE;
+
+#define UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \
+ CR (a, \
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE, \
+ SimpleFileSystem, \
+ UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \
+ )
+
+#define UNIX_EFI_FILE_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('l', 'o', 'f', 's')
+
+typedef struct {
+ UINTN Signature;
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
+ EFI_FILE EfiFile;
+ INTN fd;
+ DIR *Dir;
+ BOOLEAN IsRootDirectory;
+ BOOLEAN IsDirectoryPath;
+ BOOLEAN IsOpenedByRead;
+ char *FileName;
+ struct dirent *Dirent;
+} UNIX_EFI_FILE_PRIVATE;
+
+#define UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \
+ CR (a, \
+ UNIX_EFI_FILE_PRIVATE, \
+ EfiFile, \
+ UNIX_EFI_FILE_PRIVATE_SIGNATURE \
+ )
+
+//
+// Global Protocol Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gUnixSimpleFileSystemDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUnixSimpleFileSystemComponentName;
+
+//
+// Driver Binding protocol member functions
+//
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Check to see if the driver supports a given controller.
+
+Arguments:
+
+ This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
+
+ ControllerHandle - EFI handle of the controller to test.
+
+ RemainingDevicePath - Pointer to remaining portion of a device path.
+
+Returns:
+
+ EFI_SUCCESS - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver
+ specified by This.
+
+ EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
+ the driver specified by This.
+
+ EFI_ACCESS_DENIED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
+ a different driver or an application that requires exclusive access.
+
+ EFI_UNSUPPORTED - The device specified by ControllerHandle and RemainingDevicePath is not supported by the
+ driver specified by This.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Starts a device controller or a bus controller.
+
+Arguments:
+
+ This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
+
+ ControllerHandle - EFI handle of the controller to start.
+
+ RemainingDevicePath - Pointer to remaining portion of a device path.
+
+Returns:
+
+ EFI_SUCCESS - The device or bus controller has been started.
+
+ EFI_DEVICE_ERROR - The device could not be started due to a device failure.
+
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
+
+ ControllerHandle - A handle to the device to be stopped.
+
+ NumberOfChildren - The number of child device handles in ChildHandleBuffer.
+
+ ChildHandleBuffer - An array of child device handles to be freed.
+
+Returns:
+
+ EFI_SUCCESS - The device has been stopped.
+
+ EFI_DEVICE_ERROR - The device could not be stopped due to a device failure.
+
+--*/
+;
+
+//
+// Simple File System protocol member functions
+//
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemOpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE **Root
+ )
+/*++
+
+Routine Description:
+
+ Open the root directory on a volume.
+
+Arguments:
+
+ This - A pointer to the volume to open.
+
+ Root - A pointer to storage for the returned opened file handle of the root directory.
+
+Returns:
+
+ EFI_SUCCESS - The volume was opened.
+
+ EFI_UNSUPPORTED - The volume does not support the requested file system type.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
+
+ EFI_ACCESS_DENIED - The service denied access to the file.
+
+ EFI_OUT_OF_RESOURCES - The file volume could not be opened due to lack of resources.
+
+ EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemOpen (
+ IN EFI_FILE *This,
+ OUT EFI_FILE **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Open a file relative to the source file location.
+
+Arguments:
+
+ This - A pointer to the source file location.
+
+ NewHandle - Pointer to storage for the new file handle.
+
+ FileName - Pointer to the file name to be opened.
+
+ OpenMode - File open mode information.
+
+ Attributes - File creation attributes.
+
+Returns:
+
+ EFI_SUCCESS - The file was opened.
+
+ EFI_NOT_FOUND - The file could not be found in the volume.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
+
+ EFI_WRITE_PROTECTED - The volume or file is write protected.
+
+ EFI_ACCESS_DENIED - The service denied access to the file.
+
+ EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
+
+ EFI_VOLUME_FULL - There is not enough space left to create the new file.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemClose (
+ IN EFI_FILE *This
+ )
+/*++
+
+Routine Description:
+
+ Close the specified file handle.
+
+Arguments:
+
+ This - Pointer to a returned opened file handle.
+
+Returns:
+
+ EFI_SUCCESS - The file handle has been closed.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemDelete (
+ IN EFI_FILE *This
+ )
+/*++
+
+Routine Description:
+
+ Close and delete a file.
+
+Arguments:
+
+ This - Pointer to a returned opened file handle.
+
+Returns:
+
+ EFI_SUCCESS - The file handle was closed and deleted.
+
+ EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemRead (
+ IN EFI_FILE *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Read data from a file.
+
+Arguments:
+
+ This - Pointer to a returned open file handle.
+
+ BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
+
+ Buffer - Pointer to the first byte of the read Buffer.
+
+Returns:
+
+ EFI_SUCCESS - The data was read.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
+
+ EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
+ *BufferSize has been updated with the size needed to complete the request.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemWrite (
+ IN EFI_FILE *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Write data to a file.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
+ of data written to the file.
+
+ Buffer - Pointer to the first by of data in the buffer to write to the file.
+
+Returns:
+
+ EFI_SUCCESS - The data was written to the file.
+
+ EFI_UNSUPPORTED - Writes to an open directory are not supported.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
+
+ EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
+
+ EFI_ACCESS_DENIED - The file was opened read-only.
+
+ EFI_VOLUME_FULL - The volume is full.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemSetPosition (
+ IN EFI_FILE *This,
+ IN UINT64 Position
+ )
+/*++
+
+Routine Description:
+
+ Set a file's current position.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ Position - The byte position from the start of the file to set.
+
+Returns:
+
+ EFI_SUCCESS - The file position has been changed.
+
+ EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemGetPosition (
+ IN EFI_FILE *This,
+ OUT UINT64 *Position
+ )
+/*++
+
+Routine Description:
+
+ Get a file's current position.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ Position - Pointer to storage for the current position.
+
+Returns:
+
+ EFI_SUCCESS - The file position has been reported.
+
+ EFI_UNSUPPORTED - Not valid for directories.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemGetInfo (
+ IN EFI_FILE *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Return information about a file or volume.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ InformationType - GUID describing the type of information to be returned.
+
+ BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
+ information buffer.
+
+ Buffer - Pointer to the first byte of the information buffer.
+
+Returns:
+
+ EFI_SUCCESS - The requested information has been written into the buffer.
+
+ EFI_UNSUPPORTED - The InformationType is not known.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
+
+ EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
+ been updated with the size needed to complete the requested operation.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemSetInfo (
+ IN EFI_FILE *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Set information about a file or volume.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+ InformationType - GUID identifying the type of information to set.
+
+ BufferSize - Number of bytes of data in the information buffer.
+
+ Buffer - Pointer to the first byte of data in the information buffer.
+
+Returns:
+
+ EFI_SUCCESS - The file or volume information has been updated.
+
+ EFI_UNSUPPORTED - The information identifier is not recognised.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
+
+ EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
+
+ EFI_ACCESS_DENIED - The file was opened read-only.
+
+ EFI_VOLUME_FULL - The volume is full.
+
+ EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSimpleFileSystemFlush (
+ IN EFI_FILE *This
+ )
+/*++
+
+Routine Description:
+
+ Flush all modified data to the media.
+
+Arguments:
+
+ This - Pointer to an opened file handle.
+
+Returns:
+
+ EFI_SUCCESS - The data has been flushed.
+
+ EFI_NO_MEDIA - The device has no media.
+
+ EFI_DEVICE_ERROR - The device reported an error.
+
+ EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
+
+ EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
+
+ EFI_ACCESS_DENIED - The file was opened read-only.
+
+ EFI_VOLUME_FULL - The volume is full.
+
+--*/
+;
+
+#endif /* _UNIX_SIMPLE_FILE_SYSTEM_H_ */
+
+/* eof - UnixSimpleFileSystem.h */
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.msa b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.msa
new file mode 100644
index 0000000000..c57aa7165e
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.msa
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+ <MsaHeader>
+ <ModuleName>UnixSimpleFileSystem</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>f330834e-8985-11db-a295-0040d02b1835</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Simple filesystem driver</Abstract>
+ <Description>
+ Produce Simple File System abstractions for directories on your PC using Unix APIs.
+ The configuration of what devices to mount or emulate comes from
+ environment variables.
+ </Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>UnixSimpleFileSystem</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>UnixSimpleFileSystem.h</Filename>
+ <Filename>UnixSimpleFileSystem.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ <Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiUnixIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiSimpleFileSystemProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixFileSystemGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiFileSystemInfoGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiFileInfoGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiFileSystemVolumeLabelInfoIdGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gUnixSimpleFileSystemDriverBinding</DriverBinding>
+ <ComponentName>gUnixSimpleFileSystemComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/ComponentName.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/ComponentName.c
new file mode 100644
index 0000000000..e6e5ebe3a5
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/ComponentName.c
@@ -0,0 +1,187 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "UnixUga.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+UnixUgaComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+UnixUgaComponentNameGetControllerName (
+ 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
+//
+EFI_COMPONENT_NAME_PROTOCOL gUnixUgaComponentName = {
+ UnixUgaComponentNameGetDriverName,
+ UnixUgaComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mUnixUgaDriverNameTable[] = {
+ { "eng", L"Unix Universal Graphics Adapter Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+UnixUgaComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that 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.
+ DriverName - 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.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gUnixUgaComponentName.SupportedLanguages,
+ mUnixUgaDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UnixUgaComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - 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.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that 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.
+ ControllerName - 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.
+
+ Returns:
+ 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.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_UGA_DRAW_PROTOCOL *UgaDraw;
+ UGA_PRIVATE_DATA *Private;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUgaDrawProtocolGuid,
+ (VOID **)&UgaDraw,
+ gUnixUgaDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (UgaDraw);
+
+ return LookupUnicodeString (
+ Language,
+ gUnixUgaComponentName.SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName
+ );
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUga.h b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUga.h
new file mode 100644
index 0000000000..c34768d5c6
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUga.h
@@ -0,0 +1,289 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ UnixUga.h
+
+Abstract:
+
+ Private data for the Uga driver that is bound to the Unix Thunk protocol
+
+--*/
+
+#ifndef _UNIX_UGA_H_
+#define _UNIX_UGA_H_
+
+#include "Protocol/UnixUgaIo.h"
+
+#define UNIX_UGA_CLASS_NAME L"UnixUgaWindow"
+
+#define UGA_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('S', 'g', 'o', 'N')
+typedef struct {
+ UINT64 Signature;
+
+ EFI_HANDLE Handle;
+ EFI_UGA_DRAW_PROTOCOL UgaDraw;
+ EFI_SIMPLE_TEXT_IN_PROTOCOL SimpleTextIn;
+
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+ //
+ // UGA Private Data for GetMode ()
+ //
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ UINT32 ColorDepth;
+ UINT32 RefreshRate;
+
+ //
+ // UGA Private Data knowing when to start hardware
+ //
+ BOOLEAN HardwareNeedsStarting;
+
+ CHAR16 *WindowName;
+
+ EFI_UNIX_UGA_IO_PROTOCOL *UgaIo;
+
+} UGA_PRIVATE_DATA;
+
+#define UGA_DRAW_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, UGA_PRIVATE_DATA, UgaDraw, UGA_PRIVATE_DATA_SIGNATURE)
+
+#define UGA_PRIVATE_DATA_FROM_TEXT_IN_THIS(a) \
+ CR(a, UGA_PRIVATE_DATA, SimpleTextIn, UGA_PRIVATE_DATA_SIGNATURE)
+
+//
+// Global Protocol Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gUnixUgaDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUnixUgaComponentName;
+
+//
+// Uga Hardware abstraction internal worker functions
+//
+EFI_STATUS
+UnixUgaSupported (
+ IN EFI_UNIX_IO_PROTOCOL *UnixIo
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ UnixIo - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+UnixUgaConstructor (
+ IN UGA_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+UnixUgaDestructor (
+ IN UGA_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+//
+// EFI 1.1 driver model prototypes for Win NT UGA
+//
+
+EFI_STATUS
+EFIAPI
+UnixUgaInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ImageHandle - TODO: add argument description
+ SystemTable - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixUgaDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixUgaDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixUgaDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+UgaPrivateAddQ (
+ IN UGA_PRIVATE_DATA *Private,
+ IN EFI_INPUT_KEY Key
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+ Key - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+UnixUgaInitializeSimpleTextInForWindow (
+ IN UGA_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+#endif
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUga.msa b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUga.msa
new file mode 100644
index 0000000000..864576f6ac
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUga.msa
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+ <MsaHeader>
+ <ModuleName>UnixUga</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>f33cad86-8985-11db-8040-0040d02b1835</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Uga driver</Abstract>
+ <Description>
+ UGA is short hand for Universal Graphics Abstraction protocol.
+ This file is a verision of UgaIo the uses UnixThunk system calls as an IO
+ abstraction. For a PCI device UnixIo would be replaced with
+ a PCI IO abstraction that abstracted a specific PCI device.
+ </Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>UnixUga</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>UnixUga.h</Filename>
+ <Filename>UnixUgaInput.c</Filename>
+ <Filename>UnixUgaDriver.c</Filename>
+ <Filename>UnixUgaScreen.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ <Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiUnixIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiUgaDrawProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiUnixUgaIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiSimpleTextInProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Events>
+ <CreateEvents>
+ <EventTypes EventGuidCName="gEfiEventExitBootServicesGuid" Usage="SOMETIMES_CONSUMED">
+ <EventType>EVENT_GROUP_GUID</EventType>
+ </EventTypes>
+ </CreateEvents>
+ </Events>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixUgaGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gUnixUgaDriverBinding</DriverBinding>
+ <ComponentName>gUnixUgaComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaDriver.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaDriver.c
new file mode 100644
index 0000000000..5e08fe838b
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaDriver.c
@@ -0,0 +1,296 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ UnixUgaDriver.c
+
+Abstract:
+
+ This file implements the EFI 1.1 Device Driver model requirements for UGA
+
+ UGA is short hand for Universal Graphics Abstraction protocol.
+
+ This file is a verision of UgaIo the uses UnixThunk system calls as an IO
+ abstraction. For a PCI device UnixIo would be replaced with
+ a PCI IO abstraction that abstracted a specific PCI device.
+
+--*/
+
+#include "UnixUga.h"
+
+EFI_DRIVER_BINDING_PROTOCOL gUnixUgaDriverBinding = {
+ UnixUgaDriverBindingSupported,
+ UnixUgaDriverBindingStart,
+ UnixUgaDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+
+EFI_STATUS
+EFIAPI
+UnixUgaDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Handle - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID **)&UnixIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = UnixUgaSupported (UnixIo);
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixUgaDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Handle - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ EFI_STATUS Status;
+ UGA_PRIVATE_DATA *Private;
+
+ //
+ // Grab the protocols we need
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID **)&UnixIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Allocate Private context data for SGO inteface.
+ //
+ Private = NULL;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (UGA_PRIVATE_DATA),
+ (VOID **)&Private
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ //
+ // Set up context record
+ //
+ Private->Signature = UGA_PRIVATE_DATA_SIGNATURE;
+ Private->Handle = Handle;
+ Private->UnixThunk = UnixIo->UnixThunk;
+
+ Private->ControllerNameTable = NULL;
+
+ AddUnicodeString (
+ "eng",
+ gUnixUgaComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ UnixIo->EnvString
+ );
+
+ Private->WindowName = UnixIo->EnvString;
+
+ Status = UnixUgaConstructor (Private);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ //
+ // Publish the Uga interface to the world
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiUgaDrawProtocolGuid,
+ &Private->UgaDraw,
+ &gEfiSimpleTextInProtocolGuid,
+ &Private->SimpleTextIn,
+ NULL
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ if (Private != NULL) {
+ //
+ // On Error Free back private data
+ //
+ if (Private->ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+ }
+
+ gBS->FreePool (Private);
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixUgaDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Handle - add argument and description to function comment
+// TODO: NumberOfChildren - add argument and description to function comment
+// TODO: ChildHandleBuffer - add argument and description to function comment
+// TODO: EFI_NOT_STARTED - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+{
+ EFI_UGA_DRAW_PROTOCOL *UgaDraw;
+ EFI_STATUS Status;
+ UGA_PRIVATE_DATA *Private;
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUgaDrawProtocolGuid,
+ (VOID **)&UgaDraw,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // If the UGA interface does not exist the driver is not started
+ //
+ return EFI_NOT_STARTED;
+ }
+
+ //
+ // Get our private context information
+ //
+ Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (UgaDraw);
+
+ //
+ // Remove the SGO interface from the system
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Private->Handle,
+ &gEfiUgaDrawProtocolGuid,
+ &Private->UgaDraw,
+ &gEfiSimpleTextInProtocolGuid,
+ &Private->SimpleTextIn,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Shutdown the hardware
+ //
+ Status = UnixUgaDestructor (Private);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ //
+ // Free our instance data
+ //
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+ gBS->FreePool (Private);
+
+ }
+
+ return Status;
+}
+
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaInput.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaInput.c
new file mode 100644
index 0000000000..babfa4bdac
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaInput.c
@@ -0,0 +1,221 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ UnixUgaInput.c
+
+Abstract:
+
+ This file produces the Simple Text In for an Uga window.
+
+ This stuff is linked at the hip to the Window, since the window
+ processing is done in a thread kicked off in UnixUgaImplementation.c
+
+ Since the window information is processed in an other thread we need
+ a keyboard Queue to pass data about. The Simple Text In code just
+ takes data off the Queue. The WinProc message loop takes keyboard input
+ and places it in the Queue.
+
+--*/
+
+#include "UnixUga.h"
+
+//
+// Simple Text In implementation.
+//
+
+EFI_STATUS
+EFIAPI
+UnixUgaSimpleTextInReset (
+ IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ExtendedVerification - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UGA_PRIVATE_DATA *Private;
+ EFI_INPUT_KEY Key;
+ EFI_TPL OldTpl;
+
+ Private = UGA_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
+ if (Private->UgaIo == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ //
+ // A reset is draining the Queue
+ //
+ while (Private->UgaIo->UgaGetKey(Private->UgaIo, &Key) == EFI_SUCCESS)
+ ;
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+UnixUgaSimpleTextInReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Key - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ UGA_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ Private = UGA_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
+ if (Private->UgaIo == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Status = Private->UgaIo->UgaGetKey(Private->UgaIo, Key);
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+STATIC
+VOID
+EFIAPI
+UnixUgaSimpleTextInWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Event - TODO: add argument description
+ Context - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ UGA_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ Private = (UGA_PRIVATE_DATA *) Context;
+ if (Private->UgaIo == NULL) {
+ return;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Status = Private->UgaIo->UgaCheckKey(Private->UgaIo);
+ if (!EFI_ERROR (Status)) {
+ //
+ // If a there is a key in the queue signal our event.
+ //
+ gBS->SignalEvent (Event);
+ }
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+}
+
+EFI_STATUS
+UnixUgaInitializeSimpleTextInForWindow (
+ IN UGA_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Initialize Simple Text In protoocol
+ //
+ Private->SimpleTextIn.Reset = UnixUgaSimpleTextInReset;
+ Private->SimpleTextIn.ReadKeyStroke = UnixUgaSimpleTextInReadKeyStroke;
+
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UnixUgaSimpleTextInWaitForKey,
+ Private,
+ &Private->SimpleTextIn.WaitForKey
+ );
+
+ return Status;
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaScreen.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaScreen.c
new file mode 100644
index 0000000000..85c23f0d8f
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/Uga/UnixUgaScreen.c
@@ -0,0 +1,446 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ UnixUgaScreen.c
+
+Abstract:
+
+ This file produces the graphics abstration of UGA. It is called by
+ UnixUgaDriver.c file which deals with the EFI 1.1 driver model.
+ This file just does graphics.
+
+--*/
+
+#include "UnixUga.h"
+
+EFI_UNIX_THUNK_PROTOCOL *mUnix;
+static EFI_EVENT mUgaScreenExitBootServicesEvent;
+
+STATIC
+EFI_STATUS
+UnixUgaStartWindow (
+ IN UGA_PRIVATE_DATA *Private,
+ IN UINT32 HorizontalResolution,
+ IN UINT32 VerticalResolution,
+ IN UINT32 ColorDepth,
+ IN UINT32 RefreshRate
+ );
+
+STATIC
+VOID
+EFIAPI
+KillNtUgaThread (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+//
+// UGA Protocol Member Functions
+//
+
+EFI_STATUS
+EFIAPI
+UnixUgaGetMode (
+ EFI_UGA_DRAW_PROTOCOL *This,
+ UINT32 *HorizontalResolution,
+ UINT32 *VerticalResolution,
+ UINT32 *ColorDepth,
+ UINT32 *RefreshRate
+ )
+/*++
+
+ Routine Description:
+ Return the current video mode information.
+
+ Arguments:
+ This - Protocol instance pointer.
+ HorizontalResolution - Current video horizontal resolution in pixels
+ VerticalResolution - Current video Vertical resolution in pixels
+ ColorDepth - Current video color depth in bits per pixel
+ RefreshRate - Current video refresh rate in Hz.
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
+ EFI_INVALID_PARAMETER - One of the input args was NULL.
+
+--*/
+// TODO: ADD IN/OUT description here
+{
+ UGA_PRIVATE_DATA *Private;
+
+ Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);
+
+ if (Private->HardwareNeedsStarting) {
+ return EFI_NOT_STARTED;
+ }
+
+ if ((HorizontalResolution == NULL) ||
+ (VerticalResolution == NULL) ||
+ (ColorDepth == NULL) ||
+ (RefreshRate == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *HorizontalResolution = Private->HorizontalResolution;
+ *VerticalResolution = Private->VerticalResolution;
+ *ColorDepth = Private->ColorDepth;
+ *RefreshRate = Private->RefreshRate;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixUgaSetMode (
+ EFI_UGA_DRAW_PROTOCOL *This,
+ UINT32 HorizontalResolution,
+ UINT32 VerticalResolution,
+ UINT32 ColorDepth,
+ UINT32 RefreshRate
+ )
+/*++
+
+ Routine Description:
+ Return the current video mode information.
+
+ Arguments:
+ This - Protocol instance pointer.
+ HorizontalResolution - Current video horizontal resolution in pixels
+ VerticalResolution - Current video Vertical resolution in pixels
+ ColorDepth - Current video color depth in bits per pixel
+ RefreshRate - Current video refresh rate in Hz.
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
+ EFI_INVALID_PARAMETER - One of the input args was NULL.
+
+--*/
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: ADD IN/OUT description here
+{
+ EFI_STATUS Status;
+ UGA_PRIVATE_DATA *Private;
+ EFI_UGA_PIXEL Fill;
+
+ Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);
+
+ if (Private->HardwareNeedsStarting) {
+ Status = UnixUgaStartWindow (
+ Private,
+ HorizontalResolution,
+ VerticalResolution,
+ ColorDepth,
+ RefreshRate
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Private->HardwareNeedsStarting = FALSE;
+ }
+ Status = Private->UgaIo->UgaSize(Private->UgaIo,
+ HorizontalResolution,
+ VerticalResolution);
+
+ Private->HorizontalResolution = HorizontalResolution;
+ Private->VerticalResolution = VerticalResolution;
+ Private->ColorDepth = ColorDepth;
+ Private->RefreshRate = RefreshRate;
+
+ Fill.Red = 0x00;
+ Fill.Green = 0x00;
+ Fill.Blue = 0x00;
+ This->Blt (
+ This,
+ &Fill,
+ EfiUgaVideoFill,
+ 0,
+ 0,
+ 0,
+ 0,
+ HorizontalResolution,
+ VerticalResolution,
+ HorizontalResolution * sizeof (EFI_UGA_PIXEL)
+ );
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixUgaBlt (
+ IN EFI_UGA_DRAW_PROTOCOL *This,
+ IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_UGA_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Blt pixels from the rectangle (Width X Height) formed by the BltBuffer
+ onto the graphics screen starting a location (X, Y). (0, 0) is defined as
+ the upper left hand side of the screen. (X, Y) can be outside of the
+ current screen geometry and the BltBuffer will be cliped when it is
+ displayed. X and Y can be negative or positive. If Width or Height is
+ bigger than the current video screen the image will be clipped.
+
+ Arguments:
+ This - Protocol instance pointer.
+ X - X location on graphics screen.
+ Y - Y location on the graphics screen.
+ Width - Width of BltBuffer.
+ Height - Hight of BltBuffer
+ BltOperation - Operation to perform on BltBuffer and video memory
+ BltBuffer - Buffer containing data to blt into video buffer. This
+ buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
+ SourceX - If the BltOperation is a EfiCopyBlt this is the source
+ of the copy. For other BLT operations this argument is not
+ used.
+ SourceX - If the BltOperation is a EfiCopyBlt this is the source
+ of the copy. For other BLT operations this argument is not
+ used.
+
+ Returns:
+ EFI_SUCCESS - The palette is updated with PaletteArray.
+ EFI_INVALID_PARAMETER - BltOperation is not valid.
+ EFI_DEVICE_ERROR - A hardware error occured writting to the video
+ buffer.
+
+--*/
+// TODO: SourceY - add argument and description to function comment
+// TODO: DestinationX - add argument and description to function comment
+// TODO: DestinationY - add argument and description to function comment
+// TODO: Delta - add argument and description to function comment
+{
+ UGA_PRIVATE_DATA *Private;
+ EFI_TPL OriginalTPL;
+ EFI_STATUS Status;
+
+ Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);
+
+ if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width == 0 || Height == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
+ // the number of bytes in each row can be computed.
+ //
+ if (Delta == 0) {
+ Delta = Width * sizeof (EFI_UGA_PIXEL);
+ }
+
+ //
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
+ // We would not want a timer based event (Cursor, ...) to come in while we are
+ // doing this operation.
+ //
+ OriginalTPL = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Status = Private->UgaIo->UgaBlt (Private->UgaIo,
+ BltBuffer,
+ BltOperation,
+ SourceX, SourceY,
+ DestinationX, DestinationY,
+ Width, Height,
+ Delta);
+
+ gBS->RestoreTPL (OriginalTPL);
+
+ return Status;
+}
+
+
+//
+// Construction and Destruction functions
+//
+
+EFI_STATUS
+UnixUgaSupported (
+ IN EFI_UNIX_IO_PROTOCOL *UnixIo
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: UnixIo - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ //
+ // Check to see if the IO abstraction represents a device type we support.
+ //
+ // This would be replaced a check of PCI subsystem ID, etc.
+ //
+ if (!CompareGuid (UnixIo->TypeGuid, &gEfiUnixUgaGuid)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS
+UnixUgaStartWindow (
+ IN UGA_PRIVATE_DATA *Private,
+ IN UINT32 HorizontalResolution,
+ IN UINT32 VerticalResolution,
+ IN UINT32 ColorDepth,
+ IN UINT32 RefreshRate
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+ HorizontalResolution - TODO: add argument description
+ VerticalResolution - TODO: add argument description
+ ColorDepth - TODO: add argument description
+ RefreshRate - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+
+ mUnix = Private->UnixThunk;
+
+ Private->HorizontalResolution = HorizontalResolution;
+ Private->VerticalResolution = VerticalResolution;
+
+ //
+ // Register to be notified on exit boot services so we can destroy the window.
+ //
+ Status = gBS->CreateEvent (
+ EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+ EFI_TPL_CALLBACK,
+ KillNtUgaThread,
+ Private,
+ &mUgaScreenExitBootServicesEvent
+ );
+
+ Status = Private->UnixThunk->UgaCreate(&Private->UgaIo, Private->WindowName);
+ return Status;
+}
+
+EFI_STATUS
+UnixUgaConstructor (
+ UGA_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Private - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ Private->UgaDraw.GetMode = UnixUgaGetMode;
+ Private->UgaDraw.SetMode = UnixUgaSetMode;
+ Private->UgaDraw.Blt = UnixUgaBlt;
+
+ Private->HardwareNeedsStarting = TRUE;
+ Private->UgaIo = NULL;
+
+ UnixUgaInitializeSimpleTextInForWindow (Private);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UnixUgaDestructor (
+ UGA_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Private - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ if (!Private->HardwareNeedsStarting) {
+ Private->UgaIo->UgaClose(Private->UgaIo);
+ Private->UgaIo = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+EFIAPI
+KillNtUgaThread (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ This is the UGA screen's callback notification function for exit-boot-services.
+ All we do here is call UnixUgaDestructor().
+
+Arguments:
+
+ Event - not used
+ Context - pointer to the Private structure.
+
+Returns:
+
+ None.
+
+--*/
+{
+ EFI_STATUS Status;
+ Status = UnixUgaDestructor (Context);
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/ComponentName.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/ComponentName.c
new file mode 100644
index 0000000000..b52a471531
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/ComponentName.c
@@ -0,0 +1,187 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "UnixBusDriver.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+UnixBusDriverComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+UnixBusDriverComponentNameGetControllerName (
+ 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
+//
+EFI_COMPONENT_NAME_PROTOCOL gUnixBusDriverComponentName = {
+ UnixBusDriverComponentNameGetDriverName,
+ UnixBusDriverComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mUnixBusDriverNameTable[] = {
+ { "eng", L"Unix Bus Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+UnixBusDriverComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that 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.
+ DriverName - 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.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gUnixBusDriverComponentName.SupportedLanguages,
+ mUnixBusDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UnixBusDriverComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - 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.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that 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.
+ ControllerName - 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.
+
+ Returns:
+ 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.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ UNIX_IO_DEVICE *Private;
+
+ //
+ // This is a bus driver, so ChildHandle can not be NULL.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiUnixIoProtocolGuid,
+ &UnixIo,
+ gUnixBusDriverBinding.DriverBindingHandle,
+ ChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UNIX_IO_DEVICE_FROM_THIS (UnixIo);
+
+ return LookupUnicodeString (
+ Language,
+ gUnixBusDriverComponentName.SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName
+ );
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c
new file mode 100644
index 0000000000..038c71a074
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c
@@ -0,0 +1,717 @@
+/*+++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ UnixBusDriver.c
+
+Abstract:
+
+This following section documents the envirnoment variables for the Win NT
+build. These variables are used to define the (virtual) hardware
+configuration of the NT environment
+
+A ! can be used to seperate multiple instances in a variable. Each
+instance represents a seperate hardware device.
+
+EFI_UNIX_PHYSICAL_DISKS - maps to drives on your system
+EFI_UNIX_VIRTUAL_DISKS - maps to a device emulated by a file
+EFI_UNIX_FILE_SYSTEM - mouts a directory as a file system
+EFI_UNIX_CONSOLE - make a logical comand line window (only one!)
+EFI_UNIX_UGA - Builds UGA Windows of Width and Height
+
+ <F>ixed - Fixed disk like a hard drive.
+ <R>emovable - Removable media like a floppy or CD-ROM.
+ Read <O>nly - Write protected device.
+ Read <W>rite - Read write device.
+ <block count> - Decimal number of blocks a device supports.
+ <block size> - Decimal number of bytes per block.
+
+ NT envirnonment variable contents. '<' and '>' are not part of the variable,
+ they are just used to make this help more readable. There should be no
+ spaces between the ';'. Extra spaces will break the variable. A '!' is
+ used to seperate multiple devices in a variable.
+
+ EFI_UNIX_VIRTUAL_DISKS =
+ <F | R><O | W>;<block count>;<block size>[!...]
+
+ EFI_UNIX_PHYSICAL_DISKS =
+ <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
+
+ Virtual Disks: These devices use a file to emulate a hard disk or removable
+ media device.
+
+ Thus a 20 MB emulated hard drive would look like:
+ EFI_UNIX_VIRTUAL_DISKS=FW;40960;512
+
+ A 1.44MB emulated floppy with a block size of 1024 would look like:
+ EFI_UNIX_VIRTUAL_DISKS=RW;1440;1024
+
+ Physical Disks: These devices use NT to open a real device in your system
+
+ Thus a 120 MB floppy would look like:
+ EFI_UNIX_PHYSICAL_DISKS=B:RW;245760;512
+
+ Thus a standard CD-ROM floppy would look like:
+ EFI_UNIX_PHYSICAL_DISKS=Z:RO;307200;2048
+
+ EFI_UNIX_FILE_SYSTEM =
+ <directory path>[!...]
+
+ Mounting the two directories C:\FOO and C:\BAR would look like:
+ EFI_UNIX_FILE_SYSTEM=c:\foo!c:\bar
+
+ EFI_UNIX_CONSOLE =
+ <window title>
+
+ Declaring a text console window with the title "My EFI Console" woild look like:
+ EFI_UNIX_CONSOLE=My EFI Console
+
+ EFI_UNIX_UGA =
+ <width> <height>[!...]
+
+ Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:
+ Example : EFI_UNIX_UGA=800 600!1024 768
+
+ EFI_UNIX_PASS_THROUGH =
+ <BaseAddress>;<Bus#>;<Device#>;<Function#>
+
+ Declaring a base address of 0xE0000000 (used for PCI Express devices)
+ and having NT32 talk to a device located at bus 0, device 1, function 0:
+ Example : EFI_UNIX_PASS_THROUGH=E000000;0;1;0
+
+---*/
+
+#include "UnixBusDriver.h"
+//#include "PciHostBridge.h"
+
+//
+// Define GUID for the Unix Bus Driver
+//
+static EFI_GUID gUnixBusDriverGuid = {
+ 0x419f582, 0x625, 0x4531, 0x8a, 0x33, 0x85, 0xa9, 0x96, 0x5c, 0x95, 0xbc
+};
+
+//
+// DriverBinding protocol global
+//
+EFI_DRIVER_BINDING_PROTOCOL gUnixBusDriverBinding = {
+ UnixBusDriverBindingSupported,
+ UnixBusDriverBindingStart,
+ UnixBusDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+#define UNIX_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(UNIX_PCD_ENTRY))
+
+//
+// Table to map NT Environment variable to the GUID that should be in
+// device path.
+//
+static UNIX_PCD_ENTRY mPcdEnvironment[] = {
+ {PcdToken(PcdUnixConsole), &gEfiUnixConsoleGuid},
+ {PcdToken(PcdUnixUga), &gEfiUnixUgaGuid},
+ {PcdToken(PcdUnixFileSystem), &gEfiUnixFileSystemGuid},
+ {PcdToken(PcdUnixVirtualDisk), &gEfiUnixVirtualDisksGuid},
+ {PcdToken(PcdUnixPhysicalDisk), &gEfiUnixPhysicalDisksGuid},
+ {PcdToken(PcdUnixCpuModel), &gEfiUnixCPUModelGuid},
+ {PcdToken(PcdUnixCpuSpeed), &gEfiUnixCPUSpeedGuid},
+ {PcdToken(PcdUnixMemorySize), &gEfiUnixMemoryGuid}
+};
+
+VOID *
+AllocateMemory (
+ IN UINTN Size
+ )
+{
+ EFI_STATUS Status;
+ VOID *Buffer;
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ Size,
+ (VOID *)&Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ return NULL;
+ }
+ return Buffer;
+}
+
+
+EFI_STATUS
+EFIAPI
+UnixBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: ControllerHandle - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+ UINTN Index;
+
+ //
+ // 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) {
+ if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
+ RemainingDevicePath->SubType != HW_VENDOR_DP ||
+ DevicePathNodeLength(RemainingDevicePath) != sizeof(UNIX_VENDOR_DEVICE_PATH_NODE)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ for (Index = 0; Index < UNIX_PCD_ARRAY_SIZE; Index++) {
+ if (CompareGuid (&((VENDOR_DEVICE_PATH *) RemainingDevicePath)->Guid, mPcdEnvironment[Index].DevicePathGuid)) {
+ break;
+ }
+ }
+
+ if (Index >= UNIX_PCD_ARRAY_SIZE) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Open the IO Abstraction(s) 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;
+ }
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixThunkProtocolGuid,
+ (VOID **)&UnixThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Since we call through UnixThunk we need to make sure it's valid
+ //
+ Status = EFI_SUCCESS;
+ if (UnixThunk->Signature != EFI_UNIX_THUNK_PROTOCOL_SIGNATURE) {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: ControllerHandle - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_STATUS InstallStatus;
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ UNIX_BUS_DEVICE *UnixBusDevice;
+ UNIX_IO_DEVICE *UnixDevice;
+ UINTN Index;
+ CHAR16 *StartString;
+ CHAR16 *SubString;
+ UINT16 Count;
+ UINTN StringSize;
+ UINT16 ComponentName[MAX_UNIX_ENVIRNMENT_VARIABLE_LENGTH];
+ UNIX_VENDOR_DEVICE_PATH_NODE *Node;
+ BOOLEAN CreateDevice;
+ CHAR16 *TempStr;
+ CHAR16 *PcdTempStr;
+ UINTN TempStrSize;
+
+ 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,
+ &gEfiUnixThunkProtocolGuid,
+ (VOID **)&UnixThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ if (Status != EFI_ALREADY_STARTED) {
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (UNIX_BUS_DEVICE),
+ (VOID *) &UnixBusDevice
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ UnixBusDevice->Signature = UNIX_BUS_DEVICE_SIGNATURE;
+ UnixBusDevice->ControllerNameTable = NULL;
+
+ AddUnicodeString (
+ "eng",
+ gUnixBusDriverComponentName.SupportedLanguages,
+ &UnixBusDevice->ControllerNameTable,
+ L"Unix Bus Controller"
+ );
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gUnixBusDriverGuid,
+ UnixBusDevice,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ FreeUnicodeStringTable (UnixBusDevice->ControllerNameTable);
+ gBS->FreePool (UnixBusDevice);
+ return Status;
+ }
+ }
+
+ //
+ // Loop on the Variable list. Parse each variable to produce a set of handles that
+ // represent virtual hardware devices.
+ //
+ InstallStatus = EFI_NOT_FOUND;
+ for (Index = 0; Index < UNIX_PCD_ARRAY_SIZE; Index++) {
+ PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);
+ ASSERT (PcdTempStr != NULL);
+
+ TempStrSize = StrLen (PcdTempStr);
+ TempStr = AllocateMemory ((TempStrSize * sizeof (CHAR16)) + 1);
+ StrCpy (TempStr, PcdTempStr);
+
+ StartString = TempStr;
+
+ //
+ // Parse the envirnment variable into sub strings using '!' as a delimator.
+ // Each substring needs it's own handle to be added to the system. This code
+ // does not understand the sub string. Thats the device drivers job.
+ //
+ Count = 0;
+ while (*StartString != '\0') {
+
+ //
+ // Find the end of the sub string
+ //
+ SubString = StartString;
+ while (*SubString != '\0' && *SubString != '!') {
+ SubString++;
+ }
+
+ if (*SubString == '!') {
+ //
+ // Replace token with '\0' to make sub strings. If this is the end
+ // of the string SubString will already point to NULL.
+ //
+ *SubString = '\0';
+ SubString++;
+ }
+
+ CreateDevice = TRUE;
+ if (RemainingDevicePath != NULL) {
+ CreateDevice = FALSE;
+ Node = (UNIX_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 (UNIX_VENDOR_DEVICE_PATH_NODE)
+ ) {
+ if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&
+ Node->Instance == Count
+ ) {
+ CreateDevice = TRUE;
+ }
+ }
+ }
+
+ if (CreateDevice) {
+
+ //
+ // Allocate instance structure, and fill in parent information.
+ //
+ UnixDevice = AllocateMemory (sizeof (UNIX_IO_DEVICE));
+ if (UnixDevice == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UnixDevice->Handle = NULL;
+ UnixDevice->ControllerHandle = ControllerHandle;
+ UnixDevice->ParentDevicePath = ParentDevicePath;
+
+ UnixDevice->UnixIo.UnixThunk = UnixThunk;
+
+ //
+ // Plus 2 to account for the NULL at the end of the Unicode string
+ //
+ StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);
+ UnixDevice->UnixIo.EnvString = AllocateMemory (StringSize);
+ if (UnixDevice->UnixIo.EnvString != NULL) {
+ CopyMem (UnixDevice->UnixIo.EnvString, StartString, StringSize);
+ }
+
+ UnixDevice->ControllerNameTable = NULL;
+
+ // FIXME: check size
+ StrCpy(ComponentName, UnixDevice->UnixIo.EnvString);
+
+ UnixDevice->DevicePath = UnixBusCreateDevicePath (
+ ParentDevicePath,
+ mPcdEnvironment[Index].DevicePathGuid,
+ Count
+ );
+ if (UnixDevice->DevicePath == NULL) {
+ gBS->FreePool (UnixDevice);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AddUnicodeString (
+ "eng",
+ gUnixBusDriverComponentName.SupportedLanguages,
+ &UnixDevice->ControllerNameTable,
+ ComponentName
+ );
+
+ UnixDevice->UnixIo.TypeGuid = mPcdEnvironment[Index].DevicePathGuid;
+ UnixDevice->UnixIo.InstanceNumber = Count;
+
+ UnixDevice->Signature = UNIX_IO_DEVICE_SIGNATURE;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &UnixDevice->Handle,
+ &gEfiDevicePathProtocolGuid,
+ UnixDevice->DevicePath,
+ &gEfiUnixIoProtocolGuid,
+ &UnixDevice->UnixIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ FreeUnicodeStringTable (UnixDevice->ControllerNameTable);
+ gBS->FreePool (UnixDevice);
+ } else {
+ //
+ // Open For Child Device
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixThunkProtocolGuid,
+ (VOID **)&UnixThunk,
+ This->DriverBindingHandle,
+ UnixDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (!EFI_ERROR (Status)) {
+ InstallStatus = EFI_SUCCESS;
+ }
+ }
+ }
+
+ //
+ // Parse Next sub string. This will point to '\0' if we are at the end.
+ //
+ Count++;
+ StartString = SubString;
+ }
+
+ gBS->FreePool (TempStr);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+UnixBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: ControllerHandle - add argument and description to function comment
+// TODO: NumberOfChildren - add argument and description to function comment
+// TODO: ChildHandleBuffer - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ UNIX_BUS_DEVICE *UnixBusDevice;
+ UNIX_IO_DEVICE *UnixDevice;
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+
+ //
+ // 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,
+ &gUnixBusDriverGuid,
+ (VOID **)&UnixBusDevice,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ ControllerHandle,
+ &gUnixBusDriverGuid,
+ UnixBusDevice,
+ NULL
+ );
+
+ FreeUnicodeStringTable (UnixBusDevice->ControllerNameTable);
+
+ gBS->FreePool (UnixBusDevice);
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixThunkProtocolGuid,
+ 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],
+ &gEfiUnixIoProtocolGuid,
+ (VOID **)&UnixIo,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+
+ UnixDevice = UNIX_IO_DEVICE_FROM_THIS (UnixIo);
+
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUnixThunkProtocolGuid,
+ This->DriverBindingHandle,
+ UnixDevice->Handle
+ );
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ UnixDevice->Handle,
+ &gEfiDevicePathProtocolGuid,
+ UnixDevice->DevicePath,
+ &gEfiUnixIoProtocolGuid,
+ &UnixDevice->UnixIo,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUnixThunkProtocolGuid,
+ (VOID **) &UnixThunk,
+ This->DriverBindingHandle,
+ UnixDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ //
+ // Close the child handle
+ //
+ FreeUnicodeStringTable (UnixDevice->ControllerNameTable);
+ gBS->FreePool (UnixDevice);
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+UnixBusCreateDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,
+ IN EFI_GUID *Guid,
+ IN UINT16 InstanceNumber
+ )
+/*++
+
+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
+
+--*/
+{
+ UNIX_VENDOR_DEVICE_PATH_NODE DevicePath;
+
+ DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;
+ DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;
+ SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (UNIX_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
+ );
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.h b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.h
new file mode 100644
index 0000000000..4d8530bc8f
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.h
@@ -0,0 +1,297 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+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.
+
+Module Name:
+
+ UnixBusDriver.h
+
+Abstract:
+
+This following section documents the PCD for the Unix
+build. These variables are used to define the (virtual) hardware
+configuration of the Unix environment
+
+A ! can be used to seperate multiple instances in a variable. Each
+instance represents a seperate hardware device.
+
+EFI_UNIX_PHYSICAL_DISKS - maps to drives on your system
+EFI_UNIX_VIRTUAL_DISKS - maps to a device emulated by a file
+EFI_UNIX_FILE_SYSTEM - mouts a directory as a file system
+EFI_UNIX_CONSOLE - make a logical comand line window (only one!)
+EFI_UNIX_UGA - Builds UGA Windows of Width and Height
+EFI_UNIX_SERIAL_PORT - maps physical serial ports
+EFI_UNIX_PASS_THRU - associates a device with our PCI support
+
+ <F>ixed - Fixed disk like a hard drive.
+ <R>emovable - Removable media like a floppy or CD-ROM.
+ Read <O>nly - Write protected device.
+ Read <W>rite - Read write device.
+ <block count> - Decimal number of blocks a device supports.
+ <block size> - Decimal number of bytes per block.
+
+ NT envirnonment variable contents. '<' and '>' are not part of the variable,
+ they are just used to make this help more readable. There should be no
+ spaces between the ';'. Extra spaces will break the variable. A '!' is
+ used to seperate multiple devices in a variable.
+
+ EFI_UNIX_VIRTUAL_DISKS =
+ <F | R><O | W>;<block count>;<block size>[!...]
+
+ EFI_UNIX_PHYSICAL_DISKS =
+ <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
+
+ Virtual Disks: These devices use a file to emulate a hard disk or removable
+ media device.
+
+ Thus a 20 MB emulated hard drive would look like:
+ EFI_UNIX_VIRTUAL_DISKS=FW;40960;512
+
+ A 1.44MB emulated floppy with a block size of 1024 would look like:
+ EFI_UNIX_VIRTUAL_DISKS=RW;1440;1024
+
+ Physical Disks: These devices use NT to open a real device in your system
+
+ Thus a 120 MB floppy would look like:
+ EFI_UNIX_PHYSICAL_DISKS=B:RW;245760;512
+
+ Thus a standard CD-ROM floppy would look like:
+ EFI_UNIX_PHYSICAL_DISKS=Z:RO;307200;2048
+
+ EFI_UNIX_FILE_SYSTEM =
+ <directory path>[!...]
+
+ Mounting the two directories C:\FOO and C:\BAR would look like:
+ EFI_UNIX_FILE_SYSTEM=c:\foo!c:\bar
+
+ EFI_UNIX_CONSOLE =
+ <window title>
+
+ Declaring a text console window with the title "My EFI Console" woild look like:
+ EFI_UNIX_CONSOLE=My EFI Console
+
+ EFI_UNIX_UGA =
+ <width> <height>[!...]
+
+ Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:
+ Example : EFI_UNIX_UGA=800 600!1024 768
+
+ EFI_UNIX_SERIAL_PORT =
+ <port name>[!...]
+
+ Declaring two serial ports on COM1 and COM2 would look like:
+ Example : EFI_UNIX_SERIAL_PORT=COM1!COM2
+
+ EFI_UNIX_PASS_THROUGH =
+ <BaseAddress>;<Bus#>;<Device#>;<Function#>
+
+ Declaring a base address of 0xE0000000 (used for PCI Express devices)
+ and having NT32 talk to a device located at bus 0, device 1, function 0:
+ Example : EFI_UNIX_PASS_THROUGH=E000000;0;1;0
+
+---*/
+
+#ifndef __UNIX_BUS_DRIVER_H__
+#define __UNIX_BUS_DRIVER_H__
+
+
+
+//
+// Unix Bus Driver Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gUnixBusDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUnixBusDriverComponentName;
+
+//
+// Unix Bus Controller Structure
+//
+#define UNIX_BUS_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('L', 'X', 'B', 'D')
+
+typedef struct {
+ UINT64 Signature;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+} UNIX_BUS_DEVICE;
+
+//
+// Unix Child Device Controller Structure
+//
+#define UNIX_IO_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('L', 'X', 'V', 'D')
+
+typedef struct {
+ UINT64 Signature;
+ EFI_HANDLE Handle;
+ EFI_UNIX_IO_PROTOCOL UnixIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // Private data about the parent
+ //
+ EFI_HANDLE ControllerHandle;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+} UNIX_IO_DEVICE;
+
+#define UNIX_IO_DEVICE_FROM_THIS(a) \
+ CR(a, UNIX_IO_DEVICE, UnixIo, UNIX_IO_DEVICE_SIGNATURE)
+
+//
+// This is the largest env variable we can parse
+//
+#define MAX_UNIX_ENVIRNMENT_VARIABLE_LENGTH 512
+
+typedef struct {
+ UINTN Token;
+ EFI_GUID *DevicePathGuid;
+} UNIX_PCD_ENTRY;
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ UINT32 Instance;
+} UNIX_VENDOR_DEVICE_PATH_NODE;
+
+EFI_STATUS
+EFIAPI
+CpuIoInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ImageHandle - TODO: add argument description
+ SystemTable - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+//
+// Driver Binding Protocol function prototypes
+//
+EFI_STATUS
+EFIAPI
+UnixBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ParentHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ParentHandle - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+//
+// Unix Bus Driver private worker functions
+//
+EFI_DEVICE_PATH_PROTOCOL *
+UnixBusCreateDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,
+ IN EFI_GUID *Guid,
+ IN UINT16 InstanceNumber
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootDevicePath - TODO: add argument description
+ Guid - TODO: add argument description
+ InstanceNumber - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+
+#endif
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa
new file mode 100644
index 0000000000..2ca466c2c5
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+ <MsaHeader>
+ <ModuleName>UnixBusDriver</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>f320d656-8985-11db-90e0-0040d02b1835</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Unix Bus driver</Abstract>
+ <Description>
+ This following section documents the envirnoment variables for the Win NT
+ build. These variables are used to define the (virtual) hardware
+ configuration of the NT environment
+ </Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>UnixBusDriver</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PcdLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DevicePathLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>UnixBusDriver.h</Filename>
+ <Filename>UnixBusDriver.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ <Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiUnixIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiUnixThunkProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gPcdProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixVirtualDisksGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixPhysicalDisksGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixFileSystemGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixUgaGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixConsoleGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixMemoryGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixCPUModelGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixCPUSpeedGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gUnixBusDriverBinding</DriverBinding>
+ <ComponentName>gUnixBusDriverComponentName</ComponentName>
+ </Extern>
+ </Externs>
+ <PcdCoded>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdUnixConsole</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>This PCD declares the title string of the text console window.
+ such as "My EFI Console".
+ The item type of this PCD can only be "DYNAMIC".</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdUnixUga</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>This PCD declares the resolutions for the UGA windows.
+ The item type of this PCD can only be "DYNAMIC".</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdUnixFileSystem</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>This PCD defines the windows directory who will be mounted as
+ harddisk in simulator.
+ The item type of this PCD can only be "DYNAMIC".</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdUnixVirtualDisk</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>This PCD defines the devices which use a file to emulate a hard disk or
+ removable media device
+ The item type if this PCD can only be "DYNAMIC".</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdUnixPhysicalDisk</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>This PCD defines physical disk which will be simualted as a
+ harddisk in simulator.
+ The item type of this PCD can only be "DYNAMIC".</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdUnixCpuModel</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>This PCD defines simulated CPU model string.
+ The item type of this PCD can only be "DYNAMIC".</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdUnixCpuSpeed</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>This PCD defines simulated CPU speed string.</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdUnixMemorySize</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>This PCD defines the size of simulated memory size.
+ The item type of this PCD can only be "DYNAMIC".</HelpText>
+ </PcdEntry>
+ </PcdCoded>
+</ModuleSurfaceArea>