/** @file
PCI Host Bridge Definitions

Copyright (c) 2013-2015 Intel Corporation.

SPDX-License-Identifier: BSD-2-Clause-Patent

**/


Name(PBRS, ResourceTemplate() {
   WORDBusNumber(            //Bus number resource (0); the bridge produces bus numbers for its subsequent buses
      ResourceProducer,      // bit 0 of general flags is 1
      MinFixed,              // Range is fixed
      MaxFixed,              // Range is fixed
      PosDecode,             // PosDecode
      0x0000,                // Granularity
      0x0000,                // Min
      0x001f,                // Max
      0x0000,                // Translation
      0x0020                 // Range Length = Max-Min+1
   )

   WORDIO(                   //Consumed-and-produced resource (all I/O below CF8)
      ResourceProducer,      // bit 0 of general flags is 0
      MinFixed,              // Range is fixed
      MaxFixed,              // Range is fixed
      PosDecode,
      EntireRange,
      0x0000,                // Granularity
      0x0000,                // Min
      0x0cf7,                // Max
      0x0000,                // Translation
      0x0cf8                 // Range Length
   )

   IO(                       //Consumed resource (CF8-CFF)
      Decode16,
      0x0cf8,
      0xcf8,
      1,
      8
   )

   WORDIO(                   //Consumed-and-produced resource (all I/O above CFF)
      ResourceProducer,      // bit 0 of general flags is 0
      MinFixed,              // Range is fixed
      MaxFixed,              // Range is fixed
      PosDecode,
      EntireRange,
      0x0000,                // Granularity
      0x0d00,                // Min
      0xffff,                // Max
      0x0000,                // Translation
      0xf300                 // Range Length
   )

   DWORDMEMORY(              // descriptor for dos area(0->0xa0000)
      ResourceProducer,      // bit 0 of general flags is 0
      PosDecode,
      MinFixed,              // Range is fixed
      MaxFixed,              // Range is Fixed
      Cacheable,
      ReadWrite,
      0x00000000,            // Granularity
      0x000a0000,            // Min
      0x000bffff,            // Max
      0x00000000,            // Translation
      0x00020000             // Range Length
   )

   DWORDMemory(              // Consumed-and-produced resource for pci memory mapped memory
      ResourceProducer,      // bit 0 of general flags is 0
      PosDecode,             // positive Decode
      MinFixed,              // Range is fixed
      MaxFixed,              // Range is fixed
      Cacheable,
      ReadWrite,
      0x00000000,            // Granularity
      0x00000000,            // Min (calculated dynamically)

      0xfebfffff,            // Max = IO Apic base address - 1
      0x00000000,            // Translation
      0xfec00000,            // Range Length (calculated dynamically)
      ,                      // Optional field left blank
      ,                      // Optional field left blank
      MEM1                   // Name declaration for this descriptor
   )

})          // end of CRES Buffer


Method(_CRS, 0x0, NotSerialized)
{
    CreateDWordField(PBRS, \_SB.PCI0.MEM1._MIN, MMIN)
    CreateDWordField(PBRS, \_SB.PCI0.MEM1._MAX, MMAX)
    CreateDWordField(PBRS, \_SB.PCI0.MEM1._LEN, MLEN)

    // HMBOUND is PCI memory base
    And(MNRD(0x03, 0x08), 0xFFFFF000, MMIN)
    Add(Subtract(MMAX, MMIN), 1, MLEN)

    Return(PBRS)
}

// Message Nework Registers
OperationRegion(MNR, PCI_Config, 0xD0, 0x10)
Field(MNR, DWordAcc, NoLock, Preserve)
{
    MCR, 32,           // Message Control Register
    MDR, 32            // Message Data Register
}

// Message Nework Read Method
// Arg0 = Port
// Arg1 = RegAddress
// return 32 bit register value
Method(MNRD, 2, Serialized)
{
    Or(ShiftLeft(Arg0, 16), ShiftLeft(Arg1, 8), Local0)
    Or(Local0, 0x100000F0, Local0)
    Store(Local0, MCR)
    Return(MDR)
}

// Message Nework Write Method
// Arg0 = Port
// Arg1 = RegAddress
// Arg2 = 32 bit write value
Method(MNWR, 3, Serialized)
{
    Store(Arg2, MDR)
    Or(ShiftLeft(Arg0, 16), ShiftLeft(Arg1, 8), Local0)
    Or(Local0, 0x110000F0, Local0)
    Store(Local0, MCR)
}

Method(_PRT, 0, NotSerialized)
{
  If (LEqual(\GPIC, Zero)) // 8259 Interrupt Routing
  {
    Return (
      Package()
      {
        // Bus 0, Device 20 - IOSFAHB Bridge
        Package() {0x0014ffff, 0, \_SB.PCI0.LPC.LNKA, 0}, // INTA
        Package() {0x0014ffff, 1, \_SB.PCI0.LPC.LNKB, 0}, // INTB
        Package() {0x0014ffff, 2, \_SB.PCI0.LPC.LNKC, 0}, // INTC
        Package() {0x0014ffff, 3, \_SB.PCI0.LPC.LNKD, 0}, // INTD

        // Bus 0, Device 21 - IOSFAHB Bridge
        Package() {0x0015ffff, 0, \_SB.PCI0.LPC.LNKA, 0}, // INTA
        Package() {0x0015ffff, 1, \_SB.PCI0.LPC.LNKB, 0}, // INTB
        Package() {0x0015ffff, 2, \_SB.PCI0.LPC.LNKC, 0}, // INTC
        Package() {0x0015ffff, 3, \_SB.PCI0.LPC.LNKD, 0}, // INTD

        // Bus 0, Device 23 - PCIe port 0
        Package() {0x0017ffff, 0, \_SB.PCI0.LPC.LNKE, 0}, // INTA
        Package() {0x0017ffff, 1, \_SB.PCI0.LPC.LNKF, 0}, // INTB
        Package() {0x0017ffff, 2, \_SB.PCI0.LPC.LNKG, 0}, // INTC
        Package() {0x0017ffff, 3, \_SB.PCI0.LPC.LNKH, 0}, // INTD

        // Bus 0, Device 31
        Package() {0x001fffff, 0, \_SB.PCI0.LPC.LNKA, 0}, // LPC Bridge
      }
    )
  }
  else {
    Return (
      Package()
      {
        // Bus 0, Device 20 - IOSFAHB Bridge
        Package() {0x0014ffff, 0, 0, 16}, // INTA
        Package() {0x0014ffff, 1, 0, 17}, // INTB
        Package() {0x0014ffff, 2, 0, 18}, // INTC
        Package() {0x0014ffff, 3, 0, 19}, // INTD

        // Bus 0, Device 21 - IOSFAHB Bridge
        Package() {0x0015ffff, 0, 0, 16}, // INTA
        Package() {0x0015ffff, 1, 0, 17}, // INTB
        Package() {0x0015ffff, 2, 0, 18}, // INTC
        Package() {0x0015ffff, 3, 0, 19}, // INTD

        // Bus 0, Device 23 - PCIe port 0
        Package() {0x0017ffff, 0, 0, 20}, // INTA
        Package() {0x0017ffff, 1, 0, 21}, // INTB
        Package() {0x0017ffff, 2, 0, 22}, // INTC
        Package() {0x0017ffff, 3, 0, 23}, // INTD

        // Bus 0, Device 31
        Package() {0x001fffff, 0, 0, 16}, // LPC Bridge
      }
    )
  }
}
