/** @file

  @copyright
  Copyright 2001 - 2016 Intel Corporation. <BR>

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

  Name (SUPP, 0)
  Name (CTRL, 0)

  Method(_OSC,4) {
    //
    // Create DWord-addressable fields from the capabilities Buffer
    //
    CreateDWordField(Arg3,0,CDW1)
    CreateDWordField(Arg3,4,CDW2)
    If(LGreater(Arg2,2)) {
      CreateDWordField(Arg3,8,CDW3)
    }


      If (LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
        //
        // Save Capabilities DWord2 & 3
        //
        Store(CDW2,SUPP)
        Store(CDW3,CTRL)

        //
        // Only allow native hot plug control if OS supports
        // * ASPM
        // * MSI/MSI-X
        //
        If (LOr(AHPE, LNotEqual(And(SUPP, 0x16), 0x16))) { // Conditions not met?
          And(CTRL, 0x1E, CTRL) // Mask bit 0 to deny.
          Sleep(1000)
        }

        //
        // Never allow SHPC (no SHPC controller in system)
        //
        And(CTRL, 0x1D, CTRL)
        //And (CTRL, 0x1C, CTRL)

          If (LNotEqual(Arg1,one)) { // unknown revision
            Or(CDW1,0x08,CDW1)
          }

          If(LNotEqual(CDW3,CTRL)) { // capabilities bits were masked
            Or(CDW1,0x10,CDW1)
          }
          //
          // update DWORD3 in the buffer
          //
          Store(CTRL,CDW3)
          Return(Arg3)

      } Else {
        //
        // Just indicate unrecognized UUID
        // Leave it at that
        //
        Or (CDW1,4,CDW1)
        Store (0xEE, IO80)
        Return(Arg3)
      }
  }

  Method(_STA){
    // Check if Virtual FPGA is present
    if(LEqual(P0FB, 0x1)) {
      // Virtual FPGA present and logically online
      Return(0x0F)
    }
    // Virtual FPGA logically offline
    Return(0x00)

  } // End Method STA

  Name (RBUF, 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
      0x0000,                 // Max
      0x0000,                 // Translation
      0x0001,                 // Range Length = Max-Min+1
      ,
      ,
      FBUS
    )

    DWORDMemory(              // Consumed-and-produced resource(all of memory space)
      ResourceProducer,       // bit 0 of general flags is 0
      PosDecode,              // positive Decode
      MinFixed,               // Range is fixed
      MaxFixed,               // Range is fixed
      NonCacheable,
      ReadWrite,
      0x00000000,             // Granularity (FIX7 - Patched by ACPI Platform Driver during POST)
      0x00000000,             // Min (calculated dynamically) (FIX7 - Patched by ACPI Platform Driver during POST)
      0x00000000,             // Max = 4GB - 1MB  (fwh + fwh alias) (FIX7 - Patched by ACPI Platform Driver during POST)
      0x00000000,             // Translation
      0x00000000,             // Range Length (calculated dynamically) (FIX7 - Patched by ACPI Platform Driver during POST)
                ,
                ,
      FPGM                    // DescriptorName populated so iASL outputs offset for it in a .h file
    )

    DWORDMemory(              // Consumed-and-produced resource(all of memory space)
      ResourceProducer,       // bit 0 of general flags is 0
      PosDecode,              // positive Decode
      MinFixed,               // Range is fixed
      MaxFixed,               // Range is fixed
      NonCacheable,
      ReadWrite,
      0x00000000,             // Granularity (FIXZ - Patched by ACPI Platform Driver during POST)
      0x00000000,             // Min (calculated dynamically) (FIXZ - Patched by ACPI Platform Driver during POST)
      0x00000000,             // Max = 4GB - 1MB  (fwh + fwh alias) (FIXZ - Patched by ACPI Platform Driver during POST)
      0x00000000,             // Translation
      0x00000000,             // Range Length (calculated dynamically) (FIXZ - Patched by ACPI Platform Driver during POST)
                ,
                ,
      FIXZ                    // DescriptorName populated so iASL outputs offset for it in a .h file
    )

  })

  Method(_CRS, 0x0, NotSerialized) {
    ///
    /// Patch 32b memory
    ///
    CreateDwordField(^RBUF, ^FPGM._MIN, FMN1)
    CreateDwordField(^RBUF, ^FPGM._MAX, FMX1)
    CreateDwordField(^RBUF, ^FPGM._LEN, FLN1)
    Store(FMB0, FMN1)
    Store(FML0, FMX1)
    Subtract (FMX1, FMN1, FLN1)
    Add (FLN1, 1, FLN1)

    ///
    /// Patch _BBN
    ///
    If(LGreater(FBL0, FBB0)) {
      CreateWordField(^RBUF, ^FBUS._MIN, BMIN)
      CreateWordField(^RBUF, ^FBUS._MAX, BMAX)
      CreateWordField(^RBUF, ^FBUS._LEN, BLEN)
      Store(FBB0, BMIN)
      Store(FBL0, BMAX)
      Subtract (BMAX, BMIN, BLEN)
      Add (BLEN, 1, BLEN)
    }
    Return (RBUF)
  }
