From 42bf54f96d7c43ac130608dee1da2f166fdeacaf Mon Sep 17 00:00:00 2001 From: David Welch Date: Thu, 2 May 2002 23:45:33 +0000 Subject: [PATCH] Fixed irq problems. Print more information on kernel mode exceptions. Translate grub style command lines. svn path=/trunk/; revision=2903 --- reactos/apps/utils/pice/loader/stdinc.h | 2 +- reactos/hal/hal/hal.def | 2 +- reactos/hal/hal/hal.edf | 2 +- reactos/hal/halx86/irql.c | 269 +++++++++--------------- reactos/ntoskrnl/include/internal/ke.h | 9 + reactos/ntoskrnl/kd/kdebug.c | 4 +- reactos/ntoskrnl/ke/bug.c | 15 +- reactos/ntoskrnl/ke/catch.c | 32 +-- reactos/ntoskrnl/ke/i386/exp.c | 189 +++++++++-------- reactos/ntoskrnl/ke/i386/irq.c | 125 ++++++----- reactos/ntoskrnl/ke/i386/irqhand.s | 48 ----- reactos/ntoskrnl/ke/main.c | 75 +++++-- reactos/ntoskrnl/ldr/loader.c | 4 +- reactos/ntoskrnl/ntoskrnl.def | 3 +- reactos/ntoskrnl/ntoskrnl.edf | 3 +- 15 files changed, 374 insertions(+), 408 deletions(-) diff --git a/reactos/apps/utils/pice/loader/stdinc.h b/reactos/apps/utils/pice/loader/stdinc.h index e0b27c2e0c5..6ce4d2c8e22 100644 --- a/reactos/apps/utils/pice/loader/stdinc.h +++ b/reactos/apps/utils/pice/loader/stdinc.h @@ -12,7 +12,7 @@ //#include //#include //#include -#include +#include #include #include //#include diff --git a/reactos/hal/hal/hal.def b/reactos/hal/hal/hal.def index 6b2b3a8feca..24763ec834f 100644 --- a/reactos/hal/hal/hal.def +++ b/reactos/hal/hal/hal.def @@ -69,8 +69,8 @@ KdPortDisableInterrupts@0 KdPortEnableInterrupts@0 KeAcquireSpinLock@8 @KeAcquireSpinLockRaiseToSynch@4 -KeFlushWriteBuffer@0 KeGetCurrentIrql@0 +KeFlushWriteBuffer@0 KeLowerIrql@4 KeQueryPerformanceCounter@4 KeRaiseIrql@8 diff --git a/reactos/hal/hal/hal.edf b/reactos/hal/hal/hal.edf index 9257549588d..63636f7ed70 100644 --- a/reactos/hal/hal/hal.edf +++ b/reactos/hal/hal/hal.edf @@ -69,8 +69,8 @@ KdPortDisableInterrupts=KdPortDisableInterrupts@0 KdPortEnableInterrupts=KdPortEnableInterrupts@0 KeAcquireSpinLock=KeAcquireSpinLock@8 KeAcquireSpinLockRaiseToSynch=@KeAcquireSpinLockRaiseToSynch@4 -KeFlushWriteBuffer=KeFlushWriteBuffer@0 KeGetCurrentIrql=KeGetCurrentIrql@0 +KeFlushWriteBuffer=KeFlushWriteBuffer@0 KeLowerIrql=KeLowerIrql@4 KeQueryPerformanceCounter=KeQueryPerformanceCounter@4 KeRaiseIrql=KeRaiseIrql@8 diff --git a/reactos/hal/halx86/irql.c b/reactos/hal/halx86/irql.c index 868a3767633..a18a5aa6cec 100644 --- a/reactos/hal/halx86/irql.c +++ b/reactos/hal/halx86/irql.c @@ -11,13 +11,13 @@ #include #include #include +#include #define NDEBUG #include /* GLOBALS ******************************************************************/ -/* FIXME: this should be in a header file */ #define NR_IRQS (16) #define IRQ_BASE (0x40) @@ -28,165 +28,107 @@ static KIRQL CurrentIrql = HIGH_LEVEL; extern IMPORTED ULONG DpcQueueSize; -static VOID KeSetCurrentIrql(KIRQL newlvl); +static ULONG HalpPendingInterruptCount[NR_IRQS]; #define DIRQL_TO_IRQ(x) (PROFILE_LEVEL - x) #define IRQ_TO_DIRQL(x) (PROFILE_LEVEL - x) +VOID STDCALL +KiInterruptDispatch2 (ULONG Irq, KIRQL old_level); + /* FUNCTIONS ****************************************************************/ -VOID HalpInitPICs(VOID) -{ - /* Initialization sequence */ - WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11); - WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11); - /* Start of hardware irqs (0x24) */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0x40); - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x48); - /* 8259-1 is master */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4); - /* 8259-2 is slave */ - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2); - /* 8086 mode */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1); - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1); - /* Mask off all interrupts from PICs */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0xff); - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0xff); - - /* We can know enable interrupts */ - __asm__ __volatile__ ("sti\n\t"); -} - -static ULONG -HiSetCurrentPICMask(unsigned int mask) -{ - WRITE_PORT_UCHAR((PUCHAR)0x21,mask & 0xff); - WRITE_PORT_UCHAR((PUCHAR)0xa1,(mask >> 8) & 0xff); - - return mask; -} - -static VOID HiSwitchIrql(KIRQL oldIrql) -/* - * FUNCTION: Switches to the current irql - * NOTE: Must be called with interrupt disabled - */ -{ - unsigned int i; - PKTHREAD CurrentThread; - - CurrentThread = KeGetCurrentThread(); - - /* - * Disable all interrupts - */ - if (CurrentIrql >= IPI_LEVEL) - { - HiSetCurrentPICMask(0xFFFF); - __asm__("sti\n\t"); - return; - } - - /* - * Disable all interrupts but the timer - */ - if (CurrentIrql == PROFILE_LEVEL || - CurrentIrql == CLOCK1_LEVEL || - CurrentIrql == CLOCK2_LEVEL) - { - HiSetCurrentPICMask(0xFFFE); - __asm__("sti\n\t"); - return; - } - - /* - * Disable all interrupts of lesser priority - */ - if (CurrentIrql > DISPATCH_LEVEL) - { - unsigned int current_mask = 0; - - for (i = CurrentIrql; i > (PROFILE_LEVEL - 15); i--) - { - current_mask = current_mask | (1 << (PROFILE_LEVEL - i)); - } - - HiSetCurrentPICMask(current_mask); - __asm__("sti\n\t"); - return; - } - - /* - * Enable all interrupts - */ - if (CurrentIrql == DISPATCH_LEVEL) - { - HiSetCurrentPICMask(0); - __asm__("sti\n\t"); - return; - } - - /* - * APCs are disabled but execute any pending DPCs - */ - if (CurrentIrql == APC_LEVEL) - { - HiSetCurrentPICMask(0); - __asm__("sti\n\t"); - if (DpcQueueSize > 0) - { - CurrentIrql = DISPATCH_LEVEL; - KiDispatchInterrupt(); - CurrentIrql = APC_LEVEL; - } - return; - } - - /* - * Execute any pending DPCs or APCs - */ - if (CurrentIrql == PASSIVE_LEVEL) - { - HiSetCurrentPICMask(0); - __asm__("sti"); - if (DpcQueueSize > 0) - { - CurrentIrql = DISPATCH_LEVEL; - KiDispatchInterrupt(); - CurrentIrql = PASSIVE_LEVEL; - } - if (CurrentThread != NULL && - CurrentThread->ApcState.KernelApcPending) - { - CurrentIrql = APC_LEVEL; - KiDeliverApc(0, 0, 0); - CurrentIrql = PASSIVE_LEVEL; - } - } -} - - -KIRQL STDCALL -KeGetCurrentIrql (VOID) +KIRQL STDCALL KeGetCurrentIrql (VOID) /* * PURPOSE: Returns the current irq level * RETURNS: The current irq level */ { - return(CurrentIrql); + return(CurrentIrql); } - -STATIC VOID -KeSetCurrentIrql(KIRQL newlvl) -/* - * PURPOSE: Sets the current irq level without taking any action - */ +VOID HalpInitPICs(VOID) { - CurrentIrql = newlvl; + memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount)); + + /* Initialization sequence */ + WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11); + WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11); + /* Start of hardware irqs (0x24) */ + WRITE_PORT_UCHAR((PUCHAR)0x21, 0x40); + WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x48); + /* 8259-1 is master */ + WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4); + /* 8259-2 is slave */ + WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2); + /* 8086 mode */ + WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1); + WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1); + /* Enable all interrupts from PICs */ + WRITE_PORT_UCHAR((PUCHAR)0x21, 0x0); + WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x0); + + /* We can now enable interrupts */ + __asm__ __volatile__ ("sti\n\t"); } +VOID STATIC +HalpExecuteIrqs(KIRQL NewIrql) +{ + ULONG IrqLimit, i; + + IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS); + + /* + * For each irq if there have been any deferred interrupts then now + * dispatch them. + */ + for (i = 0; i < IrqLimit; i++) + { + while (HalpPendingInterruptCount[i] > 0) + { + /* + * For each deferred interrupt execute all the handlers at DIRQL. + */ + CurrentIrql = IRQ_TO_DIRQL(i); + KiInterruptDispatch2(i, NewIrql); + HalpPendingInterruptCount[i]--; + } + } +} + +VOID STATIC +HalpLowerIrql(KIRQL NewIrql) +{ + if (NewIrql > PROFILE_LEVEL) + { + CurrentIrql = NewIrql; + return; + } + HalpExecuteIrqs(NewIrql); + if (NewIrql >= DISPATCH_LEVEL) + { + CurrentIrql = NewIrql; + return; + } + CurrentIrql = DISPATCH_LEVEL; + if (DpcQueueSize > 0) + { + KiDispatchInterrupt(); + } + if (NewIrql == APC_LEVEL) + { + CurrentIrql = NewIrql; + return; + } + CurrentIrql = APC_LEVEL; + if (KeGetCurrentThread() != NULL && + KeGetCurrentThread()->ApcState.KernelApcPending) + { + KiDeliverApc(0, 0, 0); + } + CurrentIrql = PASSIVE_LEVEL; +} /********************************************************************** * NAME EXPORTED @@ -204,14 +146,11 @@ KeSetCurrentIrql(KIRQL newlvl) * NOTES * Uses fastcall convention */ - VOID FASTCALL KfLowerIrql (KIRQL NewIrql) { KIRQL OldIrql; - __asm__("cli\n\t"); - DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql); if (NewIrql > CurrentIrql) @@ -222,9 +161,7 @@ KfLowerIrql (KIRQL NewIrql) for(;;); } - OldIrql = CurrentIrql; - CurrentIrql = NewIrql; - HiSwitchIrql(OldIrql); + HalpLowerIrql(NewIrql); } @@ -283,14 +220,8 @@ KfRaiseIrql (KIRQL NewIrql) for(;;); } - __asm__("cli\n\t"); OldIrql = CurrentIrql; CurrentIrql = NewIrql; - - DPRINT ("NewIrql %x OldIrql %x CurrentIrql %x\n", - NewIrql, OldIrql, CurrentIrql); - HiSwitchIrql(OldIrql); - return OldIrql; } @@ -374,7 +305,9 @@ HalBeginSystemInterrupt (ULONG Vector, PKIRQL OldIrql) { if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS) - return FALSE; + { + return(FALSE); + } /* Send EOI to the PICs */ WRITE_PORT_UCHAR((PUCHAR)0x20,0x20); @@ -383,24 +316,26 @@ HalBeginSystemInterrupt (ULONG Vector, WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20); } - *OldIrql = KeGetCurrentIrql(); - if (Vector-IRQ_BASE != 0) + if (CurrentIrql >= Irql) { - DPRINT("old_level %d\n",*OldIrql); + HalpPendingInterruptCount[Vector - IRQ_BASE]++; + return(FALSE); } - KeSetCurrentIrql(Irql); - - return TRUE; + *OldIrql = CurrentIrql; + CurrentIrql = Irql; + + return(TRUE); } -VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, - ULONG Unknown2) +VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2) +/* + * FUNCTION: Finish a system interrupt and restore the specified irq level. + */ { - KeSetCurrentIrql(Irql); + HalpLowerIrql(Irql); } - BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector, ULONG Unknown2) { diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 19604a2d104..7fedba83361 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -212,6 +212,15 @@ KePushAndStackSwitchAndSysRet(ULONG A, ULONG B, ULONG C, ULONG D, ULONG E, ULONG F, PVOID NewStack); VOID STDCALL KeStackSwitchAndRet(PVOID NewStack); +VOID STDCALL +KeBugCheckWithTf(ULONG BugCheckCode, + ULONG BugCheckParameter1, + ULONG BugCheckParameter2, + ULONG BugCheckParameter3, + ULONG BugCheckParameter4, + PKTRAP_FRAME Tf); +VOID +KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2); #endif /* not __ASM__ */ diff --git a/reactos/ntoskrnl/kd/kdebug.c b/reactos/ntoskrnl/kd/kdebug.c index 7f0417b7ff0..a608be4bc39 100644 --- a/reactos/ntoskrnl/kd/kdebug.c +++ b/reactos/ntoskrnl/kd/kdebug.c @@ -1,4 +1,4 @@ -/* $Id: kdebug.c,v 1.34 2002/02/09 18:41:24 chorns Exp $ +/* $Id: kdebug.c,v 1.35 2002/05/02 23:45:32 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -297,7 +297,7 @@ KdpPrintString(PANSI_STRING String) break; case GdbDebug: - KdGdbDebugPrint(pch); + KdGdbDebugPrint(pch); break; case PiceDebug: diff --git a/reactos/ntoskrnl/ke/bug.c b/reactos/ntoskrnl/ke/bug.c index 5e46f75a533..16d2e718c96 100644 --- a/reactos/ntoskrnl/ke/bug.c +++ b/reactos/ntoskrnl/ke/bug.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: bug.c,v 1.20 2002/02/09 18:41:24 chorns Exp $ +/* $Id: bug.c,v 1.21 2002/05/02 23:45:32 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/bug.c @@ -73,6 +73,19 @@ KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord, return(TRUE); } +VOID STDCALL +KeBugCheckWithTf(ULONG BugCheckCode, + ULONG BugCheckParameter1, + ULONG BugCheckParameter2, + ULONG BugCheckParameter3, + ULONG BugCheckParameter4, + PKTRAP_FRAME Tf) +{ + DbgPrint("Bug detected code: 0x%X\n", BugCheckCode); + KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2); + for(;;); +} + VOID STDCALL KeBugCheckEx(ULONG BugCheckCode, ULONG BugCheckParameter1, diff --git a/reactos/ntoskrnl/ke/catch.c b/reactos/ntoskrnl/ke/catch.c index 6653ee7b9ab..8461f1626b9 100644 --- a/reactos/ntoskrnl/ke/catch.c +++ b/reactos/ntoskrnl/ke/catch.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: catch.c,v 1.18 2002/02/09 18:41:24 chorns Exp $ +/* $Id: catch.c,v 1.19 2002/05/02 23:45:33 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/catch.c @@ -270,24 +270,28 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, KD_CONTINUE_TYPE Action; /* PreviousMode == KernelMode */ - + if (!KdDebuggerEnabled || KdDebugType != GdbDebug) { - KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED); - } + /* FIXME: Get ExceptionNr and CR2 */ + KeBugCheckWithTf (KMODE_EXCEPTION_NOT_HANDLED, 0, 0, 0, 0, Tf); + } Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf); if (Action != kdHandleException) - { - Value = RtlpDispatchException (ExceptionRecord, Context); - - DPRINT("RtlpDispatchException() returned with 0x%X\n", Value); - /* If RtlpDispatchException() does not handle the exception then bugcheck */ - if (Value != ExceptionContinueExecution) - { - KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED); - } - } + { + Value = RtlpDispatchException (ExceptionRecord, Context); + + DPRINT("RtlpDispatchException() returned with 0x%X\n", Value); + /* + * If RtlpDispatchException() does not handle the exception then + * bugcheck + */ + if (Value != ExceptionContinueExecution) + { + KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED); + } + } else { KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame); diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 7790c0d6b2f..a4a4d59f8e4 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -162,7 +162,8 @@ print_address(PVOID address) if ((Offset >= Symbol->RelativeAddress) && (Offset < NextAddress)) { - DbgPrint("<%ws: %x (%wZ)>", current->Name, Offset, &Symbol->Name); + DbgPrint("<%ws: %x (%wZ)>", current->Name, Offset, + &Symbol->Name); Printed = TRUE; break; } @@ -203,14 +204,14 @@ KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2) } else { - if (ExceptionNr < 16) - { - Er.ExceptionCode = ExceptionToNtStatus[ExceptionNr]; - } - else - { - Er.ExceptionCode = STATUS_ACCESS_VIOLATION; - } + if (ExceptionNr < 16) + { + Er.ExceptionCode = ExceptionToNtStatus[ExceptionNr]; + } + else + { + Er.ExceptionCode = STATUS_ACCESS_VIOLATION; + } Er.NumberParameters = 0; } @@ -223,18 +224,20 @@ ULONG KiDoubleFaultHandler(VOID) { unsigned int cr2; - ULONG i, j; ULONG StackLimit; ULONG StackBase; ULONG Esp0; ULONG ExceptionNr = 8; KTSS* OldTss; PULONG Frame; +#if 0 + ULONG i, j; static PVOID StackTrace[MM_STACK_SIZE / sizeof(PVOID)]; static ULONG StackRepeatCount[MM_STACK_SIZE / sizeof(PVOID)]; static ULONG StackRepeatLength[MM_STACK_SIZE / sizeof(PVOID)]; ULONG TraceLength; BOOLEAN FoundRepeat; +#endif /* Use the address of the trap frame as approximation to the ring0 esp */ OldTss = KeGetCurrentKPCR()->TSS; @@ -318,6 +321,15 @@ KiDoubleFaultHandler(VOID) StackBase = (ULONG)&init_stack; } +#if 1 + DbgPrint("Frames: "); + Frame = (PULONG)OldTss->Ebp; + while (Frame != NULL && (ULONG)Frame >= StackBase) + { + print_address((PVOID)Frame[1]); + Frame = (PULONG)Frame[0]; + } +#else DbgPrint("Frames: "); i = 0; Frame = (PULONG)OldTss->Ebp; @@ -395,93 +407,24 @@ KiDoubleFaultHandler(VOID) i = i + StackRepeatLength[i] * StackRepeatCount[i]; } } +#endif } DbgPrint("\n"); for(;;); } -ULONG -KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) -/* - * FUNCTION: Called by the lowlevel execption handlers to print an amusing - * message and halt the computer - * ARGUMENTS: - * Complete CPU context - */ +VOID +KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2) { -#define SEH - unsigned int cr2; -#ifndef SEH - unsigned int cr3; - unsigned int i; - ULONG StackLimit; - PULONG Frame; -#endif -// unsigned int j, sym; - NTSTATUS Status; - ULONG Esp0; + unsigned int cr3; + unsigned int i; + ULONG StackLimit; + PULONG Frame; + ULONG Esp0; - /* Use the address of the trap frame as approximation to the ring0 esp */ - Esp0 = (ULONG)&Tf->Eip; + Esp0 = (ULONG)Tf; - /* Get CR2 */ - __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); - - /* - * If this was a V86 mode exception then handle it specially - */ - if (Tf->Eflags & (1 << 17)) - { - return(KeV86Exception(ExceptionNr, Tf, cr2)); - } - - /* - * Check for stack underflow, this may be obsolete - */ - if (PsGetCurrentThread() != NULL && - Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit) - { - DbgPrint("Stack underflow (tf->esp %x Limit %x)\n", - Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit); - ExceptionNr = 12; - } - - /* - * Maybe handle the page fault and return - */ - if (ExceptionNr == 14) - { - __asm__("sti\n\t"); - Status = MmPageFault(Tf->Cs&0xffff, - &Tf->Eip, - &Tf->Eax, - cr2, - Tf->ErrorCode); - if (NT_SUCCESS(Status)) - { - return(0); - } - - } - - /* - * Handle user exceptions differently - */ - if ((Tf->Cs & 0xFFFF) == USER_CS) - { - return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2)); - } - else - { -#ifdef SEH - return(KiKernelTrapHandler(Tf, ExceptionNr, (PVOID)cr2)); -#endif - } - - -#ifndef SEH - /* * Print out the CPU registers */ @@ -556,11 +499,75 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) { DbgPrint("\n"); } +} - for(;;); +ULONG +KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) +/* + * FUNCTION: Called by the lowlevel execption handlers to print an amusing + * message and halt the computer + * ARGUMENTS: + * Complete CPU context + */ +{ + unsigned int cr2; + NTSTATUS Status; + ULONG Esp0; - return 0; -#endif + /* Use the address of the trap frame as approximation to the ring0 esp */ + Esp0 = (ULONG)&Tf->Eip; + + /* Get CR2 */ + __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); + + /* + * If this was a V86 mode exception then handle it specially + */ + if (Tf->Eflags & (1 << 17)) + { + return(KeV86Exception(ExceptionNr, Tf, cr2)); + } + + /* + * Check for stack underflow, this may be obsolete + */ + if (PsGetCurrentThread() != NULL && + Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit) + { + DbgPrint("Stack underflow (tf->esp %x Limit %x)\n", + Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit); + ExceptionNr = 12; + } + + /* + * Maybe handle the page fault and return + */ + if (ExceptionNr == 14) + { + __asm__("sti\n\t"); + Status = MmPageFault(Tf->Cs&0xffff, + &Tf->Eip, + &Tf->Eax, + cr2, + Tf->ErrorCode); + if (NT_SUCCESS(Status)) + { + return(0); + } + + } + + /* + * Handle user exceptions differently + */ + if ((Tf->Cs & 0xFFFF) == USER_CS) + { + return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2)); + } + else + { + return(KiKernelTrapHandler(Tf, ExceptionNr, (PVOID)cr2)); + } } VOID diff --git a/reactos/ntoskrnl/ke/i386/irq.c b/reactos/ntoskrnl/ke/i386/irq.c index 6da2230ec02..2d3959837e7 100644 --- a/reactos/ntoskrnl/ke/i386/irq.c +++ b/reactos/ntoskrnl/ke/i386/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.18 2002/04/20 03:21:35 phreak Exp $ +/* $Id: irq.c,v 1.19 2002/05/02 23:45:33 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -371,6 +371,32 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) #else /* MP */ +VOID STDCALL +KiInterruptDispatch2 (ULONG Irq, KIRQL old_level) +{ + PKINTERRUPT isr; + PLIST_ENTRY current; + + if (Irq == 0) + { + KiUpdateSystemTime(old_level, 0); + } + else + { + /* + * Iterate the list until one of the isr tells us its device interrupted + */ + current = isr_table[Irq].Flink; + isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); + while (current != &isr_table[Irq] && + !isr->ServiceRoutine(isr, isr->ServiceContext)) + { + current = current->Flink; + isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); + } + } +} + VOID KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe) /* @@ -380,24 +406,36 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe) */ { KIRQL old_level; - PKINTERRUPT isr; - PLIST_ENTRY current; - -#ifdef DBG + static ULONG Irq0Count = 0; +#if 0 KTRAP_FRAME KernelTrapFrame; KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame); KeGetCurrentThread()->TrapFrame = &KernelTrapFrame; - #endif /* DBG */ + if (InterlockedIncrement(&Irq0Count) > 32) + { + __asm__("int $3\n\t"); + } + /* - * Notify the rest of the kernel of the raised irq level + * At this point we have interrupts disabled, nothing has been done to + * the PIC. */ - HalBeginSystemInterrupt (irq + IRQ_BASE, - PROFILE_LEVEL - irq, - &old_level); + + /* + * Notify the rest of the kernel of the raised irq level. For the + * default HAL this will send an EOI to the PIC and alter the IRQL. + */ + if (!HalBeginSystemInterrupt (irq + IRQ_BASE, + PROFILE_LEVEL - irq, + &old_level)) + { + InterlockedDecrement(&Irq0Count); + return; + } /* * Enable interrupts @@ -405,67 +443,22 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe) */ __asm__("sti\n\t"); - if (irq == 0) - { - KiUpdateSystemTime(old_level, Trapframe->Eip); - } - else - { - DPRINT("KiInterruptDispatch(irq %d)\n",irq); - /* - * Iterate the list until one of the isr tells us its device interrupted - */ - current = isr_table[irq].Flink; - isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); - DPRINT("current %x isr %x\n",current,isr); - while (current!=(&isr_table[irq]) && - !isr->ServiceRoutine(isr,isr->ServiceContext)) - { - current = current->Flink; - isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); - DPRINT("current %x isr %x\n",current,isr); - } - } - /* - * Disable interrupts + * Actually call the ISR. */ - __asm__("cli\n\t"); - + KiInterruptDispatch2(irq, old_level); + /* - * Unmask the related irq + * End the system interrupt. */ - HalEnableSystemInterrupt (irq + IRQ_BASE, 0, 0); - - /* - * If the processor level will drop below dispatch level on return then - * issue a DPC queue drain interrupt - */ - __asm__("sti\n\t"); - - if (old_level < DISPATCH_LEVEL) - { - HalEndSystemInterrupt (DISPATCH_LEVEL, 0); - - if (KeGetCurrentThread() != NULL) - { - KeGetCurrentThread()->LastEip = Trapframe->Eip; - } - KiDispatchInterrupt(); - if (irq == 0) - { - PsDispatchThread(THREAD_STATE_RUNNABLE); - } - if (KeGetCurrentThread() != NULL && - KeGetCurrentThread()->Alerted[1] != 0 && - Trapframe->Cs != KERNEL_CS) - { - HalEndSystemInterrupt (APC_LEVEL, 0); - KiDeliverNormalApc(); - } - } - HalEndSystemInterrupt (old_level, 0); + + InterlockedDecrement(&Irq0Count); + + if (old_level < DISPATCH_LEVEL && irq == 0) + { + PsDispatchThread(THREAD_STATE_RUNNABLE); + } } #endif /* MP */ diff --git a/reactos/ntoskrnl/ke/i386/irqhand.s b/reactos/ntoskrnl/ke/i386/irqhand.s index fdc616d399d..4694bbc9276 100644 --- a/reactos/ntoskrnl/ke/i386/irqhand.s +++ b/reactos/ntoskrnl/ke/i386/irqhand.s @@ -14,9 +14,6 @@ _irq_handler_0: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0x21,%al - orb $1<<0,%al - outb %al,$0x21 pushl %esp pushl $0 call _KiInterruptDispatch @@ -42,9 +39,6 @@ _irq_handler_1: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0x21,%al - orb $1<<1,%al - outb %al,$0x21 pushl %esp pushl $1 call _KiInterruptDispatch @@ -70,9 +64,6 @@ _irq_handler_2: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0x21,%al - orb $1<<2,%al - outb %al,$0x21 pushl %esp pushl $2 call _KiInterruptDispatch @@ -98,9 +89,6 @@ _irq_handler_3: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0x21,%al - orb $1<<3,%al - outb %al,$0x21 pushl %esp pushl $3 call _KiInterruptDispatch @@ -126,9 +114,6 @@ _irq_handler_4: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0x21,%al - orb $1<<4,%al - outb %al,$0x21 pushl %esp pushl $4 call _KiInterruptDispatch @@ -154,9 +139,6 @@ _irq_handler_5: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0x21,%al - orb $1<<5,%al - outb %al,$0x21 pushl %esp pushl $5 call _KiInterruptDispatch @@ -182,9 +164,6 @@ _irq_handler_6: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0x21,%al - orb $1<<6,%al - outb %al,$0x21 pushl %esp pushl $6 call _KiInterruptDispatch @@ -210,9 +189,6 @@ _irq_handler_7: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0x21,%al - orb $1<<7,%al - outb %al,$0x21 pushl %esp pushl $7 call _KiInterruptDispatch @@ -238,9 +214,6 @@ _irq_handler_8: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0xa1,%al - orb $1<<(8-8),%al - outb %al,$0xa1 pushl %esp pushl $8 call _KiInterruptDispatch @@ -266,9 +239,6 @@ _irq_handler_9: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0xa1,%al - orb $1<<(9-8),%al - outb %al,$0xa1 pushl %esp pushl $9 call _KiInterruptDispatch @@ -294,9 +264,6 @@ _irq_handler_10: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0xa1,%al - orb $1<<(10-8),%al - outb %al,$0xa1 pushl %esp pushl $10 call _KiInterruptDispatch @@ -322,9 +289,6 @@ _irq_handler_11: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0xa1,%al - orb $1<<(11-8),%al - outb %al,$0xa1 pushl %esp pushl $11 call _KiInterruptDispatch @@ -350,9 +314,6 @@ _irq_handler_12: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0xa1,%al - orb $1<<(12-8),%al - outb %al,$0xa1 pushl %esp pushl $12 call _KiInterruptDispatch @@ -378,9 +339,6 @@ _irq_handler_13: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0xa1,%al - orb $1<<(13-8),%al - outb %al,$0xa1 pushl %esp pushl $13 call _KiInterruptDispatch @@ -406,9 +364,6 @@ _irq_handler_14: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0xa1,%al - orb $1<<(14-8),%al - outb %al,$0xa1 pushl %esp pushl $14 call _KiInterruptDispatch @@ -434,9 +389,6 @@ _irq_handler_15: movw %ax,%es movl $PCR_SELECTOR, %eax movl %eax, %fs - inb $0xa1,%al - orb $1<<(15-8),%al - outb %al,$0xa1 pushl %esp pushl $15 call _KiInterruptDispatch diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index cd3a12d594f..51176716fcf 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: main.c,v 1.119 2002/04/26 19:57:11 ekohl Exp $ +/* $Id: main.c,v 1.120 2002/05/02 23:45:33 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/main.c @@ -451,17 +451,17 @@ InitSystemSharedUserPage (PCSZ ParameterLine) p = strchr (ParamBuffer, '\\'); if (p) { - DPRINT("Boot path: %s\n", p); - RtlCreateUnicodeStringFromAsciiz (&BootPath, p); - *p = 0; + DPRINT("Boot path: %s\n", p); + RtlCreateUnicodeStringFromAsciiz (&BootPath, p); + *p = 0; } else { - DPRINT("Boot path: %s\n", "\\"); - RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\"); + DPRINT("Boot path: %s\n", "\\"); + RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\"); } DPRINT("Arc name: %s\n", ParamBuffer); - + /* Only arc name left - build full arc name */ ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR)); swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer); @@ -556,8 +556,8 @@ InitSystemSharedUserPage (PCSZ ParameterLine) DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath); swprintf(SharedUserData->NtSystemRoot, L"%C:%wZ", 'A' + i, &BootPath); - - BootDriveFound = TRUE; + + BootDriveFound = TRUE; } NtClose (Handle); @@ -567,7 +567,7 @@ InitSystemSharedUserPage (PCSZ ParameterLine) RtlFreeUnicodeString (&DriveDeviceName); RtlFreeUnicodeString (&ArcDeviceName); - DPRINT("DosDeviceMap: 0x%x\n", SharedPage->DosDeviceMap); + DPRINT("DosDeviceMap: 0x%x\n", SharedUserData->DosDeviceMap); if (BootDriveFound == FALSE) { @@ -1096,7 +1096,57 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) KeLoaderBlock.ModsCount++; KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules; - strcpy(KeLoaderCommandLine, (PUCHAR)_LoaderBlock->CommandLine); + if (((PUCHAR)_LoaderBlock->CommandLine)[0] == '(') + { + ULONG DiskNumber, PartNumber; + PCH p; + CHAR Temp[256]; + PCH options; + PCH s1; + + if (((PUCHAR)_LoaderBlock->CommandLine)[1] == 'h' && + ((PUCHAR)_LoaderBlock->CommandLine)[2] == 'd') + { + DiskNumber = ((PUCHAR)_LoaderBlock->CommandLine)[3] - '0'; + PartNumber = ((PUCHAR)_LoaderBlock->CommandLine)[5] - '0'; + } + strcpy(Temp, &((PUCHAR)_LoaderBlock->CommandLine)[7]); + if ((options = strchr(Temp, ' ')) != NULL) + { + *options = 0; + options++; + } + else + { + options = ""; + } + if ((s1 = strrchr(Temp, '/')) != NULL) + { + *s1 = 0; + if ((s1 = strrchr(Temp, '/')) != NULL) + { + *s1 = 0; + } + } + sprintf(KeLoaderCommandLine, + "multi(0)disk(0)rdisk(%ld)partition(%ld)%s %s", + DiskNumber, PartNumber + 1, Temp, options); + + p = KeLoaderCommandLine; + while (*p != 0 && *p != ' ') + { + if ((*p) == '/') + { + (*p) = '\\'; + } + p++; + } + DPRINT1("Command Line: %s\n", KeLoaderCommandLine); + } + else + { + strcpy(KeLoaderCommandLine, (PUCHAR)_LoaderBlock->CommandLine); + } KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine; strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe"); @@ -1118,7 +1168,8 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) #endif HalBase = KeLoaderModules[1].ModStart; - DriverBase = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd; + DriverBase = + PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd); /* * Process hal.dll diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 750a84d6799..4199454082c 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.101 2002/04/27 19:24:15 hbirr Exp $ +/* $Id: loader.c,v 1.102 2002/05/02 23:45:33 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -373,7 +373,7 @@ static VOID LdrLoadAutoConfigDriver (LPWSTR RelativeDriverName) Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode); if (!NT_SUCCESS(Status)) { - return; + return; } Status = LdrLoadDriver(&DriverName, DeviceNode, FALSE); diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 8297e8adec3..93b98dd9c66 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.def,v 1.132 2002/03/23 19:44:46 chorns Exp $ +; $Id: ntoskrnl.def,v 1.133 2002/05/02 23:45:32 dwelch Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -450,6 +450,7 @@ KeWaitForSingleObject@20 ;KiCoprocessorError@0 KiDeliverApc@12 KiDispatchInterrupt@0 +KiInterruptDispatch2@8 ;KiIpiServiceRoutine@8 ;@KiReleaseSpinLock@4 ;KiUnexpectedInterrupt diff --git a/reactos/ntoskrnl/ntoskrnl.edf b/reactos/ntoskrnl/ntoskrnl.edf index f1a1c1ff8c3..10a26e2c6c1 100644 --- a/reactos/ntoskrnl/ntoskrnl.edf +++ b/reactos/ntoskrnl/ntoskrnl.edf @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.edf,v 1.118 2002/03/23 19:44:46 chorns Exp $ +; $Id: ntoskrnl.edf,v 1.119 2002/05/02 23:45:32 dwelch Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -450,6 +450,7 @@ KeWaitForSingleObject=KeWaitForSingleObject@20 ;KiCoprocessorError@0 KiDeliverApc=KiDeliverApc@12 KiDispatchInterrupt=KiDispatchInterrupt@0 +KiInterruptDispatch2=KiInterruptDispatch2@8 ;KiIpiServiceRoutine@8 ;KiReleaseSpinLock@4 ;KiUnexpectedInterrupt