268 lines
5.4 KiB
C
268 lines
5.4 KiB
C
|
/*
|
|||
|
* 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;
|
|||
|
}
|