summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/hallego/alpha
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/hallego/alpha
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/hallego/alpha')
-rw-r--r--private/ntos/nthals/hallego/alpha/addrsup.c590
-rw-r--r--private/ntos/nthals/hallego/alpha/adjust.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/allstart.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/alphaio.s7
-rw-r--r--private/ntos/nthals/hallego/alpha/apecs.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/apecserr.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/apecsio.s7
-rw-r--r--private/ntos/nthals/hallego/alpha/bios.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/busdata.c129
-rw-r--r--private/ntos/nthals/hallego/alpha/cache.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/chipset.h1
-rw-r--r--private/ntos/nthals/hallego/alpha/cmos8k.c2
-rw-r--r--private/ntos/nthals/hallego/alpha/ebsgdma.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/eisasup.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/ev4cache.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/ev4int.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/ev4ints.s6
-rw-r--r--private/ntos/nthals/hallego/alpha/ev4mchk.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/ev4mem.s7
-rw-r--r--private/ntos/nthals/hallego/alpha/ev4prof.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/fwreturn.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/haldebug.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/halpal.s7
-rw-r--r--private/ntos/nthals/hallego/alpha/idle.s7
-rw-r--r--private/ntos/nthals/hallego/alpha/info.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/inithal.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/intsup.s7
-rw-r--r--private/ntos/nthals/hallego/alpha/ioproc.c74
-rw-r--r--private/ntos/nthals/hallego/alpha/iousage.c647
-rw-r--r--private/ntos/nthals/hallego/alpha/iousage.h107
-rw-r--r--private/ntos/nthals/hallego/alpha/legodef.h671
-rw-r--r--private/ntos/nthals/hallego/alpha/lginitnt.c1409
-rw-r--r--private/ntos/nthals/hallego/alpha/lgintr.s121
-rw-r--r--private/ntos/nthals/hallego/alpha/lgintsup.c732
-rw-r--r--private/ntos/nthals/hallego/alpha/lgmapio.c232
-rw-r--r--private/ntos/nthals/hallego/alpha/lgsysint.c679
-rw-r--r--private/ntos/nthals/hallego/alpha/machdep.h46
-rw-r--r--private/ntos/nthals/hallego/alpha/memory.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/nvenv.c1
-rw-r--r--private/ntos/nthals/hallego/alpha/nvram.c1
-rw-r--r--private/ntos/nthals/hallego/alpha/pcd8584.c653
-rw-r--r--private/ntos/nthals/hallego/alpha/pcd8584.h196
-rw-r--r--private/ntos/nthals/hallego/alpha/pcf8574.c336
-rw-r--r--private/ntos/nthals/hallego/alpha/pcf8574.h175
-rw-r--r--private/ntos/nthals/hallego/alpha/pcibus.c111
-rw-r--r--private/ntos/nthals/hallego/alpha/pciir.c646
-rw-r--r--private/ntos/nthals/hallego/alpha/pcisio.c587
-rw-r--r--private/ntos/nthals/hallego/alpha/pcisup.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/pcrtc.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/pcserial.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/pcspeakr.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/perfcntr.c7
-rw-r--r--private/ntos/nthals/hallego/alpha/pintolin.h273
-rw-r--r--private/ntos/nthals/hallego/alpha/smerr.c390
-rw-r--r--private/ntos/nthals/hallego/alpha/smir.c722
-rw-r--r--private/ntos/nthals/hallego/alpha/smsup.c363
-rw-r--r--private/ntos/nthals/hallego/alpha/vga.c7
57 files changed, 10103 insertions, 0 deletions
diff --git a/private/ntos/nthals/hallego/alpha/addrsup.c b/private/ntos/nthals/hallego/alpha/addrsup.c
new file mode 100644
index 000000000..2a7deb1f6
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/addrsup.c
@@ -0,0 +1,590 @@
+/*++
+
+Copyright (c) 1993 Digital Equipment Corporation
+
+Module Name:
+
+ addrsup.c
+
+Abstract:
+
+ This module contains the platform dependent code to create bus addreses
+ and QVAs for the Avanti system.
+
+Author:
+
+ Joe Notarangelo 22-Oct-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ Eric Rehm (Digital) 03-Jan-1994
+ Added PCIBus(0) and dense space support to all routines.
+
+ Gene Morgan (Digital) 11-Oct-1995
+ Initial LEGO version -- adapted from Avanti
+
+--*/
+
+#include "halp.h"
+#include "eisa.h"
+#include "legodef.h"
+
+typedef PVOID QUASI_VIRTUAL_ADDRESS;
+
+QUASI_VIRTUAL_ADDRESS
+HalCreateQva(
+ IN PHYSICAL_ADDRESS PA,
+ IN PVOID VA
+ );
+
+
+BOOLEAN
+HalpTranslateSystemBusAddress(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ )
+
+
+/*++
+
+Routine Description:
+
+ This function returns the system physical address for a specified I/O bus
+ address. The return value is suitable for use in a subsequent call to
+ MmMapIoSpace.
+
+Arguments:
+
+ BusHandler - Registered BUSHANDLER for the target configuration space
+ Supplies the bus handler (bus no, interface type).
+
+ RootHandler - Registered BUSHANDLER for the orginating
+ HalTranslateBusAddress request.
+
+ BusAddress - Supplies the bus relative address.
+
+ AddressSpace - Supplies the address space number for the device: 0 for
+ memory and 1 for I/O space. If the desired access mode is user mode,
+ then bit 1 must be TRUE.
+
+ TranslatedAddress - Supplies a pointer to return the translated address
+
+
+Notes:
+
+ This is a variation of what began in the MIPS code. The intel code often
+ assumes that if an address is in I/O space, the bottom 32 bits of the
+ physical address can be used "like" a virtual address, and are returned
+ to the user. This doesn't work on MIPs machines where physical
+ addresses can be larger than 32 bits.
+
+ Since we are using superpage addresses for I/O on Alpha, we can do
+ almost what is done on intel. If AddressSpace is equal to 0 or 1, then
+ we assume the user is doing kernel I/O and we call
+ HalCreateQva to build a Quasi Virtual Address and return
+ that to the caller. We then set AddressSpace to a 1, so that the caller
+ will not call MmMapIoSpace. The Caller will use the low 32 bits of the
+ physical address we return as the VA. (Which we built a QVA in).
+ If the caller wants to access EISA I/O or Memory through user mode, then
+ the caller must set bit 1 in AddressSpace to a 1 (AddressSpace=2 or 3,
+ depending on whether EISA I/O or Memory), then the caller is returned the
+ 34 bit Physical address. The caller will then call MmMapIoSpace, or
+ ZwMapViewOfSection which in turn calls HalCreateQva to build a QVA out
+ of a VA mapped through the page tables.
+
+ **** Note ****
+
+ The QVA in user mode can only be used via the user-mode access macros.
+
+
+
+Return Value:
+
+ A return value of TRUE indicates that a system physical address
+ corresponding to the supplied bus relative address and bus address
+ number has been returned in TranslatedAddress.
+
+ A return value of FALSE occurs if the translation for the address was
+ not possible
+
+--*/
+
+{
+ INTERFACE_TYPE InterfaceType = BusHandler->InterfaceType;
+ ULONG BusNumber = BusHandler->BusNumber;
+
+ PVOID va = 0; // note, this is used for a placeholder
+
+ //
+ // The only buses available on Avanti are an ISA bus and a PCI bus.
+ // We support any translations for EISA devices as well, though
+ // if they are true EISA devices they won't even be able to plug into
+ // the connectors!
+ //
+
+ if (InterfaceType != Isa &&
+ InterfaceType != Eisa &&
+ InterfaceType != PCIBus) {
+
+ //
+ // Not on this system return nothing.
+ //
+
+ *AddressSpace = 0;
+ TranslatedAddress->LowPart = 0;
+ return(FALSE);
+ }
+
+ //
+ // Determine the address based on whether the bus address is in I/O space
+ // or bus memory space.
+ //
+
+ switch ( (ADDRESS_SPACE_TYPE)(*AddressSpace) ) {
+
+ case BusMemory: {
+
+ //
+ // The address is in PCI memory space, kernel mode.
+ //
+
+ switch( InterfaceType ) {
+
+ case Isa: {
+
+ //
+ // Can't go above 16MB (24 Bits) for Isa Buses
+ //
+ if( BusAddress.LowPart >= __16MB ){
+
+ *AddressSpace = 0;
+ TranslatedAddress->LowPart = 0;
+ return(FALSE);
+
+ }
+
+ break;
+
+ } // case Isa
+
+ case PCIBus: {
+
+ if ( BusAddress.LowPart > PCI_MAX_DENSE_MEMORY_ADDRESS ) {
+
+ //
+ // Unsupported dense PCI bus address.
+ //
+#if HALDBG
+ DbgPrint ("Unsupported PCI address %x:%x\n",
+ BusAddress.HighPart,
+ BusAddress.LowPart);
+#endif
+ *AddressSpace = 0;
+ TranslatedAddress->LowPart = 0;
+ return(FALSE);
+ }
+ else if( BusAddress.LowPart >= PCI_MIN_DENSE_MEMORY_ADDRESS &&
+ BusAddress.LowPart <= PCI_MAX_DENSE_MEMORY_ADDRESS ) {
+
+#if HALDBG
+ DbgPrint ("Translating PCI kernel dense address %x:%x\n",
+ BusAddress.HighPart,
+ BusAddress.LowPart);
+#endif
+ //
+ // Bus Address is in dense PCI memory space
+ //
+
+ //
+ // QVA, as such, is simply the PCI bus address
+ //
+
+ TranslatedAddress->LowPart = BusAddress.LowPart;
+
+ //
+ // clear high longword for QVA
+ //
+
+ TranslatedAddress->HighPart = 0;
+
+ //
+ // dont let the user call MmMapIoSpace
+ //
+
+ *AddressSpace = 1;
+
+ return (TRUE);
+
+
+ }
+
+ //
+ // Bus Address is in sparse PCI memory space
+ //
+
+
+#if HALDBG
+ DbgPrint ("Translating PCI kernel sparse address %x:%x\n",
+ BusAddress.HighPart,
+ BusAddress.LowPart);
+#endif
+
+ break;
+ } // case PCIBus
+
+ case Eisa: {
+ break;
+ } // case Eisa
+
+ } // switch( InterfaceType )
+
+ //
+ // Start with the base physical address and add the
+ // bus address by converting it to the physical address.
+ //
+
+ TranslatedAddress->QuadPart = APECS_PCI_MEMORY_BASE_PHYSICAL;
+ TranslatedAddress->QuadPart += ((ULONGLONG)BusAddress.LowPart << IO_BIT_SHIFT);
+
+ //
+ // Now call HalCreateQva. This will create a QVA
+ // that we'll return to the caller. Then we will implicitly set
+ // AddressSpace to a 1. The caller then will not call MmMapIoSpace
+ // and will use the address we return as a VA.
+ //
+
+ TranslatedAddress->LowPart =
+ (ULONG) HalCreateQva( *TranslatedAddress, va);
+
+ //
+ // clear high longword for QVA
+ //
+
+ TranslatedAddress->HighPart = 0;
+
+ //
+ // don't let the user call MmMapIoSpace
+ //
+
+ *AddressSpace = 1;
+
+ return(TRUE);
+
+ } // case BusMemory
+
+
+ case BusIo: {
+
+ //
+ // The address is in PCI I/O space, kernel mode.
+ //
+
+ switch( InterfaceType ) {
+
+ case Isa: {
+ //
+ // Can't go above 64KB (16 Bits) for Isa Buses
+ //
+ if( BusAddress.LowPart >= __64K ){
+
+ *AddressSpace = 0;
+ TranslatedAddress->LowPart = 0;
+ return(FALSE);
+
+ }
+ break;
+ } // case Isa
+
+ case PCIBus: {
+
+ //
+ // PCI IO space is always below 16MB (24 Bits) BusAddress
+ // If the address cannot be mapped, just return FALSE.
+ //
+ // IMPORTANT: For now we have set HAXR2 to 0(see ebinitnt.c)
+ //
+ if( BusAddress.LowPart >= __16MB ){
+
+ *AddressSpace = 0;
+ TranslatedAddress->LowPart = 0;
+ return(FALSE);
+
+ }
+ //
+ // if the BusAddress.LowPart is > 64K then we use the HAXR2
+ // register.
+ //
+ break;
+ } // case PCIBus
+
+ case Eisa: {
+ break;
+ } // case Eisa
+
+ } // switch( InterfaceType )
+
+
+ //
+ // Start with the base physical address and add the
+ // bus address by converting it to the physical address.
+ //
+
+ TranslatedAddress->QuadPart = APECS_PCI_IO_BASE_PHYSICAL;
+ TranslatedAddress->QuadPart += ((ULONGLONG)BusAddress.LowPart << IO_BIT_SHIFT);
+
+ //
+ // Now call HalCreateQva. This will create a QVA
+ // that we'll return to the caller. Then we will implicitly set
+ // AddressSpace to a 1. The caller then will not call MmMapIoSpace
+ // and will use the address we return as a VA.
+
+ TranslatedAddress->LowPart = (ULONG) HalCreateQva( *TranslatedAddress,
+ va);
+
+ TranslatedAddress->HighPart = 0; // clear high longword for QVA
+
+ *AddressSpace = 1; // Make sure user doesn't call
+ // MmMapIoSpace.
+
+ return(TRUE);
+
+ } // case BusIo
+
+ case UserBusMemory: {
+
+ //
+ // The address is in PCI memory space, user mode.
+ //
+
+ //
+ // Start with the base physical address and add the
+ // bus address by converting it to the physical address.
+ //
+
+ TranslatedAddress->QuadPart = APECS_PCI_MEMORY_BASE_PHYSICAL;
+ TranslatedAddress->QuadPart += ((ULONGLONG)BusAddress.LowPart << IO_BIT_SHIFT);
+
+ *AddressSpace = 0; // Let the user call MmMapIoSpace
+
+ return(TRUE);
+
+ }
+
+ case UserBusIo: {
+
+ //
+ // The address is in PCI I/O space, user mode.
+ //
+
+ //
+ // Start with the base physical address and add the
+ // bus address by converting it to the physical address.
+ //
+
+ TranslatedAddress->QuadPart = APECS_PCI_IO_BASE_PHYSICAL;
+ TranslatedAddress->QuadPart += ((ULONGLONG)BusAddress.LowPart << IO_BIT_SHIFT);
+
+ *AddressSpace = 0; // Make sure user can call
+ // MmMapIoSpace.
+
+ return(TRUE);
+
+ }
+
+
+ case KernelPciDenseMemory:
+ case UserPciDenseMemory:
+ {
+
+ //
+ // The address is in PCI memory space, user mode.
+ // Note that ISA and EISA buses can also request this space
+ //
+
+ //
+ // Start with the base physical address and add the
+ // bus address by converting it to the physical address.
+ //
+
+ TranslatedAddress->QuadPart = APECS_PCI_DENSE_BASE_PHYSICAL;
+ TranslatedAddress->QuadPart += BusAddress.LowPart;
+
+ *AddressSpace = 0; // Let the user call MmMapIoSpace
+
+ return(TRUE);
+
+ }
+
+ default: {
+
+ //
+ // Unsupported address space.
+
+ *AddressSpace = 0;
+ TranslatedAddress->LowPart = 0;
+ return(FALSE);
+
+ }
+
+
+ }
+}
+
+PVOID
+HalCreateQva(
+ IN PHYSICAL_ADDRESS PA,
+ IN PVOID VA
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called two ways. First, from HalTranslateBusAddress,
+ if the caller is going to run in kernel mode and use superpages.
+ The second way is if the user is going to access in user mode.
+ MmMapIoSpace or ZwViewMapOfSection will call this.
+
+ If the input parameter VA is zero, then we assume super page and build
+ a QUASI virtual address that is only usable by calling the hal I/O
+ access routines.
+
+ if the input parameter VA is non-zero, we assume the user has either
+ called MmMapIoSpace or ZwMapViewOfSection and will use the user mode
+ access macros.
+
+ If the PA is not a sparse I/O space address (PCI I/O, PCI Memory),
+ then return the VA as the QVA.
+
+Arguments:
+
+ PA - the physical address generated by HalTranslateBusAddress
+
+ VA - the virtual address returned by MmMapIoSpace
+
+Return Value:
+
+ The returned value is a quasi virtual address in that it can be
+ added to and subtracted from, but it cannot be used to access the
+ bus directly. The top bits are set so that we can trap invalid
+ accesses in the memory management subsystem. All access should be
+ done through the Hal Access Routines in *ioacc.s if it was a superpage
+ kernel mode access. If it is usermode, then the user mode access
+ macros must be used.
+
+--*/
+{
+
+ PVOID qva;
+
+ if( (PA.QuadPart >= APECS_COMANCHE_BASE_PHYSICAL)
+ && (PA.QuadPart < APECS_PCI_DENSE_BASE_PHYSICAL)
+ )
+ {
+
+ //
+ // The physical address is within one of the sparse I/O spaces.
+ //
+
+ if (VA == 0) {
+
+ qva = (PVOID)(PA.QuadPart >> IO_BIT_SHIFT);
+
+ } else {
+
+ qva = (PVOID)((ULONG)VA >> IO_BIT_SHIFT);
+ }
+
+ qva = (PVOID)((ULONG)qva | QVA_ENABLE);
+
+ return(qva);
+ }
+
+ //
+ // It is not a sparse I/O space address, return the VA as the QVA
+ //
+
+ return(VA);
+
+}
+
+PVOID
+HalDereferenceQva(
+ PVOID Qva,
+ INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber
+ )
+/*++
+
+Routine Description:
+
+ This function performs the inverse of the HalCreateQva for I/O addresses
+ that are memory-mapped (i.e. the quasi-virtual address was created from
+ a virtual address rather than a physical address).
+
+Arguments:
+
+ Qva - Supplies the quasi-virtual address to be converted back to a
+ virtual address.
+
+ InterfaceType - Supplies the interface type of the bus to which the
+ Qva pertains.
+
+ BusNumber - Supplies the bus number of the bus to which the Qva pertains.
+
+Return Value:
+
+ The Virtual Address from which the quasi-address was originally created
+ is returned.
+
+--*/
+{
+
+
+ //
+ // For Lego we have only bus types:
+ //
+ // Isa
+ // PCIBus
+ //
+ // We will allow Eisa as an alias for Isa. All other values not named
+ // above will be considered bogus.
+ //
+
+ switch (InterfaceType ){
+
+ case Isa:
+ case Eisa:
+ case PCIBus:
+
+ //
+ // Support dense space: check to see if it's really
+ // a sparse space QVA.
+ //
+
+ if ( ((ULONG) Qva & QVA_SELECTORS) == QVA_ENABLE )
+ {
+ return( (PVOID)( (ULONG)Qva << IO_BIT_SHIFT ) );
+ }
+ else
+ {
+ return (Qva);
+ }
+ break;
+
+
+ default:
+
+ return NULL;
+
+ }
+
+
+}
diff --git a/private/ntos/nthals/hallego/alpha/adjust.c b/private/ntos/nthals/hallego/alpha/adjust.c
new file mode 100644
index 000000000..47c267fb8
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/adjust.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\adjust.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/allstart.c b/private/ntos/nthals/hallego/alpha/allstart.c
new file mode 100644
index 000000000..42f70b7ca
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/allstart.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\allstart.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/alphaio.s b/private/ntos/nthals/hallego/alpha/alphaio.s
new file mode 100644
index 000000000..d2fe61a53
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/alphaio.s
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\alphaio.s"
+
diff --git a/private/ntos/nthals/hallego/alpha/apecs.c b/private/ntos/nthals/hallego/alpha/apecs.c
new file mode 100644
index 000000000..06eb91348
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/apecs.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\apecs.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/apecserr.c b/private/ntos/nthals/hallego/alpha/apecserr.c
new file mode 100644
index 000000000..441154cc9
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/apecserr.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\apecserr.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/apecsio.s b/private/ntos/nthals/hallego/alpha/apecsio.s
new file mode 100644
index 000000000..27bb7caa7
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/apecsio.s
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\apecsio.s"
+
diff --git a/private/ntos/nthals/hallego/alpha/bios.c b/private/ntos/nthals/hallego/alpha/bios.c
new file mode 100644
index 000000000..3a9d3aa50
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/bios.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\bios.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/busdata.c b/private/ntos/nthals/hallego/alpha/busdata.c
new file mode 100644
index 000000000..b04915a0e
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/busdata.c
@@ -0,0 +1,129 @@
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+Copyright (c) 1994 Digital Equipment Corporation
+
+Module Name:
+
+ busdata.c
+
+Abstract:
+
+ This module contains get/set bus data routines.
+
+Author:
+
+ Darryl E. Havens (darrylh) 11-Apr-1990
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ Gene Morgan [Digital] 11-Oct-1995
+
+ Initial version for Lego. Adapted from Avanti.
+
+
+--*/
+
+#include "halp.h"
+
+//
+// External Function Prototypes
+//
+
+ULONG
+HalpNoBusData (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpRegisterInternalBusHandlers)
+#endif
+
+
+VOID
+HalpRegisterInternalBusHandlers (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This function registers the bushandlers for buses on the system
+ that will always be present on the system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PBUS_HANDLER Bus;
+
+ //
+ // Initalize BusHandler data before registering any handlers
+ //
+
+ HalpInitBusHandler ();
+
+ //
+ // Build the processor internal bus 0
+ //
+
+ HaliRegisterBusHandler (ProcessorInternal, // Bus Type
+ -1, // No config space
+ 0, // Bus Number
+ -1, // No parent bus type
+ 0, // No parent bus number
+ 0, // No extension data
+ NULL, // No install handler
+ &Bus); // Bushandler return
+
+ Bus->GetInterruptVector = HalpGetSystemInterruptVector;
+
+ //
+ // Build internal-bus 0, or system level bus
+ //
+
+ HaliRegisterBusHandler (Internal, // Bus Type
+ -1, // No config space
+ 0, // Bus Number
+ -1, // No parent bus type
+ 0, // No parent bus number
+ 0, // No extension data
+ NULL, // No install handler
+ &Bus); // Bushandler return
+
+ Bus->GetInterruptVector = HalpGetSystemInterruptVector;
+ Bus->TranslateBusAddress = HalpTranslateSystemBusAddress;
+
+ //
+ // Build Isa bus #0
+ //
+
+ HaliRegisterBusHandler (Isa, // Bus Type
+ -1, // No config space
+ 0, // Internal bus #0
+ Internal, // Parent bus type
+ 0, // Parent bus number
+ 0, // No extension data
+ NULL, // No install handler
+ &Bus); // Bushandler return
+
+ Bus->GetBusData = HalpNoBusData;
+ Bus->AdjustResourceList = HalpAdjustIsaResourceList;
+
+}
diff --git a/private/ntos/nthals/hallego/alpha/cache.c b/private/ntos/nthals/hallego/alpha/cache.c
new file mode 100644
index 000000000..561528477
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/cache.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\cache.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/chipset.h b/private/ntos/nthals/hallego/alpha/chipset.h
new file mode 100644
index 000000000..0a72ef8cb
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/chipset.h
@@ -0,0 +1 @@
+#include "apecs.h"
diff --git a/private/ntos/nthals/hallego/alpha/cmos8k.c b/private/ntos/nthals/hallego/alpha/cmos8k.c
new file mode 100644
index 000000000..483709b57
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/cmos8k.c
@@ -0,0 +1,2 @@
+#include "..\halalpha\cmos8k.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/ebsgdma.c b/private/ntos/nthals/hallego/alpha/ebsgdma.c
new file mode 100644
index 000000000..f2f033fad
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/ebsgdma.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\ebsgdma.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/eisasup.c b/private/ntos/nthals/hallego/alpha/eisasup.c
new file mode 100644
index 000000000..0d46ef3e4
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/eisasup.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\eisasup.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/ev4cache.c b/private/ntos/nthals/hallego/alpha/ev4cache.c
new file mode 100644
index 000000000..b0cf9e3be
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/ev4cache.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\ev4cache.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/ev4int.c b/private/ntos/nthals/hallego/alpha/ev4int.c
new file mode 100644
index 000000000..8a10705d7
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/ev4int.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\ev4int.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/ev4ints.s b/private/ntos/nthals/hallego/alpha/ev4ints.s
new file mode 100644
index 000000000..6df823ab6
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/ev4ints.s
@@ -0,0 +1,6 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+#include "..\halalpha\ev4ints.s"
+
diff --git a/private/ntos/nthals/hallego/alpha/ev4mchk.c b/private/ntos/nthals/hallego/alpha/ev4mchk.c
new file mode 100644
index 000000000..697087c15
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/ev4mchk.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\ev4mchk.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/ev4mem.s b/private/ntos/nthals/hallego/alpha/ev4mem.s
new file mode 100644
index 000000000..f410d09a3
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/ev4mem.s
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\ev4mem.s"
+
diff --git a/private/ntos/nthals/hallego/alpha/ev4prof.c b/private/ntos/nthals/hallego/alpha/ev4prof.c
new file mode 100644
index 000000000..7ecdfa8b7
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/ev4prof.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\ev4prof.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/fwreturn.c b/private/ntos/nthals/hallego/alpha/fwreturn.c
new file mode 100644
index 000000000..65ae88cb8
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/fwreturn.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\fwreturn.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/haldebug.c b/private/ntos/nthals/hallego/alpha/haldebug.c
new file mode 100644
index 000000000..ce91863ec
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/haldebug.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\haldebug.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/halpal.s b/private/ntos/nthals/hallego/alpha/halpal.s
new file mode 100644
index 000000000..fc89f8370
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/halpal.s
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\halpal.s"
+
diff --git a/private/ntos/nthals/hallego/alpha/idle.s b/private/ntos/nthals/hallego/alpha/idle.s
new file mode 100644
index 000000000..f517bab2f
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/idle.s
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\idle.s"
+
diff --git a/private/ntos/nthals/hallego/alpha/info.c b/private/ntos/nthals/hallego/alpha/info.c
new file mode 100644
index 000000000..22aef63a3
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/info.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\info.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/inithal.c b/private/ntos/nthals/hallego/alpha/inithal.c
new file mode 100644
index 000000000..a99cb9a1a
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/inithal.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\inithal.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/intsup.s b/private/ntos/nthals/hallego/alpha/intsup.s
new file mode 100644
index 000000000..a7d9f8f4f
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/intsup.s
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+#include "pcrtc.h"
+#include "..\halalpha\intsup.s"
+
diff --git a/private/ntos/nthals/hallego/alpha/ioproc.c b/private/ntos/nthals/hallego/alpha/ioproc.c
new file mode 100644
index 000000000..14af7ad42
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/ioproc.c
@@ -0,0 +1,74 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ ioproc.c
+
+Abstract:
+
+ Stub functions for UP hals.
+
+Author:
+
+ Ken Reneris (kenr) 22-Jan-1991
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ Added to Avanti Hals (Sameer Dekate) 04-May-1994
+
+--*/
+
+#include "halp.h"
+#include "iousage.h"
+
+UCHAR HalName[] = "Alpha Compatible PCI/Eisa/Isa HAL";
+
+BOOLEAN
+HalpInitMP (
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+VOID HalpInitializePciBuses (VOID);
+VOID HalpInitOtherBuses (VOID);
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpInitMP)
+#pragma alloc_text(INIT,HalpInitOtherBuses)
+#endif
+
+
+
+BOOLEAN
+HalpInitMP (
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+{
+ return TRUE;
+ // do nothing
+}
+
+
+VOID
+HalpResetAllProcessors (
+ VOID
+ )
+{
+ // Just return, that will invoke the standard PC reboot code
+}
+
+
+VOID
+HalpInitOtherBuses (
+ VOID
+ )
+{
+ // no other internal buses supported
+}
diff --git a/private/ntos/nthals/hallego/alpha/iousage.c b/private/ntos/nthals/hallego/alpha/iousage.c
new file mode 100644
index 000000000..6ac8f6f4e
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/iousage.c
@@ -0,0 +1,647 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ iousage.c
+
+Abstract:
+
+Author:
+
+ Ken Reneris (kenr)
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ Chao Chen 1-25-1995
+
+--*/
+
+#include "halp.h"
+#include "iousage.h"
+
+//
+// Externals.
+//
+
+extern KAFFINITY HalpActiveProcessors;
+
+//
+// Private resource list.
+//
+
+static PBUS_USAGE HalpBusUsageList = NULL;
+static PRESOURCE_USAGE HalpResourceUsageList = NULL;
+
+//
+// Default HAL name.
+//
+
+#define MAX_NAME_LENGTH 256
+UCHAR HalRegisteredName[MAX_NAME_LENGTH] = "Alpha Compatible PCI/EISA/ISA HAL";
+
+//
+// Function prototype.
+//
+
+VOID
+HalpReportResourceUsage (
+ IN PUNICODE_STRING HalName
+ );
+
+VOID
+HalpGetResourceSortValue (
+ IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc,
+ OUT PULONG sortscale,
+ OUT PLARGE_INTEGER sortvalue
+ );
+
+//
+// Pragma stuff.
+//
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpRegisterHalName)
+#pragma alloc_text(INIT,HalpRegisterBusUsage)
+#pragma alloc_text(INIT,HalpRegisterResourceUsage)
+#pragma alloc_text(INIT,HalReportResourceUsage)
+#pragma alloc_text(INIT,HalpReportResourceUsage)
+#pragma alloc_text(INIT,HalpGetResourceSortValue)
+#endif
+
+//
+// Function definitions.
+//
+
+
+VOID
+HalpRegisterHalName(
+ IN PUCHAR NewHalName
+ )
+/*++
+
+Routine Description:
+
+ Allow the HAL to register a name string.
+
+Arguments:
+
+ HalName - Supplies a pointer to the HAL name to register.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ strncpy( HalRegisteredName, NewHalName, MAX_NAME_LENGTH );
+ return;
+}
+
+
+
+VOID
+HalpRegisterBusUsage (
+ IN INTERFACE_TYPE BusType
+ )
+/*++
+
+Routine Description:
+
+ Register the different bus types in the system.
+
+Arguments:
+
+ BusType - bus type that requires registering.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PBUS_USAGE Temp;
+
+ //
+ // Allocate the buffer to store the bus information.
+ //
+
+ Temp = (PBUS_USAGE)ExAllocatePool(NonPagedPool, sizeof(BUS_USAGE));
+
+ //
+ // Save the bus type.
+ //
+
+ Temp->BusType = BusType;
+
+ //
+ // Add the bus type to the head of the list.
+ //
+
+ Temp->Next = HalpBusUsageList;
+ HalpBusUsageList = Temp;
+}
+
+
+
+VOID
+HalpRegisterResourceUsage (
+ IN PRESOURCE_USAGE Resource
+ )
+/*++
+
+Routine Description:
+
+ Register the resources used internally by the HAL to the I/O system.
+
+Arguments:
+
+ Resource - resource that requires registering.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PRESOURCE_USAGE Temp;
+
+ //
+ // Allocate the buffer to store the resource information.
+ //
+
+ Temp = (PRESOURCE_USAGE)ExAllocatePool(NonPagedPool, sizeof(RESOURCE_USAGE));
+
+ //
+ // Copy the resource to the buffer we allocated.
+ //
+
+ RtlCopyMemory(Temp, Resource, sizeof(RESOURCE_USAGE));
+
+ //
+ // Add the resource to the head of the resource list.
+ //
+
+ Temp->Next = HalpResourceUsageList;
+ HalpResourceUsageList = Temp;
+}
+
+
+
+VOID
+HalReportResourceUsage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Report the resources used internally by the HAL to the I/O system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ ANSI_STRING AHalName;
+ UNICODE_STRING UHalName;
+
+ //
+ // Convert the string.
+ //
+
+ RtlInitAnsiString (&AHalName, HalRegisteredName);
+ RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE);
+
+ //
+ // Report the resources registered as in use by the HAL.
+ //
+
+ HalpReportResourceUsage(&UHalName);
+
+ RtlFreeUnicodeString(&UHalName);
+}
+
+
+
+VOID
+HalpGetResourceSortValue (
+ IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc,
+ OUT PULONG sortscale,
+ OUT PLARGE_INTEGER sortvalue
+ )
+/*++
+
+Routine Description:
+
+ Used by HalpReportResourceUsage in order to properly sort
+ partial_resource_descriptors.
+
+Arguments:
+
+ pRCurLoc - resource descriptor
+
+Return Value:
+
+ sortscale - scaling of resource descriptor for sorting
+ sortvalue - value to sort on
+
+
+--*/
+{
+
+ switch (pRCurLoc->Type) {
+ case CmResourceTypeInterrupt:
+ *sortscale = 0;
+ sortvalue->QuadPart = pRCurLoc->u.Interrupt.Level;
+ break;
+
+ case CmResourceTypePort:
+ *sortscale = 1;
+ *sortvalue = pRCurLoc->u.Port.Start;
+ break;
+
+ case CmResourceTypeMemory:
+ *sortscale = 2;
+ *sortvalue = pRCurLoc->u.Memory.Start;
+ break;
+
+ case CmResourceTypeDma:
+ *sortscale = 3;
+ sortvalue->QuadPart = pRCurLoc->u.Dma.Channel;
+ break;
+
+ default:
+ *sortscale = 4;
+ sortvalue->QuadPart = 0;
+ break;
+ }
+}
+
+
+
+VOID
+HalpReportResourceUsage (
+ IN PUNICODE_STRING HalName
+ )
+/*++
+
+Routine Description:
+
+ This routine registers the resources for the hal.
+
+Arguments:
+
+ HalName - the name of the hal to be registered.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PCM_RESOURCE_LIST RawResourceList, TranslatedResourceList;
+ PCM_FULL_RESOURCE_DESCRIPTOR pRFullDesc, pTFullDesc;
+ PCM_PARTIAL_RESOURCE_LIST pRPartList, pTPartList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, pTCurLoc;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR pRSortLoc, pTSortLoc;
+ CM_PARTIAL_RESOURCE_DESCRIPTOR RPartialDesc, TPartialDesc;
+ ULONG i, j, k, ListSize, Count;
+ ULONG curscale, sortscale;
+ LARGE_INTEGER curvalue, sortvalue;
+ PHYSICAL_ADDRESS PhyAddress;
+ PBUS_USAGE CurrentBus;
+ PRESOURCE_USAGE CurrentResource;
+
+ //
+ // Allocate some space to build the resource structure.
+ //
+
+ RawResourceList=
+ (PCM_RESOURCE_LIST)ExAllocatePool(NonPagedPool, PAGE_SIZE*2);
+ TranslatedResourceList=
+ (PCM_RESOURCE_LIST)ExAllocatePool(NonPagedPool, PAGE_SIZE*2);
+
+ //
+ // This functions assumes unset fields are zero.
+ //
+
+ RtlZeroMemory (RawResourceList, PAGE_SIZE*2);
+ RtlZeroMemory (TranslatedResourceList, PAGE_SIZE*2);
+
+ //
+ // Initialize the lists
+ //
+
+ RawResourceList->List[0].InterfaceType = (INTERFACE_TYPE) -1;
+ pRFullDesc = RawResourceList->List;
+ pRCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) RawResourceList->List;
+ pTCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) TranslatedResourceList->List;
+
+ //
+ // Report all the HAL resources.
+ //
+
+ CurrentBus = HalpBusUsageList;
+
+ while (CurrentBus) {
+
+ //
+ // Start at the head of the resource list for each bus type.
+ //
+
+ CurrentResource = HalpResourceUsageList;
+
+ while (CurrentResource) {
+
+ //
+ // Register the resources for a particular bus.
+ //
+
+ if (CurrentBus->BusType == CurrentResource->BusType) {
+
+ switch (CurrentResource->ResourceType) {
+
+ case CmResourceTypeInterrupt:
+
+ //
+ // Process interrupt resources.
+ //
+
+ RPartialDesc.Type = CmResourceTypeInterrupt;
+ RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
+
+ if (CurrentResource->u.InterruptMode == Latched)
+ RPartialDesc.Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+ else
+ RPartialDesc.Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+
+ RPartialDesc.u.Interrupt.Vector =
+ CurrentResource->u.BusInterruptVector;
+ RPartialDesc.u.Interrupt.Level =
+ CurrentResource->u.BusInterruptVector;
+ RPartialDesc.u.Interrupt.Affinity = HalpActiveProcessors;
+
+ RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc));
+ TPartialDesc.u.Interrupt.Vector =
+ CurrentResource->u.SystemInterruptVector;
+ TPartialDesc.u.Interrupt.Level =
+ CurrentResource->u.SystemIrql;
+
+ break;
+
+ case CmResourceTypePort:
+ case CmResourceTypeMemory:
+
+ //
+ // Process port and memory resources.
+ //
+
+ RPartialDesc.Type = CurrentResource->ResourceType;
+ RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
+
+ if (RPartialDesc.Type == CmResourceTypePort) {
+
+ //
+ // In IO space.
+ //
+
+ i = 1;
+ RPartialDesc.Flags = CM_RESOURCE_PORT_IO;
+
+ } else {
+
+ //
+ // In memory space.
+ //
+
+ i = 0;
+ RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+ }
+
+ //
+ // Notice: assume u.Memory and u.Port have the same layout.
+ //
+
+ RPartialDesc.u.Memory.Start.HighPart = 0;
+ RPartialDesc.u.Memory.Start.LowPart = CurrentResource->u.Start;
+ RPartialDesc.u.Memory.Length = CurrentResource->u.Length;
+
+ RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc));
+
+ //
+ // Translate the address.
+ //
+
+ HalTranslateBusAddress(CurrentResource->BusType,
+ CurrentResource->BusNumber,
+ RPartialDesc.u.Memory.Start,
+ &i,
+ &PhyAddress );
+
+ TPartialDesc.u.Memory.Start = PhyAddress;
+
+ if ((RPartialDesc.Type == CmResourceTypePort) && (i == 0))
+ TPartialDesc.Flags = CM_RESOURCE_PORT_MEMORY;
+
+ break;
+
+ case CmResourceTypeDma:
+
+ //
+ // Process dma resources.
+ //
+
+ RPartialDesc.Type = CmResourceTypeDma;
+ RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
+
+ RPartialDesc.u.Dma.Channel = CurrentResource->u.DmaChannel;
+ RPartialDesc.u.Dma.Port = CurrentResource->u.DmaPort;
+
+ RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc));
+ TPartialDesc.u.Dma.Channel = CurrentResource->u.DmaChannel;
+ TPartialDesc.u.Dma.Port = CurrentResource->u.DmaPort;
+
+ break;
+
+ default:
+
+ //
+ // Got a resource we don't know. Bail out!
+ //
+
+ goto NextResource;
+ }
+
+ //
+ // Include the current resource in the HAL list.
+ //
+
+ if (pRFullDesc->InterfaceType != CurrentBus->BusType) {
+
+ //
+ // Interface type changed, add another full section
+ //
+
+ RawResourceList->Count++;
+ TranslatedResourceList->Count++;
+
+ pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)pRCurLoc;
+ pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)pTCurLoc;
+
+ pRFullDesc->InterfaceType = CurrentBus->BusType;
+ pTFullDesc->InterfaceType = CurrentBus->BusType;
+
+ pRPartList = &pRFullDesc->PartialResourceList;
+ pTPartList = &pTFullDesc->PartialResourceList;
+
+ //
+ // Bump current location pointers up
+ //
+
+ pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
+ pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
+ }
+
+ //
+ // Add current resource in.
+ //
+
+ pRPartList->Count++;
+ pTPartList->Count++;
+ RtlCopyMemory(pRCurLoc, &RPartialDesc, sizeof(RPartialDesc));
+ RtlCopyMemory(pTCurLoc, &TPartialDesc, sizeof(TPartialDesc));
+
+ pRCurLoc++;
+ pTCurLoc++;
+ }
+
+ //
+ // Finished with this resource, move to the next one.
+ //
+
+ NextResource:
+ CurrentResource = CurrentResource->Next;
+ }
+
+ //
+ // Finished with this bus, move to the next one.
+ //
+
+ CurrentBus = CurrentBus->Next;
+ }
+
+ //
+ // Do the actual reporting.
+ //
+
+ ListSize = (ULONG)(((PUCHAR)pRCurLoc) - ((PUCHAR)RawResourceList));
+
+ //
+ // The HAL's resource usage structures have been built
+ // Sort the partial lists based on the Raw resource values.
+ //
+
+ pRFullDesc = RawResourceList->List;
+ pTFullDesc = TranslatedResourceList->List;
+
+ for (i=0; i < RawResourceList->Count; i++) {
+
+ pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
+ pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
+ Count = pRFullDesc->PartialResourceList.Count;
+
+ for (j=0; j < Count; j++) {
+ HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue);
+
+ pRSortLoc = pRCurLoc;
+ pTSortLoc = pTCurLoc;
+
+ for (k=j; k < Count; k++) {
+ HalpGetResourceSortValue (pRSortLoc, &sortscale, &sortvalue);
+
+ if (sortscale < curscale ||
+ (sortscale == curscale &&
+ (sortvalue.QuadPart < curvalue.QuadPart)) ){
+
+ //
+ // Swap the elements.
+ //
+
+ RtlCopyMemory (&RPartialDesc, pRCurLoc, sizeof RPartialDesc);
+ RtlCopyMemory (pRCurLoc, pRSortLoc, sizeof RPartialDesc);
+ RtlCopyMemory (pRSortLoc, &RPartialDesc, sizeof RPartialDesc);
+
+ //
+ // Swap translated descriptor as well.
+ //
+
+ RtlCopyMemory (&TPartialDesc, pTCurLoc, sizeof TPartialDesc);
+ RtlCopyMemory (pTCurLoc, pTSortLoc, sizeof TPartialDesc);
+ RtlCopyMemory (pTSortLoc, &TPartialDesc, sizeof TPartialDesc);
+
+ //
+ // Get new curscale & curvalue.
+ //
+
+ HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue);
+ }
+
+ pRSortLoc++;
+ pTSortLoc++;
+ }
+
+ pRCurLoc++;
+ pTCurLoc++;
+ }
+
+ pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc;
+ pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc;
+ }
+
+ //
+ // Inform the IO system of our resources.
+ //
+
+ IoReportHalResourceUsage(HalName,
+ RawResourceList,
+ TranslatedResourceList,
+ ListSize);
+
+ ExFreePool (RawResourceList);
+ ExFreePool (TranslatedResourceList);
+
+ //
+ // Free all registered buses.
+ //
+
+ while (HalpBusUsageList) {
+
+ CurrentBus = HalpBusUsageList;
+ HalpBusUsageList = HalpBusUsageList->Next;
+ ExFreePool(CurrentBus);
+ }
+
+ //
+ // Free all registered resources.
+ //
+
+ while (HalpResourceUsageList) {
+
+ CurrentResource = HalpResourceUsageList;
+ HalpResourceUsageList = HalpResourceUsageList->Next;
+ ExFreePool(CurrentResource);
+ }
+}
+
diff --git a/private/ntos/nthals/hallego/alpha/iousage.h b/private/ntos/nthals/hallego/alpha/iousage.h
new file mode 100644
index 000000000..b54cd179a
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/iousage.h
@@ -0,0 +1,107 @@
+/*++
+
+Copyright (c) 1993-1995 Microsoft Corporation
+Copyright (c) 1993-1995 Digital Equipment Corporation
+
+Module Name:
+
+ iousage.h
+
+Abstract:
+
+ This header file defines the iousage definitions
+
+Author:
+
+ Sameer Dekate 5-3-1994
+
+
+Revision History:
+
+ Chao Chen 1-25-1995
+
+--*/
+
+//
+// Resource usage information
+//
+
+//
+// Bus usage information.
+//
+
+typedef struct _HalBusUsage{
+ INTERFACE_TYPE BusType;
+ struct _HalBusUsage *Next;
+} BUS_USAGE, *PBUS_USAGE;
+
+//
+// Address usage information.
+//
+
+typedef struct _HalResourceUsage {
+
+ //
+ // Common elements.
+ //
+
+ INTERFACE_TYPE BusType;
+ ULONG BusNumber;
+ CM_RESOURCE_TYPE ResourceType;
+ struct _HalResourceUsage *Next;
+
+ //
+ // Resource type specific.
+ //
+
+ union {
+
+ //
+ // Address usage.
+ //
+
+ struct {
+ ULONG Start;
+ ULONG Length;
+ };
+
+ //
+ // Vector type specific.
+ //
+
+ struct {
+ KINTERRUPT_MODE InterruptMode;
+ ULONG BusInterruptVector;
+ ULONG SystemInterruptVector;
+ KIRQL SystemIrql;
+ };
+
+ //
+ // Dma type specific.
+ //
+
+ struct {
+ ULONG DmaChannel;
+ ULONG DmaPort;
+ };
+ } u;
+} RESOURCE_USAGE, *PRESOURCE_USAGE;
+
+//
+// Functions to report HAL's resource usage.
+//
+
+VOID
+HalpRegisterHalName(
+ IN PUCHAR HalName
+ );
+
+VOID
+HalpRegisterBusUsage (
+ IN INTERFACE_TYPE BusType
+ );
+
+VOID
+HalpRegisterResourceUsage (
+ IN PRESOURCE_USAGE Resource
+ );
diff --git a/private/ntos/nthals/hallego/alpha/legodef.h b/private/ntos/nthals/hallego/alpha/legodef.h
new file mode 100644
index 000000000..14213c792
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/legodef.h
@@ -0,0 +1,671 @@
+/*++
+
+Copyright (c) 1993,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ legodef.h
+
+Abstract:
+
+ This module specifies platform-specific definitions for the
+ Lego modules.
+
+Author:
+
+ Joe Notarangelo 25-Oct-1993
+
+Revision History:
+
+ Gene Morgan [Digital] 11-Oct-1995
+ Initial version for Lego. Adapted from Avanti.
+
+ Gene Morgan 15-Apr-1996
+ New Platform Name strings
+
+--*/
+
+#ifndef _LEGODEF_
+#define _LEGODEF_
+
+#include "alpharef.h"
+#include "apecs.h"
+#include "isaaddr.h"
+
+//****************************************************************
+// Lego family configurations
+// (PCI/ISA slots and backplane features).
+//
+// PCI "Virtual slot" concept comes from Microsoft's pci.h file.
+//
+//****************************************************************
+
+// Atacama -- Baby-AT form factor
+//
+#define NUMBER_ATACAMA_ISA_SLOTS 4
+#define NUMBER_ATACAMA_PCI_SLOTS 3 // 2 are 64-bit. NCR810 is in what would be 2nd slot
+
+//
+// Gobi -- 15 slot backplane
+//
+// Addition of one DECchip 21052 PPB yields 4 32-bit PCI slots (at cost of one 32-bit slot).
+// NCR810 is gone, too.
+//
+// Gobi PCI config
+// Slot function IDSEL int pin routing (mod 4)
+// ---- -------- ----- ----------------------
+// 20 PCI-PCI bridge 31 +3
+// 19 64-bit slot 30 +2
+// 18 64-bit slot 29 +1
+// 17 32-bit slot 28 +0
+//
+// 15 bridge 1 slot 31 +0
+// 14 bridge 1 slot 30 +1
+// 13 bridge 1 slot 29 +2
+// 12 bridge 1 slot 28 +3
+//
+// 7 ISA SIO 18 --
+//
+#define NUMBER_GOBI_ISA_SLOTS 5
+#define NUMBER_GOBI_PCI_SLOTS 7
+
+// Sahara -- 20 slot backplane
+//
+// Addition of another 21052...
+//
+#define NUMBER_SAHARA_ISA_SLOTS 7
+#define NUMBER_SAHARA_PCI_SLOTS 10
+
+// Generic -- use Sahara's values
+//
+// ??? Used ???
+//
+#define NUMBER_ISA_SLOTS (NUMBER_SAHARA_ISA_SLOTS)
+#define NUMBER_PCI_SLOTS (NUMBER_SAHARA_PCI_SLOTS)
+
+// Lowest virtual local PCI slot is 17 == IDSEL PCI_AD[28]
+// Highest Virtual local PCI Slot is 20 == IDSEL PCI_AD[31]
+// This gives the following slot layout:
+//
+// Virtual Device Physical Device/slot IDSEL
+// 17 1 28
+// 18 2 29
+// 19 3 30
+// 20 4 31
+//
+// Used for sizing Pin-to-Line table.
+//
+#define PCI_MIN_LOCAL_DEVICE 17 //[wem] not used
+#define PCI_MAX_LOCAL_DEVICE 20
+
+// LEGO Family Members -
+//
+// concatenate cpu and backplane type to get family type
+//
+
+#define CPU_UNKNOWN 0x0 // Can't tell what CPU
+#define CPU_LEGO_K2 0x1 // K2 CPU card
+
+#define BACKPLANE_UNKNOWN 0x0 // Can't determine backplane -- assume PICMIG-compliant
+#define BACKPLANE_ATACAMA 0x1
+#define BACKPLANE_GOBI 0x2
+#define BACKPLANE_SAHARA 0x3
+
+//
+// Backplane/CPU feature mask
+//
+
+#define LEGO_FEATURE_INT_ACCEL 0x01
+#define LEGO_FEATURE_SERVER_MGMT 0x02
+#define LEGO_FEATURE_WATCHDOG 0x04 // PSU (not in first rev of K2)
+#define LEGO_FEATURE_OCP_DISPLAY 0x08 // I2C bus and PCF8574s are present
+#define LEGO_FEATURE_PSU 0x10 // System has DMCC backplane with support
+ // for multiple power supplies
+
+#define LEGO_NUMBER_OF_FEATURES 5
+
+//
+// Server Management Conditions
+//
+
+#define LEGO_CONDITION_OVERTEMP 0x01
+#define LEGO_CONDITION_CPU_OVERTEMP 0x02
+#define LEGO_CONDITION_CPU_TEMPOK 0x04
+#define LEGO_CONDITION_BADFAN 0x08
+#define LEGO_CONDITION_CPU_BADFAN 0x10
+#define LEGO_CONDITION_POWER1_BAD 0x20
+#define LEGO_CONDITION_POWER2_BAD 0x40
+
+#define CONDITION_QUERY 0x10000 // force recheck of server management register
+
+#define LEGO_NUMBER_OF_CONDITIONS 7
+
+//
+// Define known Lego platform names.
+//
+
+#define PLATFORM_NAME_LEGO_K2 "LegoK2"
+#define PLATFORM_NAME_K2_ATA "LegoK2A" // Atacama
+#define PLATFORM_NAME_K2_GOBI "LegoK2G" // Gobi
+#define PLATFORM_NAME_K2_SAHA "LegoK2S" // Sahara
+#define PLATFORM_NAME_UNKNOWN "LegoUnk" // Unknown
+
+//
+// PCI Interrupt routing types
+//
+// PCI Interrupts in LEGO may be routed in one of three ways:
+// SIO - INTA .. INTD off the PCI bus routed through the SIO.
+// DIRECT - INTA .. INTD off the PCI bus routed to an interrupt
+// register.
+// FULL - INTA .. INTD from each primary or bridged slot (64 signals)
+// routed to one of four interrupt registers.
+//
+#define PCI_INTERRUPT_ROUTING_SIO 1
+#define PCI_INTERRUPT_ROUTING_FULL 2
+#define PCI_INTERRUPT_ROUTING_DIRECT 3
+
+
+//*******************************************************
+//
+// End Lego-specific configuration info
+//
+// Lego-specific register layouts and addresses
+// are at the end of this file.
+//
+//*******************************************************
+
+//[wem] same as avanti.h
+//
+#define PCI_SPARSE_IO_BASE_QVA ((ULONG)(HAL_MAKE_QVA(APECS_PCI_IO_BASE_PHYSICAL))) //[wem] LEGO-OK
+
+//
+// PCI-E/ISA Bridge chip configuration space base is at physical address
+// 0x1e0000000. The equivalent QVA is:
+// ((0x1e0000000 + cache line offset) >> IO_BIT_SHIFT) | QVA_ENABLE
+//
+// N.B.: The PCI configuration space address is what we're really referring
+// to, here; both symbols are useful.
+//
+
+#define PCI_REVISION (0x0100 >> IO_BIT_SHIFT)
+
+#define PCI_CONFIGURATION_BASE_QVA 0xaf000000
+#define PCI_CONFIG_CYCLE_TYPE_0 0x0 // Local PCI device
+#define PCI_CONFIG_CYCLE_TYPE_1 0x1 // Nested PCI device
+
+#define PCI_ISA_BRIDGE_HEADER_OFFSET (0x00070000 >> IO_BIT_SHIFT) // AD[18] //[wem] LEGO-OK
+
+//
+// PCI-ISA Bridge Non-Configuration control register offsets.
+// These offsets are in PCI I/O space and should be ored with
+// PCI_SPARSE_IO_BASE_QVA.
+//
+
+#define SIO_II_EDGE_LEVEL_CONTROL_1 (0x9a00 >> IO_BIT_SHIFT) //[wem] LEGO-OK
+#define SIO_II_EDGE_LEVEL_CONTROL_2 (0x9a20 >> IO_BIT_SHIFT)
+
+//
+// Register offsets for unique functions on Lego. Some of these are offsets
+// into ISA I/O space -- they cannot be reached via PCI I/O space.
+//
+
+// PCI offsets...
+//
+
+#define PCI_INDEX (0x04c0 >> IO_BIT_SHIFT) //[wem] 0x4DC0 for LEGO ?
+#define PCI_DATA (0x04e0 >> IO_BIT_SHIFT) //[wem] 0x4DE0 for LEGO ?
+
+//
+// PCI-ISA Bridge Configuration register offsets.
+//
+
+#define PCI_VENDOR_ID (0x0000 >> IO_BIT_SHIFT) //[wem] LEGO-OK
+#define PCI_DEVICE_ID (0x0040 >> IO_BIT_SHIFT)
+#define PCI_COMMAND (0x0080 >> IO_BIT_SHIFT)
+#define PCI_DEVICE_STATUS (0x00c0 >> IO_BIT_SHIFT)
+#define PCI_REVISION (0x0100 >> IO_BIT_SHIFT)
+#define PCI_CONTROL (0x0800 >> IO_BIT_SHIFT)
+#define PCI_ARBITER_CONTROL (0x0820 >> IO_BIT_SHIFT)
+#define UTIL_BUS_CHIP_SELECT_ENAB_A (0x09c0 >> IO_BIT_SHIFT)
+#define UTIL_BUS_CHIP_SELECT_ENAB_B (0x09e0 >> IO_BIT_SHIFT)
+#define PIRQ0_ROUTE_CONTROL (0x0c00 >> IO_BIT_SHIFT)
+#define PIRQ1_ROUTE_CONTROL (0x0c20 >> IO_BIT_SHIFT)
+#define PIRQ2_ROUTE_CONTROL (0x0c40 >> IO_BIT_SHIFT)
+#define PIRQ3_ROUTE_CONTROL (0x0c60 >> IO_BIT_SHIFT)
+
+//
+// SIO-II value for setting edge/level operation in the control words.
+//
+
+#define IRQ0_LEVEL_SENSITIVE 0x01
+#define IRQ1_LEVEL_SENSITIVE 0x02
+#define IRQ2_LEVEL_SENSITIVE 0x04
+#define IRQ3_LEVEL_SENSITIVE 0x08
+#define IRQ4_LEVEL_SENSITIVE 0x10
+#define IRQ5_LEVEL_SENSITIVE 0x20
+#define IRQ6_LEVEL_SENSITIVE 0x40
+#define IRQ7_LEVEL_SENSITIVE 0x80
+#define IRQ8_LEVEL_SENSITIVE 0x01
+#define IRQ9_LEVEL_SENSITIVE 0x02
+#define IRQ10_LEVEL_SENSITIVE 0x04
+#define IRQ11_LEVEL_SENSITIVE 0x08
+#define IRQ12_LEVEL_SENSITIVE 0x10
+#define IRQ13_LEVEL_SENSITIVE 0x20
+#define IRQ14_LEVEL_SENSITIVE 0x40
+#define IRQ15_LEVEL_SENSITIVE 0x80
+
+//
+// Values for PIRQ route control settings.
+// see 82378 SIO spec, section 4.1.27
+//
+
+#define PIRQX_ROUTE_IRQ3 0x03
+#define PIRQX_ROUTE_IRQ4 0x04
+#define PIRQX_ROUTE_IRQ5 0x05
+#define PIRQX_ROUTE_IRQ6 0x06
+#define PIRQX_ROUTE_IRQ7 0x07
+#define PIRQX_ROUTE_IRQ9 0x09
+#define PIRQX_ROUTE_IRQ10 0x0a
+#define PIRQX_ROUTE_IRQ11 0x0b
+#define PIRQX_ROUTE_IRQ12 0x0c
+#define PIRQX_ROUTE_IRQ14 0x0d
+#define PIRQX_ROUTE_IRQ15 0x0f
+#define PIRQX_ROUTE_ENABLE 0x00
+#define PIRQX_ROUTE_DISABLE 0x80
+
+//
+// Define primary (and only) CPU on Lego system
+//
+
+#define HAL_PRIMARY_PROCESSOR ((ULONG)0x0)
+#define HAL_MAXIMUM_PROCESSOR ((ULONG)0x0)
+
+//
+// Define the default processor clock frequency used before the actual
+// value can be determined.
+//
+
+#define DEFAULT_PROCESSOR_FREQUENCY_MHZ (233)
+
+#if !defined (_LANGUAGE_ASSEMBLY)
+
+#if !defined (AXP_FIRMWARE)
+//
+// Define the per-processor data structures allocated in the PCR
+// for each EV4 processor.
+//
+typedef struct _LEGO_PCR{
+ ULONGLONG HalpCycleCount; // 64-bit per-processor cycle count
+ EV4ProfileCount ProfileCount; // Profile counter state, do not move
+ EV4IrqStatus IrqStatusTable[MaximumIrq]; // Irq status table
+} LEGO_PCR, *PLEGO_PCR;
+
+#endif
+
+#define HAL_PCR ( (PLEGO_PCR)(&(PCR->HalReserved)) )
+
+#endif
+
+//**************************************************
+//
+// The remainder of this file contain Lego-specific
+// definitions.
+//
+//**************************************************
+
+// The Lego server management data structure
+//
+// The server management register is at ISA address 506h.
+//
+// The SINT signals are routed to CPU IRQ5. Writing a 1 to an SINT
+// bit will clear the interrupt (an edge will reassert it). The temperature
+// sensors can clear and reassert themselves, the fan sensors are one-shots.
+//
+// The NMI signals are routed to CPU IRQ3. The bits cannot be cleared, only
+// masked.
+//
+// Note: PINT and MPINT bits are not in first rev of K2.
+//
+#if !defined(_LANGUAGE_ASSEMBLY)
+
+typedef union _LEGO_SRV_MGMT{
+ struct {
+ USHORT CpuTempRestored : 1; // rw - SINT1
+ USHORT CpuTempFailure : 1; // rw - SINT2
+ USHORT EnclFanFailure : 1; // rw - SINT3
+ USHORT EnclTempFailureNmi : 1; // ro - SNMI1
+ USHORT CpuFanFailureNmi : 1; // ro - SNMI2
+ USHORT IntMask : 1; // rw - MSINT - set to mask SINT[1..3]
+ USHORT NmiMask : 1; // rw - MSNMI - set to mask SNMI[1..2]
+ USHORT PowerOff : 1; // rw - POFF - set to switch off power
+ USHORT PsuMask : 1; // rw - MPINT - set to mask PINT[2..1]
+ USHORT Psu1Failure : 1; // rw - PINT1 - PSU status change
+ USHORT Psu2Failure : 1; // rw - PINT2 - PSU status change
+ USHORT Reserved : 5; // ro/undefined
+ };
+ USHORT All;
+} LEGO_SRV_MGMT, *PLEGO_SRV_MGMT;
+
+// The Lego watchdog timer data structure
+// The watchdog timer register is at ISA address 504h.
+//
+// The WINT signal is routed to CPU IRQ5. The interrupt
+// is cleared by writing a 1 to WINT.
+//
+// Notes:
+// WMODE, T1CF, and T2CF can be written iff the watchdog is disabled.
+// The watchdog cannot be disabled if timer 2 running.
+// To disable the watchdog:
+// (WPHAS==0) ? WEN = 0 : WPHAS = 1, WEN = 0;
+// If timer two is allowed to expire, a system-wide reset occurs.
+// Write 1 to WPHAS, WINT to clear them.
+//
+typedef union _LEGO_WATCHDOG{
+ struct {
+ USHORT TimerOnePeriod : 3; // rw - T1CF[2:0]
+ USHORT TimerTwoPeriod : 3; // rw - T2CF[2:0]
+ USHORT Enabled : 1; // rw - WEN - set to enable timer
+ USHORT Mode : 1; // rw - WMODE - see WATCHDOG_MODE_*
+ USHORT Phase : 1; // rw - WPHAS - see WATCHDOG_PHASE_*
+ USHORT Interrupt : 1; // rw - WINT - timer one expired.
+ USHORT Reserved : 6; // ro/undefined
+ };
+ USHORT All;
+} LEGO_WATCHDOG, *PLEGO_WATCHDOG;
+
+// Watchdog phase - detect whether timer (phase) one or two is running.
+// Writing one to the phase bit will place timer in phase one.
+//
+#define WATCHDOG_PHASE_ONE 0
+#define WATCHDOG_PHASE_TWO 1
+
+// Watchdog mode - select whether to run in one-timer or two-timer mode
+//
+#define WATCHDOG_MODE_2TIMER 0
+#define WATCHDOG_MODE_1TIMER 1
+
+#define WATCHDOG_MODE_DISABLED 2
+
+// Timeout periods for timers 1 and 2
+//
+#define WATCHDOG_PERIOD_10MS 0
+#define WATCHDOG_PERIOD_100MS 1
+#define WATCHDOG_PERIOD_500MS 2
+#define WATCHDOG_PERIOD_1S 3
+#define WATCHDOG_PERIOD_8S 4
+#define WATCHDOG_PERIOD_60S 5
+#define WATCHDOG_PERIOD_300S 6
+#define WATCHDOG_PERIOD_1200S 7
+
+// Lego PCI Interrupt Support
+//
+// Define registers used for facilitating PCI interrupt processing:
+// Configuration register (LEGO_PCI_INT_CONFIG) - controls interrupt routing
+// Master Interrupt register (LEGO_PCI_INT_MASTER) - slot-level int and mask
+// Interrupt Registers 1-4 (LEGO_PCI_INT_REGISTER) - device-level int and mask
+// The interrupt registers may hold interrupt and mask signals for a single
+// primary slot, or for the four slots that may reside behind the bridge.
+//
+// The registers are all defined as 16-bit registers since LEGO's ISA bus
+// is limited to 16-bit reads and writes.
+//
+
+// Lego PCI Interrupt Support Configuration Register (ISA address 502h)
+// CFG - read-only field that identifies which primary slots hold bridges.
+// ADR - used to establish the base address of the 4 4-byte interrupt registers.
+//
+typedef union _LEGO_PCI_INT_CONFIG{
+ struct {
+ USHORT BackplaneConfig : 4; // ro - CFG[4:1] - see LEGO_CONFIG_*
+ USHORT IntRegisterBaseAddr : 12; // rw - ADR[15:4]
+ };
+ USHORT All;
+} LEGO_PCI_INT_CONFIG, *PLEGO_PCI_INT_CONFIG;
+
+// Configurations
+//
+// Value is a bitmask that indicates which primary slots are
+// bridges -- the rightmost bit is for device 1.
+//
+#define LEGO_CONFIG_ATACAMA 0x0 // b0000 - all primary slots are connectors
+#define LEGO_CONFIG_GOBI 0x1 // b0001 - primary slot one is a PPB
+#define LEGO_CONFIG_SAHARA 0x3 // b0011 - primary slots one and two are PPBs
+
+// Lego PCI Interrupt Support Master Register (ISA address 500h)
+//
+// INTE and INTF and reserved for on-board PCI functions. Their use
+// is not currently defined.
+//
+// OWN - controls who drives bits 13-15 on a read to the Interrupt Master Register
+// 0 (default) - backplane drives the bits on a read
+// 1 - cpu card drives the bits
+//
+typedef union _LEGO_PCI_INT_MASTER{
+ struct {
+ USHORT Interrupt : 4; // ro - INTA..INTD
+ USHORT InterruptRes : 2; // ro - INTE,F **reserved**
+ USHORT IntMask : 4; // rw - MINTA..MINTD
+ USHORT IntMaskRes : 2; // rw - MINTE,F **reserved**
+ USHORT IntOwner : 1; // rw - OWN
+ USHORT IntRegMaskEnable : 1; // rw - MSKEN
+ USHORT InterruptEnable : 1; // rw - PCIE
+ USHORT InterruptMode : 1; // rw - MODE
+ };
+ USHORT All;
+} LEGO_PCI_INT_MASTER, *PLEGO_PCI_INT_MASTER;
+
+#define INTA 0x1
+#define INTB 0x2
+#define INTC 0x4
+#define INTD 0x8
+
+#define SLOT1INTA (INTA)
+#define SLOT1INTB (INTB)
+#define SLOT1INTC (INTC)
+#define SLOT1INTD (INTD)
+#define SLOT2INTA (INTA<<4)
+#define SLOT2INTB (INTB<<4)
+#define SLOT2INTC (INTC<<4)
+#define SLOT2INTD (INTD<<4)
+#define SLOT3INTA (INTA<<8)
+#define SLOT3INTB (INTB<<8)
+#define SLOT3INTC (INTC<<8)
+#define SLOT3INTD (INTD<<8)
+#define SLOT4INTA (INTA<<12)
+#define SLOT4INTB (INTB<<12)
+#define SLOT4INTC (INTC<<12)
+#define SLOT4INTD (INTD<<12)
+
+// Lego PCI Interrupt Support -- Interrupt Register.
+//
+typedef union _LEGO_PCI_INT_REGISTER {
+ union {
+ struct {
+ USHORT Slot1IntA : 1; // ro - S1IA
+ USHORT Slot1IntB : 1; // ro - S1IB
+ USHORT Slot1IntC : 1; // ro - S1IC
+ USHORT Slot1IntD : 1; // ro - S1ID
+ USHORT Slot2IntA : 1; // ro - S2IA
+ USHORT Slot2IntB : 1; // ro - S2IB
+ USHORT Slot2IntC : 1; // ro - S2IC
+ USHORT Slot2IntD : 1; // ro - S2ID
+ USHORT Slot3IntA : 1; // ro - S3IA
+ USHORT Slot3IntB : 1; // ro - S3IB
+ USHORT Slot3IntC : 1; // ro - S3IC
+ USHORT Slot3IntD : 1; // ro - S3ID
+ USHORT Slot4IntA : 1; // ro - S4IA
+ USHORT Slot4IntB : 1; // ro - S4IB
+ USHORT Slot4IntC : 1; // ro - S4IC
+ USHORT Slot4IntD : 1; // ro - S4ID
+ } bridge;
+ struct {
+ USHORT IntA : 1; // ro - IA
+ USHORT IntB : 1; // ro - IB
+ USHORT IntC : 1; // ro - IC
+ USHORT IntD : 1; // ro - ID
+ USHORT Reserved : 12; // ro - reserved
+ } primary;
+ } slot;
+ USHORT All;
+} LEGO_PCI_INT_REGISTER, *PLEGO_PCI_INT_REGISTER;
+
+// Lego PCI Interrupt Support -- Interrupt Mask Register.
+//
+typedef union _LEGO_PCI_INT_MASK_REGISTER {
+ union {
+ struct {
+ USHORT Slot1MaskIntA : 1; // rw - MS1IA
+ USHORT Slot1MaskIntB : 1; // rw - MS1IB
+ USHORT Slot1MaskIntC : 1; // rw - MS1IC
+ USHORT Slot1MaskIntD : 1; // rw - MS1ID
+ USHORT Slot2MaskIntA : 1; // rw - MS2IA
+ USHORT Slot2MaskIntB : 1; // rw - MS2IB
+ USHORT Slot2MaskIntC : 1; // rw - MS2IC
+ USHORT Slot2MaskIntD : 1; // rw - MS2ID
+ USHORT Slot3MaskIntA : 1; // rw - MS3IA
+ USHORT Slot3MaskIntB : 1; // rw - MS3IB
+ USHORT Slot3MaskIntC : 1; // rw - MS3IC
+ USHORT Slot3MaskIntD : 1; // rw - MS3ID
+ USHORT Slot4MaskIntA : 1; // rw - MS4IA
+ USHORT Slot4MaskIntB : 1; // rw - MS4IB
+ USHORT Slot4MaskIntC : 1; // rw - MS4IC
+ USHORT Slot4MaskIntD : 1; // rw - MS4ID
+ } bridge;
+ struct {
+ USHORT MaskIntA : 1; // rw - MIA
+ USHORT MaskIntB : 1; // rw - MIB
+ USHORT MaskIntC : 1; // rw - MIC
+ USHORT MaskIntD : 1; // rw - MID
+ USHORT Reserved : 12; // ro - reserved
+ } primary;
+ } slot;
+ USHORT All;
+} LEGO_PCI_INT_MASK_REGISTER, *PLEGO_PCI_INT_MASK_REGISTER;
+
+#endif //!_LANGUAGE_ASSEMBLY
+
+// Define "non-standard" primary interrupts for Lego/K2
+//
+#define PCI_VECTOR PRIMARY0_VECTOR // from alpharef.h
+#define SERVER_MGMT_VECTOR PRIMARY1_VECTOR
+
+#define SERVER_MGMT_VECTORS 80
+
+// server management conditions (via CPU IRQ5)
+//
+#define WATCHDOG_VECTOR (0 + SERVER_MGMT_VECTORS)
+#define SM_WARNING_VECTOR (1 + SERVER_MGMT_VECTORS)
+#define SM_PSU_FAILURE_VECTOR (2 + SERVER_MGMT_VECTORS)
+
+// NMI conditions (via CPU IRQ3)
+//
+#define SM_ERROR_VECTOR (5 + SERVER_MGMT_VECTORS)
+#define HALT_BUTTON_VECTOR (6 + SERVER_MGMT_VECTORS)
+
+#define MAXIMUM_SERVER_MGMT_VECTOR (7 + SERVER_MGMT_VECTORS)
+
+//
+// Define interrupt level for server management interrupts,
+// including watchdog timer.
+// Level should be high, but not as high as NMI
+// Using IPI_LEVEL, which is normally for interprocessor interrupts,
+//[wem] ??? IPI_LEVEL is between NMI and CLOCK levels -- is this OK ?
+//
+
+#define SERVER_MGMT_LEVEL IPI_LEVEL // from alpharef.h
+
+//
+// Highest PCI interrupt vector is in ISA Vector Space
+// Standard vectors are defined in alpharef.h
+//
+
+#define ISA_DEVICE_VECTORS (ISA_VECTORS)
+#define PCI_DEVICE_VECTORS (PCI_VECTORS)
+#define LEGO_MAXIMUM_PCI_VECTOR (PCI_VECTORS + 0x50) //[wem] 16 vectors wasted
+
+// Lego device port ISA offsets - 16-bit access only
+
+//
+// server management and watchdog timer control
+//
+
+#define SERVER_MANAGEMENT_REGISTER 0x506
+#define WATCHDOG_REGISTER 0x504
+
+//
+// PCI interrupt control registers
+//
+
+#define PCI_INTERRUPT_MASTER_REGISTER 0x500
+#define PCI_INTERRUPT_CONFIG_REGISTER 0x502
+
+//
+// Base address of interrupt and mask registers
+//
+// The actual base address is determined by reading the IntRegisterBaseAddr field
+// of the config register. This is presumably the value established by SROM. [wem] check this
+//
+
+#define PCI_INTERRUPT_BASE_REGISTER 0x510
+
+//
+// offsets from base address set in IntRegisterBaseAddr field of
+// PCI_INTERRUPT_CONFIG_REGISTER (set to PCI_INTERRUPT_BASE_REGISTER).
+//
+// NOTE: USHORT accesses can be made to these offsets, or ULONG accesses
+// can be made to the PCI_INTERRUPT_REGISTER_* offsets to read/write
+// the interrupt state and interrupt mask in a single access.
+//
+
+#define MAXIMUM_PCI_INTERRUPT_REGISTERS 4
+#define PCI_INTERRUPT_REGISTER_1 (0x00) // << IO_SHORT_OFFSET)
+#define PCI_INTMASK_REGISTER_1 (0x02)
+#define PCI_INTERRUPT_REGISTER_2 (0x04)
+#define PCI_INTMASK_REGISTER_2 (0x06)
+#define PCI_INTERRUPT_REGISTER_3 (0x08)
+#define PCI_INTMASK_REGISTER_3 (0x0a)
+#define PCI_INTERRUPT_REGISTER_4 (0x0c)
+#define PCI_INTMASK_REGISTER_4 (0x0e)
+
+//
+// PCI vector offsets. Interrupt vectors that originate from register
+// 1 start at 0x11 for bit position 0. So, when servicing an interrupt from
+// register 1, you must add 0x11 to the bit position to get the interrupt
+// vector. Likewise, if you have an interrupt vector, and you would like to
+// determine which interrupt register it resides in, you can use the vector
+// offsets to determine this. All vectors in interrupt register 1 are between
+// 0x11 and 0x20. All vectors in interrupt register 2 are between 0x21 and
+// 0x30, and so on. Subtracting the vector offset for a register from the
+// interrupt vector will give you the bit position of the vector. For example,
+// Vector 0x14 corresponds to bit 3 of interrupt register 1, Vector 0x27
+// corresponds to bit 6 of interrupt register 2, and so on.
+//
+//[wem] used?
+//
+
+#define REGISTER_1_VECTOR_OFFSET 0x00
+#define REGISTER_2_VECTOR_OFFSET 0x10
+#define REGISTER_3_VECTOR_OFFSET 0x20
+#define REGISTER_4_VECTOR_OFFSET 0x30
+
+//
+// I2C Interface -- via PCF8584
+//
+// The PCF8584 presents 2 ports:
+// Control Status Register, or CSR (ISA address 509h) -
+// Register Window (data port) (ISA address 508h) -
+//
+// I2C support is via pcd8584.h,.c
+//
+// I2C bus in Lego has a single device -- the OCP.
+//
+// OCP support is via pcf8574.c
+//
+
+#define I2C_INTERFACE_DATA_PORT 0x508
+#define I2C_INTERFACE_CSR_PORT 0x509
+#define I2C_INTERFACE_LENGTH 0x2
+#define I2C_INTERFACE_MASK 0x1
+
+
+#endif // _LEGODEF_
diff --git a/private/ntos/nthals/hallego/alpha/lginitnt.c b/private/ntos/nthals/hallego/alpha/lginitnt.c
new file mode 100644
index 000000000..205a87096
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/lginitnt.c
@@ -0,0 +1,1409 @@
+/*++
+
+Copyright (c) 1993 Digital Equipment Corporation
+Copyright (c) 1994,1996 Digital Equipment Corporation
+
+
+Module Name:
+
+ lginitnt.c
+
+Abstract:
+
+ This module implements the platform-specific initialization for
+ a Lego system.
+
+Author:
+
+ Joe Notarangelo 25-Oct-1993
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ Gene Morgan [Digital] 11-Oct-1995
+ Initial version for Lego. Adapted from Avanti and Mikasa.
+
+ Gene Morgan 15-Apr-1996
+ Error loggin/correction, OCP model/speed display,
+ screen display of server management features.
+
+--*/
+
+#include "halp.h"
+#include "pcrtc.h"
+#include "legodef.h"
+#include "halpcsl.h"
+#include "eisa.h"
+#include "pci.h"
+#include "pcip.h"
+#include "iousage.h"
+#include "arccodes.h"
+#include "pcf8574.h"
+#include "errframe.h"
+#include "stdio.h"
+
+#include "fwcallbk.h"
+
+#include <ntverp.h> // to get the product build number.
+//
+// Define extern global buffer for the Uncorrectable Error Frame.
+// declared in halalpha\inithal.c
+//
+
+extern PERROR_FRAME PUncorrectableError;
+
+//[wem]
+//[wem] *******************DEBUG*********************
+//[wem]
+
+#ifdef WEMDBG
+extern PVOID DBG_IOBASE;
+
+#define DBGPUTCHR(c) \
+ { UCHAR lsr; \
+ while (1) { \
+ lsr = READ_REGISTER_UCHAR ((PUCHAR)(((ULONG)DBG_IOBASE) | 0x3FD)); \
+ if ((lsr & 0x60) != 0) \
+ break; \
+ } \
+ WRITE_REGISTER_UCHAR ((PUCHAR)(((ULONG)DBG_IOBASE) | 0x3F8), c ); \
+ }
+#else
+
+#define DBGPUTCHR(c)
+
+#endif
+
+VOID
+DBGPUTNL(VOID);
+
+VOID
+DBGPUTHEXB(UCHAR Datum);
+
+VOID
+DBGPUTHEXL(ULONG Datum);
+
+VOID
+DBGPUTHEXP(PVOID Datum);
+
+VOID
+DBGPUTSTR(UCHAR *str);
+
+//[wem]
+//[wem] *******************DEBUG*********************
+//[wem]
+
+//
+// Product Naming data.
+//
+PCHAR HalpFamilyName = "DMCC"; //[wem] ??? real values needed
+PCHAR HalpProductName = "Alpha 21064A PICMG SBC";
+ULONG HalpProcessorNumber = 4;
+
+// Qvas for Server Management and Watchdog Timer functions
+//
+extern PVOID HalpLegoWatchdogQva;
+extern PVOID HalpLegoServerMgmtQva;
+
+//
+// Globals for conveying Cpu and Backplane type
+//
+BOOLEAN HalpLegoCpu;
+BOOLEAN HalpLegoBackplane;
+ULONG HalpLegoCpuType;
+ULONG HalpLegoBackplaneType;
+UCHAR HalpLegoFeatureMask;
+ULONG HalpLegoPciRoutingType;
+
+//
+// True if we are servicing watchdog
+//
+BOOLEAN HalpLegoServiceWatchdog;
+BOOLEAN HalpLegoWatchdogSingleMode;
+BOOLEAN LegoDebugWatchdogIsr;
+
+//
+// True if someone has "enabled" interrupts
+// for a particular server management event.
+//
+BOOLEAN HalpLegoDispatchWatchdog;
+BOOLEAN HalpLegoDispatchNmi;
+BOOLEAN HalpLegoDispatchInt;
+BOOLEAN HalpLegoDispatchPsu;
+BOOLEAN HalpLegoDispatchHalt;
+
+#define MAX_INIT_MSG (80)
+
+//
+// Define global data for builtin device interrupt enables.
+//
+
+USHORT HalpBuiltinInterruptEnable;
+
+
+// irql mask and tables
+//
+// irql 0 - passive
+// irql 1 - sfw apc level
+// irql 2 - sfw dispatch level
+// irql 3 - device low
+// irql 4 - device high
+// irql 5 - clock
+// irql 6 - real time, ipi, performance counters
+// irql 7 - error, mchk, nmi, halt
+//
+//
+// IDT mappings:
+// For the built-ins, GetInterruptVector will need more info,
+// or it will have to be built-in to the routines, since
+// these don't match IRQL levels in any meaningful way.
+//
+// 0 passive 8 perf cntr 1
+// 1 apc 9
+// 2 dispatch 10 PIC
+// 3 11
+// 4 12 errors
+// 5 clock 13
+// 6 perf cntr 0 14 halt
+// 7 nmi 15
+//
+// This is assuming the following prioritization:
+// nmi
+// halt
+// errors
+// performance counters
+// clock
+// pic
+
+//
+// The hardware interrupt pins are used as follows for Lego/K2
+//
+// IRQ_H[0] = EPIC Error
+// IRQ_H[1] = PCI Interrupt (if PCI Interrupt controller enabled)
+// IRQ_H[2] = PIC (ISA Device interrupt)
+// IRQ_H[3] = NMI, Server management fatal errors, Halt button
+// IRQ_H[4] = Clock
+// IRQ_H[5] = Watchdog timer, Server Management warning conditions
+
+//
+// For information purposes: here is what the IDT division looks like:
+//
+// 000-015 Built-ins (we only use 8 entries; NT wants 10)
+// 016-031 ISA
+// 048-063 EISA
+// 064-127 PCI
+// 128-144 Server Management and Watchdog Timer
+// 144-255 unused, as are all other holes
+//
+//[wem] Here's what it is really like (as per alpharef.h and legodef.h)
+//
+// 000-019 Built-ins DEVICE_VECTORS - MAXIMUM_BUILTIN_VECTOR
+// 020-029 Platform-specific PRIMARY_VECTORS, PRIMARY0_VECTOR - PRIMARY9_VECTOR
+// 048-063 EISA & ISA ISA_VECTORS - MAXIMUM_ISA_VECTOR
+// 080-089 Server Mgmt and Watchdog Timer SERVER_MGMT_VECTORS - MAXIMUM_SERVER_MGMT_VECTORS
+// 100-164 PCI PCI_VECTORS - MAXIMUM_PCI_VECTOR
+// 165-255 unused, as are all other holes
+//
+//[wem] Here's what Lego uses for PCI
+//
+// 117-180 PCI (64h + 11h through 64h + 50h) Same size range, just shifted (16 vectors wasted).
+// PCI_VECTORS - LEGO_MAXIMUM_PCI_VECTOR
+// 181-255 unused, as are all other holes
+
+//
+// HalpClockFrequency is the processor cycle counter frequency in units
+// of cycles per second (Hertz). It is a large number (e.g., 125,000,000)
+// but will still fit in a ULONG.
+//
+// HalpClockMegaHertz is the processor cycle counter frequency in units
+// of megahertz. It is a small number (e.g., 125) and is also the number
+// of cycles per microsecond. The assumption here is that clock rates will
+// always be an integral number of megahertz.
+//
+// Having the frequency available in both units avoids multiplications, or
+// especially divisions in time critical code.
+//
+
+extern ULONG HalpClockFrequency;
+extern ULONG HalpClockMegaHertz;
+//
+// Define the bus type, this value allows us to distinguish between
+// EISA and ISA systems.
+//
+ULONG HalpBusType = MACHINE_TYPE_ISA;
+
+//
+// Define global data used to communicate new clock rates to the clock
+// interrupt service routine.
+//
+
+ULONG HalpCurrentTimeIncrement;
+ULONG HalpNextRateSelect;
+ULONG HalpNextTimeIncrement;
+ULONG HalpNewTimeIncrement;
+
+
+VOID
+HalpInitializeHAERegisters(
+ VOID
+ );
+
+VOID
+HalpClearInterrupts(
+ );
+
+BOOLEAN
+HalpInitializeLegoInterrupts(
+ VOID
+ );
+
+VOID
+HalpParseLoaderBlock(
+ PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+VOID
+HalpRegisterPlatformResources(
+ VOID
+ );
+
+VOID
+HalpDetermineMachineType(
+ VOID
+ );
+
+
+BOOLEAN
+HalpInitializeInterrupts (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes interrupts for a Lego/K2 system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ A value of TRUE is returned if the initialization is successfully
+ completed. Otherwise a value of FALSE is returned.
+
+--*/
+
+{
+
+ UCHAR DataByte;
+ ULONG DataLong;
+ ULONG Index;
+ ULONG Irq;
+ KIRQL Irql;
+ UCHAR Priority;
+ ULONG Vector;
+
+ //
+ // Initialize HAL private data from the PCR. This must be done before
+ // HalpStallExecution is called.
+ //
+
+ //
+ // Compute integral megahertz first to
+ // avoid rounding errors due to imprecise cycle clock period values.
+ //
+
+ HalpClockMegaHertz =
+ ((1000 * 1000) + (PCR->CycleClockPeriod >> 1)) / PCR->CycleClockPeriod;
+ HalpClockFrequency = HalpClockMegaHertz * (1000 * 1000);
+
+ //
+ // Connect the Stall interrupt vector to the clock. When the
+ // profile count is calculated, we then connect the normal
+ // clock.
+
+ PCR->InterruptRoutine[CLOCK2_LEVEL] = HalpStallInterrupt;
+
+ //
+ // Clear all pending interrupts
+ //
+
+ HalpClearInterrupts();
+
+ //
+ // Start the peridodic interrupt from the RTC
+ //
+ HalpProgramIntervalTimer(MAXIMUM_RATE_SELECT);
+
+//jnfix, wkc - init the Eisa interrupts after the chip, don't init the
+// PIC here, fix halenablesysteminterrupt to init the pic
+// interrrupt, as in sable
+
+ //
+ // Initialize the PCI/ISA interrupt controller.
+ //
+
+ HalpInitializeLegoInterrupts();
+
+ //
+ // Initialize the 21064 interrupts.
+ //
+
+ HalpInitialize21064Interrupts();
+
+ HalpEnable21064SoftwareInterrupt( Irql = APC_LEVEL );
+
+ HalpEnable21064SoftwareInterrupt( Irql = DISPATCH_LEVEL );
+
+ HalpEnable21064HardwareInterrupt( Irq = 5,
+ Irql = SERVER_MGMT_LEVEL,
+ Vector = SERVER_MGMT_VECTOR,
+ Priority = 0 );
+
+ HalpEnable21064HardwareInterrupt( Irq = 4,
+ Irql = CLOCK_LEVEL,
+ Vector = CLOCK_VECTOR,
+ Priority = 0 );
+
+ HalpEnable21064HardwareInterrupt( Irq = 3,
+ Irql = HIGH_LEVEL,
+ Vector = EISA_NMI_VECTOR,
+ Priority = 0 );
+
+ HalpEnable21064HardwareInterrupt( Irq = 2,
+ Irql = DEVICE_LEVEL,
+ Vector = PIC_VECTOR,
+ Priority = 0 );
+
+ if (HalpLegoPciRoutingType == PCI_INTERRUPT_ROUTING_FULL) {
+
+ HalpEnable21064HardwareInterrupt( Irq = 1,
+ Irql = PCI_DEVICE_LEVEL,
+ Vector = PCI_VECTOR,
+ Priority = 0 );
+#if DBG
+ } else {
+ DbgPrint("Irq 1 disabled -- PCI interrupts via SIO\n");
+#endif
+ }
+
+ return TRUE;
+
+}
+
+
+VOID
+HalpClearInterrupts(
+ )
+/*++
+
+Routine Description:
+
+ This function no longer does anything.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ return;
+}
+
+
+VOID
+HalpSetTimeIncrement(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This routine is responsible for setting the time increment for an EV4
+ based machine via a call into the kernel.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ //
+ // Set the time increment value.
+ //
+
+ HalpCurrentTimeIncrement = MAXIMUM_INCREMENT;
+ HalpNextTimeIncrement = MAXIMUM_INCREMENT;
+ HalpNextRateSelect = 0;
+ KeSetTimeIncrement( MAXIMUM_INCREMENT, MINIMUM_INCREMENT );
+
+}
+
+//
+// Define global data used to calibrate and stall processor execution.
+//
+
+ULONG HalpProfileCountRate;
+
+VOID
+HalpInitializeClockInterrupts(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called during phase 1 initialization to complete
+ the initialization of clock interrupts. For EV4, this function
+ connects the true clock interrupt handler and initializes the values
+ required to handle profile interrupts.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ LEGO_WATCHDOG WdRegister;
+
+ //
+ // Compute the profile interrupt rate.
+ //
+
+ HalpProfileCountRate = ((1000 * 1000 * 10) / KeQueryTimeIncrement());
+
+ //
+ // Set the time increment value and connect the real clock interrupt
+ // routine.
+ //
+
+ PCR->InterruptRoutine[CLOCK2_LEVEL] = HalpClockInterrupt;
+
+ //
+ // If desired, turn on the watchdog timer
+ //
+
+ if (HalpLegoServiceWatchdog) {
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+ WdRegister.Enabled = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All);
+
+ }
+
+ return;
+}
+
+VOID
+HalpEstablishErrorHandler(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This routine performs the initialization necessary for the HAL to
+ begin servicing machine checks.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ BOOLEAN ReportCorrectables;
+
+ //
+ // Connect the machine check handler via the PCR.
+ //
+
+ PCR->MachineCheckError = HalMachineCheck;
+
+ //
+ // Initialize error handling for APECS.
+ //
+
+ HalpInitializeMachineChecks( ReportCorrectables = TRUE );
+
+ return;
+}
+
+VOID
+HalpInitializeMachineDependent(
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+/*++
+
+Routine Description:
+
+ This function performs any EV4-specific initialization based on
+ the current phase on initialization.
+
+Arguments:
+
+ Phase - Supplies an indicator for phase of initialization, phase 0 or
+ phase 1.
+
+ LoaderBlock - supplies a pointer to the loader block.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ UCHAR MsgBuffer[MAX_INIT_MSG];
+ CHAR MhzString[9];
+
+ if( Phase == 0 ){
+
+ //
+ // Phase 0 Initialization.
+ //
+
+ //
+ // Parse the Loader Parameter block looking for PCI entry to determine
+ // if PCI parity should be disabled
+ //
+ HalpParseLoaderBlock( LoaderBlock );
+
+ //
+ // Re-establish the error handler, to reflect the parity checking
+ //
+ HalpEstablishErrorHandler();
+
+ HalpInitializeHAERegisters();
+
+ //
+ // Determine what flavor platform we are on
+ //
+ HalpDetermineMachineType();
+
+ } else {
+
+ //
+ // Phase 1 Initialization.
+ //
+
+ //
+ // Initialize the existing bus handlers.
+ //
+ HalpRegisterInternalBusHandlers();
+
+ //
+ // Initialize PCI Bus.
+ //
+ HalpInitializePCIBus (LoaderBlock);
+
+ //
+ // Initialize profiler.
+ //
+ HalpInitializeProfiler();
+
+ //
+ // Print out a cool-o message
+ //
+
+ sprintf(MsgBuffer,
+ "Digital Equipment Corporation %s %s\n",
+ HalpFamilyName,
+ HalpProductName);
+
+ HalDisplayString(MsgBuffer);
+
+ //
+ // Display system speed on the OCP
+ //
+
+ sprintf (MhzString, " 4A/%3d ", HalpClockMegaHertz);
+ HalpOcpInitDisplay();
+ HalpOcpPutSlidingString(MhzString,8);
+
+ //
+ // Register HAL name and I/O resources
+ //
+
+ HalpRegisterPlatformResources();
+
+ }
+
+ return;
+}
+
+
+
+VOID
+HalpRegisterPlatformResources(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Register I/O resources used by the HAL.
+
+Arguments:
+
+ HalName - Supplies a pointer to the name for the HAL.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ RESOURCE_USAGE Resource;
+ UCHAR HalName[256];
+
+ //
+ // Register the buses.
+ //
+
+ HalpRegisterBusUsage(Internal);
+ HalpRegisterBusUsage(Isa);
+ HalpRegisterBusUsage(PCIBus);
+
+ //
+ // Register the name of the HAL.
+ //
+
+ sprintf(HalName,
+ "%s %s, %d Mhz, PCI/ISA HAL\n",
+ HalpFamilyName,
+ HalpProductName,
+ HalpClockMegaHertz );
+
+ HalpRegisterHalName( HalName );
+
+ //
+ // Report the apecs mapping to the Io subsystem
+ //
+ // This is the PCI Memory space that cannot be used by anyone
+ // and therefore the HAL says it is reserved for itself
+ //
+ //[wem] ??? check register resource for PCI memory ?
+ //
+
+ Resource.BusType = PCIBus;
+ Resource.BusNumber = 0;
+ Resource.ResourceType = CmResourceTypeMemory;
+ Resource.Next = NULL;
+ Resource.u.Start = __8MB;
+ Resource.u.Length = __32MB - __8MB;
+ HalpRegisterResourceUsage(&Resource);
+
+ //
+ // Register the interrupt vector used for the cascaded interrupt
+ // on the 8254s.
+ //
+
+ Resource.BusType = Isa;
+ Resource.BusNumber = 0;
+ Resource.ResourceType = CmResourceTypeInterrupt;
+ Resource.u.InterruptMode = Latched;
+ Resource.u.BusInterruptVector = 2;
+ Resource.u.SystemInterruptVector = 2;
+ Resource.u.SystemIrql = 2;
+ HalpRegisterResourceUsage(&Resource);
+
+ //
+ // Register machine specific io/memory addresses.
+ //
+
+ Resource.BusType = Isa;
+ Resource.BusNumber = 0;
+ Resource.ResourceType = CmResourceTypePort;
+ Resource.u.Start = I2C_INTERFACE_DATA_PORT;
+ Resource.u.Length = I2C_INTERFACE_LENGTH;
+ HalpRegisterResourceUsage(&Resource);
+
+//[wem] ??? What is this?
+// Resource.u.Start = SUPERIO_INDEX_PORT;
+// Resource.u.Length = SUPERIO_PORT_LENGTH;
+// HalpRegisterResourceUsage(&Resource);
+
+ //
+ // Register the DMA channel used for the cascade.
+ //
+
+ Resource.BusType = Isa;
+ Resource.BusNumber = 0;
+ Resource.ResourceType = CmResourceTypeDma;
+ Resource.u.DmaPort = 0x0;
+ Resource.u.DmaChannel = 0x4;
+ HalpRegisterResourceUsage(&Resource);
+}
+
+
+VOID
+HalpStallInterrupt (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function serves as the stall calibration interrupt service
+ routine. It is executed in response to system clock interrupts
+ during the initialization of the HAL layer.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ HalpAcknowledgeClockInterrupt();
+
+ return;
+}
+
+
+ULONG
+HalSetTimeIncrement (
+ IN ULONG DesiredIncrement
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to set the clock interrupt rate to the frequency
+ required by the specified time increment value.
+
+Arguments:
+
+ DesiredIncrement - Supplies desired number of 100ns units between clock
+ interrupts.
+
+Return Value:
+
+ The actual time increment in 100ns units.
+
+--*/
+
+{
+ ULONG NewTimeIncrement;
+ ULONG NextRateSelect;
+ KIRQL OldIrql;
+
+ //
+ // Raise IRQL to the highest level, set the new clock interrupt
+ // parameters, lower IRQl, and return the new time increment value.
+ //
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ if (DesiredIncrement < MINIMUM_INCREMENT) {
+ DesiredIncrement = MINIMUM_INCREMENT;
+ }
+ if (DesiredIncrement > MAXIMUM_INCREMENT) {
+ DesiredIncrement = MAXIMUM_INCREMENT;
+ }
+
+ //
+ // Find the allowed increment that is less than or equal to
+ // the desired increment.
+ //
+ if (DesiredIncrement >= RTC_PERIOD_IN_CLUNKS4) {
+ NewTimeIncrement = RTC_PERIOD_IN_CLUNKS4;
+ NextRateSelect = RTC_RATE_SELECT4;
+ } else if (DesiredIncrement >= RTC_PERIOD_IN_CLUNKS3) {
+ NewTimeIncrement = RTC_PERIOD_IN_CLUNKS3;
+ NextRateSelect = RTC_RATE_SELECT3;
+ } else if (DesiredIncrement >= RTC_PERIOD_IN_CLUNKS2) {
+ NewTimeIncrement = RTC_PERIOD_IN_CLUNKS2;
+ NextRateSelect = RTC_RATE_SELECT2;
+ } else {
+ NewTimeIncrement = RTC_PERIOD_IN_CLUNKS1;
+ NextRateSelect = RTC_RATE_SELECT1;
+ }
+
+ HalpNextRateSelect = NextRateSelect;
+ HalpNewTimeIncrement = NewTimeIncrement;
+
+ KeLowerIrql(OldIrql);
+
+ return NewTimeIncrement;
+}
+
+
+VOID
+HalpInitializeHAERegisters(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This function initializes the HAE registers in the EPIC/APECS chipset.
+
+Arguments:
+
+ none
+
+Return Value:
+
+ none
+
+--*/
+{
+ //
+ // We set HAXR1 to 0. This means no address extension
+ //
+
+ WRITE_EPIC_REGISTER( &((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->Haxr1, 0);
+
+ //
+ // We set HAXR2 to 0. Which means we have the following
+ // PCI IO addresses:
+ // 0 to 64KB VALID. HAXR2 Not used in address translation
+ // 64K to 16MB VALID. HAXR2 is used in the address translation
+ //
+
+ WRITE_EPIC_REGISTER( &((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->Haxr2, 0);
+
+#if 0
+#if DBG
+ DumpEpic();
+#endif // DBG
+#endif
+}
+
+
+VOID
+HalpResetHAERegisters(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This function resets the HAE registers in the EPIC/APECS chipset to 0.
+ This is routine called during a shutdown so that the prom
+ gets a predictable environment.
+
+Arguments:
+
+ none
+
+Return Value:
+
+ none
+
+--*/
+{
+ WRITE_EPIC_REGISTER( &((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->Haxr1, 0 );
+ WRITE_EPIC_REGISTER( &((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->Haxr2, 0 );
+}
+
+
+VOID
+HalpGetMachineDependentErrorFrameSizes(
+ PULONG RawProcessorSize,
+ PULONG RawSystemInfoSize
+ )
+/*++
+
+Routine Description:
+
+ This function returns the size of the system specific structures.
+
+
+Arguments:
+
+ RawProcessorSize - Pointer to a buffer that will receive the
+ size of the processor specific error information buffer.
+
+ RawSystemInfoSize - Pointer to a buffer that will receive the
+ size of the system specific error information buffer.
+
+Return Value:
+
+ none
+
+--*/
+{
+ *RawProcessorSize = sizeof(PROCESSOR_EV4_UNCORRECTABLE);
+ *RawSystemInfoSize = sizeof(APECS_UNCORRECTABLE_FRAME);
+ return;
+}
+
+
+VOID
+HalpGetSystemInfo(SYSTEM_INFORMATION *SystemInfo)
+/*++
+
+Routine Description:
+
+ This function fills in the System information.
+
+
+Arguments:
+
+ SystemInfo - Pointer to the SYSTEM_INFORMATION buffer that needs
+ to be filled in.
+
+Return Value:
+
+ none
+
+--*/
+{
+ char systemtype[] = "LegoK2"; // 8 char max.
+ EXTENDED_SYSTEM_INFORMATION FwExtSysInfo;
+
+
+ VenReturnExtendedSystemInformation(&FwExtSysInfo);
+
+ RtlCopyMemory(SystemInfo->FirmwareRevisionId,
+ FwExtSysInfo.FirmwareVersion,
+ 16);
+
+ RtlCopyMemory(SystemInfo->SystemType,systemtype, 8);
+
+ SystemInfo->ClockSpeed =
+ ((1000 * 1000) + (PCR->CycleClockPeriod >> 1)) / PCR->CycleClockPeriod;
+
+ SystemInfo->SystemRevision = PCR->SystemRevision;
+
+ RtlCopyMemory(SystemInfo->SystemSerialNumber,
+ PCR->SystemSerialNumber,
+ 16);
+
+ SystemInfo->SystemVariant = PCR->SystemVariant;
+
+
+ SystemInfo->PalMajorVersion = PCR->PalMajorVersion;
+ SystemInfo->PalMinorVersion = PCR->PalMinorVersion;
+
+ SystemInfo->OsRevisionId = VER_PRODUCTBUILD;
+
+ //
+ // For now fill in dummy values.
+ //
+ SystemInfo->ModuleVariant = 1UL;
+ SystemInfo->ModuleRevision = 1UL;
+ SystemInfo->ModuleSerialNumber = 0;
+
+ return;
+}
+
+VOID
+HalpInitializeUncorrectableErrorFrame (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Allocate an Uncorrectable Error frame for this
+ system and initializes the frame with certain constant/global
+ values.
+
+ Called during machine dependent system initialization.
+
+Arguments:
+
+ none
+
+Return Value:
+
+ none
+
+--*/
+{
+ PROCESSOR_EV4_UNCORRECTABLE processorFrame;
+ APECS_UNCORRECTABLE_FRAME LegoUnCorrrectable; //[wem] used?
+
+ //
+ // If the Uncorrectable error buffer is not set then simply return
+ //
+ if(PUncorrectableError == NULL)
+ return;
+
+ PUncorrectableError->Signature = ERROR_FRAME_SIGNATURE;
+
+ PUncorrectableError->FrameType = UncorrectableFrame;
+
+ //
+ // ERROR_FRAME_VERSION is define in errframe.h and will
+ // change as and when there is a change in the errframe.h.
+ // This Version number helps the service, that reads this
+ // information from the dumpfile, to check if it knows about
+ // this frmae version type to decode. If it doesn't know, it
+ // will dump the entire frame to the EventLog with a message
+ // "Error Frame Version Mismatch".
+ //
+
+ PUncorrectableError->VersionNumber = ERROR_FRAME_VERSION;
+
+ //
+ // The sequence number will always be 1 for Uncorrectable errors.
+ //
+
+ PUncorrectableError->SequenceNumber = 1;
+
+ //
+ // The PerformanceCounterValue field is not used for Uncorrectable
+ // errors.
+ //
+
+ PUncorrectableError->PerformanceCounterValue = 0;
+
+ //
+ // We will fill in the UncorrectableFrame.SystemInfo here.
+ //
+
+ HalpGetSystemInfo(&PUncorrectableError->UncorrectableFrame.System);
+
+ PUncorrectableError->UncorrectableFrame.Flags.SystemInformationValid = 1;
+
+ return;
+}
+
+
+VOID
+HalpDetermineMachineType(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Determine which Lego variant of backplane and cpu we're on
+ and set HalpLegoCpu, HalpLegoBackplane, HalpLegoCpuType,
+ and HalpLegoBackplaneType accordingly.
+
+Arguments:
+
+ None.
+
+Return value:
+
+ None.
+
+Notes:
+
+ [wem] ??? Missing - method of detecting OCP Display from HAL
+
+--*/
+{
+ PSYSTEM_ID SystemId;
+ PUCHAR ProductId;
+ LEGO_SRV_MGMT SmRegister;
+ LEGO_WATCHDOG WdRegister;
+ BOOLEAN PsuMask;
+ UCHAR temp;
+
+ //
+ // Get the ProductId, and see if it is one of the
+ // Lego strings.
+ //
+ // Product ID is only eight characters!
+ //
+
+ SystemId = ArcGetSystemId();
+
+ ProductId = &SystemId->ProductId[0];
+
+#if DBG
+ DbgPrint("ProductId: %s, product type: ",ProductId);
+#endif
+
+ if (strstr(ProductId,PLATFORM_NAME_K2_ATA)!=0) {
+
+#if DBG
+ DbgPrint("K2+Atacama");
+#endif
+
+ HalpLegoCpu = TRUE;
+ HalpLegoBackplane = TRUE;
+ HalpLegoCpuType = CPU_LEGO_K2;
+ HalpLegoBackplaneType = BACKPLANE_ATACAMA;
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_FULL;
+
+ } else if (strstr(ProductId,PLATFORM_NAME_K2_GOBI)!=0) {
+
+#if DBG
+ DbgPrint("K2+Gobi");
+#endif
+
+ HalpLegoCpu = TRUE;
+ HalpLegoBackplane = TRUE;
+ HalpLegoCpuType = CPU_LEGO_K2;
+ HalpLegoBackplaneType = BACKPLANE_GOBI;
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_FULL;
+
+ } else if (strstr(ProductId,PLATFORM_NAME_K2_SAHA)!=0) {
+
+#if DBG
+ DbgPrint("K2+Sahara");
+#endif
+
+ HalpLegoCpu = TRUE;
+ HalpLegoBackplane = TRUE;
+ HalpLegoCpuType = CPU_LEGO_K2;
+ HalpLegoBackplaneType = BACKPLANE_SAHARA;
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_FULL;
+
+ } else if (strstr(ProductId,PLATFORM_NAME_LEGO_K2)!=0) {
+
+#if DBG
+ DbgPrint("K2+unknown backplane");
+#endif
+
+ HalpLegoCpu = TRUE;
+ HalpLegoBackplane = FALSE;
+ HalpLegoCpuType = CPU_LEGO_K2;
+ HalpLegoBackplaneType = BACKPLANE_UNKNOWN;
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_SIO;
+
+ } else {
+
+#if DBG
+ DbgPrint("unknown cpu, unknown backplane");
+#endif
+ HalpLegoCpu = FALSE;
+ HalpLegoBackplane = FALSE;
+ HalpLegoCpuType = CPU_UNKNOWN;
+ HalpLegoBackplaneType = BACKPLANE_UNKNOWN;
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_SIO;
+
+ }
+
+#if DBG
+ DbgPrint("\n");
+#endif
+
+ //
+ // Read environment variable to get PCI Interrupt Routing
+ //
+ // If environment variable is absent or unreadable, use
+ // default setting of PCI_INTERRUPT_ROUTING_SIO
+ //
+ {
+ ARC_STATUS Status;
+ CHAR Buffer[16];
+
+ Status = HalGetEnvironmentVariable ("LGPCII",16,Buffer);
+
+#if DBG
+ DbgPrint("Get LGPCII = %s\n",Buffer);
+#endif
+
+ if (Status==ESUCCESS) {
+
+ if (tolower(*Buffer) == 's') {
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_SIO;
+ }
+ else if (tolower(*Buffer) == 'f') {
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_FULL;
+ }
+ else if (tolower(*Buffer) == 'd') {
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_DIRECT;
+ }
+ else {
+ //
+ // Bad setting
+ //
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_SIO;
+ }
+ }
+ else {
+ //
+ // No setting - use default
+ //
+ HalpLegoPciRoutingType = PCI_INTERRUPT_ROUTING_SIO;
+ }
+ }
+
+ HalDisplayString ("DMCC Interrupt Routing: ");
+
+ HalDisplayString ((HalpLegoPciRoutingType==PCI_INTERRUPT_ROUTING_SIO) ? "ISA PIRQs" :
+ (HalpLegoPciRoutingType==PCI_INTERRUPT_ROUTING_DIRECT) ? "Interrupt Registers" :
+ (HalpLegoPciRoutingType==PCI_INTERRUPT_ROUTING_FULL) ? "Interrupt Accelerator" : "Unknown!");
+
+ HalDisplayString ("\n");
+
+#if DBG
+ DbgPrint("\n");
+ DbgPrint("Interrupt Routing is via ");
+ DbgPrint((HalpLegoPciRoutingType == PCI_INTERRUPT_ROUTING_SIO)
+ ? "SIO.\n\r" : "Interrupt accelerator.\n\r");
+#endif
+
+ // Setup feature mask
+ //
+ HalpLegoFeatureMask = 0;
+ if (HalpLegoCpu) {
+
+ // Is watchdog timer present?
+ //
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+ if (WdRegister.All != 0xffff) {
+ HalpLegoFeatureMask |= LEGO_FEATURE_WATCHDOG;
+ }
+
+ // Is server management register present?
+ //
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ if (SmRegister.All != 0xffff) {
+ HalpLegoFeatureMask |= LEGO_FEATURE_SERVER_MGMT;
+
+ // Is multiple PSU support present?
+ // Write 0 then 1 into PSU mask bit, and read it
+ // back each time to see if setting sticks.
+ //
+ PsuMask = (SmRegister.PsuMask == 1); // save setting
+ SmRegister.PsuMask = 0; // clear mask
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+
+ if (SmRegister.PsuMask == 0) {
+ //
+ // mask bit is cleared
+ //
+ SmRegister.PsuMask = 1; // set mask
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+
+ if (SmRegister.PsuMask == 1) {
+ //
+ // mask bit is set. Feature is
+ // present, restore mask bit's original setting
+ //
+ HalpLegoFeatureMask |= LEGO_FEATURE_PSU;
+ SmRegister.PsuMask = (PsuMask) ? 1 : 0;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+ }
+ }
+ }
+ temp = HalpLegoFeatureMask;
+ if (temp != 0) {
+ HalDisplayString ("DMCC Platform Features: ");
+ if ((temp & LEGO_FEATURE_WATCHDOG) != 0) {
+ temp &= ~LEGO_FEATURE_WATCHDOG;
+ HalDisplayString ("Watchdog Timer");
+ HalDisplayString ((temp!=0)?", ":".");
+ }
+ if ((temp & LEGO_FEATURE_SERVER_MGMT) != 0) {
+ temp &= ~LEGO_FEATURE_SERVER_MGMT;
+ HalDisplayString ("Server Management");
+ HalDisplayString ((temp!=0)?", ":".");
+ }
+ if ((HalpLegoFeatureMask & LEGO_FEATURE_PSU) != 0) {
+ HalDisplayString ("Multiple PSU Support.");
+ }
+ HalDisplayString ("\n");
+ } else {
+ HalDisplayString("No LEGO Platform Features detected!\n");
+ }
+
+ if ((HalpLegoFeatureMask & LEGO_FEATURE_WATCHDOG) != 0) {
+
+ //
+ // Read environment variable to get Watchdog Timer setting
+ //
+ // If environment variable is absent or unreadable, use
+ // default setting of NOT HalpLegoServiceWatchdog
+ //
+
+ {
+ ARC_STATUS Status;
+ CHAR Buffer[16];
+
+ Status = HalGetEnvironmentVariable ("LGWD",16,Buffer);
+
+ #if DBG
+ DbgPrint("Get LGWD = %s\n",Buffer);
+ #endif
+
+ if (Status==ESUCCESS) {
+
+ if (Buffer[0]=='0') {
+ HalpLegoServiceWatchdog = TRUE;
+ HalpLegoWatchdogSingleMode = FALSE;
+ }
+ else if (Buffer[0]=='1') {
+ HalpLegoServiceWatchdog = TRUE;
+ HalpLegoWatchdogSingleMode = TRUE;
+ }
+ else {
+ HalpLegoServiceWatchdog = FALSE;
+ }
+
+ //
+ // Check for special debug variable -- if set,
+ // don't service the watchdog in the clock ISR
+ //
+
+ Status = HalGetEnvironmentVariable ("LGWDD",16,Buffer);
+
+ if (Status==ESUCCESS) {
+ LegoDebugWatchdogIsr = TRUE;
+ }
+ else {
+ LegoDebugWatchdogIsr = FALSE;
+ }
+
+ }
+ else {
+ //
+ // No setting - use default
+ //
+
+ HalpLegoServiceWatchdog = FALSE;
+ HalpLegoWatchdogSingleMode = FALSE;
+ LegoDebugWatchdogIsr = FALSE;
+ }
+ }
+
+ HalDisplayString("DMCC Watchdog Timer is ");
+ if (HalpLegoServiceWatchdog) {
+ HalDisplayString("active ");
+ HalDisplayString((HalpLegoWatchdogSingleMode)
+ ? "(single timeout)."
+ : "(double timeout).");
+ }
+ else {
+ HalDisplayString("inactive.");
+ }
+ HalDisplayString("\n");
+ }
+ else {
+ HalpLegoServiceWatchdog = FALSE;
+ }
+ }
+}
diff --git a/private/ntos/nthals/hallego/alpha/lgintr.s b/private/ntos/nthals/hallego/alpha/lgintr.s
new file mode 100644
index 000000000..f9de5d6ef
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/lgintr.s
@@ -0,0 +1,121 @@
+// TITLE("Lego PCI/ServerMgmt Interrupt Handler")
+//++
+//
+// Copyright (c) 1994,1995 Digital Equipment Corporation
+//
+// Module Name:
+//
+// lgintr.s
+//
+// Abstract:
+//
+// This module implements first level interrupt handlers for Lego
+//
+// Author:
+//
+// Joe Notarangelo 08-Jul-1993
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+// 29-Apr-1994 James Livingston
+// Adapt from Avanti ebintr.s for Mikasa
+//
+// 3-Nov-1995 Gene Morgan
+// Initial version for Lego. Adapt from Mikasa's mkintr.s,
+// add Server Management dispatch.
+//
+//--
+
+#include "halalpha.h"
+
+ SBTTL("Lego PCI Interrupt Handler")
+//++
+//
+// VOID
+// HalpPciInterruptHandler
+// IN PKINTERRUPT Interrupt,
+// IN PVOID ServiceContext
+// )
+//
+// Routine Description:
+//
+// This function is executed as the result of an interrupt on the PCI I/O
+// bus. The function is responsible for calling HalpPciDispatch to
+// appropriately dispatch the interrupt.
+//
+// N.B. This function exists only to capture the trap frame and forward
+// the interrupt to HalpPciDispatch.
+//
+// Arguments:
+//
+// Interrupt (a0) - Supplies a pointer to the interrupt object.
+//
+// ServiceContext (a1) - Supplies a pointer to the service context for
+// PCI interrupts.
+//
+// TrapFrame (fp/s6) - Supplies a pointer to the trap frame for
+// the interrupt.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpPciInterruptHandler)
+
+ bis fp, zero, a2 // capture trap frame as argument
+ br zero, HalpPciDispatch // dispatch the interrupt to the PCI handler
+
+ ret zero, (ra) // will never get here
+
+ .end HalpPciInterruptHandler
+
+
+ SBTTL("Lego Server Management Interrupt Handler")
+//++
+//
+// VOID
+// HalpPciInterruptHandler
+// IN PKINTERRUPT Interrupt,
+// IN PVOID ServiceContext
+// )
+//
+// Routine Description:
+//
+// This function is executed as the result of an interrupt on the
+// CPU IRQ pin allocated to Lego Server Management functions.
+// The function is responsible for calling HalpServerMgmtDispatch() to
+// appropriately dispatch the interrupt.
+//
+// N.B. This function exists only to capture the trap frame and forward
+// the interrupt to HalpServerMgmtDispatch.
+//
+// Arguments:
+//
+// Interrupt (a0) - Supplies a pointer to the interrupt object.
+//
+// ServiceContext (a1) - Supplies a pointer to the service context for
+// Server Management interrupts.
+//
+// TrapFrame (fp/s6) - Supplies a pointer to the trap frame for
+// the interrupt.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpServerMgmtInterruptHandler)
+
+ bis fp, zero, a2 // capture trap frame as argument
+ br zero, HalpServerMgmtDispatch // dispatch the interrupt to the PCI handler
+
+ ret zero, (ra) // will never get here
+
+ .end HalpServerMgmtInterruptHandler
diff --git a/private/ntos/nthals/hallego/alpha/lgintsup.c b/private/ntos/nthals/hallego/alpha/lgintsup.c
new file mode 100644
index 000000000..2b2e73beb
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/lgintsup.c
@@ -0,0 +1,732 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+Copyright (c) 1992,1993,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ lgintsup.c
+
+Abstract:
+
+ The module provides the interrupt support for Lego systems.
+
+Author:
+
+ Eric Rehm (DEC) 29-December-1993
+
+Revision History:
+
+ James Livingston (DEC) 30-Apr-1994
+ Adapted from Avanti module for Mikasa.
+
+ Janet Schneider (Digital) 27-July-1995
+ Added support for the Noritake.
+
+ Gene Morgan (Digital) 25-Oct-1995
+ Initial version for Lego. Adapted from Mikasa's mkintsup.c.
+
+ Gene Morgan 15-Apr-1996
+ Service watchdog timer.
+
+--*/
+
+#include "halp.h"
+#include "eisa.h"
+#include "ebsgdma.h"
+#include "legodef.h"
+#include "pcrtc.h"
+#include "pintolin.h"
+
+//
+// Server management and watchdog timer control
+//
+extern PVOID HalpLegoServerMgmtQva;
+extern PVOID HalpLegoWatchdogQva;
+
+extern BOOLEAN HalpLegoServiceWatchdog;
+extern BOOLEAN HalpLegoWatchdogSingleMode;
+extern BOOLEAN LegoDebugWatchdogIsr;
+
+extern BOOLEAN HalpLegoDispatchNmi;
+extern BOOLEAN HalpLegoDispatchHalt;
+
+//
+// Global to control whether halt button triggers breakpoint
+// 0 -> no breakpoint
+// !0 -> breakpoint when halt button is pressed
+//
+ULONG HalpHaltButtonBreak = 0;
+
+//
+// PCI Interrupt control
+//
+extern PVOID HalpLegoPciInterruptConfigQva;
+extern PVOID HalpLegoPciInterruptMasterQva;
+extern PVOID HalpLegoPciInterruptRegisterBaseQva;
+extern PVOID HalpLegoPciInterruptRegisterQva[];
+extern PVOID HalpLegoPciIntMaskRegisterQva[];
+
+//
+// Import globals declared in HalpMapIoSpace.
+//
+
+extern PVOID HalpServerControlQva;
+
+// Count NMI interrupts
+//
+ULONG NMIcount = 0;
+
+// Declare the interrupt structures and spinlocks for the intermediate
+// interrupt dispatchers.
+//
+KINTERRUPT HalpPciInterrupt;
+KINTERRUPT HalpServerMgmtInterrupt;
+
+// The following is the interrupt object used for DMA controller interrupts.
+// DMA controller interrupts occur when a memory parity error occurs or a
+// programming error occurs to the DMA controller.
+//
+KINTERRUPT HalpEisaNmiInterrupt;
+
+//
+// Declare the interrupt handler for the PCI bus. The interrupt dispatch
+// routine, HalpPciDispatch, is called from this handler.
+//
+
+BOOLEAN
+HalpPciInterruptHandler(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+//
+// Declare the interrupt handler for Server Management and Watchdog Timer
+// functions. The interrupt dispatch routine, HalpServermgmtDispatch, is
+// called from this handler.
+//
+
+BOOLEAN
+HalpServerMgmtInterruptHandler(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+//
+// Declare the interrupt handler for the EISA bus. The interrupt dispatch
+// routine, HalpEisaDispatch, is called from this handler.
+//
+
+BOOLEAN
+HalpEisaInterruptHandler(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+//
+// The following function initializes NMI handling.
+//
+
+VOID
+HalpInitializeNMI(
+ VOID
+ );
+
+//
+// The following function is called when an EISA NMI occurs.
+//
+
+BOOLEAN
+HalHandleNMI(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+VOID
+HalpInitializePciInterrupts(
+ VOID
+ );
+
+VOID
+HalpInitializeServerMgmtInterrupts(
+ VOID
+ );
+
+
+//
+// External routines
+//
+
+BOOLEAN
+LegoServerMgmtDelayedShutdown(
+ ULONG DelaySeconds
+ );
+
+VOID
+LegoServerMgmtReportFatalError(
+ USHORT SmRegAll
+ );
+
+
+
+BOOLEAN
+HalpInitializeLegoInterrupts(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the structures necessary for EISA & PCI operations
+ and connects the intermediate interrupt dispatchers. It also initializes
+ the ISA interrupt controller; Lego's SIO-based interrupt controller is
+ compatible with Avanti and with the EISA interrupt contoller used on Jensen.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the second level interrupt dispatchers are connected, then a value of
+ TRUE is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+ KIRQL oldIrql;
+
+ //
+ // Initialize the EISA NMI interrupt.
+ //
+
+ HalpInitializeNMI();
+
+ //
+ // Directly connect the ISA interrupt dispatcher to the level for
+ // ISA bus interrupt.
+ //
+ // N.B. This vector is reserved for exclusive use by the HAL (see
+ // interrupt initialization.
+ //
+
+ PCR->InterruptRoutine[PIC_VECTOR] = HalpSioDispatch;
+ HalEnableSystemInterrupt(PIC_VECTOR, ISA_DEVICE_LEVEL, LevelSensitive);
+
+ //
+ // Initialize the interrupt dispatchers for PCI & Server management interrupts.
+ //
+
+ KeInitializeInterrupt( &HalpPciInterrupt,
+ HalpPciInterruptHandler,
+ (PVOID) HalpLegoPciInterruptMasterQva, // Service Context
+ (PKSPIN_LOCK)NULL,
+ PCI_VECTOR,
+ PCI_DEVICE_LEVEL,
+ PCI_DEVICE_LEVEL,
+ LevelSensitive,
+ TRUE,
+ 0,
+ FALSE
+ );
+
+ if (!KeConnectInterrupt( &HalpPciInterrupt )) {
+ return(FALSE);
+ }
+
+ KeInitializeInterrupt( &HalpServerMgmtInterrupt,
+ HalpServerMgmtInterruptHandler,
+ (PVOID) HalpLegoServerMgmtQva, // Service Context is...
+ (PKSPIN_LOCK)NULL,
+ SERVER_MGMT_VECTOR,
+ SERVER_MGMT_LEVEL,
+ SERVER_MGMT_LEVEL,
+ LevelSensitive,
+ TRUE,
+ 0,
+ FALSE
+ );
+
+ if (!KeConnectInterrupt( &HalpServerMgmtInterrupt )) {
+ return(FALSE);
+ }
+
+ //
+ // Intitialize interrupt controller
+ //
+
+ KeRaiseIrql(ISA_DEVICE_LEVEL, &oldIrql);
+
+ //
+ // We must initialize the SIO's PICs, for ISA interrupts.
+ //
+
+ HalpInitializeSioInterrupts();
+
+ //
+ // There's no initialization required for the Lego PCI interrupt
+ // "controller," as it's the wiring of the hardware, rather than a
+ // PIC like the 82c59 that directs interrupts. We do set the IMR to
+ // zero to disable all interrupts, initially.
+ //
+
+ HalpInitializePciInterrupts();
+
+ //
+ // Setup server management interrupts.
+ // On return, server management interrupts will be unmasked,
+ // but secondary dispatch will not be performed unless appropriate
+ // boolean has been set due to enable call.
+ //
+
+ HalpInitializeServerMgmtInterrupts();
+
+ //
+ // Restore the IRQL.
+ //
+
+ KeLowerIrql(oldIrql);
+
+ //
+ // Initialize the EISA DMA mode registers to a default value.
+ // Disable all of the DMA channels except channel 4 which is the
+ // cascade of channels 0-3.
+ //
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Dma1BasePort.AllMask,
+ 0x0F
+ );
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Dma2BasePort.AllMask,
+ 0x0E
+ );
+
+ return(TRUE);
+}
+
+
+VOID
+HalpInitializeNMI(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This function is called to intialize SIO NMI interrupts.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+--*/
+{
+ UCHAR DataByte;
+
+ //
+ // Initialize the SIO NMI interrupt.
+ //
+
+ KeInitializeInterrupt( &HalpEisaNmiInterrupt,
+ HalHandleNMI,
+ NULL,
+ NULL,
+ EISA_NMI_VECTOR,
+ EISA_NMI_LEVEL,
+ EISA_NMI_LEVEL,
+ LevelSensitive,
+ FALSE,
+ 0,
+ FALSE
+ );
+
+ //
+ // Don't fail if the interrupt cannot be connected.
+ //
+
+ KeConnectInterrupt( &HalpEisaNmiInterrupt );
+
+ //
+ // Clear the Eisa NMI disable bit. This bit is the high order of the
+ // NMI enable register. Note that the other bits should be left as
+ // they are, according to the chip's documentation.
+ //
+ //[wem] ?? Avanti simply writes zero to NmiEnable -- OK
+
+ DataByte = READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
+ ((PNMI_ENABLE)(&DataByte))->NmiDisable = 0;
+ WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, DataByte);
+
+#ifdef DBG
+ DbgPrint("HalpIntializeNMI: wrote 0x%x to NmiEnable\n", DataByte);
+#endif
+
+}
+
+BOOLEAN
+HalHandleNMI(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ )
+/*++
+
+Routine Description:
+
+ This function is called when an EISA NMI occurs. It prints the
+ appropriate status information and bugchecks.
+
+Arguments:
+
+ Interrupt - Supplies a pointer to the interrupt object
+
+ ServiceContext - Bug number to call bugcheck with.
+
+Return Value:
+
+ Returns TRUE.
+
+--*/
+{
+ LEGO_SRV_MGMT SmRegister;
+ UCHAR NmiControl, NmiStatus;
+ BOOLEAN GotSerr, GotIochk, GotSmFan, GotSmTemp, GotHalt;
+
+ NMIcount++;
+
+#if DBG
+ if (NMIcount<5) {
+ DbgPrint("II<NMI><");
+ }
+ if (NMIcount % 100 == 0) {
+ DbgPrint("II<NMI><%08x><", NMIcount);
+ }
+#endif
+
+ GotSerr = GotIochk = GotSmFan = GotSmTemp = GotHalt = FALSE;
+
+ //
+ // Set the Eisa NMI disable bit. We do this to mask further NMI
+ // interrupts while we're servicing this one.
+ //
+ NmiControl = READ_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
+ ((PNMI_ENABLE)(&NmiControl))->NmiDisable = 1;
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, NmiControl);
+
+#ifdef DBG
+ DbgPrint("HalHandleNMI: wrote 0x%x to NmiEnable\n", NmiControl);
+#endif
+
+ NmiStatus =
+ READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);
+
+ if (NmiStatus & 0x80) {
+ GotSerr = TRUE;
+
+#ifdef DBG
+ DbgPrint("HalHandleNMI: Parity Check / Parity Error\n");
+ DbgPrint("HalHandleNMI: NMI Status = 0x%x\n", NmiStatus);
+#endif
+ HalAcquireDisplayOwnership(NULL);
+ HalDisplayString ("NMI: Parity Check / Parity Error\n");
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+ return (TRUE);
+ }
+
+ if (NmiStatus & 0x40) {
+ GotIochk = TRUE;
+#ifdef DBG
+ DbgPrint("HalHandleNMI: Channel Check / IOCHK\n");
+ DbgPrint("HalHandleNMI: NMI Status = 0x%x\n", NmiStatus);
+#endif
+ HalAcquireDisplayOwnership(NULL);
+ HalDisplayString ("NMI: Channel Check / IOCHK\n");
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+ return (TRUE);
+ }
+
+ // Read server management register
+ // Events that can be reported as NMI are:
+ // Enclosure temperature too high
+ // CPU Fan failure
+ //
+ // For now, generate a bugcheck.
+ // [wem] Future: perform secondary dispatch to give
+ // driver shot at reporting problem.
+ //
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+
+ GotSmFan = SmRegister.CpuFanFailureNmi == 1;
+ GotSmTemp = SmRegister.EnclTempFailureNmi == 1;
+
+ if (GotSmFan || GotSmTemp) {
+
+#ifdef DBG
+ DbgPrint("HalHandleNMI: Server management NMI\n");
+ DbgPrint("HalHandleNMI: NMI Status = 0x%x\n", NmiStatus);
+ DbgPrint("HalHandleNMI: Server Management Status = 0x%x\n", SmRegister);
+#endif
+
+ //
+ // If secondary dispatch enabled, do it now.
+ //
+#if 0
+ if (HalpLegoDispatchNmi
+ && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[SM_ERROR_VECTOR])(
+ PCR->InterruptRoutine[SM_ERROR_VECTOR],
+ TrapFrame)
+ ) {
+ return TRUE;
+ }
+#endif
+
+ //
+ // Build uncorrectable error frame and
+ // prepare for orderly shutdown
+ //
+ // The delayed shutdown depends on watchdog timer support
+ // A power off cannot be directly done since KeBugChk() turns
+ // off interrupts, so there's no way to get control back.
+ //
+ // WARNING: Pick a delay that allows a dump to complete.
+ //
+
+ LegoServerMgmtReportFatalError(SmRegister.All);
+ LegoServerMgmtDelayedShutdown(8); // Issue reset in 8 seconds
+
+ HalAcquireDisplayOwnership(NULL);
+
+ HalDisplayString ("NMI: Hardware Failure -- ");
+ HalDisplayString ((SmRegister.CpuFanFailureNmi==1) ? "CPU fan failed."
+ : "Enclosure termperature too high.");
+ HalDisplayString ("\nSystem Power Down will be attempted in 8 seconds...\n\n");
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+ return (TRUE);
+ }
+
+
+ //
+ // Halt button was hit.
+ //
+ // [wem] Perform second-level dispatch here too?
+ //
+ if (!GotSerr && !GotIochk && !GotSmFan && !GotSmTemp) {
+
+ //
+ // If secondary dispatch enabled, do it now.
+ //
+#if 0
+ if (HalpLegoDispatchHalt
+ && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[HALT_BUTTON_VECTOR])(
+ PCR->InterruptRoutine[HALT_BUTTON_VECTOR],
+ TrapFrame)
+ ) {
+ return TRUE;
+ }
+#endif
+
+ GotHalt = TRUE;
+ HalDisplayString ("NMI: Halt button pressed.\n");
+
+ if (HalpHaltButtonBreak) {
+ DbgBreakPoint();
+ }
+
+ return (TRUE);
+ }
+
+ //
+ // Clear and re-enable SERR# and IOCHK#, then re-enable NMI
+ //
+
+#ifdef DBG
+ DbgPrint("HalHandleNMI: Shouldn't get here!\n");
+#endif
+
+ if (GotSerr) {
+#ifdef DBG
+ DbgPrint("HalHandleNMI: Resetting SERR#; NMI count = %d\n", NMIcount);
+#endif
+ //
+ // Reset SERR# (and disable it), then re-enable it.
+ //
+ WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x04);
+ WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);
+ }
+
+ if (GotIochk) {
+#ifdef DBG
+ DbgPrint("HalHandleNMI: Resetting IOCHK#; NMI count = %d\n", NMIcount);
+#endif
+ //
+ // Reset IOCHK# (and disable it), then re-enable it.
+ //
+ WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x08);
+ WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);
+ }
+
+ if (GotSmFan || GotSmTemp) {
+ //
+ // Reset Server management condition.
+ //
+ // Interrupt must be cleared or the NMI will continue
+ // to occur.
+ //
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ if (GotSmFan) {
+ SmRegister.CpuFanFailureNmi = 1;
+ }
+ else {
+ SmRegister.EnclTempFailureNmi = 1;
+ }
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+ }
+
+ //
+ // Clear the Eisa NMI disable bit. This re-enables NMI interrupts,
+ // now that we're done servicing this one.
+ //
+ NmiControl = READ_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
+ ((PNMI_ENABLE)(&NmiControl))->NmiDisable = 0;
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, NmiControl);
+#ifdef DBG
+ DbgPrint("HalHandleNMI: wrote 0x%x to NmiEnable\n", NmiControl);
+#endif
+
+ return(TRUE);
+}
+
+VOID
+HalpAcknowledgeClockInterrupt(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Acknowledge the clock interrupt from the interval timer. The interval
+ timer for Lego comes from the Dallas real-time clock.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ LEGO_WATCHDOG WdRegister;
+
+ static LEGO_WATCHDOG WdRegisterDbg;
+ static ULONG DbgWdCnt = 0;
+ static ULONG WdNextService = 0;
+ static BOOLEAN WdIntervalSet = FALSE;
+
+ //
+ // Make watchdog service interval a function of the timer period.
+ //
+
+#if 1
+ static ULONG WdServiceIntervals[8] = {1, 1, 5, 15, 100, 600, 3000, 20000};
+#else
+ static ULONG WdServiceIntervals[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+#endif
+
+ //
+ // Acknowledge the clock interrupt by reading the control register C of
+ // the Real Time Clock.
+ //
+
+ HalpReadClockRegister( RTC_CONTROL_REGISTERC );
+
+ //
+ // If we are to service the Watchdog Timer, do it here
+ //
+ // Setting Phase to one will restart the timer...
+ // [wem] this needs more work. For example, no need to touch it each clock tick!...
+ //
+
+ if (HalpLegoServiceWatchdog) {
+
+ if (WdNextService==0) {
+
+ //
+ // read register to get service interval
+ //
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+ WdNextService = WdServiceIntervals[WdRegister.TimerOnePeriod];
+
+#if DBG
+ if (!WdIntervalSet) {
+ DbgPrint(" <Watchdog:%04x> ",WdRegister.All);
+ DbgPrint(" <WdInterval:%d> ",WdNextService);
+ WdRegisterDbg.All = WdRegister.All;
+ WdIntervalSet = TRUE;
+ }
+#endif
+ }
+
+ WdNextService--;
+
+ //
+ // If service interval falls to zero, read register to service timer
+ //
+
+ if (WdNextService==0) {
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+
+#if DBG
+
+ if (WdRegisterDbg.All != WdRegister.All) {
+ WdRegisterDbg.All = WdRegister.All;
+ DbgWdCnt = 0;
+ }
+
+ if (DbgWdCnt < 2) {
+ DbgPrint(" <Watchdog:%04x> ",WdRegister.All);
+ }
+
+ if ((DbgWdCnt % 10000)==0) {
+ DbgPrint(" <Watchdog:%04x> ",WdRegister.All);
+ DbgWdCnt = 1;
+ }
+
+ DbgWdCnt++;
+#endif
+
+ //
+ // Reset the timer. This is done by writing 1 then 0
+ // to the Watchdog register's Phase bit
+ //
+ // If LegoDebugWatchdogIsr is true, let watchdog timer expire.
+ // This will result in a watchdog interrupt or a system reset
+ // depending on the watchdog mode.
+ //
+
+ if (!LegoDebugWatchdogIsr) {
+#if 0
+ if (HalpLegoWatchdogSingleMode) {
+ WdRegister.Mode = WATCHDOG_MODE_1TIMER;
+ }
+#endif
+ WdRegister.Phase = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All);
+ WdRegister.Phase = 0;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All);
+ }
+ }
+ }
+}
diff --git a/private/ntos/nthals/hallego/alpha/lgmapio.c b/private/ntos/nthals/hallego/alpha/lgmapio.c
new file mode 100644
index 000000000..02f14a08b
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/lgmapio.c
@@ -0,0 +1,232 @@
+/*++
+
+Copyright (c) 1993 Digital Equipment Corporation
+
+Module Name:
+
+ lgmapio.c
+
+Abstract:
+
+ This module contains the functions to map HAL-accessed I/O addresses
+ on the Lego systems.
+
+Author:
+
+ Joe Notarangelo 25-Oct-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ Gene Morgan [Digital] 11-Oct-1995
+
+ Initial version for Lego. Adapted from Avanti and Mikasa
+
+
+--*/
+
+#include "halp.h"
+#include "legodef.h"
+
+//
+// Define global data used to locate the EISA control space.
+//
+
+PVOID HalpEisaControlBase;
+PVOID HalpEisaIntAckBase;
+PVOID HalpCMOSRamBase;
+
+//
+// SIO's Int Ack Register (if it exists)
+//
+// Used when interrupt accelerator is active, and we
+// must not generate PCI Interrupt Acknowledge cycles
+// for ISA devices.
+//
+
+PVOID HalpSioIntAckQva;
+
+//
+// Server management and watchdog timer control
+//
+PVOID HalpLegoServerMgmtQva;
+PVOID HalpLegoWatchdogQva;
+
+//
+// PCI Interrupt control
+//
+PVOID HalpLegoPciInterruptConfigQva;
+PVOID HalpLegoPciInterruptMasterQva;
+PVOID HalpLegoPciInterruptRegisterBaseQva;
+PVOID HalpLegoPciInterruptRegisterQva[4];
+PVOID HalpLegoPciIntMaskRegisterQva[4];
+
+
+BOOLEAN
+HalpMapIoSpace (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the HAL I/O space for Lego
+ system using the Quasi VA mechanism.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the initialization is successfully completed, than a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+ PVOID PciIoSpaceBase;
+
+ //
+ // Map base addresses in QVA space.
+ //
+
+ PciIoSpaceBase = HAL_MAKE_QVA( APECS_PCI_IO_BASE_PHYSICAL );
+
+ HalpEisaControlBase = PciIoSpaceBase;
+
+ //
+ // Interrupt Acknowledge ports
+ //
+
+ HalpEisaIntAckBase = HAL_MAKE_QVA( APECS_PCI_INTACK_BASE_PHYSICAL );
+ HalpSioIntAckQva = (PVOID)((ULONG)PciIoSpaceBase + 0x238);
+
+ //
+ // CMOS ram addresses encoded in nvram.c - kept for commonality
+ // in environ.c
+ //
+ //[wem] NOTE: halavant version of ebmapio.c sets HalpCMOSRamBase to (PVOID)0 ???
+ //
+
+ HalpCMOSRamBase = (PVOID) ((ULONG)PciIoSpaceBase + CMOS_ISA_PORT_ADDRESS);
+
+ //
+ // Map the real-time clock registers.
+ //
+
+ HalpRtcAddressPort = (PVOID)((ULONG)PciIoSpaceBase + RTC_ISA_ADDRESS_PORT);
+ HalpRtcDataPort = (PVOID)((ULONG)PciIoSpaceBase + RTC_ISA_DATA_PORT);
+
+ //
+ // Map Lego server management and watchog control registers
+ //
+
+ HalpLegoServerMgmtQva = (PVOID)((ULONG)PciIoSpaceBase | SERVER_MANAGEMENT_REGISTER);
+ HalpLegoWatchdogQva = (PVOID)((ULONG)PciIoSpaceBase | WATCHDOG_REGISTER);
+
+ //
+ // Map Lego PCI Interrupt control registers
+ //
+
+ HalpLegoPciInterruptConfigQva = (PVOID)((ULONG)PciIoSpaceBase | PCI_INTERRUPT_CONFIG_REGISTER);
+ HalpLegoPciInterruptMasterQva = (PVOID)((ULONG)PciIoSpaceBase | PCI_INTERRUPT_MASTER_REGISTER);
+ HalpLegoPciInterruptRegisterBaseQva = (PVOID)((ULONG)PciIoSpaceBase | PCI_INTERRUPT_BASE_REGISTER);
+
+ //
+ // Lego PCI interrupt state and interrupt mask registers
+ //
+ // NOTE: The InterruptRegister Qvas can be used to access the interrupt
+ // state (via USHORT), or the interrupt state and interrupt mask (via ULONG).
+ // The IntMaskRegister Qvas can only be used to access the interrupt
+ // mask (via USHORT).
+ //
+
+ HalpLegoPciIntMaskRegisterQva[0] =
+ (PVOID)((ULONG)HalpLegoPciInterruptRegisterBaseQva | PCI_INTMASK_REGISTER_1);
+ HalpLegoPciIntMaskRegisterQva[1] =
+ (PVOID)((ULONG)HalpLegoPciInterruptRegisterBaseQva | PCI_INTMASK_REGISTER_2);
+ HalpLegoPciIntMaskRegisterQva[2] =
+ (PVOID)((ULONG)HalpLegoPciInterruptRegisterBaseQva | PCI_INTMASK_REGISTER_3);
+ HalpLegoPciIntMaskRegisterQva[3] =
+ (PVOID)((ULONG)HalpLegoPciInterruptRegisterBaseQva | PCI_INTMASK_REGISTER_4);
+
+ HalpLegoPciInterruptRegisterQva[0] =
+ (PVOID)((ULONG)HalpLegoPciInterruptRegisterBaseQva | PCI_INTERRUPT_REGISTER_1);
+ HalpLegoPciInterruptRegisterQva[1] =
+ (PVOID)((ULONG)HalpLegoPciInterruptRegisterBaseQva | PCI_INTERRUPT_REGISTER_2);
+ HalpLegoPciInterruptRegisterQva[2] =
+ (PVOID)((ULONG)HalpLegoPciInterruptRegisterBaseQva | PCI_INTERRUPT_REGISTER_3);
+ HalpLegoPciInterruptRegisterQva[3] =
+ (PVOID)((ULONG)HalpLegoPciInterruptRegisterBaseQva | PCI_INTERRUPT_REGISTER_4);
+
+ return TRUE;
+
+}
+
+ULONG
+HalpMapDebugPort(
+ IN ULONG ComPort,
+ OUT PULONG ReadQva,
+ OUT PULONG WriteQva
+ )
+/*++
+
+Routine Description:
+
+ This routine maps the debug com port so that the kernel debugger
+ may function - if called it is called very earlier in the boot sequence.
+
+Arguments:
+
+ ComPort - Supplies the number of the com port to use as the debug port.
+
+ ReadQva - Receives the QVA used to access the read registers of the debug
+ port.
+
+ WriteQva - Receives the QVA used to access the write registers of the
+ debug port.
+
+Return Value:
+
+ Returns the base bus address of the device used as the debug port.
+
+--*/
+{
+ ULONG ComPortAddress;
+ ULONG PortQva;
+
+ //
+ // Compute the port address, based on the desired com port.
+ //
+
+ switch( ComPort ){
+
+ case 1:
+
+ ComPortAddress = COM1_ISA_PORT_ADDRESS;
+ break;
+
+ case 2:
+ default:
+
+ ComPortAddress = COM2_ISA_PORT_ADDRESS;
+
+ }
+
+ //
+ // Return the QVAs for read and write access.
+ //
+
+ PortQva = (ULONG)HAL_MAKE_QVA(APECS_PCI_IO_BASE_PHYSICAL) + ComPortAddress;
+
+ *ReadQva = PortQva;
+ *WriteQva = PortQva;
+
+ return ComPortAddress;
+
+}
diff --git a/private/ntos/nthals/hallego/alpha/lgsysint.c b/private/ntos/nthals/hallego/alpha/lgsysint.c
new file mode 100644
index 000000000..e735721bf
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/lgsysint.c
@@ -0,0 +1,679 @@
+/*++
+
+Copyright (c) 1993,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ lgsysint.c
+
+Abstract:
+
+ This module implements the HAL enable/disable system interrupt, and
+ request interprocessor interrupt routines for the Lego system.
+
+Author:
+
+ Joe Notarangelo 25-Oct-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ Gene Morgan [Digital] 11-Oct-1995
+ Initial version for Lego. Adapted from Avanti and Mikasa
+
+ Gene Morgan 15-Apr-1996
+ Remove debugging code.
+ Add error logging for server management events (e.g., fan and temp)
+
+
+--*/
+
+#include "halp.h"
+#include "legodef.h"
+#include "axp21064.h"
+
+
+
+extern ULONG HalpLegoPciRoutingType;
+extern BOOLEAN HalpServerMgmtLoggingEnabled;
+
+//
+// External function prototypes
+//
+
+ULONG
+HalpGet21064CorrectableVector(
+ IN ULONG BusInterruptLevel,
+ OUT PKIRQL Irql
+ );
+
+VOID
+HalpSetMachineCheckEnables(
+ IN BOOLEAN DisableMachineChecks,
+ IN BOOLEAN DisableProcessorCorrectables,
+ IN BOOLEAN DisableSystemCorrectables
+ );
+
+//
+// Local function prototypes
+//
+
+VOID
+HalpDisablePciInterrupt(
+ IN ULONG Vector
+ );
+
+VOID
+HalpDisableServerMgmtInterrupt(
+ IN ULONG Vector
+ );
+
+VOID
+HalpEnablePciInterrupt(
+ IN ULONG Vector,
+ IN KINTERRUPT_MODE InterruptMode
+ );
+
+VOID
+HalpEnableServerMgmtInterrupt(
+ IN ULONG Vector,
+ IN KINTERRUPT_MODE InterruptMode
+ );
+
+//
+// Define reference to the builtin device interrupt enables.
+//
+
+extern USHORT HalpBuiltinInterruptEnable;
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE,HalpGetSystemInterruptVector)
+#endif
+
+
+VOID
+HalDisableSystemInterrupt (
+ IN ULONG Vector,
+ IN KIRQL Irql
+ )
+
+/*++
+
+Routine Description:
+
+ This routine disables the specified system interrupt.
+
+Arguments:
+
+ Vector - Supplies the vector of the system interrupt that is disabled.
+
+ Irql - Supplies the IRQL of the interrupting source.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG Irq;
+ KIRQL OldIrql;
+
+ //
+ // Raise IRQL to the highest level.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ //
+ // If the vector number is within the range of the
+ // Server Management interrupts, then disable the appropriate
+ // interrupt.
+ //
+ if (Vector >= SERVER_MGMT_VECTORS &&
+ Vector < MAXIMUM_SERVER_MGMT_VECTOR &&
+ Irql == SERVER_MGMT_LEVEL) {
+
+#if DBG
+ DbgPrint("Dm<%02x>",Vector);
+#endif
+ HalpDisableServerMgmtInterrupt(Vector);
+ }
+
+ //
+ // If the vector number is within the range of the
+ // ISA interrupts, then disable the ISA interrupt.
+ //
+ else if (Vector >= ISA_DEVICE_VECTORS &&
+ Vector < MAXIMUM_ISA_VECTOR &&
+ Irql == ISA_DEVICE_LEVEL) {
+
+#if DBG
+ DbgPrint("Ds<%02x>",Vector);
+#endif
+ HalpDisableSioInterrupt(Vector);
+ }
+
+ //
+ // If the vector number is within the range of the
+ // PCI interrupts, then disable the PCI interrupt.
+ //
+ else if (Vector >= PCI_DEVICE_VECTORS &&
+ Vector < LEGO_MAXIMUM_PCI_VECTOR &&
+ Irql == PCI_DEVICE_LEVEL) {
+
+#if DBG
+ DbgPrint("Dp<%02x>",Vector);
+#endif
+ HalpDisablePciInterrupt(Vector);
+ }
+
+ //
+ // If the vector is a performance counter vector or one of the internal
+ // device vectors then disable the interrupt for the 21064.
+ //
+
+ else {
+
+ switch (Vector) {
+
+ //
+ // Performance counter 0 interrupt (internal to 21064)
+ //
+
+ case PC0_VECTOR:
+ case PC0_SECONDARY_VECTOR:
+
+#if DBG
+ DbgPrint("Dc0<%02x>",Vector);
+#endif
+ HalpDisable21064PerformanceInterrupt( PC0_VECTOR );
+ break;
+
+ //
+ // Performance counter 1 interrupt (internal to 21064)
+ //
+
+ case PC1_VECTOR:
+ case PC1_SECONDARY_VECTOR:
+
+#if DBG
+ DbgPrint("Dc1<%02x>",Vector);
+#endif
+ HalpDisable21064PerformanceInterrupt( PC1_VECTOR );
+ break;
+
+ case CORRECTABLE_VECTOR:
+
+ //
+ // Disable the correctable error interrupt.
+ //
+
+ {
+ EPIC_ECSR Ecsr;
+
+ Ecsr.all = READ_EPIC_REGISTER(
+ &((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->EpicControlAndStatusRegister );
+
+ Ecsr.Dcei = 0x0;
+
+ WRITE_EPIC_REGISTER(
+ &((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->EpicControlAndStatusRegister,
+ Ecsr.all );
+
+ HalpSetMachineCheckEnables( FALSE, TRUE, TRUE );
+
+ //
+ // Disable logging of server management errors as well
+ //
+
+ HalpServerMgmtLoggingEnabled = FALSE;
+
+ break;
+ }
+
+#if DBG
+ default:
+
+ //
+ // unrecognized
+ //
+
+ DbgPrint("D?<%02x>",Vector);
+#endif
+ } //end switch Vector
+ }
+
+ //
+ // Lower IRQL to the previous level.
+ //
+
+ KeLowerIrql(OldIrql);
+ return;
+}
+
+BOOLEAN
+HalEnableSystemInterrupt (
+ IN ULONG Vector,
+ IN KIRQL Irql,
+ IN KINTERRUPT_MODE InterruptMode
+ )
+
+/*++
+
+Routine Description:
+
+ This routine enables the specified system interrupt.
+
+Arguments:
+
+ Vector - Supplies the vector of the system interrupt that is enabled.
+
+ Irql - Supplies the IRQL of the interrupting source.
+
+ InterruptMode - Supplies the mode of the interrupt;
+ LevelSensitive or Latched.
+
+Return Value:
+
+ TRUE if the system interrupt was enabled
+
+--*/
+
+{
+ BOOLEAN Enabled = FALSE;
+ ULONG Irq;
+ KIRQL OldIrql;
+
+ //
+ // Raise IRQL to the highest level.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ //
+ // If the vector number is within the range of the
+ // Server Management interrupts, then enable the appropriate
+ // interrrupt.
+ //
+ if (Vector >= SERVER_MGMT_VECTORS &&
+ Vector < MAXIMUM_SERVER_MGMT_VECTOR &&
+ Irql == SERVER_MGMT_LEVEL) {
+
+#if DBG
+ DbgPrint("Em<%02x,%02x>",Vector,InterruptMode);
+#endif
+ HalpEnableServerMgmtInterrupt(Vector,InterruptMode);
+ Enabled = TRUE;
+ }
+
+ //
+ // If the vector number is within the range of the
+ // ISA interrupts, then enable the ISA interrupt and
+ // set the Level/Edge register.
+ //
+ else if (Vector >= ISA_DEVICE_VECTORS &&
+ Vector < MAXIMUM_ISA_VECTOR &&
+ Irql == ISA_DEVICE_LEVEL) {
+
+#if DBG
+ DbgPrint("Es<%02x,%02x>",Vector,InterruptMode);
+#endif
+ HalpEnableSioInterrupt( Vector, InterruptMode );
+ Enabled = TRUE;
+ }
+
+ //
+ // If the vector number is within the range of the
+ // PCI interrupts, then enable the PCI interrupt.
+ //
+ else if (Vector >= PCI_DEVICE_VECTORS &&
+ Vector < LEGO_MAXIMUM_PCI_VECTOR &&
+ Irql == PCI_DEVICE_LEVEL) {
+
+#if DBG
+ DbgPrint("Ep<%02x,%02x>",Vector,InterruptMode);
+#endif
+ HalpEnablePciInterrupt(Vector, InterruptMode);
+ Enabled = TRUE;
+ }
+
+ //
+ // If the vector is a performance counter vector or one of the
+ // internal device vectors then perform 21064-specific enable.
+ //
+ else {
+
+ switch (Vector) {
+
+ //
+ // Performance counter 0 (internal to 21064)
+ //
+
+ case PC0_VECTOR:
+ case PC0_SECONDARY_VECTOR:
+
+#if DBG
+ DbgPrint("Ec0<%02x,%02x>",Vector,Irql);
+#endif
+ HalpEnable21064PerformanceInterrupt( PC0_VECTOR, Irql );
+ Enabled = TRUE;
+ break;
+
+ //
+ // Performance counter 1 (internal to 21064)
+ //
+
+ case PC1_VECTOR:
+ case PC1_SECONDARY_VECTOR:
+
+#if DBG
+ DbgPrint("Ec1<%02x,%02x>",Vector,Irql);
+#endif
+ HalpEnable21064PerformanceInterrupt( PC1_VECTOR, Irql );
+ Enabled = TRUE;
+ break;
+
+ case CORRECTABLE_VECTOR:
+
+ //
+ // Enable the correctable error interrupt.
+ //
+
+ {
+ EPIC_ECSR Ecsr;
+
+ Ecsr.all = READ_EPIC_REGISTER(
+ &((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->EpicControlAndStatusRegister );
+
+ Ecsr.Dcei = 0x1;
+
+ WRITE_EPIC_REGISTER(
+ &((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->EpicControlAndStatusRegister,
+ Ecsr.all );
+
+ HalpSetMachineCheckEnables( FALSE, FALSE, FALSE );
+
+ //
+ // Will log server management errors as well
+ //
+
+ HalpServerMgmtLoggingEnabled = TRUE;
+
+ Enabled = TRUE;
+ break;
+
+ }
+
+#if DBG
+ default:
+
+ //
+ // not enabled
+ //
+
+ DbgPrint("E?<%02x,%02x,%02x>",Vector,Irql,InterruptMode);
+#endif
+
+ } //end switch Vector
+ }
+
+ //
+ // Lower IRQL to the previous level.
+ //
+
+ KeLowerIrql(OldIrql);
+ return Enabled;
+}
+
+ULONG
+HalpGetSystemInterruptVector(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ )
+
+/*++
+
+Routine Description:
+
+ This function returns the system interrupt vector and IRQL level
+ corresponding to the specified bus interrupt level and/or vector. The
+ system interrupt vector and IRQL are suitable for use in a subsequent call
+ to KeInitializeInterrupt.
+
+ We only use InterfaceType, and BusInterruptLevel. BusInterruptVector
+ for ISA and ISA are the same as the InterruptLevel, so ignore.
+
+Arguments:
+
+ BusHandler - Registered BUSHANDLER for the target configuration space
+
+ RootHandler - Registered BUSHANDLER for the orginating HalGetBusData
+ request.
+
+ BusInterruptLevel - Supplies the bus specific interrupt level.
+
+ BusInterruptVector - Supplies the bus specific interrupt vector.
+
+ Irql - Returns the system request priority.
+
+ Affinity - Returns the affinity for the requested vector
+
+Return Value:
+
+ Returns the system interrupt vector corresponding to the specified device.
+
+--*/
+
+{
+ INTERFACE_TYPE InterfaceType = BusHandler->InterfaceType;
+ ULONG BusNumber = BusHandler->BusNumber;
+
+ ULONG Vector;
+
+#if DBG
+ DbgPrint("GIV< l:%02x, v:%02x => ",
+ BusInterruptLevel,BusInterruptVector);
+#endif
+
+ *Affinity = 1;
+
+ switch (InterfaceType) {
+
+ case ProcessorInternal:
+
+ //
+ // Handle the internal defined for the processor itself
+ // and used to control the performance counters and
+ // correctable errors in the 21064.
+ //
+
+ Vector = HalpGet21064PerformanceVector(BusInterruptLevel,Irql);
+
+ if (Vector != 0) {
+
+#if DBG
+ DbgPrint("PIperf: i:%02x, v:%02x >.", Vector, *Irql);
+#endif
+
+ return Vector; // Performance counter interrupt
+ }
+
+ Vector = HalpGet21064CorrectableVector( BusInterruptLevel,Irql);
+
+ if (Vector != 0) {
+
+#if DBG
+ DbgPrint("PIcorr: i:%02x, v:%02x >.", Vector, *Irql);
+#endif
+
+ return Vector; // Correctable error interrupt
+ }
+
+ // Check for unrecognized processor interrupt.
+ //
+ if (Vector == 0) {
+ *Irql = 0;
+ *Affinity = 0;
+ }
+
+#if DBG
+ DbgPrint("PI: i:00, v:00 >.");
+#endif
+ return Vector; // zero if unrecognized interrupt
+
+ case Internal:
+
+ //
+ // This bus type is for things connected to the processor
+ // in some way other than a standard bus, e.g., (E)ISA, PCI.
+ // Since devices on this "bus," apart from the special case of
+ // the processor, above, interrupt via the 82c59 cascade in the
+ // ESC, we assign vectors based on (E)ISA_VECTORS - see below.
+ // Firmware must agree on these vectors, as it puts them in
+ // the CDS.
+ //
+ // Assume interrupt can be mapped to Lego System Management.
+ // [wem] ??? check this ?
+ //
+ *Irql = SERVER_MGMT_LEVEL;
+
+ // The vector is equal to the specified bus level plus
+ // SERVER_MGMT_VECTORS.
+ //
+#if DBG
+ DbgPrint("SM: i:%02x, v:%02x >.",
+ SERVER_MGMT_LEVEL,
+ BusInterruptLevel + SERVER_MGMT_VECTORS);
+#endif
+ return(BusInterruptLevel + SERVER_MGMT_VECTORS);
+
+ case PCIBus:
+
+ //[wem] if interrupt accelerator is enabled, direct
+ // PCI interrupts via the PCI_DEVICE_VECTORS
+ // Otherwise, fall into the ISA case...
+ //
+ if (HalpLegoPciRoutingType == PCI_INTERRUPT_ROUTING_FULL) {
+
+ //
+ // All PCI devices coming in on same CPU IRQ pin
+ //
+ *Irql = PCI_DEVICE_LEVEL;
+
+ //
+ // The vector is equal to the specified bus level
+ // plus the PCI Device Vector base
+ //
+#if DBG
+ DbgPrint("PCI: i:%02x, v:%02x >.",
+ PCI_DEVICE_LEVEL,
+ BusInterruptLevel + PCI_DEVICE_VECTORS);
+#endif
+ return((BusInterruptLevel) + PCI_DEVICE_VECTORS);
+
+#if DBG
+ } else {
+
+ //
+ // Fall into ISA interrupt handling code
+ //
+
+ DbgPrint("PCI*");
+#endif
+ }
+
+ case Isa:
+
+ //
+ // Assumes all ISA devices coming in on same pin
+ //
+ *Irql = ISA_DEVICE_LEVEL;
+
+ //
+ // The vector is equal to the specified bus level plus
+ // the ISA_VECTOR. This is assuming that the ISA levels
+ // not assigned Interrupt Levels in the Beta programming
+ // guide are unused in the LCA system. Otherwise, need
+ // a different encoding scheme.
+ //
+ // Not all interrupt levels are actually supported on Beta;
+ // Should we make some of them illegal here?
+ //
+
+#if DBG
+ DbgPrint("ISA: i:%02x, v:%02x >.",
+ ISA_DEVICE_LEVEL,
+ BusInterruptLevel + ISA_DEVICE_VECTORS);
+#endif
+ return(BusInterruptLevel + ISA_DEVICE_VECTORS);
+
+ case Eisa:
+
+ //[wem] Should never occur
+ //
+ // Assumes all EISA devices coming in on same pin
+ //
+ *Irql = EISA_DEVICE_LEVEL;
+
+ //
+ // The vector is equal to the specified bus level plus the EISA_VECTOR.
+ //
+ return(BusInterruptLevel + EISA_VECTORS);
+
+ default:
+
+ //
+ // Not an interface supported on Lego systems
+ //
+#if DBG
+ DbgPrint("LGSYSINT: InterfaceType (%d) not supported.\n",
+ InterfaceType);
+#endif
+#if DBG
+ DbgPrint("?: i:00, v:00 >.");
+#endif
+ *Irql = 0;
+ *Affinity = 0;
+ return(0);
+
+ } //end switch(InterfaceType)
+
+}
+
+VOID
+HalRequestIpi (
+ IN ULONG Mask
+ )
+
+/*++
+
+Routine Description:
+
+ This routine requests an interprocessor interrupt on a set of processors.
+ This routine performs no function on an Avanti because it is a
+ uni-processor system.
+
+Arguments:
+
+ Mask - Supplies the set of processors that are sent an interprocessor
+ interrupt.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ return;
+}
diff --git a/private/ntos/nthals/hallego/alpha/machdep.h b/private/ntos/nthals/hallego/alpha/machdep.h
new file mode 100644
index 000000000..264be0ec2
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/machdep.h
@@ -0,0 +1,46 @@
+/*++
+
+Copyright (c) 1993 Digital Equipment Corporation
+
+Module Name:
+
+ machdep.h
+
+Abstract:
+
+ This file includes the platform-dependent include files used to
+ build the HAL.
+
+Author:
+
+ Joe Notarangelo 01-Dec-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ Gene Morgan [Digital] 11-Oct-1995
+
+ Initial version for Lego. Adapted from Avanti.
+
+
+--*/
+
+#ifndef _MACHDEP_
+#define _MACHDEP_
+
+//
+// Include Lego platform-specific definitions.
+//
+
+#include "legodef.h"
+
+//
+// Include scatter/gather definitions.
+//
+
+#include "ebsgdma.h"
+
+#endif //_MACHDEP_
diff --git a/private/ntos/nthals/hallego/alpha/memory.c b/private/ntos/nthals/hallego/alpha/memory.c
new file mode 100644
index 000000000..76b1eb7df
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/memory.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\memory.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/nvenv.c b/private/ntos/nthals/hallego/alpha/nvenv.c
new file mode 100644
index 000000000..ba5a5c8f7
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/nvenv.c
@@ -0,0 +1 @@
+#include "..\halalpha\nvenv.c"
diff --git a/private/ntos/nthals/hallego/alpha/nvram.c b/private/ntos/nthals/hallego/alpha/nvram.c
new file mode 100644
index 000000000..879c41c68
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/nvram.c
@@ -0,0 +1 @@
+#include "..\halalpha\nvram.c"
diff --git a/private/ntos/nthals/hallego/alpha/pcd8584.c b/private/ntos/nthals/hallego/alpha/pcd8584.c
new file mode 100644
index 000000000..981a3aca3
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcd8584.c
@@ -0,0 +1,653 @@
+/*++
+
+Copyright (c) 1994,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ pcd8584.c
+
+Abstract:
+
+ This module contains the routines that support operations
+ on the PCD8584 I2C bus controller.
+
+Author:
+
+ James Livingston [DEC] 13-Sep-1994
+
+Environment:
+
+ Alpha AXP ARC firmware
+
+Revision History:
+
+ Gene Morgan (Digital) 08-Nov-1995
+ Adapted for LEGO platforms from Mikasa
+
+ Gene Morgan 15-Apr-1996
+ Cleanup, fix OCP corruption problem.
+
+
+--*/
+
+#include <stdarg.h>
+#include "halp.h"
+#include "string.h"
+#include "arccodes.h"
+#include "pcd8584.h"
+
+extern PVOID HalpEisaControlBase;
+
+BOOLEAN PcdValid = FALSE;
+
+//
+// I2C data and csr ports.
+//
+ULONG I2cInterfaceCsrPort;
+ULONG I2cInterfaceDataPort;
+
+//
+// Data for testing internal registers in the PCD8584 I2C bus controller.
+//
+I2C_TEST_REG I2cTestReg[] = { "CSR", I2C_STATUS, 0x3d, 0xff,
+ "S0", I2C_DATA, 0x7f, I2C_S0,
+ "S2", I2C_DATA, 0x1f, I2C_S2,
+ "S3", I2C_DATA, 0xff, I2C_S3,
+ };
+
+//
+// External prototypes
+//
+
+static VOID
+FwStallExecution (
+ IN ULONG MicroSeconds
+ )
+{
+ HalpStallExecution(MicroSeconds);
+}
+
+//
+// Private function prototypes
+//
+
+VOID
+FwPcdWrite(
+ IN UCHAR Argument,
+ IN UCHAR Register
+ );
+
+UCHAR
+FwPcdRead(
+ IN UCHAR Register
+ );
+
+ARC_STATUS
+FwPcdStatusWaitWithTimeout(
+ BOOLEAN BusIdle,
+ BOOLEAN PendingInterrupt,
+ BOOLEAN AckByte,
+ ULONG Timeout
+ );
+
+//
+// Code begins.
+//
+
+ARC_STATUS
+FwPcdInit(
+ ULONG I2cCsrPort,
+ ULONG I2cDataPort
+ )
+/*++
+
+Routine Description:
+
+ This function initializes the PCD8584 I2C controller for use in
+ writing to the LCD display on the Mikasa Operator Control Panel.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ ESUCCESS - Everything's ready to go.
+ ENODEV - Something's wrong.
+
+--*/
+
+{
+ UCHAR Datum;
+ UCHAR DataRead;
+ ARC_STATUS Status;
+ ULONG i;
+
+ //
+ // Set the csr and data port for I2C bus.
+ //
+ I2cInterfaceCsrPort = I2cCsrPort;
+ I2cInterfaceDataPort = I2cDataPort;
+
+#if 0 // Done by firmware -- don't do it again
+
+ //
+ // Write the PIN bit to "1", as Dave Baird discovered was a
+ // requirement some years back.
+ //
+ // This should turn off ESO
+ //
+ //[wem] ??? needed for Lego ?
+ //
+ FwPcdWrite(I2C_PIN, I2C_STATUS);
+ FwPcdWrite(I2C_PIN, I2C_STATUS);
+
+ //
+ // Initialize the PCD8584 with its own node address. A write
+ // to this register must be the first access to the device
+ // after a reset.
+ //
+ //[wem] OK for Lego.
+ //
+ Datum = (I2C_MASTER_NODE >> 1) & 0x7f;
+ FwPcdWrite(I2C_S0P, I2C_STATUS); //[wem] Lego spec recommends I2C_PIN also
+ FwPcdWrite(I2C_S0P, I2C_STATUS); //[wem] Lego spec recommends I2C_PIN also
+ FwPcdWrite(Datum, I2C_DATA);
+ FwPcdWrite(Datum, I2C_DATA);
+
+ //
+ // Define clock frequencies for the I2C bus. After this is done
+ // we should be able to write to a node on the bus.
+ //
+ //[wem] OK for Lego.
+ //
+ FwPcdWrite(I2C_S2, I2C_STATUS); //[wem] Lego spec recommends I2C_PIN also
+ FwPcdWrite(I2C_S2, I2C_STATUS); //[wem] Lego spec recommends I2C_PIN also
+ FwPcdWrite(I2C_CLOCK, I2C_DATA);
+ FwPcdWrite(I2C_CLOCK, I2C_DATA);
+
+ // jwlfix - this is to see what we can read from the PCD8584.
+ // We'll want to get rid of it when things start doing
+ // what we want. For now, it's a good verification that
+ // we're able to reach the device.
+ //
+ //[wem] If all the reads return 0xFF, assume no I2C bus is present (and return ENODEV)
+ //
+#if 0
+ for (i = 0; i < 4; i++) {
+ if (I2cTestReg[i].Setup != -1) {
+ FwPcdWrite(I2cTestReg[i].Setup, I2C_STATUS);
+ }
+ DataRead = FwPcdRead(I2cTestReg[i].Target);
+
+#ifdef DBG
+ DbgPrint("Pcd8584: register %s = 0x%2x\r\n", I2cTestReg[i].Name,
+ DataRead);
+#endif
+ if (DataRead != (UCHAR)0xFF) {
+ // Good.
+ PcdValid = TRUE;
+ }
+ }
+#else
+ PcdValid = TRUE;
+#endif
+
+ //
+ // Issue Stop command (twice)
+ //
+ //[wem] recommended for Lego.
+ //
+ FwPcdWrite(I2C_STOP, I2C_STATUS);
+ FwPcdWrite(I2C_STOP, I2C_STATUS);
+
+#if 0 //[wem] needed for Lego ?
+ //
+ // Now write communication initialization
+ // to the PCD8584 CSR (S1).
+ // This must be done only once, so we do it here.
+ //
+
+ FwPcdWrite(I2C_INIT, I2C_STATUS); //[wem] Lego spec recommends I2C_PIN | I2C_ACKB also
+#endif
+#endif
+
+ PcdValid = TRUE;
+
+ return ((PcdValid) ? ESUCCESS : ENODEV);
+}
+
+
+VOID
+FwPcdWrite(
+ UCHAR Argument,
+ UCHAR Register
+ )
+/*++
+
+Routine Description:
+
+ This function writes a byte to one of the two EISA interface
+ registers of the PCD8584 I2C bus controller.
+
+Arguments:
+
+ Argument - The byte to be written.
+
+ Register - Selector for the EISA port to be written.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ ULONG Offset = Register ? I2cInterfaceCsrPort : I2cInterfaceDataPort;
+
+ WRITE_PORT_UCHAR((PUCHAR)((ULONG)HalpEisaControlBase | Offset), Argument);
+
+ return;
+}
+
+UCHAR
+FwPcdRead(
+ UCHAR Register
+ )
+/*++
+
+Routine Description:
+
+ This function reads a byte from one of the two EISA interface
+ registers of the PCD8584 I2C bus controller.
+
+Arguments:
+
+ Register - Selector for the EISA port to be read.
+
+Return Value:
+
+ Character supplied by the PCD8584.
+
+--*/
+
+{
+ ULONG Offset = Register ? I2cInterfaceCsrPort : I2cInterfaceDataPort;
+ UCHAR Datum;
+
+ Datum = READ_PORT_UCHAR((PUCHAR)((ULONG)HalpEisaControlBase | Offset));
+
+ return Datum;
+}
+
+ARC_STATUS
+FwI2cWrite(
+ UCHAR Node,
+ UCHAR Datum
+ )
+/*++
+
+Routine Description:
+
+ This function sends a data byte to the specified node on the I2C bus.
+
+Arguments:
+
+ Node - The I2C address to which the data byte should go.
+
+ Datum - The data byte.
+
+Return Value:
+
+ ESUCCESS - The operation succeeded.
+ ENODEV - Something's wrong.
+
+--*/
+
+{
+ BOOLEAN BusIdle;
+ BOOLEAN PendingInterrupt;
+ BOOLEAN AckByte;
+ ARC_STATUS Status;
+ ULONG Timeout;
+ ULONG Count;
+
+#if 0
+ if (!PcdValid) return ENODEV;
+#endif
+
+ //
+ // Set timeout to 100ms.
+ //
+
+ Timeout = 100 * 1000;
+
+ //
+ // Mask off the low-order node number bit, then write the
+ // result to the PCD8584 DATA register.
+ //
+
+ Status = FwPcdStatusWaitWithTimeout( BusIdle = TRUE,
+ PendingInterrupt = FALSE,
+ AckByte = FALSE,
+ Timeout );
+ if( Status != ESUCCESS ){
+#if DBG
+ DbgPrint ("I2C: Timeout waiting for bus idle, status=%X\r\n",Status);
+#endif
+ return Status;
+ }
+
+ FwPcdWrite((Node & 0xfe) | I2C_WRITE_DIR, I2C_DATA);
+
+ //
+ // Now start up the PCD8584 communication with the specified node.
+ //
+ Count = 10;
+ while (1) {
+
+ FwPcdWrite(I2C_START, I2C_STATUS);
+
+ FwStallExecution(__1MSEC*1); // The device is picky about how quickly
+ // you may access it again.
+ // Wait for PIN to drop
+ //
+ //[wem] Lego repeated start inside loop -- is this OK ?
+ //[wem] Lego -- is 10ms long enough?
+ //
+ Status = FwPcdStatusWaitWithTimeout( BusIdle = FALSE,
+ PendingInterrupt = TRUE,
+ AckByte = FALSE,
+ 10 * 1000 );
+ if( Status == ESUCCESS){
+ break;
+ } else {
+ if (Count-- == 0) {
+#if DBG
+ DbgPrint ("I2C: Timeout during addr phase, status=%X\r\n",Status);
+#endif
+ return Status; // status from wait
+ }
+ }
+ }
+
+ //
+ // Write the desired datum onto the bus. We can do this lots of
+ // times, if we wish, without restarting the process. That'll be
+ // another direction of exploration, as time permits.
+ //
+
+
+ //[wem] Should check for LRB (lost arbitration) set before writing.
+ //[wem] If LRB set, then issue Stop.
+
+ FwPcdWrite(Datum, I2C_DATA);
+ FwPcdWrite(I2C_START, I2C_STATUS);
+
+ //
+ //[wem] Wait for PIN to drop
+ //
+
+ FwStallExecution(__1MSEC*1); // The device is picky about how quickly
+ // you may access it again.
+
+ Status = FwPcdStatusWaitWithTimeout( BusIdle = FALSE,
+ PendingInterrupt = TRUE,
+ AckByte = FALSE,
+ Timeout );
+ if( Status != ESUCCESS ){
+#if DBG
+ DbgPrint ("I2C: Timeout during data phase, status=%X\r\n",Status);
+#endif
+ return Status; // status from wait
+ }
+
+ //
+ // Finally, close down the communication with the target node.
+ //
+ //[wem] If LRB is still clear, it is safe to issue
+ //[wem] another data write. Otherwise, must issue Stop.
+
+ FwStallExecution(__1MSEC*1); // The device is picky about how quickly
+
+ Count = 10;
+ while (1) {
+
+ FwPcdWrite(I2C_STOP, I2C_STATUS);
+
+ FwStallExecution(__1MSEC*1); // The device is picky about how quickly
+ // you may access it again.
+
+ // Wait for PIN to drop
+ //
+ //[wem] Lego repeated start inside loop -- is this OK ?
+ //[wem] Lego -- is 10ms long enough?
+ //
+ Status = FwPcdStatusWaitWithTimeout( BusIdle = FALSE,
+ PendingInterrupt = TRUE,
+ AckByte = TRUE,
+ 10 * 1000 );
+ if( Status == ESUCCESS){
+ break;
+ } else {
+ if (Count-- == 0) {
+#if DBG
+ DbgPrint ("I2C: Timeout during stop, status=%X\r\n",Status);
+#endif
+ return Status; // status from wait
+ }
+ }
+ }
+
+ //
+ // And this writes just a single byte to the I2C bus; whew! We'd
+ // like to get smarter, when this works right.
+ //
+
+ return ESUCCESS;
+}
+
+ARC_STATUS
+FwI2cRead(
+ IN UCHAR Node,
+ OUT PUCHAR ReadDatum
+ )
+/*++
+
+Routine Description:
+
+ This function receives a single data byte from a node on
+ the I2C bus.
+
+Arguments:
+
+ Node - The I2C address from which the data byte should come.
+
+Return Value:
+
+ The data byte.
+
+--*/
+
+{
+ ARC_STATUS Status;
+
+ *ReadDatum = 0;
+ Status = ESUCCESS;
+
+ if (!PcdValid) return ENODEV;
+
+// jwlfix - currently unused function, and probably incorrect.
+#if 0
+ I2C_STATUS_BITS I2cStatus;
+
+ //
+ // Mask off the low-order node number bit, then write the
+ // result to the PCD8584 DATA register.
+ //
+ do {
+ I2cStatus.All = FwPcdRead(I2C_STATUS);
+ } while (I2cStatus.NotBusBusy == 0);
+ FwPcdWrite((Node & 0xfe) | I2C_READ_DIR, I2C_DATA);
+
+ //
+ // Now start up the PCD8584 communication with the specified node.
+ //
+ do {
+ I2cStatus.All = FwPcdRead(I2C_STATUS);
+ } while (I2cStatus.NotBusBusy == 0);
+ FwPcdWrite(I2C_START, I2C_STATUS);
+
+ //
+ // Read the desired datum from the bus: first wait for PIN to
+ // clear, then NACK the transmission, since we're only reading
+ // the single byte; next, read a byte. That byte is the
+ // address we wrote into the data port, increased by one. Why?
+ // Dunno; that's just what happens, currently.
+ //
+ do {
+ I2cStatus.All = FwPcdRead(I2C_STATUS);
+ } while (I2cStatus.NotPendingInterrupt == 1);
+ FwPcdWrite(I2C_NACK, I2C_STATUS);
+ ReadDatum = FwPcdRead(I2C_DATA);
+ //
+ // Now we wait for PIN to clear, saying that we've received
+ // the byte acutally sent by the node, and then read that.
+ //
+ do {
+ I2cStatus.All = FwPcdRead(I2C_STATUS);
+ } while (I2cStatus.NotPendingInterrupt == 1);
+ ReadDatum = FwPcdRead(I2C_DATA);
+
+ //
+ // Finally, close down the communication with the target node.
+ //
+ FwPcdWrite(I2C_STOP, I2C_STATUS);
+#endif
+ return Status;
+}
+
+
+ARC_STATUS
+FwPcdStatusWaitWithTimeout (
+ BOOLEAN BusIdle,
+ BOOLEAN PendingInterrupt,
+ BOOLEAN AckByte,
+ ULONG Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for the desired I2C bus status state with a timeout value.
+
+ N.B. - This routine will only wait for one of the two states that
+ can be specified.
+
+Arguments:
+
+ BusIdle - Supplies a boolean that if true specifies that the
+ routine should wait for status to indicate that the bus is
+ not busy (NotBusBusy == 1).
+
+ PendingInterrupt - Supplies a boolean that if true specifies that
+ the routine should wait for status to indicate that
+ there is a pending interrupt (NotPendingInterrupt == 0).
+
+ AckByte - true indicates that the routine should wait for
+ status to indicate that status == PIN + ACKB
+
+ Timeout - Supplies the timeout value in microseconds.
+
+Return Value:
+
+ The status of the operation. ESUCCESS is returned if the specified
+ status is read on the bus before the timeout expires. EBUSY is
+ returned if the operation times out.
+
+Notes:
+
+ [wem] This routine should also check for lost arbitration.
+
+--*/
+
+{
+ LONG CyclesBeforeTimeout;
+ ULONG CycleCount;
+#if 0 //[wem] redundant?
+ extern ULONG HalpClockMegaHertz;
+#endif
+ ULONG ElapsedCycles;
+ I2C_STATUS_BITS I2cStatus;
+ ULONG PreviousCycleCount;
+ ARC_STATUS Status;
+ int MinLoopCnt;
+
+ //
+ // Compute Cycles to wait.
+ //
+
+ CyclesBeforeTimeout = Timeout * HalpClockMegaHertz;
+
+ //
+ // Capture initial time.
+ //
+
+ PreviousCycleCount = HalpRpcc();
+
+ //
+ // Continue the loop while waiting for the timeout. Assume timeout
+ // status.
+ //
+
+ Status = EBUSY;
+
+ while( CyclesBeforeTimeout > 0){
+
+ I2cStatus.All = FwPcdRead(I2C_STATUS);
+
+ //
+ // Check for bus not busy.
+ //
+
+ if( (BusIdle == TRUE) && (I2cStatus.NotBusBusy == 1) ){
+ Status = ESUCCESS;
+ break;
+ }
+
+ //
+ // Check for pending interrupt.
+ //
+ //[wem] AckByte case is to recognize successful
+ //[wem] stop command for Lego.
+ //
+
+ if (PendingInterrupt == TRUE) {
+ if (AckByte == TRUE) {
+ if (I2cStatus.NotPendingInterrupt == 1
+ && I2cStatus.NotBusBusy == 1) {
+ Status = ESUCCESS;
+ break;
+ }
+ } else {
+ if (I2cStatus.NotPendingInterrupt == 0) {
+ Status = ESUCCESS;
+ break;
+ }
+ }
+ }
+
+ //
+ // Update the number of cycles remaining before timeout.
+ //
+
+ CycleCount = HalpRpcc();
+ ElapsedCycles = CycleCount - PreviousCycleCount;
+ CyclesBeforeTimeout -= ElapsedCycles;
+ PreviousCycleCount = CycleCount;
+
+ }
+
+ return Status;
+
+}
diff --git a/private/ntos/nthals/hallego/alpha/pcd8584.h b/private/ntos/nthals/hallego/alpha/pcd8584.h
new file mode 100644
index 000000000..3344e42c5
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcd8584.h
@@ -0,0 +1,196 @@
+/*++
+
+Copyright (c) 1994 Digital Equipment Corporation
+
+Module Name:
+
+ pcd8584.h
+
+Abstract:
+
+ This module contains the definitions that support the PCD8584 I2C
+ bus controller.
+
+Author:
+
+ James Livingston [DEC] 13-Sep-1994
+
+Environment:
+
+ Alpha AXP ARC firmware
+
+Revision History:
+
+ Gene Morgan (Digital) 08-Nov-1995
+ Adapted for LEGO platforms from Mikasa
+
+--*/
+
+#if !defined (_LANGUAGE_ASSEMBLY)
+//
+// jwlfix - These definitions are used in unused test code.
+//
+typedef struct _I2C_TEST_REG {
+ PUCHAR Name;
+ ULONG Target;
+ UCHAR Mask;
+ UCHAR Setup;
+} I2C_TEST_REG, *PI2C_TEST_REG;
+
+//
+// The following definitions are used to program the PCD8584 I2C bus
+// controller.
+//
+typedef union _I2C_CONTROL_BITS{
+ struct {
+ UCHAR AckEachByte: 1;
+ UCHAR SendStop: 1;
+ UCHAR SendStart: 1;
+ UCHAR ExtInterruptEnable: 1;
+ UCHAR Reserved: 2;
+ UCHAR EnableSerialOutput: 1;
+ UCHAR NotPendingInterrupt: 1;
+ };
+ UCHAR All;
+} I2C_CONTROL_BITS, *PI2C_CONTROL_BITS;
+
+typedef union _I2C_STATUS_BITS{
+ struct {
+ UCHAR NotBusBusy: 1;
+ UCHAR LostArbitration: 1;
+ UCHAR AddressedAsSlave: 1;
+ UCHAR Address0LastRBit: 1;
+ UCHAR BusError: 1;
+ UCHAR ExternalStop: 1;
+ UCHAR Reserved: 1;
+ UCHAR NotPendingInterrupt: 1;
+ };
+ UCHAR All;
+} I2C_STATUS_BITS, *PI2C_STATUS_BITS;
+
+#endif // !defined (_LANGUAGE_ASSEMBLY)
+
+#define __1MSEC 1000
+#define __HALF_MSEC 500
+#define __1USEC 1
+
+#define I2C_DATA 0
+#define I2C_STATUS 1
+#define I2C_MASTER_NODE 0xb6
+
+//[wem] It probably doesn't matter, but I2C_MASTER_NODE
+//[wem] should be in machine dependent file.
+//#define I2C_MASTER_NODE 0xaa //[wem] as per LEGO spec
+
+//
+// Control register bit definitions
+//
+#define I2C_S0 0x00 // Data register
+#define I2C_S0P 0x00 // Own address register
+#define I2C_S2 0x20 // Clock register
+#define I2C_S3 0x10 // Interrupt vector register
+
+//
+// Clock register SCL (data clocking) frequency bit definitions
+//
+#define I2C_SCL_90 0x00 // 90 KHz
+#define I2C_SCL_45 0x01 // 45 KHz
+#define I2C_SCL_11 0x02 // 11 KHz
+#define I2C_SCL_15 0x03 // 1.5 KHz
+
+//
+// Clock register input clock frequency bit definitions.
+//
+#define I2C_CLOCK_3 0x00 // 3 MHz
+#define I2C_CLOCK_443 0x10 // 4.3 MHz
+#define I2C_CLOCK_6 0x14 // 6 MHz
+#define I2C_CLOCK_8 0x18 // 8 MHz
+#define I2C_CLOCK_12 0x1c // 12 MHz
+
+//
+// I2C bus control byte bit definitions
+//
+#define I2C_ACKB 0x01 // Ack each byte sent
+#define I2C_STO 0x02 // Send stop condition
+#define I2C_STA 0x04 // Send start condition
+#define I2C_ENI 0x08 // Enable external interrupt
+#define I2C_ESO 0x40 // Enable serial output
+#define I2C_PIN 0x80 // Pending interrupt NOT
+
+//
+// Data direction (PCD8584 state) flags
+//
+#define I2C_WRITE_DIR 0x00
+#define I2C_READ_DIR 0x01
+#define I2C_IDLE 0x02
+#define I2C_S_WRITE 0x03
+#define I2C_S_READ 0x04
+#define I2C_SR_DONE 0x0a
+
+//
+// Setup condition constants for this implementation.
+//
+// Dave Baird's and Carey McMasters' choices:
+//#define I2C_CLOCK (I2C_SCL_90 | I2C_CLOCK_6)
+//
+// LEGO Settings [wem] ??? check this ?
+//
+// I2C_CLOCK should be in machine-dependent section,
+// unlike the bulk of this file.
+//
+//#define I2C_CLOCK (I2C_SCL_90 | I2C_CLOCK_12)
+//
+#define I2C_CLOCK (I2C_SCL_90 | I2C_CLOCK_8)
+
+//
+// jwlfix - These would need to be defined as bit-field assignments,
+// e.g.,
+//
+// I2C_STOP:
+// ---------
+// ((PI2C_CONTROL_BITS)&Datum)->AckEachByte = 1;
+// ((PI2C_CONTROL_BITS)&Datum)->SendStop = 1;
+// ((PI2C_CONTROL_BITS)&Datum)->EnableSerialOutput = 1;
+// ((PI2C_CONTROL_BITS)&Datum)->NotPendingInterrupt = 1;
+//
+// for stylistic consistency. We'll see if that's a better
+// way to do it after the function's running. I suppose it's
+// a matter of what the compiler generates, in each case.
+//
+#define I2C_STOP (I2C_S0 | I2C_ESO | I2C_ACKB | I2C_STO | I2C_PIN)
+#if 0 //[wem] set PIN for Lego.
+#define I2C_START (I2C_S0 | I2C_ESO | I2C_ACKB | I2C_STA)
+#else
+#define I2C_START (I2C_S0 | I2C_ESO | I2C_ACKB | I2C_STA | I2C_PIN)
+#endif
+#define I2C_INIT (I2C_S0 | I2C_ESO)
+#define I2C_NACK (I2C_S0 | I2C_ESO)
+#define I2C_ACK (I2C_S0 | I2C_ESO | I2C_ACKB)
+
+#define I2C_MASTER_TYPE 0
+#define I2C_LED_TYPE 1
+
+//
+// Function prototypes
+//
+#if !defined (_LANGUAGE_ASSEMBLY)
+
+ARC_STATUS
+FwPcdInit(
+ ULONG I2cCsrPort,
+ ULONG I2cDataPort
+ );
+
+ARC_STATUS
+FwI2cWrite(
+ UCHAR Node,
+ UCHAR Datum
+ );
+
+ARC_STATUS
+FwI2cRead(
+ IN UCHAR Node,
+ OUT PUCHAR ReadDatum
+ );
+
+#endif // !defined (_LANGUAGE_ASSEMBLY)
diff --git a/private/ntos/nthals/hallego/alpha/pcf8574.c b/private/ntos/nthals/hallego/alpha/pcf8574.c
new file mode 100644
index 000000000..65f1f21ec
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcf8574.c
@@ -0,0 +1,336 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+Copyright (c) 1994,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ pcf8574.c
+
+Abstract:
+
+ This module contains the routines that operate the 8-character
+ display on Lego's Operator Console Panel.
+
+ The OCP display is implemented via two PCF8574's, which
+ drive the LED display, select which character position will
+ be written, and select which character to write.
+
+ This module uses a subset of interface defined in ocplcd.c for
+ Mikasa and others. Lego uses a much simpler device, so some of
+ the functions defined for Mikasa are not needed.
+
+Author:
+
+ Gene Morgan (Digital)
+
+Environment:
+
+ Alpha AXP ARC firmware.
+
+Revision History:
+
+ Gene Morgan (Digital) 11-Nov-1995
+ Initial version
+
+ Gene Morgan 15-Apr-1996
+ Cleanup, add HalpOcpTestDisplay() and HalpOcpPutSlidingString()
+
+--*/
+
+#include "halp.h"
+#include "legodef.h"
+#include "arccodes.h"
+#include "pcf8574.h"
+#include "pcd8584.h"
+
+//
+// OcpValid -- Gate for access to OCP.
+// Init code will set to TRUE if OCP is reachable
+// If FALSE, OCP access routines become no-ops
+//
+
+BOOLEAN OcpValid = FALSE;
+
+ARC_STATUS
+HalpOcpInitDisplay(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initialize the display and the PCF8574 control register.
+
+ This sequence must be completed before any characters
+ are written to the device.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ ARC_STATUS sts;
+
+ if (OcpValid) {
+
+ //[wem] Attempt to reach OCP device?
+ //[wem] Or let FwI2cWrite() fail?
+ //
+ //return ENODEV;
+
+ return ESUCCESS;
+ }
+
+ FwPcdInit(I2C_INTERFACE_CSR_PORT, I2C_INTERFACE_DATA_PORT);
+
+ //
+ // Issue a reset.
+ //
+
+#if 0 //[wem] not tested
+
+ sts = FwI2cWrite(OCP_SLAVE_CONTROL, OCP_CMD_INIT); // Turn on Reset, Chip Enable, and Read
+ if (sts != ESUCCESS) {
+ OcpValid = FALSE;
+ return sts;
+ }
+
+ sts = FwI2cWrite(OCP_SLAVE_CONTROL, OCP_CMD_INITCLR); // Clear Reset, leave Chip Enable asserted
+ if (sts != ESUCCESS) {
+ OcpValid = FALSE;
+ return sts;
+ }
+#endif
+
+ OcpValid = TRUE;
+
+ return ESUCCESS;
+}
+
+VOID
+HalpOcpTestDisplay(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Display text sequences to allow visual checkout
+ of OCP.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ UCHAR string[9] = " ";
+ int index, i, j, k;
+
+ for (index=0;index<100;index++) {
+ string[7] = 'A' + (index % 26);
+ HalpOcpPutString(string, 8, 0);
+ for (i=0;i<7;i++) {
+ string[i] = string[i+1];
+ }
+ }
+
+ for (i=0;i<32;i++) {
+
+ string[0] = '0' + (i / 10);
+ string[1] = '0' + (i % 10);
+ string[2] = ' ';
+ string[3] = ' ';
+ HalpOcpPutString(string, 4, 0);
+
+ HalpStallExecution(__1MSEC * 100);
+
+ for (j=0;j<8;j++) {
+ string[j] = (i*8)+j;
+ }
+
+ for (j=0;j<5;j++) {
+ HalpOcpPutString(string, 8, 0);
+ }
+
+ HalpStallExecution(__1MSEC * 100);
+ }
+}
+
+VOID
+HalpOcpClearDisplay(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ Clear the display of the Operator Control
+ Panel (OCP).
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None.
+
+Notes:
+
+ (1) Turn on Reset, Chip Enable, and Write
+ (2) Clear Reset, leave Chip Enable asserted
+
+--*/
+{
+
+ if (!OcpValid) return;
+
+ FwI2cWrite(OCP_SLAVE_CONTROL, OCP_CMD_RESET);
+ FwI2cWrite(OCP_SLAVE_CONTROL, OCP_CMD_CLEAR);
+
+}
+
+VOID
+HalpOcpPutString(
+ IN PUCHAR String,
+ IN ULONG Count,
+ IN ULONG Start
+ )
+
+/*++
+
+Routine Description:
+
+ Prints a string to the Operator Control
+ Panel (OCP).
+
+Arguments:
+
+ String - An ASCII character string for display on the OCP.
+ Count - The number of characters in the argument string.
+ Start - Starting position on the OCP (0..7)
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PUCHAR ArgString = String;
+ ULONG CharCount, End;
+
+ if (!OcpValid) return;
+
+ //
+ // Limit the string to a maximum of OCP_SIZE characters.
+ //
+ End = (Start+Count > OCP_SIZE) ? OCP_SIZE : Start+Count;
+
+ for (CharCount = Start; CharCount < End; CharCount++) {
+ HalpOcpPutByte((UCHAR)CharCount, *ArgString++);
+ }
+ return;
+}
+
+VOID
+HalpOcpPutSlidingString(
+ IN PUCHAR String,
+ IN ULONG Count
+ )
+
+/*++
+
+Routine Description:
+
+ Prints a sliding string to the Operator Control
+ Panel (OCP).
+
+Arguments:
+
+ String - An ASCII character string for display on the OCP.
+ Count - The number of characters in the argument string.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ UCHAR DisplayString[OCP_SIZE];
+ int index, i;
+ int count = Count;
+
+ if (!OcpValid) return;
+
+ for (i=0;i<OCP_SIZE;i++)
+ DisplayString[i] = ' ';
+
+ for (index=0;index<count;index++) {
+ DisplayString[7] = String[index]; // move next char in from right
+ HalpOcpPutString(DisplayString, OCP_SIZE, 0);
+ for (i=0;i<(OCP_SIZE-1);i++) {
+ DisplayString[i] = DisplayString[i+1]; // slide right 7 chars 1 space to left
+ }
+ }
+
+ // Leaves last 8 characters of string in display...
+}
+
+VOID
+HalpOcpPutByte(
+ UCHAR Position,
+ UCHAR Datum
+ )
+/*++
+
+Routine Description:
+
+ This function sends a data byte in Datum to the high-order node
+ address of the OCP, its data port.
+
+ The byte will be displayed at the position indicated by Position.
+
+Arguments:
+
+ Position - The character position to write Datum.
+ Datum - The byte to be written to the OCP data port.
+
+Return Value:
+
+ None.
+
+Notes:
+
+ Assume that FPCE is set upon entry.
+
+--*/
+
+{
+ UCHAR Command;
+
+ if (!OcpValid) return;
+
+ Command = OCP_CMD_READY | OCP_FP_ADDRESS(Position);
+
+ FwI2cWrite(OCP_SLAVE_CONTROL, Command); // Assert address, ready to write
+ FwI2cWrite(OCP_SLAVE_DATA, Datum); // Load data byte in data port.
+ FwI2cWrite(OCP_SLAVE_CONTROL, OCP_CMD_ISSUE(Command)); // Clear FPCE
+ FwI2cWrite(OCP_SLAVE_CONTROL, Command); // Reassert FPCE
+
+ return;
+}
+
+/* end pcf8574.c */
diff --git a/private/ntos/nthals/hallego/alpha/pcf8574.h b/private/ntos/nthals/hallego/alpha/pcf8574.h
new file mode 100644
index 000000000..76b4b8ae6
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcf8574.h
@@ -0,0 +1,175 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+Copyright (c) 1994,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ pcf8574.h
+
+Abstract:
+
+ This module contains the definitions for controlling Lego's
+ OCP display.
+
+ The OCP display is on the I2C bus and is implemented via two
+ PCF8574's, which drive the LED display, select which character
+ position will be written, and select which character to write.
+
+Author:
+
+ Gene Morgan (Digital)
+
+Environment:
+
+ Alpha AXP ARC firmware.
+
+Revision History:
+
+ Gene Morgan (Digital) 11-Nov-1995
+ Initial version
+
+ Gene Morgan 15-Apr-1996
+ Update function prototypes.
+
+--*/
+
+#ifndef _PCF8754_
+#define _PCF8754_
+
+
+// Lego OCP interface
+//
+// The interface is implemented via the I2C bus. Two PCF8574's
+// provide the two slave device registers that control Lego's
+// 8-character LED display. The two registers are Display
+// Address and Control, and Display Data.
+//
+/*--
+ Display Address and Control Register:
+
+ +-------+-------+-------+-------+----------------------+
+ | FPRST | RES | FPCE | FPWR | FPAD[3:0] |
+ +-------+-------+-------+-------+----------------------+
+ | | | | |
+ | reserved | | +-- Front Panel Address
+ | | | 0x8 -> char 0 (Left)
+ +-- Front Panel | | 0xF -> char 7 (Right)
+ Reset | +-- Front Panel Write
+ 1 -> reset | 0 -> write, 1 -> read
+ +-- Front Panel Chip Enable
+ 0 -> FPAD, FPWR, and data are valid
+
+ Current implementation always writes 1 to the reserved bit, and the
+ initialization sequence clears FPWR (i.e., set to read). It is not known
+ whether these actions are necessary.
+--*/
+// The Display Data register receives or delivers a single byte,
+// depending on the setting of FPWR.
+//
+
+//
+// OCP Slave addresses
+//
+
+#define OCP_SLAVE_CONTROL 0x40 // Display Address and Control register
+#define OCP_SLAVE_DATA 0x42 // Display Data register
+#define OCP_SIZE 8 // 8 character display
+
+//
+// OCP Display Address and Control definitions
+//
+
+#define OCP_FP_RESET 0x80 // FPRST -- Set to perform reset
+#define OCP_FP_RES 0x40 // RES -- Reserved, currently always set
+#define OCP_FP_ENABLE 0x20 // FPCE -- Clear to assert valid address and data
+#define OCP_FP_READ 0x10 // FPWR -- Set to perform read
+#define OCP_FP_ADDRESS(pos) ((UCHAR)(0x8 | (pos & 0x7)))
+ // FPAD3..FPAD0 -- Display character address
+//
+// OCP Command Settings
+//
+
+//
+// OCP_CMD_RESET issues a reset to the OCP (which clears the display)
+// OCP_CMD_CLEAR clears reset
+
+#define OCP_CMD_RESET ((UCHAR)(OCP_FP_RES | OCP_FP_RESET) | OCP_FP_ADDRESS(0))
+#define OCP_CMD_CLEAR ((UCHAR)(OCP_FP_RES) | OCP_FP_ADDRESS(0))
+
+//
+// OCP_CMD_READY is sent before data is issued
+// OCP_CMD_ISSUE indicates that the address and data for the transfer are valid
+//
+
+#define OCP_CMD_READY ((UCHAR)(OCP_FP_RES | OCP_FP_ENABLE))
+#define OCP_CMD_ISSUE(cmd) ((UCHAR)(cmd & ~OCP_FP_ENABLE))
+
+//
+// Init sequence -- not tested.
+//
+
+#define OCP_CMD_INIT ((UCHAR)(OCP_FP_RES | OCP_FP_RESET | OCP_FP_ENABLE))
+#define OCP_CMD_INITCLR ((UCHAR)(OCP_CMD_INIT & ~OCP_FP_RESET))
+
+//
+// Function prototypes.
+//
+#if !defined (_LANGUAGE_ASSEMBLY)
+
+// FwOcpInitDisplay
+// Call once to set the OCP display to a known state
+// Returns:
+// ESUCCESS - Initialization was successful
+// ENODEV - OCP couldn't be reached
+//
+ARC_STATUS
+HalpOcpInitDisplay(
+ VOID
+ );
+
+// HalpOcpTestDisplay
+// Perfom visual test of OCP
+//
+VOID
+HalpOcpTestDisplay(
+ VOID
+ );
+
+// HalpOcpClearDisplay
+// Clear display
+VOID
+HalpOcpClearDisplay(
+ VOID
+ );
+
+// FwOcpPutString
+// Call to display a string on the OCP display.
+//
+VOID
+HalpOcpPutString(
+ IN PUCHAR String,
+ IN ULONG Count,
+ IN ULONG Start
+ );
+
+// HalpOcpPutSlidingString
+// Display a string on the OCP display.
+//
+VOID
+HalpOcpPutSlidingString(
+ IN PUCHAR String,
+ IN ULONG Count
+ );
+
+// FwOcpPutByte
+// Call to a display a single byte on the OCP display.
+VOID
+HalpOcpPutByte(
+ UCHAR Position,
+ UCHAR Datum
+ );
+
+#endif // !defined (_LANGUAGE_ASSEMBLY)
+
+#endif // _PCF8574_
diff --git a/private/ntos/nthals/hallego/alpha/pcibus.c b/private/ntos/nthals/hallego/alpha/pcibus.c
new file mode 100644
index 000000000..472054ee0
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcibus.c
@@ -0,0 +1,111 @@
+/*++
+
+
+Copyright (c) 1993 Microsoft Corporationn, Digital Equipment Corporation
+
+Module Name:
+
+ pcibus.c
+
+Abstract:
+
+ Platform-specific PCI bus routines
+
+Author:
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ Gene Morgan [Digital] 11-Oct-1995
+
+ Initial version for Lego. Adapted from Avanti.
+
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+#include "machdep.h"
+
+// Highest numbered bus detected during PCI configuration
+//
+extern ULONG PCIMaxBus;
+
+
+
+PCI_CONFIGURATION_TYPES
+HalpPCIConfigCycleType(
+ IN PBUS_HANDLER BusHandler
+ )
+{
+ if (BusHandler->BusNumber == 0) {
+ return PciConfigType0;
+ } else {
+ return PciConfigType1;
+ }
+}
+
+
+VOID
+HalpPCIConfigAddr (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ PPCI_CFG_CYCLE_BITS pPciAddr
+ )
+{
+ PCI_CONFIGURATION_TYPES ConfigType;
+
+ ConfigType = HalpPCIConfigCycleType(BusHandler);
+
+ if (ConfigType == PciConfigType0)
+ {
+ //
+ // Initialize PciAddr for a type 0 configuration cycle
+ //
+ // Device number is mapped to address bits 11:24.
+ // In APECS pass 2, the format of a type 0 cycle is the same as the
+ // format of a type 1. Note that HalpValidPCISlot has already
+ // done bounds checking on DeviceNumber.
+ //
+ // PciAddr can be intialized for different bus numbers
+ // with distinct configuration spaces here.
+ //
+
+ pPciAddr->u.AsULONG = (ULONG) APECS_PCI_CONFIG_BASE_QVA;
+ pPciAddr->u.AsULONG += ( (Slot.u.bits.DeviceNumber) << 11 );
+
+ pPciAddr->u.bits0.FunctionNumber = Slot.u.bits.FunctionNumber;
+ pPciAddr->u.bits0.Reserved1 = PciConfigType0;
+
+#if HALDBG
+ DbgPrint("HalpPCIConfigAddr: Type 0 PCI Config Access @ %x\n", pPciAddr->u.AsULONG);
+#endif // DBG
+
+ }
+ else
+ {
+ //
+ // Initialize PciAddr for a type 1 configuration cycle
+ //
+ //
+
+ pPciAddr->u.AsULONG = (ULONG) APECS_PCI_CONFIG_BASE_QVA;
+ pPciAddr->u.bits1.BusNumber = BusHandler->BusNumber;
+ pPciAddr->u.bits1.FunctionNumber = Slot.u.bits.FunctionNumber;
+ pPciAddr->u.bits1.DeviceNumber = Slot.u.bits.DeviceNumber;
+ pPciAddr->u.bits1.Reserved1 = PciConfigType1;
+
+#if HALDBG
+ DbgPrint("Type 1 PCI Config Access @ %x\n", pPciAddr->u.AsULONG);
+#endif // DBG
+
+ }
+
+ return;
+}
+
+
diff --git a/private/ntos/nthals/hallego/alpha/pciir.c b/private/ntos/nthals/hallego/alpha/pciir.c
new file mode 100644
index 000000000..d1e8fe7e9
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pciir.c
@@ -0,0 +1,646 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+Copyright (c) 1992,1993,1994,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ pciir.c
+
+Abstract:
+
+ The module provides the interrupt support for the Lego's PCI
+ interrupts.
+
+Author:
+
+ James Livingston 2-May-1994
+
+Revision History:
+
+ Janet Schneider (Digital) 27-July-1995
+ Added support for the Noritake.
+
+ Gene Morgan (Digital) 28-Oct-1995
+ Initial version for Lego. Adapted from Mikasa/Noritake.
+
+ Gene Morgan 15-Apr-1996
+ Fix PICMG-mode initialization.
+
+--*/
+
+#include "halp.h"
+
+//
+// Define external function prototypes
+//
+
+UCHAR
+HalpAcknowledgePciInterrupt(
+ PVOID ServiceContext
+ );
+
+//
+// Import save area for PCI interrupt mask register.
+//
+USHORT HalpLegoPciInterruptMasterMask;
+
+// Cache current contents of interrupt mask registers
+//
+USHORT HalpLegoPciInterruptMask[4];
+
+//
+// PCI Interrupt control -- defined in I/O mapping module
+//
+extern PVOID HalpLegoPciInterruptConfigQva;
+extern PVOID HalpLegoPciInterruptMasterQva;
+extern PVOID HalpLegoPciInterruptRegisterBaseQva;
+extern PVOID HalpLegoPciInterruptRegisterQva[];
+extern PVOID HalpLegoPciIntMaskRegisterQva[];
+
+//
+// Globals for conveying Cpu and Backplane type
+//
+extern BOOLEAN HalpLegoCpu;
+extern BOOLEAN HalpLegoBackplane;
+extern ULONG HalpLegoCpuType;
+extern ULONG HalpLegoBackplaneType;
+extern UCHAR HalpLegoFeatureMask;
+extern ULONG HalpLegoPciRoutingType;
+
+VOID
+DbgDumpIntRegs(
+ VOID
+ )
+{
+#if DBG
+ LEGO_PCI_INT_MASTER MasterRegister;
+ USHORT MaskReg[4];
+ USHORT IntReg[4];
+ int i;
+
+ MasterRegister.All = READ_REGISTER_USHORT((PUSHORT)HalpLegoPciInterruptMasterQva);
+
+ MaskReg[0] = READ_REGISTER_USHORT( (PUSHORT) HalpLegoPciIntMaskRegisterQva[0]);
+ MaskReg[1] = READ_REGISTER_USHORT( (PUSHORT) HalpLegoPciIntMaskRegisterQva[1]);
+ MaskReg[2] = READ_REGISTER_USHORT( (PUSHORT) HalpLegoPciIntMaskRegisterQva[2]);
+ MaskReg[3] = READ_REGISTER_USHORT( (PUSHORT) HalpLegoPciIntMaskRegisterQva[3]);
+
+ IntReg[0] = READ_REGISTER_USHORT( (PUSHORT) HalpLegoPciInterruptRegisterQva[0]);
+ IntReg[1] = READ_REGISTER_USHORT( (PUSHORT) HalpLegoPciInterruptRegisterQva[1]);
+ IntReg[2] = READ_REGISTER_USHORT( (PUSHORT) HalpLegoPciInterruptRegisterQva[2]);
+ IntReg[3] = READ_REGISTER_USHORT( (PUSHORT) HalpLegoPciInterruptRegisterQva[3]);
+
+ DbgPrint ("\nMaster: %04X\n",MasterRegister.All);
+ DbgPrint (" Mask: %04X %04X %04X %04X\n", MaskReg[0], MaskReg[1], MaskReg[2], MaskReg[3]);
+ DbgPrint ("IntReg: %04X %04X %04X %04X\n", IntReg[0], IntReg[1], IntReg[2], IntReg[3]);
+#endif
+}
+
+
+VOID
+HalpInitializePciInterrupts(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the Lego PCI interrupts.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ LEGO_PCI_INT_CONFIG ConfigRegister;
+ LEGO_PCI_INT_MASTER MasterRegister;
+
+#if DBG
+ //
+ // Dump current contents of master and config interrupt registers
+ //
+ ConfigRegister.All = READ_REGISTER_USHORT((PUSHORT)HalpLegoPciInterruptConfigQva);
+ MasterRegister.All = READ_REGISTER_USHORT((PUSHORT)HalpLegoPciInterruptMasterQva);
+
+ DbgPrint("PCI-INTACC[config:%04x,master:%04x]\n",
+ ConfigRegister.All, MasterRegister.All);
+#endif
+
+
+ if (HalpLegoPciRoutingType != PCI_INTERRUPT_ROUTING_FULL) {
+
+ //
+ // disable interrupt accelerator and return
+ //
+
+ MasterRegister.All = READ_REGISTER_USHORT((PUSHORT)HalpLegoPciInterruptMasterQva); //[wem] added PEFT
+ MasterRegister.InterruptMode = 0; // MODE - select SIO routing
+ MasterRegister.InterruptEnable = 0; // valid iff MODE==0
+ MasterRegister.IntRegMaskEnable = 0;
+ MasterRegister.IntMask = 0;
+ WRITE_REGISTER_USHORT( (PUSHORT)HalpLegoPciInterruptMasterQva,
+ MasterRegister.All );
+
+ MasterRegister.All = READ_REGISTER_USHORT((PUSHORT)HalpLegoPciInterruptMasterQva);
+#if DBG
+ DbgPrint("PCI-INTACC[config:%04x,master:%04x]\n",
+ ConfigRegister.All, MasterRegister.All);
+#endif
+
+ MasterRegister.InterruptMode = 0; // MODE - select SIO routing
+ MasterRegister.InterruptEnable = 0; // valid iff MODE==0
+ MasterRegister.IntRegMaskEnable = 0;
+ MasterRegister.IntMask = 0;
+ WRITE_REGISTER_USHORT( (PUSHORT)HalpLegoPciInterruptMasterQva,
+ MasterRegister.All );
+
+#if DBG
+ MasterRegister.All = READ_REGISTER_USHORT((PUSHORT)HalpLegoPciInterruptMasterQva);
+
+ DbgPrint("PCI-INTACC[config:%04x,master:%04x]\n",
+ ConfigRegister.All, MasterRegister.All);
+#endif
+ return;
+ }
+
+ //
+ // Initialize the Lego PCI interrupts. There's a master
+ // interrupt and mask register, plus individual interrupt
+ // and mask registers for each physical slot.
+ //
+ // 1. Write base address of interrupt registers.
+ // 2. Write MODE, MSKEN, and MINT[D:A].
+ // 3. Set all mask bits to "disabled".
+ //
+
+ ConfigRegister.All = 0;
+ ConfigRegister.IntRegisterBaseAddr = PCI_INTERRUPT_BASE_REGISTER >> 4;
+ WRITE_REGISTER_USHORT( (PUSHORT)HalpLegoPciInterruptConfigQva,
+ ConfigRegister.All );
+
+ //
+ // Set interrupt accelerator mode
+ // Mask interrupts until interrupt registers are setup.
+ //
+ // Note: The interrupt mask in the master register is always clear
+ //
+
+ MasterRegister.All = 0;
+ MasterRegister.InterruptMode = 1; // MODE
+ MasterRegister.InterruptEnable = 0; // valid iff MODE==0
+ MasterRegister.IntRegMaskEnable = 1; // valid iff MODE==1
+#if 0 //[wem] remove PEFT
+ MasterRegister.IntMask = HalpLegoPciInterruptMasterMask;
+#endif
+ WRITE_REGISTER_USHORT( (PUSHORT)HalpLegoPciInterruptMasterQva,
+ MasterRegister.All );
+
+ //
+ // Turn on mask bits for each interrupt register
+ //
+
+ HalpLegoPciInterruptMask[0] = (USHORT)~0;
+ HalpLegoPciInterruptMask[1] = (USHORT)~0;
+ HalpLegoPciInterruptMask[2] = (USHORT)~0;
+ HalpLegoPciInterruptMask[3] = (USHORT)~0;
+
+ WRITE_REGISTER_USHORT( (PUSHORT) HalpLegoPciIntMaskRegisterQva[0],
+ HalpLegoPciInterruptMask[0] );
+ WRITE_REGISTER_USHORT( (PUSHORT) HalpLegoPciIntMaskRegisterQva[1],
+ HalpLegoPciInterruptMask[1] );
+ WRITE_REGISTER_USHORT( (PUSHORT) HalpLegoPciIntMaskRegisterQva[2],
+ HalpLegoPciInterruptMask[2] );
+ WRITE_REGISTER_USHORT( (PUSHORT) HalpLegoPciIntMaskRegisterQva[3],
+ HalpLegoPciInterruptMask[3] );
+
+ // Turn off mask bits in master interrupt register
+ //
+ MasterRegister.All = 0;
+ MasterRegister.InterruptMode = 1; // MODE
+ MasterRegister.InterruptEnable = 0; // valid iff MODE==0
+ MasterRegister.IntRegMaskEnable = 1; // valid iff MODE==1
+ MasterRegister.IntMask = (USHORT)~(INTA | INTB | INTC | INTD);
+ WRITE_REGISTER_USHORT( (PUSHORT)HalpLegoPciInterruptMasterQva,
+ MasterRegister.All );
+
+#if DBG
+ DbgDumpIntRegs();
+#endif
+
+}
+
+
+VOID
+HalpDisablePciInterrupt(
+ IN ULONG Vector
+ )
+
+/*++
+
+Routine Description:
+
+ This function disables the PCI interrupt specified by Vector.
+
+Arguments:
+
+ Vector - Supplies the vector of the PCI interrupt to disable.
+
+Return Value:
+
+ None.
+
+Notes:
+
+ The register contents are cached in HalpLegoPciInterruptMask
+ array. [wem] ??? Is this safe ?
+
+--*/
+
+{
+ ULONG RegSelect;
+ USHORT BitMask, NewMask;
+
+ // Remove offset to yield register and bit position.
+ //
+ Vector -= PCI_DEVICE_VECTORS;
+
+ // High order nibble of Vector selects the register, low order
+ // selects the bit.
+ //
+ RegSelect = (Vector >> 4) - 1;
+ BitMask = 1 << ((Vector & 0xf) - 1);
+
+ // Assume the current state of the interrupt mask register
+ // is in HalpLegoPciInterruptMask.
+ //
+ // Set bit indicated by Vector to disable interrupts
+ //
+ NewMask = HalpLegoPciInterruptMask[RegSelect] | BitMask;
+
+ // If changed, write new register contents
+ //
+ if (NewMask != HalpLegoPciInterruptMask[RegSelect]) {
+ HalpLegoPciInterruptMask[RegSelect] = NewMask;
+ WRITE_REGISTER_USHORT( (PUSHORT)
+ HalpLegoPciIntMaskRegisterQva[RegSelect],
+ HalpLegoPciInterruptMask[RegSelect] );
+ }
+
+#if DBG
+ DbgPrint("\nDisable PCI vector: %02X", Vector);
+ DbgDumpIntRegs();
+#endif
+
+}
+
+
+VOID
+HalpEnablePciInterrupt(
+ IN ULONG Vector,
+ IN KINTERRUPT_MODE InterruptMode
+ )
+
+/*++
+
+Routine Description:
+
+ This function enables the PCI interrupt specified by Vector.
+Arguments:
+
+ Vector - Supplies the vector of the PCI interrupt that is enabled.
+
+ InterruptMode - Supplies the mode of the interrupt;
+ LevelSensitive or Latched (ignored for Lego PCI
+ interrupts; they're always levels).
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ ULONG RegSelect;
+ USHORT BitMask, NewMask;
+
+ //
+ // Remove offset to yield register and bit position.
+ //
+
+ Vector -= PCI_DEVICE_VECTORS;
+
+ //
+ // High order nibble of Vector selects the register, low order
+ // selects the bit.
+ //
+
+ RegSelect = (Vector >> 4) - 1;
+ BitMask = 1 << ((Vector & 0xf) - 1);
+
+ //
+ // Assume the current state of the interrupt mask register
+ // is in HalpLegoPciInterruptMask.
+ //
+ // Clear bit indicated by Vector to enable interrupts.
+ //
+
+ NewMask = HalpLegoPciInterruptMask[RegSelect] & ~BitMask;
+
+ //
+ // If changed, write new register contents
+ //
+
+ if (NewMask != HalpLegoPciInterruptMask[RegSelect]) {
+ HalpLegoPciInterruptMask[RegSelect] = NewMask;
+ WRITE_REGISTER_USHORT( (PUSHORT)
+ HalpLegoPciIntMaskRegisterQva[RegSelect],
+ HalpLegoPciInterruptMask[RegSelect] );
+ }
+
+#if DBG
+ DbgPrint("\nEnable PCI vector: %02X", Vector);
+ DbgPrint("\n Old: %04X, New: %04X", HalpLegoPciInterruptMask[RegSelect], NewMask);
+ DbgDumpIntRegs();
+#endif
+
+}
+
+// Table for mapping from per-slot interrupt signal
+// to which slot to service.
+// Index is 4-bit value representing interrupt status for
+// <slot 4> <slot 3> <slot 2> <slot 1>
+// Current priority ordering is slot 1, 2, 3, 4
+// Index zero has no meaning, but it should do no harm.
+//
+//
+USHORT
+HighestPrioritySlot[16] = {
+// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f // value
+ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 // slot (based from zero)
+ };
+
+ULONG
+HighestPrioritySlotHits[4][16] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+UCHAR
+HighestPriorityLine (
+ LEGO_PCI_INT_MASTER MasterReg
+ )
+/*++
+
+Routine Description:
+
+ Policy routine for determining which PCI device to service next.
+
+Arguments:
+
+ MasterReg -- current Lego Master Interrupt register. Interrupt
+ field indicates which slots have pending interrupts.
+
+Return Value:
+
+ Value in range of 0..64, indicating which device should be serviced.
+
+--*/
+{
+ USHORT IntReg;
+
+ UCHAR Nib;
+ USHORT IrContents;
+ USHORT RegSelect, BitSelect;
+ int i;
+
+ RegSelect = HighestPrioritySlot[MasterReg.Interrupt];
+
+ // Read interrupt register for slot
+ //
+ IntReg = READ_REGISTER_USHORT( (PUSHORT)
+ HalpLegoPciInterruptRegisterQva[RegSelect]);
+
+ if (IntReg==0)
+ return 0xff;
+
+ // Find lowest numbered bit.
+ //
+ BitSelect = 0;
+ while (IntReg!=0) {
+ Nib = IntReg & 0xf;
+ if (Nib != 0) {
+ BitSelect += HighestPrioritySlot[Nib];
+ break;
+ }
+ IntReg = IntReg >> 4;
+ BitSelect += 4;
+ }
+
+
+#if DBG
+ if (HighestPrioritySlotHits[RegSelect][BitSelect]++ == 0) {
+ DbgPrint("\nSlot: %d, %d", RegSelect, BitSelect);
+ DbgDumpIntRegs();
+ }
+#endif
+
+ return ((RegSelect + 1) << 4) + (BitSelect + 1);
+
+}
+
+UCHAR
+HalpAcknowledgePciInterrupt(
+ PVOID ServiceContext
+ )
+/*++
+
+Routine Description:
+
+ Acknowledge the PCI interrupt. Return the vector number of the
+ highest priority pending interrupt.
+
+Arguments:
+
+ ServiceContext - Service context of the interrupt service - supplies
+ a QVA to Lego's Master PCI interrupt register.
+
+Return Value:
+
+
+ Return the value of the highest priority pending interrupt,
+ or 0xff if none.
+
+--*/
+{
+ LEGO_PCI_INT_MASTER MasterReg;
+ UCHAR InterruptVector;
+
+ UCHAR ISAVector = 0; //[wem] DEBUG - ack PCI int
+
+ static ULONG Count = 0;
+
+ //
+ // Check the master register to see which primary slot is
+ // requesting service (slot may be a PPB requesting service
+ // on behalf of one of its slots). Then check that slot's
+ // interrupt register.
+ //
+ // A set bit in the master or slot register indicates an active
+ // interrupt. Note that if the interrupt is masked, the bit will
+ // not be set. Also note that the code does not use the master
+ // register's mask bits unless all PCI interrupts need to be
+ // disabled at once.
+ //
+ // Scan is currently depth-first from slot 1 to slot 4. For
+ // each slot, INTA is serviced first and INTD serviced last.
+ //
+ // [wem] There's some interesting opportunities here.
+ // For example, it is possible to scan and detect how many
+ // waiting interrupts there are. It is also possible remember
+ // last vector and scan forward from that point (as in round
+ // robin), or to implement a fairness algorithm that incorporates
+ // priority.
+ //
+
+#if 0
+ //
+ //[wem] This requires an interrupt controller to respond to the
+ // interrupt acknowledge. The SIO has been programmed to not
+ // respond, so someone else has to do it (the interrupt accelerator?).
+ //
+
+ ISAVector = READ_PORT_UCHAR(HalpEisaIntAckBase);
+#endif
+
+ // Read master register.
+ //
+ MasterReg.All = READ_REGISTER_USHORT(
+ (PUSHORT) HalpLegoPciInterruptMasterQva);
+
+ if (MasterReg.Interrupt==0) {
+ return 0xff; // no interrupts
+ }
+
+ // Scan
+ //
+ InterruptVector = HighestPriorityLine (MasterReg);
+
+#if DBG
+ if (Count++ < 5 && ISAVector != 0xff) {
+ DbgPrint("<PCIACK:%02X:%02X>",ISAVector,InterruptVector);
+ }
+#endif
+
+ return( InterruptVector );
+}
+
+
+BOOLEAN
+HalpPciDispatch(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext,
+ IN PKTRAP_FRAME TrapFrame
+ )
+/*++
+
+Routine Description:
+
+ This routine is entered as the result of an interrupt having been generated
+ via the vector connected to the PCI device interrupt object. Its function
+ is to call the second-level interrupt dispatch routine.
+
+ This service routine could have been connected as follows, where the
+ ISR is the assembly wrapper that does the handoff to this function:
+
+ KeInitializeInterrupt( &Interrupt,
+ HalpPciInterruptHandler,
+ (PVOID) HalpPciIrQva,
+ (PKSPIN_LOCK)NULL,
+ PCI_VECTOR,
+ PCI_DEVICE_LEVEL,
+ PCI_DEVICE_LEVEL,
+ LevelSensitive,
+ TRUE,
+ 0,
+ FALSE);
+
+ KeConnectInterrupt(&Interrupt);
+
+Arguments:
+
+ Interrupt - Supplies a pointer to the interrupt object.
+
+ ServiceContext - Supplies a pointer to the PCI interrupt register.
+
+ TrapFrame - Supplies a pointer to the trap frame for this interrupt.
+
+Return Value:
+
+ Returns the value returned from the second level routine.
+
+--*/
+{
+ UCHAR PCIVector;
+ BOOLEAN returnValue;
+ USHORT PCRInOffset;
+
+ //[wem] DEBUG - count SIO dispatch entries
+ //
+ static long PciCount = 0;
+
+#if DBG //[wem]
+ PciCount++;
+ if (PciCount<5) {
+ DbgPrint("II<PCI><");
+ }
+ if (PciCount % 5000 == 0) {
+ DbgPrint("II<PCI><%08x><",PciCount);
+ }
+#endif
+
+ //
+ // Acknowledge interrupt and receive the returned interrupt vector.
+ // If we got 0xff back, there were no enabled interrupts, so we
+ // signal that with a FALSE return, immediately.
+ //
+
+ PCIVector = HalpAcknowledgePciInterrupt(ServiceContext);
+
+ if (PCIVector == 0xff) {
+
+#if DBG //[wem]
+ if (PciCount<5 || (PciCount % 5000) == 0) {
+ DbgPrint("ff>.");
+ }
+#endif
+ return( FALSE );
+ }
+
+ // Compute new vector based on PCI bus state
+ //
+ PCRInOffset = PCIVector + PCI_DEVICE_VECTORS;
+
+ // Re-dispatch via new vector
+ //
+ returnValue = ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[PCRInOffset])(
+ PCR->InterruptRoutine[PCRInOffset],
+ TrapFrame
+ );
+
+#if DBG //[wem]
+ if (PciCount<5 || (PciCount % 5000) == 0) {
+ DbgPrint("%02x>.",returnValue);
+ }
+#endif
+
+ return( returnValue );
+}
diff --git a/private/ntos/nthals/hallego/alpha/pcisio.c b/private/ntos/nthals/hallego/alpha/pcisio.c
new file mode 100644
index 000000000..91153d23c
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcisio.c
@@ -0,0 +1,587 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+Copyright (c) 1992, 1993, 1994 Digital Equipment Corporation
+
+Module Name:
+
+ pic8259.c
+
+Abstract:
+
+ The module provides the interrupt support for the PCI SIO
+ programmable interrupt controller.
+
+
+Author:
+
+ Eric Rehm (DEC) 4-Feburary-1994
+
+Revision History:
+
+
+--*/
+
+#include "halp.h"
+#include "eisa.h"
+
+#if 0 //[wem] not yet
+extern PVOID HalpSioIntAckQva;
+extern ULONG HalpLegoPciRoutingType;
+#endif
+
+//
+// Import save area for SIO interrupt mask registers.
+//
+
+UCHAR HalpSioInterrupt1Mask;
+UCHAR HalpSioInterrupt2Mask;
+UCHAR HalpSioInterrupt1Level;
+UCHAR HalpSioInterrupt2Level;
+
+//
+// Define the context structure for use by interrupt service routines.
+//
+
+typedef BOOLEAN (*PSECOND_LEVEL_DISPATCH)(
+ PKINTERRUPT InterruptObject
+ );
+
+
+VOID
+HalpInitializeSioInterrupts (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the standard dual 8259 programmable interrupt
+ controller.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ UCHAR DataByte;
+
+ //
+ // Initialize the SIO interrupt controller. There are two cascaded
+ // interrupt controllers, each of which must initialized with 4 initialize
+ // control words.
+ //
+
+ DataByte = 0;
+ ((PINITIALIZATION_COMMAND_1) &DataByte)->Icw4Needed = 1;
+ ((PINITIALIZATION_COMMAND_1) &DataByte)->InitializationFlag = 1;
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0,
+ DataByte
+ );
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort0,
+ DataByte
+ );
+
+ //
+ // The second intitialization control word sets the iterrupt vector to
+ // 0-15.
+ //
+
+ DataByte = 0;
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ DataByte
+ );
+
+ DataByte = 0x08;
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ DataByte
+ );
+
+ //
+ // The thrid initialization control word set the controls for slave mode.
+ // The master ICW3 uses bit position and the slave ICW3 uses a numberic.
+ //
+
+ DataByte = 1 << SLAVE_IRQL_LEVEL;
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ DataByte
+ );
+
+ DataByte = SLAVE_IRQL_LEVEL;
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ DataByte
+ );
+
+ //
+ // The fourth initialization control word is used to specify normal
+ // end-of-interrupt mode and not special-fully-nested mode.
+ //
+
+ DataByte = 0;
+ ((PINITIALIZATION_COMMAND_4) &DataByte)->I80x86Mode = 1;
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ DataByte
+ );
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ DataByte
+ );
+
+
+ //
+ // Disable all of the interrupts except the slave.
+ //
+
+ HalpSioInterrupt1Mask = (UCHAR)(~(1 << SLAVE_IRQL_LEVEL));
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ HalpSioInterrupt1Mask
+ );
+
+ HalpSioInterrupt2Mask = 0xFF;
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ HalpSioInterrupt2Mask
+ );
+
+
+ //
+ // Initialize the edge/level register masks to 0 which is the default
+ // edge sensitive value.
+ //
+
+ HalpSioInterrupt1Level = 0;
+ HalpSioInterrupt2Level = 0;
+
+ return;
+
+}
+
+VOID
+HalpDisableSioInterrupt(
+ IN ULONG Vector
+ )
+
+/*++
+
+Routine Description:
+
+ This function Disables the SIO bus specified SIO bus interrupt.
+
+Arguments:
+
+ Vector - Supplies the vector of the ESIA interrupt that is Disabled.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Calculate the SIO interrupt vector.
+ //
+
+ Vector -= ISA_VECTORS;
+
+ //
+ // Determine if this vector is for interrupt controller 1 or 2.
+ //
+
+ if (Vector & 0x08) {
+
+ //
+ // The interrupt is in controller 2.
+ //
+
+ Vector &= 0x7;
+
+ HalpSioInterrupt2Mask |= (UCHAR) 1 << Vector;
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ HalpSioInterrupt2Mask
+ );
+
+ } else {
+
+ //
+ // The interrupt is in controller 1.
+ //
+
+ Vector &= 0x7;
+
+ //
+ // never disable IRQL2, it is the slave interrupt
+ //
+
+ if (Vector != SLAVE_IRQL_LEVEL) {
+ HalpSioInterrupt1Mask |= (ULONG) 1 << Vector;
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ HalpSioInterrupt1Mask
+ );
+ }
+
+ }
+
+}
+
+VOID
+HalpEnableSioInterrupt(
+ IN ULONG Vector,
+ IN KINTERRUPT_MODE InterruptMode
+ )
+
+/*++
+
+Routine Description:
+
+ This function enables the SIO bus specified SIO bus interrupt.
+Arguments:
+
+ Vector - Supplies the vector of the SIO interrupt that is enabled.
+
+ InterruptMode - Supplies the mode of the interrupt; LevelSensitive or
+ Latched.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Calculate the SIO interrupt vector.
+ //
+
+ Vector -= ISA_VECTORS;
+
+ //
+ // Determine if this vector is for interrupt controller 1 or 2.
+ //
+
+ if (Vector & 0x08) {
+
+ //
+ // The interrupt is in controller 2.
+ //
+
+ Vector &= 0x7;
+
+ HalpSioInterrupt2Mask &= (UCHAR) ~(1 << Vector);
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ HalpSioInterrupt2Mask
+ );
+
+ //
+ // Set the level/edge control register.
+ //
+
+ if (InterruptMode == LevelSensitive) {
+
+ HalpSioInterrupt2Level |= (UCHAR) (1 << Vector);
+
+ } else {
+
+ HalpSioInterrupt2Level &= (UCHAR) ~(1 << Vector);
+
+ }
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2EdgeLevel,
+ HalpSioInterrupt2Level
+ );
+
+ } else {
+
+ //
+ // The interrupt is in controller 1.
+ //
+
+ Vector &= 0x7;
+
+ HalpSioInterrupt1Mask &= (UCHAR) ~(1 << Vector);
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ HalpSioInterrupt1Mask
+ );
+
+ //
+ // Set the level/edge control register.
+ //
+
+ if (InterruptMode == LevelSensitive) {
+
+ HalpSioInterrupt1Level |= (UCHAR) (1 << Vector);
+
+ } else {
+
+ HalpSioInterrupt1Level &= (UCHAR) ~(1 << Vector);
+
+ }
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1EdgeLevel,
+ HalpSioInterrupt1Level
+ );
+ }
+
+}
+
+UCHAR
+HalpAcknowledgeSioInterrupt(
+ PVOID ServiceContext
+ )
+/*++
+
+Routine Description:
+
+ Acknowledge the Sio interrupt. Return the vector number of the
+ highest priority pending interrupt.
+
+Arguments:
+
+ ServiceContext - Service context of the interrupt service - supplies
+ a QVA to Lego's Master PCI interrupt register.
+
+Return Value:
+
+
+ Return the value of the highest priority pending interrupt,
+ or 0xff if none.
+
+--*/
+{
+ UCHAR ISAVector;
+ UCHAR Int1Isr;
+ UCHAR Int2Isr;
+
+ //
+ // If PCI interrupts are being routed through the SIO, then
+ // a write to HalpEisaIntAckBase will generate a correct
+ // PCI Interrupt Acknowledge cycle for both PCI and ISA devices.
+ //
+ // If PCI interrupts are being routed through the interrupt
+ // accelerator, then the Interrupt Acknowledge cannot be issued
+ // on the PCI bus (since the SIO no longer has complete knowledge
+ // of interrupts). Instead, ISA interrupts must be acknowledged
+ // via a special port of the SIO, and PCI interrupts must be
+ // acknowledged via a PCI Interrupt Acknowledge (but that's another
+ // story).
+ //
+
+
+#if 0 //[wem] not yet
+ if (HalpLegoPciRoutingType == PCI_INTERRUPT_ROUTING_FULL) {
+
+ //
+ // The interrupt accelerator is active. Issue the
+ // interrupt acknowledge directly to the SIO
+ //
+
+ ISAVector = READ_PORT_UCHAR(HalpSioIntAckQva);
+ }
+ else {
+
+ // The interrupt accelerator is in PICMG mode. All
+ // interrupts are going through the SIO, so a PCI
+ // interrupt acknowledge is safe.
+ //
+ ISAVector = READ_PORT_UCHAR(HalpEisaIntAckBase);
+ }
+#else
+
+ //
+ // Acknowledge the PCI/ISA interrupt via the SIO
+ //
+ // Note: This path is not used for PCI interrupts when
+ // interrupt accelerator is active.
+ //
+
+ ISAVector = READ_PORT_UCHAR(HalpEisaIntAckBase);
+
+#endif
+
+
+ if ((ISAVector & 0x07) == 0x07) {
+
+ //
+ // Check for a passive release by looking at the inservice register.
+ // If there is a real IRQL7 interrupt, just go along normally. If there
+ // is not, then it is a passive release. So just dismiss it.
+ //
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0,
+ 0x0B
+ );
+
+ Int1Isr = READ_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0);
+
+ //
+ // do second controller
+ //
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort0,
+ 0x0B
+ );
+
+ Int2Isr = READ_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort0);
+
+
+ if (!(Int2Isr & 0x80) && !(Int1Isr & 0x80)) {
+
+ //
+ // Clear the master controller to clear situation
+ //
+
+ if (!(Int2Isr & 0x80)) {
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0,
+ NONSPECIFIC_END_OF_INTERRUPT
+ );
+
+ }
+
+ return 0xFF; // ecrfix - now returns a value
+
+ }
+
+ }
+
+ return ISAVector & 0x0F;
+
+}
+
+
+BOOLEAN
+HalpSioDispatch(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This routine is entered as the result of an interrupt being generated
+ via the vector that is directly connected to an interrupt object that
+ describes the SIO device interrupts. Its function is to call the second
+ level interrupt dispatch routine and acknowledge the interrupt at the SIO
+ controller.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ Returns the value returned from the second level routine.
+
+--*/
+{
+ UCHAR ISAVector;
+ PKPRCB Prcb;
+ BOOLEAN returnValue;
+ USHORT PCRInOffset;
+ PULONG DispatchCode;
+ PKINTERRUPT InterruptObject;
+
+ //[wem] DEBUG - count SIO dispatch entries
+ //
+ static long SioCount = 0;
+
+#if DBG
+ SioCount++;
+ if (SioCount<5) {
+ DbgPrint("II<SIO><");
+ }
+ if (SioCount % 1000 == 0) {
+ DbgPrint("II<SIO><%08x><",SioCount);
+ }
+#endif
+
+ //
+ // Acknowledge the Interrupt controller and receive the returned
+ // interrupt vector.
+ //
+
+ ISAVector = HalpAcknowledgeSioInterrupt(NULL);
+
+ if (ISAVector==0xff)
+ return FALSE;
+
+ //
+ // Dispatch to the secondary interrupt service routine.
+ //
+
+ PCRInOffset = ISAVector + ISA_VECTORS;
+ DispatchCode = (PULONG)PCR->InterruptRoutine[PCRInOffset];
+ InterruptObject = CONTAINING_RECORD(DispatchCode,
+ KINTERRUPT,
+ DispatchCode);
+
+ returnValue = ((PSECOND_LEVEL_DISPATCH)InterruptObject->DispatchAddress)(InterruptObject);
+
+ //
+ // Dismiss the interrupt in the SIO interrupt controllers.
+ //
+
+ //
+ // If this is a cascaded interrupt then the interrupt must be dismissed in
+ // both controlles.
+ //
+
+ if (ISAVector & 0x08) {
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort0,
+ NONSPECIFIC_END_OF_INTERRUPT
+ );
+
+ }
+
+ WRITE_PORT_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0,
+ NONSPECIFIC_END_OF_INTERRUPT
+ );
+
+#if DBG //[wem]
+ if (SioCount<5 || (SioCount % 1000)==0) {
+ DbgPrint("%02x>.", returnValue);
+ }
+#endif
+
+ return(returnValue);
+}
+
+
diff --git a/private/ntos/nthals/hallego/alpha/pcisup.c b/private/ntos/nthals/hallego/alpha/pcisup.c
new file mode 100644
index 000000000..360919f42
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcisup.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\pcisup.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/pcrtc.c b/private/ntos/nthals/hallego/alpha/pcrtc.c
new file mode 100644
index 000000000..2e57b87d6
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcrtc.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\pcrtc.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/pcserial.c b/private/ntos/nthals/hallego/alpha/pcserial.c
new file mode 100644
index 000000000..a2f159c48
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcserial.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\pcserial.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/pcspeakr.c b/private/ntos/nthals/hallego/alpha/pcspeakr.c
new file mode 100644
index 000000000..807b6f324
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pcspeakr.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\pcspeakr.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/perfcntr.c b/private/ntos/nthals/hallego/alpha/perfcntr.c
new file mode 100644
index 000000000..6c0a8f892
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/perfcntr.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\perfcntr.c"
+
diff --git a/private/ntos/nthals/hallego/alpha/pintolin.h b/private/ntos/nthals/hallego/alpha/pintolin.h
new file mode 100644
index 000000000..86843acd3
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/pintolin.h
@@ -0,0 +1,273 @@
+/*++
+
+Copyright (c) 1993 Microsoft Corporation
+Copyright (c) 1994,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ pintolin.h
+
+Abstract:
+
+ This file includes the platform-dependent Pin To Line Tables for Lego
+
+Author:
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ Gene Morgan [Digital] 15-Apr-1996
+ Fix swapped PICMG-mode (ISA shared mode) lines -- affects
+ Gobi and Sahara bridged slots (first and third) if interrupts
+ in use.
+
+--*/
+
+//
+// These tables represent the mapping from slot number and interrupt pin
+// into a PCI Interrupt Vector.
+// On Mustang, EB66, and Lego, the interrupt vector is Interrupt Request Register bit
+// representing that interrupt + 1.
+// On EB66 and Lego, the value also represents the Interrupt Mask Register Bit,
+// since it is identical to the Interrupt Read Register. On Mustang,
+// the Interrupt Mask Register only allows masking of all interrupts
+// from the two plug-in slots.
+//
+// Formally, these mappings can be expressed as:
+//
+// PCIPinToLine:
+// SlotNumber.DeviceNumber x InterruptPin -> InterruptLine
+//
+// LineToVector:
+// InterruptLine -> InterruptVector
+//
+// VectorToIRRBit:
+// InterruptVector -> InterruptRequestRegisterBit
+//
+// VectorToIMRBit:
+// InterruptVector -> InterruptMaskRegisterBit
+//
+// SlotNumberToIDSEL:
+// SlotNumber.DeviceNumber -> IDSEL
+//
+// subject to following invariants (predicates must always be true):
+//
+// Slot.DeviceNumber in {0,...,15}
+//
+// InterruptPin in {1, 2, 3, 4}
+//
+// InterruptRequestRegisterBit in {0,...,15}
+//
+// InterruptMaskRegisterBit in {0,...,15}
+//
+// PCIPinToLine(SlotNumber.DeviceNumber, InterruptPin) =
+// PCIPinToLineTable[SlotNumber.DeviceNumber, InterruptPin]
+// (Table-lookup function initialized below)
+//
+// LineToVector(InterruptLine) = PCI_DEVICE_VECTORS + InterruptLine
+//
+// VectorToIRRBit(InterruptVector) = InterruptVector - 1
+//
+// VectorToIMRBit(InterruptVector) [see below]
+//
+// SlotNumberToIDSEL(SlotNumber.DeviceNumber) = (1 << (Slot.DeviceNumber+11))
+//
+// where:
+//
+// SlotNumber.DeviceNumber:
+// Alpha AXP Platforms receive interrupts on local PCI buses only, which //[wem] ???problem?
+// are limited to 16 devices (PCI AD[11]-AD[26]). (We loose AD[17]-AD[31] //[wem] ???problem?
+// since PCI Config space is a sparse space, requiring a five-bit shift.) //[wem] ???problem?
+//
+// InterruptPin:
+// Each virtual slot has up to four interrupt pins INTA#, INTB#, INTC#, INTD#,
+// as per the PCI Spec. V2.0, Section 2.2.6. (FYI, only multifunction devices
+// use INTB#, INTC#, INTD#.)
+//
+// PCI configuration space indicates which interrupt pin a device will use
+// in the InterruptPin register, which has the values:
+//
+// INTA# = 1, INTB# = 2, INTC# = 3, INTD# = 4
+//
+// Note that there may be up to 8 functions/device on a PCI multifunction
+// device plugged into the option slots, e.g., Slot #0.
+// Each function has its own PCI configuration space, addressed
+// by the SlotNumber.FunctionNumber field, and will identify which
+// interrput pin of the four it will use in its own InterruptPin register.
+//
+// If the option is a PCI-PCI bridge, interrupts across the bridge will
+// be combined to appear on some combination of the four interrupt pins
+// that the bridge plugs into. On Lego platforms, that routing is dictated by
+// the PICMG specification.
+//
+// InterruptLine:
+// This PCI Configuration register, unlike x86 PC's, is maintained by
+// software and represents offset into PCI interrupt vectors.
+// Whenever HalGetBusData or HalGetBusDataByOffset is called,
+// HalpPCIPinToLine() computes the correct InterruptLine register value
+// by using the HalpPCIPinToLineTable mapping.
+//
+// InterruptRequestRegisterBit:
+// 0xff is used to mark an invalid IRR bit, hence an invalid request
+// for a vector. Also, note that the 16 bits of the EB66 IRR must
+// be access as two 8-bit reads.
+//
+// InterruptMaskRegisterBit:
+// On EB66, the PinToLine table may also be find the to write the
+// InterruptMaskRegister. Formally, we can express this invariant as
+//
+// VectorToIMRBit(InterrruptVector) = InterruptVector - 1
+//
+// On Mustang, the table is useless. The InterruptMaskRegister has
+// only two bits the completely mask all interrupts from either
+// Slot #0 or Slot#1 (PCI AD[17] and AD[18]):
+//
+// InterruptVector in {3,4,5,6} then VectorToIMRBit(InterruptVector) = 0
+// InterruptVector in {7,8,9,10} then VectorToIMRBit(InterruptVector) = 1
+//
+// IDSEL:
+// For accessing PCI configuration space on a local PCI bus (as opposed
+// to over a PCI-PCI bridge), type 0 configuration cycles must be generated.
+// In this case, the IDSEL pin of the device to be accessed is tied to one
+// of the PCI Address lines AD[11] - AD[31]. (The function field in the
+// PCI address is used should we be accessing a multifunction device.)
+// Anyway, virtual slot 0 represents the device with IDSEL = AD[11], and
+// so on.
+//
+
+//
+// Interrupt Vector Table Mapping for Lego
+//
+// You can limit init table to MAX_PCI_LOCAL_DEVICES entries.
+// The virtual slot range on lego is 17-20, so
+// MAX_PCI_LOCAL_DEVICE is defined as 20 in the platform dependent
+// header file (legodef.H). HalpValidPCISlot assures us that
+// we won't ever try to set an InterruptLine register of a slot
+// greater than Virtual slot 20 = PCI_AD[31].
+//
+
+ULONG *HalpPCIPinToLineTable;
+
+//
+// Interrupt Vector Table Mapping for Lego
+//
+// Lego PCI interrupts are mapped to ISA IRQs in the table below.
+//
+// Limit init table to 20 entries, which is the
+// MAX_PCI_LOCAL_DEVICES for Lego.
+// We won't ever try to set an InterruptLine register of a slot
+// less than virtual slot 17 = PCI_AD[28]
+// or greater than Virtual slot 20 = PCI_AD[31].
+//
+
+#define SLOT_UNREACHABLE { 0xff, 0xff, 0xff, 0xff }
+
+#define SLOTS_UNREACHABLE_8 \
+ SLOT_UNREACHABLE, SLOT_UNREACHABLE, SLOT_UNREACHABLE, SLOT_UNREACHABLE, \
+ SLOT_UNREACHABLE, SLOT_UNREACHABLE, SLOT_UNREACHABLE, SLOT_UNREACHABLE
+
+#define SLOTS_UNREACHABLE_12 \
+ SLOTS_UNREACHABLE_8, \
+ SLOT_UNREACHABLE, SLOT_UNREACHABLE, SLOT_UNREACHABLE, SLOT_UNREACHABLE
+
+
+#define SLOTS_UNREACHABLE_17 \
+ SLOTS_UNREACHABLE_12, \
+ SLOT_UNREACHABLE, SLOT_UNREACHABLE, SLOT_UNREACHABLE, SLOT_UNREACHABLE, \
+ SLOT_UNREACHABLE
+
+#define PTL0 0xa
+#define PTL1 0xf
+#define PTL2 0x9
+#define PTL3 0xb
+
+// Pin to Line Table for primary (bus 0) slots
+// when PCI Interrupts routed through SIO
+//
+// **tested**
+//
+ULONG LegoPCIPinToLineTableIsa[][4]=
+{
+ SLOTS_UNREACHABLE_17, // Virtual Slots 0..16 = PCI_AD[11..27]
+ { PTL0, PTL1, PTL2, PTL3 }, // Virtual Slot 17 = PCI_AD[28] Slot #4
+ { PTL3, PTL0, PTL1, PTL2 }, // Virtual Slot 18 = PCI_AD[29] Slot #3
+ { PTL2, PTL3, PTL0, PTL1 }, // Virtual Slot 19 = PCI_AD[30] Slot #2
+ { PTL1, PTL2, PTL3, PTL0 } // Virtual Slot 20 = PCI_AD[31] Slot #1
+};
+
+// Slot 2 is SCSI (NCR810) on Atacama.
+// Give it a dedicated SIO IRQ (as Avanti and friends do)
+//
+// **tested**
+//
+ULONG LegoPCIPinToLineTableIsaAtacama[][4]=
+{
+ SLOTS_UNREACHABLE_17, // Virtual Slots 0..16 = PCI_AD[11..27]
+ { PTL0, PTL1, PTL2, PTL3 }, // Virtual Slot 17 = PCI_AD[28] Slot #4
+ { PTL3, PTL0, PTL1, PTL2 }, // Virtual Slot 18 = PCI_AD[29] Slot #3 -- SCSI
+ { PTL2, 0xff, 0xff, 0xff }, // Virtual Slot 19 = PCI_AD[30] Slot #2
+ { PTL1, PTL2, PTL3, PTL0 } // Virtual Slot 20 = PCI_AD[31] Slot #1
+};
+
+// Pin to Line Table for Bus 1 slots when PCI Interrupts
+// routed through SIO. Bus 1 is behind a PPB in primary slot 1.
+//
+ULONG LegoPCIPinToLineTableIsaBus1[][4]=
+{
+ SLOTS_UNREACHABLE_12, // Virtual Slots 0..11 = PCI_AD[11..27]
+ { PTL1, PTL2, PTL3, PTL0 }, // Virtual Slot 12 = PCI_AD[28] Slot #4
+ { PTL2, PTL3, PTL0, PTL1 }, // Virtual Slot 13 = PCI_AD[29] Slot #3
+ { PTL3, PTL0, PTL1, PTL2 }, // Virtual Slot 14 = PCI_AD[30] Slot #2
+ { PTL0, PTL1, PTL2, PTL3 } // Virtual Slot 15 = PCI_AD[31] Slot #1
+};
+
+// Pin to Line Table for Bus 2 slots when PCI Interrupts
+// routed through SIO. Bus 2 is behind a PPB in primary slot 2.
+//
+ULONG LegoPCIPinToLineTableIsaBus2[][4]=
+{
+ SLOTS_UNREACHABLE_8, // Virtual Slots 0..7 = PCI_AD[11..27]
+ { PTL2, PTL3, PTL0, PTL1 }, // Virtual Slot 8 = PCI_AD[28] Slot #4
+ { PTL3, PTL0, PTL1, PTL2 }, // Virtual Slot 9 = PCI_AD[29] Slot #3
+ { PTL0, PTL1, PTL2, PTL3 }, // Virtual Slot 10 = PCI_AD[30] Slot #2
+ { PTL1, PTL2, PTL3, PTL0 } // Virtual Slot 11 = PCI_AD[31] Slot #1
+};
+
+// Pin to Line Table for primary (bus 0) slots when Lego PCI Interrupt routing enabled
+//
+ULONG LegoPCIPinToLineTable[][4]=
+{
+ SLOTS_UNREACHABLE_17, // Virtual Slots 0..16 = PCI_AD[11..27]
+ { 0x41, 0x42, 0x43, 0x44 }, // Virtual Slot 17 = PCI_AD[28] Slot #4
+ { 0x31, 0x32, 0x33, 0x34 }, // Virtual Slot 18 = PCI_AD[29] Slot #3
+ { 0x21, 0x22, 0x23, 0x24 }, // Virtual Slot 19 = PCI_AD[30] Slot #2
+ { 0x11, 0x12, 0x13, 0x14 } // Virtual Slot 20 = PCI_AD[31] Slot #1
+};
+
+// Pin to Line Table for Bus 1 slots when Lego PCI Interrupt routing enabled
+// Bus 1 is behind a PPB in primary slot 1
+//
+ULONG LegoPCIPinToLineTableBus1[][4]=
+{
+ SLOTS_UNREACHABLE_12, // Virtual Slots 0..11 = PCI_AD[11..27]
+ { 0x1d, 0x1e, 0x1f, 0x20 }, // Virtual Slot 12 = PCI_AD[28] Slot #7 (Gobi) or #6 (Sahara)
+ { 0x19, 0x1a, 0x1b, 0x1c }, // Virtual Slot 13 = PCI_AD[29] Slot #6 or #5
+ { 0x15, 0x16, 0x17, 0x18 }, // Virtual Slot 14 = PCI_AD[30] Slot #5 or #4
+ { 0x11, 0x12, 0x13, 0x14 } // Virtual Slot 15 = PCI_AD[31] Slot #4 or #3
+};
+
+// Pin to Line Table for Bus 2 slots when Lego PCI Interrupt routing enabled
+// Bus 2 is behind a PPB in primary slot 2
+//
+ULONG LegoPCIPinToLineTableBus2[][4]=
+{
+ SLOTS_UNREACHABLE_8, // Virtual Slots 0..7 = PCI_AD[11..27]
+ { 0x2d, 0x2e, 0x2f, 0x30 }, // Virtual Slot 8 = PCI_AD[28] Slot #10
+ { 0x29, 0x2a, 0x2b, 0x2c }, // Virtual Slot 9 = PCI_AD[29] Slot #9
+ { 0x25, 0x26, 0x27, 0x28 }, // Virtual Slot 10 = PCI_AD[30] Slot #8
+ { 0x21, 0x22, 0x23, 0x24 } // Virtual Slot 11 = PCI_AD[31] Slot #7
+};
+
diff --git a/private/ntos/nthals/hallego/alpha/smerr.c b/private/ntos/nthals/hallego/alpha/smerr.c
new file mode 100644
index 000000000..993131568
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/smerr.c
@@ -0,0 +1,390 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+Copyright (c) 1996 Digital Equipment Corporation
+
+Module Name:
+
+ smerr.c
+
+Abstract:
+
+ The module provides the error logging support for Lego's
+ Server Management and Watchdog timer functions.
+
+Author:
+
+ Gene Morgan (Digital) 17-Apr-1996
+
+Revision History:
+
+ Gene Morgan (Digital) 17-Apr-1996
+ Initial version.
+
+--*/
+
+#include "halp.h"
+#include "errframe.h"
+
+//
+// Context structure used interrupt service routines.
+//
+
+typedef BOOLEAN (*PSECOND_LEVEL_DISPATCH)(
+ PKINTERRUPT InterruptObject,
+ PVOID ServiceContext
+ );
+
+//
+// External variable UncorrectableError is declared in inithal.c.
+//
+
+extern PERROR_FRAME PUncorrectableError;
+
+//
+// Counter for correctable events
+//
+
+extern ULONG CorrectedMemoryReads;
+ULONG ServerMgmtEvents = 0;
+
+BOOLEAN HalpServerMgmtLoggingEnabled;
+
+//
+// External function prototypes
+//
+
+UCHAR
+HalpAcknowledgeServerMgmtInterrupt(
+ PVOID ServiceContext
+ );
+
+int
+sprintf( char *, const char *, ... );
+
+//
+// Local prototypes
+//
+
+VOID
+LegoServerMgmtReportWarningCondition(
+ BOOLEAN ReportWatchdog,
+ USHORT SmRegAll,
+ USHORT WdRegAll
+ );
+
+VOID
+LegoServerMgmtReportFatalError(
+ USHORT SmRegAll
+ );
+
+
+//
+// Local routines
+//
+
+VOID
+LegoServerMgmtReportWarningCondition(
+ BOOLEAN ReportWatchdog,
+ USHORT SmRegAll,
+ USHORT WdRegAll
+ )
+/*++
+
+Routine Description:
+
+ Report "correctable error" condition to error log.
+
+Arguments:
+
+ ReportWd -- reporting watchdog timer expiration
+ SmRegAll -- copy of server management register that is to be reported
+ (if ReportWd == FALSE)
+ WdRegAll -- copy of watchdog register that is to be reported
+ (if ReportWd == TRUE)
+
+Return Value:
+
+ None
+
+Notes:
+
+--*/
+{
+ LEGO_SRV_MGMT SmRegister;
+ LEGO_WATCHDOG WdRegister;
+
+ static ERROR_FRAME Frame; // Copy here for error logger's use
+
+ ERROR_FRAME TempFrame; // Build frame here
+ PCORRECTABLE_ERROR CorrPtr;
+ PEXTENDED_ERROR PExtended;
+
+ PBOOLEAN ErrorlogBusy;
+ PULONG DispatchCode;
+ PKINTERRUPT InterruptObject;
+ PKSPIN_LOCK ErrorlogSpinLock;
+
+ //
+ // Copy provided register values
+ //
+
+ WdRegister.All = WdRegAll;
+ SmRegister.All = SmRegAll;
+
+ //
+ // Update the number of correctable errors.
+ //
+
+ CorrectedMemoryReads += 1; // sequence number for all correctable errors
+ ServerMgmtEvents += 1;
+
+
+ //
+ // If error logger not available, do not attempt
+ // to log an error.
+ //
+
+ if (!HalpServerMgmtLoggingEnabled) {
+ return;
+ }
+
+ //
+ // Init the error frame struct
+ //
+
+ RtlZeroMemory(&TempFrame, sizeof(ERROR_FRAME));
+
+ //
+ // Fill in the error frame information.
+ //
+
+ TempFrame.Signature = ERROR_FRAME_SIGNATURE;
+ TempFrame.FrameType = CorrectableFrame;
+ TempFrame.VersionNumber = ERROR_FRAME_VERSION;
+ TempFrame.SequenceNumber = CorrectedMemoryReads;
+ TempFrame.PerformanceCounterValue = KeQueryPerformanceCounter(NULL).QuadPart;
+
+ //
+ // Fill in the specific error information
+ //
+
+ CorrPtr = &TempFrame.CorrectableFrame;
+ CorrPtr->Flags.SystemInformationValid = 1;
+ CorrPtr->Flags.AddressSpace = UNIDENTIFIED;
+ CorrPtr->Flags.MemoryErrorSource = UNIDENTIFIED;
+
+ CorrPtr->Flags.ExtendedErrorValid = 1;
+
+ PExtended = &CorrPtr->ErrorInformation;
+
+ if (ReportWatchdog) {
+
+ //
+ // Unexpected watchdog timer expiration
+ //
+
+ PExtended->SystemError.Flags.WatchDogExpiredValid = 1;
+ PExtended->SystemError.WatchdogExpiration = WdRegister.All; // Watchdog timer expired
+
+ }
+ else {
+
+ //
+ // Server management warning condition
+ //
+
+ if (SmRegister.EnclFanFailure) {
+ PExtended->SystemError.Flags.FanNumberValid = 1;
+ PExtended->SystemError.FanNumber = 2; // Enclosure Fan died
+ }
+ else if (SmRegister.CpuTempFailure) {
+ PExtended->SystemError.Flags.TempSensorNumberValid = 1;
+ PExtended->SystemError.TempSensorNumber = 1; // CPU temp sensor alert
+ }
+ else if (SmRegister.CpuTempRestored) {
+ PExtended->SystemError.Flags.TempSensorNumberValid = 1;
+ PExtended->SystemError.TempSensorNumber = 101; // CPU temp sensor OK
+ }
+ else if (SmRegister.Psu1Failure) {
+ PExtended->SystemError.Flags.PowerSupplyNumberValid = 1;
+ PExtended->SystemError.PowerSupplyNumber = 1; // Power supply #1 dead
+ }
+ else if (SmRegister.Psu2Failure) {
+ PExtended->SystemError.Flags.PowerSupplyNumberValid = 1;
+ PExtended->SystemError.PowerSupplyNumber = 2; // Power supply #2 dead
+ }
+ else {
+
+ //
+ // Error didn't match any expected value -- leave extended error info flag on,
+ // leave all condition flags off.
+ //
+
+ CorrPtr->Flags.ExtendedErrorValid = 1;
+
+#if HALDBG
+ DbgPrint("smerr: No Server Mgmt error to report!\n");
+
+#endif
+ }
+
+ }
+
+ //
+ // Correctable frame complete
+ //
+
+
+ //
+ // Get the interrupt object.
+ //
+
+ DispatchCode = (PULONG)(PCR->InterruptRoutine[CORRECTABLE_VECTOR]);
+ InterruptObject = CONTAINING_RECORD(DispatchCode,
+ KINTERRUPT,
+ DispatchCode);
+
+ //
+ // Acquire spinlock for exclusive access to error frame.
+ //
+
+ ErrorlogBusy = (PBOOLEAN)((PUCHAR)InterruptObject->ServiceContext + sizeof(PERROR_FRAME));
+ ErrorlogSpinLock = (PKSPIN_LOCK)((PUCHAR)ErrorlogBusy + sizeof(PBOOLEAN));
+
+ KiAcquireSpinLock(ErrorlogSpinLock);
+
+ //
+ // Check to see if an errorlog operation is in progress already.
+ //
+
+ if (!*ErrorlogBusy) {
+
+ //
+ // Set the raw system information.
+ //
+
+ CorrPtr->RawSystemInformationLength = 0;
+ CorrPtr->RawSystemInformation = NULL;
+
+ //
+ // Set the raw processor information. Disregard at the moment.
+ //
+
+ CorrPtr->RawProcessorInformationLength = 0;
+
+ //
+ // Set reporting processor information. Disregard at the moment.
+ //
+
+ CorrPtr->Flags.ProcessorInformationValid = 0;
+
+ //
+ // Copy the information that we need to log.
+ //
+
+ RtlCopyMemory(&Frame,
+ &TempFrame,
+ sizeof(ERROR_FRAME));
+
+ //
+ // Put frame into ISR service context.
+ //
+
+ *(PERROR_FRAME *)InterruptObject->ServiceContext = &Frame;
+
+ } else {
+
+ //
+ // An errorlog operation is in progress already. We will
+ // set various lost bits and then get out without doing
+ // an actual errorloging call.
+ //
+ // Chao claims it is not possible to reach this on a UP system.
+ //
+
+ Frame.CorrectableFrame.Flags.LostCorrectable = TRUE;
+ Frame.CorrectableFrame.Flags.LostAddressSpace =
+ TempFrame.CorrectableFrame.Flags.AddressSpace;
+ Frame.CorrectableFrame.Flags.LostMemoryErrorSource =
+ TempFrame.CorrectableFrame.Flags.MemoryErrorSource;
+ }
+
+ //
+ // Release the spinlock.
+ //
+
+ KiReleaseSpinLock(ErrorlogSpinLock);
+
+ //
+ // Dispatch to the secondary correctable interrupt service routine.
+ // The assumption here is that if this interrupt ever happens, then
+ // some driver enabled it, and the driver should have the ISR connected.
+ //
+
+ ((PSECOND_LEVEL_DISPATCH)InterruptObject->DispatchAddress)(
+ InterruptObject,
+ InterruptObject->ServiceContext);
+}
+
+VOID
+LegoServerMgmtReportFatalError(
+ USHORT SmRegAll
+ )
+/*++
+
+Routine Description:
+
+ Report an uncorrectable error.
+
+Arguments:
+
+ SmRegAll -- copy of server management register that is to be reported
+
+Return Value:
+
+ None
+
+Notes:
+
+--*/
+{
+ LEGO_SRV_MGMT SmRegister;
+ PEXTENDED_ERROR PExtended;
+
+ SmRegister.All = SmRegAll;
+
+ //
+ // Load fields of uncorrectable error record
+ //
+
+ if (PUncorrectableError) {
+
+ PUncorrectableError->UncorrectableFrame.Flags.SystemInformationValid = 1;
+ PUncorrectableError->UncorrectableFrame.Flags.AddressSpace = UNIDENTIFIED;
+ PUncorrectableError->UncorrectableFrame.Flags.MemoryErrorSource = UNIDENTIFIED;
+
+ PUncorrectableError->UncorrectableFrame.Flags.ErrorStringValid = 1;
+
+ PUncorrectableError->UncorrectableFrame.Flags.ExtendedErrorValid = 1;
+ PExtended = &PUncorrectableError->UncorrectableFrame.ErrorInformation;
+
+ if (SmRegister.CpuFanFailureNmi) {
+ PExtended->SystemError.Flags.FanNumberValid = 1;
+ PExtended->SystemError.FanNumber = 1; // CPU Fan
+ sprintf(PUncorrectableError->UncorrectableFrame.ErrorString,
+ "CPU fan failed.");
+ }
+ else if (SmRegister.EnclTempFailureNmi) {
+ PExtended->SystemError.Flags.TempSensorNumberValid = 1;
+ PExtended->SystemError.TempSensorNumber = 2; // Enclosure sensor
+ sprintf(PUncorrectableError->UncorrectableFrame.ErrorString,
+ "Enclosure temperature too high for safe operation.");
+ }
+ else {
+ PUncorrectableError->UncorrectableFrame.Flags.ExtendedErrorValid = 0;
+ sprintf(PUncorrectableError->UncorrectableFrame.ErrorString,
+ "Unknown server management NMI failure."); // BUG!
+ }
+ }
+}
diff --git a/private/ntos/nthals/hallego/alpha/smir.c b/private/ntos/nthals/hallego/alpha/smir.c
new file mode 100644
index 000000000..3fe96ccff
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/smir.c
@@ -0,0 +1,722 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+Copyright (c) 1992,1993,1994,1995,1996 Digital Equipment Corporation
+
+Module Name:
+
+ smir.c
+
+Abstract:
+
+ The module provides the interrupt support for Lego's
+ Server Management and Watchdog timer functions.
+
+Author:
+
+ Gene Morgan (Digital) 3-Nov-1995
+
+Revision History:
+
+ Gene Morgan (Digital) 3-Nov-1995
+ Initial version for Lego. Adapted from Mikasa/Noritake.
+
+ Gene Morgan 15-Apr-1996
+ Service Watchdog Timer.
+
+--*/
+
+#include "halp.h"
+
+//
+// Define external function prototypes
+//
+
+UCHAR
+HalpAcknowledgeServerMgmtInterrupt(
+ PVOID ServiceContext
+ );
+
+VOID
+LegoServerMgmtReportWarningCondition(
+ BOOLEAN ReportWatchdog,
+ USHORT SmRegAll,
+ USHORT WdRegAll
+ );
+
+BOOLEAN
+HalpLegoShutdownWatchdog(
+ VOID
+ );
+
+
+//
+// Save area for interrupt mask register.
+//
+USHORT HalpLegoServerMgmtInterruptMask;
+
+//
+// Server management and watchdog timer control.
+// defined/setup in lgmapio.c
+//
+extern PVOID HalpLegoServerMgmtQva;
+extern PVOID HalpLegoWatchdogQva;
+
+//
+// Globals for conveying Cpu and Backplane type
+//
+extern BOOLEAN HalpLegoCpu;
+extern BOOLEAN HalpLegoBackplane;
+extern ULONG HalpLegoCpuType;
+extern ULONG HalpLegoBackplaneType;
+extern UCHAR HalpLegoFeatureMask;
+extern BOOLEAN HalpLegoServiceWatchdog;
+
+//
+// Track whether error logger is available
+//
+extern BOOLEAN HalpServerMgmtLoggingEnabled;
+
+//
+// True if someone has "enabled" interrupts
+// for a particular server management event.
+//
+extern BOOLEAN HalpLegoDispatchWatchdog;
+extern BOOLEAN HalpLegoDispatchNmi;
+extern BOOLEAN HalpLegoDispatchInt;
+extern BOOLEAN HalpLegoDispatchPsu;
+extern BOOLEAN HalpLegoDispatchHalt;
+
+
+VOID
+HalpInitializeServerMgmtInterrupts(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the Lego
+ Server Management and Watchdog Timer functions
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+Notes:
+
+ Goal is to set the Server Management and Watchdog
+ functions to a known state.
+
+--*/
+{
+ LEGO_SRV_MGMT SmRegister;
+ LEGO_WATCHDOG WdRegister;
+
+ //
+ // Initial state is error logger is not available
+ //
+
+ HalpServerMgmtLoggingEnabled = FALSE;
+
+ //
+ // Assume watchdog is idle.
+ // There's no interrupt mask bit, so no work needs to be done here.
+ //
+
+ if (HalpLegoFeatureMask & LEGO_FEATURE_WATCHDOG) {
+
+ //
+ // Do nothing until clock is started.
+ //
+
+ HalpLegoDispatchWatchdog = FALSE;
+
+ }
+
+ // Set the mask bits for all Server Management functions
+ // (i.e., block interrupts)
+ //
+ if (HalpLegoFeatureMask & LEGO_FEATURE_SERVER_MGMT) {
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegister.IntMask = 0;
+ SmRegister.NmiMask = 0;
+ SmRegister.PsuMask = 0; // not present on all platforms
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+
+ HalpLegoDispatchNmi = FALSE;
+ HalpLegoDispatchInt = FALSE;
+ HalpLegoDispatchPsu = FALSE;
+ HalpLegoDispatchHalt = FALSE;
+ }
+}
+
+
+VOID
+HalpDisableServerMgmtInterrupt(
+ IN ULONG Vector
+ )
+
+/*++
+
+Routine Description:
+
+ This function disables the Server Management
+ or Watchdog Timer interrupt specified by Vector.
+
+Arguments:
+
+ Vector - Supplies the vector of the interrupt to disable.
+
+Return Value:
+
+ None.
+
+Notes:
+
+ An interrupt is masked by setting the appropriate mask bit to 1.
+ The halt button cannot be masked.
+
+--*/
+
+{
+ LEGO_SRV_MGMT SmRegister;
+ LEGO_WATCHDOG WdRegister;
+
+ // dispatch on vector to determine which interrupt mask to clear
+ //
+ switch (Vector) {
+
+ case WATCHDOG_VECTOR:
+ //
+ // Disable Watchdog timer interrupts (and the timer itself)
+ //
+ // If timer is running and timer 2 is active, timer 2
+ // must be stopped before the timer can be disabled.
+ //
+
+ HalpLegoShutdownWatchdog();
+
+ //
+ // Re-enable timer but stop performing secondary dispatch
+ //
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+ WdRegister.Enabled = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All );
+
+ HalpLegoDispatchWatchdog = FALSE;
+ break;
+
+ case SM_WARNING_VECTOR:
+
+#if 0
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegister.IntMask = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+#endif
+
+ HalpLegoDispatchInt = FALSE;
+ break;
+
+ case SM_ERROR_VECTOR:
+
+#if 0
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegister.NmiMask = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+#endif
+
+ HalpLegoDispatchNmi = FALSE;
+ break;
+
+ case SM_PSU_FAILURE_VECTOR:
+
+#if 0
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegister.PsuMask = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+#endif
+
+ HalpLegoDispatchPsu = FALSE;
+ break;
+
+ case HALT_BUTTON_VECTOR:
+ //
+ // Halt button cannot be masked -- ignore
+ //
+
+ HalpLegoDispatchHalt = FALSE;
+ break;
+
+ default:
+ //
+ // Error - unrecognized vector
+ //
+ break;
+ }
+}
+
+
+VOID
+HalpEnableServerMgmtInterrupt(
+ IN ULONG Vector,
+ IN KINTERRUPT_MODE InterruptMode
+ )
+
+/*++
+
+Routine Description:
+
+ This function enables the Server Management or
+ Watchdog Timer interrupt specified by Vector.
+
+Arguments:
+
+ Vector - Supplies the vector of the interrupt to be enabled.
+
+ InterruptMode - Supplies the mode of the interrupt;
+ LevelSensitive or Latched //[wem] ??? check this ???
+
+Return Value:
+
+ None.
+
+Notes:
+
+ An interrupt is enabled by clearing the appropriate mask bit (i.e., set to 0).
+ The halt button cannot be masked.
+
+--*/
+
+{
+ LEGO_SRV_MGMT SmRegister;
+ LEGO_WATCHDOG WdRegister;
+
+ // dispatch on vector to determine which interrupt mask to clear
+ //
+ switch (Vector) {
+
+ case WATCHDOG_VECTOR:
+ //
+ // Enable Watchdog timer interrupts (and the timer itself)
+ // Assume all other aspects of the timer are correctly setup, but:
+ //
+ // If timer is already running and timer 2 is active, re-establish timer 1.
+ //
+
+ HalpLegoShutdownWatchdog();
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+ WdRegister.Enabled = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All );
+
+ //
+ // Watchdog is enabled and Timer 1 is now running
+ //
+
+ HalpLegoDispatchWatchdog = TRUE;
+ break;
+
+ case SM_WARNING_VECTOR:
+
+#if 0
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegister.IntMask = 0;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+#endif
+ HalpLegoDispatchInt = TRUE;
+ break;
+
+ case SM_ERROR_VECTOR:
+
+#if 0
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegister.NmiMask = 0;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+#endif
+ HalpLegoDispatchNmi = TRUE;
+ break;
+
+ case SM_PSU_FAILURE_VECTOR:
+
+#if 0
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegister.PsuMask = 0;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+#endif
+ HalpLegoDispatchPsu = TRUE;
+ break;
+
+ case HALT_BUTTON_VECTOR:
+
+ //
+ // Halt button cannot be masked.
+ //
+
+ HalpLegoDispatchHalt = TRUE;
+ break;
+
+ default:
+
+ //
+ // Error - unrecognized vector
+ //
+
+ break;
+ }
+
+}
+
+UCHAR
+HalpAcknowledgeServerMgmtInterrupt(
+ PVOID ServiceContext
+ )
+/*++
+
+Routine Description:
+
+ Acknowledge the Server Management interrupt. Return vector number of the
+ highest priority pending interrupt.
+
+Arguments:
+
+ ServiceContext - Service context of the interrupt service - supplies
+ a QVA to Lego's Server Management interrupt register.
+
+Return Value:
+
+ Return the value of the highest priority pending interrupt,
+ or 0xff if none.
+
+--*/
+{
+ LEGO_SRV_MGMT SmRegister;
+ LEGO_WATCHDOG WdRegister;
+ UCHAR Vector;
+
+ //
+ // Check the watchdog and server management registers to see which
+ // event occurred.
+ //
+ // Read watchdog first since it is most probable cause of interrupt
+ //
+
+ //
+ // Value to return if no match
+ //
+
+ Vector = 0xFF;
+
+ //
+ // Check Watchdog register's interrupt bit.
+ //
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+
+#if DBG
+ DbgPrint(" <WdReg:%04x> ",WdRegister.All);
+#endif
+
+ if (WdRegister.Interrupt==1) {
+
+ Vector = (WATCHDOG_VECTOR - SERVER_MGMT_VECTORS);
+
+#if DBG
+ DbgPrint(" <WdReg:%04x> ",WdRegister.All);
+#endif
+
+ }
+ else {
+
+ //
+ // Check Server Management register bits
+ //
+
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+
+#if DBG
+ DbgPrint(" <SmReg:%04x> ",SmRegister.All);
+#endif
+
+ if (SmRegister.CpuTempFailure==1
+ || SmRegister.CpuTempRestored==1
+ || SmRegister.EnclFanFailure==1) {
+
+ Vector = (SM_WARNING_VECTOR - SERVER_MGMT_VECTORS);
+ }
+ else if (SmRegister.Psu1Failure==1
+ || SmRegister.Psu2Failure) {
+
+ Vector = (SM_PSU_FAILURE_VECTOR - SERVER_MGMT_VECTORS);
+ }
+ }
+
+ return Vector;
+}
+
+
+BOOLEAN
+HalpServerMgmtDispatch(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext,
+ IN PKTRAP_FRAME TrapFrame
+ )
+/*++
+
+Routine Description:
+
+ This routine is entered as the result of an interrupt having been generated
+ via the vector connected to the Server Management device interrupt object.
+ Its function is to call the second-level interrupt dispatch routine.
+
+ If the second level dispatch doesn't handle, then this routine will perform
+ default handling.
+
+ This service routine could have been connected as follows, where the
+ ISR is the assembly wrapper that does the handoff to this function:
+
+ KeInitializeInterrupt( &Interrupt,
+ HalpServerMgmtInterruptHandler,
+ (PVOID) HalpLegoServerMgmtInterruptQva,
+ (PKSPIN_LOCK)NULL,
+ SERVER_MGMT_VECTOR,
+ SERVER_MGMT_DEVICE_LEVEL,
+ SERVER_MGMT_DEVICE_LEVEL,
+ LevelSensitive,
+ TRUE,
+ 0,
+ FALSE);
+
+ KeConnectInterrupt(&Interrupt);
+
+Arguments:
+
+ Interrupt - Supplies a pointer to the interrupt object.
+
+ ServiceContext - Supplies a pointer to the Server Management
+ interrupt register.
+
+ TrapFrame - Supplies a pointer to the trap frame for this interrupt.
+
+Return Value:
+
+ Returns the value returned from the second level routine.
+
+Notes:
+
+ Only the CPU IRQ5 interrupts come through here. Server management
+ NMIs are handled by HalpHandleNmi()
+
+--*/
+{
+ UCHAR SmVector;
+ BOOLEAN returnValue;
+ LEGO_SRV_MGMT SmRegister, SmRegisterLog;
+ LEGO_WATCHDOG WdRegister, WdRegisterLog;
+
+ BOOLEAN LogIt = FALSE;
+ BOOLEAN LogWatchdog = FALSE;
+
+ //
+ // [wem] DEBUG - count SM dispatch entries
+ //
+ static long IntCount = 0;
+
+#if DBG //[wem]
+ IntCount++;
+ if (IntCount<5) {
+ DbgPrint("II<SM><");
+ }
+ if (IntCount % 1000 == 0) {
+ DbgPrint("II<SM><%08x><", IntCount);
+ }
+#endif
+
+ //
+ // Acknowledge interrupt and receive the returned interrupt vector.
+ // If we got 0xff back, there were no enabled interrupts, so we
+ // signal that with a FALSE return, immediately.
+ //
+
+ SmVector = HalpAcknowledgeServerMgmtInterrupt(ServiceContext);
+
+#if DBG
+ DbgPrint("<SmVector:%04x> ",SmVector);
+#endif
+
+ if (SmVector == ((UCHAR)0xff)) {
+
+#if DBG //[wem]
+ if (IntCount<5 || (IntCount % 1000)==0) {
+ DbgPrint("ff>.");
+ }
+#endif
+ return( FALSE );
+ }
+
+ SmVector += SERVER_MGMT_VECTORS;
+
+#if DBG
+ DbgPrint("<SmVector:%04x> ",SmVector);
+#endif
+
+ switch (SmVector) {
+
+ case WATCHDOG_VECTOR:
+
+ if (HalpLegoDispatchWatchdog
+ && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[SmVector])(
+ PCR->InterruptRoutine[SmVector],
+ TrapFrame)
+ ) {
+ return TRUE;
+ }
+
+ WdRegisterLog.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+
+#if DBG
+ DbgPrint("<WdReg:%04x> ",WdRegisterLog.All);
+#endif
+
+ if (HalpLegoServiceWatchdog) {
+
+ //
+ // Get control of the watchdog timer
+ //
+
+ HalpLegoShutdownWatchdog();
+
+ //
+ // Re-enable it
+ //
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+ WdRegister.Enabled = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All);
+
+ returnValue = TRUE;
+ }
+ else {
+
+ //
+ // Dismiss the interrupt -- but system is on the way down!
+ //
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+ WdRegister.Interrupt = 1;
+ WdRegister.Enabled = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All );
+
+ //
+ // Interrupt not serviced
+ //
+
+ returnValue = FALSE;
+
+ }
+
+ LogIt = TRUE;
+ LogWatchdog = TRUE;
+
+ break;
+
+ case SM_WARNING_VECTOR:
+
+ if (HalpLegoDispatchInt
+ && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[SmVector])(
+ PCR->InterruptRoutine[SmVector],
+ TrapFrame)
+ ) {
+ return TRUE;
+ }
+
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegisterLog.All = SmRegister.All;
+
+ // Handle any that were not handled by secondary dispatch
+ //
+ if (SmRegister.CpuTempRestored==1) {
+ HalDisplayString ("Server Management: CPU Temperature restored.\n");
+ }
+ if (SmRegister.CpuTempFailure==1) {
+ HalDisplayString ("Server Management: CPU Temperature warning.\n");
+ }
+ if (SmRegister.EnclFanFailure==1) {
+ HalDisplayString ("Server Management: System fan failure.\n");
+ }
+
+ // Any interrupts will be cleared
+ // Don't touch PSU interrupts
+ //
+ SmRegister.Psu1Failure = 0;
+ SmRegister.Psu2Failure = 0;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+
+ LogIt = TRUE;
+ returnValue = TRUE;
+ break;
+
+ case SM_PSU_FAILURE_VECTOR:
+
+ if (HalpLegoDispatchPsu
+ && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[SmVector])(
+ PCR->InterruptRoutine[SmVector],
+ TrapFrame)
+ ) {
+ return TRUE;
+ }
+
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
+ SmRegisterLog.All = SmRegister.All;
+
+ //
+ // Handle any that were not handled by secondary dispatch
+ //
+
+ if (SmRegister.Psu1Failure==1) {
+ HalDisplayString ("Server Management: PSU 1 has failed.\n");
+ }
+ if (SmRegister.Psu2Failure==1) {
+ HalDisplayString ("Server Management: PSU 2 has failed.\n");
+ }
+
+ // Any interrupts will be cleared
+ // Don't touch fan/temperature interrupts
+ //
+ SmRegister.CpuTempRestored = 0;
+ SmRegister.CpuTempFailure = 0;
+ SmRegister.EnclFanFailure = 0;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
+
+ LogIt = TRUE;
+ returnValue = TRUE;
+
+ break;
+
+
+ default:
+ returnValue = FALSE; //[wem] Error -- bugcheck?
+ }
+
+#if DBG //[wem]
+ if (IntCount<5 || (IntCount % 1000)==0) {
+ DbgPrint("%02x>.", returnValue);
+ }
+#endif
+
+ //
+ // Post "correctable" error record to error log.
+ //
+
+ if (LogIt) {
+ LegoServerMgmtReportWarningCondition(LogWatchdog, SmRegisterLog.All,WdRegisterLog.All);
+ }
+
+ return( returnValue );
+}
diff --git a/private/ntos/nthals/hallego/alpha/smsup.c b/private/ntos/nthals/hallego/alpha/smsup.c
new file mode 100644
index 000000000..c84269e4e
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/smsup.c
@@ -0,0 +1,363 @@
+/*++
+
+Copyright (c) 1996 Digital Equipment Corporation
+
+Module Name:
+
+ smsup.c
+
+Abstract:
+
+ Server Management support
+
+Author:
+
+ Gene Morgan (Digital) 28-Apr-1996
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+#include "pcf8574.h"
+
+
+//
+// Local prototypes
+//
+
+BOOLEAN
+HalpLegoShutdownWatchdog(
+ VOID
+ );
+
+VOID
+HalpLegoInitWatchdog(
+ UCHAR WdMode,
+ UCHAR WdTimer1,
+ UCHAR WdTimer2,
+ BOOLEAN Enabled
+ );
+
+VOID
+HalpPowerOff(
+ VOID
+ );
+
+BOOLEAN
+LegoServerMgmtDelayedShutdown(
+ ULONG DelaySeconds
+ );
+
+
+//
+// Server management and watchdog timer control.
+// defined/setup in lgmapio.c
+//
+extern PVOID HalpLegoServerMgmtQva;
+extern PVOID HalpLegoWatchdogQva;
+
+//
+// Globals for conveying Cpu and Backplane type
+//
+extern BOOLEAN HalpLegoCpu;
+extern BOOLEAN HalpLegoBackplane;
+extern ULONG HalpLegoCpuType;
+extern ULONG HalpLegoBackplaneType;
+extern UCHAR HalpLegoFeatureMask;
+extern BOOLEAN HalpLegoServiceWatchdog;
+
+
+BOOLEAN
+HalpLegoShutdownWatchdog(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ Shutdown the wtachdog timer.
+
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ TRUE if watchdog was successfully shut down, FALSE otherwise.
+
+Notes:
+
+ Algorithm works if watchdog is in stage one or two.
+
+ On TRUE return, Watchdog is ready to be enabled.
+ On FALSE return, watchdog is running, reset will eventually occur.
+
+--*/
+{
+ LEGO_WATCHDOG WdRegister;
+ ULONG Count;
+#if DBG
+ ULONG DbgCnt;
+
+ DbgCnt = 0;
+ DbgPrint(" <Wd:reset:");
+#endif
+
+ Count = 100; // Observations indicate that 2 cycles is sufficient. Still...
+
+ while (1) {
+
+ WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
+
+ if ((WdRegister.Enabled == 0) || (Count-- == 0)) {
+ break;
+ }
+
+ if (WdRegister.Phase == WATCHDOG_PHASE_ONE) {
+
+ WdRegister.Enabled = 0;
+ }
+ else {
+
+ WdRegister.Phase = 1; // should revert to phase 1
+ WdRegister.Enabled = 0;
+ }
+
+ WRITE_REGISTER_USHORT((PUSHORT)HalpLegoWatchdogQva,WdRegister.All);
+
+#if DBG
+ DbgCnt++;
+ if (DbgCnt>10) {
+ DbgPrint(">10> ");
+ break;
+ }
+#endif
+ }
+
+#if DBG
+ DbgPrint("%d> ",DbgCnt);
+#endif
+
+ //
+ // Return TRUE if count not exhausted
+ //
+ return (Count > 0);
+
+}
+
+
+VOID
+HalpLegoInitWatchdog(
+ UCHAR WdMode,
+ UCHAR WdTimer1,
+ UCHAR WdTimer2,
+ BOOLEAN Enabled
+ )
+/*++
+
+Routine Description:
+
+ Setup the Lego watchdog timer.
+
+Arguments:
+
+ WdMode, WdTimer1, WdTimer2 -- new parameters for watchdog timer
+ Enabled -- TRUE if timer should be started
+
+Return Value:
+
+ None.
+
+ ++*/
+{
+ LEGO_WATCHDOG WdRegister;
+
+ if (HalpLegoFeatureMask & LEGO_FEATURE_WATCHDOG) {
+
+ //
+ // Disable watchdog in case it was running
+ //
+
+ HalpLegoShutdownWatchdog();
+ }
+
+ if (HalpLegoFeatureMask & LEGO_FEATURE_WATCHDOG) {
+
+ //
+ // Set mode and timers, leave disabled for now
+ // HAL will enable the timer during its initialization
+ //
+
+ WdRegister.All = 0;
+ WdRegister.Mode = WdMode;
+ WdRegister.TimerOnePeriod = WdTimer1;
+ WdRegister.TimerTwoPeriod = WdTimer2;
+
+#if DBG
+ DbgPrint("Watchdog setting: %04x\n",WdRegister.All);
+#endif
+ WRITE_REGISTER_USHORT((PUSHORT)HalpLegoWatchdogQva,WdRegister.All);
+
+ if (Enabled) {
+ WdRegister.Enabled = 1;
+ WRITE_REGISTER_USHORT((PUSHORT)HalpLegoWatchdogQva,WdRegister.All);
+ }
+ }
+}
+
+
+VOID
+HalpPowerOff(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Shutdown the system (i.e., shutdown power supply)
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ Doesn't return.
+
+Notes:
+
+ This will work iff the proper connections to the power supply exists.
+
+ ++*/
+{
+ LEGO_SRV_MGMT SmRegister;
+ UCHAR Buffer[2];
+ int i,j,k;
+
+ //
+ // Set the power off bit in the server management register
+ //
+ // [wem] ??? Currently it appears that toggling the bit 1->0 triggers
+ // the shutdown. Toggle it both ways just in case...
+
+ SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva);
+ SmRegister.PowerOff = 0;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva,SmRegister.All);
+ SmRegister.PowerOff = 1;
+ WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva,SmRegister.All);
+
+ //
+ // Wait forever if necessary
+ //
+
+ i=j=k=0;
+ HalpOcpPutString("SHUT:000", 8, 0);
+ Buffer[1] = '\0';
+
+ while (1) {
+
+ if (i == 10) {
+ i = 0;
+ if (j == 10) {
+ j = 0;
+ if (k == 10) {
+ k = 0;
+ }
+ HalpOcpPutString(((k & 1)==0)?"DOWN":"SHUT", 4, 0);
+ Buffer[0] = '0' + k;
+ HalpOcpPutString(Buffer, 1, 5);
+ k++;
+ }
+ Buffer[0] = '0' + j;
+ HalpOcpPutString(Buffer, 1, 6);
+ j++;
+ }
+ Buffer[0] = '0' + i;
+ HalpOcpPutString(Buffer, 1, 7);
+ i++;
+ }
+
+}
+
+BOOLEAN
+LegoServerMgmtDelayedShutdown(
+ ULONG DelaySeconds
+ )
+/*++
+
+Routine Description:
+
+ Schedule a powerdown.
+
+ Current algorithm:
+ 1. Shutdown watchdog.
+ 2. Init watchdog for requested delay and single-stage timeout
+ (since interrupts will be shut off
+ 3. Set boolean to indicate power-down in progress
+ 4. return TRUE if power-down will occur
+
+ When reset is performed, firmware will get control, rediscover
+ failure, and act accordingly.
+
+ Problem? will shutdown or KeBugCheck disable interrupts? May have to do
+ something else...
+
+Arguments:
+
+ DelaySeconds -- desired delay. Should match capabilities of watchdog.
+
+Return Value:
+
+ TRUE if reset successfully initiated
+
+Notes:
+
+--*/
+{
+ BOOLEAN WillShutdown;
+ UCHAR Period;
+ ULONG Count;
+
+ //
+ // If watchdog not present, bail out
+ //
+
+ if (!(HalpLegoFeatureMask & LEGO_FEATURE_WATCHDOG)) {
+ return FALSE;
+ }
+
+ //
+ // Shutdown watchdog, then set it up for the
+ // requested delay.
+ //
+
+ WillShutdown = HalpLegoShutdownWatchdog();
+
+ if (WillShutdown) {
+ if (DelaySeconds <= 1) {
+ Period = WATCHDOG_PERIOD_1S;
+ }
+ else if (DelaySeconds <= 8) {
+ Period = WATCHDOG_PERIOD_8S;
+ }
+ else if (DelaySeconds <= 60) {
+ Period = WATCHDOG_PERIOD_60S;
+ }
+ else if (DelaySeconds <= 300) {
+ Period = WATCHDOG_PERIOD_300S;
+ }
+ else if (DelaySeconds <= 1200) {
+ Period = WATCHDOG_PERIOD_1200S;
+ }
+
+ HalpLegoInitWatchdog(WATCHDOG_MODE_1TIMER,
+ Period,
+ Period,
+ TRUE);
+ }
+
+ return WillShutdown; // Power-off attempt failed!
+}
diff --git a/private/ntos/nthals/hallego/alpha/vga.c b/private/ntos/nthals/hallego/alpha/vga.c
new file mode 100644
index 000000000..764c585af
--- /dev/null
+++ b/private/ntos/nthals/hallego/alpha/vga.c
@@ -0,0 +1,7 @@
+//
+// This file simply includes the source file from the common Alpha
+// HAL directory.
+//
+
+#include "..\halalpha\vga.c"
+