summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halr98b/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/halr98b/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/halr98b/mips')
-rw-r--r--private/ntos/nthals/halr98b/mips/allstart.c412
-rw-r--r--private/ntos/nthals/halr98b/mips/cacherr.h225
-rw-r--r--private/ntos/nthals/halr98b/mips/cacherr.s1435
-rw-r--r--private/ntos/nthals/halr98b/mips/cirrus.h298
-rw-r--r--private/ntos/nthals/halr98b/mips/cmdcnst.h105
-rw-r--r--private/ntos/nthals/halr98b/mips/esmnvram.h271
-rw-r--r--private/ntos/nthals/halr98b/mips/glint.h580
-rw-r--r--private/ntos/nthals/halr98b/mips/halp.h674
-rw-r--r--private/ntos/nthals/halr98b/mips/j4cache.s1190
-rw-r--r--private/ntos/nthals/halr98b/mips/j4flshbf.s58
-rw-r--r--private/ntos/nthals/halr98b/mips/j4flshio.c212
-rw-r--r--private/ntos/nthals/halr98b/mips/j4prof.c340
-rw-r--r--private/ntos/nthals/halr98b/mips/jxbeep.c131
-rw-r--r--private/ntos/nthals/halr98b/mips/jxdisp.c3544
-rw-r--r--private/ntos/nthals/halr98b/mips/jxebsup.c1178
-rw-r--r--private/ntos/nthals/halr98b/mips/jxenvirv.c691
-rw-r--r--private/ntos/nthals/halr98b/mips/jxmapio.c124
-rw-r--r--private/ntos/nthals/halr98b/mips/jxmaptb.c68
-rw-r--r--private/ntos/nthals/halr98b/mips/jxport.c779
-rw-r--r--private/ntos/nthals/halr98b/mips/jxreturn.c181
-rw-r--r--private/ntos/nthals/halr98b/mips/jxsysint.c327
-rw-r--r--private/ntos/nthals/halr98b/mips/jxtime.c319
-rw-r--r--private/ntos/nthals/halr98b/mips/jxusage.c541
-rw-r--r--private/ntos/nthals/halr98b/mips/mipsdat.c137
-rw-r--r--private/ntos/nthals/halr98b/mips/mode542x.h1302
-rw-r--r--private/ntos/nthals/halr98b/mips/modeset.h86
-rw-r--r--private/ntos/nthals/halr98b/mips/pcip.h189
-rw-r--r--private/ntos/nthals/halr98b/mips/r98bdef.h228
-rw-r--r--private/ntos/nthals/halr98b/mips/r98breg.h649
-rw-r--r--private/ntos/nthals/halr98b/mips/rgb525.h468
-rw-r--r--private/ntos/nthals/halr98b/mips/rxbusdat.c290
-rw-r--r--private/ntos/nthals/halr98b/mips/rxclock.s368
-rw-r--r--private/ntos/nthals/halr98b/mips/rxdisp.c61
-rw-r--r--private/ntos/nthals/halr98b/mips/rxdspt.c547
-rw-r--r--private/ntos/nthals/halr98b/mips/rxecc.c791
-rw-r--r--private/ntos/nthals/halr98b/mips/rxeif.c694
-rw-r--r--private/ntos/nthals/halr98b/mips/rxesm.c761
-rw-r--r--private/ntos/nthals/halr98b/mips/rxesm.h84
-rw-r--r--private/ntos/nthals/halr98b/mips/rxhalp.h212
-rw-r--r--private/ntos/nthals/halr98b/mips/rxhwlog.c1409
-rw-r--r--private/ntos/nthals/halr98b/mips/rxhwlog.h469
-rw-r--r--private/ntos/nthals/halr98b/mips/rxhwsup.c2124
-rw-r--r--private/ntos/nthals/halr98b/mips/rxinfo.c95
-rw-r--r--private/ntos/nthals/halr98b/mips/rxint.s1564
-rw-r--r--private/ntos/nthals/halr98b/mips/rxipiint.s79
-rw-r--r--private/ntos/nthals/halr98b/mips/rxisabus.c729
-rw-r--r--private/ntos/nthals/halr98b/mips/rxnvr.h176
-rw-r--r--private/ntos/nthals/halr98b/mips/rxpcibrd.c1157
-rw-r--r--private/ntos/nthals/halr98b/mips/rxpcibus.c2826
-rw-r--r--private/ntos/nthals/halr98b/mips/rxpciint.c615
-rw-r--r--private/ntos/nthals/halr98b/mips/rxsysbus.c214
-rw-r--r--private/ntos/nthals/halr98b/mips/tga.h101
-rw-r--r--private/ntos/nthals/halr98b/mips/x86bios.c1256
-rw-r--r--private/ntos/nthals/halr98b/mips/xxcalstl.c260
-rw-r--r--private/ntos/nthals/halr98b/mips/xxclock.c207
-rw-r--r--private/ntos/nthals/halr98b/mips/xxidle.s76
-rw-r--r--private/ntos/nthals/halr98b/mips/xxinithl.c894
-rw-r--r--private/ntos/nthals/halr98b/mips/xxinitnt.c424
58 files changed, 35225 insertions, 0 deletions
diff --git a/private/ntos/nthals/halr98b/mips/allstart.c b/private/ntos/nthals/halr98b/mips/allstart.c
new file mode 100644
index 000000000..debb7dcf6
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/allstart.c
@@ -0,0 +1,412 @@
+
+/*++
+
+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.
+
+--*/
+
+/*
+ */
+
+
+#include "halp.h"
+
+KINTERRUPT HalpEifInterrupt[R98B_MAX_CPU];
+
+//
+// This is Interrupt Level define.
+// HalpIntLevelofIpr[HalpMachineType][Ipr] = INT X
+//
+UCHAR HalpIntLevelofIpr[R98_CPU_NUM_TYPE][NUMBER_OF_IPR_BIT]={
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,5,5,5,5},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,4,4,4,4}
+};
+
+//
+// This is Interrupt connect pattern.
+// [NumberOfCpu][IPR] meas what connect cpu(Affinity But UCHAR. when use you must Cast Affinity)
+//
+UCHAR HalpIntConnectPattern[R98B_MAX_CPU][NUMBER_OF_IPR_BIT]={
+// At 1 Processor System
+{0,1,1,0,1,1,0,1,1,0,0,0,0,1,1,1, 0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,
+ 0,0,0x0,0x1,1,1,1,1,0,0,0,0,0,0,0,0, 0x1,0x1,0x1,0x1,0,0,0,0,0x1,0x1,0,0,0,0x1,0x1,0},
+// At 2 Processor System
+// {0,1,1,0,1,1,0,1,1,0,0,0,0,1,1,1, 0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1, // snes kai
+{0,1,1,0,1,1,0,1,1,0,0,0,0,1,1,1, 0,0,0,0,2,2,2,2,2,2,0,0,0,2,2,2,
+ 0,0,0x0,0x3,1,1,1,1,0,0,0,0,0,0,0,0, 0x3,0x3,0x3,0x3,0,0,0,0,0x3,0x3,0,0,0,0x3,0x3,0},
+// At 3 Processor System
+{0,1,1,0,1,1,0,1,1,0,0,0,0,1,1,1, 0,0,0,0,2,2,4,4,2,2,0,0,0,2,4,4,
+ 0,0,0x0,0x7,1,1,1,1,0,0,0,0,0,0,0,0, 0x7,0x7,0x7,0x7,0,0,0,0,0x7,0x7,0,0,0,0x7,0x7,0},
+// At 4 Processor System
+{0,1,1,0,1,1,0,1,1,0,0,0,0,1,1,1, 0,0,0,0,2,2,4,8,2,2,0,0,0,2,4,8,
+ 0,0,0x0,0xF,1,1,1,1,0,0,0,0,0,0,0,0, 0xF,0xF,0xF,0xF,0,0,0,0,0xf,0xf,0,0,0,0xF,0xF,0}
+};
+
+
+extern ULONG HalpLogicalCPU2PhysicalCPU[R98B_MAX_CPU];
+
+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.
+
+--*/
+
+{
+ ULONG ipr;
+ PULONG Vp;
+ ULONG NumCpu;
+ KIRQL OldIrql;
+ ULONG Value[2];
+ ULONG IntNo;
+
+ ULONG MagBuffer;
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ //
+ // In This Time I know Number Of CPU.
+ //
+ NumCpu = **((PULONG *)(&KeNumberProcessors));
+
+ //
+ // Number to Array Index.
+ //
+ NumCpu--;
+
+
+ for(ipr=0;ipr<64; ipr++){
+ if((HalpIntConnectPattern[NumCpu][ipr] & (1 <<PCR->Number))== 0 ){
+ //
+ // This Interrupt Connect Target CPU Not for me. So Set
+ // ~~~
+ Vp = (PULONG)&(HalpIntEntry[HalpMachineCpu][PCR->Number][ HalpIntLevelofIpr[HalpMachineCpu][ipr] ].Enable);
+
+ if( ipr < 32){
+ Vp[0] &= ~(0x1 << ipr);
+ Vp[1] &= 0xffffffff;
+ }else{
+ Vp[0] &= 0xffffffff;
+ Vp[1] &= ~(0x1 << (ipr-32));
+ }
+
+ }
+ }
+ //
+ // Enable Interrupt at Columnbs
+ // At This Interrupt Mask is perfact.
+ //
+ Value[0] = (ULONG)0xFFFFFFFF;
+ Value[1] = (ULONG)0xFFFFFFFF;
+ //
+ // ReBuild Mask
+ //
+ for(IntNo=0 ; IntNo< 6 ;IntNo++){
+ Vp = (PULONG)&(HalpIntEntry[HalpMachineCpu][PCR->Number][IntNo].Enable);
+ Value[0] &= ~Vp[0];
+ Value[1] &= ~Vp[1];
+
+ }
+ Vp = (PULONG)&(COLUMNBS_LCNTL)->MKR;
+ WRITE_REGISTER_ULONG( Vp++,Value[0]);
+ WRITE_REGISTER_ULONG( Vp, Value[1]);
+
+ // 2CPU
+ // Reset Interrupt of do Mask.
+ //
+ Vp = (PULONG)&(COLUMNBS_LCNTL)->IPRR;
+ WRITE_REGISTER_ULONG( Vp++,Value[0]);
+ WRITE_REGISTER_ULONG( Vp, Value[1]);
+
+ //
+ // ECC ERROR CHECK START
+ //
+#if 1 // ECC 1bit error/Multi bit error enable
+ if (PCR->Number == 0) {
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0) == 0 ){
+ MagBuffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRI )
+;
+ MagBuffer &= ECC_ERROR_ENABLE;
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRI, MagBuffer )
+;
+ }
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1) == 0 ){
+ MagBuffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRI )
+;
+ MagBuffer &= ECC_ERROR_ENABLE;
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRI, MagBuffer )
+;
+ }
+ }
+#endif
+
+ KeLowerIrql(OldIrql);
+
+#if DBG
+ DbgPrint("All Pro 0 CPU= %x :MKR = Low = 0x%x High = 0x%x\n",PCR->Number,Value[0],Value[1]);
+#endif
+
+
+
+ //
+ // Restart all timer interrupt. because, generate interrupt for same time
+ // All CPU
+
+ if (PCR->Number == 0) {
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->TCIR,
+ TCIR_ALL_CLOCK_RESTART| 0x000f0000);
+ }
+
+
+#if 0
+ //
+ // F/W Setup. So Never Fix.
+ //
+ if (PCR->Number == 0) {
+ IntNo = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(0)->PERRI);
+ DbgPrint(" PONCE_PERRI 0= 0x%x\n",IntNo);
+ IntNo = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(0)->PERRM);
+ DbgPrint(" PONCE_PERRM 0= 0x%x\n",IntNo);
+#if 0
+ //
+ // Ponce #0 PCI Error Eif Enable.
+ // Future implement.
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(0)->PERRM,PONCE_PXERR_PMDER);
+ //
+ // PCI Error Eif inhibit off.
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(0)->PERRI,PONCE_PXERR_PMDER);
+#else //test kbnes
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(0)->PERRM,(PONCE_PXERR_PMDER|PONCE_PXERR_PPERM));
+ //
+ // PCI Error Eif inhibit off.
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(0)->PERRI, PONCE_PXERR_PPERM));
+
+
+#endif
+ //
+ // Ponce #1 PCI Error Eif Enable.
+ // Future implement.
+ //
+#if 0
+
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(1)->PERRM,(PONCE_PXERR_PMDER|PONCE_PXERR_PPERM));
+ //
+ // PCI Error Eif inhibit off.
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(1)->PERRI, (PONCE_PXERR_PMDER|PONCE_PXERR_PPERM));
+#else //SNES tst
+ IntNo = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(1)->PERRI);
+ DbgPrint(" PONCE_PERRI 1= 0x%x\n",IntNo);
+ IntNo = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(1)->PERRM);
+ DbgPrint(" PONCE_PERRM 1= 0x%x\n",IntNo);
+
+
+
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(1)->PERRM,(PONCE_PXERR_PMDER|PONCE_PXERR_PPERM));
+ //
+ // PCI Error Eif inhibit off.
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(1)->PERRI, PONCE_PXERR_PPERM));
+
+
+#endif
+ }
+#endif
+
+ //
+ // On phase 0 EIF_VECTOR: direct connect by hal. so early interrupt imprement!!
+ // After This time. Eif Vector can share with ather device( MRC Driver)
+ //
+
+ KeInitializeInterrupt(
+ &HalpEifInterrupt[PCR->Number],
+ HalpHandleEif,
+ NULL,
+ NULL,
+ EIF_VECTOR,
+ (KIRQL)(INT0_LEVEL + HalpIntLevelofIpr[HalpMachineCpu][EIF_VECTOR - DEVICE_VECTORS]),
+ (KIRQL)(INT0_LEVEL + HalpIntLevelofIpr[HalpMachineCpu][EIF_VECTOR - DEVICE_VECTORS]),
+ LevelSensitive,
+ TRUE,
+ PCR->Number,
+ FALSE
+ );
+
+ KeConnectInterrupt( &HalpEifInterrupt[PCR->Number]);
+
+ PCR->InterruptRoutine[UNDEFINE_TLB_VECTOR] = (PKINTERRUPT_ROUTINE)HalpIoTlbLimitOver;
+
+ // F/W Setup. So Never Fix.
+ //
+ //
+ // Columnbs Error Eif and NMI Enable.
+ // Future implement.
+ //
+ // WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRMK,0x0);
+ //
+ // inhibit off.
+ //
+ // WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRI,0x0);
+
+ //
+ // If the number of processors in the host configuration is one,
+ // all Interrupt connect processor 0.
+ //
+
+#if DBG
+ DbgPrint("SecondLevelIcacheFillSize = 0x%x\n",PCR->SecondLevelIcacheFillSize);
+#endif
+
+ return HalpConnectIoInterrupt(NumCpu);
+
+}
+
+//
+//
+// Which MPU X IPR Bit X Connect
+// N.B
+// All CPU Execute!!
+//
+
+BOOLEAN
+HalpConnectIoInterrupt(
+ IN ULONG NumCpu
+ )
+{
+ PULONG IntTg;
+ PUCHAR Cnpttn;
+ UCHAR Number;
+ ULONG OldIntGValue;
+ ULONG ipr;
+
+
+ ULONG PhysicalNumber;
+
+ Cnpttn = &HalpIntConnectPattern[NumCpu][0];
+ Number = PCR->Number;
+
+ //
+ // If Interrupt for me!! then do so myself.
+ // Ipr 44 of max device interrupt. upper 44 is ipi or clock or profile
+ // or eif. etc...
+ //
+ KiAcquireSpinLock(&HalpIprInterruptLock);
+ for(ipr=0;ipr< 43;ipr++){
+ //
+ // BroadCast Type Implement OK!!.
+ // N.B
+ // But INT Dispatcher not Supported.
+ //
+ if(Cnpttn[ipr] & (0x1 << Number)){
+ HalpResetValue[ipr].Cpu = (UCHAR)Number;
+ IntTg = (PULONG) &PONCE_CNTL(HalpResetValue[ipr].Ponce)->INTTG[10 - HalpResetValue[ipr].IntGResetBit];
+
+#if 0
+ //
+ // Broadcast But Imprement Not Complete.
+ //
+ //
+ OldIntGValue = READ_REGISTER_ULONG( IntTg );
+ OldIntGValue &= 0xf0;
+#else
+ //
+ // Device Interrupt Connect to 1 CPU Only.
+ // Not Broadcast
+ //
+ OldIntGValue = 0x0;
+#endif
+
+ PhysicalNumber=HalpLogicalCPU2PhysicalCPU[Number];
+ WRITE_REGISTER_ULONG(
+ IntTg,
+ (OldIntGValue | (0x10 << PhysicalNumber))
+ );
+ }
+ }
+ KiReleaseSpinLock(&HalpIprInterruptLock);
+ //
+ // if eisa interrupt connect to me!
+ // Initialize EISA bus interrupts.
+ //
+ if(HalpResetValue[EISA_DISPATCH_VECTOR - DEVICE_VECTORS].Cpu == Number){
+ HalpCreateEisaStructures();
+ }
+
+ return TRUE;
+
+}
+//
+// Default All Interrupt Disable.
+//
+ULONG HalpInterruptPonceMask[PONCE_MAX] = { 0x000007ff,0x000007ff,0x000007ff};
+
+//
+//
+// This function Enable or Disable Interrupt connect to Ponce.
+//
+BOOLEAN
+HalpInterruptFromPonce(
+ IN ULONG Vector,
+ IN ULONG Enable
+ )
+{
+ ULONG Ponce;
+ ULONG IprBitNum;
+
+ IprBitNum = Vector - DEVICE_VECTORS; //SNES
+ //
+ // Check interrupt was connected to ponce!!.
+ //
+ if( HalpResetValue[IprBitNum].IntGResetBit > INTSA0)
+ return FALSE;
+
+ Ponce = HalpResetValue[IprBitNum].Ponce;
+
+ KiAcquireSpinLock(&HalpSystemInterruptLock);
+
+ // Bit X
+ // 1: Enable Interrupt
+ // 0: Disable Interrupt
+ if(Enable){
+ HalpInterruptPonceMask[Ponce] &= (ULONG) ~(0x1 <<
+ HalpResetValue[IprBitNum].IntGResetBit);
+ }else{
+ HalpInterruptPonceMask[Ponce] |= (ULONG) (0x1 <<
+ HalpResetValue[IprBitNum].IntGResetBit);
+
+ }
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(Ponce)->INTM,HalpInterruptPonceMask[Ponce]);
+
+ KiReleaseSpinLock(&HalpSystemInterruptLock);
+
+}
diff --git a/private/ntos/nthals/halr98b/mips/cacherr.h b/private/ntos/nthals/halr98b/mips/cacherr.h
new file mode 100644
index 000000000..94e009714
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/cacherr.h
@@ -0,0 +1,225 @@
+//
+// Error Log Offset
+//
+
+#ifndef _CHELOG_H
+#define _CHELOG_H
+
+//
+// For R10000
+//
+
+#define R10_FATAL_ERR 0x00
+#define R10_NORMAL_ERR 0x80
+
+#define R10_ICHE 0x80
+#define R10_DCHE 0x81
+#define R10_SCHE_2BIT 0x82
+#define R10_SYSAD_PARITY 0x83
+#define R10_CHER_IN_CHER 0x84
+#define R10_SCHE_1BIT 0x86
+
+#define R10_St2 0x0a
+#define R10_St3 0x0b
+#define R10_ErrEPC 0x20
+#define R10_Status 0x28
+#define R10_Config 0x2c
+#define R10_PRid 0x30
+#define R10_CacheEr 0x34
+#define R10_BrDiag 0x38
+#define R10_PC_Ctrl 0x40
+#define R10_PC_Count 0x44
+#define R10_p_count 0x48
+#define R10_s_count 0x4c
+#define R10_CheAdd_1bit 0x50
+#define R10_CheAdd 0x54
+#define R10_TagHi 0x58
+#define R10_TagLo 0x5c
+#define R10_Cache_data0_Hi 0x60
+#define R10_Cache_data0_Lo 0x64
+#define R10_Cache_data1_Hi 0x68
+#define R10_Cache_data1_Lo 0x6c
+#define R10_Cache_data2_Hi 0x70
+#define R10_Cache_data2_Lo 0x74
+#define R10_Cache_data3_Hi 0x78
+#define R10_Cache_data3_Lo 0x7c
+#define R10_Cache_data4_Hi 0x80
+#define R10_Cache_data4_Lo 0x84
+#define R10_Cache_data5_Hi 0x88
+#define R10_Cache_data5_Lo 0x8c
+#define R10_Cache_data6_Hi 0x90
+#define R10_Cache_data6_Lo 0x94
+#define R10_Cache_data7_Hi 0x98
+#define R10_Cache_data7_Lo 0x9c
+#define R10_ECC0 0xa0
+#define R10_ECC1 0xa4
+#define R10_ECC2 0xa8
+#define R10_ECC3 0xac
+#define R10_ECC4 0xb0
+#define R10_ECC5 0xb4
+#define R10_ECC6 0xb8
+#define R10_ECC7 0xbc
+
+#define R10_BrDiag_Hi 0x38
+#define R10_BrDiag_Lo 0x3c
+
+/*
+ * R10000 CacheErr register bit structure define
+ */
+#define R10CHE_KIND_MASK 0xc0000000 /* Kind of Cache error */
+#define R10CHE_KIND_I 0x00000000 /* I-Cache error */
+#define R10CHE_KIND_D 0x40000000 /* D-Cache error */
+#define R10CHE_KIND_S 0x80000000 /* S-Cache error */
+#define R10CHE_KIND_Y 0xc0000000 /* System I/F error */
+#define R10CHE_EW 0x20000000 /* Duplicated cache error */
+#define R10CHE_EE 0x10000000 /* Fatal error(D/Y) */
+#define R10CHE_D_MASK 0x0c000000 /* Data aray(I/D/S/Y) */
+#define R10CHE_D_WAY0 0x04000000 /* way0 */
+#define R10CHE_D_WAY1 0x08000000 /* way1 */
+#define R10CHE_TA_MASK 0x03000000 /* Tag Address aray(I/D/S) */
+#define R10CHE_TA_WAY0 0x01000000 /* way0 */
+#define R10CHE_TA_WAY1 0x02000000 /* way1 */
+#define R10CHE_TS_MASK 0x00c00000 /* Tag State aray(I/D) */
+#define R10CHE_TS_WAY0 0x00400000 /* way0 */
+#define R10CHE_TS_WAY1 0x00800000 /* way1 */
+#define R10CHE_TM_MASK 0x00300000 /* Tag Mod aray(D) */
+#define R10CHE_TM_WAY0 0x00100000 /* way0 */
+#define R10CHE_TM_WAY1 0x00200000 /* way1 */
+#define R10CHE_SA 0x02000000 /* SysAD address parity error */
+#define R10CHE_SC 0x01000000 /* SysCmd parity error */
+#define R10CHE_SR 0x00800000 /* SysResp parity error */
+#define R10CHE_PIDX_BLK 0x00003fC0 /* Primary block index */
+#define R10CHE_PIDX_DW 0x00003ff8 /* Primary double word index */
+#define R10CHE_SIDX_BLK 0x007fffC0 /* Secondary block index */
+#define R10CHE_BLK_SHIFT 6 /* block index shift */
+#define R10CHE_DW_SHIFT 3 /* double word index shift */
+
+/*
+ * R10000 Cache Instruction Opecode define
+ */
+#define IndexInvalidate_I 0x00
+#define IndexLoadTag_I 0x04
+#define IndexStoreTag_I 0x08
+#define HitInvalidate_I 0x10
+#define CacheBarrier_I 0x14
+#define IndexLoadData_I 0x18
+#define IndexStoreData_I 0x1c
+
+#define IndexWriteBack_D 0x01
+#define IndexLoadTag_D 0x05
+#define IndexStoreTag_D 0x09
+#define HitInvalidate_D 0x11
+#define HitWriteBack_D 0x15
+#define IndexLoadData_D 0x19
+#define IndexStoreData_D 0x1d
+
+#define IndexWriteBack_S 0x03
+#define IndexLoadTag_S 0x07
+#define IndexStoreTag_S 0x0b
+#define HitInvalidate_S 0x13
+#define HitWriteBack_S 0x17
+#define IndexLoadData_S 0x1b
+#define IndexStoreData_S 0x1f
+
+
+
+#define branchdiag $22
+
+#if 0
+/* dmfc0 rt, rd */
+#define DMFC0( rt, rd ) \
+ .word 0x40200000 | (rt<<16) | (rd<<11)
+/* dmfc0 rt, rd */
+#define DMTC0( rt, rd ) \
+ .word 0x40a00000 | (rt<<16) | (rd<<11)
+/* mfpc rt, reg */
+#define MFPC( rt, reg ) \
+ .word 0x4000c801 | (rt<<16) | (reg<<1)
+/* mtpc rt, reg */
+#define MTPC( rt, reg ) \
+ .word 0x4080c801 | (rt<<16) | (reg<<1)
+/* mfps rt, reg */
+#define MFPS( rt, reg ) \
+ .word 0x4000c800 | (rt<<16) | (reg<<1)
+/* mtps rt, reg */
+#define MTPS( rt, reg ) \
+ .word 0x4080c800 | (rt<<16) | (reg<<1)
+#endif
+
+
+//
+// For R4400
+//
+
+#define EPC_cpu 0x0
+#define Psr_cpu 0x8
+#define CFG_cpu 0xc
+#define PRID_cpu 0x10
+#define CHERR_cpu 0x14
+#define CheAdd_p 0x18
+#define CheAdd_s 0x1c
+#define TagLo_p 0x20
+#define ECC_p 0x24
+#define TagLo_s 0x28
+#define ECC_s 0x2c
+#define data_s 0x30
+#define Good_data_s 0x38
+#define Good_TagLo_s 0x40
+#define Good_ECC_s 0x44
+#define tag_synd_s 0x48
+#define data_synd_s 0x4c
+#define xkphs_share 0x50
+//Error Code
+
+#define ICHE_EX 0x00
+#define ICHE_TAG 0x01
+#define ICHE_DAT 0x02
+#define ICHE_EB 0x03
+#define ICHE_UNKNOWN 0x0f
+
+#define DCHE_TAG_EX 0x10
+#define DCHE_TAG_CLEAN 0x11
+#define DCHE_TAG_DIRTY 0x12
+#define DCHE_TAG_UNKNOW 0x13
+#define DCHE_DAT_EX 0x14
+#define DCHE_DAT_DIRTY 0x16
+#define DCHE_UNKNOWN 0x1f
+
+#define SCHE_TAG_1BIT 0x20
+#define SCHE_TAG_2BIT 0x21
+#define SCHE_TAG_UNKNOW 0x23
+#define SCHE_DAT_EX 0x24
+#define SCHE_DAT_INV 0x25
+#define SCHE_DAT_1BIT 0x26
+#define SCHE_DAT_2BIT_C 0x27
+#define SCHE_DAT_2BIT_D 0x28
+#define SCHE_DAT_UNKNOW 0x29
+#define SCHE_UNKNOWN 0x2f
+
+#define SYSAD_PARITY 0x30
+// REG MASK
+
+#define CHERR_ER 0x80000000
+#define CHERR_EC 0x40000000
+#define CHERR_ED 0x20000000
+#define CHERR_ET 0x10000000
+#define CHERR_ES 0x08000000
+#define CHERR_EE 0x04000000
+#define CHERR_EB 0x02000000
+#define CHERR_EI 0x01000000
+#define CHERR_EW 0x00800000
+#define CHERR_SIDX 0x0003fff8
+#define CHERR_SIDX2 0x0003fff8
+#define CHERR_PIDX 0x00000007
+
+#define R4CT_PSTAT_MASK 0x000000c0
+#define R4CT_PSTAT_DRE 0x000000c0
+#define R4CT_PTAG_MASK 0xffffff00
+#define R4CT_SSTAT_MASK 0x00001c00
+#define R4CT_SSTAT_DRE 0x00001400
+#define R4CT_SSTAT_INV 0x00000000
+#define R4CT_STAG_MASK 0xffffe000
+
+#define CHERR_PSHF 12
+
+#endif /* _CHELOG_H */
diff --git a/private/ntos/nthals/halr98b/mips/cacherr.s b/private/ntos/nthals/halr98b/mips/cacherr.s
new file mode 100644
index 000000000..bcb23554f
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/cacherr.s
@@ -0,0 +1,1435 @@
+// "@(#) NEC cacherr.s 1.2 94/10/17 11:02:44"
+// TITLE("Cache Error Handling")
+//++
+//
+// Copyright (c) 1993-1994 Microsoft Corporation
+//
+// Module Name:
+//
+// cacherr.s
+//
+// Abstract:
+//
+// This module implements cache error handling. It is entered in KSEG1
+// directly from the cache error vector wiht ERL set in the processor
+// state.
+//
+// N.B. All the code in this routine MUST run in KSEG1 and reference
+// data only in KSEG1 until which time as any cache errors have
+// been corrected.
+//
+// N.B. This routine is NOT COMPLETE. All cache errors result in a
+// soft reset.
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+//--
+
+#include "halmips.h"
+#include "cacherr.h"
+
+//
+// Define local save area for register state.
+//
+
+ .data
+SavedAt:.space 4 // saved integer register at - a3
+SavedV0:.space 4 //
+SavedV1:.space 4 //
+SavedA0:.space 4 //
+SavedA1:.space 4 //
+SavedA2:.space 4 //
+SavedA3:.space 4 //
+
+ SBTTL("Cache Error Handling")
+//++
+//
+// VOID
+// HalpCacheErrorRoutine (
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function is entered from the cache error vector executing
+// in KSEG1. If the error is a single bit ECC error in the second
+// level data cache or the error is in the primary instruction cache,
+// then the error is corrected and execution is continued. Otherwise,
+// a fatal system error has occured and control is transfered to the
+// soft reset vector.
+//
+// N.B. No state has been saved when this routine is entered.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpCacheErrorRoutine)
+
+//
+// Save volatile registers needed to fix cache error.
+//
+
+ .set noreorder
+ .set noat
+//K001
+// la k0,SavedAt // get address of register save area
+// li k1,KSEG1_BASE // convert address of KSEG1 address
+// or k0,k0,k1 //
+// sw AT,0(k0) // save registers AT - a3
+// sw v0,4(k0) //
+// sw v1,8(k0) //
+// sw a0,12(k0) //
+// sw a1,16(k0) //
+// sw a2,20(k0) //
+ li k1,0xb9800310 // Get CPU#
+ lw k0,0x0(k1)
+ li k1,0x0f000000
+ and k0,k0,k1
+ srl k0,k0,24
+ li k1,0x4
+ sub k0,k0,k1
+ mtc0 k0,lladdr
+ nop
+ nop
+ nop
+ nop
+ li k1,0xd
+ sll k0,k0,k1
+ la k1,HalpCacheErrorStack
+ add k0,k0,k1
+ add k0,k0,0x2000
+ li k1,KSEG1_BASE
+ or k0,k0,k1
+ subu k0,k0,TrapFrameLength
+#if !defined(NT_40)
+ sw sp,TrIntSp(k0) // save integer register sp
+ move sp,k0 // set new stack pointer
+ cfc1 k1,fsr // get floating status register
+ sw gp,TrIntGp(sp) // save integer register gp
+ sw s8,TrIntS8(sp) // save integer register s8
+ sw k1,TrFsr(sp) // save current FSR
+ mfc0 k0,psr
+ nop
+ nop
+ nop
+ sw k0,TrPsr(sp) // save processor state
+ sw ra,TrIntRa(sp) // save integer register ra
+ move s8,sp
+ sw AT,TrIntAt(s8) // save assembler temporary register
+ sw v0,TrIntV0(s8) // save integer register v0
+ sw v1,TrIntV1(s8) // save integer register v1
+ sw a0,TrIntA0(s8) // save integer registers a0 - a3
+ sw a1,TrIntA1(s8) //
+ sw a2,TrIntA2(s8) //
+ sw a3,TrIntA3(s8) //
+ sw t0,TrIntT0(s8) // save integer registers t0 - t2
+ sw t1,TrIntT1(s8) //
+ sw t2,TrIntT2(s8) //
+ sw t3,TrIntT3(s8) // save integer register t3 - t9
+ sw t4,TrIntT4(s8) //
+ sw t5,TrIntT5(s8) //
+ sw t6,TrIntT6(s8) //
+ sw t7,TrIntT7(s8) //
+ sw t8,TrIntT8(s8) //
+ sw t9,TrIntT9(s8) //
+ mflo t3 // get multiplier/quotient lo and hi
+ mfhi t4 //
+ sw t3,TrIntLo(s8) // save multiplier/quotient lo and hi
+ sw t4,TrIntHi(s8) //
+ mfc0 a2,errorepc
+ nop
+ nop
+ nop
+ sw a2,TrFir(s8) // save exception PC
+#else
+ sd sp,TrXIntSp(k0) // save integer register sp
+ move sp,k0 // set new stack pointer
+ cfc1 k1,fsr // get floating status register
+ sd gp,TrXIntGp(sp) // save integer register gp
+ sd s8,TrXIntS8(sp) // save integer register s8
+ sw k1,TrFsr(sp) // save current FSR
+ mfc0 k0,psr
+ nop
+ nop
+ nop
+ sw k0,TrPsr(sp) // save processor state
+ sd ra,TrXIntRa(sp) // save integer register ra
+ move s8,sp
+ sd AT,TrXIntAt(s8) // save assembler temporary register
+ sd v0,TrXIntV0(s8) // save integer register v0
+ sd v1,TrXIntV1(s8) // save integer register v1
+ sd a0,TrXIntA0(s8) // save integer registers a0 - a3
+ sd a1,TrXIntA1(s8) //
+ sd a2,TrXIntA2(s8) //
+ sd a3,TrXIntA3(s8) //
+ sd t0,TrXIntT0(s8) // save integer registers t0 - t2
+ sd t1,TrXIntT1(s8) //
+ sd t2,TrXIntT2(s8) //
+ sd t3,TrXIntT3(s8) // save integer register t3 - t7
+ sd t4,TrXIntT4(s8) //
+ sd t5,TrXIntT5(s8) //
+ sd t6,TrXIntT6(s8) //
+ sd t7,TrXIntT7(s8) //
+ sd s0,TrXIntS0(s8) // save integer registers s0 - s7
+ sd s1,TrXIntS1(s8) //
+ sd s2,TrXIntS2(s8) //
+ sd s3,TrXIntS3(s8) //
+ sd s4,TrXIntS4(s8) //
+ sd s5,TrXIntS5(s8) //
+ sd s6,TrXIntS6(s8) //
+ sd s7,TrXIntS7(s8) //
+ sd t8,TrXIntT8(s8) // save integer registers t8 - t9
+ sd t9,TrXIntT9(s8) //
+ mflo t3 // get multiplier/quotient lo and hi
+ mfhi t4 //
+ sd t3,TrXIntLo(s8) // save multiplier/quotient lo and hi
+ sd t4,TrXIntHi(s8) //
+ mfc0 a2,errorepc
+ nop
+ nop
+ nop
+ sw a2,TrFir(s8) // save exception PC
+
+#endif
+ move a3,k0
+
+//
+// Get the current processor state and cache error register, and check
+// if the error can be corrected.
+//
+
+ mfc0 a0,lladdr
+ nop
+ nop
+ nop
+ li t1,0x1 // Log Format For FW
+ sll t3,t1,a0
+ li t1,0xb9800388 // NVRAM enable
+ li t0,0x00040000
+ sw t0,0x0(t1)
+ li t0,0xbf09fd64 // NVRAM log For FW
+ lw t1,0x0(t0)
+ or t3,t1,t3
+ sb t3,0x0(t0)
+#if 0
+ li t1,0xb9800388 // NVRAM disable
+ li t0,0x04040000
+ sw t0,0x0(t1)
+#endif
+ mfc0 a1,cacheerr // get cache error state
+ nop
+ nop
+ nop
+ la t1,HalpCacheErrorHwLog
+ li t2,KSEG1_BASE
+ or t1,t1,t2
+//
+// Check CPU
+//
+
+// li a1,0x00000000
+
+ mfc0 t2,prid
+ nop
+ nop
+ nop
+ nop
+ and t2,t2,0xff00 // isolate processor id
+ xor t2,t2,0x0900 // check if r10000 processor
+ beq zero,t2,t5clog // if eq, r10000 processor
+
+
+
+//
+// R4400 log
+//
+
+ addi t2,t1,0x20
+ .set at
+ .set reorder
+
+//
+// ****** temp ******
+//
+// The following code is temporary and will be removed when full cache
+// error support is included.
+//
+// ****** temp ******
+//
+// K001 For cacheErrorLog
+
+// jal HalpCacheErrorLog
+// nop
+//
+// b SoftReset // ****** all error soft rest
+/********************************
+ * cache error routine
+ *
+ * v0 = return code (return value)
+ *
+ * a0 = log field address (argument)
+ * a1 = error code address (argument)
+ * a2 = TagLo reg
+ * a3 = ECC reg
+ * t0 = cache virtual address
+ * t1 = Cache error reg
+ * t2 = d-cache virtual address for s-cache
+ * t3 = xkphs address
+ * t4 - t7 temprary data
+ * t8 = a2(TagLo) save
+ * t9 = return address
+ ********************************/
+//LEAF(che_log)
+
+ .set noreorder
+// DMFC0 (T8, D_ERROREPC)
+ move v1,a0 // CPU #
+
+ move a0,t2 // Data addr
+ move t2,a1
+ move a1,t1 // Header addr
+ move t1,t2 // CacheError REg
+ move t8,a2 // Error Epc
+// mfc0 t7, C0_SR
+ move t7,a3 // PSR
+ mfc0 t6, config
+ mfc0 t5, prid
+// Log
+ sw t8,EPC_cpu(a0)
+ sw t7,Psr_cpu(a0)
+ sw t6,CFG_cpu(a0)
+ sw t5,PRID_cpu(a0)
+ sw t1,CHERR_cpu(a0)
+// mfc0 t1, C0_CACHEERR
+// or t4, t7, (SR_DE | SR_KX | SR_ERL)
+ or t4,t7,(0x1<<PSR_DE)
+ mtc0 t4, psr
+ nop
+ nop
+ nop
+ .set reorder
+
+ and t4, t1, CHERR_EE # sysad parity error?
+ bnez t4, sysad_log
+
+ and t4, t1, CHERR_EC # primary cache error?
+ bnez t4, sche_log
+
+ and t4, t1, CHERR_ER # p-inst cache error?
+ bnez t4, dche_log
+
+/*
+ * primary instruction cache parity error
+ */
+ and t0, t1, CHERR_PIDX # K1(p) address
+// sll t0, t0,CHERR_PSHFT
+// sll t0, t0,12
+ and t4, t1, CHERR_SIDX2
+ or t0, t4
+ or t0, KSEG0_BASE
+
+ .set noreorder
+ cache 4, 0(t0) # I-cache index load tag
+ nop
+ nop
+ nop
+ mfc0 a2, taglo
+ mfc0 a3, ecc
+ .set reorder
+
+ sw t0, CheAdd_p(a0) # save cache address
+ sw a2, TagLo_p(a0) # save TagLo
+ sw a3, ECC_p(a0) # save ECC
+
+ and t4, t1, CHERR_ES # external reference?
+ bnez t4, iche_log_ex # then degrade error
+
+ and t4, t1, CHERR_EB # also occured data error?
+ bnez t4, iche_log_eb # then fatal error
+
+ and t4, t1, CHERR_ET # tag error?
+ bnez t4, iche_log_tag # then fatal error
+
+ and t4, t1, CHERR_ED # data error?
+ bnez t4, iche_log_dat # then degrade error
+
+// li t4, FATAL_ERR # else fatal error
+// sw t4, (a1)
+ li v0, ICHE_UNKNOWN
+ j iche_log_end
+
+iche_log_dat:
+// # li t4, RECOVER_ERR
+// # sw t4, (a1)
+ li v0, ICHE_DAT
+ j iche_log_end
+
+iche_log_tag:
+// # li t4, FATAL_ERR
+// # sw t4, (a1)
+ li v0, ICHE_TAG
+ j iche_log_end
+
+iche_log_eb:
+// li t4, FATAL_ERR
+ sw t4, (a1)
+ li v0, ICHE_EB
+ j iche_log_end
+
+iche_log_ex:
+// # li t4, RECOVER_ERR
+// # sw t4, (a1)
+ li v0, ICHE_EX
+
+iche_log_end:
+ .set noreorder
+ mtc0 zero,taglo
+ nop
+ cache 8, 0(t0) //# I-cache index store tag(invalid)
+ cache 20,0(t0) //# I-cache fill
+ cache 8, 0(t0) //# I-cache index store tag(invalid)
+ .set reorder
+ j che_log_end
+
+/*
+ * primary data cache parity error
+ */
+dche_log:
+ and t0, t1, CHERR_SIDX2 //# K1(p) address
+ or t0, KSEG0_BASE
+
+dche_log_loop:
+ .set noreorder
+ cache 5, 0(t0) //# D-cache index load tag
+ nop
+ nop
+ nop
+ mfc0 a2, taglo
+ mfc0 a3, ecc
+ .set reorder
+
+ sw t0, CheAdd_p(a0) //# save cache address
+ sw a2, TagLo_p(a0) //# save TagLo
+ sw a3, ECC_p(a0) //# save ECC
+
+ and t4, t1, CHERR_ET //# tag error?
+ beqz t4, dche_log_dat //# else data error
+//#
+//# Tag field error
+//#
+ jal tag_parity_chk //# check tag parity
+ bnez v0, dche_tag_parity
+
+ add t0, 0x1000 //# check next PIDX
+ bltu t0, 0x80004000, dche_log_loop
+ //# less than 16K then loop
+// li t4, FATAL_ERR # else fatal error
+// sw t4, (a1)
+ li v0, DCHE_TAG_UNKNOW
+ j che_log_end
+
+dche_tag_parity:
+ and t4, t1, CHERR_ES //# external reference?
+ bnez t4, dche_tag_ex //# then fatal error
+
+ and t4, a2, R4CT_PSTAT_MASK //# dirty?
+ beq t4, R4CT_PSTAT_DRE, dche_tag_dirty
+ beqz t4, dche_tag_clean
+
+ and t4, a2, R4CT_PTAG_MASK //# k1(s) address
+ sll t4, 4
+ and t5, t1, CHERR_SIDX2
+ or t4, t5
+ and t4, CHERR_SIDX
+ or t4, KSEG0_BASE
+
+ .set noreorder
+ cache 7, 0(t4) //# S-cache index load tag
+ nop
+ nop
+ nop
+ mfc0 t5, taglo
+ mfc0 t6, ecc
+ .set reorder
+
+ sw t4, CheAdd_s(a0) //# save cache address
+ sw t5, TagLo_s(a0) //# save TagLo
+ sw t6, ECC_s(a0) //# save ECC
+
+ and t7, t5, R4CT_SSTAT_MASK //# dirty?
+ beq t7, R4CT_SSTAT_DRE, dche_tag_dirty
+
+dche_tag_clean:
+// li t4, RECOVER_ERR
+// sw t4, (a1)
+ li v0, DCHE_TAG_CLEAN
+ j dche_log_end
+
+dche_tag_dirty:
+// li t4, FATAL_ERR
+// sw t4, (a1)
+ li v0, DCHE_TAG_DIRTY
+ j dche_log_end
+
+dche_tag_ex:
+// li t4, FATAL_ERR
+// sw t4, (a1)
+ li v0, DCHE_TAG_EX
+ j dche_log_end
+
+ //#
+ //# Data field error
+// #
+dche_log_dat:
+ and t4, t1, CHERR_ED //# DATA error?
+ bnez t4, dche_dat //# then data error
+
+// li t4, FATAL_ERR //# else fatal error
+// sw t4, (a1)
+ li v0, DCHE_UNKNOWN
+ j che_log_end
+
+dche_dat:
+ and t4, t1, CHERR_ES //# external reference?
+ beqz t4, dche_dat_chk //# else data error check
+
+// li t4, FATAL_ERR //# then fatal error
+// sw t4, (a1)
+ li v0, DCHE_DAT_EX
+ j che_log_end
+
+dche_dat_chk:
+/* For NT
+ and t4, a2, R4CT_PSTAT_MASK //# invalid?
+ beqz t4, dche_dat_next
+
+ move t8, a2 //# save TagLo
+
+ and t3, a2, R4CT_PTAG_MASK //# xkphs cached address
+ DSLL32 (T3, T3, 0)
+ DSRL (T3, T3, 28)
+ and t4, t1, CHERR_SIDX2
+ or t3, t4
+ li t4, XKPHYSEGMENT_HI_CCS
+ DSLL32 (T4, T4, 0)
+ or t3, t4
+
+ LD (A2, 0, T3) # load erronious data
+ SD (T3, xkphs_share, A0)
+ SD (A2, data_s, A0)
+
+ # jal dat_parity_chk # check data parity
+ move a2, t8 # resotore TagLo
+ # bnez v0, dche_dat_parity
+
+ .set noreorder
+ cache 1, 0(t0) # D-cache index writevack invalidate
+ lw zero, (t0) # D-cache dummy load
+ mtc0 zero, C0_TAGLO
+ nop
+ cache 9, 0(t0) # D-cache index store tag(invalid)
+ .set reorder
+
+dche_dat_next:
+ add t0, 0x1000 # check next PIDX
+ bltu t0, 0x80004000, dche_log_loop
+ # less than 16K then loop
+
+ li t4, FATAL_ERR # all D-cache error is fatal
+ sw t4, (a1)
+*/
+ li v0, DCHE_DAT_DIRTY
+ j che_log_end
+
+/* comment out 1993.11.12
+
+ li t4, FATAL_ERR # else fatal error
+ sw t4, (a1)
+ li v0, DCHE_DAT_UNKNOW
+ j che_log_end
+
+dche_dat_parity:
+ and t4, a2, R4CT_PSTAT_MASK # dirty?
+ beq t4, R4CT_PSTAT_DRE, dche_dat_dirty
+ bnez t4, dche_dat_dirty
+
+dche_dat_clean:
+ li t4, RECOVER_ERR
+ sw t4, (a1)
+ li v0, DCHE_DAT_CLEAN
+ j dche_log_end
+
+dche_dat_dirty:
+ li t4, FATAL_ERR
+ sw t4, (a1)
+ li v0, DCHE_DAT_DIRTY
+*/
+
+dche_log_end:
+ .set noreorder
+ mtc0 zero,taglo
+ nop
+ cache 9, 0(t0) # D-cache index store tag(invalid)
+ lw zero, (t0) # D-cache dummy load
+ cache 9, 0(t0) # D-cache index store tag(invalid)
+ .set reorder
+
+ j che_log_end
+
+/*
+ * secondary cache error
+ */
+sche_log:
+ and t2, t1, CHERR_PIDX # K1(p) address
+// sll t2, t2,CHERR_PSHFT
+ sll t2, t2,12
+ and t4, t1, CHERR_SIDX2
+ or t2, t4
+ or t2, KSEG0_BASE
+ sw t2, CheAdd_p(a0) # save cache address
+
+ and t4, t1, CHERR_EI # store miss error?
+ beqz t4, sche_log_tag # else tag error
+
+ .set noreorder
+ mtc0 zero, taglo
+ nop
+ cache 9, 0(t2) # D-cache index store tag(invalid)
+ .set reorder
+
+sche_log_tag:
+ and t0, t1, CHERR_SIDX # K1(s) address
+ or t0, KSEG0_BASE
+
+ .set noreorder
+ cache 7, 0(t0) # S-cache index load tag
+ nop
+ nop
+ nop
+ mfc0 a2, taglo
+ mfc0 a3, ecc
+ .set reorder
+
+ sw t0, CheAdd_s(a0) # save cache address
+ sw a2, TagLo_s(a0) # save TagLo
+ sw a3, ECC_s(a0) # save ECC
+
+ and t4, t1, CHERR_ET # tag error?
+ beqz t4, sche_log_dat # else data error
+
+// #
+// # Tag field error
+// #
+ move k0,v1
+ jal tag_ecc_chk //# check tag ecc
+ sw v1, tag_synd_s(a0)
+ move v1,k0
+ sw a2, Good_TagLo_s(a0)
+ beq v0, SCHE_TAG_1BIT, sche_tag_1bit
+ beq v0, SCHE_TAG_UNKNOW, sche_tag_noerr
+
+sche_tag_2bit:
+ and t2, ~63 # 64byte boundary
+ .set noreorder
+ mtc0 zero, taglo
+ nop
+ cache 9, 0(t2) # D-cache index store tag(invalid)
+ cache 9, 16(t2)
+ cache 9, 32(t2)
+ cache 9, 48(t2)
+ cache 11, 0(t0) # S-cache index store tag(invalid)
+ .set reorder
+
+// li t4, FATAL_ERR
+ j che_log_end
+
+sche_tag_1bit:
+ .set noreorder
+ mtc0 a2, taglo
+ nop
+ cache 11, 0(t0) # S-cache index store tag(modify)
+ .set reorder
+
+sche_tag_noerr:
+ and t4, t1, CHERR_ED # data error?
+ beqz t4, che_log_end # else end
+
+sche_log_dat:
+ and t4, t1, CHERR_ED # data error?
+ bnez t4, sche_dat_0
+
+// li t4, FATAL_ERR # else fatal error
+// sw t4, (a1)
+ li v0, SCHE_UNKNOWN
+ j che_log_end
+
+sche_dat_0:
+ and t4, t1, CHERR_ES # external reference?
+// *tmp*
+// beqz t4, sche_dat_1
+
+// li t4, FATAL_ERR # then fatal error
+// sw t4, (a1)
+// li v0, SCHE_DAT_EX
+ li v0, SCHE_DAT_UNKNOW
+ j sche_log_end
+/*
+sche_dat_1:
+ and t4, a2, R4CT_SSTAT_MASK # dirty?
+ bne t4, R4CT_SSTAT_INV, sche_dat_chk
+
+ li t4, FATAL_ERR # then fatal error
+ sw t4, (a1)
+ li v0, SCHE_DAT_INV
+ j sche_log_end
+
+sche_dat_chk:
+ move t8, a2 # save TagLo
+
+ and t3, a2, R4CT_STAG_MASK # xkphs cached address
+ DSLL32 (T3, T3, 0)
+ DSRL (T3, T3, 28)
+ and t4, t1, CHERR_SIDX
+ or t3, t4
+ li t4, XKPHYSEGMENT_HI_CCS
+ DSLL32 (T4, T4, 0)
+ or t3, t4
+
+ LD (A2, 0, T3) # load erronious data
+ SD (T3, xkphs_share, A0)
+ SD (A2, data_s, A0)
+ jal dat_ecc_chk # check data ecc
+
+ sw v1, data_synd_s(a0)
+ SD (A2, Good_data_s, A0)
+ sw a3, Good_ECC_s(a0)
+ move v1, a2 # save good data
+ move a2, t8 # resotore TagLo
+ beq v0, SCHE_DAT_2BIT_C, sche_dat_2bit
+ beq v0, SCHE_DAT_UNKNOW, sche_dat_unknown
+
+ SD (V1, 0, T3) # modified data
+ j sche_log_end
+
+sche_dat_2bit:
+ and t4, a2, R4CT_SSTAT_MASK # dirty?
+ beq t4, R4CT_SSTAT_DRE, sche_dat_dirty
+
+sche_dat_clean:
+ lw zero, (t0) # dummy read
+
+ li t4, RECOVER_ERR
+ sw t4, (a1)
+ j sche_log_end
+
+sche_dat_dirty:
+ li v0, SCHE_DAT_2BIT_D
+ SD (V1, 0, T3) # rewrite error data
+
+sche_dat_unknown:
+ li t4, FATAL_ERR
+ sw t4, (a1)
+*/
+sche_log_end:
+ and t2, ~63 # 64byte boundary
+
+ .set noreorder
+ cache 1, 0(t2) # D-cache index write back invalidate
+ cache 1, 16(t2)
+ cache 1, 32(t2)
+ cache 1, 48(t2)
+ cache 3, 0(t0) # S-cache index write back invalidate
+ .set reorder
+
+ j che_log_end
+
+/*
+ * System address data parity error
+ */
+sysad_log:
+// li t4, FATAL_ERR
+// sw t4, (a1)
+ li v0, SYSAD_PARITY
+
+che_log_end:
+//For Log Function areg
+ move t0,a0
+ move a0,v1
+/* lw a2,EPC_cpu(t0)
+ lw a1,CHERR_cpu(t0)
+*/
+ move a2,v0
+ j HalpCacheErrorLog
+//tmp lw t5, Status(a0) # load Status
+/*
+ .set noreorder
+ mfc0 t4, cacheerr
+ mtc0 t5, psr
+ nop
+ nop
+ .set reorder
+
+// tmp
+ and t4, CHERR_EW # cache error in chelog?
+ beqz t4, che_log_end2
+
+ li t4, FATAL_ERR
+ sw t4, (a1)
+ li v0, CHER_IN_CHER
+
+che_log_end2:
+ j t9 # return
+*/
+// END(che_log)
+
+//
+// R10000 log
+//
+
+t5clog:
+// Get Log data.
+ .set noreorder
+
+ move v1,a0
+ move a0,t1 # a0 = data address
+
+ move t8,a2 # t8 = ErrorEpc
+ move t7,a3 # t7 = Status
+ mfc0 t6,config # t6 = Config
+ mfc0 t5,prid # t5 = Prid
+ move t1,a1 # t1 = cache error state
+
+ or t4,t7,( 1 << PSR_ERL )
+ mtc0 t4,psr
+ dmfc0 t3,branchdiag
+// mfps t2,$0
+// mfpc t0,$0
+ move t2,zero
+ move t0,zero
+
+ .set reorder
+
+// Set log data.
+ sw t8,R10_ErrEPC(a0) # save ErrEPC
+ sw t7,R10_Status(a0) # save Status
+ sw t6,R10_Config(a0) # save Config
+ sw t5,R10_PRid(a0) # save Prid
+ sw t1,R10_CacheEr(a0) # save CacheErr
+ sw t3,R10_BrDiag_Hi(a0) # save BranchDiag
+ srl t4,t3,16
+ srl t4,t4,16
+ sw t4,R10_BrDiag_Lo(a0)
+ sw t2,R10_PC_Ctrl(a0) # save PC Control
+ sw t0,R10_PC_Count(a0) # save PC Count
+
+ li t0,KSEG0_BASE # t0 = cache address
+
+ li t4,R10CHE_KIND_MASK
+ and t4,t1,t4
+
+// I-cache error
+ li v0,R10_ICHE
+ li t5,R10CHE_KIND_I
+ beq t4,t5,t5_iche_log # I-cache parity error?
+
+// D-cache error
+ li v0,R10_DCHE
+ li t5,R10CHE_KIND_D
+ beq t4,t5,t5_dche_log # D-cache parity error?
+
+// S-cache error
+ li v0,R10_SCHE_2BIT
+ li t5,R10CHE_KIND_S
+ beq t4,t5,t5_sche_log # S-cache ECC error?
+
+// SysAd error
+ li v0,R10_SYSAD_PARITY
+// li t4,R10_FATAL_ERR
+// sw t4,(a1)
+ and t4,t1,(R10CHE_SA | R10CHE_SC | R10CHE_SR)
+ bne t4,zero,t5_log_end # Sys I/F fatal error
+
+
+t5_sche_log:
+// Make cache addr
+ and t4,t1,R10CHE_SIDX_BLK
+ or t0,t4
+ and t4,t1,(R10CHE_D_WAY1 | R10CHE_TA_WAY1)
+ sne t4,0
+ or t0,t4 # t0 = cache way address
+
+// TagHi & TagLo
+ .set noreorder
+ cache IndexLoadTag_S, 0(t0) # load tag
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ .set reorder
+
+ sw t0,R10_CheAdd(a0) # save cache address
+ sw t4,R10_TagHi(a0) # save TagHi
+ sw t5,R10_TagLo(a0) # save TagLo
+
+// Cache data & ECC
+ addu t3,t0,64 # t3 = cacne address increment
+ addu t7,a0,64 # t7 = data save address increment
+ addu t8,a0,32 # t8 = ECC save address increment
+
+load_Scache_loop:
+ subu t3,8 # new cache address
+ subu t7,8 # new data save address
+ subu t8,4 # new ECC save address
+
+ .set noreorder
+ cache IndexLoadData_S,0(t3) # load data
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ mfc0 t6,ecc
+ .set reorder
+
+ sw t4,R10_Cache_data0_Hi(t7) # save data high
+ sw t5,R10_Cache_data0_Lo(t7) # save data low
+ sw t6,R10_ECC0(t8) # save ECC
+
+ bne t3,t0,load_Scache_loop # 8 times
+
+ .set noreorder
+ cache IndexWriteBack_S,0(t0)
+ .set reorder
+
+// li t4,R10_FATAL_ERR
+// sw t4,(a1)
+
+ j t5_log_end
+
+
+// I-cache
+t5_iche_log:
+// Make cache addr
+ and t4, t1, R10CHE_PIDX_BLK
+ or t0, t4
+ and t4, t1, (R10CHE_D_WAY1 | R10CHE_TA_WAY1 | R10CHE_TS_WAY1)
+ sne t4, 0
+ or t0, t4 # t0 = cache way address
+
+// TagHi & TagLo
+ .set noreorder
+ cache IndexLoadTag_I, 0(t0) # load tag
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ .set reorder
+
+ sw t0,R10_CheAdd(a0) # save cache address
+ sw t4,R10_TagHi(a0) # save TagHi
+ sw t5,R10_TagLo(a0) # save TagLo
+
+// Cache data & ECC
+ addu t3,t0,64 # t3 = cacne address increment
+ addu t7,a0,64 # t7 = data save address increment
+ addu t8,a0,32 # t8 = ECC save address increment
+
+load_Icache_loop:
+ subu t3,4 # new cache address
+ subu t7,4 # new data save address
+ subu t8,2 # new ECC save address
+
+ .set noreorder
+ cache IndexLoadData_I,0(t3) # load data
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ mfc0 t6,ecc
+ .set reorder
+
+ sw t5,R10_Cache_data0_Hi(t7) # save data low
+ sll t4,8
+ or t6,t4
+ sh t6,R10_ECC0(t8) # save ECC
+
+ bne t3,t0,load_Icache_loop # 16 times
+
+// Cache invalidate
+ .set noreorder
+ cache IndexInvalidate_I, 0(t0)
+ .set reorder
+
+// li t4,NORMAL_ERR
+// sw t4,(a1)
+
+ j t5_log_end
+
+
+// D-cache
+t5_dche_log:
+// Make cache addr
+ and t4,t1,R10CHE_PIDX_DW
+ or t0,t4
+ and t4,t1,(R10CHE_D_WAY1|R10CHE_TA_WAY1|R10CHE_TS_WAY1|R10CHE_TM_WAY1)
+ sne t4,0
+ or t0,t4 # t0 = cache way address
+
+// TagHi & TagLo
+ .set noreorder
+ cache IndexLoadTag_D,0(t0) # load tag
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ .set reorder
+
+ sw t0,R10_CheAdd(a0) # save cache address
+ sw t4,R10_TagHi(a0) # save TagHi
+ sw t5,R10_TagLo(a0) # save TagLo
+
+// Cache data & ECC
+ and t0,0xffffffe1 # 32 bytes boundary block
+ addu t3,t0,32 # t3 = cacne address increment
+ addu t7,a0,64 # t7 = data save address increment
+ addu t8,a0,32 # t8 = ECC save address increment
+
+load_Dcache_loop:
+ subu t3,4 # new cache address
+ subu t7,8 # new data save address
+ subu t8,4 # new ECC save address
+
+ .set noreorder
+ cache IndexLoadData_D,0(t3) # load data
+ mfc0 t5,taglo
+ mfc0 t6,ecc
+ .set reorder
+
+ sw t5,R10_Cache_data0_Lo(t7) # save data low
+ sw t6,R10_ECC0(t8) # save ECC
+
+ bne t3,t0,load_Dcache_loop # 8 times
+
+ .set noreorder
+ cache IndexWriteBack_D,0(t0)
+ .set reorder
+
+// li t4,FATAL_ERR
+// sw t4,(a1)
+
+t5_log_end:
+ .set noreorder
+
+ lw t5,R10_Status(a0) # save Status
+ mfc0 t4,cacheerr
+ mtc0 t5,psr
+ nop
+ nop
+
+ .set reorder
+
+ and t4,R10CHE_EW # cache error in chelog?
+ beqz t4,t5_che_log_end
+
+ li v0,R10_CHER_IN_CHER
+// li t4,FATAL_ERR
+// sw t4,(a1)
+
+t5_che_log_end:
+
+ move a1,a0
+ move a2,v0
+ move a0,v1
+ j HalpCacheErrorLog
+
+ .end HalpCacheErrorRoutine
+
+
+/*********************************
+ * cache psued failure
+ *
+ * a0 = error code (argument)
+ ********************************/
+/*
+//LEAF(psued_che)
+
+ LEAF_ENTRY(psude_che)
+
+ .set noreorder
+ li t0, PSUED_ADDRESS # error address
+ lw t1, (t0)
+ mfc0 t4, psr # save SR
+ sw t1, (t0)
+ li t6, 1
+ or t5, t4, (SR_CE | SR_DE)
+ mtc0 t6, ecc # ECC error
+ mtc0 t5, psr # set CE,DE bit
+ .set reorder
+
+ beqz a0, sche_yellow
+ li t1, 0xbadfaced
+ sw t1,(t0) # D-cache parity error
+ j psued_end
+
+sche_yellow:
+ .set noreorder
+ cache 1, (t0) # S-cache 2bit error
+ nop
+psued_end:
+ mtc0 C0_SR,t4 # restore sr
+ j ra
+ nop
+ .set reorder
+
+ END(psued_che)
+*/
+
+ .set at
+ .set reorder
+
+//
+// ****** temp ******
+/*********************************
+ * 32bit tag parity check
+ *
+ * v0 = return code (return value)
+ * 0 -- no error
+ * 1 -- error
+ *
+ * a0 = log field address (argument) : not used and not broken
+ * a1 = error code address (argument) : not used and not broken
+ * a2 = check data (argument)
+ * t0 = cache virtual address : not used and not broken
+ * t1 = Cache error reg : not used and not broken
+ * t2 = TagLo reg : not used and not broken
+ * t3 = ECC reg : not used and not broken
+ * t4 - t7 temprary data
+ ********************************/
+LEAF_ENTRY(tag_parity_chk)
+ .set reorder
+ li t4, 1 # target check bit
+ move v0, zero # Hparity bit and return value
+
+ptag_chk_loop:
+ and t5, a2, t4
+ sne t5, 0
+ xor v0, t5 # calcurate parity
+ sll t4, 1
+ bnez t4, ptag_chk_loop # loop 31 times
+ j ra
+
+// END(tag_parity_chk)
+ .end tag_parity_chk
+
+/*********************************
+ * 64bit data parity check
+ *
+ * v0 = return code (return value)
+ * 0 -- no error
+ * 1 -- error
+ *
+ * a0 = log field address (argument) : not used and not broken
+ * a1 = error code address (argument) : not used and not broken
+ * a2 = 64bit data (argument)
+ * a3 = 8bit check data (argument)
+ * t0 = cache virtual address : not used and not broken
+ * t1 = Cache error reg : not used and not broken
+ * t2 = TagLo reg : not used and not broken
+ * t3 = ECC reg : not used and not broken
+ * t4 - t7 temprary data
+ ********************************/
+#if 0
+LEAF(dat_parity_chk)
+ .set reorder
+ li t4, 1 # target check bit
+ li t5, 1 # target parity bit
+ li t6, 8 # byte counter
+ move v0, zero # Hparity bit and return value
+
+pdat_chk_loop:
+ and t7, a2, t4
+ sne t7, 0
+ xor v0, t7 # calcurate parity
+ DSLL (T4, T4, 1)
+
+ subu t6, 1 # if 1byte check end?
+ bnez t6, pdat_chk_skip # else skip
+
+ and t7, a3, t5 # then check parity bit
+ sne t7, 0
+ xor v0, t7 # calcurate parity
+ xor v0, 1 # odd parity, not even 1993.11.7
+ sll t5, 1
+ li t6, 8 # reload byte counter
+
+ beqz v0, pdat_chk_skip # if no parity error then continue
+ j ra # else error return
+
+pdat_chk_skip:
+ bnez t4, pdat_chk_loop # loop 63 times
+ j ra
+
+ END(dat_parity_chk)
+#endif
+
+/*********************************
+ * 2nd cache tag ECC check
+ *
+ * v0 = return code (return value)
+ * 0x20 -- SCHE_TAG_1BIT
+ * 0x21 -- SCHE_TAG_2BIT
+ * 0x23 -- SCHE_TAG_UNKNOW
+ * v1 = tag syndrome (return value)
+ *
+ * a0 = log field address (argument) : not used and not broken
+ * a1 = error code address (argument) : not used and not broken
+ * a2 = 2nd Tag erronious data (argument, return value)
+ * t0 = cache virtual address : not used and not broken
+ * t1 = Cache error reg : not used and not broken
+ * t2 = TagLo reg : not used and not broken
+ * t3 = ECC reg : not used and not broken
+ * t4 - t7 temprary data
+ ********************************/
+LEAF_ENTRY(tag_ecc_chk)
+ .set reorder
+ li t4, 1 # target check bit
+ la t5, tag_synd # tag syndrome data
+ move v1, zero # tag syndrome and return value
+
+// # make syndrome data
+tag_ecc_loop1:
+ and t6, a2, t4
+ beqz t6, tag_ecc_skip0
+ lbu t7, (t5) # make syndrome
+ xor v1, t7 #
+tag_ecc_skip0:
+ sll t4, 1
+ addu t5, 1
+ bnez t4, tag_ecc_loop1 # loop 31 times
+
+ bnez v1, tag_ecc_err # if no error
+ li v0, SCHE_TAG_UNKNOW # then unknown error
+ j ra
+
+// # modify data
+tag_ecc_err:
+ li t4, 1 # target check bit
+ la t5, tag_synd # tag syndrome data
+
+tag_ecc_loop2:
+ lbu t7, (t5) # 1bit error
+ beq v1, t7, tag_ecc_1bit # then 1bit error
+
+ sll t4, 1
+ addu t5, 1
+ bnez t4, tag_ecc_loop2 # loop 31 times
+
+ li v0, SCHE_TAG_2BIT # 2bit error
+ j ra
+
+tag_ecc_1bit:
+ xor a2, t4 # modified data
+ li v0, SCHE_TAG_1BIT # 1bit error
+ j ra
+
+tag_synd:
+ .byte 0x01 # ECC 0 (bit 25)
+ .byte 0x02 # ECC 1 (bit 26)
+ .byte 0x04 # ECC 2 (bit 27)
+ .byte 0x08 # ECC 3 (bit 28)
+ .byte 0x10 # ECC 4 (bit 29)
+ .byte 0x20 # ECC 5 (bit 30)
+ .byte 0x40 # ECC 6 (bit 31)
+ .byte 0x45 # Pidx 0 (bit 19)
+ .byte 0x29 # Pidx 1 (bit 20)
+ .byte 0x51 # Pidx 2 (bit 21)
+ .byte 0x13 # CS 0 (bit 22)
+ .byte 0x49 # CS 1 (bit 23)
+ .byte 0x25 # CS 2 (bit 24)
+ .byte 0x07 # STag 00 (bit 00)
+ .byte 0x16 # STag 01 (bit 01)
+ .byte 0x26 # STag 02 (bit 02)
+ .byte 0x46 # STag 03 (bit 03)
+ .byte 0x0d # STag 04 (bit 04)
+ .byte 0x0e # STag 05 (bit 05)
+ .byte 0x1c # STag 06 (bit 06)
+ .byte 0x4c # STag 07 (bit 07)
+ .byte 0x31 # STag 08 (bit 08)
+ .byte 0x32 # STag 09 (bit 09)
+ .byte 0x38 # STag 10 (bit 10)
+ .byte 0x70 # STag 11 (bit 11)
+ .byte 0x61 # STag 12 (bit 12)
+ .byte 0x62 # STag 13 (bit 13)
+ .byte 0x64 # STag 14 (bit 14)
+ .byte 0x68 # STag 15 (bit 15)
+ .byte 0x0b # STag 16 (bit 16)
+ .byte 0x15 # STag 17 (bit 17)
+ .byte 0x23 # STag 18 (bit 18)
+
+// END(tag_ecc_chk)
+ .end tag_ecc_chk
+#if 0
+/*********************************
+ * 2nd cache 64bit data ECC check
+ *
+ * v0 = return code (return value)
+ * 0x26 -- SCHE_DAT_1BIT
+ * 0x27 -- SCHE_DAT_2BIT_C
+ * 0x29 -- SCHE_DAT_UNKNOW
+ * v1 = data syndrome (return value)
+ *
+ * a0 = log field address (argument) : not used and not broken
+ * a1 = error code address (argument) : not used and not broken
+ * a2 = 2nd 64bit data erronious data (argument, return value)
+ * a3 = 8bit ECC data (argument, return value)
+ * t0 = cache virtual address : not used and not broken
+ * t1 = Cache error reg : not used and not broken
+ * t2 = TagLo reg : not used and not broken
+ * t3 = ECC reg : not used and not broken
+ * t4 - t7 temprary data
+ ********************************/
+LEAF(dat_ecc_chk)
+ .set reorder
+ li t4, 1 # target check bit
+ la t5, dat_synd # data syndrome address
+ move v1, zero # data syndrome and return value
+
+ # make syndrome data
+dat_ecc_loop1:
+ and t6, a2, t4
+ beqz t6, dat_ecc_skip0
+ lbu t7, (t5) # make syndrome of data
+ xor v1, t7 #
+dat_ecc_skip0:
+ addu t5, 1
+ DSLL (T4, T4, 1)
+ bnez t4, dat_ecc_loop1 # loop 63 times
+
+ li t4, 1 # target check bit
+dat_ecc_loop2:
+ and t6, a3, t4
+ beqz t6, dat_ecc_skip1
+ lbu t7, (t5) # make syndrome of data
+ xor v1, t7 #
+dat_ecc_skip1:
+ sll t4, 1
+ addu t5, 1
+ bne t4, 0x100, dat_ecc_loop2 # loop 7 times
+
+ bnez v1, dat_ecc_err # if error
+ li v0, SCHE_DAT_UNKNOW # else unknown error
+ j ra
+
+ # modify data
+dat_ecc_err:
+ li t4, 1 # target check bit
+ la t5, dat_synd # tag syndrome data
+
+dat_ecc_loop3:
+ lbu t7, (t5) # 1bit error
+ beq v1, t7, dat_ecc_1bit # then 1bit error
+
+ DSLL (T4, T4, 1)
+ addu t5, 1
+ bnez t4, dat_ecc_loop3 # loop 63 times
+
+ li t4, 1 # target check bit
+
+dat_ecc_loop4:
+ lbu t7, (t5) # 1bit error
+ beq v1, t7, dat_ecc_1bit2 # then 1bit error
+
+ sll t4, 1
+ addu t5, 1
+ bne t4, 0x100, dat_ecc_loop4 # loop 7 times
+
+ li v0, SCHE_DAT_2BIT_C # 2bit error
+ j ra
+
+dat_ecc_1bit2:
+ xor a3, t4 # modified ECC
+ j dat_ecc_1bitend
+
+dat_ecc_1bit:
+ xor a2, t4 # modified data
+dat_ecc_1bitend:
+ li v0, SCHE_DAT_1BIT # 1bit error
+ j ra
+
+dat_synd:
+ .byte 0x13 # Data 00 (bit 00)
+ .byte 0x23 # Data 01 (bit 01)
+ .byte 0x43 # Data 02 (bit 02)
+ .byte 0x83 # Data 03 (bit 03)
+ .byte 0x2f # Data 04 (bit 04)
+ .byte 0xf1 # Data 05 (bit 05)
+ .byte 0x0d # Data 06 (bit 06)
+ .byte 0x07 # Data 07 (bit 07)
+ .byte 0xd0 # Data 08 (bit 08)
+ .byte 0x70 # Data 09 (bit 09)
+ .byte 0x4f # Data 10 (bit 10)
+ .byte 0xf8 # Data 11 (bit 11)
+ .byte 0x61 # Data 12 (bit 12)
+ .byte 0x62 # Data 13 (bit 13)
+ .byte 0x64 # Data 14 (bit 14)
+ .byte 0x68 # Data 15 (bit 15)
+ .byte 0x1c # Data 16 (bit 16)
+ .byte 0x2c # Data 17 (bit 17)
+ .byte 0x4c # Data 18 (bit 18)
+ .byte 0x8c # Data 19 (bit 19)
+ .byte 0x15 # Data 20 (bit 20)
+ .byte 0x25 # Data 21 (bit 21)
+ .byte 0x45 # Data 22 (bit 22)
+ .byte 0x85 # Data 23 (bit 23)
+ .byte 0x19 # Data 24 (bit 24)
+ .byte 0x29 # Data 25 (bit 25)
+ .byte 0x49 # Data 26 (bit 26)
+ .byte 0x89 # Data 27 (bit 27)
+ .byte 0x1a # Data 28 (bit 28)
+ .byte 0x2a # Data 29 (bit 29)
+ .byte 0x4a # Data 30 (bit 30)
+ .byte 0x8a # Data 31 (bit 31)
+ .byte 0x51 # Data 32 (bit 32)
+ .byte 0x52 # Data 33 (bit 33)
+ .byte 0x54 # Data 34 (bit 34)
+ .byte 0x58 # Data 35 (bit 35)
+ .byte 0x91 # Data 36 (bit 36)
+ .byte 0x92 # Data 37 (bit 37)
+ .byte 0x94 # Data 38 (bit 38)
+ .byte 0x98 # Data 39 (bit 39)
+ .byte 0xa1 # Data 40 (bit 40)
+ .byte 0xa2 # Data 41 (bit 41)
+ .byte 0xa4 # Data 42 (bit 42)
+ .byte 0xa8 # Data 43 (bit 43)
+ .byte 0x31 # Data 44 (bit 44)
+ .byte 0x32 # Data 45 (bit 45)
+ .byte 0x34 # Data 46 (bit 46)
+ .byte 0x38 # Data 47 (bit 47)
+ .byte 0x16 # Data 48 (bit 48)
+ .byte 0x26 # Data 49 (bit 49)
+ .byte 0x46 # Data 50 (bit 50)
+ .byte 0x86 # Data 51 (bit 51)
+ .byte 0x1f # Data 52 (bit 52)
+ .byte 0xf2 # Data 53 (bit 53)
+ .byte 0x0b # Data 54 (bit 54)
+ .byte 0x0e # Data 55 (bit 55)
+ .byte 0xb0 # Data 56 (bit 56)
+ .byte 0xe0 # Data 57 (bit 57)
+ .byte 0x8f # Data 58 (bit 58)
+ .byte 0xf4 # Data 59 (bit 59)
+ .byte 0xc1 # Data 60 (bit 60)
+ .byte 0xc2 # Data 61 (bit 61)
+ .byte 0xc4 # Data 62 (bit 62)
+ .byte 0xc8 # Data 63 (bit 63)
+
+ .byte 0x01 # ECC 0 (bit 0)
+ .byte 0x02 # ECC 1 (bit 1)
+ .byte 0x04 # ECC 2 (bit 2)
+ .byte 0x08 # ECC 3 (bit 3)
+ .byte 0x10 # ECC 4 (bit 4)
+ .byte 0x20 # ECC 5 (bit 5)
+ .byte 0x40 # ECC 6 (bit 6)
+ .byte 0x80 # ECC 7 (bit 7)
+
+ END(dat_ecc_chk)
+#endif
diff --git a/private/ntos/nthals/halr98b/mips/cirrus.h b/private/ntos/nthals/halr98b/mips/cirrus.h
new file mode 100644
index 000000000..9f9846aaf
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/cirrus.h
@@ -0,0 +1,298 @@
+#ident "@(#) NEC cirrus.h 1.2 94/11/21 13:58:39"
+/* #pragma comment(exestr, "@(#) NEC(MIPS) cirrus.h 1.7 94/02/03 18:58:17" ) */
+/* #pragma comment(exestr, "@(#) NEC(MIPS) cirrus.h 1.6 94/01/28 11:50:02" ) */
+/* #pragma comment(exestr, "@(#) NEC(MIPS) cirrus.h 1.4 93/10/29 12:25:02" ) */
+/*++
+
+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
+ *
+ * M002 1994.2.2 A. Kuriyama @ oa2
+ * - Bug fix
+ *
+ * Modify : Video Memory Physical Address
+ *
+ *
+ * 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
+ *
+ ***************************************************************
+ *
+ * S001 1994.06.06 T.Samezima
+ *
+ * - Modify for R98 MIPS R4400
+ *
+ * Change : LA_MASK
+ *
+ * S002 '94.11/21 T.Samezima
+ * Chg invalid S001
+ *
+ */
+
+//
+// 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 */
+
+/* START M002 */
+#define LA_MASK 0xe // S001, S002
+/* END M002 */
+#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/halr98b/mips/cmdcnst.h b/private/ntos/nthals/halr98b/mips/cmdcnst.h
new file mode 100644
index 000000000..ea2bba221
--- /dev/null
+++ b/private/ntos/nthals/halr98b/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/halr98b/mips/esmnvram.h b/private/ntos/nthals/halr98b/mips/esmnvram.h
new file mode 100644
index 000000000..cded099f2
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/esmnvram.h
@@ -0,0 +1,271 @@
+/*++
+
+Copyright (C) 1994, 1995 NEC Corporation
+
+File Name:
+
+ esmnvram.h
+
+Abstract:
+
+ This module contains the definitions for the extended NVRAM.
+
+Author:
+
+
+Modification History:
+
+ - M000 12/22/94 - created by Takehiro Ueda (tueda@oa2.kbnes.nec.co.jp)
+ - M001 11/22/95 - modified by Masayuki Fujii (masa@oa2.kbnes.nec.co.jp)
+ - M002 02/12/96 - modified by Masayuki Fujii (masa@oa2.kbnes.nec.co.jp)
+--*/
+
+
+#pragma pack(1)
+
+
+//
+// define structures for each area of NVRAM
+//
+
+
+//
+// WAS & PS common infromation for ECC memory error
+//
+
+typedef struct _MEM_ERR_REC {
+ UCHAR mem_status;
+ UCHAR err_count;
+} MEM_ERR_REC, *pMEM_ERR_REC;
+
+
+//
+// setting for ALIVE information area
+//
+
+typedef struct _ALIVE_AREA_INFO {
+ USHORT offset_alive;
+} ALIVE_AREA_INFO, *pALIVE_AREA_INFO;
+
+
+//
+// setting for ECC 1bit error information area
+//
+
+typedef struct _ECC1_ERR_AREA_INFO {
+ USHORT offset_1biterr;
+ USHORT size_rec;
+ USHORT num_rec;
+ USHORT offset_latest;
+ ULONG read_data_latest;
+ UCHAR err_count_group0;
+ UCHAR err_count_group1;
+ UCHAR err_count_group2;
+ UCHAR err_count_group3;
+ UCHAR err_count_group4;
+ UCHAR err_count_group5;
+ UCHAR err_count_group6;
+ UCHAR err_count_group7;
+} ECC1_ERR_AREA_INFO, *pECC1_ERR_AREA_INFO;
+
+
+//
+// setting for ECC 2bit error information area
+//
+
+typedef struct _ECC2_ERR_AREA_INFO {
+ USHORT offset_2biterr;
+ USHORT size_rec;
+ USHORT num_rec;
+ USHORT offset_latest;
+ ULONG read_data_latest;
+ UCHAR simm_flag_group1;
+ UCHAR simm_flag_group2;
+ UCHAR simm_flag_group3;
+ UCHAR simm_flag_group4;
+ CHAR reserved[4];
+} ECC2_ERR_AREA_INFO, *pECC2_ERR_AREA_INFO;
+
+
+//
+// setting for system error information area
+//
+
+typedef struct _SYSTEM_ERR_AREA_INFO {
+ USHORT offset_systemerr;
+ USHORT size_rec;
+ USHORT num_rec;
+ USHORT offset_latest;
+} SYSTEM_ERR_AREA_INFO, *pSYSTEM_ERR_AREA_INFO;
+
+
+//
+// setting for critical error information area
+//
+
+typedef struct _CRITICAL_ERR_AREA_INFO {
+ USHORT offset_critical;
+ USHORT size_rec;
+ USHORT num_rec;
+ USHORT offset_latest;
+} CRITICAL_ERR_AREA_INFO, *pCRITICAL_ERR_AREA_INFO;
+
+
+//
+// setting for reduction information area
+//
+
+typedef struct _RED_AREA_INFO {
+ USHORT offset_red;
+} RED_AREA_INFO, *pRED_AREA_INFO;
+
+
+//
+// setting for reserved area
+//
+
+typedef struct _RESERVE_AREA_INFO {
+ USHORT offset_reserve;
+} RESERVE_AREA_INFO, *pRESERVE_AREA_INFO;
+
+
+//
+// system information structure
+// 49 bytes
+//
+
+typedef struct _SYS_INFO {
+ UCHAR system_flag;
+ CHAR reserved1[3]; // for 4 byte alignment
+ CHAR sys_description[32];
+ ULONG serial_num;
+ ULONG magic;
+ CHAR reserved2[4]; // reserved
+} SYS_INFO, *pSYS_INFO;
+
+
+//
+// NVRAM header structure
+// 640 bytes
+//
+
+typedef struct _NVRAM_HEADER {
+ MEM_ERR_REC mem_err_map[256]; // common area for NT & NW
+ UCHAR nvram_flag;
+ CHAR when_formatted[14];
+ CHAR reserved[3]; // for 4 byte alignment
+ ALIVE_AREA_INFO alive;
+ ECC1_ERR_AREA_INFO ecc1bit_err;
+ ECC2_ERR_AREA_INFO ecc2bit_err;
+ SYSTEM_ERR_AREA_INFO system_err;
+ CRITICAL_ERR_AREA_INFO critical_err_log;
+ RED_AREA_INFO red;
+ RESERVE_AREA_INFO reserve;
+ SYS_INFO system;
+} NVRAM_HEADER, *pNVRAM_HEADER;
+
+
+//
+// ALIVE, pager call information structure
+// 80 bytes
+//
+
+typedef struct _ALIVE_INFO {
+ UCHAR alert_level;
+ CHAR primary_destination[16];
+ CHAR secondary_destinaiton[16];
+ CHAR reserved[47]; // reserved
+} ALIVE_INFO, *pALIVE_INFO;
+
+
+//
+// ECC 1bit error information structure
+//
+
+typedef struct _ECC1_ERR_REC {
+ UCHAR record_flag;
+ ULONG err_address;
+ CHAR when_happened[14];
+ ULONG syndrome;
+ UCHAR specified_group;
+ UCHAR specified_simm;
+} ECC1_ERR_REC, *pECC1_ERR_REC;
+
+
+//
+// ECC 2bit error information structure
+//
+
+typedef struct _ECC2_ERR_REC {
+ UCHAR record_flag;
+ ULONG err_address;
+ CHAR when_happened[14];
+ ULONG syndrome;
+ UCHAR specified_group;
+ UCHAR specified_simm;
+} ECC2_ERR_REC, *pECC2_ERR_REC;
+
+
+//
+// stop error information structure
+//
+
+typedef struct _STOP_ERR_REC {
+ UCHAR record_flag;
+ CHAR when_happened[14];
+ CHAR err_description[496];
+ CHAR reserved[1]; // reserved
+} STOP_ERR_REC, *pSTOP_ERR_REC;
+
+
+//
+// critical error information structure
+//
+
+typedef struct _CRITICAL_ERR_REC {
+ UCHAR record_flag;
+ CHAR when_happened[14];
+ CHAR source[20];
+ CHAR err_description[80];
+ UCHAR error_code;
+ CHAR reserved[12]; // reserved
+} CRITICAL_ERR_REC, *pCRITICAL;
+
+
+//
+// memory reduction information structure
+//
+
+typedef struct _MEM_RED_INF {
+ ULONG simm_red_inf;
+ CHAR simm_rfu0[4]; // reserved
+ ULONG simm_stp_inf;
+ CHAR simm_rfu1[4]; // reserved
+ ULONG simm_phy_inf;
+ CHAR simm_rfu2[12]; // reserved
+} MEM_RED_INF, *pMEM_RED;
+
+
+//
+// SIMM size information structure
+//
+
+typedef struct _MEM_CAP_INF {
+ CHAR simm_phy_cap[64];
+} MEM_CAP_INF, *pMEM_CAP;
+
+
+//
+// CPU reduction information structure
+//
+
+typedef struct _CPU_RED_INF {
+ ULONG cpu_red_inf;
+ ULONG cpu_stp_inf;
+ ULONG cpu_phy_inf;
+ CHAR cpu_rfu[4] ; // reserved
+} CPU_RED_INF, *pCPU_RED;
+
+
+#pragma pack()
+
diff --git a/private/ntos/nthals/halr98b/mips/glint.h b/private/ntos/nthals/halr98b/mips/glint.h
new file mode 100644
index 000000000..156c3efcc
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/glint.h
@@ -0,0 +1,580 @@
+// #ident "@(#) glint.h 1.1 95/06/30 05:27:26 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/halr98b/mips/halp.h b/private/ntos/nthals/halr98b/mips/halp.h
new file mode 100644
index 000000000..25f675868
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/halp.h
@@ -0,0 +1,674 @@
+/*
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ halp.h
+
+Abstract:
+
+ This header file defines the private Hardware Architecture Layer (HAL)
+ interfaces.
+
+--*/
+
+#ifndef _HALP_
+#define _HALP_
+
+#if defined(NT_UP)
+#undef NT_UP
+#endif
+
+
+#include "nthal.h"
+#include "hal.h"
+
+#include "r98bdef.h"
+#include "r98breg.h"
+#include "rxhalp.h"
+#include "hali.h"
+
+#include "xm86.h"
+#include "x86new.h"
+
+extern PVOID HalpEisaControlBase;
+extern PVOID HalpRealTimeClockBase;
+extern PVOID HalpEisaMemoryBase;
+
+//
+// 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
+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
+ );
+
+BOOLEAN
+HalpInitializeX86DisplayAdapter(
+ VOID
+ );
+
+VOID
+HalpResetX86DisplayAdapter(
+ VOID
+ );
+
+
+VOID
+HalpInt0Dispatch(
+ VOID
+ );
+
+VOID
+HalpInt1Dispatch(
+ VOID
+ );
+
+VOID
+HalpInt2Dispatch(
+ VOID
+ );
+
+VOID
+HalpInt3Dispatch(
+ VOID
+ );
+
+VOID
+HalpInt4Dispatch(
+ VOID
+ );
+
+VOID
+HalpInt5Dispatch(
+ VOID
+ );
+
+VOID
+HalpInitDisplayStringIntoNvram(
+ VOID
+ );
+
+
+VOID
+HalpTimerDispatch(
+ VOID
+ );
+
+VOID
+HalpEifDispatch(
+ VOID
+ );
+
+VOID
+HalpOutputSegment(
+ IN ULONG Number,
+ IN UCHAR Data
+ );
+
+VOID
+HalpDisplaySegment(
+ IN ULONG Number,
+ IN UCHAR Data
+ );
+
+BOOLEAN
+HalpEisaDispatch(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+BOOLEAN
+HalpCreateEisaStructures (
+ VOID
+ );
+
+BOOLEAN
+HalpCreatePciStructures (
+ VOID
+ );
+
+ULONG
+HalpPonceNumber (
+ IN ULONG BusNumber
+ );
+
+PADAPTER_OBJECT
+HalpAllocateEisaAdapter(
+ IN PDEVICE_DESCRIPTION DeviceDescriptor
+ );
+
+VOID
+HalpEisaMapTransfer(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN BOOLEAN WriteToDevice
+ );
+
+
+KIRQL
+HalpMapNvram (
+ IN PENTRYLO SavedPte
+ );
+
+VOID
+HalpUnmapNvram (
+ IN PENTRYLO SavedPte,
+ IN KIRQL OldIrql
+ );
+
+VOID
+HalpDisableEisaInterrupt(
+ IN ULONG Vector
+ );
+
+VOID
+HalpEnableEisaInterrupt(
+ IN ULONG Vector,
+ IN KINTERRUPT_MODE InterruptMode
+ );
+
+
+VOID
+HalpDisablePciInterrupt(
+ IN ULONG Vector
+ );
+
+VOID
+HalpEnablePciInterrupt(
+ IN ULONG Vector
+ );
+
+//
+// I change parameter on following large Register access function.
+// v-masank@microsoft.com
+// 5/21/96
+//
+VOID
+HalpReadLargeRegister(
+ IN volatile PULONGLONG VirtualAddress,
+ OUT PULONGLONG Buffer
+ );
+
+VOID
+HalpWriteLargeRegister(
+ IN volatile PULONGLONG VirtualAddress,
+ IN PULONGLONG Buffer
+ );
+
+VOID
+HalpRegisterNmi(
+ VOID
+ );
+
+VOID
+HalpAllocateMapRegisters(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+
+BOOLEAN
+HalpHandleEif(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ );
+
+ULONG
+HalpGetCause(
+ VOID
+ );
+
+
+VOID
+HalpNmiHandler(
+ VOID
+ );
+
+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
+);
+
+VOID
+HalpEccMultiBitError(
+ IN ULONG MagellanAllError,
+ IN UCHAR magSet
+ );
+
+VOID
+HalpEcc1bitError(
+ VOID
+ );
+
+VOID
+HalpInitDisplayStringIntoNvram(
+ VOID
+ );
+
+VOID
+HalpSetInitDisplayTimeStamp(
+ VOID
+ );
+
+VOID
+HalpSuccessOsStartUp(
+ VOID
+ );
+
+VOID
+HalpChangePanicFlag(
+ IN ULONG NewPanicFlg,
+ IN UCHAR NewLogFlg,
+ IN UCHAR CurrentLogFlgMask
+ );
+
+ULONG
+HalpReadPhysicalAddr(
+ IN ULONG PhysicalAddr
+ );
+
+
+VOID
+HalStringIntoBuffer(
+ IN UCHAR Character
+ );
+
+VOID
+HalStringIntoBufferStart(
+ IN ULONG Column,
+ IN ULONG Row
+ );
+
+VOID
+HalpStringBufferCopyToNvram(
+ VOID
+ );
+
+
+VOID
+HalpLocalDeviceReadWrite(
+ IN ULONG Offset,
+ IN OUT PUCHAR Data,
+ IN ULONG ReadWrite
+ );
+
+VOID
+HalpMrcModeChange(
+ UCHAR Mode
+ );
+
+
+ULONG
+HalpReadAndWritePhysicalAddr(
+ IN ULONG PhysicalAddr
+ );
+
+VOID
+WRITE_REGISTER_ULONGLONG(
+ IN PVOID,
+ IN PVOID
+ );
+
+VOID
+READ_REGISTER_ULONGLONG(
+ IN PVOID,
+ IN PVOID
+ );
+
+
+
+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
+ );
+
+
+BOOLEAN
+HalpTranslateSystemBusAddress(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ );
+
+
+NTSTATUS
+HalpAdjustEisaResourceList (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
+ );
+
+HalpGetEisaData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+BOOLEAN
+HalpTranslateEisaBusAddress (
+ 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
+HalpTranslatePCIBusAddress(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ );
+
+
+#if DBG
+
+
+VOID
+HalpTestPciPrintResult(
+ IN PULONG Buffer,
+ IN ULONG Length
+);
+
+
+VOID
+R98DebugOutPut(
+ ULONG DebugPrintLevel, // Debug Level
+ PCSZ DebugMessageLed, // For LED strings. shuld be 4Byte.
+ PCSZ DebugMessage, // For DISPLAY or SIO
+ ...
+ );
+
+
+
+#define R98DbgPrint(_x_) R98DebugOutPut _x_
+#else
+#define R98DbgPrint(_x_)
+#endif
+
+
+#ifdef RtlMoveMemory
+#undef RtlMoveMemory
+#undef RtlCopyMemory
+#undef RtlFillMemory
+#undef RtlZeroMemory
+
+#define RtlCopyMemory(Destination,Source,Length) RtlMoveMemory((Destination),(Source),(Length))
+VOID
+RtlMoveMemory (
+ PVOID Destination,
+ CONST VOID *Source,
+ ULONG Length
+ );
+
+VOID
+RtlFillMemory (
+ PVOID Destination,
+ ULONG Length,
+ UCHAR Fill
+ );
+
+VOID
+RtlZeroMemory (
+ PVOID Destination,
+ ULONG Length
+ );
+
+#endif // #ifdef RtlMoveMemory
+
+
+//
+// Define external references.
+//
+
+extern KSPIN_LOCK HalpBeepLock;
+extern KSPIN_LOCK HalpDisplayAdapterLock;
+extern ULONG HalpProfileCountRate;
+extern ULONG HalpStallScaleFactor;
+extern KSPIN_LOCK HalpSystemInterruptLock;
+extern KSPIN_LOCK HalpIprInterruptLock;
+extern KSPIN_LOCK HalpDieLock;
+extern KSPIN_LOCK HalpLogLock;
+
+
+extern UCHAR HalpChangeIntervalFlg[];
+extern ULONG HalpChangeIntervalCount;
+extern ULONG HalpNextTimeIncrement;
+extern ULONG HalpCurrentTimeIncrement;
+extern ULONG HalpNextIntervalCount;
+extern ULONG HalpNewTimeIncrement;
+
+extern ULONG HalpNvramValid;
+extern USHORT ErrBufferArea;
+
+LONG HalpECC1bitDisableFlag;
+LONG HalpECC1bitDisableTime;
+ULONG HalpECC1bitScfrBuffer;
+extern volatile ULONG HalpNMIFlag;
+extern ULONG HalpNMIHappend[R98B_MAX_CPU];
+
+
+//
+//
+// Resource usage information
+//
+
+
+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;
+#if defined(NT_40)
+ ULONG Length;
+#else
+ USHORT Length;
+#endif
+ } Element[];
+} ADDRESS_USAGE;
+
+#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;
+
+extern ADDRESS_USAGE HalpDefaultPcIoSpace;
+extern ADDRESS_USAGE HalpEisaIoSpace;
+extern ADDRESS_USAGE HalpMapRegisterMemorySpace;
+
+#define HalpRegisterAddressUsage(a) \
+ (a)->Next = HalpAddressUsageList, HalpAddressUsageList = (a);
+
+
+#define IRQ_PREFERRED 0x02
+#define IRQ_VALID 0x01
+
+
+VOID
+HalpReportResourceUsage (
+ IN PUNICODE_STRING HalName,
+ IN INTERFACE_TYPE DeviceInterfaceToUse
+);
+
+//
+// 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;
+
+BOOLEAN
+HalpIoTlbLimitOver(
+ IN PKINTERRUPT Interrupt
+ );
+
+#endif // _HALP_
diff --git a/private/ntos/nthals/halr98b/mips/j4cache.s b/private/ntos/nthals/halr98b/mips/j4cache.s
new file mode 100644
index 000000000..5a4a772a9
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/j4cache.s
@@ -0,0 +1,1190 @@
+// "@(#) NEC j4cache.s 1.5 94/12/06 10:46:13"
+// TITLE("Cache Flush")
+//++
+//
+// Copyright (c) 1991-1994 Microsoft Corporation
+//
+// Module Name:
+//
+// j4cache.s
+//
+// Abstract:
+//
+// This module implements the code necessary for cache operations on
+// a MIPS R4000.
+//
+//--
+
+#include "halmips.h"
+
+/*
+ * Original source: Build Number 1.612
+ *
+ * Modify for R98(MIPS/R4400)
+ *
+ ***********************************************************************
+ *
+ * S001 94.08/22 T.Samezima on SNES
+ *
+ * Add define _DUO_
+ *
+ * K001 94/10/11 N.Kugimoto
+ * Fix 807 Base
+ * K002 94/12/06 N.Kugimoto
+ * Fix Mem32
+ */
+
+#define _DUO_ // S001
+
+//
+// Define cache operations constants.
+//
+
+#define COLOR_BITS (7 << PAGE_SHIFT) // color bit (R4000 - 8kb cache)
+#define COLOR_MASK (0x7fff) // color mask (R4000 - 8kb cache)
+#define FLUSH_BASE 0xfffe0000 // flush base address
+#define PROTECTION_BITS ((1 << ENTRYLO_V) | (1 << ENTRYLO_D)) //
+
+ SBTTL("Change Color Page")
+//++
+//
+// VOID
+// HalChangeColorPage (
+// IN PVOID NewColor,
+// IN PVOID OldColor,
+// IN ULONG PageFrame
+// )
+//
+// Routine Description:
+//
+// This function changes the color of a page if the old and new colors
+// do not match.
+//
+// The algorithm used to change colors for a page is as follows:
+//
+// 1. Purge (hit/invalidate) the page from the instruction cache
+// using the old color.
+//
+// 2. Purge (hit/invalidate) the page from the data cache using
+// the old color.
+//
+// Arguments:
+//
+// NewColor (a0) - Supplies the page aligned virtual address of the
+// new color of the page to change.
+//
+// OldColor (a1) - Supplies the page aligned virtual address of the
+// old color of the page to change.
+//
+// PageFrame (a2) - Supplies the page frame number of the page that
+// is changed.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ .struct 0
+ .space 3 * 4 // fill
+CpRa: .space 4 // saved return address
+CpFrameLength: // length of stack frame
+CpA0: .space 4 // (a0)
+CpA1: .space 4 // (a1)
+CpA2: .space 4 // (a2)
+CpA3: .space 4 // (a3)
+
+ NESTED_ENTRY(HalChangeColorPage, CpFrameLength, zero)
+
+ subu sp,sp,CpFrameLength // allocate stack frame
+ sw ra,CpRa(sp) // save return address
+
+ PROLOGUE_END
+
+ and a0,a0,COLOR_BITS // isolate new color bits
+ and a1,a1,COLOR_BITS // isolate old color bits
+ beq a0,a1,10f // if eq, colors match
+ sw a1,CpA1(sp) // save old color bits
+ sw a2,CpA2(sp) // save page frame
+
+//
+// Purge the instruction cache using the old page color.
+//
+
+ move a0,a1 // set color value
+ move a1,a2 // set page frame number
+ li a2,PAGE_SIZE // set length of purge
+ jal HalPurgeIcachePage // purge instruction cache page
+
+//
+// Flush the data cache using the old page color.
+//
+
+ lw a0,CpA1(sp) // get old color bits
+ lw a1,CpA2(sp) // get page frame number
+ li a2,PAGE_SIZE // set length of purge
+ jal HalFlushDcachePage // purge data cache page
+10: lw ra,CpRa(sp) // get return address
+ addu sp,sp,CpFrameLength // deallocate stack frame
+ j ra // return
+
+ .end HalChangeColorPage
+
+ SBTTL("Flush Data Cache Page")
+//++
+//
+// VOID
+// HalFlushDcachePage (
+// IN PVOID Color,
+// IN ULONG PageFrame,
+// IN ULONG Length
+// )
+//
+// Routine Description:
+//
+// This function flushes (hit/writeback/invalidate) up to a page of data
+// from the data cache.
+//
+// Arguments:
+//
+// Color (a0) - Supplies the starting virtual address and color of the
+// data that is flushed.
+//
+// PageFrame (a1) - Supplies the page frame number of the page that
+// is flushed.
+//
+// Length (a2) - Supplies the length of the region in the page that is
+// flushed.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalFlushDcachePage)
+
+#if DBG
+
+ lw t0,KeDcacheFlushCount // get address of dcache flush count
+ lw t1,0(t0) // increment the count of flushes
+ addu t1,t1,1 //
+ sw t1,0(t0) // store result
+
+#endif
+
+ .set noreorder
+ .set noat
+ lw v0,KiPcr + PcAlignedCachePolicy(zero) // get cache policy
+ and a0,a0,COLOR_MASK // isolate color and offset bits
+ li t0,FLUSH_BASE // get base flush address
+ or t0,t0,a0 // compute color virtual address
+ sll t1,a1,ENTRYLO_PFN // shift page frame into position
+ or t1,t1,PROTECTION_BITS // merge protection bits
+ or t1,t1,v0 // merge cache policy
+ and a0,a0,0x1000 // isolate TB entry index
+ beql zero,a0,10f // if eq, first entry
+ move t2,zero // set second page table entry
+ move t2,t1 // set second page table entry
+ move t1,zero // set first page table entry
+10: mfc0 t3,wired // get TB entry index
+ lw v0,KiPcr + PcSecondLevelDcacheFillSize(zero) // get 2nd fill size
+ lw t4,KiPcr + PcFirstLevelDcacheFillSize(zero) // get 1st fill size
+ bnel zero,v0,15f // if ne, second level cache present
+ move t4,v0 // set flush block size
+ .set at
+ .set reorder
+
+//
+// Flush a page from the data cache.
+//
+
+15: DISABLE_INTERRUPTS(t5) // disable interrupts
+
+ .set noreorder
+ .set noat
+ mfc0 t6,entryhi // get current PID and VPN2
+ srl t7,t0,ENTRYHI_VPN2 // isolate VPN2 of virtual address
+ sll t7,t7,ENTRYHI_VPN2 //
+ and t6,t6,0xff << ENTRYHI_PID // isolate current PID
+ or t7,t7,t6 // merge PID with VPN2 of virtual address
+ mtc0 t7,entryhi // set VPN2 and PID for probe
+ mtc0 t1,entrylo0 // set first PTE value
+ mtc0 t2,entrylo1 // set second PTE value
+ mtc0 t3,index // set TB index value
+ nop // fill
+ tlbwi // write TB entry - 3 cycle hazzard
+ subu t6,t4,1 // compute block size minus one
+ and t7,t0,t6 // compute offset in block
+ addu a2,a2,t6 // round up to next block
+ addu a2,a2,t7 //
+ nor t6,t6,zero // complement block size minus one
+ and a2,a2,t6 // truncate length to even number
+ beq zero,a2,30f // if eq, no blocks to flush
+ and t8,t0,t6 // compute starting virtual address
+ addu t9,t8,a2 // compute ending virtual address
+ bne zero,v0,40f // if ne, second level cache present
+ subu t9,t9,t4 // compute ending loop address
+
+//
+// Flush the primary data cache only.
+//
+
+20: cache HIT_WRITEBACK_INVALIDATE_D,0(t8) // invalidate cache block
+ bne t8,t9,20b // if ne, more blocks to invalidate
+ addu t8,t8,t4 // compute next block address
+ .set at
+ .set reorder
+
+30: ENABLE_INTERRUPTS(t5) // enable interrupts
+
+ j ra // return
+
+//
+// Flush the primary and secondary data caches.
+//
+
+ .set noreorder
+ .set noat
+40: cache HIT_WRITEBACK_INVALIDATE_SD,0(t8) // invalidate cache block
+ bne t8,t9,40b // if ne, more blocks to invalidate
+ addu t8,t8,t4 // compute next block address
+ .set at
+ .set reorder
+
+ ENABLE_INTERRUPTS(t5) // enable interrupts
+
+ j ra // return
+
+ .end HalFlushDcachePage
+
+ SBTTL("Purge Data Cache Page")
+//++
+//
+// VOID
+// HalPurgeDcachePage (
+// IN PVOID Color,
+// IN ULONG PageFrame,
+// IN ULONG Length
+// )
+//
+// Routine Description:
+//
+// This function purges (hit/invalidate) up to a page of data from the
+// data cache.
+//
+// Arguments:
+//
+// Color (a0) - Supplies the starting virtual address and color of the
+// data that is purged.
+//
+// PageFrame (a1) - Supplies the page frame number of the page that
+// is purged.
+//
+// Length (a2) - Supplies the length of the region in the page that is
+// purged.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalPurgeDcachePage)
+
+#if DBG
+
+ lw t0,KeDcacheFlushCount // get address of dcache flush count
+ lw t1,0(t0) // increment the count of flushes
+ addu t1,t1,1 //
+ sw t1,0(t0) // store result
+
+#endif
+
+ .set noreorder
+ .set noat
+ lw v0,KiPcr + PcAlignedCachePolicy(zero) // get cache policy
+ and a0,a0,COLOR_MASK // isolate color bits
+ li t0,FLUSH_BASE // get base flush address
+ or t0,t0,a0 // compute color virtual address
+ sll t1,a1,ENTRYLO_PFN // shift page frame into position
+ or t1,t1,PROTECTION_BITS // merge protection bits
+ or t1,t1,v0 // merge cache policy
+ and a0,a0,0x1000 // isolate TB entry index
+ beql zero,a0,10f // if eq, first entry
+ move t2,zero // set second page table entry
+ move t2,t1 // set second page table entry
+ move t1,zero // set first page table entry
+10: mfc0 t3,wired // get TB entry index
+ lw v0,KiPcr + PcSecondLevelDcacheFillSize(zero) // get 2nd fill size
+ lw t4,KiPcr + PcFirstLevelDcacheFillSize(zero) // get 1st fill size
+ bnel zero,v0,15f // if ne, second level cache present
+ move t4,v0 // set purge block size
+ .set at
+ .set reorder
+
+//
+// Purge data from the data cache.
+//
+
+15: DISABLE_INTERRUPTS(t5) // disable interrupts
+
+ .set noreorder
+ .set noat
+ mfc0 t6,entryhi // get current PID and VPN2
+ srl t7,t0,ENTRYHI_VPN2 // isolate VPN2 of virtual address
+ sll t7,t7,ENTRYHI_VPN2 //
+ and t6,t6,0xff << ENTRYHI_PID // isolate current PID
+ or t7,t7,t6 // merge PID with VPN2 of virtual address
+ mtc0 t7,entryhi // set VPN2 and PID for probe
+ mtc0 t1,entrylo0 // set first PTE value
+ mtc0 t2,entrylo1 // set second PTE value
+ mtc0 t3,index // set TB index value
+ nop // fill
+ tlbwi // write TB entry - 3 cycle hazzard
+ subu t6,t4,1 // compute block size minus one
+ and t7,t0,t6 // compute offset in block
+ addu a2,a2,t6 // round up to next block
+ addu a2,a2,t7 //
+ nor t6,t6,zero // complement block size minus one
+ and a2,a2,t6 // truncate length to even number
+ beq zero,a2,30f // if eq, no blocks to purge
+ and t8,t0,t6 // compute starting virtual address
+ addu t9,t8,a2 // compute ending virtual address
+ bne zero,v0,40f // if ne, second level cache present
+ subu t9,t9,t4 // compute ending loop address
+
+//
+// Purge the primary data cache only.
+//
+
+20: cache HIT_INVALIDATE_D,0(t8) // invalidate cache block
+ bne t8,t9,20b // if ne, more blocks to invalidate
+ addu t8,t8,t4 // compute next block address
+ .set at
+ .set reorder
+
+30: ENABLE_INTERRUPTS(t5) // enable interrupts
+
+ j ra // return
+
+//
+// Purge the primary and secondary data caches.
+//
+
+ .set noreorder
+ .set noat
+40: cache HIT_INVALIDATE_SD,0(t8) // invalidate cache block
+ bne t8,t9,40b // if ne, more blocks to invalidate
+ addu t8,t8,t4 // compute next block address
+ .set at
+ .set reorder
+
+ ENABLE_INTERRUPTS(t5) // enable interrupts
+
+ j ra // return
+
+ .end HalPurgeDcachePage
+
+ SBTTL("Purge Instruction Cache Page")
+//++
+//
+// VOID
+// HalPurgeIcachePage (
+// IN PVOID Color,
+// IN ULONG PageFrame,
+// IN ULONG Length
+// )
+//
+// Routine Description:
+//
+// This function purges (hit/invalidate) up to a page fo data from the
+// instruction cache.
+//
+// Arguments:
+//
+// Color (a0) - Supplies the starting virtual address and color of the
+// data that is purged.
+//
+// PageFrame (a1) - Supplies the page frame number of the page that
+// is purged.
+//
+// Length (a2) - Supplies the length of the region in the page that is
+// purged.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalPurgeIcachePage)
+
+#if DBG
+
+ lw t0,KeIcacheFlushCount // get address of icache flush count
+ lw t1,0(t0) // increment the count of flushes
+ addu t1,t1,1 //
+ sw t1,0(t0) // store result
+
+#endif
+
+ .set noreorder
+ .set noat
+ lw v0,KiPcr + PcAlignedCachePolicy(zero) // get cache policy
+ and a0,a0,COLOR_MASK // isolate color bits
+ li t0,FLUSH_BASE // get base flush address
+ or t0,t0,a0 // compute color virtual address
+ sll t1,a1,ENTRYLO_PFN // shift page frame into position
+ or t1,t1,PROTECTION_BITS // merge protection bits
+ or t1,t1,v0 // merge cache policy
+ and a0,a0,0x1000 // isolate TB entry index
+ beql zero,a0,10f // if eq, first entry
+ move t2,zero // set second page table entry
+ move t2,t1 // set second page table entry
+ move t1,zero // set first page table entry
+10: mfc0 t3,wired // get TB entry index
+ lw v0,KiPcr + PcSecondLevelIcacheFillSize(zero) // get 2nd fill size
+ lw t4,KiPcr + PcFirstLevelIcacheFillSize(zero) // get 1st fill size
+ bnel zero,v0,15f // if ne, second level cache present
+ move t4,v0 // set purge block size
+ .set at
+ .set reorder
+
+//
+// Purge data from the instruction cache.
+//
+
+15: DISABLE_INTERRUPTS(t5) // disable interrupts
+
+ .set noreorder
+ .set noat
+ mfc0 t6,entryhi // get current PID and VPN2
+ srl t7,t0,ENTRYHI_VPN2 // isolate VPN2 of virtual address
+ sll t7,t7,ENTRYHI_VPN2 //
+ and t6,t6,0xff << ENTRYHI_PID // isolate current PID
+ or t7,t7,t6 // merge PID with VPN2 of virtual address
+ mtc0 t7,entryhi // set VPN2 and PID for probe
+ mtc0 t1,entrylo0 // set first PTE value
+ mtc0 t2,entrylo1 // set second PTE value
+ mtc0 t3,index // set TB index value
+ nop // fill
+ tlbwi // write TB entry - 3 cycle hazzard
+ subu t6,t4,1 // compute block size minus one
+ and t7,t0,t6 // compute offset in block
+ addu a2,a2,t6 // round up to next block
+ addu a2,a2,t7 //
+ nor t6,t6,zero // complement block size minus one
+ and a2,a2,t6 // truncate length to even number
+ beq zero,a2,30f // if eq, no blocks to purge
+ and t8,t0,t6 // compute starting virtual address
+ addu t9,t8,a2 // compute ending virtual address
+ bne zero,v0,40f // if ne, second level cache present
+ subu t9,t9,t4 // compute ending loop address
+
+//
+// Purge the primary instruction cache only.
+//
+
+20: cache HIT_INVALIDATE_I,0(t8) // invalidate cache block
+ bne t8,t9,20b // if ne, more blocks to invalidate
+ addu t8,t8,t4 // compute next block address
+ .set at
+ .set reorder
+
+30: ENABLE_INTERRUPTS(t5) // enable interrupts
+
+ j ra // return
+
+//
+// Purge the primary and secondary instruction caches.
+//
+
+ .set noreorder
+ .set noat
+40: cache HIT_INVALIDATE_SI,0(t8) // invalidate cache block
+ bne t8,t9,40b // if ne, more blocks to invalidate
+ addu t8,t8,t4 // compute next block address
+ .set at
+ .set reorder
+
+ ENABLE_INTERRUPTS(t5) // enable interrupts
+
+ j ra // return
+
+ .end HalPurgeIcachePage
+
+ SBTTL("Sweep Data Cache")
+//++
+//
+// VOID
+// HalSweepDcache (
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function sweeps (index/writeback/invalidate) the entire data cache.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalSweepDcache)
+
+#if DBG
+
+ lw t0,KeDcacheFlushCount // get address of dcache flush count
+ lw t1,0(t0) // increment the count of flushes
+ addu t1,t1,1 //
+ sw t1,0(t0) // store result
+
+#endif
+ DISABLE_INTERRUPTS(t5) // disable interrupts K002
+
+ lw t0,KiPcr + PcFirstLevelDcacheSize(zero) // get data cache size
+ lw t1,KiPcr + PcFirstLevelDcacheFillSize(zero) // get block size
+ li a0,KSEG0_BASE // set starting index value
+ addu a1,a0,t0 // compute ending cache address
+ subu a1,a1,t1 // compute ending block address
+
+
+//
+// Sweep the primary data cache.
+//
+
+ .set noreorder
+ .set noat
+//For T5
+ mfc0 t4,prid
+ nop
+ nop
+ nop
+ nop
+ and t4,t4,0xff00 // isolate processor id
+ xor t3,t4,0x900 // check if r10000 processor
+10: cache INDEX_WRITEBACK_INVALIDATE_D,0(a0) // writeback/invalidate on index
+ nop
+ nop
+ nop
+ nop
+ nop
+ bne zero,t3,12f // if ne, not r10000 processor
+ nop
+ cache INDEX_WRITEBACK_INVALIDATE_D,1(a0) // writeback/invalidate on index way 1 for t5
+ nop
+ nop
+ nop
+ nop
+ nop
+12:
+
+
+
+#if defined(_MIPS_R4600) //K001
+
+ nop // fill
+ cache INDEX_WRITEBACK_INVALIDATE_D,8192(a0) // writeback/invalidate on index
+
+#endif
+
+ bne a0,a1,10b // if ne, more to invalidate
+ addu a0,a0,t1 // compute address of next block
+ .set at
+ .set reorder
+
+ lw t0,KiPcr + PcSecondLevelDcacheSize(zero) // get data cache size
+ lw t1,KiPcr + PcSecondLevelDcacheFillSize(zero) // get block size
+ beq zero,t1,30f // if eq, no second level cache
+ li a0,KSEG0_BASE // set starting index value
+ addu a1,a0,t0 // compute ending cache address
+ subu a1,a1,t1 // compute ending block address
+
+//
+// Sweep the secondary data cache.
+//
+
+ .set noreorder
+ .set noat
+//For T5
+ mfc0 t4,prid
+ nop
+ nop
+ nop
+ nop
+ and t4,t4,0xff00 // isolate processor id
+ xor t3,t4,0x900 // check if r10000 processor
+20: cache INDEX_WRITEBACK_INVALIDATE_SD,0(a0) // writeback/invalidate on index
+ nop
+ nop
+ nop
+ nop
+ nop
+ bne zero,t3,22f // if ne, not r10000 processor
+ nop
+ cache INDEX_WRITEBACK_INVALIDATE_SD,1(a0) // writeback/invalidate on index way 1 for t5
+ nop
+ nop
+ nop
+ nop
+ nop
+22:
+ bne a0,a1,20b // if ne, more to invalidate
+ addu a0,a0,t1 // compute address of next block
+ .set at
+ .set reorder
+
+30:
+ ENABLE_INTERRUPTS(t5) // enable interrupts K002
+ j ra // return
+
+ .end HalSweepDcache
+
+ SBTTL("Sweep Data Cache Range")
+//++
+//
+// VOID
+// HalSweepDcacheRange (
+// IN PVOID BaseAddress,
+// IN ULONG Length
+// )
+//
+// Routine Description:
+//
+// This function sweeps (index/writeback/invalidate) the specified range
+// of virtual addresses from the primary data cache.
+//
+// Arguments:
+//
+// BaseAddress (a0) - Supplies the base address of the range that is swept
+// from the data cache.
+//
+// Length (a1) - Supplies the length of the range that is swept from the
+// data cache.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalSweepDcacheRange)
+
+#if DBG
+
+ lw t0,KeDcacheFlushCount // get address of dcache flush count
+ lw t1,0(t0) // increment the count of flushes
+ addu t1,t1,1 //
+ sw t1,0(t0) // store result conditionally
+
+#endif
+
+ DISABLE_INTERRUPTS(t5) // disable interrupts K002
+
+ and a0,a0,COLOR_MASK // isolate color and offset bits
+ or a0,a0,KSEG0_BASE // convert to physical address
+ lw t0,KiPcr + PcFirstLevelDcacheFillSize(zero) // get block size
+ addu a1,a0,a1 // compute ending cache address
+ subu a1,a1,t0 // compute ending block address
+
+//
+// Sweep the primary data cache.
+//
+
+ .set noreorder
+ .set noat
+//For T5
+ mfc0 t4,prid
+ nop
+ nop
+ nop
+ nop
+ and t4,t4,0xff00 // isolate processor id
+ xor t3,t4,0x900 // check if r10000 processor
+10: cache INDEX_WRITEBACK_INVALIDATE_D,0(a0) // writeback/invalidate on index
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ bne zero,t3,12f // if ne, not r10000 processor
+ nop
+ cache INDEX_WRITEBACK_INVALIDATE_D,1(a0) // writeback/invalidate on index way 1 for t5
+ nop
+ nop
+ nop
+ nop
+ nop
+12:
+#if defined(_MIPS_R4600)
+
+ nop // fill
+ cache INDEX_WRITEBACK_INVALIDATE_D,8192(a0) // writeback/invalidate on index
+
+#endif
+
+ bne a0,a1,10b // if ne, more to invalidate
+ addu a0,a0,t0 // compute address of next block
+ .set at
+ .set reorder
+
+ ENABLE_INTERRUPTS(t5) // enable interrupts K002
+
+ j ra // return
+
+ .end HalSweepDcacheRange
+
+ SBTTL("Sweep Instruction Cache")
+//++
+//
+// VOID
+// HalSweepIcache (
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function sweeps (index/invalidate) the entire instruction cache.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalSweepIcache)
+
+#if DBG
+
+ lw t0,KeIcacheFlushCount // get address of icache flush count
+ lw t1,0(t0) // increment the count of flushes
+ addu t1,t1,1 //
+ sw t1,0(t0) // store result
+
+#endif
+
+ lw t0,KiPcr + PcSecondLevelIcacheSize(zero) // get instruction cache size
+ lw t1,KiPcr + PcSecondLevelIcacheFillSize(zero) // get fill size
+ beq zero,t1,20f // if eq, no second level cache
+ li a0,KSEG0_BASE // set starting index value
+ addu a1,a0,t0 // compute ending cache address
+ subu a1,a1,t1 // compute ending block address
+
+//
+// Sweep the secondary instruction cache.
+//
+
+ .set noreorder
+ .set noat
+//For T5
+ mfc0 t4,prid
+ nop
+ nop
+ nop
+ nop
+ and t4,t4,0xff00 // isolate processor id
+ xor t3,t4,0x900 // check if r10000 processor
+10: cache INDEX_INVALIDATE_SI,0(a0) // invalidate cache line
+ nop
+ nop
+ nop
+ nop
+ nop
+ bne zero,t3,12f // if ne, not r10000 processor
+ nop
+ cache INDEX_INVALIDATE_SI,1(a0) // invalidate on index way 1 for t5
+ nop
+ nop
+ nop
+ nop
+ nop
+12:
+ bne a0,a1,10b // if ne, more to invalidate
+ addu a0,a0,t1 // compute address of next block
+ .set at
+ .set reorder
+
+20: lw t0,KiPcr + PcFirstLevelIcacheSize(zero) // get instruction cache size
+ lw t1,KiPcr + PcFirstLevelIcacheFillSize(zero) // get fill size
+ li a0,KSEG0_BASE // set starting index value
+ addu a1,a0,t0 // compute ending cache address
+ subu a1,a1,t1 // compute ending block address
+
+//
+// Sweep the primary instruction cache.
+//
+
+#if defined(_MIPS_R4600)
+
+ DISABLE_INTERRUPTS(t0) // disable interrupts
+
+#endif
+
+ .set noreorder
+ .set noat
+//For T5
+ mfc0 t4,prid
+ nop
+ nop
+ nop
+ nop
+ and t4,t4,0xff00 // isolate processor id
+ xor t3,t4,0x900 // check if r10000 processor
+30: cache INDEX_INVALIDATE_I,0(a0) // invalidate cache line
+ nop
+ nop
+ nop
+ nop
+ nop
+ bne zero,t3,32f // if ne, not r10000 processor
+ nop
+ cache INDEX_INVALIDATE_I,1(a0) // invalidate on index way 1 for t5
+ nop
+ nop
+ nop
+ nop
+ nop
+32:
+
+#if defined(_MIPS_R4600) //K001
+
+ nop // fill
+ cache INDEX_INVALIDATE_I,8192(a0) // writeback/invalidate on index
+
+#endif
+
+ bne a0,a1,30b // if ne, more to invalidate
+ addu a0,a0,t1 // compute address of next block
+ .set at
+ .set reorder
+
+#if defined(_MIPS_R4600)
+
+ ENABLE_INTERRUPTS(t0) // enable interrupts
+
+#endif
+
+ j ra // return
+
+ .end HalSweepIcache
+
+ SBTTL("Sweep Instruction Cache Range")
+//++
+//
+// VOID
+// HalSweepIcacheRange (
+// IN PVOID BaseAddress,
+// IN ULONG Length
+// )
+//
+// Routine Description:
+//
+// This function sweeps (index/invalidate) the specified range of addresses
+// from the instruction cache.
+//
+// Arguments:
+//
+// BaseAddress (a0) - Supplies the base address of the range that is swept
+// from the instruction cache.
+//
+// Length (a1) - Supplies the length of the range that is swept from the
+// instruction cache.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalSweepIcacheRange)
+
+#if DBG
+
+ lw t0,KeIcacheFlushCount // get address of icache flush count
+ lw t1,0(t0) // increment the count of flushes
+ addu t1,t1,1 //
+ sw t1,0(t0) // store result
+
+#endif
+
+ and a0,a0,COLOR_MASK // isolate color and offset bits
+ or a0,a0,KSEG0_BASE // convert to physical address
+ lw t0,KiPcr + PcFirstLevelIcacheFillSize(zero) // get fill size
+ addu a1,a0,a1 // compute ending cache address
+ subu a1,a1,t0 // compute ending block address
+
+//
+// Sweep the primary instruction cache.
+//
+
+#if defined(_MIPS_R4600)
+
+ DISABLE_INTERRUPTS(t1) // disable interrupts
+
+#endif
+
+ .set noreorder
+ .set noat
+//For T5
+ mfc0 t4,prid
+ nop
+ nop
+ nop
+ nop
+ and t4,t4,0xff00 // isolate processor id
+ xor t3,t4,0x900 // check if r10000 processor
+10: cache INDEX_INVALIDATE_I,0(a0) // invalidate cache line
+ nop
+ nop
+ nop
+ nop
+ nop
+ bne zero,t3,12f // if ne, not r10000 processor
+ nop
+ cache INDEX_INVALIDATE_I,1(a0) // invalidate on index way 1 for t5
+ nop
+ nop
+ nop
+ nop
+ nop
+12:
+
+#if defined(_MIPS_R4600)
+
+ nop // fill
+ cache INDEX_INVALIDATE_I,8192(a0) // writeback/invalidate on index
+
+#endif
+
+ bne a0,a1,10b // if ne, more to invalidate
+ addu a0,a0,t0 // compute address of next block
+ .set at
+ .set reorder
+
+#if defined(_MIPS_R4600)
+
+ ENABLE_INTERRUPTS(t1) // enable interrupts
+
+#endif
+
+ j ra // return
+
+ .end HalSweepIcacheRange
+
+ SBTTL("Zero Page")
+//++
+//
+// VOID
+// HalZeroPage (
+// IN PVOID NewColor,
+// IN PVOID OldColor,
+// IN ULONG PageFrame
+// )
+//
+// Routine Description:
+//
+// This function zeros a page of memory.
+//
+// The algorithm used to zero a page is as follows:
+//
+// 1. Purge (hit/invalidate) the page from the instruction cache
+// using the old color iff the old color is not the same as
+// the new color.
+//
+// 2. Purge (hit/invalidate) the page from the data cache using
+// the old color iff the old color is not the same as the new
+// color.
+//
+// 3. Create (create/dirty/exclusive) the page in the data cache
+// using the new color.
+//
+// 4. Write zeros to the page using the new color.
+//
+// Arguments:
+//
+// NewColor (a0) - Supplies the page aligned virtual address of the
+// new color of the page that is zeroed.
+//
+// OldColor (a1) - Supplies the page aligned virtual address of the
+// old color of the page that is zeroed.
+//
+// PageFrame (a2) - Supplies the page frame number of the page that
+// is zeroed.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ .struct 0
+ .space 3 * 4 // fill
+ZpRa: .space 4 // saved return address
+ZpFrameLength: // length of stack frame
+ZpA0: .space 4 // (a0)
+ZpA1: .space 4 // (a1)
+ZpA2: .space 4 // (a2)
+ZpA3: .space 4 // (a3)
+
+ NESTED_ENTRY(HalZeroPage, ZpFrameLength, zero)
+
+ subu sp,sp,ZpFrameLength // allocate stack frame
+ sw ra,ZpRa(sp) // save return address
+
+ PROLOGUE_END
+
+ and a0,a0,COLOR_BITS // isolate new color bits
+ and a1,a1,COLOR_BITS // isolate old color bits
+ sw a0,ZpA0(sp) // save new color bits
+ sw a2,ZpA2(sp) // save page frame
+
+//
+// If the old page color is not equal to the new page color, then change
+// the color of the page.
+//
+
+ beq a0,a1,10f // if eq, colors match
+ jal KeChangeColorPage // chagne page color
+
+//
+// Create dirty exclusive cache blocks and zero the data.
+//
+
+10: lw a3,ZpA0(sp) // get new color bits
+ lw a1,ZpA2(sp) // get page frame number
+
+ .set noreorder
+ .set noat
+ lw v0,KiPcr + PcAlignedCachePolicy(zero) // get cache polciy
+ li t0,FLUSH_BASE // get base flush address
+ or t0,t0,a3 // compute new color virtual address
+ sll t1,a1,ENTRYLO_PFN // shift page frame into position
+ or t1,t1,PROTECTION_BITS // merge protection bits
+ or t1,t1,v0 // merge cache policy
+ and a3,a3,0x1000 // isolate TB entry index
+ beql zero,a3,20f // if eq, first entry
+ move t2,zero // set second page table entry
+ move t2,t1 // set second page table entry
+ move t1,zero // set first page table entry
+20: mfc0 t3,wired // get TB entry index
+ lw t4,KiPcr + PcFirstLevelDcacheFillSize(zero) // get 1st fill size
+ lw v0,KiPcr + PcSecondLevelDcacheFillSize(zero) // get 2nd fill size
+ .set at
+ .set reorder
+
+ DISABLE_INTERRUPTS(t5) // disable interrupts
+
+ .set noreorder
+ .set noat
+ mfc0 t6,entryhi // get current PID and VPN2
+ srl t7,t0,ENTRYHI_VPN2 // isolate VPN2 of virtual address
+ sll t7,t7,ENTRYHI_VPN2 //
+ and t6,t6,0xff << ENTRYHI_PID // isolate current PID
+ or t7,t7,t6 // merge PID with VPN2 of virtual address
+ mtc0 t7,entryhi // set VPN2 and PID for probe
+ mtc0 t1,entrylo0 // set first PTE value
+ mtc0 t2,entrylo1 // set second PTE value
+ mtc0 t3,index // set TB index value
+ nop // fill
+ tlbwi // write TB entry - 3 cycle hazzard
+ addu t9,t0,PAGE_SIZE // compute ending address of block
+ dmtc1 zero,f0 // set write pattern
+ bne zero,v0,50f // if ne, second level cache present
+ and t8,t4,0x10 // test if 16-byte cache block
+
+//
+// Zero page in primary data cache only.
+//
+
+#if defined(_DUO_)
+
+30: sdc1 f0,0(t0) // zero 64-byte block
+ sdc1 f0,8(t0) //
+ sdc1 f0,16(t0) //
+ sdc1 f0,24(t0) //
+ sdc1 f0,32(t0) //
+ sdc1 f0,40(t0) //
+ sdc1 f0,48(t0) //
+ addu t0,t0,64 // advance to next 64-byte block
+ bne t0,t9,30b // if ne, more to zero
+ sdc1 f0,-8(t0) //
+
+#else
+
+30: cache CREATE_DIRTY_EXCLUSIVE_D,0(t0) // create cache block
+ addu t0,t0,t4 // compute next block address
+ bne zero,t8,40f // if ne, 16-byte cache line
+ sdc1 f0,-16(t0) //
+ sdc1 f0,-24(t0) // zero 16 bytes
+ sdc1 f0,-32(t0) //
+40: bne t0,t9,30b // if ne, more blocks to zero
+ sdc1 f0,-8(t0) // zero 16 bytes
+
+#endif
+
+ .set at
+ .set reorder
+
+ ENABLE_INTERRUPTS(t5) // enable interrupts
+
+ lw ra,ZpRa(sp) // get return address
+ addu sp,sp,ZpFrameLength // deallocate stack frame
+ j ra // return
+
+//
+// Zero page in primary and secondary data caches.
+//
+
+ .set noreorder
+ .set noat
+
+#if defined(_DUO_)
+
+50: sdc1 f0,0(t0) // zero 64-byte block
+ sdc1 f0,8(t0) //
+ sdc1 f0,16(t0) //
+ sdc1 f0,24(t0) //
+ sdc1 f0,32(t0) //
+ sdc1 f0,40(t0) //
+ sdc1 f0,48(t0) //
+ addu t0,t0,64 // advance to next 64-byte block
+ bne t0,t9,50b // if ne, more to zero
+ sdc1 f0,-8(t0) //
+
+#else
+
+50: cache CREATE_DIRTY_EXCLUSIVE_SD,0(t0) // create secondary cache block
+ addu v1,v0,t0 // compute ending primary block address
+60: addu t0,t0,t4 // compute next block address
+ bne zero,t8,70f // if ne, 16-byte primary cache line
+ sdc1 f0,-16(t0) //
+ sdc1 f0,-24(t0) // zero 16 bytes
+ sdc1 f0,-32(t0) //
+70: bne t0,v1,60b // if ne, more primary blocks to zero
+ sdc1 f0,-8(t0) // zero 16 bytes
+ bne t0,t9,50b // if ne, more secondary blocks to zero
+ nop // fill
+
+#endif
+
+ .set at
+ .set reorder
+
+ ENABLE_INTERRUPTS(t5) // enable interrupts
+
+ lw ra,ZpRa(sp) // get return address
+ addu sp,sp,ZpFrameLength // deallocate stack frame
+ j ra // return
+
+ .end HalZeroPage
diff --git a/private/ntos/nthals/halr98b/mips/j4flshbf.s b/private/ntos/nthals/halr98b/mips/j4flshbf.s
new file mode 100644
index 000000000..b9a1cda9b
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/j4flshbf.s
@@ -0,0 +1,58 @@
+// "@(#) NEC j4flshbf.s 1.2 94/10/17 11:11:16"
+#if defined(R4000)
+
+// TITLE("Miscellaneous Kernel Functions")
+//++
+//
+// Copyright (c) 1991-1994 Microsoft Corporation
+//
+// Module Name:
+//
+// j3flshbf.s
+//
+// Abstract:
+//
+// This module implements the system dependent kernel function to flush
+// the write buffer or otherwise synchronize writes on a MIPS R4000 Jazz
+// system.
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+//--
+
+#include "halmips.h"
+
+ SBTTL("Flush Write Buffer")
+//++
+//
+// NTSTATUS
+// KeFlushWriteBuffer (
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function flushes the write buffer on the current processor.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(KeFlushWriteBuffer)
+
+ sync // synchronize writes
+ j ra // return
+
+ .end KeFlushWritebuffer
+
+#endif
diff --git a/private/ntos/nthals/halr98b/mips/j4flshio.c b/private/ntos/nthals/halr98b/mips/j4flshio.c
new file mode 100644
index 000000000..868141c2a
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/j4flshio.c
@@ -0,0 +1,212 @@
+/*++
+
+Copyright (c) 1991-1994 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.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#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;
+
+ //
+ // R98 I/O Cache Supported So Nothing to Do Dma Operation!!.
+ //
+ if (DmaOperation == TRUE){
+ return;
+ }
+
+
+ //
+ // 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/halr98b/mips/j4prof.c b/private/ntos/nthals/halr98b/mips/j4prof.c
new file mode 100644
index 000000000..7fdd27e98
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/j4prof.c
@@ -0,0 +1,340 @@
+
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ j4prof.c
+
+Abstract:
+
+ This module contains the code to start and stop the profiling interrupt
+ and to compute the profiling interval for a MIPS R98B system.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+
+//
+// Define one second and round values.
+//
+
+#define ONE_SECOND (10 * 1000 * 1000) // 1 second in 100ns units
+#define ROUND_VALUE ((ONE_SECOND) - 1) // 1 second minus 100ns
+
+//
+// Define static data.
+//
+
+LARGE_INTEGER HalpPerformanceCounter[8];
+
+ULONG HalpProfileInterval = DEFAULT_PROFILETIMER_INTERVAL;
+
+
+LARGE_INTEGER
+KeQueryPerformanceCounter (
+ OUT PLARGE_INTEGER Frequency OPTIONAL
+ )
+
+/*++
+
+Routine Description:
+
+ This routine returns the current performance counter value and the
+ performance counter frequency.
+
+Arguments:
+
+ Frequency - Supplies an optional pointer to a variable which receives
+ the performance counter frequency in Hertz.
+
+Return Value:
+
+ The current performance counter value is returned as the function
+ value.
+
+--*/
+
+{
+
+ ULONG CurrentCount;
+ KIRQL OldIrql;
+ LARGE_INTEGER PerformanceCounter;
+
+ //
+ // Raise IRQL to PROFILE_LEVEL, read the current value of the count
+ // register, read the performance counter, and lower IRQL to its
+ // previous value.
+ //
+ // N.B. The minimum, maximum, and default values for the profile
+ // count are chosen such that count register only overflows
+ // after about 20 seconds at 50mhz. Therefore, there is never
+ // a problem with the counter wrapping in the following code.
+ //
+
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ CurrentCount = HalpReadCountRegister();
+ PerformanceCounter = HalpPerformanceCounter[KeGetCurrentPrcb()->Number];
+ KeLowerIrql(OldIrql);
+
+ //
+ // If the frequency parameter is specified, then return the performance
+ // counter frequency as the current system time frequency.
+ //
+
+ if (ARGUMENT_PRESENT(Frequency) != FALSE) {
+ *Frequency = RtlConvertUlongToLargeInteger(HalpProfileCountRate);
+ }
+
+ //
+ // Return the value of the performance counter.
+ //
+
+ return RtlLargeIntegerAdd(PerformanceCounter,
+ RtlConvertUlongToLargeInteger(CurrentCount));
+}
+
+VOID
+HalCalibratePerformanceCounter (
+ IN volatile PLONG Number
+ )
+
+/*++
+
+Routine Description:
+
+ This routine resets the performance counter value for the current
+ processor to zero. The reset is done such that the resulting value
+ is closely synchronized with other processors in the configuration.
+
+Arguments:
+
+ Number - Supplies a pointer to count of the number of processors in
+ the configuration.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ KSPIN_LOCK Lock;
+ KIRQL OldIrql;
+ PKPRCB Prcb;
+
+ //
+ // Raise IRQL to HIGH_LEVEL, decrement the number of processors, and
+ // wait until the number is zero.
+ //
+
+ KeInitializeSpinLock(&Lock);
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ if (ExInterlockedDecrementLong(Number, &Lock) != RESULT_ZERO) {
+ do {
+ } while (*Number !=0);
+ }
+
+ //
+ // Write the compare register, clear the count register, and zero the
+ // performance counter for the current processor.
+ //
+
+ HalpWriteCompareRegisterAndClear(DEFAULT_PROFILETIMER_COUNT);
+
+ WRITE_REGISTER_ULONG( &(COLUMNBS_LCNTL)->TMSR2.Long,
+ DEFAULT_PROFILETIMER_COUNT);
+
+
+ Prcb = KeGetCurrentPrcb();
+ HalpPerformanceCounter[Prcb->Number].LowPart = 0;
+ HalpPerformanceCounter[Prcb->Number].HighPart = 0;
+
+ WRITE_REGISTER_ULONG( &(COLUMNBS_LCNTL)->TMCR2.Long, 0x3);
+
+
+ //
+ // Restore IRQL to its previous value and return.
+ //
+
+ KeLowerIrql(OldIrql);
+ return;
+}
+
+ULONG
+HalSetProfileInterval (
+ IN ULONG Interval
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets the profile interrupt interval.
+
+Arguments:
+
+ Interval - Supplies the desired profile interval in 100ns units.
+
+Return Value:
+
+ The actual profile interval.
+
+--*/
+
+{
+
+
+
+ //
+ // If the specified profile interval is less that the minimum profile
+ // interval or greater than the maximum profile interval, then set the
+ // profile interval to the minimum or maximum as appropriate.
+ //
+
+
+ if (Interval < MINIMUM_PROFILETIMER_INTERVAL) {
+ Interval = MINIMUM_PROFILETIMER_INTERVAL;
+
+ } else if (Interval > MAXIMUM_PROFILETIMER_INTERVAL) {
+ Interval = MAXIMUM_PROFILETIMER_INTERVAL;
+ }
+
+ HalpProfileInterval = Interval;
+
+
+ return HalpProfileInterval;
+}
+
+VOID
+HalStartProfileInterrupt (
+ KPROFILE_SOURCE Reserved
+ )
+
+/*++
+
+Routine Description:
+
+ This routine computes the profile count value, writes the compare
+ register, clears the count register, and updates the performance
+ counter.
+
+ N.B. This routine must be called at PROFILE_LEVEL while holding the
+ profile lock.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PKPRCB Prcb;
+ ULONG PreviousCount;
+
+ ULONG TempValue;
+
+
+ //
+ // Compute the profile count from the current profile interval.
+ //
+
+ // The R98A/B machines use the External Interrupt for
+ // the profile and clock interrupt. The hardware requires the
+ // value decremented by 1
+
+ TempValue = HalpProfileInterval * COLUMBUS_CLOCK_FREQUENCY / 1000 / 10 - 1;
+
+ //
+ // Write the compare register and clear the count register.
+ //
+ // SR2 - Columbus chip Internal Countdown register. The Columbus
+ // chip decrements this register every Columbus cycle (COLUMBUS_CLOCK_FREQUENCY).
+ // When the value is zero it signals the External Interrupt
+ // CR2 - Columbus chip clock control register. This enables countdown register
+ // and external interrupts.
+ PreviousCount = HalpWriteCompareRegisterAndClear(TempValue);
+ WRITE_REGISTER_ULONG( &(COLUMNBS_LCNTL)->TMSR2.Long, TempValue);
+ WRITE_REGISTER_ULONG( &(COLUMNBS_LCNTL)->TMCR2.Long, 0x3);
+
+
+ //
+ // Update the performance counter by adding in the previous count value.
+ //
+
+ Prcb = KeGetCurrentPrcb();
+ HalpPerformanceCounter[Prcb->Number] =
+ RtlLargeIntegerAdd(HalpPerformanceCounter[Prcb->Number],
+ RtlConvertUlongToLargeInteger(PreviousCount));
+
+ return;
+}
+
+VOID
+HalStopProfileInterrupt (
+ KPROFILE_SOURCE Reserved
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets the default count value, writes the compare
+ register, clears the count register, and updates the performance
+ counter.
+
+ N.B. This routine must be called at PROFILE_LEVEL while holding the
+ profile lock.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PKPRCB Prcb;
+ ULONG PreviousCount;
+
+ //
+ // Write the compare register and clear the count register.
+ //
+ // Columbus hardware specifies SET VALUE AS VALUE MINUS ONE
+ PreviousCount = HalpWriteCompareRegisterAndClear(DEFAULT_PROFILETIMER_COUNT-1);
+
+ WRITE_REGISTER_ULONG( &(COLUMNBS_LCNTL)->TMSR2.Long,
+ DEFAULT_PROFILETIMER_COUNT-1);
+ WRITE_REGISTER_ULONG( &(COLUMNBS_LCNTL)->TMCR2.Long, 0x3);
+
+
+ //
+ // Update the performance counter by adding in the previous count value.
+ //
+
+ Prcb = KeGetCurrentPrcb();
+ HalpPerformanceCounter[Prcb->Number] =
+ RtlLargeIntegerAdd(HalpPerformanceCounter[Prcb->Number],
+ RtlConvertUlongToLargeInteger(PreviousCount));
+
+ return;
+}
diff --git a/private/ntos/nthals/halr98b/mips/jxbeep.c b/private/ntos/nthals/halr98b/mips/jxbeep.c
new file mode 100644
index 000000000..d39405c78
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxbeep.c
@@ -0,0 +1,131 @@
+#ident "@(#) NEC jxbeep.c 1.2 94/10/17 11:22:04"
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxbeep.c
+
+Abstract:
+
+ This module implements the HAL speaker "beep" routines for a MIPS
+ system.
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+#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;
+ NMI_STATUS NmiStatus;
+ 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.
+ //
+
+ *((PUCHAR)&NmiStatus) = READ_REGISTER_UCHAR(&controlBase->NmiStatus);
+ NmiStatus.SpeakerGate = 0;
+ NmiStatus.SpeakerData = 0;
+ WRITE_REGISTER_UCHAR(&controlBase->NmiStatus, *((PUCHAR)&NmiStatus));
+
+ //
+ // 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 {
+
+ //
+ // 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));
+
+ //
+ // Set the speaker timer to the correct mode.
+ //
+
+ WRITE_REGISTER_UCHAR(&controlBase->SpeakerTone, (UCHAR)(newCount & 0xff));
+ WRITE_REGISTER_UCHAR(&controlBase->SpeakerTone, (UCHAR)(newCount >> 8));
+
+ //
+ // Start the speaker.
+ //
+
+ NmiStatus.SpeakerGate = 1;
+ NmiStatus.SpeakerData = 1;
+ WRITE_REGISTER_UCHAR(&controlBase->NmiStatus, *((PUCHAR) &NmiStatus));
+ Result = TRUE;
+ }
+ }
+
+ //
+ // Release the beep spin lock and lower IRQL to its previous value.
+ //
+
+ KeReleaseSpinLock(&HalpBeepLock, OldIrql);
+ return Result;
+}
diff --git a/private/ntos/nthals/halr98b/mips/jxdisp.c b/private/ntos/nthals/halr98b/mips/jxdisp.c
new file mode 100644
index 000000000..03b9d0c7e
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxdisp.c
@@ -0,0 +1,3544 @@
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxdisp.c
+
+Abstract:
+
+ This module implements the HAL display initialization and output routines
+ for a MIPS R4000 or R10000 R98x system.
+
+History:
+
+--*/
+
+/*
+ * NEW CODE for R98B
+ * 1995/09/11 K.Kitagaki
+ *
+ * S001 1995/11/10 T.Samezima
+ * add x86 bios and GLiNT logic
+ *
+ */
+
+#include "halp.h"
+#include "jazzvdeo.h"
+#include "jzvxl484.h"
+#include <jaginit.h>
+#include "cirrus.h"
+#include "modeset.h"
+#include "mode542x.h"
+#include "string.h"
+#include <tga.h>
+#include <glint.h> // S001
+#include <rgb525.h> // S001
+
+#include "pci.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, HalpInitializeDisplay0)
+#pragma alloc_text(INIT, HalpInitializeDisplay1)
+
+#endif
+
+// S001 vvv
+#define _GLINT60HZ_
+
+#if defined(R96DBG)
+#define DispDbgPrint(STRING) \
+ DbgPrint STRING;
+#else
+#define DispDbgPrint(STRING)
+#endif
+
+//
+// for x86bios emulate
+//
+PCHAR K351UseBios=NULL;
+
+PHAL_RESET_DISPLAY_PARAMETERS HalpResetDisplayParameters;
+
+#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
+ );
+
+VOID
+HalpDisplayCharacterOld (
+ IN UCHAR Character
+ );
+
+VOID
+HalpOutputCharacterOld (
+ IN PUCHAR Glyph
+ );
+// S001 ^^^
+
+VOID
+HalpDisplayCirrusSetup (
+ VOID
+ );
+
+BOOLEAN
+HalpCirrusInterpretCmdStream (
+ PUSHORT pusCmdStream
+ );
+
+VOID
+HalpDisplayTgaSetup(
+ VOID
+ );
+
+VOID
+Write_Dbg_Uchar(
+ PUCHAR,
+ UCHAR
+ );
+
+// S001 vvv
+#if 0
+VOID
+RGB525_WRITE(
+ ULONG dac,
+ ULONG offset,
+ UCHAR data );
+
+VOID
+RGB525_SET_REG(
+ ULONG dac,
+ ULONG index,
+ UCHAR data );
+#endif
+
+VOID
+HalpDisplayGlintSetup(
+ VOID
+ );
+// S001 ^^^
+
+//
+// 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)(0x1c403000 | KSEG1_BASE))
+#define CIRRUS_OFFSET ((PUSHORT)0x3b0)
+#define PCI_0_IO_BASE 0x1c000000 // S001
+#define PCI_1_IO_BASE 0x1c400000
+#define CIRRUS_CONTROL_BASE_OFFSET 0x3000
+#define CIRRUS_MEMORY_BASE_LOW 0xa0000000
+
+#define KSEG1_BASE 0xa0000000
+
+#define TGA_REGISTER_BASE ((ULONG)0x403ff000)
+#define PONCE_ADDR_REG ((PULONG)(0x1a000008 | KSEG1_BASE))
+#define PONCE_DATA_REG ((PULONG)(0x1a000010 | KSEG1_BASE))
+#define PONCE_PERRM ((PULONG)(0x1a000810 | KSEG1_BASE))
+#define PONCE_PAERR ((PULONG)(0x1a000800 | KSEG1_BASE))
+#define PONCE_PERST ((PULONG)(0x1a000820 | KSEG1_BASE))
+
+// S001 vvv
+#define GLINT_CONTROL_REGISTER_BASE ((ULONG)0x403ff000)
+#define GLINT_VIDEO_REGISTER_BASE ((ULONG)0x403fe000)
+#define RGB525_REGISTER_BASE ((ULONG)0x403fd000)
+
+//
+// Define controller setup routine type.
+//
+
+typedef
+VOID
+(*PHALP_CONTROLLER_SETUP) (
+ VOID
+ );
+
+typedef
+VOID
+(*PHALP_DISPLAY_CHARACTER) (
+ UCHAR
+ );
+
+typedef
+VOID
+(*PHALP_SCROLL_SCREEN) (
+ UCHAR
+ );
+
+PHALP_DISPLAY_CHARACTER HalpDisplayCharacter = NULL;
+// S001 ^^^
+
+//
+// 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; // S001
+
+//
+// Define display variables.
+//
+
+BOOLEAN HalpDisplayOwnedByHal;
+ENTRYLO HalpDisplayPte;
+ULONG HalpDisplayControlBase = 0;
+ULONG HalpDisplayMemoryBase = 0;
+ULONG HalpDisplayResetRegisterBase = 0;
+PHALP_CONTROLLER_SETUP HalpDisplayControllerSetup = NULL;
+MONITOR_CONFIGURATION_DATA HalpMonitorConfigurationData;
+BOOLEAN HalpDisplayTypeUnknown = FALSE;
+ULONG HalpDisplayPCIDevice = FALSE;
+
+LARGE_INTEGER HalpCirrusPhigicalVideo = {0,0};
+LARGE_INTEGER HalpTgaPhigicalVideo = {0,0};
+LARGE_INTEGER HalpTgaPhigicalVideoCont = {0,0};
+// S001 vvv
+LARGE_INTEGER HalpGlintPhygicalVideo = {0,0};
+LARGE_INTEGER HalpGlintPhygicalVideoCont = {0,0};
+ULONG HalpDisplayType16BPP = FALSE;
+// S001 ^^^
+
+
+ULONG HalpCirrusAlive=FALSE;
+
+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;
+
+BOOLEAN
+HalpCheckPCIDevice (
+ IN PCI_SLOT_NUMBER Slot
+ );
+
+volatile PULONG HalpPonceConfigAddrReg = PONCE_ADDR_REG;
+volatile PULONG HalpPonceConfigDataReg = PONCE_DATA_REG;
+volatile PULONG HalpPoncePerrm = PONCE_PERRM;
+volatile PULONG HalpPoncePaerr = PONCE_PAERR;
+volatile PULONG HalpPoncePerst = PONCE_PERST;
+
+// S001 vvv
+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 PUSHORT Buffer,
+ IN ULONG Offset
+ );
+
+VOID
+HalpWritePCIConfigUshortByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUSHORT Buffer,
+ IN ULONG Offset
+ );
+
+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
+ );
+// S001 ^^^
+
+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++;
+ }
+ }
+}
+
+
+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;
+
+ HalpPonceConfigAddrReg = PONCE_ADDR_REG;
+ HalpPonceConfigDataReg = PONCE_DATA_REG;
+ HalpPoncePerrm = PONCE_PERRM;
+ HalpPoncePaerr = PONCE_PAERR;
+ HalpPoncePerst = PONCE_PERST;
+
+ //
+ // 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;
+
+ //
+ // Find the configuration entry for the first display controller.
+ //
+
+ DispDbgPrint(("Hal: HalpInitializeDisplay0\n")); // S001
+
+ MatchKey = 0;
+ ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
+ ControllerClass,
+ DisplayController,
+ &MatchKey);
+
+ DispDbgPrint(("Hal: ConfigurationEntry Found\n")); // S001
+
+ 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.
+ //
+
+ // S001 vvv
+ if (LoaderBlock->LoadOptions != NULL) {
+ Options = LoaderBlock->LoadOptions;
+ //
+ // Why link error occure?
+ // So, I change.
+ // v-masank@microsoft.com
+ // 5/21/96
+ //
+ //strupr(Options);
+ K351UseBios = strstr(Options, "USEBIOS");
+ }
+ if(K351UseBios!=NULL){
+ DispDbgPrint(("HAL: Use X86BIOS emulation\n"));
+
+ HalpDisplayControllerSetup = HalpDisplayINT10Setup;
+ HalpDisplayCharacter = HalpDisplayCharacterVGA;
+ HalpDisplayControlBase = PCI_0_IO_BASE;
+ }else
+ // S001 ^^^
+ if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
+ "necvdfrb")) {
+ DispDbgPrint(("necvdfrb Config found\n"));
+
+ HalpDisplayControllerSetup = HalpDisplayCirrusSetup;
+ HalpCirrusAlive =TRUE;
+ HalpDisplayCharacter = HalpDisplayCharacterOld; // S001
+ HalpDisplayControlBase = PCI_1_IO_BASE + CIRRUS_CONTROL_BASE_OFFSET;
+ HalpDisplayMemoryBase = CIRRUS_MEMORY_BASE_LOW;
+ HalpDisplayPCIDevice = TRUE;
+
+ } else if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,"10110004")) {
+ //
+ // for DEC21030 PCI
+ //
+ DispDbgPrint(("DEC G/A found\n"));
+
+ HalpDisplayControllerSetup = HalpDisplayTgaSetup;
+ HalpDisplayCharacter = HalpDisplayCharacterOld; // S001
+ HalpDisplayPCIDevice = TRUE;
+
+ Slot.u.bits.FunctionNumber = 0;
+
+ for (Slot.u.bits.DeviceNumber = 1; Slot.u.bits.DeviceNumber < 6; Slot.u.bits.DeviceNumber++){
+ DispDbgPrint(("DEC G/A found 2vvvv\n"));
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+#if defined (DBG7)
+ DbgPrint("DEVICE-VENDER=0x%x\n",ReadValue);
+#endif
+ DispDbgPrint(("DEC G/A found 200\n"));
+
+ if (ReadValue == 0x00041011){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
+
+#if defined (DBG7)
+ DbgPrint("PCI-COMMAND=0x%x\n",ReadValue);
+#endif
+
+ if ((ReadValue & 0x00000002) == 0x2){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+#if defined (DBG7)
+ DbgPrint("DISPLAY-MEMORY-BASE=0x%x\n",ReadValue);
+#endif
+ HalpDisplayControlBase =
+ (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
+ HalpDisplayControlBase |= 0x40000000;
+#if defined (DBG7)
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x14);
+ DbgPrint("DISPLAY-IO-BASE=0x%x\n",ReadValue);
+ DbgPrint("DEC G/A HalpDisplayControlBase=0x%x\n",HalpDisplayControlBase);
+#endif
+ DispDbgPrint(("DEC G/A found 2\n"));
+
+ } else {
+
+ DispDbgPrint(("DEC G/A found 2-1\n"));
+
+ return FALSE;
+ }
+ }
+ }
+
+ DispDbgPrint(("DEC G/A found 3-0\n"));
+
+ if (HalpNumberOfPonce == 2){
+
+ DispDbgPrint(("DEC G/A found 3\n"));
+
+ HalpPonceConfigAddrReg += 0x400;
+ HalpPonceConfigDataReg += 0x400;
+ HalpPoncePerrm += 0x400;
+ HalpPoncePaerr += 0x400;
+ HalpPoncePerst += 0x400;
+
+ for (Slot.u.bits.DeviceNumber = 5; Slot.u.bits.DeviceNumber < 7; Slot.u.bits.DeviceNumber++){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+#if defined (DBG7)
+ DbgPrint("DEVICE-VENDER=0x%x\n",ReadValue);
+#endif
+
+ if (ReadValue == 0x00041011){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
+
+#if defined (DBG7)
+ DbgPrint("PCI-COMMAND=0x%x\n",ReadValue);
+#endif
+
+ if ((ReadValue & 0x00000002) == 0x2){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+#if defined (DBG7)
+ DbgPrint("DISPLAY-MEMORY-BASE=0x%x\n",ReadValue);
+#endif
+ HalpDisplayControlBase =
+ (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
+ HalpDisplayControlBase |= 0x80000000;
+
+#if defined (DBG7)
+ DbgPrint("DEC G/A HalpDisplayControlBase=0x%x\n",HalpDisplayControlBase);
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x14);
+ DbgPrint("DISPLAY-IO-BASE=0x%x\n",ReadValue);
+#endif
+
+ DispDbgPrint(("DEC G/A found 4\n"));
+
+ } else {
+
+ DispDbgPrint(("DEC G/A found 4-1\n"));
+
+ return FALSE;
+ }
+ }
+ }
+ } else {
+
+ DispDbgPrint(("DEC G/A found 5\n"));
+
+ HalpPonceConfigAddrReg += 0x800;
+ HalpPonceConfigDataReg += 0x800;
+ HalpPoncePerrm += 0x800;
+ HalpPoncePaerr += 0x800;
+ HalpPoncePerst += 0x800;
+
+ for (Slot.u.bits.DeviceNumber = 1; Slot.u.bits.DeviceNumber < 5; 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;
+ HalpDisplayControlBase |= 0xC0000000;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+ }
+ // S001 vvv
+ } else if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,"3D3D0001")) {
+
+ ULONG ponceNumber;
+ ULONG glintFound=FALSE;
+
+ //
+ // for GLINT 300SX PCI
+ //
+
+ DispDbgPrint(("Hal: GLiNT config entry found\n"));
+
+ HalpDisplayControllerSetup = HalpDisplayGlintSetup;
+ HalpDisplayCharacter = HalpDisplayCharacterOld;
+ HalpDisplayPCIDevice = TRUE;
+ HalpDisplayType16BPP = TRUE;
+
+ //
+ // FunctionNumber always zero
+ //
+
+ Slot.u.bits.FunctionNumber = 0;
+
+ for (ponceNumber = 0; ponceNumber < R98B_MAX_PONCE ; ponceNumber++) {
+ ULONG startDevNum;
+ ULONG endDevNum;
+ ULONG addressOffset;
+
+ HalpPonceConfigAddrReg = PONCE_ADDR_REG + (ponceNumber * 0x400);
+ HalpPonceConfigDataReg = PONCE_DATA_REG + (ponceNumber * 0x400);
+ HalpPoncePerrm = PONCE_PERRM + (ponceNumber * 0x400);
+ HalpPoncePaerr = PONCE_PAERR + (ponceNumber * 0x400);
+ HalpPoncePerst = PONCE_PERST + (ponceNumber * 0x400);
+
+ addressOffset = (ponceNumber+1) * 0x40000000;
+
+ DispDbgPrint(("Hal: search GLiNT board on PONCE#%d\n", ponceNumber));
+
+ switch(ponceNumber){
+ case 0:
+ startDevNum = 2;
+ endDevNum = 5;
+ break;
+
+ case 1:
+ if (HalpNumberOfPonce == 3) {
+ DispDbgPrint(("Hal: Skip PONCE#1\n"));
+ continue;
+ }
+ startDevNum = 3;
+ endDevNum = 6;
+ break;
+
+ case 2:
+ if (HalpNumberOfPonce == 2) {
+ DispDbgPrint(("Hal: Skip PONCE#2\n"));
+ continue;
+ }
+ startDevNum = 1;
+ endDevNum = 4;
+ break;
+
+ default:
+ continue;
+ }
+
+ for (Slot.u.bits.DeviceNumber = startDevNum;
+ Slot.u.bits.DeviceNumber <= endDevNum;
+ Slot.u.bits.DeviceNumber++){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+ if (ReadValue == 0x00013d3d){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
+
+ DispDbgPrint(("Hal: GLiNT found on PONCE#%d, Device=%d\n", ponceNumber,Slot.u.bits.DeviceNumber));
+
+ //
+ // GLINT 300SX has no I/O space regions
+ //
+
+ if (ReadValue & 0x2){
+
+ //
+ // Control Registers
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ HalpDisplayControlBase = (ReadValue & 0xfffffff0);
+ HalpDisplayControlBase |= addressOffset;
+
+ DispDbgPrint(("Hal: GLiNT HalpDisplayControlBase=0x%08lx\n", HalpDisplayControlBase));
+ //
+ // Framebuffer
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
+ HalpDisplayMemoryBase = (ReadValue & 0xfffffff0);
+ HalpDisplayMemoryBase |= addressOffset;
+
+ DispDbgPrint(("Hal: GLiNT HalpDisplayMemoryBase=0x%08lx\n", HalpDisplayMemoryBase));
+ //
+ // Revision ID
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x08);
+
+ HalpGlintRevisionId = (ReadValue & 0x000000ff);
+
+ DispDbgPrint(("Hal: GLiNT HalpGlintRevisionId=0x%08lx\n", HalpGlintRevisionId));
+
+ //
+ // Enable ROM.
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x30);
+ ReadValue |= 0x1;
+ HalpWritePCIConfigUlongByOffset(Slot,&ReadValue, 0x30);
+
+ glintFound = TRUE;
+
+ break;
+
+ } else {
+ DispDbgPrint(("Hal: GLiNT have not I/O space\n"));
+
+ return FALSE;
+
+ }
+ }
+ }
+
+ if(glintFound == TRUE) {
+ DispDbgPrint(("Hal: GLiNT adapter already found\n"));
+ break;
+ }
+ }
+
+ } else {
+ DispDbgPrint(("DisplayTypeUnknown\n"));
+
+ HalpDisplayControllerSetup = HalpDisplayINT10Setup;
+ HalpDisplayCharacter = HalpDisplayCharacterVGA;
+ HalpDisplayControlBase = PCI_0_IO_BASE;
+ HalpDisplayTypeUnknown = TRUE;
+ // S001 ^^^
+ }
+
+ Child = ConfigurationEntry->Child;
+
+ DispDbgPrint(("Hal: parameters read start\n"));
+
+ RtlMoveMemory((PVOID)&HalpMonitorConfigurationData,
+ Child->ConfigurationData,
+ Child->ComponentEntry.ConfigurationDataLength);
+
+ //
+ // Compute character output display parameters.
+ //
+
+ HalpDisplayText =
+ HalpMonitorConfigurationData.VerticalResolution / HalpCharacterHeight;
+
+ if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
+ HalpScrollLine =
+ 1024 * HalpCharacterHeight;
+ // S001 vvv
+ } else if (HalpDisplayType16BPP) {
+ HalpScrollLine =
+ HalpMonitorConfigurationData.HorizontalResolution * HalpCharacterHeight * sizeof(USHORT);
+ // S001 ^^^
+ } else {
+ HalpScrollLine =
+ HalpMonitorConfigurationData.HorizontalResolution * HalpCharacterHeight;
+ }
+
+ HalpScrollLength = HalpScrollLine * (HalpDisplayText - 1);
+
+ if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
+ HalpDisplayWidth =
+ 1024 / HalpCharacterWidth;
+
+ }else{
+
+ HalpDisplayWidth =
+ HalpMonitorConfigurationData.HorizontalResolution / HalpCharacterWidth;
+ }
+
+ DispDbgPrint(("Hal: HalpDisplayText = %d\n", HalpDisplayText));
+ DispDbgPrint(("Hal: HalpDisplayWidth = %d\n", HalpDisplayWidth));
+ DispDbgPrint(("Hal: HalpScrollLine = %d\n", HalpScrollLine));
+ DispDbgPrint(("Hal: HalpScrollLength = %d\n", HalpScrollLength));
+
+ //
+ // Scan the memory allocation descriptors and allocate a free page
+ // to map the video memory and control registers, and initialize the
+ // PDE entry.
+ //
+
+ DispDbgPrint(("Hal: Mem get \n"));
+
+ 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;
+
+ Pte.C = UNCACHED_POLICY;
+
+ //
+ // 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)));
+
+ // S001 vvv
+ if (HalpDisplayControllerSetup == HalpDisplayINT10Setup) {
+
+ HalpCirrusPhigicalVideo.HighPart = 1;
+ HalpCirrusPhigicalVideo.LowPart = 0x40000000;
+
+ Pte.PFN = (HalpCirrusPhigicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpCirrusPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+ }else
+ // S001 ^^^
+ if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup) {
+
+ HalpCirrusPhigicalVideo.HighPart = 1;
+ HalpCirrusPhigicalVideo.LowPart = CIRRUS_MEMORY_BASE_LOW;
+
+ 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;
+
+#if defined (DBG7)
+ DbgPrint("DEC G/A HalpTgaPhigicalVideo.HighPart=0x%x\n",HalpTgaPhigicalVideo.HighPart);
+ DbgPrint("DEC G/A HalpTgaPhigicalVideo.LowPart=0x%x\n",HalpTgaPhigicalVideo.LowPart);
+#endif
+
+ Pte.PFN = (HalpTgaPhigicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpTgaPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+
+ }
+ // S001 vvv
+ 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);
+ }
+ // S001 ^^^
+
+ Pte.G = 0;
+ Pte.V = 1;
+ Pte.D = 1;
+ Pte.C = UNCACHED_POLICY;
+
+ //
+ // 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) {
+ HalpTgaPhigicalVideo.HighPart = 1;
+ HalpTgaPhigicalVideo.LowPart = HalpDisplayControlBase;
+ Pte.PFN = (HalpDisplayControlBase >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpTgaPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+ *PageFrame = Pte;
+
+ // S001 vvv
+ } 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){
+ DispDbgPrint(("HAL: Map x86 and cirrus control register\n"));
+
+ Pte.PFN = ((ULONG)HalpDisplayControlBase + 0xffff) >> PAGE_SHIFT;
+
+ for (Index = 0; Index < (0x10000 / PAGE_SIZE ); Index++) {
+ *PageFrame-- = Pte;
+ DispDbgPrint(("HAL: Map index %x pfn %x\n",Index,Pte.PFN));
+ Pte.PFN -= 1;
+ }
+ // S001 ^^^
+ } else {
+
+ //
+ // Page table for the video registers.
+ //
+
+ Pte.PFN = ((ULONG)HalpDisplayControlBase) >> PAGE_SHIFT;
+ *PageFrame = Pte;
+ }
+
+ //
+ // Initialize the display controller.
+ //
+
+ // S001 vvv
+ if(HalpDisplayControllerSetup == HalpDisplayINT10Setup){
+ if (HalpInitializeX86DisplayAdapter()) {
+// HalpDisplayControllerSetup(); // initialize twice bugbug
+ }else{
+ return FALSE;
+ }
+ }
+ // S001 ^^^
+ HalpDisplayControllerSetup();
+
+ HalpInitDisplayStringIntoNvram();
+
+ 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;
+
+ HalpSetInitDisplayTimeStamp();
+
+ 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.
+
+--*/
+
+{
+ HalpSuccessOsStartUp();
+
+ //
+ // Set HAL ownership of the display to false.
+ //
+
+ HalpResetDisplayParameters=ResetDisplayParameters; // S001
+ HalpMrcModeChange((UCHAR)MRC_OP_DUMP_ONLY_NMI);
+ HalpDisplayOwnedByHal = FALSE;
+
+ DispDbgPrint(("HAL: DisplayOwnedByHal = FALSE, DispResetRoutine = 0x%x\n",
+ (ULONG)HalpResetDisplayParameters));
+
+ 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, dac_dmyread;
+
+#if defined(DBCS) && defined(_MIPS_)
+ 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 ) {
+ DispDbgPrint(("HAL: 640x480 60Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_640x480_256_60);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else {
+ DispDbgPrint(("HAL: 640x480 72Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_640x480_256_72);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ }
+ break;
+
+ case 800:
+ if( verticalFrequency < 58 ) {
+ DispDbgPrint(("HAL: 800x600 56Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_800x600_256_56);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else if( verticalFrequency < 66 ) {
+ DispDbgPrint(("HAL: 800x600 60Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_800x600_256_60);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else {
+ DispDbgPrint(("HAL: 800x600 72Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_800x600_256_72);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ }
+ break;
+
+ case 1024:
+ if( verticalFrequency < 52 ) {
+ DispDbgPrint(("HAL: 1024x768 87Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_1024x768_256_87);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else if( verticalFrequency < 65 ) {
+ DispDbgPrint(("HAL: 1024x768 60Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_1024x768_256_60);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else if( verticalFrequency < 78 ) {
+ DispDbgPrint(("HAL: 1024x768 70Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_1024x768_256_70);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ } else {
+ DispDbgPrint(("HAL: 1024x768 87Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_1024x768_256_87);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ }
+ break;
+ default:
+ DispDbgPrint(("HAL: 640x480 60Hz setup\n"));
+ HalpCirrusInterpretCmdStream(CL542x_640x480_256_60);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+// return;
+ }
+#else // defined(DBCS) && defined(_MIPS_)
+
+ switch (HalpMonitorConfigurationData.HorizontalResolution) {
+ case 640:
+
+ DispDbgPrint(("640x480 setup\n"));
+
+ HalpCirrusInterpretCmdStream(HalpCirrus_640x480_256);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ break;
+ case 800:
+
+ DispDbgPrint(("800x600 setup\n"));
+
+ HalpCirrusInterpretCmdStream(HalpCirrus_800x600_256);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ break;
+ case 1024:
+
+ DispDbgPrint(("1024x768 setup\n"));
+
+ HalpCirrusInterpretCmdStream(HalpCirrus_1024x768_256);
+ HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
+ break;
+ default:
+ return;
+ }
+#endif // defined(DBCS) && defined(_MIPS_)
+
+ DispDbgPrint(("color set\n"));
+
+ dac_address = (ULONG)CIRRUS_BASE + 0x3b0 + DAC_ADDRESS_WRITE_PORT;
+ dac_dmyread = (ULONG)CIRRUS_BASE + 0x3b0 + DAC_STATE_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);
+ READ_PORT_UCHAR((PUCHAR)dac_dmyread);
+
+ 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));
+ READ_PORT_UCHAR((PUCHAR)dac_dmyread);
+
+ //
+ // 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;
+
+ 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 };
+ const UCHAR PLLbits800x600_60[7] = { 0x80, 0x04, 0x80, 0xa5, 0x78, 0x20, 0x08 };
+ const UCHAR PLLbits1024x768_60[7] = { 0x80, 0x00, 0x80, 0x24, 0x48, 0x20, 0x98 };
+
+ const UCHAR Vga_Ini_ColorTable[48] =
+ { VGA_INI_PALETTE_HI_WHITE_R, VGA_INI_PALETTE_HI_WHITE_G, VGA_INI_PALETTE_HI_WHITE_B,
+ 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_WHITE_R, VGA_INI_PALETTE_WHITE_G, VGA_INI_PALETTE_WHITE_B,
+ 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
+ };
+
+ DispDbgPrint(("TGA Set Up IN\n"));
+
+ //
+ // 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;
+ } else {
+ PLLbits = (PVOID)PLLbits640x480_60;
+ }
+ } else if( HalpMonitorConfigurationData.HorizontalResolution == 800
+ && HalpMonitorConfigurationData.VerticalResolution == 600 ){
+ if( VerticalFrequency > 66 ){
+ PLLbits = (PVOID)PLLbits800x600_72;
+ } else {
+ PLLbits = (PVOID)PLLbits800x600_60;
+ }
+ } else if( HalpMonitorConfigurationData.HorizontalResolution == 1024
+ && HalpMonitorConfigurationData.VerticalResolution == 768 ){
+ PLLbits = (PVOID)PLLbits1024x768_60;
+ } else {
+ PLLbits = (PVOID)PLLbits640x480_60;
+ }
+
+ // 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);
+ }
+ }
+#if defined (DBG7)
+ DbgPrint("TGA Set Up 1\n");
+
+ DbgPrint("TGA_REGISTER_BASE=0x%x\n",TGA_REGISTER_BASE);
+ DbgPrint("COMMAND_STATUS=0x%x\n",COMMAND_STATUS);
+ DbgPrint("TGA_REGISTER_BASE + COMMAND_STATUS=0x%x\n",(READ_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + COMMAND_STATUS) )));
+#endif
+
+ // Verify 21030 is idle ( check busy bit on Command Status Register )
+ while( (READ_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + COMMAND_STATUS) ) & 1) == 1 ){
+ }
+#if defined (DBG7)
+ DbgPrint("TGA Set Up 2\n");
+#endif
+
+ // 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 ){
+ }
+#if defined (DBG7)
+ DbgPrint("TGA Set Up 3\n");
+#endif
+
+ // 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), 0x3c294a0 ); // K1001
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x070349e0 );
+ } else {
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0xe64ca0 ); // K1001
+ 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), 0x1a7a4c8 ); // K1001
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x05c6fa58 );
+ } else {
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x2681cc8 ); // K1001
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x05c40a58 );
+ }
+ } else if( HalpMonitorConfigurationData.HorizontalResolution == 1024
+ && HalpMonitorConfigurationData.VerticalResolution == 768 ){
+ //60Hz Only
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x4889300 ); // // K1001
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x07461b00 );
+ } else {
+ WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0xe64ca0 ); // K1001
+ 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 );
+#if defined (DBG7)
+ DbgPrint("TGA Set Up 4\n");
+#endif
+
+ KeStallExecutionProcessor(10000L);
+#if defined (DBG7)
+ DbgPrint("TGA Set Up 5\n");
+#endif
+
+ // 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;
+#if defined (DBG7)
+ DbgPrint("TGA Set Up End\n");
+#endif
+
+ 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;
+ ULONG NowDisplayControlBase;
+ ULONG NowDisplayMemoryBase;
+ PENTRYLO PageFrame;
+ ENTRYLO Pte;
+ LONG Index;
+ PCI_SLOT_NUMBER Slot;
+ ULONG ReadValue;
+ ULONG cpu;
+
+ //
+ // 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.
+ //
+
+// DispDbgPrint(("HalDisplayString\n"));
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ KiAcquireSpinLock(&HalpDisplayAdapterLock);
+
+ // S001 vvv
+ HalpPonceConfigAddrReg = PONCE_ADDR_REG;
+ HalpPonceConfigDataReg = PONCE_DATA_REG;
+ HalpPoncePerrm = PONCE_PERRM;
+ HalpPoncePaerr = PONCE_PAERR;
+ HalpPoncePerst = PONCE_PERST;
+ // S001 ^^^
+
+ 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;
+
+ if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
+
+ HalpPonceConfigAddrReg += 0x400;
+ HalpPonceConfigDataReg += 0x400;
+ HalpPoncePerrm += 0x400;
+ HalpPoncePaerr += 0x400;
+ HalpPoncePerst += 0x400;
+
+ Slot.u.bits.DeviceNumber = 4;
+
+ HalpReadPCIConfigUlongByOffset( Slot,&ReadValue,0x14);
+
+ DispDbgPrint(("CirrusControlBase:=0x%x\n",ReadValue));
+
+ NowDisplayControlBase = (ReadValue & 0x0000fc00) + PCI_1_IO_BASE;
+ HalpReadPCIConfigUlongByOffset( Slot,&ReadValue,0x10);
+
+ DispDbgPrint(("NowDisplayControlBase = 0x%x\n",NowDisplayControlBase));
+ DispDbgPrint(("CirrusMemoryBase:=0x%x\n",ReadValue));
+
+ NowDisplayMemoryBase = (ReadValue & 0xff000000) + 0x80000000;
+
+ DispDbgPrint(("NowDisplayMemoryBase = 0x%x\n",NowDisplayMemoryBase));
+
+ } else {
+
+ for (Slot.u.bits.DeviceNumber = 1; Slot.u.bits.DeviceNumber < 6; Slot.u.bits.DeviceNumber++){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+ if (HalpDisplayControllerSetup == HalpDisplayTgaSetup && ReadValue == 0x00041011){
+ //
+ // DEC 21030
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ DispDbgPrint(("DECControlBase:=0x%x\n",ReadValue));
+ NowDisplayControlBase = (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
+ NowDisplayControlBase |= 0x40000000;
+ NowDisplayMemoryBase = 0;
+
+ // S001 vvv
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup && ReadValue == 0x00013d3d){
+ //
+ // GLINT 300SX
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ NowDisplayControlBase = (ReadValue & 0xfffffff0);
+ NowDisplayControlBase |= 0x40000000;
+ DispDbgPrint(("HAL:GLiNTCtrlBase=0x%08lx,Now=0x%08lx\n",
+ ReadValue, NowDisplayControlBase));
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
+ NowDisplayMemoryBase = (ReadValue & 0xfffffff0);
+ NowDisplayMemoryBase |= 0x40000000;
+ DispDbgPrint(("HAL:GLiNTMemBase =0x%08lx,Now=0x%08lx\n",
+ ReadValue, NowDisplayMemoryBase));
+ // S001 ^^^
+ }
+ }
+ if (HalpNumberOfPonce == 2){
+
+ HalpPonceConfigAddrReg += 0x400;
+ HalpPonceConfigDataReg += 0x400;
+ HalpPoncePerrm += 0x400;
+ HalpPoncePaerr += 0x400;
+ HalpPoncePerst += 0x400;
+
+ for (Slot.u.bits.DeviceNumber = 5; Slot.u.bits.DeviceNumber < 7; Slot.u.bits.DeviceNumber++){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+ if (HalpDisplayControllerSetup == HalpDisplayTgaSetup && ReadValue == 0x00041011){
+ //
+ // DEC 21030
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x10);
+ NowDisplayControlBase = (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
+ NowDisplayControlBase |= 0x80000000;
+ NowDisplayMemoryBase = 0;
+ // S001 vvv
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup && ReadValue == 0x00013d3d){
+ //
+ // GLINT 300SX
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ NowDisplayControlBase = (ReadValue & 0xfffffff0);
+ NowDisplayControlBase |= 0x80000000;
+ DispDbgPrint(("HAL:GLiNTCtrlBase=0x%08lx,Now=0x%08lx\n",
+ ReadValue, NowDisplayControlBase));
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
+ NowDisplayMemoryBase = (ReadValue & 0xfffffff0);
+ NowDisplayMemoryBase |= 0x80000000;
+ DispDbgPrint(("HAL:GLiNTMemBase =0x%08lx,Now=0x%08lx\n",
+ ReadValue, NowDisplayMemoryBase));
+ // S001 ^^^
+ }
+ }
+ } else {
+ HalpPonceConfigAddrReg += 0x800;
+ HalpPonceConfigDataReg += 0x800;
+ HalpPoncePerrm += 0x800;
+ HalpPoncePaerr += 0x800;
+ HalpPoncePerst += 0x800;
+
+ for (Slot.u.bits.DeviceNumber = 1; Slot.u.bits.DeviceNumber < 5; Slot.u.bits.DeviceNumber++){
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
+
+ if (HalpDisplayControllerSetup == HalpDisplayTgaSetup && ReadValue == 0x00041011){
+
+ //
+ // DEC 21030
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x10);
+ NowDisplayControlBase = (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
+ NowDisplayControlBase |= 0xC0000000;
+ NowDisplayMemoryBase = 0;
+
+ // S001 vvv
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup && ReadValue == 0x00013d3d){
+ //
+ // GLINT 300SX
+ //
+
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
+ NowDisplayControlBase = (ReadValue & 0xfffffff0);
+ NowDisplayControlBase |= 0xc0000000;
+ HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
+ NowDisplayMemoryBase = (ReadValue & 0xfffffff0);
+ NowDisplayMemoryBase |= 0xc0000000;
+ // S001 ^^^
+ }
+ }
+ }
+ }
+
+ //
+ // 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;
+ Pte.C = UNCACHED_POLICY;
+
+ PageFrame = (PENTRYLO)(PTE_BASE | (VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
+
+ if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup) {
+ HalpCirrusPhigicalVideo.HighPart = 1;
+ HalpCirrusPhigicalVideo.LowPart = HalpDisplayMemoryBase;
+ Pte.PFN = (HalpCirrusPhigicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpCirrusPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+
+ } else 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);
+ // S001 vvv
+ } else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) {
+ HalpGlintPhygicalVideo.HighPart = 1;
+ HalpGlintPhygicalVideo.LowPart = HalpDisplayMemoryBase;
+ Pte.PFN = (HalpGlintPhygicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpGlintPhygicalVideo.HighPart << (32 - PAGE_SHIFT);
+ // S001 ^^^
+ }
+
+ for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
+ *PageFrame++ = Pte;
+ Pte.PFN += 1;
+ }
+
+ if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup) {
+
+ //
+ // Page table for the video registers.
+ //
+
+ Pte.PFN = ((ULONG)HalpDisplayControlBase) >> PAGE_SHIFT;
+ *PageFrame = Pte;
+
+ } else 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;
+ // S001 vvv
+ } 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;
+ // S001 ^^^
+ }
+ }
+ }
+
+ //
+ // 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) {
+ // S001 vvv
+
+ DispDbgPrint(("HAL: Re Initialize Controller\n"));
+ DispDbgPrint(("HAL: Str = %s\n",String));
+
+ 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.
+ //
+
+ DispDbgPrint(("HAL: Call x86 reset routine\n"));
+
+ if (HalpResetDisplayParameters(80, 50)) {
+ }
+ }
+ // S001 ^^^
+
+ if(HalpNMIFlag == 0){
+ //
+ // Non NMI. It is Panic.
+ //
+ HalpMrcModeChange((UCHAR)MRC_OP_DUMP_AND_POWERSW_NMI);
+ //
+ // Do not make eif. retun only at dump key
+ //
+ for (cpu=0;cpu < R98B_MAX_CPU;cpu++)
+ HalpNMIHappend[cpu] = 1;
+ }
+
+ DispDbgPrint(("HAL: Call DisplayControllerSetup\n"));
+
+ HalpDisplayControllerSetup();
+ HalpInitDisplayStringIntoNvram();
+// HalpResetX86DisplayAdapter(); /* for X86 */
+ }
+
+ HalStringIntoBufferStart( HalpColumn, HalpRow );
+
+ //
+ // Display characters until a null byte is encountered.
+ //
+
+ while (*String != 0) {
+ HalpDisplayCharacter(*String++);
+ }
+
+ 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;
+
+ KiReleaseSpinLock(&HalpDisplayAdapterLock);
+
+ 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; // S001
+ 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 {
+#if 0
+ RtlMoveMemory((PVOID)VIDEO_MEMORY_BASE,
+ (PVOID)(VIDEO_MEMORY_BASE + HalpScrollLine),
+ HalpScrollLength);
+#else
+ HalpMoveMemory32((PUCHAR)VIDEO_MEMORY_BASE,
+ (PUCHAR)(VIDEO_MEMORY_BASE + HalpScrollLine),
+ HalpScrollLength);
+#endif
+
+ // S001 vvv
+ if (HalpDisplayType16BPP) {
+ DestinationShort = (PUSHORT)(VIDEO_MEMORY_BASE + HalpScrollLength); // M022
+ } 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;
+ }
+ }
+ // S001 ^^^
+ }
+
+ HalpStringBufferCopyToNvram();
+ HalStringIntoBufferStart( HalpColumn, HalpRow );
+
+ } else if (Character == '\r') {
+ HalpColumn = 0;
+
+ HalpStringBufferCopyToNvram();
+ HalStringIntoBufferStart( HalpColumn, HalpRow );
+
+ } else {
+ HalStringIntoBuffer( Character );
+
+ if ((Character < HalpFontHeader->FirstCharacter) ||
+ (Character > HalpFontHeader->LastCharacter)) {
+ Character = HalpFontHeader->DefaultCharacter;
+ }
+
+ Character -= HalpFontHeader->FirstCharacter;
+ HalpOutputCharacterOld((PUCHAR)HalpFontHeader + HalpFontHeader->Map[Character].Offset);
+ }
+
+ return;
+}
+
+// S001 vvv
+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);
+ }
+ }
+
+ //=========================================================================
+ //
+ // 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') {
+ HalpColumn = 0;
+ } else if (Character == 0x7f) { /* DEL character */
+ if (HalpColumn != 0) {
+ HalpColumn -= 1;
+ HalpOutputCharacterINT10(0);
+ HalpColumn -= 1;
+ } else /* do nothing */
+ ;
+ } else if (Character >= 0x20) {
+ // 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() */
+// S001 ^^^
+
+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; // S001
+ 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.
+ //
+
+ // S001 vvv
+ if (HalpDisplayType16BPP) {
+ DestinationShort = (PUSHORT)(VIDEO_MEMORY_BASE +
+ (HalpRow * HalpScrollLine) + (HalpColumn * HalpCharacterWidth * sizeof(USHORT)));
+ } else {
+ Destination = (PUCHAR)(VIDEO_MEMORY_BASE +
+ (HalpRow * HalpScrollLine) + (HalpColumn * HalpCharacterWidth));
+ }
+ // S001 ^^^
+
+ 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) {
+ // S001 vvv
+ if (HalpDisplayType16BPP) {
+ if (FontValue >> 31)
+ *DestinationShort++ = (USHORT)0xffff;
+ else
+ *DestinationShort++ = (USHORT)0x000f;
+ }else{
+ *Destination++ = (UCHAR) (FontValue >> 31) ^ 1;
+ }
+ // S001 ^^^
+ FontValue <<= 1;
+ }
+
+ if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
+ Destination +=
+ (1024 - HalpCharacterWidth);
+ // S001 vvv
+ } else if (HalpDisplayType16BPP){
+ DestinationShort +=
+ (HalpMonitorConfigurationData.HorizontalResolution - HalpCharacterWidth);
+ // S001 ^^^
+ } else {
+ Destination +=
+ (HalpMonitorConfigurationData.HorizontalResolution - HalpCharacterWidth);
+ }
+ }
+ HalpColumn += 1;
+ return;
+}
+
+VOID
+Write_Dbg_Uchar(
+ PUCHAR Ioadress,
+ UCHAR Moji
+ )
+{
+// DispDbgPrint(("Disply I/O Adress %x Char %x \n",Ioadress,Moji));
+
+ WRITE_PORT_UCHAR(Ioadress,Moji);
+}
+
+// S001 vvv
+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
+ 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;
+ HalpScrollLine = 160;
+ HalpScrollLength = HalpScrollLine * (HalpDisplayText - 1);
+
+ HalpDisplayOwnedByHal = TRUE;
+
+ HalpResetX86DisplayAdapter(); // for compaq q-vision reset
+
+ //
+ // Load 8x8 font 80x50 on VGA
+ //
+ Eax = 0x1112; // AH = 11 AL=12
+ Ebx = 0;
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+
+ //
+ // 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);
+
+}
+// S001 ^^^
+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;
+
+ //
+ // Disable PCI-MasterAbort interrupt during configration read.
+ //
+
+// DispDbgPrint(("Hal: Chk perrmAddr=0x%x, paerrAddr=0x%x\n",HalpPoncePerrm, HalpPoncePaerr));
+
+ OrigData = READ_REGISTER_ULONG(HalpPoncePerrm);
+
+// DispDbgPrint(("Hal: origdata perrm data=0x%08lx\n",OrigData));
+
+ WRITE_REGISTER_ULONG(HalpPoncePerrm, OrigData | 0x00800000);
+
+ //
+ // 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;
+
+// DispDbgPrint(("Hal: deviceNum=%d, funcNum=%d\n",Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber));
+
+ //
+ // Synchronize with PCI configuration
+ //
+
+ WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
+ IdValue = READ_REGISTER_ULONG(HalpPonceConfigDataReg);
+
+ //
+ // Release spinlock
+ //
+
+ if ((USHORT)(IdValue & 0xffff) == 0xffff){
+
+ //
+ // waiting until ReceivedMasterAbort bit is set
+ //
+
+// DispDbgPrint(("Hal: chk 0\n"));
+// DispDbgPrint(("Hal: PERRI = 0x%x\n",READ_REGISTER_ULONG((PULONG)0xba000818)));
+// DispDbgPrint(("Hal: paerr = 0x%x\n",READ_REGISTER_ULONG(HalpPoncePaerr)));
+
+ //
+ // clear the ReceivedMasterAbort bit
+ //
+
+ WRITE_REGISTER_ULONG(HalpPoncePerst, 0x00800000);
+
+ //
+ // Clear memory address error registers.
+ //
+
+// {
+// LARGE_INTEGER registerLarge;
+// READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, &registerLarge);
+// }
+
+// DispDbgPrint(("Hal: chk 1\n"));
+
+ ReturnValue = FALSE;
+
+ } else {
+
+// DispDbgPrint(("Hal: chk 2\n"));
+
+ ReturnValue = TRUE;
+
+ }
+
+ //
+ // Restore the PCIInterruptEnable register.
+ //
+
+ WRITE_REGISTER_ULONG(HalpPoncePerrm, OrigData);
+
+// DispDbgPrint(("Hal: chk 3\n"));
+
+ return ReturnValue;
+}
+// S001 vvv
+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 */
+ DispDbgPrint(("Hal: GLiNT Display setup\n"));
+
+ if ( HalpGlintRevisionId == 0){
+ Video->RefDivCount = RGB525_PLL_REFCLK_40_MHz;
+ } else {
+ Video->RefDivCount = RGB525_PLL_REFCLK_50_MHz;
+ }
+
+ //
+ // 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_
+
+ DispDbgPrint(("HAL: VerticalResolution=%d\n",HalpMonitorConfigurationData.VerticalResolution));
+ DispDbgPrint(("HAL: horizontalTotal=%d\n",horizontalTotal));
+ DispDbgPrint(("HAL: verticalTotal=%d\n",verticalTotal));
+
+ //
+ // Initialize video data
+ //
+
+ /* get timing values for named resolution */
+
+ if ( HalpMonitorConfigurationData.HorizontalResolution == 1280
+ && HalpMonitorConfigurationData.VerticalResolution == 1024
+ && VerticalFrequency == 75)
+ {
+ DispDbgPrint(("HAL: GLiNT 1280x1024 75Hz setup\n"));
+ 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)
+ {
+ DispDbgPrint(("HAL: GLiNT 1024x768 75Hz setup\n"));
+ 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)
+ {
+ DispDbgPrint(("HAL: GLiNT 1024x768 60Hz setup\n"));
+ 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)
+ {
+ DispDbgPrint(("HAL: GLiNT 800x600 75Hz setup\n"));
+ 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)
+ {
+ DispDbgPrint(("HAL: GLiNT 800x600 60Hz setup\n"));
+ 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)
+ {
+ DispDbgPrint(("HAL: GLiNT 640x480 60Hz setup\n"));
+ 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)
+ {
+ DispDbgPrint(("HAL: GLiNT 640x480 75Hz setup\n"));
+ 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)
+ {
+ DispDbgPrint(("HAL: GLiNT 1280x1024 57Hz setup\n"));
+ 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)
+ //
+
+ DispDbgPrint(("HAL: GLiNT 1024x768 60Hz setup (default setting)\n"));
+ 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) * 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;
+}
+
+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
+ //
+
+ WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
+
+ *Buffer = READ_REGISTER_ULONG(HalpPonceConfigDataReg);
+
+ return;
+}
+
+VOID
+HalpReadPCIConfigUshortByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUSHORT Buffer,
+ IN ULONG Offset
+ )
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ if (!HalpCheckPCIDevice(Slot)) {
+ *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;
+
+ WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
+
+ *Buffer = READ_REGISTER_USHORT((PUCHAR)HalpPonceConfigDataReg + (Offset % sizeof(ULONG)));
+
+ return;
+}
+
+VOID
+HalpReadPCIConfigUcharByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ if (!HalpCheckPCIDevice(Slot)) {
+ *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;
+
+ WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
+
+ *Buffer = READ_REGISTER_UCHAR((PUCHAR)HalpPonceConfigDataReg + (Offset % sizeof(ULONG)));
+
+ return;
+}
+
+VOID
+HalpWritePCIConfigUlongByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PULONG Buffer,
+ IN ULONG Offset
+ )
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ if (!HalpCheckPCIDevice(Slot)) {
+ *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;
+
+ WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
+
+ WRITE_REGISTER_ULONG(HalpPonceConfigDataReg, *Buffer);
+
+ return;
+}
+
+VOID
+HalpWritePCIConfigUshortByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUSHORT Buffer,
+ IN ULONG Offset
+ )
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ if (!HalpCheckPCIDevice(Slot)) {
+ *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;
+
+ WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
+
+ WRITE_REGISTER_USHORT((PUCHAR)HalpPonceConfigDataReg + (Offset % sizeof(ULONG)),*Buffer);
+
+ return;
+}
+
+VOID
+HalpWritePCIConfigUcharByOffset (
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
+ USHORT StatusValue;
+ KIRQL OldIrql;
+
+ if (!HalpCheckPCIDevice(Slot)) {
+ *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;
+
+ WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
+
+ WRITE_REGISTER_UCHAR((PUCHAR)HalpPonceConfigDataReg + (Offset % sizeof(ULONG)), *Buffer);
+
+ return;
+}
+// S001 ^^^
diff --git a/private/ntos/nthals/halr98b/mips/jxebsup.c b/private/ntos/nthals/halr98b/mips/jxebsup.c
new file mode 100644
index 000000000..2b513060c
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxebsup.c
@@ -0,0 +1,1178 @@
+/*++
+
+Copyright (c) 1990-1994 Microsoft Corporation
+
+Module Name:
+
+ jxebsup.c
+
+Abstract:
+
+ The module provides the EISA bus support for R98B systems.
+
+--*/
+
+#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
+ );
+
+//
+// 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;
+
+
+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; // S004
+
+ 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 (channelNumber) {
+ 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; // S004
+
+ 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;
+ KIRQL oldIrql;
+ UCHAR charBuffer;
+
+
+ //
+ // 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_DISPATCH_VECTOR] = (PKINTERRUPT_ROUTINE)HalpEisaDispatch;
+
+ //
+ // Raise the IRQL while the EISA interrupt controller is initalized.
+ //
+ KeRaiseIrql(EISA_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;
+
+ //
+ // Restore IRQL level.
+ //
+
+ KeLowerIrql(oldIrql);
+
+
+ //
+ // EISA Interrupt to PONCE Enable!!.
+ //
+ HalpInterruptFromPonce(EISA_DISPATCH_VECTOR ,1); //SNES
+
+ //
+ // 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
+ );
+
+
+
+ charBuffer = READ_REGISTER_UCHAR( &((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus );
+ //
+ // IOCHK# NMI Disable and Clear
+ // PERR# PCI System Board Error Disable
+ //
+ charBuffer = ((charBuffer & 0x03) | 0x0C);
+ WRITE_REGISTER_UCHAR( &((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus,
+ charBuffer
+ );
+ //
+ // Disbale Bus Timeout,Fail Safe NMI adn Software NMI
+ //
+ charBuffer = READ_REGISTER_UCHAR(
+ &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl
+ );
+
+ charBuffer = (charBuffer & 0x01);
+ WRITE_REGISTER_UCHAR( &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl,
+ charBuffer );
+
+ return(TRUE);
+}
+
+
+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
+ );
+
+ }
+
+}
+//
+//
+//extern KSPIN_LOCK HalpIoMapSpinLock;
+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;
+ KIRQL Irql;
+
+ BytePtr = (PUCHAR) &Offset;
+
+// ASSERT(Offset >= 0x100000); // S009
+
+
+ //
+ // grab the spinlock for the system DMA controller
+ // Internal Floppy Device used ESC DMA and May be diffirent Onprocessor
+ // with EISA Drivers OnProcessor.
+ // So grab.
+
+ KeAcquireSpinLock( &AdapterObject->MasterAdapter->SpinLock, &Irql );
+
+
+ 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)
+ );
+
+ }
+ KeReleaseSpinLock (&AdapterObject->MasterAdapter->SpinLock, Irql);
+ 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)
+ );
+ }
+
+ KeReleaseSpinLock (&AdapterObject->MasterAdapter->SpinLock, Irql);
+
+}
+
+
+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 EISA 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
+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;
+
+ //
+ // Read the interrupt vector.
+ //
+
+ interruptVector = (UCHAR)READ_REGISTER_ULONG( (PULONG)&PONCE_CNTL(0)->INTAC);
+
+
+ //
+ // 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) {
+ //K001 Start
+ if(interruptVector == 7|| interruptVector==15 ){
+
+ PVOID IsrPortAddr;
+ UCHAR IsrValue;
+
+#define OCW3_READ_ISR 0x0B
+#define OCW3_READ_IRR 0x0A
+
+ //
+ // Master or Slave ?
+ //
+ IsrPortAddr = (interruptVector == 7) ?
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt1ControlPort0:
+ &((PEISA_CONTROL) HalpEisaControlBase)->Interrupt2ControlPort0;
+
+ // SetUp to ISR Regsiter
+ WRITE_REGISTER_UCHAR( IsrPortAddr, OCW3_READ_ISR );
+ // Read ISR Register
+ IsrValue=READ_REGISTER_UCHAR( IsrPortAddr );
+ // Resume to IRR Register
+ WRITE_REGISTER_UCHAR( IsrPortAddr, OCW3_READ_IRR);
+
+ if(!IsrValue){
+ // This is a spurious interrupt!!. No Call Driver.
+ goto NocallDriver;
+ }
+ }
+ // K001 End
+
+ //
+ // Mask the upper bits off since the vector is only a byte and
+ // dispatch to the secondary interrupt service routine.
+ //
+
+ interruptVector &= 0xff;
+ dispatchCode = (PULONG)(PCR->InterruptRoutine[EISA_VECTORS + interruptVector]);
+ interruptObject = CONTAINING_RECORD(dispatchCode,
+ KINTERRUPT,
+ DispatchCode);
+
+ returnValue = ((PSECONDARY_DISPATCH)interruptObject->DispatchAddress)(interruptObject);
+
+NocallDriver:
+
+ //
+ // 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 = HalHandleNMI(NULL, NULL);
+// }
+
+ } else {
+ returnValue = FALSE;
+ }
+
+ return returnValue;
+}
+
+
+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.
+
+--*/
+{
+ KeBugCheck(NMI_HARDWARE_FAILURE);
+ return(TRUE);
+}
diff --git a/private/ntos/nthals/halr98b/mips/jxenvirv.c b/private/ntos/nthals/halr98b/mips/jxenvirv.c
new file mode 100644
index 000000000..e6cef4381
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxenvirv.c
@@ -0,0 +1,691 @@
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxenvirv.c
+
+Abstract:
+
+ This module implements the HAL get and set environment variable routines
+ for a R98B system.
+
+Author:
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+#include "arccodes.h"
+#include "rxnvr.h"
+#include "string.h"
+
+//
+// Define base address at which to map NVRAM.
+//
+//
+// Define local upcase macro.
+//
+
+#define UpCase(c) ((c) >= 'a' && (c) <= 'z' ? (c) - ('a' - 'A') : (c))
+
+KIRQL
+HalpMapNvram (
+ IN PENTRYLO SavedPte
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to map the NVRAM into the address space of
+ the current process.
+
+Arguments:
+
+ SavedPte - Supplies a pointer to an array which receives the old NVRAM
+ PTE values.
+
+Return Value:
+
+ The previous IRQL is returned as the function value.
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+ //
+ // disable nvram Write protection. Set Write Enable
+ //
+#if 0
+ //
+ // No Gard. for Driver. Fix.
+ //
+
+
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->STSR ,STSR_WNVWINH);
+#endif
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ return OldIrql;
+}
+
+VOID
+HalpUnmapNvram (
+ IN PENTRYLO SavedPte,
+ IN KIRQL OldIrql
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to unmap the NVRAM from the address space of
+ the current process.
+
+Arguments:
+
+ SavedPte - Supplies a pointer to an array which contains the old NVRAM
+ PTE values.
+
+ OldIrql - Supplies the previous IRQL value.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+#if 0
+ // N.B For Driver.
+ //
+
+ //
+ // Set nvram write protect
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->STSR ,STSR_NVWINH|STSR_WNVWINH);
+#endif
+ //
+ // Unmap the NVRAM from the address space of the current process.
+ //
+
+ 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_MEMORY_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_MEMORY_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_MEMORY_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;
+ ENTRYLO SavedPte[2];
+ ARC_STATUS Status;
+ ULONG ValueIndex;
+ ULONG VariableIndex;
+
+#if defined(DBG1)
+ DbgPrint("NVRAM 0S\n");
+#endif
+
+
+ //
+ // Map the NVRAM into the address space of the current process.
+ //
+
+ OldIrql = HalpMapNvram(&SavedPte[0]);
+
+ //
+ // 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_MEMORY_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(&SavedPte[0], OldIrql);
+
+#if defined(DBG1)
+ DbgPrint("NVRAM 0E\n");
+#endif
+
+ 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;
+ ENTRYLO SavedPte[2];
+ ARC_STATUS Status;
+ ULONG TopIndex;
+ ULONG VariableIndex;
+ ULONG VariableLength;
+ ULONG ValueEnd;
+ ULONG ValueIndex;
+ ULONG ValueLength;
+
+#if DBG
+ DbgPrint("NVRAM 1S\n");
+#endif
+
+ //
+ // Map the NVRAM into the address space of the current process.
+ //
+
+ OldIrql = HalpMapNvram(&SavedPte[0]);
+ Environment = &((PNV_CONFIGURATION)NVRAM_MEMORY_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(&SavedPte[0], OldIrql);
+#if DBG
+ DbgPrint("NVRAM 1E\n");
+#endif
+
+
+ return Status;
+}
+
+
diff --git a/private/ntos/nthals/halr98b/mips/jxmapio.c b/private/ntos/nthals/halr98b/mips/jxmapio.c
new file mode 100644
index 000000000..e1daa9da5
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxmapio.c
@@ -0,0 +1,124 @@
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxmapio.c
+
+Abstract:
+
+ This module implements the mapping of HAL I/O space a MIPS R98B
+ system.
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+#include "halp.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, HalpMapIoSpace)
+
+#endif
+
+//
+// Define global data used to locate the EISA control space and the realtime
+// clock registers.
+//
+
+PVOID HalpEisaControlBase;
+PVOID HalpEisaMemoryBase;
+PVOID HalpRealTimeClockBase;
+
+BOOLEAN
+HalpMapIoSpace (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the HAL I/O space for a MIPS R3000 or R4000 Jazz
+ system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the initialization is successfully completed, than a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+#if defined(_R98B_)
+ //
+ // R98B EISA Control area can access KSEG1_BASE.
+ // N.B Implement below 64K
+ // But above 64K I/O area can't !!
+
+ //
+ // set EISA control space.
+ //
+
+ HalpEisaControlBase = (PVOID)(KSEG1_BASE + EISA_CNTL_PHYSICAL_BASE_LOW);
+
+ //
+ // set realtime clock registers.
+ //
+
+ HalpRealTimeClockBase = (PVOID)(KSEG1_BASE + RTCLOCK_PHYSICAL_BASE);
+ return TRUE;
+#else // #if !defined(_R98B_)
+
+ PHYSICAL_ADDRESS physicalAddress;
+
+ //
+ // Map EISA control space. Map all 16 slots. This is done so the NMI
+ // code can probe the cards.
+ //
+
+ physicalAddress.HighPart = 0;
+ physicalAddress.LowPart = EISA_CONTROL_PHYSICAL_BASE;
+ HalpEisaControlBase = MmMapIoSpace(physicalAddress,
+ PAGE_SIZE * 16,
+ FALSE);
+
+ //
+ // Map realtime clock registers.
+ //
+
+ physicalAddress.LowPart = RTCLOCK_PHYSICAL_BASE;
+ HalpRealTimeClockBase = MmMapIoSpace(physicalAddress,
+ PAGE_SIZE,
+ FALSE);
+
+ //
+ // If either mapped address is NULL, then return FALSE as the function
+ // value. Otherwise, return TRUE.
+ //
+
+
+ if ((HalpEisaControlBase == NULL) || (HalpRealTimeClockBase == NULL)) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+#endif // #if defined(_R98B_)
+
+}
diff --git a/private/ntos/nthals/halr98b/mips/jxmaptb.c b/private/ntos/nthals/halr98b/mips/jxmaptb.c
new file mode 100644
index 000000000..db2b8a931
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxmaptb.c
@@ -0,0 +1,68 @@
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxmaptb.c
+
+Abstract:
+
+ This module implements the mapping of fixed TB entries for a MIPS R98B
+ system. It also sets the instruction and data cache line sizes for a
+ R98 system.
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+#define HEADER_FILE
+#include "kxmips.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, HalpMapFixedTbEntries)
+
+#endif
+
+BOOLEAN
+HalpMapFixedTbEntries (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is return only.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ Returns TRUE.
+
+--*/
+
+{
+ return TRUE;
+}
+
+
+
+
+
+
diff --git a/private/ntos/nthals/halr98b/mips/jxport.c b/private/ntos/nthals/halr98b/mips/jxport.c
new file mode 100644
index 000000000..674276641
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxport.c
@@ -0,0 +1,779 @@
+
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxport.c
+
+Abstract:
+
+ This module implements the code that provides communication between
+ the kernel debugger on a MIPS R98system and the host
+ system.
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+#include "jazzserp.h"
+
+#define HEADER_FILE
+#include "kxmips.h"
+
+
+VOID
+HalpGetDivisorFromBaud(
+ IN ULONG ClockRate,
+ IN LONG DesiredBaud,
+ OUT PSHORT AppropriateDivisor
+ );
+
+
+#pragma alloc_text(INIT,HalpGetDivisorFromBaud)
+
+
+//
+// BUGBUG Temporarily, we use counter to do the timeout
+//
+
+#define TIMEOUT_COUNT 1024*512
+
+//
+// BUGBUG Temp until we have a configuration manager.
+//
+
+PUCHAR KdComPortInUse = NULL;
+BOOLEAN KdUseModemControl = FALSE;
+
+//
+// Define serial port read and write addresses.
+//
+
+#define SP_READ ((PSP_READ_REGISTERS )(SERIAL0_PHYSICAL_BASE|KSEG1_BASE))
+#define SP_WRITE ((PSP_WRITE_REGISTERS)(SERIAL0_PHYSICAL_BASE|KSEG1_BASE))
+
+//
+// Define forward referenced prototypes.
+//
+
+SP_LINE_STATUS
+KdReadLsr (
+ IN BOOLEAN WaitReason
+ );
+
+//
+// Define baud rate divisor to be used on the debugger port.
+//
+
+SHORT HalpBaudRateDivisor = 0;
+
+
+ULONG
+HalpGetByte (
+ IN PCHAR Input,
+ IN BOOLEAN Wait
+ )
+
+/*++
+
+Routine Description:
+
+ This routine gets a byte from the serial port used by the kernel
+ debugger.
+
+Arguments:
+
+ Input - Supplies a pointer to a variable that receives the input
+ data byte.
+
+ Wait - Supplies a boolean value that detemines whether a timeout
+ is applied to the input operation.
+
+Return Value:
+
+ CP_GET_SUCCESS is returned if a byte is successfully read from the
+ kernel debugger line.
+
+ CP_GET_ERROR is returned if an error is encountered during reading.
+
+ CP_GET_NODATA is returned if timeout occurs.
+
+--*/
+
+{
+
+ SP_LINE_STATUS LsrByte;
+ UCHAR DataByte;
+ ULONG TimeoutCount;
+
+ //
+ // Attempt to read a byte from the debugger port until a byte is
+ // available or until a timeout occurs.
+ //
+
+ TimeoutCount = Wait ? TIMEOUT_COUNT : 1;
+ do {
+ TimeoutCount -= 1;
+
+ //
+ // Wait until data is available in the receive buffer.
+ //
+
+ KeStallExecutionProcessor(1);
+ LsrByte = KdReadLsr(TRUE);
+ if (LsrByte.DataReady == 0) {
+ continue;
+ }
+
+ //
+ // Read input byte and store in callers buffer.
+ //
+
+ *Input = READ_REGISTER_UCHAR(&SP_READ->ReceiveBuffer);
+
+ //
+ // If using modem controls, then skip any incoming data while
+ // ReceiveData not set.
+ //
+
+ if (KdUseModemControl) {
+ DataByte = READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
+ if ( ((PSP_MODEM_STATUS)&DataByte)->ReceiveDetect == 0) {
+ continue;
+ }
+ }
+
+ //
+ // Return function value as the not of the error indicators.
+ //
+
+ if (LsrByte.ParityError ||
+ LsrByte.FramingError ||
+ LsrByte.OverrunError ||
+ LsrByte.BreakIndicator) {
+ return CP_GET_ERROR;
+ }
+
+ return CP_GET_SUCCESS;
+ } while(TimeoutCount != 0);
+
+ return CP_GET_NODATA;
+}
+
+BOOLEAN
+KdPortInitialize (
+ PDEBUG_PARAMETERS DebugParameters,
+ PLOADER_PARAMETER_BLOCK LoaderBlock,
+ BOOLEAN Initialize
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the serial port used by the kernel debugger
+ and must be called during system initialization.
+
+Arguments:
+
+ DebugParameter - Supplies a pointer to the debug port parameters.
+
+ LoaderBlock - Supplies a pointer to the loader parameter block.
+
+ Initialize - Specifies a boolean value that determines whether the
+ debug port is initialized or just the debug port parameters
+ are captured.
+
+Return Value:
+
+ A value of TRUE is returned is the port was successfully initialized.
+ Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+ PCONFIGURATION_COMPONENT_DATA ConfigurationEntry;
+ UCHAR DataByte;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
+ PCM_SERIAL_DEVICE_DATA DeviceData;
+ PCM_PARTIAL_RESOURCE_LIST List;
+ ULONG MatchKey;
+ ULONG BaudRate;
+ ULONG BaudClock;
+
+
+ //
+ // Find the configuration information for the first serial port.
+ //
+
+ if (LoaderBlock != NULL) {
+ MatchKey = 0;
+ ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
+ ControllerClass,
+ SerialController,
+ &MatchKey);
+
+ } else {
+ ConfigurationEntry = NULL;
+ }
+
+ if (DebugParameters->BaudRate != 0) {
+ BaudRate = DebugParameters->BaudRate;
+ } else {
+ BaudRate = 19200;
+ }
+
+ //
+ // If the serial configuration entry was not found or the frequency
+ // specified is not supported, then default the baud clock to 800000.
+ //
+
+ BaudClock = 8000000;
+ if (ConfigurationEntry != NULL) {
+ List = (PCM_PARTIAL_RESOURCE_LIST)ConfigurationEntry->ConfigurationData;
+ Descriptor = &List->PartialDescriptors[List->Count];
+ DeviceData = (PCM_SERIAL_DEVICE_DATA)Descriptor;
+ if ((DeviceData->BaudClock == 1843200) ||
+ (DeviceData->BaudClock == 4233600) ||
+ (DeviceData->BaudClock == 8000000)) {
+ BaudClock = DeviceData->BaudClock;
+ }
+ }
+
+ HalpGetDivisorFromBaud(
+ BaudClock,
+ BaudRate,
+ &HalpBaudRateDivisor
+ );
+
+ //
+ // If the debugger is not being enabled, then return.
+ //
+
+ if (Initialize == FALSE) {
+ return TRUE;
+ }
+
+ KdComPortInUse=(PUCHAR)SERIAL0_PHYSICAL_BASE;
+
+
+ //
+ // Clear the divisor latch, clear all interrupt enables, and reset and
+ // disable the FIFO's.
+ //
+
+ WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, 0x0);
+ WRITE_REGISTER_UCHAR(&SP_WRITE->InterruptEnable, 0x0);
+ DataByte = 0;
+ ((PSP_FIFO_CONTROL)(&DataByte))->ReceiveFifoReset = 1;
+ ((PSP_FIFO_CONTROL)(&DataByte))->TransmitFifoReset = 1;
+ WRITE_REGISTER_UCHAR(&SP_WRITE->FifoControl, DataByte);
+
+ //
+ // Set the divisor latch and set the baud rate.
+ //
+ ((PSP_LINE_CONTROL)(&DataByte))->DivisorLatch = 1;
+ WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, DataByte);
+ WRITE_REGISTER_UCHAR(&SP_WRITE->TransmitBuffer,(UCHAR)(HalpBaudRateDivisor&0xFF));
+
+ WRITE_REGISTER_UCHAR(&SP_WRITE->InterruptEnable,(UCHAR)(HalpBaudRateDivisor>>8));
+
+ //
+ // Clear the divisor latch and set the character size to eight bits
+ // with one stop bit and no parity checking.
+ //
+
+ DataByte = 0;
+ ((PSP_LINE_CONTROL)(&DataByte))->CharacterSize = EIGHT_BITS;
+ WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, DataByte);
+
+ //
+ // Set data terminal ready and request to send.
+ //
+
+ DataByte = 0;
+ ((PSP_MODEM_CONTROL)(&DataByte))->DataTerminalReady = 1;
+ ((PSP_MODEM_CONTROL)(&DataByte))->RequestToSend = 1;
+ WRITE_REGISTER_UCHAR(&SP_WRITE->ModemControl, DataByte);
+
+ //
+ // Free the TB entry if one was allocated.
+ //
+ return TRUE;
+}
+
+ULONG
+KdPortGetByte (
+ OUT PUCHAR Input
+ )
+
+/*++
+
+Routine Description:
+
+ This routine gets a byte from the serial port used by the kernel
+ debugger.
+
+ N.B. It is assumed that the IRQL has been raised to the highest
+ level, and necessary multiprocessor synchronization has been
+ performed before this routine is called.
+
+Arguments:
+
+ Input - Supplies a pointer to a variable that receives the input
+ data byte.
+
+Return Value:
+
+ CP_GET_SUCCESS is returned if a byte is successfully read from the
+ kernel debugger line.
+
+ CP_GET_ERROR is returned if an error is encountered during reading.
+
+ CP_GET_NODATA is returned if timeout occurs.
+
+--*/
+
+{
+
+ return HalpGetByte(Input, TRUE);
+}
+
+ULONG
+KdPortPollByte (
+ OUT PUCHAR Input
+ )
+
+/*++
+
+Routine Description:
+
+ This routine gets a byte from the serial port used by the kernel
+ debugger iff a byte is available.
+
+ N.B. It is assumed that the IRQL has been raised to the highest
+ level, and necessary multiprocessor synchronization has been
+ performed before this routine is called.
+
+Arguments:
+
+ Input - Supplies a pointer to a variable that receives the input
+ data byte.
+
+Return Value:
+
+ CP_GET_SUCCESS is returned if a byte is successfully read from the
+ kernel debugger line.
+
+ CP_GET_ERROR is returned if an error encountered during reading.
+
+ CP_GET_NODATA is returned if timeout occurs.
+
+--*/
+
+{
+
+ ULONG Status;
+
+ //
+ // Save port status, map the serial controller, get byte from the
+ // debugger port is one is avaliable, restore port status, unmap
+ // the serial controller, and return the operation status.
+ //
+
+ KdPortSave();
+ Status = HalpGetByte(Input, FALSE);
+ KdPortRestore();
+ return Status;
+}
+
+VOID
+KdPortPutByte (
+ IN UCHAR Output
+ )
+
+/*++
+
+Routine Description:
+
+ This routine puts a byte to the serial port used by the kernel debugger.
+
+ N.B. It is assumed that the IRQL has been raised to the highest level,
+ and necessary multiprocessor synchronization has been performed
+ before this routine is called.
+
+Arguments:
+
+ Output - Supplies the output data byte.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ UCHAR DataByte;
+
+ if (KdUseModemControl) {
+ //
+ // Modem control, make sure DSR, CTS and CD are all set before
+ // sending any data.
+ //
+
+ for (; ;) {
+ DataByte = READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
+ if ( ((PSP_MODEM_STATUS)&DataByte)->ClearToSend &&
+ ((PSP_MODEM_STATUS)&DataByte)->DataSetReady &&
+ ((PSP_MODEM_STATUS)&DataByte)->ReceiveDetect ) {
+ break;
+ }
+
+ KdReadLsr(FALSE);
+ }
+ }
+
+ //
+ // Wait for transmit ready.
+ //
+
+ while (KdReadLsr(FALSE).TransmitHoldingEmpty == 0 );
+
+ //
+ // Wait for data set ready.
+ //
+
+// do {
+// LsrByte = READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
+// } while (((PSP_MODEM_STATUS)(&LsrByte))->DataSetReady == 0);
+
+ //
+ // Transmit data.
+ //
+
+ WRITE_REGISTER_UCHAR(&SP_WRITE->TransmitBuffer, Output);
+ return;
+}
+
+VOID
+KdPortRestore (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine restores the state of the serial port after the kernel
+ debugger has been active.
+
+ N.B. This routine performs no function on the Jazz system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Free the TB entry if one was allocated.
+ //
+ return;
+}
+
+VOID
+KdPortSave (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine saves the state of the serial port and initializes the port
+ for use by the kernel debugger.
+
+ N.B. This routine performs no function on the Jazz system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ return;
+}
+
+SP_LINE_STATUS
+KdReadLsr (
+ IN BOOLEAN WaitReason
+ )
+
+/*++
+
+Routine Description:
+
+ Returns current line status.
+
+ If status which is being waited for is ready, then the function
+ checks the current modem status and causes a possible display update
+ of the current statuses.
+
+Arguments:
+
+ WaitReason - Suuplies a boolean value that determines whether the line
+ status is required for a receive or transmit.
+
+Return Value:
+
+ The current line status is returned as the function value.
+
+--*/
+
+{
+
+ static UCHAR RingFlag = 0;
+ UCHAR DataLsr, DataMsr;
+
+ //
+ // Get the line status for a recevie or a transmit.
+ //
+
+ DataLsr = READ_REGISTER_UCHAR(&SP_READ->LineStatus);
+ if (WaitReason) {
+
+ //
+ // Get line status for receive data.
+ //
+
+ if (((PSP_LINE_STATUS)&DataLsr)->DataReady) {
+ return *((PSP_LINE_STATUS)&DataLsr);
+ }
+
+ } else {
+
+ //
+ // Get line status for transmit empty.
+ //
+
+ if (((PSP_LINE_STATUS)&DataLsr)->TransmitEmpty) {
+ return *((PSP_LINE_STATUS)&DataLsr);
+ }
+ }
+
+ DataMsr = READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
+ RingFlag |= ((PSP_MODEM_STATUS)&DataMsr)->RingIndicator ? 1 : 2;
+ if (RingFlag == 3) {
+
+ //
+ // The ring indicate line has toggled, use modem control from
+ // now on.
+ //
+
+ KdUseModemControl = TRUE;
+ }
+
+ return *((PSP_LINE_STATUS) &DataLsr);
+}
+
+VOID
+HalpGetDivisorFromBaud(
+ IN ULONG ClockRate,
+ IN LONG DesiredBaud,
+ OUT PSHORT AppropriateDivisor
+ )
+
+/*++
+
+Routine Description:
+
+ This routine will determine a divisor based on an unvalidated
+ baud rate.
+
+Arguments:
+
+ ClockRate - The clock input to the controller.
+
+ DesiredBaud - The baud rate for whose divisor we seek.
+
+ AppropriateDivisor - Given that the DesiredBaud is valid, the
+ SHORT pointed to by this parameter will be set to the appropriate
+ value. If the requested baud rate is unsupportable on the machine
+ return a divisor appropriate for 19200.
+
+Return Value:
+
+ none.
+
+--*/
+
+{
+
+ SHORT calculatedDivisor;
+ ULONG denominator;
+ ULONG remainder;
+
+ //
+ // Allow up to a 1 percent error
+ //
+
+ ULONG maxRemain18 = 18432;
+ ULONG maxRemain30 = 30720;
+ ULONG maxRemain42 = 42336;
+ ULONG maxRemain80 = 80000;
+ ULONG maxRemain;
+
+ //
+ // Reject any non-positive bauds.
+ //
+
+ denominator = DesiredBaud*(ULONG)16;
+
+ if (DesiredBaud <= 0) {
+
+ *AppropriateDivisor = -1;
+
+ } else if ((LONG)denominator < DesiredBaud) {
+
+ //
+ // If the desired baud was so huge that it cause the denominator
+ // calculation to wrap, don't support it.
+ //
+
+ *AppropriateDivisor = -1;
+
+ } else {
+
+ if (ClockRate == 1843200) {
+ maxRemain = maxRemain18;
+ } else if (ClockRate == 3072000) {
+ maxRemain = maxRemain30;
+ } else if (ClockRate == 4233600) {
+ maxRemain = maxRemain42;
+ } else {
+ maxRemain = maxRemain80;
+ }
+
+ calculatedDivisor = (SHORT)(ClockRate / denominator);
+ remainder = ClockRate % denominator;
+
+ //
+ // Round up.
+ //
+
+ if (((remainder*2) > ClockRate) && (DesiredBaud != 110)) {
+
+ calculatedDivisor++;
+ }
+
+
+ //
+ // Only let the remainder calculations effect us if
+ // the baud rate is > 9600.
+ //
+
+ if (DesiredBaud >= 9600) {
+
+ //
+ // If the remainder is less than the maximum remainder (wrt
+ // the ClockRate) or the remainder + the maximum remainder is
+ // greater than or equal to the ClockRate then assume that the
+ // baud is ok.
+ //
+
+ if ((remainder >= maxRemain) && ((remainder+maxRemain) < ClockRate)) {
+ calculatedDivisor = -1;
+ }
+
+ }
+
+ //
+ // Don't support a baud that causes the denominator to
+ // be larger than the clock.
+ //
+
+ if (denominator > ClockRate) {
+
+ calculatedDivisor = -1;
+
+ }
+
+ //
+ // Ok, Now do some special casing so that things can actually continue
+ // working on all platforms.
+ //
+
+ if (ClockRate == 1843200) {
+
+ if (DesiredBaud == 56000) {
+ calculatedDivisor = 2;
+ }
+
+ } else if (ClockRate == 3072000) {
+
+ if (DesiredBaud == 14400) {
+ calculatedDivisor = 13;
+ }
+
+ } else if (ClockRate == 4233600) {
+
+ if (DesiredBaud == 9600) {
+ calculatedDivisor = 28;
+ } else if (DesiredBaud == 14400) {
+ calculatedDivisor = 18;
+ } else if (DesiredBaud == 19200) {
+ calculatedDivisor = 14;
+ } else if (DesiredBaud == 38400) {
+ calculatedDivisor = 7;
+ } else if (DesiredBaud == 56000) {
+ calculatedDivisor = 5;
+ }
+
+ } else if (ClockRate == 8000000) {
+
+ if (DesiredBaud == 14400) {
+ calculatedDivisor = 35;
+ } else if (DesiredBaud == 56000) {
+ calculatedDivisor = 9;
+ }
+
+ }
+
+ *AppropriateDivisor = calculatedDivisor;
+
+ }
+
+
+ if (*AppropriateDivisor == -1) {
+
+ HalpGetDivisorFromBaud(
+ ClockRate,
+ 19200,
+ AppropriateDivisor
+ );
+
+ }
+
+
+}
diff --git a/private/ntos/nthals/halr98b/mips/jxreturn.c b/private/ntos/nthals/halr98b/mips/jxreturn.c
new file mode 100644
index 000000000..58340ee80
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxreturn.c
@@ -0,0 +1,181 @@
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxreturn.c
+
+Abstract:
+
+ This module implements the HAL return to firmware function.
+
+--*/
+
+/*
+ * S001 1995/12/01 T.Samezima
+ * add x86 bios logic
+ *
+ */
+
+#include "halp.h"
+#define HEADER_FILE
+#include "kxmips.h"
+
+//
+// Define keyboard registers structure.
+//
+
+typedef struct _KBD_REGISTERS {
+ union {
+ UCHAR Output;
+ UCHAR Input;
+ } Data;
+ UCHAR Pad0;
+ UCHAR Pad1;
+ UCHAR Pad2;
+ 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;
+ ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp; //S001
+
+ volatile KBD_REGISTERS * KbdBase = (KBD_REGISTERS *)(KEYBOARD_PHYSICAL_BASE|KSEG1_BASE);
+ //
+ // Disable Interrupts.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ //
+ // Case on the type of return.
+ //
+
+ switch (Routine) {
+ case HalHaltRoutine:
+
+ //
+ // Hang looping.
+ //
+
+ for (;;) {
+ }
+
+ case HalPowerDownRoutine:
+
+ // S001 vvv
+ //
+ // Reset ISA Display Adapter to 80x25 color text mode.
+ //
+
+ Eax = 0x12; // AH = 0 AL = 0x12
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+ // S001 ^^^
+
+ //
+ // Send Powerdown Command to the MRC.
+ //
+
+ for (;TRUE;) {
+ {
+ UCHAR Data;
+ Data = 0x1;
+ HalpLocalDeviceReadWrite(MRC_SWPOWEROFF, &Data, LOCALDEV_OP_WRITE);
+ }
+ }
+
+ case HalRestartRoutine:
+ case HalRebootRoutine:
+ case HalInteractiveModeRoutine:
+#if 1
+ {
+#if 0
+ DbgPrint("Hal return 0\n");
+#endif
+ HalpMrcModeChange((UCHAR)MRC_OP_DUMP_AND_POWERSW_NMI);
+#if 0
+ DbgPrint("Hal return 1\n");
+#endif
+
+ }
+#endif
+
+
+ // S001 vvv
+ //
+ // Reset ISA Display Adapter to 80x25 color text mode.
+ //
+
+ Eax = 0x12; // AH = 0 AL = 0x12
+ HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
+ // S001 ^^^
+
+ //
+ // Reset ISA Display Adapter to 80x25 color text mode.
+ //
+
+ HalpResetX86DisplayAdapter();
+
+ //
+ // 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/halr98b/mips/jxsysint.c b/private/ntos/nthals/halr98b/mips/jxsysint.c
new file mode 100644
index 000000000..ad8ddc460
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxsysint.c
@@ -0,0 +1,327 @@
+
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxsysint.c
+
+Abstract:
+
+ This module implements the HAL enable/disable system interrupt, and
+ request interprocessor interrupt routines for R98B
+
+--*/
+
+
+#include "halp.h"
+
+
+//
+// Define Ipi Interrupt Reqest value table.
+// Index is Mask
+// IntIR register target Cpu bit is Not Mask.
+// Mask High Bit is IntIR Target CPU Bit Low.
+//
+ULONG HalpIpiIntRequestMask[] = {
+ IntIR_REQUEST_IPI | (0), //0: error!!.
+ IntIR_REQUEST_IPI | (ToNODE4), //1: to CPU #0
+ IntIR_REQUEST_IPI | ( ToNODE5), //2: to CPU #1
+ IntIR_REQUEST_IPI | (ToNODE4|ToNODE5 ), //3: to CPU #0 #1
+ IntIR_REQUEST_IPI | ( ToNODE6), //4: to CPU #2
+ IntIR_REQUEST_IPI | (ToNODE4| ToNODE6), //5: to CPU #0 #2
+ IntIR_REQUEST_IPI | ( ToNODE5|ToNODE6), //6: to CPU #1 #2
+ IntIR_REQUEST_IPI | (ToNODE4|ToNODE5|ToNODE6 ), //7: to CPU #0 #1 #2
+ IntIR_REQUEST_IPI | ( ToNODE7), //8: to CPU #3
+ IntIR_REQUEST_IPI | (ToNODE4| ToNODE7), //9: to CPU #0 #3
+ IntIR_REQUEST_IPI | ( ToNODE5| ToNODE7), //10:to CPU #1 #3
+ IntIR_REQUEST_IPI | (ToNODE4|ToNODE5| ToNODE7), //11:to CPU #0 #1 #3
+ IntIR_REQUEST_IPI | ( ToNODE6|ToNODE7), //12:to CPU #2 #3
+ IntIR_REQUEST_IPI | (ToNODE4| ToNODE6|ToNODE7), //13:to CPU #0 #2 #3
+ IntIR_REQUEST_IPI | ( ToNODE5|ToNODE6|ToNODE7), //14:to CPU #1 #2 #3
+ IntIR_REQUEST_IPI | (ToNODE4|ToNODE5|ToNODE6|ToNODE7) //15:to CPU #0 #1 #2 #3
+
+ };
+
+
+extern ULONG HalpLogicalCPU2PhysicalCPU[R98B_MAX_CPU];
+
+ULONG
+HalpAffinity2Physical (
+ IN ULONG Mask
+ );
+
+
+
+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);
+
+#if defined(DBG3)
+ DbgPrint("HAL Vector Disable Vector=0x%x\n",Vector);
+#endif
+
+
+
+ //
+ // If the vector number is within the range of the EISA interrupts, then
+ // disable the EISA interrrupt.
+ //
+ if (Vector >= EISA_VECTORS && Vector <= MAXIMUM_EISA_VECTORS){
+#if defined(DBG3)
+ DbgPrint("HAL Vector Disable EISA=0x%x\n",Vector);
+#endif
+
+ HalpDisableEisaInterrupt(Vector);
+ }
+
+ //
+ // If the vector number is within the range of builtin devices, then
+ // disable the builtin device interrupt.
+ //
+ //
+ // If the vector number is within the range of the PCI interrupts, then
+ // disable the PCI interrrupt.
+ //
+
+ if ((Vector >= (DEVICE_VECTORS )) && (Vector <= MAXIMUM_DEVICE_VECTORS)) {
+#if defined(DBG3)
+ DbgPrint("HAL Vector DIable EISA=0x%x\n",Vector);
+#endif
+
+ HalpInterruptFromPonce(Vector,0);
+ }
+
+ //
+ // Release the device enable spin loc and lower IRQL to the previous level.
+ //
+
+ KeLowerIrql(OldIrql);
+ return;
+}
+
+BOOLEAN
+HalEnableSystemInterrupt (
+ IN ULONG Vector,
+ IN KIRQL Irql,
+ IN KINTERRUPT_MODE InterruptMode
+ )
+
+/*++
+
+Routine Description:
+
+ This routine enables the specified system interrupt.
+
+Arguments:
+
+ Vector - Supplies the vector of the system interrupt that is enabled.
+
+ Irql - Supplies the IRQL of the interrupting source.
+
+ InterruptMode - Supplies the mode of the interrupt; LevelSensitive or
+ Latched.
+
+Return Value:
+
+ TRUE if the system interrupt was enabled
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+
+ //
+ // Raise IRQL to the highest level and acquire device enable spinlock.
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+#if defined(DBG3)
+ DbgPrint("HAL Vector Enable in =0x%x\n",Vector);
+#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 <= MAXIMUM_EISA_VECTORS){
+#if DBG
+ DbgPrint("HAL Vector Enable EISA=0x%x\n",Vector);
+#endif
+
+ HalpEnableEisaInterrupt( Vector, InterruptMode);
+ }
+
+ //
+ // If the vector number is within the range of builtin devices, then
+ // enable the builtin device interrupt.
+ //
+ // If the vector number is within the range of the PCI interrupts, then
+ // disable the PCI interrrupt.
+ //
+
+ if ((Vector >= (DEVICE_VECTORS )) && (Vector <= MAXIMUM_DEVICE_VECTORS)) {
+#if defined(DBG3)
+ DbgPrint("HAL Vector Enable internal or PCI=0x%x\n",Vector);
+#endif
+
+ //
+ // enable interrupt from ponce.
+ //
+ HalpInterruptFromPonce(Vector,1);
+ }
+
+#if defined(DBG3)
+ DbgPrint("HAL Vector Enable Out =0x%x\n",Vector);
+#endif
+
+ //
+ // Release the device enable spin loc and lower IRQL to the previous level.
+ //
+
+ KeLowerIrql(OldIrql);
+ return TRUE;
+}
+
+//
+// IPI function.
+//
+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.
+
+--*/
+
+{
+
+ ULONG IntIR;
+
+
+
+ ULONG Maskp;
+ ULONG PhysicalNumber;
+
+ if(!Mask){
+ return;
+ }
+
+ Maskp=HalpAffinity2Physical(Mask);
+ PhysicalNumber=HalpLogicalCPU2PhysicalCPU[(ULONG)((PCR->Prcb)->Number)];
+
+
+ //
+ // Request an interprocessor interrupt on each of the specified target
+ // processors.
+ //
+ IntIR = HalpIpiIntRequestMask[(Maskp & 0xf)] |
+ ( (ATLANTIC_CODE_IPI_FROM_CPU0 + PhysicalNumber) << IntIR_CODE_BIT);
+
+#if defined(DBG3)
+ DbgPrint("IntIR = 0x%x\n",IntIR);
+#endif
+
+ //
+ // write IntIR Register. make ipi!!
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->IntIR,IntIR);
+
+ return;
+}
+
+
+
+ULONG
+HalpAffinity2Physical (
+ IN ULONG Mask
+ )
+
+
+/*++
+
+Routine Description:
+
+ This routine translate logical affinity into physical affinity.
+
+Arguments:
+
+ Mask Losical Affinity
+
+Return Value:
+
+ Physical Affinity
+
+--*/
+{
+
+ ULONG i,j,PhysicalAffinity;
+
+ i=0;
+ j=0;
+ PhysicalAffinity=0;
+
+ for(i=0;i<4;i++){
+
+ if(Mask&0x1==0x1){
+ j=HalpLogicalCPU2PhysicalCPU[i];
+ PhysicalAffinity=PhysicalAffinity|(0x1<<j);
+ }
+ Mask=(Mask>>1);
+ }
+
+ return PhysicalAffinity;
+}
+
diff --git a/private/ntos/nthals/halr98b/mips/jxtime.c b/private/ntos/nthals/halr98b/mips/jxtime.c
new file mode 100644
index 000000000..c2678cd45
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxtime.c
@@ -0,0 +1,319 @@
+#ident "@(#) NEC jxtime.c 1.4 94/11/22 20:09:27"
+/*++
+
+Copyright (c) 1991-1994 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.
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+/*
+ * Original source: Build Number 1.612
+ *
+ * Modify for R98(MIPS/R4400)
+ *
+ ***********************************************************************
+ *
+ * S001 94.03/23 T.Samezima
+ *
+ * Change Irql Level
+ *
+ ***********************************************************************
+ *
+ * S002 94.07/5 T.Samezima
+ *
+ * Change Register access mask
+ *
+ *
+ */
+
+#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.
+ //
+
+#if defined(NT_40)
+ KeRaiseIrql( HIGH_LEVEL, &OldIrql);
+#else
+ KeRaiseIrql((KIRQL)(INT0_LEVEL+HalpIntLevelofIpr[HalpMachineCpu][CLOCK_VECTOR - DEVICE_VECTORS]), &OldIrql);
+#endif
+
+ 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.
+ //
+
+#if defined(NT_40)
+ KeRaiseIrql( HIGH_LEVEL, &OldIrql);
+#else
+ KeRaiseIrql((KIRQL)(INT0_LEVEL+HalpIntLevelofIpr[HalpMachineCpu][CLOCK_VECTOR - DEVICE_VECTORS]), &OldIrql);
+#endif
+
+ 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.
+
+--*/
+
+{
+
+ //
+ // 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.
+ //
+
+ /* Start S002 */
+ Register |= 0x80;
+ /* End S002 */
+
+ WRITE_REGISTER_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable,
+ Register);
+
+ //
+ // Read the realtime clock register value.
+ //
+
+ return READ_REGISTER_UCHAR((PUCHAR)HalpRealTimeClockBase);
+}
+
+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.
+
+--*/
+
+{
+
+ //
+ // 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.
+ //
+
+ /* Start S002 */
+ Register |= 0x80;
+ /* End S002 */
+
+ WRITE_REGISTER_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable,
+ Register);
+
+ //
+ // Write the realtime clock register value.
+ //
+
+ WRITE_REGISTER_UCHAR((PUCHAR)HalpRealTimeClockBase, Value);
+ return;
+}
diff --git a/private/ntos/nthals/halr98b/mips/jxusage.c b/private/ntos/nthals/halr98b/mips/jxusage.c
new file mode 100644
index 000000000..2d6809693
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/jxusage.c
@@ -0,0 +1,541 @@
+
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ jxusage.c
+
+Abstract:
+
+Author:
+
+ Ken Reneris (kenr)
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+
+//
+// Array to remember hal's IDT usage
+//
+#if !defined(_R98B_) // CMP001
+extern ADDRESS_USAGE *HalpAddressUsageList;
+extern IDTUsage HalpIDTUsage[MAXIMUM_IDTVECTOR];
+#endif // _R98B_
+
+UCHAR HalName[] = "NEC Mips HAL Frontier 3.00";
+
+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 (_R98B_)
+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 // _R98B_
+
+
+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;
+
+
+ //
+ // 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(_R98B_)
+ for(i=0; i < EISA_VECTORS; i++) {
+ 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) {
+ //
+ // 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);
+}
+
+
+VOID
+HalReportResourceUsage(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+
+ ANSI_STRING AHalName;
+ UNICODE_STRING UHalName;
+
+ RtlInitAnsiString (&AHalName, HalName);
+ RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE);
+
+ HalpReportResourceUsage (
+ &UHalName, // descriptive name
+#if 1
+ PCIBus // device space interface type
+#else
+ Internal
+#endif
+ );
+
+ RtlFreeUnicodeString (&UHalName);
+
+ // Get PCI RegInfo.
+ //
+ //
+ //
+ HalpInitializePciBus ();
+
+ //
+ // SVP Board Check!!
+ //
+ HalpSVPSlotDetect();
+#if DBG
+ HalpDisplayAllBusRanges();
+ DbgPrint("HAL Report finished\n");
+#endif
+}
+
diff --git a/private/ntos/nthals/halr98b/mips/mipsdat.c b/private/ntos/nthals/halr98b/mips/mipsdat.c
new file mode 100644
index 000000000..e50fbfe7e
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/mipsdat.c
@@ -0,0 +1,137 @@
+/*++
+
+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:
+
+
+--*/
+
+#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 R98_MAPREGISTER_BASE 100
+
+
+ADDRESS_USAGE HalpMapRegisterMemorySpace = {
+ NULL, CmResourceTypeMemory, InternalUsage,
+ {
+ R98_MAPREGISTER_BASE, (USHORT)(DMA_TRANSLATION_LIMIT/(sizeof(TRANSLATION_ENTRY))*PAGE_SIZE), // for Map Register Area CMP001
+ 0, 0
+ }
+};
+
+//
+// from ixdat.c
+//
+
+UCHAR HalpSzBreak[] = "BREAK";
+UCHAR HalpSzPciLock[] = "PCILOCK";
+
+//
+// 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
+//
+//
+#if defined(MIPS)
+IDTUsage HalpIDTUsage[MAXIMUM_VECTOR]; // Size of PCR->InterruptRoutine[]
+#else
+IDTUsage HalpIDTUsage[MAXIMUM_IDTVECTOR];
+#endif
+
diff --git a/private/ntos/nthals/halr98b/mips/mode542x.h b/private/ntos/nthals/halr98b/mips/mode542x.h
new file mode 100644
index 000000000..00445a6d9
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/mode542x.h
@@ -0,0 +1,1302 @@
+#ident "@(#) NEC mode542x.h 1.3 95/07/05 13:10:57"
+/*++
+
+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/halr98b/mips/modeset.h b/private/ntos/nthals/halr98b/mips/modeset.h
new file mode 100644
index 000000000..b699eacc7
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/modeset.h
@@ -0,0 +1,86 @@
+#ident "@(#) NEC modeset.h 1.1 94/07/05 14:06:24"
+/* #pragma comment(exestr, "@(#) NEC(MIPS) modeset.h 1.3 93/10/29 12:25:59" ) */
+/*++
+
+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/halr98b/mips/pcip.h b/private/ntos/nthals/halr98b/mips/pcip.h
new file mode 100644
index 000000000..d0337f7d3
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/pcip.h
@@ -0,0 +1,189 @@
+#ident "@(#) NEC pcip.h 1.4 95/06/19 11:13:40"
+
+//
+// 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_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)
+
+
+#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
+ );
+
+NTSTATUS
+HalpGetISAFixedPCIIrq (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER PciSlot,
+ OUT PSUPPORTED_RANGE *Interrupt
+ );
+
+
+VOID
+HalpPCIPin2SystemLine (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciData
+ );
+
+VOID
+HalpPCISystemLine2Pin (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PPCI_COMMON_CONFIG PciNewData,
+ IN PPCI_COMMON_CONFIG PciOldData
+ );
+
+
+//
+// Prototypes for functions in ixpcibrd.c
+//
+
+BOOLEAN
+HalpGetPciBridgeConfig (
+ IN ULONG HwType,
+ IN ULONG StartPciBus, //R98B
+ 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/halr98b/mips/r98bdef.h b/private/ntos/nthals/halr98b/mips/r98bdef.h
new file mode 100644
index 000000000..6166a583e
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/r98bdef.h
@@ -0,0 +1,228 @@
+/*
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ r98bdef.h
+
+Abstract:
+
+ This module is the header file that describes hardware addresses
+ for the r98B system.
+
+Author:
+
+
+
+Revision History:
+
+--*/
+
+#ifndef _R98BDEF_
+#define _R98BDEF_
+
+//
+// Define the size of the DMA translation table.
+//
+#define DMA_TRANSLATION_LIMIT 0x5000 // translation table limit
+
+//
+// Define the maximum number of map registers allowed per allocation.
+//
+// 2M 2M 2M
+// + PONCE0: PONCE1:
+// | | |
+// | +-------------+
+// +
+// +
+// EISA/ISA
+// Max 3 Slot + Internal Floppy(Use ESC DMA channel #2) = 4 --> 512K *4 = 2M
+//
+// 2M is for 1M Logical Area Reserv!!.
+//
+#define DMA_TRANSLATION_RESERV 0x1000 // 4k /8 = 2M
+#define DMA_REQUEST_LIMIT ((DMA_TRANSLATION_LIMIT-DMA_TRANSLATION_RESERV)/(sizeof(TRANSLATION_ENTRY) * 16))
+//
+//#define DMA_REQUEST_LIMIT (DMA_TRANSLATION_LIMIT/(sizeof(TRANSLATION_ENTRY) * 4))
+//
+// N.B
+// May be 1 page reserved for PCEB Prefetch cycle.
+// It Cause Ponce I/O TLB page fault.
+//
+#define DMA_REQUEST_EISA_LIMIT (DMA_REQUEST_LIMIT-1)
+#define EISA_MAX_DEVICE 3
+
+
+#define R98B_MAX_CPU 4
+
+#define R98B_MAX_MAGELLAN 2
+
+#define R98B_MAX_PONCE 3 //R100
+
+#define R98_CPU_R4400 0
+#define R98_CPU_R10000 1
+#define R98_CPU_NUM_TYPE 2
+
+#define DEVICE_VECTORS 32
+#define EISA_DISPATCH_VECTOR (13+DEVICE_VECTORS)
+#define PARALLEL_VECTOR (14+DEVICE_VECTORS) // Parallel device interrupt vector
+#define NET_VECTOR (29+DEVICE_VECTORS) // ethernet device interrupt vector
+#define SCSI0_VECTOR (31+DEVICE_VECTORS) // SCSI device interrupt vector
+#define SCSI1_VECTOR (30+DEVICE_VECTORS) // SCSI device interrupt vector
+#define UNDEFINE_TLB_VECTOR (35+DEVICE_VECTORS) // TLB undefine address interrupt vector
+#define MOUSE_VECTOR (36+DEVICE_VECTORS) // Mouse device interrupt vector
+#define KEYBOARD_VECTOR (37+DEVICE_VECTORS) // Keyboard device interrupt vector
+#define SERIAL1_VECTOR (38+DEVICE_VECTORS) // Serial device 1 interrupt vector
+#define SERIAL0_VECTOR (39+DEVICE_VECTORS) // Serial device 0 interrupt vector
+#define IPI_VECTOR3 (48+DEVICE_VECTORS) // IPI From #3
+#define IPI_VECTOR2 (49+DEVICE_VECTORS) // IPI From #2
+#define IPI_VECTOR1 (50+DEVICE_VECTORS) // IPI From #1
+#define IPI_VECTOR0 (51+DEVICE_VECTORS) // IPI From #0
+#define PROFILE_VECTOR (56+DEVICE_VECTORS) // Define Profile interrupt vector
+#define CLOCK_VECTOR (57+DEVICE_VECTORS) // Define Clock interrupt vector
+
+#define EIF_VECTOR (61+DEVICE_VECTORS) // EIF Vector
+
+#define ECC_1BIT_VECTOR (62+DEVICE_VECTORS) // ECC 1bit Error interrupt vector
+
+//SNES #define MAXIMUM_DEVICE_VECTORS 43 // IPR Bit 43
+#define MAXIMUM_DEVICE_VECTORS (43+DEVICE_VECTORS)
+//
+// Define EISA device interrupt vectors.
+//
+#define EISA_VECTORS 16
+#define MAXIMUM_EISA_VECTORS (15 + EISA_VECTORS) // maximum EISA vector
+
+#define INT0_LEVEL 3 // PCR->InterruptRoutine[3]
+#define INT1_LEVEL 4 // PCR->InterruptRoutine[4]
+#define INT2_LEVEL 5 // PCR->InterruptRoutine[5]
+#define INT3_LEVEL 6 // PCR->InterruptRoutine[6]
+#define INT4_LEVEL 7 // PCR->InterruptRoutine[7]
+#define INT5_LEVEL 8 // PCR->InterruptRoutine[8]
+
+#define EISA_LEVEL INT0_LEVEL // R98B/R98A same
+#define NUMBER_OF_INT 6
+
+//
+// Define the minimum and maximum system time increment values in 100ns units.
+//
+
+#define MAXIMUM_INCREMENT (10 * 1000 * 10)
+#define MINIMUM_INCREMENT (1 * 1000 * 10)
+
+//
+//
+// Time increment in 1us units
+// The Columbus chip clock frequency is 1.024 MHZ
+#define COLUMBUS_CLOCK_FREQUENCY 1024
+
+// The hardware expects that this value is decremented by one
+#define CLOCK_INTERVAL (((MAXIMUM_INCREMENT * COLUMBUS_CLOCK_FREQUENCY) / 1000) / 10)
+
+//
+// 1 Interval != 1 micro sec. ==> 1 Interval = 1/1.024 microsec
+// 1 Count (H/W register) is 1/1.024 microsec
+//
+#define DEFAULT_PROFILETIMER_INTERVAL (500 * 10) // = 500 us (100ns units)
+#define MAXIMUM_PROFILETIMER_INTERVAL (64000 * 10) // = 64 ms (100ns units)
+#define DEFAULT_PROFILETIMER_COUNT (MAXIMUM_PROFILETIMER_INTERVAL / 10) //Set count value
+#define MINIMUM_PROFILETIMER_INTERVAL (40 * 10) // = 40 us (100ns units)
+
+
+
+
+//
+// Chip Set Addr
+//
+#define COLUMNBS_LPHYSICAL_BASE 0x19800000
+#define COLUMNBS_GPHYSICAL_BASE 0x19000000
+#define PONCE_PHYSICAL_BASE 0x1a000000
+#define MAGELLAN_0_PHYSICAL_BASE 0x18000000
+#define MAGELLAN_1_PHYSICAL_BASE 0x18020000
+#define LOCALDEV_PHYSICAL_BASE 0x1f0f0000
+
+
+
+#define EISA_CONTROL_PHYSICAL_BASE 0x1C000000 // physical base of EISA control
+#define SERIAL0_PHYSICAL_BASE (EISA_CONTROL_PHYSICAL_BASE+0x3f8) //serial
+#define KEYBOARD_PHYSICAL_BASE (EISA_CONTROL_PHYSICAL_BASE+0x60) //serial
+//
+// R98X have 2 I/O Area(per Ponce). But Not Use apper area!!.
+// used lower area only.
+//
+#define PCI_CNTL_PHYSICAL_BASE 0x1c000000
+#define PCI_MAX_CNTL_SIZE 0x400000 //4M
+
+//
+// R98X PCI Memory area size 1Gmax. Not 4G!!.
+//
+#define PCI_MAX_MEMORY_SIZE 0x40000000 //1G max
+#define PCI_MEMORY_PHYSICAL_BASE_LOW 0x40000000
+#define PCI_MEMORY_PHYSICAL_BASE_HIGH 0x1
+
+// Ponce #0 have EISA/ISA.
+//
+#define EISA_MEMORY_PHYSICAL_BASE_LOW PCI_MEMORY_PHYSICAL_BASE_LOW
+#define EISA_MEMORY_PHYSICAL_BASE_HIGH PCI_MEMORY_PHYSICAL_BASE_HIGH
+
+#define EISA_CNTL_PHYSICAL_BASE PCI_CNTL_PHYSICAL_BASE
+#define EISA_CNTL_PHYSICAL_BASE_LOW PCI_CNTL_PHYSICAL_BASE
+#define EISA_CNTL_PHYSICAL_BASE_HIGH 0x0
+
+//
+// RTC Register
+//
+#define RTCLOCK_PHYSICAL_BASE 0x1c000071 // physical base of realtime clock
+
+//
+// Actually nvram start at
+//
+#define NVRAM_ACTUALLY_PHYSICAL_BASE 0x1F080000 // physical base of NonVolatile RAM
+//
+// s/w read/write ble erea this address
+//
+#define NVRAM_PHYSICAL_BASE 0x1F082000 // physical base of NonVolatile RAM For S/W
+#define NVRAM_MEMORY_BASE (KSEG1_BASE + NVRAM_PHYSICAL_BASE)
+
+//
+// R4400 cause register.
+//
+#define CAUSE_INT_PEND_BIT 0xA //Int0 base
+
+//
+// Local Device Function Operation.
+//
+#define LOCALDEV_OP_READ 0x1
+#define LOCALDEV_OP_WRITE 0x0
+
+
+//
+// Local Device MRC Function Operation.
+//
+#define MRC_OP_DUMP_ONLY_NMI 0x1
+#define MRC_OP_DUMP_AND_POWERSW_NMI 0x0
+
+//
+// ECC 1bit/Multi bit Error Operation.
+//
+#define ECC_1BIT_ENABLE 0xfffffff5
+#define ECC_MULTI_ENABLE 0xfffffffa
+#define ECC_ERROR_DISABLE 0x0000000f
+#define ECC_ERROR_ENABLE 0xfffffff0
+#define MAGELLAN_ERRI_OFFSET 0x2330
+
+//
+// Define cause register read macro
+//
+
+#define READ_CAUSE_REGISTER(reg) \
+ .set noreorder; \
+ .set noat; \
+ mfc0 reg,cause; \
+ nop; \
+ nop; \
+ .set at; \
+ .set reorder;
+
+
+#endif // _R98BDEF_
diff --git a/private/ntos/nthals/halr98b/mips/r98breg.h b/private/ntos/nthals/halr98b/mips/r98breg.h
new file mode 100644
index 000000000..5fc5e2f67
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/r98breg.h
@@ -0,0 +1,649 @@
+
+#ifndef _R98BREG_
+#define _R98BREG_
+
+
+#include <r98bdef.h>
+//
+// R98B Chip Set Register Define
+//
+//
+// Define COLUMBS register structure.
+//
+typedef struct _COLUMNBUS_REGISTER {
+ ULONG Long;
+ ULONG Fill;
+} COLUMNBUS_REGISTER, *PCOLUMNBUS_REGISTER;
+
+typedef struct _COLUMNBUS_LARGE_REGISTER {
+// ULONG Low;
+// ULONG High;
+
+ ULONGLONG Llong;
+} COLUMNBUS_LARGE_REGISTER, *PCOLUMNBUS_LARGE_REGISTER;
+
+typedef volatile struct _COLUMNBUS_REGISTERS {
+ // offset(H)
+ COLUMNBUS_LARGE_REGISTER IPR; // 0x0
+ COLUMNBUS_LARGE_REGISTER MKR; // 0x8
+ COLUMNBUS_LARGE_REGISTER IPRR; // 0x10
+ COLUMNBUS_REGISTER IPSR; // 0x18
+ COLUMNBUS_REGISTER MKRR; // 0x20
+ COLUMNBUS_REGISTER MKSR; // 0x28
+ COLUMNBUS_REGISTER NMIR; // 0x30
+ COLUMNBUS_REGISTER NMIRST; // 0x38
+ COLUMNBUS_REGISTER TMSR1; // 0x40
+ COLUMNBUS_REGISTER TMR1; // 0x48
+ COLUMNBUS_REGISTER TOVCT1; // 0x50
+ COLUMNBUS_REGISTER TMCR1; // 0x58
+ COLUMNBUS_REGISTER TMSR2; // 0x60
+ COLUMNBUS_REGISTER TMR2; // 0x68
+ COLUMNBUS_REGISTER TOVCT2; // 0x70
+ COLUMNBUS_REGISTER TMCR2; // 0x78
+ COLUMNBUS_REGISTER WDTSR; // 0x80
+ COLUMNBUS_REGISTER WDT; // 0x88
+ COLUMNBUS_REGISTER WDTCR; // 0x90
+ COLUMNBUS_REGISTER IRLEV; // 0x98
+ COLUMNBUS_REGISTER Reserved1[12]; // 0xa0-0xF8
+ COLUMNBUS_REGISTER SYNDM; // 0x100
+ COLUMNBUS_REGISTER SDMRST; // 0x108
+ COLUMNBUS_REGISTER Reserved2[14]; // 0x110
+ COLUMNBUS_REGISTER STCON; // 0x180
+ COLUMNBUS_REGISTER STSAD; // 0x188
+ COLUMNBUS_REGISTER STADMK; // 0x190
+ COLUMNBUS_REGISTER STDATH; // 0x198
+ COLUMNBUS_REGISTER STDATL; // 0x1a0
+ COLUMNBUS_REGISTER Reserved21; // 0x1a8
+ COLUMNBUS_REGISTER Reserved3[10]; // 0x1b0 - 0x1f8
+ COLUMNBUS_REGISTER CTAddr; // 0x200
+ COLUMNBUS_REGISTER CTDataA; // 0x208
+ COLUMNBUS_REGISTER CTDataB; // 0x210
+ COLUMNBUS_REGISTER CTCTL; // 0x218
+ COLUMNBUS_REGISTER EVCNT1H; // 0x220
+ COLUMNBUS_REGISTER EVCNT1L; // 0x228
+ COLUMNBUS_REGISTER EVCNTCR1; // 0x230
+ COLUMNBUS_REGISTER Reserved4[25]; // 0x238- 0x2F8
+ COLUMNBUS_REGISTER CNFG; // 0x300
+ COLUMNBUS_REGISTER DISN; // 0x208
+ COLUMNBUS_REGISTER REVR; // 0x310
+ COLUMNBUS_REGISTER AERR; // 0x318
+ COLUMNBUS_REGISTER FERR; // 0x320
+ COLUMNBUS_REGISTER ERRMK; // 0x328
+ COLUMNBUS_REGISTER ERRI; // 0x330
+ COLUMNBUS_REGISTER ERRST; // 0x338
+ COLUMNBUS_REGISTER NMIM; // 0x340
+ COLUMNBUS_REGISTER EAHI; // 0x348
+ COLUMNBUS_REGISTER EALI; // 0x350
+ COLUMNBUS_REGISTER AERR2; // 0x358
+ COLUMNBUS_REGISTER FERR2; // 0x360
+ COLUMNBUS_REGISTER ERRMK2; // 0x368
+ COLUMNBUS_REGISTER ERRI2; // 0x370
+ COLUMNBUS_REGISTER ERRST2; // 0x378
+ COLUMNBUS_REGISTER NMIM2; // 0x380
+ COLUMNBUS_REGISTER STSR; // 0x388
+ COLUMNBUS_REGISTER EVCNT0H; // 0x390
+ COLUMNBUS_REGISTER EVCNT0L; // 0x398
+ COLUMNBUS_REGISTER EVCNTCR0; // 0x3a0
+ COLUMNBUS_REGISTER MODE; // 0x3a8
+ COLUMNBUS_REGISTER Reserved5[10]; // 0x3b0- 0x3f8
+ COLUMNBUS_REGISTER RRMT0H; // 0x400
+ COLUMNBUS_REGISTER RRMT0L; // 0x408
+ COLUMNBUS_REGISTER RRMT1H; // 0x410
+ COLUMNBUS_REGISTER RRMT1L; // 0x418
+ COLUMNBUS_REGISTER RRMT2H; // 0x420
+ COLUMNBUS_REGISTER RRMT2L; // 0x428
+ COLUMNBUS_REGISTER RRMT3H; // 0x430
+ COLUMNBUS_REGISTER RRMT3L; // 0x438
+ COLUMNBUS_REGISTER RRMT4H; // 0x440
+ COLUMNBUS_REGISTER RRMT4L; // 0x448
+ COLUMNBUS_REGISTER RRMT5H; // 0x450
+ COLUMNBUS_REGISTER RRMT5L; // 0x458
+ COLUMNBUS_REGISTER RRMT6H; // 0x460
+ COLUMNBUS_REGISTER RRMT6L; // 0x468
+ COLUMNBUS_REGISTER RRMT7H; // 0x470
+ COLUMNBUS_REGISTER RRMT7L; // 0x478
+ COLUMNBUS_REGISTER RRMT8H; // 0x480
+ COLUMNBUS_REGISTER RRMT8L; // 0x488
+ COLUMNBUS_REGISTER RRMT9H; // 0x490
+ COLUMNBUS_REGISTER RRMT9L; // 0x498
+ COLUMNBUS_REGISTER RRMT10H; // 0x4a0
+ COLUMNBUS_REGISTER RRMT10L; // 0x4a8
+ COLUMNBUS_REGISTER RRMT11H; // 0x4b0
+ COLUMNBUS_REGISTER RRMT11L; // 0x4b8
+ COLUMNBUS_REGISTER RRMT12H; // 0x4c0
+ COLUMNBUS_REGISTER RRMT12L; // 0x4c8
+ COLUMNBUS_REGISTER RRMT13H; // 0x4d0
+ COLUMNBUS_REGISTER RRMT13L; // 0x4d8
+ COLUMNBUS_REGISTER RRMT14H; // 0x4e0
+ COLUMNBUS_REGISTER RRMT14L; // 0x4e8
+ COLUMNBUS_REGISTER RRMT15H; // 0x4f0
+ COLUMNBUS_REGISTER RRMT15L; // 0x4f8
+ COLUMNBUS_REGISTER HPT0; // 0x500
+ COLUMNBUS_REGISTER HPT1; // 0x508
+ COLUMNBUS_REGISTER HPT2; // 0x510
+ COLUMNBUS_REGISTER HPT3; // 0x518
+ COLUMNBUS_REGISTER HPT4; // 0x520
+ COLUMNBUS_REGISTER HPT5; // 0x528
+ COLUMNBUS_REGISTER HPT6; // 0x530
+ COLUMNBUS_REGISTER HPT7; // 0x538
+ COLUMNBUS_REGISTER HPT8; // 0x540
+ COLUMNBUS_REGISTER HPT9; // 0x548
+ COLUMNBUS_REGISTER NRTY1; // 0x550
+ COLUMNBUS_REGISTER Reserved6[5]; // 0x558-0x57f
+ COLUMNBUS_REGISTER IntIR; // 0x580
+ COLUMNBUS_REGISTER RCIR; // 0x588
+ COLUMNBUS_REGISTER TCIR; // 0x590
+ COLUMNBUS_REGISTER HPTIR; // 0x598
+ COLUMNBUS_REGISTER CBIR; // 0x5a0
+ COLUMNBUS_REGISTER Reserved7[11]; // 0x5a8-0x5f8
+ COLUMNBUS_REGISTER SIOCNT; // 0x600
+ COLUMNBUS_REGISTER SIODAT; // 0x608
+ COLUMNBUS_REGISTER ERRNOD; // 0x610
+ COLUMNBUS_REGISTER ERNDRS; // 0x618
+ COLUMNBUS_REGISTER Reserved8[28]; // 0x620-0x6f8
+ COLUMNBUS_REGISTER ARTYCT; // 0x700
+ COLUMNBUS_REGISTER DRTYCT; // 0x708
+ COLUMNBUS_REGISTER TOSR; // 0x710
+ COLUMNBUS_REGISTER NRTY2; // 0x718
+
+} COLUMNBUS_REGISTERS, *PCOLUMNBUS_REGISTERS;
+
+
+
+#define COLUMNBS_GADDR_SHIFT 12
+//
+// How to Access Local Area
+//
+#define COLUMNBS_LCNTL ((volatile PCOLUMNBUS_REGISTERS)(KSEG1_BASE | COLUMNBS_LPHYSICAL_BASE))
+//
+// How to Access Gloabal Area
+// N.B parameter is Node
+// Columbs #0: NODE 4
+// Columbs #1: NODE 5
+// Columbs #2: NODE 6
+// Columbs #3: NODE 7
+//
+#define COLUMNBS_GCNTL( Node ) ((volatile PCOLUMNBUS_REGISTERS)(KSEG1_BASE | \
+ COLUMNBS_GPHYSICAL_BASE | \
+ ((Node) << COLUMNBS_GADDR_SHIFT)))
+//
+// IPR Register
+//
+#define NUMBER_OF_IPR_BIT 64
+
+//
+// TMCRX Register Bit Define
+//
+#define TIMER_NOOP 0x00
+#define TIMER_STOP 0x1
+#define TIMER_START 0x2
+#define TIMER_RELOAD_START 0x3
+
+//
+// TCIR Register Bit Define
+//
+#define TCIR_CLOCK_CMD_SHIFT 26
+#define TCIR_PROFILE_CMD_SHIFT 24
+#define TCIR_ALL_CLOCK_RESTART (TIMER_RELOAD_START << TCIR_CLOCK_CMD_SHIFT)
+
+//
+// STSR Register Bit Define
+//
+#define STSR_EIF 0x80000000
+#define STSR_EIFMK 0x40000000
+#define STSR_FREEZ 0x20000000
+#define STSR_NMIMK 0x08000000
+#define STSR_NVWINH 0x04000000
+#define STSR_NVBINH 0x02000000
+#define STSR_WEIF 0x00800000
+#define STSR_WEIFMK 0x00400000
+#define STSR_WFREEZ 0x00200000
+#define STSR_WNMIMK 0x00080000
+#define STSR_WNVWINH 0x00040000
+#define STSR_WNVBINH 0x00020000
+#define STSR_CLBER 0x00008000
+#define STSR_WAMRST 0x00004000
+#define STSR_EFIFOEMP 0x00000800
+#define STSR_ITVPND 0x00000400
+#define STSR_WRPND 0x00000200
+#define STSR_CTEXE 0x00000100
+#define STSR_MPU 0x00000080
+#define STSR_ENDIAN 0x00000040
+#define STSR_SCSIZE 0x0000001c
+
+//
+// IntIR Register define
+//
+#define IntIR_REQUEST_IPI 0x80000000 // Interrupt Kick
+#define IntIR_CODE_BIT 24 // Bit 24-30 is interrupt code
+#define ATLANTIC_CODE_IPI_FROM_CPU0 0xC
+#define ToNODE4 0x00080000 // to CPU#0
+#define ToNODE5 0x00040000 // to CPU#1
+#define ToNODE6 0x00020000 // to CPU#2
+#define ToNODE7 0x00010000 // to CPU#3
+
+//
+// ERRNOD Register define
+//
+#define ERRNOD_NODE0 0x0008 //PONCE#0
+#define ERRNOD_NODE1 0x0004 //PONCE#1
+#define ERRNOD_NODE4 0x8000 //CPU#0
+#define ERRNOD_NODE5 0x4000 //CPU#1
+#define ERRNOD_NODE6 0x2000 //CPU#2
+#define ERRNOD_NODE7 0x1000 //CPU#3
+#define ERRNOD_NODE8 0x0080 //Magellan#0
+#define ERRNOD_NODE9 0x0040 //Magellan#1
+#define ERRNOD_EISANMI 0x0200 //EISANMI
+#define ERRNOD_ALARM 0x0100 //ALARM
+
+
+//
+// CNFG Register define
+//
+//
+#define CNFG_CONNECT0_PONCE0 0x80000000 //it is Ponce 0
+#define CNFG_CONNECT1_PONCE1 0x40000000 //it is Ponce 1
+#define CNFG_CONNECT4_CPU0 0x08000000 //it is CPU #0
+#define CNFG_CONNECT4_CPU1 0x04000000 //it is CPU #1
+#define CNFG_CONNECT4_CPU2 0x02000000 //it is CPU #2
+#define CNFG_CONNECT4_CPU3 0x01000000 //it is CPU #3
+#define CNFG_CONNECT4_MAGELLAN0 0x00800000 //it is MAGELLAN 0
+#define CNFG_CONNECT4_MAGELLAN1 0x00400000 //it is MAGELLAN 1
+
+
+#define ERRNOD_ALLNODE ((ERRNOD_NODE0|ERRNOD_NODE1| \
+ ERRNOD_NODE4|ERRNOD_NODE5| \
+ ERRNOD_NODE6|ERRNOD_NODE7| \
+ ERRNOD_NODE8|ERRNOD_NODE9))
+
+//
+// NMIR Register define
+//
+//
+#define NMIR_EXNMI 0x0008 //DUMP Key
+#define NMIR_WDTOV 0x0004 //watch dog timer
+#define NMIR_CLBNMI 0x0002 //COLUMBUS Internal
+#define NMIR_UNANMI 0x0001 //F/W,S/W
+
+//
+// ********************************************************************
+// PONCE Register
+//
+typedef struct _PONCE_REGISTER {
+ ULONG Long;
+ ULONG Fill;
+}PONCE_REGISTER,*PPONCE_REGISTER;
+//
+// PONCE Register define
+//
+typedef volatile struct _PONCE_REGISTERS {
+
+ PONCE_REGISTER INTAC; //0x000
+ PONCE_REGISTER CONFA; //0x008
+ PONCE_REGISTER CONFD; //0x010
+ PONCE_REGISTER PTBSR; //0x018
+ PONCE_REGISTER Reserve0; //0x020
+ PONCE_REGISTER PTLMR; //0x028
+ PONCE_REGISTER Reserve1; //0x030
+ PONCE_REGISTER TFLSR; //0x038
+ PONCE_REGISTER Reserve2; //0x040
+ PONCE_REGISTER TLBTG[8]; //0x048
+ PONCE_REGISTER Reserve3[9]; //0x088
+ PONCE_REGISTER ADCFR0; //0x0d0
+ PONCE_REGISTER Reserve4; //0x0d8
+ PONCE_REGISTER PMODR; //0x0e0
+ PONCE_REGISTER Reserve5[3]; //0x0e8
+ PONCE_REGISTER VENID; //0x100
+ PONCE_REGISTER DEVID; //0x108
+ PONCE_REGISTER PCMDN; //0x110
+ PONCE_REGISTER PSTAT; //0x118
+ PONCE_REGISTER REVID; //0x120
+ PONCE_REGISTER CLASS; //0x128
+ PONCE_REGISTER LTNCY; //0x130
+ PONCE_REGISTER Reserve6[2]; //0x138
+ PONCE_REGISTER TLBDT[8]; //0x148
+ PONCE_REGISTER Reserve7[0xf]; //0x188
+
+ PONCE_REGISTER INTRG; //0x200
+ PONCE_REGISTER INTM; //0x208
+ PONCE_REGISTER INTPH; //0x210
+ PONCE_REGISTER INTPL; //0x218
+ PONCE_REGISTER INTTG[11]; //0x220
+ PONCE_REGISTER INTCD[11]; //0x278 - 0x2c8
+ PONCE_REGISTER CAFLS; //0x2d0
+ PONCE_REGISTER CASEL; //0x2d8
+ PONCE_REGISTER CADATH; //0x2e0
+ PONCE_REGISTER CADATL; //0x2e8
+ PONCE_REGISTER CATAGH; //0x2f0
+ PONCE_REGISTER CATAGL; //0x2f8
+ PONCE_REGISTER Reserve8[2]; //0x300 0x308
+ PONCE_REGISTER REVR; //0x310
+ PONCE_REGISTER AERR; //0x318
+ PONCE_REGISTER FERR; //0x320
+ PONCE_REGISTER ERRM; //0x328
+ PONCE_REGISTER ERRI; //0x330
+ PONCE_REGISTER ERRST; //0x338
+ PONCE_REGISTER Reserve9; //0x340
+ PONCE_REGISTER EAHI; //0x348
+ PONCE_REGISTER EALI; //0x350
+ PONCE_REGISTER Reservea[21]; //0x358
+ PONCE_REGISTER RRMT0H; //0x400
+ PONCE_REGISTER RRMT0L; //0x408
+ PONCE_REGISTER RRMT1H; //0x410
+ PONCE_REGISTER RRMT1L; //0x418
+ PONCE_REGISTER RRMT2H; //0x420
+ PONCE_REGISTER RRMT2L; //0x428
+ PONCE_REGISTER RRMT3H; //0x430
+ PONCE_REGISTER RRMT3L; //0x438
+ PONCE_REGISTER RRMT4H; //0x440
+ PONCE_REGISTER RRMT4L; //0x448
+ PONCE_REGISTER RRMT5H; //0x450
+ PONCE_REGISTER RRMT5L; //0x458
+ PONCE_REGISTER RRMT6H; //0x460
+ PONCE_REGISTER RRMT6L; //0x468
+ PONCE_REGISTER RRMT7H; //0x470
+ PONCE_REGISTER RRMT7L; //0x478
+ PONCE_REGISTER Reserveb[16]; //0x480
+
+ PONCE_REGISTER HPT0; //0x500
+ PONCE_REGISTER HPT1; //0x508
+ PONCE_REGISTER HPT2; //0x510
+ PONCE_REGISTER HPT3; //0x518
+ PONCE_REGISTER HPT4; //0x520
+ PONCE_REGISTER HPT5; //0x528
+ PONCE_REGISTER HPT6; //0x530
+ PONCE_REGISTER HPT7; //0x538
+ PONCE_REGISTER HPT8; //0x540
+ PONCE_REGISTER HPT9; //0x548
+ PONCE_REGISTER Reservec[54]; //0x550
+
+ PONCE_REGISTER ANRC; //0x700
+ PONCE_REGISTER DNRC; //0x708
+ PONCE_REGISTER ABRMT; //0x710
+ PONCE_REGISTER Reserved; //0x718
+ PONCE_REGISTER ANKRL2; //0x720
+ PONCE_REGISTER DISN; //0x728
+ PONCE_REGISTER Reserved2[26]; //0x730
+
+ PONCE_REGISTER PAERR; //0x800
+ PONCE_REGISTER PFERR; //0x808
+ PONCE_REGISTER PERRM; //0x810
+ PONCE_REGISTER PERRI; //0x818
+ PONCE_REGISTER PERST; //0x820
+ PONCE_REGISTER PTOL; //0x828
+ PONCE_REGISTER Reservee; //0x830
+ PONCE_REGISTER PNRT; //0x838
+ PONCE_REGISTER PRCOL; //0x840
+ PONCE_REGISTER PMDL; //0x848
+ PONCE_REGISTER PRST; //0x850
+ PONCE_REGISTER ERITTG[3]; //0x858,0x860,0x868
+ PONCE_REGISTER ERITCD[3]; //0x870,0x878,0x880
+ PONCE_REGISTER Reservef[0xf]; //0x888
+ PONCE_REGISTER TRSM; //0x900
+ PONCE_REGISTER TROM; //0x908
+ PONCE_REGISTER TRAC; //0x910
+ PONCE_REGISTER TRDS; //0x918
+ PONCE_REGISTER TRDE; //0x920
+ PONCE_REGISTER TRDO; //0x928
+ PONCE_REGISTER Reserve10[2]; //0x930,0x938
+ PONCE_REGISTER INTSM; //0x940
+
+}PONCE_REGISTERS,*PPONCE_REGISTERS;
+
+
+#define PONCE_ADDR_SHIFT 12
+#define PONCE_MAX 3 //R98[a-z] max Ponce is 3.
+#define PONCE_ADDR_MASK (PONCE_MAX << PONCE_ADDR_SHIFT)
+
+#define PONCE_IOADDR_SHIFT 22
+//
+// Ponce max pci device( Never PCI_MAX_DEVICES)
+//
+#define PONCE_PCI_MAX_DEVICES 21
+
+//
+// I/O TLB
+//
+#define PONCE_MAX_IOTLB_ENTRY 8
+//
+// PONCE Register Access
+//
+#define PONCE_CNTL_BASE_SHIFT 12
+#define PONCE_CNTL(Ponce) ((volatile PPONCE_REGISTERS) \
+ (KSEG1_BASE | PONCE_PHYSICAL_BASE | \
+ ((Ponce) << PONCE_ADDR_SHIFT)))
+
+
+
+//
+// PAERR,PFERR,PERRM,PERRI,PERST Registers Bit Define
+// Bit31 - Bit21 only other is MBZ
+//
+#define PONCE_PXERR_PPERM 0x80000000
+#define PONCE_PXERR_PPERS 0x40000000
+#define PONCE_PXERR_PPERN 0x20000000
+#define PONCE_PXERR_PSERR 0x10000000
+#define PONCE_PXERR_PPCER 0x08000000
+#define PONCE_PXERR_PTOUT 0x04000000
+#define PONCE_PXERR_PROER 0x02000000
+#define PONCE_PXERR_PMDER 0x01000000
+#define PONCE_PXERR_PMABS 0x00800000
+#define PONCE_PXERR_PTABS 0x00400000
+#define PONCE_PXERR_PTABO 0x00200000
+#define PONCE_PXERR_MASK 0xFFE00000
+
+//
+// AERR,FERR,ERRM,ERRI,ERRST Registers Bit Define
+// Bit31 - Bit9 only other is RFU
+//
+#define PONCE_XERR_ACPBERR 0x80000000
+#define PONCE_XERR_RRIBERR 0x40000000
+#define PONCE_XERR_ZERO 0x20000000
+#define PONCE_XERR_SNDERR 0x10000000
+#define PONCE_XERR_ABTMOT 0x08000000
+#define PONCE_XERR_ABWTLT 0x04000000
+#define PONCE_XERR_ABRTYOV 0x02000000
+#define PONCE_XERR_ABRERTOV 0x01000000
+#define PONCE_XERR_NERRR 0x00800000
+#define PONCE_XERR_UNADER 0x00400000
+#define PONCE_XERR_UNCMDER 0x00200000
+#define PONCE_XERR_BWDPER 0x00100000
+#define PONCE_XERR_SLWDPER 0x00080000
+#define PONCE_XERR_BDRPER 0x00040000
+#define PONCE_XERR_SLDRPER 0x00020000
+#define PONCE_XERR_ADPER 0x00010000
+#define PONCE_XERR_CDPER 0x00008000
+#define PONCE_XERR_RRPER 0x00004000
+#define PONCE_XERR_CHICT 0x00002000
+#define PONCE_XERR_STATUMT 0x00001000
+#define PONCE_XERR_TUAER 0x00000800
+#define PONCE_XERR_TIVER 0x00000400
+#define PONCE_XERR_MOVER 0x00000200
+#define PONCE_XERR_MASK 0xDFFFFE00
+
+
+//
+// Dummy Read Registers Index
+//
+typedef enum _INTRG{
+ PCIINTD,
+ PCIINTC,
+ PCIINTB,
+ PCIINTA3,
+ PCIINTA2,
+ PCIINTA1,
+ PCIINTA0,
+ INTSB1,
+ INTSB0,
+ INTSA1,
+ INTSA0,
+}INTRG,*PINTRG;
+
+
+//
+// Dummy Read Registers
+//
+//
+typedef enum _DUMMY_ADDR{
+ DUMMY_A0,
+ DUMMY_A1,
+ DUMMY_A2,
+ DUMMY_A3,
+ DUMMY_A4,
+ DUMMY_A5
+}DUMMY_ADDR,*PDUMMY_ADDR;
+
+#define PONCE0 0x0
+#define PONCE1 0x1
+
+
+//
+// Magellan registers
+//
+//
+
+typedef struct _MAGELLAN_REGISTER {
+ ULONG Long;
+ ULONG Fill;
+}MAGELLAN_REGISTER,*PMAGELLAN_REGISTER;
+//
+// PONCE Register define
+//
+
+typedef volatile struct _MAGELLAN_REGISTERS{
+ MAGELLAN_REGISTER ADEC0; //0x0000
+ MAGELLAN_REGISTER ADEC1; //0x0008
+ MAGELLAN_REGISTER ADEC2; //0x0010
+ MAGELLAN_REGISTER ADEC3; //0x0018
+ MAGELLAN_REGISTER Reserved0[0x1c]; //0x0020
+ MAGELLAN_REGISTER EAADEC0; //0x0100
+ MAGELLAN_REGISTER EAADEC1; //0x0108
+ MAGELLAN_REGISTER Reserved1[0x1de]; //0x0110
+ MAGELLAN_REGISTER INLC; //0x1000
+ MAGELLAN_REGISTER RCFD; //0x1008
+ MAGELLAN_REGISTER Reserved2; //0x1010
+ MAGELLAN_REGISTER DTRG; //0x1018
+ MAGELLAN_REGISTER Reserved4[0x5d]; //0x1020
+ MAGELLAN_REGISTER DISN; //0x1308
+ MAGELLAN_REGISTER REVR; //0x1310
+ MAGELLAN_REGISTER Reserved5[0x3d]; //0x1318
+ MAGELLAN_REGISTER HPT0; //0x1500
+ MAGELLAN_REGISTER HPT1; //0x1508
+ MAGELLAN_REGISTER HPT2; //0x1510
+ MAGELLAN_REGISTER HPT3; //0x1518
+ MAGELLAN_REGISTER HPT4; //0x1520
+ MAGELLAN_REGISTER HPT5; //0x1528
+ MAGELLAN_REGISTER HPT6; //0x1530
+ MAGELLAN_REGISTER HPT7; //0x1538
+ MAGELLAN_REGISTER HPT8; //0x1540
+ MAGELLAN_REGISTER HPT9; //0x1548
+ MAGELLAN_REGISTER Reserved6[0x1b9]; //0x1550
+ MAGELLAN_REGISTER AERR; //0x2318
+ MAGELLAN_REGISTER FERR; //0x2320
+ MAGELLAN_REGISTER ERRM; //0x2328
+ MAGELLAN_REGISTER ERRI; //0x2330
+ MAGELLAN_REGISTER ERRST; //0x2338
+ MAGELLAN_REGISTER Reserved7; //0x2340
+ MAGELLAN_REGISTER EIFM; //0x2348
+ MAGELLAN_REGISTER EAHI; //0x2350
+ MAGELLAN_REGISTER EALI; //0x2358
+ MAGELLAN_REGISTER Reserved8[2]; //0x2360
+ MAGELLAN_REGISTER CKE0; //0x2370
+ MAGELLAN_REGISTER Reserved9; //0x2378
+ MAGELLAN_REGISTER SECT; //0x2380
+ MAGELLAN_REGISTER STS1; //0x2388
+ MAGELLAN_REGISTER RSRG; //0x2390
+ MAGELLAN_REGISTER DATM; //0x2398
+ MAGELLAN_REGISTER DSRG; //0x23a0
+ MAGELLAN_REGISTER SDLM; //0x23a8
+ MAGELLAN_REGISTER Reserveda[0x18a]; //0x23b0
+ MAGELLAN_REGISTER SDCR; //0x3000
+ MAGELLAN_REGISTER Reservedb[0x27f]; //0x3008
+ MAGELLAN_REGISTER RRMTH0; //0x4400
+ MAGELLAN_REGISTER RRMTL0; //0x4408
+ MAGELLAN_REGISTER RRMTH1; //0x4410
+ MAGELLAN_REGISTER RRMTL1; //0x4418
+ MAGELLAN_REGISTER RRMTH2; //0x4420
+ MAGELLAN_REGISTER RRMTL2; //0x4428
+ MAGELLAN_REGISTER RRMTH3; //0x4430
+ MAGELLAN_REGISTER RRMTL3; //0x4438
+ MAGELLAN_REGISTER RRMTH4; //0x4440
+ MAGELLAN_REGISTER RRMTL4; //0x4448
+ MAGELLAN_REGISTER RRMTH5; //0x4450
+ MAGELLAN_REGISTER RRMTL5; //0x4458
+ MAGELLAN_REGISTER RRMTH6; //0x4460
+ MAGELLAN_REGISTER RRMTL6; //0x4468
+ MAGELLAN_REGISTER RRMTH7; //0x4470
+ MAGELLAN_REGISTER RRMTL7; //0x4478
+ MAGELLAN_REGISTER Reservedc[0x170]; //0x4480
+ MAGELLAN_REGISTER PCM; //0x5000
+ MAGELLAN_REGISTER PCH; //0x5008
+ MAGELLAN_REGISTER Reservedd[0x1e]; //0x5010
+ MAGELLAN_REGISTER TMOD; //0x5100
+ MAGELLAN_REGISTER TRA; //0x5108
+ MAGELLAN_REGISTER Reservede[0x1e]; //0x5110
+ MAGELLAN_REGISTER TRM0[0x20]; //0x5200
+ MAGELLAN_REGISTER TRM1[0x20]; //0x5300
+ MAGELLAN_REGISTER TRM2[0x20]; //0x5400
+}MAGELLAN_REGISTERS,*PMAGELLAN_REGISTERS;
+
+
+
+//
+// How to Access Local Area
+//
+#define MAGELLAN_0_CNTL ((volatile PMAGELLAN_REGISTERS)(KSEG1_BASE | MAGELLAN_0_PHYSICAL_BASE))
+#define MAGELLAN_1_CNTL ((volatile PMAGELLAN_REGISTERS)(KSEG1_BASE | MAGELLAN_1_PHYSICAL_BASE))
+
+#define MAGELLAN_X_CNTL(x) ((volatile PMAGELLAN_REGISTERS)(KSEG1_BASE |\
+ ((x) ? MAGELLAN_1_PHYSICAL_BASE : MAGELLAN_0_PHYSICAL_BASE)))
+
+//
+// Define LOCAL device Control register structure.
+//
+typedef struct _LOCAL_REGISTERS { // offset(H)
+ UCHAR LBCTL; // 0x0
+ UCHAR Reserved0[15];
+ UCHAR LBADL; // 0x10
+ UCHAR Reserved1[7];
+ UCHAR LBADH; // 0x18
+ UCHAR Reserved2[7];
+ UCHAR LBDT; // 0x20
+}LOCAL_REGISTERS, *PLOCAL_REGISTERS;
+
+
+//
+// LBCTL Regiser Bit define
+//
+
+#define LBCTL_SWE 0x80
+#define LBCTL_SEMAPHORE 0x40
+#define LBCTL_CMD 0x10
+#define LBCTL_READ 0x08
+
+//
+// MRC Register Offset
+//
+#define MRCINT 0x0200
+#define MRCMODE 0x0208
+#define MRC_SWPOWEROFF 0x0230
+#define MRC_FDWRITEPROTECT 0x0250
+
+
+//
+// ALARM Register Offset
+//
+#define ALARM_LOW 0x410
+#define ALARM_HIGH 0x411
+#define ALMINH_LOW 0x414
+#define ALMINH_HIGH 0x415
+#define ALMSNS_LOW 0x418
+#define ALMSNS_HIGH 0x419
+
+//
+// Define pointer to Local Device Control registers.
+//
+#define LOCAL_CNTL ((volatile PLOCAL_REGISTERS)(KSEG1_BASE | LOCALDEV_PHYSICAL_BASE))
+
+
+#endif _R98BREG_
diff --git a/private/ntos/nthals/halr98b/mips/rgb525.h b/private/ntos/nthals/halr98b/mips/rgb525.h
new file mode 100644
index 000000000..9c157bc95
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rgb525.h
@@ -0,0 +1,468 @@
+// #pragma comment(exestr, "@(#) rgb525.h 1.1 95/07/24 10:53:20 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/halr98b/mips/rxbusdat.c b/private/ntos/nthals/halr98b/mips/rxbusdat.c
new file mode 100644
index 000000000..fdf6541bb
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxbusdat.c
@@ -0,0 +1,290 @@
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ rxbusdat.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:
+
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+
+ULONG
+HalpNoBusData (
+ IN PVOID BusHandler,
+ IN PVOID RootHandler,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+
+//
+// Prototype for system bus handlers
+//
+
+
+NTSTATUS
+HalpHibernateHal (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler
+ );
+
+NTSTATUS
+HalpResumeHal (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler
+ );
+
+#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;
+
+#if 0
+ //
+ // Hibernate and resume the hal by getting notifications
+ // for when this bus is hibernated or resumed. Since it's
+ // the first bus to be added, it will be the last to hibernate
+ // and the first to resume
+ //
+
+ Bus->HibernateBus = HalpHibernateHal;
+ Bus->ResumeBus = HalpResumeHal;
+#endif
+
+ //
+ // 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;
+ //
+ // R98B Build Other Bus (PCIBus)
+ // move to jxusage.c
+ // HalpInitializePciBus();
+
+}
+
+
+
+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;
+ ULONG Ponce;
+
+ //
+ // 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;
+
+ // R98B must be MemorySpace!!.
+ Bus->BusAddresses->IO.SystemAddressSpace = 0;
+ Bus->BusAddresses->PrefetchMemory.Base = 1;
+
+ switch(InterfaceType) {
+
+ case PCIBus:
+
+ Ponce = HalpPonceNumber((ULONG)BusNumber);
+ if(Ponce == 0){
+ // Ponce 0: Below 64M is EISA/ISA Memory Area.
+ Bus->BusAddresses->Memory.Base = 0x04000000;
+ }else{
+// Bus->BusAddresses->Memory.Base = 0x0;
+ // Less than 16M is PCI DMA area.
+ Bus->BusAddresses->Memory.Base = 0x01000000;
+ }
+ Bus->BusAddresses->Memory.Limit = 0x3fffffff; //1G
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart
+ = PCI_MEMORY_PHYSICAL_BASE_LOW+
+ PCI_MAX_MEMORY_SIZE * Ponce;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->HighPart
+ = PCI_MEMORY_PHYSICAL_BASE_HIGH;
+ if(Ponce == 0){
+ // N.B
+ // Io Manager allocate PCI I/O area From high addr of I/O space.
+ // EISA I/O Addr is Slot dependent and R98B max eisa slot is 3.
+ // So EISA i/o addr is below 0x4000. Perhaps PCI and EISA I/O area
+ // not conflict. But When One of PCI Device big I/O area required
+ // whitch EISA Device Slot dependent I/O area.
+ // PCI device positive decode and EISA Device can't decode.
+ // EISA device can decode when PCEB substruct decode of PCI cycle.
+ // (Any Device can't positivedecode)
+ // So Set IO.Base EISA 4 slot I/O addr.(Never EISA Slot 4)
+ //
+// Bus->BusAddresses->IO.Base = 0x00004000;
+ //
+ // 4000 - 4fff is dummy backward compatibility for scsi.
+ // It is Dummy Area. See
+ //
+ Bus->BusAddresses->IO.Base = 0x00005000;
+ }else{
+ Bus->BusAddresses->IO.Base = 0x00000000;
+ }
+ Bus->BusAddresses->IO.Limit = 0x0000FFFF; //64K
+
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->LowPart
+ = PCI_CNTL_PHYSICAL_BASE+
+ PCI_MAX_CNTL_SIZE * Ponce;
+
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->HighPart
+ = 0x0;
+ break;
+
+
+ case Internal:
+
+ Bus->BusAddresses->Dma.Limit = 7; // 0-7 channel
+ Bus->BusAddresses->Memory.Base
+ = 0x00000000;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Limit))->LowPart
+ = 0x3FFFFFFF; // 1G
+ Bus->BusAddresses->Memory.SystemBase
+ = 0x00000000;
+ Bus->BusAddresses->IO.Base
+ = 0x00000000;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.Limit))->LowPart
+ = 0x3FFFFFFF; // 1G
+ Bus->BusAddresses->IO.SystemBase
+ = 0x00000000;
+ break;
+
+
+ case Eisa:
+ case Isa:
+
+ Bus->BusAddresses->Dma.Limit = 7; // 0-7 channel
+
+ Bus->BusAddresses->Memory.Base = 0x00000000;
+
+ if(InterfaceType == Eisa){
+ Bus->BusAddresses->Memory.Limit = 0x03FFFFFF; //64M
+ }else{
+ //
+ // ISA or Internal(XBus)
+ //
+ Bus->BusAddresses->Memory.Limit = 0x00FFFFFF; //16M
+ }
+
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart
+ = EISA_MEMORY_PHYSICAL_BASE_LOW;
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->HighPart
+ = EISA_MEMORY_PHYSICAL_BASE_HIGH;
+
+ Bus->BusAddresses->IO.Base = 0x00000000;
+
+ //
+ // Max Slot is 3 . Bad Alias . So 3fff --> 4fff
+ //
+ Bus->BusAddresses->IO.Limit = 0x00004fff; // For max 3 slot.
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->LowPart
+ = EISA_CNTL_PHYSICAL_BASE;
+
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->HighPart
+ = 0;
+ break;
+ }
+ }
+
+ return Bus;
+}
diff --git a/private/ntos/nthals/halr98b/mips/rxclock.s b/private/ntos/nthals/halr98b/mips/rxclock.s
new file mode 100644
index 000000000..9c0010046
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxclock.s
@@ -0,0 +1,368 @@
+// TITLE("Interval and Profile Clock Interrupts")
+//++
+//
+// Copyright (c) 1991-1994 Microsoft Corporation
+//
+// Module Name:
+//
+// r98clock.s
+//
+// Abstract:
+//
+// This module implements the code necessary to field and process the
+// interval and profile clock interrupts on a MIPS R4000 system.
+//
+//--
+
+#include "halmips.h"
+#include "r98bdef.h"
+
+#define ECC_ERROR_COUNT_LIMIT 1
+#define CNFG_CONNECT4_MAGELLAN0 0x00800000 //it is MAGELLAN 0
+#define CNFG_CONNECT4_MAGELLAN1 0x00400000 //it is MAGELLAN 1
+
+
+ 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:
+//
+// a0 - 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
+
+ sw zero,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x50(zero) // Columnbs TOVCT1 reg.
+
+ 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.
+//
+
+ la t0,HalpStartWDTFlag
+ lw t1,0x0(t0)
+ beq zero,t1,2f
+ la t2,HalpSetWDTCount
+ lw t1,0x0(t2)
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x80(zero) // Columnbs reg.
+ li t1,0x00000002
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x90(zero) // Columnbs reg.
+ sw zero,0x0(t0)
+2: la t0,HalpStopWDTFlag
+ lw t1,0x0(t0)
+ beq zero,t1,3f
+ li t1,0x00000001
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x90(zero) // Columnbs reg.
+ sw zero,0x0(t0)
+3: la t0,HalpSetWDTFlag
+ lw t1,0x0(t0)
+ beq zero,t1,4f
+ li t1,0x00000002
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x90(zero) // Columnbs reg.
+ sw zero,0x0(t0)
+4:
+
+//
+// Check ECC 1bit error flag.
+//
+
+ lw t0,HalpECC1bitDisableTime // get value of disable time
+ beq zero,t0,10f // if ne, check ecc 1bit
+ lw t1,HalpCurrentTimeIncrement // get current time increment
+ subu t0,t0,t1 // declement disable time
+ sw t0,HalpECC1bitDisableTime //
+ blez t0,5f // if lez, enable ecc 1bit
+ beq zero,zero,10f // not lez,
+
+5: sw zero,HalpECC1bitDisableTime // clear disable time
+ li t0,ECC_ERROR_COUNT_LIMIT // set new flag
+ sw t0,HalpECC1bitDisableFlag //
+ la t1,KSEG1_BASE+MAGELLAN_0_PHYSICAL_BASE+MAGELLAN_ERRI_OFFSET
+ lw t2,HalpPhysicalNode // check connect to Magellan
+ and t0,t2,CNFG_CONNECT4_MAGELLAN0
+ bne t0,zero,7f
+ lw t0,0x0(t1)
+ and t0,ECC_1BIT_ENABLE
+ sw t0,0x0(t1) // enable ECC 1bit error
+7:
+ and t0,t2,CNFG_CONNECT4_MAGELLAN1
+ bne t0,zero,10f
+ la t1,KSEG1_BASE+MAGELLAN_1_PHYSICAL_BASE+MAGELLAN_ERRI_OFFSET
+ lw t0,0x0(t1)
+ and t0,ECC_1BIT_ENABLE
+ sw t0,0x0(t1) // enable ECC 1bit error
+
+//
+// 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).
+//
+
+10: 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
+
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x40(zero) // Columnbs TMSR1 reg.
+
+ .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
+ break BREAKIN_BREAKPOINT // break into the 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:
+//
+// a0 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpClockInterrupt1)
+
+ sw zero,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x50(zero) // Columnbs TOVCT1 reg.
+
+ lw t1,KiPcr + PcPrcb(zero) // get current processor block address
+
+#if 0
+ la t2,HalpChangeIntervalFlg // get change flag of timer interval
+ lbu t1,PbNumber(t1) // get processor number
+ add t2,t1,t2 // check flag
+ lb t1,0x0(t2) // get change flag of this CPU
+ beq t1,zero,10f // if eq, no change timer interval
+ sb zero,0x0(t2) // clear change flag of timer interval
+
+ lw t1,HalpChangeIntervalCount // get next interval count
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x40(zero) // Columnbs TMSR1 reg.
+10:
+#endif
+
+ lw t1,KiPcr + PcPrcb(zero) // get current processor block address
+ lbu t4,PbNumber(t1) // get processor number
+ sll t4,t4,2 // compute address
+ la t0,HalpStartWDTFlag
+ addu t0,t0,t4 //
+ lw t1,0x0(t0)
+ beq zero,t1,12f
+ la t2,HalpSetWDTCount
+ addu t2,t2,t4 //
+ lw t1,0x0(t2)
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x80(zero) // Columnbs reg.
+ li t1,0x00000002
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x90(zero) // Columnbs reg.
+ sw zero,0x0(t0)
+12: la t0,HalpStopWDTFlag
+ addu t0,t0,t4 //
+ lw t1,0x0(t0)
+ beq zero,t1,14f
+ li t1,0x00000001
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x90(zero) // Columnbs reg.
+ sw zero,0x0(t0)
+14: la t0,HalpSetWDTFlag
+ addu t0,t0,t4 //
+ lw t1,0x0(t0)
+ beq zero,t1,16f
+ li t1,0x00000002
+ sw t1,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x90(zero) // Columnbs reg.
+ sw zero,0x0(t0)
+16: lw t1,__imp_KeUpdateRunTime // update system runtime
+ j t1
+
+ .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:
+//
+// a0 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpProfileInterrupt)
+
+ .set noreorder
+ .set noat
+
+ li t0,KSEG1_BASE + COLUMNBS_LPHYSICAL_BASE+0x70
+ sw zero 0x0(t0)
+
+ mfc0 t0,count // get current count value
+ addu t1,zero,3 // set initial count value
+ mtc0 t1,count // set new count register value
+
+ .set at
+ .set reorder
+
+ 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 //
+
+ 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
+
+ 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/halr98b/mips/rxdisp.c b/private/ntos/nthals/halr98b/mips/rxdisp.c
new file mode 100644
index 000000000..a006c603e
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxdisp.c
@@ -0,0 +1,61 @@
+//
+// Compile test for stub
+//
+//
+
+#include "halp.h"
+#include "jazzvdeo.h"
+#include "jzvxl484.h"
+#include <jaginit.h>
+
+#include "cirrus.h"
+#include "modeset.h"
+#include "mode542x.h"
+
+#include "string.h"
+#include <tga.h>
+
+
+VOID
+HalAcquireDisplayOwnership (
+ IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters
+ )
+
+{
+ return;
+}
+
+VOID
+HalDisplayString (
+ PUCHAR String
+ )
+{ return;}
+
+VOID
+HalQueryDisplayParameters (
+ OUT PULONG WidthInCharacters,
+ OUT PULONG HeightInLines,
+ OUT PULONG CursorColumn,
+ OUT PULONG CursorRow
+ )
+{ return;}
+
+VOID
+HalSetDisplayParameters (
+ IN ULONG CursorColumn,
+ IN ULONG CursorRow
+ )
+{return;}
+
+BOOLEAN
+HalpInitializeDisplay0 (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+{return TRUE;}
+
+BOOLEAN
+HalpInitializeDisplay1 (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+
+{return TRUE;}
diff --git a/private/ntos/nthals/halr98b/mips/rxdspt.c b/private/ntos/nthals/halr98b/mips/rxdspt.c
new file mode 100644
index 000000000..11aa9fc80
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxdspt.c
@@ -0,0 +1,547 @@
+/*++
+
+Copyright (c) 1994 Kobe NEC Software
+
+Module Name:
+
+ rxdspt.c
+
+Abstract:
+
+ This module implements the interrupt dispatch routines for R98
+
+Author:
+
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+
+
+#include "halp.h"
+
+#include "bugcodes.h"
+
+//
+// Define the context structure for use by the interrupt routine.
+//
+
+typedef BOOLEAN (*PSECONDARY_DISPATCH)(
+ PVOID InterruptRoutine
+ );
+
+typedef BOOLEAN (*PTIMER_DISPATCH)(
+ ULONG TrapFrame
+ );
+
+
+//
+// Dummy Read Registers
+//
+//
+volatile ULONG DUMMYADDRS[]={
+ 0x1c0003f1|KSEG1_BASE, //FDC37C665 config register
+ 0x1c4033c7|KSEG1_BASE, //VGA DAC STATE register
+ 0x1c0003f1|KSEG1_BASE, //FDC37C665 config register
+ 0x1c000023|KSEG1_BASE, //ESC Configuration register
+ 0x1c4033c7|KSEG1_BASE, //VGA DAC STATE register
+ 0x19800610|KSEG1_BASE //Err node register
+
+};
+
+//
+// Following structures will be changed by HalAllProcessorsStarted() on
+// boot up HAL.
+// Because each interrupt connects each processor on boot up HAL.
+// v-masank@microsoft.com
+//
+
+INT_ENTRY HalpIntEntry[R98_CPU_NUM_TYPE][R98B_MAX_CPU][NUMBER_OF_INT]={
+
+{// For R4400 [CPU][INT x] {StartBit, NumberOfBit,Arbitar,Enable,Open}
+
+ { // For CPU #0
+ {0, 16 ,0,(ULONGLONG)0x000000000000e1b6,0}, //INT0
+ {16, 16 ,0,(ULONGLONG)0x00000000e3f00000,0}, //INT1
+ {32, 12 ,0,(ULONGLONG)0x000000f800000000,0}, //INT2
+ {56, 2 ,0,(ULONGLONG)0x0300000000000000,0}, //INT3
+ {48, 4 ,0,(ULONGLONG)0x000f000000000000,0}, //INT4
+ {61, 2 ,0,(ULONGLONG)0x6000000000000000,0} //INT5
+ },
+ { // For CPU #1
+ {0, 16 ,0,(ULONGLONG)0x000000000000e1b6,0}, //INT0
+ {16, 16 ,0,(ULONGLONG)0x00000000e3f00000,0}, //INT1
+ {32, 12 ,0,(ULONGLONG)0x000000f800000000,0}, //INT2
+ {56, 2 ,0,(ULONGLONG)0x0300000000000000,0}, //INT3
+ {48, 4 ,0,(ULONGLONG)0x000f000000000000,0}, //INT4
+ {61, 2 ,0,(ULONGLONG)0x6000000000000000,0} //INT5
+ },
+ { // For CPU #2
+ {0, 16 ,0,(ULONGLONG)0x000000000000e1b6,0}, //INT0
+ {16, 16 ,0,(ULONGLONG)0x00000000e3f00000,0}, //INT1
+ {32, 12 ,0,(ULONGLONG)0x000000f800000000,0}, //INT2
+ {56, 2 ,0,(ULONGLONG)0x0300000000000000,0}, //INT3
+ {48, 4 ,0,(ULONGLONG)0x000f000000000000,0}, //INT4
+ {61, 2 ,0,(ULONGLONG)0x6000000000000000,0} //INT5
+ },
+ { // For CPU #3
+ {0, 16 ,0,(ULONGLONG)0x000000000000e1b6,0}, //INT0
+ {16, 16 ,0,(ULONGLONG)0x00000000e3f00000,0}, //INT1
+ {32, 12 ,0,(ULONGLONG)0x000000f800000000,0}, //INT2
+ {56, 2 ,0,(ULONGLONG)0x0300000000000000,0}, //INT3
+ {48, 4 ,0,(ULONGLONG)0x000f000000000000,0}, //INT4
+ {61, 2 ,0,(ULONGLONG)0x6000000000000000,0} //INT5
+ }
+
+},
+
+{// For R10000 [CPU][INT x] {StartBit, NumberOfBit,Arbitar,Enable,Open}
+
+
+ {
+ {0, 16 ,0,(ULONGLONG)0x000000000000e1b6,0}, //INT0
+ {16, 28 ,0,(ULONGLONG)0x000000f8e3f00000,0}, //INT1
+ {56, 2 ,0,(ULONGLONG)0x0300000000000000,0}, //INT2
+ {48, 4 ,0,(ULONGLONG)0x000f000000000000,0}, //INT3
+ {61, 2 ,0,(ULONGLONG)0x6000000000000000,0}, //INT4
+ {NONE, 0 ,0,(ULONGLONG)0,0} //INT5
+ },
+ {
+ {0, 16 ,0,(ULONGLONG)0x000000000000e1b6,0}, //INT0
+ {16, 28 ,0,(ULONGLONG)0x000000f8e3f00000,0}, //INT1
+ {56, 2 ,0,(ULONGLONG)0x0300000000000000,0}, //INT2
+ {48, 4 ,0,(ULONGLONG)0x000f000000000000,0}, //INT3
+ {61, 2 ,0,(ULONGLONG)0x6000000000000000,0}, //INT4
+ {NONE, 0 ,0,(ULONGLONG)0,0} //INT5
+ },
+ {
+ {0, 16 ,0,(ULONGLONG)0x000000000000e1b6,0}, //INT0
+ {16, 28 ,0,(ULONGLONG)0x000000f8e3f00000,0}, //INT1
+ {56, 2 ,0,(ULONGLONG)0x0300000000000000,0}, //INT2
+ {48, 4 ,0,(ULONGLONG)0x000f000000000000,0}, //INT3
+ {61, 2 ,0,(ULONGLONG)0x6000000000000000,0}, //INT4
+ {NONE, 0 ,0,(ULONGLONG)0,0} //INT5
+ },
+ {
+ {0, 16 ,0,(ULONGLONG)0x000000000000e1b6,0}, //INT0
+ {16, 28 ,0,(ULONGLONG)0x000000f8e3f00000,0}, //INT1
+ {56, 2 ,0,(ULONGLONG)0x0300000000000000,0}, //INT2
+ {48, 4 ,0,(ULONGLONG)0x000f000000000000,0}, //INT3
+ {61, 2 ,0,(ULONGLONG)0x6000000000000000,0}, //INT4
+ {NONE, 0 ,0,(ULONGLONG)0,0} //INT5
+ }
+}
+
+};
+
+RESET_REGISTER HalpResetValue[NUMBER_OF_IPR_BIT]={
+ {0,0,0,0}, //Bit 0
+ {PONCE1,PCIINTD,0,DUMMY_A4}, //Bit 1 PCI I/O Slot#8-#10 INTD
+ {PONCE0,PCIINTD,0,DUMMY_A3}, //Bit 2 PCI I/O Slot#4-#7 INTD
+ {0x0,0x0,0,0}, //Bit 3
+
+ {PONCE1,PCIINTC,0,DUMMY_A4}, //Bit 4 PCI I/O Slot#8-#10 INTC
+ {PONCE0,PCIINTC,0,DUMMY_A3}, //Bit 5 PCI I/O Slot#4-#7 INTC
+ {0x0,0x0,0,0} , //Bit 6
+ {PONCE1,PCIINTB,0,DUMMY_A4}, //Bit 7 PCI I/O Slot#8-#10 INTB
+
+ {PONCE0,PCIINTB,0,DUMMY_A3}, //Bit8 PCI I/O Slot#4-#7 INTB
+ {0x0,0x0,0,0}, //Bit9
+ {0x0,0x0,0,0}, //Bit10
+ {0x0,0x0,0,0}, //Bit11
+
+ {0x0,0x0,0,0}, //Bit12
+ {PONCE0,INTSA0,0x0,DUMMY_A3}, //Bit13 EISA Bridge
+ {PONCE1,INTSB0,0x0,DUMMY_A2}, //Bit14 Parallel
+ {PONCE0,INTSB0,0x0,DUMMY_A2}, //Bit15 FDC
+
+ {0x0,0x0,0,0}, //Bit16
+ {0x0,0x0,0,0}, //Bit17
+ {0x0,0x0,0,0}, //Bit18
+ {0x0,0x0,0,0}, //Bit19
+
+ {PONCE1,PCIINTA1,0x0,DUMMY_A4}, //Bit20 PCI I/O Slot#8 INTA
+ {PONCE1,PCIINTA0,0x0,DUMMY_A4}, //Bit21 PCI I/O Slot#9 INTA
+ {PONCE0,PCIINTA3,0x0,DUMMY_A3}, //Bit22 PCI I/O Slot#4 INTA
+ {PONCE0,PCIINTA2,0x0,DUMMY_A3}, //Bit23 PCI I/O Slot#5 INTA
+
+ {PONCE0,PCIINTA1,0,DUMMY_A3}, //Bit24 PCI I/O Slot#6 INTA
+ {PONCE0,PCIINTA0,0,DUMMY_A3}, //Bit25 PCI I/O Slot#7 INTA
+ {0x0,0x0,0,0}, //Bit26
+ {0x0,0x0,0,0}, //Bit27
+
+ {0x0,0x0,0,0}, //Bit28
+ {PONCE1,INTSA0,0x0,DUMMY_A1}, //Bit29 LAN(Ethernet)
+ {PONCE1,PCIINTA3,0x0,DUMMY_A1}, //Bit30 SCSI#1(Narrow)
+ {PONCE1,PCIINTA2,0x0,DUMMY_A1}, //Bit31 SCSI#0(Wide)
+
+ {0x0,0x0,0,0}, //Bit32
+ {0x0,0x0,0,0}, //Bit33
+ {0x0,0x0,0,0}, //Bit34 Tracer ponce Internal
+ {0x0,0x0,0,0}, //Bit35 TLB Undefine Address
+
+ {PONCE1,INTSB1,0,DUMMY_A0}, //Bit36 Mouse
+ {PONCE1,INTSA1,0,DUMMY_A0}, //Bit37 KeyBoard
+ {PONCE0,INTSB1,0,DUMMY_A0}, //Bit38 SIO#1
+ {PONCE0,INTSA1,0,DUMMY_A0}, //Bit39 SIO#0
+
+ { RFU,0,0,0}, //Bit40
+ { RFU,0,0,0}, //Bit41
+ { RFU,0,0,0}, //Bit42
+ { RFU,0,0,0}, //Bit43
+
+// Never Used This is no Device Interrupt.
+
+ { RFU,0,0,0}, //Bit44
+ { RFU,0,0,0}, //Bit45
+ { RFU,0,0,0}, //Bit46
+ { RFU,0,0,0}, //Bit47
+
+ { RFU,0,0,0}, //Bit48 From CPU#3 IPI
+ { RFU,0,0,0}, //Bit49 From CPU#2 IPI
+ { RFU,0,0,0}, //Bit50 From CPU#1 IPI
+ { RFU,0,0,0}, //Bit51 From CPU#0 IPI
+
+ { RFU,0,0,0}, //Bit52
+ { RFU,0,0,0}, //Bit53
+ { RFU,0,0,0}, //Bit54
+ { RFU,0,0,0}, //Bit55
+
+ { RFU,0,0,0}, //Bit56 Interval timer 2 Profile
+ { RFU,0,0,0}, //Bit57 Interval timer 1 Clock
+ { RFU,0,0,0}, //Bit58
+ { RFU,0,0,0}, //Bit59
+
+ { RFU,0,0,0}, //Bit60
+ { RFU,0,0,0}, //Bit61 EIF+MRCINT
+ { RFU,0,0,0}, //Bit62 Memory 1Bit Error
+ { RFU,0,0,0} //Bit63
+
+};
+
+// Thanks very much for pete-san's cooporation.
+// Pete-san write most of following source code.
+// v-masak@microsoft.com
+// 5/17/96
+
+#define HalpFindFirstSetMember(Set) \
+ ((Set & 0xFF) ? HalpFindFirstSet[Set & 0xFF] : \
+ ((Set & 0xFF00) ? HalpFindFirstSet[(Set >> 8) & 0xFF] + 8 : \
+ ((Set & 0xFF0000) ? HalpFindFirstSet[(Set >> 16) & 0xFF] + 16 : \
+ HalpFindFirstSet[(Set >> 24) & 0xff] + 24)))
+
+ULONG HalpFindFirstSet[256] = {
+ 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
+
+PINT_ENTRY HalpIntEntryPointer;
+
+//
+// I use LargeReigester access function for performance
+// v-masank@microsoft.com
+// I used 64 bit shift.
+// v-masank@microsoft.com
+//
+
+VOID
+HalpGeneralDispatch(
+ IN ULONG TrapFrame,
+ IN ULONG IntNo
+ )
+
+/*++
+
+Routine Description:
+
+ This is the general hal interrupt dispatch routine. This services hardware interrupts
+ for range ip[3..8]
+
+
+Arguments:
+
+ IN ULONG TrapFrame - This interrupts trapframe
+ IN ULONG IntNo - The current Interrupt Number range IntNo[0..5] maps to IP[3..8]
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ volatile PULONGLONG Register;
+ ULONGLONG Enable;
+ volatile ULONGLONG IPR;
+ ULONGLONG IprBit;
+ ULONG ULIPR;
+ ULONG CpuNumber;
+ ULONG cnt;
+ ULONG IprBitNumber;
+ ULONG Ponce;
+ UCHAR Data;
+ ULONG StartBit;
+ //
+ // Get CpuNumber
+ //
+ CpuNumber = PCR->Number;
+
+ //
+ // Get Enable table offset
+ //
+ cnt = CpuNumber * NUMBER_OF_INT;
+ //
+ // The interrupt controller on the R98A/B occasionally (rarely) sends
+ // an interrupt to multiple processors. One is the correct processor to
+ // handle the interrupt the other is not. The enable bit
+ // determines if this processor handles this interrupt.
+ //
+ // The table HalpIntEntryPointer gets initalized for the correct processor at boot
+ // (i.e., R98A or R98B).
+
+ Enable=HalpIntEntryPointer[cnt+IntNo].Enable;
+ StartBit = HalpIntEntryPointer[cnt+IntNo].StartBitNo;
+ //
+ // Do until no more interrupts pending
+ //
+ do {
+
+ //
+ // IPR register read
+ //
+ Register = (PULONGLONG)&((COLUMNBS_LCNTL)->IPR);
+ HalpReadLargeRegister(Register,(PULONGLONG)&IPR);
+
+ // MASK
+ //
+ // Determine if this Interrupt enabled for this processor
+ //
+ IPR = IPR & Enable;
+ //
+ // 28 is the largest interrupt bit vector possible on these machines
+ // StartBit is the starting bit position for this interrupt level
+ // Shift the 64 bit interrupt register into a 32 bit field
+ // to make the find first bit set operation easier
+ ULIPR = (ULONG) (IPR >> StartBit);
+ if(ULIPR==0){
+ continue; // No interrupts handled by this processor
+ }
+ do{
+ //
+ // Service all pending interrupts for this ip level
+ //
+ while(ULIPR!=0){
+
+ //
+ // Get Interrupt bit set No. on IPR.
+ //
+ IprBitNumber = HalpFindFirstSetMember(ULIPR) + StartBit;
+ IprBit = 1UI64 << IprBitNumber; // Save this value for clearing INT
+ //
+ // IPR register read
+ // IntNo 0 1 2 3 4 5
+ //
+ // R98A Starting bit pos 0 16 32 56 48 61
+ // R98B Starting bit pos 0 16 56 48 61 NA
+ //
+ // On the R98A/B Each interrupt level can have multiple
+ // concurrentinterrupt sources
+ // (e.g., the read of IPR can have more than 1 bit set
+ //
+ //
+ // Hardware Ip #of possible interrupt sources
+ // R98A R98B
+ // ip[3] 16 16
+ // ip[4] 16 28
+ // ip[5] 12 2
+ // ip[6] 2 4
+ // ip[7] 4 2
+ // ip[8] 2 0
+ //
+ // During initialization the HAL assigns affinity to interrupt sources. So that
+ // the interrupt always gets serviced on the same processor
+
+
+
+ switch (IprBitNumber) {
+
+ case 62:
+ //
+ // call Ecc Error service routine
+ //
+ ((PSECONDARY_DISPATCH)PCR->InterruptRoutine[62+DEVICE_VECTORS])
+ (PCR->InterruptRoutine[62+DEVICE_VECTORS]);
+ //
+ // Clear IPR
+ //
+ Register=(PULONGLONG) &((COLUMNBS_LCNTL)->IPRR);
+ HalpWriteLargeRegister(Register,&IprBit);
+ break;
+ case 61:
+ //
+ // This interrupt gets sent to all processors.
+ // Our friend the HalpDieLock controls exclusive access
+ // protecting the power switch interrupt service routine
+ // and for some reason the read/write of the Power interrupt
+ // register.
+ //
+ //
+ KiAcquireSpinLock(&HalpDieLock);
+ //
+ // It's EIF or MRC INT
+ //
+ ((PSECONDARY_DISPATCH)PCR->InterruptRoutine[61+DEVICE_VECTORS])
+ (PCR->InterruptRoutine[61+DEVICE_VECTORS]);
+
+
+ // HACK HACK HACK !!
+ HalpLocalDeviceReadWrite(MRCINT,&Data,LOCALDEV_OP_READ);
+ if( Data & 0x04){
+ //
+ // At This time If MRCINT Register reported Power Interrupt.
+ // Power Driver failed or happenig ocurred.
+ // if anyone push DUMP KEY. Hal may be system reset.
+ // So Reset Power Interrupt.
+ //
+
+ Data = 0x0;
+ HalpLocalDeviceReadWrite(MRCINT, &Data, LOCALDEV_OP_WRITE);
+ }
+
+ KiReleaseSpinLock(&HalpDieLock);
+
+ //
+ //Clear IPR
+ //
+
+ Register= (PULONGLONG) &(COLUMNBS_LCNTL)->IPRR;
+ HalpWriteLargeRegister(Register,&IprBit);
+ break;
+ case 56:
+ case 57:
+ //
+ // Profile or Clock
+ //
+ ((PTIMER_DISPATCH)PCR->InterruptRoutine[IprBitNumber+DEVICE_VECTORS])(TrapFrame);
+ //
+ //Clear IPR
+ //
+
+ Register= (PULONGLONG)&(COLUMNBS_LCNTL)->IPRR;
+ HalpWriteLargeRegister(Register,&IprBit);
+ break;
+ case 48:
+ case 49:
+ case 50:
+ case 51:
+
+ //
+ // Clear IPR
+ //
+
+ Register= (PULONGLONG) &(COLUMNBS_LCNTL)->IPRR;
+ HalpWriteLargeRegister(Register,&IprBit);
+
+ //
+ // IPI interrupts. One for each possible CPU
+ //
+ ((PTIMER_DISPATCH) PCR->InterruptRoutine[IprBitNumber+DEVICE_VECTORS])(TrapFrame);
+ break;
+ default:
+ //
+ // Device Interrupt !!
+ //
+ Ponce = HalpResetValue[IprBitNumber].Ponce;
+
+
+ //
+ // 1. Clear INTRG register of PONCE
+ //
+ WRITE_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->INTRG,
+ 0x1 << HalpResetValue[IprBitNumber].IntGResetBit);
+
+ //
+ // 2. Call interrupt service routine
+ //
+ ((PSECONDARY_DISPATCH)PCR->InterruptRoutine[IprBitNumber+DEVICE_VECTORS])(
+ PCR->InterruptRoutine[IprBitNumber+DEVICE_VECTORS]);
+
+ //
+ // 3. Dummy Read execute
+ //
+
+ READ_REGISTER_UCHAR( DUMMYADDRS[HalpResetValue[IprBitNumber].Dummy]);
+ READ_REGISTER_UCHAR( DUMMYADDRS[HalpResetValue[IprBitNumber].Dummy]);
+
+ //
+ // 4. Clear IPR Bit By IPRR Register
+ //
+
+ Register = (PULONGLONG) &(COLUMNBS_LCNTL)->IPRR;
+ HalpWriteLargeRegister(Register,&IprBit);
+
+ //
+ // 5.Clear INTRG register of PONCE
+ //
+
+
+ WRITE_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->INTRG,
+ 0x1 << (HalpResetValue[IprBitNumber].IntGResetBit + 21));
+
+ } // End Switch
+ //
+ // Clear the bit in the interrupt register
+ // that we just serviced
+ //
+ ULIPR = ULIPR & ~(1 << (IprBitNumber - StartBit));
+ } // End while servicing current interrupt. Check for more
+ //
+ // Determine if another interrupt pending at the same level before leaving
+ // this dispatch routine. The hardware spec implies that there is
+ // a small window that the interrupt register has bits set before the
+ // cause register. So it suggests checking the interrupt register
+ // before the cause
+ //
+ //
+ // check new interrupt
+ //
+ //
+ // IPR register read
+ //
+ Register = (PULONGLONG)&((COLUMNBS_LCNTL)->IPR);
+ HalpReadLargeRegister(Register,(PULONGLONG)&IPR);
+
+ // MASK
+ //
+ // Determine if this Interrupt enabled for this processor
+ //
+
+ IPR = IPR & Enable;
+ ULIPR = (ULONG) (IPR >> StartBit);
+ }while(ULIPR!=0); // End do-while
+ //
+ // Check cause register to see if an interrupt pending for the current level
+ //
+ } while(HalpGetCause() & (1 << CAUSE_INT_PEND_BIT+IntNo));
+}
+
diff --git a/private/ntos/nthals/halr98b/mips/rxecc.c b/private/ntos/nthals/halr98b/mips/rxecc.c
new file mode 100644
index 000000000..677fe877e
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxecc.c
@@ -0,0 +1,791 @@
+/*++
+
+Copyright (c) 1994 Kobe NEC Software
+
+Module Name:
+
+ rxecc.c
+
+Abstract:
+
+ This module implements the ECC 1bit/Multi bit Error interrupt service routine for R98B
+
+Author:
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+/*
+ *
+ * NEW CODE '95.11/17 K.Kitagaki
+ *
+ */
+
+#include "halp.h"
+#include "esmnvram.h"
+#include "rxesm.h"
+#include "bugcodes.h"
+#include "stdio.h"
+
+#if defined(ECC_DBG)
+int
+TmpInitNvram(void);
+int
+TmpInitNvram2(void);
+#endif
+
+//
+// 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 ESM_MM_SYUKUTAI_TOPOST_OFFSET 0x1d08
+
+
+#define TIME_STAMP_SIZE 14
+
+//
+// define value
+//
+#define NVRAM_VALID 3
+#define ECC_LOG_VALID_FLG 1
+
+#define STRING_BUFFER_SIZE 512
+
+#define ECC_1BIT_ERROR_DISABLE_TIME 5*1000*1000*10
+
+#define ECC_1BIT_ENABLE_MASK 0x0000000a
+#define ECC_1BIT_DISABLE_MASK 0xfffffff5
+
+//
+// Define global variable. This variable use in display string into nvram.
+//
+USHORT ErrBufferLatest;
+USHORT ErrBufferArea;
+USHORT ErrBufferStart;
+USHORT ErrBufferEnd;
+USHORT ErrBufferCurrent;
+UCHAR HalpNvramStringBuffer[STRING_BUFFER_SIZE];
+
+LONG HalpECC1bitDisableFlag=1;
+LONG HalpECC1bitDisableTime=0;
+ULONG HalpECC1bitScfrBuffer=0;
+
+VOID
+HalpEcc1Logger(
+ IN ULONG Node
+);
+VOID
+HalpEcc2Logger(
+ IN ULONG Node
+);
+//
+// Define macro
+//
+
+#define GET_TIME(Buffer) { \
+ TIME_FIELDS timeBuffer; \
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKSR,\
+ 63-(EIF_VECTOR-DEVICE_VECTORS ));\
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKSR,\
+ 63-(ECC_1BIT_VECTOR-DEVICE_VECTORS ));\
+ HalQueryRealTimeClock( &timeBuffer ); \
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKRR,\
+ 63-(EIF_VECTOR-DEVICE_VECTORS ));\
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKRR,\
+ 63-(ECC_1BIT_VECTOR-DEVICE_VECTORS ));\
+ sprintf( (Buffer), \
+ "%04d%02d%02d%02d%02d%02d", \
+ timeBuffer.Year, \
+ timeBuffer.Month, \
+ timeBuffer.Day, \
+ timeBuffer.Hour, \
+ timeBuffer.Minute, \
+ timeBuffer.Second \
+ ); \
+}
+
+#define DONT_NOTIFY_ECC1BIT { \
+ ULONG buffer; \
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0) == 0 ){ \
+ buffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRI ); \
+ buffer |= ECC_1BIT_ENABLE_MASK; \
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRI, buffer); \
+ } \
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1) == 0 ){ \
+ buffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRI ); \
+ buffer |= ECC_1BIT_ENABLE_MASK; \
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRI, buffer); \
+ } \
+}
+
+#define NOTIFY_ECC1BIT { \
+ ULONG buffer; \
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0) == 0 ){ \
+ buffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRI ); \
+ buffer &= ECC_1BIT_DISABLE_MASK; \
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRI, buffer); \
+ } \
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1) == 0 ){ \
+ buffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRI ); \
+ buffer &= ECC_1BIT_DISABLE_MASK; \
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRI, buffer); \
+ } \
+}
+
+#if 1 // suported
+
+VOID
+HalpEcc1bitError(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine check ecc 1bit error and error log put in NVRAM.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ ULONG magSet;
+ USHORT infoOffset;
+ USHORT writeOffset;
+ ULONG sts1Buffer;
+ ULONG sdlmBuffer;
+ ULONG dsrgBuffer;
+ ULONG buffer;
+ ULONG i;
+ ULONG errAddr;
+ UCHAR dataBuf[36];
+ UCHAR infoBuf[24];
+ UCHAR tempBuf[24];
+
+ ULONG Ponce0AllError;
+ ULONG MagellanAdec;
+ ULONG Magellan0AllError = 0;
+ ULONG Magellan1AllError = 0;
+ ULONG simmMIN;
+ ULONG MemoryBlock;
+ volatile PULONG Registerp;
+
+#if defined(ECC_DBG)
+ DbgPrint("ECC 1Bit Error IN !!!\n");
+#endif
+
+// HalpECC1bitScfrBuffer = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD);
+ Ponce0AllError = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(0)->AERR);
+
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0) == 0 ){
+ Magellan0AllError = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->AERR );
+ }
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1) == 0 ){
+ Magellan1AllError = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->AERR );
+ }
+
+ //
+ // Check ECC 1bit error
+ //
+
+ if ( Ponce0AllError & 0x00000200 ){
+ if ( Magellan0AllError & 0x0000000a ){
+ magSet = 0;
+#if defined(ECC_DBG)
+ DbgPrint("Magellan#%x:AERR = %x\n",magSet,Magellan0AllError);
+#endif
+ } else if ( Magellan1AllError & 0x0000000a ){
+ magSet = 1;
+#if defined(ECC_DBG)
+ DbgPrint("Magellan#%x:AERR = %x\n",magSet,Magellan1AllError);
+#endif
+ } else {
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:OTHER ERR 1\n");
+#endif
+ return;
+ }
+ } else {
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:OTHER ERR 2\n");
+#endif
+ return;
+ }
+
+ //
+ // read diagnosis registers.
+ //
+
+ sts1Buffer = READ_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->STS1 );
+ dsrgBuffer = READ_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->DSRG );
+ sdlmBuffer = READ_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->SDLM );
+
+#if defined(ECC_DBG)
+ DbgPrint("Magellan#%x:STS1 = %x\n",magSet,sts1Buffer);
+#endif
+
+ Registerp = (PULONG)&MAGELLAN_X_CNTL(magSet)->ADEC0;
+ MagellanAdec = READ_REGISTER_ULONG( Registerp + ((sts1Buffer>>30)<<1) );
+
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:ADEC%x = %x\n",(sts1Buffer>>30),MagellanAdec);
+#endif
+
+ simmMIN = (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->MIN ) << 24;
+ if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->BLOCK ) == 1 ) {
+ MemoryBlock = 0x00000000;
+ } else if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->BLOCK ) == 2 ) {
+ MemoryBlock = 0x20000000;
+ } else {
+ return;
+ }
+
+ //
+ // HW Logging
+ //
+ HalpEcc1Logger( 8 + magSet );
+
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:MemoryBlock = %x\n",MemoryBlock);
+
+// TmpInitNvram();
+#endif
+
+ HalNvramRead( NVRAM_STATE_FLG_OFFSET, 1, dataBuf );
+ HalNvramRead( NVRAM_MAGIC_NO_OFFSET, 4, tempBuf );
+
+// case MAGELLAN_ECC_1BIT_ERROR:
+
+ if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){
+
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:Nvram Save Routine IN !!!\n");
+#endif
+ infoOffset=ECC_1BIT_ERROR_LOG_INFO_OFFSET;
+
+ HalNvramRead( (ULONG)infoOffset, 20, infoBuf);
+
+ //
+ // Disable and clear ECC 1bit error.
+ //
+
+ DONT_NOTIFY_ECC1BIT;
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:ECC 1bit Disable\n");
+#endif
+
+ WRITE_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->ERRST, 0x0a );
+ WRITE_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->SDCR, 0x00 );
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:ERRST, SDCR CLEAR\n");
+#endif
+
+ do {
+ buffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(magSet)->AERR );
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:AERR = %x\n", buffer);
+// DbgBreakPoint();
+#endif
+ } while ( (buffer & 0x0000000a) != 0 );
+
+ WRITE_REGISTER_ULONG((PULONG)&PONCE_CNTL(0)->ERRST, 0x00000200 );
+
+ Registerp = (PULONG)&(COLUMNBS_LCNTL)->IPRR;
+ WRITE_REGISTER_ULONG( Registerp++, 0x40000000 );
+#if defined(ECC_DBG)
+ DbgPrint("Columbus:IPRR CLEAR\n");
+#endif
+
+ //
+ // Check New error or Old error.
+ //
+
+ //
+ // Error Address Generate
+ //
+
+ if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->MAG ) == 0 ) { // B-MODE
+ if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->SIMM_2 ) == 0 ) {
+ errAddr = MemoryBlock + simmMIN +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->RF) << 24) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL0_1) << 4) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL2_9) << 6) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW0_9) << 14);
+#if defined(ECC_DBG)
+ DbgPrint("ERROR_ADDR = %x\n",errAddr);
+#endif
+ } else if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->SIMM_2 ) == 1 ) {
+ errAddr = MemoryBlock + simmMIN +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->RF) << 26) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL0_1) << 4) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL2_9) << 6) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL10) << 14) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW0_9) << 15) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW10) << 25);
+ }
+ } else if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->MAG ) == 1 ) { // M-MODE
+ if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->SIMM_2 ) == 0 ) {
+ errAddr = MemoryBlock + simmMIN +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->RF) << 25) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL0_1) << 4) +
+ ((ULONG)( magSet << 6 )) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL2_9) << 7) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW0_9) << 15);
+ } else if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->SIMM_2 ) == 1 ) {
+ errAddr = MemoryBlock + simmMIN +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->RF) << 27) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL0_1) << 4) +
+ ((ULONG)( magSet << 6 )) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL2_9) << 7) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL10) << 15) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW0_9) << 16) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW10) << 26);
+ }
+ }
+
+
+ HalpReadAndWritePhysicalAddr( errAddr );
+
+ 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 ( (errAddr == ((pECC1_ERR_REC)dataBuf)->err_address) &&
+ ( (((pECC1_ERR_REC)dataBuf)->record_flag & 0x1) != 0) ) {
+#if defined(ECC_DBG)
+ DbgPrint("for loop break\n");
+#endif
+ break;
+ }
+ }
+
+ if( i != ((pECC1_ERR_AREA_INFO)infoBuf)->num_rec ) {
+#if defined(ECC_DBG)
+ DbgPrint("goto next1bit P-1\n");
+#endif
+ goto next1bit;
+ }
+
+ //
+ // wait 20 us.
+ //
+
+ KeStallExecutionProcessor(20);
+
+ //
+ // Enable ECC 1bit error.
+ //
+
+ NOTIFY_ECC1BIT;
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:ECC 1bit Enable\n");
+#endif
+
+ //
+ // Check ECC 1bit error.
+ //
+
+ HalpReadPhysicalAddr( errAddr );
+
+ buffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(magSet)->AERR );
+
+ if( (buffer & 0x0000000a) == 0 ) {
+#if defined(ECC_DBG)
+ DbgPrint("goto next1bit P-2\n");
+#endif
+ goto next1bit;
+ }
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:AERR = %x\n", buffer);
+#endif
+
+ //
+ // ECC 1bit error occur again.
+ //
+
+ ((pECC1_ERR_REC)dataBuf)->record_flag = ECC_LOG_VALID_FLG;
+
+ ((pECC1_ERR_REC)dataBuf)->err_address = errAddr;
+
+ GET_TIME(tempBuf);
+ RtlMoveMemory( (PVOID)( ((pECC1_ERR_REC)dataBuf)->when_happened ),
+ (PVOID)tempBuf,
+ TIME_STAMP_SIZE
+ );
+
+ ((pECC1_ERR_REC)dataBuf)->syndrome = sdlmBuffer;
+
+ ((pECC1_ERR_REC)dataBuf)->specified_group =
+ (UCHAR)( ((PSTS1_REGISTER)&sts1Buffer)->ARE + magSet * 4);
+
+ ((pECC1_ERR_REC)dataBuf)->specified_simm =
+ (UCHAR)( ((PSTS1_REGISTER)&sts1Buffer)->BANK );
+
+ 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);
+ }
+
+next1bit:
+
+// if(returnValue == SIC_ECC_1BIT_ERROR) {
+
+ DONT_NOTIFY_ECC1BIT;
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:ECC 1bit Disable\n");
+#endif
+
+ WRITE_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->ERRST, 0x0a );
+
+ do {
+ buffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(magSet)->AERR );
+ } while ( (buffer & 0x0000000a) != 0 );
+
+ WRITE_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->SDCR, 0x00 );
+
+ do {
+ sts1Buffer = READ_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->STS1 );
+ sdlmBuffer = READ_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->SDLM );
+ } while ( ((sdlmBuffer) != 0) && ((sts1Buffer & 0x0a000000) == 0) );
+
+ WRITE_REGISTER_ULONG((PULONG)&PONCE_CNTL(0)->ERRST, 0x00000200 );
+
+ Registerp = (PULONG)&(COLUMNBS_LCNTL)->IPRR;
+ WRITE_REGISTER_ULONG( Registerp++, 0x40000000 );
+
+#if defined(ECC_DBG)
+ DbgPrint("HalpECC1bitDisableFlag = %x\n",HalpECC1bitDisableFlag);
+#endif
+ if(HalpECC1bitDisableFlag > 0) {
+ HalpECC1bitDisableFlag--;
+ if(HalpECC1bitDisableFlag > 0) {
+ NOTIFY_ECC1BIT;
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:ECC 1bit Enable\n");
+#endif
+ }
+ else {
+ HalpECC1bitDisableTime = ECC_1BIT_ERROR_DISABLE_TIME;
+ HalpECC1bitDisableFlag = 0;
+#if defined(ECC_DBG)
+ DbgPrint("HalpECC1bitDisableTime = %x\n",HalpECC1bitDisableTime);
+#endif
+ }
+ }
+
+ return;
+}
+
+#endif // don't suported yet
+
+VOID
+HalpEccMultiBitError(
+ IN ULONG MagellanAllError,
+ IN UCHAR magSet
+ )
+
+/*++
+
+Routine Description:
+
+ This routine check ecc multi bit error and error log put in NVRAM.
+
+Arguments:
+
+ MagellanAllError - Magellan#0/#1 AERR register.
+ magSet - Magellan Number(#0 or #1).
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ USHORT infoOffset;
+ USHORT writeOffset;
+ ULONG sts1Buffer;
+ ULONG sdlmBuffer;
+ ULONG dsrgBuffer;
+ ULONG errAddr;
+ UCHAR dataBuf[36];
+ UCHAR infoBuf[24];
+ UCHAR tempBuf[24];
+ ULONG simmMIN;
+ ULONG MemoryBlock;
+ ULONG MagellanAdec;
+ ULONG syukuBuffer;
+ volatile PULONG Registerp;
+
+#if defined(ECC_DBG)
+ DbgPrint("ECC Multi Bit Error IN !!!\n");
+#endif
+
+// HalpECC1bitScfrBuffer = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD);
+
+ //
+ // read diagnosis registers.
+ //
+
+ sts1Buffer = READ_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->STS1 );
+ dsrgBuffer = READ_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->DSRG );
+ sdlmBuffer = READ_REGISTER_ULONG( (PULONG) &MAGELLAN_X_CNTL(magSet)->SDLM );
+
+#if defined(ECC_DBG)
+ DbgPrint("Magellan#%x:AERR = %x\n",magSet,MagellanAllError);
+ DbgPrint("Magellan#%x:STS1 = %x\n",magSet,sts1Buffer);
+#endif
+
+ Registerp = (PULONG)&MAGELLAN_X_CNTL(magSet)->ADEC0;
+ MagellanAdec = READ_REGISTER_ULONG( Registerp + ((sts1Buffer>>30)<<1) );
+
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:ADEC%x = %x\n",(sts1Buffer>>30),MagellanAdec);
+#endif
+
+ simmMIN = (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->MIN ) << 24;
+ if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->BLOCK ) == 1 ) {
+ MemoryBlock = 0x00000000;
+ } else if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->BLOCK ) == 2 ) {
+ MemoryBlock = 0x20000000;
+ } else {
+ return;
+ }
+
+ //
+ // HW Logging
+ //
+ HalpEcc2Logger( 8 + magSet );
+
+#if defined(ECC_DBG)
+ DbgPrint("Magellan:MemoryBlock = %x\n",MemoryBlock);
+
+// TmpInitNvram2();
+#endif
+
+ HalNvramRead( NVRAM_STATE_FLG_OFFSET, 1, dataBuf );
+ HalNvramRead( NVRAM_MAGIC_NO_OFFSET, 4, tempBuf );
+
+ if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){
+
+ infoOffset = ECC_2BIT_ERROR_LOG_INFO_OFFSET;
+ HalNvramRead( (ULONG)infoOffset, 20, infoBuf);
+
+ ((pECC2_ERR_REC)dataBuf)->record_flag = ECC_LOG_VALID_FLG;
+
+ //
+ // Error address generate
+ //
+
+ if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->MAG ) == 0 ) { // B-MODE
+ if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->SIMM_2 ) == 0 ) {
+ errAddr = MemoryBlock + simmMIN +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->RF) << 24) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL0_1) << 4) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL2_9) << 6) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW0_9) << 14);
+#if defined(ECC_DBG)
+ DbgPrint("ERROR_ADDR = %x\n",errAddr);
+#endif
+ } else if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->SIMM_2 ) == 1 ) {
+ errAddr = MemoryBlock + simmMIN +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->RF) << 26) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL0_1) << 4) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL2_9) << 6) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL10) << 14) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW0_9) << 15) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW10) << 25);
+ }
+ } else if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->MAG ) == 1 ) { // M-MODE
+ if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->SIMM_2 ) == 0 ) {
+ errAddr = MemoryBlock + simmMIN +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->RF) << 25) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL0_1) << 4) +
+ ((ULONG)( magSet << 6 )) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL2_9) << 7) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW0_9) << 15);
+ } else if ( (UCHAR)( ((PADEC_REGISTER)&MagellanAdec)->SIMM_2 ) == 1 ) {
+ errAddr = MemoryBlock + simmMIN +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->RF) << 27) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL0_1) << 4) +
+ ((ULONG)( magSet << 6 )) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL2_9) << 7) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->COL10) << 15) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW0_9) << 16) +
+ ((ULONG)(((PSTS1_REGISTER)&sts1Buffer)->ROW10) << 26);
+ }
+ }
+
+ GET_TIME(tempBuf);
+ RtlMoveMemory( (PVOID)( ((pECC2_ERR_REC)dataBuf)->when_happened ),
+ (PVOID)tempBuf,
+ TIME_STAMP_SIZE
+ );
+
+ ((pECC2_ERR_REC)dataBuf)->err_address = errAddr;
+ ((pECC2_ERR_REC)dataBuf)->syndrome = sdlmBuffer;
+
+ ((pECC2_ERR_REC)dataBuf)->specified_group =
+ (UCHAR)( ((PSTS1_REGISTER)&sts1Buffer)->ARE + magSet * 4);
+
+ ((pECC2_ERR_REC)dataBuf)->specified_simm =
+ (UCHAR)( ((PSTS1_REGISTER)&sts1Buffer)->BANK );
+
+ 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);
+
+ //
+ // MM sykutai to POST
+ //
+ syukuBuffer = 0x0f << ((((pECC2_ERR_REC)dataBuf)->specified_group) << 2 );
+ HalNvramWrite( ESM_MM_SYUKUTAI_TOPOST_OFFSET,
+ 4,
+ (PVOID)&syukuBuffer);
+
+ }
+ return;
+}
+
+#if 0 // for test mode
+
+int
+TmpInitNvram(void)
+{
+ UCHAR buf[256];
+ ULONG i;
+
+ buf[0]=0x77;
+ for(i=768; i<768+25*16; 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);
+
+
+#if defined(ECC_DBG)
+ DbgPrint("Hal: ESM setup = 0x%x\n",NVRAM_STATE_FLG_OFFSET);
+ DbgPrint("Hal: ESM setup = 0x%x\n",NVRAM_MAGIC_NO_OFFSET);
+#endif
+
+ //
+ // 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);
+
+ return(0);
+}
+
+int
+TmpInitNvram2(void)
+{
+ UCHAR buf[256];
+ ULONG i;
+
+ buf[0]=0x77;
+ for(i=768+400; i<768+400+25*4; 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);
+
+
+#if defined(ECC_DBG)
+ DbgPrint("Hal: ESM setup = 0x%x\n",NVRAM_STATE_FLG_OFFSET);
+ DbgPrint("Hal: ESM setup = 0x%x\n",NVRAM_MAGIC_NO_OFFSET);
+#endif
+
+ //
+ // 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;
+
+ HalNvramWrite( ECC_2BIT_ERROR_LOG_INFO_OFFSET,
+ sizeof(ECC2_ERR_AREA_INFO),
+ buf);
+
+ return(0);
+}
+#endif
diff --git a/private/ntos/nthals/halr98b/mips/rxeif.c b/private/ntos/nthals/halr98b/mips/rxeif.c
new file mode 100644
index 000000000..224715021
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxeif.c
@@ -0,0 +1,694 @@
+/*++
+
+Copyright (c) 1994 Kobe NEC Software
+
+Module Name:
+
+ rxeif.c
+
+Abstract:
+
+ This module implements the Eif interrupt service routine for R98B
+
+Author:
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+
+#include "halp.h"
+
+#include "bugcodes.h"
+#include "eisa.h"
+#include "stdio.h"
+
+extern ULONG HalpLogicalCPU2PhysicalCPU[R98B_MAX_CPU];
+
+//
+// define Columnbs buffer index
+//
+
+typedef enum _COLUMNBS_BUFFER_INDEX {
+ COLUMNBS_AERR,
+ COLUMNBS_FERR,
+ COLUMNBS_ERRMK,
+ COLUMNBS_ERRI,
+ COLUMNBS_ERRST,
+ COLUMNBS_NMIM,
+ COLUMNBS_EAHI,
+ COLUMNBS_EALI,
+ COLUMNBS_AERR2,
+ COLUMNBS_FERR2,
+ COLUMNBS_ERRMK2,
+ COLUMNBS_ERRI2,
+ COLUMNBS_ERRST2,
+ COLUMNBS_NMIM2,
+ COLUMNBS_STSR,
+ COLUMNBS_ERRNOD,
+ COLUMNBS_MAX_REGISTER
+}COLUMNBS_BUFFER_INDEX,*PCOLUMNBS_BUFFER_INDEX;
+
+//
+// define MAGELLAN buffer index
+//
+typedef enum _MAGELLAN_BUFFER_INDEX {
+ MAGELLAN_AERR,
+ MAGELLAN_FERR,
+ MAGELLAN_ERRM,
+ MAGELLAN_ERRI,
+ MAGELLAN_ERRST,
+ MAGELLAN_EIFM,
+ MAGELLAN_EAHI,
+ MAGELLAN_EALI,
+ MAGELLAN_CKE0,
+ MAGELLAN_SECT,
+ MAGELLAN_STS1,
+ MAGELLAN_DATM,
+ MAGELLAN_DSRG,
+ MAGELLAN_MAX_REGISTER
+}MAGELLAN_BUFFER_INDEX,*PMAGELLAN_BUFFER_INDEX;
+
+
+//
+// define PONCE buffer index
+//
+typedef enum _PONCE_BUFFER_INDEX {
+ PONCE_AERR,
+ PONCE_FERR,
+ PONCE_ERRM,
+ PONCE_ERRI,
+ PONCE_ERRST,
+ PONCE_EAHI,
+ PONCE_EALI,
+ PONCE_PAERR,
+ PONCE_PFERR,
+ PONCE_PERRM,
+ PONCE_PERRI,
+ PONCE_PERST,
+ PONCE_PTOL,
+ PONCE_MAX_REGISTER
+}PONCE_BUFFER_INDEX,*PPONCE_BUFFER_INDEX;
+
+//
+// System Diagnotics Registers of R98
+//
+ULONG r98bDiagColumnbs[R98B_MAX_CPU][COLUMNBS_MAX_REGISTER];
+ULONG r98bDiagMagellan[R98B_MAX_MAGELLAN][MAGELLAN_MAX_REGISTER];
+ULONG r98bDiagPonce[R98B_MAX_PONCE][PONCE_MAX_REGISTER];
+ULONG r98bDiagEisaNmi;
+
+
+volatile ULONG HalpNMIFlag=0;
+ULONG HalpNMIHappend[R98B_MAX_CPU];
+ULONG HalpNmiSvp[R98B_MAX_CPU];
+ULONG HalpDumpFlag=0;
+
+#if DBG
+ULONG HalpNMISecond[R98B_MAX_CPU];
+ULONG HalpResetCount[R98B_MAX_CPU];
+
+#endif
+
+
+BOOLEAN
+HalpHandleEif(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID ServiceContext
+ )
+
+/*++
+
+Routine Description:
+
+ This routine manage the eif interrupt
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ UCHAR messageBuffer[256];
+ UCHAR charBuffer;
+ ULONG counter;
+
+ UCHAR EisaPort;
+ ULONG port;
+
+ ULONG displaycount;
+ ULONG CpuNo;
+ ULONG CpuNumber;
+ PCOLUMNBUS_REGISTER ColumnbusRegister;
+ ULONG i;
+ ULONG ERRNOD;
+ ULONG Cregisters;
+ volatile ULONG CpuCount=0;
+ ULONG PhysicalCpuNumber;
+ ULONG data1,data2,data3,data4;
+
+ PULONG Vp;
+ ULONG Value[2];
+ ULONG Magellan0AllError = 0;
+ ULONG Magellan1AllError = 0;
+ UCHAR Data;
+
+ // I am ..
+ CpuNo=(PCR->Prcb)->Number;
+ CpuCount=**((PULONG *)(&KeNumberProcessors));
+
+// DbgBreakPoint(); //for snes
+
+ //
+ // Get Node. What happend NODE X!!.
+ //
+ PhysicalCpuNumber = HalpLogicalCPU2PhysicalCPU[CpuNo];
+
+
+ ERRNOD = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD );
+ r98bDiagColumnbs[PhysicalCpuNumber][COLUMNBS_ERRNOD] = ERRNOD;
+
+ //
+ // First Check is MRC. This is Power SW Interrupt!!.
+ //
+ HalpLocalDeviceReadWrite(MRCINT,&Data,LOCALDEV_OP_READ);
+ if( Data & 0x04){
+ Data = 0x0;
+ //
+ // Reset is MRC Interrupt debug Only.
+ //
+ // HalpLocalDeviceReadWrite(MRCINT, &Data, LOCALDEV_OP_WRITE);
+
+ return FALSE;
+
+ }else
+
+ //
+ // Is This Alarm EIF?
+ //
+ if( ERRNOD & ERRNOD_ALARM ) {
+ //
+ // Second time DUMMY Read.
+ //
+ READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD );
+ //
+ // Do Hwlogging
+ //
+ HalpEifReturnLog();
+
+ //
+ // We Reset Node Register. Now Register had Locked.
+ // If We Reset Node Register. Other CPU which EIF Broadcasted was
+ // Never aknowrege EIF Ocurred. So Quick Return.
+ //
+ //WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD,ERRNOD_ALARM );
+
+ return FALSE;
+
+ }
+
+ if(( (ERRNOD & ERRNOD_ALLNODE) == 0) && (HalpNMIFlag == 0) ){
+
+ // DbgBreakPoint();
+ // Any Node Reported EIF.
+ //
+ return FALSE;
+ }
+
+
+ //
+ //
+ // We Will die.
+ //
+
+ if(HalpNMIFlag == 0){
+ for (i=0;i< R98B_MAX_CPU;i++)
+ HalpNMIHappend[i] = 1;
+
+ }
+
+
+ //
+ // CHeck ECC Multi Bit Error
+ //
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0) == 0 ){
+ Magellan0AllError = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->AERR );
+ }
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1) == 0 ){
+ Magellan1AllError = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->AERR );
+ }
+
+ if ( Magellan0AllError & 0x00000005 ){
+ HalpEccMultiBitError( Magellan0AllError, 0 );
+ } else if ( Magellan1AllError & 0x00000005 ){
+ HalpEccMultiBitError( Magellan1AllError, 1 );
+ }
+
+ // cpu #0 cpu #1 cpu #2 cpu #3
+ // r98bDiagbuffers[]
+ // save H/W register Context of COLUMNBS.
+ //
+
+ for(CpuNumber = 0; CpuNumber < CpuCount; CpuNumber++){
+ PhysicalCpuNumber = HalpLogicalCPU2PhysicalCPU[CpuNumber];
+ ColumnbusRegister = (PCOLUMNBUS_REGISTER)&COLUMNBS_GCNTL(4+PhysicalCpuNumber)->AERR;
+ for(Cregisters = 0; Cregisters < COLUMNBS_ERRNOD;Cregisters++){
+ r98bDiagColumnbs[PhysicalCpuNumber][Cregisters] =
+ READ_REGISTER_ULONG( (PULONG)ColumnbusRegister );
+ ColumnbusRegister++;
+ }
+
+ }
+
+ //
+ // Save H/W register Context of Magellan.
+ //
+ for(i = 0; i < R98B_MAX_MAGELLAN ; i++){
+ if( !(HalpPhysicalNode & (CNFG_CONNECT4_MAGELLAN0 >> i))){
+ r98bDiagMagellan[i][MAGELLAN_AERR] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->AERR );
+ r98bDiagMagellan[i][MAGELLAN_FERR] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->FERR );
+ r98bDiagMagellan[i][MAGELLAN_ERRM] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->ERRM );
+ r98bDiagMagellan[i][MAGELLAN_ERRI] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->ERRI );
+// r98bDiagMagellan[i][MAGELLAN_ERRST] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->ERRST);
+
+// r98bDiagMagellan[i][MAGELLAN_EIFM] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->EIFM );
+ r98bDiagMagellan[i][MAGELLAN_EAHI] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->EAHI );
+ r98bDiagMagellan[i][MAGELLAN_EALI] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->EALI );
+
+ r98bDiagMagellan[i][MAGELLAN_CKE0] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->CKE0 );
+ r98bDiagMagellan[i][MAGELLAN_SECT] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->SECT );
+
+ r98bDiagMagellan[i][MAGELLAN_STS1] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->STS1 );
+ r98bDiagMagellan[i][MAGELLAN_DATM] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->DATM );
+ r98bDiagMagellan[i][MAGELLAN_DSRG] = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(i)->DSRG );
+ }
+ }
+
+ //
+ // Save H/W register Context of Ponce.
+ //
+ for(i = 0; i < HalpNumberOfPonce; i++){
+ r98bDiagPonce[i][PONCE_AERR] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->AERR);
+ r98bDiagPonce[i][PONCE_FERR] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->FERR);
+ r98bDiagPonce[i][PONCE_ERRM] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->ERRM);
+ r98bDiagPonce[i][PONCE_ERRI] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->ERRI);
+ //
+ // THis Register is write only
+ //
+ //r98bDiagPonce[i][PONCE_ERRST] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->ERRST);
+ r98bDiagPonce[i][PONCE_EAHI] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->EAHI);
+ r98bDiagPonce[i][PONCE_EALI] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->EALI);
+ r98bDiagPonce[i][PONCE_PAERR] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PAERR);
+ r98bDiagPonce[i][PONCE_PFERR] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PFERR);
+ r98bDiagPonce[i][PONCE_PERRM] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PERRM);
+ r98bDiagPonce[i][PONCE_PERRI] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PERRI);
+ //
+ // This Register is Read Only.....
+ //
+// r98bDiagPonce[i][PONCE_PERST] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PERST);
+ r98bDiagPonce[i][PONCE_PTOL] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PTOL);
+ }
+
+ //
+ // Display EISA Nmi status.
+ //
+
+ charBuffer = READ_REGISTER_UCHAR( &((PEISA_CONTROL)HalpEisaControlBase )->NmiStatus);
+ r98bDiagEisaNmi = charBuffer << 24;
+
+ charBuffer = READ_REGISTER_UCHAR(
+ &( (PEISA_CONTROL)HalpEisaControlBase )->ExtendedNmiResetControl
+ );
+ r98bDiagEisaNmi |= charBuffer << 16;
+
+ //
+ // 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);
+ charBuffer = READ_PORT_UCHAR ((PUCHAR) port);
+
+ if ((charBuffer & 0x80) == 0) {
+ //
+ // Found valid Eisa board, Check to see if it's
+ // if IOCHKERR is asserted.
+ //
+ charBuffer = READ_PORT_UCHAR ((PUCHAR) port+4);
+ if (charBuffer & 0x2) {
+ r98bDiagEisaNmi |= EisaPort;
+ }
+ }
+ }
+
+
+ //
+ // Display COLUMNBS Register
+ //
+ for(CpuNumber = 0; CpuNumber < CpuCount; CpuNumber++){
+ displaycount = 0;
+ PhysicalCpuNumber=HalpLogicalCPU2PhysicalCPU[CpuNumber];
+ sprintf( (char *)messageBuffer, "\nMPU Controller %1d Registers:\n",PhysicalCpuNumber );
+ HalDisplayString( (char *)messageBuffer );
+
+ for(Cregisters = 0; Cregisters < COLUMNBS_MAX_REGISTER;Cregisters++){
+
+ sprintf( (char *)messageBuffer, "0x%08lX,",r98bDiagColumnbs[PhysicalCpuNumber][Cregisters] );
+
+ HalDisplayString( (char *)messageBuffer );
+ if( (displaycount % 7) == 6 ) {
+ sprintf( (char *)messageBuffer, "\n");
+ HalDisplayString( (char *)messageBuffer );
+ }
+ displaycount++;
+ }
+ }
+
+
+ //
+ // Display MAGELLAN Register
+ //
+ for(i = 0; i < R98B_MAX_MAGELLAN ; i++){
+ displaycount=0;
+ if( !(HalpPhysicalNode & (CNFG_CONNECT4_MAGELLAN0 >> i))){
+ sprintf( (char *)messageBuffer, "\nMEMORY Controller %1d Registers:\n",i );
+ HalDisplayString( (char *)messageBuffer );
+
+ for(Cregisters = 0; Cregisters < MAGELLAN_MAX_REGISTER;Cregisters++){
+ sprintf( (char *)messageBuffer, "0x%08lX,",r98bDiagMagellan[i][Cregisters] );
+ HalDisplayString( (char *)messageBuffer );
+ if( (displaycount % 7) == 6 ) {
+ sprintf( (char *)messageBuffer, "\n");
+ HalDisplayString( (char *)messageBuffer );
+ }
+ displaycount++;
+ }
+
+ }else{
+ sprintf( (char *)messageBuffer, "\nMEMORY Controller %1d Not Present.",i );
+ HalDisplayString( (char *)messageBuffer );
+ }
+ }
+
+ //
+ // Display PONCE Register
+ //
+ for(i = 0; i < HalpNumberOfPonce; i++){
+ displaycount=0;
+ sprintf( (char *)messageBuffer, "\nPCI Controller %1d Registers:\n",i );
+ HalDisplayString( (char *)messageBuffer );
+
+ for(Cregisters = 0; Cregisters < PONCE_MAX_REGISTER;Cregisters++){
+ sprintf( (char *)messageBuffer, "0x%08lX,",r98bDiagPonce[i][Cregisters] );
+ HalDisplayString( (char *)messageBuffer );
+ if( (displaycount % 7) == 6 ) {
+ sprintf( (char *)messageBuffer, "\n");
+ HalDisplayString( (char *)messageBuffer );
+ }
+ displaycount++;
+ }
+ }
+
+
+
+ Vp = (PULONG)&(COLUMNBS_LCNTL)->MKR;
+ Value[0]= READ_REGISTER_ULONG( Vp++);
+ Value[1]= READ_REGISTER_ULONG( Vp);
+
+ Vp = (PULONG)&(COLUMNBS_LCNTL)->MKR;
+ WRITE_REGISTER_ULONG( Vp++,0xffffffff);
+ WRITE_REGISTER_ULONG( Vp, 0xffffffff);
+
+ PhysicalCpuNumber = HalpLogicalCPU2PhysicalCPU[CpuNo];
+
+// if( ((HalpNMIFlag & 0xffff) == NMIR_EXNMI) && !HalpNmiSvp[PhysicalCpuNumber] ) {
+ if( ((HalpNMIFlag & 0xffff) == NMIR_EXNMI) && HalpDumpFlag ) {
+ HalpChangePanicFlag( 16, 0x05, 0x10);
+ } else {
+ HalpChangePanicFlag( 16, 0x01, 0x10);
+ }
+
+ Vp = (PULONG)&(COLUMNBS_LCNTL)->MKR;
+ WRITE_REGISTER_ULONG( Vp++,Value[0]);
+ WRITE_REGISTER_ULONG( Vp, Value[1]);
+
+ //
+ if( HalpNMIFlag != 0 ){
+ //
+ // From Nmi. Nmi is supported by Cause EIF at nmi occured!!.
+ //
+ HalDisplayString("\nNMI: ");
+
+ switch( HalpNMIFlag & 0xffff){
+ case NMIR_EXNMI:
+// if(HalpNmiSvp[PhysicalCpuNumber])
+ if(HalpDumpFlag==0)
+ HalDisplayString("SVP issued NMI");
+ else
+ HalDisplayString("Dump Switch Pressed");
+ break;
+ case NMIR_WDTOV:
+ HalDisplayString("Time out of Watch-dog Timer occured");
+ break;
+ case NMIR_CLBNMI:
+ HalDisplayString("MPU Controller Internal Error");
+ break;
+ case NMIR_UNANMI:
+ HalDisplayString("Invalid Access");
+ break;
+ default:
+ HalDisplayString("[Other ?]");
+ }
+
+ data1 = r98bDiagColumnbs[PhysicalCpuNumber][COLUMNBS_AERR];
+ data2 = r98bDiagColumnbs[PhysicalCpuNumber][COLUMNBS_AERR2];
+ data3 = HalpNMIFlag;
+ data4 = r98bDiagColumnbs[PhysicalCpuNumber][COLUMNBS_NMIM];
+
+ HalpNmiLog();
+
+ }else {
+ //
+ // Acutually EIF Interrupt Occured!
+ //
+
+ if( ( Magellan0AllError & 0x00000005 ) ||
+ ( Magellan1AllError & 0x00000005 ) ){
+ HalDisplayString("\nEIF: Uncorrectable Error in Memory");
+ }
+
+ HalDisplayString("\nEIF Reported: ");
+ sprintf( (char *)messageBuffer, "Exe CPU=No.%1d NodeR = %x ",
+ CpuNo, r98bDiagColumnbs[PhysicalCpuNumber][COLUMNBS_ERRNOD]);
+ HalDisplayString( (char *)messageBuffer );
+
+ switch( r98bDiagColumnbs[PhysicalCpuNumber][COLUMNBS_ERRNOD] & 0xf3cc){
+ case ERRNOD_NODE0 :
+ HalDisplayString("[ From PCI Controller 0]");
+ data1 = r98bDiagPonce[0][PONCE_AERR];
+ data2 = r98bDiagPonce[0][PONCE_FERR];
+ data3 = r98bDiagPonce[0][PONCE_PAERR];
+ data4 = r98bDiagPonce[0][PONCE_PFERR];
+ break;
+ case ERRNOD_NODE1 :
+ HalDisplayString("[ From PCI Controller 1]");
+ data1 = r98bDiagPonce[1][PONCE_AERR];
+ data2 = r98bDiagPonce[1][PONCE_FERR];
+ data3 = r98bDiagPonce[1][PONCE_PAERR];
+ data4 = r98bDiagPonce[1][PONCE_PFERR];
+ break;
+ case ERRNOD_NODE4 :
+ HalDisplayString("[ From MPU Controller 0]");
+ data1 = r98bDiagColumnbs[0][COLUMNBS_AERR];
+ data2 = r98bDiagColumnbs[0][COLUMNBS_AERR2];
+ data3 = r98bDiagColumnbs[0][COLUMNBS_EAHI];
+ data4 = r98bDiagColumnbs[0][COLUMNBS_EALI];
+ break;
+ case ERRNOD_NODE5 :
+ HalDisplayString("[ From MPU Controller 1]");
+ data1 = r98bDiagColumnbs[1][COLUMNBS_AERR];
+ data2 = r98bDiagColumnbs[1][COLUMNBS_AERR2];
+ data3 = r98bDiagColumnbs[1][COLUMNBS_EAHI];
+ data4 = r98bDiagColumnbs[1][COLUMNBS_EALI];
+ break;
+ case ERRNOD_NODE6 :
+ HalDisplayString("[ From MPU Controller 2]");
+ data1 = r98bDiagColumnbs[2][COLUMNBS_AERR];
+ data2 = r98bDiagColumnbs[2][COLUMNBS_AERR2];
+ data3 = r98bDiagColumnbs[2][COLUMNBS_EAHI];
+ data4 = r98bDiagColumnbs[2][COLUMNBS_EALI];
+ break;
+ case ERRNOD_NODE7 :
+ HalDisplayString("[ From MPU Controller 3]");
+ data1 = r98bDiagColumnbs[3][COLUMNBS_AERR];
+ data2 = r98bDiagColumnbs[3][COLUMNBS_AERR2];
+ data3 = r98bDiagColumnbs[3][COLUMNBS_EAHI];
+ data4 = r98bDiagColumnbs[3][COLUMNBS_EALI];
+ break;
+ case ERRNOD_NODE8 :
+ HalDisplayString("[ From MEMORY Controller 0]");
+ data1 = r98bDiagMagellan[0][MAGELLAN_AERR];
+ data2 = r98bDiagMagellan[0][MAGELLAN_FERR];
+ data3 = r98bDiagMagellan[0][MAGELLAN_EAHI];
+ data4 = r98bDiagMagellan[0][MAGELLAN_EALI];
+ break;
+ case ERRNOD_NODE9 :
+ HalDisplayString("[ From MEMORY Controller 1]");
+ data1 = r98bDiagMagellan[1][MAGELLAN_AERR];
+ data2 = r98bDiagMagellan[1][MAGELLAN_FERR];
+ data3 = r98bDiagMagellan[1][MAGELLAN_EAHI];
+ data4 = r98bDiagMagellan[1][MAGELLAN_EALI];
+ break;
+ case ERRNOD_EISANMI:
+ HalDisplayString("[ From EISA]");
+ data1 = r98bDiagEisaNmi;
+ data2 = 0;
+ data3 = 0;
+ data4 = 0;
+ break;
+//
+// This case never happend.
+//
+ case ERRNOD_ALARM :
+ HalDisplayString("[ From ALARM]");
+ data1 = 0;
+ data2 = 0;
+ data3 = 0;
+ data4 = 0;
+ break;
+
+
+ default:
+ HalDisplayString("[Other ?]");
+ data1 = 0;
+ data2 = 0;
+ data3 = 0;
+ data4 = 0;
+ }
+ // HwLog kusano
+ HalpEifLog();
+
+ }
+
+ KeBugCheckEx(NMI_HARDWARE_FAILURE,
+ data1,
+ data2,
+ data3,
+ data4
+ );
+
+#if 1 // WORK_AROUND_BBM for compiler
+ return FALSE;
+#endif
+}
+
+
+BOOLEAN
+HalpIoTlbLimitOver(
+ PKINTERRUPT Interrupt
+ )
+{
+ KIRQL irql;
+ ULONG data1,data2,data3,data4;
+ ULONG i;
+ ULONG displaycount;
+ UCHAR messageBuffer[256];
+ ULONG Cregisters;
+
+ KeRaiseIrql(HIGH_LEVEL, &irql);
+ KiAcquireSpinLock(&HalpDieLock);
+
+ //
+ // Save H/W register Context of Ponce.
+ //
+ for(i = 0; i < HalpNumberOfPonce; i++){
+ r98bDiagPonce[i][PONCE_AERR] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->AERR);
+ r98bDiagPonce[i][PONCE_FERR] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->FERR);
+ r98bDiagPonce[i][PONCE_ERRM] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->ERRM);
+ r98bDiagPonce[i][PONCE_ERRI] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->ERRI);
+ //
+ // THis Register is write only
+ //
+ //r98bDiagPonce[i][PONCE_ERRST] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->ERRST);
+ r98bDiagPonce[i][PONCE_EAHI] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->EAHI);
+ r98bDiagPonce[i][PONCE_EALI] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->EALI);
+ r98bDiagPonce[i][PONCE_PAERR] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PAERR);
+ r98bDiagPonce[i][PONCE_PFERR] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PFERR);
+ r98bDiagPonce[i][PONCE_PERRM] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PERRM);
+ r98bDiagPonce[i][PONCE_PERRI] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PERRI);
+ //
+ // This Register is Read Only.....
+ //
+// r98bDiagPonce[i][PONCE_PERST] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PERST);
+ r98bDiagPonce[i][PONCE_PTOL] = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(i)->PTOL);
+ }
+
+ //
+ // Display PONCE Register
+ //
+ for(i = 0; i < HalpNumberOfPonce; i++){
+ displaycount=0;
+ sprintf( (char *)messageBuffer, "\nPCI Controller %1d Registers:\n",i );
+ HalDisplayString( (char *)messageBuffer );
+
+ for(Cregisters = 0; Cregisters < PONCE_MAX_REGISTER;Cregisters++){
+ sprintf( (char *)messageBuffer, "0x%08lX,",r98bDiagPonce[i][Cregisters] );
+ HalDisplayString( (char *)messageBuffer );
+ if( (displaycount % 7) == 6 ) {
+ sprintf( (char *)messageBuffer, "\n");
+ HalDisplayString( (char *)messageBuffer );
+ }
+ displaycount++;
+ }
+ }
+
+ if( r98bDiagPonce[1][PONCE_AERR] & (PONCE_XERR_TUAER | PONCE_XERR_TIVER) ){
+ data1 = r98bDiagPonce[1][PONCE_AERR];
+ data2 = r98bDiagPonce[1][PONCE_FERR];
+ data3 = r98bDiagPonce[1][PONCE_PAERR];
+ data4 = r98bDiagPonce[1][PONCE_PFERR];
+ i = 1;
+ } else {
+ data1 = r98bDiagPonce[0][PONCE_AERR];
+ data2 = r98bDiagPonce[0][PONCE_FERR];
+ data3 = r98bDiagPonce[0][PONCE_PAERR];
+ data4 = r98bDiagPonce[0][PONCE_PFERR];
+ i = 0;
+ }
+
+ HalpChangePanicFlag( 16, 0x01, 0x10);
+
+ if ( data1 & PONCE_XERR_TUAER ){
+ HalDisplayString("\nI/O TLB Logical Address Limit Over\n");
+ } else {
+ HalDisplayString("\nI/O TLB Invalid\n");
+ }
+
+ sprintf( (char *)messageBuffer, " [ From PCI Controller %d]\n",i );
+ HalDisplayString( (char *)messageBuffer );
+
+ KeBugCheckEx(NMI_HARDWARE_FAILURE,
+ data1,
+ data2,
+ data3,
+ data4
+ );
+
+ KiReleaseSpinLock (&HalpDieLock);
+ KeLowerIrql (irql);
+
+ return TRUE;
+}
diff --git a/private/ntos/nthals/halr98b/mips/rxesm.c b/private/ntos/nthals/halr98b/mips/rxesm.c
new file mode 100644
index 000000000..d10a659a6
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxesm.c
@@ -0,0 +1,761 @@
+/*++
+
+Copyright (c) 1994 Kobe NEC Software
+
+Module Name:
+
+ rxesm.c
+
+Abstract:
+
+ This module implements the ESM service routine for R98B
+
+Author:
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+
+#include "rxesm.h"
+#include "esmnvram.h"
+#include "bugcodes.h"
+#include "stdio.h"
+#include "halp.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 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 global variable. This variable use in display string into nvram.
+//
+ULONG HalpNvramValid=FALSE;
+ULONG CallCountOfInitDisplay=0;
+USHORT ErrBufferLatest;
+USHORT ErrBufferArea;
+USHORT ErrBufferStart;
+USHORT ErrBufferEnd;
+USHORT ErrBufferCurrent;
+ULONG HalpPanicFlg=0;
+UCHAR HalpNvramStringBuffer[STRING_BUFFER_SIZE];
+ULONG HalpNvramStringBufferCounter=0;
+
+UCHAR KernelPanicMessage[]="*** STOP: 0x";
+
+extern ULONG HalpLogicalCPU2PhysicalCPU[R98B_MAX_CPU];
+extern ULONG HalpSvpEisaSlot;
+extern ULONG HalpSvpWindow0;
+extern ULONG HalpSvpWindow1;
+extern ULONG HalpSvpWindow2;
+extern ULONG HalpSvpGlobal;
+extern ULONG HalpSvpAlive ;
+
+#define GET_TIME(Buffer) { \
+ TIME_FIELDS timeBuffer; \
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKSR,\
+ 63-(EIF_VECTOR-DEVICE_VECTORS ));\
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKSR,\
+ 63-(ECC_1BIT_VECTOR-DEVICE_VECTORS ));\
+ HalQueryRealTimeClock( &timeBuffer ); \
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKRR,\
+ 63-(EIF_VECTOR-DEVICE_VECTORS ));\
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKRR,\
+ 63-(ECC_1BIT_VECTOR-DEVICE_VECTORS ));\
+ sprintf( (Buffer), \
+ "%04d%02d%02d%02d%02d%02d", \
+ timeBuffer.Year, \
+ timeBuffer.Month, \
+ timeBuffer.Day, \
+ timeBuffer.Hour, \
+ timeBuffer.Minute, \
+ timeBuffer.Second \
+ ); \
+}
+
+BOOLEAN
+HalNvramWrite(
+ ULONG Offset, // Offset Of ESM NVRAM
+ ULONG Count, // Write Byte Count
+ PVOID Buffer // Pointer Of Buffer Write to NVRAM
+){
+ // Write into NVRAM
+#if defined(DBG1)
+ DbgPrint("NVRAM write start\n");
+#endif
+ return HalpNvramReadWrite(Offset,Count,Buffer,1);
+#if defined(DBG1)
+ DbgPrint("NVRAM write end\n");
+#endif
+}
+
+BOOLEAN
+HalNvramRead(
+ ULONG Offset, // Offset Of ESM NVRAM
+ ULONG Count, // Read Byte Count
+ PVOID Buffer // Pointer Of Buffer Read From NVRAM
+){
+ // Read From NVRAM
+#if defined(DBG1)
+ DbgPrint("NVRAM read start\n");
+#endif
+ return HalpNvramReadWrite(Offset,Count,Buffer,0);
+#if defined(DBG1)
+ DbgPrint("NVRAM read end\n");
+#endif
+}
+
+BOOLEAN
+HalpNvramReadWrite(
+ ULONG Offset, // Read/Write offset of ESM NVRAM
+ ULONG Count, // Read/Write Byte Count
+ PVOID Buffer, // read/Write Pointer
+ ULONG Write // Operation
+){
+
+ ENTRYLO SavedPte[2];
+ KIRQL OldIrql;
+ ULONG i;
+ //
+ // Check is addr . So decrement 1
+ //
+ if(
+ Offset >=0 &&
+ Count >=0 &&
+ NVRAM_ESM_BASE+Offset <=NVRAM_ESM_END &&
+ NVRAM_ESM_BASE+Offset+Count-1 <=NVRAM_ESM_END
+
+ ){
+
+ if(Write){
+ OldIrql = HalpMapNvram(&SavedPte[0]);
+ for(i=0;i<Count;i++){
+ WRITE_REGISTER_UCHAR((PUCHAR)(NVRAM_ESM_BASE+Offset+i),((PUCHAR)Buffer)[i]);
+ }
+ HalpUnmapNvram(&SavedPte[0], OldIrql);
+ }else{
+ for(i=0;i<Count;i++){
+ ((PUCHAR)Buffer)[i] =READ_REGISTER_UCHAR((PUCHAR)(NVRAM_ESM_BASE+Offset+i));
+
+ }
+ }
+
+ return TRUE;
+
+ }else{
+
+ //
+ // It is no ESM NVRAM Erea.
+ return FALSE;
+ }
+
+}
+
+
+#if 0
+
+int
+TmpInitNvram(void)
+{
+ UCHAR buf[256];
+ ULONG i;
+
+ buf[0]=0x00;
+ 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);
+
+
+#if DBG
+ DbgPrint("Hal: ESM setup = 0x%x\n",NVRAM_STATE_FLG_OFFSET);
+ DbgPrint("Hal: ESM setup = 0x%x\n",NVRAM_MAGIC_NO_OFFSET);
+#endif
+
+ //
+ // 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(SYSTEM_ERR_AREA_INFO),
+ buf);
+
+ return(0);
+}
+
+#endif
+
+
+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){
+
+#if 0 //test only
+ TmpInitNvram();
+#endif
+ //
+ // 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);
+ }
+}
+
+VOID
+HalpSetInitDisplayTimeStamp(
+ VOID
+ )
+{
+ UCHAR buf[32];
+
+ //
+ // 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[32];
+// For WDT STOP and NVRAM set
+ volatile ULONG CpuCount=0;
+ ULONG PhysicalCpuNumber;
+ ULONG CpuNumber;
+ PUCHAR FwNvram;
+ UCHAR Bootflag;
+ PCOLUMNBUS_REGISTER ColumnbusRegister;
+ CpuCount=**((PULONG *)(&KeNumberProcessors));
+
+ if((NewPanicFlg>HalpPanicFlg)&(NewPanicFlg>0)){
+ for(CpuNumber = 0; CpuNumber < CpuCount; CpuNumber++){
+ PhysicalCpuNumber = HalpLogicalCPU2PhysicalCPU[CpuNumber];
+ ColumnbusRegister = (PCOLUMNBUS_REGISTER)&COLUMNBS_GCNTL(4+PhysicalCpuNumber)->WDTCR;
+ WRITE_REGISTER_ULONG( (PULONG)ColumnbusRegister,0x00000001);
+ }
+ (ULONG)FwNvram=0xbf081c00;
+ Bootflag=(*FwNvram);
+ *FwNvram=Bootflag|0x10;
+ // SVP EIF MASK
+ if(HalpSvpAlive){
+ WRITE_PORT_UCHAR(HalpSvpGlobal + 0x49,0x00 );
+ }
+ }
+
+
+
+ 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 );
+ }
+ }
+}
+
+
+
+VOID
+HalpLocalDeviceReadWrite(
+ IN ULONG Offset,
+ IN OUT PUCHAR Data,
+ IN ULONG ReadOp
+)
+/*++
+
+Routine Description:
+
+ This routine is Access Local Device
+
+Arguments:
+ Offset Register Offset of Local Device
+ Data Pointer of read or write data
+ ReadOp 1 is Read.
+
+Return Value:
+
+ None
+
+--*/
+{
+ ULONG stsr;
+ KIRQL oldirql;
+#if DBG0
+ DbgPrint("LOCAL: 1 \n");
+#endif
+ // NMI and EIF mask
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->STSR,0x08080000) ;
+ KeRaiseIrql(HIGH_LEVEL, &oldirql);
+
+ //
+ // Get H/W Semaphore
+ //
+ while (READ_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBCTL) & LBCTL_SEMAPHORE )
+ ;
+
+#if DBG0
+ DbgPrint("LOCAL: 2\n");
+#endif
+
+ //
+ // Set register Offset Hi Byte
+ //
+ WRITE_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBADH, (UCHAR)(Offset >> 8) );
+
+#if DBG0
+ DbgPrint("LOCAL: 3\n");
+#endif
+
+
+ //
+ // Set register Offset Lo Byte
+ //
+ WRITE_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBADL, (UCHAR)(Offset & 0xFF));
+
+#if DBG0
+ DbgPrint("LOCAL: 4\n");
+#endif
+
+ if(ReadOp){
+ //
+ // LBCTL Device read command Set.
+ //
+ WRITE_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBCTL, LBCTL_CMD|LBCTL_READ);
+
+ }else{
+ //
+ // Write data Set
+ //
+ WRITE_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBDT,*Data);
+ //
+ // LBCTL Device Write command Set.
+ //
+ WRITE_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBCTL, LBCTL_CMD);
+
+ }
+#if DBG0
+ DbgPrint("LOCAL: 5\n");
+#endif
+
+ //
+ // pooling LBCTL cmmand bit
+ //
+ while (READ_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBCTL) & LBCTL_CMD )
+ ;
+
+#if DBG0
+ DbgPrint("LOCAL: 6\n");
+#endif
+
+
+ //
+ // If Read Operation Data Get
+ //
+ if(ReadOp)
+ *Data = READ_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBDT);
+
+#if DBG0
+ DbgPrint("LOCAL: 7\n");
+#endif
+
+ //
+ // Finish!!
+ //
+ WRITE_REGISTER_UCHAR( (PUCHAR)&(LOCAL_CNTL)->LBCTL,LBCTL_SWE );
+
+ // EIF NMI enable
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->STSR,0x00080000) ;
+ KeLowerIrql(oldirql);
+
+}
+
+VOID
+HalLocalDeviceReadWrite(
+ IN ULONG Offset,
+ IN OUT PUCHAR Data,
+ IN ULONG ReadOp
+)
+/*++
+
+Routine Description:
+
+ This routine is Access Local Device for Driver
+
+Arguments:
+ Offset Register Offset of Local Device
+ Data Pointer of read or write data
+ ReadOp 1 is Read.
+
+Return Value:
+
+ None
+
+--*/
+{
+ HalpLocalDeviceReadWrite(Offset,Data,ReadOp);
+}
+
+
+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
+
+--*/
+{
+
+
+ UCHAR ModeNow;
+ //
+ // Read MRC Mode Register
+ //
+ HalpLocalDeviceReadWrite(MRCMODE,&ModeNow,LOCALDEV_OP_READ);
+
+#if DBG0
+ DbgPrint("MRC Read : 1 = 0x%x\n",(UCHAR)ModeNow);
+#endif
+
+ //
+ // Write MRC Mode bit
+ //
+
+ ModeNow = ((ModeNow & 0x02) | (Mode << 7));
+#if DBG0
+ DbgPrint("MRC WRITE : 2 = 0x%x\n",(UCHAR)ModeNow);
+#endif
+
+ HalpLocalDeviceReadWrite(MRCMODE,&ModeNow,LOCALDEV_OP_WRITE);
+
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/private/ntos/nthals/halr98b/mips/rxesm.h b/private/ntos/nthals/halr98b/mips/rxesm.h
new file mode 100644
index 000000000..7fc976409
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxesm.h
@@ -0,0 +1,84 @@
+/*
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ rxesm.h
+
+Abstract:
+
+ This module is the header file that describes hardware addresses
+ for the r98B system.
+
+Author:
+
+
+
+Revision History:
+
+--*/
+
+#ifndef _RXESM_
+#define _RXESM_
+
+#include "halp.h"
+
+#define NVRAM_ESM_PHYSICAL_BASE 0x1f09e000 // See rxnvr.h
+#define NVRAM_ESM_PHYSICAL_END 0x1f09ffff // See rxnvr.h
+#define NVRAM_ESM_BASE (NVRAM_ESM_PHYSICAL_BASE + KSEG1_BASE)
+#define NVRAM_ESM_END (NVRAM_ESM_PHYSICAL_END + KSEG1_BASE)
+
+
+
+//
+// define value
+//
+#define NVRAM_VALID 3
+//#define NVRAM_MAGIC 0xff651026
+#define NVRAM_MAGIC 0xff951115
+#define STRING_BUFFER_SIZE 512
+#define TIME_STAMP_SIZE 14
+
+
+VOID
+HalpMrcModeChange(
+ UCHAR Mode
+ );
+
+//
+// Define STS1 register
+//
+typedef struct _STS1_REGISTER {
+ ULONG COL0_1 : 2;
+ ULONG COL2_9 : 8;
+ ULONG COL10 : 1;
+ ULONG ROW0_9 : 10;
+ ULONG ROW10 : 1;
+ ULONG RF : 1;
+ ULONG RW : 1;
+ ULONG MBE1 : 1;
+ ULONG SBE1 : 1;
+ ULONG MBE0 : 1;
+ ULONG SBE0 : 1;
+ ULONG SIDE : 1;
+ ULONG BANK : 1;
+ ULONG ARE : 2;
+} STS1_REGISTER, *PSTS1_REGISTER;
+
+//
+// Define ADEC register
+//
+typedef struct _ADEC_REGISTER {
+ ULONG MIN : 7;
+ ULONG NOUSE1 : 1;
+ ULONG MAX : 7;
+ ULONG NOUSE2 : 9;
+ ULONG SIMM_1 : 1;
+ ULONG SIMM_2 : 1;
+ ULONG NOUSE3 : 1;
+ ULONG MAG : 1;
+ ULONG BLOCK : 3;
+ ULONG NOUSE4 : 1;
+} ADEC_REGISTER, *PADEC_REGISTER;
+
+#endif // _RXESM_
diff --git a/private/ntos/nthals/halr98b/mips/rxhalp.h b/private/ntos/nthals/halr98b/mips/rxhalp.h
new file mode 100644
index 000000000..d5b2f0e71
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxhalp.h
@@ -0,0 +1,212 @@
+/*
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ rxhalp.h
+
+Abstract:
+
+ This header file defines the private Hardware Architecture Layer (HAL)
+ R98[a-z]* specific interfaces, defines and structures.
+
+Author:
+
+
+Revision History:
+
+--*/
+
+#ifndef _RXHALP_
+#define _RXHALP_
+
+
+//
+// Define global data used to locate the EISA control space and the realtime
+// clock registers.
+//
+
+extern PVOID HalpEisaControlBase;
+extern PVOID HalpEisaMemoryBase;
+extern PVOID HalpRealTimeClockBase;
+
+extern ULONG HalpMachineCpu;
+extern ULONG HalpNumberOfPonce;
+extern ULONG HalpPhysicalNode;
+extern UCHAR HalpIntLevelofIpr[R98_CPU_NUM_TYPE][NUMBER_OF_IPR_BIT];
+extern ULONG HalpStartPciBusNumberPonce[];
+extern ULONG HalpCirrusAlive;
+
+typedef struct _INT_ENTRY {
+ ULONG StartBitNo;
+ ULONG NumberOfBit;
+ ULONG Arbitar;
+ ULONGLONG Enable; // 1: Enable 0: Open
+ ULONGLONG Open; // This Int Group Open Bit
+}INT_ENTRY,*PINT_ENTRY;
+
+extern INT_ENTRY HalpIntEntry[R98_CPU_NUM_TYPE][R98B_MAX_CPU][NUMBER_OF_INT];
+
+//
+// This is PONCE Interrupt relationship
+//
+
+typedef struct _RESET_REGISTER {
+ UCHAR Ponce; //Connet Interrupt Ponce
+ UCHAR IntGResetBit; //ResetValue Bit Define
+ UCHAR Cpu; //Connet CPU Initialize at inittime.
+ UCHAR Dummy; //Dummy Read Addr Index
+}RESET_REGISTER,*PRESET_REGISTER;
+
+extern RESET_REGISTER HalpResetValue[64];
+
+
+#define NONE (0xFFFFFFFF)
+#define RFU ((UCHAR)(0xFF))
+
+
+//
+// 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;
+} ADAPTER_OBJECT;
+
+
+// I/O TLB Entry Format(PTE Format)
+// 63 33 32 12 0
+// +---------+-------+----+-+
+// |MBZ | PFN |MBZ |V|
+// +---------+-------+----+-+
+// Valid : 1 Valid
+// : 0 InValid
+// Define translation table entry structure.
+//
+
+typedef volatile struct _TRANSLATION_ENTRY {
+ ULONG PageFrame;
+ ULONG Fill;
+} TRANSLATION_ENTRY, *PTRANSLATION_ENTRY;
+
+
+#define PAGE_TABLE_ENTRY_VALID 0x1
+
+//
+// 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
+ );
+
+BOOLEAN
+HalpInterruptFromPonce(
+ IN ULONG Vector,
+ IN ULONG Enable
+ );
+
+BOOLEAN
+HalpConnectIoInterrupt(
+ IN ULONG NumCpu
+ );
+
+
+VOID
+HalpSetupNmiHandler(
+ VOID
+ );
+
+VOID
+HalpCpuCheck(
+ VOID
+ );
+
+VOID
+HalpSVPSlotDetect(
+ VOID
+);
+
+
+VOID
+HalpBusErrorLog(
+ VOID
+ );
+
+VOID
+HalpEifLog(
+ VOID
+ );
+
+VOID
+HalpEifReturnLog(
+ VOID
+ );
+
+VOID
+HalpNmiLog(
+ VOID
+ );
+
+VOID
+HalpHwLogger(
+ IN ULONG Type,
+ IN ULONG Context
+ );
+
+#endif // _RXHALP_
diff --git a/private/ntos/nthals/halr98b/mips/rxhwlog.c b/private/ntos/nthals/halr98b/mips/rxhwlog.c
new file mode 100644
index 000000000..d3308e395
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxhwlog.c
@@ -0,0 +1,1409 @@
+/*++
+
+Copyright (c) 1994 Kobe NEC Software
+
+Module Name:
+
+ rxhwlog.c
+
+Abstract:
+
+ This module implements the ESM service routine for R98B
+
+Author:
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+#include "rxhwlog.h"
+#include "eisa.h"
+#include "stdio.h"
+
+UCHAR HwLogBuff[HWLOG_RECORD_SIZE+HWLOG_REV1_RECORD_SIZE+1024];
+extern ULONG HalpLogicalCPU2PhysicalCPU[];
+extern ULONG HalpNmiSvp[];
+
+#define NMI_BUFFER_SIZE 64
+
+ULONG HalpNMIBuf[R98B_MAX_CPU][NMI_BUFFER_SIZE];
+
+#define GET_TIME2(Buffer) { \
+ TIME_FIELDS timeBuffer; \
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKSR,\
+ 63-(EIF_VECTOR-DEVICE_VECTORS ));\
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKSR,\
+ 63-(ECC_1BIT_VECTOR-DEVICE_VECTORS ));\
+ HalQueryRealTimeClock( &timeBuffer ); \
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKRR,\
+ 63-(EIF_VECTOR-DEVICE_VECTORS ));\
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKRR,\
+ 63-(ECC_1BIT_VECTOR-DEVICE_VECTORS ));\
+ Header->YY = (timeBuffer.Year % 100) + ((timeBuffer.Year % 100) / 10) * 6; \
+ Header->MM = timeBuffer.Month+ (timeBuffer.Month/ 10) * 6; \
+ Header->DD = timeBuffer.Day + (timeBuffer.Day / 10) * 6; \
+ Header->hh = timeBuffer.Hour + (timeBuffer.Hour / 10) * 6; \
+ Header->mm = timeBuffer.Minute+(timeBuffer.Minute/10) * 6; \
+ Header->ss = timeBuffer.Second+(timeBuffer.Second/10) * 6; \
+}
+
+
+//
+// Interrupt set register 2 ( 0xz447 )
+//
+#define SVP_INTR2_SET_VIT3SET 0x0040
+#define SVP_WINDOW0_OFFSET 0x0000 // Window 0 start offset ( EISA I/O Space)
+#define SVP_WINDOW1_OFFSET 0x0800 // Window 1 start offset ( EISA I/O Space)
+#define SVP_WINDOW2_OFFSET 0x0c00 // Window 2 start offset ( EISA I/O Space)
+#define SVP_GLOBAL_OFFSET 0x0400 // Global Window start offset ( EISA I/O Space)
+//
+// EISA Slot is 1 orign. so When HalpSvpEisaSLot is 0 SPV no slot in.
+//
+ULONG HalpSvpEisaSlot = 0;
+ULONG HalpSvpWindow0;
+ULONG HalpSvpWindow1;
+ULONG HalpSvpWindow2;
+ULONG HalpSvpGlobal;
+ULONG HalpSvpAlive = FALSE;
+ULONG HalpBusySvpFlag=0;
+// For Cache
+
+// For Cache
+VOID
+HalpCacheErrorLog(
+ IN ULONG cpu,
+ IN PVOID pbuf,
+ IN ULONG errorcode
+);
+ULONG HalpCacheErrorStack[8196];
+UCHAR HalpCacheErrorHwLog[HWLOG_RECORD_SIZE+HWLOG_REV1_RECORD_SIZE];
+#define HEADER_CACHE 0x06
+
+//
+// SVP ISA Board Detect. This Borad is ISA but EISA Configration!!.
+// So Search EISA Configration.
+//
+VOID
+HalpSVPSlotDetect(
+ VOID
+)
+{
+ ULONG SlotNumber;
+ ULONG DataLength;
+ ULONG CompressedId;
+ UCHAR Buf[ sizeof(CM_EISA_SLOT_INFORMATION) + sizeof(CM_EISA_FUNCTION_INFORMATION)];
+ PCM_EISA_SLOT_INFORMATION SlotInformation;
+ PCM_EISA_FUNCTION_INFORMATION funcInformation;
+ ULONG i;
+ UCHAR Data;
+
+ //
+ // SVP H/W Alive by F/W.
+ //
+ HalpLocalDeviceReadWrite(ALMSNS_HIGH,&Data,LOCALDEV_OP_READ);
+ //
+ // detected By F/W .
+ //
+ if( Data & 0x1){
+ //
+ //F/W diag is fail !!
+ //
+ return;
+ }
+
+
+ for(SlotNumber =1 ;SlotNumber <= EISA_MAX_DEVICE;SlotNumber++){
+ for (i =0;i<sizeof(CM_EISA_SLOT_INFORMATION) + sizeof(CM_EISA_FUNCTION_INFORMATION);i++)
+ Buf[i]=0;
+
+ DataLength = HalGetBusData(
+ EisaConfiguration,
+ 0, //EISA Bus is 0
+ SlotNumber,
+ Buf,
+ sizeof(CM_EISA_SLOT_INFORMATION) +
+ sizeof(CM_EISA_FUNCTION_INFORMATION)
+ );
+ SlotInformation=( PCM_EISA_SLOT_INFORMATION)Buf;
+ funcInformation=( PCM_EISA_FUNCTION_INFORMATION)&Buf[sizeof(CM_EISA_SLOT_INFORMATION)];
+ //
+ // 0x018ca338 == > NEC SVP (38 a3 8c 01)
+ //
+ //
+ if(((SlotInformation->CompressedId) &0xffffff)== 0x8ca338){
+ HalpSvpEisaSlot = SlotNumber;
+ HalpSvpWindow0 = ( (SlotNumber<< PAGE_SHIFT)|EISA_CNTL_PHYSICAL_BASE|KSEG1_BASE|SVP_WINDOW0_OFFSET);
+ HalpSvpWindow1 = ( (SlotNumber<< PAGE_SHIFT)|EISA_CNTL_PHYSICAL_BASE|KSEG1_BASE|SVP_WINDOW1_OFFSET);
+ HalpSvpWindow2 = ( (SlotNumber<< PAGE_SHIFT)|EISA_CNTL_PHYSICAL_BASE|KSEG1_BASE|SVP_WINDOW2_OFFSET);
+ HalpSvpGlobal = ( (SlotNumber<< PAGE_SHIFT)|EISA_CNTL_PHYSICAL_BASE|KSEG1_BASE|SVP_GLOBAL_OFFSET);
+ break;
+ }
+#if DBG
+
+ DbgPrint("EISA Slot #%x DataLen= 0x%x\n",SlotNumber, DataLength );
+ DbgPrint("EISA Slot #%x CompressedId = 0x%x\n",SlotNumber, SlotInformation->CompressedId);
+ DbgPrint("EISA Slot #%x RetunCode = 0x%x\n",SlotNumber, SlotInformation->ReturnCode);
+ DbgPrint("EISA Slot #%x Checksum = 0x%x\n",SlotNumber, SlotInformation->Checksum);
+
+ DbgPrint("EISA Slot #%x FCompressedId = 0x%x\n",SlotNumber, funcInformation->CompressedId);
+ DbgPrint("EISA Slot #%x FMinorRevision= 0x%x\n",SlotNumber, funcInformation->MinorRevision);
+ DbgPrint("EISA Slot #%x FMajorRevision= 0x%x\n",SlotNumber, funcInformation->MajorRevision);
+ DbgPrint("EISA Slot #%x FFunctionFlags= 0x%x\n",SlotNumber, funcInformation->FunctionFlags);
+
+ DbgPrint("EISA Slot #%x FTypeString = %s\n",SlotNumber, funcInformation->TypeString);
+#endif
+ }
+ //
+ // Eisa Configration Ok.
+ //
+ if( HalpSvpEisaSlot){
+ HalpSvpAlive = TRUE;
+#if DBG
+ DbgPrint("SVP ALIVE\n" );
+#endif
+ }
+}
+
+VOID
+HalSvpIntToSvp(
+ VOID
+ )
+{
+
+ UCHAR Status;
+ UCHAR LockCode;
+ UCHAR LockCode2;
+ ULONG i;
+
+ ULONG RetryCount =10;
+ UCHAR Code = 0x7;
+
+ KiAcquireSpinLock(&HalpLogLock);
+
+
+
+ Status = READ_PORT_UCHAR( HalpSvpWindow2 + 0xc1 );
+ KeStallExecutionProcessor( 1000 ); // wait 1msec
+
+ for( i = 0; (i < RetryCount ) && (Status != 0); i++ ){
+ KeStallExecutionProcessor( 1000 ); // wait 1msec
+ Status = READ_PORT_UCHAR( HalpSvpWindow2 + 0xc1 );
+ }
+
+ if( Status != 0x00 ){
+ // Flag on for dump
+ HalpBusySvpFlag = 1;
+ return;
+ }
+
+
+ LockCode = READ_PORT_UCHAR( HalpSvpGlobal + 0x58 );
+ WRITE_PORT_UCHAR(HalpSvpGlobal + 0x58,0xff );
+ LockCode2= READ_PORT_UCHAR( HalpSvpGlobal + 0x50 );
+ WRITE_PORT_UCHAR(HalpSvpGlobal + 0x50,0xff );
+
+ WRITE_PORT_UCHAR( HalpSvpWindow2 + 0xc1, Code );
+
+ WRITE_PORT_UCHAR( HalpSvpGlobal + 0x58,LockCode );
+ WRITE_PORT_UCHAR( HalpSvpGlobal + 0x50,LockCode2 );
+
+ WRITE_PORT_UCHAR( HalpSvpGlobal + 0x47,SVP_INTR2_SET_VIT3SET);
+
+ KiReleaseSpinLock(&HalpLogLock);
+
+ return;
+}
+
+
+
+
+VOID
+NVRAM_HWLOG_WRITE(
+ IN PVOID Buff,
+ IN ULONG StartBlockNo,
+ IN ULONG NumBlock
+){
+
+ ULONG i,j;
+
+
+ for(i=0;i<NumBlock;i++){
+ for(j=0;j<HWLOG_RECORD_SIZE;j++){
+ //
+ // Byte write only.
+ //
+ WRITE_REGISTER_UCHAR(
+ (PUCHAR)(NVRAM_HWLOG_BASE+
+// (PUCHAR)(NVRAM_HWLOG_BASE+HWLOG_RECORD_SIZE +
+ StartBlockNo * HWLOG_RECORD_SIZE +
+ i*HWLOG_RECORD_SIZE+
+ j),
+
+ ((PUCHAR)Buff)[i*HWLOG_RECORD_SIZE + j]
+ );
+ }
+ }
+
+
+}
+
+
+
+VOID
+NVRAM_HWLOG_READ(
+ IN PVOID Buff,
+ IN ULONG StartBlockNo,
+ IN ULONG NumBlock
+){
+
+ ULONG i,j;
+
+
+ for(i=0;i<NumBlock;i++){
+ for(j=0;j<HWLOG_RECORD_SIZE;j++){
+ //
+ // read
+ //
+ ((PUCHAR)Buff)[i*HWLOG_RECORD_SIZE + j]= READ_REGISTER_UCHAR( (PUCHAR)(NVRAM_HWLOG_BASE+ StartBlockNo * HWLOG_RECORD_SIZE + i*HWLOG_RECORD_SIZE+ j) );
+ }
+ }
+
+
+}
+
+VOID
+HalpHwLogBuffInit(
+){
+ ULONG i;
+ for(i=0;i< HWLOG_RECORD_SIZE+HWLOG_REV1_RECORD_SIZE;i++)
+ HwLogBuff[i] = 0x0;
+}
+
+VOID
+HalpHwLogHeaderInit(
+
+){
+ PHW_LOG_AREA_HEADER Header;
+ PUCHAR Sump;
+ ULONG i;
+ //
+ // Genelic Buffer Initialization to all 0x0
+ //
+ HalpHwLogBuffInit();
+
+ Header = (PHW_LOG_AREA_HEADER)HwLogBuff;
+ //
+ // Build This record header
+ //
+ Header->Ident = (USHORT)HEADER_IDENT_REV0;
+ //
+ // Time Field is BCD
+ //
+ GET_TIME2(&(Header->YY));
+ Header->RCT = HEADER_PANIC;
+ Header->ST1 = 0;
+ Header->ST2 = 0;
+ Header->ST3 = 0;
+ Header->DTLEN = HWLOG_REV1_RECORD_SIZE;
+ //
+ // Endian Convert to Big
+ //
+ Header->DTLEN = (
+ ((Header->DTLEN & 0xFF) << 8) |
+ ((Header->DTLEN & 0xFF00) >> 8)
+ );
+ Header->FRU1[0]=Header->FRU1[1] = 0;
+ Header->FRU2[0]=Header->FRU2[1] = 0;
+
+ //Make Check Sum
+ Header->CSM = 0;
+ Sump = (PUCHAR) HwLogBuff;
+ for (i= 0; i<= 14; i++){
+ Header->CSM += *(Sump+i);
+ }
+ Header->CSM = (UCHAR)( Header->CSM & 0xff);
+ // Header Build Conpleate!!
+
+
+}
+
+BOOLEAN
+HalpSetHwLog(
+ IN PVOID Buff,
+ IN ULONG NumBlock
+){
+
+ PHWLOG_CONTROL_INFO Control;
+ HW_LOG_AREA_HEADER Header;
+ ULONG StartBlockNo;
+ ULONG AllFree;
+ ULONG RemainFree;
+ ULONG i;
+ UCHAR InBuff[sizeof(HWLOG_CONTROL_INFO)];
+ PUCHAR Sump;
+ ULONG Csm;
+ ULONG FreeLen,Len;
+
+#if 0 //test only
+ //
+ // Get Control area
+ //
+ for (i = 0;i < sizeof(HWLOG_CONTROL_INFO);i++)
+ InBuff[i] = 0;
+ NVRAM_HWLOG_WRITE((PUCHAR)InBuff, 0x0,1);
+
+#endif
+
+
+ //
+ // Get Control area
+ //
+ for (i = 0;i < sizeof(HWLOG_CONTROL_INFO);i++)
+ InBuff[i] = READ_REGISTER_UCHAR( (PUCHAR)(NVRAM_HWLOG_BASE+i));
+
+ Control= ( PHWLOG_CONTROL_INFO)InBuff;
+ //Convert Endian to littl
+ Control->BASE = ( ((Control->BASE & 0xFF00) >> 8) | ((Control->BASE & 0x00FF) << 8) );
+ Control->NREC = ( ((Control->NREC & 0xFF00) >> 8) | ((Control->NREC & 0x00FF) << 8) );
+ Control->TBASE= ( ((Control->TBASE& 0xFF00) >> 8) | ((Control->TBASE& 0x00FF) << 8) );
+ Control->TN = ( ((Control->TN & 0xFF00) >> 8) | ((Control->TN & 0x00FF) << 8) );
+ Control->RBASE= ( ((Control->RBASE& 0xFF00) >> 8) | ((Control->RBASE& 0x00FF) << 8) );
+ //
+ // Write Log Number
+ // This data Big endian
+ //
+ ((PHW_LOG_AREA_HEADER)Buff)->LGN = Control->LOGNUM;
+ Csm = 0;
+ Sump = (PUCHAR) Buff;
+ for (i= 0; i<= 14; i++){
+ Csm += (ULONG)(*(Sump+i));
+ }
+// Csm = ((PHW_LOG_AREA_HEADER)Buff)->CSM + Control->LOGNUM;
+ ((PHW_LOG_AREA_HEADER)Buff)->CSM = (UCHAR)(Csm & 0xFF);
+ Control->RN = ( ((Control->RN & 0xFF00) >> 8) | ((Control->RN & 0x00FF) << 8) );
+
+ //
+ // Log Field Invalid
+ //
+#if 1
+ if ( (Control->STAT & 0x01) == 0 ){
+ // If SVP Board alive So write port of svp.
+ // IF EIF Occured SVP Board required reset port.
+ //
+
+ if(HalpSvpAlive)
+ HalSvpIntToSvp();
+ return FALSE;
+ }
+#endif
+
+ if ((Control->BASE < 0) || (NVRAM_HWLOG_MAX_ENTRY <= Control->BASE ) ||
+ (Control->NREC < 0) || (NVRAM_HWLOG_MAX_ENTRY < Control->NREC ) ||
+ (Control->RBASE < 0) || (NVRAM_HWLOG_MAX_ENTRY <= Control->RBASE) ||
+ (Control->RN < 0) || (NVRAM_HWLOG_MAX_ENTRY < Control->RN ))
+ {
+ // If SVP Board alive So write port of svp.
+ // IF EIF Occured SVP Board required reset port.
+ //
+
+ if(HalpSvpAlive)
+ HalSvpIntToSvp();
+ return FALSE;
+ }
+
+ StartBlockNo = Control->RBASE+Control->RN;
+
+ if(StartBlockNo > NVRAM_HWLOG_MAX_ENTRY)
+ StartBlockNo -= NVRAM_HWLOG_MAX_ENTRY;
+
+ //
+ // We Can't Logging. as if used log area wrieted back disk.
+ //
+ if(
+ ( (NVRAM_HWLOG_MAX_ENTRY - Control->NREC) < NumBlock) ||
+ ( (NVRAM_HWLOG_MAX_ENTRY - Control->NREC == 0))
+ ){
+ // If SVP Board alive So write port of svp.
+ // IF EIF Occured SVP Board required reset port.
+ //
+
+ if(HalpSvpAlive)
+ HalSvpIntToSvp();
+
+ return FALSE;
+ }
+
+ //
+ // as if used log area writed back disk as posible.
+ //
+ if(
+ (NVRAM_HWLOG_MAX_ENTRY - Control->RN) < NumBlock &&
+ (NVRAM_HWLOG_MAX_ENTRY - Control->NREC) >= NumBlock
+ ){
+
+
+ RemainFree = (NVRAM_HWLOG_MAX_ENTRY - Control->RN);
+
+ NVRAM_HWLOG_WRITE(Buff, StartBlockNo+1,RemainFree);
+ Control->NREC += (USHORT)RemainFree;
+ Control->RN += (USHORT)RemainFree;
+ NumBlock -= RemainFree;
+#if 0
+ Control->RBASE += (USHORT)NumBlock;
+
+#endif
+ //
+ // Move RBASE
+ //
+ FreeLen=0;
+
+ do{
+ //
+ // Read RBASE Header
+ //
+
+ NVRAM_HWLOG_READ(&Header,Control->RBASE,1);
+
+ //
+ // Check Header
+ //
+
+ if(Header.Ident != HEADER_IDENT_REV0){
+ // If SVP Board alive So write port of svp.
+ // IF EIF Occured SVP Board required reset port.
+ //
+
+ if(HalpSvpAlive)
+ HalSvpIntToSvp();
+ return FALSE;
+ }
+
+ //
+ // Check Csm
+ //
+
+ Csm = 0;
+ Sump = (PUCHAR) &Header;
+ for (i= 0; i<= 14; i++){
+ Csm += *(Sump+i);
+ }
+ Csm = (UCHAR)( Csm & 0xff);
+ if(Header.CSM!=Csm){
+ // If SVP Board alive So write port of svp.
+ // IF EIF Occured SVP Board required reset port.
+ //
+
+ if(HalpSvpAlive)
+ HalSvpIntToSvp();
+ return FALSE;
+ }
+ //
+ // FreeLen
+ //
+ Len=0;
+ Len = ( ((Header.DTLEN & 0xFF) << 8) | ((Header.DTLEN & 0xFF00) >> 8) );
+ if(Len%32){
+ Len=(Len/32)+1;
+ }else{
+ Len=Len/32;
+ }
+ FreeLen=FreeLen+Len+1;
+
+ //
+ // Move RBASE
+ //
+ Control->RBASE = Control->RBASE+(USHORT)FreeLen;
+ if(Control->RBASE >= NVRAM_HWLOG_MAX_ENTRY){
+ Control->RBASE=Control->RBASE - NVRAM_HWLOG_MAX_ENTRY;
+ }
+ }while(FreeLen < NumBlock);
+
+ Control->RN=Control->RN - (USHORT)FreeLen;
+ StartBlockNo = 0;
+ }
+
+ NVRAM_HWLOG_WRITE(Buff, StartBlockNo+1,NumBlock);
+
+ Control->RN += (USHORT)NumBlock;
+ if(Control->LOGNUM==0xff){
+ Control->LOGNUM=0;
+ }else{
+ Control->LOGNUM++;
+ }
+ Control->NREC += (USHORT)NumBlock;
+
+ //
+ // Convet endian to big
+ //
+ Control->BASE = ( ((Control->BASE & 0xFF00) >> 8) | ((Control->BASE & 0x00FF) << 8) );
+ Control->NREC = ( ((Control->NREC & 0xFF00) >> 8) | ((Control->NREC & 0x00FF) << 8) );
+ Control->TBASE= ( ((Control->TBASE& 0xFF00) >> 8) | ((Control->TBASE& 0x00FF) << 8) );
+ Control->TN = ( ((Control->TN & 0xFF00) >> 8) | ((Control->TN & 0x00FF) << 8) );
+ Control->RBASE= ( ((Control->RBASE& 0xFF00) >> 8) | ((Control->RBASE& 0x00FF) << 8) );
+ Control->RN = ( ((Control->RN & 0xFF00) >> 8) | ((Control->RN & 0x00FF) << 8) );
+
+ //
+ // Write fix HW Log Control Area.
+ // Block No = 0;
+ // Number of block = 1;
+ NVRAM_HWLOG_WRITE((PUCHAR)Control, 0x0,1);
+
+
+ // If SVP Board alive So write port of svp.
+ // IF EIF Occured SVP Board required reset port.
+ //
+
+ if(HalpSvpAlive)
+ HalSvpIntToSvp();
+
+ return TRUE;
+}
+
+VOID
+HalpColumnbsSysbusLogger(
+ IN ULONG Node
+){
+
+ PHW_LOG_COLUMNBS_SYSBUS_CONTEXT Buf;
+ PCOLUMNBUS_REGISTER ColumnbusRegister;
+ ULONG i;
+ ULONG PhysicalCpuNumber;
+ //
+ // Builg Log Header
+ //
+ HalpHwLogHeaderInit();
+
+ Buf = (PHW_LOG_COLUMNBS_SYSBUS_CONTEXT)HwLogBuff;
+
+ //
+ // CPU Context.
+ //
+ Buf->EPC.Long = 0;
+ Buf->STATUS = 0;
+ Buf->CAUSE = 0;
+ Buf->CONFIG = 0;
+ Buf->LLADR = 0;
+ Buf->RPID = 0;
+ Buf->CASHEER = 0;
+ Buf->ERREPC.Long = 0;
+
+ //
+ // This Register is local read Only.
+ //
+ Buf->COLUMNBS_ERRNOD= READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD);
+#if 0
+ //
+ // Error CPU detect
+ //
+ if( Buf->COLUMNBS_ERRNOD & ERRNOD_NODE4){
+ Node = COLUMBUS0_NODE;
+ break;
+ else if( Buf->COLUMNBS_ERRNOD & ERRNOD_NODE5)
+ Node = COLUMBUS1_NODE;
+ break;
+ else if( Buf->COLUMNBS_ERRNOD & ERRNOD_NODE6)
+ Node = COLUMBUS2_NODE;
+ break;
+ else if( Buf->COLUMNBS_ERRNOD & ERRNOD_NODE7)
+ Node = COLUMBUS3_NODE;
+ break;
+ default :
+ break;
+
+ }
+#endif
+ //
+ // Erred Columbus H/W Register Context.
+ //
+ Buf->COLUMNBS_NMIR = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->NMIR);
+ Buf->COLUMNBS_CNFG = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->CNFG);
+ Buf->COLUMNBS_STSR = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->STSR);
+ //
+ // This Register is local read Only.
+ //
+// Buf->COLUMNBS_ERRNOD= READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD);
+
+ Buf->COLUMNBS_AERR = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->AERR);
+ Buf->COLUMNBS_AERR2 = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->AERR2);
+ Buf->COLUMNBS_FERR = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->FERR);
+ Buf->COLUMNBS_FERR2 = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->FERR2);
+ Buf->COLUMNBS_ERRMK = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->ERRMK);
+ Buf->COLUMNBS_ERRMK2= READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->ERRMK2);
+ Buf->COLUMNBS_ERRI = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->ERRI);
+ Buf->COLUMNBS_ERRI2 = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->ERRI2);
+ Buf->COLUMNBS_NMIM = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->NMIM);
+ Buf->COLUMNBS_NMIM2 = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->NMIM2);
+ Buf->COLUMNBS_ARTYCT= READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->ARTYCT);
+ Buf->COLUMNBS_DRTYCT= READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->DRTYCT);
+ Buf->COLUMNBS_REVR = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->REVR);
+ Buf->COLUMNBS_MODE = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->MODE);
+ Buf->IPR.Long = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->IPR);
+ Buf->IPR.Fill = READ_REGISTER_ULONG( ((PULONG)&COLUMNBS_GCNTL(Node)->IPR) +1);
+ Buf->MKR.Long = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->MKR);
+ Buf->MKR.Fill = READ_REGISTER_ULONG( ((PULONG)&COLUMNBS_GCNTL(Node)->MKR) +1);
+
+#if 1
+ ColumnbusRegister = (PCOLUMNBUS_REGISTER)&COLUMNBS_GCNTL(Node)->RRMT0H;
+
+ for(i=0;i< 8;i++){
+ Buf->RRMTXX[i].Long = READ_REGISTER_ULONG( (PULONG)(ColumnbusRegister++) );
+ Buf->RRMTXX[i].Fill = READ_REGISTER_ULONG( (PULONG)(ColumnbusRegister++) );
+// ColumnbusRegister++;
+ }
+
+ //
+ // STCON Register Local Access Only. So We report when CPU == happned CPU.
+ //
+ PhysicalCpuNumber = Node & 0x3;
+ if(PhysicalCpuNumber == HalpLogicalCPU2PhysicalCPU[(PCR->Prcb)->Number]){
+ Buf->COLUMNBS_SYNDM = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->SYNDM);
+ Buf->COLUMNBS_STCON = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->STCON);
+ Buf->COLUMNBS_STSAD = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->STSAD);
+ Buf->COLUMNBS_STADMK = READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->STADMK);
+
+ ColumnbusRegister = (PCOLUMNBUS_REGISTER)&COLUMNBS_GCNTL(Node)->STDATH;
+
+ WRITE_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->STCON,
+ Buf->COLUMNBS_STCON & 0x004fffff);
+ while(READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->STCON ) & 0x00800000)
+ ;
+ for(i=0;i< 64;i++){
+ Buf->TRACE[i].Long = READ_REGISTER_ULONG( (PULONG)ColumnbusRegister );
+ Buf->TRACE[i].Fill = READ_REGISTER_ULONG( (PULONG)(ColumnbusRegister+1) );
+// ColumnbusRegister++;
+ }
+ WRITE_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->STCON,
+ Buf->COLUMNBS_STCON | 0x00800000 );
+ }
+#endif
+
+ //
+ // Write Log Record
+ //
+ HalpSetHwLog(Buf,(HWLOG_REV1_RECORD_SIZE / HWLOG_RECORD_SIZE)+1);
+
+}
+
+VOID
+HalpMpuLogger(
+ IN ULONG Node
+){
+ HalpColumnbsSysbusLogger(Node);
+}
+
+
+//
+//
+//
+VOID
+HalpPoncePciBuserrLogger(
+ IN ULONG Node
+){
+ //
+ //
+
+ PHW_LOG_PONCE_CONTEXT Buf;
+ ULONG Ponce;
+ PPONCE_REGISTER PonceRegister;
+ ULONG i;
+
+ //
+ // Builg Log Header
+ //
+ HalpHwLogHeaderInit();
+
+ Buf = (PHW_LOG_PONCE_CONTEXT)HwLogBuff;
+ Ponce = Node;
+ //
+ // CPU Context.
+ //
+ Buf->EPC.Long = 0;
+ //
+ // Columbus H/W Register Context.
+ //
+ Buf->COLUMNBS_ERRNOD= READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD);
+ Buf->PONCE_REVR = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->REVR);
+ Buf->PONCE_AERR = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->AERR);
+ Buf->PONCE_FERR = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->FERR);
+ Buf->PONCE_ERRM = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->ERRM);
+ Buf->PONCE_ERRI = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->ERRI);
+ Buf->PONCE_EAHI = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->EAHI);
+ Buf->PONCE_EALI = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->EALI);
+ Buf->PONCE_PAERR = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PAERR);
+ Buf->PONCE_PFERR = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PFERR);
+ Buf->PONCE_PERRM = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PERRM);
+ Buf->PONCE_PERRI = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PERRI);
+ Buf->PONCE_PTOL = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PTOL);
+ Buf->PONCE_PNRT = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PNRT);
+ Buf->PONCE_PRCOL = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PRCOL);
+ Buf->PONCE_PMDL = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PMDL);
+ Buf->PONCE_ANRC = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->ANRC);
+ Buf->PONCE_DNRC = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->DNRC);
+ Buf->PONCE_PCMDN = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PCMDN);
+ Buf->PONCE_PSTAT = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PSTAT);
+ Buf->PONCE_REVID = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->REVID);
+ Buf->PONCE_LTNCY = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->LTNCY);
+
+#if 0
+ PonceRegister = (PPONCE_REGISTER)&PONCE_CNTL(Ponce)->RRMT0H;
+
+ for(i=0;i< 8;i++){
+ Buf->PONCE_RRMTX[i].Long = READ_REGISTER_ULONG( (PULONG)PonceRegister );
+ Buf->PONCE_RRMTX[i].Fill = READ_REGISTER_ULONG( (PULONG)(PonceRegister+1) );
+ PonceRegister++;
+ }
+
+ Buf->PONCE_TRSM = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->TRSM);
+// Buf->PONCE_TROM = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->TROM);
+ Buf->PONCE_TRAC = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->TRAC);
+ Buf->PONCE_TRDS = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->TRDS);
+#endif
+
+ //
+ // Write Log Record
+ //
+ HalpSetHwLog(Buf,(HWLOG_REV1_RECORD_SIZE / HWLOG_RECORD_SIZE)+1);
+
+}
+
+VOID
+HalpPonceSysbuserrLogger(
+ IN ULONG Node
+){
+
+ HalpPoncePciBuserrLogger(Node);
+
+}
+
+VOID
+HalpMagellanSysbuserrLogger(
+ IN ULONG Node
+){
+
+
+ PHW_LOG_MAGELLAN_SYSBUS_CONTEXT Buf;
+ ULONG Magellan;
+ ULONG i;
+ //
+ // Builg Log Header
+ //
+ HalpHwLogHeaderInit();
+
+ Buf = ( PHW_LOG_MAGELLAN_SYSBUS_CONTEXT)HwLogBuff;
+ Magellan = Node - MAGELLAN0_NODE;
+ //
+ // Magellan Context.
+ //
+ Buf->MAGELLAN_AERR = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->AERR );
+ Buf->MAGELLAN_FERR = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->FERR );
+ Buf->MAGELLAN_ERRM = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->ERRM );
+ Buf->MAGELLAN_ERRI = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->ERRI );
+#if 0 //non support
+ Buf->MAGELLAN_NMIM = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->NMIM );
+#endif
+ Buf->MAGELLAN_EAHI = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->EAHI );
+ Buf->MAGELLAN_EALI = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->EALI );
+ Buf->MAGELLAN_CKE0 = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->CKE0 );
+ Buf->MAGELLAN_SECT = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->SECT );
+ Buf->MAGELLAN_STS1 = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->STS1 );
+ Buf->MAGELLAN_DATM.Long =READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->DATM );
+ Buf->MAGELLAN_DSRG.Long =READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->DSRG );
+ Buf->MAGELLAN_SDLM.Long = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->SDLM );
+
+ Buf->COLUMNBS_ERRNOD= READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD);
+
+ Buf->ECC1ERROR_COUNT = 0;
+ Buf->SIMM_ITF_RESULT = 0;
+ Buf->MEMORYMAP_ITF_RESULT =0;
+
+
+ Buf->MAGELLAN_INLC = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->INLC );
+ Buf->MAGELLAN_RCFD = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->RCFD );
+ Buf->MAGELLAN_DTRG = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->DTRG );
+ Buf->MAGELLAN_REVR = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->REVR );
+ Buf->MAGELLAN_ADECX[0] =READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->ADEC0 );
+ Buf->MAGELLAN_ADECX[1] =READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->ADEC1 );
+ Buf->MAGELLAN_ADECX[2] =READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->ADEC2 );
+ Buf->MAGELLAN_ADECX[3] =READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->ADEC3 );
+ Buf->MAGELLAN_EADECX[1]=READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->EAADEC0 );
+ Buf->MAGELLAN_EADECX[2]=READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(Magellan)->EAADEC1 );
+ Buf->EPC.Long = 0;
+
+#if 1
+ //
+ // These registers are not S/W specification
+ //
+ Buf->MAGELLAN_TMODE = READ_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD) );
+ Buf->MAGELLAN_TRA = READ_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TRA) );
+
+ WRITE_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD),
+ Buf->MAGELLAN_TMODE & 0x7fffffff);
+ while( READ_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD) ) & 0x80000000)
+ ;
+
+ i = READ_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD ) );
+ WRITE_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD),
+ i | 0x08000000);
+ while( !(READ_REGISTER_ULONG((PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD)) & 0x08000000) )
+ ;
+
+ for(i=0;i<32;i++){
+ Buf->TRMX[i][0] = READ_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TRM0[i]) );
+ Buf->TRMX[i][1] = READ_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TRM1[i]) );
+ Buf->TRMX[i][2] = READ_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TRM2[i]) );
+ }
+ i = READ_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD ) );
+ WRITE_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD),
+ i & 0xf7ffffff );
+ WRITE_REGISTER_ULONG( (PULONG)(&MAGELLAN_X_CNTL(Magellan)->TMOD),
+ ( i & 0xf7ffffff ) | 0x80000000);
+#endif
+
+ //
+ // Write Log Record
+ //
+ HalpSetHwLog(Buf,(HWLOG_REV1_RECORD_SIZE / HWLOG_RECORD_SIZE)+1);
+}
+
+//
+//
+VOID
+HalpEcc1Logger(
+ IN ULONG Node
+)
+{
+ HalpMagellanSysbuserrLogger(Node);
+}
+
+//
+//
+VOID
+HalpEcc2Logger(
+ IN ULONG Node
+)
+{
+ HalpMagellanSysbuserrLogger(Node);
+}
+
+VOID
+HalpEisaLogger(
+ IN ULONG Node
+){
+
+ PHW_LOG_EISA_CONTEXT Buf;
+
+ //
+ // Builg Log Header
+ //
+ HalpHwLogHeaderInit();
+
+ Buf = ( PHW_LOG_EISA_CONTEXT)HwLogBuff;
+
+ Buf->COLUMNBS_ERRNOD= READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD);
+
+ Buf->ESC_NMISC = READ_REGISTER_UCHAR( &((PEISA_CONTROL)HalpEisaControlBase )->NmiStatus);
+ Buf->ESC_NMIERTC = READ_REGISTER_UCHAR( &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
+ Buf->ESC_NMIESC = READ_REGISTER_UCHAR(
+ &( (PEISA_CONTROL)HalpEisaControlBase )->ExtendedNmiResetControl
+ );
+ Buf->ESC_SOFTNMI = READ_REGISTER_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiIoInterruptPort);
+
+ //
+ // Write Log Record
+ //
+ HalpSetHwLog(Buf,(HWLOG_REV1_RECORD_SIZE / HWLOG_RECORD_SIZE)+1);
+
+}
+
+VOID
+HalpCacheErrorLog(
+ IN ULONG cpu,
+ IN PVOID pbuf,
+ IN ULONG errorcode
+ )
+{
+ UCHAR string[256];
+ ULONG cacherr,errorepc;
+
+ PHW_LOG_AREA_HEADER Header;
+ PUCHAR Sump;
+ ULONG i;
+ PHW_LOG_CACHE_ERROR PCache_err;
+ //
+ // Genelic Buffer Initialization to all 0x0
+ //
+
+ Header = (PHW_LOG_AREA_HEADER)pbuf;
+ //
+ // Build This record header
+ //
+ Header->Ident = (USHORT)HEADER_IDENT_REV0;
+ //
+ // Time Field is BCD
+ //
+ GET_TIME2(&(Header->YY));
+ Header->RCT = HEADER_PANIC;
+ Header->ST1 = HEADER_CACHE;
+ Header->ST2 = (UCHAR)cpu;
+ Header->ST3 = (UCHAR)errorcode;
+ Header->DTLEN = HWLOG_REV1_RECORD_SIZE;
+ //
+ // Endian Convert to Big
+ //
+ Header->DTLEN = (
+ ((Header->DTLEN & 0xFF) << 8) |
+ ((Header->DTLEN & 0xFF00) >> 8)
+ );
+ Header->FRU1[0]=Header->FRU1[1] = 0;
+ Header->FRU2[0]=Header->FRU2[1] = 0;
+ Header->CSM = 0;
+ Sump = (PUCHAR) pbuf;
+ for (i= 0; i<= 14; i++){
+ Header->CSM += *(Sump+i);
+ }
+ Header->CSM = (UCHAR)( Header->CSM & 0xff);
+ // Header Build Conpleate!!
+ // Set hw log
+
+ HalpSetHwLog(pbuf,(HWLOG_REV1_RECORD_SIZE / HWLOG_RECORD_SIZE)+1);
+
+
+ // Display Error message
+
+ PCache_err=(PHW_LOG_CACHE_ERROR)pbuf;
+ cacherr=PCache_err->CHERR_cpu;
+ errorepc=PCache_err->EPC_cpu;
+ sprintf(string,"CPU #%x Cache Error %x %x %x ",cpu,cacherr,errorepc,errorcode);
+ HalpChangePanicFlag( 16, 0x01, 0x10);
+ HalDisplayString(string);
+ for(;;){
+// DbgBreakPoint();
+ }
+}
+
+VOID
+HalpCacheerrR4400Logger(
+ IN ULONG Node
+){
+
+}
+
+VOID
+HalpCacheerrR10000Logger(
+ IN ULONG Node
+){
+
+}
+
+VOID
+HalpNmiCpuContextCopy(
+ IN ULONG Node
+){
+ PHW_LOG_WDT_CONTEXT Buf;
+ ULONG Cpu;
+
+ Buf = (PHW_LOG_WDT_CONTEXT)HwLogBuff;
+
+ Cpu = Node - COLUMBUS0_NODE;
+
+ Buf->Cpu.At.Long =HalpNMIBuf[Cpu][0];
+ Buf->Cpu.V0.Long =HalpNMIBuf[Cpu][1];
+ Buf->Cpu.V1.Long =HalpNMIBuf[Cpu][2];
+ Buf->Cpu.A0.Long =HalpNMIBuf[Cpu][3];
+ Buf->Cpu.A1.Long =HalpNMIBuf[Cpu][4];
+ Buf->Cpu.A2.Long =HalpNMIBuf[Cpu][5];
+ Buf->Cpu.A3.Long =HalpNMIBuf[Cpu][6];
+ Buf->Cpu.T0.Long =HalpNMIBuf[Cpu][7];
+ Buf->Cpu.T1.Long =HalpNMIBuf[Cpu][8];
+ Buf->Cpu.T2.Long =HalpNMIBuf[Cpu][9];
+ Buf->Cpu.T3.Long =HalpNMIBuf[Cpu][10];
+ Buf->Cpu.T4.Long =HalpNMIBuf[Cpu][11];
+ Buf->Cpu.T5.Long =HalpNMIBuf[Cpu][12];
+ Buf->Cpu.T6.Long =HalpNMIBuf[Cpu][13];
+ Buf->Cpu.T7.Long =HalpNMIBuf[Cpu][14];
+ Buf->Cpu.T8.Long =HalpNMIBuf[Cpu][15];
+ Buf->Cpu.T9.Long =HalpNMIBuf[Cpu][16];
+ Buf->Cpu.GP.Long =HalpNMIBuf[Cpu][17];
+ Buf->Cpu.SP.Long =HalpNMIBuf[Cpu][18];
+ Buf->Cpu.FP.Long =HalpNMIBuf[Cpu][19];
+ Buf->Cpu.RA.Long =HalpNMIBuf[Cpu][20];
+ Buf->Cpu.STATUS =HalpNMIBuf[Cpu][21];
+ Buf->Cpu.CAUSE =HalpNMIBuf[Cpu][22];
+
+ Buf->Cpu.EPC.Long =HalpNMIBuf[Cpu][23];
+ Buf->Cpu.ERREPC.Long =HalpNMIBuf[Cpu][24];
+
+ Buf->Cpu.S0.Long = HalpNMIBuf[Cpu][25];
+ Buf->Cpu.S1.Long = HalpNMIBuf[Cpu][26];
+ Buf->Cpu.S2.Long = HalpNMIBuf[Cpu][27];
+ Buf->Cpu.S3.Long = HalpNMIBuf[Cpu][28];
+ Buf->Cpu.S4.Long = HalpNMIBuf[Cpu][29];
+ Buf->Cpu.S5.Long = HalpNMIBuf[Cpu][30];
+ Buf->Cpu.S6.Long = HalpNMIBuf[Cpu][31];
+ Buf->Cpu.S7.Long = HalpNMIBuf[Cpu][32];
+
+ Buf->Cpu.K0.Long = 0;
+
+ Buf->Cpu.ENTRYLO0.Long = HalpNMIBuf[Cpu][33];
+ Buf->Cpu.ENTRYLO1.Long = HalpNMIBuf[Cpu][34];
+ Buf->Cpu.BADVADDR.Long = HalpNMIBuf[Cpu][35];
+ Buf->Cpu.ENTRYHI.Long = HalpNMIBuf[Cpu][36];
+
+
+ Buf->Cpu.PAGEMASK = HalpNMIBuf[Cpu][37];
+ Buf->Cpu.PRID = HalpNMIBuf[Cpu][38];
+ Buf->Cpu.CONFIG = HalpNMIBuf[Cpu][39];
+ Buf->Cpu.LLADDR = HalpNMIBuf[Cpu][40];
+ Buf->Cpu.WATCHLO = HalpNMIBuf[Cpu][41];
+ Buf->Cpu.WATCHHI = HalpNMIBuf[Cpu][42];
+ Buf->Cpu.XCONTEXT.Long = HalpNMIBuf[Cpu][43];
+ Buf->Cpu.ECC = HalpNMIBuf[Cpu][44];
+ Buf->Cpu.CASEER = HalpNMIBuf[Cpu][45];
+ Buf->Cpu.TAGLO = HalpNMIBuf[Cpu][46];
+ Buf->Cpu.TAGHI = HalpNMIBuf[Cpu][47];
+
+}
+
+
+
+VOID
+HalpNmiWdtLogger(
+ IN ULONG Node
+){
+
+ PHW_LOG_WDT_CONTEXT Buf;
+
+ Buf = (PHW_LOG_WDT_CONTEXT)HwLogBuff;
+ //
+ // Builg Log Header
+ //
+ HalpHwLogHeaderInit();
+
+ HalpNmiCpuContextCopy(Node);
+
+ Buf->COLUMNBS_NMIR = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->NMIR);
+ Buf->COLUMNBS_CNFG = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->CNFG);
+ Buf->COLUMNBS_WDTSR= READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->WDTSR);
+ Buf->COLUMNBS_WDT = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->WDT);
+ Buf->IPR.Long = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->IPR);
+ Buf->IPR.Fill = READ_REGISTER_ULONG( ((PULONG)&(COLUMNBS_LCNTL)->IPR+1));
+ Buf->MKR.Long = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKR);
+ Buf->MKR.Fill = READ_REGISTER_ULONG( ((PULONG)&(COLUMNBS_LCNTL)->MKR+1));
+
+ //
+ // Write Log Record
+ //
+ HalpSetHwLog(Buf,(HWLOG_REV1_RECORD_SIZE / HWLOG_RECORD_SIZE)+1);
+
+}
+
+VOID
+HalpNmiSvpLogger(
+ IN ULONG Node
+){
+
+ PHW_LOG_SVP_CONTEXT Buf;
+
+ Buf = (PHW_LOG_SVP_CONTEXT)HwLogBuff;
+
+ //
+ // Builg Log Header
+ //
+ HalpHwLogHeaderInit();
+
+ HalpNmiCpuContextCopy(Node);
+ //
+ // Write Log Record
+ //
+ HalpSetHwLog(Buf,(HWLOG_REV1_RECORD_SIZE / HWLOG_RECORD_SIZE)+1);
+
+}
+
+VOID
+HalpNmiLog(
+ VOID
+){
+ ULONG PhysicalCpuNumber;
+ ULONG Node;
+
+ PhysicalCpuNumber = HalpLogicalCPU2PhysicalCPU[(PCR->Prcb)->Number];
+ Node = PhysicalCpuNumber + COLUMBUS0_NODE;
+
+ switch( HalpNMIFlag & 0xffff){
+ case NMIR_EXNMI :
+// if(HalpNmiSvp[PhysicalCpuNumber])
+ HalpNmiSvpLogger(Node);
+
+
+ break;
+ case NMIR_WDTOV:
+ HalpNmiWdtLogger(Node);
+ break;
+#if 0
+ case NMIR_CLBNMI:
+ case NMIR_UNANMI:
+ HalpColumnbsSysbusLogger(Node);
+ break;
+#endif
+ default:
+ if ( READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->AERR) & HW_LOG_MPU_INTERNAL_AERR)
+ HalpMpuLogger(Node);
+ else
+ HalpColumnbsSysbusLogger(Node);
+ break;
+ }
+
+
+}
+
+
+VOID
+HalpPowerLogger(
+ IN ULONG Node
+//
+// Node Not used.
+//
+//
+
+){
+
+
+ PHW_LOG_POWER_CONTEXT Buf;
+ UCHAR Data;
+ PHW_LOG_AREA_HEADER Header;
+ //
+ // Builg Log Header
+ //
+ HalpHwLogHeaderInit();
+ Header = (PHW_LOG_AREA_HEADER)HwLogBuff;
+
+ Header->RCT = HEADER_NOT_PANIC;
+ Buf = (PHW_LOG_POWER_CONTEXT)HwLogBuff;
+
+ Buf->COLUMNBS_ERRNOD= READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD);
+
+ HalpLocalDeviceReadWrite(ALARM_LOW,&Data,LOCALDEV_OP_READ);
+ Buf->LOCAL_ALARM = (USHORT)Data;
+ HalpLocalDeviceReadWrite(ALARM_HIGH,&Data,LOCALDEV_OP_READ);
+ Buf->LOCAL_ALARM |= (USHORT)(Data << 8);
+
+
+ HalpLocalDeviceReadWrite(ALMINH_LOW, &Data,LOCALDEV_OP_READ);
+ Buf->LOCAL_ALMINH = (USHORT)Data;
+ HalpLocalDeviceReadWrite(ALMINH_HIGH,&Data,LOCALDEV_OP_READ);
+ Buf->LOCAL_ALMINH |= (USHORT)(Data << 8);
+
+
+ HalpSetHwLog(Buf,(HWLOG_REV1_RECORD_SIZE / HWLOG_RECORD_SIZE)+1);
+
+
+
+}
+
+VOID
+HalpEifReturnLog(
+ VOID
+){
+
+ HalpPowerLogger(0);
+
+}
+
+
+VOID
+HalpHwLogger(
+ IN ULONG Type,
+ IN ULONG Context
+){
+
+ switch(Type){
+ case HWLOG_MPU_INTERNAL:
+ HalpMpuLogger(Context); //fix
+ break;
+ case HWLOG_COLUMNBS_SYSBUS:
+ HalpColumnbsSysbusLogger(Context); //fix
+ break;
+ case HWLOG_PCI_BUSERROR:
+ HalpPoncePciBuserrLogger(Context); //fix
+ break;
+ case HWLOG_PONCE_SYSBUS:
+ HalpPonceSysbuserrLogger(Context); //fix
+ break;
+ case HWLOG_MAGELLAN_SYSBUS:
+ HalpMagellanSysbuserrLogger(Context); //fix
+ break;
+ case HWLOG_EISA:
+ HalpEisaLogger(Context); //fix
+ break;
+ case HWLOG_POWER:
+ HalpPowerLogger(Context); //fix
+ break;
+ case HWLOG_2BITERROR:
+ HalpEcc2Logger(Context); //fix
+ break;
+ case HWLOG_CACHEERR_R4400:
+ HalpCacheerrR4400Logger(Context);
+ break;
+ case HWLOG_CACHEERR_R10000:
+ case HWLOG_SYSCORERR:
+ HalpCacheerrR10000Logger(Context);
+ break;
+ case HWLOG_NMI_WDT:
+ HalpNmiWdtLogger(Context);
+ break;
+
+ case HWLOG_NMI_SVP:
+ HalpNmiSvpLogger(Context); //fix
+ break;
+ case HWLOG_ECC1:
+ HalpEcc1Logger(Context); //fix
+ break;
+ default :
+ break;
+ }
+
+}
+
+//
+// This Function Called HalpHandleEif()
+//
+VOID
+HalpEifLog(
+ VOID
+){
+ ULONG Noder;
+ ULONG Node;
+ ULONG ErrorType;
+ ULONG Context;
+
+
+#if 0
+ //
+ // EIF logging only exec 1 cpu.
+ //
+ KiAcquireSpinLock(&HalpLogLock);
+#endif
+ //
+ // Node Get By reported CPU.
+ //
+ Noder = (READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRNOD)& 0xf3cc);
+
+ switch(Noder){
+ case ERRNOD_NODE0 :
+ case ERRNOD_NODE1 :
+ if(Noder & ERRNOD_NODE0)
+ Node = PONCE0_NODE;
+ else
+ Node = PONCE1_NODE;
+
+ if(READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Node)->AERR))
+ ErrorType = HWLOG_PONCE_SYSBUS; //bugbug
+ else
+ ErrorType = HWLOG_PCI_BUSERROR;
+ break;
+ case ERRNOD_NODE4 :
+ case ERRNOD_NODE5 :
+ case ERRNOD_NODE6 :
+ case ERRNOD_NODE7 :
+ if(Noder & ERRNOD_NODE4)
+ Node = COLUMBUS0_NODE;
+ else if(Noder & ERRNOD_NODE5)
+ Node = COLUMBUS1_NODE;
+ else if(Noder & ERRNOD_NODE6)
+ Node = COLUMBUS2_NODE;
+ else if(Noder & ERRNOD_NODE7)
+ Node = COLUMBUS3_NODE;
+
+ //
+ // Read AERR2 Register From EIF happend CPU. Not Reported CPU!!
+ //
+ if ( READ_REGISTER_ULONG( (PULONG)&COLUMNBS_GCNTL(Node)->AERR2) & HW_LOG_MPU_INTERNAL_AERR2)
+ ErrorType = HWLOG_MPU_INTERNAL;
+ else
+ ErrorType = HWLOG_COLUMNBS_SYSBUS;
+
+ break;
+ case ERRNOD_NODE8 :
+ case ERRNOD_NODE9 :
+
+ ErrorType = HWLOG_MAGELLAN_SYSBUS;
+
+ if(Noder & ERRNOD_NODE8)
+ Node = MAGELLAN0_NODE;
+ else
+ Node = MAGELLAN1_NODE;
+ break;
+
+ case ERRNOD_EISANMI:
+ ErrorType = HWLOG_EISA;
+ break;
+
+ default:
+ //
+ // if There is no CPU Coused EIF. So Reported CPU set.
+ //
+ ErrorType = HWLOG_COLUMNBS_SYSBUS;
+ Node = HalpLogicalCPU2PhysicalCPU[(PCR->Prcb)->Number] + COLUMBUS0_NODE;
+ break;
+ }
+ Context = Node;
+ HalpHwLogger(ErrorType, Context);
+
+#if 0
+ KiReleaseSpinLock(&HalpLogLock);
+#endif
+}
+
+
+//
+// This Function Called HalpBusError()
+//
+VOID
+HalpBusErrorLog(
+ VOID
+){
+ ULONG Node;
+ ULONG ErrorType;
+ ULONG Context;
+
+
+// KiAcquireSpinLock(&HalpLogLock);
+ //
+ // Node Get By reported CPU.
+ //
+ Node = (READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->EAHI) & 0xF000) >> 12;
+
+ switch(Node){
+ case PONCE0_NODE:
+ case PONCE1_NODE:
+ ErrorType = HWLOG_PONCE_SYSBUS;
+ break;
+ case COLUMBUS0_NODE:
+ case COLUMBUS1_NODE:
+ case COLUMBUS2_NODE:
+ case COLUMBUS3_NODE:
+ ErrorType = HWLOG_COLUMNBS_SYSBUS;
+ break;
+ case MAGELLAN0_NODE:
+ case MAGELLAN1_NODE:
+ ErrorType = HWLOG_2BITERROR;
+ break;
+ default:
+ ErrorType = HWLOG_COLUMNBS_SYSBUS;
+ //
+ // This is safe code
+ //
+ Node = HalpLogicalCPU2PhysicalCPU[(PCR->Prcb)->Number] + COLUMBUS0_NODE;
+ break;
+ }
+ Context = Node;
+ HalpHwLogger(ErrorType, Context);
+
+
+// KiReleaseSpinLock(&HalpLogLock);
+}
diff --git a/private/ntos/nthals/halr98b/mips/rxhwlog.h b/private/ntos/nthals/halr98b/mips/rxhwlog.h
new file mode 100644
index 000000000..077f3816f
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxhwlog.h
@@ -0,0 +1,469 @@
+/*
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ rxhwlog.h
+
+Abstract:
+
+ This module is the header file that describes hardware addresses
+ for the r98B system.
+
+Author:
+
+
+
+Revision History:
+
+--*/
+
+#ifndef _RXHWLOG_
+#define _RXHWLOG_
+
+#include "halp.h"
+
+
+#define NVRAM_HWLOG_PHYSIACL_ADDRESS 0x1F084000
+#define NVRAM_HWLOG_END 0x1F08C000
+#define NVRAM_HWLOG_BASE (KSEG1_BASE|NVRAM_HWLOG_PHYSIACL_ADDRESS)
+#define NVRAM_HWLOG_MAX_ENTRY (((NVRAM_HWLOG_END - NVRAM_HWLOG_PHYSIACL_ADDRESS)\
+ - sizeof(HWLOG_CONTROL_INFO)) / HWLOG_RECORD_SIZE)
+
+#define HWLOG_RECORD_SIZE 0x20
+#define HWLOG_REV1_RECORD_SIZE (0x200)
+//
+// Log Record RCT field
+//
+#define RCT_EPU 0x00
+#define RCT_MEMORY 0x01
+#define RCT_SYSBUS 0x03
+#define RCT_IOBUS 0x04
+#define RCT_CACHE 0x05
+#define RCT_SVP 0x06
+#define RCT_POWER 0x08
+#define RCT_COLUMNUS_SYSBUS 0x03
+
+
+//
+// Log Record ST1 field
+// PC: PCI BusNumber
+// EC: Errcode
+// MP: MPU Number
+//
+#define ST1_WDT_RUNOUT 0x00
+#define ST1_SVPNMI 0x08
+#define ST1_MPU 0x10
+#define ST1_SYS_IF_TRACE_LOG 0x12
+#define ST1_MEMORY_2BIT_ERR 0x00
+#define ST1_MEMORY_1BIT_HARD1 0x01
+#define ST1_MEMORY_1BIT_HARDN 0x02
+#define ST1_MEMORY_1BIT_HARD 0x03
+#define ST1_MEMORY_INTERNAL 0x10
+//#define ST1_COLUMNBUS_SYSBUS 0xEC
+//#define ST1_PONCE_SYSBUS 0xEC
+//#define ST1_MAGELLAN_SYSBUS 0xEC
+#define ST1_SYSBUS_TRACE_LOG 0x09
+//#define ST1_PCI_BUS_ERR PC
+#define ST1_EISA_BUS_ERR 0x07
+//#define ST1_CACHE_ERR_R4400 MP
+//#define ST1_CACHE_ERR_R10000 MP
+#define ST1_SVP_COM 0x01
+#define ST1_POWER_ALARM 0x20
+#define ST1_FAN_ALARM 0x21
+#define ST1_NPCI2_ALARM 0x22
+#define ST1_SVP_ALARM 0x23
+
+
+//
+// Log Record DTLEN
+//
+
+#define DTLEN_WDT 0x8001
+#define DTLEN_SVPNMI 0x6001
+#define DTLEN_MPU_INTERNAL 0x0002
+#define DTLEN_SYSTEM_IF_TRACE_LOG 0x0002
+#define DTLEN_ECC1_BIT 0x0002
+
+//
+// Log Record FRU1
+//
+#define FRU1_WDT "MPUx"
+#define FRU1_SVPNMI "MPUx"
+
+#pragma pack(1)
+
+typedef struct _MPU_REGISTER {
+ ULONG Long;
+ ULONG Fill;
+} MPU_REGISTER, *PMPU_REGISTER;
+
+typedef struct _HWLOG_CONTROL_INFO {
+ USHORT PAD0;
+ USHORT BASE;
+
+ USHORT PAD1;
+ USHORT NREC;
+
+ USHORT PAD2;
+ UCHAR PAD3;
+ UCHAR LOGNUM;
+
+ USHORT PAD4;
+ UCHAR PAD5;
+ UCHAR STAT;
+
+ USHORT PAD6;
+ USHORT TBASE;
+
+ USHORT PAD7;
+ USHORT TN;
+
+ USHORT PAD8;
+ USHORT RBASE;
+
+ USHORT PAD9;
+ USHORT RN;
+
+} HWLOG_CONTROL_INFO,*PHWLOG_CONTROL_INFO;
+
+
+typedef struct _HW_LOG_AREA_HEADER {
+ USHORT Ident;
+ UCHAR YY;
+ UCHAR MM;
+
+ UCHAR DD;
+ UCHAR hh;
+ UCHAR mm;
+ UCHAR ss;
+
+ UCHAR RCT;
+ UCHAR ST1;
+ UCHAR ST2;
+ UCHAR ST3;
+
+ USHORT DTLEN;
+ UCHAR LGN;
+ UCHAR CSM;
+
+ ULONG FRU1[2];
+ ULONG FRU2[2];
+
+}HW_LOG_AREA_HEADER,*PHW_LOG_AREA_HEADER;
+
+
+#define HEADER_IDENT_REV0 0xFFFFF
+#define HEADER_PANIC 0x10
+#define HEADER_NOT_PANIC 0x11
+typedef struct _HW_LOG_CPU_CONTEXT {
+ MPU_REGISTER At;
+ MPU_REGISTER V0;
+ MPU_REGISTER V1;
+ MPU_REGISTER V2;
+ MPU_REGISTER A0;
+ MPU_REGISTER A1;
+ MPU_REGISTER A2;
+ MPU_REGISTER A3;
+ MPU_REGISTER T0;
+ MPU_REGISTER T1;
+ MPU_REGISTER T2;
+ MPU_REGISTER T3;
+ MPU_REGISTER T4;
+ MPU_REGISTER T5;
+ MPU_REGISTER T6;
+ MPU_REGISTER T7;
+ MPU_REGISTER S0;
+ MPU_REGISTER S1;
+ MPU_REGISTER S2;
+ MPU_REGISTER S3;
+ MPU_REGISTER S4;
+ MPU_REGISTER S5;
+ MPU_REGISTER S6;
+ MPU_REGISTER S7;
+ MPU_REGISTER T8;
+ MPU_REGISTER T9;
+ MPU_REGISTER K0;
+ MPU_REGISTER GP;
+ MPU_REGISTER SP;
+ MPU_REGISTER FP;
+ MPU_REGISTER RA;
+ MPU_REGISTER ENTRYLO0;
+ MPU_REGISTER ENTRYLO1;
+ MPU_REGISTER CONTEXT;
+ MPU_REGISTER BADVADDR;
+ MPU_REGISTER ENTRYHI;
+ ULONG STATUS;
+ ULONG CAUSE;
+ MPU_REGISTER EPC;
+ ULONG PAGEMASK;
+ ULONG PRID;
+ ULONG CONFIG;
+ ULONG LLADDR;
+ ULONG WATCHLO;
+ ULONG WATCHHI;
+ MPU_REGISTER XCONTEXT;
+ ULONG ECC;
+ ULONG CASEER;
+ ULONG TAGLO;
+ ULONG TAGHI;
+ MPU_REGISTER ERREPC;
+}HW_LOG_CPU_CONTEXT,*PHW_LOG_CPU_CONTEXT;
+
+
+typedef struct _HW_LOG_WDT_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+ HW_LOG_CPU_CONTEXT Cpu;
+ ULONG COLUMNBS_NMIR;
+ ULONG COLUMNBS_CNFG;
+ ULONG COLUMNBS_WDTSR;
+ ULONG COLUMNBS_WDT;
+ COLUMNBUS_REGISTER IPR;
+ COLUMNBUS_REGISTER MKR;
+}HW_LOG_WDT_CONTEXT,*PHW_LOG_WDT_CONTEXT;
+
+
+typedef struct _HW_LOG_SVP_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+ HW_LOG_CPU_CONTEXT Cpu;
+}HW_LOG_SVP_CONTEXT,*PHW_LOG_SVP_CONTEXT;
+
+
+typedef struct _HW_LOG_MPU_INTERNAL_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+
+ MPU_REGISTER EPC;
+ ULONG STATUS;
+ ULONG CAUSE;
+ ULONG CONFIG;
+ ULONG LLADR;
+ ULONG RPID;
+ ULONG CASHEER;
+ MPU_REGISTER ERREPC;
+
+ ULONG COLUMNBS_NMIR;
+ ULONG COLUMNBS_CNFG;
+ ULONG COLUMNBS_STSR;
+ ULONG COLUMNBS_ERRNOD;
+ ULONG COLUMNBS_AERR;
+ ULONG COLUMNBS_AERR2;
+ ULONG COLUMNBS_FERR;
+ ULONG COLUMNBS_FERR2;
+ ULONG COLUMNBS_ERRMK;
+ ULONG COLUMNBS_ERRMK2;
+ ULONG COLUMNBS_ERRI;
+ ULONG COLUMNBS_ERRI2;
+ ULONG COLUMNBS_NMIM;
+ ULONG COLUMNBS_NMIM2;
+ ULONG COLUMNBS_ARTYCT;
+ ULONG COLUMNBS_DRTYCT;
+ ULONG COLUMNBS_REVR;
+ ULONG COLUMNBS_MODE;
+ COLUMNBUS_REGISTER IPR;
+ COLUMNBUS_REGISTER MKR;
+ COLUMNBUS_REGISTER RRMTXX[8];
+ ULONG COLUMNBS_SYNDM;
+ ULONG COLUMNBS_STCON;
+ ULONG COLUMNBS_STSAD;
+ ULONG COLUMNBS_STADMK;
+ COLUMNBUS_REGISTER TRACE[64];
+}HW_LOG_MPU_INTERNAL_CONTEXT,*PHW_LOG_MPU_INTERNAL_CONTEXT;
+
+#define HW_LOG_COLUMNBS_SYSBUS_CONTEXT HW_LOG_MPU_INTERNAL_CONTEXT
+#define PHW_LOG_COLUMNBS_SYSBUS_CONTEXT PHW_LOG_MPU_INTERNAL_CONTEXT
+
+#define HW_BUSERROR_MPU_CONTEXT HW_LOG_MPU_INTERNAL_CONTEXT
+#define PHW_BUSERROR_MPU_CONTEXT PHW_LOG_MPU_INTERNAL_CONTEXT
+
+#define HW_NMI_COLUMNBS_CONTEXT HW_LOG_MPU_INTERNAL_CONTEXT
+#define PHW_NMI_COLUMNBS_CONTEXT PHW_LOG_MPU_INTERNAL_CONTEXT
+
+#define HW_LOG_ECC1_CONTEXT HW_LOG_MAGELLAN_SYSBUS_CONTEXT
+#define PHW_LOG_ECC1_CONTEXT PHW_LOG_MAGELLAN_SYSBUS_CONTEXT
+
+#if 0
+typedef struct HW_LOG_MPU_INTERNAL_CONTEXT HW_LOG_COLUMNBS_SYSBUS_CONTEXT;
+typedef struct HW_LOG_COLUMNBS_SYSBUS_CONTEXT * PHW_LOG_COLUMNBS_SYSBUS_CONTEXT;
+typedef struct HW_LOG_MPU_INTERNAL_CONTEXT HW_BUSERROR_MPU_CONTEXT,*PHW_BUSERROR_MPU_CONTEXT;
+typedef struct HW_LOG_MPU_INTERNAL_CONTEXT HW_NMI_COLUMNBS_CONTEXT,*PHW_NMI_COLUMNBS_CONTEXT;
+typedef struct HW_LOG_MAGELLAN_SYSBUS_CONTEXT HW_LOG_ECC1_CONTEXT,*PHW_LOG_ECC1_CONTEXT;
+#endif
+
+typedef struct _HW_LOG_SYSTEM_IF_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+ COLUMNBUS_REGISTER SYNDM;
+ COLUMNBUS_REGISTER STCON;
+ COLUMNBUS_REGISTER STSAD;
+ COLUMNBUS_REGISTER STADMK;
+ USHORT STDATHL[64][2];
+}HW_LOG_SYSTEM_IF_CONTEXT,*PHW_LOG_SYSTEM_IF_CONTEXT;
+
+
+
+typedef struct _HW_LOG_MAGELLAN_SYSBUS_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+ ULONG MAGELLAN_AERR;
+ ULONG MAGELLAN_FERR;
+ ULONG MAGELLAN_ERRM;
+ ULONG MAGELLAN_ERRI;
+ ULONG MAGELLAN_NMIM;
+ ULONG MAGELLAN_EAHI;
+ ULONG MAGELLAN_EALI;
+ ULONG MAGELLAN_CKE0;
+ ULONG MAGELLAN_SECT;
+ ULONG MAGELLAN_STS1;
+ MAGELLAN_REGISTER MAGELLAN_DATM;
+ MAGELLAN_REGISTER MAGELLAN_DSRG;
+ MAGELLAN_REGISTER MAGELLAN_SDLM;
+ ULONG COLUMNBS_ERRNOD;
+ ULONG ECC1ERROR_COUNT;
+ ULONG SIMM_ITF_RESULT;
+ ULONG MEMORYMAP_ITF_RESULT;
+ ULONG MAGELLAN_INLC;
+ ULONG MAGELLAN_RCFD;
+ ULONG MAGELLAN_DTRG;
+ ULONG MAGELLAN_REVR;
+ ULONG MAGELLAN_ADECX[4];
+ ULONG MAGELLAN_EADECX[2];
+ MPU_REGISTER EPC;
+ ULONG MAGELLAN_TMODE;
+ ULONG MAGELLAN_TRA;
+ ULONG TRMX[32][3];
+}HW_LOG_MAGELLAN_SYSBUS_CONTEXT,*PHW_LOG_MAGELLAN_SYSBUS_CONTEXT;
+
+typedef struct _HW_LOG_PONCE_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+ MPU_REGISTER EPC;
+ ULONG COLUMNBS_ERRNOD;
+ ULONG PONCE_REVR;
+ ULONG PONCE_AERR;
+ ULONG PONCE_FERR;
+ ULONG PONCE_ERRM;
+ ULONG PONCE_ERRI;
+ ULONG PONCE_EAHI;
+ ULONG PONCE_EALI;
+ ULONG PONCE_PAERR;
+ ULONG PONCE_PFERR;
+ ULONG PONCE_PERRM;
+ ULONG PONCE_PERRI;
+ ULONG PONCE_PTOL;
+ ULONG PONCE_PNRT;
+ ULONG PONCE_PRCOL;
+ ULONG PONCE_PMDL;
+ ULONG PONCE_ANRC;
+ ULONG PONCE_DNRC;
+ ULONG PONCE_PCMDN;
+ ULONG PONCE_PSTAT;
+ ULONG PONCE_REVID;
+ ULONG PONCE_LTNCY;
+ PONCE_REGISTER PONCE_RRMTX[8];
+ ULONG PONCE_TRSM;
+ ULONG PONCE_TROM;
+ ULONG PONCE_TRAC;
+ ULONG PONCE_TRDS;
+ UCHAR PONCE_BUSTRACE[344]; //All 0
+}HW_LOG_PONCE_CONTEXT,*PHW_LOG_PONCE_CONTEXT;
+
+typedef struct _HW_LOG_SYSBUS_TRACE_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+ ULONG MAGELLAN_TMOD;
+ ULONG MAGELLAN_TRA;
+ ULONG TRMX[42][3];
+}HW_LOG_SYSBUS_TRACE_CONTEXT,*PHW_LOG_SYSBUS_TRACE_CONTEXT;
+
+
+typedef struct _HW_LOG_EISA_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+ ULONG COLUMNBS_ERRNOD;
+ ULONG ESC_NMISC;
+ ULONG ESC_NMIERTC;
+ ULONG ESC_NMIESC;
+ ULONG ESC_SOFTNMI;
+}HW_LOG_EISA_CONTEXT,*PHW_LOG_EISA_CONTEXT;
+
+
+
+
+typedef struct _HW_LOG_SVP_CON_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+}HW_LOG_SVP_CON_CONTEXT,*PHW_LOG_SVP_CON_CONTEXT;
+
+
+typedef struct _HW_LOG_POWER_CONTEXT {
+ HW_LOG_AREA_HEADER Header;
+ ULONG COLUMNBS_ERRNOD;
+ USHORT LOCAL_ALARM;
+ USHORT LOCAL_ALMINH;
+}HW_LOG_POWER_CONTEXT,*PHW_LOG_POWER_CONTEXT;
+
+#pragma pack(4)
+
+
+#define HWLOG_MPU_INTERNAL 0x1
+#define HWLOG_COLUMNBS_SYSBUS 0x2
+
+#define HWLOG_PCI_BUSERROR 0x100
+#define HWLOG_PONCE_SYSBUS 0x200
+#define HWLOG_MAGELLAN_SYSBUS 0x400
+
+#define HWLOG_EISA 0x10
+#define HWLOG_POWER 0x20
+#define HWLOG_2BITERROR 0x40
+
+#define HWLOG_CACHEERR_R4400 0x80
+#define HWLOG_CACHEERR_R10000 0x1000
+#define HWLOG_SYSCORERR 0x2000
+#define HWLOG_NMI_WDT 0x4000
+
+
+#define HWLOG_NMI_SVP 0x100000
+#define HWLOG_ECC1 0x200000
+
+
+#define HW_LOG_MPU_INTERNAL_AERR 0x37f
+#define HW_LOG_MPU_INTERNAL_AERR2 0xffffffff
+
+
+#define PONCE0_NODE 0
+#define PONCE1_NODE 1
+#define COLUMBUS0_NODE 4
+#define COLUMBUS1_NODE 5
+#define COLUMBUS2_NODE 6
+#define COLUMBUS3_NODE 7
+
+#define MAGELLAN0_NODE 8
+#define MAGELLAN1_NODE 9
+
+//Cache Error Log
+
+typedef struct _HW_LOG_CACHE_ERROR{
+ HW_LOG_AREA_HEADER Header;
+ ULONG EPC_cpu;
+ ULONG Rev;
+ ULONG Psr_cpu;
+ ULONG CFG_cpu;
+ ULONG PRID_cpu;
+ ULONG CHERR_cpu;
+ ULONG CheAdd_p;
+ ULONG CheAdd_s;
+ ULONG TagLo_p;
+ ULONG ECC_p;
+ ULONG TagLo_s;
+ ULONG ECC_s;
+ LONGLONG data_s;
+ LONGLONG Good_data_s;
+ ULONG Good_TagLo_s;
+ ULONG Good_ECC_s;
+ ULONG tag_synd_s;
+ ULONG data_synd_s;
+ LONGLONG xkphs_share;
+}HW_LOG_CACHE_ERROR,*PHW_LOG_CACHE_ERROR;
+
+
+
+
+#endif // _RXHWLOG_
+
+
+
+
diff --git a/private/ntos/nthals/halr98b/mips/rxhwsup.c b/private/ntos/nthals/halr98b/mips/rxhwsup.c
new file mode 100644
index 000000000..d4cc09ef1
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxhwsup.c
@@ -0,0 +1,2124 @@
+/*++
+
+Copyright (c) 1990-1993 Microsoft Corporation
+
+Module Name:
+
+ rxhwsup.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:
+
+
+
+Environment:
+
+ Kernel mode, local to I/O system
+
+Revision History:
+
+ S001 96/2/9 T.Samezima
+ -Add TLB limit over check.
+
+--*/
+
+#include "halp.h"
+#include "bugcodes.h"
+#include "eisa.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, HalpCreateDmaStructures)
+
+#endif
+
+extern POBJECT_TYPE IoAdapterObjectType;
+
+extern ULONG HalpLogicalCPU2PhysicalCPU[];
+
+//
+// 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 HalpInt0Interrupt;
+
+UCHAR DmaChannelMsg[] = "\nHAL: DMA channel x interrupted. ";
+
+//
+// Pointer to phyiscal memory for map registers.
+//
+
+ULONG HalpMapRegisterPhysicalBase;
+ULONG HalpLogicalAddressLimit = 0; // S001
+
+//
+// The following is an array of adapter object structures for the internal DMA
+// channels.
+//
+
+//
+// R98B AdapterObject for PCIBus is per PONCE
+//
+PADAPTER_OBJECT HalpPciAdapterObject[PONCE_MAX];
+
+IO_ALLOCATION_ACTION
+HalpAllocationRoutine (
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID MapRegisterBase,
+ IN PVOID Context
+ );
+
+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;
+
+ //
+ // 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)) {
+
+ MapRegisterNumber = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ NumberOfMapRegisters,
+ (0x100000 / PAGE_SIZE)
+ );
+
+ //
+ // Make sure this map register is valid for this adapter.
+ // No Check !! R98B 0-1M Never Free
+
+ }
+
+ 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);
+
+ //
+ // R98B Must Be Cached!!
+ //
+ CacheEnabled =TRUE;
+
+ //
+ // 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;
+
+ //
+ // 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.
+ // R98
+
+ MapRegisterNumber = (ULONG)-1;
+
+ MapRegisterNumber = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ *NumberOfMapRegisters,
+ (0x100000 / PAGE_SIZE)
+ );
+
+ //
+ // Ensure that any allocated map registers are valid for this adapter.
+ // No Check. R98B 0-1M Never Free!!.
+
+ 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,
+ (0x100000 / PAGE_SIZE),
+ *NumberOfMapRegisters
+ );
+ MapRegisterNumber =(0x100000 / PAGE_SIZE) ;
+
+ }
+
+ //
+ // 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.
+
+--*/
+
+{
+
+ 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;
+
+
+ //
+ // R98B Must Be Cached!!
+ //
+ CacheEnabled =TRUE;
+
+ //
+ // 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;
+ ULONG Ponce;
+
+ //
+ // 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 ) {
+#if DBG
+ DbgPrint("NumberOfMapRegister REQUEST = 0x%x\n",*NumberOfMapRegisters);
+#endif
+ *NumberOfMapRegisters = DMA_REQUEST_LIMIT;
+
+
+ }
+
+ if (DeviceDescription->InterfaceType == PCIBus) {
+
+ //
+ // Create a PCI adapter object.
+ //
+ Ponce = HalpPonceNumber(DeviceDescription->BusNumber);
+
+ if (HalpPciAdapterObject[Ponce] == NULL) {
+ adapterObject = HalpAllocateAdapter(0, &HalpPciAdapterObject[Ponce], NULL);
+ HalpPciAdapterObject[Ponce] = adapterObject;
+
+ } else {
+ adapterObject = HalpPciAdapterObject[Ponce];
+
+ }
+
+ return(adapterObject);
+
+ }
+ //
+ // If the request is for a unsupported bus then return NULL.
+ //
+
+ if (DeviceDescription->InterfaceType != Isa &&
+ DeviceDescription->InterfaceType != Eisa &&
+ //
+ // R98B Internal(Xbus) floppy used ESC DMAC channel 2
+ //
+ (DeviceDescription->InterfaceType == Internal && (DeviceDescription->DmaChannel !=2))
+ ) {
+
+ //
+ // This bus type is unsupported return NULL.
+ //
+
+ return(NULL);
+ }
+
+ //
+ // Create an adapter object.
+ //
+
+ adapterObject = HalpAllocateEisaAdapter( DeviceDescription );
+//
+// USE Limit DMA_REQUEST_LIMIT
+//
+//
+#if 0
+ if (*NumberOfMapRegisters > MasterAdapterObject->MapRegistersPerChannel / EISA_MAX_DEVICE) {
+
+ *NumberOfMapRegisters = MasterAdapterObject->MapRegistersPerChannel / EISA_MAX_DEVICE;
+ }
+#endif
+ return(adapterObject);
+}
+
+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;
+ ULONG Ponce;
+ PTRANSLATION_ENTRY PageTableEntry;
+ ULONG i;
+ ULONG NodeMask;
+
+ ULONG tst; //SNES
+ //
+ // 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 );
+ // R98B
+ // Reserv 0 - (1M-1) Logical addr!!.
+ //
+ RtlSetBits (
+ AdapterObject->MapRegisters,
+ 0x0, // Start 0
+ 0x100 // 256 is 1M
+ );
+ // R98B
+ // Reserv 15M - (16M-1) Logical addr!!.
+ //
+ //RtlSetBits (
+ // AdapterObject->MapRegisters,
+ // 0xF00, // Start 15M
+ // 0x100 // END 16M-1
+ //);
+
+ // R98B
+ // Reserv Last 1 Logical addr!!. For PCEB Prefetch Cycle.
+ //
+ RtlSetBits (
+ AdapterObject->MapRegisters,
+ DMA_TRANSLATION_LIMIT/(sizeof(TRANSLATION_ENTRY))-1, // Last 1 page.
+ 0x1 // 1 page Reserved.
+ );
+
+ //
+ // 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.
+ // R98B Page Table must be Cached!!.
+ //
+ AdapterObject->MapRegisterBase = (PVOID)
+ (HalpMapRegisterPhysicalBase | KSEG0_BASE);
+
+ //
+ // N.B This Version Selected
+ // PCEB Prefetch cycle may be Cause TLB refill!!.
+ // So Set Valid Bit All Entry.as We could't invalid transfer.
+ // ~~~~~~~~~~~~~~~~~
+ // Another aprouch.
+ // When Request Mapregster at "NumberOfMapregister"
+ // reserve NumberOfMapregster+1.This one page for PCEB Prefetch
+ // cycle. Driver unknown plus 1 page. Hal know only.
+ //
+ PageTableEntry= (PTRANSLATION_ENTRY)AdapterObject->MapRegisterBase;
+
+ for(i=0;i< DMA_TRANSLATION_LIMIT/ sizeof( TRANSLATION_ENTRY); i++){
+ (PageTableEntry)->PageFrame = (ULONG) PAGE_TABLE_ENTRY_VALID;
+ (PageTableEntry)->Fill = (ULONG) 0;
+ PageTableEntry++;
+ }
+#if defined(DBG5)
+ DbgPrint("HAL Channel init Master\n");
+ DbgPrint("HAL Page Table is 0x%x\n",AdapterObject->MapRegisterBase);
+#endif
+
+ for(Ponce=0;Ponce < HalpNumberOfPonce; Ponce++){
+ //
+ // I/O TLB Page Table Base Set.
+ //
+#if defined(DBG5)
+ DbgPrint("HAL:Ponce No = 0x%x PTBSR addr =0x%x\n",Ponce,(PULONG)&PONCE_CNTL(Ponce)->PTBSR);
+#endif
+
+ WRITE_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->PTBSR,
+ (HalpMapRegisterPhysicalBase) >> 1 //SNES
+ );
+#if defined(DBG5)
+ DbgPrint("HAL:Ponce No = 0x%x PTLMR addr =0x%x\n",Ponce,(PULONG)&PONCE_CNTL(Ponce)->PTLMR);
+
+ tst=READ_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->PMODR,
+ );
+
+ DbgPrint("HAL:Ponce No = 0x%x PMODR data =0x%x\n",Ponce,tst);
+ tst |= 0x10000000;
+
+ //
+ // I/O TLB Page Table Limit
+ //
+ WRITE_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->PMODR,
+ tst
+ );
+#endif
+
+ //
+ // I/O TLB Page Table Limit
+ //
+ WRITE_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->PTLMR,
+ ((HalpMapRegisterPhysicalBase+MapRegisterSize)) >>1
+ );
+#if defined(DBG5)
+ DbgPrint("HAL:Ponce No = 0x%x TFLSR addr =0x%x\n",Ponce,(PULONG)&PONCE_CNTL(Ponce)->TFLSR);
+#endif
+
+ //
+ // I/O TLB Entry All Flush!!
+ //
+ WRITE_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->TFLSR,
+ 0x1
+ );
+ //
+ // Enable I/O TLB error.
+ //
+ NodeMask = 0;
+ for(i=0; i < **((PULONG *)(&KeNumberProcessors)); i++){
+ NodeMask |= 0x10 << HalpLogicalCPU2PhysicalCPU[i];
+ }
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(0)->ERITTG[1], NodeMask );
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(1)->ERITTG[1], NodeMask );
+ }
+ }
+ } 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;
+
+
+
+ //
+ // 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.
+ //
+ // R98B mapregiser allways allocated 1M.
+ // 0-1M reserved hal.
+ //
+
+ MapRegisterNumber = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ NumberOfMapRegisters,
+ 0x100000 / PAGE_SIZE
+ );
+
+ //
+ // Make sure this map register is valid for this adapter.
+ // No Check. Because 0-1M was never free.
+
+ 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;
+
+
+ //
+ // 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)) {
+
+ MapRegisterNumber = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ Wcb->NumberOfMapRegisters,
+ 0x100000 / PAGE_SIZE
+ );
+
+ //
+ // Make sure this map register is valid for this adapter.
+ // R98B No Check!!. 0-1M Never free!!
+ //
+
+ }
+
+ 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.
+
+--*/
+
+{
+
+ // This code is executed phase 1 on processor 0
+ //
+ // 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).
+ //
+
+ 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;
+ ULONG Ponce;
+ //
+ // Begin by determining where in the buffer this portion of the operation
+ // is taking place.
+ //
+
+ 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);
+
+ // S001 vvv
+ // Set the offset to point to the map register plus the offset.
+ //
+
+ Offset += ((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
+
+ if ( Offset + *Length >= HalpLogicalAddressLimit ){
+ UCHAR messageBuffer[256];
+
+ HalpChangePanicFlag( 16, 0x01, 0x10);
+
+ HalDisplayString("\nHAL I/O TLB SETUP: Logical address limit over.\n");
+
+ sprintf( (char *)messageBuffer, " Offst=0x%08lx, Len =0x%08lx, Limit=0x%08lx\n",
+ Offset, *Length, HalpLogicalAddressLimit );
+ HalDisplayString( (char *)messageBuffer );
+
+ sprintf( (char *)messageBuffer, " CurVa=0x%08lx, StrVa=0x%08lx, RegBs=0x%08lx, MsrBs=0x%08lx\n",
+ (ULONG)CurrentVa, (ULONG)Mdl->StartVa, (ULONG)MapRegisterBase, (ULONG)MasterAdapterObject->MapRegisterBase);
+ HalDisplayString( (char *)messageBuffer );
+
+ sprintf( (char *)messageBuffer, " AdObj=0x%08lx, Mdl =0x%08lx, Write=%d\n",
+ (ULONG)AdapterObject, (ULONG)Mdl, (ULONG)WriteToDevice );
+ HalDisplayString( (char *)messageBuffer );
+
+ KeBugCheckEx(NMI_HARDWARE_FAILURE,
+ Offset,
+ *Length,
+ HalpLogicalAddressLimit,
+ 0
+ );
+ }
+
+ //
+ // Setup I/O TLB entry.
+ //
+
+ for (i = 0; i < NumberOfPages; i++) {
+ (DmaMapRegister++)->PageFrame = (ULONG) (*PageFrameNumber++ << PAGE_SHIFT)
+ | PAGE_TABLE_ENTRY_VALID;
+ } // S001 ^^^
+#if 0
+ for(Ponce = 0;Ponce < HalpNumberOfPonce;Ponce++){
+ //
+ // I/O TLB Entry All Flush!!
+ //
+ WRITE_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->TFLSR,
+ 0x1
+ );
+ }
+
+#else
+ //
+ // Invalidate the translation entry.
+ //
+ if(NumberOfPages >= PONCE_MAX_IOTLB_ENTRY){
+
+ for(Ponce = 0;Ponce < HalpNumberOfPonce;Ponce++){
+ //
+ // I/O TLB Entry All Flush!!
+ //
+ WRITE_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->TFLSR,
+ 0x1
+ );
+ }
+ } else {
+
+ for (i = 0; i < NumberOfPages; i++) {
+
+ //
+ // I/O TLB Entry Flush!!
+ //
+ for(Ponce = 0;Ponce <HalpNumberOfPonce;Ponce++){
+ WRITE_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->TFLSR,
+ (Offset + i*PAGE_SIZE) & 0xFFFFF000 );
+ }
+ }
+ }
+#endif
+ //
+ // Are You BusMaster?. So Nothing to do anymore!!.
+ //
+ if ( AdapterObject == NULL) {
+ return(RtlConvertUlongToLargeInteger(Offset));
+ }
+ // R98B
+ // Start the EISA DMA controller program.
+ // EISA DMA slave or ISA BusMaster or ISA Slave
+
+ 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;
+
+ if (AdapterObject == NULL) {
+
+ //
+ // This is a master adadapter so there is nothing to do.
+ //
+
+ return(TRUE);
+ }
+
+
+ //
+ // 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)
+ );
+
+ }
+
+ 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);
+}
+
+
+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 count;
+ ULONG high;
+ KIRQL Irql;
+
+ KeAcquireSpinLock( &AdapterObject->MasterAdapter->SpinLock, &Irql );
+ //
+ // 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));
+
+ }
+ KeReleaseSpinLock( &AdapterObject->MasterAdapter->SpinLock, Irql );
+
+ //
+ // The DMA counter has a bias of one and can only be 16 bit long.
+ //
+
+ count = (count + 1) & 0xFFFF;
+
+ return(count);
+}
+
+
+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;
+
+ // S001 vvv
+ HalpLogicalAddressLimit = (DMA_TRANSLATION_LIMIT / sizeof(TRANSLATION_ENTRY)) << PAGE_SHIFT;
+#if DBG
+ DbgPrint("HAL: HalpLogicalAddressLimit = 0x%x\n",HalpLogicalAddressLimit);
+#endif
+ // S001 ^^^
+}
diff --git a/private/ntos/nthals/halr98b/mips/rxinfo.c b/private/ntos/nthals/halr98b/mips/rxinfo.c
new file mode 100644
index 000000000..2d616d754
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxinfo.c
@@ -0,0 +1,95 @@
+/*++
+
+Copyright (C) 1991-1995 Microsoft Corporation
+All rights reserved.
+
+Module Name:
+
+ rxinfo.c
+
+Abstract:
+
+Environment:
+
+ Kernel mode only.
+
+Revision History
+
+--*/
+
+
+#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/halr98b/mips/rxint.s b/private/ntos/nthals/halr98b/mips/rxint.s
new file mode 100644
index 000000000..e2604fc68
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxint.s
@@ -0,0 +1,1564 @@
+//
+// TITLE("Interrupts service routine")
+//++
+//
+// Copyright (c) 1994 Kobe NEC Software
+//
+// Module Name:
+//
+// rxint.s
+//
+// Abstract:
+//
+//
+// Author:
+//
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+//
+//--
+
+#include "halmips.h"
+#include "r98bdef.h"
+
+
+
+ SBTTL("HalpNmiHandler")
+//++
+// K001
+// Routine Description:
+//
+// This routine is reset status Register on NMI.
+// Return from this function EIF Interrupt Occur!!
+// Argments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpNmiHandler)
+ .set noat
+ .set noreorder //
+
+ //
+ // reset NMIR register, set NMI flag and save CPU register.
+ //
+
+ li k0,0xb9800388 // Set Colombs STSR local address
+ li k1,0x08080000 // Disable NMI
+ sw k1,0x0(k0) // store value
+ la k0,HalpSvpAlive // SVP check
+ lw k1,0x0(k0)
+ nop
+ beq k1,zero,10f
+ nop
+ la k0,HalpLogLock
+3: ll k1,0(k0) // get current lock value
+ bne zero,k1,3b // if ne, spin lock owned
+ nop
+ li k1,0x1
+ sc k1,0(k0) // set spin lock owned
+ beq zero,k1,3b // if eq, store conditional failure
+ nop
+ la k0,HalpSvpGlobal // NMI clear
+ lw k1,0x0(k0)
+ li k0,0x80
+ sb k0,0x42(k1)
+ sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ la k0,HalpSvpWindow2 // Nmi para clear
+ lw k1,0x0(k0)
+ lb k0,0xe6(k1)
+ sync
+ la k0,HalpSvpGlobal //Svp EIF MASK
+ lw k1,0x0(k0)
+ sb zero,0x49(k1)
+ sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ lb k0,0x58(k1) // Windows2 write lock
+ la k1,HalpNmiSvp
+ sw k0,0x0(k1)
+ sync
+ la k0,HalpSvpGlobal
+ lw k1,0x0(k0)
+ li k0,0xff
+ sb k0,0x58(k1)
+ sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ la k0,HalpSvpWindow2 // Nmi para clear
+ lw k1,0x0(k0)
+4:
+ sb zero,0xe6(k1)
+ sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ lb k0,0xe6(k1)
+ bne zero,k0,4b
+ nop
+ la k0,HalpNmiSvp // Svp Window2 lock
+ lw k1,0x0(k0)
+ la k0,HalpSvpGlobal
+ lw k0,0x0(k0)
+ nop
+ sb k1,0x58(k0)
+ sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ la k0,HalpLogLock // ZERO CLEAR
+ sw zero,0x0(k0)
+ nop
+
+// spinlock
+// lw t0,KiPcr + PcCurrentThread(zero) // get address of current thread
+#if 0
+ la k0,HalpLogLock
+5: ll k1,0(k0) // get current lock value
+ bne zero,k1,5b // if ne, spin lock owned
+ nop
+ li k1,0x1
+ sc k1,0(k0) // set spin lock owned
+ beq zero,k1,5b // if eq, store conditional failure
+ nop
+#endif
+
+//
+// Check it DUMP Key or Power SW
+// To Checked Interrupt cause SetUp MRCMODE to PowerSW Interrupt mode.
+//
+
+10:
+ li k0, 0xbf0f0000 //LBCTL addr
+ lb k0, (k0)
+ li k1, 0x40
+ and k1,k0,k1
+ bne zero,k1,10b
+ nop
+//
+// Local Device Lock Complete
+//
+#if 1 //SVP
+//
+// when EXTNMI happend. which NMI DUMP Key or SVP
+//
+ li k0, 0xbf0f0018 //LBADH addr
+ li k1, 0x02 //MRCMODE Hi
+ sb k1, (k0)
+
+ li k0, 0xbf0f0010 //LBADL addr
+ li k1, 0x08 //MRCMODE li
+ sb k1, (k0)
+
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x18 //Read Command
+ sb k1, (k0)
+
+
+99:
+ li k0, 0xbf0f0000 //LBCTL addr
+ lb k1, (k0) //LBCTL read
+ li k0, 0x10 //CMD Bit
+ and k1,k0,k1
+ bne zero,k1, 99b
+ nop
+
+ li k0, 0xbf0f0020 //LBDT addr
+ lb k0, (k0) //Read MRMODE Register Value
+
+
+ li k1,0x2 //MRCMODE register DUMP Bit
+ and k1,k0,k1
+ bne zero,k1,Dump // if neq --> dump key
+ nop
+ nop
+
+
+// Save CPU Register Context
+//
+//
+#if 0
+ li k0,0xb9800310 // get Colombs REVR Local Address
+ lw k0 ,0x0(k0) // get value
+
+ li k1,0x03000000 // NODE Bit Mask. But low 2 bit only
+ and k0,k0,k1 // Get NODE Bit Only
+ srl k0,k0,17 // shift right 17(23 - 6) bit for offset
+
+ la k1,HalpNmiSvp // get performance counter address
+ addu k0,k0,k1 // compute address of nmi buffer
+ lw k1,0x0(k0)
+ addi k1,k1,1
+ sw k1,0x0(k0)
+ nop
+ nop
+//#endif
+ la k0,HalpSvpAlive // SVP check
+ lw k1,0x0(k0)
+ nop
+ beq k1,zero,5f
+ nop
+ la k0,HalpLogLock
+3: ll k1,0(k0) // get current lock value
+ bne zero,k1,3b // if ne, spin lock owned
+ nop
+ li k1,0x1
+ sc k1,0(k0) // set spin lock owned
+ beq zero,k1,3b // if eq, store conditional failure
+ nop
+ la k0,HalpSvpGlobal //Svp Windows2 lock
+ lb k1,0x58(k0)
+ la k0,HalpNmiSvp
+ sb k1,0x0(k0)
+ sync
+ la k0,HalpSvpGlobal
+ li k1,0xff
+ sb k1,0x58(k0)
+ sync
+ la k0,HalpSvpWindow2 // Nmi para clear
+ lb k1,0xe6(k1)
+ sb zero,0xe6(k0)
+ sync
+ la k0,HalpNmiSvp // Svp Window2 lock
+ lb k1,0x0(k0)
+ la k0,HalpSvpGlobal
+ sb k1,0x58(k0)
+ sync
+ la k0,HalpLogLock // ZERO CLEAR
+ sw zero,0x0(k0)
+ nop
+#endif
+ j 25f
+ nop
+
+
+
+Dump:
+#endif
+ la k0,HalpDumpFlag
+ li k1,0x01
+ sw k1,0x0(k0)
+
+
+
+ li k0, 0xbf0f0018 //LBADH addr
+ li k1, 0x02 //MRCMODE Addr Hi
+ sb k1, (k0)
+
+ li k0, 0xbf0f0010 //LBADL addr
+ li k1, 0x08 //MRCMODE Addr li
+ sb k1, (k0)
+
+ li k0, 0xbf0f0020 //LBDT addr
+ li k1, 0x80 //
+ sb k1, (k0) //
+
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x10 //Write Command
+ sb k1, (k0)
+
+20:
+ li k0, 0xbf0f0000 //LBCTL addr
+ lb k1, (k0) //LBCTL read
+ li k0, 0x10 //CMD Bit
+ and k1,k0,k1
+ bne zero,k1, 20b
+ nop
+25:
+
+//
+// MRCMODE Setuped to MRCINT mode.
+// So Check DUMP Key or Power Switch
+
+ li k0, 0xbf0f0018 //LBADH addr
+ li k1, 0x02 //MRCINT Hi
+ sb k1, (k0)
+
+ li k0, 0xbf0f0010 //LBADL addr
+ li k1, 0x00 //MRCINT li
+ sb k1, (k0)
+
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x18 //Read Command
+ sb k1, (k0)
+
+
+50:
+ li k0, 0xbf0f0000 //LBCTL addr
+ lb k1, (k0) //LBCTL read
+ li k0, 0x10 //CMD Bit
+ and k1,k0,k1
+ bne zero,k1, 50b
+ nop
+
+
+ li k0, 0xbf0f0020 //LBDT addr
+ lb k0, (k0) //Read MRCINT Register Value
+
+ li k1,0x4 //MRCINT register OFFSW Bit
+ and k1,k0,k1
+ beq zero,k1,DumpKey // if eq --> Not Power SW. it is DUMP Key.
+ nop
+ nop
+
+
+#if DBG
+
+
+ li k0,0xb9800310 // get Colombs REVR Local Address
+ lw k1 ,0x0(k0) // get value
+ li k0,0x03000000 // NODE Bit Mask. But low 2 bit only
+
+ and k0,k0,k1 // Get NODE Bit Only
+ srl k1,k0,22 // shift right 24>> <<2 bit for offset
+
+ la k0,HalpResetCount // get address
+ addu k0,k0,k1 // compute address of nmihappend buffer
+ lw k1,0x0(k0)
+ addi k1,k1,1
+ sw k1,0x0(k0)
+ nop
+#endif
+
+
+//
+// This Is Power Switch NMI so Power down.
+//
+
+resetloop:
+
+
+ li k0, 0xbf0f0018 //LBADH addr
+ li k1, 0x02 //Power S/W Hi
+ sb k1, (k0)
+
+ li k0, 0xbf0f0010 //LBADL addr
+ li k1, 0x30 //Power S/W li
+ sb k1, (k0)
+
+ li k0, 0xbf0f0020 //LBDT addr
+ li k1, 0x01 //Set Power SW OFF
+ sb k1, (k0)
+
+
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x10 //Write Command
+ sb k1, (k0)
+
+
+poll6:
+ li k0, 0xbf0f0000 //LBCTL addr
+ lb k1, (k0) //LBCTL read
+ li k0, 0x10 //CMD Bit
+ and k1,k0,k1
+ bne zero,k1, poll6
+ nop
+
+ j resetloop
+ nop
+ nop
+
+//
+// This Is DUMP KEY NMI
+//
+DumpKey:
+
+
+//
+// Early time I was crashed ?
+//
+ li k0,0xb9800310 // get Colombs REVR Local Address
+ lw k1 ,0x0(k0) // get value
+ li k0,0x03000000 // NODE Bit Mask. But low 2 bit only
+
+ and k0,k0,k1 // Get NODE Bit Only
+ srl k1,k0,22 // shift right 24>> <<2 bit for offset
+
+ la k0,HalpNMIHappend // get address
+ addu k0,k0,k1 // compute address of nmihappend buffer
+ lw k1,0x0(k0)
+ nop
+ nop
+
+ beq zero,k1,doeif //if eq it was first time dump key.
+ nop
+ nop
+
+ //
+ // Setup DUMP Key And Power Key to NMI
+ //
+ li k0, 0xbf0f0018 //LBADH addr
+ li k1, 0x02 //MRCMODE Hi
+ sb k1, (k0)
+
+ li k0, 0xbf0f0010 //LBADL addr
+ li k1, 0x08 //MRCMODE li
+ sb k1, (k0)
+
+ li k0, 0xbf0f0020 //LBDT addr
+ li k1, 0x0 //DUMP KEY Reset.
+ sb k1, (k0) //
+
+
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x10 //Write Command
+ sb k1, (k0)
+
+34:
+ li k0, 0xbf0f0000 //LBCTL addr
+ lb k1, (k0) //LBCTL read
+ li k0, 0x10 //CMD Bit
+ and k1,k0,k1
+ bne zero,k1, 34b
+ nop
+
+
+
+#if DBG
+
+ li k0,0xb9800310 // get Colombs REVR Local Address
+ lw k1 ,0x0(k0) // get value
+ li k0,0x03000000 // NODE Bit Mask. But low 2 bit only
+
+ and k0,k0,k1 // Get NODE Bit Only
+ srl k1,k0,22 // shift right 24>> <<2 bit for offset
+
+ la k0,HalpNMISecond // get address
+ addu k0,k0,k1 // compute address of nmihappend buffer
+ lw k1,0x0(k0)
+ addi k1,k1,1
+ sw k1,0x0(k0)
+
+#endif
+
+
+nomakeeif:
+ //
+ // UnLock
+ //
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x80 //
+ sb k1, (k0)
+ nop
+ nop
+
+ // CHIPSet Reset
+ // This version implement of EXNMI Only.
+ //
+ //
+
+ li k0,0xb9800038 // get Colombs NMIRST Local Address
+ li k1,0xf // Bit Reset
+ sw k1,(k0) // reset nmi
+
+
+ li k0,0xb9800388 // Set Colombs STSR local address
+ li k1,0x00080000 // Enable NMI
+ sw k1,0x0(k0) // store value
+ nop
+
+ // CPU Reset.
+ // This is a test code.
+ // We must clear BEV bit of psr register.
+ //
+
+ mfc0 k1,psr // get psr
+ li k0,0xffbfffff // clear BEV bit
+ nop // fill
+ nop // fill
+ and k1,k1,k0 //
+ nop //
+ nop //
+ mtc0 k1,psr // set psr
+ nop // fill
+ nop //
+ nop //
+ nop
+ eret // return to errorepc
+ nop
+ nop
+ nop
+ eret // errata
+ nop
+
+
+// This Is First NMI By DUMP Key.
+// Save CPU Context. And Markd.
+// And Make EIF!!
+//
+doeif:
+ addi k1, k1, 0x1 // mark set.
+ nop
+ sw k1, 0x0(k0) // HalpNMIHappend[NODE] = 1
+ nop
+
+ //
+ // MRCMODE Register Set Up For Next NMI (DumpKey and PoeHwerSW)
+ //
+#if 0
+
+
+ //
+ // MRCINT Clear
+ //
+ nop
+ li k0, 0xbf0f0018 //LBADH addr
+ li k1, 0x02 //MRCINT Hi
+ sb k1, (k0)
+
+ li k0, 0xbf0f0010 //LBADL addr
+ li k1, 0x00 //MRCINT li
+ sb k1, (k0)
+
+ li k0, 0xbf0f0020 //LBDT addr
+ li k1, 0x0 //Reset PowerOff Interrupt
+ sb k1, (k0)
+
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x10 //Write Command
+ sb k1, (k0)
+
+
+250:
+ li k0, 0xbf0f0000 //LBCTL addr
+ lb k1, (k0) //LBCTL read
+ li k0, 0x10 //CMD Bit
+ and k1,k0,k1
+ bne zero,k1, 250b
+ nop
+
+#endif
+
+
+ //
+ // Reset NMI
+ //
+ li k0, 0xbf0f0018 //LBADH addr
+ li k1, 0x02 //MRCMODE Hi
+ sb k1, (k0)
+
+ li k0, 0xbf0f0010 //LBADL addr
+ li k1, 0x08 //MRCMODE li
+ sb k1, (k0)
+
+ li k0, 0xbf0f0020 //LBDT addr
+ li k1, 0x0 //DUMP KEY Reset.
+ sb k1, (k0) //
+
+
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x10 //Write Command
+ sb k1, (k0)
+
+64:
+ li k0, 0xbf0f0000 //LBCTL addr
+ lb k1, (k0) //LBCTL read
+ li k0, 0x10 //CMD Bit
+ and k1,k0,k1
+ bne zero,k1, 64b
+ nop
+
+
+
+#if 0
+
+ //
+ // SetUp NMIFlag for rxeif.c
+ //
+ la k0,HalpNMIFlag // set NMI flag address
+ li k1,0xb9800030 // set Colombs NMIR local address
+ lw k1,(k1) // get NMIR register value
+ //
+ // N.B NMIR register high 16 bit is RFU.
+ // so used s/w flag for Hal.
+ sw k1,(k0) // store NMIR regiser value to HalpNmiFlag
+
+
+
+//
+// UnLock Local Device
+//
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x80 //
+ sb k1, (k0)
+
+#endif
+
+
+// Save CPU Register Context
+//
+//
+ li k0,0xb9800310 // get Colombs REVR Local Address
+ lw k0 ,0x0(k0) // get value
+
+ li k1,0x03000000 // NODE Bit Mask. But low 2 bit only
+ and k0,k0,k1 // Get NODE Bit Only
+ srl k0,k0,16 // shift right 16(23 - 5) bit for offset
+
+ la k1,HalpNMIBuf // get performance counter address
+ addu k0,k0,k1 // compute address of nmi buffer
+
+// sw at,0x0(k0) // register save.0
+ sw v0,0x4(k0) // 1
+ sw v1,0x8(k0) // 2
+ sw a0,0xc(k0) // 3
+ sw a1,0x10(k0) // 4
+ sw a2,0x14(k0) // 5
+ sw a3,0x18(k0) // 6
+ sw t0,0x1c(k0) // 7
+ sw t1,0x20(k0) // 8
+ sw t2,0x24(k0) // 9
+ sw t3,0x28(k0) // 10
+ sw t4,0x2c(k0) // 11
+ sw t5,0x30(k0) // 12
+ sw t6,0x34(k0) // 13
+ sw t7,0x38(k0) // 14
+ sw t8,0x3c(k0) // 15
+ sw t9,0x40(k0) // 16
+ sw gp,0x44(k0) // 17
+ sw sp,0x48(k0) // 18
+ sw s8,0x4c(k0) // 19
+ sw ra,0x50(k0) // 20
+
+ mfc0 k1,psr // 21
+ sw k1,0x54(k0) //
+ mfc0 k1,cause // 22
+ sw k1,0x58(k0) //
+ mfc0 k1,epc // 23
+ sw k1,0x5c(k0) //
+ mfc0 k1,errorepc // 24
+ sw k1,0x60(k0) //
+
+
+
+#if 1 //ras
+
+ sw s0,0x64(k0) // 25
+ sw s1,0x68(k0) // 26
+ sw s2,0x6c(k0) // 27
+ sw s3,0x70(k0) // 28
+ sw s4,0x74(k0) // 29
+ sw s5,0x78(k0) // 30
+ sw s6,0x7c(k0) // 31
+ sw s7,0x80(k0) // 32
+
+ mfc0 k1,entrylo0 //
+ sw k1,0x84(k0) // 33
+
+ mfc0 k1,entrylo1 //
+ sw k1,0x88(k0) // 34
+
+ mfc0 k1,badvaddr //
+ sw k1,0x8c(k0) // 35
+
+ mfc0 k1,entryhi
+ sw k1,0x90(k0) // 36
+
+
+ mfc0 k1,pagemask
+ sw k1,0x94(k0) // 37
+
+ mfc0 k1,prid
+ sw k1,0x98(k0) // 38
+
+ mfc0 k1,config
+ sw k1,0x9c(k0) // 39
+
+ mfc0 k1,lladdr
+ sw k1,0xa0(k0) // 40
+
+ mfc0 k1,watchlo
+ sw k1,0xa4(k0) // 41
+
+ mfc0 k1,watchhi
+ sw k1,0xa8(k0) // 42
+
+ mfc0 k1,$20 //xcontext
+ sw k1,0xac(k0) // 43
+
+ mfc0 k1,ecc
+ sw k1,0xb0(k0) // 44
+
+ mfc0 k1,cacheerr
+ sw k1,0xb4(k0) // 45
+
+ mfc0 k1,taglo
+ sw k1,0xb8(k0) // 46
+
+ mfc0 k1,taghi
+ sw k1,0xbc(k0) // 47
+
+#endif
+
+#if 0
+//
+// Copy CPU state to NvRAM.
+//
+
+ li t0,0xb9800388 // Set Colombs STSR local address
+ li t1,0x00040000 // Enable write to NvRam
+ sw t1,0x0(t0) // store value
+
+ li t0,0xb9800310 // get Colombs REVR Local Address
+ lw t0,0x0(t0) // get value
+
+ li t1,0x03000000 // NODE Bit Mask. But low 2 bit only
+ and t0,t0,t1 // Get NODE Bit Only
+ srl t0,t0,16 // shift right 16(23 - 5) bit for offset
+
+ li t1,0xbf09dc00
+ addu t0,t0,t1 // compute address of nmi buffer
+ move t1,k0 // src address
+ li t2,0x100 // calc end address
+ addu t2,t2,t0
+
+cploop:
+ lb t3,0(t1)
+ addiu t1,t1,1
+ sb t3,0(t0)
+ addiu t0,t0,1
+ bne t2,t0,cploop
+ nop
+
+ lw t0,0x1c(k0) // 7
+ lw t1,0x20(k0) // 8
+ lw t2,0x24(k0) // 9
+ lw t3,0x28(k0) // 10
+#endif
+
+#if 1
+ //
+ // SetUp NMIFlag for rxeif.c
+ //
+ la k0,HalpNMIFlag // set NMI flag address
+ lw k1,(k0) // get HalpNmiFlag
+ bne zero,k1, nomakeeif
+ nop
+
+ li k1,0xb9800030 // set Colombs NMIR local address
+ lw k1,(k1) // get NMIR register value
+ //
+ // N.B NMIR register high 16 bit is RFU.
+ // so used s/w flag for Hal.
+ sw k1,(k0) // store NMIR regiser value to HalpNmiFlag
+
+#endif
+
+ //
+ // UnLock
+ //
+ li k0, 0xbf0f0000 //LBCTL addr
+ li k1, 0x80 //
+ sb k1, (k0)
+
+ // CHIPSet Reset
+ // This version implement of EXNMI Only.
+ //
+ //
+
+ li k0,0xb9800038 // get Colombs NMIRST Local Address
+ li k1,0xf // Bit Reset
+ sw k1,(k0) // reset nmi
+
+
+ li k0,0xb9800388 // Set Colombs STSR local address
+ li k1,0x00080000 // Enable NMI
+ sw k1,0x0(k0) // store value
+ nop
+
+
+ // CPU Reset.
+ // This is a test code.
+ // We must clear BEV bit of psr register.
+ //
+
+ mfc0 k1,psr // get psr
+ li k0,0xffbfffff // clear BEV bit
+ nop // fill
+ nop // fill
+ and k1,k1,k0 //
+ nop //
+ nop //
+ mtc0 k1,psr // set psr
+ nop // fill
+ nop //
+ nop //
+
+ //
+ // Do EIF to Myself.
+ //
+ //
+
+
+ li k0,0xb9800310 // get Colombs REVR Local Address
+ lw k0 ,0x0(k0) // get value
+
+ li k1,0x03000000 // NODE Bit Mask. node 4-7
+ and k0,k0,k1 // Get NODE Bit Only (lower 3 Bit Only)
+ srl k0,k0,24 // Convert CPU number
+
+ li k1,0x00080000 // Node 4 set
+ srl k1,k1,k0 // make Node Bit (NODE 4 >> CpuNumber)
+
+
+ li k0,0x82000000 // OP bit And Atlantic code 0x2 = EIF
+ or k1,k1,k0 // make OP Bit And CODE And NODE
+
+
+ li k0,0xb9800580 // get Colombs IntIR Local Address
+ sw k1,(k0) //
+
+ nop
+ nop
+ eret // return to errorepc
+ nop
+ nop
+ nop
+ eret // errata
+ nop
+ nop // for interrupt cache aligned line
+ nop
+ nop
+ nop
+ nop
+ .set at
+ .set reorder
+
+
+ .end HalpNmiHandler
+
+
+
+
+ SBTTL("Int 1 Interrupt")
+//++
+//
+// Routine Description:
+//
+// This routine is enterd as the result of an Int 1 interrupt.
+//
+// Argments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpInt1Dispatch)
+
+ move a0,s8 // trap frame
+ li a1,0x1 // Interrupt is INT1
+ j HalpGeneralDispatch
+
+ .end
+
+ SBTTL("Int 2 Interrupt")
+//++
+//
+// Routine Description:
+//
+// This routine is enterd as the result of an Int 2 interrupt.
+//
+// Argments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpInt2Dispatch)
+
+ move a0,s8 // trap frame
+ li a1,0x2 // Interrupt is INT2
+ j HalpGeneralDispatch
+
+ .end
+
+ SBTTL("Int 3 Interrupt")
+//++
+//
+// Routine Description:
+//
+// This routine is enterd as the result of an Int 3 interrupt.
+//
+// Argments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpInt3Dispatch)
+
+ move a0,s8 // trap frame
+ li a1,0x3 // Interrupt is INT3
+ j HalpGeneralDispatch
+
+ .end
+
+ SBTTL("Int 4 Interrupt")
+//++
+//
+// Routine Description:
+//
+// This routine is enterd as the result of an Int 4 interrupt.
+//
+// This routine checks for IPI interrupt. The IPI interrupt is
+// ip[5] on the R98B and ip[6] on the R98A. So this routine
+// reads the cause register to determine correct dispatch function
+//
+// CAVEAT: This is an R98B specific routine. It is only
+// called on an R98B.
+// CAVEAT: This routine is only used on NT 4.0 because Nt3.51 does
+// not have SYNC IRQL
+// Argments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+#if defined(NT_40)
+
+//
+// SYNCH Level must enable IPI on R98B.
+// Sync level enable IPI on R98A .
+// But on R98B, Sync level disable IPI.
+// So, on R98B, we need to change Irql mask table.
+// Hal determines IPI or EIF here.
+// Because when IPI occured, HAl returns same IRQL value from EIF.
+// v-masank@microsoft.com 5/11/96
+// Thanks for samejima's comments
+// I change that following function is for R98B only.
+// Because R98A does not need following function.
+// v-masank@microsoft.com 5/21/96
+//
+ LEAF_ENTRY(HalpT5Int4Dispatch)
+
+ move a0,s8 // trap frame
+ READ_CAUSE_REGISTER(t0) // Read Cause register
+ and t0,t0,0x00004000 // INT4 ?
+ bne t0,zero,10f // ne INT4
+ li a1,0x3 // INT3
+ j HalpGeneralDispatch
+
+10:
+ li a1,0x4 // Interrupt is INT4
+ j HalpGeneralDispatch
+ .end
+#endif
+
+
+
+//++
+//
+// Routine Description:
+//
+// This routine is enterd as the result of an Int 4 interrupt.
+//
+// CAVEAT: This routine used by R98A on NT 3.51 and NT4.0
+// This routine used by R98B on NT 3.51
+//
+// CAVEAT: This routine is only used on NT 3.51 because Nt3.51 does
+// not have SYNC IRQL
+// Argments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpInt4Dispatch)
+
+ move a0,s8 // trap frame
+ li a1,0x4 // Interrupt is INT4
+ j HalpGeneralDispatch
+
+ .end
+
+ SBTTL("Read Cause Register")
+//++
+// S005
+// Routine Description:
+//
+// This routine is get of cause register
+//
+// Argments:
+//
+// None.
+//
+// Return Value:
+//
+// cause rezister value.
+//
+//--
+
+ LEAF_ENTRY(HalpGetCause)
+
+ READ_CAUSE_REGISTER(v0)
+
+ j ra // return
+
+ .end HalpGetCause
+
+
+
+ SBTTL("Int 0 Interrupt")
+//++
+//
+// Routine Description:
+//
+// This routine is enterd as the result of an Int 1 interrupt.
+//
+// Argments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpInt0Dispatch)
+
+ move a0,s8 // trap frame
+ li a1,0x0 // Interrupt is INT0
+ j HalpGeneralDispatch
+
+ .end
+
+
+
+ SBTTL("Int 5 Interrupt")
+//++
+//
+// Routine Description:
+//
+// This routine is enterd as the result of an Int 1 interrupt.
+//
+// Argments:
+//
+// s8 - Supplies a pointer to a trap frame.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpInt5Dispatch)
+
+ move a0,s8 // trap frame
+ li a1,0x5 // Interrupt is INT5
+ j HalpGeneralDispatch
+
+ .end
+
+
+//#if 0
+// I use following function for performance.
+// v-masank@microsoft.com 5/21/96
+//++
+ SBTTL("Read Large Register")
+//
+// Routine Description:
+//
+// This routine is read of large register
+//
+// Argments:
+//
+// a0 - Virtual address
+//
+// a1 - pointer to buffer of large register
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpReadLargeRegister)
+#if !defined(NT_40)
+ lw t2,0x0(a0) // get register(upper)
+ lw t3,0x4(a0) // get register(lower)
+
+ sw t2,0x0(a1) // set upper register value
+ sw t3,0x4(a1) // set lower register value
+#else
+ ld t2,0x0(a0) // get register
+ sd t2,0x0(a1) // set register
+#endif
+
+ j ra // return
+
+ .end HalpReadLargeRegister
+
+
+
+ SBTTL("Write Large Register")
+//++
+//
+// Routine Description:
+//
+// This routine is write of large register
+//
+// Argments:
+//
+// a0 - Virtual address
+//
+// a1 - pointer to value of large register
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpWriteLargeRegister)
+
+#if !defined(NT_40)
+
+ lw t2,0x0(a1) // load register value
+ lw t3,0x4(a1) //
+
+ sw t2,0x0(a0) // set register value
+ sw t3,0x4(a0) //
+#else
+ ld t2,0x0(a1)
+ sd t2,0x0(a0)
+#endif
+
+ sync //
+
+ j ra // return
+
+ .end HalpWriteLargeRegister
+
+
+//#endif
+
+// S005 vvv
+ SBTTL("Read Physical Address")
+//++
+//
+// Routine Description:
+//
+// This routine is read of physical address.
+//
+// Argments:
+//
+// a0 - Physical address
+//
+// Return Value:
+//
+// read data.
+//
+//--
+
+ LEAF_ENTRY(HalpReadPhysicalAddr)
+
+ li t1,0x90000000
+
+ .set noreorder
+ .set noat
+ li t6,1 << PSR_CU1 // disable interrupt
+ ori t6,t6,1 << PSR_KX // use 64bit address mode
+ mfc0 t7,psr //
+ mtc0 t6,psr //
+ nop
+ nop
+ .set at
+ .set reorder
+
+ and t0,zero,zero
+ dsll t0,t1,32 // shift entry address to upper 32-bits
+ or t0,t0,a0 // make access address
+ lw v0,0(t0)
+
+ .set noreorder
+ .set noat
+ mtc0 t7,psr // enable interrupt
+ nop
+ .set at
+ .set reorder
+
+ j ra // return
+
+ .end HalpReadPhysicalAddress
+// S005 ^^^
+// S006 vvv
+ SBTTL("Write Physical Address")
+//++
+//
+// Routine Description:
+//
+// This routine is Write of physical address.
+//
+// Argments:
+//
+// a0 - Physical address
+//
+// a1 - Write Data
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpWritePhysicalAddr)
+
+ li t1,0x90000000
+
+ .set noreorder
+ .set noat
+ li t6,1 << PSR_CU1 // disable interrupt
+ ori t6,t6,1 << PSR_KX // use 64bit address mode
+ mfc0 t7,psr //
+ mtc0 t6,psr //
+ nop
+ nop
+ .set at
+ .set reorder
+
+ and t0,zero,zero
+ dsll t0,t1,32 // shift entry address to upper 32-bits
+ or t0,t0,a0 // make access address
+ sw a1,0(t0)
+
+ .set noreorder
+ .set noat
+ mtc0 t7,psr // enable interrupt
+ nop
+ .set at
+ .set reorder
+
+ j ra // return
+
+ .end HalpWritePhysicalAddress
+
+
+ SBTTL("Read And Write Physical Address")
+//++
+//
+// Routine Description:
+//
+// This routine is read and write of physical address.
+//
+// Argments:
+//
+// a0 - Physical address
+//
+// Return Value:
+//
+// read data.
+//
+//--
+
+ LEAF_ENTRY(HalpReadAndWritePhysicalAddr)
+
+ li t1,0x90000000
+
+ .set noreorder
+ .set noat
+ li t6,1 << PSR_CU1 // disable interrupt
+ ori t6,t6,1 << PSR_KX // use 64bit address mode
+ mfc0 t7,psr //
+ mtc0 t6,psr //
+ nop
+ nop
+ .set at
+ .set reorder
+
+ and t0,zero,zero
+ dsll t0,t1,32 // shift entry address to upper 32-bits
+ or t0,t0,a0 // make access address
+ lw v0,0(t0)
+ sw v0,0(t0)
+
+ .set noreorder
+ .set noat
+ mtc0 t7,psr // enable interrupt
+ nop
+ .set at
+ .set reorder
+
+ j ra // return
+
+ .end HalpReadAndWritePhysicalAddress
+// S006 ^^^
+
+
+#if 0 //koredmo ugoku kedo waikomi disable ha amari yokuarimasenn....
+
+//++
+//
+// VOID
+// READ_REGISTER_ULONGLONG (
+// IN PLARGE_INTEGER RegisterAddress,
+// IN PVOID Variable
+// )
+//
+// Routine Description:
+//
+// 64-bit 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.
+//
+//--
+
+#if 1
+ .struct 0
+sv1f0: .space 4*2
+Length1F0:
+ NESTED_ENTRY(READ_REGISTER_ULONGLONG, Length1F0, zero)
+ subu sp,sp,Length1F0 // allocate stack frame
+ DISABLE_INTERRUPTS(t7) // disable interrupts
+ sdc1 f0,sv1f0(sp) // f0 save
+#else
+ LEAF_ENTRY(READ_REGISTER_ULONGLONG)
+#endif
+
+ ldc1 f0,0(a0) // move 8-byte block
+ sdc1 f0,0(a1) //
+#if 1
+ ldc1 f0,sv1f0(sp) // f0 resume
+ addu sp,sp,Length1F0 // deallocate stack frame
+ ENABLE_INTERRUPTS(t7) // enable interrupts
+#endif
+
+ sync // synchronize read
+
+ j ra // return
+
+ .end READ_REGISTER_ULONGLONG
+
+
+//++
+//
+// VOID
+// WRITE_REGISTER_ULONGLONG (
+// 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.
+//
+//--
+
+#if 1
+ .struct 0
+sv2f0: .space 4*2
+Length2F0:
+ NESTED_ENTRY(WRITE_REGISTER_ULONGLONG, Length2F0, zero)
+ subu sp,sp,Length2F0 // allocate stack frame
+ DISABLE_INTERRUPTS(t7) // disable interrupts
+ sdc1 f0,sv2f0(sp) // f0 save
+#else
+ LEAF_ENTRY(WRITE_REGISTER_ULONGLONG)
+#endif
+
+ ldc1 f0,0(a1) // move 8-byte block
+ sdc1 f0,0(a0) //
+#if 1
+ ldc1 f0,sv2f0(sp) // f0 resume
+ addu sp,sp,Length2F0 // deallocate stack frame
+ ENABLE_INTERRUPTS(t7) // enable interrupts
+#endif
+
+ sync // synchronize write
+
+ j ra // return
+
+ .end WRITE_REGISTER_ULONGLONG
+
+#else //korede warikomi ha enable no mama syori dekimasu.
+//
+//
+//
+//
+
+ .struct 0
+CiArgs: .space 4 * 4 // saved arguments
+ .space 3 * 4 // fill
+Rt7: .space 4
+Rt8: .space 4
+
+LengthRtN:
+
+ NESTED_ENTRY(READ_REGISTER_ULONGLONG, LengthRtN, zero)
+// DISABLE_INTERRUPTS(t9) // disable interrupts
+ subu sp,sp,LengthRtN // allocate stack frame
+
+
+ PROLOGUE_END
+ sw t7,Rt7(sp)
+ sw t8,Rt8(sp)
+
+ lw t7,0x0(a0)
+ lw t8,0x4(a0)
+
+ sw t7,0x0(a1)
+ sw t8,0x4(a1)
+
+ lw t7,Rt7(sp)
+ lw t8,Rt8(sp)
+
+ addu sp,sp,LengthRtN // deallocate stack frame
+// ENABLE_INTERRUPTS(t9) // enable interrupts
+ sync // synchronize read
+
+ j ra // return
+
+ .end READ_REGISTER_ULONGLONG
+
+//
+//
+//
+//
+ .struct 0
+DiArgs: .space 4 * 4 // saved arguments
+ .space 3 * 4 // fill
+Wt7: .space 4
+Wt8: .space 4
+
+LengthWtN:
+
+ NESTED_ENTRY(WRITE_REGISTER_ULONGLONG, LengthWtN, zero)
+// DISABLE_INTERRUPTS(t9) // disable interrupts
+ subu sp,sp,LengthWtN // allocate stack frame
+
+
+ PROLOGUE_END
+
+ sw t7,Wt7(sp)
+ sw t8,Wt8(sp)
+
+ lw t7,0x0(a1)
+ lw t8,0x4(a1)
+ sw t7,0x0(a0)
+ sw t8,0x4(a0)
+
+ lw t7,Wt7(sp)
+ lw t8,Wt8(sp)
+
+ addu sp,sp,LengthWtN // deallocate stack frame
+// ENABLE_INTERRUPTS(t9) // enable interrupts
+ sync // synchronize read
+
+ j ra // return
+
+ .end WRITE_REGISTER_ULONGLONG
+
+#endif
+
+
+ SBTTL("T5 Int 5 Interrupt")
+//
+// On the R98B (r10k) this hardware interrupt is for the internal timer
+// interrupt. This is not used for the PROFILE interrupt on the R98B
+//
+
+//
+// InternalTimer interrupt does not use for profile interrupt.
+// So,Here is only clear internal interrupt.
+// v-masank@microsoft.com
+
+ LEAF_ENTRY(HalpT5Int5Dispatch)
+
+ .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
+ nop
+ nop
+ .set at
+ .set reorder
+
+ move a0,s8 // trap frame
+ li a1,0x5 // Interrupt is INT5
+ j HalpGeneralDispatch
+
+ .end HalpT5Int5Dispatch
+
+
diff --git a/private/ntos/nthals/halr98b/mips/rxipiint.s b/private/ntos/nthals/halr98b/mips/rxipiint.s
new file mode 100644
index 000000000..c3e99ffd2
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxipiint.s
@@ -0,0 +1,79 @@
+// TITLE("Interprocessor Interrupts")
+//++
+//
+// Copyright (c) 1993 Microsoft Corporation
+//
+// Module Name:
+//
+// rxipiint.s
+//
+// Abstract:
+//
+// This module implements the code necessary to field and process the
+// interprocessor interrupts on a MIPS R98 system.
+//
+// Author:
+//
+//
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+//--
+
+#include "halmips.h"
+
+
+ SBTTL("Interprocessor Interrupt")
+//++
+//
+// Routine Description:
+//
+// This routine is entered as the result of an interprocessor interrupt.
+// Its function is to acknowledge the interrupt and transfer control to
+// the standard system routine to process interprocessor requrests.
+//
+// Arguments:
+//
+// s8 - Supplies a pointer to a trap frame at hal first dispatch
+// a0 - Supplies a pointer to a trap frame at kernel trap frame
+// a1 - intx
+// Return Value:
+//
+// None.
+//
+//--
+// secondary
+
+ .struct 0
+ //
+liArgs: .space 4 * 4 // saved arguments
+IiS8: .space 4 //
+IiRa: .space 4 //
+IiFrameLength: //
+
+ NESTED_ENTRY(HalpIpiInterrupt, IiFrameLength, zero)
+
+ subu sp,sp,IiFrameLength // allocate stack frame
+ sw s8,IiS8(sp) // save s8
+ sw ra,IiRa(sp) // save Ra
+
+ PROLOGUE_END
+
+ or s8,a0,zero // set up trapframe to s8
+ // KeIpiInterrupt require trapframe at s8
+
+ lw t1,__imp_KeIpiInterrupt // process interprocessor requests
+ jal t1 //
+
+ lw ra,IiRa(sp) // restore ra
+ lw s8,IiS8(sp) // restore s8
+ addu sp,sp,IiFrameLength // deallocate stack frame
+ j ra // return
+
+ .end HalpIpIInterrupt
+
+
diff --git a/private/ntos/nthals/halr98b/mips/rxisabus.c b/private/ntos/nthals/halr98b/mips/rxisabus.c
new file mode 100644
index 000000000..abc396c95
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxisabus.c
@@ -0,0 +1,729 @@
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ ixisabus.c
+
+Abstract:
+
+Author:
+
+Environment:
+
+Revision History:
+
+
+--*/
+
+#include "halp.h"
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE,HalpGetEisaInterruptVector)
+#pragma alloc_text(PAGE,HalpAdjustEisaResourceList)
+#pragma alloc_text(PAGE,HalpGetEisaData)
+#endif
+
+
+ULONG
+HalpGetEisaInterruptVector(
+ 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.
+
+--*/
+{
+ UNREFERENCED_PARAMETER( BusInterruptVector );
+
+ //
+ // On standard PCs, IRQ 2 is the cascaded interrupt, and it really shows
+ // up on IRQ 9.
+ //
+ if (BusInterruptLevel == 2) {
+ BusInterruptLevel = 9;
+ }
+
+ if (BusInterruptLevel > 15) {
+ return 0;
+ }
+
+ *Irql = (KIRQL)(INT0_LEVEL+HalpIntLevelofIpr[HalpMachineCpu][EISA_DISPATCH_VECTOR-DEVICE_VECTORS]);
+ *Affinity = 0x1 <<HalpResetValue[EISA_DISPATCH_VECTOR-DEVICE_VECTORS].Cpu;
+
+ //
+ // Get parent's translation from here..
+ //
+
+ //
+ // The vector is equal to the specified bus level plus the EISA_VECTOR.
+ //
+
+ return(BusInterruptLevel + EISA_VECTORS);
+
+}
+
+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
+ );
+}
+
+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;
+#if 1
+ PHYSICAL_ADDRESS BusAddressTmp;
+#endif
+ //
+ // Translated normally
+ //
+#if defined(DBG1)
+ DbgPrint("Hal: Trans ISA IN\n");
+#endif
+
+
+ Status = HalpTranslateSystemBusAddress (
+ BusHandler,
+ RootHandler,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress
+ );
+
+#if DBG
+// DbgPrint("Hal: Trans ISA IN 2 Status = 0x%x\n",Status);
+#endif
+
+
+ //
+ // 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) {
+#if DBG
+// DbgPrint("Hal: Trans ISA IN3\n");
+#endif
+
+ Status = HalTranslateBusAddress (
+ Eisa,
+ BusHandler->BusNumber,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress
+ );
+ }
+ //
+ // Add BackWard Compatibility.
+ //
+ //
+#if 1
+ else
+
+ //
+ // If it could not be translated, and It's ISA Alias at Eisa Slot
+ // range then (for compatibility) try translating it on the
+ // dummy slot io range
+ //
+
+ if (Status == FALSE &&
+ *AddressSpace == 1 &&
+ BusAddress.HighPart == 0 &&
+ BusAddress.LowPart >= 0x4000 &&
+ BusAddress.LowPart <= 0xFFFF) {
+
+#if DBG
+// DbgPrint("Isa Low ffffffffff= 0x%x\n",BusAddress.LowPart);
+// DbgPrint("Isa Hig ffffffffff= 0x%x\n",BusAddress.HighPart);
+// DbgPrint("Isa add ffffffffff= 0x%x\n", *AddressSpace);
+
+#endif
+ BusAddressTmp.LowPart = BusAddress.LowPart;
+ BusAddressTmp.LowPart &= 0x0fff;
+ BusAddressTmp.LowPart |= 0x4000;
+ BusAddressTmp.HighPart = 0 ;
+
+
+ Status = HalpTranslateSystemBusAddress (
+ BusHandler,
+ RootHandler,
+ BusAddressTmp,
+ AddressSpace,
+ TranslatedAddress
+ );
+#if DBG
+// DbgPrint("EIsa Low = 0x%x\n",TranslatedAddress->LowPart);
+// DbgPrint("EIsa Hig = 0x%x\n",TranslatedAddress->HighPart);
+// DbgPrint("EIsa add = 0x%x\n", *AddressSpace);
+// DbgPrint("Eisa Status = 0x%x\n", Status);
+#endif
+
+ }
+#endif
+
+
+
+#if defined(DBG)
+// DbgPrint("Hal: Trans ISA Out\n");
+
+// DbgPrint("Isa Low = 0x%x\n",BusAddress.LowPart);
+// DbgPrint("Isa Hig = 0x%x\n",BusAddress.HighPart);
+// DbgPrint("Isa add = 0x%x\n", *AddressSpace);
+// DbgPrint("Isa TLow = 0x%x\n",TranslatedAddress->LowPart);
+// DbgPrint("Isa THig = 0x%x\n",TranslatedAddress->HighPart);
+// DbgPrint("Isa Status = 0x%x\n", Status);
+
+
+#endif
+
+
+ return Status;
+}
+
+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;
+#if 1
+ PHYSICAL_ADDRESS BusAddressTmp;
+#endif
+
+ //
+ // 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
+ );
+ }
+ //
+ // Add BackWard Compatibility.
+ //
+ //
+#if 1
+
+ else
+
+
+ //
+ // If it could not be translated, and It's EISA Slot
+ // range then (for compatibility) try translating it on the
+ // dummy slot io range
+ //
+
+ if (Status == FALSE &&
+ *AddressSpace == 1 &&
+ BusAddress.HighPart == 0 &&
+ BusAddress.LowPart >= 0x4000 &&
+ BusAddress.LowPart <= 0xFFFF) {
+
+#if DBG
+// DbgPrint("EIsa Low ffffffffff= 0x%x\n",BusAddress.LowPart);
+// DbgPrint("EIsa Hig ffffffffff= 0x%x\n",BusAddress.HighPart);
+// DbgPrint("EIsa add ffffffffff= 0x%x\n", *AddressSpace);
+#endif
+
+ BusAddressTmp.LowPart = BusAddress.LowPart;
+ BusAddressTmp.LowPart &= 0x0fff;
+ BusAddressTmp.LowPart |= 0x4000;
+ BusAddressTmp.HighPart = 0 ;
+
+
+
+ Status = HalpTranslateSystemBusAddress (
+ BusHandler,
+ RootHandler,
+ BusAddressTmp,
+ AddressSpace,
+ TranslatedAddress
+ );
+#if DBG
+// DbgPrint("EIsa Low = 0x%x\n",TranslatedAddress->LowPart);
+// DbgPrint("EIsa Hig = 0x%x\n",TranslatedAddress->HighPart);
+// DbgPrint("EIsa add = 0x%x\n", *AddressSpace);
+// DbgPrint("Eisa Status = 0x%x\n", Status);
+#endif
+
+ }
+#endif
+
+ return Status;
+}
+
+
+HalpGetEisaData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ 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 ();
+
+#if DBG //SNES
+ DbgPrint("Halp Get Eisa DataOh!\n");
+#endif
+ 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)) {
+#if DBG
+ DbgPrint("HAL: Open Status = %x\n",NtStatus);
+#endif
+ return(0);
+ }
+#if DBG
+ DbgPrint("Halp Get EisaAdapter Key Open Complete !\n");
+#endif
+
+
+ //
+ // 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)) {
+#if DBG
+ DbgPrint("HAL: Opening Bus Number: Status = %x\n",NtStatus);
+#endif
+ 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;
+}
diff --git a/private/ntos/nthals/halr98b/mips/rxnvr.h b/private/ntos/nthals/halr98b/mips/rxnvr.h
new file mode 100644
index 000000000..71824fe8c
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxnvr.h
@@ -0,0 +1,176 @@
+
+/*++
+
+Module Name:
+
+ rxnvr.h
+
+Abstract:
+
+ This module contains definitions for the R98B non-volatile ram structures.
+
+--*/
+
+
+#ifndef _RXNVR_
+#define _RXNVR_
+
+
+//
+// R98B Nvram Physicall Map
+//
+// 0x1f08 0000 +-------+
+// | 4K | POST/ITF and NMI Vector
+// 0x1f08 1000 +-------+
+// | 2K |
+// 0x1f08 1800 +-------+
+// | 2K | Free
+// 0x1f08 2000 +-------+
+// | 800B | Configuration Packet
+// 0x1f08 2320 +-------+
+// | 516B | Identifier
+// 0x1f08 2524 +-------+
+// | 2K | Configuration Data
+// 0x1f08 2d24 +-------+
+// | 4B | Checksum1
+// 0x1f08 2d28 +-------+
+// | 1K | Environment
+// 0x1f08 3128 +-------+
+// | 4BK | Checksum2
+// 0x1f08 312c +-------+
+// | 3796B | Reserved For ARC FW
+// 0x1f08 4000 +-------+
+// | 32K | H/W Logging field
+// 0x1f08 c000 +-------+
+// | 4K | Reserved
+// 0x1f08 d000 +-------+
+// | 4K | XXXXXX
+// 0x1f08 e000 +-------+
+// | 8B | Ethrnet Address
+// 0x1f08 e008 +-------+
+// | 2K | UP Area
+// 0x1f08 e800 +-------+
+// | 4092B | EISA Configuration
+// 0x1f08 f7fc +-------+
+// | 4B | Checksum3
+// 0x1f08 f800 +-------+
+// | 57K | Free
+// 0x1f09 dc00 +-------+
+// | 1K | Hal
+// 0x1f09 e000 +-------+
+// | 8K | ESM
+// 0x1f0a 0000 +-------+
+//
+
+
+
+// Define the private configuration packet structure, which contains a
+// configuration component as well as pointers to the component's parent,
+// peer, child, and configuration data.
+//
+
+typedef struct _CONFIGURATION_PACKET {
+ CONFIGURATION_COMPONENT Component;
+ struct _CONFIGURATION_PACKET *Parent;
+ struct _CONFIGURATION_PACKET *Peer;
+ struct _CONFIGURATION_PACKET *Child;
+ PVOID ConfigurationData;
+} CONFIGURATION_PACKET, *PCONFIGURATION_PACKET;
+
+//
+// The compressed configuration packet structure used to store configuration
+// data in NVRAM.
+//
+
+typedef struct _COMPRESSED_CONFIGURATION_PACKET {
+ UCHAR Parent;
+ UCHAR Class;
+ UCHAR Type;
+ UCHAR Flags;
+ ULONG Key;
+ USHORT Version;
+ USHORT ConfigurationDataLength;
+ USHORT Identifier;
+ USHORT ConfigurationData;
+} COMPRESSED_CONFIGURATION_PACKET, *PCOMPRESSED_CONFIGURATION_PACKET;
+
+//
+// Defines for Identifier index.
+//
+
+#define NO_CONFIGURATION_IDENTIFIER 0xFFFF
+
+//
+// Defines for the volatile and non-volatile configuration tables.
+//
+
+#define NUMBER_OF_ENTRIES 50
+#define LENGTH_OF_IDENTIFIER 516
+#define LENGTH_OF_DATA 2048
+#define LENGTH_OF_ENVIRONMENT 1024
+#define LENGTH_OF_EISA_DATA 4092
+
+//
+// The volatile configuration table structure.
+//
+
+typedef struct _CONFIGURATION {
+ CONFIGURATION_PACKET Packet[NUMBER_OF_ENTRIES];
+ UCHAR Identifier[LENGTH_OF_IDENTIFIER];
+ UCHAR Data[LENGTH_OF_DATA];
+} CONFIGURATION, *PCONFIGURATION;
+
+//
+// The non-volatile configuration table structure.
+//
+
+
+typedef struct _NV_CONFIGURATION {
+
+ COMPRESSED_CONFIGURATION_PACKET Packet[NUMBER_OF_ENTRIES]; // 800B =16B * 50 Entry
+ UCHAR Identifier[LENGTH_OF_IDENTIFIER]; // 516B
+ UCHAR Data[LENGTH_OF_DATA]; // 2048B
+
+ UCHAR Checksum1[4];
+ UCHAR Environment[LENGTH_OF_ENVIRONMENT]; // 1024B
+ UCHAR Checksum2[4];
+ UCHAR ArcReserved[3796];
+ UCHAR HwLogging[1024 * 32];
+ UCHAR Reserved0[1024 * 4];
+ UCHAR Reserved1[1224 * 4];
+ UCHAR EthernetAddress[8];
+ UCHAR UPArea[1024 * 2];
+ UCHAR EisaData[LENGTH_OF_EISA_DATA]; // 4092B
+ UCHAR Checksum3[4];
+ UCHAR Reserved2[ 1024 * 57];
+ UCHAR Hal[ 1024];
+ UCHAR Esm[1024 * 8];
+// UCHAR NmiVector[4];
+} NV_CONFIGURATION, *PNV_CONFIGURATION;
+
+
+//
+// Nmi Vecter Address table structure. by kita
+//
+#define NMIVECTER_PHYSICAL_BASE 0x1F080000
+#define NMIVECTER_BASE (KSEG1_BASE + NMIVECTER_PHYSICAL_BASE)
+
+typedef struct _NVRAM_NMIVECTER {
+ UCHAR NotUsed[12];
+ UCHAR NmiVector[4];
+} NVRAM_NMIVECTER, *PNVRAM_NMIVECTER;
+
+
+
+//
+// Non-volatile ram layout.
+//
+
+#if defined(MIPS)
+
+#define NVRAM_CONFIGURATION NVRAM_VIRTUAL_BASE
+#define NVRAM_SYSTEM_ID NVRAM_VIRTUAL_BASE + 0x00002000
+
+#endif
+
+#endif // _RXNVR_
diff --git a/private/ntos/nthals/halr98b/mips/rxpcibrd.c b/private/ntos/nthals/halr98b/mips/rxpcibrd.c
new file mode 100644
index 000000000..37aef5f43
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxpcibrd.c
@@ -0,0 +1,1157 @@
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ rxpcibrd.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 ULONG StartPciBus, //R98B
+ 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;
+ ULONG Ponce;
+
+
+ Rescan = 0;
+ FoundDisabledBridge = FALSE;
+ // This is Ponce Number;
+
+ //
+ // 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;
+ // R98B
+ //
+#if DBG
+ DbgPrint("HAL PCI StartPCIBusNo =0x%x\n",(ULONG)StartPciBus);
+ DbgPrint("HAL PCI MaxPciBus =0x%x\n",*MaxPciBus);
+#endif
+
+ for (BusNo=StartPciBus; BusNo < *MaxPciBus; BusNo++) {
+ CB.BusHandler = HalpHandlerForBus (PCIBus, BusNo);
+ CB.BusData = (PPCIPBUSDATA) CB.BusHandler->BusData;
+#if DBG
+ DbgPrint("HAL PCI BusNo =0x%x\n",(ULONG)BusNo);
+// DbgPrint("HAL PCI brg =0x%x\n",(ULONG)CB.BusHandler);
+// DbgPrint("HAL PCI busdata =0x%x\n",(ULONG)CB.BusData);
+#endif
+
+ 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 DBG
+ HalpTestPciPrintResult((PULONG)CB.PciData,PCI_COMMON_HDR_LENGTH );
+#if 0 //f/w debug
+
+ CB.PciData->Command = 0x7;
+
+ if(BusNo == 0 && CB.PciData->u.type1.SecondaryBus == 1){
+ CB.PciData->u.type1.IOBase = 0x50;
+ CB.PciData->u.type1.IOLimit = 0x60;
+
+ }else if(BusNo == 0 && CB.PciData->u.type1.SecondaryBus == 2 ){
+ CB.PciData->u.type1.IOBase = 0x70;
+ CB.PciData->u.type1.IOLimit = 0x80;
+ CB.PciData->u.type1.MemoryBase =0x0620;
+ CB.PciData->u.type1.MemoryLimit =0x0630;
+
+ }
+ else if(BusNo == 3 && CB.PciData->u.type1.SecondaryBus == 1 ){
+ CB.PciData->u.type1.IOBase = 0x40;
+ CB.PciData->u.type1.IOLimit = 0x50;
+
+ }
+ else if(BusNo == 3 && CB.PciData->u.type1.SecondaryBus == 2 ){
+ CB.PciData->u.type1.IOBase = 0x60;
+ CB.PciData->u.type1.IOLimit = 0x70;
+
+ CB.PciData->u.type1.MemoryBase =0x0620;
+ CB.PciData->u.type1.MemoryLimit =0x0630;
+
+
+// CB.PciData->u.type1.PrefetchBase = 0x0010;
+// CB.PciData->u.type1.PrefetchLimit= 0x0010;
+
+ }
+
+ HalpWritePCIConfig (
+ CB.BusHandler,
+ CB.SlotNumber,
+ CB.PciData,
+ 0,
+ PCI_COMMON_HDR_LENGTH
+ );
+#if DBG
+ DbgPrint ("HAL Brdge fix -----------!!!\n");
+#endif
+// HalpReadPCIConfig (
+// CB.BusHandler,
+// CB.SlotNumber,
+// CB.PciData,
+// 0,
+// PCI_COMMON_HDR_LENGTH
+// );
+
+// HalpTestPciPrintResult((PULONG)CB.PciData,PCI_COMMON_HDR_LENGTH );
+
+#endif
+#endif
+
+ if (!(CB.PciData->Command & PCI_ENABLE_BUS_MASTER)) {
+
+ // this PCI bridge is not enabled - skip it for now
+ DBGMSG ("HAL Bridge is not enable contineu!!!\n");
+ FoundDisabledBridge = TRUE;
+ continue;
+
+ }
+
+ // R98B First PCI Bus of Ponce Must be 0.
+ // So Convert System(NT) BusNumber to required BusNumber for PONCE.
+ //
+ Ponce = HalpPonceNumber(CB.BusHandler->BusNumber);
+ if ((ULONG) CB.PciData->u.type1.PrimaryBus !=
+ CB.BusHandler->BusNumber - HalpStartPciBusNumberPonce[Ponce]) {
+#if DBG
+ DbgPrint ("HAL GetPciData: bad BusNumber =0x%x!!!\n",(ULONG) CB.BusHandler->BusNumber);
+ DbgPrint ("HAL GetPciData: bad primarybus =0x%x!!!\n",(ULONG) CB.PciData->u.type1.PrimaryBus);
+ // what to do?
+#endif
+ }
+
+ //
+ // Found a PCI-PCI bridge. Determine it's parent child
+ // releationships
+ //
+#if DBG
+ DbgPrint ("HAL Bridge secondrybus =0x%x!!!\n",(ULONG) CB.PciData->u.type1.SecondaryBus);
+#endif
+
+ ChildBus = HalpHandlerForBus (PCIBus,
+ CB.PciData->u.type1.SecondaryBus+HalpStartPciBusNumberPonce[Ponce]
+ );
+
+ if (!ChildBus) {
+ DBGMSG ("HAL GetPciData: found configured pci bridge\n");
+
+ // up the number of buses
+ if (CB.PciData->u.type1.SecondaryBus+HalpStartPciBusNumberPonce[Ponce] > Rescan) {
+ Rescan = CB.PciData->u.type1.SecondaryBus+(UCHAR)HalpStartPciBusNumberPonce[Ponce]+1;
+ HalpStartPciBusNumberPonce[Ponce+1]++;
+ }
+ 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) {
+#if DBG
+ DbgPrint("Hal Bridge VGA Busnum =0x%x\n",ChildBus->BusNumber);
+#endif
+ 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) {
+#if DBG
+ DbgPrint("Hal Bridge 256 limit\n");
+#endif
+
+ // 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,
+ (ULONG)0, // address space
+ (LONGLONG)(PCI_CNTL_PHYSICAL_BASE+ // system base
+ PCI_MAX_CNTL_SIZE * Ponce),
+ (LONGLONG)i, // bus address
+ (LONGLONG)(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);
+
+#if 1
+//
+// If F/W setup PrefetchBaseUpper32 == 0
+// This Bus Range add PrefetchMemory area. This Range not support..
+// Under Ponce #0. Memory area start 64MG so never append prefetch memory area.
+// But Punder Pnce 1#. Memory area start 0MG So append prefetch memory area by addrange.
+//
+ // On x86 it's ok to clip Prefetch to 32 bits
+
+ if (CB.PciData->u.type1.PrefetchBaseUpper32 == 0) {
+#if DBG
+ DbgPrint("Hal Bridge prefetch upper32\n");
+#endif
+
+ 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;
+ }
+ }
+
+#endif
+ // 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;
+
+#if DBG
+ DbgPrint("HAL Fix Range 0\n");
+#endif
+
+ //
+ // 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;
+ }
+ }
+
+#if DBG
+ DbgPrint("HAL Fix Range 1\n");
+#endif
+
+ //
+ // 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;
+ }
+ }
+#if DBG
+ DbgPrint("HAL Fix Range 2\n");
+#endif
+
+ //
+ // Cleanup
+ //
+
+ for (i = 0; i < MaxBuses; i++) {
+ Bus = HalpHandlerForBus (PCIBus, i);
+ HalpConsolidateRanges (Bus->BusAddresses);
+ }
+#if DBG
+ for (i = 0; i < MaxBuses; i++) {
+ Bus = HalpHandlerForBus (PCIBus, i);
+ DbgPrint("HAL: PCIBus#%d, MemBase=%x.%x, Lmt=%x.%x, SysBase=%x.%x, IoBase=%x.%x, Lmt=%x.%x\n",
+ i,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Base))->HighPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Base))->LowPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Limit))->HighPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Limit))->LowPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->HighPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.Base))->HighPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.Base))->LowPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.Limit))->HighPart,
+ ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.Limit))->LowPart
+ );
+ }
+#endif
+}
+
+
+
+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/halr98b/mips/rxpcibus.c b/private/ntos/nthals/halr98b/mips/rxpcibus.c
new file mode 100644
index 000000000..6796e1804
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxpcibus.c
@@ -0,0 +1,2826 @@
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ rxpcibus.c
+
+Abstract:
+
+ Get/Set bus data routines for the PCI bus
+
+Author:
+
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+
+#if defined(INTEL_9036)
+ULONG intel_9036=FALSE;
+#endif
+
+extern WCHAR rgzMultiFunctionAdapter[];
+extern WCHAR rgzConfigurationData[];
+extern WCHAR rgzIdentifier[];
+extern WCHAR rgzPCIIdentifier[];
+
+ULONG HalpCirrusDel = FALSE;
+
+typedef ULONG (*FncConfigIO) (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+typedef VOID (*FncSync) (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PVOID State
+ );
+
+typedef VOID (*FncReleaseSync) (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ );
+
+typedef struct _PCI_CONFIG_HANDLER {
+ FncSync Synchronize;
+ FncReleaseSync ReleaseSynchronzation;
+ FncConfigIO ConfigRead[3];
+ FncConfigIO ConfigWrite[3];
+} PCI_CONFIG_HANDLER, *PPCI_CONFIG_HANDLER;
+
+
+
+//
+// Prototypes
+//
+
+ULONG
+HalpGetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+ULONG
+HalpSetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+NTSTATUS
+HalpAssignPCISlotResources (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName OPTIONAL,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ IN ULONG SlotNumber,
+ IN OUT PCM_RESOURCE_LIST *AllocatedResources
+ );
+
+VOID
+HalpInitializePciBus (
+ VOID
+ );
+
+BOOLEAN
+HalpIsValidPCIDevice (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ );
+
+BOOLEAN
+HalpValidPCISlot (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ );
+
+
+VOID HalpPCISynchronizeType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PVOID State
+ );
+
+VOID HalpPCIReleaseSynchronzationType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN KIRQL Irql
+ );
+
+ULONG HalpPCIReadUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIReadUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+ULONG HalpPCIWriteUshortType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PVOID State,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ );
+
+//
+// Globals
+//
+
+KSPIN_LOCK HalpPCIConfigLock;
+
+// R98B Configuration Mechanism #1.
+//
+PCI_CONFIG_HANDLER PCIConfigHandler = {
+ HalpPCISynchronizeType1,
+ HalpPCIReleaseSynchronzationType1,
+ {
+ HalpPCIReadUlongType1, // 0
+ HalpPCIReadUcharType1, // 1
+ HalpPCIReadUshortType1 // 2
+ },
+ {
+ HalpPCIWriteUlongType1, // 0
+ HalpPCIWriteUcharType1, // 1
+ HalpPCIWriteUshortType1 // 2
+ }
+};
+
+
+UCHAR PCIDeref[4][4] = { {0,1,2,2},{1,1,1,1},{2,1,2,2},{1,1,1,1} };
+
+extern BOOLEAN HalpDoingCrashDump;
+
+VOID
+HalpPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN FncConfigIO *ConfigIO
+ );
+
+#if DBG
+#define DBGMSG(a) DbgPrint(a)
+VOID
+HalpTestPci (
+ ULONG
+ );
+#else
+#define DBGMSG(a)
+#endif
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpInitializePciBus)
+#pragma alloc_text(INIT,HalpAllocateAndInitPciBusHandler)
+#pragma alloc_text(INIT,HalpIsValidPCIDevice)
+#pragma alloc_text(PAGE,HalpAssignPCISlotResources)
+#endif
+
+// Number Of PCI Bus.
+//
+UCHAR HalpNumberOfAllPciBus=0;
+
+// Start Pci BusNumber of PONCE #0,#1 #n ,,,
+//
+ULONG HalpStartPciBusNumberPonce[R98B_MAX_PONCE+1];
+//
+// Get PONCE Number (0 origin) From System(NT) BusNumber.
+//
+ULONG
+HalpPonceNumber (
+ IN ULONG BusNumber
+ )
+{
+ ULONG Ponce;
+
+ if( BusNumber <HalpStartPciBusNumberPonce[1]){
+ Ponce = 0;
+ }else if(BusNumber <HalpStartPciBusNumberPonce[2]){
+ Ponce = 1;
+ }else if(BusNumber <HalpStartPciBusNumberPonce[3]){
+ Ponce = 2;
+ }
+
+ return Ponce;
+
+}
+
+#if DBG
+
+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);
+ for (i = 0; i < 4; pchar += 4, i++) {
+ if (pchar >= Length)
+ break;
+ DbgPrint("%08x ", *Buffer++);
+ }
+ DbgPrint("\n");
+ }
+}
+
+
+VOID
+HalpTestPciNec (ULONG flag2)
+{
+ PCI_SLOT_NUMBER SlotNumber;
+ PCI_COMMON_CONFIG PciData, OrigData;
+ ULONG i, f, j, k, bus;
+ BOOLEAN flag;
+ ULONG MaxDevice;
+
+ if (!flag2) {
+ return ;
+ }
+
+ DbgPrint("Nec Test Start --------------------------------------------\n");
+ 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 < HalpNumberOfAllPciBus; bus++) { /* R98B Support Only 2 */
+// for (bus = 3; flag && bus < 4; bus++) { //under ponce #1 only
+ DbgPrint("Config data BusNumber = 0x%x --------------------------------------------\n",bus);
+ if( (bus == HalpStartPciBusNumberPonce[0]) || (bus == HalpStartPciBusNumberPonce[1]) )
+ MaxDevice = 7;
+ else
+ MaxDevice = PONCE_PCI_MAX_DEVICES;
+
+ for (i = 0; i < MaxDevice; i++) {
+ SlotNumber.u.bits.DeviceNumber = i;
+
+ for (f = 0; f < 8; f++) {
+ SlotNumber.u.bits.FunctionNumber = f;
+ DbgPrint("===== GetBusData bus(%d) slot(%d) func(%d) ", bus,i, f);
+
+ //
+ // Read PCI configuration information
+ //
+
+ j = HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ if (j == 0) {
+ // out of buses
+ flag = FALSE;
+ break;
+ }
+ HalpTestPciPrintResult((PULONG)&PciData, j);
+
+ if (j < PCI_COMMON_HDR_LENGTH) {
+ continue;
+ }
+ DbgPrint("===== SetBusData bus(%d) slot(%d) func(%d) ", bus,i, f);
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ 1
+ );
+ HalpTestPciPrintResult((PULONG)&PciData, 1);
+ DbgPrint("===== GetBusData bus(%d) slot(%d) func(%d) ", bus,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) bus(%d) slot(%d) func(%d) ", bus,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 bus(%d) slot(%d) func(%d) ", bus, 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");
+ }
+ }
+ }
+ }
+
+}
+
+#endif
+
+#define KOTEI 0
+
+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;
+ ULONG Ponce;
+
+#if 1
+ PBUS_HANDLER Bus;
+ PSUPPORTED_RANGES Addresses;
+#endif
+
+
+#if KOTEI
+
+ PCI_REGISTRY_INFO tPCIRegInfo; // only for debug
+
+#endif
+ ULONG mnum;
+
+
+#if DBG
+ DbgPrint("HAL PCI init\n");
+#endif
+
+
+#if !KOTEI
+ //
+ // 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,
+ NULL);
+
+ status = ZwOpenKey (&hMFunc, KEY_READ, &objectAttributes);
+
+ if (!NT_SUCCESS(status)) {
+#if DBG
+ DbgPrint("HAL PCI init 0 Status = 0x%x\n",status);
+#endif
+
+ return ;
+ }
+
+
+#if DBG
+ DbgPrint("HAL PCI init 0\n");
+#endif
+
+
+ unicodeString.Buffer = wstr;
+ unicodeString.MaximumLength = sizeof (wstr);
+ RtlInitUnicodeString (&ConfigName, rgzConfigurationData);
+ RtlInitUnicodeString (&IdentName, rgzIdentifier);
+
+ ValueInfo = (PKEY_VALUE_FULL_INFORMATION) buffer;
+
+#endif // !KOTEI
+
+
+ // Number Of Host Bridge
+ for(Ponce = 0 ;Ponce < HalpNumberOfPonce;Ponce++){
+
+#if !KOTEI // Original mode
+
+//org for (i=HalpStartPciBusNumberPonce[Ponce]; TRUE; i++) {
+ for (i=HalpStartPciBusNumberPonce[Ponce]+1; 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;
+ }
+ }
+#else //SNES BBM Kotei Mode
+
+
+ PCIRegInfo = &tPCIRegInfo;
+ PCIRegInfo->NoBuses = 1;
+ PCIRegInfo->HardwareMechanism=0x1;
+
+#endif
+
+#if DBG
+ DbgPrint("HAL PCI init 3 NoBuses = 0x%x\n",PCIRegInfo->NoBuses);
+#endif
+
+
+ //
+ // Initialize spinlock for synchronizing access to PCI space
+ // First Time Only.
+ if(Ponce == 0)
+ KeInitializeSpinLock (&HalpPCIConfigLock);
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+
+ //
+ // PCIRegInfo describes the system's PCI support as indicated by the ARC System
+ // R98B HardwareMechanism is #1 Only.
+
+ HwType = PCIRegInfo->HardwareMechanism & 0xf;
+
+ // R98B
+ // HalpStartPciBusNumberPonce[Ponce #0] = 0 (allways)
+ // HalpStartPciBusNumberPonce[Ponce #1] = Number Of PCIbus Ponce#0 = start pci number
+ // HalpStartPciBusNumberPonce[Ponce #2] = Number Of PCIbus Ponce#0,#1 = start pci number
+ // HalpStartPciBusNumberPonce[ ] = Number Of PCIbus Ponce#1,#2 = start pci number
+ //
+
+
+ HalpNumberOfAllPciBus += PCIRegInfo->NoBuses;
+ HalpStartPciBusNumberPonce[Ponce+1]=
+ HalpStartPciBusNumberPonce[Ponce]+PCIRegInfo->NoBuses;
+ //
+ // For each PCI bus present, allocate a handler structure and
+ // fill in the dispatch functions
+ //
+
+ do {
+ // R98B
+ // SNES
+// for (i=HalpStartPciBusNumberPonce[Ponce]; i < HalpStartPciBusNumberPonce[Ponce] +PCIRegInfo->NoBuses; i++) {
+ for (i=HalpStartPciBusNumberPonce[Ponce]; i < HalpNumberOfAllPciBus;i++) {
+
+ //
+ // If handler not already built, do it now
+ //
+
+ if (!HalpHandlerForBus (PCIBus, i)) {
+#if DBG
+ DbgPrint("HAL PCI init 5\n");
+#endif
+
+ HalpAllocateAndInitPciBusHandler (HwType, i, FALSE);
+#if DBG
+ DbgPrint("HAL PCI init 6\n");
+#endif
+
+ }
+ }
+
+ //
+ // Bus handlers for all PCI buses have been allocated, go collect
+ // pci bridge information.
+ // R98B
+
+ } while (HalpGetPciBridgeConfig (HwType,HalpStartPciBusNumberPonce[Ponce] ,&HalpNumberOfAllPciBus)) ;
+
+// HalpNumberOfAllPciBus += PCIRegInfo->NoBuses;
+// HalpStartPciBusNumberPonce[Ponce+1]=
+// HalpStartPciBusNumberPonce[Ponce]+PCIRegInfo->NoBuses;
+
+ //
+ // Search Next Ponce!!.
+ //
+
+ }
+#if DBG
+ DbgPrint("HAL PCI init 7\n");
+
+ for(Ponce =0;Ponce < 4;Ponce++)
+ DbgPrint( "HalpStartPciBusNumberPonce[%x] = 0x%x\n",Ponce,HalpStartPciBusNumberPonce[Ponce]);
+
+ DbgPrint("HalpNumberOfAllPciBus = 0x%x\n",HalpNumberOfAllPciBus);
+#endif
+
+ //
+ // Fixup SUPPORTED_RANGES
+ // R98B fix NumberOfPcibus
+
+ HalpFixupPciSupportedRanges ( HalpNumberOfAllPciBus );
+
+#if 1 //org
+ //
+ // If not Display is CIRRUS. deleate range CIRRUS VGA I/O area.
+ // As interrupt Dummy read register is CIRRUS register.
+ // So Allways had mapped CIRRUS I/O area.
+ //
+ // If did not delete rage of CIRRUS I/O. Another PCI Driver
+ // May be Configration by I/O manager allocate CIRRUS I/O Area.
+ // confrict ocurred.
+ //
+ // Do Cirrus Memory area disable. So that another device allocate
+ // memory area.
+ //
+ if (!HalpCirrusAlive) {
+ Bus = HaliHandlerForBus (PCIBus, HalpStartPciBusNumberPonce[1]);
+ Addresses = Bus->BusAddresses;
+ HalpRemoveRange(&Addresses->IO,0x3000,0x3fff);
+
+ SlotNumber.u.bits.Reserved = 0;
+ SlotNumber.u.bits.DeviceNumber = 0x4;
+ SlotNumber.u.bits.FunctionNumber = 0;
+ //
+ // Cconfig command only
+ //
+ HalpReadPCIConfig (Bus, SlotNumber, PciData, 0x0, PCI_COMMON_HDR_LENGTH);
+
+ PciData->Command &= ~(PCI_ENABLE_MEMORY_SPACE);
+ //
+ // Cirrus Memory Space Disable
+ //
+ PciData->Command |= PCI_ENABLE_IO_SPACE | PCI_ENABLE_BUS_MASTER;
+
+ //
+ // Cconfig command only
+ //
+ HalpWritePCIConfig (Bus, SlotNumber, PciData, 0x0, PCI_COMMON_HDR_LENGTH);
+ //
+ // after this flag. CIRRUS device can't see Software.(Hal Only)
+ //
+ //
+ HalpCirrusDel = TRUE;
+
+ //for test only snes
+// HalpRemoveRange(&Addresses->Memory,0x08000000,0x2fffffff);
+ }
+#endif
+
+
+#if DBG
+ DbgPrint("HAL PCI init 8\n");
+#endif
+
+
+ //
+ // Look for PCI controllers which have known work-arounds, and make
+ // sure they are applied.
+ //
+
+ SlotNumber.u.bits.Reserved = 0;
+ //
+ // R98B fix NumberOfPcibus
+ //
+ for (BusNo=0; BusNo < HalpNumberOfAllPciBus ; 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
+
+#if DBG
+ DbgPrint("HAL PCI init 9\n");
+#endif
+
+#if DBG
+ HalpTestPci (0);
+ HalpTestPciNec(0);
+#endif
+}
+
+
+PBUS_HANDLER
+HalpAllocateAndInitPciBusHandler (
+ IN ULONG HwType,
+ IN ULONG BusNo,
+ IN BOOLEAN TestAllocation
+ )
+{
+ PBUS_HANDLER Bus;
+ PPCIPBUSDATA BusData;
+ ULONG Ponce;
+
+ Bus = HalpAllocateBusHandler (
+ PCIBus, // Interface type
+ PCIConfiguration, // Has this configuration space
+ BusNo, // bus #
+#if 0
+ Internal, // child of this bus
+ 0, // and number
+#else
+ InterfaceTypeUndefined, // R98B
+ 0,
+#endif
+ sizeof (PCIPBUSDATA) // sizeof bus specific buffer
+ );
+
+ //
+ // Fill in PCI handlers
+ //
+
+ Bus->GetBusData = (PGETSETBUSDATA) HalpGetPCIData;
+ Bus->SetBusData = (PGETSETBUSDATA) HalpSetPCIData;
+ //
+ // R98B
+ Bus->GetInterruptVector = (PGETINTERRUPTVECTOR) HalpGetSystemInterruptVector;
+ Bus->AdjustResourceList = (PADJUSTRESOURCELIST) HalpAdjustPCIResourceList;
+ Bus->AssignSlotResources = (PASSIGNSLOTRESOURCES) HalpAssignPCISlotResources;
+ Bus->BusAddresses->Dma.Limit = 0;
+ //
+ // R98B
+// Bus->TranslateBusAddress = HalpTranslatePCIBusAddress;
+ Bus->TranslateBusAddress = HalpTranslateSystemBusAddress;
+ 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;
+ //
+ // R98B
+ //
+ BusData->CommonData.Pin2Line = (PciPin2Line) HalpPCIPin2SystemLine;
+ BusData->CommonData.Line2Pin = (PciLine2Pin) HalpPCISystemLine2Pin;
+
+ //
+ // Set defaults
+ //
+
+ BusData->MaxDevice = PONCE_PCI_MAX_DEVICES;
+ BusData->GetIrqRange = (PciIrqRange) HalpGetISAFixedPCIIrq;
+
+ RtlInitializeBitMap (&BusData->DeviceConfigured,
+ BusData->ConfiguredBits, 256);
+
+ switch (HwType) {
+ case 1:
+ //
+ // Initialize access port information for Type1 handlers
+ // R98B
+ Ponce = HalpPonceNumber(BusNo);
+ BusData->Config.Type1.Address = (PULONG)&PONCE_CNTL(Ponce)->CONFA;
+ BusData->Config.Type1.Data = (ULONG)&PONCE_CNTL(Ponce)->CONFD;
+ break;
+
+ case 2:
+ // R98B Not Support Configuration Mechanism #2.
+ default:
+ // unsupport type
+ DBGMSG ("HAL: Unkown PCI type\n");
+ }
+
+ if (!TestAllocation) {
+#ifdef SUBCLASSPCI
+ HalpSubclassPCISupport (Bus, HwType);
+#endif
+ }
+
+ return Bus;
+}
+
+BOOLEAN
+HalpIsValidPCIDevice (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ )
+/*++
+
+Routine Description:
+
+ Reads the device configuration data for the given slot and
+ returns TRUE if the configuration data appears to be valid for
+ a PCI device; otherwise returns FALSE.
+
+Arguments:
+
+ BusHandler - Bus to check
+ Slot - Slot to check
+
+--*/
+
+{
+ PPCI_COMMON_CONFIG PciData;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ ULONG i, j;
+
+
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+
+ //
+ // Read device common header
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Valid device header?
+ //
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != PCI_DEVICE_TYPE) {
+
+ return FALSE;
+ }
+
+ //
+ // Check fields for reasonable values
+ //
+
+ if ((PciData->u.type0.InterruptPin && PciData->u.type0.InterruptPin > 4) ||
+ (PciData->u.type0.InterruptLine & 0x70)) {
+ return FALSE;
+ }
+
+ for (i=0; i < PCI_TYPE0_ADDRESSES; i++) {
+ j = PciData->u.type0.BaseAddresses[i];
+
+ if (j & PCI_ADDRESS_IO_SPACE) {
+
+ if (j > 0xffff) {
+ // IO port > 64k?
+ return FALSE;
+ }
+
+ } else {
+ if (j > 0xf && j < 0x80000) {
+ // Mem address < 0x8000h?
+ return FALSE;
+ }
+ }
+
+ if (Is64BitBaseAddress(j)) {
+ i += 1;
+ }
+ }
+
+ //
+ // Guess it's a valid device..
+ //
+
+ return TRUE;
+}
+
+
+
+
+
+ULONG
+HalpGetPCIData (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ The function returns the Pci bus data for a device.
+
+Arguments:
+
+ BusNumber - Indicates which bus.
+
+ VendorSpecificDevice - The VendorID (low Word) and DeviceID (High Word)
+
+ Buffer - Supplies the space to store the data.
+
+ Length - Supplies a count in bytes of the maximum amount to return.
+
+Return Value:
+
+ Returns the amount of data stored into the buffer.
+
+ If this PCI slot has never been set, then the configuration information
+ returned is zeroed.
+
+
+--*/
+{
+ PPCI_COMMON_CONFIG PciData;
+ UCHAR iBuffer[PCI_COMMON_HDR_LENGTH];
+ PPCIPBUSDATA BusData;
+ ULONG Len;
+ ULONG i, bit;
+
+ if (Length > sizeof (PCI_COMMON_CONFIG)) {
+ Length = sizeof (PCI_COMMON_CONFIG);
+ }
+
+ Len = 0;
+ PciData = (PPCI_COMMON_CONFIG) iBuffer;
+
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The user did not request any data from the common
+ // header. Verify the PCI device exists, then continue
+ // in the device specific area.
+ //
+
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, sizeof(ULONG));
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID) {
+ return 0;
+ }
+
+ } else {
+
+ //
+ // Caller requested at least some data within the
+ // common header. Read the whole header, effect the
+ // fields we need to and then copy the user's requested
+ // bytes from the header
+ //
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ //
+ // Read this PCI devices slot data
+ //
+
+ Len = PCI_COMMON_HDR_LENGTH;
+ HalpReadPCIConfig (BusHandler, Slot, PciData, 0, Len);
+
+ if (PciData->VendorID == PCI_INVALID_VENDORID ||
+ PCI_CONFIG_TYPE (PciData) != PCI_DEVICE_TYPE) {
+ PciData->VendorID = PCI_INVALID_VENDORID;
+ Len = 2; // only return invalid id
+
+ } else {
+
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, Slot, PciData);
+ }
+
+ //
+ // Has this PCI device been configured?
+ //
+
+#if 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 defined(DBG7)
+ DbgPrint("HalpSetPCIData:in\n");
+#endif
+
+
+ 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");
+ }
+#endif
+
+ //
+ // Set new PCI configuration
+ //
+
+ HalpWritePCIConfig (BusHandler, Slot, iBuffer2+Offset, Offset, Len);
+
+
+ Offset += Len;
+ Buffer += Len;
+ Length -= Len;
+ }
+
+ if (Length) {
+ if (Offset >= PCI_COMMON_HDR_LENGTH) {
+ //
+ // The remaining Buffer comes from the Device Specific
+ // area - put on the kitten gloves and write it
+ //
+ // Specific read/writes to the PCI device specific area
+ // are guarenteed:
+ //
+ // Not to read/write any byte outside the area specified
+ // by the caller. (this may cause WORD or BYTE references
+ // to the area in order to read the non-dword aligned
+ // ends of the request)
+ //
+ // To use a WORD access if the requested length is exactly
+ // a WORD long.
+ //
+ // To use a BYTE access if the requested length is exactly
+ // a BYTE long.
+ //
+
+ HalpWritePCIConfig (BusHandler, Slot, Buffer, Offset, Length);
+ Len += Length;
+ }
+ }
+
+#if defined(DBG7)
+ DbgPrint("HalpSetPCIData:out 1\n");
+#endif
+
+ return Len;
+}
+
+#if DBG
+
+ULONG HalsavePonce;
+#endif
+
+// On PONCE If device num cause master Abort!!.
+//
+ULONG
+HalpConfigMask(
+ IN PPCIPBUSDATA BusData
+ )
+{
+
+ ULONG PERRM;
+ ULONG Ponce;
+
+ // PONCE!!.
+ Ponce = ((ULONG)BusData->Config.Type1.Address & PONCE_ADDR_MASK) >> PONCE_ADDR_SHIFT;
+
+
+ // save original mask value
+ PERRM = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PERRM);
+
+ // Set Mask of PONCE.
+ //
+ WRITE_REGISTER_ULONG(
+ (PULONG)&PONCE_CNTL(Ponce)->PERRM,
+ PERRM |(PONCE_PXERR_PMABS)
+ );
+ return PERRM;
+}
+
+BOOLEAN
+HalpConfigUnMask(
+ IN PPCIPBUSDATA BusData,
+ IN ULONG PERRM
+#if DBG
+,
+PCI_SLOT_NUMBER Slot
+#endif
+ )
+{
+
+ BOOLEAN Error;
+ ULONG PAERR;
+ ULONG Ponce;
+
+
+
+ Error=FALSE;
+
+ // whitch PONCE!!.
+ Ponce = ((ULONG)BusData->Config.Type1.Address & PONCE_ADDR_MASK) >>PONCE_ADDR_SHIFT;
+
+ // Check Abort was Occured!!.
+ //
+ PAERR = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PAERR)
+ & (PONCE_PXERR_PMABS);
+ if(PAERR){
+#if DBG
+ // Abort Occured!!. So Reset
+ DbgPrint("PCI Master Abort Occured\n ");
+ DbgPrint("DeviceNumber=0x%x\n ",Slot.u.bits.DeviceNumber);
+ DbgPrint("FUnction=0x%x\n \n",Slot.u.bits.FunctionNumber);
+ DbgPrint("ULONG=0x%x\n ",(ULONG)Slot.u.AsULONG);
+#endif
+ WRITE_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PERST,PAERR);
+ Error=TRUE;
+ }
+
+ WRITE_REGISTER_ULONG((PULONG)&PONCE_CNTL(Ponce)->PERRM, PERRM );
+
+ return Error;
+}
+
+
+VOID
+HalpReadPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+
+
+ if (!HalpValidPCISlot (BusHandler, Slot)) {
+ //
+ // Invalid SlotID return no data
+ //
+
+ RtlFillMemory (Buffer, Length, (UCHAR) -1);
+ return ;
+ }
+
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) Buffer, Offset, Length,
+ PCIConfigHandler.ConfigRead);
+}
+
+VOID
+HalpWritePCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ if (!HalpValidPCISlot (BusHandler, Slot)) {
+ //
+ // Invalid SlotID do nothing
+ //
+ return ;
+ }
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) Buffer, Offset, Length,
+ PCIConfigHandler.ConfigWrite);
+}
+
+BOOLEAN
+HalpValidPCISlot (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot
+ )
+{
+ PCI_SLOT_NUMBER Slot2;
+ PPCIPBUSDATA BusData;
+ UCHAR HeaderType;
+ ULONG i;
+
+ ULONG IdValue;
+ ULONG PERRM;
+
+
+ IdValue = 0x0;
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+
+ if (Slot.u.bits.Reserved != 0) {
+
+ return FALSE;
+ }
+ // R98B Ponce max device is 21
+
+#if 0 //kugi 1214
+ if (Slot.u.bits.DeviceNumber == 0) {
+
+ return FALSE;
+ }
+#endif
+
+#if 1
+ // Hack Hack
+ // display is !cirrus. But Driver installed cirrus.
+ // cirrus configration must do fail to panic.
+ // "DISPLAY ......."
+ //
+ // If Booted display is not CIRRUS.
+ // PCI Configration can't see CIRRUS.
+ //
+ if( !HalpCirrusAlive && HalpCirrusDel &&
+ (BusHandler->BusNumber == HalpStartPciBusNumberPonce[1]) &&
+ (Slot.u.bits.DeviceNumber == 0x4)
+ )
+ return FALSE;
+#endif
+
+
+
+ // R98B Ponce max device is 21
+ // 0 <= device number <= 21 (PONCE_PCI_MAX_DEVICES)
+ //
+ if ( (
+ (BusHandler->BusNumber == HalpStartPciBusNumberPonce[0]) ||
+ (BusHandler->BusNumber == HalpStartPciBusNumberPonce[1])
+ ) &&
+
+ (Slot.u.bits.DeviceNumber > 6)
+ )
+ {
+ return FALSE;
+ }else if (Slot.u.bits.DeviceNumber >= BusData->MaxDevice) {
+ return FALSE;
+ }
+
+
+ // Check Actually device is there!!. Do Vendor ID register Read.
+ //
+ PERRM=HalpConfigMask(BusData);
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) &IdValue, 0, 4,
+ PCIConfigHandler.ConfigRead);
+
+
+#if DBG
+ HalpConfigUnMask(BusData,PERRM,Slot);
+#else
+ HalpConfigUnMask(BusData,PERRM);
+#endif
+
+#if DBG
+ if(Slot.u.bits.FunctionNumber !=Slot.u.bits.FunctionNumber){
+ DbgPrint("BAd Function = 0x%x\n",Slot.u.bits.FunctionNumber);
+ DbgPrint("Bad Function ato= 0x%x\n",Slot.u.bits.FunctionNumber);
+ }
+#endif
+
+
+ if ((IdValue & 0x0000ffff) == 0xffff){
+#if defined(DBG9)
+ DbgPrint("ID Value Function = 0x%x",Slot.u.bits.FunctionNumber);
+ DbgPrint("ID Value Device = 0x%x",Slot.u.bits.DeviceNumber);
+ DbgPrint("ID Value BusNum = 0x%x\n",BusHandler->BusNumber);
+#endif
+
+ return FALSE;
+ }
+
+#if defined(INTEL_9036)
+{
+ ULONG RevisionID;
+
+ PERRM=HalpConfigMask(BusData);
+
+ HalpPCIConfig (BusHandler, Slot, (PUCHAR) &RevisionID, 0x8, 4,
+ PCIConfigHandler.ConfigRead);
+
+ if( (IdValue & 0x0000ffff)==0x8086 &&
+ (IdValue & 0xffff0000)==0x12260000 &&
+ (RevisionID & 0xff) <=0x3
+ ){
+ intel_9036=TRUE;
+#if DBG
+ DbgPrint("EtherExpress tm PRO/PCI Found!!\n");
+#endif
+ }else{
+ intel_9036=FALSE;
+ }
+#if DBG
+ HalpConfigUnMask(BusData,PERRM,Slot);
+#else
+ HalpConfigUnMask(BusData,PERRM);
+#endif
+}
+#endif
+
+ 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) {
+#if defined(DBG9)
+ DbgPrint("Header bad type = 0x%x\n",HeaderType);
+#endif
+
+
+ // this device doesn't exists or doesn't support MULTIFUNCTION types
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+VOID
+HalpPCIConfig (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PUCHAR Buffer,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN FncConfigIO *ConfigIO
+ )
+{
+ KIRQL OldIrql;
+ ULONG i;
+ UCHAR State[20];
+ PPCIPBUSDATA BusData;
+
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+ PCIConfigHandler.Synchronize (BusHandler, Slot, &OldIrql, State);
+
+ while (Length) {
+ i = PCIDeref[Offset % sizeof(ULONG)][Length % sizeof(ULONG)];
+ i = ConfigIO[i] (BusData, State, Buffer, Offset);
+ Offset += i;
+ Buffer += i;
+ Length -= i;
+ }
+
+ PCIConfigHandler.ReleaseSynchronzation (BusHandler, OldIrql);
+}
+
+VOID HalpPCISynchronizeType1 (
+ IN PBUS_HANDLER BusHandler,
+ IN PCI_SLOT_NUMBER Slot,
+ IN PKIRQL Irql,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1
+ )
+{
+ ULONG Ponce;
+ //
+ // Initialize PciCfg1
+ //
+
+ PciCfg1->u.AsULONG = 0;
+ //
+ // First PCIBus Number of PONCE must be 0. So Conver System(NT) BusNumber
+ // H/W required BusNumber.
+ //
+ Ponce = HalpPonceNumber(BusHandler->BusNumber);
+ PciCfg1->u.bits.BusNumber = BusHandler->BusNumber - HalpStartPciBusNumberPonce[Ponce];
+ 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 (HIGH_LEVEL, Irql);
+ 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;
+#if 0 //snes
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1.u.AsULONG);
+#else
+// dame READ_PORT_ULONG (BusData->Config.Type1.Data);
+// ok demo moxtuto eehouhouga aru KeStallExecutionProcessor(20);
+KeStallExecutionProcessor(20);
+
+#endif
+ //
+ // Release spinlock
+ //
+
+ if (!HalpDoingCrashDump) {
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql);
+ }
+}
+
+
+ULONG
+HalpPCIReadUcharType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+ ULONG i;
+
+ i = Offset % sizeof(ULONG);
+ PciCfg1->u.bits.RegisterNumber = Offset / sizeof(ULONG);
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1->u.AsULONG);
+#if defined(INTEL_9036)
+ if(intel_9036){
+ *Buffer = *((PUCHAR)(& READ_PORT_ULONG ((PULONG) BusData->Config.Type1.Data))+i);
+ }else
+#endif
+ *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);
+#if defined(INTEL_9036)
+ {
+ ULONG data;
+
+ if(intel_9036){
+ data = READ_PORT_ULONG ((PULONG) BusData->Config.Type1.Data);
+ *((PUCHAR)(&data)+i) = *Buffer;
+// WRITE_PORT_ULONG (PUCHAR) (BusData->Config.Type1.Data + i), data);
+#if 1 //SNES WORK_AROUND
+ READ_PORT_ULONG ((PULONG) (BusData->Config.Type1.Data ));
+#endif
+ WRITE_PORT_ULONG (BusData->Config.Type1.Address, PciCfg1->u.AsULONG);
+ WRITE_PORT_ULONG ((PULONG) BusData->Config.Type1.Data, data);
+#if 1 //SNES WORK_AROUND
+ READ_PORT_ULONG ((PULONG) (BusData->Config.Type1.Data ));
+#endif
+ return sizeof (UCHAR);
+ }
+ }
+#endif
+
+ WRITE_PORT_UCHAR ((PUCHAR) BusData->Config.Type1.Data + i, *Buffer);
+
+#if 1 //SNES WORK_AROUND
+ READ_PORT_UCHAR ((PUCHAR) (BusData->Config.Type1.Data + i));
+#endif
+ 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));
+#if 1 //SNES WORK_AROUND
+ READ_PORT_USHORT ((PUSHORT) (BusData->Config.Type1.Data + i));
+#endif
+
+ return sizeof (USHORT);
+}
+
+ULONG
+HalpPCIWriteUlongType1 (
+ IN PPCIPBUSDATA BusData,
+ IN PPCI_TYPE1_CFG_BITS PciCfg1,
+ IN PUCHAR Buffer,
+ IN ULONG Offset
+ )
+{
+#if 1
+ extern volatile ULONG DUMMYADDRS[];
+#endif
+ 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));
+
+#if 1
+ //
+ // Hack Hack.
+ //
+ if(BusData->Config.Type1.Address == (PULONG)&PONCE_CNTL(1)->CONFA &&
+ PciCfg1->u.bits.BusNumber == 0 &&
+ PciCfg1->u.bits.DeviceNumber == 0x04 &&
+ PciCfg1->u.bits.RegisterNumber== (0x14 / 4 ) &&
+ (*((PULONG) Buffer) & 0xffff0000) == 0
+ ){
+ DUMMYADDRS[1]= DUMMYADDRS[4]= (*((PULONG) Buffer) & 0xfffc) + 0xBc4003c7;
+#if DBG
+ DbgPrint("DUMMYADDRS[1] = 0x%x\n", DUMMYADDRS[1]);
+#endif
+ }
+#endif
+
+#if 1 //SNES WORK_AROUND
+ READ_PORT_ULONG ((PULONG) (BusData->Config.Type1.Data ));
+#endif
+
+ return sizeof (ULONG);
+}
+
+
+NTSTATUS
+HalpAssignPCISlotResources (
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName OPTIONAL,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ IN ULONG Slot,
+ IN OUT PCM_RESOURCE_LIST *pAllocatedResources
+ )
+/*++
+
+Routine Description:
+
+ Reads the targeted device to determine it's required resources.
+ Calls IoAssignResources to allocate them.
+ Sets the targeted device with it's assigned resoruces
+ and returns the assignments to the caller.
+
+Arguments:
+
+Return Value:
+
+ STATUS_SUCCESS or error
+
+--*/
+{
+ NTSTATUS status;
+ PUCHAR WorkingPool;
+ PPCI_COMMON_CONFIG PciData, PciOrigData, PciData2;
+ PCI_SLOT_NUMBER PciSlot;
+ PPCIPBUSDATA BusData;
+ PIO_RESOURCE_REQUIREMENTS_LIST CompleteList;
+ PIO_RESOURCE_DESCRIPTOR Descriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor;
+ ULONG BusNumber;
+ ULONG i, j, m, length, memtype;
+ ULONG NoBaseAddress, RomIndex, Option;
+ PULONG BaseAddress[PCI_TYPE0_ADDRESSES + 1];
+ PULONG OrigAddress[PCI_TYPE0_ADDRESSES + 1];
+ BOOLEAN Match, EnableRomBase;
+#if 0
+ ULONG Ponce;
+#endif
+
+ *pAllocatedResources = NULL;
+ PciSlot = *((PPCI_SLOT_NUMBER) &Slot);
+#if 1 //org SNES
+ BusNumber = BusHandler->BusNumber;
+#else
+ Ponce = HalpPonceNumber(BusHandler->BusNumber);
+ BusNumber = BusHandler->BusNumber - HalpStartPciBusNumberPonce[Ponce];
+#endif
+ 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) {
+#if DBG
+ DbgPrint ("HalAssign faild return 0\n");
+#endif
+ 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);
+#if DBG
+ DbgPrint ("HalAssign faild return 1\n");
+#endif
+
+ 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);
+#if DBG
+ DbgPrint ("HalAssign faild return \n");
+#endif
+
+
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+ //
+ // If the BIOS doesn't have the device's ROM enabled, then we won't
+ // enable it either. Remove it from the list.
+ //
+
+ EnableRomBase = TRUE;
+ if (!(*BaseAddress[RomIndex] & PCI_ROMADDRESS_ENABLED)) {
+ ASSERT (RomIndex+1 == NoBaseAddress);
+ EnableRomBase = FALSE;
+ NoBaseAddress -= 1;
+ }
+
+ //
+ // Set resources to all bits on to see what type of resources
+ // are required.
+ //
+
+ for (j=0; j < NoBaseAddress; j++) {
+ *BaseAddress[j] = 0xFFFFFFFF;
+ }
+
+ PciData->Command &= ~(PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE);
+ *BaseAddress[RomIndex] &= ~PCI_ROMADDRESS_ENABLED;
+ HalpWritePCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+ HalpReadPCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ // note type0 & type1 overlay ROMBaseAddress, InterruptPin, and InterruptLine
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, PciSlot, PciData);
+
+ //
+ // Build an IO_RESOURCE_REQUIREMENTS_LIST for the PCI device
+ //
+
+ CompleteList->InterfaceType = PCIBus;
+ CompleteList->BusNumber = BusNumber;
+ CompleteList->SlotNumber = Slot;
+ CompleteList->AlternativeLists = 1;
+
+ CompleteList->List[0].Version = 1;
+ CompleteList->List[0].Revision = 1;
+
+ Descriptor = CompleteList->List[0].Descriptors;
+
+ //
+ // If PCI device has an interrupt resource, add it
+ //
+
+ if (PciData->u.type0.InterruptPin) {
+ CompleteList->List[0].Count++;
+
+ Descriptor->Option = 0;
+ Descriptor->Type = CmResourceTypeInterrupt;
+ Descriptor->ShareDisposition = CmResourceShareShared;
+ Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+
+ // Fill in any vector here - we'll pick it back up in
+ // HalAdjustResourceList and adjust it to it's allowed settings
+ Descriptor->u.Interrupt.MinimumVector = 0;
+ Descriptor->u.Interrupt.MaximumVector = 0xff;
+ Descriptor++;
+ }
+
+ //
+ // Add a memory/port resoruce for each PCI resource
+ //
+
+ // 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 (!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;
+ }
+
+ //
+ // Add this IO range
+ //
+
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO;
+
+ Descriptor->u.Port.Length = length;
+ Descriptor->u.Port.Alignment = length;
+ Descriptor->u.Port.MaximumAddress.LowPart = m;
+
+ } else {
+
+ memtype = i & PCI_ADDRESS_MEMORY_TYPE_MASK;
+
+ Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+ if (j == RomIndex) {
+ // this is a ROM address
+ Descriptor->Flags = CM_RESOURCE_MEMORY_READ_ONLY;
+ }
+
+ if (i & PCI_ADDRESS_MEMORY_PREFETCHABLE) {
+ Descriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE;
+ }
+
+ if (!Is64BitBaseAddress(i) &&
+ (j == RomIndex ||
+ PciOrigData->Command & PCI_ENABLE_MEMORY_SPACE)) {
+
+ //
+ // The memory range is/was already enabled at some location, add that
+ // as it's preferred setting.
+ //
+
+ Descriptor->Type = CmResourceTypeMemory;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Option = IO_RESOURCE_PREFERRED;
+
+ Descriptor->u.Port.Length = length;
+ Descriptor->u.Port.Alignment = length;
+ Descriptor->u.Port.MinimumAddress.LowPart = *OrigAddress[j] & ~0xF;
+ Descriptor->u.Port.MaximumAddress.LowPart =
+ Descriptor->u.Port.MinimumAddress.LowPart + length - 1;
+
+ CompleteList->List[0].Count++;
+ Descriptor++;
+
+ Descriptor->Flags = Descriptor[-1].Flags;
+ Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
+ }
+
+ //
+ // Add this memory range
+ //
+
+ Descriptor->Type = CmResourceTypeMemory;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+
+ Descriptor->u.Memory.Length = length;
+ Descriptor->u.Memory.Alignment = length;
+ Descriptor->u.Memory.MaximumAddress.LowPart = m;
+
+ if (memtype == PCI_TYPE_20BIT && m > 0xFFFFF) {
+ // limit to 20 bit address
+ Descriptor->u.Memory.MaximumAddress.LowPart = 0xFFFFF;
+ }
+ }
+
+ 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
+ //
+
+ status = IoAssignResources (
+ RegistryPath,
+ DriverClassName,
+ DriverObject,
+ DeviceObject,
+ CompleteList,
+ pAllocatedResources
+ );
+
+ if (!NT_SUCCESS(status)) {
+#if DBG
+ DbgPrint ("HalAssign Io Assgin faild: = 0x%x\n",status);
+#endif
+
+
+ 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;
+#if DBG
+ DbgPrint ("Vector: = 0x%x\n",PciData->u.type0.InterruptLine);
+#endif
+ 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
+
+ DbgPrint("HalAssign: Port Address %x\n", *BaseAddress[j]);
+ DbgPrint("HalAssign: BusNumber %x\n",BusHandler->BusNumber );
+#endif
+ } else {
+ *BaseAddress[j] = CmDescriptor->u.Memory.Start.LowPart;
+#if DBG
+ DbgPrint("HalAssign: Memory Address %x\n", *BaseAddress[j]);
+ DbgPrint("HalAssign: BusNumber %x\n",BusHandler->BusNumber );
+#endif
+
+ }
+ CmDescriptor++;
+ }
+
+ if (Is64BitBaseAddress(i)) {
+ // skip upper 32 bits
+ j++;
+ }
+ }
+
+ // koko de new ni kakikomunoda..
+ // Turn off decodes, then set new addresses
+ //
+
+ HalpWritePCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // Read configuration back and verify address settings took
+ //
+
+ HalpReadPCIConfig(BusHandler, PciSlot, PciData2, 0, PCI_COMMON_HDR_LENGTH);
+
+ Match = TRUE;
+#if 0 //SNE org
+ if (PciData->u.type0.InterruptLine != PciData2->u.type0.InterruptLine ||
+#else
+ if(
+#endif
+ PciData->u.type0.InterruptPin != PciData2->u.type0.InterruptPin ||
+ PciData->u.type0.ROMBaseAddress != PciData2->u.type0.ROMBaseAddress) {
+
+#if DBG
+ DbgPrint ("W InterruptLine = 0x%x\n",PciData->u.type0.InterruptLine);
+ DbgPrint ("W InterruptPinn = 0x%x\n",PciData->u.type0.InterruptPin);
+ DbgPrint ("W RomBaseAddress= 0x%x\n",PciData->u.type0.ROMBaseAddress);
+
+ DbgPrint ("R InterruptLine = 0x%x\n",PciData2->u.type0.InterruptLine);
+ DbgPrint ("R InterruptPinn = 0x%x\n",PciData2->u.type0.InterruptPin);
+ DbgPrint ("R RomBaseAddress= 0x%x\n",PciData2->u.type0.ROMBaseAddress);
+
+#endif
+
+
+ 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;
+ }
+
+ //
+ // 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 //intel networktest
+ if (PciData.u.type0.BaseAddresses[j] == 0x10001) {
+ DbgPrint (" Express INTEL\n");
+ PciData.u.type0.BaseAddresses[j] = 0x5001;
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ }
+#endif
+ }
+ }
+
+#if 0
+ if (PciData.u.type0.ROMBaseAddress == 0xC08001) {
+
+ PciData.u.type0.ROMBaseAddress = 0xC00001;
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ HalGetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &PciData,
+ sizeof (PciData)
+ );
+
+ DbgPrint ("\n Bogus rom address, edit yields:%08lx",
+ PciData.u.type0.ROMBaseAddress);
+ }
+#endif
+
+ if (k) {
+ DbgPrint ("\n");
+ }
+
+ if (PciData.VendorID == 0x8086) {
+ // dump complete buffer
+ DbgPrint ("Command %x, Status %x, BIST %x\n",
+ PciData.Command, PciData.Status,
+ PciData.BIST
+ );
+
+ DbgPrint ("CacheLineSz %x, LatencyTimer %x",
+ PciData.CacheLineSize, PciData.LatencyTimer
+ );
+
+ for (j=0; j < 192; j++) {
+ if ((j & 0xf) == 0) {
+ DbgPrint ("\n%02x: ", j + 0x40);
+ }
+ DbgPrint ("%02x ", PciData.DeviceSpecific[j]);
+ }
+ DbgPrint ("\n");
+ }
+
+
+#if 0
+ //
+ // now print original data
+ //
+
+ if (OrigData.u.type0.ROMBaseAddress) {
+ DbgPrint (" oROM:%08lx", OrigData.u.type0.ROMBaseAddress);
+ }
+
+ DbgPrint ("\n");
+ k = 0;
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ if (OrigData.u.type0.BaseAddresses[j]) {
+ DbgPrint (" oAd%d:%08lx", j, OrigData.u.type0.BaseAddresses[j]);
+ k = 1;
+ }
+ }
+
+ //
+ // Restore original settings
+ //
+
+ HalSetBusData (
+ PCIConfiguration,
+ bus,
+ SlotNumber.u.AsULONG,
+ &OrigData,
+ sizeof (PciData)
+ );
+#endif
+
+ //
+ // Next
+ //
+
+ if (k) {
+ DbgPrint ("\n\n");
+ }
+ }
+ }
+ }
+ DbgBreakPoint ();
+}
+#endif
diff --git a/private/ntos/nthals/halr98b/mips/rxpciint.c b/private/ntos/nthals/halr98b/mips/rxpciint.c
new file mode 100644
index 000000000..717d6cf3a
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxpciint.c
@@ -0,0 +1,615 @@
+/*++
+
+
+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:
+
+
+--*/
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+
+ULONG PciIsaIrq;
+ULONG HalpEisaELCR;
+BOOLEAN HalpDoingCrashDump = FALSE;
+BOOLEAN HalpPciLockSettings;
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE,HalpGetPCIIntOnISABus)
+#pragma alloc_text(PAGE,HalpAdjustPCIResourceList)
+#pragma alloc_text(PAGE,HalpGetISAFixedPCIIrq)
+#endif
+//
+// PCI Configuration Type #0 Area Offset 0x3D: Interrupt Pin
+//
+// Interrupt Pin INT
+// ----------------+-----------------
+// 0 :Non Use Interrupt
+// 1 :INT A
+// 2 :INT B
+// 3 :INT C
+// 4 :INT D
+//
+// Device or Phys Slot # :PONCE # : Device Number:
+// ------------------------+--------+------------------------------
+// PCEB/ESC :PONCE0 : 1 :PCI/EISA Bridge
+// SLOT #4 :PONCE0 : 2 :
+// SLOT #5 :PONCE0 : 3 :
+// SLOT #6 :PONCE0 : 4 :
+// SLOT #7 :PONCE0 : 5 :
+// ------------------------+--------+------------------------------
+// 53C825#0 :PONCE1 : 1 :SCSI(Wide)
+// 53C825#1 :PONCE1 : 2 :SCSI(Narrow)
+// SLOT #1 DEC21140 :PONCE1 : 3 :Ehternet Card
+// GD5430 :PONCE1 : 4 :VGA
+// SLOT #2 :PONCE1 : 5 :
+// SLOT #3 :PONCE1 : 6 :
+// ------------------------+--------+------------------------------
+
+// (See 8-15)
+// R98B_PCIPinToLineTableForPonceX[] is Convert table for PCI Pin OutPut to Line.
+// Line is Same as Columbus IPR Rgister Bit3.
+//
+// Table Access is [DeviceNumber][Interrupt Pin].
+//
+// INTA is Per Device/Slot.
+// INTB,INTC,INTD was Shared
+//
+UCHAR R98B_PCIPinTolineTable[R98B_MAX_PONCE][7][5] = {
+#if 0
+ { // { Interrupt NonUse,INTA,INTB,INTC,INTD}
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #0 is none. (DUMMY)
+ { RFU, 13,RFU,RFU,RFU }, // Device Num #1 is PCEB/ESC
+ { RFU, 25, 8, 5, 2 }, // Device Num #2 is Slot #7
+ { RFU, 24, 8, 5, 2 }, // Device Num #3 is Slot #6
+ { RFU, 23, 8, 5, 2 }, // Device Num #4 is Slot #5
+ { RFU, 22, 8, 5, 2 }, // Device Num #5 is Slot #4
+ { RFU,RFU,RFU,RFU,RFU } // Device Num #6 is none. (DUMMY)
+ },
+
+ { // { Interrupt NonUse,INTA,INTB,INTC,INTD}
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #0 is none. (DUMMY)
+ { RFU, 31,RFU,RFU,RFU }, // Device Num #1 is 53C825#0 SCSI(Wide)
+ { RFU, 30,RFU,RFU,RFU }, // Device Num #2 is 53C825#1 SCSI(Narrow)
+ { RFU, 29, 7, 4, 1 }, // Device Num #3 is Slot #1 DEC21440 Ether
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #4 is GD5430 nonused.
+ { RFU, 21, 7, 4, 1 }, // Device Num #5 is Slot #9
+ { RFU, 20, 7, 4, 1 } // Device Num #6 is Slot #8
+ },
+
+ { // { Interrupt NonUse,INTA,INTB,INTC,INTD}
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #0
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #1
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #2
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #3
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #4
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #5
+ { RFU,RFU,RFU,RFU,RFU } // Device Num #6
+ }
+#endif
+ { // { Interrupt NonUse,INTA,INTB,INTC,INTD}
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #0 is none. (DUMMY)
+ { RFU, 13,RFU,RFU,RFU }, // Device Num #1 is PCEB/ESC
+ { RFU, 5, 7, 15, 12 }, // Device Num #2 is Slot #7
+ { RFU, 4, 7, 15, 12 }, // Device Num #3 is Slot #6
+ { RFU, 3, 7, 15, 12 }, // Device Num #4 is Slot #5
+ { RFU, 2, 7, 15, 12 }, // Device Num #5 is Slot #4
+ { RFU,RFU,RFU,RFU,RFU } // Device Num #6 is none. (DUMMY)
+ },
+
+ { // { Interrupt NonUse,INTA,INTB,INTC,INTD}
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #0 is none. (DUMMY)
+ { RFU, 31,RFU,RFU,RFU }, // Device Num #1 is 53C825#0 SCSI(Wide)
+ { RFU, 30,RFU,RFU,RFU }, // Device Num #2 is 53C825#1 SCSI(Narrow)
+ { RFU, 9, 6, 14, 11 }, // Device Num #3 is Slot #1 DEC21440 Ethe
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #4 is GD5430 nonused.
+ { RFU, 1, 6, 14, 11 }, // Device Num #5 is Slot #9
+ { RFU, 10, 6, 14, 11 } // Device Num #6 is Slot #8
+ },
+
+ { // { Interrupt NonUse,INTA,INTB,INTC,INTD}
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #0
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #1
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #2
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #3
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #4
+ { RFU,RFU,RFU,RFU,RFU }, // Device Num #5
+ { RFU,RFU,RFU,RFU,RFU } // Device Num #6
+ }
+};
+UCHAR HalpPciLogical2PhysicalInt[32]=
+ {0,21,22,23,24,25, 7, 8, 0,29,20, 1, 2,13, 4, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,30,31};
+
+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
+HalpPCIPin2SystemLine (
+ 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.
+
+--*/
+{
+ ULONG Ponce;
+ PPCIBUSDATA BusData;
+ PBUS_HANDLER tBusHandler, pBusHandler;
+ PCI_SLOT_NUMBER bSlotNumber;
+ ULONG ActualSlotNumber;
+ ULONG PinNo;
+
+ if (!PciData->u.type0.InterruptPin) {
+ return ;
+ }
+
+ Ponce = HalpPonceNumber ( BusHandler->BusNumber );
+
+ tBusHandler = BusHandler;
+ pBusHandler = BusHandler->ParentHandler;
+
+ //
+ // My Mother Search!!
+ //
+ if(pBusHandler)
+ for(;TRUE;){
+ if (pBusHandler->BusNumber != HalpStartPciBusNumberPonce[Ponce]) {
+ tBusHandler = pBusHandler;
+ pBusHandler = pBusHandler->ParentHandler;
+ } else {
+ break;
+ }
+ }
+
+ BusData = (PPCIBUSDATA)tBusHandler->BusData;
+
+ if(pBusHandler)
+ bSlotNumber = BusData->ParentSlot;
+ else
+ bSlotNumber = SlotNumber;
+
+ ActualSlotNumber = bSlotNumber.u.bits.DeviceNumber;
+
+ if(pBusHandler)
+ PinNo = (PciData->u.type0.InterruptPin + SlotNumber.u.bits.DeviceNumber) % 4;
+ else
+ PinNo = PciData->u.type0.InterruptPin;
+
+ //
+ //
+ //
+ PciData->u.type0.InterruptLine =
+ (UCHAR) R98B_PCIPinTolineTable[Ponce][ActualSlotNumber][PinNo];
+
+}
+
+
+
+VOID
+HalpPCISystemLine2Pin (
+ 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.
+
+--*/
+{
+ ULONG Ponce;
+ PPCIBUSDATA BusData;
+ PBUS_HANDLER tBusHandler, pBusHandler;
+ PCI_SLOT_NUMBER bSlotNumber;
+ ULONG ActualSlotNumber;
+ ULONG PinNo;
+
+ if (!PciNewData->u.type0.InterruptPin) {
+ return ;
+ }
+
+
+ Ponce = HalpPonceNumber ( BusHandler->BusNumber );
+
+ tBusHandler = BusHandler;
+ pBusHandler = BusHandler->ParentHandler;
+
+ //
+ // My Mother Search!!
+ //
+
+ if(pBusHandler)
+ for(;TRUE;){
+ if (pBusHandler->BusNumber != HalpStartPciBusNumberPonce[Ponce]) {
+ tBusHandler = pBusHandler;
+ pBusHandler = pBusHandler->ParentHandler;
+ } else {
+ break;
+ }
+ }
+
+ BusData = (PPCIBUSDATA)tBusHandler->BusData;
+
+ if(pBusHandler)
+ bSlotNumber = BusData->ParentSlot;
+ else
+ bSlotNumber = SlotNumber;
+
+ ActualSlotNumber = bSlotNumber.u.bits.DeviceNumber;
+
+ if(pBusHandler)
+ PinNo = (PciOldData->u.type0.InterruptPin + SlotNumber.u.bits.DeviceNumber) % 4;
+ else
+ PinNo = PciOldData->u.type0.InterruptPin;
+
+ //
+ //
+ //
+ PciNewData->u.type0.InterruptLine =
+ (UCHAR) R98B_PCIPinTolineTable[Ponce][ActualSlotNumber][PinNo];
+
+
+#if DBG
+ if (PciNewData->u.type0.InterruptLine != PciOldData->u.type0.InterruptLine ||
+ PciNewData->u.type0.InterruptPin != PciOldData->u.type0.InterruptPin) {
+ DbgPrint ("HalpPCISystem2Pin: System does not support changing the PCI device interrupt routing\n");
+
+// DbgPrint ("N Line = 0x%x\n",PciNewData->u.type0.InterruptLine);
+// DbgPrint ("O Line = 0x%x\n",PciOldData->u.type0.InterruptLine);
+// DbgPrint ("N Pin = 0x%x\n",PciNewData->u.type0.InterruptPin);
+// DbgPrint ("O Pin = 0x%x\n",PciOldData->u.type0.InterruptPin);
+// DbgBreakPoint ();
+ }
+#endif
+}
+
+#if !defined(SUBCLASSPCI)
+
+VOID
+HalpPCIAcquireType2Lock (
+ PKSPIN_LOCK SpinLock,
+ PKIRQL Irql
+ )
+{
+ if (!HalpDoingCrashDump) {
+ KeRaiseIrql (HIGH_LEVEL, Irql);
+ KiAcquireSpinLock (SpinLock);
+ } else {
+ *Irql = HIGH_LEVEL;
+ }
+}
+
+
+VOID
+HalpPCIReleaseType2Lock (
+ PKSPIN_LOCK SpinLock,
+ KIRQL Irql
+ )
+{
+ if (!HalpDoingCrashDump) {
+ KiReleaseSpinLock (SpinLock);
+ KeLowerIrql (Irql);
+ }
+}
+
+#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;
+ PSUPPORTED_RANGE Range;
+ PSUPPORTED_RANGES SupportedRanges;
+ PPCI_COMMON_CONFIG PciData, PciOrigData;
+ UCHAR buffer[PCI_COMMON_HDR_LENGTH];
+ UCHAR buffer2[PCI_COMMON_HDR_LENGTH];
+ BOOLEAN UseBusRanges;
+ ULONG i, j, RomIndex, length, ebit;
+ ULONG Base[PCI_TYPE0_ADDRESSES + 1];
+ PULONG BaseAddress[PCI_TYPE0_ADDRESSES + 1];
+
+ 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;
+ }
+
+ SupportedRanges = NULL;
+ UseBusRanges = TRUE;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+
+ if (HalpPciLockSettings) {
+
+ PciData = (PPCI_COMMON_CONFIG) buffer;
+ PciOrigData = (PPCI_COMMON_CONFIG) buffer2;
+ HalpReadPCIConfig (BusHandler, PciSlot, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ //
+ // If this is a device, and it current has its decodes enabled,
+ // then use the currently programmed ranges only
+ //
+
+ if (PCI_CONFIG_TYPE(PciData) == 0 &&
+ (PciData->Command & (PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE))) {
+
+ //
+ // Save current settings
+ //
+
+ RtlMoveMemory (PciOrigData, PciData, PCI_COMMON_HDR_LENGTH);
+
+ for (j=0; j < PCI_TYPE0_ADDRESSES; j++) {
+ BaseAddress[j] = &PciData->u.type0.BaseAddresses[j];
+ }
+ BaseAddress[j] = &PciData->u.type0.ROMBaseAddress;
+ RomIndex = j;
+
+ //
+ // Write all one-bits to determine lengths for each address
+ //
+
+ for (j=0; j < PCI_TYPE0_ADDRESSES + 1; j++) {
+ Base[j] = *BaseAddress[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);
+
+ //
+ // restore original settings
+ //
+
+ 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)
+ );
+
+ //
+ // Build a memory & io range list of just the ranges already
+ // programmed into the device
+ //
+
+ UseBusRanges = FALSE;
+ SupportedRanges = HalpAllocateNewRangeList();
+ if (!SupportedRanges) {
+ goto CleanUp;
+ }
+
+ *BaseAddress[RomIndex] &= ~PCI_ADDRESS_IO_SPACE;
+ for (j=0; j < PCI_TYPE0_ADDRESSES + 1; j++) {
+
+ i = *BaseAddress[j];
+
+ if (i & PCI_ADDRESS_IO_SPACE) {
+ length = 1 << 2;
+ Range = &SupportedRanges->IO;
+ ebit = PCI_ENABLE_IO_SPACE;
+
+ } else {
+ length = 1 << 4;
+ Range = &SupportedRanges->Memory;
+ ebit = PCI_ENABLE_MEMORY_SPACE;
+
+ if (i & PCI_ADDRESS_MEMORY_PREFETCHABLE) {
+ Range = &SupportedRanges->PrefetchMemory;
+ }
+ }
+
+ Base[j] &= ~(length-1);
+ while (!(i & length) && length) {
+ length <<= 1;
+ }
+
+ if (j == RomIndex &&
+ !(PciOrigData->u.type0.ROMBaseAddress & PCI_ROMADDRESS_ENABLED)) {
+
+ // range not enabled, don't use it
+ length = 0;
+ }
+
+ if (length) {
+ if (!(PciOrigData->Command & ebit)) {
+ // range not enabled, don't use preprogrammed values
+ UseBusRanges = TRUE;
+ }
+
+ if (Range->Limit >= Range->Base) {
+ Range->Next = ExAllocatePool (PagedPool, sizeof (SUPPORTED_RANGE));
+ Range = Range->Next;
+ if (!Range) {
+ goto CleanUp;
+ }
+
+ Range->Next = NULL;
+ }
+
+ Range->Base = Base[j];
+ Range->Limit = Base[j] + length - 1;
+ }
+
+ if (Is64BitBaseAddress(i)) {
+ // skip upper half of 64 bit address since this processor
+ // only supports 32 bits of address space
+ j++;
+ }
+ }
+ }
+ }
+
+ //
+ // Adjust resources
+ //
+
+ Status = HaliAdjustResourceListRange (
+ UseBusRanges ? BusHandler->BusAddresses : SupportedRanges,
+ Interrupt,
+ pResourceList
+ );
+
+CleanUp:
+ if (SupportedRanges) {
+ HalpFreeRangeList (SupportedRanges);
+ }
+
+ 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;
+ PPCIPBUSDATA BusData;
+
+ 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
+
+ //
+ // R98B
+ //
+ BusData = (PPCIPBUSDATA) BusHandler->BusData;
+ BusData->CommonData.Pin2Line (BusHandler, RootHandler, PciSlot, PciData);
+
+ (*Interrupt)->Base = PciData->u.type0.InterruptLine;
+ (*Interrupt)->Limit = PciData->u.type0.InterruptLine;
+ return STATUS_SUCCESS;
+}
+
+
diff --git a/private/ntos/nthals/halr98b/mips/rxsysbus.c b/private/ntos/nthals/halr98b/mips/rxsysbus.c
new file mode 100644
index 000000000..c2e592eb0
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/rxsysbus.c
@@ -0,0 +1,214 @@
+/*++
+
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ ixsysbus.c
+
+Abstract:
+
+Author:
+
+Environment:
+
+Revision History:
+
+
+--*/
+
+#include "halp.h"
+
+ULONG HalpDefaultInterruptAffinity;
+extern UCHAR HalpPciLogical2PhysicalInt[];
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE,HalpGetSystemInterruptVector)
+#endif
+
+
+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;
+#if DBG
+ PULONG datap;
+ PULONG datap2;
+#endif
+
+ 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;
+
+
+#if 0
+
+ datap = (PULONG)&(BusAddress.QuadPart);
+
+ DbgPrint("HAL T BusAddress HIGH:LOW = %08lX:%08lX \n",
+ datap[1],
+ datap[0]
+ );
+ datap = (PULONG)&(pRange->Base);
+ datap2 =(PULONG)&(pRange->Limit);
+ DbgPrint("HAL T RBase-RLimit HIGH:LOW = %08lX:%08lX -- %08lX:%08lX\n",
+ datap[1],
+ datap[0],
+ datap2[1],
+ datap2[0]
+ );
+
+ datap = (PULONG)&(pRange->SystemBase);
+ DbgPrint("HAL T RSysbase HIGH:LOW = %08lX:%08lX \n",
+ datap[1],
+ datap[0]
+ );
+
+ DbgPrint("HAL T BusNo = (0x%x) AddrSpace = 0x%x TransAddr HIGH:LOW = %08lX:%08lX \n",
+ BusHandler->BusNumber,
+ *AddressSpace,
+ TranslatedAddress->u.HighPart,
+ TranslatedAddress->u.LowPart
+ );
+#endif
+
+
+ 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.
+
+--*/
+{
+ ULONG SystemVector;
+ ULONG NumCpu;
+ ULONG PhysicalInterrupt;
+
+ UNREFERENCED_PARAMETER( RootHandler );
+
+ //
+ // R98B
+ //
+ if(BusHandler->InterfaceType == PCIBus){
+ PhysicalInterrupt= (ULONG)HalpPciLogical2PhysicalInt[BusInterruptVector];
+ SystemVector = PhysicalInterrupt + DEVICE_VECTORS;
+ }else{
+ PhysicalInterrupt= BusInterruptVector;
+ SystemVector = BusInterruptVector + DEVICE_VECTORS;
+ }
+ *Irql = (KIRQL)(INT0_LEVEL + HalpIntLevelofIpr[HalpMachineCpu][PhysicalInterrupt]);
+ //For MRCINT
+ if(PhysicalInterrupt < 43){
+ *Affinity = 0x1 <<HalpResetValue[PhysicalInterrupt].Cpu;
+ }else{
+ NumCpu = (**((PULONG *)(&KeNumberProcessors)));
+ *Affinity = (0x1 <<NumCpu)-1;
+ }
+
+ return SystemVector;
+}
+
diff --git a/private/ntos/nthals/halr98b/mips/tga.h b/private/ntos/nthals/halr98b/mips/tga.h
new file mode 100644
index 000000000..a8db1925a
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/tga.h
@@ -0,0 +1,101 @@
+#ident "@(#) NEC tga.h 1.1 94/11/29 14:09:17"
+/*++
+
+Module Name:
+
+ tga.h
+
+Abstract:
+
+ This module contains the register definitions for the TGA (DEC21030)
+
+Author:
+
+ T.Katoh create-data 1994/11/11
+
+Revision Histort:
+
+--*/
+
+/*
+ * D001 1994.11.29 T.Katoh
+ *
+ * Del: non-used definitions
+ * Chg: TGA_DSP_BUF_OFFSET value
+ * Add: VIDEO_BASE definition
+ */
+
+// TGA Core Space Map offset for 8-bpp Frame Buffers
+
+#define TGA_REG_SPC_OFFSET 0x00100000
+#define TGA_DSP_BUF_OFFSET 0x00200000 // D001
+
+// 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 // D001
+#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/halr98b/mips/x86bios.c b/private/ntos/nthals/halr98b/mips/x86bios.c
new file mode 100644
index 000000000..46543c412
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/x86bios.c
@@ -0,0 +1,1256 @@
+/*++
+
+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:
+
+--*/
+
+/*
+ * S001 samezima@oa2.kbnes.nec.co.jp
+ * - marge r94d glint and x86bios source and.
+ *
+ */
+
+
+#include "halp.h"
+#include "pci.h"
+#include "pcip.h"
+//#include "xm86.h"
+//#include "x86new.h"
+
+#if defined(_X86_DBG_)
+#define X86DbgPrint(STRING) \
+ DbgPrint STRING;
+#else
+#define X86DbgPrint(STRING)
+#endif
+
+#define VIDEO_MEMORY_BASE 0x40000000
+
+#define PCI_0_IO_BASE 0x1c000000
+
+#define PONCE_ADDR_REG ((PULONG)(0x1a000008 | KSEG1_BASE))
+#define PONCE_DATA_REG ((PULONG)(0x1a000010 | KSEG1_BASE))
+#define PONCE_PERRM ((PULONG)(0x1a000810 | KSEG1_BASE))
+#define PONCE_PAERR ((PULONG)(0x1a000800 | KSEG1_BASE))
+#define PONCE_PERST ((PULONG)(0x1a000820 | KSEG1_BASE))
+
+extern PULONG HalpPonceConfigAddrReg;
+extern PULONG HalpPonceConfigDataReg;
+extern PULONG HalpPoncePerrm;
+extern PULONG HalpPoncePaerr;
+extern PULONG HalpPoncePerst;
+
+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
+ );
+
+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
+ );
+
+extern ULONG HalpDisplayControlBase;
+
+// S001 ^^^
+
+//
+// Define global data.
+//
+
+ULONG HalpX86BiosInitialized = FALSE;
+ULONG HalpEnableInt10Calls = FALSE;
+// S001 vvv
+PVOID HalpIoMemoryBase = NULL;
+PVOID HalpIoControlBase= NULL;
+PUCHAR HalpRomBase = NULL;
+
+ULONG ROM_Length;
+#define BUFFER_SIZE (64*1024)
+UCHAR ROM_Buffer[BUFFER_SIZE];
+
+ULONG X86BoardOnPonce = 0; // S001
+
+extern KSPIN_LOCK HalpPCIConfigLock;
+
+BOOLEAN
+HalpInitX86Emulator(
+ VOID
+ )
+{
+ ULONG ROMsave, ROM_size = 0;
+ PHYSICAL_ADDRESS PhysAddr;
+ UCHAR BaseClass, SubClass, ProgIf;
+ USHORT Cmd,SetCmd, VendorID, DeviceID, Slot;
+ PUCHAR ROM_Ptr, ROM_Shadow;
+ ULONG i;
+ ULONG r;
+ USHORT PciDataOffset;
+ PCI_SLOT_NUMBER PciSlot;
+ UCHAR header;
+ KIRQL Irql;
+ ULONG ponceNumber; // S001
+ ULONG Index;
+ ENTRYLO Pte;
+ PENTRYLO PageFrame;
+ LARGE_INTEGER HalpX86PhigicalVideo = {0,0};
+
+ PhysAddr.HighPart = 0x00000000;
+
+// KeInitializeSpinLock (&HalpPCIConfigLock);
+ KeRaiseIrql (PROFILE_LEVEL, &Irql);
+ KiAcquireSpinLock (&HalpPCIConfigLock);
+
+// Temp Same vvv
+ ponceNumber = 1;
+ HalpPonceConfigAddrReg = PONCE_ADDR_REG + (ponceNumber * 0x400);
+ HalpPonceConfigDataReg = PONCE_DATA_REG + (ponceNumber * 0x400);
+ HalpPoncePerrm = PONCE_PERRM + (ponceNumber * 0x400);
+ HalpPoncePaerr = PONCE_PAERR + (ponceNumber * 0x400);
+ HalpPoncePerst = PONCE_PERST + (ponceNumber * 0x400);
+
+ PciSlot.u.bits.FunctionNumber = 0;
+ PciSlot.u.bits.DeviceNumber = 4;
+
+ //
+ // Disable on-board cirrus memory space
+ //
+
+ HalpReadPCIConfigUshortByOffset(
+ PciSlot,&Cmd,FIELD_OFFSET (PCI_COMMON_CONFIG, Command)
+ );
+// SetCmd = Cmd & 0xfffd;
+ SetCmd = Cmd;
+ HalpWritePCIConfigUshortByOffset(
+ PciSlot,&SetCmd,FIELD_OFFSET (PCI_COMMON_CONFIG, Command)
+ );
+// Temp Same ^^^
+
+ //
+ // Scan PCI slots for video BIOS ROMs, except 3 PCI "slots" on motherboard
+ //
+
+ for (ponceNumber = 0; ponceNumber < R98B_MAX_PONCE ; ponceNumber++) {
+ ULONG startDevNum;
+ ULONG endDevNum;
+ ULONG Slot;
+
+ PageFrame = (PENTRYLO)(PTE_BASE |
+ (VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
+
+ HalpX86PhigicalVideo.HighPart = 1;
+ HalpX86PhigicalVideo.LowPart = 0x40000000 * (ponceNumber+1);
+
+ HalpDisplayControlBase = PCI_0_IO_BASE + (ponceNumber * 0x400000);
+
+ Pte.PFN = (HalpX86PhigicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpX86PhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+
+ Pte.G = 0;
+ Pte.V = 1;
+ Pte.D = 1;
+ Pte.C = UNCACHED_POLICY;
+
+ //
+ // Page table entries of the video memory.
+ //
+
+ for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
+ *PageFrame++ = Pte;
+ Pte.PFN += 1;
+ }
+
+ Pte.PFN = ((ULONG)HalpDisplayControlBase + 0xffff) >> PAGE_SHIFT;
+
+ for (Index = 0; Index < (0x10000 / PAGE_SIZE ); Index++) {
+ *PageFrame-- = Pte;
+ Pte.PFN -= 1;
+ }
+
+ HalpPonceConfigAddrReg = PONCE_ADDR_REG + (ponceNumber * 0x400);
+ HalpPonceConfigDataReg = PONCE_DATA_REG + (ponceNumber * 0x400);
+ HalpPoncePerrm = PONCE_PERRM + (ponceNumber * 0x400);
+ HalpPoncePaerr = PONCE_PAERR + (ponceNumber * 0x400);
+ HalpPoncePerst = PONCE_PERST + (ponceNumber * 0x400);
+
+ switch(ponceNumber){
+ case 0:
+ startDevNum = 2;
+ endDevNum = 5;
+ break;
+
+ case 1:
+ if (HalpNumberOfPonce == 3)
+ continue;
+ startDevNum = 3;
+ endDevNum = 6;
+ break;
+
+ case 2:
+ if (HalpNumberOfPonce == 2)
+ continue;
+ startDevNum = 1;
+ endDevNum = 4;
+ break;
+
+ default:
+ continue;
+ }
+
+ for (Slot = startDevNum; Slot <= endDevNum; Slot++) {
+
+ X86DbgPrint(("HAL: PCI SLot Number=%x",Slot));
+
+ //
+ // 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));
+ X86DbgPrint((" Vendor ID=%x",VendorID));
+
+ if (VendorID == 0xFFFF){
+ X86DbgPrint(("\n"));
+ continue; // Slot is empty; go to next slot
+ }
+
+ //
+ // 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 == 0x1013 && DeviceID == 0x00a0) || // S001
+ (VendorID == 0x1011 && DeviceID == 0x0004) ) {
+
+ X86DbgPrint(("\n"));
+ continue;
+ }
+
+ //
+ // Check Base Class Code
+ //
+ HalpReadPCIConfigUcharByOffset(PciSlot,&BaseClass,FIELD_OFFSET (PCI_COMMON_CONFIG, BaseClass));
+
+ //
+ // Check Sub Class Code
+ //
+ HalpReadPCIConfigUcharByOffset(PciSlot,&SubClass,FIELD_OFFSET (PCI_COMMON_CONFIG, SubClass));
+
+ //
+ // Check Proglamming Interface
+ //
+ HalpReadPCIConfigUcharByOffset(PciSlot,&ProgIf,FIELD_OFFSET (PCI_COMMON_CONFIG, ProgIf));
+ X86DbgPrint((" BaseClass =%x, SubClass =%x, ProgIf =%x\n", BaseClass, SubClass, ProgIf));
+
+ //
+ // check if video card
+ //
+ if ( ( (BaseClass == 0) && (SubClass == 1) && (ProgIf == 0) ) ||
+ ( (BaseClass == 3) && (SubClass == 0) && (ProgIf == 0) ) ||
+ ( (BaseClass == 3) && (SubClass == 1) && (ProgIf == 0) ) ||
+ ( (BaseClass == 3) && (SubClass == 0x80) && (ProgIf == 0) ) ) {
+
+ X86DbgPrint(("HAL: This is Video card \n"));
+
+ } else {
+ X86DbgPrint(("HAL: This is not Video card \n"));
+ continue;
+ }
+
+ //
+ // Get size of ROM
+ //
+
+ ROM_size=0xFFFFFFFF;
+
+ HalpReadPCIConfigUlongByOffset(PciSlot,&ROMsave,FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+
+ HalpWritePCIConfigUlongByOffset(PciSlot,&ROM_size,FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+ HalpReadPCIConfigUlongByOffset(PciSlot,&ROM_size,FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+
+ HalpWritePCIConfigUlongByOffset(PciSlot,&ROMsave,FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+
+ X86DbgPrint(("HAL: ROM_Size = %0x\n",ROM_size));
+
+ 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));
+ X86DbgPrint(("HAL: READ CMD=%0x\n",Cmd));
+
+ SetCmd = Cmd|0x3;
+ HalpWritePCIConfigUshortByOffset(PciSlot,&SetCmd,FIELD_OFFSET (PCI_COMMON_CONFIG, Command));
+
+ //
+ // Create a mapping to the PCI memory space
+ //
+ HalpIoMemoryBase = (PVOID)0x40000000;
+ //
+ // Look for PCI option video ROM signature
+ //
+ HalpRomBase = ROM_Ptr = (PUCHAR) HalpIoMemoryBase + 0xC0000;
+
+ X86DbgPrint(("HAL: HalpRomBase=%x,\n",HalpRomBase));
+ X86DbgPrint(("HAL: RomSignature[0]=%x, RomSignature[1]=%x, RomSize=%x\n",
+ *(ROM_Ptr+0), *(ROM_Ptr+1), *(ROM_Ptr+2)<<9 ));
+
+ 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) {
+ X86DbgPrint(("HAL: ROM Copy:"));
+
+ for (i=0; i<ROM_Length; i++){
+ ROM_Buffer[i] = *ROM_Ptr++;
+ if( !(i % 0x400) )
+ X86DbgPrint(("."));
+ }
+
+ X86DbgPrint(("\n"));
+ HalpRomBase = (PUCHAR) ROM_Buffer;
+
+ }
+ X86DbgPrint(("HAL: ROM Short HalpRomBase=%x\n",HalpRomBase));
+
+ //
+ // Io Map.
+ //
+ HalpIoControlBase= (PVOID)0x403f0000;
+
+ PhysAddr.LowPart = 0x000C0000;
+ HalpWritePCIConfigUlongByOffset(PciSlot,&(PhysAddr.LowPart),FIELD_OFFSET (PCI_COMMON_CONFIG, u.type0.ROMBaseAddress));
+
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql);
+
+ X86BoardOnPonce = ponceNumber; // S001
+
+ return TRUE; // Exit slot scan after finding 1st option ROM
+ }
+
+ // Not Found So Reset!!.
+ // Delete mapping to PCI memory space
+
+ // Found PCI VIDEO ROM.
+ // 1.Map ISA Memory Space
+ // 2.
+
+ X86DbgPrint(("HAL: Found PCI ROM BIOS\n"));
+
+ // 0: rom enable so do PCI
+ // 1: rom disable so do EISA vga
+
+ HalpWritePCIConfigUshortByOffset(PciSlot,&Cmd,FIELD_OFFSET (PCI_COMMON_CONFIG, Command));
+
+ } // end of if clause
+
+ X86DbgPrint(("HAL: ROM SIZE invalid\n"));
+
+ } // end of for loop
+
+ } // end of ponce searce loop
+
+ KiReleaseSpinLock (&HalpPCIConfigLock);
+ KeLowerIrql (Irql);
+
+ X86DbgPrint(("HAL: Search (E)ISA ROM BIOS\n"));
+
+ PageFrame = (PENTRYLO)(PTE_BASE |
+ (VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
+
+ HalpX86PhigicalVideo.HighPart = 1;
+ HalpX86PhigicalVideo.LowPart = 0x40000000;
+
+ HalpDisplayControlBase = PCI_0_IO_BASE;
+
+ Pte.PFN = (HalpX86PhigicalVideo.LowPart >> PAGE_SHIFT) &
+ (0x7fffffff >> PAGE_SHIFT-1) |
+ HalpX86PhigicalVideo.HighPart << (32 - PAGE_SHIFT);
+
+ Pte.G = 0;
+ Pte.V = 1;
+ Pte.D = 1;
+ Pte.C = UNCACHED_POLICY;
+
+ //
+ // Page table entries of the video memory.
+ //
+
+ for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
+ *PageFrame++ = Pte;
+ Pte.PFN += 1;
+ }
+
+ Pte.PFN = ((ULONG)HalpDisplayControlBase + 0xffff) >> PAGE_SHIFT;
+
+ for (Index = 0; Index < (0x10000 / PAGE_SIZE ); Index++) {
+ *PageFrame-- = Pte;
+ Pte.PFN -= 1;
+ }
+
+ //
+ // 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) {
+
+ //
+ // Copy ROM to RAM. PCI Spec says you can't execute from ROM.
+ // ROM and video RAM sometimes can't co-exist.
+ //
+ X86DbgPrint(("HAL: EISA ROM BIOS Found \n"));
+
+ 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;
+ HalpIoControlBase= (PVOID)0x403f0000;
+ return TRUE;
+ }
+
+ //
+ // No video option ROM was found. Delete mapping to PCI memory space.
+ //
+
+ X86DbgPrint(("HAL: 55AA BIOS Not \n"));
+
+ return FALSE;
+}
+// S001 ^^^
+
+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.
+
+--*/
+
+{
+ 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;
+ // S001 vvv
+ if (x86BiosExecuteInterrupt((UCHAR)BiosCommand,
+ &Context,
+ HalpIoControlBase,
+ HalpIoMemoryBase) != XM_SUCCESS) {
+ return FALSE;
+ }
+ // S001 ^^^
+
+ //
+ // 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;
+}
+
+// S001 vvv
+BOOLEAN
+HalpInitializeX86DisplayAdapter(
+ VOID
+ )
+// S001 ^^^
+/*++
+
+Routine Description:
+
+ This function initializes a display adapter using the x86 bios emulator.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // If EISA I/O Ports or EISA memory could not be mapped, then don't
+ // attempt to initialize the display adapter.
+ //
+
+ // S001 vvv
+ if (!HalpInitX86Emulator()){
+ X86DbgPrint(("HAL: X86 HalpInitX86Emulator() False\n")); // S001
+ return FALSE;
+ }
+
+ if (HalpIoControlBase == NULL || HalpIoMemoryBase == NULL) {
+ X86DbgPrint(("HAL: X86 Bios or Mem Base False\n")); // S001
+ return FALSE;
+ }
+ // S001 ^^^
+
+ //
+ // Initialize the x86 bios emulator.
+ //
+
+ x86BiosInitializeBios(HalpIoControlBase, HalpIoMemoryBase); // S001
+ 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) { // S001
+ HalpEnableInt10Calls = FALSE;
+ return FALSE; // S001
+ }
+
+ HalpEnableInt10Calls = TRUE;
+
+ return TRUE; // S001
+}
+
+VOID
+HalpResetX86DisplayAdapter(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function resets a display adapter using the x86 bios emulator.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ 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);
+
+ return;
+}
+
+// S001 vvv
+//
+// 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);
+
+ X86DbgPrint(("HAL: HalpRomBase=%0x\n",HalpRomBase));
+
+ 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);
+
+ 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);
+
+ 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);
+
+ X86DbgPrint(("HAL: EMU INIT \n"));
+
+ 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) {
+
+ X86DbgPrint(("HAL: Interrupt emulation failed, status %lx\n", Status));
+
+ }
+
+ 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;
+
+
+ X86DbgPrint(("HAL: BIOS INIT \n"));
+
+ //
+ // If BIOS emulation has not been initialized, then return an error.
+ //
+
+ if (x86BiosInitialized == FALSE) {
+ X86DbgPrint(("HAL: x86BiosInitializeAdapter() False 1\n"));
+ 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)) {
+ X86DbgPrint(("HAL: x86BiosInitializeAdapter() False 2\n"));
+ 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);
+
+ X86DbgPrint(("HAL: Emcall BIOS start \n"));
+
+ Status = XmEmulateFarCall(Segment, Offset, Context);
+
+ X86DbgPrint(("HAL: Emcall BIOS End \n"));
+
+ if (Status != XM_SUCCESS) {
+
+ X86DbgPrint(("HAL: Adapter initialization falied, status %lx\n", Status));
+
+ }
+
+ return Status;
+}
+// S001 ^^^
diff --git a/private/ntos/nthals/halr98b/mips/xxcalstl.c b/private/ntos/nthals/halr98b/mips/xxcalstl.c
new file mode 100644
index 000000000..0a8a7197d
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/xxcalstl.c
@@ -0,0 +1,260 @@
+/*++
+
+Copyright (c) 1991-1994 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 R98 System
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+
+#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.
+ //
+
+ HalpProfileCountRate =
+ HalpProfileCountRate * ((1000 * 1000 * 10) / MAXIMUM_INCREMENT);
+
+ //
+ // 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[CLOCK_VECTOR] = HalpClockInterrupt0;
+
+ //
+ // Write the compare register and clear the count register, and
+ // connect the profile interrupt.
+ //
+
+ HalpWriteCompareRegisterAndClear(DEFAULT_PROFILE_COUNT);
+
+ PCR->InterruptRoutine[PROFILE_VECTOR] = HalpProfileInterrupt;
+ WRITE_REGISTER_ULONG( (PULONG) &(COLUMNBS_LCNTL)->MKRR, PROFILE_VECTOR - DEVICE_VECTORS);
+ WRITE_REGISTER_ULONG( (PULONG) &(COLUMNBS_LCNTL)->TMCR2, TIMER_RELOAD_START);
+
+
+ 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.
+
+--*/
+
+{
+
+ //
+ // 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;
+ HalpWriteCompareRegisterAndClear(0);
+
+ } else if ((HalpStallStart != 0) && (HalpStallEnd == 0)) {
+ HalpStallEnd = PCR->StallExecutionCount;
+ HalpProfileCountRate = HalpWriteCompareRegisterAndClear(0);
+
+ }
+
+ return;
+}
diff --git a/private/ntos/nthals/halr98b/mips/xxclock.c b/private/ntos/nthals/halr98b/mips/xxclock.c
new file mode 100644
index 000000000..4f953ab8d
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/xxclock.c
@@ -0,0 +1,207 @@
+/*++
+
+Copyright (c) 1994 Microsoft Corporation
+
+Module Name:
+
+ xxclock.c
+
+Abstract:
+
+
+ This module implements the function necesssary to change the clock
+ interrupt rate.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+/*
+ * Original source: Build Number 1.612
+ *
+ * Modify for R98(MIPS/R4400)
+ *
+ ***********************************************************************
+ *
+ * K001 95.11.24 M.Kusano
+ * Add for WDT
+ */
+
+
+#include "halp.h"
+
+//
+// Define global data used to communicate new clock rates to the clock
+// interrupt service routine.
+//
+
+ULONG HalpCurrentTimeIncrement;
+ULONG HalpNextIntervalCount;
+ULONG HalpNextTimeIncrement;
+ULONG HalpNewTimeIncrement;
+//K001
+ULONG HalpStartWDTFlag[R98B_MAX_CPU];
+ULONG HalpStopWDTFlag[R98B_MAX_CPU];
+ULONG HalpSetWDTFlag[R98B_MAX_CPU];
+ULONG HalpSetWDTCount[R98B_MAX_CPU];
+
+VOID
+HalStartWDT(
+ IN ULONG Count
+ );
+
+VOID
+HalStopWDT(
+ VOID
+ );
+
+VOID
+HalSetWDTCounter(
+ VOID
+ );
+
+ULONG
+HalSetTimeIncrement (
+ IN ULONG DesiredIncrement
+ )
+/*++
+
+Routine Description:
+
+ This function is called to set the clock interrupt rate to the frequency
+ required by the specified time increment value.
+
+ N.B. This function is only executed on the processor that keeps the
+ system time.
+
+Arguments:
+
+ DesiredIncrement - Supplies desired number of 100ns units between clock
+ interrupts.
+
+Return Value:
+
+ The actual time increment in 100ns units.
+
+--*/
+
+{
+
+ ULONG NewTimeIncrement;
+ ULONG NextIntervalCount;
+ KIRQL OldIrql;
+
+ //
+ // If the specified time increment value is less that the minimum value
+ // or greater than the maximum value ,then set the time increment value
+ // to the minimum or maximum as appropriate.
+ //
+
+ if (DesiredIncrement < MINIMUM_INCREMENT) {
+ DesiredIncrement = MINIMUM_INCREMENT;
+
+ } else if (DesiredIncrement > MAXIMUM_INCREMENT) {
+ DesiredIncrement = MAXIMUM_INCREMENT;
+ }
+
+ //
+ // Raise IRQL to the highest level, set the new clock interrupt
+ // parameters, lower IRQl, and return the new time increment value.
+ //
+
+ // Adjust clock values to the Columbus clock frequency
+ //
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+ NextIntervalCount = ((DesiredIncrement * COLUMBUS_CLOCK_FREQUENCY) / 1000) / 10;
+ NewTimeIncrement = (NextIntervalCount * 1000 * 10) / COLUMBUS_CLOCK_FREQUENCY;
+ HalpNextIntervalCount = NextIntervalCount;
+ HalpNewTimeIncrement = NewTimeIncrement;
+ KeLowerIrql(OldIrql);
+ return NewTimeIncrement;
+}
+
+//K001
+VOID HalStartWDT(
+ IN ULONG Count
+)
+/*++
+Routine Description:
+
+ This function is called to start WDT.
+
+Arguments:
+
+ Count - Counter value for WDT.
+
+Return Value:
+
+ NONE
+--*/
+{
+ ULONG NumCPU,i;
+
+ NumCPU=**((PULONG *)(&KeNumberProcessors));
+ NumCPU--;
+
+ for(i=0;i<=NumCPU;i++){
+ HalpStartWDTFlag[i]=1;
+ HalpSetWDTCount[i]=Count;
+ }
+}
+
+VOID HalStopWDT(
+)
+/*++
+Routine Description:
+
+ This function is called to stop WDT.
+
+Arguments:
+
+ NONE
+
+Return Value:
+
+ NONE
+--*/
+{
+ ULONG NumCPU,i;
+
+ NumCPU=**((PULONG *)(&KeNumberProcessors));
+ NumCPU--;
+
+ for(i=0;i<=NumCPU;i++){
+ HalpStopWDTFlag[i]=1;
+ }
+}
+
+VOID HalSetWDTCounter(
+)
+/*++
+Routine Description:
+
+ This function is called to stop WDT.
+
+Arguments:
+
+ NONE
+
+Return Value:
+
+ NONE
+--*/
+{
+ ULONG NumCPU,i;
+
+ NumCPU=**((PULONG *)(&KeNumberProcessors));
+ NumCPU--;
+
+ for(i=0;i<=NumCPU;i++){
+ HalpSetWDTFlag[i]=1;
+ }
+}
diff --git a/private/ntos/nthals/halr98b/mips/xxidle.s b/private/ntos/nthals/halr98b/mips/xxidle.s
new file mode 100644
index 000000000..e202c795c
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/xxidle.s
@@ -0,0 +1,76 @@
+// "@(#) NEC xxidle.s 1.2 94/10/17 11:59:42"
+// TITLE("Processor Idle")
+//++
+//
+// Copyright (c) 1994 Microsoft Corporation
+//
+// Module Name:
+//
+// xxidle.s
+//
+// Abstract:
+//
+// This module implements system platform dependent power management
+// support.
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+//--
+
+#include "halmips.h"
+
+ SBTTL("Processor Idle")
+//++
+//
+// VOID
+// HalProcessorIdle(
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function is called when the current processor is idle with
+// interrupts disabled. There is no thread active and there are no
+// DPCs to process. Therefore, power can be switched to a standby
+// mode until the the next interrupt occurs on the current processor.
+//
+// N.B. This routine is entered with IE in PSR clear. This routine
+// must do any power management enabling necessary, set the IE
+// bit in PSR, then either return or wait for an interrupt.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalProcessorIdle)
+
+//
+// Perform power management enabling.
+//
+
+ .set noreorder
+ .set noat
+ mfc0 v0,psr // get current PSR
+ nop // fill
+ or v0,v0,1 << PSR_IE // set interrupt enable.
+ mtc0 v0,psr // enable interrupts
+ .set at
+ .set reorder
+
+//
+// Wait for an interrupt if supported.
+//
+
+ j ra // return
+
+ .end HalProcessorIdle
diff --git a/private/ntos/nthals/halr98b/mips/xxinithl.c b/private/ntos/nthals/halr98b/mips/xxinithl.c
new file mode 100644
index 000000000..5071b6b61
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/xxinithl.c
@@ -0,0 +1,894 @@
+/*++
+
+Copyright (c) 1991-1993 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 R98B system.
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+// For CPU
+#define CPU_PHY_INF_OFFSET 0x1d68
+#define CPU_RED_INF_OFFSET 0x1d60
+//For Memory
+#define SIMM_PHY_INF_OFFSET 0x1d10
+#define SIMM_RED_INF_OFFSET 0x1d00
+#define SIMM_PHY_CAP_OFFSET 0x1d20
+#define FW_NOT_DETECT 0x0000
+#define FW_16_DETECT 0x0001
+#define FW_32_DETECT 0x0002
+#define FW_64_DETECT 0x0004
+#define FW_128_DETECT 0x0008
+
+
+ULONG HalpMachineCpu;
+ULONG HalpNumberOfPonce;
+ULONG HalpPhysicalNode;
+
+
+//For CPU
+ULONG HalpLogicalCPU2PhysicalCPU[R98B_MAX_CPU];
+ULONG HalpPhysicalAffinity=0;
+ULONG HalpFwAffinity=0;
+ULONG HalpFwDetectErrorCpu=0;
+// For Memory
+ULONG HalpFwDetectMemory=0;
+ULONG HalpPhysicalMemory=0;
+ULONG HalpFwDetectErrorMemory=0;
+UCHAR HalpPhysicalSimmSize[64];
+// For INTERRUPT
+// v-masank@microsoft.com
+//
+extern PINT_ENTRY HalpIntEntryPointer;
+//
+// Define forward referenced prototypes.
+//
+
+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
+ );
+
+VOID
+HalpCopyROMs(
+ VOID
+ );
+
+extern PVOID HalpIoControlBase;
+extern PVOID HalpIoMemoryBase;
+extern UCHAR HalpSzPciLock[];
+extern UCHAR HalpSzBreak[];
+extern BOOLEAN HalpPciLockSettings;
+
+VOID
+HalpGetParameters (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+//
+// 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, HalpGetParameters)
+#pragma alloc_text(INIT, HalInitializeProcessor)
+#pragma alloc_text(INIT, HalStartNextProcessor)
+#pragma alloc_text(INIT, HalpCpuCheck)
+
+#endif
+
+//
+// Define global spin locks used to synchronize various HAL operations.
+//
+
+KSPIN_LOCK HalpBeepLock;
+KSPIN_LOCK HalpDisplayAdapterLock;
+KSPIN_LOCK HalpSystemInterruptLock;
+KSPIN_LOCK HalpIprInterruptLock;
+KSPIN_LOCK HalpDieLock;
+KSPIN_LOCK HalpLogLock;
+//
+// 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;
+
+extern ULONG HalpX86BiosInitialized;
+extern ULONG X86BoardOnPonce;
+
+KBUGCHECK_CALLBACK_RECORD HalpCallbackRecord;
+
+UCHAR HalpComponentId[] = "hal.dll";
+
+
+VOID
+HalpGetParameters (
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+/*++
+
+Routine Description:
+
+ This gets any parameters from the boot.ini invocation line.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None
+
+--*/
+{
+ PCHAR Options;
+
+ if (LoaderBlock != NULL && LoaderBlock->LoadOptions != NULL) {
+ Options = LoaderBlock->LoadOptions;
+
+ //
+ // Check if PCI settings are locked down
+ //
+
+ if (strstr(Options, HalpSzPciLock)) {
+ HalpPciLockSettings = TRUE;
+ }
+
+ //
+ // Has the user asked for an initial BreakPoint?
+ //
+
+ if (strstr(Options, HalpSzBreak)) {
+ DbgBreakPoint();
+ }
+
+ }
+
+ return;
+}
+
+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.
+
+--*/
+
+{
+
+ PKPRCB Prcb;
+ PHYSICAL_ADDRESS PhysicalAddress;
+ PHYSICAL_ADDRESS ZeroAddress;
+ ULONG AddressSpace;
+
+ ULONG Revr;
+ ULONG PhysicalNumber;
+
+ ULONG Cnfg;
+ ULONG TmpAffinity;
+ PUCHAR FwNvram;
+ PULONG FwNvram2;
+ UCHAR FwCpu;
+ ULONG i,j;
+ ULONG FwMemory;
+ ULONG FwNoMemory;
+ //
+ // Initialize the HAL components based on the phase of initialization
+ // and the processor number.
+ //
+
+ Prcb = PCR->Prcb;
+ //
+ // DataBuserr handling
+ //
+ PCR->DataBusError = HalpBusError;
+ //
+ // Instruction BusError handling
+ //
+ PCR->InstructionBusError = HalpBusError;
+
+ if ((Phase == 0) || (Prcb->Number != 0)) {
+
+ //
+ // 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();
+ HalpGetParameters (LoaderBlock);
+
+ Revr=READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->REVR ) ;
+ PhysicalNumber=((Revr&0x0f000000)>>24)-4;
+ HalpLogicalCPU2PhysicalCPU[Prcb->Number]=PhysicalNumber;
+
+ //
+ // If processor 0 is being initialized, then initialize various
+ // variables, spin locks, and the display adapter.
+ //
+
+ if (Prcb->Number == 0) {
+
+ //
+ // Fill in handlers for APIs which this hal supports
+ //
+
+ HalQuerySystemInformation = HaliQuerySystemInformation;
+ HalSetSystemInformation = HaliSetSystemInformation;
+#if !defined(NT_40)
+ HalRegisterBusHandler = HaliRegisterBusHandler;
+ HalHandlerForBus = HaliHandlerForBus;
+ HalHandlerForConfigSpace = HaliHandlerForConfigSpace;
+ HalQueryBusSlots = HaliQueryBusSlots;
+ HalSlotControl = HaliSlotControl;
+ HalCompleteSlotControl = HaliCompleteSlotControl;
+#endif
+
+ //
+ // Set NMI interrupt service routine on NVRAM
+ //
+
+ HalpSetupNmiHandler(); // DUMP by kita
+
+ //
+ // Set the number of process id's and TB entries.
+ //
+
+ **((PULONG *)(&KeNumberProcessIds)) = 256;
+
+ //
+ // Cpu Type
+ //
+
+ HalpCpuCheck();
+
+ //
+ // Set the interval clock increment value.
+ //
+
+ HalpCurrentTimeIncrement = MAXIMUM_INCREMENT;
+ HalpNextTimeIncrement = MAXIMUM_INCREMENT;
+ HalpNextIntervalCount = 0;
+ KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT);
+
+ //
+ // Set DMA I/O coherency attributes.
+ //
+
+ KeSetDmaIoCoherency(DMA_READ_DCACHE_INVALIDATE | DMA_READ_ICACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP);
+
+ //
+ // Initialize all spin locks.
+ //
+
+ KeInitializeSpinLock(&HalpBeepLock);
+ KeInitializeSpinLock(&HalpDisplayAdapterLock);
+ KeInitializeSpinLock(&HalpSystemInterruptLock);
+ KeInitializeSpinLock(&HalpIprInterruptLock);
+ KeInitializeSpinLock(&HalpDieLock);
+ KeInitializeSpinLock(&HalpLogLock);
+
+ //
+ // Set address of cache error routine.
+ //
+
+ KeSetCacheErrorRoutine(HalpCacheErrorRoutine);
+
+ //
+ // Initialize the display adapter.
+ //
+
+ HalpInitializeDisplay0(LoaderBlock);
+
+ //
+ // Allocate map register memory.
+ //
+
+ HalpAllocateMapRegisters(LoaderBlock);
+
+ //
+ // Initialize and register a bug check callback record.
+ //
+
+ KeInitializeCallbackRecord(&HalpCallbackRecord);
+ KeRegisterBugCheckCallback(&HalpCallbackRecord,
+ HalpBugCheckCallback,
+ &HalpBugCheckBuffer,
+ sizeof(HALP_BUGCHECK_BUFFER),
+ &HalpComponentId[0]);
+
+ // For CPU log(FW Nvram -> OS Nvram)
+ Cnfg=READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->CNFG ) ;
+ TmpAffinity=((~((Cnfg&0x0f000000)>>24))&0x0000000f);
+
+ for(i=0;i<4;i++){
+ HalpPhysicalAffinity = HalpPhysicalAffinity | ((TmpAffinity>>i)&0x1);
+ if(i==3){
+ break;
+ }
+ HalpPhysicalAffinity=(HalpPhysicalAffinity)<<1;
+ }
+
+ (ULONG)FwNvram=0xbf080000;
+ FwCpu=(*FwNvram);
+ HalpFwAffinity=(ULONG)FwCpu;
+ HalpFwDetectErrorCpu=((HalpPhysicalAffinity)&(~HalpFwAffinity));
+ HalNvramWrite(CPU_RED_INF_OFFSET,4,&HalpFwDetectErrorCpu);
+ HalNvramWrite(CPU_PHY_INF_OFFSET,4,&HalpPhysicalAffinity);
+
+ //For memory Log(FW Nvram -> OS NVram)
+ (ULONG)FwNvram2=0xbf080050;
+ HalpFwDetectMemory=(*FwNvram2);
+ FwMemory=0;
+ FwNoMemory=0;
+ for(i=0;i<4;i++){
+ FwMemory=((FwMemory)|((HalpFwDetectMemory <<(i*8))& 0xff000000)) ;
+ if(i==3){
+ break;
+ }
+ FwMemory=((FwMemory)>>8);
+ }
+ for(i=0;i<8;i++){
+ switch(FwMemory&0xf){
+ case FW_NOT_DETECT:
+ FwNoMemory=(FwNoMemory|(0xf<<(i*4)));
+ break;
+ case FW_16_DETECT:
+ for(j=0;j<4;j++){
+ HalpPhysicalSimmSize[i*4+j]=0x04;
+ }
+ break;
+ case FW_32_DETECT:
+ for(j=0;j<4;j++){
+ HalpPhysicalSimmSize[i*4+j]=0x08;
+ }
+ break;
+ case FW_64_DETECT:
+ for(j=0;j<4;j++){
+ HalpPhysicalSimmSize[i*4+j]=0x16;
+ }
+ break;
+ case FW_128_DETECT:
+ for(j=0;j<4;j++){
+ HalpPhysicalSimmSize[i*4+j]=0x32;
+ }
+ break;
+ default:
+ HalpFwDetectErrorMemory=(HalpFwDetectErrorMemory|(0xf<<(i*4) ));
+ }
+ FwMemory=((FwMemory)>>4);
+ }
+ HalpPhysicalMemory=~(FwNoMemory);
+
+ HalNvramWrite(SIMM_RED_INF_OFFSET,4,&HalpFwDetectErrorMemory);
+ HalNvramWrite(SIMM_PHY_INF_OFFSET,4,&HalpPhysicalMemory);
+ HalNvramWrite(SIMM_PHY_CAP_OFFSET,64,HalpPhysicalSimmSize);
+ }
+
+ //
+ // Initialize I/O address
+ //
+
+ HalpMapIoSpace();
+
+#if DBG
+ DbgPrint("Errnod addr is 0x%x\n",(PULONG)&(COLUMNBS_LCNTL)->ERRNOD );
+#endif
+ //
+ // 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 ();
+
+ if (HalpInitializeDisplay1(LoaderBlock) == FALSE) {
+ return FALSE;
+
+ } else {
+
+ //
+ // Map I/O space, calibrate the stall execution scale factor,
+ // and create DMA data structures.
+ //
+
+ HalpCalibrateStall();
+
+ HalpCreateDmaStructures();
+
+ //
+ // 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);
+
+ //
+ // reset EISA io/memory base for HalCallBios() use.
+ //
+ if( HalpX86BiosInitialized ){
+ if(X86BoardOnPonce == 0){
+ HalpIoControlBase = HalpEisaControlBase;
+ HalpIoMemoryBase = HalpEisaMemoryBase;
+ } else {
+ HalpIoControlBase = (PVOID)(
+ KSEG1_BASE +
+ PCI_CNTL_PHYSICAL_BASE +
+ (0x40000 * X86BoardOnPonce )
+ );
+ PhysicalAddress.HighPart = 1;
+ PhysicalAddress.LowPart = 0x40000000 * (X86BoardOnPonce+1);
+ HalpIoMemoryBase = MmMapIoSpace(PhysicalAddress,
+ PAGE_SIZE * 256,
+ FALSE
+ );
+ }
+ DbgPrint("HAL: X86 Bus=%d, HalpIoControlBase = 0x%x, HalpIoMemoryBase = 0x%x%x\n",
+ X86BoardOnPonce, HalpIoControlBase, HalpIoMemoryBase);
+ }
+
+#if DBG
+ DbgPrint("HAL: EisaMemoryBase = 0x%x\n", HalpEisaMemoryBase);
+#endif
+// HalpInitializeX86DisplayAdapter();
+
+ return TRUE;
+ }
+ }
+}
+
+//
+// Check MPU is R4400 or R10000
+//
+VOID
+HalpCpuCheck(
+ VOID
+ )
+{
+ //
+ // For Driver. NVRAM Erea Write Enable Any Time.
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->STSR ,STSR_WNVWINH);
+ //
+ // Default setup. future implement is daynamic diagnotics.
+ //
+ HalpNumberOfPonce = 2;
+
+ //
+ // Set DUMP Key Only NMI.
+ // PUSH Power SW coused Interrupt. Not NMI!!
+ //
+ HalpMrcModeChange((UCHAR)MRC_OP_DUMP_AND_POWERSW_NMI);
+
+ HalpPhysicalNode = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->CNFG );
+
+ if( READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->STSR) & STSR_MPU){
+ HalpMachineCpu = R98_CPU_R4400;
+ **((PULONG *)(&KeNumberTbEntries)) = 48;
+
+ }else{
+ HalpMachineCpu = R98_CPU_R10000;
+ **((PULONG *)(&KeNumberTbEntries)) = 64;
+
+#if defined(NT_40)
+ //
+ // Set SyncIrql
+ //
+ // Hal must not set SyncIrql
+ // v-masank@microsoft.com 5/10/96
+ // KeSetSynchIrql(5);
+#endif
+ }
+ //v-masank@microsoft.com for interrupt
+ //
+ HalpIntEntryPointer= (&HalpIntEntry[HalpMachineCpu][0][0]);
+}
+
+
+
+#include "rxnvr.h"
+
+VOID
+HalpSetupNmiHandler(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine set NMI handler to nvRAM.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+#if 1 //NMI Vector not imprement yet -> modify by kita
+ ULONG funcAddr;
+ KIRQL OldIrql;
+ ENTRYLO SavedPte[2];
+ PNVRAM_NMIVECTER NvramNmiVecter;
+
+ //
+ // Get address of HalpNmiHandler
+ //
+
+ funcAddr = (ULONG)HalpNmiHandler;
+
+
+ ASSERT( ((ULONG)&HalpNmiHandler >= KSEG0_BASE) &&
+ ((ULONG)&HalpNmiHandler < KSEG2_BASE) );
+
+ //
+ // Map the NVRAM into the address space of the current process.
+ //
+
+ OldIrql = HalpMapNvram(&SavedPte[0]);
+
+ NvramNmiVecter = (PNVRAM_NMIVECTER)NMIVECTER_BASE;
+
+ WRITE_REGISTER_UCHAR(&NvramNmiVecter->NmiVector[0],
+ (UCHAR)(funcAddr >> 24));
+
+ WRITE_REGISTER_UCHAR(&NvramNmiVecter->NmiVector[1],
+ (UCHAR)((funcAddr >> 16) & 0xFF));
+
+ WRITE_REGISTER_UCHAR(&NvramNmiVecter->NmiVector[2],
+ (UCHAR)((funcAddr >> 8) & 0xFF));
+
+ WRITE_REGISTER_UCHAR(&NvramNmiVecter->NmiVector[3],
+ (UCHAR)(funcAddr & 0xFF));
+
+ //
+ // Unmap the NVRAM from the address space of the current process.
+ //
+
+ HalpUnmapNvram(&SavedPte[0], OldIrql);
+#endif
+ return;
+}
+
+
+
+
+//
+// no change
+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.
+
+--*/
+
+{
+
+ //
+ // N.B This version Not Implement.
+ // Future support!!
+ //
+ 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 MagellanAllError0 =0;
+ ULONG MagellanAllError1 =0;
+ ULONG ColumbsAllError;
+
+ //
+ // Only one Eif or Buserr trap
+ //
+
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKSR,
+ 63-(EIF_VECTOR-DEVICE_VECTORS ));
+
+ KiAcquireSpinLock(&HalpDieLock);
+ HalpBusErrorLog();
+
+// KiReleaseSpinLock(&HalpDieLock);
+ //
+ // Bus Error case (Instruction Fetch and Data Load or Store)
+ // -At Memory Read Multi Bit Error.
+ // -Read to Memory Hole Area
+ // -Read to reserved area or protection area
+ //
+ if(!(HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0 ))
+ MagellanAllError0 = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->AERR );
+ if(!(HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1 ))
+ MagellanAllError1 = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->AERR );
+
+ ColumbsAllError = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->AERR);
+
+
+ KeBugCheckEx(ExceptionRecord->ExceptionCode & 0xffff,
+ (ULONG)VirtualAddress,
+ ColumbsAllError,
+ MagellanAllError0,
+ MagellanAllError1
+ );
+ return FALSE;
+}
+
+
+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.
+
+--*/
+
+{
+ 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;
+ }
+
+ if (NextRestartBlock->BootStatus.ProcessorReady != FALSE){
+ Number += 1;
+ }
+ NextRestartBlock = NextRestartBlock->NextRestartBlock;
+ } while (NextRestartBlock != NULL);
+
+ return FALSE;
+}
+
+VOID
+HalpVerifyPrcbVersion(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function ?
+
+Arguments:
+
+ None.
+
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ return;
+}
diff --git a/private/ntos/nthals/halr98b/mips/xxinitnt.c b/private/ntos/nthals/halr98b/mips/xxinitnt.c
new file mode 100644
index 000000000..e0f4bae5a
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/xxinitnt.c
@@ -0,0 +1,424 @@
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ xxinitnt.c
+
+Abstract:
+
+
+ This module implements the interrupt initialization for a MIPS R98B
+ system.
+
+--*/
+
+
+#include "halp.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, HalpInitializeInterrupts)
+
+#endif
+
+VOID
+HalpT5Int5Dispatch(
+ VOID
+ );
+
+
+//
+// Define the IRQL mask and level mapping table.
+//
+// These tables are transfered to the PCR and determine the priority of
+// interrupts.
+//
+// N.B. The two software interrupt levels MUST be the lowest levels.
+//
+
+UCHAR HalpIrqlMask[] = {4, 5, 6, 6, 7, 7, 7, 7, // 0000 - 0111 high 4-bits
+ 8, 8, 8, 8, 8, 8, 8, 8, // 1000 - 1111 high 4-bits
+ 0, 1, 2, 2, 3, 3, 3, 3, // 0000 - 0111 low 4-bits
+ 4, 4, 4, 4, 4, 4, 4, 4}; // 1000 - 1111 low 4-bits
+
+UCHAR HalpIrqlTable[] = {0xff, // IRQL 0
+ 0xfe, // IRQL 1
+ 0xfc, // IRQL 2
+ 0xf8, // IRQL 3
+ 0xf0, // IRQL 4
+ 0xe0, // IRQL 5
+ 0xc0, // IRQL 6
+ 0x80, // IRQL 7
+ 0x00}; // IRQL 8
+
+#if defined(NT_40)
+//
+// SYNCH Level must enable IPI on R98B.
+// Sync level enable IPI on R98A .
+// But on R98B, Sync level disable IPI.
+// So, on R98B, we need to change Irql mask table.
+// v-masank@microsoft.com 5/10/96
+//
+// And mask Internal Timer.
+// Because Internal Timer does not use for Profile Interrupt.
+// v-masank@microsoft.com 5/14/96
+// For R98B INT4 handler.
+// v-masank@microsoft.com 5/21/96
+//
+UCHAR HalpIrqlMaskForR98b[] = {4, 5, 7, 7, 7, 7, 7, 7, // 0000 - 0111 high 4-bits
+ 8, 8, 8, 8, 8, 8, 8, 8, // 1000 - 1111 high 4-bits
+ 0, 1, 2, 2, 3, 3, 3, 3, // 0000 - 0111 low 4-bits
+ 4, 4, 4, 4, 4, 4, 4, 4}; // 1000 - 1111 low 4-bits
+
+
+// On the R98B ip[7] is the internal clock. The internal clock
+// is not used for profile interrupt. On the R98B ip[4] used
+// for Profile Interrupt AND clock interrupt. The ip[4] has
+// two external clock interrupts.
+
+UCHAR HalpIrqlTableForR98b[] = {0x7f, // IRQL 0
+ 0x7e, // IRQL 1
+ 0x7c, // IRQL 2
+ 0x78, // IRQL 3
+ 0x70, // IRQL 4
+ 0x60, // IRQL 5
+ 0x60, // IRQL 6
+ 0x00, // IRQL 7
+ 0x00}; // IRQL 8
+VOID
+HalpT5Int4Dispatch(
+ VOID
+ );
+#endif
+
+BOOLEAN
+HalpInitializeInterrupts (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes interrupts for a Jazz or Duo MIPS system.
+
+ N.B. This function is only called during phase 0 initialization.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ A value of TRUE is returned if the initialization is successfully
+ completed. Otherwise a value of FALSE is returned.
+
+--*/
+
+{
+
+ ULONG Value[2];
+
+ PULONG Vp;
+ PKPRCB Prcb;
+ ULONG fcpu;
+ ULONG IntNo;
+ ULONG Index;
+ ULONG TmpValue;
+ ULONG Ponce;
+ ULONG DataLong;
+ ULONG BitCount;
+ ULONG repeatCounter;
+ ULONG MagBuffer;
+
+ //
+ // Get the address of the processor control block for the current
+ // processor.
+ //
+
+ Prcb = PCR->Prcb;
+
+ //
+ // Initialize the IRQL translation tables in the PCR. These tables are
+ // used by the interrupt dispatcher to determine the new IRQL and the
+ // mask value that is to be loaded into the PSR. They are also used by
+ // the routines that raise and lower IRQL to load a new mask value into
+ // the PSR.
+ //
+
+#if defined(NT_40)
+ //
+ // SYNCH Level must enable IPI on R98B.
+ // Sync level enable IPI on R98A .
+ // But on R98B, Sync level disable IPI.
+ // So, On R98B, we need to change Irql mask table.
+ // v-masank@microsoft.com 5/10/96
+ //
+ if( HalpMachineCpu == R98_CPU_R10000 ){
+ for (Index = 0; Index < sizeof(HalpIrqlMaskForR98b); Index += 1) {
+ PCR->IrqlMask[Index] = HalpIrqlMaskForR98b[Index];
+ }
+ for (Index = 0; Index < sizeof(HalpIrqlTableForR98b); Index += 1) {
+ PCR->IrqlTable[Index] = HalpIrqlTableForR98b[Index];
+ }
+ }else{
+ for (Index = 0; Index < sizeof(HalpIrqlMask); Index += 1) {
+ PCR->IrqlMask[Index] = HalpIrqlMask[Index];
+ }
+ for (Index = 0; Index < sizeof(HalpIrqlTable); Index += 1) {
+
+ PCR->IrqlTable[Index] = HalpIrqlTable[Index];
+ }
+ }
+#else
+ for (Index = 0; Index < sizeof(HalpIrqlMask); Index += 1) {
+ PCR->IrqlMask[Index] = HalpIrqlMask[Index];
+ }
+ for (Index = 0; Index < sizeof(HalpIrqlTable); Index += 1) {
+
+ PCR->IrqlTable[Index] = HalpIrqlTable[Index];
+ }
+#endif
+
+
+ //
+ // All interrupt disables.
+ //
+ Value[0] = (ULONG)0xFFFFFFFF;
+ Value[1] = (ULONG)0xFFFFFFFF;
+ Vp = (PULONG)&(COLUMNBS_LCNTL)->MKR;
+ WRITE_REGISTER_ULONG( Vp++, Value[0]);
+ WRITE_REGISTER_ULONG( Vp, Value[1]);
+
+ if( HalpMachineCpu == R98_CPU_R10000 ){
+
+ //
+ // Disable illegal memory access error on Columbus.
+ //
+ TmpValue = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRMK) | 0x94400000;
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRMK, TmpValue);
+
+ TmpValue = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRMK2) | 0x00000540;
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->ERRMK2, TmpValue);
+
+ TmpValue = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->NMIM2) | 0x00000540;
+ WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->NMIM2, TmpValue);
+
+ if( Prcb->Number == 0 ){
+ //
+ // Disable illegal memory access error on Magellan.
+ //
+
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0) == 0 ){
+
+ TmpValue = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRM) | 0x000000c0;
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRM, TmpValue );
+
+ }
+
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1) == 0 ){
+
+ TmpValue = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRM) | 0x000000c0;
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRM, TmpValue );
+
+ }
+
+ //
+ // Disable illegal memory access error on Ponce.
+ //
+
+ TmpValue = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(0)->ERRM ) | 0x90400000;
+ WRITE_REGISTER_ULONG((PULONG)&PONCE_CNTL(0)->ERRM, TmpValue );
+
+ TmpValue = READ_REGISTER_ULONG((PULONG)&PONCE_CNTL(1)->ERRM ) | 0x90400000;
+ WRITE_REGISTER_ULONG((PULONG)&PONCE_CNTL(1)->ERRM, TmpValue );
+ }
+ }
+
+ //
+ // If processor 0 is being initialized, then set all device
+ // interrupt disables.
+ //
+
+ if (Prcb->Number == 0) {
+
+ for (Ponce = 0;Ponce <HalpNumberOfPonce;Ponce++){
+ repeatCounter = 0;
+ while(
+ ((DataLong = READ_REGISTER_ULONG( (PULONG)&PONCE_CNTL(Ponce)->INTRG) & 0x07ff07ff) != 0) &&
+ (++repeatCounter < 60)
+ ) {
+
+ for( BitCount = 0 ; BitCount <=10 ; BitCount++ ) {
+ if( (DataLong & ( 1 << BitCount )) != 0) {
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(Ponce)->INTRG,0x1 << (BitCount));
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(Ponce)->INTRG,0x1 << (BitCount+21));
+ }
+ }
+ }
+
+ //
+ // Disable I/O TLB error.
+ //
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(Ponce)->ERITTG[1], 0x0 );
+ WRITE_REGISTER_ULONG( (PULONG)&PONCE_CNTL(Ponce)->ERRST, PONCE_XERR_TUAER | PONCE_XERR_TIVER );
+ }
+ }
+
+ PCR->InterruptRoutine[INT0_LEVEL] = (PKINTERRUPT_ROUTINE) HalpInt0Dispatch;
+ PCR->InterruptRoutine[INT1_LEVEL] = (PKINTERRUPT_ROUTINE) HalpInt1Dispatch;
+ PCR->InterruptRoutine[INT2_LEVEL] = (PKINTERRUPT_ROUTINE) HalpInt2Dispatch;
+ PCR->InterruptRoutine[INT3_LEVEL] = (PKINTERRUPT_ROUTINE) HalpInt3Dispatch;
+
+ //
+ // On NT4.0 , INT4 handler is different between R98A and R98B.
+ // v-masank@microsoft.com 5/21/96
+ //
+ PCR->InterruptRoutine[INT4_LEVEL] = (PKINTERRUPT_ROUTINE) HalpInt4Dispatch;
+
+
+ if( HalpMachineCpu == R98_CPU_R4400){
+ //
+ // R4400 System (R98A)
+ //
+ PCR->InterruptRoutine[INT5_LEVEL] = (PKINTERRUPT_ROUTINE) HalpInt5Dispatch;
+
+ }else{
+ //
+ // R10000 System (R98B)
+ //
+#if defined(NT_40)
+ PCR->InterruptRoutine[INT4_LEVEL] = (PKINTERRUPT_ROUTINE) HalpT5Int4Dispatch;
+#endif
+ PCR->InterruptRoutine[INT5_LEVEL] = (PKINTERRUPT_ROUTINE) HalpT5Int5Dispatch;
+
+ }
+
+ //
+ // If processor 0 is being initialized, then connect the interval timer
+ // interrupt to the stall interrupt routine so the stall execution count
+ // can be computed during phase 1 initialization. Otherwise, connect the
+ // interval timer interrupt to the appropriate interrupt service routine
+ // and set stall execution count from the computation made on processor
+ // 0.
+ //
+
+ if (Prcb->Number == 0) {
+
+ PCR->InterruptRoutine[CLOCK_VECTOR] = HalpStallInterrupt;
+
+ } else {
+
+ PCR->InterruptRoutine[CLOCK_VECTOR] = HalpClockInterrupt1;
+
+ PCR->StallScaleFactor = HalpStallScaleFactor;
+ }
+
+ //
+ // Initialize the interval timer to interrupt at the specified interval.
+ //
+
+ WRITE_REGISTER_ULONG( (PULONG) &(COLUMNBS_LCNTL)->TMSR1, CLOCK_INTERVAL-1);
+
+ //
+ // Initialize the profile timer to interrupt at the default interval.
+ //
+
+ WRITE_REGISTER_ULONG( (PULONG) &(COLUMNBS_LCNTL)->TMSR2,
+ DEFAULT_PROFILETIMER_COUNT);
+ //
+ // Enable the interval timer interrupt on the current processor.
+ //
+ WRITE_REGISTER_ULONG( (PULONG) &(COLUMNBS_LCNTL)->MKRR, CLOCK_VECTOR - DEVICE_VECTORS);
+ WRITE_REGISTER_ULONG( (PULONG) &(COLUMNBS_LCNTL)->TMCR1, TIMER_RELOAD_START);
+
+ //
+ // If processor 0 is being initialized, then connect the count/compare
+ // interrupt to the count interrupt routine to handle early count/compare
+ // interrupts during phase 1 initialization. Otherwise, connect the
+ // count\comapre interrupt to the appropriate interrupt service routine.
+ //
+
+ if (Prcb->Number != 0) {
+ PCR->InterruptRoutine[PROFILE_VECTOR] = HalpProfileInterrupt;
+ WRITE_REGISTER_ULONG( (PULONG) &(COLUMNBS_LCNTL)->MKRR, PROFILE_VECTOR - DEVICE_VECTORS);
+ WRITE_REGISTER_ULONG( (PULONG) &(COLUMNBS_LCNTL)->TMCR2,TIMER_RELOAD_START);
+ }
+
+ //
+ // ECC 1Bit Error Vector Set
+ //
+
+ if (Prcb->Number == 0) {
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0) == 0 ){
+ MagBuffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRI );
+ MagBuffer |= ECC_ERROR_DISABLE;
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->ERRI, MagBuffer );
+ }
+ if ( (HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1) == 0 ){
+ MagBuffer = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRI );
+ MagBuffer |= ECC_ERROR_DISABLE;
+ WRITE_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->ERRI, MagBuffer );
+ }
+ }
+ PCR->InterruptRoutine[ECC_1BIT_VECTOR] = HalpEcc1bitError;
+
+ //
+ // Connect the interprocessor interrupt service routine and enable
+ // interprocessor interrupts.
+ //
+ for(fcpu = 0;fcpu < R98B_MAX_CPU;fcpu++)
+ PCR->InterruptRoutine[IPI_VECTOR3+fcpu] = HalpIpiInterrupt;
+
+
+ //
+ // Enable Interrupt at Columnbs
+ // N.B
+ // At This Interrupt Mask is not perfact. Because Number Of CPU is unknown.
+ // So fix at HalAllProcessorsStarted ()
+ //
+ Value[0] = (ULONG)0xFFFFFFFF;
+ Value[1] = (ULONG)0xFFFFFFFF;
+
+ //
+ // Build Mask
+ //
+ for(IntNo=0 ; IntNo< 6 ;IntNo++){
+ Vp = (PULONG)&(HalpIntEntry[HalpMachineCpu][PCR->Number][IntNo].Enable);
+#if DBG
+ DbgPrint("Init Interrupt CPU= %x: INT 0x%x Low =0x%x High = 0x%X\n",
+ PCR->Number,IntNo, Vp[0], Vp[1]);
+#endif
+ Value[0] &= ~Vp[0];
+ Value[1] &= ~Vp[1];
+ }
+#if DBG
+ DbgPrint("Init Interrupt CPU= %x :MKR Low =0x%x High = 0x%X\n",
+ PCR->Number,Value[0], Value[1]);
+#endif
+ Vp = (PULONG)&(COLUMNBS_LCNTL)->MKR;
+ WRITE_REGISTER_ULONG(Vp++,Value[0]);
+ WRITE_REGISTER_ULONG(Vp, Value[1]);
+
+ //
+ // Reserve the local device interrupt vector for exclusive use by the HAL.
+ //
+ PCR->ReservedVectors |= ((1 << INT0_LEVEL) |(1 << INT1_LEVEL)|(1 << INT2_LEVEL)|
+ (1 << INT4_LEVEL));
+
+ if( HalpMachineCpu == R98_CPU_R4400){
+ PCR->ReservedVectors = (0x1 <<INT5_LEVEL);
+ }
+
+ return TRUE;
+}