windows-nt/Source/XPSP1/NT/base/hals/halacpi/pmpic.c
2020-09-26 16:20:57 +08:00

293 lines
5.1 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Module Name:
pmpic.c
Abstract:
This file contains functions that are specific to
the PIC version of the ACPI hal.
Author:
Jake Oshins
Environment:
Kernel mode only.
Revision History:
*/
#include "halp.h"
#include "acpitabl.h"
#include "xxacpi.h"
#include "eisa.h"
#include "ixsleep.h"
VOID
HalpAcpiSetTempPicState(
VOID
);
VOID
HalpMaskAcpiInterrupt(
VOID
);
VOID
HalpUnmaskAcpiInterrupt(
VOID
);
extern PVOID HalpEisaControlBase;
#define EISA_CONTROL (PUCHAR)&((PEISA_CONTROL) HalpEisaControlBase)
BOOLEAN HalpPicStateIntact = TRUE;
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGELK, HalpAcpiSetTempPicState)
#pragma alloc_text(PAGELK, HalpSetAcpiEdgeLevelRegister)
#pragma alloc_text(PAGELK, HalpAcpiPicStateIntact)
#pragma alloc_text(PAGELK, HalpSaveInterruptControllerState)
#pragma alloc_text(PAGELK, HalpRestoreInterruptControllerState)
#pragma alloc_text(PAGELK, HalpSetInterruptControllerWakeupState)
#pragma alloc_text(PAGELK, HalpPostSleepMP)
#pragma alloc_text(PAGELK, HalpMaskAcpiInterrupt)
#pragma alloc_text(PAGELK, HalpUnmaskAcpiInterrupt)
#pragma alloc_text(PAGE, HaliSetVectorState)
#pragma alloc_text(PAGE, HaliIsVectorValid)
#endif
VOID
HaliSetVectorState(
IN ULONG Vector,
IN ULONG Flags
)
{
return;
}
BOOLEAN
HaliIsVectorValid(
IN ULONG Vector
)
{
if (Vector < 16) {
return TRUE;
}
return FALSE;
}
VOID
HalpAcpiSetTempPicState(
VOID
)
{
ULONG flags;
USHORT picMask;
_asm {
pushfd
pop eax
mov flags, eax
cli
}
HalpInitializePICs(FALSE);
//
// Halacpi lets the PCI interrupt programming be
// dynamic. So...
//
// Unmask only the clock sources on the PIC and the
// ACPI vector. The rest of the vectors will be
// unmasked later, after we have restored PCI IRQ
// routing.
//
picMask = 0xfefe; // mask everything but clocks
//
// Unmask ACPI vector
//
picMask &= ~(1 << (UCHAR)HalpFixedAcpiDescTable.sci_int_vector);
//
// Write the mask into the hardware.
//
WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt1ControlPort1,
(UCHAR)(picMask & 0xff));
WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt2ControlPort1,
(UCHAR)((picMask >> 8) & 0xff));
//
// For now, set the edge-level control register
// so that all vectors are edge except the
// ACPI vector. This is done because the PIC
// will trigger if an idle ISA vector is set to
// edge. After the ACPI driver resets all the
// PCI vectors to what we thought they should be,
//
HalpSetAcpiEdgeLevelRegister();
HalpPicStateIntact = FALSE;
_asm {
mov eax, flags
push eax
popfd
}
}
VOID
HalpSetAcpiEdgeLevelRegister(
VOID
)
{
USHORT elcr;
//
// The idea here is to set the ELCR so that only the ACPI
// vector is set to 'level.' That way we can reprogram
// the PCI interrupt router without worrying that the
// PIC will start triggering endless interrupts because
// we have a source programmed to level that is being
// routed to the ISA bus.
//
if (HalpFixedAcpiDescTable.sci_int_vector < PIC_VECTORS) {
elcr = 1 << HalpFixedAcpiDescTable.sci_int_vector;
WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt1EdgeLevel,
(UCHAR)(elcr & 0xff));
WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt2EdgeLevel,
(UCHAR)(elcr >> 8));
}
}
VOID
HalpRestoreInterruptControllerState(
VOID
)
{
ULONG flags;
USHORT picMask;
_asm {
pushfd
pop eax
mov flags, eax
cli
}
//
// This function is called after PCI interrupt routing has
// been restored.
//
WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt1ControlPort1,
HalpMotherboardState.PicState.MasterMask);
WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt2ControlPort1,
HalpMotherboardState.PicState.SlaveMask);
HalpRestorePicEdgeLevelRegister();
HalpPicStateIntact = TRUE;
_asm {
mov eax, flags
push eax
popfd
}
}
BOOLEAN
HalpAcpiPicStateIntact(
VOID
)
{
return HalpPicStateIntact;
}
VOID
HalpSaveInterruptControllerState(
VOID
)
{
HalpSavePicState();
}
VOID
HalpSetInterruptControllerWakeupState(
ULONG Context
)
{
HalpAcpiSetTempPicState();
}
VOID
HalpPostSleepMP(
IN LONG NumberProcessors,
IN volatile PLONG Number
)
{
}
VOID
HalpMaskAcpiInterrupt(
VOID
)
{
}
VOID
HalpUnmaskAcpiInterrupt(
VOID
)
{
}
#if DBG
NTSTATUS
HalpGetApicIdByProcessorNumber(
IN UCHAR Processor,
IN OUT USHORT *ApicId
)
/*++
Routine Description:
This routine only exists on DEBUG builds of the PIC ACPI HAL because
that HAL is build MP and the SRAT code will be included. The SRAT
code will not be exercised but needs this routine in order to link.
Arguments:
Ignored.
Return Value:
STATUS_NOT_FOUND
--*/
{
return STATUS_NOT_FOUND;
}
#endif