📄 sysbuspci.c
字号:
( 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 regAddr; UINT busDevFunc; /* * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) */ busDevFunc = pciConfigBdfPack(bus, device, function); regAddr = 0x80000000 | ((offset|busDevFunc) & 0xFFFFFFFC); key = intLock(); /* * Write config register address to the PCI config address register */ sysPciOutLong(PCI_CFGADDR, regAddr); /* * Write value to be written to the PCI config data register */ switch (width) { case 1: sysPciOutByte(PCI_CFGDATA | (offset & 0x3), (UCHAR)(data & 0xFF)); break; case 2: sysPciOutWord(PCI_CFGDATA | (offset & 0x3), (UINT16)(data & 0xFFFF)); break; case 4: sysPciOutLong(PCI_CFGDATA | (offset & 0x3), data); break; }#ifdef PPC405GP_REVB sysPciOutLong(PCI_CFGADDR, 0x00000000); /* For 405GP rev B errata # 6 */#endif intUnlock (key); /* mutual exclusion stop */ return(OK); }/********************************************************************************* ibmPciConfigRead - reads one PCI configuration space register location of the* specified size (1, 2 or 4 bytes).** This routine reads one PCI configuration register location** RETURNS : contents of specified register*/STATUS ibmPciConfigRead ( int bus, int device, int function, int offset, /* offset into the configuration space */ int width, /* data width */ void *pResult ) { int key; UINT regAddr; UINT data = 0; UINT busDevFunc; UCHAR * pCfgByte; UINT16 * pCfgWord; UINT * pCfgLong; /* * bit 31 must be 1 and bits 1:0 must be 0 (note Little Endian bit notation) */ busDevFunc = pciConfigBdfPack(bus, device, function); regAddr = 0x80000000 | ((offset|busDevFunc) & 0xFFFFFFFC); key = intLock(); /* * Write config register address to the PCI config address register */ sysPciOutLong(PCI_CFGADDR, regAddr); /* * Read value from the PCI config data register */ switch (width) { case 1: data = (unsigned int)sysPciInByte(PCI_CFGDATA | (offset & 0x3)); pCfgByte = (UCHAR *)pResult; *pCfgByte = (UCHAR)data; break; case 2: data = (unsigned int)sysPciInWord(PCI_CFGDATA | (offset & 0x3)); pCfgWord = (UINT16 *)pResult; *pCfgWord = (UINT16)data; break; case 4: data = (sysPciInLong(PCI_CFGDATA | (offset & 0x3))); pCfgLong = (UINT *)pResult; *pCfgLong = (UINT)data; break; }#ifdef PPC405GP_REVB sysPciOutLong(PCI_CFGADDR, 0x00000000); /* For 405GP rev B errata # 6 */#endif 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.* Parameters set are:* CPU->PCI (master/initiator) address translation* PCI->CPU (slave/target) address translation** RETURNS: N/A**/STATUS sysPciHostBridgeInit() { UINT16 temp_short; /* * Disable all PCI Master regions initially */ sysPciOutLong(PCIL_PMM0MA, PMM_UNUSED); sysPciOutLong(PCIL_PMM1MA, PMM_UNUSED); sysPciOutLong(PCIL_PMM2MA, PMM_UNUSED); /* * Disable PCI Target region 2 initially. Region 1 is hardwired to always * be active. */ sysPciOutLong(PCIL_PTM2MS, PTM_UNUSED); /* * Drive PCI Reset out. This is done for warm start. * Reset must be held for at least 1ms. */ ibmPciConfigRead(PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCI_CFG_BRDGOPT2, 2, &temp_short); ibmPciConfigWrite(PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCI_CFG_BRDGOPT2, 2, temp_short | 0x1000); sysLocalDelay(1); /* kernel may not be up yet!! */ ibmPciConfigWrite(PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCI_CFG_BRDGOPT2, 2, temp_short); /* * Set up the PCI Master configuration (PMM). This is the local memory * address to PCI memory address mapping. * See config.h */ sysPciOutLong(PCIL_PMM0LA, PMM0_LOCAL_ADRS); /* PMM region 0 */ sysPciOutLong(PCIL_PMM0PCILA, PMM0_PCI_LOW_ADRS); sysPciOutLong(PCIL_PMM0PCIHA, PMM0_PCI_HIGH_ADRS); sysPciOutLong(PCIL_PMM0MA, PMM0_PCI_MASK_ATTRIB); sysPciOutLong(PCIL_PMM1LA, PMM1_LOCAL_ADRS); /* PMM region 1 */ sysPciOutLong(PCIL_PMM1PCILA, PMM1_PCI_LOW_ADRS); sysPciOutLong(PCIL_PMM1PCIHA, PMM1_PCI_HIGH_ADRS); sysPciOutLong(PCIL_PMM1MA, PMM1_PCI_MASK_ATTRIB); sysPciOutLong(PCIL_PMM2LA, PMM2_LOCAL_ADRS); /* PMM region 2 */ sysPciOutLong(PCIL_PMM2PCILA, PMM2_PCI_LOW_ADRS); sysPciOutLong(PCIL_PMM2PCIHA, PMM2_PCI_HIGH_ADRS); sysPciOutLong(PCIL_PMM2MA, PMM2_PCI_MASK_ATTRIB); /* * Set up the PCI Target configuration (PTM). This is the PCI memory * address to local memory address mapping (slave window). * See config.h. The enable bit for region 1 is hardwired on. */ sysPciOutLong(PCIL_PTM1LA, PTM1_LOCAL_ADRS); sysPciOutLong(PCIL_PTM1MS, PTM1_SIZE_ATTRIB); ibmPciConfigWrite(PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCI_CFG_BASE_ADDRESS_1, 4, PCI_SLV_MEM_BUS); /* * It is possible that the enable bit in PCIL_PTM2MS could be set at power * up. If PTM2 is not going to be used, we must make sure that PTM2 * is properly disabled to avoid PCI target conflicts. PTM2MS must be * enabled to write PTM 2 BAR. Zero out PTM 2 BAR, then disable via PTM2MS. */ if (PTM2_SIZE_ATTRIB == PTM_UNUSED) /* PTM2 not being used */ { sysPciOutLong(PCIL_PTM2LA, PTM_UNUSED); sysPciOutLong(PCIL_PTM2MS, PTM_ENABLE); /* enable temporarily */ ibmPciConfigWrite(PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCI_CFG_BASE_ADDRESS_2, 4, PTM_UNUSED); sysPciOutLong(PCIL_PTM2MS, PTM_UNUSED); /* now disable */ } else /* PTM2 will be used */ { sysPciOutLong(PCIL_PTM2LA, PTM2_LOCAL_ADRS); sysPciOutLong(PCIL_PTM2MS, PTM2_SIZE_ATTRIB); } /* * 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). */ ibmPciConfigRead(PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCI_CFG_COMMAND, 2, &temp_short); temp_short |= (PCI_CMD_MASTER_ENABLE | PCI_CMD_MEM_ENABLE); ibmPciConfigWrite(PCI_HOST_BUS, PCI_HOST_DEVICE, PCI_HOST_FUNCTION, PCI_CFG_COMMAND, 2, temp_short); /* * Default value of the Bridge Options1 register is OK (0xFF60). * No need to change it. */ /* Default value of the Bridge Options2 register is OK (0x0100) for * 405GP Rev B and beyond. */ return(OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -