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

📄 pci_serv.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 5 页
字号:
//=============================================================================
//
//      pci_serv.c - Cyclone Diagnostics
//
//=============================================================================
//####COPYRIGHTBEGIN####
//                                                                          
// -------------------------------------------                              
// The contents of this file are subject to the Red Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this file except in         
// compliance with the License.  You may obtain a copy of the License at    
// http://www.redhat.com/                                                   
//                                                                          
// Software distributed under the License is distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
// License for the specific language governing rights and limitations under 
// the License.                                                             
//                                                                          
// The Original Code is eCos - Embedded Configurable Operating System,      
// released September 30, 1998.                                             
//                                                                          
// The Initial Developer of the Original Code is Red Hat.                   
// Portions created by Red Hat are                                          
// Copyright (C) 2001 Red Hat, Inc.                             
// All Rights Reserved.                                                     
// -------------------------------------------                              
//                                                                          
//####COPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
// Contributors:
// Date:        2001-01-25
// Purpose:     
// Description: 
//
//####DESCRIPTIONEND####
//
//===========================================================================*/

/********************************************************************************/
/* PCI_SERV.C - PCI driver for IQ80310									        */
/*																			    */			
/* History:                                                                     */
/*  15sep00 ejb Ported to Cygmon on IQ80310									    */
/*  18dec00 snc                                                                 */
/********************************************************************************/
#include "iq80310.h"
#include "pci_bios.h"



#undef  DEBUG_PCI

#define	IB_MA_ERROR	0x2000

/*==========================================================================*/
/* Globals                                                                  */
/*==========================================================================*/
ULONG	memspace_ptr[NUM_PCI_BUSES];
ULONG	iospace_ptr[NUM_PCI_BUSES];
ULONG	memspace_limit[NUM_PCI_BUSES];
ULONG	iospace_limit[NUM_PCI_BUSES];
UINT	nextbus;
UINT	secondary_busno = SECONDARY_BUS_NUM;
UINT	primary_busno = PRIMARY_BUS_NUM;
UINT    lastbus;
unsigned long dram_size;		/* global storing the size of DRAM */	
int bus0_lastbus;        /* last secondary bus number behind bus 0 */
int bus1_lastbus;        /* last secondary bus number behind bus 1 */

int nmi_verbose;	/* global flag to indicate whether or not PCI Error messages should be
					   printed.  This flag is used to prevent a painful deluge of messages
					   when performing PCI configuration reads/writes to possibly non-existant
					   devices. */

int pci_config_error = FALSE; /* becomes TRUE if an NMI interrupt occurs due to a PCI config cycle */

#define PRINT_ON()	nmi_verbose = TRUE
#define PRINT_OFF() nmi_verbose = FALSE

/*==========================================================================*/
/* Function prototypes                                                      */
/*==========================================================================*/
static void sys_pci_bus_init (UINT bus, UINT root_bus, PCI_DATA* pci_data);
void print_config_space (int bus, int device, int function);


void show_pci(void);
void show_bus(int);
void init_312_pci(void);

typedef int (*FUNCPTR) ();	   /* ptr to function returning int */

typedef struct
{
	FUNCPTR	handler;
	int		arg;
	int		bus;
	int		device;
} INT_HANDLER;

#define NUM_PCI_XINTS		4		/* XINT0 - XINT3 */
#define MAX_PCI_HANDLERS	8		/* maximum handlers per PCI Xint */

/* Table where the interrupt handler addresses are stored. */
INT_HANDLER pci_int_handlers[4][MAX_PCI_HANDLERS];


extern void printf();
extern void hexIn();

extern int pci_config_cycle;

extern void _enableFiqIrq();	 
extern void config_ints(void);	/* configure interrupts */

/*********************************************************************************
* pci_to_xint - convert a PCI device number and Interrupt line to an 80312 XINT
*
* This function converts a PCI slot number (0 - 7) and an Interrupt line
* (INTA - INTD) to a i960 processor XINT number (0 - 3)
*
* RETURNS: OK or ERROR if arguments are invalid
*
*/
STATUS pci_to_xint(int device, int intpin, int *xint)
{
	int device_base;	/* all devices mod 4 follow same interrupt mapping scheme */

    /* check validity of arguments */
	if ((intpin < INTA) || (intpin > INTD) || (device > 31))
		return (ERROR);

	device_base = device % 4;

	/* interrupt mapping scheme as per PCI-to-PCI Bridge Specification */
	switch (device_base)
    {
	case 0:
	    switch (intpin)
		{
		case INTA:
			*xint = XINT0;
			break;
		case INTB:
			*xint = XINT1;
			break;
		case INTC:
			*xint = XINT2;
			break;
		case INTD:
			*xint = XINT3;
			break;
		}
		break;
	case 1:
	    switch (intpin)
		{
	   	case INTA:
			*xint = XINT1;
			break;
		case INTB:
			*xint = XINT2;
			break;
		case INTC:
			*xint = XINT3;
			break;
		case INTD:
			*xint = XINT0;
			break;
		}
	    break;
	case 2:
	    switch (intpin)
		{
		case INTA:
			*xint = XINT2;
			break;
		case INTB:
			*xint = XINT3;
			break;
		case INTC:
			*xint = XINT0;
			break;
		case INTD:
			*xint = XINT1;
			break;
		}
		break;
	case 3:
	    switch (intpin)
		{
		case INTA:
			*xint = XINT3;
			break;
		case INTB:
			*xint = XINT0;
			break;
		case INTC:
			*xint = XINT1;
			break;
		case INTD:
			*xint = XINT2;
			break;
		}
	    break;
    }
	return (OK);
}


/******************************************************************************
*
* Checks to see if the "bus" argument identifies a PCI bus which is located 
* off of the Primary PCI bus of the board.
*/
int off_ppci_bus (int busno)
{
	if (busno == primary_busno) 
		return (TRUE);
	else if (busno == secondary_busno) 
		return (FALSE);
	else if (busno <= bus0_lastbus)
		return (TRUE);
	else
		return (FALSE);
}

static unsigned old_abort_vec;

/*************************************************************************
* pci_cycle_cleanup - cleanup after a PCI configuration cycle
*
* This function will clear the various PCI abort bits if a configuration
* cycle to a non-existant device is attempted. Covers both ATU and
* bridge functions.
*
* RETURNS: OK if no PCI abort bits were set or ERROR if abort bits were 
*          detected.
*/
static int pci_cycle_cleanup (ULONG busno)
{
  UINT16 *pci_status_reg16;
  UINT16 pci_status16;
  UINT32 *pci_status_reg;
  UINT32 pci_status;
  UINT8 status;
  UINT8 bus_select = 0;		/* quiet the compiler warning */
    
  pci_status16 = 0;
  pci_status = 0;
  status = 0;

	/* this if-else structure must be done in the correct order to
       ensure that the correct ATU is chosen */
	if (busno == primary_busno) 
		bus_select = PRIMARY_BUS_NUM;
	else if (busno == secondary_busno) 
		bus_select = SECONDARY_BUS_NUM;
	else if (busno <= bus0_lastbus)
		bus_select = PRIMARY_BUS_NUM;
    else if (busno <= bus1_lastbus)
		bus_select = SECONDARY_BUS_NUM;
	else return (ERROR);


  /* Read/clear bus status and bus interrupt status registers */

  switch (bus_select) 	
  {
		case 0:  /* Primary Bus */
			pci_status_reg16 = (UINT16 *) PATUSR_ADDR;
			pci_status16 = *pci_status_reg16;
		
			if ((pci_status16 & 0xF900) == 0) goto skip1;

			#ifdef DEBUG_PCI
				if (pci_status16 &  PARITY_ERROR)	printf("Parity Error Detected - Primary Bus - ATU\n");
				if (pci_status16 &  SERR_ERROR)		printf("P_SERR# Asserted - Primary Bus - ATU\n");
				if (pci_status16 &  MASTER_ABORT)	printf("Master Abort Detected - Primary Bus - ATU\n");
				if (pci_status16 &  TARGET_ABORT_M) printf("Target Abort Detected - Primary Bus - ATU is master\n");
				if (pci_status16 &  TARGET_ABORT_T) printf("Target Abort Detected - Primary Bus - ATU is target\n");
				if (pci_status16 &  MASTER_PAR_ERR) printf("Master Parity Error - Primary Bus - ATU\n");
			#endif
			status = 1;
			pci_status16 &= 0xF980;
			*pci_status_reg16 = pci_status16;
		
skip1:
			pci_status_reg16 = (UINT16 *) PSR_ADDR;
			pci_status16 = *pci_status_reg16;
	
			if ((pci_status16 & 0xF900) == 0) goto skip2;

			#ifdef DEBUG_PCI
				if (pci_status16 &  PARITY_ERROR)	printf("Parity Error Detected - Primary Bus - Bridge\n");
				if (pci_status16 &  SERR_ERROR)		printf("P_SERR# Asserted - Primary Bus - Bridge\n");
				if (pci_status16 &  MASTER_ABORT)	printf("Master Abort Detected - Primary Bus - Bridge\n");
				if (pci_status16 &  TARGET_ABORT_M) printf("Target Abort Detected - Primary Bus - Bridge is master\n");
				if (pci_status16 &  TARGET_ABORT_T) printf("Target Abort Detected - Primary Bus - Bridge is target\n");
				if (pci_status16 &  MASTER_PAR_ERR) printf("Master Parity Error - Primary Bus - Bridge\n");
			#endif
			status = 1;
			pci_status16 &= 0xF980;
			*pci_status_reg16 = pci_status16;
		
skip2:

			pci_status_reg = (UINT32 *) PATUISR_ADDR;
			pci_status = *pci_status_reg;
	
			if ((pci_status & 0x0000079F) == 0) goto skip3;

			#ifdef DEBUG_PCI
				if (pci_status &  ATU_BIST_ERR) printf("ATU BIST Error - Primary Bus\n");
				if (pci_status &  IB_MA_ERROR)	printf("Internal Bus Master Abort - Primary Bus - ATU\n");
			#endif
			status = 1;
			pci_status &= 0x0000079f;
			*pci_status_reg = pci_status;
skip3:

			pci_status_reg = (UINT32 *) PBISR_ADDR;
			pci_status = *pci_status_reg;
			
			if ((pci_status & 0x0000003F) == 0) goto skip4;

			#ifdef DEBUG_PCI
				if (pci_status16 &  BRIDGE_PERR)	printf("Parity Error Detected - Primary Bus - Bridge\n");
				if (pci_status16 &  SERR_ERROR)		printf("P_SERR# Asserted - Primary Bus - Bridge\n");
				if (pci_status16 &  MASTER_ABORT)	printf("Master Abort Detected - Primary Bus - Bridge\n");
				if (pci_status16 &  TARGET_ABORT_M) printf("Target Abort Detected - Primary Bus - Bridge is master\n");
				if (pci_status16 &  TARGET_ABORT_T) printf("Target Abort Detected - Primary Bus - Bridge is target\n");
				if (pci_status16 &  MASTER_PAR_ERR) printf("Master Parity Error - Primary Bus - Bridge\n");		
			#endif
			status = 1;
			pci_status &= 0x0000003F;
			*pci_status_reg = pci_status;
skip4:
			break;


		case 1:   /* Secondary Bus */	
			pci_status_reg16 = (UINT16 *) SATUSR_ADDR;
			pci_status16 = *pci_status_reg16;

			if ((pci_status16 & 0xF900) == 0) goto skip5;
			#ifdef DEBUG_PCI
				if (pci_status16 &  PARITY_ERROR)	printf("Parity Error Detected - Secondary Bus - ATU\n");
				if (pci_status16 &  SERR_ERROR)		printf("S_SERR# Asserted - Secondary Bus - ATU\n");
				if (pci_status16 &  MASTER_ABORT)	printf("Master Abort Detected - Secondary Bus - ATU\n");
				if (pci_status16 &  TARGET_ABORT_M) printf("Target Abort Detected - Secondary Bus - ATU is master\n");
				if (pci_status16 &  TARGET_ABORT_T) printf("Target Abort Detected - Secondary Bus - ATU is target\n");
				if (pci_status16 &  MASTER_PAR_ERR) printf("Master Parity Error - Secondary Bus - ATU\n");
			#endif	
			status = 1;
			pci_status16 &= 0xF900;
			*pci_status_reg16 = pci_status16;
skip5:
			pci_status_reg16 = (UINT16 *) SSR_ADDR;
			pci_status16 = *pci_status_reg16;

			if ((pci_status16 & 0xF900) == 0) goto skip6;

			#ifdef DEBUG_PCI
				if (pci_status16 &  PARITY_ERROR)	printf("Parity Error Detected - Secondary Bus - Bridge\n");
				if (pci_status16 &  SERR_ERROR)		printf("S_SERR# Asserted - Secondary Bus - Bridge\n");
				if (pci_status16 &  MASTER_ABORT)	printf("Master Abort Detected - Secondary Bus - Bridge\n");
				if (pci_status16 &  TARGET_ABORT_M) printf("Target Abort Detected - Secondary Bus - Bridge is master\n");
				if (pci_status16 &  TARGET_ABORT_T) printf("Target Abort Detected - Secondary Bus - Bridge is target\n");
				if (pci_status16 &  MASTER_PAR_ERR) printf("Master Parity Error - Secondary Bus - Bridge\n");
			#endif	
			status = 1;
			pci_status16 &= 0xF980;
			*pci_status_reg16 = pci_status16;

skip6:
			pci_status_reg = (UINT32 *) SATUISR_ADDR;
			pci_status = *pci_status_reg;

			if ((pci_status & 0x0000069F) == 0) goto skip7;

			#ifdef DEBUG_PCI
				if (pci_status &  IB_MA_ERROR) printf("Internal Bus Master Abort - Secondary Bus - ATU\n");
			#endif
			status = 1;
			pci_status &= 0x0000069F;
			*pci_status_reg = pci_status;
skip7:
			break;

		default: return (ERROR);
  }

⌨️ 快捷键说明

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