debugport.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 874 行 · 第 1/2 页
C
874 行
"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,
&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 (
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 = EfiLibAllocatePool (DataSize);
if (DebugPortDevice->DebugPortVariable != NULL) {
gRT->GetVariable (
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)
);
}
}
}
}
STATIC
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;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?