diff options
Diffstat (limited to 'arch/cris/arch-v32/kernel/vcs_hook.c')
-rw-r--r-- | arch/cris/arch-v32/kernel/vcs_hook.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/arch/cris/arch-v32/kernel/vcs_hook.c b/arch/cris/arch-v32/kernel/vcs_hook.c new file mode 100644 index 000000000000..64d71c54c22c --- /dev/null +++ b/arch/cris/arch-v32/kernel/vcs_hook.c | |||
@@ -0,0 +1,96 @@ | |||
1 | // $Id: vcs_hook.c,v 1.2 2003/08/12 12:01:06 starvik Exp $ | ||
2 | // | ||
3 | // Call simulator hook. This is the part running in the | ||
4 | // simulated program. | ||
5 | // | ||
6 | |||
7 | #include "vcs_hook.h" | ||
8 | #include <stdarg.h> | ||
9 | #include <asm/arch-v32/hwregs/reg_map.h> | ||
10 | #include <asm/arch-v32/hwregs/intr_vect_defs.h> | ||
11 | |||
12 | #define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */ | ||
13 | #define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */ | ||
14 | |||
15 | #define HOOK_DATA(offset) ((unsigned*) HOOK_MEM_BASE_ADDR)[offset] | ||
16 | #define VHOOK_DATA(offset) ((volatile unsigned*) HOOK_MEM_BASE_ADDR)[offset] | ||
17 | #define HOOK_TRIG(funcid) do { *((unsigned *) HOOK_TRIG_ADDR) = funcid; } while(0) | ||
18 | #define HOOK_DATA_BYTE(offset) ((unsigned char*) HOOK_MEM_BASE_ADDR)[offset] | ||
19 | |||
20 | |||
21 | // ------------------------------------------------------------------ hook_call | ||
22 | int hook_call( unsigned id, unsigned pcnt, ...) { | ||
23 | va_list ap; | ||
24 | unsigned i; | ||
25 | unsigned ret; | ||
26 | #ifdef USING_SOS | ||
27 | PREEMPT_OFF_SAVE(); | ||
28 | #endif | ||
29 | |||
30 | // pass parameters | ||
31 | HOOK_DATA(0) = id; | ||
32 | |||
33 | /* Have to make hook_print_str a special case since we call with a | ||
34 | parameter of byte type. Should perhaps be a separate | ||
35 | hook_call. */ | ||
36 | |||
37 | if (id == hook_print_str) { | ||
38 | int i; | ||
39 | char *str; | ||
40 | |||
41 | HOOK_DATA(1) = pcnt; | ||
42 | |||
43 | va_start(ap, pcnt); | ||
44 | str = (char*)va_arg(ap,unsigned); | ||
45 | |||
46 | for (i=0; i!=pcnt; i++) { | ||
47 | HOOK_DATA_BYTE(8+i) = str[i]; | ||
48 | } | ||
49 | HOOK_DATA_BYTE(8+i) = 0; /* null byte */ | ||
50 | } | ||
51 | else { | ||
52 | va_start(ap, pcnt); | ||
53 | for( i = 1; i <= pcnt; i++ ) HOOK_DATA(i) = va_arg(ap,unsigned); | ||
54 | va_end(ap); | ||
55 | } | ||
56 | |||
57 | // read from mem to make sure data has propagated to memory before trigging | ||
58 | *((volatile unsigned*) HOOK_MEM_BASE_ADDR); | ||
59 | |||
60 | // trigger hook | ||
61 | HOOK_TRIG(id); | ||
62 | |||
63 | // wait for call to finish | ||
64 | while( VHOOK_DATA(0) > 0 ) {} | ||
65 | |||
66 | // extract return value | ||
67 | |||
68 | ret = VHOOK_DATA(1); | ||
69 | |||
70 | #ifdef USING_SOS | ||
71 | PREEMPT_RESTORE(); | ||
72 | #endif | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | unsigned | ||
77 | hook_buf(unsigned i) | ||
78 | { | ||
79 | return (HOOK_DATA(i)); | ||
80 | } | ||
81 | |||
82 | void print_str( const char *str ) { | ||
83 | int i; | ||
84 | for (i=1; str[i]; i++); /* find null at end of string */ | ||
85 | hook_call(hook_print_str, i, str); | ||
86 | } | ||
87 | |||
88 | // --------------------------------------------------------------- CPU_KICK_DOG | ||
89 | void CPU_KICK_DOG(void) { | ||
90 | (void) hook_call( hook_kick_dog, 0 ); | ||
91 | } | ||
92 | |||
93 | // ------------------------------------------------------- CPU_WATCHDOG_TIMEOUT | ||
94 | void CPU_WATCHDOG_TIMEOUT( unsigned t ) { | ||
95 | (void) hook_call( hook_dog_timeout, 1, t ); | ||
96 | } | ||