win-pvdrivers

view xenpci/gnttbl.c @ 398:e7292fd9e55a

Fixup xenpci for mingw build with DBG enabled.

add FUNCTION_EXIT_STATUS macro
run unix2dos to fix line endings
update mingw makefiles
use FUNCTION_* macros in xenpci
author Andy Grover <andy.grover@oracle.com>
date Thu Jul 17 10:33:40 2008 -0700 (2008-07-17)
parents 46b6fa5bb7ad
children a7cf863172cf
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"
22 VOID
23 GntTbl_PutRef(PVOID Context, grant_ref_t ref)
24 {
25 PXENPCI_DEVICE_DATA xpdd = Context;
26 KIRQL OldIrql = PASSIVE_LEVEL;
28 if (xpdd->suspend_state != SUSPEND_STATE_HIGH_IRQL)
29 {
30 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
31 KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
32 }
33 xpdd->gnttab_list[ref] = xpdd->gnttab_list[0];
34 xpdd->gnttab_list[0] = ref;
35 if (xpdd->suspend_state != SUSPEND_STATE_HIGH_IRQL)
36 {
37 KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
38 }
39 }
41 grant_ref_t
42 GntTbl_GetRef(PVOID Context)
43 {
44 PXENPCI_DEVICE_DATA xpdd = Context;
45 unsigned int ref;
46 KIRQL OldIrql = PASSIVE_LEVEL;
48 UNREFERENCED_PARAMETER(OldIrql);
50 if (xpdd->suspend_state != SUSPEND_STATE_HIGH_IRQL)
51 {
52 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
53 KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
54 }
55 ref = xpdd->gnttab_list[0];
56 xpdd->gnttab_list[0] = xpdd->gnttab_list[ref];
57 if (xpdd->suspend_state != SUSPEND_STATE_HIGH_IRQL)
58 {
59 KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
60 }
62 return ref;
63 }
65 int
66 GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx)
67 {
68 PXENPCI_DEVICE_DATA xpdd = Context;
69 struct xen_add_to_physmap xatp;
70 unsigned int i = end_idx;
72 /* Loop backwards, so that the first hypercall has the largest index, ensuring that the table will grow only once. */
73 do {
74 xatp.domid = DOMID_SELF;
75 xatp.idx = i;
76 xatp.space = XENMAPSPACE_grant_table;
77 xatp.gpfn = (xen_pfn_t)(xpdd->gnttab_table_physical.QuadPart >> PAGE_SHIFT) + i;
78 if (HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp))
79 {
80 KdPrint((__DRIVER_NAME " ***ERROR MAPPING FRAME***\n"));
81 }
82 } while (i-- > start_idx);
84 return 0;
85 }
87 grant_ref_t
88 GntTbl_GrantAccess(
89 PVOID Context,
90 domid_t domid,
91 uint32_t frame, // xen api limits pfn to 32bit, so no guests over 8TB
92 int readonly,
93 grant_ref_t ref)
94 {
95 PXENPCI_DEVICE_DATA xpdd = Context;
97 //KdPrint((__DRIVER_NAME " --> GntTbl_GrantAccess\n"));
99 //KdPrint((__DRIVER_NAME " Granting access to frame %08x\n", frame));
101 if (ref == 0)
102 ref = GntTbl_GetRef(Context);
103 xpdd->gnttab_table[ref].frame = frame;
104 xpdd->gnttab_table[ref].domid = domid;
106 if (xpdd->gnttab_table[ref].flags)
107 KdPrint((__DRIVER_NAME " WARNING: Attempting to re-use grant entry that is already in use!\n"));
109 KeMemoryBarrier();
110 readonly *= GTF_readonly;
111 xpdd->gnttab_table[ref].flags = GTF_permit_access | (uint16_t)readonly;
113 //KdPrint((__DRIVER_NAME " <-- GntTbl_GrantAccess (ref = %d)\n", ref));
115 return ref;
116 }
118 #ifdef __MINGW32__
119 /* from linux/include/asm-i386/cmpxchg.h */
120 static inline short InterlockedCompareExchange16(
121 short volatile *dest,
122 short exch,
123 short comp)
124 {
125 unsigned long prev;
127 __asm__ __volatile__("lock;"
128 "cmpxchgw %w1,%2"
129 : "=a"(prev)
130 : "r"(exch), "m"(*(dest)), "0"(comp)
131 : "memory");
133 FUNCTION_MSG(("Check that I work as expected!\n"));
135 return prev;
136 }
137 #endif
139 BOOLEAN
140 GntTbl_EndAccess(
141 PVOID Context,
142 grant_ref_t ref,
143 BOOLEAN keepref)
144 {
145 PXENPCI_DEVICE_DATA xpdd = Context;
146 unsigned short flags, nflags;
148 //KdPrint((__DRIVER_NAME " --> GntTbl_EndAccess\n"));
150 nflags = xpdd->gnttab_table[ref].flags;
151 do {
152 if ((flags = nflags) & (GTF_reading|GTF_writing))
153 {
154 KdPrint((__DRIVER_NAME "WARNING: g.e. still in use!\n"));
155 return FALSE;
156 }
157 } while ((nflags = InterlockedCompareExchange16(
158 (volatile SHORT *)&xpdd->gnttab_table[ref].flags, 0, flags)) != flags);
160 if (!keepref)
161 GntTbl_PutRef(Context, ref);
162 //KdPrint((__DRIVER_NAME " <-- GntTbl_EndAccess\n"));
163 return TRUE;
164 }
166 static unsigned int
167 GntTbl_QueryMaxFrames(PXENPCI_DEVICE_DATA xpdd)
168 {
169 struct gnttab_query_size query;
170 int rc;
172 query.dom = DOMID_SELF;
174 rc = HYPERVISOR_grant_table_op(xpdd,GNTTABOP_query_size, &query, 1);
175 if ((rc < 0) || (query.status != GNTST_okay))
176 {
177 KdPrint((__DRIVER_NAME " ***CANNOT QUERY MAX GRANT FRAME***\n"));
178 return 4; /* Legacy max supported number of frames */
179 }
180 return query.max_nr_frames;
181 }
183 VOID
184 GntTbl_InitMap(PXENPCI_DEVICE_DATA xpdd)
185 {
186 int i;
187 ULONG grant_frames;
188 int grant_entries;
189 //KdPrint((__DRIVER_NAME " --> GntTbl_Init\n"));
191 grant_frames = GntTbl_QueryMaxFrames(xpdd);
192 grant_entries = min(NR_GRANT_ENTRIES, (grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
193 KdPrint((__DRIVER_NAME " grant_entries : %d\n", grant_entries));
195 if (xpdd->gnttab_list)
196 {
197 if (grant_frames > xpdd->max_grant_frames)
198 {
199 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
200 /* this won't actually work as it will be called at HIGH_IRQL and the free and unmap functions won't work... */
201 ExFreePoolWithTag(xpdd->gnttab_list, XENPCI_POOL_TAG);
202 MmUnmapIoSpace(xpdd->gnttab_table, PAGE_SIZE * xpdd->max_grant_frames);
203 xpdd->gnttab_list = NULL;
204 }
205 }
207 if (!xpdd->gnttab_list)
208 {
209 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
210 xpdd->gnttab_list = ExAllocatePoolWithTag(NonPagedPool, sizeof(grant_ref_t) * grant_entries, XENPCI_POOL_TAG);
211 xpdd->gnttab_table_physical = XenPci_AllocMMIO(xpdd,
212 PAGE_SIZE * grant_frames);
213 xpdd->gnttab_table = MmMapIoSpace(xpdd->gnttab_table_physical,
214 PAGE_SIZE * grant_frames, MmNonCached);
215 if (!xpdd->gnttab_table)
216 {
217 KdPrint((__DRIVER_NAME " Error Mapping Grant Table Shared Memory\n"));
218 // this should be a show stopper...
219 return;
220 }
221 xpdd->max_grant_frames = grant_frames;
222 }
223 RtlZeroMemory(xpdd->gnttab_list, sizeof(grant_ref_t) * grant_entries);
224 for (i = NR_RESERVED_ENTRIES; i < grant_entries; i++)
225 GntTbl_PutRef(xpdd, i);
227 GntTbl_Map(xpdd, 0, grant_frames - 1);
228 }
230 VOID
231 GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
232 {
233 //KdPrint((__DRIVER_NAME " --> GntTbl_Init\n"));
235 KeInitializeSpinLock(&xpdd->grant_lock);
236 GntTbl_InitMap(xpdd);
238 //KdPrint((__DRIVER_NAME " <-- GntTbl_Init table mapped at %p\n", gnttab_table));
239 }