win-pvdrivers

view xenpci/xenpci_dbgprint.c @ 979:8f483a2b2991

Fix up PREfast warnings
author James Harper <james.harper@bendigoit.com.au>
date Sun Apr 15 19:47:10 2012 +1000 (2012-04-15)
parents 373c6b36220c
children a5d1d333e0e2
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 <aux_klib.h>
23 #pragma intrinsic(_enable)
24 #pragma intrinsic(_disable)
26 #pragma pack(1)
27 #ifdef _AMD64_
28 typedef struct __KIDT_ENTRY
29 {
30 USHORT addr_0_15;
31 USHORT selector;
32 USHORT access;
33 USHORT addr_16_31;
34 ULONG addr_32_63;
35 ULONG reserved;
36 } IDT_ENTRY, *PIDT_ENTRY;
37 #else
38 typedef struct __KIDT_ENTRY
39 {
40 USHORT addr_0_15;
41 USHORT selector;
42 USHORT access;
43 USHORT addr_16_31;
44 } IDT_ENTRY, *PIDT_ENTRY;
45 #endif
46 #pragma pack()
48 #pragma pack(2)
49 typedef struct _IDT
50 {
51 USHORT limit;
52 PIDT_ENTRY entries;
53 } IDT, *PIDT;
54 #pragma pack()
56 /* Not really necessary but keeps PREfast happy */
57 #if (VER_PRODUCTBUILD >= 7600)
58 static KBUGCHECK_CALLBACK_ROUTINE XenPci_BugcheckCallback;
59 #endif
60 KBUGCHECK_CALLBACK_RECORD callback_record;
62 extern VOID Int2dHandlerNew(VOID);
63 extern PVOID Int2dHandlerOld;
65 static BOOLEAN debug_port_enabled = FALSE;
66 static volatile LONG debug_print_lock = 0;
68 static BOOLEAN last_newline = TRUE;
70 /* This appears to be called with interrupts disabled already, so no need to go to HIGH_LEVEL or anything like that */
71 static void XenDbgPrint(PCHAR string, ULONG length)
72 {
73 ULONG i;
74 ULONGLONG j;
75 LARGE_INTEGER current_time;
76 //KIRQL old_irql = 0;
78 while(InterlockedCompareExchange(&debug_print_lock, 1, 0) == 1)
79 KeStallExecutionProcessor(1);
81 for (i = 0; i < length; i++)
82 {
83 /* only write a timestamp if the last character was a newline */
84 if (last_newline)
85 {
86 KeQuerySystemTime(&current_time);
87 current_time.QuadPart /= 10000; /* convert to ms */
88 for (j = 1000000000000000000L; j >= 1; j /= 10)
89 if (current_time.QuadPart / j)
90 break;
91 for (; j >= 1; j /= 10) {
92 #pragma warning(suppress:28138)
93 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, '0' + (UCHAR)((current_time.QuadPart / j) % 10));
94 }
95 #pragma warning(suppress:28138)
96 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, ':');
97 #pragma warning(suppress:28138)
98 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, ' ');
99 }
100 #pragma warning(suppress:28138)
101 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, string[i]);
102 last_newline = (string[i] == '\n');
103 }
104 /* release the lock */
105 InterlockedExchange(&debug_print_lock, 0);
106 }
108 static VOID
109 XenPci_DbgWriteChar(CHAR c)
110 {
111 #pragma warning(suppress:28138)
112 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, c);
113 }
115 static VOID
116 XenPci_DbgWriteString(PCHAR string)
117 {
118 while (*string)
119 {
120 #pragma warning(suppress:28138)
121 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, *string);
122 string++;
123 }
124 }
126 static VOID
127 XenPci_DbgWriteHexByte(UCHAR byte)
128 {
129 char *digits = "0123456789ABCDEF";
130 XenPci_DbgWriteChar(digits[byte >> 4]);
131 XenPci_DbgWriteChar(digits[byte & 0x0F]);
132 }
134 static VOID
135 XenPci_DbgWriteULONG(ULONG data)
136 {
137 int i;
138 for (i = 0; i < sizeof(data); i++)
139 XenPci_DbgWriteHexByte((UCHAR)(data >> ((sizeof(data) - 1 - i) << 3)));
140 }
142 static VOID
143 XenPci_DbgWriteULONG_PTR(ULONG_PTR data)
144 {
145 int i;
146 for (i = 0; i < sizeof(data); i++)
147 XenPci_DbgWriteHexByte((UCHAR)(data >> ((sizeof(data) - 1 - i) << 3)));
148 }
150 static VOID
151 XenPci_BugcheckCallback(PVOID buffer, ULONG length)
152 {
153 NTSTATUS status;
154 KBUGCHECK_DATA bugcheck_data;
156 UNREFERENCED_PARAMETER(buffer);
157 UNREFERENCED_PARAMETER(length);
159 bugcheck_data.BugCheckDataSize = sizeof(bugcheck_data);
160 status = AuxKlibGetBugCheckData(&bugcheck_data);
161 if(!NT_SUCCESS(status))
162 {
163 XenPci_DbgWriteString(__DRIVER_NAME " AuxKlibGetBugCheckData returned ");
164 XenPci_DbgWriteULONG(status);
165 XenPci_DbgWriteString("\n");
166 return;
167 }
168 XenPci_DbgWriteString(__DRIVER_NAME " Bug check 0x");
169 XenPci_DbgWriteULONG(bugcheck_data.BugCheckCode);
170 XenPci_DbgWriteString(" (0x");
171 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter1);
172 XenPci_DbgWriteString(", 0x");
173 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter2);
174 XenPci_DbgWriteString(", 0x");
175 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter3);
176 XenPci_DbgWriteString(", 0x");
177 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter4);
178 XenPci_DbgWriteString(")\n");
179 }
181 VOID
182 Int2dHandlerProc(ULONG_PTR dbg_type, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5)
183 {
184 CHAR buf[512];
186 switch (dbg_type)
187 {
188 case 1: /* DbgPrint */
189 XenDbgPrint((PCHAR)arg2, (ULONG)(ULONG_PTR)arg3);
190 break;
191 case 2: /* ASSERT */
192 case 3: /* ??? */
193 case 4: /* ??? */
194 break;
195 default:
196 RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "*** %d %08x %08x %08x %08x\n", dbg_type, arg2, arg3, arg4, arg5);
197 XenDbgPrint(buf, (ULONG)strlen(buf));
198 break;
199 }
200 return;
201 }
203 static VOID
204 XenPci_DbgPrintCallback(PSTRING output, ULONG component_id, ULONG level)
205 {
206 UNREFERENCED_PARAMETER(component_id);
207 UNREFERENCED_PARAMETER(level);
209 XenDbgPrint(output->Buffer, output->Length);
210 }
212 #if 0
213 typedef struct _hook_info {
214 PIDT_ENTRY idt_entry;
215 } hook_info_t;
216 #endif
218 #if (NTDDI_VERSION < NTDDI_VISTA)
219 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
220 static VOID
221 XenPci_HookDbgPrint_High(PVOID context)
222 {
223 IDT idt;
224 PIDT_ENTRY idt_entry;
226 UNREFERENCED_PARAMETER(context);
228 idt.limit = 0;
229 __sidt(&idt);
230 idt_entry = &idt.entries[0x2D];
231 #ifdef _AMD64_
232 Int2dHandlerOld = (PVOID)((ULONG_PTR)idt_entry->addr_0_15 | ((ULONG_PTR)idt_entry->addr_16_31 << 16) | ((ULONG_PTR)idt_entry->addr_32_63 << 32));
233 #else
234 Int2dHandlerOld = (PVOID)((ULONG_PTR)idt_entry->addr_0_15 | ((ULONG_PTR)idt_entry->addr_16_31 << 16));
235 #endif
236 idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerNew;
237 idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerNew >> 16);
238 #ifdef _AMD64_
239 idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerNew >> 32);
240 #endif
241 }
243 static VOID
244 XenPci_UnHookDbgPrint_High(PVOID context)
245 {
246 IDT idt;
247 PIDT_ENTRY idt_entry;
249 UNREFERENCED_PARAMETER(context);
251 idt.limit = 0;
252 __sidt(&idt);
253 idt_entry = &idt.entries[0x2D];
254 idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerOld;
255 idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerOld >> 16);
256 #ifdef _AMD64_
257 idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerOld >> 32);
258 #endif
259 }
260 #endif
261 #endif
263 NTSTATUS
264 XenPci_HookDbgPrint()
265 {
266 NTSTATUS status = STATUS_SUCCESS;
268 #pragma warning(suppress:28138)
269 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
270 #pragma warning(suppress:28138)
271 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
272 {
273 //#pragma warning(suppress:4055)
274 //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
275 #if (NTDDI_VERSION >= NTDDI_VISTA)
276 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback found\n"));
277 status = DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, TRUE);
278 if (!NT_SUCCESS(status))
279 {
280 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback failed - %08x\n", status));
281 }
282 //DbgSetDebugFilterState(componentid, level, state);
283 DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, 0xFFFFFFFF, TRUE);
284 #else
285 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback not found\n"));
286 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
287 XenPci_HighSync(XenPci_HookDbgPrint_High, XenPci_HookDbgPrint_High, NULL);
288 #endif
289 #endif
290 }
291 else
292 {
293 status = STATUS_UNSUCCESSFUL;
294 }
296 KeInitializeCallbackRecord(&callback_record);
297 if (!KeRegisterBugCheckCallback(&callback_record, XenPci_BugcheckCallback, NULL, 0, (PUCHAR)"XenPci"))
298 {
299 KdPrint((__DRIVER_NAME " KeRegisterBugCheckCallback failed\n"));
300 status = STATUS_UNSUCCESSFUL;
301 }
303 return status;
304 }
306 NTSTATUS
307 XenPci_UnHookDbgPrint()
308 {
309 NTSTATUS status = STATUS_SUCCESS;
311 #pragma warning(suppress:28138)
312 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
313 #pragma warning(suppress:28138)
314 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
315 {
316 //#pragma warning(suppress:4055)
317 //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
318 #if (NTDDI_VERSION >= NTDDI_VISTA)
319 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback found\n"));
320 status = DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, FALSE);
321 if (!NT_SUCCESS(status))
322 {
323 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback failed - %08x\n", status));
324 }
325 //DbgSetDebugFilterState(componentid, level, state);
326 //DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, 0xFFFFFFFF, TRUE);
327 #else
328 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback not found\n"));
329 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
330 XenPci_HighSync(XenPci_UnHookDbgPrint_High, XenPci_UnHookDbgPrint_High, NULL);
331 #endif
332 #endif
333 }
334 else
335 {
336 status = STATUS_UNSUCCESSFUL;
337 }
339 if (!KeDeregisterBugCheckCallback(&callback_record))
340 {
341 KdPrint((__DRIVER_NAME " KeDeregisterBugCheckCallback failed\n"));
342 status = STATUS_UNSUCCESSFUL;
343 }
345 return status;
346 }