diff --git a/EdkModulePkg/Core/DxeIplX64Peim/DxeIpl.h b/EdkModulePkg/Core/DxeIplX64Peim/DxeIpl.h
index 5e35042861..13b1a69bae 100644
--- a/EdkModulePkg/Core/DxeIplX64Peim/DxeIpl.h
+++ b/EdkModulePkg/Core/DxeIplX64Peim/DxeIpl.h
@@ -115,7 +115,7 @@ PeimInitializeDxeIpl (
);
EFI_STATUS
-PeiLoadx64File (
+PeiLoadPeImage (
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader,
IN VOID *Pe32Data,
IN EFI_MEMORY_TYPE MemoryType,
diff --git a/EdkModulePkg/Core/DxeIplX64Peim/DxeIplX64.msa b/EdkModulePkg/Core/DxeIplX64Peim/DxeIplX64.msa
index 929a62719f..849842d20d 100644
--- a/EdkModulePkg/Core/DxeIplX64Peim/DxeIplX64.msa
+++ b/EdkModulePkg/Core/DxeIplX64Peim/DxeIplX64.msa
@@ -42,9 +42,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
HobLib
-
- PerformanceLib
-
PeiServicesLib
@@ -75,9 +72,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
MemoryAllocationLib
-
- EdkPeCoffLoaderX64Lib
-
DxeIpl.dxs
diff --git a/EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c b/EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c
index 9a036e6246..4015222036 100644
--- a/EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c
+++ b/EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c
@@ -247,7 +247,7 @@ Returns:
//
// Install the PEI Protocols that are shared between PEI and DXE
//
- PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderX64Protocol ();
+ PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
ASSERT (PeiEfiPeiPeCoffLoader != NULL);
//
@@ -313,7 +313,7 @@ Returns:
//
// Load the DXE Core from a Firmware Volume
//
- Status = PeiLoadx64File (
+ Status = PeiLoadPeImage (
PeiEfiPeiPeCoffLoader,
DxeCorePe32Data,
EfiBootServicesData,
@@ -446,7 +446,7 @@ Returns:
}
EFI_STATUS
-PeiLoadx64File (
+PeiLoadPeImage (
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader,
IN VOID *Pe32Data,
IN EFI_MEMORY_TYPE MemoryType,
@@ -578,7 +578,7 @@ Returns:
//
// Relocate DxeIpl into memory by using loadfile service
//
- Status = PeiLoadx64File (
+ Status = PeiLoadPeImage (
PeiEfiPeiPeCoffLoader,
(VOID *) (Section + 1),
EfiBootServicesData,
@@ -659,7 +659,7 @@ Returns:
//
// Load the PE image from the FFS file
//
- Status = PeiLoadx64File (
+ Status = PeiLoadPeImage (
PeiEfiPeiPeCoffLoader,
Pe32Data,
EfiBootServicesData,
diff --git a/EdkModulePkg/EdkModulePkg.fpd b/EdkModulePkg/EdkModulePkg.fpd
index 5a71aa6926..77f402c51b 100644
--- a/EdkModulePkg/EdkModulePkg.fpd
+++ b/EdkModulePkg/EdkModulePkg.fpd
@@ -17294,6 +17294,350 @@
PE32_PEIM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PcdReportStatusCodePropertyMask
+ 0x00000007
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0x06
+
+
+ PcdDebugPropertyMask
+ 0x00000005
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0x0f
+
+
+ PcdDebugClearMemoryValue
+ 0x00000008
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0xAF
+
+
+ PcdDebugPrintErrorLevel
+ 0x00000006
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 0x80000000
+
+
+ PcdMaximumUnicodeStringLength
+ 0x00000001
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdMaximumAsciiStringLength
+ 0x00000002
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdMaximumLinkedListLength
+ 0x00000003
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdSpinLockTimeout
+ 0x00000004
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 10000000
+
+
+
+ NULL
+ BS_DRIVER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PcdReportStatusCodePropertyMask
+ 0x00000007
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0x06
+
+
+ PcdDebugPropertyMask
+ 0x00000005
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0x0f
+
+
+ PcdDebugClearMemoryValue
+ 0x00000008
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0xAF
+
+
+ PcdDebugPrintErrorLevel
+ 0x00000006
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 0x80000000
+
+
+ PcdMaximumUnicodeStringLength
+ 0x00000001
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdMaximumAsciiStringLength
+ 0x00000002
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdMaximumLinkedListLength
+ 0x00000003
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdSpinLockTimeout
+ 0x00000004
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 10000000
+
+
+
+ NULL
+ BS_DRIVER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PcdReportStatusCodePropertyMask
+ 0x00000007
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0x06
+
+
+ PcdDebugPropertyMask
+ 0x00000005
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0x0f
+
+
+ PcdDebugClearMemoryValue
+ 0x00000008
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0xAF
+
+
+ PcdDebugPrintErrorLevel
+ 0x00000006
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 0x80000000
+
+
+ PcdMaximumUnicodeStringLength
+ 0x00000001
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdMaximumAsciiStringLength
+ 0x00000002
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdMaximumLinkedListLength
+ 0x00000003
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdSpinLockTimeout
+ 0x00000004
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 10000000
+
+
+
+ NULL
+ BS_DRIVER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PcdReportStatusCodePropertyMask
+ 0x00000007
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0x06
+
+
+ PcdDebugPropertyMask
+ 0x00000005
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0x0f
+
+
+ PcdDebugClearMemoryValue
+ 0x00000008
+ gEfiMdePkgTokenSpaceGuid
+ UINT8
+ 1
+ 0xAF
+
+
+ PcdDebugPrintErrorLevel
+ 0x00000006
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 0x80000000
+
+
+ PcdMaximumUnicodeStringLength
+ 0x00000001
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdMaximumAsciiStringLength
+ 0x00000002
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdMaximumLinkedListLength
+ 0x00000003
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 1000000
+
+
+ PcdSpinLockTimeout
+ 0x00000004
+ gEfiMdePkgTokenSpaceGuid
+ UINT32
+ 4
+ 10000000
+
+
+
+ NULL
+ BS_DRIVER
+
+
diff --git a/EdkModulePkg/EdkModulePkg.spd b/EdkModulePkg/EdkModulePkg.spd
index c449fd4574..02d2867c60 100644
--- a/EdkModulePkg/EdkModulePkg.spd
+++ b/EdkModulePkg/EdkModulePkg.spd
@@ -440,6 +440,7 @@
Universal/WatchdogTimer/Dxe/WatchDogTimer.msa
Universal/StatusCode/Pei/PeiStatusCode.msa
Universal/StatusCode/Dxe/DxeStatusCode.msa
+ Universal/ConPlatform/Dxe/ConPlatform.msa
Include/EdkPeim.h
diff --git a/EdkModulePkg/Universal/ConPlatform/Dxe/ComponentName.c b/EdkModulePkg/Universal/ConPlatform/Dxe/ComponentName.c
new file mode 100644
index 0000000000..f854499937
--- /dev/null
+++ b/EdkModulePkg/Universal/ConPlatform/Dxe/ComponentName.c
@@ -0,0 +1,141 @@
+/*++
+
+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 "ConPlatform.h"
+#include "ComponentName.h"
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME_PROTOCOL gConPlatformComponentName = {
+ ConPlatformComponentNameGetDriverName,
+ ConPlatformComponentNameGetControllerName,
+ "eng"
+};
+
+STATIC EFI_UNICODE_STRING_TABLE mConPlatformDriverNameTable[] = {
+ {
+ "eng",
+ L"Platform Console Management Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+EFI_STATUS
+EFIAPI
+ConPlatformComponentNameGetDriverName (
+ 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,
+ gConPlatformComponentName.SupportedLanguages,
+ mConPlatformDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+ConPlatformComponentNameGetControllerName (
+ 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.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/EdkModulePkg/Universal/ConPlatform/Dxe/ComponentName.h b/EdkModulePkg/Universal/ConPlatform/Dxe/ComponentName.h
new file mode 100644
index 0000000000..3bada842d7
--- /dev/null
+++ b/EdkModulePkg/Universal/ConPlatform/Dxe/ComponentName.h
@@ -0,0 +1,44 @@
+/*++
+
+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.h
+
+Abstract:
+
+--*/
+
+#ifndef CON_MANAGE_COMPONENT_NAME_H_
+#define CON_MANAGE_COMPONENT_NAME_H_
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+ConPlatformComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+ConPlatformComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+#endif
diff --git a/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.c b/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.c
new file mode 100644
index 0000000000..4b7d2796d0
--- /dev/null
+++ b/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.c
@@ -0,0 +1,811 @@
+/*++
+
+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:
+
+ ConPlatform.c
+
+Abstract:
+
+--*/
+
+#include "ConPlatform.h"
+
+EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextInDriverBinding = {
+ ConPlatformTextInDriverBindingSupported,
+ ConPlatformTextInDriverBindingStart,
+ ConPlatformDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding = {
+ ConPlatformTextOutDriverBindingSupported,
+ ConPlatformTextOutDriverBindingStart,
+ ConPlatformDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformTextInDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+ Supported
+
+Arguments:
+ (Standard DriverBinding Protocol Supported() function)
+
+Returns:
+
+ None
+
+--*/
+{
+ return ConPlatformDriverBindingSupported (
+ This,
+ ControllerHandle,
+ RemainingDevicePath,
+ &gEfiSimpleTextInProtocolGuid
+ );
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformTextOutDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+ Supported
+
+Arguments:
+ (Standard DriverBinding Protocol Supported() function)
+
+Returns:
+
+ None
+
+--*/
+{
+ return ConPlatformDriverBindingSupported (
+ This,
+ ControllerHandle,
+ RemainingDevicePath,
+ &gEfiSimpleTextOutProtocolGuid
+ );
+}
+
+EFI_STATUS
+ConPlatformDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ IN EFI_GUID *ProtocolGuid
+ )
+/*++
+
+Routine Description:
+ Supported
+
+Arguments:
+ (Standard DriverBinding Protocol Supported() function)
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+
+ //
+ // Test to see if this is a physical device by checking to see if
+ // it has a Device Path Protocol
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Test to see if this device supports the Simple Text Output Protocol
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ ProtocolGuid,
+ (VOID **) &Interface,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ ProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformTextInDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+ (Standard DriverBinding Protocol Start() function)
+
+Returns:
+
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;
+
+ //
+ // Get the Device Path Protocol so the environment variables can be updated
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Open the Simple Input Protocol BY_DRIVER
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextInProtocolGuid,
+ (VOID **) &TextIn,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Check the device handle, if it is a hot plug device,
+ // do not put the device path into ConInDev, and install
+ // gEfiConsoleInDeviceGuid to the device handle directly.
+ // The policy is, make hot plug device plug in and play immediately.
+ //
+ if (IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {
+ gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiConsoleInDeviceGuid,
+ NULL,
+ NULL
+ );
+ } else {
+ //
+ // Append the device path to the ConInDev environment variable
+ //
+ ConPlatformUpdateDeviceVariable (
+ VarConsoleInpDev,
+ DevicePath,
+ APPEND
+ );
+
+ //
+ // If the device path is an instance in the ConIn environment variable,
+ // then install EfiConsoleInDeviceGuid onto ControllerHandle
+ //
+ Status = ConPlatformUpdateDeviceVariable (
+ VarConsoleInp,
+ DevicePath,
+ CHECK
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiConsoleInDeviceGuid,
+ NULL,
+ NULL
+ );
+ } else {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextInProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformTextOutDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+ (Standard DriverBinding Protocol Start() function)
+
+Returns:
+
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;
+
+ BOOLEAN NeedClose;
+
+ NeedClose = TRUE;
+
+ //
+ // Get the Device Path Protocol so the environment variables can be updated
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Open the Simple Text Output Protocol BY_DRIVER
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ (VOID **) &TextOut,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Check the device handle, if it is a hot plug device,
+ // do not put the device path into ConOutDev and StdErrDev,
+ // and install gEfiConsoleOutDeviceGuid to the device handle directly.
+ // The policy is, make hot plug device plug in and play immediately.
+ //
+ if (IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {
+ gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiConsoleOutDeviceGuid,
+ NULL,
+ NULL
+ );
+ } else {
+ //
+ // Append the device path to the ConOutDev environment variable
+ //
+ ConPlatformUpdateDeviceVariable (
+ VarConsoleOutDev,
+ DevicePath,
+ APPEND
+ );
+ //
+ // Append the device path to the StdErrDev environment variable
+ //
+ ConPlatformUpdateDeviceVariable (
+ VarErrorOutDev,
+ DevicePath,
+ APPEND
+ );
+
+ //
+ // If the device path is an instance in the ConOut environment variable,
+ // then install EfiConsoleOutDeviceGuid onto ControllerHandle
+ //
+ Status = ConPlatformUpdateDeviceVariable (
+ VarConsoleOut,
+ DevicePath,
+ CHECK
+ );
+ if (!EFI_ERROR (Status)) {
+ NeedClose = FALSE;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiConsoleOutDeviceGuid,
+ NULL,
+ NULL
+ );
+ }
+ //
+ // If the device path is an instance in the StdErr environment variable,
+ // then install EfiStandardErrorDeviceGuid onto ControllerHandle
+ //
+ Status = ConPlatformUpdateDeviceVariable (
+ VarErrorOut,
+ DevicePath,
+ CHECK
+ );
+ if (!EFI_ERROR (Status)) {
+ NeedClose = FALSE;
+ gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiStandardErrorDeviceGuid,
+ NULL,
+ NULL
+ );
+ }
+
+ if (NeedClose) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+ (Standard DriverBinding Protocol Stop() function)
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // hot plug device is not included into the console associated variables,
+ // so no need to check variable for those hot plug devices.
+ //
+ if (!IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {
+ //
+ // Get the Device Path Protocol so the environment variables can be updated
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Remove DevicePath from ConInDev, ConOutDev, and StdErrDev
+ //
+ ConPlatformUpdateDeviceVariable (
+ VarConsoleInpDev,
+ DevicePath,
+ DELETE
+ );
+ ConPlatformUpdateDeviceVariable (
+ VarConsoleOutDev,
+ DevicePath,
+ DELETE
+ );
+ ConPlatformUpdateDeviceVariable (
+ VarErrorOutDev,
+ DevicePath,
+ DELETE
+ );
+ }
+ }
+ //
+ // Uninstall the Console Device GUIDs from Controller Handle
+ //
+ ConPlatformUnInstallProtocol (
+ This,
+ ControllerHandle,
+ &gEfiConsoleInDeviceGuid
+ );
+
+ ConPlatformUnInstallProtocol (
+ This,
+ ControllerHandle,
+ &gEfiConsoleOutDeviceGuid
+ );
+
+ ConPlatformUnInstallProtocol (
+ This,
+ ControllerHandle,
+ &gEfiStandardErrorDeviceGuid
+ );
+
+ //
+ // Close the Simple Input and Simple Text Output Protocols
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextInProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_SUCCESS;
+}
+
+VOID
+ConPlatformUnInstallProtocol (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *ProtocolGuid
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ ProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ Handle,
+ ProtocolGuid,
+ NULL,
+ NULL
+ );
+ }
+
+ return ;
+}
+
+VOID *
+ConPlatformGetVariable (
+ IN CHAR16 *Name
+ )
+/*++
+
+Routine Description:
+ Read the EFI variable (Name) and return a dynamically allocated
+ buffer, and the size of the buffer. On failure return NULL.
+
+Arguments:
+ Name - String part of EFI variable name
+
+Returns:
+ Dynamically allocated memory that contains a copy of the EFI variable.
+ Caller is repsoncible freeing the buffer.
+
+ NULL - Variable was not read
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *Buffer;
+ UINTN BufferSize;
+
+ BufferSize = 0;
+ Buffer = NULL;
+
+ //
+ // Test to see if the variable exists. If it doesn't reuturn NULL
+ //
+ Status = gRT->GetVariable (
+ Name,
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &BufferSize,
+ Buffer
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // Allocate the buffer to return
+ //
+ Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ //
+ // Read variable into the allocated buffer.
+ //
+ Status = gRT->GetVariable (
+ Name,
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &BufferSize,
+ Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (Buffer);
+ Buffer = NULL;
+ }
+ }
+
+ return Buffer;
+}
+
+EFI_STATUS
+ConPlatformMatchDevicePaths (
+ IN EFI_DEVICE_PATH_PROTOCOL * Multi,
+ IN EFI_DEVICE_PATH_PROTOCOL * Single,
+ IN EFI_DEVICE_PATH_PROTOCOL **NewDevicePath OPTIONAL,
+ IN BOOLEAN Delete
+ )
+/*++
+
+Routine Description:
+ Function compares a device path data structure to that of all the nodes of a
+ second device path instance.
+
+Arguments:
+ Multi - A pointer to a multi-instance device path data structure.
+
+ Single - A pointer to a single-instance device path data structure.
+
+ NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
+ points to the remaining device path data structure.
+ (remaining device path = Multi - Single.)
+
+ Delete - If TRUE, means removing Single from Multi.
+ If FALSE, the routine just check whether Single matches
+ with any instance in Multi.
+
+Returns:
+
+ The function returns EFI_SUCCESS if the Single is contained within Multi.
+ Otherwise, EFI_NOT_FOUND is returned.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath1;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath2;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
+ UINTN Size;
+
+ //
+ // The passed in DevicePath should not be NULL
+ //
+ if ((!Multi) || (!Single)) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // if performing Delete operation, the NewDevicePath must not be NULL.
+ //
+ TempDevicePath1 = NULL;
+
+ DevicePath = Multi;
+ DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
+
+ //
+ // search for the match of 'Single' in 'Multi'
+ //
+ while (DevicePathInst) {
+ if (CompareMem (Single, DevicePathInst, Size) == 0) {
+ if (!Delete) {
+ gBS->FreePool (DevicePathInst);
+ return EFI_SUCCESS;
+ }
+ } else {
+ if (Delete) {
+ TempDevicePath2 = AppendDevicePathInstance (
+ TempDevicePath1,
+ DevicePathInst
+ );
+ gBS->FreePool (TempDevicePath1);
+ TempDevicePath1 = TempDevicePath2;
+ }
+ }
+
+ gBS->FreePool (DevicePathInst);
+ DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
+ }
+
+ if (Delete) {
+ *NewDevicePath = TempDevicePath1;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+ConPlatformUpdateDeviceVariable (
+ IN CHAR16 *VariableName,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONPLATFORM_VAR_OPERATION Operation
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *VariableDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *NewVariableDevicePath;
+
+ VariableDevicePath = NULL;
+ NewVariableDevicePath = NULL;
+
+ //
+ // Get Variable according to variable name.
+ // The memory for Variable is allocated within ConPlatformGetVarible(),
+ // it is the caller's responsibility to free the memory before return.
+ //
+ VariableDevicePath = ConPlatformGetVariable (VariableName);
+
+ if (Operation != DELETE) {
+
+ Status = ConPlatformMatchDevicePaths (
+ VariableDevicePath,
+ DevicePath,
+ NULL,
+ FALSE
+ );
+
+ if ((Operation == CHECK) || (!EFI_ERROR (Status))) {
+ //
+ // The device path is already in the variable
+ //
+ gBS->FreePool (VariableDevicePath);
+
+ return Status;
+ }
+ //
+ // The device path is not in variable. Append DevicePath to the
+ // environment variable that is a multi-instance device path.
+ //
+ Status = EFI_SUCCESS;
+ NewVariableDevicePath = AppendDevicePathInstance (
+ VariableDevicePath,
+ DevicePath
+ );
+ if (NewVariableDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ } else {
+ //
+ // Remove DevicePath from the environment variable that
+ // is a multi-instance device path.
+ //
+ Status = ConPlatformMatchDevicePaths (
+ VariableDevicePath,
+ DevicePath,
+ &NewVariableDevicePath,
+ TRUE
+ );
+ }
+
+ gBS->FreePool (VariableDevicePath);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ GetDevicePathSize (NewVariableDevicePath),
+ NewVariableDevicePath
+ );
+
+ gBS->FreePool (NewVariableDevicePath);
+
+ return Status;
+}
+
+BOOLEAN
+IsHotPlugDevice (
+ EFI_HANDLE DriverBindingHandle,
+ EFI_HANDLE ControllerHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiHotPlugDeviceGuid,
+ NULL,
+ DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.h b/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.h
new file mode 100644
index 0000000000..41b025625b
--- /dev/null
+++ b/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.h
@@ -0,0 +1,126 @@
+/*++
+
+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:
+
+ ConPlatform.h
+
+Abstract:
+
+--*/
+
+#ifndef CON_MANAGE_H_
+#define CON_MANAGE_H_
+
+//
+//
+//
+#define VarConsoleInpDev L"ConInDev"
+#define VarConsoleInp L"ConIn"
+#define VarConsoleOutDev L"ConOutDev"
+#define VarConsoleOut L"ConOut"
+#define VarErrorOutDev L"ErrOutDev"
+#define VarErrorOut L"ErrOut"
+
+typedef enum {
+ CHECK,
+ APPEND,
+ DELETE
+} CONPLATFORM_VAR_OPERATION;
+
+EFI_STATUS
+ConPlatformDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ IN EFI_GUID *ProtocolGuid
+ );
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformTextInDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformTextOutDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformTextInDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformTextOutDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConPlatformDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+VOID
+ConPlatformUnInstallProtocol (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *ProtocolGuid
+ );
+
+VOID *
+ConPlatformGetVariable (
+ IN CHAR16 *Name
+ );
+
+EFI_STATUS
+ConPlatformMatchDevicePaths (
+ IN EFI_DEVICE_PATH_PROTOCOL * Multi,
+ IN EFI_DEVICE_PATH_PROTOCOL * Single,
+ IN EFI_DEVICE_PATH_PROTOCOL **NewDevicePath OPTIONAL,
+ IN BOOLEAN Delete
+ );
+
+EFI_STATUS
+ConPlatformUpdateDeviceVariable (
+ IN CHAR16 *VariableName,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONPLATFORM_VAR_OPERATION Operation
+ );
+
+BOOLEAN
+IsHotPlugDevice (
+ EFI_HANDLE DriverBindingHandle,
+ EFI_HANDLE ControllerHandle
+ );
+
+#endif
diff --git a/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.msa b/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.msa
new file mode 100644
index 0000000000..ebedff844a
--- /dev/null
+++ b/EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.msa
@@ -0,0 +1,144 @@
+
+
+
+
+ ConPlatform
+ UEFI_DRIVER
+ 51ccf399-4fdf-4e55-a45b-e123f84d456a
+ 1.0
+ Console Platfrom Driver
+ Console Platfrom DXE Driver, install Console protocols
+ 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.
+ FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052
+
+
+ IA32 X64 IPF EBC
+ false
+ ConPlatform
+
+
+
+ DebugLib
+
+
+ UefiDriverModelLib
+
+
+ UefiDriverEntryPoint
+
+
+ UefiLib
+
+
+ BaseLib
+
+
+ BaseMemoryLib
+
+
+ MemoryAllocationLib
+
+
+ UefiBootServicesTableLib
+
+
+ UefiRuntimeServicesTableLib
+
+
+ DevicePathLib
+
+
+
+ ConPlatform.c
+ ConPlatform.h
+ ComponentName.h
+ ComponentName.c
+
+
+
+
+
+
+
+ gEfiSimpleTextOutProtocolGuid
+
+
+ gEfiSimpleTextInProtocolGuid
+
+
+ gEfiDevicePathProtocolGuid
+
+
+
+
+ 0x0043 0x006F 0x006E 0x0049 0x006E 0x0044 0x0065 0x0076
+ gConInDevGuid
+
+
+ 0x0043 0x006F 0x006E 0x0049 0x006E
+ gConInGuid
+
+
+ 0x0043 0x006F 0x006E 0x004F 0x0075 0x0074 0x0044 0x0065 0x0076
+ gConOutDevGuid
+
+
+ 0x0043 0x006F 0x006E 0x004F 0x0075 0x0074
+ gConOutGuid
+
+
+ 0x0045 0x0072 0x0072 0x004F 0x0075 0x0074 0x0044 0x0065 0x0076
+ gErrOutDevGuid
+
+
+ 0x0045 0x0072 0x0072 0x004F 0x0075 0x0074
+ gErrOutGuid
+
+
+
+
+ gEfiConsoleInDeviceGuid
+
+
+ gEfiConsoleOutDeviceGuid
+
+
+ gEfiStandardErrorDeviceGuid
+
+
+ gEfiHotPlugDeviceGuid
+
+
+ gEfiGlobalVariableGuid
+
+
+
+ EFI_SPECIFICATION_VERSION 0x00020000
+ EDK_RELEASE_VERSION 0x00020000
+
+ gConPlatformTextInDriverBinding
+
+
+ gConPlatformComponentName
+
+
+ gConPlatformTextOutDriverBinding
+
+
+ gConPlatformComponentName
+
+
+
\ No newline at end of file