conplatform.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 861 行 · 第 1/2 页
C
861 行
CHECK
);
if (!EFI_ERROR (Status)) {
NeedClose = FALSE;
gBS->InstallMultipleProtocolInterfaces (
&ControllerHandle,
&gEfiStandardErrorDeviceGuid,
NULL,
NULL
);
}
if (NeedClose) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiSimpleTextOutProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
}
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
ConPlatformDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Arguments:
(Standard DriverBinding Protocol Stop() function)
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
//
// hot plug device is not included into the console associated variables,
// so no need to check variable for those hot plug devices.
//
if (!IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {
//
// Get the Device Path Protocol so the environment variables can be updated
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &DevicePath,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
//
// Remove DevicePath from ConInDev, ConOutDev, and StdErrDev
//
ConPlatformUpdateDeviceVariable (
VarConsoleInpDev,
DevicePath,
DELETE
);
ConPlatformUpdateDeviceVariable (
VarConsoleOutDev,
DevicePath,
DELETE
);
ConPlatformUpdateDeviceVariable (
VarErrorOutDev,
DevicePath,
DELETE
);
}
}
//
// Uninstall the Console Device GUIDs from Controller Handle
//
ConPlatformUnInstallProtocol (
This,
ControllerHandle,
&gEfiConsoleInDeviceGuid
);
ConPlatformUnInstallProtocol (
This,
ControllerHandle,
&gEfiConsoleOutDeviceGuid
);
ConPlatformUnInstallProtocol (
This,
ControllerHandle,
&gEfiStandardErrorDeviceGuid
);
//
// Close the Simple Input and Simple Text Output Protocols
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiSimpleTextInProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEfiSimpleTextOutProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
VOID
ConPlatformUnInstallProtocol (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_GUID *ProtocolGuid
)
{
EFI_STATUS Status;
Status = gBS->OpenProtocol (
Handle,
ProtocolGuid,
NULL,
This->DriverBindingHandle,
Handle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Status)) {
gBS->UninstallMultipleProtocolInterfaces (
Handle,
ProtocolGuid,
NULL,
NULL
);
}
return ;
}
VOID *
ConPlatformGetVariable (
IN CHAR16 *Name
)
/*++
Routine Description:
Read the EFI variable (Name) and return a dynamically allocated
buffer, and the size of the buffer. On failure return NULL.
Arguments:
Name - String part of EFI variable name
Returns:
Dynamically allocated memory that contains a copy of the EFI variable.
Caller is repsoncible freeing the buffer.
NULL - Variable was not read
--*/
{
EFI_STATUS Status;
VOID *Buffer;
UINTN BufferSize;
BufferSize = 0;
Buffer = NULL;
//
// Test to see if the variable exists. If it doesn't reuturn NULL
//
Status = gRT->GetVariable (
Name,
&gEfiGlobalVariableGuid,
NULL,
&BufferSize,
Buffer
);
if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Allocate the buffer to return
//
Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer);
if (EFI_ERROR (Status)) {
return NULL;
}
//
// Read variable into the allocated buffer.
//
Status = gRT->GetVariable (
Name,
&gEfiGlobalVariableGuid,
NULL,
&BufferSize,
Buffer
);
if (EFI_ERROR (Status)) {
gBS->FreePool (Buffer);
Buffer = NULL;
}
}
return Buffer;
}
EFI_STATUS
ConPlatformMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL * Multi,
IN EFI_DEVICE_PATH_PROTOCOL * Single,
IN EFI_DEVICE_PATH_PROTOCOL **NewDevicePath OPTIONAL,
IN BOOLEAN Delete
)
/*++
Routine Description:
Function compares a device path data structure to that of all the nodes of a
second device path instance.
Arguments:
Multi - A pointer to a multi-instance device path data structure.
Single - A pointer to a single-instance device path data structure.
NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
points to the remaining device path data structure.
(remaining device path = Multi - Single.)
Delete - If TRUE, means removing Single from Multi.
If FALSE, the routine just check whether Single matches
with any instance in Multi.
Returns:
The function returns EFI_SUCCESS if the Single is contained within Multi.
Otherwise, EFI_NOT_FOUND is returned.
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath1;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath2;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
UINTN Size;
//
// The passed in DevicePath should not be NULL
//
if ((!Multi) || (!Single)) {
return EFI_NOT_FOUND;
}
//
// if performing Delete operation, the NewDevicePath must not be NULL.
//
TempDevicePath1 = NULL;
DevicePath = Multi;
DevicePathInst = EfiDevicePathInstance (&DevicePath, &Size);
//
// search for the match of 'Single' in 'Multi'
//
while (DevicePathInst) {
if (EfiCompareMem (Single, DevicePathInst, Size) == 0) {
if (!Delete) {
gBS->FreePool (DevicePathInst);
return EFI_SUCCESS;
}
} else {
if (Delete) {
TempDevicePath2 = EfiAppendDevicePathInstance (
TempDevicePath1,
DevicePathInst
);
gBS->FreePool (TempDevicePath1);
TempDevicePath1 = TempDevicePath2;
}
}
gBS->FreePool (DevicePathInst);
DevicePathInst = EfiDevicePathInstance (&DevicePath, &Size);
}
if (Delete) {
*NewDevicePath = TempDevicePath1;
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
EFI_STATUS
ConPlatformUpdateDeviceVariable (
IN CHAR16 *VariableName,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CONPLATFORM_VAR_OPERATION Operation
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *VariableDevicePath;
EFI_DEVICE_PATH_PROTOCOL *NewVariableDevicePath;
VariableDevicePath = NULL;
NewVariableDevicePath = NULL;
//
// Get Variable according to variable name.
// The memory for Variable is allocated within ConPlatformGetVarible(),
// it is the caller's responsibility to free the memory before return.
//
VariableDevicePath = ConPlatformGetVariable (VariableName);
if (Operation != DELETE) {
Status = ConPlatformMatchDevicePaths (
VariableDevicePath,
DevicePath,
NULL,
FALSE
);
if ((Operation == CHECK) || (!EFI_ERROR (Status))) {
//
// The device path is already in the variable
//
gBS->FreePool (VariableDevicePath);
return Status;
}
//
// The device path is not in variable. Append DevicePath to the
// environment variable that is a multi-instance device path.
//
Status = EFI_SUCCESS;
NewVariableDevicePath = EfiAppendDevicePathInstance (
VariableDevicePath,
DevicePath
);
if (NewVariableDevicePath == NULL) {
Status = EFI_OUT_OF_RESOURCES;
}
} else {
//
// Remove DevicePath from the environment variable that
// is a multi-instance device path.
//
Status = ConPlatformMatchDevicePaths (
VariableDevicePath,
DevicePath,
&NewVariableDevicePath,
TRUE
);
}
gBS->FreePool (VariableDevicePath);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gRT->SetVariable (
VariableName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
EfiDevicePathSize (NewVariableDevicePath),
NewVariableDevicePath
);
gBS->FreePool (NewVariableDevicePath);
return Status;
}
BOOLEAN
IsHotPlugDevice (
EFI_HANDLE DriverBindingHandle,
EFI_HANDLE ControllerHandle
)
{
EFI_STATUS Status;
//
// HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiHotPlugDeviceGuid,
NULL,
DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?