mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
- Finally figured out a way to make the old HAL IRQ implementation work with the new Ke Interrupt implementation without requiring my new HAL IRQ code (which doesn't work).
- Remove the "deprecated" directory from ntoskrnl since it now truly is. - Remove KeInitInterrupts hack. - Remove KiDispatchInterrupt2 export hack from kernel and stop using it from the HAL. - HAL can now be built/tested with Windows/TinyKRNL since the export hack is gone and interrupts are sent properly through the IDT. - Remove a bunch of completed krnlfun entries. - Fix progressbar during bootcd bug. svn path=/trunk/; revision=24972
This commit is contained in:
parent
495e62c516
commit
96d593c9ba
9 changed files with 128 additions and 660 deletions
|
@ -156,7 +156,7 @@ FrLdrLoadImage(IN PCHAR szFileName,
|
|||
FrLdrMapImage(FilePointer, szShortName);
|
||||
|
||||
/* Update Processbar and return success */
|
||||
UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
|
||||
if (!FrLdrBootType) UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,11 +127,130 @@ VOID HalpEndSystemInterrupt(KIRQL Irql)
|
|||
_enable();
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt30(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x30");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt31(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x31");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt32(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x32");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt33(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x33");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt34(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x34");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt35(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x35");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt36(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x36");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt37(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x37");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt38(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x38");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt39(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x39");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt3A(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x3A");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt3B(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x3B");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt3C(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x3C");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt3D(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x3D");
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt3E(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x3E");
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpHardwareInt3F(VOID)
|
||||
{
|
||||
__asm__ __volatile__ ("int $0x3F");
|
||||
}
|
||||
|
||||
|
||||
typedef VOID (*PHARDWARE_INT)(VOID);
|
||||
|
||||
PHARDWARE_INT HalpHardwareInt[NR_IRQS] =
|
||||
{
|
||||
HalpHardwareInt30,
|
||||
HalpHardwareInt31,
|
||||
HalpHardwareInt32,
|
||||
HalpHardwareInt33,
|
||||
HalpHardwareInt34,
|
||||
HalpHardwareInt35,
|
||||
HalpHardwareInt36,
|
||||
HalpHardwareInt37,
|
||||
HalpHardwareInt38,
|
||||
HalpHardwareInt39,
|
||||
HalpHardwareInt3A,
|
||||
HalpHardwareInt3B,
|
||||
HalpHardwareInt3C,
|
||||
HalpHardwareInt3D,
|
||||
HalpHardwareInt3E,
|
||||
HalpHardwareInt3F
|
||||
};
|
||||
|
||||
VOID
|
||||
HalpExecuteIrqs(KIRQL NewIrql)
|
||||
{
|
||||
ULONG IrqLimit, i;
|
||||
|
||||
IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS);
|
||||
|
||||
/*
|
||||
|
@ -150,10 +269,10 @@ HalpExecuteIrqs(KIRQL NewIrql)
|
|||
* For each deferred interrupt execute all the handlers at DIRQL.
|
||||
*/
|
||||
HalpPendingInterruptCount[i]--;
|
||||
KiInterruptDispatch2(i + IRQ_BASE, NewIrql);
|
||||
HalpHardwareInt[i]();
|
||||
}
|
||||
KeGetPcr()->Irql--;
|
||||
HalpEndSystemInterrupt(KeGetPcr()->Irql);
|
||||
//KeGetPcr()->Irql--;
|
||||
//HalpEndSystemInterrupt(KeGetPcr()->Irql);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,12 +453,13 @@ HalBeginSystemInterrupt (KIRQL Irql,
|
|||
WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (KeGetPcr()->Irql >= Irql)
|
||||
{
|
||||
HalpPendingInterruptCount[irq]++;
|
||||
return(FALSE);
|
||||
}
|
||||
#endif
|
||||
*OldIrql = KeGetPcr()->Irql;
|
||||
KeGetPcr()->Irql = Irql;
|
||||
|
||||
|
|
|
@ -29,16 +29,13 @@
|
|||
// Ke:
|
||||
// - Figure out why the DPC stack doesn't really work.
|
||||
// - Add DR macro/save and VM macro/save.
|
||||
// - New interrupt implementation.
|
||||
// - New optimized table-based tick-hashed timer implementation.
|
||||
// - New Thread Scheduler based on 2003.
|
||||
// - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
|
||||
//
|
||||
// Hal:
|
||||
// - New IRQL Implementation.
|
||||
// - New PCI/Bus Handler Implementation.
|
||||
// - CMOS Initialization and CMOS Spinlock.
|
||||
// - Timer/StallExecution Cleanup.
|
||||
// - Report resource usage to kernel (HalReportResourceUsage).
|
||||
//
|
||||
// Lpc:
|
||||
|
|
|
@ -1,543 +0,0 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ke/i386/irq.c
|
||||
* PURPOSE: Manages the Kernel's IRQ support for external drivers,
|
||||
* for the purpopses of connecting, disconnecting and setting
|
||||
* up ISRs for drivers. The backend behind the Io* Interrupt
|
||||
* routines.
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* DEPRECATED ****************************************************************/
|
||||
|
||||
#include <../hal/halx86/include/halirq.h>
|
||||
#include <../hal/halx86/include/mps.h>
|
||||
|
||||
void irq_handler_0(void);
|
||||
void irq_handler_1(void);
|
||||
void irq_handler_2(void);
|
||||
void irq_handler_3(void);
|
||||
void irq_handler_4(void);
|
||||
void irq_handler_5(void);
|
||||
void irq_handler_6(void);
|
||||
void irq_handler_7(void);
|
||||
void irq_handler_8(void);
|
||||
void irq_handler_9(void);
|
||||
void irq_handler_10(void);
|
||||
void irq_handler_11(void);
|
||||
void irq_handler_12(void);
|
||||
void irq_handler_13(void);
|
||||
void irq_handler_14(void);
|
||||
void irq_handler_15(void);
|
||||
|
||||
static unsigned int irq_handler[NR_IRQS]=
|
||||
{
|
||||
(int)&irq_handler_0,
|
||||
(int)&irq_handler_1,
|
||||
(int)&irq_handler_2,
|
||||
(int)&irq_handler_3,
|
||||
(int)&irq_handler_4,
|
||||
(int)&irq_handler_5,
|
||||
(int)&irq_handler_6,
|
||||
(int)&irq_handler_7,
|
||||
(int)&irq_handler_8,
|
||||
(int)&irq_handler_9,
|
||||
(int)&irq_handler_10,
|
||||
(int)&irq_handler_11,
|
||||
(int)&irq_handler_12,
|
||||
(int)&irq_handler_13,
|
||||
(int)&irq_handler_14,
|
||||
(int)&irq_handler_15,
|
||||
};
|
||||
|
||||
/*
|
||||
* PURPOSE: Object describing each isr
|
||||
* NOTE: The data in this table is only modified at passsive level but can
|
||||
* be accessed at any irq level.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY ListHead;
|
||||
KSPIN_LOCK Lock;
|
||||
ULONG Count;
|
||||
}
|
||||
ISR_TABLE, *PISR_TABLE;
|
||||
|
||||
static ISR_TABLE IsrTable[NR_IRQS];
|
||||
|
||||
#define TAG_ISR_LOCK TAG('I', 'S', 'R', 'L')
|
||||
|
||||
#define PRESENT (0x8000)
|
||||
#define I486_INTERRUPT_GATE (0xe00)
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
NTAPI
|
||||
KeInitInterrupts (VOID)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Setup the IDT entries to point to the interrupt handlers
|
||||
*/
|
||||
for (i=0;i<NR_IRQS;i++)
|
||||
{
|
||||
((IDT_DESCRIPTOR*)&KiIdt[IRQ_BASE+i])->a=(irq_handler[i]&0xffff)+(KGDT_R0_CODE<<16);
|
||||
((IDT_DESCRIPTOR*)&KiIdt[IRQ_BASE+i])->b=(irq_handler[i]&0xffff0000)+PRESENT+
|
||||
I486_INTERRUPT_GATE;
|
||||
{
|
||||
InitializeListHead(&IsrTable[i].ListHead);
|
||||
KeInitializeSpinLock(&IsrTable[i].Lock);
|
||||
IsrTable[i].Count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
KiInterruptDispatch2 (ULONG vector, KIRQL old_level)
|
||||
/*
|
||||
* FUNCTION: Calls all the interrupt handlers for a given irq.
|
||||
* ARGUMENTS:
|
||||
* vector - The number of the vector to call handlers for.
|
||||
* old_level - The irql of the processor when the irq took place.
|
||||
* NOTES: Must be called at DIRQL.
|
||||
*/
|
||||
{
|
||||
PKINTERRUPT isr;
|
||||
PLIST_ENTRY current;
|
||||
KIRQL oldlvl;
|
||||
PISR_TABLE CurrentIsr;
|
||||
|
||||
/*
|
||||
* Iterate the list until one of the isr tells us its device interrupted
|
||||
*/
|
||||
CurrentIsr = &IsrTable[vector - IRQ_BASE];
|
||||
|
||||
KiAcquireSpinLock(&CurrentIsr->Lock);
|
||||
|
||||
CurrentIsr->Count++;
|
||||
current = CurrentIsr->ListHead.Flink;
|
||||
|
||||
while (current != &CurrentIsr->ListHead)
|
||||
{
|
||||
isr = CONTAINING_RECORD(current,KINTERRUPT,InterruptListEntry);
|
||||
oldlvl = KeAcquireInterruptSpinLock(isr);
|
||||
if (isr->ServiceRoutine(isr, isr->ServiceContext))
|
||||
{
|
||||
KeReleaseInterruptSpinLock(isr, oldlvl);
|
||||
break;
|
||||
}
|
||||
KeReleaseInterruptSpinLock(isr, oldlvl);
|
||||
current = current->Flink;
|
||||
}
|
||||
KiReleaseSpinLock(&CurrentIsr->Lock);
|
||||
}
|
||||
|
||||
VOID
|
||||
KiInterruptDispatch3 (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
|
||||
/*
|
||||
* FUNCTION: Calls the irq specific handler for an irq
|
||||
* ARGUMENTS:
|
||||
* irq = IRQ that has interrupted
|
||||
*/
|
||||
{
|
||||
KIRQL old_level;
|
||||
PKTHREAD CurrentThread;
|
||||
|
||||
/*
|
||||
* At this point we have interrupts disabled, nothing has been done to
|
||||
* the PIC.
|
||||
*/
|
||||
KeGetCurrentPrcb()->InterruptCount++;
|
||||
|
||||
/*
|
||||
* 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 (VECTOR2IRQL(vector),
|
||||
vector,
|
||||
&old_level))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable interrupts
|
||||
* NOTE: Only higher priority interrupts will get through
|
||||
*/
|
||||
_enable();
|
||||
|
||||
ASSERT (VECTOR2IRQ(vector) != 0);
|
||||
|
||||
/*
|
||||
* Actually call the ISR.
|
||||
*/
|
||||
KiInterruptDispatch2(vector, old_level);
|
||||
|
||||
/*
|
||||
* End the system interrupt.
|
||||
*/
|
||||
_disable();
|
||||
|
||||
if (old_level==PASSIVE_LEVEL && Trapframe->Cs != KGDT_R0_CODE)
|
||||
{
|
||||
HalEndSystemInterrupt (APC_LEVEL, 0);
|
||||
|
||||
CurrentThread = KeGetCurrentThread();
|
||||
if (CurrentThread!=NULL && CurrentThread->ApcState.UserApcPending)
|
||||
{
|
||||
ASSERT (CurrentThread->TrapFrame);
|
||||
|
||||
_enable();
|
||||
KiDeliverApc(UserMode, NULL, NULL);
|
||||
_disable();
|
||||
|
||||
ASSERT(KeGetCurrentThread() == CurrentThread);
|
||||
ASSERT (CurrentThread->TrapFrame);
|
||||
}
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
HalEndSystemInterrupt (old_level, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiGetVectorDispatch(IN ULONG Vector,
|
||||
IN PDISPATCH_INFO Dispatch)
|
||||
{
|
||||
PKINTERRUPT_ROUTINE Handler;
|
||||
ULONG Current;
|
||||
|
||||
/* Setup the unhandled dispatch */
|
||||
Dispatch->NoDispatch = (PVOID)(((ULONG_PTR)&KiStartUnexpectedRange) +
|
||||
(Vector - PRIMARY_VECTOR_BASE) *
|
||||
KiUnexpectedEntrySize);
|
||||
|
||||
/* Setup the handlers */
|
||||
Dispatch->InterruptDispatch = KiInterruptDispatch;
|
||||
Dispatch->FloatingDispatch = NULL; // Floating Interrupts are not supported
|
||||
Dispatch->ChainedDispatch = KiChainedDispatch;
|
||||
Dispatch->FlatDispatch = NULL;
|
||||
|
||||
/* Get the current handler */
|
||||
Current = ((((PKIPCR)KeGetPcr())->IDT[Vector].ExtendedOffset << 16)
|
||||
& 0xFFFF0000) |
|
||||
(((PKIPCR)KeGetPcr())->IDT[Vector].Offset & 0xFFFF);
|
||||
|
||||
/* Set the interrupt */
|
||||
Dispatch->Interrupt = CONTAINING_RECORD(Current,
|
||||
KINTERRUPT,
|
||||
DispatchCode);
|
||||
|
||||
/* Check what this interrupt is connected to */
|
||||
if ((PKINTERRUPT_ROUTINE)Current == Dispatch->NoDispatch)
|
||||
{
|
||||
/* Not connected */
|
||||
Dispatch->Type = NoConnect;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the handler */
|
||||
Handler = Dispatch->Interrupt->DispatchAddress;
|
||||
if (Handler == Dispatch->ChainedDispatch)
|
||||
{
|
||||
/* It's a chained interrupt */
|
||||
Dispatch->Type = ChainConnect;
|
||||
}
|
||||
else if ((Handler == Dispatch->InterruptDispatch) ||
|
||||
(Handler == Dispatch->FloatingDispatch))
|
||||
{
|
||||
/* It's unchained */
|
||||
Dispatch->Type = NormalConnect;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unknown */
|
||||
Dispatch->Type = UnknownConnect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiConnectVectorToInterrupt(IN PKINTERRUPT Interrupt,
|
||||
IN CONNECT_TYPE Type)
|
||||
{
|
||||
DISPATCH_INFO Dispatch;
|
||||
PKINTERRUPT_ROUTINE Handler;
|
||||
PULONG Patch = &Interrupt->DispatchCode[0];
|
||||
|
||||
/* Get vector data */
|
||||
KiGetVectorDispatch(Interrupt->Vector, &Dispatch);
|
||||
|
||||
/* Check if we're only disconnecting */
|
||||
if (Type == NoConnect)
|
||||
{
|
||||
/* Set the handler to NoDispatch */
|
||||
Handler = Dispatch.NoDispatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the right handler */
|
||||
Handler = (Type == NormalConnect) ?
|
||||
Dispatch.InterruptDispatch:
|
||||
Dispatch.ChainedDispatch;
|
||||
ASSERT(Interrupt->FloatingSave == FALSE);
|
||||
|
||||
/* Set the handler */
|
||||
Interrupt->DispatchAddress = Handler;
|
||||
|
||||
/* Jump to the last 4 bytes */
|
||||
Patch = (PULONG)((ULONG_PTR)Patch +
|
||||
((ULONG_PTR)&KiInterruptTemplateDispatch -
|
||||
(ULONG_PTR)KiInterruptTemplate) - 4);
|
||||
|
||||
/* Apply the patch */
|
||||
*Patch = (ULONG)((ULONG_PTR)Handler - ((ULONG_PTR)Patch + 4));
|
||||
|
||||
/* Now set the final handler address */
|
||||
ASSERT(Dispatch.FlatDispatch == NULL);
|
||||
Handler = (PVOID)&Interrupt->DispatchCode;
|
||||
}
|
||||
|
||||
/* Set the pointer in the IDT */
|
||||
((PKIPCR)KeGetPcr())->IDT[Interrupt->Vector].ExtendedOffset =
|
||||
(USHORT)(((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
||||
((PKIPCR)KeGetPcr())->IDT[Interrupt->Vector].Offset =
|
||||
(USHORT)PtrToUlong(Handler);
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
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)
|
||||
{
|
||||
ULONG i;
|
||||
PULONG DispatchCode = &Interrupt->DispatchCode[0], Patch = DispatchCode;
|
||||
|
||||
/* Set the Interrupt Header */
|
||||
Interrupt->Type = InterruptObject;
|
||||
Interrupt->Size = sizeof(KINTERRUPT);
|
||||
|
||||
/* Check if we got a spinlock */
|
||||
if (SpinLock)
|
||||
{
|
||||
/* Use the spinlock given to us */
|
||||
Interrupt->ActualLock = SpinLock;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This means we'll be using the built-in one */
|
||||
KeInitializeSpinLock(&Interrupt->SpinLock);
|
||||
Interrupt->ActualLock = &Interrupt->SpinLock;
|
||||
}
|
||||
|
||||
/* Set the other settings */
|
||||
Interrupt->ServiceRoutine = ServiceRoutine;
|
||||
Interrupt->ServiceContext = ServiceContext;
|
||||
Interrupt->Vector = Vector;
|
||||
Interrupt->Irql = Irql;
|
||||
Interrupt->SynchronizeIrql = SynchronizeIrql;
|
||||
Interrupt->Mode = InterruptMode;
|
||||
Interrupt->ShareVector = ShareVector;
|
||||
Interrupt->Number = ProcessorNumber;
|
||||
Interrupt->FloatingSave = FloatingSave;
|
||||
|
||||
/* Loop the template in memory */
|
||||
for (i = 0; i < KINTERRUPT_DISPATCH_CODES; i++)
|
||||
{
|
||||
/* Copy the dispatch code */
|
||||
*DispatchCode++ = KiInterruptTemplate[i];
|
||||
}
|
||||
|
||||
/* Jump to the last 4 bytes */
|
||||
Patch = (PULONG)((ULONG_PTR)Patch +
|
||||
((ULONG_PTR)&KiInterruptTemplateObject -
|
||||
(ULONG_PTR)KiInterruptTemplate) - 4);
|
||||
|
||||
/* Apply the patch */
|
||||
*Patch = PtrToUlong(Interrupt);
|
||||
|
||||
/* Disconnect it at first */
|
||||
Interrupt->Connected = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KeConnectInterrupt(IN PKINTERRUPT InterruptObject)
|
||||
{
|
||||
KIRQL oldlvl,synch_oldlvl;
|
||||
PKINTERRUPT ListHead;
|
||||
ULONG Vector;
|
||||
PISR_TABLE CurrentIsr;
|
||||
BOOLEAN Result;
|
||||
|
||||
DPRINT("KeConnectInterrupt()\n");
|
||||
|
||||
Vector = InterruptObject->Vector;
|
||||
|
||||
if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
|
||||
return FALSE;
|
||||
|
||||
Vector -= IRQ_BASE;
|
||||
|
||||
ASSERT (InterruptObject->Number < KeNumberProcessors);
|
||||
|
||||
KeSetSystemAffinityThread(1 << InterruptObject->Number);
|
||||
|
||||
CurrentIsr = &IsrTable[Vector];
|
||||
|
||||
KeRaiseIrql(VECTOR2IRQL(Vector + IRQ_BASE),&oldlvl);
|
||||
KiAcquireSpinLock(&CurrentIsr->Lock);
|
||||
|
||||
/*
|
||||
* Check if the vector is already in use that we can share it
|
||||
*/
|
||||
if (!IsListEmpty(&CurrentIsr->ListHead))
|
||||
{
|
||||
ListHead = CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,InterruptListEntry);
|
||||
if (InterruptObject->ShareVector == FALSE || ListHead->ShareVector==FALSE)
|
||||
{
|
||||
KiReleaseSpinLock(&CurrentIsr->Lock);
|
||||
KeLowerIrql(oldlvl);
|
||||
KeRevertToUserAffinityThread();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
|
||||
|
||||
Result = HalEnableSystemInterrupt(Vector + IRQ_BASE, InterruptObject->Irql, InterruptObject->Mode);
|
||||
if (Result)
|
||||
{
|
||||
InsertTailList(&CurrentIsr->ListHead,&InterruptObject->InterruptListEntry);
|
||||
}
|
||||
|
||||
InterruptObject->Connected = TRUE;
|
||||
KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
|
||||
|
||||
/*
|
||||
* Release the table spinlock
|
||||
*/
|
||||
KiReleaseSpinLock(&CurrentIsr->Lock);
|
||||
KeLowerIrql(oldlvl);
|
||||
|
||||
KeRevertToUserAffinityThread();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KeDisconnectInterrupt(IN PKINTERRUPT Interrupt)
|
||||
{
|
||||
KIRQL OldIrql, Irql;
|
||||
ULONG Vector;
|
||||
DISPATCH_INFO Dispatch;
|
||||
PKINTERRUPT NextInterrupt;
|
||||
BOOLEAN State;
|
||||
|
||||
/* Set the affinity */
|
||||
KeSetSystemAffinityThread(1 << Interrupt->Number);
|
||||
|
||||
/* Lock the dispatcher */
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Check if it's actually connected */
|
||||
State = Interrupt->Connected;
|
||||
if (State)
|
||||
{
|
||||
/* Get the vector and IRQL */
|
||||
Irql = Interrupt->Irql;
|
||||
Vector = Interrupt->Vector;
|
||||
|
||||
/* Get vector dispatch data */
|
||||
KiGetVectorDispatch(Vector, &Dispatch);
|
||||
|
||||
/* Check if it was chained */
|
||||
if (Dispatch.Type == ChainConnect)
|
||||
{
|
||||
/* Check if the top-level interrupt is being removed */
|
||||
ASSERT(Irql <= SYNCH_LEVEL);
|
||||
if (Interrupt == Dispatch.Interrupt)
|
||||
{
|
||||
/* Get the next one */
|
||||
Dispatch.Interrupt = CONTAINING_RECORD(Dispatch.Interrupt->
|
||||
InterruptListEntry.Flink,
|
||||
KINTERRUPT,
|
||||
InterruptListEntry);
|
||||
|
||||
/* Reconnect it */
|
||||
KiConnectVectorToInterrupt(Dispatch.Interrupt, ChainConnect);
|
||||
}
|
||||
|
||||
/* Remove it */
|
||||
RemoveEntryList(&Interrupt->InterruptListEntry);
|
||||
|
||||
/* Get the next one */
|
||||
NextInterrupt = CONTAINING_RECORD(Dispatch.Interrupt->
|
||||
InterruptListEntry.Flink,
|
||||
KINTERRUPT,
|
||||
InterruptListEntry);
|
||||
|
||||
/* Check if this is the only one left */
|
||||
if (Dispatch.Interrupt == NextInterrupt)
|
||||
{
|
||||
/* Connect it in non-chained mode */
|
||||
KiConnectVectorToInterrupt(Dispatch.Interrupt, NormalConnect);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Only one left, disable and remove it */
|
||||
HalDisableSystemInterrupt(Interrupt->Vector, Irql);
|
||||
KiConnectVectorToInterrupt(Interrupt, NoConnect);
|
||||
}
|
||||
|
||||
/* Disconnect it */
|
||||
Interrupt->Connected = FALSE;
|
||||
}
|
||||
|
||||
/* Unlock the dispatcher and revert affinity */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
KeRevertToUserAffinityThread();
|
||||
|
||||
/* Return to caller */
|
||||
return State;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,99 +0,0 @@
|
|||
#include <ndk/asm.h>
|
||||
#include <../hal/halx86/include/halirq.h>
|
||||
|
||||
_KiCommonInterrupt:
|
||||
cld
|
||||
pushl %ds
|
||||
pushl %es
|
||||
pushl %fs
|
||||
pushl %gs
|
||||
pushl $0xceafbeef
|
||||
|
||||
/* Load DS/ES (with override) */
|
||||
.intel_syntax noprefix
|
||||
mov eax, KGDT_R3_DATA + RPL_MASK
|
||||
.byte 0x66
|
||||
mov ds, ax
|
||||
.byte 0x66
|
||||
mov es, ax
|
||||
|
||||
/* Clear gs */
|
||||
xor eax, eax
|
||||
.byte 0x66
|
||||
mov gs, ax
|
||||
.att_syntax
|
||||
movl $KGDT_R0_PCR,%eax
|
||||
movl %eax,%fs
|
||||
pushl %esp
|
||||
pushl %ebx
|
||||
call _KiInterruptDispatch3
|
||||
addl $0xC, %esp
|
||||
popl %gs
|
||||
popl %fs
|
||||
popl %es
|
||||
popl %ds
|
||||
popa
|
||||
iret
|
||||
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#define BUILD_INTERRUPT_HANDLER(intnum) \
|
||||
.global _KiUnexpectedInterrupt##intnum; \
|
||||
_KiUnexpectedInterrupt##intnum:; \
|
||||
pusha; \
|
||||
movl $0x##intnum, %ebx; \
|
||||
jmp _KiCommonInterrupt;
|
||||
|
||||
/* Interrupt handlers and declarations */
|
||||
|
||||
#define B(x,y) \
|
||||
BUILD_INTERRUPT_HANDLER(x##y)
|
||||
|
||||
#define B16(x) \
|
||||
B(x,0) B(x,1) B(x,2) B(x,3) \
|
||||
B(x,4) B(x,5) B(x,6) B(x,7) \
|
||||
B(x,8) B(x,9) B(x,A) B(x,B) \
|
||||
B(x,C) B(x,D) B(x,E) B(x,F)
|
||||
|
||||
B16(3) B16(4) B16(5) B16(6)
|
||||
B16(7) B16(8) B16(9) B16(A)
|
||||
B16(B) B16(C) B16(D) B16(E)
|
||||
B16(F)
|
||||
|
||||
#undef B
|
||||
#undef B16
|
||||
#undef BUILD_INTERRUPT_HANDLER
|
||||
|
||||
#else /* CONFIG_SMP */
|
||||
|
||||
#define BUILD_INTERRUPT_HANDLER(intnum) \
|
||||
.global _irq_handler_##intnum; \
|
||||
_irq_handler_##intnum:; \
|
||||
pusha; \
|
||||
movl $(##intnum + IRQ_BASE), %ebx; \
|
||||
jmp _KiCommonInterrupt;
|
||||
|
||||
/* Interrupt handlers and declarations */
|
||||
|
||||
#define B(x) \
|
||||
BUILD_INTERRUPT_HANDLER(x)
|
||||
|
||||
B(0) B(1) B(2) B(3)
|
||||
B(4) B(5) B(6) B(7)
|
||||
B(8) B(9) B(10) B(11)
|
||||
B(12) B(13) B(14) B(15)
|
||||
|
||||
#undef B
|
||||
#undef BUILD_INTERRUPT_HANDLER
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
.intel_syntax noprefix
|
||||
.globl _KiUnexpectedInterrupt@0
|
||||
_KiUnexpectedInterrupt@0:
|
||||
|
||||
/* Bugcheck with invalid interrupt code */
|
||||
push 0x12
|
||||
call _KeBugCheck@4
|
||||
|
|
@ -369,7 +369,6 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
|||
|
||||
/* Setup the IDT */
|
||||
KeInitExceptions(); // ONCE HACK BELOW IS GONE, MOVE TO KISYSTEMSTARTUP!
|
||||
KeInitInterrupts(); // ROS HACK DEPRECATED SOON BY NEW HAL
|
||||
|
||||
/* Set up the VDM Data */
|
||||
NtEarlyInitVdm();
|
||||
|
|
|
@ -2010,15 +2010,14 @@ GetIntLock:
|
|||
RELEASE_SPINLOCK(esi)
|
||||
|
||||
/* Exit the interrupt */
|
||||
mov esi, $
|
||||
cli
|
||||
call _HalEndSystemInterrupt@8
|
||||
jmp _Kei386EoiHelper@0
|
||||
|
||||
SpuriousInt:
|
||||
/* Exit the interrupt */
|
||||
jmp $
|
||||
add esp, 8
|
||||
mov esi, $
|
||||
jmp _Kei386EoiHelper@0
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
@ -660,7 +660,6 @@ KiCoprocessorError@0
|
|||
KiCheckForKernelApcDelivery@0
|
||||
KiDeliverApc@12
|
||||
KiDispatchInterrupt@0
|
||||
KiInterruptDispatch2@8
|
||||
KiEnableTimerWatchdog
|
||||
KiIpiServiceRoutine@8
|
||||
@KiReleaseSpinLock@4
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<file>ctxswitch.S</file>
|
||||
<file>clock.S</file>
|
||||
<file>exp.c</file>
|
||||
<!-- <file>irq.c</file> -->
|
||||
<file>irq.c</file>
|
||||
<file>kiinit.c</file>
|
||||
<file>ldt.c</file>
|
||||
<file>mtrr.c</file>
|
||||
|
@ -73,10 +73,6 @@
|
|||
<file>timer.c</file>
|
||||
<file>wait.c</file>
|
||||
</directory>
|
||||
<directory name="deprecated">
|
||||
<file>irqhand.S</file>
|
||||
<file>irq.c</file>
|
||||
</directory>
|
||||
<directory name="cc">
|
||||
<file>cacheman.c</file>
|
||||
<file>copy.c</file>
|
||||
|
|
Loading…
Reference in a new issue