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.
326 lines
7.0 KiB
326 lines
7.0 KiB
|
|
|
|
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Copyright (c) 1994 MOTOROLA, INC. All Rights Reserved. This file
|
|
contains copyrighted material. Use of this file is restricted
|
|
by the provisions of a Motorola Software License Agreement.
|
|
|
|
Copyright (c) 1996 International Business Machines Corporation
|
|
|
|
Module Name:
|
|
|
|
pxmemctl.c
|
|
|
|
Abstract:
|
|
|
|
The module initializes any planar registers.
|
|
This module also implements machince check parity error handling.
|
|
|
|
Author:
|
|
|
|
Jim Wooldridge ([email protected])
|
|
|
|
|
|
Revision History:
|
|
|
|
T. White -- Added dword I/O to allow GXT150P to work correctly
|
|
|
|
Special Note:
|
|
|
|
Please make sure that the dword I/O mechanisms are carried
|
|
forward for any box which is to support the GXT150P graphics
|
|
adapter. The GXT150P graphics adapter runs in any PowerPC
|
|
machine with a standard PCI bus connector.
|
|
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
#include "pci.h"
|
|
#include "pcip.h"
|
|
|
|
extern PVOID HalpPciConfigBase;
|
|
#define PCI_INTERRUPT_ROUTING_SCSI 13
|
|
#define PCI_INTERRUPT_ROUTING_OTHER 15
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE,HalpGetPCIIrq)
|
|
#endif
|
|
|
|
ULONG HalpPciConfigSlot[] = { 0x0800,
|
|
0x1000,
|
|
0x2000,
|
|
0x4000,
|
|
0x8000,
|
|
0x10000,
|
|
0x20000,
|
|
0x40000,
|
|
};
|
|
ULONG HalpPciMaxSlots = 7;
|
|
|
|
ULONG
|
|
HalpTranslatePciSlotNumber (
|
|
ULONG BusNumber,
|
|
ULONG SlotNumber
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine translate a PCI slot number to a PCI device number.
|
|
This is a sandalfoot memory map implementation.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Returns length of data written.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Sandalfoot only has 1 PCI bus so bus number is unused
|
|
//
|
|
|
|
UNREFERENCED_PARAMETER(BusNumber);
|
|
|
|
return ((ULONG) ((PUCHAR) HalpPciConfigBase + HalpPciConfigSlot[SlotNumber]));
|
|
|
|
}
|
|
|
|
|
|
ULONG
|
|
HalpPhase0SetPciDataByOffset (
|
|
ULONG BusNumber,
|
|
ULONG SlotNumber,
|
|
PUCHAR Buffer,
|
|
ULONG Offset,
|
|
ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine writes to PCI configuration space prior to bus handler installation.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Returns length of data written.
|
|
|
|
--*/
|
|
|
|
{
|
|
PUCHAR to;
|
|
PUCHAR from;
|
|
ULONG tmpLength;
|
|
PULONG ulong_to, ulong_from;
|
|
|
|
if (SlotNumber < HalpPciMaxSlots) {
|
|
|
|
to = (PUCHAR)HalpPciConfigBase + HalpPciConfigSlot[SlotNumber];
|
|
to += Offset;
|
|
from = Buffer;
|
|
|
|
// The GXT150P graphics adapter requires the use of dword I/O
|
|
// to some of its PCI configuration registers. Therefore, this
|
|
// code uses dword I/O when possible.
|
|
|
|
// If the bus address is not dword aligned or the length
|
|
// is not a multiple of 4 (dword size) bytes, then use byte I/O
|
|
if(((ULONG)to & 0x3)||(Length & 0x3)){
|
|
tmpLength = Length;
|
|
while (tmpLength > 0) {
|
|
*to++ = *from++;
|
|
tmpLength--;
|
|
}
|
|
// If the bus address is dword aligned and the length is
|
|
// a multiple of 4 (dword size) bytes, then use dword I/O
|
|
}else{
|
|
ulong_to = (PULONG) to;
|
|
ulong_from = (PULONG) from;
|
|
tmpLength = Length >> 2;
|
|
while (tmpLength > 0) {
|
|
*ulong_to++ = *ulong_from++;
|
|
tmpLength--;
|
|
}
|
|
}
|
|
|
|
return(Length);
|
|
}
|
|
else {
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
ULONG
|
|
HalpPhase0GetPciDataByOffset (
|
|
ULONG BusNumber,
|
|
ULONG SlotNumber,
|
|
PUCHAR Buffer,
|
|
ULONG Offset,
|
|
ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine reads PCI config space prior to bus handlder installation.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Amount of data read.
|
|
|
|
--*/
|
|
|
|
{
|
|
PUCHAR to;
|
|
PUCHAR from;
|
|
ULONG tmpLength;
|
|
PULONG ulong_to, ulong_from;
|
|
|
|
if (SlotNumber < HalpPciMaxSlots) {
|
|
|
|
from = (PUCHAR)HalpPciConfigBase + HalpPciConfigSlot[SlotNumber];
|
|
from += Offset;
|
|
to = Buffer;
|
|
|
|
// The GXT150P graphics adapter requires the use of dword I/O
|
|
// to some of its PCI configuration registers. Therefore, this
|
|
// code uses dword I/O when possible.
|
|
|
|
// If the bus address is not dword aligned or the length
|
|
// is not a multiple of 4 (dword size) bytes, then use byte I/O
|
|
if(((ULONG)from & 0x3)||(Length & 0x3)){
|
|
tmpLength = Length;
|
|
while (tmpLength > 0) {
|
|
*to++ = *from++;
|
|
tmpLength--;
|
|
}
|
|
// If the bus address is dword aligned and the length is
|
|
// a multiple of 4 (dword size) bytes, then use dword I/O
|
|
}else{
|
|
ulong_to = (PULONG) to;
|
|
ulong_from = (PULONG) from;
|
|
tmpLength = Length >> 2;
|
|
while (tmpLength > 0) {
|
|
*ulong_to++ = *ulong_from++;
|
|
tmpLength--;
|
|
}
|
|
}
|
|
|
|
return(Length);
|
|
}
|
|
else {
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
NTSTATUS
|
|
HalpGetPCIIrq (
|
|
IN PBUS_HANDLER BusHandler,
|
|
IN PBUS_HANDLER RootHandler,
|
|
IN PCI_SLOT_NUMBER PciSlot,
|
|
OUT PSUPPORTED_RANGE *Interrupt
|
|
)
|
|
{
|
|
ULONG buffer[PCI_COMMON_HDR_LENGTH/sizeof(ULONG)];
|
|
PPCI_COMMON_CONFIG PciData;
|
|
|
|
#define PCI_VENDOR_NCR 0x1000
|
|
|
|
PciData = (PPCI_COMMON_CONFIG) buffer;
|
|
HalGetBusData (
|
|
PCIConfiguration,
|
|
BusHandler->BusNumber,
|
|
PciSlot.u.AsULONG,
|
|
PciData,
|
|
PCI_COMMON_HDR_LENGTH
|
|
);
|
|
|
|
if (PciData->VendorID == PCI_INVALID_VENDORID ||
|
|
PCI_CONFIG_TYPE (PciData) != 0) {
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
*Interrupt = ExAllocatePool (PagedPool, sizeof (SUPPORTED_RANGE));
|
|
if (!*Interrupt) {
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlZeroMemory (*Interrupt, sizeof (SUPPORTED_RANGE));
|
|
|
|
if (PciSlot.u.bits.DeviceNumber == 1) {
|
|
(*Interrupt)->Base = PCI_INTERRUPT_ROUTING_SCSI;
|
|
(*Interrupt)->Limit = PCI_INTERRUPT_ROUTING_SCSI;
|
|
} else {
|
|
(*Interrupt)->Base = PCI_INTERRUPT_ROUTING_OTHER;
|
|
(*Interrupt)->Limit = PCI_INTERRUPT_ROUTING_OTHER;
|
|
}
|
|
|
|
#if defined(SOFT_HDD_LAMP)
|
|
|
|
if ( (PciData->BaseClass == 1) ||
|
|
( (PciData->VendorID == PCI_VENDOR_NCR) && (PciData->DeviceID == 1) ) ) {
|
|
//
|
|
// This device is a Mass Storage Controller, set flag to
|
|
// turn on the HDD Lamp when interrupts come in on this
|
|
// vector.
|
|
//
|
|
// N.B. We recognize NCR 810 controllers as they were implemented
|
|
// before class codes.
|
|
//
|
|
|
|
extern ULONG HalpMassStorageControllerVectors;
|
|
|
|
HalpMassStorageControllerVectors |= 1 << (*Interrupt)->Base;
|
|
}
|
|
|
|
#endif
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
HalpMapPlugInPciBridges(
|
|
UCHAR NoBuses
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Looks for any unexpected (plug-in) PCI-PCI bridges so
|
|
that interrupts can be mapped from these buses back
|
|
into the interrupt controller.
|
|
|
|
Arguments:
|
|
|
|
NoBuses -- This is the number of buses that HalpGetPciBridgeConfig found
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
// Sandalfoot doesn't support plug-in PCI busses!!!
|
|
|
|
return;
|
|
}
|
|
|