mirror of https://github.com/lianthony/NT4.0
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.
329 lines
5.9 KiB
329 lines
5.9 KiB
/*++
|
|
|
|
Copyright (c) 1992 NCR Corporation
|
|
|
|
Module Name:
|
|
|
|
ncrqic.c
|
|
|
|
Abstract:
|
|
|
|
|
|
Author:
|
|
|
|
Rick Ulmer
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
#include "ncr.h"
|
|
#include "ncrsus.h"
|
|
#include "stdio.h"
|
|
|
|
PQIC_IPI IpiAddresses[NCR_MAX_NUMBER_QUAD_PROCESSORS];
|
|
PQIC_IPI PhysicalIpiAddresses[NCR_MAX_NUMBER_QUAD_PROCESSORS];
|
|
|
|
extern PPROCESSOR_BOARD_INFO SUSBoardInfo;
|
|
extern ULONG NCRLogicalDyadicProcessorMask;
|
|
extern ULONG NCRLogicalQuadProcessorMask;
|
|
extern ULONG NCRLogicalNumberToPhysicalMask[];
|
|
extern ULONG NCRExistingQuadProcessorMask;
|
|
|
|
extern ULONG NCRActiveProcessorMask;
|
|
|
|
ULONG NCRQicSpurCount = 0;
|
|
|
|
|
|
VOID
|
|
HalQicRequestIpi (
|
|
IN KAFFINITY Mask,
|
|
IN ULONG Level
|
|
);
|
|
|
|
VOID
|
|
HalRequestIpi (
|
|
IN KAFFINITY Mask
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Send Ipi's to processors
|
|
|
|
Arguments:
|
|
Processors Mask;
|
|
|
|
Return Value:
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (Mask & NCRLogicalDyadicProcessorMask) {
|
|
HalVicRequestIpi(Mask & NCRLogicalDyadicProcessorMask);
|
|
}
|
|
|
|
if (Mask & NCRLogicalQuadProcessorMask) {
|
|
HalQicRequestIpi(Mask & NCRLogicalQuadProcessorMask, NCR_IPI_LEVEL_CPI);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
HalQicRequestIpi (
|
|
IN KAFFINITY Mask,
|
|
IN ULONG Level
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Send Ipi's to processors
|
|
|
|
Arguments:
|
|
Processors Mask;
|
|
|
|
Return Value:
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
PKPCR pPCR;
|
|
ULONG my_logical_mask;
|
|
|
|
PQIC_IPI IpiAddress;
|
|
ULONG logical_mask;
|
|
ULONG cpu_id;
|
|
|
|
|
|
pPCR = KeGetPcr();
|
|
my_logical_mask = ((PProcessorPrivateData)pPCR->HalReserved)->MyLogicalMask;
|
|
|
|
logical_mask = Mask;
|
|
|
|
cpu_id = 0;
|
|
|
|
//
|
|
// See if we need to send the cpi two ourselves
|
|
//
|
|
|
|
if (my_logical_mask & logical_mask) {
|
|
WRITE_PORT_UCHAR((PUCHAR)(0xFCC0+(0x8*Level)),0x1);
|
|
logical_mask ^= my_logical_mask;
|
|
}
|
|
|
|
|
|
//
|
|
// Now send to all other processors
|
|
//
|
|
|
|
while (logical_mask) {
|
|
if (logical_mask & 0x01) {
|
|
IpiAddress = IpiAddresses[cpu_id];
|
|
IpiAddress->QIC_LEVEL[Level].Ipi = 1;
|
|
}
|
|
cpu_id++;
|
|
logical_mask >>= 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HalQicStartupIpi (
|
|
ULONG ProcessorNumber
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Send Ipi's to processors
|
|
|
|
Arguments:
|
|
Processors Mask;
|
|
|
|
Return Value:
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
register QIC_IPI *IpiAddress;
|
|
|
|
IpiAddress = PhysicalIpiAddresses[ProcessorNumber];
|
|
IpiAddress->QIC_LEVEL[2].Ipi = 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
ULONG
|
|
NCRClearQicIpi (
|
|
IN Level
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Send Ipi's to processors
|
|
|
|
Arguments:
|
|
Processors Mask;
|
|
|
|
Return Value:
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
PKPCR pPCR;
|
|
ULONG my_logical_number;
|
|
register QIC_IPI *IpiAddress;
|
|
|
|
|
|
pPCR = KeGetPcr();
|
|
my_logical_number = ((PProcessorPrivateData)pPCR->HalReserved)->MyLogicalNumber;
|
|
|
|
//
|
|
// Clear the interrupt
|
|
//
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)0xfc8b, (UCHAR) (0x1<<Level));
|
|
|
|
// there is some window during bootup where we are hitting this code before
|
|
// IpiAddresses is filled in
|
|
|
|
IpiAddress = IpiAddresses[my_logical_number];
|
|
|
|
return (IpiAddress->QIC_LEVEL[Level].Ipi);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
NCRFindIpiAddress (
|
|
ULONG ProcessorNumber
|
|
)
|
|
|
|
{
|
|
ULONG physical_processor_number;
|
|
ULONG physical_mask;
|
|
ULONG mask;
|
|
ULONG i;
|
|
|
|
physical_mask = NCRLogicalNumberToPhysicalMask[ProcessorNumber];
|
|
|
|
physical_processor_number = 0;
|
|
|
|
for ( mask = 0x1; mask < (0x1 << NCR_MAX_NUMBER_PROCESSORS); mask <<= 1, physical_processor_number++) {
|
|
if (mask & physical_mask) {
|
|
break;
|
|
}
|
|
}
|
|
IpiAddresses[ProcessorNumber] = PhysicalIpiAddresses[physical_processor_number];
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
NCRMapIpiAddresses (
|
|
)
|
|
|
|
{
|
|
ULONG i;
|
|
PQUAD_DESCRIPTION quad_desc;
|
|
PCHAR cpiaddr[8] = {0};
|
|
ULONG cpipage[8] = {0};
|
|
ULONG modules;
|
|
ULONG slot;
|
|
ULONG cpu_offset;
|
|
ULONG proc_id;
|
|
ULONG physical_processor_number;
|
|
ULONG mask;
|
|
|
|
if (NCRExistingQuadProcessorMask == 0) {
|
|
return;
|
|
}
|
|
|
|
physical_processor_number = 0;
|
|
|
|
for ( mask = NCRExistingQuadProcessorMask; mask != 0; mask >>= 1, physical_processor_number++) {
|
|
|
|
if (!(mask & 1)) {
|
|
continue;
|
|
}
|
|
|
|
slot = (physical_processor_number / 4);
|
|
proc_id = physical_processor_number % 4;
|
|
|
|
DBGMSG(("NCRMapIpiAddress: Physical Proc 0x%x, slot = 0x%x, proc_id = 0x%x\n",
|
|
physical_processor_number, slot, proc_id));
|
|
|
|
modules = SUSBoardInfo->NumberOfBoards;
|
|
quad_desc = SUSBoardInfo->QuadData;
|
|
|
|
cpu_offset = proc_id * 0x100;
|
|
|
|
DBGMSG(("NCRMapIpiAddress: modules = %d\n",modules));
|
|
|
|
for ( i = 0; i < modules; quad_desc++, i++) {
|
|
|
|
DBGMSG(("NCRMapIpiAddress: quad_desc Type = 0x%x, slot = 0x%x\n",quad_desc->Type, quad_desc->Slot));
|
|
|
|
if ( quad_desc->Slot == (slot+1)) {
|
|
if (quad_desc->Type == QUAD ) {
|
|
if (cpipage[slot] == 0 ) {
|
|
cpipage[slot] = (ULONG) quad_desc->IpiBaseAddress & ~POFFMASK;
|
|
cpiaddr[slot] = HalpMapPhysicalMemory(cpipage[slot],1);
|
|
}
|
|
PhysicalIpiAddresses[physical_processor_number] =
|
|
cpiaddr[slot]+(cpu_offset+(quad_desc->IpiBaseAddress & POFFMASK));
|
|
|
|
DBGMSG(("NCRMapIpiAddress: Proc %d, Address = 0x%x\n",
|
|
physical_processor_number,
|
|
PhysicalIpiAddresses[physical_processor_number]));
|
|
|
|
break;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
NCRHandleQicSpuriousInt (TrapFramePtr, ExceptionRecordPtr)
|
|
IN PKTRAP_FRAME TrapFramePtr;
|
|
IN PVOID ExceptionRecordPtr;
|
|
/*++
|
|
|
|
Routine Description:
|
|
Handles the NCR Qic Spurious interrupts
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
none.
|
|
|
|
--*/
|
|
{
|
|
UCHAR qic_irr0;
|
|
UCHAR qic_irr1;
|
|
|
|
NCRQicSpurCount++;
|
|
|
|
#ifdef NEVER
|
|
qic_irr0 = READ_PORT_UCHAR(0xfc82);
|
|
qic_irr1 = READ_PORT_UCHAR(0xfc83);
|
|
|
|
DBGMSG(("NCRHandleQicSpurious: Count %d, QicIrr0 = 0x%x, QicIrr1 = 0x%x\n",
|
|
NCRQicSpurCount, qic_irr0, qic_irr1));
|
|
#endif
|
|
}
|