mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 13:10:39 +00:00
[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 svn path=/trunk/; revision=53719
This commit is contained in:
parent
52d89c3b87
commit
4dfa3c52a3
5 changed files with 242 additions and 29 deletions
|
@ -13,11 +13,10 @@
|
||||||
#ifdef _M_AMD64
|
#ifdef _M_AMD64
|
||||||
#include <ksamd64.inc>
|
#include <ksamd64.inc>
|
||||||
#include <trapamd64.inc>
|
#include <trapamd64.inc>
|
||||||
#define KI_PUSH_FAKE_ERROR_CODE TF_PUSH_FAKE_ERROR_CODE
|
|
||||||
.code
|
.code
|
||||||
|
|
||||||
TRAP_ENTRY HalpClockInterrupt, KI_PUSH_FAKE_ERROR_CODE
|
TRAP_ENTRY HalpClockInterrupt, (TF_VOLATILES OR TF_SEND_EOI)
|
||||||
TRAP_ENTRY HalpProfileInterrupt, KI_PUSH_FAKE_ERROR_CODE
|
TRAP_ENTRY HalpProfileInterrupt, (TF_VOLATILES OR TF_SEND_EOI)
|
||||||
|
|
||||||
PUBLIC ApicSpuriousService
|
PUBLIC ApicSpuriousService
|
||||||
ApicSpuriousService:
|
ApicSpuriousService:
|
||||||
|
@ -37,6 +36,7 @@ HackEoi:
|
||||||
mov dword ptr [HEX(0FFFFFFFFFFFE00B0)], 0
|
mov dword ptr [HEX(0FFFFFFFFFFFE00B0)], 0
|
||||||
iretq
|
iretq
|
||||||
HackEoiReturn:
|
HackEoiReturn:
|
||||||
|
add rsp, 8 // esp was changed by the iret to the pushed value
|
||||||
ret
|
ret
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -109,32 +109,36 @@ HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
|
||||||
/* Enter trap */
|
/* Enter trap */
|
||||||
KiEnterInterruptTrap(TrapFrame);
|
KiEnterInterruptTrap(TrapFrame);
|
||||||
|
#ifdef _M_AMD64
|
||||||
|
/* This is for debugging */
|
||||||
|
TrapFrame->ErrorCode = 0xc10c4;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Start the interrupt */
|
/* 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 */
|
/* Spurious, just end the interrupt */
|
||||||
HalpReadCmos(RTC_REGISTER_C);;
|
KiEoiHelper(TrapFrame);
|
||||||
|
|
||||||
/* 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 */
|
/* Read register C, so that the next interrupt can happen */
|
||||||
KiEoiHelper(TrapFrame);
|
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
|
VOID
|
||||||
|
|
|
@ -55,10 +55,12 @@ _CalibrationISR_Exit:
|
||||||
|
|
||||||
EXTERN TscCalibrationPhase:BYTE
|
EXTERN TscCalibrationPhase:BYTE
|
||||||
EXTERN TscCalibrationArray:DWORD
|
EXTERN TscCalibrationArray:DWORD
|
||||||
|
EXTERN HalpSendEOI:PROC
|
||||||
|
|
||||||
PUBLIC TscCalibrationISR
|
PUBLIC TscCalibrationISR
|
||||||
FUNC TscCalibrationISR
|
FUNC TscCalibrationISR
|
||||||
push rax
|
push rax
|
||||||
|
push rbx
|
||||||
push rcx
|
push rcx
|
||||||
push rdx
|
push rdx
|
||||||
.ENDPROLOG
|
.ENDPROLOG
|
||||||
|
@ -74,17 +76,28 @@ FUNC TscCalibrationISR
|
||||||
jnb CalibrationISR_Exit
|
jnb CalibrationISR_Exit
|
||||||
|
|
||||||
/* Store the current value */
|
/* Store the current value */
|
||||||
shl rcx, 1
|
shl rcx, 3
|
||||||
lea rax, [TscCalibrationArray]
|
lea rbx, [TscCalibrationArray]
|
||||||
mov dword ptr [rax + rcx], eax
|
mov dword ptr [rbx + rcx], eax
|
||||||
mov dword ptr [rax + rcx + 4], edx
|
mov dword ptr [rbx + rcx + 4], edx
|
||||||
|
|
||||||
/* Advance phase */
|
/* Advance phase */
|
||||||
inc byte ptr [TscCalibrationPhase]
|
inc byte ptr [TscCalibrationPhase]
|
||||||
|
|
||||||
CalibrationISR_Exit:
|
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 rdx
|
||||||
pop rcx
|
pop rcx
|
||||||
|
pop rbx
|
||||||
pop rax
|
pop rax
|
||||||
iretq
|
iretq
|
||||||
ENDFUNC TscCalibrationISR
|
ENDFUNC TscCalibrationISR
|
||||||
|
|
|
@ -846,7 +846,7 @@ HalpInitProcessor(
|
||||||
#define KfLowerIrql KeLowerIrql
|
#define KfLowerIrql KeLowerIrql
|
||||||
#define KiEnterInterruptTrap(TrapFrame) /* We do all neccessary in asm code */
|
#define KiEnterInterruptTrap(TrapFrame) /* We do all neccessary in asm code */
|
||||||
#define KiEoiHelper(TrapFrame) return /* Just return to the caller */
|
#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
|
#ifndef CONFIG_SMP
|
||||||
/* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
|
/* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
|
||||||
#define KiAcquireSpinLock(SpinLock)
|
#define KiAcquireSpinLock(SpinLock)
|
||||||
|
|
196
reactos/include/asm/trapamd64.inc
Normal file
196
reactos/include/asm/trapamd64.inc
Normal file
|
@ -0,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
|
||||||
|
|
Loading…
Reference in a new issue