⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci.c

📁 一个开放源码
💻 C
字号:
/* $Id: pci.c,v 1.2 2000/11/15 17:44:54 apc Exp $ *//* Copyright 1999-2000  AG Electronics Ltd. *//* This code is distributed without warranty under the GPL v2 (see COPYING) *//* Copyright 1999 AG Electronics Ltd */#include <pci.h>#include <iotypes.h>#include <stdio.h>#include <io.h>#define MMIO_DM_BASE 0xc0000000#define IO_DM_BASE   0x80000000#define MAXIMUM_RANGE 0xc0000000#define PLX_BASE 0x40000000#define PLX_REG(x) (*(volatile unsigned *)(PLX_BASE+(x)))#define LOCALREG_BASE 0x60000000#define LOCAL_REG(x) (*(volatile unsigned char *)(LOCALREG_BASE+(x)))#define PLX_COMMAND_BYTE (*(volatile unsigned char *)(PLX_BASE + 7))#define PLX_STATUS_BYTE (*(volatile unsigned char *)(PLX_BASE + 4))#define PLX_CONFIG_CONTROL PLX_REG(0xaC)#define PLX_MASTER_TYPE PLX_REG(0xa8)u32 read_32(ioaddr address){    u32 result;    __asm__ volatile ("lwbrx %0, 0, %1" : "=r" (result) : "r" (address));    return result;    }void write_32(ioaddr address, u32 data){    __asm__ volatile ("stwbrx %0, 0, %1" : : "r" (data), "r" (address));}u16 read_16(ioaddr address){    u16 result;    __asm__ volatile ("lhbrx %0, 0, %1" : "=r" (result) : "r" (address));    return result;    }void write_16(ioaddr address, u16 data){    __asm__ volatile ("sthbrx %0, 0, %1" : : "r" (data), "r" (address));}u8 read_8(ioaddr addr){    return *(volatile char *)addr;   }void write_8(ioaddr addr, u8 data){    *(volatile char *)addr = data;}typedef enum {PCI32, PCI16, PCI8} access_size;/* static ioaddr pci_offset; always zero */void *pci_to_local(ioaddr addr){    return (void *)(addr);}static ioaddr local_pci_address;ioaddr local_to_pci(volatile void *addr){    return local_pci_address + (ioaddr)addr;}void tpe3_init_pci(void){    /* Disable any current mastering setup */    PLX_REG(0xa0) = 0;    /* Turn off romboot */    LOCAL_REG(0) = 0;    /* Turn on initdone */    LOCAL_REG(1) = 1;    /* and range */    PLX_REG(0x9c) = MAXIMUM_RANGE;    /* Base address for mastering must be on 2GB boundary */    PLX_REG(0xa0) = MMIO_DM_BASE;    PLX_REG(0xa4) = IO_DM_BASE;    /* Set PCI base address and enable it all */    PLX_REG(0xa8) = MMIO_DM_BASE | 0x2007;        /* Put the slave window at the bottom of memory for now */    local_pci_address = PLX_REG(0x18) & 0xffffff00;    PLX_REG(0x84) = 1;}static unsigned config_read(unsigned address, int *error, access_size size){    unsigned result = 0;    unsigned status;        /* Put the address into the CONFIG cycle register */    PLX_CONFIG_CONTROL = (address & ~3) | 0x80000000;    address = IO_DM_BASE | (address & 3);        /* Perform the read or write */    if (error)	*error = 0;        /* Clear any PCI errors */    PLX_STATUS_BYTE = PLX_STATUS_BYTE;    /* Perform the read or write */    switch(size)    {        case PCI32:            result = read_32(address);            break;        case PCI16:            result = read_16(address);            break;        case PCI8:            result = read_8(address);    }        /* Clear the error, and record for the user */    status = PLX_STATUS_BYTE;    PLX_STATUS_BYTE = status;    if ((status & 0xf9) && error)	*error = -1;        PLX_CONFIG_CONTROL = 0;    return result;}static void config_write(unsigned address, unsigned data,        access_size size){    /* Put the address into the CONFIG cycle register */    PLX_CONFIG_CONTROL = (address & ~3) | 0x80000000;    address = IO_DM_BASE | (address & 3);        /* Clear any PCI errors */    PLX_STATUS_BYTE = PLX_STATUS_BYTE;    /* Perform the read or write */    switch(size)    {        case PCI32:            write_32(address, data);            break;        case PCI16:            write_16(address, data);            break;        case PCI8:            write_8(address, data);    }    /* Perform a read of a same location to ensure write has completed */    read_32(address);    PLX_CONFIG_CONTROL = 0;    /* Clear any PCI errors */    PLX_STATUS_BYTE = PLX_STATUS_BYTE;}int pci_config_read_32(int bus, int device, int function,                int reg, u32 *data){    unsigned pci_address = (bus << 16) | (device << 11) | (function << 8) | reg;    int error;    *data = config_read(pci_address, &error, PCI32);    return error;}void pci_config_write_32(int bus, int device, int function, int reg,                          u32 data){     unsigned pci_address = (bus << 16) | (device << 11) | (function << 8) | reg;     config_write(pci_address, data, PCI32);    } int pci_config_read_16(int bus, int device, int function,                int reg, u16 *data){    unsigned pci_address = (bus << 16) | (device << 11) | (function << 8) | reg;    int error;    *data = config_read(pci_address, &error, PCI16);        return error;}void pci_config_write_16(int bus, int device, int function, int reg,                          u16 data){     unsigned pci_address = (bus << 16) | (device << 11) | (function << 8) | reg;     config_write(pci_address, data, PCI16);    } int pci_config_read_8(int bus, int device, int function,                int reg, u8 *data){    unsigned pci_address = (bus << 16) | (device << 11) | (function << 8) | reg;    int error;    *data = config_read(pci_address, &error, PCI8);        return error;}void pci_config_write_8(int bus, int device, int function, int reg,                          u8 data){     unsigned pci_address = (bus << 16) | (device << 11) | (function << 8) | reg;     config_write(pci_address, data, PCI8);    } u8 in_8(ioaddr addr){    return read_8(addr | IO_DM_BASE);   }u16 in_16(ioaddr addr){    return read_16(addr | IO_DM_BASE);   }u32 in_32(ioaddr addr){    return read_32(addr | IO_DM_BASE);   }void out_8(ioaddr addr, u8 data){    write_8(addr | IO_DM_BASE, data);}void out_16(ioaddr addr, u16 data){    write_16(addr | IO_DM_BASE, data);}void out_32(ioaddr addr, u32 data){    write_32(addr | IO_DM_BASE, data);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -