summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halps/ppc
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/nthals/halps/ppc
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/nthals/halps/ppc')
-rw-r--r--private/ntos/nthals/halps/ppc/ctrlops.c1
-rw-r--r--private/ntos/nthals/halps/ppc/fwnvr.c1
-rw-r--r--private/ntos/nthals/halps/ppc/mk48time.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pcibios.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxbeep.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxbusdat.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxcache.s1
-rw-r--r--private/ntos/nthals/halps/ppc/pxcalstl.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxclksup.s1
-rw-r--r--private/ntos/nthals/halps/ppc/pxclock.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxdakota.h57
-rw-r--r--private/ntos/nthals/halps/ppc/pxdat.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxdisp.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxds1385.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxenviro.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxflshbf.s117
-rw-r--r--private/ntos/nthals/halps/ppc/pxflshio.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxhwsup.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxidle.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxinfo.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxinithl.c384
-rw-r--r--private/ntos/nthals/halps/ppc/pxintsup.s1
-rw-r--r--private/ntos/nthals/halps/ppc/pxirql.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxisabus.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxl2.s183
-rw-r--r--private/ntos/nthals/halps/ppc/pxmapio.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxmemctl.c1132
-rw-r--r--private/ntos/nthals/halps/ppc/pxmisc.s1
-rw-r--r--private/ntos/nthals/halps/ppc/pxpcibrd.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxpcibus.c2289
-rw-r--r--private/ntos/nthals/halps/ppc/pxpciint.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxpcisup.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxport.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxpower.s1
-rw-r--r--private/ntos/nthals/halps/ppc/pxproc.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxprof.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxreset.s433
-rw-r--r--private/ntos/nthals/halps/ppc/pxreturn.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxsiosup.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxstall.s1
-rw-r--r--private/ntos/nthals/halps/ppc/pxsysbus.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxsysint.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxsystyp.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxtime.c1
-rw-r--r--private/ntos/nthals/halps/ppc/pxusage.c1
-rw-r--r--private/ntos/nthals/halps/ppc/sysbios.c1
-rw-r--r--private/ntos/nthals/halps/ppc/x86bios.c1
47 files changed, 4635 insertions, 0 deletions
diff --git a/private/ntos/nthals/halps/ppc/ctrlops.c b/private/ntos/nthals/halps/ppc/ctrlops.c
new file mode 100644
index 000000000..d6419aa5f
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/ctrlops.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\ctrlops.c>
diff --git a/private/ntos/nthals/halps/ppc/fwnvr.c b/private/ntos/nthals/halps/ppc/fwnvr.c
new file mode 100644
index 000000000..34ac6b7a6
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/fwnvr.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\fwnvr.c>
diff --git a/private/ntos/nthals/halps/ppc/mk48time.c b/private/ntos/nthals/halps/ppc/mk48time.c
new file mode 100644
index 000000000..c8af7cb9e
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/mk48time.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\mk48time.c>
diff --git a/private/ntos/nthals/halps/ppc/pcibios.c b/private/ntos/nthals/halps/ppc/pcibios.c
new file mode 100644
index 000000000..63cbc3092
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pcibios.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pcibios.c>
diff --git a/private/ntos/nthals/halps/ppc/pxbeep.c b/private/ntos/nthals/halps/ppc/pxbeep.c
new file mode 100644
index 000000000..11eef682e
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxbeep.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxbeep.c>
diff --git a/private/ntos/nthals/halps/ppc/pxbusdat.c b/private/ntos/nthals/halps/ppc/pxbusdat.c
new file mode 100644
index 000000000..4eb375ea6
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxbusdat.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxbusdat.c>
diff --git a/private/ntos/nthals/halps/ppc/pxcache.s b/private/ntos/nthals/halps/ppc/pxcache.s
new file mode 100644
index 000000000..464a93823
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxcache.s
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxcache.s>
diff --git a/private/ntos/nthals/halps/ppc/pxcalstl.c b/private/ntos/nthals/halps/ppc/pxcalstl.c
new file mode 100644
index 000000000..7b5e7048c
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxcalstl.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxcalstl.c>
diff --git a/private/ntos/nthals/halps/ppc/pxclksup.s b/private/ntos/nthals/halps/ppc/pxclksup.s
new file mode 100644
index 000000000..3bb344c2b
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxclksup.s
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxclksup.s>
diff --git a/private/ntos/nthals/halps/ppc/pxclock.c b/private/ntos/nthals/halps/ppc/pxclock.c
new file mode 100644
index 000000000..140008534
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxclock.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxclock.c>
diff --git a/private/ntos/nthals/halps/ppc/pxdakota.h b/private/ntos/nthals/halps/ppc/pxdakota.h
new file mode 100644
index 000000000..597c7d413
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxdakota.h
@@ -0,0 +1,57 @@
+/*++ BUILD Version: 0001 // Increment this if a change has global effects
+
+
+Module Name:
+
+ pxdakota.h
+
+Abstract:
+
+ This header file defines the structures for the planar registers
+ on Dakota memory controllers.
+
+--*/
+
+
+//
+// define stuctures for memory control and planar register
+//
+
+
+
+typedef struct _DAKOTA_CONTROL {
+ UCHAR Reserved0[0x803]; // Offset 0x000
+ UCHAR SimmId; // Offset 0x803
+ UCHAR SimmPresent; // Offset 0x804
+ UCHAR Reserved1[3];
+ UCHAR HardfileLight; // Offset 0x808
+ UCHAR Reserved2[3];
+ UCHAR EquiptmentPresent; // Offset 0x80C
+ UCHAR Reserved3[3];
+ UCHAR PasswordProtect1; // Offset 0x810
+ UCHAR Reserved4;
+ UCHAR PasswordProtect2; // Offset 0x812
+ UCHAR Reserved5;
+ UCHAR L2Flush; // Offset 0x814
+ UCHAR Reserved6[3];
+ UCHAR Keylock; // Offset 0x818
+ UCHAR Reserved7[3];
+ UCHAR SystemControl; // Offset 0x81c
+ UCHAR Reserved8[3];
+ UCHAR MemoryController; // Offset 0x820
+ UCHAR MemoryControllerTiming; // Offset 0x821
+ UCHAR Reserved9[0x16];
+ UCHAR Eoi9; // Offset 0x838
+ UCHAR Reserved10[3];
+ UCHAR Eoi11; // Offset 0x83C
+ UCHAR Reserved11[3];
+ UCHAR MemoryParityErrorStatus; // Offset 0x840
+ UCHAR MemoryParityErrorClear; // Offset 0x841
+ UCHAR L2CacheErrorStatus; // Offset 0x842
+ UCHAR L2CacheErrorClear; // Offset 0x843
+ UCHAR TransferErrorStatus; // Offset 0x844
+ UCHAR TransferErrorClear; // Offset 0x845
+ UCHAR Reserved12[0xa];
+ UCHAR IoMap; // Offset 0x850
+ UCHAR Reserved13[3];
+} DAKOTA_CONTROL, *PDAKOTA_CONTROL;
diff --git a/private/ntos/nthals/halps/ppc/pxdat.c b/private/ntos/nthals/halps/ppc/pxdat.c
new file mode 100644
index 000000000..9036550ff
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxdat.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxdat.c>
diff --git a/private/ntos/nthals/halps/ppc/pxdisp.c b/private/ntos/nthals/halps/ppc/pxdisp.c
new file mode 100644
index 000000000..e476e5e83
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxdisp.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxdisp.c>
diff --git a/private/ntos/nthals/halps/ppc/pxds1385.c b/private/ntos/nthals/halps/ppc/pxds1385.c
new file mode 100644
index 000000000..6164c0faa
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxds1385.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxds1385.c>
diff --git a/private/ntos/nthals/halps/ppc/pxenviro.c b/private/ntos/nthals/halps/ppc/pxenviro.c
new file mode 100644
index 000000000..bb67da576
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxenviro.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxenviro.c>
diff --git a/private/ntos/nthals/halps/ppc/pxflshbf.s b/private/ntos/nthals/halps/ppc/pxflshbf.s
new file mode 100644
index 000000000..358b5de88
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxflshbf.s
@@ -0,0 +1,117 @@
+// TITLE("Miscellaneous Kernel Functions")
+//++
+//
+// Copyright (C) 1991-1995 Microsoft Corporation
+//
+// Copyright (C) 1994,1995 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:
+//
+// pxflshbf.s
+//
+// Abstract:
+//
+// This module implements the system dependent kernel function to flush
+// the write buffer or otherwise synchronize writes on a Power PC
+// system.
+//
+//
+//
+// Author:
+//
+// David N. Cutler (davec) 24-Apr-1991
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+// Jim Wooldridge (jimw@austin.vnet.ibm.com) Initial PowerPC port
+//
+// Used PowerPC eieio instruction to flush writes
+//
+//--
+
+#include "kxppc.h"
+
+
+// SBTTL("Flush Write Buffer")
+//
+//++
+//
+// NTSTATUS
+// KeFlushWriteBuffer (
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function flushes the write buffer on the current processor.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(KeFlushWriteBuffer)
+
+ eieio // synchronize I/O
+
+ LEAF_EXIT(KeFlushWriteBuffer)
+
+
+
+//
+//++
+//
+// NTSTATUS
+// HalpSynchronizeExecution()
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function flushes the write buffer on the current processor.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpSynchronizeExecution)
+
+ sync // synchronize
+
+ LEAF_EXIT(HalpSynchronizeExecution)
+
+
+//
+//++
+//
+// VOID
+// HalpSetSDR1(
+// ULONG HashedPageTableBase,
+// ULONG HashedPageTableSize
+// )
+//
+// HashedPageTableSize is unused because we ASSUME that the HPT is 64K
+//
+
+ LEAF_ENTRY(HalpSetSDR1)
+
+ mtsdr1 r.3
+
+ LEAF_EXIT(HalpSetSDR1)
diff --git a/private/ntos/nthals/halps/ppc/pxflshio.c b/private/ntos/nthals/halps/ppc/pxflshio.c
new file mode 100644
index 000000000..50fe4eb28
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxflshio.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxflshio.c>
diff --git a/private/ntos/nthals/halps/ppc/pxhwsup.c b/private/ntos/nthals/halps/ppc/pxhwsup.c
new file mode 100644
index 000000000..af734beb1
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxhwsup.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxhwsup.c>
diff --git a/private/ntos/nthals/halps/ppc/pxidle.c b/private/ntos/nthals/halps/ppc/pxidle.c
new file mode 100644
index 000000000..edd5c4520
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxidle.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxidle.c>
diff --git a/private/ntos/nthals/halps/ppc/pxinfo.c b/private/ntos/nthals/halps/ppc/pxinfo.c
new file mode 100644
index 000000000..5c76d0b6c
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxinfo.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxinfo.c>
diff --git a/private/ntos/nthals/halps/ppc/pxinithl.c b/private/ntos/nthals/halps/ppc/pxinithl.c
new file mode 100644
index 000000000..48149828a
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxinithl.c
@@ -0,0 +1,384 @@
+/*++
+
+Copyright (c) 1991-1993 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:
+
+ pxinithl.c
+
+Abstract:
+
+
+ This module implements the initialization of the system dependent
+ functions that define the Hardware Architecture Layer (HAL) for a
+ Power PC system.
+
+
+Author:
+
+ David N. Cutler (davec) 25-Apr-1991
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ Jim Wooldridge (jimw@austin.ibm.com) Initial Power PC port
+
+ Removed call to HalpMapFixedTbEntries, the PPC port
+ maps all memory via calls to MmMapIoSpace().
+ Removed call to HalpInitializeInterrupts - 8259 initialized in phase 1
+ Removed Cache error handler - 601 has no cache error interrupt
+ Removed call to HalpCreateDmaSturctures - it supports internal DMA
+
+--*/
+
+#include "halp.h"
+#include "pxmemctl.h"
+#include "pxsystyp.h"
+
+extern ADDRESS_USAGE HalpDefaultIoSpace;
+extern ULONG HalpPciMaxSlots;
+extern ULONG HalpPciConfigSize;
+
+ULONG
+HalpSizeL2Cache(
+ VOID
+ );
+
+VOID
+HalpSynchronizeExecution(
+ VOID
+ );
+
+VOID
+HalpCopyROMs(
+ VOID
+ );
+
+
+//
+// Put all code for HAL initialization in the INIT section. It will be
+// deallocated by memory management when phase 1 initialization is
+// completed.
+//
+
+#if defined(ALLOC_PRAGMA)
+
+#pragma alloc_text(INIT, HalInitSystem)
+#pragma alloc_text(INIT, HalInitializeProcessor)
+
+#endif
+
+PVOID HalpIoControlBase = (PVOID) 0;
+
+VOID
+HalpInitBusHandlers (
+ VOID
+ );
+
+VOID
+HalpRegisterInternalBusHandlers (
+ VOID
+ );
+
+VOID
+HalpEnableBridgeSettings(
+ VOID
+ );
+
+VOID
+HalpCheckHardwareRevisionLevels(
+ VOID
+ );
+
+VOID
+HalpDumpHardwareState(
+ VOID
+ );
+
+VOID
+HalpEnableL2Cache(
+ VOID
+ );
+
+
+//
+// Define global spin locks used to synchronize various HAL operations.
+//
+
+KSPIN_LOCK HalpBeepLock;
+KSPIN_LOCK HalpDisplayAdapterLock;
+KSPIN_LOCK HalpSystemInterruptLock;
+
+BOOLEAN
+HalInitSystem (
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes the Hardware Architecture Layer (HAL) for a
+ Power PC system.
+
+Arguments:
+
+ Phase - Supplies the initialization phase (zero or one).
+
+ LoaderBlock - Supplies a pointer to a loader parameter block.
+
+Return Value:
+
+ A value of TRUE is returned is the initialization was successfully
+ complete. Otherwise a value of FALSE is returend.
+
+--*/
+
+{
+
+ extern KSPIN_LOCK NVRAM_Spinlock;
+ PKPRCB Prcb;
+
+
+ //
+ // Initialize the HAL components based on the phase of initialization
+ // and the processor number.
+ //
+
+ Prcb = PCR->Prcb;
+ if ((Phase == 0) || (Prcb->Number != 0)) {
+
+ if (Prcb->Number == 0)
+ HalpSetSystemType( LoaderBlock );
+
+ //
+ // Phase 0 initialization.
+ //
+ // N.B. Phase 0 initialization is executed on all processors.
+ //
+ //
+ // Get access to I/O space, check if I/O space has already been
+ // mapped by debbuger initialization.
+ //
+
+ if (HalpIoControlBase == NULL) {
+
+ HalpIoControlBase = (PVOID)KePhase0MapIo(IO_CONTROL_PHYSICAL_BASE, 0x20000);
+
+ if ( !HalpIoControlBase ) {
+ return FALSE;
+ }
+ }
+
+ //
+ // Initialize the display adapter. Must be done early
+ // so KeBugCheck() will be able to display
+ //
+ if (!HalpInitializeDisplay(LoaderBlock))
+ return FALSE;
+
+ // Verify that the processor block major version number conform
+ // to the system that is being loaded.
+ //
+
+ if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) {
+ KeBugCheck(MISMATCHED_HAL);
+ }
+
+ //
+ // If processor 0 is being initialized, then initialize various
+ // variables, spin locks, and the display adapter.
+ //
+
+ if (Prcb->Number == 0) {
+
+ //
+ // Initialize Spinlock for NVRAM
+ //
+
+ KeInitializeSpinLock( &NVRAM_Spinlock );
+
+ //
+ // Set the interval clock increment value.
+ //
+
+ HalpCurrentTimeIncrement = MAXIMUM_INCREMENT;
+ HalpNewTimeIncrement = MAXIMUM_INCREMENT;
+ KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT);
+
+ //
+ // Initialize all spin locks.
+ //
+
+#if defined(_MP_PPC_)
+
+ KeInitializeSpinLock(&HalpBeepLock);
+ KeInitializeSpinLock(&HalpDisplayAdapterLock);
+ KeInitializeSpinLock(&HalpSystemInterruptLock);
+
+#endif
+
+ HalpRegisterAddressUsage (&HalpDefaultIoSpace);
+
+ //
+ // Calibrate execution stall
+ //
+ HalpCalibrateStall();
+
+ //
+ // Compute size of PCI Configuration Space mapping
+ //
+ HalpPciConfigSize = PAGE_SIZE * ((1 << (HalpPciMaxSlots-2)) + 1);
+
+ //
+ // Fill in handlers for APIs which this HAL supports
+ //
+
+ HalQuerySystemInformation = HaliQuerySystemInformation;
+ HalSetSystemInformation = HaliSetSystemInformation;
+ HalRegisterBusHandler = HaliRegisterBusHandler;
+ HalHandlerForBus = HaliHandlerForBus;
+ HalHandlerForConfigSpace = HaliHandlerForConfigSpace;
+
+ }
+
+ //
+ // InitializeInterrupts
+ //
+
+ if (!HalpInitializeInterrupts())
+
+ return FALSE;
+
+ //
+ // return success
+ //
+
+ return TRUE;
+
+
+ } else {
+
+ if (Phase != 1)
+ return(FALSE);
+
+
+ //
+ // Phase 1 initialization.
+ //
+ // N.B. Phase 1 initialization is only executed on processor 0.
+ //
+
+
+ HalpRegisterInternalBusHandlers ();
+
+
+ if (!HalpAllocateMapBuffer()) {
+ return FALSE;
+ }
+
+
+ //
+ // Map I/O space and create ISA data structures.
+ //
+
+ if (!HalpMapIoSpace()) {
+ return FALSE;
+ }
+
+ if (!HalpCreateSioStructures()) {
+ return FALSE;
+ }
+
+ HalpCheckHardwareRevisionLevels();
+ HalpEnableL2Cache();
+ HalpEnableBridgeSettings();
+ HalpDumpHardwareState();
+ HalpCopyROMs();
+
+ return TRUE;
+
+ }
+}
+
+VOID
+HalInitializeProcessor (
+ IN ULONG Number
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called early in the initialization of the kernel
+ to perform platform dependent initialization for each processor
+ before the HAL Is fully functional.
+
+ N.B. When this routine is called, the PCR is present but is not
+ fully initialized. In order to access the PCR from this
+ routine, use the PCRsprg1 macro, not the PCR macro.
+
+Arguments:
+
+ Number - Supplies the number of the processor to initialize.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ ULONG IcacheSize, DcacheSize;
+ ULONG CacheBlockAlignment;
+
+ switch (HalpGetProcessorVersion() >> 16) {
+
+ case 1: // 601
+ IcacheSize = 32*1024;
+ DcacheSize = 32*1024;
+ CacheBlockAlignment = 32 - 1;
+ break;
+
+ case 3: // 603
+ IcacheSize = 8*1024;
+ DcacheSize = 8*1024;
+ CacheBlockAlignment = 32 - 1;
+ break;
+
+ case 6: // 603e
+ case 7: // 603ev
+ case 4: // 604
+ IcacheSize = 16*1024;
+ DcacheSize = 16*1024;
+ CacheBlockAlignment = 32 - 1;
+ break;
+
+ case 9: // 604+
+ IcacheSize = 32*1024;
+ DcacheSize = 32*1024;
+ CacheBlockAlignment = 32 - 1;
+ break;
+
+ default:
+ KeBugCheck(HAL_INITIALIZATION_FAILED);
+ return;
+ }
+
+
+ PCRsprg1->FirstLevelIcacheSize = IcacheSize;
+ PCRsprg1->FirstLevelDcacheSize = DcacheSize;
+ PCRsprg1->DcacheAlignment = CacheBlockAlignment;
+ PCRsprg1->IcacheAlignment = CacheBlockAlignment;
+
+ return;
+}
+
diff --git a/private/ntos/nthals/halps/ppc/pxintsup.s b/private/ntos/nthals/halps/ppc/pxintsup.s
new file mode 100644
index 000000000..98c676fb5
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxintsup.s
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxintsup.s>
diff --git a/private/ntos/nthals/halps/ppc/pxirql.c b/private/ntos/nthals/halps/ppc/pxirql.c
new file mode 100644
index 000000000..3889d1b8c
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxirql.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxirql.c>
diff --git a/private/ntos/nthals/halps/ppc/pxisabus.c b/private/ntos/nthals/halps/ppc/pxisabus.c
new file mode 100644
index 000000000..524dfa8ef
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxisabus.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxisabus.c>
diff --git a/private/ntos/nthals/halps/ppc/pxl2.s b/private/ntos/nthals/halps/ppc/pxl2.s
new file mode 100644
index 000000000..a45f5dd6f
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxl2.s
@@ -0,0 +1,183 @@
+//
+//
+// Copyright (c) 1993 IBM 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:
+//
+// PXL2.S
+//
+// Abstract:
+//
+// This module implements the routines to size the L2 cache
+// on PowerStack based system.
+//
+// Author:
+//
+// Karl Rusnock (karl_rusnock@phx.mcd.mot.com)
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+// 08-Dec-95 kjr Created this file for MCG PowerStack 2 Systems.
+//
+
+#include "kxppc.h"
+#include "halppc.h"
+
+ .extern HalpIoControlBase
+ .set HID0, 1008
+//
+// L2 cache sizes:
+//
+ .set L2_SIZE, 0x3 // Bits 1..0 (LE bit order)
+ .set L2_1M, 0x2
+ .set L2_512K, 0x0
+ .set L2_256K, 0x1
+ .set L2_LINE_SIZE, 32
+
+ .set CacheSize, r.3 // Return value
+ .set L2CONFIG, r.9
+ .set ISA, r.10 // Pointer to ISA I/O space
+
+//***********************************************************************
+//
+// Synopsis:
+// ULONG HalpSizeL2(VOID)
+//
+// Purpose:
+// Sizes the L2 cache.
+//
+// Returns:
+// Size of L2 cache or zero if not installed.
+// Valid sizes are 256, 512, and 1024.
+//
+// Global Variables Referenced:
+// HalpIoControlBase
+//
+// NOTE: Interrupts are assumed to be disabled upon entry.
+//***********************************************************************
+
+
+ LEAF_ENTRY(HalpSizeL2)
+
+//
+// Get ptr to Bridge I/O (ISA bus)
+//
+ lwz ISA,[toc]HalpIoControlBase(r.toc) // Get base of ISA I/O
+ lwz ISA,0(ISA)
+
+ lbz r.0, 0x823(ISA) // Cache Configuration Register.
+
+ andi. r.0, r.0, L2_SIZE // Isolate L2 size field
+ cmpi 0,0, r.0, L2_SIZE // L2 Cache Not Present?
+ li CacheSize, 0
+ beq L2_Exit
+
+ li CacheSize, 256
+ cmpi 0,0,r.0, L2_256K
+ beq L2_Exit
+
+ li CacheSize, 512
+ cmpi 0,0,r.0, L2_512K
+ beq L2_Exit
+
+ li CacheSize, 1024
+
+L2_Exit:
+
+//
+// r.3 = cache size in KB
+//
+ LEAF_EXIT(HalpSizeL2)
+
+
+//***********************************************************************
+//
+// Synopsis:
+// VOID HalpFlushAndDisableL2(VOID)
+//
+// Purpose:
+// Assumes that the L2 is enabled and in WRITE-THROUGH mode.
+// The L2 is invalidated and disabled.
+//
+// Returns:
+// nothing
+//
+// Global Variables Referenced:
+// HalpIoControlBase
+//
+// NOTE: Interrupts are assumed to be disabled upon entry.
+//***********************************************************************
+
+
+ LEAF_ENTRY(HalpFlushAndDisableL2)
+
+ mfspr r.9, HID0 // Lock the Icache
+ ori r.0, r.9, 0x2000
+ mtspr HID0, r.0
+ isync
+
+ li r.3, 0xC0 // Bits controlling L2
+ lwz ISA, [toc]HalpIoControlBase(r.toc) // Get base of ISA I/O
+ lwz ISA, 0(ISA)
+
+ lbz r.5, 0x81C(ISA) // Read System Control Register.
+ andc r.5, r.5, r.3 // Set bits to disable L2.
+ stb r.5, 0x814(ISA) // Invalidate L2 first.
+ stb r.5, 0x81C(ISA) // Disable L2 second.
+ stb r.5, 0x814(ISA) // Invalidate L2 again, to be safe.
+ lbz r.5, 0x81C(ISA) // Synchronize with I/O.
+ sync
+
+ mtspr HID0, r.9 // Unlock the Icache
+
+ LEAF_EXIT(HalpFlushAndDisableL2)
+
+
+//***********************************************************************
+//
+// Synopsis:
+// VOID HalpFlushAndEnableL2(VOID)
+//
+// Purpose:
+// Assumes that the L2 is Disabled.
+// The L2 is invalidated and enabled.
+//
+// Returns:
+// nothing
+//
+// Global Variables Referenced:
+// HalpIoControlBase
+//
+// NOTE: Interrupts are assumed to be disabled upon entry.
+//***********************************************************************
+
+
+ LEAF_ENTRY(HalpFlushAndEnableL2)
+
+ mfspr r.9, HID0 // Lock the Icache
+ ori r.0, r.9, 0x2000
+ mtspr HID0, r.0
+ isync
+
+ li r.3, 0xC0 // Bits controlling L2
+ lwz ISA, [toc]HalpIoControlBase(r.toc) // Get base of ISA I/O
+ lwz ISA, 0(ISA)
+
+ lbz r.5, 0x81C(ISA) // Read System Control Register.
+ or r.5, r.5, r.3 // Set bits to disable L2.
+ stb r.5, 0x814(ISA) // Invalidate L2 first.
+ stb r.5, 0x81C(ISA) // Enable L2 second.
+ lbz r.5, 0x81C(ISA) // Synchronize with I/O.
+ sync
+
+ mtspr HID0, r.9 // Unlock the Icache
+
+ LEAF_EXIT(HalpFlushAndEnableL2)
+
diff --git a/private/ntos/nthals/halps/ppc/pxmapio.c b/private/ntos/nthals/halps/ppc/pxmapio.c
new file mode 100644
index 000000000..110871d90
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxmapio.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxmapio.c>
diff --git a/private/ntos/nthals/halps/ppc/pxmemctl.c b/private/ntos/nthals/halps/ppc/pxmemctl.c
new file mode 100644
index 000000000..73cdad933
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxmemctl.c
@@ -0,0 +1,1132 @@
+
+/*++
+
+Copyright (C) 1990-1995 Microsoft Corporation
+
+Copyright (C) 1994,1995 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.
+
+--*/
+
+
+
+#include "halp.h"
+#include "pxmemctl.h"
+#include "pxdakota.h"
+#include "arccodes.h"
+
+
+VOID HalDisplayString(PUCHAR String);
+ULONG HalpGetHID0(VOID);
+VOID HalpSetHID0(ULONG Value);
+BOOLEAN HalpStrCmp( char *, char *);
+VOID HalpEnableL2Cache(VOID);
+ULONG HalpSizeL2Cache(VOID);
+extern ULONG HalpSizeL2(VOID);
+BOOLEAN HalpInitPlanar(VOID);
+BOOLEAN HalpMapPlanarSpace(VOID);
+VOID HalpFlushAndEnableL2(VOID);
+VOID HalpFlushAndDisableL2(VOID);
+VOID HalpEnableBridgeSettings(VOID);
+VOID HalpEnable_HID0_Settings(VOID);
+VOID HalpCheckHardwareRevisionLevels(VOID);
+VOID HalpDumpHardwareState(VOID);
+
+#define PCI_CONFIG_PHYSICAL_BASE 0x80800000 // physical base of PCI config space
+#define PCI_CONFIG_SIZE 0x00800000
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpStrCmp)
+#pragma alloc_text(INIT,HalpInitPlanar)
+#pragma alloc_text(INIT,HalpMapPlanarSpace)
+#pragma alloc_text(INIT,HalpEnableL2Cache)
+#pragma alloc_text(INIT,HalpSizeL2Cache)
+#pragma alloc_text(INIT,HalpEnableBridgeSettings)
+#pragma alloc_text(INIT,HalpEnable_HID0_Settings)
+#pragma alloc_text(INIT,HalpCheckHardwareRevisionLevels)
+#endif
+
+#define NEGATECHAR '~'
+
+#define BridgeIndexRegister ((PULONG) (((PUCHAR) HalpIoControlBase) + 0xcf8))
+#define BridgeDataRegister (((ULONG) HalpIoControlBase) + 0xcfc)
+
+#define HalpReadBridgeUlong(Port) \
+ (*BridgeIndexRegister = (Port), __builtin_eieio(), *((PULONG) BridgeDataRegister))
+
+#define HalpWriteBridgeUlong(Port, Value) \
+ (*BridgeIndexRegister = (Port), *((PULONG) BridgeDataRegister) = (Value), __builtin_sync())
+
+#define HalpReadBridgeUshort(Port) \
+ (*BridgeIndexRegister = (Port), __builtin_eieio(), *((PUSHORT)(BridgeDataRegister+(Port&0x2))))
+
+#define HalpWriteBridgeUshort(Port, Value) \
+ (*BridgeIndexRegister = (Port), *((PUSHORT)(BridgeDataRegister+(Port&0x2))) = (Value), __builtin_sync())
+
+#define HalpReadBridgeUchar(Port) \
+ (*BridgeIndexRegister = (Port), __builtin_eieio(), *((PUCHAR)(BridgeDataRegister+(Port&0x3))))
+
+#define HalpWriteBridgeUchar(Port, Value) \
+ (*BridgeIndexRegister = (Port), *((PUCHAR)(BridgeDataRegister+(Port&0x3))) = (Value), __builtin_sync())
+
+
+#define HalpDisplayHex32(Num, Buf) HalpDisplayHex( 32, Num, Buf)
+#define HalpDisplayHex16(Num, Buf) HalpDisplayHex( 16, Num, Buf)
+#define HalpDisplayHex8(Num, Buf) HalpDisplayHex( 8, Num, Buf)
+
+VOID HalpDisplayHex(
+ ULONG NoBits,
+ ULONG Number,
+ IN PUCHAR Buffer
+)
+{ int Bits;
+
+ for (Bits=NoBits-4; Bits >= 0; Bits -=4) {
+ *Buffer++ = (UCHAR) ((((Number >> Bits) & 0xF) > 9) ?
+ ((Number >> Bits) & 0xF) - 10 + 'A' :
+ ((Number >> Bits) & 0xF) + '0');
+ }
+ *Buffer++ = '.';
+ *Buffer++ = '\n';
+ *Buffer++ = '\0';
+
+}
+
+
+UCHAR HalpUpperCase(UCHAR c)
+{
+ if (c >= 'a' && c <= 'z')
+ c -= 'a'-'A';
+ return c;
+}
+
+
+//
+// Routine Description:
+//
+// This routine is a helper routine for parameter parsing.
+// It compares UpperCase of String1 to UpperCase of String2.
+//
+// Return Value
+//
+// TRUE if strings match; otherwise FALSE
+//
+
+BOOLEAN HalpStrCmp( char *String0, char *String1 )
+{
+char *tmp0, *tmp1;
+
+ tmp0 = String0;
+ tmp1 = String1;
+ while( (*tmp0 = toupper( *tmp0 )) && (*tmp1 = toupper( *tmp1 )) )
+ {
+ tmp0++; tmp1++;
+ }
+ return( strcmp(String0, String1) == 0 );
+}
+
+
+// Oem Output Display function filter noise if OEM or quite
+
+VOID OemDisplayString (
+ PUCHAR String
+ )
+
+{
+#define BUF_LEN 120
+UCHAR CharBuffer[BUF_LEN];
+
+ if(HalGetEnvironmentVariable("HALREPORT",sizeof(CharBuffer),&CharBuffer[0]) == ESUCCESS) {
+ if(HalpStrCmp("YES", CharBuffer)) {
+ HalDisplayString(String);
+ }
+ } else {
+ if(HalGetEnvironmentVariable("MOT-OEM-ID",sizeof(CharBuffer),&CharBuffer[0]) != ESUCCESS) {
+ HalDisplayString(String);
+ }
+ }
+}
+
+BOOLEAN
+HalpInitPlanar (
+ VOID
+ )
+
+{
+ USHORT CpuRevision, CpuType;
+ UCHAR BridgeRevision, c;
+ UCHAR CharBuffer[20], i;
+
+ OemDisplayString("\nHAL: Motorola PowerStack 2 Systems.");
+ OemDisplayString("\nHAL: Version 2.37 5/24/96.");
+
+ CpuType = (USHORT)(HalpGetProcessorVersion() >> 16);
+ CpuRevision = (USHORT)(HalpGetProcessorVersion() & 0xFFFF);
+
+ OemDisplayString("\nHAL: Processor is a 6");
+ i = 0;
+ switch (CpuType) {
+ case 1:
+ case 3:
+ case 4:
+ CharBuffer[i++] = '0';
+ CharBuffer[i++] = (UCHAR)(CpuType) + '0';
+ break;
+
+ case 6:
+ CharBuffer[i++] = '0';
+ CharBuffer[i++] = '3';
+ CharBuffer[i++] = 'e';
+ break;
+
+ case 7:
+ CharBuffer[i++] = '0';
+ CharBuffer[i++] = '3';
+ CharBuffer[i++] = 'e';
+ CharBuffer[i++] = 'v';
+ break;
+
+ case 9:
+ CharBuffer[i++] = '0';
+ CharBuffer[i++] = '4';
+ CharBuffer[i++] = 'e';
+ CharBuffer[i++] = 'v';
+ break;
+
+ case 20:
+ CharBuffer[i++] = '2';
+ CharBuffer[i++] = '0';
+ break;
+
+ default:
+ CharBuffer[i++] = '?';
+ CharBuffer[i++] = '?';
+ break;
+ }
+ CharBuffer[i] = '\0';
+ OemDisplayString(CharBuffer);
+
+ OemDisplayString(" revision ");
+ i = 0;
+ c = (UCHAR)((CpuRevision >> 8) & 0xf);
+ CharBuffer[i++] = c + '0';
+ CharBuffer[i++] = '.';
+ if (c = (UCHAR)((CpuRevision >> 4) & 0xf))
+ CharBuffer[i++] = c + '0';
+ c = (UCHAR)(CpuRevision & 0xf);
+ CharBuffer[i++] = c + '0';
+ CharBuffer[i++] = '.';
+ CharBuffer[i] = '\0';
+ OemDisplayString(CharBuffer);
+
+ OemDisplayString("\nHAL: Bridge 27-82660 revision ");
+ BridgeRevision = HalpReadBridgeUchar(0x80000008);
+ i = 0;
+ CharBuffer[i++] = (UCHAR) (BridgeRevision >> 4) + '0';
+ CharBuffer[i++] = '.';
+ CharBuffer[i++] = (UCHAR) (BridgeRevision & 0x0F) + '0';
+ CharBuffer[i++] = '.';
+ CharBuffer[i++] = '\n';
+ CharBuffer[i] = '\0';
+ OemDisplayString(CharBuffer);
+
+ return TRUE;
+}
+
+char *
+MyStrtok (
+ char * string,
+ const char * control
+ )
+{
+ unsigned char *str;
+ const unsigned char *ctrl = control;
+
+ unsigned char map[32];
+ int count;
+
+ static char *nextoken;
+
+ /* Clear control map */
+ for (count = 0; count < 32; count++)
+ map[count] = 0;
+
+ /* Set bits in delimiter table */
+ do {
+ map[*ctrl >> 3] |= (1 << (*ctrl & 7));
+ } while (*ctrl++);
+
+ /* Initialize str. If string is NULL, set str to the saved
+ * pointer (i.e., continue breaking tokens out of the string
+ * from the last strtok call) */
+ if (string)
+ str = string;
+ else
+ str = nextoken;
+
+ /* Find beginning of token (skip over leading delimiters). Note that
+ * there is no token iff this loop sets str to point to the terminal
+ * null (*str == '\0') */
+ while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
+ str++;
+
+ string = str;
+
+ /* Find the end of the token. If it is not the end of the string,
+ * put a null there. */
+ for ( ; *str ; str++ )
+ if ( map[*str >> 3] & (1 << (*str & 7)) ) {
+ *str++ = '\0';
+ break;
+ }
+
+ /* Update nextoken (or the corresponding field in the per-thread data
+ * structure */
+ nextoken = str;
+
+ /* Determine if a token has been found. */
+ if ( string == str )
+ return NULL;
+ else
+ return string;
+}
+
+
+VOID
+HalpEnableBridgeSettings(
+ VOID
+ )
+{
+ UCHAR CharBuffer[BUF_LEN], *Value;
+ BOOLEAN Negate;
+ ULONG StatusRegister;
+ volatile ULONG ErrorAddress;
+
+#define SetBridgeUchar( Clear, Offset, Val ) \
+ SetBridgeReg(Clear, Offset, Val, HalpReadBridgeUchar, HalpWriteBridgeUchar);
+
+#define SetBridgeUshort( Clear, Offset, Val ) \
+ SetBridgeReg(Clear, Offset, Val, HalpReadBridgeUshort, HalpWriteBridgeUshort);
+
+#define SetBridgeUlong( Clear, Offset, Val ) \
+ SetBridgeReg(Clear, Offset, Val, HalpReadBridgeUlong, HalpWriteBridgeUlong);
+
+#define SetBridgeReg( Clear, Offset, Val, GetReg, SetReg) \
+{ \
+ if (Clear) { \
+ SetReg(Offset, GetReg(Offset) & ~Val); \
+ } else { \
+ SetReg(Offset, GetReg(Offset) | Val); \
+ } \
+}
+
+ //
+ // MOTKJR - Errata 19 from the Errata Summary Revision 1.3 says:
+ // The error handling logic incorrectly detects EIEIO as a CPU transfer type error.
+ // Always mask CPU transfer type errors (Error Enable 1 bit 0).
+ //
+ StatusRegister = HalpReadBridgeUchar(0x800000C0); // Clear CPU Transfer type error enable bit.
+ HalpWriteBridgeUchar(0x800000C0, ~0x01 & (UCHAR)(StatusRegister));
+
+ //
+ // The environment variable "BRIDGESETTINGS" is defined as:
+ // Matching a string serves to enable that feature while a tilde (~)
+ // immediately before the parameter string indicates that it is to be disabled.
+ //
+
+ if ((HalGetEnvironmentVariable("BRIDGESETTINGS", BUF_LEN, &CharBuffer[0]) == ESUCCESS) ||
+ (HalGetEnvironmentVariable("EAGLESETTINGS", BUF_LEN, &CharBuffer[0]) == ESUCCESS)) {
+
+ for( Value = MyStrtok(CharBuffer, " :;,"); Value; Value = MyStrtok(NULL, " :;,") ) {
+
+ Negate = FALSE;
+
+ if (*Value == NEGATECHAR) {
+ Value++;
+ Negate = TRUE;
+ }
+
+ if (HalpStrCmp("PCI_PARITY", Value)) {
+ SetBridgeUshort( Negate, 0x80000004, 0x0040 );
+ }
+ else if (HalpStrCmp("SERR", Value)) {
+ SetBridgeUshort( Negate, 0x80000004, 0x0140 );
+ }
+ else if (HalpStrCmp("MCP_EN", Value) || HalpStrCmp("MCP", Value)) {
+ SetBridgeUchar( Negate, 0x800000BA, 0x01 );
+ }
+ else if (HalpStrCmp("TEA_EN", Value) || HalpStrCmp("TEA", Value)) {
+ SetBridgeUchar( Negate, 0x800000BA, 0x02 );
+ }
+ else if (HalpStrCmp("PCI_ISA_IO_MAPPING", Value)) {
+ SetBridgeUchar( Negate, 0x800000BA, 0x04 );
+ }
+ else if (HalpStrCmp("POWER_MANAGEMENT", Value)) {
+ SetBridgeUchar( Negate, 0x800000BB, 0x02 );
+ }
+ else if (HalpStrCmp("CPU_TRANSFER_TYPE", Value)) {
+ SetBridgeUchar( Negate, 0x800000C0, 0x01 );
+ }
+ else if (HalpStrCmp("PARITY", Value) || HalpStrCmp("MEMORY", Value)) {
+ SetBridgeUchar( Negate, 0x800000C0, 0x04 );
+ }
+ else if (HalpStrCmp("SINGLE_BIT_ECC", Value)) {
+ SetBridgeUchar( Negate, 0x800000C0, 0x04 );
+ }
+ else if (HalpStrCmp("MULTI_BIT_ECC", Value)) {
+ SetBridgeUchar( Negate, 0x800000C0, 0x08 );
+ }
+ else if (HalpStrCmp("SELECT", Value)) {
+ SetBridgeUchar( Negate, 0x800000C0, 0x20 );
+ }
+ else if (HalpStrCmp("SERR_WHEN_PERR", Value)) {
+ SetBridgeUchar( Negate, 0x800000C0, 0x40 );
+ }
+ else if (HalpStrCmp("TARGET_ABORT", Value)) {
+ SetBridgeUchar( Negate, 0x800000C0, 0x80 );
+ }
+ else if (HalpStrCmp("CPU_DATA_BUS_PARITY", Value)) {
+ SetBridgeUchar( Negate, 0x800000C4, 0x04 );
+ }
+ else if (HalpStrCmp("L2_PARITY", Value) || HalpStrCmp("L2", Value)) {
+ SetBridgeUchar( Negate, 0x800000C4, 0x08 );
+ }
+ else if (HalpStrCmp("MASTER_ABORT", Value)) {
+ SetBridgeUchar( Negate, 0x800000C4, 0x10 );
+ }
+ else if (HalpStrCmp("ECC", Value) || HalpStrCmp("MEMORY_ERROR_CHECKING", Value)) {
+ SetBridgeUchar( Negate, 0x800000D4, 0x01 );
+ SetBridgeUchar( Negate, 0x800000C0, 0x08 );
+ }
+ else if (HalpStrCmp("MEMORY_DRAM", Value)) {
+ SetBridgeUchar( Negate, 0x800000D4, 0x04 );
+ }
+ else if (HalpStrCmp("L2_SRAM", Value)) {
+ SetBridgeUchar( Negate, 0x800000D4, 0x08 );
+ }
+ else if (HalpStrCmp("MCP_MODE", Value)) {
+ SetBridgeUchar( Negate, 0x800000D4, 0x10 );
+ }
+ else if (HalpStrCmp("EXTERNAL_REGISTER", Value)) {
+ SetBridgeUchar( Negate, 0x800000D4, 0x20 );
+ }
+ else if (HalpStrCmp("BROADCAST_SNOOP", Value)) {
+ SetBridgeUchar( Negate, 0x800000D4, 0x80 );
+ } else {
+ HalDisplayString("HAL: Error in BRIDGESETTINGS environment variable: ");
+ HalDisplayString(CharBuffer);
+ HalDisplayString("\n");
+ }
+ } // End for
+ } // End If
+
+ //
+ // Clear the error address register and L2 Cache Error register.
+ //
+
+ ErrorAddress = READ_PORT_ULONG(HalpErrorAddressRegister);
+ StatusRegister = READ_PORT_UCHAR(&((PDAKOTA_CONTROL)
+ HalpIoControlBase)->L2CacheErrorClear);
+
+ HalpWriteBridgeUchar(0x800000C1, 0xFF); // Clear Error Detection Register 1.
+ HalpWriteBridgeUchar(0x800000C5, 0xFF); // Clear Error Detection Register 2.
+ StatusRegister = HalpReadBridgeUshort(0x80000006); // Get any Un-documented Status bits.
+ HalpWriteBridgeUshort(0x80000006, 0xF900 | (USHORT)(StatusRegister)); // Clear Device Status Register.
+
+ //
+ // Initialize the PowerPC HID0 register here,
+ // before we clear the detection bits in the Kauai/Lanai.
+ // Otherwise we can miss the MCP pin signal transition.
+ //
+ HalpEnable_HID0_Settings(); // Setup HID0 register.
+}
+
+
+ULONG
+HalpSizeL2Cache(
+ VOID
+ )
+{
+ return (HalpSizeL2());
+}
+
+
+VOID
+HalpEnableL2Cache(
+ VOID
+ )
+{
+ BOOLEAN Negate;
+ int i;
+ UCHAR CharBuffer[BUF_LEN], *Value;
+ UCHAR L2_Parameter[BUF_LEN];
+ UCHAR ControlByte;
+
+ //
+ // Parse the environment variable "L2"
+ //
+
+ if (HalGetEnvironmentVariable("L2", BUF_LEN, &CharBuffer[0]) == ESUCCESS) {
+
+ // Copy L2 environment variable
+ i = 0;
+ while (L2_Parameter[i] = CharBuffer[i]) {
+ i++;
+ }
+
+ for( Value = MyStrtok(CharBuffer, " :;,"); Value; Value = MyStrtok(NULL, " :;,") )
+ {
+ if (*Value == NEGATECHAR) {
+ Value++;
+ Negate = TRUE;
+ } else
+ Negate = FALSE;
+
+ // Check for L2 = "OFF"
+ if (HalpStrCmp( "OFF", Value ))
+ {
+ OemDisplayString("HAL: L2 cache is disabled via environment variable L2\n");
+ HalpFlushAndDisableL2();
+ PCR->SecondLevelDcacheSize = PCR->SecondLevelIcacheSize = 0;
+ return;
+ }
+ // Check for WriteThrough
+ else if ( HalpStrCmp( "WT", Value ) || HalpStrCmp( "ON", Value ))
+ {
+ if (Negate) {
+ Value--;
+ goto ParseError;
+ }
+
+ //
+ // Enable L2 cache on Kauai / Lanai.
+ //
+ HalpFlushAndEnableL2();
+
+ } else {
+
+ParseError: HalDisplayString("HAL: Error in L2 environment variable: ");
+ HalDisplayString(L2_Parameter);
+ HalDisplayString("\n illegal parameter begins here ");
+ for (i = 0; i < Value - CharBuffer; i++)
+ HalDisplayString("\304");
+ HalDisplayString("^\n");
+ break;
+ }
+
+ } // End for
+ } // End If
+
+ return;
+}
+
+VOID
+HalpEnable_HID0_Settings(
+ VOID
+ )
+{
+ USHORT CpuRevision, CpuType;
+ UCHAR CharBuffer[BUF_LEN], *Value;
+ ULONG HidEnable, HidDisable, CurrentHID0;
+ BOOLEAN Negate;
+
+#define HID_MCP (0x80000000)
+#define HID_CACHE (0x40000000)
+#define HID_ADDRESS (0x20000000)
+#define HID_DATA (0x10000000)
+#define HID_PAR (0x01000000)
+#define HID_DPM (0x00100000)
+#define HID_FBIOB (0x00000010)
+#define HID_BHT (0x00000004)
+#define HID_NOOPTI (0x00000001)
+
+#define SetCPUMask( Disable, Val ) \
+{ \
+ if (Disable) \
+ HidDisable |= Val; \
+ else \
+ HidEnable |= Val; \
+}
+
+ CpuType = (USHORT)(HalpGetProcessorVersion() >> 16);
+ CpuRevision = (USHORT)(HalpGetProcessorVersion() & 0xFFFF);
+
+ HidEnable = 0;
+ HidDisable = 0;
+ CurrentHID0 = HalpGetHID0();
+
+ switch (CpuType) {
+ case 7: // 603ev
+ //
+ // Work-around for early parts.
+ //
+ CurrentHID0 |= HID_NOOPTI;
+
+ case 3: // 603
+ case 6: // 603e
+ //
+ // Enable Dynamic Power Management
+ //
+ CurrentHID0 |= HID_DPM;
+ break;
+
+ case 4: // 604
+ case 9: // 604e
+ //
+ // Enable L1 Cache Parity Checking
+ //
+ CurrentHID0 |= HID_CACHE;
+ break;
+ }
+
+ //
+ // Set the default CPU Parity Checking.
+ // This default can be platform dependent.
+ //
+
+ CurrentHID0 |= HID_MCP;
+
+ //
+ // The environment variable "HID0SETTINGS" is defined either as:
+ // "CACHE", "ADDRESS", "DATA", "MCP", "DPM" with either blank or semi-colon
+ // characters used as separators. Matching a string serves to enable
+ // that feature while a tilde (~) immediately before the parameter
+ // string indicates that it is to be disabled.
+ //
+
+ if (HalGetEnvironmentVariable("HID0SETTINGS", BUF_LEN, &CharBuffer[0]) == ESUCCESS) {
+ for( Value = MyStrtok(CharBuffer, " :;,"); Value; Value = MyStrtok(NULL, " :;,") ) {
+
+ Negate = FALSE;
+
+ if (*Value == NEGATECHAR) {
+ Value++;
+ Negate = TRUE;
+ }
+
+ if (HalpStrCmp("MCP", Value)) {
+ SetCPUMask(Negate, HID_MCP);
+ } else if (HalpStrCmp("ADDRESS", Value)) {
+ SetCPUMask(Negate, HID_ADDRESS);
+ } else if (HalpStrCmp("DATA", Value)) {
+ SetCPUMask(Negate, HID_DATA);
+ } else if (HalpStrCmp("PAR", Value)) {
+ SetCPUMask(Negate, HID_PAR);
+ } else if (HalpStrCmp("BHT", Value)) {
+ SetCPUMask(Negate, HID_BHT);
+ } else if (HalpStrCmp("CACHE", Value)) {
+ SetCPUMask(Negate, HID_CACHE);
+ } else if (HalpStrCmp("DPM", Value)) {
+ SetCPUMask(Negate, HID_DPM);
+ } else if (HalpStrCmp("FBIOB", Value)) {
+ SetCPUMask(Negate, HID_FBIOB);
+ } else if (HalpStrCmp("NOOPTI", Value)) {
+ SetCPUMask(Negate, HID_NOOPTI);
+ } else {
+
+ HalDisplayString("HAL: Error in HID0SETTINGS environment variable: ");
+ HalDisplayString(CharBuffer);
+ HalDisplayString("\n");
+ }
+ } // End While
+ } // End If
+
+ //
+ // Check for inconsistencies in HID0SETTINGS
+ //
+ if (HidEnable & HidDisable) {
+ HalDisplayString("HAL: Inconsistent settings in HID0SETTINGS environment variable.\n");
+ HalDisplayString(" Disable setting will override enable setting.\n");
+ //
+ // Enforce DISABLE override ENABLE
+ //
+ HidEnable &= ~HidDisable;
+ }
+
+ //
+ // Disable and Enable the bits in the HID0 register.
+ //
+ CurrentHID0 &= ~HidDisable; // Disable bits first.
+ HalpSetHID0(CurrentHID0);
+
+ CurrentHID0 |= HidEnable; // Enable Bits last.
+ HalpSetHID0(CurrentHID0);
+}
+
+
+BOOLEAN
+HalpMapPlanarSpace (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the interrupt acknowledge and error address
+ spaces for a PowerPC system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the initialization is successfully completed, than a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+
+ PHYSICAL_ADDRESS physicalAddress;
+
+
+ //
+ // Map interrupt control space.
+ //
+
+ physicalAddress.HighPart = 0;
+ physicalAddress.LowPart = INTERRUPT_PHYSICAL_BASE;
+ HalpInterruptBase = MmMapIoSpace(physicalAddress,
+ PAGE_SIZE,
+ FALSE);
+
+ //
+ // Map the error address register
+ //
+
+ physicalAddress.HighPart = 0;
+ physicalAddress.LowPart = ERROR_ADDRESS_REGISTER;
+ HalpErrorAddressRegister = MmMapIoSpace(physicalAddress,
+ PAGE_SIZE,
+ FALSE);
+
+ if (HalpInterruptBase == NULL || HalpErrorAddressRegister == NULL)
+ return FALSE;
+ else
+ return TRUE;
+
+
+
+}
+
+BOOLEAN
+HalpMapBusConfigSpace (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the HAL PCI config
+ spaces for a PowerPC system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the initialization is successfully completed, than a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+
+ PHYSICAL_ADDRESS physicalAddress;
+
+
+ //
+ // Map the PCI config space.
+ //
+
+ physicalAddress.LowPart = PCI_CONFIG_PHYSICAL_BASE;
+ HalpPciConfigBase = MmMapIoSpace(physicalAddress,
+ PCI_CONFIG_SIZE,
+ FALSE);
+
+ if (HalpPciConfigBase == NULL)
+ return FALSE;
+ else
+ return TRUE;
+
+}
+
+BOOLEAN
+HalpPhase0MapBusConfigSpace (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the HAL PCI config
+ spaces for a PowerPC system during phase 0 initialization.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the initialization is successfully completed, than a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ //
+ // Map the PCI config space.
+ //
+
+ HalpPciConfigBase = (PUCHAR)KePhase0MapIo(PCI_CONFIG_PHYSICAL_BASE, 0x400000);
+
+ if (HalpPciConfigBase == NULL)
+ return FALSE;
+ else
+ return TRUE;
+
+}
+
+VOID
+HalpPhase0UnMapBusConfigSpace (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the HAL PCI config
+ spaces for a PowerPC system during phase 0 initialization.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the initialization is successfully completed, than a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ //
+ // Unmap the PCI config space and set HalpPciConfigBase to NULL.
+ //
+
+ KePhase0DeleteIoMap(PCI_CONFIG_PHYSICAL_BASE, 0x400000);
+ HalpPciConfigBase = NULL;
+
+}
+
+
+VOID
+HalpHandleMemoryError(
+ VOID
+ )
+
+{
+
+ UCHAR StatusByte;
+ ULONG ErrorAddress;
+ UCHAR TextAddress[20];
+ USHORT DeviceStatus;
+
+ //
+ // Read the error address register first
+ //
+
+ ErrorAddress = READ_PORT_ULONG(HalpErrorAddressRegister);
+
+ //
+ // Convert error address to HEX characters
+ //
+
+ HalpDisplayHex32(ErrorAddress, TextAddress );
+
+ DeviceStatus = HalpReadBridgeUshort(0x80000006);
+ if (DeviceStatus & 0x8100)
+ HalDisplayString("\n27-82660: Status Register: PARITY Error Detected.\n");
+ if (DeviceStatus & 0x4000)
+ HalDisplayString("\n27-82660: Status Register: SERR asserted.\n");
+
+// MOTKJR 08/22/95 - Don't check for the following bit.
+// It is always set when NT scans the slots on the PCI bus.
+// if (DeviceStatus & 0x2000)
+// HalDisplayString("\n27-82660: Status Register: Transaction terminated with master-abort.\n");
+
+ if (DeviceStatus & 0x1000)
+ HalDisplayString("\n27-82660: Status Register: Transaction terminated by target-abort while master.\n");
+ if (DeviceStatus & 0x0800)
+ HalDisplayString("\n27-82660: Status Register: Transaction terminated by target-abort while slave.\n");
+
+ //
+ // Check TEA conditions
+ //
+
+ StatusByte = READ_PORT_UCHAR(&((PDAKOTA_CONTROL)
+ HalpIoControlBase)->MemoryParityErrorStatus);
+
+ if (!(StatusByte & 0x01)) {
+ HalDisplayString ("27-82660: Memory Parity Error at Address ");
+ HalDisplayString (TextAddress);
+ }
+
+ StatusByte = READ_PORT_UCHAR(&((PDAKOTA_CONTROL)
+ HalpIoControlBase)->L2CacheErrorStatus);
+
+ if (!(StatusByte & 0x01)) {
+ HalDisplayString ("27-82660: L2 Cache Parity Error\n");
+ }
+
+ StatusByte = READ_PORT_UCHAR(&((PDAKOTA_CONTROL)
+ HalpIoControlBase)->TransferErrorStatus);
+
+ if (!(StatusByte & 0x01)) {
+ HalDisplayString ("27-82660: Transfer Error at Address ");
+ HalDisplayString (TextAddress);
+ }
+
+ //
+ // Check the Error Status 1 Register
+ //
+
+ StatusByte = HalpReadBridgeUchar(0x800000C1);
+
+ if (StatusByte & 0x03)
+ HalDisplayString("27-82660: CPU Transfer Error.\n");
+
+ if (StatusByte & 0x04)
+ HalDisplayString("27-82660: Memory Parity Error.\n");
+
+ if (StatusByte & 0x08)
+ HalDisplayString("27-82660: Memory Multi-bit ECC Error.\n");
+
+ if (StatusByte & 0x20)
+ HalDisplayString("27-82660: Memory Select Error.\n");
+
+ if (StatusByte & 0x40)
+ HalDisplayString("27-82660: PCI Data Bus Parity Error or PCI_SERR asserted.\n");
+
+ //
+ // Check the Error Status 2 Register
+ //
+
+ StatusByte = HalpReadBridgeUchar(0x800000C5);
+
+ if (StatusByte & 0x04)
+ HalDisplayString("27-82660: CPU Data Bus Parity Error.\n");
+
+ if (StatusByte & 0x08)
+ HalDisplayString("27-82660: L2 Parity Error.\n");
+
+ //
+ // Check the PCI Bus Error Status Register
+ //
+
+ StatusByte = HalpReadBridgeUchar(0x800000C7);
+
+ if (StatusByte & 0x10)
+ HalDisplayString("27-82660: PCI cycle with 82660 Bridge as target.\n");
+
+#if DBG
+ //
+ // We have had a catastrophic hardware malfunction.
+ // Dump the state of the Bridge and HID 0 registers.
+ //
+ HalDisplayString("\n");
+ HalpDumpHardwareState();
+#endif
+}
+
+
+VOID
+HalpCheckHardwareRevisionLevels(
+ VOID
+ )
+{
+ USHORT CpuRevision, CpuType;
+ UCHAR BridgeRevision;
+ UCHAR CharBuffer[20], i;
+ ARC_STATUS Status;
+
+ CpuType = (USHORT)(HalpGetProcessorVersion() >> 16);
+ CpuRevision = (USHORT)(HalpGetProcessorVersion() & 0xFFFF);
+ BridgeRevision = HalpReadBridgeUchar(0x80000008);
+
+ //
+ // Minimum hardware requirements:
+ // 660 Bridge: v1.1 or greater
+ // 603 or 604: v3.2 or greater
+ // 603e: v1.4 or greater
+ // 603ev: any CPU revision
+ // 601, 604e, 620: any CPU revision
+ //
+ if (BridgeRevision >= 0x01) {
+ switch (CpuType) {
+ case 3: // 603
+ case 4: // 604
+ if (CpuRevision >= 0x0302)
+ return;
+ break;
+
+ case 6: // 603e
+ if (CpuRevision >= 0x0104)
+ return;
+ break;
+
+ case 1: // 601
+ case 7: // 603ev
+ case 9: // 604e
+ case 20: // 620
+ default:
+ return;
+ }
+ }
+
+ //
+ // If the environment variable BOOTOLDHARDWARE exists
+ // (value is a don't care), then try to boot anyway.
+ //
+ Status = HalGetEnvironmentVariable("BOOTOLDHARDWARE", 5, CharBuffer);
+ if (Status == ESUCCESS || Status == ENOMEM)
+ return;
+
+ HalDisplayString("HAL: Unsupported CPU and/or Bridge revision level.");
+
+ //
+ // Bug check - after stalling to allow
+ // any information printed on the screen
+ // to be read and seen by the user.
+ //
+ for (i=0; i<15; i++) {
+ HalDisplayString(".");
+ KeStallExecutionProcessor(1000000);
+ }
+
+ KeBugCheck(HAL_INITIALIZATION_FAILED);
+ return;
+}
+
+
+VOID HalpDumpHardwareState(VOID)
+{ ULONG BridgeRegister, HID0;
+ UCHAR CharBuffer[12];
+
+#if DBG
+
+ if ( HalGetEnvironmentVariable("DBG_HAL", BUF_LEN, &CharBuffer[0]) == ESUCCESS ) {
+
+ BridgeRegister = HalpReadBridgeUshort(0x80000004);
+ HalDisplayString("HAL: Bridge register 04 = 0x");
+ HalpDisplayHex16(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUshort(0x80000006);
+ HalDisplayString("HAL: Bridge register 06 = 0x");
+ HalpDisplayHex16(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000A0);
+ HalDisplayString("HAL: Bridge register A0 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000A1);
+ HalDisplayString("HAL: Bridge register A1 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000A2);
+ HalDisplayString("HAL: Bridge register A2 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000B1);
+ HalDisplayString("HAL: Bridge register B1 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000BA);
+ HalDisplayString("HAL: Bridge register BA = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000BB);
+ HalDisplayString("HAL: Bridge register BB = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000C0);
+ HalDisplayString("HAL: Bridge register C0 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000C1);
+ HalDisplayString("HAL: Bridge register C1 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000C3);
+ HalDisplayString("HAL: Bridge register C3 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000C4);
+ HalDisplayString("HAL: Bridge register C4 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000C5);
+ HalDisplayString("HAL: Bridge register C5 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000C7);
+ HalDisplayString("HAL: Bridge register C7 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUlong(0x800000C8);
+ HalDisplayString("HAL: Bridge register C8 = 0x");
+ HalpDisplayHex32(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ BridgeRegister = HalpReadBridgeUchar(0x800000D4);
+ HalDisplayString("HAL: Bridge register D4 = 0x");
+ HalpDisplayHex8(BridgeRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ HID0 = HalpGetHID0();
+ HalDisplayString("HAL: PowerPC Register HID0 = 0x");
+ HalpDisplayHex32(HID0, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ HalDisplayString("HAL: PCR Virtual Address - sprg1 = 0x");
+ HalpDisplayHex32((ULONG)PCRsprg1, CharBuffer );
+ HalDisplayString(CharBuffer);
+ }
+
+#endif
+
+}
diff --git a/private/ntos/nthals/halps/ppc/pxmisc.s b/private/ntos/nthals/halps/ppc/pxmisc.s
new file mode 100644
index 000000000..e7014c025
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxmisc.s
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxmisc.s>
diff --git a/private/ntos/nthals/halps/ppc/pxpcibrd.c b/private/ntos/nthals/halps/ppc/pxpcibrd.c
new file mode 100644
index 000000000..d9b36ce5d
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxpcibrd.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxpcibrd.c>
diff --git a/private/ntos/nthals/halps/ppc/pxpcibus.c b/private/ntos/nthals/halps/ppc/pxpcibus.c
new file mode 100644
index 000000000..ef86e6e28
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxpcibus.c
@@ -0,0 +1,2289 @@
+/*++
+
+
+Copyright (C) 1989-1995 Microsoft Corporation
+
+Module Name:
+
+ pxpcibus.c
+
+Abstract:
+
+ Get/Set bus data routines for the PCI bus
+
+Author:
+
+ Ken Reneris (kenr) 14-June-1994
+ Jim Wooldridge Port to PowerPC
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+
+#include "pxmemctl.h"
+#include "pxpcisup.h"
+
+extern WCHAR rgzMultiFunctionAdapter[];
+extern WCHAR rgzConfigurationData[];
+extern WCHAR rgzIdentifier[];
+extern WCHAR rgzPCIIdentifier[];
+
+extern ULONG HalpPciMaxSlots;
+
+typedef ULONG (*FncConfigIO) (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+typedef VOID (*FncSync) (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PVOID State
+ );
+
+typedef VOID (*FncReleaseSync) (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ );
+
+typedef struct _PCI_CONFIG_HANDLER {
+ FncSync Synchronize;
+ FncReleaseSync ReleaseSynchronzation;
+ FncConfigIO ConfigRead[3];
+ FncConfigIO ConfigWrite[3];
+} PCI_CONFIG_HANDLER, *PPCI_CONFIG_HANDLER;
+
+
+
+//
+// Prototypes
+//
+
+ULONG
+HalpGetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+ULONG
+HalpSetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+NTSTATUS
+HalpAssignPCISlotResources (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName OPTIONAL,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ IN ULONG SlotNumber,
+ IN OUT PCM_RESOURCE_LIST *AllocatedResources
+ );
+
+VOID
+HalpInitializePciBus (
+ VOID
+ );
+
+BOOLEAN
+HalpIsValidPCIDevice (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ );
+
+BOOLEAN
+HalpValidPCISlot (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ );
+
+//-------------------------------------------------
+
+VOID HalpPCISynchronizeType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PVOID State
+ );
+
+VOID HalpPCIReleaseSynchronzationType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ );
+
+ULONG HalpPCIReadUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+VOID HalpPCISynchronizeType2 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PVOID State
+ );
+
+VOID HalpPCIReleaseSynchronzationType2 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ );
+
+ULONG HalpPCIReadUlongType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUcharType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUshortType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUlongType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUcharType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUshortType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+
+//
+// Globals
+//
+
+KSPIN_LOCK HalpPCIConfigLock;
+
+PCI_CONFIG_HANDLER PCIConfigHandler;
+
+PCI_CONFIG_HANDLER PCIConfigHandlerType1 = {
+ HalpPCISynchronizeType1,
+ HalpPCIReleaseSynchronzationType1,
+ {
+ HalpPCIReadUlongType1, // 0
+ HalpPCIReadUcharType1, // 1
+ HalpPCIReadUshortType1 // 2
+ },
+ {
+ HalpPCIWriteUlongType1, // 0
+ HalpPCIWriteUcharType1, // 1
+ HalpPCIWriteUshortType1 // 2
+ }
+};
+
+PCI_CONFIG_HANDLER PCIConfigHandlerType2 = {
+ HalpPCISynchronizeType2,
+ HalpPCIReleaseSynchronzationType2,
+ {
+ HalpPCIReadUlongType2, // 0
+ HalpPCIReadUcharType2, // 1
+ HalpPCIReadUshortType2 // 2
+ },
+ {
+ HalpPCIWriteUlongType2, // 0
+ HalpPCIWriteUcharType2, // 1
+ HalpPCIWriteUshortType2 // 2
+ }
+};
+
+UCHAR PCIDeref[4][4] = { {0,1,2,2},{1,1,1,1},{2,1,2,2},{1,1,1,1} };
+
+VOID
+HalpPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN FncConfigIO *ConfigIO
+ );
+
+#if DBG
+#define DBGMSG(a) DbgPrint(a)
+VOID
+HalpTestPci (
+ ULONG
+ );
+#else
+#define DBGMSG(a)
+#endif
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpInitializePciBus)
+#pragma alloc_text(INIT,HalpAllocateAndInitPciBusHandler)
+#pragma alloc_text(INIT,HalpIsValidPCIDevice)
+#pragma alloc_text(PAGE,HalpAssignPCISlotResources)
+#endif
+
+
+
+VOID
+HalpInitializePciBus (
+ VOID
+ )
+{
+ PPCI_REGISTRY_INFO PCIRegInfo;
+ UNICODE_STRING unicodeString, ConfigName, IdentName;
+ OBJECT_ATTRIBUTES objectAttributes;
+ HANDLE hMFunc, hBus;
+ NTSTATUS status;
+ UCHAR buffer [sizeof(PPCI_REGISTRY_INFO) + 99];
+ PWSTR p;
+ WCHAR wstr[8];
+ ULONG i, d, junk, HwType;
+ PBUS_HANDLER BusHandler;
+ PCI_SLOT_NUMBER SlotNumber;
+ PKEY_VALUE_FULL_INFORMATION ValueInfo;
+ PCM_FULL_RESOURCE_DESCRIPTOR Desc;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PDesc;
+
+
+ //
+ // Search the hardware description looking for any reported
+ // PCI bus. The first ARC entry for a PCI bus will contain
+ // the PCI_REGISTRY_INFO.
+
+ RtlInitUnicodeString (&unicodeString, rgzMultiFunctionAdapter);
+ InitializeObjectAttributes (
+ &objectAttributes,
+ &unicodeString,
+ OBJ_CASE_INSENSITIVE,
+ NULL, // handle
+ NULL);
+
+
+ status = ZwOpenKey (&hMFunc, KEY_READ, &objectAttributes);
+ if (!NT_SUCCESS(status)) {
+ return ;
+ }
+
+ unicodeString.Buffer = wstr;
+ unicodeString.MaximumLength = sizeof (wstr);
+
+ RtlInitUnicodeString (&ConfigName, rgzConfigurationData);
+ RtlInitUnicodeString (&IdentName, rgzIdentifier);
+
+ ValueInfo = (PKEY_VALUE_FULL_INFORMATION) buffer;
+
+ for (i=0; TRUE; i++) {
+ RtlIntegerToUnicodeString (i, 10, &unicodeString);
+ InitializeObjectAttributes (
+ &objectAttributes,
+ &unicodeString,
+ OBJ_CASE_INSENSITIVE,
+ hMFunc,
+ NULL);
+
+ status = ZwOpenKey (&hBus, KEY_READ, &objectAttributes);
+ if (!NT_SUCCESS(status)) {
+ //
+ // Out of Multifunction adapter entries...
+ //
+
+ ZwClose (hMFunc);
+ return ;
+ }
+
+ //
+ // Check the Indentifier to see if this is a PCI entry
+ //
+
+ status = ZwQueryValueKey (
+ hBus,
+ &IdentName,
+ KeyValueFullInformation,
+ ValueInfo,
+ sizeof (buffer),
+ &junk
+ );
+
+ if (!NT_SUCCESS (status)) {
+ ZwClose (hBus);
+ continue;
+ }
+
+ p = (PWSTR) ((PUCHAR) ValueInfo + ValueInfo->DataOffset);
+ if (p[0] != L'P' || p[1] != L'C' || p[2] != L'I' || p[3] != 0) {
+ ZwClose (hBus);
+ continue;
+ }
+
+ //
+ // The first PCI entry has the PCI_REGISTRY_INFO structure
+ // attached to it.
+ //
+
+ status = ZwQueryValueKey (
+ hBus,
+ &ConfigName,
+ KeyValueFullInformation,
+ ValueInfo,
+ sizeof (buffer),
+ &junk
+ );
+
+ ZwClose (hBus);
+ if (!NT_SUCCESS(status)) {
+ continue ;
+ }
+
+ Desc = (PCM_FULL_RESOURCE_DESCRIPTOR) ((PUCHAR)
+ ValueInfo + ValueInfo->DataOffset);
+ PDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)
+ Desc->PartialResourceList.PartialDescriptors);
+
+ if (PDesc->Type == CmResourceTypeDeviceSpecific) {
+ // got it..
+ PCIRegInfo = (PPCI_REGISTRY_INFO) (PDesc+1);
+ break;
+ }
+ }
+
+ //
+ // Initialize spinlock for synchronizing access to PCI space
+ //
+
+ KeInitializeSpinLock (&HalpPCIConfigLock);
+
+ //
+ // PCIRegInfo describes the system's PCI support as indicated by the BIOS.
+ //
+
+ HwType = PCIRegInfo->HardwareMechanism & 0xf;
+
+#if 0
+ //
+ // Some AMI bioses claim machines are Type2 configuration when they
+ // are really type1. If this is a Type2 with at least one bus,
+ // try to verify it's not really a type1 bus
+ //
+
+ if (PCIRegInfo->NoBuses && HwType == 2) {
+
+ //
+ // Check each slot for a valid device. Which every style configuration
+ // space shows a valid device first will be used
+ //
+
+ SlotNumber.u.bits.Reserved = 0;
+ SlotNumber.u.bits.FunctionNumber = 0;
+
+ for (d = 0; d < PCI_MAX_DEVICES; d++) {
+ SlotNumber.u.bits.DeviceNumber = d;
+
+ //
+ // First try what the BIOS claims - type 2. Allocate type2
+ // test handle for PCI bus 0.
+ //
+
+ HwType = 2;
+ BusHandler = HalpAllocateAndInitPciBusHandler (HwType, 0, TRUE);
+
+ if (HalpIsValidPCIDevice (BusHandler, SlotNumber)) {
+ break;
+ }
+
+ //
+ // Valid device not found on Type2 access for this slot.
+ // Reallocate the bus handler are Type1 and take a look.
+ //
+
+ HwType = 1;
+ BusHandler = HalpAllocateAndInitPciBusHandler (HwType, 0, TRUE);
+
+ if (HalpIsValidPCIDevice (BusHandler, SlotNumber)) {
+ break;
+ }
+
+ HwType = 2;
+ }
+
+ //
+ // Reset handler for PCI bus 0 to whatever style config space
+ // was finally decided.
+ //
+
+ HalpAllocateAndInitPciBusHandler (HwType, 0, FALSE);
+ }
+#endif
+
+
+ //
+ // For each PCI bus present, allocate a handler structure and
+ // fill in the dispatch functions
+ //
+
+ do {
+ for (i=0; i < PCIRegInfo->NoBuses; i++) {
+
+ //
+ // If handler not already built, do it now
+ //
+
+ if (!HalpHandlerForBus (PCIBus, i)) {
+ HalpAllocateAndInitPciBusHandler (HwType, i, FALSE);
+ }
+ }
+
+ //
+ // Bus handlers for all PCI buses have been allocated, go collect
+ // pci bridge information.
+ //
+
+ } while (HalpGetPciBridgeConfig (HwType, &PCIRegInfo->NoBuses)) ;
+
+ //
+ // Fixup SUPPORTED_RANGES
+ //
+
+ HalpFixupPciSupportedRanges (PCIRegInfo->NoBuses);
+
+#if DBG
+ HalpTestPci (0);
+#endif
+}
+
+
+PBUS_HANDLER
+HalpAllocateAndInitPciBusHandler (
+ IN ULONG HwType,
+ IN ULONG BusNo,
+ IN BOOLEAN TestAllocation
+ )
+{
+ PBUS_HANDLER Bus;
+ PPCIPBUSDATA BusData;
+
+ Bus = HalpAllocateBusHandler (
+ PCIBus, // Interface type
+ PCIConfiguration, // Has this configuration space
+ BusNo, // bus #
+ Internal, // child of this bus
+ 0, // and number
+ sizeof (PCIPBUSDATA) // sizeof bus specific buffer
+ );
+
+ //
+ // Fill in PCI handlers
+ //
+
+ Bus->GetBusData = (PGETSETBUSDATA) HalpGetPCIData;
+ Bus->SetBusData = (PGETSETBUSDATA) HalpSetPCIData;
+ Bus->GetInterruptVector = (PGETINTERRUPTVECTOR) HalpGetPCIIntOnISABus;
+ Bus->AdjustResourceList = (PADJUSTRESOURCELIST) HalpAdjustPCIResourceList;
+ Bus->AssignSlotResources = (PASSIGNSLOTRESOURCES) HalpAssignPCISlotResources;
+ Bus->BusAddresses->Dma.Limit = 0;
+
+ BusData = (PPCIPBUSDATA) Bus->BusData;
+
+ //
+ // Fill in common PCI data
+ //
+
+ BusData->CommonData.Tag = PCI_DATA_TAG;
+ BusData->CommonData.Version = PCI_DATA_VERSION;
+ BusData->CommonData.ReadConfig = (PciReadWriteConfig) HalpReadPCIConfig;
+ BusData->CommonData.WriteConfig = (PciReadWriteConfig) HalpWritePCIConfig;
+ BusData->CommonData.Pin2Line = (PciPin2Line) HalpPCIPin2ISALine;
+ BusData->CommonData.Line2Pin = (PciLine2Pin) HalpPCIISALine2Pin;
+
+ //
+ // Set defaults
+ //
+
+ Bus->BusAddresses->Memory.Limit = 0x3EFFFFFF;
+ Bus->BusAddresses->IO.Limit = 0x3F7FFFFF;
+ BusData->GetIrqRange = (PciIrqRange) HalpGetISAFixedPCIIrq;
+
+ RtlInitializeBitMap (&BusData->DeviceConfigured,
+ BusData->ConfiguredBits, 256);
+
+ switch (HwType) {
+ case 1:
+ //
+ // Initialize access port information for Type1 handlers
+ // direct Method.
+ //
+
+ RtlCopyMemory (&PCIConfigHandler,
+ &PCIConfigHandlerType1,
+ sizeof (PCIConfigHandler));
+
+ BusData->MaxDevice = HalpPciMaxSlots;
+ break;
+
+ case 2:
+ //
+ // Initialize access port information for Type2 handlers
+ // indirect Method.
+ //
+
+ RtlCopyMemory (&PCIConfigHandler,
+ &PCIConfigHandlerType2,
+ sizeof (PCIConfigHandler));
+
+ //
+ // Allow access all 32 devices per bus.
+ //
+ BusData->MaxDevice = PCI_MAX_DEVICES;
+ break;
+
+ default:
+ // unsupport type
+ DBGMSG ("HAL: Unkown PCI type\n");
+ }
+
+ if (!TestAllocation) {
+#ifdef SUBCLASSPCI
+ HalpSubclassPCISupport (Bus, HwType);
+#endif
+ }
+
+ return Bus;
+}
+
+BOOLEAN
+HalpIsValidPCIDevice (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ )
+/*++
+
+Routine Description:
+
+ Reads the device configuration data for the given slot and
+ returns TRUE if the configuration data appears to be valid for
+ a PCI device; otherwise returns FALSE.
+
+Arguments:
+
+ BusHandler - Bus to check
+ Slot - Slot to check
+
+--*/
+
+{
+ PPCI_COMMON_CONFIG PciData;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ ULONG i, j;
+
+
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+
+ //
+ // Read device common header
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Valid device header?
+ //
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != PCI_DEVICE_TYPE) {
+
+ return FALSE;
+ }
+
+ //
+ // Check fields for reasonable values
+ //
+
+ if ((PciData->u.type0.InterruptPin && PciData->u.type0.InterruptPin > 4) ||
+ (PciData->u.type0.InterruptLine & 0x70)) {
+ return FALSE;
+ }
+
+ for (i=0; i < PCI_TYPE0_ADDRESSES; i++) {
+ j = PciData->u.type0.BaseAddresses[i];
+
+ if (j & PCI_ADDRESS_IO_SPACE) {
+ if (j > 0xffff) {
+ // IO port > 64k?
+ return FALSE;
+ }
+ } else {
+ if (j > 0xf && j < 0x80000) {
+ // Mem address < 0x8000h?
+ return FALSE;
+ }
+ }
+
+ if (Is64BitBaseAddress(j)) {
+ i += 1;
+ }
+ }
+
+ //
+ // Guess it's a valid device..
+ //
+
+ return TRUE;
+}
+
+
+
+
+
+ULONG
+HalpGetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function returns the Pci bus data for a device.
+
+Arguments:
+
+ BusNumber - Indicates which bus.
+
+ VendorSpecificDevice - The VendorID (low Word) and DeviceID (High Word)
+
+ Buffer - Supplies the space to store the data.
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+ If this PCI slot has never been set, then the configuration information
+ returned is zeroed.
+
+
+--*/
+{
+ PPCI_COMMON_CONFIG PciData;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ PPCIPBUSDATA BusData;
+ ULONG Len;
+ ULONG i, bit;
+
+ if (Length > sizeof (PCI_COMMON_CONFIG)) {
+ Length = sizeof (PCI_COMMON_CONFIG);
+ }
+
+ Len = 0;
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The user did not request any data from the common
+ // header. Verify the PCI device exists, then continue
+ // in the device specific area.
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, sizeof(ULONG));
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID) {
+ return 0;
+ }
+
+ } else {
+
+ //
+ // Caller requested at least some data within the
+ // common header. Read the whole header, effect the
+ // fields we need to and then copy the user's requested
+ // bytes from the header
+ //
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ //
+ // Read this PCI devices slot data
+ //
+
+ Len = PCI_COMMON_HDR_LENGTH;
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, Len);
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != PCI_DEVICE_TYPE) {
+ PciData->VendorID = PCI_INVALID_VENDORID;
+ Len = 2; // only return invalid id
+
+ } else {
+
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, Slot, PciData);
+ }
+
+ //
+ // Has this PCI device been configured?
+ //
+
+#if 0
+ //
+ // On DBG build, if this PCI device has not yet been configured,
+ // then don't report any current configuration the device may have.
+ //
+
+ bit = PciBitIndex(Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber);
+ if (!RtlCheckBit(&BusData->DeviceConfigured, bit)) {
+
+ for (i=0; i < PCI_TYPE0_ADDRESSES; i++) {
+ PciData->u.type0.BaseAddresses[i] = 0;
+ }
+
+ PciData->u.type0.ROMBaseAddress = 0;
+ PciData->Command &= ~(PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE);
+ }
+#endif
+
+
+ //
+ // Copy whatever data overlaps into the callers buffer
+ //
+
+ if (Len < Offset) {
+ // no data at caller's buffer
+ return 0;
+ }
+
+ Len -= Offset;
+ if (Len > Length) {
+ Len = Length;
+ }
+
+ RtlMoveMemory(Buffer, iBuffer + Offset, Len);
+
+ Offset += Len;
+ Buffer += Len;
+ Length -= Len;
+ }
+
+ if (Length) {
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The remaining Buffer comes from the Device Specific
+ // area - put on the kitten gloves and read from it.
+ //
+ // Specific read/writes to the PCI device specific area
+ // are guarenteed:
+ //
+ // Not to read/write any byte outside the area specified
+ // by the caller. (this may cause WORD or BYTE references
+ // to the area in order to read the non-dword aligned
+ // ends of the request)
+ //
+ // To use a WORD access if the requested length is exactly
+ // a WORD long.
+ //
+ // To use a BYTE access if the requested length is exactly
+ // a BYTE long.
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, Buffer, Offset, Length);
+ Len += Length;
+ }
+ }
+
+ return Len;
+}
+
+ULONG
+HalpSetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function returns the Pci bus data for a device.
+
+Arguments:
+
+
+ VendorSpecificDevice - The VendorID (low Word) and DeviceID (High Word)
+
+ Buffer - Supplies the space to store the data.
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+--*/
+{
+ PPCI_COMMON_CONFIG PciData, PciData2;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ UCHAR iBuffer2[PCI_COMMON_HDR_LENGTH];
+ PPCIPBUSDATA BusData;
+ ULONG Len, cnt;
+
+
+ if (Length > sizeof (PCI_COMMON_CONFIG)) {
+ Length = sizeof (PCI_COMMON_CONFIG);
+ }
+
+
+ Len = 0;
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+ PciData2 = (PPCI_COMMON_CONFIG) iBuffer2;
+
+
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The user did not request any data from the common
+ // header. Verify the PCI device exists, then continue in
+ // the device specific area.
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, sizeof(ULONG));
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID) {
+ return 0;
+ }
+
+ } else {
+
+ //
+ // Caller requested to set at least some data within the
+ // common header.
+ //
+
+ Len = PCI_COMMON_HDR_LENGTH;
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, Len);
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != PCI_DEVICE_TYPE) {
+
+ // no device, or header type unkown
+ return 0;
+ }
+
+
+ //
+ // Set this device as configured
+ //
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+#if 0
+ cnt = PciBitIndex(Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber);
+ RtlSetBits (&BusData->DeviceConfigured, cnt, 1);
+#endif
+ //
+ // Copy COMMON_HDR values to buffer2, then overlay callers changes.
+ //
+
+ RtlMoveMemory (iBuffer2, iBuffer, Len);
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, Slot, PciData2);
+
+ Len -= Offset;
+ if (Len > Length) {
+ Len = Length;
+ }
+
+ RtlMoveMemory (iBuffer2+Offset, Buffer, Len);
+
+ // in case interrupt line or pin was editted
+ BusData->CommonData.Line2Pin (BusHandler, RootHandler, Slot, PciData2, PciData);
+
+#if DBG
+ //
+ // Verify R/O fields haven't changed
+ //
+ if (PciData2->VendorID != PciData->VendorID ||
+ PciData2->DeviceID != PciData->DeviceID ||
+ PciData2->RevisionID != PciData->RevisionID ||
+ PciData2->ProgIf != PciData->ProgIf ||
+ PciData2->SubClass != PciData->SubClass ||
+ PciData2->BaseClass != PciData->BaseClass ||
+ PciData2->HeaderType != PciData->HeaderType ||
+ PciData2->BaseClass != PciData->BaseClass ||
+ PciData2->u.type0.MinimumGrant != PciData->u.type0.MinimumGrant ||
+ PciData2->u.type0.MaximumLatency != PciData->u.type0.MaximumLatency) {
+ DbgPrint ("PCI SetBusData: Read-Only configuration value changed\n");
+ //DbgBreakPoint ();
+ }
+#endif
+ //
+ // Set new PCI configuration
+ //
+
+ HalpWritePCIConfig (BusHandler, Slot, iBuffer2+Offset, Offset, Len);
+
+ Offset += Len;
+ Buffer += Len;
+ Length -= Len;
+ }
+
+ if (Length) {
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The remaining Buffer comes from the Device Specific
+ // area - put on the kitten gloves and write it
+ //
+ // Specific read/writes to the PCI device specific area
+ // are guarenteed:
+ //
+ // Not to read/write any byte outside the area specified
+ // by the caller. (this may cause WORD or BYTE references
+ // to the area in order to read the non-dword aligned
+ // ends of the request)
+ //
+ // To use a WORD access if the requested length is exactly
+ // a WORD long.
+ //
+ // To use a BYTE access if the requested length is exactly
+ // a BYTE long.
+ //
+
+ HalpWritePCIConfig (BusHandler, Slot, Buffer, Offset, Length);
+ Len += Length;
+ }
+ }
+
+ return Len;
+}
+
+VOID
+HalpReadPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+#define ATIBUG 1
+#if ATIBUG
+ USHORT VendorId;
+ LONG Len;
+#endif
+
+ if (!HalpValidPCISlot (BusHandler, Slot)) {
+ //
+ // Invalid SlotID return no data
+ //
+
+ RtlFillMemory (Buffer, Length, (UCHAR) -1);
+ return ;
+ }
+
+#if ATIBUG
+//
+// Temporary Hack (MOTKJR) - We have discovered a problem between the ATI
+// Video Driver and the NCR 810/825 SCSI parts. The NCR chip has hardware
+// registers in Configuration Space above 0x40 which have a side effect that
+// a read from these registers is destructive to its contents. If a SCSI
+// operation is active when these registers are read, the NCR device will
+// abort the operation and further I/O is impossible. Therefore, we will
+// not allow anyone to read from Offset 0x40 to 0xFF for any PCI slot that
+// has an NCR vendor ID number. Care must be taken to check for requests
+// which overlap both the PCI Common Header and the Device Dependent area.
+//
+#define NCR_VENDOR_ID 0x1000
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) &VendorId, 0x0, sizeof(VendorId),
+ PCIConfigHandler.ConfigRead);
+
+ if ((VendorId == NCR_VENDOR_ID) && (Offset + Length > PCI_COMMON_HDR_LENGTH)) {
+ Len = PCI_COMMON_HDR_LENGTH - Offset;
+ if (Len < 0)
+ Len = 0;
+ RtlFillMemory ((PVOID)((PUCHAR)Buffer+Len), Length-Len, (UCHAR) -1);
+ if (Offset >= PCI_COMMON_HDR_LENGTH)
+ return;
+ Length = Len;
+ }
+#endif
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) Buffer, Offset, Length,
+ PCIConfigHandler.ConfigRead);
+}
+
+VOID
+HalpWritePCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ if (!HalpValidPCISlot (BusHandler, Slot)) {
+ //
+ // Invalid SlotID do nothing
+ //
+ return ;
+ }
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) Buffer, Offset, Length,
+ PCIConfigHandler.ConfigWrite);
+}
+
+BOOLEAN
+HalpValidPCISlot (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ )
+{
+ PCI_SLOT_NUMBER Slot2;
+ PPCIPBUSDATA BusData;
+ UCHAR HeaderType;
+ ULONG i;
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ if (Slot.u.bits.Reserved != 0) {
+ return FALSE;
+ }
+
+ if (Slot.u.bits.DeviceNumber >= BusData->MaxDevice) {
+ return FALSE;
+ }
+
+ if (Slot.u.bits.FunctionNumber == 0) {
+ return TRUE;
+ }
+
+ //
+ // Non zero function numbers are only supported if the
+ // device has the PCI_MULTIFUNCTION bit set in it's header
+ //
+
+ i = Slot.u.bits.DeviceNumber;
+
+ //
+ // Read DeviceNumber, Function zero, to determine if the
+ // PCI supports multifunction devices
+ //
+
+ Slot2 = Slot;
+ Slot2.u.bits.FunctionNumber = 0;
+
+ HalpReadPCIConfig (
+ BusHandler,
+ Slot2,
+ &HeaderType,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, HeaderType),
+ sizeof (UCHAR)
+ );
+
+ if (!(HeaderType & PCI_MULTIFUNCTION) || HeaderType == 0xFF) {
+ // this device doesn't exists or doesn't support MULTIFUNCTION types
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+VOID
+HalpPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN FncConfigIO *ConfigIO
+ )
+{
+ KIRQL OldIrql;
+ ULONG i;
+ UCHAR State[20];
+ PPCIPBUSDATA BusData;
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+ PCIConfigHandler.Synchronize (BusHandler, Slot, &OldIrql, State);
+
+ while (Length) {
+ i = PCIDeref[Offset % sizeof(ULONG)][Length % sizeof(ULONG)];
+ i = ConfigIO[i] (BusData, State, Buffer, Offset);
+
+ Offset += i;
+ Buffer += i;
+ Length -= i;
+ }
+
+ PCIConfigHandler.ReleaseSynchronzation (BusHandler, OldIrql);
+}
+
+VOID HalpPCISynchronizeType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1
+ )
+{
+ //
+ // Initialize PciCfg1
+ //
+
+ PciCfg1->u.AsULONG = HalpTranslatePciSlotNumber(BusHandler->BusNumber, Slot.u.bits.DeviceNumber)
+ + 0x100 * Slot.u.bits.FunctionNumber;
+
+}
+
+VOID HalpPCIReleaseSynchronzationType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ )
+{
+
+
+}
+
+
+ULONG
+HalpPCIReadUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ *Buffer = READ_PORT_UCHAR ((PUCHAR)(PciCfg1->u.AsULONG + i));
+ return sizeof (UCHAR);
+}
+
+ULONG
+HalpPCIReadUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ *((PUSHORT) Buffer) = READ_PORT_USHORT ((PUSHORT)(PciCfg1->u.AsULONG + i));
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIReadUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ *((PULONG) Buffer) = READ_PORT_ULONG ((PULONG) (PciCfg1->u.AsULONG));
+ return sizeof (ULONG);
+}
+
+
+ULONG
+HalpPCIWriteUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_UCHAR (PciCfg1->u.AsULONG + i, *Buffer );
+ return sizeof (UCHAR);
+}
+
+ULONG
+HalpPCIWriteUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_USHORT (PciCfg1->u.AsULONG + i, *((PUSHORT) Buffer) );
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIWriteUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_ULONG (PciCfg1->u.AsULONG, *((PULONG) Buffer) );
+ return sizeof (ULONG);
+}
+
+VOID HalpPCISynchronizeType2 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1
+ )
+{
+
+ //
+ // Initialize PciCfg1
+ //
+
+ PciCfg1->u.AsULONG = 0;
+ if ((PciCfg1->u.bits.BusNumber = BusHandler->BusNumber) == 0) {
+
+ // This hack is to maintain device number compatibility
+ // on bus 0 with the Type1 functions. We do this so that
+ // the installed base maintains the same "slot" numbering.
+ // The notable issue is with network interfaces where the
+ // slot number is stored in the registry at install time.
+ // It was judged too subtle and too painful to have everyone
+ // reinstall networking if they added a bridged device to
+ // their system.
+
+ int MappedDev;
+ ULONG Offset;
+ #define PRESHIFT 9 // Make invalid slot numbers to map to dev 0.
+ // Dev 0 is inaccessible from the 27-82660 Bridge.
+
+ // Get the offset from the Type1 (direct mapping) offset table.
+ // If the device number isn't "valid", use an offset that won't
+ // actually end up selecting any device.
+
+ Offset = (Slot.u.bits.DeviceNumber < HalpPciMaxSlots) ?
+ HalpPciConfigSlot[Slot.u.bits.DeviceNumber] : (1 << (PRESHIFT+1));
+
+ // Determine the device number accessed by the "offset".
+ // If bit 11 is set, MappedDev = 11; bit 12, MappedDev = 12;...
+
+ Offset >>= PRESHIFT;
+ MappedDev = PRESHIFT - 1;
+
+ do {
+ MappedDev++;
+ Offset >>= 1;
+
+ } while (Offset);
+
+ // The 27-82660 docs say to set the device number field to
+ // 10 less than the PCI Address bit number.
+
+ PciCfg1->u.bits.DeviceNumber = MappedDev - 10;
+
+ } else {
+ PciCfg1->u.bits.DeviceNumber = Slot.u.bits.DeviceNumber;
+ }
+ PciCfg1->u.bits.FunctionNumber = Slot.u.bits.FunctionNumber;
+ PciCfg1->u.bits.Enable = TRUE;
+
+ KeRaiseIrql (PROFILE_LEVEL, Irql);
+ KiAcquireSpinLock (&HalpPCIConfigLock);
+
+}
+
+
+VOID HalpPCIReleaseSynchronzationType2 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ )
+{
+
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql);
+
+}
+
+
+ULONG
+HalpPCIReadUcharType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_ULONG (&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigAddress, PciCfg1->u.AsULONG );
+ *((PUCHAR) Buffer) = READ_PORT_UCHAR ((PUCHAR)&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigData + i);
+ return sizeof (UCHAR);
+}
+
+ULONG
+HalpPCIReadUshortType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_ULONG (&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigAddress, PciCfg1->u.AsULONG );
+ *((PUSHORT) Buffer) = READ_PORT_USHORT ((PUCHAR)&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigData + i);
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIReadUlongType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_ULONG (&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigAddress, PciCfg1->u.AsULONG);
+ *((PULONG) Buffer) = READ_PORT_ULONG (&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigData);
+ return sizeof(ULONG);
+}
+
+
+ULONG
+HalpPCIWriteUcharType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_ULONG (&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigAddress, PciCfg1->u.AsULONG );
+ WRITE_PORT_UCHAR ((PUCHAR)&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigData + i,*Buffer);
+ return sizeof (UCHAR);
+}
+
+ULONG
+HalpPCIWriteUshortType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_ULONG (&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigAddress, PciCfg1->u.AsULONG );
+ WRITE_PORT_USHORT ((PUCHAR)&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigData + (USHORT) i,*((PUSHORT)Buffer));
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIWriteUlongType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+
+ WRITE_PORT_ULONG (&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigAddress, PciCfg1->u.AsULONG);
+ WRITE_PORT_ULONG (&((PPLANAR_CONTROL)HalpIoControlBase)->ConfigData,*((PULONG)Buffer));
+ return sizeof(ULONG);
+}
+
+
+NTSTATUS
+HalpAssignPCISlotResources (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName OPTIONAL,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ IN ULONG Slot,
+ IN OUT PCM_RESOURCE_LIST *pAllocatedResources
+ )
+/*++
+
+Routine Description:
+
+ Reads the targeted device to determine it's required resources.
+ Calls IoAssignResources to allocate them.
+ Sets the targeted device with it's assigned resoruces
+ and returns the assignments to the caller.
+
+Arguments:
+
+Return Value:
+
+ STATUS_SUCCESS or error
+
+--*/
+{
+ NTSTATUS status;
+ PUCHAR WorkingPool;
+ PPCI_COMMON_CONFIG PciData, PciOrigData, PciData2;
+ PCI_SLOT_NUMBER PciSlot;
+ PPCIPBUSDATA BusData;
+ PIO_RESOURCE_REQUIREMENTS_LIST CompleteList;
+ PIO_RESOURCE_DESCRIPTOR Descriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor;
+ ULONG BusNumber;
+ ULONG i, j, m, length, memtype;
+ ULONG NoBaseAddress, RomIndex, Option;
+ PULONG BaseAddress[PCI_TYPE0_ADDRESSES + 1];
+ PULONG OrigAddress[PCI_TYPE0_ADDRESSES + 1];
+ BOOLEAN Match, EnableRomBase;
+
+
+ *pAllocatedResources = NULL;
+ PciSlot = *((PPCI_SLOT_NUMBER) &Slot);
+ BusNumber = BusHandler->BusNumber;
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ //
+ // Allocate some pool for working space
+ //
+
+ i = sizeof (IO_RESOURCE_REQUIREMENTS_LIST) +
+ sizeof (IO_RESOURCE_DESCRIPTOR) * (PCI_TYPE0_ADDRESSES + 2) * 2 +
+ PCI_COMMON_HDR_LENGTH * 3;
+
+ WorkingPool = (PUCHAR) ExAllocatePool (PagedPool, i);
+ if (!WorkingPool) {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // Zero initialize pool, and get pointers into memory
+ //
+
+ RtlZeroMemory (WorkingPool, i);
+ CompleteList = (PIO_RESOURCE_REQUIREMENTS_LIST) WorkingPool;
+ PciData = (PPCI_COMMON_CONFIG) (WorkingPool + i - PCI_COMMON_HDR_LENGTH * 3);
+ PciData2 = (PPCI_COMMON_CONFIG) (WorkingPool + i - PCI_COMMON_HDR_LENGTH * 2);
+ PciOrigData = (PPCI_COMMON_CONFIG) (WorkingPool + i - PCI_COMMON_HDR_LENGTH * 1);
+
+ //
+ // Read the PCI device's configuration
+ //
+
+ HalpReadPCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+ if (PciData->VendorID == PCI_INVALID_VENDORID) {
+ ExFreePool (WorkingPool);
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+ //
+ // Make a copy of the device's current settings
+ //
+
+ RtlMoveMemory (PciOrigData, PciData, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Initialize base addresses base on configuration data type
+ //
+
+ switch (PCI_CONFIG_TYPE(PciData)) {
+ case 0 :
+ NoBaseAddress = PCI_TYPE0_ADDRESSES+1;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ BaseAddress[j] = &PciData->u.type0.BaseAddresses[j];
+ OrigAddress[j] = &PciOrigData->u.type0.BaseAddresses[j];
+ }
+ BaseAddress[j] = &PciData->u.type0.ROMBaseAddress;
+ OrigAddress[j] = &PciOrigData->u.type0.ROMBaseAddress;
+ RomIndex = j;
+ break;
+ case 1:
+ NoBaseAddress = PCI_TYPE1_ADDRESSES+1;
+ for (j=0; j < PCI_TYPE1_ADDRESSES; j++) {
+ BaseAddress[j] = &PciData->u.type1.BaseAddresses[j];
+ OrigAddress[j] = &PciOrigData->u.type1.BaseAddresses[j];
+ }
+ BaseAddress[j] = &PciData->u.type1.ROMBaseAddress;
+ OrigAddress[j] = &PciOrigData->u.type1.ROMBaseAddress;
+ RomIndex = j;
+ break;
+
+ default:
+ ExFreePool (WorkingPool);
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+ //
+ // If the BIOS doesn't have the device's ROM enabled, then we won't
+ // enable it either. Remove it from the list.
+ //
+
+ EnableRomBase = TRUE;
+ if (!(*BaseAddress[RomIndex] & PCI_ROMADDRESS_ENABLED)) {
+ ASSERT (RomIndex+1 == NoBaseAddress);
+ EnableRomBase = FALSE;
+ NoBaseAddress -= 1;
+ }
+
+ //
+ // Set resources to all bits on to see what type of resources
+ // are required.
+ //
+
+ for (j=0; j < NoBaseAddress; j++) {
+ *BaseAddress[j] = 0xFFFFFFFF;
+ }
+
+//*BJ* PciData->Command &= ~(PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE);
+ *BaseAddress[RomIndex] &= ~PCI_ROMADDRESS_ENABLED;
+ HalpWritePCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+ HalpReadPCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ // note type0 & type1 overlay ROMBaseAddress, InterruptPin, and InterruptLine
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, PciSlot, PciData);
+
+ //
+ // Build an IO_RESOURCE_REQUIREMENTS_LIST for the PCI device
+ //
+
+ CompleteList->InterfaceType = PCIBus;
+ CompleteList->BusNumber = BusNumber;
+ CompleteList->SlotNumber = Slot;
+ CompleteList->AlternativeLists = 1;
+
+ CompleteList->List[0].Version = 1;
+ CompleteList->List[0].Revision = 1;
+
+ Descriptor = CompleteList->List[0].Descriptors;
+
+ //
+ // If PCI device has an interrupt resource, add it
+ //
+
+ if (PciData->u.type0.InterruptPin) {
+ CompleteList->List[0].Count++;
+
+ Descriptor->Option = 0;
+ Descriptor->Type = CmResourceTypeInterrupt;
+ Descriptor->ShareDisposition = CmResourceShareShared;
+ Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+
+ // Fill in any vector here - we'll pick it back up in
+ // HalAdjustResourceList and adjust it to it's allowed settings
+ Descriptor->u.Interrupt.MinimumVector = 0;
+ Descriptor->u.Interrupt.MaximumVector = 0xff;
+ Descriptor++;
+ }
+
+ //
+ // Add a memory/port resoruce for each PCI resource
+ //
+
+ *BaseAddress[RomIndex] &= ~0x7ff;
+
+ //
+ // Rom Base Address resource is not enabled, as the ROM code cannot
+ // be executed on a risk box, and the algorithm below interprets
+ // the card's Rom Base Address requirements incorrectly
+ //
+
+
+ for (j=0; j < NoBaseAddress; j++) {
+ if (*BaseAddress[j]) {
+ i = *BaseAddress[j];
+
+ // scan for first set bit, that's the length & alignment
+ length = 1 << (i & PCI_ADDRESS_IO_SPACE ? 2 : 4);
+ while (!(i & length) && length) {
+ length <<= 1;
+ }
+
+ // scan for last set bit, that's the maxaddress + 1
+ for (m = length; i & m; m <<= 1) ;
+ m--;
+
+ // check for hosed PCI configuration requirements
+ if (length & ~m) {
+#if DBG
+ DbgPrint ("PCI: defective device! Bus %d, Slot %d, Function %d\n",
+ BusNumber,
+ PciSlot.u.bits.DeviceNumber,
+ PciSlot.u.bits.FunctionNumber
+ );
+
+ DbgPrint ("PCI: BaseAddress[%d] = %08lx\n", j, i);
+#endif
+ // the device is in error - punt. don't allow this
+ // resource any option - it either gets set to whatever
+ // bits it was able to return, or it doesn't get set.
+
+ if (i & PCI_ADDRESS_IO_SPACE) {
+ m = i & ~0x3;
+ Descriptor->u.Port.MinimumAddress.LowPart = m;
+ } else {
+ m = i & ~0xf;
+ Descriptor->u.Memory.MinimumAddress.LowPart = m;
+ }
+
+ m += length; // max address is min address + length
+ }
+
+ //
+ // Add requested resource
+ //
+
+ Descriptor->Option = 0;
+ if (i & PCI_ADDRESS_IO_SPACE) {
+ memtype = 0;
+
+ if (PciOrigData->Command & PCI_ENABLE_IO_SPACE) {
+
+ //
+ // The IO range is/was already enabled at some location, add that
+ // as it's preferred setting.
+ //
+
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO;
+ Descriptor->Option = IO_RESOURCE_PREFERRED;
+
+ Descriptor->u.Port.Length = length;
+ Descriptor->u.Port.Alignment = length;
+ Descriptor->u.Port.MinimumAddress.LowPart = *OrigAddress[j] & ~0x3;
+ Descriptor->u.Port.MaximumAddress.LowPart =
+ Descriptor->u.Port.MinimumAddress.LowPart + length - 1;
+
+ CompleteList->List[0].Count++;
+ Descriptor++;
+
+ Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
+ }
+
+ //
+ // Add this IO range
+ //
+
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO;
+
+ Descriptor->u.Port.Length = length;
+ Descriptor->u.Port.Alignment = length;
+ Descriptor->u.Port.MaximumAddress.LowPart = m;
+
+ } else {
+
+ memtype = i & PCI_ADDRESS_MEMORY_TYPE_MASK;
+
+ Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+ if (j == RomIndex) {
+ // this is a ROM address
+ Descriptor->Flags = CM_RESOURCE_MEMORY_READ_ONLY;
+ }
+
+ if (i & PCI_ADDRESS_MEMORY_PREFETCHABLE) {
+ Descriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE;
+ }
+
+ if (!Is64BitBaseAddress(i) &&
+ (j == RomIndex ||
+ PciOrigData->Command & PCI_ENABLE_MEMORY_SPACE)) {
+
+ //
+ // The memory range is/was already enabled at some location, add that
+ // as it's preferred setting.
+ //
+
+ Descriptor->Type = CmResourceTypeMemory;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Option = IO_RESOURCE_PREFERRED;
+
+ Descriptor->u.Port.Length = length;
+ Descriptor->u.Port.Alignment = length;
+ Descriptor->u.Port.MinimumAddress.LowPart = *OrigAddress[j] & ~0xF;
+ Descriptor->u.Port.MaximumAddress.LowPart =
+ Descriptor->u.Port.MinimumAddress.LowPart + length - 1;
+
+ CompleteList->List[0].Count++;
+ Descriptor++;
+
+ Descriptor->Flags = Descriptor[-1].Flags;
+ Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
+ }
+
+ //
+ // Add this memory range
+ //
+
+ Descriptor->Type = CmResourceTypeMemory;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+
+ Descriptor->u.Memory.Length = length;
+ Descriptor->u.Memory.Alignment = length;
+ Descriptor->u.Memory.MaximumAddress.LowPart = m;
+
+ if (memtype == PCI_TYPE_20BIT && m > 0xFFFFF) {
+ // limit to 20 bit address
+ Descriptor->u.Memory.MaximumAddress.LowPart = 0xFFFFF;
+ }
+
+ if (Is64BitBaseAddress(i)) {
+ // skip upper half of 64 bit address since this processor
+ // only supports 32 bits of address space
+ j++;
+ }
+ }
+
+ CompleteList->List[0].Count++;
+ Descriptor++;
+
+ }
+ }
+
+ CompleteList->ListSize = (ULONG)
+ ((PUCHAR) Descriptor - (PUCHAR) CompleteList);
+
+ //
+ // Restore the device settings as we found them, enable memory
+ // and io decode after setting base addresses. This is done in
+ // case HalAdjustResourceList wants to read the current settings
+ // in the device.
+ //
+
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ &PciOrigData->Status,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Status),
+ PCI_COMMON_HDR_LENGTH - FIELD_OFFSET (PCI_COMMON_CONFIG, Status)
+ );
+
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ PciOrigData,
+ 0,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Status)
+ );
+
+ //
+ // Have the IO system allocate resource assignments
+ //
+
+ status = IoAssignResources (
+ RegistryPath,
+ DriverClassName,
+ DriverObject,
+ DeviceObject,
+ CompleteList,
+ pAllocatedResources
+ );
+
+ if (!NT_SUCCESS(status)) {
+ goto CleanUp;
+ }
+
+ //
+ // Slurp the assigments back into the PciData structure and
+ // perform them
+ //
+
+ CmDescriptor = (*pAllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
+
+ //
+ // If PCI device has an interrupt resource then that was
+ // passed in as the first requested resource
+ //
+
+ if (PciData->u.type0.InterruptPin) {
+ PciData->u.type0.InterruptLine = (UCHAR) CmDescriptor->u.Interrupt.Vector;
+ BusData->CommonData.Line2Pin (BusHandler, RootHandler, PciSlot, PciData, PciOrigData);
+ CmDescriptor++;
+ }
+
+ //
+ // Pull out resources in the order they were passed to IoAssignResources
+ //
+
+ m = 0;
+ for (j=0; j < NoBaseAddress; j++) {
+ i = *BaseAddress[j];
+ if (i) {
+ if (i & PCI_ADDRESS_IO_SPACE) {
+ m |= PCI_ENABLE_IO_SPACE;
+ *BaseAddress[j] = CmDescriptor->u.Port.Start.LowPart;
+ } else {
+ m |= PCI_ENABLE_MEMORY_SPACE;
+ *BaseAddress[j] = CmDescriptor->u.Memory.Start.LowPart;
+
+ if (Is64BitBaseAddress(i)) {
+ // skip upper 32 bits
+ j++;
+ }
+ }
+ CmDescriptor++;
+ }
+ }
+
+ //
+ // Set addresses, but do not turn on decodes
+ //
+
+ HalpWritePCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Read configuration back and verify address settings took
+ //
+
+ HalpReadPCIConfig(BusHandler, PciSlot, PciData2, 0, PCI_COMMON_HDR_LENGTH);
+
+ Match = TRUE;
+ if (PciData->u.type0.InterruptLine != PciData2->u.type0.InterruptLine ||
+ PciData->u.type0.InterruptPin != PciData2->u.type0.InterruptPin ||
+ PciData->u.type0.ROMBaseAddress != PciData2->u.type0.ROMBaseAddress) {
+ Match = FALSE;
+ }
+
+ for (j=0; j < NoBaseAddress; j++) {
+ if (*BaseAddress[j]) {
+ if (*BaseAddress[j] & PCI_ADDRESS_IO_SPACE) {
+ i = (ULONG) ~0x3;
+ } else {
+ i = (ULONG) ~0xF;
+ }
+
+ if ((*BaseAddress[j] & i) !=
+ *((PULONG) ((PUCHAR) BaseAddress[j] -
+ (PUCHAR) PciData +
+ (PUCHAR) PciData2)) & i) {
+
+ Match = FALSE;
+ }
+
+ if (!(*BaseAddress[j] & PCI_ADDRESS_IO_SPACE) &&
+ (Is64BitBaseAddress(*BaseAddress[j]))) {
+ // skip upper 32 bits
+ j++;
+ }
+ }
+ }
+
+ if (!Match) {
+#if DBG
+ DbgPrint ("PCI: defective device! Bus %d, Slot %d, Function %d\n",
+ BusNumber,
+ PciSlot.u.bits.DeviceNumber,
+ PciSlot.u.bits.FunctionNumber
+ );
+#endif
+ status = STATUS_DEVICE_PROTOCOL_ERROR;
+ goto CleanUp;
+ }
+
+ //
+ // Settings took - turn on the appropiate decodes
+ //
+
+ if (EnableRomBase && *BaseAddress[RomIndex]) {
+ // a rom address was allocated and should be enabled
+ *BaseAddress[RomIndex] |= PCI_ROMADDRESS_ENABLED;
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ BaseAddress[RomIndex],
+ (ULONG) ((PUCHAR) BaseAddress[RomIndex] - (PUCHAR) PciData),
+ sizeof (ULONG)
+ );
+ }
+
+ // enable IO & Memory decodes (use HalSetBusData since valid settings now set)
+
+ // Set Bus master bit on for win95 compatability
+ m |= PCI_ENABLE_BUS_MASTER;
+
+ PciData->Command |= (USHORT) m;
+ HalSetBusDataByOffset (
+ PCIConfiguration,
+ BusHandler->BusNumber,
+ PciSlot.u.AsULONG,
+ &PciData->Command,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Command),
+ sizeof (PciData->Command)
+ );
+
+CleanUp:
+ if (!NT_SUCCESS(status)) {
+
+ //
+ // Failure, if there are any allocated resources free them
+ //
+
+ if (*pAllocatedResources) {
+ IoAssignResources (
+ RegistryPath,
+ DriverClassName,
+ DriverObject,
+ DeviceObject,
+ NULL,
+ NULL
+ );
+
+ ExFreePool (*pAllocatedResources);
+ *pAllocatedResources = NULL;
+ }
+
+ //
+ // Restore the device settings as we found them, enable memory
+ // and io decode after setting base addresses
+ //
+
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ &PciOrigData->Status,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Status),
+ PCI_COMMON_HDR_LENGTH - FIELD_OFFSET (PCI_COMMON_CONFIG, Status)
+ );
+
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ PciOrigData,
+ 0,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Status)
+ );
+ }
+
+ ExFreePool (WorkingPool);
+ return status;
+}
+
+#if DBG
+VOID
+HalpTestPci (ULONG flag2)
+{
+ PCI_SLOT_NUMBER SlotNumber;
+ PCI_COMMON_CONFIG PciData, OrigData;
+ ULONG i, f, j, k, bus;
+ BOOLEAN flag;
+
+
+ if (!flag2) {
+ return ;
+ }
+
+ DbgBreakPoint ();
+ SlotNumber.u.bits.Reserved = 0;
+
+ //
+ // Read every possible PCI Device/Function and display it's
+ // default info.
+ //
+ // (note this destories it's current settings)
+ //
+
+ flag = TRUE;
+ for (bus = 0; flag; bus++) {
+
+ for (i = 0; i < PCI_MAX_DEVICES; i++) {
+ SlotNumber.u.bits.DeviceNumber = i;
+
+ for (f = 0; f < PCI_MAX_FUNCTION; f++) {
+ SlotNumber.u.bits.FunctionNumber = f;
+
+ //
+ // Note: This is reading the DeviceSpecific area of
+ // the device's configuration - normally this should
+ // only be done on device for which the caller understands.
+ // I'm doing it here only for debugging.
+ //
+
+ j = HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ if (j == 0) {
+ // out of buses
+ flag = FALSE;
+ break;
+ }
+
+ if (j < PCI_COMMON_HDR_LENGTH) {
+ continue;
+ }
+
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ 1
+ );
+
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+#if 0
+ memcpy (&OrigData, &PciData, sizeof PciData);
+
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ PciData.u.type0.BaseAddresses[j] = 0xFFFFFFFF;
+ }
+
+ PciData.u.type0.ROMBaseAddress = 0xFFFFFFFF;
+
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+#endif
+
+ DbgPrint ("PCI Bus %d Slot %2d %2d ID:%04lx-%04lx Rev:%04lx",
+ bus, i, f, PciData.VendorID, PciData.DeviceID,
+ PciData.RevisionID);
+
+
+ if (PciData.u.type0.InterruptPin) {
+ DbgPrint (" IntPin:%x", PciData.u.type0.InterruptPin);
+ }
+
+ if (PciData.u.type0.InterruptLine) {
+ DbgPrint (" IntLine:%x", PciData.u.type0.InterruptLine);
+ }
+
+ if (PciData.u.type0.ROMBaseAddress) {
+ DbgPrint (" ROM:%08lx", PciData.u.type0.ROMBaseAddress);
+ }
+
+ DbgPrint ("\n Cmd:%04x Status:%04x ProgIf:%04x SubClass:%04x BaseClass:%04lx\n",
+ PciData.Command, PciData.Status, PciData.ProgIf,
+ PciData.SubClass, PciData.BaseClass);
+
+ k = 0;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ if (PciData.u.type0.BaseAddresses[j]) {
+ DbgPrint (" Ad%d:%08lx", j, PciData.u.type0.BaseAddresses[j]);
+ k = 1;
+ }
+ }
+
+#if 0
+ if (PciData.u.type0.ROMBaseAddress == 0xC08001) {
+
+ PciData.u.type0.ROMBaseAddress = 0xC00001;
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ DbgPrint ("\n Bogus rom address, edit yields:%08lx",
+ PciData.u.type0.ROMBaseAddress);
+ }
+#endif
+
+ if (k) {
+ DbgPrint ("\n");
+ }
+
+ if (PciData.VendorID == 0x8086) {
+ // dump complete buffer
+ DbgPrint ("Command %x, Status %x, BIST %x\n",
+ PciData.Command, PciData.Status,
+ PciData.BIST
+ );
+
+ DbgPrint ("CacheLineSz %x, LatencyTimer %x",
+ PciData.CacheLineSize, PciData.LatencyTimer
+ );
+
+ for (j=0; j < 192; j++) {
+ if ((j & 0xf) == 0) {
+ DbgPrint ("\n%02x: ", j + 0x40);
+ }
+ DbgPrint ("%02x ", PciData.DeviceSpecific[j]);
+ }
+ DbgPrint ("\n");
+ }
+
+
+#if 0
+ //
+ // now print original data
+ //
+
+ if (OrigData.u.type0.ROMBaseAddress) {
+ DbgPrint (" oROM:%08lx", OrigData.u.type0.ROMBaseAddress);
+ }
+
+ DbgPrint ("\n");
+ k = 0;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ if (OrigData.u.type0.BaseAddresses[j]) {
+ DbgPrint (" oAd%d:%08lx", j, OrigData.u.type0.BaseAddresses[j]);
+ k = 1;
+ }
+ }
+
+ //
+ // Restore original settings
+ //
+
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &OrigData,
+ sizeof (PciData)
+ );
+#endif
+
+ //
+ // Next
+ //
+
+ if (k) {
+ DbgPrint ("\n\n");
+ }
+ }
+ }
+ }
+ DbgBreakPoint ();
+}
+#endif
diff --git a/private/ntos/nthals/halps/ppc/pxpciint.c b/private/ntos/nthals/halps/ppc/pxpciint.c
new file mode 100644
index 000000000..0160a0c96
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxpciint.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxpciint.c>
diff --git a/private/ntos/nthals/halps/ppc/pxpcisup.c b/private/ntos/nthals/halps/ppc/pxpcisup.c
new file mode 100644
index 000000000..abf5bc95f
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxpcisup.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxpcisup.c>
diff --git a/private/ntos/nthals/halps/ppc/pxport.c b/private/ntos/nthals/halps/ppc/pxport.c
new file mode 100644
index 000000000..d6ca10d1f
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxport.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxport.c>
diff --git a/private/ntos/nthals/halps/ppc/pxpower.s b/private/ntos/nthals/halps/ppc/pxpower.s
new file mode 100644
index 000000000..cb0822573
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxpower.s
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxpower.s>
diff --git a/private/ntos/nthals/halps/ppc/pxproc.c b/private/ntos/nthals/halps/ppc/pxproc.c
new file mode 100644
index 000000000..91b9dc338
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxproc.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxproc.c>
diff --git a/private/ntos/nthals/halps/ppc/pxprof.c b/private/ntos/nthals/halps/ppc/pxprof.c
new file mode 100644
index 000000000..e04f3f9bd
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxprof.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxprof.c>
diff --git a/private/ntos/nthals/halps/ppc/pxreset.s b/private/ntos/nthals/halps/ppc/pxreset.s
new file mode 100644
index 000000000..d328bf4a3
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxreset.s
@@ -0,0 +1,433 @@
+//++
+//
+// Copyright (C) 1993-1995 IBM Corporation
+//
+// Copyright (C) 1994-1995 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:
+//
+// pxreset.s
+//
+// Abstract:
+//
+// This module implements the routine HalpPowerPcReset, which can be
+// used to return the PowerPC to Big Endian with cache flushed and
+// branches to the rom based machine reset handler.
+//
+//
+// Environment:
+//
+// Kernel mode only.
+//
+//
+//--
+
+#include "kxppc.h"
+
+ .set C_LINE_SZ, 64
+ .set C_LINE_CNT, 64
+ .set C_SETS, 8
+
+ .set C_SIZE, C_LINE_SZ * C_LINE_CNT * C_SETS
+
+ .set HID0, 1008
+ .set DISABLES, MASK_SPR(MSR_DR,1) | MASK_SPR(MSR_IR,1)
+
+
+ .set H0_603_DCE, 0x4000 // 603 Data Cache Enable
+ .set H0_603_ICE, 0x8000 // 603 Instruction Cache Enable
+ .set H0_603_ICFI, 0x0800 // 603 I-Cache Flash Invalidate
+
+ .set H0_604_DCE, 0x4000 // 604 Data Cache Enable
+ .set H0_604_ICE, 0x8000 // 604 Instruction Cache Enable
+ .set H0_604_DCIA, 0x0400 // 604 I-Cache Invalidate All
+ .set H0_604_ICIA, 0x0800 // 604 I-Cache Invalidate All
+
+ .set TLB_CLASSES_601, 128 // 601 tlb has 128 congruence classes
+ .set TLB_CLASSES_603, 32 // 603 tlb has 32 congruence classes
+ .set TLB_CLASSES_604, 64 // 604 tlb has 64 congruence classes
+
+ LEAF_ENTRY(HalpPowerPcReset)
+ LWI(r.4, 0xfff00100) // address of rom reset handler
+ mfspr r.5, HID0
+ mfpvr r.31 // determine processor type
+ li r.6, 0
+ li r.7, 0x92
+ oris r.7, r.7, 0x8000
+ mfmsr r.8
+ rlwinm r.8, r.8, 0, ~MASK_SPR(MSR_EE,1) // disable interrupts
+ mtmsr r.8
+ cror 0,0,0 // N.B. 603e/ev Errata 15
+
+ //
+ // invalidate all tlb entries
+ //
+
+ li r.3, TLB_CLASSES_601 // use largest known number of
+ // congruence classes
+ mtctr r.3 // number of classes = iteration count
+zaptlb: tlbie r.3 // invalidate tlb congruence class
+ addi r.3, r.3, 4096 // increment to next class address
+ bdnz zaptlb // loop through all classes
+
+ srwi r.31, r.31, 16 // isolate processor type
+ cmpwi r.31, 1 // is 601?
+
+ bl here // get current address
+here:
+ mflr r.9 // (r.9) = &here
+ rlwinm r.9, r.9, 0, 0x7fffffff // convert address to physical
+
+ bne not_601
+
+ //
+ // processor is a 601
+ //
+
+ rlwinm r.5, r.5, 0, ~(0x0008) // turn off little endian
+
+ //
+ // disable instruction and data relocation and switch
+ // interrupt prefix to fetch from ROM
+ //
+
+ andi. r.8, r.8, ~DISABLES & 0xffff
+ ori r.8, r.8, MASK_SPR(MSR_IP,1)
+ mtsrr1 r.8 // this will also be target state
+ nop // for rfi
+
+//
+// Ensure all code from 'cachem' to 'end_little' is in cache by loading a
+// byte in each address line in that range.
+
+ addi r.9, r.9, cachem-here // (r.9) = physical &cachem
+
+ // r.9 now contains the physical address of cachem. (assuming
+ // this code was loaded as part of kernel which is loaded at
+ // physical 0 = virtual 0x80000000). We effect the switch to
+ // physical addressing thru an rfi with the target state set
+ // to resume at cachem with relocation and interrupts disabled.
+
+ mtsrr0 r.9 // address of cachem for rfi
+ addi r.10, r.9, end_little-cachem // (r.10) = &end_little
+ addi r.11, r.9, HalpPowerPcReset.end-cachem // (r.11) = &reset_end
+
+ addi r.12, r.9, -C_LINE_SZ // bias addr for 1st iteration by
+ // amount added by lbzu prior to load
+
+ rfi // switch
+cachem:
+ lbzu r.13, C_LINE_SZ(r.12) // get byte at (r.13)+C_LINE_SZ
+ cmplw r.12, r.10 // bumping r.12 by C_LINE_SZ
+ addi r.13, r.13, 1 // ensure load completed.
+ blt cachem // get all in range here-end_little.
+
+ mtsrr0 r.4 // set rom reset target for next rfi
+ lis r.9, 0x87f0 // Segment register base 0x87f00000
+ li r.10, 0xf // Set all 16 segment registers
+ li r.11, 0
+ mtibatl 0, r.6 // zero bat 0-3 upper and lower
+ mtibatu 0, r.6
+ mtibatl 1, r.6
+ mtibatu 1, r.6
+ mtibatl 2, r.6
+ mtibatu 2, r.6
+ mtibatl 3, r.6
+ mtibatu 3, r.6
+setsr: rlwimi r.11, r.10, 28, 0, 3 // Shift segment reg. # to bits 0-3
+ or r.12, r.9, r.10 // Segment register value 0x87f000sr
+ mtsrin r.12, r.11
+ addic. r.10, r.10, -1 // Next segment register
+ bne setsr
+ mtsr 0, r.9 // Set the last segment register
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ sync // quiet the machine down
+ sync
+ sync
+ sync
+ stb r.6, 0(r.7) // switch memory
+ eieio // flush io
+ sync
+ sync
+ sync
+ sync
+ mtspr HID0, r.5 // switch ends on the cpu
+ sync
+ sync
+ sync
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+
+ rfi // head off into the reset handler
+end_little:
+ addi r.0, r.1, 0x138 // we never get here
+ addi r.0, r.1, 0x138
+
+ b $
+
+//
+// For the 603 (and hopefully other) processor(s) things are a little
+// easier because little-endianness is controlled by the MSR. We still
+// have to change memory seperately so we still want code from the memory
+// switch thru the cpu switch in cache.
+//
+// When we get here
+// r.4 contains the address of the ROM resident Machine Reset
+// handler.
+// r.5 contains HID0 present value.
+// r.6 contains 0.
+// r.7 contains the port address (real) used to switch memory
+// endianness.
+// r.8 contains MSR present value.
+// r.9 contains the physical address of "here"
+// r.31 contains the processor type
+
+
+not_601:
+ cmpwi r.31, 3 // is 603?
+ beq is_603
+ cmpwi r.31, 6 // is 603+?
+ beq is_603
+ cmpwi r.31, 7 // is 603ev?
+ beq is_603
+
+ cmpwi cr.2, r.31, 4 // is 604?
+ cmpwi cr.3, r.31, 9 // is 604+?
+ b not_603
+
+//
+// 603 I-Cache is invalidated by setting ICFI in HID0. Unlike
+// the 604, this bit is not self clearing.
+//
+
+is_603: rlwinm r.5, r.5, 0, ~H0_603_DCE// turn off D-cache
+ rlwinm r.10, r.5, 0, ~H0_603_ICE// turn off I-cache
+ ori r.10, r.10, H0_603_ICFI // I-Cache Flash Invalidate
+ ori r.5, r.5, H0_603_ICE // I-cache enable
+ isync
+ mtspr HID0, r.10 // invalidate/disable
+ mtspr HID0, r.5 // enable
+ b common_6034
+
+not_603:
+ beq cr.2, is_604
+// bne not_604
+
+// Note: the above branch is commented out because we don't
+// currently have any other options,... 620 will probably
+// be different.
+
+
+is_604: tlbsync // wait all processor tlb invalidate
+
+//
+// 604 caches must be enabled in order to be invalidated. It
+// is acceptable to enable and invalidate with the same move
+// to hid0. The data cache will be left disabled, the instruction
+// cache enabled.
+//
+
+ ori r.5, r.5, H0_604_DCE | H0_604_ICE
+ ori r.10, r.5, H0_604_DCIA | H0_604_ICIA
+
+ rlwinm r.5, r.5, 0, ~H0_604_DCE
+ rlwinm r.5, r.5, 0, ~H0_604_DCIA
+ rlwinm r.5, r.5, 0, ~H0_604_ICIA
+
+ mtspr HID0, r.10 // enable + invalidate
+ mtspr HID0, r.5 // disable data cache
+
+ rlwinm r.10, r.5, 0, ~H0_604_ICE // disable i-cache later
+
+// b common_6034 // join common code
+
+
+//
+// The following is common to both 603 and 604
+//
+
+common_6034:
+
+//
+// MSR bits ILE and POW must be disabled via mtmsr as rfi only moves
+// the least significant 16 bits into the MSR.
+//
+
+ rlwinm r.8, r.8, 0, ~MASK_SPR(MSR_DR,1) // -= Data Relocation
+ rlwinm r.8, r.8, 0, ~MASK_SPR(MSR_POW,1) // -= Power Management
+ rlwinm r.8, r.8, 0, ~MASK_SPR(MSR_ILE,1) // -= Interrupt Little Endian
+ sync
+ mtmsr r.8
+ sync
+
+//
+// Try to issue a hard reset. If this fails, the fall
+// thru and continue to manually return to firmware.
+//
+
+ addi r.5, r.0, 0xFF // All ones
+ stb r.5, 0(r.7) // Reset the System
+ sync
+ sync
+ sync
+ sync
+
+//
+// Continue returning to firmware...
+//
+
+//
+// Use an rfi to switch to big-endian, untranslated, interrupt prefix on
+// with a target address in the nice harmless pallindromic code below.
+// use another rfi to branch to the rom resident reset handler.
+//
+
+ li r.8, MASK_SPR(MSR_ME,1) | MASK_SPR(MSR_IP,1)
+ addi r.9, r.9, uncached_6034-here
+ mtsrr1 r.8 // state = Machine Check Enabled
+ bl here2
+here2: mflr r.28
+ rlwinm r.28, r.28, 0, 0x7fffffff // convert address to physical
+ lwz r.29, endofroutine - here2(r.28)
+ mtsrr0 r.9 // rfi to uncached_6034
+ b jumpswap
+
+memoryswap:
+ ori r.8, r.28, 0
+ addi r.8, r.8, swapend - uncached_6034
+ addis r.15, r.15, 0
+ addi r.9, 0, 0
+ addi r.15, r.15, swapend - uncached_6034
+ addis r.14, 0, 0
+ addi r.14, 0, 4
+swaploop:
+ lwz r.11, 0(r.8)
+ lwz r.12, 4(r.8)
+ stwbrx r.11, r.14, r.8
+ stwbrx r.12, 0, r.8
+ addi r.8, r.8, 8
+ subi r.15, r.15, 8
+ cmpi 0, 0, r.15, 0
+ bgt swaploop
+
+jumpswap:
+
+//
+// The following bizzareness is to ensure that the memory switch thru
+// the disabling of cache is in cache. There is less than 32 bytes so
+// they must be part of either the cache line we are currently in, or
+// the one at the target of the branch. Therefore, branching over them,
+// doing a little and branching back to them should be enough to enure
+// they're cache resident.
+//
+
+ b fill_icache
+goto_bigendian:
+ stb r.6, 0(r.7) // switch memory
+ sync
+ sync
+ sync
+ sync
+ sync
+ lwz r.30, endofroutine - here2(r.28)
+ cmp 0, 0, r.29, r.30
+ beq memoryswap
+ rfi
+fill_icache:
+ isync
+ sync // complete everything!
+ b goto_bigendian
+
+ .align 5
+ .globl uncached_6034
+ .long uncached_6034
+
+uncached_6034:
+ .big_endian // out of cache fetches must be
+ // assembled in same mode as processor
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ addi r.0, r.1, 0x138 // same both ways
+ mtsrr0 r.4 // rfi target = 0xfff00100
+ mtspr HID0, r.10 // DISABLE CACHING
+ mtibatl 0, r.6 // invalidate/clear all bats
+ mtibatu 0, r.6
+ mtibatl 1, r.6
+ mtibatu 1, r.6
+ mtibatl 2, r.6
+ mtibatu 2, r.6
+ mtibatl 3, r.6
+ mtibatu 3, r.6
+ mtdbatl 0, r.6
+ mtdbatu 0, r.6
+ mtdbatl 1, r.6
+ mtdbatu 1, r.6
+ mtdbatl 2, r.6
+ mtdbatu 2, r.6
+ mtdbatl 3, r.6
+ mtdbatu 3, r.6
+ mtsr 0, r.6
+ mtsr 1, r.6
+ mtsr 2, r.6
+ mtsr 3, r.6
+ mtsr 4, r.6
+ mtsr 5, r.6
+ mtsr 6, r.6
+ mtsr 7, r.6
+ mtsr 8, r.6
+ mtsr 9, r.6
+ mtsr 10, r.6
+ mtsr 11, r.6
+ mtsr 12, r.6
+ mtsr 13, r.6
+ mtsr 14, r.6
+ mtsr 15, r.6
+ rfi // go to machine reset handler
+ // never get here
+ .little_endian
+endofroutine:
+ sync
+ .globl swapend
+ .long swapend
+swapend:
+
+ LEAF_EXIT(HalpPowerPcReset)
diff --git a/private/ntos/nthals/halps/ppc/pxreturn.c b/private/ntos/nthals/halps/ppc/pxreturn.c
new file mode 100644
index 000000000..812168de2
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxreturn.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxreturn.c>
diff --git a/private/ntos/nthals/halps/ppc/pxsiosup.c b/private/ntos/nthals/halps/ppc/pxsiosup.c
new file mode 100644
index 000000000..ab763410f
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxsiosup.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxsiosup.c>
diff --git a/private/ntos/nthals/halps/ppc/pxstall.s b/private/ntos/nthals/halps/ppc/pxstall.s
new file mode 100644
index 000000000..b22d5550b
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxstall.s
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxstall.s>
diff --git a/private/ntos/nthals/halps/ppc/pxsysbus.c b/private/ntos/nthals/halps/ppc/pxsysbus.c
new file mode 100644
index 000000000..c3d901bd9
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxsysbus.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxsysbus.c>
diff --git a/private/ntos/nthals/halps/ppc/pxsysint.c b/private/ntos/nthals/halps/ppc/pxsysint.c
new file mode 100644
index 000000000..4c2e8240d
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxsysint.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxsysint.c>
diff --git a/private/ntos/nthals/halps/ppc/pxsystyp.c b/private/ntos/nthals/halps/ppc/pxsystyp.c
new file mode 100644
index 000000000..d80b78b0e
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxsystyp.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxsystyp.c>
diff --git a/private/ntos/nthals/halps/ppc/pxtime.c b/private/ntos/nthals/halps/ppc/pxtime.c
new file mode 100644
index 000000000..fed4558b9
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxtime.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxtime.c>
diff --git a/private/ntos/nthals/halps/ppc/pxusage.c b/private/ntos/nthals/halps/ppc/pxusage.c
new file mode 100644
index 000000000..1c856c8e5
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/pxusage.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\pxusage.c>
diff --git a/private/ntos/nthals/halps/ppc/sysbios.c b/private/ntos/nthals/halps/ppc/sysbios.c
new file mode 100644
index 000000000..9838c5a93
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/sysbios.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\sysbios.c>
diff --git a/private/ntos/nthals/halps/ppc/x86bios.c b/private/ntos/nthals/halps/ppc/x86bios.c
new file mode 100644
index 000000000..62067325c
--- /dev/null
+++ b/private/ntos/nthals/halps/ppc/x86bios.c
@@ -0,0 +1 @@
+#include <..\..\haleagle\ppc\x86bios.c>