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