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