mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +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 *************************************************************/
|
||||
|
||||
KIRQL
|
||||
NTAPI
|
||||
KdbpAcquireLock(
|
||||
_In_ PKSPIN_LOCK SpinLock);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdbpReleaseLock(
|
||||
_In_ PKSPIN_LOCK SpinLock,
|
||||
_In_ KIRQL OldIrql);
|
||||
|
||||
VOID
|
||||
KdpScreenAcquire(VOID);
|
||||
|
||||
|
|
|
@ -37,14 +37,6 @@ CPPORT SerialPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
|||
static CHAR KdpScreenLineBuffer[KdpScreenLineLengthDefault + 1] = "";
|
||||
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;
|
||||
LIST_ENTRY KdProviders = {&KdProviders, &KdProviders};
|
||||
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
|
||||
NTAPI
|
||||
KdpScreenPrint(PCHAR String,
|
||||
ULONG Length)
|
||||
{
|
||||
PCHAR pch = String;
|
||||
KIRQL OldIrql;
|
||||
ULONG beg, end, num;
|
||||
|
||||
while (pch < String + Length && *pch)
|
||||
{
|
||||
|
@ -497,45 +481,6 @@ KdpScreenPrint(PCHAR String,
|
|||
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
|
||||
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
|
||||
|
@ -557,22 +502,9 @@ KdpScreenInit(
|
|||
}
|
||||
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 */
|
||||
KdpScreenAcquire();
|
||||
|
||||
/* Initialize spinlock */
|
||||
KeInitializeSpinLock(&KdpDmesgLogSpinLock);
|
||||
|
||||
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 */
|
||||
BOOLEAN KdbpBugCheckRequested = FALSE;
|
||||
|
||||
/* Vars for dmesg */
|
||||
/* defined in ../kd/kdio.c, declare here: */
|
||||
extern volatile BOOLEAN KdbpIsInDmesgMode;
|
||||
extern const ULONG KdpDmesgBufferSize;
|
||||
extern PCHAR KdpDmesgBuffer;
|
||||
extern volatile ULONG KdpDmesgCurrentPosition;
|
||||
extern volatile ULONG KdpDmesgFreeBytes;
|
||||
extern volatile ULONG KdbDmesgTotalWritten;
|
||||
/* Variables for Dmesg */
|
||||
static const ULONG KdpDmesgBufferSize = 128 * 1024; // 512*1024;
|
||||
static PCHAR KdpDmesgBuffer = NULL;
|
||||
static volatile ULONG KdpDmesgCurrentPosition = 0;
|
||||
static volatile ULONG KdpDmesgFreeBytes = 0;
|
||||
static volatile ULONG KdbDmesgTotalWritten = 0;
|
||||
static volatile BOOLEAN KdbpIsInDmesgMode = FALSE;
|
||||
static KSPIN_LOCK KdpDmesgLogSpinLock;
|
||||
|
||||
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
|
||||
NTAPI
|
||||
KdbDebugPrint(
|
||||
PCH Message,
|
||||
ULONG Length)
|
||||
_In_ PCHAR String,
|
||||
_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 */
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue