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

📄 projectx.c

📁 ARM ADS 程序示例(源码),coprotest.c,partest.c,interrupts.c
💻 C
字号:
/* ProjectX.c - Exception Generator Memory Model
 */

#include "minperip.h"
#include "armul_mem.h"

static int ProjectX_Access(void *handle, 
                        struct ARMul_AccessRequest *req);

static void clearIrq( void *handle );
static void clearFiq( void *handle );
static void setIrq( void *handle );
static void setFiq( void *handle );

#define ModelName (tag_t)"ProjectX"

#if !defined(NDEBUG)
# if 1
# else
#  define VERBOSE
# endif
#endif

BEGIN_STATE_DECL(ProjectX)

	/* store details of peripheral registration */
	ARMul_BusPeripAccessRegistration my_bpar;

END_STATE_DECL(ProjectX)

BEGIN_INIT(ProjectX)
Hostif_PrettyPrint(state->hostif, config, ", ProjectX");
{
	/* Note that BEGIN_INIT macro defines ProjectXState *state     */
	
	unsigned err;
	
  	err = RDIError_NoError;
  	
    /* Provide access-callback */
    state->my_bpar.access_func = ProjectX_Access;
    state->my_bpar.access_handle = state;
    state->my_bpar.capabilities = PeripAccessCapability_Minimum;

    err = ARMulif_ReadBusRange(&state->coredesc, state->hostif,
                         ToolConf_FlatChild(config, (tag_t)"RANGE"),
                         &state->my_bpar,  
                         0x200000,0x0D,"");

    err = state->my_bpar.bus->bus_registerPeripFunc(BusRegAct_Insert, 
                                                    &state->my_bpar);
    if (err)
        return err;
}
END_INIT(ProjectX)


BEGIN_EXIT(ProjectX)
END_EXIT(ProjectX)

/* MemAccess functions */
static int ProjectX_Access(void *handle, 
                        struct ARMul_AccessRequest *req)
{
    ARMWord address = req->req_address[0];
    ARMWord *data = req->req_data;
    unsigned type = req->req_access_type;
    ProjectXState *state=(ProjectXState *)handle;
    ARMTime Now, delay, nextEventTime;
   
    assert(address >= state->my_bpar.range[0].lo && address <= state->my_bpar.range[0].hi);
    
    if( (address == 0x200000) && acc_WRITE(type) ) {
    	switch(*data) {
    		case 1:
    			Hostif_ConsolePrint( state->hostif, "IRQ requested\n" );
    			ARMulif_SetSignal( &(state->coredesc), RDIPropID_ARMSignal_IRQ, TRUE );
    			break;
    			
    		case 2:
    			Hostif_ConsolePrint( state->hostif, "FIQ requested\n" );
    			ARMulif_SetSignal( &(state->coredesc), RDIPropID_ARMSignal_FIQ, TRUE );
    			break;
    	}
			
		Hostif_ConsolePrint( state->hostif, "Write to 0x200000 - value = %08x\n", *data );
		return PERIP_OK;
	}
	
	/* IRQ scheduling */
	if( (address == 0x200004) && acc_WRITE(type) ) {
		delay = *data;
    	Hostif_ConsolePrint( state->hostif, "IRQ scheduled in %d cycles\n", delay );
    	
    	Now = ARMulif_Time(&state->coredesc);
		nextEventTime = Now + delay;
  	
		ARMulif_ScheduleNewTimedCallback(
   			&state->coredesc, setIrq, state, nextEventTime, 0 );
   		
   		/* DEBUG schedule event for the same time to see which happens
   		ARMulif_ScheduleNewTimedCallback(
   			&state->coredesc, dummyCallback, state, nextEventTime, 0 );
   			
   		 */	
   		
   		Hostif_ConsolePrint( state->hostif, "Write to 0x200004 - value = %08x\n", delay );	

		return PERIP_OK;
	}
	
	/* FIQ scheduling */
	if( (address == 0x200008) && acc_WRITE(type) ) {
		delay = *data;
    	Hostif_ConsolePrint( state->hostif, "FIQ scheduled in %d cycles\n", delay );
    	
    	Now = ARMulif_Time(&state->coredesc);
		nextEventTime = Now + delay;
  	
		ARMulif_ScheduleNewTimedCallback(
   			&state->coredesc, setFiq, state, nextEventTime, 0 );
   			
   		Hostif_ConsolePrint( state->hostif, "Write to 0x200008 - value = %08x\n", delay );	

		return PERIP_OK;
	}
	
	/* Interrupt Clearing */
	if( (address == 0x20000C) && acc_WRITE(type) ) {
    	switch(*data) {
    		case 1:
    			Hostif_ConsolePrint( state->hostif, "IRQ cleared\n" );
    			clearIrq(state);
    			break;
    			
    		case 2:
    			Hostif_ConsolePrint( state->hostif, "FIQ cleared\n" );
    			clearFiq(state);
    			break;
    	}
			
		Hostif_ConsolePrint( state->hostif, "Write to 0x20000C - value = %08x\n", *data );
		return 1;
	}
	
	/* did not decode the address */
	return PERIP_NODECODE;
}

static void clearIrq( void *handle )
{
	ProjectXState *state = (ProjectXState *) handle;
	ARMulif_SetSignal( &(state->coredesc), RDIPropID_ARMSignal_IRQ, FALSE );
}

static void clearFiq( void *handle )
{
	ProjectXState *state = (ProjectXState *) handle;
	ARMulif_SetSignal( &(state->coredesc), RDIPropID_ARMSignal_FIQ, FALSE );
}

static void setIrq( void *handle )
{
	ProjectXState *state = (ProjectXState *) handle;
	/* DEBUG */
	/* Hostif_ConsolePrint( state->hostif, "setIrq called. cycles: %d\n", ARMulif_Time(&state->coredesc) ); */
	ARMulif_SetSignal( &(state->coredesc), RDIPropID_ARMSignal_IRQ, TRUE );
}

static void setFiq( void *handle )
{
	ProjectXState *state = (ProjectXState *) handle;
	/* DEBUG */
	/*Hostif_ConsolePrint( state->hostif, "setFiq called. cycles: %d\n", ARMulif_Time(&state->coredesc) ); */
	ARMulif_SetSignal( &(state->coredesc), RDIPropID_ARMSignal_FIQ, TRUE );
}

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

#define SORDI_DLL_NAME_STRING "ProjectX"
#define SORDI_DLL_DESCRIPTION_STRING "Exception Generator model"
#define SORDI_RDI_PROCVEC ProjectX_AgentRDI
#include "perip_sordi.h"

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

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




/* EOF ProjectX.c */








⌨️ 快捷键说明

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