aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-x86/x86_32/asm_defns.h
blob: a04033e1b98deffe1e64403033fbaad13b995b16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef __X86_32_ASM_DEFNS_H__
#define __X86_32_ASM_DEFNS_H__

/* Maybe auto-generate the following two cases (quoted vs. unquoted). */
#ifndef __ASSEMBLY__

#define __SAVE_ALL_PRE                                                  \
        "cld;"                                                          \
        "pushl %eax;"                                                   \
        "pushl %ebp;"                                                   \
        "pushl %edi;"                                                   \
        "pushl %esi;"                                                   \
        "pushl %edx;"                                                   \
        "pushl %ecx;"                                                   \
        "pushl %ebx;"                                                   \
        "testl $"STR(X86_EFLAGS_VM)","STR(UREGS_eflags)"(%esp);"        \
        "jz 2f;"                                                        \
        "call setup_vm86_frame;"                                        \
        "jmp 3f;"                                                       \
        "2:testb $3,"STR(UREGS_cs)"(%esp);"                             \
        "jz 1f;"                                                        \
        "movl %ds,"STR(UREGS_ds)"(%esp);"                               \
        "movl %es,"STR(UREGS_es)"(%esp);"                               \
        "movl %fs,"STR(UREGS_fs)"(%esp);"                               \
        "movl %gs,"STR(UREGS_gs)"(%esp);"                               \
        "3:"

#define SAVE_ALL_NOSEGREGS(_reg)                \
        __SAVE_ALL_PRE                          \
        "1:"

#define SET_XEN_SEGMENTS(_reg)                                  \
        "movl $("STR(__HYPERVISOR_DS)"),%e"STR(_reg)"x;"        \
        "movl %e"STR(_reg)"x,%ds;"                              \
        "movl %e"STR(_reg)"x,%es;"

#define SAVE_ALL(_reg)                          \
        __SAVE_ALL_PRE                          \
        SET_XEN_SEGMENTS(_reg)                  \
        "1:"

#else

#define __SAVE_ALL_PRE                                  \
        cld;                                            \
        pushl %eax;                                     \
        pushl %ebp;                                     \
        pushl %edi;                                     \
        pushl %esi;                                     \
        pushl %edx;                                     \
        pushl %ecx;                                     \
        pushl %ebx;                                     \
        testl $X86_EFLAGS_VM,UREGS_eflags(%esp);        \
        jz 2f;                                          \
        call setup_vm86_frame;                          \
        jmp 3f;                                         \
        2:testb $3,UREGS_cs(%esp);                      \
        jz 1f;                                          \
        movl %ds,UREGS_ds(%esp);                        \
        movl %es,UREGS_es(%esp);                        \
        movl %fs,UREGS_fs(%esp);                        \
        movl %gs,UREGS_gs(%esp);                        \
        3:

#define SAVE_ALL_NOSEGREGS(_reg)                \
        __SAVE_ALL_PRE                          \
        1:

#define SET_XEN_SEGMENTS(_reg)                          \
        movl $(__HYPERVISOR_DS),%e ## _reg ## x;        \
        movl %e ## _reg ## x,%ds;                       \
        movl %e ## _reg ## x,%es;

#define SAVE_ALL(_reg)                          \
        __SAVE_ALL_PRE                          \
        SET_XEN_SEGMENTS(_reg)                  \
        1:

#ifdef PERF_COUNTERS
#define PERFC_INCR(_name,_idx)                          \
    lock incl perfcounters+_name(,_idx,4)
#else
#define PERFC_INCR(_name,_idx)
#endif

#endif

#define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
#define XBUILD_SMP_INTERRUPT(x,v)               \
asmlinkage void x(void);                        \
__asm__(                                        \
    "\n"__ALIGN_STR"\n"                         \
    STR(x) ":\n\t"                              \
    "pushl $"#v"<<16\n\t"                       \
    SAVE_ALL(a)                                 \
    "call "STR(smp_##x)"\n\t"                   \
    "jmp ret_from_intr\n");

#define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v)
#define XBUILD_SMP_TIMER_INTERRUPT(x,v)         \
asmlinkage void x(struct cpu_user_regs * regs); \
__asm__(                                        \
"\n"__ALIGN_STR"\n"                             \
STR(x) ":\n\t"                                  \
    "pushl $"#v"<<16\n\t"                       \
    SAVE_ALL(a)                                 \
    "movl %esp,%eax\n\t"                        \
    "pushl %eax\n\t"                            \
    "call "STR(smp_##x)"\n\t"                   \
    "addl $4,%esp\n\t"                          \
    "jmp ret_from_intr\n");

#define BUILD_COMMON_IRQ()                      \
__asm__(                                        \
    "\n" __ALIGN_STR"\n"                        \
    "common_interrupt:\n\t"                     \
    SAVE_ALL(a)                                 \
    "movl %esp,%eax\n\t"                        \
    "pushl %eax\n\t"                            \
    "call " STR(do_IRQ) "\n\t"                  \
    "addl $4,%esp\n\t"                          \
    "jmp ret_from_intr\n");

#define IRQ_NAME2(nr) nr##_interrupt(void)
#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)

#define BUILD_IRQ(nr)                           \
asmlinkage void IRQ_NAME(nr);                   \
__asm__(                                        \
"\n"__ALIGN_STR"\n"                             \
STR(IRQ) #nr "_interrupt:\n\t"                  \
    "pushl $"#nr"<<16\n\t"                      \
    "jmp common_interrupt");

#endif /* __X86_32_ASM_DEFNS_H__ */