]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.c
ArmPlatformPkg: PCI emulation - Define a vendor and device id
[mirror_edk2.git] / ArmPlatformPkg / ArmJunoPkg / Drivers / ArmJunoDxe / PciEmulation.c
CommitLineData
9f38945f
OM
1/** @file\r
2\r
3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
4 Copyright (c) 2013 - 2014, ARM Ltd. All rights reserved.<BR>\r
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "PciEmulation.h"\r
17\r
18#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44\r
19\r
20typedef struct {\r
21 ACPI_HID_DEVICE_PATH AcpiDevicePath;\r
22 PCI_DEVICE_PATH PciDevicePath;\r
23 EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
24} EFI_PCI_IO_DEVICE_PATH;\r
25\r
26typedef struct {\r
27 UINT32 Signature;\r
28 EFI_PCI_IO_DEVICE_PATH DevicePath;\r
29 EFI_PCI_IO_PROTOCOL PciIoProtocol;\r
30 PCI_TYPE00 *ConfigSpace;\r
31 PCI_ROOT_BRIDGE RootBridge;\r
32 UINTN Segment;\r
33} EFI_PCI_IO_PRIVATE_DATA;\r
34\r
35#define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o')\r
36#define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, EFI_PCI_IO_PRIVATE_DATA, PciIoProtocol, EFI_PCI_IO_PRIVATE_DATA_SIGNATURE)\r
37\r
38EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate =\r
39{\r
40 {\r
41 { ACPI_DEVICE_PATH, ACPI_DP, { sizeof (ACPI_HID_DEVICE_PATH), 0 } },\r
42 EISA_PNP_ID(0x0A03), // HID\r
43 0 // UID\r
44 },\r
45 {\r
46 { HARDWARE_DEVICE_PATH, HW_PCI_DP, { sizeof (PCI_DEVICE_PATH), 0 } },\r
47 0,\r
48 0\r
49 },\r
50 { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} }\r
51};\r
52\r
53STATIC\r
54VOID\r
55ConfigureUSBHost (\r
56 VOID\r
57 )\r
58{\r
59}\r
60\r
61\r
62EFI_STATUS\r
63PciIoPollMem (\r
64 IN EFI_PCI_IO_PROTOCOL *This,\r
65 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
66 IN UINT8 BarIndex,\r
67 IN UINT64 Offset,\r
68 IN UINT64 Mask,\r
69 IN UINT64 Value,\r
70 IN UINT64 Delay,\r
71 OUT UINT64 *Result\r
72 )\r
73{\r
74 ASSERT (FALSE);\r
75 return EFI_UNSUPPORTED;\r
76}\r
77\r
78EFI_STATUS\r
79PciIoPollIo (\r
80 IN EFI_PCI_IO_PROTOCOL *This,\r
81 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
82 IN UINT8 BarIndex,\r
83 IN UINT64 Offset,\r
84 IN UINT64 Mask,\r
85 IN UINT64 Value,\r
86 IN UINT64 Delay,\r
87 OUT UINT64 *Result\r
88 )\r
89{\r
90 ASSERT (FALSE);\r
91 return EFI_UNSUPPORTED;\r
92}\r
93\r
94EFI_STATUS\r
95PciIoMemRead (\r
96 IN EFI_PCI_IO_PROTOCOL *This,\r
97 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
98 IN UINT8 BarIndex,\r
99 IN UINT64 Offset,\r
100 IN UINTN Count,\r
101 IN OUT VOID *Buffer\r
102 )\r
103{\r
104 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);\r
105\r
106 return PciRootBridgeIoMemRead (&Private->RootBridge.Io,\r
107 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
108 Private->ConfigSpace->Device.Bar[BarIndex] + Offset, //Fix me ConfigSpace\r
109 Count,\r
110 Buffer\r
111 );\r
112}\r
113\r
114EFI_STATUS\r
115PciIoMemWrite (\r
116 IN EFI_PCI_IO_PROTOCOL *This,\r
117 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
118 IN UINT8 BarIndex,\r
119 IN UINT64 Offset,\r
120 IN UINTN Count,\r
121 IN OUT VOID *Buffer\r
122 )\r
123{\r
124 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);\r
125\r
126 return PciRootBridgeIoMemWrite (&Private->RootBridge.Io,\r
127 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
128 Private->ConfigSpace->Device.Bar[BarIndex] + Offset, //Fix me ConfigSpace\r
129 Count,\r
130 Buffer\r
131 );\r
132}\r
133\r
134EFI_STATUS\r
135PciIoIoRead (\r
136 IN EFI_PCI_IO_PROTOCOL *This,\r
137 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
138 IN UINT8 BarIndex,\r
139 IN UINT64 Offset,\r
140 IN UINTN Count,\r
141 IN OUT VOID *Buffer\r
142 )\r
143{\r
144 ASSERT (FALSE);\r
145 return EFI_UNSUPPORTED;\r
146}\r
147\r
148EFI_STATUS\r
149PciIoIoWrite (\r
150 IN EFI_PCI_IO_PROTOCOL *This,\r
151 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
152 IN UINT8 BarIndex,\r
153 IN UINT64 Offset,\r
154 IN UINTN Count,\r
155 IN OUT VOID *Buffer\r
156 )\r
157{\r
158 ASSERT (FALSE);\r
159 return EFI_UNSUPPORTED;\r
160}\r
161\r
8a8641b5
RC
162/**\r
163 Enable a PCI driver to read PCI controller registers in PCI configuration space.\r
164\r
165 @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
166 @param[in] Width Signifies the width of the memory operations.\r
167 @param[in] Offset The offset within the PCI configuration space for\r
168 the PCI controller.\r
169 @param[in] Count The number of PCI configuration operations to\r
170 perform. Bytes moved is Width size * Count,\r
171 starting at Offset.\r
172\r
173 @param[in out] Buffer The destination buffer to store the results.\r
174\r
175 @retval EFI_SUCCESS The data was read from the PCI controller.\r
176 @retval EFI_INVALID_PARAMETER "Width" is invalid.\r
177 @retval EFI_INVALID_PARAMETER "Buffer" is NULL.\r
178\r
179**/\r
9f38945f
OM
180EFI_STATUS\r
181PciIoPciRead (\r
8a8641b5
RC
182 IN EFI_PCI_IO_PROTOCOL *This,\r
183 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
184 IN UINT32 Offset,\r
185 IN UINTN Count,\r
186 IN OUT VOID *Buffer\r
9f38945f
OM
187 )\r
188{\r
189 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);\r
190 EFI_STATUS Status;\r
191\r
8a8641b5
RC
192 if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {\r
193 return EFI_INVALID_PARAMETER;\r
194 }\r
195\r
196 Status = PciRootBridgeIoMemRW (\r
197 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,\r
198 Count,\r
199 TRUE,\r
200 (PTR)(UINTN)Buffer,\r
201 TRUE,\r
202 (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset) //Fix me ConfigSpace\r
203 );\r
204\r
9f38945f
OM
205 return Status;\r
206}\r
207\r
8a8641b5
RC
208/**\r
209 Enable a PCI driver to write PCI controller registers in PCI configuration space.\r
210\r
211 @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
212 @param[in] Width Signifies the width of the memory operations.\r
213 @param[in] Offset The offset within the PCI configuration space for\r
214 the PCI controller.\r
215 @param[in] Count The number of PCI configuration operations to\r
216 perform. Bytes moved is Width size * Count,\r
217 starting at Offset.\r
218\r
219 @param[in out] Buffer The source buffer to write data from.\r
220\r
221 @retval EFI_SUCCESS The data was read from the PCI controller.\r
222 @retval EFI_INVALID_PARAMETER "Width" is invalid.\r
223 @retval EFI_INVALID_PARAMETER "Buffer" is NULL.\r
224\r
225**/\r
9f38945f
OM
226EFI_STATUS\r
227PciIoPciWrite (\r
228 IN EFI_PCI_IO_PROTOCOL *This,\r
229 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
230 IN UINT32 Offset,\r
231 IN UINTN Count,\r
232 IN OUT VOID *Buffer\r
233 )\r
234{\r
235 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);\r
236\r
8a8641b5
RC
237 if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {\r
238 return EFI_INVALID_PARAMETER;\r
239 }\r
240\r
9f38945f
OM
241 return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
242 Count,\r
243 TRUE,\r
244 (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset), //Fix me ConfigSpace\r
245 TRUE,\r
246 (PTR)(UINTN)Buffer\r
247 );\r
248}\r
249\r
250EFI_STATUS\r
251PciIoCopyMem (\r
252 IN EFI_PCI_IO_PROTOCOL *This,\r
253 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
254 IN UINT8 DestBarIndex,\r
255 IN UINT64 DestOffset,\r
256 IN UINT8 SrcBarIndex,\r
257 IN UINT64 SrcOffset,\r
258 IN UINTN Count\r
259 )\r
260{\r
261 ASSERT (FALSE);\r
262 return EFI_UNSUPPORTED;\r
263}\r
264\r
265EFI_STATUS\r
266PciIoMap (\r
267 IN EFI_PCI_IO_PROTOCOL *This,\r
268 IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
269 IN VOID *HostAddress,\r
270 IN OUT UINTN *NumberOfBytes,\r
271 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
272 OUT VOID **Mapping\r
273 )\r
274{\r
275 DMA_MAP_OPERATION DmaOperation;\r
276\r
277 if (Operation == EfiPciIoOperationBusMasterRead) {\r
278 DmaOperation = MapOperationBusMasterRead;\r
279 } else if (Operation == EfiPciIoOperationBusMasterWrite) {\r
280 DmaOperation = MapOperationBusMasterWrite;\r
281 } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) {\r
282 DmaOperation = MapOperationBusMasterCommonBuffer;\r
283 } else {\r
284 return EFI_INVALID_PARAMETER;\r
285 }\r
286 return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);\r
287}\r
288\r
289EFI_STATUS\r
290PciIoUnmap (\r
291 IN EFI_PCI_IO_PROTOCOL *This,\r
292 IN VOID *Mapping\r
293 )\r
294{\r
295 return DmaUnmap (Mapping);\r
296}\r
297\r
8a8641b5
RC
298/**\r
299 Allocate pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer\r
300 mapping.\r
301\r
302 @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
303 @param[in] Type This parameter is not used and must be ignored.\r
304 @param[in] MemoryType The type of memory to allocate, EfiBootServicesData or\r
305 EfiRuntimeServicesData.\r
306 @param[in] Pages The number of pages to allocate.\r
307 @param[out] HostAddress A pointer to store the base system memory address of\r
308 the allocated range.\r
309 @param[in] Attributes The requested bit mask of attributes for the allocated\r
310 range. Only the attributes,\r
311 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE and\r
312 EFI_PCI_ATTRIBUTE_MEMORY_CACHED may be used with this\r
313 function. If any other bits are set, then EFI_UNSUPPORTED\r
314 is returned. This function ignores this bit mask.\r
315\r
316 @retval EFI_SUCCESS The requested memory pages were allocated.\r
317 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
318 @retval EFI_INVALID_PARAMETER MemoryType is invalid.\r
319 @retval EFI_UNSUPPORTED Attributes is unsupported.\r
320 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
321\r
322**/\r
9f38945f
OM
323EFI_STATUS\r
324PciIoAllocateBuffer (\r
8a8641b5
RC
325 IN EFI_PCI_IO_PROTOCOL *This,\r
326 IN EFI_ALLOCATE_TYPE Type,\r
327 IN EFI_MEMORY_TYPE MemoryType,\r
328 IN UINTN Pages,\r
329 OUT VOID **HostAddress,\r
330 IN UINT64 Attributes\r
9f38945f
OM
331 )\r
332{\r
8a8641b5
RC
333 if (Attributes &\r
334 (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
335 EFI_PCI_ATTRIBUTE_MEMORY_CACHED ))) {\r
9f38945f
OM
336 return EFI_UNSUPPORTED;\r
337 }\r
338\r
339 return DmaAllocateBuffer (MemoryType, Pages, HostAddress);\r
340}\r
341\r
342\r
343EFI_STATUS\r
344PciIoFreeBuffer (\r
345 IN EFI_PCI_IO_PROTOCOL *This,\r
346 IN UINTN Pages,\r
347 IN VOID *HostAddress\r
348 )\r
349{\r
350 return DmaFreeBuffer (Pages, HostAddress);\r
351}\r
352\r
353\r
354EFI_STATUS\r
355PciIoFlush (\r
356 IN EFI_PCI_IO_PROTOCOL *This\r
357 )\r
358{\r
359 return EFI_SUCCESS;\r
360}\r
361\r
8a8641b5
RC
362/**\r
363 Retrieves this PCI controller's current PCI bus number, device number, and function number.\r
364\r
365 @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
366 @param[out] SegmentNumber The PCI controller's current PCI segment number.\r
367 @param[out] BusNumber The PCI controller's current PCI bus number.\r
368 @param[out] DeviceNumber The PCI controller's current PCI device number.\r
369 @param[out] FunctionNumber The PCI controller’s current PCI function number.\r
370\r
371 @retval EFI_SUCCESS The PCI controller location was returned.\r
372 @retval EFI_INVALID_PARAMETER At least one out of the four output parameters is\r
373 a NULL pointer.\r
374**/\r
9f38945f
OM
375EFI_STATUS\r
376PciIoGetLocation (\r
8a8641b5
RC
377 IN EFI_PCI_IO_PROTOCOL *This,\r
378 OUT UINTN *SegmentNumber,\r
379 OUT UINTN *BusNumber,\r
380 OUT UINTN *DeviceNumber,\r
381 OUT UINTN *FunctionNumber\r
9f38945f
OM
382 )\r
383{\r
384 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);\r
385\r
8a8641b5
RC
386 if ((SegmentNumber == NULL) || (BusNumber == NULL) ||\r
387 (DeviceNumber == NULL) || (FunctionNumber == NULL) ) {\r
388 return EFI_INVALID_PARAMETER;\r
9f38945f
OM
389 }\r
390\r
8a8641b5
RC
391 *SegmentNumber = Private->Segment;\r
392 *BusNumber = 0xff;\r
393 *DeviceNumber = 0;\r
394 *FunctionNumber = 0;\r
9f38945f
OM
395\r
396 return EFI_SUCCESS;\r
397}\r
398\r
8a8641b5
RC
399/**\r
400 Performs an operation on the attributes that this PCI controller supports.\r
401\r
402 The operations include getting the set of supported attributes, retrieving\r
403 the current attributes, setting the current attributes, enabling attributes,\r
404 and disabling attributes.\r
405\r
406 @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
407 @param[in] Operation The operation to perform on the attributes for this\r
408 PCI controller.\r
409 @param[in] Attributes The mask of attributes that are used for Set,\r
410 Enable and Disable operations.\r
411 @param[out] Result A pointer to the result mask of attributes that are\r
412 returned for the Get and Supported operations. This\r
413 is an optional parameter that may be NULL for the\r
414 Set, Enable, and Disable operations.\r
415\r
416 @retval EFI_SUCCESS The operation on the PCI controller's\r
417 attributes was completed. If the operation\r
418 was Get or Supported, then the attribute mask\r
419 is returned in Result.\r
420 @retval EFI_INVALID_PARAMETER Operation is greater than or equal to\r
421 EfiPciIoAttributeOperationMaximum.\r
422 @retval EFI_INVALID_PARAMETER Operation is Get and Result is NULL.\r
423 @retval EFI_INVALID_PARAMETER Operation is Supported and Result is NULL.\r
424\r
425**/\r
9f38945f
OM
426EFI_STATUS\r
427PciIoAttributes (\r
428 IN EFI_PCI_IO_PROTOCOL *This,\r
429 IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
430 IN UINT64 Attributes,\r
431 OUT UINT64 *Result OPTIONAL\r
432 )\r
433{\r
434 switch (Operation) {\r
435 case EfiPciIoAttributeOperationGet:\r
436 case EfiPciIoAttributeOperationSupported:\r
437 if (Result == NULL) {\r
438 return EFI_INVALID_PARAMETER;\r
439 }\r
8a8641b5 440 //\r
9f38945f 441 // We are not a real PCI device so just say things we kind of do\r
8a8641b5
RC
442 //\r
443 *Result = EFI_PCI_DEVICE_ENABLE;\r
9f38945f
OM
444 break;\r
445\r
446 case EfiPciIoAttributeOperationSet:\r
447 case EfiPciIoAttributeOperationEnable:\r
448 case EfiPciIoAttributeOperationDisable:\r
8a8641b5
RC
449 if (Attributes & (~EFI_PCI_DEVICE_ENABLE)) {\r
450 return EFI_UNSUPPORTED;\r
451 }\r
9f38945f
OM
452 // Since we are not a real PCI device no enable/set or disable operations exist.\r
453 return EFI_SUCCESS;\r
454\r
455 default:\r
9f38945f
OM
456 return EFI_INVALID_PARAMETER;\r
457 };\r
458 return EFI_SUCCESS;\r
459}\r
460\r
461EFI_STATUS\r
462PciIoGetBarAttributes (\r
463 IN EFI_PCI_IO_PROTOCOL *This,\r
464 IN UINT8 BarIndex,\r
465 OUT UINT64 *Supports, OPTIONAL\r
466 OUT VOID **Resources OPTIONAL\r
467 )\r
468{\r
469 ASSERT (FALSE);\r
470 return EFI_UNSUPPORTED;\r
471}\r
472\r
473EFI_STATUS\r
474PciIoSetBarAttributes (\r
475 IN EFI_PCI_IO_PROTOCOL *This,\r
476 IN UINT64 Attributes,\r
477 IN UINT8 BarIndex,\r
478 IN OUT UINT64 *Offset,\r
479 IN OUT UINT64 *Length\r
480 )\r
481{\r
482 ASSERT (FALSE);\r
483 return EFI_UNSUPPORTED;\r
484}\r
485\r
486EFI_PCI_IO_PROTOCOL PciIoTemplate =\r
487{\r
488 PciIoPollMem,\r
489 PciIoPollIo,\r
490 { PciIoMemRead, PciIoMemWrite },\r
491 { PciIoIoRead, PciIoIoWrite },\r
492 { PciIoPciRead, PciIoPciWrite },\r
493 PciIoCopyMem,\r
494 PciIoMap,\r
495 PciIoUnmap,\r
496 PciIoAllocateBuffer,\r
497 PciIoFreeBuffer,\r
498 PciIoFlush,\r
499 PciIoGetLocation,\r
500 PciIoAttributes,\r
501 PciIoGetBarAttributes,\r
502 PciIoSetBarAttributes,\r
503 0,\r
504 0\r
505};\r
506\r
507EFI_STATUS\r
508PciInstallDevice (\r
509 IN UINTN DeviceId,\r
510 IN PHYSICAL_ADDRESS MemoryStart,\r
511 IN UINT64 MemorySize,\r
512 IN UINTN ClassCode1,\r
513 IN UINTN ClassCode2,\r
514 IN UINTN ClassCode3\r
515 )\r
516{\r
517 EFI_STATUS Status;\r
518 EFI_HANDLE Handle;\r
519 EFI_PCI_IO_PRIVATE_DATA *Private;\r
520\r
521 // Configure USB host\r
522 ConfigureUSBHost ();\r
523\r
524 // Create a private structure\r
525 Private = AllocatePool (sizeof (EFI_PCI_IO_PRIVATE_DATA));\r
526 if (Private == NULL) {\r
527 Status = EFI_OUT_OF_RESOURCES;\r
528 return Status;\r
529 }\r
530\r
531 Private->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature\r
532 Private->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too\r
533 Private->RootBridge.MemoryStart = MemoryStart; // Get the USB capability register base\r
534 Private->Segment = 0; // Default to segment zero\r
535\r
536 // Calculate the total size of the USB controller (OHCI + EHCI).\r
537 Private->RootBridge.MemorySize = MemorySize; //CapabilityLength + (HOST_CONTROLLER_OPERATION_REG_SIZE + ((4 * PhysicalPorts) - 1));\r
538\r
539 // Create fake PCI config space: OHCI + EHCI\r
540 Private->ConfigSpace = AllocateZeroPool (sizeof (PCI_TYPE00));\r
541 if (Private->ConfigSpace == NULL) {\r
542 Status = EFI_OUT_OF_RESOURCES;\r
543 FreePool (Private);\r
544 return Status;\r
545 }\r
546\r
547 //\r
548 // Configure PCI config space: OHCI + EHCI\r
549 //\r
6e8b37f1
RC
550 Private->ConfigSpace->Hdr.VendorId = 0xFFFF; // Invalid vendor Id as it is not an actual device.\r
551 Private->ConfigSpace->Hdr.DeviceId = 0x0000; // Not relevant as the vendor id is not valid.\r
9f38945f
OM
552 Private->ConfigSpace->Hdr.ClassCode[0] = ClassCode1;\r
553 Private->ConfigSpace->Hdr.ClassCode[1] = ClassCode2;\r
554 Private->ConfigSpace->Hdr.ClassCode[2] = ClassCode3;\r
555 Private->ConfigSpace->Device.Bar[0] = MemoryStart;\r
556\r
557 Handle = NULL;\r
558\r
559 // Unique device path.\r
560 CopyMem (&Private->DevicePath, &PciIoDevicePathTemplate, sizeof (PciIoDevicePathTemplate));\r
561 Private->DevicePath.AcpiDevicePath.UID = 0;\r
562 Private->DevicePath.PciDevicePath.Device = DeviceId;\r
563\r
564 // Copy protocol structure\r
565 CopyMem (&Private->PciIoProtocol, &PciIoTemplate, sizeof (PciIoTemplate));\r
566\r
567 Status = gBS->InstallMultipleProtocolInterfaces (&Handle,\r
568 &gEfiPciIoProtocolGuid, &Private->PciIoProtocol,\r
569 &gEfiDevicePathProtocolGuid, &Private->DevicePath,\r
570 NULL);\r
571 if (EFI_ERROR (Status)) {\r
572 DEBUG ((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces () failed.\n"));\r
573 }\r
574\r
575 return Status;\r
576}\r
577\r
578EFI_STATUS\r
579PciEmulationEntryPoint (\r
580 VOID\r
581 )\r
582{\r
583 EFI_STATUS Status;\r
584\r
585 Status = PciInstallDevice (0, FixedPcdGet32 (PcdSynopsysUsbOhciBaseAddress), SIZE_64KB, PCI_IF_OHCI, PCI_CLASS_SERIAL_USB, PCI_CLASS_SERIAL);\r
586 if (EFI_ERROR (Status)) {\r
587 DEBUG ((EFI_D_ERROR, "PciEmulation: failed to install OHCI device.\n"));\r
588 }\r
589\r
590 Status = PciInstallDevice (1, FixedPcdGet32 (PcdSynopsysUsbEhciBaseAddress), SIZE_64KB, PCI_IF_EHCI, PCI_CLASS_SERIAL_USB, PCI_CLASS_SERIAL);\r
591 if (EFI_ERROR (Status)) {\r
592 DEBUG ((EFI_D_ERROR, "PciEmulation: failed to install EHCI device.\n"));\r
593 }\r
594\r
595 return Status;\r
596}\r