📄 pci_serv.c
字号:
//=============================================================================//// 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); } if (pci_config_error) /* check to see if the NMI handler during the config cycle */ status = 1; pci_config_cycle = 0; /* turn on exception handling after pci config cycle */ if (old_abort_vec) { ((volatile unsigned *)0x20)[4] = old_abort_vec; old_abort_vec = 0; _flushICache();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -