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

📄 sb1250_pci_machdep.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  *********************************************************************    *  Broadcom Common Firmware Environment (CFE)    *    *  BCM1250-specific PCI support		File: sb1250_pci_machdep.c    *      *********************************************************************      *    *  Copyright 2001,2002,2003    *  Broadcom Corporation. All rights reserved.    *    *  This software is furnished under license and may be used and     *  copied only in accordance with the following terms and     *  conditions.  Subject to these conditions, you may download,     *  copy, install, use, modify and distribute modified or unmodified     *  copies of this software in source and/or binary form.  No title     *  or ownership is transferred hereby.    *      *  1) Any source code used, modified or distributed must reproduce     *     and retain this copyright notice and list of conditions     *     as they appear in the source file.    *      *  2) No right is granted to use any trade name, trademark, or     *     logo of Broadcom Corporation.  The "Broadcom Corporation"     *     name may not be used to endorse or promote products derived     *     from this software without the prior written permission of     *     Broadcom Corporation.    *      *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR     *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT     *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN     *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR 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), EVEN IF ADVISED OF     *     THE POSSIBILITY OF SUCH DAMAGE.    ********************************************************************* *//* * Based in part on the algor p5064 version of pci_machdep.c, * from SiByte sources dated 20000824, which was distributed with * the copyright and license notices below: *//* Very loosely based on: *//*	$NetBSD: pci_machdep.c,v 1.17 1995/07/27 21:39:59 cgd Exp $	*//* * Copyright (c) 1994 Charles 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 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. *//* * Sibyte SB-1250 machine-specific functions for PCI autoconfiguration. */#include "cfe.h"#include "sbmips.h"#include "sb1250_defs.h"#include "sb1250_regs.h"#include "sb1250_scd.h"#include "lib_physio.h"#include "env_subr.h"extern void cfe_ledstr(const char *);#include "pcivar.h"#include "pci_internal.h"#include "pcireg.h"#include "ldtreg.h"#define	SBD_DISPLAY(msg)	cfe_ledstr(msg)const cons_t pci_optnames[] = {    {"verbose",PCI_FLG_VERBOSE},    {"ldt_rev_017",PCI_FLG_LDT_REV_017},    {NULL,0}};extern int _pciverbose;/* PCI regions in system physical (ZBbus) space.  See Figure 37. */#define PCI_PORTMAX  (PCI_HOST_PORTS-1)static struct {    /* ZBbus space allocated for mapping to the standard PCI address spaces */    uint32_t mem_space;    uint32_t mem_space_size;    uint32_t io_space;    uint32_t io_space_size;    uint32_t cfg_space;    uint32_t cfg_space_size;    /* PCI space available for configuration */    uint32_t pci_mem_base;    uint32_t pci_io_base;    /* Bits for endian policy (0: match bytes, 1: match bits) */    uint32_t mem_bit_endian;    uint32_t io_bit_endian;    uint32_t cfg_bit_endian;    /* Match bits base for configuration (convenience variable) */    physaddr_t cfg_base;    /* Message Signaled Interrupt destinations. */    uint64_t msi_set_base;    uint64_t msi_clear_base;    uint64_t msi_bit_endian;} Q;static voidpci_set_root (void){    Q.mem_space = A_PHYS_LDTPCI_IO_MATCH_BYTES_32;  /* 0x0040000000 */    Q.mem_space_size = 0x0020000000;    Q.io_space = A_PHYS_LDTPCI_IO_MATCH_BYTES;      /* 0x00DC000000 */    Q.io_space_size = 0x0002000000;    Q.cfg_space = A_PHYS_LDTPCI_CFG_MATCH_BYTES;    /* 0x00DE000000 */    Q.cfg_space_size = 0x0001000000;    Q.pci_mem_base = 0x40000000;    Q.pci_io_base = 0x00000000;    Q.mem_bit_endian = 0x0020000000;    Q.io_bit_endian = 0x0020000000;    Q.cfg_bit_endian = 0x0020000000;    Q.cfg_base = PHYS_TO_XKSEG_UNCACHED(Q.cfg_space | Q.cfg_bit_endian);    Q.msi_set_base = A_IMR_REGISTER(0, R_IMR_ALIAS_MAILBOX_SET_CPU);    Q.msi_clear_base = A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU);    Q.msi_bit_endian = 0x0020000000;}/* Templates for bus attributes. */static const struct pci_bus sb1250_pci_bus = {	0,		/* minimum grant */	255,		/* maximum latency */	1,		/* devsel time = medium */	1,		/* we support fast back-to-back */	1,		/* we support prefetch */	1,		/* we support 66 MHz */	0,		/* we don't support 64 bits */	4000000,	/* bandwidth: in 0.25us cycles / sec */	0,		/* initially no devices on bus */};static const struct pci_bus secondary_pci_bus = {	0,		/* minimum grant */	255,		/* maximum latency */	0,		/* devsel time = unknown */	0,		/* configure fast back-to-back */	0,		/* we don't prefetch */	0,		/* configure 66 MHz */	0,		/* we don't support 64 bits */	4000000,	/* bandwidth: in 0.25us cycles / sec */	0,		/* initially no devices on bus */};#define MAXBUS	10static struct pci_bus _pci_bus[MAXBUS];static int _pci_nbus = 0;#define	SB1250_PCI_MAKE_TAG(b,d,f)					\    (((b) << 16) | ((d) << 11) | ((f) << 8))#if defined(__MIPSEB)/* This is for big-endian with a match bits policy. */#define	SB1250_CFG_ADDR(t, o, w)					\    ((Q.cfg_base + (t) + (o)) ^ (4 - (w)))#elif defined(__MIPSEL)/* This is for little-endian, either policy. */#define	SB1250_CFG_ADDR(t, o, w)					\    (Q.cfg_base + (t) + (o))#else#error "Must specifiy either MIPSEL or MIPSEB"#endifpcireg_t  pci_conf_read8(pcitag_t, int);void	  pci_conf_write8(pcitag_t, int, pcireg_t);#ifndef pci_conf_read32#define pci_conf_read32  pci_conf_read#endif#ifndef pci_conf_write32#define pci_conf_write32 pci_conf_write#endif/* Access functions *//* The following should return the index of the last usable bus port. */intpci_maxport (void){    return PCI_PORTMAX;}/* The following must either fail or return the next sequential bus   number to make secondary/subordinate numbering work correctly. */intpci_nextbus (int port){    int bus = _pci_nbus;    if (bus >= MAXBUS)	return -1;    _pci_nbus++;    return bus;}  intpci_maxbus (int port){    return _pci_nbus - 1;}struct pci_bus *pci_businfo (int port, int bus){    return (bus < _pci_nbus ? &_pci_bus[bus] : NULL);}/* * PCI address resources. * NB: initial limits for address allocation are assumed to be aligned * appropriately for PCI bridges (4K boundaries for I/O, 1M for memory). */pcireg_tpci_minmemaddr (int port){    /* skip the 16MB reserved for ISA mem space */    return Q.pci_mem_base + 0x1000000;}pcireg_tpci_maxmemaddr (int port){    return Q.pci_mem_base + Q.mem_space_size;}pcireg_tpci_minioaddr (int port){    /* Skip the 32KB reserved for ISA i/o space. */    return Q.pci_io_base + 0x8000;}pcireg_tpci_maxioaddr (int port){    return Q.pci_io_base + Q.io_space_size;}/* The SB-1250 integrated host bridges. */#define PCI_VENDOR_SIBYTE               0x166d#define	SB1250_PCI_BRIDGE	(SB1250_PCI_MAKE_TAG(0,0,0))#define	SB1250_LDT_BRIDGE	(SB1250_PCI_MAKE_TAG(0,1,0))static int sb1250_in_device_mode;static int sb1250_ldt_slave_mode;static int sb1250_ldt_init;   /* Set to one after LHB sees InitDone *//* The pass 1 BCM1250 does not implement EOI cycles correctly.  Later   passes do.  The following variable controls whether PCI interrupt   mappings are programmed to be level-sensitive (EOI) or   edge-sensitive (no EOI) in LDT-PCI bridges. */int eoi_implemented;/* Implementation-specific registers for the PCI Host Bridge (PHB) */#define PHB_FEATURE_REG                 0x40#define PHB_FEATURE_DEFAULTS		0x7DB38080#define PHB_MAP_REG_BASE                0x44#define PHB_MAP_N_ENTRIES               16/* The format of MAP table entries */#define PHB_MAP_ENABLE                  (1 << 0)#define PHB_MAP_SEND_LDT                (1 << 1)#define PHB_MAP_L2CA                    (1 << 2)#define PHB_MAP_ENDIAN                  (1 << 3)#define PHB_MAP_ADDR_SHIFT              12#define PHB_MAP_ADDR_MASK               0xFFFFF000#define PHB_MAP_ENTRY_SPAN              (1 << 20)#define PHB_ERRORADDR_REG               0x84#define PHB_ADD_STAT_CMD_REG            0x88#define PHB_SUBSYSSET_REG               0x8C/* pass 2 additions */#define PHB_READHOST_REG                0x94#define PHB_READHOST_DISABLE            (0 << 0)   /* write only */#define PHB_READHOST_ENABLE             (1 << 0)#define PHB_ADAPTEXT_REG                0x98#define PHB_DIS_DMAR_IOW_DEP            (1 << 6)/* PCI host bridge configuration * * Note that the PCI host bridge has two, mostly disjoint, sets of * configuration registers.  One is used in Host mode and is * accessible from the ZBbus; the other is used in Device mode and is * accessible from the PCI bus.  The MAP registers are shared but in * Pass 1 are write-only, from the ZBbus side.  In pass 2, they are * readable iff read_host is set. */static voidphb_init (void){    int i;    pcireg_t csr, cr, aer, icr;    pcireg_t t;            /* used for reads that push writes */    /* reset the PCI busses */    /* PCI is only reset at system reset */        /* PCI: disable and clear the BAR0 MAP registers */    for (i = 0; i < PHB_MAP_N_ENTRIES; i++)        pci_conf_write32(SB1250_PCI_BRIDGE, PHB_MAP_REG_BASE + 4*i, 0);    /* Because they write to the ZBbus bank of configuration       registers, some of the following initializations are noops in       Device mode, but they do no harm. */    /* PCI: set feature and timeout registers to their default. */    pci_conf_write32(SB1250_PCI_BRIDGE, PHB_FEATURE_REG, PHB_FEATURE_DEFAULTS);    /* PCI: enable bridge to PCI and PCI memory accesses, including       write-invalidate, plus error handling */    csr = PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE |          PCI_COMMAND_INVALIDATE_ENABLE |          PCI_COMMAND_SERR_ENABLE |  PCI_COMMAND_PARITY_ENABLE;    pci_conf_write32(SB1250_PCI_BRIDGE, PCI_COMMAND_STATUS_REG, csr);    /* PCI: clear errors */    csr = pci_conf_read32(SB1250_PCI_BRIDGE, PCI_COMMAND_STATUS_REG);    csr |= PCI_STATUS_PARITY_ERROR | PCI_STATUS_SYSTEM_ERROR |           PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT |           PCI_STATUS_TARGET_TARGET_ABORT | PCI_STATUS_PARITY_DETECT;    pci_conf_write32(SB1250_PCI_BRIDGE, PCI_COMMAND_STATUS_REG, csr);    /* PCI: allow liberal ordering rules */    /* Despite the manual, setting dis_dmar_iow_dep is recommended       unless strict ordering is required, since it can substantially       improve performance in the presence of slow devices. */    aer = pci_conf_read32(SB1250_PCI_BRIDGE, PHB_ADAPTEXT_REG);    aer |= PHB_DIS_DMAR_IOW_DEP;    pci_conf_write32(SB1250_PCI_BRIDGE, PHB_ADAPTEXT_REG, aer);    /* PCI: set up interrupt mapping */    icr = pci_conf_read32(SB1250_PCI_BRIDGE, PCI_BPARAM_INTERRUPT_REG);

⌨️ 快捷键说明

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