/***************************************************************************************\

Module Name:    MtxPci0.h

Description:    Definition of PCI configuration space structures and registers.

References:     None.

    Copyright (c) 2000, Matrox Graphics Inc.
    All Rights Reserved.

\***************************************************************************************/

#ifndef INC_MTXPCI0_H
#define INC_MTXPCI0_H

// --------------------------------------------------------------------------------------
//                               H E A D E R   F I L E S
// --------------------------------------------------------------------------------------

#include "MtxType.h"

// --------------------------------------------------------------------------------------
//                        C O N S T A N T S   A N D   T Y P E S
// --------------------------------------------------------------------------------------

// PCI Interrupt number
#define PCI_SERVICE             0x1A

// PCI Function numbers
#define PCI_BIOS_PRESENT        0xB101
#define FIND_PCI_DEVICE         0xB102
#define FIND_PCI_CLASS_CODE     0xB103
#define GENERATE_SPECIAL_CYCLE  0xB106
#define READ_CONFIG_BYTE        0xB108
#define READ_CONFIG_WORD        0xB109
#define READ_CONFIG_DWORD       0xB10A
#define WRITE_CONFIG_BYTE       0xB10B
#define WRITE_CONFIG_WORD       0xB10C
#define WRITE_CONFIG_DWORD      0xB10D


// pci BIOS Information structure
typedef struct
{
    BYTE name       [4];    // PCI BIOS signature
    BYTE status     [1];    // PCI BIOS status
    BYTE mechanism  [1];    // Configuration space access mechanism
    BYTE version    [2];    // PCI BIOS version number
    BYTE lastbus    [1];    // Maximum value for bus

} ST_PCI_BIOS_INFO;


// Generic Register Indexes
#define PCI_DEVID               0x00L
#define PCI_DEVCTRL             0x04L
#define PCI_CLASS               0x08L
#define PCI_HEADER              0x0CL
#define PCI_TERMBASE            0x10L
#define PCI_TERMBASE0           0x10L
#define PCI_TERMBASE1           0x14L
#define PCI_TERMBASE2           0x18L
#define PCI_TERMBASE3           0x1CL
#define PCI_TERMBASE4           0x20L
#define PCI_TERMBASE5           0x24L
#define PCI_BAR                 0x10L
#define PCI_BAR0                0x10L
#define PCI_BAR1                0x14L
#define PCI_BAR2                0x18L
#define PCI_BAR3                0x1CL
#define PCI_BAR4                0x20L
#define PCI_BAR5                0x24L
#define PCI_CIS_PTR             0x28L
#define PCI_SUBSYSID            0x2CL
#define PCI_ROMBASE             0x30L
#define PCI_CAP_PTR             0x34L
#define PCI_INTCTRL             0x3CL


// Matrox specific register indexes
#define PCI_MGABASE2            0x10L
#define PCI_MGABASE1            0x14L
#define PCI_MGABASE3            0x18L
#define PCI_SUBSYSID_RO         0x2CL
#define PCI_OPTION              0x40L
#define PCI_MGAINDEX            0x44L
#define PCI_MGADATA             0x48L
#define PCI_SUBSYSID_WO         0x4CL
#define PCI_OPTION2             0x50L
#define PCI_OPTION3             0x54L
#define PCI_PM_IDENT            0xDCL
#define PCI_PM_CSR              0xE0L
#define PCI_AGP_IDENT           0xF0L
#define PCI_AGP_STS             0xF4L
#define PCI_AGP_CMD             0xF8L


// Pci-Pci bridge Register Indexes
#define PCI_BRIDGE_DEVID                    0x00L
#define PCI_BRIDGE_DEVCTRL                  0x04L
#define PCI_BRIDGE_CLASS                    0x08L
#define PCI_BRIDGE_HEADER                   0x0CL
#define PCI_BRIDGE_BAR0                     0x10L
#define PCI_BRIDGE_BAR1                     0x14L
#define PCI_BRIDGE_BUS_CFG                  0x18L
#define PCI_BRIDGE_SEC_STATUS               0x1CL
#define PCI_BRIDGE_MEMORY                   0x20L
#define PCI_BRIDGE_PREFETCH                 0x24L
#define PCI_BRIDGE_PREFETCH_BASE_UPPER32    0x28L
#define PCI_BRIDGE_PREFETCH_LIMIT_UPPER32   0x2CL
#define PCI_BRIDGE_IO_UPPER16               0x30L
#define PCI_BRIDGE_CAP_PTR                  0x34L
#define PCI_BRIDGE_ROMBASE                  0x38L

#ifndef LINUX_PCI_H                           // To avoid warnings with <linux/pci.h>
  #define PCI_BRIDGE_CONTROL                  0x3CL
#endif

#define DECLAREALL      \
    DWORD all

/*
#define DECLAREALL32    \
    union               \
    {                   \
        DWORD all32[1]; \
        WORD  all16[2]; \
        BYTE  all8[4];  \
    }

#define DECLAREALL64    \
    union               \
    {                   \
        DWORD all32[2]; \
        WORD  all16[4]; \
        BYTE  all8[8];  \
    }

#define DECALREALL128   \
    union               \
    {                   \
        DWORD all32[4]; \
        WORD  all16[8]; \
        BYTE  all8[16]; \
    }
*/


typedef union
{
    DECLAREALL;

    struct
    {
        DWORD vendor        :16;    // <15:0>
        DWORD device        :16;    // <31:16>
    };

} ST_PCI_DEVID;

// Vendor IDs
#define PCI_VENDOR_MASK             0x0000FFFFL
#define PCI_VENDOR_NONE             0x0000FFFFL
#define PCI_VENDOR_INVALID          0x0000FFFFL
#define PCI_VENDOR_UNKNOWN          0x0000FFFFL
#define PCI_VENDOR_MATROX           0x0000102BL
#define PCI_VENDOR_INTEL            0x00008086L
#define PCI_VENDOR_PHILIPS          0x00001131L
#define PCI_VENDOR_ALI              0x000010B9L
#define PCI_VENDOR_SIS              0x00001039L
#define PCI_VENDOR_VIA              0x00001106L
#define PCI_VENDOR_RELIANCE         0x00001166L

// Device IDs
#define PCI_DEVICE_SHIFT            16L
#define PCI_DEVICE_STORM            0x00000519L
#define PCI_DEVICE_HURRICANE        0x0000051AL
#define PCI_DEVICE_CHINOOK          0x0000051EL
#define PCI_DEVICE_MISTRAL_PCI      0x0000051BL
#define PCI_DEVICE_MISTRAL_AGP      0x0000051FL
#define PCI_DEVICE_TWISTER_PCI      0x00001000L
#define PCI_DEVICE_TWISTER_AGP      0x00001001L
#define PCI_DEVICE_ECLIPSE_PCI      0x00000520L
#define PCI_DEVICE_ECLIPSE_AGP      0x00000521L
#define PCI_DEVICE_TOUCAN           0x00000525L
#define PCI_DEVICE_CONDORPLUS       0x00002527L
#define PCI_DEVICE_PARHELIA         0x00000527L
#define PCI_DEVICE_MONOPCI1         0x00004028L
#define PCI_DEVICE_MONOPCI2         0x00003000L
#define PCI_DEVICE_MONOPCI3         0x00003004L

// DEVID values
#define PCI_DEVID_TRITON            0x122D8086L
#define PCI_DEVID_ORION             0x84C48086L
#define PCI_DEVID_440LX             0x71808086L
#define PCI_DEVID_440BX             0x71908086L
#define PCI_DEVID_440GX             0x71A08086L
#define PCI_DEVID_CAMINO0           0x25008086L
#define PCI_DEVID_CAMINO1           0x25018086L
#define PCI_DEVID_CAMINO2           0x25028086L
#define PCI_DEVID_CAMINO3           0x25038086L
#define PCI_DEVID_CAMINO4           0x25048086L
#define PCI_DEVID_CAMINOB           0x250B8086L
#define PCI_DEVID_CAMINOF           0x250F8086L
#define PCI_DEVID_KARMEL1           0x1A218086L
#define PCI_DEVID_KARMEL3           0x1A238086L
#define PCI_DEVID_SOLANO            0x11308086L
#define PCI_DEVID_I845              0x1A308086L
#define PCI_DEVID_I850              0x25308086L
#define PCI_DEVID_I860              0x25318086L
#define PCI_DEVID_ALI_1531          0x153110B9L
#define PCI_DEVID_ALI_1541          0x154110B9L
#define PCI_DEVID_ALADDINV          0x154110B9L
#define PCI_DEVID_SIS_5591          0x55911039L
#define PCI_DEVID_SIS_5592          0x55921039L
#define PCI_DEVID_VT694X            0x06911106L
#define PCI_DEVID_VT8605            0x06051106L
#define PCI_DEVID_VT8371            0x03911106L
#define PCI_DEVID_CNB20LE           0x00071166L
#define PCI_DEVID_CNB20HE           0x00081166L
#define PCI_DEVID_AMD_751           0x70061022L
#define PCI_DEVID_AMD_761           0x700E1022L
#define PCI_DEVID_AMD_762           0x700C1022L
#define PCI_DEVID_STORM             0x0519102BL
#define PCI_DEVID_HURRICANE         0x051A102BL
#define PCI_DEVID_MISTRAL_PCI       0x051B102BL
#define PCI_DEVID_MISTRAL_AGP       0x051F102BL
#define PCI_DEVID_TWISTER_PCI       0x1000102BL
#define PCI_DEVID_TWISTER_AGP       0x1001102BL
#define PCI_DEVID_ECLIPSE_PCI       0x0520102BL
#define PCI_DEVID_ECLIPSE_AGP       0x0521102BL
#define PCI_DEVID_TOUCAN            0x0525102BL
#define PCI_DEVID_CONDORPLUS        0x2527102BL
#define PCI_DEVID_PARHELIA          0x0527102BL
#define PCI_DEVID_MONOPCI1          0x4028102BL
#define PCI_DEVID_MONOPCI2          0x3000102BL
#define PCI_DEVID_MONOPCI3          0x3004102BL

typedef union // DEVCTRL
{
    DECLAREALL;

    struct
    {
        DWORD iospace       :1;     // <0>
        DWORD memspace      :1;     // <1>
        DWORD busmaster     :1;     // <2>
        DWORD specialcycle  :1;     // <3>
        DWORD memwrien      :1;     // <4>
        DWORD vgasnoop      :1;     // <5>
        DWORD resparerr     :1;     // <6>
        DWORD waitcycle     :1;     // <7>
        DWORD serrenable    :1;     // <8>
        DWORD _RSVD9_19     :11;    // <19:9>
        DWORD caplist       :1;     // <20>
        DWORD cap66mhz      :1;     // <21>
        DWORD udfsup        :1;     // <22>
        DWORD fastbackcap   :1;     // <23>
        DWORD _RSVD24       :1;     // <24>
        DWORD devseltim     :2;     // <26:25>
        DWORD sigtargab     :1;     // <27>
        DWORD rectargab     :1;     // <28>
        DWORD recmastab     :1;     // <29>
        DWORD sigsyserr     :1;     // <30>
        DWORD detparerr     :1;     // <31>
    };

} ST_PCI_DEVCTRL;

// PCI_DEVCTRL bit fields
#define PCI_DEVCTRL_IOSPACE_SHIFT           0L
#define PCI_DEVCTRL_IOSPACE_MASK            (1L << PCI_DEVCTRL_IOSPACE_SHIFT)
#define PCI_DEVCTRL_IOSPACE_0               (0L << PCI_DEVCTRL_IOSPACE_SHIFT)
#define PCI_DEVCTRL_IOSPACE_1               (1L << PCI_DEVCTRL_IOSPACE_SHIFT)
#define PCI_DEVCTRL_MEMSPACE_SHIFT          1L
#define PCI_DEVCTRL_MEMSPACE_MASK           (1L << PCI_DEVCTRL_MEMSPACE_SHIFT)
#define PCI_DEVCTRL_MEMSPACE_0              (0L << PCI_DEVCTRL_MEMSPACE_SHIFT)
#define PCI_DEVCTRL_MEMSPACE_1              (1L << PCI_DEVCTRL_MEMSPACE_SHIFT)
#define PCI_DEVCTRL_BUSMASTER_SHIFT         2L
#define PCI_DEVCTRL_BUSMASTER_MASK          (1L << PCI_DEVCTRL_BUSMASTER_SHIFT)
#define PCI_DEVCTRL_BUSMASTER_0             (0L << PCI_DEVCTRL_BUSMASTER_SHIFT)
#define PCI_DEVCTRL_BUSMASTER_1             (1L << PCI_DEVCTRL_BUSMASTER_SHIFT)
#define PCI_DEVCTRL_SPECIALCYCLE_SHIFT      3L
#define PCI_DEVCTRL_SPECIALCYCLE_MASK       (1L << PCI_DEVCTRL_SPECIALCYCLE_SHIFT)
#define PCI_DEVCTRL_SPECIALCYCLE_0          (0L << PCI_DEVCTRL_SPECIALCYCLE_SHIFT)
#define PCI_DEVCTRL_SPECIALCYCLE_1          (1L << PCI_DEVCTRL_SPECIALCYCLE_SHIFT)
#define PCI_DEVCTRL_MEMWRIEN_SHIFT          4L
#define PCI_DEVCTRL_MEMWRIEN_MASK           (1L << PCI_DEVCTRL_MEMWRIEN_SHIFT)
#define PCI_DEVCTRL_MEMWRIEN_0              (0L << PCI_DEVCTRL_MEMWRIEN_SHIFT)
#define PCI_DEVCTRL_MEMWRIEN_1              (1L << PCI_DEVCTRL_MEMWRIEN_SHIFT)
#define PCI_DEVCTRL_VGASNOOP_SHIFT          5L
#define PCI_DEVCTRL_VGASNOOP_MASK           (1L << PCI_DEVCTRL_VGASNOOP_SHIFT)
#define PCI_DEVCTRL_VGASNOOP_0              (0L << PCI_DEVCTRL_VGASNOOP_SHIFT)
#define PCI_DEVCTRL_VGASNOOP_1              (1L << PCI_DEVCTRL_VGASNOOP_SHIFT)
#define PCI_DEVCTRL_RESPARERR_SHIFT         6L
#define PCI_DEVCTRL_RESPARERR_MASK          (1L << PCI_DEVCTRL_RESPARERR_SHIFT)
#define PCI_DEVCTRL_RESPARERR_0             (0L << PCI_DEVCTRL_RESPARERR_SHIFT)
#define PCI_DEVCTRL_RESPARERR_1             (1L << PCI_DEVCTRL_RESPARERR_SHIFT)
#define PCI_DEVCTRL_WAITCYCLE_SHIFT         7L
#define PCI_DEVCTRL_WAITCYCLE_MASK          (1L << PCI_DEVCTRL_WAITCYCLE_SHIFT)
#define PCI_DEVCTRL_WAITCYCLE_0             (0L << PCI_DEVCTRL_WAITCYCLE_SHIFT)
#define PCI_DEVCTRL_WAITCYCLE_1             (1L << PCI_DEVCTRL_WAITCYCLE_SHIFT)
#define PCI_DEVCTRL_SERRENABLE_SHIFT        8L
#define PCI_DEVCTRL_SERRENABLE_MASK         (1L << PCI_DEVCTRL_SERRENABLE_SHIFT)
#define PCI_DEVCTRL_SERRENABLE_0            (0L << PCI_DEVCTRL_SERRENABLE_SHIFT)
#define PCI_DEVCTRL_SERRENABLE_1            (1L << PCI_DEVCTRL_SERRENABLE_SHIFT)
#define PCI_DEVCTRL_CAPLIST_SHIFT           20L
#define PCI_DEVCTRL_CAPLIST_MASK            (1L << PCI_DEVCTRL_CAPLIST_SHIFT)
#define PCI_DEVCTRL_CAPLIST_0               (0L << PCI_DEVCTRL_CAPLIST_SHIFT)
#define PCI_DEVCTRL_CAPLIST_1               (1L << PCI_DEVCTRL_CAPLIST_SHIFT)
#define PCI_DEVCTRL_CAP66MHZ_SHIFT          21L
#define PCI_DEVCTRL_CAP66MHZ_MASK           (1L << PCI_DEVCTRL_CAP66MHZ_SHIFT)
#define PCI_DEVCTRL_CAP66MHZ_0              (0L << PCI_DEVCTRL_CAP66MHZ_SHIFT)
#define PCI_DEVCTRL_CAP66MHZ_1              (1L << PCI_DEVCTRL_CAP66MHZ_SHIFT)
#define PCI_DEVCTRL_UDFSUP_SHIFT            22L
#define PCI_DEVCTRL_UDFSUP_MASK             (1L << PCI_DEVCTRL_UDFSUP_SHIFT)
#define PCI_DEVCTRL_UDFSUP_0                (0L << PCI_DEVCTRL_UDFSUP_SHIFT)
#define PCI_DEVCTRL_UDFSUP_1                (1L << PCI_DEVCTRL_UDFSUP_SHIFT)
#define PCI_DEVCTRL_FASTBACKCAP_SHIFT       23L
#define PCI_DEVCTRL_FASTBACKCAP_MASK        (1L << PCI_DEVCTRL_FASTBACKCAP_SHIFT)
#define PCI_DEVCTRL_FASTBACKCAP_0           (0L << PCI_DEVCTRL_FASTBACKCAP_SHIFT)
#define PCI_DEVCTRL_FASTBACKCAP_1           (1L << PCI_DEVCTRL_FASTBACKCAP_SHIFT)
#define PCI_DEVCTRL_DEVSELTIM_SHIFT         25L
#define PCI_DEVCTRL_DEVSELTIM_MASK          (3L << PCI_DEVCTRL_DEVSELTIM_SHIFT)
#define PCI_DEVCTRL_SIGTARGAB_SHIFT         27L
#define PCI_DEVCTRL_SIGTARGAB_MASK          (1L << PCI_DEVCTRL_SIGTARGAB_SHIFT)
#define PCI_DEVCTRL_SIGTARGAB_0             (0L << PCI_DEVCTRL_SIGTARGAB_SHIFT)
#define PCI_DEVCTRL_SIGTARGAB_1             (1L << PCI_DEVCTRL_SIGTARGAB_SHIFT)
#define PCI_DEVCTRL_RECTARGAB_SHIFT         28L
#define PCI_DEVCTRL_RECTARGAB_MASK          (1L << PCI_DEVCTRL_RECTARGAB_SHIFT)
#define PCI_DEVCTRL_RECTARGAB_0             (0L << PCI_DEVCTRL_RECTARGAB_SHIFT)
#define PCI_DEVCTRL_RECTARGAB_1             (1L << PCI_DEVCTRL_RECTARGAB_SHIFT)
#define PCI_DEVCTRL_RECMASTAB_SHIFT         29L
#define PCI_DEVCTRL_RECMASTAB_MASK          (1L << PCI_DEVCTRL_RECMASTAB_SHIFT)
#define PCI_DEVCTRL_RECMASTAB_0             (0L << PCI_DEVCTRL_RECMASTAB_SHIFT)
#define PCI_DEVCTRL_RECMASTAB_1             (1L << PCI_DEVCTRL_RECMASTAB_SHIFT)
#define PCI_DEVCTRL_SIGSYSERR_SHIFT         30L
#define PCI_DEVCTRL_SIGSYSERR_MASK          (1L << PCI_DEVCTRL_SIGSYSERR_SHIFT)
#define PCI_DEVCTRL_SIGSYSERR_0             (0L << PCI_DEVCTRL_SIGSYSERR_SHIFT)
#define PCI_DEVCTRL_SIGSYSERR_1             (1L << PCI_DEVCTRL_SIGSYSERR_SHIFT)
#define PCI_DEVCTRL_DETPARERR_SHIFT         31L
#define PCI_DEVCTRL_DETPARERR_MASK          (1L << PCI_DEVCTRL_DETPARERR_SHIFT)
#define PCI_DEVCTRL_DETPARERR_0             (0L << PCI_DEVCTRL_DETPARERR_SHIFT)
#define PCI_DEVCTRL_DETPARERR_1             (1L << PCI_DEVCTRL_DETPARERR_SHIFT)


typedef union // CLASS
{
    DECLAREALL;

    struct
    {
        DWORD revision      :8;     // <7:0>
        DWORD _interface    :8;     // <15:8>
        DWORD subclassid    :8;     // <23:16>
        DWORD classid       :8;     // <31:24>
    };

} ST_PCI_CLASS;

// Enumeration for PCI_CLASS.classid
#define CLASS_ID_MASK               0xFFL
#define CLASS_ID_OLD                0L      // backward compatibility
#define CLASS_ID_DISK               1L      // mass storage controllers
#define CLASS_ID_NETWORK            2L      // network controllers
#define CLASS_ID_DISPLAY            3L      // display controllers
#define CLASS_ID_MULTIMEDIA         4L      // multimedia devices
#define CLASS_ID_MEMORY             5L      // memory controllers
#define CLASS_ID_BRIDGE             6L      // bridge devices
#define CLASS_ID_COM                7L      // simple communications controllers
#define CLASS_ID_PERIPHERAL         8L      // generic system peripherals
#define CLASS_ID_INPUT              9L      // input devices
#define CLASS_ID_DOCKING            10L     // docking stations
#define CLASS_ID_PROCESSOR          11L     // processors
#define CLASS_ID_SERIAL_BUS         12L     // serial bus controllers
#define CLASS_ID_WIRELESS           13L     // Wireless controllers
#define CLASS_ID_INTELLIGENTIO      14L     // Intelligent I/O controllers
#define CLASS_ID_SATCOM             15L     // Satellite communication controllers
#define CLASS_ID_ENCRYPT            16L     // Encryption/Decryption controllers
#define CLASS_ID_DSP                17L     // Data acquisition and signal processing controllers
#define CLASS_ID_UNKNOWN            0xFFL   // Device does not fit in any defined classes

// PCI_CLASS bit fields
#define PCI_CLASS_ID_SHIFT                  24L
#define PCI_CLASS_ID_MASK                   (CLASS_ID_MASK << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_OLD                    (CLASS_ID_OLD << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_DISK                   (CLASS_ID_DISK << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_NETWORK                (CLASS_ID_NETWORK << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_DISPLAY                (CLASS_ID_DISPLAY << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_MULTIMEDIA             (CLASS_ID_MULTIMEDIA << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_MEMORY                 (CLASS_ID_MEMORY << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_BRIDGE                 (CLASS_ID_BRIDGE << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_COM                    (CLASS_ID_COM << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_PERIPHERAL             (CLASS_ID_PERIPHERAL << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_INPUT                  (CLASS_ID_INPUT << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_DOCKING                (CLASS_ID_DOCKING << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_PROCESSOR              (CLASS_ID_PROCESSOR << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_SERIAL_BUS             (CLASS_ID_SERIAL_BUS << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_WIRELESS               (CLASS_ID_WIRELESS << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_INTELLIGENTIO          (CLASS_ID_INTELLIGENTIO << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_SATCOM                 (CLASS_ID_SATCOM << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_ENCRYPT                (CLASS_ID_ENCRYPT << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_DSP                    (CLASS_ID_DSP << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_ID_UNKNOWN                (CLASS_ID_UNKNOWN << PCI_CLASS_ID_SHIFT)
#define PCI_CLASS_SUB_SHIFT                 16L
#define PCI_CLASS_SUB_MASK                  (0xFFL << PCI_CLASS_SUB_SHIFT)
#define PCI_CLASS_INTERFACE_SHIFT           8L
#define PCI_CLASS_INTERFACE_MASK            (0xFFL << PCI_CLASS_INTERFACE_SHIFT)
#define PCI_CLASS_REVISION_SHIFT            0L
#define PCI_CLASS_REVISION_MASK             (0xFFL << PCI_CLASS_REVISION_SHIFT)


typedef union // HEADER
{
    DECLAREALL;

    struct
    {
        DWORD cacheline     :8;     // <7:0>
        DWORD latentim      :8;     // <15:8>
        DWORD header        :7;     // <22:16>
        DWORD multifunction :1;     // <23>
        DWORD bist_compcode :4;     // <27:24>
        DWORD _RSVD28_29    :2;     // <29:28>
        DWORD bist_start    :1;     // <30>
        DWORD bist_capable  :1;     // <31>
    };

} ST_PCI_HEADER;

// Enumeration for PCI_HEADER.type
#define HEADER_TYPE_MASK                    0x7FL
#define HEADER_TYPE_NORMAL                  0x00L   // Generic config space header
#define HEADER_TYPE_BRIDGE                  0x01L   // Pci-Pci bridge header
#define HEADER_TYPE_CARDBUS                 0x02L   // Cardbus header

// PCI_HEADER bit fields
#define PCI_HEADER_CACHELINE_SHIFT          0L
#define PCI_HEADER_CACHELINE_MASK           (0xFFL << PCI_HEADER_CACHELINE_SHIFT)
#define PCI_HEADER_LATENTIM_SHIFT           8L
#define PCI_HEADER_LATENTIM_MASK            (0xFFL << PCI_HEADER_LATENTIM_SHIFT)
#define PCI_HEADER_TYPE_SHIFT               16L
#define PCI_HEADER_TYPE_MASK                (HEADER_TYPE_MASK << PCI_HEADER_TYPE_SHIFT)
#ifndef LINUX_PCI_H                           // To avoid warnings with <linux/pci.h>
  #define PCI_HEADER_TYPE_NORMAL              (HEADER_TYPE_NORMAL << PCI_HEADER_TYPE_SHIFT)
  #define PCI_HEADER_TYPE_BRIDGE              (HEADER_TYPE_BRIDGE << PCI_HEADER_TYPE_SHIFT)
  #define PCI_HEADER_TYPE_CARDBUS             (HEADER_TYPE_CARDBUS << PCI_HEADER_TYPE_SHIFT)
#endif
#define PCI_HEADER_MULTIFUNC_SHIFT          23L
#define PCI_HEADER_MULTIFUNC_MASK           (1L << PCI_HEADER_MULTIFUNC_SHIFT)

typedef union // BAR
{
    DECLAREALL;

    struct
    {
        DWORD memspace      :1;     // <0>
        DWORD type          :2;     // <2:1>
        DWORD prefetchable  :1;     // <3>
        DWORD baseaddress   :28;    // <31:4>
    };

} ST_PCI_TERMBASE;

// Enumeration for PCI_TERMBASE.memspace
#define TERMBASE_MEMSPACE_MASK              1L
#define TERMBASE_MEMSPACE_MEMORY            0L
#define TERMBASE_MEMSPACE_IO                1L

// Enumeration for PCI_TERMBASE.type
#define TERMBASE_TYPE_MASK                  3L
#define TERMBASE_TYPE_32BIT                 0L
#define TERMBASE_TYPE_BELOW1MB              1L
#define TERMBASE_TYPE_64BIT                 2L

// PCI_TERMBASE bit fields
#define PCI_TERMBASE_MEMSPACE_SHIFT         0L
#define PCI_TERMBASE_MEMSPACE_MASK          (TERMBASE_MEMSPACE_MASK << PCI_TERMBASE_MEMSPACE_SHIFT)
#define PCI_TERMBASE_MEMSPACE_MEMORY        (TERMBASE_MEMSPACE_MEMORY << PCI_TERMBASE_MEMSPACE_SHIFT)
#define PCI_TERMBASE_MEMSPACE_IO            (TERMBASE_MEMSPACE_IO << PCI_TERMBASE_MEMSPACE_SHIFT)
#define PCI_TERMBASE_TYPE_SHIFT             1L
#define PCI_TERMBASE_TYPE_MASK              (TERMBASE_TYPE_MASK << PCI_TERMBASE_TYPE_SHIFT)
#define PCI_TERMBASE_TYPE_32BIT             (TERMBASE_TYPE_32BIT << PCI_TERMBASE_TYPE_SHIFT)
#define PCI_TERMBASE_TYPE_BELOW1MB          (TERMBASE_TYPE_BELOW1MB << PCI_TERMBASE_TYPE_SHIFT)
#define PCI_TERMBASE_TYPE_64BIT             (TERMBASE_TYPE_64BIT << PCI_TERMBASE_TYPE_SHIFT)
#define PCI_TERMBASE_ADDR_SHIFT             4L
#define PCI_TERMBASE_ADDR_MASK              (0x0FFFFFFFL << PCI_TERMBASE_ADDR_SHIFT)


typedef union // CIS_PTR
{
    DECLAREALL;

    struct
    {
        DWORD _RSVD0_31     :32;    // <31:0>
    };

} ST_PCI_CIS_PTR;


typedef union // SUBSYSID
{
    DECLAREALL;

    struct
    {
        DWORD subsysvid     :16;    // <15:0>
        DWORD subsysid      :16;    // <31:16>
    };

} ST_PCI_SUBSYSID;

// PCI_SUBSYSID bit fields
#define PCI_SUBSYSID_VENDOR_SHIFT           0L
#define PCI_SUBSYSID_VENDOR_MASK            (0xFFFFL << PCI_SUBSYSID_VENDOR_SHIFT)
#define PCI_SUBSYSID_DEVICE_SHIFT           16L
#define PCI_SUBSYSID_DEVICE_MASK            (0xFFFFL << PCI_SUBSYSID_DEVICE_SHIFT)


typedef union // CAP_PTR
{
    DECLAREALL;

    struct
    {
        DWORD cap_ptr       :8;     // <7:0>
        DWORD _RSVD8_31     :24;    // <31:8>
    };

} ST_PCI_CAP_PTR;

#define PCI_CAP_PTR_SHIFT           0L
#define PCI_CAP_PTR_MASK            0xFCL   // Mask for reserved bits
#define PCI_CAP_PTR_MIN             0x40L   // Inclusive minimum
#define PCI_CAP_PTR_MAX             0xFCL   // Inclusive maximum

typedef union // CAP_HEADER
{
    DECLAREALL;

    struct
    {
        DWORD cap_id        :8;     // <7:0>
        DWORD cap_next_ptr  :8;     // <15:8>
        DWORD _RSVD16_31    :16;    // <31:16>
    };

} ST_PCI_CAP_HEADER;

#define CAP_ID_PM                   1L // Power Management
#define CAP_ID_AGP                  2L // Accelerated Graphics Port
#define CAP_ID_VPD                  3L // Vital product data
#define CAP_ID_SLOT                 4L // Slot identification
#define CAP_ID_MSI                  5L // Message signaled interrupts
#define CAP_ID_HOTSWAP              6L // CompactPCI hot swap

#define PCI_CAP_ID_SHIFT                    0L
#define PCI_CAP_ID_MASK                     (0xFFL << PCI_CAP_ID_SHIFT)
#ifndef LINUX_PCI_H
  #define PCI_CAP_ID_PM                       (CAP_ID_PM << PCI_CAP_ID_SHIFT)
  #define PCI_CAP_ID_AGP                      (CAP_ID_AGP << PCI_CAP_ID_SHIFT)
  #define PCI_CAP_ID_VPD                      (CAP_ID_VPD << PCI_CAP_ID_SHIFT)
#endif
#define PCI_CAP_ID_SLOT                     (CAP_ID_SLOT << PCI_CAP_ID_SHIFT)
#ifndef LINUX_PCI_H
  #define PCI_CAP_ID_MSI                      (CAP_ID_MSI << PCI_CAP_ID_SHIFT)
#endif
#define PCI_CAP_ID_HOTSWAP                  (CAP_ID_HOTSWAP << PCI_CAP_ID_SHIFT)
#define PCI_CAP_NEXT_SHIFT                  8L
#define PCI_CAP_NEXT_MASK                   (0xFFL << PCI_CAP_NEXT_SHIFT)


typedef union // ROMBASE
{
    DECLAREALL;

    struct
    {
        DWORD enable        :1;     // <0>
        DWORD _RSVD1_9      :9;     // <9:1>
        DWORD address       :22;    // <31:10>
    };

} ST_PCI_ROMBASE;

#define ROMBASE_DISABLE             0L
#define ROMBASE_ENABLE              1L

#define ROMBASE_ADDRESS_MASK        0xFFFFFC00L
#define ROMBASE_ADDRESS_SHIFT       10L


typedef struct
{
    BYTE signature          [2];    // 0h-1h
    BYTE _RSVD2_17          [22];   // 2h-17h
    BYTE pPCIData           [2];    // 18h-19h

} ST_ROMHEADER;

#define ROMHEADER_SIGNATURE         0xAA55


typedef struct
{
    BYTE signature          [4];    // 0
    BYTE vendorid           [2];    // 4
    BYTE deviceid           [2];    // 6
    BYTE vitalproductdata   [2];    // 8
    BYTE pcidatalength      [2];    // A
    BYTE pcidatarev         [1];    // C
    BYTE classcode          [3];    // D
    BYTE imagelength        [2];    // 10
    BYTE coderev            [2];    // 12
    BYTE codetype           [1];    // 14
    BYTE indicator          [1];    // 15
    BYTE _RSVD16            [2];    // 16

} ST_PCIDATA;

#define PCIDATA_SIGNATURE       "PCIR"

#define PCIDATA_CODETYPE_INTEL          0
#define PCIDATA_CODETYPE_OPENFIRMWARE   1
#define PCIDATA_CODETYPE_HP_PARISC      2


typedef union
{
    DECLAREALL;

    struct
    {
        DWORD intline       :8;     // <7:0>
        DWORD intpin        :8;     // <15:8>
        DWORD mingnt        :8;     // <23:16>
        DWORD maxlat        :8;     // <31:24>
    };

} ST_PCI_INTCTRL;

// Constants for PCI_INTCTRL.intline field
#define INTLINE_MASK                0xFFL
#define INTLINE_NONE                0xFFL

// Constants for PCI_INTCTRL.intpin field
#define INTPIN_MASK                 0xFFL
#define INTPIN_NONE                 0L
#define INTPIN_INTA                 1L
#define INTPIN_INTB                 2L
#define INTPIN_INTC                 3L
#define INTPIN_INTD                 4L

// PCI_INTCTRL bit fields
#define PCI_INTCTRL_INTLINE_SHIFT           0L
#define PCI_INTCTRL_INTLINE_MASK            (INTLINE_MASK << PCI_INTCTRL_INTLINE_SHIFT)
#define PCI_INTCTRL_INTLINE_NONE            (INTLINE_NONE << PCI_INTCTRL_INTLINE_SHIFT)
#define PCI_INTCTRL_INTPIN_SHIFT            8L
#define PCI_INTCTRL_INTPIN_MASK             (INTPIN_MASK << PCI_INTCTRL_INTPIN_SHIFT)
#define PCI_INTCTRL_INTPIN_NONE             (INTPIN_NONE << PCI_INTCTRL_INTPIN_SHIFT)
#define PCI_INTCTRL_INTPIN_INTA             (INTPIN_INTA << PCI_INTCTRL_INTPIN_SHIFT)
#define PCI_INTCTRL_INTPIN_INTB             (INTPIN_INTB << PCI_INTCTRL_INTPIN_SHIFT)
#define PCI_INTCTRL_INTPIN_INTC             (INTPIN_INTC << PCI_INTCTRL_INTPIN_SHIFT)
#define PCI_INTCTRL_INTPIN_INTD             (INTPIN_INTD << PCI_INTCTRL_INTPIN_SHIFT)
#define PCI_INTCTRL_MINGNT_SHIFT            16L
#define PCI_INTCTRL_MINGNT_MASK             (0xFFL << PCI_INTCTRL_MINGNT_SHIFT)
#define PCI_INTCTRL_MAXLAT_SHIFT            24L
#define PCI_INTCTRL_MAXLAT_MASK             (0xFFL << PCI_INTCTRL_MAXLAT_SHIFT)


// Generic offsets for AGP registers
#define OFFSET_AGP_IDENT            0
#define OFFSET_AGP_STS              4
#define OFFSET_AGP_CMD              8

typedef union
{
    DECLAREALL;

    struct
    {
        DWORD agp_cad_id    :8;     // <7:0>
        DWORD agp_next_ptr  :8;     // <15:8>
        DWORD agp_rev       :8;     // <23:16>
        DWORD _RSVD24_31    :8;     // <31:24>
    };

} ST_PCI_AGP_IDENT;


typedef union
{
    DECLAREALL;

    struct
    {
        DWORD rate_cap      :3;     // <2:0>
        DWORD _RSVD3        :1;     // <3>
        DWORD fw_cap        :1;     // <4>
        DWORD addr4g_cap    :1;     // <5>
        DWORD _RSVD6_8      :3;     // <8:6>
        DWORD sba_cap       :1;     // <9>
        DWORD _RSVD10_32    :14;    // <23:10>
        DWORD rq            :8;     // <31:24>
    };

} ST_PCI_AGP_STS;

#define RATE_CAP_SHIFT              0L
#define RATE_CAP_MASK               (0x7L << RATE_CAP_SHIFT)
#define RATE_CAP_NONE               (0x0L << RATE_CAP_SHIFT)
#define RATE_CAP_1X                 (0x1L << RATE_CAP_SHIFT)
#define RATE_CAP_2X                 (0x2L << RATE_CAP_SHIFT)
#define RATE_CAP_4X                 (0x4L << RATE_CAP_SHIFT)

#define FW_CAP_SHIFT                4L
#define FW_CAP_MASK                 (1L << FW_CAP_SHIFT)
#define FW_CAP_OFF                  (0L << FW_CAP_SHIFT)
#define FW_CAP_ON                   (1L << FW_CAP_SHIFT)

#define ADDR4G_CAP_SHIFT            5L
#define ADDR4G_CAP_MASK             (1L << ADDR4G_CAP_SHIFT)
#define ADDR4G_CAP_OFF              (0L << ADDR4G_CAP_SHIFT)
#define ADDR4G_CAP_ON               (1L << ADDR4G_CAP_SHIFT)

#define SBA_CAP_SHIFT               9L
#define SBA_CAP_MASK                (1L << SBA_CAP_SHIFT)
#define SBA_CAP_OFF                 (0L << SBA_CAP_SHIFT)
#define SBA_CAP_ON                  (1L << SBA_CAP_SHIFT)

#define RQ_CAP_SHIFT                24L
#define RQ_CAP_MASK                 (0xFFL << RQ_CAP_SHIFT)

typedef union
{
    DECLAREALL;

    struct
    {
        DWORD data_rate     :3;     // <2:0>
        DWORD _RSVD3        :1;     // <3>
        DWORD fw_enable     :1;     // <4>
        DWORD addr4g_enable :1;     // <5>
        DWORD _RSVD6_7      :2;     // <7:6>
        DWORD agp_enable    :1;     // <8>
        DWORD sba_enable    :1;     // <9>
        DWORD _RSVD10_23    :14;    // <23:10>
        DWORD rq_depth      :8;     // <31:24>
    };

} ST_PCI_AGP_CMD;

#define DATA_RATE_NONE              0L
#define DATA_RATE_1X                1L
#define DATA_RATE_2X                2L
#define DATA_RATE_4X                4L

#define FW_ENABLE_SHIFT             4L
#define FW_ENABLE_MASK              (1L << FW_ENABLE_SHIFT)
#define FW_ENABLE_OFF               (0L << FW_ENABLE_SHIFT)
#define FW_ENABLE_ON                (1L << FW_ENABLE_SHIFT)

#define ADDR4G_ENABLE_SHIFT         5L
#define ADDR4G_ENABLE_MASK          (1L << ADDR4G_ENABLE_SHIFT)
#define ADDR4G_ENABLE_OFF           (0L << ADDR4G_ENABLE_SHIFT)
#define ADDR4G_ENABLE_ON            (1L << ADDR4G_ENABLE_SHIFT)

#define AGP_ENABLE_SHIFT            8L
#define AGP_ENABLE_MASK             (1L << AGP_ENABLE_SHIFT)
#define AGP_ENABLE_OFF              (0L << AGP_ENABLE_SHIFT)
#define AGP_ENABLE_ON               (1L << AGP_ENABLE_SHIFT)

#define SBA_ENABLE_SHIFT            9L
#define SBA_ENABLE_MASK             (1L << SBA_ENABLE_SHIFT)
#define SBA_ENABLE_OFF              (0L << SBA_ENABLE_SHIFT)
#define SBA_ENABLE_ON               (1L << SBA_ENABLE_SHIFT)

#define RQ_DEPTH_SHIFT              24L
#define RQ_DEPTH_MASK               (0xFFL << RQ_DEPTH_SHIFT)


// Generic offsets for powermanagement registers
#define OFFSET_PM_IDENT             0
#define OFFSET_PM_CSR               4

typedef union
{
    DECLAREALL;

    struct
    {
        // Linked list
        DWORD cap_id        :8;     // 7::0
        DWORD next_ptr      :8;     // 15::8

        // Power Management Capabilities
        DWORD version       :3;     // 18::16
        DWORD pmeclock      :1;     // 19
        DWORD _RSVD20       :1;     // 20
        DWORD dsi           :1;     // 21
        DWORD aux_current   :3;     // 24::22
        DWORD d1_sup        :1;     // 25
        DWORD d2_sup        :1;     // 26
        DWORD pme_support   :5;     // 31::27
    };

} ST_PCI_PM_IDENT;

#define PM_VERSION_1_1              2 // PM specification 1.1

#define AUX_CURRENT_SELF            0
#define AUX_CURRENT_55mA            1
#define AUX_CURRENT_100mA           2
#define AUX_CURRENT_160mA           3
#define AUX_CURRENT_220mA           4
#define AUX_CURRENT_270mA           5
#define AUX_CURRENT_320mA           6
#define AUX_CURRENT_375mA           7

#define PME_SUPPORT_D0              1
#define PME_SUPPORT_D1              2
#define PME_SUPPORT_D2              4
#define PME_SUPPORT_D3_HOT          8
#define PME_SUPPORT_D3_COLD         16


typedef union
{
    DECLAREALL;

    struct
    {
        // PMCSR
        DWORD powerstate    :2;     // 1::0
        DWORD _RSVD2_7      :6;     // 7::2
        DWORD pme_en        :1;     // 8
        DWORD data_select   :4;     // 12::9
        DWORD data_scale    :2;     // 14::13
        DWORD pme_status    :1;     // 15

        // PMCSR_BSE
        DWORD _RSVD16_21    :6;     // 21::16
        DWORD b2_b3         :1;     // 22
        DWORD bpcc_en       :1;     // 23

        // DATA
        DWORD data          :8;     // 31::24
    };

} ST_PCI_PM_CSR;

#define PCI_POWERSTATE_D0               0   // On
#define PCI_POWERSTATE_D1               1   //
#define PCI_POWERSTATE_D2               2   //
#define PCI_POWERSTATE_D3               3   // Off

typedef union
{
    DECLAREALL;

    struct
    {
        DWORD priBusNb      :8;     // 7::0
        DWORD secBusNb      :8;     // 15::8
        DWORD subBusNb      :8;     // 23::16
        DWORD secLtcTim     :8;     // 31::24
    };

} ST_PCI_BRIDGE_BUS_CFG;


typedef union
{
    DECLAREALL;

    struct
    {
        DWORD intline       :8;     // 7::0
        DWORD intpin        :8;     // 15::8
        DWORD parity        :1;     // 16
        DWORD serrenable    :1;     // 17
        DWORD isaenable     :1;     // 18
        DWORD vgaenable     :1;     // 19
        DWORD _RSVD20       :1;     // 20
        DWORD masterabort   :1;     // 21
        DWORD secbusreset   :1;     // 22
        DWORD fastbbenable  :1;     // 23
        DWORD pridiscard    :1;     // 24
        DWORD secdiscard    :1;     // 25
        DWORD discardstatus :1;     // 26
        DWORD discardserr   :1;     // 27
        DWORD _RSVD28_31    :4;     // 31::28
    };

} ST_PCI_BRIDGE_CONTROL;

// --------------------------------------------------------------------------------------
//                 G L O B A L   V A R I A B L E   R E F E R E N C E S
// --------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------
//               I N T E R F A C E   F U N C T I O N   P R O T O T Y P E S
// --------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------
//                           I N L I N E S   A N D   M A C R O S
// --------------------------------------------------------------------------------------

#endif  // #ifndef INC_MTXPCIREGS_H
