win-pvdrivers

view xenpci/evtchn.c @ 6:8f643f8e229b

Bug Fixes... trying to find a problem that turned out to be me running an old version of xen by mistake!
author James Harper <james.harper@bendigoit.com.au>
date Mon Nov 12 22:26:30 2007 +1100 (2007-11-12)
parents 435e5753300f
children be8c09632f31 37c64fba5fc7
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenpci.h"
21 #include "hypercall.h"
23 #define NR_EVENTS 1024
25 typedef struct _ev_action_t {
26 PKSERVICE_ROUTINE ServiceRoutine;
27 PVOID ServiceContext;
28 ULONG Count;
29 } ev_action_t;
31 static ev_action_t ev_actions[NR_EVENTS];
33 static unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
35 BOOLEAN
36 EvtChn_Interrupt(WDFINTERRUPT Interrupt, ULONG MessageID)
37 {
38 int cpu = 0;
39 vcpu_info_t *vcpu_info;
40 // int i;
41 unsigned long evt_words, evt_word;
42 unsigned long evt_bit;
43 unsigned long port;
44 ev_action_t *ev_action;
46 UNREFERENCED_PARAMETER(Interrupt);
47 UNREFERENCED_PARAMETER(MessageID);
49 //KdPrint((__DRIVER_NAME " I+\n"));
50 //KdPrint((__DRIVER_NAME " --> XenPCI_ISR\n"));
52 vcpu_info = &shared_info_area->vcpu_info[cpu];
54 vcpu_info->evtchn_upcall_pending = 0;
56 evt_words = _InterlockedExchange((volatile LONG *)&vcpu_info->evtchn_pending_sel, 0);
58 while (_BitScanForward(&evt_word, evt_words))
59 {
60 evt_words &= ~(1 << evt_word);
61 while (_BitScanForward(&evt_bit, shared_info_area->evtchn_pending[evt_word] & ~shared_info_area->evtchn_mask[evt_word]))
62 {
63 port = (evt_word << 5) + evt_bit;
64 ev_action = &ev_actions[port];
65 if (ev_action->ServiceRoutine == NULL)
66 {
67 KdPrint((__DRIVER_NAME " Unhandled Event!!!\n"));
68 }
69 else
70 {
71 //KdPrint((__DRIVER_NAME " Calling Handler for port %d\n", port));
72 ev_action->ServiceRoutine(NULL, ev_action->ServiceContext);
73 }
74 _interlockedbittestandreset((volatile LONG *)&shared_info_area->evtchn_pending[0], port);
75 }
76 }
78 //KdPrint((__DRIVER_NAME " <-- XenPCI_ISR\n"));
80 //KdPrint((__DRIVER_NAME " I-\n"));
82 return TRUE;
83 }
85 evtchn_port_t
86 EvtChn_AllocUnbound(domid_t Domain)
87 {
88 evtchn_alloc_unbound_t op;
90 //KdPrint((__DRIVER_NAME " --> AllocUnbound\n"));
92 op.dom = DOMID_SELF;
93 op.remote_dom = Domain;
94 HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
96 //KdPrint((__DRIVER_NAME " <-- AllocUnbound\n"));
98 return op.port;
99 }
102 NTSTATUS
103 EvtChn_Bind(evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
104 {
105 KdPrint((__DRIVER_NAME " --> EvtChn_Bind\n"));
107 if(ev_actions[Port].ServiceRoutine != NULL)
108 {
109 KdPrint((__DRIVER_NAME " Handler for port %d already registered, replacing\n", Port));
110 }
112 ev_actions[Port].ServiceContext = ServiceContext;
113 KeMemoryBarrier();
114 ev_actions[Port].ServiceRoutine = ServiceRoutine;
116 EvtChn_Unmask(Port);
118 KdPrint((__DRIVER_NAME " <-- EvtChn_Bind\n"));
120 return STATUS_SUCCESS;
121 }
123 NTSTATUS
124 EvtChn_Unbind(evtchn_port_t Port)
125 {
126 //KdPrint((__DRIVER_NAME " --> EvtChn_UnBind\n"));
128 EvtChn_Mask(Port);
129 ev_actions[Port].ServiceContext = NULL;
130 ev_actions[Port].ServiceRoutine = NULL;
132 //KdPrint((__DRIVER_NAME " <-- EvtChn_UnBind\n"));
134 return STATUS_SUCCESS;
135 }
137 NTSTATUS
138 EvtChn_Mask(evtchn_port_t Port)
139 {
140 //KdPrint((__DRIVER_NAME " --> EvtChn_Mask\n"));
142 _interlockedbittestandset((volatile LONG *)&shared_info_area->evtchn_mask[0], Port);
144 //KdPrint((__DRIVER_NAME " <-- EvtChn_Mask\n"));
146 return STATUS_SUCCESS;
147 }
149 NTSTATUS
150 EvtChn_Unmask(evtchn_port_t Port)
151 {
152 //KdPrint((__DRIVER_NAME " --> EvtChn_Unmask\n"));
154 _interlockedbittestandreset((volatile LONG *)&shared_info_area->evtchn_mask[0], Port);
155 // should we kick off pending interrupts here too???
157 //KdPrint((__DRIVER_NAME " <-- EvtChn_Unmask\n"));
159 return STATUS_SUCCESS;
160 }
162 NTSTATUS
163 EvtChn_Notify(evtchn_port_t Port)
164 {
165 struct evtchn_send send;
167 //KdPrint((__DRIVER_NAME " --> EvtChn_Notify\n"));
169 send.port = Port;
171 (void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
173 //KdPrint((__DRIVER_NAME " <-- EvtChn_Notify\n"));
175 return STATUS_SUCCESS;
176 }
179 evtchn_port_t
180 EvtChn_GetXenStorePort()
181 {
182 evtchn_port_t Port;
184 //KdPrint((__DRIVER_NAME " --> EvtChn_GetStorePort\n"));
186 Port = (evtchn_port_t)hvm_get_parameter(HVM_PARAM_STORE_EVTCHN);
188 //KdPrint((__DRIVER_NAME " <-- EvtChn_GetStorePort\n"));
190 return Port;
191 }
193 PVOID
194 EvtChn_GetXenStoreRingAddr()
195 {
196 PHYSICAL_ADDRESS pa_xen_store_interface;
197 PVOID xen_store_interface;
199 ULONG xen_store_mfn;
201 //KdPrint((__DRIVER_NAME " --> EvtChn_GetRingAddr\n"));
203 xen_store_mfn = (ULONG)hvm_get_parameter(HVM_PARAM_STORE_PFN);
205 pa_xen_store_interface.QuadPart = xen_store_mfn << PAGE_SHIFT;
206 xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
208 //KdPrint((__DRIVER_NAME " xen_store_mfn = %08x\n", xen_store_mfn));
209 //KdPrint((__DRIVER_NAME " xen_store_evtchn = %08x\n", xen_store_evtchn));
210 //KdPrint((__DRIVER_NAME " xen_store_interface = %08x\n", xen_store_interface));
212 //KeInitializeEvent(&xenbus_waitevent, NotificationEvent, FALSE);
214 //KdPrint((__DRIVER_NAME " <-- EvtChn_GetRingAddr\n"));
216 return xen_store_interface;
217 }
219 NTSTATUS
220 EvtChn_Init()
221 {
222 int i;
224 for (i = 0; i < NR_EVENTS; i++)
225 {
226 EvtChn_Mask(i);
227 ev_actions[i].ServiceRoutine = NULL;
228 ev_actions[i].ServiceContext = NULL;
229 ev_actions[i].Count = 0;
230 }
232 for (i = 0; i < 8; i++) {
233 shared_info_area->evtchn_pending[i] = 0;
234 }
235 shared_info_area->vcpu_info[0].evtchn_upcall_pending = 0;
236 shared_info_area->vcpu_info[0].evtchn_pending_sel = 0;
238 return STATUS_SUCCESS;
239 }
241 static ev_action_t ev_actions[NR_EVENTS];