diff --git a/reactos/ntoskrnl/include/internal/kd64.h b/reactos/ntoskrnl/include/internal/kd64.h index 61d84e55c63..213c83219a1 100644 --- a/reactos/ntoskrnl/include/internal/kd64.h +++ b/reactos/ntoskrnl/include/internal/kd64.h @@ -374,7 +374,7 @@ KdpSysReadIoSpace( 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 @@ KdpSysWriteIoSpace( IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize ); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index ef5458aa748..a85180e8daa 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -192,6 +192,29 @@ extern ULONG KiDPCTimeout; /* INTERNAL KERNEL FUNCTIONS ************************************************/ +VOID +NTAPI +CPUID( + IN ULONG InfoType, + OUT PULONG CpuInfoEax, + 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 @@ -273,16 +296,6 @@ KiSelectNextThread( IN PKPRCB Prcb ); -VOID -NTAPI -CPUID( - IN ULONG InfoType, - OUT PULONG CpuInfoEax, - OUT PULONG CpuInfoEbx, - OUT PULONG CpuInfoEcx, - OUT PULONG CpuInfoEdx -); - BOOLEAN FASTCALL KiInsertTimerTable( @@ -1006,13 +1019,6 @@ VOID NTAPI KiI386PentiumLockErrataFixup(VOID); -VOID -NTAPI -WRMSR( - IN ULONG Register, - IN LONGLONG Value -); - BOOLEAN NTAPI KeFreezeExecution(IN PKTRAP_FRAME TrapFrame, diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index a247a08105b..4237c75bd11 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -30,6 +30,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) #define MEMORY_AREA_INVALID (0) @@ -455,6 +471,18 @@ typedef VOID 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 diff --git a/reactos/ntoskrnl/kd64/amd64/kdsup.c b/reactos/ntoskrnl/kd64/amd64/kdsup.c index ba07617060c..06c08c59f3c 100644 --- a/reactos/ntoskrnl/kd64/amd64/kdsup.c +++ b/reactos/ntoskrnl/kd64/amd64/kdsup.c @@ -125,7 +125,7 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, 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 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { diff --git a/reactos/ntoskrnl/kd64/arm/kdsup.c b/reactos/ntoskrnl/kd64/arm/kdsup.c index 44857e65cb3..3c4dc94e641 100644 --- a/reactos/ntoskrnl/kd64/arm/kdsup.c +++ b/reactos/ntoskrnl/kd64/arm/kdsup.c @@ -125,7 +125,7 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, 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 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { diff --git a/reactos/ntoskrnl/kd64/i386/kdsup.c b/reactos/ntoskrnl/kd64/i386/kdsup.c index 69d1f341297..5aa98546185 100644 --- a/reactos/ntoskrnl/kd64/i386/kdsup.c +++ b/reactos/ntoskrnl/kd64/i386/kdsup.c @@ -95,7 +95,7 @@ KdpSetContextState(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange, 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 @@ NTAPI 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 @@ NTAPI 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 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, 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 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { diff --git a/reactos/ntoskrnl/kd64/kdapi.c b/reactos/ntoskrnl/kd64/kdapi.c index c4a213df3de..c899f2b052e 100644 --- a/reactos/ntoskrnl/kd64/kdapi.c +++ b/reactos/ntoskrnl/kd64/kdapi.c @@ -14,6 +14,76 @@ /* 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 KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State, @@ -264,9 +334,14 @@ KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) { + PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory; STRING Header; - ULONG Length = State->u.ReadMemory.TransferCount; - NTSTATUS Status = STATUS_SUCCESS; + 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 @@ KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State, 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 + /* Do the read */ + State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress, + Data->Buffer, + Length, + 0, + MMDBG_COPY_UNSAFE, + &Length); - 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; + /* Return the actual length read */ + Data->Length = ReadMemory->ActualBytesRead = Length; /* Send the packet */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, @@ -318,11 +374,27 @@ KdpWriteVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State, 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 @@ KdpReadPhysicalmemory(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) { + PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory; STRING Header; + ULONG Length = ReadMemory->TransferCount; + ULONG Flags, CacheFlags; - /* 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 */ + /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); Header.Buffer = (PCHAR)State; - Data->Length = 0; - State->ReturnStatus = STATUS_UNSUCCESSFUL; + ASSERT(Data->Length == 0); - /* Send it */ + /* 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 @@ KdpWritePhysicalmemory(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) { + PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; STRING Header; + ULONG Flags, CacheFlags; - /* 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 */ + /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); Header.Buffer = (PCHAR)State; - Data->Length = 0; - State->ReturnStatus = STATUS_UNSUCCESSFUL; - /* Send it */ + /* 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, - Data, + NULL, &KdpContext); } @@ -425,7 +557,6 @@ KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State, { PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; STRING Header; - ULONG Length; /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); @@ -436,10 +567,7 @@ KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State, 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 @@ KdpCheckLowMemory(IN PDBGKD_MANIPULATE_STATE64 State) 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,