NT4/private/ntos/nthals/halfire/ppc/pxsysbus.c
2020-09-30 17:12:29 +02:00

299 lines
6.3 KiB
C

/*
* Copyright (c) 1995 FirePower Systems, Inc.
* DO NOT DISTRIBUTE without permission
*
* $RCSfile: pxsysbus.c $
* $Revision: 1.30 $
* $Date: 1996/07/13 01:16:01 $
* $Locker: $
*/
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
pxsysbus.c
Abstract:
Author:
Environment:
Revision History:
Jim Wooldridge - ported to PowerPC
--*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arccodes.h>
#include "fpdebug.h"
#include "halp.h"
#include "phsystem.h"
#include "eisa.h"
#include "pxmemctl.h"
extern ULONG Vector2Irql[];
extern ULONG Vector2Affinity[];
//
// Which Ints on Processor 1?
//
BOOLEAN HalpGetAffinityCalled = FALSE;
#define TBS " "
void
HalpGetAffinity();
BOOLEAN
HalpTranslateSystemBusAddress(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN PHYSICAL_ADDRESS BusAddress,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress
);
ULONG
HalpGetSystemInterruptVector(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN ULONG BusInterruptLevel,
IN ULONG BusInterruptVector,
OUT PKIRQL Irql,
OUT PKAFFINITY Affinity
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,HalpGetSystemInterruptVector)
#endif
/*++
Routine Description:
This function translates a bus-relative address space and address into
a system physical address.
Arguments:
BusAddress - Supplies the bus-relative address
AddressSpace - Supplies the address space number.
Returns the host address space number.
AddressSpace == 0 => memory space
AddressSpace == 1 => I/O space
TranslatedAddress - Supplies a pointer to return the translated address
Return Value:
A return value of TRUE indicates that a system physical address
corresponding to the supplied bus relative address and bus address
number has been returned in TranslatedAddress.
A return value of FALSE occurs if the translation for the address was
not possible
--*/
BOOLEAN
HalpTranslateSystemBusAddress(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN PHYSICAL_ADDRESS BusAddress,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress
)
{
UNREFERENCED_PARAMETER( BusHandler );
UNREFERENCED_PARAMETER( RootHandler );
TranslatedAddress->HighPart = BusAddress.HighPart;
//
// Determine the address based on whether the bus address
// is in I/O space, system space, or bus memory space.
//
switch (*AddressSpace) {
case MEMORY_ADDRESS_SPACE:
//
// The address is in memory space.
//
TranslatedAddress->LowPart = BusAddress.LowPart +
PCI_MEMORY_PHYSICAL_BASE;
if (VER_PRODUCTBUILD > 1233) {
//
// Due to a change in NT defined spaces, our previous method
// of using AddressSpace to communicate a driver's mapping
// needs no longer will work. So, starting with Build 1297
// we need to make sure the display driver is not mapped into
// the PCI_MEMORY_PHYSICAL_BASE but into it's "natural"
// location.
//
// This is a temp fix and must be revisited so that we
// can more specifically detect the framebuffer based
// driver requirements and not affect other devices that
// may have a legitimate need for this address offset into
// a bus location.
//
if ((BusAddress.LowPart&0xf0000000)==(0x70000000)) {
TranslatedAddress->LowPart = BusAddress.LowPart;
}
}
break;
//
// Everyone should be assumed IO space if not otherwise requested
//
default:
case IO_ADDRESS_SPACE:
//
// The address is in I/O space.
//
TranslatedAddress->LowPart = BusAddress.LowPart +
IO_CONTROL_PHYSICAL_BASE;
break;
case SYSTEM_ADDRESS_SPACE:
//
// The address is in system space.
//
TranslatedAddress->LowPart = BusAddress.LowPart;
break;
}
*AddressSpace = 0;
if (TranslatedAddress->LowPart < BusAddress.LowPart) {
//
// A carry occurred.
//
TranslatedAddress->HighPart += 1;
}
return(TRUE);
}
/*++
Routine Description:
Arguments:
BusInterruptLevel - Supplies the bus specific interrupt level.
BusInterruptVector - Supplies the bus specific interrupt vector.
Irql - Returns the system request priority.
Affinity - Returns the system wide irq affinity.
Return Value:
Returns the system interrupt vector corresponding to the specified device.
--*/
ULONG
HalpGetSystemInterruptVector(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN ULONG BusInterruptLevel,
IN ULONG BusInterruptVector,
OUT PKIRQL Irql,
OUT PKAFFINITY Affinity
)
{
UNREFERENCED_PARAMETER( BusHandler );
UNREFERENCED_PARAMETER( RootHandler );
UNREFERENCED_PARAMETER( BusInterruptLevel );
if (HalpGetAffinityCalled == FALSE) {
HalpGetAffinity();
HalpGetAffinityCalled = TRUE;
}
*Affinity = Vector2Affinity[BusInterruptVector];
HDBG(DBG_INTERRUPTS|DBG_MPINTS,
HalpDebugPrint("HalpGetSystemInterruptVector: %x, %x, %d, %x\n",
BusInterruptLevel, BusInterruptVector, *Irql, *Affinity););
*Irql = (UCHAR) Vector2Irql[BusInterruptVector]; // see define in ntdef.h
//
// The vector is equal to the specified bus level plus the DEVICE_VECTORS.
//
BusInterruptLevel = BusInterruptVector;
HDBG(DBG_INTERRUPTS|DBG_MPINTS,
HalpDebugPrint( "%sint request: returning %x + %x = %x\n",
TBS, BusInterruptVector, DEVICE_VECTORS,
BusInterruptVector + DEVICE_VECTORS ););
return(BusInterruptVector + DEVICE_VECTORS);
}
//
// HalpGetAffinity()
//
// This is a simple routine that gets a value from NVRAM to
// overwrite the default value for where interrupts go.
// This is mostly a hack for now.
//
void
HalpGetAffinity()
{
CHAR buf[256];
PKPRCB pPRCB;
ULONG count;
extern HalpInitProcAffinity(PCHAR,ULONG);
if ((count = HalpProcessorCount()) < 2) {
HalpInitProcAffinity((PCHAR)0,1);
return;
}
pPRCB = KeGetCurrentPrcb();
if (pPRCB->BuildType & PRCB_BUILD_UNIPROCESSOR) {
HalpInitProcAffinity((PCHAR)0,1);
return;
}
if (HalGetEnvironmentVariable("UNIPROCESSOR", sizeof(buf), buf)
== ESUCCESS) {
if (_stricmp(buf, "true") == 0) {
HalpInitProcAffinity((PCHAR)0,1);
return;
}
}
// it is mulitprocessor system.
//
// Get PROCNINTS Value from NVRAM
//
if (HalGetEnvironmentVariable("PROCNINTS", sizeof(buf), buf)
== ESUCCESS) {
HalpInitProcAffinity(buf,count);
return;
} else {
HalpInitProcAffinity((PCHAR)0,count);
return;
}
}