/** @file

  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
                                                                                   
  This program and the accompanying materials are licensed and made available under
  the terms and conditions of the BSD License that accompanies this distribution.  
  The full text of the license may be found at                                     
  http://opensource.org/licenses/bsd-license.php.                                  
                                                                                   
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,            
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.    
                                                                                   

Module Name:


  PciDevice.c

Abstract:

  Platform Initialization Driver.

Revision History

--*/

#include "PlatformDxe.h"
#include "Library/DxeServicesTableLib.h"
#include "PciBus.h"
#include "Guid/PciLanInfo.h"

extern  VOID    *mPciLanInfo;
extern  UINTN   mPciLanCount;

extern  EFI_HANDLE  mImageHandle;
extern  SYSTEM_CONFIGURATION    mSystemConfiguration;


VOID       *mPciRegistration;
#define NCR_VENDOR_ID  0x1000
#define ATI_VENDOR_ID  0x1002
#define INTEL_VENDOR_ID 0x8086
#define ATI_RV423_ID   0x5548
#define ATI_RV423_ID2  0x5d57
#define ATI_RV380_ID   0x3e50
#define ATI_RV370_ID   0x5b60
#define SI_VENDOR_ID   0x1095
#define SI_SISATA_ID   0x3114
#define SI_SIRAID_PCIUNL 0x40
#define INTEL_82573E_IDER 0x108D

typedef struct {
  UINT8               ClassCode;
  UINT8               SubClassCode;
  UINT16              VendorId;
  UINT16              DeviceId;
} BAD_DEVICE_TABLE;

BAD_DEVICE_TABLE BadDeviceTable[] = {
                    {(UINT8)PCI_CLASS_MASS_STORAGE,(UINT8)PCI_CLASS_MASS_STORAGE_SCSI,(UINT16)NCR_VENDOR_ID, (UINT16)0xffff}, // Any NCR cards
                    {(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
                    {(UINT8)0xff,(UINT8)0xff,(UINT16)0xffff,(UINT16)0xffff}
                  };

EFI_STATUS
PciBusDriverHook (
  )
{
  EFI_STATUS                Status;
  EFI_EVENT                 FilterEvent;

  //
  // Register for callback to PCI I/O protocol
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  PciBusEvent,
                  NULL,
                  &FilterEvent
                  );
  ASSERT_EFI_ERROR(Status);

  //
  // Register for protocol notifications on this event
  //
  Status = gBS->RegisterProtocolNotify (
                  &gEfiPciIoProtocolGuid,
                  FilterEvent,
                  &mPciRegistration
                  );
  ASSERT_EFI_ERROR (Status);

  return  EFI_SUCCESS;
}

VOID
InitBadBars(
  IN    EFI_PCI_IO_PROTOCOL           *PciIo,
  IN    UINT16                        VendorId,
  IN    UINT16                        DeviceId
  )
{

  EFI_STATUS                          Status;
  PCI_IO_DEVICE                       *PciIoDevice;
  UINT64                              BaseAddress = 0;
  UINT64                              TempBaseAddress = 0;
  UINT8                               RevId = 0;
  UINT32                              Bar;
  UINT64                              IoSize;
  UINT64                              MemSize;
  UINTN                               MemSizeBits;


  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
  switch ( VendorId) {
    case ATI_VENDOR_ID:
      //
      //  ATI fix-ups. At this time all ATI cards in BadDeviceTable
      //  have same problem in that OPROM BAR needs to be increased.
      //
      Bar = 0x30 ;
      //
      // Get original BAR address
      //
      Status = PciIo->Pci.Read (
                            PciIo,
                            EfiPciIoWidthUint32,
                            Bar,
                            1,
                                (VOID *) &BaseAddress
                            );
      //
      // Find BAR size
      //
      TempBaseAddress = 0xffffffff;
      Status = PciIo->Pci.Write (
                            PciIo,
                            EfiPciIoWidthUint32,
                            Bar,
                            1,
                                 (VOID *) &TempBaseAddress
                            );
      Status = PciIo->Pci.Read (
                            PciIo,
                            EfiPciIoWidthUint32,
                            Bar,
                            1,
                                (VOID *) &TempBaseAddress
                            );
      TempBaseAddress &= 0xfffffffe;
      MemSize = 1;
      while ((TempBaseAddress & 0x01) == 0) {
        TempBaseAddress = TempBaseAddress >> 1;
        MemSize = MemSize << 1;
      }

      //
      // Free up allocated memory memory and re-allocate with increased size.
      //
      Status = gDS->FreeMemorySpace (
                      BaseAddress,
                      MemSize
                      );
      //
      // Force new alignment
      //
      MemSize = 0x8000000;
      MemSizeBits = 28;

      Status = gDS->AllocateMemorySpace (
                      EfiGcdAllocateAnySearchBottomUp,
                      EfiGcdMemoryTypeMemoryMappedIo,
                      MemSizeBits,           // Alignment
                      MemSize,
                      &BaseAddress,
                      mImageHandle,
                      NULL
                      );
      Status = PciIo->Pci.Write (
                            PciIo,
                            EfiPciIoWidthUint32,
                            Bar,
                            1,
                                 (VOID *) &BaseAddress
                            );

      break;
    case    NCR_VENDOR_ID:
#define MIN_NCR_IO_SIZE  0x800
#define NCR_GRAN  11  // 2**11 = 0x800
  //
  // NCR SCSI cards like 8250S lie about IO needed. Assign as least 0x80.
  //
  for (Bar = 0x10; Bar < 0x28; Bar+= 4) {

    Status = PciIo->Pci.Read (
                          PciIo,
                          EfiPciIoWidthUint32,
                          Bar,
                          1,
                              (VOID *) &BaseAddress
                          );
    if (BaseAddress && 0x01) {
      TempBaseAddress = 0xffffffff;
      Status = PciIo->Pci.Write (
                            PciIo,
                            EfiPciIoWidthUint32,
                            Bar,
                            1,
                                 (VOID *) &TempBaseAddress
                            );
      TempBaseAddress &= 0xfffffffc;
      IoSize = 1;
      while ((TempBaseAddress & 0x01) == 0) {
        TempBaseAddress = TempBaseAddress >> 1;
        IoSize = IoSize << 1;
      }
      if (IoSize < MIN_NCR_IO_SIZE) {
        Status = gDS->FreeIoSpace (
                        BaseAddress,
                        IoSize
                        );

        Status = gDS->AllocateIoSpace (
                        EfiGcdAllocateAnySearchTopDown,
                        EfiGcdIoTypeIo,
                        NCR_GRAN,           // Alignment
                        MIN_NCR_IO_SIZE,
                        &BaseAddress,
                        mImageHandle,
                        NULL
                        );
        TempBaseAddress = BaseAddress + 1;
        Status = PciIo->Pci.Write (
                              PciIo,
                              EfiPciIoWidthUint32,
                              Bar,
                              1,
                                   (VOID *) &TempBaseAddress
                              );
      }
    }
  }

      break;

    case INTEL_VENDOR_ID:
      if (DeviceId == INTEL_82573E_IDER) {
        //
        //  Tekoa i82573E IDE-R fix-ups. At this time A2 step and earlier parts do not
        //  support any BARs except BAR0. Other BARS will actualy map to BAR0 so disable
        //  them all for Control Blocks and Bus mastering ops as well as Secondary IDE
        //  Controller.
        //  All Tekoa A2 or earlier step chips for now.
        //
        Status = PciIo->Pci.Read (
                              PciIo,
                              EfiPciIoWidthUint8,
                              PCI_REVISION_ID_OFFSET,
                              1,
                              &RevId
                              );
        if (RevId <= 0x02) {
          for (Bar = 0x14; Bar < 0x24; Bar+= 4) {
            //
            // Maybe want to clean this up a bit later but for now just clear out the secondary
            // Bars don't worry aboyut freeing up thge allocs.
            //
            TempBaseAddress = 0x0;
            Status = PciIo->Pci.Write (
                                  PciIo,
                                  EfiPciIoWidthUint32,
                                  Bar,
                                  1,
                                       (VOID *) &TempBaseAddress
                                  );
          } // end for
        }
        else
        {
        	//
          //Tekoa A3 or above:
          //Clear bus master base address (PCI register 0x20)
          //since Tekoa does not fully support IDE Bus Mastering
          //
          TempBaseAddress = 0x0;
          Status = PciIo->Pci.Write (
                                PciIo,
                                EfiPciIoWidthUint32,
                                0x20,
                                1,
                                     (VOID *) &TempBaseAddress
                                );
        }
      }
      break;

    default:
      break;
  }
  return;
}

VOID
ProgramPciLatency(
  IN    EFI_PCI_IO_PROTOCOL           *PciIo
  )
{
  EFI_STATUS                          Status;

  //
  // Program Master Latency Timer
  //
  if (mSystemConfiguration.PciLatency != 0) {
     Status = PciIo->Pci.Write (
                           PciIo,
                           EfiPciIoWidthUint8,
                           PCI_LATENCY_TIMER_OFFSET,
                           1,
                           &mSystemConfiguration.PciLatency
                           );
  }
  return;
}

/**
During S5 shutdown, we need to program PME in all LAN devices.
Here we identify LAN devices and save their bus/dev/func.

**/
VOID
SavePciLanAddress(
  IN EFI_PCI_IO_PROTOCOL    *PciIo
  )
{
  EFI_STATUS        Status;
  UINTN             PciSegment,
                    PciBus,
                    PciDevice,
                    PciFunction;
  VOID              *NewBuffer;
  PCI_LAN_INFO      *x;

  Status = PciIo->GetLocation (
                    PciIo,
                    &PciSegment,
                    &PciBus,
                    &PciDevice,
                    &PciFunction
                    );
  if (EFI_ERROR (Status)) {
    return;
  }

  mPciLanCount ++;
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  mPciLanCount * sizeof(PCI_LAN_INFO),
                  &NewBuffer
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  if (mPciLanCount > 1) {
    //
    // copy old data into new, larger buffer
    //
    gBS->CopyMem (
           NewBuffer,
           mPciLanInfo,
           (mPciLanCount - 1) * sizeof(PCI_LAN_INFO)
           );

    //
    // free the old memory buffer
    //
    gBS->FreePool (mPciLanInfo);

  }

  //
  // init the new entry
  //
  x = (PCI_LAN_INFO *)NewBuffer + (mPciLanCount - 1);
  x->PciBus = (UINT8)PciBus;
  x->PciDevice = (UINT8)PciDevice;
  x->PciFunction = (UINT8)PciFunction;

  mPciLanInfo = NewBuffer;

  return;
}

/**
  @param  Event          the event that is signaled.
  @param Context        not used here.


**/
VOID
EFIAPI
PciBusEvent (
  IN EFI_EVENT    Event,
  IN VOID*        Context
  )
{

  EFI_STATUS                    Status;
  UINTN                         BufferSize;
  EFI_HANDLE                    Handle;
  EFI_PCI_IO_PROTOCOL           *PciIo;
  PCI_IO_DEVICE                 *PciIoDevice;
  UINT64                        Supports;
  UINTN                         Index;
  UINT8                         mCacheLineSize = 0x10;

  while (TRUE) {
    BufferSize = sizeof (EFI_HANDLE);
    Status = gBS->LocateHandle (
                    ByRegisterNotify,
                    NULL,
                    mPciRegistration,
                    &BufferSize,
                    &Handle
                    );
    if (EFI_ERROR (Status)) {
      //
      // If no more notification events exist
      //
      return;
    }

    Status = gBS->HandleProtocol (
                    Handle,
                    &gEfiPciIoProtocolGuid,
                    (void **)&PciIo
                    );

    PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);

    //
    // Enable I/O for bridge so port 0x80 codes will come out
    //
    if (PciIoDevice->Pci.Hdr.VendorId == V_PCH_INTEL_VENDOR_ID)
    {
      Status = PciIo->Attributes(
                        PciIo,
                        EfiPciIoAttributeOperationSupported,
                        0,
                        &Supports
                        );
      Supports &= EFI_PCI_DEVICE_ENABLE;
      Status = PciIo->Attributes (
                        PciIo,
                        EfiPciIoAttributeOperationEnable,
                        Supports,
                        NULL
                        );
      break;
    }

    //
    // Program PCI Latency Timer
    //
    ProgramPciLatency(PciIo);

    //
    // Program Cache Line Size to 64 bytes (0x10 DWORDs)
    //
    Status = PciIo->Pci.Write (
                          PciIo,
                          EfiPciIoWidthUint8,
                          PCI_CACHELINE_SIZE_OFFSET,
                          1,
                          &mCacheLineSize
                          );

    //
    // If PCI LAN device, save bus/dev/func info
    // so we can program PME during S5 shutdown
    //
    if (PciIoDevice->Pci.Hdr.ClassCode[2] == PCI_CLASS_NETWORK) {
      SavePciLanAddress(PciIo);
      break;
    }

    //
    // Workaround for cards with bad BARs
    //
    Index = 0;
    while (BadDeviceTable[Index].ClassCode != 0xff) {
      if (BadDeviceTable[Index].DeviceId == 0xffff) {
        if ((PciIoDevice->Pci.Hdr.ClassCode[2] == BadDeviceTable[Index].ClassCode) &&
            (PciIoDevice->Pci.Hdr.ClassCode[1] == BadDeviceTable[Index].SubClassCode) &&
            (PciIoDevice->Pci.Hdr.VendorId == BadDeviceTable[Index].VendorId)) {
          InitBadBars(PciIo,BadDeviceTable[Index].VendorId,BadDeviceTable[Index].DeviceId);
        }
      } else {
        if ((PciIoDevice->Pci.Hdr.ClassCode[2] == BadDeviceTable[Index].ClassCode) &&
            (PciIoDevice->Pci.Hdr.ClassCode[1] == BadDeviceTable[Index].SubClassCode) &&
            (PciIoDevice->Pci.Hdr.VendorId == BadDeviceTable[Index].VendorId) &&
            (PciIoDevice->Pci.Hdr.DeviceId == BadDeviceTable[Index].DeviceId)) {

          InitBadBars(PciIo,BadDeviceTable[Index].VendorId,BadDeviceTable[Index].DeviceId);
        }
      }
      ++Index;
    }
      break;
    }

  return;
}

