1/** @file 2 Collect Sio information from Native EFI Drivers. 3 Sio is floppy, parallel, serial, ... hardware 4 5Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> 6 7This program and the accompanying materials 8are licensed and made available under the terms and conditions 9of the BSD License which accompanies this distribution. The 10full text of the license may be found at 11http://opensource.org/licenses/bsd-license.php 12 13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 14WITHOUT 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**/ 29EFI_STATUS 30LegacyBiosBuildSioData ( 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