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

300 lines
5.7 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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) 1995-96 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 (jimw@austin.vnet.ibm.com)
Revision History:
--*/
#include "halp.h"
#include "pci.h"
#include "pcip.h"
extern PVOID HalpPciConfigBase;
#define PCI_INTERRUPT_ROUTING_OTHER 15 //IBMCPK: should we really have seperate scsi int??
#define PCI_INTERRUPT_ROUTING_SCSI PCI_INTERRUPT_ROUTING_OTHER
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,HalpGetPCIIrq)
#endif
ULONG HalpPciMaxSlots = PCI_MAX_DEVICES;
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
//
PCI_TYPE1_CFG_BITS PciConfig;
PCI_SLOT_NUMBER PciSlotNumber;
PciSlotNumber.u.AsULONG = SlotNumber;
PciConfig.u.AsULONG = 0;
PciConfig.u.bits.DeviceNumber = PciSlotNumber.u.bits.DeviceNumber;
PciConfig.u.bits.FunctionNumber = PciSlotNumber.u.bits.FunctionNumber;
PciConfig.u.bits.BusNumber = BusNumber;
PciConfig.u.bits.Enable = TRUE;
return (PciConfig.u.AsULONG);
}
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.
--*/
{
ULONG to;
PUCHAR from;
ULONG tmpLength;
ULONG i;
if (SlotNumber < HalpPciMaxSlots) {
to = (ULONG) HalpPciConfigBase + (SlotNumber << 11);
to += Offset;
from = Buffer;
tmpLength = Length;
while (tmpLength > 0) {
WRITE_PORT_ULONG ((PUCHAR)HalpIoControlBase + 0xCF8, to );
i = to % sizeof(ULONG);
WRITE_PORT_UCHAR ((PUCHAR)HalpIoControlBase + 0xCFC + i,*from);
to++;
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;
ULONG from;
ULONG tmpLength;
ULONG i;
if (SlotNumber < HalpPciMaxSlots) {
from = (ULONG) HalpPciConfigBase + (SlotNumber << 11);
from += Offset;
to = Buffer;
tmpLength = Length;
while (tmpLength > 0) {
WRITE_PORT_ULONG ((PUCHAR)HalpIoControlBase + 0xCF8, from);
i = from % sizeof(ULONG);
*((PUCHAR) to) = READ_PORT_UCHAR ((PUCHAR)HalpIoControlBase + 0xCFC + i);
to++;
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 == 2) {
(*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
--*/
{
// Carolina supports some plug-in PCI busses, but this
// HAL doesn't need to build the map because all Carolina PCI
// interrupts are routed to the same IRQ. Hence the
// map reduces to nothing.
return;
}