]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacySio.c
IntelFrameworkModulePkg/LegacyBios: Get COM base from SerialIo parent
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / LegacyBiosDxe / LegacySio.c
1 /** @file
2 Collect Sio information from Native EFI Drivers.
3 Sio is floppy, parallel, serial, ... hardware
4
5 Copyright (c) 2006 - 2016, 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 through ISA IO interface.
23
24 @param SioPtr Pointer to SIO data.
25
26 @retval EFI_SUCCESS When SIO data is got successfully.
27 @retval EFI_NOT_FOUND When ISA IO interface is absent.
28
29 **/
30 EFI_STATUS
31 LegacyBiosBuildSioDataFromIsaIo (
32 IN DEVICE_PRODUCER_DATA_HEADER *SioPtr
33 )
34 {
35 EFI_STATUS Status;
36 DEVICE_PRODUCER_SERIAL *SioSerial;
37 DEVICE_PRODUCER_PARALLEL *SioParallel;
38 DEVICE_PRODUCER_FLOPPY *SioFloppy;
39 UINTN HandleCount;
40 EFI_HANDLE *HandleBuffer;
41 UINTN Index;
42 UINTN ResourceIndex;
43 UINTN ChildIndex;
44 EFI_ISA_IO_PROTOCOL *IsaIo;
45 EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
46 EFI_ISA_ACPI_RESOURCE *IoResource;
47 EFI_ISA_ACPI_RESOURCE *DmaResource;
48 EFI_ISA_ACPI_RESOURCE *InterruptResource;
49 UINTN EntryCount;
50 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
51 EFI_BLOCK_IO_PROTOCOL *BlockIo;
52 EFI_SERIAL_IO_PROTOCOL *SerialIo;
53
54 //
55 // Get the list of ISA controllers in the system
56 //
57 Status = gBS->LocateHandleBuffer (
58 ByProtocol,
59 &gEfiIsaIoProtocolGuid,
60 NULL,
61 &HandleCount,
62 &HandleBuffer
63 );
64 if (EFI_ERROR (Status)) {
65 return EFI_NOT_FOUND;
66 }
67 //
68 // Collect legacy information from each of the ISA controllers in the system
69 //
70 for (Index = 0; Index < HandleCount; Index++) {
71
72 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo);
73 if (EFI_ERROR (Status)) {
74 continue;
75 }
76
77 ResourceList = IsaIo->ResourceList;
78
79 if (ResourceList == NULL) {
80 continue;
81 }
82 //
83 // Collect the resource types neededto fill in the SIO data structure
84 //
85 IoResource = NULL;
86 DmaResource = NULL;
87 InterruptResource = NULL;
88 for (ResourceIndex = 0;
89 ResourceList->ResourceItem[ResourceIndex].Type != EfiIsaAcpiResourceEndOfList;
90 ResourceIndex++
91 ) {
92 switch (ResourceList->ResourceItem[ResourceIndex].Type) {
93 case EfiIsaAcpiResourceIo:
94 IoResource = &ResourceList->ResourceItem[ResourceIndex];
95 break;
96
97 case EfiIsaAcpiResourceMemory:
98 break;
99
100 case EfiIsaAcpiResourceDma:
101 DmaResource = &ResourceList->ResourceItem[ResourceIndex];
102 break;
103
104 case EfiIsaAcpiResourceInterrupt:
105 InterruptResource = &ResourceList->ResourceItem[ResourceIndex];
106 break;
107
108 default:
109 break;
110 }
111 }
112 //
113 // See if this is an ISA serial port
114 //
115 // Ignore DMA resource since it is always returned NULL
116 //
117 if (ResourceList->Device.HID == EISA_PNP_ID (0x500) || ResourceList->Device.HID == EISA_PNP_ID (0x501)) {
118
119 if (ResourceList->Device.UID <= 3 &&
120 IoResource != NULL &&
121 InterruptResource != NULL
122 ) {
123 //
124 // Get the handle of the child device that has opened the ISA I/O Protocol
125 //
126 Status = gBS->OpenProtocolInformation (
127 HandleBuffer[Index],
128 &gEfiIsaIoProtocolGuid,
129 &OpenInfoBuffer,
130 &EntryCount
131 );
132 if (EFI_ERROR (Status)) {
133 continue;
134 }
135 //
136 // We want resource for legacy even if no 32-bit driver installed
137 //
138 for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) {
139 if ((OpenInfoBuffer[ChildIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
140 Status = gBS->HandleProtocol (OpenInfoBuffer[ChildIndex].AgentHandle, &gEfiSerialIoProtocolGuid, (VOID **) &SerialIo);
141 if (!EFI_ERROR (Status)) {
142 SioSerial = &SioPtr->Serial[ResourceList->Device.UID];
143 SioSerial->Address = (UINT16) IoResource->StartRange;
144 SioSerial->Irq = (UINT8) InterruptResource->StartRange;
145 SioSerial->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF;
146 break;
147 }
148 }
149 }
150
151 FreePool (OpenInfoBuffer);
152 }
153 }
154 //
155 // See if this is an ISA parallel port
156 //
157 // Ignore DMA resource since it is always returned NULL, port
158 // only used in output mode.
159 //
160 if (ResourceList->Device.HID == EISA_PNP_ID (0x400) || ResourceList->Device.HID == EISA_PNP_ID (0x401)) {
161 if (ResourceList->Device.UID <= 2 &&
162 IoResource != NULL &&
163 InterruptResource != NULL &&
164 DmaResource != NULL
165 ) {
166 SioParallel = &SioPtr->Parallel[ResourceList->Device.UID];
167 SioParallel->Address = (UINT16) IoResource->StartRange;
168 SioParallel->Irq = (UINT8) InterruptResource->StartRange;
169 SioParallel->Dma = (UINT8) DmaResource->StartRange;
170 SioParallel->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;
171 }
172 }
173 //
174 // See if this is an ISA floppy controller
175 //
176 if (ResourceList->Device.HID == EISA_PNP_ID (0x604)) {
177 if (IoResource != NULL && InterruptResource != NULL && DmaResource != NULL) {
178 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
179 if (!EFI_ERROR (Status)) {
180 SioFloppy = &SioPtr->Floppy;
181 SioFloppy->Address = (UINT16) IoResource->StartRange;
182 SioFloppy->Irq = (UINT8) InterruptResource->StartRange;
183 SioFloppy->Dma = (UINT8) DmaResource->StartRange;
184 SioFloppy->NumberOfFloppy++;
185 }
186 }
187 }
188 //
189 // See if this is a mouse
190 // Always set mouse found so USB hot plug will work
191 //
192 // Ignore lower byte of HID. Pnp0fxx is any type of mouse.
193 //
194 // Hid = ResourceList->Device.HID & 0xff00ffff;
195 // PnpId = EISA_PNP_ID(0x0f00);
196 // if (Hid == PnpId) {
197 // if (ResourceList->Device.UID == 1) {
198 // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer);
199 // if (!EFI_ERROR (Status)) {
200 //
201 SioPtr->MousePresent = 0x01;
202 //
203 // }
204 // }
205 // }
206 //
207 }
208
209 FreePool (HandleBuffer);
210 return EFI_SUCCESS;
211 }
212
213 /**
214 Collect EFI Info about legacy devices.
215
216 @param Private Legacy BIOS Instance data
217
218 @retval EFI_SUCCESS It should always work.
219
220 **/
221 EFI_STATUS
222 LegacyBiosBuildSioData (
223 IN LEGACY_BIOS_INSTANCE *Private
224 )
225 {
226 EFI_STATUS Status;
227 DEVICE_PRODUCER_DATA_HEADER *SioPtr;
228 EFI_HANDLE IsaBusController;
229 UINTN HandleCount;
230 EFI_HANDLE *HandleBuffer;
231
232 //
233 // Get the pointer to the SIO data structure
234 //
235 SioPtr = &Private->IntThunk->EfiToLegacy16BootTable.SioData;
236
237 //
238 // Zero the data in the SIO data structure
239 //
240 gBS->SetMem (SioPtr, sizeof (DEVICE_PRODUCER_DATA_HEADER), 0);
241
242 //
243 // Find the ISA Bus Controller used for legacy
244 //
245 Status = Private->LegacyBiosPlatform->GetPlatformHandle (
246 Private->LegacyBiosPlatform,
247 EfiGetPlatformIsaBusHandle,
248 0,
249 &HandleBuffer,
250 &HandleCount,
251 NULL
252 );
253 IsaBusController = HandleBuffer[0];
254 if (!EFI_ERROR (Status)) {
255 //
256 // Force ISA Bus Controller to produce all ISA devices
257 //
258 gBS->ConnectController (IsaBusController, NULL, NULL, TRUE);
259 }
260
261 LegacyBiosBuildSioDataFromIsaIo (SioPtr);
262
263 return EFI_SUCCESS;
264 }