;-----------------------------------------------------------------------------
;
; IBM/Microsoft Confidential
;
; Copyright (c) IBM Corporation 1987, 1989
; Copyright (c) Microsoft Corporation 1987, 1989
;
; All Rights Reserved
;
;-----------------------------------------------------------------------------
; DosHlpWHYNMI contains the following DosHlp routines:
;
;       DosHlpWhyNMI                - Return message explaining cause of NMI
;       DosHlpAckNMI                - Acknowledge NMI
;-----------------------------------------------------------------------------

        .xlist
        include basemaca.inc            ; Base macros
        include osmaca.inc              ; Os macros
        include doshlp.inc              ; DosHlp macros
        include eisa.inc                ; EISA definitions
        include sysinvar.inc            ; Definition of DOSHLP_DATASEL
        include basemid.inc
        include mi.inc
        include iodelay.inc
        include struc.inc               ;Structure macros
        .list

        include segments.inc            ; DosHlp segment definitions

        .386p

        EXTRN16 DH32ProtGetMessage
        EXTRN16 DH16FindParity
        EXTRN16 DH16DisableCache
        EXTRN16 DH16EnableCache
        EXTRN16 DH16GetErrorLogPtr
        EXTRN16 DH16WriteErrorLog
        EXTRN16 DH16ReadErrorLog
        EXTRN16 DH16ResetParity


DosHlpData SEGMENT

        extrn   _config_flags:word
        extrn   _fSubModel:byte
        extrn   _MachineSubModel:byte
eisa_nmi_index  dw      0
DosHlpData ENDS

DosHlp32Data SEGMENT

;*   NMI error code messages

NmiMsg          label   word
                dw      MSG_NMI
                dw      MSG_NMI_EXC1
                dw      MSG_NM12_EXC2
                dw      MSG_NMI2_EXC3
                dw      MSG_NMI2_EXC4
                dw      MSG_EISA_NMI_SOFTWARE
                dw      MSG_EISA_NMI_BUS
                dw      MSG_EISA_NMI_FAILSAFE
                dw      MSG_EISA_NMI_IOCHK
                dw      MSG_EISA_NMI_PARITY
NmiMsgCnt       equ     ($ - NmiMsg)/2

DosHlp32Data ENDS


DosHlp32Code SEGMENT

;***    DosHlpWhyNMI - DosHlp Subroutine to return NMI error message
;
;       DosHlpWhyNMI can interrogate the hardware to determine the
;       cause of the non-maskable-interrupt and pass a message
;       pointer back to the kernel to be displayed to the user.
;
;       On the AT, we can not determine the cause so we always
;       return the same error message.
;
;       Entry:  AX : NMI error number
;
;       Exit:   FS:EDX->Appropriate error message
;
;       USES:   Flags
;
;       Note:   Upon entry AX will contain 0 if it is an AT
;               or EISA architecture
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING

        PUBLIC  DHWhyNMI
DHWhyNMI        PROC NEAR

        push    eax                     ; save eax

        mov     dx,DOSHLP_DATASEL
        mov     fs,dx                   ; get selector
        assume  fs:DGROUP

        test    _config_flags, CFG_EISA ; Are we on EISA?
        jz      short wnmi20            ; no - report given message
        mov     ax,eisa_nmi_index

wnmi20:
        movzx   eax,ax
        mov     ax,NmiMsg[eax*type NmiMsg]
        CALLDH16    DH32ProtGetMessage      ; Message address in DS:ESI
        mov     ax,ds                       ; Put message address in FS:EDX
        mov     fs,ax
        mov     edx,esi

        pop     eax
        RET

DHWhyNMI              ENDP


;***    DosHlpAckNMI - DosHlp Subroutine to Acknowledge NMI
;
;       DosHlpAckNMI acknowledges an NMI so that further IRETs will
;       not cause any further NMIs. It also obtains and saves any
;       hardware information that DosHlpWhyNMI needs to process a
;       subsequent request about the cause of the NMI.
;
;       ENTRY:  None
;
;       EXIT:   BX contains NMI error code ( 1 = Parity, 2 = IO Channel Check)
;
;       USES:   Flags
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING

        PUBLIC  DHAckNMI
DHAckNMI        PROC NEAR

        extrn   DosHlp32Delay: near

        push    eax
        push    ecx
        push    edx
        push    es

        mov     ax,DOSHLP_DATASEL
        mov     es,ax
        assume  es:DGROUP

        xor     eax,eax                 ; clear eax

     ;* @V3.0RV01 - 137252
     ;* test    _config_flags, CFG_EISA ; Are we on EISA?
     ;* jz      short anmi22            ; no - skip getting reason for NMI

        in      al,EisaNMI_Port1        ; get first NMI port info - 61h
        test    _config_flags, CFG_EISA ; Are we on EISA? - @V3.0RV01
        jz      short anmi19            ; no - it is ISA - so skip
        shl     ax,2                    ; put al[6-7] in ah[0-1]
        mov     dx,EisaNMI_Port2
        in      al,dx                   ; get second NMI port info
        and     ax,EisaNMI_Ports_Mask   ; mask out uneeded bits
        jmp     anmi20
anmi19:
        and     ax,11000000b            ; isa nmi port mask - @V3.0RV01
anmi20:
        bsf     ax,ax                   ; get index of set bit
        jnz     short anmi22            ; bit was set - Get message
        xor     ax,ax                   ; no bit set - Set generic index
anmi22:
        mov     eisa_nmi_index,ax       ; save NMI message index
        in      al,NMI_STATUS_PORT      ; NMI status port = EisaNMI_Port1
        or      al,(NMI_IOCHK_CONTROL OR NMI_FAILSAFE_CONTROL)
                                        ; Mask further NMIs - If on an EISA
                                        ; machine, FAILSAFE is actually the
                                        ; PARITY NMI but needs to be masked
                                        ; all the same
        call    DosHlp32Delay
        out     NMI_STATUS_PORT,al      ; write value back to port

        test    _config_flags, CFG_EISA ; Are we on EISA?
        jz      short anmi25            ; no - skip port 2

        mov     dx,EisaNMI_Port2        ; NMI status port 2
        in      al,dx
        and     al,11110001b            ; Mask further NMIs
        call    DosHlp32Delay
        out     dx,al                   ; write value back to port
anmi25:
        xor     ebx,ebx
        cmp     eisa_nmi_index,0
        jz      anmi30
        mov     bx,eisa_nmi_index
        test    _config_flags, CFG_EISA ; Are we on EISA?
        jnz     anmi30
        cmp     eisa_nmi_index,7        ; @V3.0RV01 - 137252
        jne     anmi26                  ; @V3.0RV01 - 137252
        mov     bl,01H                  ; @V3.0RV01 - 137252
        jmp     anmi30                  ; @V3.0RV01 - 137252
anmi26:                                 ; @V3.0RV01 - 137252
        cmp     eisa_nmi_index,6        ; @V3.0RV01 - 137252
        jne     anmi30                  ; @V3.0RV01 - 137252
        mov     bl,02H                  ; @V3.0RV01 - 137252
anmi30:
        pop     es
        pop     edx
        pop     ecx
        pop     eax
        RET

DHAckNMI              ENDP

;***    DHGetErrorLogPtr - Get Error Log Pointer
;
;       DHGetErrorLogPtr returns the current pointer to NVRAM error log
;
;       ENTRY:  NONE
;
;       EXIT:   AX = -1 No NVRAM for machine
;               AX = Error Log Pointer
;
;       USES:   Flags
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING
public DHGetErrorLogPtr
DHGetErrorLogPtr PROC NEAR
        CALLDH16    DH16GetErrorLogPtr
        ret
DHGetErrorLogPtr ENDP


;***    DHWriteErrorLog - Write Error Log
;
;       DHWriteErrorLog Writes to NVRAM error log
;
;       ENTRY:  AX = Error Log Pointer
;              EDX = Physical Address to put into log
;
;       EXIT:  NONE
;
;       USES:   Flags
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING
public DHWriteErrorLog
DHWriteErrorLog PROC NEAR
        CALLDH16    DH16WriteErrorLog
        ret
DHWriteErrorLog ENDP

;***    DHReadErrorLog - Read Error Log
;
;       DHReadErrorLog Reads NVRAM error log
;
;       ENTRY:  AX = Error Log Pointer
;
;
;       EXIT:  EDX = -1 NO Physical Address
;              EDX = Physical Address in log
;
;       USES:   Flags
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING
public DHReadErrorLog
DHReadErrorLog PROC NEAR
        CALLDH16    DH16ReadErrorLog
        ret
DHReadErrorLog ENDP

;***    DHResetParity - Reset Parity
;
;       DHResetParity is the thunk layer that calls the 16 bit version to
;       reset parity
;
;       ENTRY:  NONE
;
;       EXIT:   NC -> if parity reset
;               C -> if parity not reset
;
;       USES:   Flags
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING
public DHResetParity
DHResetParity PROC NEAR
        CALLDH16    DH16ResetParity
        ret
DHResetParity ENDP

;***    DHFindParityParity - FindParity Parity
;
;       DHFindParity is the thunk layer that calls the 16 bit version to
;       find parity
;
;       ENTRY:  DS:ESI->memory containing possible parity
;                  ECX->number of bytes to test for parity
;
;       EXIT:   NC -> if parity not found
;               C -> if parity found
;
;       USES:   Flags
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING
public DHFindParity
DHFindParity PROC NEAR
        CALLDH16    DH16FindParity
        ret
DHFindParity ENDP

;***    DHDisableCache - Disable Cache
;
;       DHDisableCache is the thunk layer that calls the 16 bit version to
;       disable hardware cache
;
;       ENTRY:  NONE
;
;       EXIT:   NC -> if cache disabled
;               C -> if cache not disabled
;
;       USES:   Flags
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING
public DHDisableCache
DHDisableCache PROC NEAR
        CALLDH16    DH16DisableCache
        ret
DHDisableCache ENDP

;***    DHEnableCache - Enable Cache
;
;       DHEnableCache is the thunk layer that calls the 16 bit version to
;       enable hardware cache
;
;       ENTRY:  NONE
;
;       EXIT:   NC -> if cache enabled
;               C -> if cache not enabled
;
;       USES:   Flags
;
        ASSUME  CS:DosHlp32Code,DS:NOTHING,ES:NOTHING,FS:NOTHING,GS:NOTHING,SS:NOTHING
public DHEnableCache
DHEnableCache PROC NEAR
        CALLDH16    DH16EnableCache
        ret
DHEnableCache ENDP

DosHlp32Code    ENDS
        END
