|
|
1.1 root 1: /*
2: * Copyright (C) 2006-2009 Free Software Foundation
3: *
4: * This program is free software ; you can redistribute it and/or modify
5: * it under the terms of the GNU General Public License as published by
6: * the Free Software Foundation ; either version 2 of the License, or
7: * (at your option) any later version.
8: *
9: * This program is distributed in the hope that it will be useful,
10: * but WITHOUT ANY WARRANTY ; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: * GNU General Public License for more details.
13: *
14: * You should have received a copy of the GNU General Public License
15: * along with the program ; if not, write to the Free Software
16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17: */
18:
19: #include <mach/machine/asm.h>
20:
21: #include <i386/i386asm.h>
22: #include <i386/cpu_number.h>
23: #include <i386/xen.h>
24:
25: .data 2
26: int_active:
27: .long 0
28:
29:
30: .text
31: .globl hyp_callback, hyp_failsafe_callback
32: P2ALIGN(TEXT_ALIGN)
33: hyp_callback:
34: pushl %eax
35: jmp EXT(all_intrs)
36:
37: ENTRY(interrupt)
38: incl int_active /* currently handling interrupts */
39: call EXT(hyp_c_callback) /* call generic interrupt routine */
40: decl int_active /* stopped handling interrupts */
41: sti
42: ret
43:
44: /* FIXME: if we're _very_ unlucky, we may be re-interrupted, filling stack
45: *
46: * Far from trivial, see mini-os. That said, maybe we could just, before poping
47: * everything (which is _not_ destructive), save sp into a known place and use
48: * it+jmp back?
49: *
50: * Mmm, there seems to be an iret hypcall that does exactly what we want:
51: * perform iret, and if IF is set, clear the interrupt mask.
52: */
53:
54: /* Pfff, we have to check pending interrupts ourselves. Some other DomUs just make an hypercall for retriggering the irq. Not sure it's really easier/faster */
55: ENTRY(hyp_sti)
56: pushl %ebp
57: movl %esp, %ebp
58: _hyp_sti:
59: movb $0,hyp_shared_info+CPU_CLI /* Enable interrupts */
60: cmpl $0,int_active /* Check whether we were already checking pending interrupts */
61: jz 0f
62: popl %ebp
63: ret /* Already active, just return */
64: 0:
65: /* Not active, check pending interrupts by hand */
66: /* no memory barrier needed on x86 */
67: cmpb $0,hyp_shared_info+CPU_PENDING
68: jne 0f
69: popl %ebp
70: ret
71: 0:
72: movb $0xff,hyp_shared_info+CPU_CLI
73: 1:
74: pushl %eax
75: pushl %ecx
76: pushl %edx
77: incl int_active /* currently handling interrupts */
78:
79: pushl $0
80: pushl $0
81: call EXT(hyp_c_callback)
82: popl %edx
83: popl %edx
84:
85: popl %edx
86: popl %ecx
87: popl %eax
88: decl int_active /* stopped handling interrupts */
89: cmpb $0,hyp_shared_info+CPU_PENDING
90: jne 1b
91: jmp _hyp_sti
92:
93: /* Hypervisor failed to reload segments. Dump them. */
94: hyp_failsafe_callback:
95: #if 1
96: /* load sane segments */
97: mov %ss, %ax
98: mov %ax, %ds
99: mov %ax, %es
100: mov %ax, %fs
101: mov %ax, %gs
102: push %esp
103: call EXT(hyp_failsafe_c_callback)
104: #else
105: popl %ds
106: popl %es
107: popl %fs
108: popl %gs
109: iret
110: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.