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

📄 intc.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
   1. Make the FIQStatus using FIQRawStatus & Enable.
   2. Set the nFiq signal
*/

static void FIQUpdate(IntCtrlState *intcs)
{
    /* Make the FIQStatus using FIQRawStatus & FIQEnable */
    intcs->myIntc.FIQStatus = intcs->myIntc.FIQRawStatus & intcs->myIntc.FIQEnable;

    /* Set the nFiq signal */
    if ( intcs->myIntc.FIQStatus )
    {
        /* There is at least ONE active interrupt ( although probably only one)
         * - so trigger FIQ 
         */
        ARMulif_SetSignal(&intcs->coredesc, RDIPropID_ARMSignal_FIQ,
                          Signal_On);
    }
    else
    {
        /* There are no active interrupt sources - clear FIQ source */
        ARMulif_SetSignal(&intcs->coredesc, RDIPropID_ARMSignal_FIQ,
                          Signal_Off);
    }
}




/* 
 ************************************************************************
 * Memory veneer functions                                              *
 * Pass on the call to the real function, then check for the watchpoint.*
 ************************************************************************
*/

 
  
/*
Function Name: INTCRegisterAccess
Parameters: 
        IntcState *intcs - IntcState pointer - in this case the
                           MemAccess handle is the IntcState - but needs to 
                           be cast to IntcState type.
        ARMword addr - the 32 bit address to access
        ARMword *word - pointer to the data word ARMulator want us to
                        fill in/read from depending on acc.
        ARMul_acc acc - the access information ( read/write, seq etc. )

Return: int  0 = Waiting
             1 = success
             -1 = Abort
             -2 = Address not decoded ** This is new for switch/peripherals

Description:  Finished the address decoding that the switch started.
        Resolves an address to a particular register - or rejects the
        access if the decode fails or is to a reserved address.
        For writes to registers FIQ/IRQUpdate is called, this ensures
        that the interrupt registers and signals reflect any changes
        immediately. 

Notes:  It may not be obvious why this code isn't in MemAccess.
        This code is kept in a separate function to ease future
        maintenance should the Memory interface be changed in the future.
*/


static int INTCRegisterAccess(IntCtrlState *intcs, ARMword addr, ARMword *word,
                              unsigned /*ARMul_acc*/ acc)
{
    unsigned long  maskedAddress = addr & 0x000001ff;
#ifdef VERBOSE_ACCESS
    printf("INTCRegisterAccess, addr:%08lx range=(%08lx,%08lx) type:%04x "
           "@data:%08lx \n",
           (unsigned long)addr,
           (unsigned long)intcs->range.lo,
              (unsigned long)intcs->range.hi,
           acc, *(ARMword*)word);
#endif
    if (ACCESS_SIZE(acc) != ACCESS_WORD)
        return PERIP_DABORT;  /* Words are all we know about */
    
    if ( ACCESS_IS_READ(acc) )
    {
    /* Read from registers */
    switch ( maskedAddress)
        {
        case 0x00:       
                *word = intcs->myIntc.IRQStatus;
                break;
        case 0x04:
                *word = intcs->myIntc.IRQRawStatus;
                break;
        case 0x08:
                *word = intcs->myIntc.IRQEnable;
                break;
        case 0x100:
                *word = intcs->myIntc.FIQStatus;
                break;
        case 0x104:
                *word = intcs->myIntc.FIQRawStatus;
                break;
        case 0x108:
                *word = intcs->myIntc.FIQEnable;
                break;
        case 0x0c:
        case 0x10:
        case 0x10c: 
                if (intcs->warn && ACCESS_IS_REAL(acc)) {    
                Hostif_ConsolePrint(intcs->hostif,
                                    "Warning - attempted read from "
                                    "Reserved INTC register address %08x\n",addr);
                }
                /* We accept the read - but always return 0 */
                *word = 0;
                break;
         default:
                return PERIP_NODECODE;  /* Failed to decode address */
        }
    }
    else
    {
    /* Write to registers */
    switch ( maskedAddress)
        {
        case 0x0:
        case 0x04:
        case 0x100:
        case 0x104:
                if (intcs->warn && ACCESS_IS_REAL(acc)) {
                Hostif_ConsolePrint(intcs->hostif,
                                    "Warning - attempted write to "
                                    "Reserved INTC register address %08x\n",addr);
                }
                /* We accept the write - but throw away the data */
                 break;
        case 0x08:
                intcs->myIntc.IRQEnable |= *word; /* IRQEnableSet - add set bits
                                                    to IRQEnable */
                IRQUpdate(intcs);
                break;
        case 0x0c:
                {
                 intcs->myIntc.IRQEnable &=  ~(*word); /* IRQEnableClear - clear
                                                the set bits in IRQEnable reg */
                IRQUpdate(intcs);
                break;
                }
        case 0x10:
            /* IRQSoft - or programmed IRQ interrupt */
            /* Only bit 1 has any effect. */
                intcs->myIntc.IRQRawStatus &= ~2;
                intcs->myIntc.IRQRawStatus |= *word & 2;                

                IRQUpdate(intcs);
                break;
        case 0x108:
                intcs->myIntc.FIQEnable |= *word; /* FIQEnableSet - add set bits
                                        to FIQEnable */
                FIQUpdate(intcs);
                break;
        case 0x10c:
                intcs->myIntc.FIQEnable &= ~(*word); /* FIQEnableClear - clear
                                                the set bits in FIQEnable reg */
                FIQUpdate(intcs);
                break;
        default:
                return PERIP_NODECODE;  /* Failed to decode address */
        }
    }
    return PERIP_OK;
}
    
/* Bus state machine
 */
static int BusState(IntCtrlState *is, ARMword addr, ARMword *word,
                    unsigned /*ARMul_acc*/ acc)
{
#ifdef VERBOSE_ACCESS
    printf("IntCtrl_Access/BusState addr:%08lx range=(%08lx,%08lx) type:%04x "
           "@data:%08lx \n",
           (unsigned long)addr,
           (unsigned long)is->range.lo,
           (unsigned long)is->range.hi,
           acc, *(ARMword*)word);
#endif
    if (!ACCESS_IS_REAL(acc)) {
        return INTCRegisterAccess(is, addr, word, acc);
    }

    if ( is->accessState == 0 )
    {
      /* Idle on access */
      if ( is->waitStates == 0)
          {
          /* No waits - do access now */
          return INTCRegisterAccess(is,addr,word,acc);
          }
      else
         {
         /* First access -but with waits - so decrement  and return 0*/
         is->waits = is->waitStates;
         is->accessState=1; 
         return PERIP_BUSY;  /* tell core to wait */
         }
    }
    else /* ( is->accessState == 1) */
    {
      /* Waiting state */
      if ( is->waits == 0)
          {
          /* No waits - do access now */
          is->accessState = 0; /* restore access state */
          /* Post wait - doing access */
          return INTCRegisterAccess(is,addr,word,acc);
          }
      else
         {
         /* Subsequent access -but with waits - so decrement  and return 0*/
         is->waits--;
         /* Subsequent wait */
         return PERIP_BUSY;  /* tell core to wait */
         }
    }  
/* accessState : 0=Idle,  1= Waiting */
}


/* Memory interface functions */
static int IntCtrl_Access(void *handle, 
                          struct ARMul_AccessRequest *req)
{
  IntCtrlState *is=(IntCtrlState *)handle;
 
  /* We have idenfitied an intc memory access */
  return BusState(is,req->req_address[0],req->req_data,
                  req->req_access_type);
}

/* Reset handler */
static void InitialiseState(IntCtrlState *intcs)
{
    intcs->myIntc.IRQStatus=0;
    intcs->myIntc.IRQRawStatus=0;
    intcs->myIntc.IRQEnable=0;     /*all interrupts disabled */
    intcs->myIntc.IRQEnableClear=0;
    intcs->myIntc.IRQSoft=0;
    intcs->myIntc.FIQStatus=0;
    intcs->myIntc.FIQRawStatus=0;
    intcs->myIntc.FIQEnable=0;
    intcs->myIntc.FIQEnableClear=0;
    intcs->myIntc.nIRQ=1;
    intcs->myIntc.nFIQ=1;
}


/*--- <SORDI STUFF> ---*/


#define SORDI_DLL_DESCRIPTION_STRING "Interrupt Controller "\
    "(a Reference Peripheral)"
#define SORDI_RDI_PROCVEC IntCtrl_AgentRDI
#include "perip_sordi.h"

#include "perip_rdi_agent.h"
    IMPLEMENT_AGENT_PROCS_NOEXE_NOMODULE(IntCtrl)
    IMPLEMENT_AGENT_PROCVEC_NOEXE(IntCtrl)

/*--- </> ---*/



/* EOF intc.c */







⌨️ 快捷键说明

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