📄 watchdog.c
字号:
}
}
else
{
/* Was sensible - so allows user period to be written */
ts->peripheral1.WatchPeriod = *word;
}
break;
case 0x08:
if ( *word < 2000 )
{
/* Disallow excessively short watchdog periods */
ts->peripheral1.WatchPeriod2 = 5000;
if ( ts->warn == TRUE) {
Hostif_ConsolePrint(ts->hostif,"Warning - Attempt to write value < 2000 as watchdog timeout period 2\n");
Hostif_ConsolePrint(ts->hostif,"Defaulted to 5000 as timeout period 2.\n");
}
}
else
{
/* Was sensible - so allows user period to be written */
ts->peripheral1.WatchPeriod2 = *word;
}
break;
/* >>>>>>>>>>>>Modify Me<<<<<<<<<<<<< */
/* See note 10 */
/* Reserved */
case 0x0c:
if ( ts->warn == TRUE) {
Hostif_ConsolePrint(ts->hostif,"Warning - accessed Reserved WDOG register address %08x\n",addr);
}
break;
default:
return PERIP_NODECODE; /* Failed to decode address */
}
}
}
return PERIP_OK; /* Successful */
}
/* Bus state machine */
static int BusState(
WatchdogState *ts, ARMword addr, ARMword *word,ARMul_acc acc)
{
if (!acc_ACCOUNT(acc)) {
return RegisterAccess(ts, addr, word, acc);
}
if ( ts->accessState == 0 )
{
/* Idle on access */
if ( ts->waitStates == 0)
{
/* No waits - do access now */
return RegisterAccess(ts,addr,word,acc);
}
else
{
/* First access -but with waits - so decrement and return 0*/
ts->waits = ts->waitStates;
ts->accessState=1;
return PERIP_BUSY; /* tell core to wait */
}
}
else /* ts->accessState == 1) */
{
/* Waiting state */
if ( ts->waits == 0)
{
/* No waits - do access now */
ts->accessState = 0; /* restore access state */
/* Post wait - doing access */
return RegisterAccess(ts,addr,word,acc);
}
else
{
/* Subsequent access -but with waits - so decrement and return 0*/
ts->waits--;
/* Subsequent wait */
return PERIP_BUSY; /* tell core to wait */
}
}
/* accessState : 0=Idle, 1= Waiting */
}
/* MemAccess functions */
static int Watchdog_Access(void *handle,
struct ARMul_AccessRequest *req)
{
ARMWord addr = req->req_address[0];
ARMWord *data = req->req_data;
unsigned acctype = req->req_access_type;
WatchdogState *ts=(WatchdogState *)handle;
assert(addr >= ts->my_bpar.range[0].lo && \
addr <= ts->my_bpar.range[0].hi);
return BusState(ts,addr,data,acctype);
}
static unsigned Watchdog_ConfigEvents(void *handle, void *data)
{
WatchdogState *ts = (WatchdogState*)handle;
ARMul_Event *evt = data;
if (evt->event == ConfigEvent_Reset)
{
/* We are only interested in the Reset event */
Hostif_PrettyPrint(ts->hostif,ts->config,"Watchdog Reset ");
/* If there is an event then kill it */
if ( ts->peripheral1.inCountdown ==1 )
{
if ( ts->peripheral1.nextIRQEventTime != 0)
{
ARMulif_DescheduleTimedFunction(&ts->coredesc,
ts->peripheral1.nextIRQEvent_killhandle);
ts->peripheral1.nextIRQEventTime=0;
/* On reset we are NOT on countdown to doom */
ts->peripheral1.inCountdown =0;
}
}
else
{
if ( ts->peripheral1.nextEventTime != 0)
{
if( ts->peripheral1.nextIRQEvent_killhandle != NULL)
ARMulif_DescheduleTimedFunction(&ts->coredesc,
ts->peripheral1.nextIRQEvent_killhandle);
ts->peripheral1.nextEventTime=0;
}
}
/* Kick off the first wdog event */
if ( ts->peripheral1.runOnStartup == TRUE)
{
unsigned long delay;
delay = ts->peripheral1.WatchPeriod;
/* We must start wdog on startup */
Hostif_PrettyPrint(ts->hostif,ts->config," (running on startup).");
/*Schedule the event and also record the timeout time
* so that we can rescehdule */
{ ARMTime Now = ARMulif_Time(&ts->coredesc);
ARMTime when = Now + delay;
ts->peripheral1.nextEventTime = when;
ts->peripheral1.nextEvent_killhandle =
ARMulif_ScheduleNewTimedCallback(
&ts->coredesc, WatchdogTimeout, ts, when, 0);
}
}
else
{
Hostif_PrettyPrint(ts->hostif,ts->config," (not running).");
}
} /* end if which & ARMul_InterruptUpcallReset */
return FALSE;
}
BEGIN_INIT(Watchdog)
{
WatchdogState *ts = state;
unsigned int value1; /* Key value local*/
unsigned int value2; /* WATCHPERIOD local */
unsigned int value3; /* IRQPERIOD local */
int value4; /* Interrupt number */
int startup, contafter;
int warn;
int waits;
Hostif_PrettyPrint(ts->hostif,ts->config,", Watchdog");
/*
Look up the watchdog parameters from armul.cnf
*/
value1 = ToolConf_DLookupUInt(config, ARMulCnf_KeyValue, 0xA1B2C2D4);
value2 = ToolConf_DLookupUInt(config, ARMulCnf_WatchPeriod, 500000);
value3 = ToolConf_DLookupUInt(config, ARMulCnf_IRQPeriod,10000);
value4 = ToolConf_DLookupUInt(config, ARMulCnf_IntNumber,16);
startup = ToolConf_DLookupBool(config, ARMulCnf_StartOnReset, FALSE);
contafter = ToolConf_DLookupBool(config, ARMulCnf_RunAfterBark,FALSE);
warn = ToolConf_DLookupBool(config, ARMulCnf_Warn, FALSE);
waits = ToolConf_DLookupUInt(config, ARMulCnf_Waits, 1);
/* If warning is enabled then announce it */
if ( warn == TRUE) Hostif_PrettyPrint(ts->hostif,ts->config," (warn on)");
if ( waits < 0 || waits > 30)
{
Hostif_PrettyPrint(ts->hostif,ts->config,"(Timer Error: Invalid wait state value - defaulting to zero waits)");
waits = 0;
}
/* Fill in other entries */
/* record whether we warn about dubious register accesses or not */
ts->warn = warn;
ts->waitStates = waits;
ts->waits=0;
ts->accessState=0; /* Reset to idle */
/* Register our peripheral-access-function. */
{ unsigned err = RDIError_NoError;
state->my_bpar.access_func = Watchdog_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,
0xb0000000,0x4,""); /* Defaults from old .cnf */
err = state->my_bpar.bus->bus_registerPeripFunc(BusRegAct_Insert,
&state->my_bpar);
if (err)
return err;
}
/* Set up the WatchdogState peripheral parameters */
ts->peripheral1.KeyValue= value1;
if ( value2 < 5000 )
{
ts->peripheral1.WatchPeriod=5000;
}
else
{
ts->peripheral1.WatchPeriod=value2;
}
/* Set up the IRQ timeout period */
if ( value3 < 1000 )
{
ts->peripheral1.WatchPeriod2=1000;
}
else
{
ts->peripheral1.WatchPeriod2=value3;
}
/* Set up the interrupt number */
ts->peripheral1.interruptNumber = value4;
/* Record how we behave on timeout bark ;
we can either halt on say tough - you cannot proceed
or we can warn, halt but allow to continue
*/
ts->peripheral1.continueOnTimeout = contafter;
/* Record whether we start running on reset */
ts->peripheral1.runOnStartup = startup;
/* Get the Interrupt controller interface structure pointer.
It is important that the interrupt controller is installed
before any peripherals that use it - otherwise the interface
will not be available at initialisation time.
It is possible to install the interface later - but this
pollutes the peripheral emulation code with initialisation
functionality.
*/
ts->intcInterface = ARMulif_GetInterruptController(&ts->coredesc);
ts->peripheral1.nextEventTime = 0; /* Should be zero until we have done 1st one */
/* Display appropriate startup banner message */
if ( ts->peripheral1.runOnStartup == TRUE)
{
Hostif_PrettyPrint(ts->hostif,ts->config," (running on startup)");
}
else
{
Hostif_PrettyPrint(ts->hostif,ts->config," (not running)");
}
ARMulif_InstallEventHandler(&state->coredesc,
ConfigEventSel,
Watchdog_ConfigEvents, state);
ARMulif_InstallUnkRDIInfoHandler(&state->coredesc,
RDI_info,state);
}
END_INIT(Watchdog)
BEGIN_EXIT(Watchdog)
END_EXIT(Watchdog)
/*--- <SORDI STUFF> ---*/
#define SORDI_DLL_NAME_STRING "Watchdog"
#define SORDI_DLL_DESCRIPTION_STRING "Watchdog Timer (test only)"
#define SORDI_RDI_PROCVEC Watchdog_AgentRDI
#include "perip_sordi.h"
#include "perip_rdi_agent.h"
IMPLEMENT_AGENT_PROCS_NOEXE_NOMODULE(Watchdog)
IMPLEMENT_AGENT_PROCVEC_NOEXE(Watchdog)
/*--- </> ---*/
/* EOF watchdog.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -