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

📄 pci_sabre.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $Id: pci_sabre.c,v 1.41.2.1 2002/03/03 10:31:56 davem Exp $ * pci_sabre.c: Sabre specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) * Copyright (C) 1998, 1999 Eddie C. Dost   (ecd@skynet.be) * Copyright (C) 1999 Jakub Jelinek   (jakub@redhat.com) */#include <linux/kernel.h>#include <linux/types.h>#include <linux/pci.h>#include <linux/init.h>#include <linux/slab.h>#include <asm/apb.h>#include <asm/pbm.h>#include <asm/iommu.h>#include <asm/irq.h>#include <asm/smp.h>#include "pci_impl.h"#include "iommu_common.h"/* All SABRE registers are 64-bits.  The following accessor * routines are how they are accessed.  The REG parameter * is a physical address. */#define sabre_read(__reg) \({	u64 __ret; \	__asm__ __volatile__("ldxa [%1] %2, %0" \			     : "=r" (__ret) \			     : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \			     : "memory"); \	__ret; \})#define sabre_write(__reg, __val) \	__asm__ __volatile__("stxa %0, [%1] %2" \			     : /* no outputs */ \			     : "r" (__val), "r" (__reg), \			       "i" (ASI_PHYS_BYPASS_EC_E) \			     : "memory")/* SABRE PCI controller register offsets and definitions. */#define SABRE_UE_AFSR		0x0030UL#define  SABRE_UEAFSR_PDRD	 0x4000000000000000UL	/* Primary PCI DMA Read */#define  SABRE_UEAFSR_PDWR	 0x2000000000000000UL	/* Primary PCI DMA Write */#define  SABRE_UEAFSR_SDRD	 0x0800000000000000UL	/* Secondary PCI DMA Read */#define  SABRE_UEAFSR_SDWR	 0x0400000000000000UL	/* Secondary PCI DMA Write */#define  SABRE_UEAFSR_SDTE	 0x0200000000000000UL	/* Secondary DMA Translation Error */#define  SABRE_UEAFSR_PDTE	 0x0100000000000000UL	/* Primary DMA Translation Error */#define  SABRE_UEAFSR_BMSK	 0x0000ffff00000000UL	/* Bytemask */#define  SABRE_UEAFSR_OFF	 0x00000000e0000000UL	/* Offset (AFAR bits [5:3] */#define  SABRE_UEAFSR_BLK	 0x0000000000800000UL	/* Was block operation */#define SABRE_UECE_AFAR		0x0038UL#define SABRE_CE_AFSR		0x0040UL#define  SABRE_CEAFSR_PDRD	 0x4000000000000000UL	/* Primary PCI DMA Read */#define  SABRE_CEAFSR_PDWR	 0x2000000000000000UL	/* Primary PCI DMA Write */#define  SABRE_CEAFSR_SDRD	 0x0800000000000000UL	/* Secondary PCI DMA Read */#define  SABRE_CEAFSR_SDWR	 0x0400000000000000UL	/* Secondary PCI DMA Write */#define  SABRE_CEAFSR_ESYND	 0x00ff000000000000UL	/* ECC Syndrome */#define  SABRE_CEAFSR_BMSK	 0x0000ffff00000000UL	/* Bytemask */#define  SABRE_CEAFSR_OFF	 0x00000000e0000000UL	/* Offset */#define  SABRE_CEAFSR_BLK	 0x0000000000800000UL	/* Was block operation */#define SABRE_UECE_AFAR_ALIAS	0x0048UL	/* Aliases to 0x0038 */#define SABRE_IOMMU_CONTROL	0x0200UL#define  SABRE_IOMMUCTRL_ERRSTS	 0x0000000006000000UL	/* Error status bits */#define  SABRE_IOMMUCTRL_ERR	 0x0000000001000000UL	/* Error present in IOTLB */#define  SABRE_IOMMUCTRL_LCKEN	 0x0000000000800000UL	/* IOTLB lock enable */#define  SABRE_IOMMUCTRL_LCKPTR	 0x0000000000780000UL	/* IOTLB lock pointer */#define  SABRE_IOMMUCTRL_TSBSZ	 0x0000000000070000UL	/* TSB Size */#define  SABRE_IOMMU_TSBSZ_1K   0x0000000000000000#define  SABRE_IOMMU_TSBSZ_2K   0x0000000000010000#define  SABRE_IOMMU_TSBSZ_4K   0x0000000000020000#define  SABRE_IOMMU_TSBSZ_8K   0x0000000000030000#define  SABRE_IOMMU_TSBSZ_16K  0x0000000000040000#define  SABRE_IOMMU_TSBSZ_32K  0x0000000000050000#define  SABRE_IOMMU_TSBSZ_64K  0x0000000000060000#define  SABRE_IOMMU_TSBSZ_128K 0x0000000000070000#define  SABRE_IOMMUCTRL_TBWSZ	 0x0000000000000004UL	/* TSB assumed page size */#define  SABRE_IOMMUCTRL_DENAB	 0x0000000000000002UL	/* Diagnostic Mode Enable */#define  SABRE_IOMMUCTRL_ENAB	 0x0000000000000001UL	/* IOMMU Enable */#define SABRE_IOMMU_TSBBASE	0x0208UL#define SABRE_IOMMU_FLUSH	0x0210UL#define SABRE_IMAP_A_SLOT0	0x0c00UL#define SABRE_IMAP_B_SLOT0	0x0c20UL#define SABRE_IMAP_SCSI		0x1000UL#define SABRE_IMAP_ETH		0x1008UL#define SABRE_IMAP_BPP		0x1010UL#define SABRE_IMAP_AU_REC	0x1018UL#define SABRE_IMAP_AU_PLAY	0x1020UL#define SABRE_IMAP_PFAIL	0x1028UL#define SABRE_IMAP_KMS		0x1030UL#define SABRE_IMAP_FLPY		0x1038UL#define SABRE_IMAP_SHW		0x1040UL#define SABRE_IMAP_KBD		0x1048UL#define SABRE_IMAP_MS		0x1050UL#define SABRE_IMAP_SER		0x1058UL#define SABRE_IMAP_UE		0x1070UL#define SABRE_IMAP_CE		0x1078UL#define SABRE_IMAP_PCIERR	0x1080UL#define SABRE_IMAP_GFX		0x1098UL#define SABRE_IMAP_EUPA		0x10a0UL#define SABRE_ICLR_A_SLOT0	0x1400UL#define SABRE_ICLR_B_SLOT0	0x1480UL#define SABRE_ICLR_SCSI		0x1800UL#define SABRE_ICLR_ETH		0x1808UL#define SABRE_ICLR_BPP		0x1810UL#define SABRE_ICLR_AU_REC	0x1818UL#define SABRE_ICLR_AU_PLAY	0x1820UL#define SABRE_ICLR_PFAIL	0x1828UL#define SABRE_ICLR_KMS		0x1830UL#define SABRE_ICLR_FLPY		0x1838UL#define SABRE_ICLR_SHW		0x1840UL#define SABRE_ICLR_KBD		0x1848UL#define SABRE_ICLR_MS		0x1850UL#define SABRE_ICLR_SER		0x1858UL#define SABRE_ICLR_UE		0x1870UL#define SABRE_ICLR_CE		0x1878UL#define SABRE_ICLR_PCIERR	0x1880UL#define SABRE_WRSYNC		0x1c20UL#define SABRE_PCICTRL		0x2000UL#define  SABRE_PCICTRL_MRLEN	 0x0000001000000000UL	/* Use MemoryReadLine for block loads/stores */#define  SABRE_PCICTRL_SERR	 0x0000000400000000UL	/* Set when SERR asserted on PCI bus */#define  SABRE_PCICTRL_ARBPARK	 0x0000000000200000UL	/* Bus Parking 0=Ultra-IIi 1=prev-bus-owner */#define  SABRE_PCICTRL_CPUPRIO	 0x0000000000100000UL	/* Ultra-IIi granted every other bus cycle */#define  SABRE_PCICTRL_ARBPRIO	 0x00000000000f0000UL	/* Slot which is granted every other bus cycle */#define  SABRE_PCICTRL_ERREN	 0x0000000000000100UL	/* PCI Error Interrupt Enable */#define  SABRE_PCICTRL_RTRYWE	 0x0000000000000080UL	/* DMA Flow Control 0=wait-if-possible 1=retry */#define  SABRE_PCICTRL_AEN	 0x000000000000000fUL	/* Slot PCI arbitration enables */#define SABRE_PIOAFSR		0x2010UL#define  SABRE_PIOAFSR_PMA	 0x8000000000000000UL	/* Primary Master Abort */#define  SABRE_PIOAFSR_PTA	 0x4000000000000000UL	/* Primary Target Abort */#define  SABRE_PIOAFSR_PRTRY	 0x2000000000000000UL	/* Primary Excessive Retries */#define  SABRE_PIOAFSR_PPERR	 0x1000000000000000UL	/* Primary Parity Error */#define  SABRE_PIOAFSR_SMA	 0x0800000000000000UL	/* Secondary Master Abort */#define  SABRE_PIOAFSR_STA	 0x0400000000000000UL	/* Secondary Target Abort */#define  SABRE_PIOAFSR_SRTRY	 0x0200000000000000UL	/* Secondary Excessive Retries */#define  SABRE_PIOAFSR_SPERR	 0x0100000000000000UL	/* Secondary Parity Error */#define  SABRE_PIOAFSR_BMSK	 0x0000ffff00000000UL	/* Byte Mask */#define  SABRE_PIOAFSR_BLK	 0x0000000080000000UL	/* Was Block Operation */#define SABRE_PIOAFAR		0x2018UL#define SABRE_PCIDIAG		0x2020UL#define  SABRE_PCIDIAG_DRTRY	 0x0000000000000040UL	/* Disable PIO Retry Limit */#define  SABRE_PCIDIAG_IPAPAR	 0x0000000000000008UL	/* Invert PIO Address Parity */#define  SABRE_PCIDIAG_IPDPAR	 0x0000000000000004UL	/* Invert PIO Data Parity */#define  SABRE_PCIDIAG_IDDPAR	 0x0000000000000002UL	/* Invert DMA Data Parity */#define  SABRE_PCIDIAG_ELPBK	 0x0000000000000001UL	/* Loopback Enable - not supported */#define SABRE_PCITASR		0x2028UL#define  SABRE_PCITASR_EF	 0x0000000000000080UL	/* Respond to 0xe0000000-0xffffffff */#define  SABRE_PCITASR_CD	 0x0000000000000040UL	/* Respond to 0xc0000000-0xdfffffff */#define  SABRE_PCITASR_AB	 0x0000000000000020UL	/* Respond to 0xa0000000-0xbfffffff */#define  SABRE_PCITASR_89	 0x0000000000000010UL	/* Respond to 0x80000000-0x9fffffff */#define  SABRE_PCITASR_67	 0x0000000000000008UL	/* Respond to 0x60000000-0x7fffffff */#define  SABRE_PCITASR_45	 0x0000000000000004UL	/* Respond to 0x40000000-0x5fffffff */#define  SABRE_PCITASR_23	 0x0000000000000002UL	/* Respond to 0x20000000-0x3fffffff */#define  SABRE_PCITASR_01	 0x0000000000000001UL	/* Respond to 0x00000000-0x1fffffff */#define SABRE_PIOBUF_DIAG	0x5000UL#define SABRE_DMABUF_DIAGLO	0x5100UL#define SABRE_DMABUF_DIAGHI	0x51c0UL#define SABRE_IMAP_GFX_ALIAS	0x6000UL	/* Aliases to 0x1098 */#define SABRE_IMAP_EUPA_ALIAS	0x8000UL	/* Aliases to 0x10a0 */#define SABRE_IOMMU_VADIAG	0xa400UL#define SABRE_IOMMU_TCDIAG	0xa408UL#define SABRE_IOMMU_TAG		0xa580UL#define  SABRE_IOMMUTAG_ERRSTS	 0x0000000001800000UL	/* Error status bits */#define  SABRE_IOMMUTAG_ERR	 0x0000000000400000UL	/* Error present */#define  SABRE_IOMMUTAG_WRITE	 0x0000000000200000UL	/* Page is writable */#define  SABRE_IOMMUTAG_STREAM	 0x0000000000100000UL	/* Streamable bit - unused */#define  SABRE_IOMMUTAG_SIZE	 0x0000000000080000UL	/* 0=8k 1=16k */#define  SABRE_IOMMUTAG_VPN	 0x000000000007ffffUL	/* Virtual Page Number [31:13] */#define SABRE_IOMMU_DATA	0xa600UL#define SABRE_IOMMUDATA_VALID	 0x0000000040000000UL	/* Valid */#define SABRE_IOMMUDATA_USED	 0x0000000020000000UL	/* Used (for LRU algorithm) */#define SABRE_IOMMUDATA_CACHE	 0x0000000010000000UL	/* Cacheable */#define SABRE_IOMMUDATA_PPN	 0x00000000001fffffUL	/* Physical Page Number [33:13] */#define SABRE_PCI_IRQSTATE	0xa800UL#define SABRE_OBIO_IRQSTATE	0xa808UL#define SABRE_FFBCFG		0xf000UL#define  SABRE_FFBCFG_SPRQS	 0x000000000f000000	/* Slave P_RQST queue size */#define  SABRE_FFBCFG_ONEREAD	 0x0000000000004000	/* Slave supports one outstanding read */#define SABRE_MCCTRL0		0xf010UL#define  SABRE_MCCTRL0_RENAB	 0x0000000080000000	/* Refresh Enable */#define  SABRE_MCCTRL0_EENAB	 0x0000000010000000	/* Enable all ECC functions */#define  SABRE_MCCTRL0_11BIT	 0x0000000000001000	/* Enable 11-bit column addressing */#define  SABRE_MCCTRL0_DPP	 0x0000000000000f00	/* DIMM Pair Present Bits */#define  SABRE_MCCTRL0_RINTVL	 0x00000000000000ff	/* Refresh Interval */#define SABRE_MCCTRL1		0xf018UL#define  SABRE_MCCTRL1_AMDC	 0x0000000038000000	/* Advance Memdata Clock */#define  SABRE_MCCTRL1_ARDC	 0x0000000007000000	/* Advance DRAM Read Data Clock */#define  SABRE_MCCTRL1_CSR	 0x0000000000e00000	/* CAS to RAS delay for CBR refresh */#define  SABRE_MCCTRL1_CASRW	 0x00000000001c0000	/* CAS length for read/write */#define  SABRE_MCCTRL1_RCD	 0x0000000000038000	/* RAS to CAS delay */#define  SABRE_MCCTRL1_CP	 0x0000000000007000	/* CAS Precharge */#define  SABRE_MCCTRL1_RP	 0x0000000000000e00	/* RAS Precharge */#define  SABRE_MCCTRL1_RAS	 0x00000000000001c0	/* Length of RAS for refresh */#define  SABRE_MCCTRL1_CASRW2	 0x0000000000000038	/* Must be same as CASRW */#define  SABRE_MCCTRL1_RSC	 0x0000000000000007	/* RAS after CAS hold time */#define SABRE_RESETCTRL		0xf020UL#define SABRE_CONFIGSPACE	0x001000000UL#define SABRE_IOSPACE		0x002000000UL#define SABRE_IOSPACE_SIZE	0x000ffffffUL#define SABRE_MEMSPACE		0x100000000UL#define SABRE_MEMSPACE_SIZE	0x07fffffffUL/* UltraSparc-IIi Programmer's Manual, page 325, PCI * configuration space address format: *  *  32             24 23 16 15    11 10       8 7   2  1 0 * --------------------------------------------------------- * |0 0 0 0 0 0 0 0 1| bus | device | function | reg | 0 0 | * --------------------------------------------------------- */#define SABRE_CONFIG_BASE(PBM)	\	((PBM)->config_space | (1UL << 24))#define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG)	\	(((unsigned long)(BUS)   << 16) |	\	 ((unsigned long)(DEVFN) << 8)  |	\	 ((unsigned long)(REG)))static int hummingbird_p;static struct pci_bus *sabre_root_bus;static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm,				     unsigned char bus,				     unsigned int devfn,				     int where){	if (!pbm)		return NULL;	return (void *)		(SABRE_CONFIG_BASE(pbm) |		 SABRE_CONFIG_ENCODE(bus, devfn, where));}static int sabre_out_of_range(unsigned char devfn){	if (hummingbird_p)		return 0;	return (((PCI_SLOT(devfn) == 0) && (PCI_FUNC(devfn) > 0)) ||		((PCI_SLOT(devfn) == 1) && (PCI_FUNC(devfn) > 1)) ||		(PCI_SLOT(devfn) > 1));}static int __sabre_out_of_range(struct pci_pbm_info *pbm,				unsigned char bus,				unsigned char devfn){	if (hummingbird_p)		return 0;	return ((pbm->parent == 0) ||		((pbm == &pbm->parent->pbm_B) &&		 (bus == pbm->pci_first_busno) &&		 PCI_SLOT(devfn) > 8) ||		((pbm == &pbm->parent->pbm_A) &&		 (bus == pbm->pci_first_busno) &&		 PCI_SLOT(devfn) > 8));}static int __sabre_read_byte(struct pci_dev *dev, int where, u8 *value){	struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];	unsigned char bus = dev->bus->number;	unsigned int devfn = dev->devfn;	u8 *addr;	*value = 0xff;	addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);	if (!addr)		return PCIBIOS_SUCCESSFUL;	if (__sabre_out_of_range(pbm, bus, devfn))		return PCIBIOS_SUCCESSFUL;	pci_config_read8(addr, value);	return PCIBIOS_SUCCESSFUL;}static int __sabre_read_word(struct pci_dev *dev, int where, u16 *value){	struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];	unsigned char bus = dev->bus->number;	unsigned int devfn = dev->devfn;	u16 *addr;	*value = 0xffff;	addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);	if (!addr)		return PCIBIOS_SUCCESSFUL;	if (__sabre_out_of_range(pbm, bus, devfn))		return PCIBIOS_SUCCESSFUL;	if (where & 0x01) {		printk("pcibios_read_config_word: misaligned reg [%x]\n",		       where);		return PCIBIOS_SUCCESSFUL;	}	pci_config_read16(addr, value);	return PCIBIOS_SUCCESSFUL;}static int __sabre_read_dword(struct pci_dev *dev, int where, u32 *value){	struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];	unsigned char bus = dev->bus->number;	unsigned int devfn = dev->devfn;	u32 *addr;	*value = 0xffffffff;	addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);	if (!addr)		return PCIBIOS_SUCCESSFUL;	if (__sabre_out_of_range(pbm, bus, devfn))		return PCIBIOS_SUCCESSFUL;	if (where & 0x03) {		printk("pcibios_read_config_dword: misaligned reg [%x]\n",		       where);		return PCIBIOS_SUCCESSFUL;	}	pci_config_read32(addr, value);	return PCIBIOS_SUCCESSFUL;}/* When accessing PCI config space of the PCI controller itself (bus * 0, device slot 0, function 0) there are restrictions.  Each * register must be accessed as it's natural size.  Thus, for example * the Vendor ID must be accessed as a 16-bit quantity. */static int sabre_read_byte(struct pci_dev *dev, int where, u8 *value){	if (!dev->bus->number && sabre_out_of_range(dev->devfn)) {		*value = 0xff;		return PCIBIOS_SUCCESSFUL;	}	if (dev->bus->number || PCI_SLOT(dev->devfn))		return __sabre_read_byte(dev, where, value);	if (where < 8) {		u16 tmp;		__sabre_read_word(dev, where & ~1, &tmp);		if (where & 1)			*value = tmp >> 8;		else			*value = tmp & 0xff;		return PCIBIOS_SUCCESSFUL;	} else		return __sabre_read_byte(dev, where, value);}static int sabre_read_word(struct pci_dev *dev, int where, u16 *value){	if (!dev->bus->number && sabre_out_of_range(dev->devfn)) {		*value = 0xffff;		return PCIBIOS_SUCCESSFUL;	}	if (dev->bus->number || PCI_SLOT(dev->devfn))		return __sabre_read_word(dev, where, value);	if (where < 8)		return __sabre_read_word(dev, where, value);	else {		u8 tmp;		__sabre_read_byte(dev, where, &tmp);		*value = tmp;		__sabre_read_byte(dev, where + 1, &tmp);		*value |= tmp << 8;		return PCIBIOS_SUCCESSFUL;	}}static int sabre_read_dword(struct pci_dev *dev, int where, u32 *value){	u16 tmp;	if (!dev->bus->number && sabre_out_of_range(dev->devfn)) {		*value = 0xffffffff;		return PCIBIOS_SUCCESSFUL;	}	if (dev->bus->number || PCI_SLOT(dev->devfn))		return __sabre_read_dword(dev, where, value);	sabre_read_word(dev, where, &tmp);	*value = tmp;	sabre_read_word(dev, where + 2, &tmp);	*value |= tmp << 16;	return PCIBIOS_SUCCESSFUL;}static int __sabre_write_byte(struct pci_dev *dev, int where, u8 value){	struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];	unsigned char bus = dev->bus->number;	unsigned int devfn = dev->devfn;	u8 *addr;	addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);	if (!addr)		return PCIBIOS_SUCCESSFUL;	if (__sabre_out_of_range(pbm, bus, devfn))		return PCIBIOS_SUCCESSFUL;	pci_config_write8(addr, value);	return PCIBIOS_SUCCESSFUL;}static int __sabre_write_word(struct pci_dev *dev, int where, u16 value){	struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];	unsigned char bus = dev->bus->number;	unsigned int devfn = dev->devfn;	u16 *addr;	addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);	if (!addr)		return PCIBIOS_SUCCESSFUL;	if (__sabre_out_of_range(pbm, bus, devfn))		return PCIBIOS_SUCCESSFUL;	if (where & 0x01) {		printk("pcibios_write_config_word: misaligned reg [%x]\n",		       where);		return PCIBIOS_SUCCESSFUL;	}	pci_config_write16(addr, value);	return PCIBIOS_SUCCESSFUL;}

⌨️ 快捷键说明

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