sysLib.c
资源名称:idt438.rar [点击查看]
上传用户:yingyi0918
上传日期:2022-06-26
资源大小:214k
文件大小:60k
源码类别:
VxWorks
开发平台:
C/C++
- /* sysLib.c - IDT 79PMC438 system-dependent routines */
- /* Copyright 1984-2002 Wind River Systems, Inc. */
- #include "copyright_wrs.h"
- /*
- * This file has been developed or significantly modified by the
- * MIPS Center of Excellence Dedicated Engineering Staff.
- * This notice is as per the MIPS Center of Excellence Master Partner
- * Agreement, do not remove this notice without checking first with
- * WR/Platforms MIPS Center of Excellence engineering management.
- */
- /*
- modification history
- --------------------
- 01a,02jun02,krao adapted to 79PMC438 board
- */
- /*
- DESCRIPTION
- This library provides board-specific routines for the IDT79PMC438 board.
- INCLUDE FILES: sysLib.h
- SEE ALSO:
- .pG "Configuration"
- */
- /* includes */
- #include "vxWorks.h"
- #include "vxLib.h"
- #include "config.h"
- #include "version.h"
- #include "arch/mips/cacheMipsLib.h"
- #include "arch/mips/ivMips.h"
- #include "arch/mips/esfMips.h"
- #include "sysLib.h"
- #include "string.h"
- #include "intLib.h"
- #include "logLib.h"
- #include "rc32438.h"
- #include "sysI2CDrv.h"
- #ifdef BROADCOM_BSP
- #include "netinet/in.h" /* for sysBindFix() */
- #include "sockLib.h" /* for sysBindFix() */
- #include "symLib.h"
- #ifdef INCLUDE_PCI
- int sysPCIBridgeProbe(int instance,
- int primary,
- int secondary,
- int subordinate);
- #endif
- #endif /*!BROADCOM_BSP */
- #ifdef INCLUDE_IDT_END
- #include "end.h"
- #include "netBufLib.h"
- #include "idt32438End.h"
- #endif
- /* externs */
- IMPORT void sys557PciInit (void);
- IMPORT void sysWbFlush ();
- IMPORT ULONG taskSRInit ();
- IMPORT void sysClearTlbEntry ();
- IMPORT int sysCompareSet ();
- IMPORT int sysCompareGet ();
- IMPORT int sysPridGet ();
- IMPORT int sysCountGet ();
- IMPORT int sysCountSet ();
- IMPORT int sysConfig1Get ();
- IMPORT void sysPciBusErrEnable ();
- IMPORT void sysPciBusErrDisable ();
- IMPORT void sysRc32438ClkEnable ();
- IMPORT void sysRc32438ClkDisable ();
- IMPORT UINT8 ffsMsbTbl[]; /* Msb high interrupt hash table */
- IMPORT UINT8 ffsLsbTbl[]; /* Lsb high interrupt hash table */
- IMPORT int printf (const char *, ...);
- IMPORT int isprint (char);
- /* cache initialization */
- IMPORT STATUS cache4kcLibInit(CACHE_MODE, CACHE_MODE,
- UINT32, UINT32, UINT32, UINT32);
- /*defines */
- #define WAIT(x) { volatile int iCount=0; while (++iCount < (x)) ; }
- /*
- * Override max # PCI buses to optimize pciFindDevice
- * and PCI auto-config.
- */
- /* Timer defines */
- #define TIMER_ENABLE 1
- #define TIMER_DISABLE 0
- /*typedef */
- typedef struct priotable
- {
- ULONG intCause; /* cause of interrupt */
- ULONG bsrTableOffset; /* index to BSR table */
- ULONG statusReg; /* interrupt level */
- ULONG pad; /* pad for ease of use */
- } PRIO_TABLE;
- /*globals */
- /*
- * Interrupt demux routine for RC32438 internal devices - This must be
- * defined here even though it's not global. It's used in the
- * intPrioTable below.
- */
- LOCAL ULONG sysRc32438IntDemux (int arg);
- LOCAL ULONG sysRc32438GpioDemux (int arg);
- LOCAL BOOL sysIsPciMapped (ULONG address);
- LOCAL void sysClkInt ();
- LOCAL ULONG sysTimerIsr (int arg);
- /* GLOBAL - Timer handlers */
- FUNCPTR sysTimer0Routine = NULL;
- FUNCPTR sysTimer1Routine = NULL;
- FUNCPTR sysTimer2Routine = NULL;
- FUNCPTR sysRefreshTimerRoutine = NULL;
- FUNCPTR sysWatchdogTimerRoutine = NULL;
- FUNCPTR sysUndecodedCPUWriteRoutine = NULL;
- ULONG sysSoftCompare = 0; /* last target compare reg value */
- /*
- * intPrioTable is a board dependant structure that aids in the
- * processing of the 8 Rc32438 interrupt conditions.
- * It is used by excLib to determine the pending interrupt and
- * to call the user attached handler. The present search algorithm
- * relies on a one to one mapping of Rc32438 interrupt lines and
- * table entries.
- *
- * Each entry has 4 fields, the first (intCause) is the interrupt ID,
- * second (bsrTableOffset) is the vector number, third is unused
- * last (pad) is the multiplex field. When an interrupt is received
- * the handler maps the pending Rc32438 line to its' corresponding
- * table entry (ie. Software interrupt 0 would map to the first entry
- * in the table). At this point interrupts that are not pending are
- * enabled. Next the multiplex field is read, if it is zero, field
- * two is taken as the interrupt vector number in the BSR table,
- * otherwise it is interpreted as a demultiplex function and called
- * with field 4 passed as it's parameter. The job of the demultiplex
- * routine is to calculate the correct interrupt vector number and pass
- * it back to the handler. The handler can then call the routine the
- * user has installed in the BSR table with intVecSet, or intConnect.
- *
- * This table is critical to interrupt processing. Do not alter
- * it's contents until you understand the consequences. The routine
- * sysPrioUpdate can aid modification during runtime.
- */
- PRIO_TABLE intPrioTable[8] =
- {
- {CAUSE_SW1,(ULONG) IV_SWTRAP0_VEC, 0x0100, 0}, /* sw trap 0 */
- {CAUSE_SW2,(ULONG) IV_SWTRAP1_VEC, 0x0200, 0}, /* sw trap 1 */
- {CAUSE_IP3,(ULONG) sysTimerIsr, 0x8000, 1}, /* IRQ0 */
- {CAUSE_IP4,(ULONG) INT_VEC_GRP3, 0x0800, 0}, /* IRQ1 */
- {CAUSE_IP5,(ULONG) INT_VEC_GRP4, 0x1000, 0}, /* IRQ2 */
- {CAUSE_IP6,(ULONG) sysRc32438IntDemux, 0x2000, 1}, /* IRQ3 */
- {CAUSE_IP7,(ULONG) sysRc32438GpioDemux,0x4000, 1}, /* IRQ4 */
- {CAUSE_IP8,(ULONG) INT_VEC_GRP7, 0x0400, 0} /* IRQ5 */
- };
- /*
- * Since tying interrupt lines to the processor is board dependent sysHashOrder
- * is provided to select the prioritization of interrupt lines. Setting the
- * #define INT_PRIO_MSB to TRUE prioritizes interrupts from 7-0, 7 being
- * highest priority, 0 being lowest. Setting it to FALSE prioritizes
- * interrupts from 0-7. See idt79pmc438.h for the definition of INT_PRIO_MSB.
- */
- #if (INT_PRIO_MSB == TRUE)
- UINT8 * sysHashOrder = ffsMsbTbl; /* interrupt prio., 7 = high 0 = low */
- #else /* INT_PRIO_MSB == TRUE */
- UINT8 * sysHashOrder = ffsLsbTbl; /* interrupt prio., 0 = high 7 = low */
- #endif /* INT_PRIO_MSB == TRUE */
- /*locals */
- int sysMemTopDebug = 0;
- typedef struct dma_int_vect
- {
- void * func; /* pointer to interrupt service routine */
- void * param; /* parameter passed to interrupt service routine */
- } DMA_INT_VECT;
- LOCAL DMA_INT_VECT dmaInterruptVectors [MAX_DMA_INTRS];
- /* DMA interrupt vector table */
- volatile unsigned char *ptr;
- #if defined (AUTO_CACHE_DETECT)
- LOCAL int cacheSize[] = { 64, 128, 256, 512, 1024, 2048, 4096, 0 };
- LOCAL int cacheLineSize[] = { 0, 4, 8, 16, 32, 64, 128, 0 };
- LOCAL int cacheAssoc[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
- #endif
- LOCAL BOOL sysAuxClkRunning = FALSE; /* aux clock enabled flag */
- LOCAL BOOL sysAuxClkConnected = FALSE; /* aux clock connect flag */
- LOCAL int sysAuxClkTicksPerSecond = 100 ; /* aux timer rate */
- LOCAL int sysAuxClkArg = 0 ; /* aux clock int routine arg */
- LOCAL FUNCPTR sysAuxClkRoutine = NULL ; /* aux clock interpt routine */
- /* locals */
- LOCAL int sysClkTicksPerSecond = 100 ; /* default sys timer rate */
- LOCAL int sysClkArg = 0 ; /* clock int routine arg */
- LOCAL BOOL sysClkConnected = FALSE; /* sys clock connect flag */
- LOCAL BOOL sysClkRunning = FALSE; /* sys clock enabled flag */
- LOCAL int sysClkProcessorTicks ; /* Rc32364 clock ticks */
- LOCAL FUNCPTR sysClkRoutine = NULL ; /* clock interrupt routine */
- #ifdef INCLUDE_TIMESTAMP
- LOCAL BOOL sysTimestampRunning = FALSE; /* timestamp running flag */
- #endif /* INCLUDE_TIMESTAMP */
- /*forward declarations */
- void sysDmaIntrVectorSet (int, void (*fptr) (), void *);
- void sysDmaIntrVectorClr (int);
- LOCAL void sysDmaIntVecTblInit (void);
- LOCAL void sysDmaIsr (int parm);
- LOCAL void sysAuxClkInt ();
- LOCAL void sysDeviceInterruptDisable (void);
- /* includes (source file) */
- #include "sysDelay.c" /* uSec delay routine */
- #include "sysI2CDrv.c" /* I2C driver */
- #include "sysSerial.c" /* serial driver */
- #include "sysMipsLib.c" /* Mips common routines */
- #include "sysIo.c" /* I/O routines: must be before PCI includes */
- #ifdef INCLUDE_PCI /* PCI modules */
- #define PCI_AUTO_STATIC_LIST
- #include "pci/pciConfigLib.c"
- #include "pci/pciIntLib.c"
- #include "pci/pciAutoConfigLib.c"
- #include "sysPci.c"
- #endif /* INCLUDE_PCI */
- /*****************************************************************************
- *
- * sysModel - return the model name of the CPU board
- *
- * This routine returns the model name of the CPU board.
- *
- * RETURNS: A pointer to the string "IDT 79PMC438".
- */
- char *sysModel (void)
- {
- return ("IDT 79PMC438");
- }
- /*******************************************************************************
- *
- * sysCPUSubsystemName - return the text name of the CPU board / system.
- *
- * This routine returns the model name of either the CPU CPCI board
- * or of the embedded-CPU system board.
- *
- * RETURNS: A pointer to a text string.
- */
- char cpu_subsystem_name[64] = ""; /* Initially NULL, set to proper text */
- char *sysCPUSubsystemName (void)
- {
- /* Table of known platforms based on the IDTRC32438 CPU */
- struct revid_s {
- UINT8 revid;
- char *id_text;
- } platform_list[] = {
- /* {rev_id_value, "Text description"} */
- {0x00, "Modular IDT79PMC438"},
- {0x0, NULL}
- };
- if (!cpu_subsystem_name[0]) {
- /* UINT8 revid=sysBoardRev(); ******* FIX THIS!!! *******/
- UINT8 revid=0; /* Use this until fixed */
- struct revid_s *platform = &platform_list[0];
- while (platform->id_text != NULL) {
- if (revid == platform->revid) {
- strcpy(cpu_subsystem_name,platform->id_text);
- break;
- }
- platform++;
- }
- if (!cpu_subsystem_name[0])
- sprintf(cpu_subsystem_name,"Unknown IDTRC32438 (REVID=0x%02X)%c",revid,' ');
- }
- return cpu_subsystem_name;
- }
- /****************************************************************************
- *
- * sysBspRev - return the bsp version with the revision eg 1.1/<x>
- *
- * This function returns a pointer to a bsp version with the revision.
- * for eg. 1.1/<x>. BSP_REV is concatanated to BSP_VERSION to form the
- * BSP identification string.
- *
- * RETURNS: A pointer to the BSP version/revision string.
- */
- char * sysBspRev (void)
- {
- return (BSP_VERSION BSP_REV);
- }
- /*****************************************************************************
- *
- * sysHwInit - initialize the CPU board hardware
- *
- * This routine initializes various features of the IDT pmc438.
- * It is called from usrInit() in usrConfig.c before interrupts
- * are enabled.
- * This routine initializes and turns off the timers.
- *
- * NOTE:
- * This routine should not be called directly by the user.
- *
- * RETURNS: N/A
- */
- void sysHwInit (void)
- {
- int sr; /*status register */
- /* set default task status register for RC32438 */
- sr = RC32438_SR;
- taskSRInit (sr);
- /* init status register but leave interrupts disabled */
- intSRSet (sr & ~SR_IE);
- /* Initialize the I2C Interface */
- sysI2CInit ();
- sysDeviceInterruptDisable (); /* Disable device interrupts */
- sysPciTlbInit();
- #ifdef INCLUDE_PCI
- sysPciHostBridgeInit (); /* Configure the RC32438 PCI host bridge */
- /* Initialize PCI modules and perform automatic configuration
- * of PCI memory space.
- */
- pciConfigLibInit (PCI_MECHANISM_1, PMC438_PCI_CONFIG_ADDR,
- PMC438_PCI_CONFIG_DATA, NONE);
- pciIntLibInit ();
- sysPciAutoConfig ();
- pciConfigOutLong(0, 0, 0, PCI_CFG_BASE_ADDRESS_0, PCI_TO_CPU_MEM_BASE);
- /* Always probe for bus1: DC-21150/HB4 PCI-PCI bridge */
- #ifdef HB_RESET_HACK
- pciConfigOutByte(0,0x14,0,0x41,1); /* Reset the bridge */
- #endif
- sysPCIBridgeProbe(0, 0, 1, 1);
- #endif /* INCLUDE_PCI */
- /* Setup the serial device descriptors. */
- sysSerialHwInit ();
- sysWbFlush (); /* Flush write buffers */
- }
- /*****************************************************************************
- *
- * sysHwInit2 - additional system configuration and initialization
- *
- * This routine connects system interrupts and does any additional
- * configuration necessary.
- *
- * RETURNS: N/A
- *
- * NOMANUAL
- */
- void sysHwInit2 (void)
- {
- int parm = 0; /*temp variable */
- /* connect sys clock and aux clock interrupts */
- (void) intConnect (INUM_TO_IVEC(TMR0_INT_NUM), sysClkInt, 0);
- /* Initialize DMA interrupts & connect sysDmaIsr */
- sysDmaIntVecTblInit ();
- intConnect (INUM_TO_IVEC(INT_VEC_GRP3), sysDmaIsr, (int)parm);
- /* connect serial channel interrupts */
- sysSerialHwInit2 ();
- sysWbFlush (); /* Flush write buffers */
- /* Mask the timer and PCI interrupts */
- INTERRUPT.i2.imask &= ~INTR_MASK_TIMER0;
- GPIO.gpioilevel = 0x0;
- GPIO.gpioistat = 0x0;
- #if 0
- *(volatile unsigned char *)(0xb060000b)&=((INTR_PCI_ABCD_MASK>>24)&0xFF);
- *(volatile unsigned char *)(0xb0c00023)&=((INTR_PCI_ABCD_MASK>>24)&0xFF);
- *(volatile unsigned char *)(0xb0c00027)&=((INTR_PCI_ABCD_MASK>>24)&0xFF);
- #endif
- INTERRUPT.i6.imask &= ~INTR_PCI_ABCD_MASK;
- }
- /**************************************************************************
- *
- * sysRc32438IntDemux - Demultiplex the RC32438 interrupt
- *
- * The RC32438 ORs most of it's internal device interrupts into
- * a single interrupt request - INT3.
- *
- * This routine determines which internal RC32438 device is causing
- * the interrupt and returns the appropriate interrupt number so that
- * the ISR can be dispatched. It is used in the intPrioTable (above).
- *
- * NOTE: This routine runs in the interrupt context!
- *
- * RETURNS: Interrupt number for connected ISR
- */
- LOCAL ULONG sysRc32438IntDemux
- (
- int arg /* Argument from intPrioTable */
- )
- {
- volatile UINT32 intrStatusVal; /* Value of master interrupt pend reg */
- intrStatusVal = INTERRUPT.i5.ipend;
- if (intrStatusVal & UART1_GENERAL_INTR_MASK)
- {
- return COM2_INT_NUM;
- }
- else if (intrStatusVal & UART0_GENERAL_INTR_MASK)
- {
- return COM1_INT_NUM;
- }
- else if (intrStatusVal & INTR_MASK_ETH0_OVR )
- {
- return ETH_OVR_NUM0;
- }
- else if (intrStatusVal & INTR_MASK_ETH1_OVR )
- {
- return ETH_OVR_NUM1;
- }
- else
- {
- return HIGH_VEC;
- }
- }
- /**************************************************************************
- *
- * sysRc32438GpioDemux - Demultiplex the RC32438 GPIO interrupts
- *
- *
- *
- * This routine determines which GPIO pin of RC32438 is causing
- * the interrupt and returns the appropriate interrupt number so that
- * the ISR can be dispatched. It is used in the intPrioTable (above).
- *
- * NOTE: This routine runs in the interrupt context!
- *
- * RETURNS: Interrupt number for connected ISR
- */
- LOCAL ULONG sysRc32438GpioDemux
- (
- int arg /* Argument from intPrioTable */
- )
- {
- volatile UINT32 intrStatusVal; /* Value of master interrupt pend reg */
- intrStatusVal = INTERRUPT.i6.ipend;
- GPIO.gpioistat = 0;
- if (intrStatusVal & INTR_PCI_ABCD_MASK)
- {
- return INT_NUM_PCI_ABCD;
- }
- else
- {
- return HIGH_VEC;
- }
- }
- /***************************************************************************
- *
- * sysDeviceInterruptDisable - Disable device interrupts
- *
- * This routine disables devices interrupts. It is done as a safeguard
- * during cold boots, but is required on a warm boot.
- *
- * RETURNS: N/A
- *
- */
- LOCAL void sysDeviceInterruptDisable (void)
- {
- volatile UINT32* auxTimerIMsk = (UINT32*)(AUX_TIMER_INTR_MASK);
- /* Clear Ethernet Interface */
- sysOutLong(ETH_INTFC0,0);
- sysOutLong(ETH_INTFC1,0);
- /* Clear DMA Controller Registers for ETH0 */
- sysOutLong (DMA2C,0);
- sysOutLong (DMA3C,0);
- sysOutLong (DMA2S,0);
- sysOutLong (DMA3S,0);
- sysOutLong (DMA2DPTR,0);
- sysOutLong (DMA3DPTR,0);
- sysOutLong (DMA2NDPTR,0);
- sysOutLong (DMA3NDPTR,0);
- sysOutLong (DMA4C,0);
- sysOutLong (DMA5C,0);
- sysOutLong (DMA4S,0);
- sysOutLong (DMA5S,0);
- sysOutLong (DMA4DPTR,0);
- sysOutLong (DMA5DPTR,0);
- sysOutLong (DMA4NDPTR,0);
- sysOutLong (DMA5NDPTR,0);
- /* Mask and clear RC32438 UART interrupts */
- INTERRUPT.i5.imask |= 0xFC000 ;
- /*Mask and clear Aux Timer interrupts */
- *auxTimerIMsk = (UINT32)0xffffffff;
- /* Mask and clear RC32438 timer interrupts */
- TIMER.ct0.ctc = ( TIMER.ct0.ctc & ~0x20 ) ;
- INTERRUPT.i2.imask |= 0x1F ;
- INTERRUPT.i6.imask |= 0xffffffff;
- GPIO.gpioilevel = 0x0;
- GPIO.gpioistat = 0x0;
- }
- /*****************************************************************************
- *
- * sysPhysMemTop - get the address of the top of memory
- *
- * This routine returns the address of the first missing byte of memory, which
- * indicates the top of memory.
- *
- * NOTE: Do not adjust LOCAL_MEM_SIZE to reserve memory for application
- * use. See sysMemTop() for more information on reserving memory.
- *
- * RETURNS: The address of the top of memory.
- */
- char *sysPhysMemTop (void)
- {
- static char * memTop = NULL; /* Returned pointer to top of memory */
- if (memTop == NULL)
- {
- memTop = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE);
- }
- return (memTop);
- }
- /*****************************************************************************
- *
- * sysMemTop - get the address of the top of logical memory
- *
- * This routine returns the address of the first unusable byte of memory.
- * VxWorks will not use any memory at or above this address.
- *
- * The user can reserve local memory from the board by declaring the
- * macro USER_RESERVED_MEM with the amount of memory to reserve. This
- * routine will return a pointer to the first byte of the reserved memory
- * area.
- *
- * RETURNS: The address of the top of usable memory.
- */
- char *sysMemTop (void)
- {
- static char * memTop = NULL; /* Returned pointer to top of memory */
- if (memTop == NULL)
- {
- memTop = sysPhysMemTop () - USER_RESERVED_MEM;
- }
- return (memTop);
- }
- #ifndef BROADCOM_BSP
- /*****************************************************************************
- *
- * sysToMonitor - transfer control to the ROM monitor
- *
- * This routine transfers control to the ROM monitor. Normally, it is called
- * only by reboot()--which services ^X--and bus errors at interrupt level.
- * However, in some circumstances, the user may wish to introduce a
- * <startType> to enable special boot ROM facilities.
- *
- * RETURNS: Does not return.
- */
- STATUS sysToMonitor
- (
- int startType /* parameter passed to ROM to tell it how to boot */
- )
- {
- FUNCPTR pRom = (FUNCPTR) (ROM_TEXT_ADRS + 8);
- sysWbFlush (); /* Flush write buffers */
- (*pRom) (startType);
- return (OK); /* in case we ever continue from rom monitor */
- }
- #endif /*BROADCOM_BSP */
- /*****************************************************************************
- *
- * sysAutoAck - acknowledge the RC32438 interrupt condition
- *
- * This routine acknowledges an RC32438 interrupt for a specified interrupt
- * vector.
- *
- * NOTE:
- * This routine must be provided on all RC32438 board support packages.
- * Most interrupts are automatically acknowledged in the interrupt service
- * routine.
- *
- * RETURNS: The result of the interrupt acknowledge cycle.
- */
- int sysAutoAck
- (
- int vecNum /* vector num of interrupt that bugs us */
- )
- {
- int result = OK; /* Returned status */
- switch (vecNum)
- {
- case IV_TIMER_VEC:
- sysCompareSet (0);
- break;
- case IV_SWTRAP0_VEC: /* software trap 0 */
- result = sysSw0Ack ();
- break;
- case IV_SWTRAP1_VEC: /* software trap 1 */
- result = sysSw1Ack ();
- break;
- default:
- result = ERROR;
- break;
- }
- sysWbFlush (); /* Flush write buffers */
- return (result);
- }
- /*****************************************************************************
- *
- * sysClkEnable - turn on system clock interrupts
- *
- * This routine enables system clock interrupts.
- *
- * RETURNS: N/A
- *
- * SEE ALSO: sysClkDisable(), sysClkRateSet()
- */
- void sysClkEnable (void)
- {
- /* start the timer */
- int key;
- volatile UINT32* tmr0ctrl = (UINT32*)(CNTR_TMR0_CTRLREG);
- sysClkProcessorTicks = CPU_CLOCK_RATE /sysClkTicksPerSecond ;
- key = intLock ();
- sysCompareSet (0);
- sysCountSet (1);
- sysCompareSet (sysClkProcessorTicks);
- sysSoftCompare = sysClkProcessorTicks;
- sysClkRunning = TRUE;
- *tmr0ctrl = (UINT32)TIMER_ENABLE ;
- intUnlock (key);
- }
- /*****************************************************************************
- *
- * sysClkRateGet - get the system clock rate
- *
- * This routine returns the interrupt rate of the system clock.
- *
- * RETURNS: The number of ticks per second of the system clock.
- *
- * SEE ALSO: sysClkRateSet()
- */
- int sysClkRateGet (void)
- {
- return (sysClkTicksPerSecond);
- }
- /*****************************************************************************
- *
- * sysClkRateSet - set the system clock rate
- *
- * This routine sets the interrupt rate of the system clock. It does not
- * enable system clock interrupts. Normally, it is called by usrRoot() in
- * usrConfig.c.
- *
- * NOTE
- * The RC32364 internal timer is used to provide the system clock.
- *
- * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be
- * set.
- *
- * SEE ALSO: sysClkDisable(), sysClkEnable(), sysClkRateGet()
- */
- STATUS sysClkRateSet
- (
- int ticksPerSecond /* number of clock interrupts per second */
- )
- {
- if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
- return (ERROR);
- sysClkTicksPerSecond = ticksPerSecond;
- if (sysClkRunning)
- {
- sysClkDisable ();
- sysClkEnable ();
- }
- return (OK);
- }
- /*****************************************************************************
- *
- * sysClkInt - handle a system clock interrupt
- *
- * This routine handles a system clock interrupt. It increments the value
- * on the front panel display and calls the routine installed by
- * sysClkConnect().
- *
- * RETURNS: N/A
- */
- LOCAL void sysClkInt (void)
- {
- volatile unsigned int *ptr;
- ptr = (unsigned int *) CNTR_TMR0_CTRLREG;
- TIMER.ct0.ctc = 0;
- sysCountSet(0);
- sysCompareSet(CPU_CLOCK_RATE /sysClkTicksPerSecond);
- *ptr = 0x1;
- #if defined(PCI_INTA_HACK)
- SOC_INTR_INVOKE();
- #endif
- if (sysClkRoutine != NULL)
- (*sysClkRoutine) (sysClkArg);
- }
- /*****************************************************************************
- *
- * sysClkConnect - connect a routine to the system clock interrupt
- *
- * This routine specifies the interrupt handler to be called at each system
- * clock interrupt. It does not enable system clock interrupts. Normally,
- * it is called from usrRoot() in usrConfig.c to connect usrClock() to the
- * system clock interrupt. Other standard interrupt handlers are also set up
- * at this time.
- *
- * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
- *
- * SEE ALSO: intConnect(), usrClock()
- */
- STATUS sysClkConnect
- (
- FUNCPTR routine, /* routine called at each system clock interrupt */
- int arg /* argument with which to call routine */
- )
- {
- if (sysClkConnected == FALSE)
- {
- sysHwInit2 ();
- sysClkConnected = TRUE;
- }
- sysClkRoutine = routine;
- sysClkArg = arg;
- return (OK);
- }
- /*****************************************************************************
- *
- * sysClkDisable - turn off system clock interrupts
- *
- * This routine disables system clock interrupts.
- *
- * RETURNS: N/A
- *
- * SEE ALSO: sysClkEnable(), sysClkRateSet()
- */
- void sysClkDisable (void)
- {
- int key;
- volatile UINT32* tmr0ctrl = (UINT32*)(CNTR_TMR0_CTRLREG);
- /* we cannot disable interrupts so we do this instead... */
- key = intLock ();
- sysCompareSet (0);
- sysCountSet (1);
- sysClkProcessorTicks = CPU_CLOCK_RATE /sysClkTicksPerSecond;
- sysCompareSet (sysClkProcessorTicks);
- sysSoftCompare = sysClkProcessorTicks;
- sysClkRunning = FALSE;
- *tmr0ctrl = (UINT32)TIMER_DISABLE;
- intUnlock (key);
- }
- /*****************************************************************************
- *
- * sysAuxClkInt - interrupt level processing for auxiliary clock
- *
- * This routine handles the auxiliary clock interrupt. It is attached to the
- * clock interrupt vector by the routine sysAuxClkConnect().
- * The appropriate routine is called and the interrupt is acknowleged.
- *
- * RETURNS: N/A
- */
- LOCAL void sysAuxClkInt (void)
- {
- if (sysAuxClkRoutine != NULL)
- (*sysAuxClkRoutine) (sysAuxClkArg); /*call system clock routine */
- /* Mask and clear RC32438 timer interrupts */
- TIMER.ct1.ctc = ( TIMER.ct1.ctc & ~0x20 ) ;
- sysWbFlush (); /* Flush write buffers */
- }
- /*****************************************************************************
- *
- * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
- *
- * This routine specifies the interrupt service routine to be called at each
- * auxiliary clock interrupt. It does not enable auxiliary clock
- * interrupts.
- *
- * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
- *
- * SEE ALSO: intConnect(), sysAuxClkEnable()
- */
- STATUS sysAuxClkConnect
- (
- FUNCPTR routine, /*routine called at each aux clock interrupt */
- int arg /*argument to auxiliary clock interrupt routine*/
- )
- {
- if (!sysAuxClkConnected)
- {
- sysAuxClkConnected = TRUE;
- }
- sysAuxClkRoutine = routine;
- sysAuxClkArg = arg;
- return (OK);
- }
- /*****************************************************************************
- *
- * sysAuxClkDisable - turn off auxiliary clock interrupts
- *
- * This routine disables auxiliary clock interrupts.
- *
- * RETURNS: N/A
- *
- * SEE ALSO: sysAuxClkEnable()
- */
- void sysAuxClkDisable (void)
- {
- sysRc32438ClkDisable ();
- sysAuxClkRunning = FALSE ;
- }
- /*****************************************************************************
- *
- * sysAuxClkEnable - turn on auxiliary clock interrupts
- *
- * This routine enables auxiliary clock interrupts.
- *
- * RETURNS: N/A
- *
- * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
- */
- void sysAuxClkEnable (void)
- {
- sysTimer1Routine = (FUNCPTR) sysAuxClkInt;
- sysRc32438ClkEnable (sysAuxClkTicksPerSecond);
- sysAuxClkRunning = TRUE ;
- }
- /****************************************************************************
- *
- * sysAuxClkRateGet - get the auxiliary clock rate
- *
- * This routine returns the interrupt rate of the auxiliary clock.
- *
- * RETURNS: The number of ticks per second of the auxiliary clock.
- *
- * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
- */
- int sysAuxClkRateGet (void)
- {
- return (sysAuxClkTicksPerSecond);
- }
- /*******************************************************************************
- *
- * sysAuxClkRateSet - set the auxiliary clock rate
- *
- * This routine sets the interrupt rate of the auxiliary clock.
- * It does not enable auxiliary clock interrupts.
- *
- * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
- *
- * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
- */
- STATUS sysAuxClkRateSet
- (
- int ticksPerSecond /* number of clock interrupts per second*/
- )
- {
- if ( ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
- {
- return (ERROR);
- }
- sysAuxClkTicksPerSecond = ticksPerSecond ;
- if ( sysAuxClkRunning )
- {
- sysAuxClkDisable ();
- sysAuxClkEnable ();
- }
- return (OK);
- }
- /***************************************************************************
- *
- * sysCacheInit - initialize the RC32438 cache library
- *
- * Initializes the generic cache library to work with the IDTPMC438.
- *
- * RETURNS: OK or ERROR
- *
- * NOMANUAL
- */
- LOCAL STATUS sysCacheInit
- (
- CACHE_MODE instMode,
- CACHE_MODE dataMode
- )
- {
- #if defined (AUTO_CACHE_DETECT)
- UINT32 config1 = sysConfig1Get();
- int iCacheSize;
- int iCacheLineSize;
- int iCacheAssoc;
- int dCacheSize;
- int dCacheLineSize;
- int dCacheAssoc;
- iCacheSize =
- cacheSize[((config1 & IDT32438_CONFIG1_IS_MSK) >> IDT32438_CONFIG1_IS_SHF)];
- iCacheLineSize =
- cacheLineSize[((config1 & IDT32438_CONFIG1_IL_MSK)
- >> IDT32438_CONFIG1_IL_SHF)];
- iCacheAssoc =
- cacheAssoc[((config1 & IDT32438_CONFIG1_IA_MSK)
- >> IDT32438_CONFIG1_IA_SHF)];
- iCacheSize *= (iCacheLineSize * iCacheAssoc);
- dCacheSize =
- cacheSize[((config1 & IDT32438_CONFIG1_DS_MSK)
- >> IDT32438_CONFIG1_DS_SHF)];
- dCacheLineSize =
- cacheLineSize[((config1 & IDT32438_CONFIG1_DL_MSK)
- >> IDT32438_CONFIG1_DL_SHF)];
- dCacheAssoc =
- cacheAssoc[((config1 & IDT32438_CONFIG1_DA_MSK)
- >> IDT32438_CONFIG1_DA_SHF)];
- dCacheSize *= (dCacheLineSize * dCacheAssoc);
- return cache4kcLibInit(
- instMode, /* I-cache mode */
- dataMode, /* D-cache mode */
- iCacheSize,
- iCacheLineSize,
- dCacheSize,
- dCacheLineSize
- );
- #else
- return cache4kcLibInit(
- instMode, /* I-cache mode */
- dataMode, /* D-cache mode */
- iCacheSize,
- iCacheLineSize,
- dCacheSize,
- dCacheLineSize
- );
- #endif
- }
- /******************************************************************************
- *
- * sysNvRamGet - get the contents of non-volatile RAM
- *
- * This routine copies the contents of non-volatile memory into a specified
- * string. The string will be terminated with an EOS.
- *
- * RETURNS: OK, or ERROR if access is outside the non-volatile RAM range.
- *
- * SEE ALSO: sysNvRamSet()
- */
- STATUS sysNvRamGet
- (
- char *string, /* where to copy non-volatile RAM */
- int strLen, /* maximum number of bytes to copy */
- int offset /* byte offset into non-volatile RAM */
- )
- {
- int key; /* Saved status register for int lock */
- offset += NV_BOOT_OFFSET; /* boot line begins at <offset> = 0 */
- if ((offset < 0) || (strLen < 0) || ((offset + strLen) > NV_RAM_SIZE))
- return (ERROR);
- /* Exclude preemption */
- key = intLock ();
- sysI2CStringRead (I2C_READ_WRITE_ADRS + offset, string, strLen);
- string [strLen] = EOS;
- intUnlock (key);
- return (OK);
- }
- /*******************************************************************************
- *
- *
- * sysNvRamSet - write to non-volatile RAM
- *
- * This routine copies a specified string into non-volatile RAM.
- *
- * RETURNS: OK, or ERROR if access is outside the non-volatile RAM range.
- *
- * SEE ALSO: sysNvRamGet()
- */
- STATUS sysNvRamSet
- (
- char * string, /* string to be copied into non-volatile RAM */
- int strLen, /* maximum number of bytes to copy */
- int offset /* byte offset into non-volatile RAM */
- )
- {
- int key; /* Saved status register for int lock */
- offset += NV_BOOT_OFFSET; /* Boot line begins at <offset> = 0 */
- if ((offset < 0) || (strLen < 0) || ((offset + strLen) > NV_RAM_SIZE))
- return (ERROR);
- /* Exclude preemption */
- key = intLock ();
- sysI2CStringWrite ((I2C_READ_WRITE_ADRS + offset), string, strLen);
- /* Allow preemption */
- intUnlock (key);
- return (OK);
- }
- /******************************************************************
- * sysDmaIntVecTblInit - Initialize the DMA interrupt vector table.
- *
- * Initialize the DMA interrupt vector table.
- *
- * RETURNS N/A
- */
- LOCAL void sysDmaIntVecTblInit ()
- {
- int vect; /* interrupt vector */
- for (vect = 0; vect < MAX_DMA_INTRS; vect++)
- {
- dmaInterruptVectors[vect].func = (void *)0;
- dmaInterruptVectors[vect].param = (void *)0;
- }
- }
- /*****************************************************************************
- *
- * sysDmaIntEnable - enable interrupts for a DMA channel
- *
- * This function enables DMA interrupts at the RC32438 interrupt
- * controller for a single DMA channel. It does not alter the system
- * status register mask or any DMA device registers.
- *
- * RETURNS: N/A
- */
- void sysDmaIntEnable
- (
- unsigned int dmaChan /* DMA channel number (0-15) */
- )
- {
- if (dmaChan < MAX_DMA_INTRS)
- INTERRUPT.i3.imask &= ~(1 << dmaChan);
- return;
- }
- /******************************************************************
- *
- * sysDmaIntDisable - disable interrupts for a DMA channel
- *
- * This function disables DMA interrupts at the RC32438 interrupt
- * controller for a single DMA channel. It does not alter the system
- * status register mask or any DMA device registers.
- *
- * RETURNS: N/A
- */
- void sysDmaIntDisable
- (
- unsigned int dmaChan /* DMA channel number (0-15) */
- )
- {
- if (dmaChan < MAX_DMA_INTRS)
- INTERRUPT.i3.imask |= (1 << dmaChan);
- return;
- }
- /******************************************************************
- * sysDmaIntrVectorClr - Clear a DMA interrupt vector
- *
- * Clear the DMA interrupt vector table entry for this vector.
- *
- * RETURNS: N/A
- */
- void sysDmaIntrVectorClr
- (
- int vect /* interrupt vector */
- )
- {
- if (vect < 0 || vect >= MAX_DMA_INTRS)
- return;
- dmaInterruptVectors[vect].func = (void *) NULL;
- dmaInterruptVectors[vect].param = NULL;
- }
- /******************************************************************
- * sysDmaIntrVectorSet - Set a DMA interrupt vector
- *
- * Set the DMA interrupt vector table entry to the handler routine.
- *
- * RETURNS: N/A
- */
- void sysDmaIntrVectorSet
- (
- int vect, /* interrupt vector */
- void (*fptr) (), /* function pointer */
- void * param /* parameter to be passed to the function */
- )
- {
- if (vect < 0 || vect >= MAX_DMA_INTRS)
- return;
- dmaInterruptVectors[vect].func = (void *) fptr;
- dmaInterruptVectors[vect].param = param;
- }
- /******************************************************************
- * sysDmaIsr - DMA interrupt service routine
- *
- * RC32438 has 12 DMA channels that share same interrupt line. The DMA
- * interrupt service routine demultiplexes this interrupt for the all
- * the dma channels. The device driver using a dma channel, initializes
- * a global list ( having maximum of 12 entries : dma channel 0 through
- * 11) which is referenced by the dmaIsr function to call the
- * appropriate interrupt handlers.
- *
- * RETURNS: N/A
- */
- LOCAL void sysDmaIsr
- (
- int parm /* parameter value */
- )
- {
- int vect; /* index into DMA interrupt vector array */
- UINT32 iPend; /* interrupt pending register value */
- UINT32 mask; /* bit mask */
- unsigned (*func) ();
- /* Read the IPEND3 register */
- iPend = INTERRUPT.i3.ipend;
- mask = 1;
- for (vect = 0; (iPend != 0) && (vect < MAX_DMA_INTRS); vect++)
- {
- if (iPend & mask)
- {
- func = ((unsigned (*) ()) dmaInterruptVectors[vect].func);
- if (func != NULL)
- {
- (* func) (vect, dmaInterruptVectors[vect].param);
- }
- else
- {
- (void)logMsg("Uninit DMA int: %dn", vect, 2, 3, 4, 5, 6);
- INTERRUPT.i3.imask |= mask;
- }
- iPend &= ~mask;
- }
- mask = mask << 1;
- }
- }
- /****************************************************************************
- * FUNCTION : sysTimerIsr
- *
- *
- *
- * RC32438 has 5 timers that share same interrupt line.
- * The timer interrupt service routine demultiplexes this interrupt for
- * all the timers. The timerIsr function calls the
- * appropriate interrupt handlers. In order to maintain equal opportunity
- * for all the timers, the timerIsr function services all the timer
- * interrupts in an order to ensure fairness to the timer interrupts among
- * the active timers.
- *
- *
- * RETURNS: N/A
- */
- LOCAL ULONG sysTimerIsr
- (
- int parm /* parameter value */
- )
- {
- UINT32 ipend; /*interrupt pending reg */
- UINT32 imask; /*mask value */
- ipend = INTERRUPT.i2.ipend;
- imask = INTERRUPT.i2.imask;
- ipend &= ~imask;
- if (ipend & CNTR_TMR0_MASK)
- {
- return TMR0_INT_NUM;
- }
- if (ipend & CNTR_TMR1_MASK)
- {
- if (sysTimer1Routine != NULL)
- (*sysTimer1Routine) ();
- TIMER.ct1.ctc &= ~CTC_TO;
- }
- if (ipend & CNTR_TMR2_MASK)
- {
- if (sysTimer2Routine != NULL)
- (*sysTimer2Routine) ();
- TIMER.ct2.ctc = CTC_EN;
- }
- if (ipend & REFRESH_TIMER_MASK)
- {
- if (sysRefreshTimerRoutine != NULL)
- (*sysRefreshTimerRoutine) ();
- TIMER.rtc = CTC_EN;
- }
- if (ipend & WDOG_TMR_TO_MASK)
- {
- if (sysWatchdogTimerRoutine != NULL)
- (*sysWatchdogTimerRoutine) ();
- SYSINTEG.wtc &= ~WTC_TO;
- SYSINTEG.errcs &= ~ERRCS_WTO;
- }
- if (ipend & UNDEC_CPU_WR_MASK)
- {
- if (sysUndecodedCPUWriteRoutine!= NULL)
- (*sysUndecodedCPUWriteRoutine) ();
- SYSINTEG.errcs &= ~ERRCS_UCW;
- }
- return (OK);
- }
- /*******************************************************************************
- *
- * sysRc32438ClkEnable - enable the Rc32438 timer0 interrupt
- *
- * This routine enables the Rc32438 timer0 to give a periodic interrupt.
- * The <ticksPerSecond> parameter specifies the number of interrupts to generate
- * per second.
- *
- *
- * RETURNS: N/A
- *
- * SEE ALSO: sysRc32438ClkDisable()
- *
- * NOMANUAL
- */
- void sysRc32438ClkEnable
- (
- int ticksPerSecond /*interrupt frequency */
- )
- {
- volatile UINT32* rc32438Timer1CntlReg ; /*timer control reg*/
- volatile UINT32* rc32438Timer1CntReg ; /*timer count reg */
- volatile UINT32* rc32438Timer1CmpReg ; /*timer compare reg */
- volatile UINT32* rc32438TimerMask ; /*timer mask reg */
- volatile UINT32* rc32438TimerPend ; /*timer pend reg */
- int key ; /*temp variable */
- rc32438Timer1CntlReg = (UINT32*)AUX_TIMER_CNTL_REG ;
- rc32438Timer1CntReg = (UINT32*)AUX_TIMER_CNT_REG ;
- rc32438Timer1CmpReg = (UINT32*)AUX_TIMER_CMP_REG ;
- rc32438TimerPend = (UINT32*)AUX_TIMER_INTR_PEND ;
- rc32438TimerMask = (UINT32*)AUX_TIMER_INTR_MASK ;
- key = intLock ();
- *rc32438Timer1CntlReg = (UINT32)0x0; /* Clear any pending interrupt */
- *rc32438Timer1CntReg = (UINT32)0x0; /* Count is made Zero */
- /* Compare=BUSFREQ/ticks PerSecond */
- *rc32438Timer1CmpReg = (UINT32)(AUX_CLOCK_FREQ / ticksPerSecond) ;
- *rc32438Timer1CntlReg = (UINT32)0x0; /* Clear any pending interrupt */
- *rc32438TimerMask &= (UINT32)0xfffffffd;
- /* Enable Timer1 Interrupt */
- *rc32438Timer1CntlReg = (UINT32)0x1; /* Enable the Timer1 */
- intUnlock (key);
- }
- /*****************************************************************************
- *
- * sysRc32438ClkDisable - disable the Rc32438 timer1 interrupt
- *
- * This routine disables the Rc32438 timer1 interrupt.
- *
- * RETURNS: N/A
- *
- * SEE ALSO: sysRc32438ClkEnable()
- *
- * NOMANUAL
- */
- void sysRc32438ClkDisable ()
- {
- UINT32* rc32438Timer1CntlReg ; /*timer control reg */
- UINT32* rc32438Timer1CntReg ; /*timer count reg */
- UINT32* rc32438Timer1CmpReg ; /*timer compare reg */
- UINT32* rc32438TimerMask ; /*timer mask reg */
- UINT32* rc32438TimerPend ; /*timer pend reg */
- int key ; /*temp variable */
- rc32438Timer1CntlReg = (UINT32*)AUX_TIMER_CNTL_REG ;
- rc32438Timer1CntReg = (UINT32*)AUX_TIMER_CNT_REG ;
- rc32438Timer1CmpReg = (UINT32*)AUX_TIMER_CMP_REG ;
- rc32438TimerPend = (UINT32*)AUX_TIMER_INTR_PEND ;
- rc32438TimerMask = (UINT32*)AUX_TIMER_INTR_MASK ;
- key = intLock ();
- *rc32438Timer1CntlReg = (UINT32)0x0; /* Disable the Timer1 */
- *rc32438Timer1CntReg = (UINT32)0x0; /* Count is made Zero */
- *rc32438TimerMask |= (UINT32)0xfffffffE;/* Disable Timer1 Interrupt */
- intUnlock (key);
- }
- /**************************************************************************
- *
- * sysEnetReverse - Reverse bytes in ethernet address array
- *
- * This routine reverses the order of bytes in a 6-character array.
- * This utility is required because the boot shell 'N' command and
- * the ethernet driver expect the opposite byte order for ethernet
- * addresses. Given an address 00:11:22:33:44:55, the boot shell
- * expects to see it stored in an array as 55,44,33,22,11,00, but
- * the ethernet driver expects to see it as 00,11,22,33,44,55.
- *
- * RETURNS: N/A
- */
- LOCAL void sysEnetReverse
- (
- uchar_t *inpAddr, /* Input address array */
- uchar_t *revAddr /* Reversed output array */
- )
- {
- int idx; /* loop index */
- for (idx = 0; idx < ENET_SIZE; idx++)
- {
- revAddr[idx] = inpAddr[ENET_SIZE - idx - 1];
- }
- }
- /**************************************************************************
- *
- * sysEnetAddrGet - Read ethernet address from NVRAM for boot shell.
- *
- * This routine reads the ethernet address saved in NVRAM and reverses
- * the bytes read before returning the result. This interface
- * accomodates the 'N' command in the boot shell. If an unknown unit
- * number is passed, then an ethernet address of all zeros is returned.
- *
- * RETURNS: N/A
- */
- void sysEnetAddrGet
- (
- int unit, /* Unit number */
- uchar_t* retEnetAddr /* Returned ethernet addr */
- )
- {
- uchar_t readEnetAddr [ENET_SIZE + 1]; /* read from NVRAM, natural order */
- if (unit == IDT_UNIT0)
- {
- sysNvRamGet ((char *) readEnetAddr, ENET_SIZE, NV_ENET_OFFSET0);
- sysEnetReverse (readEnetAddr, retEnetAddr);
- }
- else if (unit == IDT_UNIT1)
- {
- sysNvRamGet ((char *) readEnetAddr, ENET_SIZE, NV_ENET_OFFSET0);
- sysEnetReverse (readEnetAddr, retEnetAddr);
- retEnetAddr[5]= retEnetAddr[5] + 1;
- }
- else
- {
- bfill ((char *) retEnetAddr, ENET_SIZE, 0);
- }
- }
- /**************************************************************************
- *
- * sysEnetAddrSet - Write ethernet address to NVRAM for boot shell.
- *
- * This routine writes the passed ethernet address to NVRAM. For a
- * given address 00:11:22:33:44:55, the parameter order would be
- * sysEnetAddrSet(00,11,22,33,44,55). This interface accomodates the
- * 'N' command in the boot shell.
- *
- * RETURNS: N/A
- */
- void sysEnetAddrSet
- (
- uchar_t addr0, /* Address offset 0 - first byte of address */
- uchar_t addr1, /* Address offset 1 */
- uchar_t addr2, /* Address offset 2 */
- uchar_t addr3, /* Address offset 3 */
- uchar_t addr4, /* Address offset 4 */
- uchar_t addr5 /* Address offset 5 - last byte of address */
- )
- {
- char enetAddr [ENET_SIZE];
- enetAddr [0] = addr0;
- enetAddr [1] = addr1;
- enetAddr [2] = addr2;
- enetAddr [3] = addr3;
- enetAddr [4] = addr4;
- enetAddr [5] = addr5;
- sysNvRamSet ((char *) enetAddr, ENET_SIZE, NV_ENET_OFFSET0);
- }
- /******************************************************************************
- *
- * sysidt32438EnetAddrGet - Retrieve ethernet address for ethernet driver.
- *
- * This routine returns a six-byte ethernet address for a given ethernet unit.
- * The ethernet driver uses this routine to obtain the ethernet address if
- * indicated by a user-flag in the LoadString (above) - or if the reading the
- * ethernet address ROM is unsuccessful.
- *
- * RETURNS: OK
- */
- STATUS sysidt32438EnetAddrGet
- (
- int unit, /* unit number */
- char * enetAddr /*returned ethernet address */
- )
- {
- sysNvRamGet (enetAddr, ENET_SIZE, NV_ENET_OFFSET0);
- return (OK);
- }
- /**************************************************************************
- *
- * sysEnetAddrInit - Initialize NVRAM with default ethernet address
- *
- * This routine checks the ethernet address stored in NVRAM. If the
- * first three bytes are not set to the unused manufacturing code
- * (ENET_DEFAULT, defined in config.h), then a default address
- * is written into NVRAM which comprises the unused manufacturing code
- * and 3 lower bytes of 0xff.
- *
- * RETURNS: N/A
- */
- void sysEnetAddrInit (void)
- {
- char defEnetAddr [ENET_SIZE] = /* Default ethernet address */
- {
- ((ENET_DEFAULT & 0x0000ff00) >> 8),
- ((ENET_DEFAULT & 0x00ff0000) >> 16),
- ((ENET_DEFAULT & 0xff000000) >> 24),
- 0xff, 0xff, 0xff
- };
- char curEnetAddr [ENET_SIZE + 1]; /* Current ethernet address */
- /* Read current ethernet address */
- sysNvRamGet(curEnetAddr, ENET_SIZE, NV_ENET_OFFSET0);
- /* If first three bytes of current ethernet address are not
- * ENET_DEFAULT, then write default address.
- */
- if ((curEnetAddr[0] != defEnetAddr[0])
- || (curEnetAddr[1] != defEnetAddr[1])
- || (curEnetAddr[2] != defEnetAddr[2])
- )
- {
- sysNvRamSet (defEnetAddr, ENET_SIZE, NV_ENET_OFFSET0);
- }
- }
- #ifdef INCLUDE_TIMESTAMP
- /*******************************************************************************
- *
- * sysTimestampConnect - connect a user routine to a timestamp timer interrupt
- *
- * This routine specifies the user interrupt routine to be called at each
- * timestamp timer interrupt.
- *
- * RETURNS: ERROR, always.
- */
- STATUS sysTimestampConnect
- (
- FUNCPTR routine, /* routine called at each timestamp timer interrupt */
- int arg /* argument with which to call routine */
- )
- {
- return (ERROR);
- }
- /*******************************************************************************
- *
- * sysTimestampEnable - enable a timestamp timer interrupt
- *
- * This routine enables timestamp timer interrupts and resets the counter.
- *
- * RETURNS: OK, always.
- *
- * SEE ALSO: sysTimestampDisable()
- */
- STATUS sysTimestampEnable (void)
- {
- if (sysTimestampRunning)
- {
- return (OK);
- }
- if (!sysClkRunning)
- return (ERROR);
- sysTimestampRunning = TRUE;
- return (OK);
- }
- /*******************************************************************************
- *
- * sysTimestampDisable - disable a timestamp timer interrupt
- *
- * This routine disables timestamp timer interrupts.
- *
- * RETURNS: OK, always.
- *
- * SEE ALSO: sysTimestampEnable()
- */
- STATUS sysTimestampDisable (void)
- {
- if (sysTimestampRunning)
- sysTimestampRunning = FALSE;
- return (OK);
- }
- /*******************************************************************************
- *
- * sysTimestampPeriod - get the period of a timestamp timer
- *
- * This routine gets the period of the timestamp timer, in ticks. The
- * period, or terminal count, is the number of ticks to which the timestamp
- * timer counts before rolling over and restarting the counting process.
- *
- * RETURNS: The period of the timestamp timer in counter ticks.
- */
- UINT32 sysTimestampPeriod (void)
- {
- /*
- * The period of the timestamp depends on the clock rate of the on-chip
- * timer.
- */
- return (CPU_CLOCK_RATE/sysClkTicksPerSecond);
- }
- /*******************************************************************************
- *
- * sysTimestampFreq - get a timestamp timer clock frequency
- *
- * This routine gets the frequency of the timer clock, in ticks per
- * second. The rate of the timestamp timer is set explicitly by the
- * hardware and typically cannot be altered.
- *
- * RETURNS: The timestamp timer clock frequency, in ticks per second.
- */
- UINT32 sysTimestampFreq (void)
- {
- return (CPU_CLOCK_RATE);
- }
- /*******************************************************************************
- *
- * sysTimestamp - get a timestamp timer tick count
- *
- * This routine returns the current value of the timestamp timer tick counter.
- * The tick count can be converted to seconds by dividing it by the return of
- * sysTimestampFreq().
- *
- * This routine should be called with interrupts locked. If interrupts are
- * not locked, sysTimestampLock() should be used instead.
- *
- * RETURNS: The current timestamp timer tick count.
- *
- * SEE ALSO: sysTimestampFreq(), sysTimestampLock()
- */
- UINT32 sysTimestamp (void)
- {
- return (sysCountGet() - (sysSoftCompare - sysClkProcessorTicks) + 1);
- }
- /*******************************************************************************
- *
- * sysTimestampLock - lock interrupts and get the timestamp timer tick count
- *
- * This routine locks interrupts when the tick counter must be stopped
- * in order to read it or when two independent counters must be read.
- * It then returns the current value of the timestamp timer tick
- * counter.
- *
- * The tick count can be converted to seconds by dividing it by the return of
- * sysTimestampFreq().
- *
- * If interrupts are already locked, sysTimestamp() should be
- * used instead.
- *
- * RETURNS: The current timestamp timer tick count.
- *
- * SEE ALSO: sysTimestampFreq(), sysTimestamp()
- */
- UINT32 sysTimestampLock (void)
- {
- return(sysCountGet() - (sysSoftCompare - sysClkProcessorTicks)+ 1);
- }
- #endif /* INCLUDE_TIMESTAMP */
- #ifdef BROADCOM_BSP
- /******************************************************************************
- *
- * sysBacktraceMips - perform a stack trace of the caller with symbols
- * by Curt McDowell - csm@broadcom.com 03-20-01
- *
- * NOTE:
- *
- * This routine is specific to MIPS and GCC stack frame generation.
- * Each function generated by the compiler must begin with a decrement
- * of the stack pointer, then in the next few instructions, must save
- * the return address on the stack.
- *
- * 27bdffd0 addiu $sp,$sp,-48
- * ...
- * afbf0028 sw $ra,40($sp)
- * ...
- */
- /* Hack; some day fix to locate function start using symFindByValue */
- #define SYSBT_MAX_FUNC_WORDS 4096
- LOCAL void sysbt_addr2sym(char *symName, UINT addr)
- {
- extern SYMTAB_ID sysSymTbl;
- UINT symVal;
- SYM_TYPE symType;
- int rc;
- #if VX_VERSION==55
- char **psymName;
- rc = symByValueFind(sysSymTbl,
- (UINT) addr,
- psymName, &symVal, &symType);
- if (rc != ERROR)
- strcpy(symName, *psymName);
- #else
- rc = symFindByValue(sysSymTbl,
- (UINT) addr,
- symName, &symVal, &symType);
- #endif
- if (rc == ERROR)
- sprintf(symName, "0x%x", addr);
- else if (symVal < addr)
- sprintf(symName + strlen(symName),
- " + 0x%x", addr - symVal);
- else if (symVal > addr)
- sprintf(symName + strlen(symName),
- " - 0x%x", symVal - addr);
- }
- #define VALID_K0(addr)
- (IS_KSEG0(addr) && K0_TO_PHYS(addr) < K0_TO_PHYS(sysPhysMemTop()))
- #define VALID_K1(addr)
- (IS_KSEG1(addr) && K1_TO_PHYS(addr) < K0_TO_PHYS(sysPhysMemTop()))
- #define VALID_ADDR(addr)
- (VALID_K0(addr) || VALID_K1(addr))
- #define VALID_TEXT_ADDR(addr)
- VALID_ADDR(addr) /* some day fix for text range */
- #define VALID_STACK_ADDR(addr)
- VALID_ADDR(addr) /* some day fix for stack range */
- void sysBacktraceMips(char *pfx, char *sfx, int direct)
- {
- UINT *sp, *pc, *fn_start, *caller_sp, *ra;
- extern UINT *vxSpGet(), *vxPcGet(); /* sysALib.s */
- int limit, first = 1;
- char buf[2048], symName[128], *s;
- int ra_off, sp_off;
- extern void sysSerialPrintString(char *s);
- sp = vxSpGet();
- pc = vxPcGet();
- s = buf;
- strcpy(s, pfx);
- while (*s) s++;
- while (s < &buf[sizeof (buf) - 128]) {
- fn_start = pc;
- for (limit = 0; limit < SYSBT_MAX_FUNC_WORDS; limit++) {
- /* sw $ra,x($sp); x>=0 */
- if ((*--fn_start & 0xffff8000) == 0xafbf0000)
- break;
- }
- if (limit == SYSBT_MAX_FUNC_WORDS)
- break;
- ra_off = (*fn_start & 0x7fff);
- for (limit = 0; limit < SYSBT_MAX_FUNC_WORDS; limit++) {
- /* addiu $sp,$sp,-x; x<0 */
- if ((*--fn_start & 0xffff8000) == 0x27bd8000)
- break;
- }
- if (limit == SYSBT_MAX_FUNC_WORDS)
- break;
- sp_off = (int) (*fn_start | 0xffff0000);
- ra = (UINT *) sp[ra_off / 4];
- caller_sp = sp - (sp_off / 4);
- sysbt_addr2sym(symName, (UINT) pc);
- if (! first)
- sprintf(s,
- "FUNC = 0x%x, PC = 0x%x (%s), SP = 0x%xn",
- (UINT) fn_start, (UINT) pc, symName, (UINT) sp);
- while (*s) s++;
- if (! VALID_TEXT_ADDR(ra)) {
- sprintf(s, "RA 0x%x out of rangen", (UINT) ra);
- while (*s) s++;
- break;
- }
- if (! VALID_STACK_ADDR(caller_sp)) {
- sprintf(s, "Caller SP 0x%x out of rangen", (UINT) caller_sp);
- while (*s) s++;
- break;
- }
- pc = ra;
- sp = caller_sp;
- first = 0;
- }
- strcpy(s, sfx);
- if (direct)
- sysSerialPrintString(buf); /* Atomically print giant string */
- else {
- fputs(buf, stdout); /* Regular print giant string */
- fflush(stdout);
- }
- }
- /*******************************************************************************
- *
- * sysToMonitor - transfer control to the ROM monitor
- *
- * This routine transfers control to the ROM monitor. Normally, it is called
- * only by reboot()--which services ^X--and bus errors at interrupt level.
- * However, in some circumstances, the user may wish to introduce a
- * <startType> to enable special boot ROM facilities.
- *
- * RETURNS: Does not return.
- */
- int sysToMonitorExcMessage = 0;
- int sysToMonitorBacktrace = 1;
- int sysToMonitorReboot = 1;
- void (*sysToMonitorHook)(void);
- STATUS sysToMonitor
- (
- int startType /* parameter passed to ROM to tell it how to boot */
- )
- {
- if (sysToMonitorHook)
- (*sysToMonitorHook)();
- if (sysToMonitorBacktrace)
- sysBacktraceMips("n--- Stack Trace ---n", "", 1);
- if (sysToMonitorReboot) {
- FUNCPTR pRom = (FUNCPTR) (ROM_TEXT_ADRS + 8);
- intLock();
- sysWbFlush (); /* Flush write buffers */
- (*pRom) (startType);
- return (OK); /* in case we ever continue from rom monitor */
- }
- return (OK);
- }
- /*******************************************************************************
- *
- * sysReboot - Reboots the system
- *
- *
- * RETURNS: Does not return.
- */
- void sysReboot
- (
- void
- )
- {
- sysToMonitor(0);
- }
- void
- SYS_TOD_SET()
- {
- }
- void
- sysSerialPrintString()
- {
- }
- /* Detect HHB4 / DC21150 PCI-PCI bridge chips, and configure bus if
- * found. Note that this code should be run whenever we find a PCI
- * class code of type bridge. After we have run this procedure for the
- * first bridge, we then need to traverse any sub-bridges. This code
- * deals with only one PCI-PCI bridge and it's IO space for
- * sub-devices. See mousse.h for more details as well as the PCI-PCI
- * bridge specification.
- */
- #ifdef INCLUDE_PCI
- int sysPCIBridgeProbe(int instance,
- int primary,
- int secondary,
- int subordinate)
- {
- int BusNo, DevNo, FuncNo;
- unsigned int buses = 0;
- sysPciBusErrDisable();
- /* Find DC21150 PCI-PCI bridge or
- * HINTCORP HB4 PCI-PCI Bridge
- */
- if ( (pciFindDevice(DC21150_VENDOR_ID,
- DC21150_DEVICE_ID,
- instance,
- &BusNo, &DevNo, &FuncNo) != ERROR) ||
- (pciFindDevice(PERICOM_VENDOR_ID,
- PERICOM_8150_DEV_ID,
- instance,
- &BusNo, &DevNo, &FuncNo) != ERROR) ||
- (pciFindDevice(HINT_HB4_VENDOR_ID,
- HINT_HB4_DEVICE_ID,
- instance,
- &BusNo, &DevNo, &FuncNo) != ERROR)) {
- /* Disable device */
- pciConfigOutWord(BusNo,DevNo,FuncNo, PCI_CFG_COMMAND, 0x0000);
- pciConfigOutWord(BusNo,DevNo,FuncNo, PCI_CFG_STATUS, 0xffff);
- /* Reset secondary bus */
- pciConfigOutWord(BusNo,DevNo,FuncNo,
- PCI_CFG_BRIDGE_CONTROL,
- 0x0040);
- /* Setup topology info */
- buses = (buses & 0xff000000)
- | ((unsigned int)(primary) << 0)
- | ((unsigned int)(secondary) << 8)
- | ((unsigned int)(subordinate) << 16);
- /*
- * linux, -We need to blast all three values with a single write.
- */
- pciConfigOutLong(BusNo, DevNo, FuncNo,
- PCI_CFG_PRIMARY_BUS, buses);
- /* Clear secondary status */
- pciConfigOutWord(BusNo,DevNo,FuncNo,
- PCI_CFG_SEC_STATUS, 0xffff);
- /* Setup memory address space mapping */
- pciConfigOutWord(BusNo,DevNo,FuncNo,
- PCI_CFG_MEM_BASE,
- ((P2P_NONPREF_MEM_BASE & 0xFFF00000) >> 16));
- pciConfigOutWord(BusNo,DevNo,FuncNo,
- PCI_CFG_MEM_LIMIT,
- ((P2P_NONPREF_MEM_BASE +
- P2P_NONPREF_MEM_SIZE - 1) & 0xFFF00000) >> 16);
- /* Clear bridge control */
- pciConfigOutWord(BusNo,DevNo,FuncNo,
- PCI_CFG_BRIDGE_CONTROL,0x0000);
- /* Enable PCI clocks on remote end */
- pciConfigOutWord(BusNo,DevNo,FuncNo,
- PCI_CFG_DEC21150_SEC_CLK,
- P2P_CLK_ENABLE);
- /* Clear status */
- pciConfigOutByte(BusNo,DevNo,FuncNo,
- PCI_CFG_DEC21150_SERR_STAT, 0xff);
- /* Clear status */
- pciConfigOutWord(BusNo,DevNo,FuncNo,
- PCI_CFG_STATUS, 0xffff);
- /* Re-enable config space */
- pciConfigOutWord(BusNo,DevNo,FuncNo, PCI_CFG_COMMAND,
- P2P_PMC_ENABLE);
- return OK;
- }
- sysPciBusErrEnable();
- return ERROR;
- }
- #endif
- /*****************************************************************************
- *
- * Each time VxWorks is rebooted, it starts assigning system-assigned
- * port numbers beginning at 1024. Thus, if vxWorks is rebooted two or
- * more times in succession, the same port number will be re-used.
- *
- * This behavior causes problems when vxWorks is being booted from a
- * remote FTP server (particularly one running Solaris), because port
- * 1024 goes into a TIME_WAIT state on the server and cannot be reused
- * until it times out, typically in 2-4 minutes.
- *
- * This hack reduces the likelihood of this happening by "wasting"
- * a different number of system-assigned port numbers for each boot.
- */
- void sysBindFix(void)
- {
- UINT8 N;
- sysNvRamGet((char *) &N, 1, NV_OFF_BINDFIX);
- N -= 16;
- sysNvRamSet((char *) &N, 1, NV_OFF_BINDFIX);
- /* This is quite fast even when N=255 */
- while (N--) {
- int s;
- struct sockaddr_in saddr;
- saddr.sin_addr.s_addr = htonl(INADDR_ANY);
- saddr.sin_port = 0;
- saddr.sin_family = AF_INET;
- s = socket(AF_INET, SOCK_STREAM, 0);
- bind(s, (struct sockaddr *) &saddr, sizeof(saddr));
- close(s);
- }
- }
- #ifdef PCI_DECOUPLED
- #define MAX_POLL_PCI_DECOUPLED 256
- UINT32 sysMaxPciRpolls = 0;
- UINT32 sysMaxPciWpolls = 0;
- UINT32 sysMaxPciRpollsDist[256] = { 0 };
- #ifdef INCLUDE_PCI
- void
- sysPciRWInit()
- {
- PCI.pcidac = PCIDAC_DEN; /* Enable PCI decoupled accesses at */
- /* initialization */
- for(sysMaxPciRpolls = 0;
- sysMaxPciRpolls < sizeof(sysMaxPciRpollsDist)/sizeof(UINT32);
- sysMaxPciRpolls++) {
- sysMaxPciRpollsDist[sysMaxPciRpolls] = 0;
- }
- sysMaxPciRpolls = 0;
- sysMaxPciWpolls = 0;
- }
- UINT32
- sysPciRead(UINT32 *addr)
- {
- volatile UINT32 data;
- UINT32 spl;
- UINT32 cpolls = 0;
- spl = intLock();
- data = *addr;
- while (((PCI.pcidas) & PCIDAS_D) == 0) {
- if (sysMaxPciRpolls < ++cpolls ) sysMaxPciRpolls = cpolls;
- if (((PCI.pcidas) & PCIDAS_E) != 0) break;
- if (cpolls > MAX_POLL_PCI_DECOUPLED) break;
- }
- if (cpolls < sizeof(sysMaxPciRpollsDist)/sizeof(UINT32)) {
- sysMaxPciRpollsDist[cpolls]++;
- }
- data = PCI.pcidad;
- data = ((data & 0xFF000000) >> 24) |
- ((data & 0x00FF0000) >> 8) |
- ((data & 0x0000FF00) << 8) |
- ((data & 0x000000FF) << 24) ;
- PCI.pcidas &= (~(PCIDAS_D));
- intUnlock(spl);
- return(data);
- }
- void
- sysPciWrite(UINT32 *addr, UINT32 data)
- {
- UINT32 spl;
- UINT32 cpolls = 0;
- spl = intLock();
- while ((PCI.pcidas & PCIDAS_OFE) == 0) {
- if (sysMaxPciWpolls < ++cpolls ) sysMaxPciWpolls = cpolls;
- if (cpolls > MAX_POLL_PCI_DECOUPLED) break;
- }
- *addr = data;
- cpolls = 0;
- intUnlock(spl);
- }
- #endif
- #endif /* PCI_DECOUPLED */
- #endif /*BROADCOM_BSP */