?? sysbuspci.c
字號:
/* sysBusPci.c - Motorola CPV3060 PCI "board" special configuration code *//* Copyright 1997-2000 Wind River Systems, Inc. All Rights Reserved *//* Copyright 1997-2000 Motorola, Inc. All Rights Reserved *//*modification history--------------------01j,12jan01,rcs corrected include path to pciAutoConfigLib.h & pciConfigLib.h01i,05dec00,rhk Code cleanup to adhere to WRS coding standards.01h,26jul99,rhk changed the PCI prefetchable Memory space and the PCI I/O space allocation start addresses to begin above the area reserved for QSPAN register allocation in PCI space.01g,14jul99,rhk changed interrupt values in intLine, additional changes per code review.01f,16jun99,srr changed to match with WRS PCI Auto Configuration.01e,09jun99,srr changed to support cpv3060.01d,06nov98,rhk fixed interrupt level value for 21554 and PMC.01c,04nov98,rhk fixed pciCase1IntLine table, removed entries above dev #15.01b,27oct98,srr fixed pciAddinIndx allocation problem with QSpan.01a,02oct98,srr converted from MCP750 BSP (revision 01e).*//*DESCRIPTIONThis module contains the "non-generic" or "board specific" PCI-PCIbridge initialization code. The module contains code to: 1. Determine if a particular function is to be excluded from the automatic configuration process. 2. Program the "interrupt line" field of the PCI configuration header.*//* includes */#include "cpv3060.h"#include "drv/pci/pciAutoConfigLib.h"#include "drv/pci/pciConfigLib.h"/* defines */#define INTA2INTD 4#define CPCI_LOGIGAL_SLOTS 8#define PCI_INTA 0#define PCI_INTB 1#define PCI_INTC 2#define PCI_INTD 3#define DEV_ON_ADDIN_BUS 1/* typedefs *//* globals *//* locals *//* * Table for converting (device number, interrupt pin) to interrupt * line value for programming the PCI configuration header. This * table only applies to PCI devices which reside on bus 0 (Case 1 * as explained in sysPciAutoConfigIntAsgn()). */static UCHAR intLine [][4] = { { 0xff, 0xff, 0xff, 0xff }, /* dev #0 */ { 0xff, 0xff, 0xff, 0xff }, /* dev #1 */ { IVEC_TO_INUM(IV_QSPAN_PCI), IVEC_TO_INUM(IV_QSPAN_PCI), IVEC_TO_INUM(IV_QSPAN_PCI), IVEC_TO_INUM(IV_QSPAN_PCI) }, /* dev #2, QSPAN */ { IVEC_TO_INUM(IV_DEC21554), IVEC_TO_INUM(IV_DEC21554), IVEC_TO_INUM(IV_DEC21554), IVEC_TO_INUM(IV_DEC21554) }, /* dev #3, 21554 */ { IVEC_TO_INUM(IV_PMC1_INTA), IVEC_TO_INUM(IV_PMC1_INTB), IVEC_TO_INUM(IV_PMC1_INTC), IVEC_TO_INUM(IV_PMC1_INTD) }, /* dev #4, PMC-1 slot */ { IVEC_TO_INUM(IV_PMC2_INTA), IVEC_TO_INUM(IV_PMC2_INTB), IVEC_TO_INUM(IV_PMC2_INTC), IVEC_TO_INUM(IV_PMC2_INTD) }, /* dev #5, PMC-2 slot */ { 0xff, 0xff, 0xff, 0xff }, /* dev #6 */ { 0xff, 0xff, 0xff, 0xff }, /* dev #7 */ { 0xff, 0xff, 0xff, 0xff }, /* dev #8 */ { 0xff, 0xff, 0xff, 0xff }, /* dev #9 */ { 0xff, 0xff, 0xff, 0xff }, /* dev #10 */ { 0xff, 0xff, 0xff, 0xff }, /* dev #11, Not Used */ { 0xff, 0xff, 0xff, 0xff }, /* dev #12, Not used */ { 0xff, 0xff, 0xff, 0xff }, /* dev #13, Not used */ { 0xff, 0xff, 0xff, 0xff }, /* dev #14, Not Used */ { 0xff, 0xff, 0xff, 0xff }, /* dev #15, Not used */ };LOCAL PCI_SYSTEM sysParams;#ifdef PCI_ROLL_CALL_LIST_ENTRIES/* * PCI autoconfig roll call support * * Roll call list entry structure, list elements specified in "config.h" */typedef struct _PCI_ROLL_CALL_LIST { UINT count; UINT Dev; UINT Vend; } PCI_ROLL_CALL_LIST;LOCAL PCI_ROLL_CALL_LIST rollCall[] = { PCI_ROLL_CALL_LIST_ENTRIES { 0xffff, 0xffff, 0xffff } /* Required entry: marks end of list */ };#endif /* PCI_ROLL_CALL_LIST_ENTRIES *//* forward declarations */LOCAL UCHAR sysPciAutoConfigIntAsgn ( PCI_SYSTEM * pSys, PCI_LOC * pFunc, UCHAR intPin );LOCAL STATUS sysPciAutoConfigInclude ( PCI_SYSTEM *pSys, PCI_LOC *pciLoc, UINT devVend );#ifdef PCI_ROLL_CALL_LIST_ENTRIESLOCAL STATUS sysPciRollcallRtn ( );#endif /* PCI_ROLL_CALL_LIST_ENTRIES *//******************************************************************************** sysPciAutoConfigInclude - Determine if function is to be autoConfigured** This function is called with PCI bus, device, function, and vendor * information. It returns an indication of whether or not the particular* function should be included in the automatic configuration process.* This capability is useful if it is desired that a particular function* NOT be automatically configured. Of course, if the device is not* included in automatic configuration, it will be unusable unless the* user's code made provisions to configure the function outside of the* the automatic process.** RETURNS: OK if function is to be included in automatic configuration,* ERROR otherwise.*/ LOCAL STATUS sysPciAutoConfigInclude ( PCI_SYSTEM *pSys, /* input: AutoConfig system information */ PCI_LOC *pciLoc, /* input: PCI address of this function */ UINT devVend /* input: Device/vendor ID number */ ) { BOOL retVal = OK; /* If it's the host bridge then exclude it */ if ((pciLoc->bus == 0) && (pciLoc->device == 0) && (pciLoc->function == 0)) return ERROR; switch(devVend) { /* EXCLUDED Devices */ case PCI_ID_QSPAN: retVal = ERROR; PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Excluding QSPAN\n", 0, 0, 0, 0, 0, 0); break; /* INCLUDED Devices */ case PCI_ID_BR_DEC21554: retVal = OK; PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Including DEC 21554 bridge\n", 0, 0, 0, 0, 0, 0); break; default: retVal = OK; PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Including unknown device\n", 0, 0, 0, 0, 0, 0); break; } return retVal; }/******************************************************************************** sysPciAutoConfigIntAssign - Assign the "interrupt line" value** RETURNS: "interrupt line" value.*/LOCAL UCHAR sysPciAutoConfigIntAsgn ( PCI_SYSTEM * pSys, /* input: AutoConfig system information */ PCI_LOC * pFunc, /* input: pointer to device bus location structure */ UCHAR intPin /* input: interrupt pin number */ ) { UCHAR irqValue = 0xff; /* Calculated value */ if (intPin == 0) return irqValue; irqValue = intLine [(pFunc->device)][(intPin - 1)]; PCI_AUTO_DEBUG_MSG("intAssign called for device [%d %d %d] IRQ: %d\n", pFunc->bus, pFunc->device, pFunc->function, irqValue, 0, 0 ); return (irqValue); }#ifdef PCI_ROLL_CALL_LIST_ENTRIES/******************************************************************************* sysPciRollCallRtn - Check "roll call" list against list of PCI devices found** This function checks if the number of devices actually found during* the 1st pass of PCI autoconfiguration (bus enumeration process)* passes the "roll call" test. That is, for each entry in the roll call* list (consisting of a count and device/vendor ID), a check is made to* insure that at least the specified minimum number of devices has* actually been discovered. If the roll call passes, the function returns* TRUE. If the roll call fails and the time duration in seconds represented* by ROLL_CALL_MAX_DURATION has not elapsed, the function will wait 1* second and return FALSE. If the roll call fails and the time duration in* seconds represented by ROLL_CALL_MAX_DURATION has elapsed, the function* will return TRUE.** RETURNS: TRUE if roll call test passes or timeout, FALSE otherwise.*/LOCAL STATUS sysPciRollcallRtn ( ) { STATUS rollCallPass; /* Flag indicating pass or fail */ int rollIndex; UINT bus; UINT dev; UINT func; int count; static int secDelay = -1; if (secDelay == -1) secDelay = ROLL_CALL_MAX_DURATION; rollCallPass = TRUE; /* Default = "passed" */ rollIndex = 0; while (secDelay >= 0) { if (rollCall[rollIndex].Vend == 0xffff) break; /* End of roll call list, we're done */ count = 0; while (pciFindDevice(rollCall[rollIndex].Vend, rollCall[rollIndex].Dev, count, &bus, &dev, &func) == OK) count++; if (count < rollCall[rollIndex].count) { secDelay--; if (secDelay < 0) { rollCallPass = TRUE; /* Timeout, say we passed */ break; } else { rollCallPass = FALSE; /* Roll call - someone is missing */ sysMsDelay(1000); /* Delay a second */ break; } } rollIndex++; } if (rollCallPass == TRUE) secDelay = -1; return (rollCallPass); }#endif /* PCI_ROLL_CALL_LIST_ENTRIES *//********************************************************************************* sysPciAutoConfig - PCI autoConfig support routine** This routine instantiates the PCI_SYSTEM structure needed to configure* the system. This consists of assigning address ranges to each category* of PCI system resource: Prefetchable and Non-Prefetchable 32-bit Memory, and* 16- and 32-bit I/O. Global values for the Cache Line Size and Maximum* Latency are also specified. Finally, the four supplemental routines for * device inclusion/exclusion, interrupt assignment, and pre- and* post-enumeration bridge initialization are specified. ** RETURNS: N/A*/void sysPciAutoConfig(void) { /* * 32-bit Non-prefetchable Memory Space * offset by 0x10 so that it doesn't start at PCI address 0x0 */ sysParams.pciMemIo32 = (PCI_MSTR_MEMIO_BUS + 0x10); sysParams.pciMemIo32Size = PCI_MSTR_MEMIO_SIZE; /* 32-bit Prefetchable Memory Space */ sysParams.pciMem32 = (PCI_MSTR_MEM_BUS + QSPAN_REG_SIZE); sysParams.pciMem32Size = (PCI_MSTR_MEM_SIZE - QSPAN_REG_SIZE); /* 16-bit ISA I/O Space - start after legacy devices. */ sysParams.pciIo16 = ISA_MSTR_IO_BUS + ISA_LEGACY_SIZE; sysParams.pciIo16Size = ISA_MSTR_IO_SIZE - ISA_LEGACY_SIZE; /* 32-bit PCI I/O Space */ sysParams.pciIo32 = (PCI_MSTR_IO_BUS + QSPAN_REG_SIZE); sysParams.pciIo32Size = (PCI_MSTR_IO_SIZE - QSPAN_REG_SIZE); /* Configuration space parameters */ sysParams.maxBus = 0; sysParams.cacheSize = ( _CACHE_ALIGN_SIZE / sizeof(UINT32) ); sysParams.maxLatency = PCI_LAT_TIMER; sysParams.autoIntRouting = TRUE; /* Device inclusion and interrupt routing routines */ sysParams.includeRtn = sysPciAutoConfigInclude; sysParams.intAssignRtn = sysPciAutoConfigIntAsgn;#ifdef PCI_ROLL_CALL_LIST_ENTRIES /* "Roll call" routine */ sysParams.pciRollcallRtn = sysPciRollcallRtn;#endif /* PCI_ROLL_CALL_LIST_ENTRIES */ /* PCI-to-PCI Bridge Pre and Post-enumeration init routines */ sysParams.bridgePreConfigInit = NULL; sysParams.bridgePostConfigInit = NULL; /* Perform AutoConfig */ pciAutoConfig(&sysParams); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -