📄 pci.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 + -