-
-
[讨论]懂APIC编程的进,bugchecker的maskinterrupt函数是不是错了。。
-
发表于: 2011-8-13 20:08 4143
-
IOAPIC的中断PRT表项,一共是2个DWORD,低32位的第16位表示Mask,为1的时候屏蔽。
bugchecker源代码中apic.c中的MaskInterrupts函数用于关闭指定的中断(IRQ0~IRQ15),但是我看这代码。感觉他置Mask位那里错了啊,他设置了高32位的bit16=1。。
test dword ptr [ esp ], 1
下面那个jz是不是应该是jnz啊。。。
VOID MaskInterrupts( IN BYTE bPIC1Mask, IN BYTE bPIC2Mask, OUT SYSINTERRUPTS_STATUS* psisSysInterrStatus )
{
DWORD dwIrqMask = 0xFFFF0000 | ( bPIC2Mask << 8 ) | bPIC1Mask;
// Do the Requested Operation.
__asm
{
push eax
push ebx
push ecx
push edx
mov ebx, psisSysInterrStatus
// Skip the 8259 Programming if a I/O APIC is present.
cmp [ ebx ]SYSINTERRUPTS_STATUS.pvIoApicMemoryPtr, 0
jne _Skip8259Programming
// Set IMR of PIC1
in al, 0x21
mov [ ebx ]SYSINTERRUPTS_STATUS.bPic1IMR, al
mov al, bPIC1Mask
out 0x21, al
// Set IMR of PIC2
in al, 0xA1
mov [ ebx ]SYSINTERRUPTS_STATUS.bPic2IMR, al
mov al, bPIC2Mask
out 0xA1, al
_Skip8259Programming:
// Check to see whether we have an I/O Apic.
mov edx, [ ebx ]SYSINTERRUPTS_STATUS.pvIoApicMemoryPtr
or edx, edx
jz _IoApicIsNOTPresent
push ebx
mov eax, 0x10
mov ecx, [ ebx ]SYSINTERRUPTS_STATUS.dwIORedirTableBackupItemsNum
lea ebx, [ ebx ]SYSINTERRUPTS_STATUS.viiIORedirTableBackup
_IORedirTableBackUpLoop:
push ecx
// Save this Entry.
mov [ edx ], eax
mov ecx, [ edx + 0x10 ]
mov [ ebx ], ecx
// Modify this Entry.
test dwIrqMask, 1
jz _DoNotConsiderFirst32Bits
test dword ptr [ esp ], 1 // <--- ### LOOP ECX !!! ###
jz _DoNotConsiderFirst32Bits
or ecx, 0x00010000
mov [ edx ], eax
mov [ edx + 0x10 ], ecx
_DoNotConsiderFirst32Bits:
// Increment.
inc eax
add ebx, 4
pop ecx
test ecx, 1
jz _DoNotShiftIrqMask
shr dwIrqMask, 1
_DoNotShiftIrqMask:
loop _IORedirTableBackUpLoop
pop ebx
_IoApicIsNOTPresent:
pop edx
pop ecx
pop ebx
pop eax
}
// Return to the Caller.
return;
}
bugchecker源代码中apic.c中的MaskInterrupts函数用于关闭指定的中断(IRQ0~IRQ15),但是我看这代码。感觉他置Mask位那里错了啊,他设置了高32位的bit16=1。。
test dword ptr [ esp ], 1
下面那个jz是不是应该是jnz啊。。。
VOID MaskInterrupts( IN BYTE bPIC1Mask, IN BYTE bPIC2Mask, OUT SYSINTERRUPTS_STATUS* psisSysInterrStatus )
{
DWORD dwIrqMask = 0xFFFF0000 | ( bPIC2Mask << 8 ) | bPIC1Mask;
// Do the Requested Operation.
__asm
{
push eax
push ebx
push ecx
push edx
mov ebx, psisSysInterrStatus
// Skip the 8259 Programming if a I/O APIC is present.
cmp [ ebx ]SYSINTERRUPTS_STATUS.pvIoApicMemoryPtr, 0
jne _Skip8259Programming
// Set IMR of PIC1
in al, 0x21
mov [ ebx ]SYSINTERRUPTS_STATUS.bPic1IMR, al
mov al, bPIC1Mask
out 0x21, al
// Set IMR of PIC2
in al, 0xA1
mov [ ebx ]SYSINTERRUPTS_STATUS.bPic2IMR, al
mov al, bPIC2Mask
out 0xA1, al
_Skip8259Programming:
// Check to see whether we have an I/O Apic.
mov edx, [ ebx ]SYSINTERRUPTS_STATUS.pvIoApicMemoryPtr
or edx, edx
jz _IoApicIsNOTPresent
push ebx
mov eax, 0x10
mov ecx, [ ebx ]SYSINTERRUPTS_STATUS.dwIORedirTableBackupItemsNum
lea ebx, [ ebx ]SYSINTERRUPTS_STATUS.viiIORedirTableBackup
_IORedirTableBackUpLoop:
push ecx
// Save this Entry.
mov [ edx ], eax
mov ecx, [ edx + 0x10 ]
mov [ ebx ], ecx
// Modify this Entry.
test dwIrqMask, 1
jz _DoNotConsiderFirst32Bits
test dword ptr [ esp ], 1 // <--- ### LOOP ECX !!! ###
jz _DoNotConsiderFirst32Bits
or ecx, 0x00010000
mov [ edx ], eax
mov [ edx + 0x10 ], ecx
_DoNotConsiderFirst32Bits:
// Increment.
inc eax
add ebx, 4
pop ecx
test ecx, 1
jz _DoNotShiftIrqMask
shr dwIrqMask, 1
_DoNotShiftIrqMask:
loop _IORedirTableBackUpLoop
pop ebx
_IoApicIsNOTPresent:
pop edx
pop ecx
pop ebx
pop eax
}
// Return to the Caller.
return;
}
赞赏
他的文章
看原图
赞赏
雪币:
留言: