Author: sginsberg Date: Tue Oct 13 21:45:40 2009 New Revision: 43440
URL: http://svn.reactos.org/svn/reactos?rev=43440&view=rev Log: - Add the MMDBG_COPY_* flags and MmDbgCopyMemory's prototype. - Add KdpCopyMemoryChunks and use it to handle virtual memory read/write (physical memory support still stubbed). The actual copy is still a hack and its only safeguard against invalid memory is still a simple check for NULL. - Properly implement KdpReadVirtualMemory, KdpWriteVirtualMemory, KdpReadPhysicalmemory and KdpWritePhysicalmemory using KdpCopyMemoryChunks. - Merge Timo's ReportFlags fix from the AMD64 branch. - Implement KdpSysWriteMsr and KdpSysReadMsr for x86. SEH is commented as our GPF handler seems to swallow exceptions caused by accessing invalid MSRs. - Change DataValue parameter of KdpSysReadIoSpace and KdpSysWriteIoSpace to PVOID to better match how it is used.
Modified: trunk/reactos/ntoskrnl/include/internal/kd64.h trunk/reactos/ntoskrnl/include/internal/ke.h trunk/reactos/ntoskrnl/include/internal/mm.h trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c trunk/reactos/ntoskrnl/kd64/arm/kdsup.c trunk/reactos/ntoskrnl/kd64/i386/kdsup.c trunk/reactos/ntoskrnl/kd64/kdapi.c
Modified: trunk/reactos/ntoskrnl/include/internal/kd64.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/kd64.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/kd64.h [iso-8859-1] Tue Oct 13 21:45:40 2009 @@ -374,7 +374,7 @@ IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize ); @@ -386,7 +386,7 @@ IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize );
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Tue Oct 13 21:45:40 2009 @@ -192,87 +192,6 @@
/* INTERNAL KERNEL FUNCTIONS ************************************************/
-/* Finds a new thread to run */ -NTSTATUS -FASTCALL -KiSwapThread( - IN PKTHREAD Thread, - IN PKPRCB Prcb -); - -VOID -NTAPI -KeReadyThread( - IN PKTHREAD Thread -); - -BOOLEAN -NTAPI -KeSetDisableBoostThread( - IN OUT PKTHREAD Thread, - IN BOOLEAN Disable -); - -VOID -NTAPI -KeBalanceSetManager(IN PVOID Context); - -VOID -NTAPI -KiReadyThread(IN PKTHREAD Thread); - -ULONG -NTAPI -KeSuspendThread(PKTHREAD Thread); - -BOOLEAN -NTAPI -KeReadStateThread(IN PKTHREAD Thread); - -BOOLEAN -FASTCALL -KiSwapContext( - IN PKTHREAD CurrentThread, - IN PKTHREAD NewThread -); - -VOID -NTAPI -KiAdjustQuantumThread(IN PKTHREAD Thread); - -VOID -FASTCALL -KiExitDispatcher(KIRQL OldIrql); - -VOID -FASTCALL -KiDeferredReadyThread(IN PKTHREAD Thread); - -PKTHREAD -FASTCALL -KiIdleSchedule( - IN PKPRCB Prcb -); - -VOID -FASTCALL -KiProcessDeferredReadyList( - IN PKPRCB Prcb -); - -KAFFINITY -FASTCALL -KiSetAffinityThread( - IN PKTHREAD Thread, - IN KAFFINITY Affinity -); - -PKTHREAD -FASTCALL -KiSelectNextThread( - IN PKPRCB Prcb -); - VOID NTAPI CPUID( @@ -281,6 +200,100 @@ OUT PULONG CpuInfoEbx, OUT PULONG CpuInfoEcx, OUT PULONG CpuInfoEdx +); + +LONGLONG +FASTCALL +RDMSR( + IN ULONG Register +); + +VOID +NTAPI +WRMSR( + IN ULONG Register, + IN LONGLONG Value +); + +/* Finds a new thread to run */ +NTSTATUS +FASTCALL +KiSwapThread( + IN PKTHREAD Thread, + IN PKPRCB Prcb +); + +VOID +NTAPI +KeReadyThread( + IN PKTHREAD Thread +); + +BOOLEAN +NTAPI +KeSetDisableBoostThread( + IN OUT PKTHREAD Thread, + IN BOOLEAN Disable +); + +VOID +NTAPI +KeBalanceSetManager(IN PVOID Context); + +VOID +NTAPI +KiReadyThread(IN PKTHREAD Thread); + +ULONG +NTAPI +KeSuspendThread(PKTHREAD Thread); + +BOOLEAN +NTAPI +KeReadStateThread(IN PKTHREAD Thread); + +BOOLEAN +FASTCALL +KiSwapContext( + IN PKTHREAD CurrentThread, + IN PKTHREAD NewThread +); + +VOID +NTAPI +KiAdjustQuantumThread(IN PKTHREAD Thread); + +VOID +FASTCALL +KiExitDispatcher(KIRQL OldIrql); + +VOID +FASTCALL +KiDeferredReadyThread(IN PKTHREAD Thread); + +PKTHREAD +FASTCALL +KiIdleSchedule( + IN PKPRCB Prcb +); + +VOID +FASTCALL +KiProcessDeferredReadyList( + IN PKPRCB Prcb +); + +KAFFINITY +FASTCALL +KiSetAffinityThread( + IN PKTHREAD Thread, + IN KAFFINITY Affinity +); + +PKTHREAD +FASTCALL +KiSelectNextThread( + IN PKPRCB Prcb );
BOOLEAN @@ -1006,13 +1019,6 @@ NTAPI KiI386PentiumLockErrataFixup(VOID);
-VOID -NTAPI -WRMSR( - IN ULONG Register, - IN LONGLONG Value -); - BOOLEAN NTAPI KeFreezeExecution(IN PKTRAP_FRAME TrapFrame,
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/m... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] Tue Oct 13 21:45:40 2009 @@ -29,6 +29,22 @@ struct _MM_PAGEOP; typedef ULONG SWAPENTRY; typedef ULONG PFN_TYPE, *PPFN_TYPE; + +// +//MmDbgCopyMemory Flags +// +#define MMDBG_COPY_WRITE 0x00000001 +#define MMDBG_COPY_PHYSICAL 0x00000002 +#define MMDBG_COPY_UNSAFE 0x00000004 +#define MMDBG_COPY_CACHED 0x00000008 +#define MMDBG_COPY_UNCACHED 0x00000010 +#define MMDBG_COPY_WRITE_COMBINED 0x00000020 + +// +// Maximum chunk size per copy +// +#define MMDBG_COPY_MAX_SIZE 0x8 +
#define MI_STATIC_MEMORY_AREAS (8)
@@ -455,6 +471,18 @@ BOOLEAN Dirty );
+// +// Mm copy support for Kd +// +NTSTATUS +NTAPI +MmDbgCopyMemory( + IN ULONG64 Address, + IN PVOID Buffer, + IN ULONG Size, + IN ULONG Flags +); + /* marea.c *******************************************************************/
NTSTATUS
Modified: trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c [iso-8859-1] Tue Oct 13 21:45:40 2009 @@ -125,7 +125,7 @@ IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { @@ -140,7 +140,7 @@ IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) {
Modified: trunk/reactos/ntoskrnl/kd64/arm/kdsup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/arm/kdsup.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/arm/kdsup.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/arm/kdsup.c [iso-8859-1] Tue Oct 13 21:45:40 2009 @@ -125,7 +125,7 @@ IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { @@ -140,7 +140,7 @@ IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) {
Modified: trunk/reactos/ntoskrnl/kd64/i386/kdsup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/i386/kdsup.c?... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/i386/kdsup.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/i386/kdsup.c [iso-8859-1] Tue Oct 13 21:45:40 2009 @@ -95,7 +95,7 @@ WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS; if (WaitStateChange->ControlReport.SegCs == KGDT_R0_CODE) { - WaitStateChange->ControlReport.ReportFlags = REPORT_STANDARD_CS; + WaitStateChange->ControlReport.ReportFlags |= REPORT_STANDARD_CS; } }
@@ -104,9 +104,21 @@ KdpSysReadMsr(IN ULONG Msr, OUT PLARGE_INTEGER MsrValue) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_UNSUCCESSFUL; + /* Wrap this in SEH in case the MSR doesn't exist */ + //_SEH2_TRY + { + /* Read from the MSR */ + MsrValue->QuadPart = RDMSR(Msr); + } + //_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Invalid MSR */ + //_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE); + } + //_SEH2_END; + + /* Success */ + return STATUS_SUCCESS; }
NTSTATUS @@ -114,9 +126,21 @@ KdpSysWriteMsr(IN ULONG Msr, IN PLARGE_INTEGER MsrValue) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_UNSUCCESSFUL; + /* Wrap this in SEH in case the MSR doesn't exist */ + //_SEH2_TRY + { + /* Write to the MSR */ + WRMSR(Msr, MsrValue->QuadPart); + } + //_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Invalid MSR */ + //_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE); + } + //_SEH2_END; + + /* Success */ + return STATUS_SUCCESS; }
NTSTATUS @@ -228,7 +252,7 @@ IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { @@ -243,7 +267,7 @@ IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) {
Modified: trunk/reactos/ntoskrnl/kd64/kdapi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdapi.c?rev=4... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] Tue Oct 13 21:45:40 2009 @@ -13,6 +13,76 @@ #include <debug.h>
/* PRIVATE FUNCTIONS *********************************************************/ + +NTSTATUS +NTAPI +KdpCopyMemoryChunks(IN ULONG64 Address, + IN PVOID Buffer, + IN ULONG TotalSize, + IN ULONG ChunkSize, + IN ULONG Flags, + OUT PULONG ActualSize OPTIONAL) +{ + ULONG Length; + NTSTATUS Status; + + /* Check if this is physical or virtual copy */ + if (Flags & MMDBG_COPY_PHYSICAL) + { + /* Fail physical memory read/write for now */ + if (Flags & MMDBG_COPY_WRITE) + { + KdpDprintf("KdpCopyMemoryChunks: Failing write for Physical Address 0x%I64x Length: %x\n", + Address, + TotalSize); + } + else + { + KdpDprintf("KdpCopyMemoryChunks: Failing read for Physical Address 0x%I64x Length: %x\n", + Address, + TotalSize); + } + + /* Return an error */ + Length = 0; + Status = STATUS_UNSUCCESSFUL; + } + else + { + /* Protect against NULL */ + if (!Address) + { + if (ActualSize) *ActualSize = 0; + return STATUS_UNSUCCESSFUL; + } + + /* Check if this is read or write */ + if (Flags & MMDBG_COPY_WRITE) + { + /* Do the write */ + RtlCopyMemory((PVOID)(ULONG_PTR)Address, + Buffer, + TotalSize); + } + else + { + /* Do the read */ + RtlCopyMemory(Buffer, + (PVOID)(ULONG_PTR)Address, + TotalSize); + } + + /* Set size and status */ + Length = TotalSize; + Status = STATUS_SUCCESS; + } + + /* Return the actual length if requested */ + if (ActualSize) *ActualSize = Length; + + /* Return status */ + return Status; +}
VOID NTAPI @@ -264,9 +334,14 @@ IN PSTRING Data, IN PCONTEXT Context) { - STRING Header; - ULONG Length = State->u.ReadMemory.TransferCount; - NTSTATUS Status = STATUS_SUCCESS; + PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory; + STRING Header; + ULONG Length = ReadMemory->TransferCount; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + ASSERT(Data->Length == 0);
/* Validate length */ if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) @@ -275,35 +350,16 @@ Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); }
-#if 0 - if (!MmIsAddressValid((PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress)) - { - KdpDprintf("Tried to read invalid address %p\n", - (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress); - while (TRUE); - } -#endif - - if (!State->u.ReadMemory.TargetBaseAddress) - { - Length = 0; - Status = STATUS_UNSUCCESSFUL; - } - else - { - RtlCopyMemory(Data->Buffer, - (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress, - Length); - } - - /* Fill out the header */ - Data->Length = Length; - Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); - Header.Buffer = (PCHAR)State; - - /* Fill out the state */ - State->ReturnStatus = Status; - State->u.ReadMemory.ActualBytesRead = Length; + /* Do the read */ + State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress, + Data->Buffer, + Length, + 0, + MMDBG_COPY_UNSAFE, + &Length); + + /* Return the actual length read */ + Data->Length = ReadMemory->ActualBytesRead = Length;
/* Send the packet */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, @@ -318,11 +374,27 @@ IN PSTRING Data, IN PCONTEXT Context) { - /* FIXME: STUB */ - KdpDprintf("KdpWriteVirtualMemory called for Address: %p Length %x\n", - (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress, - State->u.ReadMemory.TransferCount); - while (TRUE); + PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; + STRING Header; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + + /* Do the write */ + State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress, + Data->Buffer, + Data->Length, + 0, + MMDBG_COPY_UNSAFE | + MMDBG_COPY_WRITE, + &WriteMemory->ActualBytesWritten); + + /* Send the packet */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + NULL, + &KdpContext); }
VOID @@ -331,20 +403,56 @@ IN PSTRING Data, IN PCONTEXT Context) { - STRING Header; - - /* FIXME: STUB */ - KdpDprintf("KdpWritePhysicalMemory called for Address %I64x Length: %x\n", - State->u.ReadMemory.TargetBaseAddress, - State->u.ReadMemory.TransferCount); - - /* Setup an empty message, with failure */ - Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); - Header.Buffer = (PCHAR)State; - Data->Length = 0; - State->ReturnStatus = STATUS_UNSUCCESSFUL; - - /* Send it */ + PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory; + STRING Header; + ULONG Length = ReadMemory->TransferCount; + ULONG Flags, CacheFlags; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + ASSERT(Data->Length == 0); + + /* Validate length */ + if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) + { + /* Overflow, set it to maximum possible */ + Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); + } + + /* Start with the default flags */ + Flags = MMDBG_COPY_UNSAFE | MMDBG_COPY_PHYSICAL; + + /* Get the caching flags and check if a type is specified */ + CacheFlags = ReadMemory->ActualBytesRead; + if (CacheFlags == DBGKD_CACHING_CACHED) + { + /* Cached */ + Flags |= MMDBG_COPY_CACHED; + } + else if (CacheFlags == DBGKD_CACHING_UNCACHED) + { + /* Uncached */ + Flags |= MMDBG_COPY_UNCACHED; + } + else if (CacheFlags == DBGKD_CACHING_UNCACHED) + { + /* Write Combined */ + Flags |= DBGKD_CACHING_WRITE_COMBINED; + } + + /* Do the read */ + State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress, + Data->Buffer, + Length, + 0, + Flags, + &Length); + + /* Return the actual length read */ + Data->Length = ReadMemory->ActualBytesRead = Length; + + /* Send the packet */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Header, Data, @@ -357,23 +465,47 @@ IN PSTRING Data, IN PCONTEXT Context) { - STRING Header; - - /* FIXME: STUB */ - KdpDprintf("KdpWritePhysicalMemory called for Address %I64x Length: %x\n", - State->u.ReadMemory.TargetBaseAddress, - State->u.ReadMemory.TransferCount); - - /* Setup an empty message, with failure */ - Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); - Header.Buffer = (PCHAR)State; - Data->Length = 0; - State->ReturnStatus = STATUS_UNSUCCESSFUL; - - /* Send it */ - KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, - &Header, - Data, + PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; + STRING Header; + ULONG Flags, CacheFlags; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + + /* Start with the default flags */ + Flags = MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE | MMDBG_COPY_PHYSICAL; + + /* Get the caching flags and check if a type is specified */ + CacheFlags = WriteMemory->ActualBytesWritten; + if (CacheFlags == DBGKD_CACHING_CACHED) + { + /* Cached */ + Flags |= MMDBG_COPY_CACHED; + } + else if (CacheFlags == DBGKD_CACHING_UNCACHED) + { + /* Uncached */ + Flags |= MMDBG_COPY_UNCACHED; + } + else if (CacheFlags == DBGKD_CACHING_UNCACHED) + { + /* Write Combined */ + Flags |= DBGKD_CACHING_WRITE_COMBINED; + } + + /* Do the write */ + State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress, + Data->Buffer, + Data->Length, + 0, + Flags, + &WriteMemory->ActualBytesWritten); + + /* Send the packet */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + NULL, &KdpContext); }
@@ -425,7 +557,6 @@ { PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; STRING Header; - ULONG Length;
/* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); @@ -436,10 +567,7 @@ WriteMemory->TargetBaseAddress, Data->Buffer, Data->Length, - &Length); - - /* Return the length written */ - WriteMemory->ActualBytesWritten = Length; + &WriteMemory->ActualBytesWritten);
/* Send the reply */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, @@ -835,7 +963,7 @@ Header.Buffer = (PCHAR)State;
/* Call the internal routine */ - State->ReturnStatus = KdpSysCheckLowMemory(0x4); + State->ReturnStatus = KdpSysCheckLowMemory(MMDBG_COPY_UNSAFE);
/* Send the reply */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,