!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/arch/mips/gt64120/common/   drwxr-xr-x
Free 318.29 GB of 458.09 GB (69.48%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     pci.c (30.64 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * BRIEF MODULE DESCRIPTION
 * Galileo Evaluation Boards PCI support.
 *
 * The general-purpose functions to read/write and configure the GT64120A's
 * PCI registers (function names start with pci0 or pci1) are either direct
 * copies of functions written by Galileo Technology, or are modifications
 * of their functions to work with Linux 2.4 vs Linux 2.2.  These functions
 * are Copyright - Galileo Technology.
 *
 * Other functions are derived from other MIPS PCI implementations, or were
 * written by RidgeRun, Inc,  Copyright (C) 2000 RidgeRun, Inc.
 *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
 *
 * Copyright 2001 MontaVista Software Inc.
 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <asm/pci.h>
#include <asm/io.h>
#include <asm/gt64120/gt64120.h>

#include <linux/init.h>

#ifdef CONFIG_PCI

#define SELF 0

/*
 * These functions and structures provide the BIOS scan and mapping of the PCI
 * devices.
 */

#define MAX_PCI_DEVS 10

struct pci_device {
    u32 slot;
    u32 BARtype[6];
    u32 BARsize[6];
};

static void __init scan_and_initialize_pci(void);
static u32 __init scan_pci_bus(struct pci_device *pci_devices);
static void __init allocate_pci_space(struct pci_device *pci_devices);

/*
 * The functions that actually read and write to the controller.
 *
 *  Copied from or modified from Galileo Technology code.
 */
static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device);
static void pci0WriteConfigReg(unsigned int offset,
                   struct pci_dev *device, unsigned int data);
static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device);
static void pci1WriteConfigReg(unsigned int offset,
                   struct pci_dev *device, unsigned int data);

static void pci0MapIOspace(unsigned int pci0IoBase,
               unsigned int pci0IoLength);
static void pci1MapIOspace(unsigned int pci1IoBase,
               unsigned int pci1IoLength);
static void pci0MapMemory0space(unsigned int pci0Mem0Base,
                unsigned int pci0Mem0Length);
static void pci1MapMemory0space(unsigned int pci1Mem0Base,
                unsigned int pci1Mem0Length);
static void pci0MapMemory1space(unsigned int pci0Mem1Base,
                unsigned int pci0Mem1Length);
static void pci1MapMemory1space(unsigned int pci1Mem1Base,
                unsigned int pci1Mem1Length);
static unsigned int pci0GetIOspaceBase(void);
static unsigned int pci0GetIOspaceSize(void);
static unsigned int pci0GetMemory0Base(void);
static unsigned int pci0GetMemory0Size(void);
static unsigned int pci0GetMemory1Base(void);
static unsigned int pci0GetMemory1Size(void);
static unsigned int pci1GetIOspaceBase(void);
static unsigned int pci1GetIOspaceSize(void);
static unsigned int pci1GetMemory0Base(void);
static unsigned int pci1GetMemory0Size(void);
static unsigned int pci1GetMemory1Base(void);
static unsigned int pci1GetMemory1Size(void);


/*  Functions to implement "pci ops"  */
static int galileo_pcibios_read_config_word(struct pci_dev *dev,
                        int offset, u16 * val);
static int galileo_pcibios_read_config_byte(struct pci_dev *dev,
                        int offset, u8 * val);
static int galileo_pcibios_read_config_dword(struct pci_dev *dev,
                         int offset, u32 * val);
static int galileo_pcibios_write_config_byte(struct pci_dev *dev,
                         int offset, u8 val);
static int galileo_pcibios_write_config_word(struct pci_dev *dev,
                         int offset, u16 val);
static int galileo_pcibios_write_config_dword(struct pci_dev *dev,
                          int offset, u32 val);
static void galileo_pcibios_set_master(struct pci_dev *dev);

/*
 *  General-purpose PCI functions.
 */

/*
 * pci0MapIOspace - Maps PCI0 IO space for the master.
 * Inputs: base and length of pci0Io
 */

static void pci0MapIOspace(unsigned int pci0IoBase,
               unsigned int pci0IoLength)
{
    unsigned int pci0IoTop =
        (unsigned int) (pci0IoBase + pci0IoLength);

    if (pci0IoLength == 0)
        pci0IoTop++;

    pci0IoBase = (unsigned int) (pci0IoBase >> 21);
    pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21);
    GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase);
    GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop);
}

/*
 * pci1MapIOspace - Maps PCI1 IO space for the master.
 * Inputs: base and length of pci1Io
 */

static void pci1MapIOspace(unsigned int pci1IoBase,
               unsigned int pci1IoLength)
{
    unsigned int pci1IoTop =
        (unsigned int) (pci1IoBase + pci1IoLength);

    if (pci1IoLength == 0)
        pci1IoTop++;

    pci1IoBase = (unsigned int) (pci1IoBase >> 21);
    pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21);
    GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase);
    GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop);
}

/*
 * pci0MapMemory0space - Maps PCI0 memory0 space for the master.
 * Inputs: base and length of pci0Mem0
 */

static void pci0MapMemory0space(unsigned int pci0Mem0Base,
                unsigned int pci0Mem0Length)
{
    unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length;

    if (pci0Mem0Length == 0)
        pci0Mem0Top++;

    pci0Mem0Base = pci0Mem0Base >> 21;
    pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21;
    GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base);
    GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top);
}

/*
 * pci1MapMemory0space - Maps PCI1 memory0 space for the master.
 * Inputs: base and length of pci1Mem0
 */

static void pci1MapMemory0space(unsigned int pci1Mem0Base,
                unsigned int pci1Mem0Length)
{
    unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length;

    if (pci1Mem0Length == 0)
        pci1Mem0Top++;

    pci1Mem0Base = pci1Mem0Base >> 21;
    pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21;
    GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base);
    GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top);
}

/*
 * pci0MapMemory1space - Maps PCI0 memory1 space for the master.
 * Inputs: base and length of pci0Mem1
 */

static void pci0MapMemory1space(unsigned int pci0Mem1Base,
                unsigned int pci0Mem1Length)
{
    unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length;

    if (pci0Mem1Length == 0)
        pci0Mem1Top++;

    pci0Mem1Base = pci0Mem1Base >> 21;
    pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21;
    GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base);
    GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top);

}

/*
 * pci1MapMemory1space - Maps PCI1 memory1 space for the master.
 * Inputs: base and length of pci1Mem1
 */

static void pci1MapMemory1space(unsigned int pci1Mem1Base,
                unsigned int pci1Mem1Length)
{
    unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length;

    if (pci1Mem1Length == 0)
        pci1Mem1Top++;

    pci1Mem1Base = pci1Mem1Base >> 21;
    pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21;
    GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base);
    GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top);
}

/*
 * pci0GetIOspaceBase - Return PCI0 IO Base Address.
 * Inputs: N/A
 * Returns: PCI0 IO Base Address.
 */

static unsigned int pci0GetIOspaceBase(void)
{
    unsigned int base;
    GT_READ(GT_PCI0IOLD_OFS, &base);
    base = base << 21;
    return base;
}

/*
 * pci0GetIOspaceSize - Return PCI0 IO Bar Size.
 * Inputs: N/A
 * Returns: PCI0 IO Bar Size.
 */

static unsigned int pci0GetIOspaceSize(void)
{
    unsigned int top, base, size;
    GT_READ(GT_PCI0IOLD_OFS, &base);
    base = base << 21;
    GT_READ(GT_PCI0IOHD_OFS, &top);
    top = (top << 21);
    size = ((top - base) & 0xfffffff);
    size = size | 0x1fffff;
    return (size + 1);
}

/*
 * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address.
 * Inputs: N/A
 * Returns: PCI0 Memory 0 Base Address.
 */

static unsigned int pci0GetMemory0Base(void)
{
    unsigned int base;
    GT_READ(GT_PCI0M0LD_OFS, &base);
    base = base << 21;
    return base;
}

/*
 * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size.
 * Inputs: N/A
 * Returns: PCI0 Memory 0 Bar Size.
 */

static unsigned int pci0GetMemory0Size(void)
{
    unsigned int top, base, size;
    GT_READ(GT_PCI0M0LD_OFS, &base);
    base = base << 21;
    GT_READ(GT_PCI0M0HD_OFS, &top);
    top = (top << 21);
    size = ((top - base) & 0xfffffff);
    size = size | 0x1fffff;
    return (size + 1);
}

/*
 * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address.
 * Inputs: N/A
 * Returns: PCI0 Memory 1 Base Address.
 */

static unsigned int pci0GetMemory1Base(void)
{
    unsigned int base;
    GT_READ(GT_PCI0M1LD_OFS, &base);
    base = base << 21;
    return base;
}

/*
 * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size.
 * Inputs: N/A
 * Returns: PCI0 Memory 1 Bar Size.
 */

static unsigned int pci0GetMemory1Size(void)
{
    unsigned int top, base, size;
    GT_READ(GT_PCI0M1LD_OFS, &base);
    base = base << 21;
    GT_READ(GT_PCI0M1HD_OFS, &top);
    top = (top << 21);
    size = ((top - base) & 0xfffffff);
    size = size | 0x1fffff;
    return (size + 1);
}

/*
 * pci1GetIOspaceBase - Return PCI1 IO Base Address.
 * Inputs: N/A
 * Returns: PCI1 IO Base Address.
 */

static unsigned int pci1GetIOspaceBase(void)
{
    unsigned int base;
    GT_READ(GT_PCI1IOLD_OFS, &base);
    base = base << 21;
    return base;
}

/*
 * pci1GetIOspaceSize - Return PCI1 IO Bar Size.
 * Inputs: N/A
 * Returns: PCI1 IO Bar Size.
 */

static unsigned int pci1GetIOspaceSize(void)
{
    unsigned int top, base, size;
    GT_READ(GT_PCI1IOLD_OFS, &base);
    base = base << 21;
    GT_READ(GT_PCI1IOHD_OFS, &top);
    top = (top << 21);
    size = ((top - base) & 0xfffffff);
    size = size | 0x1fffff;
    return (size + 1);
}

/*
 * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address.
 * Inputs: N/A
 * Returns: PCI1 Memory 0 Base Address.
 */

static unsigned int pci1GetMemory0Base(void)
{
    unsigned int base;
    GT_READ(GT_PCI1M0LD_OFS, &base);
    base = base << 21;
    return base;
}

/*
 * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size.
 * Inputs: N/A
 * Returns: PCI1 Memory 0 Bar Size.
 */

static unsigned int pci1GetMemory0Size(void)
{
    unsigned int top, base, size;
    GT_READ(GT_PCI1M1LD_OFS, &base);
    base = base << 21;
    GT_READ(GT_PCI1M1HD_OFS, &top);
    top = (top << 21);
    size = ((top - base) & 0xfffffff);
    size = size | 0x1fffff;
    return (size + 1);
}

/*
 * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address.
 * Inputs: N/A
 * Returns: PCI1 Memory 1 Base Address.
 */

static unsigned int pci1GetMemory1Base(void)
{
    unsigned int base;
    GT_READ(GT_PCI1M1LD_OFS, &base);
    base = base << 21;
    return base;
}

/*
 * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size.
 * Inputs: N/A
 * Returns: PCI1 Memory 1 Bar Size.
 */

static unsigned int pci1GetMemory1Size(void)
{
    unsigned int top, base, size;
    GT_READ(GT_PCI1M1LD_OFS, &base);
    base = base << 21;
    GT_READ(GT_PCI1M1HD_OFS, &top);
    top = (top << 21);
    size = ((top - base) & 0xfffffff);
    size = size | 0x1fffff;
    return (size + 1);
}



/*
 * pci_range_ck -
 *
 * Check if the pci device that are trying to access does really exists
 * on the evaluation board.  
 *
 * Inputs :
 * bus - bus number (0 for PCI 0 ; 1 for PCI 1)
 * dev - number of device on the specific pci bus
 *
 * Outpus :
 * 0 - if OK , 1 - if failure
 */
static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev)
{
    /*
     * We don't even pretend to handle other busses than bus 0 correctly.
     * Accessing device 31 crashes the CP7000 for some reason.
     */
    if ((bus == 0) && (dev != 31))
        return 0;
    return -1;
}

/*
 * pciXReadConfigReg  - Read from a PCI 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
 *
 */
static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device)
{
    unsigned int DataForRegCf8;
    unsigned int data;

    DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
             (PCI_FUNC(device->devfn) << 8) |
             (offset & ~0x3)) | 0x80000000;
    GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);

    /*
     * The casual observer might wonder why the READ is duplicated here,
     * rather than immediately following the WRITE, and just have the swap
     * in the "if".  That's because there is a latency problem with trying
     * to read immediately after setting up the address register.  The "if"
     * check gives enough time for the address to stabilize, so the READ
     * can work.
     */
    if (PCI_SLOT(device->devfn) == SELF) {    /* This board */
        GT_READ(GT_PCI0_CFGDATA_OFS, &data);
        return data;
    } else { /* The PCI is working in LE Mode so swap the Data. */
        GT_READ(GT_PCI0_CFGDATA_OFS, &data);
        return cpu_to_le32(data);
    }
}

static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device)
{
    unsigned int DataForRegCf8;
    unsigned int data;

    DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
             (PCI_FUNC(device->devfn) << 8) |
             (offset & ~0x3)) | 0x80000000;
    /*
     * The casual observer might wonder why the READ is duplicated here,
     * rather than immediately following the WRITE, and just have the
     * swap in the "if".  That's because there is a latency problem
     * with trying to read immediately after setting up the address
     * register.  The "if" check gives enough time for the address
     * to stabilize, so the READ can work.
     */
    if (PCI_SLOT(device->devfn) == SELF) {    /* This board */
        /* when configurating our own PCI 1 L-unit the access is through  
           the PCI 0 interface with reg number = reg number + 0x80 */
        DataForRegCf8 |= 0x80;
        GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
    } else {        /* The PCI is working in LE Mode so swap the Data. */
        GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);
    }
    if (PCI_SLOT(device->devfn) == SELF) {    /* This board */
        GT_READ(GT_PCI0_CFGDATA_OFS, &data);
        return data;
    } else {
        GT_READ(GT_PCI1_CFGDATA_OFS, &data);
        return cpu_to_le32(data);
    }
}



/*
 * pciXWriteConfigReg - Write to a PCI configuration register
 *                    - Make sure the GT is configured as a master before 
 *                      writingto 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
 *
 */
static void pci0WriteConfigReg(unsigned int offset,
                   struct pci_dev *device, unsigned int data)
{
    unsigned int DataForRegCf8;

    DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
             (PCI_FUNC(device->devfn) << 8) |
             (offset & ~0x3)) | 0x80000000;
    GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
    if (PCI_SLOT(device->devfn) == SELF) {    /* This board */
        GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
    } else {        /* configuration Transaction over the pci. */
        /* The PCI is working in LE Mode so swap the Data. */
        GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data));
    }
}

static void pci1WriteConfigReg(unsigned int offset,
                   struct pci_dev *device, unsigned int data)
{
    unsigned int DataForRegCf8;

    DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
             (PCI_FUNC(device->devfn) << 8) |
             (offset & ~0x3)) | 0x80000000;
    /*
     * There is a latency problem
     * with trying to read immediately after setting up the address
     * register.  The "if" check gives enough time for the address
     * to stabilize, so the WRITE can work.
     */
    if (PCI_SLOT(device->devfn) == SELF) {    /* This board */
        /*
         * when configurating our own PCI 1 L-unit the access is through
         * the PCI 0 interface with reg number = reg number + 0x80
         */
        DataForRegCf8 |= 0x80;
        GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
    } else {    /* configuration Transaction over the pci. */
        /* The PCI is working in LE Mode so swap the Data. */
        GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);
    }
    if (PCI_SLOT(device->devfn) == SELF) {    /* This board */
        GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
    } else {        /* configuration Transaction over the pci. */
        GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data));
    }
}


/*
 * galileo_pcibios_(read/write)_config_(dword/word/byte) -
 *
 * reads/write a dword/word/byte register from the configuration space
 * of a device.
 *
 * Inputs :
 * bus - bus number
 * dev - device number
 * offset - register offset in the configuration space
 * val - value to be written / read
 *
 * Outputs :
 * PCIBIOS_SUCCESSFUL when operation was succesfull
 * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous
 * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned
 */

static int galileo_pcibios_read_config_dword(struct pci_dev *device,
                         int offset, u32 * val)
{
    int dev, bus;
    bus = device->bus->number;
    dev = PCI_SLOT(device->devfn);

    if (pci_range_ck(bus, dev)) {
        *val = 0xffffffff;
        return PCIBIOS_DEVICE_NOT_FOUND;
    }
    if (offset & 0x3)
        return PCIBIOS_BAD_REGISTER_NUMBER;
    if (bus == 0)
        *val = pci0ReadConfigReg(offset, device);

    /*  This is so that the upper PCI layer will get the correct return value if
       we're not attached to anything.  */
    if ((offset == 0) && (*val == 0xffffffff)) {
        return PCIBIOS_DEVICE_NOT_FOUND;
    }

    return PCIBIOS_SUCCESSFUL;
}

static int galileo_pcibios_read_config_word(struct pci_dev *device,
                        int offset, u16 * val)
{
    int dev, bus;

    bus = device->bus->number;
    dev = PCI_SLOT(device->devfn);

    if (pci_range_ck(bus, dev)) {
        *val = 0xffff;
        return PCIBIOS_DEVICE_NOT_FOUND;
    }
    if (offset & 0x1)
        return PCIBIOS_BAD_REGISTER_NUMBER;

    if (bus == 0)
        *val =
            (unsigned short) (pci0ReadConfigReg(offset, device) >>
                      ((offset & ~0x3) * 8));

    return PCIBIOS_SUCCESSFUL;
}

static int galileo_pcibios_read_config_byte(struct pci_dev *device,
                        int offset, u8 * val)
{
    int dev, bus;

    bus = device->bus->number;
    dev = PCI_SLOT(device->devfn);

    if (pci_range_ck(bus, dev)) {
        *val = 0xff;
        return PCIBIOS_DEVICE_NOT_FOUND;
    }

    if (bus == 0)
        *val =
            (unsigned char) (pci0ReadConfigReg(offset, device) >>
                     ((offset & ~0x3) * 8));

    /*
     *  This is so that the upper PCI layer will get the correct return
     * value if we're not attached to anything.
     */
    if ((offset == 0xe) && (*val == 0xff)) {
        u32 MasterAbort;
        GT_READ(GT_INTRCAUSE_OFS, &MasterAbort);
        if (MasterAbort & 0x40000) {
            GT_WRITE(GT_INTRCAUSE_OFS,
                 (MasterAbort & 0xfffbffff));
            return PCIBIOS_DEVICE_NOT_FOUND;
        }
    }

    return PCIBIOS_SUCCESSFUL;
}

static int galileo_pcibios_write_config_dword(struct pci_dev *device,
                          int offset, u32 val)
{
    int dev, bus;

    bus = device->bus->number;
    dev = PCI_SLOT(device->devfn);

    if (pci_range_ck(bus, dev))
        return PCIBIOS_DEVICE_NOT_FOUND;
    if (offset & 0x3)
        return PCIBIOS_BAD_REGISTER_NUMBER;
    if (bus == 0)
        pci0WriteConfigReg(offset, device, val);
//  if (bus == 1) pci1WriteConfigReg (offset,device,val);

    return PCIBIOS_SUCCESSFUL;
}


static int galileo_pcibios_write_config_word(struct pci_dev *device,
                         int offset, u16 val)
{
    int dev, bus;
    unsigned long tmp;

    bus = device->bus->number;
    dev = PCI_SLOT(device->devfn);

    if (pci_range_ck(bus, dev))
        return PCIBIOS_DEVICE_NOT_FOUND;
    if (offset & 0x1)
        return PCIBIOS_BAD_REGISTER_NUMBER;
    if (bus == 0)
        tmp = pci0ReadConfigReg(offset, device);
//  if (bus == 1) tmp = pci1ReadConfigReg (offset,device);

    if ((offset % 4) == 0)
        tmp = (tmp & 0xffff0000) | (val & 0xffff);
    if ((offset % 4) == 2)
        tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16);

    if (bus == 0)
        pci0WriteConfigReg(offset, device, tmp);
//  if (bus == 1) pci1WriteConfigReg (offset,device,tmp);
    return PCIBIOS_SUCCESSFUL;
}

static int galileo_pcibios_write_config_byte(struct pci_dev *device,
                         int offset, u8 val)
{
    int dev, bus;
    unsigned long tmp;

    bus = device->bus->number;
    dev = PCI_SLOT(device->devfn);

    if (pci_range_ck(bus, dev))
        return PCIBIOS_DEVICE_NOT_FOUND;
    if (bus == 0)
        tmp = pci0ReadConfigReg(offset, device);
//  if (bus == 1) tmp = pci1ReadConfigReg (offset,device);

    if ((offset % 4) == 0)
        tmp = (tmp & 0xffffff00) | (val & 0xff);
    if ((offset % 4) == 1)
        tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8);
    if ((offset % 4) == 2)
        tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16);
    if ((offset % 4) == 3)
        tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24);

    if (bus == 0)
        pci0WriteConfigReg(offset, device, tmp);
//  if (bus == 1) pci1WriteConfigReg (offset,device,tmp);

    return PCIBIOS_SUCCESSFUL;
}

static void galileo_pcibios_set_master(struct pci_dev *dev)
{
    u16 cmd;

    galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
    cmd |= PCI_COMMAND_MASTER;
    galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
}

/*  Externally-expected functions.  Do not change function names  */

int pcibios_enable_resources(struct pci_dev *dev)
{
    u16 cmd, old_cmd;
    u8 tmp1;
    int idx;
    struct resource *r;

    galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
    old_cmd = cmd;
    for (idx = 0; idx < 6; idx++) {
        r = &dev->resource[idx];
        if (!r->start && r->end) {
            printk(KERN_ERR
                   "PCI: Device %s not available because of "
                   "resource collisions\n", dev->slot_name);
            return -EINVAL;
        }
        if (r->flags & IORESOURCE_IO)
            cmd |= PCI_COMMAND_IO;
        if (r->flags & IORESOURCE_MEM)
            cmd |= PCI_COMMAND_MEMORY;
    }
    if (cmd != old_cmd) {
        galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
    }

    /*
     * Let's fix up the latency timer and cache line size here.  Cache
     * line size = 32 bytes / sizeof dword (4) = 8.
     * Latency timer must be > 8.  32 is random but appears to work.
     */
    galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
    if (tmp1 != 8) {
        printk(KERN_WARNING "PCI setting cache line size to 8 from "
               "%d\n", tmp1);
        galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
                          8);
    }
    galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1);
    if (tmp1 < 32) {
        printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
               tmp1);
        galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER,
                          32);
    }

    return 0;
}

int pcibios_enable_device(struct pci_dev *dev)
{
    return pcibios_enable_resources(dev);
}

void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
                 struct resource *res, int resource)
{
    u32 new, check;
    int reg;

    return;

    new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
    if (resource < 6) {
        reg = PCI_BASE_ADDRESS_0 + 4 * resource;
    } else if (resource == PCI_ROM_RESOURCE) {
        res->flags |= PCI_ROM_ADDRESS_ENABLE;
        reg = dev->rom_base_reg;
    } else {
        /*
         * Somebody might have asked allocation of a non-standard
         * resource
         */
        return;
    }

    pci_write_config_dword(dev, reg, new);
    pci_read_config_dword(dev, reg, &check);
    if ((new ^ check) &
        ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
         PCI_BASE_ADDRESS_MEM_MASK)) {
        printk(KERN_ERR "PCI: Error while updating region "
               "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
               new, check);
    }
}

void pcibios_align_resource(void *data, struct resource *res,
                unsigned long size)
{
    struct pci_dev *dev = data;

    if (res->flags & IORESOURCE_IO) {
        unsigned long start = res->start;

        /* We need to avoid collisions with `mirrored' VGA ports
           and other strange ISA hardware, so we always want the
           addresses kilobyte aligned.  */
        if (size > 0x100) {
            printk(KERN_ERR "PCI: I/O Region %s/%d too large"
                   " (%ld bytes)\n", dev->slot_name,
                    dev->resource - res, size);
        }

        start = (start + 1024 - 1) & ~(1024 - 1);
        res->start = start;
    }
}

struct pci_ops galileo_pci_ops = {
    galileo_pcibios_read_config_byte,
    galileo_pcibios_read_config_word,
    galileo_pcibios_read_config_dword,
    galileo_pcibios_write_config_byte,
    galileo_pcibios_write_config_word,
    galileo_pcibios_write_config_dword
};

struct pci_fixup pcibios_fixups[] = {
    {0}
};

void __init pcibios_fixup_bus(struct pci_bus *c)
{
    gt64120_board_pcibios_fixup_bus(c);
}

/*
 * This code was derived from Galileo Technology's example
 * and significantly reworked.
 *
 * This is very simple.  It does not scan multiple function devices.  It does
 * not scan behind bridges.  Those would be simple to implement, but we don't
 * currently need this.
 */

static void __init scan_and_initialize_pci(void)
{
    struct pci_device pci_devices[MAX_PCI_DEVS];

    if (scan_pci_bus(pci_devices)) {
        allocate_pci_space(pci_devices);
    }
}

/*
 * This is your basic PCI scan.  It goes through each slot and checks to
 * see if there's something that responds.  If so, then get the size and
 * type of each of the responding BARs.  Save them for later.
 */

static u32 __init scan_pci_bus(struct pci_device *pci_devices)
{
    u32 arrayCounter = 0;
    u32 memType;
    u32 memSize;
    u32 pci_slot, bar;
    u32 id;
    u32 c18RegValue;
    struct pci_dev device;

    /*
     * According to PCI REV 2.1 MAX agents on the bus are 21.
     * We don't bother scanning ourselves (slot 0).
     */
    for (pci_slot = 1; pci_slot < 22; pci_slot++) {

        device.devfn = PCI_DEVFN(pci_slot, 0);
        id = pci0ReadConfigReg(PCI_VENDOR_ID, &device);

        /*
         *  Check for a PCI Master Abort (nothing responds in the
         * slot)
         */
        GT_READ(GT_INTRCAUSE_OFS, &c18RegValue);
        /*
         * Clearing bit 18 of in the Cause Register 0xc18 by
         * writting 0.
         */
        GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff));
        if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) {
            pci_devices[arrayCounter].slot = pci_slot;
            for (bar = 0; bar < 6; bar++) {
                memType =
                    pci0ReadConfigReg(PCI_BASE_ADDRESS_0 +
                              (bar * 4), &device);
                pci_devices[arrayCounter].BARtype[bar] =
                    memType & 1;
                pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
                           (bar * 4), &device,
                           0xffffffff);
                memSize =
                    pci0ReadConfigReg(PCI_BASE_ADDRESS_0 +
                              (bar * 4), &device);
                if (memType & 1) {    /*  IO space  */
                    pci_devices[arrayCounter].
                        BARsize[bar] =
                        ~(memSize & 0xfffffffc) + 1;
                } else {    /*  memory space */
                    pci_devices[arrayCounter].
                        BARsize[bar] =
                        ~(memSize & 0xfffffff0) + 1;
                }
            }    /*  BAR counter  */

            arrayCounter++;
        }
        /*  found a device  */
    } /*  slot counter  */

    if (arrayCounter < MAX_PCI_DEVS)
        pci_devices[arrayCounter].slot = -1;

    return arrayCounter;
}

#define ALIGN(val,align)        (((val) + ((align) - 1)) & ~((align) - 1))
#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))

/*
 * This function goes through the list of devices and allocates the BARs in
 * either IO or MEM space.  It does it in order of size, which will limit the
 * amount of fragmentation we have in the IO and MEM spaces.
 */

static void __init allocate_pci_space(struct pci_device *pci_devices)
{
    u32 count, maxcount, bar;
    u32 maxSize, maxDevice, maxBAR;
    u32 alignto;
    u32 base;
    u32 pci0_mem_base = pci0GetMemory0Base();
    u32 pci0_io_base = pci0GetIOspaceBase();
    struct pci_dev device;

    /*  How many PCI devices do we have?  */
    maxcount = MAX_PCI_DEVS;
    for (count = 0; count < MAX_PCI_DEVS; count++) {
        if (pci_devices[count].slot == -1) {
            maxcount = count;
            break;
        }
    }

    do {
        /*  Find the largest size BAR we need to allocate  */
        maxSize = 0;
        for (count = 0; count < maxcount; count++) {
            for (bar = 0; bar < 6; bar++) {
                if (pci_devices[count].BARsize[bar] >
                    maxSize) {
                    maxSize =
                        pci_devices[count].
                        BARsize[bar];
                    maxDevice = count;
                    maxBAR = bar;
                }
            }
        }

        /*
         * We've found the largest BAR.  Allocate it into IO or
         * mem space.  We don't idiot check the bases to make
         * sure they haven't overflowed the current size for that
         * aperture.  
         * Don't bother to enable the device's IO or MEM space here.
         * That will be done in pci_enable_resources if the device is
         * activated by a driver.
         */
        if (maxSize) {
            device.devfn =
                PCI_DEVFN(pci_devices[maxDevice].slot, 0);
            if (pci_devices[maxDevice].BARtype[maxBAR] == 1) {
                alignto = MAX(0x1000, maxSize);
                base = ALIGN(pci0_io_base, alignto);
                pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
                           (maxBAR * 4), &device,
                           base | 0x1);
                pci0_io_base = base + alignto;
            } else {
                alignto = MAX(0x1000, maxSize);
                base = ALIGN(pci0_mem_base, alignto);
                pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
                           (maxBAR * 4), &device,
                           base);
                pci0_mem_base = base + alignto;
            }
            /*
             * This entry is finished.  Remove it from the list
             * we'll scan.
             */
            pci_devices[maxDevice].BARsize[maxBAR] = 0;
        }
    } while (maxSize);
}

void __init pcibios_init(void)
{
    u32 tmp;
    struct pci_dev controller;

    controller.devfn = SELF;

    GT_READ(GT_PCI0_CMD_OFS, &tmp);
    GT_READ(GT_PCI0_BARE_OFS, &tmp);

    /*
     * You have to enable bus mastering to configure any other
     * card on the bus.
     */
    tmp = pci0ReadConfigReg(PCI_COMMAND, &controller);
    tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
    pci0WriteConfigReg(PCI_COMMAND, &controller, tmp);

    /*  This scans the PCI bus and sets up initial values.  */
    scan_and_initialize_pci();

    /*
     *  Reset PCI I/O and PCI MEM values to ones supported by EVM.
     */
    ioport_resource.start = GT_PCI_IO_BASE;
    ioport_resource.end   = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
    iomem_resource.start  = GT_PCI_MEM_BASE;
    iomem_resource.end    = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1;

    pci_scan_bus(0, &galileo_pci_ops, NULL);
}

/*
 * for parsing "pci=" kernel boot arguments.
 */
char *pcibios_setup(char *str)
{
        printk(KERN_INFO "rr: pcibios_setup\n");
        /* Nothing to do for now.  */

        return str;
}

unsigned __init int pcibios_assign_all_busses(void)
{
    return 1;
}

#endif    /* CONFIG_PCI */

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0062 ]--