        TITLE   "System Control Interrupt Service Routine"
;++
;
;  Copyright (c) 2001  Microsoft Corporation
;
;  Module Name:
;
;     sciinta.asm
;
;  Abstract:
;
;     This module implements the routines to handle a System Control Interrupt
;     (SCI) from the ACPI logic block or external SMI.
;
;  Environment:
;
;     Kernel mode only.
;
;--

        .586p
        .xlist
INCLUDE ks386.inc
INCLUDE callconv.inc
INCLUDE i386\kimacro.inc
INCLUDE i386\ix8259.inc
INCLUDE i386\mcpxacpi.inc
        .list

        EXTRNP  HalBeginSystemControlInterrupt,2,,FASTCALL
        EXTRNP  HalEndSystemLevelInterrupt,1,,FASTCALL
        EXTRNP  _KeInsertQueueDpc,3
        EXTRNP  _HalpAcpiTimerCarry,0
        EXTRN   _KiPCR:DWORD
        EXTRN   _HalpSystemControlInterruptDpc:DWORD

_TEXT   SEGMENT DWORD PUBLIC 'CODE'
        ASSUME  DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING

;++
;
; VOID
; HalpSystemControlInterrupt(
;     VOID
;     )
;
; Routine Description:
;
;    This routine is entered as the result of an interrupt generated by the
;    ACPI logic block or an external SMI that has been rerouted to the SCI.
;
; Arguments:
;
;    None.
;
; Return Value:
;
;    None.
;
;--
cPublicProc _HalpSystemControlInterrupt, 0

        ENTER_INTERRUPT

        mov     ecx, SCI_VECTOR - PRIMARY_VECTOR_BASE
        mov     edx, SCI_LEVEL
        push    0                       ; allocate space to save OldIrql
        fstCall HalBeginSystemControlInterrupt

;
; Check if the signal for an ACPI timer overflow has been set.  If so, clear the
; signal and increment the high bits of the performance counter.
;

        mov     edx, XPCICFG_LPCBRIDGE_IO_REGISTER_BASE_0 + MCPX_ACPI_PM1_STATUS_REGISTER
        in      al, dx
        and     al, PM1_TIMER_STATUS
        jz      NotAcpiTimerInterrupt
        out     dx, al                  ; clear signal by writing the bit back
        stdCall _HalpAcpiTimerCarry

;
; Check if the signal for the external SMI has been set.  If so, clear the
; signal and queue a DPC to talk to the SMC at a safe point.
;

NotAcpiTimerInterrupt:
        mov     edx, XPCICFG_LPCBRIDGE_IO_REGISTER_BASE_0 + MCPX_ACPI_GPE0_STATUS_REGISTER
        in      al, dx
        test    al, GPE0_EXTSMI_STATUS
        jz      NotExternalSMI
        mov     al, GPE0_EXTSMI_STATUS
        out     dx, al

        stdCall _KeInsertQueueDpc,<offset _HalpSystemControlInterruptDpc, 0, 0>

NotExternalSMI:
        mov     eax, SCI_VECTOR - PRIMARY_VECTOR_BASE
        LEVEL_INTERRUPT_EXIT

stdENDP _HalpSystemControlInterrupt

_TEXT   ends
        end
