diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 749b92f843d..2643eab7d17 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,36 @@ +2003-04-06 Casper S. Hornstrup + + * drivers/storage/atapi/atapi.c (AtapiReadWrite): Expect an interrupt a + bit sooner. + * hal/halx86/isa.c (HalpGetIsaInterruptVector): Compute vector for MP. + * hal/halx86/pci.c (HalpGetPciInterruptVector): Ditto. + * hal/halx86/sysbus.c (HalpGetSystemInterruptVector): Ditto. + * hal/halx86/mp.c (AssignIrqVector): Rewrite. + (MpsTimerHandler): Disable for now. + (MpsSpuriousHandler): Do not acknowledge interrupt. + (HalAllProcessorsStarted): Only boot 1 CPU for now. + (RescheduleDpcRoutine): New function. + (RescheduleDpc): New variable. + (HalpInitMPS): Initialize RescheduleDpc. Fix bug in call to memset. + * hal/halx86/mpsirql.c: Rewrite. + * hal/halx86/include/mps.h (VECTOR2IRQ, IRQ2VECTOR, VECTOR2IRQL, + IRQL2VECTOR): New macros. + * ntoskrnl/ntoskrnl.def: Add KeRescheduleThread@0. + * ntoskrnl/ntoskrnl.edf: Ditto. + * ntoskrnl/include/internal/ke.h (KeRescheduleThread): Prototype. + * ntoskrnl/ke/kthread.c (KeRescheduleThread): New function. + * ntoskrnl/ke/i386/exp.c (KeInitExceptions): Remove unneeded call to + set_trap_gate(). + * ntoskrnl/ke/i386/irq.c (VECTOR2IRQ, IRQ2VECTOR, VECTOR2IRQL): Correct. + (IRQ_BASE): Define as FIRST_DEVICE_VECTOR. + (NR_IRQS): Define using IRQ_BASE. + (KeInitInterrupts): Use IRQ_BASE. + (KiInterruptDispatch2): Rewrite. + (KiInterruptDispatch): Ditto. + (KeConnectInterrupt): Pass Vector to HalEnableSystemInterrupt() for MP. + (KeDisconnectInterrupt): Pass Vector to HalDisableSystemInterrupt() for MP. + * ntoskrnl/ke/i386/trap.s (_KiTrapProlog): Change 0x124 to KPCR_CURRENT_THREAD. + 2003-04-06 Casper S. Hornstrup * Makefile: Add format. diff --git a/reactos/drivers/storage/atapi/atapi.c b/reactos/drivers/storage/atapi/atapi.c index 71034510320..5ebea8323a9 100644 --- a/reactos/drivers/storage/atapi/atapi.c +++ b/reactos/drivers/storage/atapi/atapi.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: atapi.c,v 1.37 2003/01/30 22:08:15 ekohl Exp $ +/* $Id: atapi.c,v 1.38 2003/04/06 10:45:15 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS ATAPI miniport driver @@ -2174,6 +2174,9 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow); IDEWriteDriveHead(DeviceExtension->CommandPortBase, IDE_DH_FIXED | DrvHead); + /* Indicate expecting an interrupt. */ + DeviceExtension->ExpectingInterrupt = TRUE; + /* Issue command to drive */ IDEWriteCommand(DeviceExtension->CommandPortBase, Command); @@ -2224,8 +2227,6 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, TransferSize); } } - /* Indicate expecting an interrupt. */ - DeviceExtension->ExpectingInterrupt = TRUE; DPRINT("AtapiReadWrite() done!\n"); diff --git a/reactos/hal/halx86/include/mps.h b/reactos/hal/halx86/include/mps.h index 6fc8e47ccb2..0311bcab0f2 100644 --- a/reactos/hal/halx86/include/mps.h +++ b/reactos/hal/halx86/include/mps.h @@ -1,6 +1,16 @@ #ifndef __INCLUDE_HAL_MPS #define __INCLUDE_HAL_MPS +/* + * FIXME: This does not work if we have more than 24 IRQs (ie. more than one + * I/O APIC) + */ +#define VECTOR2IRQ(vector) (((vector) - FIRST_DEVICE_VECTOR) / 8) +#define IRQ2VECTOR(vector) ((vector * 8) + FIRST_DEVICE_VECTOR) +#define VECTOR2IRQL(vector) (DISPATCH_LEVEL /* 2 */ + 1 + VECTOR2IRQ(vector)) +#define IRQL2VECTOR(irql) (IRQ2VECTOR(irql - DISPATCH_LEVEL /* 2 */ - 1)) + + #define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */ #define IOAPIC_DEFAULT_BASE 0xFEC00000 /* Default I/O APIC Base Register Address */ diff --git a/reactos/hal/halx86/isa.c b/reactos/hal/halx86/isa.c index d039adb6edb..a611eea3663 100644 --- a/reactos/hal/halx86/isa.c +++ b/reactos/hal/halx86/isa.c @@ -1,4 +1,4 @@ -/* $Id: isa.c,v 1.4 2002/12/09 19:44:44 hbirr Exp $ +/* $Id: isa.c,v 1.5 2003/04/06 10:45:15 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -11,8 +11,12 @@ /* INCLUDES ***************************************************************/ +#include #include #include +#ifdef MP +#include +#endif /* FUNCTIONS *****************************************************************/ @@ -67,8 +71,14 @@ HalpGetIsaInterruptVector(PVOID BusHandler, PKIRQL Irql, PKAFFINITY Affinity) { +#ifdef MP + *Irql = PROFILE_LEVEL - BusInterruptVector; + *Affinity = 0xFFFFFFFF; + return IRQ2VECTOR(BusInterruptVector); +#else *Irql = PROFILE_LEVEL - BusInterruptVector; *Affinity = 0xFFFFFFFF; return BusInterruptVector; +#endif } /* EOF */ diff --git a/reactos/hal/halx86/mp.c b/reactos/hal/halx86/mp.c index aeceeb90272..ab7caf6171f 100644 --- a/reactos/hal/halx86/mp.c +++ b/reactos/hal/halx86/mp.c @@ -1,4 +1,4 @@ -/* $Id: mp.c,v 1.6 2002/12/26 17:36:12 robd Exp $ +/* $Id: mp.c,v 1.7 2003/04/06 10:45:15 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -82,7 +82,8 @@ extern VOID MpsSpuriousInterrupt(VOID); WRITE_PORT_UCHAR((PUCHAR)0x71, value); \ }) -BOOLEAN MPSInitialized = FALSE; /* Is the MP system initialized? */ +static BOOLEAN MPSInitialized = FALSE; /* Is the MP system initialized? */ +static KDPC RescheduleDpc; VOID APICDisable(VOID); static VOID APICSyncArbIDs(VOID); @@ -96,8 +97,7 @@ ULONG lastvalw = 0; #endif /* MP */ -BOOLEAN BSPInitialized = FALSE; /* Is the BSP initialized? */ - +static BOOLEAN BSPInitialized = FALSE; /* Is the BSP initialized? */ /* FUNCTIONS *****************************************************************/ @@ -148,12 +148,10 @@ volatile ULONG IOAPICRead( PULONG Base; Base = (PULONG)IOAPICMap[Apic].ApicAddress; - - *Base = Offset; - return *((PULONG)((ULONG)Base + IOAPIC_IOWIN)); + *Base = Offset; + return *((PULONG)((ULONG)Base + IOAPIC_IOWIN)); } - VOID IOAPICWrite( ULONG Apic, ULONG Offset, @@ -162,9 +160,8 @@ VOID IOAPICWrite( PULONG Base; Base = (PULONG)IOAPICMap[Apic].ApicAddress; - *Base = Offset; - *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value; + *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value; } @@ -179,6 +176,7 @@ VOID IOAPICClearPin( */ memset(&Entry, 0, sizeof(Entry)); Entry.mask = 1; + IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0)); IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1)); } @@ -210,6 +208,7 @@ VOID IOAPICMaskIrq( *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq); Entry.mask = 1; + IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry)); } @@ -223,6 +222,7 @@ VOID IOAPICUnmaskIrq( *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq); Entry.mask = 0; + IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry)); } @@ -268,7 +268,7 @@ IOAPICSetupIds(VOID) tmp &= ~IOAPIC_ID_MASK; tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId); - + IOAPICWrite(apic, IOAPIC_ID, tmp); /* @@ -582,25 +582,26 @@ static ULONG IOAPICGetIrqEntry( static ULONG AssignIrqVector( ULONG irq) { - static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0; + static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0; ULONG vector; /* There may already have been assigned a vector for this IRQ */ vector = IRQVectorMap[irq]; - if (vector > 0) - return vector; + if (vector > 0) + return vector; - current_vector += 8; if (current_vector > FIRST_SYSTEM_VECTOR) { - vector_offset++; + vector_offset++; current_vector = FIRST_DEVICE_VECTOR + vector_offset; } else if (current_vector == FIRST_SYSTEM_VECTOR) { DPRINT1("Ran out of interrupt sources!"); KeBugCheck(0); } - IRQVectorMap[irq] = current_vector; - return current_vector; + vector = current_vector; + IRQVectorMap[irq] = vector; + current_vector += 8; + return vector; } @@ -651,6 +652,8 @@ VOID IOAPICSetupIrqs( vector = AssignIrqVector(irq); entry.vector = vector; + DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq); + if (irq == 0) { /* Mask timer IRQ */ @@ -1167,7 +1170,6 @@ VOID WaitFor8254Wraparound(VOID) LONG Delta; CurCount = Read8254Timer(); - do { PrevCount = CurCount; CurCount = Read8254Timer(); @@ -1235,8 +1237,8 @@ VOID APICCalibrateTimer( /* Setup timer for normal operation */ //APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100); // 100ns - APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 15000); // 15ms - //APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms +// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 15000); // 15ms + APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms DPRINT("CPU clock speed is %ld.%04ld MHz.\n", CPUMap[CPU].CoreSpeed/1000000, @@ -1374,37 +1376,52 @@ VOID MpsTimerHandler( { #if 0 KIRQL OldIrql; -#endif - DPRINT("T1"); + DPRINT("T:\n"); + + /* + * Notify the rest of the kernel of the raised irq level + */ + //OldIrql = KeRaiseIrqlToSynchLevel(); + KeRaiseIrql(PROFILE_LEVEL, &OldIrql); + + /* + * Enable interrupts + * NOTE: Only higher priority interrupts will get through + */ + __asm__("sti\n\t"); + + if (KeGetCurrentProcessorNumber() == 0) + { + //KIRQL OldIrql2; + //KeLowerIrql(PROFILE_LEVEL); + KiInterruptDispatch2(OldIrql, 0); + //KeRaiseIrql(CLOCK2_LEVEL, &OldIrql2); + } + + DbgPrint("MpsTimerHandler() called at IRQL 0x%.08x\n", OldIrql); + //(BOOLEAN) KeInsertQueueDpc(&RescheduleDpc, NULL, NULL); + + DbgPrint("MpsTimerHandler() -1 IRQL 0x%.08x\n", OldIrql); + + /* + * Disable interrupts + */ + __asm__("cli\n\t"); + + DbgPrint("MpsTimerHandler() 0 IRQL 0x%.08x\n", OldIrql); /* * Acknowledge the interrupt */ APICSendEOI(); -#if 0 - /* - * Notify the rest of the kernel of the raised irq level - */ - OldIrql = KeRaiseIrqlToSynchLevel(); -#endif - __asm__("sti\n\t"); - /* - * Call the dispatcher - */ - // TODO FIXME - What happened to definition for PsDispatchThread ??? - //PsDispatchThread(THREAD_STATE_READY); - - // KeGetCurrentThread is linked into hal from ntoskrnl, so can - // PsDispatchThread be exported from ntoskrnl also ??? - - -#if 0 /* * Lower irq level */ + DbgPrint("MpsTimerHandler() 1 IRQL 0x%.08x\n", OldIrql); KeLowerIrql(OldIrql); + DbgPrint("MpsTimerHandler() 2 IRQL 0x%.08x\n", OldIrql); #endif } @@ -1445,10 +1462,8 @@ VOID MpsSpuriousHandler( { DPRINT1("Spurious interrupt on CPU(%d)\n", ThisCPU()); - /* - * Acknowledge the interrupt - */ - APICSendEOI(); + /* No need to send EOI here */ + APICDump(); for (;;); } @@ -1494,7 +1509,7 @@ VOID APICSetup( APICWrite(APIC_SIVR, tmp); /* - * Only the BP should see the LINT1 NMI signal, obviously. + * Only the BSP should see the LINT1 NMI signal, obviously. */ if (CPU == 0) tmp = APIC_DM_NMI; @@ -1744,7 +1759,8 @@ HalAllProcessorsStarted ( #ifdef MP - return (NextCPU >= CPUCount); + //return (NextCPU >= CPUCount); + return (NextCPU >= 1); #else /* MP */ @@ -2214,6 +2230,7 @@ static VOID HaliConstructDefaultISAMPTable( } } + BOOLEAN HaliScanForMPConfigTable( ULONG Base, @@ -2301,6 +2318,22 @@ HaliScanForMPConfigTable( } +static VOID STDCALL +RescheduleDpcRoutine(PKDPC Dpc, PVOID DeferredContext, + PVOID SystemArgument1, PVOID SystemArgument2) +{ + KIRQL OldIrql; + KIRQL NewIrql; + + DbgPrint("RDR()"); + NewIrql = KeGetCurrentIrql(); + KeLowerIrql(APC_LEVEL); + KeRescheduleThread(); + KeRaiseIrql(NewIrql, &OldIrql); + DbgPrint("...\n"); +} + + VOID HalpInitMPS( VOID) @@ -2328,6 +2361,8 @@ HalpInitMPS( MPSInitialized = TRUE; + KeInitializeDpc(&RescheduleDpc, RescheduleDpcRoutine, NULL); + /* Scan the system memory for an MP configuration table 1) Scan the first KB of system base memory @@ -2350,7 +2385,7 @@ HalpInitMPS( } /* Setup IRQ to vector translation map */ - memset(&IRQVectorMap, sizeof(IRQVectorMap), 0); + memset(&IRQVectorMap, 0, sizeof(IRQVectorMap)); /* Initialize the bootstrap processor */ HaliInitBSP(); diff --git a/reactos/hal/halx86/mpsirql.c b/reactos/hal/halx86/mpsirql.c index fbb47d77d72..b1c078017de 100644 --- a/reactos/hal/halx86/mpsirql.c +++ b/reactos/hal/halx86/mpsirql.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #define NDEBUG @@ -21,117 +22,131 @@ /* GLOBALS ******************************************************************/; +#define IRQ_BASE (0x30) +#define NR_VECTORS (0x100 - IRQ_BASE) + extern IMPORTED ULONG DpcQueueSize; -static VOID KeSetCurrentIrql(KIRQL newlvl); +static ULONG HalpPendingInterruptCount[NR_VECTORS]; + +static VOID KeSetCurrentIrql (KIRQL newlvl); + +VOID STDCALL +KiInterruptDispatch2 (ULONG Irq, KIRQL old_level); + +#define IRQL2TPR(irql) (FIRST_DEVICE_VECTOR + ((irql - DISPATCH_LEVEL /* 2 */ - 1) * 8)) /* FUNCTIONS ****************************************************************/ -#define IRQL2TPR(irql) (APIC_TPR_MIN + ((irql - DISPATCH_LEVEL - 1) * 8)) - -static VOID HiSetCurrentPriority( - ULONG Priority) -{ - //DbgPrint(" P(0x%X)\n", Priority); - APICWrite(APIC_TPR, Priority & APIC_TPR_PRI); -} - - -static VOID HiSwitchIrql(KIRQL OldIrql, ULONG Flags) -/* - * FUNCTION: Switches to the current irql - * NOTE: Must be called with interrupt disabled - */ -{ - PKTHREAD CurrentThread; - KIRQL CurrentIrql; - - //DbgPrint("HiSwitchIrql(OldIrql %d)\n", OldIrql); - - CurrentIrql = KeGetCurrentKPCR()->Irql; - - if (CurrentIrql >= IPI_LEVEL) - { - /* Block all interrupts */ - HiSetCurrentPriority(APIC_TPR_MAX); - return; - } - - if (CurrentIrql == CLOCK2_LEVEL) - { - HiSetCurrentPriority(APIC_TPR_MAX - 16); - popfl(Flags); - return; - } - - if (CurrentIrql > DISPATCH_LEVEL) - { - HiSetCurrentPriority(IRQL2TPR(CurrentIrql)); - popfl(Flags); - return; - } - - /* Pass all interrupts */ - HiSetCurrentPriority(0); - - if (CurrentIrql == DISPATCH_LEVEL) - { - popfl(Flags); - return; - } - - if (CurrentIrql == APC_LEVEL) - { - if (DpcQueueSize > 0 ) - { - KeSetCurrentIrql(DISPATCH_LEVEL); - __asm__("sti\n\t"); - KiDispatchInterrupt(); - __asm__("cli\n\t"); - KeSetCurrentIrql(PASSIVE_LEVEL); - } - popfl(Flags); - return; - } - - CurrentThread = KeGetCurrentThread(); - - if (CurrentIrql == PASSIVE_LEVEL && - CurrentThread != NULL && - CurrentThread->ApcState.KernelApcPending) - { - KeSetCurrentIrql(APC_LEVEL); - __asm__("sti\n\t"); - KiDeliverApc(0, 0, 0); - __asm__("cli\n\t"); - KeSetCurrentIrql(PASSIVE_LEVEL); - popfl(Flags); - } - else - { - popfl(Flags); - } -} - - KIRQL STDCALL KeGetCurrentIrql (VOID) /* * PURPOSE: Returns the current irq level * RETURNS: The current irq level */ { - return(KeGetCurrentKPCR()->Irql); + if (KeGetCurrentKPCR ()->Irql > HIGH_LEVEL) + { + DPRINT1 ("CurrentIrql %x\n", KeGetCurrentKPCR ()->Irql); + KeBugCheck (0); + for(;;); + } + + return(KeGetCurrentKPCR ()->Irql); } -static VOID KeSetCurrentIrql(KIRQL newlvl) +static VOID KeSetCurrentIrql (KIRQL NewIrql) /* * PURPOSE: Sets the current irq level without taking any action */ { -// DPRINT("KeSetCurrentIrql(newlvl %x)\n",newlvl); + if (NewIrql > HIGH_LEVEL) + { + DPRINT1 ("NewIrql %x\n", NewIrql); + KeBugCheck (0); + for(;;); + } - KeGetCurrentKPCR()->Irql = newlvl; + KeGetCurrentKPCR ()->Irql = NewIrql; +} + + +VOID HalpEndSystemInterrupt (KIRQL Irql) +/* + * FUNCTION: Enable all irqs with higher priority. + */ +{ + /* Interrupts should be disabled while enabling irqs */ + __asm__("pushf\n\t"); + __asm__("cli\n\t"); + APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI); + __asm__("popf\n\t"); +} + + +VOID STATIC +HalpExecuteIrqs(KIRQL NewIrql) +{ + ULONG VectorLimit, i; + + VectorLimit = min(IRQL2VECTOR (NewIrql), NR_VECTORS); + + /* + * For each vector if there have been any deferred interrupts then now + * dispatch them. + */ + for (i = 0; i < VectorLimit; i++) + { + if (HalpPendingInterruptCount[i] > 0) + { + KeSetCurrentIrql (VECTOR2IRQL (i)); + + while (HalpPendingInterruptCount[i] > 0) + { + /* + * For each deferred interrupt execute all the handlers at DIRQL. + */ + KiInterruptDispatch2 (i, NewIrql); + HalpPendingInterruptCount[i]--; + } + KeSetCurrentIrql (KeGetCurrentIrql () - 1); + HalpEndSystemInterrupt (KeGetCurrentIrql ()); + } + } + +} + + +VOID STATIC +HalpLowerIrql(KIRQL NewIrql) +{ + if (NewIrql >= PROFILE_LEVEL) + { + KeSetCurrentIrql (NewIrql); + return; + } + HalpExecuteIrqs (NewIrql); + if (NewIrql >= DISPATCH_LEVEL) + { + KeSetCurrentIrql (NewIrql); + return; + } + KeSetCurrentIrql (DISPATCH_LEVEL); + if (DpcQueueSize > 0) + { + KiDispatchInterrupt (); + } + KeSetCurrentIrql (APC_LEVEL); + if (NewIrql == APC_LEVEL) + { + return; + } + if (KeGetCurrentThread () != NULL && + KeGetCurrentThread ()->ApcState.KernelApcPending) + { + KiDeliverApc (0, 0, 0); + } + KeSetCurrentIrql (PASSIVE_LEVEL); } @@ -151,34 +166,19 @@ static VOID KeSetCurrentIrql(KIRQL newlvl) * NOTES * Uses fastcall convention */ - VOID FASTCALL -KfLowerIrql ( - KIRQL NewIrql - ) +KfLowerIrql (KIRQL NewIrql) { - KIRQL CurrentIrql; KIRQL OldIrql; - ULONG Flags; - //DbgPrint("KfLowerIrql(NewIrql %d)\n", NewIrql); - - pushfl(Flags); - __asm__ ("\n\tcli\n\t"); - - CurrentIrql = KeGetCurrentKPCR()->Irql; - - if (NewIrql > CurrentIrql) + if (NewIrql > KeGetCurrentIrql ()) { - DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n", - __FILE__, __LINE__, NewIrql, CurrentIrql); - KeBugCheck(0); + DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, KeGetCurrentIrql ()); + KeBugCheck (0); for(;;); } - OldIrql = CurrentIrql; - KeGetCurrentKPCR()->Irql = NewIrql; - HiSwitchIrql(OldIrql, Flags); + HalpLowerIrql (NewIrql); } @@ -198,13 +198,10 @@ KfLowerIrql ( * NOTES */ -VOID -STDCALL -KeLowerIrql ( - KIRQL NewIrql - ) +VOID STDCALL +KeLowerIrql (KIRQL NewIrql) { - KfLowerIrql (NewIrql); + KfLowerIrql (NewIrql); } @@ -225,37 +222,21 @@ KeLowerIrql ( * Uses fastcall convention */ -KIRQL -FASTCALL -KfRaiseIrql ( - KIRQL NewIrql - ) +KIRQL FASTCALL +KfRaiseIrql (KIRQL NewIrql) { - KIRQL CurrentIrql; KIRQL OldIrql; - ULONG Flags; - - //DbgPrint("KfRaiseIrql(NewIrql %d)\n", NewIrql); - - pushfl(Flags); - __asm__ ("\n\tcli\n\t"); - - CurrentIrql = KeGetCurrentKPCR()->Irql; - - if (NewIrql < CurrentIrql) - { - DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n", - __FILE__,__LINE__,CurrentIrql,NewIrql); - KeBugCheck (0); - for(;;); - } - - OldIrql = CurrentIrql; - KeGetCurrentKPCR()->Irql = NewIrql; - - //DPRINT("NewIrql %x OldIrql %x\n", NewIrql, OldIrql); - HiSwitchIrql(OldIrql, Flags); - return OldIrql; + + if (NewIrql < KeGetCurrentIrql ()) + { + DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql); + KeBugCheck (0); + for(;;); + } + + OldIrql = KeGetCurrentIrql (); + KeSetCurrentIrql (NewIrql); + return OldIrql; } @@ -276,15 +257,11 @@ KfRaiseIrql ( * NOTES * Calls KfRaiseIrql */ - -VOID -STDCALL -KeRaiseIrql ( - KIRQL NewIrql, - PKIRQL OldIrql - ) +VOID STDCALL +KeRaiseIrql (KIRQL NewIrql, + PKIRQL OldIrql) { - *OldIrql = KfRaiseIrql (NewIrql); + *OldIrql = KfRaiseIrql (NewIrql); } @@ -305,11 +282,10 @@ KeRaiseIrql ( * Calls KfRaiseIrql */ -KIRQL -STDCALL +KIRQL STDCALL KeRaiseIrqlToDpcLevel (VOID) { - return KfRaiseIrql (DISPATCH_LEVEL); + return KfRaiseIrql (DISPATCH_LEVEL); } @@ -330,88 +306,91 @@ KeRaiseIrqlToDpcLevel (VOID) * Calls KfRaiseIrql */ -KIRQL -STDCALL +KIRQL STDCALL KeRaiseIrqlToSynchLevel (VOID) { - return KfRaiseIrql (CLOCK2_LEVEL); + return KfRaiseIrql (CLOCK2_LEVEL); } -BOOLEAN STDCALL HalBeginSystemInterrupt (ULONG Vector, - KIRQL Irql, - PKIRQL OldIrql) +BOOLEAN STDCALL +HalBeginSystemInterrupt (ULONG Vector, + KIRQL Irql, + PKIRQL OldIrql) { - DPRINT("Vector (0x%X) Irql (0x%X)\n", - Vector, Irql); + DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql); if (Vector < FIRST_DEVICE_VECTOR || - Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { + Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { DPRINT("Not a device interrupt\n"); return FALSE; } - /* - * Acknowledge the interrupt - */ + HalDisableSystemInterrupt (Vector, 0); + APICSendEOI(); - *OldIrql = KeGetCurrentIrql(); + if (KeGetCurrentIrql () >= Irql) + { + HalpPendingInterruptCount[Vector]++; + return(FALSE); + } + *OldIrql = KeGetCurrentIrql (); + KeSetCurrentIrql (Irql); - KeSetCurrentIrql(Irql); - - return TRUE; + 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); + HalpEndSystemInterrupt (Irql); } - - -BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector, - ULONG Unknown2) + +BOOLEAN STDCALL +HalDisableSystemInterrupt (ULONG Vector, + ULONG Unknown2) { ULONG irq; - DPRINT("Vector (0x%X)\n", Vector); + DPRINT ("Vector (0x%X)\n", Vector); if (Vector < FIRST_DEVICE_VECTOR || - Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { - DPRINT("Not a device interrupt\n"); - return FALSE; - } - // TODO FIXME - What happened to definition for VECTOR2IRQ ??? - //irq = VECTOR2IRQ(Vector); - - IOAPICMaskIrq(0, irq); - - return TRUE; -} - - -BOOLEAN STDCALL HalEnableSystemInterrupt (ULONG Vector, - ULONG Unknown2, - ULONG Unknown3) -{ - ULONG irq; - - DPRINT("Vector (0x%X)\n", Vector); - - if (Vector < FIRST_DEVICE_VECTOR || - Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { + Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { DPRINT("Not a device interrupt\n"); return FALSE; } - // TODO FIXME - What happened to definition for VECTOR2IRQ ??? - //irq = VECTOR2IRQ(Vector); + irq = VECTOR2IRQ (Vector); + IOAPICMaskIrq (ThisCPU (), irq); - IOAPICUnmaskIrq(0, irq); + return TRUE; +} + + +BOOLEAN STDCALL +HalEnableSystemInterrupt (ULONG Vector, + ULONG Unknown2, + ULONG Unknown3) +{ + ULONG irq; + + DPRINT ("Vector (0x%X)\n", Vector); + + if (Vector < FIRST_DEVICE_VECTOR || + Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { + DPRINT("Not a device interrupt\n"); + return FALSE; + } + + irq = VECTOR2IRQ (Vector); + IOAPICUnmaskIrq (ThisCPU (), irq); return TRUE; } - -/* EOF */ diff --git a/reactos/hal/halx86/pci.c b/reactos/hal/halx86/pci.c index 67ba8717bd2..6ffb7980fe0 100644 --- a/reactos/hal/halx86/pci.c +++ b/reactos/hal/halx86/pci.c @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.7 2003/02/17 21:24:13 gvg Exp $ +/* $Id: pci.c,v 1.8 2003/04/06 10:45:15 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -18,8 +18,13 @@ /* INCLUDES *****************************************************************/ +#include #include #include +#ifdef MP +#include +#endif + #define NDEBUG #include @@ -546,9 +551,15 @@ HalpGetPciInterruptVector(PVOID BusHandler, PKIRQL Irql, PKAFFINITY Affinity) { +#ifdef MP + *Irql = PROFILE_LEVEL - BusInterruptVector; + *Affinity = 0xFFFFFFFF; + return IRQ2VECTOR(BusInterruptVector); +#else *Irql = PROFILE_LEVEL - BusInterruptVector; *Affinity = 0xFFFFFFFF; return BusInterruptVector; +#endif } static BOOLEAN STDCALL diff --git a/reactos/hal/halx86/sysbus.c b/reactos/hal/halx86/sysbus.c index 83dec2be37c..5a55370a354 100644 --- a/reactos/hal/halx86/sysbus.c +++ b/reactos/hal/halx86/sysbus.c @@ -1,4 +1,4 @@ -/* $Id: sysbus.c,v 1.4 2002/12/09 19:46:39 hbirr Exp $ +/* $Id: sysbus.c,v 1.5 2003/04/06 10:45:15 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -11,8 +11,12 @@ /* INCLUDES *****************************************************************/ +#include #include #include +#ifdef MP +#include +#endif /* FUNCTIONS ****************************************************************/ @@ -25,9 +29,15 @@ HalpGetSystemInterruptVector(PVOID BusHandler, PKIRQL Irql, PKAFFINITY Affinity) { - *Irql = PROFILE_LEVEL - BusInterruptVector; - *Affinity = 0xFFFFFFFF; - return BusInterruptVector; +#ifdef MP + *Irql = PROFILE_LEVEL - BusInterruptVector; + *Affinity = 0xFFFFFFFF; + return IRQ2VECTOR(BusInterruptVector); +#else + *Irql = PROFILE_LEVEL - BusInterruptVector; + *Affinity = 0xFFFFFFFF; + return BusInterruptVector; +#endif } diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index e41a3e88ffc..7cc8aad47c5 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -36,6 +36,8 @@ struct _KTHREAD; +VOID STDCALL KeRescheduleThread(); + VOID KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip); VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait); diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index d85a9ebf512..a5918d8d7c5 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -538,7 +538,6 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) { return(0); } - } /* @@ -629,7 +628,6 @@ KeInitExceptions(VOID) set_trap_gate(11, (ULONG)KiTrap11); set_trap_gate(12, (ULONG)KiTrap12); set_trap_gate(13, (ULONG)KiTrap13); - set_trap_gate(14, (ULONG)KiTrap14); set_interrupt_gate(14, (ULONG)KiTrap14); set_trap_gate(15, (ULONG)KiTrap15); set_trap_gate(16, (ULONG)KiTrap16); diff --git a/reactos/ntoskrnl/ke/i386/irq.c b/reactos/ntoskrnl/ke/i386/irq.c index 32989e16d33..1033c27fb96 100644 --- a/reactos/ntoskrnl/ke/i386/irq.c +++ b/reactos/ntoskrnl/ke/i386/irq.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: irq.c,v 1.28 2003/01/15 19:58:07 chorns Exp $ +/* $Id: irq.c,v 1.29 2003/04/06 10:45:16 chorns Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/i386/irq.c @@ -60,11 +60,13 @@ * FIXME: This does not work if we have more than 24 IRQs (ie. more than one * I/O APIC) */ -#define VECTOR2IRQ(vector) (((vector) - 0x31) / 8) -#define VECTOR2IRQL(vector) (4 + VECTOR2IRQ(vector)) +#define VECTOR2IRQ(vector) (((vector) - FIRST_DEVICE_VECTOR) / 8) +#define IRQ2VECTOR(vector) ((vector * 8) + FIRST_DEVICE_VECTOR) +#define VECTOR2IRQL(vector) (DISPATCH_LEVEL /* 2 */ + 1 + VECTOR2IRQ(vector)) -#define IRQ_BASE FIRST_DEVICE_VECTOR -#define NR_IRQS 0x100 - 0x30 + +#define IRQ_BASE 0x30 +#define NR_IRQS 0x100 - IRQ_BASE #define __STR(x) #x #define STR(x) __STR(x) @@ -225,8 +227,8 @@ VOID KeInitInterrupts (VOID) */ for (i=0;iServiceRoutine(isr, isr->ServiceContext)) { current = current->Flink; @@ -335,12 +338,10 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) * ARGUMENTS: * Vector = Interrupt vector * Trapframe = CPU context + * NOTES: Interrupts are disabled at this point. */ { KIRQL old_level; - PKINTERRUPT isr; - PLIST_ENTRY current; - ULONG irq; #ifdef DBG @@ -351,16 +352,22 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) #endif /* DBG */ - DPRINT("I(%d) ", Vector); + DbgPrint("V(0x%.02x)", Vector); /* * Notify the rest of the kernel of the raised irq level */ - HalBeginSystemInterrupt (Vector, + if (!HalBeginSystemInterrupt (Vector, VECTOR2IRQL(Vector), - &old_level); + &old_level)) + { + return; + } - irq = VECTOR2IRQ(Vector); + /* + * Mask the related irq + */ + //HalDisableSystemInterrupt (Vector, 0); /* * Enable interrupts @@ -368,33 +375,11 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) */ __asm__("sti\n\t"); - if (irq == 0) - { - if (KeGetCurrentProcessorNumber() == 0) - { - KiUpdateSystemTime(old_level, Trapframe->Eip); -#ifdef KDBG - KdbProfileInterrupt(Trapframe->Eip); -#endif /* KDBG */ - } - } - else - { - DPRINT("KiInterruptDispatch(Vector %d)\n", Vector); - /* - * 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); - } - } + /* + * Actually call the ISR. + */ + KiInterruptDispatch2(Vector, old_level); + /* * Disable interrupts */ @@ -403,35 +388,13 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) /* * Unmask the related irq */ - HalEnableSystemInterrupt (Vector, 0, 0); + //HalEnableSystemInterrupt (Vector, 0, 0); + + //DbgPrint("E(0x%.02x)\n", Vector); /* - * If the processor level will drop below dispatch level on return then - * issue a DPC queue drain interrupt + * End the system interrupt. */ - - __asm__("sti\n\t"); - - if (old_level < DISPATCH_LEVEL) - { - - HalEndSystemInterrupt (DISPATCH_LEVEL, 0); - - if (KeGetCurrentThread() != NULL) - { - // FIXME TODO - What happend to LastEip definition? - //KeGetCurrentThread()->LastEip = Trapframe->Eip; - } - KiDispatchInterrupt(); - if (KeGetCurrentThread() != NULL && - KeGetCurrentThread()->Alerted[1] != 0 && - Trapframe->Cs != KERNEL_CS) - { - HalEndSystemInterrupt (APC_LEVEL, 0); - KiDeliverNormalApc(); - } - } - HalEndSystemInterrupt (old_level, 0); } @@ -602,7 +565,11 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject) DPRINT("%x %x\n",isr_table[Vector].Flink,isr_table[Vector].Blink); if (IsListEmpty(&isr_table[Vector])) { - HalEnableSystemInterrupt(Vector + IRQ_BASE, 0, 0); +#ifdef MP + HalEnableSystemInterrupt(Vector, 0, 0); +#else + HalEnableSystemInterrupt(Vector + IRQ_BASE, 0, 0); +#endif } InsertTailList(&isr_table[Vector],&InterruptObject->Entry); DPRINT("%x %x\n",InterruptObject->Entry.Flink, @@ -636,7 +603,11 @@ KeDisconnectInterrupt(PKINTERRUPT InterruptObject) RemoveEntryList(&InterruptObject->Entry); if (IsListEmpty(&isr_table[InterruptObject->Vector])) { +#ifdef MP + HalDisableSystemInterrupt(InterruptObject->Vector, 0); +#else HalDisableSystemInterrupt(InterruptObject->Vector + IRQ_BASE, 0); +#endif } KeReleaseSpinLockFromDpcLevel(InterruptObject->IrqLock); KeLowerIrql(oldlvl); diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index f5374655bc3..a73678a587e 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -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: trap.s,v 1.16 2002/09/08 10:23:30 chorns Exp $ +/* $Id: trap.s,v 1.17 2003/04/06 10:45:16 chorns Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/i386/trap.s @@ -170,7 +170,7 @@ _KiTrapProlog: addl $4, %esp /* Get a pointer to the current thread */ - movl %fs:0x124, %esi + movl %fs:KPCR_CURRENT_THREAD, %esi /* Restore the old trap frame pointer */ popl %ebx diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 257410456bb..ba1007586e3 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.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: kthread.c,v 1.35 2002/10/01 19:27:21 chorns Exp $ +/* $Id: kthread.c,v 1.36 2003/04/06 10:45:16 chorns Exp $ * * FILE: ntoskrnl/ke/kthread.c * PURPOSE: Microkernel thread support @@ -236,3 +236,8 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First) */ } +VOID STDCALL +KeRescheduleThread() +{ + PsDispatchThread(THREAD_STATE_READY); +} diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index da2f4bf03f3..1f4a07fabd9 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.def,v 1.148 2003/03/20 09:45:57 gvg Exp $ +; $Id: ntoskrnl.def,v 1.149 2003/04/06 10:45:16 chorns Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -412,6 +412,7 @@ KeQuerySystemTime@4 KeQueryTickCount@4 KeQueryTimeIncrement@0 ;KeRaiseUserException +KeRescheduleThread@0 KeReadStateEvent@4 KeReadStateMutant@4 KeReadStateMutex@4 diff --git a/reactos/ntoskrnl/ntoskrnl.edf b/reactos/ntoskrnl/ntoskrnl.edf index 42099730ec2..7a6299214c2 100644 --- a/reactos/ntoskrnl/ntoskrnl.edf +++ b/reactos/ntoskrnl/ntoskrnl.edf @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.edf,v 1.134 2003/03/20 09:45:57 gvg Exp $ +; $Id: ntoskrnl.edf,v 1.135 2003/04/06 10:45:16 chorns Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -411,6 +411,7 @@ KeQuerySystemTime=KeQuerySystemTime@4 KeQueryTickCount=KeQueryTickCount@4 KeQueryTimeIncrement=KeQueryTimeIncrement@0 ;KeRaiseUserException +KeRescheduleThread=KeRescheduleThread@0 KeReadStateEvent=KeReadStateEvent@4 KeReadStateMutant=KeReadStateMutant@4 KeReadStateMutex=KeReadStateMutex@4