/** @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
  )
{

  UINT64                              BaseAddress = 0;
  UINT64                              TempBaseAddress = 0;
  UINT8                               RevId = 0;
  UINT32                              Bar;
  UINT64                              IoSize;
  UINT64                              MemSize;
  UINTN                               MemSizeBits;

  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
      //
      PciIo->Pci.Read (
                   PciIo,
                   EfiPciIoWidthUint32,
                   Bar,
                   1,
                       (VOID *) &BaseAddress
                   );
      //
      // Find BAR size
      //
      TempBaseAddress = 0xffffffff;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   Bar,
                   1,
                        (VOID *) &TempBaseAddress
                   );
      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.
      //
      gDS->FreeMemorySpace (
             BaseAddress,
             MemSize
             );
      //
      // Force new alignment
      //
      MemSize = 0x8000000;
      MemSizeBits = 28;

      gDS->AllocateMemorySpace (
             EfiGcdAllocateAnySearchBottomUp,
             EfiGcdMemoryTypeMemoryMappedIo,
             MemSizeBits,           // Alignment
             MemSize,
             &BaseAddress,
             mImageHandle,
             NULL
             );
      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) {

    PciIo->Pci.Read (
                 PciIo,
                 EfiPciIoWidthUint32,
                 Bar,
                 1,
                     (VOID *) &BaseAddress
                 );
    if (BaseAddress && 0x01) {
      TempBaseAddress = 0xffffffff;
      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) {
        gDS->FreeIoSpace (
               BaseAddress,
               IoSize
               );

        gDS->AllocateIoSpace (
               EfiGcdAllocateAnySearchTopDown,
               EfiGcdIoTypeIo,
               NCR_GRAN,           // Alignment
               MIN_NCR_IO_SIZE,
               &BaseAddress,
               mImageHandle,
               NULL
               );
        TempBaseAddress = BaseAddress + 1;
        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.
        //
        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;
            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;
          PciIo->Pci.Write (
                       PciIo,
                       EfiPciIoWidthUint32,
                       0x20,
                       1,
                            (VOID *) &TempBaseAddress
                       );
        }
      }
      break;

    default:
      break;
  }
  return;
}

VOID
ProgramPciLatency(
  IN    EFI_PCI_IO_PROTOCOL           *PciIo
  )
{
  //
  // Program Master Latency Timer
  //
  if (mSystemConfiguration.PciLatency != 0) {
     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;
}

