提交 7ab0d619 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Start of e1000 and PCI code...

..basic e1000 initialization fails on ud0 due to reading EEPROM via EERD.
上级 1195b1b9
......@@ -32,6 +32,7 @@ OBJS = \
cga.o \
condvar.o \
console.o \
e1000.o \
exec.o \
file.o \
fs.o \
......@@ -45,6 +46,7 @@ OBJS = \
memide.o \
mp.o \
ns.o \
pci.o \
picirq.o \
pipe.o \
proc.o \
......
#include "types.h"
#include "amd64.h"
#include "kernel.h"
#include "pci.h"
#include "e1000reg.h"
static struct {
u32 membase;
u32 iobase;
u16 pcidevid;
} e1000;
static u32
e1000_io_read(u32 reg)
{
paddr pa = e1000.membase + reg;
volatile u32 *ptr = p2v(pa);
return *ptr;
}
static void
e1000_io_write(u32 reg, u32 val)
{
paddr pa = e1000.membase + reg;
volatile u32 *ptr = p2v(pa);
*ptr = val;
}
static int
eeprom_eerd_read(u16 off)
{
u32 reg;
int x;
// [E1000 5.3.1] Software EEPROM access
e1000_io_write(WMREG_EERD, (off<<EERD_ADDR_SHIFT) | EERD_START);
for (x = 0; x < 100; x++) {
reg = e1000_io_read(WMREG_EERD);
if (reg & EERD_DONE)
return (reg&EERD_DATA_MASK) >> EERD_DATA_SHIFT;
microdelay(50000);
}
return -1;
}
static int
eeprom_read(u16 *buf, int off, int count)
{
for (int i = 0; i < count; i++) {
int r = eeprom_eerd_read(off+i);
if (r < 0) {
cprintf("eeprom_read: cannot read\n");
return -1;
}
buf[i] = r;
}
return 0;
}
int
e1000attach(struct pci_func *pcif)
{
int r;
pci_func_enable(pcif);
e1000.membase = pcif->reg_base[0];
e1000.iobase = pcif->reg_base[2];
e1000.pcidevid = pcif->dev_id;
// Get the MAC address
u16 myaddr[3];
r = eeprom_read(&myaddr[0], EEPROM_OFF_MACADDR, 3);
if (r < 0)
return 0;
u8 *addr = (u8*) &myaddr[0];
cprintf("%x:%x:%x:%x:%x:%x\n",
addr[0], addr[1], addr[2],
addr[3], addr[4], addr[5]);
return 0;
}
/* $NetBSD: if_wmreg.h,v 1.14.4.1 2005/08/28 09:49:37 tron Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*/
/*
* Register description for the Intel i82542 (``Wiseman''),
* i82543 (``Livengood''), and i82544 (``Cordova'') Gigabit
* Ethernet chips.
*/
/*
* The Wiseman receive descriptor.
*
* The receive descriptor ring must be aligned to a 4K boundary,
* and there must be an even multiple of 8 descriptors in the ring.
*/
typedef struct wiseman_rxdesc {
u64 wrx_addr; /* buffer address */
u16 wrx_len; /* buffer length */
u16 wrx_cksum; /* checksum (starting at PCSS) */
u8 wrx_status; /* Rx status */
u8 wrx_errors; /* Rx errors */
u16 wrx_special; /* special field (VLAN, etc.) */
} __attribute__((__packed__)) wiseman_rxdesc_t;
/* wrx_status bits */
#define WRX_ST_DD (1U << 0) /* descriptor done */
#define WRX_ST_EOP (1U << 1) /* end of packet */
#define WRX_ST_IXSM (1U << 2) /* ignore checksum indication */
#define WRX_ST_VP (1U << 3) /* VLAN packet */
#define WRX_ST_BPDU (1U << 4) /* ??? */
#define WRX_ST_TCPCS (1U << 5) /* TCP checksum performed */
#define WRX_ST_IPCS (1U << 6) /* IP checksum performed */
#define WRX_ST_PIF (1U << 7) /* passed in-exact filter */
/* wrx_error bits */
#define WRX_ER_CE (1U << 0) /* CRC error */
#define WRX_ER_SE (1U << 1) /* symbol error */
#define WRX_ER_SEQ (1U << 2) /* sequence error */
#define WRX_ER_ICE (1U << 3) /* ??? */
#define WRX_ER_CXE (1U << 4) /* carrier extension error */
#define WRX_ER_TCPE (1U << 5) /* TCP checksum error */
#define WRX_ER_IPE (1U << 6) /* IP checksum error */
#define WRX_ER_RXE (1U << 7) /* Rx data error */
/* wrx_special field for VLAN packets */
#define WRX_VLAN_ID(x) ((x) & 0x0fff) /* VLAN identifier */
#define WRX_VLAN_CFI (1U << 12) /* Canonical Form Indicator */
#define WRX_VLAN_PRI(x) (((x) >> 13) & 7)/* VLAN priority field */
/*
* The Wiseman transmit descriptor.
*
* The transmit descriptor ring must be aligned to a 4K boundary,
* and there must be an even multiple of 8 descriptors in the ring.
*/
typedef struct wiseman_tx_fields {
u8 wtxu_status; /* Tx status */
u8 wtxu_options; /* options */
u16 wtxu_vlan; /* VLAN info */
} __attribute__((__packed__)) wiseman_txfields_t;
typedef struct wiseman_txdesc {
u64 wtx_addr; /* buffer address */
u32 wtx_cmdlen; /* command and length */
wiseman_txfields_t wtx_fields; /* fields; see below */
} __attribute__((__packed__)) wiseman_txdesc_t;
/* Commands for wtx_cmdlen */
#define WTX_CMD_EOP (1U << 24) /* end of packet */
#define WTX_CMD_IFCS (1U << 25) /* insert FCS */
#define WTX_CMD_RS (1U << 27) /* report status */
#define WTX_CMD_RPS (1U << 28) /* report packet sent */
#define WTX_CMD_DEXT (1U << 29) /* descriptor extension */
#define WTX_CMD_VLE (1U << 30) /* VLAN enable */
#define WTX_CMD_IDE (1U << 31) /* interrupt delay enable */
/* Descriptor types (if DEXT is set) */
#define WTX_DTYP_C (0U << 20) /* context */
#define WTX_DTYP_D (1U << 20) /* data */
/* wtx_fields status bits */
#define WTX_ST_DD (1U << 0) /* descriptor done */
#define WTX_ST_EC (1U << 1) /* excessive collisions */
#define WTX_ST_LC (1U << 2) /* late collision */
#define WTX_ST_TU (1U << 3) /* transmit underrun */
/* wtx_fields option bits for IP/TCP/UDP checksum offload */
#define WTX_IXSM (1U << 0) /* IP checksum offload */
#define WTX_TXSM (1U << 1) /* TCP/UDP checksum offload */
/* Maximum payload per Tx descriptor */
#define WTX_MAX_LEN 4096
/*
* The Livengood TCP/IP context descriptor.
*/
struct livengood_tcpip_ctxdesc {
u32 tcpip_ipcs; /* IP checksum context */
u32 tcpip_tucs; /* TCP/UDP checksum context */
u32 tcpip_cmdlen;
u32 tcpip_seg; /* TCP segmentation context */
};
/* commands for context descriptors */
#define WTX_TCPIP_CMD_TCP (1U << 24) /* 1 = TCP, 0 = UDP */
#define WTX_TCPIP_CMD_IP (1U << 25) /* 1 = IPv4, 0 = IPv6 */
#define WTX_TCPIP_CMD_TSE (1U << 26) /* segmentation context valid */
#define WTX_TCPIP_IPCSS(x) ((x) << 0) /* checksum start */
#define WTX_TCPIP_IPCSO(x) ((x) << 8) /* checksum value offset */
#define WTX_TCPIP_IPCSE(x) ((x) << 16) /* checksum end */
#define WTX_TCPIP_TUCSS(x) ((x) << 0) /* checksum start */
#define WTX_TCPIP_TUCSO(x) ((x) << 8) /* checksum value offset */
#define WTX_TCPIP_TUCSE(x) ((x) << 16) /* checksum end */
#define WTX_TCPIP_SEG_STATUS(x) ((x) << 0)
#define WTX_TCPIP_SEG_HDRLEN(x) ((x) << 8)
#define WTX_TCPIP_SEG_MSS(x) ((x) << 16)
/*
* PCI config registers used by the Wiseman.
*/
#define WM_PCI_MMBA PCI_MAPREG_START
/*
* Wiseman Control/Status Registers.
*/
#define WMREG_CTRL 0x0000 /* Device Control Register */
#define CTRL_FD (1U << 0) /* full duplex */
#define CTRL_BEM (1U << 1) /* big-endian mode */
#define CTRL_PRIOR (1U << 2) /* 0 = receive, 1 = fair */
#define CTRL_LRST (1U << 3) /* link reset */
#define CTRL_ASDE (1U << 5) /* auto speed detect enable */
#define CTRL_SLU (1U << 6) /* set link up */
#define CTRL_ILOS (1U << 7) /* invert loss of signal */
#define CTRL_SPEED(x) ((x) << 8) /* speed (Livengood) */
#define CTRL_SPEED_10 CTRL_SPEED(0)
#define CTRL_SPEED_100 CTRL_SPEED(1)
#define CTRL_SPEED_1000 CTRL_SPEED(2)
#define CTRL_SPEED_MASK CTRL_SPEED(3)
#define CTRL_FRCSPD (1U << 11) /* force speed (Livengood) */
#define CTRL_FRCFDX (1U << 12) /* force full-duplex (Livengood) */
#define CTRL_SWDPINS_SHIFT 18
#define CTRL_SWDPINS_MASK 0x0f
#define CTRL_SWDPIN(x) (1U << (CTRL_SWDPINS_SHIFT + (x)))
#define CTRL_SWDPIO_SHIFT 22
#define CTRL_SWDPIO_MASK 0x0f
#define CTRL_SWDPIO(x) (1U << (CTRL_SWDPIO_SHIFT + (x)))
#define CTRL_RST (1U << 26) /* device reset */
#define CTRL_RFCE (1U << 27) /* Rx flow control enable */
#define CTRL_TFCE (1U << 28) /* Tx flow control enable */
#define CTRL_VME (1U << 30) /* VLAN Mode Enable */
#define CTRL_PHY_RESET (1U << 31) /* PHY reset (Cordova) */
#define WMREG_CTRL_SHADOW 0x0004 /* Device Control Register (shadow) */
#define WMREG_STATUS 0x0008 /* Device Status Register */
#define STATUS_FD (1U << 0) /* full duplex */
#define STATUS_LU (1U << 1) /* link up */
#define STATUS_TCKOK (1U << 2) /* Tx clock running */
#define STATUS_RBCOK (1U << 3) /* Rx clock running */
#define STATUS_FUNCID_SHIFT 2 /* 82546 function ID */
#define STATUS_FUNCID_MASK 3 /* ... */
#define STATUS_TXOFF (1U << 4) /* Tx paused */
#define STATUS_TBIMODE (1U << 5) /* fiber mode (Livengood) */
#define STATUS_SPEED(x) ((x) << 6) /* speed indication */
#define STATUS_SPEED_10 STATUS_SPEED(0)
#define STATUS_SPEED_100 STATUS_SPEED(1)
#define STATUS_SPEED_1000 STATUS_SPEED(2)
#define STATUS_ASDV(x) ((x) << 8) /* auto speed det. val. (Livengood) */
#define STATUS_MTXCKOK (1U << 10) /* MTXD clock running */
#define STATUS_PCI66 (1U << 11) /* 66MHz bus (Livengood) */
#define STATUS_BUS64 (1U << 12) /* 64-bit bus (Livengood) */
#define STATUS_PCIX_MODE (1U << 13) /* PCIX mode (Cordova) */
#define STATUS_PCIXSPD(x) ((x) << 14) /* PCIX speed indication (Cordova) */
#define STATUS_PCIXSPD_50_66 STATUS_PCIXSPD(0)
#define STATUS_PCIXSPD_66_100 STATUS_PCIXSPD(1)
#define STATUS_PCIXSPD_100_133 STATUS_PCIXSPD(2)
#define STATUS_PCIXSPD_MASK STATUS_PCIXSPD(3)
#define WMREG_EECD 0x0010 /* EEPROM Control Register */
#define EECD_SK (1U << 0) /* clock */
#define EECD_CS (1U << 1) /* chip select */
#define EECD_DI (1U << 2) /* data in */
#define EECD_DO (1U << 3) /* data out */
#define EECD_FWE(x) ((x) << 4) /* flash write enable control */
#define EECD_FWE_DISABLED EECD_FWE(1)
#define EECD_FWE_ENABLED EECD_FWE(2)
#define EECD_EE_REQ (1U << 6) /* (shared) EEPROM request */
#define EECD_EE_GNT (1U << 7) /* (shared) EEPROM grant */
#define EECD_EE_PRES (1U << 8) /* EEPROM present */
#define EECD_EE_SIZE (1U << 9) /* EEPROM size
(0 = 64 word, 1 = 256 word) */
#define EECD_EE_ABITS (1U << 10) /* EEPROM address bits
(based on type) */
#define EECD_EE_TYPE (1U << 13) /* EEPROM type
(0 = Microwire, 1 = SPI) */
#define UWIRE_OPC_ERASE 0x04 /* MicroWire "erase" opcode */
#define UWIRE_OPC_WRITE 0x05 /* MicroWire "write" opcode */
#define UWIRE_OPC_READ 0x06 /* MicroWire "read" opcode */
#define SPI_OPC_WRITE 0x02 /* SPI "write" opcode */
#define SPI_OPC_READ 0x03 /* SPI "read" opcode */
#define SPI_OPC_A8 0x08 /* opcode bit 3 == address bit 8 */
#define SPI_OPC_WREN 0x06 /* SPI "set write enable" opcode */
#define SPI_OPC_WRDI 0x04 /* SPI "clear write enable" opcode */
#define SPI_OPC_RDSR 0x05 /* SPI "read status" opcode */
#define SPI_OPC_WRSR 0x01 /* SPI "write status" opcode */
#define SPI_MAX_RETRIES 5000 /* max wait of 5ms for RDY signal */
#define SPI_SR_RDY 0x01
#define SPI_SR_WEN 0x02
#define SPI_SR_BP0 0x04
#define SPI_SR_BP1 0x08
#define SPI_SR_WPEN 0x80
#define EEPROM_OFF_MACADDR 0x00 /* MAC address offset */
#define EEPROM_OFF_CFG1 0x0a /* config word 1 */
#define EEPROM_OFF_CFG2 0x0f /* config word 2 */
#define EEPROM_OFF_SWDPIN 0x20 /* SWD Pins (Cordova) */
#define EEPROM_CFG1_LVDID (1U << 0)
#define EEPROM_CFG1_LSSID (1U << 1)
#define EEPROM_CFG1_PME_CLOCK (1U << 2)
#define EEPROM_CFG1_PM (1U << 3)
#define EEPROM_CFG1_ILOS (1U << 4)
#define EEPROM_CFG1_SWDPIO_SHIFT 5
#define EEPROM_CFG1_SWDPIO_MASK (0xf << EEPROM_CFG1_SWDPIO_SHIFT)
#define EEPROM_CFG1_IPS1 (1U << 8)
#define EEPROM_CFG1_LRST (1U << 9)
#define EEPROM_CFG1_FD (1U << 10)
#define EEPROM_CFG1_FRCSPD (1U << 11)
#define EEPROM_CFG1_IPS0 (1U << 12)
#define EEPROM_CFG1_64_32_BAR (1U << 13)
#define EEPROM_CFG2_CSR_RD_SPLIT (1U << 1)
#define EEPROM_CFG2_APM_EN (1U << 2)
#define EEPROM_CFG2_64_BIT (1U << 3)
#define EEPROM_CFG2_MAX_READ (1U << 4)
#define EEPROM_CFG2_DMCR_MAP (1U << 5)
#define EEPROM_CFG2_133_CAP (1U << 6)
#define EEPROM_CFG2_MSI_DIS (1U << 7)
#define EEPROM_CFG2_FLASH_DIS (1U << 8)
#define EEPROM_CFG2_FLASH_SIZE(x) (((x) & 3) >> 9)
#define EEPROM_CFG2_ANE (1U << 11)
#define EEPROM_CFG2_PAUSE(x) (((x) & 3) >> 12)
#define EEPROM_CFG2_ASDE (1U << 14)
#define EEPROM_CFG2_APM_PME (1U << 15)
#define EEPROM_CFG2_SWDPIO_SHIFT 4
#define EEPROM_CFG2_SWDPIO_MASK (0xf << EEPROM_CFG2_SWDPIO_SHIFT)
#define EEPROM_SWDPIN_MASK 0xdf
#define EEPROM_SWDPIN_SWDPIN_SHIFT 0
#define EEPROM_SWDPIN_SWDPIO_SHIFT 8
#define WMREG_EERD 0x0014 /* EEPROM read register */
#define EERD_START 0x00000001
#define EERD_DONE 0x00000010
#define EERD_ADDR_SHIFT 8
#define EERD_ADDR_MASK 0x0000ff00
#define EERD_DATA_SHIFT 16
#define EERD_DATA_MASK 0xffff0000
#define WMREG_CTRL_EXT 0x0018 /* Extended Device Control Register */
#define CTRL_EXT_GPI_EN(x) (1U << (x)) /* gpin interrupt enable */
#define CTRL_EXT_SWDPINS_SHIFT 4
#define CTRL_EXT_SWDPINS_MASK 0x0d
#define CTRL_EXT_SWDPIN(x) (1U << (CTRL_EXT_SWDPINS_SHIFT + (x) - 4))
#define CTRL_EXT_SWDPIO_SHIFT 8
#define CTRL_EXT_SWDPIO_MASK 0x0d
#define CTRL_EXT_SWDPIO(x) (1U << (CTRL_EXT_SWDPIO_SHIFT + (x) - 4))
#define CTRL_EXT_ASDCHK (1U << 12) /* ASD check */
#define CTRL_EXT_EE_RST (1U << 13) /* EEPROM reset */
#define CTRL_EXT_IPS (1U << 14) /* invert power state bit 0 */
#define CTRL_EXT_SPD_BYPS (1U << 15) /* speed select bypass */
#define CTRL_EXT_IPS1 (1U << 16) /* invert power state bit 1 */
#define CTRL_EXT_RO_DIS (1U << 17) /* relaxed ordering disabled */
#define WMREG_MDIC 0x0020 /* MDI Control Register */
#define MDIC_DATA(x) ((x) & 0xffff)
#define MDIC_REGADD(x) ((x) << 16)
#define MDIC_PHYADD(x) ((x) << 21)
#define MDIC_OP_WRITE (1U << 26)
#define MDIC_OP_READ (2U << 26)
#define MDIC_READY (1U << 28)
#define MDIC_I (1U << 29) /* interrupt on MDI complete */
#define MDIC_E (1U << 30) /* MDI error */
#define WMREG_FCAL 0x0028 /* Flow Control Address Low */
#define FCAL_CONST 0x00c28001 /* Flow Control MAC addr low */
#define WMREG_FCAH 0x002c /* Flow Control Address High */
#define FCAH_CONST 0x00000100 /* Flow Control MAC addr high */
#define WMREG_FCT 0x0030 /* Flow Control Type */
#define WMREG_VET 0x0038 /* VLAN Ethertype */
#define WMREG_RAL_BASE 0x0040 /* Receive Address List */
#define WMREG_CORDOVA_RAL_BASE 0x5400
#define WMREG_RAL_LO(b, x) ((b) + ((x) << 3))
#define WMREG_RAL_HI(b, x) (WMREG_RAL_LO(b, x) + 4)
/*
* Receive Address List: The LO part is the low-order 32-bits
* of the MAC address. The HI part is the high-order 16-bits
* along with a few control bits.
*/
#define RAL_AS(x) ((x) << 16) /* address select */
#define RAL_AS_DEST RAL_AS(0) /* (cordova?) */
#define RAL_AS_SOURCE RAL_AS(1) /* (cordova?) */
#define RAL_RDR1 (1U << 30) /* put packet in alt. rx ring */
#define RAL_AV (1U << 31) /* entry is valid */
#define WM_RAL_TABSIZE 16
#define WMREG_ICR 0x00c0 /* Interrupt Cause Register */
#define ICR_TXDW (1U << 0) /* Tx desc written back */
#define ICR_TXQE (1U << 1) /* Tx queue empty */
#define ICR_LSC (1U << 2) /* link status change */
#define ICR_RXSEQ (1U << 3) /* receive sequence error */
#define ICR_RXDMT0 (1U << 4) /* Rx ring 0 nearly empty */
#define ICR_RXO (1U << 6) /* Rx overrun */
#define ICR_RXT0 (1U << 7) /* Rx ring 0 timer */
#define ICR_MDAC (1U << 9) /* MDIO access complete */
#define ICR_RXCFG (1U << 10) /* Receiving /C/ */
#define ICR_GPI(x) (1U << (x)) /* general purpose interrupts */
#define WMREG_ITR 0x00c4 /* Interrupt Throttling Register */
#define ITR_IVAL_MASK 0xffff /* Interval mask */
#define ITR_IVAL_SHIFT 0 /* Interval shift */
#define WMREG_ICS 0x00c8 /* Interrupt Cause Set Register */
/* See ICR bits. */
#define WMREG_IMS 0x00d0 /* Interrupt Mask Set Register */
/* See ICR bits. */
#define WMREG_IMC 0x00d8 /* Interrupt Mask Clear Register */
/* See ICR bits. */
#define WMREG_RCTL 0x0100 /* Receive Control */
#define RCTL_EN (1U << 1) /* receiver enable */
#define RCTL_SBP (1U << 2) /* store bad packets */
#define RCTL_UPE (1U << 3) /* unicast promisc. enable */
#define RCTL_MPE (1U << 4) /* multicast promisc. enable */
#define RCTL_LPE (1U << 5) /* large packet enable */
#define RCTL_LBM(x) ((x) << 6) /* loopback mode */
#define RCTL_LBM_NONE RCTL_LBM(0)
#define RCTL_LBM_PHY RCTL_LBM(3)
#define RCTL_RDMTS(x) ((x) << 8) /* receive desc. min thresh size */
#define RCTL_RDMTS_1_2 RCTL_RDMTS(0)
#define RCTL_RDMTS_1_4 RCTL_RDMTS(1)
#define RCTL_RDMTS_1_8 RCTL_RDMTS(2)
#define RCTL_RDMTS_MASK RCTL_RDMTS(3)
#define RCTL_MO(x) ((x) << 12) /* multicast offset */
#define RCTL_BAM (1U << 15) /* broadcast accept mode */
#define RCTL_2k (0 << 16) /* 2k Rx buffers */
#define RCTL_1k (1 << 16) /* 1k Rx buffers */
#define RCTL_512 (2 << 16) /* 512 byte Rx buffers */
#define RCTL_256 (3 << 16) /* 256 byte Rx buffers */
#define RCTL_BSEX_16k (1 << 16) /* 16k Rx buffers (BSEX) */
#define RCTL_BSEX_8k (2 << 16) /* 8k Rx buffers (BSEX) */
#define RCTL_BSEX_4k (3 << 16) /* 4k Rx buffers (BSEX) */
#define RCTL_DPF (1U << 22) /* discard pause frames */
#define RCTL_PMCF (1U << 23) /* pass MAC control frames */
#define RCTL_BSEX (1U << 25) /* buffer size extension (Livengood) */
#define RCTL_SECRC (1U << 26) /* strip Ethernet CRC */
#define WMREG_OLD_RDTR0 0x0108 /* Receive Delay Timer (ring 0) */
#define WMREG_RDTR 0x2820
#define RDTR_FPD (1U << 31) /* flush partial descriptor */
#define WMREG_RADV 0x282c /* Receive Interrupt Absolute Delay Timer */
#define WMREG_OLD_RDBAL0 0x0110 /* Receive Descriptor Base Low (ring 0) */
#define WMREG_RDBAL 0x2800
#define WMREG_OLD_RDBAH0 0x0114 /* Receive Descriptor Base High (ring 0) */
#define WMREG_RDBAH 0x2804
#define WMREG_OLD_RDLEN0 0x0118 /* Receive Descriptor Length (ring 0) */
#define WMREG_RDLEN 0x2808
#define WMREG_OLD_RDH0 0x0120 /* Receive Descriptor Head (ring 0) */
#define WMREG_RDH 0x2810
#define WMREG_OLD_RDT0 0x0128 /* Receive Descriptor Tail (ring 0) */
#define WMREG_RDT 0x2818
#define WMREG_RXDCTL 0x2828 /* Receive Descriptor Control */
#define RXDCTL_PTHRESH(x) ((x) << 0) /* prefetch threshold */
#define RXDCTL_HTHRESH(x) ((x) << 8) /* host threshold */
#define RXDCTL_WTHRESH(x) ((x) << 16) /* write back threshold */
#define RXDCTL_GRAN (1U << 24) /* 0 = cacheline, 1 = descriptor */
#define WMREG_OLD_RDTR1 0x0130 /* Receive Delay Timer (ring 1) */
#define WMREG_OLD_RDBA1_LO 0x0138 /* Receive Descriptor Base Low (ring 1) */
#define WMREG_OLD_RDBA1_HI 0x013c /* Receive Descriptor Base High (ring 1) */
#define WMREG_OLD_RDLEN1 0x0140 /* Receive Drscriptor Length (ring 1) */
#define WMREG_OLD_RDH1 0x0148
#define WMREG_OLD_RDT1 0x0150
#define WMREG_OLD_FCRTH 0x0160 /* Flow Control Rx Threshold Hi (OLD) */
#define WMREG_FCRTL 0x2160 /* Flow Control Rx Threshold Lo */
#define FCRTH_DFLT 0x00008000
#define WMREG_OLD_FCRTL 0x0168 /* Flow Control Rx Threshold Lo (OLD) */
#define WMREG_FCRTH 0x2168 /* Flow Control Rx Threhsold Hi */
#define FCRTL_DFLT 0x00004000
#define FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
#define WMREG_FCTTV 0x0170 /* Flow Control Transmit Timer Value */
#define FCTTV_DFLT 0x00000600
#define WMREG_TXCW 0x0178 /* Transmit Configuration Word (TBI mode) */
/* See MII ANAR_X bits. */
#define TXCW_TxConfig (1U << 30) /* Tx Config */
#define TXCW_ANE (1U << 31) /* Autonegotiate */
#define WMREG_RXCW 0x0180 /* Receive Configuration Word (TBI mode) */
/* See MII ANLPAR_X bits. */
#define RXCW_NC (1U << 26) /* no carrier */
#define RXCW_IV (1U << 27) /* config invalid */
#define RXCW_CC (1U << 28) /* config change */
#define RXCW_C (1U << 29) /* /C/ reception */
#define RXCW_SYNCH (1U << 30) /* synchronized */
#define RXCW_ANC (1U << 31) /* autonegotiation complete */
#define WMREG_MTA 0x0200 /* Multicast Table Array */
#define WMREG_CORDOVA_MTA 0x5200
#define WMREG_TCTL 0x0400 /* Transmit Control Register */
#define TCTL_EN (1U << 1) /* transmitter enable */
#define TCTL_PSP (1U << 3) /* pad short packets */
#define TCTL_CT(x) (((x) & 0xff) << 4) /* 4:11 - collision threshold */
#define TCTL_COLD(x) (((x) & 0x3ff) << 12) /* 12:21 - collision distance */
#define TCTL_SWXOFF (1U << 22) /* software XOFF */
#define TCTL_RTLC (1U << 24) /* retransmit on late collision */
#define TCTL_NRTU (1U << 25) /* no retransmit on underrun */
#define TX_COLLISION_THRESHOLD 15
#define TX_COLLISION_DISTANCE_HDX 64
#define TX_COLLISION_DISTANCE_FDX 512
#define WMREG_TQSA_LO 0x0408
#define WMREG_TQSA_HI 0x040c
#define WMREG_TIPG 0x0410 /* Transmit IPG Register */
#define TIPG_IPGT(x) (x) /* IPG transmit time */
#define TIPG_IPGR1(x) ((x) << 10) /* IPG receive time 1 */
#define TIPG_IPGR2(x) ((x) << 20) /* IPG receive time 2 */
#define TIPG_WM_DFLT (TIPG_IPGT(0x0a) | TIPG_IPGR1(0x02) | TIPG_IPGR2(0x0a))
#define TIPG_LG_DFLT (TIPG_IPGT(0x06) | TIPG_IPGR1(0x08) | TIPG_IPGR2(0x06))
#define TIPG_1000T_DFLT (TIPG_IPGT(0x08) | TIPG_IPGR1(0x08) | TIPG_IPGR2(0x06))
#define WMREG_TQC 0x0418
#define WMREG_RDFH 0x2410 /* Receive Data FIFO Head */
#define WMREG_RDFT 0x2418 /* Receive Data FIFO Tail */
#define WMREG_RDFHS 0x2420 /* Receive Data FIFO Head Saved */
#define WMREG_RDFTS 0x2428 /* Receive Data FIFO Tail Saved */
#define WMREG_TDFH 0x3410 /* Transmit Data FIFO Head */
#define WMREG_TDFT 0x3418 /* Transmit Data FIFO Tail */
#define WMREG_TDFHS 0x3420 /* Transmit Data FIFO Head Saved */
#define WMREG_TDFTS 0x3428 /* Transmit Data FIFO Tail Saved */
#define WMREG_TDFPC 0x3430 /* Transmit Data FIFO Packet Count */
#define WMREG_OLD_TDBAL 0x0420 /* Transmit Descriptor Base Lo */
#define WMREG_TDBAL 0x3800
#define WMREG_OLD_TDBAH 0x0424 /* Transmit Descriptor Base Hi */
#define WMREG_TDBAH 0x3804
#define WMREG_OLD_TDLEN 0x0428 /* Transmit Descriptor Length */
#define WMREG_TDLEN 0x3808
#define WMREG_OLD_TDH 0x0430 /* Transmit Descriptor Head */
#define WMREG_TDH 0x3810
#define WMREG_OLD_TDT 0x0438 /* Transmit Descriptor Tail */
#define WMREG_TDT 0x3818
#define WMREG_OLD_TIDV 0x0440 /* Transmit Delay Interrupt Value */
#define WMREG_TIDV 0x3820
#define WMREG_TXDCTL 0x3828 /* Trandmit Descriptor Control */
#define TXDCTL_PTHRESH(x) ((x) << 0) /* prefetch threshold */
#define TXDCTL_HTHRESH(x) ((x) << 8) /* host threshold */
#define TXDCTL_WTHRESH(x) ((x) << 16) /* write back threshold */
#define WMREG_TADV 0x382c /* Transmit Absolute Interrupt Delay Timer */
#define WMREG_AIT 0x0458 /* Adaptive IFS Throttle */
#define WMREG_VFTA 0x0600
#define WM_MC_TABSIZE 128
#define WM_VLAN_TABSIZE 128
#define WMREG_PBA 0x1000 /* Packet Buffer Allocation */
#define PBA_RX_MASK 0xffff
#define PBA_RX_SHIFT 0
#define PBA_TX_MASK 0xffff
#define PBA_TX_SHIFT 16
#define WMREG_TXDMAC 0x3000 /* Transfer DMA Control */
#define TXDMAC_DPP (1U << 0) /* disable packet prefetch */
#define WMREG_TSPMT 0x3830 /* TCP Segmentation Pad and Minimum
Threshold (Cordova) */
#define TSPMT_TSMT(x) (x) /* TCP seg min transfer */
#define TSPMT_TSPBP(x) ((x) << 16) /* TCP seg pkt buf padding */
#define WMREG_RXCSUM 0x5000 /* Receive Checksum register */
#define RXCSUM_PCSS 0x000000ff /* Packet Checksum Start */
#define RXCSUM_IPOFL (1U << 8) /* IP checksum offload */
#define RXCSUM_TUOFL (1U << 9) /* TCP/UDP checksum offload */
#define WMREG_XONRXC 0x4048 /* XON Rx Count - R/clr */
#define WMREG_XONTXC 0x404c /* XON Tx Count - R/clr */
#define WMREG_XOFFRXC 0x4050 /* XOFF Rx Count - R/clr */
#define WMREG_XOFFTXC 0x4054 /* XOFF Tx Count - R/clr */
#define WMREG_FCRUC 0x4058 /* Flow Control Rx Unsupported Count - R/clr */
#define WMREG_MANC 0x5820 /* Management control */
#define MANC_ARP_REQ 0x00002000 /* ARP request filtering */
#define MANC_ARP_RES 0x00008000 /* ARP response filtering */
#define MANC_MNG2HOST 0x00200000 /* Management packets to host */
#define WMREG_MANC2H 0x5860 /* Management control to host */
#define MANC2H_PORT_623 0x0020
#define MANC2H_PORT_664 0x0040
......@@ -25,6 +25,7 @@ extern void inituser(void);
extern void inithz(void);
extern void initwq(void);
extern void initsamp(void);
extern void initpci(void);
static volatile int bstate;
......@@ -102,6 +103,7 @@ cmain(u64 mbmagic, u64 mbaddr)
initwq(); // work queues
#endif
initsamp();
initpci();
cprintf("ncpu %d %lu MHz\n", ncpu, cpuhz / 1000000);
......
#include "types.h"
#include "amd64.h"
#include "kernel.h"
#include "pci.h"
#include "pcireg.h"
extern int e1000attach(struct pci_func *pcif);
// Flag to do "lspci" at bootup
static int pci_show_devs = 1;
static int pci_show_addrs = 1;
// PCI "configuration mechanism one"
static u32 pci_conf1_addr_ioport = 0x0cf8;
static u32 pci_conf1_data_ioport = 0x0cfc;
// PCI driver table
struct pci_driver {
u32 key1, key2;
int (*attachfn) (struct pci_func *pcif);
};
// Forward declarations
static int pci_bridge_attach(struct pci_func *pcif);
// pci_attach_class matches the class and subclass of a PCI device
struct pci_driver pci_attach_class[] = {
{ PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI, &pci_bridge_attach },
{ 0, 0, 0 },
};
// pci_attach_vendor matches the vendor ID and device ID of a PCI device
struct pci_driver pci_attach_vendor[] = {
// [E1000 5.2]
// QEMU emulates an 82540EM, specifically.
{ 0x8086, 0x100e, &e1000attach },
// Both of ud0's e1000e
{ 0x8086, 0x108c, &e1000attach },
{ 0x8086, 0x109A, &e1000attach },
{ 0, 0, 0 },
};
static const char *pci_class[] =
{
[0x0] = "Unknown",
[0x1] = "Storage controller",
[0x2] = "Network controller",
[0x3] = "Display controller",
[0x4] = "Multimedia device",
[0x5] = "Memory controller",
[0x6] = "Bridge device",
};
static void
pci_print_func(struct pci_func *f)
{
const char *class = pci_class[0];
if (PCI_CLASS(f->dev_class) < sizeof(pci_class) / sizeof(pci_class[0]))
class = pci_class[PCI_CLASS(f->dev_class)];
cprintf("PCI: %x:%x.%d: %x:%x: class: %x.%x (%s) irq: %d\n",
f->bus->busno, f->dev, f->func,
PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id),
PCI_CLASS(f->dev_class), PCI_SUBCLASS(f->dev_class), class,
f->irq_line);
}
static void
pci_conf1_set_addr(u32 bus,
u32 dev,
u32 func,
u32 offset)
{
if (!(bus < 256 &&
dev < 32 &&
func < 8 &&
offset < 256 &&
(offset&0x3) == 0))
panic("pci_conf1_set_addr");
u32 v = (1 << 31) | // config-space
(bus << 16) | (dev << 11) | (func << 8) | (offset);
outl(pci_conf1_addr_ioport, v);
}
static u32
pci_conf_read(struct pci_func *f, u32 off)
{
pci_conf1_set_addr(f->bus->busno, f->dev, f->func, off);
return inl(pci_conf1_data_ioport);
}
static void
pci_conf_write(struct pci_func *f, u32 off, u32 v)
{
pci_conf1_set_addr(f->bus->busno, f->dev, f->func, off);
outl(pci_conf1_data_ioport, v);
}
static int __attribute__((warn_unused_result))
pci_attach_match(u32 key1, u32 key2,
struct pci_driver *list, struct pci_func *pcif)
{
u32 i;
for (i = 0; list[i].attachfn; i++) {
if (list[i].key1 == key1 && list[i].key2 == key2) {
int r = list[i].attachfn(pcif);
if (r > 0)
return r;
if (r < 0)
cprintf("pci_attach_match: attaching "
"%x.%x (%p): e\n",
key1, key2, list[i].attachfn, r);
}
}
return 0;
}
static int
pci_attach(struct pci_func *f)
{
return
pci_attach_match(PCI_CLASS(f->dev_class),
PCI_SUBCLASS(f->dev_class),
&pci_attach_class[0], f) ||
pci_attach_match(PCI_VENDOR(f->dev_id),
PCI_PRODUCT(f->dev_id),
&pci_attach_vendor[0], f);
}
static int
pci_scan_bus(struct pci_bus *bus)
{
int totaldev = 0;
struct pci_func df;
memset(&df, 0, sizeof(df));
df.bus = bus;
for (df.dev = 0; df.dev < 32; df.dev++) {
u32 bhlc = pci_conf_read(&df, PCI_BHLC_REG);
if (PCI_HDRTYPE_TYPE(bhlc) > 1) // Unsupported or no device
continue;
totaldev++;
struct pci_func f = df;
for (f.func = 0; f.func < (PCI_HDRTYPE_MULTIFN(bhlc) ? 8 : 1);
f.func++) {
struct pci_func af = f;
af.dev_id = pci_conf_read(&f, PCI_ID_REG);
if (PCI_VENDOR(af.dev_id) == 0xffff)
continue;
u32 intr = pci_conf_read(&af, PCI_INTERRUPT_REG);
af.irq_line = PCI_INTERRUPT_LINE(intr);
af.dev_class = pci_conf_read(&af, PCI_CLASS_REG);
if (pci_show_devs)
pci_print_func(&af);
pci_attach(&af);
}
}
return totaldev;
}
static int
pci_bridge_attach(struct pci_func *pcif)
{
u32 ioreg = pci_conf_read(pcif, PCI_BRIDGE_STATIO_REG);
u32 busreg = pci_conf_read(pcif, PCI_BRIDGE_BUS_REG);
if (PCI_BRIDGE_IO_32BITS(ioreg)) {
cprintf("PCI: %x:%x.%d: 32-bit bridge IO not supported.\n",
pcif->bus->busno, pcif->dev, pcif->func);
return 0;
}
struct pci_bus nbus;
memset(&nbus, 0, sizeof(nbus));
nbus.parent_bridge = pcif;
nbus.busno = (busreg >> PCI_BRIDGE_BUS_SECONDARY_SHIFT) & 0xff;
if (pci_show_devs)
cprintf("PCI: %x:%x.%d: bridge to PCI bus %d--%d\n",
pcif->bus->busno, pcif->dev, pcif->func,
nbus.busno,
(busreg >> PCI_BRIDGE_BUS_SUBORDINATE_SHIFT) & 0xff);
pci_scan_bus(&nbus);
return 1;
}
void
pci_func_enable(struct pci_func *f)
{
pci_conf_write(f, PCI_COMMAND_STATUS_REG,
PCI_COMMAND_IO_ENABLE |
PCI_COMMAND_MEM_ENABLE |
PCI_COMMAND_MASTER_ENABLE);
u32 bar_width;
u32 bar;
for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
bar += bar_width)
{
u32 oldv = pci_conf_read(f, bar);
bar_width = 4;
pci_conf_write(f, bar, 0xffffffff);
u32 rv = pci_conf_read(f, bar);
if (rv == 0)
continue;
int regnum = PCI_MAPREG_NUM(bar);
u32 base, size;
if (PCI_MAPREG_TYPE(rv) == PCI_MAPREG_TYPE_MEM) {
if (PCI_MAPREG_MEM_TYPE(rv) == PCI_MAPREG_MEM_TYPE_64BIT)
bar_width = 8;
size = PCI_MAPREG_MEM_SIZE(rv);
base = PCI_MAPREG_MEM_ADDR(oldv);
if (pci_show_addrs)
cprintf(" mem region %d: %d bytes at 0x%x\n",
regnum, size, base);
} else {
size = PCI_MAPREG_IO_SIZE(rv);
base = PCI_MAPREG_IO_ADDR(oldv);
if (pci_show_addrs)
cprintf(" io region %d: %d bytes at 0x%x\n",
regnum, size, base);
}
pci_conf_write(f, bar, oldv);
f->reg_base[regnum] = base;
f->reg_size[regnum] = size;
if (size && !base)
cprintf("PCI device %02x:%02x.%d (%04x:%04x) "
"may be misconfigured: "
"region %d: base 0x%x, size %d\n",
f->bus->busno, f->dev, f->func,
PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id),
regnum, base, size);
}
cprintf("PCI function %x:%x.%d (%x:%x) enabled\n",
f->bus->busno, f->dev, f->func,
PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id));
}
void
initpci(void)
{
static struct pci_bus root_bus;
memset(&root_bus, 0, sizeof(root_bus));
pci_scan_bus(&root_bus);
}
// PCI subsystem interface
enum { pci_res_bus, pci_res_mem, pci_res_io, pci_res_max };
struct pci_bus;
struct pci_func {
struct pci_bus *bus; // Primary bus for bridges
u32 dev;
u32 func;
u32 dev_id;
u32 dev_class;
u32 reg_base[6];
u32 reg_size[6];
u8 irq_line;
};
struct pci_bus {
struct pci_func *parent_bridge;
u32 busno;
};
int pci_init(void);
void pci_func_enable(struct pci_func *f);
/* $NetBSD: pcireg.h,v 1.45 2004/02/04 06:58:24 soren Exp $ */
/*
* Copyright (c) 1995, 1996, 1999, 2000
* Christopher G. Demetriou. All rights reserved.
* Copyright (c) 1994, 1996 Charles M. Hannum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Charles M. Hannum.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
*/
#ifndef _DEV_PCI_PCIREG_H_
#define _DEV_PCI_PCIREG_H_
/*
* Standardized PCI configuration information
*
* XXX This is not complete.
*/
/*
* Device identification register; contains a vendor ID and a device ID.
*/
#define PCI_ID_REG 0x00
typedef u16 pci_vendor_id_t;
typedef u16 pci_product_id_t;
#define PCI_VENDOR_SHIFT 0
#define PCI_VENDOR_MASK 0xffff
#define PCI_VENDOR(id) \
(((id) >> PCI_VENDOR_SHIFT) & PCI_VENDOR_MASK)
#define PCI_PRODUCT_SHIFT 16
#define PCI_PRODUCT_MASK 0xffff
#define PCI_PRODUCT(id) \
(((id) >> PCI_PRODUCT_SHIFT) & PCI_PRODUCT_MASK)
#define PCI_ID_CODE(vid,pid) \
((((vid) & PCI_VENDOR_MASK) << PCI_VENDOR_SHIFT) | \
(((pid) & PCI_PRODUCT_MASK) << PCI_PRODUCT_SHIFT)) \
/*
* Command and status register.
*/
#define PCI_COMMAND_STATUS_REG 0x04
#define PCI_COMMAND_SHIFT 0
#define PCI_COMMAND_MASK 0xffff
#define PCI_STATUS_SHIFT 16
#define PCI_STATUS_MASK 0xffff
#define PCI_COMMAND_STATUS_CODE(cmd,stat) \
((((cmd) & PCI_COMMAND_MASK) >> PCI_COMMAND_SHIFT) | \
(((stat) & PCI_STATUS_MASK) >> PCI_STATUS_SHIFT)) \
#define PCI_COMMAND_IO_ENABLE 0x00000001
#define PCI_COMMAND_MEM_ENABLE 0x00000002
#define PCI_COMMAND_MASTER_ENABLE 0x00000004
#define PCI_COMMAND_SPECIAL_ENABLE 0x00000008
#define PCI_COMMAND_INVALIDATE_ENABLE 0x00000010
#define PCI_COMMAND_PALETTE_ENABLE 0x00000020
#define PCI_COMMAND_PARITY_ENABLE 0x00000040
#define PCI_COMMAND_STEPPING_ENABLE 0x00000080
#define PCI_COMMAND_SERR_ENABLE 0x00000100
#define PCI_COMMAND_BACKTOBACK_ENABLE 0x00000200
#define PCI_STATUS_CAPLIST_SUPPORT 0x00100000
#define PCI_STATUS_66MHZ_SUPPORT 0x00200000
#define PCI_STATUS_UDF_SUPPORT 0x00400000
#define PCI_STATUS_BACKTOBACK_SUPPORT 0x00800000
#define PCI_STATUS_PARITY_ERROR 0x01000000
#define PCI_STATUS_DEVSEL_FAST 0x00000000
#define PCI_STATUS_DEVSEL_MEDIUM 0x02000000
#define PCI_STATUS_DEVSEL_SLOW 0x04000000
#define PCI_STATUS_DEVSEL_MASK 0x06000000
#define PCI_STATUS_TARGET_TARGET_ABORT 0x08000000
#define PCI_STATUS_MASTER_TARGET_ABORT 0x10000000
#define PCI_STATUS_MASTER_ABORT 0x20000000
#define PCI_STATUS_SPECIAL_ERROR 0x40000000
#define PCI_STATUS_PARITY_DETECT 0x80000000
/*
* PCI Class and Revision Register; defines type and revision of device.
*/
#define PCI_CLASS_REG 0x08
typedef u8 pci_class_t;
typedef u8 pci_subclass_t;
typedef u8 pci_interface_t;
typedef u8 pci_revision_t;
#define PCI_CLASS_SHIFT 24
#define PCI_CLASS_MASK 0xff
#define PCI_CLASS(cr) \
(((cr) >> PCI_CLASS_SHIFT) & PCI_CLASS_MASK)
#define PCI_SUBCLASS_SHIFT 16
#define PCI_SUBCLASS_MASK 0xff
#define PCI_SUBCLASS(cr) \
(((cr) >> PCI_SUBCLASS_SHIFT) & PCI_SUBCLASS_MASK)
#define PCI_INTERFACE_SHIFT 8
#define PCI_INTERFACE_MASK 0xff
#define PCI_INTERFACE(cr) \
(((cr) >> PCI_INTERFACE_SHIFT) & PCI_INTERFACE_MASK)
#define PCI_REVISION_SHIFT 0
#define PCI_REVISION_MASK 0xff
#define PCI_REVISION(cr) \
(((cr) >> PCI_REVISION_SHIFT) & PCI_REVISION_MASK)
#define PCI_CLASS_CODE(mainclass, subclass, interface) \
((((mainclass) & PCI_CLASS_MASK) << PCI_CLASS_SHIFT) | \
(((subclass) & PCI_SUBCLASS_MASK) << PCI_SUBCLASS_SHIFT) | \
(((interface) & PCI_INTERFACE_MASK) << PCI_INTERFACE_SHIFT))
/* base classes */
#define PCI_CLASS_PREHISTORIC 0x00
#define PCI_CLASS_MASS_STORAGE 0x01
#define PCI_CLASS_NETWORK 0x02
#define PCI_CLASS_DISPLAY 0x03
#define PCI_CLASS_MULTIMEDIA 0x04
#define PCI_CLASS_MEMORY 0x05
#define PCI_CLASS_BRIDGE 0x06
#define PCI_CLASS_COMMUNICATIONS 0x07
#define PCI_CLASS_SYSTEM 0x08
#define PCI_CLASS_INPUT 0x09
#define PCI_CLASS_DOCK 0x0a
#define PCI_CLASS_PROCESSOR 0x0b
#define PCI_CLASS_SERIALBUS 0x0c
#define PCI_CLASS_WIRELESS 0x0d
#define PCI_CLASS_I2O 0x0e
#define PCI_CLASS_SATCOM 0x0f
#define PCI_CLASS_CRYPTO 0x10
#define PCI_CLASS_DASP 0x11
#define PCI_CLASS_UNDEFINED 0xff
/* 0x00 prehistoric subclasses */
#define PCI_SUBCLASS_PREHISTORIC_MISC 0x00
#define PCI_SUBCLASS_PREHISTORIC_VGA 0x01
/* 0x01 mass storage subclasses */
#define PCI_SUBCLASS_MASS_STORAGE_SCSI 0x00
#define PCI_SUBCLASS_MASS_STORAGE_IDE 0x01
#define PCI_SUBCLASS_MASS_STORAGE_FLOPPY 0x02
#define PCI_SUBCLASS_MASS_STORAGE_IPI 0x03
#define PCI_SUBCLASS_MASS_STORAGE_RAID 0x04
#define PCI_SUBCLASS_MASS_STORAGE_ATA 0x05
#define PCI_SUBCLASS_MASS_STORAGE_SATA 0x06
#define PCI_SUBCLASS_MASS_STORAGE_MISC 0x80
/* 0x02 network subclasses */
#define PCI_SUBCLASS_NETWORK_ETHERNET 0x00
#define PCI_SUBCLASS_NETWORK_TOKENRING 0x01
#define PCI_SUBCLASS_NETWORK_FDDI 0x02
#define PCI_SUBCLASS_NETWORK_ATM 0x03
#define PCI_SUBCLASS_NETWORK_ISDN 0x04
#define PCI_SUBCLASS_NETWORK_WORLDFIP 0x05
#define PCI_SUBCLASS_NETWORK_PCIMGMULTICOMP 0x06
#define PCI_SUBCLASS_NETWORK_MISC 0x80
/* 0x03 display subclasses */
#define PCI_SUBCLASS_DISPLAY_VGA 0x00
#define PCI_SUBCLASS_DISPLAY_XGA 0x01
#define PCI_SUBCLASS_DISPLAY_3D 0x02
#define PCI_SUBCLASS_DISPLAY_MISC 0x80
/* 0x04 multimedia subclasses */
#define PCI_SUBCLASS_MULTIMEDIA_VIDEO 0x00
#define PCI_SUBCLASS_MULTIMEDIA_AUDIO 0x01
#define PCI_SUBCLASS_MULTIMEDIA_TELEPHONY 0x02
#define PCI_SUBCLASS_MULTIMEDIA_MISC 0x80
/* 0x05 memory subclasses */
#define PCI_SUBCLASS_MEMORY_RAM 0x00
#define PCI_SUBCLASS_MEMORY_FLASH 0x01
#define PCI_SUBCLASS_MEMORY_MISC 0x80
/* 0x06 bridge subclasses */
#define PCI_SUBCLASS_BRIDGE_HOST 0x00
#define PCI_SUBCLASS_BRIDGE_ISA 0x01
#define PCI_SUBCLASS_BRIDGE_EISA 0x02
#define PCI_SUBCLASS_BRIDGE_MC 0x03 /* XXX _MCA? */
#define PCI_SUBCLASS_BRIDGE_PCI 0x04
#define PCI_SUBCLASS_BRIDGE_PCMCIA 0x05
#define PCI_SUBCLASS_BRIDGE_NUBUS 0x06
#define PCI_SUBCLASS_BRIDGE_CARDBUS 0x07
#define PCI_SUBCLASS_BRIDGE_RACEWAY 0x08
#define PCI_SUBCLASS_BRIDGE_STPCI 0x09
#define PCI_SUBCLASS_BRIDGE_INFINIBAND 0x0a
#define PCI_SUBCLASS_BRIDGE_MISC 0x80
/* 0x07 communications subclasses */
#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00
#define PCI_SUBCLASS_COMMUNICATIONS_PARALLEL 0x01
#define PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL 0x02
#define PCI_SUBCLASS_COMMUNICATIONS_MODEM 0x03
#define PCI_SUBCLASS_COMMUNICATIONS_GPIB 0x04
#define PCI_SUBCLASS_COMMUNICATIONS_SMARTCARD 0x05
#define PCI_SUBCLASS_COMMUNICATIONS_MISC 0x80
/* 0x08 system subclasses */
#define PCI_SUBCLASS_SYSTEM_PIC 0x00
#define PCI_SUBCLASS_SYSTEM_DMA 0x01
#define PCI_SUBCLASS_SYSTEM_TIMER 0x02
#define PCI_SUBCLASS_SYSTEM_RTC 0x03
#define PCI_SUBCLASS_SYSTEM_PCIHOTPLUG 0x04
#define PCI_SUBCLASS_SYSTEM_MISC 0x80
/* 0x09 input subclasses */
#define PCI_SUBCLASS_INPUT_KEYBOARD 0x00
#define PCI_SUBCLASS_INPUT_DIGITIZER 0x01
#define PCI_SUBCLASS_INPUT_MOUSE 0x02
#define PCI_SUBCLASS_INPUT_SCANNER 0x03
#define PCI_SUBCLASS_INPUT_GAMEPORT 0x04
#define PCI_SUBCLASS_INPUT_MISC 0x80
/* 0x0a dock subclasses */
#define PCI_SUBCLASS_DOCK_GENERIC 0x00
#define PCI_SUBCLASS_DOCK_MISC 0x80
/* 0x0b processor subclasses */
#define PCI_SUBCLASS_PROCESSOR_386 0x00
#define PCI_SUBCLASS_PROCESSOR_486 0x01
#define PCI_SUBCLASS_PROCESSOR_PENTIUM 0x02
#define PCI_SUBCLASS_PROCESSOR_ALPHA 0x10
#define PCI_SUBCLASS_PROCESSOR_POWERPC 0x20
#define PCI_SUBCLASS_PROCESSOR_MIPS 0x30
#define PCI_SUBCLASS_PROCESSOR_COPROC 0x40
/* 0x0c serial bus subclasses */
#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00
#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x01
#define PCI_SUBCLASS_SERIALBUS_SSA 0x02
#define PCI_SUBCLASS_SERIALBUS_USB 0x03
#define PCI_SUBCLASS_SERIALBUS_FIBER 0x04 /* XXX _FIBRECHANNEL */
#define PCI_SUBCLASS_SERIALBUS_SMBUS 0x05
#define PCI_SUBCLASS_SERIALBUS_INFINIBAND 0x06
#define PCI_SUBCLASS_SERIALBUS_IPMI 0x07
#define PCI_SUBCLASS_SERIALBUS_SERCOS 0x08
#define PCI_SUBCLASS_SERIALBUS_CANBUS 0x09
/* 0x0d wireless subclasses */
#define PCI_SUBCLASS_WIRELESS_IRDA 0x00
#define PCI_SUBCLASS_WIRELESS_CONSUMERIR 0x01
#define PCI_SUBCLASS_WIRELESS_RF 0x10
#define PCI_SUBCLASS_WIRELESS_BLUETOOTH 0x11
#define PCI_SUBCLASS_WIRELESS_BROADBAND 0x12
#define PCI_SUBCLASS_WIRELESS_802_11A 0x20
#define PCI_SUBCLASS_WIRELESS_802_11B 0x21
#define PCI_SUBCLASS_WIRELESS_MISC 0x80
/* 0x0e I2O (Intelligent I/O) subclasses */
#define PCI_SUBCLASS_I2O_STANDARD 0x00
/* 0x0f satellite communication subclasses */
/* PCI_SUBCLASS_SATCOM_??? 0x00 / * XXX ??? */
#define PCI_SUBCLASS_SATCOM_TV 0x01
#define PCI_SUBCLASS_SATCOM_AUDIO 0x02
#define PCI_SUBCLASS_SATCOM_VOICE 0x03
#define PCI_SUBCLASS_SATCOM_DATA 0x04
/* 0x10 encryption/decryption subclasses */
#define PCI_SUBCLASS_CRYPTO_NETCOMP 0x00
#define PCI_SUBCLASS_CRYPTO_ENTERTAINMENT 0x10
#define PCI_SUBCLASS_CRYPTO_MISC 0x80
/* 0x11 data acquisition and signal processing subclasses */
#define PCI_SUBCLASS_DASP_DPIO 0x00
#define PCI_SUBCLASS_DASP_TIMEFREQ 0x01
#define PCI_SUBCLASS_DASP_SYNC 0x10
#define PCI_SUBCLASS_DASP_MGMT 0x20
#define PCI_SUBCLASS_DASP_MISC 0x80
/*
* PCI BIST/Header Type/Latency Timer/Cache Line Size Register.
*/
#define PCI_BHLC_REG 0x0c
#define PCI_BIST_SHIFT 24
#define PCI_BIST_MASK 0xff
#define PCI_BIST(bhlcr) \
(((bhlcr) >> PCI_BIST_SHIFT) & PCI_BIST_MASK)
#define PCI_HDRTYPE_SHIFT 16
#define PCI_HDRTYPE_MASK 0xff
#define PCI_HDRTYPE(bhlcr) \
(((bhlcr) >> PCI_HDRTYPE_SHIFT) & PCI_HDRTYPE_MASK)
#define PCI_HDRTYPE_TYPE(bhlcr) \
(PCI_HDRTYPE(bhlcr) & 0x7f)
#define PCI_HDRTYPE_MULTIFN(bhlcr) \
((PCI_HDRTYPE(bhlcr) & 0x80) != 0)
#define PCI_LATTIMER_SHIFT 8
#define PCI_LATTIMER_MASK 0xff
#define PCI_LATTIMER(bhlcr) \
(((bhlcr) >> PCI_LATTIMER_SHIFT) & PCI_LATTIMER_MASK)
#define PCI_CACHELINE_SHIFT 0
#define PCI_CACHELINE_MASK 0xff
#define PCI_CACHELINE(bhlcr) \
(((bhlcr) >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK)
#define PCI_BHLC_CODE(bist,type,multi,latency,cacheline) \
((((bist) & PCI_BIST_MASK) << PCI_BIST_SHIFT) | \
(((type) & PCI_HDRTYPE_MASK) << PCI_HDRTYPE_SHIFT) | \
(((multi)?0x80:0) << PCI_HDRTYPE_SHIFT) | \
(((latency) & PCI_LATTIMER_MASK) << PCI_LATTIMER_SHIFT) | \
(((cacheline) & PCI_CACHELINE_MASK) << PCI_CACHELINE_SHIFT))
/*
* PCI header type
*/
#define PCI_HDRTYPE_DEVICE 0
#define PCI_HDRTYPE_PPB 1
#define PCI_HDRTYPE_PCB 2
/*
* Mapping registers
*/
#define PCI_MAPREG_START 0x10
#define PCI_MAPREG_END 0x28
#define PCI_MAPREG_ROM 0x30
#define PCI_MAPREG_PPB_END 0x18
#define PCI_MAPREG_PCB_END 0x14
#define PCI_MAPREG_TYPE(mr) \
((mr) & PCI_MAPREG_TYPE_MASK)
#define PCI_MAPREG_TYPE_MASK 0x00000001
#define PCI_MAPREG_TYPE_MEM 0x00000000
#define PCI_MAPREG_TYPE_IO 0x00000001
#define PCI_MAPREG_ROM_ENABLE 0x00000001
#define PCI_MAPREG_MEM_TYPE(mr) \
((mr) & PCI_MAPREG_MEM_TYPE_MASK)
#define PCI_MAPREG_MEM_TYPE_MASK 0x00000006
#define PCI_MAPREG_MEM_TYPE_32BIT 0x00000000
#define PCI_MAPREG_MEM_TYPE_32BIT_1M 0x00000002
#define PCI_MAPREG_MEM_TYPE_64BIT 0x00000004
#define PCI_MAPREG_MEM_PREFETCHABLE(mr) \
(((mr) & PCI_MAPREG_MEM_PREFETCHABLE_MASK) != 0)
#define PCI_MAPREG_MEM_PREFETCHABLE_MASK 0x00000008
#define PCI_MAPREG_MEM_ADDR(mr) \
((mr) & PCI_MAPREG_MEM_ADDR_MASK)
#define PCI_MAPREG_MEM_SIZE(mr) \
(PCI_MAPREG_MEM_ADDR(mr) & -PCI_MAPREG_MEM_ADDR(mr))
#define PCI_MAPREG_MEM_ADDR_MASK 0xfffffff0
#define PCI_MAPREG_MEM64_ADDR(mr) \
((mr) & PCI_MAPREG_MEM64_ADDR_MASK)
#define PCI_MAPREG_MEM64_SIZE(mr) \
(PCI_MAPREG_MEM64_ADDR(mr) & -PCI_MAPREG_MEM64_ADDR(mr))
#define PCI_MAPREG_MEM64_ADDR_MASK 0xfffffffffffffff0ULL
#define PCI_MAPREG_IO_ADDR(mr) \
((mr) & PCI_MAPREG_IO_ADDR_MASK)
#define PCI_MAPREG_IO_SIZE(mr) \
(PCI_MAPREG_IO_ADDR(mr) & -PCI_MAPREG_IO_ADDR(mr))
#define PCI_MAPREG_IO_ADDR_MASK 0xfffffffc
#define PCI_MAPREG_SIZE_TO_MASK(size) \
(-(size))
#define PCI_MAPREG_NUM(offset) \
(((unsigned)(offset)-PCI_MAPREG_START)/4)
/*
* Cardbus CIS pointer (PCI rev. 2.1)
*/
#define PCI_CARDBUS_CIS_REG 0x28
/*
* Subsystem identification register; contains a vendor ID and a device ID.
* Types/macros for PCI_ID_REG apply.
* (PCI rev. 2.1)
*/
#define PCI_SUBSYS_ID_REG 0x2c
/*
* Capabilities link list (PCI rev. 2.2)
*/
#define PCI_CAPLISTPTR_REG 0x34 /* header type 0 */
#define PCI_CARDBUS_CAPLISTPTR_REG 0x14 /* header type 2 */
#define PCI_CAPLIST_PTR(cpr) ((cpr) & 0xff)
#define PCI_CAPLIST_NEXT(cr) (((cr) >> 8) & 0xff)
#define PCI_CAPLIST_CAP(cr) ((cr) & 0xff)
#define PCI_CAP_RESERVED0 0x00
#define PCI_CAP_PWRMGMT 0x01
#define PCI_CAP_AGP 0x02
#define PCI_CAP_AGP_MAJOR(cr) (((cr) >> 20) & 0xf)
#define PCI_CAP_AGP_MINOR(cr) (((cr) >> 16) & 0xf)
#define PCI_CAP_VPD 0x03
#define PCI_CAP_SLOTID 0x04
#define PCI_CAP_MSI 0x05
#define PCI_CAP_CPCI_HOTSWAP 0x06
#define PCI_CAP_PCIX 0x07
#define PCI_CAP_LDT 0x08
#define PCI_CAP_VENDSPEC 0x09
#define PCI_CAP_DEBUGPORT 0x0a
#define PCI_CAP_CPCI_RSRCCTL 0x0b
#define PCI_CAP_HOTPLUG 0x0c
#define PCI_CAP_AGP8 0x0e
#define PCI_CAP_SECURE 0x0f
#define PCI_CAP_PCIEXPRESS 0x10
#define PCI_CAP_MSIX 0x11
/*
* Vital Product Data; access via capability pointer (PCI rev 2.2).
*/
#define PCI_VPD_ADDRESS_MASK 0x7fff
#define PCI_VPD_ADDRESS_SHIFT 16
#define PCI_VPD_ADDRESS(ofs) \
(((ofs) & PCI_VPD_ADDRESS_MASK) << PCI_VPD_ADDRESS_SHIFT)
#define PCI_VPD_DATAREG(ofs) ((ofs) + 4)
#define PCI_VPD_OPFLAG 0x80000000
/*
* Power Management Capability; access via capability pointer.
*/
/* Power Management Capability Register */
#define PCI_PMCR 0x02
#define PCI_PMCR_D1SUPP 0x0200
#define PCI_PMCR_D2SUPP 0x0400
/* Power Management Control Status Register */
#define PCI_PMCSR 0x04
#define PCI_PMCSR_STATE_MASK 0x03
#define PCI_PMCSR_STATE_D0 0x00
#define PCI_PMCSR_STATE_D1 0x01
#define PCI_PMCSR_STATE_D2 0x02
#define PCI_PMCSR_STATE_D3 0x03
/*
* PCI-X capability.
*/
/*
* Command. 16 bits at offset 2 (e.g. upper 16 bits of the first 32-bit
* word at the capability; the lower 16 bits are the capability ID and
* next capability pointer).
*
* Since we always read PCI config space in 32-bit words, we define these
* as 32-bit values, offset and shifted appropriately. Make sure you perform
* the appropriate R/M/W cycles!
*/
#define PCI_PCIX_CMD 0x00
#define PCI_PCIX_CMD_PERR_RECOVER 0x00010000
#define PCI_PCIX_CMD_RELAXED_ORDER 0x00020000
#define PCI_PCIX_CMD_BYTECNT_MASK 0x000c0000
#define PCI_PCIX_CMD_BYTECNT_SHIFT 18
#define PCI_PCIX_CMD_BCNT_512 0x00000000
#define PCI_PCIX_CMD_BCNT_1024 0x00040000
#define PCI_PCIX_CMD_BCNT_2048 0x00080000
#define PCI_PCIX_CMD_BCNT_4096 0x000c0000
#define PCI_PCIX_CMD_SPLTRANS_MASK 0x00700000
#define PCI_PCIX_CMD_SPLTRANS_1 0x00000000
#define PCI_PCIX_CMD_SPLTRANS_2 0x00100000
#define PCI_PCIX_CMD_SPLTRANS_3 0x00200000
#define PCI_PCIX_CMD_SPLTRANS_4 0x00300000
#define PCI_PCIX_CMD_SPLTRANS_8 0x00400000
#define PCI_PCIX_CMD_SPLTRANS_12 0x00500000
#define PCI_PCIX_CMD_SPLTRANS_16 0x00600000
#define PCI_PCIX_CMD_SPLTRANS_32 0x00700000
/*
* Status. 32 bits at offset 4.
*/
#define PCI_PCIX_STATUS 0x04
#define PCI_PCIX_STATUS_FN_MASK 0x00000007
#define PCI_PCIX_STATUS_DEV_MASK 0x000000f8
#define PCI_PCIX_STATUS_BUS_MASK 0x0000ff00
#define PCI_PCIX_STATUS_64BIT 0x00010000
#define PCI_PCIX_STATUS_133 0x00020000
#define PCI_PCIX_STATUS_SPLDISC 0x00040000
#define PCI_PCIX_STATUS_SPLUNEX 0x00080000
#define PCI_PCIX_STATUS_DEVCPLX 0x00100000
#define PCI_PCIX_STATUS_MAXB_MASK 0x00600000
#define PCI_PCIX_STATUS_MAXB_SHIFT 21
#define PCI_PCIX_STATUS_MAXB_512 0x00000000
#define PCI_PCIX_STATUS_MAXB_1024 0x00200000
#define PCI_PCIX_STATUS_MAXB_2048 0x00400000
#define PCI_PCIX_STATUS_MAXB_4096 0x00600000
#define PCI_PCIX_STATUS_MAXST_MASK 0x03800000
#define PCI_PCIX_STATUS_MAXST_1 0x00000000
#define PCI_PCIX_STATUS_MAXST_2 0x00800000
#define PCI_PCIX_STATUS_MAXST_3 0x01000000
#define PCI_PCIX_STATUS_MAXST_4 0x01800000
#define PCI_PCIX_STATUS_MAXST_8 0x02000000
#define PCI_PCIX_STATUS_MAXST_12 0x02800000
#define PCI_PCIX_STATUS_MAXST_16 0x03000000
#define PCI_PCIX_STATUS_MAXST_32 0x03800000
#define PCI_PCIX_STATUS_MAXRS_MASK 0x1c000000
#define PCI_PCIX_STATUS_MAXRS_1K 0x00000000
#define PCI_PCIX_STATUS_MAXRS_2K 0x04000000
#define PCI_PCIX_STATUS_MAXRS_4K 0x08000000
#define PCI_PCIX_STATUS_MAXRS_8K 0x0c000000
#define PCI_PCIX_STATUS_MAXRS_16K 0x10000000
#define PCI_PCIX_STATUS_MAXRS_32K 0x14000000
#define PCI_PCIX_STATUS_MAXRS_64K 0x18000000
#define PCI_PCIX_STATUS_MAXRS_128K 0x1c000000
#define PCI_PCIX_STATUS_SCERR 0x20000000
/*
* Interrupt Configuration Register; contains interrupt pin and line.
*/
#define PCI_INTERRUPT_REG 0x3c
typedef u8 pci_intr_latency_t;
typedef u8 pci_intr_grant_t;
typedef u8 pci_intr_pin_t;
typedef u8 pci_intr_line_t;
#define PCI_MAX_LAT_SHIFT 24
#define PCI_MAX_LAT_MASK 0xff
#define PCI_MAX_LAT(icr) \
(((icr) >> PCI_MAX_LAT_SHIFT) & PCI_MAX_LAT_MASK)
#define PCI_MIN_GNT_SHIFT 16
#define PCI_MIN_GNT_MASK 0xff
#define PCI_MIN_GNT(icr) \
(((icr) >> PCI_MIN_GNT_SHIFT) & PCI_MIN_GNT_MASK)
#define PCI_INTERRUPT_GRANT_SHIFT 24
#define PCI_INTERRUPT_GRANT_MASK 0xff
#define PCI_INTERRUPT_GRANT(icr) \
(((icr) >> PCI_INTERRUPT_GRANT_SHIFT) & PCI_INTERRUPT_GRANT_MASK)
#define PCI_INTERRUPT_LATENCY_SHIFT 16
#define PCI_INTERRUPT_LATENCY_MASK 0xff
#define PCI_INTERRUPT_LATENCY(icr) \
(((icr) >> PCI_INTERRUPT_LATENCY_SHIFT) & PCI_INTERRUPT_LATENCY_MASK)
#define PCI_INTERRUPT_PIN_SHIFT 8
#define PCI_INTERRUPT_PIN_MASK 0xff
#define PCI_INTERRUPT_PIN(icr) \
(((icr) >> PCI_INTERRUPT_PIN_SHIFT) & PCI_INTERRUPT_PIN_MASK)
#define PCI_INTERRUPT_LINE_SHIFT 0
#define PCI_INTERRUPT_LINE_MASK 0xff
#define PCI_INTERRUPT_LINE(icr) \
(((icr) >> PCI_INTERRUPT_LINE_SHIFT) & PCI_INTERRUPT_LINE_MASK)
#define PCI_INTERRUPT_CODE(lat,gnt,pin,line) \
((((lat)&PCI_INTERRUPT_LATENCY_MASK)<<PCI_INTERRUPT_LATENCY_SHIFT)| \
(((gnt)&PCI_INTERRUPT_GRANT_MASK) <<PCI_INTERRUPT_GRANT_SHIFT) | \
(((pin)&PCI_INTERRUPT_PIN_MASK) <<PCI_INTERRUPT_PIN_SHIFT) | \
(((line)&PCI_INTERRUPT_LINE_MASK) <<PCI_INTERRUPT_LINE_SHIFT))
#define PCI_INTERRUPT_PIN_NONE 0x00
#define PCI_INTERRUPT_PIN_A 0x01
#define PCI_INTERRUPT_PIN_B 0x02
#define PCI_INTERRUPT_PIN_C 0x03
#define PCI_INTERRUPT_PIN_D 0x04
#define PCI_INTERRUPT_PIN_MAX 0x04
/* Header Type 1 (Bridge) configuration registers */
#define PCI_BRIDGE_BUS_REG 0x18
#define PCI_BRIDGE_BUS_PRIMARY_SHIFT 0
#define PCI_BRIDGE_BUS_SECONDARY_SHIFT 8
#define PCI_BRIDGE_BUS_SUBORDINATE_SHIFT 16
#define PCI_BRIDGE_STATIO_REG 0x1C
#define PCI_BRIDGE_STATIO_IOBASE_SHIFT 0
#define PCI_BRIDGE_STATIO_IOLIMIT_SHIFT 8
#define PCI_BRIDGE_STATIO_STATUS_SHIFT 16
#define PCI_BRIDGE_STATIO_IOBASE_MASK 0xf0
#define PCI_BRIDGE_STATIO_IOLIMIT_MASK 0xf0
#define PCI_BRIDGE_STATIO_STATUS_MASK 0xffff
#define PCI_BRIDGE_IO_32BITS(reg) (((reg) & 0xf) == 1)
#define PCI_BRIDGE_MEMORY_REG 0x20
#define PCI_BRIDGE_MEMORY_BASE_SHIFT 4
#define PCI_BRIDGE_MEMORY_LIMIT_SHIFT 20
#define PCI_BRIDGE_MEMORY_BASE_MASK 0xffff
#define PCI_BRIDGE_MEMORY_LIMIT_MASK 0xffff
#define PCI_BRIDGE_PREFETCHMEM_REG 0x24
#define PCI_BRIDGE_PREFETCHMEM_BASE_SHIFT 4
#define PCI_BRIDGE_PREFETCHMEM_LIMIT_SHIFT 20
#define PCI_BRIDGE_PREFETCHMEM_BASE_MASK 0xffff
#define PCI_BRIDGE_PREFETCHMEM_LIMIT_MASK 0xffff
#define PCI_BRIDGE_PREFETCHMEM_64BITS(reg) ((reg) & 0xf)
#define PCI_BRIDGE_PREFETCHBASE32_REG 0x28
#define PCI_BRIDGE_PREFETCHLIMIT32_REG 0x2C
#define PCI_BRIDGE_IOHIGH_REG 0x30
#define PCI_BRIDGE_IOHIGH_BASE_SHIFT 0
#define PCI_BRIDGE_IOHIGH_LIMIT_SHIFT 16
#define PCI_BRIDGE_IOHIGH_BASE_MASK 0xffff
#define PCI_BRIDGE_IOHIGH_LIMIT_MASK 0xffff
#define PCI_BRIDGE_CONTROL_REG 0x3C
#define PCI_BRIDGE_CONTROL_SHIFT 16
#define PCI_BRIDGE_CONTROL_MASK 0xffff
#define PCI_BRIDGE_CONTROL_PERE (1 << 0)
#define PCI_BRIDGE_CONTROL_SERR (1 << 1)
#define PCI_BRIDGE_CONTROL_ISA (1 << 2)
#define PCI_BRIDGE_CONTROL_VGA (1 << 3)
/* Reserved (1 << 4) */
#define PCI_BRIDGE_CONTROL_MABRT (1 << 5)
#define PCI_BRIDGE_CONTROL_SECBR (1 << 6)
#define PCI_BRIDGE_CONTROL_SECFASTB2B (1 << 7)
#define PCI_BRIDGE_CONTROL_PRI_DISC_TIMER (1 << 8)
#define PCI_BRIDGE_CONTROL_SEC_DISC_TIMER (1 << 9)
#define PCI_BRIDGE_CONTROL_DISC_TIMER_STAT (1 << 10)
#define PCI_BRIDGE_CONTROL_DISC_TIMER_SERR (1 << 11)
/* Reserved (1 << 12) - (1 << 15) */
/*
* Vital Product Data resource tags.
*/
struct pci_vpd_smallres {
u8 vpdres_byte0; /* length of data + tag */
/* Actual data. */
} __attribute__((__packed__));
struct pci_vpd_largeres {
u8 vpdres_byte0;
u8 vpdres_len_lsb; /* length of data only */
u8 vpdres_len_msb;
/* Actual data. */
} __attribute__((__packed__));
#define PCI_VPDRES_ISLARGE(x) ((x) & 0x80)
#define PCI_VPDRES_SMALL_LENGTH(x) ((x) & 0x7)
#define PCI_VPDRES_SMALL_NAME(x) (((x) >> 3) & 0xf)
#define PCI_VPDRES_LARGE_NAME(x) ((x) & 0x7f)
#define PCI_VPDRES_TYPE_COMPATIBLE_DEVICE_ID 0x3 /* small */
#define PCI_VPDRES_TYPE_VENDOR_DEFINED 0xe /* small */
#define PCI_VPDRES_TYPE_END_TAG 0xf /* small */
#define PCI_VPDRES_TYPE_IDENTIFIER_STRING 0x02 /* large */
#define PCI_VPDRES_TYPE_VPD 0x10 /* large */
struct pci_vpd {
u8 vpd_key0;
u8 vpd_key1;
u8 vpd_len; /* length of data only */
/* Actual data. */
} __attribute__((__packed__));
/*
* Recommended VPD fields:
*
* PN Part number of assembly
* FN FRU part number
* EC EC level of assembly
* MN Manufacture ID
* SN Serial Number
*
* Conditionally recommended VPD fields:
*
* LI Load ID
* RL ROM Level
* RM Alterable ROM Level
* NA Network Address
* DD Device Driver Level
* DG Diagnostic Level
* LL Loadable Microcode Level
* VI Vendor ID/Device ID
* FU Function Number
* SI Subsystem Vendor ID/Subsystem ID
*
* Additional VPD fields:
*
* Z0-ZZ User/Product Specific
*/
/*
* Threshold below which 32bit PCI DMA needs bouncing.
*/
#define PCI32_DMA_BOUNCE_THRESHOLD 0x100000000ULL
#endif /* _DEV_PCI_PCIREG_H_ */
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论