| /************************************************** |
| * |
| * copyright @ motorola, 1999 |
| * |
| *************************************************/ |
| #include <mpc824x.h> |
| #include <common.h> |
| #include "epic.h" |
| |
| |
| #define PRINT(format, args...) printf(format , ## args) |
| |
| typedef void (*VOIDFUNCPTR) (void); /* ptr to function returning void */ |
| struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */ |
| { |
| { EPIC_EX_INT0_VEC_REG, "External Direct/Serial Source 0"}, |
| { EPIC_EX_INT1_VEC_REG, "External Direct/Serial Source 1"}, |
| { EPIC_EX_INT2_VEC_REG, "External Direct/Serial Source 2"}, |
| { EPIC_EX_INT3_VEC_REG, "External Direct/Serial Source 3"}, |
| { EPIC_EX_INT4_VEC_REG, "External Direct/Serial Source 4"}, |
| |
| { EPIC_SR_INT5_VEC_REG, "External Serial Source 5"}, |
| { EPIC_SR_INT6_VEC_REG, "External Serial Source 6"}, |
| { EPIC_SR_INT7_VEC_REG, "External Serial Source 7"}, |
| { EPIC_SR_INT8_VEC_REG, "External Serial Source 8"}, |
| { EPIC_SR_INT9_VEC_REG, "External Serial Source 9"}, |
| { EPIC_SR_INT10_VEC_REG, "External Serial Source 10"}, |
| { EPIC_SR_INT11_VEC_REG, "External Serial Source 11"}, |
| { EPIC_SR_INT12_VEC_REG, "External Serial Source 12"}, |
| { EPIC_SR_INT13_VEC_REG, "External Serial Source 13"}, |
| { EPIC_SR_INT14_VEC_REG, "External Serial Source 14"}, |
| { EPIC_SR_INT15_VEC_REG, "External Serial Source 15"}, |
| |
| { EPIC_I2C_INT_VEC_REG, "Internal I2C Source"}, |
| { EPIC_DMA0_INT_VEC_REG, "Internal DMA0 Source"}, |
| { EPIC_DMA1_INT_VEC_REG, "Internal DMA1 Source"}, |
| { EPIC_MSG_INT_VEC_REG, "Internal Message Source"}, |
| }; |
| |
| VOIDFUNCPTR intVecTbl[MAXVEC]; /* Interrupt vector table */ |
| |
| |
| /**************************************************************************** |
| * epicInit - Initialize the EPIC registers |
| * |
| * This routine resets the Global Configuration Register, thus it: |
| * - Disables all interrupts |
| * - Sets epic registers to reset values |
| * - Sets the value of the Processor Current Task Priority to the |
| * highest priority (0xF). |
| * epicInit then sets the EPIC operation mode to Mixed Mode (vs. Pass |
| * Through or 8259 compatible mode). |
| * |
| * If IRQType (input) is Direct IRQs: |
| * - IRQType is written to the SIE bit of the EPIC Interrupt |
| * Configuration register (ICR). |
| * - clkRatio is ignored. |
| * If IRQType is Serial IRQs: |
| * - both IRQType and clkRatio will be written to the ICR register |
| */ |
| |
| void epicInit |
| ( |
| unsigned int IRQType, /* Direct or Serial */ |
| unsigned int clkRatio /* Clk Ratio for Serial IRQs */ |
| ) |
| { |
| ULONG tmp; |
| |
| tmp = sysEUMBBARRead(EPIC_GLOBAL_REG); |
| tmp |= 0xa0000000; /* Set the Global Conf. register */ |
| sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp); |
| /* |
| * Wait for EPIC to reset - CLH |
| */ |
| while( (sysEUMBBARRead(EPIC_GLOBAL_REG) & 0x80000000) == 1); |
| sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000); |
| tmp = sysEUMBBARRead(EPIC_INT_CONF_REG); /* Read interrupt conf. reg */ |
| |
| if (IRQType == EPIC_DIRECT_IRQ) /* direct mode */ |
| sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff); |
| else /* Serial mode */ |
| { |
| tmp = (clkRatio << 28) | 0x08000000; /* Set clock ratio */ |
| sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp); |
| } |
| |
| while (epicIntAck() != 0xff) /* Clear all pending interrupts */ |
| epicEOI(); |
| } |
| |
| /**************************************************************************** |
| * epicIntEnable - Enable an interrupt source |
| * |
| * This routine clears the mask bit of an external, an internal or |
| * a Timer register to enable the interrupt. |
| * |
| * RETURNS: None |
| */ |
| void epicIntEnable(int intVec) |
| { |
| ULONG tmp; |
| ULONG srAddr; |
| |
| srAddr = SrcVecTable[intVec].srcAddr; /* Retrieve src Vec/Prio register */ |
| tmp = sysEUMBBARRead(srAddr); |
| tmp &= ~EPIC_VEC_PRI_MASK; /* Clear the mask bit */ |
| tmp |= (EPIC_VEC_PRI_DFLT_PRI << 16); /* Set priority to Default - CLH */ |
| tmp |= intVec; /* Set Vector number */ |
| sysEUMBBARWrite(srAddr, tmp); |
| |
| return; |
| } |
| |
| /**************************************************************************** |
| * epicIntDisable - Disable an interrupt source |
| * |
| * This routine sets the mask bit of an external, an internal or |
| * a Timer register to disable the interrupt. |
| * |
| * RETURNS: OK or ERROR |
| * |
| */ |
| |
| void epicIntDisable |
| ( |
| int intVec /* Interrupt vector number */ |
| ) |
| { |
| |
| ULONG tmp, srAddr; |
| |
| srAddr = SrcVecTable[intVec].srcAddr; |
| tmp = sysEUMBBARRead(srAddr); |
| tmp |= 0x80000000; /* Set the mask bit */ |
| sysEUMBBARWrite(srAddr, tmp); |
| return; |
| } |
| |
| /**************************************************************************** |
| * epicIntSourceConfig - Set properties of an interrupt source |
| * |
| * This function sets interrupt properites (Polarity, Sense, Interrupt |
| * Prority, and Interrupt Vector) of an Interrupt Source. The properties |
| * can be set when the current source is not in-request or in-service, |
| * which is determined by the Activity bit. This routine return ERROR |
| * if the the Activity bit is 1 (in-request or in-service). |
| * |
| * This function assumes that the Source Vector/Priority register (input) |
| * is a valid address. |
| * |
| * RETURNS: OK or ERROR |
| */ |
| |
| int epicIntSourceConfig |
| ( |
| int Vect, /* interrupt source vector number */ |
| int Polarity, /* interrupt source polarity */ |
| int Sense, /* interrupt source Sense */ |
| int Prio /* interrupt source priority */ |
| ) |
| |
| { |
| ULONG tmp, newVal; |
| ULONG actBit, srAddr; |
| |
| srAddr = SrcVecTable[Vect].srcAddr; |
| tmp = sysEUMBBARRead(srAddr); |
| actBit = (tmp & 40000000) >> 30; /* retrieve activity bit - bit 30 */ |
| if (actBit == 1) |
| return ERROR; |
| |
| tmp &= 0xff30ff00; /* Erase previously set P,S,Prio,Vector bits */ |
| newVal = (Polarity << 23) | (Sense << 22) | (Prio << 16) | Vect; |
| sysEUMBBARWrite(srAddr, tmp | newVal ); |
| return (OK); |
| } |
| |
| /**************************************************************************** |
| * epicIntAck - acknowledge an interrupt |
| * |
| * This function reads the Interrupt acknowldge register and return |
| * the vector number of the highest pending interrupt. |
| * |
| * RETURNS: Interrupt Vector number. |
| */ |
| |
| unsigned int epicIntAck(void) |
| { |
| return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG )); |
| } |
| |
| /**************************************************************************** |
| * epicEOI - signal an end of interrupt |
| * |
| * This function writes 0x0 to the EOI register to signal end of interrupt. |
| * It is usually called after an interrupt routine is served. |
| * |
| * RETURNS: None |
| */ |
| |
| void epicEOI(void) |
| { |
| sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0); |
| } |
| |
| /**************************************************************************** |
| * epicCurTaskPrioSet - sets the priority of the Processor Current Task |
| * |
| * This function should be called after epicInit() to lower the priority |
| * of the processor current task. |
| * |
| * RETURNS: OK or ERROR |
| */ |
| |
| int epicCurTaskPrioSet |
| ( |
| int prioNum /* New priority value */ |
| ) |
| { |
| |
| if ( (prioNum < 0) || (prioNum > 0xF)) |
| return ERROR; |
| sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum); |
| return OK; |
| } |
| |
| |
| /************************************************************************ |
| * function: epicIntTaskGet |
| * |
| * description: Get value of processor current interrupt task priority register |
| * |
| * note: |
| ***********************************************************************/ |
| unsigned char epicIntTaskGet() |
| { |
| /* get the interrupt task priority register */ |
| ULONG reg; |
| unsigned char rec; |
| |
| reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG ); |
| rec = ( reg & 0x0F ); |
| return rec; |
| } |
| |
| |
| /************************************************************** |
| * function: epicISR |
| * |
| * description: EPIC service routine called by the core exception |
| * at 0x500 |
| * |
| * note: |
| **************************************************************/ |
| unsigned int epicISR(void) |
| { |
| return 0; |
| } |
| |
| |
| /************************************************************ |
| * function: epicModeGet |
| * |
| * description: query EPIC mode, return 0 if pass through mode |
| * return 1 if mixed mode |
| * |
| * note: |
| *************************************************************/ |
| unsigned int epicModeGet(void) |
| { |
| ULONG val; |
| |
| val = sysEUMBBARRead( EPIC_GLOBAL_REG ); |
| return (( val & 0x20000000 ) >> 29); |
| } |
| |
| |
| /********************************************* |
| * function: epicConfigGet |
| * |
| * description: Get the EPIC interrupt Configuration |
| * return 0 if not error, otherwise return 1 |
| * |
| * note: |
| ********************************************/ |
| void epicConfigGet( unsigned int *clkRatio, unsigned int *serEnable) |
| { |
| ULONG val; |
| |
| val = sysEUMBBARRead( EPIC_INT_CONF_REG ); |
| *clkRatio = ( val & 0x70000000 ) >> 28; |
| *serEnable = ( val & 0x8000000 ) >> 27; |
| } |
| |
| |
| /******************************************************************* |
| * sysEUMBBARRead - Read a 32-bit EUMBBAR register |
| * |
| * This routine reads the content of a register in the Embedded |
| * Utilities Memory Block, and swaps to big endian before returning |
| * the value. |
| * |
| * RETURNS: The content of the specified EUMBBAR register. |
| */ |
| |
| ULONG sysEUMBBARRead |
| ( |
| ULONG regNum |
| ) |
| { |
| ULONG temp; |
| |
| temp = *(ULONG *) (CFG_EUMB_ADDR + regNum); |
| return ( LONGSWAP(temp)); |
| } |
| |
| /******************************************************************* |
| * sysEUMBBARWrite - Write a 32-bit EUMBBAR register |
| * |
| * This routine swaps the value to little endian then writes it to |
| * a register in the Embedded Utilities Memory Block address space. |
| * |
| * RETURNS: N/A |
| */ |
| |
| void sysEUMBBARWrite |
| ( |
| ULONG regNum, /* EUMBBAR register address */ |
| ULONG regVal /* Value to be written */ |
| ) |
| { |
| |
| *(ULONG *) (CFG_EUMB_ADDR + regNum) = LONGSWAP(regVal); |
| return ; |
| } |
| |
| |
| /******************************************************** |
| * function: epicVendorId |
| * |
| * description: return the EPIC Vendor Identification |
| * register: |
| * |
| * siliccon version, device id, and vendor id |
| * |
| * note: |
| ********************************************************/ |
| void epicVendorId |
| ( |
| unsigned int *step, |
| unsigned int *devId, |
| unsigned int *venId |
| ) |
| { |
| ULONG val; |
| val = sysEUMBBARRead( EPIC_VENDOR_ID_REG ); |
| *step = ( val & 0x00FF0000 ) >> 16; |
| *devId = ( val & 0x0000FF00 ) >> 8; |
| *venId = ( val & 0x000000FF ); |
| } |
| |
| /************************************************** |
| * function: epicFeatures |
| * |
| * description: return the number of IRQ supported, |
| * number of CPU, and the version of the |
| * OpenEPIC |
| * |
| * note: |
| *************************************************/ |
| void epicFeatures |
| ( |
| unsigned int *noIRQs, |
| unsigned int *noCPUs, |
| unsigned int *verId |
| ) |
| { |
| ULONG val; |
| |
| val = sysEUMBBARRead( EPIC_FEATURES_REG ); |
| *noIRQs = ( val & 0x07FF0000 ) >> 16; |
| *noCPUs = ( val & 0x00001F00 ) >> 8; |
| *verId = ( val & 0x000000FF ); |
| } |
| |
| |
| /********************************************************* |
| * function: epciTmFrequncySet |
| * |
| * description: Set the timer frequency reporting register |
| ********************************************************/ |
| void epicTmFrequencySet( unsigned int frq ) |
| { |
| sysEUMBBARWrite(EPIC_TM_FREQ_REG, frq); |
| } |
| |
| /******************************************************* |
| * function: epicTmFrequncyGet |
| * |
| * description: Get the current value of the Timer Frequency |
| * Reporting register |
| * |
| ******************************************************/ |
| unsigned int epicTmFrequencyGet(void) |
| { |
| return( sysEUMBBARRead(EPIC_TM_FREQ_REG)) ; |
| } |
| |
| |
| /**************************************************** |
| * function: epicTmBaseSet |
| * |
| * description: Set the #n global timer base count register |
| * return 0 if no error, otherwise return 1. |
| * |
| * note: |
| ****************************************************/ |
| unsigned int epicTmBaseSet |
| ( |
| ULONG srcAddr, /* Address of the Timer Base register */ |
| unsigned int cnt, /* Base count */ |
| unsigned int inhibit /* 1 - count inhibit */ |
| ) |
| { |
| |
| unsigned int val = 0x80000000; |
| /* First inhibit counting the timer */ |
| sysEUMBBARWrite(srcAddr, val) ; |
| |
| /* set the new value */ |
| val = (cnt & 0x7fffffff) | ((inhibit & 0x1) << 31); |
| sysEUMBBARWrite(srcAddr, val) ; |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * function: epicTmBaseGet |
| * |
| * description: Get the current value of the global timer base count register |
| * return 0 if no error, otherwise return 1. |
| * |
| * note: |
| ***********************************************************************/ |
| unsigned int epicTmBaseGet( ULONG srcAddr, unsigned int *val ) |
| { |
| *val = sysEUMBBARRead( srcAddr ); |
| *val = *val & 0x7fffffff; |
| return 0; |
| } |
| |
| /*********************************************************** |
| * function: epicTmCountGet |
| * |
| * description: Get the value of a given global timer |
| * current count register |
| * return 0 if no error, otherwise return 1 |
| * note: |
| **********************************************************/ |
| unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val ) |
| { |
| *val = sysEUMBBARRead( srcAddr ); |
| *val = *val & 0x7fffffff; |
| return 0; |
| } |
| |
| |
| /*********************************************************** |
| * function: epicTmInhibit |
| * |
| * description: Stop counting of a given global timer |
| * return 0 if no error, otherwise return 1 |
| * |
| * note: |
| ***********************************************************/ |
| unsigned int epicTmInhibit( unsigned int srcAddr ) |
| { |
| ULONG val; |
| |
| val = sysEUMBBARRead( srcAddr ); |
| val |= 0x80000000; |
| sysEUMBBARWrite( srcAddr, val ); |
| return 0; |
| } |
| |
| /****************************************************************** |
| * function: epicTmEnable |
| * |
| * description: Enable counting of a given global timer |
| * return 0 if no error, otherwise return 1 |
| * |
| * note: |
| *****************************************************************/ |
| unsigned int epicTmEnable( ULONG srcAddr ) |
| { |
| ULONG val; |
| |
| val = sysEUMBBARRead( srcAddr ); |
| val &= 0x7fffffff; |
| sysEUMBBARWrite( srcAddr, val ); |
| return 0; |
| } |
| |
| void epicSourcePrint(int Vect) |
| { |
| ULONG srcVal; |
| |
| srcVal = sysEUMBBARRead(SrcVecTable[Vect].srcAddr); |
| PRINT("%s\n", SrcVecTable[Vect].srcName); |
| PRINT("Address = 0x%lx\n", SrcVecTable[Vect].srcAddr); |
| PRINT("Vector = %ld\n", (srcVal & 0x000000FF) ); |
| PRINT("Mask = %ld\n", srcVal >> 31); |
| PRINT("Activitiy = %ld\n", (srcVal & 40000000) >> 30); |
| PRINT("Polarity = %ld\n", (srcVal & 0x00800000) >> 23); |
| PRINT("Sense = %ld\n", (srcVal & 0x00400000) >> 22); |
| PRINT("Priority = %ld\n", (srcVal & 0x000F0000) >> 16); |
| } |