IoConnectInterrupt个人注释

来源:互联网 发布:北漂 知乎 编辑:程序博客网 时间:2024/06/10 00:04
/* * @implemented 来看一下跟中断对象有关的两个对象: typedef struct _IO_INTERRUPT{    KINTERRUPT FirstInterrupt;    PKINTERRUPT Interrupt[MAXIMUM_PROCESSORS];    KSPIN_LOCK SpinLock;} IO_INTERRUPT, *PIO_INTERRUPT; typedef struct _KINTERRUPT { CSHORT Type; CSHORT Size; LIST_ENTRY InterruptListEntry; PKSERVICE_ROUTINE ServiceRoutine;#if (NTDDI_VERSION >= NTDDI_LONGHORN) PKSERVICE_ROUTINE MessageServiceRoutine; ULONG MessageIndex;#endif...#if (NTDDI_VERSION >= NTDDI_LONGHORN) ULONGLONG Rsvd1;#endif //指向INT_PROLOG代码段地址 ULONG DispatchCode[KINTERRUPT_DISPATCH_CODES]; } KINTERRUPT, *PKINTERRUPT;安装中断过程势必分配一个中断对象KINTERRUPT,对于单个CPU。如果主机上有多个CPU,那就必须为每个CPU分配相同的中断对象,这样,不同的CPU接到中断信号后才能有相同的处理过程。如果有这么多功能相同的却离散分布的中断对象,管理起来比较麻烦,于是Reactos为这些具有相同处理过程的中断对象分配一个统一的管理对象_IO_INTERRUPT,把同一类中断对象装入到这个_IO_INTERRUPT结构中去如此看来_KINTERRUPT是实际的处理者,而_IO_INTERRUPT更像一个管理者 */
NTSTATUSNTAPIIoConnectInterrupt(OUT PKINTERRUPT *InterruptObject,                   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 KAFFINITY ProcessorEnableMask,                   IN BOOLEAN FloatingSave){    PKINTERRUPT Interrupt;    PKINTERRUPT InterruptUsed;//IO_INTERRUPT:具有相同中断处理函数的CPU的集合    PIO_INTERRUPT IoInterrupt;    PKSPIN_LOCK SpinLockUsed;    BOOLEAN FirstRun = TRUE;    CCHAR Count = 0;    KAFFINITY Affinity;    PAGED_CODE();    /* Assume failure */    *InterruptObject = NULL;    /* Get the affinity */    Affinity = ProcessorEnableMask & KeActiveProcessors;    while (Affinity)    {        /* Increase count */        if (Affinity & 1) Count++;        Affinity >>= 1;    }    /* Make sure we have a valid CPU count */    if (!Count) return STATUS_INVALID_PARAMETER;    /* Allocate the array of I/O Interrupts *//*Count>1 针对多CPU的情况. struct _IO_INTERRUPT IoInterrupt是用于管理多CPU中断处理的结构IoInterrupt->KINTERRUPT[0]->ISR                ->KINTERRUPT[1]->ISR                ->KINTERRUPT[2]->ISR这么说,在SMP结构中调用一次IoConnectInterrupt就会为所有具有中断处理能力的CPU都安装相同的中断处理过程(即中断对象)*//*主要是分配IO_INTERRUPT--中断对象的管理者,其次才是在这个对象的尾部跟上诺干数量上和系统中具有该中断处理能力的CPU的中断对象当本函数后面KeInitializeInterrupt/KeConnectInterrupt调用完成后,将这个中断对象添加到IO_INTERRUPT管理者中*/    IoInterrupt = ExAllocatePoolWithTag(NonPagedPool,                                        (Count - 1) * sizeof(KINTERRUPT) +                                        sizeof(IO_INTERRUPT),                                        TAG_KINTERRUPT);    if (!IoInterrupt) return STATUS_INSUFFICIENT_RESOURCES;    /* Select which Spinlock to use */    SpinLockUsed = SpinLock ? SpinLock : &IoInterrupt->SpinLock;    /* We first start with a built-in Interrupt inside the I/O Structure */    *InterruptObject = &IoInterrupt->FirstInterrupt;    Interrupt = (PKINTERRUPT)(IoInterrupt + 1);    FirstRun = TRUE;    /* Start with a fresh structure */    RtlZeroMemory(IoInterrupt, sizeof(IO_INTERRUPT));    /* Now create all the interrupts */    Affinity = ProcessorEnableMask & KeActiveProcessors;//初始化IO_INTERRUPT中每个KINTERRUPT结构    for (Count = 0; Affinity; Count++, Affinity >>= 1)    {        /* Check if it's enabled for this CPU *///Affinity & 1-->具有处理能力的CPU        if (Affinity & 1)        {            /* Check which one we will use */            InterruptUsed = FirstRun ? &IoInterrupt->FirstInterrupt : Interrupt;            /* Initialize it */            KeInitializeInterrupt(InterruptUsed,                                  ServiceRoutine,                                  ServiceContext,                                  SpinLockUsed,                                  Vector,                                  Irql,                                  SynchronizeIrql,                                  InterruptMode,                                  ShareVector,                                  Count,                                  FloatingSave);            /* Connect it */            if (!KeConnectInterrupt(InterruptUsed))            {                /* Check how far we got */                if (FirstRun)                {                    /* We failed early so just free this */                    ExFreePool(IoInterrupt);                }                else                {                    /* Far enough, so disconnect everything */                    IoDisconnectInterrupt(&IoInterrupt->FirstInterrupt);                }                /* And fail */                return STATUS_INVALID_PARAMETER;            }            /* Now we've used up our First Run */            if (FirstRun)            {            //处理完FirstInterrupt,即将对其他CPU进行处理                FirstRun = FALSE;            }            else            {                /* Move on to the next one *//*前面针对多处理器分配了多个中断处理对象,把经过处理的KINTERRUPT结构加入到IoInterrupt管理机构中(意即:这些CPU上已有这种中断处理程序)*/                IoInterrupt->Interrupt[(UCHAR)Count] = Interrupt++;            }        }    }    /* Return Success */    return STATUS_SUCCESS;}


0 0
原创粉丝点击