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

📄 bcm1480_pci_machdep.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  *********************************************************************    *  Broadcom Common Firmware Environment (CFE)    *    *  BCM1400-specific PCI support		File: bcm1480_pci_machdep.c    *      *********************************************************************      *    *  Copyright 2001,2002,2003,2004    *  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. *//* * BCM1280/BCM1480 machine-specific functions for PCI autoconfiguration. */#include "cfe.h"#include "sbmips.h"#include "bcm1480_regs.h"#include "bcm1480_pci.h"#include "bcm1480_ht.h"#include "bcm1480_hsp.h"#include "bcm1480_scd.h"#include "lib_physio.h"#include "env_subr.h"#include "pcivar.h"#include "pci_internal.h"#include "pcireg.h"#include "ldtreg.h"#ifndef CONFIG_HT#define CONFIG_HT   1#endifconst cons_t pci_optnames[] = {    {"verbose",PCI_FLG_VERBOSE},    {NULL,0}};extern int _pciverbose;/* PCI regions in system physical (ZBbus) space.  See Figure 17. */#define PCI_PORTMAX   (PCI_HOST_PORTS-1)struct host_port {    /* 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;};static struct host_port P[PCI_HOST_PORTS];/* The current bus space */static int               root;static struct host_port *pci_select_root (int bus_space){    struct host_port *p;    switch (bus_space) {	case 0:    /* PCI interface (Figure 17) */	    root = 0;	    p = &P[0];	    p->mem_space = A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES;  /* 0x0030000000 */	    p->mem_space_size = 0x0010000000;	    p->io_space = A_BCM1480_PHYS_PCI_IO_MATCH_BYTES;    /* 0x002C000000 */	    p->io_space_size = 0x0002000000;	    p->cfg_space = A_BCM1480_PHYS_PCI_CFG_MATCH_BYTES;  /* 0x002E000000 */	    p->cfg_space_size = 0x0001000000;	    p->pci_mem_base = p->mem_space;             /* now transparent */	    p->pci_io_base = 0x00000000;	    p->mem_bit_endian = 0x0080000000;           /* now all the same */	    p->io_bit_endian  = 0x0080000000;	    p->cfg_bit_endian = 0x0080000000;	    break;	case 1:    /* HT interface (Figure 26) */	    root = 1;	    p = &P[1];	    p->mem_space = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES;   /* 0x0040000000 */	    p->mem_space_size = 0x0020000000;	    p->io_space = A_BCM1480_PHYS_HT_IO_MATCH_BYTES;     /* 0x00DC000000 */	    p->io_space_size = 0x0020000000;	    p->cfg_space = A_BCM1480_PHYS_HT_CFG_MATCH_BYTES;   /* 0x00DE000000 */	    p->cfg_space_size = 0x0001000000;	    p->pci_mem_base = p->mem_space;             /* transparent */	    p->pci_io_base = 0x00000000;	    p->mem_bit_endian = 0x0020000000;	    p->io_bit_endian  = 0x0020000000;	    p->cfg_bit_endian = 0x0020000000;	    break;	default:	    return NULL;    }    p->cfg_base = PHYS_TO_XKSEG_UNCACHED(p->cfg_space | p->cfg_bit_endian);    return p;}/* Templates for bus attributes. */static const struct pci_bus bcm1400_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 */	1,		/* we support 64 bit addressing and DAC */	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	BCM1400_PCI_MAKE_TAG(p,b,d,f)					\    (((p) << 24) | ((b) << 16) | ((d) << 11) | ((f) << 8))#define BCM1400_HOST_PORT(tag) (((tag) >> 24) & 0xFF)#if defined(__MIPSEB)/* This is for big-endian with a match bits policy. */#define	BCM1400_CFG_ADDR(t, o, w)					\   ((P[BCM1400_HOST_PORT(t)].cfg_base + ((t) & 0xFFFF00) + (o)) ^ (4 - (w)))#elif defined(__MIPSEL)/* This is for little-endian, either policy. */#define	BCM1400_CFG_ADDR(t, o, w)					\    (P[BCM1400_HOST_PORT(t)].cfg_base + ((t) & 0xFFFF00) + (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   (less than the maximum for the bcm1255, bcm1455, etc.) */intpci_maxport (void){    uint64_t sysrev;    sysrev = SBREADCSR(A_SCD_SYSTEM_REVISION);    return ((G_SYS_PART(sysrev) & 0xF) == 0x6 ? 2 : 1) - 1;}/* 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 P[port].pci_mem_base + 0x1000000;}pcireg_tpci_maxmemaddr (int port){    return P[port].pci_mem_base + P[port].mem_space_size;}pcireg_tpci_minioaddr (int port){    /* Skip the 32KB reserved for ISA i/o space. */    return P[port].pci_io_base + 0x8000;}pcireg_tpci_maxioaddr (int port){    return P[port].pci_io_base + P[port].io_space_size;}/* The BCM1400 integrated host bridges. */#define PCI_VENDOR_SIBYTE       0x166d#define	BCM1400_PCI_BRIDGE	(BCM1400_PCI_MAKE_TAG(0,0,0,0))#define	BCM1400_LDT_BRIDGE	(BCM1400_PCI_MAKE_TAG(1,0,4,0))/* The BCM1400 integrated external PCI/HT bridges. */#define BCM1400_EXT0_BRIDGE     (BCM1400_PCI_MAKE_TAG(1,0,0,0))#define BCM1400_EXT1_BRIDGE     (BCM1400_PCI_MAKE_TAG(1,0,1,0))#define BCM1400_EXT2_BRIDGE     (BCM1400_PCI_MAKE_TAG(1,0,2,0))static int bcm1400_in_device_mode;static int bcm1400_ldt_slave_mode;int eoi_implemented;    /* vestigal 1250 *//* Convenience definitions for the PCI Host Bridge (PHB) */#define M_BCM1480_PCI_RST_ASSERTS       (M_BCM1480_PCI_PERR_RST_ASSERT   | \                                         M_BCM1480_PCI_DEVSEL_RST_ASSERT | \                                         M_BCM1480_PCI_STOP_RST_ASSERT   | \                                         M_BCM1480_PCI_TRDY_RST_ASSERT)#define M_BCM1480_PHB_FCTRL_MEM_EN	(M_BCM1480_PHB_FCTRL_LOW_MEM_EN | \                                         M_BCM1480_PHB_FCTRL_UPPER_MEM_EN)#define V_BCM1480_PHB_READHOST_DISABLE   0#define V_BCM1480_PHB_READHOST_ENABLE    M_BCM1480_PHB_EXT_CONFIG_DIS/* * PCI-X host bridge configuration */static voidphb_init (void){    uint64_t reset_ctl, reset_stat;    enum {pci33, pci66, pcix66, pcix133} mode;    enum {pci_bus, pcix_bus} protocol;    unsigned int clock;    int i;    pcireg_t csr, icr;    pcireg_t id;    pcireg_t t;            /* used for reads that push writes */    /* PCI: reset the busses rooted in this host bridge */    reset_ctl = SBREADCSR(A_BCM1480_PCI_RESET);    if ((reset_ctl & M_BCM1480_PCI_RESET_PIN) == 0) {	reset_ctl |= M_BCM1480_PCI_RESET_PIN;	SBWRITECSR(A_BCM1480_PCI_RESET, reset_ctl);	cfe_usleep(100);	}    pci_clock_reset();    reset_ctl &= ~M_BCM1480_PCI_PCIXCAP_PULLUP;    SBWRITECSR(A_BCM1480_PCI_RESET, reset_ctl);    cfe_usleep(100);    reset_stat = SBREADCSR(A_BCM1480_PCI_RESET);    if ((reset_stat & M_BCM1480_PCI_PCIXCAP_STATUS) != 0) {	mode = pcix133;	protocol = pcix_bus;	}    else {	reset_ctl |= M_BCM1480_PCI_PCIXCAP_PULLUP;	SBWRITECSR(A_BCM1480_PCI_RESET, reset_ctl);	cfe_usleep(100);	reset_stat = SBREADCSR(A_BCM1480_PCI_RESET);	if ((reset_stat & M_BCM1480_PCI_PCIXCAP_STATUS) != 0) {	    mode = pcix66;	    protocol = pcix_bus;	    }	else {	    protocol = pci_bus;	    if ((reset_stat & M_BCM1480_PCI_M66EN_STATUS) != 0)		mode = pci66;	    else		mode = pci33;	    }	reset_ctl &= ~M_BCM1480_PCI_PCIXCAP_PULLUP;	SBWRITECSR(A_BCM1480_PCI_RESET, reset_ctl);	}    /* Choose the clock speed. */    pci_tagprintf(BCM1400_PCI_BRIDGE, "configuring bus for ");    reset_ctl &= ~M_BCM1480_PCI_RST_ASSERTS;    switch (mode) {	case pci33:  default:	    clock = pci_clock_select(33);	    break;	case pci66:	    clock = pci_clock_select(66);	    break;	case pcix66:	    reset_ctl |= M_BCM1480_PCI_STOP_RST_ASSERT;	    clock = pci_clock_select(66);	    break;	case pcix133:	    reset_ctl |= (M_BCM1480_PCI_TRDY_RST_ASSERT | 			  M_BCM1480_PCI_STOP_RST_ASSERT);	    clock = pci_clock_select(133);	    break;	}    xprintf("%dMHz PCI%s\n", clock, (protocol == pcix_bus ? "-X" : ""));        pci_clock_enable(1);    cfe_usleep(1000);        /* Let clocks stabilize. */    SBWRITECSR(A_BCM1480_PCI_RESET, reset_ctl);    cfe_usleep(1000);        /* Set up Init Pattern */    pci_clock_enable(1);    cfe_usleep(1000);        /* Let clocks stabilize. */    /* Release PCI reset */    reset_ctl &= ~M_BCM1480_PCI_RESET_PIN;    SBWRITECSR(A_BCM1480_PCI_RESET, reset_ctl);    for (i = 1000; i > 0; i--) {	reset_stat = SBREADCSR(A_BCM1480_PCI_RESET);	if ((reset_stat & 0x3) == 0)	    break;	cfe_usleep(100);	}    if (i == 0)	xprintf("phb: PCI reset failed to clear\n");    /* Delay here to guarantee 0.5 sec device initialization time. */    cfe_sleep(CFE_HZ/2);        /* The ResetIntr bit is always set here; clear it. */    SBWRITECSR(A_BCM1480_PCI_RESET, reset_ctl | M_BCM1480_PCI_RESET_INTR);#if (PCI_DEBUG != 0)    xprintf("phb: post-reset %08llx\n",	    SBREADCSR(A_BCM1480_PCI_RESET) & 0xFFFFFFFF);#endif    /* PCI: disable and clear the BAR0 MAP registers */    for (i = 0; i < BCM1480_PHB_MAPENTRIES; i++)        pci_conf_write32(BCM1400_PCI_BRIDGE, R_BCM1480_PHB_MAPBASE + 4*i, 0);    /* PCI: set feature register to its default. */    pci_conf_write32(BCM1400_PCI_BRIDGE, R_BCM1480_PHB_FCTRL,

⌨️ 快捷键说明

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