terminal.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,176 行 · 第 1/3 页
C
1,176 行
goto Error;
}
EfiZeroMem(TerminalDevice, sizeof (TERMINAL_DEV));
TerminalDevice->Signature = TERMINAL_DEV_SIGNATURE;
TerminalDevice->TerminalType = TerminalType;
TerminalDevice->SerialIo = SerialIo;
//
// Simple Input Protocol
//
TerminalDevice->SimpleInput.Reset = TerminalConInReset;
TerminalDevice->SimpleInput.ReadKeyStroke = TerminalConInReadKeyStroke;
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_WAIT,
EFI_TPL_NOTIFY,
TerminalConInWaitForKey,
&TerminalDevice->SimpleInput,
&TerminalDevice->SimpleInput.WaitForKey
);
if (EFI_ERROR (Status)) {
goto Error;
}
//
// initialize the FIFO buffer used for accommodating
// the pre-read pending characters
//
InitializeRawFiFo (TerminalDevice);
InitializeUnicodeFiFo (TerminalDevice);
InitializeEfiKeyFiFo (TerminalDevice);
//
// Set the timeout value of serial buffer for
// keystroke response performance issue
//
Mode = TerminalDevice->SerialIo->Mode;
SerialInTimeOut = 0;
if (Mode->BaudRate != 0) {
SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits)
* 2 * 1000000 / (UINTN) Mode->BaudRate;
}
Status = TerminalDevice->SerialIo->SetAttributes (
TerminalDevice->SerialIo,
Mode->BaudRate,Mode->ReceiveFifoDepth,
(UINT32)SerialInTimeOut,
Mode->Parity,
(UINT8)Mode->DataBits,
Mode->StopBits
);
if(EFI_ERROR(Status)) {
//
// if set attributes operation fails, invalidate
// the value of SerialInTimeOut,thus make it
// inconsistent with the default timeout value
// of serial buffer. This will invoke the recalculation
// in the readkeystroke routine.
//
TerminalDevice->SerialInTimeOut = 0;
} else {
TerminalDevice->SerialInTimeOut = SerialInTimeOut;
}
Status = TerminalDevice->SimpleInput.Reset (
&TerminalDevice->SimpleInput,
FALSE
);
if (EFI_ERROR (Status)) {
goto Error;
}
//
// Simple Text Output Protocol
//
TerminalDevice->SimpleTextOutput.Reset = TerminalConOutReset;
TerminalDevice->SimpleTextOutput.OutputString = TerminalConOutOutputString;
TerminalDevice->SimpleTextOutput.TestString = TerminalConOutTestString;
TerminalDevice->SimpleTextOutput.QueryMode = TerminalConOutQueryMode;
TerminalDevice->SimpleTextOutput.SetMode = TerminalConOutSetMode;
TerminalDevice->SimpleTextOutput.SetAttribute = TerminalConOutSetAttribute;
TerminalDevice->SimpleTextOutput.ClearScreen = TerminalConOutClearScreen;
TerminalDevice->SimpleTextOutput.SetCursorPosition = TerminalConOutSetCursorPosition;
TerminalDevice->SimpleTextOutput.EnableCursor = TerminalConOutEnableCursor;
TerminalDevice->SimpleTextOutput.Mode = &TerminalDevice->SimpleTextOutputMode;
TerminalDevice->SimpleTextOutputMode.MaxMode = 1;
//
// For terminal devices, cursor is always visible
//
TerminalDevice->SimpleTextOutputMode.CursorVisible = TRUE;
TerminalDevice->SimpleTextOutputMode.Attribute = EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK);
Status = TerminalDevice->SimpleTextOutput.Reset (
&TerminalDevice->SimpleTextOutput,
FALSE
);
if (EFI_ERROR (Status)) {
goto Error;
}
Status = TerminalDevice->SimpleTextOutput.SetMode (
&TerminalDevice->SimpleTextOutput,
0
);
if (EFI_ERROR (Status)) {
goto Error;
}
Status = TerminalDevice->SimpleTextOutput.EnableCursor (
&TerminalDevice->SimpleTextOutput,
TRUE
);
if (EFI_ERROR (Status)) {
goto Error;
}
//
//
//
TerminalDevice->InputState = INPUT_STATE_DEFAULT;
TerminalDevice->ResetState = RESET_STATE_DEFAULT;
Status = gBS->CreateEvent (
EFI_EVENT_TIMER,
EFI_TPL_CALLBACK,
NULL,
NULL,
&TerminalDevice->TwoSecondTimeOut
);
//
// Build the device path for the child device
//
Status = SetTerminalDevicePath (
TerminalDevice->TerminalType,
ParentDevicePath,
&TerminalDevice->DevicePath
);
if (EFI_ERROR(Status)) {
goto Error;
}
//
// Build the component name for the child device
//
TerminalDevice->ControllerNameTable = NULL;
switch (TerminalDevice->TerminalType) {
case PcAnsiType:
EfiLibAddUnicodeString (
"eng",
gTerminalComponentName.SupportedLanguages,
&TerminalDevice->ControllerNameTable,
L"PC-ANSI Serial Console"
);
break;
case VT100Type:
EfiLibAddUnicodeString (
"eng",
gTerminalComponentName.SupportedLanguages,
&TerminalDevice->ControllerNameTable,
L"VT-100 Serial Console"
);
break;
case VT100PlusType:
EfiLibAddUnicodeString (
"eng",
gTerminalComponentName.SupportedLanguages,
&TerminalDevice->ControllerNameTable,
L"VT-100+ Serial Console"
);
break;
case VTUTF8Type:
EfiLibAddUnicodeString (
"eng",
gTerminalComponentName.SupportedLanguages,
&TerminalDevice->ControllerNameTable,
L"VT-UTF8 Serial Console"
);
break;
}
//
// Install protocol interfaces for the serial device.
//
Status = gBS->InstallMultipleProtocolInterfaces (
&TerminalDevice->Handle,
&gEfiDevicePathProtocolGuid, TerminalDevice->DevicePath,
&gEfiSimpleTextInProtocolGuid, &TerminalDevice->SimpleInput,
&gEfiSimpleTextOutProtocolGuid,
&TerminalDevice->SimpleTextOutput,
NULL
);
if (EFI_ERROR (Status)) {
goto Error;
}
//
// if the serial device is a hot plug device, attaches the HotPlugGuid
// onto the terminal device handle.
//
Status = gBS->OpenProtocol (
Controller,
&gEfiHotPlugDeviceGuid,
NULL,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR(Status)) {
Status = gBS->InstallMultipleProtocolInterfaces (
&TerminalDevice->Handle,
&gEfiHotPlugDeviceGuid, NULL,
NULL
);
}
//
// Register the Parent-Child relationship via
// EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
//
Status = gBS->OpenProtocol (
Controller,
&gEfiSerialIoProtocolGuid,
(VOID **)&TerminalDevice->SerialIo,
This->DriverBindingHandle,
TerminalDevice->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
goto Error;
}
return EFI_SUCCESS;
Error:
//
// Use the Stop() function to free all resources allocated in Start()
//
if (TerminalDevice != NULL) {
if (TerminalDevice->Handle != NULL) {
This->Stop (This, Controller, 1, &TerminalDevice->Handle);
} else {
if (TerminalDevice->TwoSecondTimeOut != NULL) {
gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
}
if (TerminalDevice->SimpleInput.WaitForKey != NULL) {
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
}
if (TerminalDevice->ControllerNameTable) {
EfiLibFreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
}
gBS->FreePool (TerminalDevice);
}
}
This->Stop (This, Controller, 0, NULL);
return Status;
}
EFI_STATUS
TerminalDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
UINTN Index;
BOOLEAN AllChildrenStopped;
EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOutput;
TERMINAL_DEV *TerminalDevice;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_SERIAL_IO_PROTOCOL *SerialIo;
//
// Complete all outstanding transactions to Controller.
// Don't allow any new transaction to Controller to be started.
//
if (NumberOfChildren == 0) {
//
// Close the bus driver
//
Status = gBS->OpenProtocol (
Controller,
&gTerminalDriverGuid,
(VOID **)&ParentDevicePath,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
//
// Remove Parent Device Path from
// the Console Device Environment Variables
//
TerminalRemoveConsoleDevVariable (VarConsoleInpDev, ParentDevicePath);
TerminalRemoveConsoleDevVariable (VarConsoleOutDev, ParentDevicePath);
TerminalRemoveConsoleDevVariable (VarErrorOutDev, ParentDevicePath);
//
// Uninstall the Terminal Driver's GUID Tag from the Serial controller
//
Status = gBS->UninstallMultipleProtocolInterfaces (
Controller,
&gTerminalDriverGuid, ParentDevicePath,
NULL
);
//
// Free the ParentDevicePath that was duplicated in Start()
//
if (!EFI_ERROR (Status)) {
gBS->FreePool (ParentDevicePath);
}
}
gBS->CloseProtocol (
Controller,
&gEfiSerialIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}
AllChildrenStopped = TRUE;
for (Index = 0; Index < NumberOfChildren; Index++) {
Status = gBS->OpenProtocol (
ChildHandleBuffer[Index],
&gEfiSimpleTextOutProtocolGuid,
(VOID **)&SimpleTextOutput,
This->DriverBindingHandle,
ChildHandleBuffer[Index],
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR(Status)) {
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS(SimpleTextOutput);
gBS->CloseProtocol (
Controller,
&gEfiSerialIoProtocolGuid,
This->DriverBindingHandle,
ChildHandleBuffer[Index]
);
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandleBuffer[Index],
&gEfiSimpleTextInProtocolGuid,
&TerminalDevice->SimpleInput,
&gEfiSimpleTextOutProtocolGuid,
&TerminalDevice->SimpleTextOutput,
&gEfiDevicePathProtocolGuid,
TerminalDevice->DevicePath,
NULL
);
if (EFI_ERROR (Status)) {
gBS->OpenProtocol (
Controller,
&gEfiSerialIoProtocolGuid,
(VOID **)&SerialIo,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?