| /* |
| * 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) |
| { |
| } |