You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
273 lines
5.2 KiB
273 lines
5.2 KiB
/*++
|
|
|
|
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;
|
|
|
|
flags = HalpDisableInterrupts();
|
|
|
|
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;
|
|
|
|
HalpRestoreInterrupts(flags);
|
|
}
|
|
|
|
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;
|
|
|
|
flags = HalpDisableInterrupts();
|
|
|
|
//
|
|
// 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;
|
|
|
|
HalpRestoreInterrupts(flags);
|
|
}
|
|
|
|
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
|
|
|