3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 Platform Initialization Driver.
27 #include "PlatformDxe.h"
28 #include "Library/DxeServicesTableLib.h"
30 #include "Guid/PciLanInfo.h"
32 extern VOID
*mPciLanInfo
;
33 extern UINTN mPciLanCount
;
35 extern EFI_HANDLE mImageHandle
;
36 extern SYSTEM_CONFIGURATION mSystemConfiguration
;
39 VOID
*mPciRegistration
;
40 #define NCR_VENDOR_ID 0x1000
41 #define ATI_VENDOR_ID 0x1002
42 #define INTEL_VENDOR_ID 0x8086
43 #define ATI_RV423_ID 0x5548
44 #define ATI_RV423_ID2 0x5d57
45 #define ATI_RV380_ID 0x3e50
46 #define ATI_RV370_ID 0x5b60
47 #define SI_VENDOR_ID 0x1095
48 #define SI_SISATA_ID 0x3114
49 #define SI_SIRAID_PCIUNL 0x40
50 #define INTEL_82573E_IDER 0x108D
59 BAD_DEVICE_TABLE BadDeviceTable
[] = {
60 {(UINT8
)PCI_CLASS_MASS_STORAGE
,(UINT8
)PCI_CLASS_MASS_STORAGE_SCSI
,(UINT16
)NCR_VENDOR_ID
, (UINT16
)0xffff}, // Any NCR cards
61 {(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
62 {(UINT8
)0xff,(UINT8
)0xff,(UINT16
)0xffff,(UINT16
)0xffff}
70 EFI_EVENT FilterEvent
;
73 // Register for callback to PCI I/O protocol
75 Status
= gBS
->CreateEvent (
82 ASSERT_EFI_ERROR(Status
);
85 // Register for protocol notifications on this event
87 Status
= gBS
->RegisterProtocolNotify (
88 &gEfiPciIoProtocolGuid
,
92 ASSERT_EFI_ERROR (Status
);
99 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
105 UINT64 BaseAddress
= 0;
106 UINT64 TempBaseAddress
= 0;
116 // ATI fix-ups. At this time all ATI cards in BadDeviceTable
117 // have same problem in that OPROM BAR needs to be increased.
121 // Get original BAR address
128 (VOID
*) &BaseAddress
133 TempBaseAddress
= 0xffffffff;
139 (VOID
*) &TempBaseAddress
146 (VOID
*) &TempBaseAddress
148 TempBaseAddress
&= 0xfffffffe;
150 while ((TempBaseAddress
& 0x01) == 0) {
151 TempBaseAddress
= TempBaseAddress
>> 1;
152 MemSize
= MemSize
<< 1;
156 // Free up allocated memory memory and re-allocate with increased size.
158 gDS
->FreeMemorySpace (
163 // Force new alignment
168 gDS
->AllocateMemorySpace (
169 EfiGcdAllocateAnySearchBottomUp
,
170 EfiGcdMemoryTypeMemoryMappedIo
,
171 MemSizeBits
, // Alignment
182 (VOID
*) &BaseAddress
187 #define MIN_NCR_IO_SIZE 0x800
188 #define NCR_GRAN 11 // 2**11 = 0x800
190 // NCR SCSI cards like 8250S lie about IO needed. Assign as least 0x80.
192 for (Bar
= 0x10; Bar
< 0x28; Bar
+= 4) {
199 (VOID
*) &BaseAddress
201 if (BaseAddress
&& 0x01) {
202 TempBaseAddress
= 0xffffffff;
208 (VOID
*) &TempBaseAddress
210 TempBaseAddress
&= 0xfffffffc;
212 while ((TempBaseAddress
& 0x01) == 0) {
213 TempBaseAddress
= TempBaseAddress
>> 1;
214 IoSize
= IoSize
<< 1;
216 if (IoSize
< MIN_NCR_IO_SIZE
) {
222 gDS
->AllocateIoSpace (
223 EfiGcdAllocateAnySearchTopDown
,
225 NCR_GRAN
, // Alignment
231 TempBaseAddress
= BaseAddress
+ 1;
237 (VOID
*) &TempBaseAddress
245 case INTEL_VENDOR_ID
:
246 if (DeviceId
== INTEL_82573E_IDER
) {
248 // Tekoa i82573E IDE-R fix-ups. At this time A2 step and earlier parts do not
249 // support any BARs except BAR0. Other BARS will actualy map to BAR0 so disable
250 // them all for Control Blocks and Bus mastering ops as well as Secondary IDE
252 // All Tekoa A2 or earlier step chips for now.
257 PCI_REVISION_ID_OFFSET
,
262 for (Bar
= 0x14; Bar
< 0x24; Bar
+= 4) {
264 // Maybe want to clean this up a bit later but for now just clear out the secondary
265 // Bars don't worry aboyut freeing up thge allocs.
267 TempBaseAddress
= 0x0;
273 (VOID
*) &TempBaseAddress
281 //Clear bus master base address (PCI register 0x20)
282 //since Tekoa does not fully support IDE Bus Mastering
284 TempBaseAddress
= 0x0;
290 (VOID
*) &TempBaseAddress
304 IN EFI_PCI_IO_PROTOCOL
*PciIo
308 // Program Master Latency Timer
310 if (mSystemConfiguration
.PciLatency
!= 0) {
314 PCI_LATENCY_TIMER_OFFSET
,
316 &mSystemConfiguration
.PciLatency
323 During S5 shutdown, we need to program PME in all LAN devices.
324 Here we identify LAN devices and save their bus/dev/func.
329 IN EFI_PCI_IO_PROTOCOL
*PciIo
340 Status
= PciIo
->GetLocation (
347 if (EFI_ERROR (Status
)) {
352 Status
= gBS
->AllocatePool (
354 mPciLanCount
* sizeof(PCI_LAN_INFO
),
357 if (EFI_ERROR (Status
)) {
361 if (mPciLanCount
> 1) {
363 // copy old data into new, larger buffer
368 (mPciLanCount
- 1) * sizeof(PCI_LAN_INFO
)
372 // free the old memory buffer
374 gBS
->FreePool (mPciLanInfo
);
379 // init the new entry
381 x
= (PCI_LAN_INFO
*)NewBuffer
+ (mPciLanCount
- 1);
382 x
->PciBus
= (UINT8
)PciBus
;
383 x
->PciDevice
= (UINT8
)PciDevice
;
384 x
->PciFunction
= (UINT8
)PciFunction
;
386 mPciLanInfo
= NewBuffer
;
392 @param Event the event that is signaled.
393 @param Context not used here.
408 EFI_PCI_IO_PROTOCOL
*PciIo
;
409 PCI_IO_DEVICE
*PciIoDevice
;
412 UINT8 mCacheLineSize
= 0x10;
415 BufferSize
= sizeof (EFI_HANDLE
);
416 Status
= gBS
->LocateHandle (
423 if (EFI_ERROR (Status
)) {
425 // If no more notification events exist
430 Status
= gBS
->HandleProtocol (
432 &gEfiPciIoProtocolGuid
,
436 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
439 // Enable I/O for bridge so port 0x80 codes will come out
441 if (PciIoDevice
->Pci
.Hdr
.VendorId
== V_PCH_INTEL_VENDOR_ID
)
443 Status
= PciIo
->Attributes(
445 EfiPciIoAttributeOperationSupported
,
449 Supports
&= EFI_PCI_DEVICE_ENABLE
;
450 Status
= PciIo
->Attributes (
452 EfiPciIoAttributeOperationEnable
,
460 // Program PCI Latency Timer
462 ProgramPciLatency(PciIo
);
465 // Program Cache Line Size to 64 bytes (0x10 DWORDs)
467 Status
= PciIo
->Pci
.Write (
470 PCI_CACHELINE_SIZE_OFFSET
,
476 // If PCI LAN device, save bus/dev/func info
477 // so we can program PME during S5 shutdown
479 if (PciIoDevice
->Pci
.Hdr
.ClassCode
[2] == PCI_CLASS_NETWORK
) {
480 SavePciLanAddress(PciIo
);
485 // Workaround for cards with bad BARs
488 while (BadDeviceTable
[Index
].ClassCode
!= 0xff) {
489 if (BadDeviceTable
[Index
].DeviceId
== 0xffff) {
490 if ((PciIoDevice
->Pci
.Hdr
.ClassCode
[2] == BadDeviceTable
[Index
].ClassCode
) &&
491 (PciIoDevice
->Pci
.Hdr
.ClassCode
[1] == BadDeviceTable
[Index
].SubClassCode
) &&
492 (PciIoDevice
->Pci
.Hdr
.VendorId
== BadDeviceTable
[Index
].VendorId
)) {
493 InitBadBars(PciIo
,BadDeviceTable
[Index
].VendorId
,BadDeviceTable
[Index
].DeviceId
);
496 if ((PciIoDevice
->Pci
.Hdr
.ClassCode
[2] == BadDeviceTable
[Index
].ClassCode
) &&
497 (PciIoDevice
->Pci
.Hdr
.ClassCode
[1] == BadDeviceTable
[Index
].SubClassCode
) &&
498 (PciIoDevice
->Pci
.Hdr
.VendorId
== BadDeviceTable
[Index
].VendorId
) &&
499 (PciIoDevice
->Pci
.Hdr
.DeviceId
== BadDeviceTable
[Index
].DeviceId
)) {
501 InitBadBars(PciIo
,BadDeviceTable
[Index
].VendorId
,BadDeviceTable
[Index
].DeviceId
);