293 lines
5.1 KiB
C
293 lines
5.1 KiB
C
|
/*++
|
|||
|
|
|||
|
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
|
|||
|
|