/* PCI.c - PCI functions */

/* Copyright - Galileo technology. */

#include <galileo/core.h>
#include <galileo/pci.h>
#include <linux/string.h>

/********************************************************************
* pci0ScanDevices   - This function scan PCI0 bus, if found any device on
*                     this bus it interrogate the Device for the information 
*                     it can discover.
*                     The fields with all information are the following: 
*    char            type[20];
*    unsigned int    deviceNum;
*    unsigned int    venID;                                            
*    unsigned int    deviceID;
*    unsigned int    bar0Base;
*    unsigned int    bar0Size;
*    unsigned int    bar1Base;
*    unsigned int    bar1Size;
*    unsigned int    bar2Base;
*    unsigned int    bar2Size;
*    unsigned int    bar3Base;
*    unsigned int    bar3Size;
*    unsigned int    bar4Base;
*    unsigned int    bar4Size;
*    unsigned int    bar5Base;
*    unsigned int    bar5Size;
* 
* Inputs:   PCI0_DEVICE* pci0Detect - Pointer to an array of STRUCT PCI0_DEVICE.
*           unsigned int numberOfElment - The PCI0_DEVICE Array length.
* Output:   None.
*********************************************************************/
void    pci0ScanDevices(PCI_DEVICE* pci0Detect,unsigned int numberOfElment) 
{
    PCI_DEVICE*             pci0ArrayPointer = pci0Detect;
    unsigned int            id;         /* PCI Configuration register 0x0.*/
    unsigned int            device;     /* device`s Counter.*/
    unsigned int            classCode;  /* PCI Configuration register 0x8 */
    unsigned int            arrayCounter = 0;
    unsigned int            memBaseAddress;
    unsigned int            memSize;
    unsigned int            pci0Cause;
    
    RESET_REG_BITS(PCI_0ERROR_CAUSE,BIT8); /* clears PCI_0 cause. */
    PCI0_MASTER_ENABLE(SELF);
    /* According to PCI REV 2.1 MAX agents allowed on the bus are -21- */
    for(device = 1 ; device < 22 ; device ++) 
    {
        id = pci0ReadConfigReg(PCI_DEVICE_AND_VENDOR_ID,device);
        GT_REG_READ(PCI_0ERROR_CAUSE,&pci0Cause);
        /* Clearing bit 8 of in the Cause Register 0x1d58 by writing 0. */
        RESET_REG_BITS(PCI_0ERROR_CAUSE,BIT8); /* clears PCI_0 cause. */
        if ( (id != 0xffffffff) && !(pci0Cause & BIT8) ) /* agent was found */
        {
            classCode = pci0ReadConfigReg(PCI_CLASS_CODE_AND_REVISION_ID,
                                          device);
            pci0ArrayPointer->deviceNum = device;
            pci0ArrayPointer->venID = ( id & 0xffff);
            pci0ArrayPointer->deviceID = ( ( id & 0xffff0000) >> 16 );
            /* BAR0 parameters */
            memBaseAddress = pci0ReadConfigReg(BAR0,device);
            pci0ArrayPointer->bar0Type = memBaseAddress & BIT0;
            pci0ArrayPointer->bar0Base = memBaseAddress & 0xfffff000;
            pci0WriteConfigReg(BAR0,device,0xffffffff);
            memSize = pci0ReadConfigReg(BAR0,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci0ArrayPointer->bar0Size = 0;
            }
            else
            {
                if (pci0ArrayPointer->bar0Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1;                   
                else                                   /* IO space */    
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci0ArrayPointer->bar0Size = memSize;
            }
            /* restore the previous value to BAR_0 base */
            pci0WriteConfigReg(BAR0,device,memBaseAddress);
            /* BAR1 parameters */
            memBaseAddress = pci0ReadConfigReg(BAR1,device);
            pci0ArrayPointer->bar1Type = memBaseAddress & BIT0;
            pci0ArrayPointer->bar1Base = memBaseAddress & 0xfffff000;
            pci0WriteConfigReg(BAR1,device,0xffffffff);
            memSize = pci0ReadConfigReg(BAR1,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci0ArrayPointer->bar1Size = 0;
            }
            else
            {
                if (pci0ArrayPointer->bar1Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1; 
                else                                   /* IO space */
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci0ArrayPointer->bar1Size = memSize;
            }
            /* restore the previous value to BAR_1 base */
            pci0WriteConfigReg(BAR1,device,memBaseAddress);
            /* BAR2 parameters */
            memBaseAddress = pci0ReadConfigReg(BAR2,device);
            pci0ArrayPointer->bar2Type = memBaseAddress & BIT0;
            pci0ArrayPointer->bar2Base = memBaseAddress & 0xfffff000;
            pci0WriteConfigReg(BAR2,device,0xffffffff);
            memSize = pci0ReadConfigReg(BAR2,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci0ArrayPointer->bar2Size = 0;
            }
            else
            {
                if (pci0ArrayPointer->bar2Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1; 
                else                                   /* IO space */
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci0ArrayPointer->bar2Size = memSize;
            }
            /* restore the previous value to BAR_2 base */
            pci0WriteConfigReg(BAR2,device,memBaseAddress);
            /* BAR3 parameters */
            memBaseAddress = pci0ReadConfigReg(BAR3,device);
            pci0ArrayPointer->bar3Type = memBaseAddress & BIT0;
            pci0ArrayPointer->bar3Base = memBaseAddress & 0xfffff000;
            pci0WriteConfigReg(BAR3,device,0xffffffff);
            memSize = pci0ReadConfigReg(BAR3,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci0ArrayPointer->bar3Size = 0;
            }
            else
            {
                if (pci0ArrayPointer->bar3Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1; 
                else                                   /* IO space */
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci0ArrayPointer->bar3Size = memSize;
            }
            /* restore the previous value to BAR_3 base */
            pci0WriteConfigReg(BAR3,device,memBaseAddress);
            /* BAR4 parameters */
            memBaseAddress = pci0ReadConfigReg(BAR4,device);
            pci0ArrayPointer->bar4Type = memBaseAddress & BIT0;
            pci0ArrayPointer->bar4Base = memBaseAddress & 0xfffff000;
            pci0WriteConfigReg(BAR4,device,0xffffffff);
            memSize = pci0ReadConfigReg(BAR4,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci0ArrayPointer->bar4Size = 0;
            }
            else
            {
                if (pci0ArrayPointer->bar4Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1; 
                else                                   /* IO space */
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci0ArrayPointer->bar4Size = memSize;
            }
            /* restore the previous value to BAR_4 base */
            pci0WriteConfigReg(BAR4,device,memBaseAddress);
            /* BAR5 parameters */
            memBaseAddress = pci0ReadConfigReg(BAR5,device);
            pci0ArrayPointer->bar5Type = memBaseAddress & BIT0;
            pci0ArrayPointer->bar5Base = memBaseAddress & 0xfffff000;
            pci0WriteConfigReg(BAR5,device,0xffffffff);
            memSize = pci0ReadConfigReg(BAR5,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci0ArrayPointer->bar5Size = 0;
            }
            else
            {
                if (pci0ArrayPointer->bar5Type == 1)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1; 
                else                                   /* IO space */
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci0ArrayPointer->bar5Size = memSize;
            }
            /* restore the previous value to BAR_5 base */
            pci0WriteConfigReg(BAR5,device,memBaseAddress);
            /* End of BARs Detection. */
            
            classCode =  ( (classCode & 0xff000000 ) >> 24 );
            switch(classCode) {
                case 0x0:
                    strcpy(pci0ArrayPointer->type,"Old generation device");
                    break;
                case 0x1:
                    strcpy(pci0ArrayPointer->type,"Mass storage controller");
                    break;
                case 0x2:
                    strcpy(pci0ArrayPointer->type,"Network controller");
                    break;
                case 0x3:
                    strcpy(pci0ArrayPointer->type,"Display controller");
                    break;
                case 0x4:
                    strcpy(pci0ArrayPointer->type,"Multimedia device");
                    break;
                case 0x5:
                    strcpy(pci0ArrayPointer->type,"Memory controller");
                    break;
                case 0x6:
                   strcpy(pci0ArrayPointer->type,"Bridge Device");
                    break;
                case 0x7:
                    strcpy(pci0ArrayPointer->type,"Simple Communication controllers");
                    break;
                case 0x8:
                    strcpy(pci0ArrayPointer->type,"Base system peripherals");
                    break;
                case 0x9:
                    strcpy(pci0ArrayPointer->type,"Input Devices");
                    break;
                case 0xa:
                    strcpy(pci0ArrayPointer->type,"Docking stations");
                    break;
                case 0xb:
                    strcpy(pci0ArrayPointer->type,"Processors");
                    break;
                case 0xc:
                    strcpy(pci0ArrayPointer->type,"Serial bus controllers");
                    break;
                case 0xd:
                    strcpy(pci0ArrayPointer->type,"Wireless controllers");
                    break;
                case 0xe:
                    strcpy(pci0ArrayPointer->type,"Intelligent I/O controllers");
                    break;
                case 0xf:
                    strcpy(pci0ArrayPointer->type,"Satellite communication controllers");
                    break;
                case 0x10:
                    strcpy(pci0ArrayPointer->type,"Encryption/Decryption controllers");
                    break;
                case 0x11:
                    strcpy(pci0ArrayPointer->type,"Data acquisition and \
                                            signal processing controllers");
                    break;
                default:
                    break;

            }
            arrayCounter++; /* point to the next element in the Array. */
            if(arrayCounter == numberOfElment) 
                return; /* When the Array is fully used, return. */
            /* Else, points to next free Element.*/
            pci0ArrayPointer = &pci0Detect[arrayCounter]; 
        }     
    }         
    pci0ArrayPointer->deviceNum = 0; /* 0 => End of List */
}


/********************************************************************
* pci1ScanDevices   - This function scan PCI1 bus, if found any device on
*                     this bus it interrogate the Device for the information 
*                     it can discover.
*                     The fields with all information are the following: 
*    char    type[20];
*    unsigned int    deviceNum;
*    unsigned int    venID;                                            
*    unsigned int    deviceID;
*    unsigned int    bar0Base;
*    unsigned int    bar0Size;
*    unsigned int    bar1Base;
*    unsigned int    bar1Size;
*    unsigned int    bar2Base;
*    unsigned int    bar2Size;
*    unsigned int    bar3Base;
*    unsigned int    bar3Size;
*    unsigned int    bar4Base;
*    unsigned int    bar4Size;
*    unsigned int    bar5Base;
*    unsigned int    bar5Size;
* 
* Inputs:   Pointer to an array of STRUCT PCI1_DEVICE. 
* Output:   None.
*********************************************************************/
void    pci1ScanDevices(PCI_DEVICE* pci1Detect,unsigned int numberOfElment) 
{
    PCI_DEVICE*    pci1ArrayPointer = pci1Detect;
    unsigned int    id;         /* PCI Configuration register 0x0.*/
    unsigned int    device;     /* device`s Counter.*/
    unsigned int    classCode;  /* PCI Configuration register 0x8 */
    unsigned int    arrayCounter=0;
    unsigned int    memBaseAddress;
    unsigned int    memSize;
    unsigned int    pci1Cause;

    RESET_REG_BITS(PCI_1ERROR_CAUSE,BIT8); /* clears PCI_0 cause. */
    PCI1_MASTER_ENABLE(SELF);
    /* According to PCI REV 2.1 MAX agents on the bus are -21- */
    for(device = 1 ; device < 22 ; device ++) 
    {
        id = pci1ReadConfigReg(PCI_DEVICE_AND_VENDOR_ID,device);
        GT_REG_READ(PCI_1ERROR_CAUSE,&pci1Cause);
        /* Clearing bit 8 of in the Cause Register 0x1d58 by writing 0. */
        RESET_REG_BITS(PCI_1ERROR_CAUSE,BIT8); /* clears PCI_1 cause. */
        if ( (id != 0xffffffff) && !(pci1Cause & 0x40000) )
        {
            classCode = pci1ReadConfigReg(PCI_CLASS_CODE_AND_REVISION_ID,device);
            pci1ArrayPointer->deviceNum = device;
            pci1ArrayPointer->venID = ( id & 0xffff);
            pci1ArrayPointer->deviceID = ( ( id & 0xffff0000) >> 16 );
            
            /* BAR0 parameters */
            memBaseAddress = pci1ReadConfigReg(BAR0,device);
            pci1ArrayPointer->bar0Type = memBaseAddress & BIT0;
            pci1ArrayPointer->bar0Base = memBaseAddress & 0xfffff000;
            pci1WriteConfigReg(BAR0,device,0xffffffff);
            memSize = pci1ReadConfigReg(BAR0,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci1ArrayPointer->bar0Size = 0;
            }
            else
            {
                if (pci1ArrayPointer->bar0Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1;                   
                else                                   /* IO space */    
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci1ArrayPointer->bar0Size = memSize;
            }
            /* restore the previous value to BAR_0 base */
            pci1WriteConfigReg(BAR0,device,memBaseAddress);
            /* BAR1 parameters */
            memBaseAddress = pci1ReadConfigReg(BAR1,device);
            pci1ArrayPointer->bar1Type = memBaseAddress & BIT0;
            pci1ArrayPointer->bar1Base = memBaseAddress & 0xfffff000;
            pci1WriteConfigReg(BAR1,device,0xffffffff);
            memSize = pci1ReadConfigReg(BAR1,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci1ArrayPointer->bar1Size = 0;
            }
            else
            {
                if (pci1ArrayPointer->bar1Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1;                   
                else                                   /* IO space */    
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci1ArrayPointer->bar1Size = memSize;
            }
            /* restore the previous value to BAR_1 base */
            pci1WriteConfigReg(BAR1,device,memBaseAddress);
            /* BAR2 parameters */
            memBaseAddress = pci1ReadConfigReg(BAR2,device);
            pci1ArrayPointer->bar2Type = memBaseAddress & BIT0;
            pci1ArrayPointer->bar2Base = memBaseAddress & 0xfffff000;
            pci1WriteConfigReg(BAR2,device,0xffffffff);
            memSize = pci1ReadConfigReg(BAR2,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci1ArrayPointer->bar2Size = 0;
            }
            else
            {
                if (pci1ArrayPointer->bar2Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1;                   
                else                                   /* IO space */    
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci1ArrayPointer->bar2Size = memSize;
            }
            /* restore the previous value to BAR_2 base */
            pci1WriteConfigReg(BAR2,device,memBaseAddress);
            /* BAR3 parameters */
            memBaseAddress = pci1ReadConfigReg(BAR3,device);
            pci1ArrayPointer->bar3Type = memBaseAddress & BIT0;
            pci1ArrayPointer->bar3Base = memBaseAddress & 0xfffff000;
            pci1WriteConfigReg(BAR3,device,0xffffffff);
            memSize = pci1ReadConfigReg(BAR3,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci1ArrayPointer->bar3Size = 0;
            }
            else
            {
                if (pci1ArrayPointer->bar3Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1;                   
                else                                   /* IO space */    
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci1ArrayPointer->bar3Size = memSize;
            }
            /* restore the previous value to BAR_3 base */
            pci1WriteConfigReg(BAR3,device,memBaseAddress);
            /* BAR4 parameters */
            memBaseAddress = pci1ReadConfigReg(BAR4,device);
            pci1ArrayPointer->bar4Type = memBaseAddress & BIT0;
            pci1ArrayPointer->bar4Base = memBaseAddress & 0xfffff000;
            pci1WriteConfigReg(BAR4,device,0xffffffff);
            memSize = pci1ReadConfigReg(BAR4,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci1ArrayPointer->bar4Size = 0;
            }
            else
            {
                if (pci1ArrayPointer->bar4Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1;                   
                else                                   /* IO space */    
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci1ArrayPointer->bar4Size = memSize;
            }
            /* restore the previous value to BAR_4 base */
            pci1WriteConfigReg(BAR4,device,memBaseAddress);
            /* BAR5 parameters */
            memBaseAddress = pci1ReadConfigReg(BAR5,device);
            pci1ArrayPointer->bar5Type = memBaseAddress & BIT0;
            pci1ArrayPointer->bar5Base = memBaseAddress & 0xfffff000;
            pci1WriteConfigReg(BAR5,device,0xffffffff);
            memSize = pci1ReadConfigReg(BAR5,device);
            if(memSize == 0) /* case of an empty BAR */
            {
                pci1ArrayPointer->bar5Size = 0;
            }
            else
            {
                if (pci1ArrayPointer->bar5Type == 0)   /* memory space */
                    memSize = ~(memSize & 0xfffffff0) + 1;                   
                else                                   /* IO space */    
                    memSize = ~(memSize & 0xfffffffc) + 1; 
                pci1ArrayPointer->bar5Size = memSize;
            }
            /* restore the previous value to BAR_5 base */
            pci1WriteConfigReg(BAR5,device,memBaseAddress);
            /* End of BARs Detection. */

            classCode =  ( (classCode & 0xff000000 ) >> 24 );

            switch(classCode) {
                case 0x0:
                    strcpy(pci1ArrayPointer->type,"Old generation device");
                    break;
                case 0x1:
                    strcpy(pci1ArrayPointer->type,"Mass storage controller");
                    break;
                case 0x2:
                    strcpy(pci1ArrayPointer->type,"Network controller");
                    break;
                case 0x3:
                    strcpy(pci1ArrayPointer->type,"Display controller");
                    break;
                case 0x4:
                    strcpy(pci1ArrayPointer->type,"Multimedia device");
                    break;
                case 0x5:
                    strcpy(pci1ArrayPointer->type,"Memory controller");
                    break;
                case 0x6:
                    strcpy(pci1ArrayPointer->type,"Bridge Device");
                    break;
                case 0x7:
                    strcpy(pci1ArrayPointer->type,"Simple Communication controllers");
                    break;
                case 0x8:
                    strcpy(pci1ArrayPointer->type,"Base system peripherals");
                    break;
                case 0x9:
                    strcpy(pci1ArrayPointer->type,"Input Devices");
                   break;
                case 0xa:
                    strcpy(pci1ArrayPointer->type,"Docking stations");
                    break;
                case 0xb:
                    strcpy(pci1ArrayPointer->type,"Processors");
                    break;
                case 0xc:
                    strcpy(pci1ArrayPointer->type,"Serial bus controllers");
                    break;
                case 0xd:
                    strcpy(pci1ArrayPointer->type,"Wireless controllers");
                    break;
                case 0xe:
                    strcpy(pci1ArrayPointer->type,"Intelligent I/O controllers");
                    break;
                case 0xf:
                    strcpy(pci1ArrayPointer->type,"Satellite communication controllers");
                    break;
                case 0x10:
                    strcpy(pci1ArrayPointer->type,"Encryption/Decryption controllers");
                    break;
                case 0x11:
                    strcpy(pci1ArrayPointer->type,"Data acquisition and \
                                                signal processing controllers");
                    break;
            }
            arrayCounter++; /* point to the next element in the Array. */
            if(arrayCounter == numberOfElment) 
                return; /* When the Array is fully used, return. */
            /* Else, points to next free Element.*/
            pci1ArrayPointer = &pci1Detect[arrayCounter]; 
        }     
    }         
    pci1ArrayPointer->deviceNum = 0; /* 0 => End of List */
}

/********************************************************************
* pci0WriteConfigReg - Write to a PCI configuration register
*                    - Make sure the GT is configured as a master before writing
*                      to another device on the PCI.
*                    - The function takes care of Big/Little endian conversion.
*
*
* Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec 
*                   (or any other PCI device spec)
*           pciDevNum: The device number needs to be addressed.                
*
*  Configuration Address 0xCF8:
*
*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
*  |congif|Reserved|  Bus |Device|Function|Register|00|
*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
*
*********************************************************************/
void pci0WriteConfigReg(unsigned int regOffset,unsigned int pciDevNum,unsigned int data)
{                                                      
   	volatile unsigned int DataForRegCf8;
    unsigned int functionNum;
    unsigned int busNum = 0;

    if(pciDevNum > 32) /* illegal device Number */
        return;
    if(pciDevNum == SELF) /* configure our configuration space. */
    {
        pciDevNum = (GTREGREAD(PCI_0P2P_CONFIGURATION) >> 24) & 0x1f;
        busNum = GTREGREAD(PCI_0P2P_CONFIGURATION) & 0xff0000;
    }
   	functionNum =  regOffset & 0x00000700;
    pciDevNum = pciDevNum << 11;
    regOffset = regOffset & 0xfc;
   	DataForRegCf8 = ( regOffset | pciDevNum | functionNum | busNum) | BIT31;
    GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS,DataForRegCf8);
    GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,data);
}

/********************************************************************
* pci1WriteConfigReg - Write to a PCI configuration register
*                   - Make sure the GT is configured as a master before writing
*                     to another device on the PCI.
*                   - The function takes care of Big/Little endian conversion.
* Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec 
*                   (or any other PCI device spec)
*           pciDevNum: The device number needs to be addressed.                
*
*  Configuration Address 0xCF8:
*
*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
*  |congif|Reserved|  Bus |Device|Function|Register|00|
*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
*
*********************************************************************/
void pci1WriteConfigReg(unsigned int regOffset,unsigned int pciDevNum,unsigned int data)
{                                                      
   	volatile unsigned int DataForRegCf8;
    unsigned int functionNum;
    unsigned int busNum = 0;

    if(pciDevNum > 32) /* illegal device Number */
        return;
    if(pciDevNum == SELF) /* configure our configuration space. */
    {
        pciDevNum = (GTREGREAD(PCI_1P2P_CONFIGURATION) >> 24) & 0x1f;
        busNum = GTREGREAD(PCI_1P2P_CONFIGURATION) & 0xff0000;
    }
   	functionNum = regOffset & 0x00000700;
    pciDevNum = pciDevNum << 11;
    regOffset = regOffset & 0xfc;
    DataForRegCf8 = ( regOffset | pciDevNum | functionNum | busNum) | BIT31;
    GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS,DataForRegCf8);
    GT_REG_WRITE(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,data);
}

/********************************************************************
* pci0ReadConfigReg  - Read from a PCI0 configuration register
*                    - Make sure the GT is configured as a master before reading
*                     from another device on the PCI.
*                   - The function takes care of Big/Little endian conversion.
* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
*                        spec)
*           pciDevNum: The device number needs to be addressed.                
* RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
*                 cause register to make sure the data is valid
*
*  Configuration Address 0xCF8:
*
*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
*  |congif|Reserved|  Bus |Device|Function|Register|00|
*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
*
*********************************************************************/
unsigned int pci0ReadConfigReg (unsigned int regOffset,unsigned int pciDevNum)
{
    volatile unsigned int DataForRegCf8;
   	unsigned int data;
    unsigned int functionNum;
    unsigned int busNum = 0;
   	
    if(pciDevNum > 32) /* illegal device Number */
        return 0xffffffff;
    if(pciDevNum == SELF) /* configure our configuration space. */
    {
        pciDevNum = (GTREGREAD(PCI_0P2P_CONFIGURATION) >> 24) & 0x1f;
        busNum = GTREGREAD(PCI_0P2P_CONFIGURATION) & 0xff0000;
    }
    functionNum = regOffset & 0x00000700;
   	pciDevNum = pciDevNum << 11;
    regOffset = regOffset & 0xfc;
    DataForRegCf8 = (regOffset | pciDevNum | functionNum | busNum) | BIT31 ;
    GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS,DataForRegCf8);
    GT_REG_READ(PCI_0CONFIGURATION_ADDRESS, &data);
    if (data != DataForRegCf8)
        return 0xffffffff;
    GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, &data);
    return data;
}

/********************************************************************
* pci1ReadConfigReg  - Read from a PCI1 configuration register
*                    - Make sure the GT is configured as a master before reading
*                     from another device on the PCI.
*                   - The function takes care of Big/Little endian conversion.
* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
*                        spec)
*           pciDevNum: The device number needs to be addressed.                
* RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
*                 cause register to make sure the data is valid
*
*  Configuration Address 0xCF8:
*
*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
*  |congif|Reserved|  Bus |Device|Function|Register|00|
*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
*
*********************************************************************/
unsigned int pci1ReadConfigReg (unsigned int regOffset,unsigned int pciDevNum)
{
    volatile unsigned int DataForRegCf8;
   	unsigned int data;
    unsigned int functionNum;
    unsigned int busNum = 0;
   	
    if(pciDevNum > 32) /* illegal device Number */
        return 0xffffffff;
    if(pciDevNum == SELF) /* configure our configuration space. */
    {
        pciDevNum = (GTREGREAD(PCI_1P2P_CONFIGURATION) >> 24) & 0x1f;
        busNum = GTREGREAD(PCI_1P2P_CONFIGURATION) & 0xff0000;
    }
    functionNum = regOffset & 0x00000700;
   	pciDevNum = pciDevNum << 11;
    regOffset = regOffset & 0xff;
    DataForRegCf8 = (regOffset | pciDevNum | functionNum | busNum) | BIT31;
    GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS,DataForRegCf8);
    GT_REG_READ(PCI_1CONFIGURATION_ADDRESS, &data);
    if (data != DataForRegCf8)
        return 0xffffffff;
    GT_REG_READ(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER, &data);
    return data;
}

/********************************************************************
* pci0OverBridgeWriteConfigReg - Write to a PCI configuration register where  
*                                the agent is placed on another Bus. For more 
*                                information read P2P in the PCI spec.
*
* Inputs:   unsigned int regOffset - The register offset as it apears in the  
*           GT spec (or any other PCI device spec).
*           unsigned int pciDevNum - The device number needs to be addressed.
*           unsigned int busNum - On which bus does the Target agent connect
*                                 to.  
*           unsigned int data - data to be written.              
*
*  Configuration Address 0xCF8:
*
*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
*  |congif|Reserved|  Bus |Device|Function|Register|01|
*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
*
*  The configuration Address is configure as type-I (bits[1:0] = '01') due to
*   PCI spec referring to P2P.   
*
*********************************************************************/
void pci0OverBridgeWriteConfigReg(unsigned int regOffset,
                                  unsigned int pciDevNum,
                                  unsigned int busNum,unsigned int data)
{
   	unsigned int   DataForRegCf8;
    unsigned int   functionNum;

   	functionNum =  regOffset & 0x00000700;
    pciDevNum = pciDevNum << 11;
    regOffset = regOffset & 0xff;
    busNum = busNum << 16;
    if(pciDevNum == SELF) /* This board */
    {
        DataForRegCf8 = ( regOffset | pciDevNum | functionNum) | BIT0;
    }
    else
    {
        DataForRegCf8 = ( regOffset | pciDevNum | functionNum | busNum) | 
            BIT31 | BIT0;
    }
    GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS,DataForRegCf8);
    if(pciDevNum == SELF) /* This board */
    {
        GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,data);
    }
    else /* configuration Transaction over the pci. */
    {
        /* The PCI is working in LE Mode So it swap the Data. */
        GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,WORD_SWAP(data));
    }
}

/********************************************************************
* pci1OverBridgeWriteConfigReg - Write to a PCI configuration register where  
*                                the agent is placed on another Bus. For more 
*                                information read P2P in the PCI spec.
*
* Inputs:   unsigned int regOffset - The register offset as it apears in the  
*           GT spec (or any other PCI device spec).
*           unsigned int pciDevNum - The device number needs to be addressed.
*           unsigned int busNum - On which bus does the Target agent connect
*                                 to.  
*           unsigned int data - data to be written.              
*
*  Configuration Address 0xCF8:
*
*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
*  |congif|Reserved|  Bus |Device|Function|Register|01|
*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
*
*  The configuration Address is configure as type-I (bits[1:0] = '01') due to
*   PCI spec referring to P2P.   
*
*********************************************************************/
void pci1OverBridgeWriteConfigReg(unsigned int regOffset,
                                  unsigned int pciDevNum,
                                  unsigned int busNum,unsigned int data)
{
   	unsigned int   DataForRegCf8;
    unsigned int   functionNum;

   	functionNum =  regOffset & 0x00000700;
    pciDevNum = pciDevNum << 11;
    regOffset = regOffset & 0xff;
    busNum = busNum << 16;
    if(pciDevNum == SELF) /* This board */
    {
        DataForRegCf8 = ( regOffset | pciDevNum | functionNum | 0x80) | BIT31;
        GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS,DataForRegCf8);
    }
    else
    {
        DataForRegCf8 = ( regOffset | pciDevNum | functionNum | busNum) | 
            BIT31 | BIT0;
        GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS,DataForRegCf8);
    }
    if(pciDevNum == SELF) /* This board */
    {
        GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,data);
    }
    else /* configuration Transaction over the pci. */
    {
        /* The PCI is working in LE Mode So it swap the Data. */
        GT_REG_WRITE(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,WORD_SWAP(data));
    }
}

/********************************************************************
* pci0OverBridgeReadConfigReg  - Read from a PCI0 configuration register where  
*                                the agent target locate on another PCI bus.
*                              - Make sure the GT is configured as a master  
*                                before reading from another device on the PCI.
*                              - The function takes care of Big/Little endian 
*                                conversion.
* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
*                        spec). (configuration register offset.)
*           pciDevNum: The device number needs to be addressed.
*           busNum: the Bus number where the agent is place.               
* RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
*                 cause register to make sure the data is valid
*
*  Configuration Address 0xCF8:
*
*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
*  |congif|Reserved|  Bus |Device|Function|Register|01|
*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
*
*********************************************************************/
unsigned int pci0OverBridgeReadConfigReg(unsigned int regOffset,
                                         unsigned int pciDevNum,
                                         unsigned int busNum)
{
    unsigned int DataForRegCf8;
   	unsigned int data;
    unsigned int functionNum;      
   	
    functionNum = regOffset & 0x00000700;
   	pciDevNum = pciDevNum << 11;
    regOffset = regOffset & 0xff;
    busNum = busNum << 16;
    if (pciDevNum == SELF) /* This board */
    {
        DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31 ;
    }
    else /* agent on another bus */
    {
        DataForRegCf8 = (regOffset | pciDevNum | functionNum | busNum) | 
        BIT0 | BIT31 ;
    }
    GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS,DataForRegCf8);
    if (pciDevNum == SELF) /* This board */
   	{
        GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, &data);
    	return data;
    }
    else /* The PCI is working in LE Mode So it swap the Data. */
    {
        GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, &data);
    	return WORD_SWAP(data);
    }
}

/********************************************************************
* pci1OverBridgeReadConfigReg  - Read from a PCI_1 configuration register where  
*                                the agent target locate on another PCI bus.
*                              - Make sure the GT is configured as a master  
*                                before reading from another device on the PCI.
*                              - The function takes care of Big/Little endian 
*                                conversion.
* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
*                        spec). (configuration register offset.)
*           pciDevNum: The device number needs to be addressed.
*           busNum: the Bus number where the agent is place.               
* RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
*                 cause register to make sure the data is valid
*
*  Configuration Address 0xCF8:
*
*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
*  |congif|Reserved|  Bus |Device|Function|Register|01|
*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
*
*********************************************************************/
unsigned int pci1OverBridgeReadConfigReg(unsigned int regOffset,
                                         unsigned int pciDevNum,
                                         unsigned int busNum)
{
    unsigned int DataForRegCf8;
   	unsigned int data;
    unsigned int functionNum;      
   	
    functionNum = regOffset & 0x00000700;
   	pciDevNum = pciDevNum << 11;
    regOffset = regOffset & 0xff;
    busNum = busNum << 16;
    if (pciDevNum == SELF) /* This board */
    {
        DataForRegCf8 = (regOffset | pciDevNum | functionNum) | 0x80 | BIT31 ;
        GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS,DataForRegCf8);
    }
    else /* agent on another bus */
    {
        DataForRegCf8 = (regOffset | pciDevNum | functionNum | busNum) | 
        BIT0 | BIT31 ;
        GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS,DataForRegCf8);
    }
    GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS,DataForRegCf8);
    if (pciDevNum == SELF) /* This board */
   	{
        GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, &data);
    	return data;
    }
    else /* The PCI is working in LE Mode So it swap the Data. */
    {
        GT_REG_READ(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER, &data);
    	return WORD_SWAP(data);
    }
}

/********************************************************************
* pci0MapIOspace - Maps PCI_0 IO space from the CPU side.
*
*
* Inputs: base and length of pci0 IO
* Return: N/A
*********************************************************************/
void pci0MapIOspace(unsigned int pci0IoBase,unsigned int pci0IoLength)
{
    unsigned int pci0IoTop = (unsigned int)(pci0IoBase + pci0IoLength);
    unsigned int currentLow;

    GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS,&currentLow);
    pci0IoBase 	 = pci0IoBase >> 20;
    pci0IoBase = (pci0IoBase & 0xffff) | (currentLow & 0xffff0000);
    pci0IoTop  = pci0IoTop >> 20;   
    GT_REG_WRITE(PCI_0I_O_LOW_DECODE_ADDRESS,0xffff);
    if(pci0IoLength != 0)
    {
        GT_REG_WRITE(PCI_0I_O_HIGH_DECODE_ADDRESS,pci0IoTop - 1);
        GT_REG_WRITE(PCI_0I_O_LOW_DECODE_ADDRESS,pci0IoBase);
    }
    else
    {
        GT_REG_WRITE(PCI_0I_O_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci1MapIOspace - Maps PCI_1 IO space for the master.
* Inputs: base and length of pci1Io
*********************************************************************/
void pci1MapIOspace(unsigned int pci1IoBase,unsigned int pci1IoLength)
{
    unsigned int pci1IoTop = (unsigned int)(pci1IoBase + pci1IoLength);
    unsigned int currentLow;

    GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS,&currentLow);
    pci1IoBase 	 = pci1IoBase >> 20;
    pci1IoBase = (pci1IoBase & 0xffff) | (currentLow & 0xffff0000);
    pci1IoTop  = pci1IoTop >> 20;   
    GT_REG_WRITE(PCI_1I_O_LOW_DECODE_ADDRESS,0xffff);
    if(pci1IoLength != 0)
    {
        GT_REG_WRITE(PCI_1I_O_HIGH_DECODE_ADDRESS,pci1IoTop - 1);
        GT_REG_WRITE(PCI_1I_O_LOW_DECODE_ADDRESS,pci1IoBase);
    }
    else
    {
        GT_REG_WRITE(PCI_1I_O_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci0MapMemory0space - Maps PCI_0 memory0 space for the master.
* Inputs: base and length of pci0Mem0
*********************************************************************/
void pci0MapMemory0space(unsigned int pci0Mem0Base,unsigned int pci0Mem0Length)
{
    unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length;
    unsigned int currentLow;

    GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS,&currentLow);
    pci0Mem0Base = pci0Mem0Base >> 20;
    pci0Mem0Base = (pci0Mem0Base & 0xffff) | (currentLow & 0xffff0000);
    pci0Mem0Top  = pci0Mem0Top >> 20;   
    GT_REG_WRITE(PCI_0MEMORY0_LOW_DECODE_ADDRESS,0xffff);
    if(pci0Mem0Length != 0)
    {
        GT_REG_WRITE(PCI_0MEMORY0_HIGH_DECODE_ADDRESS,pci0Mem0Top - 1);
        GT_REG_WRITE(PCI_0MEMORY0_LOW_DECODE_ADDRESS,pci0Mem0Base);
    }
    else
    {
        GT_REG_WRITE(PCI_0MEMORY0_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci1MapMemory0space - Maps PCI_1 memory0 space for the master.
* Inputs: base and length of pci1Mem0
*********************************************************************/
void pci1MapMemory0space(unsigned int pci1Mem0Base,unsigned int pci1Mem0Length)
{
    unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length;
    unsigned int currentLow;

    GT_REG_READ(PCI_1MEMORY0_LOW_DECODE_ADDRESS,&currentLow);
    pci1Mem0Base = pci1Mem0Base >> 20;
    pci1Mem0Base = (pci1Mem0Base & 0xffff) | (currentLow & 0xffff0000);
    pci1Mem0Top  = pci1Mem0Top >> 20;   
    GT_REG_WRITE(PCI_1MEMORY0_LOW_DECODE_ADDRESS,0xffff);
    if(pci1Mem0Length != 0)
    {
        GT_REG_WRITE(PCI_1MEMORY0_HIGH_DECODE_ADDRESS,pci1Mem0Top - 1);
        GT_REG_WRITE(PCI_1MEMORY0_LOW_DECODE_ADDRESS,pci1Mem0Base);
    }
    else
    {
        GT_REG_WRITE(PCI_1MEMORY0_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci0MapMemory1space - Maps PCI_0 memory1 space for the master.
* Inputs: base and length of pci0Mem1
*********************************************************************/
void pci0MapMemory1space(unsigned int pci0Mem1Base,unsigned int pci0Mem1Length)
{
    unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length;
    unsigned int currentLow;

    GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS,&currentLow);
    pci0Mem1Base = pci0Mem1Base >> 20;
    pci0Mem1Base = (pci0Mem1Base & 0xffff) | (currentLow & 0xffff0000);
    pci0Mem1Top  = pci0Mem1Top >> 20;   
    GT_REG_WRITE(PCI_0MEMORY1_LOW_DECODE_ADDRESS,0xffff);
    if(pci0Mem1Length != 0)
    {
        GT_REG_WRITE(PCI_0MEMORY1_HIGH_DECODE_ADDRESS,pci0Mem1Top - 1);
        GT_REG_WRITE(PCI_0MEMORY1_LOW_DECODE_ADDRESS,pci0Mem1Base);
    }
    else
    {
        GT_REG_WRITE(PCI_0MEMORY1_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci1MapMemory1space - Maps PCI_1 memory1 space for the master.
* Inputs: base and length of pci1Mem1
*********************************************************************/
void pci1MapMemory1space(unsigned int pci1Mem1Base,unsigned int pci1Mem1Length)
{
    unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length;
    unsigned int currentLow;

    GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS,&currentLow);
    pci1Mem1Base = pci1Mem1Base >> 20;
    pci1Mem1Base = (pci1Mem1Base & 0xffff) | (currentLow & 0xffff0000);
    pci1Mem1Top  = pci1Mem1Top >> 20;   
    GT_REG_WRITE(PCI_1MEMORY1_LOW_DECODE_ADDRESS,0xffff);
    if(pci1Mem1Length != 0)
    {
        GT_REG_WRITE(PCI_1MEMORY1_HIGH_DECODE_ADDRESS,pci1Mem1Top - 1);
        GT_REG_WRITE(PCI_1MEMORY1_LOW_DECODE_ADDRESS,pci1Mem1Base);
    }
    else
    {
        GT_REG_WRITE(PCI_1MEMORY1_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci0MapMemory2space - Maps PCI_0 memory2 space for the master.
* Inputs: base and length of pci0Mem2
*********************************************************************/
void pci0MapMemory2space(unsigned int pci0Mem2Base,unsigned int pci0Mem2Length)
{
    unsigned int pci0Mem2Top = pci0Mem2Base + pci0Mem2Length;
    unsigned int currentLow;

    GT_REG_READ(PCI_0MEMORY2_LOW_DECODE_ADDRESS,&currentLow);
    pci0Mem2Base = pci0Mem2Base >> 20;
    pci0Mem2Base = (pci0Mem2Base & 0xffff) | (currentLow & 0xffff0000);
    pci0Mem2Top  = pci0Mem2Top >> 20;   
    GT_REG_WRITE(PCI_0MEMORY2_LOW_DECODE_ADDRESS,0xffff);
    if(pci0Mem2Length != 0)
    {
        GT_REG_WRITE(PCI_0MEMORY2_HIGH_DECODE_ADDRESS,pci0Mem2Top - 1);
        GT_REG_WRITE(PCI_0MEMORY2_LOW_DECODE_ADDRESS,pci0Mem2Base);
    }
    else
    {
        GT_REG_WRITE(PCI_0MEMORY2_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci1MapMemory2space - Maps PCI_1 memory2 space for the master.
* Inputs: base and length of pci1Mem2
*********************************************************************/
void pci1MapMemory2space(unsigned int pci1Mem2Base,unsigned int pci1Mem2Length)
{
    unsigned int pci1Mem2Top = pci1Mem2Base + pci1Mem2Length;
    unsigned int currentLow;

    GT_REG_READ(PCI_1MEMORY2_LOW_DECODE_ADDRESS,&currentLow);
    pci1Mem2Base = pci1Mem2Base >> 20;
    pci1Mem2Base = (pci1Mem2Base & 0xffff) | (currentLow & 0xffff0000);
    pci1Mem2Top  = pci1Mem2Top >> 20;   
    GT_REG_WRITE(PCI_1MEMORY2_LOW_DECODE_ADDRESS,0xffff);
    if(pci1Mem2Length != 0)
    {
        GT_REG_WRITE(PCI_1MEMORY2_HIGH_DECODE_ADDRESS,pci1Mem2Top - 1);
        GT_REG_WRITE(PCI_1MEMORY2_LOW_DECODE_ADDRESS,pci1Mem2Base);
    }
    else
    {
        GT_REG_WRITE(PCI_1MEMORY2_HIGH_DECODE_ADDRESS,0x0);
    }
}


/********************************************************************
* pci0MapMemory3space - Maps PCI_0 memory3 space for the master.
* Inputs: base and length of pci0Mem3
*********************************************************************/
void pci0MapMemory3space(unsigned int pci0Mem3Base,unsigned int pci0Mem3Length)
{
    unsigned int pci0Mem3Top = pci0Mem3Base + pci0Mem3Length;
    unsigned int currentLow;

    GT_REG_READ(PCI_0MEMORY3_LOW_DECODE_ADDRESS,&currentLow);
    pci0Mem3Base = pci0Mem3Base >> 20;
    pci0Mem3Base = (pci0Mem3Base & 0xffff) | (currentLow & 0xffff0000);
    pci0Mem3Top  = pci0Mem3Top >> 20;   
    GT_REG_WRITE(PCI_0MEMORY3_LOW_DECODE_ADDRESS,0xffff);
    if(pci0Mem3Length != 0)
    {
        GT_REG_WRITE(PCI_0MEMORY3_HIGH_DECODE_ADDRESS,pci0Mem3Top - 1);
        GT_REG_WRITE(PCI_0MEMORY3_LOW_DECODE_ADDRESS,pci0Mem3Base);
    }
    else
    {
        GT_REG_WRITE(PCI_0MEMORY3_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci1MapMemory3space - Maps PCI_1 memory3 space for the master.
* Inputs: base and length of pci1Mem3
*********************************************************************/
void pci1MapMemory3space(unsigned int pci1Mem3Base,unsigned int pci1Mem3Length)
{
    unsigned int pci1Mem3Top = pci1Mem3Base + pci1Mem3Length;
    unsigned int currentLow;

    GT_REG_READ(PCI_1MEMORY3_LOW_DECODE_ADDRESS,&currentLow);
    pci1Mem3Base = pci1Mem3Base >> 20;
    pci1Mem3Base = (pci1Mem3Base & 0xffff) | (currentLow & 0xffff0000);
    pci1Mem3Top  = pci1Mem3Top >> 20;   
    GT_REG_WRITE(PCI_1MEMORY3_LOW_DECODE_ADDRESS,0xffff);
    if(pci1Mem3Length != 0)
    {
        GT_REG_WRITE(PCI_1MEMORY3_HIGH_DECODE_ADDRESS,pci1Mem3Top - 1);
        GT_REG_WRITE(PCI_1MEMORY3_LOW_DECODE_ADDRESS,pci1Mem3Base);
    }
    else
    {
        GT_REG_WRITE(PCI_1MEMORY3_HIGH_DECODE_ADDRESS,0x0);
    }
}

/********************************************************************
* pci0GetIOspaceBase - Return PCI_0 IO Base Address.
* Inputs: N/A
* Returns: PCI0 IO Base Address.
*********************************************************************/
unsigned int pci0GetIOspaceBase()
{
    unsigned int base;

    GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci0GetIOspaceSize - Return PCI_0 IO Bar Size.
* Inputs: N/A
* Returns: PCI0 IO Bar Size.
*********************************************************************/
unsigned int pci0GetIOspaceSize()
{
    unsigned int top,base,size;

    GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_0I_O_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci0GetMemory0Base - Return PCI_0 Memory 0 Base Address.
* Inputs: N/A
* Returns: PCI0 Memory 0 Base Address.
*********************************************************************/
unsigned int pci0GetMemory0Base()
{
    unsigned int base;

    GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci0GetMemory0Size - Return PCI_0 Memory 0 Bar Size.
* Inputs: N/A
* Returns: PCI0 Memory 0 Bar Size.
*********************************************************************/
unsigned int pci0GetMemory0Size()
{
    unsigned int top,base,size;

    GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_0MEMORY0_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci0GetMemory1Base - Return PCI_0 Memory 1 Base Address.
* Inputs: N/A
* Returns: PCI0 Memory 1 Base Address.
*********************************************************************/
unsigned int pci0GetMemory1Base()
{
    unsigned int base;

    GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci0GetMemory1Size - Return PCI_0 Memory 1 Bar Size.
* Inputs: N/A
* Returns: PCI0 Memory 1 Bar Size.
*********************************************************************/
unsigned int pci0GetMemory1Size()
{
    unsigned int top,base,size;
    GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_0MEMORY1_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci0GetMemory2Base - Return PCI_0 Memory 2 Base Address.
* Inputs: N/A
* Returns: PCI0 Memory 2 Base Address.
*********************************************************************/
unsigned int pci0GetMemory2Base()
{
    unsigned int base;
    GT_REG_READ(PCI_0MEMORY2_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci0GetMemory2Size - Return PCI_0 Memory 2 Bar Size.
* Inputs: N/A
* Returns: PCI0 Memory 2 Bar Size.
*********************************************************************/
unsigned int pci0GetMemory2Size()
{
    unsigned int top,base,size;
    GT_REG_READ(PCI_0MEMORY2_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_0MEMORY2_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci0GetMemory3Base - Return PCI_0 Memory 3 Base Address.
* Inputs: N/A
* Returns: PCI0 Memory 3 Base Address.
*********************************************************************/
unsigned int pci0GetMemory3Base()
{
    unsigned int base;
    GT_REG_READ(PCI_0MEMORY3_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci0GetMemory3Size - Return PCI_0 Memory 3 Bar Size.
* Inputs: N/A
* Returns: PCI0 Memory 3 Bar Size.
*********************************************************************/
unsigned int pci0GetMemory3Size()
{
    unsigned int top,base,size;
    GT_REG_READ(PCI_0MEMORY3_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_0MEMORY3_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci1GetIOspaceBase - Return PCI_1 IO Base Address.
* Inputs: N/A
* Returns: PCI1 IO Base Address.
*********************************************************************/
unsigned int pci1GetIOspaceBase()
{
    unsigned int base;
    GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci1GetIOspaceSize - Return PCI_1 IO Bar Size.
* Inputs: N/A
* Returns: PCI1 IO Bar Size.
*********************************************************************/
unsigned int pci1GetIOspaceSize()
{
    unsigned int top,base,size;
    GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_1I_O_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci1GetMemory0Base - Return PCI_1 Memory 0 Base Address.
* Inputs: N/A
* Returns: PCI1 Memory 0 Base Address.
*********************************************************************/
unsigned int pci1GetMemory0Base()
{
    unsigned int base;
    GT_REG_READ(PCI_1MEMORY0_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci1GetMemory0Size - Return PCI_1 Memory 0 Bar Size.
* Inputs: N/A
* Returns: PCI1 Memory 0 Bar Size.
*********************************************************************/
unsigned int pci1GetMemory0Size()
{
    unsigned int top,base,size;
    GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci1GetMemory1Base - Return PCI_1 Memory 1 Base Address.
* Inputs: N/A
* Returns: PCI1 Memory 1 Base Address.
*********************************************************************/
unsigned int pci1GetMemory1Base()
{
    unsigned int base;
    GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci1GetMemory1Size - Return PCI_1 Memory 1 Bar Size.
* Inputs: N/A
* Returns: PCI1 Memory 1 Bar Size.
*********************************************************************/
unsigned int pci1GetMemory1Size()
{
    unsigned int top,base,size;
    GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci1GetMemory1Base - Return PCI_1 Memory 2 Base Address.
* Inputs: N/A
* Returns: PCI1 Memory 2 Base Address.
*********************************************************************/
unsigned int pci1GetMemory2Base()
{
    unsigned int base;
    GT_REG_READ(PCI_1MEMORY2_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci1GetMemory1Size - Return PCI_1 Memory 2 Bar Size.
* Inputs: N/A
* Returns: PCI1 Memory 2 Bar Size.
*********************************************************************/
unsigned int pci1GetMemory2Size()
{
    unsigned int top,base,size;
    GT_REG_READ(PCI_1MEMORY2_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_1MEMORY2_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci1GetMemory3Base - Return PCI_1 Memory 3 Base Address.
* Inputs: N/A
* Returns: PCI1 Memory 3 Base Address.
*********************************************************************/
unsigned int pci1GetMemory3Base()
{
    unsigned int base;
    GT_REG_READ(PCI_1MEMORY3_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    return base;
}

/********************************************************************
* pci1GetMemory3Size - Return PCI_1 Memory 3 Bar Size.
* Inputs: N/A
* Returns: PCI1 Memory 3 Bar Size.
*********************************************************************/
unsigned int pci1GetMemory3Size()
{
    unsigned int top,base,size;
    GT_REG_READ(PCI_1MEMORY3_LOW_DECODE_ADDRESS,&base);
    base = base << 20;
    GT_REG_READ(PCI_1MEMORY3_HIGH_DECODE_ADDRESS,&top);
    top = (top << 20);
    size = (top - base);
    size = size | 0xfffff; 
    return (size + 1);
}

/********************************************************************
* pci0ScanSelfBars - update in PCI_SELF_BARS struct all bars base and sizes.
*
* Inputs: PCI_SELF_BARS *pci0SelfBars - the struct which the data will be update
*                                       in.
*********************************************************************/
void pci0ScanSelfBars(PCI_SELF_BARS *pci0SelfBars)
{
    unsigned int size;
    pci0SelfBars->SCS0Base = pci0ReadConfigReg(PCI_SCS_0_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0SCS_0_BANK_SIZE);
    if(size)
        pci0SelfBars->SCS0Size = size + 0x1000;
    else
        pci0SelfBars->SCS0Size = 0;
    pci0SelfBars->SCS1Base = pci0ReadConfigReg(PCI_SCS_1_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0SCS_1_BANK_SIZE);
    if(size)
        pci0SelfBars->SCS1Size = size + 0x1000;
    else
        pci0SelfBars->SCS1Size = 0;
    pci0SelfBars->SCS2Base = pci0ReadConfigReg(PCI_SCS_2_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0SCS_2_BANK_SIZE);
    if(size)
        pci0SelfBars->SCS2Size = size + 0x1000;
    else
        pci0SelfBars->SCS2Size = 0;
    pci0SelfBars->SCS3Base = pci0ReadConfigReg(PCI_SCS_3_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0SCS_3_BANK_SIZE);
    if(size)
        pci0SelfBars->SCS3Size = size + 0x1000;
    else
        size = 0;
    pci0SelfBars->CS0Base = pci0ReadConfigReg(PCI_CS_0_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_0_BANK_SIZE);
    if(size)
        pci0SelfBars->CS0Size = size + 0x1000;
    else
        pci0SelfBars->CS0Size = 0;
    pci0SelfBars->CS1Base = pci0ReadConfigReg(PCI_CS_1_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_1_BANK_SIZE);
    if(size)
        pci0SelfBars->CS1Size = size + 0x1000;
    else
        pci0SelfBars->CS1Size = 0;
    pci0SelfBars->CS2Base = pci0ReadConfigReg(PCI_CS_2_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_2_BANK_SIZE);
    if(size)
        pci0SelfBars->CS2Size = size + 0x1000;
    else
        pci0SelfBars->CS2Size = 0;
    pci0SelfBars->CS3Base = pci0ReadConfigReg(PCI_CS_3_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_3_BANK_SIZE);
    if(size)
        pci0SelfBars->CS3Size = size + 0x1000;
    else
        pci0SelfBars->CS3Size = 0;
    pci0SelfBars->CSBootBase = pci0ReadConfigReg(PCI_BOOTCS_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_BOOT_BANK_SIZE);
    if(size)
        pci0SelfBars->CSBootSize = size + 0x1000;
    else
        pci0SelfBars->CSBootSize = 0;
    pci0SelfBars->internalMemBase = pci0ReadConfigReg(
        PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,SELF) &
                             0xfffff000;
    pci0SelfBars->internalIOBase = pci0ReadConfigReg(
        PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,SELF) &
                             0xfffff000;
    pci0SelfBars->P2PMem0Base = pci0ReadConfigReg(PCI_P2P_MEM0_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0P2P_MEM0_BAR_SIZE);
    if(size)
        pci0SelfBars->P2PMem0Size = size + 0x1000;
    else
        pci0SelfBars->P2PMem0Size = 0;
    pci0SelfBars->P2PMem1Base = pci0ReadConfigReg(PCI_P2P_MEM1_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0P2P_MEM1_BAR_SIZE);
    if(size)
        pci0SelfBars->P2PMem1Size = size + 0x1000;
    else
        pci0SelfBars->P2PMem1Size = 0;
    pci0SelfBars->P2PIOBase = pci0ReadConfigReg(PCI_P2P_I_O_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0P2P_I_O_BAR_SIZE);
    if(size)
        pci0SelfBars->P2PIOSize = size + 0x1000;
    else
        pci0SelfBars->P2PIOSize = 0;
    pci0SelfBars->CPUBase = pci0ReadConfigReg(PCI_CPU_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CPU_BAR_SIZE);
    if(size)
        pci0SelfBars->CPUSize = size + 0x1000;
    else
        pci0SelfBars->CPUSize = 0;
}

/********************************************************************
* pci1ScanSelfBars - update in PCI_SELF_BARS struct all bars base and sizes.
*
* Inputs: PCI_SELF_BARS *pci1SelfBars - the struct which the data will be update
*                                       in.
*********************************************************************/
void pci1ScanSelfBars(PCI_SELF_BARS *pci1SelfBars)
{
    unsigned int size;
    pci1SelfBars->SCS0Base = pci1ReadConfigReg(PCI_SCS_0_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0SCS_0_BANK_SIZE);
    if(size)
        pci1SelfBars->SCS0Size = size + 0x1000;
    else
        pci1SelfBars->SCS0Size = 0;
    pci1SelfBars->SCS1Base = pci1ReadConfigReg(PCI_SCS_1_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0SCS_1_BANK_SIZE);
    if(size)
        pci1SelfBars->SCS1Size = size + 0x1000;
    else
        pci1SelfBars->SCS1Size = 0;
    pci1SelfBars->SCS2Base = pci1ReadConfigReg(PCI_SCS_2_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0SCS_2_BANK_SIZE);
    if(size)
        pci1SelfBars->SCS2Size = size + 0x1000;
    else
        pci1SelfBars->SCS2Size = 0;
    pci1SelfBars->SCS3Base = pci1ReadConfigReg(PCI_SCS_3_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0SCS_3_BANK_SIZE);
    if(size)
        pci1SelfBars->SCS3Size = size + 0x1000;
    else
        size = 0;
    pci1SelfBars->CS0Base = pci1ReadConfigReg(PCI_CS_0_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_0_BANK_SIZE);
    if(size)
        pci1SelfBars->CS0Size = size + 0x1000;
    else
        pci1SelfBars->CS0Size = 0;
    pci1SelfBars->CS1Base = pci1ReadConfigReg(PCI_CS_1_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_1_BANK_SIZE);
    if(size)
        pci1SelfBars->CS1Size = size + 0x1000;
    else
        pci1SelfBars->CS1Size = 0;
    pci1SelfBars->CS2Base = pci1ReadConfigReg(PCI_CS_2_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_2_BANK_SIZE);
    if(size)
        pci1SelfBars->CS2Size = size + 0x1000;
    else
        pci1SelfBars->CS2Size = 0;
    pci1SelfBars->CS3Base = pci1ReadConfigReg(PCI_CS_3_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_3_BANK_SIZE);
    if(size)
        pci1SelfBars->CS3Size = size + 0x1000;
    else
        pci1SelfBars->CS3Size = 0;
    pci1SelfBars->CSBootBase = pci1ReadConfigReg(PCI_BOOTCS_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CS_BOOT_BANK_SIZE);
    if(size)
        pci1SelfBars->CSBootSize = size + 0x1000;
    else
        pci1SelfBars->CSBootSize = 0;
    pci1SelfBars->internalMemBase = pci1ReadConfigReg(
        PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,SELF) &
                             0xfffff000;
    pci1SelfBars->internalIOBase = pci1ReadConfigReg(
        PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,SELF) &
                             0xfffff000;
    pci1SelfBars->P2PMem0Base = pci1ReadConfigReg(PCI_P2P_MEM0_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0P2P_MEM0_BAR_SIZE);
    if(size)
        pci1SelfBars->P2PMem0Size = size + 0x1000;
    else
        pci1SelfBars->P2PMem0Size = 0;
    pci1SelfBars->P2PMem1Base = pci1ReadConfigReg(PCI_P2P_MEM1_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0P2P_MEM1_BAR_SIZE);
    if(size)
        pci1SelfBars->P2PMem1Size = size + 0x1000;
    else
        pci1SelfBars->P2PMem1Size = 0;
    pci1SelfBars->P2PIOBase = pci1ReadConfigReg(PCI_P2P_I_O_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0P2P_I_O_BAR_SIZE);
    if(size)
        pci1SelfBars->P2PIOSize = size + 0x1000;
    else
        pci1SelfBars->P2PIOSize = 0;
    pci1SelfBars->CPUBase = pci1ReadConfigReg(PCI_CPU_BASE_ADDRESS,SELF) &
                             0xfffff000;
    size = GTREGREAD(PCI_0CPU_BAR_SIZE);
    if(size)
        pci1SelfBars->CPUSize = size + 0x1000;
    else
        pci1SelfBars->CPUSize = 0;
}

/********************************************************************
* pci0MapInternalRegSpace - Maps the internal registers memory space for the 
*                           slave.
*
* Inputs: base of pci0 internal register
*********************************************************************/
void pci0MapInternalRegSpace(unsigned int pci0InternalBase)
{
  	pci0InternalBase = pci0InternalBase & 0xfffff000;
    pci0InternalBase = pci0InternalBase | (pci0ReadConfigReg(
        PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,SELF,
                       pci0InternalBase);
}

/********************************************************************
* pci1MapInternalRegSpace - Maps the internal registers memory space for the 
*                           slave.
*
* Inputs: base of pci1 internal register
*********************************************************************/
void pci1MapInternalRegSpace(unsigned int pci1InternalBase)
{
  	pci1InternalBase = pci1InternalBase & 0xfffff000;
    pci1InternalBase = pci1InternalBase | (pci1ReadConfigReg(
        PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,SELF,
                       pci1InternalBase);
}

/********************************************************************
* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the 
*                             slave.
*
* Inputs: base of pci0 internal io register
*********************************************************************/
void pci0MapInternalRegIOSpace(unsigned int pci0InternalBase)
{
  	pci0InternalBase = pci0InternalBase & 0xfffff000;
    pci0InternalBase = pci0InternalBase | (pci0ReadConfigReg(
        PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,SELF,
                       pci0InternalBase);  
}

/********************************************************************
* pci1MapInternalRegIOSpace - Maps the internal registers IO space for the 
*                             slave.
* Inputs: base of pci1 internal io register
*********************************************************************/
void pci1MapInternalRegIOSpace(unsigned int pci1InternalBase)
{
  	pci1InternalBase = pci1InternalBase & 0xfffff000;
    pci1InternalBase = pci1InternalBase | (pci1ReadConfigReg(
        PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,SELF,
                       pci1InternalBase);
}

/********************************************************************
* pci0MapMemoryBank0 - Maps PCI0 memory bank 0 for the slave.
*
* Inputs: base and size of PCI0 SCS0
*********************************************************************/
void pci0MapMemoryBank0(unsigned int pci0Dram0Base,unsigned int pci0Dram0Size)
{
  	pci0Dram0Base = pci0Dram0Base & 0xfffff000;
    pci0Dram0Base = pci0Dram0Base | (pci0ReadConfigReg(
        PCI_SCS_0_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_SCS_0_BASE_ADDRESS,SELF,pci0Dram0Base);
  	if(pci0Dram0Size == 0) 
        pci0Dram0Size ++;
    GT_REG_WRITE(PCI_0SCS_0_BANK_SIZE, pci0Dram0Size-1);
}

/********************************************************************
* pci0MapMemoryBank1 - Maps PCI0 memory bank 1 for the slave.
*
* Inputs: base and size of PCI0 SCS1
*********************************************************************/
void pci0MapMemoryBank1(unsigned int pci0Dram1Base,unsigned int pci0Dram1Size)
{
  	pci0Dram1Base = pci0Dram1Base & 0xfffff000;
    pci0Dram1Base = pci0Dram1Base | (pci0ReadConfigReg(
        PCI_SCS_1_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_SCS_1_BASE_ADDRESS,SELF,pci0Dram1Base);
  	if(pci0Dram1Size == 0) 
        pci0Dram1Size ++;
    GT_REG_WRITE(PCI_0SCS_1_BANK_SIZE, pci0Dram1Size-1);
}


/********************************************************************
* pci1MapMemoryBank0 - Maps PCI1 memory bank 0 for the slave.
*
* Inputs: base and size of PCI1 SCS0
*********************************************************************/
void pci1MapMemoryBank0(unsigned int pci1Dram0Base,
                         unsigned int pci1Dram0Size)
{
  	pci1Dram0Base = pci1Dram0Base & 0xfffff000;
    pci1Dram0Base = pci1Dram0Base | (pci1ReadConfigReg(
        PCI_SCS_0_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_SCS_0_BASE_ADDRESS,SELF,pci1Dram0Base);
  	if(pci1Dram0Size == 0) 
        pci1Dram0Size ++;
    GT_REG_WRITE(PCI_1SCS_0_BANK_SIZE, pci1Dram0Size-1);
}

/********************************************************************
* pci1MapMemoryBank1 - Maps PCI1 memory bank 1 for the slave.
*
* Inputs: base and size of PCI1 SCS1
*********************************************************************/
void pci1MapMemoryBank1(unsigned int pci1Dram1Base,unsigned int pci1Dram1Size)
{
  	pci1Dram1Base = pci1Dram1Base & 0xfffff000;
    pci1Dram1Base = pci1Dram1Base | (pci1ReadConfigReg(
        PCI_SCS_1_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_SCS_1_BASE_ADDRESS,SELF,pci1Dram1Base);
  	if(pci1Dram1Size == 0) 
        pci1Dram1Size ++;
    GT_REG_WRITE(PCI_1SCS_1_BANK_SIZE, pci1Dram1Size-1);
}


/********************************************************************
* pci0MapMemoryBank2 - Maps PCI0 memory bank 2 for the slave.
*
* Inputs: base and size of PCI0 SCS2
*********************************************************************/
void pci0MapMemoryBank2(unsigned int pci0Dram2Base,unsigned int pci0Dram2Size)
{
  	pci0Dram2Base = pci0Dram2Base & 0xfffff000;
    pci0Dram2Base = pci0Dram2Base | (pci0ReadConfigReg(
        PCI_SCS_2_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_SCS_2_BASE_ADDRESS,SELF,pci0Dram2Base);
    if(pci0Dram2Size == 0) 
        pci0Dram2Size++;
  	GT_REG_WRITE(PCI_0SCS_2_BANK_SIZE , pci0Dram2Size-1);
}

/********************************************************************
* pci0MapMemoryBank3 - Maps PCI0 memory bank 3 for the slave.
*
* Inputs: base and size of PCI0 SCS3
*********************************************************************/
void pci0MapMemoryBank3(unsigned int pci0Dram3Base,unsigned int pci0Dram3Size)
{
  	pci0Dram3Base = pci0Dram3Base & 0xfffff000;
    pci0Dram3Base = pci0Dram3Base | (pci0ReadConfigReg(
        PCI_SCS_3_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_SCS_3_BASE_ADDRESS,SELF,pci0Dram3Base);
    if(pci0Dram3Size == 0) 
        pci0Dram3Size++;
  	GT_REG_WRITE(PCI_0SCS_3_BANK_SIZE , pci0Dram3Size-1);
}

/********************************************************************
* pci1MapMemoryBank2 - Maps PCI1 memory bank 2 for the slave.
*
* Inputs: base and size of PCI1 SCS2
*********************************************************************/
void pci1MapMemoryBank2(unsigned int pci1Dram2Base,unsigned int pci1Dram2Size)
{
  	pci1Dram2Base = pci1Dram2Base & 0xfffff000;
    pci1Dram2Base = pci1Dram2Base | (pci1ReadConfigReg(
        PCI_SCS_2_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_SCS_2_BASE_ADDRESS,SELF,pci1Dram2Base);
    if(pci1Dram2Size == 0) 
        pci1Dram2Size++;
  	GT_REG_WRITE(PCI_1SCS_2_BANK_SIZE , pci1Dram2Size-1);
}

/********************************************************************
* pci1MapMemoryBank3 - Maps PCI1 memory bank 3 for the slave.
*
* Inputs: base and size of PCI1 SCS3
*********************************************************************/
void pci1MapMemoryBank3(unsigned int pci1Dram3Base,unsigned int pci1Dram3Size)
{
  	pci1Dram3Base = pci1Dram3Base & 0xfffff000;
    pci1Dram3Base = pci1Dram3Base | (pci1ReadConfigReg(
        PCI_SCS_3_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_SCS_3_BASE_ADDRESS,SELF,pci1Dram3Base);
    if(pci1Dram3Size == 0) 
        pci1Dram3Size++;
  	GT_REG_WRITE(PCI_1SCS_3_BANK_SIZE , pci1Dram3Size-1);
}

/********************************************************************
* pci0MapDevice0MemorySpace - Maps PCI0 device0 memory spaces for the slave.
*
* Inputs: base and length of pci0 device0
*********************************************************************/
void pci0MapDevice0MemorySpace(unsigned int pci0Dev0Base,
                               unsigned int pci0Dev0Length)
{
  	pci0Dev0Base = pci0Dev0Base & 0xfffff000;
    pci0Dev0Base = pci0Dev0Base | (pci0ReadConfigReg(
        PCI_CS_0_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_CS_0_BASE_ADDRESS,SELF,pci0Dev0Base );
    if(pci0Dev0Length == 0) 
        pci0Dev0Length++;
  	GT_REG_WRITE(PCI_0CS_0_BANK_SIZE,pci0Dev0Length-1);
}

/********************************************************************
* pci0MapDevice1MemorySpace - Maps PCI0 device1 memory spaces for the slave.
*
* Inputs: base and length of pci0 device1
*********************************************************************/
void pci0MapDevice1MemorySpace(unsigned int pci0Dev1Base,
                               unsigned int pci0Dev1Length)
{
  	pci0Dev1Base = pci0Dev1Base & 0xfffff000;
    pci0Dev1Base = pci0Dev1Base | (pci0ReadConfigReg(
        PCI_CS_1_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_CS_1_BASE_ADDRESS,SELF,pci0Dev1Base );
    if(pci0Dev1Length == 0) 
        pci0Dev1Length++;
  	GT_REG_WRITE(PCI_0CS_1_BANK_SIZE,pci0Dev1Length-1);
}

/********************************************************************
* pci0MapDevice2MemorySpace - Maps PCI0 device2 memory spaces for the slave.
*
* Inputs: base and length of pci0 device1
*********************************************************************/
void pci0MapDevice2MemorySpace(unsigned int pci0Dev2Base,
                               unsigned int pci0Dev2Length)
{
  	pci0Dev2Base = pci0Dev2Base & 0xfffff000;
    pci0Dev2Base = pci0Dev2Base | (pci0ReadConfigReg(
        PCI_CS_2_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_CS_2_BASE_ADDRESS,SELF,pci0Dev2Base );
    if(pci0Dev2Length == 0) 
        pci0Dev2Length++;
  	GT_REG_WRITE(PCI_0CS_2_BANK_SIZE,pci0Dev2Length-1);
}

/********************************************************************
* pci1MapDevice0MemorySpace - Maps PCI1 device0 memory spaces for the slave.
*
* Inputs: base and length of pci1 device0
*********************************************************************/
void pci1MapDevice0MemorySpace(unsigned int pci1Dev0Base,
                               unsigned int pci1Dev0Length)
{
  	pci1Dev0Base = pci1Dev0Base & 0xfffff000;
    pci1Dev0Base = pci1Dev0Base | (pci1ReadConfigReg(
        PCI_CS_0_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_CS_0_BASE_ADDRESS,SELF,pci1Dev0Base );
    if(pci1Dev0Length == 0) 
        pci1Dev0Length++;
  	GT_REG_WRITE(PCI_1CS_0_BANK_SIZE,pci1Dev0Length-1);
}

/********************************************************************
* pci1MapDevice1MemorySpace - Maps PCI1 device1 memory spaces for the slave.
*
* Inputs: base and lengthof pci1 device1
*********************************************************************/
void pci1MapDevice1MemorySpace(unsigned int pci1Dev1Base,
                               unsigned int pci1Dev1Length)
{
  	pci1Dev1Base = pci1Dev1Base & 0xfffff000;
    pci1Dev1Base = pci1Dev1Base | (pci1ReadConfigReg(
        PCI_CS_1_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_CS_1_BASE_ADDRESS,SELF,pci1Dev1Base);
    if(pci1Dev1Length == 0) 
        pci1Dev1Length++;
  	GT_REG_WRITE(PCI_1CS_1_BANK_SIZE,pci1Dev1Length-1);
}

/********************************************************************
* pci1MapDevice2MemorySpace - Maps PCI1 device2 memory spaces for the slave.
*
* Inputs: base and length of pci1 device2
*********************************************************************/
void pci1MapDevice2MemorySpace(unsigned int pci1Dev2Base,
                               unsigned int pci1Dev2Length)
{
  	pci1Dev2Base = pci1Dev2Base & 0xfffff000;
    pci1Dev2Base = pci1Dev2Base | (pci1ReadConfigReg(
        PCI_CS_2_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_CS_2_BASE_ADDRESS,SELF,pci1Dev2Base);
    if(pci1Dev2Length == 0) 
        pci1Dev2Length++;
  	GT_REG_WRITE(PCI_1CS_2_BANK_SIZE,pci1Dev2Length-1);
}

/********************************************************************
* pci0MapDevice3MemorySpace - Maps PCI0 devices 3 spaces for the slave.
*
* Inputs: base and length of pci0 device3.
*********************************************************************/
void pci0MapDevice3MemorySpace(unsigned int pci0Dev3Base,
                               unsigned int pci0Dev3Length)
{
  	pci0Dev3Base = pci0Dev3Base & 0xfffff000;
    pci0Dev3Base = pci0Dev3Base | (pci0ReadConfigReg(
        PCI_CS_3_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_CS_3_BASE_ADDRESS,SELF,pci0Dev3Base );
  	if(pci0Dev3Length == 0) 
        pci0Dev3Length++;
    GT_REG_WRITE(PCI_0CS_3_BANK_SIZE , pci0Dev3Length-1);
}

/********************************************************************
* pci0MapBootDeviceMemorySpace - Maps PCI0 boot memory spaces for the slave.
*
* Inputs: base and length of pci0 boot.
*********************************************************************/
void pci0MapBootDeviceMemorySpace(unsigned int pci0DevBootBase,
                                  unsigned int pci0DevBootLength)
{
  	pci0DevBootBase = pci0DevBootBase & 0xfffff000;
    pci0DevBootBase = pci0DevBootBase | (pci0ReadConfigReg(
        PCI_BOOTCS_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_BOOTCS_BASE_ADDRESS,SELF,pci0DevBootBase );
  	if(pci0DevBootLength == 0) 
        pci0DevBootLength++;
    GT_REG_WRITE(PCI_0CS_BOOT_BANK_SIZE , pci0DevBootLength-1);
}

/********************************************************************
* pci1MapDevice3MemorySpace - Maps PCI1 devices 3 spaces for the slave.
*
* Inputs: base and length of pci1 device3.
*********************************************************************/
void pci1MapDevice3MemorySpace(unsigned int pci1Dev3Base,
                               unsigned int pci1Dev3Length)
{
  	pci1Dev3Base = pci1Dev3Base & 0xfffff000;
    pci1Dev3Base = pci1Dev3Base | (pci1ReadConfigReg(
        PCI_CS_3_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_CS_3_BASE_ADDRESS,SELF,pci1Dev3Base );
  	if(pci1Dev3Length == 0) 
        pci1Dev3Length++;
    GT_REG_WRITE(PCI_1CS_3_BANK_SIZE , pci1Dev3Length-1);
}

/********************************************************************
* pci1MapBootDeviceMemorySpace - Maps PCI1 boot memory spaces for the slave.
*
* Inputs: base and length of pci1 boot.
*********************************************************************/
void pci1MapBootDeviceMemorySpace(unsigned int pci1DevBootBase,
                                  unsigned int pci1DevBootLength)
{
  	pci1DevBootBase = pci1DevBootBase & 0xfffff000;
    pci1DevBootBase = pci1DevBootBase | (pci1ReadConfigReg(
        PCI_BOOTCS_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_BOOTCS_BASE_ADDRESS,SELF,pci1DevBootBase );
  	if(pci1DevBootLength == 0) 
        pci1DevBootLength++;
    GT_REG_WRITE(PCI_1CS_BOOT_BANK_SIZE , pci1DevBootLength-1);
}

/********************************************************************
* pci0p2pMem0 - Maps PCI0 pci2pci memory0 spaces for the slave.
*
* Inputs: base and length of pci0P2pMem0 
*********************************************************************/
void pci0MapP2pMem0Space(unsigned int pci0P2pMem0Base, 
                         unsigned int pci0P2pMem0Length)

{
    pci0P2pMem0Base = pci0P2pMem0Base & 0xfffff000;
    pci0P2pMem0Base = pci0P2pMem0Base | (pci0ReadConfigReg(
        PCI_P2P_MEM0_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_P2P_MEM0_BASE_ADDRESS,SELF,pci0P2pMem0Base);
    if(pci0P2pMem0Length == 0) 
        pci0P2pMem0Length++;
    GT_REG_WRITE(PCI_0P2P_MEM0_BAR_SIZE , pci0P2pMem0Length-1);
}

/********************************************************************
* pci1p2pMem0 - Maps PCI1 pci2pci memory0 spaces for the slave.
*
* Inputs: base and length of pci1P2pMem0
*********************************************************************/
void pci1MapP2pMem0Space(unsigned int pci1P2pMem0Base,
                            unsigned int pci1P2pMem0Length)
{
    pci1P2pMem0Base = pci1P2pMem0Base & 0xfffff000;
    pci1P2pMem0Base = pci1P2pMem0Base | (pci1ReadConfigReg(
        PCI_P2P_MEM0_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_P2P_MEM0_BASE_ADDRESS,SELF,pci1P2pMem0Base);
    if(pci1P2pMem0Length == 0) 
        pci1P2pMem0Length++;
    GT_REG_WRITE(PCI_1P2P_MEM0_BAR_SIZE , pci1P2pMem0Length-1);
}

/********************************************************************
* pci0p2pMem1 - Maps PCI0 pci2pci memory1 spaces for the slave.
*
* Inputs: base and length of pci0P2pMem1 
*********************************************************************/
void pci0MapP2pMem1Space(unsigned int pci0P2pMem1Base, 
                         unsigned int pci0P2pMem1Length)
{
    pci0P2pMem1Base = pci0P2pMem1Base & 0xfffff000;
    pci0P2pMem1Base = pci0P2pMem1Base | (pci0ReadConfigReg(
        PCI_P2P_MEM1_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_P2P_MEM1_BASE_ADDRESS,SELF,pci0P2pMem1Base );
    if(pci0P2pMem1Length == 0) 
        pci0P2pMem1Length++;
    GT_REG_WRITE(PCI_0P2P_MEM1_BAR_SIZE , pci0P2pMem1Length-1);
}

/********************************************************************
* pci1p2pMem1 - Maps PCI1 pci2pci memory1 spaces for the slave.
*
* Inputs: base and length of pci1P2pMem1 
*********************************************************************/
void pci1MapP2pMem1Space(unsigned int pci1P2pMem1Base, 
                         unsigned int pci1P2pMem1Length)
{
    pci1P2pMem1Base = pci1P2pMem1Base & 0xfffff000;
    pci1P2pMem1Base = pci1P2pMem1Base | (pci1ReadConfigReg(
        PCI_P2P_MEM1_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_P2P_MEM1_BASE_ADDRESS,SELF,pci1P2pMem1Base );
    if(pci1P2pMem1Length == 0) 
        pci1P2pMem1Length++;
    GT_REG_WRITE(PCI_1P2P_MEM1_BAR_SIZE , pci1P2pMem1Length-1);
}

/********************************************************************
* pci0p2pIO - Maps PCI0 pci2pci io spaces for the slave.
*
* Inputs: base and length of pci0P2pIo 
*********************************************************************/
void    pci0MapP2pIoSpace(unsigned int pci0P2pIoBase, 
                          unsigned int pci0P2pIoLength)
{
    pci0P2pIoBase = pci0P2pIoBase & 0xfffff000;
    pci0P2pIoBase = pci0P2pIoBase | (pci0ReadConfigReg(
        PCI_P2P_MEM0_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_P2P_I_O_BASE_ADDRESS,SELF,pci0P2pIoBase );
    if(pci0P2pIoLength == 0) 
        pci0P2pIoLength++;
    GT_REG_WRITE(PCI_0P2P_I_O_BAR_SIZE , pci0P2pIoLength-1);
}

/********************************************************************
* pci1p2pIO - Maps PCI1 pci2pci io spaces for the slave.
*
* Inputs: base and length of pci1P2pIo 
*********************************************************************/
void pci1MapP2pIoSpace(unsigned int pci1P2pIoBase, unsigned int pci1P2pIoLength)

{
    pci1P2pIoBase = pci1P2pIoBase & 0xfffff000;
    pci1P2pIoBase = pci1P2pIoBase | (pci1ReadConfigReg(
        PCI_P2P_I_O_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_P2P_I_O_BASE_ADDRESS,SELF,pci1P2pIoBase);
    if(pci1P2pIoLength == 0) 
        pci1P2pIoLength++;
    GT_REG_WRITE(PCI_1P2P_I_O_BAR_SIZE , pci1P2pIoLength-1);
}

/********************************************************************
* pci0CPU - Maps PCI0 cpu spaces for the slave.
*
* Inputs: base and length of pci0Cpu 
*********************************************************************/
void pci0MapCPUspace(unsigned int pci0CpuBase, unsigned int pci0CpuLengs)
{
    pci0CpuBase = pci0CpuBase & 0xfffff000;
    pci0CpuBase = pci0CpuBase | (pci0ReadConfigReg(
        PCI_CPU_BASE_ADDRESS,SELF) & 0x00000fff);
    pci0WriteConfigReg(PCI_CPU_BASE_ADDRESS,SELF,pci0CpuBase );
    if(pci0CpuLengs == 0) 
        pci0CpuLengs++;
    GT_REG_WRITE(PCI_0CPU_BAR_SIZE , pci0CpuLengs-1);
}

/********************************************************************
* pci1CPU - Maps PCI1 cpu spaces for the slave.
*
* Inputs: base and length of pci1Cpu 
*********************************************************************/
void pci1MapCPUspace(unsigned int pci1CpuBase, unsigned int pci1CpuLengs)
{
    pci1CpuBase = pci1CpuBase & 0xfffff000;
    pci1CpuBase = pci1CpuBase | (pci1ReadConfigReg(
        PCI_CPU_BASE_ADDRESS,SELF) & 0x00000fff);
    pci1WriteConfigReg(PCI_CPU_BASE_ADDRESS,SELF,pci1CpuBase );
    if(pci1CpuLengs == 0) 
        pci1CpuLengs++;
    GT_REG_WRITE(PCI_1CPU_BAR_SIZE , pci1CpuLengs-1);
}


/********************************************************************
* pci0SetRegionFeatures - This function modifys one of the 8 regions with 
*                         feature bits given as an input.
*                       - Be advised to check the spec before modifying them.
* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
*         unsigned int features - See file: pci.h there are defintion for those
*                                 region features.
*         unsigned int baseAddress - The region base Address.
*         unsigned int topAddress - The region top Address.
* Returns: false if one of the parameters is erroneous true otherwise.
*********************************************************************/
bool pci0SetRegionFeatures(PCI_ACCESS_REGIONS region,unsigned int features, 
                           unsigned int baseAddress,unsigned int regionLength)
{
    unsigned int accessLow;
    unsigned int accessHigh;
    unsigned int accessTop = baseAddress + regionLength;

    if(regionLength == 0) /* close the region. */
    {
        pci0DisableAccessRegion(region);
        return true;
    }
    /* base Address is store is bits [11:0] */
    accessLow = (baseAddress & 0xfff00000) >> 20;
    /* All the features are update according to the defines in pci.h (to be on
       the safe side we disable bits: [11:0] */
    accessLow = accessLow | (features & 0xfffff000);
    /* write to the Low Access Region register */
    GT_REG_WRITE(PCI_0ACCESS_CONTROL_BASE_0_LOW + 0x10*region,accessLow);
    accessHigh = (accessTop & 0xfff00000) >> 20;
    if(regionLength != 0)
    {
        /* write to the High Access Region register */
        GT_REG_WRITE(PCI_0ACCESS_CONTROL_TOP_0 + 0x10*region,accessHigh - 1);
    }
    else
    {
        GT_REG_WRITE(PCI_0ACCESS_CONTROL_TOP_0 + 0x10*region,0);
    }
    return true;
}

/********************************************************************
* pci1SetRegionFeatures - This function modifys one of the 8 regions with 
*                         feature bits given as an input.
*                       - Be advised to check the spec before modifying them.
* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
*         unsigned int features - See file: pci.h there are defintion for those
*                                 region features.
*         unsigned int baseAddress - The region base Address.
*         unsigned int topAddress - The region top Address.
* Returns: false if one of the parameters is erroneous true otherwise.
*********************************************************************/
bool pci1SetRegionFeatures(PCI_ACCESS_REGIONS region,unsigned int features, 
                           unsigned int baseAddress,unsigned int regionLength)
{
    unsigned int accessLow;
    unsigned int accessHigh;
    unsigned int accessTop = baseAddress + regionLength;

    if(regionLength == 0) /* close the region. */
    {
        pci1DisableAccessRegion(region);
        return true;
    }
    /* base Address is store is bits [11:0] */
    accessLow = (baseAddress & 0xfff00000) >> 20;
    /* All the features are update according to the defines in pci.h (to be on
       the safe side we disable bits: [11:0] */
    accessLow = accessLow | (features & 0xfffff000);
    /* write to the Low Access Region register */
    GT_REG_WRITE(PCI_1ACCESS_CONTROL_BASE_0_LOW + 0x10*region,accessLow);
    accessHigh = (accessTop & 0xfff00000) >> 20;
    if(regionLength != 0)
    {
        /* write to the High Access Region register */
        GT_REG_WRITE(PCI_1ACCESS_CONTROL_TOP_0 + 0x10*region,accessHigh - 1);
    }
    else
    {
        GT_REG_WRITE(PCI_1ACCESS_CONTROL_TOP_0 + 0x10*region,0);
    }
    return true;
}

/********************************************************************
* pci0DisableAccessRegion - Disable The given Region by writing MAX size
*                           to its low Address and MIN size to its high Address. 
*
* Inputs:   PCI_ACCESS_REGIONS region - The region we to be Disabled.
* Returns:  N/A.
*********************************************************************/
void pci0DisableAccessRegion(PCI_ACCESS_REGIONS region)
{
    /* writing back the registers default values. */
    GT_REG_WRITE(PCI_0ACCESS_CONTROL_BASE_0_LOW + 0x10*region,0x01001fff);
    GT_REG_WRITE(PCI_0ACCESS_CONTROL_TOP_0 + 0x10*region,0);
}

/********************************************************************
* pci1DisableAccessRegion - Disable The given Region by writing MAX size
*                           to its low Address and MIN size to its high Address. 
*
* Inputs:   PCI_ACCESS_REGIONS region - The region we to be Disabled.
* Returns:  N/A.
*********************************************************************/
void pci1DisableAccessRegion(PCI_ACCESS_REGIONS region)
{
    /* writing back the registers default values. */
    GT_REG_WRITE(PCI_1ACCESS_CONTROL_BASE_0_LOW + 0x10*region,0x01001fff);
    GT_REG_WRITE(PCI_1ACCESS_CONTROL_TOP_0 + 0x10*region,0);
}

/********************************************************************
* pci0ArbiterEnable - Enables PCI-0`s Arbitration mechanism.
*
* Inputs:   N/A
* Returns:  true.
*********************************************************************/
bool pci0ArbiterEnable()
{
    unsigned int regData;

    GT_REG_READ(PCI_0ARBITER_CONTROL,&regData);
    GT_REG_WRITE(PCI_0ARBITER_CONTROL,regData | BIT31);
    return true;
}

/********************************************************************
* pci1ArbiterEnable - Enables PCI-1`s Arbitration mechanism.
*
* Inputs:   N/A
* Returns:  true.
*********************************************************************/
bool pci1ArbiterEnable()
{
    unsigned int regData;

    GT_REG_READ(PCI_1ARBITER_CONTROL,&regData);
    GT_REG_WRITE(PCI_1ARBITER_CONTROL,regData | BIT31); 
    return true;
}

/********************************************************************
* pci0ArbiterDisable - Disable PCI-0`s Arbitration mechanism.
*
* Inputs:   N/A
* Returns:  true
*********************************************************************/
bool pci0ArbiterDisable()
{
    unsigned int regData;

    GT_REG_READ(PCI_0ARBITER_CONTROL,&regData);
    GT_REG_WRITE(PCI_0ARBITER_CONTROL,regData & 0x7fffffff);
    return true;
}
/********************************************************************
* pci1ArbiterDisable - Disable PCI-1`s Arbitration mechanism.
*
* Inputs:   N/A
* Returns:  true
*********************************************************************/
bool pci1ArbiterDisable()
{
    unsigned int regData;

    GT_REG_READ(PCI_1ARBITER_CONTROL,&regData);
    GT_REG_WRITE(PCI_1ARBITER_CONTROL,regData & 0x7fffffff);
    return true;
}

/********************************************************************
* pci0SetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low)   
*
* Inputs:   PCI_AGENT_PRIO internalAgent - priotity for internal agent.
*           PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent.
*           PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent.
*           PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent.
*           PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent.
*           PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent.
*           PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent.
* Returns:  true
*********************************************************************/
bool pci0SetArbiterAgentsPriority(PCI_AGENT_PRIO internalAgent,
                                  PCI_AGENT_PRIO externalAgent0,
                                  PCI_AGENT_PRIO externalAgent1,
                                  PCI_AGENT_PRIO externalAgent2,
                                  PCI_AGENT_PRIO externalAgent3,
                                  PCI_AGENT_PRIO externalAgent4,
                                  PCI_AGENT_PRIO externalAgent5)
{
    unsigned int regData;
    unsigned int writeData;

    GT_REG_READ(PCI_0ARBITER_CONTROL,&regData);
    writeData = (internalAgent << 7) + (externalAgent0 << 8) +      
                (externalAgent1 << 9) + (externalAgent2 << 10) +    
                (externalAgent3 << 11) + (externalAgent4 << 12) +   
                (externalAgent5 << 13);
    regData = (regData & 0xffffc07f) + writeData;
    GT_REG_WRITE(PCI_0ARBITER_CONTROL,regData & regData);
    return true;
}

/********************************************************************
* pci1SetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low)   
*
* Inputs:   PCI_AGENT_PRIO internalAgent - priotity for internal agent.
*           PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent.
*           PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent.
*           PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent.
*           PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent.
*           PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent.
*           PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent.
* Returns:  true
*********************************************************************/
bool pci1SetArbiterAgentsPriority(PCI_AGENT_PRIO internalAgent,
                                  PCI_AGENT_PRIO externalAgent0,
                                  PCI_AGENT_PRIO externalAgent1,
                                  PCI_AGENT_PRIO externalAgent2,
                                  PCI_AGENT_PRIO externalAgent3,
                                  PCI_AGENT_PRIO externalAgent4,
                                  PCI_AGENT_PRIO externalAgent5)
{
    unsigned int regData;
    unsigned int writeData;

    GT_REG_READ(PCI_1ARBITER_CONTROL,&regData);
    writeData = (internalAgent << 7) + (externalAgent0 << 8) +      \
                (externalAgent1 << 9) + (externalAgent2 << 10) +    \
                (externalAgent3 << 11) + (externalAgent4 << 12) +   \
                (externalAgent5 << 13);
    regData = (regData & 0xffffc07f) + writeData;
    GT_REG_WRITE(PCI_1ARBITER_CONTROL,regData & regData);
    return true;
}

/********************************************************************
* pci0ParkingDisable - Park on last option disable, with this function you can
*                      disable the park on last mechanism for each agent.
*                      disabling this option for all agents results parking
*                      on the internal master.    
*
* Inputs: PCI_AGENT_PARK internalAgent -  parking Disable for internal agent.
*         PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
*         PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
*         PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
*         PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
*         PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
*         PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
* Returns:  true 
*********************************************************************/
bool pci0ParkingDisable(PCI_AGENT_PARK internalAgent,
                        PCI_AGENT_PARK externalAgent0,
                        PCI_AGENT_PARK externalAgent1,
                        PCI_AGENT_PARK externalAgent2,
                        PCI_AGENT_PARK externalAgent3,
                        PCI_AGENT_PARK externalAgent4,
                        PCI_AGENT_PARK externalAgent5)
{
    unsigned int regData;
    unsigned int writeData;

    GT_REG_READ(PCI_0ARBITER_CONTROL,&regData);
    writeData = (internalAgent << 14) + (externalAgent0 << 15) +     \
                (externalAgent1 << 16) + (externalAgent2 << 17) +    \
                (externalAgent3 << 18) + (externalAgent4 << 19) +    \
                (externalAgent5 << 20);
    regData = (regData & 0xffffc07f) + writeData;
    regData = (regData & 0xffe03fff) + writeData;
    GT_REG_WRITE(PCI_0ARBITER_CONTROL,regData & regData);
    return true;
}

/********************************************************************
* pci1ParkingDisable - Park on last option disable, with this function you can
*                      disable the park on last mechanism for each agent.
*                      disabling this option for all agents results parking
*                      on the internal master.    
*
* Inputs: PCI_AGENT_PARK internalAgent -  parking Disable for internal agent.
*         PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
*         PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
*         PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
*         PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
*         PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
*         PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
* Returns:  true 
*********************************************************************/
bool pci1ParkingDisable(PCI_AGENT_PARK internalAgent,
                        PCI_AGENT_PARK externalAgent0,
                        PCI_AGENT_PARK externalAgent1,
                        PCI_AGENT_PARK externalAgent2,
                        PCI_AGENT_PARK externalAgent3,
                        PCI_AGENT_PARK externalAgent4,
                        PCI_AGENT_PARK externalAgent5)
{
    unsigned int regData;
    unsigned int writeData;

    GT_REG_READ(PCI_1ARBITER_CONTROL,&regData);
    writeData = (internalAgent << 14) + (externalAgent0 << 15) +     \
                (externalAgent1 << 16) + (externalAgent2 << 17) +    \
                (externalAgent3 << 18) + (externalAgent4 << 19) +    \
                (externalAgent5 << 20);
    regData = (regData & 0xffffc07f) + writeData;
    regData = (regData & 0xffe03fff) + writeData;
    GT_REG_WRITE(PCI_1ARBITER_CONTROL,regData & regData);
    return true;
}

/********************************************************************
* pci0EnableBrokenAgentDetection - A master is said to be broken if it fails to
*                       respond to grant assertion within a window specified in
*                       the input value: 'brokenValue'. 
*
* Inputs: unsigned char brokenValue -  A value which limits the Master to hold the
*                       grant without asserting frame.
* Returns:  Error for illegal broken value otherwise true. 
*********************************************************************/
bool pci0EnableBrokenAgentDetection(unsigned char brokenValue)
{
    unsigned int data;
    unsigned int regData;

    if (brokenValue > 0xf) 
        return false; /* brokenValue must be 4 bit */
    data = brokenValue << 3;
    GT_REG_READ(PCI_0ARBITER_CONTROL,&regData);
    regData = (regData & 0xffffff87) | data;
    GT_REG_WRITE(PCI_0ARBITER_CONTROL,regData | BIT1);
    return true;
}

/********************************************************************
* pci1EnableBrokenAgentDetection - A master is said to be broken if it fails to
*                       respond to grant assertion within a window specified in
*                       the input value: 'brokenValue'. 
*
* Inputs: unsigned char brokenValue -  A value which limits the Master to hold the
*                       grant without asserting frame.
* Returns:  Error for illegal broken value otherwise true. 
*********************************************************************/
bool pci1EnableBrokenAgentDetection(unsigned char brokenValue)
{
    unsigned int data;
    unsigned int regData;

    if (brokenValue > 0xf) 
        return false; /* brokenValue must be 4 bit */
    data = brokenValue << 3;
    GT_REG_READ(PCI_1ARBITER_CONTROL,&regData);
    regData = (regData & 0xffffff87) | data;
    GT_REG_WRITE(PCI_1ARBITER_CONTROL,regData | BIT1); 
    return true;
}

/********************************************************************
* pci0DisableBrokenAgentDetection - This function disable the Broken agent
*                           Detection mechanism.
*                           NOTE: This operation may cause a dead lock on the 
*                           pci0 arbitration.
*
* Inputs:   N/A
* Returns:  true. 
*********************************************************************/
bool pci0DisableBrokenAgentDetection()
{
    unsigned int regData;

    GT_REG_READ(PCI_0ARBITER_CONTROL,&regData);
    regData = regData & 0xfffffffd;
    GT_REG_WRITE(PCI_0ARBITER_CONTROL,regData);
    return true;
}

/********************************************************************
* disablePci1BrokenAgentDetection - This function disable the Broken agent
*                           Detection mechanism.
*                           NOTE: This operation may cause a dead lock on the 
*                           pci1 arbitration.
*
* Inputs:   N/A
* Returns:  true. 
*********************************************************************/
bool pci1DisableBrokenAgentDetection()
{
    unsigned int regData;

    GT_REG_READ(PCI_1ARBITER_CONTROL,&regData);
    regData = regData & 0xfffffffd;
    GT_REG_WRITE(PCI_1ARBITER_CONTROL,regData); 
    return true;
}

/********************************************************************
* pci0P2PConfig - This function set the PCI_0 P2P configurate.
*                 For more information on the P2P read PCI spec.  
*
* Inputs:  unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
*                                      Boundry.
*          unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
*                                      Boundry.         
*          unsigned int busNum - The CPI bus number to which the PCI interface
*                                      is connected.
*          unsigned int devNum - The PCI interface's device number.
*   
* Returns:  true. 
*********************************************************************/
bool pci0P2PConfig(unsigned int SecondBusLow,unsigned int SecondBusHigh,
                   unsigned int busNum,unsigned int devNum)
{
    unsigned int regData;

    regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
        ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
    GT_REG_WRITE(PCI_0P2P_CONFIGURATION,regData);
    return true;
}

/********************************************************************
* pci1P2PConfig - This function set the PCI_1 P2P configurate.
*                 For more information on the P2P read PCI spec.  
*
* Inputs:  unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
*               Boundry.
*          unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
*               Boundry.         
*          unsigned int busNum - The CPI bus number to which the PCI interface
*               is connected.
*          unsigned int devNum - The PCI interface's device number.
*   
* Returns:  true. 
*********************************************************************/
bool pci1P2PConfig(unsigned int SecondBusLow,unsigned int SecondBusHigh,
                   unsigned int busNum,unsigned int devNum)
{
    unsigned int regData;

    regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
        ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
    GT_REG_WRITE(PCI_1P2P_CONFIGURATION,regData);
    return true;
}

/********************************************************************
* pci0SetRegionSnoopMode - This function modifys one of the 4 regions which   
*                          supports Cache Coherency in the PCI_0 interface.
* Inputs: region - One of the four regions.
*         snoopType - There is four optional Types:
*                        1. No Snoop.
*                        2. Snoop to WT region.
*                        3. Snoop to WB region.
*                        4. Snoop & Invalidate to WB region.
*         baseAddress - Base Address of this region.
*         regionLength - Region length.
* Returns: false if one of the parameters is wrong otherwise return true.
*********************************************************************/
bool pci0SetRegionSnoopMode(PCI_SNOOP_REGION region,PCI_SNOOP_TYPE snoopType,
                            unsigned int baseAddress,
                            unsigned int regionLength)
{
    unsigned int snoopXbaseAddress;
    unsigned int snoopXtopAddress;
    unsigned int data;
    unsigned int snoopHigh = baseAddress + regionLength;

    if( (region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB) )
        return false;
    snoopXbaseAddress = PCI_0SNOOP_CONTROL_BASE_0_LOW + 0x10 * region;
    snoopXtopAddress = PCI_0SNOOP_CONTROL_TOP_0 + 0x10 * region;
    if(regionLength == 0) /* closing the region */
    {
        GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
        GT_REG_WRITE(snoopXtopAddress,0);
        return true;
    }
    baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
    data = (baseAddress >> 20) | snoopType << 12;
    GT_REG_WRITE(snoopXbaseAddress,data); 
    snoopHigh = (snoopHigh & 0xfff00000) >> 20;
    GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
    return true;
}

/********************************************************************
* pci1SetRegionSnoopMode - This function modifys one of the 4 regions which   
*                          supports Cache Coherency in the PCI_1 interface.
* Inputs: region - One of the four regions.
*         snoopType - There is four optional Types:
*                        1. No Snoop.
*                        2. Snoop to WT region.
*                        3. Snoop to WB region.
*                        4. Snoop & Invalidate to WB region.
*         baseAddress - Base Address of this region.
*         regionLength - Region length.
* Returns: false if one of the parameters is wrong otherwise return true.
*********************************************************************/
bool pci1SetRegionSnoopMode(PCI_SNOOP_REGION region,PCI_SNOOP_TYPE snoopType,
                            unsigned int baseAddress,
                            unsigned int regionLength)
{
    unsigned int snoopXbaseAddress;
    unsigned int snoopXtopAddress;
    unsigned int data;
    unsigned int snoopHigh = baseAddress + regionLength;

    if( (region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB) )
        return false;
    snoopXbaseAddress = PCI_1SNOOP_CONTROL_BASE_0_LOW + 0x10 * region;
    snoopXtopAddress = PCI_1SNOOP_CONTROL_TOP_0 + 0x10 * region;
    if(regionLength == 0) /* closing the region */
    {
        GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
        GT_REG_WRITE(snoopXtopAddress,0);
        return true;
    }
    baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
    data = (baseAddress >> 20) | snoopType << 12;
    GT_REG_WRITE(snoopXbaseAddress,data); 
    snoopHigh = (snoopHigh & 0xfff00000) >> 20;
    GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
    return true;
}
