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