EFI_STATUS EFIAPI FdcControllerDriverSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) /*++ Routine Description: ControllerDriver Protocol Method Arguments: Returns: --*/ // GC_TODO: This - add argument and description to function comment // GC_TODO: Controller - add argument and description to function comment // GC_TODO: RemainingDevicePath - add argument and description to function comment { EFI_STATUS Status; EFI_INTERFACE_DEFINITION_FOR_ISA_IO *IsaIo; // // Open the ISA I/O Protocol // Status = gBS->OpenProtocol ( Controller, EFI_ISA_IO_PROTOCOL_VERSION, (VOID **) &IsaIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Use the ISA I/O Protocol to see if Controller is a Floppy Disk Controller // Status = EFI_SUCCESS; if ((IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) && (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x700))) { Status = EFI_UNSUPPORTED; } // // Close the ISA I/O Protocol // gBS->CloseProtocol ( Controller, EFI_ISA_IO_PROTOCOL_VERSION, This->DriverBindingHandle, Controller ); return Status; }
EFI_STATUS EFIAPI KbdControllerDriverSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) /*++ Routine Description: ControllerDriver Protocol Method Arguments: Returns: --*/ // GC_TODO: This - add argument and description to function comment // GC_TODO: Controller - add argument and description to function comment // GC_TODO: RemainingDevicePath - add argument and description to function comment { EFI_STATUS Status; EFI_INTERFACE_DEFINITION_FOR_ISA_IO *IsaIo; // // Open the IO Abstraction(s) needed to perform the supported test // Status = gBS->OpenProtocol ( Controller, EFI_ISA_IO_PROTOCOL_VERSION, (VOID **) &IsaIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Use the ISA I/O Protocol to see if Controller is the Keyboard controller // if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303) || IsaIo->ResourceList->Device.UID != 0) { Status = EFI_UNSUPPORTED; } // // Close the I/O Abstraction(s) used to perform the supported test // gBS->CloseProtocol ( Controller, EFI_ISA_IO_PROTOCOL_VERSION, This->DriverBindingHandle, Controller ); return Status; }
/** Check whether the device path node is ISA Serial Node. @param Acpi Device path node to be checked @retval TRUE It's ISA Serial Node. @retval FALSE It's NOT ISA Serial Node. **/ BOOLEAN IsIsaSerialNode ( IN ACPI_HID_DEVICE_PATH *Acpi ) { return (BOOLEAN) ( (DevicePathType (Acpi) == ACPI_DEVICE_PATH) && (DevicePathSubType (Acpi) == ACPI_DP) && (ReadUnaligned32 (&Acpi->HID) == EISA_PNP_ID (0x0501)) ); }
BOOLEAN RetrieveUartUid ( IN EFI_HANDLE Handle, IN OUT UINT32 *AcpiUid ) /*++ Routine Description: Retrieve ACPI UID of UART from device path Arguments: Handles - EFI_SERIAL_IO_PROTOCOL handle Returns: TRUE - Find valid UID from device path FALSE - Can't find --*/ { UINT32 Match; UINT8 *Ptr; ACPI_HID_DEVICE_PATH *Acpi; EFI_DEVICE_PATH_PROTOCOL *DevicePath; gBS->HandleProtocol ( Handle, &gEfiDevicePathProtocolGuid, &DevicePath ); Ptr = (UINT8 *) DevicePath; while (*Ptr != END_DEVICE_PATH_TYPE) { Ptr++; } Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH); Acpi = (ACPI_HID_DEVICE_PATH *) Ptr; Match = EISA_PNP_ID (0x0501); if (EfiCompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { if (AcpiUid != NULL) { *AcpiUid = Acpi->UID; } return TRUE; } else { return FALSE; } }
/** Test controller is a keyboard Controller. @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL @param Controller driver's controller @param RemainingDevicePath children device path @retval EFI_UNSUPPORTED controller is not floppy disk @retval EFI_SUCCESS controller is floppy disk **/ EFI_STATUS EFIAPI KbdControllerDriverSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_ISA_IO_PROTOCOL *IsaIo; // // Open the IO Abstraction(s) needed to perform the supported test // Status = gBS->OpenProtocol ( Controller, &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Use the ISA I/O Protocol to see if Controller is the Keyboard controller // if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303) || IsaIo->ResourceList->Device.UID != 0) { Status = EFI_UNSUPPORTED; } // // Close the I/O Abstraction(s) used to perform the supported test // gBS->CloseProtocol ( Controller, &gEfiIsaIoProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
EFI_STATUS UpdateComAttributeFromVariable ( EFI_DEVICE_PATH_PROTOCOL *DevicePath ) /*++ Routine Description: Update Com Ports attributes from DevicePath Arguments: DevicePath - DevicePath that contains Com ports Returns: --*/ { EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *SerialNode; ACPI_HID_DEVICE_PATH *Acpi; UART_DEVICE_PATH *Uart; UART_DEVICE_PATH *Uart1; UINT32 Match; UINTN TerminalNumber; BM_MENU_ENTRY *NewMenuEntry; BM_TERMINAL_CONTEXT *NewTerminalContext; UINTN Index; Match = EISA_PNP_ID (0x0501); Node = DevicePath; Node = NextDevicePathNode (Node); TerminalNumber = 0; for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { while (!IsDevicePathEnd (Node)) { if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) { Acpi = (ACPI_HID_DEVICE_PATH *) Node; if (EfiCompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { EfiCopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32)); } } if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { Uart = (UART_DEVICE_PATH *) Node; NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber); if (NULL == NewMenuEntry) { return EFI_NOT_FOUND; } NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; EfiCopyMem ( &NewTerminalContext->BaudRate, &Uart->BaudRate, sizeof (UINT64) ); EfiCopyMem ( &NewTerminalContext->DataBits, &Uart->DataBits, sizeof (UINT8) ); EfiCopyMem ( &NewTerminalContext->Parity, &Uart->Parity, sizeof (UINT8) ); EfiCopyMem ( &NewTerminalContext->StopBits, &Uart->StopBits, sizeof (UINT8) ); SerialNode = NewTerminalContext->DevicePath; SerialNode = NextDevicePathNode (SerialNode); while (!IsDevicePathEnd (SerialNode)) { if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) { // // Update following device paths according to // previous acquired uart attributes // Uart1 = (UART_DEVICE_PATH *) SerialNode; EfiCopyMem ( &Uart1->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); EfiCopyMem ( &Uart1->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); EfiCopyMem ( &Uart1->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); EfiCopyMem ( &Uart1->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); break; } SerialNode = NextDevicePathNode (SerialNode); } // // end while // } Node = NextDevicePathNode (Node); } // // end while // } return EFI_SUCCESS; }
BOOLEAN IsTerminalDevicePath ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT TYPE_OF_TERMINAL *Termi, OUT UINTN *Com ) /*++ Routine Description: Test whether DevicePath is a valid Terminal Arguments: DevicePath - DevicePath to be checked Termi - If is terminal, give its type Com - If is Com Port, give its type Returns: TRUE - If DevicePath point to a Terminal FALSE --*/ { UINT8 *Ptr; BOOLEAN IsTerminal; VENDOR_DEVICE_PATH *Vendor; ACPI_HID_DEVICE_PATH *Acpi; UINT32 Match; EFI_GUID TempGuid; IsTerminal = FALSE; // // Parse the Device Path, should be change later!!! // Ptr = (UINT8 *) DevicePath; while (*Ptr != END_DEVICE_PATH_TYPE) { Ptr++; } Ptr = Ptr - sizeof (VENDOR_DEVICE_PATH); Vendor = (VENDOR_DEVICE_PATH *) Ptr; // // There are four kinds of Terminal types // check to see whether this devicepath // is one of that type // EfiCopyMem (&TempGuid, &Vendor->Guid, sizeof (EFI_GUID)); if (EfiCompareGuid (&TempGuid, &Guid[0])) { *Termi = PC_ANSI; IsTerminal = TRUE; } else { if (EfiCompareGuid (&TempGuid, &Guid[1])) { *Termi = VT_100; IsTerminal = TRUE; } else { if (EfiCompareGuid (&TempGuid, &Guid[2])) { *Termi = VT_100_PLUS; IsTerminal = TRUE; } else { if (EfiCompareGuid (&TempGuid, &Guid[3])) { *Termi = VT_UTF8; IsTerminal = TRUE; } else { IsTerminal = FALSE; } } } } if (!IsTerminal) { return FALSE; } Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH); Acpi = (ACPI_HID_DEVICE_PATH *) Ptr; Match = EISA_PNP_ID (0x0501); if (EfiCompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { EfiCopyMem (Com, &Acpi->UID, sizeof (UINT32)); } else { return FALSE; } return TRUE; }
EFI_STATUS LocateSerialIo ( VOID ) /*++ Routine Description: Build a list containing all serial devices Arguments: Returns: --*/ { UINT8 *Ptr; UINTN Index; UINTN Index2; UINTN NoHandles; EFI_HANDLE *Handles; EFI_STATUS Status; ACPI_HID_DEVICE_PATH *Acpi; EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINT32 Match; EFI_SERIAL_IO_PROTOCOL *SerialIo; EFI_DEVICE_PATH_PROTOCOL *OutDevicePath; EFI_DEVICE_PATH_PROTOCOL *InpDevicePath; EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath; BM_MENU_ENTRY *NewMenuEntry; BM_TERMINAL_CONTEXT *NewTerminalContext; EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; VENDOR_DEVICE_PATH Vendor; // // Get all handles that have SerialIo protocol installed // InitializeListHead (&TerminalMenu.Head); TerminalMenu.MenuNumber = 0; Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles ); if (EFI_ERROR (Status)) { // // No serial ports present // return EFI_UNSUPPORTED; } // // Sort Uart handles array with Acpi->UID from low to high // then Terminal menu can be built from low Acpi->UID to high Acpi->UID // SortedUartHandle (Handles, NoHandles); for (Index = 0; Index < NoHandles; Index++) { // // Check to see whether the handle has DevicePath Protocol installed // gBS->HandleProtocol ( Handles[Index], &gEfiDevicePathProtocolGuid, &DevicePath ); Ptr = (UINT8 *) DevicePath; while (*Ptr != END_DEVICE_PATH_TYPE) { Ptr++; } Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH); Acpi = (ACPI_HID_DEVICE_PATH *) Ptr; Match = EISA_PNP_ID (0x0501); if (EfiCompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT); if (!NewMenuEntry) { SafeFreePool (Handles); return EFI_OUT_OF_RESOURCES; } NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; EfiCopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32)); NewTerminalContext->DevicePath = DevicePathInstanceDup (DevicePath); // // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system! // coz' the misc data for each platform is not correct, actually it's the device path stored in // datahub which is not completed, so a searching for end of device path will enter a // dead-loop. // NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath); if (NULL == NewMenuEntry->DisplayString) { NewMenuEntry->DisplayString = DevicePathToStr (DevicePath); } NewMenuEntry->HelpString = NULL; gBS->HandleProtocol ( Handles[Index], &gEfiSerialIoProtocolGuid, &SerialIo ); EfiCopyMem ( &NewTerminalContext->BaudRate, &SerialIo->Mode->BaudRate, sizeof (UINT64) ); EfiCopyMem ( &NewTerminalContext->DataBits, &SerialIo->Mode->DataBits, sizeof (UINT8) ); EfiCopyMem ( &NewTerminalContext->Parity, &SerialIo->Mode->Parity, sizeof (UINT8) ); EfiCopyMem ( &NewTerminalContext->StopBits, &SerialIo->Mode->StopBits, sizeof (UINT8) ); InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link); TerminalMenu.MenuNumber++; } } SafeFreePool (Handles); // // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var // OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid); InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid); ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid); if (OutDevicePath) { UpdateComAttributeFromVariable (OutDevicePath); } if (InpDevicePath) { UpdateComAttributeFromVariable (InpDevicePath); } if (ErrDevicePath) { UpdateComAttributeFromVariable (ErrDevicePath); } for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index); if (NULL == NewMenuEntry) { return EFI_NOT_FOUND; } NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; NewTerminalContext->TerminalType = 0; NewTerminalContext->IsConIn = FALSE; NewTerminalContext->IsConOut = FALSE; NewTerminalContext->IsStdErr = FALSE; Vendor.Header.Type = MESSAGING_DEVICE_PATH; Vendor.Header.SubType = MSG_VENDOR_DP; for (Index2 = 0; Index2 < 4; Index2++) { EfiCopyMem (&Vendor.Guid, &Guid[Index2], sizeof (EFI_GUID)); SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH)); NewDevicePath = EfiAppendDevicePathNode ( NewTerminalContext->DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &Vendor ); SafeFreePool (NewMenuEntry->HelpString); // // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath); // NewMenuEntry->DisplayString = NewMenuEntry->HelpString; // NewMenuEntry->HelpString = NULL; if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) { NewTerminalContext->IsConOut = TRUE; NewTerminalContext->TerminalType = (UINT8) Index2; } if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) { NewTerminalContext->IsConIn = TRUE; NewTerminalContext->TerminalType = (UINT8) Index2; } if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) { NewTerminalContext->IsStdErr = TRUE; NewTerminalContext->TerminalType = (UINT8) Index2; } } } return EFI_SUCCESS; }
EFI_STATUS ChangeTerminalDevicePath ( EFI_DEVICE_PATH_PROTOCOL *DevicePath, BOOLEAN ChangeTerminal ) { EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *Node1; ACPI_HID_DEVICE_PATH *Acpi; UART_DEVICE_PATH *Uart; UART_DEVICE_PATH *Uart1; UINTN Com; UINT32 Match; BM_TERMINAL_CONTEXT *NewTerminalContext; BM_MENU_ENTRY *NewMenuEntry; Match = EISA_PNP_ID (0x0501); Node = DevicePath; Node = NextDevicePathNode (Node); Com = 0; while (!IsDevicePathEnd (Node)) { if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) { Acpi = (ACPI_HID_DEVICE_PATH *) Node; if (EfiCompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { EfiCopyMem (&Com, &Acpi->UID, sizeof (UINT32)); } } NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com); if (NULL == NewMenuEntry) { return EFI_NOT_FOUND; } NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { Uart = (UART_DEVICE_PATH *) Node; EfiCopyMem ( &Uart->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); EfiCopyMem ( &Uart->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); EfiCopyMem ( &Uart->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); EfiCopyMem ( &Uart->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); // // Change the device path in the ComPort // if (ChangeTerminal) { Node1 = NewTerminalContext->DevicePath; Node1 = NextDevicePathNode (Node1); while (!IsDevicePathEnd (Node1)) { if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) { Uart1 = (UART_DEVICE_PATH *) Node1; EfiCopyMem ( &Uart1->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); EfiCopyMem ( &Uart1->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); EfiCopyMem ( &Uart1->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); EfiCopyMem ( &Uart1->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); break; } // // end if // Node1 = NextDevicePathNode (Node1); } // // end while // break; } } Node = NextDevicePathNode (Node); } return EFI_SUCCESS; }
VOID ChangeVariableDevicePath ( EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { EFI_DEVICE_PATH_PROTOCOL *Node; ACPI_HID_DEVICE_PATH *Acpi; UART_DEVICE_PATH *Uart; UINTN Com; UINT32 Match; BM_TERMINAL_CONTEXT *NewTerminalContext; BM_MENU_ENTRY *NewMenuEntry; Match = EISA_PNP_ID (0x0501); Node = DevicePath; Node = NextDevicePathNode (Node); Com = 0; while (!IsDevicePathEnd (Node)) { if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) { Acpi = (ACPI_HID_DEVICE_PATH *) Node; if (EfiCompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { EfiCopyMem (&Com, &Acpi->UID, sizeof (UINT32)); } } if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { NewMenuEntry = BOpt_GetMenuEntry ( &TerminalMenu, Com ); ASSERT (NewMenuEntry != NULL); NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; Uart = (UART_DEVICE_PATH *) Node; EfiCopyMem ( &Uart->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); EfiCopyMem ( &Uart->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); EfiCopyMem ( &Uart->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); EfiCopyMem ( &Uart->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); } Node = NextDevicePathNode (Node); } return ; }
/** Test controller is a keyboard Controller. @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL @param Controller driver's controller @param RemainingDevicePath children device path @retval EFI_UNSUPPORTED controller is not floppy disk @retval EFI_SUCCESS controller is floppy disk **/ EFI_STATUS EFIAPI KbdControllerDriverSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_SIO_PROTOCOL *Sio; EFI_DEVICE_PATH_PROTOCOL *DevicePath; ACPI_HID_DEVICE_PATH *Acpi; // // Check whether the controller is keyboard. // Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } do { Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath; DevicePath = NextDevicePathNode (DevicePath); } while (!IsDevicePathEnd (DevicePath)); if (DevicePathType (Acpi) != ACPI_DEVICE_PATH || (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) { return EFI_UNSUPPORTED; } if (Acpi->HID != EISA_PNP_ID (0x303) || Acpi->UID != 0) { return EFI_UNSUPPORTED; } // // Open the IO Abstraction(s) needed to perform the supported test // Status = gBS->OpenProtocol ( Controller, &gEfiSioProtocolGuid, (VOID **) &Sio, This->DriverBindingHandle, Controller, 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 ( Controller, &gEfiSioProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
/** Checks the state of the floppy and if media is inserted. This routine checks the state of the floppy and if media is inserted. There are 3 cases: No floppy present - Set BBS entry to ignore Floppy present & no media - Set BBS entry to lowest priority. We cannot set it to ignore since 16-bit CSM will indicate no floppy and thus drive A: is unusable. CSM-16 will not try floppy since lowest priority and thus not incur boot time penality. Floppy present & media - Set BBS entry to some priority. @return State of floppy media **/ UINT8 HasMediaInFloppy ( VOID ) { EFI_STATUS Status; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINTN Index; EFI_ISA_IO_PROTOCOL *IsaIo; EFI_BLOCK_IO_PROTOCOL *BlkIo; HandleBuffer = NULL; HandleCount = 0; gBS->LocateHandleBuffer ( ByProtocol, &gEfiIsaIoProtocolGuid, NULL, &HandleCount, &HandleBuffer ); // // If don't find any ISA/IO protocol assume no floppy. Need for floppy // free system // if (HandleCount == 0) { return FLOPPY_NOT_PRESENT; } ASSERT (HandleBuffer != NULL); for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol ( HandleBuffer[Index], &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo ); if (EFI_ERROR (Status)) { continue; } if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) { continue; } // // Update blockio in case the floppy is inserted in during BdsTimeout // Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); if (EFI_ERROR (Status)) { continue; } Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); if (EFI_ERROR (Status)) { continue; } Status = gBS->HandleProtocol ( HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlkIo ); if (EFI_ERROR (Status)) { continue; } if (BlkIo->Media->MediaPresent) { FreePool (HandleBuffer); return FLOPPY_PRESENT_WITH_MEDIA; } else { FreePool (HandleBuffer); return FLOPPY_PRESENT_NO_MEDIA; } } FreePool (HandleBuffer); return FLOPPY_NOT_PRESENT; }
/** Test to see if this driver supports ControllerHandle. Any ControllerHandle than contains a IsaIo protocol can be supported. @param This Protocol instance pointer. @param ControllerHandle Handle of device to test @param RemainingDevicePath Optional parameter use to pick a specific child device to start. @retval EFI_SUCCESS This driver supports this device @retval EFI_ALREADY_STARTED This driver is already running on this device @retval other This driver does not support this device **/ EFI_STATUS EFIAPI PS2MouseDriverSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_SIO_PROTOCOL *Sio; EFI_DEVICE_PATH_PROTOCOL *DevicePath; ACPI_HID_DEVICE_PATH *Acpi; // // Check whether the controller is keyboard. // Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } do { Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath; DevicePath = NextDevicePathNode (DevicePath); } while (!IsDevicePathEnd (DevicePath)); if (DevicePathType (Acpi) != ACPI_DEVICE_PATH || (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) { return EFI_UNSUPPORTED; } switch (Acpi->HID) { case EISA_PNP_ID (0xF03): // // Microsoft PS/2 style mouse // case EISA_PNP_ID (0xF13): // // PS/2 Port for PS/2-style Mice // break; case EISA_PNP_ID (0x303): // // IBM Enhanced (101/102-key, PS/2 mouse support) // if (Acpi->UID == 1) { break; } default: return EFI_UNSUPPORTED; break; } // // Open the IO Abstraction(s) needed to perform the supported test // Status = gBS->OpenProtocol ( Controller, &gEfiSioProtocolGuid, (VOID **) &Sio, This->DriverBindingHandle, Controller, 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 ( Controller, &gEfiSioProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
UINT32 Signature; EFI_PCI_IO_DEVICE_PATH DevicePath; EFI_PCI_IO_PROTOCOL PciIoProtocol; PCI_TYPE00 *ConfigSpace; PCI_ROOT_BRIDGE RootBridge; UINTN Segment; } EFI_PCI_IO_PRIVATE_DATA; #define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o') #define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_PCI_IO_PRIVATE_DATA, PciIoProtocol, EFI_PCI_IO_PRIVATE_DATA_SIGNATURE) EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate = { { { ACPI_DEVICE_PATH, ACPI_DP, sizeof (ACPI_HID_DEVICE_PATH), 0}, EISA_PNP_ID(0x0A03), // HID 0 // UID }, { { HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH), 0}, 0, 0 }, { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} }; STATIC VOID ConfigureUSBHost ( VOID )
/** Collect EFI Info about legacy devices through Super IO interface. @param SioPtr Pointer to SIO data. @retval EFI_SUCCESS When SIO data is got successfully. @retval EFI_NOT_FOUND When ISA IO interface is absent. **/ EFI_STATUS LegacyBiosBuildSioDataFromSio ( IN DEVICE_PRODUCER_DATA_HEADER *SioPtr ) { EFI_STATUS Status; DEVICE_PRODUCER_SERIAL *SioSerial; DEVICE_PRODUCER_PARALLEL *SioParallel; DEVICE_PRODUCER_FLOPPY *SioFloppy; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINTN Index; UINTN ChildIndex; EFI_SIO_PROTOCOL *Sio; ACPI_RESOURCE_HEADER_PTR Resources; EFI_ACPI_IO_PORT_DESCRIPTOR *IoResource; EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *FixedIoResource; EFI_ACPI_DMA_DESCRIPTOR *DmaResource; EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR *IrqResource; UINT16 Address; UINT8 Dma; UINT8 Irq; UINTN EntryCount; EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_SERIAL_IO_PROTOCOL *SerialIo; EFI_DEVICE_PATH_PROTOCOL *DevicePath; ACPI_HID_DEVICE_PATH *Acpi; // // Get the list of ISA controllers in the system // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSioProtocolGuid, NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } // // Collect legacy information from each of the ISA controllers in the system // for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSioProtocolGuid, (VOID **) &Sio); if (EFI_ERROR (Status)) { continue; } Address = MAX_UINT16; Dma = MAX_UINT8; Irq = MAX_UINT8; Status = Sio->GetResources (Sio, &Resources); if (!EFI_ERROR (Status)) { // // Get the base address information from ACPI resource descriptor. // while (Resources.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) { switch (Resources.SmallHeader->Byte) { case ACPI_IO_PORT_DESCRIPTOR: IoResource = (EFI_ACPI_IO_PORT_DESCRIPTOR *) Resources.SmallHeader; Address = IoResource->BaseAddressMin; break; case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR: FixedIoResource = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) Resources.SmallHeader; Address = FixedIoResource->BaseAddress; break; case ACPI_DMA_DESCRIPTOR: DmaResource = (EFI_ACPI_DMA_DESCRIPTOR *) Resources.SmallHeader; Dma = (UINT8) LowBitSet32 (DmaResource->ChannelMask); break; case ACPI_IRQ_DESCRIPTOR: case ACPI_IRQ_NOFLAG_DESCRIPTOR: IrqResource = (EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR *) Resources.SmallHeader; Irq = (UINT8) LowBitSet32 (IrqResource->Mask); break; default: break; } if (Resources.SmallHeader->Bits.Type == 0) { Resources.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) Resources.SmallHeader + Resources.SmallHeader->Bits.Length + sizeof (*Resources.SmallHeader)); } else { Resources.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) Resources.LargeHeader + Resources.LargeHeader->Length + sizeof (*Resources.LargeHeader)); } } } DEBUG ((EFI_D_INFO, "LegacySio: Address/Dma/Irq = %x/%d/%d\n", Address, Dma, Irq)); DevicePath = DevicePathFromHandle (HandleBuffer[Index]); if (DevicePath == NULL) { continue; } Acpi = NULL; while (!IsDevicePathEnd (DevicePath)) { Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath; DevicePath = NextDevicePathNode (DevicePath); } if ((Acpi == NULL) || (DevicePathType (Acpi) != ACPI_DEVICE_PATH) || ((DevicePathSubType (Acpi) != ACPI_DP) && (DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) ) { continue; } // // See if this is an ISA serial port // // Ignore DMA resource since it is always returned NULL // if (Acpi->HID == EISA_PNP_ID (0x500) || Acpi->HID == EISA_PNP_ID (0x501)) { if (Acpi->UID < 4 && Address != MAX_UINT16 && Irq != MAX_UINT8) { // // Get the handle of the child device that has opened the Super I/O Protocol // Status = gBS->OpenProtocolInformation ( HandleBuffer[Index], &gEfiSioProtocolGuid, &OpenInfoBuffer, &EntryCount ); if (EFI_ERROR (Status)) { continue; } for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) { if ((OpenInfoBuffer[ChildIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { Status = gBS->HandleProtocol (OpenInfoBuffer[ChildIndex].ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID **) &SerialIo); if (!EFI_ERROR (Status)) { SioSerial = &SioPtr->Serial[Acpi->UID]; SioSerial->Address = Address; SioSerial->Irq = Irq; SioSerial->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF; break; } } } FreePool (OpenInfoBuffer); } } // // See if this is an ISA parallel port // // Ignore DMA resource since it is always returned NULL, port // only used in output mode. // if (Acpi->HID == EISA_PNP_ID (0x400) || Acpi->HID == EISA_PNP_ID (0x401)) { if (Acpi->UID < 3 && Address != MAX_UINT16 && Irq != MAX_UINT8 && Dma != MAX_UINT8) { SioParallel = &SioPtr->Parallel[Acpi->UID]; SioParallel->Address = Address; SioParallel->Irq = Irq; SioParallel->Dma = Dma; SioParallel->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY; } } // // See if this is an ISA floppy controller // if (Acpi->HID == EISA_PNP_ID (0x604)) { if (Address != MAX_UINT16 && Irq != MAX_UINT8 && Dma != MAX_UINT8) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo); if (!EFI_ERROR (Status)) { SioFloppy = &SioPtr->Floppy; SioFloppy->Address = Address; SioFloppy->Irq = Irq; SioFloppy->Dma = Dma; SioFloppy->NumberOfFloppy++; } } } // // See if this is a mouse // Always set mouse found so USB hot plug will work // // Ignore lower byte of HID. Pnp0fxx is any type of mouse. // // Hid = ResourceList->Device.HID & 0xff00ffff; // PnpId = EISA_PNP_ID(0x0f00); // if (Hid == PnpId) { // if (ResourceList->Device.UID == 1) { // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer); // if (!EFI_ERROR (Status)) { // SioPtr->MousePresent = 0x01; // // } // } // } // } FreePool (HandleBuffer); return EFI_SUCCESS; }
EFI_STATUS EFIAPI LpcDriverSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_PCI_IO_PROTOCOL *PciIo; EFI_DEVICE_PATH_PROTOCOL *IsaBridgeDevicePath; ACPI_HID_DEVICE_PATH *AcpiNode; PCI_DEVICE_PATH *PciNode; PCI_TYPE00 Pci; // // Get the ISA bridge's Device Path and test it // the following code is specific // Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **)&IsaBridgeDevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } Status = EFI_SUCCESS; AcpiNode = (ACPI_HID_DEVICE_PATH *)IsaBridgeDevicePath; if (AcpiNode->Header.Type != ACPI_DEVICE_PATH || AcpiNode->Header.SubType != ACPI_DP || DevicePathNodeLength (&AcpiNode->Header) != sizeof(ACPI_HID_DEVICE_PATH) || AcpiNode -> HID != EISA_PNP_ID(0x0A03) || AcpiNode -> UID != 0 ) { Status = EFI_UNSUPPORTED; } else { // // Get the next node // IsaBridgeDevicePath = NextDevicePathNode (IsaBridgeDevicePath); PciNode = (PCI_DEVICE_PATH *)IsaBridgeDevicePath; if (PciNode->Header.Type != HARDWARE_DEVICE_PATH || PciNode->Header.SubType != HW_PCI_DP || DevicePathNodeLength (&PciNode->Header) != sizeof (PCI_DEVICE_PATH) || PciNode -> Function != 0x00 || PciNode -> Device != 0x1f ) { Status = EFI_UNSUPPORTED; } } gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } // // Get PciIo protocol instance // Status = gBS->OpenProtocol ( Controller, &gEfiPciIoProtocolGuid, (VOID **)&PciIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR(Status)) { return Status; } Status = PciIo->Pci.Read ( PciIo, EfiPciIoWidthUint32, 0, sizeof(Pci) / sizeof(UINT32), &Pci ); if (!EFI_ERROR (Status)) { Status = EFI_SUCCESS; //TODO: force return success as temp solution EFI_UNSUPPORTED; if ((Pci.Hdr.Command & 0x03) == 0x03) { if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) { // // See if this is a standard PCI to ISA Bridge from the Base Code // and Class Code // if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) { Status = EFI_SUCCESS; } else { } // // See if this is an Intel PCI to ISA bridge in Positive Decode Mode // if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE && Pci.Hdr.VendorId == 0x8086 && Pci.Hdr.DeviceId == 0x7110) { Status = EFI_SUCCESS; } else { } } else { } } else { } } gBS->CloseProtocol ( Controller, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
/*++ * @name EfiInitTranslateDevicePath * * The EfiInitTranslateDevicePath routine * * @param DevicePath * UEFI Image Handle for the current loaded application. * * @param DeviceEntry * Pointer to the UEFI System Table. * * @return None * *--*/ NTSTATUS EfiInitTranslateDevicePath ( _In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath, _In_ PBL_DEVICE_DESCRIPTOR DeviceEntry ) { NTSTATUS Status; EFI_DEVICE_PATH_PROTOCOL* DeviceNode; MEMMAP_DEVICE_PATH* MemDevicePath; ACPI_HID_DEVICE_PATH *AcpiPath; HARDDRIVE_DEVICE_PATH *DiskPath; /* Assume failure */ Status = STATUS_UNSUCCESSFUL; /* Set size first */ DeviceEntry->Size = sizeof(*DeviceEntry); /* Check if we are booting from a RAM Disk */ if ((DevicePath->Type == HARDWARE_DEVICE_PATH) && (DevicePath->SubType == HW_MEMMAP_DP)) { /* Get the EFI data structure matching this */ MemDevicePath = (MEMMAP_DEVICE_PATH*)DevicePath; /* Set the boot library specific device types */ DeviceEntry->DeviceType = LocalDevice; DeviceEntry->Local.Type = RamDiskDevice; /* Extract the base, size, and offset */ DeviceEntry->Local.RamDisk.ImageBase.QuadPart = MemDevicePath->StartingAddress; DeviceEntry->Local.RamDisk.ImageSize.QuadPart = MemDevicePath->EndingAddress - MemDevicePath->StartingAddress; DeviceEntry->Local.RamDisk.ImageOffset = 0; return STATUS_SUCCESS; } /* Otherwise, check what kind of device node this is */ DeviceNode = EfiInitpGetDeviceNode(DevicePath); switch (DeviceNode->Type) { /* ACPI */ case ACPI_DEVICE_PATH: /* We only support floppy drives */ AcpiPath = (ACPI_HID_DEVICE_PATH*)DeviceNode; if ((AcpiPath->HID != EISA_PNP_ID(0x604)) && (AcpiPath->HID != EISA_PNP_ID(0x700))) { return Status; } /* Set the boot library specific device types */ DeviceEntry->DeviceType = LocalDevice; DeviceEntry->Local.Type = FloppyDevice; /* The ACPI UID is the drive number */ DeviceEntry->Local.FloppyDisk.DriveNumber = AcpiPath->UID; return STATUS_SUCCESS; /* Network, ATAPI, SCSI, USB */ case MESSAGING_DEVICE_PATH: /* Check if it's network */ if ((DeviceNode->SubType == MSG_MAC_ADDR_DP) || (DeviceNode->SubType == MSG_IPv4_DP)) { /* Set the boot library specific device types */ DeviceEntry->DeviceType = UdpDevice; DeviceEntry->Remote.Unknown = 256; return STATUS_SUCCESS; } /* Other types should come in as MEDIA_DEVICE_PATH -- Windows assumes this is a floppy */ DeviceEntry->DeviceType = DiskDevice; DeviceEntry->Local.Type = FloppyDevice; DeviceEntry->Local.FloppyDisk.DriveNumber = 0; return STATUS_SUCCESS; /* Disk or CDROM */ case MEDIA_DEVICE_PATH: /* Extract the disk path and check if it's a physical disk */ DiskPath = (HARDDRIVE_DEVICE_PATH*)DeviceNode; if (DeviceNode->SubType == MEDIA_HARDDRIVE_DP) { /* Check if this is an MBR partition */ if (DiskPath->SignatureType == SIGNATURE_TYPE_MBR) { /* Set that this is a local partition */ DeviceEntry->DeviceType = LegacyPartitionDevice; DeviceEntry->Partition.Disk.Type = LocalDevice; DeviceEntry->Partition.Disk.HardDisk.PartitionType = MbrPartition; DeviceEntry->Partition.Disk.HardDisk.Mbr.PartitionSignature = *(PULONG)&DiskPath->Signature[0]; DeviceEntry->Partition.Mbr.PartitionNumber = DiskPath->PartitionNumber; return STATUS_SUCCESS; } /* Check if it's a GPT partition */ if (DiskPath->SignatureType == SIGNATURE_TYPE_GUID) { /* Set that this is a local disk */ DeviceEntry->DeviceType = PartitionDevice; DeviceEntry->Partition.Disk.Type = LocalDevice; /* Set GPT partition ID */ DeviceEntry->Partition.Disk.HardDisk.PartitionType = GptPartition; /* Copy the signature GUID */ RtlCopyMemory(&DeviceEntry->Partition.Gpt.PartitionGuid, DiskPath->Signature, sizeof(GUID)); DeviceEntry->Flags |= 4u; return STATUS_SUCCESS; } /* Otherwise, raw boot is not supported */ DeviceEntry->DeviceType = PartitionDevice; DeviceEntry->Partition.Disk.Type = LocalDevice; DeviceEntry->Partition.Disk.HardDisk.PartitionType = RawPartition; DeviceEntry->Partition.Disk.HardDisk.Raw.DiskNumber = 0; } else if (DeviceNode->SubType == MEDIA_CDROM_DP) { /* Set the right type for a CDROM */ DeviceEntry->DeviceType = DiskDevice; DeviceEntry->Local.Type = CdRomDevice; /* Set the drive number to zero */ DeviceEntry->Local.FloppyDisk.DriveNumber = 0; return STATUS_SUCCESS; } /* Fail anything else */ default: break; } /* Return here only on failure */ return Status; }
/** Return whether the controller is a SIO serial controller. @param Controller The controller handle. @retval EFI_SUCCESS The controller is a SIO serial controller. @retval others The controller is not a SIO serial controller. **/ EFI_STATUS IsSioSerialController ( EFI_HANDLE Controller ) { EFI_STATUS Status; EFI_SIO_PROTOCOL *Sio; EFI_DEVICE_PATH_PROTOCOL *DevicePath; ACPI_HID_DEVICE_PATH *Acpi; // // Open the IO Abstraction(s) needed to perform the supported test // Status = gBS->OpenProtocol ( Controller, &gEfiSioProtocolGuid, (VOID **) &Sio, gSerialControllerDriver.DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (Status == EFI_ALREADY_STARTED) { return EFI_SUCCESS; } if (!EFI_ERROR (Status)) { // // Close the I/O Abstraction(s) used to perform the supported test // gBS->CloseProtocol ( Controller, &gEfiSioProtocolGuid, gSerialControllerDriver.DriverBindingHandle, Controller ); Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath, gSerialControllerDriver.DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); ASSERT (Status != EFI_ALREADY_STARTED); if (!EFI_ERROR (Status)) { do { Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath; DevicePath = NextDevicePathNode (DevicePath); } while (!IsDevicePathEnd (DevicePath)); if (DevicePathType (Acpi) != ACPI_DEVICE_PATH || (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP) || Acpi->HID != EISA_PNP_ID (0x501) ) { Status = EFI_UNSUPPORTED; } } // // Close protocol, don't use device path protocol in the Support() function // gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, gSerialControllerDriver.DriverBindingHandle, Controller ); } return Status; }
/** Test to see if this driver supports ControllerHandle. Any ControllerHandle than contains a IsaIo protocol can be supported. @param This Protocol instance pointer. @param ControllerHandle Handle of device to test @param RemainingDevicePath Optional parameter use to pick a specific child device to start. @retval EFI_SUCCESS This driver supports this device @retval EFI_ALREADY_STARTED This driver is already running on this device @retval other This driver does not support this device **/ EFI_STATUS EFIAPI PS2MouseAbsolutePointerDriverSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_ISA_IO_PROTOCOL *IsaIo; Status = EFI_SUCCESS; // // Open the IO Abstraction(s) needed to perform the supported test // Status = gBS->OpenProtocol ( Controller, &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Use the ISA I/O Protocol to see if Controller is the Mouse controller // switch (IsaIo->ResourceList->Device.HID) { case EISA_PNP_ID (0xF03): // // Microsoft PS/2 style mouse // case EISA_PNP_ID (0xF13): // // PS/2 Port for PS/2-style Mice // break; case EISA_PNP_ID (0x303): // // IBM Enhanced (101/102-key, PS/2 mouse support) // if (IsaIo->ResourceList->Device.UID == 1) { break; } default: Status = EFI_UNSUPPORTED; break; } // // Close the I/O Abstraction(s) used to perform the supported test // gBS->CloseProtocol ( Controller, &gEfiIsaIoProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
/** Test if the controller is a floppy disk drive device @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] Controller The handle of the controller to test. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. @retval EFI_SUCCESS The device is supported by this driver. @retval EFI_ALREADY_STARTED The device is already being managed by this driver. @retval EFI_ACCESS_DENIED The device is already being managed by a different driver or an application that requires exclusive access. @retval EFI_UNSUPPORTED The device is is not supported by this driver. **/ EFI_STATUS EFIAPI FdcControllerDriverSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_ISA_IO_PROTOCOL *IsaIo; EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; // // Ignore the parameter RemainingDevicePath because this is a device driver. // // // Open the device path protocol // Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &ParentDevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); // // Open the ISA I/O Protocol // Status = gBS->OpenProtocol ( Controller, &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Use the ISA I/O Protocol to see if Controller is a floppy disk drive device // Status = EFI_SUCCESS; if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) { Status = EFI_UNSUPPORTED; } // // Close the ISA I/O Protocol // gBS->CloseProtocol ( Controller, &gEfiIsaIoProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
/** Collect EFI Info about legacy devices through ISA IO interface. @param SioPtr Pointer to SIO data. @retval EFI_SUCCESS When SIO data is got successfully. @retval EFI_NOT_FOUND When ISA IO interface is absent. **/ EFI_STATUS LegacyBiosBuildSioDataFromIsaIo ( IN DEVICE_PRODUCER_DATA_HEADER *SioPtr ) { EFI_STATUS Status; DEVICE_PRODUCER_SERIAL *SioSerial; DEVICE_PRODUCER_PARALLEL *SioParallel; DEVICE_PRODUCER_FLOPPY *SioFloppy; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINTN Index; UINTN ResourceIndex; UINTN ChildIndex; EFI_ISA_IO_PROTOCOL *IsaIo; EFI_ISA_ACPI_RESOURCE_LIST *ResourceList; EFI_ISA_ACPI_RESOURCE *IoResource; EFI_ISA_ACPI_RESOURCE *DmaResource; EFI_ISA_ACPI_RESOURCE *InterruptResource; UINTN EntryCount; EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_SERIAL_IO_PROTOCOL *SerialIo; // // Get the list of ISA controllers in the system // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiIsaIoProtocolGuid, NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } // // Collect legacy information from each of the ISA controllers in the system // for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo); if (EFI_ERROR (Status)) { continue; } ResourceList = IsaIo->ResourceList; if (ResourceList == NULL) { continue; } // // Collect the resource types neededto fill in the SIO data structure // IoResource = NULL; DmaResource = NULL; InterruptResource = NULL; for (ResourceIndex = 0; ResourceList->ResourceItem[ResourceIndex].Type != EfiIsaAcpiResourceEndOfList; ResourceIndex++ ) { switch (ResourceList->ResourceItem[ResourceIndex].Type) { case EfiIsaAcpiResourceIo: IoResource = &ResourceList->ResourceItem[ResourceIndex]; break; case EfiIsaAcpiResourceMemory: break; case EfiIsaAcpiResourceDma: DmaResource = &ResourceList->ResourceItem[ResourceIndex]; break; case EfiIsaAcpiResourceInterrupt: InterruptResource = &ResourceList->ResourceItem[ResourceIndex]; break; default: break; } } // // See if this is an ISA serial port // // Ignore DMA resource since it is always returned NULL // if (ResourceList->Device.HID == EISA_PNP_ID (0x500) || ResourceList->Device.HID == EISA_PNP_ID (0x501)) { if (ResourceList->Device.UID <= 3 && IoResource != NULL && InterruptResource != NULL ) { // // Get the handle of the child device that has opened the ISA I/O Protocol // Status = gBS->OpenProtocolInformation ( HandleBuffer[Index], &gEfiIsaIoProtocolGuid, &OpenInfoBuffer, &EntryCount ); if (EFI_ERROR (Status)) { continue; } // // We want resource for legacy even if no 32-bit driver installed // for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) { if ((OpenInfoBuffer[ChildIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { Status = gBS->HandleProtocol (OpenInfoBuffer[ChildIndex].ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID **) &SerialIo); if (!EFI_ERROR (Status)) { SioSerial = &SioPtr->Serial[ResourceList->Device.UID]; SioSerial->Address = (UINT16) IoResource->StartRange; SioSerial->Irq = (UINT8) InterruptResource->StartRange; SioSerial->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF; break; } } } FreePool (OpenInfoBuffer); } } // // See if this is an ISA parallel port // // Ignore DMA resource since it is always returned NULL, port // only used in output mode. // if (ResourceList->Device.HID == EISA_PNP_ID (0x400) || ResourceList->Device.HID == EISA_PNP_ID (0x401)) { if (ResourceList->Device.UID <= 2 && IoResource != NULL && InterruptResource != NULL && DmaResource != NULL ) { SioParallel = &SioPtr->Parallel[ResourceList->Device.UID]; SioParallel->Address = (UINT16) IoResource->StartRange; SioParallel->Irq = (UINT8) InterruptResource->StartRange; SioParallel->Dma = (UINT8) DmaResource->StartRange; SioParallel->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY; } } // // See if this is an ISA floppy controller // if (ResourceList->Device.HID == EISA_PNP_ID (0x604)) { if (IoResource != NULL && InterruptResource != NULL && DmaResource != NULL) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo); if (!EFI_ERROR (Status)) { SioFloppy = &SioPtr->Floppy; SioFloppy->Address = (UINT16) IoResource->StartRange; SioFloppy->Irq = (UINT8) InterruptResource->StartRange; SioFloppy->Dma = (UINT8) DmaResource->StartRange; SioFloppy->NumberOfFloppy++; } } } // // See if this is a mouse // Always set mouse found so USB hot plug will work // // Ignore lower byte of HID. Pnp0fxx is any type of mouse. // // Hid = ResourceList->Device.HID & 0xff00ffff; // PnpId = EISA_PNP_ID(0x0f00); // if (Hid == PnpId) { // if (ResourceList->Device.UID == 1) { // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer); // if (!EFI_ERROR (Status)) { // SioPtr->MousePresent = 0x01; // // } // } // } // } FreePool (HandleBuffer); return EFI_SUCCESS; }
/** Create a structure that maps the relative positions of PCI root buses to bus numbers. In the "bootorder" fw_cfg file, QEMU refers to extra PCI root buses by their positions, in relative root bus number order, not by their actual PCI bus numbers. The ACPI HID device path nodes however that are associated with PciRootBridgeIo protocol instances in the system have their UID fields set to the bus numbers. Create a map that gives, for each extra PCI root bus's position (ie. "serial number") its actual PCI bus number. @param[out] ExtraRootBusMap The data structure implementing the map. @retval EFI_SUCCESS ExtraRootBusMap has been populated. @retval EFI_OUT_OF_RESOURCES Memory allocation failed. @retval EFI_ALREADY_STARTED A duplicate root bus number has been found in the system. (This should never happen.) @return Error codes returned by gBS->LocateHandleBuffer() and gBS->HandleProtocol(). **/ EFI_STATUS CreateExtraRootBusMap ( OUT EXTRA_ROOT_BUS_MAP **ExtraRootBusMap ) { EFI_STATUS Status; UINTN NumHandles; EFI_HANDLE *Handles; ORDERED_COLLECTION *Collection; EXTRA_ROOT_BUS_MAP *Map; UINTN Idx; ORDERED_COLLECTION_ENTRY *Entry, *Entry2; // // Handles and Collection are temporary / helper variables, while in Map we // build the return value. // Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPciRootBridgeIoProtocolGuid, NULL /* SearchKey */, &NumHandles, &Handles); if (EFI_ERROR (Status)) { return Status; } Collection = OrderedCollectionInit (RootBridgePathCompare, RootBridgePathKeyCompare); if (Collection == NULL) { Status = EFI_OUT_OF_RESOURCES; goto FreeHandles; } Map = AllocateZeroPool (sizeof *Map); if (Map == NULL) { Status = EFI_OUT_OF_RESOURCES; goto FreeCollection; } // // Collect the ACPI device path protocols of the root bridges. // for (Idx = 0; Idx < NumHandles; ++Idx) { EFI_DEVICE_PATH_PROTOCOL *DevicePath; Status = gBS->HandleProtocol (Handles[Idx], &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath); if (EFI_ERROR (Status)) { goto FreeMap; } // // Examine if the device path is an ACPI HID one, and if so, if UID is // nonzero (ie. the root bridge that the bus number belongs to is "extra", // not the main one). In that case, link the device path into Collection. // if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH && DevicePathSubType (DevicePath) == ACPI_DP && ((ACPI_HID_DEVICE_PATH *)DevicePath)->HID == EISA_PNP_ID(0x0A03) && ((ACPI_HID_DEVICE_PATH *)DevicePath)->UID > 0) { Status = OrderedCollectionInsert (Collection, NULL, DevicePath); if (EFI_ERROR (Status)) { goto FreeMap; } ++Map->Count; } } if (Map->Count > 0) { // // At least one extra PCI root bus exists. // Map->BusNumbers = AllocatePool (Map->Count * sizeof *Map->BusNumbers); if (Map->BusNumbers == NULL) { Status = EFI_OUT_OF_RESOURCES; goto FreeMap; } } // // Now collect the bus numbers of the extra PCI root buses into Map. // Idx = 0; Entry = OrderedCollectionMin (Collection); while (Idx < Map->Count) { ACPI_HID_DEVICE_PATH *Acpi; ASSERT (Entry != NULL); Acpi = OrderedCollectionUserStruct (Entry); Map->BusNumbers[Idx] = Acpi->UID; DEBUG ((EFI_D_VERBOSE, "%a: extra bus position 0x%Lx maps to bus number (UID) 0x%x\n", __FUNCTION__, (UINT64)(Idx + 1), Acpi->UID)); ++Idx; Entry = OrderedCollectionNext (Entry); } ASSERT (Entry == NULL); *ExtraRootBusMap = Map; Status = EFI_SUCCESS; // // Fall through in order to release temporaries. // FreeMap: if (EFI_ERROR (Status)) { if (Map->BusNumbers != NULL) { FreePool (Map->BusNumbers); } FreePool (Map); } FreeCollection: for (Entry = OrderedCollectionMin (Collection); Entry != NULL; Entry = Entry2) { Entry2 = OrderedCollectionNext (Entry); OrderedCollectionDelete (Collection, Entry, NULL); } OrderedCollectionUninit (Collection); FreeHandles: FreePool (Handles); return Status; }