📄 syspciautoconfig.c
字号:
/* sysPciAutoConfig.c - sbc405gp PCI autoconfig support *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------01a,09may01,g_h written.*//*DESCRIPTIONThis file contains functions needed to initialize and kick off the PCIauto-configuration process, functions needed by the PCI auto-configurationsroutines to perform configuration cycles (mechanism 0), and a function toinitialize the PCI bridge in the 405GP.*//* includes */#include "vxWorks.h"#include "logLib.h"#include "taskLib.h"#include "config.h"#include "wrSbc405gp.h"#include "drv/pci/pciConfigLib.h"#include "drv/pci/pciAutoConfigLib.h"#include "pci/pciAutoConfigLib.c"/* defines */typedef enum regSize { REG_8BIT = 1, REG_16BIT = 2, REG_32BIT = 4 } REG_SIZE;/* typedefs *//* globals */PCI_SYSTEM sysParams;/* locals *//* forward declarations */LOCAL UCHAR sysPciAutoConfigIntAsgn ( PCI_SYSTEM * pSys, PCI_LOC * pFunc, UCHAR intPin );LOCAL STATUS sysPciAutoConfigInclude ( PCI_SYSTEM * pSys, PCI_LOC * pciLoc, UINT devVend );/* subroutines *//**************************************************************************** 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: TRUE if function is to be included in automatic configuration,* FALSE otherwise.*/LOCAL int 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) { default: retVal = OK; break; } return retVal; }/***************************************************************************** sysPciAutoConfigIntAssign - Assign the "interrupt line" value.** This routiner assign the interrupt line value.** RETURNS: "interrupt line" value.*/LOCAL UCHAR sysPciAutoConfigIntAsgn ( PCI_SYSTEM * pSys, /* input: AutoConfig system information */ PCI_LOC * pFunc, UCHAR intPin /* input: interrupt pin number */ ) { UCHAR retVal = 0xFF; switch(pFunc->bus) { case PPC405PCI_BRIDGE: /* Base board */ retVal = SBC405GP_PCI_INTA_IRQ; /* Carrier board PCI slot */ break; case INTEL21154PCI_BRIDGE: /* PCI Expansion board */ switch (pFunc->device) { case EXPANTION_BOARD_PCI_SLOT_J26: retVal = PCI_EXPAND_PCI_INTA_IRQ; break; case EXPANTION_BOARD_PCI_SLOT_J25: retVal = PCI_EXPAND_PCI_INTB_IRQ; break; case EXPANTION_BOARD_PCI_SLOT_J24: retVal = PCI_EXPAND_PCI_INTC_IRQ; break; case EXPANTION_BOARD_cPCI_SLOT_J22: retVal = PCI_EXPAND_PCI_INTD_IRQ; break; } } return(retVal); }/***************************************************************************** sysPciConfigWrite - write to one PCI configuration space register location** This routine writes one PCI configuration space register location of the * specified size (1, 2 or 4 bytes).** RETURNS: OK** SEE ALSO: sysPciConfigRead()*/STATUS sysPciConfigWrite ( int bus, int device, int function, int offset, /* offset into the configuration space */ int width, /* data width */ UINT data /* data to be written */ ) { int key; UINT busDevFunc; /* * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) */ busDevFunc = pciConfigBdfPack (bus, device, function); key = intLock (); sysPciOutLong (PCI_ADDRESS_REGISTER, busDevFunc | 0x80000000 | (offset & ~3)); switch (width) { case 4: sysPciOutLong (PCI_DATA_REGISTER, data); break; case 2: sysPciOutWord (PCI_DATA_REGISTER + (offset & 3), data); break; case 1: default: sysPciOutByte (PCI_DATA_REGISTER + (offset & 3), data); break; } intUnlock (key); return (OK); }/***************************************************************************** sysPciConfigRead - reads one PCI configuration space register location** This routine reads one PCI configuration space register location of the* specified size (1, 2 or 4 bytes).** RETURNS : OK** SEE ALSO: sysPciConfigWrite()*/STATUS sysPciConfigRead ( int bus, int device, int function, int offset, /* offset into the configuration space */ int width, /* data width */ void * pResult ) { int key; UINT32 data; UCHAR * pCfgByte; UINT16 * pCfgWord; UINT * pCfgLong; UINT busDevFunc; /* * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) */ busDevFunc = pciConfigBdfPack (bus, device, function); key = intLock (); sysPciOutLong (PCI_ADDRESS_REGISTER, busDevFunc | 0x80000000 | (offset & ~3)); switch (width) { case 4: data = sysPciInLong (PCI_DATA_REGISTER); pCfgLong = (UINT *)pResult; *pCfgLong = (UINT)data; break; case 2: data = sysPciInWord (PCI_DATA_REGISTER + (offset & 3)); pCfgWord = (UINT16 *)pResult; *pCfgWord = (UINT16)data; break; case 1: default: data = sysPciInByte (PCI_DATA_REGISTER + (offset & 3)); pCfgByte = (UCHAR *)pResult; *pCfgByte = (UCHAR)data; break; } intUnlock (key); /* mutual exclusion stop */ return (OK); }/**************************************************************************** sysPciHostBridgeInit - Initialize the 405GP PCI Host Bridge** Initializes the PCI bridge so it can operate as both a PCI master and slave.** NOTE: Parameters set are:* CPU->PCI (master/initiator) address translation* PCI->CPU (slave/target) address translation** RETURNS: N/A*/STATUS sysPciHostBridgeInit ( void ) { UINT16 tempShort; /* * 405GP PCI Master configuration. * Map one 512 MB range of PLB/processor addresses to PCI memory space. * PLB address 0x80000000-0x9FFFFFFF ==> PCI address 0x80000000-0x9FFFFFFF * Use byte reversed out routines to handle endianess. */ sysPciOutLong (PCIL_PMM0MA, PMM_UNUSED); /* ensure disabled b4 setting PMM0LA */ sysPciOutLong (PCIL_PMM0LA, 0x80000000); sysPciOutLong (PCIL_PMM0PCILA, 0x80000000); sysPciOutLong (PCIL_PMM0PCIHA, PMM_UNUSED); sysPciOutLong (PCIL_PMM0MA, 0xE0000001); /* no prefetching, and enable region */ /* * Map one 512 MB range of PLB/processor addresses to PCI memory space. * PLB address 0xA0000000-0xBFFFFFFF ==> PCI address 0x00000000-0x1FFFFFFF * Use byte reversed out routines to handle endianess. * This space is for the VGA card. */ sysPciOutLong (PCIL_PMM1MA, PMM_UNUSED); /* ensure disabled b4 setting PMM1LA */ sysPciOutLong (PCIL_PMM1LA, 0xA0000000); sysPciOutLong (PCIL_PMM1PCILA, PMM_UNUSED); sysPciOutLong (PCIL_PMM1PCIHA, PMM_UNUSED); sysPciOutLong (PCIL_PMM1MA, 0xE0000001); /* no prefetching, and enable region */ /* * PMM2 is not used. Initialize them to zero. */ sysPciOutLong (PCIL_PMM2MA, PMM_UNUSED); /* ensure disabled b4 setting PMM2LA */ sysPciOutLong (PCIL_PMM2LA, PMM_UNUSED); sysPciOutLong (PCIL_PMM2PCILA, PMM_UNUSED); sysPciOutLong (PCIL_PMM2PCIHA, PMM_UNUSED); sysPciOutLong (PCIL_PMM2MA, PMM_UNUSED); /* not enabled */ /* * 405GP PCI Target configuration. (PTM1) * Map one 2 GB range of PCI addresses to PLB/processor address space. * PCI address 0x00000000-0x7FFFFFFF ==> PLB address 0x00000000-0x7FFFFFFF * The 0x00000008 default value of the 405GP PTM1 Base Address Register * (in the PCI config header) is correct for this mapping. * Note: PTM1MS is hardwire enabled but we set the enable bit anyway. */ sysPciOutLong (PCIL_PTM1LA, PMM_UNUSED); sysPciOutLong (PCIL_PTM1MS, 0x80000001); /* 2GB, enable bit is hard-wired to 1 */ /* * 405GP PCI Target configuration. (PTM2) Not used here. * It is possible that the enable bit in PTM2MS could be set at power * up. The ROM monitor only needs to use PTM1, so we must make sure that * PTM2 is disabled to avoid PCI target conflicts. * Note: PTM2MS must be enabled to write PTM 2 BAR. * Zero out PTM 2 BAR, then disable via PTM2MS. */ sysPciOutLong (PCIL_PTM2LA, PMM_UNUSED); sysPciOutLong (PCIL_PTM2MS, 0x00000001); /* set enable bit */ sysPciConfigWrite (PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCIBASEADDR2, 4, PMM_UNUSED); sysPciOutLong (PCIL_PTM2MS, PMM_UNUSED); /* disable */ /* * Write the 405GP PCI Configuration regs. * Enable 405GP to be a master on the PCI bus (PMM). * Enable 405GP to act as a PCI memory target (PTM). */ sysPciConfigRead (PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCICMD, 2, &tempShort); sysPciConfigWrite (PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCICMD, 2, tempShort | BM_EN | MEM_EN); return (OK); }/***************************************************************************** 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 */ sysParams.pciMemIo32 = PCI_MEMIO_ADRS; sysParams.pciMemIo32Size = PCI_MEMIO_SIZE; /* 32-bit Prefetchable Memory Space */ sysParams.pciMem32 = PCI_MEM_ADRS; sysParams.pciMem32Size = PCI_MEM_SIZE; /* 16-bit ISA I/O Space - First block of memory in the I/O space */ sysParams.pciIo16 = PCI_ISA_IO_ADRS; sysParams.pciIo16Size = PCI_ISA_IO_SIZE; /* 32-bit PCI I/O Space - Remaining memory in the I/O space */ sysParams.pciIo32 = PCI_IO_ADRS; sysParams.pciIo32Size = PCI_IO_SIZE; /* Configuration space parameters */ sysParams.cacheSize = (_CACHE_ALIGN_SIZE / 2); /* Should be equal to 16 */ sysParams.maxLatency = PCI_LAT_TIMER; /* Should be equal to 255 */ sysParams.autoIntRouting = FALSE; sysParams.includeRtn = sysPciAutoConfigInclude; sysParams.intAssignRtn = sysPciAutoConfigIntAsgn; sysParams.bridgePreConfigInit = NULL; sysParams.bridgePostConfigInit = NULL; /* Perform AutoConfig */ pciAutoConfig (&sysParams); /* PciConfig leaves error bits in bridge status register */ sysPciConfigWrite (PCI_HOST_BUS, /* bus */ PCI_HOST_DEVICE, /* device */ PCI_HOST_FUNCTION, /* function */ 6, /* offset */ 2, /* width */ 0xf800 /* data */); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -