Initial import.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
bbahnsen
2006-04-21 22:54:32 +00:00
commit 878ddf1fc3
2651 changed files with 624620 additions and 0 deletions

View File

@@ -0,0 +1,531 @@
/*++
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 "ConSplitter.h"
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
ConSplitterComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
ConSplitterConInComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
EFI_STATUS
EFIAPI
ConSplitterSimplePointerComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
EFI_STATUS
EFIAPI
ConSplitterConOutComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
EFI_STATUS
EFIAPI
ConSplitterStdErrComponentNameGetControllerName (
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 gConSplitterConInComponentName = {
ConSplitterComponentNameGetDriverName,
ConSplitterConInComponentNameGetControllerName,
"eng"
};
EFI_COMPONENT_NAME_PROTOCOL gConSplitterSimplePointerComponentName = {
ConSplitterComponentNameGetDriverName,
ConSplitterSimplePointerComponentNameGetControllerName,
"eng"
};
EFI_COMPONENT_NAME_PROTOCOL gConSplitterConOutComponentName = {
ConSplitterComponentNameGetDriverName,
ConSplitterConOutComponentNameGetControllerName,
"eng"
};
EFI_COMPONENT_NAME_PROTOCOL gConSplitterStdErrComponentName = {
ConSplitterComponentNameGetDriverName,
ConSplitterStdErrComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mConSplitterDriverNameTable[] = {
{
"eng",
(CHAR16 *) L"Console Splitter Driver"
},
{
NULL,
NULL
}
};
static EFI_UNICODE_STRING_TABLE mConSplitterConInControllerNameTable[] = {
{
"eng",
(CHAR16 *) L"Primary Console Input Device"
},
{
NULL,
NULL
}
};
static EFI_UNICODE_STRING_TABLE mConSplitterSimplePointerControllerNameTable[] = {
{
"eng",
(CHAR16 *) L"Primary Simple Pointer Device"
},
{
NULL,
NULL
}
};
static EFI_UNICODE_STRING_TABLE mConSplitterConOutControllerNameTable[] = {
{
"eng",
(CHAR16 *) L"Primary Console Output Device"
},
{
NULL,
NULL
}
};
static EFI_UNICODE_STRING_TABLE mConSplitterStdErrControllerNameTable[] = {
{
"eng",
(CHAR16 *) L"Primary Standard Error Device"
},
{
NULL,
NULL
}
};
EFI_STATUS
EFIAPI
ConSplitterComponentNameGetDriverName (
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,
gConSplitterConInComponentName.SupportedLanguages,
mConSplitterDriverNameTable,
DriverName
);
}
EFI_STATUS
EFIAPI
ConSplitterConInComponentNameGetControllerName (
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_IN_PROTOCOL *TextIn;
//
// here ChildHandle is not an Optional parameter.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimpleTextInProtocolGuid,
(VOID **) &TextIn,
NULL,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
return LookupUnicodeString (
Language,
gConSplitterConInComponentName.SupportedLanguages,
mConSplitterConInControllerNameTable,
ControllerName
);
}
EFI_STATUS
EFIAPI
ConSplitterSimplePointerComponentNameGetControllerName (
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_POINTER_PROTOCOL *SimplePointer;
//
// here ChildHandle is not an Optional parameter.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimplePointerProtocolGuid,
(VOID **) &SimplePointer,
NULL,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
return LookupUnicodeString (
Language,
gConSplitterSimplePointerComponentName.SupportedLanguages,
mConSplitterSimplePointerControllerNameTable,
ControllerName
);
}
EFI_STATUS
EFIAPI
ConSplitterConOutComponentNameGetControllerName (
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 *TextOut;
//
// here ChildHandle is not an Optional parameter.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimpleTextOutProtocolGuid,
(VOID **) &TextOut,
NULL,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
return LookupUnicodeString (
Language,
gConSplitterConOutComponentName.SupportedLanguages,
mConSplitterConOutControllerNameTable,
ControllerName
);
}
EFI_STATUS
EFIAPI
ConSplitterStdErrComponentNameGetControllerName (
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 *ErrOut;
//
// here ChildHandle is not an Optional parameter.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimpleTextOutProtocolGuid,
(VOID **) &ErrOut,
NULL,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
return LookupUnicodeString (
Language,
gConSplitterStdErrComponentName.SupportedLanguages,
mConSplitterStdErrControllerNameTable,
ControllerName
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,623 @@
/*++
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:
ConSplitter.h
Abstract:
Private data structures for the Console Splitter driver
--*/
#ifndef SPLITER_H_
#define SPLITER_H_
//
// Private Data Structures
//
#define CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT 32
#define CONSOLE_SPLITTER_MODES_ALLOC_UNIT 32
#define MAX_STD_IN_PASSWORD 80
typedef struct {
UINTN Columns;
UINTN Rows;
} TEXT_OUT_SPLITTER_QUERY_DATA;
//
// Private data for the EFI_SIMPLE_INPUT_PROTOCOL splitter
//
#define TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('T', 'i', 'S', 'p')
typedef struct {
UINT64 Signature;
EFI_HANDLE VirtualHandle;
EFI_SIMPLE_TEXT_IN_PROTOCOL TextIn;
UINTN CurrentNumberOfConsoles;
EFI_SIMPLE_TEXT_IN_PROTOCOL **TextInList;
UINTN TextInListCount;
EFI_SIMPLE_POINTER_PROTOCOL SimplePointer;
EFI_SIMPLE_POINTER_MODE SimplePointerMode;
UINTN CurrentNumberOfPointers;
EFI_SIMPLE_POINTER_PROTOCOL **PointerList;
UINTN PointerListCount;
BOOLEAN PasswordEnabled;
CHAR16 Password[MAX_STD_IN_PASSWORD];
UINTN PwdIndex;
CHAR16 PwdAttempt[MAX_STD_IN_PASSWORD];
EFI_EVENT LockEvent;
BOOLEAN KeyEventSignalState;
BOOLEAN InputEventSignalState;
} TEXT_IN_SPLITTER_PRIVATE_DATA;
#define TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \
CR (a, \
TEXT_IN_SPLITTER_PRIVATE_DATA, \
TextIn, \
TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE \
)
#define TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS(a) \
CR (a, \
TEXT_IN_SPLITTER_PRIVATE_DATA, \
SimplePointer, \
TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE \
)
//
// Private data for the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL splitter
//
#define TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('T', 'o', 'S', 'p')
typedef struct {
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;
BOOLEAN TextOutEnabled;
} TEXT_OUT_AND_UGA_DATA;
typedef struct {
UINT64 Signature;
EFI_HANDLE VirtualHandle;
EFI_SIMPLE_TEXT_OUT_PROTOCOL TextOut;
EFI_SIMPLE_TEXT_OUTPUT_MODE TextOutMode;
EFI_UGA_DRAW_PROTOCOL UgaDraw;
UINT32 UgaHorizontalResolution;
UINT32 UgaVerticalResolution;
UINT32 UgaColorDepth;
UINT32 UgaRefreshRate;
EFI_UGA_PIXEL *UgaBlt;
EFI_CONSOLE_CONTROL_PROTOCOL ConsoleControl;
UINTN CurrentNumberOfConsoles;
TEXT_OUT_AND_UGA_DATA *TextOutList;
UINTN TextOutListCount;
TEXT_OUT_SPLITTER_QUERY_DATA *TextOutQueryData;
UINTN TextOutQueryDataCount;
INT32 *TextOutModeMap;
EFI_CONSOLE_CONTROL_SCREEN_MODE UgaMode;
UINTN DevNullColumns;
UINTN DevNullRows;
CHAR16 *DevNullScreen;
INT32 *DevNullAttributes;
} TEXT_OUT_SPLITTER_PRIVATE_DATA;
#define TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \
CR (a, \
TEXT_OUT_SPLITTER_PRIVATE_DATA, \
TextOut, \
TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE \
)
#define UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \
CR (a, \
TEXT_OUT_SPLITTER_PRIVATE_DATA, \
UgaDraw, \
TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE \
)
#define CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \
CR (a, \
TEXT_OUT_SPLITTER_PRIVATE_DATA, \
ConsoleControl, \
TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE \
)
//
// Function Prototypes
//
EFI_STATUS
EFIAPI
ConSplitterDriverEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
;
EFI_STATUS
ConSplitterTextInConstructor (
TEXT_IN_SPLITTER_PRIVATE_DATA *Private
)
;
EFI_STATUS
ConSplitterTextOutConstructor (
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private
)
;
//
// Driver Binding Functions
//
EFI_STATUS
EFIAPI
ConSplitterConInDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
ConSplitterSimplePointerDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
ConSplitterConOutDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
ConSplitterStdErrDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
ConSplitterConInDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
ConSplitterSimplePointerDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
ConSplitterConOutDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
ConSplitterStdErrDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
ConSplitterConInDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
;
EFI_STATUS
EFIAPI
ConSplitterSimplePointerDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
;
EFI_STATUS
EFIAPI
ConSplitterConOutDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
;
EFI_STATUS
EFIAPI
ConSplitterStdErrDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
;
//
// TextIn Constructor/Destructor functions
//
EFI_STATUS
ConSplitterTextInAddDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn
)
;
EFI_STATUS
ConSplitterTextInDeleteDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn
)
;
//
// SimplePointer Constuctor/Destructor functions
//
EFI_STATUS
ConSplitterSimplePointerAddDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer
)
;
EFI_STATUS
ConSplitterSimplePointerDeleteDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer
)
;
//
// TextOut Constuctor/Destructor functions
//
EFI_STATUS
ConSplitterTextOutAddDevice (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut,
IN EFI_UGA_DRAW_PROTOCOL *UgaDraw
)
;
EFI_STATUS
ConSplitterTextOutDeleteDevice (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut
)
;
//
// TextIn I/O Functions
//
EFI_STATUS
EFIAPI
ConSplitterTextInReset (
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
;
EFI_STATUS
EFIAPI
ConSplitterTextInReadKeyStroke (
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
)
;
VOID
EFIAPI
ConSplitterTextInWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
)
;
BOOLEAN
ConSpliterConssoleControlStdInLocked (
VOID
)
;
VOID
EFIAPI
ConSpliterConsoleControlLockStdInEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
;
EFI_STATUS
EFIAPI
ConSpliterConsoleControlLockStdIn (
IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
IN CHAR16 *Password
)
;
EFI_STATUS
EFIAPI
ConSplitterTextInPrivateReadKeyStroke (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
OUT EFI_INPUT_KEY *Key
)
;
EFI_STATUS
EFIAPI
ConSplitterSimplePointerReset (
IN EFI_SIMPLE_POINTER_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
;
EFI_STATUS
EFIAPI
ConSplitterSimplePointerGetState (
IN EFI_SIMPLE_POINTER_PROTOCOL *This,
IN OUT EFI_SIMPLE_POINTER_STATE *State
)
;
VOID
EFIAPI
ConSplitterSimplePointerWaitForInput (
IN EFI_EVENT Event,
IN VOID *Context
)
;
//
// TextOut I/O Functions
//
VOID
ConSplitterSynchronizeModeData (
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutReset (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutOutputString (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *WString
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutTestString (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *WString
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutQueryMode (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber,
OUT UINTN *Columns,
OUT UINTN *Rows
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutSetMode (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutSetAttribute (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Attribute
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutClearScreen (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutSetCursorPosition (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Column,
IN UINTN Row
)
;
EFI_STATUS
EFIAPI
ConSplitterTextOutEnableCursor (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN Visible
)
;
EFI_STATUS
ConSplitterGrowBuffer (
IN UINTN SizeOfCount,
IN UINTN *Count,
IN OUT VOID **Buffer
)
;
EFI_STATUS
EFIAPI
ConSpliterConsoleControlGetMode (
IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
OUT BOOLEAN *UgaExists,
OUT BOOLEAN *StdInLocked
)
;
EFI_STATUS
EFIAPI
ConSpliterConsoleControlSetMode (
IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
)
;
EFI_STATUS
EFIAPI
ConSpliterUgaDrawGetMode (
IN EFI_UGA_DRAW_PROTOCOL *This,
OUT UINT32 *HorizontalResolution,
OUT UINT32 *VerticalResolution,
OUT UINT32 *ColorDepth,
OUT UINT32 *RefreshRate
)
;
EFI_STATUS
EFIAPI
ConSpliterUgaDrawSetMode (
IN EFI_UGA_DRAW_PROTOCOL *This,
IN UINT32 HorizontalResolution,
IN UINT32 VerticalResolution,
IN UINT32 ColorDepth,
IN UINT32 RefreshRate
)
;
EFI_STATUS
EFIAPI
ConSpliterUgaDrawBlt (
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
)
;
EFI_STATUS
DevNullUgaSync (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,
IN EFI_UGA_DRAW_PROTOCOL *UgaDraw
)
;
EFI_STATUS
DevNullTextOutOutputString (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,
IN CHAR16 *WString
)
;
EFI_STATUS
DevNullTextOutSetMode (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,
IN UINTN ModeNumber
)
;
EFI_STATUS
DevNullTextOutClearScreen (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private
)
;
EFI_STATUS
DevNullTextOutSetCursorPosition (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,
IN UINTN Column,
IN UINTN Row
)
;
EFI_STATUS
DevNullTextOutEnableCursor (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,
IN BOOLEAN Visible
)
;
EFI_STATUS
DevNullSyncUgaStdOut (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private
)
;
#endif

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>ConSplitter</BaseName>
<Guid>408edcec-cf6d-477c-a5a8-b4844e3de281</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>UefiDriverModelLib</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>BaseLib</Library>
<Library>DxeMemoryAllocationLib</Library>
</Libraries>
</ModuleBuildDescription>

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>ConSplitter</BaseName>
<ModuleType>DXE_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>408edcec-cf6d-477c-a5a8-b4844e3de281</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>ConSplitter.c</Filename>
<Filename>ConSplitter.h</Filename>
<Filename>ComponentName.c</Filename>
<Filename>ConSplitterGraphics.c</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
<PackageName>EdkModulePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="ALWAYS_CONSUMED">UgaDraw</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">SimpleTextOut</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">SimpleTextIn</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">SimplePointer</Protocol>
<Protocol Usage="ALWAYS_PRODUCED">ConsoleControl</Protocol>
</Protocols>
<Guids>
<GuidEntry Usage="ALWAYS_PRODUCED">
<C_Name>PrimaryStandardErrorDevice</C_Name>
</GuidEntry>
<GuidEntry Usage="ALWAYS_PRODUCED">
<C_Name>PrimaryConsoleInDevice</C_Name>
</GuidEntry>
<GuidEntry Usage="ALWAYS_PRODUCED">
<C_Name>PrimaryConsoleOutDevice</C_Name>
</GuidEntry>
<GuidEntry Usage="ALWAYS_CONSUMED">
<C_Name>ConsoleOutDevice</C_Name>
</GuidEntry>
<GuidEntry Usage="ALWAYS_CONSUMED">
<C_Name>StandardErrorDevice</C_Name>
</GuidEntry>
<GuidEntry Usage="ALWAYS_CONSUMED">
<C_Name>ConsoleInDevice</C_Name>
</GuidEntry>
</Guids>
<Externs>
<Extern>
<ModuleEntryPoint>ConSplitterDriverEntry</ModuleEntryPoint>
</Extern>
<Extern>
<DriverBinding>gConSplitterConInDriverBinding</DriverBinding>
<ComponentName>gConSplitterConInComponentName</ComponentName>
</Extern>
<Extern>
<DriverBinding>gConSplitterSimplePointerDriverBinding</DriverBinding>
<ComponentName>gConSplitterSimplePointerComponentName</ComponentName>
</Extern>
<Extern>
<DriverBinding>gConSplitterConOutDriverBinding</DriverBinding>
<ComponentName>gConSplitterConOutComponentName</ComponentName>
</Extern>
<Extern>
<DriverBinding>gConSplitterStdErrDriverBinding</DriverBinding>
<ComponentName>gConSplitterStdErrComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="ConSplitter"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Console\ConSplitter\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="ConSplitter">
<GenBuild baseName="ConSplitter" mbdFilename="${MODULE_DIR}\ConSplitter.mbd" msaFilename="${MODULE_DIR}\ConSplitter.msa"/>
</target>
<target name="ConSplitterLite">
<GenBuild baseName="ConSplitterLite" mbdFilename="${MODULE_DIR}\ConSplitterLite.mbd" msaFilename="${MODULE_DIR}\ConSplitterLite.msa"/>
</target>
<target depends="ConSplitter_clean" name="clean"/>
<target depends="ConSplitter_cleanall" name="cleanall"/>
<target name="ConSplitter_clean">
<OutputDirSetup baseName="ConSplitter" mbdFilename="${MODULE_DIR}\ConSplitter.mbd" msaFilename="${MODULE_DIR}\ConSplitter.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\ConSplitter_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\ConSplitter_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="ConSplitterLite_clean">
<OutputDirSetup baseName="ConSplitterLite" mbdFilename="${MODULE_DIR}\ConSplitterLite.mbd" msaFilename="${MODULE_DIR}\ConSplitterLite.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\ConSplitterLite_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\ConSplitterLite_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="ConSplitter_cleanall">
<OutputDirSetup baseName="ConSplitter" mbdFilename="${MODULE_DIR}\ConSplitter.mbd" msaFilename="${MODULE_DIR}\ConSplitter.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\ConSplitter_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\ConSplitter_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**ConSplitter*"/>
</delete>
</target>
<target name="ConSplitterLite_cleanall">
<OutputDirSetup baseName="ConSplitterLite" mbdFilename="${MODULE_DIR}\ConSplitterLite.mbd" msaFilename="${MODULE_DIR}\ConSplitterLite.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\ConSplitterLite_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\ConSplitterLite_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**ConSplitterLite*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,139 @@
/*++
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 "GraphicsConsole.h"
//
// EFI Component Name Protocol
//
EFI_COMPONENT_NAME_PROTOCOL gGraphicsConsoleComponentName = {
GraphicsConsoleComponentNameGetDriverName,
GraphicsConsoleComponentNameGetControllerName,
"eng"
};
STATIC EFI_UNICODE_STRING_TABLE mGraphicsConsoleDriverNameTable[] = {
{
"eng",
(CHAR16 *)L"UGA Console Driver"
},
{
NULL,
NULL
}
};
EFI_STATUS
EFIAPI
GraphicsConsoleComponentNameGetDriverName (
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,
gGraphicsConsoleComponentName.SupportedLanguages,
mGraphicsConsoleDriverNameTable,
DriverName
);
}
EFI_STATUS
EFIAPI
GraphicsConsoleComponentNameGetControllerName (
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;
}

View File

@@ -0,0 +1,51 @@
/*++
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:
Revision History
--*/
#ifndef _GRAPHICS_CONSOLE_COMPONENT_NAME_H
#define _GRAPHICS_CONSOLE_COMPONENT_NAME_H
extern EFI_COMPONENT_NAME_PROTOCOL gGraphicsConsoleComponentName;
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
GraphicsConsoleComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
;
EFI_STATUS
EFIAPI
GraphicsConsoleComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
/*++
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:
GraphicsConsole.h
Abstract:
Revision History
--*/
#ifndef _GRAPHICS_CONSOLE_H
#define _GRAPHICS_CONSOLE_H
#include "ComponentName.h"
//
// Glyph database
//
#define GLYPH_WIDTH 8
#define GLYPH_HEIGHT 19
typedef union {
EFI_NARROW_GLYPH NarrowGlyph;
EFI_WIDE_GLYPH WideGlyph;
} GLYPH_UNION;
extern EFI_NARROW_GLYPH UsStdNarrowGlyphData[];
extern EFI_WIDE_GLYPH UsStdWideGlyphData[];
//
// Device Structure
//
#define GRAPHICS_CONSOLE_DEV_SIGNATURE EFI_SIGNATURE_32 ('g', 's', 't', 'o')
typedef struct {
UINTN Columns;
UINTN Rows;
INTN DeltaX;
INTN DeltaY;
UINT32 UgaWidth;
UINT32 UgaHeight;
} GRAPHICS_CONSOLE_MODE_DATA;
#define GRAPHICS_MAX_MODE 3
typedef struct {
UINTN Signature;
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
EFI_SIMPLE_TEXT_OUT_PROTOCOL SimpleTextOutput;
EFI_SIMPLE_TEXT_OUTPUT_MODE SimpleTextOutputMode;
GRAPHICS_CONSOLE_MODE_DATA ModeData[GRAPHICS_MAX_MODE];
EFI_UGA_PIXEL *LineBuffer;
EFI_HII_HANDLE HiiHandle;
} GRAPHICS_CONSOLE_DEV;
#define GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS(a) \
CR (a, GRAPHICS_CONSOLE_DEV, SimpleTextOutput, GRAPHICS_CONSOLE_DEV_SIGNATURE)
//
// Global Variables
//
extern EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding;
//
// Prototypes
//
UINTN
ReturnNarrowFontSize (
VOID
);
UINTN
ReturnWideFontSize (
VOID
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutReset (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutOutputString (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *WString
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutTestString (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *WString
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutQueryMode (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber,
OUT UINTN *Columns,
OUT UINTN *Rows
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutSetMode (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutSetAttribute (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Attribute
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutClearScreen (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutSetCursorPosition (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Column,
IN UINTN Row
);
EFI_STATUS
EFIAPI
GraphicsConsoleConOutEnableCursor (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN Visible
);
EFI_STATUS
EfiLocateHiiProtocol (
VOID
);
#endif

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>GraphicsConsole</BaseName>
<Guid>CCCB0C28-4B24-11d5-9A5A-0090273FC14D</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>UefiLib</Library>
<Library>UefiMemoryLib</Library>
<Library>HiiLib</Library>
<Library>UefiDriverModelLib</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>BaseLib</Library>
<Library>DxeMemoryAllocationLib</Library>
</Libraries>
</ModuleBuildDescription>

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>GraphicsConsole</BaseName>
<ModuleType>DXE_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>CCCB0C28-4B24-11d5-9A5A-0090273FC14D</Guid>
<Version>0</Version>
<Abstract>Component description file for GraphicsConsole module</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>GraphicsConsole.h</Filename>
<Filename>GraphicsConsole.c</Filename>
<Filename>LaffStd.c</Filename>
<Filename>ComponentName.c</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="TO_START">UgaDraw</Protocol>
<Protocol Usage="TO_START">Hii</Protocol>
<Protocol Usage="BY_START">SimpleTextOut</Protocol>
<Protocol Usage="TO_START">DevicePath</Protocol>
</Protocols>
<Externs>
<Extern>
<ModuleEntryPoint></ModuleEntryPoint>
</Extern>
<Extern>
<DriverBinding>gGraphicsConsoleDriverBinding</DriverBinding>
<ComponentName>gGraphicsConsoleComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,290 @@
/*++
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:
LaffStd.c
Abstract:
Revision History
--*/
#include "GraphicsConsole.h"
EFI_NARROW_GLYPH UsStdNarrowGlyphData[] = {
//
// Unicode glyphs from 0x20 to 0x7e are the same as ASCII characters 0x20 to 0x7e
//
{ 0x0020, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x0021, 0x00, {0x00,0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}},
{ 0x0022, 0x00, {0x00,0x00,0x00,0x6C,0x6C,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x0023, 0x00, {0x00,0x00,0x00,0x00,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00}},
{ 0x0024, 0x00, {0x00,0x00,0x18,0x18,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x18,0x18,0x00,0x00,0x00}},
{ 0x0025, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x60,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x0026, 0x00, {0x00,0x00,0x00,0x78,0xCC,0xCC,0xCC,0x78,0x76,0xDC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x0027, 0x00, {0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x0028, 0x00, {0x00,0x00,0x00,0x06,0x0C,0x0C,0x18,0x18,0x18,0x18,0x18,0x18,0x0C,0x0C,0x06,0x00,0x00,0x00,0x00}},
{ 0x0029, 0x00, {0x00,0x00,0x00,0xC0,0x60,0x60,0x30,0x30,0x30,0x30,0x30,0x30,0x60,0x60,0xC0,0x00,0x00,0x00,0x00}},
{ 0x002a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x38,0xFE,0x38,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x002b, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x002c, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00}},
{ 0x002d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x002e, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
{ 0x002f, 0x00, {0x00,0x00,0x00,0x06,0x06,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x60,0xC0,0xC0,0x00,0x00,0x00,0x00}},
{ 0x0030, 0x00, {0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00}},
{ 0x0031, 0x00, {0x00,0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}},
{ 0x0032, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0x06,0x06,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC2,0xFE,0x00,0x00,0x00,0x00}},
{ 0x0033, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0x06,0x06,0x06,0x3C,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0034, 0x00, {0x00,0x00,0x00,0x1C,0x1C,0x3C,0x3C,0x6C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}},
{ 0x0035, 0x00, {0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0036, 0x00, {0x00,0x00,0x00,0x3C,0x60,0xC0,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0037, 0x00, {0x00,0x00,0x00,0xFE,0xC6,0x06,0x06,0x06,0x0C,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00}},
{ 0x0038, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0039, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00}},
{ 0x003a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
{ 0x003b, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00}},
{ 0x003c, 0x00, {0x00,0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00}},
{ 0x003d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x003e, 0x00, {0x00,0x00,0x00,0x00,0xC0,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00,0x00,0x00,0x00}},
{ 0x003f, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}},
{ 0x0040, 0x00, {0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0xC0,0x7E,0x00,0x00,0x00,0x00}},
{ 0x0041, 0x00, {0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x0042, 0x00, {0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00}},
{ 0x0043, 0x00, {0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00}},
{ 0x0044, 0x00, {0x00,0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00}},
{ 0x0045, 0x00, {0x00,0x00,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},
{ 0x0046, 0x00, {0x00,0x00,0x00,0xFE,0x66,0x62,0x60,0x64,0x7C,0x64,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}},
{ 0x0047, 0x00, {0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xDE,0xC6,0xC6,0xC6,0x66,0x3C,0x00,0x00,0x00,0x00}},
{ 0x0048, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x0049, 0x00, {0x00,0x00,0x00,0xFC,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xFC,0x00,0x00,0x00,0x00}},
{ 0x004a, 0x00, {0x00,0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00}},
{ 0x004b, 0x00, {0x00,0x00,0x00,0xE6,0x66,0x6C,0x6C,0x78,0x70,0x78,0x6C,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}},
{ 0x004c, 0x00, {0x00,0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},
{ 0x004d, 0x00, {0x00,0x00,0x00,0xC6,0xEE,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x004e, 0x00, {0x00,0x00,0x00,0xC6,0xE6,0xF6,0xF6,0xF6,0xDE,0xCE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x004f, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0050, 0x00, {0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}},
{ 0x0051, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0x7C,0x1C,0x0E,0x00,0x00}},
{ 0x0052, 0x00, {0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x78,0x6C,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}},
{ 0x0053, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x60,0x38,0x0C,0x06,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0054, 0x00, {0x00,0x00,0x00,0xFC,0xFC,0xB4,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}},
{ 0x0055, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0056, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00}},
{ 0x0057, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00}},
{ 0x0058, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0x6C,0x6C,0x38,0x6C,0x6C,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x0059, 0x00, {0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}},
{ 0x005a, 0x00, {0x00,0x00,0x00,0xFE,0xC6,0x86,0x0C,0x0C,0x18,0x30,0x60,0xC0,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00}},
{ 0x005b, 0x00, {0x00,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1E,0x00,0x00,0x00,0x00}},
{ 0x005c, 0x00, {0x00,0x00,0x00,0xC0,0xC0,0x60,0x60,0x30,0x30,0x18,0x18,0x0C,0x0C,0x06,0x06,0x00,0x00,0x00,0x00}},
{ 0x005d, 0x00, {0x00,0x00,0x00,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0x00,0x00,0x00,0x00}},
{ 0x005e, 0x00, {0x00,0x00,0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x005f, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00}},
{ 0x0060, 0x00, {0x00,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x0061, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x0062, 0x00, {0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0063, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0064, 0x00, {0x00,0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0xCC,0x7E,0x00,0x00,0x00,0x00}},
{ 0x0065, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0066, 0x00, {0x00,0x00,0x00,0x1E,0x33,0x30,0x30,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}},
{ 0x0067, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00}},
{ 0x0068, 0x00, {0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}},
{ 0x0069, 0x00, {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x006a, 0x00, {0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x6C,0x38,0x00}},
{ 0x006b, 0x00, {0x00,0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x70,0x78,0x6C,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00}},
{ 0x006c, 0x00, {0x00,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x006d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEC,0xEE,0xFE,0xD6,0xD6,0xD6,0xD6,0xD6,0x00,0x00,0x00,0x00}},
{ 0x006e, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00}},
{ 0x006f, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0070, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00}},
{ 0x0071, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00}},
{ 0x0072, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x60,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}},
{ 0x0073, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0x7C,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x0074, 0x00, {0x00,0x00,0x00,0x10,0x30,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00}},
{ 0x0075, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x0076, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x00,0x00,0x00,0x00}},
{ 0x0077, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00}},
{ 0x0078, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x6C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x0079, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00}},
{ 0x007a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x86,0x0C,0x18,0x30,0x60,0xC0,0xFE,0x00,0x00,0x00,0x00}},
{ 0x007b, 0x00, {0x00,0x00,0x00,0x0E,0x18,0x18,0x18,0x18,0x30,0x18,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00}},
{ 0x007c, 0x00, {0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00}},
{ 0x007d, 0x00, {0x00,0x00,0x00,0xE0,0x30,0x30,0x30,0x30,0x18,0x30,0x30,0x30,0x30,0x30,0xE0,0x00,0x00,0x00,0x00}},
{ 0x007e, 0x00, {0x00,0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00a0, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00a1, 0x00, {0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00}},
{ 0x00a2, 0x00, {0x00,0x00,0x00,0x00,0x18,0x18,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x18,0x18,0x00,0x00,0x00,0x00}},
{ 0x00a3, 0x00, {0x00,0x00,0x00,0x38,0x6C,0x64,0x60,0x60,0xF0,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00}},
{ 0x00a4, 0x00, {0x00,0x00,0x18,0x00,0x00,0x00,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0xC6,0x00,0x00,0x00,0x00,0x00}},
{ 0x00a5, 0x00, {0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00}},
{ 0x00a6, 0x00, {0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00}},
{ 0x00a7, 0x00, {0x00,0x00,0x18,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00a8, 0x00, {0x00,0x00,0x00,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00a9, 0x00, {0x00,0x00,0x00,0x00,0x7C,0x82,0x9A,0xA2,0xA2,0xA2,0x9A,0x82,0x7C,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00aa, 0x00, {0x00,0x00,0x00,0x00,0x3C,0x6C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00ab, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00ac, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00ad, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00ae, 0x00, {0x00,0x00,0x00,0x00,0x7C,0x82,0xB2,0xAA,0xAA,0xB2,0xAA,0xAA,0x82,0x7C,0x00,0x00,0x00,0x00,0x00}},
{ 0x00af, 0x00, {0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00b0, 0x00, {0x00,0x00,0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00b1, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00}},
{ 0x00b2, 0x00, {0x00,0x00,0x00,0x3C,0x66,0x0C,0x18,0x32,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00b3, 0x00, {0x00,0x00,0x00,0x7C,0x06,0x3C,0x06,0x06,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00b4, 0x00, {0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00b5, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xC0,0x00}},
{ 0x00b6, 0x00, {0x00,0x00,0x00,0x7F,0xDB,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00}},
{ 0x00b7, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00b8, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0x78,0x00,0x00,0x00}},
{ 0x00b9, 0x00, {0x00,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00ba, 0x00, {0x00,0x00,0x00,0x00,0x38,0x6C,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00bb, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00bc, 0x00, {0x00,0x00,0x00,0x60,0xE0,0x62,0x66,0x6C,0x18,0x30,0x66,0xCE,0x9A,0x3F,0x06,0x06,0x00,0x00,0x00}},
{ 0x00bd, 0x00, {0x00,0x00,0x00,0x60,0xE0,0x62,0x66,0x6C,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00,0x00}},
{ 0x00be, 0x00, {0x00,0x00,0x00,0xE0,0x30,0x62,0x36,0xEC,0x18,0x30,0x66,0xCE,0x9A,0x3F,0x06,0x06,0x00,0x00,0x00}},
{ 0x00bf, 0x00, {0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00c0, 0x00, {0x60,0x30,0x18,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x00c1, 0x00, {0x18,0x30,0x60,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x00c2, 0x00, {0x10,0x38,0x6C,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x00c3, 0x00, {0x76,0xDC,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x00c4, 0x00, {0xCC,0xCC,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x00c5, 0x00, {0x38,0x6C,0x38,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x00c6, 0x00, {0x00,0x00,0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00}},
{ 0x00c7, 0x00, {0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x18,0x70,0x00,0x00}},
{ 0x00c8, 0x00, {0x60,0x30,0x18,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},
{ 0x00c9, 0x00, {0x18,0x30,0x60,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},
{ 0x00ca, 0x00, {0x10,0x38,0x6C,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},
{ 0x00cb, 0x00, {0xCC,0xCC,0x00,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},
{ 0x00cc, 0x00, {0x60,0x30,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00cd, 0x00, {0x18,0x30,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00ce, 0x00, {0x10,0x38,0x6C,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00cf, 0x00, {0xCC,0xCC,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00d0, 0x00, {0x00,0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0xF6,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00}},
{ 0x00d1, 0x00, {0x76,0xDC,0x00,0x00,0xC6,0xE6,0xE6,0xF6,0xF6,0xDE,0xDE,0xCE,0xCE,0xC6,0xC6,0x00,0x00,0x00,0x00}},
{ 0x00d2, 0x00, {0x60,0x30,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00d3, 0x00, {0x18,0x30,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00d4, 0x00, {0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00d5, 0x00, {0x76,0xDC,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00d6, 0x00, {0xCC,0xCC,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00d7, 0x00, {0x10,0x28,0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x6C,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00}},
{ 0x00d8, 0x00, {0x00,0x00,0x00,0x7C,0xCE,0xCE,0xDE,0xD6,0xD6,0xD6,0xD6,0xF6,0xE6,0xE6,0x7C,0x40,0x00,0x00,0x00}},
{ 0x00d9, 0x00, {0x60,0x30,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00da, 0x00, {0x18,0x30,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00db, 0x00, {0x10,0x38,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00dc, 0x00, {0xCC,0xCC,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00dd, 0x00, {0x18,0x30,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00de, 0x00, {0x00,0x00,0x10,0x00,0xF0,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00,0x00,0x00}},
{ 0x00df, 0x00, {0x00,0x00,0x00,0x78,0xCC,0xCC,0xCC,0xCC,0xD8,0xCC,0xC6,0xC6,0xC6,0xC6,0xCC,0x00,0x00,0x00,0x00}},
{ 0x00e0, 0x00, {0x00,0x30,0x30,0x60,0x30,0x18,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00e1, 0x00, {0x00,0x00,0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00e2, 0x00, {0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00e3, 0x00, {0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00e4, 0x00, {0x00,0x00,0x00,0xCC,0xCC,0x00,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00e5, 0x00, {0x00,0x00,0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00e6, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEC,0x36,0x36,0x7E,0xD8,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00}},
{ 0x00e7, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC0,0xC6,0x7C,0x18,0x70,0x00,0x00}},
{ 0x00e8, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00e9, 0x00, {0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00ea, 0x00, {0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00eb, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00ec, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00ed, 0x00, {0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00ee, 0x00, {0x00,0x00,0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00ef, 0x00, {0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00f0, 0x00, {0x00,0x00,0x00,0x34,0x18,0x2C,0x0C,0x06,0x3E,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00}},
{ 0x00f1, 0x00, {0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00}},
{ 0x00f2, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00f3, 0x00, {0x00,0x00,0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00f4, 0x00, {0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00f5, 0x00, {0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00f6, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00f7, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x00f8, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xCE,0xDE,0xD6,0xF6,0xE6,0xC6,0x7C,0x00,0x00,0x00,0x00}},
{ 0x00f9, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00fa, 0x00, {0x00,0x00,0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00fb, 0x00, {0x00,0x00,0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00fc, 0x00, {0x00,0x00,0x00,0xCC,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},
{ 0x00fd, 0x00, {0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00}},
{ 0x00fe, 0x00, {0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00}},
{ 0x00ff, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00}},
{ (CHAR16)BOXDRAW_HORIZONTAL, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_VERTICAL, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_DOWN_RIGHT, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_DOWN_LEFT, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_UP_RIGHT, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_UP_LEFT, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_VERTICAL_RIGHT, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_VERTICAL_LEFT, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_DOWN_HORIZONTAL, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_UP_HORIZONTAL, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_VERTICAL_HORIZONTAL, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_DOUBLE_HORIZONTAL, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_DOUBLE_VERTICAL, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOWN_RIGHT_DOUBLE, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_DOWN_DOUBLE_RIGHT, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOUBLE_DOWN_RIGHT, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOWN_LEFT_DOUBLE, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_DOWN_DOUBLE_LEFT, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOUBLE_DOWN_LEFT, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_UP_RIGHT_DOUBLE, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_UP_DOUBLE_RIGHT, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_DOUBLE_UP_RIGHT, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_UP_LEFT_DOUBLE, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_UP_DOUBLE_LEFT, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_DOUBLE_UP_LEFT, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_VERTICAL_LEFT_DOUBLE, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_VERTICAL_DOUBLE_LEFT, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOUBLE_VERTICAL_LEFT, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_UP_HORIZONTAL_DOUBLE, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_UP_DOUBLE_HORIZONTAL, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_DOUBLE_UP_HORIZONTAL, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
{ (CHAR16)BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
{ (CHAR16)BLOCKELEMENT_FULL_BLOCK, 0x00, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
{ (CHAR16)BLOCKELEMENT_LIGHT_SHADE, 0x00, {0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22}},
{ (CHAR16)GEOMETRICSHAPE_RIGHT_TRIANGLE, 0x00, {0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)GEOMETRICSHAPE_LEFT_TRIANGLE, 0x00, {0x00,0x00,0x00,0x00,0x00,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)GEOMETRICSHAPE_UP_TRIANGLE, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)GEOMETRICSHAPE_DOWN_TRIANGLE, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)ARROW_UP, 0x00, {0x00,0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)ARROW_DOWN, 0x00, {0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)ARROW_LEFT, 0x00, {0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x60,0xFE,0xFE,0x60,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00}},
{ (CHAR16)ARROW_RIGHT, 0x00, {0x00,0x00,0x00,0x00,0x00,0x08,0x0C,0x0C,0xFE,0xFE,0x0C,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00}},
{ 0x0000, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} //EOL
};
UINTN
ReturnNarrowFontSize (
VOID
)
{
//
// I need the size of this outside of this file, so here is a stub function to do that for me
//
return sizeof (UsStdNarrowGlyphData);
}

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="GraphicsConsole"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Console\GraphicsConsole\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="GraphicsConsole">
<GenBuild baseName="GraphicsConsole" mbdFilename="${MODULE_DIR}\GraphicsConsole.mbd" msaFilename="${MODULE_DIR}\GraphicsConsole.msa"/>
</target>
<target depends="GraphicsConsole_clean" name="clean"/>
<target depends="GraphicsConsole_cleanall" name="cleanall"/>
<target name="GraphicsConsole_clean">
<OutputDirSetup baseName="GraphicsConsole" mbdFilename="${MODULE_DIR}\GraphicsConsole.mbd" msaFilename="${MODULE_DIR}\GraphicsConsole.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\GraphicsConsole_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\GraphicsConsole_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="GraphicsConsole_cleanall">
<OutputDirSetup baseName="GraphicsConsole" mbdFilename="${MODULE_DIR}\GraphicsConsole.mbd" msaFilename="${MODULE_DIR}\GraphicsConsole.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\GraphicsConsole_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\GraphicsConsole_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**GraphicsConsole*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,194 @@
/*++
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 "Terminal.h"
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
TerminalComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
TerminalComponentNameGetControllerName (
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 gTerminalComponentName = {
TerminalComponentNameGetDriverName,
TerminalComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mTerminalDriverNameTable[] = {
{
"eng",
(CHAR16 *) L"Serial Terminal Driver"
},
{
NULL,
NULL
}
};
EFI_STATUS
EFIAPI
TerminalComponentNameGetDriverName (
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,
gTerminalComponentName.SupportedLanguages,
mTerminalDriverNameTable,
DriverName
);
}
EFI_STATUS
EFIAPI
TerminalComponentNameGetControllerName (
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 *SimpleTextOutput;
TERMINAL_DEV *TerminalDevice;
//
// 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,
&gEfiSimpleTextOutProtocolGuid,
(VOID **) &SimpleTextOutput,
gTerminalDriverBinding.DriverBindingHandle,
ChildHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
return LookupUnicodeString (
Language,
gTerminalComponentName.SupportedLanguages,
TerminalDevice->ControllerNameTable,
ControllerName
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,506 @@
/*++
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:
terminal.h
Abstract:
Revision History
--*/
#ifndef _TERMINAL_H
#define _TERMINAL_H
#define RAW_FIFO_MAX_NUMBER 256
#define FIFO_MAX_NUMBER 128
typedef struct {
UINT8 Head;
UINT8 Tail;
UINT8 Data[RAW_FIFO_MAX_NUMBER + 1];
} RAW_DATA_FIFO;
typedef struct {
UINT8 Head;
UINT8 Tail;
UINT16 Data[FIFO_MAX_NUMBER + 1];
} UNICODE_FIFO;
typedef struct {
UINT8 Head;
UINT8 Tail;
EFI_INPUT_KEY Data[FIFO_MAX_NUMBER + 1];
} EFI_KEY_FIFO;
#define TERMINAL_DEV_SIGNATURE EFI_SIGNATURE_32 ('t', 'm', 'n', 'l')
typedef struct {
UINTN Signature;
EFI_HANDLE Handle;
UINT8 TerminalType;
EFI_SERIAL_IO_PROTOCOL *SerialIo;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
VENDOR_DEVICE_PATH Node;
EFI_SIMPLE_TEXT_IN_PROTOCOL SimpleInput;
EFI_SIMPLE_TEXT_OUT_PROTOCOL SimpleTextOutput;
EFI_SIMPLE_TEXT_OUTPUT_MODE SimpleTextOutputMode;
UINTN SerialInTimeOut;
RAW_DATA_FIFO RawFiFo;
UNICODE_FIFO UnicodeFiFo;
EFI_KEY_FIFO EfiKeyFiFo;
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
EFI_EVENT TwoSecondTimeOut;
UINT32 InputState;
UINT32 ResetState;
//
// Esc could not be output to the screen by user,
// but the terminal driver need to output it to
// the terminal emulation software to send control sequence.
// This boolean is used by the terminal driver only
// to indicate whether the Esc could be sent or not.
//
BOOLEAN OutputEscChar;
} TERMINAL_DEV;
#define INPUT_STATE_DEFAULT 0x00
#define INPUT_STATE_ESC 0x01
#define INPUT_STATE_CSI 0x02
#define INPUT_STATE_LEFTOPENBRACKET 0x04
#define INPUT_STATE_O 0x08
#define INPUT_STATE_2 0x10
#define RESET_STATE_DEFAULT 0x00
#define RESET_STATE_ESC_R 0x01
#define RESET_STATE_ESC_R_ESC_r 0x02
#define TERMINAL_CON_IN_DEV_FROM_THIS(a) CR (a, TERMINAL_DEV, SimpleInput, TERMINAL_DEV_SIGNATURE)
#define TERMINAL_CON_OUT_DEV_FROM_THIS(a) CR (a, TERMINAL_DEV, SimpleTextOutput, TERMINAL_DEV_SIGNATURE)
typedef union {
UINT8 Utf8_1;
UINT8 Utf8_2[2];
UINT8 Utf8_3[3];
} UTF8_CHAR;
#define PcAnsiType 0
#define VT100Type 1
#define VT100PlusType 2
#define VTUTF8Type 3
#define LEFTOPENBRACKET 0x5b // '['
#define ACAP 0x41
#define BCAP 0x42
#define CCAP 0x43
#define DCAP 0x44
#define MODE0_COLUMN_COUNT 80
#define MODE0_ROW_COUNT 25
#define BACKSPACE 8
#define ESC 27
#define CSI 0x9B
#define DEL 127
#define BRIGHT_CONTROL_OFFSET 2
#define FOREGROUND_CONTROL_OFFSET 6
#define BACKGROUND_CONTROL_OFFSET 11
#define ROW_OFFSET 2
#define COLUMN_OFFSET 5
typedef struct {
UINT16 Unicode;
CHAR8 PcAnsi;
CHAR8 Ascii;
} UNICODE_TO_CHAR;
#define VarConsoleInpDev L"ConInDev"
#define VarConsoleOutDev L"ConOutDev"
#define VarErrorOutDev L"ErrOutDev"
//
// Global Variables
//
extern EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gTerminalComponentName;
//
// Prototypes
//
EFI_STATUS
EFIAPI
InitializeTerminal (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
;
EFI_STATUS
EFIAPI
TerminalConInReset (
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
;
EFI_STATUS
EFIAPI
TerminalConInReadKeyStroke (
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
)
;
VOID
EFIAPI
TerminalConInWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
)
;
EFI_STATUS
EFIAPI
TerminalConOutReset (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
;
EFI_STATUS
EFIAPI
TerminalConOutOutputString (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *WString
)
;
EFI_STATUS
EFIAPI
TerminalConOutTestString (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *WString
)
;
EFI_STATUS
EFIAPI
TerminalConOutQueryMode (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber,
OUT UINTN *Columns,
OUT UINTN *Rows
)
;
EFI_STATUS
EFIAPI
TerminalConOutSetMode (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber
)
;
EFI_STATUS
EFIAPI
TerminalConOutSetAttribute (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Attribute
)
;
EFI_STATUS
EFIAPI
TerminalConOutClearScreen (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
)
;
EFI_STATUS
EFIAPI
TerminalConOutSetCursorPosition (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Column,
IN UINTN Row
)
;
EFI_STATUS
EFIAPI
TerminalConOutEnableCursor (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN Visible
)
;
//
// internal functions
//
EFI_STATUS
TerminalConInCheckForKey (
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This
)
;
VOID
TerminalUpdateConsoleDevVariable (
IN CHAR16 *VariableName,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath
)
;
VOID
TerminalRemoveConsoleDevVariable (
IN CHAR16 *VariableName,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath
)
;
VOID *
TerminalGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
)
;
EFI_STATUS
SetTerminalDevicePath (
IN UINT8 TerminalType,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
OUT EFI_DEVICE_PATH_PROTOCOL **TerminalDevicePath
)
;
VOID
InitializeRawFiFo (
IN TERMINAL_DEV *TerminalDevice
)
;
VOID
InitializeUnicodeFiFo (
IN TERMINAL_DEV *TerminalDevice
)
;
VOID
InitializeEfiKeyFiFo (
IN TERMINAL_DEV *TerminalDevice
)
;
EFI_STATUS
GetOneKeyFromSerial (
EFI_SERIAL_IO_PROTOCOL *SerialIo,
UINT8 *Input
)
;
BOOLEAN
RawFiFoInsertOneKey (
TERMINAL_DEV *TerminalDevice,
UINT8 Input
)
;
BOOLEAN
RawFiFoRemoveOneKey (
TERMINAL_DEV *TerminalDevice,
UINT8 *Output
)
;
BOOLEAN
IsRawFiFoEmpty (
TERMINAL_DEV *TerminalDevice
)
;
BOOLEAN
IsRawFiFoFull (
TERMINAL_DEV *TerminalDevice
)
;
BOOLEAN
EfiKeyFiFoInsertOneKey (
TERMINAL_DEV *TerminalDevice,
EFI_INPUT_KEY Key
)
;
BOOLEAN
EfiKeyFiFoRemoveOneKey (
TERMINAL_DEV *TerminalDevice,
EFI_INPUT_KEY *Output
)
;
BOOLEAN
IsEfiKeyFiFoEmpty (
TERMINAL_DEV *TerminalDevice
)
;
BOOLEAN
IsEfiKeyFiFoFull (
TERMINAL_DEV *TerminalDevice
)
;
BOOLEAN
UnicodeFiFoInsertOneKey (
TERMINAL_DEV *TerminalDevice,
UINT16 Input
)
;
BOOLEAN
UnicodeFiFoRemoveOneKey (
TERMINAL_DEV *TerminalDevice,
UINT16 *Output
)
;
BOOLEAN
IsUnicodeFiFoEmpty (
TERMINAL_DEV *TerminalDevice
)
;
BOOLEAN
IsUnicodeFiFoFull (
TERMINAL_DEV *TerminalDevice
)
;
UINT8
UnicodeFiFoGetKeyCount (
TERMINAL_DEV *TerminalDevice
)
;
VOID
TranslateRawDataToEfiKey (
IN TERMINAL_DEV *TerminalDevice
)
;
//
// internal functions for PC ANSI
//
VOID
AnsiRawDataToUnicode (
IN TERMINAL_DEV *PcAnsiDevice
)
;
VOID
UnicodeToEfiKey (
IN TERMINAL_DEV *PcAnsiDevice
)
;
EFI_STATUS
AnsiTestString (
IN TERMINAL_DEV *TerminalDevice,
IN CHAR16 *WString
)
;
//
// internal functions for VT100
//
EFI_STATUS
VT100TestString (
IN TERMINAL_DEV *VT100Device,
IN CHAR16 *WString
)
;
//
// internal functions for VT100Plus
//
EFI_STATUS
VT100PlusTestString (
IN TERMINAL_DEV *TerminalDevice,
IN CHAR16 *WString
)
;
//
// internal functions for VTUTF8
//
VOID
VTUTF8RawDataToUnicode (
IN TERMINAL_DEV *VtUtf8Device
)
;
EFI_STATUS
VTUTF8TestString (
IN TERMINAL_DEV *TerminalDevice,
IN CHAR16 *WString
)
;
VOID
UnicodeToUtf8 (
IN CHAR16 Unicode,
OUT UTF8_CHAR *Utf8Char,
OUT UINT8 *ValidBytes
)
;
VOID
GetOneValidUtf8Char (
IN TERMINAL_DEV *Utf8Device,
OUT UTF8_CHAR *Utf8Char,
OUT UINT8 *ValidBytes
)
;
VOID
Utf8ToUnicode (
IN UTF8_CHAR Utf8Char,
IN UINT8 ValidBytes,
OUT CHAR16 *UnicodeChar
)
;
//
// functions for boxdraw unicode
//
BOOLEAN
TerminalIsValidTextGraphics (
IN CHAR16 Graphic,
OUT CHAR8 *PcAnsi, OPTIONAL
OUT CHAR8 *Ascii OPTIONAL
)
;
BOOLEAN
TerminalIsValidAscii (
IN CHAR16 Ascii
)
;
BOOLEAN
TerminalIsValidEfiCntlChar (
IN CHAR16 CharC
)
;
#endif

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>Terminal</BaseName>
<Guid>9E863906-A40F-4875-977F-5B93FF237FC6</Guid>
<Version>EDK_RELEASE_VERSION 0x00020000</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-22 19:05</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>UefiRuntimeServicesTableLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>UefiDriverModelLib</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>EdkDxePrintLib</Library>
<Library>BaseLib</Library>
<Library>DxeMemoryAllocationLib</Library>
<Library>UefiDevicePathLib</Library>
</Libraries>
</ModuleBuildDescription>

View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>Terminal</BaseName>
<ModuleType>DXE_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>9E863906-A40F-4875-977F-5B93FF237FC6</Guid>
<Version>EDK_RELEASE_VERSION 0x00020000</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>EFI_SPECIFICATION_VERSION 0x00000000</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-22 19:05</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>Terminal.h</Filename>
<Filename>Terminal.c</Filename>
<Filename>TerminalConIn.c</Filename>
<Filename>TerminalConOut.c</Filename>
<Filename>ansi.c</Filename>
<Filename>vtutf8.c</Filename>
<Filename>ComponentName.c</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
<PackageName>EdkModulePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="BY_START">SimpleTextOut</Protocol>
<Protocol Usage="BY_START">SimpleTextIn</Protocol>
<Protocol Usage="TO_START">DevicePath</Protocol>
<Protocol Usage="TO_START">SerialIo</Protocol>
</Protocols>
<Variables>
<Variable Usage="SOMETIMES_CONSUMED">
<String>ConInDev</String>
<Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>
</Variable>
<Variable Usage="SOMETIMES_CONSUMED">
<String>ConOutDev</String>
<Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>
</Variable>
<Variable Usage="SOMETIMES_CONSUMED">
<String>ErrOutDev</String>
<Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>
</Variable>
</Variables>
<Guids>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>HotPlugDevice</C_Name>
</GuidEntry>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>GlobalVariable</C_Name>
</GuidEntry>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>PcAnsi</C_Name>
</GuidEntry>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>VT100Plus</C_Name>
</GuidEntry>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>VT100</C_Name>
</GuidEntry>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>VTUTF8</C_Name>
</GuidEntry>
</Guids>
<Externs>
<Extern>
<ModuleEntryPoint></ModuleEntryPoint>
</Extern>
<Extern>
<DriverBinding>gTerminalDriverBinding</DriverBinding>
<ComponentName>gTerminalComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,997 @@
/*++
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:
TerminalConOut.c
Abstract:
Revision History
--*/
#include "Terminal.h"
#include <Common/StatusCode.h>
//
// This list is used to define the valid extend chars.
// It also provides a mapping from Unicode to PCANSI or
// ASCII. The ASCII mapping we just made up.
//
//
STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {
{ BOXDRAW_HORIZONTAL, 0xc4, L'-' },
{ BOXDRAW_VERTICAL, 0xb3, L'|' },
{ BOXDRAW_DOWN_RIGHT, 0xda, L'/' },
{ BOXDRAW_DOWN_LEFT, 0xbf, L'\\' },
{ BOXDRAW_UP_RIGHT, 0xc0, L'\\' },
{ BOXDRAW_UP_LEFT, 0xd9, L'/' },
{ BOXDRAW_VERTICAL_RIGHT, 0xc3, L'|' },
{ BOXDRAW_VERTICAL_LEFT, 0xb4, L'|' },
{ BOXDRAW_DOWN_HORIZONTAL, 0xc2, L'+' },
{ BOXDRAW_UP_HORIZONTAL, 0xc1, L'+' },
{ BOXDRAW_VERTICAL_HORIZONTAL, 0xc5, L'+' },
{ BOXDRAW_DOUBLE_HORIZONTAL, 0xcd, L'-' },
{ BOXDRAW_DOUBLE_VERTICAL, 0xba, L'|' },
{ BOXDRAW_DOWN_RIGHT_DOUBLE, 0xd5, L'/' },
{ BOXDRAW_DOWN_DOUBLE_RIGHT, 0xd6, L'/' },
{ BOXDRAW_DOUBLE_DOWN_RIGHT, 0xc9, L'/' },
{ BOXDRAW_DOWN_LEFT_DOUBLE, 0xb8, L'\\' },
{ BOXDRAW_DOWN_DOUBLE_LEFT, 0xb7, L'\\' },
{ BOXDRAW_DOUBLE_DOWN_LEFT, 0xbb, L'\\' },
{ BOXDRAW_UP_RIGHT_DOUBLE, 0xd4, L'\\' },
{ BOXDRAW_UP_DOUBLE_RIGHT, 0xd3, L'\\' },
{ BOXDRAW_DOUBLE_UP_RIGHT, 0xc8, L'\\' },
{ BOXDRAW_UP_LEFT_DOUBLE, 0xbe, L'/' },
{ BOXDRAW_UP_DOUBLE_LEFT, 0xbd, L'/' },
{ BOXDRAW_DOUBLE_UP_LEFT, 0xbc, L'/' },
{ BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0xc6, L'|' },
{ BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0xc7, L'|' },
{ BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0xcc, L'|' },
{ BOXDRAW_VERTICAL_LEFT_DOUBLE, 0xb5, L'|' },
{ BOXDRAW_VERTICAL_DOUBLE_LEFT, 0xb6, L'|' },
{ BOXDRAW_DOUBLE_VERTICAL_LEFT, 0xb9, L'|' },
{ BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0xd1, L'+' },
{ BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0xd2, L'+' },
{ BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0xcb, L'+' },
{ BOXDRAW_UP_HORIZONTAL_DOUBLE, 0xcf, L'+' },
{ BOXDRAW_UP_DOUBLE_HORIZONTAL, 0xd0, L'+' },
{ BOXDRAW_DOUBLE_UP_HORIZONTAL, 0xca, L'+' },
{ BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+' },
{ BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+' },
{ BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+' },
{ BLOCKELEMENT_FULL_BLOCK, 0xdb, L'*' },
{ BLOCKELEMENT_LIGHT_SHADE, 0xb0, L'+' },
{ GEOMETRICSHAPE_UP_TRIANGLE, 0x1e, L'^' },
{ GEOMETRICSHAPE_RIGHT_TRIANGLE, 0x10, L'>' },
{ GEOMETRICSHAPE_DOWN_TRIANGLE, 0x1f, L'v' },
{ GEOMETRICSHAPE_LEFT_TRIANGLE, 0x11, L'<' },
{ ARROW_LEFT, 0x3c, L'<' },
{ ARROW_UP, 0x18, L'^' },
{ ARROW_RIGHT, 0x3e, L'>' },
{ ARROW_DOWN, 0x19, L'v' },
{ 0x0000, 0x00, L'\0' }
};
CHAR16 mSetModeString[] = { ESC, '[', '=', '3', 'h', 0 };
CHAR16 mSetAttributeString[] = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 };
CHAR16 mClearScreenString[] = { ESC, '[', '2', 'J', 0 };
CHAR16 mSetCursorPositionString[] = { ESC, '[', '0', '0', ';', '0', '0', 'H', 0 };
//
// Body of the ConOut functions
//
EFI_STATUS
EFIAPI
TerminalConOutReset (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.Reset().
If ExtendeVerification is TRUE, then perform dependent serial device reset,
and set display mode to mode 0.
If ExtendedVerification is FALSE, only set display mode to mode 0.
Arguments:
This - Indicates the calling context.
ExtendedVerification - Indicates that the driver may perform a more exhaustive
verification operation of the device during reset.
Returns:
EFI_SUCCESS
The reset operation succeeds.
EFI_DEVICE_ERROR
The terminal is not functioning correctly or the serial port reset fails.
--*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
//
// Perform a more exhaustive reset by resetting the serial port.
//
if (ExtendedVerification) {
//
// Report progress code here
//
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET,
TerminalDevice->DevicePath
);
Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);
if (EFI_ERROR (Status)) {
//
// Report error code here
//
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_ERROR_CODE | EFI_ERROR_MINOR,
EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,
TerminalDevice->DevicePath
);
return Status;
}
}
This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
Status = This->SetMode (This, 0);
return Status;
}
EFI_STATUS
EFIAPI
TerminalConOutOutputString (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *WString
)
/*++
Routine Description:
Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.OutputString().
The Unicode string will be converted to terminal expressible data stream
and send to terminal via serial port.
Arguments:
This - Indicates the calling context.
WString - The Null-terminated Unicode string to be displayed on
the terminal screen.
Returns:
EFI_SUCCESS
The string is output successfully.
EFI_DEVICE_ERROR
The serial port fails to send the string out.
EFI_WARN_UNKNOWN_GLYPH
Indicates that some of the characters in the Unicode string could not
be rendered and are skipped.
EFI_UNSUPPORTED
--*/
{
TERMINAL_DEV *TerminalDevice;
EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
UINTN MaxColumn;
UINTN MaxRow;
UINTN Length;
UTF8_CHAR Utf8Char;
CHAR8 GraphicChar;
CHAR8 AsciiChar;
EFI_STATUS Status;
UINT8 ValidBytes;
//
// flag used to indicate whether condition happens which will cause
// return EFI_WARN_UNKNOWN_GLYPH
//
BOOLEAN Warning;
ValidBytes = 0;
Warning = FALSE;
//
// get Terminal device data structure pointer.
//
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
//
// get current display mode
// Terminal driver only support mode 0
//
Mode = This->Mode;
if (Mode->Mode != 0) {
return EFI_UNSUPPORTED;
}
This->QueryMode (
This,
Mode->Mode,
&MaxColumn,
&MaxRow
);
for (; *WString != CHAR_NULL; WString++) {
switch (TerminalDevice->TerminalType) {
case PcAnsiType:
case VT100Type:
case VT100PlusType:
if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {
//
// If it's not a graphic character convert Unicode to ASCII.
//
GraphicChar = (CHAR8) *WString;
if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {
//
// when this driver use the OutputString to output control string,
// TerminalDevice->OutputEscChar is set to let the Esc char
// to be output to the terminal emulation software.
//
if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {
GraphicChar = 27;
} else {
GraphicChar = '?';
Warning = TRUE;
}
}
AsciiChar = GraphicChar;
}
if (TerminalDevice->TerminalType != PcAnsiType) {
GraphicChar = AsciiChar;
}
Length = 1;
Status = TerminalDevice->SerialIo->Write (
TerminalDevice->SerialIo,
&Length,
&GraphicChar
);
if (EFI_ERROR (Status)) {
goto OutputError;
}
break;
case VTUTF8Type:
UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);
Length = ValidBytes;
Status = TerminalDevice->SerialIo->Write (
TerminalDevice->SerialIo,
&Length,
(UINT8 *) &Utf8Char
);
if (EFI_ERROR (Status)) {
goto OutputError;
}
break;
}
//
// Update cursor position.
//
switch (*WString) {
case CHAR_BACKSPACE:
if (Mode->CursorColumn > 0) {
Mode->CursorColumn--;
}
break;
case CHAR_LINEFEED:
if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
Mode->CursorRow++;
}
break;
case CHAR_CARRIAGE_RETURN:
Mode->CursorColumn = 0;
break;
default:
if (Mode->CursorColumn < (INT32) (MaxColumn - 1)) {
Mode->CursorColumn++;
} else {
Mode->CursorColumn = 0;
if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
Mode->CursorRow++;
}
}
break;
};
}
if (Warning) {
return EFI_WARN_UNKNOWN_GLYPH;
}
return EFI_SUCCESS;
OutputError:
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_ERROR_CODE | EFI_ERROR_MINOR,
EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_OUTPUT_ERROR,
TerminalDevice->DevicePath
);
return EFI_DEVICE_ERROR;
}
EFI_STATUS
EFIAPI
TerminalConOutTestString (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *WString
)
/*++
Routine Description:
Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.TestString().
If one of the characters in the *Wstring is
neither valid Unicode drawing characters,
not ASCII code, then this function will return
EFI_UNSUPPORTED.
Arguments:
This - Indicates the calling context.
WString - The Null-terminated Unicode string to be tested.
Returns:
EFI_SUCCESS
The terminal is capable of rendering the output string.
EFI_UNSUPPORTED
Some of the characters in the Unicode string cannot be rendered.
--*/
{
TERMINAL_DEV *TerminalDevice;
EFI_STATUS Status;
//
// get Terminal device data structure pointer.
//
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
switch (TerminalDevice->TerminalType) {
case PcAnsiType:
case VT100Type:
case VT100PlusType:
Status = AnsiTestString (TerminalDevice, WString);
break;
case VTUTF8Type:
Status = VTUTF8TestString (TerminalDevice, WString);
break;
default:
Status = EFI_UNSUPPORTED;
break;
}
return Status;
}
EFI_STATUS
EFIAPI
TerminalConOutQueryMode (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber,
OUT UINTN *Columns,
OUT UINTN *Rows
)
/*++
Routine Description:
Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.QueryMode().
It returns information for an available text mode
that the terminal supports.
In this driver, we only support text mode 80x25, which is
defined as mode 0.
Arguments:
*This
Indicates the calling context.
ModeNumber
The mode number to return information on.
Columns
The returned columns of the requested mode.
Rows
The returned rows of the requested mode.
Returns:
EFI_SUCCESS
The requested mode information is returned.
EFI_UNSUPPORTED
The mode number is not valid.
EFI_DEVICE_ERROR
--*/
{
if (This->Mode->MaxMode > 1) {
return EFI_DEVICE_ERROR;
}
if (ModeNumber == 0) {
*Columns = MODE0_COLUMN_COUNT;
*Rows = MODE0_ROW_COUNT;
return EFI_SUCCESS;
}
return EFI_UNSUPPORTED;
}
EFI_STATUS
EFIAPI
TerminalConOutSetMode (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber
)
/*++
Routine Description:
Implements EFI_SIMPLE_TEXT_OUT.SetMode().
Set the terminal to a specified display mode.
In this driver, we only support mode 0.
Arguments:
This
Indicates the calling context.
ModeNumber
The text mode to set.
Returns:
EFI_SUCCESS
The requested text mode is set.
EFI_DEVICE_ERROR
The requested text mode cannot be set because of serial device error.
EFI_UNSUPPORTED
The text mode number is not valid.
--*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
//
// get Terminal device data structure pointer.
//
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
if (ModeNumber != 0) {
return EFI_UNSUPPORTED;
}
This->Mode->Mode = 0;
This->ClearScreen (This);
TerminalDevice->OutputEscChar = TRUE;
Status = This->OutputString (This, mSetModeString);
TerminalDevice->OutputEscChar = FALSE;
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
This->Mode->Mode = 0;
Status = This->ClearScreen (This);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
TerminalConOutSetAttribute (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Attribute
)
/*++
Routine Description:
Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.SetAttribute().
Arguments:
This
Indicates the calling context.
Attribute
The attribute to set. Only bit0..6 are valid, all other bits
are undefined and must be zero.
Returns:
EFI_SUCCESS
The requested attribute is set.
EFI_DEVICE_ERROR
The requested attribute cannot be set due to serial port error.
EFI_UNSUPPORTED
The attribute requested is not defined by EFI spec.
--*/
{
UINT8 ForegroundControl;
UINT8 BackgroundControl;
UINT8 BrightControl;
INT32 SavedColumn;
INT32 SavedRow;
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
SavedColumn = 0;
SavedRow = 0;
//
// get Terminal device data structure pointer.
//
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
//
// only the bit0..6 of the Attribute is valid
//
if ((Attribute | 0x7f) != 0x7f) {
return EFI_UNSUPPORTED;
}
//
// convert Attribute value to terminal emulator
// understandable foreground color
//
switch (Attribute & 0x07) {
case EFI_BLACK:
ForegroundControl = 30;
break;
case EFI_BLUE:
ForegroundControl = 34;
break;
case EFI_GREEN:
ForegroundControl = 32;
break;
case EFI_CYAN:
ForegroundControl = 36;
break;
case EFI_RED:
ForegroundControl = 31;
break;
case EFI_MAGENTA:
ForegroundControl = 35;
break;
case EFI_BROWN:
ForegroundControl = 33;
break;
default:
case EFI_LIGHTGRAY:
ForegroundControl = 37;
break;
}
//
// bit4 of the Attribute indicates bright control
// of terminal emulator.
//
BrightControl = (UINT8) ((Attribute >> 3) & 1);
//
// convert Attribute value to terminal emulator
// understandable background color.
//
switch ((Attribute >> 4) & 0x07) {
case EFI_BLACK:
BackgroundControl = 40;
break;
case EFI_BLUE:
BackgroundControl = 44;
break;
case EFI_GREEN:
BackgroundControl = 42;
break;
case EFI_CYAN:
BackgroundControl = 46;
break;
case EFI_RED:
BackgroundControl = 41;
break;
case EFI_MAGENTA:
BackgroundControl = 45;
break;
case EFI_BROWN:
BackgroundControl = 43;
break;
default:
case EFI_LIGHTGRAY:
BackgroundControl = 47;
break;
}
//
// terminal emulator's control sequence to set attributes
//
mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);
mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));
mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));
mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));
mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));
//
// save current column and row
// for future scrolling back use.
//
SavedColumn = This->Mode->CursorColumn;
SavedRow = This->Mode->CursorRow;
TerminalDevice->OutputEscChar = TRUE;
Status = This->OutputString (This, mSetAttributeString);
TerminalDevice->OutputEscChar = FALSE;
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
//
// scroll back to saved cursor position.
//
This->Mode->CursorColumn = SavedColumn;
This->Mode->CursorRow = SavedRow;
This->Mode->Attribute = (INT32) Attribute;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
TerminalConOutClearScreen (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
)
/*++
Routine Description:
Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.ClearScreen().
It clears the ANSI terminal's display to the
currently selected background color.
Arguments:
This
Indicates the calling context.
Returns:
EFI_SUCCESS
The operation completed successfully.
EFI_DEVICE_ERROR
The terminal screen cannot be cleared due to serial port error.
EFI_UNSUPPORTED
The terminal is not in a valid display mode.
--*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
//
// control sequence for clear screen request
//
TerminalDevice->OutputEscChar = TRUE;
Status = This->OutputString (This, mClearScreenString);
TerminalDevice->OutputEscChar = FALSE;
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
Status = This->SetCursorPosition (This, 0, 0);
return Status;
}
EFI_STATUS
EFIAPI
TerminalConOutSetCursorPosition (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Column,
IN UINTN Row
)
/*++
Routine Description:
Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.SetCursorPosition().
Arguments:
This
Indicates the calling context.
Column
The row to set cursor to.
Row
The column to set cursor to.
Returns:
EFI_SUCCESS
The operation completed successfully.
EFI_DEVICE_ERROR
The request fails due to serial port error.
EFI_UNSUPPORTED
The terminal is not in a valid text mode, or the cursor position
is invalid for current mode.
--*/
{
EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
UINTN MaxColumn;
UINTN MaxRow;
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
//
// get current mode
//
Mode = This->Mode;
//
// get geometry of current mode
//
Status = This->QueryMode (
This,
Mode->Mode,
&MaxColumn,
&MaxRow
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
if (Column >= MaxColumn || Row >= MaxRow) {
return EFI_UNSUPPORTED;
}
//
// control sequence to move the cursor
//
mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));
mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));
mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));
mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));
TerminalDevice->OutputEscChar = TRUE;
Status = This->OutputString (This, mSetCursorPositionString);
TerminalDevice->OutputEscChar = FALSE;
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
//
// update current cursor position
// in the Mode data structure.
//
Mode->CursorColumn = (INT32) Column;
Mode->CursorRow = (INT32) Row;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
TerminalConOutEnableCursor (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN Visible
)
/*++
Routine Description:
Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
In this driver, the cursor cannot be hidden.
Arguments:
This
Indicates the calling context.
Visible
If TRUE, the cursor is set to be visible,
If FALSE, the cursor is set to be invisible.
Returns:
EFI_SUCCESS
The request is valid.
EFI_UNSUPPORTED
The terminal does not support cursor hidden.
--*/
{
if (!Visible) {
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
}
BOOLEAN
TerminalIsValidTextGraphics (
IN CHAR16 Graphic,
OUT CHAR8 *PcAnsi, OPTIONAL
OUT CHAR8 *Ascii OPTIONAL
)
/*++
Routine Description:
Detects if a Unicode char is for Box Drawing text graphics.
Arguments:
Graphic - Unicode char to test.
PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.
Ascii - Optional pointer to return ASCII equivalent of Graphic.
Returns:
TRUE if Graphic is a supported Unicode Box Drawing character.
--*/
{
UNICODE_TO_CHAR *Table;
if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
//
// Unicode drawing code charts are all in the 0x25xx range,
// arrows are 0x21xx
//
return FALSE;
}
for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
if (Graphic == Table->Unicode) {
if (PcAnsi != NULL) {
*PcAnsi = Table->PcAnsi;
}
if (Ascii != NULL) {
*Ascii = Table->Ascii;
}
return TRUE;
}
}
return FALSE;
}
BOOLEAN
TerminalIsValidAscii (
IN CHAR16 Ascii
)
{
//
// valid ascii code lies in the extent of 0x20 ~ 0x7f
//
if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
return TRUE;
}
return FALSE;
}
BOOLEAN
TerminalIsValidEfiCntlChar (
IN CHAR16 CharC
)
{
//
// only support four control characters.
//
if (CharC == CHAR_NULL ||
CharC == CHAR_BACKSPACE ||
CharC == CHAR_LINEFEED ||
CharC == CHAR_CARRIAGE_RETURN ||
CharC == CHAR_TAB
) {
return TRUE;
}
return FALSE;
}

View File

@@ -0,0 +1,68 @@
/*++
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:
ansi.c
Abstract:
Revision History
--*/
#include "Terminal.h"
VOID
AnsiRawDataToUnicode (
IN TERMINAL_DEV *TerminalDevice
)
{
UINT8 RawData;
//
// pop the raw data out from the raw fifo,
// and translate it into unicode, then push
// the unicode into unicode fifo, until the raw fifo is empty.
//
while (!IsRawFiFoEmpty (TerminalDevice)) {
RawFiFoRemoveOneKey (TerminalDevice, &RawData);
UnicodeFiFoInsertOneKey (TerminalDevice, (UINT16) RawData);
}
}
EFI_STATUS
AnsiTestString (
IN TERMINAL_DEV *TerminalDevice,
IN CHAR16 *WString
)
{
CHAR8 GraphicChar;
//
// support three kind of character:
// valid ascii, valid efi control char, valid text graphics.
//
for (; *WString != CHAR_NULL; WString++) {
if ( !(TerminalIsValidAscii (*WString) ||
TerminalIsValidEfiCntlChar (*WString) ||
TerminalIsValidTextGraphics (*WString, &GraphicChar, NULL) )) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="Terminal"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Console\Terminal\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="Terminal">
<GenBuild baseName="Terminal" mbdFilename="${MODULE_DIR}\Terminal.mbd" msaFilename="${MODULE_DIR}\Terminal.msa"/>
</target>
<target depends="Terminal_clean" name="clean"/>
<target depends="Terminal_cleanall" name="cleanall"/>
<target name="Terminal_clean">
<OutputDirSetup baseName="Terminal" mbdFilename="${MODULE_DIR}\Terminal.mbd" msaFilename="${MODULE_DIR}\Terminal.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\Terminal_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\Terminal_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="Terminal_cleanall">
<OutputDirSetup baseName="Terminal" mbdFilename="${MODULE_DIR}\Terminal.mbd" msaFilename="${MODULE_DIR}\Terminal.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\Terminal_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\Terminal_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**Terminal*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,270 @@
/*++
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:
vtutf8.c
Abstract:
Revision History
--*/
#include "Terminal.h"
VOID
VTUTF8RawDataToUnicode (
IN TERMINAL_DEV *TerminalDevice
)
{
UTF8_CHAR Utf8Char;
UINT8 ValidBytes;
UINT16 UnicodeChar;
ValidBytes = 0;
//
// pop the raw data out from the raw fifo,
// and translate it into unicode, then push
// the unicode into unicode fifo, until the raw fifo is empty.
//
while (!IsRawFiFoEmpty (TerminalDevice)) {
GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes);
if (ValidBytes < 1 || ValidBytes > 3) {
continue;
}
Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar);
UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar);
}
}
VOID
GetOneValidUtf8Char (
IN TERMINAL_DEV *Utf8Device,
OUT UTF8_CHAR *Utf8Char,
OUT UINT8 *ValidBytes
)
{
UINT8 Temp;
UINT8 Index;
BOOLEAN FetchFlag;
Temp = 0;
Index = 0;
FetchFlag = TRUE;
//
// if no valid Utf8 char is found in the RawFiFo,
// then *ValidBytes will be zero.
//
*ValidBytes = 0;
while (!IsRawFiFoEmpty (Utf8Device)) {
RawFiFoRemoveOneKey (Utf8Device, &Temp);
switch (*ValidBytes) {
case 0:
if ((Temp & 0x80) == 0) {
//
// one-byte utf8 char
//
*ValidBytes = 1;
Utf8Char->Utf8_1 = Temp;
FetchFlag = FALSE;
} else if ((Temp & 0xe0) == 0xc0) {
//
// two-byte utf8 char
//
*ValidBytes = 2;
Utf8Char->Utf8_2[1] = Temp;
} else if ((Temp & 0xf0) == 0xe0) {
//
// three-byte utf8 char
//
*ValidBytes = 3;
Utf8Char->Utf8_3[2] = Temp;
Index++;
} else {
//
// reset *ValidBytes to zero, let valid utf8 char search restart
//
*ValidBytes = 0;
}
break;
case 2:
if ((Temp & 0xc0) == 0x80) {
Utf8Char->Utf8_2[0] = Temp;
FetchFlag = FALSE;
} else {
*ValidBytes = 0;
}
break;
case 3:
if ((Temp & 0xc0) == 0x80) {
Utf8Char->Utf8_3[2 - Index] = Temp;
Index++;
if (Index == 3) {
FetchFlag = FALSE;
}
} else {
*ValidBytes = 0;
Index = 0;
}
break;
default:
break;
}
if (!FetchFlag) {
break;
}
}
return ;
}
VOID
Utf8ToUnicode (
IN UTF8_CHAR Utf8Char,
IN UINT8 ValidBytes,
OUT CHAR16 *UnicodeChar
)
{
UINT8 UnicodeByte0;
UINT8 UnicodeByte1;
UINT8 Byte0;
UINT8 Byte1;
UINT8 Byte2;
*UnicodeChar = 0;
//
// translate utf8 code to unicode, in terminal standard,
// up to 3 bytes utf8 code is supported.
//
switch (ValidBytes) {
case 1:
//
// one-byte utf8 code
//
*UnicodeChar = (UINT16) Utf8Char.Utf8_1;
break;
case 2:
//
// two-byte utf8 code
//
Byte0 = Utf8Char.Utf8_2[0];
Byte1 = Utf8Char.Utf8_2[1];
UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));
UnicodeByte1 = (UINT8) ((Byte1 >> 2) & 0x07);
*UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));
break;
case 3:
//
// three-byte utf8 code
//
Byte0 = Utf8Char.Utf8_3[0];
Byte1 = Utf8Char.Utf8_3[1];
Byte2 = Utf8Char.Utf8_3[2];
UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));
UnicodeByte1 = (UINT8) ((Byte2 << 4) | ((Byte1 >> 2) & 0x0f));
*UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));
default:
break;
}
return ;
}
VOID
UnicodeToUtf8 (
IN CHAR16 Unicode,
OUT UTF8_CHAR *Utf8Char,
OUT UINT8 *ValidBytes
)
{
UINT8 UnicodeByte0;
UINT8 UnicodeByte1;
//
// translate unicode to utf8 code
//
UnicodeByte0 = (UINT8) Unicode;
UnicodeByte1 = (UINT8) (Unicode >> 8);
if (Unicode < 0x0080) {
Utf8Char->Utf8_1 = (UINT8) (UnicodeByte0 & 0x7f);
*ValidBytes = 1;
} else if (Unicode < 0x0800) {
//
// byte sequence: high -> low
// Utf8_2[0], Utf8_2[1]
//
Utf8Char->Utf8_2[1] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);
Utf8Char->Utf8_2[0] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x1f) + 0xc0);
*ValidBytes = 2;
} else {
//
// byte sequence: high -> low
// Utf8_3[0], Utf8_3[1], Utf8_3[2]
//
Utf8Char->Utf8_3[2] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);
Utf8Char->Utf8_3[1] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80);
Utf8Char->Utf8_3[0] = (UINT8) (((UnicodeByte1 >> 4) & 0x0f) + 0xe0);
*ValidBytes = 3;
}
}
EFI_STATUS
VTUTF8TestString (
IN TERMINAL_DEV *TerminalDevice,
IN CHAR16 *WString
)
{
//
// to utf8, all kind of characters are supported.
//
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,655 @@
/*++
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:
DataHub.c
Abstract:
This code produces the Data Hub protocol. It preloads the data hub
with status information copied in from PEI HOBs.
Only code that implements the Data Hub protocol should go in this file!
The Term MTC stands for MonoTonicCounter.
For more information please look at DataHub.doc
NOTE: For extra security of the log GetNextDataRecord () could return a copy
of the data record.
--*/
#include "DataHub.h"
CONST EFI_GUID gZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
//
// Worker functions private to this file
//
STATIC
DATA_HUB_FILTER_DRIVER *
FindFilterDriverByEvent (
IN LIST_ENTRY *Head,
IN EFI_EVENT Event
);
STATIC
EFI_DATA_RECORD_HEADER *
GetNextDataRecord (
IN LIST_ENTRY *Head,
IN UINT64 ClassFilter,
IN OUT UINT64 *PtrCurrentMTC
);
EFI_STATUS
EFIAPI
DataHubLogData (
IN EFI_DATA_HUB_PROTOCOL *This,
IN EFI_GUID *DataRecordGuid,
IN EFI_GUID *ProducerName,
IN UINT64 DataRecordClass,
IN VOID *RawData,
IN UINT32 RawDataSize
)
/*++
Routine Description:
Log data record into the data logging hub
Arguments:
This - Protocol instance structure
DataRecordGuid - GUID that defines record contents
ProducerName - GUID that defines the name of the producer of the data
DataRecordClass - Class that defines generic record type
RawData - Data Log record as defined by DataRecordGuid
RawDataSize - Size of Data Log data in bytes
Returns:
EFI_SUCCESS - If data was logged
EFI_OUT_OF_RESOURCES - If data was not logged due to lack of system
resources.
--*/
{
EFI_STATUS Status;
DATA_HUB_INSTANCE *Private;
EFI_DATA_ENTRY *LogEntry;
UINT32 TotalSize;
UINT32 RecordSize;
EFI_DATA_RECORD_HEADER *Record;
VOID *Raw;
DATA_HUB_FILTER_DRIVER *FilterEntry;
LIST_ENTRY *Link;
LIST_ENTRY *Head;
Private = DATA_HUB_INSTANCE_FROM_THIS (This);
//
// Combine the storage for the internal structs and a copy of the log record.
// Record follows PrivateLogEntry. The consumer will be returned a pointer
// to Record so we don't what it to be the thing that was allocated from
// pool, so the consumer can't free an data record by mistake.
//
RecordSize = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize;
TotalSize = sizeof (EFI_DATA_ENTRY) + RecordSize;
//
// The Logging action is the critical section, so it is locked.
// The MTC asignment & update, time, and logging must be an
// atomic operation, so use the lock.
//
Status = EfiAcquireLockOrFail (&Private->DataLock);
if (EFI_ERROR (Status)) {
//
// Reentrancy detected so exit!
//
return Status;
}
Status = gBS->AllocatePool (EfiBootServicesData, TotalSize, (VOID **) &LogEntry);
if (EFI_ERROR (Status)) {
EfiReleaseLock (&Private->DataLock);
return EFI_OUT_OF_RESOURCES;
}
ZeroMem (LogEntry, TotalSize);
Record = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1);
Raw = (VOID *) (Record + 1);
//
// Build Standard Log Header
//
Record->Version = EFI_DATA_RECORD_HEADER_VERSION;
Record->HeaderSize = sizeof (EFI_DATA_RECORD_HEADER);
Record->RecordSize = RecordSize;
CopyMem (&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID));
CopyMem (&Record->ProducerName, ProducerName, sizeof (EFI_GUID));
Record->DataRecordClass = DataRecordClass;
Record->LogMonotonicCount = Private->GlobalMonotonicCount++;
gRT->GetTime (&Record->LogTime, NULL);
//
// Insert log into the internal linked list.
//
LogEntry->Signature = EFI_DATA_ENTRY_SIGNATURE;
LogEntry->Record = Record;
LogEntry->RecordSize = sizeof (EFI_DATA_ENTRY) + RawDataSize;
InsertTailList (&Private->DataListHead, &LogEntry->Link);
CopyMem (Raw, RawData, RawDataSize);
EfiReleaseLock (&Private->DataLock);
//
// Send Signal to all the filter drivers which are interested
// in the record's class and guid.
//
Head = &Private->FilterDriverListHead;
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
FilterEntry = FILTER_ENTRY_FROM_LINK (Link);
if (((FilterEntry->ClassFilter & DataRecordClass) != 0) &&
(CompareGuid (&FilterEntry->FilterDataRecordGuid, &gZeroGuid) ||
CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) {
gBS->SignalEvent (FilterEntry->Event);
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DataHubGetNextRecord (
IN EFI_DATA_HUB_PROTOCOL *This,
IN OUT UINT64 *MonotonicCount,
IN EFI_EVENT *FilterDriverEvent, OPTIONAL
OUT EFI_DATA_RECORD_HEADER **Record
)
/*++
Routine Description:
Get a previously logged data record and the MonotonicCount for the next
availible Record. This allows all records or all records later
than a give MonotonicCount to be returned. If an optional FilterDriverEvent
is passed in with a MonotonicCout of zero return the first record
not yet read by the filter driver. If FilterDriverEvent is NULL and
MonotonicCount is zero return the first data record.
Arguments:
This - The EFI_DATA_HUB_PROTOCOL instance.
MonotonicCount - Specifies the Record to return. On input, zero means
return the first record. On output, contains the next
record to availible. Zero indicates no more records.
FilterDriverEvent - If FilterDriverEvent is not passed in a MonotonicCount
of zero, it means to return the first data record.
If FilterDriverEvent is passed in, then a MonotonicCount
of zero means to return the first data not yet read by
FilterDriverEvent.
Record - Returns a dynamically allocated memory buffer with a data
record that matches MonotonicCount.
Returns:
EFI_SUCCESS - Data was returned in Record.
EFI_INVALID_PARAMETER - FilterDriverEvent was passed in but does not exist.
EFI_NOT_FOUND - MonotonicCount does not match any data record in the
system. If a MonotonicCount of zero was passed in, then
no data records exist in the system.
EFI_OUT_OF_RESOURCES - Record was not returned due to lack of system resources.
--*/
{
DATA_HUB_INSTANCE *Private;
DATA_HUB_FILTER_DRIVER *FilterDriver;
UINT64 ClassFilter;
UINT64 FilterMonotonicCount;
Private = DATA_HUB_INSTANCE_FROM_THIS (This);
FilterDriver = NULL;
FilterMonotonicCount = 0;
ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |
EFI_DATA_RECORD_CLASS_ERROR |
EFI_DATA_RECORD_CLASS_DATA |
EFI_DATA_RECORD_CLASS_PROGRESS_CODE;
if (FilterDriverEvent != NULL) {
//
// For events the beginning is the last unread record. This info is
// stored in the instance structure, so we must look up the event
// to get the data.
//
FilterDriver = FindFilterDriverByEvent (
&Private->FilterDriverListHead,
*FilterDriverEvent
);
if (FilterDriver == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Use the Class filter the event was created with.
//
ClassFilter = FilterDriver->ClassFilter;
if (*MonotonicCount == 0) {
//
// Use the MTC from the Filter Driver.
//
FilterMonotonicCount = FilterDriver->GetNextMonotonicCount;
if (FilterMonotonicCount != 0) {
//
// The GetNextMonotonicCount field remembers the last value from the previous time.
// But we already processed this vaule, so we need to find the next one. So if
// It is not the first time get the new record entry.
//
*Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, &FilterMonotonicCount);
*MonotonicCount = FilterMonotonicCount;
if (FilterMonotonicCount == 0) {
//
// If there is no new record to get exit now.
//
return EFI_NOT_FOUND;
}
}
}
}
//
// Return the record
//
*Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);
if (*Record == NULL) {
return EFI_NOT_FOUND;
}
if (FilterDriver != NULL) {
//
// If we have a filter driver update the records that have been read.
// If MonotonicCount is zero No more reacords left.
//
if (*MonotonicCount == 0) {
if (FilterMonotonicCount != 0) {
//
// Return the result of our extra GetNextDataRecord.
//
FilterDriver->GetNextMonotonicCount = FilterMonotonicCount;
}
} else {
//
// Point to next undread record
//
FilterDriver->GetNextMonotonicCount = *MonotonicCount;
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DataHubRegisterFilterDriver (
IN EFI_DATA_HUB_PROTOCOL * This,
IN EFI_EVENT FilterEvent,
IN EFI_TPL FilterTpl,
IN UINT64 FilterClass,
IN EFI_GUID * FilterDataRecordGuid OPTIONAL
)
/*++
Routine Description:
This function registers the data hub filter driver that is represented
by FilterEvent. Only one instance of each FilterEvent can be registered.
After the FilterEvent is registered, it will be signaled so it can sync
with data records that have been recorded prior to the FilterEvent being
registered.
Arguments:
This - The EFI_DATA_HUB_PROTOCOL instance.
FilterEvent - The EFI_EVENT to signal whenever data that matches
FilterClass is logged in the system.
FilterTpl - The maximum EFI_TPL at which FilterEvent can be
signaled. It is strongly recommended that you use the
lowest EFI_TPL possible.
FilterClass - FilterEvent will be signaled whenever a bit in
EFI_DATA_RECORD_HEADER.DataRecordClass is also set in
FilterClass. If FilterClass is zero, no class-based
filtering will be performed.
FilterDataRecordGuid - FilterEvent will be signaled whenever FilterDataRecordGuid
matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If
FilterDataRecordGuid is NULL, then no GUID-based filtering
will be performed.
Returns:
EFI_SUCCESS - The filter driver event was registered.
EFI_ALREADY_STARTED - FilterEvent was previously registered and cannot be
registered again.
EFI_OUT_OF_RESOURCES - The filter driver event was not registered due to lack of
system resources.
--*/
{
DATA_HUB_INSTANCE *Private;
DATA_HUB_FILTER_DRIVER *FilterDriver;
Private = DATA_HUB_INSTANCE_FROM_THIS (This);
FilterDriver = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool (sizeof (DATA_HUB_FILTER_DRIVER));
if (FilterDriver == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Initialize filter driver info
//
FilterDriver->Signature = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE;
FilterDriver->Event = FilterEvent;
FilterDriver->Tpl = FilterTpl;
FilterDriver->GetNextMonotonicCount = 0;
if (FilterClass == 0) {
FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |
EFI_DATA_RECORD_CLASS_ERROR |
EFI_DATA_RECORD_CLASS_DATA |
EFI_DATA_RECORD_CLASS_PROGRESS_CODE;
} else {
FilterDriver->ClassFilter = FilterClass;
}
if (FilterDataRecordGuid != NULL) {
CopyMem (&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID));
}
//
// Search for duplicate entries
//
if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) {
gBS->FreePool (FilterDriver);
return EFI_ALREADY_STARTED;
}
//
// Make insertion an atomic operation with the lock.
//
EfiAcquireLock (&Private->DataLock);
InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link);
EfiReleaseLock (&Private->DataLock);
//
// Signal the Filter driver we just loaded so they will recieve all the
// previous history. If we did not signal here we would have to wait until
// the next data was logged to get the history. In a case where no next
// data was logged we would never get synced up.
//
gBS->SignalEvent (FilterEvent);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DataHubUnregisterFilterDriver (
IN EFI_DATA_HUB_PROTOCOL *This,
IN EFI_EVENT FilterEvent
)
/*++
Routine Description:
Remove a Filter Driver, so it no longer gets called when data
information is logged.
Arguments:
This - Protocol instance structure
FilterEvent - Event that represents a filter driver that is to be
Unregistered.
Returns:
EFI_SUCCESS - If FilterEvent was unregistered
EFI_NOT_FOUND - If FilterEvent does not exist
--*/
{
DATA_HUB_INSTANCE *Private;
DATA_HUB_FILTER_DRIVER *FilterDriver;
Private = DATA_HUB_INSTANCE_FROM_THIS (This);
//
// Search for duplicate entries
//
FilterDriver = FindFilterDriverByEvent (
&Private->FilterDriverListHead,
FilterEvent
);
if (FilterDriver == NULL) {
return EFI_NOT_FOUND;
}
//
// Make removal an atomic operation with the lock
//
EfiAcquireLock (&Private->DataLock);
RemoveEntryList (&FilterDriver->Link);
EfiReleaseLock (&Private->DataLock);
return EFI_SUCCESS;
}
//
// STATIC Worker fucntions follow
//
STATIC
DATA_HUB_FILTER_DRIVER *
FindFilterDriverByEvent (
IN LIST_ENTRY *Head,
IN EFI_EVENT Event
)
/*++
Routine Description:
Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that
represents Event and return it.
Arguments:
Head - Head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER
structures.
Event - Event to be search for in the Head list.
Returns:
EFI_DATA_HUB_FILTER_DRIVER - Returned if Event stored in the
Head doubly linked list.
NULL - If Event is not in the list
--*/
{
DATA_HUB_FILTER_DRIVER *FilterEntry;
LIST_ENTRY *Link;
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
FilterEntry = FILTER_ENTRY_FROM_LINK (Link);
if (FilterEntry->Event == Event) {
return FilterEntry;
}
}
return NULL;
}
STATIC
EFI_DATA_RECORD_HEADER *
GetNextDataRecord (
IN LIST_ENTRY *Head,
IN UINT64 ClassFilter,
IN OUT UINT64 *PtrCurrentMTC
)
/*++
Routine Description:
Search the Head doubly linked list for the passed in MTC. Return the
matching element in Head and the MTC on the next entry.
Arguments:
Head - Head of Data Log linked list.
ClassFilter - Only match the MTC if it is in the same Class as the
ClassFilter.
PtrCurrentMTC - On IN contians MTC to search for. On OUT contians next
MTC in the data log list or zero if at end of the list.
Returns:
EFI_DATA_LOG_ENTRY - Return pointer to data log data from Head list.
NULL - If no data record exists.
--*/
{
EFI_DATA_ENTRY *LogEntry;
LIST_ENTRY *Link;
BOOLEAN ReturnFirstEntry;
EFI_DATA_RECORD_HEADER *Record;
EFI_DATA_ENTRY *NextLogEntry;
//
// If MonotonicCount == 0 just return the first one
//
ReturnFirstEntry = (BOOLEAN) (*PtrCurrentMTC == 0);
Record = NULL;
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
LogEntry = DATA_ENTRY_FROM_LINK (Link);
if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) {
//
// Skip any entry that does not have the correct ClassFilter
//
continue;
}
if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) {
//
// Return record to the user
//
Record = LogEntry->Record;
//
// Calculate the next MTC value. If there is no next entry set
// MTC to zero.
//
*PtrCurrentMTC = 0;
for (Link = Link->ForwardLink; Link != Head; Link = Link->ForwardLink) {
NextLogEntry = DATA_ENTRY_FROM_LINK (Link);
if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) {
//
// Return the MTC of the next thing to search for if found
//
*PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount;
break;
}
}
//
// Record found exit loop and return
//
break;
}
}
return Record;
}
//
// Module Global:
// Since this driver will only ever produce one instance of the Logging Hub
// protocol you are not required to dynamically allocate the PrivateData.
//
DATA_HUB_INSTANCE mPrivateData;
EFI_STATUS
EFIAPI
DataHubInstall (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Install Driver to produce Data Hub protocol.
Arguments:
(Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
Returns:
EFI_SUCCESS - Logging Hub protocol installed
Other - No protocol installed, unload driver.
--*/
{
EFI_STATUS Status;
UINT32 HighMontonicCount;
mPrivateData.Signature = DATA_HUB_INSTANCE_SIGNATURE;
mPrivateData.DataHub.LogData = DataHubLogData;
mPrivateData.DataHub.GetNextRecord = DataHubGetNextRecord;
mPrivateData.DataHub.RegisterFilterDriver = DataHubRegisterFilterDriver;
mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver;
//
// Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is
// required by this protocol
//
InitializeListHead (&mPrivateData.DataListHead);
InitializeListHead (&mPrivateData.FilterDriverListHead);
EfiInitializeLock (&mPrivateData.DataLock, EFI_TPL_NOTIFY);
//
// Make sure we get a bigger MTC number on every boot!
//
Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount);
if (EFI_ERROR (Status)) {
//
// if system service fails pick a sane value.
//
mPrivateData.GlobalMonotonicCount = 0;
} else {
mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32);
}
//
// Make a new handle and install the protocol
//
mPrivateData.Handle = NULL;
Status = gBS->InstallProtocolInterface (
&mPrivateData.Handle,
&gEfiDataHubProtocolGuid,
EFI_NATIVE_INTERFACE,
&mPrivateData.DataHub
);
return Status;
}

View File

@@ -0,0 +1,26 @@
/*++
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:
DataHub.dxs
Abstract:
Dependency expression source file.
--*/
#include <AutoGen.h>
#include <DxeDepex.h>
DEPENDENCY_START
TRUE
DEPENDENCY_END

View File

@@ -0,0 +1,122 @@
/*++
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:
DataHub.h
Abstract:
This code supports a the private implementation
of the Data Hub protocol
--*/
#ifndef _DATA_HUB_H_
#define _DATA_HUB_H_
#define DATA_HUB_INSTANCE_SIGNATURE EFI_SIGNATURE_32 ('D', 'H', 'u', 'b')
typedef struct {
UINT32 Signature;
EFI_HANDLE Handle;
//
// Produced protocol(s)
//
EFI_DATA_HUB_PROTOCOL DataHub;
//
// Private Data
//
//
// Updates to GlobalMonotonicCount, LogListHead, and FilterDriverListHead
// must be locked.
//
EFI_LOCK DataLock;
//
// Runing Monotonic Count to use for each error record.
// Increment AFTER use in an error record.
//
UINT64 GlobalMonotonicCount;
//
// List of EFI_DATA_ENTRY structures. This is the data log! The list
// must be in assending order of LogMonotonicCount.
//
LIST_ENTRY DataListHead;
//
// List of EFI_DATA_HUB_FILTER_DRIVER structures. Represents all
// the registered filter drivers.
//
LIST_ENTRY FilterDriverListHead;
} DATA_HUB_INSTANCE;
#define DATA_HUB_INSTANCE_FROM_THIS(this) CR (this, DATA_HUB_INSTANCE, DataHub, DATA_HUB_INSTANCE_SIGNATURE)
//
// Private data structure to contain the data log. One record per
// structure. Head pointer to the list is the Log member of
// EFI_DATA_ENTRY. Record is a copy of the data passed in.
//
#define EFI_DATA_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('D', 'r', 'e', 'c')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
EFI_DATA_RECORD_HEADER *Record;
UINTN RecordSize;
} EFI_DATA_ENTRY;
#define DATA_ENTRY_FROM_LINK(link) CR (link, EFI_DATA_ENTRY, Link, EFI_DATA_ENTRY_SIGNATURE)
//
// Private data to contain the filter driver Event and it's
// associated EFI_TPL.
//
#define EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('D', 'h', 'F', 'd')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
//
// Store Filter Driver Event and Tpl level it can be Signaled at.
//
EFI_EVENT Event;
EFI_TPL Tpl;
//
// Monotonic count on the get next operation for Event.
// Zero indicates get next has not been called for this event yet.
//
UINT64 GetNextMonotonicCount;
//
// Filter driver will register what class filter should be used.
//
UINT64 ClassFilter;
//
// Filter driver will register what record guid filter should be used.
//
EFI_GUID FilterDataRecordGuid;
} DATA_HUB_FILTER_DRIVER;
#define FILTER_ENTRY_FROM_LINK(link) CR (link, DATA_HUB_FILTER_DRIVER, Link, EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE)
#endif

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>DataHub</BaseName>
<Guid>53BCC14F-C24F-434C-B294-8ED2D4CC1860</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>UefiRuntimeServicesTableLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>BaseLib</Library>
<Library>DxeMemoryAllocationLib</Library>
</Libraries>
<BuildOptions ToolChain="MSFT">
<ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
</BuildOptions>
</ModuleBuildDescription>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>DataHub</BaseName>
<ModuleType>DXE_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>53BCC14F-C24F-434C-B294-8ED2D4CC1860</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>DataHub.c</Filename>
<Filename>DataHub.h</Filename>
<Filename>DataHub.dxs</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
<PackageName>EdkModulePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="ALWAYS_PRODUCED">DataHub</Protocol>
</Protocols>
<Externs>
<Extern>
<ModuleEntryPoint>DataHubInstall</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="DataHub"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\DataHub\DataHub\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="DataHub">
<GenBuild baseName="DataHub" mbdFilename="${MODULE_DIR}\DataHub.mbd" msaFilename="${MODULE_DIR}\DataHub.msa"/>
</target>
<target depends="DataHub_clean" name="clean"/>
<target depends="DataHub_cleanall" name="cleanall"/>
<target name="DataHub_clean">
<OutputDirSetup baseName="DataHub" mbdFilename="${MODULE_DIR}\DataHub.mbd" msaFilename="${MODULE_DIR}\DataHub.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DataHub_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DataHub_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="DataHub_cleanall">
<OutputDirSetup baseName="DataHub" mbdFilename="${MODULE_DIR}\DataHub.mbd" msaFilename="${MODULE_DIR}\DataHub.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DataHub_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DataHub_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**DataHub*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,163 @@
/*++
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:
DataHubStdErr.c
Abstract:
Data Hub filter driver that takes DEBUG () info from Data Hub and writes it
to StdErr if it exists.
--*/
EFI_DATA_HUB_PROTOCOL *mDataHub = NULL;
EFI_EVENT mDataHubStdErrEvent;
STATIC
VOID
EFIAPI
DataHubStdErrEventHandler (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This
handler reads the Data Hub and sends any DEBUG info to StdErr.
Arguments:
Event - The event that occured, not used
Context - DataHub Protocol Pointer
Returns:
None.
--*/
{
EFI_STATUS Status;
EFI_DATA_HUB_PROTOCOL *DataHub;
EFI_DATA_RECORD_HEADER *Record;
DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord;
UINT64 Mtc;
EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;
INT32 OldAttribute;
DataHub = (EFI_DATA_HUB_PROTOCOL *) Context;
//
// If StdErr is not yet initialized just return a DEBUG print in the BDS
// after consoles are connect will make sure data gets flushed properly
// when StdErr is availible.
//
if (gST == NULL) {
return ;
}
if (gST->StdErr == NULL) {
return ;
}
//
// Mtc of zero means return the next record that has not been read by the
// event handler.
//
Mtc = 0;
do {
Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record);
if (!EFI_ERROR (Status)) {
if (CompareGuid (&Record->DataRecordGuid, &gEfiStatusCodeGuid)) {
DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize);
if (DataRecord->Data.HeaderSize > 0) {
if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) {
//
// If the Data record is from a DEBUG () then send it to Standard Error
//
Sto = gST->StdErr;
OldAttribute = Sto->Mode->Attribute;
Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));
Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1));
Sto->SetAttribute (Sto, OldAttribute);
}
}
}
}
} while ((Mtc != 0) && !EFI_ERROR (Status));
}
EFI_STATUS
EFIAPI
DataHubStdErrInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Register an event handler with the Data Hub to parse EFI_DEBUG_CODE. This
handler reads the Data Hub and sends any DEBUG info to StdErr.
Arguments:
ImageHandle - Image handle of this driver.
SystemTable - Pointer to EFI system table.
Returns:
EFI_SUCCESS - The event handler was registered.
EFI_OUT_OF_RESOURCES - The event hadler was not registered due to lack of
system resources.
--*/
{
EFI_STATUS Status;
UINT64 DataClass;
gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub);
//
// Should never fail due to Depex grammer.
//
ASSERT (mDataHub != NULL);
//
// Create an event and register it with the filter driver
//
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_CALLBACK,
DataHubStdErrEventHandler,
mDataHub,
&mDataHubStdErrEvent
);
if (EFI_ERROR (Status)) {
return Status;
}
DataClass = EFI_DATA_RECORD_CLASS_DEBUG | EFI_DATA_RECORD_CLASS_ERROR;
Status = mDataHub->RegisterFilterDriver (
mDataHub,
mDataHubStdErrEvent,
EFI_TPL_CALLBACK,
DataClass,
NULL
);
if (EFI_ERROR (Status)) {
gBS->CloseEvent (mDataHubStdErrEvent);
}
return Status;
}

View File

@@ -0,0 +1,27 @@
/*++
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:
DataHubStdErr.dxs
Abstract:
Dependency expression source file.
--*/
#include <AutoGen.h>
#include <DxeDepex.h>
DEPENDENCY_START
EFI_DATA_HUB_PROTOCOL_GUID
DEPENDENCY_END

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>DataHubStdErr</BaseName>
<Guid>CA515306-00CE-4032-874E-11B755FF6866</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>BaseLib</Library>
</Libraries>
<BuildOptions ToolChain="MSFT">
<ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
</BuildOptions>
</ModuleBuildDescription>

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>DataHubStdErr</BaseName>
<ModuleType>DXE_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>CA515306-00CE-4032-874E-11B755FF6866</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>DataHubStdErr.c</Filename>
<Filename>DataHubStdErr.dxs</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
<PackageName>EdkModulePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="ALWAYS_CONSUMED">DataHub</Protocol>
</Protocols>
<Guids>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>StatusCode</C_Name>
</GuidEntry>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>StatusCodeDataTypeDebug</C_Name>
</GuidEntry>
</Guids>
<Externs>
<Extern>
<ModuleEntryPoint>DataHubStdErrInitialize</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="DataHubStdErr"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\DataHub\DataHubStdErr\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="DataHubStdErr">
<GenBuild baseName="DataHubStdErr" mbdFilename="${MODULE_DIR}\DataHubStdErr.mbd" msaFilename="${MODULE_DIR}\DataHubStdErr.msa"/>
</target>
<target depends="DataHubStdErr_clean" name="clean"/>
<target depends="DataHubStdErr_cleanall" name="cleanall"/>
<target name="DataHubStdErr_clean">
<OutputDirSetup baseName="DataHubStdErr" mbdFilename="${MODULE_DIR}\DataHubStdErr.mbd" msaFilename="${MODULE_DIR}\DataHubStdErr.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DataHubStdErr_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DataHubStdErr_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="DataHubStdErr_cleanall">
<OutputDirSetup baseName="DataHubStdErr" mbdFilename="${MODULE_DIR}\DataHubStdErr.mbd" msaFilename="${MODULE_DIR}\DataHubStdErr.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DataHubStdErr_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DataHubStdErr_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**DataHubStdErr*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,151 @@
/*++
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:
DebugSupport.c
Abstract:
Top level C file for debug support driver. Contains initialization function.
Revision History
--*/
//
// private header files
//
#include "plDebugSupport.h"
//
// This is a global that is the actual interface
//
EFI_DEBUG_SUPPORT_PROTOCOL gDebugSupportProtocolInterface = {
EFI_ISA,
GetMaximumProcessorIndex,
RegisterPeriodicCallback,
RegisterExceptionCallback,
InvalidateInstructionCache
};
//
// Driver Entry Point
//
EFI_STATUS
InitializeDebugSupportDriver (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Driver entry point. Checks to see there's not already a DebugSupport protocol
installed for the selected processor before installing protocol.
Arguments:
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
Returns:
EFI_STATUS
--*/
// TODO: ImageHandle - add argument and description to function comment
// TODO: SystemTable - add argument and description to function comment
{
EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocolPtr;
EFI_STATUS Status;
EFI_HANDLE Handle;
EFI_HANDLE *HandlePtr;
UINTN NumHandles;
EFI_DEBUG_SUPPORT_PROTOCOL *DebugSupportProtocolPtr;
//
// Install Protocol Interface...
//
// First check to see that the debug support protocol for this processor
// type is not already installed
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiDebugSupportProtocolGuid,
NULL,
&NumHandles,
&HandlePtr
);
if (Status != EFI_NOT_FOUND) {
do {
NumHandles--;
Status = gBS->OpenProtocol (
HandlePtr[NumHandles],
&gEfiDebugSupportProtocolGuid,
(VOID **) &DebugSupportProtocolPtr,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (Status == EFI_SUCCESS && DebugSupportProtocolPtr->Isa == EFI_ISA) {
gBS->FreePool (HandlePtr);
Status = EFI_ALREADY_STARTED;
goto ErrExit;
}
} while (NumHandles > 0);
gBS->FreePool (HandlePtr);
}
//
// Get our image information and install platform specific unload handler
//
Status = gBS->OpenProtocol (
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **) &LoadedImageProtocolPtr,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
ASSERT (!EFI_ERROR (Status));
if (Status != EFI_SUCCESS) {
goto ErrExit;
}
LoadedImageProtocolPtr->Unload = plUnloadDebugSupportDriver;
//
// Call hook for platform specific initialization
//
Status = plInitializeDebugSupportDriver ();
ASSERT (!EFI_ERROR (Status));
if (Status != EFI_SUCCESS) {
goto ErrExit;
}
//
// Install DebugSupport protocol to new handle
//
Handle = NULL;
Status = gBS->InstallProtocolInterface (
&Handle,
&gEfiDebugSupportProtocolGuid,
EFI_NATIVE_INTERFACE,
&gDebugSupportProtocolInterface
);
ASSERT (!EFI_ERROR (Status));
if (Status != EFI_SUCCESS) {
goto ErrExit;
}
ErrExit:
return Status;
}

View File

@@ -0,0 +1,26 @@
/*++
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:
DebugSupport.dxs
Abstract:
Dependency expression source file.
--*/
#include <AutoGen.h>
#include <DxeDepex.h>
DEPENDENCY_START
TRUE
DEPENDENCY_END

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>DebugSupport</BaseName>
<Guid>911D584C-35F7-4955-BEF9-B452769DDC3A</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>BaseLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>DxeMemoryAllocationLib</Library>
</Libraries>
<BuildOptions ToolChain="MSFT">
<ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
</BuildOptions>
</ModuleBuildDescription>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>DebugSupport</BaseName>
<ModuleType>DXE_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>911D584C-35F7-4955-BEF9-B452769DDC3A</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>DebugSupport.c</Filename>
<Filename>DebugSupport.dxs</Filename>
<Arch ArchType="IA32">
<Filename>ia32\AsmFuncs.asm</Filename>
<Filename>ia32\plDebugSupport.c</Filename>
</Arch>
<Arch ArchType="IPF">
<Filename>ipf\AsmFuncs.s</Filename>
<Filename>ipf\common.i</Filename>
<Filename>ipf\ds64macros.i</Filename>
<Filename>ipf\plDebugSupport.c</Filename>
</Arch>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
<PackageName>EdkModulePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="SOMETIMES_PRODUCED">DebugSupport</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>
</Protocols>
<Externs>
<Extern>
<ModuleEntryPoint>InitializeDebugSupportDriver</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="DebugSupport"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\DebugSupport\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="DebugSupport">
<GenBuild baseName="DebugSupport" mbdFilename="${MODULE_DIR}\DebugSupport.mbd" msaFilename="${MODULE_DIR}\DebugSupport.msa"/>
</target>
<target depends="DebugSupport_clean" name="clean"/>
<target depends="DebugSupport_cleanall" name="cleanall"/>
<target name="DebugSupport_clean">
<OutputDirSetup baseName="DebugSupport" mbdFilename="${MODULE_DIR}\DebugSupport.mbd" msaFilename="${MODULE_DIR}\DebugSupport.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DebugSupport_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DebugSupport_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="DebugSupport_cleanall">
<OutputDirSetup baseName="DebugSupport" mbdFilename="${MODULE_DIR}\DebugSupport.mbd" msaFilename="${MODULE_DIR}\DebugSupport.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DebugSupport_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DebugSupport_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**DebugSupport*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,547 @@
;******************************************************************************
;*
;* 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.
;*
;******************************************************************************
.586p
.MODEL FLAT, C
EXCPT32_DIVIDE_ERROR EQU 0
EXCPT32_DEBUG EQU 1
EXCPT32_NMI EQU 2
EXCPT32_BREAKPOINT EQU 3
EXCPT32_OVERFLOW EQU 4
EXCPT32_BOUND EQU 5
EXCPT32_INVALID_OPCODE EQU 6
EXCPT32_DOUBLE_FAULT EQU 8
EXCPT32_INVALID_TSS EQU 10
EXCPT32_SEG_NOT_PRESENT EQU 11
EXCPT32_STACK_FAULT EQU 12
EXCPT32_GP_FAULT EQU 13
EXCPT32_PAGE_FAULT EQU 14
EXCPT32_FP_ERROR EQU 16
EXCPT32_ALIGNMENT_CHECK EQU 17
EXCPT32_MACHINE_CHECK EQU 18
EXCPT32_SIMD EQU 19
FXSTOR_FLAG EQU 01000000h ; bit cpuid 24 of feature flags
;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87,
;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver
;; MUST check the CPUID feature flags to see that these instructions are available
;; and fail to init if they are not.
;; fxstor [edi]
FXSTOR_EDI MACRO
db 0fh, 0aeh, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [edi]
ENDM
;; fxrstor [esi]
FXRSTOR_ESI MACRO
db 0fh, 0aeh, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [esi]
ENDM
.DATA
public OrigVector, InterruptEntryStub, StubSize, CommonIdtEntry, FxStorSupport
StubSize dd InterruptEntryStubEnd - InterruptEntryStub
AppEsp dd 11111111h ; ?
DebugEsp dd 22222222h ; ?
ExtraPush dd 33333333h ; ?
ExceptData dd 44444444h ; ?
Eflags dd 55555555h ; ?
OrigVector dd 66666666h ; ?
;; The declarations below define the memory region that will be used for the debug stack.
;; The context record will be built by pushing register values onto this stack.
;; It is imparitive that alignment be carefully managed, since the FXSTOR and
;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned.
;;
;; The stub will switch stacks from the application stack to the debuger stack
;; and pushes the exception number.
;;
;; Then we building the context record on the stack. Since the stack grows down,
;; we push the fields of the context record from the back to the front. There
;; are 132 bytes of stack used prior allocating the 512 bytes of stack to be
;; used as the memory buffer for the fxstor instruction. Therefore address of
;; the buffer used for the FXSTOR instruction is &Eax - 132 - 512, which
;; must be 16 byte aligned.
;;
;; We carefully locate the stack to make this happen.
;;
;; For reference, the context structure looks like this:
;; struct {
;; UINT32 ExceptionData;
;; FX_SAVE_STATE FxSaveState; // 512 bytes, must be 16 byte aligned
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
;; UINT32 Ldtr, Tr;
;; UINT64 Gdtr, Idtr;
;; UINT32 EFlags;
;; UINT32 Eip;
;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs;
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record
align 16
DebugStackEnd db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment
dd 1ffdh dup (000000000h) ;; 32K should be enough stack
;; This allocation is coocked to insure
;; that the the buffer for the FXSTORE instruction
;; will be 16 byte aligned also.
;;
ExceptionNumber dd ? ;; first entry will be the vector number pushed by the stub
DebugStackBegin db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub
.CODE
externdef InterruptDistrubutionHub:near
;------------------------------------------------------------------------------
; BOOLEAN
; FxStorSupport (
; void
; )
;
; Abstract: Returns TRUE if FxStor instructions are supported
;
FxStorSupport PROC C PUBLIC
;
; cpuid corrupts ebx which must be preserved per the C calling convention
;
push ebx
mov eax, 1
cpuid
mov eax, edx
and eax, FXSTOR_FLAG
shr eax, 24
pop ebx
ret
FxStorSupport ENDP
;------------------------------------------------------------------------------
; DESCRIPTOR *
; GetIdtr (
; void
; )
;
; Abstract: Returns physical address of IDTR
;
GetIdtr PROC C PUBLIC
LOCAL IdtrBuf:FWORD
sidt IdtrBuf
mov eax, DWORD PTR IdtrBuf + 2
ret
GetIdtr ENDP
;------------------------------------------------------------------------------
; BOOLEAN
; WriteInterruptFlag (
; BOOLEAN NewState
; )
;
; Abstract: Programs interrupt flag to the requested state and returns previous
; state.
;
WriteInterruptFlag PROC C PUBLIC State:DWORD
pushfd
pop eax
and eax, 200h
shr eax, 9
mov ecx, State
.IF ecx == 0
cli
.ELSE
sti
.ENDIF
ret
WriteInterruptFlag ENDP
;------------------------------------------------------------------------------
; void
; Vect2Desc (
; DESCRIPTOR * DestDesc,
; void (*Vector) (void)
; )
;
; Abstract: Encodes an IDT descriptor with the given physical address
;
Vect2Desc PROC C PUBLIC DestPtr:DWORD, Vector:DWORD
mov eax, Vector
mov ecx, DestPtr
mov word ptr [ecx], ax ; write bits 15..0 of offset
mov word ptr [ecx+2], 20h ; SYS_CODE_SEL from GDT
mov word ptr [ecx+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
shr eax, 16
mov word ptr [ecx+6], ax ; write bits 31..16 of offset
ret
Vect2Desc ENDP
;------------------------------------------------------------------------------
; InterruptEntryStub
;
; Abstract: This code is not a function, but is a small piece of code that is
; copied and fixed up once for each IDT entry that is hooked.
;
InterruptEntryStub::
mov AppEsp, esp ; save stack top
mov esp, offset DebugStackBegin ; switch to debugger stack
push 0 ; push vector number - will be modified before installed
db 0e9h ; jump rel32
dd 0 ; fixed up to relative address of CommonIdtEntry
InterruptEntryStubEnd:
;------------------------------------------------------------------------------
; CommonIdtEntry
;
; Abstract: This code is not a function, but is the common part for all IDT
; vectors.
;
CommonIdtEntry::
;;
;; At this point, the stub has saved the current application stack esp into AppEsp
;; and switched stacks to the debug stack, where it pushed the vector number
;;
;; The application stack looks like this:
;;
;; ...
;; (last application stack entry)
;; eflags from interrupted task
;; CS from interrupted task
;; EIP from interrupted task
;; Error code <-------------------- Only present for some exeption types
;;
;;
;; The stub switched us to the debug stack and pushed the interrupt number.
;;
;; Next, construct the context record. It will be build on the debug stack by
;; pushing the registers in the correct order so as to create the context structure
;; on the debug stack. The context record must be built from the end back to the
;; beginning because the stack grows down...
;
;; For reference, the context record looks like this:
;;
;; typedef
;; struct {
;; UINT32 ExceptionData;
;; FX_SAVE_STATE FxSaveState;
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
;; UINT32 Cr0, Cr2, Cr3, Cr4;
;; UINT32 Ldtr, Tr;
;; UINT64 Gdtr, Idtr;
;; UINT32 EFlags;
;; UINT32 Eip;
;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs;
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
pushad
;; Save interrupt state eflags register...
pushfd
pop eax
mov dword ptr Eflags, eax
;; We need to determine if any extra data was pushed by the exception, and if so, save it
;; To do this, we check the exception number pushed by the stub, and cache the
;; result in a variable since we'll need this again.
.IF ExceptionNumber == EXCPT32_DOUBLE_FAULT
mov ExtraPush, 1
.ELSEIF ExceptionNumber == EXCPT32_INVALID_TSS
mov ExtraPush, 1
.ELSEIF ExceptionNumber == EXCPT32_SEG_NOT_PRESENT
mov ExtraPush, 1
.ELSEIF ExceptionNumber == EXCPT32_STACK_FAULT
mov ExtraPush, 1
.ELSEIF ExceptionNumber == EXCPT32_GP_FAULT
mov ExtraPush, 1
.ELSEIF ExceptionNumber == EXCPT32_PAGE_FAULT
mov ExtraPush, 1
.ELSEIF ExceptionNumber == EXCPT32_ALIGNMENT_CHECK
mov ExtraPush, 1
.ELSE
mov ExtraPush, 0
.ENDIF
;; If there's some extra data, save it also, and modify the saved AppEsp to effectively
;; pop this value off the application's stack.
.IF ExtraPush == 1
mov eax, AppEsp
mov ebx, [eax]
mov ExceptData, ebx
add eax, 4
mov AppEsp, eax
.ELSE
mov ExceptData, 0
.ENDIF
;; The "pushad" above pushed the debug stack esp. Since what we're actually doing
;; is building the context record on the debug stack, we need to save the pushed
;; debug ESP, and replace it with the application's last stack entry...
mov eax, [esp + 12]
mov DebugEsp, eax
mov eax, AppEsp
add eax, 12
; application stack has eflags, cs, & eip, so
; last actual application stack entry is
; 12 bytes into the application stack.
mov [esp + 12], eax
;; continue building context record
;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
mov eax, ss
push eax
; CS from application is one entry back in application stack
mov eax, AppEsp
movzx eax, word ptr [eax + 4]
push eax
mov eax, ds
push eax
mov eax, es
push eax
mov eax, fs
push eax
mov eax, gs
push eax
;; UINT32 Eip;
; Eip from application is on top of application stack
mov eax, AppEsp
push dword ptr [eax]
;; UINT64 Gdtr, Idtr;
push 0
push 0
sidt fword ptr [esp]
push 0
push 0
sgdt fword ptr [esp]
;; UINT32 Ldtr, Tr;
xor eax, eax
str ax
push eax
sldt ax
push eax
;; UINT32 EFlags;
;; Eflags from application is two entries back in application stack
mov eax, AppEsp
push dword ptr [eax + 8]
;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
;; insure FXSAVE/FXRSTOR is enabled in CR4...
;; ... while we're at it, make sure DE is also enabled...
mov eax, cr4
or eax, 208h
mov cr4, eax
push eax
mov eax, cr3
push eax
mov eax, cr2
push eax
push 0
mov eax, cr0
push eax
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
mov eax, dr7
push eax
;; clear Dr7 while executing debugger itself
xor eax, eax
mov dr7, eax
mov eax, dr6
push eax
;; insure all status bits in dr6 are clear...
xor eax, eax
mov dr6, eax
mov eax, dr3
push eax
mov eax, dr2
push eax
mov eax, dr1
push eax
mov eax, dr0
push eax
;; FX_SAVE_STATE FxSaveState;
sub esp, 512
mov edi, esp
; IMPORTANT!! The debug stack has been carefully constructed to
; insure that esp and edi are 16 byte aligned when we get here.
; They MUST be. If they are not, a GP fault will occur.
FXSTOR_EDI
;; UINT32 ExceptionData;
mov eax, ExceptData
push eax
; call to C code which will in turn call registered handler
; pass in the vector number
mov eax, esp
push eax
mov eax, ExceptionNumber
push eax
call InterruptDistrubutionHub
add esp, 8
; restore context...
;; UINT32 ExceptionData;
add esp, 4
;; FX_SAVE_STATE FxSaveState;
mov esi, esp
FXRSTOR_ESI
add esp, 512
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
pop eax
mov dr0, eax
pop eax
mov dr1, eax
pop eax
mov dr2, eax
pop eax
mov dr3, eax
;; skip restore of dr6. We cleared dr6 during the context save.
add esp, 4
pop eax
mov dr7, eax
;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
pop eax
mov cr0, eax
add esp, 4
pop eax
mov cr2, eax
pop eax
mov cr3, eax
pop eax
mov cr4, eax
;; UINT32 EFlags;
mov eax, AppEsp
pop dword ptr [eax + 8]
;; UINT16 Ldtr, Tr;
;; UINT64 Gdtr, Idtr;
;; Best not let anyone mess with these particular registers...
add esp, 24
;; UINT32 Eip;
pop dword ptr [eax]
;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs;
;; NOTE - modified segment registers could hang the debugger... We
;; could attempt to insulate ourselves against this possibility,
;; but that poses risks as well.
;;
pop gs
pop fs
pop es
pop ds
pop [eax + 4]
pop ss
;; The next stuff to restore is the general purpose registers that were pushed
;; using the pushad instruction.
;;
;; The value of ESP as stored in the context record is the application ESP
;; including the 3 entries on the application stack caused by the exception
;; itself. It may have been modified by the debug agent, so we need to
;; determine if we need to relocate the application stack.
mov ebx, [esp + 12] ; move the potentially modified AppEsp into ebx
mov eax, AppEsp
add eax, 12
cmp ebx, eax
je NoAppStackMove
mov eax, AppEsp
mov ecx, [eax] ; EIP
mov [ebx], ecx
mov ecx, [eax + 4] ; CS
mov [ebx + 4], ecx
mov ecx, [eax + 8] ; EFLAGS
mov [ebx + 8], ecx
mov eax, ebx ; modify the saved AppEsp to the new AppEsp
mov AppEsp, eax
NoAppStackMove:
mov eax, DebugEsp ; restore the DebugEsp on the debug stack
; so our popad will not cause a stack switch
mov [esp + 12], eax
cmp ExceptionNumber, 068h
jne NoChain
Chain:
;; Restore eflags so when we chain, the flags will be exactly as if we were never here.
;; We gin up the stack to do an iretd so we can get ALL the flags.
mov eax, AppEsp
mov ebx, [eax + 8]
and ebx, NOT 300h ; special handling for IF and TF
push ebx
push cs
push PhonyIretd
iretd
PhonyIretd:
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
popad
;; Switch back to application stack
mov esp, AppEsp
;; Jump to original handler
jmp OrigVector
NoChain:
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
popad
;; Switch back to application stack
mov esp, AppEsp
;; We're outa here...
iretd
END

View File

@@ -0,0 +1,440 @@
/*++
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:
plDebugSupport.c
Abstract:
IA32 specific debug support functions
Revision History
--*/
//
// private header files
//
#include "plDebugSupport.h"
//
// This the global main table to keep track of the interrupts
//
IDT_ENTRY *IdtEntryTable = NULL;
DESCRIPTOR NullDesc = 0;
#ifndef EFI_NT_EMULATOR
STATIC
EFI_STATUS
CreateEntryStub (
IN EFI_EXCEPTION_TYPE ExceptionType,
OUT VOID **Stub
)
/*++
Routine Description: Allocate pool for a new IDT entry stub. Copy the generic
stub into the new buffer and fixup the vector number and jump target address.
Arguments:
ExceptionType - This is the exception type that the new stub will be created
for.
Stub - On successful exit, *Stub contains the newly allocated entry stub.
Returns:
Typically EFI_SUCCESS
other possibilities are passed through from AllocatePool
--*/
{
EFI_STATUS Status;
UINT8 *StubCopy;
//
// First, allocate a new buffer and copy the stub code into it
//
Status = gBS->AllocatePool (EfiBootServicesData, StubSize, Stub);
if (Status == EFI_SUCCESS) {
StubCopy = *Stub;
gBS->CopyMem (StubCopy, InterruptEntryStub, StubSize);
//
// Next fixup the stub code for this vector
//
// The stub code looks like this:
//
// 00000000 89 25 00000004 R mov AppEsp, esp ; save stack top
// 00000006 BC 00008014 R mov esp, offset DbgStkBot ; switch to debugger stack
// 0000000B 6A 00 push 0 ; push vector number - will be modified before installed
// 0000000D E9 db 0e9h ; jump rel32
// 0000000E 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry
//
//
// poke in the exception type so the second push pushes the exception type
//
StubCopy[0x0c] = (UINT8) ExceptionType;
//
// fixup the jump target to point to the common entry
//
*(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize];
}
return Status;
}
STATIC
EFI_STATUS
HookEntry (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN VOID (*NewCallback) ()
)
/*++
Routine Description:
Creates a nes entry stub. Then saves the current IDT entry and replaces it
with an interrupt gate for the new entry point. The IdtEntryTable is updated
with the new registered function.
This code executes in boot services context. The stub entry executes in interrupt
context.
Arguments:
ExceptionType - specifies which vector to hook.
NewCallback - a pointer to the new function to be registered.
Returns:
EFI_SUCCESS
Other possibilities are passed through by CreateEntryStub
--*/
// TODO: ) - add argument and description to function comment
{
BOOLEAN OldIntFlagState;
EFI_STATUS Status;
Status = CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry);
if (Status == EFI_SUCCESS) {
OldIntFlagState = WriteInterruptFlag (0);
ReadIdt (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[0] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[0];
((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[3];
Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry);
IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback;
WriteIdt (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc));
WriteInterruptFlag (OldIntFlagState);
}
return Status;
}
STATIC
EFI_STATUS
UnhookEntry (
IN EFI_EXCEPTION_TYPE ExceptionType
)
/*++
Routine Description:
Undoes HookEntry. This code executes in boot services context.
Arguments:
ExceptionType - specifies which entry to unhook
Returns:
EFI_SUCCESS
Other values are passed through from FreePool
--*/
{
BOOLEAN OldIntFlagState;
EFI_STATUS Status;
OldIntFlagState = WriteInterruptFlag (0);
WriteIdt (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
Status = gBS->FreePool ((VOID *) (UINTN) IdtEntryTable[ExceptionType].StubEntry);
ZeroMem (&IdtEntryTable[ExceptionType], sizeof (IDT_ENTRY));
WriteInterruptFlag (OldIntFlagState);
return (Status);
}
#endif
EFI_STATUS
ManageIdtEntryTable (
VOID (*NewCallback)(),
EFI_EXCEPTION_TYPE ExceptionType
)
/*++
Routine Description:
This is the main worker function that manages the state of the interrupt
handlers. It both installs and uninstalls interrupt handlers based on the
value of NewCallback. If NewCallback is NULL, then uninstall is indicated.
If NewCallback is non-NULL, then install is indicated.
Arguments:
NewCallback - If non-NULL, NewCallback specifies the new handler to register.
If NULL, specifies that the previously registered handler should
be uninstalled.
ExceptionType - Indicates which entry to manage
Returns:
EFI_SUCCESS
EFI_INVALID_PARAMETER - requested uninstalling a handler from a vector that has
no handler registered for it
EFI_ALREADY_STARTED - requested install to a vector that already has a handler registered.
Other possible return values are passed through from UnHookEntry and HookEntry.
--*/
// TODO: ) - add argument and description to function comment
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
#ifndef EFI_NT_EMULATOR
if (CompareDescriptor (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc)) {
//
// we've already installed to this vector
//
if (NewCallback != NULL) {
//
// if the input handler is non-null, error
//
Status = EFI_ALREADY_STARTED;
} else {
Status = UnhookEntry (ExceptionType);
}
} else {
//
// no user handler installed on this vector
//
if (NewCallback == NULL) {
//
// if the input handler is null, error
//
Status = EFI_INVALID_PARAMETER;
} else {
Status = HookEntry (ExceptionType, NewCallback);
}
}
#endif
return Status;
}
EFI_STATUS
EFIAPI
GetMaximumProcessorIndex (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
OUT UINTN *MaxProcessorIndex
)
/*++
Routine Description: This is a DebugSupport protocol member function.
Arguments:
Returns: Always returns EFI_SUCCESS with *MaxProcessorIndex set to 0
--*/
// TODO: This - add argument and description to function comment
// TODO: MaxProcessorIndex - add argument and description to function comment
{
*MaxProcessorIndex = 0;
return (EFI_SUCCESS);
}
EFI_STATUS
EFIAPI
RegisterPeriodicCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_PERIODIC_CALLBACK PeriodicCallback
)
/*++
Routine Description: This is a DebugSupport protocol member function.
Arguments:
Returns:
--*/
// TODO: This - add argument and description to function comment
// TODO: ProcessorIndex - add argument and description to function comment
// TODO: PeriodicCallback - add argument and description to function comment
{
return ManageIdtEntryTable (PeriodicCallback, SYSTEM_TIMER_VECTOR);
}
EFI_STATUS
EFIAPI
RegisterExceptionCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_EXCEPTION_CALLBACK NewCallback,
IN EFI_EXCEPTION_TYPE ExceptionType
)
/*++
Routine Description:
This is a DebugSupport protocol member function.
This code executes in boot services context.
Arguments:
Returns:
None
--*/
// TODO: This - add argument and description to function comment
// TODO: ProcessorIndex - add argument and description to function comment
// TODO: NewCallback - add argument and description to function comment
// TODO: ExceptionType - add argument and description to function comment
{
return ManageIdtEntryTable (NewCallback, ExceptionType);
}
EFI_STATUS
EFIAPI
InvalidateInstructionCache (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN VOID *Start,
IN UINT64 Length
)
/*++
Routine Description:
This is a DebugSupport protocol member function.
For IA32, this is a no-op since the instruction and data caches are coherent.
Arguments:
Returns:
None
--*/
// TODO: This - add argument and description to function comment
// TODO: ProcessorIndex - add argument and description to function comment
// TODO: Start - add argument and description to function comment
// TODO: Length - add argument and description to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
return EFI_SUCCESS;
}
EFI_STATUS
plInitializeDebugSupportDriver (
VOID
)
/*++
Routine Description:
Initializes driver's handler registration database.
This code executes in boot services context.
Arguments:
None
Returns:
EFI_SUCCESS
EFI_UNSUPPORTED - if IA32 processor does not support FXSTOR/FXRSTOR instructions,
the context save will fail, so these processor's are not supported.
--*/
// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
{
if (!FxStorSupport ()) {
return EFI_UNSUPPORTED;
} else {
IdtEntryTable = AllocateZeroPool (sizeof (IDT_ENTRY) * NUM_IDT_ENTRIES);
if (IdtEntryTable != NULL) {
return EFI_SUCCESS;
} else {
return EFI_OUT_OF_RESOURCES;
}
}
}
EFI_STATUS
EFIAPI
plUnloadDebugSupportDriver (
IN EFI_HANDLE ImageHandle
)
/*++
Routine Description:
This is the callback that is written to the LoadedImage protocol instance
on the image handle. It uninstalls all registered handlers and frees all entry
stub memory.
This code executes in boot services context.
Arguments:
ImageHandle - The image handle of the unload handler
Returns:
None
--*/
// TODO: EFI_SUCCESS - add return value to function comment
{
EFI_EXCEPTION_TYPE ExceptionType;
for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) {
ManageIdtEntryTable (NULL, ExceptionType);
}
gBS->FreePool (IdtEntryTable);
return EFI_SUCCESS;
}
VOID
InterruptDistrubutionHub (
EFI_EXCEPTION_TYPE ExceptionType,
EFI_SYSTEM_CONTEXT_IA32 *ContextRecord
)
/*++
Routine Description: Common piece of code that invokes the registered handlers.
This code executes in exception context so no efi calls are allowed.
Arguments:
Returns:
None
--*/
// TODO: ExceptionType - add argument and description to function comment
// TODO: ContextRecord - add argument and description to function comment
{
if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) {
if (ExceptionType != SYSTEM_TIMER_VECTOR) {
IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord);
} else {
OrigVector = IdtEntryTable[ExceptionType].OrigVector;
IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord);
}
}
}

View File

@@ -0,0 +1,312 @@
/*++
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:
plDebugSupport.h
Abstract:
IA32 specific debug support macros, typedefs and prototypes.
Revision History
--*/
#ifndef _PLDEBUG_SUPPORT_H
#define _PLDEBUG_SUPPORT_H
#define NUM_IDT_ENTRIES 0x78
#define SYSTEM_TIMER_VECTOR 0x68
#define VECTOR_ENTRY_PAGES 1
#define CopyDescriptor(Dest, Src) CopyMem ((Dest), (Src), sizeof (DESCRIPTOR))
#define ZeroDescriptor(Dest) CopyDescriptor ((Dest), &NullDesc)
#define ReadIdt(Vector, Dest) CopyDescriptor ((Dest), &((GetIdtr ())[(Vector)]))
#define WriteIdt(Vector, Src) CopyDescriptor (&((GetIdtr ())[(Vector)]), (Src))
#define CompareDescriptor(Desc1, Desc2) CompareMem ((Desc1), (Desc2), sizeof (DESCRIPTOR))
#define EFI_ISA IsaIa32
#define FF_FXSR (1 << 24)
typedef UINT64 DESCRIPTOR;
typedef struct {
DESCRIPTOR OrigDesc;
VOID (*OrigVector) (VOID);
DESCRIPTOR NewDesc;
VOID (*StubEntry) (VOID);
VOID (*RegisteredCallback) ();
} IDT_ENTRY;
extern EFI_SYSTEM_CONTEXT SystemContext;
extern UINT8 InterruptEntryStub[];
extern UINT32 StubSize;
extern VOID (*OrigVector) (VOID);
VOID
CommonIdtEntry (
VOID
)
/*++
Routine Description:
TODO: Add function description
Arguments:
None
Returns:
TODO: add return values
--*/
;
BOOLEAN
FxStorSupport (
VOID
)
/*++
Routine Description:
TODO: Add function description
Arguments:
None
Returns:
TODO: add return values
--*/
;
DESCRIPTOR *
GetIdtr (
VOID
)
/*++
Routine Description:
TODO: Add function description
Arguments:
None
Returns:
TODO: add return values
--*/
;
VOID
Vect2Desc (
DESCRIPTOR * DestDesc,
VOID (*Vector) (VOID)
)
/*++
Routine Description:
TODO: Add function description
Arguments:
DestDesc - TODO: add argument description
) - TODO: add argument description
Returns:
TODO: add return values
--*/
;
BOOLEAN
WriteInterruptFlag (
BOOLEAN NewState
)
/*++
Routine Description:
TODO: Add function description
Arguments:
NewState - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
plInitializeDebugSupportDriver (
VOID
)
/*++
Routine Description:
TODO: Add function description
Arguments:
None
Returns:
TODO: add return values
--*/
;
EFI_STATUS
EFIAPI
plUnloadDebugSupportDriver (
IN EFI_HANDLE ImageHandle
)
/*++
Routine Description:
TODO: Add function description
Arguments:
ImageHandle - TODO: add argument description
Returns:
TODO: add return values
--*/
;
//
// DebugSupport protocol member functions
//
EFI_STATUS
EFIAPI
GetMaximumProcessorIndex (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
OUT UINTN *MaxProcessorIndex
)
/*++
Routine Description:
TODO: Add function description
Arguments:
This - TODO: add argument description
MaxProcessorIndex - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
EFIAPI
RegisterPeriodicCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_PERIODIC_CALLBACK PeriodicCallback
)
/*++
Routine Description:
TODO: Add function description
Arguments:
This - TODO: add argument description
ProcessorIndex - TODO: add argument description
PeriodicCallback - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
EFIAPI
RegisterExceptionCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_EXCEPTION_CALLBACK NewCallback,
IN EFI_EXCEPTION_TYPE ExceptionType
)
/*++
Routine Description:
TODO: Add function description
Arguments:
This - TODO: add argument description
ProcessorIndex - TODO: add argument description
NewCallback - TODO: add argument description
ExceptionType - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
EFIAPI
InvalidateInstructionCache (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN VOID *Start,
IN UINT64 Length
)
/*++
Routine Description:
TODO: Add function description
Arguments:
This - TODO: add argument description
ProcessorIndex - TODO: add argument description
Start - TODO: add argument description
Length - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,85 @@
//++
// 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:
//
// Ds64Macros.i
//
// Abstract:
//
// This is set of macros used in calculating offsets in the IVT
//
// Revision History:
//
//--
#define EXCPT_EXTERNAL_INTERRUPT 12
#define MASK_0_4 0x000000000000001F // mask bits 0 through 4
#define SLOT0 0
#define SLOT1 1
#define SLOT2 2
#define PSR_DT 17
#define PSR_TB 26
#define PSR_RT 27
#define PSR_IS 34
#define PSR_IT 36
#define PSR_IC 13
#define PSR_I 14
#define PSR_SS 40
#define PSR_BN 44
#define PSR_RI_MASK 0x60000000000
#define EXCPT_EXTERNAL_INTERRUPT 12
#define SCRATCH_REG0 r23
#define SCRATCH_REG1 r24
#define SCRATCH_REG2 r25
#define SCRATCH_REG3 r26
#define SCRATCH_REG4 r27
#define SCRATCH_REG5 r28
#define SCRATCH_REG6 r29
#define PR_REG r30
#define B0_REG r31
// EXT_INT_OFFSET is the offset of the external interrupt entry in the IVT
#define EXT_INT_ENTRY_OFFSET 0x03000
// PATCH_ENTRY_OFFSET is the offset into the IVT of the entry that is coopted (stolen)
// for use by the handler. The entire entry is restored when the handler is
// unloaded.
#define PATCH_ENTRY_OFFSET 0x03400
// PATCH_BUNDLES is the number of bundles actually in the patch
#define NUM_PATCH_BUNDLES ((EndPatchCode - PatchCode) / 0x10)
// A hard coded branch back into the external interrupt IVT entry's second bundle
// is put here, just in case the original bundle zero did not have a branch
// This is the last bundle in the reserved IVT entry
#define FAILSAFE_BRANCH_OFFSET (PATCH_ENTRY_OFFSET + 0x400 - 0x10)
// the original external interrupt IVT entry bundle zero is copied and relocated
// here... also in the reserved IVT entry
// This is the second-to-last bundle in the reserved IVT entry
#define RELOCATED_EXT_INT (PATCH_ENTRY_OFFSET + 0x400 - 0x20)
// The patch is actually stored at the end of IVT:PATCH_ENTRY. The PATCH_OFFSET
// is the offset into IVT where the patch is actually stored. It is carefully
// located so that when we run out of patch code, the next bundle is the
// relocated bundle 0 from the original external interrupt handler
#define PATCH_OFFSET (PATCH_ENTRY_OFFSET + 0x400 - ( EndPatchCode - PatchCode ) - 0x20)
#define PATCH_RETURN_OFFSET (PATCH_ENTRY_OFFSET + 0x400 - ( EndPatchCode - PatchCodeRet ) - 0x20)
// PATCH_BRANCH is used only in the new bundle that is placed at the beginning
// of the external interrupt IVT entry.
#define PATCH_BRANCH (PATCH_OFFSET - EXT_INT_ENTRY_OFFSET)

View File

@@ -0,0 +1,34 @@
//++
// 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:
//
// Common.i
//
// Abstract:
//
// This is set of useful macros
//
// Revision History:
//
//--
#define NESTED_SETUP(i,l,o,r) \
alloc loc1=ar##.##pfs,i,l,o,r ; \
mov loc0=b0 ;;
#define NESTED_RETURN \
mov b0=loc0 ; \
mov ar##.##pfs=loc1 ;; \
br##.##ret##.##dpnt b0 ;;
#define MASK(bp,value) (value << bp)

View File

@@ -0,0 +1,625 @@
/*++
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:
PlDebugSupport.c
Abstract:
IPF specific debug support functions
Revision History
--*/
//
// Master EFI header file
//
#include "Tiano.h"
//
// Common library header files
//
#include "EfiDriverLib.h"
//
// Produced protocols
//
#include EFI_PROTOCOL_DEFINITION (DebugSupport)
//
// private header files
//
#include "plDebugSupport.h"
typedef struct {
UINT64 low;
UINT64 high;
} BUNDLE;
//
// number of bundles to swap in ivt
//
#define NUM_BUNDLES_IN_STUB 5
#define NUM_IVT_ENTRIES 64
typedef struct {
BUNDLE OrigBundles[NUM_BUNDLES_IN_STUB];
VOID (*RegisteredCallback) ();
} IVT_ENTRY;
STATIC
EFI_STATUS
ManageIvtEntryTable (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN BUNDLE NewBundles[4],
IN VOID (*NewCallback) ()
);
STATIC
VOID
HookEntry (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN BUNDLE NewBundles[4],
IN VOID (*NewCallback) ()
);
STATIC
VOID
UnhookEntry (
IN EFI_EXCEPTION_TYPE ExceptionType
);
STATIC
VOID
ChainExternalInterrupt (
IN VOID (*NewCallback) ()
);
STATIC
VOID
UnchainExternalInterrupt (
VOID
);
STATIC
VOID
GetHandlerEntryPoint (
UINTN HandlerIndex,
VOID **EntryPoint
);
IVT_ENTRY IvtEntryTable[NUM_IVT_ENTRIES];
//
// IPF context record is overallocated by 512 bytes to guarantee a 512 byte alignment exists
// within the buffer and still have a large enough buffer to hold a whole IPF context record.
//
UINT8 IpfContextBuf[sizeof (EFI_SYSTEM_CONTEXT_IPF) + 512];
//
// The PatchSaveBuffer is used to store the original bundles from the IVT where it is patched
// with the common handler.
//
UINT8 PatchSaveBuffer[0x400];
UINTN ExternalInterruptCount;
EFI_STATUS
plInitializeDebugSupportDriver (
VOID
)
/*++
Routine Description:
IPF specific DebugSupport driver initialization. Must be public because it's
referenced from DebugSupport.c
Arguments:
Returns:
EFI_SUCCESS
--*/
{
gBS->SetMem (IvtEntryTable, sizeof (IvtEntryTable), 0);
ExternalInterruptCount = 0;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
plUnloadDebugSupportDriver (
IN EFI_HANDLE ImageHandle
)
/*++
Routine Description:
Unload handler that is called during UnloadImage() - deallocates pool memory
used by the driver. Must be public because it's referenced from DebugSuport.c
Arguments:
IN EFI_HANDLE ImageHandle
Returns:
EFI_STATUS - anything other than EFI_SUCCESS indicates the callback was not registered.
--*/
// TODO: ImageHandle - add argument and description to function comment
{
EFI_EXCEPTION_TYPE ExceptionType;
for (ExceptionType = 0; ExceptionType < NUM_IVT_ENTRIES; ExceptionType++) {
ManageIvtEntryTable (ExceptionType, NULL, NULL);
}
return EFI_SUCCESS;
}
VOID
CommonHandler (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT Context
)
/*++
Routine Description:
C routine that is called for all registered exceptions. This is the main
exception dispatcher. Must be public because it's referenced from AsmFuncs.s.
Arguments:
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT Context
Returns:
Nothing
--*/
// TODO: ExceptionType - add argument and description to function comment
// TODO: Context - add argument and description to function comment
{
static BOOLEAN InHandler = FALSE;
DEBUG_CODE (
if (InHandler) {
EfiDebugPrint (EFI_D_GENERIC, "ERROR: Re-entered debugger!\n"
" ExceptionType == %X\n"
" Context == %X\n"
" Context.SystemContextIpf->CrIip == %X\n"
" Context.SystemContextIpf->CrIpsr == %X\n"
" InHandler == %X\n",
ExceptionType,
Context,
Context.SystemContextIpf->CrIip,
Context.SystemContextIpf->CrIpsr,
InHandler);
}
)
ASSERT (!InHandler);
InHandler = TRUE;
if (IvtEntryTable[ExceptionType].RegisteredCallback != NULL) {
if (ExceptionType != EXCEPT_IPF_EXTERNAL_INTERRUPT) {
IvtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, Context.SystemContextIpf);
} else {
IvtEntryTable[ExceptionType].RegisteredCallback (Context.SystemContextIpf);
}
} else {
ASSERT (0);
}
InHandler = FALSE;
}
STATIC
VOID
GetHandlerEntryPoint (
UINTN HandlerIndex,
VOID **EntryPoint
)
/*++
Routine Description:
Given an integer number, return the physical address of the entry point in the IFT
Arguments:
UINTN HandlerIndex,
VOID ** EntryPoint
Returns:
Nothing
--*/
// TODO: HandlerIndex - add argument and description to function comment
// TODO: EntryPoint - add argument and description to function comment
{
UINT8 *TempPtr;
//
// get base address of IVT
//
TempPtr = GetIva ();
if (HandlerIndex < 20) {
//
// first 20 provide 64 bundles per vector
//
TempPtr += 0x400 * HandlerIndex;
} else {
//
// the rest provide 16 bundles per vector
//
TempPtr += 0x5000 + 0x100 * (HandlerIndex - 20);
}
*EntryPoint = (VOID *) TempPtr;
}
STATIC
EFI_STATUS
ManageIvtEntryTable (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN BUNDLE NewBundles[NUM_BUNDLES_IN_STUB],
IN VOID (*NewCallback) ()
)
/*++
Routine Description:
This is the worker function that installs and removes all handlers
Arguments:
IN EFI_EXCEPTION_TYPE ExceptionType,
IN BUNDLE NewBundles[NUM_BUNDLES_IN_STUB],
IN VOID (*NewCallback) ()
Returns:
EFI_STATUS - any return other than EFI_SUCCESS indicates the request was not
satisfied.
--*/
// TODO: ExceptionType - add argument and description to function comment
// TODO: ] - add argument and description to function comment
// TODO: ) - add argument and description to function comment
// TODO: EFI_ALREADY_STARTED - add return value to function comment
{
BUNDLE *B0Ptr;
UINT64 InterruptFlags;
EFI_TPL OldTpl;
//
// Get address of bundle 0
//
GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr);
if (IvtEntryTable[ExceptionType].RegisteredCallback != NULL) {
//
// we've already installed to this vector
//
if (NewCallback != NULL) {
//
// if the input handler is non-null, error
//
return EFI_ALREADY_STARTED;
} else {
//
// else remove the previously installed handler
//
OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
InterruptFlags = ProgramInterruptFlags (DISABLE_INTERRUPTS);
if (ExceptionType == EXCEPT_IPF_EXTERNAL_INTERRUPT) {
UnchainExternalInterrupt ();
} else {
UnhookEntry (ExceptionType);
}
ProgramInterruptFlags (InterruptFlags);
gBS->RestoreTPL (OldTpl);
//
// re-init IvtEntryTable
//
gBS->SetMem (&IvtEntryTable[ExceptionType], sizeof (IVT_ENTRY), 0);
}
} else {
//
// no user handler installed on this vector
//
if (NewCallback != NULL) {
OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
InterruptFlags = ProgramInterruptFlags (DISABLE_INTERRUPTS);
if (ExceptionType == EXCEPT_IPF_EXTERNAL_INTERRUPT) {
ChainExternalInterrupt (NewCallback);
} else {
HookEntry (ExceptionType, NewBundles, NewCallback);
}
ProgramInterruptFlags (InterruptFlags);
gBS->RestoreTPL (OldTpl);
}
}
return EFI_SUCCESS;
}
STATIC
VOID
HookEntry (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN BUNDLE NewBundles[4],
IN VOID (*NewCallback) ()
)
/*++
Routine Description:
Saves original IVT contents and inserts a few new bundles which are fixed up
to store the ExceptionType and then call the common handler.
Arguments:
IN EFI_EXCEPTION_TYPE ExceptionType,
IN BUNDLE NewBundles[4],
IN VOID (*NewCallback) ()
Returns:
Nothing
--*/
// TODO: ExceptionType - add argument and description to function comment
// TODO: ] - add argument and description to function comment
// TODO: ) - add argument and description to function comment
{
BUNDLE *FixupBundle;
BUNDLE *B0Ptr;
//
// Get address of bundle 0
//
GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr);
//
// copy original bundles from IVT to IvtEntryTable so we can restore them later
//
gBS->CopyMem (
IvtEntryTable[ExceptionType].OrigBundles,
B0Ptr,
sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB
);
//
// insert new B0
//
gBS->CopyMem (B0Ptr, NewBundles, sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB);
//
// fixup IVT entry so it stores its index and whether or not to chain...
//
FixupBundle = B0Ptr + 2;
FixupBundle->high |= ExceptionType << 36;
InstructionCacheFlush (B0Ptr, 5);
IvtEntryTable[ExceptionType].RegisteredCallback = NewCallback;
}
STATIC
VOID
UnhookEntry (
IN EFI_EXCEPTION_TYPE ExceptionType
)
/*++
Routine Description:
Restores original IVT contents when unregistering a callback function
Arguments:
IN EFI_EXCEPTION_TYPE ExceptionType,
Returns:
Nothing
--*/
// TODO: ExceptionType - add argument and description to function comment
{
BUNDLE *B0Ptr;
//
// Get address of bundle 0
//
GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr);
//
// restore original bundles in IVT
//
gBS->CopyMem (
B0Ptr,
IvtEntryTable[ExceptionType].OrigBundles,
sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB
);
InstructionCacheFlush (B0Ptr, 5);
}
STATIC
VOID
ChainExternalInterrupt (
IN VOID (*NewCallback) ()
)
/*++
Routine Description:
Sets up cache flush and calls assembly function to chain external interrupt.
Records new callback in IvtEntryTable.
Arguments:
IN VOID (*NewCallback) ()
Returns:
Nothing
--*/
// TODO: ) - add argument and description to function comment
{
VOID *Start;
Start = (VOID *) ((UINT8 *) GetIva () + 0x400 * EXCEPT_IPF_EXTERNAL_INTERRUPT + 0x400);
IvtEntryTable[EXCEPT_IPF_EXTERNAL_INTERRUPT].RegisteredCallback = NewCallback;
ChainHandler ();
InstructionCacheFlush (Start, 0x400);
}
STATIC
VOID
UnchainExternalInterrupt (
VOID
)
/*++
Routine Description:
Sets up cache flush and calls assembly function to restore external interrupt.
Removes registered callback from IvtEntryTable.
Arguments:
Nothing
Returns:
Nothing
--*/
{
VOID *Start;
Start = (VOID *) ((UINT8 *) GetIva () + 0x400 * EXCEPT_IPF_EXTERNAL_INTERRUPT + 0x400);
UnchainHandler ();
InstructionCacheFlush (Start, 0x400);
IvtEntryTable[EXCEPT_IPF_EXTERNAL_INTERRUPT].RegisteredCallback = NULL;
}
//
// The rest of the functions in this file are all member functions for the
// DebugSupport protocol
//
EFI_STATUS
EFIAPI
GetMaximumProcessorIndex (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
OUT UINTN *MaxProcessorIndex
)
/*++
Routine Description: This is a DebugSupport protocol member function. Hard
coded to support only 1 processor for now.
Arguments:
Returns: Always returns EFI_SUCCESS with *MaxProcessorIndex set to 0
--*/
// TODO: This - add argument and description to function comment
// TODO: MaxProcessorIndex - add argument and description to function comment
{
*MaxProcessorIndex = 0;
return (EFI_SUCCESS);
}
EFI_STATUS
EFIAPI
RegisterPeriodicCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_PERIODIC_CALLBACK NewPeriodicCallback
)
/*++
Routine Description:
DebugSupport protocol member function
Arguments:
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_PERIODIC_CALLBACK NewPeriodicCallback
Returns:
EFI_STATUS - anything other than EFI_SUCCESS indicates the callback was not registered.
--*/
// TODO: This - add argument and description to function comment
// TODO: ProcessorIndex - add argument and description to function comment
// TODO: NewPeriodicCallback - add argument and description to function comment
{
return ManageIvtEntryTable (EXCEPT_IPF_EXTERNAL_INTERRUPT, NULL, NewPeriodicCallback);
}
EFI_STATUS
EFIAPI
RegisterExceptionCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_EXCEPTION_CALLBACK NewCallback,
IN EFI_EXCEPTION_TYPE ExceptionType
)
/*++
Routine Description:
DebugSupport protocol member function
Arguments:
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN EFI_EXCEPTION_CALLBACK NewCallback,
IN EFI_EXCEPTION_TYPE ExceptionType
Returns:
EFI_STATUS - anything other than EFI_SUCCESS indicates the callback was not registered.
--*/
// TODO: This - add argument and description to function comment
// TODO: ProcessorIndex - add argument and description to function comment
// TODO: NewCallback - add argument and description to function comment
// TODO: ExceptionType - add argument and description to function comment
{
return ManageIvtEntryTable (
ExceptionType,
(BUNDLE *) ((EFI_PLABEL *) HookStub)->EntryPoint,
NewCallback
);
}
EFI_STATUS
EFIAPI
InvalidateInstructionCache (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN VOID *Start,
IN UINTN Length
)
/*++
Routine Description:
DebugSupport protocol member function. Calls assembly routine to flush cache.
Arguments:
Returns:
EFI_SUCCESS
--*/
// TODO: This - add argument and description to function comment
// TODO: ProcessorIndex - add argument and description to function comment
// TODO: Start - add argument and description to function comment
// TODO: Length - add argument and description to function comment
{
InstructionCacheFlush (Start, Length);
return (EFI_SUCCESS);
}

View File

@@ -0,0 +1,108 @@
/*++
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:
Component name protocol member functions for DebugPort...
--*/
#include "DebugPort.h"
//
// EFI Component Name Protocol
//
EFI_COMPONENT_NAME_PROTOCOL gDebugPortComponentName = {
DebugPortComponentNameGetDriverName,
DebugPortComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mDebugPortDriverNameTable[] = {
{
"eng",
(CHAR16 *) L"DebugPort Driver"
},
{
NULL,
NULL
}
};
EFI_STATUS
EFIAPI
DebugPortComponentNameGetDriverName (
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,
gDebugPortComponentName.SupportedLanguages,
mDebugPortDriverNameTable,
DriverName
);
}
EFI_STATUS
EFIAPI
DebugPortComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
/*++
Routine Description:
The debug port driver does not support GetControllerName, so this function
is just stubbed and returns EFI_UNSUPPORTED.
Arguments:
Per EFI 1.10 driver model
Returns:
EFI_UNSUPPORTED
--*/
{
return EFI_UNSUPPORTED;
}

View File

@@ -0,0 +1,833 @@
/*++
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:
DebugPort.c
Abstract:
Top level C file for debugport driver. Contains initialization function.
This driver layers on top of SerialIo.
ALL CODE IN THE SERIALIO STACK MUST BE RE-ENTRANT AND CALLABLE FROM
INTERRUPT CONTEXT.
Revision History
--*/
#include "DebugPort.h"
//
// Misc. functions local to this module
//
STATIC
VOID
GetDebugPortVariable (
DEBUGPORT_DEVICE *DebugPortDevice
);
EFI_STATUS
EFIAPI
ImageUnloadHandler (
EFI_HANDLE ImageHandle
);
//
// Globals
//
EFI_DRIVER_BINDING_PROTOCOL gDebugPortDriverBinding = {
DebugPortSupported,
DebugPortStart,
DebugPortStop,
DEBUGPORT_DRIVER_VERSION,
NULL,
NULL
};
DEBUGPORT_DEVICE *gDebugPortDevice;
static UINT32 mHid16550;
static UINT32 mHidStdPcComPort;
//
// implementation code
//
EFI_STATUS
EFIAPI
InitializeDebugPortDriver (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Driver entry point. Reads DebugPort variable to determine what device and settings
to use as the debug port. Binds exclusively to SerialIo. Reverts to defaults \
if no variable is found.
Creates debugport and devicepath protocols on new handle.
Arguments:
ImageHandle,
SystemTable
Returns:
EFI_UNSUPPORTED
EFI_OUT_OF_RESOURCES
--*/
{
mHid16550 = EFI_ACPI_16550UART_HID;
mHidStdPcComPort = EFI_ACPI_PC_COMPORT_HID;
//
// Allocate and Initialize dev structure
//
gDebugPortDevice = AllocateZeroPool (sizeof (DEBUGPORT_DEVICE));
if (gDebugPortDevice == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Fill in static and default pieces of device structure first.
//
gDebugPortDevice->Signature = DEBUGPORT_DEVICE_SIGNATURE;
gDebugPortDevice->DebugPortInterface.Reset = DebugPortReset;
gDebugPortDevice->DebugPortInterface.Read = DebugPortRead;
gDebugPortDevice->DebugPortInterface.Write = DebugPortWrite;
gDebugPortDevice->DebugPortInterface.Poll = DebugPortPoll;
gDebugPortDevice->BaudRate = DEBUGPORT_UART_DEFAULT_BAUDRATE;
gDebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
gDebugPortDevice->Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;
gDebugPortDevice->Parity = DEBUGPORT_UART_DEFAULT_PARITY;
gDebugPortDevice->DataBits = DEBUGPORT_UART_DEFAULT_DATA_BITS;
gDebugPortDevice->StopBits = DEBUGPORT_UART_DEFAULT_STOP_BITS;
return EFI_SUCCESS;
}
//
// DebugPort driver binding member functions...
//
EFI_STATUS
EFIAPI
DebugPortSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Checks to see that there's not already a DebugPort interface somewhere. If so,
fail.
If there's a DEBUGPORT variable, the device path must match exactly. If there's
no DEBUGPORT variable, then device path is not checked and does not matter.
Checks to see that there's a serial io interface on the controller handle
that can be bound BY_DRIVER | EXCLUSIVE.
If all these tests succeed, then we return EFI_SUCCESS, else, EFI_UNSUPPORTED
or other error returned by OpenProtocol.
Arguments:
This
ControllerHandle
RemainingDevicePath
Returns:
EFI_UNSUPPORTED
EFI_OUT_OF_RESOURCES
EFI_SUCCESS
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *Dp1;
EFI_DEVICE_PATH_PROTOCOL *Dp2;
EFI_SERIAL_IO_PROTOCOL *SerialIo;
EFI_DEBUGPORT_PROTOCOL *DebugPortInterface;
EFI_HANDLE TempHandle;
//
// Check to see that there's not a debugport protocol already published
//
if (gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **) &DebugPortInterface) != EFI_NOT_FOUND) {
return EFI_UNSUPPORTED;
}
//
// Read DebugPort variable to determine debug port selection and parameters
//
GetDebugPortVariable (gDebugPortDevice);
if (gDebugPortDevice->DebugPortVariable != NULL) {
//
// There's a DEBUGPORT variable, so do LocateDevicePath and check to see if
// the closest matching handle matches the controller handle, and if it does,
// check to see that the remaining device path has the DebugPort GUIDed messaging
// device path only. Otherwise, it's a mismatch and EFI_UNSUPPORTED is returned.
//
Dp1 = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) gDebugPortDevice->DebugPortVariable);
if (Dp1 == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Dp2 = Dp1;
Status = gBS->LocateDevicePath (
&gEfiSerialIoProtocolGuid,
&Dp2,
&TempHandle
);
if (Status == EFI_SUCCESS && TempHandle != ControllerHandle) {
Status = EFI_UNSUPPORTED;
}
if (Status == EFI_SUCCESS && (Dp2->Type != 3 || Dp2->SubType != 10 || *((UINT16 *) Dp2->Length) != 20)) {
Status = EFI_UNSUPPORTED;
}
if (Status == EFI_SUCCESS && CompareMem (&gEfiDebugPortDevicePathGuid, Dp2 + 1, sizeof (EFI_GUID))) {
Status = EFI_UNSUPPORTED;
}
gBS->FreePool (Dp1);
if (EFI_ERROR (Status)) {
return Status;
}
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
(VOID **) &SerialIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
);
if (EFI_ERROR (Status)) {
return Status;
}
gBS->CloseProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DebugPortStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Binds exclusively to serial io on the controller handle. Produces DebugPort
protocol and DevicePath on new handle.
Arguments:
This
ControllerHandle
RemainingDevicePath
Returns:
EFI_OUT_OF_RESOURCES
EFI_SUCCESS
--*/
{
EFI_STATUS Status;
DEBUGPORT_DEVICE_PATH DebugPortDP;
EFI_DEVICE_PATH_PROTOCOL EndDP;
EFI_DEVICE_PATH_PROTOCOL *Dp1;
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
(VOID **) &gDebugPortDevice->SerialIoBinding,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
);
if (EFI_ERROR (Status)) {
return Status;
}
gDebugPortDevice->SerialIoDeviceHandle = ControllerHandle;
//
// Initialize the Serial Io interface...
//
Status = gDebugPortDevice->SerialIoBinding->SetAttributes (
gDebugPortDevice->SerialIoBinding,
gDebugPortDevice->BaudRate,
gDebugPortDevice->ReceiveFifoDepth,
gDebugPortDevice->Timeout,
gDebugPortDevice->Parity,
gDebugPortDevice->DataBits,
gDebugPortDevice->StopBits
);
if (EFI_ERROR (Status)) {
gDebugPortDevice->BaudRate = 0;
gDebugPortDevice->Parity = DefaultParity;
gDebugPortDevice->DataBits = 0;
gDebugPortDevice->StopBits = DefaultStopBits;
gDebugPortDevice->ReceiveFifoDepth = 0;
Status = gDebugPortDevice->SerialIoBinding->SetAttributes (
gDebugPortDevice->SerialIoBinding,
gDebugPortDevice->BaudRate,
gDebugPortDevice->ReceiveFifoDepth,
gDebugPortDevice->Timeout,
gDebugPortDevice->Parity,
gDebugPortDevice->DataBits,
gDebugPortDevice->StopBits
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
}
gDebugPortDevice->SerialIoBinding->Reset (gDebugPortDevice->SerialIoBinding);
//
// Create device path instance for DebugPort
//
DebugPortDP.Header.Type = MESSAGING_DEVICE_PATH;
DebugPortDP.Header.SubType = MSG_VENDOR_DP;
SetDevicePathNodeLength (&(DebugPortDP.Header), sizeof (DebugPortDP));
gBS->CopyMem (&DebugPortDP.Guid, &gEfiDebugPortDevicePathGuid, sizeof (EFI_GUID));
Dp1 = DevicePathFromHandle (ControllerHandle);
if (Dp1 == NULL) {
Dp1 = &EndDP;
SetDevicePathEndNode (Dp1);
}
gDebugPortDevice->DebugPortDevicePath = AppendDevicePathNode (Dp1, (EFI_DEVICE_PATH_PROTOCOL *) &DebugPortDP);
if (gDebugPortDevice->DebugPortDevicePath == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Publish DebugPort and Device Path protocols
//
Status = gBS->InstallMultipleProtocolInterfaces (
&gDebugPortDevice->DebugPortDeviceHandle,
&gEfiDevicePathProtocolGuid,
gDebugPortDevice->DebugPortDevicePath,
&gEfiDebugPortProtocolGuid,
&gDebugPortDevice->DebugPortInterface,
NULL
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
//
// Connect debugport child to serial io
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
(VOID **) &gDebugPortDevice->SerialIoBinding,
This->DriverBindingHandle,
gDebugPortDevice->DebugPortDeviceHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
DEBUG_CODE (
UINTN BufferSize;
BufferSize = 48;
DebugPortWrite (
&gDebugPortDevice->DebugPortInterface,
0,
&BufferSize,
"DebugPort driver failed to open child controller\n\n"
);
);
gBS->CloseProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
DEBUG_CODE (
UINTN BufferSize;
BufferSize = 38;
DebugPortWrite (
&gDebugPortDevice->DebugPortInterface,
0,
&BufferSize,
"Hello World from the DebugPort driver\n\n"
);
);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DebugPortStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
We're never intending to be stopped via the driver model so this just returns
EFI_UNSUPPORTED
Arguments:
Per EFI 1.10 driver model
Returns:
EFI_UNSUPPORTED
EFI_SUCCESS
--*/
{
EFI_STATUS Status;
if (NumberOfChildren == 0) {
//
// Close the bus driver
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gDebugPortDevice->SerialIoBinding = NULL;
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->FreePool (gDebugPortDevice->DebugPortDevicePath);
return EFI_SUCCESS;
} else {
//
// Disconnect SerialIo child handle
//
Status = gBS->CloseProtocol (
gDebugPortDevice->SerialIoDeviceHandle,
&gEfiSerialIoProtocolGuid,
This->DriverBindingHandle,
gDebugPortDevice->DebugPortDeviceHandle
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Unpublish our protocols (DevicePath, DebugPort)
//
Status = gBS->UninstallMultipleProtocolInterfaces (
gDebugPortDevice->DebugPortDeviceHandle,
&gEfiDevicePathProtocolGuid,
gDebugPortDevice->DebugPortDevicePath,
&gEfiDebugPortProtocolGuid,
&gDebugPortDevice->DebugPortInterface,
NULL
);
if (EFI_ERROR (Status)) {
gBS->OpenProtocol (
ControllerHandle,
&gEfiSerialIoProtocolGuid,
(VOID **) &gDebugPortDevice->SerialIoBinding,
This->DriverBindingHandle,
gDebugPortDevice->DebugPortDeviceHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
gDebugPortDevice->DebugPortDeviceHandle = NULL;
}
}
return Status;
}
//
// Debugport protocol member functions
//
EFI_STATUS
EFIAPI
DebugPortReset (
IN EFI_DEBUGPORT_PROTOCOL *This
)
/*++
Routine Description:
DebugPort protocol member function. Calls SerialIo:GetControl to flush buffer.
We cannot call SerialIo:SetAttributes because it uses pool services, which use
locks, which affect TPL, so it's not interrupt context safe or re-entrant.
SerialIo:Reset() calls SetAttributes, so it can't be used either.
The port itself should be fine since it was set up during initialization.
Arguments:
This
Returns:
EFI_SUCCESS
--*/
{
DEBUGPORT_DEVICE *DebugPortDevice;
UINTN BufferSize;
UINTN BitBucket;
DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
while (This->Poll (This) == EFI_SUCCESS) {
BufferSize = 1;
This->Read (This, 0, &BufferSize, &BitBucket);
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DebugPortRead (
IN EFI_DEBUGPORT_PROTOCOL *This,
IN UINT32 Timeout,
IN OUT UINTN *BufferSize,
IN VOID *Buffer
)
/*++
Routine Description:
DebugPort protocol member function. Calls SerialIo:Read() after setting
if it's different than the last SerialIo access.
Arguments:
IN EFI_DEBUGPORT_PROTOCOL *This
IN UINT32 Timeout,
IN OUT UINTN *BufferSize,
IN VOID *Buffer
Returns:
EFI_STATUS
--*/
{
DEBUGPORT_DEVICE *DebugPortDevice;
UINTN LocalBufferSize;
EFI_STATUS Status;
UINT8 *BufferPtr;
DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
BufferPtr = Buffer;
LocalBufferSize = *BufferSize;
do {
Status = DebugPortDevice->SerialIoBinding->Read (
DebugPortDevice->SerialIoBinding,
&LocalBufferSize,
BufferPtr
);
if (Status == EFI_TIMEOUT) {
if (Timeout > DEBUGPORT_UART_DEFAULT_TIMEOUT) {
Timeout -= DEBUGPORT_UART_DEFAULT_TIMEOUT;
} else {
Timeout = 0;
}
} else if (EFI_ERROR (Status)) {
break;
}
BufferPtr += LocalBufferSize;
LocalBufferSize = *BufferSize - (BufferPtr - (UINT8 *) Buffer);
} while (LocalBufferSize != 0 && Timeout > 0);
*BufferSize = (UINTN) (BufferPtr - (UINT8 *) Buffer);
return Status;
}
EFI_STATUS
EFIAPI
DebugPortWrite (
IN EFI_DEBUGPORT_PROTOCOL *This,
IN UINT32 Timeout,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
/*++
Routine Description:
DebugPort protocol member function. Calls SerialIo:Write() Writes 8 bytes at
a time and does a GetControl between 8 byte writes to help insure reads are
interspersed This is poor-man's flow control..
Arguments:
This - Pointer to DebugPort protocol
Timeout - Timeout value
BufferSize - On input, the size of Buffer.
On output, the amount of data actually written.
Buffer - Pointer to buffer to write
Returns:
EFI_SUCCESS - The data was written.
EFI_DEVICE_ERROR - The device reported an error.
EFI_TIMEOUT - The data write was stopped due to a timeout.
--*/
{
DEBUGPORT_DEVICE *DebugPortDevice;
UINTN Position;
UINTN WriteSize;
EFI_STATUS Status;
UINT32 SerialControl;
Status = EFI_SUCCESS;
DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
WriteSize = 8;
for (Position = 0; Position < *BufferSize && !EFI_ERROR (Status); Position += WriteSize) {
DebugPortDevice->SerialIoBinding->GetControl (
DebugPortDevice->SerialIoBinding,
&SerialControl
);
if (*BufferSize - Position < 8) {
WriteSize = *BufferSize - Position;
}
Status = DebugPortDevice->SerialIoBinding->Write (
DebugPortDevice->SerialIoBinding,
&WriteSize,
&((UINT8 *) Buffer)[Position]
);
}
*BufferSize = Position;
return Status;
}
EFI_STATUS
EFIAPI
DebugPortPoll (
IN EFI_DEBUGPORT_PROTOCOL *This
)
/*++
Routine Description:
DebugPort protocol member function. Calls SerialIo:Write() after setting
if it's different than the last SerialIo access.
Arguments:
IN EFI_DEBUGPORT_PROTOCOL *This
Returns:
EFI_SUCCESS - At least 1 character is ready to be read from the DebugPort interface
EFI_NOT_READY - There are no characters ready to read from the DebugPort interface
EFI_DEVICE_ERROR - A hardware failure occured... (from SerialIo)
--*/
{
EFI_STATUS Status;
UINT32 SerialControl;
DEBUGPORT_DEVICE *DebugPortDevice;
DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
Status = DebugPortDevice->SerialIoBinding->GetControl (
DebugPortDevice->SerialIoBinding,
&SerialControl
);
if (!EFI_ERROR (Status)) {
if (SerialControl & EFI_SERIAL_INPUT_BUFFER_EMPTY) {
Status = EFI_NOT_READY;
} else {
Status = EFI_SUCCESS;
}
}
return Status;
}
//
// Misc. functions local to this module..
//
STATIC
VOID
GetDebugPortVariable (
DEBUGPORT_DEVICE *DebugPortDevice
)
/*++
Routine Description:
Local worker function to obtain device path information from DebugPort variable.
Records requested settings in DebugPort device structure.
Arguments:
DEBUGPORT_DEVICE *DebugPortDevice,
Returns:
Nothing
--*/
{
UINTN DataSize;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_STATUS Status;
DataSize = 0;
Status = gRT->GetVariable (
(CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,
&gEfiDebugPortVariableGuid,
NULL,
&DataSize,
DebugPortDevice->DebugPortVariable
);
if (Status == EFI_BUFFER_TOO_SMALL) {
if (gDebugPortDevice->DebugPortVariable != NULL) {
gBS->FreePool (gDebugPortDevice->DebugPortVariable);
}
DebugPortDevice->DebugPortVariable = AllocatePool (DataSize);
if (DebugPortDevice->DebugPortVariable != NULL) {
gRT->GetVariable (
(CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,
&gEfiDebugPortVariableGuid,
NULL,
&DataSize,
DebugPortDevice->DebugPortVariable
);
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DebugPortDevice->DebugPortVariable;
while (!EfiIsDevicePathEnd (DevicePath) && !EfiIsUartDevicePath (DevicePath)) {
DevicePath = EfiNextDevicePathNode (DevicePath);
}
if (EfiIsDevicePathEnd (DevicePath)) {
gBS->FreePool (gDebugPortDevice->DebugPortVariable);
DebugPortDevice->DebugPortVariable = NULL;
} else {
gBS->CopyMem (
&DebugPortDevice->BaudRate,
&((UART_DEVICE_PATH *) DevicePath)->BaudRate,
sizeof (((UART_DEVICE_PATH *) DevicePath)->BaudRate)
);
DebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
DebugPortDevice->Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;
gBS->CopyMem (
&DebugPortDevice->Parity,
&((UART_DEVICE_PATH *) DevicePath)->Parity,
sizeof (((UART_DEVICE_PATH *) DevicePath)->Parity)
);
gBS->CopyMem (
&DebugPortDevice->DataBits,
&((UART_DEVICE_PATH *) DevicePath)->DataBits,
sizeof (((UART_DEVICE_PATH *) DevicePath)->DataBits)
);
gBS->CopyMem (
&DebugPortDevice->StopBits,
&((UART_DEVICE_PATH *) DevicePath)->StopBits,
sizeof (((UART_DEVICE_PATH *) DevicePath)->StopBits)
);
}
}
}
}
EFI_STATUS
EFIAPI
ImageUnloadHandler (
EFI_HANDLE ImageHandle
)
/*++
Routine Description:
Unload function that is registered in the LoadImage protocol. It un-installs
protocols produced and deallocates pool used by the driver. Called by the core
when unloading the driver.
Arguments:
EFI_HANDLE ImageHandle
Returns:
EFI_SUCCESS
--*/
{
EFI_STATUS Status;
if (gDebugPortDevice->SerialIoBinding != NULL) {
return EFI_ABORTED;
}
Status = gBS->UninstallMultipleProtocolInterfaces (
ImageHandle,
&gEfiDriverBindingProtocolGuid,
&gDebugPortDevice->DriverBindingInterface,
&gEfiComponentNameProtocolGuid,
&gDebugPortDevice->ComponentNameInterface,
NULL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Clean up allocations
//
if (gDebugPortDevice->DebugPortVariable != NULL) {
gBS->FreePool (gDebugPortDevice->DebugPortVariable);
}
gBS->FreePool (gDebugPortDevice);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,26 @@
/*++
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:
DebugPort.dxs
Abstract:
Dependency expression source file.
--*/
#include <AutoGen.h>
#include <DxeDepex.h>
DEPENDENCY_START
TRUE
DEPENDENCY_END

View File

@@ -0,0 +1,172 @@
/*++
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:
DebugPort.h
Abstract:
Definitions and prototypes for DebugPort driver
--*/
#ifndef __DEBUGPORT_H__
#define __DEBUGPORT_H__
//
// local type definitions
//
#define DEBUGPORT_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('D', 'B', 'G', 'P')
//
// Device structure used by driver
//
typedef struct {
UINT32 Signature;
EFI_HANDLE DriverBindingHandle;
EFI_HANDLE DebugPortDeviceHandle;
VOID *DebugPortVariable;
EFI_DRIVER_BINDING_PROTOCOL DriverBindingInterface;
EFI_COMPONENT_NAME_PROTOCOL ComponentNameInterface;
EFI_DEVICE_PATH_PROTOCOL *DebugPortDevicePath;
EFI_DEBUGPORT_PROTOCOL DebugPortInterface;
EFI_HANDLE SerialIoDeviceHandle;
EFI_SERIAL_IO_PROTOCOL *SerialIoBinding;
UINT64 BaudRate;
UINT32 ReceiveFifoDepth;
UINT32 Timeout;
EFI_PARITY_TYPE Parity;
UINT8 DataBits;
EFI_STOP_BITS_TYPE StopBits;
} DEBUGPORT_DEVICE;
#define DEBUGPORT_DEVICE_FROM_THIS(a) CR (a, DEBUGPORT_DEVICE, DebugPortInterface, DEBUGPORT_DEVICE_SIGNATURE)
#define EFI_ACPI_PC_COMPORT_HID EISA_PNP_ID (0x0500)
#define EFI_ACPI_16550UART_HID EISA_PNP_ID (0x0501)
#define DEBUGPORT_UART_DEFAULT_BAUDRATE 115200
#define DEBUGPORT_UART_DEFAULT_PARITY 0
#define DEBUGPORT_UART_DEFAULT_FIFO_DEPTH 16
#define DEBUGPORT_UART_DEFAULT_TIMEOUT 50000 // 5 ms
#define DEBUGPORT_UART_DEFAULT_DATA_BITS 8
#define DEBUGPORT_UART_DEFAULT_STOP_BITS 1
#define DEBUGPORT_DRIVER_VERSION 1
#define EfiIsUartDevicePath(dp) (DevicePathType (dp) == MESSAGING_DEVICE_PATH && DevicePathSubType (dp) == MSG_UART_DP)
//
// globals
//
extern DEBUGPORT_DEVICE *gDebugPortDevice;
//
// Driver binding interface functions...
//
EFI_STATUS
DebugPortEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
;
EFI_STATUS
EFIAPI
DebugPortSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
DebugPortStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
;
EFI_STATUS
EFIAPI
DebugPortStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
;
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
DebugPortComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
;
EFI_STATUS
EFIAPI
DebugPortComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
;
//
// DebugPort member functions
//
EFI_STATUS
EFIAPI
DebugPortReset (
IN EFI_DEBUGPORT_PROTOCOL *This
)
;
EFI_STATUS
EFIAPI
DebugPortRead (
IN EFI_DEBUGPORT_PROTOCOL *This,
IN UINT32 Timeout,
IN OUT UINTN *BufferSize,
IN VOID *Buffer
)
;
EFI_STATUS
EFIAPI
DebugPortWrite (
IN EFI_DEBUGPORT_PROTOCOL *This,
IN UINT32 Timeout,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
;
EFI_STATUS
EFIAPI
DebugPortPoll (
IN EFI_DEBUGPORT_PROTOCOL *This
)
;
#endif

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>DebugPort</BaseName>
<Guid>73E9457A-CEA1-4917-9A9C-9F1F0F0FD322</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>UefiRuntimeServicesTableLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>UefiDriverModelLib</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>BaseLib</Library>
<Library>DxeMemoryAllocationLib</Library>
<Library>UefiDevicePathLib</Library>
</Libraries>
<BuildOptions ToolChain="MSFT">
<ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
</BuildOptions>
</ModuleBuildDescription>

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>DebugPort</BaseName>
<ModuleType>UEFI_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>73E9457A-CEA1-4917-9A9C-9F1F0F0FD322</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>DebugPort.h</Filename>
<Filename>DebugPort.c</Filename>
<Filename>ComponentName.c</Filename>
<Filename>DebugPort.dxs</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
<PackageName>EdkModulePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="BY_START">DebugPort</Protocol>
<Protocol Usage="BY_START">DevicePath</Protocol>
<Protocol Usage="TO_START">SerialIo</Protocol>
</Protocols>
<Variables>
<Variable Usage="SOMETIMES_CONSUMED">
<String>DEBUGPORT</String>
<Guid>0xEBA4E8D2, 0x3858, 0x41EC, 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0</Guid>
</Variable>
</Variables>
<Externs>
<Extern>
<ModuleEntryPoint>InitializeDebugPortDriver</ModuleEntryPoint>
<ModuleUnloadImage>ImageUnloadHandler</ModuleUnloadImage>
</Extern>
<Extern>
<DriverBinding>gDebugPortDriverBinding</DriverBinding>
<ComponentName>gDebugPortComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="DebugPort"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Debugger\Debugport\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="DebugPort">
<GenBuild baseName="DebugPort" mbdFilename="${MODULE_DIR}\DebugPort.mbd" msaFilename="${MODULE_DIR}\DebugPort.msa"/>
</target>
<target depends="DebugPort_clean" name="clean"/>
<target depends="DebugPort_cleanall" name="cleanall"/>
<target name="DebugPort_clean">
<OutputDirSetup baseName="DebugPort" mbdFilename="${MODULE_DIR}\DebugPort.mbd" msaFilename="${MODULE_DIR}\DebugPort.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DebugPort_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DebugPort_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="DebugPort_cleanall">
<OutputDirSetup baseName="DebugPort" mbdFilename="${MODULE_DIR}\DebugPort.mbd" msaFilename="${MODULE_DIR}\DebugPort.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DebugPort_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DebugPort_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**DebugPort*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,160 @@
/*++
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 "DiskIo.h"
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
DiskIoComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
DiskIoComponentNameGetControllerName (
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 gDiskIoComponentName = {
DiskIoComponentNameGetDriverName,
DiskIoComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mDiskIoDriverNameTable[] = {
{
"eng",
(CHAR16 *)L"Generic Disk I/O Driver"
},
{
NULL,
NULL
}
};
EFI_STATUS
EFIAPI
DiskIoComponentNameGetDriverName (
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,
gDiskIoComponentName.SupportedLanguages,
mDiskIoDriverNameTable,
DriverName
);
}
EFI_STATUS
EFIAPI
DiskIoComponentNameGetControllerName (
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;
}

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>DiskIo</BaseName>
<Guid>6B38F7B4-AD98-40e9-9093-ACA2B5A253C4</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>UefiDriverModelLib</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>BaseLib</Library>
<Library>DxeMemoryAllocationLib</Library>
</Libraries>
</ModuleBuildDescription>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>DiskIo</BaseName>
<ModuleType>UEFI_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>6B38F7B4-AD98-40e9-9093-ACA2B5A253C4</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>diskio.c</Filename>
<Filename>diskio.h</Filename>
<Filename>ComponentName.c</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="TO_START">BlockIo</Protocol>
<Protocol Usage="BY_START">DiskIo</Protocol>
</Protocols>
<Externs>
<Extern>
<ModuleEntryPoint></ModuleEntryPoint>
</Extern>
<Extern>
<DriverBinding>gDiskIoDriverBinding</DriverBinding>
<ComponentName>gDiskIoComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="DiskIo"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Disk\DiskIo\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="DiskIo">
<GenBuild baseName="DiskIo" mbdFilename="${MODULE_DIR}\DiskIo.mbd" msaFilename="${MODULE_DIR}\DiskIo.msa"/>
</target>
<target depends="DiskIo_clean" name="clean"/>
<target depends="DiskIo_cleanall" name="cleanall"/>
<target name="DiskIo_clean">
<OutputDirSetup baseName="DiskIo" mbdFilename="${MODULE_DIR}\DiskIo.mbd" msaFilename="${MODULE_DIR}\DiskIo.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DiskIo_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DiskIo_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="DiskIo_cleanall">
<OutputDirSetup baseName="DiskIo" mbdFilename="${MODULE_DIR}\DiskIo.mbd" msaFilename="${MODULE_DIR}\DiskIo.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DiskIo_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DiskIo_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**DiskIo*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,876 @@
/*++
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:
DiskIo.c
Abstract:
DiskIo driver that layers it's self on every Block IO protocol in the system.
DiskIo converts a block oriented device to a byte oriented device.
ReadDisk may have to do reads that are not aligned on sector boundaries.
There are three cases:
UnderRun - The first byte is not on a sector boundary or the read request is
less than a sector in length.
Aligned - A read of N contiguous sectors.
OverRun - The last byte is not on a sector boundary.
--*/
#include "DiskIo.h"
//
// Prototypes
// Driver model protocol interface
//
EFI_STATUS
EFIAPI
DiskIoDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
DiskIoDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
DiskIoDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
//
// Disk I/O Protocol Interface
//
EFI_STATUS
EFIAPI
DiskIoReadDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
DiskIoWriteDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
IN VOID *Buffer
);
EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding = {
DiskIoDriverBindingSupported,
DiskIoDriverBindingStart,
DiskIoDriverBindingStop,
0x10,
NULL,
NULL
};
DISK_IO_PRIVATE_DATA gDiskIoPrivateDataTemplate = {
DISK_IO_PRIVATE_DATA_SIGNATURE,
{
EFI_DISK_IO_PROTOCOL_REVISION,
DiskIoReadDisk,
DiskIoWriteDisk
},
NULL
};
EFI_STATUS
EFIAPI
DiskIoDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
/*++
Routine Description:
Test to see if this driver supports ControllerHandle. Any ControllerHandle
than contains a BlockIo protocol can be supported.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to test.
RemainingDevicePath - Not used.
Returns:
EFI_SUCCESS - This driver supports this device.
EFI_ALREADY_STARTED - This driver is already running on this device.
other - This driver does not support this device.
--*/
{
EFI_STATUS Status;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
/*
DEBUG_CODE_BEGIN
UINT32 Bar;
UINT32 Foo;
UINT32 HotPlug;
//
// Get TYPE 0
//
Bar = PcdGet32 (PciExpressBaseVersion);
DEBUG ((EFI_D_ERROR, "PciExpressBaseVersion = %08x\n", Bar));
//
// Get TYPE 1
//
Foo = PcdGet32 (PciExpressBaseAddress);
DEBUG ((EFI_D_ERROR, "PciExpressBaseAddress = %08x\n", Foo));
//
// Set TYPE 1
//
PcdSet32 (PciExpressBaseAddress, Foo + 1);
//
// Get TYPE 1
//
Foo = PcdGet32 (PciExpressBaseAddress);
DEBUG ((EFI_D_ERROR, "PciExpressBaseAddress = %08x\n", Foo));
//
// Get TYPE 2
//
HotPlug = PcdGet32 (PciExpressBaseHotPlug);
DEBUG ((EFI_D_ERROR, "PciExpressHotPlug = %08x\n", HotPlug));
//
// Set TYPE 1
//
PcdSet32 (PciExpressBaseHotPlug, HotPlug + 1);
//
// Get TYPE 1
//
HotPlug = PcdGet32 (PciExpressBaseHotPlug);
DEBUG ((EFI_D_ERROR, "PciExpressHotPlug = %08x\n", HotPlug));
DEBUG_CODE_END
DEBUG_CODE_BEGIN
UINT32 MyVariable;
if (ControllerHandle == NULL) {
MyVariable = 32 * (UINTN)This;
ControllerHandle = (EFI_HANDLE)MyVariable;
DEBUG ((EFI_D_ERROR, "DiskIoSupported-DebugCode. MyVariable = %08x\n", MyVariable));
ASSERT (MyVariable != 32);
}
DEBUG_CODE_END
*/
DEBUG ((EFI_D_ERROR, "DiskIoSupported\n"));
// Io8Or (0x400, 1);
// Io8And (0x400, 1);
// Io8AndThenOr (0x400, 1, 2);
// Mmio8Or (0xa0000000, 1);
// Mmio8And (0xa0000000, 1);
// Mmio8AndThenOr (0xa0000000, 1, 2);
/*
PciRead8 (PCI_LIB_ADDRESS (1,2,3,4));
PciRead16 (PCI_LIB_ADDRESS (1,2,3,4));
PciRead32 (PCI_LIB_ADDRESS (1,2,3,4));
PciWrite8 (PCI_LIB_ADDRESS (1,2,3,4), 0xAA);
PciWrite16 (PCI_LIB_ADDRESS (1,2,3,4), 0xAA55);
PciWrite32 (PCI_LIB_ADDRESS (1,2,3,4), 0xAA55A55A);
Pci8Or (PCI_LIB_ADDRESS (1,2,3,4), 0xAA);
Pci8And (PCI_LIB_ADDRESS (1,2,3,4), 0x55);
Pci8AndThenOr (PCI_LIB_ADDRESS (1,2,3,4), 0xAA, 0x55);
Pci16Or (PCI_LIB_ADDRESS (1,2,3,4), 0xAA55);
Pci16And (PCI_LIB_ADDRESS (1,2,3,4), 0x55AA);
Pci16AndThenOr (PCI_LIB_ADDRESS (1,2,3,4), 0xAA55, 0x55AA);
Pci32Or (PCI_LIB_ADDRESS (1,2,3,4), 0xAA55A55A);
Pci32And (PCI_LIB_ADDRESS (1,2,3,4), 0x55AA5AA5);
Pci32AndThenOr (PCI_LIB_ADDRESS (1,2,3,4), 0xAA555AA5, 0x55AAA55A);
*/
//
// Open the IO Abstraction(s) needed to perform the supported test.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close the I/O Abstraction(s) used to perform the supported test.
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DiskIoDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
/*++
Routine Description:
Start this driver on ControllerHandle by opening a Block IO protocol and
installing a Disk IO protocol on ControllerHandle.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to bind driver to.
RemainingDevicePath - Not used, always produce all possible children.
Returns:
EFI_SUCCESS - This driver is added to ControllerHandle.
EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
other - This driver does not support this device.
--*/
{
EFI_STATUS Status;
DISK_IO_PRIVATE_DATA *Private;
Private = NULL;
DEBUG ((EFI_D_ERROR, "DiskIoStart\n"));
//
// Connect to the Block IO interface on ControllerHandle.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &gDiskIoPrivateDataTemplate.BlockIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Initialize the Disk IO device instance.
//
Private = AllocateCopyPool (sizeof (DISK_IO_PRIVATE_DATA), &gDiskIoPrivateDataTemplate);
if (Private == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
//
// Install protocol interfaces for the Disk IO device.
//
Status = gBS->InstallProtocolInterface (
&ControllerHandle,
&gEfiDiskIoProtocolGuid,
EFI_NATIVE_INTERFACE,
&Private->DiskIo
);
ErrorExit:
if (EFI_ERROR (Status)) {
if (Private != NULL) {
gBS->FreePool (Private);
}
gBS->CloseProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
}
return Status;
}
EFI_STATUS
EFIAPI
DiskIoDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop this driver on ControllerHandle by removing Disk IO protocol and closing
the Block IO protocol on ControllerHandle.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to stop driver on.
NumberOfChildren - Not used.
ChildHandleBuffer - Not used.
Returns:
EFI_SUCCESS - This driver is removed ControllerHandle.
other - This driver was not removed from this device.
EFI_UNSUPPORTED
--*/
{
EFI_STATUS Status;
EFI_DISK_IO_PROTOCOL *DiskIo;
DISK_IO_PRIVATE_DATA *Private;
DEBUG ((EFI_D_ERROR, "DiskIoStop\n"));
//
// Get our context back.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Private = DISK_IO_PRIVATE_DATA_FROM_THIS (DiskIo);
Status = gBS->UninstallProtocolInterface (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
&Private->DiskIo
);
if (!EFI_ERROR (Status)) {
Status = gBS->CloseProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
}
if (!EFI_ERROR (Status)) {
gBS->FreePool (Private);
}
return Status;
}
EFI_STATUS
EFIAPI
DiskIoReadDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Read BufferSize bytes from Offset into Buffer.
Reads may support reads that are not aligned on
sector boundaries. There are three cases:
UnderRun - The first byte is not on a sector boundary or the read request is
less than a sector in length.
Aligned - A read of N contiguous sectors.
OverRun - The last byte is not on a sector boundary.
Arguments:
This - Protocol instance pointer.
MediaId - Id of the media, changes every time the media is replaced.
Offset - The starting byte offset to read from.
BufferSize - Size of Buffer.
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_CHNAGED - The MediaId does not matched the current device.
EFI_INVALID_PARAMETER - The read request contains device addresses that are not
valid for the device.
EFI_OUT_OF_RESOURCES
--*/
{
EFI_STATUS Status;
DISK_IO_PRIVATE_DATA *Private;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO_MEDIA *Media;
UINT32 BlockSize;
UINT64 Lba;
UINT64 OverRunLba;
UINT32 UnderRun;
UINT32 OverRun;
BOOLEAN TransactionComplete;
UINTN WorkingBufferSize;
UINT8 *WorkingBuffer;
UINTN Length;
UINT8 *Data;
UINT8 *PreData;
UINTN IsBufferAligned;
UINTN DataBufferSize;
BOOLEAN LastRead;
DEBUG ((EFI_D_ERROR, "DiskIoReadDisk\n"));
Private = DISK_IO_PRIVATE_DATA_FROM_THIS (This);
BlockIo = Private->BlockIo;
Media = BlockIo->Media;
BlockSize = Media->BlockSize;
if (Media->MediaId != MediaId) {
return EFI_MEDIA_CHANGED;
}
WorkingBuffer = Buffer;
WorkingBufferSize = BufferSize;
//
// Allocate a temporary buffer for operation
//
DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;
if (Media->IoAlign > 1) {
PreData = AllocatePool (DataBufferSize + Media->IoAlign);
Data = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;
} else {
PreData = AllocatePool (DataBufferSize);
Data = PreData;
}
if (PreData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Lba = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
Length = BlockSize - UnderRun;
TransactionComplete = FALSE;
Status = EFI_SUCCESS;
if (UnderRun != 0) {
//
// Offset starts in the middle of an Lba, so read the entire block.
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
if (Length > BufferSize) {
Length = BufferSize;
TransactionComplete = TRUE;
}
CopyMem (WorkingBuffer, Data + UnderRun, Length);
WorkingBuffer += Length;
WorkingBufferSize -= Length;
if (WorkingBufferSize == 0) {
goto Done;
}
Lba += 1;
}
OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);
if (!TransactionComplete && WorkingBufferSize >= BlockSize) {
//
// If the DiskIo maps directly to a BlockIo device do the read.
//
if (OverRun != 0) {
WorkingBufferSize -= OverRun;
}
//
// Check buffer alignment
//
IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);
if (Media->IoAlign <= 1 || IsBufferAligned == 0) {
//
// Alignment is satisfied, so read them together
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
WorkingBufferSize,
WorkingBuffer
);
if (EFI_ERROR (Status)) {
goto Done;
}
WorkingBuffer += WorkingBufferSize;
} else {
//
// Use the allocated buffer instead of the original buffer
// to avoid alignment issue.
// Here, the allocated buffer (8-byte align) can satisfy the alignment
//
LastRead = FALSE;
do {
if (WorkingBufferSize <= DataBufferSize) {
//
// It is the last calling to readblocks in this loop
//
DataBufferSize = WorkingBufferSize;
LastRead = TRUE;
}
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
DataBufferSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
CopyMem (WorkingBuffer, Data, DataBufferSize);
WorkingBufferSize -= DataBufferSize;
WorkingBuffer += DataBufferSize;
Lba += DATA_BUFFER_BLOCK_NUM;
} while (!LastRead);
}
}
if (!TransactionComplete && OverRun != 0) {
//
// Last read is not a complete block.
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
OverRunLba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
CopyMem (WorkingBuffer, Data, OverRun);
}
Done:
if (PreData != NULL) {
gBS->FreePool (PreData);
}
return Status;
}
EFI_STATUS
EFIAPI
DiskIoWriteDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
IN VOID *Buffer
)
/*++
Routine Description:
Read BufferSize bytes from Offset into Buffer.
Writes may require a read modify write to support writes that are not
aligned on sector boundaries. There are three cases:
UnderRun - The first byte is not on a sector boundary or the write request
is less than a sector in length. Read modify write is required.
Aligned - A write of N contiguous sectors.
OverRun - The last byte is not on a sector boundary. Read modified write
required.
Arguments:
This - Protocol instance pointer.
MediaId - Id of the media, changes every time the media is replaced.
Offset - The starting byte offset to read from.
BufferSize - Size of Buffer.
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_INVALID_PARAMETER - The write request contains device addresses that are not
valid for the device.
EFI_OUT_OF_RESOURCES
--*/
{
EFI_STATUS Status;
DISK_IO_PRIVATE_DATA *Private;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO_MEDIA *Media;
UINT32 BlockSize;
UINT64 Lba;
UINT64 OverRunLba;
UINT32 UnderRun;
UINT32 OverRun;
BOOLEAN TransactionComplete;
UINTN WorkingBufferSize;
UINT8 *WorkingBuffer;
UINTN Length;
UINT8 *Data;
UINT8 *PreData;
UINTN IsBufferAligned;
UINTN DataBufferSize;
BOOLEAN LastWrite;
DEBUG ((EFI_D_ERROR, "DiskIoWriteDisk\n"));
Private = DISK_IO_PRIVATE_DATA_FROM_THIS (This);
BlockIo = Private->BlockIo;
Media = BlockIo->Media;
BlockSize = Media->BlockSize;
if (Media->ReadOnly) {
return EFI_WRITE_PROTECTED;
}
if (Media->MediaId != MediaId) {
return EFI_MEDIA_CHANGED;
}
DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;
if (Media->IoAlign > 1) {
PreData = AllocatePool (DataBufferSize + Media->IoAlign);
Data = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;
} else {
PreData = AllocatePool (DataBufferSize);
Data = PreData;
}
if (PreData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
WorkingBuffer = Buffer;
WorkingBufferSize = BufferSize;
Lba = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
Length = BlockSize - UnderRun;
TransactionComplete = FALSE;
Status = EFI_SUCCESS;
if (UnderRun != 0) {
//
// Offset starts in the middle of an Lba, so do read modify write.
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
if (Length > BufferSize) {
Length = BufferSize;
TransactionComplete = TRUE;
}
CopyMem (Data + UnderRun, WorkingBuffer, Length);
Status = BlockIo->WriteBlocks (
BlockIo,
MediaId,
Lba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
WorkingBuffer += Length;
WorkingBufferSize -= Length;
if (WorkingBufferSize == 0) {
goto Done;
}
Lba += 1;
}
OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);
if (!TransactionComplete && WorkingBufferSize >= BlockSize) {
//
// If the DiskIo maps directly to a BlockIo device do the write.
//
if (OverRun != 0) {
WorkingBufferSize -= OverRun;
}
//
// Check buffer alignment
//
IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);
if (Media->IoAlign <= 1 || IsBufferAligned == 0) {
//
// Alignment is satisfied, so write them together
//
Status = BlockIo->WriteBlocks (
BlockIo,
MediaId,
Lba,
WorkingBufferSize,
WorkingBuffer
);
if (EFI_ERROR (Status)) {
goto Done;
}
WorkingBuffer += WorkingBufferSize;
} else {
//
// The buffer parameter is not aligned with the request
// So use the allocated instead.
// It can fit almost all the cases.
//
LastWrite = FALSE;
do {
if (WorkingBufferSize <= DataBufferSize) {
//
// It is the last calling to writeblocks in this loop
//
DataBufferSize = WorkingBufferSize;
LastWrite = TRUE;
}
CopyMem (Data, WorkingBuffer, DataBufferSize);
Status = BlockIo->WriteBlocks (
BlockIo,
MediaId,
Lba,
DataBufferSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
WorkingBufferSize -= DataBufferSize;
WorkingBuffer += DataBufferSize;
Lba += DATA_BUFFER_BLOCK_NUM;
} while (!LastWrite);
}
}
if (!TransactionComplete && OverRun != 0) {
//
// Last bit is not a complete block, so do a read modify write.
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
OverRunLba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
CopyMem (Data, WorkingBuffer, OverRun);
Status = BlockIo->WriteBlocks (
BlockIo,
MediaId,
OverRunLba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
}
Done:
if (PreData != NULL) {
gBS->FreePool (PreData);
}
return Status;
}

View File

@@ -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:
DiskIo.h
Abstract:
Private Data definition for Disk IO driver
--*/
#ifndef _DISK_IO_H
#define _DISK_IO_H
#define DISK_IO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('d', 's', 'k', 'I')
#define DATA_BUFFER_BLOCK_NUM (64)
typedef struct {
UINTN Signature;
EFI_DISK_IO_PROTOCOL DiskIo;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
} DISK_IO_PRIVATE_DATA;
#define DISK_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DISK_IO_PRIVATE_DATA, DiskIo, DISK_IO_PRIVATE_DATA_SIGNATURE)
//
// Global Variables
//
extern EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gDiskIoComponentName;
#endif

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>DiskIoPartition</BaseName>
<Guid>854E153A-8AC8-40f4-A5A9-4C51F18CFB1B</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>BaseLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>UefiDriverModelLib</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>DxeMemoryAllocationLib</Library>
<Library>UefiDevicePathLib</Library>
</Libraries>
</ModuleBuildDescription>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>DiskIoPartition</BaseName>
<ModuleType>UEFI_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>854E153A-8AC8-40f4-A5A9-4C51F18CFB1B</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>..\..\DiskIo\Dxe\diskio.c</Filename>
<Filename>..\..\DiskIo\Dxe\diskio.h</Filename>
<Filename>..\..\DiskIo\Dxe\ComponentName.c</Filename>
<Filename>..\..\Partition\Dxe\Partition.h</Filename>
<Filename>..\..\Partition\Dxe\ElTorito.h</Filename>
<Filename>..\..\Partition\Dxe\Gpt.h</Filename>
<Filename>..\..\Partition\Dxe\Mbr.h</Filename>
<Filename>..\..\Partition\Dxe\Partition.c</Filename>
<Filename>..\..\Partition\Dxe\Eltorito.c</Filename>
<Filename>..\..\Partition\Dxe\Gpt.c</Filename>
<Filename>..\..\Partition\Dxe\Mbr.c</Filename>
<Filename>..\..\Partition\Dxe\ComponentName.c</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="TO_START">BlockIo</Protocol>
<Protocol Usage="TO_START">DiskIo</Protocol>
<Protocol Usage="TO_START">DevicePath</Protocol>
</Protocols>
<Guids>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>PartTypeSystemPart</C_Name>
</GuidEntry>
<GuidEntry Usage="ALWAYS_CONSUMED">
<C_Name>PartTypeUnused</C_Name>
</GuidEntry>
</Guids>
<Externs>
<Extern>
<ModuleEntryPoint></ModuleEntryPoint>
</Extern>
<Extern>
<DriverBinding>gPartitionDriverBinding</DriverBinding>
<ComponentName>gPartitionComponentName</ComponentName>
</Extern>
<Extern>
<DriverBinding>gDiskIoDriverBinding</DriverBinding>
<ComponentName>gDiskIoComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="DiskIoPartition"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Disk\DiskIoPartition\dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="DiskIoPartition">
<GenBuild baseName="DiskIoPartition" mbdFilename="${MODULE_DIR}\DiskIoPartition.mbd" msaFilename="${MODULE_DIR}\DiskIoPartition.msa"/>
</target>
<target depends="DiskIoPartition_clean" name="clean"/>
<target depends="DiskIoPartition_cleanall" name="cleanall"/>
<target name="DiskIoPartition_clean">
<OutputDirSetup baseName="DiskIoPartition" mbdFilename="${MODULE_DIR}\DiskIoPartition.mbd" msaFilename="${MODULE_DIR}\DiskIoPartition.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DiskIoPartition_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DiskIoPartition_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="DiskIoPartition_cleanall">
<OutputDirSetup baseName="DiskIoPartition" mbdFilename="${MODULE_DIR}\DiskIoPartition.mbd" msaFilename="${MODULE_DIR}\DiskIoPartition.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\DiskIoPartition_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\DiskIoPartition_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**DiskIoPartition*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,160 @@
/*++
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 "Partition.h"
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
PartitionComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
PartitionComponentNameGetControllerName (
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 gPartitionComponentName = {
PartitionComponentNameGetDriverName,
PartitionComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mPartitionDriverNameTable[] = {
{
"eng",
(CHAR16 *)L"Partition Driver(MBR/GPT/El Torito)"
},
{
NULL,
NULL
}
};
EFI_STATUS
EFIAPI
PartitionComponentNameGetDriverName (
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,
gPartitionComponentName.SupportedLanguages,
mPartitionDriverNameTable,
DriverName
);
}
EFI_STATUS
EFIAPI
PartitionComponentNameGetControllerName (
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;
}

View File

@@ -0,0 +1,277 @@
/*++
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:
ElTorito.c
Abstract:
Decode an El Torito formatted CD-ROM
Revision History
--*/
#include "Partition.h"
#include "ElTorito.h"
BOOLEAN
PartitionInstallElToritoChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
/*++
Routine Description:
Install child handles if the Handle supports El Torito format.
Arguments:
This - Calling context.
Handle - Parent Handle
DiskIo - Parent DiskIo interface
BlockIo - Parent BlockIo interface
DevicePath - Parent Device Path
Returns:
TRUE - some child handle(s) was added
FALSE - no child handle was added
--*/
{
EFI_STATUS Status;
UINT32 VolDescriptorLba;
UINT32 Lba;
EFI_BLOCK_IO_MEDIA *Media;
CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
ELTORITO_CATALOG *Catalog;
UINTN Check;
UINTN Index;
UINTN BootEntry;
UINTN MaxIndex;
UINT16 *CheckBuffer;
CDROM_DEVICE_PATH CdDev;
UINT32 SubBlockSize;
UINT32 SectorCount;
BOOLEAN Found;
UINT32 VolSpaceSize;
Found = FALSE;
Media = BlockIo->Media;
VolSpaceSize = 0;
//
// CD_ROM has the fixed block size as 2048 bytes
//
if (Media->BlockSize != 2048) {
return FALSE;
}
VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);
if (VolDescriptor == NULL) {
return FALSE;
}
Catalog = (ELTORITO_CATALOG *) VolDescriptor;
//
// the ISO-9660 volume descriptor starts at 32k on the media
// and CD_ROM has the fixed block size as 2048 bytes, so...
//
//
// ((16*2048) / Media->BlockSize) - 1;
//
VolDescriptorLba = 15;
//
// Loop: handle one volume descriptor per time
//
while (TRUE) {
VolDescriptorLba += 1;
if (VolDescriptorLba > Media->LastBlock) {
//
// We are pointing past the end of the device so exit
//
break;
}
Status = BlockIo->ReadBlocks (
BlockIo,
Media->MediaId,
VolDescriptorLba,
Media->BlockSize,
VolDescriptor
);
if (EFI_ERROR (Status)) {
break;
}
//
// Check for valid volume descriptor signature
//
if (VolDescriptor->Type == CDVOL_TYPE_END ||
CompareMem (VolDescriptor->Id, CDVOL_ID, sizeof (VolDescriptor->Id)) != 0
) {
//
// end of Volume descriptor list
//
break;
}
//
// Read the Volume Space Size from Primary Volume Descriptor 81-88 byte,
// the 32-bit numerical values is stored in Both-byte orders
//
if (VolDescriptor->Type == CDVOL_TYPE_CODED) {
VolSpaceSize = VolDescriptor->VolSpaceSize[1];
}
//
// Is it an El Torito volume descriptor?
//
if (CompareMem (VolDescriptor->SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) {
continue;
}
//
// Read in the boot El Torito boot catalog
//
Lba = UNPACK_INT32 (VolDescriptor->EltCatalog);
if (Lba > Media->LastBlock) {
continue;
}
Status = BlockIo->ReadBlocks (
BlockIo,
Media->MediaId,
Lba,
Media->BlockSize,
Catalog
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status));
continue;
}
//
// We don't care too much about the Catalog header's contents, but we do want
// to make sure it looks like a Catalog header
//
if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {
DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header IDs not correct\n"));
continue;
}
Check = 0;
CheckBuffer = (UINT16 *) Catalog;
for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {
Check += CheckBuffer[Index];
}
if (Check & 0xFFFF) {
DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n"));
continue;
}
MaxIndex = Media->BlockSize / sizeof (ELTORITO_CATALOG);
for (Index = 1, BootEntry = 1; Index < MaxIndex; Index += 1) {
//
// Next entry
//
Catalog += 1;
//
// Check this entry
//
if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {
continue;
}
SubBlockSize = 512;
SectorCount = Catalog->Boot.SectorCount;
switch (Catalog->Boot.MediaType) {
case ELTORITO_NO_EMULATION:
SubBlockSize = Media->BlockSize;
break;
case ELTORITO_HARD_DISK:
break;
case ELTORITO_12_DISKETTE:
SectorCount = 0x50 * 0x02 * 0x0F;
break;
case ELTORITO_14_DISKETTE:
SectorCount = 0x50 * 0x02 * 0x12;
break;
case ELTORITO_28_DISKETTE:
SectorCount = 0x50 * 0x02 * 0x24;
break;
default:
DEBUG ((EFI_D_INIT, "EltCheckDevice: unsupported El Torito boot media type %x\n", Catalog->Boot.MediaType));
SectorCount = 0;
SubBlockSize = Media->BlockSize;
break;
}
//
// Create child device handle
//
CdDev.Header.Type = MEDIA_DEVICE_PATH;
CdDev.Header.SubType = MEDIA_CDROM_DP;
SetDevicePathNodeLength (&CdDev.Header, sizeof (CdDev));
if (Index == 1) {
//
// This is the initial/default entry
//
BootEntry = 0;
}
CdDev.BootEntry = (UINT32) BootEntry;
BootEntry++;
CdDev.PartitionStart = Catalog->Boot.Lba;
if (SectorCount < 2) {
CdDev.PartitionSize = VolSpaceSize;
} else {
CdDev.PartitionSize = DivU64x32 (
MultU64x32 (
SectorCount,
SubBlockSize
) + Media->BlockSize - 1,
Media->BlockSize
);
}
Status = PartitionInstallChildHandle (
This,
Handle,
DiskIo,
BlockIo,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &CdDev,
Catalog->Boot.Lba,
Catalog->Boot.Lba + CdDev.PartitionSize - 1,
SubBlockSize,
FALSE
);
if (!EFI_ERROR (Status)) {
Found = TRUE;
}
}
}
gBS->FreePool (VolDescriptor);
return Found;
}

View File

@@ -0,0 +1,130 @@
/*++
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:
ElTorito.h
Abstract:
Data Structures required for detecting ElTorito Partitions
Revision History
--*/
#ifndef _ELTORITO_H_
#define _ELTORITO_H_
#pragma pack(1)
//
// CDROM_VOLUME_DESCRIPTOR.Types
//
#define CDVOL_TYPE_STANDARD 0x0
#define CDVOL_TYPE_CODED 0x1
#define CDVOL_TYPE_END 0xFF
//
// CDROM_VOLUME_DESCRIPTOR.Id
//
#define CDVOL_ID "CD001"
//
// CDROM_VOLUME_DESCRIPTOR.SystemId
//
#define CDVOL_ELTORITO_ID "EL TORITO SPECIFICATION"
//
// Indicator types
//
#define ELTORITO_ID_CATALOG 0x01
#define ELTORITO_ID_SECTION_BOOTABLE 0x88
#define ELTORITO_ID_SECTION_NOT_BOOTABLE 0x00
#define ELTORITO_ID_SECTION_HEADER 0x90
#define ELTORITO_ID_SECTION_HEADER_FINAL 0x91
//
// ELTORITO_CATALOG.Boot.MediaTypes
//
#define ELTORITO_NO_EMULATION 0x00
#define ELTORITO_12_DISKETTE 0x01
#define ELTORITO_14_DISKETTE 0x02
#define ELTORITO_28_DISKETTE 0x03
#define ELTORITO_HARD_DISK 0x04
//
// El Torito Volume Descriptor
// Note that the CDROM_VOLUME_DESCRIPTOR does not match the ISO-9660
// descriptor. For some reason descriptor used by El Torito is
// different, but they start the same. The El Torito descriptor
// is left shifted 1 byte starting with the SystemId. (Note this
// causes the field to get unaligned)
//
typedef struct {
UINT8 Type;
CHAR8 Id[5]; // CD001
UINT8 Version;
CHAR8 SystemId[26];
CHAR8 Unused[38];
UINT8 EltCatalog[4];
CHAR8 Unused2[5];
UINT32 VolSpaceSize[2];
} CDROM_VOLUME_DESCRIPTOR;
//
// Catalog Entry
//
typedef union {
struct {
CHAR8 Reserved[0x20];
} Unknown;
//
// Catalog validation entry (Catalog header)
//
struct {
UINT8 Indicator;
UINT8 PlatformId;
UINT16 Reserved;
CHAR8 ManufacId[24];
UINT16 Checksum;
UINT16 Id55AA;
} Catalog;
//
// Initial/Default Entry or Section Entry
//
struct {
UINT8 Indicator;
UINT8 MediaType : 4;
UINT8 Reserved1 : 4;
UINT16 LoadSegment;
UINT8 SystemType;
UINT8 Reserved2;
UINT16 SectorCount;
UINT32 Lba;
} Boot;
//
// Section Header Entry
//
struct {
UINT8 Indicator;
UINT8 PlatformId;
UINT16 SectionEntries;
CHAR8 Id[28];
} Section;
} ELTORITO_CATALOG;
#pragma pack()
#endif

View File

@@ -0,0 +1,768 @@
/*++
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:
Gpt.c
Abstract:
Decode a hard disk partitioned with the GPT scheme in the EFI 1.0
specification.
--*/
#include "Partition.h"
#include "Gpt.h"
#include "Mbr.h"
BOOLEAN
PartitionValidGptTable (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_LBA Lba,
OUT EFI_PARTITION_TABLE_HEADER *PartHeader
);
BOOLEAN
PartitionCheckGptEntryArrayCRC (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_PARTITION_TABLE_HEADER *PartHeader
);
BOOLEAN
PartitionRestoreGptTable (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_PARTITION_TABLE_HEADER *PartHeader
);
VOID
PartitionCheckGptEntry (
IN EFI_PARTITION_TABLE_HEADER *PartHeader,
IN EFI_PARTITION_ENTRY *PartEntry,
OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
);
BOOLEAN
PartitionCheckCrcAltSize (
IN UINTN MaxSize,
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
);
BOOLEAN
PartitionCheckCrc (
IN UINTN MaxSize,
IN OUT EFI_TABLE_HEADER *Hdr
);
VOID
PartitionSetCrcAltSize (
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
);
VOID
PartitionSetCrc (
IN OUT EFI_TABLE_HEADER *Hdr
);
BOOLEAN
PartitionInstallGptChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
/*++
Routine Description:
Install child handles if the Handle supports GPT partition structure.
Arguments:
This - Calling context.
Handle - Parent Handle
DiskIo - Parent DiskIo interface
BlockIo - Parent BlockIo interface
DevicePath - Parent Device Path
Returns:
TRUE - Valid GPT disk
FALSE - Not a valid GPT disk
--*/
{
EFI_STATUS Status;
UINT32 BlockSize;
EFI_LBA LastBlock;
MASTER_BOOT_RECORD *ProtectiveMbr;
EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
EFI_PARTITION_TABLE_HEADER *BackupHeader;
EFI_PARTITION_ENTRY *PartEntry;
EFI_PARTITION_ENTRY_STATUS *PEntryStatus;
UINTN Index;
BOOLEAN GptValid;
HARDDRIVE_DEVICE_PATH HdDev;
ProtectiveMbr = NULL;
PrimaryHeader = NULL;
BackupHeader = NULL;
PartEntry = NULL;
PEntryStatus = NULL;
BlockSize = BlockIo->Media->BlockSize;
LastBlock = BlockIo->Media->LastBlock;
DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));
DEBUG ((EFI_D_INFO, " LastBlock : %x \n", LastBlock));
GptValid = FALSE;
//
// Allocate a buffer for the Protective MBR
//
ProtectiveMbr = AllocatePool (BlockSize);
if (ProtectiveMbr == NULL) {
return FALSE;
}
//
// Read the Protective MBR from LBA #0
//
Status = BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
0,
BlockIo->Media->BlockSize,
ProtectiveMbr
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Verify that the Protective MBR is valid
//
if (ProtectiveMbr->Partition[0].BootIndicator != 0x00 ||
ProtectiveMbr->Partition[0].OSIndicator != 0xEE ||
UNPACK_UINT32 (ProtectiveMbr->Partition[0].StartingLBA) != 1
) {
goto Done;
}
//
// Allocate the GPT structures
//
PrimaryHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
if (PrimaryHeader == NULL) {
goto Done;
}
BackupHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
if (BackupHeader == NULL) {
goto Done;
}
//
// Check primary and backup partition tables
//
if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) {
DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n"));
if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) {
DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n"));
goto Done;
} else {
DEBUG ((EFI_D_INFO, " Valid backup partition table\n"));
DEBUG ((EFI_D_INFO, " Restore primary partition table by the backup\n"));
if (!PartitionRestoreGptTable (BlockIo, DiskIo, BackupHeader)) {
DEBUG ((EFI_D_INFO, " Restore primary partition table error\n"));
}
if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) {
DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
}
}
} else if (!PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
DEBUG ((EFI_D_INFO, " Valid primary and !Valid backup partition table\n"));
DEBUG ((EFI_D_INFO, " Restore backup partition table by the primary\n"));
if (!PartitionRestoreGptTable (BlockIo, DiskIo, PrimaryHeader)) {
DEBUG ((EFI_D_INFO, " Restore backup partition table error\n"));
}
if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
}
}
DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n"));
//
// Read the EFI Partition Entries
//
PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY));
if (PartEntry == NULL) {
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
goto Done;
}
Status = DiskIo->ReadDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),
PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
PartEntry
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, " Partition Entry ReadBlocks error\n"));
goto Done;
}
DEBUG ((EFI_D_INFO, " Partition entries read block success\n"));
DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));
PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));
if (PEntryStatus == NULL) {
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
goto Done;
}
//
// Check the integrity of partition entries
//
PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus);
//
// If we got this far the GPT layout of the disk is valid and we should return true
//
GptValid = TRUE;
//
// Create child device handles
//
for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
if (CompareGuid (&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||
PEntryStatus[Index].OutOfRange ||
PEntryStatus[Index].Overlap
) {
//
// Don't use null EFI Partition Entries or Invalid Partition Entries
//
continue;
}
ZeroMem (&HdDev, sizeof (HdDev));
HdDev.Header.Type = MEDIA_DEVICE_PATH;
HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
HdDev.PartitionNumber = (UINT32) Index + 1;
HdDev.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
HdDev.SignatureType = SIGNATURE_TYPE_GUID;
HdDev.PartitionStart = PartEntry[Index].StartingLBA;
HdDev.PartitionSize = PartEntry[Index].EndingLBA - PartEntry[Index].StartingLBA + 1;
CopyMem (HdDev.Signature, &PartEntry[Index].UniquePartitionGUID, sizeof (EFI_GUID));
DEBUG ((EFI_D_INFO, " Index : %d\n", Index));
DEBUG ((EFI_D_INFO, " Start LBA : %x\n", HdDev.PartitionStart));
DEBUG ((EFI_D_INFO, " End LBA : %x\n", PartEntry[Index].EndingLBA));
DEBUG ((EFI_D_INFO, " Partition size: %x\n", HdDev.PartitionSize));
DEBUG ((EFI_D_INFO, " Start : %x", MultU64x32 (PartEntry[Index].StartingLBA, BlockSize)));
DEBUG ((EFI_D_INFO, " End : %x\n", MultU64x32 (PartEntry[Index].EndingLBA, BlockSize)));
Status = PartitionInstallChildHandle (
This,
Handle,
DiskIo,
BlockIo,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
PartEntry[Index].StartingLBA,
PartEntry[Index].EndingLBA,
BlockSize,
CompareGuid(&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)
);
}
DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));
Done:
if (ProtectiveMbr != NULL) {
gBS->FreePool (ProtectiveMbr);
}
if (PrimaryHeader != NULL) {
gBS->FreePool (PrimaryHeader);
}
if (BackupHeader != NULL) {
gBS->FreePool (BackupHeader);
}
if (PartEntry != NULL) {
gBS->FreePool (PartEntry);
}
if (PEntryStatus != NULL) {
gBS->FreePool (PEntryStatus);
}
return GptValid;
}
BOOLEAN
PartitionValidGptTable (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_LBA Lba,
OUT EFI_PARTITION_TABLE_HEADER *PartHeader
)
/*++
Routine Description:
Check if the GPT partition table is valid
Arguments:
BlockIo - Parent BlockIo interface
DiskIo - Disk Io protocol.
Lba - The starting Lba of the Partition Table
PartHeader - Stores the partition table that is read
Returns:
TRUE - The partition table is valid
FALSE - The partition table is not valid
--*/
{
EFI_STATUS Status;
UINT32 BlockSize;
EFI_PARTITION_TABLE_HEADER *PartHdr;
BlockSize = BlockIo->Media->BlockSize;
PartHdr = AllocateZeroPool (BlockSize);
if (PartHdr == NULL) {
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
return FALSE;
}
//
// Read the EFI Partition Table Header
//
Status = BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
Lba,
BlockSize,
PartHdr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (PartHdr);
return FALSE;
}
if (CompareMem (&PartHdr->Header.Signature, EFI_PTAB_HEADER_ID, sizeof (UINT64)) != 0 ||
!PartitionCheckCrc (BlockSize, &PartHdr->Header) ||
PartHdr->MyLBA != Lba
) {
DEBUG ((EFI_D_INFO, " !Valid efi partition table header\n"));
gBS->FreePool (PartHdr);
return FALSE;
}
CopyMem (PartHeader, PartHdr, sizeof (EFI_PARTITION_TABLE_HEADER));
if (!PartitionCheckGptEntryArrayCRC (BlockIo, DiskIo, PartHeader)) {
gBS->FreePool (PartHdr);
return FALSE;
}
DEBUG ((EFI_D_INFO, " Valid efi partition table header\n"));
gBS->FreePool (PartHdr);
return TRUE;
}
BOOLEAN
PartitionCheckGptEntryArrayCRC (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_PARTITION_TABLE_HEADER *PartHeader
)
/*++
Routine Description:
Check if the CRC field in the Partition table header is valid
for Partition entry array
Arguments:
BlockIo - parent BlockIo interface
DiskIo - Disk Io Protocol.
PartHeader - Partition table header structure
Returns:
TRUE - the CRC is valid
FALSE - the CRC is invalid
--*/
{
EFI_STATUS Status;
UINT8 *Ptr;
UINT32 Crc;
UINTN Size;
//
// Read the EFI Partition Entries
//
Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
if (Ptr == NULL) {
DEBUG ((EFI_D_ERROR, " Allocate pool error\n"));
return FALSE;
}
Status = DiskIo->ReadDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
Ptr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (Ptr);
return FALSE;
}
Size = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;
Status = gBS->CalculateCrc32 (Ptr, Size, &Crc);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "CheckPEntryArrayCRC: Crc calculation failed\n"));
gBS->FreePool (Ptr);
return FALSE;
}
gBS->FreePool (Ptr);
return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);
}
BOOLEAN
PartitionRestoreGptTable (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_PARTITION_TABLE_HEADER *PartHeader
)
/*++
Routine Description:
Restore Partition Table to its alternate place
(Primary -> Backup or Backup -> Primary)
Arguments:
BlockIo - parent BlockIo interface
DiskIo - Disk Io Protocol.
PartHeader - the source Partition table header structure
Returns:
TRUE - Restoring succeeds
FALSE - Restoring failed
--*/
{
EFI_STATUS Status;
UINTN BlockSize;
EFI_PARTITION_TABLE_HEADER *PartHdr;
EFI_LBA PEntryLBA;
UINT8 *Ptr;
PartHdr = NULL;
Ptr = NULL;
BlockSize = BlockIo->Media->BlockSize;
PartHdr = AllocateZeroPool (BlockSize);
if (PartHdr == NULL) {
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
return FALSE;
}
PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \
(PartHeader->LastUsableLBA + 1) : \
(PRIMARY_PART_HEADER_LBA + 1);
CopyMem (PartHdr, PartHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
PartHdr->MyLBA = PartHeader->AlternateLBA;
PartHdr->AlternateLBA = PartHeader->MyLBA;
PartHdr->PartitionEntryLBA = PEntryLBA;
PartitionSetCrc ((EFI_TABLE_HEADER *) PartHdr);
Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, PartHdr->MyLBA, BlockSize, PartHdr);
if (EFI_ERROR (Status)) {
goto Done;
}
Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
if (Ptr == NULL) {
DEBUG ((EFI_D_ERROR, " Allocate pool effor\n"));
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
Status = DiskIo->ReadDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
Ptr
);
if (EFI_ERROR (Status)) {
goto Done;
}
Status = DiskIo->WriteDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PEntryLBA, BlockIo->Media->BlockSize),
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
Ptr
);
Done:
gBS->FreePool (PartHdr);
gBS->FreePool (Ptr);
if (EFI_ERROR (Status)) {
return FALSE;
}
return TRUE;
}
VOID
PartitionCheckGptEntry (
IN EFI_PARTITION_TABLE_HEADER *PartHeader,
IN EFI_PARTITION_ENTRY *PartEntry,
OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
)
/*++
Routine Description:
Check each partition entry for its range
Arguments:
PartHeader - the partition table header
PartEntry - the partition entry array
PEntryStatus - the partition entry status array recording the status of
each partition
Returns:
VOID
--*/
{
EFI_LBA StartingLBA;
EFI_LBA EndingLBA;
UINTN Index1;
UINTN Index2;
DEBUG ((EFI_D_INFO, " start check partition entries\n"));
for (Index1 = 0; Index1 < PartHeader->NumberOfPartitionEntries; Index1++) {
if (CompareGuid (&PartEntry[Index1].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
continue;
}
StartingLBA = PartEntry[Index1].StartingLBA;
EndingLBA = PartEntry[Index1].EndingLBA;
if (StartingLBA > EndingLBA ||
StartingLBA < PartHeader->FirstUsableLBA ||
StartingLBA > PartHeader->LastUsableLBA ||
EndingLBA < PartHeader->FirstUsableLBA ||
EndingLBA > PartHeader->LastUsableLBA
) {
PEntryStatus[Index1].OutOfRange = TRUE;
continue;
}
for (Index2 = Index1 + 1; Index2 < PartHeader->NumberOfPartitionEntries; Index2++) {
if (CompareGuid (&PartEntry[Index2].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
continue;
}
if (PartEntry[Index2].EndingLBA >= StartingLBA && PartEntry[Index2].StartingLBA <= EndingLBA) {
//
// This region overlaps with the Index1'th region
//
PEntryStatus[Index1].Overlap = TRUE;
PEntryStatus[Index2].Overlap = TRUE;
continue;
}
}
}
DEBUG ((EFI_D_INFO, " End check partition entries\n"));
}
VOID
PartitionSetCrc (
IN OUT EFI_TABLE_HEADER *Hdr
)
/*++
Routine Description:
Updates the CRC32 value in the table header
Arguments:
Hdr - The table to update
Returns:
None
--*/
{
PartitionSetCrcAltSize (Hdr->HeaderSize, Hdr);
}
VOID
PartitionSetCrcAltSize (
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
)
/*++
Routine Description:
Updates the CRC32 value in the table header
Arguments:
Size - The size of the table
Hdr - The table to update
Returns:
None
--*/
{
UINT32 Crc;
Hdr->CRC32 = 0;
gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
Hdr->CRC32 = Crc;
}
BOOLEAN
PartitionCheckCrc (
IN UINTN MaxSize,
IN OUT EFI_TABLE_HEADER *Hdr
)
/*++
Routine Description:
Checks the CRC32 value in the table header
Arguments:
MaxSize - Max Size limit
Hdr - The table to check
Returns:
TRUE if the CRC is OK in the table
--*/
{
return PartitionCheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);
}
BOOLEAN
PartitionCheckCrcAltSize (
IN UINTN MaxSize,
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
)
/*++
Routine Description:
Checks the CRC32 value in the table header
Arguments:
MaxSize - Max Size Limit
Size - The size of the table
Hdr - The table to check
Returns:
TRUE if the CRC is OK in the table
--*/
{
UINT32 Crc;
UINT32 OrgCrc;
EFI_STATUS Status;
Crc = 0;
if (Size == 0) {
//
// If header size is 0 CRC will pass so return FALSE here
//
return FALSE;
}
if (MaxSize && Size > MaxSize) {
DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));
return FALSE;
}
//
// clear old crc from header
//
OrgCrc = Hdr->CRC32;
Hdr->CRC32 = 0;
Status = gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc calculation failed\n"));
return FALSE;
}
//
// set results
//
Hdr->CRC32 = Crc;
//
// return status
//
DEBUG_CODE (
if (OrgCrc != Crc) {
DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));
}
);
return (BOOLEAN) (OrgCrc == Crc);
}

View File

@@ -0,0 +1,76 @@
/*++
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:
Gpt.h
Abstract:
Data Structures required for detecting GPT Partitions
Revision History
--*/
#ifndef _GPT_H_
#define _GPT_H_
#pragma pack(1)
#define PRIMARY_PART_HEADER_LBA 1
#define EFI_PTAB_HEADER_ID "EFI PART"
//
// EFI Partition Attributes
//
#define EFI_PART_REQUIRED_TO_FUNCTION 0x0000000000000001
//
// GPT Partition Table Header
//
typedef struct {
EFI_TABLE_HEADER Header;
EFI_LBA MyLBA;
EFI_LBA AlternateLBA;
EFI_LBA FirstUsableLBA;
EFI_LBA LastUsableLBA;
EFI_GUID DiskGUID;
EFI_LBA PartitionEntryLBA;
UINT32 NumberOfPartitionEntries;
UINT32 SizeOfPartitionEntry;
UINT32 PartitionEntryArrayCRC32;
} EFI_PARTITION_TABLE_HEADER;
//
// GPT Partition Entry
//
typedef struct {
EFI_GUID PartitionTypeGUID;
EFI_GUID UniquePartitionGUID;
EFI_LBA StartingLBA;
EFI_LBA EndingLBA;
UINT64 Attributes;
CHAR16 PartitionName[36];
} EFI_PARTITION_ENTRY;
//
// GPT Partition Entry Status
//
typedef struct {
BOOLEAN OutOfRange;
BOOLEAN Overlap;
} EFI_PARTITION_ENTRY_STATUS;
#pragma pack()
#endif

View File

@@ -0,0 +1,317 @@
/*++
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:
Mbr.c
Abstract:
Decode a hard disk partitioned with the legacy MBR found on most PC's
MBR - Master Boot Record is in the first sector of a partitioned hard disk.
The MBR supports four partitions per disk. The MBR also contains legacy
code that is not run on an EFI system. The legacy code reads the
first sector of the active partition into memory and
BPB - Boot(?) Parameter Block is in the first sector of a FAT file system.
The BPB contains information about the FAT file system. The BPB is
always on the first sector of a media. The first sector also contains
the legacy boot strap code.
--*/
#include "Partition.h"
#include "Mbr.h"
BOOLEAN
PartitionValidMbr (
IN MASTER_BOOT_RECORD *Mbr,
IN EFI_LBA LastLba
)
/*++
Routine Description:
Test to see if the Mbr buffer is a valid MBR
Arguments:
Mbr - Parent Handle
LastLba - Last Lba address on the device.
Returns:
TRUE - Mbr is a Valid MBR
FALSE - Mbr is not a Valid MBR
--*/
{
UINT32 StartingLBA;
UINT32 EndingLBA;
UINT32 NewEndingLBA;
INTN Index1;
INTN Index2;
BOOLEAN MbrValid;
if (Mbr->Signature != MBR_SIGNATURE) {
return FALSE;
}
//
// The BPB also has this signature, so it can not be used alone.
//
MbrValid = FALSE;
for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {
if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {
continue;
}
MbrValid = TRUE;
StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);
EndingLBA = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;
if (EndingLBA > LastLba) {
//
// Compatibility Errata:
// Some systems try to hide drive space with their INT 13h driver
// This does not hide space from the OS driver. This means the MBR
// that gets created from DOS is smaller than the MBR created from
// a real OS (NT & Win98). This leads to BlockIo->LastBlock being
// wrong on some systems FDISKed by the OS.
//
// return FALSE since no block devices on a system are implemented
// with INT 13h
//
return FALSE;
}
for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {
if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {
continue;
}
NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;
if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {
//
// This region overlaps with the Index1'th region
//
return FALSE;
}
}
}
//
// Non of the regions overlapped so MBR is O.K.
//
return MbrValid;
}
BOOLEAN
PartitionInstallMbrChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
/*++
Routine Description:
Install child handles if the Handle supports MBR format.
Arguments:
This - Calling context.
Handle - Parent Handle
DiskIo - Parent DiskIo interface
BlockIo - Parent BlockIo interface
DevicePath - Parent Device Path
Returns:
EFI_SUCCESS - If a child handle was added
other - A child handle was not added
--*/
{
EFI_STATUS Status;
MASTER_BOOT_RECORD *Mbr;
UINT32 ExtMbrStartingLba;
UINTN Index;
HARDDRIVE_DEVICE_PATH HdDev;
HARDDRIVE_DEVICE_PATH ParentHdDev;
BOOLEAN Found;
UINT32 PartitionNumber;
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode;
Mbr = NULL;
Found = FALSE;
Mbr = AllocatePool (BlockIo->Media->BlockSize);
if (Mbr == NULL) {
goto Done;
}
Status = BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
0,
BlockIo->Media->BlockSize,
Mbr
);
if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) {
goto Done;
}
//
// We have a valid mbr - add each partition
//
//
// Get starting and ending LBA of the parent block device.
//
LastDevicePathNode = NULL;
ZeroMem (&ParentHdDev, sizeof (ParentHdDev));
DevicePathNode = DevicePath;
while (!EfiIsDevicePathEnd (DevicePathNode)) {
LastDevicePathNode = DevicePathNode;
DevicePathNode = EfiNextDevicePathNode (DevicePathNode);
}
if (LastDevicePathNode != NULL) {
if (DevicePathType (LastDevicePathNode) == MEDIA_DEVICE_PATH &&
DevicePathSubType (LastDevicePathNode) == MEDIA_HARDDRIVE_DP
) {
gBS->CopyMem (&ParentHdDev, LastDevicePathNode, sizeof (ParentHdDev));
} else {
LastDevicePathNode = NULL;
}
}
PartitionNumber = 1;
ZeroMem (&HdDev, sizeof (HdDev));
HdDev.Header.Type = MEDIA_DEVICE_PATH;
HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
HdDev.MBRType = MBR_TYPE_PCAT;
HdDev.SignatureType = SIGNATURE_TYPE_MBR;
if (LastDevicePathNode == NULL) {
//
// This is a MBR, add each partition
//
for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA) == 0) {
//
// Don't use null MBR entries
//
continue;
}
if (Mbr->Partition[Index].OSIndicator == 0xEE) {
//
// This is the guard MBR for the GPT. If you ever see a GPT disk with zero partitions you can get here.
// We can not produce an MBR BlockIo for this device as the MBR spans the GPT headers. So formating
// this BlockIo would corrupt the GPT structures and require a recovery that would corrupt the format
// that corrupted the GPT partition.
//
continue;
}
HdDev.PartitionNumber = PartitionNumber ++;
HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[Index].StartingLBA);
HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA);
CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (UINT32));
Status = PartitionInstallChildHandle (
This,
Handle,
DiskIo,
BlockIo,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
HdDev.PartitionStart,
HdDev.PartitionStart + HdDev.PartitionSize - 1,
MBR_SIZE,
(BOOLEAN) (Mbr->Partition[Index].OSIndicator == EFI_PARTITION)
);
if (!EFI_ERROR (Status)) {
Found = TRUE;
}
}
} else {
//
// It's an extended partition. Follow the extended partition
// chain to get all the logical drives
//
ExtMbrStartingLba = 0;
do {
Status = BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
ExtMbrStartingLba,
BlockIo->Media->BlockSize,
Mbr
);
if (EFI_ERROR (Status)) {
goto Done;
}
if (Mbr->Partition[0].OSIndicator == 0) {
break;
}
HdDev.PartitionNumber = PartitionNumber ++;
HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA) + ExtMbrStartingLba + ParentHdDev.PartitionStart;
HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA);
if (HdDev.PartitionStart + HdDev.PartitionSize - 1 >=
ParentHdDev.PartitionStart + ParentHdDev.PartitionSize) {
break;
}
//
// The signature in EBR(Extended Boot Record) should always be 0.
//
*((UINT32 *) &HdDev.Signature[0]) = 0;
Status = PartitionInstallChildHandle (
This,
Handle,
DiskIo,
BlockIo,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
HdDev.PartitionStart - ParentHdDev.PartitionStart,
HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,
MBR_SIZE,
(BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)
);
if (!EFI_ERROR (Status)) {
Found = TRUE;
}
if (Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION &&
Mbr->Partition[1].OSIndicator != EXTENDED_WINDOWS_PARTITION
) {
break;
}
ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[1].StartingLBA);
//
// Don't allow partition to be self referencing
//
if (ExtMbrStartingLba == 0) {
break;
}
} while (ExtMbrStartingLba < ParentHdDev.PartitionSize);
}
Done:
gBS->FreePool (Mbr);
return Found;
}

View File

@@ -0,0 +1,68 @@
/*++
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:
Mbr.h
Abstract:
Data Structures required for detecting MBR Partitions
Revision History
--*/
#ifndef _MBR_H_
#define _MBR_H_
#pragma pack(1)
#define MBR_SIGNATURE 0xaa55
#define MIN_MBR_DEVICE_SIZE 0x80000
#define MBR_ERRATA_PAD 0x40000 // 128 MB
#define EXTENDED_DOS_PARTITION 0x05
#define EXTENDED_WINDOWS_PARTITION 0x0F
#define MAX_MBR_PARTITIONS 4
#define EFI_PARTITION 0xef
#define MBR_SIZE 512
//
// MBR Partition Entry
//
typedef struct {
UINT8 BootIndicator;
UINT8 StartHead;
UINT8 StartSector;
UINT8 StartTrack;
UINT8 OSIndicator;
UINT8 EndHead;
UINT8 EndSector;
UINT8 EndTrack;
UINT8 StartingLBA[4];
UINT8 SizeInLBA[4];
} MBR_PARTITION_RECORD;
//
// MBR Partition table
//
typedef struct {
UINT8 BootStrapCode[440];
UINT8 UniqueMbrSignature[4];
UINT8 Unknown[2];
MBR_PARTITION_RECORD Partition[MAX_MBR_PARTITIONS];
UINT16 Signature;
} MASTER_BOOT_RECORD;
#pragma pack()
#endif

View File

@@ -0,0 +1,735 @@
/*++
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:
Partition.c
Abstract:
Partition driver that produces logical BlockIo devices from a physical
BlockIo device. The logical BlockIo devices are based on the format
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
MBR, and GPT partition schemes are supported.
--*/
#include "Partition.h"
//
// Function Prototypes
//
EFI_STATUS
EFIAPI
PartitionEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
EFIAPI
PartitionDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PartitionDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PartitionDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
//
// Partition Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {
PartitionDriverBindingSupported,
PartitionDriverBindingStart,
PartitionDriverBindingStop,
0x10,
NULL,
NULL
};
EFI_STATUS
EFIAPI
PartitionDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Test to see if this driver supports ControllerHandle. Any ControllerHandle
than contains a BlockIo and DiskIo protocol can be supported.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to test
RemainingDevicePath - Not used
Returns:
EFI_SUCCESS - This driver supports this device
EFI_ALREADY_STARTED - This driver is already running on this device
EFI_UNSUPPORTED - This driver does not support this device
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_DEV_PATH *Node;
if (RemainingDevicePath != NULL) {
Node = (EFI_DEV_PATH *) RemainingDevicePath;
if (Node->DevPath.Type != MEDIA_DEVICE_PATH ||
Node->DevPath.SubType != MEDIA_HARDDRIVE_DP ||
DevicePathNodeLength (&Node->DevPath) != sizeof (HARDDRIVE_DEVICE_PATH)
) {
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;
}
//
// Close the I/O Abstraction(s) used to perform the supported test
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
return EFI_SUCCESS;
}
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close the I/O Abstraction(s) used to perform the supported test
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
return Status;
}
EFI_STATUS
EFIAPI
PartitionDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Start this driver on ControllerHandle by opening a Block IO and Disk IO
protocol, reading Device Path, and creating a child handle with a
Disk IO and device path protocol.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to bind driver to
RemainingDevicePath - Not used
Returns:
EFI_SUCCESS - This driver is added to DeviceHandle
EFI_ALREADY_STARTED - This driver is already running on DeviceHandle
other - This driver does not support this device
--*/
{
EFI_STATUS Status;
EFI_STATUS OpenStatus;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the Device Path Protocol on ControllerHandle's handle
//
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,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
OpenStatus = Status;
//
// If no media is present, do nothing here.
//
Status = EFI_UNSUPPORTED;
if (BlockIo->Media->MediaPresent) {
//
// Try for GPT, then El Torito, and then legacy MBR partition types. If the
// media supports a given partition type install child handles to represent
// the partitions described by the media.
//
if (PartitionInstallGptChildHandles (
This,
ControllerHandle,
DiskIo,
BlockIo,
ParentDevicePath
) ||
PartitionInstallElToritoChildHandles (
This,
ControllerHandle,
DiskIo,
BlockIo,
ParentDevicePath
) ||
PartitionInstallMbrChildHandles (
This,
ControllerHandle,
DiskIo,
BlockIo,
ParentDevicePath
)) {
Status = EFI_SUCCESS;
} else {
Status = EFI_NOT_FOUND;
}
}
//
// In the case that the driver is already started (OpenStatus == EFI_ALREADY_STARTED),
// the DevicePathProtocol and the DiskIoProtocol are not actually opened by the
// driver. So don't try to close them. Otherwise, we will break the dependency
// between the controller and the driver set up before.
//
if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
}
return Status;
}
EFI_STATUS
EFIAPI
PartitionDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to stop driver on
NumberOfChildren - Number of Children in the ChildHandleBuffer
ChildHandleBuffer - List of handles for the children we need to stop.
Returns:
EFI_SUCCESS - This driver is removed DeviceHandle
EFI_DEVICE_ERROR - This driver was not removed from this device
--*/
{
EFI_STATUS Status;
UINTN Index;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
BOOLEAN AllChildrenStopped;
PARTITION_PRIVATE_DATA *Private;
EFI_DISK_IO_PROTOCOL *DiskIo;
if (NumberOfChildren == 0) {
//
// Close the bus driver
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
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],
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (BlockIo);
//
// All Software protocols have be freed from the handle so remove it.
//
BlockIo->FlushBlocks (BlockIo);
Status = gBS->CloseProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
This->DriverBindingHandle,
ChildHandleBuffer[Index]
);
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
Private->DevicePath,
&gEfiBlockIoProtocolGuid,
&Private->BlockIo,
Private->EspGuid,
NULL,
NULL
);
if (EFI_ERROR (Status)) {
gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
This->DriverBindingHandle,
ChildHandleBuffer[Index],
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
gBS->FreePool (Private->DevicePath);
gBS->FreePool (Private);
}
}
if (EFI_ERROR (Status)) {
AllChildrenStopped = FALSE;
}
}
if (!AllChildrenStopped) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PartitionReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Reset the parent 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.
--*/
{
PARTITION_PRIVATE_DATA *Private;
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);
return Private->ParentBlockIo->Reset (
Private->ParentBlockIo,
ExtendedVerification
);
}
EFI_STATUS
EFIAPI
PartitionReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Read by using the Disk IO protocol on the parent device. Lba addresses
must be converted to byte offsets.
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.
--*/
{
PARTITION_PRIVATE_DATA *Private;
UINT64 Offset;
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);
if (BufferSize % Private->BlockSize != 0) {
return EFI_BAD_BUFFER_SIZE;
}
Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;
if (Offset + BufferSize > Private->End) {
return EFI_INVALID_PARAMETER;
}
//
// Because some kinds of partition have different block size from their parent
// device, we call the Disk IO protocol on the parent device, not the Block IO
// protocol
//
return Private->DiskIo->ReadDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);
}
EFI_STATUS
EFIAPI
PartitionWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Write by using the Disk IO protocol on the parent device. Lba addresses
must be converted to byte offsets.
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.
--*/
{
PARTITION_PRIVATE_DATA *Private;
UINT64 Offset;
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);
if (BufferSize % Private->BlockSize != 0) {
return EFI_BAD_BUFFER_SIZE;
}
Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;
if (Offset + BufferSize > Private->End) {
return EFI_INVALID_PARAMETER;
}
//
// Because some kinds of partition have different block size from their parent
// device, we call the Disk IO protocol on the parent device, not the Block IO
// protocol
//
return Private->DiskIo->WriteDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);
}
EFI_STATUS
EFIAPI
PartitionFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
)
/*++
Routine Description:
Flush the parent 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 writing back the data
EFI_NO_MEDIA - There is no media in the device.
--*/
{
PARTITION_PRIVATE_DATA *Private;
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);
return Private->ParentBlockIo->FlushBlocks (Private->ParentBlockIo);
}
EFI_STATUS
PartitionInstallChildHandle (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ParentHandle,
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
IN EFI_LBA Start,
IN EFI_LBA End,
IN UINT32 BlockSize,
IN BOOLEAN InstallEspGuid
)
/*++
Routine Description:
Create a child handle for a logical block device that represents the
bytes Start to End of the Parent Block IO device.
Arguments:
This - Calling context.
ParentHandle - Parent Handle for new child
ParentDiskIo - Parent DiskIo interface
ParentBlockIo - Parent BlockIo interface
ParentDevicePath - Parent Device Path
DevicePathNode - Child Device Path node
Start - Start Block
End - End Block
BlockSize - Child block size
InstallEspGuid - Flag to install EFI System Partition GUID on handle
Returns:
EFI_SUCCESS - If a child handle was added
EFI_OUT_OF_RESOURCES - A child handle was not added
--*/
{
EFI_STATUS Status;
PARTITION_PRIVATE_DATA *Private;
Private = AllocateZeroPool (sizeof (PARTITION_PRIVATE_DATA));
if (Private == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Private->Signature = PARTITION_PRIVATE_DATA_SIGNATURE;
Private->Start = MultU64x32 (Start, ParentBlockIo->Media->BlockSize);
Private->End = MultU64x32 (End + 1, ParentBlockIo->Media->BlockSize);
Private->BlockSize = BlockSize;
Private->ParentBlockIo = ParentBlockIo;
Private->DiskIo = ParentDiskIo;
Private->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;
Private->BlockIo.Media = &Private->Media;
CopyMem (Private->BlockIo.Media, ParentBlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));
Private->Media.LogicalPartition = TRUE;
Private->Media.LastBlock = DivU64x32 (
MultU64x32 (
End - Start + 1,
ParentBlockIo->Media->BlockSize
),
BlockSize
) - 1;
Private->Media.BlockSize = (UINT32) BlockSize;
Private->BlockIo.Reset = PartitionReset;
Private->BlockIo.ReadBlocks = PartitionReadBlocks;
Private->BlockIo.WriteBlocks = PartitionWriteBlocks;
Private->BlockIo.FlushBlocks = PartitionFlushBlocks;
Private->DevicePath = AppendDevicePathNode (ParentDevicePath, DevicePathNode);
if (Private->DevicePath == NULL) {
gBS->FreePool (Private);
return EFI_OUT_OF_RESOURCES;
}
if (InstallEspGuid) {
Private->EspGuid = &gEfiPartTypeSystemPartGuid;
} else {
//
// If NULL InstallMultipleProtocolInterfaces will ignore it.
//
Private->EspGuid = NULL;
}
//
// Create the new handle
//
Private->Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&Private->Handle,
&gEfiDevicePathProtocolGuid,
Private->DevicePath,
&gEfiBlockIoProtocolGuid,
&Private->BlockIo,
Private->EspGuid,
NULL,
NULL
);
if (!EFI_ERROR (Status)) {
//
// Open the Parent Handle for the child
//
Status = gBS->OpenProtocol (
ParentHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &ParentDiskIo,
This->DriverBindingHandle,
Private->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
gBS->FreePool (Private->DevicePath);
gBS->FreePool (Private);
}
return Status;
}

View File

@@ -0,0 +1,123 @@
/*++
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:
Partition.h
Abstract:
Partition driver that produces logical BlockIo devices from a physical
BlockIo device. The logical BlockIo devices are based on the format
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
MBR, and GPT partition schemes are supported.
Revision History
--*/
#ifndef __PARTITION_H__
#define __PARTITION_H__
//
// Partition private data
//
#define PARTITION_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('P', 'a', 'r', 't')
typedef struct {
UINT64 Signature;
EFI_HANDLE Handle;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_BLOCK_IO_PROTOCOL BlockIo;
EFI_BLOCK_IO_MEDIA Media;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_BLOCK_IO_PROTOCOL *ParentBlockIo;
UINT64 Start;
UINT64 End;
UINT32 BlockSize;
EFI_GUID *EspGuid;
} PARTITION_PRIVATE_DATA;
#define PARTITION_DEVICE_FROM_BLOCK_IO_THIS(a) CR (a, PARTITION_PRIVATE_DATA, BlockIo, PARTITION_PRIVATE_DATA_SIGNATURE)
//
// Global Variables
//
extern EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gPartitionComponentName;
//
// Extract INT32 from char array
//
#define UNPACK_INT32(a) (INT32)( (((UINT8 *) a)[0] << 0) | \
(((UINT8 *) a)[1] << 8) | \
(((UINT8 *) a)[2] << 16) | \
(((UINT8 *) a)[3] << 24) )
//
// Extract UINT32 from char array
//
#define UNPACK_UINT32(a) (UINT32)( (((UINT8 *) a)[0] << 0) | \
(((UINT8 *) a)[1] << 8) | \
(((UINT8 *) a)[2] << 16) | \
(((UINT8 *) a)[3] << 24) )
EFI_STATUS
PartitionInstallChildHandle (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ParentHandle,
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
IN UINT64 Start,
IN UINT64 End,
IN UINT32 BlockSize,
IN BOOLEAN InstallEspGuid
)
;
BOOLEAN
PartitionInstallGptChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
;
BOOLEAN
PartitionInstallElToritoChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
;
BOOLEAN
PartitionInstallMbrChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
;
#endif

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>Partition</BaseName>
<Guid>1FA1F39E-FEFF-4aae-BD7B-38A070A3B609</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>BaseLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>UefiDriverModelLib</Library>
<Library>DxeMemoryAllocationLib</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>UefiDevicePathLib</Library>
</Libraries>
</ModuleBuildDescription>

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>Partition</BaseName>
<ModuleType>UEFI_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>1FA1F39E-FEFF-4aae-BD7B-38A070A3B609</Guid>
<Version>0</Version>
<Abstract>Component description file for Partition module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>Partition.h</Filename>
<Filename>ElTorito.h</Filename>
<Filename>Gpt.h</Filename>
<Filename>Mbr.h</Filename>
<Filename>Partition.c</Filename>
<Filename>Eltorito.c</Filename>
<Filename>Gpt.c</Filename>
<Filename>Mbr.c</Filename>
<Filename>ComponentName.c</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="TO_START">BlockIo</Protocol>
<Protocol Usage="TO_START">DiskIo</Protocol>
<Protocol Usage="TO_START">DevicePath</Protocol>
</Protocols>
<Guids>
<GuidEntry Usage="SOMETIMES_CONSUMED">
<C_Name>PartTypeSystemPart</C_Name>
</GuidEntry>
<GuidEntry Usage="ALWAYS_CONSUMED">
<C_Name>PartTypeUnused</C_Name>
</GuidEntry>
</Guids>
<Externs>
<Extern>
<ModuleEntryPoint></ModuleEntryPoint>
</Extern>
<Extern>
<DriverBinding>gPartitionDriverBinding</DriverBinding>
<ComponentName>gPartitionComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="Partition"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Disk\Partition\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="Partition">
<GenBuild baseName="Partition" mbdFilename="${MODULE_DIR}\Partition.mbd" msaFilename="${MODULE_DIR}\Partition.msa"/>
</target>
<target depends="Partition_clean" name="clean"/>
<target depends="Partition_cleanall" name="cleanall"/>
<target name="Partition_clean">
<OutputDirSetup baseName="Partition" mbdFilename="${MODULE_DIR}\Partition.mbd" msaFilename="${MODULE_DIR}\Partition.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\Partition_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\Partition_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="Partition_cleanall">
<OutputDirSetup baseName="Partition" mbdFilename="${MODULE_DIR}\Partition.mbd" msaFilename="${MODULE_DIR}\Partition.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\Partition_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\Partition_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**Partition*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>English</BaseName>
<Guid>CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>BaseLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
</Libraries>
</ModuleBuildDescription>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>English</BaseName>
<ModuleType>UEFI_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600</Guid>
<Version>0</Version>
<Abstract>Component description file for English module for unicode collation.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>UnicodeCollationEng.c</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="ALWAYS_PRODUCED">UnicodeCollation</Protocol>
</Protocols>
<Externs>
<Extern>
<ModuleEntryPoint>InitializeUnicodeCollationEng</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,478 @@
/*++
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:
UnicodeCollationEng.c
Abstract:
Unicode Collation Protocol (English)
Revision History
--*/
#include "UnicodeCollationEng.h"
CHAR8 mEngUpperMap[0x100];
CHAR8 mEngLowerMap[0x100];
CHAR8 mEngInfoMap[0x100];
CHAR8 mOtherChars[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'\\',
'.',
'_',
'^',
'$',
'~',
'!',
'#',
'%',
'&',
'-',
'{',
'}',
'(',
')',
'@',
'`',
'\'',
'\0'
};
EFI_HANDLE mHandle = NULL;
EFI_UNICODE_COLLATION_PROTOCOL UnicodeEng = {
EngStriColl,
EngMetaiMatch,
EngStrLwr,
EngStrUpr,
EngFatToStr,
EngStrToFat,
"eng"
};
//
//
//
EFI_STATUS
InitializeUnicodeCollationEng (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Initializes the Unicode Collation Driver
Arguments:
ImageHandle -
SystemTable -
Returns:
EFI_SUCCESS
EFI_OUT_OF_RESOURCES
--*/
{
UINTN Index;
UINTN Index2;
//
// Initialize mapping tables for the supported languages
//
for (Index = 0; Index < 0x100; Index++) {
mEngUpperMap[Index] = (CHAR8) Index;
mEngLowerMap[Index] = (CHAR8) Index;
mEngInfoMap[Index] = 0;
if ((Index >= 'a' && Index <= 'z') || (Index >= 0xe0 && Index <= 0xf6) || (Index >= 0xf8 && Index <= 0xfe)) {
Index2 = Index - 0x20;
mEngUpperMap[Index] = (CHAR8) Index2;
mEngLowerMap[Index2] = (CHAR8) Index;
mEngInfoMap[Index] |= CHAR_FAT_VALID;
mEngInfoMap[Index2] |= CHAR_FAT_VALID;
}
}
for (Index = 0; mOtherChars[Index]; Index++) {
Index2 = mOtherChars[Index];
mEngInfoMap[Index2] |= CHAR_FAT_VALID;
}
//
// Create a handle for the device
//
return gBS->InstallProtocolInterface (
&mHandle,
&gEfiUnicodeCollationProtocolGuid,
EFI_NATIVE_INTERFACE,
&UnicodeEng
);
}
INTN
EFIAPI
EngStriColl (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *s1,
IN CHAR16 *s2
)
/*++
Routine Description:
Performs a case-insensitive comparison of two Null-terminated Unicode strings.
Arguments:
This
s1
s2
Returns:
--*/
{
while (*s1) {
if (ToUpper (*s1) != ToUpper (*s2)) {
break;
}
s1 += 1;
s2 += 1;
}
return ToUpper (*s1) - ToUpper (*s2);
}
VOID
EFIAPI
EngStrLwr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *Str
)
/*++
Routine Description:
Converts all the Unicode characters in a Null-terminated Unicode string
to lower case Unicode characters.
Arguments:
This - A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
Str1 - A pointer to a Null-terminated Unicode string.
Str2 - A pointer to a Null-terminated Unicode string.
Returns:
0 - s1 is equivalent to s2.
> 0 - s1 is lexically greater than s2.
< 0 - s1 is lexically less than s2.
--*/
{
while (*Str) {
*Str = ToLower (*Str);
Str += 1;
}
}
VOID
EFIAPI
EngStrUpr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *Str
)
/*++
Routine Description:
Converts all the Unicode characters in a Null-terminated
Unicode string to upper case Unicode characters.
Arguments:
This
Str
Returns:
None
--*/
{
while (*Str) {
*Str = ToUpper (*Str);
Str += 1;
}
}
BOOLEAN
EFIAPI
EngMetaiMatch (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN CHAR16 *Pattern
)
/*++
Routine Description:
Performs a case-insensitive comparison between a Null-terminated
Unicode pattern string and a Null-terminated Unicode string.
The pattern string can use the '?' wildcard to match any character,
and the '*' wildcard to match any sub-string.
Arguments:
This - A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
String - A pointer to a Null-terminated Unicode string.
Pattern - A pointer to a Null-terminated Unicode pattern string.
Returns:
TRUE - Pattern was found in String.
FALSE - Pattern was not found in String.
--*/
{
CHAR16 CharC;
CHAR16 CharP;
CHAR16 Index3;
for (;;) {
CharP = *Pattern;
Pattern += 1;
switch (CharP) {
case 0:
//
// End of pattern. If end of string, TRUE match
//
if (*String) {
return FALSE;
} else {
return TRUE;
}
case '*':
//
// Match zero or more chars
//
while (*String) {
if (EngMetaiMatch (This, String, Pattern)) {
return TRUE;
}
String += 1;
}
return EngMetaiMatch (This, String, Pattern);
case '?':
//
// Match any one char
//
if (!*String) {
return FALSE;
}
String += 1;
break;
case '[':
//
// Match char set
//
CharC = *String;
if (!CharC) {
//
// syntax problem
//
return FALSE;
}
Index3 = 0;
CharP = *Pattern++;
while (CharP) {
if (CharP == ']') {
return FALSE;
}
if (CharP == '-') {
//
// if range of chars, get high range
//
CharP = *Pattern;
if (CharP == 0 || CharP == ']') {
//
// syntax problem
//
return FALSE;
}
if (ToUpper (CharC) >= ToUpper (Index3) && ToUpper (CharC) <= ToUpper (CharP)) {
//
// if in range, it's a match
//
break;
}
}
Index3 = CharP;
if (ToUpper (CharC) == ToUpper (CharP)) {
//
// if char matches
//
break;
}
CharP = *Pattern++;
}
//
// skip to end of match char set
//
while (CharP && CharP != ']') {
CharP = *Pattern;
Pattern += 1;
}
String += 1;
break;
default:
CharC = *String;
if (ToUpper (CharC) != ToUpper (CharP)) {
return FALSE;
}
String += 1;
break;
}
}
}
VOID
EFIAPI
EngFatToStr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN UINTN FatSize,
IN CHAR8 *Fat,
OUT CHAR16 *String
)
/*++
Routine Description:
Converts an 8.3 FAT file name using an OEM character set
to a Null-terminated Unicode string.
BUGBUG: Function has to expand DBCS FAT chars, currently not.
Arguments:
This
FatSize
Fat
String
Returns:
--*/
{
//
// No DBCS issues, just expand and add null terminate to end of string
//
while (*Fat && FatSize) {
*String = *Fat;
String += 1;
Fat += 1;
FatSize -= 1;
}
*String = 0;
}
BOOLEAN
EFIAPI
EngStrToFat (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN UINTN FatSize,
OUT CHAR8 *Fat
)
/*++
Routine Description:
Converts a Null-terminated Unicode string to legal characters
in a FAT filename using an OEM character set.
Functions has to crunch string to a fat string. Replacing
any chars that can't be represented in the fat name.
Arguments:
This
String
FatSize
Fat
Returns:
TRUE
FALSE
--*/
{
BOOLEAN SpecialCharExist;
SpecialCharExist = FALSE;
while (*String && FatSize) {
//
// Skip '.' or ' ' when making a fat name
//
if (*String != '.' && *String != ' ') {
//
// If this is a valid fat char, move it.
// Otherwise, move a '_' and flag the fact that the name needs an Lfn
//
if (*String < 0x100 && (mEngInfoMap[*String] & CHAR_FAT_VALID)) {
*Fat = mEngUpperMap[*String];
} else {
*Fat = '_';
SpecialCharExist = TRUE;
}
Fat += 1;
FatSize -= 1;
}
String += 1;
}
//
// Do not terminate that fat string
//
return SpecialCharExist;
}

View File

@@ -0,0 +1,102 @@
/*++
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:
UnicodeCollationEng.h
Abstract:
Head file for Unicode Collation Protocol (English)
Revision History
--*/
#ifndef _UNICODE_COLLATION_ENG_H
#define _UNICODE_COLLATION_ENG_H
//
// Defines
//
#define CHAR_FAT_VALID 0x01
#define ToUpper(a) (CHAR16) (a <= 0xFF ? mEngUpperMap[a] : a)
#define ToLower(a) (CHAR16) (a <= 0xFF ? mEngLowerMap[a] : a)
//
// Prototypes
//
INTN
EFIAPI
EngStriColl (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *s1,
IN CHAR16 *s2
)
;
BOOLEAN
EFIAPI
EngMetaiMatch (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN CHAR16 *Pattern
)
;
VOID
EFIAPI
EngStrLwr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *Str
)
;
VOID
EFIAPI
EngStrUpr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *Str
)
;
VOID
EFIAPI
EngFatToStr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN UINTN FatSize,
IN CHAR8 *Fat,
OUT CHAR16 *String
)
;
BOOLEAN
EFIAPI
EngStrToFat (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN UINTN FatSize,
OUT CHAR8 *Fat
)
;
EFI_STATUS
EFIAPI
InitializeUnicodeCollationEng (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
;
#endif

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="English"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Disk\UnicodeCollation\English\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="English">
<GenBuild baseName="English" mbdFilename="${MODULE_DIR}\English.mbd" msaFilename="${MODULE_DIR}\English.msa"/>
</target>
<target depends="English_clean" name="clean"/>
<target depends="English_cleanall" name="cleanall"/>
<target name="English_clean">
<OutputDirSetup baseName="English" mbdFilename="${MODULE_DIR}\English.mbd" msaFilename="${MODULE_DIR}\English.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\English_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\English_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="English_cleanall">
<OutputDirSetup baseName="English" mbdFilename="${MODULE_DIR}\English.mbd" msaFilename="${MODULE_DIR}\English.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\English_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\English_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**English*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,26 @@
/*++
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:
Ebc.dxs
Abstract:
Dependency expression file for EBC VM.
--*/
#include <AutoGen.h>
#include <DxeDepex.h>
DEPENDENCY_START
TRUE
DEPENDENCY_END

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>Ebc</BaseName>
<Guid>13AC6DD0-73D0-11D4-B06B-00AA00BD6DE7</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>
<Created>2006-03-22 14:03</Created>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>BaseLib</Library>
<Library>UefiMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>EdkDxePrintLib</Library>
<Library>DxeMemoryAllocationLib</Library>
</Libraries>
<BuildOptions ToolChain="MSFT">
<ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
</BuildOptions>
</ModuleBuildDescription>

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>Ebc</BaseName>
<ModuleType>DXE_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>13AC6DD0-73D0-11D4-B06B-00AA00BD6DE7</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-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>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-22 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>EbcInt.c</Filename>
<Filename>EbcInt.h</Filename>
<Filename>EbcExecute.c</Filename>
<Filename>EbcExecute.h</Filename>
<Filename>Ebc.dxs</Filename>
<Arch ArchType="IA32">
<Filename>Ia32\EbcLowLevel.asm</Filename>
<Filename>Ia32\Ia32Math.asm</Filename>
<Filename>Ia32\EbcSupport.c</Filename>
</Arch>
<Arch ArchType="X64">
<Filename>x64\EbcLowLevel.asm</Filename>
<Filename>x64\x64Math.c</Filename>
<Filename>x64\EbcSupport.c</Filename>
</Arch>
<Arch ArchType="IPF">
<Filename>Ipf\EbcLowLevel.s</Filename>
<Filename>Ipf\IpfMath.c</Filename>
<Filename>Ipf\IpfMul.s</Filename>
<Filename>Ipf\EbcSupport.c</Filename>
</Arch>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
<PackageName>EdkModulePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="ALWAYS_PRODUCED">Ebc</Protocol>
<Protocol Usage="ALWAYS_PRODUCED">DebugSupport</Protocol>
</Protocols>
<Externs>
<Extern>
<ModuleEntryPoint>InitializeEbcDriver</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,383 @@
/*++
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:
EbcExecute.h
Abstract:
Header file for Virtual Machine support. Contains EBC defines that can
be of use to a disassembler for the most part. Also provides function
prototypes for VM functions.
--*/
#ifndef _EBC_EXECUTE_H_
#define _EBC_EXECUTE_H_
//
// Macros to check and set alignment
//
#define ASSERT_ALIGNED(addr, size) ASSERT (!((UINT32) (addr) & (size - 1)))
#define IS_ALIGNED(addr, size) !((UINT32) (addr) & (size - 1))
//
// Define a macro to get the operand. Then we can change it to be either a
// direct read or have it call a function to read memory.
//
#define GETOPERANDS(pVM) (UINT8) (*(UINT8 *) (pVM->Ip + 1))
#define GETOPCODE(pVM) (UINT8) (*(UINT8 *) pVM->Ip)
//
// Bit masks for opcode encodings
//
#define OPCODE_M_OPCODE 0x3F // bits of interest for first level decode
#define OPCODE_M_IMMDATA 0x80
#define OPCODE_M_IMMDATA64 0x40
#define OPCODE_M_64BIT 0x40 // for CMP
#define OPCODE_M_RELADDR 0x10 // for CALL instruction
#define OPCODE_M_CMPI32_DATA 0x80 // for CMPI
#define OPCODE_M_CMPI64 0x40 // for CMPI 32 or 64 bit comparison
#define OPERAND_M_MOVIN_N 0x80
#define OPERAND_M_CMPI_INDEX 0x10
//
// Masks for instructions that encode presence of indexes for operand1 and/or
// operand2.
//
#define OPCODE_M_IMMED_OP1 0x80
#define OPCODE_M_IMMED_OP2 0x40
//
// Bit masks for operand encodings
//
#define OPERAND_M_INDIRECT1 0x08
#define OPERAND_M_INDIRECT2 0x80
#define OPERAND_M_OP1 0x07
#define OPERAND_M_OP2 0x70
//
// Masks for data manipulation instructions
//
#define DATAMANIP_M_64 0x40 // 64-bit width operation
#define DATAMANIP_M_IMMDATA 0x80
//
// For MOV instructions, need a mask for the opcode when immediate
// data applies to R2.
//
#define OPCODE_M_IMMED_OP2 0x40
//
// The MOVI/MOVIn instructions use bit 6 of operands byte to indicate
// if an index is present. Then bits 4 and 5 are used to indicate the width
// of the move.
//
#define MOVI_M_IMMDATA 0x40
#define MOVI_M_DATAWIDTH 0xC0
#define MOVI_DATAWIDTH16 0x40
#define MOVI_DATAWIDTH32 0x80
#define MOVI_DATAWIDTH64 0xC0
#define MOVI_M_MOVEWIDTH 0x30
#define MOVI_MOVEWIDTH8 0x00
#define MOVI_MOVEWIDTH16 0x10
#define MOVI_MOVEWIDTH32 0x20
#define MOVI_MOVEWIDTH64 0x30
//
// Masks for CALL instruction encodings
//
#define OPERAND_M_RELATIVE_ADDR 0x10
#define OPERAND_M_NATIVE_CALL 0x20
//
// Masks for decoding push/pop instructions
//
#define PUSHPOP_M_IMMDATA 0x80 // opcode bit indicating immediate data
#define PUSHPOP_M_64 0x40 // opcode bit indicating 64-bit operation
//
// Mask for operand of JMP instruction
//
#define JMP_M_RELATIVE 0x10
#define JMP_M_CONDITIONAL 0x80
#define JMP_M_CS 0x40
//
// Macros to determine if a given operand is indirect
//
#define OPERAND1_INDIRECT(op) ((op) & OPERAND_M_INDIRECT1)
#define OPERAND2_INDIRECT(op) ((op) & OPERAND_M_INDIRECT2)
//
// Macros to extract the operands from second byte of instructions
//
#define OPERAND1_REGNUM(op) ((op) & OPERAND_M_OP1)
#define OPERAND2_REGNUM(op) (((op) & OPERAND_M_OP2) >> 4)
#define OPERAND1_CHAR(op) ('0' + OPERAND1_REGNUM (op))
#define OPERAND2_CHAR(op) ('0' + OPERAND2_REGNUM (op))
#define OPERAND1_REGDATA(pvm, op) pvm->R[OPERAND1_REGNUM (op)]
#define OPERAND2_REGDATA(pvm, op) pvm->R[OPERAND2_REGNUM (op)]
//
// Condition masks usually for byte 1 encodings of code
//
#define CONDITION_M_CONDITIONAL 0x80
#define CONDITION_M_CS 0x40
//
// Bits in the VM->StopFlags field
//
#define STOPFLAG_APP_DONE 0x0001
#define STOPFLAG_BREAKPOINT 0x0002
#define STOPFLAG_INVALID_BREAK 0x0004
#define STOPFLAG_BREAK_ON_CALLEX 0x0008
//
// Masks for working with the VM flags register
//
#define VMFLAGS_CC 0x0001 // condition flag
#define VMFLAGS_STEP 0x0002 // step instruction mode
#define VMFLAGS_ALL_VALID (VMFLAGS_CC | VMFLAGS_STEP)
//
// Macros for operating on the VM flags register
//
#define VMFLAG_SET(pVM, Flag) (pVM->Flags |= (Flag))
#define VMFLAG_ISSET(pVM, Flag) ((pVM->Flags & (Flag)) ? 1 : 0)
#define VMFLAG_CLEAR(pVM, Flag) (pVM->Flags &= ~(Flag))
//
// Debug macro
//
#define EBCMSG(s) gST->ConOut->OutputString (gST->ConOut, s)
//
// Define OPCODES
//
#define OPCODE_BREAK 0x00
#define OPCODE_JMP 0x01
#define OPCODE_JMP8 0x02
#define OPCODE_CALL 0x03
#define OPCODE_RET 0x04
#define OPCODE_CMPEQ 0x05
#define OPCODE_CMPLTE 0x06
#define OPCODE_CMPGTE 0x07
#define OPCODE_CMPULTE 0x08
#define OPCODE_CMPUGTE 0x09
#define OPCODE_NOT 0x0A
#define OPCODE_NEG 0x0B
#define OPCODE_ADD 0x0C
#define OPCODE_SUB 0x0D
#define OPCODE_MUL 0x0E
#define OPCODE_MULU 0x0F
#define OPCODE_DIV 0x10
#define OPCODE_DIVU 0x11
#define OPCODE_MOD 0x12
#define OPCODE_MODU 0x13
#define OPCODE_AND 0x14
#define OPCODE_OR 0x15
#define OPCODE_XOR 0x16
#define OPCODE_SHL 0x17
#define OPCODE_SHR 0x18
#define OPCODE_ASHR 0x19
#define OPCODE_EXTNDB 0x1A
#define OPCODE_EXTNDW 0x1B
#define OPCODE_EXTNDD 0x1C
#define OPCODE_MOVBW 0x1D
#define OPCODE_MOVWW 0x1E
#define OPCODE_MOVDW 0x1F
#define OPCODE_MOVQW 0x20
#define OPCODE_MOVBD 0x21
#define OPCODE_MOVWD 0x22
#define OPCODE_MOVDD 0x23
#define OPCODE_MOVQD 0x24
#define OPCODE_MOVSNW 0x25 // Move signed natural with word index
#define OPCODE_MOVSND 0x26 // Move signed natural with dword index
//
// #define OPCODE_27 0x27
//
#define OPCODE_MOVQQ 0x28 // Does this go away?
#define OPCODE_LOADSP 0x29
#define OPCODE_STORESP 0x2A
#define OPCODE_PUSH 0x2B
#define OPCODE_POP 0x2C
#define OPCODE_CMPIEQ 0x2D
#define OPCODE_CMPILTE 0x2E
#define OPCODE_CMPIGTE 0x2F
#define OPCODE_CMPIULTE 0x30
#define OPCODE_CMPIUGTE 0x31
#define OPCODE_MOVNW 0x32
#define OPCODE_MOVND 0x33
//
// #define OPCODE_34 0x34
//
#define OPCODE_PUSHN 0x35
#define OPCODE_POPN 0x36
#define OPCODE_MOVI 0x37
#define OPCODE_MOVIN 0x38
#define OPCODE_MOVREL 0x39
EFI_STATUS
EbcExecute (
IN VM_CONTEXT *VmPtr
)
;
//
// Math library routines
//
INT64
DivS64x64 (
IN INT64 Value1,
IN INT64 Value2,
OUT INT64 *Remainder,
OUT UINT32 *Error
)
;
#if 0
UINT64
DivU64x64 (
IN UINT64 Value1,
IN UINT64 Value2,
OUT UINT64 *Remainder,
OUT UINT32 *Error
)
;
#endif
INT64
MulS64x64 (
IN INT64 Value1,
IN INT64 Value2,
OUT INT64 *ResultHigh
)
;
UINT64
MulU64x64 (
IN UINT64 Value1,
IN UINT64 Value2,
OUT UINT64 *ResultHigh
)
;
UINT64
DivU64x64 (
IN UINT64 Value1,
IN UINT64 Value2,
OUT UINT64 *Remainder,
OUT UINT32 *Error
)
;
INT64
ARightShift64 (
IN INT64 Operand,
IN INT64 Count
)
;
UINT64
LeftShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
;
UINT64
RightShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
;
UINT64
GetVmVersion (
VOID
)
;
EFI_STATUS
VmWriteMemN (
IN VM_CONTEXT *VmPtr,
IN UINTN Addr,
IN UINTN Data
)
;
EFI_STATUS
VmWriteMem64 (
IN VM_CONTEXT *VmPtr,
UINTN Addr,
IN UINT64 Data
)
;
//
// Define a protocol for an EBC VM test interface.
//
#define EFI_EBC_VM_TEST_PROTOCOL_GUID \
{ \
0xAAEACCFDL, 0xF27B, 0x4C17, { 0xB6, 0x10, 0x75, 0xCA, 0x1F, 0x2D, 0xFB, 0x52 } \
}
//
// Define for forward reference.
//
typedef struct _EFI_EBC_VM_TEST_PROTOCOL EFI_EBC_VM_TEST_PROTOCOL;
typedef
EFI_STATUS
(*EBC_VM_TEST_EXECUTE) (
IN EFI_EBC_VM_TEST_PROTOCOL * This,
IN VM_CONTEXT * VmPtr,
IN OUT UINTN *InstructionCount
);
typedef
EFI_STATUS
(*EBC_VM_TEST_ASM) (
IN EFI_EBC_VM_TEST_PROTOCOL * This,
IN CHAR16 *AsmText,
IN OUT INT8 *Buffer,
IN OUT UINTN *BufferLen
);
typedef
EFI_STATUS
(*EBC_VM_TEST_DASM) (
IN EFI_EBC_VM_TEST_PROTOCOL * This,
IN OUT CHAR16 *AsmText,
IN OUT INT8 *Buffer,
IN OUT UINTN *Len
);
//
// Prototype for the actual EBC test protocol interface
//
struct _EFI_EBC_VM_TEST_PROTOCOL {
EBC_VM_TEST_EXECUTE Execute;
EBC_VM_TEST_ASM Assemble;
EBC_VM_TEST_DASM Disassemble;
};
EFI_STATUS
EbcExecuteInstructions (
IN EFI_EBC_VM_TEST_PROTOCOL *This,
IN VM_CONTEXT *VmPtr,
IN OUT UINTN *InstructionCount
)
;
#endif // ifndef _EBC_EXECUTE_H_

View File

@@ -0,0 +1,932 @@
/*++
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:
EbcInt.c
Abstract:
Top level module for the EBC virtual machine implementation.
Provides auxilliary support routines for the VM. That is, routines
that are not particularly related to VM execution of EBC instructions.
--*/
#include "EbcInt.h"
#include "EbcExecute.h"
//
// We'll keep track of all thunks we create in a linked list. Each
// thunk is tied to an image handle, so we have a linked list of
// image handles, with each having a linked list of thunks allocated
// to that image handle.
//
typedef struct _EBC_THUNK_LIST {
VOID *ThunkBuffer;
struct _EBC_THUNK_LIST *Next;
} EBC_THUNK_LIST;
typedef struct _EBC_IMAGE_LIST {
struct _EBC_IMAGE_LIST *Next;
EFI_HANDLE ImageHandle;
EBC_THUNK_LIST *ThunkList;
} EBC_IMAGE_LIST;
//
// Function prototypes
//
EFI_STATUS
EFIAPI
InitializeEbcDriver (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
STATIC
EFI_STATUS
EFIAPI
EbcUnloadImage (
IN EFI_EBC_PROTOCOL *This,
IN EFI_HANDLE ImageHandle
);
STATIC
EFI_STATUS
EFIAPI
EbcCreateThunk (
IN EFI_EBC_PROTOCOL *This,
IN EFI_HANDLE ImageHandle,
IN VOID *EbcEntryPoint,
OUT VOID **Thunk
);
STATIC
EFI_STATUS
EFIAPI
EbcGetVersion (
IN EFI_EBC_PROTOCOL *This,
IN OUT UINT64 *Version
);
//
// These two functions and the GUID are used to produce an EBC test protocol.
// This functionality is definitely not required for execution.
//
STATIC
EFI_STATUS
InitEbcVmTestProtocol (
IN EFI_HANDLE *Handle
);
STATIC
EFI_STATUS
EbcVmTestUnsupported (
VOID
);
STATIC
EFI_STATUS
EFIAPI
EbcRegisterICacheFlush (
IN EFI_EBC_PROTOCOL *This,
IN EBC_ICACHE_FLUSH Flush
);
STATIC
EFI_STATUS
EFIAPI
EbcDebugGetMaximumProcessorIndex (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
OUT UINTN *MaxProcessorIndex
);
STATIC
EFI_STATUS
EFIAPI
EbcDebugRegisterPeriodicCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_PERIODIC_CALLBACK PeriodicCallback
);
STATIC
EFI_STATUS
EFIAPI
EbcDebugRegisterExceptionCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_EXCEPTION_CALLBACK ExceptionCallback,
IN EFI_EXCEPTION_TYPE ExceptionType
);
STATIC
EFI_STATUS
EFIAPI
EbcDebugInvalidateInstructionCache (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN VOID *Start,
IN UINT64 Length
);
//
// We have one linked list of image handles for the whole world. Since
// there should only be one interpreter, make them global. They must
// also be global since the execution of an EBC image does not provide
// a This pointer.
//
static EBC_IMAGE_LIST *mEbcImageList = NULL;
//
// Callback function to flush the icache after thunk creation
//
static EBC_ICACHE_FLUSH mEbcICacheFlush;
//
// These get set via calls by the debug agent
//
static EFI_PERIODIC_CALLBACK mDebugPeriodicCallback = NULL;
static EFI_EXCEPTION_CALLBACK mDebugExceptionCallback = NULL;
static EFI_GUID mEfiEbcVmTestProtocolGuid = EFI_EBC_VM_TEST_PROTOCOL_GUID;
EFI_STATUS
EFIAPI
InitializeEbcDriver (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Initializes the VM EFI interface. Allocates memory for the VM interface
and registers the VM protocol.
Arguments:
ImageHandle - EFI image handle.
SystemTable - Pointer to the EFI system table.
Returns:
Standard EFI status code.
--*/
{
EFI_EBC_PROTOCOL *EbcProtocol;
EFI_EBC_PROTOCOL *OldEbcProtocol;
EFI_STATUS Status;
EFI_DEBUG_SUPPORT_PROTOCOL *EbcDebugProtocol;
EFI_HANDLE *HandleBuffer;
UINTN NumHandles;
UINTN Index;
BOOLEAN Installed;
//
// Allocate memory for our protocol. Then fill in the blanks.
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EFI_EBC_PROTOCOL),
(VOID **) &EbcProtocol
);
if (Status != EFI_SUCCESS) {
return EFI_OUT_OF_RESOURCES;
}
EbcProtocol->CreateThunk = EbcCreateThunk;
EbcProtocol->UnloadImage = EbcUnloadImage;
EbcProtocol->RegisterICacheFlush = EbcRegisterICacheFlush;
EbcProtocol->GetVersion = EbcGetVersion;
mEbcICacheFlush = NULL;
//
// Find any already-installed EBC protocols and uninstall them
//
Installed = FALSE;
HandleBuffer = NULL;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiEbcProtocolGuid,
NULL,
&NumHandles,
&HandleBuffer
);
if (Status == EFI_SUCCESS) {
//
// Loop through the handles
//
for (Index = 0; Index < NumHandles; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiEbcProtocolGuid,
(VOID **) &OldEbcProtocol
);
if (Status == EFI_SUCCESS) {
if (gBS->ReinstallProtocolInterface (
HandleBuffer[Index],
&gEfiEbcProtocolGuid,
OldEbcProtocol,
EbcProtocol
) == EFI_SUCCESS) {
Installed = TRUE;
}
}
}
}
if (HandleBuffer != NULL) {
gBS->FreePool (HandleBuffer);
HandleBuffer = NULL;
}
//
// Add the protocol so someone can locate us if we haven't already.
//
if (!Installed) {
Status = gBS->InstallProtocolInterface (
&ImageHandle,
&gEfiEbcProtocolGuid,
EFI_NATIVE_INTERFACE,
EbcProtocol
);
if (EFI_ERROR (Status)) {
gBS->FreePool (EbcProtocol);
return Status;
}
}
//
// Allocate memory for our debug protocol. Then fill in the blanks.
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EFI_DEBUG_SUPPORT_PROTOCOL),
(VOID **) &EbcDebugProtocol
);
if (Status != EFI_SUCCESS) {
return EFI_OUT_OF_RESOURCES;
}
EbcDebugProtocol->Isa = IsaEbc;
EbcDebugProtocol->GetMaximumProcessorIndex = EbcDebugGetMaximumProcessorIndex;
EbcDebugProtocol->RegisterPeriodicCallback = EbcDebugRegisterPeriodicCallback;
EbcDebugProtocol->RegisterExceptionCallback = EbcDebugRegisterExceptionCallback;
EbcDebugProtocol->InvalidateInstructionCache = EbcDebugInvalidateInstructionCache;
//
// Add the protocol so the debug agent can find us
//
Status = gBS->InstallProtocolInterface (
&ImageHandle,
&gEfiDebugSupportProtocolGuid,
EFI_NATIVE_INTERFACE,
EbcDebugProtocol
);
//
// This is recoverable, so free the memory and continue.
//
if (EFI_ERROR (Status)) {
gBS->FreePool (EbcDebugProtocol);
}
//
// Produce a VM test interface protocol. Not required for execution.
//
DEBUG_CODE (
InitEbcVmTestProtocol (&ImageHandle);
);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
EbcCreateThunk (
IN EFI_EBC_PROTOCOL *This,
IN EFI_HANDLE ImageHandle,
IN VOID *EbcEntryPoint,
OUT VOID **Thunk
)
/*++
Routine Description:
This is the top-level routine plugged into the EBC protocol. Since thunks
are very processor-specific, from here we dispatch directly to the very
processor-specific routine EbcCreateThunks().
Arguments:
This - protocol instance pointer
ImageHandle - handle to the image. The EBC interpreter may use this to keep
track of any resource allocations performed in loading and
executing the image.
EbcEntryPoint - the entry point for the image (as defined in the file header)
Thunk - pointer to thunk pointer where the address of the created
thunk is returned.
Returns:
EFI_STATUS
--*/
{
EFI_STATUS Status;
Status = EbcCreateThunks (
ImageHandle,
EbcEntryPoint,
Thunk,
FLAG_THUNK_ENTRY_POINT
);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
EbcDebugGetMaximumProcessorIndex (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
OUT UINTN *MaxProcessorIndex
)
/*++
Routine Description:
This EBC debugger protocol service is called by the debug agent
Arguments:
This - pointer to the caller's debug support protocol interface
MaxProcessorIndex - pointer to a caller allocated UINTN in which the maximum
processor index is returned.
Returns:
Standard EFI_STATUS
--*/
{
*MaxProcessorIndex = 0;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
EbcDebugRegisterPeriodicCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_PERIODIC_CALLBACK PeriodicCallback
)
/*++
Routine Description:
This protocol service is called by the debug agent to register a function
for us to call on a periodic basis.
Arguments:
This - pointer to the caller's debug support protocol interface
PeriodicCallback - pointer to the function to call periodically
Returns:
Always EFI_SUCCESS
--*/
{
mDebugPeriodicCallback = PeriodicCallback;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
EbcDebugRegisterExceptionCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN EFI_EXCEPTION_CALLBACK ExceptionCallback,
IN EFI_EXCEPTION_TYPE ExceptionType
)
/*++
Routine Description:
This protocol service is called by the debug agent to register a function
for us to call when we detect an exception.
Arguments:
This - pointer to the caller's debug support protocol interface
PeriodicCallback - pointer to the function to call periodically
Returns:
Always EFI_SUCCESS
--*/
{
mDebugExceptionCallback = ExceptionCallback;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
EbcDebugInvalidateInstructionCache (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
IN UINTN ProcessorIndex,
IN VOID *Start,
IN UINT64 Length
)
/*++
Routine Description:
This EBC debugger protocol service is called by the debug agent. Required
for DebugSupport compliance but is only stubbed out for EBC.
Arguments:
Returns:
EFI_SUCCESS
--*/
{
return EFI_SUCCESS;
}
EFI_STATUS
EbcDebugSignalException (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EXCEPTION_FLAGS ExceptionFlags,
IN VM_CONTEXT *VmPtr
)
/*++
Routine Description:
The VM interpreter calls this function when an exception is detected.
Arguments:
VmPtr - pointer to a VM context for passing info to the EFI debugger.
Returns:
EFI_SUCCESS if it returns at all
--*/
{
EFI_SYSTEM_CONTEXT_EBC EbcContext;
EFI_SYSTEM_CONTEXT SystemContext;
EFI_STATUS_CODE_VALUE StatusCodeValue;
BOOLEAN Report;
//
// Save the exception in the context passed in
//
VmPtr->ExceptionFlags |= ExceptionFlags;
VmPtr->LastException = ExceptionType;
//
// If it's a fatal exception, then flag it in the VM context in case an
// attached debugger tries to return from it.
//
if (ExceptionFlags & EXCEPTION_FLAG_FATAL) {
VmPtr->StopFlags |= STOPFLAG_APP_DONE;
}
//
// Initialize the context structure
//
EbcContext.R0 = VmPtr->R[0];
EbcContext.R1 = VmPtr->R[1];
EbcContext.R2 = VmPtr->R[2];
EbcContext.R3 = VmPtr->R[3];
EbcContext.R4 = VmPtr->R[4];
EbcContext.R5 = VmPtr->R[5];
EbcContext.R6 = VmPtr->R[6];
EbcContext.R7 = VmPtr->R[7];
EbcContext.Ip = (UINT64) (UINTN) VmPtr->Ip;
EbcContext.Flags = VmPtr->Flags;
SystemContext.SystemContextEbc = &EbcContext;
//
// If someone's registered for exception callbacks, then call them.
// Otherwise report the status code via the status code API
//
if (mDebugExceptionCallback != NULL) {
mDebugExceptionCallback (ExceptionType, SystemContext);
}
//
// Determine if we should report the exception. We report all of them by default,
// but if a debugger is attached don't report the breakpoint, debug, and step exceptions.
// Note that EXCEPT_EBC_OVERFLOW is never reported by this VM implementation, so is
// not included in the switch statement.
//
Report = TRUE;
switch (ExceptionType) {
case EXCEPT_EBC_UNDEFINED:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_UNDEFINED;
break;
case EXCEPT_EBC_DIVIDE_ERROR:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_DIVIDE_ERROR;
break;
case EXCEPT_EBC_DEBUG:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_DEBUG;
Report = (BOOLEAN) ((mDebugExceptionCallback == NULL) ? TRUE : FALSE);
break;
case EXCEPT_EBC_BREAKPOINT:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_BREAKPOINT;
Report = (BOOLEAN) ((mDebugExceptionCallback == NULL) ? TRUE : FALSE);
break;
case EXCEPT_EBC_INVALID_OPCODE:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_INVALID_OPCODE;
break;
case EXCEPT_EBC_STACK_FAULT:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_STACK_FAULT;
break;
case EXCEPT_EBC_ALIGNMENT_CHECK:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_ALIGNMENT_CHECK;
break;
case EXCEPT_EBC_INSTRUCTION_ENCODING:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_INSTRUCTION_ENCODING;
break;
case EXCEPT_EBC_BAD_BREAK:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_BAD_BREAK;
break;
case EXCEPT_EBC_STEP:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_STEP;
Report = (BOOLEAN) ((mDebugExceptionCallback == NULL) ? TRUE : FALSE);
break;
default:
StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_NON_SPECIFIC;
break;
}
//
// If we determined that we should report the condition, then do so now.
//
if (Report) {
REPORT_STATUS_CODE (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED, StatusCodeValue);
}
switch (ExceptionType) {
//
// If ReportStatusCode returned, then for most exceptions we do an assert. The
// ExceptionType++ is done simply to force the ASSERT() condition to be met.
// For breakpoints, assume a debugger did not insert a software breakpoint
// and skip the instruction.
//
case EXCEPT_EBC_BREAKPOINT:
VmPtr->Ip += 2;
break;
case EXCEPT_EBC_STEP:
break;
case EXCEPT_EBC_UNDEFINED:
ExceptionType++;
ASSERT (ExceptionType == EXCEPT_EBC_UNDEFINED);
break;
case EXCEPT_EBC_DIVIDE_ERROR:
ExceptionType++;
ASSERT (ExceptionType == EXCEPT_EBC_DIVIDE_ERROR);
break;
case EXCEPT_EBC_DEBUG:
ExceptionType++;
ASSERT (ExceptionType == EXCEPT_EBC_DEBUG);
break;
case EXCEPT_EBC_INVALID_OPCODE:
ExceptionType++;
ASSERT (ExceptionType == EXCEPT_EBC_INVALID_OPCODE);
break;
case EXCEPT_EBC_STACK_FAULT:
ExceptionType++;
ASSERT (ExceptionType == EXCEPT_EBC_STACK_FAULT);
break;
case EXCEPT_EBC_ALIGNMENT_CHECK:
ExceptionType++;
ASSERT (ExceptionType == EXCEPT_EBC_ALIGNMENT_CHECK);
break;
case EXCEPT_EBC_INSTRUCTION_ENCODING:
ExceptionType++;
ASSERT (ExceptionType == EXCEPT_EBC_INSTRUCTION_ENCODING);
break;
case EXCEPT_EBC_BAD_BREAK:
ExceptionType++;
ASSERT (ExceptionType == EXCEPT_EBC_BAD_BREAK);
break;
default:
//
// Unknown
//
ASSERT (0);
break;
}
return EFI_SUCCESS;
}
EFI_STATUS
EbcDebugPeriodic (
IN VM_CONTEXT *VmPtr
)
/*++
Routine Description:
The VM interpreter calls this function on a periodic basis to support
the EFI debug support protocol.
Arguments:
VmPtr - pointer to a VM context for passing info to the debugger.
Returns:
Standard EFI status.
--*/
{
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
EbcUnloadImage (
IN EFI_EBC_PROTOCOL *This,
IN EFI_HANDLE ImageHandle
)
/*++
Routine Description:
This routine is called by the core when an image is being unloaded from
memory. Basically we now have the opportunity to do any necessary cleanup.
Typically this will include freeing any memory allocated for thunk-creation.
Arguments:
This - protocol instance pointer
ImageHandle - handle to the image being unloaded.
Returns:
EFI_INVALID_PARAMETER - the ImageHandle passed in was not found in
the internal list of EBC image handles.
EFI_STATUS - completed successfully
--*/
{
EBC_THUNK_LIST *ThunkList;
EBC_THUNK_LIST *NextThunkList;
EBC_IMAGE_LIST *ImageList;
EBC_IMAGE_LIST *PrevImageList;
//
// First go through our list of known image handles and see if we've already
// created an image list element for this image handle.
//
PrevImageList = NULL;
for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {
if (ImageList->ImageHandle == ImageHandle) {
break;
}
//
// Save the previous so we can connect the lists when we remove this one
//
PrevImageList = ImageList;
}
if (ImageList == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Free up all the thunk buffers and thunks list elements for this image
// handle.
//
ThunkList = ImageList->ThunkList;
while (ThunkList != NULL) {
NextThunkList = ThunkList->Next;
gBS->FreePool (ThunkList->ThunkBuffer);
gBS->FreePool (ThunkList);
ThunkList = NextThunkList;
}
//
// Now remove this image list element from the chain
//
if (PrevImageList == NULL) {
//
// Remove from head
//
mEbcImageList = ImageList->Next;
} else {
PrevImageList->Next = ImageList->Next;
}
//
// Now free up the image list element
//
gBS->FreePool (ImageList);
return EFI_SUCCESS;
}
EFI_STATUS
EbcAddImageThunk (
IN EFI_HANDLE ImageHandle,
IN VOID *ThunkBuffer,
IN UINT32 ThunkSize
)
/*++
Routine Description:
Add a thunk to our list of thunks for a given image handle.
Also flush the instruction cache since we've written thunk code
to memory that will be executed eventually.
Arguments:
ImageHandle - the image handle to which the thunk is tied
ThunkBuffer - the buffer we've created/allocated
ThunkSize - the size of the thunk memory allocated
Returns:
EFI_OUT_OF_RESOURCES - memory allocation failed
EFI_SUCCESS - successful completion
--*/
{
EBC_THUNK_LIST *ThunkList;
EBC_IMAGE_LIST *ImageList;
EFI_STATUS Status;
//
// It so far so good, then flush the instruction cache
//
if (mEbcICacheFlush != NULL) {
Status = mEbcICacheFlush ((EFI_PHYSICAL_ADDRESS) (UINTN) ThunkBuffer, ThunkSize);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// Go through our list of known image handles and see if we've already
// created a image list element for this image handle.
//
for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {
if (ImageList->ImageHandle == ImageHandle) {
break;
}
}
if (ImageList == NULL) {
//
// Allocate a new one
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EBC_IMAGE_LIST),
(VOID **) &ImageList
);
if (Status != EFI_SUCCESS) {
return EFI_OUT_OF_RESOURCES;
}
ImageList->ThunkList = NULL;
ImageList->ImageHandle = ImageHandle;
ImageList->Next = mEbcImageList;
mEbcImageList = ImageList;
}
//
// Ok, now create a new thunk element to add to the list
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EBC_THUNK_LIST),
(VOID **) &ThunkList
);
if (Status != EFI_SUCCESS) {
return EFI_OUT_OF_RESOURCES;
}
//
// Add it to the head of the list
//
ThunkList->Next = ImageList->ThunkList;
ThunkList->ThunkBuffer = ThunkBuffer;
ImageList->ThunkList = ThunkList;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
EbcRegisterICacheFlush (
IN EFI_EBC_PROTOCOL *This,
IN EBC_ICACHE_FLUSH Flush
)
{
mEbcICacheFlush = Flush;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
EbcGetVersion (
IN EFI_EBC_PROTOCOL *This,
IN OUT UINT64 *Version
)
{
if (Version == NULL) {
return EFI_INVALID_PARAMETER;
}
*Version = GetVmVersion ();
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
InitEbcVmTestProtocol (
IN EFI_HANDLE *IHandle
)
/*++
Routine Description:
Produce an EBC VM test protocol that can be used for regression tests.
Arguments:
IHandle - handle on which to install the protocol.
Returns:
EFI_OUT_OF_RESOURCES - memory allocation failed
EFI_SUCCESS - successful completion
--*/
{
EFI_HANDLE Handle;
EFI_STATUS Status;
EFI_EBC_VM_TEST_PROTOCOL *EbcVmTestProtocol;
//
// Allocate memory for the protocol, then fill in the fields
//
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_EBC_VM_TEST_PROTOCOL), (VOID **) &EbcVmTestProtocol);
if (Status != EFI_SUCCESS) {
return EFI_OUT_OF_RESOURCES;
}
EbcVmTestProtocol->Execute = (EBC_VM_TEST_EXECUTE) EbcExecuteInstructions;
DEBUG_CODE(
EbcVmTestProtocol->Assemble = (EBC_VM_TEST_ASM) EbcVmTestUnsupported;
EbcVmTestProtocol->Disassemble = (EBC_VM_TEST_DASM) EbcVmTestUnsupported;
);
//
// Publish the protocol
//
Handle = NULL;
Status = gBS->InstallProtocolInterface (&Handle, &mEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);
if (EFI_ERROR (Status)) {
gBS->FreePool (EbcVmTestProtocol);
}
return Status;
}
STATIC
EFI_STATUS
EbcVmTestUnsupported ()
{
return EFI_UNSUPPORTED;
}

View File

@@ -0,0 +1,231 @@
/*++
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:
EbcInt.h
Abstract:
Main routines for the EBC interpreter. Includes the initialization and
main interpreter routines.
--*/
#ifndef _EBC_INT_H_
#define _EBC_INT_H_
typedef INT64 VM_REGISTER;
typedef UINT8 *VMIP; // instruction pointer for the VM
typedef UINT32 EXCEPTION_FLAGS;
typedef struct {
VM_REGISTER R[8]; // General purpose registers.
UINT64 Flags; // Flags register:
// 0 Set to 1 if the result of the last compare was true
// 1 Set to 1 if stepping
// 2..63 Reserved.
VMIP Ip; // Instruction pointer.
UINTN LastException; //
EXCEPTION_FLAGS ExceptionFlags; // to keep track of exceptions
UINT32 StopFlags;
UINT32 CompilerVersion; // via break(6)
UINTN HighStackBottom; // bottom of the upper stack
UINTN LowStackTop; // top of the lower stack
UINT64 StackRetAddr; // location of final return address on stack
UINTN *StackMagicPtr; // pointer to magic value on stack to detect corruption
EFI_HANDLE ImageHandle; // for this EBC driver
EFI_SYSTEM_TABLE *SystemTable; // for debugging only
UINTN LastAddrConverted; // for debug
UINTN LastAddrConvertedValue; // for debug
VOID *FramePtr;
VOID *EntryPoint; // entry point of EBC image
UINTN ImageBase;
} VM_CONTEXT;
//
// Bits of exception flags field of VM context
//
#define EXCEPTION_FLAG_FATAL 0x80000000 // can't continue
#define EXCEPTION_FLAG_ERROR 0x40000000 // bad, but try to continue
#define EXCEPTION_FLAG_WARNING 0x20000000 // harmless problem
#define EXCEPTION_FLAG_NONE 0x00000000 // for normal return
//
// Flags passed to the internal create-thunks function.
//
#define FLAG_THUNK_ENTRY_POINT 0x01 // thunk for an image entry point
#define FLAG_THUNK_PROTOCOL 0x00 // thunk for an EBC protocol service
//
// Put this value at the bottom of the VM's stack gap so we can check it on
// occasion to make sure the stack has not been corrupted.
//
#define VM_STACK_KEY_VALUE 0xDEADBEEF
EFI_STATUS
EbcCreateThunks (
IN EFI_HANDLE ImageHandle,
IN VOID *EbcEntryPoint,
OUT VOID **Thunk,
IN UINT32 Flags
)
;
EFI_STATUS
EbcAddImageThunk (
IN EFI_HANDLE ImageHandle,
IN VOID *ThunkBuffer,
IN UINT32 ThunkSize
)
;
//
// The interpreter calls these when an exception is detected,
// or as a periodic callback.
//
EFI_STATUS
EbcDebugSignalException (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EXCEPTION_FLAGS ExceptionFlags,
IN VM_CONTEXT *VmPtr
)
;
//
// Define a constant of how often to call the debugger periodic callback
// function.
//
#define EBC_VM_PERIODIC_CALLBACK_RATE 1000
EFI_STATUS
EbcDebugSignalPeriodic (
IN VM_CONTEXT *VmPtr
)
;
//
// External low level functions that are native-processor dependent
//
UINTN
EbcLLGetEbcEntryPoint (
VOID
)
;
UINTN
EbcLLGetStackPointer (
VOID
)
;
VOID
EbcLLCALLEXNative (
IN UINTN CallAddr,
IN UINTN EbcSp,
IN VOID *FramePtr
)
;
VOID
EbcLLCALLEX (
IN VM_CONTEXT *VmPtr,
IN UINTN CallAddr,
IN UINTN EbcSp,
IN VOID *FramePtr,
IN UINT8 Size
)
;
INT64
EbcLLGetReturnValue (
VOID
)
;
//
// Defines for a simple EBC debugger interface
//
typedef struct _EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL;
#define EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL_GUID \
{ \
0x2a72d11e, 0x7376, 0x40f6, { 0x9c, 0x68, 0x23, 0xfa, 0x2f, 0xe3, 0x63, 0xf1 } \
}
typedef
EFI_STATUS
(*EBC_DEBUGGER_SIGNAL_EXCEPTION) (
IN EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL * This,
IN VM_CONTEXT * VmPtr,
IN EFI_EXCEPTION_TYPE ExceptionType
);
typedef
VOID
(*EBC_DEBUGGER_DEBUG) (
IN EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL * This,
IN VM_CONTEXT * VmPtr
);
typedef
UINT32
(*EBC_DEBUGGER_DASM) (
IN EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL * This,
IN VM_CONTEXT * VmPtr,
IN UINT16 *DasmString OPTIONAL,
IN UINT32 DasmStringSize
);
//
// This interface allows you to configure the EBC debug support
// driver. For example, turn on or off saving and printing of
// delta VM even if called. Or to even disable the entire interface,
// in which case all functions become no-ops.
//
typedef
EFI_STATUS
(*EBC_DEBUGGER_CONFIGURE) (
IN EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL * This,
IN UINT32 ConfigId,
IN UINTN ConfigValue
);
//
// Prototype for the actual EBC debug support protocol interface
//
struct _EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL {
EBC_DEBUGGER_DEBUG Debugger;
EBC_DEBUGGER_SIGNAL_EXCEPTION SignalException;
EBC_DEBUGGER_DASM Dasm;
EBC_DEBUGGER_CONFIGURE Configure;
};
typedef struct {
EFI_EBC_PROTOCOL *This;
VOID *EntryPoint;
EFI_HANDLE ImageHandle;
VM_CONTEXT VmContext;
} EFI_EBC_THUNK_DATA;
#define EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('e', 'b', 'c', 'p')
struct _EBC_PROTOCOL_PRIVATE_DATA {
UINT32 Signature;
EFI_EBC_PROTOCOL EbcProtocol;
UINTN StackBase;
UINTN StackTop;
UINTN StackSize;
} ;
#define EBC_PROTOCOL_PRIVATE_DATA_FROM_THIS(a) \
CR(a, EBC_PROTOCOL_PRIVATE_DATA, EbcProtocol, EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE)
#endif // #ifndef _EBC_INT_H_

View File

@@ -0,0 +1,148 @@
page ,132
title VM ASSEMBLY LANGUAGE ROUTINES
;****************************************************************************
;*
;* 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.
;*
;****************************************************************************
;****************************************************************************
; REV 1.0
;****************************************************************************
;
; Rev Date Description
; --- -------- ------------------------------------------------------------
; 1.0 03/14/01 Initial creation of file.
;
;****************************************************************************
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; This code provides low level routines that support the Virtual Machine
; for option ROMs.
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;---------------------------------------------------------------------------
; Equate files needed.
;---------------------------------------------------------------------------
.XLIST
.LIST
;---------------------------------------------------------------------------
; Assembler options
;---------------------------------------------------------------------------
.686p
.model flat
.code
;---------------------------------------------------------------------------
;;GenericPostSegment SEGMENT USE16
;---------------------------------------------------------------------------
;****************************************************************************
; EbcLLCALLEXNative
;
; This function is called to execute an EBC CALLEX instruction
; to native code.
; This instruction requires that we thunk out to external native
; code. For IA32, we simply switch stacks and jump to the
; specified function. On return, we restore the stack pointer
; to its original location.
;
; Destroys no working registers.
;****************************************************************************
; VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
_EbcLLCALLEXNative PROC NEAR PUBLIC
push ebp
mov ebp, esp ; standard function prolog
; Get function address in a register
; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr]
mov ecx, dword ptr [esp]+8
; Set stack pointer to new value
; mov eax, NewStackPointer => mov eax, dword ptr [NewSp]
mov eax, dword ptr [esp] + 0Ch
mov esp, eax
; Now call the external routine
call ecx
; ebp is preserved by the callee. In this function it
; equals the original esp, so set them equal
mov esp, ebp
; Standard function epilog
mov esp, ebp
pop ebp
ret
_EbcLLCALLEXNative ENDP
; UINTN EbcLLGetEbcEntryPoint(VOID);
; Routine Description:
; The VM thunk code stuffs an EBC entry point into a processor
; register. Since we can't use inline assembly to get it from
; the interpreter C code, stuff it into the return value
; register and return.
;
; Arguments:
; None.
;
; Returns:
; The contents of the register in which the entry point is passed.
;
_EbcLLGetEbcEntryPoint PROC NEAR PUBLIC
ret
_EbcLLGetEbcEntryPoint ENDP
;/*++
;
;Routine Description:
;
; Return the caller's value of the stack pointer.
;
;Arguments:
;
; None.
;
;Returns:
;
; The current value of the stack pointer for the caller. We
; adjust it by 4 here because when they called us, the return address
; is put on the stack, thereby lowering it by 4 bytes.
;
;--*/
; UINTN EbcLLGetStackPointer()
_EbcLLGetStackPointer PROC NEAR PUBLIC
mov eax, esp ; get current stack pointer
add eax, 4 ; stack adjusted by this much when we were called
ret
_EbcLLGetStackPointer ENDP
; UINT64 EbcLLGetReturnValue(VOID);
; Routine Description:
; When EBC calls native, on return the VM has to stuff the return
; value into a VM register. It's assumed here that the value is still
; in the register, so simply return and the caller should get the
; return result properly.
;
; Arguments:
; None.
;
; Returns:
; The unmodified value returned by the native code.
;
_EbcLLGetReturnValue PROC NEAR PUBLIC
ret
_EbcLLGetReturnValue ENDP
END

View File

@@ -0,0 +1,482 @@
/*++
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:
EbcSupport.c
Abstract:
This module contains EBC support routines that are customized based on
the target processor.
--*/
#include "EbcInt.h"
#include "EbcExecute.h"
//
// NOTE: This is the stack size allocated for the interpreter
// when it executes an EBC image. The requirements can change
// based on whether or not a debugger is present, and other
// platform-specific configurations.
//
#define VM_STACK_SIZE (1024 * 4)
#define EBC_THUNK_SIZE 32
VOID
EbcLLCALLEX (
IN VM_CONTEXT *VmPtr,
IN UINTN FuncAddr,
IN UINTN NewStackPointer,
IN VOID *FramePtr,
IN UINT8 Size
)
/*++
Routine Description:
This function is called to execute an EBC CALLEX instruction.
The function check the callee's content to see whether it is common native
code or a thunk to another piece of EBC code.
If the callee is common native code, use EbcLLCAllEXASM to manipulate,
otherwise, set the VM->IP to target EBC code directly to avoid another VM
be startup which cost time and stack space.
Arguments:
VmPtr - Pointer to a VM context.
FuncAddr - Callee's address
NewStackPointer - New stack pointer after the call
FramePtr - New frame pointer after the call
Size - The size of call instruction
Returns:
None.
--*/
{
UINTN IsThunk;
UINTN TargetEbcAddr;
IsThunk = 1;
TargetEbcAddr = 0;
//
// Processor specific code to check whether the callee is a thunk to EBC.
//
if (*((UINT8 *)FuncAddr) != 0xB8) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 1) != 0xBC) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 2) != 0x2E) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 3) != 0x11) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 4) != 0xCA) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 5) != 0xB8) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 10) != 0xB9) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 15) != 0xFF) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 16) != 0xE1) {
IsThunk = 0;
goto Action;
}
TargetEbcAddr = ((UINTN)(*((UINT8 *)FuncAddr + 9)) << 24) + ((UINTN)(*((UINT8 *)FuncAddr + 8)) << 16) +
((UINTN)(*((UINT8 *)FuncAddr + 7)) << 8) + ((UINTN)(*((UINT8 *)FuncAddr + 6)));
Action:
if (IsThunk == 1){
//
// The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and
// put our return address and frame pointer on the VM stack.
// Then set the VM's IP to new EBC code.
//
VmPtr->R[0] -= 8;
VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], (UINTN) FramePtr);
VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->R[0];
VmPtr->R[0] -= 8;
VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], (UINT64) (UINTN) (VmPtr->Ip + Size));
VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;
} else {
//
// The callee is not a thunk to EBC, call native code.
//
EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr);
//
// Get return value and advance the IP.
//
VmPtr->R[7] = EbcLLGetReturnValue ();
VmPtr->Ip += Size;
}
}
STATIC
UINT64
EbcInterpret (
IN OUT UINTN Arg1,
IN OUT UINTN Arg2,
IN OUT UINTN Arg3,
IN OUT UINTN Arg4,
IN OUT UINTN Arg5,
IN OUT UINTN Arg6,
IN OUT UINTN Arg7,
IN OUT UINTN Arg8
)
/*++
Routine Description:
Begin executing an EBC image. The address of the entry point is passed
in via a processor register, so we'll need to make a call to get the
value.
Arguments:
None. Since we're called from a fixed up thunk (which we want to keep
small), our only so-called argument is the EBC entry point passed in
to us in a processor register.
Returns:
The value returned by the EBC application we're going to run.
--*/
{
//
// Create a new VM context on the stack
//
VM_CONTEXT VmContext;
UINTN Addr;
//
// Get the EBC entry point from the processor register.
//
Addr = EbcLLGetEbcEntryPoint ();
//
// Now clear out our context
//
ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));
//
// Set the VM instruction pointer to the correct location in memory.
//
VmContext.Ip = (VMIP) Addr;
//
// Initialize the stack pointer for the EBC. Get the current system stack
// pointer and adjust it down by the max needed for the interpreter.
//
Addr = EbcLLGetStackPointer ();
VmContext.R[0] = (UINT64) Addr;
VmContext.R[0] -= VM_STACK_SIZE;
//
// Align the stack on a natural boundary
//
VmContext.R[0] &= ~(sizeof (UINTN) - 1);
//
// Put a magic value in the stack gap, then adjust down again
//
*(UINTN *) (UINTN) (VmContext.R[0]) = (UINTN) VM_STACK_KEY_VALUE;
VmContext.StackMagicPtr = (UINTN *) (UINTN) VmContext.R[0];
VmContext.R[0] -= sizeof (UINTN);
//
// For IA32, this is where we say our return address is
//
VmContext.StackRetAddr = (UINT64) VmContext.R[0];
VmContext.LowStackTop = (UINTN) VmContext.R[0];
//
// We need to keep track of where the EBC stack starts. This way, if the EBC
// accesses any stack variables above its initial stack setting, then we know
// it's accessing variables passed into it, which means the data is on the
// VM's stack.
// When we're called, on the stack (high to low) we have the parameters, the
// return address, then the saved ebp. Save the pointer to the return address.
// EBC code knows that's there, so should look above it for function parameters.
// The offset is the size of locals (VMContext + Addr + saved ebp).
// Note that the interpreter assumes there is a 16 bytes of return address on
// the stack too, so adjust accordingly.
// VmContext.HighStackBottom = (UINTN)(Addr + sizeof (VmContext) + sizeof (Addr));
//
VmContext.HighStackBottom = (UINTN) &Arg1 - 16;
//
// Begin executing the EBC code
//
EbcExecute (&VmContext);
//
// Return the value in R[7] unless there was an error
//
return (UINT64) VmContext.R[7];
}
STATIC
UINT64
ExecuteEbcImageEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Begin executing an EBC image. The address of the entry point is passed
in via a processor register, so we'll need to make a call to get the
value.
Arguments:
ImageHandle - image handle for the EBC application we're executing
SystemTable - standard system table passed into an driver's entry point
Returns:
The value returned by the EBC application we're going to run.
--*/
{
//
// Create a new VM context on the stack
//
VM_CONTEXT VmContext;
UINTN Addr;
//
// Get the EBC entry point from the processor register. Make sure you don't
// call any functions before this or you could mess up the register the
// entry point is passed in.
//
Addr = EbcLLGetEbcEntryPoint ();
//
// Print(L"*** Thunked into EBC entry point - ImageHandle = 0x%X\n", (UINTN)ImageHandle);
// Print(L"EBC entry point is 0x%X\n", (UINT32)(UINTN)Addr);
//
// Now clear out our context
//
ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));
//
// Save the image handle so we can track the thunks created for this image
//
VmContext.ImageHandle = ImageHandle;
VmContext.SystemTable = SystemTable;
//
// Set the VM instruction pointer to the correct location in memory.
//
VmContext.Ip = (VMIP) Addr;
//
// Initialize the stack pointer for the EBC. Get the current system stack
// pointer and adjust it down by the max needed for the interpreter.
//
Addr = EbcLLGetStackPointer ();
VmContext.R[0] = (UINT64) Addr;
VmContext.R[0] -= VM_STACK_SIZE;
//
// Put a magic value in the stack gap, then adjust down again
//
*(UINTN *) (UINTN) (VmContext.R[0]) = (UINTN) VM_STACK_KEY_VALUE;
VmContext.StackMagicPtr = (UINTN *) (UINTN) VmContext.R[0];
VmContext.R[0] -= sizeof (UINTN);
//
// Align the stack on a natural boundary
// VmContext.R[0] &= ~(sizeof(UINTN) - 1);
//
VmContext.StackRetAddr = (UINT64) VmContext.R[0];
VmContext.LowStackTop = (UINTN) VmContext.R[0];
//
// VM pushes 16-bytes for return address. Simulate that here.
//
VmContext.HighStackBottom = (UINTN) &ImageHandle - 16;
//
// Begin executing the EBC code
//
EbcExecute (&VmContext);
//
// Return the value in R[7] unless there was an error
//
return (UINT64) VmContext.R[7];
}
EFI_STATUS
EbcCreateThunks (
IN EFI_HANDLE ImageHandle,
IN VOID *EbcEntryPoint,
OUT VOID **Thunk,
IN UINT32 Flags
)
/*++
Routine Description:
Create an IA32 thunk for the given EBC entry point.
Arguments:
ImageHandle - Handle of image for which this thunk is being created
EbcEntryPoint - Address of the EBC code that the thunk is to call
Thunk - Returned thunk we create here
Returns:
Standard EFI status.
--*/
{
UINT8 *Ptr;
UINT8 *ThunkBase;
UINT32 I;
UINT32 Addr;
INT32 Size;
INT32 ThunkSize;
EFI_STATUS Status;
//
// Check alignment of pointer to EBC code
//
if ((UINT32) (UINTN) EbcEntryPoint & 0x01) {
return EFI_INVALID_PARAMETER;
}
Size = EBC_THUNK_SIZE;
ThunkSize = Size;
Status = gBS->AllocatePool (
EfiBootServicesData,
Size,
(VOID *) &Ptr
);
if (Status != EFI_SUCCESS) {
return EFI_OUT_OF_RESOURCES;
}
//
// Print(L"Allocate TH: 0x%X\n", (UINT32)Ptr);
//
// Save the start address so we can add a pointer to it to a list later.
//
ThunkBase = Ptr;
//
// Give them the address of our buffer we're going to fix up
//
*Thunk = (VOID *) Ptr;
//
// Add a magic code here to help the VM recognize the thunk..
// mov eax, 0xca112ebc => B8 BC 2E 11 CA
//
*Ptr = 0xB8;
Ptr++;
Size--;
Addr = (UINT32) 0xCA112EBC;
for (I = 0; I < sizeof (Addr); I++) {
*Ptr = (UINT8) (UINTN) Addr;
Addr >>= 8;
Ptr++;
Size--;
}
//
// Add code bytes to load up a processor register with the EBC entry point.
// mov eax, 0xaa55aa55 => B8 55 AA 55 AA
// The first 8 bytes of the thunk entry is the address of the EBC
// entry point.
//
*Ptr = 0xB8;
Ptr++;
Size--;
Addr = (UINT32) EbcEntryPoint;
for (I = 0; I < sizeof (Addr); I++) {
*Ptr = (UINT8) (UINTN) Addr;
Addr >>= 8;
Ptr++;
Size--;
}
//
// Stick in a load of ecx with the address of appropriate VM function.
// mov ecx 12345678h => 0xB9 0x78 0x56 0x34 0x12
//
if (Flags & FLAG_THUNK_ENTRY_POINT) {
Addr = (UINT32) (UINTN) ExecuteEbcImageEntryPoint;
} else {
Addr = (UINT32) (UINTN) EbcInterpret;
}
//
// MOV ecx
//
*Ptr = 0xB9;
Ptr++;
Size--;
for (I = 0; I < sizeof (Addr); I++) {
*Ptr = (UINT8) Addr;
Addr >>= 8;
Ptr++;
Size--;
}
//
// Stick in jump opcode bytes for jmp ecx => 0xFF 0xE1
//
*Ptr = 0xFF;
Ptr++;
Size--;
*Ptr = 0xE1;
Size--;
//
// Double check that our defined size is ok (application error)
//
if (Size < 0) {
ASSERT (FALSE);
return EFI_BUFFER_TOO_SMALL;
}
//
// Add the thunk to the list for this image. Do this last since the add
// function flushes the cache for us.
//
EbcAddImageThunk (ImageHandle, (VOID *) ThunkBase, ThunkSize);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,622 @@
TITLE Ia32math.asm: Generic math routines for EBC interpreter running on IA32 processor
;------------------------------------------------------------------------------
;
; 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:
;
; Ia32math.asm
;
; Abstract:
;
; Generic math routines for EBC interpreter running on IA32 processor
;
;------------------------------------------------------------------------------
.686P
.XMM
.MODEL SMALL
.CODE
LeftShiftU64 PROTO C Operand: QWORD, CountIn: QWORD
RightShiftU64 PROTO C Operand: QWORD, CountIn: QWORD
ARightShift64 PROTO C Operand: QWORD, CountIn: QWORD
MulU64x64 PROTO C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
MulS64x64 PROTO C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
DivU64x64 PROTO C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD
DivS64x64 PROTO C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD
LeftShiftU64 PROC C Operand: QWORD, CountIn: QWORD
;------------------------------------------------------------------------------
; UINT64
; LeftShiftU64 (
; IN UINT64 Operand,
; IN UINT64 CountIn
; )
;
; Routine Description:
;
; Left-shift a 64-bit value.
;
; Arguments:
;
; Operand - the value to shift
; Count - shift count
;
; Returns:
;
; Operand << Count
;------------------------------------------------------------------------------
push ecx
;
; if (CountIn > 63) return 0;
;
cmp dword ptr CountIn[4], 0
jne _LeftShiftU64_Overflow
mov ecx, dword ptr CountIn[0]
cmp ecx, 63
jbe _LeftShiftU64_Calc
_LeftShiftU64_Overflow:
xor eax, eax
xor edx, edx
jmp _LeftShiftU64_Done
_LeftShiftU64_Calc:
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
shld edx, eax, cl
shl eax, cl
cmp ecx, 32
jc short _LeftShiftU64_Done
mov edx, eax
xor eax, eax
_LeftShiftU64_Done:
pop ecx
ret
LeftShiftU64 ENDP
RightShiftU64 PROC C Operand: QWORD, CountIn: QWORD
;------------------------------------------------------------------------------
; UINT64
; RightShiftU64 (
; IN UINT64 Operand,
; IN UINT64 CountIn
; )
;
; Routine Description:
;
; Right-shift an unsigned 64-bit value.
;
; Arguments:
;
; Operand - the value to shift
; Count - shift count
;
; Returns:
;
; Operand >> Count
;------------------------------------------------------------------------------
push ecx
;
; if (CountIn > 63) return 0;
;
cmp dword ptr CountIn[4], 0
jne _RightShiftU64_Overflow
mov ecx, dword ptr CountIn[0]
cmp ecx, 63
jbe _RightShiftU64_Calc
_RightShiftU64_Overflow:
xor eax, eax
xor edx, edx
jmp _RightShiftU64_Done
_RightShiftU64_Calc:
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
shrd edx, eax, cl
shr eax, cl
cmp ecx, 32
jc short _RightShiftU64_Done
mov eax, edx
xor edx, edx
_RightShiftU64_Done:
pop ecx
ret
RightShiftU64 ENDP
ARightShift64 PROC C Operand: QWORD, CountIn: QWORD
;------------------------------------------------------------------------------
; INT64
; ARightShift64 (
; IN INT64 Operand,
; IN UINT64 CountIn
; )
;
; Routine Description:
;
; Arithmatic shift a 64 bit signed value.
;
; Arguments:
;
; Operand - the value to shift
; Count - shift count
;
; Returns:
;
; Operand >> Count
;------------------------------------------------------------------------------
push ecx
;
; If they exceeded the max shift count, then return either 0 or all F's
; depending on the sign bit.
;
cmp dword ptr CountIn[4], 0
jne _ARightShiftU64_Overflow
mov ecx, dword ptr CountIn[0]
cmp ecx, 63
jbe _ARightShiftU64_Calc
_ARightShiftU64_Overflow:
;
; Check the sign bit of Operand
;
bt dword ptr Operand[4], 31
jnc _ARightShiftU64_Return_Zero
;
; return -1
;
or eax, 0FFFFFFFFh
or edx, 0FFFFFFFFh
jmp _ARightShiftU64_Done
_ARightShiftU64_Return_Zero:
xor eax, eax
xor edx, edx
jmp _ARightShiftU64_Done
_ARightShiftU64_Calc:
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
shrd eax, edx, cl
sar edx, cl
cmp ecx, 32
jc short _ARightShiftU64_Done
;
; if ecx >= 32, then eax = edx, and edx = sign bit
;
mov eax, edx
sar edx, 31
_ARightShiftU64_Done:
pop ecx
ret
ARightShift64 ENDP
MulU64x64 PROC C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
;------------------------------------------------------------------------------
; UINT64
; MulU64x64 (
; UINT64 Value1,
; UINT64 Value2,
; UINT64 *ResultHigh
; )
;
; Routine Description:
;
; Multiply two unsigned 64-bit values.
;
; Arguments:
;
; Value1 - first value to multiply
; Value2 - value to multiply by Value1
; ResultHigh - result to flag overflows
;
; Returns:
;
; Value1 * Value2
; The 128-bit result is the concatenation of *ResultHigh and the return value
;------------------------------------------------------------------------------
push ebx
push ecx
mov ebx, ResultHigh ; ebx points to the high 4 words of result
;
; The result consists of four double-words.
; Here we assume their names from low to high: dw0, dw1, dw2, dw3
;
mov eax, dword ptr Value1[0]
mul dword ptr Value2[0]
push eax ; eax contains final result of dw0, push it
mov ecx, edx ; ecx contains partial result of dw1
mov eax, dword ptr Value1[4]
mul dword ptr Value2[0]
add ecx, eax ; add eax to partial result of dw1
adc edx, 0
mov dword ptr [ebx], edx ; lower double-word of ResultHigh contains partial result of dw2
mov eax, dword ptr Value1[0]
mul dword ptr Value2[4]
add ecx, eax ; add eax to partial result of dw1
push ecx ; ecx contains final result of dw1, push it
adc edx, 0
mov ecx, edx ; ecx contains partial result of dw2, together with ResultHigh
mov eax, dword ptr Value1[4]
mul dword ptr Value2[4]
add ecx, eax ; add eax to partial result of dw2
adc edx, 0
add dword ptr [ebx], ecx ; lower double-word of ResultHigh contains final result of dw2
adc edx, 0
mov dword ptr [ebx + 4], edx ; high double-word of ResultHigh contains final result of dw3
pop edx ; edx contains the final result of dw1
pop eax ; edx contains the final result of dw0
pop ecx
pop ebx
ret
MulU64x64 ENDP
MulS64x64 PROC C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
;------------------------------------------------------------------------------
; INT64
; MulS64x64 (
; INT64 Value1,
; INT64 Value2,
; INT64 *ResultHigh
; )
;
; Routine Description:
;
; Multiply two signed 64-bit values.
;
; Arguments:
;
; Value1 - first value to multiply
; Value2 - value to multiply by Value1
; ResultHigh - result to flag overflows
;
; Returns:
;
; Value1 * Value2
; The 128-bit result is the concatenation of *ResultHigh and the return value
;------------------------------------------------------------------------------
push ebx
push ecx
mov ebx, ResultHigh ; ebx points to the high 4 words of result
xor ecx, ecx ; the lowest bit of ecx flags the sign
mov edx, dword ptr Value1[4]
bt edx, 31
jnc short _MulS64x64_A_Positive
;
; a is negative
;
mov eax, dword ptr Value1[0]
not edx
not eax
add eax, 1
adc edx, 0
mov dword ptr Value1[0], eax
mov dword ptr Value1[4], edx
btc ecx, 0
_MulS64x64_A_Positive:
mov edx, dword ptr Value2[4]
bt edx, 31
jnc short _MulS64x64_B_Positive
;
; b is negative
;
mov eax, dword ptr Value2[0]
not edx
not eax
add eax, 1
adc edx, 0
mov dword ptr Value2[0], eax
mov dword ptr Value2[4], edx
btc ecx, 0
_MulS64x64_B_Positive:
invoke MulU64x64, Value1, Value2, ResultHigh
bt ecx, 0
jnc short _MulS64x64_Done
;
;negate the result
;
not eax
not edx
not dword ptr [ebx]
not dword ptr [ebx + 4]
add eax, 1
adc edx, 0
adc dword ptr [ebx], 0
adc dword ptr [ebx + 4], 0
_MulS64x64_Done:
pop ecx
pop ebx
ret
MulS64x64 ENDP
DivU64x64 PROC C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD,
;------------------------------------------------------------------------------
; UINT64
; DivU64x64 (
; IN UINT64 Dividend,
; IN UINT64 Divisor,
; OUT UINT64 *Remainder OPTIONAL,
; OUT UINT32 *Error
; )
;
; Routine Description:
;
; This routine allows a 64 bit value to be divided with a 64 bit value returns
; 64bit result and the Remainder
;
; Arguments:
;
; Dividend - dividend
; Divisor - divisor
; ResultHigh - result to flag overflows
; Error - flag for error
;
; Returns:
;
; Dividend / Divisor
; Remainder = Dividend mod Divisor
;------------------------------------------------------------------------------
push ecx
mov eax, Error
mov dword ptr [eax], 0
cmp dword ptr Divisor[0], 0
jne _DivU64x64_Valid
cmp dword ptr Divisor[4], 0
jne _DivU64x64_Valid
;
; the divisor is zero
;
mov dword ptr [eax], 1
cmp Remainder, 0
je _DivU64x64_Invalid_Return
;
; fill the remainder if the pointer is not null
;
mov eax, Remainder
mov dword ptr [eax], 0
mov dword ptr [eax + 4], 80000000h
_DivU64x64_Invalid_Return:
xor eax, eax
mov edx, 80000000h
jmp _DivU64x64_Done
_DivU64x64_Valid:
;
; let edx and eax contain the intermediate result of remainder
;
xor edx, edx
xor eax, eax
mov ecx, 64
_DivU64x64_Wend:
;
; shift dividend left one
;
shl dword ptr Dividend[0], 1
rcl dword ptr Dividend[4], 1
;
; rotate intermediate result of remainder left one
;
rcl eax, 1
rcl edx, 1
cmp edx, dword ptr Divisor[4]
ja _DivU64x64_Sub_Divisor
jb _DivU64x64_Cont
cmp eax, dword ptr Divisor[0]
jb _DivU64x64_Cont
_DivU64x64_Sub_Divisor:
;
; If intermediate result of remainder is larger than
; or equal to divisor, then set the lowest bit of dividend,
; and subtract divisor from intermediate remainder
;
bts dword ptr Dividend[0], 0
sub eax, dword ptr Divisor[0]
sbb edx, dword ptr Divisor[4]
_DivU64x64_Cont:
loop _DivU64x64_Wend
cmp Remainder, 0
je _DivU64x64_Assign
mov ecx, Remainder
mov dword ptr [ecx], eax
mov dword ptr [ecx + 4], edx
_DivU64x64_Assign:
mov eax, dword ptr Dividend[0]
mov edx, dword ptr Dividend[4]
_DivU64x64_Done:
pop ecx
ret
DivU64x64 ENDP
DivS64x64 PROC C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD,
;------------------------------------------------------------------------------
; INT64
; DivU64x64 (
; IN INT64 Dividend,
; IN INT64 Divisor,
; OUT UINT64 *Remainder OPTIONAL,
; OUT UINT32 *Error
; )
;
; Routine Description:
;
; This routine allows a 64 bit signed value to be divided with a 64 bit
; signed value returns 64bit result and the Remainder.
;
; Arguments:
;
; Dividend - dividend
; Divisor - divisor
; ResultHigh - result to flag overflows
; Error - flag for error
;
; Returns:
;
; Dividend / Divisor
; Remainder = Dividend mod Divisor
;------------------------------------------------------------------------------
push ecx
mov eax, Error
mov dword ptr [eax], 0
cmp dword ptr Divisor[0], 0
jne _DivS64x64_Valid
cmp dword ptr Divisor[4], 0
jne _DivS64x64_Valid
;
; the divisor is zero
;
mov dword ptr [eax], 1
cmp Remainder, 0
je _DivS64x64_Invalid_Return
;
; fill the remainder if the pointer is not null
;
mov eax, Remainder
mov dword ptr [eax], 0
mov dword ptr [eax + 4], 80000000h
_DivS64x64_Invalid_Return:
xor eax, eax
mov edx, 80000000h
jmp _DivS64x64_Done
_DivS64x64_Valid:
;
; The lowest bit of ecx flags the sign of quotient,
; The seconde lowest bit flags the sign of remainder
;
xor ecx, ecx
mov edx, dword ptr Dividend[4]
bt edx, 31
jnc short _DivS64x64_Dividend_Positive
;
; dividend is negative
;
mov eax, dword ptr Dividend[0]
not edx
not eax
add eax, 1
adc edx, 0
mov dword ptr Dividend[0], eax
mov dword ptr Dividend[4], edx
;
; set both the flags for signs of quotient and remainder
;
btc ecx, 0
btc ecx, 1
_DivS64x64_Dividend_Positive:
mov edx, dword ptr Divisor[4]
bt edx, 31
jnc short _DivS64x64_Divisor_Positive
;
; divisor is negative
;
mov eax, dword ptr Divisor[0]
not edx
not eax
add eax, 1
adc edx, 0
mov dword ptr Divisor[0], eax
mov dword ptr Divisor[4], edx
;
; just complement the flag for sign of quotient
;
btc ecx, 0
_DivS64x64_Divisor_Positive:
invoke DivU64x64, Dividend, Divisor, Remainder, Error
bt ecx, 0
jnc short _DivS64x64_Remainder
;
; negate the quotient
;
not eax
not edx
add eax, 1
adc edx, 0
_DivS64x64_Remainder:
bt ecx, 1
jnc short _DivS64x64_Done
;
; negate the remainder
;
mov ecx, remainder
not dword ptr [ecx]
not dword ptr [ecx + 4]
add dword ptr [ecx], 1
adc dword ptr [ecx + 4], 0
_DivS64x64_Done:
pop ecx
ret
DivS64x64 ENDP
END

View File

@@ -0,0 +1,167 @@
//++
// 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:
//
// EbcLowLevel.s
//
// Abstract:
//
// Contains low level routines for the Virtual Machine implementation
// on an Itanium-based platform.
//
//
//--
.file "EbcLowLevel.s"
#define PROCEDURE_ENTRY(name) .##text; \
.##type name, @function; \
.##proc name; \
name::
#define PROCEDURE_EXIT(name) .##endp name
// Note: use of NESTED_SETUP requires number of locals (l) >= 3
#define NESTED_SETUP(i,l,o,r) \
alloc loc1=ar##.##pfs,i,l,o,r ;\
mov loc0=b0
#define NESTED_RETURN \
mov b0=loc0 ;\
mov ar##.##pfs=loc1 ;;\
br##.##ret##.##dpnt b0;;
//-----------------------------------------------------------------------------
//++
// EbcAsmLLCALLEX
//
// Implements the low level EBC CALLEX instruction. Sets up the
// stack pointer, does the spill of function arguments, and
// calls the native function. On return it restores the original
// stack pointer and returns to the caller.
//
// Arguments :
//
// On Entry :
// in0 = Address of native code to call
// in1 = New stack pointer
//
// Return Value:
//
// As per static calling conventions.
//
//--
//---------------------------------------------------------------------------
;// void EbcAsmLLCALLEX (UINTN FunctionAddr, UINTN EbcStackPointer)
PROCEDURE_ENTRY(EbcAsmLLCALLEX)
NESTED_SETUP (2,6,8,0)
// NESTED_SETUP uses loc0 and loc1 for context save
//
// Save a copy of the EBC VM stack pointer
//
mov r8 = in1;;
//
// Copy stack arguments from EBC stack into registers.
// Assume worst case and copy 8.
//
ld8 out0 = [r8], 8;;
ld8 out1 = [r8], 8;;
ld8 out2 = [r8], 8;;
ld8 out3 = [r8], 8;;
ld8 out4 = [r8], 8;;
ld8 out5 = [r8], 8;;
ld8 out6 = [r8], 8;;
ld8 out7 = [r8], 8;;
//
// Save the original stack pointer
//
mov loc2 = r12;
//
// Save the gp
//
or loc3 = r1, r0
//
// Set the new aligned stack pointer. Reserve space for the required
// 16-bytes of scratch area as well.
//
add r12 = 48, in1
//
// Now call the function. Load up the function address from the descriptor
// pointed to by in0. Then get the gp from the descriptor at the following
// address in the descriptor.
//
ld8 r31 = [in0], 8;;
ld8 r30 = [in0];;
mov b1 = r31
mov r1 = r30
(p0) br.call.dptk.many b0 = b1;;
//
// Restore the original stack pointer and gp
//
mov r12 = loc2
or r1 = loc3, r0
//
// Now return
//
NESTED_RETURN
PROCEDURE_EXIT(EbcAsmLLCALLEX)
//
// UINTN EbcLLGetEbcEntryPoint(VOID)
//
// Description:
// Simply return, so that the caller retrieves the return register
// contents (R8). That's where the thunk-to-ebc code stuffed the
// EBC entry point.
//
PROCEDURE_ENTRY(EbcLLGetEbcEntryPoint)
br.ret.sptk b0 ;;
PROCEDURE_EXIT(EbcLLGetEbcEntryPoint)
//
// INT64 EbcLLGetReturnValue(VOID)
//
// Description:
// This function is called to get the value returned by native code
// to EBC. It simply returns because the return value should still
// be in the register, so the caller just gets the unmodified value.
//
PROCEDURE_ENTRY(EbcLLGetReturnValue)
br.ret.sptk b0 ;;
PROCEDURE_EXIT(EbcLLGetReturnValue)
//
// UINTN EbcLLGetStackPointer(VOID)
//
PROCEDURE_ENTRY(EbcLLGetStackPointer)
mov r8 = r12 ;;
br.ret.sptk b0 ;;
br.sptk.few b6
PROCEDURE_EXIT(EbcLLGetStackPointer)

View File

@@ -0,0 +1,906 @@
/*++
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:
EbcSupport.c
Abstract:
This module contains EBC support routines that are customized based on
the target processor.
--*/
#include "EbcInt.h"
#include "EbcExecute.h"
#define VM_STACK_SIZE (1024 * 32)
#define EBC_THUNK_SIZE 128
//
// For code execution, thunks must be aligned on 16-byte boundary
//
#define EBC_THUNK_ALIGNMENT 16
//
// Per the IA-64 Software Conventions and Runtime Architecture Guide,
// section 3.3.4, IPF stack must always be 16-byte aligned.
//
#define IPF_STACK_ALIGNMENT 16
//
// Opcodes for IPF instructions. We'll need to hand-create thunk code (stuffing
// bits) to insert a jump to the interpreter.
//
#define OPCODE_NOP (UINT64) 0x00008000000
#define OPCODE_BR_COND_SPTK_FEW (UINT64) 0x00100000000
#define OPCODE_MOV_BX_RX (UINT64) 0x00E00100000
//
// Opcode for MOVL instruction
//
#define MOVL_OPCODE 0x06
VOID
EbcAsmLLCALLEX (
IN UINTN CallAddr,
IN UINTN EbcSp
);
STATIC
EFI_STATUS
WriteBundle (
IN VOID *MemPtr,
IN UINT8 Template,
IN UINT64 Slot0,
IN UINT64 Slot1,
IN UINT64 Slot2
);
STATIC
VOID
PushU64 (
VM_CONTEXT *VmPtr,
UINT64 Arg
)
{
//
// Advance the VM stack down, and then copy the argument to the stack.
// Hope it's aligned.
//
VmPtr->R[0] -= sizeof (UINT64);
*(UINT64 *) VmPtr->R[0] = Arg;
}
UINT64
EbcInterpret (
UINT64 Arg1,
...
)
{
//
// Create a new VM context on the stack
//
VM_CONTEXT VmContext;
UINTN Addr;
VA_LIST List;
UINT64 Arg2;
UINT64 Arg3;
UINT64 Arg4;
UINT64 Arg5;
UINT64 Arg6;
UINT64 Arg7;
UINT64 Arg8;
UINTN Arg9Addr;
//
// Get the EBC entry point from the processor register. Make sure you don't
// call any functions before this or you could mess up the register the
// entry point is passed in.
//
Addr = EbcLLGetEbcEntryPoint ();
//
// Need the args off the stack.
//
VA_START (List, Arg1);
Arg2 = VA_ARG (List, UINT64);
Arg3 = VA_ARG (List, UINT64);
Arg4 = VA_ARG (List, UINT64);
Arg5 = VA_ARG (List, UINT64);
Arg6 = VA_ARG (List, UINT64);
Arg7 = VA_ARG (List, UINT64);
Arg8 = VA_ARG (List, UINT64);
Arg9Addr = (UINTN) List;
//
// Now clear out our context
//
ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));
//
// Set the VM instruction pointer to the correct location in memory.
//
VmContext.Ip = (VMIP) Addr;
//
// Initialize the stack pointer for the EBC. Get the current system stack
// pointer and adjust it down by the max needed for the interpreter.
//
Addr = (UINTN) Arg9Addr;
//
// NOTE: Eventually we should have the interpreter allocate memory
// for stack space which it will use during its execution. This
// would likely improve performance because the interpreter would
// no longer be required to test each memory access and adjust
// those reading from the stack gap.
//
// For IPF, the stack looks like (assuming 10 args passed)
// arg10
// arg9 (Bottom of high stack)
// [ stack gap for interpreter execution ]
// [ magic value for detection of stack corruption ]
// arg8 (Top of low stack)
// arg7....
// arg1
// [ 64-bit return address ]
// [ ebc stack ]
// If the EBC accesses memory in the stack gap, then we assume that it's
// actually trying to access args9 and greater. Therefore we need to
// adjust memory accesses in this region to point above the stack gap.
//
VmContext.HighStackBottom = (UINTN) Addr;
//
// Now adjust the EBC stack pointer down to leave a gap for interpreter
// execution. Then stuff a magic value there.
//
VmContext.R[0] = (UINT64) Addr;
VmContext.R[0] -= VM_STACK_SIZE;
PushU64 (&VmContext, (UINT64) VM_STACK_KEY_VALUE);
VmContext.StackMagicPtr = (UINTN *) VmContext.R[0];
VmContext.LowStackTop = (UINTN) VmContext.R[0];
//
// Push the EBC arguments on the stack. Does not matter that they may not
// all be valid.
//
PushU64 (&VmContext, Arg8);
PushU64 (&VmContext, Arg7);
PushU64 (&VmContext, Arg6);
PushU64 (&VmContext, Arg5);
PushU64 (&VmContext, Arg4);
PushU64 (&VmContext, Arg3);
PushU64 (&VmContext, Arg2);
PushU64 (&VmContext, Arg1);
//
// Push a bogus return address on the EBC stack because the
// interpreter expects one there. For stack alignment purposes on IPF,
// EBC return addresses are always 16 bytes. Push a bogus value as well.
//
PushU64 (&VmContext, 0);
PushU64 (&VmContext, 0xDEADBEEFDEADBEEF);
VmContext.StackRetAddr = (UINT64) VmContext.R[0];
//
// Begin executing the EBC code
//
EbcExecute (&VmContext);
//
// Return the value in R[7] unless there was an error
//
return (UINT64) VmContext.R[7];
}
UINT64
ExecuteEbcImageEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
IPF implementation.
Begin executing an EBC image. The address of the entry point is passed
in via a processor register, so we'll need to make a call to get the
value.
Arguments:
ImageHandle - image handle for the EBC application we're executing
SystemTable - standard system table passed into an driver's entry point
Returns:
The value returned by the EBC application we're going to run.
--*/
{
//
// Create a new VM context on the stack
//
VM_CONTEXT VmContext;
UINTN Addr;
//
// Get the EBC entry point from the processor register. Make sure you don't
// call any functions before this or you could mess up the register the
// entry point is passed in.
//
Addr = EbcLLGetEbcEntryPoint ();
//
// Now clear out our context
//
ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));
//
// Save the image handle so we can track the thunks created for this image
//
VmContext.ImageHandle = ImageHandle;
VmContext.SystemTable = SystemTable;
//
// Set the VM instruction pointer to the correct location in memory.
//
VmContext.Ip = (VMIP) Addr;
//
// Get the stack pointer. This is the bottom of the upper stack.
//
Addr = EbcLLGetStackPointer ();
VmContext.HighStackBottom = (UINTN) Addr;
VmContext.R[0] = (INT64) Addr;
//
// Allocate stack space for the interpreter. Then put a magic value
// at the bottom so we can detect stack corruption.
//
VmContext.R[0] -= VM_STACK_SIZE;
PushU64 (&VmContext, (UINT64) VM_STACK_KEY_VALUE);
VmContext.StackMagicPtr = (UINTN *) (UINTN) VmContext.R[0];
//
// When we thunk to external native code, we copy the last 8 qwords from
// the EBC stack into the processor registers, and adjust the stack pointer
// up. If the caller is not passing 8 parameters, then we've moved the
// stack pointer up into the stack gap. If this happens, then the caller
// can mess up the stack gap contents (in particular our magic value).
// Therefore, leave another gap below the magic value. Pick 10 qwords down,
// just as a starting point.
//
VmContext.R[0] -= 10 * sizeof (UINT64);
//
// Align the stack pointer such that after pushing the system table,
// image handle, and return address on the stack, it's aligned on a 16-byte
// boundary as required for IPF.
//
VmContext.R[0] &= (INT64)~0x0f;
VmContext.LowStackTop = (UINTN) VmContext.R[0];
//
// Simply copy the image handle and system table onto the EBC stack.
// Greatly simplifies things by not having to spill the args
//
PushU64 (&VmContext, (UINT64) SystemTable);
PushU64 (&VmContext, (UINT64) ImageHandle);
//
// Interpreter assumes 64-bit return address is pushed on the stack.
// IPF does not do this so pad the stack accordingly. Also, a
// "return address" is 16 bytes as required for IPF stack alignments.
//
PushU64 (&VmContext, (UINT64) 0);
PushU64 (&VmContext, (UINT64) 0x1234567887654321);
VmContext.StackRetAddr = (UINT64) VmContext.R[0];
//
// Begin executing the EBC code
//
EbcExecute (&VmContext);
//
// Return the value in R[7] unless there was an error
//
return (UINT64) VmContext.R[7];
}
EFI_STATUS
EbcCreateThunks (
IN EFI_HANDLE ImageHandle,
IN VOID *EbcEntryPoint,
OUT VOID **Thunk,
IN UINT32 Flags
)
/*++
Routine Description:
Create thunks for an EBC image entry point, or an EBC protocol service.
Arguments:
ImageHandle - Image handle for the EBC image. If not null, then we're
creating a thunk for an image entry point.
EbcEntryPoint - Address of the EBC code that the thunk is to call
Thunk - Returned thunk we create here
Flags - Flags indicating options for creating the thunk
Returns:
Standard EFI status.
--*/
{
UINT8 *Ptr;
UINT8 *ThunkBase;
UINT64 Addr;
UINT64 Code[3]; // Code in a bundle
UINT64 RegNum; // register number for MOVL
UINT64 I; // bits of MOVL immediate data
UINT64 Ic; // bits of MOVL immediate data
UINT64 Imm5c; // bits of MOVL immediate data
UINT64 Imm9d; // bits of MOVL immediate data
UINT64 Imm7b; // bits of MOVL immediate data
UINT64 Br; // branch register for loading and jumping
UINT64 *Data64Ptr;
UINT32 ThunkSize;
UINT32 Size;
EFI_STATUS Status;
//
// Check alignment of pointer to EBC code, which must always be aligned
// on a 2-byte boundary.
//
if ((UINT32) (UINTN) EbcEntryPoint & 0x01) {
return EFI_INVALID_PARAMETER;
}
//
// Allocate memory for the thunk. Make the (most likely incorrect) assumption
// that the returned buffer is not aligned, so round up to the next
// alignment size.
//
Size = EBC_THUNK_SIZE + EBC_THUNK_ALIGNMENT - 1;
ThunkSize = Size;
Status = gBS->AllocatePool (
EfiBootServicesData,
Size,
(VOID *) &Ptr
);
if (Status != EFI_SUCCESS) {
return EFI_OUT_OF_RESOURCES;
}
//
// Save the start address of the buffer.
//
ThunkBase = Ptr;
//
// Make sure it's aligned for code execution. If not, then
// round up.
//
if ((UINT32) (UINTN) Ptr & (EBC_THUNK_ALIGNMENT - 1)) {
Ptr = (UINT8 *) (((UINTN) Ptr + (EBC_THUNK_ALIGNMENT - 1)) &~ (UINT64) (EBC_THUNK_ALIGNMENT - 1));
}
//
// Return the pointer to the thunk to the caller to user as the
// image entry point.
//
*Thunk = (VOID *) Ptr;
//
// Clear out the thunk entry
// ZeroMem(Ptr, Size);
//
// For IPF, when you do a call via a function pointer, the function pointer
// actually points to a function descriptor which consists of a 64-bit
// address of the function, followed by a 64-bit gp for the function being
// called. See the the Software Conventions and Runtime Architecture Guide
// for details.
// So first off in our thunk, create a descriptor for our actual thunk code.
// This means we need to create a pointer to the thunk code (which follows
// the descriptor we're going to create), followed by the gp of the Vm
// interpret function we're going to eventually execute.
//
Data64Ptr = (UINT64 *) Ptr;
//
// Write the function's entry point (which is our thunk code that follows
// this descriptor we're creating).
//
*Data64Ptr = (UINT64) (Data64Ptr + 2);
//
// Get the gp from the descriptor for EbcInterpret and stuff it in our thunk
// descriptor.
//
*(Data64Ptr + 1) = *(UINT64 *) ((UINT64 *) (UINTN) EbcInterpret + 1);
//
// Advance our thunk data pointer past the descriptor. Since the
// descriptor consists of 16 bytes, the pointer is still aligned for
// IPF code execution (on 16-byte boundary).
//
Ptr += sizeof (UINT64) * 2;
//
// *************************** MAGIC BUNDLE ********************************
//
// Write magic code bundle for: movl r8 = 0xca112ebcca112ebc to help the VM
// to recognize it is a thunk.
//
Addr = (UINT64) 0xCA112EBCCA112EBC;
//
// Now generate the code bytes. First is nop.m 0x0
//
Code[0] = OPCODE_NOP;
//
// Next is simply Addr[62:22] (41 bits) of the address
//
Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;
//
// Extract bits from the address for insertion into the instruction
// i = Addr[63:63]
//
I = RightShiftU64 (Addr, 63) & 0x01;
//
// ic = Addr[21:21]
//
Ic = RightShiftU64 (Addr, 21) & 0x01;
//
// imm5c = Addr[20:16] for 5 bits
//
Imm5c = RightShiftU64 (Addr, 16) & 0x1F;
//
// imm9d = Addr[15:7] for 9 bits
//
Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;
//
// imm7b = Addr[6:0] for 7 bits
//
Imm7b = Addr & 0x7F;
//
// The EBC entry point will be put into r8, so r8 can be used here
// temporary. R8 is general register and is auto-serialized.
//
RegNum = 8;
//
// Next is jumbled data, including opcode and rest of address
//
Code[2] = LeftShiftU64 (Imm7b, 13)
| LeftShiftU64 (0x00, 20) // vc
| LeftShiftU64 (Ic, 21)
| LeftShiftU64 (Imm5c, 22)
| LeftShiftU64 (Imm9d, 27)
| LeftShiftU64 (I, 36)
| LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LeftShiftU64 ((RegNum & 0x7F), 6);
WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);
//
// *************************** FIRST BUNDLE ********************************
//
// Write code bundle for: movl r8 = EBC_ENTRY_POINT so we pass
// the ebc entry point in to the interpreter function via a processor
// register.
// Note -- we could easily change this to pass in a pointer to a structure
// that contained, among other things, the EBC image's entry point. But
// for now pass it directly.
//
Ptr += 16;
Addr = (UINT64) EbcEntryPoint;
//
// Now generate the code bytes. First is nop.m 0x0
//
Code[0] = OPCODE_NOP;
//
// Next is simply Addr[62:22] (41 bits) of the address
//
Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;
//
// Extract bits from the address for insertion into the instruction
// i = Addr[63:63]
//
I = RightShiftU64 (Addr, 63) & 0x01;
//
// ic = Addr[21:21]
//
Ic = RightShiftU64 (Addr, 21) & 0x01;
//
// imm5c = Addr[20:16] for 5 bits
//
Imm5c = RightShiftU64 (Addr, 16) & 0x1F;
//
// imm9d = Addr[15:7] for 9 bits
//
Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;
//
// imm7b = Addr[6:0] for 7 bits
//
Imm7b = Addr & 0x7F;
//
// Put the EBC entry point in r8, which is the location of the return value
// for functions.
//
RegNum = 8;
//
// Next is jumbled data, including opcode and rest of address
//
Code[2] = LeftShiftU64 (Imm7b, 13)
| LeftShiftU64 (0x00, 20) // vc
| LeftShiftU64 (Ic, 21)
| LeftShiftU64 (Imm5c, 22)
| LeftShiftU64 (Imm9d, 27)
| LeftShiftU64 (I, 36)
| LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LeftShiftU64 ((RegNum & 0x7F), 6);
WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);
//
// *************************** NEXT BUNDLE *********************************
//
// Write code bundle for:
// movl rx = offset_of(EbcInterpret|ExecuteEbcImageEntryPoint)
//
// Advance pointer to next bundle, then compute the offset from this bundle
// to the address of the entry point of the interpreter.
//
Ptr += 16;
if (Flags & FLAG_THUNK_ENTRY_POINT) {
Addr = (UINT64) ExecuteEbcImageEntryPoint;
} else {
Addr = (UINT64) EbcInterpret;
}
//
// Indirection on Itanium-based systems
//
Addr = *(UINT64 *) Addr;
//
// Now write the code to load the offset into a register
//
Code[0] = OPCODE_NOP;
//
// Next is simply Addr[62:22] (41 bits) of the address
//
Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;
//
// Extract bits from the address for insertion into the instruction
// i = Addr[63:63]
//
I = RightShiftU64 (Addr, 63) & 0x01;
//
// ic = Addr[21:21]
//
Ic = RightShiftU64 (Addr, 21) & 0x01;
//
// imm5c = Addr[20:16] for 5 bits
//
Imm5c = RightShiftU64 (Addr, 16) & 0x1F;
//
// imm9d = Addr[15:7] for 9 bits
//
Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;
//
// imm7b = Addr[6:0] for 7 bits
//
Imm7b = Addr & 0x7F;
//
// Put it in r31, a scratch register
//
RegNum = 31;
//
// Next is jumbled data, including opcode and rest of address
//
Code[2] = LeftShiftU64(Imm7b, 13)
| LeftShiftU64 (0x00, 20) // vc
| LeftShiftU64 (Ic, 21)
| LeftShiftU64 (Imm5c, 22)
| LeftShiftU64 (Imm9d, 27)
| LeftShiftU64 (I, 36)
| LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LeftShiftU64 ((RegNum & 0x7F), 6);
WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);
//
// *************************** NEXT BUNDLE *********************************
//
// Load branch register with EbcInterpret() function offset from the bundle
// address: mov b6 = RegNum
//
// See volume 3 page 4-29 of the Arch. Software Developer's Manual.
//
// Advance pointer to next bundle
//
Ptr += 16;
Code[0] = OPCODE_NOP;
Code[1] = OPCODE_NOP;
Code[2] = OPCODE_MOV_BX_RX;
//
// Pick a branch register to use. Then fill in the bits for the branch
// register and user register (same user register as previous bundle).
//
Br = 6;
Code[2] |= LeftShiftU64 (Br, 6);
Code[2] |= LeftShiftU64 (RegNum, 13);
WriteBundle ((VOID *) Ptr, 0x0d, Code[0], Code[1], Code[2]);
//
// *************************** NEXT BUNDLE *********************************
//
// Now do the branch: (p0) br.cond.sptk.few b6
//
// Advance pointer to next bundle.
// Fill in the bits for the branch register (same reg as previous bundle)
//
Ptr += 16;
Code[0] = OPCODE_NOP;
Code[1] = OPCODE_NOP;
Code[2] = OPCODE_BR_COND_SPTK_FEW;
Code[2] |= LeftShiftU64 (Br, 13);
WriteBundle ((VOID *) Ptr, 0x1d, Code[0], Code[1], Code[2]);
//
// Add the thunk to our list of allocated thunks so we can do some cleanup
// when the image is unloaded. Do this last since the Add function flushes
// the instruction cache for us.
//
EbcAddImageThunk (ImageHandle, (VOID *) ThunkBase, ThunkSize);
//
// Done
//
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
WriteBundle (
IN VOID *MemPtr,
IN UINT8 Template,
IN UINT64 Slot0,
IN UINT64 Slot1,
IN UINT64 Slot2
)
/*++
Routine Description:
Given raw bytes of Itanium based code, format them into a bundle and
write them out.
Arguments:
MemPtr - pointer to memory location to write the bundles to
Template - 5-bit template
Slot0-2 - instruction slot data for the bundle
Returns:
EFI_INVALID_PARAMETER - Pointer is not aligned
- No more than 5 bits in template
- More than 41 bits used in code
EFI_SUCCESS - All data is written.
--*/
{
UINT8 *BPtr;
UINT32 Index;
UINT64 Low64;
UINT64 High64;
//
// Verify pointer is aligned
//
if ((UINT64) MemPtr & 0xF) {
return EFI_INVALID_PARAMETER;
}
//
// Verify no more than 5 bits in template
//
if (Template &~0x1F) {
return EFI_INVALID_PARAMETER;
}
//
// Verify max of 41 bits used in code
//
if ((Slot0 | Slot1 | Slot2) &~0x1ffffffffff) {
return EFI_INVALID_PARAMETER;
}
Low64 = LeftShiftU64 (Slot1, 46) | LeftShiftU64 (Slot0, 5) | Template;
High64 = RightShiftU64 (Slot1, 18) | LeftShiftU64 (Slot2, 23);
//
// Now write it all out
//
BPtr = (UINT8 *) MemPtr;
for (Index = 0; Index < 8; Index++) {
*BPtr = (UINT8) Low64;
Low64 = RightShiftU64 (Low64, 8);
BPtr++;
}
for (Index = 0; Index < 8; Index++) {
*BPtr = (UINT8) High64;
High64 = RightShiftU64 (High64, 8);
BPtr++;
}
return EFI_SUCCESS;
}
VOID
EbcLLCALLEX (
IN VM_CONTEXT *VmPtr,
IN UINTN FuncAddr,
IN UINTN NewStackPointer,
IN VOID *FramePtr,
IN UINT8 Size
)
/*++
Routine Description:
This function is called to execute an EBC CALLEX instruction.
The function check the callee's content to see whether it is common native
code or a thunk to another piece of EBC code.
If the callee is common native code, use EbcLLCAllEXASM to manipulate,
otherwise, set the VM->IP to target EBC code directly to avoid another VM
be startup which cost time and stack space.
Arguments:
VmPtr - Pointer to a VM context.
FuncAddr - Callee's address
NewStackPointer - New stack pointer after the call
FramePtr - New frame pointer after the call
Size - The size of call instruction
Returns:
None.
--*/
{
UINTN IsThunk;
UINTN TargetEbcAddr;
UINTN CodeOne18;
UINTN CodeOne23;
UINTN CodeTwoI;
UINTN CodeTwoIc;
UINTN CodeTwo7b;
UINTN CodeTwo5c;
UINTN CodeTwo9d;
UINTN CalleeAddr;
IsThunk = 1;
TargetEbcAddr = 0;
//
// FuncAddr points to the descriptor of the target instructions.
//
CalleeAddr = *((UINT64 *)FuncAddr);
//
// Processor specific code to check whether the callee is a thunk to EBC.
//
if (*((UINT64 *)CalleeAddr) != 0xBCCA000100000005) {
IsThunk = 0;
goto Action;
}
if (*((UINT64 *)CalleeAddr + 1) != 0x697623C1004A112E) {
IsThunk = 0;
goto Action;
}
CodeOne18 = RightShiftU64 (*((UINT64 *)CalleeAddr + 2), 46) & 0x3FFFF;
CodeOne23 = (*((UINT64 *)CalleeAddr + 3)) & 0x7FFFFF;
CodeTwoI = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 59) & 0x1;
CodeTwoIc = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 44) & 0x1;
CodeTwo7b = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 36) & 0x7F;
CodeTwo5c = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 45) & 0x1F;
CodeTwo9d = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 50) & 0x1FF;
TargetEbcAddr = CodeTwo7b
| LeftShiftU64 (CodeTwo9d, 7)
| LeftShiftU64 (CodeTwo5c, 16)
| LeftShiftU64 (CodeTwoIc, 21)
| LeftShiftU64 (CodeOne18, 22)
| LeftShiftU64 (CodeOne23, 40)
| LeftShiftU64 (CodeTwoI, 63)
;
Action:
if (IsThunk == 1){
//
// The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and
// put our return address and frame pointer on the VM stack.
// Then set the VM's IP to new EBC code.
//
VmPtr->R[0] -= 8;
VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], (UINTN) FramePtr);
VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->R[0];
VmPtr->R[0] -= 8;
VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], (UINT64) (VmPtr->Ip + Size));
VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;
} else {
//
// The callee is not a thunk to EBC, call native code.
//
EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr);
//
// Get return value and advance the IP.
//
VmPtr->R[7] = EbcLLGetReturnValue ();
VmPtr->Ip += Size;
}
}
VOID
EbcLLCALLEXNative (
IN UINTN CallAddr,
IN UINTN EbcSp,
IN VOID *FramePtr
)
/*++
Routine Description:
Implements the EBC CALLEX instruction to call an external function, which
seems to be native code.
We'll copy the entire EBC stack frame down below itself in memory and use
that copy for passing parameters.
Arguments:
CallAddr - address (function pointer) of function to call
EbcSp - current EBC stack pointer
FramePtr - current EBC frame pointer.
Returns:
NA
--*/
{
UINTN FrameSize;
VOID *Destination;
VOID *Source;
//
// The stack for an EBC function looks like this:
// FramePtr (8)
// RetAddr (8)
// Locals (n)
// Stack for passing args (m)
//
// Pad the frame size with 64 bytes because the low-level code we call
// will move the stack pointer up assuming worst-case 8 args in registers.
//
FrameSize = (UINTN) FramePtr - (UINTN) EbcSp + 64;
Source = (VOID *) EbcSp;
Destination = (VOID *) ((UINT8 *) EbcSp - FrameSize - IPF_STACK_ALIGNMENT);
Destination = (VOID *) ((UINTN) ((UINTN) Destination + IPF_STACK_ALIGNMENT - 1) &~((UINTN) IPF_STACK_ALIGNMENT - 1));
gBS->CopyMem (Destination, Source, FrameSize);
EbcAsmLLCALLEX ((UINTN) CallAddr, (UINTN) Destination);
}

View File

@@ -0,0 +1,375 @@
/*++
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:
Ipfmath.c
Abstract:
Math routines for IPF.
--*/
UINT64
LeftShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Left-shift a 64 bit value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand << Count
--*/
{
if (Count > 63) {
return 0;
}
return Operand << Count;
}
UINT64
RightShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Right-shift a 64 bit value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
if (Count > 63) {
return 0;
}
return Operand >> Count;
}
INT64
ARightShift64 (
IN INT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Right-shift a 64 bit signed value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
if (Count > 63) {
if (Operand & (0x01 << 63)) {
return (INT64)~0;
}
return 0;
}
return Operand >> Count;
}
#if 0
//
// The compiler generates true assembly for these, so we don't need them.
//
INT32
ARightShift32 (
IN INT32 Operand,
IN UINTN Count
)
/*++
Routine Description:
Right shift a 32-bit value
Arguments:
Operand - value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
return Operand >> (Count & 0x1f);
}
INT32
MulS32x32 (
INT32 Value1,
INT32 Value2,
INT32 *ResultHigh
)
/*++
Routine Description:
Multiply two signed 32-bit numbers.
Arguments:
Value1 - first value to multiply
Value2 - value to multiply Value1 by
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value
The product fits in 32 bits if
(*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)
OR
(*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)
--*/
{
INT64 Rres64;
INT32 Result;
Res64 = (INT64) Value1 * (INT64) Value2;
*ResultHigh = (Res64 >> 32) & 0xffffffff;
Result = Res64 & 0xffffffff;
return Result;
}
UINT32
MulU32x32 (
UINT32 Value1,
UINT32 Value2,
UINT32 *ResultHigh
)
/*++
Routine Description:
Multiply two unsigned 32-bit values.
Arguments:
Value1 - first number
Value2 - number to multiply by Value1
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value.
The product fits in 32 bits if *ResultHigh == 0x00000000
--*/
{
UINT64 Res64;
UINT32 Result;
Res64 = (INT64) Value1 * (INT64) Value2;
*ResultHigh = (Res64 >> 32) & 0xffffffff;
Result = Res64 & 0xffffffff;
return Result;
}
INT32
DivS32x32 (
INT32 Value1,
INT32 Value2,
INT32 *Remainder,
UINTN *error
)
//
// signed 32-bit by signed 32-bit divide; the 32-bit remainder is
// in *Remainder and the quotient is the return value; *error = 1 if the
// divisor is 0, and it is 1 otherwise
//
{
INT32 Result;
*error = 0;
if (Value2 == 0x0) {
*error = 1;
Result = 0x80000000;
*Remainder = 0x80000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
UINT32
DivU32x32 (
UINT32 Value1,
UINT32 Value2,
UINT32 *Remainder,
UINTN *Error
)
//
// unsigned 32-bit by unsigned 32-bit divide; the 32-bit remainder is
// in *Remainder and the quotient is the return value; *error = 1 if the
// divisor is 0, and it is 1 otherwise
//
{
UINT32 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x80000000;
*Remainder = 0x80000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
#endif
INT64
DivS64x64 (
INT64 Value1,
INT64 Value2,
INT64 *Remainder,
UINTN *Error
)
/*++
Routine Description:
Divide two 64-bit signed values.
Arguments:
Value1 - dividend
Value2 - divisor
Remainder - remainder of Value1/Value2
Error - to flag errors (divide-by-0)
Returns:
Value1 / Valu2
Note:
The 64-bit remainder is in *Remainder and the quotient is the return value.
*Error = 1 if the divisor is 0, and it is 1 otherwise
--*/
{
INT64 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x8000000000000000;
*Remainder = 0x8000000000000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
UINT64
DivU64x64 (
UINT64 Value1,
UINT64 Value2,
UINT64 *Remainder,
UINTN *Error
)
/*++
Routine Description:
Divide two 64-bit unsigned values.
Arguments:
Value1 - dividend
Value2 - divisor
Remainder - remainder of Value1/Value2
Error - to flag errors (divide-by-0)
Returns:
Value1 / Valu2
Note:
The 64-bit remainder is in *Remainder and the quotient is the return value.
*Error = 1 if the divisor is 0, and it is 1 otherwise
--*/
{
UINT64 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x8000000000000000;
*Remainder = 0x8000000000000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}

View File

@@ -0,0 +1,144 @@
///*++
//
// 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:
//
// IpfMul.s
//
//Abstract:
//
// Low level routines for IPF multiply support
//
//--*/
.file "IpfMul.s"
.section .text
.proc MulS64x64#
.align 32
.global MulS64x64#
.align 32
///*++
//
//Routine Description:
//
// Multiply two 64-bit signed numbers.
//
//
//Arguments:
//
// INT64
// MulS64x64 (
// IN INT64 Value1,
// IN INT64 Value2,
// OUT INT64 *ResultHigh);
//
//Returns:
//
// 64-bit signed result
//
//--*/
MulS64x64:
// signed 64x64->128-bit multiply
// A in r32, B in r33, Q_hi stored in [r34], Q_lo returned in r8
{ .mfi
alloc r31=ar.pfs,3,0,0,0 // r32-r34
nop.f 0
nop.i 0;;
}
{.mmi
setf.sig f6=r32
setf.sig f7=r33
nop.i 0;;
}
{.mfi
nop.m 0
xma.h f8=f6,f7,f0
nop.i 0
}
{.mfi
nop.m 0
xma.l f6=f6,f7,f0
nop.i 0;;
}
{.mmb
stf8 [r34]=f8
getf.sig r8=f6
br.ret.sptk b0;;
}
.endp MulS64x64
.proc MulU64x64#
.align 32
.global MulU64x64#
.align 32
///*++
//
//Routine Description:
//
// Multiply two 64-bit unsigned numbers.
//
//
//Arguments:
//
// UINT64
// MulU64x64 (
// IN UINT64 Value1,
// IN UINT64 Value2,
// OUT UINT64 *ResultHigh);
//
//Returns:
//
// 64-bit unsigned result
//
//--*/
MulU64x64:
// A in r32, B in r33, Q_hi stored in [r34], Q_lo returned in r8
{ .mfi
alloc r31=ar.pfs,3,0,0,0 // r32-r34
nop.f 0
nop.i 0;;
}
{.mmi
setf.sig f6=r32
setf.sig f7=r33
nop.i 0;;
}
{.mfi
nop.m 0
xma.hu f8=f6,f7,f0
nop.i 0
}
{.mfi
nop.m 0
xma.l f6=f6,f7,f0
nop.i 0;;
}
{.mmb
stf8 [r34]=f8
getf.sig r8=f6
br.ret.sptk b0;;
}
.endp MulU64x64

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
<project basedir="." default="Ebc"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Ebc\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="Ebc">
<GenBuild baseName="Ebc" mbdFilename="${MODULE_DIR}\Ebc.mbd" msaFilename="${MODULE_DIR}\Ebc.msa"/>
</target>
<target depends="Ebc_clean" name="clean"/>
<target depends="Ebc_cleanall" name="cleanall"/>
<target name="Ebc_clean">
<OutputDirSetup baseName="Ebc" mbdFilename="${MODULE_DIR}\Ebc.mbd" msaFilename="${MODULE_DIR}\Ebc.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\Ebc_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\Ebc_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="Ebc_cleanall">
<OutputDirSetup baseName="Ebc" mbdFilename="${MODULE_DIR}\Ebc.mbd" msaFilename="${MODULE_DIR}\Ebc.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\Ebc_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\Ebc_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**Ebc*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,145 @@
page ,132
title VM ASSEMBLY LANGUAGE ROUTINES
;****************************************************************************
;*
;* 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.
;*
;****************************************************************************
;****************************************************************************
; REV 1.0
;****************************************************************************
;
; Rev Date Description
; --- -------- ------------------------------------------------------------
; 1.0 05/09/12 Initial creation of file.
;
;****************************************************************************
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; This code provides low level routines that support the Virtual Machine
; for option ROMs.
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;---------------------------------------------------------------------------
; Equate files needed.
;---------------------------------------------------------------------------
text SEGMENT
;---------------------------------------------------------------------------
;;GenericPostSegment SEGMENT USE16
;---------------------------------------------------------------------------
;****************************************************************************
; EbcLLCALLEX
;
; This function is called to execute an EBC CALLEX instruction.
; This instruction requires that we thunk out to external native
; code. For x64, we switch stacks, copy the arguments to the stack
; and jump to the specified function.
; On return, we restore the stack pointer to its original location.
;
; Destroys no working registers.
;****************************************************************************
; VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
EbcLLCALLEXNative PROC
push rbp
push rbx
mov rbp, rsp
; Function prolog
; Copy FuncAddr to a preserved register.
mov rbx, rcx
; Set stack pointer to new value
mov rsp, rdx
; Considering the worst case, load 4 potiential arguments
; into registers.
mov rcx, qword ptr [rsp]
mov rdx, qword ptr [rsp+8h]
mov r8, qword ptr [rsp+10h]
mov r9, qword ptr [rsp+18h]
; Now call the external routine
call rbx
; Function epilog
mov rsp, rbp
pop rbx
pop rbp
ret
EbcLLCALLEXNative ENDP
; UINTN EbcLLGetEbcEntryPoint(VOID);
; Routine Description:
; The VM thunk code stuffs an EBC entry point into a processor
; register. Since we can't use inline assembly to get it from
; the interpreter C code, stuff it into the return value
; register and return.
;
; Arguments:
; None.
;
; Returns:
; The contents of the register in which the entry point is passed.
;
EbcLLGetEbcEntryPoint PROC
ret
EbcLLGetEbcEntryPoint ENDP
;/*++
;
;Routine Description:
;
; Return the caller's value of the stack pointer.
;
;Arguments:
;
; None.
;
;Returns:
;
; The current value of the stack pointer for the caller. We
; adjust it by 4 here because when they called us, the return address
; is put on the stack, thereby lowering it by 4 bytes.
;
;--*/
; UINTN EbcLLGetStackPointer()
EbcLLGetStackPointer PROC
mov rax, rsp ; get current stack pointer
; Stack adjusted by this much when we were called,
; For this function, it's 4.
add rax, 4
ret
EbcLLGetStackPointer ENDP
; UINT64 EbcLLGetReturnValue(VOID);
; Routine Description:
; When EBC calls native, on return the VM has to stuff the return
; value into a VM register. It's assumed here that the value is still
; in the register, so simply return and the caller should get the
; return result properly.
;
; Arguments:
; None.
;
; Returns:
; The unmodified value returned by the native code.
;
EbcLLGetReturnValue PROC
ret
EbcLLGetReturnValue ENDP
text ENDS
END

View File

@@ -0,0 +1,579 @@
/*++
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:
EbcSupport.c
Abstract:
This module contains EBC support routines that are customized based on
the target x64 processor.
--*/
#include "EbcInt.h"
#include "EbcExecute.h"
//
// NOTE: This is the stack size allocated for the interpreter
// when it executes an EBC image. The requirements can change
// based on whether or not a debugger is present, and other
// platform-specific configurations.
//
#define VM_STACK_SIZE (1024 * 8)
#define EBC_THUNK_SIZE 64
STATIC
VOID
PushU64 (
VM_CONTEXT *VmPtr,
UINT64 Arg
)
/*++
Routine Description:
Push a 64 bit unsigned value to the VM stack.
Arguments:
VmPtr - The pointer to current VM context.
Arg - The value to be pushed
Returns:
VOID
--*/
{
//
// Advance the VM stack down, and then copy the argument to the stack.
// Hope it's aligned.
//
VmPtr->R[0] -= sizeof (UINT64);
*(UINT64 *) VmPtr->R[0] = Arg;
return;
}
STATIC
UINT64
EbcInterpret (
UINTN Arg1,
UINTN Arg2,
UINTN Arg3,
UINTN Arg4,
UINTN Arg5
)
/*++
Routine Description:
Begin executing an EBC image. The address of the entry point is passed
in via a processor register, so we'll need to make a call to get the
value.
Arguments:
This is a thunk function. Microsoft x64 compiler only provide fast_call
calling convention, so the first four arguments are passed by rcx, rdx,
r8, and r9, while other arguments are passed in stack.
Returns:
The value returned by the EBC application we're going to run.
--*/
{
//
// Create a new VM context on the stack
//
VM_CONTEXT VmContext;
UINTN Addr;
//
// Get the EBC entry point from the processor register.
// Don't call any function before getting the EBC entry
// point because this will collab the return register.
//
Addr = EbcLLGetEbcEntryPoint ();
//
// Now clear out our context
//
ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));
//
// Set the VM instruction pointer to the correct location in memory.
//
VmContext.Ip = (VMIP) Addr;
//
// Initialize the stack pointer for the EBC. Get the current system stack
// pointer and adjust it down by the max needed for the interpreter.
//
Addr = EbcLLGetStackPointer ();
//
// Adjust the VM's stack pointer down.
//
VmContext.R[0] = (UINT64) Addr;
VmContext.R[0] -= VM_STACK_SIZE;
//
// Align the stack on a natural boundary.
//
VmContext.R[0] &= ~(sizeof (UINTN) - 1);
//
// Put a magic value in the stack gap, then adjust down again.
//
*(UINTN *) (UINTN) (VmContext.R[0]) = (UINTN) VM_STACK_KEY_VALUE;
VmContext.StackMagicPtr = (UINTN *) (UINTN) VmContext.R[0];
//
// The stack upper to LowStackTop is belong to the VM.
//
VmContext.LowStackTop = (UINTN) VmContext.R[0];
//
// For the worst case, assume there are 4 arguments passed in registers, store
// them to VM's stack.
//
PushU64 (&VmContext, (UINT64) Arg4);
PushU64 (&VmContext, (UINT64) Arg3);
PushU64 (&VmContext, (UINT64) Arg2);
PushU64 (&VmContext, (UINT64) Arg1);
//
// Interpreter assumes 64-bit return address is pushed on the stack.
// The x64 does not do this so pad the stack accordingly.
//
PushU64 (&VmContext, (UINT64) 0);
PushU64 (&VmContext, (UINT64) 0x1234567887654321);
//
// For x64, this is where we say our return address is
//
VmContext.StackRetAddr = (UINT64) VmContext.R[0];
//
// We need to keep track of where the EBC stack starts. This way, if the EBC
// accesses any stack variables above its initial stack setting, then we know
// it's accessing variables passed into it, which means the data is on the
// VM's stack.
// When we're called, on the stack (high to low) we have the parameters, the
// return address, then the saved ebp. Save the pointer to the return address.
// EBC code knows that's there, so should look above it for function parameters.
// The offset is the size of locals (VMContext + Addr + saved ebp).
// Note that the interpreter assumes there is a 16 bytes of return address on
// the stack too, so adjust accordingly.
// VmContext.HighStackBottom = (UINTN)(Addr + sizeof (VmContext) + sizeof (Addr));
//
VmContext.HighStackBottom = (UINTN) &Arg5;
//
// Begin executing the EBC code
//
EbcExecute (&VmContext);
//
// Return the value in R[7] unless there was an error
//
return (UINT64) VmContext.R[7];
}
STATIC
UINT64
ExecuteEbcImageEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Begin executing an EBC image. The address of the entry point is passed
in via a processor register, so we'll need to make a call to get the
value.
Arguments:
ImageHandle - image handle for the EBC application we're executing
SystemTable - standard system table passed into an driver's entry point
Returns:
The value returned by the EBC application we're going to run.
--*/
{
//
// Create a new VM context on the stack
//
VM_CONTEXT VmContext;
UINTN Addr;
//
// Get the EBC entry point from the processor register. Make sure you don't
// call any functions before this or you could mess up the register the
// entry point is passed in.
//
Addr = EbcLLGetEbcEntryPoint ();
//
// Now clear out our context
//
ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));
//
// Save the image handle so we can track the thunks created for this image
//
VmContext.ImageHandle = ImageHandle;
VmContext.SystemTable = SystemTable;
//
// Set the VM instruction pointer to the correct location in memory.
//
VmContext.Ip = (VMIP) Addr;
//
// Initialize the stack pointer for the EBC. Get the current system stack
// pointer and adjust it down by the max needed for the interpreter.
//
Addr = EbcLLGetStackPointer ();
VmContext.R[0] = (UINT64) Addr;
VmContext.R[0] -= VM_STACK_SIZE;
//
// Put a magic value in the stack gap, then adjust down again
//
*(UINTN *) (UINTN) (VmContext.R[0]) = (UINTN) VM_STACK_KEY_VALUE;
VmContext.StackMagicPtr = (UINTN *) (UINTN) VmContext.R[0];
//
// Align the stack on a natural boundary
VmContext.R[0] &= ~(sizeof(UINTN) - 1);
//
VmContext.LowStackTop = (UINTN) VmContext.R[0];
//
// Simply copy the image handle and system table onto the EBC stack.
// Greatly simplifies things by not having to spill the args.
//
PushU64 (&VmContext, (UINT64) SystemTable);
PushU64 (&VmContext, (UINT64) ImageHandle);
//
// VM pushes 16-bytes for return address. Simulate that here.
//
PushU64 (&VmContext, (UINT64) 0);
PushU64 (&VmContext, (UINT64) 0x1234567887654321);
//
// For x64, this is where we say our return address is
//
VmContext.StackRetAddr = (UINT64) VmContext.R[0];
//
// Entry function needn't access high stack context, simply
// put the stack pointer here.
//
VmContext.HighStackBottom = (UINTN) Addr;
//
// Begin executing the EBC code
//
EbcExecute (&VmContext);
//
// Return the value in R[7] unless there was an error
//
return (UINT64) VmContext.R[7];
}
EFI_STATUS
EbcCreateThunks (
IN EFI_HANDLE ImageHandle,
IN VOID *EbcEntryPoint,
OUT VOID **Thunk,
IN UINT32 Flags
)
/*++
Routine Description:
Create an IA32 thunk for the given EBC entry point.
Arguments:
ImageHandle - Handle of image for which this thunk is being created
EbcEntryPoint - Address of the EBC code that the thunk is to call
Thunk - Returned thunk we create here
Returns:
Standard EFI status.
--*/
{
UINT8 *Ptr;
UINT8 *ThunkBase;
UINT32 I;
UINT64 Addr;
INT32 Size;
INT32 ThunkSize;
EFI_STATUS Status;
//
// Check alignment of pointer to EBC code
//
if ((UINT32) (UINTN) EbcEntryPoint & 0x01) {
return EFI_INVALID_PARAMETER;
}
Size = EBC_THUNK_SIZE;
ThunkSize = Size;
Status = gBS->AllocatePool (
EfiBootServicesData,
Size,
(VOID *) &Ptr
);
if (Status != EFI_SUCCESS) {
return EFI_OUT_OF_RESOURCES;
}
//
// Print(L"Allocate TH: 0x%X\n", (UINT32)Ptr);
//
// Save the start address so we can add a pointer to it to a list later.
//
ThunkBase = Ptr;
//
// Give them the address of our buffer we're going to fix up
//
*Thunk = (VOID *) Ptr;
//
// Add a magic code here to help the VM recognize the thunk..
// mov rax, ca112ebccall2ebch => 48 B8 BC 2E 11 CA BC 2E 11 CA
//
*Ptr = 0x48;
Ptr++;
Size--;
*Ptr = 0xB8;
Ptr++;
Size--;
Addr = (UINT64) 0xCA112EBCCA112EBC;
for (I = 0; I < sizeof (Addr); I++) {
*Ptr = (UINT8) (UINTN) Addr;
Addr >>= 8;
Ptr++;
Size--;
}
//
// Add code bytes to load up a processor register with the EBC entry point.
// mov rax, 123456789abcdef0h => 48 B8 F0 DE BC 9A 78 56 34 12
// The first 8 bytes of the thunk entry is the address of the EBC
// entry point.
//
*Ptr = 0x48;
Ptr++;
Size--;
*Ptr = 0xB8;
Ptr++;
Size--;
Addr = (UINT64) EbcEntryPoint;
for (I = 0; I < sizeof (Addr); I++) {
*Ptr = (UINT8) (UINTN) Addr;
Addr >>= 8;
Ptr++;
Size--;
}
//
// Stick in a load of ecx with the address of appropriate VM function.
// Using r11 because it's a volatile register and won't be used in this
// point.
// mov r11 123456789abcdef0h => 49 BB F0 DE BC 9A 78 56 34 12
//
if (Flags & FLAG_THUNK_ENTRY_POINT) {
Addr = (UINTN) ExecuteEbcImageEntryPoint;
} else {
Addr = (UINTN) EbcInterpret;
}
//
// mov r11 Addr => 0x49 0xBB
//
*Ptr = 0x49;
Ptr++;
Size--;
*Ptr = 0xBB;
Ptr++;
Size--;
for (I = 0; I < sizeof (Addr); I++) {
*Ptr = (UINT8) Addr;
Addr >>= 8;
Ptr++;
Size--;
}
//
// Stick in jump opcode bytes for jmp r11 => 0x41 0xFF 0xE3
//
*Ptr = 0x41;
Ptr++;
Size--;
*Ptr = 0xFF;
Ptr++;
Size--;
*Ptr = 0xE3;
Size--;
//
// Double check that our defined size is ok (application error)
//
if (Size < 0) {
ASSERT (FALSE);
return EFI_BUFFER_TOO_SMALL;
}
//
// Add the thunk to the list for this image. Do this last since the add
// function flushes the cache for us.
//
EbcAddImageThunk (ImageHandle, (VOID *) ThunkBase, ThunkSize);
return EFI_SUCCESS;
}
VOID
EbcLLCALLEX (
IN VM_CONTEXT *VmPtr,
IN UINTN FuncAddr,
IN UINTN NewStackPointer,
IN VOID *FramePtr,
IN UINT8 Size
)
/*++
Routine Description:
This function is called to execute an EBC CALLEX instruction.
The function check the callee's content to see whether it is common native
code or a thunk to another piece of EBC code.
If the callee is common native code, use EbcLLCAllEXASM to manipulate,
otherwise, set the VM->IP to target EBC code directly to avoid another VM
be startup which cost time and stack space.
Arguments:
VmPtr - Pointer to a VM context.
FuncAddr - Callee's address
NewStackPointer - New stack pointer after the call
FramePtr - New frame pointer after the call
Size - The size of call instruction
Returns:
None.
--*/
{
UINTN IsThunk;
UINTN TargetEbcAddr;
IsThunk = 1;
TargetEbcAddr = 0;
//
// Processor specific code to check whether the callee is a thunk to EBC.
//
if (*((UINT8 *)FuncAddr) != 0x48) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 1) != 0xB8) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 2) != 0xBC) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 3) != 0x2E) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 4) != 0x11) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 5) != 0xCA) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 6) != 0xBC) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 7) != 0x2E) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 8) != 0x11) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 9) != 0xCA) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 10) != 0x48) {
IsThunk = 0;
goto Action;
}
if (*((UINT8 *)FuncAddr + 11) != 0xB8) {
IsThunk = 0;
goto Action;
}
CopyMem (&TargetEbcAddr, (UINT8 *)FuncAddr + 12, 8);
Action:
if (IsThunk == 1){
//
// The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and
// put our return address and frame pointer on the VM stack.
// Then set the VM's IP to new EBC code.
//
VmPtr->R[0] -= 8;
VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], (UINTN) FramePtr);
VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->R[0];
VmPtr->R[0] -= 8;
VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], (UINT64) (VmPtr->Ip + Size));
VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;
} else {
//
// The callee is not a thunk to EBC, call native code.
//
EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr);
//
// Get return value and advance the IP.
//
VmPtr->R[7] = EbcLLGetReturnValue ();
VmPtr->Ip += Size;
}
}

View File

@@ -0,0 +1,451 @@
/*++
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:
x64math.c
Abstract:
Math routines for x64.
--*/
UINT64
LeftShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Left-shift a 64 bit value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand << Count
--*/
{
if (Count > 63) {
return 0;
}
return Operand << Count;
}
UINT64
RightShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Right-shift a 64 bit value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
if (Count > 63) {
return 0;
}
return Operand >> Count;
}
INT64
ARightShift64 (
IN INT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Right-shift a 64 bit signed value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
if (Count > 63) {
if (Operand & 0x8000000000000000ULL) {
return (INT64)~0;
}
return 0;
}
return Operand >> Count;
}
#if 0
//
// The compiler generates true assembly for these, so we don't need them.
//
INT32
ARightShift32 (
IN INT32 Operand,
IN UINTN Count
)
/*++
Routine Description:
Right shift a 32-bit value
Arguments:
Operand - value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
return Operand >> (Count & 0x1f);
}
INT32
MulS32x32 (
INT32 Value1,
INT32 Value2,
INT32 *ResultHigh
)
/*++
Routine Description:
Multiply two signed 32-bit numbers.
Arguments:
Value1 - first value to multiply
Value2 - value to multiply Value1 by
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value
The product fits in 32 bits if
(*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)
OR
(*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)
--*/
{
INT64 Rres64;
INT32 Result;
Res64 = (INT64) Value1 * (INT64) Value2;
*ResultHigh = (Res64 >> 32) & 0xffffffff;
Result = Res64 & 0xffffffff;
return Result;
}
UINT32
MulU32x32 (
UINT32 Value1,
UINT32 Value2,
UINT32 *ResultHigh
)
/*++
Routine Description:
Multiply two unsigned 32-bit values.
Arguments:
Value1 - first number
Value2 - number to multiply by Value1
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value.
The product fits in 32 bits if *ResultHigh == 0x00000000
--*/
{
UINT64 Res64;
UINT32 Result;
Res64 = (INT64) Value1 * (INT64) Value2;
*ResultHigh = (Res64 >> 32) & 0xffffffff;
Result = Res64 & 0xffffffff;
return Result;
}
INT32
DivS32x32 (
INT32 Value1,
INT32 Value2,
INT32 *Remainder,
UINTN *error
)
//
// signed 32-bit by signed 32-bit divide; the 32-bit remainder is
// in *Remainder and the quotient is the return value; *error = 1 if the
// divisor is 0, and it is 1 otherwise
//
{
INT32 Result;
*error = 0;
if (Value2 == 0x0) {
*error = 1;
Result = 0x80000000;
*Remainder = 0x80000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
UINT32
DivU32x32 (
UINT32 Value1,
UINT32 Value2,
UINT32 *Remainder,
UINTN *Error
)
//
// unsigned 32-bit by unsigned 32-bit divide; the 32-bit remainder is
// in *Remainder and the quotient is the return value; *error = 1 if the
// divisor is 0, and it is 1 otherwise
//
{
UINT32 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x80000000;
*Remainder = 0x80000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
#endif
INT64
MulS64x64 (
INT64 Value1,
INT64 Value2,
INT64 *ResultHigh
)
/*++
Routine Description:
Multiply two signed 32-bit numbers.
Arguments:
Value1 - first value to multiply
Value2 - value to multiply Value1 by
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value
The product fits in 32 bits if
(*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)
OR
(*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)
--*/
{
INT64 Result;
Result = Value1 * Value2;
return Result;
}
UINT64
MulU64x64 (
UINT64 Value1,
UINT64 Value2,
UINT64 *ResultHigh
)
/*++
Routine Description:
Multiply two unsigned 32-bit values.
Arguments:
Value1 - first number
Value2 - number to multiply by Value1
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value.
The product fits in 32 bits if *ResultHigh == 0x00000000
--*/
{
UINT64 Result;
Result = Value1 * Value2;
return Result;
}
INT64
DivS64x64 (
INT64 Value1,
INT64 Value2,
INT64 *Remainder,
UINTN *Error
)
/*++
Routine Description:
Divide two 64-bit signed values.
Arguments:
Value1 - dividend
Value2 - divisor
Remainder - remainder of Value1/Value2
Error - to flag errors (divide-by-0)
Returns:
Value1 / Valu2
Note:
The 64-bit remainder is in *Remainder and the quotient is the return value.
*Error = 1 if the divisor is 0, and it is 1 otherwise
--*/
{
INT64 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x8000000000000000;
*Remainder = 0x8000000000000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
UINT64
DivU64x64 (
UINT64 Value1,
UINT64 Value2,
UINT64 *Remainder,
UINTN *Error
)
/*++
Routine Description:
Divide two 64-bit unsigned values.
Arguments:
Value1 - dividend
Value2 - divisor
Remainder - remainder of Value1/Value2
Error - to flag errors (divide-by-0)
Returns:
Value1 / Valu2
Note:
The 64-bit remainder is in *Remainder and the quotient is the return value.
*Error = 1 if the divisor is 0, and it is 1 otherwise
--*/
{
UINT64 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x8000000000000000;
*Remainder = 0x8000000000000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}

View File

@@ -0,0 +1,754 @@
/*++
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:
EmuVariable.c
Abstract:
Revision History
--*/
#include "Variable.h"
//
// Don't use module globals after the SetVirtualAddress map is signaled
//
ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;
UINT32
EFIAPI
ArrayLength (
IN CHAR16 *String
)
/*++
Routine Description:
Determine the length of null terminated char16 array.
Arguments:
String Null-terminated CHAR16 array pointer.
Returns:
UINT32 Number of bytes in the string, including the double NULL at the end;
--*/
{
UINT32 Count;
if (NULL == String) {
return 0;
}
Count = 0;
while (0 != String[Count]) {
Count++;
}
return (Count * 2) + 2;
}
UINTN
EFIAPI
GetPadSize (
IN UINTN Value
)
/*++
Routine Description:
This function return the pad size for alignment
Arguments:
Value The value need to align
Returns:
Pad size for value
--*/
{
//
// If alignment is 0 or 1, means no alignment required
//
if (ALIGNMENT == 0 || ALIGNMENT == 1) {
return 0;
}
return ALIGNMENT - (Value % ALIGNMENT);
}
VARIABLE_STORE_STATUS
EFIAPI
GetVariableStoreStatus (
IN VARIABLE_STORE_HEADER *VarStoreHeader
)
/*++
Routine Description:
This code gets the pointer to the variable name.
Arguments:
VarStoreHeader Pointer to the Variable Store Header.
Returns:
EfiHealthy Variable store is healthy
EfiRaw Variable store is raw
EfiInvalid Variable store is invalid
--*/
{
if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&
VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
VarStoreHeader->State == VARIABLE_STORE_HEALTHY
) {
return EfiValid;
} else if (VarStoreHeader->Signature == 0xffffffff &&
VarStoreHeader->Size == 0xffffffff &&
VarStoreHeader->Format == 0xff &&
VarStoreHeader->State == 0xff
) {
return EfiRaw;
} else {
return EfiInvalid;
}
}
UINT8 *
EFIAPI
GetVariableDataPtr (
IN VARIABLE_HEADER *Variable
)
/*++
Routine Description:
This code gets the pointer to the variable data.
Arguments:
Variable Pointer to the Variable Header.
Returns:
UINT8* Pointer to Variable Data
--*/
{
if (Variable->StartId != VARIABLE_DATA) {
return NULL;
}
//
// Be careful about pad size for alignment
//
return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GetPadSize (Variable->NameSize));
}
VARIABLE_HEADER *
EFIAPI
GetNextVariablePtr (
IN VARIABLE_HEADER *Variable
)
/*++
Routine Description:
This code gets the pointer to the next variable header.
Arguments:
Variable Pointer to the Variable Header.
Returns:
VARIABLE_HEADER* Pointer to next variable header.
--*/
{
VARIABLE_HEADER *VarHeader;
if (Variable->StartId != VARIABLE_DATA) {
return NULL;
}
//
// Be careful about pad size for alignment
//
VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
if (VarHeader->StartId != VARIABLE_DATA ||
(sizeof (VARIABLE_HEADER) + VarHeader->DataSize + VarHeader->NameSize) > MAX_VARIABLE_SIZE
) {
return NULL;
}
return VarHeader;
}
VARIABLE_HEADER *
EFIAPI
GetEndPointer (
IN VARIABLE_STORE_HEADER *VolHeader
)
/*++
Routine Description:
This code gets the pointer to the last variable memory pointer byte
Arguments:
Variable Pointer to the Variable Header.
Returns:
VARIABLE_HEADER* Pointer to last unavailable Variable Header
--*/
{
//
// The end of variable store
//
return (VARIABLE_HEADER *) ((UINTN) VolHeader + VolHeader->Size);
}
EFI_STATUS
EFIAPI
FindVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VARIABLE_POINTER_TRACK *PtrTrack,
IN VARIABLE_GLOBAL *Global
)
/*++
Routine Description:
This code finds variable in storage blocks (Volatile or Non-Volatile)
Arguments:
VariableName Name of the variable to be found
VendorGuid Vendor GUID to be found.
PtrTrack Variable Track Pointer structure that contains
Variable Information.
Contains the pointer of Variable header.
Global VARIABLE_GLOBAL pointer
Returns:
EFI STATUS
--*/
{
VARIABLE_HEADER *Variable[2];
VARIABLE_STORE_HEADER *VariableStoreHeader[2];
UINTN Index;
//
// 0: Non-Volatile, 1: Volatile
//
VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);
VariableStoreHeader[1] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);
//
// Start Pointers for the variable.
// Actual Data Pointer where data can be written.
//
Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1);
Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1);
if (VariableName[0] != 0 && VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Find the variable by walk through non-volatile and volatile variable store
//
for (Index = 0; Index < 2; Index++) {
PtrTrack->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
while ((Variable[Index] != NULL) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {
if (Variable[Index]->StartId == VARIABLE_DATA && Variable[Index]->State == VAR_ADDED) {
if (!(EfiAtRuntime () && !(Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {
if (VariableName[0] == 0) {
PtrTrack->CurrPtr = Variable[Index];
PtrTrack->Volatile = (BOOLEAN) Index;
return EFI_SUCCESS;
} else {
if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {
if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), ArrayLength (VariableName))) {
PtrTrack->CurrPtr = Variable[Index];
PtrTrack->Volatile = (BOOLEAN) Index;
return EFI_SUCCESS;
}
}
}
}
}
Variable[Index] = GetNextVariablePtr (Variable[Index]);
}
}
PtrTrack->CurrPtr = NULL;
return EFI_NOT_FOUND;
}
EFI_STATUS
EFIAPI
GetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID * VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data,
IN VARIABLE_GLOBAL * Global,
IN UINT32 Instance
)
/*++
Routine Description:
This code finds variable in storage blocks (Volatile or Non-Volatile)
Arguments:
VariableName Name of Variable to be found
VendorGuid Variable vendor GUID
Attributes OPTIONAL Attribute value of the variable found
DataSize Size of Data found. If size is less than the
data, this value contains the required size.
Data Data pointer
Global Pointer to VARIABLE_GLOBAL structure
Instance Instance of the Firmware Volume.
Returns:
EFI STATUS
--*/
{
VARIABLE_POINTER_TRACK Variable;
UINTN VarDataSize;
EFI_STATUS Status;
if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Find existing variable
//
Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
return Status;
}
//
// Get data size
//
VarDataSize = Variable.CurrPtr->DataSize;
if (*DataSize >= VarDataSize) {
CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);
if (Attributes) {
*Attributes = Variable.CurrPtr->Attributes;
}
*DataSize = VarDataSize;
return EFI_SUCCESS;
} else {
*DataSize = VarDataSize;
return EFI_BUFFER_TOO_SMALL;
}
}
EFI_STATUS
EFIAPI
GetNextVariableName (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid,
IN VARIABLE_GLOBAL *Global,
IN UINT32 Instance
)
/*++
Routine Description:
This code Finds the Next available variable
Arguments:
VariableNameSize Size of the variable
VariableName Pointer to variable name
VendorGuid Variable Vendor Guid
Global VARIABLE_GLOBAL structure pointer.
Instance FV instance
Returns:
EFI STATUS
--*/
{
VARIABLE_POINTER_TRACK Variable;
UINTN VarNameSize;
EFI_STATUS Status;
if (VariableNameSize == NULL || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
return Status;
}
while (TRUE) {
if (VariableName[0] != 0) {
//
// If variable name is not NULL, get next variable
//
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
}
//
// If both volatile and non-volatile variable store are parsed,
// return not found
//
if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {
Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));
if (Variable.Volatile) {
Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));
Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));
} else {
return EFI_NOT_FOUND;
}
Variable.CurrPtr = Variable.StartPtr;
if (Variable.CurrPtr->StartId != VARIABLE_DATA) {
continue;
}
}
//
// Variable is found
//
if (Variable.CurrPtr->StartId == VARIABLE_DATA && Variable.CurrPtr->State == VAR_ADDED) {
if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {
VarNameSize = Variable.CurrPtr->NameSize;
if (VarNameSize <= *VariableNameSize) {
CopyMem (
VariableName,
GET_VARIABLE_NAME_PTR (Variable.CurrPtr),
VarNameSize
);
CopyMem (
VendorGuid,
&Variable.CurrPtr->VendorGuid,
sizeof (EFI_GUID)
);
Status = EFI_SUCCESS;
} else {
Status = EFI_BUFFER_TOO_SMALL;
}
*VariableNameSize = VarNameSize;
return Status;
}
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
EFIAPI
SetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data,
IN VARIABLE_GLOBAL *Global,
IN UINTN *VolatileOffset,
IN UINTN *NonVolatileOffset,
IN UINT32 Instance
)
/*++
Routine Description:
This code sets variable in storage blocks (Volatile or Non-Volatile)
Arguments:
VariableName Name of Variable to be found
VendorGuid Variable vendor GUID
Attributes Attribute value of the variable found
DataSize Size of Data found. If size is less than the
data, this value contains the required size.
Data Data pointer
Global Pointer to VARIABLE_GLOBAL structure
VolatileOffset The offset of last volatile variable
NonVolatileOffset The offset of last non-volatile variable
Instance Instance of the Firmware Volume.
Returns:
EFI STATUS
--*/
{
VARIABLE_POINTER_TRACK Variable;
EFI_STATUS Status;
VARIABLE_HEADER *NextVariable;
UINTN VarNameSize;
UINTN VarNameOffset;
UINTN VarDataOffset;
UINTN VarSize;
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
if (Status == EFI_INVALID_PARAMETER) {
return Status;
}
//
// The size of the VariableName, including the Unicode Null in bytes plus
// the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.
//
else if (sizeof (VARIABLE_HEADER) + (ArrayLength (VariableName) + DataSize) > MAX_VARIABLE_SIZE) {
return EFI_INVALID_PARAMETER;
}
//
// Make sure if runtime bit is set, boot service bit is set also
//
else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS
) {
return EFI_INVALID_PARAMETER;
}
//
// Runtime but Attribute is not Runtime
//
else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
return EFI_INVALID_PARAMETER;
}
//
// Cannot set volatile variable in Runtime
//
else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {
return EFI_INVALID_PARAMETER;
}
//
// Setting a data variable with no access, or zero DataSize attributes
// specified causes it to be deleted.
//
else if (DataSize == 0 || Attributes == 0) {
if (!EFI_ERROR (Status)) {
Variable.CurrPtr->State &= VAR_DELETED;
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
} else {
if (!EFI_ERROR (Status)) {
//
// If the variable is marked valid and the same data has been passed in
// then return to the caller immediately.
//
if (Variable.CurrPtr->DataSize == DataSize &&
!CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)
) {
return EFI_SUCCESS;
} else if (Variable.CurrPtr->State == VAR_ADDED) {
//
// Mark the old variable as in delete transition
//
Variable.CurrPtr->State &= VAR_IN_DELETED_TRANSITION;
}
}
//
// Create a new variable and copy the data.
//
VarNameOffset = sizeof (VARIABLE_HEADER);
VarNameSize = ArrayLength (VariableName);
VarDataOffset = VarNameOffset + VarNameSize + GetPadSize (VarNameSize);
VarSize = VarDataOffset + DataSize + GetPadSize (DataSize);
if (Attributes & EFI_VARIABLE_NON_VOLATILE) {
if ((UINT32) (VarSize +*NonVolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
) {
return EFI_OUT_OF_RESOURCES;
}
NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);
*NonVolatileOffset = *NonVolatileOffset + VarSize;
} else {
if (EfiAtRuntime ()) {
return EFI_INVALID_PARAMETER;
}
if ((UINT32) (VarSize +*VolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
) {
return EFI_OUT_OF_RESOURCES;
}
NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*VolatileOffset + (UINTN) Global->VolatileVariableBase);
*VolatileOffset = *VolatileOffset + VarSize;
}
NextVariable->StartId = VARIABLE_DATA;
NextVariable->Attributes = Attributes;
NextVariable->State = VAR_ADDED;
NextVariable->Reserved = 0;
//
// There will be pad bytes after Data, the NextVariable->NameSize and
// NextVariable->NameSize should not include pad size so that variable
// service can get actual size in GetVariable
//
NextVariable->NameSize = (UINT32)VarNameSize;
NextVariable->DataSize = (UINT32)DataSize;
CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarNameOffset),
VariableName,
VarNameSize
);
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarDataOffset),
Data,
DataSize
);
//
// Mark the old variable as deleted
//
if (!EFI_ERROR (Status)) {
Variable.CurrPtr->State &= VAR_DELETED;
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
InitializeVariableStore (
OUT EFI_PHYSICAL_ADDRESS *VariableBase,
OUT UINTN *LastVariableOffset
)
/*++
Routine Description:
This function initializes variable store
Arguments:
Returns:
--*/
{
VARIABLE_STORE_HEADER *VariableStore;
//
// Allocate memory for volatile variable store
//
VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (
VARIABLE_STORE_SIZE
);
if (NULL == VariableStore) {
return EFI_OUT_OF_RESOURCES;
}
SetMem (VariableStore, VARIABLE_STORE_SIZE, 0xff);
//
// Variable Specific Data
//
*VariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;
*LastVariableOffset = sizeof (VARIABLE_STORE_HEADER);
VariableStore->Signature = VARIABLE_STORE_SIGNATURE;
VariableStore->Size = VARIABLE_STORE_SIZE;
VariableStore->Format = VARIABLE_STORE_FORMATTED;
VariableStore->State = VARIABLE_STORE_HEALTHY;
VariableStore->Reserved = 0;
VariableStore->Reserved1 = 0;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
VariableCommonInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
This function does common initialization for variable services
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
//
// Allocate memory for mVariableModuleGlobal
//
mVariableModuleGlobal = (ESAL_VARIABLE_GLOBAL *) AllocateRuntimePool (
sizeof (ESAL_VARIABLE_GLOBAL)
);
if (NULL == mVariableModuleGlobal) {
return EFI_OUT_OF_RESOURCES;
}
//
// Intialize volatile variable store
//
Status = InitializeVariableStore (
&mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase,
&mVariableModuleGlobal->VolatileLastVariableOffset
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Intialize non volatile variable store
//
Status = InitializeVariableStore (
&mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset
);
return Status;
}

Some files were not shown because too many files have changed in this diff Show More