win-pvdrivers

view xenpci/xenpci_dbgprint.c @ 1013:43e76afb2398

Fix compiler warnings under 2000
author James Harper <james.harper@bendigoit.com.au>
date Mon Feb 11 20:59:11 2013 +1100 (2013-02-11)
parents 4f7d5a8636bd
children cd72cd0e1c19
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 /* make sure that each print gets to complete in its entirety */
79 while(InterlockedCompareExchange(&debug_print_lock, 1, 0) == 1)
80 KeStallExecutionProcessor(1);
82 for (i = 0; i < length; i++)
83 {
84 /* only write a timestamp if the last character was a newline */
85 if (last_newline)
86 {
87 KeQuerySystemTime(&current_time);
88 current_time.QuadPart /= 10000; /* convert to ms */
89 for (j = 1000000000000000000L; j >= 1; j /= 10)
90 if (current_time.QuadPart / j)
91 break;
92 for (; j >= 1; j /= 10) {
93 #pragma warning(suppress:28138)
94 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, '0' + (UCHAR)((current_time.QuadPart / j) % 10));
95 }
96 #pragma warning(suppress:28138)
97 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, ':');
98 #pragma warning(suppress:28138)
99 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, ' ');
100 }
101 #pragma warning(suppress:28138)
102 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, string[i]);
103 last_newline = (string[i] == '\n');
104 }
105 /* release the lock */
106 InterlockedExchange(&debug_print_lock, 0);
107 }
109 static VOID
110 XenPci_DbgWriteChar(CHAR c)
111 {
112 #pragma warning(suppress:28138)
113 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, c);
114 }
116 static VOID
117 XenPci_DbgWriteString(PCHAR string)
118 {
119 while (*string)
120 {
121 #pragma warning(suppress:28138)
122 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, *string);
123 string++;
124 }
125 }
127 static VOID
128 XenPci_DbgWriteHexByte(UCHAR byte)
129 {
130 char *digits = "0123456789ABCDEF";
131 XenPci_DbgWriteChar(digits[byte >> 4]);
132 XenPci_DbgWriteChar(digits[byte & 0x0F]);
133 }
135 static VOID
136 XenPci_DbgWriteULONG(ULONG data)
137 {
138 int i;
139 for (i = 0; i < sizeof(data); i++)
140 XenPci_DbgWriteHexByte((UCHAR)(data >> ((sizeof(data) - 1 - i) << 3)));
141 }
143 static VOID
144 XenPci_DbgWriteULONG_PTR(ULONG_PTR data)
145 {
146 int i;
147 for (i = 0; i < sizeof(data); i++)
148 XenPci_DbgWriteHexByte((UCHAR)(data >> ((sizeof(data) - 1 - i) << 3)));
149 }
151 static VOID
152 XenPci_BugcheckCallback(PVOID buffer, ULONG length)
153 {
154 NTSTATUS status;
155 KBUGCHECK_DATA bugcheck_data;
157 UNREFERENCED_PARAMETER(buffer);
158 UNREFERENCED_PARAMETER(length);
160 bugcheck_data.BugCheckDataSize = sizeof(bugcheck_data);
161 status = AuxKlibGetBugCheckData(&bugcheck_data);
162 if(!NT_SUCCESS(status))
163 {
164 XenPci_DbgWriteString(__DRIVER_NAME " AuxKlibGetBugCheckData returned ");
165 XenPci_DbgWriteULONG(status);
166 XenPci_DbgWriteString("\n");
167 return;
168 }
169 XenPci_DbgWriteString(__DRIVER_NAME " Bug check 0x");
170 XenPci_DbgWriteULONG(bugcheck_data.BugCheckCode);
171 XenPci_DbgWriteString(" (0x");
172 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter1);
173 XenPci_DbgWriteString(", 0x");
174 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter2);
175 XenPci_DbgWriteString(", 0x");
176 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter3);
177 XenPci_DbgWriteString(", 0x");
178 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter4);
179 XenPci_DbgWriteString(")\n");
180 }
182 VOID
183 Int2dHandlerProc(ULONG_PTR dbg_type, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5)
184 {
185 CHAR buf[512];
187 switch (dbg_type)
188 {
189 case 1: /* DbgPrint */
190 XenDbgPrint((PCHAR)arg2, (ULONG)(ULONG_PTR)arg3);
191 break;
192 case 2: /* ASSERT */
193 case 3: /* ??? */
194 case 4: /* ??? */
195 break;
196 default:
197 RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "*** %d %08x %08x %08x %08x\n", dbg_type, arg2, arg3, arg4, arg5);
198 XenDbgPrint(buf, (ULONG)strlen(buf));
199 break;
200 }
201 return;
202 }
204 static VOID
205 XenPci_DbgPrintCallback(PSTRING output, ULONG component_id, ULONG level)
206 {
207 UNREFERENCED_PARAMETER(component_id);
208 UNREFERENCED_PARAMETER(level);
210 XenDbgPrint(output->Buffer, output->Length);
211 }
213 #if 0
214 typedef struct _hook_info {
215 PIDT_ENTRY idt_entry;
216 } hook_info_t;
217 #endif
219 static VOID
220 XenPci_HookDbgPrint_High(PVOID context)
221 {
222 IDT idt;
223 PIDT_ENTRY idt_entry;
225 UNREFERENCED_PARAMETER(context);
227 idt.limit = 0;
228 __sidt(&idt);
229 idt_entry = &idt.entries[0x2D];
230 #ifdef _AMD64_
231 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));
232 #else
233 Int2dHandlerOld = (PVOID)((ULONG_PTR)idt_entry->addr_0_15 | ((ULONG_PTR)idt_entry->addr_16_31 << 16));
234 #endif
235 idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerNew;
236 idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerNew >> 16);
237 #ifdef _AMD64_
238 idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerNew >> 32);
239 #endif
240 }
242 static VOID
243 XenPci_UnHookDbgPrint_High(PVOID context)
244 {
245 IDT idt;
246 PIDT_ENTRY idt_entry;
248 UNREFERENCED_PARAMETER(context);
250 idt.limit = 0;
251 __sidt(&idt);
252 idt_entry = &idt.entries[0x2D];
253 idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerOld;
254 idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerOld >> 16);
255 #ifdef _AMD64_
256 idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerOld >> 32);
257 #endif
258 }
260 NTSTATUS
261 XenPci_HookDbgPrint()
262 {
263 NTSTATUS status = STATUS_SUCCESS;
265 #pragma warning(suppress:28138)
266 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
267 #pragma warning(suppress:28138)
268 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
269 {
270 //#pragma warning(suppress:4055)
271 //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
272 #if (NTDDI_VERSION >= NTDDI_VISTA)
273 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback found\n"));
274 status = DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, TRUE);
275 if (!NT_SUCCESS(status))
276 {
277 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback failed - %08x\n", status));
278 }
279 //DbgSetDebugFilterState(componentid, level, state);
280 DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, 0xFFFFFFFF, TRUE);
281 #else
282 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback not found\n"));
283 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
284 XenPci_HighSync(XenPci_HookDbgPrint_High, XenPci_HookDbgPrint_High, NULL);
285 #endif
286 #endif
287 }
288 else
289 {
290 status = STATUS_UNSUCCESSFUL;
291 }
293 KeInitializeCallbackRecord(&callback_record);
294 if (!KeRegisterBugCheckCallback(&callback_record, XenPci_BugcheckCallback, NULL, 0, (PUCHAR)"XenPci"))
295 {
296 KdPrint((__DRIVER_NAME " KeRegisterBugCheckCallback failed\n"));
297 status = STATUS_UNSUCCESSFUL;
298 }
300 return status;
301 }
303 /* always hook IDT in dump mode - patchguard is turned off so its okay */
304 /* no need for unhook routine - system is already crashed */
305 /* only for AMD64 and >= Vista */
306 VOID
307 XenPci_DumpModeHookDebugPrint() {
308 #if (NTDDI_VERSION >= NTDDI_VISTA)
309 #ifdef _AMD64_
310 #pragma warning(suppress:28138)
311 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
312 #pragma warning(suppress:28138)
313 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249) {
314 //XenPci_HighSync(XenPci_HookDbgPrint_High, XenPci_HookDbgPrint_High, NULL);
315 XenPci_HookDbgPrint_High(NULL);
316 }
317 #endif
318 #endif
319 }
321 NTSTATUS
322 XenPci_UnHookDbgPrint()
323 {
324 NTSTATUS status = STATUS_SUCCESS;
326 #pragma warning(suppress:28138)
327 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
328 #pragma warning(suppress:28138)
329 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249) {
330 //#pragma warning(suppress:4055)
331 //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
332 #if (NTDDI_VERSION >= NTDDI_VISTA)
333 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback found\n"));
334 status = DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, FALSE);
335 if (!NT_SUCCESS(status))
336 {
337 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback failed - %08x\n", status));
338 }
339 //DbgSetDebugFilterState(componentid, level, state);
340 //DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, 0xFFFFFFFF, TRUE);
341 #else
342 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback not found\n"));
343 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
344 XenPci_HighSync(XenPci_UnHookDbgPrint_High, XenPci_UnHookDbgPrint_High, NULL);
345 #endif
346 #endif
347 } else {
348 status = STATUS_UNSUCCESSFUL;
349 }
351 if (!KeDeregisterBugCheckCallback(&callback_record)) {
352 KdPrint((__DRIVER_NAME " KeDeregisterBugCheckCallback failed\n"));
353 status = STATUS_UNSUCCESSFUL;
354 }
356 return status;
357 }