Merge branch 'r6040' of git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev...
[sfrench/cifs-2.6.git] / arch / cris / arch-v32 / mach-a3 / vcs_hook.c
1 /*
2  * Simulator hook mechanism
3  */
4
5 #include "vcs_hook.h"
6 #include <asm/io.h>
7 #include <stdarg.h>
8
9 #define HOOK_TRIG_ADDR      0xb7000000
10 #define HOOK_MEM_BASE_ADDR  0xce000000
11
12 static volatile unsigned *hook_base;
13
14 #define HOOK_DATA(offset) hook_base[offset]
15 #define VHOOK_DATA(offset) hook_base[offset]
16 #define HOOK_TRIG(funcid) \
17         do { \
18                 *((unsigned *) HOOK_TRIG_ADDR) = funcid; \
19         } while (0)
20 #define HOOK_DATA_BYTE(offset) ((unsigned char *)hook_base)[offset]
21
22 static void hook_init(void)
23 {
24         static int first = 1;
25         if (first) {
26                 first = 0;
27                 hook_base = ioremap(HOOK_MEM_BASE_ADDR, 8192);
28         }
29 }
30
31 static unsigned hook_trig(unsigned id)
32 {
33         unsigned ret;
34
35         /* preempt_disable(); */
36
37         /* Dummy read from mem to make sure data has propagated to memory
38          * before trigging */
39         ret = *hook_base;
40
41         /* trigger hook */
42         HOOK_TRIG(id);
43
44         /* wait for call to finish */
45         while (VHOOK_DATA(0) > 0) ;
46
47         /* extract return value */
48
49         ret = VHOOK_DATA(1);
50
51         return ret;
52 }
53
54 int hook_call(unsigned id, unsigned pcnt, ...)
55 {
56         va_list ap;
57         int i;
58         unsigned ret;
59
60         hook_init();
61
62         HOOK_DATA(0) = id;
63
64         va_start(ap, pcnt);
65         for (i = 1; i <= pcnt; i++)
66                 HOOK_DATA(i) = va_arg(ap, unsigned);
67         va_end(ap);
68
69         ret = hook_trig(id);
70
71         return ret;
72 }
73
74 int hook_call_str(unsigned id, unsigned size, const char *str)
75 {
76         int i;
77         unsigned ret;
78
79         hook_init();
80
81         HOOK_DATA(0) = id;
82         HOOK_DATA(1) = size;
83
84         for (i = 0; i < size; i++)
85                 HOOK_DATA_BYTE(8 + i) = str[i];
86         HOOK_DATA_BYTE(8 + i) = 0;
87
88         ret = hook_trig(id);
89
90         return ret;
91 }
92
93 void print_str(const char *str)
94 {
95         int i;
96         /* find null at end of string */
97         for (i = 1; str[i]; i++) ;
98         hook_call(hook_print_str, i, str);
99 }
100
101 void CPU_WATCHDOG_TIMEOUT(unsigned t)
102 {
103 }