]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacySio.c
IntelFrameworkModulePkg/LegacyBios: Get SIO data in separate function
[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 It should always work.
27
28 **/
29 EFI_STATUS
30 LegacyBiosBuildSioDataFromIsaIo (
31 IN DEVICE_PRODUCER_DATA_HEADER *SioPtr
32 )
33 {
34 EFI_STATUS Status;
35 DEVICE_PRODUCER_SERIAL *Sio1Ptr;
36 DEVICE_PRODUCER_PARALLEL *Sio2Ptr;
37 DEVICE_PRODUCER_FLOPPY *Sio3Ptr;
38 UINTN HandleCount;
39 EFI_HANDLE *HandleBuffer;
40 UINTN Index;
41 UINTN ResourceIndex;
42 UINTN ChildIndex;
43 EFI_ISA_IO_PROTOCOL *IsaIo;
44 EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
45 EFI_ISA_ACPI_RESOURCE *IoResource;
46 EFI_ISA_ACPI_RESOURCE *DmaResource;
47 EFI_ISA_ACPI_RESOURCE *InterruptResource;
48 UINTN EntryCount;
49 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
50 EFI_BLOCK_IO_PROTOCOL *BlockIo;
51
52
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_SUCCESS;
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 Sio1Ptr = &SioPtr->Serial[ResourceList->Device.UID];
140 Sio1Ptr->Address = (UINT16) IoResource->StartRange;
141 Sio1Ptr->Irq = (UINT8) InterruptResource->StartRange;
142 Sio1Ptr->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF;
143 }
144
145 FreePool (OpenInfoBuffer);
146 }
147 }
148 //
149 // See if this is an ISA parallel port
150 //
151 // Ignore DMA resource since it is always returned NULL, port
152 // only used in output mode.
153 //
154 if (ResourceList->Device.HID == EISA_PNP_ID (0x400) || ResourceList->Device.HID == EISA_PNP_ID (0x401)) {
155 if (ResourceList->Device.UID <= 2 &&
156 IoResource != NULL &&
157 InterruptResource != NULL &&
158 DmaResource != NULL
159 ) {
160 Sio2Ptr = &SioPtr->Parallel[ResourceList->Device.UID];
161 Sio2Ptr->Address = (UINT16) IoResource->StartRange;
162 Sio2Ptr->Irq = (UINT8) InterruptResource->StartRange;
163 Sio2Ptr->Dma = (UINT8) DmaResource->StartRange;
164 Sio2Ptr->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;
165 }
166 }
167 //
168 // See if this is an ISA floppy controller
169 //
170 if (ResourceList->Device.HID == EISA_PNP_ID (0x604)) {
171 if (IoResource != NULL && InterruptResource != NULL && DmaResource != NULL) {
172 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
173 if (!EFI_ERROR (Status)) {
174 Sio3Ptr = &SioPtr->Floppy;
175 Sio3Ptr->Address = (UINT16) IoResource->StartRange;
176 Sio3Ptr->Irq = (UINT8) InterruptResource->StartRange;
177 Sio3Ptr->Dma = (UINT8) DmaResource->StartRange;
178 Sio3Ptr->NumberOfFloppy++;
179 }
180 }
181 }
182 //
183 // See if this is a mouse
184 // Always set mouse found so USB hot plug will work
185 //
186 // Ignore lower byte of HID. Pnp0fxx is any type of mouse.
187 //
188 // Hid = ResourceList->Device.HID & 0xff00ffff;
189 // PnpId = EISA_PNP_ID(0x0f00);
190 // if (Hid == PnpId) {
191 // if (ResourceList->Device.UID == 1) {
192 // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer);
193 // if (!EFI_ERROR (Status)) {
194 //
195 SioPtr->MousePresent = 0x01;
196 //
197 // }
198 // }
199 // }
200 //
201 }
202
203 FreePool (HandleBuffer);
204 return EFI_SUCCESS;
205 }
206
207 /**
208 Collect EFI Info about legacy devices.
209
210 @param Private Legacy BIOS Instance data
211
212 @retval EFI_SUCCESS It should always work.
213
214 **/
215 EFI_STATUS
216 LegacyBiosBuildSioData (
217 IN LEGACY_BIOS_INSTANCE *Private
218 )
219 {
220 EFI_STATUS Status;
221 DEVICE_PRODUCER_DATA_HEADER *SioPtr;
222 EFI_HANDLE IsaBusController;
223 UINTN HandleCount;
224 EFI_HANDLE *HandleBuffer;
225
226 //
227 // Get the pointer to the SIO data structure
228 //
229 SioPtr = &Private->IntThunk->EfiToLegacy16BootTable.SioData;
230
231 //
232 // Zero the data in the SIO data structure
233 //
234 gBS->SetMem (SioPtr, sizeof (DEVICE_PRODUCER_DATA_HEADER), 0);
235
236 //
237 // Find the ISA Bus Controller used for legacy
238 //
239 Status = Private->LegacyBiosPlatform->GetPlatformHandle (
240 Private->LegacyBiosPlatform,
241 EfiGetPlatformIsaBusHandle,
242 0,
243 &HandleBuffer,
244 &HandleCount,
245 NULL
246 );
247 IsaBusController = HandleBuffer[0];
248 if (!EFI_ERROR (Status)) {
249 //
250 // Force ISA Bus Controller to produce all ISA devices
251 //
252 gBS->ConnectController (IsaBusController, NULL, NULL, TRUE);
253 }
254
255 LegacyBiosBuildSioDataFromIsaIo (SioPtr);
256
257 return EFI_SUCCESS;
258 }