]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacySio.c
MdeModulePkg DxeS3BootScriptLib: Check (mSmst != NULL) before freeing SMRAM
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / LegacyBiosDxe / LegacySio.c
CommitLineData
bcecde14 1/** @file\r
2 Collect Sio information from Native EFI Drivers.\r
3 Sio is floppy, parallel, serial, ... hardware\r
4\r
5Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
6\r
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions\r
9of the BSD License which accompanies this distribution. The\r
10full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12\r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include "LegacyBiosInterface.h"\r
19\r
20\r
21/**\r
22 Collect EFI Info about legacy devices.\r
23\r
24 @param Private Legacy BIOS Instance data\r
25\r
26 @retval EFI_SUCCESS It should always work.\r
27\r
28**/\r
29EFI_STATUS\r
30LegacyBiosBuildSioData (\r
31 IN LEGACY_BIOS_INSTANCE *Private\r
32 )\r
33{\r
34 EFI_STATUS Status;\r
35 DEVICE_PRODUCER_DATA_HEADER *SioPtr;\r
36 DEVICE_PRODUCER_SERIAL *Sio1Ptr;\r
37 DEVICE_PRODUCER_PARALLEL *Sio2Ptr;\r
38 DEVICE_PRODUCER_FLOPPY *Sio3Ptr;\r
39 EFI_HANDLE IsaBusController;\r
40 UINTN HandleCount;\r
41 EFI_HANDLE *HandleBuffer;\r
42 UINTN Index;\r
43 UINTN ResourceIndex;\r
44 UINTN ChildIndex;\r
45 EFI_ISA_IO_PROTOCOL *IsaIo;\r
46 EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;\r
47 EFI_ISA_ACPI_RESOURCE *IoResource;\r
48 EFI_ISA_ACPI_RESOURCE *DmaResource;\r
49 EFI_ISA_ACPI_RESOURCE *InterruptResource;\r
50 UINTN EntryCount;\r
51 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
52 EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
53\r
54 //\r
55 // Get the pointer to the SIO data structure\r
56 //\r
57 SioPtr = &Private->IntThunk->EfiToLegacy16BootTable.SioData;\r
58\r
59 //\r
60 // Zero the data in the SIO data structure\r
61 //\r
62 gBS->SetMem (SioPtr, sizeof (DEVICE_PRODUCER_DATA_HEADER), 0);\r
63\r
64 //\r
65 // Find the ISA Bus Controller used for legacy\r
66 //\r
67 Status = Private->LegacyBiosPlatform->GetPlatformHandle (\r
68 Private->LegacyBiosPlatform,\r
69 EfiGetPlatformIsaBusHandle,\r
70 0,\r
71 &HandleBuffer,\r
72 &HandleCount,\r
73 NULL\r
74 );\r
75 IsaBusController = HandleBuffer[0];\r
76 if (!EFI_ERROR (Status)) {\r
77 //\r
78 // Force ISA Bus Controller to produce all ISA devices\r
79 //\r
80 gBS->ConnectController (IsaBusController, NULL, NULL, TRUE);\r
81 }\r
82 //\r
83 // Get the list of ISA controllers in the system\r
84 //\r
85 Status = gBS->LocateHandleBuffer (\r
86 ByProtocol,\r
87 &gEfiIsaIoProtocolGuid,\r
88 NULL,\r
89 &HandleCount,\r
90 &HandleBuffer\r
91 );\r
92 if (EFI_ERROR (Status)) {\r
93 return EFI_SUCCESS;\r
94 }\r
95 //\r
96 // Collect legacy information from each of the ISA controllers in the system\r
97 //\r
98 for (Index = 0; Index < HandleCount; Index++) {\r
99\r
100 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo);\r
101 if (EFI_ERROR (Status)) {\r
102 continue;\r
103 }\r
104\r
105 ResourceList = IsaIo->ResourceList;\r
106\r
107 if (ResourceList == NULL) {\r
108 continue;\r
109 }\r
110 //\r
111 // Collect the resource types neededto fill in the SIO data structure\r
112 //\r
113 IoResource = NULL;\r
114 DmaResource = NULL;\r
115 InterruptResource = NULL;\r
116 for (ResourceIndex = 0;\r
117 ResourceList->ResourceItem[ResourceIndex].Type != EfiIsaAcpiResourceEndOfList;\r
118 ResourceIndex++\r
119 ) {\r
120 switch (ResourceList->ResourceItem[ResourceIndex].Type) {\r
121 case EfiIsaAcpiResourceIo:\r
122 IoResource = &ResourceList->ResourceItem[ResourceIndex];\r
123 break;\r
124\r
125 case EfiIsaAcpiResourceMemory:\r
126 break;\r
127\r
128 case EfiIsaAcpiResourceDma:\r
129 DmaResource = &ResourceList->ResourceItem[ResourceIndex];\r
130 break;\r
131\r
132 case EfiIsaAcpiResourceInterrupt:\r
133 InterruptResource = &ResourceList->ResourceItem[ResourceIndex];\r
134 break;\r
135\r
136 default:\r
137 break;\r
138 }\r
139 }\r
140 //\r
141 // See if this is an ISA serial port\r
142 //\r
143 // Ignore DMA resource since it is always returned NULL\r
144 //\r
145 if (ResourceList->Device.HID == EISA_PNP_ID (0x500) || ResourceList->Device.HID == EISA_PNP_ID (0x501)) {\r
146\r
147 if (ResourceList->Device.UID <= 3 &&\r
148 IoResource != NULL &&\r
149 InterruptResource != NULL\r
150 ) {\r
151 //\r
152 // Get the handle of the child device that has opened the ISA I/O Protocol\r
153 //\r
154 Status = gBS->OpenProtocolInformation (\r
155 HandleBuffer[Index],\r
156 &gEfiIsaIoProtocolGuid,\r
157 &OpenInfoBuffer,\r
158 &EntryCount\r
159 );\r
160 if (EFI_ERROR (Status)) {\r
161 continue;\r
162 }\r
163 //\r
164 // We want resource for legacy even if no 32-bit driver installed\r
165 //\r
166 for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) {\r
167 Sio1Ptr = &SioPtr->Serial[ResourceList->Device.UID];\r
168 Sio1Ptr->Address = (UINT16) IoResource->StartRange;\r
169 Sio1Ptr->Irq = (UINT8) InterruptResource->StartRange;\r
170 Sio1Ptr->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF;\r
171 }\r
172\r
173 FreePool (OpenInfoBuffer);\r
174 }\r
175 }\r
176 //\r
177 // See if this is an ISA parallel port\r
178 //\r
179 // Ignore DMA resource since it is always returned NULL, port\r
180 // only used in output mode.\r
181 //\r
182 if (ResourceList->Device.HID == EISA_PNP_ID (0x400) || ResourceList->Device.HID == EISA_PNP_ID (0x401)) {\r
183 if (ResourceList->Device.UID <= 2 &&\r
184 IoResource != NULL &&\r
185 InterruptResource != NULL &&\r
186 DmaResource != NULL\r
187 ) {\r
188 Sio2Ptr = &SioPtr->Parallel[ResourceList->Device.UID];\r
189 Sio2Ptr->Address = (UINT16) IoResource->StartRange;\r
190 Sio2Ptr->Irq = (UINT8) InterruptResource->StartRange;\r
191 Sio2Ptr->Dma = (UINT8) DmaResource->StartRange;\r
192 Sio2Ptr->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;\r
193 }\r
194 }\r
195 //\r
196 // See if this is an ISA floppy controller\r
197 //\r
198 if (ResourceList->Device.HID == EISA_PNP_ID (0x604)) {\r
199 if (IoResource != NULL && InterruptResource != NULL && DmaResource != NULL) {\r
200 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);\r
201 if (!EFI_ERROR (Status)) {\r
202 Sio3Ptr = &SioPtr->Floppy;\r
203 Sio3Ptr->Address = (UINT16) IoResource->StartRange;\r
204 Sio3Ptr->Irq = (UINT8) InterruptResource->StartRange;\r
205 Sio3Ptr->Dma = (UINT8) DmaResource->StartRange;\r
206 Sio3Ptr->NumberOfFloppy++;\r
207 }\r
208 }\r
209 }\r
210 //\r
211 // See if this is a mouse\r
212 // Always set mouse found so USB hot plug will work\r
213 //\r
214 // Ignore lower byte of HID. Pnp0fxx is any type of mouse.\r
215 //\r
216 // Hid = ResourceList->Device.HID & 0xff00ffff;\r
217 // PnpId = EISA_PNP_ID(0x0f00);\r
218 // if (Hid == PnpId) {\r
219 // if (ResourceList->Device.UID == 1) {\r
220 // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer);\r
221 // if (!EFI_ERROR (Status)) {\r
222 //\r
223 SioPtr->MousePresent = 0x01;\r
224 //\r
225 // }\r
226 // }\r
227 // }\r
228 //\r
229 }\r
230\r
231 FreePool (HandleBuffer);\r
232\r
233 return EFI_SUCCESS;\r
234}\r