📄 pci_core.c
字号:
/************************************************************************ * * pci_core.c * * Core card specific PCI code * * ###################################################################### * * mips_start_of_legal_notice * * Copyright (c) 2004 MIPS Technologies, Inc. All rights reserved. * * * Unpublished rights (if any) reserved under the copyright laws of the * United States of America and other countries. * * This code is proprietary to MIPS Technologies, Inc. ("MIPS * Technologies"). Any copying, reproducing, modifying or use of this code * (in whole or in part) that is not expressly permitted in writing by MIPS * Technologies or an authorized third party is strictly prohibited. At a * minimum, this code is protected under unfair competition and copyright * laws. Violations thereof may result in criminal penalties and fines. * * MIPS Technologies reserves the right to change this code to improve * function, design or otherwise. MIPS Technologies does not assume any * liability arising out of the application or use of this code, or of any * error or omission in such code. Any warranties, whether express, * statutory, implied or otherwise, including but not limited to the implied * warranties of merchantability or fitness for a particular purpose, are * excluded. Except as expressly provided in any written license agreement * from MIPS Technologies or an authorized third party, the furnishing of * this code does not give recipient any license to any intellectual * property rights, including any patent rights, that cover this code. * * This code shall not be exported, reexported, transferred, or released, * directly or indirectly, in violation of the law of any country or * international law, regulation, treaty, Executive Order, statute, * amendments or supplements thereto. Should a conflict arise regarding the * export, reexport, transfer, or release of this code, the laws of the * United States of America shall be the governing law. * * This code constitutes one or more of the following: commercial computer * software, commercial computer software documentation or other commercial * items. If the user of this code, or any related documentation of any * kind, including related technical data or manuals, is an agency, * department, or other entity of the United States government * ("Government"), the use, duplication, reproduction, release, * modification, disclosure, or transfer of this code, or any related * documentation of any kind, is restricted in accordance with Federal * Acquisition Regulation 12.212 for civilian agencies and Defense Federal * Acquisition Regulation Supplement 227.7202 for military agencies. The use * of this code by the Government is further restricted in accordance with * the terms of the license agreement(s) and/or applicable contract terms * and conditions covering this code from MIPS Technologies or an authorized * third party. * * * * * mips_end_of_legal_notice * * ************************************************************************//************************************************************************ * Include files ************************************************************************/#include <sysdefs.h>#include <sys_api.h>#include <syserror.h>#include <pci.h>#include <pci_api.h>#include <product.h>#include <atlas.h>#include <gt64120.h>#include <bonito64.h>#include <core_bonito64.h>#include <core_sys.h>/************************************************************************ * Definitions ************************************************************************//************************************************************************ * Public variables ************************************************************************//************************************************************************ * Static variables ************************************************************************//* SDRAM ranges on Galileo */static UINT32 scs10_start, scs10_size;static UINT32 scs32_start, scs32_size;/* Galileo names */static char *name_galileo = "Galileo";static char *name_64120 = "64120";static char *name_algorithmics = "Algorithmics";static char *name_bonito64 = "Bonito64";static char *name_mips = "MIPS";static char *name_sysctrl = "MSC01";/************************************************************************ * Static function prototypes ************************************************************************/static UINT32config_gt64120( void );static UINT32config_bonito64( void );static UINT32config_sysctrl( void );static voidgt_calc_range( UINT32 ld, UINT32 hd, UINT32 *start, UINT32 *size );static UINT32sc_calc_pwr2( UINT32 arg );/************************************************************************ * Implementation : Public functions ************************************************************************//************************************************************************ * * arch_pci_config_controller * Description : * ------------- * * Configure system controller regarding PCI. * * Return values : * --------------- * * OK or ERROR_PCI_STRUCTURE (should never happen) * ************************************************************************/UINT32arch_pci_config_controller( t_pci_bar_req *bar_req, /* Array for fixed bar requests */ UINT32 *bar_count, /* Current number of fixed bar req. */ UINT32 max_bar_count, /* Max fixed bar requests */ UINT8 intline, /* Interrupt line for controller */ t_known_dev *controller ) /* Controller data to be filled out */{#ifdef BONITO_DEVID_HACK#undef PCI_DEVID_BONITO64 UINT16 PCI_DEVID_BONITO64;#endif controller->intline = intline; switch( sys_corecard ) { case MIPS_REVISION_CORID_CORE_SYS : case MIPS_REVISION_CORID_CORE_FPGA2 : case MIPS_REVISION_CORID_CORE_EMUL_SYS : /**** MIPS system controller ****/ DISP_STR( "SOCit101" ); /* Setup known device data */ controller->vendorid = PCI_VENDID_MIPS; controller->devid = PCI_DEVID_MSC01; controller->function = 0; controller->vendor = name_mips; controller->device = name_sysctrl; /* Configure System Controller */ config_sysctrl(); if( *bar_count + 1 > max_bar_count ) return ERROR_PCI_STRUCTURE; /* BAR requirements due to system Ctrl */ bar_req[*bar_count].vendorid = PCI_VENDID_MIPS; bar_req[*bar_count].devid = PCI_DEVID_MSC01; bar_req[*bar_count].function = 0; bar_req[*bar_count].bar.pos = PCI_BAR(0); bar_req[*bar_count].bar.io = FALSE; bar_req[*bar_count].bar.prefetch = FALSE; bar_req[*bar_count].bar.start = 0; bar_req[*bar_count].bar.size = sc_calc_pwr2( sys_ramsize ); (*bar_count) += 1; return OK; case MIPS_REVISION_CORID_BONITO64 : case MIPS_REVISION_CORID_CORE_20K : case MIPS_REVISION_CORID_CORE_EMUL_20K : /**** Bonito64 system controller ****/ DISP_STR( "BONITO64" ); /* Setup known device data */ controller->vendorid = PCI_VENDID_ALGORITHMICS;#ifdef BONITO_DEVID_HACK /* Needed for CORE_EMUL_20K until Rick fixes Device ID */ /* Read actual device id and use that as reuired device id */ arch_pci_config_access( 0, 0x11, 0, 2, FALSE, 2, &PCI_DEVID_BONITO64);#endif controller->devid = PCI_DEVID_BONITO64; controller->function = 0; controller->vendor = name_algorithmics; controller->device = name_bonito64; /* Configure Bonito64 */ config_bonito64(); if( *bar_count + 2 > max_bar_count ) return ERROR_PCI_STRUCTURE; /* BAR requirements due to Bonito */ bar_req[*bar_count].vendorid = PCI_VENDID_ALGORITHMICS; bar_req[*bar_count].devid = PCI_DEVID_BONITO64; bar_req[*bar_count].function = 0; bar_req[*bar_count].bar.pos = PCI_BAR(0); bar_req[*bar_count].bar.io = FALSE; bar_req[*bar_count].bar.prefetch = FALSE; bar_req[*bar_count].bar.start = 0; bar_req[*bar_count].bar.size = sys_ramsize / 2; bar_req[*bar_count + 1].vendorid = PCI_VENDID_ALGORITHMICS; bar_req[*bar_count + 1].devid = PCI_DEVID_BONITO64; bar_req[*bar_count + 1].function = 0; bar_req[*bar_count + 1].bar.pos = PCI_BAR(1); bar_req[*bar_count + 1].bar.io = FALSE; bar_req[*bar_count + 1].bar.prefetch = FALSE; bar_req[*bar_count + 1].bar.start = sys_ramsize / 2; bar_req[*bar_count + 1].bar.size = sys_ramsize / 2; (*bar_count) += 2; return OK; case MIPS_REVISION_CORID_QED_RM5261 : case MIPS_REVISION_CORID_CORE_LV : case MIPS_REVISION_CORID_CORE_FPGA : case MIPS_REVISION_CORID_CORE_FPGAr2 : /**** Galileo GT64120 system controller ****/ DISP_STR( "GT64120" ); /* Setup known device data */ controller->vendorid = PCI_VENDID_GALILEO; controller->devid = PCI_DEVID_64120; controller->function = 0; controller->vendor = name_galileo; controller->device = name_64120; /* Determine SDRAM banks */ gt_calc_range( GT_SCS10LD_OFS, GT_SCS10HD_OFS, &scs10_start, &scs10_size ); gt_calc_range( GT_SCS32LD_OFS, GT_SCS32HD_OFS, &scs32_start, &scs32_size ); /* Configure Galileo */ config_gt64120(); if( *bar_count + 3 > max_bar_count ) return ERROR_PCI_STRUCTURE; /* BAR requirements due to Galileo system controller */ bar_req[*bar_count].vendorid = PCI_VENDID_GALILEO; bar_req[*bar_count].devid = PCI_DEVID_64120; bar_req[*bar_count].function = 0; bar_req[*bar_count].bar.pos = GT_BAR_SCS10_POS; bar_req[*bar_count].bar.io = FALSE; bar_req[*bar_count].bar.prefetch = FALSE; bar_req[*bar_count].bar.start = scs10_start; bar_req[*bar_count].bar.size = scs10_size; bar_req[*bar_count + 1].vendorid = PCI_VENDID_GALILEO; bar_req[*bar_count + 1].devid = PCI_DEVID_64120; bar_req[*bar_count + 1].function = 0; bar_req[*bar_count + 1].bar.pos = GT_BAR_SCS32_POS; bar_req[*bar_count + 1].bar.io = FALSE; bar_req[*bar_count + 1].bar.prefetch = FALSE; bar_req[*bar_count + 1].bar.start = scs32_start; bar_req[*bar_count + 1].bar.size = scs32_size; /* Special requirement due to the fact that the Galileo * will not let us disable the internal registers memory * mapped BAR. * We map it where is does no harm (no overlap). */ bar_req[*bar_count + 2].vendorid = PCI_VENDID_GALILEO; bar_req[*bar_count + 2].devid = PCI_DEVID_64120; bar_req[*bar_count + 2].function = 0; bar_req[*bar_count + 2].bar.pos = GT_BAR_INTERNAL_MEM_POS; bar_req[*bar_count + 2].bar.io = FALSE; bar_req[*bar_count + 2].bar.prefetch = FALSE; bar_req[*bar_count + 2].bar.start = scs32_start + scs32_size; bar_req[*bar_count + 2].bar.size = 16; (*bar_count) += 3; return OK; /* Add new core cards here */ default : /* Should never happen */ return ERROR_PCI_STRUCTURE; }}/************************************************************************ * * arch_pci_config_access * Description : * ------------- * * PCI configuration cycle (read or write) * * Return values : * --------------- * * OK : If no error. * ERROR_PCI_ABORT : If master abort (no target) or target abort. * ************************************************************************/UINT32arch_pci_config_access( UINT32 busnum, /* PCI bus number (0 = local bus) */ UINT32 devnum, /* PCI device number */ UINT32 func, /* Function number of device */ UINT32 reg, /* Device register */ bool write, /* TRUE -> Config write, else read */ UINT8 size, /* Sizeof data (1/2/4 bytes) */ void *data ) /* write or read data */{ UINT32 intr; UINT32 data32, align, pos; UINT32 rc; /* Always perform 32 bit access */ if( size != sizeof(UINT32) ) { /* Calc 32 bit aligned word */ align = reg & ~MSK(2); /* Read word */ rc = arch_pci_config_access( busnum, devnum, func, align, FALSE, sizeof(UINT32), (void *)&data32 ); if( rc != OK ) return rc; switch( size ) { case sizeof(UINT8) : /* Calc position of byte within word * (PCI is always little endian). */ pos = (reg & MSK(2)) * 8; if( write ) { /* Modify word */ data32 &= ~(MSK(8) << pos); data32 |= *(UINT8 *)data << pos; } else { /* Calc byte */ *(UINT8 *)data = (data32 >> pos) & 0xFF; } break; case sizeof(UINT16) : /* Calc position of halfword within word * (PCI is always little endian). */ pos = (reg & (MSK(1) << 1)) * 8; if( write ) { /* Modify word */ data32 &= ~(MSK(16) << pos); data32 |= *(UINT16 *)data << pos; } else { /* Calc halfword */ *(UINT16 *)data = (data32 >> pos) & 0xFFFF; } break; default : /* Should not happen */ break; } if( write ) { /* Write the modified word */ rc = arch_pci_config_access( busnum, devnum, func, align, TRUE, sizeof(UINT32), (void *)&data32 ); } return rc; } switch( sys_corecard ) { case MIPS_REVISION_CORID_BONITO64 : case MIPS_REVISION_CORID_CORE_20K : case MIPS_REVISION_CORID_CORE_EMUL_20K : /**** Bonito64 system controller ****/ if( busnum == PCI_BUS_LOCAL ) { if ( (devnum == 0) || (devnum > PCI_DEVNUM_MAX) ) { return ERROR_PCI_ABORT; } if ( devnum == PCI_IDSEL2DEVNUM(ATLAS_IDSEL_CORE) ) { /* Access is to BONITO64 itself * According to Algorithmics: Don't loop back via PCI, * rather access Bonito's cfg registers from CPU side.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -