Author: tkreuzer Date: Fri Sep 16 09:39:41 2011 New Revision: 53719
URL: http://svn.reactos.org/svn/reactos?rev=53719&view=rev Log: [HAL/APIC/AMD64] - add common amd64 asm trap macros - fix amd64 version of HackEoi - send EOI in amd64 trap exit code, so we avoid using HackEoi - modify HalpClockInterruptHandler for better portability - fix amd64 TscCalibrationISR
Added: trunk/reactos/include/asm/trapamd64.inc Modified: trunk/reactos/hal/halx86/apic/apictrap.S trunk/reactos/hal/halx86/apic/rtctimer.c trunk/reactos/hal/halx86/apic/tsccal.S trunk/reactos/hal/halx86/include/halp.h
Modified: trunk/reactos/hal/halx86/apic/apictrap.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/apictrap.S?... ============================================================================== --- trunk/reactos/hal/halx86/apic/apictrap.S [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/apic/apictrap.S [iso-8859-1] Fri Sep 16 09:39:41 2011 @@ -13,11 +13,10 @@ #ifdef _M_AMD64 #include <ksamd64.inc> #include <trapamd64.inc> -#define KI_PUSH_FAKE_ERROR_CODE TF_PUSH_FAKE_ERROR_CODE .code
-TRAP_ENTRY HalpClockInterrupt, KI_PUSH_FAKE_ERROR_CODE -TRAP_ENTRY HalpProfileInterrupt, KI_PUSH_FAKE_ERROR_CODE +TRAP_ENTRY HalpClockInterrupt, (TF_VOLATILES OR TF_SEND_EOI) +TRAP_ENTRY HalpProfileInterrupt, (TF_VOLATILES OR TF_SEND_EOI)
PUBLIC ApicSpuriousService ApicSpuriousService: @@ -37,6 +36,7 @@ mov dword ptr [HEX(0FFFFFFFFFFFE00B0)], 0 iretq HackEoiReturn: + add rsp, 8 // esp was changed by the iret to the pushed value ret
#else
Modified: trunk/reactos/hal/halx86/apic/rtctimer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/rtctimer.c?... ============================================================================== --- trunk/reactos/hal/halx86/apic/rtctimer.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/apic/rtctimer.c [iso-8859-1] Fri Sep 16 09:39:41 2011 @@ -109,32 +109,36 @@
/* Enter trap */ KiEnterInterruptTrap(TrapFrame); +#ifdef _M_AMD64 + /* This is for debugging */ + TrapFrame->ErrorCode = 0xc10c4; +#endif
/* Start the interrupt */ - if (HalBeginSystemInterrupt(CLOCK_LEVEL, HalpClockVector, &Irql)) + if (!HalBeginSystemInterrupt(CLOCK_LEVEL, HalpClockVector, &Irql)) { - /* Read register C, so that the next interrupt can happen */ - HalpReadCmos(RTC_REGISTER_C);; - - /* Save increment */ - LastIncrement = HalpCurrentTimeIncrement; - - /* Check if someone changed the time rate */ - if (HalpClockSetMSRate) - { - /* Set new clock rate */ - RtcSetClockRate(HalpCurrentRate); - - /* We're done */ - HalpClockSetMSRate = FALSE; - } - - /* Update the system time -- the kernel will exit this trap */ - KeUpdateSystemTime(TrapFrame, LastIncrement, Irql); + /* Spurious, just end the interrupt */ + KiEoiHelper(TrapFrame); }
- /* Spurious, just end the interrupt */ - KiEoiHelper(TrapFrame); + /* Read register C, so that the next interrupt can happen */ + HalpReadCmos(RTC_REGISTER_C);; + + /* Save increment */ + LastIncrement = HalpCurrentTimeIncrement; + + /* Check if someone changed the time rate */ + if (HalpClockSetMSRate) + { + /* Set new clock rate */ + RtcSetClockRate(HalpCurrentRate); + + /* We're done */ + HalpClockSetMSRate = FALSE; + } + + /* Update the system time -- on x86 the kernel will exit this trap */ + KeUpdateSystemTime(TrapFrame, LastIncrement, Irql); }
VOID
Modified: trunk/reactos/hal/halx86/apic/tsccal.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/tsccal.S?re... ============================================================================== --- trunk/reactos/hal/halx86/apic/tsccal.S [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/apic/tsccal.S [iso-8859-1] Fri Sep 16 09:39:41 2011 @@ -55,10 +55,12 @@
EXTERN TscCalibrationPhase:BYTE EXTERN TscCalibrationArray:DWORD +EXTERN HalpSendEOI:PROC
PUBLIC TscCalibrationISR FUNC TscCalibrationISR push rax + push rbx push rcx push rdx .ENDPROLOG @@ -74,17 +76,28 @@ jnb CalibrationISR_Exit
/* Store the current value */ - shl rcx, 1 - lea rax, [TscCalibrationArray] - mov dword ptr [rax + rcx], eax - mov dword ptr [rax + rcx + 4], edx + shl rcx, 3 + lea rbx, [TscCalibrationArray] + mov dword ptr [rbx + rcx], eax + mov dword ptr [rbx + rcx + 4], edx
/* Advance phase */ inc byte ptr [TscCalibrationPhase]
CalibrationISR_Exit: + /* Read CMOS register C */ + mov al, HEX(0C) + out HEX(70), al + jmp $+2 + in al, HEX(71) + jmp $+2 + + /* Send EOI */ + call HalpSendEOI + pop rdx pop rcx + pop rbx pop rax iretq ENDFUNC TscCalibrationISR
Modified: trunk/reactos/hal/halx86/include/halp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/halp.h?r... ============================================================================== --- trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] Fri Sep 16 09:39:41 2011 @@ -846,7 +846,7 @@ #define KfLowerIrql KeLowerIrql #define KiEnterInterruptTrap(TrapFrame) /* We do all neccessary in asm code */ #define KiEoiHelper(TrapFrame) return /* Just return to the caller */ -#define HalBeginSystemInterrupt(Irql, Vector, OldIrql) (KeRaiseIrql(Irql, OldIrql), TRUE) +#define HalBeginSystemInterrupt(Irql, Vector, OldIrql) TRUE #ifndef CONFIG_SMP /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */ #define KiAcquireSpinLock(SpinLock)
Added: trunk/reactos/include/asm/trapamd64.inc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/asm/trapamd64.inc?r... ============================================================================== --- trunk/reactos/include/asm/trapamd64.inc (added) +++ trunk/reactos/include/asm/trapamd64.inc [iso-8859-1] Fri Sep 16 09:39:41 2011 @@ -1,0 +1,196 @@ + +APIC_EOI = HEX(0FFFFFFFFFFFE00B0) + +TF_VOLATILES = HEX(01) +TF_NONVOLATILES = HEX(02) +TF_XMM = HEX(04) +TF_SEGMENTS = HEX(08) +TF_DEBUG = HEX(10) +TF_IRQL = HEX(20) +TF_SAVE_ALL = (TF_VOLATILES OR TF_NONVOLATILES OR TF_XMM OR TF_SEGMENTS) +TF_HAS_ERROR_CODE = HEX(40) +TF_SEND_EOI = HEX(80) + +/* + * EnterTrap - Allocate KTRAP_FRAME_LENGTH and save registers to it + */ +MACRO(EnterTrap, Flags) + LOCAL dont_swap + + /* Save the trap flags for this trap */ + CurrentTrapFlags = VAL(Flags) + + /* Size of hardware trap frame */ + if (Flags AND TF_HAS_ERROR_CODE) + .pushframe code + SIZE_INITIAL_FRAME = 6 * 8 + else + .pushframe + SIZE_INITIAL_FRAME = 5 * 8 + endif + + /* Make room for a KTRAP_FRAME */ + sub rsp, (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME) + .allocstack (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME) + .endprolog + + /* Save rbp and rax */ + mov [rsp + KTRAP_FRAME_Rbp], rbp + mov [rsp + KTRAP_FRAME_Rax], rax + + /* Point rbp to the KTRAP_FRAME */ + lea rbp, [rsp] + + if (Flags AND TF_NONVOLATILES) + /* Save non-volatile registers */ + mov [rbp + KTRAP_FRAME_Rbx], rbx + mov [rbp + KTRAP_FRAME_Rdi], rdi + mov [rbp + KTRAP_FRAME_Rsi], rsi + endif + + if (Flags AND TF_VOLATILES) + /* Save volatile registers */ + mov [rbp + KTRAP_FRAME_Rcx], rcx + mov [rbp + KTRAP_FRAME_Rdx], rdx + mov [rbp + KTRAP_FRAME_R8], r8 + mov [rbp + KTRAP_FRAME_R9], r9 + mov [rbp + KTRAP_FRAME_R10], r10 + mov [rbp + KTRAP_FRAME_R11], r11 + endif + + if (Flags AND TF_XMM) + /* Save xmm registers */ + movdqa [rbp + KTRAP_FRAME_Xmm0], xmm0 + movdqa [rbp + KTRAP_FRAME_Xmm1], xmm1 + movdqa [rbp + KTRAP_FRAME_Xmm2], xmm2 + movdqa [rbp + KTRAP_FRAME_Xmm3], xmm3 + movdqa [rbp + KTRAP_FRAME_Xmm4], xmm4 + movdqa [rbp + KTRAP_FRAME_Xmm5], xmm5 + endif + + if (Flags AND TF_SEGMENTS) + /* Save segment selectors */ + mov [rbp + KTRAP_FRAME_SegDs], ds + mov [rbp + KTRAP_FRAME_SegEs], es + mov [rbp + KTRAP_FRAME_SegFs], fs + mov [rbp + KTRAP_FRAME_SegGs], gs + endif + + /* Save previous mode and swap gs when it was UserMode */ + mov ax, [rbp + KTRAP_FRAME_SegCs] + and al, 1 + mov [rbp + KTRAP_FRAME_PreviousMode], al + jz dont_swap + swapgs +dont_swap: + + if (Flags AND TF_IRQL) + /* Save previous irql */ + mov rax, cr8 + mov [rbp + KTRAP_FRAME_PreviousIrql], al + endif + + if (Flags AND TF_DEBUG) + /* Save debug registers */ + mov rax, dr0 + mov [rbp + KTRAP_FRAME_Dr0], rax + mov rax, dr1 + mov [rbp + KTRAP_FRAME_Dr1], rax + mov rax, dr2 + mov [rbp + KTRAP_FRAME_Dr2], rax + mov rax, dr3 + mov [rbp + KTRAP_FRAME_Dr3], rax + mov rax, dr6 + mov [rbp + KTRAP_FRAME_Dr6], rax + mov rax, dr7 + mov [rbp + KTRAP_FRAME_Dr7], rax + endif + + /* Make sure the direction flag is cleared */ + cld +ENDM + +/* + * ExitTrap - Restore registers and free stack space + */ +MACRO(ExitTrap, Flags) + LOCAL dont_swap_back + + if (Flags AND TF_SEGMENTS) + /* Restore segment selectors */ + mov ds, [rbp + KTRAP_FRAME_SegDs] + mov es, [rbp + KTRAP_FRAME_SegEs] + mov fs, [rbp + KTRAP_FRAME_SegFs] + endif + + if (Flags AND TF_IRQL) + /* Restore previous irql */ + movzx rax, byte ptr [rbp + KTRAP_FRAME_PreviousIrql] + mov cr8, rax + endif + + test byte ptr [rbp + KTRAP_FRAME_PreviousMode], 1 + jz dont_swap_back + swapgs +dont_swap_back: + + if (Flags AND TF_NONVOLATILES) + /* Restore non-volatile registers */ + mov rbx, [rbp + KTRAP_FRAME_Rbx] + mov rdi, [rbp + KTRAP_FRAME_Rdi] + mov rsi, [rbp + KTRAP_FRAME_Rsi] + endif + + if (Flags AND TF_VOLATILES) + /* Restore volatile registers */ + mov rax, [rbp + KTRAP_FRAME_Rax] + mov rcx, [rbp + KTRAP_FRAME_Rcx] + mov rdx, [rbp + KTRAP_FRAME_Rdx] + mov r8, [rbp + KTRAP_FRAME_R8] + mov r9, [rbp + KTRAP_FRAME_R9] + mov r10, [rbp + KTRAP_FRAME_R10] + mov r11, [rbp + KTRAP_FRAME_R11] + endif + + if (Flags AND TF_XMM) + /* Restore xmm registers */ + movdqa xmm0, [rbp + KTRAP_FRAME_Xmm0] + movdqa xmm1, [rbp + KTRAP_FRAME_Xmm1] + movdqa xmm2, [rbp + KTRAP_FRAME_Xmm2] + movdqa xmm3, [rbp + KTRAP_FRAME_Xmm3] + movdqa xmm4, [rbp + KTRAP_FRAME_Xmm4] + movdqa xmm5, [rbp + KTRAP_FRAME_Xmm5] + endif + + /* Restore rbp */ + mov rbp, [rbp + KTRAP_FRAME_Rbp] + + /* Adjust stack pointer */ + add rsp, KTRAP_FRAME_Rip + + if (Flags AND TF_SEND_EOI) + /* Write 0 to the local APIC EOI register */ + mov dword ptr [APIC_EOI], 0 + endif + + /* Return from the trap */ + iretq +ENDM + + +MACRO(TRAP_ENTRY, Trap, Flags) + EXTERN Trap&Handler :PROC + PUBLIC &Trap + FUNC &Trap + /* Common code to create the trap frame */ + EnterTrap Flags + + /* Call the C handler */ + mov rcx, rbp + call Trap&Handler + + /* Leave */ + ExitTrap Flags + ENDFUNC &Trap +ENDM +