win-pvdrivers

view xenpci/xenpci_dbgprint.c @ 910:1ee7940af105

Fix compilation under older DDK
author James Harper <james.harper@bendigoit.com.au>
date Fri Apr 29 23:56:03 2011 +1000 (2011-04-29)
parents e315b8490131
children 373c6b36220c
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 /* This appears to be called with interrupts disabled already, so no need to go to HIGH_LEVEL or anything like that */
69 static void XenDbgPrint(PCHAR string, ULONG length)
70 {
71 ULONG i;
72 ULONGLONG j;
73 LARGE_INTEGER current_time;
74 //KIRQL old_irql = 0;
76 while(InterlockedCompareExchange(&debug_print_lock, 1, 0) == 1)
77 KeStallExecutionProcessor(1);
79 KeQuerySystemTime(&current_time);
80 current_time.QuadPart /= 10000; /* convert to ms */
81 for (j = 1000000000000000000L; j >= 1; j /= 10)
82 if (current_time.QuadPart / j)
83 break;
84 for (; j >= 1; j /= 10)
85 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, '0' + (UCHAR)((current_time.QuadPart / j) % 10));
86 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, ':');
87 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, ' ');
89 for (i = 0; i < length; i++)
90 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, string[i]);
91 /* release the lock */
92 InterlockedExchange(&debug_print_lock, 0);
93 }
95 static VOID
96 XenPci_DbgWriteChar(CHAR c)
97 {
98 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, c);
99 }
101 static VOID
102 XenPci_DbgWriteString(PCHAR string)
103 {
104 while (*string)
105 {
106 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, *string);
107 string++;
108 }
109 }
111 static VOID
112 XenPci_DbgWriteHexByte(UCHAR byte)
113 {
114 char *digits = "0123456789ABCDEF";
115 XenPci_DbgWriteChar(digits[byte >> 4]);
116 XenPci_DbgWriteChar(digits[byte & 0x0F]);
117 }
119 static VOID
120 XenPci_DbgWriteULONG(ULONG data)
121 {
122 int i;
123 for (i = 0; i < sizeof(data); i++)
124 XenPci_DbgWriteHexByte((UCHAR)(data >> ((sizeof(data) - 1 - i) << 3)));
125 }
127 static VOID
128 XenPci_DbgWriteULONG_PTR(ULONG_PTR data)
129 {
130 int i;
131 for (i = 0; i < sizeof(data); i++)
132 XenPci_DbgWriteHexByte((UCHAR)(data >> ((sizeof(data) - 1 - i) << 3)));
133 }
135 static VOID
136 XenPci_BugcheckCallback(PVOID buffer, ULONG length)
137 {
138 NTSTATUS status;
139 KBUGCHECK_DATA bugcheck_data;
141 UNREFERENCED_PARAMETER(buffer);
142 UNREFERENCED_PARAMETER(length);
144 bugcheck_data.BugCheckDataSize = sizeof(bugcheck_data);
145 status = AuxKlibGetBugCheckData(&bugcheck_data);
146 if(!NT_SUCCESS(status))
147 {
148 XenPci_DbgWriteString(__DRIVER_NAME " AuxKlibGetBugCheckData returned ");
149 XenPci_DbgWriteULONG(status);
150 XenPci_DbgWriteString("\n");
151 return;
152 }
153 XenPci_DbgWriteString(__DRIVER_NAME " Bug check 0x");
154 XenPci_DbgWriteULONG(bugcheck_data.BugCheckCode);
155 XenPci_DbgWriteString(" (0x");
156 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter1);
157 XenPci_DbgWriteString(", 0x");
158 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter2);
159 XenPci_DbgWriteString(", 0x");
160 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter3);
161 XenPci_DbgWriteString(", 0x");
162 XenPci_DbgWriteULONG_PTR(bugcheck_data.Parameter4);
163 XenPci_DbgWriteString(")\n");
164 }
166 VOID
167 Int2dHandlerProc(ULONG_PTR dbg_type, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5)
168 {
169 CHAR buf[512];
171 switch (dbg_type)
172 {
173 case 1: /* DbgPrint */
174 XenDbgPrint((PCHAR)arg2, (ULONG)(ULONG_PTR)arg3);
175 break;
176 case 2: /* ASSERT */
177 case 3: /* ??? */
178 case 4: /* ??? */
179 break;
180 default:
181 RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "*** %d %08x %08x %08x %08x\n", dbg_type, arg2, arg3, arg4, arg5);
182 XenDbgPrint(buf, (ULONG)strlen(buf));
183 break;
184 }
185 return;
186 }
188 static VOID
189 XenPci_DbgPrintCallback(PSTRING output, ULONG component_id, ULONG level)
190 {
191 UNREFERENCED_PARAMETER(component_id);
192 UNREFERENCED_PARAMETER(level);
194 XenDbgPrint(output->Buffer, output->Length);
195 }
197 #if 0
198 typedef struct _hook_info {
199 PIDT_ENTRY idt_entry;
200 } hook_info_t;
201 #endif
203 #if (NTDDI_VERSION < NTDDI_VISTA)
204 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
205 static VOID
206 XenPci_HookDbgPrint_High(PVOID context)
207 {
208 IDT idt;
209 PIDT_ENTRY idt_entry;
211 UNREFERENCED_PARAMETER(context);
213 idt.limit = 0;
214 __sidt(&idt);
215 idt_entry = &idt.entries[0x2D];
216 #ifdef _AMD64_
217 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));
218 #else
219 Int2dHandlerOld = (PVOID)((ULONG_PTR)idt_entry->addr_0_15 | ((ULONG_PTR)idt_entry->addr_16_31 << 16));
220 #endif
221 idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerNew;
222 idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerNew >> 16);
223 #ifdef _AMD64_
224 idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerNew >> 32);
225 #endif
226 }
228 static VOID
229 XenPci_UnHookDbgPrint_High(PVOID context)
230 {
231 IDT idt;
232 PIDT_ENTRY idt_entry;
234 UNREFERENCED_PARAMETER(context);
236 idt.limit = 0;
237 __sidt(&idt);
238 idt_entry = &idt.entries[0x2D];
239 idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerOld;
240 idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerOld >> 16);
241 #ifdef _AMD64_
242 idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerOld >> 32);
243 #endif
244 }
245 #endif
246 #endif
248 NTSTATUS
249 XenPci_HookDbgPrint()
250 {
251 NTSTATUS status = STATUS_SUCCESS;
253 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
254 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
255 {
256 //#pragma warning(suppress:4055)
257 //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
258 #if (NTDDI_VERSION >= NTDDI_VISTA)
259 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback found\n"));
260 status = DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, TRUE);
261 if (!NT_SUCCESS(status))
262 {
263 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback failed - %08x\n", status));
264 }
265 //DbgSetDebugFilterState(componentid, level, state);
266 DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, 0xFFFFFFFF, TRUE);
267 #else
268 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback not found\n"));
269 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
270 XenPci_HighSync(XenPci_HookDbgPrint_High, XenPci_HookDbgPrint_High, NULL);
271 #endif
272 #endif
273 }
274 else
275 {
276 status = STATUS_UNSUCCESSFUL;
277 }
279 KeInitializeCallbackRecord(&callback_record);
280 if (!KeRegisterBugCheckCallback(&callback_record, XenPci_BugcheckCallback, NULL, 0, (PUCHAR)"XenPci"))
281 {
282 KdPrint((__DRIVER_NAME " KeRegisterBugCheckCallback failed\n"));
283 status = STATUS_UNSUCCESSFUL;
284 }
286 return status;
287 }
289 NTSTATUS
290 XenPci_UnHookDbgPrint()
291 {
292 NTSTATUS status = STATUS_SUCCESS;
294 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
295 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
296 {
297 //#pragma warning(suppress:4055)
298 //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
299 #if (NTDDI_VERSION >= NTDDI_VISTA)
300 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback found\n"));
301 status = DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, FALSE);
302 if (!NT_SUCCESS(status))
303 {
304 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback failed - %08x\n", status));
305 }
306 //DbgSetDebugFilterState(componentid, level, state);
307 //DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, 0xFFFFFFFF, TRUE);
308 #else
309 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback not found\n"));
310 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
311 XenPci_HighSync(XenPci_UnHookDbgPrint_High, XenPci_UnHookDbgPrint_High, NULL);
312 #endif
313 #endif
314 }
315 else
316 {
317 status = STATUS_UNSUCCESSFUL;
318 }
320 if (!KeDeregisterBugCheckCallback(&callback_record))
321 {
322 KdPrint((__DRIVER_NAME " KeDeregisterBugCheckCallback failed\n"));
323 status = STATUS_UNSUCCESSFUL;
324 }
326 return status;
327 }