mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 16:40:27 +00:00
[NTOS:KD] Move handling of Dmesg buffer from screen provider to KDBG provider. (#5143)
CORE-10749 The dmesg command is now available even if screen output is disabled. Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
This commit is contained in:
parent
86e2f9e635
commit
bf734e5373
3 changed files with 85 additions and 79 deletions
|
@ -53,6 +53,17 @@ VOID
|
||||||
|
|
||||||
/* INIT ROUTINES *************************************************************/
|
/* INIT ROUTINES *************************************************************/
|
||||||
|
|
||||||
|
KIRQL
|
||||||
|
NTAPI
|
||||||
|
KdbpAcquireLock(
|
||||||
|
_In_ PKSPIN_LOCK SpinLock);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KdbpReleaseLock(
|
||||||
|
_In_ PKSPIN_LOCK SpinLock,
|
||||||
|
_In_ KIRQL OldIrql);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdpScreenAcquire(VOID);
|
KdpScreenAcquire(VOID);
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,6 @@ CPPORT SerialPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||||
static CHAR KdpScreenLineBuffer[KdpScreenLineLengthDefault + 1] = "";
|
static CHAR KdpScreenLineBuffer[KdpScreenLineLengthDefault + 1] = "";
|
||||||
static ULONG KdpScreenLineBufferPos = 0, KdpScreenLineLength = 0;
|
static ULONG KdpScreenLineBufferPos = 0, KdpScreenLineLength = 0;
|
||||||
|
|
||||||
const ULONG KdpDmesgBufferSize = 128 * 1024; // 512*1024;
|
|
||||||
PCHAR KdpDmesgBuffer = NULL;
|
|
||||||
volatile ULONG KdpDmesgCurrentPosition = 0;
|
|
||||||
volatile ULONG KdpDmesgFreeBytes = 0;
|
|
||||||
volatile ULONG KdbDmesgTotalWritten = 0;
|
|
||||||
volatile BOOLEAN KdbpIsInDmesgMode = FALSE;
|
|
||||||
static KSPIN_LOCK KdpDmesgLogSpinLock;
|
|
||||||
|
|
||||||
KDP_DEBUG_MODE KdpDebugMode;
|
KDP_DEBUG_MODE KdpDebugMode;
|
||||||
LIST_ENTRY KdProviders = {&KdProviders, &KdProviders};
|
LIST_ENTRY KdProviders = {&KdProviders, &KdProviders};
|
||||||
KD_DISPATCH_TABLE DispatchTable[KdMax];
|
KD_DISPATCH_TABLE DispatchTable[KdMax];
|
||||||
|
@ -440,20 +432,12 @@ KdpScreenRelease(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Screen debug logger function KdpScreenPrint() writes text strings 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.
|
|
||||||
*/
|
|
||||||
static VOID
|
static VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdpScreenPrint(PCHAR String,
|
KdpScreenPrint(PCHAR String,
|
||||||
ULONG Length)
|
ULONG Length)
|
||||||
{
|
{
|
||||||
PCHAR pch = String;
|
PCHAR pch = String;
|
||||||
KIRQL OldIrql;
|
|
||||||
ULONG beg, end, num;
|
|
||||||
|
|
||||||
while (pch < String + Length && *pch)
|
while (pch < String + Length && *pch)
|
||||||
{
|
{
|
||||||
|
@ -497,45 +481,6 @@ KdpScreenPrint(PCHAR String,
|
||||||
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
|
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
|
||||||
KdpScreenLineBufferPos = KdpScreenLineLength;
|
KdpScreenLineBufferPos = KdpScreenLineLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dmesg: store the string in the buffer to show it later */
|
|
||||||
if (KdbpIsInDmesgMode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (KdpDmesgBuffer == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Acquire the printing spinlock without waiting at raised IRQL */
|
|
||||||
OldIrql = KdbpAcquireLock(&KdpDmesgLogSpinLock);
|
|
||||||
|
|
||||||
beg = KdpDmesgCurrentPosition;
|
|
||||||
/* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
|
|
||||||
num = min(Length, KdpDmesgFreeBytes);
|
|
||||||
if (num != 0)
|
|
||||||
{
|
|
||||||
end = (beg + num) % KdpDmesgBufferSize;
|
|
||||||
if (end > beg)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(KdpDmesgBuffer + beg, String, Length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RtlCopyMemory(KdpDmesgBuffer + beg, String, KdpDmesgBufferSize - beg);
|
|
||||||
RtlCopyMemory(KdpDmesgBuffer, String + (KdpDmesgBufferSize - beg), end);
|
|
||||||
}
|
|
||||||
KdpDmesgCurrentPosition = end;
|
|
||||||
|
|
||||||
/* Counting the total bytes written */
|
|
||||||
KdbDmesgTotalWritten += num;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the spinlock */
|
|
||||||
KdbpReleaseLock(&KdpDmesgLogSpinLock, 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 strings before they will be wiped over by next writes.
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -557,22 +502,9 @@ KdpScreenInit(
|
||||||
}
|
}
|
||||||
else if (BootPhase == 1)
|
else if (BootPhase == 1)
|
||||||
{
|
{
|
||||||
/* Allocate a buffer for dmesg log buffer. +1 for terminating null,
|
|
||||||
* see kdbp_cli.c:KdbpCmdDmesg()/2
|
|
||||||
*/
|
|
||||||
KdpDmesgBuffer = ExAllocatePoolZero(NonPagedPool,
|
|
||||||
KdpDmesgBufferSize + 1,
|
|
||||||
TAG_KDBG);
|
|
||||||
/* Ignore failure if KdpDmesgBuffer is NULL */
|
|
||||||
KdpDmesgFreeBytes = KdpDmesgBufferSize;
|
|
||||||
KdbDmesgTotalWritten = 0;
|
|
||||||
|
|
||||||
/* Take control of the display */
|
/* Take control of the display */
|
||||||
KdpScreenAcquire();
|
KdpScreenAcquire();
|
||||||
|
|
||||||
/* Initialize spinlock */
|
|
||||||
KeInitializeSpinLock(&KdpDmesgLogSpinLock);
|
|
||||||
|
|
||||||
HalDisplayString("\r\n Screen debugging enabled\r\n\r\n");
|
HalDisplayString("\r\n Screen debugging enabled\r\n\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,14 +155,14 @@ static LONG KdbNumberOfColsTerminal = -1;
|
||||||
PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
|
PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
|
||||||
BOOLEAN KdbpBugCheckRequested = FALSE;
|
BOOLEAN KdbpBugCheckRequested = FALSE;
|
||||||
|
|
||||||
/* Vars for dmesg */
|
/* Variables for Dmesg */
|
||||||
/* defined in ../kd/kdio.c, declare here: */
|
static const ULONG KdpDmesgBufferSize = 128 * 1024; // 512*1024;
|
||||||
extern volatile BOOLEAN KdbpIsInDmesgMode;
|
static PCHAR KdpDmesgBuffer = NULL;
|
||||||
extern const ULONG KdpDmesgBufferSize;
|
static volatile ULONG KdpDmesgCurrentPosition = 0;
|
||||||
extern PCHAR KdpDmesgBuffer;
|
static volatile ULONG KdpDmesgFreeBytes = 0;
|
||||||
extern volatile ULONG KdpDmesgCurrentPosition;
|
static volatile ULONG KdbDmesgTotalWritten = 0;
|
||||||
extern volatile ULONG KdpDmesgFreeBytes;
|
static volatile BOOLEAN KdbpIsInDmesgMode = FALSE;
|
||||||
extern volatile ULONG KdbDmesgTotalWritten;
|
static KSPIN_LOCK KdpDmesgLogSpinLock;
|
||||||
|
|
||||||
STRING KdbPromptString = RTL_CONSTANT_STRING("kdb:> ");
|
STRING KdbPromptString = RTL_CONSTANT_STRING("kdb:> ");
|
||||||
|
|
||||||
|
@ -3882,13 +3882,60 @@ KdbpCliInit(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug logger function.
|
||||||
|
*
|
||||||
|
* This function writes text strings into KdpDmesgBuffer, using it as
|
||||||
|
* a circular buffer. KdpDmesgBuffer contents can be later (re)viewed
|
||||||
|
* using the dmesg command. KdbDebugPrint() protects KdpDmesgBuffer
|
||||||
|
* from simultaneous writes by use of KdpDmesgLogSpinLock.
|
||||||
|
**/
|
||||||
static VOID
|
static VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdbDebugPrint(
|
KdbDebugPrint(
|
||||||
PCH Message,
|
_In_ PCHAR String,
|
||||||
ULONG Length)
|
_In_ ULONG Length)
|
||||||
{
|
{
|
||||||
/* Nothing here */
|
KIRQL OldIrql;
|
||||||
|
ULONG beg, end, num;
|
||||||
|
|
||||||
|
/* Avoid recursive calling if we already are in Dmesg mode */
|
||||||
|
if (KdbpIsInDmesgMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (KdpDmesgBuffer == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Acquire the printing spinlock without waiting at raised IRQL */
|
||||||
|
OldIrql = KdbpAcquireLock(&KdpDmesgLogSpinLock);
|
||||||
|
|
||||||
|
beg = KdpDmesgCurrentPosition;
|
||||||
|
/* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
|
||||||
|
num = min(Length, KdpDmesgFreeBytes);
|
||||||
|
if (num != 0)
|
||||||
|
{
|
||||||
|
end = (beg + num) % KdpDmesgBufferSize;
|
||||||
|
if (end > beg)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(KdpDmesgBuffer + beg, String, Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(KdpDmesgBuffer + beg, String, KdpDmesgBufferSize - beg);
|
||||||
|
RtlCopyMemory(KdpDmesgBuffer, String + (KdpDmesgBufferSize - beg), end);
|
||||||
|
}
|
||||||
|
KdpDmesgCurrentPosition = end;
|
||||||
|
|
||||||
|
/* Counting the total bytes written */
|
||||||
|
KdbDmesgTotalWritten += num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the spinlock */
|
||||||
|
KdbpReleaseLock(&KdpDmesgLogSpinLock, 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 strings before they will be wiped over by next writes. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3918,6 +3965,22 @@ KdbInitialize(
|
||||||
/* Register as a Provider */
|
/* Register as a Provider */
|
||||||
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
|
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
|
||||||
}
|
}
|
||||||
|
else if (BootPhase == 1)
|
||||||
|
{
|
||||||
|
/* Initialize Dmesg support */
|
||||||
|
|
||||||
|
/* Allocate a buffer for Dmesg log buffer. +1 for terminating null,
|
||||||
|
* see kdbp_cli.c:KdbpCmdDmesg()/2 */
|
||||||
|
KdpDmesgBuffer = ExAllocatePoolZero(NonPagedPool,
|
||||||
|
KdpDmesgBufferSize + 1,
|
||||||
|
TAG_KDBG);
|
||||||
|
/* Ignore failure if KdpDmesgBuffer is NULL */
|
||||||
|
KdpDmesgFreeBytes = KdpDmesgBufferSize;
|
||||||
|
KdbDmesgTotalWritten = 0;
|
||||||
|
|
||||||
|
/* Initialize spinlock */
|
||||||
|
KeInitializeSpinLock(&KdpDmesgLogSpinLock);
|
||||||
|
}
|
||||||
|
|
||||||
if (BootPhase <= 1)
|
if (BootPhase <= 1)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue