2005-04-25 14:44:48 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/kd/kdio.c
|
|
|
|
* PURPOSE: NT Kernel Debugger Input/Output Functions
|
|
|
|
*
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
2011-07-27 13:07:32 +00:00
|
|
|
#include <reactos/buildno.h>
|
2016-10-06 19:01:33 +00:00
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
2005-04-25 14:44:48 +00:00
|
|
|
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
#define KdpBufferSize (1024 * 512)
|
|
|
|
BOOLEAN KdpLoggingEnabled = FALSE;
|
|
|
|
PCHAR KdpDebugBuffer = NULL;
|
|
|
|
volatile ULONG KdpCurrentPosition = 0;
|
|
|
|
volatile ULONG KdpFreeBytes = 0;
|
|
|
|
KSPIN_LOCK KdpDebugLogSpinLock;
|
|
|
|
KEVENT KdpLoggerThreadEvent;
|
|
|
|
HANDLE KdpLogFileHandle;
|
2011-11-21 05:28:08 +00:00
|
|
|
ANSI_STRING KdpLogFileName = RTL_CONSTANT_STRING("\\SystemRoot\\debug.log");
|
2005-04-25 14:44:48 +00:00
|
|
|
|
2009-03-29 13:15:03 +00:00
|
|
|
KSPIN_LOCK KdpSerialSpinLock;
|
2013-05-07 00:14:36 +00:00
|
|
|
ULONG SerialPortNumber = DEFAULT_DEBUG_PORT;
|
|
|
|
CPPORT SerialPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
2005-04-25 14:44:48 +00:00
|
|
|
|
|
|
|
/* Current Port in use. FIXME: Do we support more then one? */
|
|
|
|
ULONG KdpPort;
|
|
|
|
|
2013-04-04 19:29:36 +00:00
|
|
|
#define KdpScreenLineLengthDefault 80
|
|
|
|
CHAR KdpScreenLineBuffer[KdpScreenLineLengthDefault + 1] = "";
|
2011-06-21 19:47:13 +00:00
|
|
|
ULONG KdpScreenLineBufferPos = 0, KdpScreenLineLength = 0;
|
|
|
|
|
2011-07-07 19:18:16 +00:00
|
|
|
const ULONG KdpDmesgBufferSize = 128 * 1024; // 512*1024; // 5*1024*1024;
|
|
|
|
PCHAR KdpDmesgBuffer = NULL;
|
|
|
|
volatile ULONG KdpDmesgCurrentPosition = 0;
|
|
|
|
volatile ULONG KdpDmesgFreeBytes = 0;
|
|
|
|
volatile ULONG KdbDmesgTotalWritten = 0;
|
|
|
|
KSPIN_LOCK KdpDmesgLogSpinLock;
|
2011-07-07 19:50:52 +00:00
|
|
|
volatile BOOLEAN KdbpIsInDmesgMode = FALSE;
|
2011-07-07 19:18:16 +00:00
|
|
|
|
2012-09-19 06:54:42 +00:00
|
|
|
/* UTILITY FUNCTIONS *********************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the total size of the memory before
|
|
|
|
* Mm is initialized, by counting the number
|
|
|
|
* of physical pages. Useful for debug logging.
|
|
|
|
*
|
|
|
|
* Strongly inspired by:
|
|
|
|
* mm\ARM3\mminit.c : MiScanMemoryDescriptors(...)
|
2016-10-06 19:01:33 +00:00
|
|
|
*
|
|
|
|
* See also: kd64\kdinit.c
|
2012-09-19 06:54:42 +00:00
|
|
|
*/
|
2016-10-06 19:01:33 +00:00
|
|
|
static SIZE_T
|
|
|
|
INIT_FUNCTION
|
2012-09-19 06:54:42 +00:00
|
|
|
KdpGetMemorySizeInMBs(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
|
|
|
|
SIZE_T NumberOfPhysicalPages = 0;
|
|
|
|
|
|
|
|
/* Loop the memory descriptors */
|
|
|
|
for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
|
|
|
|
ListEntry != &LoaderBlock->MemoryDescriptorListHead;
|
|
|
|
ListEntry = ListEntry->Flink)
|
|
|
|
{
|
|
|
|
/* Get the descriptor */
|
|
|
|
Descriptor = CONTAINING_RECORD(ListEntry,
|
|
|
|
MEMORY_ALLOCATION_DESCRIPTOR,
|
|
|
|
ListEntry);
|
|
|
|
|
|
|
|
/* Check if this is invisible memory */
|
|
|
|
if ((Descriptor->MemoryType == LoaderFirmwarePermanent) ||
|
|
|
|
(Descriptor->MemoryType == LoaderSpecialMemory) ||
|
|
|
|
(Descriptor->MemoryType == LoaderHALCachedMemory) ||
|
|
|
|
(Descriptor->MemoryType == LoaderBBTMemory))
|
|
|
|
{
|
|
|
|
/* Skip this descriptor */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if this is bad memory */
|
|
|
|
if (Descriptor->MemoryType != LoaderBad)
|
|
|
|
{
|
|
|
|
/* Count this in the total of pages */
|
|
|
|
NumberOfPhysicalPages += Descriptor->PageCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-02 23:19:18 +00:00
|
|
|
/* Round size up. Assumed to better match actual physical RAM size */
|
|
|
|
return ALIGN_UP_BY(NumberOfPhysicalPages * PAGE_SIZE, 1024 * 1024) / (1024 * 1024);
|
2012-09-19 06:54:42 +00:00
|
|
|
}
|
|
|
|
|
2017-10-16 09:47:14 +00:00
|
|
|
/* See also: kd64\kdinit.c */
|
|
|
|
static VOID
|
|
|
|
INIT_FUNCTION
|
|
|
|
KdpPrintBanner(IN SIZE_T MemSizeMBs)
|
|
|
|
{
|
|
|
|
DPRINT1("-----------------------------------------------------\n");
|
|
|
|
DPRINT1("ReactOS " KERNEL_VERSION_STR " (Build " KERNEL_VERSION_BUILD_STR ") (Commit " KERNEL_VERSION_COMMIT_HASH ")\n");
|
|
|
|
DPRINT1("%u System Processor [%u MB Memory]\n", KeNumberProcessors, MemSizeMBs);
|
|
|
|
DPRINT1("Command Line: %s\n", KeLoaderBlock->LoadOptions);
|
|
|
|
DPRINT1("ARC Paths: %s %s %s %s\n", KeLoaderBlock->ArcBootDeviceName, KeLoaderBlock->NtHalPathName, KeLoaderBlock->ArcHalDeviceName, KeLoaderBlock->NtBootPathName);
|
|
|
|
}
|
|
|
|
|
2011-07-07 19:18:16 +00:00
|
|
|
/* FILE DEBUG LOG FUNCTIONS **************************************************/
|
2005-04-25 14:44:48 +00:00
|
|
|
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2009-10-07 19:57:40 +00:00
|
|
|
KdpLoggerThread(PVOID Context)
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
2009-10-07 19:57:40 +00:00
|
|
|
ULONG beg, end, num;
|
2005-04-25 14:44:48 +00:00
|
|
|
IO_STATUS_BLOCK Iosb;
|
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
KdpLoggingEnabled = TRUE;
|
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
KeWaitForSingleObject(&KdpLoggerThreadEvent, 0, KernelMode, FALSE, NULL);
|
|
|
|
|
|
|
|
/* Bug */
|
2011-07-07 19:18:16 +00:00
|
|
|
/* Keep KdpCurrentPosition and KdpFreeBytes values in local
|
|
|
|
* variables to avoid their possible change from Producer part,
|
|
|
|
* KdpPrintToLogFile function
|
|
|
|
*/
|
2009-10-07 19:57:40 +00:00
|
|
|
end = KdpCurrentPosition;
|
|
|
|
num = KdpFreeBytes;
|
2011-07-07 19:18:16 +00:00
|
|
|
|
|
|
|
/* Now securely calculate values, based on local variables */
|
2009-10-07 19:57:40 +00:00
|
|
|
beg = (end + num) % KdpBufferSize;
|
|
|
|
num = KdpBufferSize - num;
|
|
|
|
|
|
|
|
/* Nothing to do? */
|
|
|
|
if (num == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (end > beg)
|
|
|
|
{
|
|
|
|
NtWriteFile(KdpLogFileHandle, NULL, NULL, NULL, &Iosb,
|
|
|
|
KdpDebugBuffer + beg, num, NULL, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NtWriteFile(KdpLogFileHandle, NULL, NULL, NULL, &Iosb,
|
|
|
|
KdpDebugBuffer + beg, KdpBufferSize - beg, NULL, NULL);
|
|
|
|
|
|
|
|
NtWriteFile(KdpLogFileHandle, NULL, NULL, NULL, &Iosb,
|
|
|
|
KdpDebugBuffer, end, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
2009-10-07 20:04:17 +00:00
|
|
|
(VOID)InterlockedExchangeAddUL(&KdpFreeBytes, num);
|
2009-10-07 19:57:40 +00:00
|
|
|
}
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2009-10-07 19:57:40 +00:00
|
|
|
KdpPrintToLogFile(PCH String,
|
|
|
|
ULONG StringLength)
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
2009-10-07 19:57:40 +00:00
|
|
|
ULONG beg, end, num;
|
|
|
|
KIRQL OldIrql;
|
|
|
|
|
|
|
|
if (KdpDebugBuffer == NULL) return;
|
|
|
|
|
|
|
|
/* Acquire the printing spinlock without waiting at raised IRQL */
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
/* Wait when the spinlock becomes available */
|
|
|
|
while (!KeTestSpinLock(&KdpDebugLogSpinLock));
|
|
|
|
|
|
|
|
/* Spinlock was free, raise IRQL */
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
/* Try to get the spinlock */
|
|
|
|
if (KeTryToAcquireSpinLockAtDpcLevel(&KdpDebugLogSpinLock))
|
|
|
|
break;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
/* Someone else got the spinlock, lower IRQL back */
|
|
|
|
KeLowerIrql(OldIrql);
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
beg = KdpCurrentPosition;
|
|
|
|
num = KdpFreeBytes;
|
|
|
|
if (StringLength < num)
|
|
|
|
num = StringLength;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
if (num != 0)
|
2005-07-26 15:15:18 +00:00
|
|
|
{
|
2009-10-07 19:57:40 +00:00
|
|
|
end = (beg + num) % KdpBufferSize;
|
|
|
|
KdpCurrentPosition = end;
|
|
|
|
KdpFreeBytes -= num;
|
|
|
|
|
|
|
|
if (end > beg)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(KdpDebugBuffer + beg, String, num);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RtlCopyMemory(KdpDebugBuffer + beg, String, KdpBufferSize - beg);
|
|
|
|
RtlCopyMemory(KdpDebugBuffer, String + KdpBufferSize - beg, end);
|
|
|
|
}
|
2005-07-26 15:15:18 +00:00
|
|
|
}
|
2009-10-07 19:57:40 +00:00
|
|
|
|
|
|
|
/* Release spinlock */
|
|
|
|
KiReleaseSpinLock(&KdpDebugLogSpinLock);
|
|
|
|
|
|
|
|
/* Lower IRQL */
|
|
|
|
KeLowerIrql(OldIrql);
|
|
|
|
|
|
|
|
/* Signal the logger thread */
|
|
|
|
if (OldIrql <= DISPATCH_LEVEL && KdpLoggingEnabled)
|
|
|
|
KeSetEvent(&KdpLoggerThreadEvent, 0, FALSE);
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2010-11-02 16:29:06 +00:00
|
|
|
INIT_FUNCTION
|
2005-04-25 14:44:48 +00:00
|
|
|
KdpInitDebugLog(PKD_DISPATCH_TABLE DispatchTable,
|
|
|
|
ULONG BootPhase)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
UNICODE_STRING FileName;
|
2009-10-07 19:57:40 +00:00
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
2005-05-09 01:38:29 +00:00
|
|
|
IO_STATUS_BLOCK Iosb;
|
2009-10-07 19:57:40 +00:00
|
|
|
HANDLE ThreadHandle;
|
|
|
|
KPRIORITY Priority;
|
2011-07-07 19:18:16 +00:00
|
|
|
SIZE_T MemSizeMBs;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-07-30 16:25:35 +00:00
|
|
|
if (!KdpDebugMode.File) return;
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
if (BootPhase == 0)
|
|
|
|
{
|
2009-01-19 23:22:22 +00:00
|
|
|
KdComPortInUse = NULL;
|
2006-06-22 21:26:31 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Write out the functions that we support for now */
|
|
|
|
DispatchTable->KdpInitRoutine = KdpInitDebugLog;
|
2009-10-07 19:57:40 +00:00
|
|
|
DispatchTable->KdpPrintRoutine = KdpPrintToLogFile;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Register as a Provider */
|
|
|
|
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
|
2006-06-11 08:25:10 +00:00
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
}
|
|
|
|
else if (BootPhase == 1)
|
|
|
|
{
|
|
|
|
/* Allocate a buffer for debug log */
|
|
|
|
KdpDebugBuffer = ExAllocatePool(NonPagedPool, KdpBufferSize);
|
|
|
|
KdpFreeBytes = KdpBufferSize;
|
|
|
|
|
|
|
|
/* Initialize spinlock */
|
|
|
|
KeInitializeSpinLock(&KdpDebugLogSpinLock);
|
|
|
|
|
2006-06-11 08:25:10 +00:00
|
|
|
/* Display separator + ReactOS version at start of the debug log */
|
2018-02-02 23:19:18 +00:00
|
|
|
/* Round size up. Assumed to better match actual physical RAM size */
|
|
|
|
MemSizeMBs = ALIGN_UP_BY(MmNumberOfPhysicalPages * PAGE_SIZE, 1024 * 1024) / (1024 * 1024);
|
2017-10-16 09:47:14 +00:00
|
|
|
KdpPrintBanner(MemSizeMBs);
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
else if (BootPhase == 2)
|
|
|
|
{
|
2013-10-13 23:04:13 +00:00
|
|
|
HalDisplayString("\r\n File log debugging enabled\r\n\r\n");
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
else if (BootPhase == 3)
|
|
|
|
{
|
2009-10-07 19:57:40 +00:00
|
|
|
/* Setup the log name */
|
2011-11-21 05:28:08 +00:00
|
|
|
Status = RtlAnsiStringToUnicodeString(&FileName, &KdpLogFileName, TRUE);
|
|
|
|
if (!NT_SUCCESS(Status)) return;
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&FileName,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
/* Create the log file */
|
|
|
|
Status = NtCreateFile(&KdpLogFileHandle,
|
|
|
|
FILE_APPEND_DATA | SYNCHRONIZE,
|
2005-04-25 14:44:48 +00:00
|
|
|
&ObjectAttributes,
|
|
|
|
&Iosb,
|
|
|
|
NULL,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
|
|
FILE_SHARE_READ,
|
|
|
|
FILE_SUPERSEDE,
|
|
|
|
FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
|
|
|
|
NULL,
|
|
|
|
0);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2011-11-21 05:28:08 +00:00
|
|
|
RtlFreeUnicodeString(&FileName);
|
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return;
|
|
|
|
|
|
|
|
KeInitializeEvent(&KdpLoggerThreadEvent, SynchronizationEvent, TRUE);
|
|
|
|
|
|
|
|
/* Create the logger thread */
|
|
|
|
Status = PsCreateSystemThread(&ThreadHandle,
|
|
|
|
THREAD_ALL_ACCESS,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
KdpLoggerThread,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status)) return;
|
|
|
|
|
|
|
|
Priority = 7;
|
|
|
|
NtSetInformationThread(ThreadHandle,
|
|
|
|
ThreadPriority,
|
|
|
|
&Priority,
|
|
|
|
sizeof(Priority));
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* SERIAL FUNCTIONS **********************************************************/
|
|
|
|
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
KdpSerialDebugPrint(LPSTR Message,
|
|
|
|
ULONG Length)
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
2009-03-29 13:15:03 +00:00
|
|
|
KIRQL OldIrql;
|
2005-04-25 14:44:48 +00:00
|
|
|
PCHAR pch = (PCHAR) Message;
|
|
|
|
|
2009-03-29 13:15:03 +00:00
|
|
|
/* Acquire the printing spinlock without waiting at raised IRQL */
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
/* Wait when the spinlock becomes available */
|
|
|
|
while (!KeTestSpinLock(&KdpSerialSpinLock));
|
|
|
|
|
2009-10-07 19:57:40 +00:00
|
|
|
/* Spinlock was free, raise IRQL */
|
2009-03-29 13:15:03 +00:00
|
|
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
|
|
|
|
|
|
|
/* Try to get the spinlock */
|
|
|
|
if (KeTryToAcquireSpinLockAtDpcLevel(&KdpSerialSpinLock))
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Someone else got the spinlock, lower IRQL back */
|
|
|
|
KeLowerIrql(OldIrql);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Output the message */
|
2017-12-12 11:38:45 +00:00
|
|
|
while (pch < Message + Length && *pch != '\0')
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
|
|
|
if (*pch == '\n')
|
|
|
|
{
|
|
|
|
KdPortPutByteEx(&SerialPortInfo, '\r');
|
|
|
|
}
|
|
|
|
KdPortPutByteEx(&SerialPortInfo, *pch);
|
|
|
|
pch++;
|
|
|
|
}
|
2009-03-29 13:15:03 +00:00
|
|
|
|
|
|
|
/* Release spinlock */
|
|
|
|
KiReleaseSpinLock(&KdpSerialSpinLock);
|
|
|
|
|
|
|
|
/* Lower IRQL */
|
|
|
|
KeLowerIrql(OldIrql);
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2005-04-25 14:44:48 +00:00
|
|
|
KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable,
|
|
|
|
ULONG BootPhase)
|
|
|
|
{
|
2011-07-07 19:18:16 +00:00
|
|
|
SIZE_T MemSizeMBs;
|
2005-04-25 14:44:48 +00:00
|
|
|
if (!KdpDebugMode.Serial) return;
|
|
|
|
|
|
|
|
if (BootPhase == 0)
|
|
|
|
{
|
|
|
|
/* Write out the functions that we support for now */
|
|
|
|
DispatchTable->KdpInitRoutine = KdpSerialInit;
|
|
|
|
DispatchTable->KdpPrintRoutine = KdpSerialDebugPrint;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Initialize the Port */
|
2013-05-07 00:14:36 +00:00
|
|
|
if (!KdPortInitializeEx(&SerialPortInfo, SerialPortNumber))
|
2005-10-02 09:42:12 +00:00
|
|
|
{
|
|
|
|
KdpDebugMode.Serial = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
2013-05-07 00:14:36 +00:00
|
|
|
KdComPortInUse = SerialPortInfo.Address;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2009-03-29 13:15:03 +00:00
|
|
|
/* Initialize spinlock */
|
|
|
|
KeInitializeSpinLock(&KdpSerialSpinLock);
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Register as a Provider */
|
|
|
|
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
|
2006-10-02 05:40:36 +00:00
|
|
|
|
2006-09-24 07:38:53 +00:00
|
|
|
/* Display separator + ReactOS version at start of the debug log */
|
2012-09-19 06:54:42 +00:00
|
|
|
MemSizeMBs = KdpGetMemorySizeInMBs(KeLoaderBlock);
|
2017-10-16 09:47:14 +00:00
|
|
|
KdpPrintBanner(MemSizeMBs);
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
else if (BootPhase == 2)
|
|
|
|
{
|
2013-10-13 23:04:13 +00:00
|
|
|
HalDisplayString("\r\n Serial debugging enabled\r\n\r\n");
|
2005-05-09 01:38:29 +00:00
|
|
|
}
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* SCREEN FUNCTIONS **********************************************************/
|
|
|
|
|
2011-07-07 19:18:16 +00:00
|
|
|
/*
|
|
|
|
* Screen debug logger function KdpScreenPrint() writes text messages into
|
|
|
|
* KdpDmesgBuffer, using it as a circular buffer. KdpDmesgBuffer contents could
|
|
|
|
* be later (re)viewed using dmesg command of kdbg. KdpScreenPrint() protects
|
|
|
|
* KdpDmesgBuffer from simultaneous writes by use of KdpDmesgLogSpinLock.
|
|
|
|
*/
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
KdpScreenPrint(LPSTR Message,
|
|
|
|
ULONG Length)
|
|
|
|
{
|
2011-07-07 19:18:16 +00:00
|
|
|
ULONG beg, end, num;
|
|
|
|
KIRQL OldIrql;
|
2011-06-21 19:47:13 +00:00
|
|
|
PCHAR pch = (PCHAR) Message;
|
|
|
|
|
2017-12-12 11:38:45 +00:00
|
|
|
while (pch < Message + Length && *pch)
|
2011-06-21 19:47:13 +00:00
|
|
|
{
|
|
|
|
if(*pch == '\b')
|
|
|
|
{
|
|
|
|
/* HalDisplayString does not support '\b'. Workaround it and use '\r' */
|
|
|
|
if(KdpScreenLineLength > 0)
|
|
|
|
{
|
|
|
|
/* Remove last character from buffer */
|
|
|
|
KdpScreenLineBuffer[--KdpScreenLineLength] = '\0';
|
|
|
|
KdpScreenLineBufferPos = KdpScreenLineLength;
|
|
|
|
|
|
|
|
/* Clear row and print line again */
|
|
|
|
HalDisplayString("\r");
|
|
|
|
HalDisplayString(KdpScreenLineBuffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
KdpScreenLineBuffer[KdpScreenLineLength++] = *pch;
|
|
|
|
KdpScreenLineBuffer[KdpScreenLineLength] = '\0';
|
|
|
|
}
|
|
|
|
|
2013-04-04 19:29:36 +00:00
|
|
|
if(*pch == '\n' || KdpScreenLineLength == KdpScreenLineLengthDefault)
|
2011-06-21 19:47:13 +00:00
|
|
|
{
|
|
|
|
/* Print buffered characters */
|
|
|
|
if(KdpScreenLineBufferPos != KdpScreenLineLength)
|
|
|
|
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
|
|
|
|
|
|
|
|
/* Clear line buffer */
|
|
|
|
KdpScreenLineBuffer[0] = '\0';
|
|
|
|
KdpScreenLineLength = KdpScreenLineBufferPos = 0;
|
|
|
|
}
|
2011-07-07 19:18:16 +00:00
|
|
|
|
2011-06-21 19:47:13 +00:00
|
|
|
++pch;
|
|
|
|
}
|
2011-07-07 19:18:16 +00:00
|
|
|
|
2011-06-21 19:47:13 +00:00
|
|
|
/* Print buffered characters */
|
|
|
|
if(KdpScreenLineBufferPos != KdpScreenLineLength)
|
|
|
|
{
|
|
|
|
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
|
|
|
|
KdpScreenLineBufferPos = KdpScreenLineLength;
|
|
|
|
}
|
2011-07-07 19:18:16 +00:00
|
|
|
|
|
|
|
/* Dmesg: store Message in the buffer to show it later */
|
|
|
|
if (KdbpIsInDmesgMode)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (KdpDmesgBuffer == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Acquire the printing spinlock without waiting at raised IRQL */
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
/* Wait when the spinlock becomes available */
|
|
|
|
while (!KeTestSpinLock(&KdpDmesgLogSpinLock));
|
|
|
|
|
|
|
|
/* Spinlock was free, raise IRQL */
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
|
|
|
|
|
|
|
/* Try to get the spinlock */
|
|
|
|
if (KeTryToAcquireSpinLockAtDpcLevel(&KdpDmesgLogSpinLock))
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Someone else got the spinlock, lower IRQL back */
|
|
|
|
KeLowerIrql(OldIrql);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize);
|
|
|
|
* set num to min(KdpDmesgFreeBytes, Length).
|
|
|
|
*/
|
2012-09-19 06:09:22 +00:00
|
|
|
num = (Length < KdpDmesgFreeBytes) ? Length : KdpDmesgFreeBytes;
|
2011-07-07 19:18:16 +00:00
|
|
|
beg = KdpDmesgCurrentPosition;
|
|
|
|
if (num != 0)
|
|
|
|
{
|
|
|
|
end = (beg + num) % KdpDmesgBufferSize;
|
|
|
|
if (end > beg)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(KdpDmesgBuffer + beg, Message, Length);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RtlCopyMemory(KdpDmesgBuffer + beg, Message, KdpDmesgBufferSize - beg);
|
|
|
|
RtlCopyMemory(KdpDmesgBuffer, Message + (KdpDmesgBufferSize - beg), end);
|
|
|
|
}
|
|
|
|
KdpDmesgCurrentPosition = end;
|
|
|
|
|
|
|
|
/* Counting the total bytes written */
|
|
|
|
KdbDmesgTotalWritten += num;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Release spinlock */
|
|
|
|
KiReleaseSpinLock(&KdpDmesgLogSpinLock);
|
|
|
|
|
|
|
|
/* Lower IRQL */
|
|
|
|
KeLowerIrql(OldIrql);
|
|
|
|
|
|
|
|
/* Optional step(?): find out a way to notify about buffer exhaustion,
|
|
|
|
* and possibly fall into kbd to use dmesg command: user will read
|
|
|
|
* debug messages before they will be wiped over by next writes.
|
|
|
|
*/
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
}
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2005-04-25 14:44:48 +00:00
|
|
|
KdpScreenInit(PKD_DISPATCH_TABLE DispatchTable,
|
|
|
|
ULONG BootPhase)
|
|
|
|
{
|
2011-07-07 19:18:16 +00:00
|
|
|
SIZE_T MemSizeMBs;
|
2005-04-25 14:44:48 +00:00
|
|
|
if (!KdpDebugMode.Screen) return;
|
|
|
|
|
|
|
|
if (BootPhase == 0)
|
|
|
|
{
|
|
|
|
/* Write out the functions that we support for now */
|
|
|
|
DispatchTable->KdpInitRoutine = KdpScreenInit;
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
DispatchTable->KdpPrintRoutine = KdpScreenPrint;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Register as a Provider */
|
|
|
|
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
|
|
|
|
}
|
2011-07-07 19:18:16 +00:00
|
|
|
else if (BootPhase == 1)
|
|
|
|
{
|
2012-09-19 06:09:22 +00:00
|
|
|
/* Allocate a buffer for dmesg log buffer. +1 for terminating null,
|
|
|
|
* see kdbp_cli.c:KdbpCmdDmesg()/2
|
|
|
|
*/
|
|
|
|
KdpDmesgBuffer = ExAllocatePool(NonPagedPool, KdpDmesgBufferSize + 1);
|
|
|
|
RtlZeroMemory(KdpDmesgBuffer, KdpDmesgBufferSize + 1);
|
|
|
|
KdpDmesgFreeBytes = KdpDmesgBufferSize;
|
|
|
|
KdbDmesgTotalWritten = 0;
|
|
|
|
|
|
|
|
/* Take control of the display */
|
|
|
|
InbvAcquireDisplayOwnership();
|
|
|
|
InbvResetDisplay();
|
|
|
|
InbvSolidColorFill(0, 0, 639, 479, 0);
|
|
|
|
InbvSetTextColor(15);
|
|
|
|
InbvSetScrollRegion(0, 0, 639, 479);
|
|
|
|
InbvInstallDisplayStringFilter(NULL);
|
|
|
|
InbvEnableDisplayString(TRUE);
|
|
|
|
|
|
|
|
/* Initialize spinlock */
|
|
|
|
KeInitializeSpinLock(&KdpDmesgLogSpinLock);
|
|
|
|
|
|
|
|
/* Display separator + ReactOS version at start of the debug log */
|
2018-02-02 23:19:18 +00:00
|
|
|
/* Round size up. Assumed to better match actual physical RAM size */
|
|
|
|
MemSizeMBs = ALIGN_UP_BY(MmNumberOfPhysicalPages * PAGE_SIZE, 1024 * 1024) / (1024 * 1024);
|
2017-10-16 09:47:14 +00:00
|
|
|
KdpPrintBanner(MemSizeMBs);
|
2011-07-07 19:18:16 +00:00
|
|
|
}
|
2005-04-25 14:44:48 +00:00
|
|
|
else if (BootPhase == 2)
|
|
|
|
{
|
2013-10-13 23:04:13 +00:00
|
|
|
HalDisplayString("\r\n Screen debugging enabled\r\n\r\n");
|
2005-05-09 01:38:29 +00:00
|
|
|
}
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* GENERAL FUNCTIONS *********************************************************/
|
|
|
|
|
|
|
|
ULONG
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2017-12-08 13:41:41 +00:00
|
|
|
KdpPrintString(
|
|
|
|
_In_reads_bytes_(Length) PCHAR UnsafeString,
|
2017-12-14 10:43:57 +00:00
|
|
|
_In_ ULONG Length,
|
|
|
|
_In_ KPROCESSOR_MODE PreviousMode)
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PKD_DISPATCH_TABLE CurrentTable;
|
2017-12-08 13:41:41 +00:00
|
|
|
PCHAR String;
|
2017-12-12 11:44:44 +00:00
|
|
|
CHAR StringBuffer[512];
|
2005-11-21 18:38:09 +00:00
|
|
|
|
2010-08-07 21:22:00 +00:00
|
|
|
if (!KdpDebugMode.Value) return 0;
|
2010-08-07 16:16:17 +00:00
|
|
|
|
2017-12-12 11:44:44 +00:00
|
|
|
Length = min(Length, sizeof(StringBuffer));
|
2017-12-08 13:41:41 +00:00
|
|
|
|
2017-12-14 10:43:57 +00:00
|
|
|
if (PreviousMode != KernelMode)
|
2017-12-08 13:41:41 +00:00
|
|
|
{
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForRead(UnsafeString, Length, 1);
|
2017-12-12 11:44:44 +00:00
|
|
|
String = StringBuffer;
|
2017-12-08 13:41:41 +00:00
|
|
|
RtlCopyMemory(String, UnsafeString, Length);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
String = UnsafeString;
|
|
|
|
}
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Call the registered handlers */
|
|
|
|
CurrentEntry = KdProviders.Flink;
|
|
|
|
while (CurrentEntry != &KdProviders)
|
|
|
|
{
|
|
|
|
/* Get the current table */
|
2005-05-09 01:38:29 +00:00
|
|
|
CurrentTable = CONTAINING_RECORD(CurrentEntry,
|
2005-04-25 14:44:48 +00:00
|
|
|
KD_DISPATCH_TABLE,
|
|
|
|
KdProvidersList);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Call it */
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
CurrentTable->KdpPrintRoutine(String, Length);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Next Table */
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Call the Wrapper Routine */
|
2009-06-22 11:32:58 +00:00
|
|
|
if (WrapperTable.KdpPrintRoutine)
|
|
|
|
WrapperTable.KdpPrintRoutine(String, Length);
|
2005-04-25 14:44:48 +00:00
|
|
|
|
|
|
|
/* Return the Length */
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
return Length;
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|