2008-01-25 17:28:10 +01:00
/*
* Call simulator hook . This is the part running in the
* simulated program .
*/
2007-11-29 17:11:23 +01:00
# include "vcs_hook.h"
# include <stdarg.h>
2008-10-21 17:45:58 +02:00
# include <arch-v32/hwregs/reg_map.h>
# include <arch-v32/hwregs/intr_vect_defs.h>
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
# define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */
# define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
# define HOOK_DATA(offset) ((unsigned *)HOOK_MEM_BASE_ADDR)[offset]
# define VHOOK_DATA(offset) ((volatile unsigned *)HOOK_MEM_BASE_ADDR)[offset]
# define HOOK_TRIG(funcid) \
do { \
* ( ( unsigned * ) HOOK_TRIG_ADDR ) = funcid ; \
} while ( 0 )
# define HOOK_DATA_BYTE(offset) ((unsigned char *)HOOK_MEM_BASE_ADDR)[offset]
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
int hook_call ( unsigned id , unsigned pcnt , . . . )
{
va_list ap ;
unsigned i ;
unsigned ret ;
2007-11-29 17:11:23 +01:00
# ifdef USING_SOS
2008-01-25 17:28:10 +01:00
PREEMPT_OFF_SAVE ( ) ;
2007-11-29 17:11:23 +01:00
# endif
2008-01-25 17:28:10 +01:00
/* pass parameters */
HOOK_DATA ( 0 ) = id ;
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
/* Have to make hook_print_str a special case since we call with a
* parameter of byte type . Should perhaps be a separate
* hook_call . */
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
if ( id = = hook_print_str ) {
int i ;
char * str ;
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
HOOK_DATA ( 1 ) = pcnt ;
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
va_start ( ap , pcnt ) ;
str = ( char * ) va_arg ( ap , unsigned ) ;
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
for ( i = 0 ; i ! = pcnt ; i + + )
HOOK_DATA_BYTE ( 8 + i ) = str [ i ] ;
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
HOOK_DATA_BYTE ( 8 + i ) = 0 ; /* null byte */
} else {
va_start ( ap , pcnt ) ;
for ( i = 1 ; i < = pcnt ; i + + )
HOOK_DATA ( i ) = va_arg ( ap , unsigned ) ;
va_end ( ap ) ;
}
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
/* read from mem to make sure data has propagated to memory before
* trigging */
ret = * ( ( volatile unsigned * ) HOOK_MEM_BASE_ADDR ) ;
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
/* trigger hook */
HOOK_TRIG ( id ) ;
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
/* wait for call to finish */
while ( VHOOK_DATA ( 0 ) > 0 ) ;
2007-11-29 17:11:23 +01:00
2008-01-25 17:28:10 +01:00
/* extract return value */
ret = VHOOK_DATA ( 1 ) ;
2007-11-29 17:11:23 +01:00
# ifdef USING_SOS
2008-01-25 17:28:10 +01:00
PREEMPT_RESTORE ( ) ;
2007-11-29 17:11:23 +01:00
# endif
2008-01-25 17:28:10 +01:00
return ret ;
2007-11-29 17:11:23 +01:00
}
2008-01-25 17:28:10 +01:00
unsigned hook_buf ( unsigned i )
2007-11-29 17:11:23 +01:00
{
2008-01-25 17:28:10 +01:00
return ( HOOK_DATA ( i ) ) ;
2007-11-29 17:11:23 +01:00
}
2008-01-25 17:28:10 +01:00
void print_str ( const char * str )
{
int i ;
/* find null at end of string */
for ( i = 1 ; str [ i ] ; i + + ) ;
hook_call ( hook_print_str , i , str ) ;
2007-11-29 17:11:23 +01:00
}
2008-01-25 17:28:10 +01:00
void CPU_KICK_DOG ( void )
{
( void ) hook_call ( hook_kick_dog , 0 ) ;
2007-11-29 17:11:23 +01:00
}
2008-01-25 17:28:10 +01:00
void CPU_WATCHDOG_TIMEOUT ( unsigned t )
{
( void ) hook_call ( hook_dog_timeout , 1 , t ) ;
2007-11-29 17:11:23 +01:00
}
2008-01-25 17:28:10 +01:00