📄 epic.c
字号:
/************************************************************************/
/* */
/* Copyright (c) 2001 by Accelerated Technology, Inc. */
/* */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in */
/* the subject matter of this material. All manufacturing, */
/* reproduction, use, and sales rights pertaining to this subject */
/* matter are governed by the license agreement. The recipient of */
/* this software implicitly accepts the terms of the license. */
/* */
/* */
/************************************************************************/
/************************************************************************/
/* FILE NAME VERSION */
/* */
/* epic.c Nucleus PLUS\MPC8245\Diab C/C++ 1.13.1 */
/* */
/* */
/* DESCRIPTION */
/* */
/* Support services for the EPIC interrupt controller for the */
/* PowerPC 8240 processor. These services assume PCI Address */
/* Map B is being used. To change to Address Map A, modify the */
/* the ECONFIG_ADDR and ECONFIG_DATA defines in epic_defs.h . */
/* These addresses should point to the PCI Configuration Address */
/* and Data registers respectively. */
/* */
/* DATA STRUCTURES */
/* */
/* none */
/* */
/* FUNCTIONS */
/* */
/* epic_Read_Config_Word */
/* epic_Write_Config_Word */
/* epic_EUMB_Read_Word */
/* epic_EUMB_Write_Word */
/* epic_IntAck */
/* epic_Init */
/* epic_Open_Direct_Int */
/* */
/* DEPENDENCIES */
/* NA */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* T. Weller 12\19\2001 Created inital version 1.13.1 */
/************************************************************************/
#include "epic_extr.h"
/************************************************************************/
/* epic_Read_Config_Word */
/* */
/* */
/* DESCRIPTION */
/* */
/* Support service for reading EPIC configuration registers */
/* */
/************************************************************************/
UINT32 epic_Read_Config_Word(UINT32 regNum)
{
UINT32 addr;
UINT32 temp;
addr = regNum & 0x000000FF;
addr |= 0x80000000;
*(UINT32 *) (ECONFIG_ADDR) = LONGSWAP(addr);
temp = *(UINT32 *) (ECONFIG_DATA);
return LONGSWAP(temp);
}
/************************************************************************/
/* epic_Write_Config_Word */
/* */
/* */
/* DESCRIPTION */
/* */
/* Support service for writing to EPIC configuration registers */
/* */
/************************************************************************/
void epic_Write_Config_Word(UINT32 regNum, UINT32 regVal)
{
UINT32 addr;
addr = regNum & 0x000000FF;
addr |= 0x80000000;
*(UINT32 *) (ECONFIG_ADDR) = LONGSWAP(addr);
*(UINT32 *) (ECONFIG_DATA) = LONGSWAP(regVal);
}
/************************************************************************/
/* epic_EUMB_Read_Word */
/* */
/* */
/* DESCRIPTION */
/* */
/* Support service for reading 32-bit values. */
/* */
/************************************************************************/
UINT32 epic_EUMB_Read_Word(UINT32 addr)
{
UINT32 temp;
temp = *(UINT32 *) (addr);
return (LONGSWAP(temp));
}
/************************************************************************/
/* epic_EUMB_Write_Word */
/* */
/* */
/* DESCRIPTION */
/* */
/* Support service for writing 32-bit values. */
/* */
/************************************************************************/
void epic_EUMB_Write_Word(UINT32 addr, UINT32 val)
{
*(UINT32 *) (addr) = LONGSWAP(val);
}
/************************************************************************/
/* epic_IntAck */
/* */
/* */
/* DESCRIPTION */
/* */
/* Performs an interrupt acknowledge for the EPIC. */
/* */
/************************************************************************/
UINT32 epic_IntAck(UINT32 eumbbar)
{
UINT32 temp;
temp = epic_EUMB_Read_Word(eumbbar+EPIC_PROC_INT_ACK_REG);
return (temp);
}
/************************************************************************/
/* epic_EOI */
/* */
/* */
/* DESCRIPTION */
/* */
/* Performs an End of Interrupt write */
/* */
/************************************************************************/
void epic_EOI(UINT32 eumbbar, UINT32 vector)
{
epic_EUMB_Write_Word(eumbbar+EPIC_PROC_EOI_REG, vector);
}
/************************************************************************/
/* epic_Init */
/* */
/* */
/* DESCRIPTION */
/* */
/* Initialization service for the EPIC controller. Performs a reset, */
/* clears all pending interrupts, then disables all interrupt */
/* sources. This function should be executed prior to enabling */
/* external interrupts, ie. Application_Initialize() */
/* */
/************************************************************************/
void epic_Init()
{
UINT32 eumbbar;
UINT32 temp;
UINT8 i;
UINT8 actBit;
/* Get the Embedded Utilities Memory Block
Base Address Register */
eumbbar = 0xFC000000;
epic_Write_Config_Word(0x78, eumbbar);
// eumbbar = epic_Read_Config_Word(0x00000078);
/* Set the process priority to 0 to allow interrupts */
temp = epic_EUMB_Read_Word(eumbbar+0x60080);
epic_EUMB_Write_Word(eumbbar+0x60080, 0x00000000);
/* Set the Global Conf. register to reset EPIC */
temp = epic_EUMB_Read_Word(eumbbar+EPIC_GLOBAL_REG);
temp |= 0x80000000;
epic_EUMB_Write_Word(eumbbar+EPIC_GLOBAL_REG, temp);
/* wait untill reset sequence completes */
while (epic_EUMB_Read_Word(eumbbar+EPIC_GLOBAL_REG) & 0x80000000);
/* Set to mixed mode */
epic_EUMB_Write_Word(eumbbar+EPIC_GLOBAL_REG, 0x20000000);
/* Read interrupt conf. reg */
/* Clear EICR[27] to set to direct mode */
temp = epic_EUMB_Read_Word(eumbbar+EPIC_INT_CONF_REG);
temp &= 0xf7ffffff;
epic_EUMB_Write_Word(eumbbar+EPIC_INT_CONF_REG, temp);
/* Clear all pending interrupts */
while(epic_IntAck(eumbbar) != 0xff)
{
temp = epic_IntAck(eumbbar);
epic_EOI(eumbbar, temp);
}
/* Read the spurious vector register */
temp = epic_EUMB_Read_Word(eumbbar+EPIC_SPUR_VEC_REG);
/* Disable all interrupt sources */
for(i=0; i<5;i++)
{
/* Read the IPVR of IRQ[i] */
temp = epic_EUMB_Read_Word(eumbbar+0x50200+(0x20*i));
/* Get activity bit IPVR[30] */
actBit = (temp & 0x40000000) >> 30;
if( actBit == 1)
{
/* spin here forever */
while(1);
}
/* Clear it all */
temp = 0x80000000;
epic_EUMB_Write_Word(eumbbar+0x50200+(0x20*i), temp);
}
}
/************************************************************************/
/* epic_Open_Direct_Int */
/* */
/* */
/* DESCRIPTION */
/* */
/* Wrapper for configuring the IPVR register for Direct interrupt */
/* vectors. */
/* */
/* INPUTS */
/* */
/* index identifies which IPVR to configure (4 max) */
/* mask 0 - interrupts enabled; 1 - interrupts are disabled */
/* polarity 0 - active-low or negative-edge triggered */
/* 1 - active-high or positive-edge triggered */
/* sense 0 - the external interrupt is edge-sensitive */
/* 1 - the external interrupt is level-sensitive */
/* priority 4bit interrupt priority. 0 is lowest(disabled) , */
/* 15 highest */
/* vector this value is returned from the interrupt */
/* acknolwedge register and is used by the PLUS */
/* external interrupt handler to dispatch LISRs. */
/* */
/************************************************************************/
STATUS epic_Open_Direct_Int(UINT8 index, UINT8 mask, UINT8 polarity,
UINT8 sense, UINT8 priority, UINT8 vector)
{
UINT32 eumbbar;
UINT32 temp;
STATUS status = NU_SUCCESS;
UINT8 actBit;
if((index > 4) || (index < 0))
{
/* Invalid device index */
status = NU_UNAVAILABLE;
return status;
}
/* Get the Embedded Utilities Memory Block
Base Address Register */
eumbbar = epic_Read_Config_Word(0x00000078);
temp = epic_EUMB_Read_Word(eumbbar+0x50200+(0x20*index));
/* Get activity bit IPVR[30] */
actBit = (temp & 0x40000000) >> 30;
if( actBit == 1)
{
/* There is activity on the interrupt line
VECTOR, PRIORITY, POLARITY, or SENSE should not
be changed while there is activity */
status = NU_UNAVAILABLE;
return status;
}
/* Create the IPVR value */
temp = (mask << 31) | (polarity << 23) | (sense << 22) | (priority << 16) | (vector);
/* Write the new IPVR value */
epic_EUMB_Write_Word(eumbbar+0x50200+(0x20*index), temp);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -