104 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Simulator hook mechanism
 | 
						|
 */
 | 
						|
 | 
						|
#include "vcs_hook.h"
 | 
						|
#include <asm/io.h>
 | 
						|
#include <stdarg.h>
 | 
						|
 | 
						|
#define HOOK_TRIG_ADDR      0xb7000000
 | 
						|
#define HOOK_MEM_BASE_ADDR  0xce000000
 | 
						|
 | 
						|
static volatile unsigned *hook_base;
 | 
						|
 | 
						|
#define HOOK_DATA(offset) hook_base[offset]
 | 
						|
#define VHOOK_DATA(offset) hook_base[offset]
 | 
						|
#define HOOK_TRIG(funcid) \
 | 
						|
	do { \
 | 
						|
		*((unsigned *) HOOK_TRIG_ADDR) = funcid; \
 | 
						|
	} while (0)
 | 
						|
#define HOOK_DATA_BYTE(offset) ((unsigned char *)hook_base)[offset]
 | 
						|
 | 
						|
static void hook_init(void)
 | 
						|
{
 | 
						|
	static int first = 1;
 | 
						|
	if (first) {
 | 
						|
		first = 0;
 | 
						|
		hook_base = ioremap(HOOK_MEM_BASE_ADDR, 8192);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static unsigned hook_trig(unsigned id)
 | 
						|
{
 | 
						|
	unsigned ret;
 | 
						|
 | 
						|
	/* preempt_disable(); */
 | 
						|
 | 
						|
	/* Dummy read from mem to make sure data has propagated to memory
 | 
						|
	 * before trigging */
 | 
						|
	ret = *hook_base;
 | 
						|
 | 
						|
	/* trigger hook */
 | 
						|
	HOOK_TRIG(id);
 | 
						|
 | 
						|
	/* wait for call to finish */
 | 
						|
	while (VHOOK_DATA(0) > 0) ;
 | 
						|
 | 
						|
	/* extract return value */
 | 
						|
 | 
						|
	ret = VHOOK_DATA(1);
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
int hook_call(unsigned id, unsigned pcnt, ...)
 | 
						|
{
 | 
						|
	va_list ap;
 | 
						|
	int i;
 | 
						|
	unsigned ret;
 | 
						|
 | 
						|
	hook_init();
 | 
						|
 | 
						|
	HOOK_DATA(0) = id;
 | 
						|
 | 
						|
	va_start(ap, pcnt);
 | 
						|
	for (i = 1; i <= pcnt; i++)
 | 
						|
		HOOK_DATA(i) = va_arg(ap, unsigned);
 | 
						|
	va_end(ap);
 | 
						|
 | 
						|
	ret = hook_trig(id);
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
int hook_call_str(unsigned id, unsigned size, const char *str)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	unsigned ret;
 | 
						|
 | 
						|
	hook_init();
 | 
						|
 | 
						|
	HOOK_DATA(0) = id;
 | 
						|
	HOOK_DATA(1) = size;
 | 
						|
 | 
						|
	for (i = 0; i < size; i++)
 | 
						|
		HOOK_DATA_BYTE(8 + i) = str[i];
 | 
						|
	HOOK_DATA_BYTE(8 + i) = 0;
 | 
						|
 | 
						|
	ret = hook_trig(id);
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
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);
 | 
						|
}
 | 
						|
 | 
						|
void CPU_WATCHDOG_TIMEOUT(unsigned t)
 | 
						|
{
 | 
						|
}
 |