Author: ion Date: Sun Feb 18 23:51:30 2007 New Revision: 25838
URL: http://svn.reactos.org/svn/reactos?rev=25838&view=rev Log: - Add kd64 folder for KD64 6.0 implementation. - Implement KdEnterDebugger, KdExitDebugger, KdEnableDebuggerWithLock, KdEnableDebugger. - Add KD Version Block, KD Component Masks, and KD Configuration Options. - Implement KdInitSystem and KdRegisterDebuggerDataBlock. - Implement KdPollBreakIn, KdpLockPort, KdpUnlockPort. - Implement KdpStub and KdpReport. Implement logic of KdpTrap but not helper calls (KdpTrap is only enabled after KD connects). - Implement KD Time Slip support, KdpSwitchProcessor, KdpQueryPerformanceCounter.
Added: branches/alex-kd-branch/reactos/ntoskrnl/kd64/ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdapi.c branches/alex-kd-branch/reactos/ntoskrnl/kd64/kddata.c branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdinit.c branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdlock.c branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdtrap.c Modified: branches/alex-kd-branch/reactos/ntoskrnl/include/internal/kd.h branches/alex-kd-branch/reactos/ntoskrnl/ke/i386/exp.c branches/alex-kd-branch/reactos/ntoskrnl/ntoskrnl.rbuild
Modified: branches/alex-kd-branch/reactos/ntoskrnl/include/internal/kd.h URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/include/internal/kd.h (original) +++ branches/alex-kd-branch/reactos/ntoskrnl/include/internal/kd.h Sun Feb 18 23:51:30 2007 @@ -1,12 +1,3 @@ -// -// Kernel Debugger Port Definition -// -extern BOOLEAN _KdDebuggerEnabled; -extern BOOLEAN _KdDebuggerNotPresent; -extern BOOLEAN KdBreakAfterSymbolLoad; - -/* KD GLOBALS ***************************************************************/ - typedef BOOLEAN (NTAPI *PKDEBUG_ROUTINE)( @@ -18,4 +9,128 @@ IN BOOLEAN SecondChance );
+typedef +BOOLEAN +(NTAPI *PKDEBUG_SWITCH_ROUTINE)( + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN BOOLEAN SecondChance +); + +BOOLEAN +NTAPI +KdpEnterDebuggerException( + IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN SecondChance +); + +VOID +NTAPI +KdpTimeSlipWork( + IN PVOID Context +); + +BOOLEAN +NTAPI +KdpSwitchProcessor( + IN PEXCEPTION_RECORD ExceptionRecord, + IN OUT PCONTEXT ContextRecord, + IN BOOLEAN SecondChanceException +); + +VOID +NTAPI +KdpTimeSlipDpcRoutine( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 +); + +BOOLEAN +NTAPI +KdpStub( + IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT ContextRecord, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN SecondChanceException +); + +BOOLEAN +NTAPI +KdpTrap( + IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT ContextRecord, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN SecondChanceException +); + +VOID +NTAPI +KdpPortLock( + VOID +); + +VOID +NTAPI +KdpPortUnlock( + VOID +); + +BOOLEAN +NTAPI +KdEnterDebugger( + IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame +); + +VOID +NTAPI +KdExitDebugger( + IN BOOLEAN Entered +); + +NTSTATUS +NTAPI +KdEnableDebuggerWithLock( + IN BOOLEAN NeedLock +); + +extern DBGKD_GET_VERSION64 KdVersionBlock; +extern KDDEBUGGER_DATA64 KdDebuggerDataBlock; +extern LIST_ENTRY KdpDebuggerDataListHead; +extern KSPIN_LOCK KdpDataSpinLock; +extern LARGE_INTEGER KdPerformanceCounterRate; +extern LARGE_INTEGER KdTimerStart; +extern ULONG KdDisableCount; +extern KD_CONTEXT KdpContext; extern PKDEBUG_ROUTINE KiDebugRoutine; +extern PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine; +extern BOOLEAN KdBreakAfterSymbolLoad; +extern BOOLEAN KdPitchDebugger; +extern BOOLEAN _KdDebuggerNotPresent; +extern BOOLEAN _KdDebuggerEnabled; +extern BOOLEAN KdAutoEnableOnEvent; +extern BOOLEAN KdPreviouslyEnabled; +extern BOOLEAN KdpDebuggerStructuresInitialized; +extern BOOLEAN KdEnteredDebugger; +extern KDPC KdpTimeSlipDpc; +extern KTIMER KdpTimeSlipTimer; +extern WORK_QUEUE_ITEM KdpTimeSlipWorkItem; +extern LONG KdpTimeSlipPending; +extern PKEVENT KdpTimeSlipEvent; +extern KSPIN_LOCK KdpTimeSlipEventLock; +extern BOOLEAN KdpControlCPressed; +extern BOOLEAN KdpControlCWaiting; +extern BOOLEAN KdpPortLocked; +extern KSPIN_LOCK KdpDebuggerLock; +extern LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference; +
Added: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdapi.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdapi.c (added) +++ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdapi.c Sun Feb 18 23:51:30 2007 @@ -1,0 +1,261 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kdapi.c + * PURPOSE: KD64 Public Routines and Internal Support + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +KdpTimeSlipDpcRoutine(IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + LONG OldSlip, NewSlip, PendingSlip; + + /* Get the current pending slip */ + PendingSlip = KdpTimeSlipPending; + do + { + /* Save the old value and either disable or enable it now. */ + OldSlip = PendingSlip; + NewSlip = OldSlip > 1 ? 1 : 0; + + /* Try to change the value */ + } while (InterlockedCompareExchange(&KdpTimeSlipPending, + NewSlip, + OldSlip) != OldSlip); + + /* If the New Slip value is 1, then do the Time Slipping */ + if (NewSlip) ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue); +} + +VOID +NTAPI +KdpTimeSlipWork(IN PVOID Context) +{ + KIRQL OldIrql; + LARGE_INTEGER DueTime; + + /* Update the System time from the CMOS */ + ExAcquireTimeRefreshLock(FALSE); + ExUpdateSystemTimeFromCmos(FALSE, 0); + ExReleaseTimeRefreshLock(); + + /* Check if we have a registered Time Slip Event and signal it */ + KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql); + if (KdpTimeSlipEvent) KeSetEvent(KdpTimeSlipEvent, 0, FALSE); + KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql); + + /* Delay the DPC until it runs next time */ + DueTime.QuadPart = -1800000000; + KeSetTimer(&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc); +} + +BOOLEAN +NTAPI +KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord, + IN OUT PCONTEXT ContextRecord, + IN BOOLEAN SecondChanceException) +{ + BOOLEAN Status; + + /* Save the port data */ + KdSave(FALSE); + + /* Report a state change */ +#if 0 + Status = KdpReportExceptionStateChange(ExceptionRecord, + ContextRecord, + SecondChanceException); +#else + Status = FALSE; +#endif + + /* Restore the port data and return */ + KdRestore(FALSE); + return Status; +} + +LARGE_INTEGER +NTAPI +KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame) +{ + LARGE_INTEGER Null = {{0}}; + + /* Check if interrupts were disabled */ + if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK)) + { + /* Nothing to return */ + return Null; + } + + /* Otherwise, do the call */ + return KeQueryPerformanceCounter(NULL); +} + +BOOLEAN +NTAPI +KdEnterDebugger(IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame) +{ + BOOLEAN Entered; + + /* Check if we have a trap frame */ + if (TrapFrame) + { + /* Calculate the time difference for the enter */ + KdTimerStop = KdpQueryPerformanceCounter(TrapFrame); + KdTimerDifference.QuadPart = KdTimerStop.QuadPart - + KdTimerStart.QuadPart; + } + else + { + /* No trap frame, so can't calculate */ + KdTimerStop.QuadPart = 0; + } + + /* Save the current IRQL */ + KeGetCurrentPrcb()->DebuggerSavedIRQL = KeGetCurrentIrql(); + + /* Freeze all CPUs */ + Entered = KeFreezeExecution(TrapFrame, ExceptionFrame); + + /* Lock the port, save the state and set debugger entered */ + KdpPortLocked = KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock); + KdSave(FALSE); + KdEnteredDebugger = TRUE; + + /* Check freeze flag */ + if (KiFreezeFlag & 1) + { + /* Print out errror */ + DbgPrint("FreezeLock was jammed! Backup SpinLock was used!\n"); + } + + /* Check processor state */ + if (KiFreezeFlag & 2) + { + /* Print out errror */ + DbgPrint("Some processors not frozen in debugger!\n"); + } + + /* Make sure we acquired the port */ + if (!KdpPortLocked) DbgPrint("Port lock was not acquired!\n"); + + /* Return enter state */ + return Entered; +} + +VOID +NTAPI +KdExitDebugger(IN BOOLEAN Entered) +{ + ULONG TimeSlip; + + /* Restore the state and unlock the port */ + KdRestore(FALSE); + if (KdpPortLocked) KdpPortUnlock(); + + /* Unfreeze the CPUs */ + KeThawExecution(Entered); + + /* Compare time with the one from KdEnterDebugger */ + if (!KdTimerStop.QuadPart) + { + /* We didn't get a trap frame earlier in so never got the time */ + KdTimerStart = KdTimerStop; + } + else + { + /* Query the timer */ + KdTimerStart = KeQueryPerformanceCounter(NULL); + } + + /* Check if a Time Slip was on queue */ + TimeSlip = InterlockedIncrement(&KdpTimeSlipPending); + if (TimeSlip == 1) + { + /* Queue a DPC for the time slip */ + InterlockedIncrement(&KdpTimeSlipPending); + KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL); + } +} + +NTSTATUS +NTAPI +KdEnableDebuggerWithLock(BOOLEAN NeedLock) +{ + KIRQL OldIrql; + + /* Check if we need to acquire the lock */ + if (NeedLock) + { + /* Lock the port */ + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + KdpPortLock(); + } + + /* Check if we're not disabled */ + if (!KdDisableCount) + { + /* Check if we had locked the port before */ + if (NeedLock) + { + /* Do the unlock */ + KeLowerIrql(OldIrql); + KdpPortUnlock(); + } + + /* Fail: We're already enabled */ + return STATUS_INVALID_PARAMETER; + } + + /* Decrease the disable count */ + if (!(--KdDisableCount)) + { + /* We're now enabled again! Were we enabled before, too? */ + if (KdPreviouslyEnabled) + { + /* Reinitialize the Debugger */ + KdInitSystem(0, NULL) ; + //KdpRestoreAllBreakpoints(); + } + } + + /* Check if we had locked the port before */ + if (NeedLock) + { + /* Yes, now unlock it */ + KeLowerIrql(OldIrql); + KdpPortUnlock(); + } + + /* We're done */ + return STATUS_SUCCESS; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +KdEnableDebugger(VOID) +{ + /* Use the internal routine */ + while (TRUE); + return KdEnableDebuggerWithLock(TRUE); +} +
Added: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kddata.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/kd64/kddata.c (added) +++ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kddata.c Sun Feb 18 23:51:30 2007 @@ -1,0 +1,305 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kddata.c + * PURPOSE: Contains all global variables and settings for KD64 + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* GLOBALS *******************************************************************/ + +// +// Debugger Version Block +// +DBGKD_GET_VERSION64 KdVersionBlock = +{ + 0, + 0, + DBGKD_64BIT_PROTOCOL_VERSION2, + KD_SECONDARY_VERSION_DEFAULT, + DBGKD_VERS_FLAG_DATA, + IMAGE_FILE_MACHINE_I386, + PACKET_TYPE_MAX, + 0, + 0, + DBGKD_SIMULATION_NONE, + {0}, + 0, + 0, + 0 +}; + +// +// Debugger Data +// +KDDEBUGGER_DATA64 KdDebuggerDataBlock; +LIST_ENTRY KdpDebuggerDataListHead; +KSPIN_LOCK KdpDataSpinLock; + +// +// Debugger State +// +KD_CONTEXT KdpContext; +BOOLEAN KdpControlCPressed; +BOOLEAN KdpControlCWaiting; +BOOLEAN KdpPortLocked; +KSPIN_LOCK KdpDebuggerLock; + +// +// Debug Trap Handlers +// +PKDEBUG_ROUTINE KiDebugRoutine = KdpStub; +PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine; + +// +// Debugger Configuration Settings +// +BOOLEAN KdBreakAfterSymbolLoad; +BOOLEAN KdPitchDebugger; +BOOLEAN _KdDebuggerNotPresent = TRUE; +BOOLEAN _KdDebuggerEnabled; +BOOLEAN KdAutoEnableOnEvent; +BOOLEAN KdPreviouslyEnabled; +BOOLEAN KdpDebuggerStructuresInitialized; +BOOLEAN KdEnteredDebugger; +ULONG KdDisableCount; +LARGE_INTEGER KdPerformanceCounterRate; + +// +// Time Slip Support +// +KDPC KdpTimeSlipDpc; +KTIMER KdpTimeSlipTimer; +WORK_QUEUE_ITEM KdpTimeSlipWorkItem; +LONG KdpTimeSlipPending; +PKEVENT KdpTimeSlipEvent; +KSPIN_LOCK KdpTimeSlipEventLock; +LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference; + +// +// Debug Filter Masks +// +ULONG Kd_WIN2000_Mask = 1; +ULONG Kd_SYSTEM_Mask; +ULONG Kd_SMSS_Mask; +ULONG Kd_SETUP_Mask; +ULONG Kd_NTFS_Mask; +ULONG Kd_FSTUB_Mask; +ULONG Kd_CRASHDUMP_Mask; +ULONG Kd_CDAUDIO_Mask; +ULONG Kd_CDROM_Mask; +ULONG Kd_CLASSPNP_Mask; +ULONG Kd_DISK_Mask; +ULONG Kd_REDBOOK_Mask; +ULONG Kd_STORPROP_Mask; +ULONG Kd_SCSIPORT_Mask; +ULONG Kd_SCSIMINIPORT_Mask; +ULONG Kd_CONFIG_Mask; +ULONG Kd_I8042PRT_Mask; +ULONG Kd_SERMOUSE_Mask; +ULONG Kd_LSERMOUS_Mask; +ULONG Kd_KBDHID_Mask; +ULONG Kd_MOUHID_Mask; +ULONG Kd_KBDCLASS_Mask; +ULONG Kd_MOUCLASS_Mask; +ULONG Kd_TWOTRACK_Mask; +ULONG Kd_WMILIB_Mask; +ULONG Kd_ACPI_Mask; +ULONG Kd_AMLI_Mask; +ULONG Kd_HALIA64_Mask; +ULONG Kd_VIDEO_Mask; +ULONG Kd_SVCHOST_Mask; +ULONG Kd_VIDEOPRT_Mask; +ULONG Kd_TCPIP_Mask; +ULONG Kd_DMSYNTH_Mask; +ULONG Kd_NTOSPNP_Mask; +ULONG Kd_FASTFAT_Mask; +ULONG Kd_SAMSS_Mask; +ULONG Kd_PNPMGR_Mask; +ULONG Kd_NETAPI_Mask; +ULONG Kd_SCSERVER_Mask; +ULONG Kd_SCCLIENT_Mask; +ULONG Kd_SERIAL_Mask; +ULONG Kd_SERENUM_Mask; +ULONG Kd_UHCD_Mask; +ULONG Kd_RPCPROXY_Mask; +ULONG Kd_AUTOCHK_Mask; +ULONG Kd_DCOMSS_Mask; +ULONG Kd_UNIMODEM_Mask; +ULONG Kd_SIS_Mask; +ULONG Kd_FLTMGR_Mask; +ULONG Kd_WMICORE_Mask; +ULONG Kd_BURNENG_Mask; +ULONG Kd_IMAPI_Mask; +ULONG Kd_SXS_Mask; +ULONG Kd_FUSION_Mask; +ULONG Kd_IDLETASK_Mask; +ULONG Kd_SOFTPCI_Mask; +ULONG Kd_TAPE_Mask; +ULONG Kd_MCHGR_Mask; +ULONG Kd_IDEP_Mask; +ULONG Kd_PCIIDE_Mask; +ULONG Kd_FLOPPY_Mask; +ULONG Kd_FDC_Mask; +ULONG Kd_TERMSRV_Mask; +ULONG Kd_W32TIME_Mask; +ULONG Kd_PREFETCHER_Mask; +ULONG Kd_RSFILTER_Mask; +ULONG Kd_FCPORT_Mask; +ULONG Kd_PCI_Mask; +ULONG Kd_DMIO_Mask; +ULONG Kd_DMCONFIG_Mask; +ULONG Kd_DMADMIN_Mask; +ULONG Kd_WSOCKTRANSPORT_Mask; +ULONG Kd_VSS_Mask; +ULONG Kd_PNPMEM_Mask; +ULONG Kd_PROCESSOR_Mask; +ULONG Kd_DMSERVER_Mask; +ULONG Kd_SR_Mask; +ULONG Kd_INFINIBAND_Mask; +ULONG Kd_IHVDRIVER_Mask; +ULONG Kd_IHVVIDEO_Mask; +ULONG Kd_IHVAUDIO_Mask; +ULONG Kd_IHVNETWORK_Mask; +ULONG Kd_IHVSTREAMING_Mask; +ULONG Kd_IHVBUS_Mask; +ULONG Kd_HPS_Mask; +ULONG Kd_RTLTHREADPOOL_Mask; +ULONG Kd_LDR_Mask; +ULONG Kd_TCPIP6_Mask; +ULONG Kd_ISAPNP_Mask; +ULONG Kd_SHPC_Mask; +ULONG Kd_STORPORT_Mask; +ULONG Kd_STORMINIPORT_Mask; +ULONG Kd_PRINTSPOOLER_Mask; +ULONG Kd_VSSDYNDISK_Mask; +ULONG Kd_VERIFIER_Mask; +ULONG Kd_VDS_Mask; +ULONG Kd_VDSBAS_Mask; +ULONG Kd_VDSDYNDR_Mask; +ULONG Kd_VDSUTIL_Mask; +ULONG Kd_DFRGIFC_Mask; +ULONG Kd_DEFAULT_Mask; +ULONG Kd_MM_Mask; +ULONG Kd_DFSC_Mask; +ULONG Kd_WOW64_Mask; +ULONG Kd_ENDOFTABLE_Mask; + +// +// Debug Filter Component Table +// +PULONG KdComponentTable[104] = +{ + &Kd_SYSTEM_Mask, + &Kd_SMSS_Mask, + &Kd_SETUP_Mask, + &Kd_NTFS_Mask, + &Kd_FSTUB_Mask, + &Kd_CRASHDUMP_Mask, + &Kd_CDAUDIO_Mask, + &Kd_CDROM_Mask, + &Kd_CLASSPNP_Mask, + &Kd_DISK_Mask, + &Kd_REDBOOK_Mask, + &Kd_STORPROP_Mask, + &Kd_SCSIPORT_Mask, + &Kd_SCSIMINIPORT_Mask, + &Kd_CONFIG_Mask, + &Kd_I8042PRT_Mask, + &Kd_SERMOUSE_Mask, + &Kd_LSERMOUS_Mask, + &Kd_KBDHID_Mask, + &Kd_MOUHID_Mask, + &Kd_KBDCLASS_Mask, + &Kd_MOUCLASS_Mask, + &Kd_TWOTRACK_Mask, + &Kd_WMILIB_Mask, + &Kd_ACPI_Mask, + &Kd_AMLI_Mask, + &Kd_HALIA64_Mask, + &Kd_VIDEO_Mask, + &Kd_SVCHOST_Mask, + &Kd_VIDEOPRT_Mask, + &Kd_TCPIP_Mask, + &Kd_DMSYNTH_Mask, + &Kd_NTOSPNP_Mask, + &Kd_FASTFAT_Mask, + &Kd_SAMSS_Mask, + &Kd_PNPMGR_Mask, + &Kd_NETAPI_Mask, + &Kd_SCSERVER_Mask, + &Kd_SCCLIENT_Mask, + &Kd_SERIAL_Mask, + &Kd_SERENUM_Mask, + &Kd_UHCD_Mask, + &Kd_RPCPROXY_Mask, + &Kd_AUTOCHK_Mask, + &Kd_DCOMSS_Mask, + &Kd_UNIMODEM_Mask, + &Kd_SIS_Mask, + &Kd_FLTMGR_Mask, + &Kd_WMICORE_Mask, + &Kd_BURNENG_Mask, + &Kd_IMAPI_Mask, + &Kd_SXS_Mask, + &Kd_FUSION_Mask, + &Kd_IDLETASK_Mask, + &Kd_SOFTPCI_Mask, + &Kd_TAPE_Mask, + &Kd_MCHGR_Mask, + &Kd_IDEP_Mask, + &Kd_PCIIDE_Mask, + &Kd_FLOPPY_Mask, + &Kd_FDC_Mask, + &Kd_TERMSRV_Mask, + &Kd_W32TIME_Mask, + &Kd_PREFETCHER_Mask, + &Kd_RSFILTER_Mask, + &Kd_FCPORT_Mask, + &Kd_PCI_Mask, + &Kd_DMIO_Mask, + &Kd_DMCONFIG_Mask, + &Kd_DMADMIN_Mask, + &Kd_WSOCKTRANSPORT_Mask, + &Kd_VSS_Mask, + &Kd_PNPMEM_Mask, + &Kd_PROCESSOR_Mask, + &Kd_DMSERVER_Mask, + &Kd_SR_Mask, + &Kd_INFINIBAND_Mask, + &Kd_IHVDRIVER_Mask, + &Kd_IHVVIDEO_Mask, + &Kd_IHVAUDIO_Mask, + &Kd_IHVNETWORK_Mask, + &Kd_IHVSTREAMING_Mask, + &Kd_IHVBUS_Mask, + &Kd_HPS_Mask, + &Kd_RTLTHREADPOOL_Mask, + &Kd_LDR_Mask, + &Kd_TCPIP6_Mask, + &Kd_ISAPNP_Mask, + &Kd_SHPC_Mask, + &Kd_STORPORT_Mask, + &Kd_STORMINIPORT_Mask, + &Kd_PRINTSPOOLER_Mask, + &Kd_VSSDYNDISK_Mask, + &Kd_VERIFIER_Mask, + &Kd_VDS_Mask, + &Kd_VDSBAS_Mask, + &Kd_VDSDYNDR_Mask, + &Kd_VDSUTIL_Mask, + &Kd_DFRGIFC_Mask, + &Kd_DEFAULT_Mask, + &Kd_MM_Mask, + &Kd_DFSC_Mask, + &Kd_WOW64_Mask, + &Kd_ENDOFTABLE_Mask, +}; + +ULONG KdComponentTableSize = sizeof(KdComponentTable);
Added: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdinit.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdinit.c (added) +++ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdinit.c Sun Feb 18 23:51:30 2007 @@ -1,0 +1,250 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kdinit.c + * PURPOSE: KD64 Initialization Code + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +KdRegisterDebuggerDataBlock(IN ULONG Tag, + IN PDBGKD_DEBUG_DATA_HEADER64 DataHeader, + IN ULONG Size) +{ + KIRQL OldIrql; + PLIST_ENTRY NextEntry; + PDBGKD_DEBUG_DATA_HEADER64 CurrentHeader; + + /* Acquire the Data Lock */ + KeAcquireSpinLock(&KdpDataSpinLock, &OldIrql); + + /* Loop the debugger data list */ + NextEntry = KdpDebuggerDataListHead.Flink; + while (NextEntry != &KdpDebuggerDataListHead) + { + /* Get the header for this entry */ + CurrentHeader = CONTAINING_RECORD(NextEntry, + DBGKD_DEBUG_DATA_HEADER64, + List); + + /* Move to the next one */ + NextEntry = NextEntry->Flink; + + /* Check if we already have this data block */ + if ((CurrentHeader == DataHeader) || (CurrentHeader->OwnerTag == Tag)) + { + /* Release the lock and fail */ + KeReleaseSpinLock(&KdpDataSpinLock, OldIrql); + return FALSE; + } + } + + /* Setup the header */ + DataHeader->OwnerTag = Tag; + DataHeader->Size = Size; + + /* Insert it into the list and release the lock */ + InsertTailList(&KdpDebuggerDataListHead, (PLIST_ENTRY)&DataHeader->List); + KeReleaseSpinLock(&KdpDataSpinLock, OldIrql); + return TRUE; +} + +BOOLEAN +NTAPI +KdInitSystem(IN ULONG BootPhase, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + BOOLEAN EnableKd; + LPSTR CommandLine, DebugLine; + ANSI_STRING ImageName; + PLDR_DATA_TABLE_ENTRY LdrEntry; + PLIST_ENTRY NextEntry; + ULONG i; + CHAR NameBuffer[256]; + return TRUE; + + /* Check if this is Phase 1 */ + if (BootPhase) + { + /* Just query the performance counter */ + KeQueryPerformanceCounter(&KdPerformanceCounterRate); + return TRUE; + } + + /* Check if we already initialized once */ + if (KdDebuggerEnabled) return TRUE; + + /* Set the Debug Routine as the Stub for now */ + KiDebugRoutine = KdpStub; + + /* Disable break after symbol load for now */ + KdBreakAfterSymbolLoad = FALSE; + + /* Check if the Debugger Data Block was already initialized */ + if (!KdpDebuggerDataListHead.Flink) + { + /* It wasn't...Initialize the KD Data Listhead */ + InitializeListHead(&KdpDebuggerDataListHead); + + /* Register the Debugger Data Block */ + KdRegisterDebuggerDataBlock(KDBG_TAG, + &KdDebuggerDataBlock.Header, + sizeof(KdDebuggerDataBlock)); + + /* Fill out the KD Version Block */ + KdVersionBlock.MajorVersion = (USHORT)(NtBuildNumber >> 28); + KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF); + +#ifdef CONFIG_SMP + /* This is an MP Build */ + KdVersionBlock.Flags |= DBGKD_VERS_FLAG_MP; +#endif + + /* Save Pointers to Loaded Module List and Debugger Data */ + KdVersionBlock.PsLoadedModuleList = (ULONG64)&PsLoadedModuleList; + KdVersionBlock.DebuggerDataList = (ULONG64)&KdpDebuggerDataListHead; + + /* Set protocol limits */ + KdVersionBlock.MaxStateChange = DbgKdMaximumStateChange - + DbgKdMinimumStateChange; + KdVersionBlock.MaxManipulate = DbgKdMaximumManipulate - + DbgKdMinimumManipulate; + KdVersionBlock.Unused[0] = 0; + + /* Link us in the KPCR */ + KeGetPcr()->KdVersionBlock = &KdVersionBlock; + } + + /* Check if we have a loader block */ + if (LoaderBlock) + { + /* Save the Kernel Base */ + KdVersionBlock.KernBase = (ULONG64)LoaderBlock->KernelStack; + + /* Check if we have a command line */ + CommandLine = LoaderBlock->LoadOptions; + if (CommandLine) + { + /* Upcase it */ + _strupr(CommandLine); + + /* Assume we'll disable KD */ + EnableKd = FALSE; + + /* Check for CRASHDEBUG and NODEBUG */ + if (strstr(CommandLine, "CRASHDEBUG")) KdPitchDebugger = FALSE; + if (strstr(CommandLine, "NODEBUG")) KdPitchDebugger = TRUE; + + /* Check if DEBUG was on */ + DebugLine = strstr(CommandLine, "DEBUG"); + if (DebugLine) + { + /* Enable KD */ + EnableKd = TRUE; + + /* Check if there was additional data */ + if (DebugLine[5] == '=') + { + /* FIXME: Check for NOUMEX, DISABLE, AUTOENABLE */ + } + } + } + else + { + /* No command line options? Disable debugger by default */ + KdPitchDebugger = TRUE; + EnableKd = FALSE; + } + } + else + { + /* Called from a bugcheck...Save the Kernel Base */ + KdVersionBlock.KernBase = PsNtosImageBase; + + /* Unconditionally enable KD */ + EnableKd = TRUE; + } + + /* Set the Kernel Base in the Data Block */ + KdDebuggerDataBlock.KernBase = KdVersionBlock.KernBase; + + /* Initialize the debugger if requested */ + if ((EnableKd) && (NT_SUCCESS(KdDebuggerInitialize0(LoaderBlock)))) + { + /* Now set our real KD routine */ + KiDebugRoutine = KdpTrap; + + /* Check if we've already initialized our structures */ + if (!KdpDebuggerStructuresInitialized) + { + /* Set the Debug Switch Routine and Retries*/ + KdpContext.KdpDefaultRetries = 20; + KiDebugSwitchRoutine = KdpSwitchProcessor; + + /* Initialize the Time Slip DPC */ + KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL); + KeInitializeTimer(&KdpTimeSlipTimer); + ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL); + + /* First-time initialization done! */ + KdpDebuggerStructuresInitialized = TRUE; + } + + /* Initialize the timer */ + KdTimerStart.QuadPart = 0; + + /* Officially enable KD */ + KdPitchDebugger = FALSE; + KdDebuggerEnabled = TRUE; + + /* Let user-mode know that it's enabled as well */ +#undef KdDebuggerEnabled + SharedUserData->KdDebuggerEnabled = TRUE; +#define KdDebuggerEnabled _KdDebuggerEnabled + + /* Check if we have a loader block */ + if (LoaderBlock) + { + /* Loop boot images */ + NextEntry = LoaderBlock->LoadOrderListHead.Flink; + i = 0; + while ((NextEntry != &LoaderBlock->LoadOrderListHead) && (i < 2)) + { + /* Get the image entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* Generate the image name */ + + /* Load symbols for image */ + RtlInitAnsiString(&ImageName, NameBuffer); + DbgLoadImageSymbols(&ImageName, LdrEntry->DllBase, -1); + + /* Go to the next entry */ + NextEntry = NextEntry->Flink; + i++; + } + } + + /* Check for incoming breakin and break on symbol load if we have it*/ + KdBreakAfterSymbolLoad = KdPollBreakIn(); + } + else + { + /* Disable debugger */ + KdDebuggerNotPresent = TRUE; + } + + /* Return initialized */ + return TRUE; +}
Added: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdlock.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdlock.c (added) +++ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdlock.c Sun Feb 18 23:51:30 2007 @@ -1,0 +1,90 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kdlock.c + * PURPOSE: KD64 Port Lock and Breakin Support + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +KdpPortLock(VOID) +{ + /* Acquire the lock */ + KiAcquireSpinLock(&KdpDebuggerLock); +} + +VOID +NTAPI +KdpPortUnlock(VOID) +{ + /* Release the lock */ + KiReleaseSpinLock(&KdpDebuggerLock); +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +BOOLEAN +NTAPI +KdPollBreakIn(VOID) +{ + BOOLEAN DoBreak = FALSE; + ULONG Flags; + + /* First make sure that KD is enabled */ + if (KdDebuggerEnabled) + { + /* Disable interrupts */ + Ke386SaveFlags(Flags); + //Flags = __getcallerseflags(); + _disable(); + + /* Check if a CTRL-C is in the queue */ + if (KdpControlCWaiting) + { + /* Set it and prepare for break */ + KdpControlCPressed = TRUE; + DoBreak = TRUE; + KdpControlCWaiting = FALSE; + } + else + { + /* Try to acquire the lock */ + if (KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock)) + { + /* Now get a packet */ + if (!KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN, + NULL, + NULL, + NULL, + NULL)) + { + /* Successful breakin */ + DoBreak = TRUE; + KdpControlCPressed = TRUE; + } + + /* Let go of the port */ + KdpPortUnlock(); + } + } + + /* Re-enable interrupts if they were disabled */ + if (Flags & EFLAGS_INTERRUPT_MASK) _enable(); + } + + /* Tell the caller to do a break */ + return DoBreak; +} +
Added: branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdtrap.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdtrap.c (added) +++ branches/alex-kd-branch/reactos/ntoskrnl/kd64/kdtrap.c Sun Feb 18 23:51:30 2007 @@ -1,0 +1,234 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kdtrap.c + * PURPOSE: KD64 Trap Handlers + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +KdpReport(IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT ContextRecord, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN SecondChanceException) +{ + BOOLEAN Entered, Status; + PKPRCB Prcb; + while (TRUE); + + /* + * Only go ahead with this if this is an INT3 or an INT1, or if the global + * flag forces us to call up the debugger on exception, or if this is a + * second chance exception which means it hasn't been handled by now. + */ + if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) || + (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) || + (NtGlobalFlag & FLG_STOP_ON_EXCEPTION) || + (SecondChanceException)) + { + /* + * Also, unless this is a second chance exception, then do not call up + * the debugger if the debug port is disconnected or the exception code + * indicates success. + */ + if (!(SecondChanceException) && + ((ExceptionRecord->ExceptionCode == STATUS_PORT_DISCONNECTED) || + (NT_SUCCESS(ExceptionRecord->ExceptionCode)))) + { + /* Return false to hide the exception */ + return FALSE; + } + + /* Enter the debugger */ + Entered = KdEnterDebugger(TrapFrame, ExceptionFrame); + + /* + * Get the KPRCB and save the CPU Control State manually instead of + * using KiSaveProcessorState, since we already have a valid CONTEXT. + */ + Prcb = KeGetCurrentPrcb(); + KiSaveProcessorControlState(&Prcb->ProcessorState); + RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, + ContextRecord, + sizeof(CONTEXT)); + + /* Report the new state */ +#if 0 + Status = KdpReportExceptionStateChange(ExceptionRecord, + &Prcb->ProcessorState. + ContextFrame, + SecondChanceException); +#else + Status = FALSE; +#endif + + /* Now restore the processor state, manually again. */ + RtlCopyMemory(ContextRecord, + &Prcb->ProcessorState.ContextFrame, + sizeof(CONTEXT)); + KiRestoreProcessorControlState(&Prcb->ProcessorState); + + /* Exit the debugger and clear the CTRL-C state */ + KdExitDebugger(Entered); + KdpControlCPressed = FALSE; + return Status; + } + + /* Fail if we got here */ + return FALSE; +} + +BOOLEAN +NTAPI +KdpTrap(IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT ContextRecord, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN SecondChanceException) +{ + BOOLEAN Unload = FALSE; + ULONG Eip, Eax; + BOOLEAN Status = FALSE; + while (TRUE); + + /* + * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or + * Load/Unload symbols. + */ + if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && + (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK)) + { + /* Save EIP */ + Eip = ContextRecord->Eip; + + /* Check what kind of operation was requested from us */ + switch (ExceptionRecord->ExceptionInformation[0]) + { + /* DbgPrint */ + case BREAKPOINT_PRINT: + + /* Call the worker routine */ + Eax = 0; + + /* Update the return value for the caller */ + ContextRecord->Eax = Eax; + break; + + /* DbgPrompt */ + case BREAKPOINT_PROMPT: + + /* Call the worker routine */ + Eax = 0; + Status = TRUE; + + /* Update the return value for the caller */ + ContextRecord->Eax = Eax; + break; + + /* DbgUnloadSymbols */ + case BREAKPOINT_UNLOAD_SYMBOLS: + + /* Drop into the load case below, with the unload parameter */ + Unload = TRUE; + + /* DbgLoadSymbols */ + case BREAKPOINT_LOAD_SYMBOLS: + + /* Call the worker routine */ + Status = TRUE; + break; + + /* DbgCommandString*/ + case BREAKPOINT_COMMAND_STRING: + + /* Call the worker routine */ + Status = TRUE; + + /* Anything else, do nothing */ + default: + + /* Get out */ + break; + } + + /* + * If EIP was not updated, we'll increment it ourselves so execution + * continues past the breakpoint. + */ + if (ContextRecord->Eip == Eip) ContextRecord->Eip++; + } + else + { + /* Call the worker routine */ + Status = KdpReport(TrapFrame, + ExceptionFrame, + ExceptionRecord, + ContextRecord, + PreviousMode, + SecondChanceException); + } + + /* Return TRUE or FALSE to caller */ + return Status; +} + +BOOLEAN +NTAPI +KdpStub(IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT ContextRecord, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN SecondChanceException) +{ + ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0]; + + /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */ + if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && + (ExceptionRecord->NumberParameters > 0) && + ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) || + (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) || + (ExceptionCommand == BREAKPOINT_COMMAND_STRING) || + (ExceptionCommand == BREAKPOINT_PRINT))) + { + /* This we can handle: simply bump EIP */ + ContextRecord->Eip++; + return TRUE; + } + else if (KdPitchDebugger) + { + /* There's no debugger, fail. */ + return FALSE; + } + else if ((KdAutoEnableOnEvent) && + (KdPreviouslyEnabled) && + !(KdDebuggerEnabled) && + (KdEnableDebugger()) && + (KdDebuggerEnabled)) + { + /* Debugging was Auto-Enabled. We can now send this to KD. */ + return KdpTrap(TrapFrame, + ExceptionFrame, + ExceptionRecord, + ContextRecord, + PreviousMode, + SecondChanceException); + } + else + { + /* FIXME: All we can do in this case is trace this exception */ + return FALSE; + } +}
Modified: branches/alex-kd-branch/reactos/ntoskrnl/ke/i386/exp.c URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/ke/i386/exp.c (original) +++ branches/alex-kd-branch/reactos/ntoskrnl/ke/i386/exp.c Sun Feb 18 23:51:30 2007 @@ -15,47 +15,6 @@ #include <debug.h>
/* GLOBALS *******************************************************************/ - -BOOLEAN -NTAPI -KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame, - IN PKEXCEPTION_FRAME ExceptionFrame, - IN PEXCEPTION_RECORD ExceptionRecord, - IN PCONTEXT Context, - IN KPROCESSOR_MODE PreviousMode, - IN BOOLEAN SecondChance) -{ - /* HACK (just like all this routine */ - if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) - { - Context->Eip++; - return TRUE; - } - - return FALSE; -} - -BOOLEAN -NTAPI -KdInitSystem(IN ULONG BootPhase, - IN PLOADER_PARAMETER_BLOCK LoaderBlock) -{ - /* STUB */ - return TRUE; -} - -BOOLEAN -NTAPI -KdPollBreakIn(VOID) -{ - /* STUB */ - return FALSE; -} - -BOOLEAN _KdDebuggerEnabled = FALSE; -BOOLEAN _KdDebuggerNotPresent = TRUE; -BOOLEAN KdBreakAfterSymbolLoad = FALSE; -PKDEBUG_ROUTINE KiDebugRoutine = KdpEnterDebuggerException;
/* DR Registers in the CONTEXT structure */ UCHAR KiDebugRegisterContextOffsets[9] =
Modified: branches/alex-kd-branch/reactos/ntoskrnl/ntoskrnl.rbuild URL: http://svn.reactos.org/svn/reactos/branches/alex-kd-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-kd-branch/reactos/ntoskrnl/ntoskrnl.rbuild (original) +++ branches/alex-kd-branch/reactos/ntoskrnl/ntoskrnl.rbuild Sun Feb 18 23:51:30 2007 @@ -193,6 +193,13 @@ <file>pnproot.c</file> </directory> </directory> + <directory name="kd64"> + <file>kdapi.c</file> + <file>kddata.c</file> + <file>kdinit.c</file> + <file>kdlock.c</file> + <file>kdtrap.c</file> + </directory> <directory name="ldr"> <file>loader.c</file> <file>rtl.c</file>