summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halr96b/mips
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/halr96b/mips
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/halr96b/mips')
-rw-r--r--private/ntos/nthals/halr96b/mips/allstart.c272
-rw-r--r--private/ntos/nthals/halr96b/mips/busdat.c1231
-rw-r--r--private/ntos/nthals/halr96b/mips/cacherr.s11
-rw-r--r--private/ntos/nthals/halr96b/mips/cirrus.h281
-rw-r--r--private/ntos/nthals/halr96b/mips/cmdcnst.h105
-rw-r--r--private/ntos/nthals/halr96b/mips/esm.c1182
-rw-r--r--private/ntos/nthals/halr96b/mips/esmnvram.h688
-rw-r--r--private/ntos/nthals/halr96b/mips/glint.h580
-rw-r--r--private/ntos/nthals/halr96b/mips/halp.h365
-rw-r--r--private/ntos/nthals/halr96b/mips/j4cache.s11
-rw-r--r--private/ntos/nthals/halr96b/mips/j4flshbf.s11
-rw-r--r--private/ntos/nthals/halr96b/mips/j4flshio.c236
-rw-r--r--private/ntos/nthals/halr96b/mips/j4prof.c11
-rw-r--r--private/ntos/nthals/halr96b/mips/jxbeep.c215
-rw-r--r--private/ntos/nthals/halr96b/mips/jxdisp.c3605
-rw-r--r--private/ntos/nthals/halr96b/mips/jxdmadsp.s11
-rw-r--r--private/ntos/nthals/halr96b/mips/jxebsup.c1398
-rw-r--r--private/ntos/nthals/halr96b/mips/jxenvirv.c800
-rw-r--r--private/ntos/nthals/halr96b/mips/jxhalp.h224
-rw-r--r--private/ntos/nthals/halr96b/mips/jxhwsup.c4265
-rw-r--r--private/ntos/nthals/halr96b/mips/jxmapio.c11
-rw-r--r--private/ntos/nthals/halr96b/mips/jxmaptb.c11
-rw-r--r--private/ntos/nthals/halr96b/mips/jxport.c11
-rw-r--r--private/ntos/nthals/halr96b/mips/jxreturn.c258
-rw-r--r--private/ntos/nthals/halr96b/mips/jxsysint.c355
-rw-r--r--private/ntos/nthals/halr96b/mips/jxtime.c377
-rw-r--r--private/ntos/nthals/halr96b/mips/jxusage.c510
-rw-r--r--private/ntos/nthals/halr96b/mips/mipsdat.c145
-rw-r--r--private/ntos/nthals/halr96b/mips/mode542x.h1302
-rw-r--r--private/ntos/nthals/halr96b/mips/modeset.h85
-rw-r--r--private/ntos/nthals/halr96b/mips/pcibrd.c1020
-rw-r--r--private/ntos/nthals/halr96b/mips/pcibus.c3585
-rw-r--r--private/ntos/nthals/halr96b/mips/pciint.c376
-rw-r--r--private/ntos/nthals/halr96b/mips/pcip.h200
-rw-r--r--private/ntos/nthals/halr96b/mips/pcisup.c632
-rw-r--r--private/ntos/nthals/halr96b/mips/r94adbg.c157
-rw-r--r--private/ntos/nthals/halr96b/mips/r94adef.h266
-rw-r--r--private/ntos/nthals/halr96b/mips/r94adma.h433
-rw-r--r--private/ntos/nthals/halr96b/mips/r94ainfo.c99
-rw-r--r--private/ntos/nthals/halr96b/mips/r94aint.h35
-rw-r--r--private/ntos/nthals/halr96b/mips/r94aio.s149
-rw-r--r--private/ntos/nthals/halr96b/mips/r94anmi.s621
-rw-r--r--private/ntos/nthals/halr96b/mips/rgb525.h468
-rw-r--r--private/ntos/nthals/halr96b/mips/tga.h93
-rw-r--r--private/ntos/nthals/halr96b/mips/x4clock.s433
-rw-r--r--private/ntos/nthals/halr96b/mips/x4tb.s11
-rw-r--r--private/ntos/nthals/halr96b/mips/x86bios.c1261
-rw-r--r--private/ntos/nthals/halr96b/mips/xxcalstl.c302
-rw-r--r--private/ntos/nthals/halr96b/mips/xxclock.c11
-rw-r--r--private/ntos/nthals/halr96b/mips/xxidle.s11
-rw-r--r--private/ntos/nthals/halr96b/mips/xxinithl.c934
-rw-r--r--private/ntos/nthals/halr96b/mips/xxinitnt.c11
-rw-r--r--private/ntos/nthals/halr96b/mips/xxipiint.s11
-rw-r--r--private/ntos/nthals/halr96b/mips/xxmvmem.s264
54 files changed, 29950 insertions, 0 deletions
diff --git a/private/ntos/nthals/halr96b/mips/allstart.c b/private/ntos/nthals/halr96b/mips/allstart.c
new file mode 100644
index 000000000..8363d1dcc
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/allstart.c
@@ -0,0 +1,272 @@
+/* #pragma comment(exestr, "@(#) NEC(MIPS) allstart.c 1.2 95/10/17 01:17:28" ) */
+/*++
+
+Copyright (c) 1995 NEC Corporation
+Copyright (c) 1994 Microsoft Corporation
+
+Module Name:
+
+ allstart.c
+
+Abstract:
+
+
+ This module implements the platform specific operations that must be
+ performed after all processors have been started.
+
+Author:
+
+ David N. Cutler (davec) 19-Jun-1994
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+Modification History for NEC R94A (MIPS R4400):
+
+ H000 Mon Oct 17 09:29:01 JST 1994 kbnes!kishimoto
+ -chg function name HalpCreateEisaStructures()
+ changed for HalpCreateEisaPCIStructures()
+ H001 Mon Oct 17 19:09:23 JST 1994 kbnes!kishimoto
+ -del Hal(p)EisaPCIXXX() rename to Hal(p)EisaXXX()
+ M002 Tue Jan 31 17:51:41 JST 1995 kbnes!A.Kuriyama
+ -add set NMI Handle routine to FW
+ M003 Tue Jan 31 18:41:45 JST 1995 kbnes!A.Kuriyama
+ -add NMI Handle valiable
+ S004 Tue Jan 31 19:05:16 JST 1995 kbnes!A.Kuriyama
+ - compile error clear
+ M005 Fri Feb 17 15:57:02 JST 1995 kbnes!A.Kuriyama
+ - set NMI routine at KSEG1_BASE
+ S006 Tue Feb 21 21:04:42 JST 1995 kbnes!A.Kuriyama
+ - disable dump nmi untill dump support.
+ M007 Wed Feb 22 11:27:18 JST 1995 kbnes!kuriyama (A)
+ - change NMI dumpflag
+ - add display NMI register
+ M008 Wed Feb 22 14:14:19 JST 1995 kbnes!kuriyama (A)
+ - compile error clear
+ S009 Wed Feb 22 14:34:31 JST 1995 kbnes!kuriyama (A)
+ - warning clear
+ S010 Tue Mar 07 14:13:41 JST 1995 kbnes!kuriyama (A)
+ - warning clear
+ S011 Sat Mar 18 20:19:57 JST 1995 kbnes!kuriyaam (A)
+ - enable dump nmi
+ M012 Sat Mar 18 20:24:58 JST 1995 kbnes!kuriyama (A)
+ - change nmi logic
+ M013 Mon May 08 23:20:10 JST 1995 kbnes!kuriyama (A)
+ - EISA/PCI interrupt change to CPU-A on MultiProcessor
+ S014 kuriyama@oa2.kb.nec.co.jp Mon May 22 03:55:08 JST 1995
+ - Set Panic Flag for esm
+ M015 kuriyama@oa2.kb.nec.co.jp Mon Jun 05 03:08:04 JST 1995
+ - Change NMI interface address to HalpNMIInterfaceAddress
+ S016 kuriyama@oa2.kb.nec.co.jp Mon Jun 05 04:49:24 JST 1995
+ - NMI Interface bug fix
+ M017 kuriyama@oa2.kb.nec.co.jp Fri Jun 16 20:26:09 JST 1995
+ - add Enable Ecc 1bit error exception
+ S018 kuriyama@oa2.kb.nec.co.jp Wed Jun 28 13:23:19 JST 1995
+ - add set dump switch flag for esm
+ M019 kuriyama@oa2.kb.nec.co.jp Wed Jun 28 18:50:42 JST 1995
+ - change ecc 1bit was not set enable
+ if nvram is not initialize.
+ M020 kisimoto@oa2.kb.nec.co.jp Fri Aug 11 14:11:16 1995
+ - clear M013. delete test code, dump switch interface.
+
+ S021 kuriyama@oa2.kbnes.nec.co.jp Tue Oct 17 00:51:42 JST 1995
+ - change length of NMISave
+
+--*/
+
+#include "halp.h"
+#include "esmnvram.h" // M019
+#include <stdio.h> // S010
+
+ULONG HalpNMIFlag = 0;
+ULONG HalpDumpNMIFlag = 0; // S006, M008
+ULONG HalpNMISave0[0x80 / 4]; // S021
+ULONG HalpNMISave1[0x80 / 4]; // S021
+
+extern ULONG HalpNMIInterfaceAddress;
+
+VOID
+HalpNMIDispatch(
+ VOID
+ );
+
+BOOLEAN
+HalAllProcessorsStarted (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function executes platform specific operations that must be
+ performed after all processors have been started. It is called
+ for each processor in the host configuration.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If platform specific operations are successful, then return TRUE.
+ Otherwise, return FALSE.
+
+--*/
+
+{
+
+ //
+ // M002,M005,M015,S016,M020
+ // set NMI Handle routine to firmware interface.
+ //
+
+ if (HalpNMIInterfaceAddress) {
+ *(PVOID *)(KSEG0_BASE|HalpNMIInterfaceAddress) = (PVOID)(KSEG1_BASE | (ULONG)HalpNMIDispatch);
+ }
+
+ //
+ // M017,M019
+ // Enable and clear ECC 1bit error.
+ //
+
+ {
+ ULONG DataWord;
+ KIRQL OldIrql;
+ UCHAR dataBuf[36];
+ UCHAR tempBuf[24];
+
+ #define NVRAM_STATE_FLG_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->nvram_flag)
+ #define NVRAM_MAGIC_NO_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->system.magic)
+ #define NVRAM_VALID 3
+ #define NVRAM_MAGIC 0xff651026
+
+ HalNvramRead( NVRAM_STATE_FLG_OFFSET, 1, dataBuf );
+ HalNvramRead( NVRAM_MAGIC_NO_OFFSET, 4, tempBuf );
+ if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){
+
+ KeRaiseIrql(HIGH_LEVEL,&OldIrql);
+ KiAcquireSpinLock(&Ecc1bitDisableLock);
+ DataWord =
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic.u.LargeInteger.LowPart;
+
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic.u.LargeInteger.LowPart =
+ 0xffddffff & DataWord;
+ KeFlushWriteBuffer();
+
+ KiReleaseSpinLock(&Ecc1bitDisableLock);
+ KeLowerIrql(OldIrql);
+ }
+
+ }
+
+ //
+ // If the number of processors in the host configuration is one,
+ // then connect EISA interrupts to that processor zero. Otherwise,
+ // connect EISA interrupts to processor one.
+ //
+
+ if (**((PULONG *)(&KeNumberProcessors)) == 1) {
+ return HalpCreateEisaStructures();
+
+#if defined(_INT_LIMIT_)
+ } else if (PCR->Number == 0) {
+#else
+ } else if (PCR->Number == 1) {
+#endif // _INT_LIMIT_
+ return HalpCreateEisaStructures();
+
+ } else {
+ return TRUE;
+ }
+}
+
+VOID
+HalpNMIInterrupt(
+ ULONG DumpStatus
+ )
+
+/*++
+
+Routine Description:
+
+ This routine was called when dump swich was pressed or Fatal NMI occued.
+ We call KeBugCheckEx() in order to Dump.
+
+Arguments:
+
+ DumpStatus: Dump Switch Status
+
+ 0 Dump Switch was not pressed.
+ 1 Dump Switch was pressed.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ ULONG NMISource;
+ ULONG MemoryFailed;
+ LARGE_INTEGER InvalidAddressValue;
+ LARGE_INTEGER EccDiagnosticValue;
+ UCHAR Buffer[100];
+
+ HalpChangePanicFlag(16, (UCHAR)(0x01 | (4 * DumpStatus)), 0x10); // S014,S018
+
+ //
+ // M007,M012
+ // Check DumpStatus.and Display NMI status.
+ //
+
+ if (DumpStatus == 1) {
+ HalDisplayString("HAL:Dump Switch Pressed!\n");
+ } else {
+ HalDisplayString("HAL:NMI occured\n");
+ }
+
+ //
+ // Display NMI registers
+ //
+
+ NMISource = READ_REGISTER_ULONG(&DMA_CONTROL->NmiSource.Long);
+ sprintf(Buffer, "HAL:NmiSource register = %x\n",NMISource);
+ HalDisplayString((UCHAR *)Buffer);
+
+ MemoryFailed = READ_REGISTER_ULONG(
+ &((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long);
+ sprintf(Buffer,
+ "HAL:MemoryFailedAddress register = %x\n",
+ MemoryFailed);
+ HalDisplayString((UCHAR *)Buffer);
+
+ READ_REGISTER_DWORD(
+ (PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress,
+ &InvalidAddressValue);
+ sprintf(Buffer,
+ "HAL:Processor Invalid Address register = %x %x\n",
+ InvalidAddressValue.HighPart,InvalidAddressValue.LowPart);
+ HalDisplayString((UCHAR *)Buffer);
+
+ READ_REGISTER_DWORD(
+ (PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic,
+ &EccDiagnosticValue);
+ sprintf(Buffer,
+ "HAL:EccDiagnostic register = %x %x\n",
+ EccDiagnosticValue.HighPart,EccDiagnosticValue.LowPart);
+ HalDisplayString((UCHAR *)Buffer);
+
+ //
+ // M007,M008
+ // call KeBugCheckEx() for dump.
+ //
+
+ KeBugCheckEx(NMI_HARDWARE_FAILURE,DumpStatus,NMISource,0,0);
+
+ return;
+
+}
diff --git a/private/ntos/nthals/halr96b/mips/busdat.c b/private/ntos/nthals/halr96b/mips/busdat.c
new file mode 100644
index 000000000..1218588b8
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/busdat.c
@@ -0,0 +1,1231 @@
+// #pragma comment(exestr, "@(#) busdat.c 1.1 95/09/28 15:30:19 nec")
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ ixhwsup.c
+
+Abstract:
+
+ This module contains the IoXxx routines for the NT I/O system that
+ are hardware dependent. Were these routines not hardware dependent,
+ they would reside in the iosubs.c module.
+
+Author:
+
+ Ken Reneris (kenr) July-28-1994
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+Modification History:
+
+ H001 Fri Jun 30 02:57:29 1995 kbnes!kisimoto
+ - Merge build 1057
+ H002 Sat Jul 1 19:53:41 1995 kbnes!kisimoto
+ - change 'Base' and 'Limit' value on Internal
+
+--*/
+
+#include "halp.h"
+#include "string.h" // H001
+
+UCHAR HalName[] = "NEC MIPS HAL"; // H001
+
+VOID HalpInitializePciBus (VOID); // H001
+VOID HalpInitOtherBuses (VOID);
+
+ULONG
+HalpNoBusData (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+#if !defined(_R94A_)
+ULONG HalpcGetCmosData (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+ULONG HalpcSetCmosData (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+ULONG HalpGetCmosData (
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Length
+ );
+
+ULONG HalpSetCmosData (
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Length
+ );
+#endif // !_R94A_
+
+HalpGetEisaData (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+//
+// Prototype for system bus handlers
+//
+
+NTSTATUS
+HalpAdjustEisaResourceList (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
+ );
+
+ULONG
+HalpGetSystemInterruptVector (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ );
+
+ULONG
+HalpGetEisaInterruptVector (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ );
+
+#if defined(_R94A_) // H001
+ULONG
+HalpGetPCIInterruptVector(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ );
+#endif
+
+BOOLEAN
+HalpTranslateSystemBusAddress (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ );
+
+BOOLEAN
+HalpTranslateIsaBusAddress (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ );
+
+BOOLEAN
+HalpTranslateEisaBusAddress (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ );
+
+VOID
+HalpRegisterInternalBusHandlers (
+ VOID
+ );
+
+NTSTATUS
+HalpHibernateHal (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler
+ );
+
+NTSTATUS
+HalpResumeHal (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler
+ );
+
+#ifdef MCA
+//
+// Default functionality of MCA handlers is the same as the Eisa handlers,
+// just use them
+//
+
+#define HalpGetMCAInterruptVector HalpGetEisaInterruptVector
+#define HalpAdjustMCAResourceList HalpAdjustEisaResourceList;
+
+HalpGetPosData (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+
+#endif
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpRegisterInternalBusHandlers)
+#pragma alloc_text(INIT,HalpAllocateBusHandler)
+#endif
+
+
+VOID
+HalpRegisterInternalBusHandlers (
+ VOID
+ )
+{
+ PBUS_HANDLER Bus;
+
+ if (KeGetCurrentPrcb()->Number) {
+ // only need to do this once
+ return ;
+ }
+
+ //
+ // Initalize BusHandler data before registering any handlers
+ //
+
+ HalpInitBusHandler ();
+
+ //
+ // Build internal-bus 0, or system level bus
+ //
+
+ Bus = HalpAllocateBusHandler (
+ Internal,
+ ConfigurationSpaceUndefined,
+ 0, // Internal BusNumber 0
+ InterfaceTypeUndefined, // no parent bus
+ 0,
+ 0 // no bus specfic data
+ );
+
+ Bus->GetInterruptVector = HalpGetSystemInterruptVector;
+ Bus->TranslateBusAddress = HalpTranslateSystemBusAddress;
+
+ //
+ // Build internal-bus 0, or system level bus
+ //
+ // H001: kugi Internal Bus was called with bus-no. 2, We have no idea.
+
+ Bus = HalpAllocateBusHandler (
+ Internal,
+ ConfigurationSpaceUndefined,
+ 1, // Internal BusNumber 1
+ InterfaceTypeUndefined, // no parent bus
+ 0,
+ 0 // no bus specfic data
+ );
+
+ Bus->GetInterruptVector = HalpGetSystemInterruptVector;
+ Bus->TranslateBusAddress = HalpTranslateSystemBusAddress;
+
+ //
+ // Build Isa/Eisa bus #0
+ //
+
+ Bus = HalpAllocateBusHandler (Eisa, EisaConfiguration, 0, Internal, 0, 0);
+ Bus->GetBusData = HalpGetEisaData;
+ Bus->GetInterruptVector = HalpGetEisaInterruptVector;
+ Bus->AdjustResourceList = HalpAdjustEisaResourceList;
+ Bus->TranslateBusAddress = HalpTranslateEisaBusAddress;
+
+ Bus = HalpAllocateBusHandler (Isa, ConfigurationSpaceUndefined, 0, Eisa, 0, 0);
+ Bus->GetBusData = HalpNoBusData;
+ Bus->BusAddresses->Memory.Limit = 0xFFFFFF;
+ Bus->TranslateBusAddress = HalpTranslateIsaBusAddress;
+ HalpInitOtherBuses ();
+}
+
+
+
+PBUS_HANDLER
+HalpAllocateBusHandler (
+ IN INTERFACE_TYPE InterfaceType,
+ IN BUS_DATA_TYPE BusDataType,
+ IN ULONG BusNumber,
+ IN INTERFACE_TYPE ParentBusInterfaceType,
+ IN ULONG ParentBusNumber,
+ IN ULONG BusSpecificData
+ )
+/*++
+
+Routine Description:
+
+ Stub function to map old style code into new HalRegisterBusHandler code.
+
+ Note we can add our specific bus handler functions after this bus
+ handler structure has been added since this is being done during
+ hal initialization.
+
+--*/
+{
+ PBUS_HANDLER Bus;
+
+
+ //
+ // Create bus handler - new style
+ //
+
+ HaliRegisterBusHandler (
+ InterfaceType,
+ BusDataType,
+ BusNumber,
+ ParentBusInterfaceType,
+ ParentBusNumber,
+ BusSpecificData,
+ NULL,
+ &Bus
+ );
+
+ if (InterfaceType != InterfaceTypeUndefined) {
+ Bus->BusAddresses = ExAllocatePool (SPRANGEPOOL, sizeof (SUPPORTED_RANGES));
+ RtlZeroMemory (Bus->BusAddresses, sizeof (SUPPORTED_RANGES));
+ Bus->BusAddresses->Version = BUS_SUPPORTED_RANGE_VERSION;
+ Bus->BusAddresses->Dma.Limit = 7;
+// Bus->BusAddresses->Memory.Limit = 0xFFFFFFFF; // H001
+ Bus->BusAddresses->IO.Limit = 0xFFFF;
+ Bus->BusAddresses->IO.SystemAddressSpace = 0; // H001
+ Bus->BusAddresses->PrefetchMemory.Base = 1;
+
+ //
+ // start H001, H002
+ // configurate the bus specific data
+ //
+
+ switch(InterfaceType) {
+
+ case Internal:
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Base))->LowPart
+ = 0x80000000;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Limit))->LowPart
+ = 0x800FFFFF;
+ Bus->BusAddresses->Memory.SystemBase
+ = 0x00000000;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.Base))->LowPart
+ = 0x80000000;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.Limit))->LowPart
+ = 0x800FFFFF;
+ Bus->BusAddresses->IO.SystemBase
+ = 0x00000000;
+ break;
+
+ case Eisa:
+ Bus->BusAddresses->Memory.Base = 0x00000000;
+ Bus->BusAddresses->Memory.Limit = 0x03FFFFFF;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart
+ = EISA_MEMORY_VERSION2_LOW;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->HighPart
+ = EISA_MEMORY_VERSION2_HIGH;
+ Bus->BusAddresses->IO.Base = 0x00000000;
+ Bus->BusAddresses->IO.Limit = 0x0000FFFF;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->LowPart
+ = EISA_CONTROL_PHYSICAL_BASE;
+ break;
+
+ case Isa:
+ Bus->BusAddresses->Memory.Base = 0x00000000;
+ Bus->BusAddresses->Memory.Limit = 0x00FFFFFF;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart
+ = EISA_MEMORY_VERSION2_LOW;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->HighPart
+ = EISA_MEMORY_VERSION2_HIGH;
+ Bus->BusAddresses->IO.Base = 0x00000000;
+ Bus->BusAddresses->IO.Limit = 0x0000FFFF;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->LowPart
+ = EISA_CONTROL_PHYSICAL_BASE;
+ break;
+
+ case PCIBus:
+ Bus->BusAddresses->Memory.Base = 0x04000000; // from 64MB
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Limit))->LowPart
+ = 0xFFFFFFFF; // up to 4GB
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart
+ = PCI_MEMORY_PHYSICAL_BASE_LOW;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->HighPart
+ = PCI_MEMORY_PHYSICAL_BASE_HIGH;
+ Bus->BusAddresses->IO.Base = 0x00000000;
+ Bus->BusAddresses->IO.Limit = 0x0000FFFF;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->LowPart
+ = PCI_CONTROL_PHYSICAL_BASE;
+ break;
+ }
+ }
+
+ return Bus;
+}
+
+
+#if !defined(_R94A_)
+
+//
+// C to Asm thunks for CMos
+//
+
+ULONG HalpcGetCmosData (
+ IN PBUS_HANDLER BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ // bugbug: this interface should be rev'ed to support non-zero offsets
+ if (Offset != 0) {
+ return 0;
+ }
+
+ return HalpGetCmosData (BusHandler->BusNumber, SlotNumber, Buffer, Length);
+}
+
+
+ULONG HalpcSetCmosData (
+ IN PBUS_HANDLER BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ // bugbug: this interface should be rev'ed to support non-zero offsets
+ if (Offset != 0) {
+ return 0;
+ }
+
+ return HalpSetCmosData (BusHandler->BusNumber, SlotNumber, Buffer, Length);
+}
+
+#endif // !_R94A_
+
+#if defined(_R94A_)
+
+VOID
+HalReportResourceUsage (
+ VOID
+ )
+{
+ ANSI_STRING AHalName;
+ UNICODE_STRING UHalName;
+
+#if 0 // H001: support next version
+ HalpRegisterAddressUsage (&HalpDefaultPcIoSpace);
+ HalpRegisterAddressUsage (&HalpEisaIoSpace);
+ HalpRegisterAddressUsage (&HalpMapRegisterMemorySpace);
+#endif
+
+ RtlInitAnsiString (&AHalName, HalName);
+ RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE);
+ HalpReportResourceUsage (
+ &UHalName, // descriptive name
+ Internal // device space interface type
+ );
+
+ RtlFreeUnicodeString (&UHalName);
+
+ //
+ // Registry is now intialized, see if there are any PCI buses
+ //
+
+ HalpInitializePciBus ();
+
+}
+
+VOID
+HalpInitOtherBuses (
+ VOID
+ )
+{
+ // no other internal buses supported
+}
+
+ULONG
+HalpGetEisaInterruptVector(
+ IN PVOID BusHandler,
+ IN PVOID 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.
+
+Arguments:
+
+ BusHandle - Per bus specific structure
+
+ Irql - Returns the system request priority.
+
+ Affinity - Returns the system wide irq affinity.
+
+Return Value:
+
+ Returns the system interrupt vector corresponding to the specified device.
+
+--*/
+{
+ //
+ // Jazz and Duo only have one I/O bus which is an EISA, so the bus
+ // number and the bus interrupt vector are unused.
+ //
+ // The IRQL level is always equal to the EISA level.
+ //
+
+ *Affinity = HalpEisaBusAffinity;
+
+ *Irql = EISA_DEVICE_LEVEL;
+
+ //
+ // Bus interrupt level 2 is actually mapped to bus level 9 in the Eisa
+ // hardware.
+ //
+
+ if (BusInterruptLevel == 2) {
+ BusInterruptLevel = 9;
+ }
+
+ //
+ // The vector is equal to the specified bus level plus the EISA_VECTOR.
+ //
+
+ return(BusInterruptLevel + EISA_VECTORS);
+}
+
+ULONG
+HalpGetPCIInterruptVector(
+ 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.
+
+Arguments:
+
+ BusHandle - Per bus specific structure
+
+ Irql - Returns the system request priority.
+
+ Affinity - Returns the system wide irq affinity.
+
+Return Value:
+
+ Returns the system interrupt vector corresponding to the specified device.
+
+--*/
+{
+ *Affinity = HalpEisaBusAffinity;
+ *Irql = EISA_DEVICE_LEVEL;
+
+ return(BusInterruptVector + PCI_VECTORS);
+}
+
+HalpGetEisaData (
+ IN PBUS_HANDLER BusHandler, // H001
+ IN PBUS_HANDLER RootHandler, // H001
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function returns the Eisa bus data for a slot or address.
+
+Arguments:
+
+ Buffer - Supplies the space to store the data.
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+--*/
+
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ OBJECT_ATTRIBUTES BusObjectAttributes;
+ PWSTR EisaPath = L"\\Registry\\Machine\\Hardware\\Description\\System\\EisaAdapter";
+ PWSTR ConfigData = L"Configuration Data";
+ ANSI_STRING TmpString;
+ ULONG BusNumber;
+ UCHAR BusString[] = "00";
+ UNICODE_STRING RootName, BusName;
+ UNICODE_STRING ConfigDataName;
+ NTSTATUS NtStatus;
+ PKEY_VALUE_FULL_INFORMATION ValueInformation;
+ PCM_FULL_RESOURCE_DESCRIPTOR Descriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource;
+ PCM_EISA_SLOT_INFORMATION SlotInformation;
+ ULONG PartialCount;
+ ULONG TotalDataSize, SlotDataSize;
+ HANDLE EisaHandle, BusHandle;
+ ULONG BytesWritten, BytesNeeded;
+ PUCHAR KeyValueBuffer;
+ ULONG i;
+ ULONG DataLength = 0;
+ PUCHAR DataBuffer = Buffer;
+ BOOLEAN Found = FALSE;
+
+ PAGED_CODE (); // H001
+
+
+ RtlInitUnicodeString(
+ &RootName,
+ EisaPath
+ );
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &RootName,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)NULL,
+ NULL
+ );
+
+ //
+ // Open the EISA root
+ //
+
+ NtStatus = ZwOpenKey(
+ &EisaHandle,
+ KEY_READ,
+ &ObjectAttributes
+ );
+
+ if (!NT_SUCCESS(NtStatus)) {
+ DbgPrint("HAL: Open Status = %x\n",NtStatus);
+ return(0);
+ }
+
+ //
+ // Init bus number path
+ //
+
+ BusNumber = BusHandler->BusNumber;
+ if (BusNumber > 99) {
+ return (0);
+ }
+
+ if (BusNumber > 9) {
+ BusString[0] += (UCHAR) (BusNumber/10);
+ BusString[1] += (UCHAR) (BusNumber % 10);
+ } else {
+ BusString[0] += (UCHAR) BusNumber;
+ BusString[1] = '\0';
+ }
+
+ RtlInitAnsiString(
+ &TmpString,
+ BusString
+ );
+
+ RtlAnsiStringToUnicodeString(
+ &BusName,
+ &TmpString,
+ TRUE
+ );
+
+
+ InitializeObjectAttributes(
+ &BusObjectAttributes,
+ &BusName,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)EisaHandle,
+ NULL
+ );
+
+ //
+ // Open the EISA root + Bus Number
+ //
+
+ NtStatus = ZwOpenKey(
+ &BusHandle,
+ KEY_READ,
+ &BusObjectAttributes
+ );
+
+ if (!NT_SUCCESS(NtStatus)) {
+ DbgPrint("HAL: Opening Bus Number: Status = %x\n",NtStatus);
+ return(0);
+ }
+
+ //
+ // opening the configuration data. This first call tells us how
+ // much memory we need to allocate
+ //
+
+ RtlInitUnicodeString(
+ &ConfigDataName,
+ ConfigData
+ );
+
+ //
+ // This should fail. We need to make this call so we can
+ // get the actual size of the buffer to allocate.
+ //
+
+ ValueInformation = (PKEY_VALUE_FULL_INFORMATION) &i;
+ NtStatus = ZwQueryValueKey(
+ BusHandle,
+ &ConfigDataName,
+ KeyValueFullInformation,
+ ValueInformation,
+ 0,
+ &BytesNeeded
+ );
+
+ KeyValueBuffer = ExAllocatePool(
+ NonPagedPool,
+ BytesNeeded
+ );
+
+ if (KeyValueBuffer == NULL) {
+#if DBG
+ DbgPrint("HAL: Cannot allocate Key Value Buffer\n");
+#endif
+ ZwClose(BusHandle);
+ return(0);
+ }
+
+ ValueInformation = (PKEY_VALUE_FULL_INFORMATION)KeyValueBuffer;
+
+ NtStatus = ZwQueryValueKey(
+ BusHandle,
+ &ConfigDataName,
+ KeyValueFullInformation,
+ ValueInformation,
+ BytesNeeded,
+ &BytesWritten
+ );
+
+
+ ZwClose(BusHandle);
+
+ if (!NT_SUCCESS(NtStatus)) {
+#if DBG
+ DbgPrint("HAL: Query Config Data: Status = %x\n",NtStatus);
+#endif
+ ExFreePool(KeyValueBuffer);
+ return(0);
+ }
+
+
+ //
+ // We get back a Full Resource Descriptor List
+ //
+
+ Descriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PUCHAR)ValueInformation +
+ ValueInformation->DataOffset);
+
+ PartialResource = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
+ &(Descriptor->PartialResourceList.PartialDescriptors);
+ PartialCount = Descriptor->PartialResourceList.Count;
+
+ for (i = 0; i < PartialCount; i++) {
+
+ //
+ // Do each partial Resource
+ //
+
+ switch (PartialResource->Type) {
+ case CmResourceTypeNull:
+ case CmResourceTypePort:
+ case CmResourceTypeInterrupt:
+ case CmResourceTypeMemory:
+ case CmResourceTypeDma:
+
+ //
+ // We dont care about these.
+ //
+
+ PartialResource++;
+
+ break;
+
+ case CmResourceTypeDeviceSpecific:
+
+ //
+ // Bingo!
+ //
+
+ TotalDataSize = PartialResource->u.DeviceSpecificData.DataSize;
+
+ SlotInformation = (PCM_EISA_SLOT_INFORMATION)
+ ((PUCHAR)PartialResource +
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+
+ while (((LONG)TotalDataSize) > 0) {
+
+ if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) {
+
+ SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION);
+
+ } else {
+
+ SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) +
+ SlotInformation->NumberFunctions *
+ sizeof(CM_EISA_FUNCTION_INFORMATION);
+ }
+
+ if (SlotDataSize > TotalDataSize) {
+
+ //
+ // Something is wrong again
+ //
+
+ ExFreePool(KeyValueBuffer);
+ return(0);
+
+ }
+
+ if (SlotNumber != 0) {
+
+ SlotNumber--;
+
+ SlotInformation = (PCM_EISA_SLOT_INFORMATION)
+ ((PUCHAR)SlotInformation + SlotDataSize);
+
+ TotalDataSize -= SlotDataSize;
+
+ continue;
+
+ }
+
+ //
+ // This is our slot
+ //
+
+ Found = TRUE;
+ break;
+
+ }
+
+ //
+ // End loop
+ //
+
+ i = PartialCount;
+
+ break;
+
+ default:
+
+#if DBG
+ DbgPrint("Bad Data in registry!\n");
+#endif
+
+ ExFreePool(KeyValueBuffer);
+ return(0);
+
+ }
+
+ }
+
+ if (Found) {
+ i = Length + Offset;
+ if (i > SlotDataSize) {
+ i = SlotDataSize;
+ }
+
+ DataLength = i - Offset;
+ RtlMoveMemory (Buffer, ((PUCHAR)SlotInformation + Offset), DataLength);
+ }
+
+ ExFreePool(KeyValueBuffer);
+ return DataLength;
+}
+
+// from ixsysbus.c
+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 translates a bus-relative address space and address into
+ a system physical address.
+
+Arguments:
+
+ BusAddress - Supplies the bus-relative address
+
+ AddressSpace - Supplies the address space number.
+ Returns the host address space number.
+
+ AddressSpace == 0 => memory space
+ AddressSpace == 1 => I/O space
+
+ TranslatedAddress - Supplies a pointer to return the translated address
+
+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
+
+--*/
+
+{
+ PSUPPORTED_RANGE pRange;
+
+ pRange = NULL;
+ switch (*AddressSpace) {
+ case 0:
+ // verify memory address is within buses memory limits
+ for (pRange = &BusHandler->BusAddresses->PrefetchMemory; pRange; pRange = pRange->Next) {
+ if (BusAddress.QuadPart >= pRange->Base &&
+ BusAddress.QuadPart <= pRange->Limit) {
+ break;
+ }
+ }
+
+ if (!pRange) {
+ for (pRange = &BusHandler->BusAddresses->Memory; pRange; pRange = pRange->Next) {
+ if (BusAddress.QuadPart >= pRange->Base &&
+ BusAddress.QuadPart <= pRange->Limit) {
+ break;
+ }
+ }
+ }
+
+ break;
+
+ case 1:
+ // verify IO address is within buses IO limits
+ for (pRange = &BusHandler->BusAddresses->IO; pRange; pRange = pRange->Next) {
+ if (BusAddress.QuadPart >= pRange->Base &&
+ BusAddress.QuadPart <= pRange->Limit) {
+ break;
+ }
+ }
+ break;
+ }
+
+ if (pRange) {
+ TranslatedAddress->QuadPart = BusAddress.QuadPart + pRange->SystemBase;
+ *AddressSpace = pRange->SystemAddressSpace;
+ return TRUE;
+ }
+
+ //
+ //
+ // PCI Translate Bus Address workaround
+ //
+ //
+
+ if (((BusHandler->InterfaceType == PCIBus)) &&
+ (*AddressSpace == 0) &&
+ (BusAddress.QuadPart >= 0) &&
+ (BusAddress.QuadPart <= 0xffffffff )) {
+ TranslatedAddress->QuadPart = BusAddress.QuadPart + 0x100000000;
+ return TRUE;
+ }
+
+
+ return FALSE;
+}
+
+ULONG
+HalpGetSystemInterruptVector(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ )
+
+/*++
+
+Routine Description:
+
+Arguments:
+
+ BusInterruptLevel - Supplies the bus specific interrupt level.
+
+ BusInterruptVector - Supplies the bus specific interrupt vector.
+
+ Irql - Returns the system request priority.
+
+ Affinity - Returns the system wide irq affinity.
+
+Return Value:
+
+ Returns the system interrupt vector corresponding to the specified device.
+
+--*/
+{
+ *Affinity = 1;
+ *Irql = (KIRQL)BusInterruptLevel;
+
+ if ( READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ASIC3Revision) == 0 ){
+
+ //
+ // The bit assign of TYPHOON(in STORM chipset)'s I/O Device Interrupt
+ // Enable register is zero origin.
+ //
+ // N.B. This obstruction is limiteded to beta-version of STORM chipset.
+ //
+
+ return(BusInterruptVector + DEVICE_VECTORS);
+
+ }else{
+
+ return(BusInterruptVector);
+
+ }
+}
+
+BOOLEAN
+HalpTranslateEisaBusAddress(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ )
+
+/*++
+
+Routine Description:
+
+ This function translates a bus-relative address space and address into
+ a system physical address.
+
+Arguments:
+
+ BusAddress - Supplies the bus-relative address
+
+ AddressSpace - Supplies the address space number.
+ Returns the host address space number.
+
+ AddressSpace == 0 => memory space
+ AddressSpace == 1 => I/O space
+
+ TranslatedAddress - Supplies a pointer to return the translated address
+
+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
+
+--*/
+
+{
+ BOOLEAN Status;
+
+ //
+ // Translated normally
+ //
+
+ Status = HalpTranslateSystemBusAddress (
+ BusHandler,
+ RootHandler,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress
+ );
+
+
+ //
+ // If it could not be translated, and it's in the 640k - 1m
+ // range then (for compatibility) try translating it on the
+ // Internal bus for
+ //
+
+ if (Status == FALSE &&
+ *AddressSpace == 0 &&
+ BusAddress.HighPart == 0 &&
+ BusAddress.LowPart >= 0xA0000 &&
+ BusAddress.LowPart < 0xFFFFF) {
+
+ Status = HalTranslateBusAddress (
+ Internal,
+ 0,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress
+ );
+ }
+
+ return Status;
+}
+
+BOOLEAN
+HalpTranslateIsaBusAddress(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ )
+
+/*++
+
+Routine Description:
+
+ This function translates a bus-relative address space and address into
+ a system physical address.
+
+Arguments:
+
+ BusAddress - Supplies the bus-relative address
+
+ AddressSpace - Supplies the address space number.
+ Returns the host address space number.
+
+ AddressSpace == 0 => memory space
+ AddressSpace == 1 => I/O space
+
+ TranslatedAddress - Supplies a pointer to return the translated address
+
+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
+
+--*/
+
+{
+ BOOLEAN Status;
+
+ //
+ // Translated normally
+ //
+
+ Status = HalpTranslateSystemBusAddress (
+ BusHandler,
+ RootHandler,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress
+ );
+
+
+ //
+ // If it could not be translated, and it's memory space
+ // then we allow the translation as it would occur on it's
+ // corrisponding EISA bus. We're allowing this because
+ // many VLBus drivers are claiming to be ISA devices.
+ // (yes, they should claim to be VLBus devices, but VLBus is
+ // run by video cards and like everything else about video
+ // there's no hope of fixing it. (At least according to
+ // Andre))
+ //
+
+ if (Status == FALSE && *AddressSpace == 0) {
+ Status = HalTranslateBusAddress (
+ Eisa,
+ BusHandler->BusNumber,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress
+ );
+ }
+
+ return Status;
+}
+
+NTSTATUS
+HalpAdjustEisaResourceList (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
+ )
+{
+ SUPPORTED_RANGE InterruptRange;
+
+ RtlZeroMemory (&InterruptRange, sizeof InterruptRange);
+ InterruptRange.Base = 0;
+ InterruptRange.Limit = 15;
+
+ return HaliAdjustResourceListRange (
+ BusHandler->BusAddresses,
+ &InterruptRange,
+ pResourceList
+ );
+}
+
+#endif // _R94A_
diff --git a/private/ntos/nthals/halr96b/mips/cacherr.s b/private/ntos/nthals/halr96b/mips/cacherr.s
new file mode 100644
index 000000000..0b3cdf5ce
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/cacherr.s
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\cacherr.s"
diff --git a/private/ntos/nthals/halr96b/mips/cirrus.h b/private/ntos/nthals/halr96b/mips/cirrus.h
new file mode 100644
index 000000000..d827568cf
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/cirrus.h
@@ -0,0 +1,281 @@
+// #pragma comment(exestr, "@(#) cirrus.h 1.1 95/09/28 15:31:10 nec")
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ cirrus.h
+
+Abstract:
+
+ This module contains the definitions for the code that implements the
+ Cirrus Logic VGA 6410/6420/542x device driver.
+
+Environment:
+
+ Kernel mode
+
+Notes:
+
+ This module based on Cirrus Minport Driver. And modify for R96 MIPS
+ R4400 HAL Cirrus display initialize.
+
+Revision History:
+
+
+--*/
+
+/*
+ * M001 1993.19.28 A. Kuriyama @ oa2
+ *
+ * - Modify for R96 MIPS R4400 HAL
+ *
+ * Delete : Miniport Driver Interface
+ *
+ *
+ * Revision History in Cirrus Miniport Driver as follows:
+ *
+ * L001 1993.10.15 Kuroki
+ *
+ * - Modify for R96 MIPS R4400 *
+ * Delete : Micro channel Bus Initialize.
+ * VDM & Text, Fullscreen mode support.
+ * Banking routine.
+ * CL64xx Chip support.
+ * 16-color mode.
+ *
+ * Add : Liner Addressing.
+ *
+ * L002 1993.10.21 Kuroki
+ *
+ * - Warniing clear
+ *
+ * S003 1993.1.13 kbnes!A.Kuriyama
+ *
+ * - VGA Address was changed
+ *
+ */
+
+//
+// Change Ushort to Uchar, because R96 is mips machine.
+//
+
+
+//
+// Base address of VGA memory range. Also used as base address of VGA
+// memory when loading a font, which is done with the VGA mapped at A0000.
+//
+
+/* START L001 */
+
+#define LA_MASK 0xE /* S003 */
+#define MEM_VGA (LA_MASK << 20)
+#define MEM_VGA_SIZE 0x100000
+
+/* END L001 */
+
+//
+// Port definitions for filling the ACCSES_RANGES structure in the miniport
+// information, defines the range of I/O ports the VGA spans.
+// There is a break in the IO ports - a few ports are used for the parallel
+// port. Those cannot be defined in the ACCESS_RANGE, but are still mapped
+// so all VGA ports are in one address range.
+//
+
+#define VGA_BASE_IO_PORT 0x000003B0
+#define VGA_START_BREAK_PORT 0x000003BB
+#define VGA_END_BREAK_PORT 0x000003C0
+#define VGA_MAX_IO_PORT 0x000003DF
+
+//
+// VGA port-related definitions.
+//
+
+//
+// VGA register definitions
+//
+ // ports in monochrome mode
+#define CRTC_ADDRESS_PORT_MONO 0x0004 // CRT Controller Address and
+#define CRTC_DATA_PORT_MONO 0x0005 // Data registers in mono mode
+#define FEAT_CTRL_WRITE_PORT_MONO 0x000A // Feature Control write port
+ // in mono mode
+#define INPUT_STATUS_1_MONO 0x000A // Input Status 1 register read
+ // port in mono mode
+#define ATT_INITIALIZE_PORT_MONO INPUT_STATUS_1_MONO
+ // Register to read to reset
+ // Attribute Controller index/data
+#define ATT_ADDRESS_PORT 0x0010 // Attribute Controller Address and
+#define ATT_DATA_WRITE_PORT 0x0010 // Data registers share one port
+ // for writes, but only Address is
+ // readable at 0x010
+#define ATT_DATA_READ_PORT 0x0011 // Attribute Controller Data reg is
+ // readable here
+#define MISC_OUTPUT_REG_WRITE_PORT 0x0012 // Miscellaneous Output reg write
+ // port
+#define INPUT_STATUS_0_PORT 0x0012 // Input Status 0 register read
+ // port
+#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013 // Bit 0 enables/disables the
+ // entire VGA subsystem
+#define SEQ_ADDRESS_PORT 0x0014 // Sequence Controller Address and
+#define SEQ_DATA_PORT 0x0015 // Data registers
+#define DAC_PIXEL_MASK_PORT 0x0016 // DAC pixel mask reg
+#define DAC_ADDRESS_READ_PORT 0x0017 // DAC register read index reg,
+ // write-only
+#define DAC_STATE_PORT 0x0017 // DAC state (read/write),
+ // read-only
+#define DAC_ADDRESS_WRITE_PORT 0x0018 // DAC register write index reg
+#define DAC_DATA_REG_PORT 0x0019 // DAC data transfer reg
+#define FEAT_CTRL_READ_PORT 0x001A // Feature Control read port
+#define MISC_OUTPUT_REG_READ_PORT 0x001C // Miscellaneous Output reg read
+ // port
+#define GRAPH_ADDRESS_PORT 0x001E // Graphics Controller Address
+#define GRAPH_DATA_PORT 0x001F // and Data registers
+
+ // ports in color mode
+#define CRTC_ADDRESS_PORT_COLOR 0x0024 // CRT Controller Address and
+#define CRTC_DATA_PORT_COLOR 0x0025 // Data registers in color mode
+#define FEAT_CTRL_WRITE_PORT_COLOR 0x002A // Feature Control write port
+#define INPUT_STATUS_1_COLOR 0x002A // Input Status 1 register read
+ // port in color mode
+#define ATT_INITIALIZE_PORT_COLOR INPUT_STATUS_1_COLOR
+ // Register to read to reset
+ // Attribute Controller index/data
+ // toggle in color mode
+
+//
+// Offsets in HardwareStateHeader->PortValue[] of save areas for non-indexed
+// VGA registers.
+//
+
+#define CRTC_ADDRESS_MONO_OFFSET 0x04
+#define FEAT_CTRL_WRITE_MONO_OFFSET 0x0A
+#define ATT_ADDRESS_OFFSET 0x10
+#define MISC_OUTPUT_REG_WRITE_OFFSET 0x12
+#define VIDEO_SUBSYSTEM_ENABLE_OFFSET 0x13
+#define SEQ_ADDRESS_OFFSET 0x14
+#define DAC_PIXEL_MASK_OFFSET 0x16
+#define DAC_STATE_OFFSET 0x17
+#define DAC_ADDRESS_WRITE_OFFSET 0x18
+#define GRAPH_ADDRESS_OFFSET 0x1E
+#define CRTC_ADDRESS_COLOR_OFFSET 0x24
+#define FEAT_CTRL_WRITE_COLOR_OFFSET 0x2A
+
+// toggle in color mode
+//
+// VGA indexed register indexes.
+//
+
+// CL-GD542x specific registers:
+//
+#define IND_CL_EXTS_ENB 0x06 // index in Sequencer to enable exts
+#define IND_CL_SCRATCH_PAD 0x0A // index in Seq of POST scratch pad
+#define IND_CL_ID_REG 0x27 // index in CRTC of ID Register
+//
+#define IND_CURSOR_START 0x0A // index in CRTC of the Cursor Start
+#define IND_CURSOR_END 0x0B // and End registers
+#define IND_CURSOR_HIGH_LOC 0x0E // index in CRTC of the Cursor Location
+#define IND_CURSOR_LOW_LOC 0x0F // High and Low Registers
+#define IND_VSYNC_END 0x11 // index in CRTC of the Vertical Sync
+ // End register, which has the bit
+ // that protects/unprotects CRTC
+ // index registers 0-7
+#define IND_SET_RESET_ENABLE 0x01 // index of Set/Reset Enable reg in GC
+#define IND_DATA_ROTATE 0x03 // index of Data Rotate reg in GC
+#define IND_READ_MAP 0x04 // index of Read Map reg in Graph Ctlr
+#define IND_GRAPH_MODE 0x05 // index of Mode reg in Graph Ctlr
+#define IND_GRAPH_MISC 0x06 // index of Misc reg in Graph Ctlr
+#define IND_BIT_MASK 0x08 // index of Bit Mask reg in Graph Ctlr
+#define IND_SYNC_RESET 0x00 // index of Sync Reset reg in Seq
+#define IND_MAP_MASK 0x02 // index of Map Mask in Sequencer
+#define IND_MEMORY_MODE 0x04 // index of Memory Mode reg in Seq
+#define IND_CRTC_PROTECT 0x11 // index of reg containing regs 0-7 in
+ // CRTC
+#define IND_CRTC_COMPAT 0x34 // index of CRTC Compatibility reg
+ // in CRTC
+#define START_SYNC_RESET_VALUE 0x01 // value for Sync Reset reg to start
+ // synchronous reset
+#define END_SYNC_RESET_VALUE 0x03 // value for Sync Reset reg to end
+ // synchronous reset
+
+//
+// Values for Attribute Controller Index register to turn video off
+// and on, by setting bit 5 to 0 (off) or 1 (on).
+//
+
+#define VIDEO_DISABLE 0
+#define VIDEO_ENABLE 0x20
+
+// Masks to keep only the significant bits of the Graphics Controller and
+// Sequencer Address registers. Masking is necessary because some VGAs, such
+// as S3-based ones, don't return unused bits set to 0, and some SVGAs use
+// these bits if extensions are enabled.
+//
+
+#define GRAPH_ADDR_MASK 0x0F
+#define SEQ_ADDR_MASK 0x07
+
+//
+// Mask used to toggle Chain4 bit in the Sequencer's Memory Mode register.
+//
+
+#define CHAIN4_MASK 0x08
+
+//
+// Value written to the Read Map register when identifying the existence of
+// a VGA in VgaInitialize. This value must be different from the final test
+// value written to the Bit Mask in that routine.
+//
+
+#define READ_MAP_TEST_SETTING 0x03
+
+//
+// Default text mode setting for various registers, used to restore their
+// states if VGA detection fails after they've been modified.
+//
+
+#define MEMORY_MODE_TEXT_DEFAULT 0x02
+#define BIT_MASK_DEFAULT 0xFF
+#define READ_MAP_DEFAULT 0x00
+
+
+//
+// Palette-related info.
+//
+
+//
+// Highest valid DAC color register index.
+//
+
+#define VIDEO_MAX_COLOR_REGISTER 0xFF
+
+//
+// Indices for type of memory mapping; used in ModesVGA[], must match
+// MemoryMap[].
+//
+
+typedef enum _VIDEO_MEMORY_MAP {
+ MemMap_Mono,
+ MemMap_CGA,
+ MemMap_VGA
+} VIDEO_MEMORY_MAP, *PVIDEO_MEMORY_MAP;
+
+//
+// For a mode, the type of banking supported. Controls the information
+// returned in VIDEO_BANK_SELECT. PlanarHCBanking includes NormalBanking.
+//
+
+typedef enum _BANK_TYPE {
+ NoBanking = 0,
+ NormalBanking,
+ PlanarHCBanking
+} BANK_TYPE, *PBANK_TYPE;
+
+#define CL6410 0x0001
+#define CL6420 0x0002
+#define CL542x 0x0004
+
+// bitfields for the DisplayType
+#define crt 0x0001
+#define panel 0x0002
+#define simulscan 0x0004 // this means both, but is unused for now.
diff --git a/private/ntos/nthals/halr96b/mips/cmdcnst.h b/private/ntos/nthals/halr96b/mips/cmdcnst.h
new file mode 100644
index 000000000..ea2bba221
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/cmdcnst.h
@@ -0,0 +1,105 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ cmdcnst.h
+
+Abstract:
+
+ This is the command string interpreter definitions
+
+Environment:
+
+ kernel mode only
+
+Notes:
+
+ This module is same file on Cirrus Minport Driver.
+
+Revision History:
+
+--*/
+
+//--------------------------------------------------------------------------
+// Definition of the set/clear mode command language.
+//
+// Each command is composed of a major portion and a minor portion.
+// The major portion of a command can be found in the most significant
+// nibble of a command byte, while the minor portion is in the least
+// significant portion of a command byte.
+//
+// maj minor Description
+// ---- ----- --------------------------------------------
+// 00 End of data
+//
+// 10 in and out type commands as described by flags
+// flags:
+//
+// xxxx
+// ||||
+// |||+-------- unused
+// ||+--------- 0/1 single/multiple values to output (in's are always
+// |+---------- 0/1 8/16 bit operation single)
+// +----------- 0/1 out/in instruction
+//
+// Outs
+// ----------------------------------------------
+// 0 reg:W val:B
+// 2 reg:W cnt:W val1:B val2:B...valN:B
+// 4 reg:W val:W
+// 6 reg:W cnt:W val1:W val2:W...valN:W
+//
+// Ins
+// ----------------------------------------------
+// 8 reg:W
+// a reg:W cnt:W
+// c reg:W
+// e reg:W cnt:W
+//
+// 20 Special purpose outs
+// 00 do indexed outs for seq, crtc, and gdc
+// indexreg:W cnt:B startindex:B val1:B val2:B...valN:B
+// 01 do indexed outs for atc
+// index-data_reg:W cnt:B startindex:B val1:B val2:B...valN:B
+// 02 do masked outs
+// indexreg:W andmask:B xormask:B
+//
+// F0 Nop
+//
+//---------------------------------------------------------------------------
+
+// some useful equates - major commands
+
+#define EOD 0x000 // end of data
+#define INOUT 0x010 // do ins or outs
+#define METAOUT 0x020 // do special types of outs
+#define NCMD 0x0f0 // Nop command
+
+
+// flags for INOUT major command
+
+//#define UNUSED 0x01 // reserved
+#define MULTI 0x02 // multiple or single outs
+#define BW 0x04 // byte/word size of operation
+#define IO 0x08 // out/in instruction
+
+// minor commands for metout
+
+#define INDXOUT 0x00 // do indexed outs
+#define ATCOUT 0x01 // do indexed outs for atc
+#define MASKOUT 0x02 // do masked outs using and-xor masks
+
+
+// composite inout type commands
+
+#define OB (INOUT) // output 8 bit value
+#define OBM (INOUT+MULTI) // output multiple bytes
+#define OW (INOUT+BW) // output single word value
+#define OWM (INOUT+BW+MULTI) // output multiple words
+
+#define IB (INOUT+IO) // input byte
+#define IBM (INOUT+IO+MULTI) // input multiple bytes
+#define IW (INOUT+IO+BW) // input word
+#define IWM (INOUT+IO+BW+MULTI) // input multiple words
diff --git a/private/ntos/nthals/halr96b/mips/esm.c b/private/ntos/nthals/halr96b/mips/esm.c
new file mode 100644
index 000000000..f15acb3c6
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/esm.c
@@ -0,0 +1,1182 @@
+// #pragma comment(exestr, "@(#) esm.c 1.1 95/09/28 15:31:51 nec")
+/*++
+
+Copyright (c) 1995 Kobe NEC Software
+
+Module Name:
+
+ esm.c
+
+Abstract:
+
+ This module implements the ESM service routine
+
+Author:
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ L001 kuriyama@oa2.kb.nec.co.jp Thu Jun 15 14:57:14 JST 1995
+ -Change HalpEccError() for support J94C ECC error
+
+ M002 kuriyama@oa2.kb.nec.co.jp Thu Jun 22 14:31:57 JST 1995
+ - add ecc 1bit safety flag
+
+ M003 kuriyama@oa2.kb.nec.co.jp Thu Jun 22 20:40:52 JST 1995
+ - add serialize ecc 1bit routine
+
+ S004 kuriyama@oa2.kb.nec.co.jp Fri Jun 23 16:55:12 JST 1995
+ - bug fix ecc 2bit error
+--*/
+#include "halp.h"
+#include "esmnvram.h"
+#include "bugcodes.h"
+#include "stdio.h"
+
+//
+// define offset.
+//
+
+#define NVRAM_STATE_FLG_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->nvram_flag)
+#define NVRAM_MAGIC_NO_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->system.magic)
+#define ECC_1BIT_ERROR_LOG_INFO_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->ecc1bit_err.offset_1biterr)
+#define ECC_1BIT_ERROR_LOG_INFO_LATEST_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->ecc1bit_err.offset_latest)
+#define ECC_2BIT_ERROR_LOG_INFO_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->ecc2bit_err.offset_2biterr)
+#define ECC_2BIT_ERROR_LOG_INFO_LATEST_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->ecc2bit_err.offset_latest)
+#define SYSTEM_ERROR_LOG_INFO_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->system_err.offset_systemerr)
+#define SYSTEM_ERROR_LOG_INFO_LATEST_OFFSET (USHORT)&(((pNVRAM_HEADER)0)->system_err.offset_latest)
+
+
+#define STOP_ERR_LOG_AREA_HEADER_SIZE (USHORT)&(((pSTOP_ERR_REC)0)->err_description)
+#define TIME_STAMP_SIZE 14
+
+//
+// define value
+//
+
+#define NVRAM_VALID 3
+#define NVRAM_MAGIC 0xff651026
+#define ECC_LOG_VALID_FLG 1
+
+// L001++
+#define STORM_ECC_1BIT_ERROR 1
+#define STORM_ECC_2BIT_ERROR 2
+#define STORM_OTHER_ERROR 0
+// L001---
+
+//#define SDCR_SET0_ADDR 0xb9100030
+//#define SDCR_SET1_ADDR 0xb9120030
+
+#define STRING_BUFFER_SIZE 512
+
+#define ECC_1BIT_ERROR_DISABLE_TIME 5*1000*1000*10
+
+// M002 +++
+
+//
+// Define Ecc safety flags
+//
+
+#define CHECKED 1
+#define NOT_CHECKED 0
+#define RUNNING 1
+#define NOT_RUNNING 0
+// M002 ---
+
+//
+// Define global variable. This variable use in display string into nvram.
+//
+
+ULONG CallCountOfInitDisplay = 0;
+ULONG HalpNvramValid=FALSE;
+USHORT ErrBufferLatest;
+USHORT ErrBufferArea;
+USHORT ErrBufferStart;
+USHORT ErrBufferEnd;
+USHORT ErrBufferCurrent;
+ULONG HalpPanicFlg=0;
+UCHAR HalpNvramStringBuffer[STRING_BUFFER_SIZE];
+ULONG HalpNvramStringBufferCounter=0;
+
+// L001+++
+//LONG HalpECC1bitDisableFlag=1; // S001
+//LONG HalpECC1bitDisableTime=0; // S003
+//ULONG HalpECC1bitScfrBuffer=0; // S003
+ULONG HalpEcc1bitCount[2] = {0,0};
+ULONG HalpOldMemoryFailed[2] = {0,0};
+ULONG HalpEcc2bitErrorFlag = 0;
+// L001---
+
+// M002 +++
+
+// ecc 1bit total count
+ULONG HalpEcc1bitTotalCount = 0;
+
+// variables for ecc1bit safety flag
+extern ULONG HalpAnotherRunningECC;
+extern ULONG HalpAnotherCheckedECC;
+// M002 ---
+
+
+UCHAR KernelPanicMessage[]="*** STOP: 0x"; // S002
+
+//
+// Define macro
+//
+#if 0
+#define GET_PADDR(addr,sts2,SicSet) { \
+ (addr) = ( ( ((PSTS2_REGISTER)&(sts2) )->COL0_9 << 4 ) \
+ + ( ((PSTS2_REGISTER)&(sts2) )->LOW0_9 << 14 ) \
+ + ( ((PSTS2_REGISTER)&(sts2) )->SIMN << 24 ) \
+ + ( ((PSTS2_REGISTER)&(sts2) )->COL10 << 25 ) \
+ + ( ((PSTS2_REGISTER)&(sts2) )->LOW10 << 26 ) \
+ + ( ((PSTS2_REGISTER)&(sts2) )->ARE << 27 ) \
+ + ( (SicSet) << 30 ) ); \
+}
+#endif // 0
+
+#define GET_TIME(Buffer) { \
+ TIME_FIELDS timeBuffer; \
+ HalQueryRealTimeClock( &timeBuffer ); \
+ sprintf( (Buffer), \
+ "%04d%02d%02d%02d%02d%02d", \
+ timeBuffer.Year, \
+ timeBuffer.Month, \
+ timeBuffer.Day, \
+ timeBuffer.Hour, \
+ timeBuffer.Minute, \
+ timeBuffer.Second \
+ ); \
+}
+
+// S002, S003 vvv
+#if 0
+#define NOTIFY_ECC1BIT(Scfr) { \
+ ULONG buffer; \
+ buffer=READ_REGISTER_ULONG(&(SIC_DATA_CONTROL_OR((SIC_NO0_OFFSET)))->DPCM.Long); \
+ SIC_DUMMY_READ; \
+ buffer &= DPCM_ENABLE_MASK; \
+ WRITE_REGISTER_ULONG(&(SIC_DATA_CONTROL_OR((SIC_SET0_OFFSET)))->DPCM.Long,buffer); \
+ if( ((Scfr) & SCFR_SIC_SET1_CONNECT) == 0 ) { \
+ buffer=READ_REGISTER_ULONG(&(SIC_DATA_CONTROL_OR((SIC_NO2_OFFSET)))->DPCM.Long); \
+ SIC_DUMMY_READ; \
+ buffer &= DPCM_ENABLE_MASK; \
+ WRITE_REGISTER_ULONG(&(SIC_DATA_CONTROL_OR((SIC_SET1_OFFSET)))->DPCM.Long, \
+ buffer); \
+ } \
+}
+
+#define DONT_NOTIFY_ECC1BIT(Scfr) { \
+ ULONG buffer; \
+ buffer=READ_REGISTER_ULONG(&(SIC_DATA_CONTROL_OR((SIC_NO0_OFFSET)))->DPCM.Long); \
+ SIC_DUMMY_READ; \
+ buffer |= DPCM_ECC1BIT_BIT; \
+ WRITE_REGISTER_ULONG(&(SIC_DATA_CONTROL_OR((SIC_SET0_OFFSET)))->DPCM.Long, \
+ buffer); \
+ if( ((Scfr) & SCFR_SIC_SET1_CONNECT) == 0 ) { \
+ buffer=READ_REGISTER_ULONG(&(SIC_DATA_CONTROL_OR((SIC_NO2_OFFSET)))->DPCM.Long); \
+ SIC_DUMMY_READ; \
+ buffer |= DPCM_ECC1BIT_BIT; \
+ WRITE_REGISTER_ULONG(&(SIC_DATA_CONTROL_OR((SIC_SET1_OFFSET)))->DPCM.Long, \
+ buffer); \
+ } \
+}
+#endif // 0
+// S002, S003 ^^^
+
+VOID
+HalpInitDisplayStringIntoNvram(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is initialize variable of use when write display data in
+ HalDisplayString into NVRAM.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ SYSTEM_ERR_AREA_INFO infoBuf;
+ UCHAR recordFlg;
+ UCHAR buf[8];
+ UCHAR buf2[8];
+
+ CallCountOfInitDisplay++;
+ if(CallCountOfInitDisplay == 1){
+
+ //
+ // Check NVRAM status
+ //
+
+ HalNvramRead( NVRAM_STATE_FLG_OFFSET, 1, buf );
+ HalNvramRead( NVRAM_MAGIC_NO_OFFSET, 4, buf2 );
+
+ if( ((buf[0] & 0xff) != NVRAM_VALID) || (*(PULONG)buf2 != NVRAM_MAGIC) ){
+ HalpNvramValid=FALSE;
+ return;
+ }
+
+ HalpNvramValid=TRUE;
+
+ //
+ // Get log area infomation.
+ //
+
+ HalNvramRead(SYSTEM_ERROR_LOG_INFO_OFFSET,
+ sizeof(SYSTEM_ERR_AREA_INFO),
+ &infoBuf);
+
+ ErrBufferLatest = infoBuf.offset_latest;
+
+ HalNvramRead( infoBuf.offset_latest, 1, &recordFlg);
+
+ //
+ // Check current record flg.
+ //
+
+ if( (recordFlg & 0x01) == 1 ) {
+ infoBuf.offset_latest += infoBuf.size_rec;
+ if( infoBuf.offset_latest >=
+ infoBuf.offset_systemerr + (infoBuf.size_rec * infoBuf.num_rec) ){
+ infoBuf.offset_latest = infoBuf.offset_systemerr;
+ }
+ HalNvramWrite(SYSTEM_ERROR_LOG_INFO_LATEST_OFFSET,
+ 2,
+ &infoBuf.offset_latest);
+ }
+
+ //
+ // initialize variable. this value use log area access.
+ //
+
+ ErrBufferArea = infoBuf.offset_latest;
+ ErrBufferStart = infoBuf.offset_latest + STOP_ERR_LOG_AREA_HEADER_SIZE;
+ ErrBufferEnd = infoBuf.offset_latest + infoBuf.size_rec-1;
+ ErrBufferCurrent = ErrBufferStart;
+
+ //
+ // status flg set.
+ //
+
+ HalpPanicFlg = 0;
+
+ recordFlg = 0x11;
+ HalNvramWrite( ErrBufferArea, 1, &recordFlg );
+
+ //
+ // buffer initialize.
+ //
+
+ buf[0]=0xff;
+ buf[1]=0xff;
+ HalNvramWrite( ErrBufferCurrent, 2, buf );
+
+ } else {
+
+ //
+ // start Panic log.
+ //
+
+ HalpChangePanicFlag( 1, 1, 0);
+ }
+}
+
+// L001 +++
+
+UCHAR
+HalpFindMemoryGroup(
+ IN ULONG MemoryFailed
+ )
+
+/*++
+
+Routine Description:
+
+ This routine finds MemoryGroup of MemoryFaled address
+
+Arguments:
+
+ MemoryFailed - MemoryFailed Register value
+
+
+Return Value:
+
+ if MemoryFaied is within any Goup, return MemoryGroup Number.
+
+ Otherwise, return 0xff
+
+--*/
+
+{
+ UCHAR returnValue = 0xff;
+ UCHAR i;
+ ULONG startAddr;
+ ULONG length;
+ ULONG simmType;
+ ULONG dataWord;
+
+ //
+ // find MemoryGroup from MemoryGroup[0:3] register.
+ //
+ // MemoryGroup[0:3] register
+ //
+ // [31] Reserved
+ // [30:22] Starting address
+ // [21:04] Reserved
+ // [03:02] SIMM type
+ // 01=Single-sided 11=Double-sided other=Reserved
+ // [01:00] SIMM size
+ // 00= 1M 01=4M 10=16M 11=64M SIMM
+ //
+ // note: 1 memory group is have 4 SIMM's
+ //
+
+ for (i = 0; i < 4; i++) {
+ dataWord = READ_REGISTER_ULONG(&DMA_CONTROL->MemoryConfig[i]);
+
+ // check SIMM type is valid
+
+ switch (dataWord & 0xc) {
+
+ case 4:
+ simmType = 1;
+ break;
+
+ case 0xc:
+ simmType = 2;
+ break;
+
+ default:
+ simmType = 3;
+ }
+
+ if (simmType == 3) {
+ continue;
+ }
+
+ // compute amount of MemoryGoup SIMM length;
+
+ length = (0x400000 << ((dataWord & 3) * 2)) * simmType;
+
+ // compute MemoryGoup SIMM start address;
+
+ startAddr = dataWord & 0x7fc00000;
+
+ // check if MemoryFailed is within this MemoryGroup
+
+ if ( (startAddr <= MemoryFailed)
+ && (MemoryFailed < (length + startAddr))) {
+ returnValue = i;
+ break;
+ }
+ }
+ return returnValue;
+
+}
+
+
+ULONG
+HalpEccError(
+ IN ULONG EccDiagnostic,
+ IN ULONG MemoryFailed
+ )
+
+/*++
+
+Routine Description:
+
+ This routine check ecc error and error log put in NVRAM.
+
+Arguments:
+
+ EccDiagnostic - EccDiagnostic Register value
+ MemoryFailed - MemoryFailed Register value
+
+
+Return Value:
+
+ return value is the following error occured.
+ 1: ecc 1bit error.
+ 2: ecc 2bit error.
+ 0: other error.
+
+--*/
+
+{
+ ULONG returnValue;
+ USHORT infoOffset;
+ USHORT writeOffset;
+ ULONG buffer; // S001
+ ULONG i; // S002
+ UCHAR dataBuf[36];
+ UCHAR infoBuf[24];
+ UCHAR tempBuf[24];
+ KIRQL OldIrql;
+ ULONG DataWord;
+ ULONG Number;
+
+ //
+ // Check for Ecc 2bit/1bit error
+ //
+
+ if (EccDiagnostic & 0x44000000) {
+ returnValue = STORM_ECC_2BIT_ERROR;
+ infoOffset=ECC_2BIT_ERROR_LOG_INFO_OFFSET;
+ } else if (EccDiagnostic & 0x22000000) {
+ returnValue = STORM_ECC_1BIT_ERROR;
+ infoOffset=ECC_1BIT_ERROR_LOG_INFO_OFFSET;
+ } else {
+ return 0; // Probably Error bit was disappered.
+ }
+
+ HalNvramRead( NVRAM_STATE_FLG_OFFSET, 1, dataBuf );
+ HalNvramRead( NVRAM_MAGIC_NO_OFFSET, 4, tempBuf );
+
+ // S002 vvv
+ switch(returnValue) {
+
+ case STORM_ECC_2BIT_ERROR:
+
+ //
+ // Disable and clear ECC 1bit error.
+ //
+
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
+ EccDiagnostic.u.LargeInteger.LowPart
+ = 0x00ee0000;
+ KeFlushWriteBuffer();
+
+ // set Flag indicate ECC 2bit error.
+
+ HalpEcc2bitErrorFlag = 1;
+
+ //
+ // Log to NVRAM
+ //
+
+ // check for nvram was valid.
+
+ if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){
+
+ HalNvramRead( (ULONG)infoOffset, 20, infoBuf);
+
+ ((pECC2_ERR_REC)dataBuf)->record_flag = ECC_LOG_VALID_FLG;
+
+ ((pECC2_ERR_REC)dataBuf)->err_address = MemoryFailed & 0xfffffff0;
+ // Error Address was 16Byte Alined.
+
+ GET_TIME(tempBuf);
+ RtlMoveMemory( (PVOID)( ((pECC2_ERR_REC)dataBuf)->when_happened ),
+ (PVOID)tempBuf,
+ TIME_STAMP_SIZE
+ );
+
+ ((pECC2_ERR_REC)dataBuf)->syndrome = EccDiagnostic;
+
+ ((pECC2_ERR_REC)dataBuf)->specified_group =
+ HalpFindMemoryGroup(MemoryFailed);
+
+ ((pECC2_ERR_REC)dataBuf)->specified_simm = 0;
+
+ writeOffset = ((pECC2_ERR_AREA_INFO)infoBuf)->offset_latest
+ +((pECC2_ERR_AREA_INFO)infoBuf)->size_rec;
+
+ if( writeOffset >= ((pECC2_ERR_AREA_INFO)infoBuf)->offset_2biterr
+ +((pECC2_ERR_AREA_INFO)infoBuf)->size_rec
+ *((pECC2_ERR_AREA_INFO)infoBuf)->num_rec ) {
+ writeOffset = ((pECC2_ERR_AREA_INFO)infoBuf)->offset_2biterr;
+ }
+
+ HalNvramWrite( (ULONG)writeOffset,
+ sizeof(ECC2_ERR_REC),
+ (PVOID)dataBuf);
+
+ HalNvramWrite( ECC_2BIT_ERROR_LOG_INFO_LATEST_OFFSET,
+ sizeof(USHORT),
+ (PVOID)&writeOffset);
+ }
+ return returnValue; // S004
+
+ case STORM_ECC_1BIT_ERROR:
+
+ //
+ // If MemoryFailed address
+ // is over 512M Nothing can do.
+ //
+ if ((MemoryFailed & 0xfffffff0) > 0x1fffffff) {
+ return returnValue;
+ }
+
+ //
+ // Disable and clear ECC 1bit error.
+ //
+
+ Number = KeGetCurrentPrcb()->Number;
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
+ EccDiagnostic.u.LargeInteger.LowPart
+ = 0x00ee0000;
+ KeFlushWriteBuffer();
+// M003 +++
+ //
+ // serialize ecc 1bit logging routine
+ //
+
+ for (;;) {
+ KiAcquireSpinLock(&Ecc1bitRoutineLock);
+ if (HalpEcc1bitCount[!Number] == 0) {
+
+ //
+ // Increment HalpEcc1bitCount
+ //
+
+ HalpEcc1bitCount[Number]++;
+ KiReleaseSpinLock(&Ecc1bitRoutineLock);
+ break;
+ }
+ KiReleaseSpinLock(&Ecc1bitRoutineLock);
+ }
+// M003 ---
+
+ switch(HalpEcc1bitCount[Number]) {
+
+ case 1:
+
+ HalpEcc1bitTotalCount++; // M002
+
+
+ HalpOldMemoryFailed[Number] = MemoryFailed;
+
+ //
+ // ReWrite error address
+ // if error address is over 512M
+ // Nothing can do.
+ //
+
+ KiAcquireSpinLock(&Ecc1bitDisableLock);
+
+ // disable ecc 1bit error again.
+
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
+ EccDiagnostic.u.LargeInteger.LowPart
+ = 0x00ee0000;
+ KeFlushWriteBuffer();
+
+ DataWord = READ_REGISTER_ULONG(
+ KSEG1_BASE
+ | (MemoryFailed & 0xfffffff0)
+ );
+ WRITE_REGISTER_ULONG(
+ KSEG1_BASE
+ | (MemoryFailed & 0xfffffff0),
+ DataWord
+ );
+
+ KiReleaseSpinLock(&Ecc1bitDisableLock);
+
+ //
+ // Wait 20 us.
+ //
+
+ KeStallExecutionProcessor(20);
+
+ //
+ // Enable and clear ECC 1bit error.
+ //
+
+ KiAcquireSpinLock(&Ecc1bitDisableLock);
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
+ EccDiagnostic.u.LargeInteger.LowPart
+ = 0x00cc0000;
+ KeFlushWriteBuffer();
+ KiReleaseSpinLock(&Ecc1bitDisableLock);
+
+ //
+ // ReRead error address
+ // if error address is over 512M
+ // Nothing can do.
+ //
+ // if Ecc 1bit error occur again , DataBusError will occur.
+ //
+
+ DataWord = READ_REGISTER_ULONG(
+ KSEG1_BASE
+ | (MemoryFailed & 0xfffffff0)
+ );
+
+ // decrement ecc 1bit count
+
+ HalpEcc1bitCount[Number]--;
+
+ return(returnValue);
+
+ case 2:
+
+ if (HalpOldMemoryFailed[Number] != MemoryFailed) {
+ break;
+ }
+ if (MemoryFailed & 2) {
+
+ // if multi error
+ // nothing can do.
+
+ break;
+ }
+
+
+ if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){
+
+
+ //
+ // Search for wheather error address was already logged
+ //
+
+ HalNvramRead( (ULONG)infoOffset, 20, infoBuf);
+
+ for( i=0; i<((pECC1_ERR_AREA_INFO)infoBuf)->num_rec; i++) {
+ HalNvramRead( (ULONG)( ((pECC1_ERR_AREA_INFO)infoBuf)->
+ size_rec * i
+ +((pECC1_ERR_AREA_INFO)infoBuf)->
+ offset_1biterr),
+ sizeof(ECC1_ERR_REC),
+ (PVOID)dataBuf);
+ if ( ((MemoryFailed & 0xfffffff0)
+ == ((pECC1_ERR_REC)dataBuf)->err_address) &&
+ ( (((pECC1_ERR_REC)dataBuf)->record_flag & 0x1) != 0) ) {
+ break;
+ }
+ }
+
+ if( i != ((pECC1_ERR_AREA_INFO)infoBuf)->num_rec ) {
+ break;
+ }
+
+ //
+ // Log to NVRAM
+ //
+
+ // check for nvram was valid.
+
+ ((pECC1_ERR_REC)dataBuf)->record_flag = ECC_LOG_VALID_FLG;
+
+ ((pECC1_ERR_REC)dataBuf)->err_address = MemoryFailed & 0xfffffff0;
+ // Error Address was 16Byte Alined.
+
+ GET_TIME(tempBuf);
+ RtlMoveMemory( (PVOID)( ((pECC1_ERR_REC)dataBuf)->when_happened ),
+ (PVOID)tempBuf,
+ TIME_STAMP_SIZE
+ );
+
+ ((pECC1_ERR_REC)dataBuf)->syndrome = EccDiagnostic;
+
+ ((pECC1_ERR_REC)dataBuf)->specified_group =
+ HalpFindMemoryGroup(MemoryFailed);
+
+ ((pECC1_ERR_REC)dataBuf)->specified_simm = 0;
+
+ writeOffset = ((pECC1_ERR_AREA_INFO)infoBuf)->offset_latest
+ +((pECC1_ERR_AREA_INFO)infoBuf)->size_rec;
+
+ if( writeOffset >= ((pECC1_ERR_AREA_INFO)infoBuf)->offset_1biterr
+ +((pECC1_ERR_AREA_INFO)infoBuf)->size_rec
+ *((pECC1_ERR_AREA_INFO)infoBuf)->num_rec ) {
+ writeOffset = ((pECC1_ERR_AREA_INFO)infoBuf)->offset_1biterr;
+ }
+
+ HalNvramWrite( (ULONG)writeOffset,
+ sizeof(ECC1_ERR_REC),
+ (PVOID)dataBuf);
+ HalNvramWrite( ECC_1BIT_ERROR_LOG_INFO_LATEST_OFFSET,
+ sizeof(USHORT),
+ (PVOID)&writeOffset);
+ }
+
+
+ // disable ecc 1bit error again.
+
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
+ EccDiagnostic.u.LargeInteger.LowPart
+ = 0x00ee0000;
+ KeFlushWriteBuffer();
+
+ // decrement ecc 1bit count
+
+ HalpEcc1bitCount[Number]--;
+
+ return(returnValue);
+ }
+
+ //
+ // Enable and clear ECC 1bit error.
+ //
+
+ KiAcquireSpinLock(&Ecc1bitDisableLock);
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
+ EccDiagnostic.u.LargeInteger.LowPart
+ = 0x00cc0000;
+ KeFlushWriteBuffer();
+ KiReleaseSpinLock(&Ecc1bitDisableLock);
+
+
+ // decrement ecc 1bit count
+
+ HalpEcc1bitCount[Number]--;
+
+ return(returnValue);
+ }
+}
+
+// L001 ---
+
+
+VOID
+HalpSetInitDisplayTimeStamp(
+ VOID
+ )
+{
+ UCHAR buf[24];
+
+ //
+ // Set time stamp on initialize display.
+ //
+
+ if(HalpNvramValid == TRUE) {
+ GET_TIME(buf);
+ HalNvramWrite( ErrBufferArea+1, TIME_STAMP_SIZE, buf );
+ }
+}
+
+
+VOID
+HalpSuccessOsStartUp(
+ VOID
+ )
+{
+ UCHAR recordFlg;
+
+ if(HalpNvramValid == TRUE) {
+ recordFlg = 0;
+ HalNvramWrite( ErrBufferArea, 1, &recordFlg );
+ HalNvramWrite( SYSTEM_ERROR_LOG_INFO_LATEST_OFFSET, 2, &ErrBufferLatest );
+ }
+}
+
+
+VOID
+HalpChangePanicFlag(
+ IN ULONG NewPanicFlg,
+ IN UCHAR NewLogFlg,
+ IN UCHAR CurrentLogFlgMask
+ )
+{
+ UCHAR recordFlg;
+ UCHAR buf[24];
+
+ if( (HalpNvramValid == FALSE) || (NewPanicFlg <= HalpPanicFlg) ) {
+ return;
+ }
+
+ HalNvramWrite(SYSTEM_ERROR_LOG_INFO_LATEST_OFFSET,
+ 2,
+ &ErrBufferArea);
+
+ //
+ // initialize currernt buffer address
+ //
+
+ ErrBufferCurrent = ErrBufferStart;
+
+ //
+ // set panic flag
+ //
+
+ HalNvramRead( ErrBufferArea, 1, &recordFlg );
+ recordFlg = (recordFlg & CurrentLogFlgMask) | NewLogFlg;
+ HalNvramWrite( ErrBufferArea, 1, &recordFlg );
+
+ GET_TIME(buf);
+ HalNvramWrite( ErrBufferArea+1, TIME_STAMP_SIZE, buf );
+
+ //
+ // set new flag of panic level
+ //
+
+ HalpPanicFlg = NewPanicFlg;
+
+ //
+ // initialize log buffer.
+ //
+
+ buf[0]=0xff;
+ buf[1]=0xff;
+ HalNvramWrite( ErrBufferCurrent, 2, buf );
+}
+
+
+// S002 vvv
+VOID
+HalStringIntoBuffer(
+ IN UCHAR Character
+ )
+{
+ if( (HalpNvramStringBufferCounter + 1) < STRING_BUFFER_SIZE - 1 ) {
+ HalpNvramStringBuffer[HalpNvramStringBufferCounter++]=Character;
+ }
+}
+
+
+VOID
+HalStringIntoBufferStart(
+ IN ULONG Column,
+ IN ULONG Row
+ )
+{
+ ULONG i;
+
+ //
+ // Initialize buffer
+ //
+
+ for(i=0; i<STRING_BUFFER_SIZE; i++) {
+ HalpNvramStringBuffer[i] = 0;
+ }
+
+ HalpNvramStringBufferCounter=0;
+
+ //
+ // set string position
+ //
+
+ HalpNvramStringBuffer[HalpNvramStringBufferCounter++]=(UCHAR)Column;
+ HalpNvramStringBuffer[HalpNvramStringBufferCounter++]=(UCHAR)Row;
+}
+
+
+VOID
+HalpStringBufferCopyToNvram(
+ VOID
+ )
+{
+ UCHAR buf[4];
+ USHORT count;
+
+ //
+ // check nvram status.
+ //
+
+ if(HalpNvramValid == FALSE) {
+ return;
+ }
+
+ //
+ // if data size is zero, when return
+ //
+
+ if( HalpNvramStringBufferCounter <= 2 ) {
+ return;
+ }
+
+ HalpNvramStringBuffer[HalpNvramStringBufferCounter++]='\0';
+
+ //
+ // check panic message
+ //
+
+ for( count=0; ; count++) {
+ if( KernelPanicMessage[count] == '\0' ){
+ HalpChangePanicFlag( 8, 0x01, 0x10);
+ break;
+ }
+ if( KernelPanicMessage[count] != HalpNvramStringBuffer[count+2] ){
+ break;
+ }
+ }
+
+ //
+ // check message length
+ //
+
+ for( count=2; ; count++) {
+ if( HalpNvramStringBuffer[count] == '\0' ){
+ count++;
+ break;
+ }
+ }
+
+loop:
+ if( ErrBufferCurrent + count + 2 < ErrBufferEnd ) {
+ HalNvramWrite( ErrBufferCurrent, count, HalpNvramStringBuffer );
+ ErrBufferCurrent += count;
+ buf[0]=0xff;
+ buf[1]=0xff;
+ HalNvramWrite( ErrBufferCurrent, 2, buf );
+
+ } else if( (count + 2 > ErrBufferEnd - ErrBufferStart) && (HalpPanicFlg == 0) ) {
+ return;
+ } else {
+ if( HalpPanicFlg == 0 ) {
+ ErrBufferCurrent = ErrBufferStart;
+ goto loop;
+ } else if(ErrBufferCurrent >= ErrBufferEnd){
+ return;
+ }
+
+ for(count=0;;count++) {
+ if(ErrBufferCurrent < ErrBufferEnd) {
+ HalNvramWrite( ErrBufferCurrent, 1, HalpNvramStringBuffer+count );
+ }
+ ErrBufferCurrent++;
+ if( (HalpNvramStringBuffer[count]=='\0') && (count>=2) ) {
+ break;
+ }
+ }
+
+ buf[0]=0xff;
+ if(ErrBufferCurrent < ErrBufferEnd) {
+ HalNvramWrite( ErrBufferCurrent++, 1, buf );
+ }
+ if(ErrBufferCurrent < ErrBufferEnd) {
+ HalNvramWrite( ErrBufferCurrent++, 1, buf );
+ }
+ }
+}
+
+#if 0
+VOID
+HalpStringIntoNvram(
+ IN ULONG Column,
+ IN ULONG Row,
+ IN PUCHAR String
+ )
+{
+ UCHAR buf[4];
+ USHORT count;
+
+ //
+ // check nvram status.
+ //
+
+ if(HalpNvramValid == FALSE) {
+ return;
+ }
+
+ //
+ // check panic message
+ //
+
+ for(count=0; 1; count++) {
+ if( KernelPanicMessage[count] == '\0' ){
+ HalpChangePanicFlag( 8, 0x01, 0x10);
+ break;
+ }
+ if( KernelPanicMessage[count] != String[count] ){
+ break;
+ }
+ }
+
+ //
+ // check message length
+ //
+
+ for(count=0;;count++) {
+ if(String[count]=='\0'){
+ count++;
+ break;
+ }
+ }
+
+loop:
+ if( ErrBufferCurrent + count + 4 < ErrBufferEnd ) {
+ buf[0]=(UCHAR)Column;
+ buf[1]=(UCHAR)Row;
+ HalNvramWrite( ErrBufferCurrent, 2, buf );
+ ErrBufferCurrent += 2;
+ HalNvramWrite( ErrBufferCurrent, count, String );
+ ErrBufferCurrent += count;
+ buf[0]=0xff;
+ buf[1]=0xff;
+ HalNvramWrite( ErrBufferCurrent, 2, buf );
+
+ } else if( count + 4 > ErrBufferEnd - ErrBufferStart ) {
+ return;
+ } else {
+ if( HalpPanicFlg == 0 ) {
+ ErrBufferCurrent = ErrBufferStart;
+ goto loop;
+ } else if(ErrBufferCurrent >= ErrBufferEnd){
+ return;
+ }
+
+ buf[0]=(UCHAR)Column;
+ buf[1]=(UCHAR)Row;
+ HalNvramWrite( ErrBufferCurrent, 2, buf );
+ ErrBufferCurrent += 2;
+
+ for(count=0;;count++) {
+ if(ErrBufferCurrent < ErrBufferEnd) {
+ HalNvramWrite( ErrBufferCurrent, 1, String+count );
+ }
+ ErrBufferCurrent++;
+ if(String[count]=='\0') {
+ break;
+ }
+ }
+
+ buf[0]=0xff;
+ if(ErrBufferCurrent < ErrBufferEnd) {
+ HalNvramWrite( ErrBufferCurrent++, 1, buf );
+ }
+ if(ErrBufferCurrent < ErrBufferEnd) {
+ HalNvramWrite( ErrBufferCurrent++, 1, buf );
+ }
+ }
+}
+#endif
+// S002 ^^^
+
+
+//
+// test code
+//
+
+int
+printNvramData(void)
+{
+ UCHAR buf[256];
+
+ HalNvramRead( (USHORT)&(((pNVRAM_HEADER)0)->nvram_flag), 1, buf );
+ DbgPrint("Nvram Flag: 0x%02lx\n", buf[0]);
+
+ HalNvramRead( (USHORT)&(((pNVRAM_HEADER)0)->when_formatted), 14, buf );
+ buf[14]=0;
+ DbgPrint("Nvram TimeStamp: %s\n", buf);
+
+ HalNvramRead( (USHORT)&(((pNVRAM_HEADER)0)->ecc1bit_err),
+ sizeof(ECC1_ERR_AREA_INFO),
+ buf );
+ DbgPrint("Nvram ECC1: offset=0x%04lx\n", *(PUSHORT)buf );
+ DbgPrint("Nvram ECC1: size =0x%04lx\n", *(PUSHORT)(buf+2) );
+ DbgPrint("Nvram ECC1: number=0x%04lx\n", *(PUSHORT)(buf+4) );
+ DbgPrint("Nvram ECC1: latest=0x%04lx\n", *(PUSHORT)(buf+6) );
+
+ HalNvramRead( (USHORT)&(((pNVRAM_HEADER)0)->ecc2bit_err),
+ sizeof(ECC2_ERR_AREA_INFO),
+ buf );
+ DbgPrint("Nvram ECC2: offset=0x%04lx\n", *(PUSHORT)buf );
+ DbgPrint("Nvram ECC2: size =0x%04lx\n", *(PUSHORT)(buf+2) );
+ DbgPrint("Nvram ECC2: number=0x%04lx\n", *(PUSHORT)(buf+4) );
+ DbgPrint("Nvram ECC2: latest=0x%04lx\n", *(PUSHORT)(buf+6) );
+
+ HalNvramRead( (USHORT)&(((pNVRAM_HEADER)0)->system_err),
+ sizeof(SYSTEM_ERR_AREA_INFO),
+ buf );
+ DbgPrint("Nvram SYSTEM: offset=0x%04lx\n", *(PUSHORT)buf );
+ DbgPrint("Nvram SYSTEM: size =0x%04lx\n", *(PUSHORT)(buf+2) );
+ DbgPrint("Nvram SYSTEM: number=0x%04lx\n", *(PUSHORT)(buf+4) );
+ DbgPrint("Nvram SYSTEM: latest=0x%04lx\n", *(PUSHORT)(buf+6) );
+
+ return(0);
+}
+
+
+int
+TmpInitNvram(void)
+{
+ UCHAR buf[256];
+ ULONG i;
+
+ buf[0]=0xff;
+ for(i=0; i<8*1024; i++)
+ HalNvramWrite( i, 1, buf);
+
+ //
+ // Make nvram flg
+ //
+
+ buf[0]=0x03;
+ HalNvramWrite( NVRAM_STATE_FLG_OFFSET, 1, buf);
+
+ i = NVRAM_MAGIC;
+ HalNvramWrite( NVRAM_MAGIC_NO_OFFSET, 4, (PUCHAR)&i);
+
+ //
+ // Make 1bit err log info
+ //
+
+ ((pECC1_ERR_AREA_INFO)buf)->offset_1biterr=768;
+ ((pECC1_ERR_AREA_INFO)buf)->size_rec=25;
+ ((pECC1_ERR_AREA_INFO)buf)->num_rec=16;
+ ((pECC1_ERR_AREA_INFO)buf)->offset_latest=768;
+
+ ((pECC1_ERR_AREA_INFO)buf)->read_data_latest=0;
+
+ ((pECC1_ERR_AREA_INFO)buf)->err_count_group0=0;
+ ((pECC1_ERR_AREA_INFO)buf)->err_count_group1=0;
+ ((pECC1_ERR_AREA_INFO)buf)->err_count_group2=0;
+ ((pECC1_ERR_AREA_INFO)buf)->err_count_group3=0;
+ ((pECC1_ERR_AREA_INFO)buf)->err_count_group4=0;
+ ((pECC1_ERR_AREA_INFO)buf)->err_count_group5=0;
+ ((pECC1_ERR_AREA_INFO)buf)->err_count_group6=0;
+ ((pECC1_ERR_AREA_INFO)buf)->err_count_group7=0;
+
+ HalNvramWrite( ECC_1BIT_ERROR_LOG_INFO_OFFSET,
+ sizeof(ECC1_ERR_AREA_INFO),
+ buf);
+
+ buf[0]=0;
+ for(i=768; i<768+25*16; i++)
+ HalNvramWrite( i, 1, buf);
+
+ //
+ // Make 2bit err log info
+ //
+
+ ((pECC2_ERR_AREA_INFO)buf)->offset_2biterr=768+400;
+ ((pECC2_ERR_AREA_INFO)buf)->size_rec=25;
+ ((pECC2_ERR_AREA_INFO)buf)->num_rec=4;
+ ((pECC2_ERR_AREA_INFO)buf)->offset_latest=768+400;
+
+ ((pECC2_ERR_AREA_INFO)buf)->read_data_latest=0;
+
+ HalNvramWrite( ECC_2BIT_ERROR_LOG_INFO_OFFSET,
+ sizeof(ECC2_ERR_AREA_INFO),
+ buf);
+
+ buf[0]=0;
+ for(i=768+400; i<768+400+25*4; i++)
+ HalNvramWrite( i, 1, buf);
+
+ //
+ // Make system err log info
+ //
+
+ ((pSYSTEM_ERR_AREA_INFO)buf)->offset_systemerr=1280;
+ ((pSYSTEM_ERR_AREA_INFO)buf)->size_rec=512;
+ ((pSYSTEM_ERR_AREA_INFO)buf)->num_rec=4;
+ ((pSYSTEM_ERR_AREA_INFO)buf)->offset_latest=1280;
+
+ HalNvramWrite( SYSTEM_ERROR_LOG_INFO_OFFSET,
+ sizeof(ECC2_ERR_AREA_INFO),
+ buf);
+
+ buf[0]=0;
+ for(i=1280; i<1280+512*4; i++)
+ HalNvramWrite( i, 1, buf);
+
+ return(0);
+}
+
diff --git a/private/ntos/nthals/halr96b/mips/esmnvram.h b/private/ntos/nthals/halr96b/mips/esmnvram.h
new file mode 100644
index 000000000..2392671e9
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/esmnvram.h
@@ -0,0 +1,688 @@
+// #pragma comment(exestr, "@(#) esmnvram.h 1.1 95/09/28 15:32:22 nec")
+
+/****************************************************************
+ ******* Copyright (C) 1994 NEC Corporation *******
+ ****************************************************************/
+
+/*******
+
+ File Name:
+
+ envram.h
+
+ Abstract:
+
+ This module contains the definitions for the extended NVRAM.
+
+ Author:
+
+ Takehiro Ueda (tueda@oa2.kb.nec.co.jp) 12/22/1994
+
+ Modification History:
+
+ - M000 12/22/94 -
+ created.
+
+*******/
+
+
+
+/*******************************************************************************
+ ******** NVRAM¡Ê8K¥Ð¥¤¥È¡Ë¤ÎÏÀÍý¥Õ¥©¡¼¥Þ¥Ã¥È¤ò°Ê²¼¤Ëµ­½Ò¤¹¤ë¡£ ********
+ *******************************************************************************
+ *
+ * S001 11/22/94
+ * ¥ì¥³¡¼¥É¤ÎÍ­¸ú/̵¸ú¥Õ¥é¥°¡¢Check̤/ºÑ¥Õ¥é¥°¤ò³Æ¥ì¥³¡¼¥É¤ÎÀèƬ¤Ë¤ª¤¯¤«
+ * ¤Þ¤È¤á¤Æ¥ì¥³¡¼¥É¥ê¡¼¥¸¥ç¥ó¤ÎÀèƬ¤Ë¤ª¤¯¤«¤Ç¡¢¥ì¥³¡¼¥É¤Î½èÍýÊýË¡¤¬ÊѤï¤Ã¤Æ
+ * ¤¯¤ë¡£¸å¼Ô¤Ï¥é¥ó¥À¥à¥¢¥¯¥»¥¹¡¢Á°¼Ô¤Ï¥·¡¼¥±¥ó¥·¥ã¥ë¥¢¥¯¥»¥¹¤Ë¤à¤¯¡£
+ * º£²ó¤ÏÁ°¼Ô¤òºÎÍÑ¡£
+ *
+ * ¹Ô¤ÎÀèƬ¤Ë¤¢¤ë¿ô»ú¤Ï³ä¤êÅö¤Æ¤ë¥Ð¥¤¥È¿ô¤ò¤¢¤é¤ï¤¹¡£
+ *
+ * ËÜ»ÅÍͤˤ·¤¿¤¬¤Ã¤Æ¹½Â¤ÂΤòºîÀ®Í½Äê¡£
+ *
+ * S002 11/26/94
+ * ³ÆÎΰè¡ÊECC´ØÏ¢¡¢¥Ñ¥Ë¥Ã¥¯¾ðÊó´ØÏ¢¡¢¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°´ØÏ¢¡¢etc.¡Ë
+ * ¤ÎÀèƬ¤Î¥Ø¥Ã¥ÀÉô¤òÁ´¤ÆNVRAM¤ÎÀèƬ¤Ë°Ü¤¹¡£NVRAM¤ÎÀèƬ¤Ë¤¢¤ë¥Ø¥Ã¥ÀÆâ¤Ë
+ * ³ÆÎΰè¤Î¥ì¥³¡¼¥É¤òľÀÜ¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Î¥ª¥Õ¥»¥Ã¥È¤ò¤â¤Ä¤è¤¦¤Ë¤¹¤ë¡£
+ *
+ * NVRAM¤Î¥¢¥¯¥»¥¹»þ¤Ë¤Ï256¥Ð¥¤¥Èñ°Ì¤Ç¥Ð¥ó¥¯Àڤ괹¤¨¤¬¤ª¤³¤Ê¤ï¤ì¤ë¤¿¤á
+ * ³Æ¥Ç¡¼¥¿¡Ê256¥Ð¥¤¥ÈĹ°Ê²¼¤Î¤â¤Î¡Ë¤¬256¥Ð¥¤¥È¥Ð¥¦¥ó¥À¥ê¤ò¤Þ¤¿¤¬¤é¤Ê¤¤¤è¤¦
+ * ¤ËÇÛθ¡£³ÆÎΰè¡ÊECC´ØÏ¢¡¢¥Ñ¥Ë¥Ã¥¯¾ðÊó´ØÏ¢¡¢etc.¡Ë¤ÎÀèƬ¤¬É¬¤º256¥Ð¥¤¥È
+ * ¥Ð¥¦¥ó¥À¥ê¤«¤é³«»Ï¤µ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¡£
+ *
+ * ECC¥¨¥é¡¼¥í¥°Æâ¤ÎSIMMÆÃÄê²½¾ðÊó¤ò2¥Ð¥¤¥È¤«¤é1¥Ð¥¤¥È¤ØÊѹ¹¡£
+ *
+ * ¡É¥ª¥Õ¥»¥Ã¥È ¡É¤Ï¤¹¤Ù¤ÆNVRAM¤ÎÀèƬ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¡£
+ *
+ * S003 12/13/94
+ * NW¥¨¡¼¥¸¥§¥ó¥È¤È¥á¥â¥ê¥¨¥é¡¼¥¨¥ê¥¢¤ò¶¦Ä̲½¤¹¤ë¤¿¤áÀèƬ512¥Ð¥¤¥È¤ò
+ * ¥á¥â¥ê¥¨¥é¡¼¥¨¥ê¥¢¤È¤·¡¢¥Õ¥©¡¼¥Þ¥Ã¥È¤òNW¥¨¡¼¥¸¥§¥ó¥È¤ÈÅý°ì¤¹¤ë¡£
+ *
+ * STEP1¤Ç¤Ï¥á¥â¥ê½ÌÂà¤ò¹Ô¤ï¤Ê¤¤¤¿¤áËÜ¥¨¥ê¥¢¤Ï»ÈÍѤ·¤Ê¤¤¡£
+ * ËÜ¥á¥â¥ê¥¨¥é¡¼¥¨¥ê¥¢¤ÏNW¥¨¡¼¥¸¥§¥ó¥È¤È¤Î¶¦Ä̲½¤Î¤¿¤á¤Ë¿·¤¿¤ËÀߤ±¤ë
+ * ¤â¤Î¤Ç¤¢¤ê¡¢°ÊÁ°¤«¤é¤ÎECC¥¨¥é¡¼¾ðÊóÎΰè¤Ï¤½¤Î¤Þ¤Þ»Ä¤ë¡£
+ *
+ * 512¥Ð¥¤¥È¤Î¥¨¥ê¥¢¤òÀèƬ¤ËÀߤ±¤ë¤¿¤á¡¢°ÊÁ°¤«¤é¤Î¤½¤Î¾Á´¤Æ¤Î¾ðÊóÎΰè¤Ï
+ * 512¥Ð¥¤¥È¥ª¥Õ¥»¥Ã¥È¤¬Â礭¤¯¤Ê¤ë¤³¤È¤Ë¤Ê¤ë¡£
+ *
+ * ¥·¥¹¥Æ¥à¾ðÊ󥨥ꥢ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È2¥Ð¥¤¥È¤òÄɲá£
+ *
+ * ¥ª¥Õ¥»¥Ã¥È¤ÎºÆ·×»»¡£
+ *
+ * S004 12/14/94
+ * ¹½Â¤ÂκîÀ®¡£
+ *
+ * ¡Ç¥Ñ¥Ë¥Ã¥¯ ¡Ç¤ò¡Ç¥¹¥È¥Ã¥×¥¨¥é¡¼ ¡Ç¤ËÊѹ¹¡£
+ *
+ * S005 12/23/94
+ * 4byte alignment¤Ë¤½¤Ê¤¨¤Æ¥Ñ¥Ç¥£¥ó¥°¤ò°ìÉôÊѹ¹¡£
+ *
+ * ¥¹¥È¥Ã¥×¥¨¥é¡¼¤Î¥Õ¥é¥°¤Î2¥Ó¥Ã¥È¤Ë¿·¤¿¤ËÄêµÁÄɲá£
+ *
+ * ¥·¥¹¥Æ¥à¾ðÊ󥨥ꥢ¤òNVRAM¥Ø¥Ã¥À¤Ë¤È¤ê¤³¤à¡£
+ * ¤³¤ì¤Ë¤È¤â¤Ê¤¤¥·¥¹¥Æ¥à¾ðÊ󥨥ꥢ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È¤ÏÉÔÍפȤʤ뤿¤á
+ * 2¥Ð¥¤¥Èʬ̤»ÈÍѤȤ¹¤ë¡£
+ *
+ * ¥·¥¹¥Æ¥à¾ðÊ󥨥ꥢ¤Ë¥Þ¥¸¥Ã¥¯¥Ê¥ó¥Ð¡¼¤òÄɲá£ÏÀÍý¥Õ¥©¡¼¥Þ¥Ã¥È¤Î̵ͭ¤ò
+ * ¥Þ¥¸¥Ã¥¯¥Ê¥ó¥Ð¡¼¤È¥Õ¥é¥°¤Ç¥Á¥§¥Ã¥¯¤¹¤ë¤è¤¦¤Ë¤¹¤ë¡£¥Þ¥¸¥Ã¥¯¥Ê¥ó¥Ð¡¼¤Ï
+ * 0xFF651026¤È¤¹¤ë¡£
+ *
+ * ¡Ç¥¹¥È¥Ã¥×¥¨¥é¡¼ ¡Ç¤ò¡Ç¥·¥¹¥Æ¥à¥¨¥é¡¼ ¡Ç¤ËÊѹ¹¡£
+ *
+ * S006 12/27/94
+ * #pragma pack() ¤òÄɲÃ
+ *
+ * char reserved[49] ¤ò char reserved[49] ¤Ë½¤Àµ¡£ËÜÊѹ¹¤Ïharmless¤Ç¤¢¤ë
+ * ¤È¿®¤¸¤ë... (^_^;
+ *
+ * unsigned short offset_ecc2err ¤ò offset_2biterr¤Ë½¤Àµ¡£ËÜÊѹ¹¤Ï
+ * harmless¤Ç¤¢¤ë¤È¿®¤¸¤ë... (^_^;
+ *
+ ******************************************************************************
+
+
+ ###################
+ # NVRAM¥Ø¥Ã¥ÀÉô #
+ ###################
+
+ ######################################################
+ # F/WÍÑ¥á¥â¥ê¡¼¥¨¥é¡¼¥¨¥ê¥¢ (NW¥¨¡¼¥¸¥§¥ó¥È¤È¶¦ÄÌ) #
+ ######################################################
+
+ 512 ¥á¥â¥ê¥¨¥é¡¼¾ðÊó¥ì¥³¡¼¥É(2¥Ð¥¤¥È) ¡ß 256
+
+ ####################
+ # ¥ì¥³¡¼¥É¤ÎÆâÍÆ #
+ ####################
+
+ ¡¡¡¡1 ¥¹¥Æ¡¼¥¿¥¹ 0:Àµ¾ï 1:°Û¾ï(2bit¥¨¥é¡¼Í­Ìµ)
+ 1 1bit¥¨¥é¡¼¥«¥¦¥ó¥È
+
+¡¡¡¡ ######################
+ # Á´ÂΤ˴ؤ¹¤ë¤â¤Î #
+ ######################
+
+ 1 NVRAM¤Î¾õÂÖ¤ò¤¢¤é¤ï¤¹¥Õ¥é¥°
+
+ ##################
+ # ¥Õ¥é¥°¤ÎÆâÍÆ #
+ ##################
+
+ ¡¡¡¡0 NVRAMÁ´ÂÎÍ­¸ú/̵¸ú 0:̵¸ú 1:Í­¸ú
+ ¡¡1 ÏÀÍý¥Õ¥©¡¼¥Þ¥Ã¥È¤Î̵ͭ 0:̵ 1:Í­
+ ¡¡¡¡2 READ-ONLY 0:NO 1:YES
+ ¡¡¡¡3 LOCK 0:NO 1:YES
+ ¡¡¡¡4 [reserved]
+ ¡¡¡¡5 ¡¡¡¡¢¬
+ ¡¡¡¡6 ¡¡¡¡¢¬
+ ¡¡¡¡7 ¡¡¡¡¢¬
+ 14 NVRAM¤¬¥Õ¥©¡¼¥Þ¥Ã¥È¤µ¤ì¤¿¥¿¥¤¥à¥¹¥¿¥ó¥×
+
+ 3 [ reserved ]
+
+¡¡¡¡ ###############################
+ # ALIVE¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î #
+ ###############################
+
+ 2 ALIVE¾ðÊóÎΰè¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+
+¡¡¡¡ #######################################
+ # ECC1bit¥¨¥é¡¼¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î #
+ #######################################
+
+ 2 ECC 1bit¥¨¥é¡¼¥í¥°Éô¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+ ¡¡ 2 ECC 1bit¥¨¥é¡¼¥í¥°1¥ì¥³¡¼¥É¥µ¥¤¥º
+ 2 ECC 1bit¥¨¥é¡¼¥í¥°¥ì¥³¡¼¥É¿ô
+ 2 ECC 1bit¥¨¥é¡¼¥í¥°¤ò°ìÈֺǸå¤ËÅÐÏ¿¤·¤¿¥ì¥³¡¼¥É¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+ 4 °ìÈֺǸå¤ÎECC1bit¥¨¥é¡¼»þ¤Î¥ê¡¼¥É¥Ç¡¼¥¿
+ ¡¡ 8 ECC 1bit¥¨¥é¡¼¥«¥¦¥ó¥È ¡ß ¥á¥â¥ê¥°¥ë¡¼¥×¿ô8
+
+¡¡¡¡ #######################################
+ # ECC2bit¥¨¥é¡¼¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î #
+ #######################################
+
+ 2 ECC 2bit¥¨¥é¡¼¥í¥°Éô¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+ ¡¡ 2 ECC 2bit¥¨¥é¡¼¥í¥°1¥ì¥³¡¼¥É¥µ¥¤¥º
+ 2 ECC 2bit¥¨¥é¡¼¥í¥°¥ì¥³¡¼¥É¿ô
+ 2 ECC 2bit¥¨¥é¡¼¥í¥°¤ò°ìÈֺǸå¤ËÅÐÏ¿¤·¤¿¥ì¥³¡¼¥É¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+ 4 °ìÈֺǸå¤ÎECCÊ£¿ôbit¥¨¥é¡¼»þ¤Î¥ê¡¼¥É¥Ç¡¼¥¿
+ 4 SIMM¸ò´¹¥Õ¥é¥° ¡ß ¥á¥â¥ê¥°¥ë¡¼¥×¿ô4
+
+ ##################
+ # ¥Õ¥é¥°¤ÎÆâÍÆ #
+ ##################
+
+ ¡¡¡¡0 ¥°¥ë¡¼¥×NÆâSIMM #0 (N=1¡Á4) 0:OK 1:NG(Í׸ò´¹)
+ ¡¡¡¡1 ¥°¥ë¡¼¥×NÆâSIMM #1 ¢¬
+ ¡¡¡¡2 ¥°¥ë¡¼¥×NÆâSIMM #2¡¡¡¡ ¢¬
+ ¡¡¡¡3 ¥°¥ë¡¼¥×NÆâSIMM #3¡¡¡¡ ¢¬
+ ¡¡¡¡4 [reserved]
+ ¡¡¡¡5 ¢¬
+ ¡¡¡¡6 ¢¬
+ ¡¡¡¡7¡¡¡¡¡¡¢¬
+ 4 [reserved]
+
+¡¡¡¡ ########################################
+ ¡¡¡¡# ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î #
+ ¡¡¡¡########################################
+
+ 2 ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊóÉô¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+ ¡¡ 2 ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊó1¥ì¥³¡¼¥É¥µ¥¤¥º
+ 2 ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊó¥ì¥³¡¼¥É¿ô
+ 2 ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊó¤ò°ìÈֺǸå¤ËÅÐÏ¿¤·¤¿¥ì¥³¡¼¥É¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+
+¡¡¡¡ ############################################
+ ¡¡¡¡# ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°Îΰè¤Ë´Ø¤¹¤ë¤â¤Î #
+ ############################################
+
+ 2 ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°Éô¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+ ¡¡ 2 ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°1¥ì¥³¡¼¥É¥µ¥¤¥º
+ 2 ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°¥ì¥³¡¼¥É¿ô
+ 2 ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°¤ò°ìÈֺǸå¤ËÅÐÏ¿¤·¤¿¥ì¥³¡¼¥É¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+
+¡¡¡¡ ##################################
+ ¡¡¡¡# ¤·¤­¤¤Ã;ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î #
+ ##################################
+
+ 2 ¤·¤­¤¤Ã;ðÊóÉô¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+
+¡¡¡¡ ##############################
+ ¡¡¡¡# ¥ê¥¶¡¼¥ÖÎΰè¤Ë´Ø¤¹¤ë¤â¤Î #
+ ##############################
+
+ 2 ¥ê¥¶¡¼¥ÖÎΰè¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È
+
+
+ ########################
+ # ¥·¥¹¥Æ¥à¾ðÊ󥨥ꥢ #
+ ########################
+
+¡¡¡¡¡¡¡¡ 1 ¥·¥¹¥Æ¥à¤Î¾õÂÖ¤ò¤¢¤é¤ï¤¹¥Õ¥é¥°
+
+ ##################
+ # ¥Õ¥é¥°¤ÎÆâÍÆ #
+ ##################
+
+ 0 [reserved]
+ ¡¡¡¡1 ¡¡¡¡¢¬
+ ¡¡¡¡2 ¡¡¡¡¢¬
+ ¡¡¡¡3 ¡¡¡¡¢¬
+ ¡¡¡¡4 ¡¡¡¡¢¬
+ ¡¡¡¡5 ¡¡¡¡¢¬
+ ¡¡¡¡6 ¡¡¡¡¢¬
+ ¡¡¡¡7 ¡¡¡¡¢¬
+ 3 [reserved]
+ 32 ¥·¥¹¥Æ¥à¤Î¾ðÊó¡Ê¥·¥¹¥Æ¥à̾¡Ë
+ 4 ¥Þ¥·¥ó¥·¥ê¥¢¥ë¥Ê¥ó¥Ð¡¼
+ 4 ¥Þ¥¸¥Ã¥¯¥Ê¥ó¥Ð¡¼
+ 4 [reserved]
+
+-----------------------------------------------------------------------------
+TOTAL 640 ¥Ð¥¤¥È
+
+
+ #######################################
+ # ALIVE, ¥Ú¡¼¥¸¥ã¡¼¥³¡¼¥ë¾ðÊ󥨥ꥢ #
+ #######################################
+
+ 1 ¸½ºß¤ÎÄÌÊó¥ì¥Ù¥ë
+ 16 ALIVE°ì¼¡ÄÌÊóÀè
+ 16 ALIVEÆó¼¡ÄÌÊóÀè
+ 47 [reserved for pager call]
+
+-----------------------------------------------------------------------------
+TOTAL 80 ¥Ð¥¤¥È
+
+
+ ##############################################################################
+ # ¢¬¤³¤³¤Þ¤Ç720¥Ð¥¤¥È¡£¼¡¤ÎÎΰè¤ÎÀèƬ¤¬256¥Ð¥¤¥È¥Ð¥¦¥ó¥À¥ê¤«¤é»Ï¤Þ¤ë¤è¤¦¤Ë #
+ # 48¥Ð¥¤¥È¤ò[reserved]¤È¤·¤Æ¥Ñ¥Ç¥£¥ó¥°¤¹¤ë¡£ #
+ ##############################################################################
+
+ 48 [reserved]
+
+
+ #######################
+ # ¥á¥â¥ê¥¨¥é¡¼¥í¥°Éô #
+ #######################
+
+ 400 1bit¥¨¥é¡¼¾ðÊó¥ì¥³¡¼¥É(25¥Ð¥¤¥È) ¡ß 16
+
+ ####################
+ # ¥ì¥³¡¼¥É¤ÎÆâÍÆ #
+ ####################
+
+ 1¡¡¡¡¥Õ¥é¥°
+
+ ¡¡¡¡ ##################
+ # ¥Õ¥é¥°¤ÎÆâÍÆ #
+ ##################
+
+ ¡¡¡¡0 Í­¸ú/̵¸ú 0:̵¸ú 1:Í­¸ú
+ ¡¡¡¡1 checkºÑ/̤ 0:̤ 1:ºÑ
+ ¡¡¡¡2 [reserved]
+ ¡¡¡¡3 ¡¡¡¡¢¬
+ ¡¡¡¡4 ¡¡¡¡¢¬
+ ¡¡¡¡5 ¡¡¡¡¢¬
+ ¡¡¡¡6 ¡¡¡¡¢¬
+ ¡¡¡¡7¡¡¡¡ ¡¡¢¬
+ ¡¡ 4 ¥¨¥é¡¼¥¢¥É¥ì¥¹
+ 14 ȯÀ¸¥¿¥¤¥à¥¹¥¿¥ó¥×
+ 4 ¥·¥ó¥É¥í¡¼¥à
+ ¡¡ 1 ¥á¥â¥ê¥°¥ë¡¼¥×
+ 1 SIMMÆÃÄê¾ðÊó
+ 100 2bit¥¨¥é¡¼¾ðÊó¥ì¥³¡¼¥É(25¥Ð¥¤¥È) ¡ß 4
+
+ ####################
+ # ¥ì¥³¡¼¥É¤ÎÆâÍÆ #
+ ####################
+
+ 1 ¥Õ¥é¥°
+
+ ##################
+ # ¥Õ¥é¥°¤ÎÆâÍÆ #
+ ##################
+
+ ¡¡¡¡0 Í­¸ú/̵¸ú 0:̵¸ú 1:Í­¸ú
+ ¡¡¡¡1 checkºÑ/̤ 0:̤ 1:ºÑ
+ ¡¡¡¡2 [reserved]
+ ¡¡¡¡3 ¡¡¡¡¢¬
+ ¡¡¡¡4 ¡¡¡¡¢¬
+ ¡¡¡¡5¡¡ ¡¡¡¡¢¬
+ ¡¡¡¡6 ¡¡¡¡¢¬
+ ¡¡¡¡7 ¡¡¡¡¢¬
+ ¡¡ 4 ¥¨¥é¡¼¥¢¥É¥ì¥¹
+ 14 ȯÀ¸¥¿¥¤¥à¥¹¥¿¥ó¥×
+ 4 ¥·¥ó¥É¥í¡¼¥à
+ ¡¡ 1 ¥á¥â¥ê¥°¥ë¡¼¥×
+ 1 SIMMÆÃÄê¾ðÊó
+
+-----------------------------------------------------------------------------
+TOTAL 500 ¥Ð¥¤¥È
+
+
+ ###############################################################################
+ # ¢¬¤³¤³¤Þ¤Ç1268¥Ð¥¤¥È¡£¼¡¤ÎÎΰè¤ÎÀèƬ¤¬256¥Ð¥¤¥È¥Ð¥¦¥ó¥À¥ê¤«¤é»Ï¤Þ¤ë¤è¤¦¤Ë #
+ # 12¥Ð¥¤¥È¤ò[reserved]¤È¤·¤Æ¥Ñ¥Ç¥£¥ó¥°¤¹¤ë¡£ #
+ ###############################################################################
+
+ 12 [reserved]
+
+
+ ##########################
+ # ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊóÉô #
+ ##########################
+
+ 2048 ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊóÉô (1¥ì¥³¡¼¥É512¥Ð¥¤¥È ¡ß 4 ¡á 2K)
+
+ ####################
+ # ¥ì¥³¡¼¥É¤ÎÆâÍÆ #
+ ####################
+
+ 1 ¥Õ¥é¥°
+
+ ##################
+ # ¥Õ¥é¥°¤ÎÆâÍÆ #
+ ##################
+
+ ¡¡¡¡0 Í­¸ú/̵¸ú 0:̵¸ú 1:Í­¸ú
+ ¡¡¡¡1 checkºÑ/̤ 0:̤ 1:ºÑ
+ ¡¡¡¡2 Dump/Dump SW 0:D 1:D SW
+ ¡¡¡¡3 ÄÌÊó¤Î̵ͭ 0:̤ 1:ºÑ
+ ¡¡¡¡4 boot·ë²Ì 0:Àµ¾ï 1:°Û¾ï
+ ¡¡¡¡5 ¡¡¡¡¢¬
+ ¡¡¡¡6 ¡¡¡¡¢¬
+ ¡¡¡¡7 ¡¡¡¡¢¬
+ 14 ȯÀ¸¥¿¥¤¥à¥¹¥¿¥ó¥×
+ 496 ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊó
+ 1 [reserved]
+
+-----------------------------------------------------------------------------
+TOTAL 2048 ¥Ð¥¤¥È
+
+
+ #######################################################
+ # ¢¬¤³¤³¤Þ¤Ç3328¥Ð¥¤¥È¡£¤Á¤ç¤¦¤É256¥Ð¥¤¥È¥Ð¥¦¥ó¥À¥ê #
+ #######################################################
+
+
+ ###############################################################
+ # ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°Éô (1¥ì¥³¡¼¥É128¥Ð¥¤¥È ¡ß 32 ¡á 4K) #
+ ###############################################################
+
+ 4096 ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°Éô (1¥ì¥³¡¼¥É128¥Ð¥¤¥È ¡ß 32 ¡á 4K)
+
+ ####################
+ # ¥ì¥³¡¼¥É¤ÎÆâÍÆ #
+ ####################
+
+ 1 ¥Õ¥é¥°
+ ##################
+ # ¥Õ¥é¥°¤ÎÆâÍÆ #
+ ##################
+
+ ¡¡¡¡0 Í­¸ú/̵¸ú 0:̵¸ú 1:Í­¸ú
+ ¡¡¡¡1 checkºÑ/̤ 0:̤ 1:ºÑ
+ ¡¡¡¡2 Panic/Shutdown 0:P 1:S
+ ¡¡¡¡3 [reserved]
+ ¡¡¡¡4 ¡¡¡¡¢¬
+ ¡¡¡¡5 ¡¡¡¡¢¬
+ ¡¡¡¡6 ¡¡¡¡¢¬
+ ¡¡¡¡7 ¡¡¡¡¢¬
+ 14 ȯÀ¸¥¿¥¤¥à¥¹¥¿¥ó¥×
+ 20 ¥½¡¼¥¹Ì¾
+ 80 ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¾ðÊó
+ 13 [reserved]
+
+-----------------------------------------------------------------------------
+TOTAL 4096 ¥Ð¥¤¥È
+
+
+ #######################################################
+ # ¢¬¤³¤³¤Þ¤Ç7424¥Ð¥¤¥È¡£¤Á¤ç¤¦¤É256¥Ð¥¤¥È¥Ð¥¦¥ó¥À¥ê #
+ #######################################################
+
+
+ ##############################
+ # ¤·¤­¤¤ÃÍȽÄêÍѥǡ¼¥¿Îΰè #
+ ##############################
+
+ ¡¡ 256 [reserved]
+
+-----------------------------------------------------------------------------
+TOTAL 256 ¥Ð¥¤¥È
+
+
+ ###############################################################
+ # ¢¬¤³¤³¤Þ¤Ç7680(7K+512)¥Ð¥¤¥È¡£¤Á¤ç¤¦¤É256¥Ð¥¤¥È¥Ð¥¦¥ó¥À¥ê #
+ ###############################################################
+
+
+ ##############################
+ # ¥ê¥¶¡¼¥ÖÎΰè (512¥Ð¥¤¥È) #
+ ##############################
+
+ 512 PAiNTSÍÑ?
+
+-----------------------------------------------------------------------------
+TOTAL 512 ¥Ð¥¤¥È
+
+
+ #############################################
+ # ¢¬¤³¤³¤Þ¤Ç8192(8K)¥Ð¥¤¥È¡£NVRAM¤Î¤·¤Ã¤Ý #
+ #############################################
+
+******************************************************************************/
+
+
+#pragma pack(1)
+
+/********************
+ * *
+ * ¡¡¹½Â¤ÂÎÄêµÁ *
+ * *
+ ********************/
+
+
+/*
+ * WAS & PS¶¦ÄÌFWÍÑ¥á¥â¥ê¥¨¥é¡¼¾ðÊóÎΰè
+ */
+typedef struct _MEM_ERR_REC {
+ unsigned char mem_status; /* ¥¹¥Æ¡¼¥¿¥¹ */
+ unsigned char err_count; /* 1bit¥¨¥é¡¼¥«¥¦¥ó¥È */
+} MEM_ERR_REC, *pMEM_ERR_REC;
+
+
+/*
+ * ALIVE¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î
+ */
+typedef struct _ALIVE_AREA_INFO {
+ unsigned short offset_alive;
+ /* ALIVE¾ðÊ󥨥ꥢ¥ª¥Õ¥»¥Ã¥È */
+} ALIVE_AREA_INFO, *pALIVE_AREA_INFO;
+
+
+/*
+ * ECC1bit¥¨¥é¡¼¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î
+ */
+typedef struct _ECC1_ERR_AREA_INFO {
+ unsigned short offset_1biterr; /* ¥¨¥ê¥¢¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È */
+ unsigned short size_rec; /* 1¥ì¥³¡¼¥É¥µ¥¤¥º */
+ unsigned short num_rec; /* Áí¥ì¥³¡¼¥É¿ô */
+ unsigned short offset_latest; /* ºÇ¿·¥ì¥³¡¼¥É¥ª¥Õ¥»¥Ã¥È */
+ unsigned long read_data_latest; /* ºÇ¿·¥ê¡¼¥É¥¨¥é¡¼¥Ç¡¼¥¿ */
+ unsigned char err_count_group0; /* ¥á¥â¥êG#0 ¥¨¥é¡¼¥«¥¦¥ó¥È */
+ unsigned char err_count_group1; /* ¥á¥â¥êG#1 ¥¨¥é¡¼¥«¥¦¥ó¥È */
+ unsigned char err_count_group2; /* ¥á¥â¥êG#2 ¥¨¥é¡¼¥«¥¦¥ó¥È */
+ unsigned char err_count_group3; /* ¥á¥â¥êG#3 ¥¨¥é¡¼¥«¥¦¥ó¥È */
+ unsigned char err_count_group4; /* ¥á¥â¥êG#4 ¥¨¥é¡¼¥«¥¦¥ó¥È */
+ unsigned char err_count_group5; /* ¥á¥â¥êG#5 ¥¨¥é¡¼¥«¥¦¥ó¥È */
+ unsigned char err_count_group6; /* ¥á¥â¥êG#6 ¥¨¥é¡¼¥«¥¦¥ó¥È */
+ unsigned char err_count_group7; /* ¥á¥â¥êG#7 ¥¨¥é¡¼¥«¥¦¥ó¥È */
+} ECC1_ERR_AREA_INFO, *pECC1_ERR_AREA_INFO;
+
+
+/*
+ * ECC2bit¥¨¥é¡¼¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î
+ */
+typedef struct _ECC2_ERR_AREA_INFO {
+ unsigned short offset_2biterr; /* ¥¨¥ê¥¢¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È */
+ unsigned short size_rec; /* 1¥ì¥³¡¼¥É¥µ¥¤¥º */
+ unsigned short num_rec; /* Áí¥ì¥³¡¼¥É¿ô */
+ unsigned short offset_latest; /* ºÇ¿·¥ì¥³¡¼¥É¥ª¥Õ¥»¥Ã¥È */
+ unsigned long read_data_latest; /* ºÇ¿·¥ê¡¼¥É¥¨¥é¡¼¥Ç¡¼¥¿ */
+ unsigned char simm_flag_group1; /* ¥á¥â¥êG#1ÆâSIMM¥Õ¥é¥° */
+ unsigned char simm_flag_group2; /* ¥á¥â¥êG#2ÆâSIMM¥Õ¥é¥° */
+ unsigned char simm_flag_group3; /* ¥á¥â¥êG#3ÆâSIMM¥Õ¥é¥° */
+ unsigned char simm_flag_group4; /* ¥á¥â¥êG#4ÆâSIMM¥Õ¥é¥° */
+ char reserved[4]; /* reserved */
+} ECC2_ERR_AREA_INFO, *pECC2_ERR_AREA_INFO;
+
+
+/*
+ * ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î
+ */
+typedef struct _SYSTEM_ERR_AREA_INFO {
+ unsigned short offset_systemerr;/* ¥¨¥ê¥¢¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È */
+ unsigned short size_rec; /* 1¥ì¥³¡¼¥É¥µ¥¤¥º */
+ unsigned short num_rec; /* Áí¥ì¥³¡¼¥É¿ô */
+ unsigned short offset_latest; /* ºÇ¿·¥ì¥³¡¼¥É¥ª¥Õ¥»¥Ã¥È */
+} SYSTEM_ERR_AREA_INFO, *pSYSTEM_ERR_AREA_INFO;
+
+
+/*
+ * ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î
+ */
+typedef struct _CRITICAL_ERR_AREA_INFO {
+ unsigned short offset_critical; /* ¥¨¥ê¥¢¤ÎÀèƬ¤Ø¤Î¥ª¥Õ¥»¥Ã¥È */
+ unsigned short size_rec; /* 1¥ì¥³¡¼¥É¥µ¥¤¥º */
+ unsigned short num_rec; /* Áí¥ì¥³¡¼¥É¿ô */
+ unsigned short offset_latest; /* ºÇ¿·¥ì¥³¡¼¥É¥ª¥Õ¥»¥Ã¥È */
+} CRITICAL_ERR_AREA_INFO, *pCRITICAL_ERR_AREA_INFO;
+
+
+/*
+ * ¤·¤­¤¤ÃÍÅù¤½¤Î¾¤Î¾ðÊóÎΰè¤Ë´Ø¤¹¤ë¤â¤Î
+ */
+typedef struct _MISC_AREA_INFO {
+ unsigned short offset_misc;
+ /* ¤·¤­¤¤¤ÁÅù¤Î¾ðÊ󥨥ꥢÀèƬ¥ª¥Õ¥»¥Ã¥È */
+} MISC_AREA_INFO, *pMISC_AREA_INFO;
+
+
+/*
+ * ¥ê¥¶¡¼¥ÖÎΰè¤Ë´Ø¤¹¤ë¤â¤Î
+ */
+typedef struct _RESERVE_AREA_INFO {
+ unsigned short offset_reserve;
+ /* ¥ê¥¶¡¼¥Ö¥¨¥ê¥¢ÀèƬ¥ª¥Õ¥»¥Ã¥È */
+} RESERVE_AREA_INFO, *pRESERVE_AREA_INFO;
+
+
+/*
+ * ¥·¥¹¥Æ¥à¾ðÊ󥨥ꥢ
+ * 49¥Ð¥¤¥È
+ */
+
+typedef struct _SYS_INFO {
+ unsigned char system_flag; /* ¥·¥¹¥Æ¥à¾õÂ֥ե饰 */
+ char reserved1[3]; /* 4byte alignment¤Ë¤½¤Ê¤¨¤Æ */
+ char sys_description[32]; /* ¥·¥¹¥Æ¥à¤Î¾ðÊó */
+ unsigned long serical_num; /* ¥Þ¥·¥ó¥·¥ê¥¢¥ë¥Ê¥ó¥Ð¡¼ */
+ unsigned long magic; /* ¥Þ¥¸¥Ã¥¯¥Ê¥ó¥Ð¡¼ */
+ char reserved2[4]; /* reserved */
+} SYS_INFO, *pSYS_INFO;
+
+
+
+/*
+ * NVRAM¥Ø¥Ã¥ÀÉô
+ * 640¥Ð¥¤¥È
+ */
+
+typedef struct _NVRAM_HEADER {
+ MEM_ERR_REC mem_err_map[256]; /* ¥á¥â¥ê¥¨¥é¡¼¾ðÊóNT&NW¶¦ÄÌ¥¨¥ê¥¢ */
+ unsigned char nvram_flag; /* nvram¤Î¾õÂ֥ե饰 */
+ char when_formatted[14]; /* ¥Õ¥©¡¼¥Þ¥Ã¥È¥¿¥¤¥à¥¹¥¿¥ó¥× */
+ char reserved[3]; /* 4byte alignment ¤Ë¤½¤Ê¤¨¤Æ */
+ ALIVE_AREA_INFO alive; /* ALIVE¾ðÊ󥨥ꥢ */
+ ECC1_ERR_AREA_INFO ecc1bit_err; /* ECC1bit¥¨¥é¡¼¾ðÊ󥨥ꥢ */
+ ECC2_ERR_AREA_INFO ecc2bit_err; /* ECC2bit¥¨¥é¡¼¾ðÊ󥨥ꥢ */
+ SYSTEM_ERR_AREA_INFO system_err;/* ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊ󥨥ꥢ */
+ CRITICAL_ERR_AREA_INFO critical_err_log;
+ /* ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°¥¨¥ê¥¢ */
+ MISC_AREA_INFO misc; /* ¤·¤­¤¤¤Á¾ðÊ󥨥ꥢ */
+ RESERVE_AREA_INFO reserve; /* ¥ê¥¶¡¼¥Ö¥¨¥ê¥¢¥ª¥Õ¥»¥Ã¥È */
+ SYS_INFO system; /* ¥·¥¹¥Æ¥à¾ðÊó */
+} NVRAM_HEADER, *pNVRAM_HEADER;
+
+
+
+/*
+ * ALIVE, ¥Ú¡¼¥¸¥ã¡¼¥³¡¼¥ë¾ðÊ󥨥ꥢ
+ * 80¥Ð¥¤¥È
+ */
+
+typedef struct _ALIVE_INFO {
+ unsigned char alert_level; /* ÄÌÊó¥ì¥Ù¥ë¥° */
+ char primary_destination[16]; /* °ì¼¡ÄÌÊóÀèÅÅÏÃÈÖ¹æ */
+ char secondary_destinaiton[16]; /* Æó¼¡ÄÌÊóÀèÅÅÏÃÈÖ¹æ */
+ char reserved[47]; /* reserved for pager call */
+} ALIVE_INFO, *pALIVE_INFO;
+
+
+/*
+ * ¢¬¤³¤³¤Þ¤Ç720¥Ð¥¤¥È¡£¼¡¤ÎÎΰè¤ÎÀèƬ¤¬256¥Ð¥¤¥È¥Ð¥¦¥ó¥À¥ê¤«¤é»Ï¤Þ¤ë¤è¤¦¤Ë
+ * 48¥Ð¥¤¥È¤ò[reserved]¤È¤·¤Æ¥Ñ¥Ç¥£¥ó¥°¤¹¤ë¡£
+ */
+
+char reserved[48];
+
+
+typedef struct _ECC1_ERR_REC {
+ unsigned char record_flag; /* ¥ì¥³¡¼¥É¥Õ¥é¥° */
+ unsigned long err_address; /* ¥¨¥é¡¼¥¢¥É¥ì¥¹ */
+ char when_happened[14]; /* ȯÀ¸¥¿¥¤¥à¥¹¥¿¥ó¥× */
+ unsigned long syndrome; /* ¥·¥ó¥É¥í¡¼¥à */
+ unsigned char specified_group; /* ¥á¥â¥ê¥°¥ë¡¼¥× */
+ unsigned char specified_simm; /* SIMMÆÃÄê¾ðÊó */
+} ECC1_ERR_REC, *pECC1_ERR_REC;
+
+
+typedef struct _ECC2_ERR_REC {
+ unsigned char record_flag; /* ¥ì¥³¡¼¥É¥Õ¥é¥° */
+ unsigned long err_address; /* ¥¨¥é¡¼¥¢¥É¥ì¥¹ */
+ char when_happened[14]; /* ȯÀ¸¥¿¥¤¥à¥¹¥¿¥ó¥× */
+ unsigned long syndrome; /* ¥·¥ó¥É¥í¡¼¥à */
+ unsigned char specified_group; /* ¥á¥â¥ê¥°¥ë¡¼¥× */
+ unsigned char specified_simm; /* SIMMÆÃÄê¾ðÊó */
+} ECC2_ERR_REC, *pECC2_ERR_REC;
+
+
+/*
+ * ¥á¥â¥ê¥¨¥é¡¼¥í¥°Éô
+ * 500 ¥Ð¥¤¥È
+ */
+
+ECC1_ERR_REC ecc1_err_rec_log[16];
+
+ECC2_ERR_REC ecc2_err_rec_log[4];
+
+
+/*
+ * ¢¬¤³¤³¤Þ¤Ç1268¥Ð¥¤¥È¡£¼¡¤ÎÎΰè¤ÎÀèƬ¤¬256¥Ð¥¤¥È¥Ð¥¦¥ó¥À¥ê¤«¤é»Ï¤Þ¤ë¤è¤¦¤Ë
+ * 12¥Ð¥¤¥È¤ò[reserved]¤È¤·¤Æ¥Ñ¥Ç¥£¥ó¥°¤¹¤ë¡£
+ */
+
+char reserved2[12];
+
+
+typedef struct _STOP_ERR_REC {
+ unsigned char record_flag; /* ¥ì¥³¡¼¥É¥Õ¥é¥° */
+ char when_happened[14]; /* ȯÀ¸¥¿¥¤¥à¥¹¥¿¥ó¥× */
+ char err_description[496]; /* ¥·¥¹¥Æ¥à¥¨¥é¡¼¾ðÊó */
+ char reserved[1]; /* reserved */
+} STOP_ERR_REC, *pSTOP_ERR_REC;
+
+/*
+ * ¥¹¥Ã¥È¥×¥¨¥é¡¼¾ðÊóÉô
+ * 2048 ¥Ð¥¤¥È
+ */
+
+STOP_ERR_REC stop_err_rec_log[4];
+
+
+typedef struct _CRITICAL_ERR_REC {
+ unsigned char record_flag; /* ¥ì¥³¡¼¥É¥Õ¥é¥° */
+ char when_happened[14]; /* ȯÀ¸¥¿¥¤¥à¥¹¥¿¥ó¥× */
+ char source[14]; /* ¥½¡¼¥¹Ì¾ */
+ char err_description[496]; /* ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¾ðÊó */
+ char reserved[13]; /* reserved */
+} CRITICAL_ERR_REC, *pCRITICAL;
+
+
+/* ¡¡
+ * ¥¯¥ê¥Æ¥£¥«¥ë¥¨¥é¡¼¥í¥°Éô (1¥ì¥³¡¼¥É128¥Ð¥¤¥È ¡ß 32 ¡á 4K)
+ * 4096¥Ð¥¤¥È
+ */
+
+CRITICAL_ERR_REC critical_err_rec_log[32];
+
+
+/*
+ * ¤·¤­¤¤ÃÍȽÄêÍÑÅù¥Ç¡¼¥¿Îΰè.
+ * 256¥Ð¥¤¥È
+ */
+
+char reserved3[256]; /* reserved */
+
+
+/*
+ * ¥ê¥¶¡¼¥ÖÎΰè(PAiNTSÍÑ?)
+ * 512¥Ð¥¤¥È
+ */
+
+char reserved4[512]; /* reserved for paints ? */
+
+#pragma pack(4)
diff --git a/private/ntos/nthals/halr96b/mips/glint.h b/private/ntos/nthals/halr96b/mips/glint.h
new file mode 100644
index 000000000..ac8c6e07a
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/glint.h
@@ -0,0 +1,580 @@
+// #pragma comment(exestr, "@(#) glint.h 1.1 95/09/28 15:32:57 nec")
+/************************************************************************
+ * *
+ * Copyright (c) 1994 3Dlabs Inc. Ltd. *
+ * All rights reserved *
+ * *
+ * This software and its associated documentation contains proprietary, *
+ * confidential and trade secret information of 3Dlabs Inc. Ltd. and *
+ * except as provided by written agreement with 3Dlabs Inc. Ltd. *
+ * *
+ * a) no part may be disclosed, distributed, reproduced, transmitted, *
+ * transcribed, stored in a retrieval system, adapted or translated *
+ * in any form or by any means electronic, mechanical, magnetic, *
+ * optical, chemical, manual or otherwise, *
+ * *
+ * and *
+ * *
+ * b) the recipient is not entitled to discover through reverse *
+ * engineering or reverse compiling or other such techniques or *
+ * processes the trade secrets contained therein or in the *
+ * documentation. *
+ * *
+ ************************************************************************/
+
+#ifndef __GLINT_H__
+#define __GLINT_H__
+
+typedef unsigned long DWORD;
+
+/************************************************************************/
+/* PCI CONFIGURATION REGION */
+/************************************************************************/
+
+#define __GLINT_CFGVendorId PCI_CS_VENDOR_ID
+#define __GLINT_CFGDeviceId PCI_CS_DEVICE_ID
+#define __GLINT_CFGRevisionId PCI_CS_REVISION_ID
+#define __GLINT_CFGClassCode PCI_CS_CLASS_CODE
+#define __GLINT_CFGHeaderType PCI_CS_HEADER_TYPE
+#define __GLINT_CFGCommand PCI_CS_COMMAND
+#define __GLINT_CFGStatus PCI_CS_STATUS
+#define __GLINT_CFGBist PCI_CS_BIST
+#define __GLINT_CFGLatTimer PCI_CS_MASTER_LATENCY
+#define __GLINT_CFGCacheLine PCI_CS_CACHE_LINE_SIZE
+#define __GLINT_CFGMaxLat PCI_CS_MAX_LAT
+#define __GLINT_CFGMinGrant PCI_CS_MIN_GNT
+#define __GLINT_CFGIntPin PCI_CS_INTERRUPT_PIN
+#define __GLINT_CFGIntLine PCI_CS_INTERRUPT_LINE
+
+#define __GLINT_CFGBaseAddr0 PCI_CS_BASE_ADDRESS_0
+#define __GLINT_CFGBaseAddr1 PCI_CS_BASE_ADDRESS_1
+#define __GLINT_CFGBaseAddr2 PCI_CS_BASE_ADDRESS_2
+#define __GLINT_CFGBaseAddr3 PCI_CS_BASE_ADDRESS_3
+#define __GLINT_CFGBaseAddr4 PCI_CS_BASE_ADDRESS_4
+#define __GLINT_CFGRomAddr PCI_CS_EXPANSION_ROM
+
+/* CFGVendorId[15:0] - 3Dlabs Vendor ID Value */
+
+#define GLINT_VENDOR_ID (0x3D3D)
+
+/* CFGDeviceId[15:0] - GLINT 300SX Device ID */
+
+#define GLINT_DEVICE_ID (0x0001)
+
+/* CFGRevisionID[7:0] - GLINT Revision Code */
+
+#define GLINT_REVISION_A (0x00)
+#define GLINT_REVISION_B (0x01)
+
+/* CFGClassCode[23:0] - Other Display Controller */
+
+#define GLINT_CLASS_CODE ((DWORD) 0x00038000)
+
+/* CFGHeaderType[7:0] - Single Function Device */
+
+#define GLINT_HEADER_TYPE (0x00)
+
+/* CFGCommand[15:0] - Reset Value Zero */
+
+#define GLINT_COMMAND_RESET_VALUE (0x0000)
+
+/* CFGCommand[1] - Memory Access Enable */
+
+#define GLINT_MEMORY_ACCESS_MASK (1 << 0)
+#define GLINT_MEMORY_ACCESS_DISABLE (0 << 0)
+#define GLINT_MEMORY_ACCESS_ENABLE (1 << 1)
+
+/* CFGCommand[2] - Master Enable */
+
+#define GLINT_MASTER_ENABLE_MASK (1 << 2)
+#define GLINT_MASTER_DISABLE (0 << 2)
+#define GLINT_MASTER_ENABLE (1 << 2)
+
+/* CFGStatus[15:0] - Reset Value Zero */
+
+#define GLINT_STATUS_RESET_VALUE (0x0000)
+
+/* CFGBist - Built In Self Test Unsupported */
+
+#define GLINT_BIST (0x00)
+
+/* CFGCacheLine - Cache Line Size Unsupported */
+
+#define GLINT_CACHE_LINE (0x00)
+
+/* CFGIntPin - Interrupt Pin INTA# */
+
+#define GLINT_INTERRUPT_PIN (0x01)
+
+/********************/
+
+#define GLINT_CONTROL_BASE __GLINT_CFGBaseAddr0
+#define GLINT_LOCAL_0_BASE __GLINT_CFGBaseAddr1
+#define GLINT_FRAME_0_BASE __GLINT_CFGBaseAddr2
+#define GLINT_LOCAL_1_BASE __GLINT_CFGBaseAddr3
+#define GLINT_FRAME_1_BASE __GLINT_CFGBaseAddr4
+#define GLINT_EPROM_BASE __GLINT_CFGRomAddr
+
+#define GLINT_EPROM_SIZE ((DWORD)(64L * 1024L))
+
+/************************************************************************/
+/* CONTROL AND STATUS REGISTERS */
+/************************************************************************/
+
+#define GLINT_REGION_0_SIZE ((DWORD)(128L * 1024L))
+
+#define __GLINT_ResetStatus 0x0000
+#define __GLINT_IntEnable 0x0008
+#define __GLINT_IntFlags 0x0010
+#define __GLINT_InFIFOSpace 0x0018
+#define __GLINT_OutFIFOWords 0x0020
+#define __GLINT_DMAAddress 0x0028
+#define __GLINT_DMACount 0x0030
+#define __GLINT_ErrorFlags 0x0038
+#define __GLINT_VClkCtl 0x0040
+#define __GLINT_TestRegister 0x0048
+#define __GLINT_Aperture0 0x0050
+#define __GLINT_Aperture1 0x0058
+#define __GLINT_DMAControl 0x0060
+
+/* ResetStatus[31] - Software Reset Flag */
+
+#define GLINT_RESET_STATUS_MASK ((DWORD) 1 << 31)
+#define GLINT_READY_FOR_USE ((DWORD) 0 << 31)
+#define GLINT_RESET_IN_PROGRESS ((DWORD) 1 << 31)
+
+/* IntEnable[4:0] - Interrupt Enable Register */
+
+#define GLINT_INT_ENABLE_DMA ((DWORD) 1 << 0)
+#define GLINT_INT_ENABLE_SYNC ((DWORD) 1 << 1)
+#define GLINT_INT_ENABLE_EXTERNAL ((DWORD) 1 << 2)
+#define GLINT_INT_ENABLE_ERROR ((DWORD) 1 << 3)
+#define GLINT_INT_ENABLE_VERTICAL ((DWORD) 1 << 4)
+
+/* IntFlags[4:0] - Interrupt Flags Register */
+
+#define GLINT_INT_FLAG_DMA ((DWORD) 1 << 0)
+#define GLINT_INT_FLAG_SYNC ((DWORD) 1 << 1)
+#define GLINT_INT_FLAG_EXTERNAL ((DWORD) 1 << 2)
+#define GLINT_INT_FLAG_ERROR ((DWORD) 1 << 3)
+#define GLINT_INT_FLAG_VERTICAL ((DWORD) 1 << 4)
+
+/* ErrorFlags[2:0] - Error Flags Register */
+
+#define GLINT_ERROR_INPUT_FIFO ((DWORD) 1 << 0)
+#define GLINT_ERROR_OUTPUT_FIFO ((DWORD) 1 << 1)
+#define GLINT_ERROR_COMMAND ((DWORD) 1 << 2)
+
+/* ApertureX[1:0] - Framebuffer Byte Control */
+
+#define GLINT_FB_BYTE_CONTROL_MASK ((DWORD) 3 << 0)
+#define GLINT_FB_LITTLE_ENDIAN ((DWORD) 0 << 0)
+#define GLINT_FB_BIG_ENDIAN ((DWORD) 1 << 0)
+#define GLINT_FB_GIB_ENDIAN ((DWORD) 2 << 0)
+#define GLINT_FB_BYTE_RESERVED ((DWORD) 3 << 0)
+
+/* ApertureX[2] - Localbuffer Byte Control */
+
+#define GLINT_LB_BYTE_CONTROL_MASK ((DWORD) 1 << 2)
+#define GLINT_LB_LITTLE_ENDIAN ((DWORD) 0 << 2)
+#define GLINT_LB_BIG_ENDIAN ((DWORD) 1 << 2)
+
+/* DMAControl[0] - DMA Byte Swap Control */
+
+#define GLINT_DMA_CONTROL_MASK ((DWORD) 1 << 0)
+#define GLINT_DMA_LITTLE_ENDIAN ((DWORD) 0 << 0)
+#define GLINT_DMA_BIG_ENDIAN ((DWORD) 1 << 0)
+
+/************************************************************************/
+/* LOCALBUFFER REGISTERS */
+/************************************************************************/
+
+#define __GLINT_LBMemoryCtl 0x1000
+
+/* LBMemoryCtl[0] - Number of Localbuffer Banks */
+
+#define GLINT_LB_BANK_MASK ((DWORD) 1 << 0)
+#define GLINT_LB_ONE_BANK ((DWORD) 0 << 0)
+#define GLINT_LB_TWO_BANKS ((DWORD) 1 << 0)
+
+/* LBMemoryCtl[2:1] - Localbuffer Page Size */
+
+#define GLINT_LB_PAGE_SIZE_MASK ((DWORD) 2 << 1)
+#define GLINT_LB_PAGE_SIZE_256_PIXELS ((DWORD) 0 << 1)
+#define GLINT_LB_PAGE_SIZE_512_PIXELS ((DWORD) 1 << 1)
+#define GLINT_LB_PAGE_SIZE_1024_PIXELS ((DWORD) 2 << 1)
+#define GLINT_LB_PAGE_SIZE_2048_PIXELS ((DWORD) 3 << 1)
+
+/* LBMemoryCtl[4:3] - Localbuffer RAS-CAS Low */
+
+#define GLINT_LB_RAS_CAS_LOW_MASK ((DWORD) 3 << 3)
+#define GLINT_LB_RAS_CAS_LOW_2_CLOCKS ((DWORD) 0 << 3)
+#define GLINT_LB_RAS_CAS_LOW_3_CLOCKS ((DWORD) 1 << 3)
+#define GLINT_LB_RAS_CAS_LOW_4_CLOCKS ((DWORD) 2 << 3)
+#define GLINT_LB_RAS_CAS_LOW_5_CLOCKS ((DWORD) 3 << 3)
+
+/* LBMemoryCtl[6:5] - Localbuffer RAS Precharge */
+
+#define GLINT_LB_RAS_PRECHARGE_MASK ((DWORD) 3 << 5)
+#define GLINT_LB_RAS_PRECHARGE_2_CLOCKS ((DWORD) 0 << 5)
+#define GLINT_LB_RAS_PRECHARGE_3_CLOCKS ((DWORD) 1 << 5)
+#define GLINT_LB_RAS_PRECHARGE_4_CLOCKS ((DWORD) 2 << 5)
+#define GLINT_LB_RAS_PRECHARGE_5_CLOCKS ((DWORD) 3 << 5)
+
+/* LBMemoryCtl[8:7] - Localbuffer CAS Low */
+
+#define GLINT_LB_CAS_LOW_MASK ((DWORD) 3 << 7)
+#define GLINT_LB_CAS_LOW_1_CLOCK ((DWORD) 0 << 7)
+#define GLINT_LB_CAS_LOW_2_CLOCKS ((DWORD) 1 << 7)
+#define GLINT_LB_CAS_LOW_3_CLOCKS ((DWORD) 2 << 7)
+#define GLINT_LB_CAS_LOW_4_CLOCKS ((DWORD) 3 << 7)
+
+/* LBMemoryCtl[9] - Localbuffer Page Mode Disable */
+
+#define GLINT_LB_PAGE_MODE_MASK ((DWORD) 1 << 9)
+#define GLINT_LB_PAGE_MODE_ENABLE ((DWORD) 0 << 9)
+#define GLINT_LB_PAGE_MODE_DISABLE ((DWORD) 1 << 9)
+
+/* LBMemoryCtl[17:10] - Localbuffer Refresh Count */
+
+#define GLINT_LB_REFRESH_COUNT_MASK ((DWORD) 0xFF << 10)
+#define GLINT_LB_REFRESH_COUNT_SHIFT (10)
+
+#define GLINT_LB_REFRESH_COUNT_DEFAULT ((DWORD) 0x20 << 10)
+
+/* LBMemoryCtl[18] - Localbuffer Dual Write Enables */
+
+#define GLINT_LB_MEM_TYPE_MASK ((DWORD) 1 << 18)
+#define GLINT_LB_MEM_DUAL_CAS ((DWORD) 0 << 18)
+#define GLINT_LB_MEM_DUAL_WE ((DWORD) 1 << 18)
+
+/* LBMemoryCtl[21:20] - PCI Maximum Latency - Read Only */
+
+#define GLINT_PCI_MAX_LATENCY_MASK ((DWORD) 3 << 20)
+#define GLINT_PCI_MAX_LATENCY_SHIFT (20)
+
+/* LBMemoryCtl[23:22] - PCI Minimum Grant - Read Only */
+
+#define GLINT_PCI_MIN_GRANT_MASK ((DWORD) 3 << 22)
+#define GLINT_PCI_MIN_GRANT_SHIFT (22)
+
+/* LBMemoryCtl[26:24] - Localbuffer Visible Region Size - Read Only */
+
+#define GLINT_LB_REGION_SIZE_MASK ((DWORD) 7 << 24)
+#define GLINT_LB_REGION_SIZE_1_MB ((DWORD) 0 << 24)
+#define GLINT_LB_REGION_SIZE_2_MB ((DWORD) 1 << 24)
+#define GLINT_LB_REGION_SIZE_4_MB ((DWORD) 2 << 24)
+#define GLINT_LB_REGION_SIZE_8_MB ((DWORD) 3 << 24)
+#define GLINT_LB_REGION_SIZE_16_MB ((DWORD) 4 << 24)
+#define GLINT_LB_REGION_SIZE_32_MB ((DWORD) 5 << 24)
+#define GLINT_LB_REGION_SIZE_64_MB ((DWORD) 6 << 24)
+#define GLINT_LB_REGION_SIZE_0_MB ((DWORD) 7 << 24)
+
+/* LBMemoryCtl[29:27] - Localbuffer Width - Read Only */
+
+#define GLINT_LB_WIDTH_MASK ((DWORD) 7 << 27)
+#define GLINT_LB_WIDTH_16_BITS ((DWORD) 0 << 27)
+#define GLINT_LB_WIDTH_18_BITS ((DWORD) 1 << 27)
+#define GLINT_LB_WIDTH_24_BITS ((DWORD) 2 << 27)
+#define GLINT_LB_WIDTH_32_BITS ((DWORD) 3 << 27)
+#define GLINT_LB_WIDTH_36_BITS ((DWORD) 4 << 27)
+#define GLINT_LB_WIDTH_40_BITS ((DWORD) 5 << 27)
+#define GLINT_LB_WIDTH_48_BITS ((DWORD) 6 << 27)
+#define GLINT_LB_WIDTH_OTHER ((DWORD) 7 << 27)
+
+/* LBMemoryCtl[30] - Localbuffer Bypass Packing - Read Only */
+
+#define GLINT_LB_BYPASS_STEP_MASK ((DWORD) 1 << 30)
+#define GLINT_LB_BYPASS_STEP_64_BITS ((DWORD) 0 << 30)
+#define GLINT_LB_BYPASS_STEP_32_BITS ((DWORD) 1 << 30)
+
+/* LBMemoryCtl[31] - Localbuffer Aperture One Enable - Read Only */
+
+#define GLINT_LB_APERTURE_ONE_MASK ((DWORD) 1 << 31)
+#define GLINT_LB_APERTURE_ONE_DISABLE ((DWORD) 0 << 31)
+#define GLINT_LB_APERTURE_ONE_ENABLE ((DWORD) 1 << 31)
+
+/************************************************************************/
+/* FRAMEBUFFER REGISTERS */
+/************************************************************************/
+
+#define __GLINT_FBMemoryCtl 0x1800
+#define __GLINT_FBModeSel 0x1808
+#define __GLINT_FBGCWrMask 0x1810
+#define __GLINT_FBGCColorMask 0x1818
+
+/* FBMemoryCtl[1:0] - Framebuffer RAS-CAS Low */
+
+#define GLINT_FB_RAS_CAS_LOW_MASK ((DWORD) 3 << 0)
+#define GLINT_FB_RAS_CAS_LOW_2_CLOCKS ((DWORD) 0 << 0)
+#define GLINT_FB_RAS_CAS_LOW_3_CLOCKS ((DWORD) 1 << 0)
+#define GLINT_FB_RAS_CAS_LOW_4_CLOCKS ((DWORD) 2 << 0)
+#define GLINT_FB_RAS_CAS_LOW_5_CLOCKS ((DWORD) 3 << 0)
+
+/* FBMemoryCtl[3:2] - Framebuffer RAS Precharge */
+
+#define GLINT_FB_RAS_PRECHARGE_MASK ((DWORD) 3 << 2)
+#define GLINT_FB_RAS_PRECHARGE_2_CLOCKS ((DWORD) 0 << 2)
+#define GLINT_FB_RAS_PRECHARGE_3_CLOCKS ((DWORD) 1 << 2)
+#define GLINT_FB_RAS_PRECHARGE_4_CLOCKS ((DWORD) 2 << 2)
+#define GLINT_FB_RAS_PRECHARGE_5_CLOCKS ((DWORD) 3 << 2)
+
+/* FBMemoryCtl[5:4] - Framebuffer CAS Low */
+
+#define GLINT_FB_CAS_LOW_MASK ((DWORD) 3 << 4)
+#define GLINT_FB_CAS_LOW_1_CLOCK ((DWORD) 0 << 4)
+#define GLINT_FB_CAS_LOW_2_CLOCKS ((DWORD) 1 << 4)
+#define GLINT_FB_CAS_LOW_3_CLOCKS ((DWORD) 2 << 4)
+#define GLINT_FB_CAS_LOW_4_CLOCKS ((DWORD) 3 << 4)
+
+/* FBMemoryCtl[13:6] - Framebuffer Refresh Count */
+
+#define GLINT_FB_REFRESH_COUNT_MASK ((DWORD) 0xFF << 6)
+#define GLINT_FB_REFRESH_COUNT_SHIFT (6)
+
+#define GLINT_FB_REFRESH_COUNT_DEFAULT ((DWORD) 0x20 << 6)
+
+/* FBMemoryCtl[14] - Framebuffer Page Mode Disable */
+
+#define GLINT_FB_PAGE_MODE_MASK ((DWORD) 1 << 14)
+#define GLINT_FB_PAGE_MODE_ENABLE ((DWORD) 0 << 14)
+#define GLINT_FB_PAGE_MODE_DISABLE ((DWORD) 1 << 14)
+
+/* FBMemoryCtl[25:20] - Reserved - Read Only */
+
+#define GLINT_FB_CTL_RESERVED_MASK ((DWORD) 0x3F << 20)
+#define GLINT_FB_CTL_RESERVED_SHIFT (20)
+
+/* FBMemoryCtl[26] - Byte Swap Configuration Space - Read Only */
+
+#define GLINT_BYTE_SWAP_CONFIG_MASK ((DWORD) 1 << 26)
+#define GLINT_BYTE_SWAP_CONFIG_DISABLE ((DWORD) 0 << 26)
+#define GLINT_BYTE_SWAP_CONFIG_ENABLE ((DWORD) 1 << 26)
+
+/* FBMemoryCtl[28] - Framebuffer Aperture One Enable - Read Only */
+
+#define GLINT_FB_APERTURE_ONE_MASK ((DWORD) 1 << 28)
+#define GLINT_FB_APERTURE_ONE_DISABLE ((DWORD) 0 << 28)
+#define GLINT_FB_APERTURE_ONE_ENABLE ((DWORD) 1 << 28)
+
+/* FBMemoryCtl[31:29] - Framebuffer Visible Region Size - Read Only */
+
+#define GLINT_FB_REGION_SIZE_MASK ((DWORD) 7 << 29)
+#define GLINT_FB_REGION_SIZE_1_MB ((DWORD) 0 << 29)
+#define GLINT_FB_REGION_SIZE_2_MB ((DWORD) 1 << 29)
+#define GLINT_FB_REGION_SIZE_4_MB ((DWORD) 2 << 29)
+#define GLINT_FB_REGION_SIZE_8_MB ((DWORD) 3 << 29)
+#define GLINT_FB_REGION_SIZE_16_MB ((DWORD) 4 << 29)
+#define GLINT_FB_REGION_SIZE_32_MB ((DWORD) 5 << 29)
+#define GLINT_FB_REGION_SIZE_RESERVED ((DWORD) 6 << 29)
+#define GLINT_FB_REGION_SIZE_0_MB ((DWORD) 7 << 29)
+
+/* FBModeSel[0] - Framebuffer Width */
+
+#define GLINT_FB_WIDTH_MASK ((DWORD) 1 << 0)
+#define GLINT_FB_WIDTH_32_BITS ((DWORD) 0 << 0)
+#define GLINT_FB_WIDTH_64_BITS ((DWORD) 1 << 0)
+
+/* FBModeSel[2:1] - Framebuffer Packing */
+
+#define GLINT_FB_PACKING_MASK ((DWORD) 2 << 1)
+#define GLINT_FB_PACKING_32_BITS ((DWORD) 0 << 1)
+#define GLINT_FB_PACKING_16_BITS ((DWORD) 1 << 1)
+#define GLINT_FB_PACKING_8_BITS ((DWORD) 2 << 1)
+#define GLINT_FB_PACKING_RESERVED ((DWORD) 3 << 1)
+
+/* FBModeSel[3] - Fast Mode Disable */
+
+#define GLINT_FB_FAST_MODE_MASK ((DWORD) 1 << 3)
+#define GLINT_FB_FAST_MODE_ENABLE ((DWORD) 0 << 3)
+#define GLINT_FB_FAST_MODE_DISABLE ((DWORD) 1 << 3)
+
+/* FBModeSel[5:4] - Shared Framebuffer Mode - Read Only */
+
+#define GLINT_SFB_MODE_MASK ((DWORD) 3 << 4)
+#define GLINT_SFB_DISABLED ((DWORD) 0 << 4)
+#define GLINT_SFB_ARBITER ((DWORD) 1 << 4)
+#define GLINT_SFB_REQUESTER ((DWORD) 2 << 4)
+#define GLINT_SFB_RESERVED ((DWORD) 3 << 4)
+
+/* FBModeSel[6] - Transfer Disable */
+
+#define GLINT_TRANSFER_MODE_MASK ((DWORD) 1 << 6)
+#define GLINT_TRANSFER_ENABLE ((DWORD) 0 << 6)
+#define GLINT_TRANSFER_DISABLE ((DWORD) 1 << 6)
+
+/* FBModeSel[7] - External VTG Select */
+
+#define GLINT_VTG_SELECT_MASK ((DWORD) 1 << 7)
+#define GLINT_INTERNAL_VTG ((DWORD) 0 << 7)
+#define GLINT_EXTERNAL_VTG ((DWORD) 1 << 7)
+
+/* FBModeSel[9:8] - Framebuffer Interleave */
+
+#define GLINT_FB_INTERLEAVE_MASK ((DWORD) 3 << 8)
+#define GLINT_FB_INTERLEAVE_1_WAY ((DWORD) 0 << 8)
+#define GLINT_FB_INTERLEAVE_2_WAY ((DWORD) 1 << 8)
+#define GLINT_FB_INTERLEAVE_4_WAY ((DWORD) 2 << 8)
+#define GLINT_FB_INTERLEAVE_8_WAY ((DWORD) 3 << 8)
+
+/* FBModeSel[11:10] - Framebuffer Block Fill Size */
+
+#define GLINT_FB_BLOCK_FILL_SIZE_MASK ((DWORD) 3 << 10)
+#define GLINT_FB_BLOCK_FILL_UNSUPPORTED ((DWORD) 0 << 10)
+#define GLINT_FB_BLOCK_FILL_4_PIXEL ((DWORD) 1 << 10)
+#define GLINT_FB_BLOCK_FILL_8_PIXEL ((DWORD) 2 << 10)
+#define GLINT_FB_BLOCK_FILL_RESERVED ((DWORD) 3 << 10)
+
+/* FBModeSel[12] - Framebuffer Dual Write Enables */
+
+#define GLINT_FB_MEM_TYPE_MASK ((DWORD) 1 << 12)
+#define GLINT_FB_MEM_DUAL_CAS ((DWORD) 0 << 12)
+#define GLINT_FB_MEM_DUAL_WE ((DWORD) 1 << 12)
+
+/************************************************************************/
+/* INTERNAL VIDEO TIMING GENERATOR REGISTERS */
+/************************************************************************/
+
+#define __GLINT_VTGHLimit 0x3000
+#define __GLINT_VTGHSyncStart 0x3008
+#define __GLINT_VTGHSyncEnd 0x3010
+#define __GLINT_VTGHBlankEnd 0x3018
+#define __GLINT_VTGVLimit 0x3020
+#define __GLINT_VTGVSyncStart 0x3028
+#define __GLINT_VTGVSyncEnd 0x3030
+#define __GLINT_VTGVBlankEnd 0x3038
+#define __GLINT_VTGHGateStart 0x3040
+#define __GLINT_VTGHGateEnd 0x3048
+#define __GLINT_VTGVGateStart 0x3050
+#define __GLINT_VTGVGateEnd 0x3058
+#define __GLINT_VTGPolarity 0x3060
+#define __GLINT_VTGFrameRowAddr 0x3068
+#define __GLINT_VTGVLineNumber 0x3070
+#define __GLINT_VTGSerialClk 0x3078
+
+/* VTGPolarity[1:0] - HSync Ctl */
+
+#define GLINT_HSYNC_POLARITY_MASK ((DWORD) 3 << 0)
+#define GLINT_HSYNC_ACTIVE_HIGH ((DWORD) 0 << 0)
+#define GLINT_HSYNC_FORCED_HIGH ((DWORD) 1 << 0)
+#define GLINT_HSYNC_ACTIVE_LOW ((DWORD) 2 << 0)
+#define GLINT_HSYNC_FORCED_LOW ((DWORD) 3 << 0)
+
+/* VTGPolarity[3:2] - Vsync Ctl */
+
+#define GLINT_VSYNC_POLARITY_MASK ((DWORD) 3 << 2)
+#define GLINT_VSYNC_ACTIVE_HIGH ((DWORD) 0 << 2)
+#define GLINT_VSYNC_FORCED_HIGH ((DWORD) 1 << 2)
+#define GLINT_VSYNC_ACTIVE_LOW ((DWORD) 2 << 2)
+#define GLINT_VSYNC_FORCED_LOW ((DWORD) 3 << 2)
+
+/* VTGPolarity[5:4] - Csync Ctl */
+
+#define GLINT_CSYNC_POLARITY_MASK ((DWORD) 3 << 4)
+#define GLINT_CSYNC_ACTIVE_HIGH ((DWORD) 0 << 4)
+#define GLINT_CSYNC_FORCED_HIGH ((DWORD) 1 << 4)
+#define GLINT_CSYNC_ACTIVE_LOW ((DWORD) 2 << 4)
+#define GLINT_CSYNC_FORCED_LOW ((DWORD) 3 << 4)
+
+/* VTGPolarity[7:6] - CBlank Ctl */
+
+#define GLINT_CBLANK_POLARITY_MASK ((DWORD) 3 << 6)
+#define GLINT_CBLANK_ACTIVE_HIGH ((DWORD) 0 << 6)
+#define GLINT_CBLANK_FORCED_HIGH ((DWORD) 1 << 6)
+#define GLINT_CBLANK_ACTIVE_LOW ((DWORD) 2 << 6)
+#define GLINT_CBLANK_FORCED_LOW ((DWORD) 3 << 6)
+
+/* VTGSerialClk[0] - QSF Select */
+
+#define GLINT_QSF_SELECT_MASK ((DWORD) 1 << 0)
+#define GLINT_EXTERNAL_QSF ((DWORD) 0 << 0)
+#define GLINT_INTERNAL_QSF ((DWORD) 1 << 0)
+
+/* VTGSerialClk[1] - Split Size */
+
+#define GLINT_SPLIT_SIZE_MASK ((DWORD) 1 << 1)
+#define GLINT_SPLIT_SIZE_128_WORD ((DWORD) 0 << 1)
+#define GLINT_SPLIT_SIZE_256_WORD ((DWORD) 1 << 1)
+
+/* VTGSerialClk[2] - SCLK Ctl */
+
+#define GLINT_SCLK_CTL_MASK ((DWORD) 1 << 2)
+#define GLINT_SCLK_VCLK ((DWORD) 0 << 2)
+#define GLINT_SCLK_VCLK_DIV_2 ((DWORD) 1 << 2)
+
+/* VTGSerialClk[3] - SOE Ctl */
+
+#define GLINT_SOE_CTL_MASK ((DWORD) 1 << 3)
+#define GLINT_SOE_0_ASSERTED ((DWORD) 0 << 3)
+#define GLINT_SOE_1_ASSERTED ((DWORD) 1 << 3)
+
+/************************************************************************/
+/* EXTERNAL VIDEO CONTROL REGISTERS */
+/************************************************************************/
+
+#define __GLINT_ExternalVideoControl 0x4000
+
+/************************************************************************/
+/* GRAPHICS CORE REGISTERS AND FIFO INTERFACE */
+/************************************************************************/
+
+#define __GLINT_GraphicsCoreRegisters 0x8000
+
+#define __GLINT_GraphicsFIFOInterface 0x2000
+
+/************************************************************************/
+/* GLINT ACCESS MACROS */
+/************************************************************************/
+
+#define GLINT_ADDR(base, offset) \
+( \
+/* (DWORD) ((volatile BYTE *)(base) + (offset)) */ \
+ (DWORD) ((volatile UCHAR *)(base) + (offset)) \
+)
+
+#define GLINT_WRITE(base, offset, data) \
+{ \
+/* DWORD_WRITE(GLINT_ADDR((base),(offset)), (data)); */ \
+ WRITE_REGISTER_ULONG(GLINT_ADDR((base),(offset)), (ULONG)(data)); \
+}
+
+#define GLINT_READ(base, offset, data) \
+{ \
+/* DWORD_READ(GLINT_ADDR((base),(offset)), (data)); */ \
+ (ULONG)(data) = READ_REGISTER_ULONG(GLINT_ADDR((base),(ULONG)(offset))); \
+}
+
+typedef struct
+{
+ /* image size */
+
+ long ImageWidth;
+ long ImageHeight;
+ long ImageDepth;
+
+ /* video timing */
+
+ DWORD HLimit;
+ DWORD HSyncStart;
+ DWORD HSyncEnd;
+ DWORD HBlankEnd;
+ DWORD HSyncPolarity;
+ DWORD VLimit;
+ DWORD VSyncStart;
+ DWORD VSyncEnd;
+ DWORD VBlankEnd;
+ DWORD VSyncPolarity;
+
+ /* Ramdac config */
+
+ DWORD PixelFormat;
+ DWORD RefDivCount;
+ DWORD PixelClock;
+
+ } __VIDEO, *VIDEO;
+
+/************************************************************************/
+
+#endif /* __GLINT_H__ */
+
+/************************************************************************/
diff --git a/private/ntos/nthals/halr96b/mips/halp.h b/private/ntos/nthals/halr96b/mips/halp.h
new file mode 100644
index 000000000..13a1b58e0
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/halp.h
@@ -0,0 +1,365 @@
+// #pragma comment(exestr, "@(#) halp.h 1.1 95/09/28 15:33:24 nec")
+/*++ BUILD Version: 0003 // Increment this if a change has global effects
+
+Copyright (c) 1991-1993 Microsoft Corporation
+
+Module Name:
+
+ halp.h
+
+Abstract:
+
+ This header file defines the private Hardware Architecture Layer (HAL)
+ interfaces.
+
+Author:
+
+ David N. Cutler (davec) 25-Apr-1991
+
+
+Revision History:
+
+ L0001 1994.9.20 kbnes!kuriyama(A)
+ -Modify for R94A original halfxs\mips\halp.h
+ -add #include"r94axxx.h "
+ L0002 Thu Oct 13 18:09:33 JST 1994 kbnes!kuriyama(A)
+ - Del HalpDisplayLED
+ - Del HalpLEDDisplayLock
+ - Del HalpLEDControlBase
+ - Add READ_REGISTER_DWORD
+ ADD001 ataka@oa2.kb.nec.co.jp Mon Oct 17 20:31:21 JST 1994
+ - add data definitions for HalReportResourceUsage
+ CMP001 ataka@oa2.kb.nec.co.jp Tue Oct 18 15:15:11 JST 1994
+ - resolve compile error
+ ADD002 kisimoto@oa2.kb.nec.co.jp Fri Nov 25 15:46:03 1994
+ add HalpGetStatusRegister() definition
+ S0003 kuriyama@oa2.kb.nec.co.jp Fri Mar 31 16:51:00 JST 1995
+ add _IPI_LIMIT_ support
+ H0004 kisimoto@oa2.kb.nec.co.jp Sun Jun 25 14:39:38 1995
+ - Merge build 1057
+ H0005 kisimoto@oa2.kb.nec.co.jp Thu Jul 20 20:03:30 1995
+ - Merge code for ESM from J94C
+ H0006 kisimoto@oa2.kb.nec.co.jp Sat Aug 12 19:23:03 1995
+ - Removed _J94C_ definitions.
+ _J94C_ definition indicates that the status of
+ the dump switch can acknowledge from Self-test
+ register.
+ S0007 kuriyama@oa2.kb.nec.co.jp Wed Aug 23 20:18:18 JST 1995
+ - change for x86bios support
+ H0008 kisimoto@oa2.kb.nec.co.jp Wed Aug 30 12:23:36 1995
+ - add spinlock to support PCI Fast Back-to-back transfer.
+
+--*/
+
+#ifndef _HALP_
+#define _HALP_
+
+#if defined(NT_UP)
+
+#undef NT_UP
+
+#endif
+
+#include "nthal.h"
+#include "hal.h" // H0004
+
+#ifndef _HALI_ // H0004
+#include "..\inc\hali.h"
+#endif
+
+#if defined(_DUO_)
+
+#if defined(_R94A_)
+
+#include "r94adma.h"
+#include "r94adef.h"
+#include "r94aint.h"
+
+#else // _R94A_
+
+#include "duodma.h"
+#include "duodef.h"
+#include "duoint.h"
+
+#endif // _R94A_
+
+#endif
+
+#if defined(_JAZZ_)
+
+#include "jazzdma.h"
+#include "jazzdef.h"
+#include "jazzint.h"
+
+#endif
+
+#include "jxhalp.h"
+
+#if defined(USE_BIOS_EMULATOR) // H0004
+
+#include "xm86.h"
+#include "x86new.h"
+
+#endif
+
+
+//
+// Define function prototypes.
+//
+
+PADAPTER_OBJECT
+HalpAllocateAdapter(
+ IN ULONG MapRegistersPerChannel,
+ IN PVOID AdapterBaseVa,
+ IN PVOID MapRegisterBase
+ );
+
+ULONG
+HalpAllocateTbEntry (
+ VOID
+ );
+
+VOID
+HalpFreeTbEntry (
+ VOID
+ );
+
+VOID
+HalpCacheErrorRoutine (
+ VOID
+ );
+
+BOOLEAN
+HalpCalibrateStall (
+ VOID
+ );
+
+VOID
+HalpClockInterrupt0 (
+ VOID
+ );
+
+VOID
+HalpClockInterrupt1 (
+ VOID
+ );
+
+BOOLEAN
+HalpCreateDmaStructures (
+ VOID
+ );
+
+BOOLEAN
+HalpDmaDispatch(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+BOOLEAN
+HalpInitializeDisplay0 (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+BOOLEAN
+HalpInitializeDisplay1 (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+BOOLEAN
+HalpInitializeInterrupts (
+ VOID
+ );
+
+VOID
+HalpIpiInterrupt (
+ VOID
+ );
+
+BOOLEAN
+HalpMapFixedTbEntries (
+ VOID
+ );
+
+BOOLEAN
+HalpMapIoSpace (
+ VOID
+ );
+
+VOID
+HalpProfileInterrupt (
+ VOID
+ );
+
+#if defined(R4000)
+
+ULONG
+HalpReadCountRegister (
+ VOID
+ );
+
+ULONG
+HalpWriteCompareRegisterAndClear (
+ IN ULONG Value
+ );
+
+#endif
+
+VOID
+HalpStallInterrupt (
+ VOID
+ );
+
+// S0007
+// change prototype HalpInitializeX86DisplayAdapter()
+
+BOOLEAN
+HalpInitializeX86DisplayAdapter(
+ VOID
+ );
+
+VOID
+HalpResetX86DisplayAdapter(
+ VOID
+ );
+
+#if defined(_R94A_)
+VOID
+READ_REGISTER_DWORD(
+ PLARGE_INTEGER,
+ PVOID
+ );
+
+VOID
+WRITE_REGISTER_DWORD(
+ PLARGE_INTEGER,
+ PVOID
+ );
+
+VOID
+HalpGetStatusRegister (
+ IN PULONG Variable
+ );
+
+BOOLEAN
+HalNvramWrite(
+ ULONG Offset,
+ ULONG Count,
+ PVOID Buffer
+);
+
+BOOLEAN
+HalNvramRead(
+ ULONG Offset,
+ ULONG Count,
+ PVOID Buffer
+);
+
+BOOLEAN
+HalpNvramReadWrite(
+ ULONG Offset,
+ ULONG Count,
+ PVOID Buffer,
+ ULONG Write
+);
+#endif
+
+//
+// Define external references.
+//
+
+extern KSPIN_LOCK HalpBeepLock;
+extern USHORT HalpBuiltinInterruptEnable;
+extern ULONG HalpCurrentTimeIncrement;
+extern KSPIN_LOCK HalpDisplayAdapterLock;
+extern KAFFINITY HalpEisaBusAffinity;
+extern ULONG HalpNextIntervalCount;
+extern ULONG HalpNextTimeIncrement;
+extern ULONG HalpNewTimeIncrement;
+extern ULONG HalpProfileCountRate;
+extern ULONG HalpStallScaleFactor;
+extern KSPIN_LOCK HalpSystemInterruptLock;
+#if defined(_IPI_LIMIT_)
+extern KSPIN_LOCK HalpIpiRequestLock;
+#endif //_IPI_LIMIT_
+extern KSPIN_LOCK Ecc1bitDisableLock;// H005
+extern KSPIN_LOCK Ecc1bitRoutineLock;// H005
+extern KSPIN_LOCK HalpPCIBackToBackLock; // H008
+
+
+// ADD001
+//
+// Resource usage information
+//
+
+#if !defined (_R94A_)
+#pragma pack(1)
+#endif
+typedef struct {
+ UCHAR Flags;
+ KIRQL Irql;
+ UCHAR BusReleativeVector;
+} IDTUsage;
+
+typedef struct _HalAddressUsage{
+ struct _HalAddressUsage *Next;
+ CM_RESOURCE_TYPE Type; // Port or Memory
+ UCHAR Flags; // same as IDTUsage.Flags
+ struct {
+ ULONG Start;
+ USHORT Length;
+ } Element[];
+} ADDRESS_USAGE;
+#if !defined (_R94A_)
+#pragma pack()
+#endif
+
+#define IDTOwned 0x01 // IDT is not available for others
+#define InterruptLatched 0x02 // Level or Latched
+#define InternalUsage 0x11 // Report usage on internal bus
+#define DeviceUsage 0x21 // Report usage on device bus
+
+extern IDTUsage HalpIDTUsage[];
+extern ADDRESS_USAGE *HalpAddressUsageList;
+// CMP001
+extern ADDRESS_USAGE HalpDefaultPcIoSpace;
+extern ADDRESS_USAGE HalpEisaIoSpace;
+extern ADDRESS_USAGE HalpMapRegisterMemorySpace;
+
+#define HalpRegisterAddressUsage(a) \
+ (a)->Next = HalpAddressUsageList, HalpAddressUsageList = (a);
+
+// CMP001
+#define IRQ_PREFERRED 0x02
+#define IRQ_VALID 0x01
+
+// CMP001
+VOID
+HalpReportResourceUsage (
+ IN PUNICODE_STRING HalName,
+ IN INTERFACE_TYPE DeviceInterfaceToUse
+);
+
+//
+// H0004: from halx86/i386/halp.h
+// Temp definitions to thunk into supporting new bus extension format
+//
+
+VOID
+HalpRegisterInternalBusHandlers (
+ VOID
+ );
+
+PBUS_HANDLER
+HalpAllocateBusHandler (
+ IN INTERFACE_TYPE InterfaceType,
+ IN BUS_DATA_TYPE BusDataType,
+ IN ULONG BusNumber,
+ IN INTERFACE_TYPE ParentBusDataType,
+ IN ULONG ParentBusNumber,
+ IN ULONG BusSpecificData
+ );
+
+#define HalpHandlerForBus HaliHandlerForBus
+#define HalpSetBusHandlerParent(c,p) (c)->ParentHandler = p;
+
+#endif // _HALP_
diff --git a/private/ntos/nthals/halr96b/mips/j4cache.s b/private/ntos/nthals/halr96b/mips/j4cache.s
new file mode 100644
index 000000000..0f17e43bf
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/j4cache.s
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\j4cache.s"
diff --git a/private/ntos/nthals/halr96b/mips/j4flshbf.s b/private/ntos/nthals/halr96b/mips/j4flshbf.s
new file mode 100644
index 000000000..04012b70b
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/j4flshbf.s
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\j4flshbf.s"
diff --git a/private/ntos/nthals/halr96b/mips/j4flshio.c b/private/ntos/nthals/halr96b/mips/j4flshio.c
new file mode 100644
index 000000000..2461bc392
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/j4flshio.c
@@ -0,0 +1,236 @@
+// #pragma comment(exestr, "@(#) j4flshio.c 1.1 95/09/28 15:34:41 nec")
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ j4flshio.c
+
+Abstract:
+
+
+ This module implements the system dependent kernel function to flush
+ the data cache for I/O transfers on a MIPS R4000 Jazz, Fision, Fusion,
+ or Duo system.
+
+Author:
+
+ David N. Cutler (davec) 24-Apr-1991
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+Modification History for NEC R94A (MIPS R4400):
+
+ H000 Fri Sep 30 20:23:02 JST 1994 kbnes!kishimoto
+ - HalFlushIoBuffers()
+ Modify to return only.
+ R94A supports I/O coherency during I/O translation.
+ N.B. This modify is enabled after Beta-machine.
+ _R94ABBMIO_ means that machine is alpha-version.
+ H001 Sat Mar 18 15:19:33 1995 kbnes!kishimoto
+ - if operation is DMA, we have nothing to do.
+
+ M002 kuriyama@oa2.kb.nec.co.jp Sat Apr 01 10:51:41 JST 1995
+ - add support I/O cache limit _IO_LIMIT_
+--*/
+
+#include "halp.h"
+
+VOID
+HalFlushIoBuffers (
+ IN PMDL Mdl,
+ IN BOOLEAN ReadOperation,
+ IN BOOLEAN DmaOperation
+ )
+
+/*++
+
+Routine Description:
+
+ This function flushes the I/O buffer specified by the memory descriptor
+ list from the data cache on the current processor.
+
+Arguments:
+
+ Mdl - Supplies a pointer to a memory descriptor list that describes the
+ I/O buffer location.
+
+ ReadOperation - Supplies a boolean value that determines whether the I/O
+ operation is a read into memory.
+
+ DmaOperation - Supplies a boolean value that determines whether the I/O
+ operation is a DMA operation.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG CacheSegment;
+ ULONG Length;
+ ULONG Offset;
+ KIRQL OldIrql;
+ PULONG PageFrame;
+ ULONG Source;
+
+#if !defined(_IO_LIMIT_) && defined(_R94A_)
+
+ //
+ // H001
+ // R94A supports cache coherency during DMA operation,
+ // so we have nothing to to.
+ //
+
+ if (DmaOperation == TRUE){
+ return;
+ }
+
+#endif
+
+ //
+ // The Jazz R4000 uses a write back data cache and, therefore, must be
+ // flushed on reads and writes.
+ //
+ // If the length of the I/O operation is greater than the size of the
+ // data cache, then sweep the entire data cache. Otherwise, flush or
+ // purge individual pages from the data cache as appropriate.
+ //
+
+ Offset = Mdl->ByteOffset & PCR->DcacheAlignment;
+ Length = (Mdl->ByteCount +
+ PCR->DcacheAlignment + Offset) & ~PCR->DcacheAlignment;
+
+ if ((Length > PCR->FirstLevelDcacheSize) &&
+ (Length > PCR->SecondLevelDcacheSize)) {
+
+ //
+ // If the I/O operation is a DMA operation, or the I/O operation is
+ // not a DMA operation and the I/O operation is a page read operation,
+ // then sweep (index/writeback/invalidate) the entire data cache.
+ //
+
+ if ((DmaOperation != FALSE) ||
+ ((DmaOperation == FALSE) &&
+ (ReadOperation != FALSE) &&
+ ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0))) {
+ HalSweepDcache();
+ }
+
+ //
+ // If the I/O operation is a page read, then sweep (index/invalidate)
+ // the entire instruction cache.
+ //
+
+ if ((ReadOperation != FALSE) &&
+ ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0)) {
+ HalSweepIcache();
+ }
+
+ } else {
+
+ //
+ // Flush or purge the specified pages from the data cache and
+ // instruction caches as appropriate.
+ //
+ // Compute the number of pages to flush and the starting MDL page
+ // frame address.
+ //
+
+ Offset = Mdl->ByteOffset & ~PCR->DcacheAlignment;
+ PageFrame = (PULONG)(Mdl + 1);
+ Source = ((ULONG)(Mdl->StartVa) & 0xfffff000) | Offset;
+
+ //
+ // Flush or purge the specified page segments from the data and
+ // instruction caches as appropriate.
+ //
+
+ do {
+ if (Length >= (PAGE_SIZE - Offset)) {
+ CacheSegment = PAGE_SIZE - Offset;
+
+ } else {
+ CacheSegment = Length;
+ }
+
+ if (ReadOperation == FALSE) {
+
+ //
+ // The I/O operation is a write and the data only needs to
+ // to be copied back into memory if the operation is also
+ // a DMA operation.
+ //
+
+ if (DmaOperation != FALSE) {
+ HalFlushDcachePage((PVOID)Source, *PageFrame, CacheSegment);
+ }
+
+ } else {
+
+ //
+ // If the I/O operation is a DMA operation, then purge the
+ // data cache. Otherwise, is the I/O operation is a page read
+ // operation, then flush the data cache.
+ //
+
+ if (DmaOperation != FALSE) {
+ HalPurgeDcachePage((PVOID)Source, *PageFrame, CacheSegment);
+
+ } else if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0) {
+ HalFlushDcachePage((PVOID)Source, *PageFrame, CacheSegment);
+ }
+
+ //
+ // If the I/O operation is a page read, then the instruction
+ // cache must be purged.
+ //
+
+ if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0) {
+ HalPurgeIcachePage((PVOID)Source, *PageFrame, CacheSegment);
+ }
+ }
+
+ PageFrame += 1;
+ Length -= CacheSegment;
+ Offset = 0;
+ Source += CacheSegment;
+ } while(Length != 0);
+ }
+
+ return;
+}
+
+ULONG
+HalGetDmaAlignmentRequirement (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function returns the alignment requirements for DMA transfers on
+ host system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ The DMA alignment requirement is returned as the fucntion value.
+
+--*/
+
+{
+
+ return PCR->DcacheFillSize;
+}
diff --git a/private/ntos/nthals/halr96b/mips/j4prof.c b/private/ntos/nthals/halr96b/mips/j4prof.c
new file mode 100644
index 000000000..dd8c2b7c9
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/j4prof.c
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\j4prof.c"
diff --git a/private/ntos/nthals/halr96b/mips/jxbeep.c b/private/ntos/nthals/halr96b/mips/jxbeep.c
new file mode 100644
index 000000000..922c80816
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxbeep.c
@@ -0,0 +1,215 @@
+// #pragma comment(exestr, "@(#) jxbeep.c 1.1 95/09/28 15:35:24 nec")
+/*++
+
+Copyright (c) 1991-1993 Microsoft Corporation
+
+Module Name:
+
+ jxbeep.c
+
+Abstract:
+
+ This module implements the HAL speaker "beep" routines for a MIPS
+ system.
+
+Author:
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ M0001 1994.9.12 kbnes!kuriyama
+ Modify for R94A MIPS R4400
+
+ - HalMakeBeep()
+ At R94A system, Buzzer controled by TYPHOON, not by EISA-Bridge.
+ Buzzer ON/OFF, Freequency Control Register was changed.
+
+ S0002 1994.12.22 kbnes!kuriyama
+ cast miss ? fixed
+
+--*/
+
+#include "halp.h"
+#include "eisa.h"
+
+BOOLEAN
+HalMakeBeep(
+ IN ULONG Frequency
+ )
+
+/*++
+
+Routine Description:
+
+ This function sets the frequency of the speaker, causing it to sound a
+ tone. The tone will sound until the speaker is explicitly turned off,
+ so the driver is responsible for controlling the duration of the tone.
+
+Arguments:
+
+ Frequency - Supplies the frequency of the desired tone. A frequency of
+ 0 means the speaker should be shut off.
+
+Return Value:
+
+ TRUE - Operation was successful (frequency within range or zero).
+ FALSE - Operation was unsuccessful (frequency was out of range).
+ Current tone (if any) is unchanged.
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+
+/* start M0001 */
+#if defined(_R94A_)
+ BUZZER_CONTROL BuzzerControl;
+#else // _R94A_
+ NMI_STATUS NmiStatus;
+#endif // _R94A_
+/* end M0001 */
+
+ PEISA_CONTROL controlBase = HalpEisaControlBase;
+ TIMER_CONTROL timerControl;
+ ULONG newCount;
+ BOOLEAN Result;
+
+ //
+ // Raise IRQL to dispatch level and acquire the beep spin lock.
+ //
+
+ KeAcquireSpinLock(&HalpBeepLock, &OldIrql);
+
+ //
+ // Stop the speaker.
+ //
+
+/* start M0001 */
+#if defined(_R94A_)
+
+ *((PUCHAR)&BuzzerControl) = READ_REGISTER_UCHAR(&DMA_CONTROL->BuzzerControl.Char);
+//S0002
+ BuzzerControl.SpeakerGate = 0;
+ BuzzerControl.SpeakerData = 0;
+ WRITE_REGISTER_UCHAR(&DMA_CONTROL->BuzzerControl.Char,*((PUCHAR) &BuzzerControl));
+// S0002
+#else // _R94A_
+
+ *((PUCHAR)&NmiStatus) = READ_REGISTER_UCHAR(&controlBase->NmiStatus);
+ NmiStatus.SpeakerGate = 0;
+ NmiStatus.SpeakerData = 0;
+ WRITE_REGISTER_UCHAR(&controlBase->NmiStatus, *((PUCHAR)&NmiStatus));
+
+#endif // _R94A_
+/* end M0001 */
+
+ //
+ // If the specified frequency is zero, then the speaker is to be stopped.
+ //
+
+ if (Frequency == 0) {
+ Result = TRUE;
+
+ } else {
+
+ //
+ // If the new count has a magnitude less than 65,536 (0x10000), then
+ // set the speaker time to the correct mode. Otherwise, return a value
+ // of FALSE sinc ethe frequency is out of range.
+ //
+
+ newCount = TIMER_CLOCK_IN / Frequency;
+ if (newCount >= 0x10000) {
+ Result = FALSE;
+
+ } else {
+
+/* start M0001 */
+#if defined(_R94A_)
+ //
+ // R94A Support only even value for newCount
+ //
+
+ newCount &= 0xfffe;
+
+ if (newCount == 0) {
+ newCount = 2;
+ }
+
+#else // _R94A_
+
+ //
+ // Set the speaker timer to the correct mode.
+ //
+
+ timerControl.BcdMode = 0;
+ timerControl.Mode = TM_SQUARE_WAVE;
+ timerControl.SelectByte = SB_LSB_THEN_MSB;
+ timerControl.SelectCounter = SELECT_COUNTER_2;
+ WRITE_REGISTER_UCHAR(&controlBase->CommandMode1, *((PUCHAR) &timerControl));
+
+#endif // _R94A_
+/* end M0001 */
+
+ //
+ // Set the speaker timer to the correct mode.
+ //
+
+/* start M0001 */
+#if defined(_R94A_)
+
+ WRITE_REGISTER_USHORT(&DMA_CONTROL->BuzzerCount.Short,(USHORT) newCount);
+// S0002
+
+#else // _R94A_
+
+ WRITE_REGISTER_UCHAR(&controlBase->SpeakerTone, (UCHAR)(newCount & 0xff));
+ WRITE_REGISTER_UCHAR(&controlBase->SpeakerTone, (UCHAR)(newCount >> 8));
+
+#endif // _R94A_
+/* end M0001 */
+
+ //
+ // Start the speaker.
+ //
+
+/* start M0001 */
+#if defined(_R94A_)
+
+ *((PUCHAR)&BuzzerControl) = READ_REGISTER_UCHAR(
+ &DMA_CONTROL->BuzzerControl.Char //S0002
+ );
+ BuzzerControl.SpeakerGate = 1;
+ BuzzerControl.SpeakerData = 1;
+ WRITE_REGISTER_UCHAR(
+ &DMA_CONTROL->BuzzerControl.Char,//S0002
+ *((PUCHAR) &BuzzerControl)
+ );
+ Result = TRUE;
+
+#else // _R94A_
+
+ NmiStatus.SpeakerGate = 1;
+ NmiStatus.SpeakerData = 1;
+ WRITE_REGISTER_UCHAR(&controlBase->NmiStatus, *((PUCHAR) &NmiStatus));
+ Result = TRUE;
+
+#endif // _R94A_
+/* end M0001 */
+
+ }
+ }
+
+ //
+ // Release the beep spin lock and lower IRQL to its previous value.
+ //
+
+ KeReleaseSpinLock(&HalpBeepLock, OldIrql);
+ return Result;
+}
+
diff --git a/private/ntos/nthals/halr96b/mips/jxdisp.c b/private/ntos/nthals/halr96b/mips/jxdisp.c
new file mode 100644
index 000000000..f30afc401
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxdisp.c
@@ -0,0 +1,3605 @@
+/* #pragma comment(exestr, "@(#) NEC(MIPS) jxdisp.c 1.2 95/10/17 01:18:22" ) */
+/*++
+
+Copyright (c) 1995 NEC Corporation
+Copyright (c) 1991-1993 Microsoft Corporation
+
+Module Name:
+
+ jxdisp.c
+
+Abstract:
+
+ This module implements the HAL display initialization and output routines
+ for a R4400 R94A system.
+
+History:
+
+
+--*/
+
+/*
+ * New Code for 3.51
+ *
+ * M001 kuriyama@oa2.kb.nec.co.jp Fri Jul 14 11:46:06 JST 1995
+ * -change textmode 80x50
+ *
+ * M002 kuriyama@oa2.kb.nec.co.jp Tue Jul 18 15:36:23 JST 1995
+ * -change for fw interface
+ *
+ * M003 kuriyama@oa2.kb.nec.co.jp Fri Jul 21 14:14:54 JST 1995
+ * -add call HalpResetDisplayParameters
+ * for bug fix DPI board panic message
+ *
+ * M004 kuriyama@oa2.kb.nec.co.jp Wed Aug 2 14:28:28 JST 1995
+ * -add ESM critical error logging
+ *
+ * S005 kuriyama@oa2.kb.nec.co.jp Wed Aug 23 23:42:59 JST 1995
+ * -change for scroll bug fix
+ *
+ * S006 nishi@oa2.kb.nec.co.jp Mon Sep 4 18:42:00 JST 1995
+ * -change for GLINT new revision board
+ * R01=00,R02=02
+ * M007 nishi@oa2.kb.nec.co.jp Mon Sep 18 18:42:00 JST 1995
+ * - Add Software Power Off, when system panic is occured
+ *
+ * M008 nishi@oa2.kb.nec.co.jp Mon Sep 18 18:42:00 JST 1995
+ * - Change Logic for resume fixed TLB for DMA
+ *
+ * M009 kuriyama@oa2.kbnes.nec.co.jp Mon Sep 18 19:58:22 JST 1995
+ * - bug fix for tga 800x600 72Hz
+ *
+ * M010 v-akitk@microsoft.com
+ * - Change for Software Power Supply(R96B)
+ *
+ */
+
+
+#include "halp.h"
+#include "jazzvdeo.h"
+#include "jzvxl484.h"
+#include <jaginit.h>
+#include "cirrus.h"
+#include "modeset.h"
+#include "mode542x.h"
+#include <tga.h>
+#include <glint.h>
+#include <rgb525.h>
+
+#include "string.h"
+#include "pci.h"
+/* START M007 */
+#define HEADER_FILE
+#include "kxmips.h"
+/* START M007 */
+//
+// Put all code for HAL initialization in the INIT section. It will be
+// deallocated by memory management when phase 1 initialization is
+// completed.
+//
+
+#if defined(ALLOC_PRAGMA)
+
+#pragma alloc_text(INIT, HalpInitializeDisplay0)
+#pragma alloc_text(INIT, HalpInitializeDisplay1)
+
+#endif
+
+//
+// for x86bios emulate
+//
+PCHAR K351UseBios=NULL;
+VOID HalpCopyROMs(VOID);
+
+PHAL_RESET_DISPLAY_PARAMETERS HalpResetDisplayParameters; // M003
+
+typedef
+VOID
+(*PHALP_CONTROLLER_SETUP) (
+ VOID
+ );
+
+typedef
+VOID
+(*PHALP_DISPLAY_CHARACTER) (
+ UCHAR
+ );
+typedef
+VOID
+(*PHALP_SCROLL_SCREEN) (
+ UCHAR
+ );
+
+#define TAB_SIZE 4
+#define TEXT_ATTR 0x1F
+
+//
+// Define forward referenced procedure prototypes.
+//
+VOID
+HalpDisplayINT10Setup (
+VOID);
+
+VOID HalpOutputCharacterINT10 (
+ IN UCHAR Character );
+
+VOID HalpScrollINT10 (
+ IN UCHAR line
+ );
+
+VOID HalpDisplayCharacterVGA (
+ IN UCHAR Character );
+
+BOOLEAN
+HalpInitializeX86DisplayAdapter(
+ VOID
+ );
+
+
+PHALP_DISPLAY_CHARACTER HalpDisplayCharacter = NULL;
+
+//
+// Define forward referenced procedure prototypes.
+//
+
+VOID
+HalpDisplayCharacterOld (
+ IN UCHAR Character
+ );
+
+VOID
+HalpOutputCharacterOld(
+ IN PUCHAR Glyph
+ );
+
+VOID
+HalpDisplayCirrusSetup (
+ VOID
+ );
+
+BOOLEAN
+HalpCirrusInterpretCmdStream (
+ PUSHORT pusCmdStream
+ );
+
+VOID
+HalpDisplayTgaSetup (
+ VOID
+ );
+
+/*
+VOID
+RGB525_WRITE(
+ ULONG dac,
+ ULONG offset,
+ UCHAR data);
+
+VOID
+RGB525_SET_REG(
+ ULONG dac,
+ ULONG index,
+ UCHAR data);
+*/
+
+VOID
+HalpDisplayGlintSetup(
+ VOID
+ );
+
+VOID
+Write_Dbg_Uchar(
+PUCHAR,
+UCHAR
+);
+
+//
+// Must use 32Bit transfer. RtlMoveMemory() uses 64Bit transfer.
+//
+
+VOID
+HalpMoveMemory32 (
+ PUCHAR Destination,
+ PUCHAR Source,
+ ULONG Length
+);
+/* Start M007 */
+VOID
+HalpMrcModeChange(
+ UCHAR Mode
+);
+/*End M007 */
+
+//
+// Define virtual address of the video memory and control registers.
+//
+
+#define VIDEO_MEMORY_BASE 0x40000000
+
+//
+// Define memory access constants for VXL
+//
+
+#define CIRRUS_BASE ((PJAGUAR_REGISTERS)0x403ff000)
+#define CIRRUS_OFFSET ((PUSHORT)0x3b0)
+
+#define TGA_REGISTER_BASE ((ULONG)0x403ff000)
+#define R94A_PCI_ADDR_REG ((PULONG)(0x80000518 | 0xffffc000))
+#define R94A_PCI_DATA_REG ((PULONG)(0x80000520 | 0xffffc000))
+
+#define GLINT_CONTROL_REGISTER_BASE ((ULONG)0x403ff000) // M021
+#define GLINT_VIDEO_REGISTER_BASE ((ULONG)0x403fe000)
+#define RGB525_REGISTER_BASE ((ULONG)0x403fd000)
+
+//
+// Define controller setup routine type.
+//
+
+typedef
+VOID
+(*PHALP_CONTROLLER_SETUP) (
+ VOID
+ );
+
+//
+// Define OEM font variables.
+//
+
+ULONG HalpBytesPerRow;
+ULONG HalpCharacterHeight;
+ULONG HalpCharacterWidth;
+ULONG HalpColumn;
+ULONG HalpDisplayText;
+ULONG HalpDisplayWidth;
+POEM_FONT_FILE_HEADER HalpFontHeader;
+ULONG HalpRow;
+ULONG HalpScrollLength;
+ULONG HalpScrollLine;
+
+ULONG HalpGlintRevisionId; // S006
+
+//
+// Define display variables.
+//
+
+BOOLEAN HalpDisplayOwnedByHal;
+ENTRYLO HalpDisplayPte;
+ULONG HalpDisplayControlBase = 0;
+ULONG HalpDisplayMemoryBase = 0; // M021
+ULONG HalpDisplayResetRegisterBase = 0;
+ULONG HalpDisplayVxlClockRegisterBase = 0;
+ULONG HalpDisplayVxlBt484RegisterBase = 0;
+ULONG HalpDisplayVxlJaguarRegisterBase = 0;
+PHALP_CONTROLLER_SETUP HalpDisplayControllerSetup = NULL;
+MONITOR_CONFIGURATION_DATA HalpMonitorConfigurationData;
+BOOLEAN HalpDisplayTypeUnknown = FALSE;
+ULONG HalpG364Type = 0;
+
+LARGE_INTEGER HalpCirrusPhigicalVideo = {0,0};
+
+LARGE_INTEGER HalpTgaPhigicalVideo = {0,0};
+LARGE_INTEGER HalpTgaPhigicalVideoCont = {0,0};
+
+LARGE_INTEGER HalpGlintPhygicalVideo = {0,0};
+LARGE_INTEGER HalpGlintPhygicalVideoCont = {0,0};
+ULONG HalpDisplayPCIDevice = FALSE;
+ULONG HalpDisplayType16BPP = FALSE;
+
+PVOID HalpMrcControlBase = NULL; // M007
+BOOLEAN HalpMrcControlMapped = FALSE; // M007
+
+typedef struct _R94A_PCI_CONFIGURATION_ADDRESS_REG{
+ ULONG Reserved2: 2;
+ ULONG RegisterNumber: 6;
+ ULONG FunctionNumber: 3;
+ ULONG DeviceNumber: 5;
+ ULONG BusNumber: 8;
+ ULONG Reserved1: 7;
+ ULONG ConfigEnable: 1;
+} R94A_PCI_CONFIGURATION_ADDRESS_REG, *PR94A_PCI_CONFIGURATION_ADDRESS_REG;
+
+VOID
+HalpReadPCIConfigUlongByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PULONG Buffer,
+ IN ULONG Offset
+ );
+
+BOOLEAN
+HalpCheckPCIDevice (
+ IN PCI_SLOT_NUMBER Slot
+ );
+
+BOOLEAN
+HalpInitializeDisplay0 (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the video memory and control registers into the user
+ part of the idle process address space, initializes the video control
+ registers, and clears the video screen.
+
+Arguments:
+
+ LoaderBlock - Supplies a pointer to the loader parameter block.
+
+Return Value:
+
+ If the initialization is successfully completed, than a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ PCONFIGURATION_COMPONENT_DATA Child;
+ PCONFIGURATION_COMPONENT_DATA ConfigurationEntry;
+ POEM_FONT_FILE_HEADER FontHeader;
+ ULONG Index;
+ ULONG MatchKey;
+ PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
+ PLIST_ENTRY NextEntry;
+ PENTRYLO PageFrame;
+ ENTRYLO Pte;
+ ULONG StartingPfn;
+ PCI_SLOT_NUMBER Slot;
+ ULONG ReadValue;
+ PCHAR Options;
+
+ //
+ // Set the address of the font file header and compute display variables.
+ //
+ // N.B. The font information suppled by the OS Loader is used during phase
+ // 0 initialization. During phase 1 initialization, a pool buffer is
+ // allocated and the font information is copied from the OS Loader
+ // heap into pool.
+ //
+
+ FontHeader = (POEM_FONT_FILE_HEADER)LoaderBlock->OemFontFile;
+ HalpFontHeader = FontHeader;
+ HalpBytesPerRow = (FontHeader->PixelWidth + 7) / 8;
+ HalpCharacterHeight = FontHeader->PixelHeight;
+ HalpCharacterWidth = FontHeader->PixelWidth;
+
+#if defined(_X86_DBG_)
+ DbgPrint("\n DISP 0\n"); //DBGDBG
+#endif // _X86_DBG_
+
+ //
+ // Find the configuration entry for the first display controller.
+ //
+
+ MatchKey = 0;
+ ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
+ ControllerClass,
+ DisplayController,
+ &MatchKey);
+ if (ConfigurationEntry == NULL) {
+ MatchKey = 1;
+ ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
+ ControllerClass,
+ DisplayController,
+ &MatchKey);
+ if (ConfigurationEntry == NULL) {
+ return FALSE;
+ }
+ }
+
+
+ //
+ // Determine which video controller is present in the system.
+ // Copy the display controller and monitor parameters in case they are
+ // needed later to reinitialize the display to output a message.
+ //
+
+ if (LoaderBlock->LoadOptions != NULL) {
+ Options = LoaderBlock->LoadOptions;
+ _strupr(Options);
+ K351UseBios = strstr(Options, "USEBIOS");
+ }
+ if(K351UseBios!=NULL){
+ DbgPrint("\nUSEBIOS---\n");
+ HalpDisplayControllerSetup = HalpDisplayINT10Setup;
+ HalpDisplayCharacter = HalpDisplayCharacterVGA;
+ HalpDisplayControlBase = 0x90000000;
+
+ }else if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
+ "necvdfrb")) {
+
+ HalpDisplayControllerSetup = HalpDisplayCirrusSetup;
+ HalpDisplayCharacter = HalpDisplayCharacterOld;
+ HalpDisplayControlBase = 0x90000000;
+
+ } else if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,"10110004")) {
+ //
+ // for DEC21030 PCI
+ //
+
+ HalpDisplayControllerSetup = HalpDisplayTgaSetup;
+ HalpDisplayCharacter = HalpDisplayCharacterOld;
+ HalpDisplayPCIDevice = TRUE;
+
+ Slot.u.bits.FunctionNumber = 0;
+
+ for (Slot.u.bits.DeviceNumber = 3; Slot.u.bits.DeviceNumber < 6; Slot.u.bits.DeviceNumber++){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+ if (ReadValue == 0x00041011){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
+
+ if ((ReadValue & 0x00000002) == 0x2){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ HalpDisplayControlBase =
+ (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
+
+ } else {
+ return FALSE;
+
+ }
+ }
+ }
+
+ } else if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,"3D3D0001")) {
+
+ //
+ // for GLINT 300SX PCI
+ //
+
+ HalpDisplayControllerSetup = HalpDisplayGlintSetup;
+ HalpDisplayCharacter = HalpDisplayCharacterOld;
+ HalpDisplayPCIDevice = TRUE;
+ HalpDisplayType16BPP = TRUE;
+
+ //
+ // FunctionNumber always zero
+ //
+
+ Slot.u.bits.FunctionNumber = 0;
+
+ for (Slot.u.bits.DeviceNumber = 3; Slot.u.bits.DeviceNumber < 6; Slot.u.bits.DeviceNumber++){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+ if (ReadValue == 0x00013d3d){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
+
+ //
+ // GLINT 300SX has no I/O space regions
+ //
+
+ if (ReadValue & 0x2){
+
+ //
+ // Control Registers
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ HalpDisplayControlBase = (ReadValue & 0xfffffff0);
+
+ //
+ // Framebuffer
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
+ HalpDisplayMemoryBase = (ReadValue & 0xfffffff0);
+
+ //
+ // Revision ID
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x08); // S006
+ HalpGlintRevisionId = (ReadValue & 0x000000ff);
+
+ } else {
+ return FALSE;
+
+ }
+ }
+ }
+ } else {
+ // M002 +++
+ HalpDisplayControllerSetup = HalpDisplayINT10Setup;
+ HalpDisplayCharacter = HalpDisplayCharacterVGA;
+ HalpDisplayControlBase = 0x90000000;
+ HalpDisplayTypeUnknown = TRUE;
+ // M002 ---
+ }
+
+ Child = ConfigurationEntry->Child;
+
+ RtlMoveMemory((PVOID)&HalpMonitorConfigurationData,
+ Child->ConfigurationData,
+ Child->ComponentEntry.ConfigurationDataLength);
+
+ //
+ // Compute character output display parameters.
+ //
+
+ HalpDisplayText =
+ HalpMonitorConfigurationData.VerticalResolution / HalpCharacterHeight;
+
+ if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
+ HalpScrollLine =
+ 1024 * HalpCharacterHeight;
+ } else if (HalpDisplayType16BPP) {
+
+ HalpScrollLine =
+ HalpMonitorConfigurationData.HorizontalResolution * HalpCharacterHeight * sizeof(USHORT);
+
+ } else {
+ HalpScrollLine =
+ HalpMonitorConfigurationData.HorizontalResolution * HalpCharacterHeight;
+ }
+
+ HalpScrollLength = HalpScrollLine * (HalpDisplayText - 1);
+
+ if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
+ HalpDisplayWidth =
+ 1024 / HalpCharacterWidth;
+
+ }else{
+
+ HalpDisplayWidth =
+ HalpMonitorConfigurationData.HorizontalResolution / HalpCharacterWidth;
+ }
+
+ //
+ // Scan the memory allocation descriptors and allocate a free page
+ // to map the video memory and control registers, and initialize the
+ // PDE entry.
+ //
+
+ NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
+ while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) {
+ MemoryDescriptor = CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ if ((MemoryDescriptor->MemoryType == LoaderFree) &&
+ (MemoryDescriptor->PageCount > 1)) {
+ StartingPfn = MemoryDescriptor->BasePage;
+ MemoryDescriptor->BasePage += 1;
+ MemoryDescriptor->PageCount -= 1;
+ break;
+ }
+
+ NextEntry = NextEntry->Flink;
+ }
+
+ ASSERT(NextEntry != &LoaderBlock->MemoryDescriptorListHead);
+
+ Pte.X1 = 0;
+ Pte.PFN = StartingPfn;
+ Pte.G = 0;
+ Pte.V = 1;
+ Pte.D = 1;
+
+#if defined(R3000)
+
+ Pte.N = 1;
+
+#endif
+
+#if defined(R4000)
+
+ Pte.C = UNCACHED_POLICY;
+
+#endif
+
+ //
+ // Save the page table page PTE for use in displaying information and
+ // map the appropriate PTE in the current page directory page to address
+ // the display controller page table page.
+ //
+
+ HalpDisplayPte = Pte;
+ *((PENTRYLO)(PDE_BASE |
+ ((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc))) = Pte;
+
+ //
+ // Initialize the page table page.
+ //
+
+ PageFrame = (PENTRYLO)(PTE_BASE |
+ (VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
+
+ if (HalpDisplayControllerSetup == HalpDisplayINT10Setup) {
+
+ HalpCirrusPhigicalVideo.HighPart = 1;
+ HalpCirrusPhigicalVideo.LowPart = 0;
+
+ Pte.PFN = (HalpCirrusPhigicalVideo.HighPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpCirrusPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+ }else if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup) {
+ HalpCirrusPhigicalVideo.HighPart = 1;
+ HalpCirrusPhigicalVideo.LowPart = MEM_VGA;
+ Pte.PFN = (HalpCirrusPhigicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpCirrusPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+ } else if (HalpDisplayControllerSetup == HalpDisplayTgaSetup) {
+ HalpTgaPhigicalVideo.HighPart = 1;
+ HalpTgaPhigicalVideo.LowPart = HalpDisplayControlBase - TGA_REG_SPC_OFFSET + TGA_DSP_BUF_OFFSET;
+ Pte.PFN = (HalpTgaPhigicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpTgaPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) { // M021
+ HalpGlintPhygicalVideo.HighPart = 1;
+ HalpGlintPhygicalVideo.LowPart = HalpDisplayMemoryBase;
+ Pte.PFN = (HalpGlintPhygicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideo.HighPart << (32 - PAGE_SHIFT);
+ }
+
+ Pte.G = 0;
+ Pte.V = 1;
+ Pte.D = 1;
+
+#if defined(R3000)
+
+ Pte.N = 1;
+
+#endif
+
+#if defined(R4000)
+
+ Pte.C = UNCACHED_POLICY;
+
+#endif
+
+ //
+ // Page table entries of the video memory.
+ //
+
+ for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
+ *PageFrame++ = Pte;
+ Pte.PFN += 1;
+ }
+
+ if (HalpDisplayControllerSetup == HalpDisplayTgaSetup) {
+ HalpTgaPhigicalVideoCont.HighPart = 1;
+ HalpTgaPhigicalVideoCont.LowPart = HalpDisplayControlBase;
+ Pte.PFN = (HalpTgaPhigicalVideoCont.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpTgaPhigicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+ *PageFrame = Pte;
+
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) {
+
+ HalpGlintPhygicalVideoCont.HighPart = 1;
+ HalpGlintPhygicalVideoCont.LowPart = HalpDisplayControlBase;
+
+ //
+ // IBM RGB525
+ //
+
+ Pte.PFN = ((HalpGlintPhygicalVideoCont.LowPart + 0x4000) >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+ *(PageFrame - 2) = Pte;
+
+ //
+ // GLINT 300SX Internal Video Registers
+ //
+
+ Pte.PFN = ((HalpGlintPhygicalVideoCont.LowPart + 0x3000) >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+ *(PageFrame - 1) = Pte;
+
+ //
+ // GLINT 300SX Control Status Registers
+ //
+
+ Pte.PFN = (HalpGlintPhygicalVideoCont.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+ *PageFrame = Pte;
+
+ } else if (HalpDisplayControllerSetup == HalpDisplayINT10Setup){
+
+#if defined(_X86_DBG_)
+ DbgPrint("Map x86 and cirrus control register\n");
+#endif // _X86_DBG_
+
+ Pte.PFN = ((ULONG)HalpDisplayControlBase + 0xffff) >> PAGE_SHIFT;
+
+ for (Index = 0; Index < (0x10000 / PAGE_SIZE ); Index++) {
+ *PageFrame-- = Pte;
+#if defined(_X86_DBG_)
+ DbgPrint("Map index %x pfn %x\n",Index,Pte.PFN);
+#endif // _X86_DBG_
+ Pte.PFN -= 1;
+ }
+
+ } else {
+
+ //
+ // If we have a 'NEC-cirrus GD5428'
+ // use the page before last to map the reset register.
+ //
+
+ //
+ // Page table for the video registers.
+ //
+
+ Pte.PFN = ((ULONG)HalpDisplayControlBase) >> PAGE_SHIFT;
+ *PageFrame = Pte;
+ }
+
+ //
+ // M004
+ // ESM critical error logging setup.
+ //
+
+ HalpInitDisplayStringIntoNvram();
+
+ //
+ // Initialize the display controller.
+ //
+
+#if defined(_X86_DBG_)
+ DbgPrint("\n x86adp init GOOO\n"); //DBGDBG
+#endif // _X86_DBG
+
+ if(HalpDisplayControllerSetup == HalpDisplayINT10Setup){
+ if (HalpInitializeX86DisplayAdapter()) {
+#if defined(_X86_DBG_)
+ DbgPrint("\n x86adp init OK\n"); //DBGDBG
+#endif // _X86_DBG
+// HalpDisplayControllerSetup(); // initialize twice bugbug
+
+ }else{
+
+ return FALSE;
+ }
+ }
+
+ HalpDisplayControllerSetup();
+
+ return TRUE;
+}
+
+BOOLEAN
+HalpInitializeDisplay1 (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+
+/*++
+
+Routine Description:
+
+ This routine allocates pool for the OEM font file and copies the font
+ information from the OS Loader heap into the allocated pool.
+
+Arguments:
+
+ LoaderBlock - Supplies a pointer to the loader parameter block.
+
+Return Value:
+
+ If the initialization is successfully completed, than a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ PVOID FontHeader;
+
+ //
+ // Allocate a pool block and copy the OEM font information from the
+ // OS Loader heap into the pool block.
+ //
+
+ FontHeader = ExAllocatePool(NonPagedPool, HalpFontHeader->FileSize);
+ if (FontHeader == NULL) {
+ return FALSE;
+ }
+
+ RtlMoveMemory(FontHeader, HalpFontHeader, HalpFontHeader->FileSize);
+ HalpFontHeader = (POEM_FONT_FILE_HEADER)FontHeader;
+ return TRUE;
+}
+
+VOID
+HalAcquireDisplayOwnership (
+ IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters
+ )
+
+/*++
+
+Routine Description:
+
+ This routine switches ownership of the display away from the HAL to
+ the system display driver. It is called when the system has reached
+ a point during bootstrap where it is self supporting and can output
+ its own messages. Once ownership has passed to the system display
+ driver any attempts to output messages using HalDisplayString must
+ result in ownership of the display reverting to the HAL and the
+ display hardware reinitialized for use by the HAL.
+
+Arguments:
+
+ ResetDisplayParameters - if non-NULL the address of a function
+ the hal can call to reset the video card. The function returns
+ TRUE if the display was reset.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Set HAL ownership of the display to false.
+ //
+
+ HalpResetDisplayParameters=ResetDisplayParameters;// M003
+ HalpDisplayOwnedByHal = FALSE;
+
+ //
+ // M010
+ // Set for Software Power supply control
+ //
+
+#if defined (_MRCPOWER_)
+ HalpMrcModeChange((UCHAR)0x1); // M007
+#endif // _MRCPOWER_
+
+ //
+ // M006
+ // ESM critical logging success set success startup.
+ //
+
+ HalpSuccessOsStartUp();
+
+ return;
+}
+
+VOID
+HalpDisplayCirrusSetup(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This routine initializes the Cirrus VGA display controlleer.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None
+
+--*/
+
+{
+ PULONG Buffer;
+ LONG Limit;
+ LONG Index;
+ ULONG dac_address, dac_reg;
+
+ ULONG verticalFrequency;
+ ULONG horizontalTotal;
+ ULONG verticalTotal;
+
+ //
+ // Calculate vertical frequency.
+ //
+
+ horizontalTotal = ( HalpMonitorConfigurationData.HorizontalDisplayTime
+ +HalpMonitorConfigurationData.HorizontalBackPorch
+ +HalpMonitorConfigurationData.HorizontalFrontPorch
+ +HalpMonitorConfigurationData.HorizontalSync );
+
+ verticalTotal = ( HalpMonitorConfigurationData.VerticalResolution
+ +HalpMonitorConfigurationData.VerticalBackPorch
+ +HalpMonitorConfigurationData.VerticalFrontPorch
+ +HalpMonitorConfigurationData.VerticalSync );
+
+ verticalFrequency = 1000000000 / ( horizontalTotal * verticalTotal);
+
+ switch (HalpMonitorConfigurationData.HorizontalResolution) {
+ case 640:
+ if( verticalFrequency < 66 ) {
+ HalpCirrusInterpretCmdStream(CL542x_640x480_256_60);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else {
+ HalpCirrusInterpretCmdStream(CL542x_640x480_256_72);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ }
+ break;
+
+ case 800:
+ if( verticalFrequency < 58 ) {
+ HalpCirrusInterpretCmdStream(CL542x_800x600_256_56);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else if( verticalFrequency < 66 ) {
+ HalpCirrusInterpretCmdStream(CL542x_800x600_256_60);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else {
+ HalpCirrusInterpretCmdStream(CL542x_800x600_256_72);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ }
+ break;
+
+ case 1024:
+
+ if( verticalFrequency < 47 ) {
+ HalpCirrusInterpretCmdStream(CL542x_1024x768_256_87);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else if ( verticalFrequency < 65) {
+ HalpCirrusInterpretCmdStream(CL542x_1024x768_256_60);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else {
+ HalpCirrusInterpretCmdStream(CL542x_1024x768_256_70);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ }
+ break;
+ default:
+ HalpCirrusInterpretCmdStream(CL542x_640x480_256_60);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ return;
+ }
+
+ //
+ // Initialize color pallete.
+ //
+
+ dac_address = (ULONG)CIRRUS_BASE + 0x3b0 + DAC_ADDRESS_WRITE_PORT;
+ dac_reg = (ULONG)CIRRUS_BASE + 0x3b0 + DAC_DATA_REG_PORT;
+
+ Write_Dbg_Uchar((PUCHAR)dac_address, (UCHAR)0x0);
+
+ Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x3f);
+ Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x3f);
+ Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x3f);
+
+ Write_Dbg_Uchar((PUCHAR)dac_address, (UCHAR)0x1);
+ Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x00);
+ Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x00);
+ Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)(0x90 >> 2));
+
+ //
+ // Set the video memory to address color one.
+ //
+ Buffer = (PULONG)VIDEO_MEMORY_BASE;
+ Limit = (1024 *
+ HalpMonitorConfigurationData.VerticalResolution) / sizeof(ULONG);
+
+ for (Index = 0; Index < Limit; Index += 1) {
+ *Buffer++ = 0x01010101;
+ }
+
+ //
+ // Initialize the current display column, row, and ownership values.
+ //
+
+ HalpColumn = 0;
+ HalpRow = 0;
+ HalpDisplayOwnedByHal = TRUE;
+ return;
+}
+
+BOOLEAN
+HalpCirrusInterpretCmdStream(
+ PUSHORT pusCmdStream
+ )
+
+/*++
+
+Routine Description:
+
+ Interprets the appropriate command array to set up VGA registers for the
+ requested mode. Typically used to set the VGA into a particular mode by
+ programming all of the registers
+
+Arguments:
+
+
+ pusCmdStream - array of commands to be interpreted.
+
+Return Value:
+
+ The status of the operation (can only fail on a bad command); TRUE for
+ success, FALSE for failure.
+
+Revision History:
+--*/
+
+
+
+{
+ ULONG ulCmd;
+ ULONG ulPort;
+ UCHAR jValue;
+ USHORT usValue;
+ ULONG culCount;
+ ULONG ulIndex;
+ ULONG ulBase;
+ if (pusCmdStream == NULL) {
+
+ return TRUE;
+ }
+
+ ulBase = (ULONG)CIRRUS_BASE+0x3b0;
+
+ //
+ // Now set the adapter to the desired mode.
+ //
+
+ while ((ulCmd = *pusCmdStream++) != EOD) {
+
+ //
+ // Determine major command type
+ //
+
+ switch (ulCmd & 0xF0) {
+
+ //
+ // Basic input/output command
+ //
+
+ case INOUT:
+
+ //
+ // Determine type of inout instruction
+ //
+
+ if (!(ulCmd & IO)) {
+
+ //
+ // Out instruction. Single or multiple outs?
+ //
+
+ if (!(ulCmd & MULTI)) {
+
+ //
+ // Single out. Byte or word out?
+ //
+
+ if (!(ulCmd & BW)) {
+
+ //
+ // Single byte out
+ //
+
+ ulPort = *pusCmdStream++;
+ jValue = (UCHAR) *pusCmdStream++;
+
+
+ Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort),
+ jValue);
+
+ } else {
+
+ //
+ // Single word out
+ //
+
+ ulPort = *pusCmdStream++;
+ usValue = *pusCmdStream++;
+
+ Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort), (UCHAR)(usValue & 0x00ff));
+
+ Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort+1 ), (UCHAR)(usValue >> 8));
+
+
+ }
+
+ } else {
+
+ //
+ // Output a string of values
+ // Byte or word outs?
+ //
+
+ if (!(ulCmd & BW)) {
+
+ //
+ // String byte outs. Do in a loop; can't use
+ // VideoPortWritePortBufferUchar because the data
+ // is in USHORT form
+ //
+
+ ulPort = ulBase + *pusCmdStream++;
+ culCount = *pusCmdStream++;
+
+ while (culCount--) {
+ jValue = (UCHAR) *pusCmdStream++;
+
+ Write_Dbg_Uchar((PUCHAR)ulPort,
+ jValue);
+
+ }
+
+ } else {
+
+ //
+ // String word outs
+ //
+
+ ulPort = *pusCmdStream++;
+ culCount = *pusCmdStream++;
+ //
+ // Buffering out is not use on the Miniport Driver for R96 machine.
+ //
+
+
+ while(culCount--)
+ {
+ usValue = *pusCmdStream++;
+
+ Write_Dbg_Uchar((PUCHAR)
+ (ulBase + ulPort), (UCHAR) (usValue & 0x00ff));
+ Write_Dbg_Uchar((PUCHAR)
+ (ulBase + ulPort+1), (UCHAR) (usValue >> 8));
+
+ }
+
+ }
+ }
+
+ } else {
+
+ // In instruction
+ //
+ // Currently, string in instructions aren't supported; all
+ // in instructions are handled as single-byte ins
+ //
+ // Byte or word in?
+ //
+
+ if (!(ulCmd & BW)) {
+ //
+ // Single byte in
+ //
+
+ ulPort = *pusCmdStream++;
+ jValue = READ_REGISTER_UCHAR((PUCHAR)ulBase+ulPort);
+
+ } else {
+
+ //
+ // Single word in
+ //
+
+ ulPort = *pusCmdStream++;
+ usValue = READ_REGISTER_USHORT((PUSHORT)
+ (ulBase+ulPort));
+ }
+
+ }
+
+ break;
+
+ //
+ // Higher-level input/output commands
+ //
+
+ case METAOUT:
+
+ //
+ // Determine type of metaout command, based on minor
+ // command field
+ //
+ switch (ulCmd & 0x0F) {
+
+ //
+ // Indexed outs
+ //
+
+ case INDXOUT:
+
+ ulPort = ulBase + *pusCmdStream++;
+ culCount = *pusCmdStream++;
+ ulIndex = *pusCmdStream++;
+
+ while (culCount--) {
+
+ usValue = (USHORT) (ulIndex +
+ (((ULONG)(*pusCmdStream++)) << 8));
+
+ Write_Dbg_Uchar((PUCHAR)ulPort, (UCHAR) (usValue & 0x00ff));
+
+ Write_Dbg_Uchar((PUCHAR)ulPort+1, (UCHAR) (usValue >> 8));
+
+ ulIndex++;
+
+ }
+
+ break;
+
+ //
+ // Masked out (read, AND, XOR, write)
+ //
+
+ case MASKOUT:
+
+ ulPort = *pusCmdStream++;
+ jValue = READ_REGISTER_UCHAR((PUCHAR)ulBase+ulPort);
+ jValue &= *pusCmdStream++;
+ jValue ^= *pusCmdStream++;
+
+ Write_Dbg_Uchar((PUCHAR)ulBase + ulPort,
+ jValue);
+
+ break;
+
+ //
+ // Attribute Controller out
+ //
+
+ case ATCOUT:
+
+ ulPort = ulBase + *pusCmdStream++;
+ culCount = *pusCmdStream++;
+ ulIndex = *pusCmdStream++;
+
+ while (culCount--) {
+
+ // Write Attribute Controller index
+
+ Write_Dbg_Uchar((PUCHAR)ulPort,
+ (UCHAR)ulIndex);
+
+ // Write Attribute Controller data
+ jValue = (UCHAR) *pusCmdStream++;
+
+ Write_Dbg_Uchar((PUCHAR)ulPort, jValue);
+
+ ulIndex++;
+
+ }
+
+ break;
+
+ //
+ // None of the above; error
+ //
+ default:
+
+ return FALSE;
+
+ }
+
+
+ break;
+
+ //
+ // NOP
+ //
+
+ case NCMD:
+
+ break;
+
+ //
+ // Unknown command; error
+ //
+
+ default:
+
+ return FALSE;
+
+ }
+
+ }
+
+ return TRUE;
+
+} // end HalpCirrusInterpretCmdStream()
+
+
+VOID
+HalpDisplayTgaSetup(
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ This routine initializes the Tga(DEC21030) Graphics accelerator.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None
+
+--*/
+
+{
+
+ PUCHAR PLLbits;
+ ULONG i, j;
+ ULONG PLLdata;
+ ULONG ColorData;
+ PULONG Buffer;
+ LONG Limit;
+ LONG Index;
+ ULONG VerticalFrequency;
+ ULONG horizontalTotal;
+ ULONG verticalTotal;
+
+// M019+++
+//
+// support for nec dec-ga(tga) board.
+// parameter change.
+//
+#if 0
+ const UCHAR PLLbits640x480_72[7] = { 0x80, 0x08, 0x80, 0x24, 0xb0, 0x20, 0xc8 };
+ const UCHAR PLLbits640x480_60[7] = { 0x80, 0x08, 0x80, 0x24, 0x88, 0x80, 0x78 };
+ const UCHAR PLLbits800x600_72[7] = { 0x80, 0x00, 0x80, 0x24, 0x88, 0x80, 0x78 };
+ const UCHAR PLLbits800x600_60[7] = { 0x80, 0x00, 0x80, 0x24, 0x70, 0xa0, 0x84 };
+ const UCHAR PLLbits1024x768_60[7] = { 0x80, 0x00, 0x80, 0x24, 0x48, 0x20, 0x98 };
+#else
+ const UCHAR PLLbits640x480_72[7] = { 0x80, 0x04, 0x80, 0xa4, 0x51, 0x80, 0x70 };
+ const UCHAR PLLbits640x480_60[7] = { 0x80, 0x04, 0x80, 0xa5, 0xc4, 0x10, 0x78 };
+ const UCHAR PLLbits800x600_72[7] = { 0x80, 0x08, 0x80, 0x24, 0xf1, 0x60, 0x38 }; // S007
+ const UCHAR PLLbits800x600_60[7] = { 0x80, 0x04, 0x80, 0xa5, 0x78, 0x20, 0x08 };
+ const UCHAR PLLbits1024x768_60[7] = { 0x80, 0x00, 0x80, 0x24, 0x48, 0x20, 0x98 };
+#endif // _NECDEC_
+// M019 ---
+
+ const UCHAR Vga_Ini_ColorTable[48] =
+// { VGA_INI_PALETTE_WHITE_R, VGA_INI_PALETTE_WHITE_G, VGA_INI_PALETTE_WHITE_B,
+ { VGA_INI_PALETTE_HI_WHITE_R, VGA_INI_PALETTE_HI_WHITE_G, VGA_INI_PALETTE_HI_WHITE_B, // M010
+ VGA_INI_PALETTE_BLUE_R, VGA_INI_PALETTE_BLUE_G, VGA_INI_PALETTE_BLUE_B,
+ VGA_INI_PALETTE_GREEN_R, VGA_INI_PALETTE_GREEN_B, VGA_INI_PALETTE_GREEN_G,
+ VGA_INI_PALETTE_YELLOW_R, VGA_INI_PALETTE_YELLOW_G, VGA_INI_PALETTE_YELLOW_B,
+ VGA_INI_PALETTE_RED_R, VGA_INI_PALETTE_RED_G, VGA_INI_PALETTE_RED_B,
+ VGA_INI_PALETTE_MAGENTA_R, VGA_INI_PALETTE_MAGENTA_G, VGA_INI_PALETTE_MAGENTA_B,
+ VGA_INI_PALETTE_CYAN_R, VGA_INI_PALETTE_CYAN_G, VGA_INI_PALETTE_CYAN_B,
+ VGA_INI_PALETTE_BLACK_R, VGA_INI_PALETTE_BLACK_G, VGA_INI_PALETTE_BLACK_B,
+// VGA_INI_PALETTE_HI_WHITE_R, VGA_INI_PALETTE_HI_WHITE_G, VGA_INI_PALETTE_HI_WHITE_B,
+ VGA_INI_PALETTE_WHITE_R, VGA_INI_PALETTE_WHITE_G, VGA_INI_PALETTE_WHITE_B, // M010
+ VGA_INI_PALETTE_HI_BLUE_R, VGA_INI_PALETTE_HI_BLUE_G, VGA_INI_PALETTE_HI_BLUE_B,
+ VGA_INI_PALETTE_HI_GREEN_R, VGA_INI_PALETTE_HI_GREEN_G, VGA_INI_PALETTE_HI_GREEN_B,
+ VGA_INI_PALETTE_HI_YELLOW_R, VGA_INI_PALETTE_HI_YELLOW_G, VGA_INI_PALETTE_HI_YELLOW_B,
+ VGA_INI_PALETTE_HI_RED_R, VGA_INI_PALETTE_HI_RED_G, VGA_INI_PALETTE_HI_RED_B,
+ VGA_INI_PALETTE_HI_MAGENTA_R, VGA_INI_PALETTE_HI_MAGENTA_G, VGA_INI_PALETTE_HI_MAGENTA_B,
+ VGA_INI_PALETTE_HI_CYAN_R, VGA_INI_PALETTE_HI_CYAN_G, VGA_INI_PALETTE_HI_CYAN_B,
+ VGA_INI_PALETTE_HI_BLACK_R, VGA_INI_PALETTE_HI_BLACK_G, VGA_INI_PALETTE_HI_BLACK_B
+ };
+
+ //
+ // Calculate vertical frequency.
+ //
+
+ horizontalTotal = ( HalpMonitorConfigurationData.HorizontalDisplayTime
+ +HalpMonitorConfigurationData.HorizontalBackPorch
+ +HalpMonitorConfigurationData.HorizontalFrontPorch
+ +HalpMonitorConfigurationData.HorizontalSync );
+
+ verticalTotal = ( HalpMonitorConfigurationData.VerticalResolution
+ +HalpMonitorConfigurationData.VerticalBackPorch
+ +HalpMonitorConfigurationData.VerticalFrontPorch
+ +HalpMonitorConfigurationData.VerticalSync );
+
+ VerticalFrequency = 1000000000 / ( horizontalTotal * verticalTotal);
+
+ //
+ // Write the PLL
+ //
+
+ // Select PLL Data
+ if( HalpMonitorConfigurationData.HorizontalResolution == 640
+ && HalpMonitorConfigurationData.VerticalResolution == 480 ){
+ if( VerticalFrequency > 66 ){
+ PLLbits = (PVOID)PLLbits640x480_72; // S012
+ } else {
+ PLLbits = (PVOID)PLLbits640x480_60; // S012
+ }
+ } else if( HalpMonitorConfigurationData.HorizontalResolution == 800
+ && HalpMonitorConfigurationData.VerticalResolution == 600 ){
+ if( VerticalFrequency > 66 ){
+ PLLbits = (PVOID)PLLbits800x600_72; // S012
+ } else {
+ PLLbits = (PVOID)PLLbits800x600_60; // S012
+ }
+ } else if( HalpMonitorConfigurationData.HorizontalResolution == 1024
+ && HalpMonitorConfigurationData.VerticalResolution == 768 ){
+ PLLbits = (PVOID)PLLbits1024x768_60; // S012
+ } else {
+ PLLbits = (PVOID)PLLbits640x480_60; // S012
+ }
+
+ // Set PLL Data
+ for( i = 0; i <= 6; i++ ){
+ for( j = 0; j <= 7; j++ ){
+ PLLdata = (PLLbits[i] >> (7-j)) & 1;
+ if( i == 6 && j == 7 )
+ PLLdata |= 2; // Set ~HOLD bit on last write
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + CLOCK), PLLdata);
+ }
+ }
+
+ // Verify 21030 is idle ( check busy bit on Command Status Register )
+ while( (READ_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + COMMAND_STATUS) ) & 1) == 1 ){
+ }
+
+ // Set to Deep Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + DEEP), 0x00014000 );
+
+ // Verify 21030 is idle ( check busy bit on Command Status Register )
+ while( (READ_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + COMMAND_STATUS) ) & 1) == 1 ){
+ }
+
+ // Set to Video Base Address Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + VIDEO_BASE), 0x00000000 );
+
+ // Set to Plane Mask Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + PLANE_MASK), 0xffffffff );
+
+ // Set to Pixel Mask Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + ONE_SHOT_PIXEL_MASK), 0xffffffff );
+
+ // Set to Raster Operation
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RASTER_OP), 0x03 );
+
+ // Set to Mode Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + MODE), 0x0000200d );
+
+ // Set to Block Color Register 0
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + BLK_COLOR_R0), 0x12345678 );
+
+ // Set to Block Color Register 1
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + BLK_COLOR_R1), 0x12345678 );
+
+ //
+ // Init. video timing registers for each resolution
+ //
+
+ if( HalpMonitorConfigurationData.HorizontalResolution == 640
+ && HalpMonitorConfigurationData.VerticalResolution == 480 ){
+ if( VerticalFrequency > 66 ){
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x03c294a0 ); // M023
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x070349e0 );
+ } else {
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x00e64ca0 ); // M023
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x064211e0 );
+ }
+ } else if( HalpMonitorConfigurationData.HorizontalResolution == 800
+ && HalpMonitorConfigurationData.VerticalResolution == 600 ){
+ if( VerticalFrequency > 66 ){
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x01a7a4c8 ); // M023
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x05c6fa58 );
+ } else {
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x02681cc8 ); // M023
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x05c40a58 );
+ }
+ } else if( HalpMonitorConfigurationData.HorizontalResolution == 1024
+ && HalpMonitorConfigurationData.VerticalResolution == 768 ){
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x04889300 ); // M023
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x07461b00 );
+ } else {
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x00e64ca0 ); // M023
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x064211e0 );
+ }
+
+ // Set to Raster Operation Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RASTER_OP), 0x03 );
+
+ // Set to Mode Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + MODE), 0x00002000 );
+
+ // M019 +++
+
+ //
+ // wait for 10 msec for nec dec-ga support
+ //
+
+ KeStallExecutionProcessor(10000L);
+
+ // M019 ---
+
+ // Set to Palette and DAC Setup & Data Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x0c );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x0ca2 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x10 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x1040 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x12 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x1220 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x00 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x01 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x14 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x1410 );
+
+ //
+ // set pass thru on off & on again to verify operation
+ //
+
+ // EEPROM Write Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + EEPROM_WRITE), 0x00000001 );
+
+ //
+ // Fill palette
+ //
+
+ // Set to Palette and DAC Setup & Data Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x00 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x00 );
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x02 );
+
+ for( i = 0; i < 48; i++ ){
+ ColorData = Vga_Ini_ColorTable[i];
+ ColorData |= 0x200;
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), ColorData );
+ }
+
+ for( i = 48; i < 768; i++ ){
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x200 );
+ }
+
+ // Set to Video Valid Register
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + VIDEO_VALID), 0x01 );
+
+ //
+ // Set Video Memory to address color one.
+ //
+
+ Buffer = (PULONG)VIDEO_MEMORY_BASE;
+ Limit = (HalpMonitorConfigurationData.HorizontalResolution *
+ HalpMonitorConfigurationData.VerticalResolution) / sizeof(ULONG);
+
+ for (Index = 0; Index < Limit; Index += 1) {
+ *Buffer++ = 0x01010101;
+ }
+
+ //
+ // Initialize the current display column, row, and ownership values.
+ //
+
+ HalpColumn = 0;
+ HalpRow = 0;
+ HalpDisplayOwnedByHal = TRUE;
+ return;
+
+}
+
+VOID
+HalDisplayString (
+ PUCHAR String
+ )
+
+/*++
+
+Routine Description:
+
+ This routine displays a character string on the display screen.
+
+
+Arguments:
+
+ String - Supplies a pointer to the characters that are to be displayed.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+ ENTRYLO SavedPte;
+ /* Start D001 */
+ ULONG NowDisplayControlBase;
+ ULONG NowDisplayMemoryBase; // M021
+ PENTRYLO PageFrame;
+ ENTRYLO Pte;
+ LONG Index;
+ /* End D001 */
+ PCI_SLOT_NUMBER Slot; // M014
+ ULONG ReadValue; // M014
+
+ //
+ // Raise IRQL to the highest level, acquire the display adapter spin lock,
+ // flush the TB, and map the display frame buffer into the address space
+ // of the current process.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+#if defined(_DUO_)
+
+ KiAcquireSpinLock(&HalpDisplayAdapterLock);
+
+#endif
+
+ SavedPte = *((PENTRYLO)(PDE_BASE |
+ ((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc)));
+
+ KeFlushCurrentTb();
+ *((PENTRYLO)(PDE_BASE |
+ ((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc))) = HalpDisplayPte;
+
+ if (HalpDisplayPCIDevice == TRUE){
+
+ //
+ // the display type is PCI
+ // check physical address and reinitialize PTE
+ // we assume that the device has no function
+ //
+
+ Slot.u.bits.FunctionNumber = 0;
+
+ for (Slot.u.bits.DeviceNumber = 3; Slot.u.bits.DeviceNumber < 6; Slot.u.bits.DeviceNumber++){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+ if (HalpDisplayControllerSetup == HalpDisplayTgaSetup && ReadValue == 0x00041011){
+
+ //
+ // DEC21030
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ NowDisplayControlBase = (ReadValue & 0xfffffff0)+ TGA_REG_SPC_OFFSET;
+ NowDisplayMemoryBase = 0;
+
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup && ReadValue == 0x00013d3d){
+
+ //
+ // GLINT 300SX
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ NowDisplayControlBase = (ReadValue & 0xfffffff0);
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
+ NowDisplayMemoryBase = (ReadValue & 0xfffffff0);
+
+ }
+ }
+
+ //
+ // check to see if address has been changed
+ //
+
+ if (HalpDisplayControlBase != NowDisplayControlBase ||
+ HalpDisplayMemoryBase != NowDisplayMemoryBase){
+
+ // Called by OS, so reinitialize PTE
+ HalpDisplayControlBase = NowDisplayControlBase;
+ HalpDisplayMemoryBase = NowDisplayMemoryBase;
+
+ Pte.G = 0;
+ Pte.V = 1;
+ Pte.D = 1;
+
+#if defined(R3000)
+ Pte.N = 1;
+#endif
+#if defined(R4000)
+ Pte.C = UNCACHED_POLICY;
+#endif
+
+ //
+ // Initialize the page table page.
+ //
+
+ PageFrame = (PENTRYLO)(PTE_BASE | (VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
+
+ if (HalpDisplayControllerSetup == HalpDisplayTgaSetup){
+ HalpTgaPhigicalVideoCont.HighPart = 1;
+ HalpTgaPhigicalVideoCont.LowPart = HalpDisplayControlBase - TGA_REG_SPC_OFFSET + TGA_DSP_BUF_OFFSET;
+ Pte.PFN = (HalpTgaPhigicalVideoCont.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpTgaPhigicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) { // M021
+
+ HalpGlintPhygicalVideo.HighPart = 1;
+ HalpGlintPhygicalVideo.LowPart = HalpDisplayMemoryBase;
+ Pte.PFN = (HalpGlintPhygicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideo.HighPart << (32 - PAGE_SHIFT);
+ }
+
+ //
+ // Page table entries of the video memory.
+ //
+
+ for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
+ *PageFrame++ = Pte;
+ Pte.PFN += 1;
+ }
+
+ if (HalpDisplayControllerSetup == HalpDisplayTgaSetup){
+ HalpTgaPhigicalVideoCont.HighPart = 1;
+ HalpTgaPhigicalVideoCont.LowPart = HalpDisplayControlBase;
+ Pte.PFN = (HalpTgaPhigicalVideoCont.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpTgaPhigicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+ *PageFrame = Pte;
+
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) { // M021
+ HalpGlintPhygicalVideoCont.HighPart = 1;
+ HalpGlintPhygicalVideoCont.LowPart = HalpDisplayControlBase;
+
+ //
+ // IBM RGB525
+ //
+
+ Pte.PFN = ((HalpGlintPhygicalVideoCont.LowPart + 0x4000) >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+ *(PageFrame - 2) = Pte;
+
+ //
+ // GLINT 300SX Internal Video Registers
+ //
+
+ Pte.PFN = ((HalpGlintPhygicalVideoCont.LowPart + 0x3000) >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+ *(PageFrame - 1) = Pte;
+
+ //
+ // GLINT 300SX Control Status Registers
+ //
+
+ Pte.PFN = (HalpGlintPhygicalVideoCont.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
+ *PageFrame = Pte;
+ }
+ }
+ }
+
+ //
+ // If ownership of the display has been switched to the system display
+ // driver, then reinitialize the display controller and revert ownership
+ // to the HAL.
+ //
+
+ if (HalpDisplayOwnedByHal == FALSE) {
+// M003 +++
+ if (HalpResetDisplayParameters &&
+ HalpDisplayControllerSetup == HalpDisplayINT10Setup) {
+ //
+ // Video work-around. The video driver has a reset function,
+ // call it before resetting the system in case the bios doesn't
+ // know how to reset the displays video mode.
+ //
+
+ if (HalpResetDisplayParameters(80, 50)) {
+ }
+// M003---
+ }
+
+ //
+ // M010
+ // for Software controlled power suply.
+ //
+
+#if defined(_MRCPOWER_)
+ HalpMrcModeChange((UCHAR)0); // M007
+#endif // _MRCPOWER_
+
+ HalpDisplayControllerSetup();
+// HalpResetX86DisplayAdapter();
+
+ //
+ // M004
+ // re-initialize critical message
+ //
+
+ HalpInitDisplayStringIntoNvram();
+
+ }
+
+ //
+ // M004
+ // ESM critical error logging start (set colomn,row)
+ //
+
+ HalStringIntoBufferStart( HalpColumn, HalpRow );
+
+ //
+ // Display characters until a null byte is encountered.
+ //
+
+ while (*String != 0) {
+ HalpDisplayCharacter(*String++);
+ }
+
+ // M004
+ // ESM critical error logging(strings)
+ //
+
+ HalpStringBufferCopyToNvram();
+
+ //
+ // Restore the previous mapping for the current process, flush the TB,
+ // release the display adapter spin lock, and lower IRQL to its previous
+ // level.
+ //
+
+ KeFlushCurrentTb();
+ *((PENTRYLO)(PDE_BASE | ((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc))) = SavedPte;
+
+#if defined(_DUO_)
+
+ KiReleaseSpinLock(&HalpDisplayAdapterLock);
+
+#endif
+
+ KeLowerIrql(OldIrql);
+ return;
+}
+
+VOID
+HalpDisplayCharacterOld (
+ IN UCHAR Character
+ )
+
+/*++
+
+Routine Description:
+
+ This routine displays a character at the current x and y positions in
+ the frame buffer. If a newline is encounter, then the frame buffer is
+ scrolled. If characters extend below the end of line, then they are not
+ displayed.
+
+Arguments:
+
+ Character - Supplies a character to be displayed.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PUCHAR Destination;
+ PUSHORT DestinationShort; // M021
+ ULONG Index;
+
+ //
+ // If the character is a newline, then scroll the screen up, blank the
+ // bottom line, and reset the x position.
+ //
+
+ if (Character == '\n') {
+ HalpColumn = 0;
+ if (HalpRow < (HalpDisplayText - 1)) {
+ HalpRow += 1;
+
+ } else {
+ HalpMoveMemory32((PUCHAR)VIDEO_MEMORY_BASE,
+ (PUCHAR)(VIDEO_MEMORY_BASE + HalpScrollLine),
+ HalpScrollLength);
+
+// /* START M002 */
+// RtlMoveMemory((PUCHAR)VIDEO_MEMORY_BASE, // S013
+// (PUCHAR)(VIDEO_MEMORY_BASE + HalpScrollLine),
+// HalpScrollLength);
+// /* END M002 */
+
+ if (HalpDisplayType16BPP) {
+ DestinationShort = (PUSHORT)(VIDEO_MEMORY_BASE + HalpScrollLength);
+
+ } else {
+ Destination = (PUCHAR)VIDEO_MEMORY_BASE + HalpScrollLength;
+ }
+
+ if (HalpDisplayType16BPP) {
+ for (Index = 0; Index < HalpScrollLine/2; Index += 1) {
+ *DestinationShort++ = (USHORT)0x000f;
+ }
+
+ } else {
+ for (Index = 0; Index < HalpScrollLine; Index += 1) {
+ *Destination++ = 1;
+ }
+ }
+
+ }
+
+ //
+ // M006
+ // ESM critical logging re-print(column, row)
+ //
+
+ HalpStringBufferCopyToNvram();
+ HalStringIntoBufferStart( HalpColumn, HalpRow );
+
+ } else if (Character == '\r') {
+ HalpColumn = 0;
+
+ //
+ // M006
+ // ESM critical logging re-print(column,row)
+ //
+
+ HalpStringBufferCopyToNvram();
+ HalStringIntoBufferStart( HalpColumn, HalpRow );
+
+ } else {
+
+ //
+ // M006
+ // ESM critical logging put character.
+ //
+
+ HalStringIntoBuffer( Character );
+
+ if ((Character < HalpFontHeader->FirstCharacter) ||
+ (Character > HalpFontHeader->LastCharacter)) {
+ Character = HalpFontHeader->DefaultCharacter;
+ }
+
+ Character -= HalpFontHeader->FirstCharacter;
+ HalpOutputCharacterOld((PUCHAR)HalpFontHeader + HalpFontHeader->Map[Character].Offset);
+ }
+
+ return;
+}
+
+//351
+VOID
+HalpDisplayCharacterVGA (
+ IN UCHAR Character
+ )
+
+/*++
+Routine Description:
+
+ This routine displays a character at the current x and y positions in
+ the frame buffer. If a newline is encounter, then the frame buffer is
+ scrolled. If characters extend below the end of line, then they are not
+ displayed.
+
+Arguments:
+
+ Character - Supplies a character to be displayed.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ //
+ // If the character is a newline, then scroll the screen up, blank the
+ // bottom line, and reset the x position.
+ //
+
+ if (Character == '\n') {
+ HalpColumn = 0;
+ if (HalpRow < (HalpDisplayText - 1)) {
+ HalpRow += 1;
+ } else { // need to scroll up the screen
+ HalpScrollINT10(1);
+ }
+
+ //
+ // M006
+ // ESM critical logging re-print(column, row)
+ //
+
+ HalpStringBufferCopyToNvram();
+ HalStringIntoBufferStart( HalpColumn, HalpRow );
+
+ }
+
+ //=========================================================================
+ //
+ // IBMBJB added tab processing
+ //
+
+ else if( Character == '\t' ) // tab?
+ {
+ HalpColumn += TAB_SIZE;
+ HalpColumn = (HalpColumn / TAB_SIZE) * TAB_SIZE;
+
+ if( HalpColumn >= 80 ) // tab beyond end of screen?
+ {
+ HalpColumn = 0; // next tab stop is 1st column of next line
+
+ if( HalpRow >= (HalpDisplayText - 1) )
+ HalpScrollINT10( 1 ); // scroll the screen up
+ else
+ ++HalpRow;
+ }
+ }
+
+ //=========================================================================
+
+ else if (Character == '\r') {
+
+ //
+ // M006
+ // ESM critical logging re-print(column,row)
+ //
+
+ HalpStringBufferCopyToNvram();
+ HalStringIntoBufferStart( HalpColumn, HalpRow );
+
+ HalpColumn = 0;
+
+ } else if (Character == 0x7f) { /* DEL character */
+ if (HalpColumn != 0) {
+ HalpColumn -= 1;
+ HalpOutputCharacterINT10(0);
+ HalpColumn -= 1;
+ } else /* do nothing */
+ ;
+ } else if (Character >= 0x20) {
+ //
+ // M006
+ // ESM critical logging put character.
+ //
+
+ HalStringIntoBuffer( Character );
+
+ // Auto wrap for 80 columns per line
+ if (HalpColumn >= 80) {
+ HalpColumn = 0;
+ if (HalpRow < (HalpDisplayText - 1)) {
+ HalpRow += 1;
+ } else { // need to scroll up the screen
+ HalpScrollINT10(1);
+ }
+ }
+ HalpOutputCharacterINT10(Character);
+ } else /* skip the nonprintable character */
+ ;
+
+ return;
+
+} /* end of HalpDisplayCharacterVGA() */
+
+VOID
+HalQueryDisplayParameters (
+ OUT PULONG WidthInCharacters,
+ OUT PULONG HeightInLines,
+ OUT PULONG CursorColumn,
+ OUT PULONG CursorRow
+ )
+
+/*++
+
+Routine Description:
+
+ This routine return information about the display area and current
+ cursor position.
+
+Arguments:
+
+ WidthInCharacter - Supplies a pointer to a varible that receives
+ the width of the display area in characters.
+
+ HeightInLines - Supplies a pointer to a variable that receives the
+ height of the display area in lines.
+
+ CursorColumn - Supplies a pointer to a variable that receives the
+ current display column position.
+
+ CursorRow - Supplies a pointer to a variable that receives the
+ current display row position.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Set the display parameter values and return.
+ //
+
+ *WidthInCharacters = HalpDisplayWidth;
+ *HeightInLines = HalpDisplayText;
+ *CursorColumn = HalpColumn;
+ *CursorRow = HalpRow;
+ return;
+}
+
+VOID
+HalSetDisplayParameters (
+ IN ULONG CursorColumn,
+ IN ULONG CursorRow
+ )
+
+/*++
+
+Routine Description:
+
+ This routine set the current cursor position on the display area.
+
+Arguments:
+
+ CursorColumn - Supplies the new display column position.
+
+ CursorRow - Supplies a the new display row position.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Set the display parameter values and return.
+ //
+
+ if (CursorColumn > HalpDisplayWidth) {
+ CursorColumn = HalpDisplayWidth;
+ }
+
+ if (CursorRow > HalpDisplayText) {
+ CursorRow = HalpDisplayText;
+ }
+
+ HalpColumn = CursorColumn;
+ HalpRow = CursorRow;
+ return;
+}
+
+VOID
+HalpOutputCharacterOld(
+ IN PUCHAR Glyph
+ )
+
+/*++
+
+Routine Description:
+
+ This routine insert a set of pixels into the display at the current x
+ cursor position. If the current x cursor position is at the end of the
+ line, then a newline is displayed before the specified character.
+
+Arguments:
+
+ Character - Supplies a character to be displayed.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PUCHAR Destination;
+ PUSHORT DestinationShort; // M021
+ ULONG FontValue;
+ ULONG I;
+ ULONG J;
+
+ //
+ // If the current x cursor position is at the end of the line, then
+ // output a line feed before displaying the character.
+ //
+
+ if (HalpColumn == HalpDisplayWidth) {
+ HalpDisplayCharacter('\n');
+ }
+
+ //
+ // Output the specified character and update the x cursor position.
+ //
+
+ if (HalpDisplayType16BPP) {
+ DestinationShort = (PUSHORT)(VIDEO_MEMORY_BASE +
+ (HalpRow * HalpScrollLine) + (HalpColumn * HalpCharacterWidth * sizeof(USHORT)));
+
+ } else {
+ Destination = (PUCHAR)(VIDEO_MEMORY_BASE +
+ (HalpRow * HalpScrollLine) + (HalpColumn * HalpCharacterWidth));
+ }
+
+ for (I = 0; I < HalpCharacterHeight; I += 1) {
+ FontValue = 0;
+ for (J = 0; J < HalpBytesPerRow; J += 1) {
+ FontValue |= *(Glyph + (J * HalpCharacterHeight)) << (24 - (J * 8));
+ }
+
+ Glyph += 1;
+ for (J = 0; J < HalpCharacterWidth ; J += 1) {
+
+ if (HalpDisplayType16BPP) {
+ if (FontValue >> 31)
+ *DestinationShort++ = (USHORT)0xffff;
+ else
+ *DestinationShort++ = (USHORT)0x000f;
+
+ }else{
+ *Destination++ = (UCHAR) (FontValue >> 31) ^ 1; /* M008 */
+ }
+
+ FontValue <<= 1;
+ }
+
+ if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
+ Destination +=
+ (1024 - HalpCharacterWidth);
+ }
+ else if (HalpDisplayType16BPP){
+ DestinationShort +=
+ (HalpMonitorConfigurationData.HorizontalResolution - HalpCharacterWidth);
+ }
+ else {
+ Destination +=
+ (HalpMonitorConfigurationData.HorizontalResolution - HalpCharacterWidth);
+ }
+
+ }
+ HalpColumn += 1;
+ return;
+}
+
+VOID
+Write_Dbg_Uchar(
+ PUCHAR Ioadress,
+ UCHAR Moji
+ )
+{
+#if defined (R96DBG)
+ DbgPrint("Disply I/O Adress %x Char %x \n",Ioadress,Moji);
+#endif
+ WRITE_PORT_UCHAR(Ioadress,Moji);
+}
+
+VOID
+HalpMoveMemory32 (
+ PUCHAR Destination,
+ PUCHAR Source,
+ ULONG Length
+ )
+
+/*++
+ Routine Description:
+
+ This function moves blocks of memory.
+
+ Arguments:
+
+ Destination - Supplies a pointer to the destination address of
+ the move operation.
+
+ Source - Supplies a pointer to the source address of the move
+ operation.
+
+ Length - Supplies the length, in bytes, of the memory to be moved.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ UCHAR Remainder;
+ PUCHAR Dstend;
+ PUCHAR Srcend;
+
+ if ( (Source == Destination) || (Length == 0) ) {
+ return;
+ }
+
+ if ((Source < Destination)&((Source + Length) > Destination)) {
+ if((Destination - Source) > 4){
+ Remainder = (UCHAR) Length &0x03;
+ Length = Length / 4;
+ Dstend = Destination + Length - 4 ;
+ Srcend = Source + Length -4;
+
+ for (; Length > 0; Length--) {
+ *(PULONG)(Dstend) = *(PULONG)(Srcend);
+ Dstend -= 4;
+ Srcend -= 4;
+ }
+ for (; Remainder > 0; Remainder--) {
+ *Dstend = *Srcend;
+ Dstend--;
+ Srcend--;
+ }
+ return;
+ }
+ for (; Length > 0; Length--) {
+ *Dstend = *Srcend;
+ Dstend--;
+ Srcend--;
+ }
+ return;
+ }
+
+ else {
+ if( (Source - Destination) > 4 ){
+ Remainder = (UCHAR) Length &0x03;
+ Length = Length / 4;
+ for (; Length > 0; Length--) {
+ *(PULONG)(Destination) = *(PULONG)(Source);
+ Destination += 4;
+ Source += 4;
+ }
+ for (; Remainder > 0; Remainder--) {
+ *Destination = *Source;
+ Destination++;
+ Source++;
+ }
+ return;
+ }
+
+ for (; Length > 0; Length--) {
+ *Destination = *Source;
+ Destination++;
+ Source++;
+ }
+ }
+}
+
+VOID
+HalpOutputCharacterINT10 (
+ IN UCHAR Character
+ )
+{
+ ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp;
+
+ Eax = 2 << 8; // AH = 2
+ Ebx = 0; // BH = page number
+ Edx = (HalpRow << 8) + HalpColumn;
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+
+ Eax = (0x0A << 8) + Character; // AH = 0xA AL = character
+ Ebx = 0;
+ Ecx = 1;
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+
+ HalpColumn += 1;
+}
+
+VOID
+HalpScrollINT10 (
+ IN UCHAR LinesToScroll
+ )
+{
+ ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp;
+
+ Eax = 6 << 8; // AH = 6 (scroll up)
+ Eax |= LinesToScroll; // AL = lines to scroll
+ Ebx = TEXT_ATTR << 8; // BH = attribute to fill blank line(s)
+ Ecx = 0; // CH,CL = upper left
+ Edx = ((HalpDisplayText - 1) << 8)
+ + (HalpDisplayWidth - 1); // DH,DL = lower right // M001,S005
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+}
+
+VOID
+HalpDisplayINT10Setup (
+ VOID
+ )
+{
+ ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp;
+
+ HalpColumn = 0;
+ HalpRow = 0;
+ HalpDisplayWidth = 80;
+ HalpDisplayText = 50; // M001
+ HalpScrollLine = 160;
+ HalpScrollLength = HalpScrollLine * (HalpDisplayText - 1);
+
+ HalpDisplayOwnedByHal = TRUE;
+
+ HalpResetX86DisplayAdapter(); // for compaq q-vision reset
+
+// M001 +++
+ //
+ // Load 8x8 font 80x50 on VGA
+ //
+ Eax = 0x1112; // AH = 11 AL=12
+ Ebx = 0;
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+// M001 ---
+
+ //
+ // Set cursor to (0,0)
+ //
+ Eax = 0x02 << 8; // AH = 2
+ Ebx = 0; // BH = page Number
+ Edx = 0; // DH = row DL = column
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+
+ //
+ // Make screen white on blue by scrolling entire screen
+ //
+ Eax = 0x06 << 8; // AH = 6 AL = 0
+ Ebx = TEXT_ATTR << 8; // BH = attribute
+ Ecx = 0; // (x,y) upper left
+ Edx = ((HalpDisplayText-1) << 8); // (x,y) lower right
+ Edx += HalpScrollLine/2;
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+
+}
+
+// start M014
+VOID
+HalpReadPCIConfigUlongByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PULONG Buffer,
+ IN ULONG Offset
+ )
+
+/*++
+ Routine Description:
+
+ This function returns PCI configuration data.
+
+ Arguments:
+
+ Slot - Supplies a PCI slot number and function number.
+ Buffer - Supplies a pointer to a configuration data is returned.
+ Offset - Offset in the PCI configuration header.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ //
+ // check to see if specified slot is valid
+ //
+
+ if (!HalpCheckPCIDevice(Slot)) {
+
+ //
+ // Invalid SlotID return no data
+ //
+
+ *Buffer = 0xffffffff;
+ return ;
+
+ }
+
+ *((PULONG) &ConfigAddressValue) = 0x0;
+
+ ConfigAddressValue.ConfigEnable = 1;
+ ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
+ ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
+ ConfigAddressValue.RegisterNumber = Offset >> 2;
+
+ //
+ // Synchronize with PCI configuration
+ //
+
+// KeRaiseIrql(PROFILE_LEVEL, &OldIrql); // M017
+// KiAcquireSpinLock(&HalpPCIConfigLock);
+
+ WRITE_REGISTER_ULONG(R94A_PCI_ADDR_REG, *((PULONG) &ConfigAddressValue));
+
+ *Buffer = READ_REGISTER_ULONG(R94A_PCI_DATA_REG);
+
+ //
+ // Release spinlock
+ //
+
+// KiReleaseSpinLock(&HalpPCIConfigLock);
+// KeLowerIrql(OldIrql);
+
+ return;
+}
+
+
+
+BOOLEAN
+HalpCheckPCIDevice (
+ IN PCI_SLOT_NUMBER Slot
+ )
+
+/*++
+ Routine Description:
+
+ This function checks if spcified PCI slot is valid.
+
+ Arguments:
+
+ Slot - Supplies a PCI slot number and function number.
+
+ Return Value:
+
+ TRUE - specified slot is valid
+ FALSE - specified slot is invalid
+
+--*/
+
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ BOOLEAN ReturnValue;
+ ULONG OrigData;
+ ULONG IdValue;
+ KIRQL OldIrql;
+
+ //
+ // Disable PCI-MasterAbort interrupt during configration read.
+ //
+
+ OrigData = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable);
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable, OrigData & 0xffffff7f);
+
+ //
+ // read VendorID and DeviceID of the specified slot
+ //
+
+ *((PULONG) &ConfigAddressValue) = 0x0;
+
+ ConfigAddressValue.ConfigEnable = 1;
+ ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
+ ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
+
+ //
+ // Synchronize with PCI configuration
+ //
+
+// KeRaiseIrql(PROFILE_LEVEL, &OldIrql); // M017
+// KiAcquireSpinLock(&HalpPCIConfigLock);
+
+ WRITE_REGISTER_ULONG(R94A_PCI_ADDR_REG, *((PULONG) &ConfigAddressValue));
+ IdValue = READ_REGISTER_ULONG(R94A_PCI_DATA_REG);
+
+ //
+ // Release spinlock
+ //
+
+// KiReleaseSpinLock(&HalpPCIConfigLock);
+// KeLowerIrql(OldIrql);
+
+ if ((USHORT)(IdValue & 0xffff) == 0xffff){
+
+ //
+ // waiting until ReceivedMasterAbort bit is set
+ //
+
+ while(!(READ_REGISTER_USHORT(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIStatus) & 0x2000))
+ ;
+
+ //
+ // clear the ReceivedMasterAbort bit
+ //
+
+ WRITE_REGISTER_USHORT(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIStatus, 0x2000)
+
+ //
+ // M018
+ // Clear memory address error registers.
+ //
+
+ {
+ LARGE_INTEGER registerLarge;
+ READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &registerLarge);
+ }
+
+ ReturnValue = FALSE;
+
+ } else {
+
+ ReturnValue = TRUE;
+
+ }
+
+ //
+ // Restore the PCIInterruptEnable register.
+ //
+
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable, OrigData);
+
+ return ReturnValue;
+
+}
+// end M014
+
+#if defined(_R94A_)
+VOID
+HalpDisplayGlintSetup(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This routine initializes the GLINT 300SX Graphics accelerator.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None
+
+--*/
+
+{
+ ULONG VerticalFrequency;
+ ULONG horizontalTotal;
+ ULONG verticalTotal;
+
+ __VIDEO __Video;
+ VIDEO Video = &__Video;
+ long ClockDivider;
+
+ // for initialize ramdac
+ ULONG Dac = RGB525_REGISTER_BASE;
+ UCHAR ByteVal;
+
+ // for initialize timing
+ ULONG Glint = GLINT_VIDEO_REGISTER_BASE - 0x3000;
+
+ // for initialize control
+ ULONG SerialClk;
+ ULONG Temp;
+ ULONG Data;
+ ULONG Mask;
+
+ // for initialize RampLut
+ ULONG Index;
+
+ // for clear the screen
+ PULONG DestinationUlong;
+ ULONG Length;
+
+ /* check revision id R01 or R02. assume 40MHz(R01) or 50MHz(R02) reference clock for now */
+
+ if ( HalpGlintRevisionId == 0){
+ Video->RefDivCount = RGB525_PLL_REFCLK_40_MHz;
+ } else {
+ Video->RefDivCount = RGB525_PLL_REFCLK_50_MHz; // S006
+ }
+
+//
+// Calculate vertical frequency.
+//
+
+#if defined(_GLINT60HZ_)
+
+ VerticalFrequency = 60;
+
+#else
+
+ horizontalTotal = ( HalpMonitorConfigurationData.HorizontalDisplayTime
+ +HalpMonitorConfigurationData.HorizontalBackPorch
+ +HalpMonitorConfigurationData.HorizontalFrontPorch
+ +HalpMonitorConfigurationData.HorizontalSync );
+
+ verticalTotal = ( HalpMonitorConfigurationData.VerticalResolution
+ +HalpMonitorConfigurationData.VerticalBackPorch
+ +HalpMonitorConfigurationData.VerticalFrontPorch
+ +HalpMonitorConfigurationData.VerticalSync );
+
+ VerticalFrequency = 1000000000 / ( horizontalTotal * verticalTotal);
+
+#endif // _GLINT60HZ_
+
+ //
+ // Initialize video data
+ //
+
+ /* get timing values for named resolution */
+
+ if ( HalpMonitorConfigurationData.HorizontalResolution == 1280
+ && HalpMonitorConfigurationData.VerticalResolution == 1024
+ && VerticalFrequency == 75)
+ {
+ Video->ImageWidth = 1280;
+ Video->ImageHeight = 1024;
+ Video->HLimit = 8 * 211;
+ Video->HSyncStart = 8 * 2;
+ Video->HSyncEnd = 8 * 20;
+ Video->HBlankEnd = 8 * 51;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ Video->VLimit = 1066;
+ Video->VSyncStart = 2;
+ Video->VSyncEnd = 5;
+ Video->VBlankEnd = 42;
+ Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ /* 134 MHz */
+ Video->PixelClock = RGB525_DF(3) | RGB525_VCO_DIV_COUNT(2);
+ }
+ else if ( HalpMonitorConfigurationData.HorizontalResolution == 1024
+ && HalpMonitorConfigurationData.VerticalResolution == 768
+ && VerticalFrequency == 75)
+ {
+ Video->ImageWidth = 1024;
+ Video->ImageHeight = 768;
+ Video->HLimit = 8 * 164;
+ Video->HSyncStart = 8 * 2;
+ Video->HSyncEnd = 8 * 14;
+ Video->HBlankEnd = 8 * 36;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_HIGH;
+ Video->VLimit = 800;
+ Video->VSyncStart = 2;
+ Video->VSyncEnd = 5;
+ Video->VBlankEnd = 32;
+ Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_HIGH;
+ /* 79 MHz */
+ Video->PixelClock = RGB525_DF(2) | RGB525_VCO_DIV_COUNT(14);
+ }
+ else if ( HalpMonitorConfigurationData.HorizontalResolution == 1024
+ && HalpMonitorConfigurationData.VerticalResolution == 768
+ && VerticalFrequency == 60)
+ {
+ Video->ImageWidth = 1024;
+ Video->ImageHeight = 768;
+ Video->HLimit = 8 * 168;
+ Video->HSyncStart = 8 * 3;
+ Video->HSyncEnd = 8 * 20;
+ Video->HBlankEnd = 8 * 40;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ Video->VLimit = 806;
+ Video->VSyncStart = 4;
+ Video->VSyncEnd = 10;
+ Video->VBlankEnd = 38;
+ Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ /* 65 MHz */
+ Video->PixelClock = RGB525_DF(2) | RGB525_VCO_DIV_COUNT(0);
+ }
+ else if ( HalpMonitorConfigurationData.HorizontalResolution == 800
+ && HalpMonitorConfigurationData.VerticalResolution == 600
+ && VerticalFrequency == 75)
+ {
+ Video->ImageWidth = 800;
+ Video->ImageHeight = 600;
+ Video->HLimit = 8 * 132;
+ Video->HSyncStart = 8 * 2;
+ Video->HSyncEnd = 8 * 12;
+ Video->HBlankEnd = 8 * 32;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_HIGH;
+ Video->VLimit = 625;
+ Video->VSyncStart = 2;
+ Video->VSyncEnd = 5;
+ Video->VBlankEnd = 25;
+ Video->VSyncPolarity = GLINT_VSYNC_ACTIVE_HIGH;
+ /* 49.5 MHz */
+ Video->PixelClock = RGB525_DF(1) | RGB525_VCO_DIV_COUNT(34);
+ }
+ else if ( HalpMonitorConfigurationData.HorizontalResolution == 800
+ && HalpMonitorConfigurationData.VerticalResolution == 600
+ && VerticalFrequency == 60)
+ {
+ Video->ImageWidth = 800;
+ Video->ImageHeight = 600;
+ Video->HLimit = 8 * 132;
+ Video->HSyncStart = 8 * 5;
+ Video->HSyncEnd = 8 * 21;
+ Video->HBlankEnd = 8 * 32;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_HIGH;
+ Video->VLimit = 628;
+ Video->VSyncStart = 2;
+ Video->VSyncEnd = 6;
+ Video->VBlankEnd = 28;
+ Video->VSyncPolarity = GLINT_VSYNC_ACTIVE_HIGH;
+ /* 40 MHz */
+ Video->PixelClock = RGB525_DF(1) | RGB525_VCO_DIV_COUNT(15);
+ }
+ else if ( HalpMonitorConfigurationData.HorizontalResolution == 640 // add 4/5/1995
+ && HalpMonitorConfigurationData.VerticalResolution == 480
+ && VerticalFrequency == 60)
+ {
+ Video->ImageWidth = 640;
+ Video->ImageHeight = 480;
+ Video->HLimit = 8 * 100;
+ Video->HSyncStart = 8 * 2;
+ Video->HSyncEnd = 8 * 14;
+ Video->HBlankEnd = 8 * 20;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ Video->VLimit = 525;
+ Video->VSyncStart = 12;
+ Video->VSyncEnd = 13;
+ Video->VBlankEnd = 45;
+ Video->VSyncPolarity = GLINT_VSYNC_ACTIVE_LOW;
+ /* 31.5 MHz */
+ Video->PixelClock = RGB525_DF(0) | RGB525_VCO_DIV_COUNT(36);
+ }
+ else if ( HalpMonitorConfigurationData.HorizontalResolution == 640
+ && HalpMonitorConfigurationData.VerticalResolution == 480
+ && VerticalFrequency == 75)
+ {
+ Video->ImageWidth = 640;
+ Video->ImageHeight = 480;
+ Video->HLimit = 8 * 105;
+ Video->HSyncStart = 8 * 2;
+ Video->HSyncEnd = 8 * 10;
+ Video->HBlankEnd = 8 * 25;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ Video->VLimit = 500;
+ Video->VSyncStart = 2;
+ Video->VSyncEnd = 5;
+ Video->VBlankEnd = 20;
+ Video->VSyncPolarity = GLINT_VSYNC_ACTIVE_LOW;
+ /* 31.5 MHz */
+ Video->PixelClock = RGB525_DF(0) | RGB525_VCO_DIV_COUNT(61);
+ }
+ else if ( HalpMonitorConfigurationData.HorizontalResolution == 1280
+ && HalpMonitorConfigurationData.VerticalResolution == 1024
+ && VerticalFrequency == 57)
+ {
+ Video->ImageWidth = 1280;
+ Video->ImageHeight = 1024;
+ Video->HLimit = 8 * 211;
+ Video->HSyncStart = 8 * 2;
+ Video->HSyncEnd = 8 * 20;
+ Video->HBlankEnd = 8 * 51;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ Video->VLimit = 1066;
+ Video->VSyncStart = 2;
+ Video->VSyncEnd = 5;
+ Video->VBlankEnd = 42;
+ Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ /* 103 MHz */
+ Video->PixelClock = RGB525_DF(2) | RGB525_VCO_DIV_COUNT(38);
+ }
+ else {
+ //
+ // force to set the resolution. 1024x768(60MHz)
+ //
+
+ Video->ImageWidth = 1024;
+ Video->ImageHeight = 768;
+ Video->HLimit = 8 * 168;
+ Video->HSyncStart = 8 * 3;
+ Video->HSyncEnd = 8 * 20;
+ Video->HBlankEnd = 8 * 40;
+ Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ Video->VLimit = 806;
+ Video->VSyncStart = 4;
+ Video->VSyncEnd = 10;
+ Video->VBlankEnd = 38;
+ Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
+ /* 65 MHz */
+ Video->PixelClock = RGB525_DF(2) | RGB525_VCO_DIV_COUNT(0);
+#if DBG
+ DbgBreakPoint();
+#endif
+ }
+
+ /* record image depth */
+
+ Video->ImageDepth = 16;
+
+ /* determine video clock divider and pixel format */
+
+ ClockDivider = 4;
+ Video->PixelFormat = RGB525_PIXEL_FORMAT_16_BPP;
+
+ /* adjust horizontal timings */
+
+ Video->HLimit /= ClockDivider;
+ Video->HSyncStart /= ClockDivider;
+ Video->HSyncEnd /= ClockDivider;
+ Video->HBlankEnd /= ClockDivider;
+
+ //
+ // Initialize ramdac data
+ //
+
+ RGB525_WRITE(Dac, __RGB525_PixelMask, 0xff);
+
+ /* set MiscControlOne register */
+ ByteVal = RGB525_MISR_CNTL_OFF
+ | RGB525_VMSK_CNTL_OFF
+ | RGB525_PADR_RFMT_READ_ADDR
+ | RGB525_SENS_DSAB_DISABLE
+ | RGB525_VRAM_SIZE_64;
+ RGB525_SET_REG(Dac, __RGB525_MiscControlOne, ByteVal);
+
+ /* set MiscControlTwo register */
+ ByteVal = RGB525_PCLK_SEL_PLL
+ | RGB525_INTL_MODE_DISABLE
+ | RGB525_BLANK_CNTL_NORMAL
+ | RGB525_COL_RES_8_BIT
+ | RGB525_PORT_SEL_VRAM;
+ RGB525_SET_REG(Dac, __RGB525_MiscControlTwo, ByteVal);
+
+ /* set MiscControlThree register */
+ ByteVal = RGB525_SWAP_RB_DISABLE
+ | RGB525_SWAP_WORD_31_00_FIRST
+ | RGB525_SWAP_NIB_07_04_FIRST;
+ RGB525_SET_REG(Dac, __RGB525_MiscControlThree, ByteVal);
+
+ /* set MiscClockControl register */
+ ByteVal = RGB525_DDOTCLK_DISABLE
+ | RGB525_SCLK_ENABLE
+ | RGB525_PLL_ENABLE;
+ RGB525_SET_REG(Dac, __RGB525_MiscClockControl, ByteVal);
+
+ /* set SyncControl register */
+ ByteVal = RGB525_DLY_CNTL_ADD
+ | RGB525_VSYN_INVT_DISABLE
+ | RGB525_HSYN_INVT_DISABLE
+ | RGB525_VSYN_CNTL_NORMAL
+ | RGB525_HSYN_CNTL_NORMAL;
+ RGB525_SET_REG(Dac, __RGB525_SyncControl, ByteVal);
+
+ /* set HSyncControl register */
+ RGB525_SET_REG(Dac, __RGB525_HSyncControl, RGB525_HSYN_POS(0));
+
+ /* set PowerManagement register */
+ ByteVal = RGB525_SCLK_PWR_NORMAL
+ | RGB525_DDOT_PWR_DISABLE
+ | RGB525_SYNC_PWR_NORMAL
+ | RGB525_ICLK_PWR_NORMAL
+ | RGB525_DAC_PWR_NORMAL;
+ RGB525_SET_REG(Dac, __RGB525_PowerManagement, ByteVal);
+
+ /* set DACOperation register */
+ ByteVal = RGB525_SOG_DISABLE
+ | RGB525_BRB_NORMAL
+ | RGB525_DSR_FAST
+ | RGB525_DPE_ENABLE; /* disable? */
+ RGB525_SET_REG(Dac, __RGB525_DACOperation, ByteVal);
+
+ /* set PaletteControl register */
+ ByteVal = RGB525_6BIT_LINEAR_ENABLE
+ | RGB525_PALETTE_PARTITION(0);
+ RGB525_SET_REG(Dac, __RGB525_PaletteControl, ByteVal);
+
+ /* set PixelFormat register */
+ RGB525_SET_REG(Dac, __RGB525_PixelFormat, Video->PixelFormat);
+
+ /* set 8BitPixelControl register */
+ RGB525_SET_REG(Dac, __RGB525_8BitPixelControl,
+ RGB525_B8_DCOL_INDIRECT);
+
+ /* set 16BitPixelControl register */
+ ByteVal = RGB525_B16_DCOL_INDIRECT
+ | RGB525_B16_565
+ | RGB525_B16_ZIB
+ | RGB525_B16_SPARSE;
+
+ RGB525_SET_REG(Dac, __RGB525_16BitPixelControl, ByteVal);
+
+ /* set 32BitPixelControl register */
+ RGB525_SET_REG(Dac, __RGB525_32BitPixelControl,
+ RGB525_B32_DCOL_INDIRECT);
+
+ /* set PLLControlOne register */
+ ByteVal = RGB525_REF_SRC_REFCLK
+ | RGB525_PLL_INT_FS_DIRECT;
+ RGB525_SET_REG(Dac, __RGB525_PLLControlOne, ByteVal);
+
+ /* set PLLControlTwo register */
+ RGB525_SET_REG(Dac, __RGB525_PLLControlTwo, RGB525_PLL_INT_FS(0));
+
+ /* set PLLRefDivCount register */
+ RGB525_SET_REG(Dac, __RGB525_PLLRefDivCount, Video->RefDivCount);
+
+ /* set F0 register */
+ RGB525_SET_REG(Dac, __RGB525_F0, Video->PixelClock);
+
+ /* set CursorControl register */
+ RGB525_SET_REG(Dac, __RGB525_CursorControl, RGB525_CURSOR_MODE_OFF);
+
+ //
+ // Initialize timing
+ //
+
+ /* horizontal video timing values */
+
+ GLINT_WRITE(Glint, __GLINT_VTGHLimit, Video->HLimit);
+ GLINT_WRITE(Glint, __GLINT_VTGHSyncStart, Video->HSyncStart);
+ GLINT_WRITE(Glint, __GLINT_VTGHSyncEnd, Video->HSyncEnd);
+ GLINT_WRITE(Glint, __GLINT_VTGHBlankEnd, Video->HBlankEnd);
+
+ /* vertical video timing values */
+
+ GLINT_WRITE(Glint, __GLINT_VTGVLimit, Video->VLimit);
+ GLINT_WRITE(Glint, __GLINT_VTGVSyncStart, Video->VSyncStart);
+ GLINT_WRITE(Glint, __GLINT_VTGVSyncEnd, Video->VSyncEnd);
+ GLINT_WRITE(Glint, __GLINT_VTGVBlankEnd, Video->VBlankEnd);
+
+ /* horizontal clock gate values */
+
+ GLINT_WRITE(Glint, __GLINT_VTGHGateStart, Video->HBlankEnd - 2);
+ GLINT_WRITE(Glint, __GLINT_VTGHGateEnd, Video->HLimit - 2);
+
+ /* vertical clock gate values */
+
+ GLINT_WRITE(Glint, __GLINT_VTGVGateStart, Video->VBlankEnd - 1)
+ GLINT_WRITE(Glint, __GLINT_VTGVGateEnd, Video->VBlankEnd);
+
+ //
+ // Initialize control
+ //
+
+ /* serial clock control */
+
+ SerialClk = GLINT_EXTERNAL_QSF
+ | GLINT_SPLIT_SIZE_128_WORD
+ | GLINT_SCLK_VCLK_DIV_2;
+
+ GLINT_WRITE(Glint, __GLINT_VTGSerialClk, SerialClk);
+
+ /* set sync polarities and unblank screen */
+
+ // UpdatePolarityRegister(Glint,
+ // GLINT_CBLANK_ACTIVE_LOW
+ // | Video->HSyncPolarity
+ // | Video->VSyncPolarity,
+ // GLINT_CBLANK_POLARITY_MASK
+ // | GLINT_HSYNC_POLARITY_MASK
+ // | GLINT_VSYNC_POLARITY_MASK);
+
+ Data = GLINT_CBLANK_ACTIVE_LOW
+ | Video->HSyncPolarity
+ | Video->VSyncPolarity;
+ Mask = GLINT_CBLANK_POLARITY_MASK
+ | GLINT_HSYNC_POLARITY_MASK
+ | GLINT_VSYNC_POLARITY_MASK;
+
+ /* read video polarity control register */
+
+ GLINT_READ(Glint, __GLINT_VTGPolarity, Temp);
+
+ /* replace existing polarity field */
+
+ Temp = (Temp & ~Mask) | (Data & Mask);
+
+ /* write result back to polarity register */
+
+ GLINT_WRITE(Glint, __GLINT_VTGPolarity, Temp);
+
+ /* set FrameRowAddr */
+
+ GLINT_WRITE(Glint, __GLINT_VTGFrameRowAddr, 0);
+
+ //
+ // Initialize RampLut
+ //
+
+ /* initialise palette address */
+
+ RGB525_WRITE(Dac, __RGB525_PalAddrWrite, 0);
+
+ /* ramp colour components using auto-increment */
+
+ for (Index = 0; Index <= 0xff; Index++)
+ {
+ RGB525_WRITE(Dac, __RGB525_PaletteData, Index);
+ RGB525_WRITE(Dac, __RGB525_PaletteData, Index);
+ RGB525_WRITE(Dac, __RGB525_PaletteData, Index);
+ }
+
+ //
+ // Clear the screen.
+ //
+
+ DestinationUlong = (PULONG)VIDEO_MEMORY_BASE;
+
+ Length = (HalpMonitorConfigurationData.VerticalResolution *
+ HalpMonitorConfigurationData.HorizontalResolution -1) * sizeof(USHORT);
+
+ for (Index = 0; Index < (Length / sizeof(ULONG)); Index++)
+ *(DestinationUlong++) = (ULONG)0x000f000f;
+
+ //
+ // Initialize the current display column, row, and ownership values.
+ //
+
+ HalpColumn = 0;
+ HalpRow = 0;
+ HalpDisplayOwnedByHal = TRUE;
+ return;
+
+}
+#endif // _R94A_
+
+//
+// M010
+// for software controlled power supply.
+//
+#if defined(_MRCPOWER_)
+/* Start M007 */
+VOID
+HalpMrcModeChange(
+ UCHAR Mode
+)
+/*++
+
+Routine Description:
+
+ This routine is change Mode bit on MRC Controller.
+
+Arguments:
+
+ Mode - Parameter for setting Mode bit on MRC
+
+Return Value:
+
+ None
+
+--*/
+{
+
+ PHYSICAL_ADDRESS physicalAddress;
+ UCHAR ModeNow;
+ KIRQL OldIrql;
+ ENTRYLO Pte[2];
+
+ //
+ // MRC Controller Mapping, when first call
+ //
+
+ if (HalpMrcControlMapped == FALSE) {
+ physicalAddress.HighPart = 0;
+ physicalAddress.LowPart = MRC_TEMP_PHYSICAL_BASE;
+ HalpMrcControlBase = MmMapIoSpace(physicalAddress,
+ PAGE_SIZE,
+ FALSE);
+ if (HalpMrcControlBase != NULL) {
+ HalpMrcControlMapped = TRUE;
+ }
+ }
+
+ if (HalpMrcControlMapped == TRUE){
+
+ ModeNow = READ_REGISTER_UCHAR(
+ &((PMRC_REGISTERS)HalpMrcControlBase)->Mode
+ );
+
+ //
+ // Set MRC Mode bit
+ //
+ WRITE_REGISTER_UCHAR(
+ &((PMRC_REGISTERS)HalpMrcControlBase)->Mode,
+ ((ModeNow & 0x02) | (Mode << 7)),
+ );
+
+ } else {
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ Pte[0].PFN = MRC_TEMP_PHYSICAL_BASE >> PAGE_SHIFT;
+
+ Pte[0].G = 1;
+ Pte[0].V = 1;
+ Pte[0].D = 1;
+
+ //
+ // set second page to global and not valid.
+ //
+
+ Pte[0].C = UNCACHED_POLICY;
+ Pte[1].G = 1;
+ Pte[1].V = 0;
+
+ //
+ // Map MRC using virtual address of DMA controller.
+ //
+
+ KeFillFixedEntryTb((PHARDWARE_PTE)&Pte[0],
+ (PVOID)DMA_VIRTUAL_BASE,
+ DMA_ENTRY);
+
+ ModeNow = READ_REGISTER_UCHAR(
+ &MRC_CONTROL->Mode // B028
+ );
+
+ //
+ // Set MRC Mode bit
+ //
+ WRITE_REGISTER_UCHAR(
+ &MRC_CONTROL->Mode,
+ ((ModeNow & 0x02) | (Mode << 7)),
+ );
+
+
+ // Start M008
+ //
+ // Resume fixed TLB for DMA
+ //
+
+ Pte[0].PFN = DMA_PHYSICAL_BASE >> PAGE_SHIFT;
+ Pte[0].G = 1;
+ Pte[0].V = 1;
+ Pte[0].D = 1;
+
+ Pte[0].C = UNCACHED_POLICY;
+
+
+ Pte[1].PFN = INTERRUPT_PHYSICAL_BASE >> PAGE_SHIFT;
+ Pte[1].G = 1;
+ Pte[1].V = 1;
+ Pte[1].D = 1;
+
+ Pte[1].C = UNCACHED_POLICY;
+
+ // End M008
+
+ KeFillFixedEntryTb((PHARDWARE_PTE)&Pte[0],
+ (PVOID)DMA_VIRTUAL_BASE,
+ DMA_ENTRY);
+
+ KeLowerIrql(OldIrql);
+ }
+}
+/* End M007 */
+#endif // _MRCPOWER_
+
+VOID
+HalpWritePCIConfigUlongByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PULONG Buffer,
+ IN ULONG Offset
+ )
+
+/*++
+ Routine Description:
+
+ This function writes PCI configuration data.
+
+ Arguments:
+
+ Slot - Supplies a PCI slot number and function number.
+ Buffer - Supplies a pointer to a configuration data to write.
+ Offset - Offset in the PCI configuration header.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ //
+ // check to see if specified slot is valid
+ //
+
+ if (!HalpCheckPCIDevice(Slot)) {
+
+ //
+ // Invalid SlotID return no data
+ //
+
+ *Buffer = 0xffffffff;
+ return ;
+
+ }
+
+ *((PULONG) &ConfigAddressValue) = 0x0;
+
+ ConfigAddressValue.ConfigEnable = 1;
+ ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
+ ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
+ ConfigAddressValue.RegisterNumber = Offset >> 2;
+
+ //
+ // Synchronize with PCI configuration
+ //
+
+// KeRaiseIrql(PROFILE_LEVEL, &OldIrql); // M017
+// KiAcquireSpinLock(&HalpPCIConfigLock);
+
+ WRITE_REGISTER_ULONG(R94A_PCI_ADDR_REG, *((PULONG) &ConfigAddressValue));
+
+// *Buffer = READ_REGISTER_ULONG(R94A_PCI_DATA_REG);
+ WRITE_REGISTER_ULONG(R94A_PCI_DATA_REG, *Buffer);
+
+ //
+ // Release spinlock
+ //
+
+// KiReleaseSpinLock(&HalpPCIConfigLock);
+// KeLowerIrql(OldIrql);
+
+ return;
+}
+VOID
+HalpReadPCIConfigUshortByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUSHORT Buffer,
+ IN ULONG Offset
+ )
+
+/*++
+ Routine Description:
+
+ This function returns PCI configuration data.
+
+ Arguments:
+
+ Slot - Supplies a PCI slot number and function number.
+ Buffer - Supplies a pointer to a configuration data is returned.
+ Offset - Offset in the PCI configuration header.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ //
+ // check to see if specified slot is valid
+ //
+
+ if (!HalpCheckPCIDevice(Slot)) {
+
+ //
+ // Invalid SlotID return no data
+ //
+
+ *Buffer = 0xffff;
+ return ;
+
+ }
+
+ *((PULONG) &ConfigAddressValue) = 0x0;
+
+ ConfigAddressValue.ConfigEnable = 1;
+ ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
+ ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
+ ConfigAddressValue.RegisterNumber = Offset >> 2;
+
+ //
+ // Synchronize with PCI configuration
+ //
+
+// KeRaiseIrql(PROFILE_LEVEL, &OldIrql); // M017
+// KiAcquireSpinLock(&HalpPCIConfigLock);
+
+ WRITE_REGISTER_ULONG(R94A_PCI_ADDR_REG, *((PULONG) &ConfigAddressValue));
+
+ *Buffer = READ_REGISTER_USHORT((PUCHAR)R94A_PCI_DATA_REG + (Offset % sizeof(ULONG)));
+
+ //
+ // Release spinlock
+ //
+
+// KiReleaseSpinLock(&HalpPCIConfigLock);
+// KeLowerIrql(OldIrql);
+
+ return;
+}
+
+VOID
+HalpWritePCIConfigUshortByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUSHORT Buffer,
+ IN ULONG Offset
+ )
+
+/*++
+ Routine Description:
+
+ This function returns PCI configuration data.
+
+ Arguments:
+
+ Slot - Supplies a PCI slot number and function number.
+ Buffer - Supplies a pointer to a configuration data is returned.
+ Offset - Offset in the PCI configuration header.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ //
+ // check to see if specified slot is valid
+ //
+
+ if (!HalpCheckPCIDevice(Slot)) {
+
+ //
+ // Invalid SlotID return no data
+ //
+
+ *Buffer = 0xffff;
+ return ;
+
+ }
+
+ *((PULONG) &ConfigAddressValue) = 0x0;
+
+ ConfigAddressValue.ConfigEnable = 1;
+ ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
+ ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
+ ConfigAddressValue.RegisterNumber = Offset >> 2;
+
+ //
+ // Synchronize with PCI configuration
+ //
+
+// KeRaiseIrql(PROFILE_LEVEL, &OldIrql); // M017
+// KiAcquireSpinLock(&HalpPCIConfigLock);
+
+ WRITE_REGISTER_ULONG(R94A_PCI_ADDR_REG, *((PULONG) &ConfigAddressValue));
+
+// *Buffer = READ_REGISTER_ULONG(R94A_PCI_DATA_REG);
+ WRITE_REGISTER_USHORT((PUCHAR)R94A_PCI_DATA_REG + (Offset % sizeof(ULONG)),*Buffer);
+
+ //
+ // Release spinlock
+ //
+
+// KiReleaseSpinLock(&HalpPCIConfigLock);
+// KeLowerIrql(OldIrql);
+
+ return;
+}
+
+VOID
+HalpReadPCIConfigUcharByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+
+/*++
+ Routine Description:
+
+ This function returns PCI configuration data.
+
+ Arguments:
+
+ Slot - Supplies a PCI slot number and function number.
+ Buffer - Supplies a pointer to a configuration data is returned.
+ Offset - Offset in the PCI configuration header.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ //
+ // check to see if specified slot is valid
+ //
+
+ if (!HalpCheckPCIDevice(Slot)) {
+
+ //
+ // Invalid SlotID return no data
+ //
+
+ *Buffer = 0xff;
+ return ;
+
+ }
+
+ *((PULONG) &ConfigAddressValue) = 0x0;
+
+ ConfigAddressValue.ConfigEnable = 1;
+ ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
+ ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
+ ConfigAddressValue.RegisterNumber = Offset >> 2;
+
+ //
+ // Synchronize with PCI configuration
+ //
+
+// KeRaiseIrql(PROFILE_LEVEL, &OldIrql); // M017
+// KiAcquireSpinLock(&HalpPCIConfigLock);
+
+ WRITE_REGISTER_ULONG(R94A_PCI_ADDR_REG, *((PULONG) &ConfigAddressValue));
+
+ *Buffer = READ_REGISTER_UCHAR((PUCHAR)R94A_PCI_DATA_REG + (Offset % sizeof(ULONG)));
+
+ //
+ // Release spinlock
+ //
+
+// KiReleaseSpinLock(&HalpPCIConfigLock);
+// KeLowerIrql(OldIrql);
+
+ return;
+}
+
+VOID
+HalpWritePCIConfigUcharByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+
+/*++
+ Routine Description:
+
+ This function returns PCI configuration data.
+
+ Arguments:
+
+ Slot - Supplies a PCI slot number and function number.
+ Buffer - Supplies a pointer to a configuration data is returned.
+ Offset - Offset in the PCI configuration header.
+
+ Return Value:
+
+ None.
+
+--*/
+
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ //
+ // check to see if specified slot is valid
+ //
+
+ if (!HalpCheckPCIDevice(Slot)) {
+
+ //
+ // Invalid SlotID return no data
+ //
+
+ *Buffer = 0xff;
+ return ;
+
+ }
+
+ *((PULONG) &ConfigAddressValue) = 0x0;
+
+ ConfigAddressValue.ConfigEnable = 1;
+ ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
+ ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
+ ConfigAddressValue.RegisterNumber = Offset >> 2;
+
+ //
+ // Synchronize with PCI configuration
+ //
+
+// KeRaiseIrql(PROFILE_LEVEL, &OldIrql); // M017
+// KiAcquireSpinLock(&HalpPCIConfigLock);
+
+ WRITE_REGISTER_ULONG(R94A_PCI_ADDR_REG, *((PULONG) &ConfigAddressValue));
+
+// *Buffer = READ_REGISTER_ULONG(R94A_PCI_DATA_REG);
+ WRITE_REGISTER_UCHAR((PUCHAR)R94A_PCI_DATA_REG + (Offset % sizeof(ULONG)),*Buffer);
+
+ //
+ // Release spinlock
+ //
+
+// KiReleaseSpinLock(&HalpPCIConfigLock);
+// KeLowerIrql(OldIrql);
+
+ return;
+}
diff --git a/private/ntos/nthals/halr96b/mips/jxdmadsp.s b/private/ntos/nthals/halr96b/mips/jxdmadsp.s
new file mode 100644
index 000000000..370edd47f
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxdmadsp.s
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\jxdmadsp.s"
diff --git a/private/ntos/nthals/halr96b/mips/jxebsup.c b/private/ntos/nthals/halr96b/mips/jxebsup.c
new file mode 100644
index 000000000..5fa4f8677
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxebsup.c
@@ -0,0 +1,1398 @@
+// #pragma comment(exestr, "@(#) jxebsup.c 1.1 95/09/28 15:36:45 nec")
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ jxebsup.c
+
+Abstract:
+
+ The module provides the EISA bus support for JAZZ systems.
+
+Author:
+
+ Jeff Havens (jhavens) 19-Jun-1991
+
+Revision History:
+
+Modification History for NEC R94A (MIPS R4400):
+
+ H000 Thu Sep 8 10:32:42 JST 1994 kbnes!kishimoto
+ - HalpCreateEisa(PCI)Structures()
+ function name changed.
+ interrupt dispatcher is changed for PCI/EISA.
+ comment out EISA NMI disable code.
+ - HalpEisaDispatch()
+ add the PCI interrupt handler.
+ add the avoidance the IR7 and IR15 spurious interrupt.
+ H001 Tue Oct 11 18:52:39 JST 1994 kbnes!kishimoto
+ - modify original compile error
+ H002 Mon Oct 17 13:54:43 JST 1994 kbnes!kishimoto
+ - Hal(p)EisaPCIXXX() rename to Hal(p)EisaXXX()
+ - modify original compile error
+ S003 Thu Dec 22 11:39:57 JST 1994 kbnes!A.Kuriyama
+ -add beta machine limit
+ S004 Mon Jan 23 13:57:08 JST 1995 kbnes!A.Kuriyama
+ -add raise irql for dummyread for EISA/PCI acknouledge
+ H003 Tue Jan 24 19:04:04 1995 kbnes!kishimoto
+ -Add Enable the PCI interrupts to the CPU
+ M005 Wed Jan 25 21:02:51 JST 1995 kbnes!A.Kuriyama
+ -add 64byte align between dummy read and EISA/PCI Ack.
+ H006 Tue Feb 7 21:04:30 JST 1995 kbnes!kisimoto
+ -bug fix when spurious interrupt occurs
+ S007 kuriyama@oa2.kb.nec.co.jp Thu Apr 06 00:18:14 JST 1995
+ - Disable EISA NMI
+ S008 kuriyama@oa2.kb.nec.co.jp Mon May 22 03:58:30 JST 1995
+ - add panicflag for esm
+ S009 kisimoto@oa2.kb.nec.co.jp Thu Jul 20 19:18:10 JST 1995
+ - Merge build 1057
+ H010 kisimoto@oa2.kb.nec.co.jp Fri Aug 11 17:40:26 1995
+ - Removed M005, etc.
+
+--*/
+
+#include "halp.h"
+#include "eisa.h"
+#include "bugcodes.h"
+
+
+//
+// Define the context structure for use by the interrupt routine.
+//
+
+typedef
+BOOLEAN
+(*PSECONDARY_DISPATCH)(
+ PKINTERRUPT Interrupt
+ );
+
+//
+// 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;
+
+UCHAR EisaNMIMsg[] = "NMI: Eisa IOCHKERR board x\n";
+
+//
+// The following function is called when an EISA NMI occurs.
+//
+
+BOOLEAN
+HalHandleNMI(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+//
+// Define save area for EISA adapter objects.
+//
+
+PADAPTER_OBJECT HalpEisaAdapter[8];
+
+//
+// Define save area for EISA interrupt mask resiters and level\edge control
+// registers.
+//
+
+UCHAR HalpEisaInterrupt1Mask;
+UCHAR HalpEisaInterrupt2Mask;
+UCHAR HalpEisaInterrupt1Level;
+UCHAR HalpEisaInterrupt2Level;
+
+//
+// Define EISA bus interrupt affinity.
+//
+
+KAFFINITY HalpEisaBusAffinity;
+
+PADAPTER_OBJECT
+HalpAllocateEisaAdapter(
+ IN PDEVICE_DESCRIPTION DeviceDescriptor
+ )
+/*++
+
+Routine Description:
+
+ This function allocates an EISA adapter object according to the
+ specification supplied in the device description. The necessary device
+ descriptor information is saved. If there is
+ no existing adapter object for this channel then a new one is allocated.
+ The saved information in the adapter object is used to set the various DMA
+ modes when the channel is allocated or a map transfer is done.
+
+Arguments:
+
+ DeviceDescription - Supplies the description of the device which want to
+ use the DMA adapter.
+
+Return Value:
+
+ Returns a pointer to the newly created adapter object or NULL if one
+ cannot be created.
+
+--*/
+
+{
+ PADAPTER_OBJECT adapterObject;
+ PVOID adapterBaseVa;
+ ULONG channelNumber;
+ ULONG controllerNumber;
+ DMA_EXTENDED_MODE extendedMode;
+ UCHAR adapterMode;
+ BOOLEAN useChannel;
+ BOOLEAN eisaSystem;
+
+ //
+ // Determine if the the channel number is important. Master cards on
+ // Eisa do not use a channel number.
+ //
+
+ if (DeviceDescriptor->InterfaceType == Eisa &&
+ DeviceDescriptor->Master) {
+
+ useChannel = FALSE;
+ } else {
+
+ useChannel = TRUE;
+ }
+
+ //
+ // Channel 4 cannot be used since it is used for chaining. Return null if
+ // it is requested.
+ //
+
+ if ((DeviceDescriptor->DmaChannel == 4 ||
+ DeviceDescriptor->DmaChannel > 7) && useChannel) {
+
+ return(NULL);
+ }
+
+ //
+ // Set the channel number number.
+ //
+
+ channelNumber = DeviceDescriptor->DmaChannel & 0x03;
+
+ //
+ // Set the adapter base address to the Base address register and controller
+ // number.
+ //
+
+ if (!(DeviceDescriptor->DmaChannel & 0x04)) {
+
+ controllerNumber = 1;
+ adapterBaseVa = (PVOID) &((PEISA_CONTROL) HalpEisaControlBase)->Dma1BasePort;
+
+ } else {
+
+ controllerNumber = 2;
+ adapterBaseVa = &((PEISA_CONTROL) HalpEisaControlBase)->Dma2BasePort;
+
+ }
+
+ //
+ // Determine if a new adapter object is necessary. If so then allocate it.
+ //
+
+ if (useChannel && HalpEisaAdapter[DeviceDescriptor->DmaChannel] != NULL) {
+
+ adapterObject = HalpEisaAdapter[DeviceDescriptor->DmaChannel];
+
+ } else {
+
+ //
+ // Allocate an adapter object.
+ //
+
+ adapterObject = (PADAPTER_OBJECT) HalpAllocateAdapter(
+ 0,
+ adapterBaseVa,
+ NULL
+ );
+
+ if (adapterObject == NULL) {
+
+ return(NULL);
+
+ }
+
+ if (useChannel) {
+
+ HalpEisaAdapter[DeviceDescriptor->DmaChannel] = adapterObject;
+
+ }
+
+ }
+
+
+ //
+ // If the channel is not used then indicate the this is an Eisa bus
+ // master by setting the page port and mode to cascade even though
+ // it is not used.
+ //
+
+ if (!useChannel) {
+ adapterObject->PagePort = (PVOID) (~0x0);
+ ((PDMA_EISA_MODE) &adapterMode)->RequestMode = CASCADE_REQUEST_MODE;
+ return(adapterObject);
+ }
+
+ //
+ // Setup the pointers to all the random registers.
+ //
+
+ adapterObject->ChannelNumber = (UCHAR)channelNumber;
+
+ if (controllerNumber == 1) {
+
+ switch ((UCHAR)channelNumber) {
+
+ case 0:
+ adapterObject->PagePort = &((PDMA_PAGE) 0)->Channel0;
+ break;
+
+ case 1:
+ adapterObject->PagePort = &((PDMA_PAGE) 0)->Channel1;
+ break;
+
+ case 2:
+ adapterObject->PagePort = &((PDMA_PAGE) 0)->Channel2;
+ break;
+
+ case 3:
+ adapterObject->PagePort = &((PDMA_PAGE) 0)->Channel3;
+ break;
+ }
+
+ //
+ // Set the adapter number.
+ //
+
+ adapterObject->AdapterNumber = 1;
+
+ //
+ // Save the extended mode register address.
+ //
+
+ adapterBaseVa =
+ &((PEISA_CONTROL) HalpEisaControlBase)->Dma1ExtendedModePort;
+
+ } else {
+
+ switch ((UCHAR)channelNumber) { // H001
+ case 1:
+ adapterObject->PagePort = &((PDMA_PAGE) 0)->Channel5;
+ break;
+
+ case 2:
+ adapterObject->PagePort = &((PDMA_PAGE) 0)->Channel6;
+ break;
+
+ case 3:
+ adapterObject->PagePort = &((PDMA_PAGE) 0)->Channel7;
+ break;
+ }
+
+ //
+ // Set the adapter number.
+ //
+
+ adapterObject->AdapterNumber = 2;
+
+ //
+ // Save the extended mode register address.
+ //
+ adapterBaseVa =
+ &((PEISA_CONTROL) HalpEisaControlBase)->Dma2ExtendedModePort;
+
+ }
+
+ //
+ // Initialzie the extended mode port.
+ //
+
+ *((PUCHAR) &extendedMode) = 0;
+
+ extendedMode.ChannelNumber = (UCHAR)channelNumber;
+
+ switch (DeviceDescriptor->DmaSpeed) {
+ case Compatible:
+ extendedMode.TimingMode = COMPATIBLITY_TIMING;
+ break;
+
+ case TypeA:
+ extendedMode.TimingMode = TYPE_A_TIMING;
+ break;
+
+ case TypeB:
+ extendedMode.TimingMode = TYPE_B_TIMING;
+ break;
+
+ case TypeC:
+ extendedMode.TimingMode = BURST_TIMING;
+ break;
+
+ default:
+ ObDereferenceObject( adapterObject );
+ return(NULL);
+
+ }
+
+ switch (DeviceDescriptor->DmaWidth) {
+ case Width8Bits:
+ extendedMode.TransferSize = BY_BYTE_8_BITS;
+ break;
+
+ case Width16Bits:
+ extendedMode.TransferSize = BY_BYTE_16_BITS;
+ break;
+
+ case Width32Bits:
+ extendedMode.TransferSize = BY_BYTE_32_BITS;
+ break;
+
+ default:
+ ObDereferenceObject( adapterObject );
+ return(NULL);
+
+ }
+
+ WRITE_REGISTER_UCHAR( adapterBaseVa, *((PUCHAR) &extendedMode));
+
+ //
+ // Initialize the adapter mode register value to the correct parameters,
+ // and save them in the adapter object.
+ //
+
+ adapterMode = 0;
+ ((PDMA_EISA_MODE) &adapterMode)->Channel = adapterObject->ChannelNumber;
+
+ if (DeviceDescriptor->Master) {
+
+ ((PDMA_EISA_MODE) &adapterMode)->RequestMode = CASCADE_REQUEST_MODE;
+
+ //
+ // Set the mode, and enable the request.
+ //
+
+ if (adapterObject->AdapterNumber == 1) {
+
+ //
+ // This request is for DMA controller 1
+ //
+
+ PDMA1_CONTROL dmaControl;
+
+ dmaControl = adapterObject->AdapterBaseVa;
+
+ WRITE_REGISTER_UCHAR( &dmaControl->Mode, adapterMode );
+
+ //
+ // Unmask the DMA channel.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->SingleMask,
+ (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber)
+ );
+
+ } else {
+
+ //
+ // This request is for DMA controller 1
+ //
+
+ PDMA2_CONTROL dmaControl;
+
+ dmaControl = adapterObject->AdapterBaseVa;
+
+ WRITE_REGISTER_UCHAR( &dmaControl->Mode, adapterMode );
+
+ //
+ // Unmask the DMA channel.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->SingleMask,
+ (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber)
+ );
+
+ }
+
+ } else if (DeviceDescriptor->DemandMode) {
+
+ ((PDMA_EISA_MODE) &adapterMode)->RequestMode = DEMAND_REQUEST_MODE;
+
+ } else {
+
+ ((PDMA_EISA_MODE) &adapterMode)->RequestMode = SINGLE_REQUEST_MODE;
+
+ }
+
+ if (DeviceDescriptor->AutoInitialize) {
+
+ ((PDMA_EISA_MODE) &adapterMode)->AutoInitialize = 1;
+
+ }
+
+ adapterObject->AdapterMode = adapterMode;
+
+ return(adapterObject);
+}
+
+BOOLEAN
+HalpCreateEisaStructures (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the structures necessary for EISA operations
+ and connects the intermediate interrupt dispatcher. It also initializes the
+ EISA interrupt controller.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the second level interrupt dispatcher is connected, then a value of
+ TRUE is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ UCHAR DataByte;
+ ULONG DataLong;
+ KIRQL oldIrql;
+
+#if !defined(_DUO_) && !defined(_R94A_) // H000
+
+ //
+ // Initialize the EISA NMI interrupt.
+ //
+
+ KeInitializeInterrupt( &HalpEisaNmiInterrupt,
+ HalHandleNMI,
+ NULL,
+ NULL,
+ EISA_NMI_LEVEL,
+ 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.
+ //
+
+// DataByte = 0;
+ //
+ // TEMPTEMP Disable the NMI because this is causing machines in the build
+ // lab to fail.
+ //
+ DataByte = 0x80;
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable,
+ DataByte
+ );
+
+#else
+
+ //
+ // Clear the Eisa NMI disable bit. This bit is the high order of the
+ // NMI enable register.
+ //
+
+// DataByte = 0;
+ //
+ // TEMPTEMP Disable the NMI because this is causing machines in the build
+ // lab to fail.
+ //
+ DataByte = 0x80;
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable,
+ DataByte
+ );
+
+#endif
+
+ //
+ // Directly connect the EISA interrupt dispatcher to the level for
+ // EISA bus interrupt.
+ //
+ // N.B. This vector is reserved for exclusive use by the HAL (see
+ // interrupt initialization.
+ //
+
+ PCR->InterruptRoutine[EISA_DEVICE_LEVEL] =
+ (PKINTERRUPT_ROUTINE)HalpEisaDispatch;
+
+ //
+ // start H003
+ // Enable the following PCI interrupts to the CPU.
+ // Target abort, Master abort
+ // SRetry overflow, ERR, PERR
+ //
+
+ DataLong = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable.Long);
+ DataLong |= ENABLE_PERR_INTERRUPTS;
+ DataLong |= ENABLE_SERR_INTERRUPTS;
+ DataLong |= ENABLE_RETRY_OVERFLOW_EISA_INTERRUPTS;
+ DataLong |= ENABLE_MASTER_ABORT_INTERRUPTS;
+ DataLong |= ENABLE_TARGET_ABORT_INTERRUPTS;
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable.Long,
+ DataLong);
+
+ //
+ // Raise the IRQL while the EISA interrupt controller is initalized.
+ //
+
+ KeRaiseIrql(EISA_DEVICE_LEVEL, &oldIrql);
+
+ //
+ // Initialize the EISA 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_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0,
+ DataByte
+ );
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort0,
+ DataByte
+ );
+
+ //
+ // The second intitialization control word sets the iterrupt vector to
+ // 0-15.
+ //
+
+ DataByte = 0;
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ DataByte
+ );
+
+ DataByte = 0x08;
+
+ WRITE_REGISTER_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_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ DataByte
+ );
+
+ DataByte = SLAVE_IRQL_LEVEL;
+
+ WRITE_REGISTER_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_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ DataByte
+ );
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ DataByte
+ );
+
+
+ //
+ // Disable all of the interrupts except the slave.
+ //
+
+ HalpEisaInterrupt1Mask = (UCHAR)~(1 << SLAVE_IRQL_LEVEL);
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ HalpEisaInterrupt1Mask
+ );
+
+ HalpEisaInterrupt2Mask = 0xFF;
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ HalpEisaInterrupt2Mask
+ );
+
+ //
+ // Initialize the edge/level register masks to 0 which is the default
+ // edge sensitive value.
+ //
+
+ HalpEisaInterrupt1Level = 0;
+ HalpEisaInterrupt2Level = 0;
+
+ //
+ // Set EISA bus interrupt affinity.
+ //
+
+ HalpEisaBusAffinity = PCR->SetMember;
+
+ //
+ // Restore IRQL level.
+ //
+
+ KeLowerIrql(oldIrql);
+
+ //
+ // Initialize the DMA mode registers to a default value.
+ // Disable all of the DMA channels except channel 4 which is that
+ // cascade of channels 0-3.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Dma1BasePort.AllMask,
+ 0x0F
+ );
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Dma2BasePort.AllMask,
+ 0x0E
+ );
+
+#if defined(_DUO_)
+
+ //
+ // Enable the EISA interrupts to the CPU.
+ //
+
+ DataLong = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InterruptEnable.Long);
+ DataLong |= ENABLE_EISA_INTERRUPTS;
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InterruptEnable.Long,
+ DataLong);
+
+#endif
+
+ return(TRUE);
+}
+
+BOOLEAN
+HalpEisaDispatch(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is entered as the result of an interrupt being generated
+ via the vector that is directly connected to EISA device interrupt.
+
+ N.B. This interrupt is directly connected and therefore, no argument
+ values are defined.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ Returns the value returned from the second level routine.
+
+--*/
+
+{
+
+ PULONG dispatchCode;
+ USHORT interruptVector;
+ PKINTERRUPT interruptObject;
+ BOOLEAN returnValue;
+
+#if defined(_DUO_)
+
+ PUSHORT Acknowledge = (PUSHORT)&DMA_CONTROL->EisaInterruptAcknowledge.Long;
+
+ //
+ // Read the interrupt vector.
+ //
+
+ interruptVector = READ_REGISTER_USHORT(Acknowledge);
+
+#else
+
+ PUCHAR Acknowledge = (PUCHAR)&DMA_CONTROL->InterruptAcknowledge.Long;
+
+ //
+ // Read the interrupt vector.
+ //
+
+ interruptVector = READ_REGISTER_UCHAR(Acknowledge);
+
+#endif
+
+ //
+ // If the vector is nonzero, then it is either an EISA interrupt
+ // of an NMI interrupt. Otherwise, the interrupt is no longer
+ // present.
+ //
+
+ if (interruptVector != 0) {
+
+ //
+ // If the interrupt vector is 0x8000 then the interrupt is an NMI.
+ // Otherwise, dispatch the interrupt to the appropriate interrupt
+ // handler.
+ //
+
+ if (interruptVector != 0x8000) {
+
+ //
+ // H000
+ // If the interrupt vector is 0x4000 then this is an PCI interrupt.
+ // Call the PCI interrupt handler.
+ //
+
+ if (interruptVector != 0x4000) {
+
+ //
+ // Mask the upper bits off since the vector is only a byte and
+ // dispatch to the secondary interrupt service routine.
+ //
+
+ interruptVector &= 0xff;
+
+ //
+ // H000
+ // check to see if this is a spurious interrupt
+ //
+
+ if (interruptVector == 7 || interruptVector == 15){
+ PVOID IsrPortAddressVa;
+ UCHAR IsrValue;
+
+ #define OCW3_READ_ISR 0x0b
+ #define OCW3_READ_IRR 0x0a
+
+ IsrPortAddressVa = (interruptVector == 7) ?
+ &(((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0):
+ &(((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort0); // H006
+
+ //
+ // Change mode OCW3 register, bacause we want to read ISR
+ // read ISR on 8259.
+ //
+
+ WRITE_REGISTER_UCHAR(IsrPortAddressVa, OCW3_READ_ISR);
+ IsrValue = READ_REGISTER_UCHAR( IsrPortAddressVa );
+
+ //
+ // resume mode OCW3 register to IRR
+ //
+
+ WRITE_REGISTER_UCHAR(IsrPortAddressVa, OCW3_READ_IRR);
+
+ //
+ // check to see if ISR is zero, then we do not call driver.
+ //
+
+ if ( !IsrValue ){
+
+ goto NotCallDriver;
+
+ }
+ }
+
+ dispatchCode = (PULONG)(PCR->InterruptRoutine[EISA_VECTORS + interruptVector]);
+ interruptObject = CONTAINING_RECORD(dispatchCode,
+ KINTERRUPT,
+ DispatchCode);
+
+ returnValue = ((PSECONDARY_DISPATCH)interruptObject->DispatchAddress)(interruptObject);
+
+NotCallDriver:
+
+ //
+ // Dismiss the interrupt in the EISA interrupt controllers.
+ //
+ // If this is a cascaded interrupt then the interrupt must be
+ // dismissed in both controllers.
+ //
+
+ if (interruptVector & 0x08) {
+ WRITE_REGISTER_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort0,
+ NONSPECIFIC_END_OF_INTERRUPT);
+ }
+
+ WRITE_REGISTER_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0,
+ NONSPECIFIC_END_OF_INTERRUPT);
+
+
+ } else {
+ returnValue = HalpPCIDispatch(NULL, NULL);
+ }
+
+ } else {
+ returnValue = HalHandleNMI(NULL, NULL);
+ }
+
+ } else {
+ returnValue = FALSE;
+ }
+
+ return returnValue;
+}
+
+VOID
+HalpDisableEisaInterrupt(
+ IN ULONG Vector
+ )
+
+/*++
+
+Routine Description:
+
+ This function Disables the EISA bus specified EISA bus interrupt.
+
+Arguments:
+
+ Vector - Supplies the vector of the ESIA interrupt that is Disabled.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Calculate the EISA interrupt vector.
+ //
+
+ Vector -= EISA_VECTORS;
+
+ //
+ // Determine if this vector is for interrupt controller 1 or 2.
+ //
+
+ if (Vector & 0x08) {
+
+ //
+ // The interrupt is in controller 2.
+ //
+
+ Vector &= 0x7;
+
+ HalpEisaInterrupt2Mask |= (UCHAR) 1 << Vector;
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ HalpEisaInterrupt2Mask
+ );
+
+ } else {
+
+ //
+ // The interrupt is in controller 1.
+ //
+
+ Vector &= 0x7;
+
+ HalpEisaInterrupt1Mask |= (ULONG) 1 << Vector;
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ HalpEisaInterrupt1Mask
+ );
+
+ }
+
+}
+
+VOID
+HalpEisaMapTransfer(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN BOOLEAN WriteToDevice
+ )
+
+/*++
+
+Routine Description:
+
+ This function programs the EISA DMA controller for a transfer.
+
+Arguments:
+
+ Adapter - Supplies the DMA adapter object to be programed.
+
+ Offset - Supplies the logical address to use for the transfer.
+
+ Length - Supplies the length of the transfer in bytes.
+
+ WriteToDevice - Indicates the direction of the transfer.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ PUCHAR BytePtr;
+ UCHAR adapterMode;
+
+ BytePtr = (PUCHAR) &Offset;
+
+ ASSERT(Offset >= 0x100000);
+
+ adapterMode = AdapterObject->AdapterMode;
+
+ //
+ // Check to see if this request is for a master I/O card.
+ //
+
+ if (((PDMA_EISA_MODE) &adapterMode)->RequestMode == CASCADE_REQUEST_MODE) {
+
+ //
+ // Set the mode, Disable the request and return.
+ //
+
+ if (AdapterObject->AdapterNumber == 1) {
+
+ //
+ // This request is for DMA controller 1
+ //
+
+ PDMA1_CONTROL dmaControl;
+
+ dmaControl = AdapterObject->AdapterBaseVa;
+
+ WRITE_REGISTER_UCHAR( &dmaControl->Mode, adapterMode );
+
+ //
+ // Unmask the DMA channel.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->SingleMask,
+ (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
+ );
+
+ } else {
+
+ //
+ // This request is for DMA controller 1
+ //
+
+ PDMA2_CONTROL dmaControl;
+
+ dmaControl = AdapterObject->AdapterBaseVa;
+
+ WRITE_REGISTER_UCHAR( &dmaControl->Mode, adapterMode );
+
+ //
+ // Unmask the DMA channel.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->SingleMask,
+ (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
+ );
+
+ }
+
+ return;
+ }
+
+
+ //
+ // Determine the mode based on the transfer direction.
+ //
+
+ ((PDMA_EISA_MODE) &adapterMode)->TransferType = WriteToDevice ?
+ WRITE_TRANSFER : READ_TRANSFER;
+
+ //
+ // Determine the controller number based on the Adapter base va.
+ //
+
+ if (AdapterObject->AdapterNumber == 1) {
+
+ //
+ // This request is for DMA controller 1
+ //
+
+ PDMA1_CONTROL dmaControl;
+
+ dmaControl = AdapterObject->AdapterBaseVa;
+
+ WRITE_REGISTER_UCHAR( &dmaControl->ClearBytePointer, 0 );
+
+ WRITE_REGISTER_UCHAR( &dmaControl->Mode, adapterMode );
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseAddress,
+ BytePtr[0]
+ );
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseAddress,
+ BytePtr[1]
+ );
+
+ WRITE_REGISTER_UCHAR(
+ ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageLowPort) +
+ (ULONG)AdapterObject->PagePort,
+ BytePtr[2]
+ );
+
+ //
+ // Write the high page register with zero value. This enable a special mode
+ // which allows ties the page register and base count into a single 24 bit
+ // address register.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort) +
+ (ULONG)AdapterObject->PagePort,
+ 0
+ );
+
+
+ //
+ // Notify DMA chip of the length to transfer.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseCount,
+ (UCHAR) ((Length - 1) & 0xff)
+ );
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseCount,
+ (UCHAR) ((Length - 1) >> 8)
+ );
+
+
+ //
+ // Set the DMA chip to read or write mode; and unmask it.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->SingleMask,
+ (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
+ );
+
+ } else {
+
+ //
+ // This request is for DMA controller 1
+ //
+
+ PDMA2_CONTROL dmaControl;
+
+ dmaControl = AdapterObject->AdapterBaseVa;
+
+ WRITE_REGISTER_UCHAR( &dmaControl->ClearBytePointer, 0 );
+
+ WRITE_REGISTER_UCHAR( &dmaControl->Mode, adapterMode );
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseAddress,
+ BytePtr[0]
+ );
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseAddress,
+ BytePtr[1]
+ );
+
+ WRITE_REGISTER_UCHAR(
+ ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageLowPort) +
+ (ULONG)AdapterObject->PagePort,
+ BytePtr[2]
+ );
+
+ //
+ // Write the high page register with zero value. This enable a special mode
+ // which allows ties the page register and base count into a single 24 bit
+ // address register.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort) +
+ (ULONG)AdapterObject->PagePort,
+ 0
+ );
+
+
+ //
+ // Notify DMA chip of the length to transfer.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseCount,
+ (UCHAR) ((Length - 1) & 0xff)
+ );
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseCount,
+ (UCHAR) ((Length - 1) >> 8)
+ );
+
+
+ //
+ // Set the DMA chip to read or write mode; and unmask it.
+ //
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->SingleMask,
+ (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
+ );
+ }
+
+}
+
+VOID
+HalpEnableEisaInterrupt(
+ IN ULONG Vector,
+ IN KINTERRUPT_MODE InterruptMode
+ )
+
+/*++
+
+Routine Description:
+
+ This function enables the EISA bus specified EISA bus interrupt and sets
+ the level/edge register to the requested value.
+
+Arguments:
+
+ Vector - Supplies the vector of the ESIA interrupt that is enabled.
+
+ InterruptMode - Supplies the mode of the interrupt; LevelSensitive or
+ Latched.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Calculate the EISA interrupt vector.
+ //
+
+ Vector -= EISA_VECTORS;
+
+ //
+ // Determine if this vector is for interrupt controller 1 or 2.
+ //
+
+ if (Vector & 0x08) {
+
+ //
+ // The interrupt is in controller 2.
+ //
+
+ Vector &= 0x7;
+
+ HalpEisaInterrupt2Mask &= (UCHAR) ~(1 << Vector);
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort1,
+ HalpEisaInterrupt2Mask
+ );
+
+ //
+ // Set the level/edge control register.
+ //
+
+ if (InterruptMode == LevelSensitive) {
+
+ HalpEisaInterrupt2Level |= (UCHAR) (1 << Vector);
+
+ } else {
+
+ HalpEisaInterrupt2Level &= (UCHAR) ~(1 << Vector);
+
+ }
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2EdgeLevel,
+ HalpEisaInterrupt2Level
+ );
+
+ } else {
+
+ //
+ // The interrupt is in controller 1.
+ //
+
+ Vector &= 0x7;
+
+ HalpEisaInterrupt1Mask &= (UCHAR) ~(1 << Vector);
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort1,
+ HalpEisaInterrupt1Mask
+ );
+
+ //
+ // Set the level/edge control register.
+ //
+
+ if (InterruptMode == LevelSensitive) {
+
+ HalpEisaInterrupt1Level |= (UCHAR) (1 << Vector);
+
+ } else {
+
+ HalpEisaInterrupt1Level &= (UCHAR) ~(1 << Vector);
+
+ }
+
+ WRITE_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1EdgeLevel,
+ HalpEisaInterrupt1Level
+ );
+ }
+
+}
+
+BOOLEAN
+HalHandleNMI(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ )
+/*++
+
+Routine Description:
+
+ This function is called when an EISA NMI occurs. It print 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.
+
+--*/
+{
+ UCHAR StatusByte;
+ UCHAR EisaPort;
+ ULONG port;
+
+ HalpChangePanicFlag(16, 0x01, 0x10); // S008
+
+ StatusByte = READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);
+
+ if (StatusByte & 0x80) {
+ HalDisplayString ("NMI: Parity Check / Parity Error\n");
+ }
+
+ if (StatusByte & 0x40) {
+ HalDisplayString ("NMI: Channel Check / IOCHK\n");
+ }
+
+ //
+ // This is an Eisa machine, check for extnded nmi information...
+ //
+
+ StatusByte = READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl);
+
+ if (StatusByte & 0x80) {
+ HalDisplayString ("NMI: Fail-safe timer\n");
+ }
+
+ if (StatusByte & 0x40) {
+ HalDisplayString ("NMI: Bus Timeout\n");
+ }
+
+ if (StatusByte & 0x20) {
+ HalDisplayString ("NMI: Software NMI generated\n");
+ }
+
+ //
+ // Look for any Eisa expansion board. See if it asserted NMI.
+ //
+
+ for (EisaPort = 0; EisaPort <= 0xf; EisaPort++) {
+ port = (EisaPort << 12) + 0xC80;
+ port += (ULONG) HalpEisaControlBase;
+ WRITE_PORT_UCHAR ((PUCHAR) port, 0xff);
+ StatusByte = READ_PORT_UCHAR ((PUCHAR) port);
+
+ if ((StatusByte & 0x80) == 0) {
+ //
+ // Found valid Eisa board, Check to see if it's
+ // if IOCHKERR is asserted.
+ //
+
+ StatusByte = READ_PORT_UCHAR ((PUCHAR) port+4);
+ if (StatusByte & 0x2) {
+ EisaNMIMsg[25] = (EisaPort > 9 ? 'A'-10 : '0') + EisaPort;
+ HalDisplayString (EisaNMIMsg);
+ }
+ }
+ }
+
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+ return(TRUE);
+}
diff --git a/private/ntos/nthals/halr96b/mips/jxenvirv.c b/private/ntos/nthals/halr96b/mips/jxenvirv.c
new file mode 100644
index 000000000..c78505bcf
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxenvirv.c
@@ -0,0 +1,800 @@
+// #pragma comment(exestr, "@(#) jxenvirv.c 1.1 95/09/28 15:37:20 nec")
+/*++
+
+Copyright (c) 1991-1993 Microsoft Corporation
+
+Module Name:
+
+ jxenvirv.c
+
+Abstract:
+
+ This module implements the HAL get and set environment variable routines
+ for a MIPS system.
+
+Author:
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ M001 95.4.25 Y.Nakatani
+ - Add Interface of NVRAM for ESM
+ M002 kuriyama@oa2.kb.nec.co.jp Sun May 21 20:46:25 JST 1995
+ - Change Nvram virtual address
+ M003 kisimoto@oa2.kb.nec.co.jp Sat Aug 12 19:25:54 JST 1995
+ - Removed _J94C_ definitions.
+ _J94C_ definition indicates that the status of
+ the dump switch can acknowledge from Self-test
+ register.
+
+--*/
+
+#include "halp.h"
+#include "arccodes.h"
+#include "jazznvr.h"
+#include "string.h"
+
+//
+// Define local upcase macro.
+//
+
+#define UpCase(c) ((c) >= 'a' && (c) <= 'z' ? (c) - ('a' - 'A') : (c))
+
+// M002 +++
+KIRQL
+HalpEsmMapNvram (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to map the ESM NVRAM into a wired TB entry.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ The previous IRQL is returned as the function value.
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+ ENTRYLO NvramPte[2];
+
+ //
+ // Construct a pair of PTE's to map NVRAM.
+ //
+
+ NvramPte[0].X1 = 0;
+ NvramPte[0].PFN = 0x80013000 >> PAGE_SHIFT;
+ NvramPte[0].G = 0;
+ NvramPte[0].V = 1;
+ NvramPte[0].D = 1;
+ NvramPte[0].C = UNCACHED_POLICY;
+ NvramPte[1] = NvramPte[0];
+ NvramPte[1].PFN += 1;
+
+ //
+ // Raise IRQL to the highest level, allocate a TB entry, map NVRAM
+ // using the alocated entry, and return the previous IRQL.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ KeFillFixedEntryTb((PHARDWARE_PTE)&NvramPte[0],
+ (PVOID)NVRAM_VIRTUAL_BASE,
+ HalpAllocateTbEntry());
+
+ return OldIrql;
+}
+// M002 ---
+
+KIRQL
+HalpMapNvram (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to map the NVRAM into a wired TB entry.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ The previous IRQL is returned as the function value.
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+ ENTRYLO NvramPte[2];
+
+ //
+ // Construct a pair of PTE's to map NVRAM.
+ //
+
+ NvramPte[0].X1 = 0;
+ NvramPte[0].PFN = NVRAM_PHYSICAL_BASE >> PAGE_SHIFT;
+ NvramPte[0].G = 0;
+ NvramPte[0].V = 1;
+ NvramPte[0].D = 1;
+ NvramPte[0].C = UNCACHED_POLICY;
+ NvramPte[1] = NvramPte[0];
+ NvramPte[1].PFN += 1;
+
+ //
+ // Raise IRQL to the highest level, allocate a TB entry, map NVRAM
+ // using the alocated entry, and return the previous IRQL.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ KeFillFixedEntryTb((PHARDWARE_PTE)&NvramPte[0],
+ (PVOID)NVRAM_VIRTUAL_BASE,
+ HalpAllocateTbEntry());
+
+ return OldIrql;
+}
+
+VOID
+HalpUnmapNvram (
+ IN KIRQL OldIrql
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to unmap the NVRAM from a wired entry in
+ the TB.
+
+Arguments:
+
+ OldIrql - Supplies the previous IRQL value.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Free the wired TB entry that was allocated to map NVRAM and lower
+ // IRQL to its previous level.
+ //
+
+ HalpFreeTbEntry();
+ KeLowerIrql(OldIrql);
+ return;
+}
+
+ARC_STATUS
+HalpEnvironmentCheckChecksum (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine checks the NVRAM environment area checksum.
+
+ N.B. The NVRAM must be mapped before this routine is called.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ ESUCCESS is returned if the checksum matches. Otherwise, EIO is returned.
+
+--*/
+
+{
+
+ ULONG Checksum1;
+ ULONG Checksum2;
+ PUCHAR Environment;
+ ULONG Index;
+ PNV_CONFIGURATION NvConfiguration;
+
+ //
+ // Compute the NVRAM environment area checksum.
+ //
+
+ NvConfiguration = (PNV_CONFIGURATION)NVRAM_VIRTUAL_BASE;
+ Environment = &NvConfiguration->Environment[0];
+ Checksum1 = 0;
+ for (Index = 0; Index < LENGTH_OF_ENVIRONMENT; Index += 1) {
+ Checksum1 += (ULONG)READ_REGISTER_UCHAR(&Environment[Index]);
+ }
+
+ //
+ // Merge the checksum bytes from the NVRAM and compare to computed value.
+ //
+
+ Checksum2 = (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[0]) |
+ (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[1]) << 8 |
+ (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[2]) << 16 |
+ (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[3]) << 24;
+
+ //
+ // If the checksum mismatches, then return an I/O error. Otherwise,
+ // return a success status.
+ //
+
+ if (Checksum1 != Checksum2) {
+ return EIO;
+
+ } else {
+ return ESUCCESS;
+ }
+}
+
+VOID
+HalpEnvironmentSetChecksum (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets the NVRAM environment area checksum.
+
+ N.B. The NVRAM must be mapped before this routine is called.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG Checksum;
+ PUCHAR Environment;
+ ULONG Index;
+ PNV_CONFIGURATION NvConfiguration;
+
+ //
+ // Compute the NVRAM environment area checksum.
+ //
+
+ NvConfiguration = (PNV_CONFIGURATION)NVRAM_VIRTUAL_BASE;
+ Environment = &NvConfiguration->Environment[0];
+ Checksum = 0;
+ for (Index = 0; Index < LENGTH_OF_ENVIRONMENT; Index += 1) {
+ Checksum += (ULONG)READ_REGISTER_UCHAR(&Environment[Index]);
+ }
+
+ //
+ // Write the NVRAM environment area checksum.
+ //
+
+ WRITE_REGISTER_UCHAR(&NvConfiguration->Checksum2[0],
+ (UCHAR)(Checksum & 0xFF));
+
+ WRITE_REGISTER_UCHAR(&NvConfiguration->Checksum2[1],
+ (UCHAR)((Checksum >> 8) & 0xFF));
+
+ WRITE_REGISTER_UCHAR(&NvConfiguration->Checksum2[2],
+ (UCHAR)((Checksum >> 16) & 0xFF));
+
+ WRITE_REGISTER_UCHAR(&NvConfiguration->Checksum2[3],
+ (UCHAR)(Checksum >> 24));
+
+ return;
+}
+
+ARC_STATUS
+HalpFindEnvironmentVariable (
+ IN PCHAR Variable,
+ OUT PULONG VariableIndex,
+ OUT PULONG ValueIndex
+ )
+
+/*++
+
+Routine Description:
+
+ This routine performs a case insensitive search of the NVRAM environment
+ area for the specified variable name.
+
+ N.B. The NVRAM must be mapped before this routine is called.
+
+
+Arguments:
+
+ Variable - Supplies a pointer to a zero terminated string containing an
+ environment variable name.
+
+Return Value:
+
+ ESUCCESS is returned if the specified variable name is located. Otherwise,
+ ENOENT is returned.
+
+--*/
+
+{
+
+ PUCHAR Environment;
+ ULONG Index;
+ PUCHAR Name;
+
+ //
+ // If the variable name is null, then return no entry found.
+ //
+
+ if (*Variable == 0) {
+ return ENOENT;
+ }
+
+ //
+ // Search the environment section of the NVRAM for a variable name match.
+ //
+
+ Environment = &((PNV_CONFIGURATION)NVRAM_VIRTUAL_BASE)->Environment[0];
+ Index = 0;
+ do {
+
+ //
+ // Set name to the beginning of the variable name and record the
+ // current index value.
+ //
+
+ Name = Variable;
+ *VariableIndex = Index;
+
+ //
+ // Search until the end of the current environment variable, the
+ // end of the specified variable name, or the end of the NVRAM is
+ // reached.
+ //
+
+ while ((Index < LENGTH_OF_ENVIRONMENT) &&
+ (READ_REGISTER_UCHAR(&Environment[Index]) != 0) && (*Name != 0)) {
+ if (READ_REGISTER_UCHAR(&Environment[Index]) != UpCase(*Name)) {
+ break;
+ }
+
+ Name += 1;
+ Index += 1;
+ }
+
+ //
+ // Check for a match which is signified by the end of the variable
+ // name and the equal separator in the current environment variable.
+ //
+
+ if ((*Name == 0) && (READ_REGISTER_UCHAR(&Environment[Index]) == '=')) {
+ *ValueIndex = Index + 1;
+ return ESUCCESS;
+ }
+
+ //
+ // Advance to the start of the next variable.
+ //
+
+ while ((Index < LENGTH_OF_ENVIRONMENT) &&
+ (READ_REGISTER_UCHAR(&Environment[Index]) != 0)) {
+ Index += 1;
+ }
+
+ Index += 1;
+ } while (Index < LENGTH_OF_ENVIRONMENT);
+
+ return ENOENT;
+}
+
+ARC_STATUS
+HalGetEnvironmentVariable (
+ IN PCHAR Variable,
+ IN USHORT Length,
+ OUT PCHAR Buffer
+ )
+
+/*++
+
+Routine Description:
+
+ This function locates an environment variable and returns its value.
+
+Arguments:
+
+ Variable - Supplies a pointer to a zero terminated environment variable
+ name.
+
+ Length - Supplies the length of the value buffer in bytes.
+
+ Buffer - Supplies a pointer to a buffer that receives the variable value.
+
+Return Value:
+
+ ESUCCESS is returned if the enviroment variable is located. Otherwise,
+ ENOENT is returned.
+
+--*/
+
+{
+
+ PUCHAR Environment;
+ ULONG Index;
+ KIRQL OldIrql;
+ ARC_STATUS Status;
+ ULONG ValueIndex;
+ ULONG VariableIndex;
+
+ //
+ // Map the NVRAM into the address space of the current process.
+ //
+
+ OldIrql = HalpMapNvram();
+
+ //
+ // If the checksum does not match or the specified variable cannot
+ // be located, then set the status to no entry found. Otherwise, copy
+ // the respective variable value to the specified output buffer.
+ //
+
+ Environment = &((PNV_CONFIGURATION)NVRAM_VIRTUAL_BASE)->Environment[0];
+ if ((HalpEnvironmentCheckChecksum() != ESUCCESS) ||
+ (HalpFindEnvironmentVariable(Variable,
+ &VariableIndex,
+ &ValueIndex) != ESUCCESS)) {
+
+ Status = ENOENT;
+
+ } else {
+
+ //
+ // Copy the specified value to the output buffer.
+ //
+
+ for (Index = 0; Index < Length; Index += 1) {
+ *Buffer = READ_REGISTER_UCHAR(&Environment[ValueIndex]);
+ if (*Buffer == 0) {
+ break;
+ }
+
+ Buffer += 1;
+ ValueIndex += 1;
+ }
+
+ //
+ // If the length terminated the loop, then return not enough memory.
+ // Otherwise, return success.
+ //
+
+ if (Index == Length) {
+ Status = ENOMEM;
+
+ } else {
+ Status = ESUCCESS;
+ }
+ }
+
+ //
+ // Unmap the NVRAM from the address space of the current process and
+ // return the function status.
+ //
+
+ HalpUnmapNvram(OldIrql);
+ return Status;
+}
+
+ARC_STATUS
+HalSetEnvironmentVariable (
+ IN PCHAR Variable,
+ IN PCHAR Value
+ )
+
+/*++
+
+Routine Description:
+
+ This function creates an environment variable with the specified value.
+
+Arguments:
+
+ Variable - Supplies a pointer to an environment variable name.
+
+ Value - Supplies a pointer to the environment variable value.
+
+Return Value:
+
+ ESUCCESS is returned if the environment variable is created. Otherwise,
+ ENOMEM is returned.
+
+--*/
+
+{
+
+ UCHAR Character;
+ PUCHAR Environment;
+ KIRQL OldIrql;
+ ARC_STATUS Status;
+ ULONG TopIndex;
+ ULONG VariableIndex;
+ ULONG VariableLength;
+ ULONG ValueEnd;
+ ULONG ValueIndex;
+ ULONG ValueLength;
+
+ //
+ // Map the NVRAM into the address space of the current process.
+ //
+
+ OldIrql = HalpMapNvram();
+ Environment = &((PNV_CONFIGURATION)NVRAM_VIRTUAL_BASE)->Environment[0];
+
+ //
+ // If the checksum does not match, then set status to an I/O error.
+ //
+
+ if (HalpEnvironmentCheckChecksum() != ESUCCESS) {
+ Status = EIO;
+ goto Unmap;
+ }
+
+ //
+ // Determine the top of the environment area by scanning backwards until
+ // the a non-null character is found or the beginning of the environment
+ // area is reached.
+ //
+
+ for (TopIndex = (LENGTH_OF_ENVIRONMENT - 1); TopIndex > 0; TopIndex -= 1) {
+ if (READ_REGISTER_UCHAR(&Environment[TopIndex]) != '\0') {
+ break;
+ }
+ }
+
+ //
+ // If the environment area contains any data, then adjust the top index
+ // to the first free byte.
+ //
+
+ if (TopIndex != 0) {
+ TopIndex += 2;
+ }
+
+ //
+ // Compute the length of the variable name and the variable value.
+ //
+
+ VariableLength = strlen(Variable) + 1;
+ ValueLength = strlen(Value) + 1;
+
+ //
+ // Check to determine if the specified variable is currently defined.
+ //
+
+ if (HalpFindEnvironmentVariable(Variable,
+ &VariableIndex,
+ &ValueIndex) == ESUCCESS) {
+
+ //
+ // The specified variable is currently defined. Determine the end
+ // of the variable value by scanning forward to the zero termination
+ // byte.
+ //
+
+ ValueEnd = ValueIndex;
+ while (READ_REGISTER_UCHAR(&Environment[ValueEnd]) != '\0') {
+ ValueEnd += 1;
+ }
+
+ ValueEnd += 1;
+
+ //
+ // If there is enough free space for the new variable value, then
+ // remove the current variable name and value from the environment
+ // area, insert the new variable value at the end of the environment
+ // if it is not null, and set the status to success. Otherwise, set
+ // the status to no space available.
+ //
+
+ if ((ValueEnd - ValueIndex + LENGTH_OF_ENVIRONMENT - TopIndex) >= ValueLength) {
+ while (ValueEnd != TopIndex) {
+ Character = READ_REGISTER_UCHAR(&Environment[ValueEnd]);
+ WRITE_REGISTER_UCHAR(&Environment[VariableIndex], Character);
+ ValueEnd += 1;
+ VariableIndex += 1;
+ }
+
+ ValueIndex = VariableIndex;
+ while (ValueIndex != TopIndex) {
+ WRITE_REGISTER_UCHAR(&Environment[ValueIndex], '\0');
+ ValueIndex += 1;
+ }
+
+ //
+ // If the new variable value is not null, then copy the variable
+ // name and the variable value into the enviroment area.
+ //
+
+ if (*Value != '\0') {
+
+ //
+ // copy the variable name to the environment area.
+ //
+
+ do {
+ WRITE_REGISTER_UCHAR(&Environment[VariableIndex], UpCase(*Variable));
+ VariableIndex += 1;
+ Variable += 1;
+ } while (*Variable != '\0');
+
+ //
+ // Insert separator character and copy variable value to the
+ // environment area.
+ //
+
+ WRITE_REGISTER_UCHAR(&Environment[VariableIndex], '=');
+ VariableIndex += 1;
+ do {
+ WRITE_REGISTER_UCHAR(&Environment[VariableIndex], *Value);
+ VariableIndex += 1;
+ Value += 1;
+ } while (*Value != '\0');
+ }
+
+ Status = ESUCCESS;
+
+ } else {
+ Status = ENOSPC;
+ }
+
+ } else {
+
+ //
+ // The specified variable does not currently have a value. If the
+ // specified variable is null or has no value, then set the status
+ // to success. Otherwise, if the free area is not large enough to
+ // hold the new variable name and its value, then set the status to
+ // no space available. Otherwise, insert the variable name and value
+ // at the end of the environment area and set the status to success.
+ //
+
+ if ((*Variable == '\0') || (*Value == '\0')) {
+ Status = ESUCCESS;
+
+ } else if ((LENGTH_OF_ENVIRONMENT - TopIndex) <
+ (VariableLength + ValueLength)) {
+ Status = ENOSPC;
+
+ } else {
+
+ //
+ // copy the variable name to the environment area.
+ //
+
+ do {
+ WRITE_REGISTER_UCHAR(&Environment[TopIndex], UpCase(*Variable));
+ TopIndex += 1;
+ Variable += 1;
+ } while (*Variable != '\0');
+
+ //
+ // Insert separator character and copy variable value to the
+ // environment area.
+ //
+
+ WRITE_REGISTER_UCHAR(&Environment[TopIndex], '=');
+ TopIndex += 1;
+ do {
+ WRITE_REGISTER_UCHAR(&Environment[TopIndex], *Value);
+ TopIndex += 1;
+ Value += 1;
+ } while (*Value != '\0');
+
+ Status = ESUCCESS;
+ }
+ }
+
+ //
+ // Compute the new checksum and write to the environment area.
+ //
+
+ HalpEnvironmentSetChecksum();
+
+ //
+ // Unmap the NVRAM from the address space of the current process.
+ //
+
+Unmap:
+ HalpUnmapNvram(OldIrql);
+ return Status;
+}
+
+BOOLEAN
+HalNvramWrite(
+ ULONG Offset, // Offset Of ESM NVRAM
+ ULONG Count, // Write Byte Count
+ PVOID Buffer // Pointer Of Buffer Write to NVRAM
+){
+ // Write into NVRAM
+ return HalpNvramReadWrite(Offset,Count,Buffer,1);
+}
+
+BOOLEAN
+HalNvramRead(
+ ULONG Offset, // Offset Of ESM NVRAM
+ ULONG Count, // Read Byte Count
+ PVOID Buffer // Pointer Of Buffer Read From NVRAM
+){
+ // Read From NVRAM
+ return HalpNvramReadWrite(Offset,Count,Buffer,0);
+}
+
+BOOLEAN
+HalpNvramReadWrite(
+ ULONG Offset, // Read/Write offset of ESM NVRAM
+ ULONG Count, // Read/Write Byte Count
+ PVOID Buffer, // read/Write Pointer
+ ULONG Write // Operation
+){
+
+ KIRQL OldIrql;
+ ULONG i;
+ //
+ // Check is addr . So decrement 1
+ //
+ if(
+ Offset >=0 &&
+ Count >=0 &&
+ Offset <= 0x1fff && // M002 +++
+ Offset+Count-1 <= 0x1fff // M002 ---
+
+ ){
+
+ if(Write){
+ OldIrql = HalpEsmMapNvram(); // M002
+// if (HalpEsmDebug == 1) // test
+// DbgBreakPoint(); // test
+ for(i=0;i<Count;i++){ // test
+ WRITE_REGISTER_UCHAR((PUCHAR)(NVRAM_VIRTUAL_BASE+Offset+i),((PUCHAR)Buffer)[i]); // M002 +++
+ }
+ HalpUnmapNvram(OldIrql);
+ }else{
+ OldIrql = HalpEsmMapNvram(); // M002
+// if (HalpEsmDebug == 1) // test
+// DbgBreakPoint(); // test
+ for(i=0;i<Count;i++){
+ ((PUCHAR)Buffer)[i] =READ_REGISTER_UCHAR((PUCHAR)(NVRAM_VIRTUAL_BASE+Offset+i)); // M002
+
+ }
+ HalpUnmapNvram(OldIrql); // M002
+ }
+
+ return TRUE;
+
+ }else{
+
+ //
+ // It is no ESM NVRAM Erea.
+ return FALSE;
+ }
+
+}
diff --git a/private/ntos/nthals/halr96b/mips/jxhalp.h b/private/ntos/nthals/halr96b/mips/jxhalp.h
new file mode 100644
index 000000000..7232ebb11
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxhalp.h
@@ -0,0 +1,224 @@
+// #pragma comment(exestr, "@(#) jxhalp.h 1.1 95/09/28 15:37:58 nec")
+
+/*++ BUILD Version: 0001 // Increment this if a change has global effects
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ jxhalp.h
+
+Abstract:
+
+ This header file defines the private Hardware Architecture Layer (HAL)
+ Jazz specific interfaces, defines and structures.
+
+Author:
+
+ Jeff Havens (jhavens) 20-Jun-91
+
+
+Modification History for NEC R94A (MIPS R4400):
+
+ H000 Thu Sep 8 10:32:42 JST 1994 kbnes!kishimoto
+ - New HalpCreateEisaPCIStructures()
+ - Del HalpCreateEisaStructures()
+ - New function HalpEisaPCIDispatch()
+ - Del function HalpEisaDispatch()
+ L000 Thu Oct 13 18:09:33 JST 1994 kbnes!kuriyama(A)
+ for BBM LED
+ - Add HalpDisplayLED
+ - Add HalpLEDDisplayLock
+ - Add HalpLEDControlBase;
+ L002 Mon Oct 17 14:21:39 JST 1994 kbnes!kuriyama(A)
+ change function name EISAPCI... EISA..
+ H001 Mon Oct 17 14:45:04 JST 1994 kbnes!kishimoto
+ - Del HalDisplayLED() function definitions.
+ (We call HalR94aDebugPrint() instead of that.)
+ H002 Thu Oct 20 20:58:45 JST 1994 kbnes!kishimoto
+ - add extern ULONG R94aBbmLEDMapped
+ for debug use only.
+ H003 Fri Oct 21 15:52:32 JST 1994 kbnes!kishimoto
+ - add HalR94aDebugPrint() prototype definition.
+ H004 Mon Jan 16 02:28:58 1995 kbnes!kishimoto
+ - add HalpPCIConfigLock
+ S005 Tue Mar 07 14:55:42 JST 1995 kbnes!kuriyama (A)
+ - add Dma32BitAddresses to AdapterObject
+ H006 Fri Jul 21 17:40:53 JST 1995 kbnes!kisimoto
+ - merge ESM functions from J94C
+ H007 Sat Aug 12 15:12:28 JST 1995 kbnes!kisimoto
+ - Removed BBMLED, R94ALEDMAP code and _J94C_ definitions.
+ _J94C_ definition indicates that the status of
+ the dump switch can acknowledge from Self-test
+ register.
+
+--*/
+
+#ifndef _JXHALP_
+#define _JXHALP_
+
+
+//
+// Define global data used to locate the EISA control space and the realtime
+// clock registers.
+//
+
+extern PVOID HalpEisaControlBase;
+extern PVOID HalpEisaMemoryBase;
+extern PVOID HalpRealTimeClockBase;
+
+//
+// Define adapter object structure.
+//
+
+typedef struct _ADAPTER_OBJECT {
+ CSHORT Type;
+ CSHORT Size;
+ struct _ADAPTER_OBJECT *MasterAdapter;
+ ULONG MapRegistersPerChannel;
+ PVOID AdapterBaseVa;
+ PVOID MapRegisterBase;
+ ULONG NumberOfMapRegisters;
+ struct _WAIT_CONTEXT_BLOCK *CurrentWcb;
+ KDEVICE_QUEUE ChannelWaitQueue;
+ PKDEVICE_QUEUE RegisterWaitQueue;
+ LIST_ENTRY AdapterQueue;
+ KSPIN_LOCK SpinLock;
+ PRTL_BITMAP MapRegisters;
+ UCHAR ChannelNumber;
+ UCHAR AdapterNumber;
+ UCHAR AdapterMode;
+ UCHAR Reserved;
+ PUCHAR SingleMaskPort;
+ PUCHAR PagePort;
+#if defined(_DMA_EXPAND_) // S005
+ BOOLEAN Dma32BitAddresses;
+#endif //_DMA_EXPAND_
+} ADAPTER_OBJECT;
+
+//
+// Define function prototypes.
+//
+
+PADAPTER_OBJECT
+HalpAllocateEisaAdapter(
+ IN PDEVICE_DESCRIPTION DeviceDescription
+ );
+
+VOID
+HalpAllocateMapRegisters(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+BOOLEAN
+HalpCreateEisaStructures(
+ VOID
+ );
+
+VOID
+HalpDisableEisaInterrupt(
+ IN ULONG Vector
+ );
+
+BOOLEAN
+HalpEisaDispatch(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+VOID
+HalpEisaMapTransfer(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN BOOLEAN WriteToDevice
+ );
+
+VOID
+HalpEnableEisaInterrupt(
+ IN ULONG Vector,
+ IN KINTERRUPT_MODE InterruptMode
+ );
+
+#if defined(_R94A_)
+
+PADAPTER_OBJECT
+HalpAllocatePCIAdapter(
+ IN PDEVICE_DESCRIPTION DeviceDescription
+ );
+
+VOID
+HalpEnablePCIInterrupt (
+ IN ULONG Vector
+ );
+
+VOID
+HalpDisablePCIInterrupt (
+ IN ULONG Vector
+ );
+
+BOOLEAN
+HalpPCIDispatch(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+VOID // H004
+HalpInitBusHandlers (
+ VOID
+ );
+
+extern KSPIN_LOCK HalpPCIConfigLock; // H004
+
+#endif
+
+VOID
+HalpChangePanicFlag(
+ IN ULONG NewPanicFlg,
+ IN UCHAR NewLogFlg,
+ IN UCHAR CurrentLogFlgMask
+ );
+
+VOID
+HalpInitDisplayStringIntoNvram(
+ VOID
+ );
+
+VOID
+HalpSuccessOsStartUp(
+ VOID
+ );
+
+VOID
+HalStringIntoBuffer(
+ IN UCHAR Character
+ );
+
+VOID
+HalStringIntoBufferStart(
+ IN ULONG Column,
+ IN ULONG Row
+ );
+
+VOID
+HalpStringBufferCopyToNvram(
+ VOID
+ );
+
+#if DBG // H003
+VOID
+HalR94aDebugPrint(
+ ULONG DebugLevel,
+ PUCHAR LedCharactor,
+ PUCHAR Message,
+ ...
+ );
+
+int
+printNvramData(
+ void
+ );
+
+#endif
+
+#endif // _JXHALP_
diff --git a/private/ntos/nthals/halr96b/mips/jxhwsup.c b/private/ntos/nthals/halr96b/mips/jxhwsup.c
new file mode 100644
index 000000000..aa220a2d8
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxhwsup.c
@@ -0,0 +1,4265 @@
+// #pragma comment(exestr, "@(#) jxhwsup.c 1.1 95/09/28 15:38:22 nec")
+/*++
+
+Copyright (c) 1990-1993 Microsoft Corporation
+
+Module Name:
+
+ jxhwsup.c
+
+Abstract:
+
+ This module contains the HalpXxx routines for the NT I/O system that
+ are hardware dependent. Were these routines not hardware dependent,
+ they would normally reside in the internal.c module.
+
+Author:
+
+ Jeff Havens (jhavens) 14-Feb-1990
+
+Environment:
+
+ Kernel mode, local to I/O system
+
+Revision History:
+
+ M0001 1994.9.8 kuriyama@oa2
+ - Modify for R94A MIPS R4400
+
+ HalGetAdapter() - add routine for support PCIBus
+ Modify Internal MAX Dma Channel (r94a 0-3)
+
+ HalTranslateBusAddress() - add routine for support PCIBus
+
+ HalGetBusDataBy
+
+ M0002 1994.10.7 kuriyama@oa2
+ - Modify HalDmaChannel() - terminal count logic bug fix.
+
+ M0003 1994.10.14 kuriyama@oa2
+ - compile error clear
+ CHG001 ataka@oa2.kb.nec.co.jp Mon Oct 17 23:20:04 JST 1994
+ - Merge BusHandlers
+
+ M0004 Fri Oct 28 14:56:02 JST 1994 kuriyama@oa2
+ - add BBM DMA routine (for edit buffer)(for BBM limited)
+ - add I/O cache flush if physical tag is valid(for BBM limited)
+ D001 ataka@oa2.kb.nec.co.jp (DMA CopyBuffer by kuriyama@oa2, other toghether)
+ Sat Nov 05 16:28:04 JST 1994
+ - Limit Check of Length (Only DbgPrint)
+ - Delete checking ByteMask
+ - TLB fill 0xff(by Kuriyama)
+
+ M005 Tue Dec 13 16:28:25 1994 kbnes!kisimoto
+ - changed the address that copies from, and source re-formated.
+
+ M0006 Thu Dec 22 11:46:16 JST 1994 kbnes!A.kuriyama
+ - add beta machine limit
+
+ S0007 Thu Jan 05 17:13:18 JST 1995 kbnes!A.Kuriyama
+ - warning clear
+
+ M0008 Fri Jan 13 13:49:51 JST 1995 kbnes!A.Kuriyama
+ - I/O cache flush routine was deleted in functions as follows
+ IoMapTransfer()
+ HalFlushCommonBuffer()
+
+ M0009 Mon Jan 23 14:31:44 JST 1995 kbnes!A.Kuriyama
+ - DMA Channel Interrupt routine change
+ - add Internal DMAC bytecount mask
+
+ M0010 Mon Jan 23 15:36:18 JST 1995 kbnes!A.Kuriyama
+ - Dma channel interrupt enable
+ HalpAllocateAdapter()
+ HalpCreateDmaStructure()
+
+ S0011 Tue Jan 24 18:28:55 JST 1995 kbnes!A.Kuriyama
+ - Compile error clear
+
+ M0012 Tue Jan 31 18:04:08 JST 1995 kbnes!A.Kuriyama
+ - add Internal slave dma 1MB limit.
+
+ M0013 Tue Jan 31 18:07:53 JST 1995 kbnes!A.Kuriyama
+
+ M0014 Tue Jan 31 18:37:33 JST 1995 kbnes!A.Kuriyama
+ - change I/O cache flush routine.
+ if length equal 0 no need i/o cache flush.
+
+ S0015 Wed Feb 01 12:03:06 JST 1995 kbnes!A.Kuriyama
+ - sccs update miss error clear
+
+ B0016 Thu Feb 2 22:09:32 1995 kbnes!kishimoto
+ - return pointer to adapterObject if InterfaceType
+ equals PCIBus
+
+ S0017 Wed Feb 22 12:00:58 JST 1995 kbnes!kuriyama (A)
+ - disable dma terminal interrupt
+
+ M0018 Tue Mar 07 11:26:44 JST 1995 kbnes!kuriyama (A)
+ - expand dma logical address space
+
+ S0019 Tue Mar 07 15:22:00 JST 1995 kbnes!kuriyama (A)
+ - compile error clear
+
+ M0020 Fri Mar 10 11:44:25 JST 1995 kbnes!kuriyama (A)
+ - logical address expand bug fix
+
+ S0021 Fri Mar 10 16:23:12 JST 1995 kbnes!kuriyama (A)
+ - internal slave bug fix
+
+ S0022 Tue Jun 27 19:12:30 JST 1995 kbnes!kisimoto
+ - del memmove prototype definition
+ to merge build 1057
+ change strings displaied with Tyhoon error
+
+ S0023 Thu Jul 20 20:11:34 JST 1995 kbnes!kisimoto
+ - add code for ESM from J94C
+
+ M0024 kuriyama@oa2.kb.nec.co.jp Wed Aug 23 19:36:13 JST 1995
+ - add for x86bios support
+ - (change internal dma address to 1M-4M)
+--*/
+
+#include "halp.h"
+#include "bugcodes.h"
+#include "eisa.h"
+
+//
+// Put all code for HAL initialization in the INIT section. It will be
+// deallocated by memory management when phase 1 initialization is
+// completed.
+//
+
+#if defined(ALLOC_PRAGMA)
+
+#pragma alloc_text(INIT, HalpCreateDmaStructures)
+
+#endif
+
+extern POBJECT_TYPE IoAdapterObjectType;
+
+#define HalDump(x,y) if(HalDebug > 0) DbgPrint( x,y )
+/* M0006 */
+
+/* start M0004 */
+ULONG HalDebug = 0;
+#if defined(_BBM_DMA_)
+//
+// define copybuffer allocate routine.
+//
+
+VOID
+HalpAllocateCopyBuffer(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+
+//
+// Allocate Variable for DMA CopyBuffer
+//
+ ULONG CopyBufferPhysicalBase;
+ ULONG CopyBufferVirtualAddress;
+
+#endif // _BBM_DMA_
+
+#if defined(_BETA_LIMIT_)
+PVOID
+HalViewMemory (
+ IN PVOID Destination,
+ IN ULONG Length
+ );
+#endif // _BETA_LIMIT_
+/* end M0004 */
+
+//
+// The DMA controller has a larger number of map registers which may be used
+// by any adapter channel. In order to pool all of the map registers a master
+// adapter object is used. This object is allocated and saved internal to this
+// file. It contains a bit map for allocation of the registers and a queue
+// for requests which are waiting for more map registers. This object is
+// allocated during the first request to allocate an adapter.
+//
+
+PADAPTER_OBJECT MasterAdapterObject;
+
+//
+// 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 HalpDmaChannelInterrupt;
+
+/* start M0001 */
+#if defined(_R94A_)
+//
+// The following is the interrupt object used for Typhoon Error interrupts.
+// Typhoon errorr interrupts occur when internal busmaster device error occurs.
+//
+
+KINTERRUPT HalpTyphoonErrorInterrupt;
+
+#endif // _R94A_
+/* end M0001 */
+
+UCHAR DmaChannelMsg[] = "\nHAL: DMA channel x interrupted. ";
+
+//
+// Pointer to phyiscal memory for map registers.
+//
+
+ULONG HalpMapRegisterPhysicalBase;
+
+//
+// The following function is called when a DMA channel interrupt occurs.
+//
+
+BOOLEAN
+HalpDmaChannel(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+//
+// The following is an array of adapter object structures for the internal DMA
+// channels.
+//
+
+PADAPTER_OBJECT HalpInternalAdapters[8];
+
+IO_ALLOCATION_ACTION
+HalpAllocationRoutine (
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID MapRegisterBase,
+ IN PVOID Context
+ );
+
+ULONG
+HalpReadEisaData (
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+/* start M0001 */
+#if defined(_R94A_)
+BOOLEAN
+HalpCreateTyphoonErrorStructures (
+ VOID
+ );
+
+BOOLEAN
+HalpTyphoonError(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+#endif // _R94A_
+/* end M0001 */
+
+
+NTSTATUS
+HalAllocateAdapterChannel(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PWAIT_CONTEXT_BLOCK Wcb,
+ IN ULONG NumberOfMapRegisters,
+ IN PDRIVER_CONTROL ExecutionRoutine
+ )
+/*++
+
+Routine Description:
+
+ This routine allocates the adapter channel specified by the adapter object.
+ This is accomplished by placing the device object of the driver that wants
+ to allocate the adapter on the adapter's queue. If the queue is already
+ "busy", then the adapter has already been allocated, so the device object
+ is simply placed onto the queue and waits until the adapter becomes free.
+
+ Once the adapter becomes free (or if it already is), then the driver's
+ execution routine is invoked.
+
+ Also, a number of map registers may be allocated to the driver by specifying
+ a non-zero value for NumberOfMapRegisters. Then the map register must be
+ allocated from the master adapter. Once there are a sufficient number of
+ map registers available, then the execution routine is called and the
+ base address of the allocated map registers in the adapter is also passed
+ to the driver's execution routine.
+
+Arguments:
+
+ AdapterObject - Pointer to the adapter control object to allocate to the
+ driver.
+
+ Wcb - Supplies a wait context block for saving the allocation parameters.
+ The DeviceObject, CurrentIrp and DeviceContext should be initalized.
+
+ NumberOfMapRegisters - The number of map registers that are to be allocated
+ from the channel, if any.
+
+ ExecutionRoutine - The address of the driver's execution routine that is
+ invoked once the adapter channel (and possibly map registers) have been
+ allocated.
+
+Return Value:
+
+ Returns STATUS_SUCESS unless too many map registers are requested.
+
+Notes:
+
+ Note that this routine MUST be invoked at DISPATCH_LEVEL or above.
+
+--*/
+
+{
+ PADAPTER_OBJECT MasterAdapter;
+ BOOLEAN Busy = FALSE;
+ IO_ALLOCATION_ACTION Action;
+ LONG MapRegisterNumber;
+ KIRQL Irql;
+ ULONG Hint;
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ ULONG Limit;
+#endif //_DMA_EXPAND_
+// M0018 ---
+
+ //
+ // Begin by obtaining a pointer to the master adapter associated with this
+ // request.
+ //
+
+ if (AdapterObject->MasterAdapter != NULL) {
+ MasterAdapter = AdapterObject->MasterAdapter;
+ } else {
+ MasterAdapter = AdapterObject;
+ }
+
+ //
+ // Initialize the device object's wait context block in case this device
+ // must wait before being able to allocate the adapter.
+ //
+
+ Wcb->DeviceRoutine = ExecutionRoutine;
+ Wcb->NumberOfMapRegisters = NumberOfMapRegisters;
+
+ //
+ // Allocate the adapter object for this particular device. If the
+ // adapter cannot be allocated because it has already been allocated
+ // to another device, then return to the caller now; otherwise,
+ // continue.
+ //
+
+ if (!KeInsertDeviceQueue( &AdapterObject->ChannelWaitQueue,
+ &Wcb->WaitQueueEntry )) {
+
+ //
+ // The adapter was not busy so it has been allocated. Now check
+ // to see whether this driver wishes to allocate any map registers.
+ // If so, then queue the device object to the master adapter queue
+ // to wait for them to become available. If the driver wants map
+ // registers, ensure that this adapter has enough total map registers
+ // to satisfy the request.
+ //
+
+ AdapterObject->CurrentWcb = Wcb;
+ AdapterObject->NumberOfMapRegisters = Wcb->NumberOfMapRegisters;
+
+ if (NumberOfMapRegisters != 0) {
+ if (NumberOfMapRegisters > MasterAdapter->MapRegistersPerChannel) {
+ AdapterObject->NumberOfMapRegisters = 0;
+ IoFreeAdapterChannel(AdapterObject);
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ //
+ // Lock the map register bit map and the adapter queue in the
+ // master adapter object. The channel structure offset is used as
+ // a hint for the register search.
+ //
+
+ KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
+
+ MapRegisterNumber = -1;
+
+ if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ if (AdapterObject->Dma32BitAddresses) {
+ Hint = EISA_MIN_ADR / PAGE_SIZE;
+ Limit = EISA_MAX_ADR / PAGE_SIZE;
+ } else {
+ Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
+ Limit = ISA_MAX_ADR / PAGE_SIZE - NumberOfMapRegisters;
+ }
+#else // _DMA_EXPAND_
+// Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
+ Hint = (0x100000 / PAGE_SIZE); // M0024
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ MapRegisterNumber = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ NumberOfMapRegisters,
+ Hint
+ );
+
+ //
+ // Make sure this map register is valid for this adapter.
+ //
+
+ if ((ULONG) MapRegisterNumber < Hint) {
+
+ //
+ // Make it look like there are no map registers.
+ //
+
+ RtlClearBits(
+ MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ NumberOfMapRegisters
+ );
+
+ MapRegisterNumber = -1;
+ }
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ //
+ // Make sure this map register is valid for this adapter.
+ //
+
+ if ((ULONG) MapRegisterNumber >= Limit ) {
+
+ //
+ // Make it look like there are no map registers.
+ //
+
+ RtlClearBits(
+ MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ NumberOfMapRegisters
+ );
+
+ MapRegisterNumber = -1;
+ }
+#endif // _DMA_EXPAND_
+// M0018 ---
+ }
+
+ if (MapRegisterNumber == -1) {
+
+ //
+ // There were not enough free map registers. Queue this request
+ // on the master adapter where is will wait until some registers
+ // are deallocated.
+ //
+
+ InsertTailList( &MasterAdapter->AdapterQueue,
+ &AdapterObject->AdapterQueue
+ );
+ Busy = 1;
+
+ } else {
+ AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase + MapRegisterNumber);
+ }
+
+ KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
+ }
+
+ //
+ // If there were either enough map registers available or no map
+ // registers needed to be allocated, invoke the driver's execution
+ // routine now.
+ //
+
+ if (!Busy) {
+
+ Action = ExecutionRoutine( Wcb->DeviceObject,
+ Wcb->CurrentIrp,
+ AdapterObject->MapRegisterBase,
+ Wcb->DeviceContext
+ );
+
+ //
+ // If the driver wishes to keep the map registers then set the number
+ // allocated to zero and set the action to deallocate object.
+ //
+
+ if (Action == DeallocateObjectKeepRegisters) {
+ AdapterObject->NumberOfMapRegisters = 0;
+ Action = DeallocateObject;
+ }
+
+ //
+ // If the driver would like to have the adapter deallocated,
+ // then deallocate any map registers allocated and then release
+ // the adapter object.
+ //
+
+ if (Action == DeallocateObject) {
+ IoFreeAdapterChannel( AdapterObject );
+ }
+ }
+ }
+
+ return(STATUS_SUCCESS);
+
+}
+
+PVOID
+HalAllocateCommonBuffer(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG Length,
+ OUT PPHYSICAL_ADDRESS LogicalAddress,
+ IN BOOLEAN CacheEnabled
+ )
+/*++
+
+Routine Description:
+
+ This function allocates the memory for a common buffer and maps so that it
+ can be accessed by a master device and the CPU.
+
+Arguments:
+
+ AdapterObject - Supplies a pointer to the adapter object used by this
+ device.
+
+ Length - Supplies the length of the common buffer to be allocated.
+
+ LogicalAddress - Returns the logical address of the common buffer.
+
+ CacheEnable - Indicates whether the memeory is cached or not.
+
+Return Value:
+
+ Returns the virtual address of the common buffer. If the buffer cannot be
+ allocated then NULL is returned.
+
+--*/
+
+{
+ PVOID virtualAddress;
+ PVOID mapRegisterBase;
+ ULONG numberOfMapRegisters;
+ ULONG mappedLength;
+ WAIT_CONTEXT_BLOCK wcb;
+ KEVENT allocationEvent;
+ NTSTATUS status;
+ PMDL mdl;
+ KIRQL irql;
+
+ numberOfMapRegisters = BYTES_TO_PAGES(Length);
+
+ //
+ // Allocate the actual buffer.
+ //
+
+ if (CacheEnabled != FALSE) {
+ virtualAddress = ExAllocatePool(NonPagedPoolCacheAligned, Length);
+
+ } else {
+ virtualAddress = MmAllocateNonCachedMemory(Length);
+ }
+
+
+ if (virtualAddress == NULL) {
+ return(virtualAddress);
+
+ }
+
+ //
+ // Initialize an event.
+ //
+
+ KeInitializeEvent( &allocationEvent, NotificationEvent, FALSE);
+
+ //
+ // Initialize the wait context block. Use the device object to indicate
+ // where the map register base should be stored.
+ //
+
+ wcb.DeviceObject = &mapRegisterBase;
+ wcb.CurrentIrp = NULL;
+ wcb.DeviceContext = &allocationEvent;
+
+ //
+ // Allocate the adapter and the map registers.
+ //
+
+ KeRaiseIrql(DISPATCH_LEVEL, &irql);
+
+ status = HalAllocateAdapterChannel(
+ AdapterObject,
+ &wcb,
+ numberOfMapRegisters,
+ HalpAllocationRoutine
+ );
+
+ KeLowerIrql(irql);
+
+ if (!NT_SUCCESS(status)) {
+
+ //
+ // Cleanup and return NULL.
+ //
+
+ if (CacheEnabled != FALSE) {
+ ExFreePool(virtualAddress);
+
+ } else {
+ MmFreeNonCachedMemory(virtualAddress, Length);
+ }
+
+ return(NULL);
+
+ }
+
+ //
+ // Wait for the map registers to be allocated.
+ //
+
+ status = KeWaitForSingleObject(
+ &allocationEvent,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL
+ );
+
+ if (!NT_SUCCESS(status)) {
+
+ //
+ // Cleanup and return NULL.
+ //
+
+ if (CacheEnabled != FALSE) {
+ ExFreePool(virtualAddress);
+
+ } else {
+ MmFreeNonCachedMemory(virtualAddress, Length);
+ }
+
+ return(NULL);
+
+ }
+
+ //
+ // Create an mdl to use with call to I/O map transfer.
+ //
+
+ mdl = IoAllocateMdl(
+ virtualAddress,
+ Length,
+ FALSE,
+ FALSE,
+ NULL
+ );
+
+ MmBuildMdlForNonPagedPool(mdl);
+
+ //
+ // Map the transfer so that the controller can access the memory.
+ //
+
+ mappedLength = Length;
+ *LogicalAddress = IoMapTransfer(
+ NULL,
+ mdl,
+ mapRegisterBase,
+ virtualAddress,
+ &mappedLength,
+ TRUE
+ );
+
+ IoFreeMdl(mdl);
+
+ if (mappedLength < Length) {
+
+ //
+ // Cleanup and indicate that the allocation failed.
+ //
+
+ HalFreeCommonBuffer(
+ AdapterObject,
+ Length,
+ *LogicalAddress,
+ virtualAddress,
+ CacheEnabled
+ );
+
+ return(NULL);
+ }
+
+ //
+ // The allocation completed successfully.
+ //
+
+ return(virtualAddress);
+
+}
+
+PVOID
+HalAllocateCrashDumpRegisters(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PULONG NumberOfMapRegisters
+ )
+/*++
+
+Routine Description:
+
+ This routine is called during the crash dump disk driver's initialization
+ to allocate a number map registers permanently.
+
+Arguments:
+
+ AdapterObject - Pointer to the adapter control object to allocate to the
+ driver.
+ NumberOfMapRegisters - Number of map registers requested and update to show
+ number actually allocated.
+
+Return Value:
+
+ Returns STATUS_SUCESS if map registers allocated.
+
+--*/
+
+{
+ PADAPTER_OBJECT MasterAdapter;
+ ULONG MapRegisterNumber;
+ ULONG Hint;
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ ULONG Limit;
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ //
+ // Begin by obtaining a pointer to the master adapter associated with this
+ // request.
+ //
+
+ if (AdapterObject->MasterAdapter) {
+ MasterAdapter = AdapterObject->MasterAdapter;
+ } else {
+ MasterAdapter = AdapterObject;
+ }
+
+ //
+ // Ensure that this adapter has enough total map registers to satisfy
+ // the request.
+ //
+
+ if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) {
+ AdapterObject->NumberOfMapRegisters = 0;
+ return NULL;
+ }
+
+ //
+ // Attempt to allocate the required number of map registers w/o
+ // affecting those registers that were allocated when the system
+ // crashed. Note that once again the map registers to be allocated
+ // must be above the 1MB range if this is an EISA bus device.
+ //
+
+ MapRegisterNumber = (ULONG)-1;
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ if (AdapterObject->Dma32BitAddresses) {
+ Hint = EISA_MIN_ADR / PAGE_SIZE;
+ Limit = EISA_MAX_ADR / PAGE_SIZE;
+ } else {
+ Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
+ Limit = ISA_MAX_ADR / PAGE_SIZE - *NumberOfMapRegisters;
+ }
+#else // _DMA_EXPAND
+// Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
+ Hint = (0x100000 / PAGE_SIZE); // M0024
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ MapRegisterNumber = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ *NumberOfMapRegisters,
+ Hint
+ );
+
+ //
+ // Ensure that any allocated map registers are valid for this adapter.
+ //
+
+ if ((ULONG) MapRegisterNumber < Hint) {
+
+ //
+ // Make it appear as if there are no map registers.
+ //
+
+ RtlClearBits(
+ MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ *NumberOfMapRegisters
+ );
+
+ MapRegisterNumber = (ULONG) -1;
+ }
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ //
+ // Make sure this map register is valid for this adapter.
+ //
+
+ if ((ULONG) MapRegisterNumber >= Limit ) {
+
+ //
+ // Make it look like there are no map registers.
+ //
+
+ RtlClearBits(
+ MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ *NumberOfMapRegisters
+ );
+
+ MapRegisterNumber = (ULONG) -1;
+ }
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ if (MapRegisterNumber == (ULONG)-1) {
+
+ //
+ // Not enough free map registers were found, so they were busy
+ // being used by the system when it crashed. Force the appropriate
+ // number to be "allocated" at the base by simply overjamming the
+ // bits and return the base map register as the start.
+ //
+
+ RtlSetBits(
+ MasterAdapter->MapRegisters,
+ Hint,
+ *NumberOfMapRegisters
+ );
+ MapRegisterNumber = Hint;
+
+ }
+
+ //
+ // Calculate the map register base from the allocated map
+ // register and base of the master adapter object.
+ //
+
+ AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase + MapRegisterNumber);
+
+ return AdapterObject->MapRegisterBase;
+}
+
+BOOLEAN
+HalFlushCommonBuffer(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG Length,
+ IN PHYSICAL_ADDRESS LogicalAddress,
+ IN PVOID VirtualAddress
+ )
+/*++
+
+Routine Description:
+
+ This function is called to flush any hardware adapter buffers when the
+ driver needs to read data written by an I/O master device to a common
+ buffer.
+
+Arguments:
+
+ AdapterObject - Supplies a pointer to the adapter object used by this
+ device.
+
+ Length - Supplies the length of the common buffer. This should be the same
+ value used for the allocation of the buffer.
+
+ LogicalAddress - Supplies the logical address of the common buffer. This
+ must be the same value return by HalAllocateCommonBuffer.
+
+ VirtualAddress - Supplies the virtual address of the common buffer. This
+ must be the same value return by HalAllocateCommonBuffer.
+
+Return Value:
+
+ Returns TRUE if no errors were detected; otherwise, FALSE is return.
+
+--*/
+
+{
+#if 0 // M0008
+/* M0006 +++ */
+#if defined(_BETA_LIMIT_)
+{
+ ULONG PtagReg, Ptag, LtagReg, Ltag, DummyRead, i;
+ KIRQL OldIrql;
+
+ // D001
+// DbgPrint("DmaFlush start\n");
+ KeRaiseIrql(DEVICE_LEVEL, &OldIrql); // kuriyama
+ for (i = 0; i < 8; i++ ) {
+ PtagReg = (ULONG)&DMA_CONTROL->IoCachePhysicalTag[i];
+ LtagReg = (ULONG)&DMA_CONTROL->IoCacheLogicalTag[i];
+ Ptag = READ_REGISTER_ULONG(PtagReg);
+ Ltag = READ_REGISTER_ULONG(LtagReg);
+ if (Ptag & 0x1) {
+ if (Ltag & 0x1) {
+ if ((LogicalAddress.LowPart & 0xffffffc0) <= (Ltag & 0xffffffc0) && ((Ltag & 0xffffffc0) < (LogicalAddress.LowPart + Length))) {
+ DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
+ DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
+ if (HalDebug)
+ DbgPrint("Found Valid Entry:0x%x Tag:0x%x. Read 0x%x=0x%x\n",
+ PtagReg, Ptag, (KSEG1_BASE|(Ptag&0xFFFFFFC0)), DummyRead);
+ }
+ }
+ }
+ }
+ KeLowerIrql(OldIrql);
+// DbgPrint("DmaFlush end\n");
+}
+#endif // _BETA_LIMIT_
+/* M0006 --- */
+#endif // 0 // M0008
+ return(TRUE);
+
+}
+
+VOID
+HalFreeCommonBuffer(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG Length,
+ IN PHYSICAL_ADDRESS LogicalAddress,
+ IN PVOID VirtualAddress,
+ IN BOOLEAN CacheEnabled
+ )
+/*++
+
+Routine Description:
+
+ This function frees a common buffer and all of the resouces it uses.
+
+Arguments:
+
+ AdapterObject - Supplies a pointer to the adapter object used by this
+ device.
+
+ Length - Supplies the length of the common buffer. This should be the same
+ value used for the allocation of the buffer.
+
+ LogicalAddress - Supplies the logical address of the common buffer. This
+ must be the same value return by HalAllocateCommonBuffer.
+
+ VirtualAddress - Supplies the virtual address of the common buffer. This
+ must be the same value return by HalAllocateCommonBuffer.
+
+ CacheEnable - Indicates whether the memeory is cached or not.
+
+Return Value:
+
+ None
+
+--*/
+
+{
+ PTRANSLATION_ENTRY mapRegisterBase;
+ ULONG numberOfMapRegisters;
+ ULONG mapRegisterNumber;
+
+ //
+ // Calculate the number of map registers, the map register number and
+ // the map register base.
+ //
+
+ numberOfMapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length);
+ mapRegisterNumber = LogicalAddress.LowPart >> PAGE_SHIFT;
+
+ mapRegisterBase = (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase
+ + mapRegisterNumber;
+
+ //
+ // Free the map registers.
+ //
+
+ IoFreeMapRegisters(
+ AdapterObject,
+ (PVOID) mapRegisterBase,
+ numberOfMapRegisters
+ );
+
+ //
+ // Free the memory for the common buffer.
+ //
+
+ if (CacheEnabled != FALSE) {
+ ExFreePool(VirtualAddress);
+
+ } else {
+ MmFreeNonCachedMemory(VirtualAddress, Length);
+ }
+
+ return;
+
+}
+
+PADAPTER_OBJECT
+HalGetAdapter(
+ IN PDEVICE_DESCRIPTION DeviceDescription,
+ IN OUT PULONG NumberOfMapRegisters
+ )
+
+/*++
+
+Routine Description:
+
+ This function returns the appropriate adapter object for the device defined
+ in the device description structure. Three bus types are supported for the
+ system: Internal, Isa, and Eisa.
+
+Arguments:
+
+ DeviceDescription - Supplies a description of the deivce.
+
+ NumberOfMapRegisters - Returns the maximum number of map registers which
+ may be allocated by the device driver.
+
+Return Value:
+
+ A pointer to the requested adapter object or NULL if an adapter could not
+ be created.
+
+--*/
+
+{
+ PADAPTER_OBJECT adapterObject;
+
+// M0020 +++
+#if DBG
+#if defined (_DMA_EXPAND_)
+ DbgPrint("\nHalGetAdapter(): DeviceDescription->32BitAddresses = %d\n",DeviceDescription->Dma32BitAddresses);
+#endif // _DMA_EXPAND_
+#endif // DBG
+// M0020 ---
+
+ //
+ // Make sure this is the correct version.
+ //
+
+ if (DeviceDescription->Version > DEVICE_DESCRIPTION_VERSION1) {
+
+ return(NULL);
+
+ }
+
+ //
+ // Return number of map registers requested based on the maximum
+ // transfer length.
+ //
+
+ *NumberOfMapRegisters = BYTES_TO_PAGES(DeviceDescription->MaximumLength) + 1;
+
+ if (*NumberOfMapRegisters > DMA_REQUEST_LIMIT) {
+ *NumberOfMapRegisters = DMA_REQUEST_LIMIT;
+ }
+
+ if (DeviceDescription->InterfaceType == Internal) {
+
+
+ //
+ // Return the adapter pointer for internal adapters.
+ //
+ // If this is a master controler such as the SONIC then return the
+ // last channel.
+ //
+
+ if (DeviceDescription->Master) {
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ //
+ // Create an adapter.
+ //
+
+ adapterObject = HalpAllocateAdapter(
+ 0,
+ (PVOID) &(DMA_CONTROL)->Channel[7],
+ NULL
+ );
+
+ adapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
+
+// M0020 +++
+#if DBG
+ DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
+#endif DBG
+
+ if (adapterObject->Dma32BitAddresses) {
+ if (*NumberOfMapRegisters > (EISA_MAX_ADR - EISA_MIN_ADR)
+ / PAGE_SIZE / 8L) {
+ *NumberOfMapRegisters = (EISA_MAX_ADR - EISA_MIN_ADR)
+ / PAGE_SIZE / 8L;
+ }
+
+ } else {
+ if (*NumberOfMapRegisters > ISA_MAX_ADR / PAGE_SIZE / 8L) {
+ *NumberOfMapRegisters = ISA_MAX_ADR / PAGE_SIZE / 8L;
+ }
+ }
+#if DBG
+ DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
+ DbgPrint("internal master adapterObject->Dma32BitAddresses = %d\n",adapterObject->Dma32BitAddresses);
+#endif // DBG
+// M0020 ---
+
+ return(adapterObject);
+
+#else // _DMA_EXPAND
+
+ //
+ // Create an adapter if necessary.
+ //
+
+ if (HalpInternalAdapters[7] == NULL) {
+
+ HalpInternalAdapters[7] = HalpAllocateAdapter(
+ 0,
+ (PVOID) &(DMA_CONTROL)->Channel[7],
+ NULL
+ );
+
+ }
+
+ return(HalpInternalAdapters[7]);
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ }
+
+ //
+ // Make sure the DMA channel range is valid. Only use channels 0-6.
+ //
+
+/* start M0001 */
+#if defined(_R94A_)
+
+ if (DeviceDescription->DmaChannel > 3) { // duo and r94a have only 0-3 channel
+
+ return(NULL);
+ }
+
+#else // _R94A_
+
+ if (DeviceDescription->DmaChannel > 6) {
+
+ return(NULL);
+ }
+
+#endif // _R94A_
+/* end M0001 */
+
+ //
+ // If necessary allocate an adapter; otherwise,
+ // just return the adapter for the requested channel.
+ //
+
+ if (HalpInternalAdapters[DeviceDescription->DmaChannel] == NULL) {
+
+ HalpInternalAdapters[DeviceDescription->DmaChannel] =
+ HalpAllocateAdapter(
+ 0,
+ (PVOID) &(DMA_CONTROL)->Channel[DeviceDescription->DmaChannel],
+ NULL
+ );
+
+ }
+
+// M0012 +++
+#if defined(_R94A_)
+// M0020 +++
+#if DBG
+ DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
+#endif DBG
+// M0020 ---
+
+ //
+ // Internal slave dma limit 1MB. (TYPHOON tip limit)
+ //
+
+ if (*NumberOfMapRegisters > ( 0x100000 >> PAGE_SHIFT )) {
+
+ *NumberOfMapRegisters = ( 0x100000 >> PAGE_SHIFT );
+ }
+
+#endif // _R94A_
+// M0012 ---
+
+ if (*NumberOfMapRegisters > MasterAdapterObject->MapRegistersPerChannel / 4) {
+
+ *NumberOfMapRegisters = MasterAdapterObject->MapRegistersPerChannel / 4;
+ }
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+// M0020 +++
+ if (HalpInternalAdapters[DeviceDescription->DmaChannel]->Dma32BitAddresses) { // S0021
+ if (*NumberOfMapRegisters > (EISA_MAX_ADR - EISA_MIN_ADR)
+ / PAGE_SIZE / 8L) {
+ *NumberOfMapRegisters = (EISA_MAX_ADR - EISA_MIN_ADR)
+ / PAGE_SIZE / 8L;
+ }
+ } else {
+ if (*NumberOfMapRegisters > ISA_MAX_ADR / PAGE_SIZE / 8L) {
+ *NumberOfMapRegisters = ISA_MAX_ADR / PAGE_SIZE / 8L;
+ }
+ }
+
+ HalpInternalAdapters[DeviceDescription->DmaChannel]->Dma32BitAddresses
+ = DeviceDescription->Dma32BitAddresses;
+#if DBG
+ DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
+ DbgPrint("internal slave HalpInternalAdapters[%d]->Dma32BitAddresses = %d\n",
+ DeviceDescription->DmaChannel,
+ HalpInternalAdapters[DeviceDescription->DmaChannel]->Dma32BitAddresses);
+#endif // DBG
+
+// M0020 ---
+#endif // _DMA_EXPAND_
+// M0018 ---
+ return(HalpInternalAdapters[DeviceDescription->DmaChannel]);
+ }
+
+/* start M0001 */
+#if defined(_R94A_)
+ //
+ // PCI Bus check.
+ //
+ if (DeviceDescription->InterfaceType == PCIBus) {
+
+ adapterObject = HalpAllocatePCIAdapter( DeviceDescription );
+
+ if (*NumberOfMapRegisters > MasterAdapterObject->MapRegistersPerChannel / 4) {
+
+ *NumberOfMapRegisters = MasterAdapterObject->MapRegistersPerChannel / 4;
+ }
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+// M0020 +++
+ if (adapterObject->Dma32BitAddresses) {
+ if (*NumberOfMapRegisters > (EISA_MAX_ADR - EISA_MIN_ADR)
+ / PAGE_SIZE / 8L) {
+ *NumberOfMapRegisters = (EISA_MAX_ADR - EISA_MIN_ADR)
+ / PAGE_SIZE / 8L;
+ }
+ } else {
+ if (*NumberOfMapRegisters > ISA_MAX_ADR / PAGE_SIZE / 8L) {
+ *NumberOfMapRegisters = ISA_MAX_ADR / PAGE_SIZE / 8L;
+ }
+ }
+
+ adapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
+#if DBG
+ DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
+ DbgPrint("PCI master adapterObject->Dma32BitAddresses = %d\n",adapterObject->Dma32BitAddresses);
+#endif // DBG
+// M0020 ---
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ return(adapterObject); // B0016
+
+ }
+#endif // _R94A_
+/* end M0001 */
+
+ //
+ // If the request is for a unsupported bus then return NULL.
+ //
+
+ if (DeviceDescription->InterfaceType != Isa &&
+ DeviceDescription->InterfaceType != Eisa) {
+
+ //
+ // This bus type is unsupported return NULL.
+ //
+
+ return(NULL);
+ }
+// M0020 +++
+#if DBG
+ DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
+#endif DBG
+// M0020 ---
+
+ //
+ // Create an adapter object.
+ //
+
+ adapterObject = HalpAllocateEisaAdapter( DeviceDescription );
+
+ if (*NumberOfMapRegisters > MasterAdapterObject->MapRegistersPerChannel / 4) {
+
+ *NumberOfMapRegisters = MasterAdapterObject->MapRegistersPerChannel / 4;
+ }
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+// M0020 +++
+ if (adapterObject->Dma32BitAddresses) {
+ if (*NumberOfMapRegisters > (EISA_MAX_ADR - EISA_MIN_ADR)
+ / PAGE_SIZE / 8L) {
+ *NumberOfMapRegisters = (EISA_MAX_ADR - EISA_MIN_ADR)
+ / PAGE_SIZE / 8L;
+ }
+ } else {
+ if (*NumberOfMapRegisters > ISA_MAX_ADR / PAGE_SIZE / 8L) {
+ *NumberOfMapRegisters = ISA_MAX_ADR / PAGE_SIZE / 8L;
+ }
+ }
+
+#if DBG
+ DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
+ DbgPrint("eisa/isa adapterObject->Dma32BitAddresses = %d\n",adapterObject->Dma32BitAddresses);
+#endif // DBG
+// M0020 ---
+
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ return(adapterObject);
+}
+
+#if 0 // CHG0001
+
+BOOLEAN
+HalTranslateBusAddress(
+ IN INTERFACE_TYPE InterfaceType,
+ IN ULONG BusNumber,
+ 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:
+
+ InterfaceType - Supplies the type of bus which the address is for.
+
+ BusNumber - Supplies the bus number for the device.
+
+ BusAddress - Supplies the bus relative address.
+
+ AddressSpace - Supplies the address space number for the device: 0 for
+ memory and 1 for I/O space. Returns the address space on this system.
+
+ TranslatedAddress - Supplies a pointer to return the translated address
+
+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
+
+--*/
+
+{
+ TranslatedAddress->HighPart = 0;
+
+ //
+ // If this is for the internal bus then just return the passed parameter.
+ //
+
+ if (InterfaceType == Internal) {
+
+ //
+ // Return the passed parameters.
+ //
+
+ TranslatedAddress->LowPart = BusAddress.LowPart;
+ return(TRUE);
+ }
+
+/* start M0001 */
+#if defined(_R94A_)
+
+ if (InterfaceType != Isa && InterfaceType != Eisa && InterfaceType != PCIBus) {
+
+#else // _R94A_
+
+ if (InterfaceType != Isa && InterfaceType != Eisa) {
+
+#endif // _R94A_
+/* end M0001 */
+
+ //
+ // Not on this system return nothing.
+ //
+
+ *AddressSpace = 0;
+ TranslatedAddress->LowPart = 0;
+ return(FALSE);
+ }
+
+ //
+ // There is only one I/O bus which is an EISA, so the bus number is unused.
+ //
+ // Determine the address based on whether the bus address is in I/O space
+ // or bus memory space.
+ //
+
+ if (*AddressSpace) {
+
+ //
+ // The address is in I/O space.
+ //
+
+ *AddressSpace = 0;
+ TranslatedAddress->LowPart = BusAddress.LowPart + EISA_CONTROL_PHYSICAL_BASE;
+ if (TranslatedAddress->LowPart < BusAddress.LowPart) {
+
+ //
+ // A carry occurred.
+ //
+
+ TranslatedAddress->HighPart = 1;
+ }
+ return(TRUE);
+
+ } else {
+
+ //
+ // The address is in memory space.
+ //
+
+ *AddressSpace = 0;
+
+#if !defined(_DUO_)
+
+ if (DMA_CONTROL->RevisionLevel.Long < 2) {
+ TranslatedAddress->LowPart = BusAddress.LowPart + EISA_MEMORY_PHYSICAL_BASE;
+ } else {
+ TranslatedAddress->LowPart = BusAddress.LowPart + EISA_MEMORY_VERSION2_LOW;
+ TranslatedAddress->HighPart = EISA_MEMORY_VERSION2_HIGH;
+
+ }
+#else
+
+ TranslatedAddress->LowPart = BusAddress.LowPart + EISA_MEMORY_VERSION2_LOW;
+ TranslatedAddress->HighPart = EISA_MEMORY_VERSION2_HIGH;
+
+#endif
+
+ if (TranslatedAddress->LowPart < BusAddress.LowPart) {
+
+ //
+ // A carry occurred.
+ //
+
+ TranslatedAddress->HighPart = 1;
+ }
+ return(TRUE);
+
+ }
+}
+#endif
+
+
+PADAPTER_OBJECT
+HalpAllocateAdapter(
+ IN ULONG MapRegistersPerChannel,
+ IN PVOID AdapterBaseVa,
+ IN PVOID MapRegisterBase
+ )
+
+/*++
+
+Routine Description:
+
+ This routine allocates and initializes an adapter object to represent an
+ adapter or a DMA controller on the system.
+
+Arguments:
+
+ MapRegistersPerChannel - Unused.
+
+ AdapterBaseVa - Base virtual address of the adapter itself. If AdapterBaseVa
+ is NULL then the MasterAdapterObject is allocated.
+
+ MapRegisterBase - Unused.
+
+Return Value:
+
+ The function value is a pointer to the allocate adapter object.
+
+--*/
+
+{
+
+ PADAPTER_OBJECT AdapterObject;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ULONG Size;
+ ULONG BitmapSize;
+ HANDLE Handle;
+ NTSTATUS Status;
+ ULONG Mode;
+
+ //
+ // Initalize the master adapter if necessary.
+ //
+
+ if (MasterAdapterObject == NULL && AdapterBaseVa != NULL ) {
+
+ MasterAdapterObject = HalpAllocateAdapter( 0,
+ NULL,
+ NULL
+ );
+
+ //
+ // If we could not allocate the master adapter then give up.
+ //
+
+ if (MasterAdapterObject == NULL) {
+ return(NULL);
+ }
+ }
+
+ //
+ // Begin by initializing the object attributes structure to be used when
+ // creating the adapter object.
+ //
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ NULL,
+ OBJ_PERMANENT,
+ (HANDLE) NULL,
+ (PSECURITY_DESCRIPTOR) NULL
+ );
+
+ //
+ // Determine the size of the adapter object. If this is the master object
+ // then allocate space for the register bit map; otherwise, just allocate
+ // an adapter object.
+ //
+
+ if (AdapterBaseVa == NULL) {
+
+
+ BitmapSize = (((sizeof( RTL_BITMAP ) +
+ ((DMA_TRANSLATION_LIMIT / sizeof( TRANSLATION_ENTRY)) + 7 >> 3))
+ + 3) & ~3);
+
+ Size = sizeof( ADAPTER_OBJECT ) + BitmapSize;
+
+ } else {
+
+ Size = sizeof( ADAPTER_OBJECT );
+
+ }
+
+ //
+ // Now create the adapter object.
+ //
+
+ Status = ObCreateObject( KernelMode,
+ *((POBJECT_TYPE *)IoAdapterObjectType),
+ &ObjectAttributes,
+ KernelMode,
+ (PVOID) NULL,
+ Size,
+ 0,
+ 0,
+ (PVOID *)&AdapterObject );
+
+ //
+ // Reference the object.
+ //
+
+ if (NT_SUCCESS(Status)) {
+
+ Status = ObReferenceObjectByPointer(
+ AdapterObject,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ *((POBJECT_TYPE *)IoAdapterObjectType),
+ KernelMode
+ );
+
+ }
+
+ //
+ // If the adapter object was successfully created, then attempt to insert
+ // it into the the object table.
+ //
+
+ if (NT_SUCCESS( Status )) {
+
+ Status = ObInsertObject( AdapterObject,
+ NULL,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ 0,
+ (PVOID *) NULL,
+ &Handle );
+
+ if (NT_SUCCESS( Status )) {
+
+ ZwClose( Handle );
+
+ //
+ // Initialize the adapter object itself.
+ //
+
+ AdapterObject->Type = IO_TYPE_ADAPTER;
+ AdapterObject->Size = (USHORT) Size;
+ AdapterObject->MapRegistersPerChannel =
+ DMA_TRANSLATION_LIMIT / sizeof( TRANSLATION_ENTRY);
+ AdapterObject->AdapterBaseVa = AdapterBaseVa;
+ AdapterObject->MasterAdapter = MasterAdapterObject;
+ AdapterObject->PagePort = NULL;
+
+ //
+ // Initialize the channel wait queue for this
+ // adapter.
+ //
+
+ KeInitializeDeviceQueue( &AdapterObject->ChannelWaitQueue );
+
+ //
+ // If this is the MasterAdatper then initialize the register bit map,
+ // AdapterQueue and the spin lock.
+ //
+
+ if ( AdapterBaseVa == NULL ) {
+ ULONG MapRegisterSize;
+
+ KeInitializeSpinLock( &AdapterObject->SpinLock );
+
+ InitializeListHead( &AdapterObject->AdapterQueue );
+
+ AdapterObject->MapRegisters = (PVOID) ( AdapterObject + 1);
+ RtlInitializeBitMap( AdapterObject->MapRegisters,
+ (PULONG) (((PCHAR) (AdapterObject->MapRegisters)) + sizeof( RTL_BITMAP )),
+ DMA_TRANSLATION_LIMIT / sizeof( TRANSLATION_ENTRY)
+ );
+ RtlClearAllBits( AdapterObject->MapRegisters );
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ //
+ // set bit for unusable area
+ //
+
+// M0020 +++
+#if DBG
+ DbgPrint("translatiron start %x\n",HalpMapRegisterPhysicalBase);
+ DbgPrint("translatiron size %x\n",MapRegisterSize);
+#endif // DBG
+
+ RtlFindClearBitsAndSet(
+ AdapterObject->MapRegisters,
+ ((EISA_MIN_ADR - ISA_MAX_ADR) / PAGE_SIZE),
+ (ISA_MAX_ADR / PAGE_SIZE)
+ );
+ DbgPrint("unused start %x\n",ISA_MAX_ADR / PAGE_SIZE);
+ DbgPrint("unused length %x\n",(EISA_MIN_ADR - ISA_MAX_ADR) / PAGE_SIZE);
+// M0020 ---
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ //
+ // The memory for the map registers was allocated by
+ // HalpAllocateMapRegisters during phase 0 initialization.
+ //
+
+ MapRegisterSize = DMA_TRANSLATION_LIMIT;
+ MapRegisterSize = ROUND_TO_PAGES(MapRegisterSize);
+
+ //
+ // Convert the physical address to a non-cached virtual address.
+ //
+
+ AdapterObject->MapRegisterBase = (PVOID)
+ (HalpMapRegisterPhysicalBase | KSEG1_BASE);
+
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->TranslationBase.Long,
+ HalpMapRegisterPhysicalBase
+ );
+
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->TranslationLimit.Long,
+ MapRegisterSize
+ );
+
+ //
+ // Initialize the DMA mode registers for the Floppy, SCSI and Sound.
+ // The initialization values come fomr the System Specification.
+ //
+
+#if defined(_JAZZ_)
+
+ Mode = 0;
+ ((PDMA_CHANNEL_MODE) &Mode)->AccessTime = ACCESS_80NS;
+ ((PDMA_CHANNEL_MODE) &Mode)->TransferWidth = WIDTH_16BITS;
+ ((PDMA_CHANNEL_MODE) &Mode)->InterruptEnable = 0;
+ ((PDMA_CHANNEL_MODE) &Mode)->BurstMode = 0;
+ ((PDMA_CHANNEL_MODE) &Mode)->FastDmaCycle = 1;
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->Channel[SCSI_CHANNEL].Mode.Long,
+ (ULONG) Mode
+ );
+
+ ((PDMA_CHANNEL_MODE) &Mode)->AccessTime = ACCESS_120NS;
+ ((PDMA_CHANNEL_MODE) &Mode)->TransferWidth = WIDTH_8BITS;
+ ((PDMA_CHANNEL_MODE) &Mode)->InterruptEnable = 0;
+ ((PDMA_CHANNEL_MODE) &Mode)->FastDmaCycle = 1;
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->Channel[FLOPPY_CHANNEL].Mode.Long,
+ (ULONG) Mode
+ );
+
+ ((PDMA_CHANNEL_MODE) &Mode)->AccessTime = ACCESS_80NS;
+ ((PDMA_CHANNEL_MODE) &Mode)->TransferWidth = WIDTH_16BITS;
+ ((PDMA_CHANNEL_MODE) &Mode)->InterruptEnable = 0;
+ ((PDMA_CHANNEL_MODE) &Mode)->BurstMode = 1;
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->Channel[SOUND_CHANNEL_A].Mode.Long,
+ (ULONG) Mode
+ );
+
+ ((PDMA_CHANNEL_MODE) &Mode)->AccessTime = ACCESS_80NS;
+ ((PDMA_CHANNEL_MODE) &Mode)->TransferWidth = WIDTH_16BITS;
+ ((PDMA_CHANNEL_MODE) &Mode)->InterruptEnable = 0;
+ ((PDMA_CHANNEL_MODE) &Mode)->BurstMode = 1;
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->Channel[SOUND_CHANNEL_B].Mode.Long,
+ (ULONG) Mode
+ );
+
+#endif
+
+ }
+
+ } else {
+
+ //
+ // An error was incurred for some reason. Set the return value
+ // to NULL.
+ //
+
+ AdapterObject = (PADAPTER_OBJECT) NULL;
+ }
+ } else {
+ AdapterObject = (PADAPTER_OBJECT) NULL;
+ }
+ return AdapterObject;
+
+ return (PADAPTER_OBJECT) NULL;
+}
+
+VOID
+IoFreeMapRegisters(
+ PADAPTER_OBJECT AdapterObject,
+ PVOID MapRegisterBase,
+ ULONG NumberOfMapRegisters
+ )
+/*++
+
+Routine Description:
+
+ This routine deallocates the map registers for the adapter. If there are
+ any queued adapter waiting for an attempt is made to allocate the next
+ entry.
+
+Arguments:
+
+ AdapterObject - The adapter object to where the map register should be
+ returned.
+
+ MapRegisterBase - The map register base of the registers to be deallocated.
+
+ NumberOfMapRegisters - The number of registers to be deallocated.
+
+Return Value:
+
+ None
+
+--+*/
+
+{
+ PADAPTER_OBJECT MasterAdapter;
+ LONG MapRegisterNumber;
+ PLIST_ENTRY Packet;
+ IO_ALLOCATION_ACTION Action;
+ PWAIT_CONTEXT_BLOCK Wcb;
+ KIRQL Irql;
+ ULONG Hint;
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ ULONG Limit;
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+
+ //
+ // Begin by getting the address of the master adapter.
+ //
+
+ if (AdapterObject->MasterAdapter != NULL) {
+ MasterAdapter = AdapterObject->MasterAdapter;
+ } else {
+ MasterAdapter = AdapterObject;
+ }
+
+ MapRegisterNumber = (PTRANSLATION_ENTRY) MapRegisterBase -
+ (PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase;
+
+ //
+ // Acquire the master adapter spinlock which locks the adapter queue and the
+ // bit map for the map registers.
+ //
+
+ KeAcquireSpinLock(&MasterAdapter->SpinLock, &Irql);
+
+ //
+ // Return the registers to the bit map.
+ //
+
+ RtlClearBits( MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ NumberOfMapRegisters
+ );
+
+ //
+ // Process any requests waiting for map registers in the adapter queue.
+ // Requests are processed until a request cannot be satisfied or until
+ // there are no more requests in the queue.
+ //
+
+ while(TRUE) {
+
+ if ( IsListEmpty(&MasterAdapter->AdapterQueue) ){
+ break;
+ }
+
+ Packet = RemoveHeadList( &MasterAdapter->AdapterQueue );
+ AdapterObject = CONTAINING_RECORD( Packet,
+ ADAPTER_OBJECT,
+ AdapterQueue
+ );
+ Wcb = AdapterObject->CurrentWcb;
+
+ //
+ // Attempt to allocate map registers for this request. Use the previous
+ // register base as a hint.
+ //
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ if (AdapterObject->Dma32BitAddresses) {
+ Hint = EISA_MIN_ADR / PAGE_SIZE;
+ Limit = EISA_MAX_ADR / PAGE_SIZE;
+ } else {
+ Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
+ Limit = ISA_MAX_ADR / PAGE_SIZE - NumberOfMapRegisters;
+ }
+#else // _DMA_EXPAND_
+// Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
+ Hint = (0x100000 / PAGE_SIZE); // M0024
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ MapRegisterNumber = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ NumberOfMapRegisters,
+ Hint
+ );
+
+ //
+ // Make sure this map register is valid for this adapter.
+ //
+
+ if ((ULONG) MapRegisterNumber < Hint) {
+
+ //
+ // Make it look like there are no map registers.
+ //
+
+ RtlClearBits(
+ MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ NumberOfMapRegisters
+ );
+
+ MapRegisterNumber = -1;
+ }
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ //
+ // Make sure this map register is valid for this adapter.
+ //
+
+ if ((ULONG) MapRegisterNumber >= Limit ) {
+
+ //
+ // Make it look like there are no map registers.
+ //
+
+ RtlClearBits(
+ MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ NumberOfMapRegisters
+ );
+
+ MapRegisterNumber = -1;
+ }
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ if (MapRegisterNumber == -1) {
+
+ //
+ // There were not enough free map registers. Put this request back on
+ // the adapter queue where is came from.
+ //
+
+ InsertHeadList( &MasterAdapter->AdapterQueue,
+ &AdapterObject->AdapterQueue
+ );
+
+ break;
+
+ }
+
+ KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
+
+ AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase + MapRegisterNumber);
+
+ //
+ // Invoke the driver's execution routine now.
+ //
+
+ Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
+ Wcb->CurrentIrp,
+ AdapterObject->MapRegisterBase,
+ Wcb->DeviceContext
+ );
+
+ //
+ // If the driver wishes to keep the map registers then set the number
+ // allocated to zero and set the action to deallocate object.
+ //
+
+ if (Action == DeallocateObjectKeepRegisters) {
+ AdapterObject->NumberOfMapRegisters = 0;
+ Action = DeallocateObject;
+ }
+
+ //
+ // If the driver would like to have the adapter deallocated,
+ // then deallocate any map registers allocated and then release
+ // the adapter object.
+ //
+
+ if (Action == DeallocateObject) {
+
+ //
+ // The map registers registers are deallocated here rather than in
+ // IoFreeAdapterChannel. This limits the number of times
+ // this routine can be called recursively possibly overflowing
+ // the stack. The worst case occurs if there is a pending
+ // request for the adapter that uses map registers and whos
+ // excution routine decallocates the adapter. In that case if there
+ // are no requests in the master adapter queue, then IoFreeMapRegisters
+ // will get called again.
+ //
+
+ if (AdapterObject->NumberOfMapRegisters != 0) {
+
+ //
+ // Deallocate the map registers and clear the count so that
+ // IoFreeAdapterChannel will not deallocate them again.
+ //
+
+ KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
+
+ RtlClearBits( MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ AdapterObject->NumberOfMapRegisters
+ );
+
+ AdapterObject->NumberOfMapRegisters = 0;
+
+ KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
+ }
+
+ IoFreeAdapterChannel( AdapterObject );
+ }
+
+ KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
+
+ }
+
+ KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
+}
+
+VOID
+IoFreeAdapterChannel(
+ IN PADAPTER_OBJECT AdapterObject
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is invoked to deallocate the specified adapter object.
+ Any map registers that were allocated are also automatically deallocated.
+ No checks are made to ensure that the adapter is really allocated to
+ a device object. However, if it is not, then kernel will bugcheck.
+
+ If another device is waiting in the queue to allocate the adapter object
+ it will be pulled from the queue and its execution routine will be
+ invoked.
+
+Arguments:
+
+ AdapterObject - Pointer to the adapter object to be deallocated.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ PKDEVICE_QUEUE_ENTRY Packet;
+ PADAPTER_OBJECT MasterAdapter;
+ BOOLEAN Busy = FALSE;
+ IO_ALLOCATION_ACTION Action;
+ PWAIT_CONTEXT_BLOCK Wcb;
+ KIRQL Irql;
+ LONG MapRegisterNumber;
+ ULONG Hint;
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ ULONG Limit;
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ //
+ // Begin by getting the address of the master adapter.
+ //
+
+ if (AdapterObject->MasterAdapter != NULL) {
+ MasterAdapter = AdapterObject->MasterAdapter;
+ } else {
+ MasterAdapter = AdapterObject;
+ }
+
+ //
+ // Pull requests of the adapter's device wait queue as long as the
+ // adapter is free and there are sufficient map registers available.
+ //
+
+ while( TRUE ){
+
+ //
+ // Begin by checking to see whether there are any map registers that
+ // need to be deallocated. If so, then deallocate them now.
+ //
+
+ if (AdapterObject->NumberOfMapRegisters != 0) {
+ IoFreeMapRegisters( AdapterObject,
+ AdapterObject->MapRegisterBase,
+ AdapterObject->NumberOfMapRegisters
+ );
+ }
+
+ //
+ // Simply remove the next entry from the adapter's device wait queue.
+ // If one was successfully removed, allocate any map registers that it
+ // requires and invoke its execution routine.
+ //
+
+ Packet = KeRemoveDeviceQueue( &AdapterObject->ChannelWaitQueue );
+ if (Packet == NULL) {
+
+ //
+ // There are no more requests break out of the loop.
+ //
+
+ break;
+ }
+
+ Wcb = CONTAINING_RECORD( Packet,
+ WAIT_CONTEXT_BLOCK,
+ WaitQueueEntry );
+
+ AdapterObject->CurrentWcb = Wcb;
+ AdapterObject->NumberOfMapRegisters = Wcb->NumberOfMapRegisters;
+
+ //
+ // Check to see whether this driver wishes to allocate any map
+ // registers. If so, then queue the device object to the master
+ // adapter queue to wait for them to become available. If the driver
+ // wants map registers, ensure that this adapter has enough total
+ // map registers to satisfy the request.
+ //
+
+ if (Wcb->NumberOfMapRegisters != 0) {
+ if (Wcb->NumberOfMapRegisters > MasterAdapter->MapRegistersPerChannel) {
+ KeBugCheck( INSUFFICIENT_SYSTEM_MAP_REGS );
+ }
+
+ //
+ // Lock the map register bit map and the adapter queue in the
+ // master adapter object. The channel structure offset is used as
+ // a hint for the register search.
+ //
+
+ KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
+
+ MapRegisterNumber = -1;
+
+ if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
+
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ if (AdapterObject->Dma32BitAddresses) {
+ Hint = EISA_MIN_ADR / PAGE_SIZE;
+ Limit = EISA_MAX_ADR / PAGE_SIZE;
+ } else {
+ Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
+ Limit = ISA_MAX_ADR / PAGE_SIZE - Wcb->NumberOfMapRegisters;
+ }
+#else // _DMA_EXPAND_
+// Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
+ Hint = (0x100000 / PAGE_SIZE); // M0024
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ MapRegisterNumber = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ Wcb->NumberOfMapRegisters,
+ Hint
+ );
+
+ //
+ // Make sure this map register is valid for this adapter.
+ //
+
+ if ((ULONG) MapRegisterNumber < Hint) {
+
+ //
+ // Make it look like there are no map registers.
+ //
+
+ RtlClearBits(
+ MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ Wcb->NumberOfMapRegisters
+ );
+
+ MapRegisterNumber = -1;
+ }
+// M0018 +++
+#if defined(_DMA_EXPAND_)
+ //
+ // Make sure this map register is valid for this adapter.
+ //
+
+ if ((ULONG) MapRegisterNumber >= Limit ) {
+
+ //
+ // Make it look like there are no map registers.
+ //
+
+ RtlClearBits(
+ MasterAdapter->MapRegisters,
+ MapRegisterNumber,
+ Wcb->NumberOfMapRegisters
+ );
+
+ MapRegisterNumber = -1;
+ }
+#endif // _DMA_EXPAND_
+// M0018 ---
+
+ }
+
+ if (MapRegisterNumber == -1) {
+
+ //
+ // There were not enough free map registers. Queue this request
+ // on the master adapter where is will wait until some registers
+ // are deallocated.
+ //
+
+ InsertTailList( &MasterAdapter->AdapterQueue,
+ &AdapterObject->AdapterQueue
+ );
+ Busy = 1;
+
+ } else {
+ AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase + MapRegisterNumber);
+ }
+
+ KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
+ }
+
+ //
+ // If there were either enough map registers available or no map
+ // registers needed to be allocated, invoke the driver's execution
+ // routine now.
+ //
+
+ if (!Busy) {
+ AdapterObject->CurrentWcb = Wcb;
+ Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
+ Wcb->CurrentIrp,
+ AdapterObject->MapRegisterBase,
+ Wcb->DeviceContext
+ );
+
+ //
+ // If the execution routine would like to have the adapter
+ // deallocated, then release the adapter object.
+ //
+
+ if (Action == KeepObject) {
+
+ //
+ // This request wants to keep the channel a while so break
+ // out of the loop.
+ //
+
+ break;
+ }
+
+ //
+ // If the driver wants to keep the map registers then set the
+ // number allocated to 0. This keeps the deallocation routine
+ // from deallocating them.
+ //
+
+ if (Action == DeallocateObjectKeepRegisters) {
+ AdapterObject->NumberOfMapRegisters = 0;
+ }
+ } else {
+
+ //
+ // This request did not get the requested number of map registers so
+ // out of the loop.
+ //
+
+ break;
+ }
+ }
+}
+
+BOOLEAN
+HalpCreateDmaStructures (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the structures necessary for DMA operations
+ and connects the intermediate interrupt dispatcher. It also connects
+ an interrupt handler to the DMA channel interrupt.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the second level interrupt dispatcher is connected, then a value of
+ TRUE is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ //
+ // Initialize the DMA interrupt dispatcher for I/O interrupts.
+ //
+
+ KeInitializeInterrupt( &HalpDmaChannelInterrupt,
+ HalpDmaChannel,
+ (PVOID) NULL,
+ (PKSPIN_LOCK) NULL,
+ DMA_LEVEL,
+ DMA_LEVEL,
+ DMA_LEVEL,
+ LevelSensitive,
+ FALSE,
+ 0,
+ FALSE
+ );
+
+ //
+ // Don't fail if the interrupt cannot be connected.
+ //
+
+ KeConnectInterrupt( &HalpDmaChannelInterrupt );
+
+ //
+ // Directly connect the local device interrupt dispatcher to the local
+ // device interrupt vector.
+ //
+ // N.B. This vector is reserved for exclusive use by the HAL (see
+ // interrupt initialization).
+ //
+
+ PCR->InterruptRoutine[DEVICE_LEVEL] = (PKINTERRUPT_ROUTINE) HalpDmaDispatch;
+
+/* start M0001 */
+#if defined(_R94A_)
+
+/* M0010 +++ */
+
+ //
+ // Enable DmaChannel Interrupt
+ //
+{
+ ULONG Dword,Channel;
+
+ Dword = READ_REGISTER_ULONG(&DMA_CONTROL->InterruptEnable.Long);
+
+ Dword |= 1; // S0011
+
+ WRITE_REGISTER_ULONG(&DMA_CONTROL->InterruptEnable.Long, Dword); // S011
+
+#if 0 // S0017
+ //
+ // Enable Interrupt when done every channel
+ //
+
+ for (Channel = 0; Channel < 4; Channel++) {
+ Dword = READ_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Mode);
+ Dword |= 0x20;
+ WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Mode, Dword);
+ }
+#endif // 0 // S0017
+}
+
+
+/* M0010 --- */
+
+ //
+ // Initialize Typhoon error interrupts.
+ //
+
+ HalpCreateTyphoonErrorStructures();
+
+#endif // _R94A_
+/* end M0001 */
+
+ return TRUE;
+}
+
+PHYSICAL_ADDRESS
+IoMapTransfer(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PMDL Mdl,
+ IN PVOID MapRegisterBase,
+ IN PVOID CurrentVa,
+ IN OUT PULONG Length,
+ IN BOOLEAN WriteToDevice
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is invoked to set up the map registers in the DMA controller
+ to allow a transfer to or from a device.
+
+Arguments:
+
+ AdapterObject - Pointer to the adapter object representing the DMA
+ controller channel that has been allocated.
+
+ Mdl - Pointer to the MDL that describes the pages of memory that are
+ being read or written.
+
+ MapRegisterBase - The address of the base map register that has been
+ allocated to the device driver for use in mapping the transfer.
+
+ CurrentVa - Current virtual address in the buffer described by the MDL
+ that the transfer is being done to or from.
+
+ Length - Supplies the length of the transfer. This determines the
+ number of map registers that need to be written to map the transfer.
+ Returns the length of the transfer which was actually mapped.
+
+ WriteToDevice - Boolean value that indicates whether this is a write
+ to the device from memory (TRUE), or vice versa.
+
+Return Value:
+
+ Returns the logical address to be used by bus masters.
+
+--*/
+
+{
+ PTRANSLATION_ENTRY DmaMapRegister = MapRegisterBase;
+ PULONG PageFrameNumber;
+ ULONG NumberOfPages;
+ ULONG Offset;
+ ULONG i;
+ KIRQL OldIrql; // kuriyama
+
+ //
+ // Begin by determining where in the buffer this portion of the operation
+ // is taking place.
+ //
+
+/* start M0004 */
+#if defined(_BBM_DMA_)
+//
+// Note. BBM Must use 4kbyte aligned CopyBuffer when ReadFromDevice
+//
+ ULONG bufferAddress;
+ ULONG bufferLogical;
+#endif // _BBM_DMA_
+/* end M0004 */
+
+#if 0 //M0008
+/* M0005 +++ */
+#if defined(_BETA_LIMIT_)
+{
+ ULONG PtagReg, Ptag, LtagReg, Ltag, DummyRead, logicalAddress;
+ KIRQL OldIrql;
+
+ if (!WriteToDevice) {
+ logicalAddress = (ULONG)((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
+ KeRaiseIrql(DEVICE_LEVEL, &OldIrql); // kuriyama
+ for (i = 0; i < 8; i++ ) {
+ PtagReg = (ULONG)&DMA_CONTROL->IoCachePhysicalTag[i];
+ LtagReg = (ULONG)&DMA_CONTROL->IoCacheLogicalTag[i];
+ Ptag = READ_REGISTER_ULONG(PtagReg);
+ Ltag = READ_REGISTER_ULONG(LtagReg);
+ if (Ptag & 0x1) {
+ if (Ltag & 0x1) {
+ if ((logicalAddress & 0xffffffc0) <= (Ltag & 0xffffffc0) && ((Ltag & 0xffffffc0) < (logicalAddress + *Length))) {
+ DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
+ DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
+ if (HalDebug)
+ DbgPrint("Found Valid Entry:0x%x Tag:0x%x. Read 0x%x=0x%x\n",
+ PtagReg, Ptag, (KSEG1_BASE|(Ptag&0xFFFFFFC0)), DummyRead);
+ }
+ }
+ }
+ }
+ KeLowerIrql(OldIrql);
+ }
+}
+#endif // _BETA_LIMIT_
+/* M0005 --- */
+#endif // 0 // M0008
+
+#if defined(_BBM_DMA_)
+{
+ ULONG PtagReg, Ptag, DummyRead;
+ // D001
+ if (*Length > (PAGE_SIZE * DMA_TRANSLATION_LIMIT / 8 / 8 )) { // kuriyama
+ DbgPrint("IoMapTransfer: *Length > %d pages\n", (DMA_TRANSLATION_LIMIT / 8 / 8));
+ }
+ KeRaiseIrql(DEVICE_LEVEL, &OldIrql); // kuriyama
+ for (i = 0; i < 8; i++ ) {
+ PtagReg = (ULONG)&DMA_CONTROL->IoCachePhysicalTag[i];
+ Ptag = READ_REGISTER_ULONG(PtagReg);
+ if (Ptag & 0x1) {
+ DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
+ DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
+ if (HalDebug)
+ DbgPrint("Found Valid Entry:0x%x Tag:0x%x. Read 0x%x=0x%x\n",
+ PtagReg, Ptag, (KSEG1_BASE|(Ptag&0xFFFFFFC0)), DummyRead);
+ }
+ }
+}
+#endif // _BBM_DMA_
+#if 0 // kuriyama // D001 Delete checking ByteMask
+// temp kuriyama start
+ for (i=0; i < 8; i++) {
+ if (READ_REGISTER_ULONG(&DMA_CONTROL->IoCacheLowByteMask[i])){
+ DbgPrint("IoMapTransfer : LowByteMask[%d] is 0x%x\n",i,(ULONG)READ_REGISTER_ULONG(&DMA_CONTROL->IoCacheLowByteMask[i]));
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+ }
+ if (READ_REGISTER_ULONG(&DMA_CONTROL->IoCacheHighByteMask[i])){
+ DbgPrint("IoMapTransfer : HighByteMask[%d] is 0x%x\n",i,(ULONG)READ_REGISTER_ULONG(&DMA_CONTROL->IoCacheHighByteMask[i]));
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+ }
+ }
+// temp kuriyaam end
+#endif // if 0 // kuriyama
+
+ Offset = BYTE_OFFSET( (PCHAR) CurrentVa - (PCHAR) Mdl->StartVa );
+
+
+ PageFrameNumber = (PULONG) (Mdl + 1);
+ NumberOfPages = (Offset + *Length + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ PageFrameNumber += (((PCHAR) CurrentVa - (PCHAR) Mdl->StartVa) >> PAGE_SHIFT);
+
+/* start M0004 */
+#if defined(_BBM_DMA_)
+//
+// Note. BBM Must use 4kbyte aligned CopyBuffer when ReadFromDevice
+//
+ if (!WriteToDevice) {
+// HalSweepDcache();
+// HalSweepIcache();
+ HalDump("IoMapTransfer: AdapterObject = %x\n",(ULONG)AdapterObject);
+ for (i = 0; i < NumberOfPages; i++) {
+ bufferLogical = (((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT) + (i << PAGE_SHIFT);
+ HalDump("IoMapTransfer: bufferLogical = %x\n",bufferLogical);
+ bufferAddress = CopyBufferPhysicalBase + bufferLogical;
+ HalDump("IoMapTransfer: bufferAddress = %x\n",bufferAddress);
+ (DmaMapRegister++)->PageFrame = bufferAddress;
+ }
+ } else {
+ for (i = 0; i < NumberOfPages; i++) {
+ (DmaMapRegister++)->PageFrame = (ULONG) *PageFrameNumber++ << PAGE_SHIFT;
+ }
+ }
+#else // _BBM_DMA_
+ for (i = 0; i < NumberOfPages; i++) {
+ (DmaMapRegister++)->PageFrame = (ULONG) *PageFrameNumber++ << PAGE_SHIFT;
+ }
+#endif // _BBM_DMA_
+/* end M0004 */
+
+/* start M0004 */
+#if defined(_BBM_DMA_)
+//
+// Note. BBM Must use 4kbyte aligned CopyBuffer when ReadFromDevice
+//
+ if (!WriteToDevice) {
+ Offset = 0;
+ ;
+ }
+#endif // _BBM_DMA_
+/* end M0004 */
+
+ //
+ // Set the offset to point to the map register plus the offset.
+ //
+
+ Offset += ((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
+/* start M0004 */
+ if (!WriteToDevice) {
+ HalDump("IoMapTransfer: Offset %x\n",Offset); /* M0004 */
+ HalDump("IoMapTransfer: Length %x\n",*Length); /* M0004 */
+ HalDump("IoMapTransfer: CurrentVa %x\n",CurrentVa); /* M0004 */
+ }
+/* end M0004 */
+
+ //
+ // Invalidate the translation entry.
+ //
+
+ WRITE_REGISTER_ULONG(&DMA_CONTROL->TranslationInvalidate.Long, 1);
+
+#if defined(_BBM_DMA_)
+ KeLowerIrql(OldIrql); // kuriyama
+#endif //_BBM_DMA_
+ if ( AdapterObject == NULL) {
+ return(RtlConvertUlongToLargeInteger(Offset));
+ }
+
+ if (AdapterObject->PagePort == NULL) {
+
+// M0013 +++
+#if defined(_R94A_)
+ //
+ // if Master Device, nothing set to DMAC.
+ //
+
+ if ( AdapterObject->AdapterBaseVa == &(DMA_CONTROL)->Channel[7]) {
+ return(RtlConvertUlongToLargeInteger(Offset));
+ }
+#endif // _R94A_
+// M0013 ---
+ //
+ // Set the local DMA Registers.
+ //
+
+ WRITE_REGISTER_ULONG(&((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Address.Long, Offset);
+ WRITE_REGISTER_ULONG(&((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->ByteCount.Long, *Length);
+
+ i = 0;
+ ((PDMA_CHANNEL_ENABLE) &i)->ChannelEnable = 1;
+ ((PDMA_CHANNEL_ENABLE) &i)->TransferDirection =
+ WriteToDevice ? DMA_WRITE_OP : DMA_READ_OP;
+ WRITE_REGISTER_ULONG(&((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long, i);
+
+
+ } else {
+
+ //
+ // Start the EISA DMA controller.
+ //
+
+ HalpEisaMapTransfer(
+ AdapterObject,
+ Offset,
+ *Length,
+ WriteToDevice
+ );
+
+ }
+ return(RtlConvertUlongToLargeInteger(Offset));
+}
+
+BOOLEAN
+IoFlushAdapterBuffers(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PMDL Mdl,
+ IN PVOID MapRegisterBase,
+ IN PVOID CurrentVa,
+ IN ULONG Length,
+ IN BOOLEAN WriteToDevice
+ )
+
+/*++
+
+Routine Description:
+
+ This routine flushes the DMA adapter object buffers and clears the
+ enable flag which aborts the dma.
+
+Arguments:
+
+ AdapterObject - Pointer to the adapter object representing the DMA
+ controller channel.
+
+ Mdl - A pointer to a Memory Descriptor List (MDL) that maps the locked-down
+ buffer to/from which the I/O occured.
+
+ MapRegisterBase - A pointer to the base of the map registers in the adapter
+ or DMA controller.
+
+ CurrentVa - The current virtual address in the buffer described the the Mdl
+ where the I/O operation occurred.
+
+ Length - Supplies the length of the transfer.
+
+ WriteToDevice - Supplies a BOOLEAN value that indicates the direction of
+ the data transfer was to the device.
+
+Return Value:
+
+ TRUE - If the transfer was successful.
+
+ FALSE - If there was an error in the transfer.
+
+--*/
+
+{
+
+ ULONG i;
+ UCHAR DataByte;
+
+/* start M0004 */
+#if defined(_BBM_DMA_)
+//
+// Note. BBM Must use 4kbyte aligned CopyBuffer when ReadFromDevice
+//
+
+#if 0
+ PCCHAR bufferAddress;
+#endif
+
+ PCCHAR mapAddress;
+ ULONG logicalAddress;
+ ULONG Offset;
+ PULONG PageFrameNumber;
+ ULONG NumberOfPages;
+
+ if (!WriteToDevice) {
+
+ HalDump("IoFlushAdapterBuffers: AdapterObject = %x\n",(ULONG)AdapterObject);
+
+#if 0
+ bufferAddress = MmGetSystemAddressForMdl(Mdl);
+ bufferAddress += (PCCHAR) CurrentVa - (PCCHAR) MmGetMdlVirtualAddress(Mdl);
+ HalDump("IoFlushAdapterBuffers: bufferAddress = %x\n",bufferAddress);
+ HalDump("IoFlushAdapterBuffers: Length = %x\n",Length);
+#endif
+
+ logicalAddress = (ULONG)((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
+ HalDump("IoFlushAdapterBuffers: logicalAddress = %x\n",logicalAddress);
+
+ Offset = BYTE_OFFSET( (PCHAR) CurrentVa - (PCHAR) Mdl->StartVa );
+ HalDump("IoFlushAdapterBuffers: Offset = %x\n",Offset);
+
+ mapAddress = (PCCHAR)(CopyBufferVirtualAddress + logicalAddress);
+
+ HalDump("IoFlushAdapterBuffers: mapAddress = %x\n",mapAddress);
+ HalDump("IoFlushAdapterBuffers: CurrentVa = %x\n",CurrentVa);
+
+// DbgBreakPoint();
+// RtlMoveMemory(CurrentVa, mapAddress, Length);
+// DbgBreakPoint();
+
+ PageFrameNumber = (PULONG) (Mdl + 1);
+ NumberOfPages = (Offset + Length + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ HalDump("IoFlushAdapterBuffers: NumberOfPages = %x\n",NumberOfPages);
+
+ PageFrameNumber += (((PCHAR) CurrentVa - (PCHAR) Mdl->StartVa) >> PAGE_SHIFT);
+
+ HalDump("IoFlushAdapterBuffers: PageFrameNumber = %x\n",PageFrameNumber);
+
+ if (NumberOfPages == 1) {
+
+#if 0
+ HalDump(
+ "IoFlushAdapterBuffers: USERBUFFER = %x\n",
+ (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE) + Offset
+ );
+ HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress);
+ HalDump("IoFlushAdapterBuffers: Length = %x\n",Length);
+#endif
+
+// HalSweepIcache();
+// HalSweepDcache();
+
+ RtlMoveMemory(
+ (PVOID)((((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE )+ Offset),
+ (PVOID)mapAddress, Length
+ );
+
+ } else if ( NumberOfPages == 2) {
+
+#if 0
+ HalDump(
+ "IoFlushAdapterBuffers: USERBUFFER = %x\n",
+ (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE) + Offset
+ );
+ HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress);
+ HalDump("IoFlushAdapterBuffers: Length = %x\n",PAGE_SIZE - Offset);
+#endif
+
+// HalSweepIcache();
+// HalSweepDcache();
+
+ RtlMoveMemory(
+ (PVOID)((((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE ) + Offset),
+ (PVOID)mapAddress, (ULONG)(PAGE_SIZE - Offset)
+ );
+
+#if 0
+ HalDump("IoFlushAdapterBuffers: USERBUFFER = %x\n",
+ (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE)
+ );
+ HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress + PAGE_SIZE + Offset);
+ HalDump("IoFlushAdapterBuffers: Length = %x\n" , BYTE_OFFSET(Length + Offset - 1) + 1);
+#endif
+
+// HalSweepIcache();
+// HalSweepDcache();
+
+ RtlMoveMemory(
+ ((PVOID)(((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE )),
+// (PVOID)(mapAddress + PAGE_SIZE + Offset),
+ (PVOID)(mapAddress + PAGE_SIZE - Offset), // H001
+ (ULONG)(BYTE_OFFSET(Length + Offset - 1) + 1)
+ );
+
+ } else {
+
+#if 0
+ HalDump(
+ "IoFlushAdapterBuffers: USERBUFFER = %x\n",
+ (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE) + Offset
+ );
+ HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress);
+ HalDump("IoFlushAdapterBuffers: Length = %x\n",PAGE_SIZE - Offset);
+#endif
+
+// HalSweepIcache();
+// HalSweepDcache();
+
+ RtlMoveMemory(
+ (PVOID)((((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE ) + Offset),
+ (PVOID)mapAddress,
+ (ULONG)(PAGE_SIZE - Offset)
+ );
+
+ for (i = 1; i < (NumberOfPages - 1); i++) {
+#if 0
+ HalDump("IoFlushAdapterBuffers: USERBUFFER = %x\n",
+ (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE)
+ );
+ HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress + (i * PAGE_SIZE) +Offset);
+ HalDump("IoFlushAdapterBuffers: Length = %x\n",PAGE_SIZE);
+#endif
+
+// HalSweepIcache();
+// HalSweepDcache();
+
+ RtlMoveMemory(
+ (PVOID)(((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE),
+// (PVOID)((mapAddress + (i * PAGE_SIZE)) + Offset),
+ (PVOID)(mapAddress + (i * PAGE_SIZE) - Offset), // H001
+ PAGE_SIZE
+ );
+
+ }
+
+#if 0
+ HalDump(
+ "IoFlushAdapterBuffers: USERBUFFER = %x\n",
+ (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE) + Offset
+ );
+ HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress + (i * PAGE_SIZE) + Offset);
+ HalDump("IoFlushAdapterBuffers: Length = %x\n",BYTE_OFFSET(Length + Offset - 1) + 1);
+#endif
+
+// HalSweepIcache();
+// HalSweepDcache();
+
+ RtlMoveMemory(
+ (PVOID)(((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE ),
+// (PVOID)(mapAddress + (i * PAGE_SIZE) + Offset),
+ (PVOID)(mapAddress + (NumberOfPages - 1) * PAGE_SIZE - Offset), // H001
+ (ULONG)(BYTE_OFFSET(Length + Offset - 1) + 1)
+ );
+
+ }
+ }
+#endif // _BBM_DMA_
+/* end M0004 */
+/* M0006 +++ */
+#if defined(_BETA_LIMIT_)
+#if 0 // M0008
+{
+ ULONG PtagReg, Ptag, LtagReg, Ltag, DummyRead, logicalAddress;
+ KIRQL OldIrql;
+
+ if (!WriteToDevice) { // M0005
+ logicalAddress = (ULONG)((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
+ // D001
+// DbgPrint("DmaFlush start\n");
+ KeRaiseIrql(DEVICE_LEVEL, &OldIrql); // kuriyama
+ for (i = 0; i < 8; i++ ) {
+ PtagReg = (ULONG)&DMA_CONTROL->IoCachePhysicalTag[i];
+ LtagReg = (ULONG)&DMA_CONTROL->IoCacheLogicalTag[i];
+ Ptag = READ_REGISTER_ULONG(PtagReg);
+ Ltag = READ_REGISTER_ULONG(LtagReg);
+ if (Ptag & 0x1) {
+ if (Ltag & 0x1) {
+ if ((logicalAddress & 0xffffffc0) <= (Ltag & 0xffffffc0) && ((Ltag & 0xffffffc0) < (logicalAddress + Length))) {
+ DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
+ DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
+ if (HalDebug)
+ DbgPrint("Found Valid Entry:0x%x Tag:0x%x. Read 0x%x=0x%x\n",
+ PtagReg, Ptag, (KSEG1_BASE|(Ptag&0xFFFFFFC0)), DummyRead);
+ }
+ }
+ }
+ }
+ KeLowerIrql(OldIrql);
+// DbgPrint("DmaFlush end\n");
+ } // M0005
+
+}
+#endif // 0 //M0008
+/* M0005,M0014 +++ */
+{
+ ULONG Offset, NumberOfPages;
+ PULONG PageFrameNumber;
+ KIRQL OldIrql;
+
+ if (Length != 0) { //S0015
+ if (!WriteToDevice) {
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql); // kuriyama
+ Offset = BYTE_OFFSET( (PCHAR) CurrentVa - (PCHAR) Mdl->StartVa );
+
+ PageFrameNumber = (PULONG) (Mdl + 1);
+ NumberOfPages = (Offset + Length + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ PageFrameNumber += (((PCHAR) CurrentVa - (PCHAR) Mdl->StartVa) >> PAGE_SHIFT);
+
+ if (NumberOfPages == 1) {
+ HalViewMemory((PVOID)((KSEG1_BASE |(((ULONG) *PageFrameNumber++
+ << PAGE_SHIFT) + Offset))),
+ Length);
+ } else {
+ HalViewMemory( (PVOID)((KSEG1_BASE |(((ULONG) *PageFrameNumber++
+ << PAGE_SHIFT) + Offset))),
+ (PAGE_SIZE - Offset));
+ for (i = 1; i < NumberOfPages -1; i++) {
+ HalViewMemory( (PVOID)((KSEG1_BASE |((ULONG) *PageFrameNumber++
+ << PAGE_SHIFT))), PAGE_SIZE);
+ }
+ HalViewMemory( (PVOID)((KSEG1_BASE
+ |((ULONG) *PageFrameNumber++ << PAGE_SHIFT))),
+ BYTE_OFFSET(Offset + Length -1) +1);
+ }
+ KeLowerIrql(OldIrql);
+ }
+ }
+}
+
+/* M0005,M0014 --- */
+
+#endif // _BETA_LIMIT_
+/* M0006 --- */
+
+ if (AdapterObject == NULL) {
+
+ //
+ // This is a master adadapter so there is nothing to do.
+ //
+
+ return(TRUE);
+ }
+
+ if (AdapterObject->PagePort) {
+
+ //
+ // If this is a master channel, then just return since the DMA
+ // request does not need to be disabled.
+ //
+
+ DataByte = AdapterObject->AdapterMode;
+
+ if (((PDMA_EISA_MODE) &DataByte)->RequestMode == CASCADE_REQUEST_MODE) {
+
+ return(TRUE);
+
+ }
+
+ //
+ // Clear the EISA DMA adapter.
+ //
+
+ if (AdapterObject->AdapterNumber == 1) {
+
+ //
+ // This request is for DMA controller 1
+ //
+
+ PDMA1_CONTROL dmaControl;
+
+ dmaControl = AdapterObject->AdapterBaseVa;
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->SingleMask,
+ (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
+ );
+
+ } else {
+
+ //
+ // This request is for DMA controller 2
+ //
+
+ PDMA2_CONTROL dmaControl;
+
+ dmaControl = AdapterObject->AdapterBaseVa;
+
+ WRITE_REGISTER_UCHAR(
+ &dmaControl->SingleMask,
+ (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
+ );
+
+ }
+
+ } else {
+
+// M0013 +++
+#if defined(_R94A_)
+ //
+ // if Master Device, nothing set to DMAC.
+ //
+
+ if ( AdapterObject->AdapterBaseVa == &(DMA_CONTROL)->Channel[7]) {
+ return(TRUE);
+ }
+#endif // _R94A_
+// M0013 ---
+ //
+ // Clear on board DMA
+ //
+
+ i = READ_REGISTER_ULONG(
+ &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long
+ );
+
+ ((PDMA_CHANNEL_ENABLE) &i)->ChannelEnable = 0;
+ WRITE_REGISTER_ULONG(
+ &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long,
+ i
+ );
+
+ i = READ_REGISTER_USHORT(
+ &((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable
+ );
+ }
+
+ return(TRUE);
+}
+
+IO_ALLOCATION_ACTION
+HalpAllocationRoutine (
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID MapRegisterBase,
+ IN PVOID Context
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called by HalAllocateAdapterChannel when sufficent resources
+ are available to the driver. This routine saves the MapRegisterBase,
+ and set the event pointed to by the context parameter.
+
+Arguments:
+
+ DeviceObject - Supplies a pointer where the map register base should be
+ stored.
+
+ Irp - Unused.
+
+ MapRegisterBase - Supplied by the Io subsystem for use in IoMapTransfer.
+
+ Context - Supplies a pointer to an event which is set to indicate the
+ AdapterObject has been allocated.
+
+Return Value:
+
+ DeallocateObjectKeepRegisters - Indicates the adapter should be freed
+ and mapregisters should remain allocated after return.
+
+--*/
+
+{
+
+ UNREFERENCED_PARAMETER(Irp);
+
+ *((PVOID *) DeviceObject) = MapRegisterBase;
+
+ (VOID) KeSetEvent( (PKEVENT) Context, 0L, FALSE );
+
+ return(DeallocateObjectKeepRegisters);
+}
+
+#if 0 // CHG0001
+
+ULONG
+HalGetBusDataByOffset(
+ IN BUS_DATA_TYPE BusDataType,
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function returns the bus data for a slot or address.
+
+Arguments:
+
+ BusDataType - Supplies the type of bus.
+
+ BusNumber - Indicates which bus.
+
+ Buffer - Supplies the space to store the data.
+
+ Offset - Offset in the BusData buffer
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+--*/
+
+{
+
+ ULONG DataLength = 0;
+
+ switch (BusDataType) {
+ case EisaConfiguration:
+ DataLength = HalpReadEisaData(BusNumber, SlotNumber, Buffer, Offset, Length);
+ break;
+
+/* start M0001 */
+#if 0
+#if defined(_R94A_)
+
+ case PCIConfiguration:
+ DataLength = HalpReadPCIData(BusNumber, SlotNumber, Buffer, Offset, Length);
+ break;
+
+#endif // _R94A_
+#endif // 0
+/* end M0001 */
+
+ }
+
+ return(DataLength);
+
+}
+ULONG
+HalGetBusData(
+ IN BUS_DATA_TYPE BusDataType,
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ Subset of HalGetBusDataByOffset, just pass the request along.
+
+--*/
+{
+ return HalGetBusDataByOffset (
+ BusDataType,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ 0,
+ Length
+ );
+}
+
+ULONG
+HalSetBusDataByOffset(
+ IN BUS_DATA_TYPE BusDataType,
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function sets the bus data for a slot or address.
+
+Arguments:
+
+ BusDataType - Supplies the type of bus.
+
+ BusNumber - Indicates which bus.
+
+ Buffer - Supplies the space to store the data.
+
+ Offset - Offset in the BusData buffer
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+--*/
+
+{
+
+ ULONG DataLength = 0;
+
+/* start M0001 */
+#if 0
+#if defined(_R94A_)
+
+ switch (BusDataType) {
+
+ case PCIConfiguration:
+ DataLength = HalpWritePCIData(BusNumber, SlotNumber, Buffer, Offset, Length);
+ break;
+ }
+
+#endif // _R94A_
+#endif // 0
+/* end M0001 */
+
+ return(DataLength);
+}
+
+ULONG
+HalSetBusData(
+ IN BUS_DATA_TYPE BusDataType,
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ Subset of HalGetBusDataByOffset, just pass the request along.
+
+--*/
+{
+ return HalSetBusDataByOffset(
+ BusDataType,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ 0,
+ Length
+ );
+}
+
+NTSTATUS
+HalAssignSlotResources (
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName OPTIONAL,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ IN INTERFACE_TYPE BusType,
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN OUT PCM_RESOURCE_LIST *AllocatedResources
+ )
+/*++
+
+Routine Description:
+
+ Reads the targeted device to determine it's required resources.
+ Calls IoAssignResources to allocate them.
+ Sets the targeted device with it's assigned resoruces
+ and returns the assignments to the caller.
+
+Arguments:
+
+ RegistryPath - Passed to IoAssignResources.
+ A device specific registry path in the current-control-set, used
+ to check for pre-assigned settings and to track various resource
+ assignment information for this device.
+
+ DriverClassName Used to report the assigned resources for the driver/device
+ DriverObject - Used to report the assigned resources for the driver/device
+ DeviceObject - Used to report the assigned resources for the driver/device
+ (ie, IoReportResoruceUsage)
+ BusType
+ BusNumber
+ SlotNumber - Together BusType,BusNumber,SlotNumber uniquely
+ indentify the device to be queried & set.
+
+Return Value:
+
+ STATUS_SUCCESS or error
+
+--*/
+{
+ //
+ // This HAL doesn't support any buses which support
+ // HalAssignSlotResources
+ //
+
+ return STATUS_NOT_SUPPORTED;
+
+}
+
+NTSTATUS
+HalAdjustResourceList (
+ IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
+ )
+/*++
+
+Routine Description:
+
+ Takes the pResourceList and limits any requested resource to
+ it's corrisponding bus requirements.
+
+Arguments:
+
+ pResourceList - The resource list to adjust.
+
+Return Value:
+
+ STATUS_SUCCESS or error
+
+--*/
+{
+ //
+ // BUGBUG: This function should verify that the resoruces fit
+ // the bus requirements - for now we will assume that the bus
+ // can support anything the device may ask for.
+ //
+
+ return STATUS_SUCCESS;
+}
+
+ULONG
+HalpReadEisaData (
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function returns the Eisa bus data for a slot or address.
+
+Arguments:
+
+ BusDataType - Supplies the type of bus.
+
+ BusNumber - Indicates which bus.
+
+ Buffer - Supplies the space to store the data.
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+--*/
+
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ OBJECT_ATTRIBUTES BusObjectAttributes;
+ PWSTR EisaPath = L"\\Registry\\Machine\\Hardware\\Description\\System\\EisaAdapter";
+ PWSTR ConfigData = L"Configuration Data";
+ ANSI_STRING TmpString;
+ UCHAR BusString[] = "00";
+ UNICODE_STRING RootName, BusName;
+ UNICODE_STRING ConfigDataName;
+ NTSTATUS NtStatus;
+ PKEY_VALUE_FULL_INFORMATION ValueInformation;
+ PCM_FULL_RESOURCE_DESCRIPTOR Descriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource;
+ PCM_EISA_SLOT_INFORMATION SlotInformation;
+ ULONG PartialCount;
+ ULONG TotalDataSize, SlotDataSize;
+ HANDLE EisaHandle, BusHandle;
+ ULONG BytesWritten, BytesNeeded;
+ PUCHAR KeyValueBuffer;
+ ULONG i;
+ ULONG DataLength = 0;
+ PUCHAR DataBuffer = Buffer;
+ BOOLEAN Found = FALSE;
+
+
+ RtlInitUnicodeString(
+ &RootName,
+ EisaPath
+ );
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &RootName,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)NULL,
+ NULL
+ );
+
+ //
+ // Open the EISA root
+ //
+
+ NtStatus = ZwOpenKey(
+ &EisaHandle,
+ KEY_READ,
+ &ObjectAttributes
+ );
+
+ if (!NT_SUCCESS(NtStatus)) {
+ KdPrint(("HAL: Open Status = %x\n",NtStatus));
+ return(0);
+ }
+
+ //
+ // Init bus number path
+ //
+
+ if (BusNumber > 99) {
+ return (0);
+ }
+
+ if (BusNumber > 9) {
+ BusString[0] += (UCHAR) (BusNumber/10);
+ BusString[1] += (UCHAR) (BusNumber % 10);
+ } else {
+ BusString[0] += (UCHAR) BusNumber;
+ BusString[1] = '\0';
+ }
+
+ RtlInitAnsiString(
+ &TmpString,
+ BusString
+ );
+
+ RtlAnsiStringToUnicodeString(
+ &BusName,
+ &TmpString,
+ TRUE
+ );
+
+
+ InitializeObjectAttributes(
+ &BusObjectAttributes,
+ &BusName,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)EisaHandle,
+ NULL
+ );
+
+ //
+ // Open the EISA root + Bus Number
+ //
+
+ NtStatus = ZwOpenKey(
+ &BusHandle,
+ KEY_READ,
+ &BusObjectAttributes
+ );
+
+ if (!NT_SUCCESS(NtStatus)) {
+ KdPrint(("HAL: Opening Bus Number: Status = %x\n",NtStatus));
+ return(0);
+ }
+
+ //
+ // opening the configuration data. This first call tells us how
+ // much memory we need to allocate
+ //
+
+ RtlInitUnicodeString(
+ &ConfigDataName,
+ ConfigData
+ );
+
+ //
+ // This should fail. We need to make this call so we can
+ // get the actual size of the buffer to allocate.
+ //
+
+ NtStatus = ZwQueryValueKey(
+ BusHandle,
+ &ConfigDataName,
+ KeyValueFullInformation,
+ ValueInformation,
+ 0,
+ &BytesNeeded
+ );
+
+ KeyValueBuffer = ExAllocatePool(
+ NonPagedPool,
+ BytesNeeded
+ );
+
+ if (KeyValueBuffer == NULL) {
+ KdPrint(("HAL: Cannot allocate Key Value Buffer\n"));
+ ZwClose(BusHandle);
+ return(0);
+ }
+
+ ValueInformation = (PKEY_VALUE_FULL_INFORMATION)KeyValueBuffer;
+
+ NtStatus = ZwQueryValueKey(
+ BusHandle,
+ &ConfigDataName,
+ KeyValueFullInformation,
+ ValueInformation,
+ BytesNeeded,
+ &BytesWritten
+ );
+
+
+ ZwClose(BusHandle);
+
+ if (!NT_SUCCESS(NtStatus) || ValueInformation->DataLength == 0) {
+ KdPrint(("HAL: Query Config Data: Status = %x\n",NtStatus));
+ ExFreePool(KeyValueBuffer);
+ return(0);
+ }
+
+
+ //
+ // We get back a Full Resource Descriptor List
+ //
+
+ Descriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PUCHAR)ValueInformation +
+ ValueInformation->DataOffset);
+
+ PartialResource = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
+ &(Descriptor->PartialResourceList.PartialDescriptors);
+ PartialCount = Descriptor->PartialResourceList.Count;
+
+ for (i = 0; i < PartialCount; i++) {
+
+ //
+ // Do each partial Resource
+ //
+
+ switch (PartialResource->Type) {
+ case CmResourceTypeNull:
+ case CmResourceTypePort:
+ case CmResourceTypeInterrupt:
+ case CmResourceTypeMemory:
+ case CmResourceTypeDma:
+
+ //
+ // We dont care about these.
+ //
+
+ PartialResource++;
+
+ break;
+
+ case CmResourceTypeDeviceSpecific:
+
+ //
+ // Bingo!
+ //
+
+ TotalDataSize = PartialResource->u.DeviceSpecificData.DataSize;
+
+ SlotInformation = (PCM_EISA_SLOT_INFORMATION)
+ ((PUCHAR)PartialResource +
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+
+ while (((LONG)TotalDataSize) > 0) {
+
+ if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) {
+
+ SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION);
+
+ } else {
+
+ SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) +
+ SlotInformation->NumberFunctions *
+ sizeof(CM_EISA_FUNCTION_INFORMATION);
+ }
+
+ if (SlotDataSize > TotalDataSize) {
+
+ //
+ // Something is wrong again
+ //
+
+ ExFreePool(KeyValueBuffer);
+ return(0);
+
+ }
+
+ if (SlotNumber != 0) {
+
+ SlotNumber--;
+
+ SlotInformation = (PCM_EISA_SLOT_INFORMATION)
+ ((PUCHAR)SlotInformation + SlotDataSize);
+
+ TotalDataSize -= SlotDataSize;
+
+ continue;
+
+ }
+
+ //
+ // This is our slot
+ //
+
+ Found = TRUE;
+ break;
+
+ }
+
+ //
+ // End loop
+ //
+
+ i = PartialCount;
+
+ break;
+
+ default:
+ KdPrint(("Bad Data in registry!\n"));
+ ExFreePool(KeyValueBuffer);
+ return(0);
+ }
+ }
+
+ if (Found) {
+
+ i = Length + Offset;
+ if (i > SlotDataSize) {
+ i = SlotDataSize;
+ }
+
+ DataLength = i - Offset;
+ RtlMoveMemory ((PVOID)Buffer, (PVOID)((PUCHAR)SlotInformation + Offset), (ULONG)DataLength);
+
+ }
+
+ ExFreePool(KeyValueBuffer);
+ return DataLength;
+}
+#endif
+
+ULONG
+HalReadDmaCounter(
+ IN PADAPTER_OBJECT AdapterObject
+ )
+/*++
+
+Routine Description:
+
+ This function reads the DMA counter and returns the number of bytes left
+ to be transfered.
+
+Arguments:
+
+ AdapterObject - Supplies a pointer to the adapter object to be read.
+
+Return Value:
+
+ Returns the number of bytes still be be transfered.
+
+--*/
+
+{
+ ULONG i;
+ ULONG saveEnable;
+ ULONG count;
+ ULONG high;
+
+ if (AdapterObject->PagePort) {
+
+ //
+ // Determine the controller number based on the Adapter number.
+ //
+
+ if (AdapterObject->AdapterNumber == 1) {
+
+ //
+ // This request is for DMA controller 1
+ //
+
+ PDMA1_CONTROL dmaControl;
+
+ dmaControl = AdapterObject->AdapterBaseVa;
+
+ //
+ // Initialize count to a value which will not match.
+ //
+
+ count = 0xFFFF00;
+
+ //
+ // Loop until the same high byte is read twice.
+ //
+
+ do {
+
+ high = count;
+
+ WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
+
+ //
+ // Read the current DMA count.
+ //
+
+ count = READ_PORT_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseCount
+ );
+
+ count |= READ_PORT_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseCount
+ ) << 8;
+
+ } while ((count & 0xFFFF00) != (high & 0xFFFF00));
+
+ } else {
+
+ //
+ // This request is for DMA controller 2
+ //
+
+ PDMA2_CONTROL dmaControl;
+
+ dmaControl = AdapterObject->AdapterBaseVa;
+
+ //
+ // Initialize count to a value which will not match.
+ //
+
+ count = 0xFFFF00;
+
+ //
+ // Loop until the same high byte is read twice.
+ //
+
+ do {
+
+ high = count;
+
+ WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
+
+ //
+ // Read the current DMA count.
+ //
+
+ count = READ_PORT_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseCount
+ );
+
+ count |= READ_PORT_UCHAR(
+ &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
+ .DmaBaseCount
+ ) << 8;
+
+ } while ((count & 0xFFFF00) != (high & 0xFFFF00));
+
+ }
+
+ //
+ // The DMA counter has a bias of one and can only be 16 bit long.
+ //
+
+ count = (count + 1) & 0xFFFF;
+
+ } else {
+
+ //
+ // Disable the DMA
+ //
+
+ i = READ_REGISTER_ULONG(
+ &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long
+ );
+
+ saveEnable = i;
+
+ ((PDMA_CHANNEL_ENABLE) &i)->ChannelEnable = 0;
+ WRITE_REGISTER_ULONG(
+ &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long,
+ i
+ );
+
+ //
+ // Read the transfer count.
+ //
+
+ count = 0xfffff & READ_REGISTER_ULONG(&((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->ByteCount.Long); // beta typhoon errata// M0009
+
+ //
+ // Reset the Enable register.
+ //
+
+ WRITE_REGISTER_ULONG(
+ &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long,
+ saveEnable
+ );
+
+ }
+
+ return(count);
+}
+
+
+BOOLEAN
+HalpDmaChannel(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ )
+/*++
+
+Routine Description:
+
+ This routine is called when a DMA channel interrupt occurs.
+ These should never occur. Bugcheck is called if an error does occur.
+
+Arguments:
+
+ Interrupt - Supplies a pointer to the interrupt object
+
+ ServiceContext - Bug number to call bugcheck with.
+
+Return Value:
+
+ Returns TRUE.
+
+--*/
+{
+
+ ULONG DataWord;
+ ULONG Channel;
+ DMA_CHANNEL_ENABLE ChannelWord;
+ ULONG ErrorFlag = 0; /* M0003 */
+
+#if defined(_JAZZ_)
+
+ //
+ // Read the DMA channel interrupt source register.
+ //
+
+ DataWord = READ_REGISTER_ULONG(&DMA_CONTROL->InterruptSource.Long);
+
+ for (Channel = 0; Channel < 8; Channel++) {
+
+ //
+ // Determine which channel is interrupting.
+ //
+
+ if (!(DataWord & ( 1 << Channel))) {
+ continue;
+ }
+
+ DmaChannelMsg[18] = (CHAR) Channel + '0';
+
+ HalDisplayString(DmaChannelMsg);
+
+ *((PULONG) &ChannelWord) =
+ READ_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Enable.Long);
+
+ if (ChannelWord.TerminalCount) {
+ HalDisplayString("Terminal count was reached.\n");
+ }
+
+ if (ChannelWord.MemoryError) {
+ HalDisplayString("A memory error was detected.\n");
+ }
+
+ if (ChannelWord.TranslationError) {
+ HalDisplayString("A translation error occured.\n");
+ }
+
+ }
+
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+
+#endif
+
+/* start M0001 */
+#if defined(_R94A_)
+
+ HalpChangePanicFlag(16, 0x01, 0x10); // S0023
+
+ //
+ // Read the DMA channel interrupt source register.
+ //
+
+ DataWord = READ_REGISTER_ULONG(&DMA_CONTROL->ChannelInterruptAcknowledge.Long);
+
+ for (Channel = 0; Channel < 4; Channel++) {
+
+ //
+ // Determine which channel is interrupting.
+ //
+
+ if (!(DataWord & ( 1 << Channel))) {
+ continue;
+ }
+
+ DmaChannelMsg[18] = (CHAR) Channel + '0';
+
+
+ *((PULONG) &ChannelWord) =
+ READ_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Enable.Long);
+
+/* start M0002 */
+ if (ChannelWord.TerminalCount) {
+ if ((0xfffff & READ_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].ByteCount.Long)) != 0) { // beta typhoon errta // M0009
+ HalDisplayString(DmaChannelMsg);
+ HalDisplayString("Terminal count was reached."); // S0011
+ ErrorFlag++;
+ }
+ }
+
+ if (ChannelWord.MemoryError) {
+ HalDisplayString(DmaChannelMsg);
+ HalDisplayString("A memory error was detected."); // S0011
+ ErrorFlag++;
+ }
+
+ if (ChannelWord.ParityError) {
+ HalDisplayString(DmaChannelMsg);
+ HalDisplayString("A Parity error occured."); // S0011
+ ErrorFlag++;
+ }
+
+ if (ChannelWord.MasterAbort) {
+ HalDisplayString(DmaChannelMsg);
+ HalDisplayString("A PCIBus Master Abort error occured."); // S0011
+ ErrorFlag++;
+ }
+
+ // Clear Dma Channel Interrupt
+ WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Enable.Long, 0x00000100); // M0009
+/* end M0002 */
+ }
+
+ if (ErrorFlag != 0) {
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+ }
+#endif // _R94A_
+/* end M0001 */
+
+ return(TRUE);
+}
+
+VOID
+HalpAllocateMapRegisters(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+/*++
+
+Routine Description:
+
+ This routine allocates memory for map registers directly from the loader
+ block information. This memory must be non-cached and contiguous.
+
+Arguments:
+
+ LoaderBlock - Pointer to the loader block which contains the memory descriptors.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
+ PLIST_ENTRY NextMd;
+ ULONG MaxPageAddress;
+ ULONG PhysicalAddress;
+ ULONG MapRegisterSize;
+
+ MapRegisterSize = DMA_TRANSLATION_LIMIT;
+ MapRegisterSize = BYTES_TO_PAGES(MapRegisterSize);
+
+ //
+ // The address must be in KSEG 0.
+ //
+
+ MaxPageAddress = (KSEG1_BASE >> PAGE_SHIFT) - 1 ;
+
+ //
+ // Scan the memory allocation descriptors and allocate map buffers
+ //
+
+ NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
+ while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
+ Descriptor = CONTAINING_RECORD(NextMd,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ //
+ // Search for a block of memory which is contains a memory chuck
+ // that is greater than size pages, and has a physical address less
+ // than MAXIMUM_PHYSICAL_ADDRESS.
+ //
+
+ if ((Descriptor->MemoryType == LoaderFree ||
+ Descriptor->MemoryType == MemoryFirmwareTemporary) &&
+ (Descriptor->BasePage) &&
+ (Descriptor->PageCount >= MapRegisterSize) &&
+ (Descriptor->BasePage + MapRegisterSize < MaxPageAddress)) {
+
+ PhysicalAddress = Descriptor->BasePage << PAGE_SHIFT;
+ break;
+ }
+
+ NextMd = NextMd->Flink;
+ }
+
+ //
+ // Use the extra descriptor to define the memory at the end of the
+ // original block.
+ //
+
+ ASSERT(NextMd != &LoaderBlock->MemoryDescriptorListHead);
+
+ if (NextMd == &LoaderBlock->MemoryDescriptorListHead)
+ return;
+
+ //
+ // Adjust the memory descriptors.
+ //
+
+ Descriptor->BasePage += MapRegisterSize;
+ Descriptor->PageCount -= MapRegisterSize;
+
+ if (Descriptor->PageCount == 0) {
+
+ //
+ // The whole block was allocated,
+ // Remove the entry from the list completely.
+ //
+
+ RemoveEntryList(&Descriptor->ListEntry);
+
+ }
+
+ //
+ // Save the map register base.
+ //
+
+ HalpMapRegisterPhysicalBase = PhysicalAddress;
+
+#if defined(_BBM_DMA_)
+/* start kuriyama TLB fill 0xff */ // D001
+ RtlFillMemory( (HalpMapRegisterPhysicalBase | KSEG1_BASE), 0x2000, 0xff);
+/* end kuriyama TLB fill 0xff */
+#endif // _BBM_DMA_
+
+/* start M0004 */
+#if defined(_BBM_DMA_)
+ HalpAllocateCopyBuffer(LoaderBlock);
+#endif // _BBM_DMA_
+/* end M0004 */
+}
+
+/* start M0001 */
+#if defined(_R94A_)
+BOOLEAN
+HalpCreateTyphoonErrorStructures (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the structures necessary for Typhoon Error
+ interrupt dispatcher. It also connects an interrupt handler to the
+ Typhoon Error interrupt.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the second level interrupt dispatcher is connected, then a value of
+ TRUE is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+ //
+ // Initialize the Typhoon Error interrupt dispatcher for I/O interrupts.
+ //
+
+ KeInitializeInterrupt( &HalpTyphoonErrorInterrupt,
+ HalpTyphoonError,
+ (PVOID) NULL,
+ (PKSPIN_LOCK) NULL,
+ TYPHOON_ERROR_INTERRUPT_VECTOR,
+ DEVICE_LEVEL,
+ DEVICE_LEVEL,
+ LevelSensitive,
+ FALSE,
+ 0,
+ FALSE
+ );
+
+ //
+ // Don't fail if the interrupt cannot be connected.
+ //
+
+ return KeConnectInterrupt( &HalpTyphoonErrorInterrupt );
+
+}
+#endif // _R94A_
+/* end M0001 */
+
+/* start M0001 */
+#if defined(_R94A_)
+BOOLEAN
+HalpTyphoonError(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ )
+/*++
+
+Routine Description:
+
+ This routine is called when a Typhoon Error interrupt occurs.
+ This error is cretical. Bugcheck is called if an error does occur.
+
+Arguments:
+
+ Interrupt - Supplies a pointer to the interrupt object
+
+ ServiceContext - Bug number to call bugcheck with.
+
+Return Value:
+
+ Returns TRUE.
+
+ Note. This function never return. This function call always KeBugCheck().
+
+--*/
+{
+
+ ULONG DataWord;
+
+ HalpChangePanicFlag(16, 0x01, 0x10); // S0023
+
+ //
+ // Read the Typhoon Error Status register.
+ //
+
+ DataWord = READ_REGISTER_ULONG(&DMA_CONTROL->TyphoonErrorStatus);
+
+ HalDisplayString("\nHAL: Internal master error occurred.\n"); // S0022
+
+ if ( DataWord & 2) {
+
+ HalDisplayString("ethernet bus master error\n");
+
+ }
+
+ if ( DataWord & 4) {
+
+ HalDisplayString("SCSI port 1 bus master error\n");
+
+ }
+
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+
+
+ return(TRUE);
+}
+#endif // _R94A_
+/* end M0001 */
+
+#if defined(_BBM_DMA_)
+VOID
+HalpAllocateCopyBuffer(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+/*++
+
+Routine Description:
+
+ This routine allocates memory for copybuffer directly from the loader
+ block information. This memory must be non-cached and contiguous.
+
+Arguments:
+
+ LoaderBlock - Pointer to the loader block which contains the memory descriptors.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
+ PLIST_ENTRY NextMd;
+ ULONG MaxPageAddress;
+ ULONG PhysicalAddress;
+ ULONG MapRegisterSize;
+
+ MapRegisterSize = 0x400000;
+ MapRegisterSize = BYTES_TO_PAGES(MapRegisterSize);
+
+ //
+ // The address must be in KSEG 0.
+ //
+
+ MaxPageAddress = (KSEG1_BASE >> PAGE_SHIFT) - 1 ;
+
+ //
+ // Scan the memory allocation descriptors and allocate map buffers
+ //
+
+ NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
+ while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
+ Descriptor = CONTAINING_RECORD(NextMd,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ //
+ // Search for a block of memory which is contains a memory chuck
+ // that is greater than size pages, and has a physical address less
+ // than MAXIMUM_PHYSICAL_ADDRESS.
+ //
+
+ if ((Descriptor->MemoryType == LoaderFree ||
+ Descriptor->MemoryType == MemoryFirmwareTemporary) &&
+ (Descriptor->BasePage) &&
+ (Descriptor->PageCount >= MapRegisterSize) &&
+ (Descriptor->BasePage + MapRegisterSize < MaxPageAddress)) {
+
+ PhysicalAddress = Descriptor->BasePage << PAGE_SHIFT;
+ break;
+ }
+
+ NextMd = NextMd->Flink;
+ }
+
+ //
+ // Use the extra descriptor to define the memory at the end of the
+ // original block.
+ //
+
+ ASSERT(NextMd != &LoaderBlock->MemoryDescriptorListHead);
+
+ if (NextMd == &LoaderBlock->MemoryDescriptorListHead)
+ return;
+
+ //
+ // Adjust the memory descriptors.
+ //
+
+ Descriptor->BasePage += MapRegisterSize;
+ Descriptor->PageCount -= MapRegisterSize;
+
+ if (Descriptor->PageCount == 0) {
+
+ //
+ // The whole block was allocated,
+ // Remove the entry from the list completely.
+ //
+
+ RemoveEntryList(&Descriptor->ListEntry);
+
+ }
+
+ //
+ // Save the map register base.
+ //
+
+ CopyBufferPhysicalBase = PhysicalAddress;
+ HalDump("Common Buffer Physical = %x\n",CopyBufferPhysicalBase);
+ CopyBufferVirtualAddress = PhysicalAddress | KSEG1_BASE;
+ HalDump("Common Buffer Virtual = %x\n",CopyBufferVirtualAddress);
+}
+#endif // _BBM_DMA_
+/* end M0004 */
diff --git a/private/ntos/nthals/halr96b/mips/jxmapio.c b/private/ntos/nthals/halr96b/mips/jxmapio.c
new file mode 100644
index 000000000..879f96410
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxmapio.c
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\jxmapio.c"
diff --git a/private/ntos/nthals/halr96b/mips/jxmaptb.c b/private/ntos/nthals/halr96b/mips/jxmaptb.c
new file mode 100644
index 000000000..9262bc775
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxmaptb.c
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\jxmaptb.c"
diff --git a/private/ntos/nthals/halr96b/mips/jxport.c b/private/ntos/nthals/halr96b/mips/jxport.c
new file mode 100644
index 000000000..26e310528
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxport.c
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\jxport.c"
diff --git a/private/ntos/nthals/halr96b/mips/jxreturn.c b/private/ntos/nthals/halr96b/mips/jxreturn.c
new file mode 100644
index 000000000..d77d5642b
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxreturn.c
@@ -0,0 +1,258 @@
+// #pragma comment(exestr, "@(#) jxreturn.c 1.1 95/09/28 15:40:17 nec")
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ jxreturn.c
+
+Abstract:
+
+ This module implements the HAL return to firmware function.
+
+Author:
+
+ David N. Cutler (davec) 21-Aug-1991
+
+Revision History:
+
+ H000 Tue Apr 25 16:02:05 1995 kbnes!kisimoto
+ -add Powerdown if argument value indicates
+ HalPowerDownRoutine
+ S001 kuriyama@oa2.kb.nec.co.jp Sun May 21 18:32:55 JST 1995
+ -compile error clear
+ S002 kuriyama@oa2.kb.nec.co.jp Sun May 21 20:19:48 JST 1995
+ - powoff bug? fixed
+ H003 Sat Aug 12 19:33:45 1995 kbnes!kisimoto
+ - Removed _J94C_ definitions.
+ _J94C_ definition indicates that the status of the
+ dump switch can acknowledge from Self-test register.
+
+ M004 kuriyama@oa2.kb.nec.co.jp Wed Aug 23 19:28:35 JST 1995
+ - add for x86bios emurator support
+--*/
+#include "halp.h"
+#define HEADER_FILE
+#include "kxmips.h"
+
+//
+// Define keyboard registers structure.
+//
+
+typedef struct _KBD_REGISTERS {
+ union {
+ UCHAR Output;
+ UCHAR Input;
+ } Data;
+
+ union {
+ UCHAR Status;
+ UCHAR Command;
+ } Control;
+} KBD_REGISTERS;
+
+#define KBD_IBF_MASK 2 // input buffer full mask
+
+#define KbdGetStatus() (READ_REGISTER_UCHAR(&KbdBase->Control.Status))
+#define KbdStoreCommand(Byte) WRITE_REGISTER_UCHAR(&KbdBase->Control.Command, Byte)
+#define KbdStoreData(Byte) WRITE_REGISTER_UCHAR(&KbdBase->Data.Input, Byte)
+#define KbdGetData() (READ_REGISTER_UCHAR(&KbdBase->Data.Output))
+
+VOID
+HalReturnToFirmware(
+ IN FIRMWARE_REENTRY Routine
+ )
+
+/*++
+
+Routine Description:
+
+ This function returns control to the specified firmware routine.
+ In most cases it generates a soft reset by asserting the reset line
+ trough the keyboard controller.
+ The Keyboard controller is mapped using the same virtual address
+ and the same fixed entry as the DMA.
+
+Arguments:
+
+ Routine - Supplies a value indicating which firmware routine to invoke.
+
+Return Value:
+
+ Does not return.
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+ ENTRYLO Pte[2];
+ ULONG Index; // A001
+ volatile KBD_REGISTERS * KbdBase = (KBD_REGISTERS *)DMA_VIRTUAL_BASE;
+ ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp; //S004
+
+ //
+ // Disable Interrupts.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ //
+ // Case on the type of return.
+ //
+
+ switch (Routine) {
+ case HalHaltRoutine:
+
+ //
+ // Hang looping.
+ //
+
+ for (;;) {
+ }
+
+ case HalPowerDownRoutine:
+
+#if defined (_MRCPOWER_)
+
+ //
+ // S004
+ // Reset ISA Display Adapter to 80x25 color text mode.
+ //
+
+ Eax = 0x12; // AH = 0 AL = 0x12
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+
+ //
+ // H000,S001
+ // Powerdown the machine
+ //
+
+ //
+ // Map the MRC
+ //
+
+ Pte[0].PFN = MRC_TEMP_PHYSICAL_BASE >> PAGE_SHIFT;
+
+ Pte[0].G = 1;
+ Pte[0].V = 1;
+ Pte[0].D = 1;
+
+ #if defined(R3000)
+
+ Pte[0].N = 1;
+
+ #endif
+
+ #if defined(R4000)
+
+ //
+ // set second page to global and not valid.
+ //
+
+ Pte[0].C = UNCACHED_POLICY;
+ Pte[1].G = 1;
+ Pte[1].V = 0;
+
+ #endif
+
+ //
+ // Map MRC using virtual address of DMA controller.
+ //
+
+ KeFillFixedEntryTb((PHARDWARE_PTE)&Pte[0],
+ (PVOID)DMA_VIRTUAL_BASE,
+ DMA_ENTRY);
+
+ //
+ // Send Powerdown Command to the MRC.
+ //
+
+
+ for (;;) { // S002
+ WRITE_REGISTER_UCHAR(
+ &MRC_CONTROL->SoftwarePowerOff,
+ 0x1
+ );
+ }
+
+ for (;;) {
+ }
+#endif //_MRCPOWER_
+
+ case HalRestartRoutine:
+ case HalRebootRoutine:
+ case HalInteractiveModeRoutine:
+
+ //
+ // S004
+ // Reset ISA Display Adapter to 80x25 color text mode.
+ //
+
+ Eax = 0x12; // AH = 0 AL = 0x12
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+
+ //
+ // Map the keyboard controller
+ //
+
+ Pte[0].PFN = KEYBOARD_PHYSICAL_BASE >> PAGE_SHIFT;
+ Pte[0].G = 1;
+ Pte[0].V = 1;
+ Pte[0].D = 1;
+
+ #if defined(R3000)
+
+ Pte[0].N = 1;
+
+ #endif
+
+ #if defined(R4000)
+
+ //
+ // set second page to global and not valid.
+ //
+
+ Pte[0].C = UNCACHED_POLICY;
+ Pte[1].G = 1;
+ Pte[1].V = 0;
+
+ #endif
+
+ //
+ // Map keyboard controller using virtual address of DMA controller.
+ //
+
+ KeFillFixedEntryTb((PHARDWARE_PTE)&Pte[0],
+ (PVOID)DMA_VIRTUAL_BASE,
+ DMA_ENTRY);
+
+ //
+ // Send WriteOutputBuffer Command to the controller.
+ //
+
+ while ((KbdGetStatus() & KBD_IBF_MASK) != 0) {
+ }
+
+ KbdStoreCommand(0xD1);
+
+ //
+ // Write a zero to the output buffer. Causes reset line to be asserted.
+ //
+
+ while ((KbdGetStatus() & KBD_IBF_MASK) != 0) {
+ }
+
+ KbdStoreData(0);
+ for (;;) {
+ }
+
+ default:
+ KdPrint(("HalReturnToFirmware invalid argument\n"));
+ KeLowerIrql(OldIrql);
+ DbgBreakPoint();
+ }
+}
+
+
diff --git a/private/ntos/nthals/halr96b/mips/jxsysint.c b/private/ntos/nthals/halr96b/mips/jxsysint.c
new file mode 100644
index 000000000..ebe54f024
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxsysint.c
@@ -0,0 +1,355 @@
+// #pragma comment(exestr, "@(#) jxsysint.c 1.1 95/09/28 15:40:45 nec")
+/*++
+
+Copyright (c) 1991-1993 Microsoft Corporation
+
+Module Name:
+
+ jxsysint.c
+
+Abstract:
+
+ This module implements the HAL enable/disable system interrupt, and
+ request interprocessor interrupt routines for a MIPS R3000 or R4000
+ Jazz system.
+
+Author:
+
+ David N. Cutler (davec) 6-May-1991
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+Modification History for NEC R94A (MIPS R4400):
+
+ H000 Thu Sep 8 10:32:42 JST 1994 kbnes!kishimoto
+ - HalDisableSystemInterrupt()
+ change Irql from EISA_DEVICE_LEVEL to EISA_PCI_DEVICE_LEVEL.
+ add the PCI interrupt vector.
+ Interrupt Enable register is zero origin on beta-version of
+ STORM chipset.
+ if ASIC3 register is zero, then chipset is beta-version.
+ - HalEnableSystemInterrupt()
+ change Irql from EISA_DEVICE_LEVEL to EISA_PCI_DEVICE_LEVEL.
+ add the PCI interrupt vector.
+ Interrupt Enable register is zero origin on beta-version of
+ STORM chipset.
+ if ASIC3 register is zero, then chipset is beta-version.
+ - HalGetInterruptVector()
+ add PCIBus interface.
+ change Irql from EISA_DEVICE_LEVEL to EISA_PCI_DEVICE_LEVEL.
+ If InterfaceType is Internal and ASIC3 register is zero,
+ then return the vector which was plus the offset of DEVICE_VECTORS.
+ H001 Mon Oct 17 14:21:21 JST 1994 kbnes!kishimoto
+ - Hal(p)EisaPCIXXX() rename to Hal(p)EisaXXX()
+ - XXX_EISA_PCI_XXX rename to XXX_EISA_XXX
+ - MAXIMUM_PCI_SLOT rename to R94A_PCI_SLOT
+ - HalGetInterruptVector()
+ returns PCI-vector plus offset PCI_VECTORS.
+ - modify original compile error
+ CMP001 ataka@oa2.kb.nec.co.jp Tue Oct 18 15:46:35 JST 1994
+ - reslve compile error
+ H002 Mon Oct 31 17:45:56 1994 kbnes!kishimoto
+ - HalGetInterruptVector()
+ Internal SCSI interrupt vector set to 5 (for BBM only)
+ M003 kuriyama@oa2.kb.nec.co.jp Fri Mar 31 17:06:37 JST 1995
+ - add _IPI_LIMIT_ support
+ S004 kuriyama@oa2.kb.nec.co.jp Sat Apr 01 11:10:52 JST 1995
+ - compile error clear
+ H005 Fri Aug 11 16:53:13 1995 kbnes!kishimoto
+ - delete M003, and HalGetInterruptVector(move to bushnd.c)
+
+--*/
+
+#include "halp.h"
+
+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.
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+
+ //
+ // Raise IRQL to the highest level and acquire device enable spinlock.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ KiAcquireSpinLock(&HalpSystemInterruptLock);
+
+ //
+ // If the vector number is within the range of builtin devices, then
+ // disable the builtin device interrupt.
+ //
+
+ if ((Vector >= (DEVICE_VECTORS + 1)) && (Vector <= MAXIMUM_BUILTIN_VECTOR)) {
+ HalpBuiltinInterruptEnable &= ~(1 << (Vector - DEVICE_VECTORS - 1));
+
+#if defined(_R94A_)
+
+ if ( READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ASIC3Revision.Long) == 0 ){
+
+ //
+ // The bit assign of TYPHOON(in STORM chipset)'s I/O Device Interrupt
+ // Enable register is zero origin.
+ //
+ // N.B. This obstruction is limiteded to beta-version of STORM chipset.
+ //
+
+ WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Fill,
+ HalpBuiltinInterruptEnable);
+ } else {
+
+ WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable,
+ HalpBuiltinInterruptEnable);
+ }
+
+#else
+
+ WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable,
+ HalpBuiltinInterruptEnable);
+
+#endif
+
+ }
+
+ //
+ // If the vector number is within the range of the EISA interrupts, then
+ // disable the EISA interrrupt.
+ //
+
+ if (Vector >= EISA_VECTORS &&
+ Vector < EISA_VECTORS + MAXIMUM_EISA_VECTOR &&
+ Irql == EISA_DEVICE_LEVEL) {
+ HalpDisableEisaInterrupt(Vector);
+ }
+
+#if defined(_R94A_)
+
+ //
+ // If the vector number is within the range of the PCI interrupts, then
+ // disable the PCI interrrupt.
+ //
+
+ if (Vector >= PCI_VECTORS &&
+ Vector <= PCI_VECTORS + R94A_PCI_SLOT &&
+ Irql == EISA_DEVICE_LEVEL) {
+ HalpDisablePCIInterrupt(Vector);
+ }
+
+#endif
+
+ //
+ // Release the device enable spin loc and lower IRQL to the previous level.
+ //
+
+ KiReleaseSpinLock(&HalpSystemInterruptLock);
+ 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
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+
+ //
+ // Raise IRQL to the highest level and acquire device enable spinlock.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ KiAcquireSpinLock(&HalpSystemInterruptLock);
+
+ //
+ // If the vector number is within the range of builtin devices, then
+ // enable the builtin device interrupt.
+ //
+
+ if ((Vector >= (DEVICE_VECTORS + 1)) && (Vector <= MAXIMUM_BUILTIN_VECTOR)) {
+ HalpBuiltinInterruptEnable |= (1 << (Vector - DEVICE_VECTORS - 1));
+
+#if defined(_R94A_)
+
+ if ( READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ASIC3Revision.Long) == 0 ){
+
+ //
+ // The bit assign of TYPHOON(in STORM chipset)'s I/O Device Interrupt
+ // Enable register is zero origin.
+ //
+ // N.B. This obstruction is limiteded to beta-version of STORM chipset.
+ //
+
+ WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Fill,
+ HalpBuiltinInterruptEnable);
+
+ } else {
+
+ WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable,
+ HalpBuiltinInterruptEnable);
+
+ }
+#else
+
+ WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable,
+ HalpBuiltinInterruptEnable);
+
+#endif
+
+ }
+
+ //
+ // If the vector number is within the range of the EISA interrupts, then
+ // enable the EISA interrrupt and set the Level/Edge register.
+ //
+
+ if (Vector >= EISA_VECTORS &&
+ Vector < EISA_VECTORS + MAXIMUM_EISA_VECTOR &&
+ Irql == EISA_DEVICE_LEVEL) {
+ HalpEnableEisaInterrupt( Vector, InterruptMode);
+ }
+
+#if defined(_R94A_)
+
+ //
+ // If the vector number is within the range of the PCI interrupts, then
+ // enable the PCI interrrupt.
+ //
+
+ if (Vector >= PCI_VECTORS &&
+ Vector <= PCI_VECTORS + R94A_PCI_SLOT &&
+ Irql == EISA_DEVICE_LEVEL) {
+ HalpEnablePCIInterrupt(Vector);
+ }
+
+#endif
+
+ //
+ // Release the device enable spin loc and lower IRQL to the previous level.
+ //
+
+ KiReleaseSpinLock(&HalpSystemInterruptLock);
+ KeLowerIrql(OldIrql);
+ return TRUE;
+}
+
+VOID
+HalRequestIpi (
+ IN ULONG Mask
+ )
+
+/*++
+
+Routine Description:
+
+ This routine requests an interprocessor interrupt on a set of processors.
+
+ N.B. This routine must ensure that the interrupt is posted at the target
+ processor(s) before returning.
+
+Arguments:
+
+ Mask - Supplies the set of processors that are sent an interprocessor
+ interrupt.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+#if defined(_DUO_) // S004
+
+// M003 +++
+#if defined(_IPI_LIMIT_)
+ ULONG OldIpiReq;
+ KIRQL OldIrql;
+
+ //
+ // Request an interprocessor interrupt on each of the specified target
+ // processors.
+ //
+ KeRaiseIrql(HIGH_LEVEL,&OldIrql);
+
+ KiAcquireSpinLock(&HalpIpiRequestLock);
+
+ OldIpiReq = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->IpInterruptRequest.Long);
+
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->IpInterruptRequest.Long,
+ OldIpiReq | Mask);
+
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->IpInterruptRequest.Long);
+
+ KiReleaseSpinLock(&HalpIpiRequestLock);
+
+ KeLowerIrql(OldIrql);
+
+
+#else // _IPI_LIMIT_
+ //
+ // Request an interprocessor interrupt on each of the specified target
+ // processors.
+ //
+
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->IpInterruptRequest.Long,
+ Mask);
+
+#endif //_IPI_LIMIT_
+// M003 ---
+
+#endif
+
+ return;
+}
diff --git a/private/ntos/nthals/halr96b/mips/jxtime.c b/private/ntos/nthals/halr96b/mips/jxtime.c
new file mode 100644
index 000000000..5d9c29705
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxtime.c
@@ -0,0 +1,377 @@
+// #pragma comment(exestr, "@(#) jxtime.c 1.1 95/09/28 15:41:57 nec")
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ jxtime.c
+
+Abstract:
+
+ This module implements the HAL set/query realtime clock routines for
+ a MIPS R3000 or R4000 Jazz system.
+
+Author:
+
+ David N. Cutler (davec) 5-May-1991
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ M0001 1994.9.9 kbnes!A.Kuriyama
+
+ Modify for R94A
+
+ HalpReadClockRegister() - R94A use RTC Index register except EISA NmiEnable
+ register.
+ HalpWriteClockRegister() - R94A use RTC Index register except EISA NmiEnable
+ register.
+
+ M0002 1994.10.8 kbnes!kuriyama(A)
+
+ HalpReadClockRegister()
+ -add specify Read Data register
+ HalpWritelockRegister()
+ -add specify Write Data register
+
+ M0003 1994.10.14 kbnes!kuriyama(A)
+
+ define error clear
+
+ M0004 1994.12.19 kbnes!kuriyama(A)
+
+ define miss fix
+--*/
+
+#include "halp.h"
+#include "jazzrtc.h"
+#include "eisa.h"
+
+
+//
+// Define forward referenced procedure prototypes.
+//
+
+UCHAR
+HalpReadClockRegister (
+ UCHAR Register
+ );
+
+VOID
+HalpWriteClockRegister (
+ UCHAR Register,
+ UCHAR Value
+ );
+
+BOOLEAN
+HalQueryRealTimeClock (
+ OUT PTIME_FIELDS TimeFields
+ )
+
+/*++
+
+Routine Description:
+
+ This routine queries the realtime clock.
+
+ N.B. This routine is required to provide any synchronization necessary
+ to query the realtime clock information.
+
+Arguments:
+
+ TimeFields - Supplies a pointer to a time structure that receives
+ the realtime clock information.
+
+Return Value:
+
+ If the power to the realtime clock has not failed, then the time
+ values are read from the realtime clock and a value of TRUE is
+ returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ UCHAR DataByte;
+ KIRQL OldIrql;
+
+ //
+ // If the realtime clock battery is still functioning, then read
+ // the realtime clock values, and return a function value of TRUE.
+ // Otherwise, return a function value of FALSE.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ DataByte = HalpReadClockRegister(RTC_CONTROL_REGISTERD);
+ if (((PRTC_CONTROL_REGISTER_D)(&DataByte))->ValidTime == 1) {
+
+ //
+ // Wait until the realtime clock is not being updated.
+ //
+
+ do {
+ DataByte = HalpReadClockRegister(RTC_CONTROL_REGISTERA);
+ } while (((PRTC_CONTROL_REGISTER_A)(&DataByte))->UpdateInProgress == 1);
+
+ //
+ // Read the realtime clock values.
+ //
+
+ TimeFields->Year = 1980 + (CSHORT)HalpReadClockRegister(RTC_YEAR);
+ TimeFields->Month = (CSHORT)HalpReadClockRegister(RTC_MONTH);
+ TimeFields->Day = (CSHORT)HalpReadClockRegister(RTC_DAY_OF_MONTH);
+ TimeFields->Weekday = (CSHORT)HalpReadClockRegister(RTC_DAY_OF_WEEK) - 1;
+ TimeFields->Hour = (CSHORT)HalpReadClockRegister(RTC_HOUR);
+ TimeFields->Minute = (CSHORT)HalpReadClockRegister(RTC_MINUTE);
+ TimeFields->Second = (CSHORT)HalpReadClockRegister(RTC_SECOND);
+ TimeFields->Milliseconds = 0;
+ KeLowerIrql(OldIrql);
+ return TRUE;
+
+ } else {
+ KeLowerIrql(OldIrql);
+ return FALSE;
+ }
+}
+
+BOOLEAN
+HalSetRealTimeClock (
+ IN PTIME_FIELDS TimeFields
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets the realtime clock.
+
+ N.B. This routine is required to provide any synchronization necessary
+ to set the realtime clock information.
+
+Arguments:
+
+ TimeFields - Supplies a pointer to a time structure that specifies the
+ realtime clock information.
+
+Return Value:
+
+ If the power to the realtime clock has not failed, then the time
+ values are written to the realtime clock and a value of TRUE is
+ returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ UCHAR DataByte;
+ KIRQL OldIrql;
+
+ //
+ // If the realtime clock battery is still functioning, then write
+ // the realtime clock values, and return a function value of TRUE.
+ // Otherwise, return a function value of FALSE.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ DataByte = HalpReadClockRegister(RTC_CONTROL_REGISTERD);
+ if (((PRTC_CONTROL_REGISTER_D)(&DataByte))->ValidTime == 1) {
+
+ //
+ // Set the realtime clock control to set the time.
+ //
+
+ DataByte = 0;
+ ((PRTC_CONTROL_REGISTER_B)(&DataByte))->HoursFormat = 1;
+ ((PRTC_CONTROL_REGISTER_B)(&DataByte))->DataMode = 1;
+ ((PRTC_CONTROL_REGISTER_B)(&DataByte))->SetTime = 1;
+ HalpWriteClockRegister(RTC_CONTROL_REGISTERB, DataByte);
+
+ //
+ // Write the realtime clock values.
+ //
+
+ HalpWriteClockRegister(RTC_YEAR, (UCHAR)(TimeFields->Year - 1980));
+ HalpWriteClockRegister(RTC_MONTH, (UCHAR)TimeFields->Month);
+ HalpWriteClockRegister(RTC_DAY_OF_MONTH, (UCHAR)TimeFields->Day);
+ HalpWriteClockRegister(RTC_DAY_OF_WEEK, (UCHAR)(TimeFields->Weekday + 1));
+ HalpWriteClockRegister(RTC_HOUR, (UCHAR)TimeFields->Hour);
+ HalpWriteClockRegister(RTC_MINUTE, (UCHAR)TimeFields->Minute);
+ HalpWriteClockRegister(RTC_SECOND, (UCHAR)TimeFields->Second);
+
+ //
+ // Set the realtime clock control to update the time.
+ //
+
+ ((PRTC_CONTROL_REGISTER_B)(&DataByte))->SetTime = 0;
+ HalpWriteClockRegister(RTC_CONTROL_REGISTERB, DataByte);
+ KeLowerIrql(OldIrql);
+ return TRUE;
+
+ } else {
+ KeLowerIrql(OldIrql);
+ return FALSE;
+ }
+}
+
+UCHAR
+HalpReadClockRegister (
+ UCHAR Register
+ )
+
+/*++
+
+Routine Description:
+
+ This routine reads the specified realtime clock register.
+
+Arguments:
+
+ Register - Supplies the number of the register whose value is read.
+
+Return Value:
+
+ The value of the register is returned as the function value.
+
+--*/
+
+{
+
+/* start M0001 */
+#if defined(_R94A_) /* M0003 */
+ // Insert the realtime clock register number, and write the value back
+ // to RTC Index register. This selects the realtime clock register
+ // that is read.
+ //
+
+ WRITE_REGISTER_UCHAR(&((PRTC_REGISTERS) HalpRealTimeClockBase)->Index,
+ Register);
+
+
+#else // _R94A_
+
+ //
+ // Insert the realtime clock register number, and write the value back
+ // to the EISA NMI enable register. This selects the realtime clock register
+ // that is read. Note this is a write only register and the EISA NMI
+ // is always enabled.
+ //
+
+ //
+ // TEMPTEMP Disable NMI's for now because this is causing machines in the
+ // build lab to get NMI's during boot.
+ //
+
+ Register |= 0x80;
+
+
+ WRITE_REGISTER_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable,
+ Register);
+
+#endif // _R94A_
+/* end M0001 */
+
+ //
+ // Read the realtime clock register value.
+ //
+
+/* start M0002 */
+#if defined(_R94A_) // M0004
+
+ return READ_REGISTER_UCHAR( &((PRTC_REGISTERS) HalpRealTimeClockBase)->Data);
+
+
+#else // _R94A_
+
+ return READ_REGISTER_UCHAR((PUCHAR)HalpRealTimeClockBase);
+
+#endif // _R94A_
+/* end M0002 */
+
+}
+
+VOID
+HalpWriteClockRegister (
+ UCHAR Register,
+ UCHAR Value
+ )
+
+/*++
+
+Routine Description:
+
+ This routine writes the specified value to the specified realtime
+ clock register.
+
+Arguments:
+
+ Register - Supplies the number of the register whose value is written.
+
+ Value - Supplies the value that is written to the specified register.
+
+Return Value:
+
+ The value of the register is returned as the function value.
+
+--*/
+
+{
+
+/* start M0001 */
+#if defined(_R94A_)
+ //
+ // Insert the realtime clock register number, and write the value back
+ // to RTC Index register. This selects the realtime clock
+ // register that is written.
+ //
+
+ WRITE_REGISTER_UCHAR(&((PRTC_REGISTERS) HalpRealTimeClockBase)->Index,
+ Register);
+
+#else // _R94A_
+
+ //
+ // Insert the realtime clock register number, and write the value back
+ // to the EISA NMI enable register. This selects the realtime clock
+ // register that is written. Note this is a write only register and
+ // the EISA NMI is always enabled.
+ //
+
+ Register |= 0x80;
+
+ WRITE_REGISTER_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable,
+ Register);
+
+#endif // _R94A_
+/* end M0001 */
+
+ //
+ // Write the realtime clock register value.
+ //
+
+/* start M0002 */
+#if defined(_R94A_) // M0004
+
+ WRITE_REGISTER_UCHAR( &((PRTC_REGISTERS) HalpRealTimeClockBase)->Data, Value);
+
+#else // _R94A_
+
+ WRITE_REGISTER_UCHAR((PUCHAR)HalpRealTimeClockBase, Value);
+
+#endif // _R94A_
+/* end M0002 */
+
+ return;
+}
+
+
+
+
+
+
+
+
+
diff --git a/private/ntos/nthals/halr96b/mips/jxusage.c b/private/ntos/nthals/halr96b/mips/jxusage.c
new file mode 100644
index 000000000..12a54de49
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/jxusage.c
@@ -0,0 +1,510 @@
+// #pragma comment(exestr, "@(#) jxusage.c 1.1 95/09/28 15:42:20 nec")
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ ixusage.c
+
+Abstract:
+
+Author:
+
+ Ken Reneris (kenr)
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ ADD001 ataka@oa2.kb.nec.co.jp Mon Oct 17 22:26:38 JST 1994
+ - Change PRIMARY_VECTOR_BASE to DEVICE_VECTOTRS
+ CHG001 ataka@oa2.kb.nec.co.jp Mon Oct 17 22:53:42 JST 1994
+ - delete HalpEnableInterruptHandler, HalpRegisterVector
+ - change IDT vector LOOP, R94A report up to DEVICE_VECTORS
+ - change MAXIMUM_IDTVECTOR to MAXIMUM_VECTOR
+ CMP001 ataka@oa2.kb.nec.co.jp Tue Oct 18 15:53:32 JST 1994
+ - resolve compile error
+ CMP002 ataka@oa2.kb.nec.co.jp Tue Oct 18 22:33:14 JST 1994
+ - add following
+ // HalpRegisterAddressUsage (&HalpDefaultPcIoSpace);
+ // HalpRegisterAddressUsage (&HalpEisaIoSpace);
+ // HalpRegisterAddressUsage (&HalpMapRegisterMemorySpace);
+
+--*/
+
+#include "halp.h"
+
+
+//
+// Array to remember hal's IDT usage
+//
+
+#if !defined(_R94A_) // CMP001
+extern ADDRESS_USAGE *HalpAddressUsageList;
+extern IDTUsage HalpIDTUsage[MAXIMUM_IDTVECTOR];
+#endif // _R94A
+
+KAFFINITY HalpActiveProcessors;
+
+VOID
+HalpGetResourceSortValue (
+ IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc,
+ OUT PULONG sortscale,
+ OUT PLARGE_INTEGER sortvalue
+ );
+
+// CMP001
+VOID
+HalpReportResourceUsage (
+ IN PUNICODE_STRING HalName,
+ IN INTERFACE_TYPE DeviceInterfaceToUse
+ );
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpGetResourceSortValue)
+#pragma alloc_text(INIT,HalpReportResourceUsage)
+#endif
+
+
+
+#if !defined (_R94A_) // CHG001
+VOID
+HalpEnableInterruptHandler (
+ IN UCHAR ReportFlags,
+ IN ULONG BusInterruptVector,
+ IN ULONG SystemInterruptVector,
+ IN KIRQL SystemIrql,
+ IN VOID (*HalInterruptServiceRoutine)(VOID),
+ IN KINTERRUPT_MODE InterruptMode
+ )
+/*++
+
+Routine Description:
+
+ This function connects & registers an IDT vectors usage by the HAL.
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ //
+ // Remember which vector the hal is connecting so it can be reported
+ // later on
+ //
+ HalpRegisterVector (ReportFlags, BusInterruptVector, SystemInterruptVector, SystemIrql);
+
+
+ //
+ // Connect the IDT and enable the vector now
+ //
+
+ KiSetHandlerAddressToIDT(SystemInterruptVector, HalInterruptServiceRoutine);
+ HalEnableSystemInterrupt(SystemInterruptVector, SystemIrql, InterruptMode);
+}
+
+
+
+VOID
+HalpRegisterVector (
+ IN UCHAR ReportFlags,
+ IN ULONG BusInterruptVector,
+ IN ULONG SystemInterruptVector,
+ IN KIRQL SystemIrql
+ )
+/*++
+
+Routine Description:
+
+ This registers an IDT vectors usage by the HAL.
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+#if DBG
+ // There are only 0ff IDT entries...
+ ASSERT (SystemInterruptVector <= MAXIMUM_IDTVECTOR &&
+ BusInterruptVector <= MAXIMUM_IDTVECTOR);
+#endif
+
+ //
+ // Remember which vector the hal is connecting so it can be reported
+ // later on
+ //
+
+ HalpIDTUsage[SystemInterruptVector].Flags = ReportFlags;
+ HalpIDTUsage[SystemInterruptVector].Irql = SystemIrql;
+ HalpIDTUsage[SystemInterruptVector].BusReleativeVector = (UCHAR) BusInterruptVector;
+}
+#endif // _R94A_
+
+
+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 = RtlConvertUlongToLargeInteger(
+ 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;
+
+ default:
+ *sortscale = 4;
+ *sortvalue = RtlConvertUlongToLargeInteger (0);
+ break;
+ }
+}
+
+
+VOID
+HalpReportResourceUsage (
+ IN PUNICODE_STRING HalName,
+ IN INTERFACE_TYPE DeviceInterfaceToUse
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ 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;
+ UCHAR pass, reporton;
+ INTERFACE_TYPE interfacetype;
+ ULONG CurrentIDT, CurrentElement;
+ ADDRESS_USAGE *CurrentAddress;
+ LARGE_INTEGER curvalue, sortvalue;
+
+
+#if defined(_R94A_)
+// HalpRegisterAddressUsage (&HalpDefaultPcIoSpace);
+// HalpRegisterAddressUsage (&HalpEisaIoSpace);
+// HalpRegisterAddressUsage (&HalpMapRegisterMemorySpace);
+#endif // _R94A_
+
+
+
+ //
+ // 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;
+
+ //
+ // Make sure all vectors 00-2f are reserved
+ // 00-1E reserved by Intel
+ // 1F reserved by Intel for APIC (apc priority level)
+ // 20-2e reserved by Microsoft
+ // 2f reserved by Microsoft for APIC (dpc priority level)
+ //
+
+#if defined(_R94A_) // CHG001
+ for(i=0; i < DEVICE_VECTORS; i++) { // ADD001
+ HalpIDTUsage[i].Flags = InternalUsage | InterruptLatched;
+ HalpIDTUsage[i].BusReleativeVector = (UCHAR) i;
+ }
+#else
+ for(i=0; i < PRIMARY_VECTOR_BASE; i++) {
+ if (!(HalpIDTUsage[i].Flags & IDTOwned)) {
+ HalpIDTUsage[i].Flags = InternalUsage;
+ HalpIDTUsage[i].BusReleativeVector = (UCHAR) i;
+ }
+ }
+#endif
+
+ for(pass=0; pass < 2; pass++) {
+ if (pass == 0) {
+ //
+ // First pass - build resource lists for resources reported
+ // reported against device usage.
+ //
+
+ reporton = DeviceUsage & ~IDTOwned;
+ interfacetype = DeviceInterfaceToUse;
+ } else {
+
+ //
+ // Second pass = build reousce lists for resources reported
+ // as internal usage.
+ //
+
+ reporton = InternalUsage & ~IDTOwned;
+ interfacetype = Internal;
+ }
+
+ CurrentIDT = 0;
+ CurrentElement = 0;
+ CurrentAddress = HalpAddressUsageList;
+
+ for (; ;) {
+ if (CurrentIDT <= MAXIMUM_VECTOR) { // CHG001
+ //
+ // Check to see if CurrentIDT needs to be reported
+ //
+
+ if (!(HalpIDTUsage[CurrentIDT].Flags & reporton)) {
+ // Don't report on this one
+ CurrentIDT++;
+ continue;
+ }
+
+ //
+ // Report CurrentIDT resource
+ //
+
+ RPartialDesc.Type = CmResourceTypeInterrupt;
+ RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
+ RPartialDesc.Flags =
+ HalpIDTUsage[CurrentIDT].Flags & InterruptLatched ?
+ CM_RESOURCE_INTERRUPT_LATCHED :
+ CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+ RPartialDesc.u.Interrupt.Vector = HalpIDTUsage[CurrentIDT].BusReleativeVector;
+ RPartialDesc.u.Interrupt.Level = HalpIDTUsage[CurrentIDT].BusReleativeVector;
+ RPartialDesc.u.Interrupt.Affinity = HalpActiveProcessors;
+
+ RtlCopyMemory (&TPartialDesc, &RPartialDesc, sizeof TPartialDesc);
+ TPartialDesc.u.Interrupt.Vector = CurrentIDT;
+ TPartialDesc.u.Interrupt.Level = HalpIDTUsage[CurrentIDT].Irql;
+
+ CurrentIDT++;
+
+ } else {
+ //
+ // Check to see if CurrentAddress needs to be reported
+ //
+
+ if (!CurrentAddress) {
+ break; // No addresses left
+ }
+
+ if (!(CurrentAddress->Flags & reporton)) {
+ // Don't report on this list
+ CurrentElement = 0;
+ CurrentAddress = CurrentAddress->Next;
+ continue;
+ }
+
+ if (!CurrentAddress->Element[CurrentElement].Length) {
+ // End of current list, go to next list
+ CurrentElement = 0;
+ CurrentAddress = CurrentAddress->Next;
+ continue;
+ }
+
+ //
+ // Report CurrentAddress
+ //
+
+ RPartialDesc.Type = (UCHAR) CurrentAddress->Type;
+ RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
+
+ if (RPartialDesc.Type == CmResourceTypePort) {
+ i = 1; // address space port
+ RPartialDesc.Flags = CM_RESOURCE_PORT_IO;
+ } else {
+ i = 0; // address space memory
+ RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+ }
+
+ // Notice: assuming u.Memory and u.Port have the same layout
+ RPartialDesc.u.Memory.Start.HighPart = 0;
+ RPartialDesc.u.Memory.Start.LowPart =
+ CurrentAddress->Element[CurrentElement].Start;
+
+ RPartialDesc.u.Memory.Length =
+ CurrentAddress->Element[CurrentElement].Length;
+
+ // translated address = Raw address
+ RtlCopyMemory (&TPartialDesc, &RPartialDesc, sizeof TPartialDesc);
+ HalTranslateBusAddress (
+ interfacetype, // device bus or internal
+ 0, // bus number
+ RPartialDesc.u.Memory.Start, // source address
+ &i, // address space
+ &TPartialDesc.u.Memory.Start ); // translated address
+
+ if (RPartialDesc.Type == CmResourceTypePort && i == 0) {
+ TPartialDesc.Flags = CM_RESOURCE_PORT_MEMORY;
+ }
+
+ CurrentElement++;
+ }
+
+ //
+ // Include the current resource in the HALs list
+ //
+
+ if (pRFullDesc->InterfaceType != interfacetype) {
+ //
+ // 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 = interfacetype;
+ pTFullDesc->InterfaceType = interfacetype;
+
+ pRPartList = &pRFullDesc->PartialResourceList;
+ pTPartList = &pTFullDesc->PartialResourceList;
+
+ //
+ // Bump current location pointers up
+ //
+ pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
+ pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
+ }
+
+
+ pRPartList->Count++;
+ pTPartList->Count++;
+ RtlCopyMemory (pRCurLoc, &RPartialDesc, sizeof RPartialDesc);
+ RtlCopyMemory (pTCurLoc, &TPartialDesc, sizeof TPartialDesc);
+
+ pRCurLoc++;
+ pTCurLoc++;
+ }
+ }
+
+ 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 &&
+ RtlLargeIntegerLessThan (sortvalue, curvalue)) ) {
+
+ //
+ // 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);
+}
diff --git a/private/ntos/nthals/halr96b/mips/mipsdat.c b/private/ntos/nthals/halr96b/mips/mipsdat.c
new file mode 100644
index 000000000..bfe2b9273
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/mipsdat.c
@@ -0,0 +1,145 @@
+// #pragma comment(exestr, "@(#) mipsdat.c 1.1 95/09/28 15:42:43 nec")
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ ixdat.c
+
+Abstract:
+
+ Declares various data which is initialize data, or pagable data.
+
+Author:
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+/*++
+
+Revision History:
+
+ ADD001 ataka@oa2.kb.nec.co.jp Mon Oct 17 20:53:16 JST 1994
+ - add HalpMapRegisterMemorySpace
+ BUG001 ataka@oa2.kb.nec.co.jp Mon Oct 17 21:49:18 JST 1994
+ - change HalpMapRegisterMemorySpace Size
+ CNG001 ataka@oa2.kb.nec.co.jp Mon Oct 17 21:58:30 JST 1994
+ - change HalpIDTUsage size to MAXIMUM_VECTOR
+ CMP001 ataka@oa2.kb.nec.co.jp Tue Oct 18 15:34:47 JST 1994
+ - resolve compile error
+ A002 ataka@oa2.kb.nec.co.jp 1995/6/17
+ - merge 1050
+
+--*/
+
+
+
+
+#include "halp.h"
+
+#ifdef ALLOC_DATA_PRAGMA
+#pragma data_seg("INIT")
+#endif
+
+//
+// The following data is only valid during system initialiation
+// and the memory will be re-claimed by the system afterwards
+//
+
+ADDRESS_USAGE HalpDefaultPcIoSpace = {
+ NULL, CmResourceTypePort, InternalUsage,
+ {
+ EISA_CONTROL_PHYSICAL_BASE+0x000, 0x10, // ISA DMA
+ EISA_CONTROL_PHYSICAL_BASE+0x0C0, 0x10, // ISA DMA
+ EISA_CONTROL_PHYSICAL_BASE+0x080, 0x10, // DMA
+
+ EISA_CONTROL_PHYSICAL_BASE+0x020, 0x2, // PIC
+ EISA_CONTROL_PHYSICAL_BASE+0x0A0, 0x2, // Cascaded PIC
+
+ EISA_CONTROL_PHYSICAL_BASE+0x040, 0x4, // Timer1, Referesh, Speaker, Control Word
+ EISA_CONTROL_PHYSICAL_BASE+0x048, 0x4, // Timer2, Failsafe
+
+ EISA_CONTROL_PHYSICAL_BASE+0x061, 0x1, // NMI (system control port B)
+ EISA_CONTROL_PHYSICAL_BASE+0x092, 0x1, // system control port A
+
+ EISA_CONTROL_PHYSICAL_BASE+0x070, 0x2, // Cmos/NMI enable
+ EISA_CONTROL_PHYSICAL_BASE+0x0F0, 0x10, // coprocessor ports
+ 0,0
+ }
+};
+
+ADDRESS_USAGE HalpEisaIoSpace = {
+ NULL, CmResourceTypePort, InternalUsage,
+ {
+ EISA_CONTROL_PHYSICAL_BASE+0x0D0, 0x10, // DMA
+ EISA_CONTROL_PHYSICAL_BASE+0x400, 0x10, // DMA
+ EISA_CONTROL_PHYSICAL_BASE+0x480, 0x10, // DMA
+ EISA_CONTROL_PHYSICAL_BASE+0x4C2, 0xE, // DMA
+ EISA_CONTROL_PHYSICAL_BASE+0x4D4, 0x2C, // DMA
+
+ EISA_CONTROL_PHYSICAL_BASE+0x461, 0x2, // Extended NMI
+ EISA_CONTROL_PHYSICAL_BASE+0x464, 0x2, // Last Eisa Bus Muster granted
+
+ EISA_CONTROL_PHYSICAL_BASE+0x4D0, 0x2, // edge/level control registers
+
+ EISA_CONTROL_PHYSICAL_BASE+0xC84, 0x1, // System board enable
+ 0, 0
+ }
+};
+
+#define R94A_MAPREGISTER_BASE 100 // CMP001
+
+// BUG001
+ADDRESS_USAGE HalpMapRegisterMemorySpace = {
+ NULL, CmResourceTypeMemory, InternalUsage,
+ {
+ R94A_MAPREGISTER_BASE, (USHORT)(DMA_TRANSLATION_LIMIT/(sizeof(TRANSLATION_ENTRY))*PAGE_SIZE), // for Map Register Area CMP001
+ 0, 0
+ }
+};
+
+
+//
+// From usage.c
+//
+
+ADDRESS_USAGE *HalpAddressUsageList;
+
+//
+// Misc hal stuff in the registry
+//
+
+WCHAR rgzHalClassName[] = L"Hardware Abstraction Layer";
+
+
+//
+// From ixpcibus.c
+//
+
+WCHAR rgzMultiFunctionAdapter[] = L"\\Registry\\Machine\\Hardware\\Description\\System\\MultifunctionAdapter";
+WCHAR rgzConfigurationData[] = L"Configuration Data";
+WCHAR rgzIdentifier[] = L"Identifier";
+WCHAR rgzPCIIndetifier[] = L"PCI";
+WCHAR rgzReservedResources[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\SystemResources\\ReservedResources"; // A002
+
+
+#ifdef ALLOC_DATA_PRAGMA
+#pragma data_seg()
+#endif
+
+//
+// IDT vector usage info
+//
+// CNG001
+#if defined(MIPS)
+IDTUsage HalpIDTUsage[MAXIMUM_VECTOR]; // Size of PCR->InterruptRoutine[]
+#else // CMP001
+IDTUsage HalpIDTUsage[MAXIMUM_IDTVECTOR];
+#endif
+
diff --git a/private/ntos/nthals/halr96b/mips/mode542x.h b/private/ntos/nthals/halr96b/mips/mode542x.h
new file mode 100644
index 000000000..3550a0714
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/mode542x.h
@@ -0,0 +1,1302 @@
+// #pragma comment(exestr, "@(#) mode542x.h 1.1 95/09/28 15:43:49 nec")
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ Mode542x.h
+
+Abstract:
+
+ This module contains all the global data used by the Cirrus Logic
+ CL-542x driver.
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+//
+// The next set of tables are for the CL542x
+// Note: all resolutions supported
+//
+
+//
+// 640x480 16-color mode (BIOS mode 12) set command string for CL 542x.
+//
+
+USHORT CL542x_640x480[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+ 0x0009, 0x000a, 0x000b, // no banking in 640x480 mode
+
+ EOD
+};
+
+//
+// 800x600 16-color (60Hz refresh) mode set command string for CL 542x.
+//
+
+USHORT CL542x_800x600[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+ 0x0009, 0x000a, 0x000b, // no banking in 800x600 mode
+
+ EOD
+};
+
+//
+// 1024x768 16-color (60Hz refresh) mode set command string for CL 542x.
+//
+
+USHORT CL542x_1024x768[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+#if ONE_64K_BANK
+ 0x0009, 0x000a, 0x000b,
+#endif
+#if TWO_32K_BANKS
+ 0x0009, 0x000a, 0x010b,
+#endif
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ EOD
+};
+
+//-----------------------------
+// standard VGA text modes here
+// 80x25 at 640x350
+//
+//-----------------------------
+
+//
+// 80x25 text mode set command string for CL 542x.
+// (720x400 pixel resolution; 9x16 character cell.)
+//
+
+USHORT CL542x_80x25Text[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+ 0x0009, 0x000a, 0x000b, // no banking in text mode
+
+ EOD
+};
+
+//
+// 80x25 text mode set command string for CL 542x.
+// (640x350 pixel resolution; 8x14 character cell.)
+//
+
+USHORT CL542x_80x25_14_Text[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+ 0x0009, 0x000a, 0x000b, // no banking in text mode
+
+ EOD
+};
+
+//
+// 1280x1024 16-color mode (BIOS mode 0x6C) set command string for CL 542x.
+//
+
+USHORT CL542x_1280x1024[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+#if ONE_64K_BANK
+ 0x0009, 0x000a, 0x000b,
+#endif
+#if TWO_32K_BANKS
+ 0x0009, 0x000a, 0x010b,
+#endif
+
+ EOD
+};
+
+//
+// 640x480 64k-color mode (BIOS mode 0x64) set command string for CL 542x.
+//
+
+USHORT CL542x_640x480_64k[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 4,
+ 0x0506, // Some BIOS's set Chain Odd maps bit
+#if ONE_64K_BANK
+ 0x0009, 0x000a, 0x000b,
+#endif
+#if TWO_32K_BANKS
+ 0x0009, 0x000a, 0x010b,
+#endif
+
+ EOD
+};
+
+#ifdef _X86_
+
+//
+// 640x480 256-color mode (BIOS mode 0x5F) set command string for CL 542x.
+//
+
+USHORT CL542x_640x480_256[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+#if ONE_64K_BANK
+ 0x0009, 0x000a, 0x000b,
+#endif
+#if TWO_32K_BANKS
+ 0x0009, 0x000a, 0x010b,
+#endif
+
+ EOD
+};
+
+//
+// 800x600 256-color mode (BIOS mode 0x5C) set command string for CL 542x.
+//
+
+USHORT CL542x_800x600_256[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+#if ONE_64K_BANK
+ 0x0009, 0x000a, 0x000b,
+#endif
+#if TWO_32K_BANKS
+ 0x0009, 0x000a, 0x010b,
+#endif
+
+ EOD
+};
+
+#else
+
+//
+// NOTE(DBCS) : Update 94/09/12 - NEC Corporation
+//
+// - Add mode set command string for NEC MIPS machine.
+//
+// - 640x480 256 color 72Hz
+// - 800x600 256 color 56 / 60Hz
+// - 1024x768 256 color 70 / 45Hz
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+//
+// For MIPS NEC machine only
+//
+
+//
+// 640x480 256-color 60Hz mode (BIOS mode 0x5F) set command string for
+// CL 542x.
+//
+
+USHORT CL542x_640x480_256_60[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 15, // count
+ 0x100, // start sync reset
+ 0x0101,0x0F02,0x0003,0x0E04, // program up sequencer
+
+//
+// the Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed Liner addressing.
+//
+
+ (LA_MASK << 12 | 0x0107),
+ 0x0008,
+ 0x4A0B,0x5B0C,0x450D,0x7E0E,
+ 0x2B1B,0x2F1C,0x301D,0x331E,
+
+ OB, // point sequencer index to ff
+ SEQ_ADDRESS_PORT,
+ 0x0F,
+
+ METAOUT+MASKOUT, // masked out.
+ SEQ_DATA_PORT,
+ 0xDF,0x20, // and mask, xor mask
+
+ OB, // misc. register
+ MISC_OUTPUT_REG_WRITE_PORT,
+ 0xE3,
+
+ OW, // text/graphics bit
+ GRAPH_ADDRESS_PORT,
+ 0x506,
+
+ OW, // end sync reset
+ SEQ_ADDRESS_PORT,
+ 0x300,
+
+ OW, // unprotect crtc 0-7
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x2011,
+
+ METAOUT+INDXOUT, // program crtc registers
+ CRTC_ADDRESS_PORT_COLOR,
+ 28,0, // count, startindex
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0x5D, 0x4F, 0x50, 0x82, 0x53, 0x9F,
+ 0x00, 0x3E, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xE1, 0x83,
+ 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3,
+ 0xFF, 0x00, 0x00, 0x22,
+
+#else
+
+ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80,
+ 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xea, 0x8c,
+ 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
+ 0xff, 0x00, 0x00, 0x22,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ METAOUT+INDXOUT, // program gdc registers
+ GRAPH_ADDRESS_PORT,
+ 9,0, // count, startindex
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0x0F, 0xFF,
+
+ IB, // prepare atc for writing
+ INPUT_STATUS_1_COLOR,
+
+ METAOUT+ATCOUT, // program atc registers
+ ATT_ADDRESS_PORT,
+ 21,0, // count, startindex
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00,
+ 0x0F, 0x00, 0x00,
+
+ OB, // turn video on.
+ ATT_ADDRESS_PORT,
+ 0x20,
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed it for Liner addressing.
+//
+
+ 0x0009, 0x000a, 0x000b,
+
+ EOD
+};
+
+//
+// 640x480 256-color 72Hz mode (BIOS mode 0x5F) set command string for
+// CL 542x.
+//
+
+USHORT CL542x_640x480_256_72[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 15, // count
+ 0x100, // start sync reset
+ 0x0101,0x0F02,0x0003,0x0E04, // program up sequencer
+
+//
+// the Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed Liner addressing.
+//
+
+ (LA_MASK << 12 | 0x0107),
+ 0x0008,
+ 0x4A0B,0x5B0C,0x450D,0x420E,
+ 0x2B1B,0x2F1C,0x301D,0x1F1E,
+
+ OB, // point sequencer index to ff
+ SEQ_ADDRESS_PORT,
+ 0x0F,
+
+ METAOUT+MASKOUT, // masked out.
+ SEQ_DATA_PORT,
+ 0xDF,0x20, // and mask, xor mask
+
+ OB, // misc. register
+ MISC_OUTPUT_REG_WRITE_PORT,
+ 0xEF,
+
+ OW, // text/graphics bit
+ GRAPH_ADDRESS_PORT,
+ 0x506,
+
+ OW, // end sync reset
+ SEQ_ADDRESS_PORT,
+ 0x300,
+
+ OW, // unprotect crtc 0-7
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x2011,
+
+ METAOUT+INDXOUT, // program crtc registers
+ CRTC_ADDRESS_PORT_COLOR,
+ 28,0, // count, startindex
+
+//
+// NOTE(DBCS) : Update 95/06/30 - NEC Corporation (same as cirrus\mode542x.h)
+//
+// - Set Mode Type is VESA compatible. (Old Miss match)
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0x61, 0x4F, 0x50, 0x82, 0x54, 0x99,
+ 0xF6, 0x1F, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03,
+ 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3,
+ 0xFF, 0x00, 0x00, 0x22,
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+
+// 0x63, 0x4F, 0x50, 0x82, 0x55, 0x9A, thase parameter not match
+// 0x06, 0x3E, 0x00, 0x40, 0x00, 0x00, VESA Mode.
+// 0x00, 0x00, 0x00, 0x00, 0xE8, 0x8B,
+// 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3,
+// 0xFF, 0x00, 0x00, 0x22,
+
+#else
+
+ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80,
+ 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xea, 0x8c,
+ 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
+ 0xff, 0x00, 0x00, 0x22,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ METAOUT+INDXOUT, // program gdc registers
+ GRAPH_ADDRESS_PORT,
+ 9,0, // count, startindex
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0x0F, 0xFF,
+
+ IB, // prepare atc for writing
+ INPUT_STATUS_1_COLOR,
+
+ METAOUT+ATCOUT, // program atc registers
+ ATT_ADDRESS_PORT,
+ 21,0, // count, startindex
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00,
+ 0x0F, 0x00, 0x00,
+
+ OB, // turn video on.
+ ATT_ADDRESS_PORT,
+ 0x20,
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed it for Liner addressing.
+//
+
+ 0x0009, 0x000a, 0x000b,
+
+ EOD
+};
+
+//
+// 800x600 256-color 56Hz mode (BIOS mode 0x5C) set command string for
+// CL 542x.
+//
+
+USHORT CL542x_800x600_256_56[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 15, // count
+ 0x100, // start sync reset
+ 0x0101,0x0F02,0x0003,0x0E04, // program up sequencer
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed Liner addressing.
+//
+
+ (LA_MASK << 12 | 0x0107),
+ 0x0008,
+ 0x4A0B,0x5B0C,0x450D,0x7E0E,
+ 0x2B1B,0x2F1C,0x301D,0x331E,
+
+ OB, // point sequencer index to ff
+ SEQ_ADDRESS_PORT,
+ 0x0F,
+
+ METAOUT+MASKOUT, // masked out.
+ SEQ_DATA_PORT,
+ 0xDF,0x20, // and mask, xor mask
+
+ OB, // misc. register
+ MISC_OUTPUT_REG_WRITE_PORT,
+ 0xEF,
+
+ OW, // text/graphics bit
+ GRAPH_ADDRESS_PORT,
+ 0x506,
+
+ OW, // end sync reset
+ SEQ_ADDRESS_PORT,
+ 0x300,
+
+ OW, // unprotect crtc 0-7
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x2011,
+
+ METAOUT+INDXOUT, // program crtc registers
+ CRTC_ADDRESS_PORT_COLOR,
+ 28,0, // count, startindex
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0x7B, 0x63, 0x64, 0x80, 0x69, 0x12,
+ 0x6F, 0xF0, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x58, 0x8A,
+ 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
+ 0xFF, 0x00, 0x00, 0x22,
+
+#else
+
+ 0x7D, 0x63, 0x64, 0x80, 0x6D, 0x1C,
+ 0x98, 0xF0, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7B, 0x80,
+ 0x57, 0x64, 0x00, 0x5F, 0x91, 0xe3,
+ 0xff, 0x00, 0x00, 0x22,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ METAOUT+INDXOUT, // program gdc registers
+ GRAPH_ADDRESS_PORT,
+ 9,0, // count, startindex
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0x0F, 0xFF,
+
+ IB, // prepare atc for writing
+ INPUT_STATUS_1_COLOR,
+
+ METAOUT+ATCOUT, // program atc registers
+ ATT_ADDRESS_PORT,
+ 21,0, // count, startindex
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00,
+ 0x0F, 0x00, 0x00,
+
+ OB, // turn video on.
+ ATT_ADDRESS_PORT,
+ 0x20,
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed it for Liner addressing.
+//
+
+ 0x0009, 0x000a, 0x000b,
+
+ EOD
+};
+
+//
+// 800x600 256-color 60Hz mode (BIOS mode 0x5C) set command string for
+// CL 542x.
+//
+
+USHORT CL542x_800x600_256_60[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 15, // count
+ 0x100, // start sync reset
+ 0x0101,0x0F02,0x0003,0x0E04, // program up sequencer
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed Liner addressing.
+//
+
+ (LA_MASK << 12 | 0x0107),
+ 0x0008,
+ 0x4A0B,0x5B0C,0x450D,0x510E,
+ 0x2B1B,0x2F1C,0x301D,0x3A1E,
+
+ OB, // point sequencer index to ff
+ SEQ_ADDRESS_PORT,
+ 0x0F,
+
+ METAOUT+MASKOUT, // masked out.
+ SEQ_DATA_PORT,
+ 0xDF,0x20, // and mask, xor mask
+
+ OB, // misc. register
+ MISC_OUTPUT_REG_WRITE_PORT,
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0xEF,
+
+#else
+
+ 0x2F,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ OW, // text/graphics bit
+ GRAPH_ADDRESS_PORT,
+ 0x506,
+
+ OW, // end sync reset
+ SEQ_ADDRESS_PORT,
+ 0x300,
+
+ OW, // unprotect crtc 0-7
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x2011,
+
+ METAOUT+INDXOUT, // program crtc registers
+ CRTC_ADDRESS_PORT_COLOR,
+ 28,0, // count, startindex
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B,
+ 0x72, 0xF0, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x58, 0x8C,
+ 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
+ 0xFF, 0x00, 0x00, 0x22,
+
+#else
+
+ 0x7D, 0x63, 0x64, 0x80, 0x6D, 0x1C,
+ 0x98, 0xF0, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7B, 0x80,
+ 0x57, 0x64, 0x00, 0x5F, 0x91, 0xe3,
+ 0xff, 0x00, 0x00, 0x22,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ METAOUT+INDXOUT, // program gdc registers
+ GRAPH_ADDRESS_PORT,
+ 9,0, // count, startindex
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0x0F, 0xFF,
+
+ IB, // prepare atc for writing
+ INPUT_STATUS_1_COLOR,
+
+ METAOUT+ATCOUT, // program atc registers
+ ATT_ADDRESS_PORT,
+ 21,0, // count, startindex
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00,
+ 0x0F, 0x00, 0x00,
+
+ OB, // turn video on.
+ ATT_ADDRESS_PORT,
+ 0x20,
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed it for Liner addressing.
+//
+
+ 0x0009, 0x000a, 0x000b,
+
+ EOD
+};
+
+//
+// 800x600 256-color 72Hz mode (BIOS mode 0x5C) set command string for
+// CL 542x.
+//
+
+USHORT CL542x_800x600_256_72[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 15, // count
+ 0x100, // start sync reset
+ 0x0101,0x0F02,0x0003,0x0E04, // program up sequencer
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed Liner addressing.
+//
+
+ (LA_MASK << 12 | 0x0107),
+ 0x0008,
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0x4A0B,0x5B0C,0x450D,0x650E,
+
+#else
+
+ 0x4A0B,0x5B0C,0x450D,0x640E,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ 0x2B1B,0x2F1C,0x301D,0x3A1E,
+
+ OB, // point sequencer index to ff
+ SEQ_ADDRESS_PORT,
+ 0x0F,
+
+ METAOUT+MASKOUT, // masked out.
+ SEQ_DATA_PORT,
+ 0xDF,0x20, // and mask, xor mask
+
+ OB, // misc. register
+ MISC_OUTPUT_REG_WRITE_PORT,
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0xEF,
+
+#else
+
+ 0x2F,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ OW, // text/graphics bit
+ GRAPH_ADDRESS_PORT,
+ 0x506,
+
+ OW, // end sync reset
+ SEQ_ADDRESS_PORT,
+ 0x300,
+
+ OW, // unprotect crtc 0-7
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x2011,
+
+ METAOUT+INDXOUT, // program crtc registers
+ CRTC_ADDRESS_PORT_COLOR,
+ 28,0, // count, startindex
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0x7D, 0x63, 0x64, 0x80, 0x6D, 0x1C,
+ 0x96, 0xF0, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7B, 0x81,
+ 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
+ 0xFF, 0x00, 0x00, 0x22,
+
+#else
+
+ 0x7D, 0x63, 0x64, 0x80, 0x6D, 0x1C,
+ 0x98, 0xF0, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7B, 0x80,
+ 0x57, 0x64, 0x00, 0x5F, 0x91, 0xe3,
+ 0xff, 0x00, 0x00, 0x22,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ METAOUT+INDXOUT, // program gdc registers
+ GRAPH_ADDRESS_PORT,
+ 9,0, // count, startindex
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0x0F, 0xFF,
+
+ IB, // prepare atc for writing
+ INPUT_STATUS_1_COLOR,
+
+ METAOUT+ATCOUT, // program atc registers
+ ATT_ADDRESS_PORT,
+ 21,0, // count, startindex
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00,
+ 0x0F, 0x00, 0x00,
+
+ OB, // turn video on.
+ ATT_ADDRESS_PORT,
+ 0x20,
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed it for Liner addressing.
+//
+
+ 0x0009, 0x000a, 0x000b,
+
+ EOD
+};
+
+//
+// 1024x768 256-color 60Hz mode (BIOS mode 0x60) set command string for
+// CL 542x.
+//
+
+USHORT CL542x_1024x768_256_60[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 15, // count
+ 0x100, // start sync reset
+ 0x0101,0x0F02,0x0003,0x0E04, // program up sequencer
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed Liner addressing.
+//
+
+ (LA_MASK << 12 | 0x0107),
+ 0x0008,
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0x4A0B, 0x5B0C, 0x450D, 0x760E,
+ 0x2B1B, 0x2F1C, 0x301D, 0x341E,
+
+#else
+
+ 0x4A0B, 0x5B0C, 0x450D, 0x3B0E,
+ 0x2B1B, 0x2F1C, 0x301D, 0x1A1E,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ OB, // point sequencer index to ff
+ SEQ_ADDRESS_PORT,
+ 0x0F,
+
+ METAOUT+MASKOUT, // masked out.
+ SEQ_DATA_PORT,
+ 0xDF,0x20, // and mask, xor mask
+
+ OB, // misc. register
+ MISC_OUTPUT_REG_WRITE_PORT,
+ 0xEF,
+
+ OW, // text/graphics bit
+ GRAPH_ADDRESS_PORT,
+ 0x506,
+
+ OW, // end sync reset
+ SEQ_ADDRESS_PORT,
+ 0x300,
+
+ OW, // unprotect crtc 0-7
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x2011,
+
+ METAOUT+INDXOUT, // program crtc registers
+ CRTC_ADDRESS_PORT_COLOR,
+ 28,0, // count, startindex
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96,
+ 0x24, 0xFD, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x88,
+ 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x22,
+
+#else
+
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96,
+ 0x24, 0xFD, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x88,
+ 0xFF, 0x80, 0x00, 0x00, 0x24, 0xe3,
+ 0xff, 0x4A, 0x00, 0x22,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ METAOUT+INDXOUT, // program gdc registers
+ GRAPH_ADDRESS_PORT,
+ 9,0, // count, startindex
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0x0F, 0xFF,
+
+ IB, // prepare atc for writing
+ INPUT_STATUS_1_COLOR,
+
+ METAOUT+ATCOUT, // program atc registers
+ ATT_ADDRESS_PORT,
+ 21,0, // count, startindex
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00,
+ 0x0F, 0x00, 0x00,
+
+ OB, // turn video on.
+ ATT_ADDRESS_PORT,
+ 0x20,
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed it for Liner addressing.
+//
+
+ 0x0009, 0x000a, 0x000b,
+
+ EOD
+};
+
+//
+// 1024x768 256-color 70Hz mode (BIOS mode 0x60) set command string for
+// CL 542x.
+//
+
+USHORT CL542x_1024x768_256_70[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 15, // count
+ 0x100, // start sync reset
+ 0x0101,0x0F02,0x0003,0x0E04, // program up sequencer
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed Liner addressing.
+//
+
+ (LA_MASK << 12 | 0x0107),
+ 0x0008,
+ 0x4A0B, 0x5B0C, 0x450D, 0x6E0E,
+ 0x2B1B, 0x2F1C, 0x301D, 0x2A1E,
+
+ OB, // point sequencer index to ff
+ SEQ_ADDRESS_PORT,
+ 0x0F,
+
+ METAOUT+MASKOUT, // masked out.
+ SEQ_DATA_PORT,
+ 0xDF,0x20, // and mask, xor mask
+
+ OB, // misc. register
+ MISC_OUTPUT_REG_WRITE_PORT,
+ 0xEF,
+
+ OW, // text/graphics bit
+ GRAPH_ADDRESS_PORT,
+ 0x506,
+
+ OW, // end sync reset
+ SEQ_ADDRESS_PORT,
+ 0x300,
+
+ OW, // unprotect crtc 0-7
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x2011,
+
+ METAOUT+INDXOUT, // program crtc registers
+ CRTC_ADDRESS_PORT_COLOR,
+ 28,0, // count, startindex
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0xA1, 0x7F, 0x80, 0x86, 0x85, 0x96,
+ 0x24, 0xFD, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x88,
+ 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x22,
+
+#else
+
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96,
+ 0x24, 0xFD, 0x00, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x88,
+ 0xFF, 0x80, 0x00, 0x00, 0x24, 0xe3,
+ 0xff, 0x4A, 0x00, 0x22,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ METAOUT+INDXOUT, // program gdc registers
+ GRAPH_ADDRESS_PORT,
+ 9,0, // count, startindex
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0x0F, 0xFF,
+
+ IB, // prepare atc for writing
+ INPUT_STATUS_1_COLOR,
+
+ METAOUT+ATCOUT, // program atc registers
+ ATT_ADDRESS_PORT,
+ 21,0, // count, startindex
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00,
+ 0x0F, 0x00, 0x00,
+
+ OB, // turn video on.
+ ATT_ADDRESS_PORT,
+ 0x20,
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed it for Liner addressing.
+//
+
+ 0x0009, 0x000a, 0x000b,
+
+ EOD
+};
+
+//
+// 1024x768 256-color 87Hz mode (BIOS mode 0x60) set command string for
+// CL 542x. (Interlaced)
+//
+
+USHORT CL542x_1024x768_256_87[] = {
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 2, // count
+ 0x1206, // enable extensions
+ 0x0012,
+
+ OWM, // begin setmode
+ SEQ_ADDRESS_PORT,
+ 15, // count
+ 0x100, // start sync reset
+ 0x0101,0x0F02,0x0003,0x0E04, // program up sequencer
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed Liner addressing.
+//
+
+ (LA_MASK << 12 | 0x0107),
+ 0x0008,
+ 0x4A0B, 0x5B0C, 0x450D, 0x550E,
+ 0x2B1B, 0x2F1C, 0x301D, 0x361E,
+
+ OB, // point sequencer index to ff
+ SEQ_ADDRESS_PORT,
+ 0x0F,
+
+ METAOUT+MASKOUT, // masked out.
+ SEQ_DATA_PORT,
+ 0xDF,0x20, // and mask, xor mask
+
+ OB, // misc. register
+ MISC_OUTPUT_REG_WRITE_PORT,
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0xEF,
+
+#else
+
+ 0x2F,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ OW, // text/graphics bit
+ GRAPH_ADDRESS_PORT,
+ 0x506,
+
+ OW, // end sync reset
+ SEQ_ADDRESS_PORT,
+ 0x300,
+
+ OW, // unprotect crtc 0-7
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x2011,
+
+ METAOUT+INDXOUT, // program crtc registers
+ CRTC_ADDRESS_PORT_COLOR,
+ 28,0, // count, startindex
+
+//
+// NOTE(DBCS) : Update 94/10/26 - NEC Corporation
+//
+// - Set Mode Type is VESA compatible.
+//
+
+#if defined(DBCS) && defined(_MIPS_)
+
+ 0x99, 0x7F, 0x80, 0x86, 0x83, 0x99,
+ 0x96, 0x1F, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x83,
+ 0x7F, 0x80, 0x00, 0x7F, 0x12, 0xE3,
+ 0xff, 0x4A, 0x01, 0x22,
+
+#else
+
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96,
+ 0xBE, 0x1F, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x81, 0x84,
+ 0x7F, 0x80, 0x00, 0x80, 0x12, 0xE3,
+ 0xff, 0x4A, 0x01, 0x22,
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ METAOUT+INDXOUT, // program gdc registers
+ GRAPH_ADDRESS_PORT,
+ 9,0, // count, startindex
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0x0F, 0xFF,
+
+ IB, // prepare atc for writing
+ INPUT_STATUS_1_COLOR,
+
+ METAOUT+ATCOUT, // program atc registers
+ ATT_ADDRESS_PORT,
+ 21,0, // count, startindex
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00,
+ 0x0F, 0x00, 0x00,
+
+ OB, // turn video on.
+ ATT_ADDRESS_PORT,
+ 0x20,
+
+ OB,
+ DAC_PIXEL_MASK_PORT,
+ 0xFF,
+
+ OWM,
+ GRAPH_ADDRESS_PORT,
+ 3,
+
+//
+// The Miniport Driver for R96 machine is Liner addressing mode.
+// This set command was changed it for Liner addressing.
+//
+
+ 0x0009, 0x000a, 0x000b,
+
+ EOD
+};
+
+#endif // defined(DBCS) && defined(_MIPS_)
+
+#endif
diff --git a/private/ntos/nthals/halr96b/mips/modeset.h b/private/ntos/nthals/halr96b/mips/modeset.h
new file mode 100644
index 000000000..63122b13b
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/modeset.h
@@ -0,0 +1,85 @@
+// #pragma comment(exestr, "@(#) modeset.h 1.1 95/09/28 15:45:03 nec")
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ Modeset.h
+
+Abstract:
+
+ This module contains all the global data used by the Cirrus Logic
+ CL-6410 and CL-6420 driver.
+
+Environment:
+
+ Kernel mode
+
+Notes:
+
+ This module based on Cirrus Minport Driver. And modify for R96 MIPS
+ R4400 HAL Cirrus display initialize.
+
+Revision History:
+
+--*/
+
+/*
+ * M001 1993.19.28 A. Kuriyama @ oa2
+ *
+ * - Modify for R96 MIPS R4400 HAL
+ *
+ * Delete : Mode structure.
+ *
+ * Revision History in Cirrus Miniport Driver as follows:
+ *
+ * L001 1993.10.15 Kuroki
+ *
+ * - Modify for R96 MIPS R4400
+ *
+ * Delete : Micro channel Bus Initialize.
+ * VDM & Text, Fullscreen mode support.
+ * Banking routine.
+ * CL64xx Chip support.
+ * 16-color mode.
+ *
+ * Add : Liner Addressing.
+ *
+ *
+ *
+ */
+
+#include "cmdcnst.h"
+
+//---------------------------------------------------------------------------
+//
+// The actual register values for the supported modes are in chipset-specific
+// include files:
+//
+// mode64xx.h has values for CL6410 and CL6420
+// mode542x.h has values for CL5422, CL5424, and CL5426
+//
+
+
+USHORT HalpCirrus_MODESET_1K_WIDE[] = {
+ OW, // stretch scans to 1k
+ CRTC_ADDRESS_PORT_COLOR,
+ 0x8013,
+
+ EOD
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/private/ntos/nthals/halr96b/mips/pcibrd.c b/private/ntos/nthals/halr96b/mips/pcibrd.c
new file mode 100644
index 000000000..2124dda34
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/pcibrd.c
@@ -0,0 +1,1020 @@
+// #pragma comment(exestr, "@(#) pcibrd.c 1.1 95/09/28 15:45:30 nec")
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ ixpcibrd.c
+
+Abstract:
+
+ Get PCI-PCI bridge information
+
+Author:
+
+ Ken Reneris (kenr) 14-June-1994
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+#include "stdio.h"
+
+// debugging only...
+// #define INIT_PCI_BRIDGE 1
+
+extern WCHAR rgzMultiFunctionAdapter[];
+extern WCHAR rgzConfigurationData[];
+extern WCHAR rgzIdentifier[];
+extern WCHAR rgzReservedResources[];
+
+
+#if DBG
+#define DBGMSG(a) DbgPrint(a)
+#else
+#define DBGMSG(a)
+#endif
+
+
+
+#define IsPciBridge(a) \
+ (a->VendorID != PCI_INVALID_VENDORID && \
+ PCI_CONFIG_TYPE(a) == PCI_BRIDGE_TYPE && \
+ a->SubClass == 4 && a->BaseClass == 6)
+
+
+typedef struct {
+ ULONG BusNo;
+ PBUS_HANDLER BusHandler;
+ PPCIPBUSDATA BusData;
+ PCI_SLOT_NUMBER SlotNumber;
+ PPCI_COMMON_CONFIG PciData;
+ ULONG IO, Memory, PFMemory;
+ UCHAR Buffer[PCI_COMMON_HDR_LENGTH];
+} CONFIGBRIDGE, *PCONFIGBRIDGE;
+
+//
+// Internal prototypes
+//
+
+
+#ifdef INIT_PCI_BRIDGE
+VOID
+HalpGetPciBridgeNeeds (
+ IN ULONG HwType,
+ IN PUCHAR MaxPciBus,
+ IN PCONFIGBRIDGE Current
+ );
+#endif
+
+VOID
+HalpSetPciBridgedVgaCronk (
+ IN ULONG BusNumber,
+ IN ULONG Base,
+ IN ULONG Limit
+ );
+
+
+ULONG
+HalpGetBridgedPCIInterrupt (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ );
+
+ULONG
+HalpGetBridgedPCIISAInt (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ );
+
+VOID
+HalpPCIBridgedPin2Line (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciData
+ );
+
+
+VOID
+HalpPCIBridgedLine2Pin (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciNewData,
+ IN PPCI_COMMON_CONFIG PciOldData
+ );
+
+NTSTATUS
+HalpGetBridgedPCIIrqTable (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER PciSlot,
+ OUT PUCHAR IrqTable
+ );
+
+
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpGetPciBridgeConfig)
+#pragma alloc_text(INIT,HalpSetPciBridgedVgaCronk)
+#pragma alloc_text(INIT,HalpFixupPciSupportedRanges)
+
+#ifdef INIT_PCI_BRIDGE
+#pragma alloc_text(PAGE,HalpGetBridgedPCIInterrupt)
+//#pragma alloc_text(PAGE,HalpGetBridgedPCIIrqTable)
+#pragma alloc_text(INIT,HalpGetPciBridgeNeeds)
+#endif
+#endif
+
+
+BOOLEAN
+HalpGetPciBridgeConfig (
+ IN ULONG HwType,
+ IN PUCHAR MaxPciBus
+ )
+/*++
+
+Routine Description:
+
+ Scan the devices on all known pci buses trying to locate any
+ pci to pci bridges. Record the hierarchy for the buses, and
+ which buses have what addressing limits.
+
+Arguments:
+
+ HwType - Configuration type.
+ MaxPciBus - # of PCI buses reported by the bios
+
+--*/
+{
+ PBUS_HANDLER ChildBus;
+ PPCIPBUSDATA ChildBusData;
+ ULONG d, f, i, j, BusNo;
+ UCHAR Rescan;
+ BOOLEAN FoundDisabledBridge;
+ CONFIGBRIDGE CB;
+
+ Rescan = 0;
+ FoundDisabledBridge = FALSE;
+
+ //
+ // Find each bus on a bridge and initialize it's base and limit information
+ //
+
+ CB.PciData = (PPCI_COMMON_CONFIG) CB.Buffer;
+ CB.SlotNumber.u.bits.Reserved = 0;
+ for (BusNo=0; BusNo < *MaxPciBus; BusNo++) {
+
+ CB.BusHandler = HalpHandlerForBus (PCIBus, BusNo);
+ CB.BusData = (PPCIPBUSDATA) CB.BusHandler->BusData;
+
+ for (d = 0; d < PCI_MAX_DEVICES; d++) {
+ CB.SlotNumber.u.bits.DeviceNumber = d;
+
+ for (f = 0; f < PCI_MAX_FUNCTION; f++) {
+ CB.SlotNumber.u.bits.FunctionNumber = f;
+
+ //
+ // Read PCI configuration information
+ //
+
+ HalpReadPCIConfig (
+ CB.BusHandler,
+ CB.SlotNumber,
+ CB.PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+ if (CB.PciData->VendorID == PCI_INVALID_VENDORID) {
+ // next device
+ break;
+ }
+
+ if (!IsPciBridge (CB.PciData)) {
+ // not a PCI-PCI bridge, next function
+ continue;
+ }
+
+ if (!(CB.PciData->Command & PCI_ENABLE_BUS_MASTER)) {
+ // this PCI bridge is not enabled - skip it for now
+ FoundDisabledBridge = TRUE;
+ continue;
+ }
+
+ if ((ULONG) CB.PciData->u.type1.PrimaryBus !=
+ CB.BusHandler->BusNumber) {
+
+ DBGMSG ("HAL GetPciData: bad primarybus!!!\n");
+ // what to do?
+ }
+
+ //
+ // Found a PCI-PCI bridge. Determine it's parent child
+ // releationships
+ //
+
+ ChildBus = HalpHandlerForBus (PCIBus, CB.PciData->u.type1.SecondaryBus);
+ if (!ChildBus) {
+ DBGMSG ("HAL GetPciData: found configured pci bridge\n");
+
+ // up the number of buses
+ if (CB.PciData->u.type1.SecondaryBus > Rescan) {
+ Rescan = CB.PciData->u.type1.SecondaryBus;
+ }
+ continue;
+ }
+
+ ChildBusData = (PPCIPBUSDATA) ChildBus->BusData;
+ if (ChildBusData->BridgeConfigRead) {
+ // this child buses releationships already processed
+ continue;
+ }
+
+ //
+ // Remember the limits which are programmed into this bridge
+ //
+
+ ChildBusData->BridgeConfigRead = TRUE;
+ HalpSetBusHandlerParent (ChildBus, CB.BusHandler);
+ ChildBusData->ParentBus = (UCHAR) CB.BusHandler->BusNumber;
+ ChildBusData->CommonData.ParentSlot = CB.SlotNumber;
+
+ ChildBus->BusAddresses->IO.Base =
+ PciBridgeIO2Base(
+ CB.PciData->u.type1.IOBase,
+ CB.PciData->u.type1.IOBaseUpper16
+ );
+
+ ChildBus->BusAddresses->IO.Limit =
+ PciBridgeIO2Limit(
+ CB.PciData->u.type1.IOLimit,
+ CB.PciData->u.type1.IOLimitUpper16
+ );
+
+ //
+ // Special VGA address remapping occuring on this bridge?
+ //
+
+ if (CB.PciData->u.type1.BridgeControl & PCI_ENABLE_BRIDGE_VGA &&
+ ChildBus->BusAddresses->IO.Base < ChildBus->BusAddresses->IO.Limit) {
+
+ HalpSetPciBridgedVgaCronk (
+ ChildBus->BusNumber,
+ (ULONG) ChildBus->BusAddresses->IO.Base,
+ (ULONG) ChildBus->BusAddresses->IO.Limit
+ );
+ }
+
+ //
+ // If supported I/O ranges on this bus are limitied to
+ // 256bytes on every 1K aligned boundry within the
+ // range, then redo supported IO BusAddresses to match
+ //
+
+ if (CB.PciData->u.type1.BridgeControl & PCI_ENABLE_BRIDGE_ISA &&
+ ChildBus->BusAddresses->IO.Base < ChildBus->BusAddresses->IO.Limit) {
+
+ // assume Base is 1K aligned
+ i = (ULONG) ChildBus->BusAddresses->IO.Base;
+ j = (ULONG) ChildBus->BusAddresses->IO.Limit;
+
+ // convert head entry
+ ChildBus->BusAddresses->IO.Limit = i + 256;
+ i += 1024;
+
+ // add remaining ranges
+ while (i < j) {
+ HalpAddRange (
+ &ChildBus->BusAddresses->IO,
+ 1, // address space
+ 0, // system base
+ i, // bus address
+ i + 256 // bus limit
+ );
+
+ // next range
+ i += 1024;
+ }
+ }
+
+ ChildBus->BusAddresses->Memory.Base =
+ PciBridgeMemory2Base(CB.PciData->u.type1.MemoryBase);
+
+ ChildBus->BusAddresses->Memory.Limit =
+ PciBridgeMemory2Limit(CB.PciData->u.type1.MemoryLimit);
+
+ // On x86 it's ok to clip Prefetch to 32 bits
+
+ if (CB.PciData->u.type1.PrefetchBaseUpper32 == 0) {
+ ChildBus->BusAddresses->PrefetchMemory.Base =
+ PciBridgeMemory2Base(CB.PciData->u.type1.PrefetchBase);
+
+
+ ChildBus->BusAddresses->PrefetchMemory.Limit =
+ PciBridgeMemory2Limit(CB.PciData->u.type1.PrefetchLimit);
+
+ if (CB.PciData->u.type1.PrefetchLimitUpper32) {
+ ChildBus->BusAddresses->PrefetchMemory.Limit = 0xffffffff;
+ }
+ }
+
+ // should call HalpAssignPCISlotResources to assign
+ // baseaddresses, etc...
+ }
+ }
+ }
+
+ if (Rescan) {
+ *MaxPciBus = Rescan;
+ return TRUE;
+ }
+
+ if (!FoundDisabledBridge) {
+ return FALSE;
+ }
+
+ DBGMSG ("HAL GetPciData: found disabled pci bridge\n");
+
+#ifdef INIT_PCI_BRIDGE
+ //
+ // We've calculated all the parent's buses known bases & limits.
+ // While doing this a pci-pci bus was found that the bios didn't
+ // configure. This is not expected, and we'll make some guesses
+ // at a configuration here and enable it.
+ //
+ // (this code is primarily for testing the above code since
+ // currently no system bioses actually configure the child buses)
+ //
+
+ for (BusNo=0; BusNo < *MaxPciBus; BusNo++) {
+
+ CB.BusHandler = HalpHandlerForBus (PCIBus, BusNo);
+ CB.BusData = (PPCIPBUSDATA) CB.BusHandler->BusData;
+
+ for (d = 0; d < PCI_MAX_DEVICES; d++) {
+ CB.SlotNumber.u.bits.DeviceNumber = d;
+
+ for (f = 0; f < PCI_MAX_FUNCTION; f++) {
+ CB.SlotNumber.u.bits.FunctionNumber = f;
+
+ HalpReadPCIConfig (
+ CB.BusHandler,
+ CB.SlotNumber,
+ CB.PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+ if (CB.PciData->VendorID == PCI_INVALID_VENDORID) {
+ break;
+ }
+
+ if (!IsPciBridge (CB.PciData)) {
+ // not a PCI-PCI bridge
+ continue;
+ }
+
+ if ((CB.PciData->Command & PCI_ENABLE_BUS_MASTER)) {
+ // this PCI bridge is enabled
+ continue;
+ }
+
+ //
+ // We have a disabled bus - assign it a number, then
+ // determine all the requirements of all devices
+ // on the other side of this bridge
+ //
+
+ CB.BusNo = BusNo;
+ HalpGetPciBridgeNeeds (HwType, MaxPciBus, &CB);
+ }
+ }
+ }
+ // preform Rescan
+ return TRUE;
+
+#else
+
+ return FALSE;
+
+#endif
+
+}
+
+VOID
+HalpFixupPciSupportedRanges (
+ IN ULONG MaxBuses
+ )
+/*++
+
+Routine Description:
+
+ PCI-PCI bridged buses only see addresses which their parent
+ bueses support. So adjust any PCI SUPPORT_RANGES to be
+ a complete subset of all of it's parent buses.
+
+ PCI-PCI briges use postive address decode to forward addresses.
+ So, remove any addresses from any PCI bus which are bridged to
+ a child PCI bus.
+
+--*/
+{
+ ULONG i;
+ PBUS_HANDLER Bus, ParentBus;
+ PSUPPORTED_RANGES HRanges;
+
+ //
+ // Pass 1 - shrink all PCI supported ranges to be a subset of
+ // all of it's parent buses
+ //
+
+ for (i = 0; i < MaxBuses; i++) {
+
+ Bus = HalpHandlerForBus (PCIBus, i);
+
+ ParentBus = Bus->ParentHandler;
+ while (ParentBus) {
+
+ HRanges = Bus->BusAddresses;
+ Bus->BusAddresses = HalpMergeRanges (
+ ParentBus->BusAddresses,
+ HRanges
+ );
+
+ HalpFreeRangeList (HRanges);
+ ParentBus = ParentBus->ParentHandler;
+ }
+ }
+
+ //
+ // Pass 2 - remove all child PCI bus ranges from parent PCI buses
+ //
+
+ for (i = 0; i < MaxBuses; i++) {
+ Bus = HalpHandlerForBus (PCIBus, i);
+
+ ParentBus = Bus->ParentHandler;
+ while (ParentBus) {
+
+ if (ParentBus->InterfaceType == PCIBus) {
+ HalpRemoveRanges (
+ ParentBus->BusAddresses,
+ Bus->BusAddresses
+ );
+ }
+
+ ParentBus = ParentBus->ParentHandler;
+ }
+ }
+
+ //
+ // Cleanup
+ //
+
+ for (i = 0; i < MaxBuses; i++) {
+ Bus = HalpHandlerForBus (PCIBus, i);
+ HalpConsolidateRanges (Bus->BusAddresses);
+ }
+}
+
+
+
+VOID
+HalpSetPciBridgedVgaCronk (
+ IN ULONG BusNumber,
+ IN ULONG BaseAddress,
+ IN ULONG LimitAddress
+ )
+/*++
+
+Routine Description: .
+
+ The 'vga compatible addresses' bit is set in the bridge control regiter.
+ This causes the bridge to pass any I/O address in the range of: 10bit
+ decode 3b0-3bb & 3c0-3df, as TEN bit addresses.
+
+ As far as I can tell this "feature" is an attempt to solve some problem
+ which the folks solving it did not fully understand, so instead of doing
+ it right we have this fine mess.
+
+ The solution is to take the least of all evils which is to remove any
+ I/O port ranges which are getting remapped from any IoAssignResource
+ request. (ie, IoAssignResources will never contimplate giving any
+ I/O port out in the suspected ranges).
+
+ note: memory allocation error here is fatal so don't bother with the
+ return codes.
+
+Arguments:
+
+ Base - Base of IO address range in question
+ Limit - Limit of IO address range in question
+
+--*/
+{
+ UNICODE_STRING unicodeString;
+ OBJECT_ATTRIBUTES objectAttributes;
+ HANDLE handle;
+ ULONG Length;
+ PCM_RESOURCE_LIST ResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
+ ULONG AddressMSBs;
+ WCHAR ValueName[80];
+ NTSTATUS status;
+
+ //
+ // Open reserved resource settings
+ //
+
+ RtlInitUnicodeString (&unicodeString, rgzReservedResources);
+ InitializeObjectAttributes( &objectAttributes,
+ &unicodeString,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ (PSECURITY_DESCRIPTOR) NULL
+ );
+
+ status = ZwOpenKey( &handle, KEY_READ|KEY_WRITE, &objectAttributes);
+ if (!NT_SUCCESS(status)) {
+ return;
+ }
+
+ //
+ // Build resource list of reseved ranges
+ //
+
+ Length = ((LimitAddress - BaseAddress) / 1024 + 2) * 2 *
+ sizeof (CM_PARTIAL_RESOURCE_DESCRIPTOR) +
+ sizeof (CM_RESOURCE_LIST);
+
+ ResourceList = (PCM_RESOURCE_LIST) ExAllocatePool (PagedPool, Length);
+ memset (ResourceList, 0, Length);
+
+ ResourceList->Count = 1;
+ ResourceList->List[0].InterfaceType = PCIBus;
+ ResourceList->List[0].BusNumber = BusNumber;
+ Descriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
+
+ while (BaseAddress < LimitAddress) {
+ AddressMSBs = BaseAddress & ~0x3ff; // get upper 10bits of addr
+
+ //
+ // Add xx3b0 through xx3bb
+ //
+
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO;
+ Descriptor->u.Port.Start.QuadPart = AddressMSBs | 0x3b0;
+ Descriptor->u.Port.Length = 0xb;
+
+ Descriptor += 1;
+ ResourceList->List[0].PartialResourceList.Count += 1;
+
+ //
+ // Add xx3c0 through xx3df
+ //
+
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO;
+ Descriptor->u.Port.Start.QuadPart = AddressMSBs | 0x3c0;
+ Descriptor->u.Port.Length = 0x1f;
+
+ Descriptor += 1;
+ ResourceList->List[0].PartialResourceList.Count += 1;
+
+ //
+ // Next range
+ //
+
+ BaseAddress += 1024;
+ }
+
+ //
+ // Add the reserved ranges to avoid during IoAssignResource
+ //
+
+ swprintf (ValueName, L"HAL_PCI_%d", BusNumber);
+ RtlInitUnicodeString (&unicodeString, ValueName);
+
+ ZwSetValueKey (handle,
+ &unicodeString,
+ 0L,
+ REG_RESOURCE_LIST,
+ ResourceList,
+ (ULONG) Descriptor - (ULONG) ResourceList
+ );
+
+
+ ExFreePool (ResourceList);
+ ZwClose (handle);
+}
+
+
+
+#ifdef INIT_PCI_BRIDGE
+
+VOID
+HalpGetPciBridgeNeeds (
+ IN ULONG HwType,
+ IN PUCHAR MaxPciBus,
+ IN PCONFIGBRIDGE Current
+ )
+{
+ ACCESS_MASK DesiredAccess;
+ UNICODE_STRING unicodeString;
+ PUCHAR buffer;
+ HANDLE handle;
+ OBJECT_ATTRIBUTES objectAttributes;
+ PCM_FULL_RESOURCE_DESCRIPTOR Descriptor;
+ PCONFIGURATION_COMPONENT Component;
+ CONFIGBRIDGE CB;
+ ULONG mnum, d, f, i;
+ NTSTATUS status;
+
+ buffer = ExAllocatePool (PagedPool, 1024);
+
+ // init
+ CB.PciData = (PPCI_COMMON_CONFIG) CB.Buffer;
+ CB.SlotNumber.u.bits.Reserved = 0;
+ Current->IO = Current->Memory = Current->PFMemory = 0;
+
+ //
+ // Assign this bridge an ID, and turn on configuration space
+ //
+
+ Current->PciData->u.type1.PrimaryBus = (UCHAR) Current->BusNo;
+ Current->PciData->u.type1.SecondaryBus = (UCHAR) *MaxPciBus;
+ Current->PciData->u.type1.SubordinateBus = (UCHAR) 0xFF;
+ Current->PciData->u.type1.SecondaryStatus = 0xffff;
+ Current->PciData->Status = 0xffff;
+ Current->PciData->Command = 0;
+
+ Current->PciData->u.type1.BridgeControl = PCI_ASSERT_BRIDGE_RESET;
+
+ HalpWritePCIConfig (
+ Current->BusHandler,
+ Current->SlotNumber,
+ Current->PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+ KeStallExecutionProcessor (100);
+
+ Current->PciData->u.type1.BridgeControl = 0;
+ HalpWritePCIConfig (
+ Current->BusHandler,
+ Current->SlotNumber,
+ Current->PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+
+ KeStallExecutionProcessor (100);
+
+ //
+ // Allocate new handler for bus
+ //
+
+ CB.BusHandler = HalpAllocateAndInitPciBusHandler (HwType, *MaxPciBus, FALSE);
+ CB.BusData = (PPCIPBUSDATA) CB.BusHandler->BusData;
+ CB.BusNo = *MaxPciBus;
+ *MaxPciBus += 1;
+
+ //
+ // Add another PCI bus in the registry
+ //
+
+ mnum = 0;
+ for (; ;) {
+ //
+ // Find next available MultiFunctionAdapter key
+ //
+
+ DesiredAccess = KEY_READ | KEY_WRITE;
+ swprintf ((PWCHAR) buffer, L"%s\\%d", rgzMultiFunctionAdapter, mnum);
+ RtlInitUnicodeString (&unicodeString, (PWCHAR) buffer);
+
+ InitializeObjectAttributes( &objectAttributes,
+ &unicodeString,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ (PSECURITY_DESCRIPTOR) NULL
+ );
+
+ status = ZwOpenKey( &handle, DesiredAccess, &objectAttributes);
+ if (!NT_SUCCESS(status)) {
+ break;
+ }
+
+ // already exists, next
+ ZwClose (handle);
+ mnum += 1;
+ }
+
+ ZwCreateKey (&handle,
+ DesiredAccess,
+ &objectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ &d
+ );
+
+ //
+ // Add needed registry values for this MultifucntionAdapter entry
+ //
+
+ RtlInitUnicodeString (&unicodeString, rgzIdentifier);
+ ZwSetValueKey (handle,
+ &unicodeString,
+ 0L,
+ REG_SZ,
+ L"PCI",
+ sizeof (L"PCI")
+ );
+
+ RtlInitUnicodeString (&unicodeString, rgzConfigurationData);
+ Descriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) buffer;
+ Descriptor->InterfaceType = PCIBus;
+ Descriptor->BusNumber = CB.BusNo;
+ Descriptor->PartialResourceList.Version = 0;
+ Descriptor->PartialResourceList.Revision = 0;
+ Descriptor->PartialResourceList.Count = 0;
+ ZwSetValueKey (handle,
+ &unicodeString,
+ 0L,
+ REG_FULL_RESOURCE_DESCRIPTOR,
+ Descriptor,
+ sizeof (*Descriptor)
+ );
+
+
+ RtlInitUnicodeString (&unicodeString, L"Component Information");
+ Component = (PCONFIGURATION_COMPONENT) buffer;
+ RtlZeroMemory (Component, sizeof (*Component));
+ Component->AffinityMask = 0xffffffff;
+ ZwSetValueKey (handle,
+ &unicodeString,
+ 0L,
+ REG_BINARY,
+ Component,
+ FIELD_OFFSET (CONFIGURATION_COMPONENT, ConfigurationDataLength)
+ );
+
+ ZwClose (handle);
+
+
+ //
+ // Since the BIOS didn't configure this bridge we'll assume that
+ // the PCI interrupts are bridged. (for BIOS configured buses we
+ // assume that the BIOS put the ISA bus IRQ in the InterruptLine value)
+ //
+
+ CB.BusData->Pin2Line = (PciPin2Line) HalpPCIBridgedPin2Line;
+ CB.BusData->Line2Pin = (PciLine2Pin) HalpPCIBridgedLine2Pin;
+ //CB.BusData->GetIrqTable = (PciIrqTable) HalpGetBridgedPCIIrqTable;
+
+ if (Current->BusHandler->GetInterruptVector == HalpGetPCIIntOnISABus) {
+
+ //
+ // The parent bus'es interrupt pin to vector mappings is not
+ // a static function, and is determined by the boot firmware.
+ //
+
+ //CB.BusHandler->GetInterruptVector = (PGETINTERRUPTVECTOR) HalpGetBridgedPCIISAInt;
+
+ // read each device on parent bus
+ for (d = 0; d < PCI_MAX_DEVICES; d++) {
+ CB.SlotNumber.u.bits.DeviceNumber = d;
+
+ for (f = 0; f < PCI_MAX_FUNCTION; f++) {
+ CB.SlotNumber.u.bits.FunctionNumber = f;
+
+ HalpReadPCIConfig (
+ Current->BusHandler,
+ CB.SlotNumber,
+ CB.PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+ if (CB.PciData->VendorID == PCI_INVALID_VENDORID) {
+ break;
+ }
+
+ if (CB.PciData->u.type0.InterruptPin &&
+ (PCI_CONFIG_TYPE (CB.PciData) == PCI_DEVICE_TYPE ||
+ PCI_CONFIG_TYPE (CB.PciData) == PCI_BRIDGE_TYPE)) {
+
+ // get bios supplied int mapping
+ i = CB.PciData->u.type0.InterruptPin + d % 4;
+ CB.BusData->SwizzleIn[i] = CB.PciData->u.type0.InterruptLine;
+ }
+ }
+ }
+
+ } else {
+ _asm int 3;
+ }
+
+ //
+ // Look at each device on the bus and determine it's resource needs
+ //
+
+ for (d = 0; d < PCI_MAX_DEVICES; d++) {
+ CB.SlotNumber.u.bits.DeviceNumber = d;
+
+ for (f = 0; f < PCI_MAX_FUNCTION; f++) {
+ CB.SlotNumber.u.bits.FunctionNumber = f;
+
+ HalpReadPCIConfig (
+ CB.BusHandler,
+ CB.SlotNumber,
+ CB.PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+ if (CB.PciData->VendorID == PCI_INVALID_VENDORID) {
+ break;
+ }
+
+ if (IsPciBridge (CB.PciData)) {
+ // oh look - another bridge ...
+ HalpGetPciBridgeNeeds (HwType, MaxPciBus, &CB);
+ continue;
+ }
+
+ if (PCI_CONFIG_TYPE (CB.PciData) != PCI_DEVICE_TYPE) {
+ continue;
+ }
+
+ // found a device - figure out the resources it needs
+ }
+ }
+
+ //
+ // Found all sub-buses set SubordinateBus accordingly
+ //
+
+ Current->PciData->u.type1.SubordinateBus = (UCHAR) *MaxPciBus - 1;
+
+ HalpWritePCIConfig (
+ Current->BusHandler,
+ Current->SlotNumber,
+ Current->PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+
+ //
+ // Set the bridges IO, Memory, and Prefetch Memory windows
+ //
+
+ // For now just pick some numbers & set everyone the same
+ // IO 0x6000 - 0xFFFF
+ // MEM 0x40000000 - 0x4FFFFFFF
+ // PFMEM 0x50000000 - 0x5FFFFFFF
+
+ Current->PciData->u.type1.IOBase = 0x6000 >> 12 << 4;
+ Current->PciData->u.type1.IOLimit = 0xffff >> 12 << 4;
+ Current->PciData->u.type1.MemoryBase = 0x40000000 >> 20 << 4;
+ Current->PciData->u.type1.MemoryLimit = 0x4fffffff >> 20 << 4;
+ Current->PciData->u.type1.PrefetchBase = 0x50000000 >> 20 << 4;
+ Current->PciData->u.type1.PrefetchLimit = 0x5fffffff >> 20 << 4;
+
+ Current->PciData->u.type1.PrefetchBaseUpper32 = 0;
+ Current->PciData->u.type1.PrefetchLimitUpper32 = 0;
+ Current->PciData->u.type1.IOBaseUpper16 = 0;
+ Current->PciData->u.type1.IOLimitUpper16 = 0;
+ Current->PciData->u.type1.BridgeControl =
+ PCI_ENABLE_BRIDGE_ISA;
+
+ HalpWritePCIConfig (
+ Current->BusHandler,
+ Current->SlotNumber,
+ Current->PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+ HalpReadPCIConfig (
+ Current->BusHandler,
+ Current->SlotNumber,
+ Current->PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+ // enable memory & io decodes
+
+ Current->PciData->Command =
+ PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE | PCI_ENABLE_BUS_MASTER;
+
+ HalpWritePCIConfig (
+ Current->BusHandler,
+ Current->SlotNumber,
+ &Current->PciData->Command,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Command),
+ sizeof (Current->PciData->Command)
+ );
+
+ ExFreePool (buffer);
+}
+
+VOID
+HalpPCIBridgedPin2Line (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciData
+ )
+/*++
+
+ This function maps the device's InterruptPin to an InterruptLine
+ value.
+
+ test function particular to dec pci-pci bridge card
+
+--*/
+{
+ PPCIPBUSDATA BusData;
+ ULONG i;
+
+ if (!PciData->u.type0.InterruptPin) {
+ return ;
+ }
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ //
+ // Convert slot Pin into Bus INTA-D.
+ //
+
+ i = (PciData->u.type0.InterruptPin +
+ SlotNumber.u.bits.DeviceNumber - 1) % 4;
+
+ PciData->u.type0.InterruptLine = BusData->SwizzleIn[i] ^ IRQXOR;
+ PciData->u.type0.InterruptLine = 0x0b ^ IRQXOR;
+}
+
+
+VOID
+HalpPCIBridgedLine2Pin (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciNewData,
+ IN PPCI_COMMON_CONFIG PciOldData
+ )
+/*++
+
+ This functions maps the device's InterruptLine to it's
+ device specific InterruptPin value.
+
+ test function particular to dec pci-pci bridge card
+
+--*/
+{
+ PPCIPBUSDATA BusData;
+ ULONG i;
+
+ if (!PciNewData->u.type0.InterruptPin) {
+ return ;
+ }
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ i = (PciNewData->u.type0.InterruptPin +
+ SlotNumber.u.bits.DeviceNumber - 1) % 4;
+
+ PciNewData->u.type0.InterruptLine = BusData->SwizzleIn[i] ^ IRQXOR;
+ PciNewData->u.type0.InterruptLine = 0x0b ^ IRQXOR;
+}
+
+#endif
diff --git a/private/ntos/nthals/halr96b/mips/pcibus.c b/private/ntos/nthals/halr96b/mips/pcibus.c
new file mode 100644
index 000000000..a77edf46e
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/pcibus.c
@@ -0,0 +1,3585 @@
+// #pragma comment(exestr, "@(#) pcibus.c 1.1 95/09/28 15:45:56 nec")
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ ixpcidat.c
+
+Abstract:
+
+ Get/Set bus data routines for the PCI bus
+
+Author:
+
+ Ken Reneris (kenr) 14-June-1994
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+Modification History:
+
+ H001 Fri Jun 30 02:54:08 1995 kbnes!kisimoto
+ - Merge build 1057 ixpcibus.c
+ H002 Tue Jul 4 20:43:12 1995 kbnes!kisimoto
+ - disable preferred setting for back-to-back
+ support. If enable, IoAssign... allocates
+ current enabled address space.
+ H003 Wed Jul 5 14:27:46 1995 kbnes!kisimoto
+ - initialize with FALSE
+ H004 Tue Sep 5 20:06:16 1995 kbnes!kisimoto
+ - PCI Fast Back-to-back transfer support
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+
+#if defined(_R94A_) // H001
+#include "r94adef.h"
+#include "string.h"
+#endif // _R94A_
+
+extern WCHAR rgzMultiFunctionAdapter[];
+extern WCHAR rgzConfigurationData[];
+extern WCHAR rgzIdentifier[];
+extern WCHAR rgzPCIIdentifier[];
+
+
+typedef ULONG (*FncConfigIO) (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+typedef VOID (*FncSync) (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PVOID State
+ );
+
+typedef VOID (*FncReleaseSync) (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ );
+
+typedef struct _PCI_CONFIG_HANDLER {
+ FncSync Synchronize;
+ FncReleaseSync ReleaseSynchronzation;
+ FncConfigIO ConfigRead[3];
+ FncConfigIO ConfigWrite[3];
+} PCI_CONFIG_HANDLER, *PPCI_CONFIG_HANDLER;
+
+
+
+//
+// Prototypes
+//
+
+ULONG
+HalpGetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+ULONG
+HalpSetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+NTSTATUS
+HalpAssignPCISlotResources (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName OPTIONAL,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ IN ULONG SlotNumber,
+ IN OUT PCM_RESOURCE_LIST *AllocatedResources
+ );
+
+#if 0
+VOID
+HalpInitializePciBus (
+ VOID
+ );
+#endif
+
+BOOLEAN
+HalpIsValidPCIDevice (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ );
+
+BOOLEAN
+HalpValidPCISlot (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ );
+
+//-------------------------------------------------
+
+VOID HalpPCISynchronizeType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PVOID State
+ );
+
+VOID HalpPCIReleaseSynchronzationType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ );
+
+ULONG HalpPCIReadUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+VOID HalpPCISynchronizeType2 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PVOID State
+ );
+
+VOID HalpPCIReleaseSynchronzationType2 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ );
+
+ULONG HalpPCIReadUlongType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUcharType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUshortType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUlongType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUcharType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUshortType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+
+//
+// Globals
+//
+
+// KSPIN_LOCK HalpPCIConfigLock; // H001
+
+PCI_CONFIG_HANDLER PCIConfigHandler;
+
+PCI_CONFIG_HANDLER PCIConfigHandlerType1 = {
+ HalpPCISynchronizeType1,
+ HalpPCIReleaseSynchronzationType1,
+ {
+ HalpPCIReadUlongType1, // 0
+ HalpPCIReadUcharType1, // 1
+ HalpPCIReadUshortType1 // 2
+ },
+ {
+ HalpPCIWriteUlongType1, // 0
+ HalpPCIWriteUcharType1, // 1
+ HalpPCIWriteUshortType1 // 2
+ }
+};
+
+PCI_CONFIG_HANDLER PCIConfigHandlerType2 = {
+ HalpPCISynchronizeType2,
+ HalpPCIReleaseSynchronzationType2,
+ {
+ HalpPCIReadUlongType2, // 0
+ HalpPCIReadUcharType2, // 1
+ HalpPCIReadUshortType2 // 2
+ },
+ {
+ HalpPCIWriteUlongType2, // 0
+ HalpPCIWriteUcharType2, // 1
+ HalpPCIWriteUshortType2 // 2
+ }
+};
+
+UCHAR PCIDeref[4][4] = { {0,1,2,2},{1,1,1,1},{2,1,2,2},{1,1,1,1} };
+
+BOOLEAN HalpDoingCrashDump = FALSE; // H003
+ULONG HalpFoundUncapablePCIDevice = 0; // H004
+ULONG HalpPCINumberOfMappedGA = 0;
+ULONG HalpPCIBackToBackReg0Start = 0;
+ULONG HalpPCIBackToBackReg1Start = 0;
+ULONG HalpPCIBackToBackReg0Open = 1;
+ULONG HalpPCIBackToBackReg1Open = 1;
+ULONG HalpNumberOfPCIGA = 0;
+ULONG HalpPCIMemoryLimit = 0xffffffff;
+
+#define INIT_VALUE_OF_BACK_TO_BACK_ADDR 0x00000000
+#define INIT_VALUE_OF_BACK_TO_BACK_MASK 0xffffffff
+
+VOID
+HalpPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN FncConfigIO *ConfigIO
+ );
+
+#if defined(_R94A_) // H001
+ULONG
+HalpGetPCIInterruptVector(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ );
+ULONG
+HalpGetNumberOfPCIGA(
+ IN ULONG NumberBuses
+ );
+VOID
+HalpSetBackToBackSpace(
+ IN PPCI_COMMON_CONFIG PciConfigRequired,
+ IN PPCI_COMMON_CONFIG PciConfigMapped,
+ IN PBUS_HANDLER BusHandler
+ );
+VOID
+HalpSetBackToBackRegister(
+ IN ULONG BaseAddress,
+ IN ULONG Length,
+ IN ULONG Register
+ );
+#endif // _R94A_
+
+#if DBG
+#define DBGMSG(a) DbgPrint(a)
+ULONG R94aDoTestPci = 0;
+ULONG R94aDoTestPciNec = 0;
+ULONG R94aDoOtherTest = 0;
+VOID
+HalpTestPciNec (
+ ULONG
+ );
+VOID
+HalpTestPciPrintResult(
+ IN PULONG Buffer,
+ IN ULONG Length
+ );
+VOID
+HalpOtherTestNec (
+ ULONG
+ );
+VOID
+HalpTestPci (
+ ULONG
+ );
+#else
+#define DBGMSG(a)
+#endif
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpInitializePciBus)
+#pragma alloc_text(INIT,HalpAllocateAndInitPciBusHandler)
+#pragma alloc_text(INIT,HalpIsValidPCIDevice)
+#pragma alloc_text(PAGE,HalpAssignPCISlotResources)
+#endif
+
+
+
+VOID
+HalpInitializePciBus (
+ VOID
+ )
+{
+ PPCI_REGISTRY_INFO PCIRegInfo;
+ UNICODE_STRING unicodeString, ConfigName, IdentName;
+ OBJECT_ATTRIBUTES objectAttributes;
+ HANDLE hMFunc, hBus;
+ NTSTATUS status;
+ UCHAR buffer [sizeof(PPCI_REGISTRY_INFO) + 99];
+ PWSTR p;
+ WCHAR wstr[8];
+ ULONG i, d, junk, HwType, BusNo, f;
+ PBUS_HANDLER BusHandler;
+ PCI_SLOT_NUMBER SlotNumber;
+ PPCI_COMMON_CONFIG PciData;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ PKEY_VALUE_FULL_INFORMATION ValueInfo;
+ PCM_FULL_RESOURCE_DESCRIPTOR Desc;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PDesc;
+
+ PCI_REGISTRY_INFO tPCIRegInfo; // H001
+
+#if 0 // H001
+ //
+ // Search the hardware description looking for any reported
+ // PCI bus. The first ARC entry for a PCI bus will contain
+ // the PCI_REGISTRY_INFO.
+
+ RtlInitUnicodeString (&unicodeString, rgzMultiFunctionAdapter);
+ InitializeObjectAttributes (
+ &objectAttributes,
+ &unicodeString,
+ OBJ_CASE_INSENSITIVE,
+ NULL, // handle
+ NULL);
+
+
+ status = ZwOpenKey (&hMFunc, KEY_READ, &objectAttributes);
+ if (!NT_SUCCESS(status)) {
+ return ;
+ }
+
+ unicodeString.Buffer = wstr;
+ unicodeString.MaximumLength = sizeof (wstr);
+
+ RtlInitUnicodeString (&ConfigName, rgzConfigurationData);
+ RtlInitUnicodeString (&IdentName, rgzIdentifier);
+
+ ValueInfo = (PKEY_VALUE_FULL_INFORMATION) buffer;
+
+ for (i=0; TRUE; i++) {
+ RtlIntegerToUnicodeString (i, 10, &unicodeString);
+ InitializeObjectAttributes (
+ &objectAttributes,
+ &unicodeString,
+ OBJ_CASE_INSENSITIVE,
+ hMFunc,
+ NULL);
+
+ status = ZwOpenKey (&hBus, KEY_READ, &objectAttributes);
+ if (!NT_SUCCESS(status)) {
+ //
+ // Out of Multifunction adapter entries...
+ //
+
+ ZwClose (hMFunc);
+ return ;
+ }
+
+ //
+ // Check the Indentifier to see if this is a PCI entry
+ //
+
+ status = ZwQueryValueKey (
+ hBus,
+ &IdentName,
+ KeyValueFullInformation,
+ ValueInfo,
+ sizeof (buffer),
+ &junk
+ );
+
+ if (!NT_SUCCESS (status)) {
+ ZwClose (hBus);
+ continue;
+ }
+
+ p = (PWSTR) ((PUCHAR) ValueInfo + ValueInfo->DataOffset);
+ if (p[0] != L'P' || p[1] != L'C' || p[2] != L'I' || p[3] != 0) {
+ ZwClose (hBus);
+ continue;
+ }
+
+ //
+ // The first PCI entry has the PCI_REGISTRY_INFO structure
+ // attached to it.
+ //
+
+ status = ZwQueryValueKey (
+ hBus,
+ &ConfigName,
+ KeyValueFullInformation,
+ ValueInfo,
+ sizeof (buffer),
+ &junk
+ );
+
+ ZwClose (hBus);
+ if (!NT_SUCCESS(status)) {
+ continue ;
+ }
+
+ Desc = (PCM_FULL_RESOURCE_DESCRIPTOR) ((PUCHAR)
+ ValueInfo + ValueInfo->DataOffset);
+ PDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)
+ Desc->PartialResourceList.PartialDescriptors);
+
+ if (PDesc->Type == CmResourceTypeDeviceSpecific) {
+ // got it..
+ PCIRegInfo = (PPCI_REGISTRY_INFO) (PDesc+1);
+ break;
+ }
+ }
+
+ //
+ // Initialize spinlock for synchronizing access to PCI space
+ //
+
+// KeInitializeSpinLock (&HalpPCIConfigLock); // H001
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+
+#endif // 0
+
+#if defined(_R94A_) // H001
+
+ PCIRegInfo = &tPCIRegInfo;
+ PCIRegInfo->NoBuses = 1;
+ PCIRegInfo->HardwareMechanism=0x1; // HURRICANE PCI Config Type
+
+#if DBG
+ DbgPrint("PCI System Get Data:\n");
+ DbgPrint("MajorRevision %x\n", PCIRegInfo->MajorRevision );
+ DbgPrint("MinorRevision %x\n", PCIRegInfo->MinorRevision );
+ DbgPrint("NoBuses %x\n", PCIRegInfo->NoBuses );
+ DbgPrint("HwMechanism %x\n", PCIRegInfo->HardwareMechanism );
+#endif // DBG
+
+#endif // _R94A_
+
+ //
+ // PCIRegInfo describes the system's PCI support as indicated by the BIOS.
+ //
+
+ HwType = PCIRegInfo->HardwareMechanism & 0xf;
+
+ //
+ // Some AMI bioses claim machines are Type2 configuration when they
+ // are really type1. If this is a Type2 with at least one bus,
+ // try to verify it's not really a type1 bus
+ //
+
+ if (PCIRegInfo->NoBuses && HwType == 2) {
+
+ //
+ // Check each slot for a valid device. Which every style configuration
+ // space shows a valid device first will be used
+ //
+
+ SlotNumber.u.bits.Reserved = 0;
+ SlotNumber.u.bits.FunctionNumber = 0;
+
+ for (d = 0; d < PCI_MAX_DEVICES; d++) {
+ SlotNumber.u.bits.DeviceNumber = d;
+
+ //
+ // First try what the BIOS claims - type 2. Allocate type2
+ // test handle for PCI bus 0.
+ //
+
+ HwType = 2;
+ BusHandler = HalpAllocateAndInitPciBusHandler (HwType, 0, TRUE);
+
+ if (HalpIsValidPCIDevice (BusHandler, SlotNumber)) {
+ break;
+ }
+
+ //
+ // Valid device not found on Type2 access for this slot.
+ // Reallocate the bus handler are Type1 and take a look.
+ //
+
+ HwType = 1;
+ BusHandler = HalpAllocateAndInitPciBusHandler (HwType, 0, TRUE);
+
+ if (HalpIsValidPCIDevice (BusHandler, SlotNumber)) {
+ break;
+ }
+
+ HwType = 2;
+ }
+
+ //
+ // Reset handler for PCI bus 0 to whatever style config space
+ // was finally decided.
+ //
+
+ HalpAllocateAndInitPciBusHandler (HwType, 0, FALSE);
+ }
+
+
+ //
+ // For each PCI bus present, allocate a handler structure and
+ // fill in the dispatch functions
+ //
+
+#if 0 // H001
+ do {
+#endif
+ for (i=0; i < PCIRegInfo->NoBuses; i++) {
+
+ //
+ // If handler not already built, do it now
+ //
+
+ if (!HalpHandlerForBus (PCIBus, i)) {
+ HalpAllocateAndInitPciBusHandler (HwType, i, FALSE);
+ }
+ }
+
+ //
+ // Bus handlers for all PCI buses have been allocated, go collect
+ // pci bridge information.
+ //
+
+#if 0 // H001
+ } while (HalpGetPciBridgeConfig (HwType, &PCIRegInfo->NoBuses)) ;
+
+ //
+ // Fixup SUPPORTED_RANGES
+ //
+
+ HalpFixupPciSupportedRanges (PCIRegInfo->NoBuses);
+
+ //
+ // Look for PCI controllers which have known work-arounds, and make
+ // sure they are applied.
+ //
+
+ SlotNumber.u.bits.Reserved = 0;
+ for (BusNo=0; BusNo < PCIRegInfo->NoBuses; BusNo++) {
+ BusHandler = HalpHandlerForBus (PCIBus, BusNo);
+
+ for (d = 0; d < PCI_MAX_DEVICES; d++) {
+ SlotNumber.u.bits.DeviceNumber = d;
+
+ for (f = 0; f < PCI_MAX_FUNCTION; f++) {
+ SlotNumber.u.bits.FunctionNumber = f;
+
+ //
+ // Read PCI configuration information
+ //
+
+ HalpReadPCIConfig (BusHandler, SlotNumber, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Check for chips with known work-arounds to apply
+ //
+
+ if (PciData->VendorID == 0x8086 &&
+ PciData->DeviceID == 0x04A3 &&
+ PciData->RevisionID < 0x11) {
+
+ //
+ // 82430 PCMC controller
+ //
+
+ HalpReadPCIConfig (BusHandler, SlotNumber, buffer, 0x53, 2);
+
+ buffer[0] &= ~0x08; // turn off bit 3 register 0x53
+
+ if (PciData->RevisionID == 0x10) { // on rev 0x10, also turn
+ buffer[1] &= ~0x01; // bit 0 register 0x54
+ }
+
+ HalpWritePCIConfig (BusHandler, SlotNumber, buffer, 0x53, 2);
+ }
+
+ if (PciData->VendorID == 0x8086 &&
+ PciData->DeviceID == 0x0484 &&
+ PciData->RevisionID <= 3) {
+
+ //
+ // 82378 ISA bridge & SIO
+ //
+
+ HalpReadPCIConfig (BusHandler, SlotNumber, buffer, 0x41, 1);
+
+ buffer[0] &= ~0x1; // turn off bit 0 register 0x41
+
+ HalpWritePCIConfig (BusHandler, SlotNumber, buffer, 0x41, 1);
+ }
+
+ } // next function
+ } // next device
+ } // next bus
+#endif
+
+ //
+ // H005
+ // Compute the number of PCI-GA device and
+ // initialize Fast Back-to-back register.
+ //
+
+ HalpNumberOfPCIGA = HalpGetNumberOfPCIGA(PCIRegInfo->NoBuses);
+
+#if DBG
+ HalpTestPci (0);
+#if defined(_R94A_)
+ DbgPrint("HalpInitializePciBus: Call HalpTestPci(%x)\n",R94aDoTestPci);
+ HalpTestPci (R94aDoTestPci);
+ DbgPrint("HalpInitializePciBus: Call HalpTestPciNec(%x)\n",R94aDoTestPciNec);
+ HalpTestPciNec (R94aDoTestPciNec);
+ DbgPrint("HalpInitializePciBus: Call HalpOtherTest(%x)\n",R94aDoOtherTest);
+ HalpOtherTestNec (R94aDoOtherTest);
+#endif
+#endif
+}
+
+
+PBUS_HANDLER
+HalpAllocateAndInitPciBusHandler (
+ IN ULONG HwType,
+ IN ULONG BusNo,
+ IN BOOLEAN TestAllocation
+ )
+{
+ PBUS_HANDLER Bus;
+ PPCIPBUSDATA BusData;
+
+ Bus = HalpAllocateBusHandler (
+ PCIBus, // Interface type
+ PCIConfiguration, // Has this configuration space
+ BusNo, // bus #
+ Internal, // child of this bus
+ 0, // and number
+ sizeof (PCIPBUSDATA) // sizeof bus specific buffer
+ );
+
+ //
+ // Fill in PCI handlers
+ //
+
+ Bus->GetBusData = (PGETSETBUSDATA) HalpGetPCIData;
+ Bus->SetBusData = (PGETSETBUSDATA) HalpSetPCIData;
+#if defined(_R94A_)
+ Bus->GetInterruptVector = (PGETINTERRUPTVECTOR) HalpGetPCIInterruptVector;
+#else
+ Bus->GetInterruptVector = (PGETINTERRUPTVECTOR) HalpGetPCIIntOnISABus;
+#endif
+ Bus->AdjustResourceList = (PADJUSTRESOURCELIST) HalpAdjustPCIResourceList;
+ Bus->AssignSlotResources = (PASSIGNSLOTRESOURCES) HalpAssignPCISlotResources;
+ Bus->BusAddresses->Dma.Limit = 0;
+
+ BusData = (PPCIPBUSDATA) Bus->BusData;
+
+ //
+ // Fill in common PCI data
+ //
+
+ BusData->CommonData.Tag = PCI_DATA_TAG;
+ BusData->CommonData.Version = PCI_DATA_VERSION;
+ BusData->CommonData.ReadConfig = (PciReadWriteConfig) HalpReadPCIConfig;
+ BusData->CommonData.WriteConfig = (PciReadWriteConfig) HalpWritePCIConfig;
+ BusData->CommonData.Pin2Line = (PciPin2Line) HalpPCIPin2ISALine;
+ BusData->CommonData.Line2Pin = (PciLine2Pin) HalpPCIISALine2Pin;
+
+ //
+ // Set defaults
+ //
+
+ BusData->MaxDevice = PCI_MAX_DEVICES;
+ BusData->GetIrqRange = (PciIrqRange) HalpGetISAFixedPCIIrq;
+
+ RtlInitializeBitMap (&BusData->DeviceConfigured,
+ BusData->ConfiguredBits, 256);
+
+ switch (HwType) {
+ case 1:
+ //
+ // Initialize access port information for Type1 handlers
+ //
+
+ RtlCopyMemory (&PCIConfigHandler,
+ &PCIConfigHandlerType1,
+ sizeof (PCIConfigHandler));
+
+#if defined(_R94A_) // H001
+ BusData->Config.Type1.Address = (PULONG)R94A_PCI_TYPE1_ADDR_PORT;
+ BusData->Config.Type1.Data = R94A_PCI_TYPE1_DATA_PORT;
+#else
+ BusData->Config.Type1.Address = PCI_TYPE1_ADDR_PORT;
+ BusData->Config.Type1.Data = PCI_TYPE1_DATA_PORT;
+#endif // _R94A_
+ break;
+
+ case 2:
+ //
+ // Initialize access port information for Type2 handlers
+ //
+
+ RtlCopyMemory (&PCIConfigHandler,
+ &PCIConfigHandlerType2,
+ sizeof (PCIConfigHandler));
+
+ BusData->Config.Type2.CSE = PCI_TYPE2_CSE_PORT;
+ BusData->Config.Type2.Forward = PCI_TYPE2_FORWARD_PORT;
+ BusData->Config.Type2.Base = PCI_TYPE2_ADDRESS_BASE;
+
+ //
+ // Early PCI machines didn't decode the last bit of
+ // the device id. Shrink type 2 support max device.
+ //
+ BusData->MaxDevice = 0x10;
+
+ break;
+
+ default:
+ // unsupport type
+ DBGMSG ("HAL: Unkown PCI type\n");
+ }
+
+ if (!TestAllocation) {
+#ifdef SUBCLASSPCI
+ HalpSubclassPCISupport (Bus, HwType);
+#endif
+ }
+
+ return Bus;
+}
+
+BOOLEAN
+HalpIsValidPCIDevice (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ )
+/*++
+
+Routine Description:
+
+ Reads the device configuration data for the given slot and
+ returns TRUE if the configuration data appears to be valid for
+ a PCI device; otherwise returns FALSE.
+
+Arguments:
+
+ BusHandler - Bus to check
+ Slot - Slot to check
+
+--*/
+
+{
+ PPCI_COMMON_CONFIG PciData;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ ULONG i, j;
+
+
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+
+ //
+ // Read device common header
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Valid device header?
+ //
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != PCI_DEVICE_TYPE) {
+
+ return FALSE;
+ }
+
+ //
+ // Check fields for reasonable values
+ //
+
+ if ((PciData->u.type0.InterruptPin && PciData->u.type0.InterruptPin > 4) ||
+ (PciData->u.type0.InterruptLine & 0x70)) {
+ return FALSE;
+ }
+
+ for (i=0; i < PCI_TYPE0_ADDRESSES; i++) {
+ j = PciData->u.type0.BaseAddresses[i];
+
+ if (j & PCI_ADDRESS_IO_SPACE) {
+ if ((j > 0x2 && j < 0xffff) || j > 0xffffff) { // H001
+ // IO port < 64KB | IO port > 16MB
+ return FALSE;
+ }
+ } else {
+ if (j > 0xf && j < 0x3ffffff) { // H001
+ // Mem address < 64MB
+ return FALSE;
+ }
+ }
+
+ if (Is64BitBaseAddress(j)) {
+ i += 1;
+ }
+ }
+
+ //
+ // Guess it's a valid device..
+ //
+
+ return TRUE;
+}
+
+
+
+
+
+ULONG
+HalpGetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function returns the Pci bus data for a device.
+
+Arguments:
+
+ BusNumber - Indicates which bus.
+
+ VendorSpecificDevice - The VendorID (low Word) and DeviceID (High Word)
+
+ Buffer - Supplies the space to store the data.
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+ If this PCI slot has never been set, then the configuration information
+ returned is zeroed.
+
+
+--*/
+{
+ PPCI_COMMON_CONFIG PciData;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ PPCIPBUSDATA BusData;
+ ULONG Len;
+ ULONG i, bit;
+
+ if (Length > sizeof (PCI_COMMON_CONFIG)) {
+ Length = sizeof (PCI_COMMON_CONFIG);
+ }
+
+ Len = 0;
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The user did not request any data from the common
+ // header. Verify the PCI device exists, then continue
+ // in the device specific area.
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, sizeof(ULONG));
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID) {
+ return 0;
+ }
+
+ } else {
+
+ //
+ // Caller requested at least some data within the
+ // common header. Read the whole header, effect the
+ // fields we need to and then copy the user's requested
+ // bytes from the header
+ //
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ //
+ // Read this PCI devices slot data
+ //
+
+ Len = PCI_COMMON_HDR_LENGTH;
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, Len);
+
+#if 0
+ DbgPrint ("--------------->>> Now Print the Slot Information\n");
+ DbgPrint ("PCI Bus %d Slot %2d %2d ID:%04lx-%04lx Rev:%04lx",
+ BusHandler->BusNumber, Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber, PciData->VendorID, PciData->DeviceID,
+ PciData->RevisionID);
+
+
+ if (PciData->u.type0.InterruptPin) {
+ DbgPrint (" IntPin:%x", PciData->u.type0.InterruptPin);
+ }
+
+ if (PciData->u.type0.InterruptLine) {
+ DbgPrint (" IntLine:%x", PciData->u.type0.InterruptLine);
+ }
+
+ if (PciData->u.type0.ROMBaseAddress) {
+ DbgPrint (" ROM:%08lx", PciData->u.type0.ROMBaseAddress);
+ }
+
+ DbgPrint ("\n ProgIf:%04x SubClass:%04x BaseClass:%04lx\n",
+ PciData->ProgIf, PciData->SubClass, PciData->BaseClass);
+
+ { ULONG k, j;
+ k = 0;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ if (PciData->u.type0.BaseAddresses[j]) {
+ DbgPrint (" Ad%d:%08lx", j, PciData->u.type0.BaseAddresses[j]);
+ k = 1;
+ }
+ }
+ DbgPrint("\n");
+ }
+#endif // DBG
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != PCI_DEVICE_TYPE) {
+ PciData->VendorID = PCI_INVALID_VENDORID;
+ Len = 2; // only return invalid id
+
+ } else {
+
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, Slot, PciData);
+ }
+
+ //
+ // Has this PCI device been configured?
+ //
+
+#if DBG
+
+ //
+ // On DBG build, if this PCI device has not yet been configured,
+ // then don't report any current configuration the device may have.
+ //
+
+ bit = PciBitIndex(Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber);
+ if (!RtlCheckBit(&BusData->DeviceConfigured, bit)) {
+
+ for (i=0; i < PCI_TYPE0_ADDRESSES; i++) {
+ PciData->u.type0.BaseAddresses[i] = 0;
+ }
+
+ PciData->u.type0.ROMBaseAddress = 0;
+ PciData->Command &= ~(PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE);
+ }
+#endif
+
+
+ //
+ // Copy whatever data overlaps into the callers buffer
+ //
+
+ if (Len < Offset) {
+ // no data at caller's buffer
+ return 0;
+ }
+
+ Len -= Offset;
+ if (Len > Length) {
+ Len = Length;
+ }
+
+ RtlMoveMemory(Buffer, iBuffer + Offset, Len);
+
+ Offset += Len;
+ Buffer += Len;
+ Length -= Len;
+ }
+
+ if (Length) {
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The remaining Buffer comes from the Device Specific
+ // area - put on the kitten gloves and read from it.
+ //
+ // Specific read/writes to the PCI device specific area
+ // are guarenteed:
+ //
+ // Not to read/write any byte outside the area specified
+ // by the caller. (this may cause WORD or BYTE references
+ // to the area in order to read the non-dword aligned
+ // ends of the request)
+ //
+ // To use a WORD access if the requested length is exactly
+ // a WORD long.
+ //
+ // To use a BYTE access if the requested length is exactly
+ // a BYTE long.
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, Buffer, Offset, Length);
+ Len += Length;
+ }
+ }
+
+ return Len;
+}
+
+ULONG
+HalpSetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function returns the Pci bus data for a device.
+
+Arguments:
+
+
+ VendorSpecificDevice - The VendorID (low Word) and DeviceID (High Word)
+
+ Buffer - Supplies the space to store the data.
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+--*/
+{
+ PPCI_COMMON_CONFIG PciData, PciData2;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ UCHAR iBuffer2[PCI_COMMON_HDR_LENGTH];
+ PPCIPBUSDATA BusData;
+ ULONG Len, cnt;
+
+
+ if (Length > sizeof (PCI_COMMON_CONFIG)) {
+ Length = sizeof (PCI_COMMON_CONFIG);
+ }
+
+
+ Len = 0;
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+ PciData2 = (PPCI_COMMON_CONFIG) iBuffer2;
+
+
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The user did not request any data from the common
+ // header. Verify the PCI device exists, then continue in
+ // the device specific area.
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, sizeof(ULONG));
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID) {
+ return 0;
+ }
+
+ } else {
+
+ //
+ // Caller requested to set at least some data within the
+ // common header.
+ //
+
+ Len = PCI_COMMON_HDR_LENGTH;
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, Len);
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != PCI_DEVICE_TYPE) {
+
+ // no device, or header type unkown
+ return 0;
+ }
+
+
+ //
+ // Set this device as configured
+ //
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+#if DBG
+ cnt = PciBitIndex(Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber);
+ RtlSetBits (&BusData->DeviceConfigured, cnt, 1);
+#endif
+ //
+ // Copy COMMON_HDR values to buffer2, then overlay callers changes.
+ //
+
+ RtlMoveMemory (iBuffer2, iBuffer, Len);
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, Slot, PciData2);
+
+ Len -= Offset;
+ if (Len > Length) {
+ Len = Length;
+ }
+
+ RtlMoveMemory (iBuffer2+Offset, Buffer, Len);
+
+ // in case interrupt line or pin was editted
+ BusData->CommonData.Line2Pin (BusHandler, RootHandler, Slot, PciData2, PciData);
+
+#if DBG
+ //
+ // Verify R/O fields haven't changed
+ //
+ if (PciData2->VendorID != PciData->VendorID ||
+ PciData2->DeviceID != PciData->DeviceID ||
+ PciData2->RevisionID != PciData->RevisionID ||
+ PciData2->ProgIf != PciData->ProgIf ||
+ PciData2->SubClass != PciData->SubClass ||
+ PciData2->BaseClass != PciData->BaseClass ||
+ PciData2->HeaderType != PciData->HeaderType ||
+ PciData2->BaseClass != PciData->BaseClass ||
+ PciData2->u.type0.MinimumGrant != PciData->u.type0.MinimumGrant ||
+ PciData2->u.type0.MaximumLatency != PciData->u.type0.MaximumLatency) {
+ DbgPrint ("PCI SetBusData: Read-Only configuration value changed\n");
+ DbgBreakPoint ();
+ }
+#endif
+ //
+ // Set new PCI configuration
+ //
+
+#if DBG // H001
+ DbgPrint("SetPciData: PciData2->u.type0.InterruptLine:%x\n",PciData2->u.type0.InterruptLine);
+#endif
+ HalpWritePCIConfig (BusHandler, Slot, iBuffer2+Offset, Offset, Len);
+
+ Offset += Len;
+ Buffer += Len;
+ Length -= Len;
+ }
+
+ if (Length) {
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The remaining Buffer comes from the Device Specific
+ // area - put on the kitten gloves and write it
+ //
+ // Specific read/writes to the PCI device specific area
+ // are guarenteed:
+ //
+ // Not to read/write any byte outside the area specified
+ // by the caller. (this may cause WORD or BYTE references
+ // to the area in order to read the non-dword aligned
+ // ends of the request)
+ //
+ // To use a WORD access if the requested length is exactly
+ // a WORD long.
+ //
+ // To use a BYTE access if the requested length is exactly
+ // a BYTE long.
+ //
+
+ HalpWritePCIConfig (BusHandler, Slot, Buffer, Offset, Length);
+ Len += Length;
+ }
+ }
+
+ return Len;
+}
+
+VOID
+HalpReadPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ USHORT IdValue; // H001
+ ULONG OrigData; // H001
+
+ if (!HalpValidPCISlot (BusHandler, Slot)) {
+ //
+ // Invalid SlotID return no data
+ //
+ RtlFillMemory (Buffer, Length, (UCHAR) -1);
+
+ return ;
+ }
+
+#if defined(_R94A_) // H001
+
+ //
+ // resolve PCI master abort during we are looking for PCI device
+ // check to see if spcified slot is valid.
+ //
+
+ //
+ // Disable PCI-MasterAbort interrupt during configration read.
+ //
+
+ OrigData = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable);
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable, OrigData & 0xffffff7f);
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) &IdValue, 0, 2,
+ PCIConfigHandler.ConfigRead);
+
+ if (IdValue == 0xffff){
+
+ //
+ // This PCI slot has no card
+ // wait until ReceivedMasterAbort bit is set
+ //
+
+ while(!(READ_REGISTER_USHORT(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIStatus) & 0x2000))
+ ;
+
+ //
+ // clear the ReceivedMasterAbort bit
+ //
+
+ WRITE_REGISTER_USHORT(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIStatus, 0x2000);
+
+ //
+ // Clear memory address error registers.
+ //
+
+ {
+ LARGE_INTEGER registerLarge;
+ READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &registerLarge);
+ }
+
+ //
+ // Restore the PCIInterruptEnable register, and return no data
+ //
+
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable, OrigData);
+ RtlFillMemory (Buffer, Length, (UCHAR) -1);
+
+ return ;
+ }
+
+ //
+ // Restore the PCIInterruptEnable register.
+ //
+
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable, OrigData);
+
+#endif // _R94A_
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) Buffer, Offset, Length,
+ PCIConfigHandler.ConfigRead);
+}
+
+VOID
+HalpWritePCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ USHORT IdValue; // H001
+ ULONG OrigData; // H001
+
+ if (!HalpValidPCISlot (BusHandler, Slot)) {
+ //
+ // Invalid SlotID do nothing
+ //
+ return ;
+ }
+
+#if defined(_R94A_) // H001
+
+ //
+ // resolve PCI master abort during we are looking for PCI device
+ // check to see if spcified slot is valid.
+ //
+
+ //
+ // Disable PCI-MasterAbort interrupt during configration read.
+ //
+
+ OrigData = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable);
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable, OrigData & 0xffffff7f);
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) &IdValue, 0, 2,
+ PCIConfigHandler.ConfigRead);
+
+ if (IdValue == 0xffff){
+
+ //
+ // This PCI slot has no card
+ // wait until ReceivedMasterAbort bit is set
+ //
+
+ while(!(READ_REGISTER_USHORT(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIStatus) & 0x2000))
+ ;
+
+ //
+ // clear the ReceivedMasterAbort bit
+ //
+
+ WRITE_REGISTER_USHORT(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIStatus, 0x2000);
+
+ //
+ // Clear memory address error registers.
+ //
+
+ {
+ LARGE_INTEGER registerLarge;
+ READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &registerLarge);
+ }
+
+ //
+ // Restore the PCIInterruptEnable register, and return no data
+ //
+
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable, OrigData);
+ RtlFillMemory (Buffer, Length, (UCHAR) -1);
+
+ return ;
+ }
+
+ //
+ // Restore the PCIInterruptEnable register.
+ //
+
+ WRITE_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable, OrigData);
+
+#endif // _R94A_
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) Buffer, Offset, Length,
+ PCIConfigHandler.ConfigWrite);
+}
+
+BOOLEAN
+HalpValidPCISlot (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ )
+{
+ PCI_SLOT_NUMBER Slot2;
+ PPCIPBUSDATA BusData;
+ UCHAR HeaderType;
+ ULONG i;
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ if (Slot.u.bits.Reserved != 0) {
+ return FALSE;
+ }
+
+#if defined(_R94A_) // H001
+ if (Slot.u.bits.DeviceNumber < 3 ||
+ Slot.u.bits.DeviceNumber > 20) {
+ return FALSE;
+ }
+#else
+ if (Slot.u.bits.DeviceNumber >= BusData->MaxDevice) {
+ return FALSE;
+ }
+#endif // _R94A_
+
+ if (Slot.u.bits.FunctionNumber == 0) {
+ return TRUE;
+ }
+
+ //
+ // Non zero function numbers are only supported if the
+ // device has the PCI_MULTIFUNCTION bit set in it's header
+ //
+
+ i = Slot.u.bits.DeviceNumber;
+
+ //
+ // Read DeviceNumber, Function zero, to determine if the
+ // PCI supports multifunction devices
+ //
+
+ Slot2 = Slot;
+ Slot2.u.bits.FunctionNumber = 0;
+
+ HalpReadPCIConfig (
+ BusHandler,
+ Slot2,
+ &HeaderType,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, HeaderType),
+ sizeof (UCHAR)
+ );
+
+ if (!(HeaderType & PCI_MULTIFUNCTION) || HeaderType == 0xFF) {
+ // this device doesn't exists or doesn't support MULTIFUNCTION types
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+VOID
+HalpPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN FncConfigIO *ConfigIO
+ )
+{
+ KIRQL OldIrql;
+ ULONG i;
+ UCHAR State[20];
+ PPCIPBUSDATA BusData;
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ if (Slot.u.bits.DeviceNumber < 3) { // H001
+#if DBG
+ DbgPrint("HalpPCIConfig: Ignore Slot %x\n",Slot.u.bits.DeviceNumber);
+#endif
+ return;
+ }
+
+ PCIConfigHandler.Synchronize (BusHandler, Slot, &OldIrql, State);
+
+ while (Length) {
+ i = PCIDeref[Offset % sizeof(ULONG)][Length % sizeof(ULONG)];
+ i = ConfigIO[i] (BusData, State, Buffer, Offset);
+
+ Offset += i;
+ Buffer += i;
+ Length -= i;
+ }
+
+ PCIConfigHandler.ReleaseSynchronzation (BusHandler, OldIrql);
+}
+
+VOID HalpPCISynchronizeType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1
+ )
+{
+ //
+ // Initialize PciCfg1
+ //
+
+ PciCfg1->u.AsULONG = 0;
+ PciCfg1->u.bits.BusNumber = BusHandler->BusNumber;
+ PciCfg1->u.bits.DeviceNumber = Slot.u.bits.DeviceNumber;
+ PciCfg1->u.bits.FunctionNumber = Slot.u.bits.FunctionNumber;
+ PciCfg1->u.bits.Enable = TRUE;
+
+ //
+ // Synchronize with PCI type1 config space
+ //
+
+ if (!HalpDoingCrashDump) {
+ KeRaiseIrql (PROFILE_LEVEL, Irql); // H001
+ KiAcquireSpinLock (&HalpPCIConfigLock);
+ } else {
+ *Irql = HIGH_LEVEL;
+ }
+}
+
+VOID HalpPCIReleaseSynchronzationType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ )
+{
+ PCI_TYPE1_CFG_BITS PciCfg1;
+ PPCIPBUSDATA BusData;
+
+ //
+ // Disable PCI configuration space
+ //
+
+ PciCfg1.u.AsULONG = 0;
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1.u.AsULONG);
+
+ //
+ // Release spinlock
+ //
+
+ if (!HalpDoingCrashDump) {
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql); // H001
+ }
+}
+
+
+ULONG
+HalpPCIReadUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1->u.AsULONG);
+ *Buffer = READ_PORT_UCHAR ((PUCHAR) (BusData->Config.Type1.Data + i));
+ return sizeof (UCHAR);
+}
+
+ULONG
+HalpPCIReadUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1->u.AsULONG);
+ *((PUSHORT) Buffer) = READ_PORT_USHORT ((PUSHORT) (BusData->Config.Type1.Data + i));
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIReadUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1->u.AsULONG);
+ *((PULONG) Buffer) = READ_PORT_ULONG ((PULONG) BusData->Config.Type1.Data);
+ return sizeof (ULONG);
+}
+
+
+ULONG
+HalpPCIWriteUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1->u.AsULONG);
+ WRITE_PORT_UCHAR ((PUCHAR) (BusData->Config.Type1.Data + i), *Buffer);
+ return sizeof (UCHAR);
+}
+
+ULONG
+HalpPCIWriteUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1->u.AsULONG);
+ WRITE_PORT_USHORT ((PUSHORT) (BusData->Config.Type1.Data + i), *((PUSHORT) Buffer));
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIWriteUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1->u.AsULONG);
+ WRITE_PORT_ULONG ((PULONG) BusData->Config.Type1.Data, *((PULONG) Buffer));
+ return sizeof (ULONG);
+}
+
+
+VOID HalpPCISynchronizeType2 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PPCI_TYPE2_ADDRESS_BITS PciCfg2Addr
+ )
+{
+ PCI_TYPE2_CSE_BITS PciCfg2Cse;
+ PPCIPBUSDATA BusData;
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ //
+ // Initialize Cfg2Addr
+ //
+
+ PciCfg2Addr->u.AsUSHORT = 0;
+ PciCfg2Addr->u.bits.Agent = (USHORT) Slot.u.bits.DeviceNumber;
+ PciCfg2Addr->u.bits.AddressBase = (USHORT) BusData->Config.Type2.Base;
+
+ //
+ // Synchronize with type2 config space - type2 config space
+ // remaps 4K of IO space, so we can not allow other I/Os to occur
+ // while using type2 config space.
+ //
+
+ HalpPCIAcquireType2Lock (&HalpPCIConfigLock, Irql);
+
+ PciCfg2Cse.u.AsUCHAR = 0;
+ PciCfg2Cse.u.bits.Enable = TRUE;
+ PciCfg2Cse.u.bits.FunctionNumber = (UCHAR) Slot.u.bits.FunctionNumber;
+ PciCfg2Cse.u.bits.Key = 0xff;
+
+ //
+ // Select bus & enable type 2 configuration space
+ //
+
+ WRITE_PORT_UCHAR (BusData->Config.Type2.Forward, (UCHAR) BusHandler->BusNumber);
+ WRITE_PORT_UCHAR (BusData->Config.Type2.CSE, PciCfg2Cse.u.AsUCHAR);
+}
+
+
+VOID HalpPCIReleaseSynchronzationType2 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ )
+{
+ PCI_TYPE2_CSE_BITS PciCfg2Cse;
+ PPCIPBUSDATA BusData;
+
+ //
+ // disable PCI configuration space
+ //
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ PciCfg2Cse.u.AsUCHAR = 0;
+ WRITE_PORT_UCHAR (BusData->Config.Type2.CSE, PciCfg2Cse.u.AsUCHAR);
+ WRITE_PORT_UCHAR (BusData->Config.Type2.Forward, (UCHAR) 0);
+
+ //
+ // Restore interrupts, release spinlock
+ //
+
+ HalpPCIReleaseType2Lock (&HalpPCIConfigLock, Irql);
+}
+
+
+ULONG
+HalpPCIReadUcharType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE2_ADDRESS_BITS PciCfg2Addr,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg2Addr->u.bits.RegisterNumber = (USHORT) Offset;
+ *Buffer = READ_PORT_UCHAR ((PUCHAR) PciCfg2Addr->u.AsUSHORT);
+ return sizeof (UCHAR);
+}
+
+ULONG
+HalpPCIReadUshortType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE2_ADDRESS_BITS PciCfg2Addr,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg2Addr->u.bits.RegisterNumber = (USHORT) Offset;
+ *((PUSHORT) Buffer) = READ_PORT_USHORT ((PUSHORT) PciCfg2Addr->u.AsUSHORT);
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIReadUlongType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE2_ADDRESS_BITS PciCfg2Addr,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg2Addr->u.bits.RegisterNumber = (USHORT) Offset;
+ *((PULONG) Buffer) = READ_PORT_ULONG ((PULONG) PciCfg2Addr->u.AsUSHORT);
+ return sizeof(ULONG);
+}
+
+
+ULONG
+HalpPCIWriteUcharType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE2_ADDRESS_BITS PciCfg2Addr,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg2Addr->u.bits.RegisterNumber = (USHORT) Offset;
+ WRITE_PORT_UCHAR ((PUCHAR) PciCfg2Addr->u.AsUSHORT, *Buffer);
+ return sizeof (UCHAR);
+}
+
+ULONG
+HalpPCIWriteUshortType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE2_ADDRESS_BITS PciCfg2Addr,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg2Addr->u.bits.RegisterNumber = (USHORT) Offset;
+ WRITE_PORT_USHORT ((PUSHORT) PciCfg2Addr->u.AsUSHORT, *((PUSHORT) Buffer));
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIWriteUlongType2 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE2_ADDRESS_BITS PciCfg2Addr,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ PciCfg2Addr->u.bits.RegisterNumber = (USHORT) Offset;
+ WRITE_PORT_ULONG ((PULONG) PciCfg2Addr->u.AsUSHORT, *((PULONG) Buffer));
+ return sizeof(ULONG);
+}
+
+
+NTSTATUS
+HalpAssignPCISlotResources (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName OPTIONAL,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ IN ULONG Slot,
+ IN OUT PCM_RESOURCE_LIST *pAllocatedResources
+ )
+/*++
+
+Routine Description:
+
+ Reads the targeted device to determine it's required resources.
+ Calls IoAssignResources to allocate them.
+ Sets the targeted device with it's assigned resoruces
+ and returns the assignments to the caller.
+
+Arguments:
+
+Return Value:
+
+ STATUS_SUCCESS or error
+
+--*/
+{
+ NTSTATUS status;
+ PUCHAR WorkingPool;
+ PPCI_COMMON_CONFIG PciData, PciOrigData, PciData2;
+ PCI_COMMON_CONFIG PciData3; // H005
+ PCI_SLOT_NUMBER PciSlot;
+ PPCIPBUSDATA BusData;
+ PIO_RESOURCE_REQUIREMENTS_LIST CompleteList;
+ PIO_RESOURCE_DESCRIPTOR Descriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor;
+ ULONG BusNumber;
+ ULONG i, j, m, length, memtype;
+ ULONG NoBaseAddress, RomIndex, Option;
+ PULONG BaseAddress[PCI_TYPE0_ADDRESSES + 1];
+ PULONG OrigAddress[PCI_TYPE0_ADDRESSES + 1];
+ BOOLEAN Match, EnableRomBase;
+
+
+ *pAllocatedResources = NULL;
+ PciSlot = *((PPCI_SLOT_NUMBER) &Slot);
+ BusNumber = BusHandler->BusNumber;
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ //
+ // Allocate some pool for working space
+ //
+
+ i = sizeof (IO_RESOURCE_REQUIREMENTS_LIST) +
+ sizeof (IO_RESOURCE_DESCRIPTOR) * (PCI_TYPE0_ADDRESSES + 2) * 2 +
+ PCI_COMMON_HDR_LENGTH * 3;
+
+ WorkingPool = (PUCHAR) ExAllocatePool (PagedPool, i);
+ if (!WorkingPool) {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // Zero initialize pool, and get pointers into memory
+ //
+
+ RtlZeroMemory (WorkingPool, i);
+ CompleteList = (PIO_RESOURCE_REQUIREMENTS_LIST) WorkingPool;
+ PciData = (PPCI_COMMON_CONFIG) (WorkingPool + i - PCI_COMMON_HDR_LENGTH * 3);
+ PciData2 = (PPCI_COMMON_CONFIG) (WorkingPool + i - PCI_COMMON_HDR_LENGTH * 2);
+ PciOrigData = (PPCI_COMMON_CONFIG) (WorkingPool + i - PCI_COMMON_HDR_LENGTH * 1);
+
+ //
+ // Read the PCI device's configuration
+ //
+
+ HalpReadPCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+ if (PciData->VendorID == PCI_INVALID_VENDORID) {
+ ExFreePool (WorkingPool);
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+ //
+ // Make a copy of the device's current settings
+ //
+
+ RtlMoveMemory (PciOrigData, PciData, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Initialize base addresses base on configuration data type
+ //
+
+ switch (PCI_CONFIG_TYPE(PciData)) {
+ case 0 :
+ NoBaseAddress = PCI_TYPE0_ADDRESSES+1;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ BaseAddress[j] = &PciData->u.type0.BaseAddresses[j];
+ OrigAddress[j] = &PciOrigData->u.type0.BaseAddresses[j];
+ }
+ BaseAddress[j] = &PciData->u.type0.ROMBaseAddress;
+ OrigAddress[j] = &PciOrigData->u.type0.ROMBaseAddress;
+ RomIndex = j;
+ break;
+ case 1:
+ NoBaseAddress = PCI_TYPE1_ADDRESSES+1;
+ for (j=0; j < PCI_TYPE1_ADDRESSES; j++) {
+ BaseAddress[j] = &PciData->u.type1.BaseAddresses[j];
+ OrigAddress[j] = &PciOrigData->u.type1.BaseAddresses[j];
+ }
+ BaseAddress[j] = &PciData->u.type1.ROMBaseAddress;
+ OrigAddress[j] = &PciOrigData->u.type1.ROMBaseAddress;
+ RomIndex = j;
+ break;
+
+ default:
+ ExFreePool (WorkingPool);
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+ //
+ // If the BIOS doesn't have the device's ROM enabled, then we won't
+ // enable it either. Remove it from the list.
+ //
+
+ EnableRomBase = TRUE;
+
+#if 0 // H001
+ if (!(*BaseAddress[RomIndex] & PCI_ROMADDRESS_ENABLED)) {
+ ASSERT (RomIndex+1 == NoBaseAddress);
+ EnableRomBase = FALSE;
+ NoBaseAddress -= 1;
+ }
+#endif
+
+ //
+ // Set resources to all bits on to see what type of resources
+ // are required.
+ //
+
+ for (j=0; j < NoBaseAddress; j++) {
+ *BaseAddress[j] = 0xFFFFFFFF;
+ }
+
+ PciData->Command &= ~(PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE);
+ *BaseAddress[RomIndex] &= ~PCI_ROMADDRESS_ENABLED;
+ HalpWritePCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+ HalpReadPCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // H004
+ // Make a copy of the device's current settings
+ //
+
+ RtlMoveMemory ((PPCI_COMMON_CONFIG)&PciData3, PciData, PCI_COMMON_HDR_LENGTH);
+
+ // note type0 & type1 overlay ROMBaseAddress, InterruptPin, and InterruptLine
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, PciSlot, PciData);
+
+ //
+ // Build an IO_RESOURCE_REQUIREMENTS_LIST for the PCI device
+ //
+
+ CompleteList->InterfaceType = PCIBus;
+ CompleteList->BusNumber = BusNumber;
+ CompleteList->SlotNumber = Slot;
+ CompleteList->AlternativeLists = 1;
+
+ CompleteList->List[0].Version = 1;
+ CompleteList->List[0].Revision = 1;
+
+ Descriptor = CompleteList->List[0].Descriptors;
+
+ //
+ // If PCI device has an interrupt resource, add it
+ //
+
+ if (PciData->u.type0.InterruptPin) {
+ CompleteList->List[0].Count++;
+
+ Descriptor->Option = 0;
+ Descriptor->Type = CmResourceTypeInterrupt;
+ Descriptor->ShareDisposition = CmResourceShareShared;
+ Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+
+ // Fill in any vector here - we'll pick it back up in
+ // HalAdjustResourceList and adjust it to it's allowed settings
+ Descriptor->u.Interrupt.MinimumVector = 0;
+ Descriptor->u.Interrupt.MaximumVector = 0xff;
+ Descriptor++;
+ }
+
+ //
+ // Add a memory/port resoruce for each PCI resource
+ //
+
+ // Clear ROM reserved bits
+
+ *BaseAddress[RomIndex] &= ~0x7FF;
+
+ for (j=0; j < NoBaseAddress; j++) {
+ if (*BaseAddress[j]) {
+ i = *BaseAddress[j];
+
+ // scan for first set bit, that's the length & alignment
+ length = 1 << (i & PCI_ADDRESS_IO_SPACE ? 2 : 4);
+ while (!(i & length) && length) {
+ length <<= 1;
+ }
+
+ // scan for last set bit, that's the maxaddress + 1
+ for (m = length; i & m; m <<= 1) ;
+ m--;
+
+ // check for hosed PCI configuration requirements
+ if (length & ~m) {
+#if DBG
+ DbgPrint ("PCI: defective device! Bus %d, Slot %d, Function %d\n",
+ BusNumber,
+ PciSlot.u.bits.DeviceNumber,
+ PciSlot.u.bits.FunctionNumber
+ );
+
+ DbgPrint ("PCI: BaseAddress[%d] = %08lx\n", j, i);
+#endif
+ // the device is in error - punt. don't allow this
+ // resource any option - it either gets set to whatever
+ // bits it was able to return, or it doesn't get set.
+
+ if (i & PCI_ADDRESS_IO_SPACE) {
+ m = i & ~0x3;
+ Descriptor->u.Port.MinimumAddress.LowPart = m;
+ } else {
+ m = i & ~0xf;
+ Descriptor->u.Memory.MinimumAddress.LowPart = m;
+ }
+
+ m += length; // max address is min address + length
+ }
+
+ //
+ // Add requested resource
+ //
+
+ Descriptor->Option = 0;
+ if (i & PCI_ADDRESS_IO_SPACE) {
+ memtype = 0;
+
+#if 0 // H002
+ if (!Is64BitBaseAddress(i) &&
+ PciOrigData->Command & PCI_ENABLE_IO_SPACE) {
+
+ //
+ // The IO range is/was already enabled at some location, add that
+ // as it's preferred setting.
+ //
+
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO;
+ Descriptor->Option = IO_RESOURCE_PREFERRED;
+
+ Descriptor->u.Port.Length = length;
+ Descriptor->u.Port.Alignment = length;
+ Descriptor->u.Port.MinimumAddress.LowPart = *OrigAddress[j] & ~0x3;
+ Descriptor->u.Port.MaximumAddress.LowPart =
+ Descriptor->u.Port.MinimumAddress.LowPart + length - 1;
+
+ CompleteList->List[0].Count++;
+ Descriptor++;
+
+ Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
+ }
+#endif
+ //
+ // Add this IO range
+ //
+
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO;
+
+ Descriptor->u.Port.Length = length;
+ Descriptor->u.Port.Alignment = length;
+ Descriptor->u.Port.MaximumAddress.LowPart = m;
+
+#if DBG // H001
+ DbgPrint("HalpAssign: Port %x len %x align %x\n", length, length, m);
+#endif // DBG
+
+ } else {
+
+ memtype = i & PCI_ADDRESS_MEMORY_TYPE_MASK;
+
+ Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+ if (j == RomIndex) {
+ // this is a ROM address
+ Descriptor->Flags = CM_RESOURCE_MEMORY_READ_ONLY;
+ }
+
+ if (i & PCI_ADDRESS_MEMORY_PREFETCHABLE) {
+ Descriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE;
+ }
+
+#if 0 // H002
+ if (!Is64BitBaseAddress(i) &&
+ (j == RomIndex ||
+ PciOrigData->Command & PCI_ENABLE_MEMORY_SPACE)) {
+
+ //
+ // The memory range is/was already enabled at some location, add that
+ // as it's preferred setting.
+ //
+
+ Descriptor->Type = CmResourceTypeMemory;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Option = IO_RESOURCE_PREFERRED;
+
+ Descriptor->u.Port.Length = length;
+ Descriptor->u.Port.Alignment = length;
+ Descriptor->u.Port.MinimumAddress.LowPart = *OrigAddress[j] & ~0xF;
+ Descriptor->u.Port.MaximumAddress.LowPart =
+ Descriptor->u.Port.MinimumAddress.LowPart + length - 1;
+
+ CompleteList->List[0].Count++;
+ Descriptor++;
+
+ Descriptor->Flags = Descriptor[-1].Flags;
+ Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
+ }
+#endif
+ //
+ // Add this memory range
+ //
+
+ Descriptor->Type = CmResourceTypeMemory;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+
+ Descriptor->u.Memory.Length = length;
+ Descriptor->u.Memory.Alignment = length;
+ Descriptor->u.Memory.MaximumAddress.LowPart = m;
+
+ if (memtype == PCI_TYPE_20BIT && m > 0xFFFFF) {
+ // limit to 20 bit address
+ Descriptor->u.Memory.MaximumAddress.LowPart = 0xFFFFF;
+ }
+
+#if DBG // H001
+ DbgPrint("HalpAssign: Memory %x len %x align %x\n", length, length, m);
+#endif // DBG
+
+ }
+
+ CompleteList->List[0].Count++;
+ Descriptor++;
+
+
+ if (Is64BitBaseAddress(i)) {
+ // skip upper half of 64 bit address since this processor
+ // only supports 32 bits of address space
+ j++;
+ }
+ }
+ }
+
+ CompleteList->ListSize = (ULONG)
+ ((PUCHAR) Descriptor - (PUCHAR) CompleteList);
+
+ //
+ // Restore the device settings as we found them, enable memory
+ // and io decode after setting base addresses. This is done in
+ // case HalAdjustResourceList wants to read the current settings
+ // in the device.
+ //
+
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ &PciOrigData->Status,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Status),
+ PCI_COMMON_HDR_LENGTH - FIELD_OFFSET (PCI_COMMON_CONFIG, Status)
+ );
+
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ PciOrigData,
+ 0,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Status)
+ );
+
+ //
+ // Have the IO system allocate resource assignments
+ //
+
+#if DBG // H001
+ DbgPrint("Call IoAssignResources\n");
+#endif // DBG
+
+ status = IoAssignResources (
+ RegistryPath,
+ DriverClassName,
+ DriverObject,
+ DeviceObject,
+ CompleteList,
+ pAllocatedResources
+ );
+
+ if (!NT_SUCCESS(status)) {
+ goto CleanUp;
+ }
+
+ //
+ // Slurp the assigments back into the PciData structure and
+ // perform them
+ //
+
+ CmDescriptor = (*pAllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
+
+ //
+ // If PCI device has an interrupt resource then that was
+ // passed in as the first requested resource
+ //
+
+ if (PciData->u.type0.InterruptPin) {
+ PciData->u.type0.InterruptLine = (UCHAR) CmDescriptor->u.Interrupt.Vector;
+ BusData->CommonData.Line2Pin (BusHandler, RootHandler, PciSlot, PciData, PciOrigData);
+ CmDescriptor++;
+ }
+
+ //
+ // Pull out resources in the order they were passed to IoAssignResources
+ //
+
+ for (j=0; j < NoBaseAddress; j++) {
+ i = *BaseAddress[j];
+ if (i) {
+ if (i & PCI_ADDRESS_IO_SPACE) {
+ *BaseAddress[j] = CmDescriptor->u.Port.Start.LowPart;
+#if DBG // H001
+ DbgPrint("HalpAssign assigned: Port %x\n", *BaseAddress[j]);
+#endif // DBG
+ } else {
+ *BaseAddress[j] = CmDescriptor->u.Memory.Start.LowPart;
+#if DBG // H001
+ DbgPrint("HalpAssign assigned: Memory %x\n", *BaseAddress[j]);
+#endif // DBG
+ }
+ CmDescriptor++;
+ }
+
+ if (Is64BitBaseAddress(i)) {
+ // skip upper 32 bits
+ j++;
+ }
+ }
+
+ //
+ // Turn off decodes, then set new addresses
+ //
+
+#if DBG // H001
+ DbgPrint("Set Assigned Resources\n");
+#endif // DBG
+
+ HalpWritePCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Read configuration back and verify address settings took
+ //
+
+#if DBG // H001
+ DbgPrint("Read Common header to see write results\n");
+#endif // DBG
+
+ HalpReadPCIConfig(BusHandler, PciSlot, PciData2, 0, PCI_COMMON_HDR_LENGTH);
+
+ Match = TRUE;
+ if (PciData->u.type0.InterruptLine != PciData2->u.type0.InterruptLine ||
+ PciData->u.type0.InterruptPin != PciData2->u.type0.InterruptPin ||
+ PciData->u.type0.ROMBaseAddress != PciData2->u.type0.ROMBaseAddress) {
+ Match = FALSE;
+ }
+
+ for (j=0; j < NoBaseAddress; j++) {
+ if (*BaseAddress[j]) {
+ if (*BaseAddress[j] & PCI_ADDRESS_IO_SPACE) {
+ i = (ULONG) ~0x3;
+ } else {
+ i = (ULONG) ~0xF;
+ }
+
+ if ((*BaseAddress[j] & i) !=
+ *((PULONG) ((PUCHAR) BaseAddress[j] -
+ (PUCHAR) PciData +
+ (PUCHAR) PciData2)) & i) {
+
+ Match = FALSE;
+ }
+
+ if (Is64BitBaseAddress(*BaseAddress[j])) {
+ // skip upper 32 bits
+ j++;
+ }
+ }
+ }
+
+ if (!Match) {
+#if DBG
+ DbgPrint ("PCI: defective device! Bus %d, Slot %d, Function %d\n",
+ BusNumber,
+ PciSlot.u.bits.DeviceNumber,
+ PciSlot.u.bits.FunctionNumber
+ );
+#endif
+ status = STATUS_DEVICE_PROTOCOL_ERROR;
+ goto CleanUp;
+ }
+
+ //
+ // H004
+ // set memory space as back-to-back available
+ //
+
+ HalpSetBackToBackSpace(&PciData3, PciData2, BusHandler);
+
+ //
+ // Settings took - turn on the appropiate decodes
+ //
+
+ if (EnableRomBase && *BaseAddress[RomIndex]) {
+ // a rom address was allocated and should be enabled
+ *BaseAddress[RomIndex] |= PCI_ROMADDRESS_ENABLED;
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ BaseAddress[RomIndex],
+ (ULONG) ((PUCHAR) BaseAddress[RomIndex] - (PUCHAR) PciData),
+ sizeof (ULONG)
+ );
+ }
+
+ //
+ // Enable IO, Memory, and BUS_MASTER decodes
+ // (use HalSetBusData since valid settings now set)
+ //
+
+ PciData->Command |= PCI_ENABLE_IO_SPACE |
+ PCI_ENABLE_MEMORY_SPACE |
+ PCI_ENABLE_BUS_MASTER;
+
+ HalSetBusDataByOffset (
+ PCIConfiguration,
+ BusHandler->BusNumber,
+ PciSlot.u.AsULONG,
+ &PciData->Command,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Command),
+ sizeof (PciData->Command)
+ );
+
+CleanUp:
+ if (!NT_SUCCESS(status)) {
+
+ //
+ // Failure, if there are any allocated resources free them
+ //
+
+ if (*pAllocatedResources) {
+ IoAssignResources (
+ RegistryPath,
+ DriverClassName,
+ DriverObject,
+ DeviceObject,
+ NULL,
+ NULL
+ );
+
+ ExFreePool (*pAllocatedResources);
+ *pAllocatedResources = NULL;
+ }
+
+ //
+ // Restore the device settings as we found them, enable memory
+ // and io decode after setting base addresses
+ //
+
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ &PciOrigData->Status,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Status),
+ PCI_COMMON_HDR_LENGTH - FIELD_OFFSET (PCI_COMMON_CONFIG, Status)
+ );
+
+ HalpWritePCIConfig (
+ BusHandler,
+ PciSlot,
+ PciOrigData,
+ 0,
+ FIELD_OFFSET (PCI_COMMON_CONFIG, Status)
+ );
+ }
+
+ ExFreePool (WorkingPool);
+ return status;
+}
+
+#if DBG
+VOID
+HalpTestPci (ULONG flag2)
+{
+ PCI_SLOT_NUMBER SlotNumber;
+ PCI_COMMON_CONFIG PciData, OrigData;
+ ULONG i, f, j, k, bus;
+ BOOLEAN flag;
+
+
+ if (!flag2) {
+ return ;
+ }
+
+ DbgBreakPoint ();
+ SlotNumber.u.bits.Reserved = 0;
+
+ //
+ // Read every possible PCI Device/Function and display it's
+ // default info.
+ //
+ // (note this destories it's current settings)
+ //
+
+ flag = TRUE;
+ for (bus = 0; flag; bus++) {
+
+ for (i = 0; i < PCI_MAX_DEVICES; i++) {
+ SlotNumber.u.bits.DeviceNumber = i;
+
+ for (f = 0; f < PCI_MAX_FUNCTION; f++) {
+ SlotNumber.u.bits.FunctionNumber = f;
+
+ //
+ // Note: This is reading the DeviceSpecific area of
+ // the device's configuration - normally this should
+ // only be done on device for which the caller understands.
+ // I'm doing it here only for debugging.
+ //
+
+ j = HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ if (j == 0) {
+ // out of buses
+ flag = FALSE;
+ break;
+ }
+
+ if (j < PCI_COMMON_HDR_LENGTH) {
+ continue;
+ }
+
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ 1
+ );
+
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+#if 0
+ memcpy (&OrigData, &PciData, sizeof PciData);
+
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ PciData.u.type0.BaseAddresses[j] = 0xFFFFFFFF;
+ }
+
+ PciData.u.type0.ROMBaseAddress = 0xFFFFFFFF;
+
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+#endif
+
+ DbgPrint ("PCI Bus %d Slot %2d %2d ID:%04lx-%04lx Rev:%04lx",
+ bus, i, f, PciData.VendorID, PciData.DeviceID,
+ PciData.RevisionID);
+
+
+ if (PciData.u.type0.InterruptPin) {
+ DbgPrint (" IntPin:%x", PciData.u.type0.InterruptPin);
+ }
+
+ if (PciData.u.type0.InterruptLine) {
+ DbgPrint (" IntLine:%x", PciData.u.type0.InterruptLine);
+ }
+
+ if (PciData.u.type0.ROMBaseAddress) {
+ DbgPrint (" ROM:%08lx", PciData.u.type0.ROMBaseAddress);
+ }
+
+ DbgPrint ("\n Cmd:%04x Status:%04x ProgIf:%04x SubClass:%04x BaseClass:%04lx\n",
+ PciData.Command, PciData.Status, PciData.ProgIf,
+ PciData.SubClass, PciData.BaseClass);
+
+ k = 0;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ if (PciData.u.type0.BaseAddresses[j]) {
+ DbgPrint (" Ad%d:%08lx", j, PciData.u.type0.BaseAddresses[j]);
+ k = 1;
+ }
+ }
+
+#if 0
+ if (PciData.u.type0.ROMBaseAddress == 0xC08001) {
+
+ PciData.u.type0.ROMBaseAddress = 0xC00001;
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ DbgPrint ("\n Bogus rom address, edit yields:%08lx",
+ PciData.u.type0.ROMBaseAddress);
+ }
+#endif
+
+ if (k) {
+ DbgPrint ("\n");
+ }
+
+ if (PciData.VendorID == 0x8086) {
+ // dump complete buffer
+ DbgPrint ("Command %x, Status %x, BIST %x\n",
+ PciData.Command, PciData.Status,
+ PciData.BIST
+ );
+
+ DbgPrint ("CacheLineSz %x, LatencyTimer %x",
+ PciData.CacheLineSize, PciData.LatencyTimer
+ );
+
+ for (j=0; j < 192; j++) {
+ if ((j & 0xf) == 0) {
+ DbgPrint ("\n%02x: ", j + 0x40);
+ }
+ DbgPrint ("%02x ", PciData.DeviceSpecific[j]);
+ }
+ DbgPrint ("\n");
+ }
+
+
+#if 0
+ //
+ // now print original data
+ //
+
+ if (OrigData.u.type0.ROMBaseAddress) {
+ DbgPrint (" oROM:%08lx", OrigData.u.type0.ROMBaseAddress);
+ }
+
+ DbgPrint ("\n");
+ k = 0;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ if (OrigData.u.type0.BaseAddresses[j]) {
+ DbgPrint (" oAd%d:%08lx", j, OrigData.u.type0.BaseAddresses[j]);
+ k = 1;
+ }
+ }
+
+ //
+ // Restore original settings
+ //
+
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &OrigData,
+ sizeof (PciData)
+ );
+#endif
+
+ //
+ // Next
+ //
+
+ if (k) {
+ DbgPrint ("\n\n");
+ }
+ }
+ }
+ }
+ DbgBreakPoint ();
+}
+
+#if defined (_R94A_) // H001
+VOID
+HalpTestPciNec (ULONG flag2)
+{
+ PCI_SLOT_NUMBER SlotNumber;
+ PCI_COMMON_CONFIG PciData, OrigData;
+ ULONG i, f, j, k, bus;
+ BOOLEAN flag;
+
+
+ if (!flag2) {
+ return ;
+ }
+
+ DbgBreakPoint ();
+ SlotNumber.u.bits.Reserved = 0;
+
+ //
+ // Read every possible PCI Device/Function and display it's
+ // default info.
+ //
+ // (note this destories it's current settings)
+ //
+
+ flag = TRUE;
+ for (bus = 0; flag && bus < 1; bus++) { /* R94A_ Support Only 1 */
+
+ for (i = 0; i < PCI_MAX_DEVICES; i++) { /* R94A_ Support Only 2 slots(include bridge) */
+ SlotNumber.u.bits.DeviceNumber = i;
+
+ for (f = 0; f < 8; f++) {
+ SlotNumber.u.bits.FunctionNumber = f;
+ DbgPrint("===== GetBusData slot(%d) func(%d)\n", i, f);
+ j = HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+ HalpTestPciPrintResult((PULONG)&PciData, j);
+ if (j == 0) {
+ // out of buses
+ flag = FALSE;
+ break;
+ }
+
+ if (j < PCI_COMMON_HDR_LENGTH) {
+ continue;
+ }
+ DbgPrint("===== SetBusData slot(%d) func(%d)\n", i, f);
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ 1
+ );
+ HalpTestPciPrintResult((PULONG)&PciData, 1);
+ DbgPrint("===== GetBusData slot(%d) func(%d)\n", i, f);
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+ HalpTestPciPrintResult((PULONG)&PciData, sizeof (PciData));
+ memcpy (&OrigData, &PciData, sizeof PciData);
+
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ PciData.u.type0.BaseAddresses[j] = 0xFFFFFFFF;
+ }
+
+ PciData.u.type0.ROMBaseAddress = 0xFFFFFFFF;
+ PciData.u.type0.InterruptLine = 5; // For trial
+ DbgPrint("===== (Change Contents (SetBusData) slot(%d) func(%d)\n", i, f);
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ PCI_COMMON_HDR_LENGTH // To avoid alias problem(HDR <--> DevSpecific)
+ );
+ HalpTestPciPrintResult((PULONG)&PciData, PCI_COMMON_HDR_LENGTH);
+ DbgPrint("===== GetBusData slot(%d) func(%d)\n", i, f);
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+ HalpTestPciPrintResult((PULONG)&PciData, sizeof (PciData));
+
+ DbgPrint ("--------------->>> Now Print the Slot Information\n");
+ DbgPrint ("PCI Bus %d Slot %2d %2d ID:%04lx-%04lx Rev:%04lx",
+ bus, i, f, PciData.VendorID, PciData.DeviceID,
+ PciData.RevisionID);
+
+
+ if (PciData.u.type0.InterruptPin) {
+ DbgPrint (" IntPin:%x", PciData.u.type0.InterruptPin);
+ }
+
+ if (PciData.u.type0.InterruptLine) {
+ DbgPrint (" IntLine:%x", PciData.u.type0.InterruptLine);
+ }
+
+ if (PciData.u.type0.ROMBaseAddress) {
+ DbgPrint (" ROM:%08lx", PciData.u.type0.ROMBaseAddress);
+ }
+
+ DbgPrint ("\n ProgIf:%04x SubClass:%04x BaseClass:%04lx\n",
+ PciData.ProgIf, PciData.SubClass, PciData.BaseClass);
+
+ k = 0;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ if (PciData.u.type0.BaseAddresses[j]) {
+ DbgPrint (" Ad%d:%08lx", j, PciData.u.type0.BaseAddresses[j]);
+ k = 1;
+ }
+ }
+
+ if (PciData.u.type0.ROMBaseAddress == 0xC08001) {
+
+ PciData.u.type0.ROMBaseAddress = 0xC00001;
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ DbgPrint ("\n Bogus rom address, edit yields:%08lx",
+ PciData.u.type0.ROMBaseAddress);
+ }
+
+ if (k) {
+ DbgPrint ("\n");
+ }
+
+ if (PciData.VendorID == 0x8086) {
+ // dump complete buffer
+ DbgPrint ("We got the bridge\n");
+ DbgPrint ("Command %x, Status %x, BIST %x\n",
+ PciData.Command, PciData.Status,
+ PciData.BIST
+ );
+
+ DbgPrint ("CacheLineSz %x, LatencyTimer %x",
+ PciData.CacheLineSize, PciData.LatencyTimer
+ );
+
+ for (j=0; j < 192; j++) {
+ if ((j & 0xf) == 0) {
+ DbgPrint ("\n%02x: ", j + 0x40);
+ }
+ DbgPrint ("%02x ", PciData.DeviceSpecific[j]);
+ }
+ DbgPrint ("\n");
+ }
+
+
+ //
+ // now print original data
+ //
+ DbgPrint ("--------------->>> Now Print the Original Slot Information\n");
+ if (OrigData.u.type0.ROMBaseAddress) {
+ DbgPrint (" oROM:%08lx", OrigData.u.type0.ROMBaseAddress);
+ }
+
+ DbgPrint ("\n");
+ k = 0;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ if (OrigData.u.type0.BaseAddresses[j]) {
+ DbgPrint (" oAd%d:%08lx", j, OrigData.u.type0.BaseAddresses[j]);
+ k = 1;
+ }
+ }
+
+ //
+ // Restore original settings
+ //
+ DbgPrint("===== Restore (GetBusData) slot(%d) func(%d)\n", i, f);
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &OrigData,
+ sizeof (PciData)
+ );
+ HalpTestPciPrintResult((PULONG)&OrigData, sizeof (PciData));
+ //
+ // Next
+ //
+
+ if (k) {
+ DbgPrint ("\n\n");
+ }
+ }
+ }
+ }
+ DbgBreakPoint ();
+}
+
+
+VOID
+HalpTestPciPrintResult(
+ IN PULONG Buffer,
+ IN ULONG Length
+)
+{
+ ULONG i, Lines, pchar;
+
+ DbgPrint("----- I/O Data. (%d)byts.\n", Length);
+
+ for (Lines = 0, pchar = 0; Lines < ((Length + 15)/ 16) && pchar < Length; Lines++) {
+ DbgPrint("%08x: ", Lines * 16);
+ for (i = 0; i < 4; pchar += 4, i++) {
+ if (pchar >= Length)
+ break;
+ DbgPrint("%08x ", *Buffer++);
+ }
+ DbgPrint("\n");
+ }
+}
+
+VOID
+HalpOtherTestNec (
+ IN ULONG doOtherTest
+)
+{
+ if (!doOtherTest)
+ return;
+
+
+ DbgPrint("\n\n===== Additional Testing...\n");
+ {
+ CM_EISA_SLOT_INFORMATION EisaSlotInfo;
+ PCM_EISA_SLOT_INFORMATION EisaBuffer;
+ PCM_EISA_FUNCTION_INFORMATION EisaFunctionInfo;
+ ULONG slot, funcs, Length;
+
+ #define MAX_EISA_SLOT 4
+
+ DbgPrint("----- Read Eisa Configration:\n");
+ for (slot = 0; slot < MAX_EISA_SLOT; slot++) {
+ Length = HalGetBusData (EisaConfiguration,0,slot,&EisaSlotInfo,sizeof (EisaSlotInfo));
+ if (Length < sizeof(CM_EISA_SLOT_INFORMATION)) {
+
+ //
+ // The data is messed up since this should never occur
+ //
+
+ break;
+ }
+ Length = sizeof(CM_EISA_SLOT_INFORMATION) +
+ (sizeof(CM_EISA_FUNCTION_INFORMATION) * EisaSlotInfo.NumberFunctions);
+ EisaBuffer = ExAllocatePool(NonPagedPool, Length);
+ HalGetBusData (EisaConfiguration,0,slot,&EisaBuffer,Length);
+ // Print all Eisa Data
+
+ EisaFunctionInfo = (PCM_EISA_FUNCTION_INFORMATION)
+ ((char *)&EisaBuffer + sizeof(CM_EISA_SLOT_INFORMATION));
+
+ DbgPrint("----- HalGetBusData Eisa Slot No=%d\n", slot);
+ DbgPrint("ReturnCode = 0x%x, ReturnFlags = 0x%x, MajorRev = 0x%x, MinorRev = 0x%x, \n",
+ EisaBuffer->ReturnCode, EisaBuffer->ReturnFlags,
+ EisaBuffer->MajorRevision, EisaBuffer->MinorRevision);
+ DbgPrint("CheckSum = 0x%x, NumberFunctions = 0x%x, FunctionInformation = 0x%x, CompressedId = 0x%x\n",
+ EisaBuffer->Checksum,
+ EisaBuffer->NumberFunctions,
+ EisaBuffer->FunctionInformation,
+ EisaBuffer->CompressedId);
+ for (funcs = 0; funcs < EisaBuffer->NumberFunctions; funcs++) {
+ DbgPrint("CompressId = 0x%x, IdSlotFlags1 = 0x%x, IdSlotFlags2 = 0x%x, MinorRevision = 0x%x, MajorRevision = 0x%x\n",
+ EisaFunctionInfo->CompressedId, EisaFunctionInfo->IdSlotFlags1,
+ EisaFunctionInfo->IdSlotFlags2, EisaFunctionInfo->MinorRevision,
+ EisaFunctionInfo->MajorRevision);
+
+ // EisaFunctionInfo->Selections[26];
+ // EisaFunctionInfo->FunctionFlags;
+ // EisaFunctionInfo->TypeString[80];
+ // EISA_MEMORY_CONFIGURATION EisaFunctionInfo->EisaMemory[9];
+ // EISA_IRQ_CONFIGURATION EisaFunctionInfo->EisaIrq[7];
+ // EISA_DMA_CONFIGURATION EisaFunctionInfo->EisaDma[4];
+ // EISA_PORT_CONFIGURATION EisaFunctionInfo->EisaPort[20];
+ // UCHAR EisaFunctionInfo->InitializationData[60];
+ EisaFunctionInfo++;
+ }
+
+ }
+ }
+ DbgBreakPoint ();
+ {
+ #define MEMORY_SPACE 0
+ #define IO_SPACE 1
+ PHYSICAL_ADDRESS cardAddress;
+ ULONG addressSpace = IO_SPACE;
+ PHYSICAL_ADDRESS PhysAddr;
+
+ PhysAddr.LowPart = 0;
+ PhysAddr.HighPart = 0;
+
+
+
+ DbgPrint("----- Translate Internal Bus Address(I/O): ");
+ HalTranslateBusAddress(Internal, (ULONG)0, PhysAddr, &addressSpace, &cardAddress);
+ DbgPrint("H-AD: %x\tL-AD: %x\n\n", cardAddress.HighPart, cardAddress.LowPart);
+
+ DbgPrint("Translate Eisa Bus Address(I/O): ");
+ addressSpace = IO_SPACE;
+ HalTranslateBusAddress(Eisa, (ULONG)0, PhysAddr, &addressSpace, &cardAddress);
+ DbgPrint("H-AD: %x\tL-AD: %x\n\n", cardAddress.HighPart, cardAddress.LowPart);
+
+ DbgPrint("Translate Isa Bus Address(I/O): ");
+ addressSpace = IO_SPACE;
+ HalTranslateBusAddress(Isa, (ULONG)0, PhysAddr, &addressSpace, &cardAddress);
+ DbgPrint("H-AD: %x\tL-AD: %x\n\n", cardAddress.HighPart, cardAddress.LowPart);
+
+ DbgPrint("Translate PCI Bus Address(I/O): ");
+ addressSpace = IO_SPACE;
+ HalTranslateBusAddress(PCIBus, (ULONG)0, PhysAddr, &addressSpace, &cardAddress);
+ DbgPrint("H-AD: %x\tL-AD: %x\n\n", cardAddress.HighPart, cardAddress.LowPart);
+
+ DbgPrint("Translate Internal Bus Address(MEMORY): ");
+ addressSpace = MEMORY_SPACE;
+ HalTranslateBusAddress(Internal, (ULONG)0, PhysAddr, &addressSpace, &cardAddress);
+ DbgPrint("H-AD: %x\tL-AD: %x\n\n", cardAddress.HighPart, cardAddress.LowPart);
+
+ DbgPrint("Translate Eisa Bus Address(MEMORY): ");
+ addressSpace = MEMORY_SPACE;
+ HalTranslateBusAddress(Eisa, (ULONG)0, PhysAddr, &addressSpace, &cardAddress);
+ DbgPrint("H-AD: %x\tL-AD: %x\n\n", cardAddress.HighPart, cardAddress.LowPart);
+
+ DbgPrint("Translate Isa Bus Address(MEMORY): ");
+ addressSpace = MEMORY_SPACE;
+ HalTranslateBusAddress(Isa, (ULONG)0, PhysAddr, &addressSpace, &cardAddress);
+ DbgPrint("H-AD: %x\tL-AD: %x\n\n", cardAddress.HighPart, cardAddress.LowPart);
+
+ DbgPrint("Translate PCI Bus Address(MEMORY): ");
+ addressSpace = MEMORY_SPACE;
+ HalTranslateBusAddress(PCIBus, (ULONG)0, PhysAddr, &addressSpace, &cardAddress);
+ DbgPrint("H-AD: %x\tL-AD: %x\n\n", cardAddress.HighPart, cardAddress.LowPart);
+ }
+ DbgBreakPoint ();
+
+ {
+ KAFFINITY affinity;
+ KIRQL Irql;
+ ULONG Vec;
+
+ DbgPrint("----- GetInterruptVector internal\n");
+ Vec = HalGetInterruptVector(Internal, 0, 0, 0, &Irql, &affinity);
+ DbgPrint(" Irql = 0x%x, affinity = 0x%x, vector = 0x%x\n\n", Irql, affinity, Vec);
+
+ DbgPrint("GetInterruptVector Eisa\n");
+ Vec = HalGetInterruptVector(Eisa, 0, 0, 0, &Irql, &affinity);
+ DbgPrint(" Irql = 0x%x, affinity = 0x%x, vector = 0x%x\n\n", Irql, affinity, Vec);
+
+ DbgPrint("GetInterruptVector Isa\n");
+ Vec = HalGetInterruptVector(Isa, 0, 0, 0, &Irql, &affinity);
+ DbgPrint(" Irql = 0x%x, affinity = 0x%x, vector = 0x%x\n\n", Irql, affinity, Vec);
+
+ DbgPrint("GetInterruptVector PCI\n");
+ Vec = HalGetInterruptVector(PCIBus, 0, 0, 0, &Irql, &affinity);
+ DbgPrint(" Irql = 0x%x, affinity = 0x%x, vector = 0x%x\n\n", Irql, affinity, Vec);
+
+ }
+ DbgBreakPoint ();
+}
+
+#endif // _R94A_
+#endif // DBG
+
+VOID
+HalpSetBackToBackSpace(
+ IN PPCI_COMMON_CONFIG PciConfigRequired,
+ IN PPCI_COMMON_CONFIG PciConfigMapped,
+ IN PBUS_HANDLER BusHandler
+ )
+/*++
+
+Routine Description:
+
+ This function sets memory space of PCI device to Fast Back-to-back register.
+
+Arguments:
+
+ PciConfigRequired - Supplies the description of the memory space which
+ device required.
+ PciConfigMapped - Supplies the description of the memory space which
+ should be mapped to back-to-back space.
+ BusHandler - Supplies the pointer to Bushandler.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ ULONG NoBaseAddress;
+ ULONG BaseAddress, LowerAddress;
+ ULONG CurrentAddress;
+ ULONG FoundMemoryAddress;
+ ULONG i, j, Length;
+
+#if DBG
+ DbgPrint(" check PCI-device!\n");
+ DbgPrint(" - VendorID ................ %04x\n", PciConfigMapped->VendorID);
+ DbgPrint(" - DeviceID ................ %04x\n", PciConfigMapped->DeviceID);
+ DbgPrint(" - back-to-back capable? ... %s\n", (PciConfigMapped->Status & 0x80) ? "o" : "x");
+ if (PciConfigMapped->BaseClass == 0x03
+ || (PciConfigMapped->BaseClass == 0x00 && PciConfigMapped->SubClass == 0x01)){
+ DbgPrint(" - Is this GA device? ...... o\n");
+ } else {
+ DbgPrint(" - Is this GA device? ...... x\n");
+ }
+#endif
+
+ KiAcquireSpinLock(&HalpPCIBackToBackLock);
+
+ //
+ // calulate memory region of this device.
+ //
+
+ switch (PCI_CONFIG_TYPE(PciConfigMapped)) {
+ case 0 :
+ NoBaseAddress = PCI_TYPE0_ADDRESSES;
+ break;
+ case 1:
+ NoBaseAddress = PCI_TYPE1_ADDRESSES;
+ break;
+ default:
+ // never come here.
+ // (already except by HalpAssignPCISlotResources)
+ return;
+ }
+
+ Length = 0;
+ BaseAddress = 0xffffffff;
+ LowerAddress = 0xffffffff;
+ FoundMemoryAddress = 0;
+
+ //
+ // get base and limit address
+ //
+
+ for (i = 0; i < NoBaseAddress; i++) {
+ CurrentAddress = PciConfigMapped->u.type0.BaseAddresses[i];
+ if (!(CurrentAddress & PCI_ADDRESS_IO_SPACE)
+ && ((CurrentAddress & PCI_ADDRESS_MEMORY_TYPE_MASK) != 0x2)) {
+
+ //
+ // this is memory space and not need to map below 1M
+ //
+
+ CurrentAddress = CurrentAddress & 0xfffffff0;
+ if (CurrentAddress) {
+ FoundMemoryAddress = 1;
+ if (LowerAddress > CurrentAddress)
+ LowerAddress = CurrentAddress;
+ // scan for first set bit, that's the length & alignment
+ j = 1 << 4;
+ while (!(PciConfigRequired->u.type0.BaseAddresses[i] & j) && j)
+ j <<= 1;
+#if DBG
+ DbgPrint(" - [%d]MemoryAddress ........ 0x%08x\n", i, CurrentAddress);
+ DbgPrint(" - [%d]Length ............... 0x%08x\n", i, j);
+#endif
+ if (Length < j){
+ BaseAddress = CurrentAddress;
+ Length = j;
+ }
+ }
+ }
+ }
+
+#if DBG
+ DbgPrint(" - LowerAddress ............ 0x%08x\n", LowerAddress);
+ DbgPrint(" - BaseAddress ............. 0x%08x\n", BaseAddress);
+ DbgPrint(" - Length .................. 0x%08x\n", Length);
+#endif
+
+ //
+ // If this device has memory space, then change memory limit
+ // value used be allocation for PCI memory space to
+ // 'LowerAddress - 1' of this device, otherwise release spinlock
+ // and return.
+ //
+
+ if (FoundMemoryAddress) {
+ HalpPCIMemoryLimit = LowerAddress - 1;
+ } else {
+ goto NotSetBackToBack;
+ }
+
+ //
+ // We do not support the PCI devices which connected under
+ // PCI-PCI bridge.
+ //
+
+ if (BusHandler->BusNumber == 0) {
+
+ if (PciConfigMapped->Status & 0x80) {
+
+ //
+ // This device is back-to-back capable.
+ // We can map the memory space of this device as
+ // back-to-back available.
+ // Set flag to indicate setting started.
+ //
+
+ if (!HalpPCIBackToBackReg0Start) {
+ HalpPCIBackToBackReg0Start = 1;
+
+ } else if (HalpPCIBackToBackReg0Start && !HalpPCIBackToBackReg0Open) {
+ HalpPCIBackToBackReg1Start = 1;
+
+ }
+
+ //
+ // BUGBUG: Some pci drivers assign its memory space by itself.
+ // This means that we can not control the memory address of
+ // such device by MemoryLimit value. So, we can not enable the
+ // following codes now.
+ // N.B. following code does not finished.
+ //
+
+// if (!HalpFoundUncapablePCIDevice) {
+//
+// //
+// // Uncapable device not mapped yet, so we can expand
+// // back-to-back space.
+// // We expand back-to-back space until uncapable device
+// // is found.
+// //
+//
+// if (back-to-back reg0 == initialize value){
+// HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)0);
+// } else {
+// back-to-back reg0 =+ add this memory range;
+// MemoryLimit = the BaseAddress of this device;
+// }
+//
+// if (PciConfigMapped->BaseClass == 0x03
+// || (PciConfigMapped->BaseClass == 0x00
+// && PciConfigMapped->SubClass == 0x01)) {
+// HalpPCINumberOfMappedGA++;
+// }
+//
+// } else {
+
+ if (HalpNumberOfPCIGA > 1) {
+
+ //
+ // There are some PCI-GA cards.
+ // If this is PCI-GA, then set to back-to-back,
+ // else we do not map.
+ //
+
+ if (PciConfigMapped->BaseClass == 0x03
+ || (PciConfigMapped->BaseClass == 0x00
+ && PciConfigMapped->SubClass == 0x01)) {
+
+ switch (HalpPCINumberOfMappedGA) {
+
+ case 0:
+
+ //
+ // We need set PCI-GA to both back-to-back space.
+ // The control reach here, it indicates PCI-GA
+ // not mapped to back-to-back space yet.
+ //
+
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)0);
+ HalpPCIBackToBackReg0Open = 0;
+ break;
+
+ case 1:
+
+ //
+ // Control is transfered to this routine when one PCI-GA
+ // is already mapped. This means that reg0 had already used.
+ // We use reg1.
+ //
+
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)1);
+ HalpPCIBackToBackReg1Open = 0;
+
+ }
+
+ HalpPCINumberOfMappedGA++;
+ }
+
+ } else {
+
+ //
+ // There is only one-card as PCI-GA.
+ // We need set PCI-GA to back-to-back.
+ // If this is GA and reg0 is opened, then use reg0.
+ // If this is GA and reg0 is closeed, then use reg1.
+ //
+
+ if (PciConfigMapped->BaseClass == 0x03
+ || (PciConfigMapped->BaseClass == 0x00
+ && PciConfigMapped->SubClass == 0x01)) {
+
+ if (HalpPCIBackToBackReg0Open) {
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)0);
+ HalpPCIBackToBackReg0Open = 0;
+
+ } else {
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)1);
+ HalpPCIBackToBackReg1Open = 0;
+
+ }
+
+ HalpPCINumberOfMappedGA++;
+
+ } else {
+
+ //
+ // We can set only if reg0 or reg1 is not used.
+ //
+
+ if (HalpPCIBackToBackReg0Open) {
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)0);
+ HalpPCIBackToBackReg0Open = 0;
+
+ } else if (HalpPCIBackToBackReg1Open){
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)1);
+ HalpPCIBackToBackReg1Open = 0;
+
+ }
+ }
+ }
+// }
+
+ } else {
+
+ //
+ // This is back-to-back uncapable.
+ //
+
+ HalpFoundUncapablePCIDevice = 1;
+
+ //
+ // if device is back-to-back uncapable¡¤map only GA.
+ //
+
+ if (PciConfigMapped->BaseClass == 0x03
+ || (PciConfigMapped->BaseClass == 0x00
+ && PciConfigMapped->SubClass == 0x01)) {
+
+ //
+ // In case of two or more cards are connected, the
+ // process is depend on the number of PCI-GA which
+ // already mapped.
+ // But we do not need to map 3rd PCI-GA or more.
+ //
+
+ if (HalpNumberOfPCIGA > 1) {
+
+ switch (HalpPCINumberOfMappedGA) {
+
+ case 0:
+
+ //
+ // Re-nitialize all values to void already settings,
+ // and use reg0
+ //
+
+ HalpPCIBackToBackReg0Start = 1;
+ HalpPCIBackToBackReg1Start = 0;
+ HalpPCIBackToBackReg0Open = 1;
+ HalpPCIBackToBackReg1Open = 1;
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)0);
+ break;
+
+ case 1:
+
+ //
+ // Control is transfered to this routine when one PCI-GA
+ // is already mapped. This means that reg0 had already used.
+ // We use reg1.
+ //
+ // N.B. We do not know reg0 is opened or closed, so close
+ // reg0 here.
+ // (ex) 1st mapped ... capable = 1, not GA
+ // 2nd mapped ... capable = 0, GA
+ //
+
+ HalpPCIBackToBackReg0Open = 0;
+ HalpPCIBackToBackReg1Start = 1;
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)1);
+
+ }
+
+ } else {
+
+ //
+ // There is only one-card as PCI-GA.
+ // If back-to-back reg0 not being useed, use reg0,
+ // else close the space of reg0 and use reg1.
+ // (Also when reg0 is closed, use reg1)
+ //
+
+ if (!HalpPCIBackToBackReg0Start) {
+ HalpPCIBackToBackReg0Start = 1;
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)0);
+
+ } else {
+ HalpPCIBackToBackReg0Open = 0;
+ HalpPCIBackToBackReg1Start = 1;
+ HalpSetBackToBackRegister(BaseAddress, Length, (ULONG)1);
+
+ }
+ }
+ }
+
+ //
+ // if being to set to back-to-back register, we have to close.
+ //
+
+ if (HalpPCIBackToBackReg0Start && HalpPCIBackToBackReg0Open) {
+ HalpPCIBackToBackReg0Open = 0;
+
+ } else if (HalpPCIBackToBackReg1Start && HalpPCIBackToBackReg1Open) {
+ HalpPCIBackToBackReg1Open = 0;
+
+ }
+
+ }
+
+ }
+
+NotSetBackToBack:
+ KiReleaseSpinLock(&HalpPCIBackToBackLock);
+
+}
+
+VOID
+HalpSetBackToBackRegister(
+ IN ULONG BaseAddress,
+ IN ULONG Length,
+ IN ULONG Register
+ )
+/*++
+
+Routine Description:
+
+ This function sets memory space of PCI device to Fast Back-to-back register.
+
+Arguments:
+
+ BaseAddress - Supplies the address which to be mapped with back-to-back.
+ Length - Supplies the length which to be mapped with back-to-back.
+ Register - Supplies the back-to-back register number.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ ULONG Mask;
+
+ //
+ // make mask value
+ //
+
+ Mask = ~(Length - 1);
+
+ //
+ // set to back-to-back register
+ //
+
+#if DBG
+ DbgPrint(" set back-to-back register.\n");
+ DbgPrint(" - Register ................ %d\n", Register);
+ DbgPrint(" - Address ................. 0x%08x\n", BaseAddress);
+ DbgPrint(" - Mask .................... 0x%08x\n", Mask);
+#endif
+
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->PCIFastBackToBack[Register].Address,
+ BaseAddress
+ );
+
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->PCIFastBackToBack[Register].Mask,
+ Mask
+ );
+
+}
+
+ULONG
+HalpGetNumberOfPCIGA(
+ IN ULONG NumberBuses
+ )
+/*++
+
+Routine Description:
+
+ This function determines the number of PCI-GAs.
+ And initialize Fast Back-to-back register.
+
+Arguments:
+
+ NumberBuses - Supplies the number of the PCI-buses.
+
+Return Value:
+
+ number of PCI-GA.
+
+--*/
+
+{
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ ULONG Bus;
+ ULONG Slot;
+ ULONG Function;
+ PBUS_HANDLER BusHandler;
+ PCI_SLOT_NUMBER SlotNumber;
+ PPCI_COMMON_CONFIG PciData;
+ ULONG Count;
+ ULONG Register;
+ USHORT commandValue;
+
+ Count = 0;
+ PciData = (PPCI_COMMON_CONFIG)&iBuffer;
+
+ //
+ // BUGBUG: Fast Back-to-back transaction can be used
+ // only bus number zero on this version.
+ // PCI devices connected on bus number 1 or more will
+ // be available with back-to-back on future.
+ //
+
+ NumberBuses = 1;
+
+ //
+ // Look for PCI controllers which have known work-arounds, and make
+ // sure they are applied.
+ //
+
+ SlotNumber.u.bits.Reserved = 0;
+ for (Bus = 0; Bus < NumberBuses; Bus++) {
+ BusHandler = HalpHandlerForBus (PCIBus, Bus);
+
+ for (Slot = 0; Slot < PCI_MAX_DEVICES; Slot++) {
+ SlotNumber.u.bits.DeviceNumber = Slot;
+
+ for (Function = 0; Function < PCI_MAX_FUNCTION; Function++) {
+ SlotNumber.u.bits.FunctionNumber = Function;
+
+ //
+ // Read PCI configuration information
+ //
+
+ HalpReadPCIConfig (BusHandler, SlotNumber, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Check for chips with known work-arounds to apply
+ //
+
+ if (PciData->BaseClass == 0x03
+ || (PciData->BaseClass == 0x00 && PciData->SubClass == 0x01)){
+
+ //
+ // This is Graphics Adapter. Inclement count.
+ //
+
+ Count++;
+ }
+
+ } // next PCI function
+
+ } // next PCI slot
+
+ } // next PCI bus
+
+#if DBG
+ DbgPrint(" number of PCI-GA.\n");
+ DbgPrint(" - number of PCI-GA ........ %d\n", Count);
+#endif
+
+ //
+ // Initialize Fast Back-to-back register.
+ //
+
+ for (Register = 0; Register < 2; Register++) {
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->PCIFastBackToBack[Register].Address,
+ INIT_VALUE_OF_BACK_TO_BACK_ADDR
+ );
+
+ WRITE_REGISTER_ULONG(
+ &DMA_CONTROL->PCIFastBackToBack[Register].Mask,
+ INIT_VALUE_OF_BACK_TO_BACK_MASK
+ );
+ }
+
+ commandValue = READ_REGISTER_USHORT(&DMA_CONTROL->PCICommand);
+ WRITE_REGISTER_USHORT(&DMA_CONTROL->PCICommand, (commandValue & ~0x0200));
+
+ return Count;
+
+}
diff --git a/private/ntos/nthals/halr96b/mips/pciint.c b/private/ntos/nthals/halr96b/mips/pciint.c
new file mode 100644
index 000000000..06571660d
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/pciint.c
@@ -0,0 +1,376 @@
+// #pragma comment(exestr, "@(#) pciint.c 1.1 95/09/28 15:46:29 nec")
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ ixpciint.c
+
+Abstract:
+
+ All PCI bus interrupt mapping is in this module, so that a real
+ system which doesn't have all the limitations which PC PCI
+ systems have can replaced this code easly.
+ (bus memory & i/o address mappings can also be fix here)
+
+Author:
+
+ Ken Reneris
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+Modification History:
+
+ H001 Fri Jun 30 02:58:57 1995 kbnes!kisimoto
+ - Merge build 1057
+ H002 Tue Sep 5 20:21:24 1995 kbnes!kisimoto
+ - PCI Fast Back-to-back transfer support
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+
+ULONG PciIsaIrq;
+ULONG HalpEisaELCR;
+BOOLEAN HalpDoingCrashDump;
+extern ULONG HalpPCIMemoryLimit; // H002
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE,HalpGetPCIIntOnISABus)
+#pragma alloc_text(PAGE,HalpAdjustPCIResourceList)
+#pragma alloc_text(PAGE,HalpGetISAFixedPCIIrq)
+#endif
+
+#if defined(_R94A_) // H001
+ULONG R94A_PCIPinToLineTable[][4] = {
+ { 0xF, 0xF, 0xF, 0xF }, // Slot 0(Hurricane)No InterruptPin
+ { 0xF, 0xF, 0xF, 0xF }, // Slot 1(Typhoon) No InterruptPin assign
+ { 0xF, 0xF, 0xF, 0xF }, // Slot 2(PCEB) No InterruptPin assign
+ { 0x3, 0x3, 0x3, 0x3 }, // Slot 3 : INT A B C D
+ { 0x2, 0x2, 0x2, 0x2 }, // Slot 4 : INT A B C D
+ { 0x1, 0x1, 0x1, 0x1 } // Slot 5 : INT A B C D
+};
+#endif // _R94A_
+
+ULONG
+HalpGetPCIIntOnISABus (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ )
+{
+ if (BusInterruptLevel < 1) {
+ // bogus bus level
+ return 0;
+ }
+
+
+ //
+ // Current PCI buses just map their IRQs ontop of the ISA space,
+ // so foreward this to the isa handler for the isa vector
+ // (the isa vector was saved away at either HalSetBusData or
+ // IoAssignReosurces time - if someone is trying to connect a
+ // PCI interrupt without performing one of those operations first,
+ // they are broken).
+ //
+
+ return HalGetInterruptVector (
+#ifndef MCA
+ Isa, 0,
+#else
+ MicroChannel, 0,
+#endif
+ BusInterruptLevel ^ IRQXOR,
+ 0,
+ Irql,
+ Affinity
+ );
+}
+
+
+VOID
+HalpPCIPin2ISALine (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciData
+ )
+/*++
+
+ This function maps the device's InterruptPin to an InterruptLine
+ value.
+
+ On the current PC implementations, the bios has already filled in
+ InterruptLine as it's ISA value and there's no portable way to
+ change it.
+
+ On a DBG build we adjust InterruptLine just to ensure driver's
+ don't connect to it without translating it on the PCI bus.
+
+--*/
+{
+ if (!PciData->u.type0.InterruptPin) {
+ return ;
+ }
+
+#if defined(_R94A_) // H001
+
+ PciData->u.type0.InterruptLine =
+ (UCHAR)R94A_PCIPinToLineTable[SlotNumber.u.bits.DeviceNumber][PciData->u.type0.InterruptPin];
+
+#else
+
+ //
+ // Set vector as a level vector. (note: this code assumes the
+ // irq is static and does not move).
+ //
+
+ if (PciData->u.type0.InterruptLine >= 1 &&
+ PciData->u.type0.InterruptLine <= 15) {
+
+ //
+ // If this bit was on the in the PIC ELCR register,
+ // then mark it in PciIsaIrq. (for use in hal.dll,
+ // such that we can assume the interrupt controller
+ // has been properly marked as a level interrupt for
+ // this IRQ. Other hals probabily don't care.)
+ //
+
+ PciIsaIrq |= HalpEisaELCR & (1 << PciData->u.type0.InterruptLine);
+ }
+
+ //
+ // On a PC there's no Slot/Pin/Line mapping which needs to
+ // be done.
+ //
+
+ PciData->u.type0.InterruptLine ^= IRQXOR;
+
+#endif // _R94A_
+
+}
+
+
+
+VOID
+HalpPCIISALine2Pin (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciNewData,
+ IN PPCI_COMMON_CONFIG PciOldData
+ )
+/*++
+
+ This functions maps the device's InterruptLine to it's
+ device specific InterruptPin value.
+
+ On the current PC implementations, this information is
+ fixed by the BIOS. Just make sure the value isn't being
+ editted since PCI doesn't tell us how to dynically
+ connect the interrupt.
+
+--*/
+{
+ if (!PciNewData->u.type0.InterruptPin) {
+ return ;
+ }
+
+#if defined(_R94A_) // H001
+
+ PciNewData->u.type0.InterruptLine =
+ (UCHAR)R94A_PCIPinToLineTable[SlotNumber.u.bits.DeviceNumber][PciOldData->u.type0.InterruptPin];
+
+#else
+
+ PciNewData->u.type0.InterruptLine ^= IRQXOR;
+
+#endif // _R94A_
+
+#if DBG
+ if (PciNewData->u.type0.InterruptLine != PciOldData->u.type0.InterruptLine ||
+ PciNewData->u.type0.InterruptPin != PciOldData->u.type0.InterruptPin) {
+ DbgPrint ("HalpPCILine2Pin: System does not support changing the PCI device interrupt routing\n");
+ // DbgBreakPoint ();
+ }
+#endif
+}
+
+#if !defined(SUBCLASSPCI)
+
+VOID
+HalpPCIAcquireType2Lock (
+ PKSPIN_LOCK SpinLock,
+ PKIRQL Irql
+ )
+{
+ if (!HalpDoingCrashDump) {
+#if defined(_R94A_) // H001
+ KeRaiseIrql(PROFILE_LEVEL, Irql);
+#else
+ *Irql = KfRaiseIrql (HIGH_LEVEL);
+#endif
+ KiAcquireSpinLock (SpinLock);
+ } else {
+ *Irql = HIGH_LEVEL;
+ }
+}
+
+
+VOID
+HalpPCIReleaseType2Lock (
+ PKSPIN_LOCK SpinLock,
+ KIRQL Irql
+ )
+{
+ if (!HalpDoingCrashDump) {
+ KiReleaseSpinLock (SpinLock);
+#if defined(_R94A_) // H001
+ KeLowerIrql (Irql);
+#else
+ KfLowerIrql (Irql);
+#endif // _R94A_
+ }
+}
+
+#endif
+
+NTSTATUS
+HalpAdjustPCIResourceList (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
+ )
+/*++
+ Rewrite the callers requested resource list to fit within
+ the supported ranges of this bus
+--*/
+{
+ NTSTATUS Status;
+ PPCIPBUSDATA BusData;
+ PCI_SLOT_NUMBER PciSlot;
+ PSUPPORTED_RANGE Interrupt;
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+ PciSlot = *((PPCI_SLOT_NUMBER) &(*pResourceList)->SlotNumber);
+
+ //
+ // Determine PCI device's interrupt restrictions
+ //
+
+ Status = BusData->GetIrqRange(BusHandler, RootHandler, PciSlot, &Interrupt);
+
+ if (!NT_SUCCESS(Status)) {
+ return Status;
+ }
+
+ //
+ // H002
+ // change Memory.Limit value to BaseAddress which last mapped.
+ //
+
+#if DBG
+ DbgPrint(" change Memory.Limit!\n");
+ DbgPrint(" - Before limit ............ 0x%08x\n",
+ ((PLARGE_INTEGER)(&BusHandler->BusAddresses->Memory.Limit))->LowPart);
+#endif
+
+ ((PLARGE_INTEGER)(&BusHandler->BusAddresses->Memory.Limit))->LowPart = HalpPCIMemoryLimit;
+
+#if DBG
+ DbgPrint(" - After limit ............. 0x%08x\n",
+ ((PLARGE_INTEGER)(&BusHandler->BusAddresses->Memory.Limit))->LowPart);
+#endif
+
+ //
+ // Adjust resources
+ //
+
+ Status = HaliAdjustResourceListRange (
+ BusHandler->BusAddresses,
+ Interrupt,
+ pResourceList
+ );
+
+ ExFreePool (Interrupt);
+ return Status;
+}
+
+
+NTSTATUS
+HalpGetISAFixedPCIIrq (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER PciSlot,
+ OUT PSUPPORTED_RANGE *Interrupt
+ )
+{
+ UCHAR buffer[PCI_COMMON_HDR_LENGTH];
+ PPCI_COMMON_CONFIG PciData;
+
+#if defined(_R94A_) // H001
+ PPCIPBUSDATA BusData;
+#endif
+
+ PciData = (PPCI_COMMON_CONFIG) buffer;
+ HalGetBusData (
+ PCIConfiguration,
+ BusHandler->BusNumber,
+ PciSlot.u.AsULONG,
+ PciData,
+ PCI_COMMON_HDR_LENGTH
+ );
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != 0) {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ *Interrupt = ExAllocatePool (PagedPool, sizeof (SUPPORTED_RANGE));
+ if (!*Interrupt) {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory (*Interrupt, sizeof (SUPPORTED_RANGE));
+ (*Interrupt)->Base = 1; // base = 1, limit = 0
+
+#if defined(_R94A_) // H001
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, PciSlot, PciData);
+
+#else
+
+ if (!PciData->u.type0.InterruptPin) {
+ return STATUS_SUCCESS;
+ }
+
+ if (PciData->u.type0.InterruptLine == IRQXOR) {
+#if DBG
+ DbgPrint ("HalpGetValidPCIFixedIrq: BIOS did not assign an interrupt vector for the device\n");
+#endif
+ //
+ // We need to let the caller continue, since the caller may
+ // not care that the interrupt vector is connected or not
+ //
+
+ return STATUS_SUCCESS;
+ }
+
+#endif // _R94A_
+
+ (*Interrupt)->Base = PciData->u.type0.InterruptLine;
+ (*Interrupt)->Limit = PciData->u.type0.InterruptLine;
+ return STATUS_SUCCESS;
+}
diff --git a/private/ntos/nthals/halr96b/mips/pcip.h b/private/ntos/nthals/halr96b/mips/pcip.h
new file mode 100644
index 000000000..8e6a361a8
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/pcip.h
@@ -0,0 +1,200 @@
+// #pragma comment(exestr, "@(#) pcip.h 1.1 95/09/28 15:46:56 nec")
+/*++
+
+ Modification History
+
+ H001 Fri Jun 30 02:51:55 1995 kbnes!kisimoto
+ - add definition
+
+--*/
+
+//
+// Hal specific PCI bus structures
+//
+
+typedef NTSTATUS
+(*PciIrqRange) (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER PciSlot,
+ OUT PSUPPORTED_RANGE *Interrupt
+ );
+
+typedef struct tagPCIPBUSDATA {
+
+ //
+ // Defined PCI data
+ //
+
+ PCIBUSDATA CommonData;
+
+ //
+ // Implementation specific data
+ //
+
+ union {
+ struct {
+ PULONG Address;
+ ULONG Data;
+ } Type1;
+ struct {
+ PUCHAR CSE;
+ PUCHAR Forward;
+ ULONG Base;
+ } Type2;
+ } Config;
+
+ ULONG MaxDevice;
+ PciIrqRange GetIrqRange;
+
+ BOOLEAN BridgeConfigRead;
+ UCHAR ParentBus;
+ UCHAR reserved[2];
+ UCHAR SwizzleIn[4];
+
+ RTL_BITMAP DeviceConfigured;
+ ULONG ConfiguredBits[PCI_MAX_DEVICES * PCI_MAX_FUNCTION / 32];
+} PCIPBUSDATA, *PPCIPBUSDATA;
+
+#define PciBitIndex(Dev,Fnc) (Fnc*32 + Dev);
+
+#define PCI_CONFIG_TYPE(PciData) ((PciData)->HeaderType & ~PCI_MULTIFUNCTION)
+
+#define Is64BitBaseAddress(a) \
+ (((a & PCI_ADDRESS_IO_SPACE) == 0) && \
+ ((a & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT))
+
+#if defined(_R94A_) // H001
+#define R94A_PCI_TYPE1_ADDR_PORT 0xFFFFc518
+#define R94A_PCI_TYPE1_DATA_PORT 0xFFFFc520
+#endif // _R94A_
+
+#if DBG
+#define IRQXOR 0x2B
+#else
+#define IRQXOR 0
+#endif
+
+
+//
+// Prototypes for functions in ixpcibus.c
+//
+
+VOID
+HalpInitializePciBus (
+ VOID
+ );
+
+VOID
+HalpReadPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+
+VOID
+HalpWritePCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+PBUS_HANDLER
+HalpAllocateAndInitPciBusHandler (
+ IN ULONG HwType,
+ IN ULONG BusNo,
+ IN BOOLEAN TestAllocation
+ );
+
+
+//
+// Prototypes for functions in ixpciint.c
+//
+
+ULONG
+HalpGetPCIIntOnISABus (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ );
+
+VOID
+HalpPCIAcquireType2Lock (
+ PKSPIN_LOCK SpinLock,
+ PKIRQL Irql
+ );
+
+VOID
+HalpPCIReleaseType2Lock (
+ PKSPIN_LOCK SpinLock,
+ KIRQL Irql
+ );
+
+NTSTATUS
+HalpAdjustPCIResourceList (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
+ );
+
+VOID
+HalpPCIPin2ISALine (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciData
+ );
+
+VOID
+HalpPCIISALine2Pin (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciNewData,
+ IN PPCI_COMMON_CONFIG PciOldData
+ );
+
+NTSTATUS
+HalpGetISAFixedPCIIrq (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER PciSlot,
+ OUT PSUPPORTED_RANGE *Interrupt
+ );
+
+//
+// Prototypes for functions in ixpcibrd.c
+//
+
+BOOLEAN
+HalpGetPciBridgeConfig (
+ IN ULONG HwType,
+ IN PUCHAR MaxPciBus
+ );
+
+VOID
+HalpFixupPciSupportedRanges (
+ IN ULONG MaxBuses
+ );
+
+//
+//
+//
+
+#ifdef SUBCLASSPCI
+
+VOID
+HalpSubclassPCISupport (
+ IN PBUS_HANDLER BusHandler,
+ IN ULONG HwType
+ );
+
+#endif
diff --git a/private/ntos/nthals/halr96b/mips/pcisup.c b/private/ntos/nthals/halr96b/mips/pcisup.c
new file mode 100644
index 000000000..d46cc00e4
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/pcisup.c
@@ -0,0 +1,632 @@
+// #pragma comment(exestr, "@(#) r94apcisup.c 1.1 95/09/28 18:37:11 nec")
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ r94apisup.c
+
+Abstract:
+
+ The module provides the PCI bus support for R94A systems.
+
+Author:
+
+
+Revision History:
+
+ L0001 1994.9.20 kbnes!kuriyama(A)
+ -New module for R94A R4400 system
+ -add HalpAllocaltePCIAdapter()
+
+ H0001 Tue Sep 20 22:58:03 JST 1994 kbnes!kishimoto
+ -add HalpEnablePCIInterrupt()
+ -add HalpDisablePCIInterrupt()
+ -add HalpPCIDispatch()
+ -add HalpPCIFatalError()
+
+ H0002 Tue Oct 4 12:47:58 JST 1994 kbnes!kishimoto
+ -modify HalpPCIFatalError()
+ display the appropriate PCI errors
+
+ L0002 1994.10.13 kbnes!kuriyama(A)
+ -add HalpAllocaltePCIAdapter()
+ -add AdapterBaseVa set routine
+
+ H0003 Fri Oct 14 14:54:40 JST 1994 kbnes!kishimoto
+ -chg use READ_REGISTER_DWORD to read 64-bit I/O register
+
+ H0003 Mon Oct 17 14:36:57 JST 1994 kbnes!kishimoto
+ -chg Hal(p)EisaPCIXXX() rename to Hal(p)EisaXXX()
+ XXX_EISA_PCI_XXX rename to XXX_EISA_XXX
+ MAXIMUM_PCI_SLOT rename to R94A_PCI_SLOT
+
+ H0004 Wed Oct 19 13:24:51 JST 1994 kbnes!kishimoto
+ -chg HalpPCIDispatch()
+ The PCI-error check change up the order.
+
+ H0005 Wed Oct 19 20:17:09 JST 1994 kbnes!kishimoto
+ -add substitute READ_REGISTER_BUFFER_UCHAR for
+ READ_REGISTER_DWORD because of storm alpha-
+ version cannot 64-bit access.
+
+ L0006 Wed Oct 19 22:01:27 JST 1994 kbnes!kuriyama(A)
+ -chg HalpAllocatePCIAdapter()
+ del useChannel
+ del channelNumber
+ del controllerNumber
+ del eisaSystem
+ chg AdapterBaseVa value
+
+ H0006 Tue Nov 22 22:10:00 1994 kbnes!kishimoto
+ -del delete _R94ABBM32_
+ The limitation of 32bit bus-access is only applied
+ under PCI-bus. I make a wrong application.
+
+ H0007 Fri Jul 21 18:02:55 1995 kbnes!kishimoto
+ -merge source with J94C
+
+--*/
+
+#include "halp.h"
+#include "eisa.h"
+
+#if defined(_R94A_)
+
+#include <stdio.h>
+
+/* start H0000 */
+
+//
+// Define the context structure for use by the interrupt routine.
+//
+
+typedef BOOLEAN (*PSECONDARY_DISPATCH)(
+ PVOID InterruptRoutine
+ );
+
+VOID
+HalpPCIFatalError(
+ STORM_PCI_INTRRUPT_STATUS InterruptStatus
+ );
+
+/* end H0000 */
+
+// start L0001
+PADAPTER_OBJECT
+HalpAllocatePCIAdapter(
+ IN PDEVICE_DESCRIPTION DeviceDescriptor
+ )
+/*++
+
+Routine Description:
+
+ This function allocates an PCI adapter object according to the
+ specification supplied in the device description. The necessary device
+ descriptor information is saved. If there is
+ no existing adapter object for this channel then a new one is allocated.
+ The saved information in the adapter object is used to set the various DMA
+ modes when the channel is allocated or a map transfer is done.
+
+Arguments:
+
+ DeviceDescription - Supplies the description of the device which want to
+ use the DMA adapter.
+
+Return Value:
+
+ Returns a pointer to the newly created adapter object or NULL if one
+ cannot be created.
+
+--*/
+
+{
+ PADAPTER_OBJECT adapterObject;
+ PVOID adapterBaseVa;
+ UCHAR adapterMode;
+
+ //
+ // All PCI Cards is Master card.
+ //
+
+ if (DeviceDescriptor->InterfaceType == PCIBus &&
+ DeviceDescriptor->Master) {
+
+ } else {
+
+ return(NULL);
+ }
+
+
+/* start L0002 */
+ //
+ // Set the adapter base address to the Base address register and controller
+ // number.
+ //
+
+ adapterBaseVa = ~0; /* L0006 */
+/* end L0002 */
+
+ //
+ // Allocate an adapter object.
+ //
+
+ adapterObject = (PADAPTER_OBJECT) HalpAllocateAdapter(
+ 0,
+ adapterBaseVa,
+ NULL
+ );
+
+ if (adapterObject == NULL) {
+
+ return(NULL);
+
+ }
+
+ //
+ // If the channel is not used then indicate the this is an PCI bus
+ // master by setting the page port and mode to cascade even though
+ // it is not used.
+ //
+
+ adapterObject->PagePort = (PVOID) (~0x0);
+ ((PDMA_EISA_MODE) &adapterMode)->RequestMode = CASCADE_REQUEST_MODE;
+ return(adapterObject);
+
+}
+// end L0001
+
+/* start H0001 */
+VOID
+HalpEnablePCIInterrupt (
+ IN ULONG Vector
+ )
+
+/*++
+
+Routine Description:
+
+ This function enables the PCI bus specified PCI bus interrupt.
+ PCI interrupts must be LevelSensitve. (PCI Spec. 2.2.6)
+
+Arguments:
+
+ Vector - Supplies the vector of the interrupt that is enabled.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG i;
+
+ //
+ // enable specified PCI bus interrupt.
+ //
+
+ i = READ_REGISTER_ULONG(
+ &((PDMA_REGISTERS) DMA_VIRTUAL_BASE)->PCIInterruptEnable
+ );
+
+ WRITE_REGISTER_ULONG(
+ &((PDMA_REGISTERS) DMA_VIRTUAL_BASE)->PCIInterruptEnable,
+ (ULONG)( i | 1 << (Vector - PCI_VECTORS))
+ );
+
+ return;
+
+}
+
+VOID
+HalpDisablePCIInterrupt (
+ IN ULONG Vector
+ )
+
+/*++
+
+Routine Description:
+
+ This function Disables the PCI bus specified PCI bus interrupt.
+ PCI interrupts must be LevelSensitve. (PCI Spec. 2.2.6)
+
+Arguments:
+
+ Vector - Supplies the vector of the PCI interrupt that is Disabled.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG i;
+
+ //
+ // disable specified PCI bus interrupt.
+ //
+
+ i = READ_REGISTER_ULONG(
+ &((PDMA_REGISTERS) DMA_VIRTUAL_BASE)->PCIInterruptEnable
+ );
+
+ WRITE_REGISTER_ULONG(
+ &((PDMA_REGISTERS) DMA_VIRTUAL_BASE)->PCIInterruptEnable,
+ (ULONG)( i & ~(1 << (Vector - PCI_VECTORS)))
+ );
+
+ return;
+
+}
+
+
+BOOLEAN
+HalpPCIDispatch(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ )
+/*++
+
+Routine Description:
+
+ This routine is entered as the result of an interrupt being generated
+ via the vector that is connected to an interrupt object that describes
+ the PCI device interrupts. Its function is to call the third
+ level interrupt dispatch routine and acknowledge the interrupt at the PCI
+ controller.
+
+ This service routine should be connected as follows:
+
+ KeInitializeInterrupt(&Interrupt, HalpEisaDispatch,
+ EISA_VIRTUAL_BASE,
+ (PKSPIN_LOCK)NULL, EISA_DEVICE_LEVEL, EISA_DEVICE_LEVEL,
+ EISA_DEVICE_LEVEL, LevelSensitive, TRUE, 0, FALSE);
+ KeConnectInterrupt(&Interrupt);
+
+Arguments:
+
+ Interrupt - Supplies a pointer to the interrupt object.
+
+ ServiceContext - Supplies a pointer to the EISA interrupt acknowledge
+ register.
+
+Return Value:
+
+ Returns the value returned from the third level routine.
+
+--*/
+
+{
+ STORM_PCI_INTRRUPT_STATUS InterruptStatus;
+ PKINTERRUPT interruptObject;
+ PULONG dispatchCode;
+ BOOLEAN returnValue;
+ LONG Index;
+
+ //
+ // Read the interrupt vector.
+ //
+
+ *((PULONG) &InterruptStatus) = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptStatus);
+
+ //
+ // BUGBUG
+ //
+
+ if (*((PULONG)&InterruptStatus) == 0) {
+
+ //
+ // There is not PCI interrupt.
+ //
+
+ return(FALSE);
+
+ }
+
+ //
+ // Check if there are any non-recoverable PCI errors.
+ // R94A has the following PCI error interrupts.
+ // Target abort interrupt
+ // Master abort interrupt
+ // Retry overflow interrupt
+ // SERR interrupt
+ // PERR interrupt
+ //
+
+ if (InterruptStatus.Perr == 1 ||
+ InterruptStatus.Serr == 1 ||
+ InterruptStatus.RetryOverflow == 1 ||
+ InterruptStatus.MasterAbort == 1 ||
+ InterruptStatus.TargetAbort == 1) {
+
+ //
+ // Display the appropriate PCI errors and bugcheck to dump the machine state.
+ //
+
+ HalpPCIFatalError(InterruptStatus);
+ KeBugCheck(DATA_BUS_ERROR);
+
+ //
+ // The following code is never executed.
+ //
+
+ return(FALSE);
+ }
+
+ //
+ // if INT[A.B.C.D] is active, then call the appropriate PCI drivers.
+ //
+
+ if ((*((PULONG)&InterruptStatus) & 0xf) != 0x0) {
+
+ //
+ // Dispatch to the secondary interrupt service routine.
+ //
+ // N.B. R94A PCI interrupts flow :
+ //
+ // system slot1 slot2 slot3
+ // INT A <----------+ + +
+ // INT B <------+ + + +
+ // INT C <---+ | + + +
+ // Reserved | | + + +
+ // | +-----------+ |
+ // +----------------------+
+ //
+ //
+ // PCI Interrupt Status Register Bit Definitions are:
+ //
+ // [31:09] Reserved
+ // [08] Target abort interrupt status
+ // [07] Master abort interrupt status
+ // [06] Retry overflow interrupt status
+ // [05] SERR interrupt status
+ // [04] PERR interrupt status
+ // [03] INTA interrupt status
+ // [02] INTB interrupt status
+ // [01] INTC interrupt status
+ // [00] INTD interrupt status
+ //
+
+ for (Index = 3; Index > (3 - R94A_PCI_SLOT); Index--) {
+
+ //
+ // Check if the PCI interrupt occur.
+ //
+
+ if (((*((PULONG)&InterruptStatus) & 0xf) & ((ULONG)1 << Index)) != 0x0) {
+
+ dispatchCode = (PULONG)(PCR->InterruptRoutine[PCI_VECTORS + Index]);
+ interruptObject = CONTAINING_RECORD(dispatchCode,
+ KINTERRUPT,
+ DispatchCode);
+
+ returnValue = ((PSECONDARY_DISPATCH)interruptObject->DispatchAddress)(interruptObject);
+
+ }
+
+ }
+
+ }
+
+ return(returnValue);
+
+}
+
+
+VOID
+HalpPCIFatalError(
+ STORM_PCI_INTRRUPT_STATUS InterruptStatus
+ )
+/*++
+
+Routine Description:
+
+ This routine is entered as the result of an PCI fatal interrupt.
+ This function displays appropriate PCI error information.
+
+Arguments:
+
+ InterruptStatus - PCI Interrupt Status value.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ UCHAR Buffer[100];
+ UCHAR registerChar;
+ ULONG registerLong;
+ LARGE_INTEGER registerLarge;
+ LARGE_INTEGER InvalidAddressValue;
+ LARGE_INTEGER EccDiagnosticValue;
+
+ HalpChangePanicFlag(16, 0x01, 0x10); // H0007
+
+ HalDisplayString("\nFatal system error occured\n\n");
+
+ //
+ // Display the following register value.
+ //
+ // register name address
+ //
+ // Remode Failed Address 0x80000010 32bit
+ // Memory Failed Address 0x80000018 32bit
+ // Processor Invalid Address 0x80000020 33bit
+ // ECC Diagnostic 0x800001c8 64bit
+ // PCI Status 0x80000606 16bit
+ // PCI Master Retry Timer 0x80000668 32bit
+ //
+
+ //
+ // Display the PCI fatal error information
+ //
+
+ if (InterruptStatus.Perr){
+ HalDisplayString("PCI: Data parity error\n");
+ }
+
+ if (InterruptStatus.Serr){
+ HalDisplayString("PCI: Address parity error\n");
+ }
+
+ if (InterruptStatus.RetryOverflow){
+ HalDisplayString("PCI: Retry overflow\n");
+ }
+
+ if (InterruptStatus.MasterAbort){
+ HalDisplayString("PCI: Master abort\n");
+ }
+
+ if (InterruptStatus.TargetAbort){
+ HalDisplayString("PCI: Target abort\n");
+ }
+
+ // ! start
+ // test test test : dump the hardware registers of R94A
+ // <cording memo>
+ // dump R94A all hardware-registers to buffer instead of display console
+ // registers that is only important for analasis dump are display to console
+ //
+ // registers which display to console are:
+ // 0x80000000 Configuration
+ // 0x80000010 RemoteFailedAddress
+ // 0x80000018 MemoryFailedAddress
+ // 0x80000020 InvalidAddress
+ // 0x80000078 NmiSource
+ // 0x800000f8 InterruptEnable
+ // 0x80000188 Errortype
+ // 0x800001c8 EccDiagnostic
+ // 0x80000530 PCIInterruptEnable
+ // 0x80000538 PCIInterruptStatus
+ // 0x80000606 PCIStatus
+ // 0x800005bc TyphoonErrorStatus
+ // 0x80000668 PCIMasterRetryTimer
+ //
+ // 0x8000f000 I/O Device Interrupt Enable
+ //
+
+ READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &InvalidAddressValue);
+ READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic, &EccDiagnosticValue);
+
+ sprintf(Buffer,
+ "Configuration : %08x RemoteFailedAddress : %08x\n",
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->Configuration.Long),
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->RemoteFailedAddress.Long));
+
+ HalDisplayString((UCHAR *)Buffer);
+
+ sprintf(Buffer,
+ "MemoryFailedAddress : %08x InvalidAddress :%01x%08x\n",
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long),
+ (InvalidAddressValue.HighPart & 0x1), InvalidAddressValue.LowPart);
+
+ HalDisplayString((UCHAR *)Buffer);
+
+ sprintf(Buffer,
+ "NmiSource : %08x InterruptEnable : %08x\n",
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->NmiSource.Long),
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InterruptEnable.Long));
+
+ HalDisplayString((UCHAR *)Buffer);
+
+ sprintf(Buffer,
+ "Errortype : %08x EccDiagnostic(High) : %08x\n",
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->NmiSource.Long),
+ EccDiagnosticValue.HighPart);
+
+ HalDisplayString((UCHAR *)Buffer);
+
+ sprintf(Buffer,
+ "EccDiagnostic(Low) : %08x PCIInterruptEnable : %08x\n",
+ EccDiagnosticValue.LowPart,
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptEnable.Long));
+
+ HalDisplayString((UCHAR *)Buffer);
+
+ sprintf(Buffer,
+ "PCIInterruptStatus : %08x PCIStatus : %08x\n",
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIInterruptStatus.Long),
+ READ_REGISTER_USHORT(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIStatus));
+
+ HalDisplayString((UCHAR *)Buffer);
+
+ sprintf(Buffer,
+ "TyphoonErrorStatus : %08x PCIMasterRetryTimer : %08x\n",
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->TyphoonErrorStatus),
+ READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIMasterRetryTimer));
+
+ HalDisplayString((UCHAR *)Buffer);
+
+ HalpGetStatusRegister(&registerLong);
+
+ sprintf(Buffer,
+ "I/O DevIntEnable : %08x (CPU)StatusRegister : %08x\n",
+ READ_REGISTER_ULONG((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE),
+ registerLong);
+
+ HalDisplayString((UCHAR *)Buffer);
+
+
+ //
+ // ! end
+ //
+
+// registerLong = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->RemoteFailedAddress.Long);
+// sprintf ((UCHAR *)Buffer, "RemodeFailedAddress = 0x%08x\n", registerLong);
+// HalDisplayString((UCHAR *)Buffer);
+
+// registerLong = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long);
+// sprintf ((UCHAR *)Buffer, "MemoryFailedAddress = 0x%08x\n", registerLong);
+// HalDisplayString((UCHAR *)Buffer);
+
+ //
+ // memo
+ //
+ // (./ntos/inc/mips.h)
+ // #define READ_REGISTER_BUFFER_UCHAR(x, y, z) {
+ // PUCHAR registerBuffer = x;
+ // PUCHAR readBuffer = y;
+ // ULONG readCount;
+ // for (readCount = z; readCount--; readBuffer++, registerBuffer++) {
+ // *readBuffer = *(volatile UCHAR * const)(registerBuffer);
+ // }
+ // }
+ //
+
+/* start H0003 */
+
+// READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &registerLarge);
+// sprintf ((UCHAR *)Buffer, "InvalidAddress =0x%01x%08x\n", registerLarge.HighPart & 0x1, registerLarge.LowPart);
+// HalDisplayString((UCHAR *)Buffer);
+
+// READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic, &registerLarge);
+// sprintf ((UCHAR *)Buffer, "EccDiagnostic(High) = 0x%08x\n", registerLarge.HighPart);
+// HalDisplayString((UCHAR *)Buffer);
+
+// sprintf ((UCHAR *)Buffer, "EccDiagnostic(Low) = 0x%08x\n", registerLarge.LowPart);
+// HalDisplayString((UCHAR *)Buffer);
+
+/* end H0003 */
+
+// registerChar = READ_REGISTER_UCHAR(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIStatus);
+// sprintf ((UCHAR *)Buffer, "PCIStatus = 0x%08x\n", registerChar);
+// HalDisplayString((UCHAR *)Buffer);
+
+// registerLong = READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->PCIMasterRetryTimer);
+// sprintf ((UCHAR *)Buffer, "PCIMasterRetryTimer = 0x%08x\n", registerLong);
+// HalDisplayString((UCHAR *)Buffer);
+
+ return;
+
+}
+
+/* end H0001 */
+#endif // _R94A_
diff --git a/private/ntos/nthals/halr96b/mips/r94adbg.c b/private/ntos/nthals/halr96b/mips/r94adbg.c
new file mode 100644
index 000000000..e48290c04
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/r94adbg.c
@@ -0,0 +1,157 @@
+// #pragma comment(exestr, "@(#) r94adbg.c 1.1 95/09/28 15:47:19 nec")
+/*++
+
+Copyright (c) 1994 KOBE NEC Software
+
+Module Name:
+
+ r94adbg.c
+
+Abstract:
+
+ The module provides the debug support functions for R94A systems.
+
+Author:
+
+Revision History:
+
+Modification History for NEC R94A (MIPS R4400):
+
+ H000 Thu Sep 8 10:32:42 JST 1994 kbnes!kishimoto
+ - add HalDisplayLED()
+ new function.
+ - add HalpOutputCharacterToLED()
+ new function.
+
+ H001 Mon Oct 17 13:01:53 JST 1994 kbnes!kishimoto
+ - add HalR94aDebugPrint()
+ new function.
+ - chg HalpDisplayLED()
+ rename from HalDisplayLED()
+
+ H002 Thu Oct 20 19:42:03 JST 1994 kbnes!kishimoto
+ - add R94aBbmLEDMapped used at KdPortInitialize()(jxport.c)
+ for debug use only
+
+ H003 Fri Oct 21 10:18:01 JST 1994 kbnes!kishimoto
+ - add specify the output device.
+
+ M004 Fri Jan 06 10:49:29 JST 1995 kbnes!kuriyama
+ - add HalpPrintMdl()
+
+ H005 Sat Mar 18 16:23:05 JST 1995 kbnes!kishimoto
+ - always include "halp.h"
+
+ S006 kuriyama@oa2.kb.nec.co.jp Mon Apr 03 10:49:48 JST 1995
+ - delete PrintMdl routine (if defined _PRINT_MDL_)
+
+--*/
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "halp.h" // H005
+
+#define R94A_LED 0
+#define R94A_DBG 1
+#define R94A_CON 2
+
+ULONG HalpR94aDebugOutput = R94A_DBG ; // start H003
+ULONG R94aDebugLevel = 1;
+
+VOID
+HalR94aDebugPrint(
+ ULONG DebugLevel,
+ PUCHAR LedCharactor,
+ PUCHAR Message,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ This function is used to display debug information.
+
+ Usage :
+ HalR94aDebugPrint(
+ (ULONG) 3,
+ "1234",
+ "Dbg : Current file is %s [%d]\n",
+ __FILE__,
+ __LINE__
+ );
+
+Arguments:
+
+ DebugLevel - Debug level for output.
+ If DebugLevel less than R94aDebugLevel, not display.
+
+ LedCharactor - Display charactor for LED.
+
+ Message - Display format for console or debug-teminal.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ va_list argp;
+ ULONG Index;
+ CHAR Buffer[100];
+
+ if (DebugLevel >= R94aDebugLevel) {
+
+ va_start(argp, Message);
+ vsprintf(Buffer, Message, argp);
+
+ if (HalpR94aDebugOutput & (1 << R94A_DBG)) { // H003
+
+ DbgPrint(Buffer);
+
+ }
+
+ if (HalpR94aDebugOutput & (1 << R94A_CON)) {
+
+ HalDisplayString(Buffer);
+
+ }
+
+ va_end(argp);
+ }
+
+ return;
+}
+/* end H001 */
+
+/* M004 +++ */
+#if defined(_PRINT_MDL_) //S006
+VOID
+HalpPrintMdl(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PLIST_ENTRY NextMd;
+ PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
+
+
+ //
+ // Get the lower bound of the free physical memory and the
+ // number of physical pages by walking the memory descriptor lists.
+ //
+
+ NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
+
+ while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
+
+ MemoryDescriptor = CONTAINING_RECORD(NextMd,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ DbgPrint("MemoryType = %d ",MemoryDescriptor->MemoryType);
+ DbgPrint("BasePage = %010x ",MemoryDescriptor->BasePage);
+ DbgPrint("PageCount = %5d\n",MemoryDescriptor->PageCount);
+
+ NextMd = MemoryDescriptor->ListEntry.Flink;
+ }
+}
+#endif // _PRINT_MDL_ // S006
+/* M004 --- */
diff --git a/private/ntos/nthals/halr96b/mips/r94adef.h b/private/ntos/nthals/halr96b/mips/r94adef.h
new file mode 100644
index 000000000..4ebbff766
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/r94adef.h
@@ -0,0 +1,266 @@
+// #pragma comment(exestr, "@(#) r94adef.h 1.1 95/09/28 15:47:51 nec")
+/*++ BUILD Version: 0005 // Increment this if a change has global effects
+
+Copyright (c) 1994 NEC Corporation
+
+Module Name:
+
+ r94adef.h
+
+Abstract:
+
+ This module is the header file that describes hardware addresses
+ for the R94A system.
+
+Author:
+
+ Akitoshi Kuriyama 23-Aug-1994
+
+Revision History:
+
+ M001 1994.8.23 A. Kuriyama
+ - Modify for R94A MIPS R4400 (original duodef.h)
+ M002 1994.9.24 A. Kuriyama
+ - Modify PCI A-D Vector Value
+ H000 Sat Sep 24 23:11:51 JST 1994 kbnes!kishimoto
+ - Add the number of PCI slots
+ ADD001 ataka@oa2.kb.nec.co.jp Mon Oct 17 17:10:13 JST 1994
+ - Add
+ #define PCI_CONTROL_PHYSICAL_BASE (EISA_CONTROL_PHYSICAL_BASE+64*1024)
+ #define PCI_MEMORY_PHYSICAL_BASE_LOW (EISA_MEMORY_VERSION2_LOW + 64*1024*1024)
+ #define PCI_MEMORY_PHYSICAL_BASE_HIGH 0x00000001
+ M003 Mon Oct 17 17:26:12 JST 1994 kbnes!kuriyama
+ name change MAXIMUN_PCI_SLOT -> R94A_PCI_SLOT
+ ADD002 ataka@oa2.kb.nec.co.jp Mon Oct 17 19:30:00 JST 1994
+ - change PCI_CONTROL_PHYSICAL_BASE, PCI_MEMORY_PHYSICAL_BASE_LOW
+ 64*1024 -> 10000 64*1024*1024 -> 4000000
+ D001 ataka@oa2.kb.nec.co.jp Sat Nov 05 16:06:26 JST 1994
+ - reduce DMA_TRANSLATION_LIMIT to 4 only for BBM DMA
+ S0004 Thu Dec 22 11:55:04 JST 1994 kbnes!A.Kuriyama
+ -add beta machine limit
+ S0005 Thu Jan 05 17:17:09 JST 1995 kbnes!A.Kuriyama
+ - warning clear
+ S0006 Thu Jan 05 18:52:51 JST 1995 kbnes!A.Kuriyama
+ - dma_limit change
+ M0007 Tue Mar 07 14:34:55 JST 1995 kbnes!kuriyama (A)
+ - expand dma logical address
+ M0008 Fri Mar 10 15:34:25 JST 1995 kbnes!kuriyama (A)
+ - expand dma logical address bug fix
+ M0009 Tue Mar 21 02:45:16 1995 kbnes!kishimoto
+ - physical base of PCI memory set to 64M
+ M0010 Tue Mar 21 03:06:05 1995 kbnes!kishimoto
+ - M0009 could not allocate memory
+ set base to zero.
+ M0011 Tue Apr 25 16:34:35 1995 kbnes!kishimoto
+ - add MRC registers
+ S0012 kuriyama@oa2.kb.nec.co.jp Mon Jun 05 01:55:08 JST 1995
+ - add NVRAM_VIRTUAL_BASE
+ M0011 Sat Aug 12 16:51:50 1995 kbnes!kishimoto
+ - rearrange the comments.
+
+--*/
+
+#ifndef _R94ADEF_
+#define _R94ADEF_
+
+//
+// ADD001,ADD002
+// Define physical base addresses for system mapping.
+//
+
+#define VIDEO_MEMORY_PHYSICAL_BASE 0x40000000 // physical base of video memory
+#define VIDEO_CONTROL_PHYSICAL_BASE 0x60000000 // physical base of video control
+#define CURSOR_CONTROL_PHYSICAL_BASE 0x60008000 // physical base of cursor control
+#define VIDEO_ID_PHYSICAL_BASE 0x60010000 // physical base of video id register
+#define VIDEO_RESET_PHYSICAL_BASE 0x60020000 // physical base of reset register
+#define DEVICE_PHYSICAL_BASE 0x80000000 // physical base of device space
+#define NET_PHYSICAL_BASE 0x80001000 // physical base of ethernet control
+#define SCSI1_PHYSICAL_BASE 0x80002000 // physical base of SCSI1 control
+#define SCSI2_PHYSICAL_BASE 0x80003000 // physical base of SCSI2 control
+#define RTCLOCK_PHYSICAL_BASE 0x80004000 // physical base of realtime clock
+#define KEYBOARD_PHYSICAL_BASE 0x80005000 // physical base of keyboard control
+#define MOUSE_PHYSICAL_BASE 0x80005000 // physical base of mouse control
+#define SERIAL0_PHYSICAL_BASE 0x80006000 // physical base of serial port 0
+#define SERIAL1_PHYSICAL_BASE 0x80007000 // physical base of serial port 1
+#define PARALLEL_PHYSICAL_BASE 0x80008000 // physical base of parallel port
+#define EISA_CONTROL_PHYSICAL_BASE 0x90000000 // physical base of EISA control
+#define EISA_MEMORY_PHYSICAL_BASE 0x91000000 // physical base of EISA memory
+#define EISA_MEMORY_VERSION2_LOW 0x00000000 // physical base of EISA memory
+#define EISA_MEMORY_VERSION2_HIGH 0x00000001 // with version 2 address chip
+#define PROM_PHYSICAL_BASE 0xfff00000 // physical base of boot PROM
+#define EEPROM_PHYSICAL_BASE 0xfff40000 // physical base of FLASH PROM
+#define PCI_CONTROL_PHYSICAL_BASE (EISA_CONTROL_PHYSICAL_BASE) // physical base of PCI control
+#define PCI_MEMORY_PHYSICAL_BASE_LOW (EISA_MEMORY_VERSION2_LOW) // physical base of PCI memory
+#define PCI_MEMORY_PHYSICAL_BASE_HIGH 0x00000001 // physical base of PCI memory
+
+//
+// S0012
+// Define virtual/physical base addresses for system mapping.
+//
+
+#define NVRAM_VIRTUAL_BASE 0xffff8000 // virtual base of nonvolatile RAM
+#define NVRAM_PHYSICAL_BASE 0x80009000 // physical base of nonvolatile RAM
+
+#define SP_VIRTUAL_BASE 0xffffa000 // virtual base of serial port 0
+#define SP_PHYSICAL_BASE SERIAL0_PHYSICAL_BASE // physical base of serial port 0
+
+#define DMA_VIRTUAL_BASE 0xffffc000 // virtual base of DMA control
+#define DMA_PHYSICAL_BASE DEVICE_PHYSICAL_BASE // physical base of DMA control
+
+#define INTERRUPT_VIRTUAL_BASE 0xffffd000 // virtual base of interrupt source
+#define INTERRUPT_PHYSICAL_BASE 0x8000f000 // physical base of interrupt source
+
+//
+// Define the size of the DMA translation table.
+//
+
+#if defined (_BBM_DMA_) // D001,S0004,S0005,S0006
+
+#define DMA_TRANSLATION_LIMIT (sizeof(TRANSLATION_ENTRY) * 8 * 4) // translation table limit
+
+#else
+
+#if defined(_DMA_EXPAND_) // M0007,M0008
+
+#define ISA_MAX_ADR 0x400000L // ISA MAX Logical Address
+#define EISA_MIN_ADR 0x1000000L // EISA/PCI MIN Logical Address
+#define EISA_MAX_ADR 0x2000000L // EISA/PCI MAX Logical Address
+#define DMA_TRANSLATION_LIMIT (EISA_MAX_ADR / PAGE_SIZE * sizeof(TRANSLATION_ENTRY) )
+ // translation table limit
+#else // _DMA_EXPAND_
+
+#define DMA_TRANSLATION_LIMIT 0x2000 // translation table limit
+
+#endif // _DMA_EXPAND_
+
+#endif // (_BBM_DMA_)
+
+
+//
+// Define the maximum number of map registers allowed per allocation.
+//
+
+#define DMA_REQUEST_LIMIT (DMA_TRANSLATION_LIMIT/(sizeof(TRANSLATION_ENTRY) * 8))
+
+//
+// Define pointer to DMA control registers.
+//
+
+#define DMA_CONTROL ((volatile PDMA_REGISTERS)(DMA_VIRTUAL_BASE))
+
+//
+// Define DMA channel interrupt level.
+//
+
+#define DMA_LEVEL 3
+
+//
+// Define the minimum and maximum system time increment values in 100ns units.
+//
+
+#define MAXIMUM_INCREMENT (10 * 1000 * 10)
+#define MINIMUM_INCREMENT (1 * 1000 * 10)
+
+//
+// Define Duo clock level.
+//
+
+#define CLOCK_LEVEL 6 // Interval clock level
+#define CLOCK_INTERVAL ((MAXIMUM_INCREMENT / (10 * 1000)) - 1) // Ms minus 1
+#define CLOCK2_LEVEL CLOCK_LEVEL //
+
+//
+// Define EISA device level.
+//
+
+#define EISA_DEVICE_LEVEL 5 // EISA bus interrupt level
+
+//
+// Define EISA device interrupt vectors.
+//
+
+#define EISA_VECTORS 32
+
+#define IRQL10_VECTOR (10 + EISA_VECTORS) // Eisa interrupt request level 10
+#define IRQL11_VECTOR (11 + EISA_VECTORS) // Eisa interrupt request level 11
+#define IRQL12_VECTOR (12 + EISA_VECTORS) // Eisa interrupt request level 12
+#define IRQL13_VECTOR (13 + EISA_VECTORS) // Eisa interrupt request level 13
+
+#define MAXIMUM_EISA_VECTOR (15 + EISA_VECTORS) // maximum EISA vector
+
+//
+// Define I/O device interrupt level.
+//
+
+#define DEVICE_LEVEL 4 // I/O device interrupt level
+
+//
+// Define device interrupt vectors.
+//
+
+#define DEVICE_VECTORS 16 // starting builtin device vector
+
+#define PARALLEL_VECTOR (1 + DEVICE_VECTORS) // Parallel device interrupt vector
+//#define VIDEO_VECTOR (3 + DEVICE_VECTORS) // video device interrupt vector
+#define AUDIO_VECTOR (3 + DEVICE_VECTORS) // audio device interrupt vector
+#define NET_VECTOR (4 + DEVICE_VECTORS) // ethernet device interrupt vector
+#define SCSI1_VECTOR (5 + DEVICE_VECTORS) // SCSI device interrupt vector
+#define SCSI2_VECTOR (6 + DEVICE_VECTORS) // SCSI device interrupt vector
+#define KEYBOARD_VECTOR (7 + DEVICE_VECTORS) // Keyboard device interrupt vector
+#define MOUSE_VECTOR (8 + DEVICE_VECTORS) // Mouse device interrupt vector
+#define SERIAL0_VECTOR (9 + DEVICE_VECTORS) // Serial device 0 interrupt vector
+#define SERIAL1_VECTOR (10 + DEVICE_VECTORS) // Serial device 1 interrupt vector
+#define TYPHOON_ERROR_INTERRUPT_VECTOR (15 + DEVICE_VECTORS) // TYPHOON error vector
+//#define MAXIMUM_BUILTIN_VECTOR SERIAL1_VECTOR // maximum builtin vector
+#define MAXIMUM_BUILTIN_VECTOR TYPHOON_ERROR_INTERRUPT_VECTOR // maximum builtin vector
+
+//
+// M0001,M0002
+// Define PCI device interrupt vectors.
+//
+
+#define PCI_VECTORS 80
+//#define INTERRUPT_D_VECTOR (0 + PCI_VECTORS)
+//#define INTERRUPT_C_VECTOR (1 + PCI_VECTORS)
+//#define INTERRUPT_B_VECTOR (2 + PCI_VECTORS)
+//#define INTERRUPT_A_VECTOR (3 + PCI_VECTORS)
+//#define MAXIMUM_PCI_VECTOR INTERRUPT_A_VECTOR
+
+//
+// Define the clock speed in megahetz for the SCSI protocol chips.
+//
+
+#define NCR_SCSI_CLOCK_SPEED 24
+
+//
+// PROM entry point definitions.
+//
+// Define base address of prom entry vector and prom entry macro.
+//
+
+#define PROM_BASE (KSEG1_BASE | 0x1fc00000)
+#define PROM_ENTRY(x) (PROM_BASE + ((x) * 8))
+
+//
+// H000,M003
+// the number of lines which PCI interrupts.
+//
+
+#define R94A_PCI_SLOT 3
+
+//
+// M0011
+// Define pointer to MRC control registers.
+//
+
+#define MRC_CONTROL ((volatile PMRC_REGISTERS)(DMA_VIRTUAL_BASE))
+
+//
+// M0011
+// Define physical base addresses for system mapping.
+//
+
+#define MRC_TEMP_PHYSICAL_BASE 0x80012000 // physical base of MRC and TEMP sensor
+
+#endif // _R94ADEF_
+
diff --git a/private/ntos/nthals/halr96b/mips/r94adma.h b/private/ntos/nthals/halr96b/mips/r94adma.h
new file mode 100644
index 000000000..5d8676ebb
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/r94adma.h
@@ -0,0 +1,433 @@
+// #pragma comment(exestr, "@(#) r94adma.h 1.1 95/09/28 15:48:23 nec")
+/*++ BUILD Version: 0001 // Increment this if a change has global effects
+
+Copyright (c) 1994 NEC Corporation
+
+Module Name:
+
+ r94adma.h
+
+Abstract:
+
+ This module is the header file that describes the DMA control register
+ structure for the R94A system.
+
+Author:
+
+ David N. Cutler (davec) 13-Nov-1990
+
+Revision History:
+
+ M001 1994.8.24 A. Kuriyama
+ - Modify for R94A MIPS R4400 (original duodma.h)
+ H000 Sat Sep 24 21:36:20 JST 1994 kbnes!kishimoto
+ - Add PCIInterruptStatus register structure definition
+ M002 Mon Oct 03 19:52:16 JST 1994 kbnes!kuriyama(A)
+ - Add PCI(HURRICANE) register
+ - Change InvalidAddress register to DMA_LARGE_REGISTER
+ - Change RTC_REGISTER structure define.
+ - add Optional... registers
+ H001 Fri Dec 9 18:29:10 1994 kbnes!kishimoto
+ - Modify LEDControl definition (SHORT -> CHAR)
+ H002 Tue Jan 24 18:24:48 1995 kbnes!kishimoto
+ - Add PCI interrupt enable bits definitions.
+ H003 Tue Apr 25 16:38:06 1995 kbnes!kishimoto
+ - Add MRC registers
+ H004 Sat Aug 12 16:18:53 1995 kbnes!kishimoto
+ - rearrange comments.
+
+--*/
+
+#ifndef _R94ADMA_
+#define _R94ADMA_
+
+//
+// M001
+// Define DMA register structures.
+//
+
+typedef struct _DMA_REGISTER {
+ ULONG Long;
+ ULONG Fill;
+} DMA_REGISTER, *PDMA_REGISTER;
+
+typedef struct _DMA_CHAR_REGISTER {
+ UCHAR Char;
+ UCHAR Fill;
+ USHORT Fill2;
+} DMA_CHAR_REGISTER, *PDMA_CHAR_REGISTER;
+
+typedef struct _DMA_SHORT_REGISTER {
+ USHORT Short;
+ USHORT Fill;
+} DMA_SHORT_REGISTER, *PDMA_SHORT_REGISTER;
+
+typedef struct _DMA_LARGE_REGISTER {
+ union {
+ LARGE_INTEGER LargeInteger;
+ double Double;
+ } u;
+} DMA_LARGE_REGISTER, *PDMA_LARGE_REGISTER;
+
+//
+// Define DMA channel register structure.
+//
+
+typedef struct _DMA_CHANNEL {
+ DMA_REGISTER Mode;
+ DMA_REGISTER Enable;
+ DMA_REGISTER ByteCount;
+ DMA_REGISTER Address;
+} DMA_CHANNEL, *PDMA_CHANNEL;
+
+//
+// M002
+// Define PCI Address/Mask register structure
+//
+
+typedef struct _PCI_ADDRESS_MASK {
+ ULONG Address;
+ ULONG Mask;
+} PCI_ADDRESS_MASK, *PPCI_ADDRESS_MASK;
+
+//
+// Define DMA control register structure.
+//
+
+typedef volatile struct _DMA_REGISTERS {
+ DMA_REGISTER Configuration; // offset 000
+ DMA_REGISTER RevisionLevel; // offset 008
+ DMA_REGISTER RemoteFailedAddress; // offset 010
+ DMA_REGISTER MemoryFailedAddress; // offset 018
+ DMA_LARGE_REGISTER InvalidAddress; // offset 020 // M002
+ DMA_REGISTER TranslationBase; // offset 028
+ DMA_REGISTER TranslationLimit; // offset 030
+ DMA_REGISTER TranslationInvalidate; // offset 038
+ DMA_REGISTER ChannelInterruptAcknowledge; // offset 040
+ DMA_REGISTER LocalInterruptAcknowledge; // offset 048
+ DMA_REGISTER EisaInterruptAcknowledge; // offset 050
+ DMA_REGISTER TimerInterruptAcknowledge; // offset 058
+ DMA_REGISTER IpInterruptAcknowledge; // offset 060
+ DMA_REGISTER Reserved1; // offset 068
+ DMA_REGISTER WhoAmI; // offset 070
+ DMA_REGISTER NmiSource; // offset 078
+ DMA_REGISTER RemoteSpeed[15]; // offset 080
+ DMA_REGISTER InterruptEnable; // offset 0f8
+ DMA_CHANNEL Channel[4]; // offset 100
+ DMA_REGISTER ArbitrationControl; // offset 180
+ DMA_REGISTER Errortype; // offset 188
+ DMA_REGISTER RefreshRate; // offset 190
+ DMA_REGISTER RefreshCounter; // offset 198
+ DMA_REGISTER SystemSecurity; // offset 1a0
+ DMA_REGISTER InterruptInterval; // offset 1a8
+ DMA_REGISTER IntervalTimer; // offset 1b0
+ DMA_REGISTER IpInterruptRequest; // offset 1b8
+ DMA_REGISTER InterruptDiagnostic; // offset 1c0
+ DMA_LARGE_REGISTER EccDiagnostic; // offset 1c8
+ DMA_REGISTER MemoryConfig[4]; // offset 1d0
+ DMA_REGISTER Reserved2;
+ DMA_REGISTER Reserved3;
+ DMA_LARGE_REGISTER IoCacheBuffer[64]; // offset 200
+ DMA_REGISTER IoCachePhysicalTag[8]; // offset 400
+ DMA_REGISTER IoCacheLogicalTag[8]; // offset 440
+ DMA_REGISTER IoCacheLowByteMask[8]; // offset 480
+ DMA_REGISTER IoCacheHighByteMask[8]; // offset ??? wrong?
+
+ //
+ // M001,M002,H001
+ // new registers of STORM-chipset
+ //
+
+ DMA_REGISTER ProcessorBootModeControl; // offset 500
+ DMA_REGISTER ClockCounter; // offset 508
+ DMA_REGISTER MemoryTimingControl; // offset 510
+ DMA_REGISTER PCIConfigurationAddress; // offset 518
+ DMA_REGISTER PCIConfigurationData; // offset 520
+ DMA_REGISTER PCISpecialCycle; // offset 528
+ DMA_REGISTER PCIInterruptEnable; // offset 530
+ DMA_REGISTER PCIInterruptStatus; // offset 538
+ DMA_REGISTER CopyTagConfiguration; // offset 540
+ DMA_REGISTER CopyTagAddress; // offset 548
+ DMA_REGISTER CopyTagData; // offset 550
+ DMA_REGISTER ASIC2Revision; // offset 558
+ DMA_REGISTER ASIC3Revision; // offset 560
+ DMA_REGISTER Reserved4; // offset 568
+ ULONG OptionalRemoteSpeed1; // offset 570
+ ULONG OptionalRemoteSpeed2; // offset 574
+ ULONG OptionalRemoteSpeed3; // offset 578
+ ULONG OptionalRemoteSpeed4; // offset 57c
+ DMA_REGISTER LocalInterruptAcknowledge2; // offset 580
+ DMA_REGISTER OptionalIoConfiguration1; // offset 588
+ DMA_REGISTER OptionalIoConfiguration2; // offset 590
+ DMA_REGISTER OptionalIoConfiguration3; // offset 598
+ DMA_REGISTER OptionalIoConfiguration4; // offset 5a0
+ DMA_SHORT_REGISTER BuzzerCount; // offset 5a8
+ DMA_CHAR_REGISTER BuzzerControl; // offset 5ac
+ DMA_SHORT_REGISTER LEDCount; // offset 5b0
+ DMA_CHAR_REGISTER LEDControl; // offset 5b4
+ DMA_SHORT_REGISTER NECIoPort; // offset 5b8
+ ULONG TyphoonErrorStatus; // offset 5bc
+ DMA_REGISTER AddressConversionRegion; // offset 5c0
+ DMA_REGISTER AddressConversionMask; // offset 5c8
+ DMA_REGISTER Reserved12; // offset 5d0
+ DMA_REGISTER Reserved13; // offset 5d8
+ DMA_REGISTER Reserved14; // offset 5e0
+ DMA_REGISTER Reserved15; // offset 5e8
+ DMA_REGISTER Reserved16; // offset 5f0
+ DMA_REGISTER Reserved17; // offset 5f8
+ USHORT PCIVenderID; // offset 600
+ USHORT PCIDeviceID; // offset 602
+ USHORT PCICommand; // offset 604
+ USHORT PCIStatus; // offset 606
+ UCHAR PCIRevisionID; // offset 608
+ UCHAR PCIProgIf; // offset 609
+ UCHAR PCISubClass; // offset 60a
+ UCHAR PCIBaseClass; // offset 60b
+ UCHAR PCICacheLineSize; // offset 60c
+ UCHAR PCILatencyTimer; // offset 60d
+ UCHAR PCIHeaderType; // offset 60e
+ UCHAR PCIBIST; // offset 60f
+ DMA_REGISTER Reserved18; // offset 610
+ DMA_REGISTER Reserved19; // offset 618
+ DMA_REGISTER Reserved20; // offset 620
+ DMA_REGISTER Reserved21; // offset 628
+ ULONG PCIROMBaseAddress; // offset 630
+ ULONG Reserved22[2]; // offset 634
+ UCHAR PCIInterruptLine; // offset 63c
+ UCHAR PCIInterruptPin; // offset 63d
+ UCHAR PCIMinimumGrant; // offset 63e
+ UCHAR PCIMaximumLatency; // offset 63f
+ PCI_ADDRESS_MASK PCIFastBackToBack[2]; // offset 640
+ PCI_ADDRESS_MASK PCIBurst[2]; // offset 650
+ PCI_ADDRESS_MASK PCIMemory; // offset 660
+ ULONG PCIMasterRetryTimer; // offset 668
+} DMA_REGISTERS, *PDMA_REGISTERS;
+
+//
+// Configuration Register values.
+//
+
+#define LOAD_CLEAN_EXCLUSIVE 0x20
+#define DISABLE_EISA_MEMORY 0x10
+#define ENABLE_PROCESSOR_B 0x08
+#define MAP_PROM 0x04
+
+//
+// Interrupt Enable bits.
+//
+#define ENABLE_CHANNEL_INTERRUPTS (1 << 0)
+#define ENABLE_DEVICE_INTERRUPTS (1 << 1)
+#define ENABLE_EISA_INTERRUPTS (1 << 2)
+#define ENABLE_TIMER_INTERRUPTS (1 << 3)
+#define ENABLE_IP_INTERRUPTS (1 << 4)
+
+//
+// Eisa Interupt Acknowledge Register values.
+//
+
+#define EISA_NMI_VECTOR 0x8000
+
+//
+// DMA_NMI_SRC register bit definitions.
+//
+
+#define NMI_SRC_MEMORY_ERROR 1
+#define NMI_SRC_R4000_ADDRESS_ERROR 2
+#define NMI_SRC_IO_CACHE_ERROR 4
+#define NMI_SRC_ADR_NMI 8
+
+//
+// Define DMA channel mode register structure.
+//
+
+typedef struct _DMA_CHANNEL_MODE {
+ ULONG AccessTime : 3;
+ ULONG TransferWidth : 2;
+ ULONG InterruptEnable : 1;
+ ULONG BurstMode : 1;
+ ULONG Reserved1 : 25;
+} DMA_CHANNEL_MODE, *PDMA_CHANNEL_MODE;
+
+//
+// Define access time values.
+//
+
+#define ACCESS_40NS 0x0 // 40ns access time
+#define ACCESS_80NS 0x1 // 80ns access time
+#define ACCESS_120NS 0x2 // 120ns access time
+#define ACCESS_160NS 0x3 // 160ns access time
+#define ACCESS_200NS 0x4 // 200ns access time
+#define ACCESS_240NS 0x5 // 240ns access time
+#define ACCESS_280NS 0x6 // 280ns access time
+#define ACCESS_320NS 0x7 // 320ns access time
+
+//
+// Define transfer width values.
+//
+
+#define WIDTH_8BITS 0x1 // 8-bit transfer width
+#define WIDTH_16BITS 0x2 // 16-bit transfer width
+#define WIDTH_32BITS 0x3 // 32-bit transfer width
+
+//
+// M001
+// Define DMA channel enable register structure.
+//
+
+typedef struct _DMA_CHANNEL_ENABLE {
+ ULONG ChannelEnable : 1;
+ ULONG TransferDirection : 1;
+ ULONG Reserved1 : 6;
+ ULONG TerminalCount : 1;
+ ULONG MemoryError : 1;
+// ULONG TranslationError : 1;
+// ULONG Reserved2 : 21;
+ ULONG ParityError : 1;
+ ULONG MasterAbort : 1;
+ ULONG Reserved2 : 20;
+} DMA_CHANNEL_ENABLE, *PDMA_CHANNEL_ENABLE;
+
+//
+// M001,M002
+// define RTC structure.
+//
+
+typedef struct _RTC_REGISTERS {
+ UCHAR Data;
+ UCHAR Index;
+} RTC_REGISTERS, *PRTC_REGISTERS;
+
+//
+// Define transfer direction values.
+//
+
+#define DMA_READ_OP 0x0 // read from device
+#define DMA_WRITE_OP 0x1 // write to device
+
+//
+// Define translation table entry structure.
+//
+
+typedef volatile struct _TRANSLATION_ENTRY {
+ ULONG PageFrame;
+ ULONG Fill;
+} TRANSLATION_ENTRY, *PTRANSLATION_ENTRY;
+
+//
+// Error Type Register values
+//
+
+#define SONIC_ADDRESS_ERROR 4
+#define SONIC_MEMORY_ERROR 0x40
+#define EISA_ADDRESS_ERROR 1
+#define EISA_MEMORY_ERROR 2
+
+//
+// Address Mask definitions.
+//
+
+#define LFAR_ADDRESS_MASK 0xfffff000
+#define RFAR_ADDRESS_MASK 0x00ffffc0
+#define MFAR_ADDRESS_MASK 0x1ffffff0
+
+//
+// ECC Register Definitions.
+//
+
+#define ECC_SINGLE_BIT_DP0 0x02000000
+#define ECC_SINGLE_BIT_DP1 0x20000000
+#define ECC_SINGLE_BIT ( ECC_SINGLE_BIT_DP0 | ECC_SINGLE_BIT_DP1 )
+#define ECC_DOUBLE_BIT_DP0 0x04000000
+#define ECC_DOUBLE_BIT_DP1 0x40000000
+#define ECC_DOUBLE_BIT ( ECC_DOUBLE_BIT_DP0 | ECC_DOUBLE_BIT_DP1 )
+#define ECC_MULTIPLE_BIT_DP0 0x08000000
+#define ECC_MULTIPLE_BIT_DP1 0x80000000
+
+#define ECC_FORCE_DP0 0x010000
+#define ECC_FORCE_DP1 0x100000
+#define ECC_DISABLE_SINGLE_DP0 0x020000
+#define ECC_DISABLE_SINGLE_DP1 0x200000
+#define ECC_ENABLE_DP0 0x040000
+#define ECC_ENABLE_DP1 0x400000
+
+//
+// LED/DIAG Register Definitions.
+//
+
+#define DIAG_NMI_SWITCH 2
+
+//
+// Common error bit definitions
+//
+
+#define SINGLE_ERROR 1
+#define MULTIPLE_ERROR 2
+#define RFAR_CACHE_FLUSH 4
+
+//
+// M001
+// Define NMI Status/Control register structure.
+//
+
+typedef struct _BUZZER_CONTROL {
+ UCHAR SpeakerGate : 1;
+ UCHAR SpeakerData : 1;
+ UCHAR Reserved1 : 3;
+ UCHAR SpeakerTimer : 1;
+ UCHAR Reserved2 : 2;
+}BUZZER_CONTROL, *PBUZZER_CONTROL;
+
+//
+// H000
+// Define PCI Interrupt Status register structure.
+//
+
+typedef struct _STORM_PCI_INTRRUPT_STATUS{
+ ULONG IntD: 1;
+ ULONG IntC: 1;
+ ULONG IntB: 1;
+ ULONG IntA: 1;
+ ULONG Perr: 1;
+ ULONG Serr: 1;
+ ULONG RetryOverflow: 1;
+ ULONG MasterAbort: 1;
+ ULONG TargetAbort: 1;
+ ULONG Reserved: 23;
+} STORM_PCI_INTRRUPT_STATUS, *PSTORM_PCI_INTRRUPT_STATUS;
+
+//
+// H002
+// PCI Interrupt Enable bits.
+//
+
+#define ENABLE_TARGET_ABORT_INTERRUPTS (1 << 8)
+#define ENABLE_MASTER_ABORT_INTERRUPTS (1 << 7)
+#define ENABLE_RETRY_OVERFLOW_EISA_INTERRUPTS (1 << 6)
+#define ENABLE_SERR_INTERRUPTS (1 << 5)
+#define ENABLE_PERR_INTERRUPTS (1 << 4)
+
+//
+// H003
+// Define MRC control register structure.
+//
+
+typedef volatile struct _MRC_REGISTERS {
+ UCHAR Reserved1[256]; // offset 000
+ UCHAR Interrupt; // offset 100
+ UCHAR Reserved2[7]; // offset 107
+ UCHAR Mode; // offset 108
+ UCHAR Reserved3[39]; // offset 109
+ UCHAR SoftwarePowerOff; // offset 130
+ UCHAR Reserved4[15]; // offset 131
+ UCHAR LEDBitControl; // offset 140
+ UCHAR Reserved5[3]; // offset 141
+ UCHAR SegmentLEDControl[4]; // offset 144
+ UCHAR Reserved6[155]; // offset 145
+ UCHAR TempEnable; // offset 1e0
+ UCHAR Reserved7[31]; // offset 145
+ UCHAR TempSensor; // offset 200
+ UCHAR Reserved8[3583]; // offset 201
+} MRC_REGISTERS, *PMRC_REGISTERS;
+
+
+#endif // _R94ADMA_
diff --git a/private/ntos/nthals/halr96b/mips/r94ainfo.c b/private/ntos/nthals/halr96b/mips/r94ainfo.c
new file mode 100644
index 000000000..a2c59341b
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/r94ainfo.c
@@ -0,0 +1,99 @@
+// #pragma comment(exestr, "@(#) r94ainfo.c 1.1 95/09/28 15:48:57 nec")
+/*++
+
+Copyright (C) 1991-1995 Microsoft Corporation
+All rights reserved.
+
+Module Name:
+
+ ixinfo.c
+
+Abstract:
+
+Environment:
+
+ Kernel mode only.
+
+Revision History
+
+ A002 1995/6/17 ataka@oa2.kb.nec.co.jp
+ - Marge 807-halr98mp-ixinfo.h to 1050-halx86-r98info.h
+
+--*/
+
+
+#include "halp.h"
+
+NTSTATUS
+HalpQueryInstalledBusInformation (
+ OUT PVOID Buffer,
+ IN ULONG BufferLength,
+ OUT PULONG ReturnedLength
+ );
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE,HaliQuerySystemInformation)
+#pragma alloc_text(PAGE,HaliSetSystemInformation)
+#endif
+
+NTSTATUS
+HaliQuerySystemInformation(
+ IN HAL_QUERY_INFORMATION_CLASS InformationClass,
+ IN ULONG BufferSize,
+ OUT PVOID Buffer,
+ OUT PULONG ReturnedLength
+ )
+{
+ NTSTATUS Status;
+ PVOID InternalBuffer;
+ ULONG Length;
+
+ PAGED_CODE();
+
+ Status = STATUS_SUCCESS;
+ *ReturnedLength = 0;
+ Length = 0;
+
+ switch (InformationClass) {
+ case HalInstalledBusInformation:
+ Status = HalpQueryInstalledBusInformation (
+ Buffer,
+ BufferSize,
+ ReturnedLength
+ );
+ break;
+
+ default:
+ Status = STATUS_INVALID_LEVEL;
+ break;
+ }
+
+ //
+ // If non-zero Length copy data to callers buffer
+ //
+
+ if (Length) {
+ if (BufferSize < Length) {
+ Length = BufferSize;
+ }
+
+ *ReturnedLength = Length;
+ RtlCopyMemory (Buffer, InternalBuffer, Length);
+ }
+
+ return Status;
+}
+
+NTSTATUS
+HaliSetSystemInformation (
+ IN HAL_SET_INFORMATION_CLASS InformationClass,
+ IN ULONG BufferSize,
+ IN PVOID Buffer
+ )
+{
+ PAGED_CODE();
+ return STATUS_INVALID_LEVEL;
+}
+
+
diff --git a/private/ntos/nthals/halr96b/mips/r94aint.h b/private/ntos/nthals/halr96b/mips/r94aint.h
new file mode 100644
index 000000000..6904b9a85
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/r94aint.h
@@ -0,0 +1,35 @@
+// #pragma comment(exestr, "@(#) r94aint.h 1.1 95/09/28 15:49:28 nec")
+/*++ BUILD Version: 0001 // Increment this if a change has global effects
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ duoint.h
+
+Abstract:
+
+ This module is the header file that describes hardware structure
+ for the interrupt source and enable registers on the DUO system.
+
+Author:
+
+ Lluis Abello (lluis) 20-Apr-1993
+
+Revision History:
+
+--*/
+
+#ifndef _DUOINT_
+#define _DUOINT_
+
+//
+// Define Interrupt register structure.
+//
+
+typedef struct _INTERRUPT_REGISTERS {
+ USHORT Fill;
+ USHORT Enable;
+} INTERRUPT_REGISTERS, *PINTERRUPT_REGISTERS;
+
+#endif // _DUOINT_
diff --git a/private/ntos/nthals/halr96b/mips/r94aio.s b/private/ntos/nthals/halr96b/mips/r94aio.s
new file mode 100644
index 000000000..fed2171e2
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/r94aio.s
@@ -0,0 +1,149 @@
+// .ident "@(#) r94aio.s 1.1 95/09/28 18:36:07 nec"
+//++
+//
+// Copyright (c) 1994 KOBE NEC Software Corporation
+//
+// Module Name:
+//
+// r94aio.s
+//
+// Abstract:
+//
+// This module implements the system dependent kernel function to read
+// and write the 64-bit register on a MIPS R4000 R94A system.
+//
+// Author:
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+// H000 Fri Oct 7 19:57:09 JST 1994 kbnes!kisimoto
+// new READ_REGISTER_DWORD
+// new WRITE_REGISTER_DWORD
+//
+//--
+
+#if defined(_R94A_)
+
+#include "halmips.h"
+
+//++
+//
+// VOID
+// READ_REGISTER_DWORD (
+// IN PLARGE_INTEGER RegisterAddress,
+// IN PVOID Variable
+// )
+//
+// Routine Description:
+//
+// 64-bit I/O space register read function.
+//
+// Arguments:
+//
+// RegisterAddress (a0) - Supplies a pointer to the destination address of
+// the move operation.
+//
+// Variable (a1) - Supplies a pointer to the source address of the move
+// operation.
+//
+// Return Value:
+//
+// None.
+//
+// Destination and Source must be 8-byte aligned.
+//
+//--
+
+ LEAF_ENTRY(READ_REGISTER_DWORD)
+
+ ldc1 f0,0(a0) // move 8-byte block
+ sdc1 f0,0(a1) //
+
+ sync // synchronize read
+
+ j ra // return
+
+ .end READ_REGISTER_DWORD
+
+
+//++
+//
+// VOID
+// WRITE_REGISTER_DWORD (
+// IN PLARGE_INTEGER RegisterAddress,
+// IN PVOID Variable
+// )
+//
+// Routine Description:
+//
+// 64-bit I/O space register write function.
+//
+// Arguments:
+//
+// RegisterAddress (a0) - Supplies a pointer to the destination address of
+// the move operation.
+//
+// Variable (a1) - Supplies a pointer to the source address of the move
+// operation.
+//
+// Return Value:
+//
+// None.
+//
+// Destination and Source must be 8-byte aligned.
+//
+//--
+
+ LEAF_ENTRY(WRITE_REGISTER_DWORD)
+
+ ldc1 f0,0(a1) // move 8-byte block
+ sdc1 f0,0(a0) //
+
+ sync // synchronize write
+
+ j ra // return
+
+ .end WRITE_REGISTER_DWORD
+
+
+//++
+//
+// VOID
+// HalpGetStatusRegister (
+// IN PULONG Variable
+// )
+//
+// Routine Description:
+//
+// This function returns value which is status register of R4400.
+//
+// Arguments:
+//
+// Variable (a0) - Supplies a pointer to the destination address of
+// the move operation.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpGetStatusRegister)
+
+ .set noreorder
+ .set noat
+ mfc0 t0,psr // get current processor status
+ nop // 1 cycle hazzard
+ sw t0,0(a0) // save integer registers a0 - a3
+ .set at
+ .set reorder
+
+ j ra // return
+
+ .end HalpGetStatusRegister
+
+#endif
diff --git a/private/ntos/nthals/halr96b/mips/r94anmi.s b/private/ntos/nthals/halr96b/mips/r94anmi.s
new file mode 100644
index 000000000..b0f87aabb
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/r94anmi.s
@@ -0,0 +1,621 @@
+/* #pragma comment(exestr, "@(#) NEC(MIPS) r94anmi.s 1.2 95/10/17 01:19:11" ) */
+//
+// TITLE("R94A NMI routine")
+//++
+//
+// Copyright (c) 1995 NEC Corporation
+//
+// Module Name:
+//
+// r94anmi.s
+//
+// Abstract:
+//
+// This routine support for dump switch.
+//
+// Author:
+//
+// Akitoshi Kuriyama (NEC Software Kobe,Inc)
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// R4400 based only.
+//
+// Revision History:
+//
+// kuriyama@oa2.kbnes.nec.co.jp Sun Oct 15 20:11:38 JST 1995
+// - new code for J94D (!_MRCDUMP_ _MRCPOWER_ compile option need)
+//
+//--
+#include "halmips.h"
+
+ SBTTL("NMI dispatch routine")
+//++
+//
+// VOID
+// HalpNMIDispatch (
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function was called by firmware when NMI occuerd.
+//
+// Arguments:
+//
+// none.
+//
+// Return Value:
+//
+// none.
+//
+//--
+
+ LEAF_ENTRY(HalpNMIDispatch)
+
+ .set noreorder
+ .set noat
+
+//
+// Save temporary Registers for use.
+// save area shoud have for every processros.
+//
+
+ li k0,0xffffc070 // get processor number.
+ lw k0,(k0) //
+ bne k0,zero,10f //
+ nop // fill
+
+ la k1,HalpNMISave0 // set save address.
+ j 20f //
+ nop // fill
+
+10:
+ la k1,HalpNMISave1 // set save address.
+ nop // 1 cycle hazzerd
+
+20:
+ sw AT,0x0(k1) // register save.
+ sw v0,0x4(k1) //
+ sw v1,0x8(k1) //
+ sw a0,0xc(k1) //
+ sw a1,0x10(k1) //
+ sw a2,0x14(k1) //
+ sw a3,0x18(k1) //
+ sw t0,0x1c(k1) //
+ sw t1,0x20(k1) //
+ sw t2,0x24(k1) //
+ sw t3,0x28(k1) //
+ sw t4,0x2c(k1) //
+ sw t5,0x30(k1) //
+ sw t6,0x34(k1) //
+ sw t7,0x38(k1) //
+ sw t8,0x3c(k1) //
+ sw t9,0x40(k1) //
+ sw gp,0x44(k1) //
+ sw sp,0x48(k1) //
+ sw s8,0x4c(k1) //
+ sw ra,0x50(k1) //
+ mfc0 k0,psr //
+ nop //
+ nop //
+ sw k0,0x54(k1) //
+ nop //
+ mfc0 k0,cause //
+ nop //
+ nop //
+ sw k0,0x58(k1) //
+ nop //
+ mfc0 k0,epc //
+ nop //
+ nop //
+ sw k0,0x5c(k1) //
+ nop //
+ mfc0 k0,errorepc //
+ nop //
+ nop //
+ sw k0,0x60(k1) //
+ nop //
+ mfc0 k0,cacheerr //
+ nop //
+ nop //
+ sw k0,0x64(k1) //
+
+ sdc1 f0,0x68(k1) //
+
+//
+// Set Dump Switch Status register to tlb fixed entry
+//
+
+ li t0,4 // set index 4(hurricane register)
+ li t1,0x80012 << 6 // set MRC register
+ li t2,0x8000e << 6 // set Self-Test address
+
+ mfc0 t3,index // save tlb registers
+ mfc0 t4,entryhi //
+ mfc0 t5,entrylo0 //
+ mfc0 t6,entrylo1 //
+ mfc0 t7,pagemask //
+ mtc0 t0,index //
+ nop
+ nop
+ nop
+
+ tlbr // read index 4 tlb
+ nop
+ nop
+ nop
+ nop
+
+ mfc0 t8,entrylo0 // Get entrylo0
+ mfc0 t9,entrylo1 // Get entrylo1
+ nop
+ nop
+ nop
+ or t1,t8,t1 // set MRC address
+ or t2,t8,t2 // set Self-test address
+ nop
+
+ mtc0 t1,entrylo0 // set MRC to tlb 4 0
+ mtc0 t2,entrylo1 // set Self-test to tlb 4 1
+ nop //
+ nop //
+ nop //
+ nop //
+
+ tlbwi // write to tlb entry
+ nop //
+ nop //
+ nop //
+ nop //
+
+//
+// read dump status
+//
+
+#if defined(_MRCDUMP_)
+
+ li t1,0xffffc108 // load MRC Mode value
+
+#else // SELFTEST DUMP
+
+ li t1,0xffffd000 // load Self-Test value
+
+ li k0,0x1b // set dash
+ sb k0,(t1) // display led
+ sync
+
+#endif // _MRCDUMP_
+
+ lb k0,(t1) // load Dump switch status.
+ nop //
+ lb k0,(t1) // wait
+ nop //
+
+//
+// Check dump status
+//
+
+ li t1,2 // check for dump switch
+ and k0,k0,t1 //
+
+#if defined(_MRCDUMP_)
+ beq k0,zero,30f // if 0 dump swith was not pressed
+#else // _MRCDUMP_
+ bne k0,zero,30f // if 0 dump swith was pressed
+#endif // _MRCDUMP_
+ nop //
+
+#if !defined(_MRCDUMP_)
+ li t1,0xffffd000 // set dump switch status address
+ li t2,0x1b // display LED dash
+ sb t2,(t1) //
+ sync //
+#endif // not _MRCDUMP_
+
+//
+// enable powoff NMI
+//
+
+#if defined(_MRCPOWER_)
+ li t1,0xffffc108 //
+ li t0,0x82 //
+ nop //
+ sb t0,(t1) //
+ nop //
+ li t0,0x80 //
+ nop //
+ sb t0,(t1) //
+ nop //
+ li t0,0x02 //
+ nop //
+ sb t0,(t1) //
+ nop //
+#endif // _MRCPOWER_
+
+//
+// restore tlb 4 entry
+//
+
+ mtc0 t8,entrylo0 // restore tlb 4 0
+ mtc0 t9,entrylo1 // restore tlb 4 1
+ nop //
+ nop //
+ nop //
+ nop //
+
+ tlbwi // write to tlb entry
+ nop //
+ nop //
+ nop //
+ nop //
+
+//
+// restore tlb registers
+//
+ mtc0 t3,index //
+ mtc0 t4,entryhi //
+ mtc0 t5,entrylo0 //
+ mtc0 t6,entrylo1 //
+ mtc0 t7,pagemask //
+
+#if !defined(_MRCDUMP_)
+ la k0,0xffffc5b8 // get NEC I/O port value
+ lb t0,(k0) //
+ nop // 1 cycle hazzerd
+ li t1,0xfd // clear dump enable bit
+ and t0,t0,t1
+ sb t0,(k0) // set NEC I/O port value
+#endif // not _MRCDUMP_
+
+//
+// set NMI flag 1
+//
+
+ la t2,HalpNMIFlag // set NMI flag address
+ li t3,0xa0000000 // set KSEG1_BASE
+ or t2,t2,t3 //
+ li t3,1 //
+ sw t3,(t2) // set NMI flag 1
+
+//
+// set dump flag 1
+//
+
+ la t2,HalpDumpNMIFlag // set Dump NMI flag address
+ li t3,0xa0000000 // set KSEG1_BASE
+ or t2,t2,t3 //
+ li t3,1 //
+ sw t3,(t2) // set NMI flag 1
+
+//
+// clear psr BEV bit
+//
+
+ mfc0 t0,psr // get psr
+ li t2,0xffbfffff // clear BEV bit
+ nop // fill
+ nop // fill
+ and t0,t0,t2 //
+ nop //
+ mtc0 t0,psr // set psr
+
+ lw t0,0x1c(k1) // restore temporary registers
+ lw t1,0x20(k1) //
+ lw t2,0x24(k1) //
+ lw t3,0x28(k1) //
+ lw t4,0x2c(k1) //
+ lw t5,0x30(k1) //
+ lw t6,0x34(k1) //
+ lw t7,0x38(k1) //
+ lw t8,0x3c(k1) //
+ lw t9,0x40(k1) //
+ lw AT,0x0(k1) //
+
+ eret // return to error epc
+ nop // errata
+ nop //
+ nop //
+ eret //
+ nop //
+
+30:
+
+//
+// No Dump Switch.
+//
+// Check Power Switch
+
+#if defined(_MRCPOWER_)
+ li t1,0xffffc108
+ nop
+ li t0,0x02
+ nop
+ sb t0,(t1)
+ nop
+
+#endif // _MRCPOWER_
+
+ mtc0 t8,entrylo0 // restore tlb 4
+ mtc0 t9,entrylo1 // restore tlb 4
+ nop //
+ nop //
+ nop //
+ nop //
+
+ tlbwi // write to tlb entry
+ nop //
+ nop //
+ nop //
+ nop //
+
+ mtc0 t3,index // restore tlb registers
+ mtc0 t4,entryhi //
+ mtc0 t5,entrylo0 //
+ mtc0 t6,entrylo1 //
+ mtc0 t7,pagemask //
+
+
+//
+// set NMI flag 1
+//
+ la t2,HalpNMIFlag // set NMI flag address
+ li t3,0xa0000000 // set KSEG1_BASE
+ or t2,t2,t3 //
+ li t3,1 //
+ sw t3,(t2) // set NMI flag 1
+
+// S003 +++
+ li t1,0xffffc078 // check NMI source
+ lw t0,(t1) // check NMI source
+ nop //
+ beq t0,zero,40f //
+ nop //
+ li t1,0xffffc020
+ nop
+ ldc1 f0,(t1) // clear processor invalid
+ nop
+ sdc1 f0,0x70(k1) // save processor invalid
+40:
+// S003 ---
+
+ mfc0 t0,psr // get psr
+ li t2,0xffbfffff // clear BEV bit
+ nop // fill
+ nop // fill
+ and t0,t0,t2 //
+ nop //
+ mtc0 t0,psr // set psr
+
+ lw t0,0x1c(k1) // restore temporary registers
+ lw t1,0x20(k1) //
+ lw t2,0x24(k1) //
+ lw t3,0x28(k1) //
+ lw t4,0x2c(k1) //
+ lw t5,0x30(k1) //
+ lw t6,0x34(k1) //
+ lw t7,0x38(k1) //
+ lw t8,0x3c(k1) //
+ lw t9,0x40(k1) //
+ lw AT,0x0(k1) //
+ ldc1 f0,0x68(k1) //
+ nop
+
+ eret // return to errorepc
+ nop // errata
+ nop //
+ nop //
+ eret //
+ nop //
+
+// L001 ---
+
+ .set at
+ .set reorder
+
+ .end HalpNMIDispatch
+
+// Start M008
+ SBTTL("Software Power Off")
+//++
+//
+// VOID
+// HalpPowOffNMIDispatch (
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function was called by firmware when NMI occuerd.
+//
+// Arguments:
+//
+// none.
+//
+// Return Value:
+//
+// none.
+//
+//--
+
+ LEAF_ENTRY(HalpPowOffNMIDispatch)
+
+ .set noat
+ .set noreorder
+
+//
+// Save temporary Registers for use.
+// save area shoud have for every processros.
+//
+
+ li k0,0xffffc070 // get processor number.
+ lw k0,(k0) //
+ bne k0,zero,60f //
+ nop // fill
+
+ la k1,HalpNMISave0 // set save address.
+ j 70f //
+ nop // fill
+
+60:
+ la k1,HalpNMISave1 // set save address.
+ nop // 1 cycle hazzerd
+
+70:
+ sw t0,0(k1) // save temporary registers
+ sw t1,4(k1) //
+ sw t2,8(k1) //
+ sw t3,12(k1) //
+ sw t4,16(k1) //
+ sw t5,20(k1) //
+ sw t6,24(k1) //
+ sw t7,28(k1) //
+ sw AT,32(k1) //
+
+//
+// Set Power Switch Status register to tlb fixed entry
+//
+ li t0,4 // set index 4(hurricane register)
+
+ li t1,0x80012 << 6 // set MRC register
+
+ mfc0 t3,index // save tlb registers
+ mfc0 t4,entryhi //
+ mfc0 t5,entrylo0 //
+ mfc0 t6,entrylo1 //
+ mfc0 t7,pagemask //
+ mtc0 t0,index //
+ nop
+ nop
+ nop
+
+ tlbr // read index 4 tlb
+ nop
+ nop
+ nop
+ nop
+
+ mfc0 t2,entrylo0 // set Self-test address to tlb
+ nop
+ nop
+ nop
+ or t1,t2,t1
+ nop
+
+ mtc0 t1,entrylo0 // set Self-Test to tlb 4
+ nop //
+ nop //
+ nop //
+ nop //
+
+ tlbwi // write to tlb entry
+ nop //
+ nop //
+ nop //
+ nop //
+
+ li t1,0xffffc100 // load MRC Int value
+
+ nop
+ lb k0,(t1) // load Interrupt status.
+ nop
+ lb k0,(t1) // wait
+ nop
+
+ li t0,0x01 // set clear value
+ sb t0,(t1) // clear OffSw bit
+
+ li t1,0x4 // check for OffSw switch
+ nop //
+ and k0,k0,t1 //
+
+ beq k0,zero,80f // 0 means Power switch was not pressed
+ nop //
+
+ li t1,0xffffc130 // load MRC Software PowerOff Register
+
+ nop
+
+ lb t0,0x1 // set PowerOff Value
+
+90:
+ sb t0,(t1) // write PowerOff bit
+ beq zero,zero,90b
+ nop
+
+ eret
+ nop
+ nop
+ nop
+ eret
+ nop
+80:
+
+//
+// No Power Switch.
+//
+
+ mtc0 t2,entrylo0 // restore tlb 4
+ nop //
+ nop //
+ nop //
+ nop //
+
+ tlbwi // write to tlb entry
+ nop //
+ nop //
+ nop //
+ nop //
+
+ mtc0 t3,index // restore tlb registers
+ mtc0 t4,entryhi //
+ mtc0 t5,entrylo0 //
+ mtc0 t6,entrylo1 //
+ mtc0 t7,pagemask //
+
+
+ la t2,HalpNMIFlag // set NMI flag address
+ li t3,0xa0000000 // set KSEG1_BASE
+ or t2,t2,t3 //
+ li t3,1 //
+ sw t3,(t2) // set NMI flag 1
+
+ lw t0,0xffffc078 // check NMI source
+ nop //
+ beq t0,zero,45f //
+ nop //
+ lw t0,0xffffc020 // clear processor invalid
+45:
+
+ mfc0 t0,psr // get psr
+ li t2,0xffbfffff // clear BEV bit
+ nop // fill
+ nop // fill
+ and t0,t0,t2 //
+ nop //
+ mtc0 t0,psr // set psr
+
+ lw t0,0(k1) // restore temporary registers
+ lw t1,4(k1) //
+ lw t2,8(k1) //
+ lw t3,12(k1) //
+ lw t4,16(k1) //
+ lw t5,20(k1) //
+ lw t6,24(k1) //
+ lw t7,28(k1) //
+ lw AT,32(k1) //
+
+ eret // return to errorepc
+ nop // errata
+ nop //
+ nop //
+ eret //
+ nop //
+
+ .set reorder
+ .set at
+
+ .end HalpPowOffNMIDispatch
+// End M008
diff --git a/private/ntos/nthals/halr96b/mips/rgb525.h b/private/ntos/nthals/halr96b/mips/rgb525.h
new file mode 100644
index 000000000..a4e53e09e
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/rgb525.h
@@ -0,0 +1,468 @@
+// #pragma comment(exestr, "@(#) rgb525.h 1.2 95/09/28 18:38:14 nec")
+/************************************************************************
+ * *
+ * Copyright (c) 1994 3Dlabs Inc. Ltd. *
+ * All rights reserved *
+ * *
+ * This software and its associated documentation contains proprietary, *
+ * confidential and trade secret information of 3Dlabs Inc. Ltd. and *
+ * except as provided by written agreement with 3Dlabs Inc. Ltd. *
+ * *
+ * a) no part may be disclosed, distributed, reproduced, transmitted, *
+ * transcribed, stored in a retrieval system, adapted or translated *
+ * in any form or by any means electronic, mechanical, magnetic, *
+ * optical, chemical, manual or otherwise, *
+ * *
+ * and *
+ * *
+ * b) the recipient is not entitled to discover through reverse *
+ * engineering or reverse compiling or other such techniques or *
+ * processes the trade secrets contained therein or in the *
+ * documentation. *
+ * *
+ ************************************************************************/
+
+#ifndef __RGB525_H__
+#define __RGB525_H__
+
+/************************************************************************/
+/* DIRECT ACCESS REGISTERS */
+/************************************************************************/
+
+/* direct registers on 64-bit boundaries */
+
+#define __RGB525_PalAddrWrite 0x00
+#define __RGB525_PaletteData 0x08
+#define __RGB525_PixelMask 0x10
+#define __RGB525_PalAddrRead 0x18
+#define __RGB525_IndexLow 0x20
+#define __RGB525_IndexHigh 0x28
+#define __RGB525_IndexedData 0x30
+#define __RGB525_IndexControl 0x38
+
+/************************************************************************/
+/* INDEXED REGISTERS - MISCELLANEOUS CONTROL */
+/************************************************************************/
+
+#define __RGB525_MiscControlOne 0x0070
+#define __RGB525_MiscControlTwo 0x0071
+#define __RGB525_MiscControlThree 0x0072
+#define __RGB525_MiscClockControl 0x0002
+#define __RGB525_SyncControl 0x0003
+#define __RGB525_HSyncControl 0x0004
+#define __RGB525_PowerManagement 0x0005
+#define __RGB525_DACOperation 0x0006
+#define __RGB525_PaletteControl 0x0007
+
+/* MiscControlOne */
+
+#define RGB525_MISR_CNTL_OFF (0 << 7)
+#define RGB525_MISR_CNTL_ON (1 << 7)
+#define RGB525_VMSK_CNTL_OFF (0 << 6)
+#define RGB525_VMSK_CNTL_ON (1 << 6)
+#define RGB525_PADR_RFMT_READ_ADDR (0 << 5)
+#define RGB525_PADR_RFMT_PAL_STATE (1 << 5)
+#define RGB525_SENS_DSAB_ENABLE (0 << 4)
+#define RGB525_SENS_DSAB_DISABLE (1 << 4)
+#define RGB525_SENS_SEL_BIT3 (0 << 3)
+#define RGB525_SENS_SEL_BIT7 (1 << 3)
+#define RGB525_VRAM_SIZE_32 (0 << 0)
+#define RGB525_VRAM_SIZE_64 (1 << 0)
+
+/* MiscControlTwo */
+
+#define RGB525_PCLK_SEL_LCLK (0 << 6)
+#define RGB525_PCLK_SEL_PLL (1 << 6)
+#define RGB525_PCLK_SEL_EXT (2 << 6)
+#define RGB525_INTL_MODE_DISABLE (0 << 5)
+#define RGB525_INTL_MODE_ENABLE (1 << 5)
+#define RGB525_BLANK_CNTL_NORMAL (0 << 4)
+#define RGB525_BLANK_CNTL_BLANKED (1 << 4)
+#define RGB525_COL_RES_6_BIT (0 << 2)
+#define RGB525_COL_RES_8_BIT (1 << 2)
+#define RGB525_PORT_SEL_VGA (0 << 0)
+#define RGB525_PORT_SEL_VRAM (1 << 0)
+
+/* MiscControlThree */
+
+#define RGB525_SWAP_RB_DISABLE (0 << 7)
+#define RGB525_SWAP_RB_ENABLE (1 << 7)
+#define RGB525_SWAP_WORD_31_00_FIRST (0 << 4)
+#define RGB525_SWAP_WORD_63_32_FIRST (1 << 4)
+#define RGB525_SWAP_NIB_07_04_FIRST (0 << 2)
+#define RGB525_SWAP_NIB_03_00_FIRST (1 << 2)
+
+/* MiscClockControl */
+
+#define RGB525_DDOTCLK_ENABLE (0 << 7)
+#define RGB525_DDOTCLK_DISABLE (1 << 7)
+#define RGB525_SCLK_ENABLE (0 << 6)
+#define RGB525_SCLK_DISABLE (1 << 6)
+#define RGB525_B24P_DDOT_DIV_PLL (0 << 5)
+#define RGB525_B24P_DDOT_SCLK (1 << 5)
+#define RGB525_DDOT_PLL_DIV_1 (0 << 1)
+#define RGB525_DDOT_PLL_DIV_2 (1 << 1)
+#define RGB525_DDOT_PLL_DIV_4 (2 << 1)
+#define RGB525_DDOT_PLL_DIV_8 (3 << 1)
+#define RGB525_DDOT_PLL_DIV_16 (4 << 1)
+#define RGB525_PLL_DISABLE (0 << 0)
+#define RGB525_PLL_ENABLE (1 << 0)
+
+/* SyncControl */
+
+#define RGB525_DLY_CNTL_ADD (0 << 7)
+#define RGB525_DLY_SYNC_NOADD (1 << 7)
+#define RGB525_CSYN_INVT_DISABLE (0 << 6)
+#define RGB525_CSYN_INVT_ENABLE (1 << 6)
+#define RGB525_VSYN_INVT_DISABLE (0 << 5)
+#define RGB525_VSYN_INVT_ENABLE (1 << 5)
+#define RGB525_HSYN_INVT_DISABLE (0 << 4)
+#define RGB525_HSYN_INVT_ENABLE (1 << 4)
+#define RGB525_VSYN_CNTL_NORMAL (0 << 2)
+#define RGB525_VSYN_CNTL_HIGH (1 << 2)
+#define RGB525_VSYN_CNTL_LOW (2 << 2)
+#define RGB525_VSYN_CNTL_DISABLE (3 << 2)
+#define RGB525_HSYN_CNTL_NORMAL (0 << 0)
+#define RGB525_HSYN_CNTL_HIGH (1 << 0)
+#define RGB525_HSYN_CNTL_LOW (2 << 0)
+#define RGB525_HSYN_CNTL_DISABLE (3 << 0)
+
+/* HSyncControl */
+
+#define RGB525_HSYN_POS(n) ((n) & 0xF)
+
+/* PowerManagement */
+
+#define RGB525_SCLK_PWR_NORMAL (0 << 4)
+#define RGB525_SCLK_PWR_DISABLE (1 << 4)
+#define RGB525_DDOT_PWR_NORMAL (0 << 3)
+#define RGB525_DDOT_PWR_DISABLE (1 << 3)
+#define RGB525_SYNC_PWR_NORMAL (0 << 2)
+#define RGB525_SYNC_PWR_DISABLE (1 << 2)
+#define RGB525_ICLK_PWR_NORMAL (0 << 1)
+#define RGB525_ICLK_PWR_DISABLE (1 << 1)
+#define RGB525_DAC_PWR_NORMAL (0 << 0)
+#define RGB525_DAC_PWR_DISABLE (1 << 0)
+
+/* DACOperation */
+
+#define RGB525_SOG_DISABLE (0 << 3)
+#define RGB525_SOG_ENABLE (1 << 3)
+#define RGB525_BRB_NORMAL (0 << 2)
+#define RGB525_BRB_ALWAYS (1 << 2)
+#define RGB525_DSR_SLOW (0 << 1)
+#define RGB525_DSR_FAST (1 << 1)
+#define RGB525_DPE_DISABLE (0 << 0)
+#define RGB525_DPE_ENABLE (1 << 0)
+
+/* PaletteControl */
+
+#define RGB525_6BIT_LINEAR_ENABLE (0 << 7)
+#define RGB525_6BIT_LINEAR_DISABLE (1 << 7)
+#define RGB525_PALETTE_PARTITION(n) ((n) & 0xF)
+
+/************************************************************************/
+/* INDEXED REGISTERS - PIXEL REPRESENTATION */
+/************************************************************************/
+
+#define __RGB525_PixelFormat 0x000A
+#define __RGB525_8BitPixelControl 0x000B
+#define __RGB525_16BitPixelControl 0x000C
+#define __RGB525_24BitPixelControl 0x000D
+#define __RGB525_32BitPixelControl 0x000E
+
+/* PixelFormat */
+
+#define RGB525_PIXEL_FORMAT_4_BPP (2 << 0)
+#define RGB525_PIXEL_FORMAT_8_BPP (3 << 0)
+#define RGB525_PIXEL_FORMAT_16_BPP (4 << 0)
+#define RGB525_PIXEL_FORMAT_24_BPP (5 << 0)
+#define RGB525_PIXEL_FORMAT_32_BPP (6 << 0)
+
+/* 8BitPixelControl */
+
+#define RGB525_B8_DCOL_INDIRECT (0 << 0)
+#define RGB525_B8_DCOL_DIRECT (1 << 0)
+
+/* 16BitPixelControl */
+
+#define RGB525_B16_DCOL_INDIRECT (0 << 6)
+#define RGB525_B16_DCOL_DYNAMIC (1 << 6)
+#define RGB525_B16_DCOL_DIRECT (3 << 6)
+#define RGB525_B16_POL_FORCES_BYPASS (0 << 5)
+#define RGB525_B16_POL_FORCES_LOOKUP (1 << 5)
+#define RGB525_B16_ZIB (0 << 2)
+#define RGB525_B16_LINEAR (1 << 2)
+#define RGB525_B16_555 (0 << 1)
+#define RGB525_B16_565 (1 << 1)
+#define RGB525_B16_SPARSE (0 << 0)
+#define RGB525_B16_CONTIGUOUS (1 << 0)
+
+/* 24BitPixelControl */
+
+#define RGB525_B24_DCOL_INDIRECT (0 << 0)
+#define RGB525_B24_DCOL_DIRECT (1 << 0)
+
+/* 32BitPixelControl */
+
+#define RGB525_B32_POL_FORCES_BYPASS (0 << 2)
+#define RGB525_B32_POL_FORCES_LOOKUP (1 << 2)
+#define RGB525_B32_DCOL_INDIRECT (0 << 0)
+#define RGB525_B32_DCOL_DYNAMIC (1 << 0)
+#define RGB525_B32_DCOL_DIRECT (3 << 0)
+
+/************************************************************************/
+/* INDEXED REGISTERS - FREQUENCY CONTROL */
+/************************************************************************/
+
+#define __RGB525_PLLControlOne 0x0010
+#define __RGB525_PLLControlTwo 0x0011
+#define __RGB525_PLLRefDivCount 0x0014
+
+#define __RGB525_F0 0x0020
+#define __RGB525_F1 0x0021
+#define __RGB525_F2 0x0022
+#define __RGB525_F3 0x0023
+#define __RGB525_F4 0x0024
+#define __RGB525_F5 0x0025
+#define __RGB525_F6 0x0026
+#define __RGB525_F7 0x0027
+#define __RGB525_F8 0x0028
+#define __RGB525_F9 0x0029
+#define __RGB525_F10 0x002A
+#define __RGB525_F11 0x002B
+#define __RGB525_F12 0x002C
+#define __RGB525_F13 0x002D
+#define __RGB525_F14 0x002E
+#define __RGB525_F15 0x002F
+
+#define __RGB525_M0 0x0020
+#define __RGB525_M1 0x0022
+#define __RGB525_M2 0x0024
+#define __RGB525_M3 0x0026
+#define __RGB525_M4 0x0028
+#define __RGB525_M5 0x002A
+#define __RGB525_M6 0x002C
+#define __RGB525_M7 ox002E
+
+#define __RGB525_N0 0x0021
+#define __RGB525_N1 0x0023
+#define __RGB525_N2 0x0025
+#define __RGB525_N3 0x0027
+#define __RGB525_N4 0x0029
+#define __RGB525_N5 0x002B
+#define __RGB525_N6 0x002D
+#define __RGB525_N7 ox002F
+
+/* PLLControlOne */
+
+#define RGB525_REF_SRC_REFCLK (0 << 4)
+#define RGB525_REF_SRC_EXTCLK (1 << 4)
+#define RGB525_PLL_EXT_FS_DIRECT (0 << 0)
+#define RGB525_PLL_EXT_FS_M_N (1 << 0)
+#define RGB525_PLL_INT_FS_DIRECT (2 << 0)
+#define RGB525_PLL_INT_FS_M_N (3 << 0)
+
+/* PLLControlTwo */
+
+#define RGB525_PLL_INT_FS(n) ((n) & 0xF)
+
+/* PLLRefDivCount */
+
+#define RGB525_REF_DIV_COUNT(n) ((n) & 0x1F)
+
+#define RGB525_PLL_REFCLK_4_MHz (0x02)
+#define RGB525_PLL_REFCLK_6_MHz (0x03)
+#define RGB525_PLL_REFCLK_8_MHz (0x04)
+#define RGB525_PLL_REFCLK_10_MHz (0x05)
+#define RGB525_PLL_REFCLK_12_MHz (0x06)
+#define RGB525_PLL_REFCLK_14_MHz (0x07)
+#define RGB525_PLL_REFCLK_16_MHz (0x08)
+#define RGB525_PLL_REFCLK_18_MHz (0x09)
+#define RGB525_PLL_REFCLK_20_MHz (0x0A)
+#define RGB525_PLL_REFCLK_22_MHz (0x0B)
+#define RGB525_PLL_REFCLK_24_MHz (0x0C)
+#define RGB525_PLL_REFCLK_26_MHz (0x0D)
+#define RGB525_PLL_REFCLK_28_MHz (0x0E)
+#define RGB525_PLL_REFCLK_30_MHz (0x0F)
+#define RGB525_PLL_REFCLK_32_MHz (0x10)
+#define RGB525_PLL_REFCLK_34_MHz (0x11)
+#define RGB525_PLL_REFCLK_36_MHz (0x12)
+#define RGB525_PLL_REFCLK_38_MHz (0x13)
+#define RGB525_PLL_REFCLK_40_MHz (0x14)
+#define RGB525_PLL_REFCLK_42_MHz (0x15)
+#define RGB525_PLL_REFCLK_44_MHz (0x16)
+#define RGB525_PLL_REFCLK_46_MHz (0x17)
+#define RGB525_PLL_REFCLK_48_MHz (0x18)
+#define RGB525_PLL_REFCLK_50_MHz (0x19)
+#define RGB525_PLL_REFCLK_52_MHz (0x1A)
+#define RGB525_PLL_REFCLK_54_MHz (0x1B)
+#define RGB525_PLL_REFCLK_56_MHz (0x1C)
+#define RGB525_PLL_REFCLK_58_MHz (0x1D)
+#define RGB525_PLL_REFCLK_60_MHz (0x1E)
+#define RGB525_PLL_REFCLK_62_MHz (0x1F)
+
+/* F0-F15[7:0] */
+
+#define RGB525_DF(n) (((n) & 0x3) << 6)
+#define RGB525_VCO_DIV_COUNT(n) ((n) & 0x3F)
+
+/************************************************************************/
+/* INDEXED REGISTERS - CURSOR */
+/************************************************************************/
+
+#define __RGB525_CursorControl 0x0030
+#define __RGB525_CursorXLow 0x0031
+#define __RGB525_CursorXHigh 0x0032
+#define __RGB525_CursorYLow 0x0033
+#define __RGB525_CursorYHigh 0x0034
+#define __RGB525_CursorHotSpotX 0x0035
+#define __RGB525_CursorHotSpotY 0x0036
+#define __RGB525_CursorColor1Red 0x0040
+#define __RGB525_CursorColor1Green 0x0041
+#define __RGB525_CursorColor1Blue 0x0042
+#define __RGB525_CursorColor2Red 0x0043
+#define __RGB525_CursorColor2Green 0x0044
+#define __RGB525_CursorColor2Blue 0x0045
+#define __RGB525_CursorColor3Red 0x0046
+#define __RGB525_CursorColor3Green 0x0047
+#define __RGB525_CursorColor3Blue 0x0048
+
+/* CursorControl */
+
+#define RGB525_SMLC_PART_0 (0 << 6)
+#define RGB525_SMLC_PART_1 (1 << 6)
+#define RGB525_SMLC_PART_2 (2 << 6)
+#define RGB525_SMLC_PART_3 (3 << 6)
+#define RGB525_PIX_ORDER_RIGHT_TO_LEFT (0 << 5)
+#define RGB525_PIX_ORDER_LEFT_TO_RIGHT (1 << 5)
+#define RGB525_LOC_READ_LAST_WRITTEN (0 << 4)
+#define RGB525_LOC_READ_ACTUAL_LOCATION (1 << 4)
+#define RGB525_UPDT_CNTL_DELAYED (0 << 3)
+#define RGB525_UPDT_CNTL_IMMEDIATE (1 << 3)
+#define RGB525_CURSOR_SIZE_32 (0 << 2)
+#define RGB525_CURSOR_SIZE_64 (1 << 2)
+#define RGB525_CURSOR_MODE_OFF (0 << 0)
+#define RGB525_CURSOR_MODE_3_COLOR (1 << 0)
+#define RGB525_CURSOR_MODE_2_COLOR_HL (2 << 0)
+#define RGB525_CURSOR_MODE_2_COLOR (3 << 0)
+
+/************************************************************************/
+/* INDEXED REGISTERS - BORDER COLOR */
+/************************************************************************/
+
+#define __RGB525_BorderColorRed 0x0060
+#define __RGB525_BorderColorGreen 0x0061
+#define __RGB525_BorderColorBlue 0x0062
+
+/************************************************************************/
+/* INDEXED REGISTERS - DIAGNOSTIC SUPPORT */
+/************************************************************************/
+
+#define __RGB525_RevisionLevel 0x0000
+#define __RGB525_ProductID 0x0001
+#define __RGB525_DACSense 0x0082
+#define __RGB525_MISRRed 0x0084
+#define __RGB525_MISRGreen 0x0086
+#define __RGB525_MISRBlue 0x0088
+#define __RGB525_PLLVCODivInput 0x008E
+#define __RGB525_PLLVCORefInput 0x008F
+#define __RGB525_VramMaskLow 0x0090
+#define __RGB525_VramMaskHigh 0x0091
+
+/* RevisionLevel */
+
+#define RGB525_PRODUCT_REV_LEVEL 0xF0
+
+/* ProductID */
+
+#define RGB525_PRODUCT_ID_CODE 0x01
+
+/************************************************************************/
+/* INDEXED REGISTERS - CURSOR ARRAY */
+/************************************************************************/
+
+#define __RGB525_CursorArray 0x0100
+
+/************************************************************************/
+/* DIRECT ACCESS MACROS */
+/************************************************************************/
+/*
+ * The pixel clock must be running to access the palette and the cursor
+ * array, and the timings for the microprocessor signals are specified
+ * in units of pixel clocks. Six clocks must be allowed for an internal
+ * access to complete, following a palette or cursor access.
+ *
+ * In the worst case (VGA 640x480 resolution) the pixel clock is 40 ns,
+ * giving a time of 280 ns for seven pixel clocks. Assuming the fastest
+ * host clock is 100 MHz, a delay of 28 host clocks is required. Again
+ * assuming that the loop below takes 3 clocks per iteration, it should
+ * be executed at least 10 times.
+ */
+
+#define RGB525_DELAY \
+{ \
+ volatile DWORD __rgb525_dly; \
+ \
+ for (__rgb525_dly = 0; __rgb525_dly < 10; __rgb525_dly++); \
+}
+
+/*
+ * All RGB525 accesses are followed by a short delay, as required by
+ * the AC Characteristics table in the RGB525 Databook. However, the
+ * text implies that non-palette or cursor-array accesses can happen
+ * closer together. Everything is delayed here for simplicity.
+ */
+
+#define RGB525_ADDR(base, offset) \
+( \
+/* (DWORD) ((volatile BYTE *)(base) + (offset)) */ \
+ (DWORD) ((base) + (offset)) \
+)
+
+#define RGB525_WRITE(dac, offset, data) \
+{ \
+/* DWORD_WRITE(RGB525_ADDR((dac),(offset)), (data)); */ \
+ WRITE_REGISTER_UCHAR(RGB525_ADDR((dac),(offset)), (UCHAR)(data)); \
+ RGB525_DELAY; \
+}
+
+#define RGB525_READ_BYTE(dac, offset, data) \
+{ \
+ DWORD __rgb525_tmp; \
+ \
+/* DWORD_READ(RGB525_ADDR((dac),(offset)), __rgb525_tmp); */ \
+ __rgb525_tmp = READ_REGISTER_UCHAR(RGB525_ADDR((dac),(offset))); \
+/* (data) = (BYTE) (__rgb525_tmp & BYTE_MAX); */ \
+ (data) = (UCHAR) (__rgb525_tmp & 0xff); \
+ RGB525_DELAY; \
+}
+
+/************************************************************************/
+/* INDEXED ACCESS MACROS */
+/************************************************************************/
+
+#define RGB525_SET_INDEX(dac, index) \
+{ \
+ RGB525_WRITE((dac), __RGB525_IndexLow, (index)); \
+/* RGB525_WRITE((dac), __RGB525_IndexHigh, (index) >> BYTE_BITS); */ \
+ RGB525_WRITE((dac), __RGB525_IndexHigh, (index) >> 8); \
+}
+
+#define RGB525_SET_REG(dac, index, data) \
+{ \
+ RGB525_SET_INDEX((dac), (index)); \
+ RGB525_WRITE((dac), __RGB525_IndexedData, (data)); \
+}
+
+#define RGB525_GET_REG(dac, index, data) \
+{ \
+ RGB525_SET_INDEX((dac), (index)); \
+ RGB525_READ_BYTE((dac), __RGB525_IndexedData, (data)); \
+}
+
+/************************************************************************/
+
+#endif /* __RGB525_H__ */
+
+/************************************************************************/
diff --git a/private/ntos/nthals/halr96b/mips/tga.h b/private/ntos/nthals/halr96b/mips/tga.h
new file mode 100644
index 000000000..3e6257c7c
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/tga.h
@@ -0,0 +1,93 @@
+// #pragma comment(exestr, "@(#) tga.h 1.1 95/09/28 18:38:49 nec")
+/*++
+
+Module Name:
+
+ tga.h
+
+Abstract:
+
+ This module contains the register definitions for the TGA (DEC21030)
+
+Author:
+
+ T.Katoh create-data 1994/11/30
+
+Revision Histort:
+
+--*/
+
+// TGA Core Space Map offset for 8-bpp Frame Buffers
+
+#define TGA_REG_SPC_OFFSET 0x00100000
+#define TGA_DSP_BUF_OFFSET 0x00200000
+
+// TGA register offsets, organized by functionality.
+
+#define PLANE_MASK 0x00000028
+#define ONE_SHOT_PIXEL_MASK 0x0000002C
+#define MODE 0x00000030
+#define RASTER_OP 0x00000034
+#define DEEP 0x00000050
+#define BLK_COLOR_R0 0X00000140
+#define BLK_COLOR_R1 0X00000144
+#define H_CONT 0x00000064
+#define V_CONT 0x00000068
+#define VIDEO_BASE 0x0000006c
+#define VIDEO_VALID 0x00000070
+#define RAMDAC_SETUP 0x000000C0
+#define EEPROM_WRITE 0x000001e0
+#define CLOCK 0x000001e8
+#define RAMDAC_DATA 0X000001f0
+#define COMMAND_STATUS 0x000001f8
+
+// Initiate Palette Data
+
+#define VGA_INI_PALETTE_BLACK_R 0x00
+#define VGA_INI_PALETTE_BLACK_G 0x00
+#define VGA_INI_PALETTE_BLACK_B 0x00
+#define VGA_INI_PALETTE_RED_R 0xAA
+#define VGA_INI_PALETTE_RED_G 0x00
+#define VGA_INI_PALETTE_RED_B 0x00
+#define VGA_INI_PALETTE_GREEN_R 0x00
+#define VGA_INI_PALETTE_GREEN_B 0xAA
+#define VGA_INI_PALETTE_GREEN_G 0x00
+#define VGA_INI_PALETTE_YELLOW_R 0xAA
+#define VGA_INI_PALETTE_YELLOW_G 0xAA
+#define VGA_INI_PALETTE_YELLOW_B 0x00
+#define VGA_INI_PALETTE_BLUE_R 0x00
+#define VGA_INI_PALETTE_BLUE_G 0x00
+#define VGA_INI_PALETTE_BLUE_B 0xAA
+#define VGA_INI_PALETTE_MAGENTA_R 0xAA
+#define VGA_INI_PALETTE_MAGENTA_G 0x00
+#define VGA_INI_PALETTE_MAGENTA_B 0xAA
+#define VGA_INI_PALETTE_CYAN_R 0x00
+#define VGA_INI_PALETTE_CYAN_G 0xAA
+#define VGA_INI_PALETTE_CYAN_B 0xAA
+#define VGA_INI_PALETTE_WHITE_R 0xAA
+#define VGA_INI_PALETTE_WHITE_G 0xAA
+#define VGA_INI_PALETTE_WHITE_B 0xAA
+#define VGA_INI_PALETTE_HI_BLACK_R 0x00
+#define VGA_INI_PALETTE_HI_BLACK_G 0x00
+#define VGA_INI_PALETTE_HI_BLACK_B 0x00
+#define VGA_INI_PALETTE_HI_RED_R 0xFF
+#define VGA_INI_PALETTE_HI_RED_G 0x00
+#define VGA_INI_PALETTE_HI_RED_B 0x00
+#define VGA_INI_PALETTE_HI_GREEN_R 0x00
+#define VGA_INI_PALETTE_HI_GREEN_G 0xFF
+#define VGA_INI_PALETTE_HI_GREEN_B 0x00
+#define VGA_INI_PALETTE_HI_YELLOW_R 0xFF
+#define VGA_INI_PALETTE_HI_YELLOW_G 0xFF
+#define VGA_INI_PALETTE_HI_YELLOW_B 0x00
+#define VGA_INI_PALETTE_HI_BLUE_R 0x00
+#define VGA_INI_PALETTE_HI_BLUE_G 0x00
+#define VGA_INI_PALETTE_HI_BLUE_B 0xFF
+#define VGA_INI_PALETTE_HI_MAGENTA_R 0xFF
+#define VGA_INI_PALETTE_HI_MAGENTA_G 0x00
+#define VGA_INI_PALETTE_HI_MAGENTA_B 0xFF
+#define VGA_INI_PALETTE_HI_CYAN_R 0x00
+#define VGA_INI_PALETTE_HI_CYAN_G 0xFF
+#define VGA_INI_PALETTE_HI_CYAN_B 0xFF
+#define VGA_INI_PALETTE_HI_WHITE_R 0xFF
+#define VGA_INI_PALETTE_HI_WHITE_G 0xFF
+#define VGA_INI_PALETTE_HI_WHITE_B 0xFF
diff --git a/private/ntos/nthals/halr96b/mips/x4clock.s b/private/ntos/nthals/halr96b/mips/x4clock.s
new file mode 100644
index 000000000..2e3aaac3a
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/x4clock.s
@@ -0,0 +1,433 @@
+// .ident "@(#) x4clock.s 1.1 95/09/28 18:39:17 nec"
+// TITLE("Interval and Profile Clock Interrupts")
+//++
+//
+// Copyright (c) 1991 Microsoft Corporation
+//
+// Module Name:
+//
+// x4clock.s
+//
+// Abstract:
+//
+// This module implements the code necessary to field and process the
+// interval and profile clock interrupts on a MIPS R4000 system.
+//
+// Author:
+//
+// David N. Cutler (davec) 26-Apr-1991
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+// M001 Fri Feb 17 17:48:03 JST 1995 kbnes!kuriyama (A)
+// - Change HalpClockInterrupt0(()
+// for dump switch support.
+//
+// S002 Tue Feb 21 21:24:13 JST 1995 kbnes!kuriyama (A)
+// - use HalpNMIFlag
+//
+// S003 Wed Feb 22 11:18:59 JST 1995 kbnes!kuriyama (A)
+// - enter kernel debugger when NMI only checked version
+//
+// S004 Wed Feb 22 14:25:20 JST 1995 kbnes!kuriyama (A)
+// - enter kernel debugger when NMI free version
+//
+// S005 Sat Mar 18 20:30:05 JST 1995 kbnes!kuriyama (A)
+// - nmi logic change
+//
+// M006 kuriyama@oa2.kb.nec.co.jp Wed Jun 28 14:16:29 JST 1995
+// - change nmi logic
+//
+// M007 Thu Jul 20 19:31:41 JST 1995 kbnes!kisimoto
+// - Merge build 1057
+//
+//--
+
+#include "halmips.h"
+
+#if defined(_DUO_)
+
+#include "duodef.h"
+
+#endif
+
+#if defined(_JAZZ_)
+
+#include "jazzdef.h"
+
+#endif
+
+// M001 +++
+#if defined(_R94A_)
+ .extern HalpNMIFlag
+ .extern HalpNMIInterrupt
+ .extern HalpDumpNMIFlag //S002
+#endif //_R94A_
+// M001 ---
+
+ SBTTL("System Clock Interrupt - Processor 0")
+//++
+//
+// Routine Description:
+//
+// This routine is entered as the result of an interrupt generated by
+// the interval timer. Its function is to acknowledge the interrupt and
+// transfer control to the standard system routine to update the system
+// time and the execution time of the current thread and process.
+//
+// Arguments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ .struct 0
+CiArgs: .space 4 * 4 // saved arguments
+ .space 3 * 4 // fill
+CiRa: .space 4 // saved return address
+CiFrameLength: //
+
+ NESTED_ENTRY(HalpClockInterrupt0, CiFrameLength, zero)
+
+ subu sp,sp,CiFrameLength // allocate stack frame
+ sw ra,CiRa(sp) // save return address
+
+ PROLOGUE_END
+
+ .set noreorder
+
+// M001 +++
+#if defined(_R94A_)
+//
+// check if dump swich flag set.
+//
+
+ la t0,HalpNMIFlag // set NMI flag address
+ li t1,0xa0000000 // set KSEG1_BASE
+ or t0,t0,t1
+ lw t1,(t0) // load NMI flag
+ nop
+ beq t1,zero,10f
+ nop
+ sw zero,(t0)
+
+ lw t0,KdDebuggerEnabled // get address of debugger enable
+ nop
+ lbu t0,0(t0) // get debugger enable flag
+ nop
+ beq zero,t0,5f // if eq, debugger not enabled
+ nop
+ nop
+ beq zero,v0,40f // if eq, no breakin requested
+ nop
+ break BREAKIN_BREAKPOINT // break into the debugger
+ nop
+5:
+
+// S002 +++
+ la t0,HalpDumpNMIFlag // set Dump NMI flag address
+ li t1,0xa0000000 // set KSEG1_BASE
+ or t0,t0,t1 //
+ lw a0,(t0) // load Dump NMI flag
+ nop //
+// S003 +++
+ sw zero,(t0) // clear Dump NMI flag
+ nop //
+// S003 ---
+// S005
+ lw zero,DMA_VIRTUAL_BASE + 0x58 // clear acknowledge // M006
+// S002 ---
+ jal HalpNMIInterrupt // jump to NMI routine
+ nop //
+10:
+#endif // _R94A_
+// M001 ---
+
+#if defined(_DUO_)
+
+ lw t0,DMA_VIRTUAL_BASE + 0x58 // acknowledge timer interrupt
+
+#endif
+
+#if defined(_JAZZ_)
+
+ lw t0,DMA_VIRTUAL_BASE + 0x230 // acknowledge timer interrupt
+
+#endif
+
+
+ .set reorder
+
+ move a0,s8 // set address of trap frame
+ lw a1,HalpCurrentTimeIncrement // set current time increment
+ lw t0,__imp_KeUpdateSystemTime // update system time
+ jal t0 //
+
+//
+// The following code is a work around for a bug in the Fusion machines
+// where the clock interrupt is not dismissed by reading the acknowledge
+// register.
+//
+
+#if defined(_JAZZ_)
+
+ .set noreorder
+ .set noat
+ mfc0 t0,cause // read the cause register
+ lw t1,HalpEisaControlBase // get EISA control base address
+ sll t0,t0,31 - (CAUSE_INTPEND + CLOCK_LEVEL - 1) // isolate clock bit
+ bgez t0,10f // if gez, no clock interrupt pending
+ li t2,0x2 // get NMI port enable bit
+ lb t3,0x70(t1) // save EISA NMI interrupt disable
+ lb t4,0x461(t1) // save EISA extended NMI status
+ sb zero,0x70(t1) // clear EISA NMI interrupt disable
+ sb t2,0x461(t1) // set EISA NMI port enable
+ sb zero,0x462(t1) // generate EISA NMI interrupt
+ sb zero,0x461(t1) // clear EISA extended NMI status
+ sb t2,0x461(t1) //
+ lb zero,0x461(t1) // synchronize clear operatin
+ sb t3,0x70(t1) // restore EISA NMI interupt disable
+ sb t4,0x461(t1) // restore EISA exteneed NMI status
+ lb zero,0x461(t1) // synchronize restore operation
+ .set at
+ .set reorder
+
+10: //
+
+#endif
+
+//
+// At each clock interrupt the next time increment is moved to the current
+// time increment to "pipeline" the update of the current increment at the
+// correct time. If the next interval count is nonzero, then the new time
+// increment is moved to the next time increment and the next interval count
+// register is loaded with the specified interval count minus one (i.e., ms).
+//
+
+ lw t0,KdDebuggerEnabled // get address of debugger enable
+ lw t1,HalpNextIntervalCount // get next interval count
+ lw t2,HalpNextTimeIncrement // get the next increment value
+ lbu t0,0(t0) // get debugger enable flag
+ lw t3,HalpNewTimeIncrement // get new new time increment value
+ lw ra,CiRa(sp) // restore return address
+ or t4,t1,t0 // set interval count or debugger?
+ sw t2,HalpCurrentTimeIncrement // set current increment value
+ bne zero,t4,20f // if ne, interval change or debugger
+ addu sp,sp,CiFrameLength // deallocate stack frame
+ j ra // return
+
+//
+// The interval count must be changed or the debugger is enabled.
+//
+
+20: sw zero,HalpNextIntervalCount // clear next interval count
+ beq zero,t1,30f // if eq, not interval count change
+ subu t1,t1,1 // compute millisecond interval count
+
+ .set noreorder
+
+#if defined(_DUO_)
+
+ sw t1,DMA_VIRTUAL_BASE + 0x1a8 // set next interval count
+
+#endif
+
+#if defined(_JAZZ_)
+
+ sw t1,DMA_VIRTUAL_BASE + 0x228 // set next interval count
+
+#endif
+
+ .set reorder
+
+ sw t3,HalpNextTimeIncrement // set next time increment value
+30: beq zero,t0,40f // if eq, debugger not enabled
+ jal KdPollBreakIn // check if breakin is requested
+ beq zero,v0,40f // if eq, no breakin requested
+ li a0,DBG_STATUS_CONTROL_C // break in and send
+ jal DbgBreakPointWithStatus // status to debugger
+40: lw ra,CiRa(sp) // restore return address
+ addu sp,sp,CiFrameLength // deallocate stack frame
+ j ra // return
+
+ .end HalpClockInterrupt0
+
+ SBTTL("System Clock Interrupt - Processor N")
+//++
+//
+// Routine Description:
+//
+// This routine is entered as the result of an interrupt generated by
+// the interval timer. Its function is to acknowledge the interrupt
+// and transfer control to the standard system routine to update the
+// execution time of the current thread and process.
+//
+// Arguments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpClockInterrupt1)
+
+#if defined(_DUO_)
+
+ lw t0,DMA_VIRTUAL_BASE + 0x58 // acknowledge timer interrupt
+ move a0,s8 // set address of trap frame
+ lw t1,__imp_KeUpdateRunTime // update system runtime
+ j t1 //
+
+#else // M007
+
+ j ra //
+
+#endif
+
+ .end HalpClockInterrupt1
+
+ SBTTL("Profile Clock Interrupt")
+//++
+//
+// Routine Description:
+//
+// This routine is entered as the result of an interrupt generated by the
+// profile clock. Its function is to acknowledge the profile interrupt,
+// compute the next compare value, update the performance counter, and
+// transfer control to the standard system routine to process any active
+// profiles.
+//
+// Arguments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpProfileInterrupt)
+
+ .set noreorder
+ .set noat
+ mfc0 t1,count // get current count value
+ mfc0 t0,compare // get current comparison value
+ addu t1,t1,8 // factor in lost cycles
+ subu t1,t1,t0 // compute initial count value
+ mtc0 t0,compare // dismiss interrupt
+ mtc0 t1,count // set new count register value
+ .set at
+ .set reorder
+
+#if defined(NT_UP)
+
+ la t1,HalpPerformanceCounter // get performance counter address
+
+#else
+
+ lw t1,KiPcr + PcPrcb(zero) // get current processor block address
+ la t2,HalpPerformanceCounter // get performance counter address
+ lbu t1,PbNumber(t1) // get processor number
+ sll t1,t1,3 // compute address of performance count
+ addu t1,t1,t2 //
+
+#endif
+
+ lw t2,LiLowPart(t1) // get low part of performance count
+ lw t3,LiHighPart(t1) // get high part of performance count
+ addu t2,t2,t0 // update low part of performance count
+ sw t2,LiLowPart(t1) // store low part of performance count
+ sltu t4,t2,t0 // generate carry into high part
+ addu t3,t3,t4 // update high part of performance count
+ sw t3,LiHighPart(t1) // store high part of performance count
+ move a0,s8 // set address of trap frame
+ lw t4,__imp_KeProfileInterrupt // process profile interrupt
+ j t4 //
+
+ .end HalpProfileInterrupt
+
+ SBTTL("Read Count Register")
+//++
+//
+// ULONG
+// HalpReadCountRegister (
+// VOID
+// );
+//
+// Routine Description:
+//
+// This routine reads the current value of the count register and
+// returns the value.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// Current value of the count register.
+//
+//--
+
+ LEAF_ENTRY(HalpReadCountRegister)
+
+ .set noreorder
+ .set noat
+ mfc0 v0,count // get count register value
+ .set at
+ .set reorder
+
+ j ra // return
+
+ .end HalpReadCountRegister
+
+ SBTTL("Write Compare Register And Clear")
+//++
+//
+// ULONG
+// HalpWriteCompareRegisterAndClear (
+// IN ULONG Value
+// );
+//
+// Routine Description:
+//
+// This routine reads the current value of the count register, writes
+// the value of the compare register, clears the count register, and
+// returns the previous value of the count register.
+//
+// Arguments:
+//
+// Value - Supplies the value written to the compare register.
+//
+// Return Value:
+//
+// Previous value of the count register.
+//
+//--
+
+ LEAF_ENTRY(HalpWriteCompareRegisterAndClear)
+
+ .set noreorder
+ .set noat
+ mfc0 v0,count // get count register value
+ mtc0 a0,compare // set compare register value
+ li t0,7 // set lost cycle count
+ mtc0 t0,count // set count register to zero
+ .set at
+ .set reorder
+
+ j ra // return
+
+ .end HalpWriteCompareRegisterAndClear
diff --git a/private/ntos/nthals/halr96b/mips/x4tb.s b/private/ntos/nthals/halr96b/mips/x4tb.s
new file mode 100644
index 000000000..be37d6677
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/x4tb.s
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\x4tb.s"
diff --git a/private/ntos/nthals/halr96b/mips/x86bios.c b/private/ntos/nthals/halr96b/mips/x86bios.c
new file mode 100644
index 000000000..68a599e80
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/x86bios.c
@@ -0,0 +1,1261 @@
+// #pragma comment(exestr, "@(#) x86bios.c 1.1 95/09/28 18:40:12 nec")
+/*++
+
+Copyright (c) 1994 Microsoft Corporation
+
+Module Name:
+
+ x86bios.c
+
+Abstract:
+
+
+ This module implements the platform specific interface between a device
+ driver and the execution of x86 ROM bios code for the device.
+
+Author:
+
+ David N. Cutler (davec) 17-Jun-1994
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ M001 kuriyama@oa2.kb.nec.co.jp Tue Jul 18 15:45:09 JST 1995
+ - add check intel based bios flag
+
+ M002 kuriyama@oa2.kb.nec.co.jp Thu Jul 20 15:16:52 JST 1995
+ - add for DPI support (NO PCI DATA structure)
+
+ S003 kuriyama@oa2.kb.nec.co.jp Tue Aug 15 14:09:30 JST 1995
+ - bug fix for canopus PowerWindows 864PCI
+
+--*/
+
+
+#define USE_BIOS_EMULATOR
+
+
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+#include "xm86.h"
+#include "x86new.h"
+
+VOID
+HalpReadPCIConfigUlongByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PULONG Buffer,
+ IN ULONG Offset
+ );
+
+VOID
+HalpWritePCIConfigUlongByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PULONG Buffer,
+ IN ULONG Offset
+ );
+
+VOID
+HalpReadPCIConfigUshortByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PSHORT Buffer,
+ IN ULONG Offset
+ );
+
+VOID
+HalpWritePCIConfigUshortByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PSHORT Buffer,
+ IN ULONG Offset
+ );
+
+// M001 +++
+VOID
+HalpReadPCIConfigUcharByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+VOID
+HalpWritePCIConfigUcharByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+// M001 ---
+
+//
+// Define global data.
+//
+
+
+ULONG HalpX86BiosInitialized = FALSE;
+ULONG HalpEnableInt10Calls = FALSE;
+PVOID HalpIoMemoryBase = NULL;
+PVOID HalpIoControlBase=NULL;
+PUCHAR HalpRomBase = NULL;
+
+ULONG ROM_Length;
+#define BUFFER_SIZE (64*1024)
+UCHAR ROM_Buffer[BUFFER_SIZE];
+
+//#define R98_PCICONFIG_START ((PULONG)(0x18ca8800 | KSEG1_BASE))
+
+extern KSPIN_LOCK HalpPCIConfigLock;
+BOOLEAN HalpInitX86Emulator(
+ VOID)
+
+{
+ ULONG ROM_size = 0;
+ PHYSICAL_ADDRESS PhysAddr;
+ UCHAR BaseClass, SubClass, ProgIf;// M001
+ USHORT Cmd,SetCmd, VendorID, DeviceID, Slot; // M002
+ PUCHAR ROM_Ptr, ROM_Shadow;
+ ULONG i;
+ ULONG r;
+ USHORT PciDataOffset; // M001
+ PCI_SLOT_NUMBER PciSlot;
+ UCHAR header;
+ KIRQL Irql;
+ PhysAddr.HighPart = 0x00000000;
+
+
+#if 1
+ KeInitializeSpinLock (&HalpPCIConfigLock);
+ //kuku
+ KeRaiseIrql (PROFILE_LEVEL, &Irql);
+ KiAcquireSpinLock (&HalpPCIConfigLock);
+
+
+
+#if 0 //tmp 707 // M001
+ // First Check ISA BIOS.Becase PCEB 0-1M Positive Decode So
+ // I Can See ROM Image.
+ // Create a mapping to ISA memory space, unless one already exists
+ //
+
+ HalpIoMemoryBase= (PVOID)0x40000000;
+ ROM_size = 0xD0000; // Map to end of option ROM space
+
+ //
+ // Look for ISA option video ROM signature
+ //
+ ROM_Ptr = (PUCHAR) HalpIoMemoryBase + 0xC0000;
+ HalpRomBase = ROM_Ptr;
+ if (*ROM_Ptr == 0x55 && *(ROM_Ptr+1) == 0xAA) {
+ //
+ // Copy ROM to RAM. PCI Spec says you can't execute from ROM.
+ // ROM and video RAM sometimes can't co-exist.
+ //
+ ROM_Length = *(ROM_Ptr+2) << 9;
+ if (ROM_Length <= BUFFER_SIZE) {
+ for (i=0; i<ROM_Length; i++)
+ ROM_Buffer[i] = *ROM_Ptr++;
+ }
+#if defined(_X86_DBG_)
+ DbgPrint("\n EISA ROM BIOS Found \n"); //DBGDBG
+#endif // _X86_DBG_
+ HalpRomBase = (PUCHAR) ROM_Buffer;
+ HalpIoControlBase= (PVOID)0x403f0000;
+
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql);
+
+ return TRUE;
+
+ }
+#endif
+
+ //
+ // Scan PCI slots for video BIOS ROMs, except 3 PCI "slots" on motherboard
+ //
+ // Slot 0: Hurrucane (host bridge)
+ // Slot 1: Typhoon (Internal-bus bridge)
+ // Slot 2: PCI-EISA bridge
+ //
+ for (Slot = 3; Slot < 6; Slot++) {
+#if defined(_X86_DBG_)
+ DbgPrint("\n PCI SLot Number=%x\n",Slot); //DBGDBG
+#endif // _X86_DBG_
+ //
+ // Create a mapping to PCI configuration space
+ //
+
+ PciSlot.u.bits.FunctionNumber = 0;
+ PciSlot.u.bits.DeviceNumber = Slot ;
+
+ //
+ // Read Vendor ID and check if slot is empty
+ //
+
+ HalpReadPCIConfigUshortByOffset(PciSlot,&VendorID,FIELD_OFFSET (PCI_COMMON_CONFIG, VendorID));
+
+#if defined(_X86_DBG_)
+DbgPrint("\n Vendor ID=%x\n",VendorID); //DBGDBG
+#endif // _X86_DBG_
+
+ if (VendorID == 0xFFFF){
+ continue; // Slot is empty; go to next slot
+ }
+
+// M002 +++
+ //
+ // Read Device ID and check if slot is empty
+ //
+
+ HalpReadPCIConfigUshortByOffset(PciSlot,&DeviceID,FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceID));
+
+ //
+ // Check for GLINT or DEC-GA board.
+ //
+
+ if ( (VendorID == 0x3d3d && DeviceID == 0x0001) ||
+ (VendorID == 0x1011 && DeviceID == 0x0004) ) {
+ continue;
+ }
+// M002 ---
+
+
+// M001 +++
+ //
+ // Check Base Class Code
+ //
+ HalpReadPCIConfigUcharByOffset(PciSlot,&BaseClass,FIELD_OFFSET (PCI_COMMON_CONFIG, BaseClass));
+
+#if defined(_X86_DBG_)
+ DbgPrint("\n BaseClass =%x\n",BaseClass); //DBGDBG
+#endif // _X86_DBG_
+
+ //
+ // Check Sub Class Code
+ //
+ HalpReadPCIConfigUcharByOffset(PciSlot,&SubClass,FIELD_OFFSET (PCI_COMMON_CONFIG, SubClass));
+
+#if defined(_X86_DBG_)
+ DbgPrint("\n SubClass =%x\n",SubClass); //DBGDBG
+#endif // _X86_DBG_
+
+ //
+ // Check Proglamming Interface
+ //
+ HalpReadPCIConfigUcharByOffset(PciSlot,&ProgIf,FIELD_OFFSET (PCI_COMMON_CONFIG, ProgIf));
+
+#if defined(_X86_DBG_)
+ DbgPrint("\n ProgIf =%x\n",ProgIf); //DBGDBG
+#endif // _X86_DBG_
+
+ //
+ // check if video card
+ //
+ if ( ( (BaseClass == 0) && (SubClass == 1) && (ProgIf == 0) ) || //S003
+ ( (BaseClass == 3) && (SubClass == 0) && (ProgIf == 0) ) ||
+ ( (BaseClass == 3) && (SubClass == 1) && (ProgIf == 0) ) ||
+ ( (BaseClass == 3) && (SubClass == 0x80) && (ProgIf == 0) ) ) {
+#if defined(_X86_DBG_)
+ DbgPrint("\n This is Video card \n");
+#endif // _X86_DBG_
+ } else {
+#if defined(_X86_DBG_)
+ DbgPrint("\n This is not Video card \n");
+#endif // _X86_DBG_
+ continue;
+ }
+// M001 ---
+
+ //
+ // Get size of ROM
+ //
+
+ ROM_size=0xFFFFFFFF;
+
+#if defined(_X86_DBG_)
+ DbgPrint("ROM size config offset = %x\n",FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+#endif // _X86_DBG_
+ HalpWritePCIConfigUlongByOffset(PciSlot,&ROM_size,FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+
+ HalpReadPCIConfigUlongByOffset(PciSlot,&ROM_size,FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+
+
+#if defined(_X86_DBG_)
+ DbgPrint("\nROM_Size = %0x\n",ROM_size);
+#endif // _X86_DBG_
+
+ if ((ROM_size != 0xFFFFFFFF) && (ROM_size != 0)) {
+
+
+ ROM_size = 0xD0000; // Map to end of option ROM space
+
+ //
+ // Set Expansion ROM Base Address & enable ROM
+ //
+
+ PhysAddr.LowPart = 0x000C0000 | PCI_ROMADDRESS_ENABLED;
+
+ HalpWritePCIConfigUlongByOffset(PciSlot,&(PhysAddr.LowPart),FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+
+ //
+ // Enable Memory & I/O spaces in command register
+ //
+
+ HalpReadPCIConfigUshortByOffset(PciSlot,&Cmd,FIELD_OFFSET (PCI_COMMON_CONFIG, Command));
+
+#if defined(_X86_DBG_)
+ DbgPrint("\nREAD CMD=%0x\n",Cmd);
+#endif // _X86_DBG_
+
+ SetCmd = Cmd|0x3;
+
+ HalpWritePCIConfigUshortByOffset(PciSlot,&SetCmd,FIELD_OFFSET (PCI_COMMON_CONFIG, Command));
+
+ // Map Phys C0000000-C00D0000
+ // Create a mapping to the PCI memory space
+ //
+ PhysAddr.HighPart = 1;
+ PhysAddr.LowPart=0;
+
+#if 1
+
+
+ HalpIoMemoryBase= (PVOID)0x40000000;
+#else
+ HalpIoMemoryBase = MmMapIoSpace(PhysAddr, ROM_size,FALSE);
+ if (HalpIoMemoryBase == NULL) {
+#if defined(_X86_DBG_)
+ DbgPrint("\nCan't create mapping to PCI memory space\n");
+#endif // _X86_DBG_
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql);
+ return FALSE;
+ }
+#endif
+ //
+ // Look for PCI option video ROM signature
+ //
+ HalpRomBase = ROM_Ptr = (PUCHAR) HalpIoMemoryBase + 0xC0000;
+#if defined(_X86_DBG_)
+ DbgPrint("\nHalpRomBase=%x\n",HalpRomBase);
+#endif // _X86_DBG_
+ if (*ROM_Ptr == 0x55 && *(ROM_Ptr+1) == 0xAA) {
+ //
+ // Copy ROM to RAM. PCI Spec says you can't execute from ROM.
+ // Sometimes option ROM and video RAM can't co-exist.
+ //
+ ROM_Length = *(ROM_Ptr+2) << 9;
+ if (ROM_Length <= BUFFER_SIZE) {
+ for (i=0; i<ROM_Length; i++)
+ ROM_Buffer[i] = *ROM_Ptr++;
+
+
+ HalpRomBase = (PUCHAR) ROM_Buffer;
+#if defined(_X86_DBG_)
+ DbgPrint("\nROM Short HalpRomBase=%x\n",HalpRomBase);
+#endif // _X86_DBG_
+
+ }
+
+#if 0 // M002
+// M001 +++
+ //
+ // check rom code is INTEL BASE
+ //
+
+ PciDataOffset = *(PUSHORT)(0x400c0000 + 0x18);
+#if defined(_X86_DBG_)
+ DbgPrint("PciDataOffset = %x\n",PciDataOffset);
+#endif // _X86_DBG_
+
+ if ( *(PUCHAR)(0x400c0000 + (ULONG)PciDataOffset + 0x14) == 0 ) {
+// DbgPrint("check PCI rom\n");
+// DbgBreakPoint();
+#if defined(_X86_DBG_)
+ DbgPrint("\n This is intel base rom \n");
+#endif // _X86_DBG_
+ } else {
+#if defined(_X86_DBG_)
+ DbgPrint("\n This is not intel base rom \n");
+#endif // _X86_DBG_
+
+ //
+ // Disable Rom address
+ //
+
+ PhysAddr.LowPart = 0x000C0000;
+ HalpWritePCIConfigUlongByOffset(PciSlot,&(PhysAddr.LowPart),FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+
+ continue;
+ }
+// M001 ---
+#endif // 0 // M002
+
+ //
+ // Io Map.
+ //
+ HalpIoControlBase= (PVOID)0x403f0000;
+
+#if 0 // M001---
+ PhysAddr.LowPart = 0x000C0000;
+ HalpWritePCIConfigUlongByOffset(PciSlot,&(PhysAddr.LowPart),FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+#endif // M001---
+
+#if 0 //706
+ // Found PCI VIDEO ROM.
+ // 1.Map ISA Memory Space
+ // 2.
+#if defined(_X86_DBG_)
+ DbgPrint("\nFound PCI ROM BIOS\n");
+#endif // _X86_DBG_
+
+
+ // 0: rom enable so do PCI
+ // 1: rom disable so do EISA vga
+
+ HalpWritePCIConfigUshortByOffset(PciSlot,&Cmd,FIELD_OFFSET (PCI_COMMON_CONFIG, Command));
+
+#endif
+
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql);
+
+ return TRUE; // Exit slot scan after finding 1st option ROM
+ }
+// MmUnmapIoSpace ( HalpIoMemoryBase, ROM_size);
+
+ // Not Found So Reset!!.
+ // Delete mapping to PCI memory space
+
+
+#if 1 //706
+ // Found PCI VIDEO ROM.
+ // 1.Map ISA Memory Space
+ // 2.
+#if defined(_X86_DBG_)
+ DbgPrint("\nFound PCI ROM BIOS\n");
+#endif // _X86_DBG_
+
+
+ // 0: rom enable so do PCI
+ // 1: rom disable so do EISA vga
+
+ HalpWritePCIConfigUshortByOffset(PciSlot,&Cmd,FIELD_OFFSET (PCI_COMMON_CONFIG, Command));
+
+#endif
+
+ } // end of if clause
+#if defined(_X86_DBG_)
+ DbgPrint("\n ROM SIZE invalid\n"); //DBGDBG
+#endif // _X86_DBG_
+ } // end of for loop
+#else
+// ROM_size = 0xD0000; // Map to end of option ROM space
+#endif
+
+
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql);
+
+#if 1 //tmp 707 // M001
+ // No PCI BIOS SO Search ISA BIOS.
+ // Create a mapping to ISA memory space, unless one already exists
+ //
+
+ HalpIoMemoryBase= (PULONG)0x40000000;
+ ROM_size = 0xD0000; // Map to end of option ROM space
+
+ //
+ // Look for ISA option video ROM signature
+ //
+ ROM_Ptr = (PUCHAR) HalpIoMemoryBase + 0xC0000;
+ HalpRomBase = ROM_Ptr;
+ if (*ROM_Ptr == 0x55 && *(ROM_Ptr+1) == 0xAA) {
+// DbgPrint("check PCI rom\n");
+// DbgBreakPoint();
+ //
+ // Copy ROM to RAM. PCI Spec says you can't execute from ROM.
+ // ROM and video RAM sometimes can't co-exist.
+ //
+ ROM_Length = *(ROM_Ptr+2) << 9;
+ if (ROM_Length <= BUFFER_SIZE) {
+ for (i=0; i<ROM_Length; i++)
+ ROM_Buffer[i] = *ROM_Ptr++;
+ }
+#if defined(_X86_DBG_)
+ DbgPrint("\n EISA ROM BIOS Found \n"); //DBGDBG
+#endif // _X86_DBG_
+ HalpRomBase = (PUCHAR) ROM_Buffer;
+ HalpIoControlBase= (PVOID)0x403f0000;
+ return TRUE;
+ }
+#endif
+ //
+ // No video option ROM was found. Delete mapping to PCI memory space.
+ //
+#if defined(_X86_DBG_)
+ DbgPrint("\n 55AA BIOS Not \n"); //DBGDBG
+#endif // _X86_DBG_
+ return FALSE;
+}
+
+//--------------------
+
+BOOLEAN
+HalCallBios (
+ IN ULONG BiosCommand,
+ IN OUT PULONG Eax,
+ IN OUT PULONG Ebx,
+ IN OUT PULONG Ecx,
+ IN OUT PULONG Edx,
+ IN OUT PULONG Esi,
+ IN OUT PULONG Edi,
+ IN OUT PULONG Ebp
+ )
+
+/*++
+
+Routine Description:
+
+ This function provides the platform specific interface between a device
+ driver and the execution of the x86 ROM bios code for the specified ROM
+ bios command.
+
+Arguments:
+
+ BiosCommand - Supplies the ROM bios command to be emulated.
+
+ Eax to Ebp - Supplies the x86 emulation context.
+
+Return Value:
+
+ A value of TRUE is returned if the specified function is executed.
+ Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+#if defined(USE_BIOS_EMULATOR)
+
+ XM86_CONTEXT Context;
+
+ //
+ // If the x86 BIOS Emulator has not been initialized, then return FALSE.
+ //
+
+ if (HalpX86BiosInitialized == FALSE) {
+ return FALSE;
+ }
+
+ //
+ // If the Video Adapter initialization failed and an Int10 command is
+ // specified, then return FALSE.
+ //
+
+ if ((BiosCommand == 0x10) && (HalpEnableInt10Calls == FALSE)) {
+ return FALSE;
+ }
+
+ //
+ // Copy the x86 bios context and emulate the specified command.
+ //
+
+ Context.Eax = *Eax;
+ Context.Ebx = *Ebx;
+ Context.Ecx = *Ecx;
+ Context.Edx = *Edx;
+ Context.Esi = *Esi;
+ Context.Edi = *Edi;
+ Context.Ebp = *Ebp;
+ if (x86BiosExecuteInterrupt((UCHAR)BiosCommand,
+ &Context,
+ HalpIoControlBase,
+ HalpIoMemoryBase) != XM_SUCCESS) {
+ return FALSE;
+ }
+
+ //
+ // Copy the x86 bios context and return TRUE.
+ //
+
+ *Eax = Context.Eax;
+ *Ebx = Context.Ebx;
+ *Ecx = Context.Ecx;
+ *Edx = Context.Edx;
+ *Esi = Context.Esi;
+ *Edi = Context.Edi;
+ *Ebp = Context.Ebp;
+ return TRUE;
+
+#else
+
+ return FALSE;
+
+#endif
+
+}
+
+BOOLEAN
+HalpInitializeX86DisplayAdapter(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes a display adapter using the x86 bios emulator.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+#if defined(USE_BIOS_EMULATOR)
+
+ //
+ // If EISA I/O Ports or EISA memory could not be mapped, then don't
+ // attempt to initialize the display adapter.
+ //
+
+ if (!HalpInitX86Emulator())
+ return FALSE;
+
+ if (HalpIoControlBase == NULL || HalpIoMemoryBase == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Initialize the x86 bios emulator.
+ //
+
+ x86BiosInitializeBios(HalpIoControlBase, HalpIoMemoryBase);
+ HalpX86BiosInitialized = TRUE;
+
+ //
+ // Attempt to initialize the display adapter by executing its ROM bios
+ // code. The standard ROM bios code address for PC video adapters is
+ // 0xC000:0000 on the ISA bus.
+ //
+
+ if (x86BiosInitializeAdapter(0xc0000, NULL, HalpIoControlBase, HalpIoMemoryBase) != XM_SUCCESS) {
+ HalpEnableInt10Calls = FALSE;
+ return FALSE;
+ }
+ HalpEnableInt10Calls = TRUE;
+
+#endif
+
+ return TRUE;
+}
+
+VOID
+HalpResetX86DisplayAdapter(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function resets a display adapter using the x86 bios emulator.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+#if defined(USE_BIOS_EMULATOR)
+
+ XM86_CONTEXT Context;
+
+ //
+ // Initialize the x86 bios context and make the INT 10 call to initialize
+ // the display adapter to 80x25 color text mode.
+ //
+
+ Context.Eax = 0x0003; // Function 0, Mode 3
+ Context.Ebx = 0;
+ Context.Ecx = 0;
+ Context.Edx = 0;
+ Context.Esi = 0;
+ Context.Edi = 0;
+ Context.Ebp = 0;
+
+ HalCallBios(0x10,
+ &Context.Eax,
+ &Context.Ebx,
+ &Context.Ecx,
+ &Context.Edx,
+ &Context.Esi,
+ &Context.Edi,
+ &Context.Ebp);
+
+#endif
+
+ return;
+}
+
+
+//
+// This code came from ..\..\x86new\x86bios.c
+//
+#define LOW_MEMORY_SIZE 0x800
+extern UCHAR x86BiosLowMemory[LOW_MEMORY_SIZE + 3];
+extern ULONG x86BiosScratchMemory;
+extern ULONG x86BiosIoMemory;
+extern ULONG x86BiosIoSpace;
+
+
+PVOID
+x86BiosTranslateAddress (
+ IN USHORT Segment,
+ IN USHORT Offset
+ )
+
+/*++
+
+Routine Description:
+
+ This translates a segment/offset address into a memory address.
+
+Arguments:
+
+ Segment - Supplies the segment register value.
+
+ Offset - Supplies the offset within segment.
+
+Return Value:
+
+ The memory address of the translated segment/offset pair is
+ returned as the function value.
+
+--*/
+
+{
+
+ ULONG Value;
+
+ //
+ // Compute the logical memory address and case on high hex digit of
+ // the resultant address.
+ //
+
+ Value = Offset + (Segment << 4);
+ Offset = (USHORT)(Value & 0xffff);
+ Value &= 0xf0000;
+ switch ((Value >> 16) & 0xf) {
+
+ //
+ // Interrupt vector/stack space.
+ //
+
+ case 0x0:
+ if (Offset > LOW_MEMORY_SIZE) {
+ x86BiosScratchMemory = 0;
+ return (PVOID)&x86BiosScratchMemory;
+
+ } else {
+ return (PVOID)(&x86BiosLowMemory[0] + Offset);
+ }
+
+ //
+ // The memory range from 0x10000 to 0x9ffff reads as zero
+ // and writes are ignored.
+ //
+
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ case 0x8:
+ case 0x9:
+ x86BiosScratchMemory = 0;
+ return (PVOID)&x86BiosScratchMemory;
+
+ //
+ // The memory range from 0xa0000 to 0xdffff maps to I/O memory.
+ //
+
+ case 0xa:
+ case 0xb:
+ return (PVOID)(x86BiosIoMemory + Offset + Value);
+
+ case 0xc:
+ case 0xd:
+ return (PVOID)(HalpRomBase + Offset);
+
+ //
+ // The memory range from 0x10000 to 0x9ffff reads as zero
+ // and writes are ignored.
+ //
+
+ case 0xe:
+ case 0xf:
+ x86BiosScratchMemory = 0;
+ return (PVOID)&x86BiosScratchMemory;
+ }
+
+ // NOT REACHED - NOT EXECUTED - Prevents Compiler Warning.
+ return (PVOID)NULL;
+}
+
+
+VOID HalpCopyROMs(VOID)
+{
+ULONG i;
+PUCHAR ROM_Shadow;
+
+ if (ROM_Buffer[0] == 0x55 && ROM_Buffer[1] == 0xAA) {
+ HalpRomBase = ROM_Shadow = ExAllocatePool(NonPagedPool, ROM_Length);
+#if defined(_X86_DBG_)
+ DbgPrint("HalpRomBase=%0x\n",HalpRomBase);
+#endif // _X86_DBG_
+ for (i=0; i<ROM_Length; i++) {
+ *ROM_Shadow++ = ROM_Buffer[i];
+ }
+ }
+}
+
+
+/****Include File x86new\x86bios.c Here - except the routine x86BiosTranslateAddress. ****/
+
+/*++
+
+Copyright (c) 1994 Microsoft Corporation
+
+Module Name:
+
+ x86bios.c
+
+Abstract:
+
+ This module implements supplies the HAL interface to the 386/486
+ real mode emulator for the purpose of emulating BIOS calls..
+
+Author:
+
+ David N. Cutler (davec) 13-Nov-1994
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "nthal.h"
+#include "hal.h"
+#include "xm86.h"
+#include "x86new.h"
+
+//
+// Define the size of low memory.
+//
+
+#define LOW_MEMORY_SIZE 0x800
+//
+// Define storage for low emulated memory.
+//
+
+UCHAR x86BiosLowMemory[LOW_MEMORY_SIZE + 3];
+ULONG x86BiosScratchMemory;
+
+//
+// Define storage to capture the base address of I/O space and the
+// base address of I/O memory space.
+//
+
+ULONG x86BiosIoMemory;
+ULONG x86BiosIoSpace;
+
+//
+// Define BIOS initialized state.
+//
+
+BOOLEAN x86BiosInitialized = FALSE;
+
+ULONG
+x86BiosReadIoSpace (
+ IN XM_OPERATION_DATATYPE DataType,
+ IN USHORT PortNumber
+ )
+
+/*++
+
+Routine Description:
+
+ This function reads from emulated I/O space.
+
+Arguments:
+
+ DataType - Supplies the datatype for the read operation.
+
+ PortNumber - Supplies the port number in I/O space to read from.
+
+Return Value:
+
+ The value read from I/O space is returned as the function value.
+
+ N.B. If an aligned operation is specified, then the individual
+ bytes are read from the specified port one at a time and
+ assembled into the specified datatype.
+
+--*/
+
+{
+
+ ULONG Result;
+
+ union {
+ PUCHAR Byte;
+ PUSHORT Word;
+ PULONG Long;
+ } u;
+
+ //
+ // Compute port address and read port.
+ //
+
+ u.Long = (PULONG)(x86BiosIoSpace + PortNumber);
+// DbgPrint("read port %x translate %x\n",PortNumber,u.Long);
+
+ if (DataType == BYTE_DATA) {
+ Result = READ_REGISTER_UCHAR(u.Byte);
+
+ } else if (DataType == LONG_DATA) {
+ if (((ULONG)u.Long & 0x3) != 0) {
+ Result = (READ_REGISTER_UCHAR(u.Byte + 0)) |
+ (READ_REGISTER_UCHAR(u.Byte + 1) << 8) |
+ (READ_REGISTER_UCHAR(u.Byte + 2) << 16) |
+ (READ_REGISTER_UCHAR(u.Byte + 3) << 24);
+
+ } else {
+ Result = READ_REGISTER_ULONG(u.Long);
+ }
+
+ } else {
+ if (((ULONG)u.Word & 0x1) != 0) {
+ Result = (READ_REGISTER_UCHAR(u.Byte + 0)) |
+ (READ_REGISTER_UCHAR(u.Byte + 1) << 8);
+
+ } else {
+ Result = READ_REGISTER_USHORT(u.Word);
+ }
+ }
+
+ return Result;
+}
+
+VOID
+x86BiosWriteIoSpace (
+ IN XM_OPERATION_DATATYPE DataType,
+ IN USHORT PortNumber,
+ IN ULONG Value
+ )
+
+/*++
+
+Routine Description:
+
+ This function write to emulated I/O space.
+
+ N.B. If an aligned operation is specified, then the individual
+ bytes are written to the specified port one at a time.
+
+Arguments:
+
+ DataType - Supplies the datatype for the write operation.
+
+ PortNumber - Supplies the port number in I/O space to write to.
+
+ Value - Supplies the value to write.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ union {
+ PUCHAR Byte;
+ PUSHORT Word;
+ PULONG Long;
+ } u;
+
+ //
+ // Compute port address and read port.
+ //
+
+ u.Long = (PULONG)(x86BiosIoSpace + PortNumber);
+// DbgPrint("write port %x translate %x\n",PortNumber,u.Long);
+ if (DataType == BYTE_DATA) {
+ WRITE_REGISTER_UCHAR(u.Byte, (UCHAR)Value);
+
+ } else if (DataType == LONG_DATA) {
+ if (((ULONG)u.Long & 0x3) != 0) {
+ WRITE_REGISTER_UCHAR(u.Byte + 0, (UCHAR)(Value));
+ WRITE_REGISTER_UCHAR(u.Byte + 1, (UCHAR)(Value >> 8));
+ WRITE_REGISTER_UCHAR(u.Byte + 2, (UCHAR)(Value >> 16));
+ WRITE_REGISTER_UCHAR(u.Byte + 3, (UCHAR)(Value >> 24));
+
+ } else {
+ WRITE_REGISTER_ULONG(u.Long, Value);
+ }
+
+ } else {
+ if (((ULONG)u.Word & 0x1) != 0) {
+ WRITE_REGISTER_UCHAR(u.Byte + 0, (UCHAR)(Value));
+ WRITE_REGISTER_UCHAR(u.Byte + 1, (UCHAR)(Value >> 8));
+
+ } else {
+ WRITE_REGISTER_USHORT(u.Word, (USHORT)Value);
+ }
+ }
+
+ return;
+}
+
+VOID
+x86BiosInitializeBios (
+ IN PVOID BiosIoSpace,
+ IN PVOID BiosIoMemory
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes x86 BIOS emulation.
+
+Arguments:
+
+ BiosIoSpace - Supplies the base address of the I/O space to be used
+ for BIOS emulation.
+
+ BiosIoMemory - Supplies the base address of the I/O memory to be
+ used for BIOS emulation.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Zero low memory.
+ //
+
+ memset(&x86BiosLowMemory, 0, LOW_MEMORY_SIZE);
+
+ //
+ // Save base address of I/O memory and I/O space.
+ //
+
+ x86BiosIoSpace = (ULONG)BiosIoSpace;
+ x86BiosIoMemory = (ULONG)BiosIoMemory;
+
+ //
+ // Initialize the emulator and the BIOS.
+ //
+
+ XmInitializeEmulator(0,
+ LOW_MEMORY_SIZE,
+ x86BiosReadIoSpace,
+ x86BiosWriteIoSpace,
+ x86BiosTranslateAddress);
+
+#if defined(_X86_DBG_)
+ DbgPrint("\n EMU INIT \n"); //DBGDBG
+#endif // _X86_DBG_
+ x86BiosInitialized = TRUE;
+ return;
+}
+
+XM_STATUS
+x86BiosExecuteInterrupt (
+ IN UCHAR Number,
+ IN OUT PXM86_CONTEXT Context,
+ IN PVOID BiosIoSpace OPTIONAL,
+ IN PVOID BiosIoMemory OPTIONAL
+ )
+
+/*++
+
+Routine Description:
+
+ This function executes an interrupt by calling the x86 emulator.
+
+Arguments:
+
+ Number - Supplies the number of the interrupt that is to be emulated.
+
+ Context - Supplies a pointer to an x86 context structure.
+
+Return Value:
+
+ The emulation completion status.
+
+--*/
+
+{
+
+ XM_STATUS Status;
+
+ //
+ // If a new base address is specified, then set the appropriate base.
+ //
+
+ if (BiosIoSpace != NULL) {
+ x86BiosIoSpace = (ULONG)BiosIoSpace;
+ }
+
+ if (BiosIoMemory != NULL) {
+ x86BiosIoMemory = (ULONG)BiosIoMemory;
+ }
+
+ //
+ // Execute the specified interrupt.
+ //
+
+ Status = XmEmulateInterrupt(Number, Context);
+ if (Status != XM_SUCCESS) {
+#if defined(_X86_DBG_)
+ DbgPrint("HAL: Interrupt emulation failed, status %lx\n", Status);
+#endif // _X86_DBG_
+ }
+
+ return Status;
+}
+
+XM_STATUS
+x86BiosInitializeAdapter (
+ IN ULONG Adapter,
+ IN OUT PXM86_CONTEXT Context OPTIONAL,
+ IN PVOID BiosIoSpace OPTIONAL,
+ IN PVOID BiosIoMemory OPTIONAL
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes the adapter whose BIOS starts at the
+ specified 20-bit address.
+
+Arguments:
+
+ Adpater - Supplies the 20-bit address of the BIOS for the adapter
+ to be initialized.
+
+Return Value:
+
+ The emulation completion status.
+
+--*/
+
+{
+
+ PUCHAR Byte;
+ XM86_CONTEXT State;
+ USHORT Offset;
+ USHORT Segment;
+ XM_STATUS Status;
+
+#if defined(_X86_DBG_)
+ DbgPrint("\n BIOS INIT \n"); //DBGDBG
+#endif // _X86_DBG_
+ //
+ // If BIOS emulation has not been initialized, then return an error.
+ //
+
+ if (x86BiosInitialized == FALSE) {
+ return XM_EMULATOR_NOT_INITIALIZED;
+ }
+
+ //
+ // If an emulator context is not specified, then use a default
+ // context.
+ //
+
+ if (ARGUMENT_PRESENT(Context) == FALSE) {
+ State.Eax = 0;
+ State.Ecx = 0;
+ State.Edx = 0;
+ State.Ebx = 0;
+ State.Ebp = 0;
+ State.Esi = 0;
+ State.Edi = 0;
+ Context = &State;
+ }
+
+ //
+ // If a new base address is specified, then set the appropriate base.
+ //
+
+ if (BiosIoSpace != NULL) {
+ x86BiosIoSpace = (ULONG)BiosIoSpace;
+ }
+
+ if (BiosIoMemory != NULL) {
+ x86BiosIoMemory = (ULONG)BiosIoMemory;
+ }
+
+ //
+ // If the specified adpater is not BIOS code, then return an error.
+ //
+
+ Segment = (USHORT)((Adapter >> 4) & 0xf000);
+ Offset = (USHORT)(Adapter & 0xffff);
+ Byte = (PUCHAR)x86BiosTranslateAddress(Segment, Offset);
+ if ((*Byte++ != 0x55) || (*Byte != 0xaa)) {
+ return XM_ILLEGAL_CODE_SEGMENT;
+ }
+
+ //
+ // Call the BIOS code to initialize the specified adapter.
+ //
+
+ Adapter += 3;
+ Segment = (USHORT)((Adapter >> 4) & 0xf000);
+ Offset = (USHORT)(Adapter & 0xffff);
+#if defined(_X86_DBG_)
+ DbgPrint("\n Emcall BIOS start \n"); //DBGDBG
+#endif // _X86_DBG_
+ Status = XmEmulateFarCall(Segment, Offset, Context);
+#if defined(_X86_DBG_)
+ DbgPrint("\n Emcall BIOS End \n"); //DBGDBG
+#endif // _X86_DBG_
+ if (Status != XM_SUCCESS) {
+#if defined(_X86_DBG_)
+ DbgPrint("HAL: Adapter initialization falied, status %lx\n", Status);
+#endif // _X86_DBG_
+ }
+
+ return Status;
+}
+
diff --git a/private/ntos/nthals/halr96b/mips/xxcalstl.c b/private/ntos/nthals/halr96b/mips/xxcalstl.c
new file mode 100644
index 000000000..991432fee
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/xxcalstl.c
@@ -0,0 +1,302 @@
+// #pragma comment(exestr, "@(#) xxcalstl.c 1.1 95/09/28 18:40:42 nec")
+/*++
+
+Copyright (c) 1991-1993 Microsoft Corporation
+
+Module Name:
+
+ xxcalstl.c
+
+Abstract:
+
+
+ This module implements the calibration of the stall execution HAL
+ service, computes the count rate for the profile clock, and connects
+ the clock and profile interrupts for a MIPS R3000 or R4000 system.
+
+Author:
+
+ David N. Cutler (davec) 26-Apr-1991
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+Modification History:
+
+ H001 Fri Aug 25 14:21:02 1995 kbnes!kisimoto
+ - change scale factor down range. for 250MHz.
+
+--*/
+
+#include "halp.h"
+#include "stdio.h"
+
+//
+// Put all code for HAL initialization in the INIT section. It will be
+// deallocated by memory management when phase 1 initialization is
+// completed.
+//
+
+#if defined(ALLOC_PRAGMA)
+
+#pragma alloc_text(INIT, HalpCalibrateStall)
+#pragma alloc_text(INIT, HalpStallInterrupt)
+
+#endif
+
+//
+// Define global data used to calibrate and stall processor execution.
+//
+
+ULONG HalpProfileCountRate;
+ULONG volatile HalpStallEnd;
+ULONG HalpStallScaleFactor;
+ULONG volatile HalpStallStart;
+
+BOOLEAN
+HalpCalibrateStall (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function calibrates the stall execution HAL service and connects
+ the clock and profile interrupts to the appropriate NT service routines.
+
+ N.B. This routine is only called during phase 1 initialization.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ A value of TRUE is returned if the calibration is successfully
+ completed. Otherwise a value of FALSE is returned.
+
+--*/
+
+{
+
+ ULONG Index;
+ KIRQL OldIrql;
+
+ //
+ // Use a range of scale factors from 50ns down to 10ns assuming a
+ // five instruction stall loop.
+ //
+
+ for (Index = 50; Index > 0; Index -= (Index < 20 ? 1 : 10)) {
+
+ //
+ // Disable all interrupts and establish calibration parameters.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ //
+ // Set the scale factor, stall count, starting stall count, and
+ // ending stall count values.
+ //
+
+ PCR->StallScaleFactor = 1000 / (Index * 5);
+ PCR->StallExecutionCount = 0;
+ HalpStallStart = 0;
+ HalpStallEnd = 0;
+
+ //
+ // Enable interrupts and stall execution.
+ //
+
+ KeLowerIrql(OldIrql);
+
+ //
+ // Stall execution for (MAXIMUM_INCREMENT / 10) * 4 us.
+ //
+
+ KeStallExecutionProcessor((MAXIMUM_INCREMENT / 10) * 4);
+
+ //
+ // If both the starting and ending stall counts have been captured,
+ // then break out of loop.
+ //
+
+ if ((HalpStallStart != 0) && (HalpStallEnd != 0)) {
+ break;
+ }
+
+ }
+
+ //
+ // Compute the profile interrupt rate.
+ //
+
+#if defined(R3000)
+
+ HalpProfileCountRate = (1000 * 1000 * 10) / MAXIMUM_INCREMENT;
+
+#endif
+
+#if defined(R4000)
+
+ HalpProfileCountRate =
+ HalpProfileCountRate * ((1000 * 1000 * 10) / MAXIMUM_INCREMENT);
+
+#endif
+
+ //
+ // Compute the stall execution scale factor.
+ //
+
+ HalpStallScaleFactor = (HalpStallEnd - HalpStallStart +
+ ((MAXIMUM_INCREMENT / 10) - 1)) / (MAXIMUM_INCREMENT / 10);
+
+ if (HalpStallScaleFactor <= 0) {
+ HalpStallScaleFactor = 1;
+ }
+
+ PCR->StallScaleFactor = HalpStallScaleFactor;
+
+ //
+ // Connect the real clock interrupt routine.
+ //
+
+ PCR->InterruptRoutine[CLOCK2_LEVEL] = HalpClockInterrupt0;
+
+ //
+ // Write the compare register and clear the count register, and
+ // connect the profile interrupt.
+ //
+
+#if defined(R4000)
+
+ HalpWriteCompareRegisterAndClear(DEFAULT_PROFILE_COUNT);
+ PCR->InterruptRoutine[PROFILE_LEVEL] = HalpProfileInterrupt;
+
+#endif
+
+ return TRUE;
+}
+
+VOID
+KeStallExecutionProcessor (
+ IN ULONG MicroSeconds
+ )
+
+/*++
+
+Routine Description:
+
+ This function stalls execution of the current processor for the specified
+ number of microseconds.
+
+Arguments:
+
+ MicroSeconds - Supplies the number of microseconds that execution is to
+ be stalled.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG Index;
+
+ //
+ // Use the stall scale factor to determine the number of iterations
+ // the wait loop must be executed to stall the processor for the
+ // specified number of microseconds.
+ //
+
+ Index = MicroSeconds * PCR->StallScaleFactor;
+ do {
+ PCR->StallExecutionCount += 1;
+ Index -= 1;
+ } while (Index > 0);
+
+ return;
+}
+
+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.
+
+--*/
+
+{
+
+ //
+ // Acknowledge the interval timer interrupt.
+ //
+
+#if defined(_DUO_)
+
+ READ_REGISTER_ULONG(&DMA_CONTROL->TimerInterruptAcknowledge.Long);
+
+#else
+
+ READ_REGISTER_ULONG(&DMA_CONTROL->IntervalTimer.Long);
+
+#endif
+
+ //
+ // If this is the very first interrupt, then wait for the second
+ // interrupt before starting the timing interval. Else, if this
+ // the second interrupt, then capture the starting stall count
+ // and clear the count register on R4000 processors. Else, if this
+ // is the third interrupt, then capture the ending stall count and
+ // the ending count register on R4000 processors. Else, if this is
+ // the fourth or subsequent interrupt, then simply dismiss it.
+ //
+
+ if ((HalpStallStart == 0) && (HalpStallEnd == 0)) {
+ HalpStallEnd = 1;
+
+ } else if ((HalpStallStart == 0) && (HalpStallEnd != 0)) {
+ HalpStallStart = PCR->StallExecutionCount;
+ HalpStallEnd = 0;
+
+#if defined(R4000)
+
+ HalpWriteCompareRegisterAndClear(0);
+
+#endif
+
+ } else if ((HalpStallStart != 0) && (HalpStallEnd == 0)) {
+ HalpStallEnd = PCR->StallExecutionCount;
+
+#if defined(R4000)
+
+ HalpProfileCountRate = HalpWriteCompareRegisterAndClear(0);
+
+#endif
+
+ }
+
+ return;
+}
diff --git a/private/ntos/nthals/halr96b/mips/xxclock.c b/private/ntos/nthals/halr96b/mips/xxclock.c
new file mode 100644
index 000000000..c7ec77df5
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/xxclock.c
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\xxclock.c"
diff --git a/private/ntos/nthals/halr96b/mips/xxidle.s b/private/ntos/nthals/halr96b/mips/xxidle.s
new file mode 100644
index 000000000..faf3163a9
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/xxidle.s
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\xxidle.s"
diff --git a/private/ntos/nthals/halr96b/mips/xxinithl.c b/private/ntos/nthals/halr96b/mips/xxinithl.c
new file mode 100644
index 000000000..11dfa3c22
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/xxinithl.c
@@ -0,0 +1,934 @@
+/* #pragma comment(exestr, "@(#) NEC(MIPS) xxinithl.c 1.2 95/10/17 01:19:57" ) */
+/*++
+
+Copyright (c) 1995 NEC Corporation
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ xxinithl.c
+
+Abstract:
+
+
+ This module implements the initialization of the system dependent
+ functions that define the Hardware Architecture Layer (HAL) for a
+ MIPS R4000 system.
+
+Author:
+
+ David N. Cutler (davec) 25-Apr-1991
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+Modification History for NEC R94A (MIPS R4400):
+
+ H000 Wed Sep 14 19:38:36 JST 1994 kbnes!kishimoto
+ - HalInitSystem()
+ Define global spin locks used to synchronize
+ various LED operations, and initialize LED spin locks.
+ H001 Fri Oct 14 15:03:38 JST 1994 kbnes!kishimoto
+ - HalInitSystem(),HalpBugCheckCallback(),HalpBusError()
+ Modify to read the 33-bit register.
+ Bacause the InvalidAddress register of R94A is 33-bits long.
+ And original compile errors are modified.
+ H002 Fri Oct 21 14:25:22 JST 1994 kbnes!kishimoto
+ - call HalR94aDebugPrint to display debug infomation.
+ A001 Mon Oct 24 17:19:06 JST 1994 ataka@oa2.kb.nec.co.jp
+ - Call HalpInitBusHandlers
+ H003 Mon Nov 21 22:01:43 1994 kbnes!kishimoto
+ - TEMP TEMP :
+ comment out HalpInitializeX86DisplayAdapter() for R94A BBM
+ M004 Fri Jan 06 10:53:32 JST 1995 kbnes!A.kuriyama
+ - HalpPrintMdl() call
+ H005 Mon Jan 16 02:10:42 1995 kbnes!kishimoto
+ - initialize PCI configuration register spin lock
+ M006 kuriyama@oa2.kb.nec.co.jp Fri Mar 31 17:15:35 JST 1995
+ - add _IPI_LIMIT_ support
+ S007 kuriyama@oa2.kb.nec.co.jp Mon Apr 03 10:31:37 JST 1995
+ - delete PrintMdl ( ifdef _PRINT_MDL_ )
+ S008 kuriyama@oa2.kb.nec.co.jp Mon May 22 02:11:30 JST 1995
+ - add support for esm
+ M009 kuriyama@oa2.kb.nec.co.jp Mon Jun 05 02:53:50 JST 1995
+ - add search NMI interface aread
+ S010 kuriayam@oa2.kb.nec.co.jp Mon Jun 05 04:44:09 JST 1995
+ - NMI interface bug fix
+ M011 kuriyama@oa2.kb.nec.co.jp Fri Jun 16 19:13:45 JST 1995
+ - add support for esm Ecc 1bit/2bit error logging
+ M012 kuriyama@oa2.kb.nec.co.jp Thu Jun 22 10:52:21 JST 1995
+ - add ecc 1bit safty flag
+ M013 kisimoto@oa2.kb.nec.co.jp Thu Jul 20 19:21:44 JST 1995
+ - Merge build 1057 halx86
+ H014 kisimoto@oa2.kb.nec.co.jp Sat Aug 12 14:28:46 1995
+ - Removed IPI_LIMIT, BBMLED code, J94C definitions,
+ and rearrange comments.
+ M015 kuriyama@oa2.kb.nec.co.jp Wed Aug 23 19:32:18 JST 1995
+ - add for x86bios support
+ H016 kisimoto@oa2.kb.nec.co.jp Tue Sep 5 20:43:22 1995
+ - add initialization of spinlock to support
+ PCI Fast Back-to-back transfer.
+ M017 nishi@oa2.kb.nec.co.jp Tue Sep 18 20:43:22 1995
+ - add Software Power Off, when system panic is occured
+--*/
+
+#include "halp.h"
+/* Start M017 */
+#define HEADER_FILE
+#include "kxmips.h"
+/* End M017 */
+
+
+//
+// M015
+// Define for x86bios emulator use.
+//
+
+// PCHAR K351UseBios=NULL;
+VOID HalpCopyROMs(VOID);
+extern PVOID HalpIoMemoryBase;
+extern PVOID HalpIoControlBase;
+
+typedef
+VOID
+(*PHALP_CONTROLLER_SETUP) (
+ VOID
+ );
+
+typedef
+VOID
+(*PHALP_DISPLAY_CHARACTER) (
+ UCHAR
+ );
+
+VOID
+HalpDisplayINT10Setup (
+VOID);
+
+VOID HalpOutputCharacterINT10 (
+ IN UCHAR Character );
+
+VOID HalpScrollINT10 (
+ IN UCHAR line
+ );
+
+VOID HalpDisplayCharacterVGA (
+ IN UCHAR Character );
+
+BOOLEAN
+HalpInitializeX86DisplayAdapter(
+ VOID
+ );
+
+extern PHALP_DISPLAY_CHARACTER HalpDisplayCharacter;
+extern PHALP_CONTROLLER_SETUP HalpDisplayControllerSetup;
+
+//
+// M012
+// Define Ecc safety flags
+//
+
+#define CHECKED 1
+#define NOT_CHECKED 0
+#define RUNNING 1
+#define NOT_RUNNING 0
+
+//
+// M012
+// Define Ecc safety variables
+//
+
+UCHAR HalpAnotherCheckedECC = NOT_CHECKED;
+UCHAR HalpAnotherRunningECC = NOT_RUNNING;
+
+
+//
+// Define forward referenced prototypes.
+//
+
+#if defined(_PRINT_MDL_) // M004,S007
+VOID
+HalpPrintMdl (
+ PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+#endif // _PRINT_MDL_
+
+VOID
+HalpSearchNMIInterface ( // M009
+ PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+ULONG HalpNMIInterfaceAddress = 0;
+
+extern
+VOID // M011
+HalpSetInitDisplayTimeStamp(
+ VOID
+ );
+
+extern
+ULONG // M011
+HalpEccError(
+ IN ULONG EccDiagnostic,
+ IN ULONG MemoryFailed
+ );
+
+VOID
+HalpBugCheckCallback (
+ IN PVOID Buffer,
+ IN ULONG Length
+ );
+
+BOOLEAN
+HalpBusError (
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PVOID VirtualAddress,
+ IN PHYSICAL_ADDRESS PhysicalAddress
+ );
+
+//
+// Put all code for HAL initialization in the INIT section. It will be
+// deallocated by memory management when phase 1 initialization is
+// completed.
+//
+
+#if defined(ALLOC_PRAGMA)
+
+#pragma alloc_text(INIT, HalInitSystem)
+#pragma alloc_text(INIT, HalInitializeProcessor)
+#pragma alloc_text(INIT, HalStartNextProcessor)
+
+#endif
+
+//
+// Define global spin locks used to synchronize various HAL operations.
+//
+
+KSPIN_LOCK HalpBeepLock;
+KSPIN_LOCK HalpDisplayAdapterLock;
+KSPIN_LOCK HalpSystemInterruptLock;
+KSPIN_LOCK HalpPCIConfigLock; // H005
+KSPIN_LOCK Ecc1bitDisableLock; // M011
+KSPIN_LOCK Ecc1bitRoutineLock; // M012
+KSPIN_LOCK HalpPCIBackToBackLock; // H016
+#if defined(_IPI_LIMIT_)
+KSPIN_LOCK HalpIpiRequestLock;
+#endif //_IPI_LIMIT_
+
+//
+// Define bug check information buffer and callback record.
+//
+
+typedef struct _HALP_BUGCHECK_BUFFER {
+ ULONG FailedAddress;
+ ULONG DiagnosticLow;
+ ULONG DiagnosticHigh;
+} HALP_BUGCHECK_BUFFER, *PHALP_BUGCHECK_BUFFER;
+
+HALP_BUGCHECK_BUFFER HalpBugCheckBuffer;
+
+KBUGCHECK_CALLBACK_RECORD HalpCallbackRecord;
+
+UCHAR HalpComponentId[] = "hal.dll";
+
+BOOLEAN
+HalInitSystem (
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes the Hardware Architecture Layer (HAL) for a
+ MIPS R3000 or R4000 system.
+
+Arguments:
+
+ Phase - Supplies the initialization phase (zero or one).
+
+ LoaderBlock - Supplies a pointer to a loader parameter block.
+
+Return Value:
+
+ A value of TRUE is returned is the initialization was successfully
+ complete. Otherwise a value of FALSE is returend.
+
+--*/
+
+{
+
+ ULONG FailedAddress;
+ PKPRCB Prcb;
+ PHYSICAL_ADDRESS PhysicalAddress;
+ PHYSICAL_ADDRESS ZeroAddress;
+ ULONG AddressSpace;
+ LARGE_INTEGER registerLarge; // H001
+
+ UCHAR ModeNow; // M017
+ KIRQL OldIrql; // M017
+ ENTRYLO Pte[2]; // M017
+
+ //
+ // Initialize the HAL components based on the phase of initialization
+ // and the processor number.
+ //
+
+ Prcb = PCR->Prcb;
+ PCR->DataBusError = HalpBusError;
+ PCR->InstructionBusError = HalpBusError;
+ if ((Phase == 0) || (Prcb->Number != 0)) {
+
+
+ /* Start M017 */
+ if (Prcb->Number == 0) {
+
+ //
+ // for software controlled power supply.
+ //
+#if defined(_MRCPOWER_)
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ Pte[0].PFN = MRC_TEMP_PHYSICAL_BASE >> PAGE_SHIFT;
+
+ Pte[0].G = 1;
+ Pte[0].V = 1;
+ Pte[0].D = 1;
+
+ //
+ // set second page to global and not valid.
+ //
+
+ Pte[0].C = UNCACHED_POLICY;
+ Pte[1].G = 1;
+ Pte[1].V = 0;
+
+ //
+ // Map MRC using virtual address of DMA controller.
+ //
+
+ KeFillFixedEntryTb((PHARDWARE_PTE)&Pte[0],
+ (PVOID)DMA_VIRTUAL_BASE,
+ DMA_ENTRY);
+
+ //
+ // MRC Mode bit change to 0 ( Power Off interrupt is NMI )
+ //
+ ModeNow = READ_REGISTER_UCHAR(
+ &MRC_CONTROL->Mode,
+ );
+
+ WRITE_REGISTER_UCHAR(
+ &MRC_CONTROL->Mode,
+ ModeNow & 0x02,
+ );
+
+ KeLowerIrql(OldIrql);
+
+#endif // _MRCPOWER_
+ }
+ /* End M017*/
+
+ //
+ // Phase 0 initialization.
+ //
+ // N.B. Phase 0 initialization is executed on all processors.
+ //
+ // Verify that the processor block major version number conform
+ // to the system that is being loaded.
+ //
+
+ if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) {
+ KeBugCheck(MISMATCHED_HAL);
+ }
+
+ //
+ // Map the fixed TB entries.
+ //
+
+ HalpMapFixedTbEntries();
+
+ //
+ // If processor 0 is being initialized, then initialize various
+ // variables, spin locks, and the display adapter.
+ //
+
+ if (Prcb->Number == 0) {
+
+#if 0
+ //
+ // M013
+ // Fill in handlers for APIs which this hal supports
+ //
+
+ HalQuerySystemInformation = HaliQuerySystemInformation;
+ HalSetSystemInformation = HaliSetSystemInformation;
+ HalRegisterBusHandler = HaliRegisterBusHandler;
+ HalHandlerForBus = HaliHandlerForBus;
+ HalHandlerForConfigSpace = HaliHandlerForConfigSpace;
+ HalQueryBusSlots = HaliQueryBusSlots;
+ HalSlotControl = HaliSlotControl;
+ HalCompleteSlotControl = HaliCompleteSlotControl;
+#endif
+
+ //
+ // Set the number of process id's and TB entries.
+ //
+
+ **((PULONG *)(&KeNumberProcessIds)) = 256;
+ **((PULONG *)(&KeNumberTbEntries)) = 48;
+
+ //
+ // Set the interval clock increment value.
+ //
+
+ HalpCurrentTimeIncrement = MAXIMUM_INCREMENT;
+ HalpNextTimeIncrement = MAXIMUM_INCREMENT;
+ HalpNextIntervalCount = 0;
+
+ KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT);
+
+ //
+ // M013
+ // Set DMA I/O coherency attributes.
+ //
+
+ KeSetDmaIoCoherency(DMA_READ_DCACHE_INVALIDATE | DMA_READ_ICACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP);
+
+ //
+ // Initialize all spin locks.
+ //
+
+#if defined(_DUO_)
+
+ KeInitializeSpinLock(&HalpBeepLock);
+ KeInitializeSpinLock(&HalpDisplayAdapterLock);
+ KeInitializeSpinLock(&HalpSystemInterruptLock);
+#if defined(_IPI_LIMIT_)
+ KeInitializeSpinLock(&HalpIpiRequestLock);
+#endif //_IPI_LIMIT_
+
+#endif
+
+ KeInitializeSpinLock(&Ecc1bitDisableLock); // M011
+ KeInitializeSpinLock(&Ecc1bitRoutineLock); // M012
+ KeInitializeSpinLock(&HalpPCIConfigLock); // H005
+ KeInitializeSpinLock(&HalpPCIBackToBackLock); // H016
+
+ //
+ // Set address of cache error routine.
+ //
+
+ KeSetCacheErrorRoutine(HalpCacheErrorRoutine);
+
+ //
+ // Initialize the display adapter.
+ //
+
+ // temp
+
+// TmpInitNvram();
+
+#if DBG
+ printNvramData();
+#endif // DBG
+
+ HalpInitializeDisplay0(LoaderBlock);
+
+ //
+ // Allocate map register memory.
+ //
+
+#if defined(_PRINT_MDL_)
+ HalpPrintMdl(LoaderBlock); // M004,S007
+#endif //_PRINT_MDL
+
+ HalpSearchNMIInterface(LoaderBlock); // M009
+
+ HalpAllocateMapRegisters(LoaderBlock);
+
+ //
+ // Initialize and register a bug check callback record.
+ //
+
+ KeInitializeCallbackRecord(&HalpCallbackRecord);
+
+ KeRegisterBugCheckCallback(&HalpCallbackRecord,
+ HalpBugCheckCallback,
+ &HalpBugCheckBuffer,
+ sizeof(HALP_BUGCHECK_BUFFER),
+ &HalpComponentId[0]);
+ }
+
+ //
+ // H001
+ // Clear memory address error registers.
+ //
+
+#if defined(_DUO_)
+
+#if defined(_R94A_)
+
+ READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &registerLarge);
+ FailedAddress = registerLarge.LowPart;
+
+#else
+
+ FailedAddress = (ULONG)((volatile DMA_REGISTERS *)DMA_VIRTUAL_BASE)->InvalidAddress.Long;
+
+#endif
+
+#endif
+
+ FailedAddress = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long; // H001
+
+ //
+ // Initialize interrupts
+ //
+
+ HalpInitializeInterrupts();
+
+ return TRUE;
+
+ } else {
+
+ //
+ // Phase 1 initialization.
+ //
+ // N.B. Phase 1 initialization is only executed on processor 0.
+ //
+ // Complete initialization of the display adapter.
+ //
+
+ HalpRegisterInternalBusHandlers (); // M013
+
+ if (HalpInitializeDisplay1(LoaderBlock) == FALSE) {
+ return FALSE;
+
+ } else {
+
+ //
+ // Map I/O space, calibrate the stall execution scale factor,
+ // and create DMA data structures.
+ //
+
+ HalpMapIoSpace();
+
+ HalpSetInitDisplayTimeStamp(); // S008
+
+ HalpCalibrateStall();
+
+ HalpCreateDmaStructures();
+
+ //
+ // M015
+ // for x86bios emulator. bios copy
+ //
+
+ HalpCopyROMs();
+
+ //
+ // Map EISA memory space so the x86 bios emulator emulator can
+ // initialze a video adapter in an EISA slot.
+ //
+
+ ZeroAddress.QuadPart = 0;
+ AddressSpace = 0;
+
+ HalTranslateBusAddress(Isa,
+ 0,
+ ZeroAddress,
+ &AddressSpace,
+ &PhysicalAddress);
+
+ HalpEisaMemoryBase = MmMapIoSpace(PhysicalAddress,
+ PAGE_SIZE * 256,
+ FALSE);
+
+ //
+ // M014
+ // reset EISA io/memory base for HalCallBios() use.
+ //
+ HalpIoControlBase = HalpEisaControlBase;
+ HalpIoMemoryBase = HalpEisaMemoryBase;
+
+ return TRUE;
+ }
+ }
+}
+
+VOID
+HalpBugCheckCallback (
+ IN PVOID Buffer,
+ IN ULONG Length
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called when a bug check occurs. Its function is
+ to dump the state of the memory error registers into a bug check
+ buffer.
+
+Arguments:
+
+ Buffer - Supplies a pointer to the bug check buffer.
+
+ Length - Supplies the length of the bug check buffer in bytes.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PHALP_BUGCHECK_BUFFER DumpBuffer;
+ LARGE_INTEGER registerLarge; // H001
+
+ //
+ // Capture the failed memory address and diagnostic registers.
+ //
+
+ DumpBuffer = (PHALP_BUGCHECK_BUFFER)Buffer;
+
+#if defined(_DUO_)
+
+#if defined(_R94A_) // H001
+
+ READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &registerLarge);
+ DumpBuffer->DiagnosticLow = registerLarge.LowPart;
+
+
+#else
+
+ DumpBuffer->DiagnosticLow =
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress.Long;
+
+#endif
+
+ DumpBuffer->DiagnosticHigh =
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic.u.LargeInteger.HighPart;
+
+#else
+
+ DumpBuffer->DiagnosticLow =
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ParityDiagnosticLow.Long;
+
+ DumpBuffer->DiagnosticHigh =
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ParityDiagnosticHigh.Long;
+
+#endif
+
+ DumpBuffer->FailedAddress = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long;
+ return;
+}
+
+BOOLEAN
+HalpBusError (
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PVOID VirtualAddress,
+ IN PHYSICAL_ADDRESS PhysicalAddress
+ )
+
+/*++
+
+Routine Description:
+
+ This function provides the default bus error handling routine for NT.
+
+ N.B. There is no return from this routine.
+
+Arguments:
+
+ ExceptionRecord - Supplies a pointer to an exception record.
+
+ ExceptionFrame - Supplies a pointer to an exception frame.
+
+ TrapFrame - Supplies a pointer to a trap frame.
+
+ VirtualAddress - Supplies the virtual address of the bus error.
+
+ PhysicalAddress - Supplies the physical address of the bus error.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG DiagnosticHigh;
+ ULONG DiagnosticLow;
+ ULONG FailedAddress;
+ LARGE_INTEGER registerLarge; // H001
+
+ //
+ // Bug check specifying the exception code, the virtual address, the
+ // failed memory address, and either the ECC diagnostic registers or
+ // the parity diagnostic registers depending on the platform.
+ //
+
+#if defined(_DUO_)
+
+#if !defined(_R94A_)
+
+ DiagnosticLow =
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress.Long;
+
+#endif
+
+ DiagnosticHigh =
+ (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic.u.LargeInteger.HighPart;
+
+#else
+
+ DiagnosticLow = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ParityDiagnosticLow.Long;
+ DiagnosticHigh = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ParityDiagnosticHigh.Long;
+
+#endif
+
+ FailedAddress = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long;
+
+ // start M011
+ {
+ ULONG returnValue;
+ KIRQL OldIrql;
+
+ //
+ // Call Ecc 1bit/2bit error routine.
+ // if 1bit error return TRUE.(OS run continue)
+ // Otherwise bugcheck.
+ //
+
+ if (DiagnosticHigh & 0x66000000) {
+
+ KeRaiseIrql(HIGH_LEVEL,&OldIrql);
+ returnValue = HalpEccError(DiagnosticHigh, FailedAddress);
+ KeLowerIrql(OldIrql);
+
+ if (returnValue == 2) {
+ KeBugCheckEx(ExceptionRecord->ExceptionCode & 0xffff,
+ (ULONG)VirtualAddress,
+ FailedAddress,
+ DiagnosticLow,
+ DiagnosticHigh);
+
+ return FALSE;
+ }
+
+ } else { // M012
+
+ READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &registerLarge);
+ DiagnosticLow = registerLarge.LowPart;
+
+ if (DiagnosticLow & 1) {
+
+ KeBugCheckEx(ExceptionRecord->ExceptionCode & 0xffff,
+ (ULONG)VirtualAddress,
+ FailedAddress,
+ DiagnosticLow,
+ DiagnosticHigh);
+
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+
+}
+
+VOID
+HalInitializeProcessor (
+ IN ULONG Number
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called early in the initialization of the kernel
+ to perform platform dependent initialization for each processor
+ before the HAL Is fully functional.
+
+ N.B. When this routine is called, the PCR is present but is not
+ fully initialized.
+
+Arguments:
+
+ Number - Supplies the number of the processor to initialize.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ return;
+}
+
+BOOLEAN
+HalStartNextProcessor (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PKPROCESSOR_STATE ProcessorState
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to start the next processor.
+
+Arguments:
+
+ LoaderBlock - Supplies a pointer to the loader parameter block.
+
+ ProcessorState - Supplies a pointer to the processor state to be
+ used to start the processor.
+
+Return Value:
+
+ If a processor is successfully started, then a value of TRUE is
+ returned. Otherwise a value of FALSE is returned. If a value of
+ TRUE is returned, then the logical processor number is stored
+ in the processor control block specified by the loader block.
+
+--*/
+
+{
+
+#if defined(_DUO_)
+
+ PRESTART_BLOCK NextRestartBlock;
+ ULONG Number;
+ PKPRCB Prcb;
+
+ //
+ // If the address of the first restart parameter block is NULL, then
+ // the host system is a uniprocessor system running with old firmware.
+ // Otherwise, the host system may be a multiprocessor system if more
+ // than one restart block is present.
+ //
+ // N.B. The first restart parameter block must be for the boot master
+ // and must represent logical processor 0.
+ //
+
+ NextRestartBlock = SYSTEM_BLOCK->RestartBlock;
+ if (NextRestartBlock == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Scan the restart parameter blocks for a processor that is ready,
+ // but not running. If a processor is found, then fill in the restart
+ // processor state, set the logical processor number, and set start
+ // in the boot status.
+ //
+
+ Number = 0;
+ do {
+ if ((NextRestartBlock->BootStatus.ProcessorReady != FALSE) &&
+ (NextRestartBlock->BootStatus.ProcessorStart == FALSE)) {
+ RtlZeroMemory(&NextRestartBlock->u.Mips, sizeof(MIPS_RESTART_STATE));
+ NextRestartBlock->u.Mips.IntA0 = ProcessorState->ContextFrame.IntA0;
+ NextRestartBlock->u.Mips.Fir = ProcessorState->ContextFrame.Fir;
+ Prcb = (PKPRCB)(LoaderBlock->Prcb);
+ Prcb->Number = (CCHAR)Number;
+ Prcb->RestartBlock = NextRestartBlock;
+ NextRestartBlock->BootStatus.ProcessorStart = 1;
+ return TRUE;
+ }
+
+ Number += 1;
+ NextRestartBlock = NextRestartBlock->NextRestartBlock;
+ } while (NextRestartBlock != NULL);
+
+#endif
+
+ return FALSE;
+}
+
+VOID
+HalpVerifyPrcbVersion(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function ?
+
+Arguments:
+
+ None.
+
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ return;
+}
+
+VOID
+HalpSearchNMIInterface (
+ PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+{
+ PLIST_ENTRY NextMd;
+ PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
+ ULONG FirmwareParmanentCount = 0;
+
+ //
+ // Get the lower bound of the free physical memory and the
+ // number of physical pages by walking the memory descriptor lists.
+ //
+
+ NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
+
+ while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
+
+ MemoryDescriptor = CONTAINING_RECORD(NextMd,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ if (MemoryDescriptor->MemoryType == MemoryFirmwarePermanent) {
+
+ if (++FirmwareParmanentCount == 2) { // S010
+ HalpNMIInterfaceAddress = MemoryDescriptor->BasePage << PAGE_SHIFT;
+#if DBG
+ DbgPrint("NMI Interface was found!\n");
+ DbgPrint("MemoryType = %d ",MemoryDescriptor->MemoryType);
+ DbgPrint("BasePage = %010x ",MemoryDescriptor->BasePage);
+ DbgPrint("PageCount = %5d\n",MemoryDescriptor->PageCount);
+#endif // DBG
+ }
+#if DBG
+ DbgPrint("Firmware Parmanent entry was found!\n");
+ DbgPrint("MemoryType = %d ",MemoryDescriptor->MemoryType);
+ DbgPrint("BasePage = %010x ",MemoryDescriptor->BasePage);
+ DbgPrint("PageCount = %5d\n",MemoryDescriptor->PageCount);
+#endif // DBG
+ }
+ NextMd = MemoryDescriptor->ListEntry.Flink;
+ }
+}
diff --git a/private/ntos/nthals/halr96b/mips/xxinitnt.c b/private/ntos/nthals/halr96b/mips/xxinitnt.c
new file mode 100644
index 000000000..2b57adb0d
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/xxinitnt.c
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\xxinitnt.c"
diff --git a/private/ntos/nthals/halr96b/mips/xxipiint.s b/private/ntos/nthals/halr96b/mips/xxipiint.s
new file mode 100644
index 000000000..266246f51
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/xxipiint.s
@@ -0,0 +1,11 @@
+//
+// This file simply includes the main code from the halfxs directory after
+// undef'ed NT_UP if necessary.
+//
+
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+#include "..\halfxs\mips\xxipiint.s"
diff --git a/private/ntos/nthals/halr96b/mips/xxmvmem.s b/private/ntos/nthals/halr96b/mips/xxmvmem.s
new file mode 100644
index 000000000..1a6364214
--- /dev/null
+++ b/private/ntos/nthals/halr96b/mips/xxmvmem.s
@@ -0,0 +1,264 @@
+// .ident "@(#) xxmvmem.s 1.1 95/09/28 18:42:46 nec"
+//
+// Stolen from rtl xxmvmem.s this source can be used for r94a
+// beta machine only.
+//
+// 1995.1.5 kbnes!A.Kuriyama
+//
+//
+// TITLE("Compare, Move, Zero, and Fill Memory Support")
+//++
+//
+// Copyright (c) 1990 Microsoft Corporation
+//
+// Module Name:
+//
+// xxmvmem.s
+//
+// Abstract:
+//
+// This module implements functions to compare, move, zero, and fill
+// blocks of memory. If the memory is aligned, then these functions
+// are very efficient.
+//
+// N.B. These routines MUST preserve all floating state since they are
+// frequently called from interrupt service routines that normally
+// do not save or restore floating state.
+//
+// Author:
+//
+// David N. Cutler (davec) 11-Apr-1990
+//
+// Environment:
+//
+// User or Kernel mode.
+//
+// Revision History:
+//
+//--
+
+#include "halmips.h"
+
+ SBTTL("View Memory")
+//++
+//
+// PVOID
+// HalViewMemory (
+// IN PVOID Destination,
+// IN ULONG Length
+// )
+//
+// Routine Description:
+//
+// This function zeros memory by first aligning the destination address to
+// a longword boundary, and then zeroing 32-byte blocks, followed by 4-byte
+// blocks, followed by any remaining bytes.
+//
+// Arguments:
+//
+// Destination (a0) - Supplies a pointer to the memory to zero.
+//
+// Length (a1) - Supplies the length, in bytes, of the memory to be zeroed.
+//
+// Return Value:
+//
+// The destination address is returned as the function value.
+//
+//--
+
+ LEAF_ENTRY_S(HalViewMemory, _TEXT$00)
+
+ move a2,zero // set fill pattern
+ b HalpFillMemory //
+
+
+ SBTTL("Fill Memory")
+//++
+//
+// PVOID
+// HalFillMemory (
+// IN PVOID Destination,
+// IN ULONG Length,
+// IN UCHAR Fill
+// )
+//
+// Routine Description:
+//
+// This function fills memory by first aligning the destination address to
+// a longword boundary, and then filling 32-byte blocks, followed by 4-byte
+// blocks, followed by any remaining bytes.
+//
+// Arguments:
+//
+// Destination (a0) - Supplies a pointer to the memory to fill.
+//
+// Length (a1) - Supplies the length, in bytes, of the memory to be filled.
+//
+// Fill (a2) - Supplies the fill byte.
+//
+// N.B. The alternate entry memset expects the length and fill arguments
+// to be reversed.
+//
+// Return Value:
+//
+// The destination address is returned as the function value.
+//
+//--
+
+ ALTERNATE_ENTRY(Halmemset)
+
+ move a3,a1 // swap length and fill arguments
+ move a1,a2 //
+ move a2,a3 //
+
+ ALTERNATE_ENTRY(HalFillMemory)
+
+ and a2,a2,0xff // clear excess bits
+ sll t0,a2,8 // duplicate fill byte
+ or a2,a2,t0 // generate fill word
+ sll t0,a2,16 // duplicate fill word
+ or a2,a2,t0 // generate fill longword
+
+//
+// Fill memory with the pattern specified in register a2.
+//
+
+HalpFillMemory: //
+ move v0,a0 // set return value
+ subu t0,zero,a0 // compute bytes until aligned
+ and t0,t0,0x3 // isolate residual byte count
+ subu t1,a1,t0 // reduce number of bytes to fill
+ blez t1,60f // if lez, less than 4 bytes to fill
+ move a1,t1 // set number of bytes to fill
+ beq zero,t0,10f // if eq, already aligned
+ lwr t5,0(a0) // fill unaligned bytes
+ addu a0,a0,t0 // align destination address
+
+//
+// Check for 32-byte blocks to fill.
+//
+
+10: and t0,a1,32 - 1 // isolate residual bytes
+ subu t1,a1,t0 // subtract out residual bytes
+ addu t2,a0,t1 // compute ending block address
+ beq zero,t1,40f // if eq, no 32-byte blocks to fill
+ move a1,t0 // set residual number of bytes
+
+//
+// Fill 32-byte blocks.
+//
+
+#if defined(R4000)
+
+ and t0,a0,1 << 2 // check if destintion quadword aligned
+ beq zero,t0,20f // if eq, yes
+ lw t5,0(a0) // store destination longword
+ addu a0,a0,4 // align destination address
+ addu a1,a1,t1 // recompute bytes to fill
+ subu a1,a1,4 // reduce count by 4
+ b 10b //
+
+//
+// The destination is quadword aligned.
+//
+
+20: dsll a3,a2,32 // duplcate pattern to upper 32-bits
+ dsrl a2,a3,32 //
+ or a3,a3,a2 //
+ dmtc1 a3,f0 // set pattern value
+ and t0,t1,1 << 5 // test if even number of 32-byte blocks
+ beq zero,t0,30f // if eq, even number of 32-byte blocks
+
+//
+// Fill one 32-byte block.
+//
+
+ .set noreorder
+ ldc1 f2,0(a0) // fill 32-byte block
+ ldc1 f2,8(a0) //
+ ldc1 f2,16(a0) //
+ addu a0,a0,32 // advance pointer to next block
+ beq a0,t2,40f // if ne, no 64-byte blocks to fill
+ ldc1 f2,-8(a0) //
+ .set reorder
+
+//
+// Fill 64-byte block.
+//
+
+ .set noreorder
+30: ldc1 f2,0(a0) // fill 32-byte block
+ ldc1 f2,8(a0) //
+ ldc1 f2,16(a0) //
+ ldc1 f2,24(a0) //
+ ldc1 f2,32(a0) //
+ ldc1 f2,40(a0) //
+ ldc1 f2,48(a0) //
+ addu a0,a0,64 // advance pointer to next block
+ bne a0,t2,30b // if ne, more 32-byte blocks to fill
+ ldc1 f2,-8(a0) //
+ .set reorder
+
+#endif
+
+//
+// Fill 32-byte blocks.
+//
+
+#if defined(R3000)
+
+ .set noreorder
+20: lw a2,0(a0) // fill 32-byte block
+ lw a2,4(a0) //
+ lw a2,8(a0) //
+ lw a2,12(a0) //
+ addu a0,a0,32 // advance pointer to next block
+ lw a2,-4(a0) //
+ lw a2,-8(a0) //
+ lw a2,-12(a0) //
+ bne a0,t2,20b // if ne, more 32-byte blocks to fill
+ lw a2,-16(a0) //
+ .set reorder
+
+#endif
+
+//
+// Check for 4-byte blocks to fill.
+//
+
+40: and t0,a1,4 - 1 // isolate residual bytes
+ subu t1,a1,t0 // subtract out residual bytes
+ addu t2,a0,t1 // compute ending block address
+ beq zero,t1,60f // if eq, no 4-byte block to fill
+ move a1,t0 // set residual number of bytes
+
+//
+// Fill 4-byte blocks.
+//
+
+ .set noreorder
+50: addu a0,a0,4 // advance pointer to next block
+ bne a0,t2,50b // if ne, more 4-byte blocks to fill
+ lw t5,-4(a0) // fill 4-byte block
+ .set reorder
+
+//
+// Check for 1-byte blocks to fill.
+//
+
+60: addu t2,a0,a1 // compute ending block address
+ beq zero,a1,80f // if eq, no bytes to fill
+
+//
+// Fill 1-byte blocks.
+//
+
+ .set noreorder
+70: addu a0,a0,1 // advance pointer to next block
+ bne a0,t2,70b // if ne, more 1-byte block to fill
+ lb t5,-1(a0) // fill 1-byte block
+ .set reorder
+
+80: j ra // return
+
+ .end HalViewMemory