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
LegacyBiosBuildSioData(IN LEGACY_BIOS_INSTANCE * Private)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