|
|
;++ ;Module Name ; imca.asm ; ;Abstract: ; Assembly support needed for Intel MCA ; ; Author: ; Anil Aggarwal (Intel Corp) ; ;Revision History: ; ; ;--
.586p .xlist include hal386.inc include callconv.inc include i386\kimacro.inc .list
EXTRNP _HalpMcaExceptionHandler,0 EXTRNP _KeBugCheckEx,5,IMPORT
KGDT_MCA_TSS EQU 0A0H MINIMUM_TSS_SIZE EQU TssIoMaps
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; TEXT Segment ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_TEXT SEGMENT PARA PUBLIC 'CODE' ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.586p
;++ ; ;VOID ;HalpSerialize( ; VOID ; ) ; ; Routine Description: ; This function implements the fence operation for out-of-order execution ; ; Arguments: ; None ; ; Return Value: ; None ; ;--
cPublicProc _HalpSerialize,0
push ebx xor eax, eax cpuid pop ebx
stdRET _HalpSerialize
stdENDP _HalpSerialize ;++ ; ; Routine Description: ; ; Machine Check exception handler ; ; ; Arguments: ; ; Return value: ; ; If the error is non-restartable, we will bugcheck. ; Otherwise, we just return ; ;-- ASSUME DS:NOTHING, SS:NOTHING, ES:NOTHING align dword public _HalpMcaExceptionHandlerWrapper _HalpMcaExceptionHandlerWrapper proc .FPO (0, 0, 0, 0, 0, 2)
cli
; ; Update the TSS pointer in the PCR to point to the MCA TSS ; (which is what we're running on, or else we wouldn't be here) ;
push dword ptr PCR[PcTss] mov eax, PCR[PcGdt] mov ch, [eax+KGDT_MCA_TSS+KgdtBaseHi] mov cl, [eax+KGDT_MCA_TSS+KgdtBaseMid] shl ecx, 16 mov cx, [eax+KGDT_MCA_TSS+KgdtBaseLow] mov PCR[PcTss], ecx
; ; Clear the busy bit in the TSS selector ; mov ecx, PCR[PcGdt] lea eax, [ecx] + KGDT_MCA_TSS mov byte ptr [eax+5], 089h ; 32bit, dpl=0, present, TSS32, not busy
; ; Clear Nested Task bit in EFLAGS ; pushfd and [esp], not 04000h popfd
; ; Check if there is a bugcheck-able error. If need to bugcheck, the ; caller does it. ; stdCall _HalpMcaExceptionHandler
; ; We're back which means that the error was restartable. ;
pop dword ptr PCR[PcTss] ; restore PcTss
mov ecx, PCR[PcGdt] lea eax, [ecx] + KGDT_TSS mov byte ptr [eax+5], 08bh ; 32bit, dpl=0, present, TSS32, *busy*
pushfd ; Set Nested Task bit in EFLAGS or [esp], 04000h ; so iretd will do a tast switch popfd
iretd ; Return from MCA Exception handler jmp short _HalpMcaExceptionHandlerWrapper ; For next Machine check exception
_HalpMcaExceptionHandlerWrapper endp
_TEXT ends
INIT SEGMENT DWORD PUBLIC 'CODE'
;++ ;VOID ;HalpMcaCurrentProcessorSetTSS( ; IN PULONG pTSS // MCE TSS area for this processor ; ) ; Routine Description: ; This function sets up the TSS for MCA exception 18 ; ; Arguments: ; pTSS : Pointer to the TSS to be used for MCE ; ; Return Value: ; None ; ;--
cPublicProc _HalpMcaCurrentProcessorSetTSS,1 ; ; Edit IDT Entry for MCA Exception (18) to contain a task gate ; mov ecx, PCR[PcIdt] ; Get IDT address lea eax, [ecx] + 090h ; MCA Exception is 18 mov byte ptr [eax + 5], 085h ; P=1,DPL=0,Type=5 mov word ptr [eax + 2], KGDT_MCA_TSS ; TSS Segment Selector
mov edx, [esp+4] ; the address of TSS in edx
; ; Set various fields in TSS ; mov eax, cr3 mov [edx + TssCR3], eax
; ; Get double fault stack address ; lea eax, [ecx] + 040h ; DF Exception is 8
; ; Get to TSS Descriptor of double fault handler TSS ; xor ecx, ecx mov cx, word ptr [eax+2] add ecx, PCR[PcGdt]
; ; Get the address of TSS from this TSS Descriptor ; mov ah, [ecx+KgdtBaseHi] mov al, [ecx+KgdtBaseMid] shl eax, 16 mov ax, [ecx+KgdtBaseLow]
; ; Get ESP from DF TSS ; mov ecx, [eax+038h]
; ; Set address of MCA Exception stack to double fault stack address ; mov dword ptr [edx+038h], ecx ; Set ESP mov dword ptr [edx+TssEsp0], ecx ; Set ESP0
mov dword ptr [edx+020h], offset FLAT:_HalpMcaExceptionHandlerWrapper ; set EIP mov dword ptr [edx+024h], 0 ; set EFLAGS mov word ptr [edx+04ch],KGDT_R0_CODE ; set value for CS mov word ptr [edx+058h],KGDT_R0_PCR ; set value for FS mov [edx+050h], ss mov word ptr [edx+048h],KGDT_R3_DATA OR RPL_MASK ; Es mov word ptr [edx+054h],KGDT_R3_DATA OR RPL_MASK ; Ds
; ; Part that gets done in KiInitialiazeTSS() ; mov word ptr [edx + 08], KGDT_R0_DATA ; Set SS0 mov word ptr [edx + 060h],0 ; Set LDT mov word ptr [edx + 064h],0 ; Set T bit mov word ptr [edx + 066h],020adh ; I/O Map base address = sizeof(KTSS)+1
; ; Edit GDT entry for KGDT_MCA_TSS to create a valid TSS Descriptor ; mov ecx, PCR[PcGdt] ; Get GDT address lea eax, [ecx] + KGDT_MCA_TSS ; offset of MCA TSS in GDT mov ecx, eax
; ; Set Type field of TSS Descriptor ; mov byte ptr [ecx + 5], 089H ; P=1, DPL=0, Type = 9
; ; Set Base Address field of TSS Descriptor ; mov eax, edx ; TSS address in eax mov [ecx + KgdtBaseLow], ax shr eax, 16 mov [ecx + KgdtBaseHi],ah mov [ecx + KgdtBaseMid],al
; ; Set Segment limit for TSS Descriptor ; mov eax, MINIMUM_TSS_SIZE mov [ecx + KgdtLimitLow],ax
stdRET _HalpMcaCurrentProcessorSetTSS
stdENDP _HalpMcaCurrentProcessorSetTSS
INIT ends
PAGELK SEGMENT DWORD PUBLIC 'CODE' ;++ ; ;VOID ;HalpSetCr4MCEBit( ; VOID ; ) ; ; Routine Description: ; This function sets the CR4.MCE bit ; ; Arguments: ; None ; ; Return Value: ; None ; ;--
cPublicProc _HalpSetCr4MCEBit,0
mov eax, cr4 or eax, CR4_MCE mov cr4, eax stdRET _HalpSetCr4MCEBit
stdENDP _HalpSetCr4MCEBit
PAGELK ends end
|