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

268 lines
5.4 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) 1995 FirePower Systems, Inc.
* DO NOT DISTRIBUTE without permission
*
* $RCSfile: pxpcisup.c $
* $Revision: 1.18 $
* $Date: 1996/05/14 02:35:00 $
* $Locker: $
*/
/*++
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.
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"
#include "pxpcisup.h"
#include "stdio.h"
#include "fpdebug.h"
#include "phsystem.h"
extern PVOID HalpPciConfigBase;
extern UCHAR PciDevicePrimaryInts[];
extern ULONG HalpGetPciInterruptSlot( PBUS_HANDLER, PCI_SLOT_NUMBER );
#define LX_PCI_INTERRUPT_ROUTING_SLOT0 25
#define LX_PCI_INTERRUPT_ROUTING_SLOT1 22
#define LX_PCI_INTERRUPT_ROUTING_SLOT2 23
#define LX_PCI_INTERRUPT_ROUTING_SLOT3 26
#define LX_PCI_INTERRUPT_ROUTING_IDEA 21
#define LX_PCI_INTERRUPT_ROUTING_IDEB 20
#define PCI_INTERRUPT_ROUTING_SLOT0 0x16 // phys dev# 2, logical 1
#define PCI_INTERRUPT_ROUTING_SLOT1 0x17 // phys dev# 3, logical 2
#define PCI_INTERRUPT_ROUTING_SCSI 0x19 // phys dev# 1, logical 3
#define PCI_INTERRUPT_ROUTING_ETHERNET 0x1a // phys dev# 4, logical 4
#define IRQ_INVALID 0x0 // goes with IRQ_VALID defines
ULONG HalpPciConfigSlot[] = { 0x0800, // phys dev# 0: SIO chip
0x1000, // phys dev# 1: mobo scsi
0x2000, // phys dev# 2: peripheral plug in
0x4000, // phys dev# 3: peripheral plug in
0x8000 // phys dev# 4: mobo ethernet
,0x10000, // IDE_IntA
0x20000 // IDE_IntB
};
/*++
Routine Description: ULONG HalpTranslatePciSlotNumber ()
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.
--*/
ULONG
HalpTranslatePciSlotNumber (
ULONG BusNumber,
ULONG SlotNumber
)
{
//
// Sandalfoot only has 1 PCI bus so bus number is unused
//
UNREFERENCED_PARAMETER(BusNumber);
return ((ULONG) ((PUCHAR) HalpPciConfigBase + HalpPciConfigSlot[SlotNumber]));
}
/*++
Routine Description: ULONG HalpPhase0SetPciDataByOffset ()
This routine writes to PCI configuration space prior to bus handler installation.
Arguments:
None.
Return Value:
Returns length of data written.
--*/
ULONG
HalpPhase0SetPciDataByOffset (
ULONG BusNumber,
ULONG SlotNumber,
PUCHAR Buffer,
ULONG Offset,
ULONG Length
)
{
PUCHAR to;
PUCHAR from;
ULONG tmpLength;
if (SlotNumber < MAXIMUM_PCI_SLOTS) {
to = (PUCHAR)HalpPciConfigBase + HalpPciConfigSlot[SlotNumber];
to += Offset;
from = Buffer;
tmpLength = Length;
while (tmpLength > 0) {
*to++ = *from++;
tmpLength--;
}
return(Length);
}
else {
return (0);
}
}
/*++
Routine Description: ULONG HalpPhase0GetPciDataByOffset ()
This routine reads PCI config space prior to bus handlder installation.
Arguments:
None.
Return Value:
Amount of data read.
--*/
ULONG
HalpPhase0GetPciDataByOffset (
ULONG BusNumber,
ULONG SlotNumber,
PUCHAR Buffer,
ULONG Offset,
ULONG Length
)
{
PUCHAR to;
PUCHAR from;
ULONG tmpLength;
if (SlotNumber < MAXIMUM_PCI_SLOTS) {
from = (PUCHAR)HalpPciConfigBase + HalpPciConfigSlot[SlotNumber];
from += Offset;
to = Buffer;
tmpLength = Length;
while (tmpLength > 0) {
*to++ = *from++;
tmpLength--;
}
return(Length);
}
else {
return (0);
}
}
NTSTATUS
HalpGetISAFixedPCIIrq (
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN PCI_SLOT_NUMBER PciSlot,
OUT PUCHAR IrqTable
)
{
UCHAR buffer[PCI_COMMON_HDR_LENGTH];
PPCI_COMMON_CONFIG PciData;
ULONG slot;
ULONG interrupt;
PciData = (PPCI_COMMON_CONFIG) buffer;
HalGetBusData (
PCIConfiguration,
BusHandler->BusNumber,
PciSlot.u.AsULONG,
PciData,
PCI_COMMON_HDR_LENGTH
);
HDBG(DBG_INTERRUPTS,
HalpDebugPrint("HalpGetISAFixedPCIIrq: %x, %x, %x, %x %x \n",
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;
}
// For Primary PCI slots, the interrupt corresponds to the primary
// slot number
if ( BusHandler->BusNumber == 0 ) {
slot = PciSlot.u.bits.DeviceNumber;
}
// For Secondary PCI slots, the interrupt corresponds to the slot
// number of the primary parent
else {
slot = HalpGetPciInterruptSlot(BusHandler, PciSlot );
}
// Search the interrupt table for the interrupt corresponding to the slot
if (slot < MAXIMUM_PCI_SLOTS) {
interrupt = PciDevicePrimaryInts[slot];
if (interrupt != INVALID_INT) {
IrqTable[interrupt] = IRQ_VALID;
} else {
return STATUS_UNSUCCESSFUL;
}
} else {
return STATUS_UNSUCCESSFUL;
}
HDBG(DBG_INTERRUPTS,
HalpDebugPrint("HalpGetISAFixedPCIIrq: index = 0x%x \n",
PciSlot.u.bits.DeviceNumber););
return STATUS_SUCCESS;
}