debuggers.hg

view netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c @ 2632:a4fbb98f00cb

bitkeeper revision 1.1159.1.202 (41616cc2-ciBh_VkJKwmQaCL6BEU6Q)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Mon Oct 04 15:31:14 2004 +0000 (2004-10-04)
parents ab0042a6d724 aa75f00efa54
children 0a4b76b6b5a0
line source
1 /* $NetBSD: hypervisor_machdep.c,v 1.2.2.2 2004/06/17 09:23:13 tron Exp $ */
3 /*
4 *
5 * Copyright (c) 2004 Christian Limpach.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Christian Limpach.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
34 /******************************************************************************
35 * hypervisor.c
36 *
37 * Communication to/from hypervisor.
38 *
39 * Copyright (c) 2002-2004, K A Fraser
40 *
41 * Permission is hereby granted, free of charge, to any person obtaining a copy
42 * of this software and associated documentation files (the "Software"), to
43 * deal in the Software without restriction, including without limitation the
44 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
45 * sell copies of the Software, and to permit persons to whom the Software is
46 * furnished to do so, subject to the following conditions:
47 *
48 * The above copyright notice and this permission notice shall be included in
49 * all copies or substantial portions of the Software.
50 *
51 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
56 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
57 * DEALINGS IN THE SOFTWARE.
58 */
61 #include <sys/cdefs.h>
62 __KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.2.2.2 2004/06/17 09:23:13 tron Exp $");
64 #include <sys/cdefs.h>
65 #include <sys/param.h>
66 #include <sys/systm.h>
68 #include <machine/xen.h>
69 #include <machine/hypervisor.h>
70 #include <machine/evtchn.h>
72 /*
73 * Force a proper event-channel callback from Xen after clearing the
74 * callback mask. We do this in a very simple manner, by making a call
75 * down into Xen. The pending flag will be checked by Xen on return.
76 */
77 void
78 hypervisor_force_callback(void)
79 {
81 (void)HYPERVISOR_xen_version(0);
82 }
84 int stipending(void);
85 int
86 stipending()
87 {
88 uint32_t l1;
89 unsigned long l2;
90 unsigned int l1i, l2i, port;
91 int irq;
92 shared_info_t *s = HYPERVISOR_shared_info;
93 struct cpu_info *ci;
94 int ret;
96 ret = 0;
97 ci = curcpu();
99 #if 0
100 if (HYPERVISOR_shared_info->events)
101 printf("stipending events %08lx mask %08lx ilevel %d\n",
102 HYPERVISOR_shared_info->events,
103 HYPERVISOR_shared_info->events_mask, ci->ci_ilevel);
104 #endif
106 /*
107 * we're only called after STIC, so we know that we'll have to
108 * STI at the end
109 */
110 cli();
111 while (s->vcpu_data[0].evtchn_upcall_pending) {
112 s->vcpu_data[0].evtchn_upcall_pending = 0;
113 /* NB. No need for a barrier here -- XCHG is a barrier
114 * on x86. */
115 l1 = x86_atomic_xchg(&s->evtchn_pending_sel, 0);
116 while ((l1i = ffs(l1)) != 0) {
117 l1i--;
118 l1 &= ~(1 << l1i);
120 l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
121 while ((l2i = ffs(l2)) != 0) {
122 l2i--;
123 l2 &= ~(1 << l2i);
125 port = (l1i << 5) + l2i;
126 if ((irq = evtchn_to_irq[port]) != -1) {
127 hypervisor_acknowledge_irq(irq);
128 ci->ci_ipending |= (1 << irq);
129 if (ret == 0 && ci->ci_ilevel <
130 ci->ci_isources[irq]->is_maxlevel)
131 ret = 1;
132 }
133 #if 0 /* XXXcl dev/evtchn */
134 else
135 evtchn_device_upcall(port);
136 #endif
137 }
138 }
139 }
140 sti();
142 #if 0
143 if (ci->ci_ipending & 0x1)
144 printf("stipending events %08lx mask %08lx ilevel %d ipending %08x\n",
145 HYPERVISOR_shared_info->events,
146 HYPERVISOR_shared_info->events_mask, ci->ci_ilevel,
147 ci->ci_ipending);
148 #endif
150 return (ret);
151 }
153 void do_hypervisor_callback(struct intrframe *regs)
154 {
155 uint32_t l1;
156 unsigned long l2;
157 unsigned int l1i, l2i, port;
158 int irq;
159 shared_info_t *s = HYPERVISOR_shared_info;
160 struct cpu_info *ci;
161 int level;
163 ci = curcpu();
164 level = ci->ci_ilevel;
166 while (s->vcpu_data[0].evtchn_upcall_pending) {
167 s->vcpu_data[0].evtchn_upcall_pending = 0;
168 /* NB. No need for a barrier here -- XCHG is a barrier
169 * on x86. */
170 l1 = x86_atomic_xchg(&s->evtchn_pending_sel, 0);
171 while ((l1i = ffs(l1)) != 0) {
172 l1i--;
173 l1 &= ~(1 << l1i);
175 l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
176 while ((l2i = ffs(l2)) != 0) {
177 l2i--;
178 l2 &= ~(1 << l2i);
180 port = (l1i << 5) + l2i;
181 if ((irq = evtchn_to_irq[port]) != -1)
182 do_event(irq, regs);
183 #if 0 /* XXXcl dev/evtchn */
184 else
185 evtchn_device_upcall(port);
186 #endif
187 }
188 }
189 }
191 #ifdef DIAGNOSTIC
192 if (level != ci->ci_ilevel)
193 printf("hypervisor done %08x level %d/%d ipending %08x\n",
194 HYPERVISOR_shared_info->evtchn_pending_sel, level,
195 ci->ci_ilevel, ci->ci_ipending);
196 #endif
197 }
199 void hypervisor_unmask_event(unsigned int ev)
200 {
201 shared_info_t *s = HYPERVISOR_shared_info;
203 x86_atomic_clear_bit(&s->evtchn_mask[0], ev);
204 /*
205 * The following is basically the equivalent of
206 * 'hw_resend_irq'. Just like a real IO-APIC we 'lose the
207 * interrupt edge' if the channel is masked.
208 */
209 if (x86_atomic_test_bit(&s->evtchn_pending[0], ev) &&
210 !x86_atomic_test_and_set_bit(&s->evtchn_pending_sel, ev>>5)) {
211 s->vcpu_data[0].evtchn_upcall_pending = 1;
212 if (!s->vcpu_data[0].evtchn_upcall_mask)
213 hypervisor_force_callback();
214 }
215 }
217 void hypervisor_mask_event(unsigned int ev)
218 {
219 shared_info_t *s = HYPERVISOR_shared_info;
221 x86_atomic_set_bit(&s->evtchn_mask[0], ev);
222 }
224 void hypervisor_clear_event(unsigned int ev)
225 {
226 shared_info_t *s = HYPERVISOR_shared_info;
228 x86_atomic_clear_bit(&s->evtchn_pending[0], ev);
229 }