win-pvdrivers

view xenpci/evtchn.c @ 31:f56c47274c37

Automated merge with ssh://win-pvdrivers@xenbits.xensource.com/win-pvdrivers.hg
author Andy Grover <andy.grover@oracle.com>
date Mon Dec 03 23:05:02 2007 -0800 (2007-12-03)
parents 53fdfc9f5d56 28803c117324
children 464d62db9cff
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 BOOLEAN
24 EvtChn_Interrupt(WDFINTERRUPT Interrupt, ULONG MessageID)
25 {
26 int cpu = 0;
27 vcpu_info_t *vcpu_info;
28 unsigned long evt_words, evt_word;
29 unsigned long evt_bit;
30 unsigned long port;
31 ev_action_t *ev_action;
32 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(WdfInterruptGetDevice(Interrupt));
33 shared_info_t *shared_info_area = xpdd->shared_info_area;
35 UNREFERENCED_PARAMETER(Interrupt);
36 UNREFERENCED_PARAMETER(MessageID);
38 //KdPrint((__DRIVER_NAME " I+\n"));
39 //KdPrint((__DRIVER_NAME " --> XenPCI_ISR\n"));
41 vcpu_info = &shared_info_area->vcpu_info[cpu];
43 vcpu_info->evtchn_upcall_pending = 0;
45 evt_words = _InterlockedExchange((volatile LONG *)&vcpu_info->evtchn_pending_sel, 0);
47 while (_BitScanForward(&evt_word, evt_words))
48 {
49 evt_words &= ~(1 << evt_word);
50 while (_BitScanForward(&evt_bit, shared_info_area->evtchn_pending[evt_word] & ~shared_info_area->evtchn_mask[evt_word]))
51 {
52 port = (evt_word << 5) + evt_bit;
53 ev_action = &xpdd->ev_actions[port];
54 if (ev_action->ServiceRoutine == NULL)
55 {
56 KdPrint((__DRIVER_NAME " Unhandled Event!!!\n"));
57 }
58 else
59 {
60 //KdPrint((__DRIVER_NAME " Calling Handler for port %d\n", port));
61 ev_action->ServiceRoutine(NULL, ev_action->ServiceContext);
62 }
63 _interlockedbittestandreset((volatile LONG *)&shared_info_area->evtchn_pending[0], port);
64 }
65 }
67 //KdPrint((__DRIVER_NAME " <-- XenPCI_ISR\n"));
69 //KdPrint((__DRIVER_NAME " I-\n"));
71 return TRUE;
72 }
74 NTSTATUS
75 EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
76 {
77 WDFDEVICE Device = Context;
78 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
80 KdPrint((__DRIVER_NAME " --> EvtChn_Bind\n"));
82 if(xpdd->ev_actions[Port].ServiceRoutine != NULL)
83 {
84 KdPrint((__DRIVER_NAME " Handler for port %d already registered, replacing\n", Port));
85 }
87 xpdd->ev_actions[Port].ServiceContext = ServiceContext;
88 KeMemoryBarrier();
89 xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
91 EvtChn_Unmask(Device, Port);
93 KdPrint((__DRIVER_NAME " <-- EvtChn_Bind\n"));
95 return STATUS_SUCCESS;
96 }
98 NTSTATUS
99 EvtChn_Unbind(PVOID Context, evtchn_port_t Port)
100 {
101 WDFDEVICE Device = Context;
102 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
104 EvtChn_Mask(Context, Port);
105 xpdd->ev_actions[Port].ServiceContext = NULL;
106 xpdd->ev_actions[Port].ServiceRoutine = NULL;
108 //KdPrint((__DRIVER_NAME " <-- EvtChn_UnBind\n"));
110 return STATUS_SUCCESS;
111 }
113 NTSTATUS
114 EvtChn_Mask(PVOID Context, evtchn_port_t Port)
115 {
116 WDFDEVICE Device = Context;
117 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
118 //KdPrint((__DRIVER_NAME " --> EvtChn_Mask\n"));
120 _interlockedbittestandset(
121 (volatile LONG *)&xpdd->shared_info_area->evtchn_mask[0], Port);
123 //KdPrint((__DRIVER_NAME " <-- EvtChn_Mask\n"));
125 return STATUS_SUCCESS;
126 }
128 NTSTATUS
129 EvtChn_Unmask(PVOID Context, evtchn_port_t Port)
130 {
131 WDFDEVICE Device = Context;
132 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
133 //KdPrint((__DRIVER_NAME " --> EvtChn_Unmask\n"));
135 _interlockedbittestandreset(
136 (volatile LONG *)&xpdd->shared_info_area->evtchn_mask[0], Port);
137 // should we kick off pending interrupts here too???
139 //KdPrint((__DRIVER_NAME " <-- EvtChn_Unmask\n"));
141 return STATUS_SUCCESS;
142 }
144 NTSTATUS
145 EvtChn_Notify(PVOID Context, evtchn_port_t Port)
146 {
147 struct evtchn_send send;
149 //KdPrint((__DRIVER_NAME " --> EvtChn_Notify\n"));
151 send.port = Port;
153 (void)HYPERVISOR_event_channel_op(Context, EVTCHNOP_send, &send);
155 //KdPrint((__DRIVER_NAME " <-- EvtChn_Notify\n"));
157 return STATUS_SUCCESS;
158 }
160 evtchn_port_t
161 EvtChn_AllocUnbound(PVOID Context, domid_t Domain)
162 {
163 evtchn_alloc_unbound_t op;
165 UNREFERENCED_PARAMETER(Context);
167 //KdPrint((__DRIVER_NAME " --> AllocUnbound\n"));
169 op.dom = DOMID_SELF;
170 op.remote_dom = Domain;
171 HYPERVISOR_event_channel_op(Context, EVTCHNOP_alloc_unbound, &op);
173 //KdPrint((__DRIVER_NAME " <-- AllocUnbound\n"));
175 return op.port;
176 }
178 evtchn_port_t
179 EvtChn_GetXenStorePort(WDFDEVICE Device)
180 {
181 evtchn_port_t Port;
183 //KdPrint((__DRIVER_NAME " --> EvtChn_GetStorePort\n"));
185 Port = (evtchn_port_t)hvm_get_parameter(Device, HVM_PARAM_STORE_EVTCHN);
187 //KdPrint((__DRIVER_NAME " <-- EvtChn_GetStorePort\n"));
189 return Port;
190 }
192 PVOID
193 EvtChn_GetXenStoreRingAddr(WDFDEVICE Device)
194 {
195 PHYSICAL_ADDRESS pa_xen_store_interface;
196 PVOID xen_store_interface;
198 ULONG xen_store_mfn;
200 //KdPrint((__DRIVER_NAME " --> EvtChn_GetRingAddr\n"));
202 xen_store_mfn = (ULONG)hvm_get_parameter(Device, HVM_PARAM_STORE_PFN);
204 pa_xen_store_interface.QuadPart = xen_store_mfn << PAGE_SHIFT;
205 xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
207 //KdPrint((__DRIVER_NAME " xen_store_mfn = %08x\n", xen_store_mfn));
208 //KdPrint((__DRIVER_NAME " xen_store_evtchn = %08x\n", xen_store_evtchn));
209 //KdPrint((__DRIVER_NAME " xen_store_interface = %08x\n", xen_store_interface));
211 //KeInitializeEvent(&xenbus_waitevent, NotificationEvent, FALSE);
213 //KdPrint((__DRIVER_NAME " <-- EvtChn_GetRingAddr\n"));
215 return xen_store_interface;
216 }
218 NTSTATUS
219 EvtChn_Init(WDFDEVICE Device)
220 {
221 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
222 int i;
224 for (i = 0; i < NR_EVENTS; i++)
225 {
226 EvtChn_Mask(Device, i);
227 xpdd->ev_actions[i].ServiceRoutine = NULL;
228 xpdd->ev_actions[i].ServiceContext = NULL;
229 xpdd->ev_actions[i].Count = 0;
230 }
232 for (i = 0; i < 8; i++)
233 {
234 xpdd->shared_info_area->evtchn_pending[i] = 0;
235 }
236 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_pending = 0;
237 xpdd->shared_info_area->vcpu_info[0].evtchn_pending_sel = 0;
239 return STATUS_SUCCESS;
240 }