ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
February 2012
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
22 participants
577 discussions
Start a n
N
ew thread
[tkreuzer] 55405: [NTOSKRNL/KE/AMD64] - Fix stack alignment in KiSwitchToBootStack - Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext - Implement KiSwapContextInternal...
by tkreuzer@svn.reactos.org
Author: tkreuzer Date: Sat Feb 4 11:32:13 2012 New Revision: 55405 URL:
http://svn.reactos.org/svn/reactos?rev=55405&view=rev
Log: [NTOSKRNL/KE/AMD64] - Fix stack alignment in KiSwitchToBootStack - Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext - Implement KiSwapContextInternal - Fix KiSwapContext and KiThreadStartup - Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger - Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution - Don't zero more than the actual PCR size in KiInitializePcr - Add asm function KiInitializeSegments to initialize the segment selectors to proper values - Initialize system call entrypoints in KiInitializeCpu - Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume - Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService Modified: trunk/reactos/ntoskrnl/ke/amd64/boot.S trunk/reactos/ntoskrnl/ke/amd64/context.c trunk/reactos/ntoskrnl/ke/amd64/ctxswitch.S trunk/reactos/ntoskrnl/ke/amd64/except.c trunk/reactos/ntoskrnl/ke/amd64/interrupt.c trunk/reactos/ntoskrnl/ke/amd64/kiinit.c trunk/reactos/ntoskrnl/ke/amd64/stubs.c trunk/reactos/ntoskrnl/ke/amd64/thrdini.c trunk/reactos/ntoskrnl/ke/amd64/trap.S Modified: trunk/reactos/ntoskrnl/ke/amd64/boot.S URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/boot.S?r…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/boot.S [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/boot.S [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -31,7 +31,9 @@ mov ax, HEX(18) mov ss, ax mov rsp, rcx - sub rsp, HEX(300) // FIXME + // Note: 8 bytes extra to compensate for the missing return address on + // the stack. On function entry the stack is unaligned by 8!! + sub rsp, HEX(308) // FIXME .ENDPROLOG jmp KiSystemStartupBootStack Modified: trunk/reactos/ntoskrnl/ke/amd64/context.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/context.…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/context.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/context.c [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -24,12 +24,16 @@ { KIRQL OldIrql; + /* Make sure we have an amd64 context, then remove the flag */ + ASSERT(ContextFlags & CONTEXT_AMD64); + ContextFlags &= ~CONTEXT_AMD64; + /* Do this at APC_LEVEL */ OldIrql = KeGetCurrentIrql(); if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql); /* Handle integer registers */ - if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) + if (ContextFlags & CONTEXT_INTEGER) { TrapFrame->Rax = Context->Rax; TrapFrame->Rbx = Context->Rbx; @@ -42,15 +46,18 @@ TrapFrame->R9 = Context->R9; TrapFrame->R10 = Context->R10; TrapFrame->R11 = Context->R11; - ExceptionFrame->R12 = Context->R12; - ExceptionFrame->R13 = Context->R13; - ExceptionFrame->R14 = Context->R14; - ExceptionFrame->R15 = Context->R15; + if (ExceptionFrame) + { + ExceptionFrame->R12 = Context->R12; + ExceptionFrame->R13 = Context->R13; + ExceptionFrame->R14 = Context->R14; + ExceptionFrame->R15 = Context->R15; + } } /* Handle floating point registers */ - if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) == - CONTEXT_FLOATING_POINT) && (Context->SegCs & MODE_MASK)) + if ((ContextFlags & CONTEXT_FLOATING_POINT) && + (Context->SegCs & MODE_MASK)) { TrapFrame->Xmm0 = Context->Xmm0; TrapFrame->Xmm1 = Context->Xmm1; @@ -58,20 +65,23 @@ TrapFrame->Xmm3 = Context->Xmm3; TrapFrame->Xmm4 = Context->Xmm4; TrapFrame->Xmm5 = Context->Xmm5; - ExceptionFrame->Xmm6 = Context->Xmm6; - ExceptionFrame->Xmm7 = Context->Xmm7; - ExceptionFrame->Xmm8 = Context->Xmm8; - ExceptionFrame->Xmm9 = Context->Xmm9; - ExceptionFrame->Xmm10 = Context->Xmm10; - ExceptionFrame->Xmm11 = Context->Xmm11; - ExceptionFrame->Xmm12 = Context->Xmm12; - ExceptionFrame->Xmm13 = Context->Xmm13; - ExceptionFrame->Xmm14 = Context->Xmm14; - ExceptionFrame->Xmm15 = Context->Xmm15; + if (ExceptionFrame) + { + ExceptionFrame->Xmm6 = Context->Xmm6; + ExceptionFrame->Xmm7 = Context->Xmm7; + ExceptionFrame->Xmm8 = Context->Xmm8; + ExceptionFrame->Xmm9 = Context->Xmm9; + ExceptionFrame->Xmm10 = Context->Xmm10; + ExceptionFrame->Xmm11 = Context->Xmm11; + ExceptionFrame->Xmm12 = Context->Xmm12; + ExceptionFrame->Xmm13 = Context->Xmm13; + ExceptionFrame->Xmm14 = Context->Xmm14; + ExceptionFrame->Xmm15 = Context->Xmm15; + } } /* Handle control registers */ - if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) + if (ContextFlags & CONTEXT_CONTROL) { /* Check if this was a Kernel Trap */ if (Context->SegCs == KGDT64_R0_CODE) @@ -94,7 +104,7 @@ } /* Handle segment selectors */ - if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) + if (ContextFlags & CONTEXT_SEGMENTS) { /* Check if this was a Kernel Trap */ if (Context->SegCs == KGDT64_R0_CODE) @@ -116,8 +126,7 @@ } /* Handle debug registers */ - if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == - CONTEXT_DEBUG_REGISTERS) + if (ContextFlags & CONTEXT_DEBUG_REGISTERS) { /* Copy the debug registers */ TrapFrame->Dr0 = Context->Dr0; @@ -158,10 +167,14 @@ Context->R9 = TrapFrame->R9; Context->R10 = TrapFrame->R10; Context->R11 = TrapFrame->R11; - Context->R12 = ExceptionFrame->R12; - Context->R13 = ExceptionFrame->R13; - Context->R14 = ExceptionFrame->R14; - Context->R15 = ExceptionFrame->R15; + + if (ExceptionFrame) + { + Context->R12 = ExceptionFrame->R12; + Context->R13 = ExceptionFrame->R13; + Context->R14 = ExceptionFrame->R14; + Context->R15 = ExceptionFrame->R15; + } } /* Handle floating point registers */ @@ -174,16 +187,19 @@ Context->Xmm3 = TrapFrame->Xmm3; Context->Xmm4 = TrapFrame->Xmm4; Context->Xmm5 = TrapFrame->Xmm5; - Context->Xmm6 = ExceptionFrame->Xmm6; - Context->Xmm7 = ExceptionFrame->Xmm7; - Context->Xmm8 = ExceptionFrame->Xmm8; - Context->Xmm9 = ExceptionFrame->Xmm9; - Context->Xmm10 = ExceptionFrame->Xmm10; - Context->Xmm11 = ExceptionFrame->Xmm11; - Context->Xmm12 = ExceptionFrame->Xmm12; - Context->Xmm13 = ExceptionFrame->Xmm13; - Context->Xmm14 = ExceptionFrame->Xmm14; - Context->Xmm15 = ExceptionFrame->Xmm15; + if (ExceptionFrame) + { + Context->Xmm6 = ExceptionFrame->Xmm6; + Context->Xmm7 = ExceptionFrame->Xmm7; + Context->Xmm8 = ExceptionFrame->Xmm8; + Context->Xmm9 = ExceptionFrame->Xmm9; + Context->Xmm10 = ExceptionFrame->Xmm10; + Context->Xmm11 = ExceptionFrame->Xmm11; + Context->Xmm12 = ExceptionFrame->Xmm12; + Context->Xmm13 = ExceptionFrame->Xmm13; + Context->Xmm14 = ExceptionFrame->Xmm14; + Context->Xmm15 = ExceptionFrame->Xmm15; + } } /* Handle control registers */ Modified: trunk/reactos/ntoskrnl/ke/amd64/ctxswitch.S URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/ctxswitc…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/ctxswitch.S [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/ctxswitch.S [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/amd64/ctxswitch.S * PURPOSE: Thread Context Switching - * + * * PROGRAMMER: Timo kreuzer (timo.kreuzer(a)reactos.org) */ @@ -12,46 +12,66 @@ #include <asm.inc> #include <ksamd64.inc> +EXTERN KiSwapContextResume:PROC + /* FUNCTIONS ****************************************************************/ .code64 -/*++ - * KiThreadStartup - * +/*! + * \name KiThreadStartup + * + * \brief * The KiThreadStartup routine is the beginning of any thread. * - * Params: - * SystemRoutine - Pointer to the System Startup Routine. Either - * PspUserThreadStartup or PspSystemThreadStartup - * - * StartRoutine - For Kernel Threads only, specifies the starting execution - * point of the new thread. - * - * StartContext - For Kernel Threads only, specifies a pointer to variable - * context data to be sent to the StartRoutine above. - * - * UserThread - Indicates whether or not this is a user thread. This tells - * us if the thread has a context or not. - * - * TrapFrame - Pointer to the KTHREAD to which the caller wishes to - * switch from. - * - * Returns: + * VOID + * KiThreadStartup( + * IN PKSTART_ROUTINE StartRoutine<rcx>, + * IN PVOID StartContext<rdx>, + * IN PVOID P3<r8>, + * IN PVOID P4<r9>, + * IN PVOID SystemRoutine); + * + * \param StartRoutine + * For Kernel Threads only, specifies the starting execution point + * of the new thread. + * + * \param StartContext + * For Kernel Threads only, specifies a pointer to variable + * context data to be sent to the StartRoutine above. + * + * \param P3, P4 - not used atm + * + * \param SystemRoutine + * Pointer to the System Startup Routine. + * Either PspUserThreadStartup or PspSystemThreadStartup + * + * \return * Should never return for a system thread. Returns through the System Call * Exit Dispatcher for a user thread. * - * Remarks: + * \remarks * If a return from a system thread is detected, a bug check will occur. * *--*/ PUBLIC KiThreadStartup -KiThreadStartup: - - /* - * Clear all the non-volatile registers, so the thread won't be tempted to - * expect any static data (like some badly coded usermode/win9x apps do) +.PROC KiThreadStartup + /* KSTART_FRAME is already on the stack when we enter here. + * The virtual prolog looks like this: + * sub rsp, 5 * 8 + * mov [rsp + SfP1Home], rcx + * mov [rsp + SfP2Home], rdx + * mov [rsp + SfP3Home], r8 + * mov [rsp + SfP4Home], r9 */ + + /* Terminate the unwind chain, by setting rbp as frame pointer, + which contains 0 */ + .setframe rbp, 0 + .endprolog + + /* Clear all the non-volatile registers, so the thread won't be tempted to + * expect any static data (like some badly coded usermode/win9x apps do) */ xor rbx, rbx xor rsi, rsi xor rdi, rdi @@ -67,73 +87,107 @@ mov rax, APC_LEVEL mov cr8, rax - /* - * Call the System Routine which is right on our stack now. - * After we pop the pointer, the Start Routine/Context is on the - * stack, we pop it as parameters to the System Routine into rcx - */ - pop rax - pop rcx - call rax - - /* The thread returned... was it a user-thread? */ - pop rcx + /* We have the KSTART_FRAME on the stack, P1Home and P2Home are preloaded + * with the parameters for the system routine. The address of the system + * routine is stored in P4Home. */ + mov rcx, [rsp + SfP1Home] /* StartRoutine */ + mov rdx, [rsp + SfP2Home] /* StartContext */ + mov r8, [rsp + SfP3Home] /* ? */ + call qword ptr [rsp + SfP4Home] /* SystemRoutine */ + + /* The thread returned. If it was a user-thread, we have a return address + and all is well, otherwise this is very bad. */ + mov rcx, [rsp + SfReturn] or rcx, rcx - jz BadThread - - /* Yes it was, set our trapframe for the System Call Exit Dispatcher */ - mov ebp, esp - - /* Exit back to user-mode */ -// jmp _KiServiceExit2 -UNIMPLEMENTED KiThreadStartup_KiServiceExit2 - -BadThread: + jnz .leave /* A system thread returned...this is very bad! */ int 3 - -/*++ - * KiSwapContextInternal - * +.leave: + /* It was a user thread, set our trapframe for the System Call Exit Dispatcher */ + lea rcx, [rsp + 6 * 8 + KEXCEPTION_FRAME_LENGTH] + + /* Return to the trap exit code */ + add rsp, 5 * 8 + ret +.ENDP + +/*! + * \name KiSwapContextInternal + * + * \brief * The KiSwapContextInternal routine switches context to another thread. * - * Params: - * ESI - Pointer to the KTHREAD to which the caller wishes to - * switch to. - * EDI - Pointer to the KTHREAD to which the caller wishes to - * switch from. - * - * Returns: + * \param rcx + * Pointer to the KTHREAD to which the caller wishes to switch to. + * + * \param rdx + * Pointer to the KTHREAD to which the caller wishes to switch from. + * + * \param r8b + * APC bypass + * + * \return * None. * - * Remarks: - * Absolutely all registers except ESP can be trampled here for maximum code flexibility. + * \remarks + * ... * *--*/ PUBLIC KiSwapContextInternal -KiSwapContextInternal: - UNIMPLEMENTED KiSwapContextInternal +.PROC KiSwapContextInternal + + push rbp + .pushreg rbp + sub rsp, 6 * 8 + .allocstack 6 * 8 + .endprolog + + /* Save APC bypass */ + mov [rsp + SwApcBypass], r8b + + /* Save kernel stack of old thread */ + mov [rdx + KTHREAD_KernelStack], rsp + + /* Save new thread in rbp */ + mov rbp, rcx + + //call KiSwapContextSuspend + + /* Load stack of new thread */ + mov rsp, [rbp + KTHREAD_KernelStack] + + /* Reload APC bypass */ + mov r8b, [rsp + SwApcBypass] + + call KiSwapContextResume + + /* Cleanup and return */ + add rsp, 6 * 8 + pop rbp ret - -/** +.ENDP + + + +/*! * KiSwapContext * * \brief * The KiSwapContext routine switches context to another thread. * * BOOLEAN - * KiSwapContext(PKTHREAD CurrentThread, PKTHREAD TargetThread); - * - * \param CurrentThread + * KiSwapContext(KIRQL WaitIrql, PKTHREAD CurrentThread); + * + * \param WaitIrql <rcx> + * ... + * + * \param CurrentThread <rdx> * Pointer to the KTHREAD of the current thread. - * - * \param TargetThread - * Pointer to the KTHREAD to which the caller wishes to switch to. - * - * \returns + * + * \return * The WaitStatus of the Target Thread. * * \remarks @@ -141,59 +195,74 @@ * non-volatile registers so that the Internal function can use all of * them. It will also save the old current thread and set the new one. * - * The calling thread does not return after KiSwapContextInternal until + * The calling thread does not return after KiSwapContextInternal until * another thread switches to IT. * *--*/ PUBLIC KiSwapContext -KiSwapContext: - - /* Save 10 registers */ - sub rsp, 10 * 8 - - /* Save all the non-volatile ones */ - mov [rsp+72], r15 - mov [rsp+64], r14 - mov [rsp+56], r13 - mov [rsp+48], r12 - mov [rsp+40], r11 - mov [rsp+32], r10 - - mov [rsp+24], rbx - mov [rsp+16], rsi - mov [rsp+8], rdi - mov [rsp+0], rbp - - /* Get the PCR */ - mov rbx, gs:[PcSelf] - - /* Get the current thread */ - mov rdi, rcx - - /* Get the New Thread */ - mov rsi, rdx - - /* Get the wait IRQL */ - movzx ecx, byte ptr [edi+KTHREAD_WAIT_IRQL] +.PROC KiSwapContext + + /* Allocate a KEXCEPTION_FRAME on the stack (+8 for proper alignment) */ + sub rsp, KEXCEPTION_FRAME_LENGTH + 8 + .allocstack KEXCEPTION_FRAME_LENGTH + 8 + + /* save non-volatiles in KEXCEPTION_FRAME */ + mov [rsp + KEXCEPTION_FRAME_Rbp], rbp + .savereg rbp, KEXCEPTION_FRAME_Rbp + mov [rsp + KEXCEPTION_FRAME_Rbx], rbx + .savereg rbx, KEXCEPTION_FRAME_Rbx + mov [rsp + KEXCEPTION_FRAME_Rdi], rdi + .savereg rdi, KEXCEPTION_FRAME_Rdi + mov [rsp + KEXCEPTION_FRAME_Rsi], rsi + .savereg rsi, KEXCEPTION_FRAME_Rsi + mov [rsp + KEXCEPTION_FRAME_R12], r12 + .savereg r12, KEXCEPTION_FRAME_R12 + mov [rsp + KEXCEPTION_FRAME_R13], r13 + .savereg r13, KEXCEPTION_FRAME_R13 + mov [rsp + KEXCEPTION_FRAME_R14], r14 + .savereg r14, KEXCEPTION_FRAME_R14 + mov [rsp + KEXCEPTION_FRAME_R15], r15 + .savereg r15, KEXCEPTION_FRAME_R15 + movdqa [rsp + KEXCEPTION_FRAME_Xmm6], xmm6 + movdqa [rsp + KEXCEPTION_FRAME_Xmm7], xmm7 + movdqa [rsp + KEXCEPTION_FRAME_Xmm8], xmm8 + movdqa [rsp + KEXCEPTION_FRAME_Xmm9], xmm9 + movdqa [rsp + KEXCEPTION_FRAME_Xmm10], xmm10 + movdqa [rsp + KEXCEPTION_FRAME_Xmm11], xmm11 + movdqa [rsp + KEXCEPTION_FRAME_Xmm12], xmm12 + movdqa [rsp + KEXCEPTION_FRAME_Xmm13], xmm13 + movdqa [rsp + KEXCEPTION_FRAME_Xmm14], xmm14 + movdqa [rsp + KEXCEPTION_FRAME_Xmm15], xmm15 + // KEXCEPTION_FRAME_MxCsr + .endprolog /* Do the swap with the registers correctly setup */ + mov rcx, gs:[PcCurrentThread] /* Pointer to the new thread */ call KiSwapContextInternal - /* Restore the registers */ - mov rbp, [rsp+0] - mov rdi, [rsp+8] - mov rsi, [rsp+16] - mov rbx, [rsp+24] - - mov r10, [rsp+32] - mov r11, [rsp+40] - mov r12, [rsp+48] - mov r13, [rsp+56] - mov r14, [rsp+64] - mov r15, [rsp+72] - - /* Clean stack */ - add esp, 10 * 8 + /* restore non-volatile registers */ + mov rbp, [rsp + KEXCEPTION_FRAME_Rbp] + mov rbx, [rsp + KEXCEPTION_FRAME_Rbx] + mov rdi, [rsp + KEXCEPTION_FRAME_Rdi] + mov rsi, [rsp + KEXCEPTION_FRAME_Rsi] + mov r12, [rsp + KEXCEPTION_FRAME_R12] + mov r13, [rsp + KEXCEPTION_FRAME_R13] + mov r14, [rsp + KEXCEPTION_FRAME_R14] + mov r15, [rsp + KEXCEPTION_FRAME_R15] + movdqa xmm6, [rsp + KEXCEPTION_FRAME_Xmm6] + movdqa xmm7, [rsp + KEXCEPTION_FRAME_Xmm7] + movdqa xmm8, [rsp + KEXCEPTION_FRAME_Xmm8] + movdqa xmm9, [rsp + KEXCEPTION_FRAME_Xmm9] + movdqa xmm10, [rsp + KEXCEPTION_FRAME_Xmm10] + movdqa xmm11, [rsp + KEXCEPTION_FRAME_Xmm11] + movdqa xmm12, [rsp + KEXCEPTION_FRAME_Xmm12] + movdqa xmm13, [rsp + KEXCEPTION_FRAME_Xmm13] + movdqa xmm14, [rsp + KEXCEPTION_FRAME_Xmm14] + movdqa xmm15, [rsp + KEXCEPTION_FRAME_Xmm15] + + /* Clean stack and return */ + add rsp, KEXCEPTION_FRAME_LENGTH + 8 ret +.ENDP END Modified: trunk/reactos/ntoskrnl/ke/amd64/except.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/except.c…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/except.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/except.c [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -13,7 +13,7 @@ #define NDEBUG #include <debug.h> -extern ULONG64 InterruptDispatchTable[256]; +extern KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]; /* GLOBALS *******************************************************************/ @@ -74,7 +74,7 @@ } else { - Offset = (ULONG64)&InterruptDispatchTable[i]; + Offset = (ULONG64)&KiUnexpectedRange[i]._Op_push; KiIdt[i].Dpl = 0; KiIdt[i].IstIndex = 0; } @@ -92,6 +92,146 @@ __lidt(&KiIdtDescriptor.Limit); } +static +VOID +KiDispatchExceptionToUser( + IN PKTRAP_FRAME TrapFrame, + IN PCONTEXT Context, + IN PEXCEPTION_RECORD ExceptionRecord) +{ + EXCEPTION_RECORD LocalExceptRecord; + ULONG Size; + ULONG64 UserRsp; + PCONTEXT UserContext; + PEXCEPTION_RECORD UserExceptionRecord; + + /* Make sure we have a valid SS */ + if (TrapFrame->SegSs != (KGDT64_R3_DATA | RPL_MASK)) + { + /* Raise an access violation instead */ + LocalExceptRecord.ExceptionCode = STATUS_ACCESS_VIOLATION; + LocalExceptRecord.ExceptionFlags = 0; + LocalExceptRecord.NumberParameters = 0; + ExceptionRecord = &LocalExceptRecord; + } + + /* Calculate the size of the exception record */ + Size = FIELD_OFFSET(EXCEPTION_RECORD, ExceptionInformation) + + ExceptionRecord->NumberParameters * sizeof(ULONG64); + + /* Get new stack pointer and align it to 16 bytes */ + UserRsp = (Context->Rsp - Size - sizeof(CONTEXT)) & ~15; + + /* Get pointers to the usermode context and exception record */ + UserContext = (PVOID)UserRsp; + UserExceptionRecord = (PVOID)(UserRsp + sizeof(CONTEXT)); + + /* Set up the user-stack */ + _SEH2_TRY + { + /* Probe stack and copy Context */ + ProbeForWrite(UserContext, sizeof(CONTEXT), sizeof(ULONG64)); + *UserContext = *Context; + + /* Probe stack and copy exception record */ + ProbeForWrite(UserExceptionRecord, Size, sizeof(ULONG64)); + *UserExceptionRecord = *ExceptionRecord; + } + _SEH2_EXCEPT((LocalExceptRecord = *_SEH2_GetExceptionInformation()->ExceptionRecord), + EXCEPTION_EXECUTE_HANDLER) + { + // FIXNE: handle stack overflow + + /* Nothing we can do here */ + _SEH2_YIELD(return); + } + _SEH2_END; + + /* Now set the two params for the user-mode dispatcher */ + TrapFrame->Rcx = (ULONG64)UserContext; + TrapFrame->Rdx = (ULONG64)UserExceptionRecord; + + /* Set new Stack Pointer */ + TrapFrame->Rsp = UserRsp; + + /* Force correct segments */ + TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK; + TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK; + TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK; + TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK; + TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK; + TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK; + + /* Set RIP to the User-mode Dispatcher */ + TrapFrame->Rip = (ULONG64)KeUserExceptionDispatcher; + + /* Exit to usermode */ + KiServiceExit2(TrapFrame); +} + +static +VOID +KiPageInDirectory(PVOID ImageBase, USHORT Directory) +{ + volatile CHAR *Pointer; + ULONG Size; + + /* Get a pointer to the debug directory */ + Pointer = RtlImageDirectoryEntryToData(ImageBase, 1, Directory, &Size); + if (!Pointer) return; + + /* Loop all pages */ + while ((LONG)Size > 0) + { + /* Touch it, to page it in */ + (void)*Pointer; + Pointer += PAGE_SIZE; + Size -= PAGE_SIZE; + } +} + +VOID +KiPrepareUserDebugData(void) +{ + PLDR_DATA_TABLE_ENTRY LdrEntry; + PPEB_LDR_DATA PebLdr; + PLIST_ENTRY ListEntry; + PTEB Teb; + + /* Get the Teb for this process */ + Teb = KeGetCurrentThread()->Teb; + if (!Teb) return; + + _SEH2_TRY + { + /* Get a pointer to the loader data */ + PebLdr = Teb->ProcessEnvironmentBlock->Ldr; + if (!PebLdr) _SEH2_YIELD(return); + + /* Now loop all entries in the module list */ + for (ListEntry = PebLdr->InLoadOrderModuleList.Flink; + ListEntry != &PebLdr->InLoadOrderModuleList; + ListEntry = ListEntry->Flink) + { + /* Get the loader entry */ + LdrEntry = CONTAINING_RECORD(ListEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + KiPageInDirectory((PVOID)LdrEntry->DllBase, + IMAGE_DIRECTORY_ENTRY_DEBUG); + + KiPageInDirectory((PVOID)LdrEntry->DllBase, + IMAGE_DIRECTORY_ENTRY_EXCEPTION); + } + + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END +} + VOID NTAPI KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, @@ -101,9 +241,6 @@ IN BOOLEAN FirstChance) { CONTEXT Context; - -// FrLdrDbgPrint("KiDispatchException(%p, %p, %p, %d, %d)\n", -// ExceptionRecord, ExceptionFrame, TrapFrame, PreviousMode, FirstChance); /* Increase number of Exception Dispatches */ KeGetCurrentPrcb()->KeExceptionDispatchCount++; @@ -179,8 +316,66 @@ } else { - /* FIXME: user-mode exception handling unimplemented */ - ASSERT(FALSE); + /* User mode exception, was it first-chance? */ + if (FirstChance) + { + /* + * Break into the kernel debugger unless a user mode debugger + * is present or user mode exceptions are ignored, except if this + * is a debug service which we must always pass to KD + */ + if ((!(PsGetCurrentProcess()->DebugPort) && + !(KdIgnoreUmExceptions)) || + (KdIsThisAKdTrap(ExceptionRecord, &Context, PreviousMode))) + { + /* Make sure the debugger can access debug directories */ + KiPrepareUserDebugData(); + + /* Call the kernel debugger */ + if (KiDebugRoutine(TrapFrame, + ExceptionFrame, + ExceptionRecord, + &Context, + PreviousMode, + FALSE)) + { + /* Exception was handled */ + goto Handled; + } + } + + /* Forward exception to user mode debugger */ + if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return; + + //KiDispatchExceptionToUser() + __debugbreak(); + } + + /* Try second chance */ + if (DbgkForwardException(ExceptionRecord, TRUE, TRUE)) + { + /* Handled, get out */ + return; + } + else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE)) + { + /* Handled, get out */ + return; + } + + /* 3rd strike, kill the process */ + DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx, BaseAddress: %lx\n", + PsGetCurrentProcess()->ImageFileName, + ExceptionRecord->ExceptionCode, + ExceptionRecord->ExceptionAddress, + PsGetCurrentProcess()->SectionBaseAddress); + + ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode); + KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, + ExceptionRecord->ExceptionCode, + (ULONG_PTR)ExceptionRecord->ExceptionAddress, + (ULONG_PTR)TrapFrame, + 0); } Handled: Modified: trunk/reactos/ntoskrnl/ke/amd64/interrupt.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/interrup…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/interrupt.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/interrupt.c [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -6,7 +6,8 @@ * for the purpopses of connecting, disconnecting and setting * up ISRs for drivers. The backend behind the Io* Interrupt * routines. - * PROGRAMMERS: Timo Kreuzer (timo.kreuzer(a)web.de) + * PROGRAMMERS: Timo Kreuzer (timo.kreuzer(a)reactos.org) + * Alex Ionescu (alex.ionescu(a)reactos.org) */ /* INCLUDES *****************************************************************/ @@ -15,30 +16,151 @@ #define NDEBUG #include <debug.h> +extern UCHAR KiInterruptDispatchTemplate[16]; +extern UCHAR KiUnexpectedRange[]; +extern UCHAR KiUnexpectedRangeEnd[]; +void KiInterruptDispatch(void); + + /* FUNCTIONS ****************************************************************/ + +VOID +NTAPI +KeInitializeInterrupt( + IN PKINTERRUPT Interrupt, + IN PKSERVICE_ROUTINE ServiceRoutine, + IN PVOID ServiceContext, + IN PKSPIN_LOCK SpinLock, + IN ULONG Vector, + IN KIRQL Irql, + IN KIRQL SynchronizeIrql, + IN KINTERRUPT_MODE InterruptMode, + IN BOOLEAN ShareVector, + IN CHAR ProcessorNumber, + IN BOOLEAN FloatingSave) +{ + + /* Initialize the header */ + Interrupt->Type = InterruptObject; + Interrupt->Size = sizeof(KINTERRUPT); + + /* If no Spinlock is given, use the internal */ + if (!SpinLock) SpinLock = &Interrupt->SpinLock; + KeInitializeSpinLock(&Interrupt->SpinLock); + + /* Set the given parameters */ + Interrupt->ServiceRoutine = ServiceRoutine; + Interrupt->ServiceContext = ServiceContext; + Interrupt->ActualLock = SpinLock; + Interrupt->Vector = Vector; + Interrupt->Irql = Irql; + Interrupt->SynchronizeIrql = SynchronizeIrql; + Interrupt->Mode = InterruptMode; + Interrupt->ShareVector = ShareVector; + Interrupt->Number = ProcessorNumber; + Interrupt->FloatingSave = FloatingSave; + + /* Set initial values */ + Interrupt->TickCount = 0; + Interrupt->Connected = FALSE; + Interrupt->ServiceCount = 0; + Interrupt->DispatchCount = 0; + Interrupt->TrapFrame = NULL; + Interrupt->Reserved = 0; + + /* Copy the dispatch code (its location independent, no need to patch it) */ + RtlCopyMemory(Interrupt->DispatchCode, + KiInterruptDispatchTemplate, + sizeof(Interrupt->DispatchCode)); + + Interrupt->DispatchAddress = 0; +} + +BOOLEAN +NTAPI +KeConnectInterrupt(IN PKINTERRUPT Interrupt) +{ + PVOID CurrentHandler; + + ASSERT(Interrupt->Vector <= MAXIMUM_IDTVECTOR); + ASSERT(Interrupt->Number < KeNumberProcessors); + ASSERT(Interrupt->Irql <= HIGH_LEVEL); + + /* Check if its already connected */ + if (Interrupt->Connected) return TRUE; + + /* Query the current handler */ + CurrentHandler = KeQueryInterruptHandler(Interrupt->Vector); + + /* Check if the vector is already unused */ + if ((CurrentHandler >= (PVOID)KiUnexpectedRange) && + (CurrentHandler <= (PVOID)KiUnexpectedRangeEnd)) + { + /* Initialize the list for chained interrupts */ + InitializeListHead(&Interrupt->InterruptListEntry); + + /* Set normal dispatch address */ + Interrupt->DispatchAddress = KiInterruptDispatch; + + /* Set the new handler */ + KeRegisterInterruptHandler(Interrupt->Vector, + Interrupt->DispatchCode); + + if (!HalEnableSystemInterrupt(Interrupt->Vector, + Interrupt->Irql, + Interrupt->Mode)) + { + /* Didn't work, restore old handler */ + DPRINT1("HalEnableSystemInterrupt failed\n"); + KeRegisterInterruptHandler(Interrupt->Vector, CurrentHandler); + return FALSE; + } + + /* Mark as connected */ + Interrupt->Connected = TRUE; + } + else + { + // later + __debugbreak(); + } + + return TRUE; +} BOOLEAN NTAPI KeDisconnectInterrupt(IN PKINTERRUPT Interrupt) { UNIMPLEMENTED; + __debugbreak(); return FALSE; } -VOID +BOOLEAN NTAPI -KeInitializeInterrupt(IN PKINTERRUPT Interrupt, - IN PKSERVICE_ROUTINE ServiceRoutine, - IN PVOID ServiceContext, - IN PKSPIN_LOCK SpinLock, - IN ULONG Vector, - IN KIRQL Irql, - IN KIRQL SynchronizeIrql, - IN KINTERRUPT_MODE InterruptMode, - IN BOOLEAN ShareVector, - IN CHAR ProcessorNumber, - IN BOOLEAN FloatingSave) +KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, + IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, + IN PVOID SynchronizeContext OPTIONAL) { - UNIMPLEMENTED; + BOOLEAN Success; + KIRQL OldIrql; + + /* Raise IRQL */ + OldIrql = KfRaiseIrql(Interrupt->SynchronizeIrql); + + /* Acquire interrupt spinlock */ + KeAcquireSpinLockAtDpcLevel(Interrupt->ActualLock); + + /* Call the routine */ + Success = SynchronizeRoutine(SynchronizeContext); + + /* Release lock */ + KeReleaseSpinLockFromDpcLevel(Interrupt->ActualLock); + + /* Lower IRQL */ + KeLowerIrql(OldIrql); + + /* Return status */ + return Success; } - Modified: trunk/reactos/ntoskrnl/ke/amd64/kiinit.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/kiinit.c…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/kiinit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/kiinit.c [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -32,6 +32,10 @@ UCHAR DECLSPEC_ALIGN(16) KiDoubleFaultStackData[KERNEL_STACK_SIZE] = {0}; ULONG_PTR P0BootStack = (ULONG_PTR)&P0BootStackData[KERNEL_STACK_SIZE]; ULONG_PTR KiDoubleFaultStack = (ULONG_PTR)&KiDoubleFaultStackData[KERNEL_STACK_SIZE]; + +void KiInitializeSegments(); +void KiSystemCallEntry64(); +void KiSystemCallEntry32(); /* FUNCTIONS *****************************************************************/ @@ -91,7 +95,7 @@ USHORT Tr = 0; /* Zero out the PCR */ - RtlZeroMemory(Pcr, PAGE_SIZE); + RtlZeroMemory(Pcr, sizeof(KIPCR)); /* Set pointers to ourselves */ Pcr->Self = (PKPCR)Pcr; @@ -152,17 +156,20 @@ /* Start us out at PASSIVE_LEVEL */ Pcr->Irql = PASSIVE_LEVEL; KeSetCurrentIrql(PASSIVE_LEVEL); +} + +VOID +NTAPI +KiInitializeCpu(PKIPCR Pcr) +{ + ULONG FeatureBits; + + /* Initialize gs */ + KiInitializeSegments(); /* Set GS base */ - __writemsr(X86_MSR_GSBASE, (ULONG64)Pcr); - __writemsr(X86_MSR_KERNEL_GSBASE, (ULONG64)Pcr); -} - -VOID -NTAPI -KiInitializeCpu(PKPRCB Prcb) -{ - ULONG FeatureBits; + __writemsr(MSR_GS_BASE, (ULONG64)Pcr); + __writemsr(MSR_GS_SWAP, (ULONG64)Pcr); /* Detect and set the CPU Type */ KiSetProcessorType(); @@ -184,7 +191,7 @@ FeatureBits |= KF_NX_ENABLED; /* Save feature bits */ - Prcb->FeatureBits = FeatureBits; + Pcr->Prcb.FeatureBits = FeatureBits; /* Enable fx save restore support */ __writecr4(__readcr4() | CR4_FXSR); @@ -203,6 +210,19 @@ /* LDT is unused */ __lldt(0); + + /* Set the systemcall entry points */ + __writemsr(MSR_LSTAR, (ULONG64)KiSystemCallEntry64); + __writemsr(MSR_CSTAR, (ULONG64)KiSystemCallEntry32); + + __writemsr(MSR_STAR, ((ULONG64)KGDT64_R0_CODE << 32) | + ((ULONG64)(KGDT64_R3_CMCODE|RPL_MASK) << 48)); + + /* Set the flags to be cleared when doing a syscall */ + __writemsr(MSR_SYSCALL_MASK, EFLAGS_IF_MASK | EFLAGS_TF | EFLAGS_DF); + + /* Enable syscall instruction */ + __writemsr(MSR_EFER, __readmsr(MSR_EFER) | MSR_SCE); } VOID @@ -339,7 +359,7 @@ /* HACK */ FrLdrDbgPrint = LoaderBlock->u.I386.CommonDataArea; - FrLdrDbgPrint("Hello from KiSystemStartup!!!\n"); + //FrLdrDbgPrint("Hello from KiSystemStartup!!!\n"); /* Save the loader block */ KeLoaderBlock = LoaderBlock; @@ -350,7 +370,6 @@ /* LoaderBlock initialization for Cpu 0 */ if (Cpu == 0) { - FrLdrDbgPrint("LoaderBlock->Prcb=%p\n", LoaderBlock->Prcb); /* Set the initial stack, idle thread and process */ LoaderBlock->KernelStack = (ULONG_PTR)P0BootStack; LoaderBlock->Thread = (ULONG_PTR)&KiInitialThread; @@ -378,7 +397,7 @@ KiInitializePcr(Pcr, Cpu, InitialThread, (PVOID)KiDoubleFaultStack); /* Initialize the CPU features */ - KiInitializeCpu(&Pcr->Prcb); + KiInitializeCpu(Pcr); /* Initial setup for the boot CPU */ if (Cpu == 0) Modified: trunk/reactos/ntoskrnl/ke/amd64/stubs.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/stubs.c?…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/stubs.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/stubs.c [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -13,12 +13,69 @@ #include <debug.h> VOID -NTAPI -KiDispatchInterrupt(VOID) -{ - UNIMPLEMENTED; - __debugbreak(); -} +KiRetireDpcListInDpcStack( + PKPRCB Prcb, + PVOID DpcStack); + +VOID +NTAPI +KiDpcInterruptHandler(VOID) +{ + PKPRCB Prcb = KeGetCurrentPrcb(); + PKTHREAD NewThread, OldThread; + KIRQL OldIrql; + + /* Raise to DISPATCH_LEVEL */ + OldIrql = KfRaiseIrql(DISPATCH_LEVEL); + + /* Send an EOI */ + KiSendEOI(); + + /* Check for pending timers, pending DPCs, or pending ready threads */ + if ((Prcb->DpcData[0].DpcQueueDepth) || + (Prcb->TimerRequest) || + (Prcb->DeferredReadyListHead.Next)) + { + /* Retire DPCs while under the DPC stack */ + KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack); + } + + /* Enable interrupts */ + _enable(); + + /* Check for quantum end */ + if (Prcb->QuantumEnd) + { + /* Handle quantum end */ + Prcb->QuantumEnd = FALSE; + KiQuantumEnd(); + } + else if (Prcb->NextThread) + { + /* Capture current thread data */ + OldThread = Prcb->CurrentThread; + NewThread = Prcb->NextThread; + + /* Set new thread data */ + Prcb->NextThread = NULL; + Prcb->CurrentThread = NewThread; + + /* The thread is now running */ + NewThread->State = Running; + OldThread->WaitReason = WrDispatchInt; + + /* Make the old thread ready */ + KxQueueReadyThread(OldThread, Prcb); + + /* Swap to the new thread */ + KiSwapContext(APC_LEVEL, OldThread); + } + + /* Go back to old irql and disable interrupts */ + KeLowerIrql(OldIrql); + _disable(); +} + VOID FASTCALL @@ -29,52 +86,13 @@ RtlZeroMemory(Address, Size); } -VOID -FASTCALL -DECLSPEC_NORETURN -KiServiceExit(IN PKTRAP_FRAME TrapFrame, - IN NTSTATUS Status) -{ - UNIMPLEMENTED; - __debugbreak(); -} - -VOID -FASTCALL -DECLSPEC_NORETURN -KiServiceExit2(IN PKTRAP_FRAME TrapFrame) -{ - UNIMPLEMENTED; - __debugbreak(); -} - -BOOLEAN -NTAPI -KeConnectInterrupt(IN PKINTERRUPT Interrupt) -{ - UNIMPLEMENTED; - __debugbreak(); - return FALSE; -} - PVOID NTAPI KeSwitchKernelStack(PVOID StackBase, PVOID StackLimit) { UNIMPLEMENTED; + __debugbreak(); return NULL; -} - -BOOLEAN -NTAPI -KeSynchronizeExecution( - IN OUT PKINTERRUPT Interrupt, - IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, - IN PVOID SynchronizeContext) -{ - UNIMPLEMENTED; - __debugbreak(); - return FALSE; } NTSTATUS @@ -91,12 +109,101 @@ } VOID -KiIdleLoop() -{ - UNIMPLEMENTED; - for(;;); -} - +FASTCALL +KiIdleLoop(VOID) +{ + PKPRCB Prcb = KeGetCurrentPrcb(); + PKTHREAD OldThread, NewThread; + + /* Initialize the idle loop: disable interrupts */ + _enable(); + YieldProcessor(); + YieldProcessor(); + _disable(); + + /* Now loop forever */ + while (TRUE) + { + /* Check for pending timers, pending DPCs, or pending ready threads */ + if ((Prcb->DpcData[0].DpcQueueDepth) || + (Prcb->TimerRequest) || + (Prcb->DeferredReadyListHead.Next)) + { + /* Quiesce the DPC software interrupt */ + HalClearSoftwareInterrupt(DISPATCH_LEVEL); + + /* Handle it */ + KiRetireDpcList(Prcb); + } + + /* Check if a new thread is scheduled for execution */ + if (Prcb->NextThread) + { + /* Enable interupts */ + _enable(); + + /* Capture current thread data */ + OldThread = Prcb->CurrentThread; + NewThread = Prcb->NextThread; + + /* Set new thread data */ + Prcb->NextThread = NULL; + Prcb->CurrentThread = NewThread; + + /* The thread is now running */ + NewThread->State = Running; + + /* Do the swap at SYNCH_LEVEL */ + KfRaiseIrql(SYNCH_LEVEL); + + /* Switch away from the idle thread */ + KiSwapContext(APC_LEVEL, OldThread); + + /* Go back to DISPATCH_LEVEL */ + KeLowerIrql(DISPATCH_LEVEL); + + /* We are back in the idle thread -- disable interrupts again */ + _enable(); + YieldProcessor(); + YieldProcessor(); + _disable(); + } + else + { + /* Continue staying idle. Note the HAL returns with interrupts on */ + Prcb->PowerState.IdleFunction(&Prcb->PowerState); + } + } +} + + +/*! \name KiInitializeUserApc + * + * \brief + * Prepares the current trap frame (which must have come from user mode) + * with the ntdll.KiUserApcDispatcher entrypoint, copying a CONTEXT + * record with the context from the old trap frame to the threads user + * mode stack. + * + * \param ExceptionFrame + * \param TrapFrame + * \param NormalRoutine + * \param NormalContext + * \param SystemArgument1 + * \param SystemArgument2 + * + * \remarks + * This function is called from KiDeliverApc, when the trap frame came + * from user mode. This happens before a systemcall or interrupt exits back + * to usermode or when a thread is started from PspUserThreadstartup. + * The trap exit code will then leave to KiUserApcDispatcher which in turn + * calls the NormalRoutine, passing NormalContext, SystemArgument1 and + * SystemArgument2 as parameters. When that function returns, it calls + * NtContinue to return back to the kernel, where the old context that was + * saved on the usermode stack is restored and execution is transferred + * back to usermode, where the original trap originated from. + * + *--*/ VOID NTAPI KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, @@ -106,8 +213,69 @@ IN PVOID SystemArgument1, IN PVOID SystemArgument2) { - UNIMPLEMENTED; - __debugbreak(); + CONTEXT Context; + ULONG64 AlignedRsp, Stack; + EXCEPTION_RECORD SehExceptRecord; + + /* Sanity check, that the trap frame is from user mode */ + ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode); + + /* Convert the current trap frame to a context */ + Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; + KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context); + + /* We jump to KiUserApcDispatcher in ntdll */ + TrapFrame->Rip = (ULONG64)KeUserApcDispatcher; + + /* Setup Ring 3 segments */ + TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK; + TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK; + TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK; + TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK; + TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK; + TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK; + + /* Sanitize EFLAGS, enable interrupts */ + TrapFrame->EFlags = (Context.EFlags & EFLAGS_USER_SANITIZE); + TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK; + + /* Set parameters for KiUserApcDispatcher */ + Context.P1Home = (ULONG64)NormalContext; + Context.P2Home = (ULONG64)SystemArgument1; + Context.P3Home = (ULONG64)SystemArgument2; + Context.P4Home = (ULONG64)NormalRoutine; + + /* Check if thread has IOPL and force it enabled if so */ + //if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL; + + /* Align Stack to 16 bytes and allocate space */ + AlignedRsp = Context.Rsp & ~15; + Stack = AlignedRsp - sizeof(CONTEXT); + TrapFrame->Rsp = Stack; + + /* The stack must be 16 byte aligned for KiUserApcDispatcher */ + ASSERT((Stack & 15) == 0); + + /* Protect with SEH */ + _SEH2_TRY + { + /* Probe the stack */ + ProbeForWrite((PCONTEXT)Stack, sizeof(CONTEXT), 8); + + /* Copy the context */ + RtlCopyMemory((PCONTEXT)Stack, &Context, sizeof(CONTEXT)); + } + _SEH2_EXCEPT((RtlCopyMemory(&SehExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER)) + { + /* Dispatch the exception */ + SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Rip; + KiDispatchException(&SehExceptRecord, + ExceptionFrame, + TrapFrame, + UserMode, + TRUE); + } + _SEH2_END; } VOID @@ -115,10 +283,126 @@ KiSwapProcess(IN PKPROCESS NewProcess, IN PKPROCESS OldProcess) { - UNIMPLEMENTED; - __debugbreak(); -} - + PKIPCR Pcr = (PKIPCR)KeGetPcr(); +#ifdef CONFIG_SMP + LONG SetMember; + + /* Update active processor mask */ + SetMember = (LONG)Pcr->SetMember; + InterlockedXor((PLONG)&NewProcess->ActiveProcessors, SetMember); + InterlockedXor((PLONG)&OldProcess->ActiveProcessors, SetMember); +#endif + + /* Update CR3 */ + __writecr3(NewProcess->DirectoryTableBase[0]); + + /* Update IOPM offset */ + Pcr->TssBase->IoMapBase = NewProcess->IopmOffset; +} + +#define MAX_SYSCALL_PARAMS 16 + +NTSTATUS +NtSyscallFailure(void) +{ + /* This is the failure function */ + return STATUS_ACCESS_VIOLATION; +} + +PVOID +KiSystemCallHandler( + IN PKTRAP_FRAME TrapFrame, + IN ULONG64 P2, + IN ULONG64 P3, + IN ULONG64 P4) +{ + PKSERVICE_TABLE_DESCRIPTOR DescriptorTable; + PKTHREAD Thread; + PULONG64 KernelParams, UserParams; + ULONG ServiceNumber, Offset, Count; + ULONG64 UserRsp; + + DPRINT("Syscall #%ld\n", TrapFrame->Rax); + //__debugbreak(); + + /* Increase system call count */ + __addgsdword(FIELD_OFFSET(KIPCR, Prcb.KeSystemCalls), 1); + + /* Get the current thread */ + Thread = KeGetCurrentThread(); + + /* Set previous mode */ + Thread->PreviousMode = TrapFrame->PreviousMode = UserMode; + + /* Save the old trap frame and set the new */ + TrapFrame->TrapFrame = (ULONG64)Thread->TrapFrame; + Thread->TrapFrame = TrapFrame; + + /* Before enabling interrupts get the user rsp from the KPCR */ + UserRsp = __readgsqword(FIELD_OFFSET(KIPCR, UserRsp)); + TrapFrame->Rsp = UserRsp; + + /* Enable interrupts */ + _enable(); + + /* If the usermode rsp was not a usermode address, prepare an exception */ + if (UserRsp > MmUserProbeAddress) UserRsp = MmUserProbeAddress; + + /* Get the address of the usermode and kernelmode parameters */ + UserParams = (PULONG64)UserRsp + 1; + KernelParams = (PULONG64)TrapFrame - MAX_SYSCALL_PARAMS; + + /* Get the system call number from the trap frame and decode it */ + ServiceNumber = (ULONG)TrapFrame->Rax; + Offset = (ServiceNumber >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK; + ServiceNumber &= SERVICE_NUMBER_MASK; + + /* Get descriptor table */ + DescriptorTable = (PVOID)((ULONG_PTR)Thread->ServiceTable + Offset); + + /* Get stack bytes and calculate argument count */ + Count = DescriptorTable->Number[ServiceNumber] / 8; + + __try + { + switch (Count) + { + case 16: KernelParams[15] = UserParams[15]; + case 15: KernelParams[14] = UserParams[14]; + case 14: KernelParams[13] = UserParams[13]; + case 13: KernelParams[12] = UserParams[12]; + case 12: KernelParams[11] = UserParams[11]; + case 11: KernelParams[10] = UserParams[10]; + case 10: KernelParams[9] = UserParams[9]; + case 9: KernelParams[8] = UserParams[8]; + case 8: KernelParams[7] = UserParams[7]; + case 7: KernelParams[6] = UserParams[6]; + case 6: KernelParams[5] = UserParams[5]; + case 5: KernelParams[4] = UserParams[4]; + case 4: KernelParams[3] = P4; + case 3: KernelParams[2] = P3; + case 2: KernelParams[1] = P2; + case 1: KernelParams[0] = TrapFrame->R10; + case 0: + break; + + default: + __debugbreak(); + break; + } + } + __except(1) + { + TrapFrame->Rax = _SEH2_GetExceptionCode(); + return (PVOID)NtSyscallFailure; + } + + + return (PVOID)DescriptorTable->Base[ServiceNumber]; +} + + +// FIXME: we need to VOID KiSystemService(IN PKTHREAD Thread, IN PKTRAP_FRAME TrapFrame, @@ -145,6 +429,7 @@ (ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2) { UNIMPLEMENTED; + __debugbreak(); return STATUS_UNSUCCESSFUL; } @@ -153,9 +438,8 @@ NtVdmControl(IN ULONG ControlCode, IN PVOID ControlData) { - UNIMPLEMENTED; - __debugbreak(); - return STATUS_UNSUCCESSFUL; + /* Not supported */ + return STATUS_NOT_IMPLEMENTED; } NTSTATUS Modified: trunk/reactos/ntoskrnl/ke/amd64/thrdini.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/thrdini.…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/thrdini.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/thrdini.c [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -2,8 +2,9 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/i386/thread.c - * PURPOSE: i386 Thread Context Creation - * PROGRAMMER: Alex Ionescu (alex(a)relsoft.net) + * PURPOSE: amd64 Thread Context Creation + * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org) + * Alex Ionescu (alex(a)relsoft.net) */ /* INCLUDES ******************************************************************/ @@ -16,6 +17,7 @@ { KSWITCH_FRAME CtxSwitchFrame; KSTART_FRAME StartFrame; + KEXCEPTION_FRAME ExceptionFrame; KTRAP_FRAME TrapFrame; //FX_SAVE_AREA FxSaveArea; } KUINIT_FRAME, *PKUINIT_FRAME; @@ -35,74 +37,52 @@ IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, - IN PCONTEXT ContextPointer) + IN PCONTEXT Context) { //PFX_SAVE_AREA FxSaveArea; //PFXSAVE_FORMAT FxSaveFormat; PKSTART_FRAME StartFrame; PKSWITCH_FRAME CtxSwitchFrame; PKTRAP_FRAME TrapFrame; - CONTEXT LocalContext; - PCONTEXT Context = NULL; ULONG ContextFlags; /* Check if this is a With-Context Thread */ - if (ContextPointer) - { + if (Context) + { + PKUINIT_FRAME InitFrame; + /* Set up the Initial Frame */ - PKUINIT_FRAME InitFrame; - InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack - - sizeof(KUINIT_FRAME)); - - /* Copy over the context we got */ - RtlCopyMemory(&LocalContext, ContextPointer, sizeof(CONTEXT)); - Context = &LocalContext; - ContextFlags = CONTEXT_CONTROL; - - /* Zero out the trap frame and save area */ - RtlZeroMemory(&InitFrame->TrapFrame, - KTRAP_FRAME_LENGTH); - - /* Setup the Fx Area */ - //FxSaveArea = &InitFrame->FxSaveArea; - -// /* Get the FX Save Format Area */ -// FxSaveFormat = (PFXSAVE_FORMAT)Context->ExtendedRegisters; -// -// /* Set an initial state */ -// FxSaveFormat->ControlWord = 0x27F; -// FxSaveFormat->StatusWord = 0; -// FxSaveFormat->TagWord = 0; -// FxSaveFormat->ErrorOffset = 0; -// FxSaveFormat->ErrorSelector = 0; -// FxSaveFormat->DataOffset = 0; -// FxSaveFormat->DataSelector = 0; -// FxSaveFormat->MXCsr = 0x1F80; - - /* Set an intial NPX State */ - //Context->FloatSave.Cr0NpxState = 0; - //FxSaveArea->Cr0NpxState = 0; - //FxSaveArea->NpxSavedCpu = 0; - - /* Now set the context flags depending on XMM support */ - //ContextFlags |= (KeI386FxsrPresent) ? CONTEXT_EXTENDED_REGISTERS : - // CONTEXT_FLOATING_POINT; + InitFrame = ((PKUINIT_FRAME)Thread->InitialStack) - 1; + StartFrame = &InitFrame->StartFrame; + CtxSwitchFrame = &InitFrame->CtxSwitchFrame; + + /* Save back the new value of the kernel stack. */ + Thread->KernelStack = (PVOID)InitFrame; + + /* Tell the thread it will run in User Mode */ + Thread->PreviousMode = UserMode; + + // FIXME Setup the Fx Area /* Set the Thread's NPX State */ Thread->NpxState = 0xA; Thread->Header.NpxIrql = PASSIVE_LEVEL; - /* Disable any debug regiseters */ - Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS; + /* Make sure, we have control registers, disable debug registers */ + ASSERT((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL); + ContextFlags = Context->ContextFlags & ~CONTEXT_DEBUG_REGISTERS; /* Setup the Trap Frame */ TrapFrame = &InitFrame->TrapFrame; + + /* Zero out the trap frame */ + RtlZeroMemory(TrapFrame, sizeof(KTRAP_FRAME)); /* Set up a trap frame from the context. */ KeContextToTrapFrame(Context, NULL, TrapFrame, - Context->ContextFlags | ContextFlags, + CONTEXT_AMD64 | ContextFlags, UserMode); /* Set SS, DS, ES's RPL Mask properly */ @@ -117,62 +97,111 @@ /* Terminate the Exception Handler List */ TrapFrame->ExceptionFrame = 0; - /* Setup the Stack for KiThreadStartup and Context Switching */ + /* We return to ... */ + StartFrame->Return = (ULONG64)KiServiceExit2; + } + else + { + PKKINIT_FRAME InitFrame; + + /* Set up the Initial Frame for the system thread */ + InitFrame = ((PKKINIT_FRAME)Thread->InitialStack) - 1; StartFrame = &InitFrame->StartFrame; CtxSwitchFrame = &InitFrame->CtxSwitchFrame; - /* Tell the thread it will run in User Mode */ - Thread->PreviousMode = UserMode; - - /* Tell KiThreadStartup of that too */ -// StartFrame->UserThread = TRUE; - } - else - { - /* Set up the Initial Frame for the system thread */ - PKKINIT_FRAME InitFrame; - InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack - - sizeof(KKINIT_FRAME)); - - /* Setup the Fx Area */ - //FxSaveArea = &InitFrame->FxSaveArea; - //RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA)); - - /* Check if we have Fxsr support */ - DPRINT1("FxsrPresent but did nothing\n"); -// /* Set the stub FX area */ -// FxSaveArea->U.FxArea.ControlWord = 0x27F; -// FxSaveArea->U.FxArea.MXCsr = 0x1F80; + /* Save back the new value of the kernel stack. */ + Thread->KernelStack = (PVOID)InitFrame; + + /* Tell the thread it will run in Kernel Mode */ + Thread->PreviousMode = KernelMode; + + // FIXME Setup the Fx Area /* No NPX State */ Thread->NpxState = 0xA; - /* Setup the Stack for KiThreadStartup and Context Switching */ - StartFrame = &InitFrame->StartFrame; - CtxSwitchFrame = &InitFrame->CtxSwitchFrame; - - /* Tell the thread it will run in Kernel Mode */ - Thread->PreviousMode = KernelMode; - - /* Tell KiThreadStartup of that too */ -// StartFrame->UserThread = FALSE; - } - - /* Now setup the remaining data for KiThreadStartup */ -// StartFrame->StartContext = StartContext; -// StartFrame->StartRoutine = StartRoutine; -// StartFrame->SystemRoutine = SystemRoutine; - - /* And set up the Context Switch Frame */ -// CtxSwitchFrame->RetAddr = KiThreadStartup; -// CtxSwitchFrame->ApcBypassDisable = TRUE; -// CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;; - - /* Save back the new value of the kernel stack. */ - Thread->KernelStack = (PVOID)CtxSwitchFrame; + /* We have no return address! */ + StartFrame->Return = 0; + } + + /* Set up the Context Switch Frame */ + CtxSwitchFrame->Return = (ULONG64)KiThreadStartup; + CtxSwitchFrame->ApcBypass = FALSE; + + StartFrame->P1Home = (ULONG64)StartRoutine; + StartFrame->P2Home = (ULONG64)StartContext; + StartFrame->P3Home = 0; + StartFrame->P4Home = (ULONG64)SystemRoutine; + StartFrame->P5Home = 0; } +BOOLEAN +KiSwapContextResume( + IN PKTHREAD NewThread, + IN PKTHREAD OldThread, + IN BOOLEAN ApcBypass) +{ + PKIPCR Pcr = (PKIPCR)KeGetPcr(); + PKPROCESS OldProcess, NewProcess; + + /* Setup ring 0 stack pointer */ + Pcr->TssBase->Rsp0 = (ULONG64)NewThread->InitialStack; // FIXME: NPX save area? + Pcr->Prcb.RspBase = Pcr->TssBase->Rsp0; + + /* Now we are the new thread. Check if it's in a new process */ + OldProcess = OldThread->ApcState.Process; + NewProcess = NewThread->ApcState.Process; + if (OldProcess != NewProcess) + { + /* Switch address space and flush TLB */ + __writecr3(NewProcess->DirectoryTableBase[0]); + + /* Set new TSS fields */ + //Pcr->TssBase->IoMapBase = NewProcess->IopmOffset; + } + + /* Set TEB pointer and GS base */ + Pcr->NtTib.Self = (PVOID)NewThread->Teb; + if (NewThread->Teb) + { + /* This will switch the usermode gs */ + __writemsr(MSR_GS_SWAP, (ULONG64)NewThread->Teb); + } + + /* Increase context switch count */ + Pcr->ContextSwitches++; + NewThread->ContextSwitches++; + + /* DPCs shouldn't be active */ + if (Pcr->Prcb.DpcRoutineActive) + { + /* Crash the machine */ + KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC, + (ULONG_PTR)OldThread, + (ULONG_PTR)NewThread, + (ULONG_PTR)OldThread->InitialStack, + 0); + } + + /* Kernel APCs may be pending */ + if (NewThread->ApcState.KernelApcPending) + { + /* Are APCs enabled? */ + if (!NewThread->SpecialApcDisable) + { + /* Request APC delivery */ + if (!ApcBypass) + HalRequestSoftwareInterrupt(APC_LEVEL); + else + return TRUE; + } + } + + /* Return stating that no kernel APCs are pending*/ + return FALSE; +} + /* EOF */ Modified: trunk/reactos/ntoskrnl/ke/amd64/trap.S URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/amd64/trap.S?r…
============================================================================== --- trunk/reactos/ntoskrnl/ke/amd64/trap.S [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/amd64/trap.S [iso-8859-1] Sat Feb 4 11:32:13 2012 @@ -20,7 +20,7 @@ EXTERN KiGeneralProtectionFaultHandler:PROC EXTERN KiXmmExceptionHandler:PROC EXTERN KiDeliverApc:PROC -EXTERN KiDispatchInterrupt:PROC +EXTERN KiDpcInterruptHandler:PROC /* GLOBALS *******************************************************************/ @@ -56,15 +56,35 @@ ALIGN 8 -PUBLIC InterruptDispatchTable -InterruptDispatchTable: +MACRO(UnexpectedVectorStub, Vector) + /* This nop is to make the relative jmp address 4 bytes aligned and to + make the whole code 8 bytes long */ + nop + /* This is a push instruction with 8bit operand. Since the instruction + sign extends the value to 32 bits, we need to offset it */ +PUBLIC KxUnexpectedInterrupt&Vector +KxUnexpectedInterrupt&Vector: + push (Vector - 128) + jmp KiUnexpectedInterrupt +ENDM + +PUBLIC KiUnexpectedRange +KiUnexpectedRange: Vector = 0 REPEAT 256 - push Vector - jmp KiUnexpectedInterrupt - ALIGN 8 + UnexpectedVectorStub %Vector Vector = Vector+1 ENDR +PUBLIC KiUnexpectedRangeEnd +KiUnexpectedRangeEnd: + +PUBLIC KiInterruptDispatchTemplate +KiInterruptDispatchTemplate: + /* This instruction pushes the return address on the stack, which is the + address of the interrupt object's DispatchCode member, then jumps + to the address stored in the interrupt object's DispatchAddress member */ + call qword ptr KiInterruptDispatchTemplate[rip - KINTERRUPT_DispatchCode + KINTERRUPT_DispatchAddress] + // rbp = TrapFrame, eax = ExceptionCode, edx = NumParams, r9,r10,r11 = params .PROC InternalDispatchException @@ -138,7 +158,7 @@ .ENDP -/* SOFTWARE INTERRUPT SERVICES ***********************************************/ +/* CPU EXCEPTION HANDLERS ****************************************************/ PUBLIC KiDivideErrorFault FUNC KiDivideErrorFault @@ -195,6 +215,14 @@ /* Push pseudo error code */ EnterTrap TF_SAVE_ALL + /* Check if the frame was from kernelmode */ + test word ptr [rbp + KTRAP_FRAME_SegCs], 3 + jz KiBreakpointTrapKMode + + /* Enable interrupts for user-mode */ + sti + +KiBreakpointTrapKMode: /* Dispatch the exception */ DispatchException STATUS_BREAKPOINT, 3, 0, 0, 0 @@ -434,7 +462,7 @@ PageFaultReturn: /* Return */ - ExitTrap TF_SAVE_ALL + ExitTrap (TF_SAVE_ALL or TF_CHECKUSERAPC) ENDFUNC @@ -494,6 +522,8 @@ ExitTrap TF_SAVE_ALL ENDFUNC + +/* SOFTWARE INTERRUPT SERVICES ***********************************************/ PUBLIC KiRaiseAssertion FUNC KiRaiseAssertion @@ -552,29 +582,43 @@ /* Disable interrupts */ cli + /* Lower IRQL back to PASSIVE */ + mov rax, PASSIVE_LEVEL + mov cr8, rax + /* Return */ ExitTrap (TF_VOLATILES or TF_IRQL) .ENDP +EXTERN KiRetireDpcList:PROC +PUBLIC KiRetireDpcListInDpcStack +.PROC KiRetireDpcListInDpcStack + push rbp + .pushreg rbp + mov rbp, rsp + .setframe rbp, 0 + .endprolog + + /* Switch stack and call the function */ + mov rsp, rdx + sub rsp, 40 + call KiRetireDpcList + + /* Restore stack, cleanup and return */ + mov rsp, rbp + pop rbp + ret +.ENDP PUBLIC KiDpcInterrupt .PROC KiDpcInterrupt /* No error code */ EnterTrap (TF_VOLATILES or TF_IRQL) - /* Raise to DISPATCH_LEVEL */ - mov rax, DISPATCH_LEVEL - mov cr8, rax - - /* End the interrupt */ - mov dword ptr [APIC_EOI], 0 - /* Call the worker routine */ - sti - call KiDispatchInterrupt - cli - - /* Return */ + call KiDpcInterruptHandler + + /* Return, but don't send an EOI! */ ExitTrap (TF_VOLATILES or TF_IRQL) .ENDP @@ -618,6 +662,253 @@ ExitTrap TF_SAVE_ALL ENDFUNC +PUBLIC KiInterruptDispatch +FUNC KiInterruptDispatch + /* The error code is a pointer to the interrupt object's code */ + EnterTrap (TF_HAS_ERROR_CODE or TF_SAVE_ALL or TF_IRQL) + + /* Increase interrupt count */ + inc dword ptr gs:[PcInterruptCount]; + + /* Load the address of the interrupt object into rcx */ + mov rcx, [rbp + KTRAP_FRAME_ErrorCode] + + /* Substract offset of the DispatchCode member plus 6 for the call instruction */ + sub rcx, KINTERRUPT_DispatchCode + 6 + + /* Raise IRQL to SynchronizeIrql */ + movzx rax, byte ptr [rcx + KINTERRUPT_SynchronizeIrql] + mov cr8, rax + +#ifdef CONFIG_SMP + /* Acquire interrupt lock */ + mov r8, [rcx + KINTERRUPT_ActualLock] + + //KxAcquireSpinLock(Interrupt->ActualLock); +#endif + + /* Call the ISR */ + mov rdx, [rcx + KINTERRUPT_ServiceContext] + call qword ptr [rcx + KINTERRUPT_ServiceRoutine] + +#ifdef CONFIG_SMP + /* Release interrupt lock */ + //KxReleaseSpinLock(Interrupt->ActualLock); +#endif + + /* Go back to old irql */ + movzx rax, byte ptr [rbp + KTRAP_FRAME_PreviousIrql] + mov cr8, rax + + /* Return */ + ExitTrap (TF_SAVE_ALL or TF_SEND_EOI) +ENDFUNC + + +#define MAX_SYSCALL_PARAM_SIZE (16 * 8) +#define HOME_SIZE 6*8 +#define SYSCALL_ALLOCATION (MAX_SYSCALL_PARAM_SIZE + HOME_SIZE) + +EXTERN KiSystemCallHandler:PROC + +/*! \name KiSystemCallEntry64 + * + * \brief This is the entrypoint for syscalls from 64bit user mode + * + * \param rax - The system call number + * \param rcx - User mode return address, set by the syscall instruction + * \param rdx,r8,r9 - Parameters 2-4 to the service function + * \param r10 - Parameter 1 to the service function + * \param r11 - RFLAGS saved by the syscall instruction + *--*/ +PUBLIC KiSystemCallEntry64 +.PROC KiSystemCallEntry64 + + /* Old stack pointer is in rcx, lie and say we saved it in rbp */ + .setframe rbp, 0 + .endprolog + + /* Swap gs to kernel, so we can access the PCR */ + swapgs + + /* Save the user mode rsp in the PCR */ + mov gs:[PcUserRsp], rsp + + /* Get the kernel stack from the PCR */ + mov rsp, gs:[PcRspBase] + + /* Allocate a TRAP_FRAME and space for parameters */ + sub rsp, (KTRAP_FRAME_LENGTH + MAX_SYSCALL_PARAM_SIZE + HOME_SIZE) +#if DBG + /* Save rbp and load it with the old stack pointer */ + mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + HOME_SIZE + KTRAP_FRAME_Rbp], rbp + mov rbp, gs:[PcUserRsp] +#endif + + /* Save important volatiles in the trap frame */ + mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rax], rax + mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rcx], rcx + mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R10], r10 + mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R11], r11 + + /* Set sane segments */ + mov ax, (KGDT64_R3_DATA or RPL_MASK) + mov ds, ax + mov es, ax + + /* Call the C-handler (will enable interrupts) */ + lea rcx, [rsp + SYSCALL_ALLOCATION] + call KiSystemCallHandler + + /* Deallocate the handlers home stack frame */ + add rsp, HOME_SIZE + + /* The return value is the address of the Nt-function */ + mov rcx, [rsp + 0] + mov rdx, [rsp + 8] + mov r8, [rsp + 16] + mov r9, [rsp + 24] + call rax + +#if DBG + /* Restore rbp */ + mov rbp, [rsp + SYSCALL_ALLOCATION + KTRAP_FRAME_Rbp] +#endif + + /* Disable interrupts for return */ + cli + + /* Restore old trap frame */ + mov rcx, gs:[PcCurrentThread] + mov rdx, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_TrapFrame] + mov [rcx + KTHREAD_TrapFrame], rdx + + /* Prepare user mode return address (rcx) and eflags (r11) for sysret */ + mov rcx, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rcx] + mov r11, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R11] + + /* Load user mode stack (It was copied to the trap frame) */ + mov rsp, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rsp] + + /* Swap gs back to user */ + swapgs + + /* return to user mode */ + .byte HEX(48) // REX prefix to return to long mode + sysret +.ENDP + + +PUBLIC KiSystemCallEntry32 +KiSystemCallEntry32: + swapgs + int 3 + + +PUBLIC KiZwSystemService +FUNC KiZwSystemService + push rbp + .pushreg rbp + sub rsp, KTRAP_FRAME_LENGTH + .allocstack KTRAP_FRAME_LENGTH + mov [rsp + KTRAP_FRAME_Rsi], rsi + .savereg rsi, KTRAP_FRAME_Rsi + mov [rsp + KTRAP_FRAME_Rdi], rdi + .savereg rdi, KTRAP_FRAME_Rdi + mov rbp, rsp + .setframe rbp, 0 + .endprolog + + /* Get current thread */ + mov r11, gs:[PcCurrentThread] + + /* Save the old trap frame in TrapFrame.Rdx */ + mov rdi, [r11 + KTHREAD_TrapFrame] + mov [rbp + KTRAP_FRAME_Rdx], rdi + + /* Set the new trap frame and previous mode */ + mov [r11 + ThTrapFrame], rbp + mov byte ptr [r11 + KTHREAD_PreviousMode], 0 + + /* allocate space for parameters */ + sub rsp, r10 + and rsp, HEX(0fffffffffffffff0) + + /* Save rcx */ + mov [rbp + KTRAP_FRAME_Rcx], rcx + + /* copy parameters to the new location */ + lea rsi, [rbp + KTRAP_FRAME_LENGTH + 16] + lea rdi, [rsp] + mov rcx, r10 + shr rcx, 3 + rep movsq + + /* Restore rcx */ + mov rcx, [rbp + KTRAP_FRAME_Rcx] + + /* Call the service function */ + call rax + + /* Restore the old trap frame */ + mov r11, gs:[PcCurrentThread] + mov rsi, [rsp + KTRAP_FRAME_Rdx] + mov [r11 + KTHREAD_TrapFrame], rsi + + /* Restore rdi and rsi */ + mov rsi, [rbp + KTRAP_FRAME_Rsi] + mov rdi, [rbp + KTRAP_FRAME_Rdi] + + /* Cleanup the stack and return */ + lea rsp, [rbp + KTRAP_FRAME_LENGTH] + pop rbp + ret + +ENDFUNC + + +KiExitToUserApc: + int 3 + +/*! + * VOID + * DECLSPEC_NORETURN + * KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status)); + */ +PUBLIC KiServiceExit +KiServiceExit: + mov [rcx + KTRAP_FRAME_Rax], rdx + mov rbp, rcx + mov rsp, rcx + + /* Return */ + //ExitTrap TF_SAVE_ALL + +/*! + * VOID + * DECLSPEC_NORETURN + * KiServiceExit2(IN PKTRAP_FRAME TrapFrame); + */ +PUBLIC KiServiceExit2 +.PROC KiServiceExit2 + .ENDPROLOG + + mov rbp, rcx + mov rsp, rcx + + /* Return */ + ExitTrap TF_SAVE_ALL +.ENDP + +PUBLIC KiInitializeSegments +KiInitializeSegments: + mov ax, KGDT64_R3_DATA or RPL_MASK + mov gs, ax + swapgs + mov gs, ax + ret + + #ifdef _MSC_VER #undef lgdt #undef lidt @@ -658,6 +949,11 @@ str word ptr [rcx] ret +PUBLIC __swapgs +__swapgs: + swapgs + ret + #endif END
12 years, 10 months
1
0
0
0
[tkreuzer] 55404: [ASM/AMD64] - Add multiple amd64 asm constant and structure offset definitions - Add more unwind information to the amd64 trap entry code - Add IRQL check, APC check and segment s...
by tkreuzer@svn.reactos.org
Author: tkreuzer Date: Sat Feb 4 11:01:19 2012 New Revision: 55404 URL:
http://svn.reactos.org/svn/reactos?rev=55404&view=rev
Log: [ASM/AMD64] - Add multiple amd64 asm constant and structure offset definitions - Add more unwind information to the amd64 trap entry code - Add IRQL check, APC check and segment sanitize code to trap entry/exit Modified: trunk/reactos/include/asm/genincdata.c trunk/reactos/include/asm/ksamd64.template.h trunk/reactos/include/asm/trapamd64.inc Modified: trunk/reactos/include/asm/genincdata.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/asm/genincdata.c?r…
============================================================================== --- trunk/reactos/include/asm/genincdata.c [iso-8859-1] (original) +++ trunk/reactos/include/asm/genincdata.c [iso-8859-1] Sat Feb 4 11:01:19 2012 @@ -15,6 +15,16 @@ #include <windbgkd.h> #include <wdbgexts.h> #include <kddll.h> + +#ifdef _M_AMD64 +enum +{ + P1Home = 1 * sizeof(PVOID), + P2Home = 2 * sizeof(PVOID), + P3Home = 3 * sizeof(PVOID), + P4Home = 4 * sizeof(PVOID), +}; +#endif // FIXME: where to put this? typedef struct _FIBER /* Field offsets: */ Modified: trunk/reactos/include/asm/ksamd64.template.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/asm/ksamd64.templa…
============================================================================== --- trunk/reactos/include/asm/ksamd64.template.h [iso-8859-1] (original) +++ trunk/reactos/include/asm/ksamd64.template.h [iso-8859-1] Sat Feb 4 11:01:19 2012 @@ -112,10 +112,10 @@ CONSTANT(EXCEPTION_ALIGNMENT_CHECK), HEADER("Argument Home Address"), -OFFSET(P1Home, CONTEXT, P1Home), -OFFSET(P2Home, CONTEXT, P1Home), -OFFSET(P3Home, CONTEXT, P1Home), -OFFSET(P4Home, CONTEXT, P1Home), +CONSTANT(P1Home), +CONSTANT(P2Home), +CONSTANT(P3Home), +CONSTANT(P4Home), HEADER("CONTEXT"), OFFSET(CONTEXT_P1Home, CONTEXT, P1Home), @@ -377,53 +377,55 @@ //OFFSET(PcNumber, KPCR, Number), //OFFSET(PcInterruptRequest, KPCR, InterruptRequest), //OFFSET(PcIdleHalt, KPCR, IdleHalt), -//OFFSET(PcCurrentThread, KPCR, CurrentThread), +OFFSET(PcCurrentThread, KIPCR, Prcb.CurrentThread), //OFFSET(PcNextThread, KPCR, NextThread), //OFFSET(PcIdleThread, KPCR, IdleThread), //OFFSET(PcIpiFrozen, KPCR, IpiFrozen), //OFFSET(PcNestingLevel, KPCR, NestingLevel), -//OFFSET(PcRspBase, KPCR, RspBase), +OFFSET(PcRspBase, KIPCR, Prcb.RspBase), //OFFSET(PcPrcbLock, KPCR, PrcbLock), +OFFSET(PcSetMember, KIPCR, Prcb.SetMember), #if 0 -OFFSET(PcSetMember, KPCR, SetMember), -OFFSET(PcCr0, KPCR, Cr0), -OFFSET(PcCr2, KPCR, Cr2), -OFFSET(PcCr3, KPCR, Cr3), -OFFSET(PcCr4, KPCR, Cr4), -OFFSET(PcKernelDr0, KPCR, KernelDr0), -OFFSET(PcKernelDr1, KPCR, KernelDr1), -OFFSET(PcKernelDr2, KPCR, KernelDr2), -OFFSET(PcKernelDr3, KPCR, KernelDr3), -OFFSET(PcKernelDr7, KPCR, KernelDr7), -OFFSET(PcGdtrLimit, KPCR, GdtrLimit), -OFFSET(PcGdtrBase, KPCR, GdtrBase), -OFFSET(PcIdtrLimit, KPCR, IdtrLimit), -OFFSET(PcIdtrBase, KPCR, IdtrBase), -OFFSET(PcTr, KPCR, Tr), -OFFSET(PcLdtr, KPCR, Ldtr), -OFFSET(PcDebugControl, KPCR, DebugControl), -OFFSET(PcLastBranchToRip, KPCR, LastBranchToRip), -OFFSET(PcLastBranchFromRip, KPCR, LastBranchFromRip), -OFFSET(PcLastExceptionToRip, KPCR, LastExceptionToRip), -OFFSET(PcLastExceptionFromRip, KPCR, LastExceptionFromRip), -OFFSET(PcCr8, KPCR, Cr8), -OFFSET(PcCpuType, KPCR, CpuType), -OFFSET(PcCpuID, KPCR, CpuID), -OFFSET(PcCpuStep, KPCR, CpuStep), -OFFSET(PcCpuVendor, KPCR, CpuVendor), -OFFSET(PcVirtualApicAssist, KPCR, VirtualApicAssist), -OFFSET(PcCFlushSize, KPCR, CFlushSize), -OFFSET(PcDeferredReadyListHead, KPCR, DeferredReadyListHead), -OFFSET(PcSystemCalls, KPCR, SystemCalls), -OFFSET(PcDpcRoutineActive, KPCR, DpcRoutineActive), -OFFSET(PcInterruptCount, KPCR, InterruptCount), -OFFSET(PcDebuggerSavedIRQL, KPCR, DebuggerSavedIRQL), -OFFSET(PcTickOffset, KPCR, TickOffset), -OFFSET(PcMasterOffset, KPCR, MasterOffset), -OFFSET(PcSkipTick, KPCR, SkipTick), -OFFSET(PcStartCycles, KPCR, StartCycles), -SIZE(ProcessorControlRegisterLength, KPCR), +OFFSET(PcCr0, KIPCR, Prcb.Cr0), +OFFSET(PcCr2, KIPCR, Prcb.Cr2), +OFFSET(PcCr3, KIPCR, Prcb.Cr3), +OFFSET(PcCr4, KIPCR, Prcb.Cr4), +OFFSET(PcKernelDr0, KIPCR, Prcb.KernelDr0), +OFFSET(PcKernelDr1, KIPCR, Prcb.KernelDr1), +OFFSET(PcKernelDr2, KIPCR, Prcb.KernelDr2), +OFFSET(PcKernelDr3, KIPCR, Prcb.KernelDr3), +OFFSET(PcKernelDr7, KIPCR, Prcb.KernelDr7), +OFFSET(PcGdtrLimit, KIPCR, Prcb.GdtrLimit), +OFFSET(PcGdtrBase, KIPCR, Prcb.GdtrBase), +OFFSET(PcIdtrLimit, KIPCR, IdtrLimit), +OFFSET(PcIdtrBase, KIPCR, IdtrBase), +OFFSET(PcTr, KIPCR, Tr), +OFFSET(PcLdtr, KIPCR, Ldtr), +OFFSET(PcDebugControl, KIPCR, DebugControl), +OFFSET(PcLastBranchToRip, KIPCR, LastBranchToRip), +OFFSET(PcLastBranchFromRip, KIPCR, LastBranchFromRip), +OFFSET(PcLastExceptionToRip, KIPCR, LastExceptionToRip), +OFFSET(PcLastExceptionFromRip, KIPCR, LastExceptionFromRip), +OFFSET(PcCr8, KIPCR, Cr8), #endif +OFFSET(PcCpuType, KIPCR, Prcb.CpuType), +OFFSET(PcCpuID, KIPCR, Prcb.CpuID), +OFFSET(PcCpuStep, KIPCR, Prcb.CpuStep), +OFFSET(PcCpuVendor, KIPCR, Prcb.CpuVendor), +OFFSET(PcCFlushSize, KIPCR, Prcb.CFlushSize), +OFFSET(PcDeferredReadyListHead, KIPCR, Prcb.DeferredReadyListHead), +OFFSET(PcSystemCalls, KIPCR, Prcb.KeSystemCalls), +OFFSET(PcDpcRoutineActive, KIPCR, Prcb.DpcRoutineActive), +OFFSET(PcInterruptCount, KIPCR, Prcb.InterruptCount), +OFFSET(PcDebuggerSavedIRQL, KIPCR, Prcb.DebuggerSavedIRQL), +OFFSET(PcTickOffset, KIPCR, Prcb.TickOffset), +OFFSET(PcMasterOffset, KIPCR, Prcb.MasterOffset), +OFFSET(PcSkipTick, KIPCR, Prcb.SkipTick), +#if (NTDDI_VERSION >= NTDDI_LONGHORN) +OFFSET(PcVirtualApicAssist, KIPCR, Prcb.VirtualApicAssist), +OFFSET(PcStartCycles, KIPCR, Prcb.StartCycles), +#endif +SIZE(ProcessorControlRegisterLength, KIPCR), HEADER("KPROCESSOR_STATE"), OFFSET(PsSpecialRegisters, KPROCESSOR_STATE, SpecialRegisters), @@ -578,4 +580,33 @@ OFFSET(EXCEPTION_RECORD_NumberParameters, EXCEPTION_RECORD, NumberParameters), OFFSET(EXCEPTION_RECORD_ExceptionInformation, EXCEPTION_RECORD, ExceptionInformation), +HEADER("KTHREAD"), OFFSET(KTHREAD_WAIT_IRQL, KTHREAD, WaitIrql), +OFFSET(KTHREAD_TrapFrame, KTHREAD, TrapFrame), +OFFSET(KTHREAD_PreviousMode, KTHREAD, PreviousMode), +OFFSET(KTHREAD_KernelStack, KTHREAD, KernelStack), +OFFSET(KTHREAD_UserApcPending, KTHREAD, ApcState.UserApcPending), + +HEADER("KINTERRUPT"), + +OFFSET(KINTERRUPT_Type, KINTERRUPT, Type), +OFFSET(KINTERRUPT_Size, KINTERRUPT, Size), +OFFSET(KINTERRUPT_InterruptListEntry, KINTERRUPT, InterruptListEntry), +OFFSET(KINTERRUPT_ServiceRoutine, KINTERRUPT, ServiceRoutine), +OFFSET(KINTERRUPT_ServiceContext, KINTERRUPT, ServiceContext), +OFFSET(KINTERRUPT_SpinLock, KINTERRUPT, SpinLock), +OFFSET(KINTERRUPT_TickCount, KINTERRUPT, TickCount), +OFFSET(KINTERRUPT_ActualLock, KINTERRUPT, ActualLock), +OFFSET(KINTERRUPT_DispatchAddress, KINTERRUPT, DispatchAddress), +OFFSET(KINTERRUPT_Vector, KINTERRUPT, Vector), +OFFSET(KINTERRUPT_Irql, KINTERRUPT, Irql), +OFFSET(KINTERRUPT_SynchronizeIrql, KINTERRUPT, SynchronizeIrql), +OFFSET(KINTERRUPT_FloatingSave, KINTERRUPT, FloatingSave), +OFFSET(KINTERRUPT_Connected, KINTERRUPT, Connected), +OFFSET(KINTERRUPT_Number, KINTERRUPT, Number), +OFFSET(KINTERRUPT_ShareVector, KINTERRUPT, ShareVector), +OFFSET(KINTERRUPT_Mode, KINTERRUPT, Mode), +OFFSET(KINTERRUPT_ServiceCount, KINTERRUPT, ServiceCount), +OFFSET(KINTERRUPT_DispatchCount, KINTERRUPT, DispatchCount), +OFFSET(KINTERRUPT_TrapFrame, KINTERRUPT, TrapFrame), +OFFSET(KINTERRUPT_DispatchCode, KINTERRUPT, DispatchCode), Modified: trunk/reactos/include/asm/trapamd64.inc URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/asm/trapamd64.inc?…
============================================================================== --- trunk/reactos/include/asm/trapamd64.inc [iso-8859-1] (original) +++ trunk/reactos/include/asm/trapamd64.inc [iso-8859-1] Sat Feb 4 11:01:19 2012 @@ -11,6 +11,7 @@ TF_HAS_ERROR_CODE = HEX(40) TF_SEND_EOI = HEX(80) //TF_SYSTEMSERVICE = (TRAPFLAG_VOLATILES or TRAPFLAG_DEBUG) +TF_CHECKUSERAPC = HEX(100) /* * Stack Layout: @@ -28,7 +29,7 @@ * EnterTrap - Allocate KTRAP_FRAME_LENGTH and save registers to it */ MACRO(EnterTrap, Flags) - LOCAL dont_swap + LOCAL kernel_mode_entry /* Save the trap flags for this trap */ CurrentTrapFlags = VAL(Flags) @@ -45,21 +46,28 @@ /* Make room for a KTRAP_FRAME */ sub rsp, (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME) .allocstack (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME) - .endprolog /* Save rbp and rax */ mov [rsp + KTRAP_FRAME_Rbp], rbp + .savereg rbp, KTRAP_FRAME_Rbp mov [rsp + KTRAP_FRAME_Rax], rax + .savereg rax, KTRAP_FRAME_Rax /* Point rbp to the KTRAP_FRAME */ lea rbp, [rsp] + .setframe rbp, 0 if (Flags AND TF_NONVOLATILES) /* Save non-volatile registers */ mov [rbp + KTRAP_FRAME_Rbx], rbx + .savereg rbx, KTRAP_FRAME_Rbx mov [rbp + KTRAP_FRAME_Rdi], rdi + .savereg rdi, KTRAP_FRAME_Rdi mov [rbp + KTRAP_FRAME_Rsi], rsi - endif + .savereg rsi, KTRAP_FRAME_Rsi + endif + + .endprolog if (Flags AND TF_VOLATILES) /* Save volatile registers */ @@ -89,19 +97,25 @@ mov [rbp + KTRAP_FRAME_SegGs], gs endif - /* Save previous mode and swap gs when it was UserMode */ + /* Save previous mode and check if it was user mode */ mov ax, [rbp + KTRAP_FRAME_SegCs] and al, 1 mov [rbp + KTRAP_FRAME_PreviousMode], al - jz dont_swap + jz kernel_mode_entry + + /* Set sane segments */ + mov ax, (KGDT64_R3_DATA or RPL_MASK) + mov ds, ax + mov es, ax swapgs -dont_swap: - - if (Flags AND TF_IRQL) + +kernel_mode_entry: + +// if (Flags AND TF_IRQL) /* Save previous irql */ mov rax, cr8 mov [rbp + KTRAP_FRAME_PreviousIrql], al - endif +// endif if (Flags AND TF_DEBUG) /* Save debug registers */ @@ -127,7 +141,16 @@ * ExitTrap - Restore registers and free stack space */ MACRO(ExitTrap, Flags) - LOCAL dont_swap_back + LOCAL kernel_mode_return + +#if DBG + /* Check previous irql */ + mov rax, cr8 + cmp [rbp + KTRAP_FRAME_PreviousIrql], al + je .irql_ok + int 3 + .irql_ok: +#endif if (Flags AND TF_SEGMENTS) /* Restore segment selectors */ @@ -142,10 +165,22 @@ mov cr8, rax endif - test byte ptr [rbp + KTRAP_FRAME_PreviousMode], 1 - jz dont_swap_back + /* Check if we came from user mode */ + test byte ptr [rbp + KTRAP_FRAME_SegCs], 1 + jz kernel_mode_return + + if (Flags AND TF_CHECKUSERAPC) + /* Load current thread into r10 */ + mov r10, gs:[PcCurrentThread] + cmp byte ptr [r10 + KTHREAD_UserApcPending], 0 + jne KiExitToUserApc + + endif + + /* Swap gs to user mode */ swapgs -dont_swap_back: + +kernel_mode_return: if (Flags AND TF_NONVOLATILES) /* Restore non-volatile registers */ @@ -204,6 +239,6 @@ /* Leave */ ExitTrap Flags - ENDFUNC &Trap + ENDFUNC ENDM
12 years, 10 months
1
0
0
0
[tkreuzer] 55403: [NTOSKRNL/MM/AMD64] - Add MI_REAL_SYSTEM_RANGE_START, which is the canonical system space base address, while MmSystemRangeStart variable contains a broken value, like on Windows....
by tkreuzer@svn.reactos.org
Author: tkreuzer Date: Sat Feb 4 10:40:27 2012 New Revision: 55403 URL:
http://svn.reactos.org/svn/reactos?rev=55403&view=rev
Log: [NTOSKRNL/MM/AMD64] - Add MI_REAL_SYSTEM_RANGE_START, which is the canonical system space base address, while MmSystemRangeStart variable contains a broken value, like on Windows. - Define MmSystemRangeStart to MI_REAL_SYSTEM_RANGE_START, since on amd64 there is no dynamic system space start address and we don't want to use the broken address anywhere - Add some more address layout definitions - Add MiIsPteOnP*eBoundary() macro - Add MMPPE, MI_WRITE_VALID_PPE and ValidKernelPpe definitions - Fix initialization of PrototypePte - Add mappings for VAD bitmap and working set list to MiInitializePageTable - Fix calculations in MiBuildNonPagedPool - Improve MiBuildSystemPteSpace - Implement MiBuildPfnDatabase, MiAddDescriptorToDatabase, MiBuildPfnDatabaseFromPageTables, MiSetupPfnForPageTable all of these are written to be portable, yet they are untested on anything else than amd64 builds - Mostly finish MiInitMachineDependent Modified: trunk/reactos/ntoskrnl/include/internal/amd64/mm.h trunk/reactos/ntoskrnl/mm/amd64/init.c Modified: trunk/reactos/ntoskrnl/include/internal/amd64/mm.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/amd64/mm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/amd64/mm.h [iso-8859-1] Sat Feb 4 10:40:27 2012 @@ -8,29 +8,39 @@ #define MI_HIGHEST_USER_ADDRESS (PVOID)0x000007FFFFFEFFFFULL #define MI_USER_PROBE_ADDRESS (PVOID)0x000007FFFFFF0000ULL #define MI_DEFAULT_SYSTEM_RANGE_START (PVOID)0xFFFF080000000000ULL +#define MI_REAL_SYSTEM_RANGE_START 0xFFFF800000000000ULL +#define MI_PAGE_TABLE_BASE 0xFFFFF68000000000ULL #define HYPER_SPACE 0xFFFFF70000000000ULL #define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL -#define MI_SESSION_SPACE_MINIMUM (PVOID)0xFFFFF90000000000ULL -#define MI_SESSION_VIEW_END (PVOID)0xFFFFF97FFF000000ULL -#define MI_SESSION_SPACE_END (PVOID)0xFFFFF98000000000ULL -#define MI_SYSTEM_PTE_START (PVOID)0xFFFFFAA000000000ULL -#define MI_PAGED_POOL_START (PVOID)0xFFFFFA8000000000ULL -#define MI_NON_PAGED_SYSTEM_START_MIN 0xFFFFFAA000000000ULL -#define MI_PFN_DATABASE (PVOID)0xFFFFFAC000000000ULL -#define MI_NONPAGED_POOL_END (PVOID)0xFFFFFAE000000000ULL -#define MI_DEBUG_MAPPING (PVOID)0xFFFFFFFF80000000ULL // FIXME +#define MI_SHARED_SYSTEM_PAGE 0xFFFFF78000000000ULL +#define MI_SYSTEM_CACHE_WS_START 0xFFFFF78000001000ULL +#define MI_LOADER_MAPPINGS 0xFFFFF80000000000ULL +#define MI_PAGED_SYSTEM_START 0xFFFFF88000000000ULL +#define MI_PAGED_POOL_START (PVOID)0xFFFFF8A000000000ULL +#define MI_PAGED_POOL_END 0xFFFFF8BFFFFFFFFFULL +#define MI_SESSION_SPACE_START 0xFFFFF90000000000ULL +#define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL +#define MI_SESSION_SPACE_END 0xFFFFF97FFFFFFFFFULL +#define MM_SYSTEM_SPACE_START 0xFFFFF98000000000ULL +#define MI_PFN_DATABASE 0xFFFFFA8000000000ULL #define MI_HIGHEST_SYSTEM_ADDRESS (PVOID)0xFFFFFFFFFFFFFFFFULL -#define MI_SYSTEM_CACHE_WS_START (PVOID)0xFFFFF78000001000ULL // CHECKME - + +/* WOW64 address definitions */ #define MM_HIGHEST_USER_ADDRESS_WOW64 0x7FFEFFFF #define MM_SYSTEM_RANGE_START_WOW64 0x80000000 - -#define MI_SYSTEM_PTE_END (PVOID)((ULONG64)MI_SYSTEM_PTE_START + MI_NUMBER_SYSTEM_PTES * PAGE_SIZE - 1) +#define MI_DEBUG_MAPPING (PVOID)0xFFFFFFFF80000000ULL // FIXME +#define MI_NON_PAGED_SYSTEM_START_MIN MM_SYSTEM_SPACE_START // FIXME +#define MI_SYSTEM_PTE_START MM_SYSTEM_SPACE_START +#define MI_SYSTEM_PTE_END (MI_SYSTEM_PTE_START + MI_NUMBER_SYSTEM_PTES * PAGE_SIZE - 1) #define MI_SYSTEM_PTE_BASE (PVOID)MiAddressToPte(KSEG0_BASE) #define MM_HIGHEST_VAD_ADDRESS (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE)) -#define MI_MAPPING_RANGE_START (ULONG64)HYPER_SPACE +#define MI_MAPPING_RANGE_START HYPER_SPACE #define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + MI_HYPERSPACE_PTES * PAGE_SIZE) +#define MI_DUMMY_PTE (MI_MAPPING_RANGE_END + PAGE_SIZE) +#define MI_VAD_BITMAP (MI_DUMMY_PTE + PAGE_SIZE) +#define MI_WORKING_SET_LIST (MI_VAD_BITMAP + PAGE_SIZE) +#define MI_NONPAGED_POOL_END 0 /* Memory sizes */ #define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255*1024*1024) >> PAGE_SHIFT) @@ -55,6 +65,8 @@ MI_SESSION_IMAGE_SIZE + \ MI_SESSION_WORKING_SET_SIZE) +#define MmSystemRangeStart ((PVOID)MI_REAL_SYSTEM_RANGE_START) + /* Misc constants */ #define _MI_PAGING_LEVELS 4 #define MI_NUMBER_SYSTEM_PTES 22000 @@ -63,9 +75,6 @@ #define NR_SECTION_PAGE_ENTRIES 1024 #define MI_HYPERSPACE_PTES (256 - 1) #define MI_ZERO_PTES (32) -#define MI_DUMMY_PTE (PMMPTE)(MI_MAPPING_RANGE_END + PAGE_SIZE) -#define MI_VAD_BITMAP (PMMPTE)(MI_DUMMY_PTE + PAGE_SIZE) -#define MI_WORKING_SET_LIST (PMMPTE)(MI_VAD_BITMAP + PAGE_SIZE) /* FIXME - different architectures have different cache line sizes... */ #define MM_CACHE_LINE_SIZE 32 @@ -74,6 +83,13 @@ #define PAE_PAGE_MASK(x) ((x)&(~0xfffLL)) #define IS_ALIGNED(addr, align) (((ULONG64)(addr) & (align - 1)) == 0) #define IS_PAGE_ALIGNED(addr) IS_ALIGNED(addr, PAGE_SIZE) + +#define MiIsPteOnPdeBoundary(PointerPte) \ + ((((ULONG_PTR)PointerPte) & (PAGE_SIZE - 1)) == 0) +#define MiIsPteOnPpeBoundary(PointerPte) \ + ((((ULONG_PTR)PointerPte) & (PDE_PER_PAGE * PAGE_SIZE - 1)) == 0) +#define MiIsPteOnPxeBoundary(PointerPte) \ + ((((ULONG_PTR)PointerPte) & (PPE_PER_PAGE * PDE_PER_PAGE * PAGE_SIZE - 1)) == 0) /* MMPTE related defines */ #define MM_EMPTY_PTE_LIST ((ULONG64)0xFFFFFFFF) @@ -129,6 +145,11 @@ /* On x86, these two are the same */ #define MMPDE MMPTE #define PMMPDE PMMPTE +#define MMPPE MMPTE +#define PMMPPE PMMPTE +#define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE + +#define ValidKernelPpe ValidKernelPde PULONG64 FORCEINLINE Modified: trunk/reactos/ntoskrnl/mm/amd64/init.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/amd64/init.c?r…
============================================================================== --- trunk/reactos/ntoskrnl/mm/amd64/init.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/amd64/init.c [iso-8859-1] Sat Feb 4 10:40:27 2012 @@ -32,13 +32,12 @@ /* Template PTE for prototype page */ MMPTE PrototypePte = {{(MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS) | - PTE_PROTOTYPE | (MI_PTE_LOOKUP_NEEDED << PAGE_SHIFT)}}; - -/* Sizes */ -SIZE_T MiNonPagedSystemSize; + PTE_PROTOTYPE | (MI_PTE_LOOKUP_NEEDED << 32)}}; /* Address ranges */ PVOID MiSessionViewEnd; +PVOID MiSystemPteSpaceStart; +PVOID MiSystemPteSpaceEnd; ULONG64 MxPfnSizeInBytes; BOOLEAN MiIncludeType[LoaderMaximum]; @@ -69,7 +68,7 @@ /* The view starts right below the session working set (itself below * the image area) */ - MiSessionViewEnd = MI_SESSION_VIEW_END; + MiSessionViewEnd = (PVOID)MI_SESSION_VIEW_END; MiSessionViewStart = (PCHAR)MiSessionViewEnd - MmSessionViewSize; ASSERT(IS_PAGE_ALIGNED(MiSessionViewStart)); @@ -110,7 +109,7 @@ { /* No, map it! */ TmplPde.u.Hard.PageFrameNumber = MxGetNextPage(1); - *PointerPpe = TmplPde; + MI_WRITE_VALID_PTE(PointerPpe, TmplPde); /* Zero out the page table */ RtlZeroMemory(MiPteToAddress(PointerPpe), PAGE_SIZE); @@ -137,7 +136,7 @@ { /* No, map it! */ TmplPde.u.Hard.PageFrameNumber = MxGetNextPage(1); - *PointerPde = TmplPde; + MI_WRITE_VALID_PTE(PointerPde, TmplPde); /* Zero out the page table */ RtlZeroMemory(MiPteToAddress(PointerPde), PAGE_SIZE); @@ -164,7 +163,10 @@ { /* No, map it! */ TmplPte.u.Hard.PageFrameNumber = MxGetNextPage(1); - *PointerPte = TmplPte; + MI_WRITE_VALID_PTE(PointerPte, TmplPte); + + /* Zero out the page (FIXME: not always neccessary) */ + RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE); } } } @@ -212,10 +214,10 @@ HyperTemplatePte = TmplPte; /* Create PDPTs (72 KB) for shared system address space, - * skip page tables and hyperspace */ + * skip page tables TODO: use global pages. */ /* Loop the PXEs */ - for (PointerPxe = MiAddressToPxe((PVOID)(HYPER_SPACE_END + 1)); + for (PointerPxe = MiAddressToPxe((PVOID)HYPER_SPACE); PointerPxe <= MiAddressToPxe(MI_HIGHEST_SYSTEM_ADDRESS); PointerPxe++) { @@ -231,8 +233,13 @@ } } - /* Setup the mapping PPEs and PDEs */ - MiMapPPEs((PVOID)MI_MAPPING_RANGE_START, (PVOID)MI_MAPPING_RANGE_END); + /* Map PPEs for paged pool */ + MiMapPPEs(MmPagedPoolStart, MmPagedPoolEnd); + + /* Setup 1 PPE for hyper space */ + MiMapPPEs((PVOID)HYPER_SPACE, (PVOID)HYPER_SPACE_END); + + /* Setup the mapping PDEs */ MiMapPDEs((PVOID)MI_MAPPING_RANGE_START, (PVOID)MI_MAPPING_RANGE_END); /* Setup the mapping PTEs */ @@ -246,6 +253,10 @@ MiMapPDEs((PVOID)MI_DEBUG_MAPPING, (PVOID)MI_DEBUG_MAPPING); MmDebugPte = MiAddressToPte((PVOID)MI_DEBUG_MAPPING); #endif + + /* Setup PDE and PTEs for VAD bitmap and working set list */ + MiMapPDEs((PVOID)MI_VAD_BITMAP, (PVOID)(MI_WORKING_SET_LIST + PAGE_SIZE - 1)); + MiMapPTEs((PVOID)MI_VAD_BITMAP, (PVOID)(MI_WORKING_SET_LIST + PAGE_SIZE - 1)); } VOID @@ -311,34 +322,31 @@ MmMaximumNonPagedPoolInBytes = MI_MAX_NONPAGED_POOL_SIZE; } - /* Put non paged pool to the end of the region */ - MmNonPagedPoolStart = (PCHAR)MmNonPagedPoolEnd - MmMaximumNonPagedPoolInBytes; - - /* Make sure it doesn't collide with the PFN database */ - if ((PCHAR)MmNonPagedPoolStart < (PCHAR)MmPfnDatabase + MxPfnSizeInBytes) - { - /* Put non paged pool after the PFN database */ - MmNonPagedPoolStart = (PCHAR)MmPfnDatabase + MxPfnSizeInBytes; - MmMaximumNonPagedPoolInBytes = (ULONG64)MmNonPagedPoolEnd - - (ULONG64)MmNonPagedPoolStart; - } - - ASSERT(IS_PAGE_ALIGNED(MmNonPagedPoolStart)); + /* Convert nonpaged pool size from bytes to pages */ + MmMaximumNonPagedPoolInPages = MmMaximumNonPagedPoolInBytes >> PAGE_SHIFT; + + /* Non paged pool starts after the PFN database */ + MmNonPagedPoolStart = MmPfnDatabase + MxPfnAllocation * PAGE_SIZE; /* Calculate the nonpaged pool expansion start region */ MmNonPagedPoolExpansionStart = (PCHAR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes; ASSERT(IS_PAGE_ALIGNED(MmNonPagedPoolExpansionStart)); + /* And this is where the none paged pool ends */ + MmNonPagedPoolEnd = (PCHAR)MmNonPagedPoolStart + MmMaximumNonPagedPoolInBytes; + ASSERT(MmNonPagedPoolEnd < (PVOID)MM_HAL_VA_START); + /* Map PPEs and PDEs for non paged pool (including expansion) */ MiMapPPEs(MmNonPagedPoolStart, MmNonPagedPoolEnd); MiMapPDEs(MmNonPagedPoolStart, MmNonPagedPoolEnd); /* Map the nonpaged pool PTEs (without expansion) */ - MiMapPTEs(MmNonPagedPoolStart, (PUCHAR)MmNonPagedPoolExpansionStart - 1); + MiMapPTEs(MmNonPagedPoolStart, (PCHAR)MmNonPagedPoolExpansionStart - 1); /* Initialize the ARM3 nonpaged pool */ MiInitializeNonPagedPool(); + MiInitializeNonPagedPoolThresholds(); /* Initialize the nonpaged pool */ InitializePool(NonPagedPool, 0); @@ -353,32 +361,18 @@ /* Use the default numer of system PTEs */ MmNumberOfSystemPtes = MI_NUMBER_SYSTEM_PTES; - - /* System PTE pool is below the PFN database */ MiNonPagedSystemSize = (MmNumberOfSystemPtes + 1) * PAGE_SIZE; - MmNonPagedSystemStart = (PCHAR)MmPfnDatabase - MiNonPagedSystemSize; - MmNonPagedSystemStart = MM_ROUND_DOWN(MmNonPagedSystemStart, 512 * PAGE_SIZE); - - /* Don't let it go below the minimum */ - if (MmNonPagedSystemStart < (PVOID)MI_NON_PAGED_SYSTEM_START_MIN) - { - /* This is a hard-coded limit in the Windows NT address space */ - MmNonPagedSystemStart = (PVOID)MI_NON_PAGED_SYSTEM_START_MIN; - - /* Reduce the amount of system PTEs to reach this point */ - MmNumberOfSystemPtes = (ULONG)(((ULONG64)MmPfnDatabase - - (ULONG64)MmNonPagedSystemStart) >> - PAGE_SHIFT); - MmNumberOfSystemPtes--; - ASSERT(MmNumberOfSystemPtes > 1000); - } - - /* Map the PDEs and PPEs for the system PTEs */ - MiMapPPEs(MI_SYSTEM_PTE_START, MI_SYSTEM_PTE_END); - MiMapPDEs(MI_SYSTEM_PTE_START, MI_SYSTEM_PTE_END); - - /* Create the system PTE space */ - PointerPte = MiAddressToPte(MI_SYSTEM_PTE_START); + + /* Put system PTEs at the start of the system VA space */ + MiSystemPteSpaceStart = MmNonPagedSystemStart; + MiSystemPteSpaceEnd = (PUCHAR)MiSystemPteSpaceStart + MiNonPagedSystemSize; + + /* Map the PPEs and PDEs for the system PTEs */ + MiMapPPEs(MiSystemPteSpaceStart, MiSystemPteSpaceEnd); + MiMapPDEs(MiSystemPteSpaceStart, MiSystemPteSpaceEnd); + + /* Initialize the system PTE space */ + PointerPte = MiAddressToPte(MiSystemPteSpaceStart); MiInitializeSystemPtes(PointerPte, MmNumberOfSystemPtes, SystemPteSpace); /* Reserve system PTEs for zeroing PTEs and clear them */ @@ -389,13 +383,302 @@ MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES - 1; } +static +VOID +MiSetupPfnForPageTable( + PFN_NUMBER PageFrameIndex, + PMMPTE PointerPte) +{ + PMMPFN Pfn; + PMMPDE PointerPde; + + /* Get the pfn entry for this page */ + Pfn = MiGetPfnEntry(PageFrameIndex); + + /* Check if it's valid memory */ + if ((PageFrameIndex <= MmHighestPhysicalPage) && + (MmIsAddressValid(Pfn)) && + (Pfn->u3.e1.PageLocation == ActiveAndValid)) + { + /* Setup the PFN entry */ + Pfn->u1.WsIndex = 0; + Pfn->u2.ShareCount++; + Pfn->PteAddress = PointerPte; + Pfn->OriginalPte = *PointerPte; + Pfn->u3.e1.PageLocation = ActiveAndValid; + Pfn->u3.e1.CacheAttribute = MiNonCached; + Pfn->u3.e2.ReferenceCount = 1; + Pfn->u4.PteFrame = PFN_FROM_PTE(MiAddressToPte(PointerPte)); + } + + /* Increase the shared count of the PFN entry for the PDE */ + PointerPde = MiAddressToPde(MiPteToAddress(PointerPte)); + Pfn = MiGetPfnEntry(PFN_FROM_PTE(PointerPde)); + Pfn->u2.ShareCount++; +} + +VOID +NTAPI +MiBuildPfnDatabaseFromPageTables(VOID) +{ + PVOID Address = NULL; + PFN_NUMBER PageFrameIndex; + PMMPDE PointerPde; + PMMPTE PointerPte; + ULONG k, l; + PMMPFN Pfn; +#if (_MI_PAGING_LEVELS >= 3) + PMMPDE PointerPpe; + ULONG j; +#endif +#if (_MI_PAGING_LEVELS == 4) + PMMPDE PointerPxe; + ULONG i; +#endif + + /* Manual setup of the top level page directory */ +#if (_MI_PAGING_LEVELS == 4) + PageFrameIndex = PFN_FROM_PTE(MiAddressToPte(PXE_BASE)); +#elif (_MI_PAGING_LEVELS == 3) + PageFrameIndex = PFN_FROM_PTE(MiAddressToPte(PPE_BASE)); +#else + PageFrameIndex = PFN_FROM_PTE(MiAddressToPte(PDE_BASE)); +#endif + Pfn = MiGetPfnEntry(PageFrameIndex); + ASSERT(Pfn->u3.e1.PageLocation == ActiveAndValid); + Pfn->u1.WsIndex = 0; + Pfn->u2.ShareCount = 1; + Pfn->PteAddress = NULL; + Pfn->u3.e1.CacheAttribute = MiNonCached; + Pfn->u3.e2.ReferenceCount = 1; + Pfn->u4.PteFrame = 0; + +#if (_MI_PAGING_LEVELS == 4) + /* Loop all PXEs in the PML4 */ + PointerPxe = MiAddressToPxe(Address); + for (i = 0; i < PXE_PER_PAGE; i++, PointerPxe++) + { + /* Skip invalid PXEs */ + if (!PointerPxe->u.Hard.Valid) continue; + + /* Handle the PFN */ + PageFrameIndex = PFN_FROM_PXE(PointerPxe); + MiSetupPfnForPageTable(PageFrameIndex, PointerPxe); + + /* Get starting VA for this PXE */ + Address = MiPxeToAddress(PointerPxe); +#endif +#if (_MI_PAGING_LEVELS >= 3) + /* Loop all PPEs in this PDP */ + PointerPpe = MiAddressToPpe(Address); + for (j = 0; j < PPE_PER_PAGE; j++, PointerPpe++) + { + /* Skip invalid PPEs */ + if (!PointerPpe->u.Hard.Valid) continue; + + /* Handle the PFN */ + PageFrameIndex = PFN_FROM_PPE(PointerPpe); + MiSetupPfnForPageTable(PageFrameIndex, PointerPpe); + + /* Get starting VA for this PPE */ + Address = MiPpeToAddress(PointerPpe); +#endif + /* Loop all PDEs in this PD */ + PointerPde = MiAddressToPde(Address); + for (k = 0; k < PDE_PER_PAGE; k++, PointerPde++) + { + /* Skip invalid PDEs */ + if (!PointerPde->u.Hard.Valid) continue; + + /* Handle the PFN */ + PageFrameIndex = PFN_FROM_PDE(PointerPde); + MiSetupPfnForPageTable(PageFrameIndex, PointerPde); + + /* Get starting VA for this PDE */ + Address = MiPdeToAddress(PointerPde); + + /* Loop all PTEs in this PT */ + PointerPte = MiAddressToPte(Address); + for (l = 0; l < PTE_PER_PAGE; l++, PointerPte++) + { + /* Skip invalid PTEs */ + if (!PointerPte->u.Hard.Valid) continue; + + /* Handle the PFN */ + PageFrameIndex = PFN_FROM_PTE(PointerPte); + MiSetupPfnForPageTable(PageFrameIndex, PointerPte); + } + } +#if (_MI_PAGING_LEVELS >= 3) + } +#endif +#if (_MI_PAGING_LEVELS == 4) + } +#endif +} + +VOID +NTAPI +INIT_FUNCTION +MiAddDescriptorToDatabase( + PFN_NUMBER BasePage, + PFN_NUMBER PageCount, + TYPE_OF_MEMORY MemoryType) +{ + PMMPFN Pfn; + + ASSERT(!MiIsMemoryTypeInvisible(MemoryType)); + + /* Check if the memory is free */ + if (MiIsMemoryTypeFree(MemoryType)) + { + /* Get the last pfn of this descriptor. Note we loop backwards */ + Pfn = &MmPfnDatabase[BasePage + PageCount - 1]; + + /* Loop all pages */ + while (PageCount--) + { + /* Add it to the free list */ + Pfn->u3.e1.CacheAttribute = MiNonCached; + MiInsertPageInFreeList(BasePage + PageCount); + + /* Go to the previous page */ + Pfn--; + } + } + else if (MemoryType == LoaderXIPRom) + { + Pfn = &MmPfnDatabase[BasePage]; + while (PageCount--) + { + /* Make it a pseudo-I/O ROM mapping */ + Pfn->PteAddress = 0; + Pfn->u1.Flink = 0; + Pfn->u2.ShareCount = 0; + Pfn->u3.e1.PageLocation = 0; + Pfn->u3.e1.CacheAttribute = MiNonCached; + Pfn->u3.e1.Rom = 1; + Pfn->u3.e1.PrototypePte = 1; + Pfn->u3.e2.ReferenceCount = 0; + Pfn->u4.InPageError = 0; + Pfn->u4.PteFrame = 0; + + /* Advance one */ + Pfn++; + } + } + else if (MemoryType == LoaderBad) + { + // FIXME: later + ASSERT(FALSE); + } + else + { + /* For now skip it */ + DbgPrint("Skipping BasePage=0x%lx, PageCount=0x%lx, MemoryType=%lx\n", + BasePage, PageCount, MemoryType); + Pfn = &MmPfnDatabase[BasePage]; + while (PageCount--) + { + /* Make an active PFN */ + Pfn->u3.e1.PageLocation = ActiveAndValid; + + /* Advance one */ + Pfn++; + } + } +} + +VOID +NTAPI +INIT_FUNCTION +MiBuildPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PLIST_ENTRY ListEntry; + PMEMORY_ALLOCATION_DESCRIPTOR Descriptor; + PFN_NUMBER BasePage, PageCount; + + /* Map the PDEs and PPEs for the pfn database (ignore holes) */ +#if (_MI_PAGING_LEVELS >= 3) + MiMapPPEs(MmPfnDatabase, (PUCHAR)MmPfnDatabase + MxPfnAllocation - 1); +#endif + MiMapPDEs(MmPfnDatabase, (PUCHAR)MmPfnDatabase + MxPfnAllocation - 1); + + /* First initialize the color tables */ + MiInitializeColorTables(); + + /* Loop the memory descriptors */ + for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink; + ListEntry != &LoaderBlock->MemoryDescriptorListHead; + ListEntry = ListEntry->Flink) + { + /* Get the descriptor */ + Descriptor = CONTAINING_RECORD(ListEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* Skip invisible memory */ + if (MiIsMemoryTypeInvisible(Descriptor->MemoryType)) continue; + + /* If this is the free descriptor, use the copy instead */ + if (Descriptor == MxFreeDescriptor) Descriptor = &MxOldFreeDescriptor; + + /* Get the range for this descriptor */ + BasePage = Descriptor->BasePage; + PageCount = Descriptor->PageCount; + + /* Map the pages for the database */ + MiMapPTEs(&MmPfnDatabase[BasePage], + (PUCHAR)(&MmPfnDatabase[BasePage + PageCount]) - 1); + + /* If this was the free descriptor, skip the next step */ + if (Descriptor == &MxOldFreeDescriptor) continue; + + /* Add this descriptor to the database */ + MiAddDescriptorToDatabase(BasePage, PageCount, Descriptor->MemoryType); + } + + /* At this point the whole pfn database is mapped. We are about to add the + pages from the free descriptor to the database, so from now on we cannot + use it anymore. */ + + /* Now add the free descriptor */ + BasePage = MxFreeDescriptor->BasePage; + PageCount = MxFreeDescriptor->PageCount; + MiAddDescriptorToDatabase(BasePage, PageCount, LoaderFree); + + /* And finally the memory we used */ + BasePage = MxOldFreeDescriptor.BasePage; + PageCount = MxFreeDescriptor->BasePage - BasePage; + MiAddDescriptorToDatabase(BasePage, PageCount, LoaderMemoryData); + + // Reset the descriptor back so we can create the correct memory blocks + *MxFreeDescriptor = MxOldFreeDescriptor; +} + NTSTATUS NTAPI INIT_FUNCTION MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - + KIRQL OldIrql; + + ASSERT(MxPfnAllocation != 0); + + /* Set some hardcoded addresses */ MmHyperSpaceEnd = (PVOID)HYPER_SPACE_END; + MmNonPagedSystemStart = (PVOID)MM_SYSTEM_SPACE_START; + MmPfnDatabase = (PVOID)MI_PFN_DATABASE; + MmWorkingSetList = (PVOID)MI_WORKING_SET_LIST; + + +// PrototypePte.u.Proto.Valid = 1 +// PrototypePte.u.ReadOnly +// PrototypePte.u.Prototype +// PrototypePte.u.Protection = MM_READWRITE; +// PrototypePte.u.ProtoAddress + PrototypePte.u.Soft.PageFileHigh = MI_PTE_LOOKUP_NEEDED; + MiInitializePageTable(); @@ -403,5 +686,33 @@ MiBuildSystemPteSpace(); + /* Need to be at DISPATCH_LEVEL for MiInsertPageInFreeList */ + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + + /* Map the PFN database pages */ + MiBuildPfnDatabase(LoaderBlock); + + /* Now process the page tables */ + MiBuildPfnDatabaseFromPageTables(); + + MiPfnsInitialized = TRUE; + + KeLowerIrql(OldIrql); + + /* Initialize the balancer */ + MmInitializeBalancer((ULONG)MmAvailablePages, 0); + + /* Make sure we have everything we need */ + ASSERT(MmPfnDatabase); + ASSERT(MmNonPagedSystemStart); + ASSERT(MmNonPagedPoolStart); + ASSERT(MmSizeOfNonPagedPoolInBytes); + ASSERT(MmMaximumNonPagedPoolInBytes); + ASSERT(MmNonPagedPoolExpansionStart); + ASSERT(MmHyperSpaceEnd); + ASSERT(MmNumberOfSystemPtes); + ASSERT(MiAddressToPde(MmNonPagedPoolStart)->u.Hard.Valid); + ASSERT(MiAddressToPte(MmNonPagedPoolStart)->u.Hard.Valid); + return STATUS_SUCCESS; }
12 years, 10 months
1
0
0
0
[rharabien] 55402: [BOOTDATA] - Don't create paging files on livecd. Verified by Alex Ionescu.
by rharabien@svn.reactos.org
Author: rharabien Date: Fri Feb 3 23:43:42 2012 New Revision: 55402 URL:
http://svn.reactos.org/svn/reactos?rev=55402&view=rev
Log: [BOOTDATA] - Don't create paging files on livecd. Verified by Alex Ionescu. Modified: trunk/reactos/boot/bootdata/livecd.inf Modified: trunk/reactos/boot/bootdata/livecd.inf URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/livecd.inf?r…
============================================================================== --- trunk/reactos/boot/bootdata/livecd.inf [iso-8859-1] (original) +++ trunk/reactos/boot/bootdata/livecd.inf [iso-8859-1] Fri Feb 3 23:43:42 2012 @@ -37,6 +37,7 @@ ; User Profile environment variables HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","USERPROFILE",0x00020000,"%SystemDrive%\Profiles\Default User" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","ALLUSERSPROFILE",0x00020000,"%SystemDrive%\Profiles\All Users" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","PagingFiles",0x00000000,"" ; Font Substitution HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Arial",0x00000000,"Liberation Sans"
12 years, 10 months
1
0
0
0
[cgutman] 55401: [HIVESYS] - Add HID devices to the critical device database - Fixes issues with mouse/keyboard not working until new device wizards are dismissed (USB drives work too) [UMPNPMGR] -...
by cgutman@svn.reactos.org
Author: cgutman Date: Fri Feb 3 23:34:21 2012 New Revision: 55401 URL:
http://svn.reactos.org/svn/reactos?rev=55401&view=rev
Log: [HIVESYS] - Add HID devices to the critical device database - Fixes issues with mouse/keyboard not working until new device wizards are dismissed (USB drives work too) [UMPNPMGR] - Fix install failure after the kernel detects a critical device [NTOSKRNL] - Finally enable the proper IopResetDevice code - Driver updating without a reboot for running devices is supported now (if someone will write the GUI) [USBEHCI][USBOHCI] - Fix removal bugs Modified: branches/usb-bringup-trunk/base/services/umpnpmgr/umpnpmgr.c branches/usb-bringup-trunk/boot/bootdata/hivesys_i386.inf branches/usb-bringup-trunk/drivers/usb/usbehci_new/hcd_controller.cpp branches/usb-bringup-trunk/drivers/usb/usbohci/hcd_controller.cpp branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/plugplay.c Modified: branches/usb-bringup-trunk/base/services/umpnpmgr/umpnpmgr.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/base/services…
============================================================================== --- branches/usb-bringup-trunk/base/services/umpnpmgr/umpnpmgr.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/base/services/umpnpmgr/umpnpmgr.c [iso-8859-1] Fri Feb 3 23:34:21 2012 @@ -2811,7 +2811,7 @@ &DeviceKey) == ERROR_SUCCESS) { if (RegQueryValueExW(DeviceKey, - L"ClassGUID", + L"Class", NULL, NULL, NULL, Modified: branches/usb-bringup-trunk/boot/bootdata/hivesys_i386.inf URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/boot/bootdata…
============================================================================== --- branches/usb-bringup-trunk/boot/bootdata/hivesys_i386.inf [iso-8859-1] (original) +++ branches/usb-bringup-trunk/boot/bootdata/hivesys_i386.inf [iso-8859-1] Fri Feb 3 23:34:21 2012 @@ -11,6 +11,7 @@ ; Critical Device Database HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\acpipic_up","ClassGUID",0x00000000,"{4D36E966-E325-11CE-BFC1-08002BE10318}" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\e_isa_up","ClassGUID",0x00000000,"{4D36E966-E325-11CE-BFC1-08002BE10318}" HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\*PNP0A03","Service",0x00000000,"pci" HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\*PNP0A03","ClassGUID",0x00000000,"{4D36E97D-E325-11CE-BFC1-08002BE10318}" @@ -44,6 +45,19 @@ HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\GenDisk","Service",0x00000000,"disk" HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\GenDisk","ClassGUID",0x00000000,"{4D36E967-E325-11CE-BFC1-08002BE10318}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#Class_03","Service",0x00000000,"hidusb" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\USB#Class_03","ClassGUID",0x00000000,"{745a17a0-74d3-11d0-b6fe-00a0c90f57da}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\GENERIC_HID_DEVICE","Service",0x00000000,"hidusb" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\GENERIC_HID_DEVICE","ClassGUID",0x00000000,"{745a17a0-74d3-11d0-b6fe-00a0c90f57da}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\HID_DEVICE_SYSTEM_KEYBOARD","Service",0x00000000,"kbdhid" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\HID_DEVICE_SYSTEM_KEYBOARD","ClassGUID",0x00000000,"{4D36E96B-E325-11CE-BFC1-08002BE10318}" + +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\HID_DEVICE_SYSTEM_MOUSE","Service",0x00000000,"mouhid" +HKLM,"SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\HID_DEVICE_SYSTEM_MOUSE","ClassGUID",0x00000000,"{4D36E96F-E325-11CE-BFC1-08002BE10318}" + HKLM,"SYSTEM\CurrentControlSet\Control\SafeBoot","AlternateShell",2,"cmd.exe" @@ -1451,26 +1465,44 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Start",0x00010001,0x00000004 HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Type",0x00010001,0x00000001 +; USB HID driver +HKLM,"SYSTEM\CurrentControlSet\Services\hidusb","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\hidusb","Group",0x00000000,"Extended Base" +HKLM,"SYSTEM\CurrentControlSet\Services\hidusb","ImagePath",0x00020000,"system32\drivers\hidusb.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\hidusb","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\hidusb","Type",0x00010001,0x00000001 + +; HID keyboard driver +HKLM,"SYSTEM\CurrentControlSet\Services\kbdhid","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\kbdhid","Group",0x00000000,"Keyboard Port" +HKLM,"SYSTEM\CurrentControlSet\Services\kbdhid","ImagePath",0x00020000,"system32\drivers\kbdhid.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\kbdhid","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\kbdhid","Type",0x00010001,0x00000001 + +; HID mouse driver +HKLM,"SYSTEM\CurrentControlSet\Services\mouhid","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\mouhid","Group",0x00000000,"Pointer Port" +HKLM,"SYSTEM\CurrentControlSet\Services\mouhid","ImagePath",0x00020000,"system32\drivers\mouhid.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\mouhid","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\mouhid","Type",0x00010001,0x00000001 + ; USB hub driver HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","Group",0x00000000,"Boot Bus Extender" -HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","Tag",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","ImagePath",0x00020000,"system32\drivers\usbhub.sys" HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","Start",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","Type",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\usbhub","Type",0x00010001,0x00000001 ; EHCI controller driver HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","Group",0x00000000,"Boot Bus Extender" -HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","Tag",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","ImagePath",0x00020000,"system32\drivers\usbehci.sys" HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","Start",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","Type",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\usbehci","Type",0x00010001,0x00000001 ; OHCI controller driver HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","Group",0x00000000,"Boot Bus Extender" -HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","Tag",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","ImagePath",0x00020000,"system32\drivers\usbohci.sys" HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\usbohci","Type",0x00010001,0x00000001 @@ -1478,7 +1510,6 @@ ; UHCI controller driver ;HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","ErrorControl",0x00010001,0x00000001 ;HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","Group",0x00000000,"Boot Bus Extender" -;HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","Tag",0x00010001,0x00000002 ;HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","ImagePath",0x00020000,"system32\drivers\usbuhci.sys" ;HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","Start",0x00010001,0x00000000 ;HKLM,"SYSTEM\CurrentControlSet\Services\usbuhci","Type",0x00010001,0x00000001 @@ -1486,7 +1517,6 @@ ; USB storage driver HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","Group",0x00000000,"Primary Disk" -HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","Tag",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","ImagePath",0x00020000,"system32\drivers\usbstor.sys" HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\usbstor","Type",0x00010001,0x00000001 @@ -1494,7 +1524,6 @@ ; USB composite generic parent HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","Group",0x00000000,"Boot Bus Extender" -HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","Tag",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","ImagePath",0x00020000,"system32\drivers\usbccgp.sys" HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\usbccgp","Type",0x00010001,0x00000001 @@ -1502,7 +1531,6 @@ ; ACPI driver HKLM,"SYSTEM\CurrentControlSet\Services\acpi","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\acpi","Group",0x00000000,"Boot Bus Extender" -HKLM,"SYSTEM\CurrentControlSet\Services\acpi","Tag",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\acpi","ImagePath",0x00020000,"system32\drivers\acpi.sys" HKLM,"SYSTEM\CurrentControlSet\Services\acpi","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\acpi","Type",0x00010001,0x00000001 @@ -1510,7 +1538,6 @@ ; PCI Bus driver HKLM,"SYSTEM\CurrentControlSet\Services\Pci","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Group",0x00000000,"Boot Bus Extender" -HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Tag",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\Pci","ImagePath",0x00020000,"system32\drivers\pci.sys" HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Type",0x00010001,0x00000001 Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/hcd_controller.cpp URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbehci_new/hcd_controller.cpp [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/hcd_controller.cpp [iso-8859-1] Fri Feb 3 23:34:21 2012 @@ -534,11 +534,36 @@ } break; } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + { + // + // sure + // + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(m_NextDeviceObject, Irp); + } case IRP_MN_REMOVE_DEVICE: { DPRINT1("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n"); // + // delete the symbolic link + // + SetSymbolicLink(FALSE); + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + IoCallDriver(m_NextDeviceObject, Irp); + + // // detach device from device stack // IoDetachDevice(m_NextDeviceObject); @@ -548,8 +573,7 @@ // IoDeleteDevice(m_FunctionalDeviceObject); - Status = STATUS_SUCCESS; - break; + return STATUS_SUCCESS; } default: { Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/hcd_controller.cpp URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbohci/hcd_controller.cpp [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbohci/hcd_controller.cpp [iso-8859-1] Fri Feb 3 23:34:21 2012 @@ -534,11 +534,36 @@ } break; } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + { + // + // sure + // + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(m_NextDeviceObject, Irp); + } case IRP_MN_REMOVE_DEVICE: { DPRINT1("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n"); // + // delete the symbolic link + // + SetSymbolicLink(FALSE); + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + IoCallDriver(m_NextDeviceObject, Irp); + + // // detach device from device stack // IoDetachDevice(m_NextDeviceObject); @@ -548,8 +573,7 @@ // IoDeleteDevice(m_FunctionalDeviceObject); - Status = STATUS_SUCCESS; - break; + return STATUS_SUCCESS; } default: { Modified: branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/plugplay.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/ntoskrnl/io/p…
============================================================================== --- branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] Fri Feb 3 23:34:21 2012 @@ -549,26 +549,42 @@ if (DeviceObject == NULL) return STATUS_NO_SUCH_DEVICE; + /* Get the device node */ DeviceNode = IopGetDeviceNode(DeviceObject); -#if 0 - /* Remove the device */ - if (DeviceNode->Flags & DNF_ENUMERATED) - { + /* Check if an FDO has been added to the stack */ + if (DeviceNode->Flags & DNF_ADDED) + { + /* Remove the device node */ Status = IopRemoveDevice(DeviceNode); if (!NT_SUCCESS(Status)) { DPRINT1("WARNING: Ignoring failed IopRemoveDevice() for %wZ (likely a driver bug)\n", &DeviceNode->InstancePath); } - } -#endif - - /* Reenumerate the device and its children */ - DeviceNode->Flags &= ~DNF_DISABLED; - Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent); - - if (NT_SUCCESS(Status)) - Status = IopActionInitChildServices(DeviceNode, DeviceNode->Parent); + + /* Invalidate device relations for the parent to reenumerate the device */ + Status = IoSynchronousInvalidateDeviceRelations(DeviceNode->Parent->PhysicalDeviceObject, BusRelations); + + DPRINT1("Reset PDO with FDO present: 0x%x\n", Status); + } + else + { + /* FIXME: We might clear some important flags */ + ASSERT(DeviceNode->Flags & DNF_ENUMERATED); + ASSERT(DeviceNode->Flags & DNF_PROCESSED); + DeviceNode->Flags = DNF_ENUMERATED | DNF_PROCESSED; + + /* Load service data from the registry */ + Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent); + + if (NT_SUCCESS(Status)) + { + /* Start the service and begin PnP initialization of the device again */ + Status = IopActionInitChildServices(DeviceNode, DeviceNode->Parent); + } + + DPRINT1("Reset PDO with no FDO present: 0x%x\n", Status); + } ObDereferenceObject(DeviceObject);
12 years, 10 months
1
0
0
0
[ion] 55400: [SMSS2]: Implement the rest of the code to create page files. All that's missing is the actual call to NtCreatePagingFile.
by ion@svn.reactos.org
Author: ion Date: Fri Feb 3 23:11:28 2012 New Revision: 55400 URL:
http://svn.reactos.org/svn/reactos?rev=55400&view=rev
Log: [SMSS2]: Implement the rest of the code to create page files. All that's missing is the actual call to NtCreatePagingFile. Modified: trunk/reactos/base/system/smss2/crashdmp.c trunk/reactos/base/system/smss2/pagefile.c trunk/reactos/base/system/smss2/smss.h Modified: trunk/reactos/base/system/smss2/crashdmp.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/crashdmp…
============================================================================== --- trunk/reactos/base/system/smss2/crashdmp.c [iso-8859-1] (original) +++ trunk/reactos/base/system/smss2/crashdmp.c [iso-8859-1] Fri Feb 3 23:11:28 2012 @@ -15,3 +15,12 @@ /* GLOBALS ********************************************************************/ /* FUNCTIONS ******************************************************************/ + +BOOLEAN +NTAPI +SmpCheckForCrashDump(IN PUNICODE_STRING FileName) +{ + return FALSE; +} + + Modified: trunk/reactos/base/system/smss2/pagefile.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/pagefile…
============================================================================== --- trunk/reactos/base/system/smss2/pagefile.c [iso-8859-1] (original) +++ trunk/reactos/base/system/smss2/pagefile.c [iso-8859-1] Fri Feb 3 23:11:28 2012 @@ -46,11 +46,13 @@ // Structure and flags describing each volume // #define SMP_VOLUME_INSERTED 0x01 +#define SMP_VOLUME_PAGEFILE_CREATED 0x04 #define SMP_VOLUME_IS_BOOT 0x08 typedef struct _SMP_VOLUME_DESCRIPTOR { LIST_ENTRY Entry; - ULONG Flags; + USHORT Flags; + USHORT PageFileCount; WCHAR DriveLetter; LARGE_INTEGER FreeSpace; FILE_FS_DEVICE_INFORMATION DeviceInfo; @@ -230,13 +232,369 @@ NTSTATUS NTAPI +SmpGetPagingFileSize(IN PUNICODE_STRING FileName, + OUT PLARGE_INTEGER Size) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + FILE_STANDARD_INFORMATION StandardInfo; + + DPRINT1("SMSS:PFILE: Trying to get size for `%wZ'\n", FileName); + Size->QuadPart = 0; + + InitializeObjectAttributes(&ObjectAttributes, + FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&FileHandle, + FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) return Status; + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &StandardInfo, + sizeof(StandardInfo), + FileStandardInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SMSS:PFILE: Failed query for size potential pagefile `%wZ' with status %X \n", + FileName, Status); + NtClose(FileHandle); + return Status; + } + + NtClose(FileHandle); + Size->LowPart = StandardInfo.AllocationSize.LowPart; + Size->HighPart = StandardInfo.AllocationSize.HighPart; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +SmpDeletePagingFile(IN PUNICODE_STRING FileName) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + FILE_DISPOSITION_INFORMATION Disposition; + + /* Open the page file */ + InitializeObjectAttributes(&ObjectAttributes, + FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&FileHandle, + DELETE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_NON_DIRECTORY_FILE); + if (NT_SUCCESS(Status)) + { + /* Delete it */ + Disposition.DeleteFile = TRUE; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &Disposition, + sizeof(Disposition), + FileDispositionInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SMSS:PFILE: Failed to delete page file `%wZ' (status %X)\n", + FileName, Status); + } + else + { + DPRINT1("SMSS:PFILE: Deleted stale paging file - %wZ\n", FileName); + } + + /* Close the handle */ + NtClose(FileHandle); + } + else + { + DPRINT1("SMSS:PFILE: Failed to open for deletion page file `%wZ' (status %X)\n", + FileName, Status); + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +SmpGetVolumeFreeSpace(IN PSMP_VOLUME_DESCRIPTOR Volume) +{ + NTSTATUS Status; + LARGE_INTEGER FreeSpace, FinalFreeSpace; + FILE_FS_SIZE_INFORMATION SizeInfo; + IO_STATUS_BLOCK IoStatusBlock; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING VolumeName; + HANDLE VolumeHandle; + WCHAR PathString[32]; + ASSERT(Volume->Flags & SMP_VOLUME_IS_BOOT); // ASSERT says "BootVolume == 1" + + /* Build the standard path */ + wcscpy(PathString, L"\\??\\A:\\"); + VolumeName.Buffer = PathString; + VolumeName.Length = wcslen(PathString) * sizeof(WCHAR); + VolumeName.MaximumLength = VolumeName.Length + sizeof(UNICODE_NULL); + VolumeName.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = Volume->DriveLetter; + DPRINT1("SMSS:PFILE: Querying volume `%wZ' for free space \n", &VolumeName); + + /* Open the volume */ + InitializeObjectAttributes(&ObjectAttributes, + &VolumeName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&VolumeHandle, + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SMSS:PFILE: Open volume `%wZ' failed with status %X \n", &VolumeName, Status); + return Status; + } + + /* Now get size information on the volume */ + Status = NtQueryVolumeInformationFile(VolumeHandle, + &IoStatusBlock, + &SizeInfo, + sizeof(SizeInfo), + FileFsSizeInformation); + if (!NT_SUCCESS(Status)) + { + /* We failed -- keep going */ + DPRINT1("SMSS:PFILE: Query volume `%wZ' (handle %p) for size failed" + " with status %X \n", + &VolumeName, + VolumeHandle, + Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, Volume); + NtClose(VolumeHandle); + return Status; + } + NtClose(VolumeHandle); + + /* Compute how much free space we have */ + FreeSpace.QuadPart = SizeInfo.AvailableAllocationUnits.QuadPart * + SizeInfo.SectorsPerAllocationUnit; + FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector; + Volume->FreeSpace = FinalFreeSpace; + + /* Check if there's less than 32MB free so we don't starve the disk */ + if (FinalFreeSpace.QuadPart <= 0x2000000) + { + /* In this case, act as if there's no free space */ + Volume->FreeSpace.QuadPart = 0; + } + else + { + /* Trim off 32MB to give the disk a bit of breathing room */ + Volume->FreeSpace.QuadPart = FinalFreeSpace.QuadPart - 0x2000000; + } + + return STATUS_SUCCESS; +} + +PSMP_VOLUME_DESCRIPTOR +NTAPI +SmpSearchVolumeDescriptor(IN WCHAR DriveLetter) +{ + WCHAR UpLetter; + PSMP_VOLUME_DESCRIPTOR Volume = NULL; + PLIST_ENTRY NextEntry; + + /* Use upper case to reduce differences */ + UpLetter = RtlUpcaseUnicodeChar(DriveLetter); + + /* Loop each volume */ + NextEntry = SmpVolumeDescriptorList.Flink; + while (NextEntry != &SmpVolumeDescriptorList) + { + /* Grab the entry */ + Volume = CONTAINING_RECORD(NextEntry, SMP_VOLUME_DESCRIPTOR, Entry); + + /* Make sure it's a valid entry with an uppcase drive letter */ + ASSERT(Volume->Flags & SMP_VOLUME_INSERTED); // Volume->Initialized in ASSERT + ASSERT(Volume->DriveLetter >= L'A' && Volume->DriveLetter <= L'Z'); + + /* Break if it matches, if not, keep going */ + if (Volume->DriveLetter == UpLetter) break; + NextEntry = NextEntry->Flink; + } + + /* Return the volume if one was found */ + if (NextEntry == &SmpVolumeDescriptorList) Volume = NULL; + return Volume; +} + +NTSTATUS +NTAPI +SmpCreatePagingFile(IN PUNICODE_STRING Name, + IN PLARGE_INTEGER MinSize, + IN PLARGE_INTEGER MaxSize, + IN ULONG Priority) +{ + NTSTATUS Status; + DPRINT1("Should request pagefile: %wZ with size %I64x and %I64x\n", Name, MinSize->QuadPart, MaxSize->QuadPart); + + /* Tell the kernel to create the pagefile */ + Status = STATUS_SUCCESS; + //Status = NtCreatePagingFile(Name, MinSize, MaxSize, Priority); + if (NT_SUCCESS(Status)) + { + DPRINT1("SMSS:PFILE: NtCreatePagingFile (%wZ, %I64X, %I64X) succeeded. \n", + Name, + MinSize->QuadPart, + MaxSize->QuadPart); + } + else + { + DPRINT1("SMSS:PFILE: NtCreatePagingFile (%wZ, %I64X, %I64X) failed with %X \n", + Name, + MinSize->QuadPart, + MaxSize->QuadPart, + Status); + } + + /* Return the status */ + return Status; +} + +NTSTATUS +NTAPI SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize) { - DPRINT1("Should create fixed pagefile of sizes: %I64d %I64d\n", - FuzzFactor->QuadPart, MinimumSize->QuadPart); - return STATUS_SUCCESS; + PSMP_VOLUME_DESCRIPTOR Volume; + BOOLEAN ShouldDelete; + NTSTATUS Status; + LARGE_INTEGER PageFileSize; + ASSERT(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] != L'?'); + + /* Try to find the volume descriptor for this drive letter */ + ShouldDelete = FALSE; + Volume = SmpSearchVolumeDescriptor(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET]); + if (!Volume) + { + /* Couldn't find it, fail */ + DPRINT1("SMSS:PFILE: No volume descriptor for `%wZ' \n", + &Descriptor->Name); + return STATUS_INVALID_PARAMETER; + } + + /* Check if this is the boot volume */ + if (Volume->Flags & SMP_VOLUME_IS_BOOT) + { + /* Check if we haven't yet processed a crash dump on this volume */ + if (!(Descriptor->Flags & SMP_PAGEFILE_DUMP_PROCESSED)) + { + /* Try to find a crash dump and extract it */ + DPRINT1("SMSS:PFILE: Checking for crash dump in `%wZ' on boot volume \n", + &Descriptor->Name); + SmpCheckForCrashDump(&Descriptor->Name); + + /* Update how much free space we have now that we extracted a dump */ + Status = SmpGetVolumeFreeSpace(Volume); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SMSS:PFILE: Failed to query free space for boot volume `%wC'\n", + Volume->DriveLetter); + } + + /* Don't process crashdump on this volume anymore */ + Descriptor->Flags |= SMP_PAGEFILE_DUMP_PROCESSED; + } + } + else + { + /* Crashdumps can only be on the boot volume */ + DPRINT1("SMSS:PFILE: Skipping crash dump checking for `%wZ' on non boot" + "volume `%wC' \n", + &Descriptor->Name, + Volume->DriveLetter); + } + + /* Update the size after dump extraction */ + Descriptor->ActualMinSize = Descriptor->MinSize; + Descriptor->ActualMaxSize = Descriptor->MaxSize; + + /* Check how big we can make the pagefile */ + Status = SmpGetPagingFileSize(&Descriptor->Name, &PageFileSize); + if (PageFileSize.QuadPart > 0) ShouldDelete = TRUE; + DPRINT1("SMSS:PFILE: Detected size %I64X for future paging file `%wZ'\n", + PageFileSize, + &Descriptor->Name); + DPRINT1("SMSS:PFILE: Free space on volume `%wC' is %I64X \n", + Volume->DriveLetter, + Volume->FreeSpace.QuadPart); + + /* Now update our size and make sure none of these are too big */ + PageFileSize.QuadPart += Volume->FreeSpace.QuadPart; + if (Descriptor->ActualMinSize.QuadPart > PageFileSize.QuadPart) + { + Descriptor->ActualMinSize = PageFileSize; + } + if (Descriptor->ActualMaxSize.QuadPart > PageFileSize.QuadPart) + { + Descriptor->ActualMaxSize = PageFileSize; + } + DPRINT1("SMSS:PFILE: min %I64X, max %I64X, real min %I64X \n", + Descriptor->ActualMinSize.QuadPart, + Descriptor->ActualMaxSize.QuadPart, + MinimumSize->QuadPart); + + /* Keep going until we've created a pagefile of the right size */ + while (Descriptor->ActualMinSize.QuadPart >= MinimumSize->QuadPart) + { + /* Call NT to do it */ + Status = SmpCreatePagingFile(&Descriptor->Name, + &Descriptor->ActualMinSize, + &Descriptor->ActualMaxSize, + 0); + if (NT_SUCCESS(Status)) + { + /* We're done, update flags and increase the count */ + Descriptor->Flags |= SMP_PAGEFILE_CREATED; + Volume->Flags |= SMP_VOLUME_PAGEFILE_CREATED; + Volume->PageFileCount++; + break; + } + + /* We failed, try a slighly smaller pagefile */ + Descriptor->ActualMinSize.QuadPart -= FuzzFactor->QuadPart; + } + + /* Check if we weren't able to create it */ + if (Descriptor->ActualMinSize.QuadPart < MinimumSize->QuadPart) + { + /* Delete the current page file and fail */ + if (ShouldDelete) SmpDeletePagingFile(&Descriptor->Name); + DPRINT1("SMSS:PFILE: Failing for min %I64X, max %I64X, real min %I64X \n", + Descriptor->ActualMinSize.QuadPart, + Descriptor->ActualMaxSize.QuadPart, + MinimumSize->QuadPart); + Status = STATUS_DISK_FULL; + } + + /* Return the status */ + return Status; } NTSTATUS @@ -245,9 +603,36 @@ IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize) { - DPRINT1("Should create 'any' pagefile of sizes: %I64d %I64d\n", - FuzzFactor->QuadPart, MinimumSize->QuadPart); - return STATUS_SUCCESS; + PSMP_VOLUME_DESCRIPTOR Volume; + NTSTATUS Status = STATUS_DISK_FULL; + PLIST_ENTRY NextEntry; + ASSERT(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == L'?'); + + /* Loop the volume list */ + NextEntry = SmpVolumeDescriptorList.Flink; + while (NextEntry != &SmpVolumeDescriptorList) + { + /* Get the volume */ + Volume = CONTAINING_RECORD(NextEntry, SMP_VOLUME_DESCRIPTOR, Entry); + + /* Make sure it's inserted and on a valid drive letter */ + ASSERT(Volume->Flags & SMP_VOLUME_INSERTED); // Volume->Initialized in ASSERT + ASSERT(Volume->DriveLetter >= L'A' && Volume->DriveLetter <= L'Z'); + + /* Write the drive letter to try creating it on this volume */ + Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = Volume->DriveLetter; + Status = SmpCreatePagingFileOnFixedDrive(Descriptor, + FuzzFactor, + MinimumSize); + if (NT_SUCCESS(Status)) break; + + /* It didn't work, make it an any pagefile again and keep going */ + Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = L'?'; + NextEntry = NextEntry->Flink; + } + + /* Return disk full or success */ + return Status; } VOID Modified: trunk/reactos/base/system/smss2/smss.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smss.h?r…
============================================================================== --- trunk/reactos/base/system/smss2/smss.h [iso-8859-1] (original) +++ trunk/reactos/base/system/smss2/smss.h [iso-8859-1] Fri Feb 3 23:11:28 2012 @@ -181,4 +181,10 @@ IN BOOLEAN ShutdownOkay ); +BOOLEAN +NTAPI +SmpCheckForCrashDump( + IN PUNICODE_STRING FileName +); +
12 years, 10 months
1
0
0
0
[cgutman] 55399: [PCI][HIDCLASS][HIDUSB][KBDHID][MOUHID][USBCCGP][USBOHCI][USBEHCI][USBHUB][USBSTOR] - Handle query remove IRPs - Fix some other removal bugs
by cgutman@svn.reactos.org
Author: cgutman Date: Fri Feb 3 22:59:53 2012 New Revision: 55399 URL:
http://svn.reactos.org/svn/reactos?rev=55399&view=rev
Log: [PCI][HIDCLASS][HIDUSB][KBDHID][MOUHID][USBCCGP][USBOHCI][USBEHCI][USBHUB][USBSTOR] - Handle query remove IRPs - Fix some other removal bugs Modified: branches/usb-bringup-trunk/drivers/bus/pci/fdo.c branches/usb-bringup-trunk/drivers/bus/pci/pdo.c branches/usb-bringup-trunk/drivers/hid/hidclass/fdo.c branches/usb-bringup-trunk/drivers/hid/hidusb/hidusb.c branches/usb-bringup-trunk/drivers/hid/kbdhid/kbdhid.c branches/usb-bringup-trunk/drivers/hid/mouhid/mouhid.c branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c branches/usb-bringup-trunk/drivers/usb/usbehci_new/hub_controller.cpp branches/usb-bringup-trunk/drivers/usb/usbhub_new/fdo.c branches/usb-bringup-trunk/drivers/usb/usbhub_new/pdo.c branches/usb-bringup-trunk/drivers/usb/usbohci/hub_controller.cpp branches/usb-bringup-trunk/drivers/usb/usbstor/fdo.c branches/usb-bringup-trunk/drivers/usb/usbstor/pdo.c Modified: branches/usb-bringup-trunk/drivers/bus/pci/fdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/bus/p…
============================================================================== --- branches/usb-bringup-trunk/drivers/bus/pci/fdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/bus/pci/fdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -96,7 +96,6 @@ { PFDO_DEVICE_EXTENSION DeviceExtension; PCI_COMMON_CONFIG PciConfig; - PLIST_ENTRY CurrentEntry; PPCI_DEVICE Device; PCI_SLOT_NUMBER SlotNumber; ULONG DeviceNumber; @@ -107,15 +106,6 @@ DPRINT("Called\n"); DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - /* Mark all devices to be removed. If we don't discover them again during - enumeration, assume that they have been surprise removed */ - CurrentEntry = DeviceExtension->DeviceListHead.Flink; - while (CurrentEntry != &DeviceExtension->DeviceListHead) { - Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry); - Device->RemovePending = TRUE; - CurrentEntry = CurrentEntry->Flink; - } DeviceExtension->DeviceListCount = 0; @@ -189,9 +179,6 @@ &Device->ListEntry, &DeviceExtension->DeviceListLock); } - - /* Don't remove this device */ - Device->RemovePending = FALSE; DeviceExtension->DeviceListCount++; Modified: branches/usb-bringup-trunk/drivers/bus/pci/pdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/bus/p…
============================================================================== --- branches/usb-bringup-trunk/drivers/bus/pci/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/bus/pci/pdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -1443,10 +1443,33 @@ case IRP_MN_STOP_DEVICE: case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: - case IRP_MN_REMOVE_DEVICE: case IRP_MN_SURPRISE_REMOVAL: Status = STATUS_SUCCESS; break; + + case IRP_MN_REMOVE_DEVICE: + { + PPDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + PFDO_DEVICE_EXTENSION FdoDeviceExtension = DeviceExtension->Fdo->DeviceExtension; + KIRQL OldIrql; + + /* Remove it from the device list */ + KeAcquireSpinLock(&FdoDeviceExtension->DeviceListLock, &OldIrql); + RemoveEntryList(&DeviceExtension->PciDevice->ListEntry); + FdoDeviceExtension->DeviceListCount--; + KeReleaseSpinLock(&FdoDeviceExtension->DeviceListLock, OldIrql); + + /* Free the device */ + ExFreePool(DeviceExtension->PciDevice); + + /* Complete the IRP */ + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + /* Delete the DO */ + IoDeleteDevice(DeviceObject); + return STATUS_SUCCESS; + } case IRP_MN_QUERY_INTERFACE: DPRINT("IRP_MN_QUERY_INTERFACE received\n"); Modified: branches/usb-bringup-trunk/drivers/hid/hidclass/fdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/hid/h…
============================================================================== --- branches/usb-bringup-trunk/drivers/hid/hidclass/fdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/hid/hidclass/fdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -554,6 +554,7 @@ { return HidClassFDO_RemoveDevice(DeviceObject, Irp); } + case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: { // @@ -567,6 +568,7 @@ IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); } + case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: { // Modified: branches/usb-bringup-trunk/drivers/hid/hidusb/hidusb.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/hid/h…
============================================================================== --- branches/usb-bringup-trunk/drivers/hid/hidusb/hidusb.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/hid/hidusb/hidusb.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -1561,19 +1561,41 @@ } // + // delete and detach device + // + IoDetachDevice(DeviceExtension->NextDeviceObject); + IoDeleteDevice(DeviceObject); + + return Status; + } + case IRP_MN_QUERY_PNP_DEVICE_STATE: + { + // + // device can not be disabled + // + Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; + + // + // pass request to next request + // + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); + + // // done // return Status; } - case IRP_MN_QUERY_PNP_DEVICE_STATE: - { - // - // device can not be disabled - // - Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; - - // - // pass request to next request + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + { + // + // we're fine with it + // + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // pass request to next driver // IoSkipCurrentIrpStackLocation(Irp); Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); Modified: branches/usb-bringup-trunk/drivers/hid/kbdhid/kbdhid.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/hid/k…
============================================================================== --- branches/usb-bringup-trunk/drivers/hid/kbdhid/kbdhid.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/hid/kbdhid/kbdhid.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -737,7 +737,11 @@ IoStack = IoGetCurrentIrpStackLocation(Irp); DPRINT1("[KBDHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction); - if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) + if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || + IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || + IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || + IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE || + IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) { /* indicate success */ Irp->IoStatus.Status = STATUS_SUCCESS; Modified: branches/usb-bringup-trunk/drivers/hid/mouhid/mouhid.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/hid/m…
============================================================================== --- branches/usb-bringup-trunk/drivers/hid/mouhid/mouhid.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/hid/mouhid/mouhid.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -788,7 +788,11 @@ IoStack = IoGetCurrentIrpStackLocation(Irp); DPRINT1("[MOUHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction); - if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) + if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || + IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || + IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || + IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE || + IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) { /* indicate success */ Irp->IoStatus.Status = STATUS_SUCCESS; Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -481,6 +481,20 @@ } break; } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + { + // + // sure + // + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); + } default: { // Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -391,6 +391,15 @@ IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + { + // + // sure + // + Status = STATUS_SUCCESS; + break; + } case IRP_MN_START_DEVICE: { // @@ -406,6 +415,7 @@ // do nothing // Status = Irp->IoStatus.Status; + break; } } Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/hub_controller.cpp URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -432,6 +432,15 @@ // register device interface // Status = SetDeviceInterface(TRUE); + break; + } + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + { + // + // sure + // + Status = STATUS_SUCCESS; break; } case IRP_MN_QUERY_ID: Modified: branches/usb-bringup-trunk/drivers/usb/usbhub_new/fdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbhub_new/fdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbhub_new/fdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -1883,6 +1883,22 @@ } break; } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + { + Irp->IoStatus.Status = STATUS_SUCCESS; + return ForwardIrpAndForget(DeviceObject, Irp); + } + case IRP_MN_REMOVE_DEVICE: + { + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + IoDetachDevice(HubDeviceExtension->LowerDeviceObject); + IoDeleteDevice(DeviceObject); + + return STATUS_SUCCESS; + } case IRP_MN_QUERY_BUS_INFORMATION: { DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n"); Modified: branches/usb-bringup-trunk/drivers/usb/usbhub_new/pdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbhub_new/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbhub_new/pdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -586,6 +586,14 @@ IoDeleteDevice(DeviceObject); return STATUS_SUCCESS; } + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + { + /* Sure, no problem */ + Status = STATUS_SUCCESS; + Information = 0; + break; + } default: { DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction); Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/hub_controller.cpp URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -435,6 +435,15 @@ // register device interface // Status = SetDeviceInterface(TRUE); + break; + } + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + { + // + // sure + // + Status = STATUS_SUCCESS; break; } case IRP_MN_QUERY_ID: Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/fdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbstor/fdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbstor/fdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -339,9 +339,11 @@ break; } case IRP_MN_STOP_DEVICE: + { DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n"); Status = STATUS_NOT_SUPPORTED; break; + } case IRP_MN_REMOVE_DEVICE: { DPRINT1("IRP_MN_REMOVE_DEVICE\n"); @@ -356,6 +358,29 @@ IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); } + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + { + // + // we can if nothing is pending + // + if (DeviceExtension->IrpPendingCount != 0 || + DeviceExtension->ActiveSrb != NULL) + { + /* We have pending requests */ + DPRINT1("Failing removal/stop request due to pending requests present\n"); + Status = STATUS_UNSUCCESSFUL; + } + else + { + /* We're all clear */ + Irp->IoStatus.Status = STATUS_SUCCESS; + + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); + } + break; + } case IRP_MN_START_DEVICE: { Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp); Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/pdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbstor/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbstor/pdo.c [iso-8859-1] Fri Feb 3 22:59:53 2012 @@ -873,6 +873,18 @@ } break; } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + { + // + // if we're not claimed it's ok + // + if (DeviceExtension->Claimed) + Status = STATUS_UNSUCCESSFUL; + else + Status = STATUS_SUCCESS; + break; + } case IRP_MN_START_DEVICE: { //
12 years, 10 months
1
0
0
0
[tkreuzer] 55398: Fix gcc build
by tkreuzer@svn.reactos.org
Author: tkreuzer Date: Fri Feb 3 21:12:18 2012 New Revision: 55398 URL:
http://svn.reactos.org/svn/reactos?rev=55398&view=rev
Log: Fix gcc build Modified: trunk/reactos/ntoskrnl/mm/marea.c Modified: trunk/reactos/ntoskrnl/mm/marea.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/marea.c?rev=55…
============================================================================== --- trunk/reactos/ntoskrnl/mm/marea.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/marea.c [iso-8859-1] Fri Feb 3 21:12:18 2012 @@ -462,7 +462,7 @@ /* Get the margins of the address space */ if (MmGetAddressSpaceOwner(AddressSpace) != NULL) { - LowestAddress = MM_LOWEST_USER_ADDRESS; + LowestAddress = (ULONG_PTR)MM_LOWEST_USER_ADDRESS; HighestAddress = (ULONG_PTR)MmHighestUserAddress; } else
12 years, 10 months
1
0
0
0
[tkreuzer] 55397: [NTOSKRNL] - Rewrite MmFindGapBottomUp and MmFindGapTopDown, the old versions were broken and were first checking the address range after the first memory area and only used the a...
by tkreuzer@svn.reactos.org
Author: tkreuzer Date: Fri Feb 3 20:59:35 2012 New Revision: 55397 URL:
http://svn.reactos.org/svn/reactos?rev=55397&view=rev
Log: [NTOSKRNL] - Rewrite MmFindGapBottomUp and MmFindGapTopDown, the old versions were broken and were first checking the address range after the first memory area and only used the area below (above) the first memory are when nothing free was found. - Fix an ASSERT, that gets triggered now that the memory areas are created at the "right" locations - Create a memory are for the boot loaded images, which previously could be overwritten happily by new memory areas, which was only prevented by the brokenness of the code - Fix a few memory regions so that they are correct for amd64 builds as well Modified: trunk/reactos/ntoskrnl/ex/init.c trunk/reactos/ntoskrnl/include/internal/i386/mm.h trunk/reactos/ntoskrnl/mm/marea.c trunk/reactos/ntoskrnl/mm/mminit.c Modified: trunk/reactos/ntoskrnl/ex/init.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=553…
============================================================================== --- trunk/reactos/ntoskrnl/ex/init.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ex/init.c [iso-8859-1] Fri Feb 3 20:59:35 2012 @@ -331,7 +331,7 @@ } /* Copy the codepage data in its new location. */ - ASSERT(SectionBase > MmSystemRangeStart); + ASSERT(SectionBase >= MmSystemRangeStart); RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize); /* Free the previously allocated buffer and set the new location */ Modified: trunk/reactos/ntoskrnl/include/internal/i386/mm.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/i386/mm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/i386/mm.h [iso-8859-1] Fri Feb 3 20:59:35 2012 @@ -30,6 +30,7 @@ #define PDE_TOP 0xC0300FFF #define PTE_TOP 0xC03FFFFF #define HYPER_SPACE 0xC0400000 +#define HYPER_SPACE_END 0xC07FFFFF #define PTE_PER_PAGE 0x400 Modified: trunk/reactos/ntoskrnl/mm/marea.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/marea.c?rev=55…
============================================================================== --- trunk/reactos/ntoskrnl/mm/marea.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/marea.c [iso-8859-1] Fri Feb 3 20:59:35 2012 @@ -456,78 +456,68 @@ ULONG_PTR Length, ULONG_PTR Granularity) { - PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; - PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ? - MmHighestUserAddress : (PVOID)MAXULONG_PTR; - PVOID AlignedAddress; - PMEMORY_AREA Node; - PMEMORY_AREA FirstNode; - PMEMORY_AREA PreviousNode; - - DPRINT("LowestAddress: %p HighestAddress: %p\n", - LowestAddress, HighestAddress); - - AlignedAddress = MM_ROUND_UP(LowestAddress, Granularity); - - /* Special case for empty tree. */ - if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL) - { - if ((ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length) - { - DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress); - return AlignedAddress; - } - DPRINT("MmFindGapBottomUp: 0\n"); - return 0; - } - - /* Go to the node with lowest address in the tree. */ - FirstNode = Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink); - - /* Traverse the tree from left to right. */ - PreviousNode = Node; - for (;;) - { - Node = MmIterateNextNode(Node); - if (Node == NULL) - break; - - AlignedAddress = MM_ROUND_UP(PreviousNode->EndingAddress, Granularity); - if (AlignedAddress >= LowestAddress) - { - if (Node->StartingAddress > AlignedAddress && - (ULONG_PTR)Node->StartingAddress - (ULONG_PTR)AlignedAddress >= Length) - { - DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress); - ASSERT(AlignedAddress >= LowestAddress); - return AlignedAddress; - } - } - PreviousNode = Node; - } - - /* Check if there is enough space after the last memory area. */ - AlignedAddress = MM_ROUND_UP(PreviousNode->EndingAddress, Granularity); - if ((ULONG_PTR)HighestAddress > (ULONG_PTR)AlignedAddress && - (ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length) - { - DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress); - ASSERT(AlignedAddress >= LowestAddress); - return AlignedAddress; - } - - /* Check if there is enough space before the first memory area. */ - AlignedAddress = MM_ROUND_UP(LowestAddress, Granularity); - if (FirstNode->StartingAddress > AlignedAddress && - (ULONG_PTR)FirstNode->StartingAddress - (ULONG_PTR)AlignedAddress >= Length) - { - DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress); - ASSERT(AlignedAddress >= LowestAddress); - return AlignedAddress; - } - - DPRINT("MmFindGapBottomUp: 0\n"); - return 0; + ULONG_PTR LowestAddress, HighestAddress, Candidate; + PMEMORY_AREA Root, Node; + + /* Get the margins of the address space */ + if (MmGetAddressSpaceOwner(AddressSpace) != NULL) + { + LowestAddress = MM_LOWEST_USER_ADDRESS; + HighestAddress = (ULONG_PTR)MmHighestUserAddress; + } + else + { + LowestAddress = (ULONG_PTR)MmSystemRangeStart; + HighestAddress = MAXULONG_PTR; + } + + /* Start with the lowest address */ + Candidate = LowestAddress; + + /* Check for overflow */ + if ((Candidate + Length) < Candidate) return NULL; + + /* Get the root of the address space tree */ + Root = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + + /* Go to the node with lowest address in the tree. */ + Node = Root ? MmIterateFirstNode(Root) : NULL; + while (Node && ((ULONG_PTR)Node->EndingAddress < LowestAddress)) + { + Node = MmIterateNextNode(Node); + } + + /* Traverse the tree from low to high addresses */ + while (Node && ((ULONG_PTR)Node->EndingAddress < HighestAddress)) + { + /* Check if the memory area fits before the current node */ + if ((ULONG_PTR)Node->StartingAddress >= (Candidate + Length)) + { + DPRINT("MmFindGapBottomUp: %p\n", Candidate); + ASSERT(Candidate >= LowestAddress); + return (PVOID)Candidate; + } + + /* Calculate next possible adress above this node */ + Candidate = ALIGN_UP_BY((ULONG_PTR)Node->EndingAddress, Granularity); + + /* Check for overflow */ + if ((Candidate + Length) < (ULONG_PTR)Node->EndingAddress) return NULL; + + /* Go to the next higher node */ + Node = MmIterateNextNode(Node); + } + + /* Check if there is enough space after the last memory area. */ + if ((Candidate + Length) <= HighestAddress) + { + DPRINT("MmFindGapBottomUp: %p\n", Candidate); + ASSERT(Candidate >= LowestAddress); + return (PVOID)Candidate; + } + + DPRINT("MmFindGapBottomUp: 0\n"); + return NULL; } @@ -537,81 +527,68 @@ ULONG_PTR Length, ULONG_PTR Granularity) { - PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; - PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ? - (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; - PVOID AlignedAddress; - PMEMORY_AREA Node; - PMEMORY_AREA PreviousNode; - - DPRINT("LowestAddress: %p HighestAddress: %p\n", - LowestAddress, HighestAddress); - - AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)HighestAddress - Length + 1, Granularity); - - /* Check for overflow. */ - if (AlignedAddress > HighestAddress) - return NULL; - - /* Special case for empty tree. */ - if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL) - { - if (AlignedAddress >= LowestAddress) - { - DPRINT("MmFindGapTopDown: %p\n", AlignedAddress); - return AlignedAddress; - } - DPRINT("MmFindGapTopDown: 0\n"); - return 0; - } - - /* Go to the node with highest address in the tree. */ - Node = MmIterateLastNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink); - - /* Check if there is enough space after the last memory area. */ - if (Node->EndingAddress <= AlignedAddress) - { - DPRINT("MmFindGapTopDown: %p\n", AlignedAddress); - return AlignedAddress; - } - - /* Traverse the tree from left to right. */ - PreviousNode = Node; - for (;;) - { - Node = MmIteratePrevNode(Node); - if (Node == NULL) - break; - - AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)PreviousNode->StartingAddress - Length + 1, Granularity); - - /* Check for overflow. */ - if (AlignedAddress > PreviousNode->StartingAddress) - return NULL; - - if (Node->EndingAddress <= AlignedAddress) - { - DPRINT("MmFindGapTopDown: %p\n", AlignedAddress); - return AlignedAddress; - } - - PreviousNode = Node; - } - - AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)PreviousNode->StartingAddress - Length + 1, Granularity); - - /* Check for overflow. */ - if (AlignedAddress > PreviousNode->StartingAddress) - return NULL; - - if (AlignedAddress >= LowestAddress) - { - DPRINT("MmFindGapTopDown: %p\n", AlignedAddress); - return AlignedAddress; - } - - DPRINT("MmFindGapTopDown: 0\n"); - return 0; + ULONG_PTR LowestAddress, HighestAddress, Candidate; + PMEMORY_AREA Root, Node; + + /* Get the margins of the address space */ + if (MmGetAddressSpaceOwner(AddressSpace) != NULL) + { + LowestAddress = (ULONG_PTR)MM_LOWEST_USER_ADDRESS; + HighestAddress = (ULONG_PTR)MmHighestUserAddress; + } + else + { + LowestAddress = (ULONG_PTR)MmSystemRangeStart; + HighestAddress = MAXULONG_PTR; + } + + /* Calculate the highest candidate */ + Candidate = ALIGN_DOWN_BY(HighestAddress + 1 - Length, Granularity); + + /* Check for overflow. */ + if (Candidate > HighestAddress) return NULL; + + /* Get the root of the address space tree */ + Root = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + + /* Go to the node with highest address in the tree. */ + Node = Root ? MmIterateLastNode(Root) : NULL; + while (Node && ((ULONG_PTR)Node->StartingAddress > HighestAddress)) + { + Node = MmIteratePrevNode(Node); + } + + /* Traverse the tree from high to low addresses */ + while (Node && ((ULONG_PTR)Node->StartingAddress > LowestAddress)) + { + /* Check if the memory area fits after the current node */ + if ((ULONG_PTR)Node->EndingAddress <= Candidate) + { + DPRINT("MmFindGapTopDown: %p\n", Candidate); + return (PVOID)Candidate; + } + + /* Calculate next possible adress below this node */ + Candidate = ALIGN_DOWN_BY((ULONG_PTR)Node->StartingAddress - Length, + Granularity); + + /* Check for overflow. */ + if (Candidate > (ULONG_PTR)Node->StartingAddress) + return NULL; + + /* Go to the next lower node */ + Node = MmIteratePrevNode(Node); + } + + /* Check if the last candidate is inside the given range */ + if (Candidate >= LowestAddress) + { + DPRINT("MmFindGapTopDown: %p\n", Candidate); + return (PVOID)Candidate; + } + + DPRINT("MmFindGapTopDown: 0\n"); + return NULL; } @@ -887,7 +864,7 @@ ULONG_PTR tmpLength; PMEMORY_AREA MemoryArea; - DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %p, " + DPRINT("MmCreateMemoryArea(Type 0x%lx, BaseAddress %p, " "*BaseAddress %p, Length %p, AllocationFlags %x, " "FixedAddress %x, Result %p)\n", Type, BaseAddress, *BaseAddress, Length, AllocationFlags, @@ -922,6 +899,7 @@ if (MmGetAddressSpaceOwner(AddressSpace) && (ULONG_PTR)(*BaseAddress) + tmpLength > (ULONG_PTR)MmSystemRangeStart) { + DPRINT("Memory area for user mode address space exceeds MmSystemRangeStart\n"); return STATUS_ACCESS_VIOLATION; } @@ -1026,8 +1004,9 @@ DPRINT("MmDeleteProcessAddressSpace(Process %x (%s))\n", Process, Process->ImageFileName); +#ifndef _M_AMD64 RemoveEntryList(&Process->MmProcessLinks); - +#endif MmLockAddressSpace(&Process->Vm); while ((MemoryArea = (PMEMORY_AREA)Process->Vm.WorkingSetExpansionLinks.Flink) != NULL) Modified: trunk/reactos/ntoskrnl/mm/mminit.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=5…
============================================================================== --- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Fri Feb 3 20:59:35 2012 @@ -1,4 +1,4 @@ -/* +/* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/mm/mminit.c @@ -45,13 +45,28 @@ BoundaryAddressMultiple.QuadPart = 0; // + // Create the memory area to define the loader mappings + // + BaseAddress = (PVOID)KSEG0_BASE; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + MmBootImageSize, + PAGE_EXECUTE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // // Create the memory area to define the PTE base // BaseAddress = (PVOID)PTE_BASE; Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, &BaseAddress, - 4 * 1024 * 1024, + PTE_TOP - PTE_BASE + 1, PAGE_READWRITE, &MArea, TRUE, @@ -66,7 +81,7 @@ Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, &BaseAddress, - 4 * 1024 * 1024, + HYPER_SPACE_END - HYPER_SPACE + 1, PAGE_READWRITE, &MArea, TRUE, @@ -165,7 +180,7 @@ 0, BoundaryAddressMultiple); ASSERT(Status == STATUS_SUCCESS); - +#ifndef _M_AMD64 // // Next, the KPCR // @@ -180,7 +195,7 @@ 0, BoundaryAddressMultiple); ASSERT(Status == STATUS_SUCCESS); - +#endif // // Now the KUSER_SHARED_DATA // @@ -238,8 +253,8 @@ // Print the memory layout // DPRINT1(" 0x%p - 0x%p\t%s\n", - MmSystemRangeStart, - (ULONG_PTR)MmSystemRangeStart + MmBootImageSize, + KSEG0_BASE, + (ULONG_PTR)KSEG0_BASE + MmBootImageSize, "Boot Loaded Image"); DPRINT1(" 0x%p - 0x%p\t%s\n", MmPfnDatabase, @@ -258,13 +273,13 @@ MiSessionSpaceEnd, "Session Space"); DPRINT1(" 0x%p - 0x%p\t%s\n", - PTE_BASE, PDE_BASE, + PTE_BASE, PTE_TOP, "Page Tables"); DPRINT1(" 0x%p - 0x%p\t%s\n", - PDE_BASE, HYPER_SPACE, + PDE_BASE, PDE_TOP, "Page Directories"); DPRINT1(" 0x%p - 0x%p\t%s\n", - HYPER_SPACE, HYPER_SPACE + (4 * 1024 * 1024), + HYPER_SPACE, HYPER_SPACE_END, "Hyperspace"); DPRINT1(" 0x%p - 0x%p\t%s\n", MmPagedPoolStart,
12 years, 10 months
1
0
0
0
[janderwald] 55396: [USBCCGP] - Remove hack of forwarding pdo requests to lower device object of fdo - Implement handling of reset port and cycle port - IOCTL_INTERNAL_USB_RESET_PORT / IOCTL_INTERN...
by janderwald@svn.reactos.org
Author: janderwald Date: Fri Feb 3 16:03:42 2012 New Revision: 55396 URL:
http://svn.reactos.org/svn/reactos?rev=55396&view=rev
Log: [USBCCGP] - Remove hack of forwarding pdo requests to lower device object of fdo - Implement handling of reset port and cycle port - IOCTL_INTERNAL_USB_RESET_PORT / IOCTL_INTERNAL_USB_CYCLE_PORT now need to be implemented in usbhub Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.c branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] Fri Feb 3 16:03:42 2012 @@ -277,7 +277,7 @@ // PDODeviceExtension->Common.IsFDO = FALSE; PDODeviceExtension->FunctionDescriptor = &FDODeviceExtension->FunctionDescriptor[Index]; - PDODeviceExtension->NextDeviceObject = FDODeviceExtension->NextDeviceObject; //DeviceObject; HACK + PDODeviceExtension->NextDeviceObject = DeviceObject; PDODeviceExtension->FunctionIndex = Index; PDODeviceExtension->FDODeviceExtension = FDODeviceExtension; PDODeviceExtension->InterfaceList = FDODeviceExtension->InterfaceList; @@ -498,8 +498,182 @@ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; - - +} + +NTSTATUS +FDO_HandleResetCyclePort( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PLIST_ENTRY ListHead, Entry; + LIST_ENTRY TempList; + PUCHAR ResetActive; + PIRP ListIrp; + KIRQL OldLevel; + + // + // get device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // get stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + DPRINT1("FDO_HandleResetCyclePort IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT) + { + // + // use reset port list + // + ListHead = &FDODeviceExtension->ResetPortListHead; + ResetActive = &FDODeviceExtension->ResetPortActive; + } + else + { + // + // use cycle port list + // + ListHead = &FDODeviceExtension->CyclePortListHead; + ResetActive = &FDODeviceExtension->CyclePortActive; + } + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->Lock, &OldLevel); + + if (*ResetActive) + { + // + // insert into pending list + // + InsertTailList(ListHead, &Irp->Tail.Overlay.ListEntry); + + // + // mark irp pending + // + IoMarkIrpPending(Irp); + Status = STATUS_PENDING; + + // + // release lock + // + KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); + } + else + { + // + // mark reset active + // + *ResetActive = TRUE; + + // + // release lock + // + KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); + + // + // forward request synchronized + // + USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp); + + // + // reacquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->Lock, &OldLevel); + + // + // mark reset as completed + // + *ResetActive = FALSE; + + // + // move all requests into temporary list + // + InitializeListHead(&TempList); + while(!IsListEmpty(ListHead)) + { + Entry = RemoveHeadList(ListHead); + InsertTailList(&TempList, Entry); + } + + // + // release lock + // + KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel); + + // + // complete pending irps + // + while(!IsListEmpty(&TempList)) + { + Entry = RemoveHeadList(&TempList); + ListIrp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); + + // + // complete request with status success + // + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + // + // status success + // + Status = STATUS_SUCCESS; + } + + return Status; +} + + + +NTSTATUS +FDO_HandleInternalDeviceControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + + // + // get device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // get stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT || + IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT) + { + // + // handle reset / cycle ports + // + Status = FDO_HandleResetCyclePort(DeviceObject, Irp); + DPRINT1("FDO_HandleResetCyclePort Status %x\n", Status); + if (Status != STATUS_PENDING) + { + // + // complete request + // + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + return Status; + } + + // + // forward and forget request + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp); } NTSTATUS @@ -517,6 +691,8 @@ { case IRP_MJ_PNP: return FDO_HandlePnp(DeviceObject, Irp); + case IRP_MJ_INTERNAL_DEVICE_CONTROL: + return FDO_HandleInternalDeviceControl(DeviceObject, Irp); default: DPRINT1("FDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction); ASSERT(FALSE); Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] Fri Feb 3 16:03:42 2012 @@ -925,6 +925,24 @@ return Status; } } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_GET_PORT_STATUS) + { + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp); + return Status; + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT) + { + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp); + return Status; + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT) + { + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp); + return Status; + } Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.c URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.c [iso-8859-1] Fri Feb 3 16:03:42 2012 @@ -43,6 +43,10 @@ FDODeviceExtension->Common.IsFDO = TRUE; FDODeviceExtension->DriverObject = DriverObject; FDODeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; + InitializeListHead(&FDODeviceExtension->ResetPortListHead); + InitializeListHead(&FDODeviceExtension->CyclePortListHead); + KeInitializeSpinLock(&FDODeviceExtension->Lock); + FDODeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); if (!FDODeviceExtension->NextDeviceObject) { Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h [iso-8859-1] Fri Feb 3 16:03:42 2012 @@ -39,6 +39,11 @@ PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor; // usb function descriptor ULONG FunctionDescriptorCount; // number of function descriptor PDEVICE_OBJECT * ChildPDO; // child pdos + LIST_ENTRY ResetPortListHead; // reset port list head + LIST_ENTRY CyclePortListHead; // cycle port list head + UCHAR ResetPortActive; // reset port active + UCHAR CyclePortActive; // cycle port active + KSPIN_LOCK Lock; // reset / cycle port list lock }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; #define USBCCPG_TAG 'cbsu'
12 years, 10 months
1
0
0
0
← Newer
1
...
51
52
53
54
55
56
57
58
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Results per page:
10
25
50
100
200