3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
16 Platform Initialization Driver.
22 #include "PlatformDxe.h"
23 #include "Library/DxeServicesTableLib.h"
25 #include "Guid/PciLanInfo.h"
27 extern VOID
*mPciLanInfo
;
28 extern UINTN mPciLanCount
;
30 extern EFI_HANDLE mImageHandle
;
31 extern SYSTEM_CONFIGURATION mSystemConfiguration
;
34 VOID
*mPciRegistration
;
35 #define NCR_VENDOR_ID 0x1000
36 #define ATI_VENDOR_ID 0x1002
37 #define INTEL_VENDOR_ID 0x8086
38 #define ATI_RV423_ID 0x5548
39 #define ATI_RV423_ID2 0x5d57
40 #define ATI_RV380_ID 0x3e50
41 #define ATI_RV370_ID 0x5b60
42 #define SI_VENDOR_ID 0x1095
43 #define SI_SISATA_ID 0x3114
44 #define SI_SIRAID_PCIUNL 0x40
45 #define INTEL_82573E_IDER 0x108D
54 BAD_DEVICE_TABLE BadDeviceTable
[] = {
55 {(UINT8
)PCI_CLASS_MASS_STORAGE
,(UINT8
)PCI_CLASS_MASS_STORAGE_SCSI
,(UINT16
)NCR_VENDOR_ID
, (UINT16
)0xffff}, // Any NCR cards
56 {(UINT8
)PCI_CLASS_MASS_STORAGE
,(UINT8
)PCI_CLASS_MASS_STORAGE_IDE
,(UINT16
)INTEL_VENDOR_ID
, (UINT16
)INTEL_82573E_IDER
}, // Intel i82573E Tekoa GBit Lan IDE-R
57 {(UINT8
)0xff,(UINT8
)0xff,(UINT16
)0xffff,(UINT16
)0xffff}
65 EFI_EVENT FilterEvent
;
68 // Register for callback to PCI I/O protocol
70 Status
= gBS
->CreateEvent (
77 ASSERT_EFI_ERROR(Status
);
80 // Register for protocol notifications on this event
82 Status
= gBS
->RegisterProtocolNotify (
83 &gEfiPciIoProtocolGuid
,
87 ASSERT_EFI_ERROR (Status
);
94 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
100 UINT64 BaseAddress
= 0;
101 UINT64 TempBaseAddress
= 0;
111 // ATI fix-ups. At this time all ATI cards in BadDeviceTable
112 // have same problem in that OPROM BAR needs to be increased.
116 // Get original BAR address
123 (VOID
*) &BaseAddress
128 TempBaseAddress
= 0xffffffff;
134 (VOID
*) &TempBaseAddress
141 (VOID
*) &TempBaseAddress
143 TempBaseAddress
&= 0xfffffffe;
145 while ((TempBaseAddress
& 0x01) == 0) {
146 TempBaseAddress
= TempBaseAddress
>> 1;
147 MemSize
= MemSize
<< 1;
151 // Free up allocated memory memory and re-allocate with increased size.
153 gDS
->FreeMemorySpace (
158 // Force new alignment
163 gDS
->AllocateMemorySpace (
164 EfiGcdAllocateAnySearchBottomUp
,
165 EfiGcdMemoryTypeMemoryMappedIo
,
166 MemSizeBits
, // Alignment
177 (VOID
*) &BaseAddress
182 #define MIN_NCR_IO_SIZE 0x800
183 #define NCR_GRAN 11 // 2**11 = 0x800
185 // NCR SCSI cards like 8250S lie about IO needed. Assign as least 0x80.
187 for (Bar
= 0x10; Bar
< 0x28; Bar
+= 4) {
194 (VOID
*) &BaseAddress
196 if (BaseAddress
&& 0x01) {
197 TempBaseAddress
= 0xffffffff;
203 (VOID
*) &TempBaseAddress
205 TempBaseAddress
&= 0xfffffffc;
207 while ((TempBaseAddress
& 0x01) == 0) {
208 TempBaseAddress
= TempBaseAddress
>> 1;
209 IoSize
= IoSize
<< 1;
211 if (IoSize
< MIN_NCR_IO_SIZE
) {
217 gDS
->AllocateIoSpace (
218 EfiGcdAllocateAnySearchTopDown
,
220 NCR_GRAN
, // Alignment
226 TempBaseAddress
= BaseAddress
+ 1;
232 (VOID
*) &TempBaseAddress
240 case INTEL_VENDOR_ID
:
241 if (DeviceId
== INTEL_82573E_IDER
) {
243 // Tekoa i82573E IDE-R fix-ups. At this time A2 step and earlier parts do not
244 // support any BARs except BAR0. Other BARS will actualy map to BAR0 so disable
245 // them all for Control Blocks and Bus mastering ops as well as Secondary IDE
247 // All Tekoa A2 or earlier step chips for now.
252 PCI_REVISION_ID_OFFSET
,
257 for (Bar
= 0x14; Bar
< 0x24; Bar
+= 4) {
259 // Maybe want to clean this up a bit later but for now just clear out the secondary
260 // Bars don't worry aboyut freeing up thge allocs.
262 TempBaseAddress
= 0x0;
268 (VOID
*) &TempBaseAddress
276 //Clear bus master base address (PCI register 0x20)
277 //since Tekoa does not fully support IDE Bus Mastering
279 TempBaseAddress
= 0x0;
285 (VOID
*) &TempBaseAddress
299 IN EFI_PCI_IO_PROTOCOL
*PciIo
303 // Program Master Latency Timer
305 if (mSystemConfiguration
.PciLatency
!= 0) {
309 PCI_LATENCY_TIMER_OFFSET
,
311 &mSystemConfiguration
.PciLatency
318 During S5 shutdown, we need to program PME in all LAN devices.
319 Here we identify LAN devices and save their bus/dev/func.
324 IN EFI_PCI_IO_PROTOCOL
*PciIo
335 Status
= PciIo
->GetLocation (
342 if (EFI_ERROR (Status
)) {
347 Status
= gBS
->AllocatePool (
349 mPciLanCount
* sizeof(PCI_LAN_INFO
),
352 if (EFI_ERROR (Status
)) {
356 if (mPciLanCount
> 1) {
358 // copy old data into new, larger buffer
363 (mPciLanCount
- 1) * sizeof(PCI_LAN_INFO
)
367 // free the old memory buffer
369 gBS
->FreePool (mPciLanInfo
);
374 // init the new entry
376 x
= (PCI_LAN_INFO
*)NewBuffer
+ (mPciLanCount
- 1);
377 x
->PciBus
= (UINT8
)PciBus
;
378 x
->PciDevice
= (UINT8
)PciDevice
;
379 x
->PciFunction
= (UINT8
)PciFunction
;
381 mPciLanInfo
= NewBuffer
;
387 @param Event the event that is signaled.
388 @param Context not used here.
403 EFI_PCI_IO_PROTOCOL
*PciIo
;
404 PCI_IO_DEVICE
*PciIoDevice
;
407 UINT8 mCacheLineSize
= 0x10;
410 BufferSize
= sizeof (EFI_HANDLE
);
411 Status
= gBS
->LocateHandle (
418 if (EFI_ERROR (Status
)) {
420 // If no more notification events exist
425 Status
= gBS
->HandleProtocol (
427 &gEfiPciIoProtocolGuid
,
431 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
434 // Enable I/O for bridge so port 0x80 codes will come out
436 if (PciIoDevice
->Pci
.Hdr
.VendorId
== V_PCH_INTEL_VENDOR_ID
)
438 Status
= PciIo
->Attributes(
440 EfiPciIoAttributeOperationSupported
,
444 Supports
&= EFI_PCI_DEVICE_ENABLE
;
445 Status
= PciIo
->Attributes (
447 EfiPciIoAttributeOperationEnable
,
455 // Program PCI Latency Timer
457 ProgramPciLatency(PciIo
);
460 // Program Cache Line Size to 64 bytes (0x10 DWORDs)
462 Status
= PciIo
->Pci
.Write (
465 PCI_CACHELINE_SIZE_OFFSET
,
471 // If PCI LAN device, save bus/dev/func info
472 // so we can program PME during S5 shutdown
474 if (PciIoDevice
->Pci
.Hdr
.ClassCode
[2] == PCI_CLASS_NETWORK
) {
475 SavePciLanAddress(PciIo
);
480 // Workaround for cards with bad BARs
483 while (BadDeviceTable
[Index
].ClassCode
!= 0xff) {
484 if (BadDeviceTable
[Index
].DeviceId
== 0xffff) {
485 if ((PciIoDevice
->Pci
.Hdr
.ClassCode
[2] == BadDeviceTable
[Index
].ClassCode
) &&
486 (PciIoDevice
->Pci
.Hdr
.ClassCode
[1] == BadDeviceTable
[Index
].SubClassCode
) &&
487 (PciIoDevice
->Pci
.Hdr
.VendorId
== BadDeviceTable
[Index
].VendorId
)) {
488 InitBadBars(PciIo
,BadDeviceTable
[Index
].VendorId
,BadDeviceTable
[Index
].DeviceId
);
491 if ((PciIoDevice
->Pci
.Hdr
.ClassCode
[2] == BadDeviceTable
[Index
].ClassCode
) &&
492 (PciIoDevice
->Pci
.Hdr
.ClassCode
[1] == BadDeviceTable
[Index
].SubClassCode
) &&
493 (PciIoDevice
->Pci
.Hdr
.VendorId
== BadDeviceTable
[Index
].VendorId
) &&
494 (PciIoDevice
->Pci
.Hdr
.DeviceId
== BadDeviceTable
[Index
].DeviceId
)) {
496 InitBadBars(PciIo
,BadDeviceTable
[Index
].VendorId
,BadDeviceTable
[Index
].DeviceId
);