Home | History | Annotate | Download | only in LegacyBiosDxe
      1 /** @file
      2   Collect Sio information from Native EFI Drivers.
      3   Sio is floppy, parallel, serial, ... hardware
      4 
      5 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
      6 
      7 This program and the accompanying materials
      8 are licensed and made available under the terms and conditions
      9 of the BSD License which accompanies this distribution.  The
     10 full text of the license may be found at
     11 http://opensource.org/licenses/bsd-license.php
     12 
     13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     15 
     16 **/
     17 
     18 #include "LegacyBiosInterface.h"
     19 
     20 
     21 /**
     22   Collect EFI Info about legacy devices.
     23 
     24   @param  Private      Legacy BIOS Instance data
     25 
     26   @retval EFI_SUCCESS  It should always work.
     27 
     28 **/
     29 EFI_STATUS
     30 LegacyBiosBuildSioData (
     31   IN  LEGACY_BIOS_INSTANCE      *Private
     32   )
     33 {
     34   EFI_STATUS                          Status;
     35   DEVICE_PRODUCER_DATA_HEADER         *SioPtr;
     36   DEVICE_PRODUCER_SERIAL              *Sio1Ptr;
     37   DEVICE_PRODUCER_PARALLEL            *Sio2Ptr;
     38   DEVICE_PRODUCER_FLOPPY              *Sio3Ptr;
     39   EFI_HANDLE                          IsaBusController;
     40   UINTN                               HandleCount;
     41   EFI_HANDLE                          *HandleBuffer;
     42   UINTN                               Index;
     43   UINTN                               ResourceIndex;
     44   UINTN                               ChildIndex;
     45   EFI_ISA_IO_PROTOCOL                 *IsaIo;
     46   EFI_ISA_ACPI_RESOURCE_LIST          *ResourceList;
     47   EFI_ISA_ACPI_RESOURCE               *IoResource;
     48   EFI_ISA_ACPI_RESOURCE               *DmaResource;
     49   EFI_ISA_ACPI_RESOURCE               *InterruptResource;
     50   UINTN                               EntryCount;
     51   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
     52   EFI_BLOCK_IO_PROTOCOL               *BlockIo;
     53 
     54   //
     55   // Get the pointer to the SIO data structure
     56   //
     57   SioPtr = &Private->IntThunk->EfiToLegacy16BootTable.SioData;
     58 
     59   //
     60   // Zero the data in the SIO data structure
     61   //
     62   gBS->SetMem (SioPtr, sizeof (DEVICE_PRODUCER_DATA_HEADER), 0);
     63 
     64   //
     65   // Find the ISA Bus Controller used for legacy
     66   //
     67   Status = Private->LegacyBiosPlatform->GetPlatformHandle (
     68                                           Private->LegacyBiosPlatform,
     69                                           EfiGetPlatformIsaBusHandle,
     70                                           0,
     71                                           &HandleBuffer,
     72                                           &HandleCount,
     73                                           NULL
     74                                           );
     75   IsaBusController = HandleBuffer[0];
     76   if (!EFI_ERROR (Status)) {
     77     //
     78     // Force ISA Bus Controller to produce all ISA devices
     79     //
     80     gBS->ConnectController (IsaBusController, NULL, NULL, TRUE);
     81   }
     82   //
     83   // Get the list of ISA controllers in the system
     84   //
     85   Status = gBS->LocateHandleBuffer (
     86                   ByProtocol,
     87                   &gEfiIsaIoProtocolGuid,
     88                   NULL,
     89                   &HandleCount,
     90                   &HandleBuffer
     91                   );
     92   if (EFI_ERROR (Status)) {
     93     return EFI_SUCCESS;
     94   }
     95   //
     96   // Collect legacy information from each of the ISA controllers in the system
     97   //
     98   for (Index = 0; Index < HandleCount; Index++) {
     99 
    100     Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo);
    101     if (EFI_ERROR (Status)) {
    102       continue;
    103     }
    104 
    105     ResourceList = IsaIo->ResourceList;
    106 
    107     if (ResourceList == NULL) {
    108       continue;
    109     }
    110     //
    111     // Collect the resource types neededto fill in the SIO data structure
    112     //
    113     IoResource        = NULL;
    114     DmaResource       = NULL;
    115     InterruptResource = NULL;
    116     for (ResourceIndex = 0;
    117          ResourceList->ResourceItem[ResourceIndex].Type != EfiIsaAcpiResourceEndOfList;
    118          ResourceIndex++
    119         ) {
    120       switch (ResourceList->ResourceItem[ResourceIndex].Type) {
    121       case EfiIsaAcpiResourceIo:
    122         IoResource = &ResourceList->ResourceItem[ResourceIndex];
    123         break;
    124 
    125       case EfiIsaAcpiResourceMemory:
    126         break;
    127 
    128       case EfiIsaAcpiResourceDma:
    129         DmaResource = &ResourceList->ResourceItem[ResourceIndex];
    130         break;
    131 
    132       case EfiIsaAcpiResourceInterrupt:
    133         InterruptResource = &ResourceList->ResourceItem[ResourceIndex];
    134         break;
    135 
    136       default:
    137         break;
    138       }
    139     }
    140     //
    141     // See if this is an ISA serial port
    142     //
    143     // Ignore DMA resource since it is always returned NULL
    144     //
    145     if (ResourceList->Device.HID == EISA_PNP_ID (0x500) || ResourceList->Device.HID == EISA_PNP_ID (0x501)) {
    146 
    147       if (ResourceList->Device.UID <= 3 &&
    148           IoResource != NULL &&
    149           InterruptResource != NULL
    150           ) {
    151         //
    152         // Get the handle of the child device that has opened the ISA I/O Protocol
    153         //
    154         Status = gBS->OpenProtocolInformation (
    155                         HandleBuffer[Index],
    156                         &gEfiIsaIoProtocolGuid,
    157                         &OpenInfoBuffer,
    158                         &EntryCount
    159                         );
    160         if (EFI_ERROR (Status)) {
    161           continue;
    162         }
    163         //
    164         // We want resource for legacy even if no 32-bit driver installed
    165         //
    166         for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) {
    167           Sio1Ptr           = &SioPtr->Serial[ResourceList->Device.UID];
    168           Sio1Ptr->Address  = (UINT16) IoResource->StartRange;
    169           Sio1Ptr->Irq      = (UINT8) InterruptResource->StartRange;
    170           Sio1Ptr->Mode     = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF;
    171         }
    172 
    173         FreePool (OpenInfoBuffer);
    174       }
    175     }
    176     //
    177     // See if this is an ISA parallel port
    178     //
    179     // Ignore DMA resource since it is always returned NULL, port
    180     // only used in output mode.
    181     //
    182     if (ResourceList->Device.HID == EISA_PNP_ID (0x400) || ResourceList->Device.HID == EISA_PNP_ID (0x401)) {
    183       if (ResourceList->Device.UID <= 2 &&
    184           IoResource != NULL &&
    185           InterruptResource != NULL &&
    186           DmaResource != NULL
    187           ) {
    188         Sio2Ptr           = &SioPtr->Parallel[ResourceList->Device.UID];
    189         Sio2Ptr->Address  = (UINT16) IoResource->StartRange;
    190         Sio2Ptr->Irq      = (UINT8) InterruptResource->StartRange;
    191         Sio2Ptr->Dma      = (UINT8) DmaResource->StartRange;
    192         Sio2Ptr->Mode     = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;
    193       }
    194     }
    195     //
    196     // See if this is an ISA floppy controller
    197     //
    198     if (ResourceList->Device.HID == EISA_PNP_ID (0x604)) {
    199       if (IoResource != NULL && InterruptResource != NULL && DmaResource != NULL) {
    200         Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
    201         if (!EFI_ERROR (Status)) {
    202           Sio3Ptr           = &SioPtr->Floppy;
    203           Sio3Ptr->Address  = (UINT16) IoResource->StartRange;
    204           Sio3Ptr->Irq      = (UINT8) InterruptResource->StartRange;
    205           Sio3Ptr->Dma      = (UINT8) DmaResource->StartRange;
    206           Sio3Ptr->NumberOfFloppy++;
    207         }
    208       }
    209     }
    210     //
    211     // See if this is a mouse
    212     // Always set mouse found so USB hot plug will work
    213     //
    214     // Ignore lower byte of HID. Pnp0fxx is any type of mouse.
    215     //
    216     //    Hid = ResourceList->Device.HID & 0xff00ffff;
    217     //    PnpId = EISA_PNP_ID(0x0f00);
    218     //    if (Hid == PnpId) {
    219     //      if (ResourceList->Device.UID == 1) {
    220     //        Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer);
    221     //      if (!EFI_ERROR (Status)) {
    222     //
    223     SioPtr->MousePresent = 0x01;
    224     //
    225     //        }
    226     //      }
    227     //    }
    228     //
    229   }
    230 
    231   FreePool (HandleBuffer);
    232 
    233   return EFI_SUCCESS;
    234 }
    235