summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halwyse7/i386
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/halwyse7/i386')
-rw-r--r--private/ntos/nthals/halwyse7/i386/halnls.h5
-rw-r--r--private/ntos/nthals/halwyse7/i386/halp.h5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ix8259.inc5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixbeep.asm5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixbusdat.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixcmos.asm5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixcmos.inc5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixdat.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixenvirv.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixfirm.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixhwsup.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixidle.asm5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixinfo.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixisa.h5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixisabus.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixisasup.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixkdcom.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixkdcom.h5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixphwsup.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixreboot.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixthunk.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/ixusage.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/wy7000mp.inc368
-rw-r--r--private/ntos/nthals/halwyse7/i386/wyclock.asm1292
-rw-r--r--private/ntos/nthals/halwyse7/i386/wydetect.asm167
-rw-r--r--private/ntos/nthals/halwyse7/i386/wyhal.c378
-rw-r--r--private/ntos/nthals/halwyse7/i386/wyipi.asm775
-rw-r--r--private/ntos/nthals/halwyse7/i386/wyirql.asm667
-rw-r--r--private/ntos/nthals/halwyse7/i386/wymapint.c185
-rw-r--r--private/ntos/nthals/halwyse7/i386/wynmi.asm108
-rw-r--r--private/ntos/nthals/halwyse7/i386/wyspin.asm449
-rw-r--r--private/ntos/nthals/halwyse7/i386/wysproc.c465
-rw-r--r--private/ntos/nthals/halwyse7/i386/wysproca.asm436
-rw-r--r--private/ntos/nthals/halwyse7/i386/wyswint.asm336
-rw-r--r--private/ntos/nthals/halwyse7/i386/wysysint.asm615
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxbiosa.asm5
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxbiosc.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxdisp.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxflshbf.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxioacc.asm5
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxkdsup.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxmemory.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxstubs.c5
-rw-r--r--private/ntos/nthals/halwyse7/i386/xxtime.c5
44 files changed, 6396 insertions, 0 deletions
diff --git a/private/ntos/nthals/halwyse7/i386/halnls.h b/private/ntos/nthals/halwyse7/i386/halnls.h
new file mode 100644
index 000000000..e829faba8
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/halnls.h
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\halnls.h"
diff --git a/private/ntos/nthals/halwyse7/i386/halp.h b/private/ntos/nthals/halwyse7/i386/halp.h
new file mode 100644
index 000000000..a9dbf1e13
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/halp.h
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\halp.h"
diff --git a/private/ntos/nthals/halwyse7/i386/ix8259.inc b/private/ntos/nthals/halwyse7/i386/ix8259.inc
new file mode 100644
index 000000000..b9e0a196a
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ix8259.inc
@@ -0,0 +1,5 @@
+;
+; Include code from halx86
+; This is a cpp style symbolic link
+
+include ..\halx86\i386\ix8259.inc
diff --git a/private/ntos/nthals/halwyse7/i386/ixbeep.asm b/private/ntos/nthals/halwyse7/i386/ixbeep.asm
new file mode 100644
index 000000000..f53bd3e58
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixbeep.asm
@@ -0,0 +1,5 @@
+;
+; Include code from halx86
+; This is a cpp style symbolic link
+
+include ..\halx86\i386\ixbeep.asm
diff --git a/private/ntos/nthals/halwyse7/i386/ixbusdat.c b/private/ntos/nthals/halwyse7/i386/ixbusdat.c
new file mode 100644
index 000000000..a42039752
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixbusdat.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixbusdat.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixcmos.asm b/private/ntos/nthals/halwyse7/i386/ixcmos.asm
new file mode 100644
index 000000000..7f4e7393e
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixcmos.asm
@@ -0,0 +1,5 @@
+;
+; Include code from halx86
+; This is a cpp style symbolic link
+
+include ..\halx86\i386\ixcmos.asm
diff --git a/private/ntos/nthals/halwyse7/i386/ixcmos.inc b/private/ntos/nthals/halwyse7/i386/ixcmos.inc
new file mode 100644
index 000000000..2fe289fb0
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixcmos.inc
@@ -0,0 +1,5 @@
+;
+; Include code from halx86
+; This is a cpp style symbolic link
+
+include ..\halx86\i386\ixcmos.inc
diff --git a/private/ntos/nthals/halwyse7/i386/ixdat.c b/private/ntos/nthals/halwyse7/i386/ixdat.c
new file mode 100644
index 000000000..f6b0e34de
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixdat.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixdat.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixenvirv.c b/private/ntos/nthals/halwyse7/i386/ixenvirv.c
new file mode 100644
index 000000000..e194820ba
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixenvirv.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixenvirv.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixfirm.c b/private/ntos/nthals/halwyse7/i386/ixfirm.c
new file mode 100644
index 000000000..f666e405c
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixfirm.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixfirm.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixhwsup.c b/private/ntos/nthals/halwyse7/i386/ixhwsup.c
new file mode 100644
index 000000000..ea91dc8d0
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixhwsup.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixhwsup.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixidle.asm b/private/ntos/nthals/halwyse7/i386/ixidle.asm
new file mode 100644
index 000000000..9bdd670f3
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixidle.asm
@@ -0,0 +1,5 @@
+;
+; Include code from halx86
+; This is a cpp style symbolic link
+
+include ..\halx86\i386\ixidle.asm
diff --git a/private/ntos/nthals/halwyse7/i386/ixinfo.c b/private/ntos/nthals/halwyse7/i386/ixinfo.c
new file mode 100644
index 000000000..7f211f7a9
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixinfo.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixinfo.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixisa.h b/private/ntos/nthals/halwyse7/i386/ixisa.h
new file mode 100644
index 000000000..f67b35f49
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixisa.h
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixisa.h"
diff --git a/private/ntos/nthals/halwyse7/i386/ixisabus.c b/private/ntos/nthals/halwyse7/i386/ixisabus.c
new file mode 100644
index 000000000..c1edfb067
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixisabus.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixisabus.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixisasup.c b/private/ntos/nthals/halwyse7/i386/ixisasup.c
new file mode 100644
index 000000000..58c426544
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixisasup.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixisasup.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixkdcom.c b/private/ntos/nthals/halwyse7/i386/ixkdcom.c
new file mode 100644
index 000000000..29bb8308e
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixkdcom.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixkdcom.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixkdcom.h b/private/ntos/nthals/halwyse7/i386/ixkdcom.h
new file mode 100644
index 000000000..22f1aac09
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixkdcom.h
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixkdcom.h"
diff --git a/private/ntos/nthals/halwyse7/i386/ixphwsup.c b/private/ntos/nthals/halwyse7/i386/ixphwsup.c
new file mode 100644
index 000000000..a1cdab598
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixphwsup.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixphwsup.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixreboot.c b/private/ntos/nthals/halwyse7/i386/ixreboot.c
new file mode 100644
index 000000000..15d7bd898
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixreboot.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixreboot.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixthunk.c b/private/ntos/nthals/halwyse7/i386/ixthunk.c
new file mode 100644
index 000000000..6f15aad73
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixthunk.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixthunk.c"
diff --git a/private/ntos/nthals/halwyse7/i386/ixusage.c b/private/ntos/nthals/halwyse7/i386/ixusage.c
new file mode 100644
index 000000000..519ec31f3
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/ixusage.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\ixusage.c"
diff --git a/private/ntos/nthals/halwyse7/i386/wy7000mp.inc b/private/ntos/nthals/halwyse7/i386/wy7000mp.inc
new file mode 100644
index 000000000..34222ea50
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wy7000mp.inc
@@ -0,0 +1,368 @@
+;++
+; Copyright (c) 1992, 1993 Wyse Technology
+;
+; Module Name:
+;
+; wy7000mp.inc
+;
+; Abstract:
+;
+; Wyse 7000i MP include file
+;
+; Author:
+; John Nels Fuller (o-johnf) 3-Apr-1992
+;--
+
+;*****************************
+; Wyse 7000i MP defines
+;
+WyModel740 Equ 00170335Fh ;EISA id for model 740 system board
+WyModel760 Equ 00178335Fh ;EISA id for model 760 system board
+WyModel780 Equ 00978335Fh ;EISA id for model 780 system board
+; ;(model hasn't been named, but
+; ; 780 is as good as anything)
+
+WyUPcpu Equ 00171335Fh ;EISA id for UP-cpu (can only be
+ ; read through EISA_ReadId)
+WyMPcpu Equ 00179335Fh ;EISA id for MP-cpu (can only be
+ ; read through EISA_ReadId)
+WyIDmask Equ 00FFFFFFFh ;mask out rev/speed for cpu id
+
+WyShadowArea Equ 0000F0000h ;physical address of BIOS RAM shadow
+WyShadowLength Equ 000010000h ;length of BIOS RAM shadow (64Kb)
+
+WarmResetVector Equ 000000467h ;address of low mem reset variable
+
+EISA_Functions Equ 00000F859h ;offset into BIOS of EISA Int 15h
+EISA_ReadId Equ 00000D884h ;function to read EISA slot ID
+MPFW_FuncTable Equ 0FFFE0100h ;physical address of F/W function table
+ fnICU_Sync_Mstr Equ 25h ;function number of F/W routine to
+ ; cause specified cpu's to sync and
+ ; report back (used to verify that
+ ; installed cpu's are running)
+ fnICU_Send_Mstr Equ 23h ;function number of F/W routine to
+ ; send command/data packtets to other
+ ; cpu's (cpu's must be running in
+ ; F/W or Diag as at boot time).
+ fnOS_Diag_Mon Equ 0Dh ;function number of O/S transfer
+ ; to Diagnostic monitor
+ fnOS_Panic Equ 0Ch ;function number of O/S transfer
+ ; to Diagnostic monitor for NMI/crash
+ ; panic
+
+; These four reigisters access the bus control unit chip (BCU) for the
+; Wyse Wyde Bus(tm) (WWB), CpuIntCmd and CpuPriortyLevel are read only
+; except for the local cpu (i.e. My+CpuIntCmt and My+CpuPriortyLevel).
+
+CpuPtrReg Equ 0800h ;cpu pointer register (add WWB slot*16)
+CpuDataReg Equ 0804h ;cpu data register (add WWB slot*16)
+CpuIntCmd Equ 0802h ;cpu interrupt cmd reg (add WWB slot*16)
+CpuPriortyLevel Equ 0806h ;cpu int priority level (add WWB slot*16)
+
+; These two registers access the cache control unit chip (CCU)
+; (80486 mp-cpu's only)
+
+CpuCCUptr Equ 0C00h ;CCU pointer register (add WWB slot*16)
+CpuCCUdata Equ 0C02h ;CCU data register (add WWB slot*16)
+
+; These three registers access the three Wyde Bus Interface chips (WBI)
+; (80486 mp-cpu's only)
+
+CpuWBIlow Equ 0C04h ;low WBI register (add WWB slot*16)
+CpuWBIhigh Equ 0C06h ;high WBI register (add WWB slot*16)
+CpuWBIaddr Equ 0C08h ;addr WBI register (add WWB slot*16)
+
+; These two registers access the WWB Data Controller chip (WDC)
+; (Pentium cpu's only) (DON'T add WWB slot*16 to these addresses)
+
+MyCpuWDCptr Equ 0CF0h ;WDC pointer register
+MyCpuWDCdata Equ 0CF2h ;WDC data register
+
+; These two registers access the WWB Data Path chip (WDP)
+; (Pentium cpu's only) (DON'T add WWB slot*16 to these addresses)
+
+MyCpuWDPlow Equ 0CF4h ;low WDP register
+MyCpuWDPhigh Equ 0CF6h ;high WDP register
+
+; Each cpu has a 16450 uart connected to the diagnostic serial port
+; on the back of the machine, only one cpu's 16450 is enabled (normally
+; processor 0) so the WWB slot for that cpu must be used for other
+; cpu's to access it. However, not all variations of cpu boards
+; support access to this uart from another cpu.
+
+CpuDiagUart Equ 0808h ;16450 base address (add WWB slot*16)
+
+; Use these fixed WWB slots numbers for modifing above i/o addresses
+
+My Equ 00F0h ;WWB slot number specifies local cpu
+Sys Equ 0000h ;WWB slot number for system board
+ ; use for 760/780 system board only
+ ; and only for BCU/ICU registers
+;
+; The following registers are accessed by writing the register number
+; to CpuPtrReg and then reading or writing the 16-bit data at CpuDataReg
+; each 16-bit access to CpuDataReg toggles bit 1 of CpuPtrReg so, for
+; example to access both ICU_IMR0 and ICU_IMR1 write ICU_IMR0 to
+; CpuPtrReg and do two 16-bit i/o's to CpuDataReg to access first the
+; low word and then the high word of the mask register.
+;
+ICU_SYS_CPU Equ 00h ;system cpu config register
+ICU_CPU_MASTER Equ 04h ;system cpu master register
+ICU_CPU_SYNC Equ 08h ;cpu synchronization register
+BCU_STAT0 Equ 0Ch ;BCU status register 0
+ PERR_LOW Equ 02h ;parity error, low 32-bits of data bus
+ PERR_HIGH Equ 04h ;parity error, high 32-bits of data bus
+ PERR_ADDR Equ 08h ;parity error, address bus
+ PERR_CCU Equ 10h ;cache control unit error
+ PERR_TAG Equ 20h ;snoop tag parity error
+ NOT_FAIL Equ 80h ;when zero red LED on CPU is on
+CPU_STAT Equ 10h ;CPU status register
+BCU_ID Equ 14h ;Slot identification (bits 0-3)
+ WWB_ID_MASK Equ 0Fh ;these bits are WWB slot number
+BCU_GPR Equ 18h ;General purpose register
+BCU_BCTLR Equ 1Ch ;BCU control register
+ A20M_WWB Equ 01h ;when set gate A20 comes from 8042
+ A20M_CPU Equ 02h ;when set forces A20 to be masked
+ SLOW_ENB Equ 04h ;when set allows CPUSlowDown from
+ ; EISA chipset to drive CPU Hold
+ ; (for 8Mhz emulation)
+ SNP_ENB Equ 08h ;when set the cache snoops bus cycles
+ BCU_FWT Equ 10h ;when set two extra clocks are inserted
+ ; in cache line operations
+BCU_ERRCTLR Equ 20h ;BCU error control register
+ ERR_MODE Equ 03h ;error mode field mask
+ ERR_MODE0 Equ 00h ;report no errors
+ ERR_MODE1 Equ 01h ;Local CPU gets NMI (only local CPU
+ ; can see this)
+ ERR_MODE2 Equ 02h ;report to WWB NMI line (all CPU's
+ ; may see this)
+ ERR_MODE3 Equ 03h ;report on WWB PCHK line (all CPU's
+ ; and ISP may see this, ISP may assert
+ ; WWB NMI in response)
+ NMI_ENB Equ 04h ;enable NMI's to CPU
+ WWB_NMI Equ 08h ;enable WWB NMI to cause NMI this CPU
+ WWB_PCHK Equ 10h ;enable WWB PCHK to cause NMI this CPU
+BCU_STAT1 Equ 24h ;BCU status register 1
+ NMISRC_WWB Equ 01h ;NMI source is WWB NMI
+ NMISRC_PCHK Equ 02h ;NMI source is WWB PCHK
+ NMISRC_BTO Equ 04h ;NMI source is WWB bus timeout
+ NMISRC_EXT Equ 08h ;NMI source is NMI button on CPU
+ NMISRC_ICU Equ 10h ;NMI source is ICU (send NMI to Slot)
+ICU_DATA Equ 40h ;ICU data register
+ICU_ICTLR Equ 44h ;ICU control register
+ WWB_INT Equ 01h ;specifies this ICU to be master
+ IACK_MODE Equ 02h ;set for MP interrupt mode
+ ICU_AEOI Equ 04h ;automatic EOI for ICU interrupts
+ INT_ENB Equ 08h ;enable interrupts from ICU
+ TMR_TEST Equ 10h ;select timer test mode
+ IVP_TEST Equ 40h ;select Int Vector Processor test mode
+ MSK_CPURST Equ 80h ;set to prevent 8042 from reseting cpu
+ICU_IMR0 Equ 48h ;ICU int mask register (low 16 bits)
+ICU_IMR1 Equ 4Ah ;ICU int mask register (high 16 bits)
+ IMR_MASK Equ 007FFFFFh ;only bits 0-22 are valid
+ICU_MSKPND0 Equ 4Ch ;ICU masked pending register (low)
+ICU_MSKPND1 Equ 4Eh ;ICU masked pending register (high)
+ICU_VB0 Equ 50h ;vector base register 0
+ICU_VB1 Equ 54h ;vector base register 1
+ICU_VB2 Equ 58h ;vector base register 2
+ICU_STAT Equ 5Ch ;ICU status register
+ INSERV0 Equ 01h ;int in service bit 0
+ INSERV1 Equ 02h ;int in service bit 1
+ICU_PSR0 Equ 60h ;pending status register (low)
+ICU_PSR1 Equ 62h ;pending status register (high)
+ICU_CNT_VAL Equ 64h ;timer count current value
+ICU_CNT_REG Equ 68h ;timer count register
+ICU_LIPTR Equ 6Ch ;local interrupt ptr register
+ ;each field specifies the Local/IPI
+ ;interrupt level of a local bus intr.
+ ;with 0 meaning the intr. is disabled
+ ;Each Local/IPI int level maps to a
+ ;specific CpuPriorityLevel (CPL)--see
+ ;chart in WYIRQL.ASM. CPL is also the
+ ;bit # in ICU_IMR to mask the level.
+ lipSlot Equ 7000h ;mask for slot IPI interrupt
+ lipSlotShl Equ 12 ;shift for slot IPI interrupt field
+ lipSlotVal Equ 1 Shl lipSlotShl ;IPI level used by this Hal
+ lipSlotCPL Equ 1 ;CPL / IMR bit number
+ lipGlobal Equ 0700h ;mask for global IPI interrupt
+ lipGlobalShl Equ 8 ;shift for global IPI interrupt field
+ lipGlobalVal Equ 3 Shl lipGlobalShl ;IPI level used by this Hal
+ lipGlobalCPL Equ 3 ;CPL / IMR bit number
+ lipSerial Equ 0070h ;mask for diagnostic uart interrupt
+ lipSerialShl Equ 4 ;shift for uart interrupt field
+ lipSerialVal Equ (lipGlobalVal Shr lipGlobalShl) Shl lipSerialShl
+ ;use same as Global
+ lipSerialCPL Equ lipGlobalCPL ;CPL / IMR bit number
+ lipTimer Equ 0007h ;mask for local timer interrupt
+ lipTimerShl Equ 0 ;shift for timer interrupt field
+ lipTimerVal Equ 2 Shl lipTimerShl ;IPI level used by this Hal
+ lipTimerCPL Equ 2 ;CPL / IMR bit number
+ lipDefault Equ lipSlotVal+lipTimerVal+lipSerialVal+0 ;Global off
+ICU_CNTREC Equ 70h ;recovery count register
+ICU_VIN Equ 74h ;vector in register
+ICU_VOUT Equ 78h ;vector out register
+SYS_WBI_LOW Equ 0F0h ;low WBI register (system board only)
+SYS_WBI_HIGH Equ 0F4h ;high WBI register (system board only)
+SYS_WBI_ADDR Equ 0F8h ;addr WBI register (system board only)
+
+;
+; The following describes the CpuIntCmd register
+;
+ICU_CMD_BUSY Equ 0100h ;do not issue command while set
+ICU_IPI_SLOT Equ 0060h ;IPI cpu in slot (add WWB slot number)
+ICU_CLR_INSERV0 Equ 00E8h ;clear interrupt in service bit 0
+ICU_CLR_INSERV1 Equ 00E9h ;clear interrupt in service bit 1
+ICU_XMT_INT_SND Equ 0020h ;rebroadcast int (add CPL of int)
+ ;(cannot be used for CLOCK2/IPI)
+ICU_XMT_GLB_INT Equ 00E0h ;Send global interrupt
+
+;
+; The following describes each WBI register
+;
+WBI_SLT_MSK Equ 000Fh ;WWB slot number
+WBI_FPAR_ERR Equ 0010h ;force parity error for diagnostics
+WBI_IACK_MODE Equ 0020h ;set for MP interrupt acknowlege mode
+WBI_FWT Equ 0040h ;force 2 clock cycles on Cpu bus
+; Equ 0080h ;reserved
+WBI_PE_IN_0 Equ 0100h ;for data WBI's:
+ ; parity err in 1st inbound data phase
+ ;for addr WBI:
+ ; parity err in inbound address
+WBI_PE_IN_1 Equ 0200h ;for data WBI's:
+ ; parity err in 2nd inboud data phase
+ ;for addr WBI:
+ ; parity err in inbound address
+WBI_PE_OUT_CPU Equ 0400h ;data parity err outbound data from cpu
+WBI_PE_OUT_CSH Equ 0800h ;data perr outbound data from cache
+WBI_PE_BYTE0 Equ 1000h ;parity error in byte lane 0
+WBI_PE_BYTE1 Equ 2000h ;parity error in byte lane 1
+WBI_PE_BYTE2 Equ 4000h ;parity error in byte lane 2
+WBI_PE_BYTE3 Equ 8000h ;parity error in byte lane 3
+
+; The following describes the bits in the WDP register that concern HAL
+;
+WDP_IACK_MODE Equ 0020h ;set for MP interrupt acknowlege mode
+WDP_FPE_EN Equ 0040h ;enable CPU FERR onto WWB (to IRQ13)
+
+;
+; The following registers are accessed by writing the register number
+; to CpuCCUptr and then reading or writing the 16-bit data at CpuCCUdata.
+;
+CCU_CR Equ 00h ;CCU control register
+ CACHE_EN Equ 0001h ;enable secondary cache
+ BURST_EN Equ 0002h ;enable CPU burst cycles
+ WWB_FPE_EN Equ 0004h ;enable CPU FERR onto WWB (to IRQ13)
+ ;(reset to use int 10h trap for
+ ; floating point errors, thus
+ ; preventing IRQ13's for FP err)
+ TPEN Equ 0008h ;cache tag parity enable
+ SHADOW_ROM_EN Equ 0010h ;enable BIOS ROM shadow in 1st Mb
+ AMOD Equ 0020h ;enable local memory mapped I/O to
+ ; cache data/tags for diagnostics,
+ ; flash rom write area, diagnostic
+ ; ROM area.
+ SRAM_MODE Equ 0040h ;specifies type of SRAM used for
+ ; cache, standard/~synchronous
+ SYSCONFIG Equ 0080h ;allows configuration cycles to be
+ ; run on WWB
+ PCD_EN Equ 0100h ;enables use of cpu PCD output
+ RDWT Equ 0200h ;adds one wait cycle to reads
+ WRWT_MSK Equ 0C00h ;mask for write wait cycle count field
+ BRWT Equ 1000h ;adds one wiat state on cpu burst reads
+ FST_ODD Equ 2000h ;force odd parity on cache state bits
+ ; for diagnostics
+ FTAG_ODD Equ 4000h ;force odd parity on cache tag bits
+ ; for diagnostics
+ CCU_FWT Equ 8000h ;force two clocks for cache-WBI data
+ ; transfers (cache fill, copy back,
+ ; intervention, & snoop update)
+CCU_ERR0 Equ 18h ;CCU latched error status register 0
+ TPAR Equ 0001h ;tag parity bit
+ SNP_ERR Equ 0002h ;snoop error
+ TAG_DATA Equ 1FFCh ;tag data bits
+ CCU_STATE Equ 6000h ;cache line state bits:
+ ; 0=default, 1=exclusive, 2=shared
+ ; 3=modified
+ SPAR Equ 8000h ;state parity bit
+CCU_ERR1 Equ 1Ah ;CCU latched error status register 1
+ TAGINDEX Equ 3FFFh ;tag index address
+ CPU_DPE Equ 4000h ;cpu data parity error
+ VALID_ERROR Equ 8000h ;set when CCU_ERR0,1 have valid info
+CCU_ID Equ 1Ch ;CCU has WWB slot number
+;*****************************
+; end of list
+
+
+;
+; The kernel leaves some space (64 byte) of the PCR for the HAL to use
+; as it needs. Currently this space is used for some efficiency in
+; some of the MP specific code and is highly implementation
+; dependant.
+;
+
+
+PcHalData struc
+; pchStallCnt dd ? ;per processor stall count
+ pchCurLiptr dd ? ;per processor current ICU_LIPTR
+ pchPrNum db ? ;NT's processor number
+ pchPrSlot db ? ;WWB processor slot
+ pchPentiumFlag db ? ;non-zero if current cpu is a Pentium
+ pchHwIrql db ? ;Irql to which CpuPriorityLevel is
+ ;programmed. Due to lazy Irql's this
+ ;may be different than PcIrql
+PcHalData ends
+
+
+cr equ 0ah
+lf equ 0dh
+
+PIC1_BASE equ PRIMARY_VECTOR_BASE
+PIC2_BASE equ PRIMARY_VECTOR_BASE + 8
+IPIv_BASE equ PRIMARY_VECTOR_BASE + 16
+
+PIC_SLAVE_IRQ equ 2
+
+IFDEF STD_CALL
+
+enproc macro pn
+ if DBG
+ %out enproc pn
+ ifndef _ProcSub@4
+ extrn _ProcSub@4:NEAR
+ endif ;_ProcSub
+ push pn ;save routine number
+ call _ProcSub@4 ;write to BCU_GPR
+ endif ;DBG
+ endm
+
+exproc macro pn
+ if DBG
+ %out exproc pn
+ push (pn) or 80h ;save routine number and exit flag
+ call _ProcSub@4 ;write to BCU_GPR
+ endif ;DBG
+ endm
+
+ELSE
+
+enproc macro pn
+ if DBG
+ %out enproc pn
+ ifndef _ProcSub
+ extrn _ProcSub:NEAR
+ endif ;_ProcSub
+ push pn ;save routine number
+ call _ProcSub ;write to BCU_GPR
+ lea esp, [esp][4] ;remove parameter w/o altering flags
+ endif ;DBG
+ endm
+
+exproc macro pn
+ if DBG
+ %out exproc pn
+ push (pn) or 80h ;save routine number and exit flag
+ call _ProcSub ;write to BCU_GPR
+ lea esp, [esp][4] ;remove parameter w/o altering flags
+ endif ;DBG
+ endm
+ENDIF
diff --git a/private/ntos/nthals/halwyse7/i386/wyclock.asm b/private/ntos/nthals/halwyse7/i386/wyclock.asm
new file mode 100644
index 000000000..c2335419b
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wyclock.asm
@@ -0,0 +1,1292 @@
+ title "Interval Clock Interrupt"
+;++
+;
+; Copyright (c) 1989-1993 Microsoft Corporation
+; Copyright (c) 1992, 1993 Wyse Technology
+;
+; Module Name:
+;
+; wyclock.asm
+;
+; Abstract:
+;
+; This module implements the code necessary to field and process the
+; interval clock interrupt.
+;
+; Author:
+;
+; Shie-Lin Tzong (shielint) 12-Jan-1990
+;
+; Environment:
+;
+; Kernel mode only.
+;
+; Revision History:
+;
+; bryanwi 20-Sep-90
+;
+; Add KiSetProfileInterval, KiStartProfileInterrupt,
+; KiStopProfileInterrupt procedures.
+; KiProfileInterrupt ISR.
+; KiProfileList, KiProfileLock are delcared here.
+;
+; shielint 10-Dec-90
+; Add performance counter support.
+; Move system clock to irq8, ie we now use RTC to generate system
+; clock. Performance count and Profile use timer 1 counter 0.
+; The interval of the irq0 interrupt can be changed by
+; KiSetProfileInterval. Performance counter does not care about the
+; interval of the interrupt as long as it knows the rollover count.
+; Note: Currently I implemented 1 performance counter for the whole
+; i386 NT. It works on UP and SystemPro.
+;
+; John Vert (jvert) 11-Jul-1991
+; Moved from ke\i386 to hal\i386. Removed non-HAL stuff
+;
+; shie-lin tzong (shielint) 13-March-92
+; Move System clock back to irq0 and use RTC (irq8) to generate
+; profile interrupt. Performance counter and system clock use time1
+; counter 0 of 8254.
+;
+; John Fuller (o-johnf) 1-Apr-92
+; convert to Wyse 7000i MP system, clock goes to cpu's local timer,
+; profile interrupt and performance counter use 8254 timer1 counter 0,
+; use cpu's local timer to initialize stall execution.
+;--
+
+.386p
+ .xlist
+include hal386.inc
+include callconv.inc ; calling convention macros
+include i386\ix8259.inc
+include i386\kimacro.inc
+include mac386.inc
+include i386\wy7000mp.inc
+ .list
+
+ extrn ReadMyCpuReg:NEAR
+ extrn WriteMyCpuReg:NEAR
+ EXTRNP _DbgBreakPoint,0,IMPORT
+ EXTRNP _KeUpdateSystemTime,0
+ EXTRNP _KeUpdateRunTime,1,IMPORT
+ EXTRNP _KeProfileInterrupt,1,IMPORT
+ EXTRNP _KeSetTimeIncrement,2,IMPORT
+ EXTRNP Kei386EoiHelper,0,IMPORT
+ EXTRNP _HalEndSystemInterrupt,2
+ EXTRNP _HalBeginSystemInterrupt,3
+ EXTRNP _HalpAcquireCmosSpinLock ,0
+ EXTRNP _HalpReleaseCmosSpinLock ,0
+ extrn _HalpIRQLtoCPL:BYTE
+ extrn _HalpIRQLtoVector:BYTE
+
+;
+; Constants used to initialize timer 0
+;
+
+TIMER1_DATA_PORT0 EQU 40H ; Timer1, channel 0 data port
+TIMER1_CONTROL_PORT0 EQU 43H ; Timer1, channel 0 control port
+TIMER2_DATA_PORT0 EQU 48H ; Timer1, channel 0 data port
+TIMER2_CONTROL_PORT0 EQU 4BH ; Timer1, channel 0 control port
+TIMER1_IRQ EQU 0 ; Irq 0 for timer1 interrupt
+
+COMMAND_8254_COUNTER0 EQU 00H ; Select count 0
+COMMAND_8254_RW_16BIT EQU 30H ; Read/Write LSB firt then MSB
+COMMAND_8254_MODE2 EQU 4 ; Use mode 2
+COMMAND_8254_BCD EQU 0 ; Binary count down
+COMMAND_8254_LATCH_READ EQU 0 ; Latch read command
+
+PERFORMANCE_FREQUENCY EQU 1193000
+
+;
+; Constants used to initialize CMOS/Real Time Clock
+;
+
+D_INT032 EQU 8E00h ; access word for 386 ring 0 interrupt gate
+
+RTC_OFFSET_SECOND EQU 0 ; second field of RTC memory
+RTC_OFFSET_MINUTE EQU 2 ; minute field of RTC memory
+RTC_OFFSET_HOUR EQU 4 ; hour field of RTC memory
+RTC_OFFSET_DAY_OF_WEEK EQU 6 ; day-of-week field of RTC memory
+RTC_OFFSET_DATE_OF_MONTH EQU 7 ; date-of-month field of RTC memory
+RTC_OFFSET_MONTH EQU 8 ; month field of RTC memory
+RTC_OFFSET_YEAR EQU 9 ; year field of RTC memory
+RTC_OFFSET_CENTURY EQU 32h ; Century field of RTC memory
+
+;
+; ==== Values used for System Clock ====
+;
+
+; Convert the interval to rollover count for ICU local timer (ltimer) device.
+; Since ltimer counts down a 16 bit value at a one count every 240ns and the
+; interval is in units of 100ns, the computation is:
+; RolloverCount = (Interval*10)/24 = (Interval*5)/12
+; Therefore, for an integral RolloverCount, Interval must be a multiple of
+; 1.2us. Since RolloverCount is a 16-bit count the maximum Interval is
+; (65535*12)/5 or 15.7284ms.
+;
+; For the convience of HalpInitializeStallExecution the TIME_INCREMENT
+; should be chosen to be an integral number of microseconds. Hence
+; TIME_INCREMENT should be a multiple of 60 (6us).
+;
+; The default Interrupt interval is 10.002ms (8335 * 1.2us)
+;
+
+TIME_INCREMENT EQU 100020 ; 10.002ms
+ROLLOVER_COUNT EQU (TIME_INCREMENT*5)/12
+
+;
+; ==== Values used for performance counter
+;
+; Maximum counter value for timer1 (8254) and its corresponding interrupt
+; interval. These values are for profiling and performance counter support.
+;
+; This value is equivalent to a value of zero (counter is 16-bit).
+; So, the rollover rate is approximately 18.2 Hz.
+; Note this value will be used if no profiling support.
+;
+MAXIMUM_ROLLOVER_COUNT Equ 0FFFFh
+MAXIMUM_ROLLOVER_INTERVAL Equ 861D2h ; in 100ns units
+
+_DATA SEGMENT DWORD PUBLIC 'DATA'
+
+;
+; The following array stores the per microsecond loop count for each
+; central processor.
+;
+
+;
+; 8254 spinlock. This must be acquired before touching the 8254 chip.
+;
+ public _Halp8254Lock
+
+_Halp8254Lock dd 0
+
+;
+; Init Stall count must have a spin lock. This lock is held a long time
+; but only processors tring to initialize the stall count will wait.
+;
+iscSpinLock dd 0
+
+HalpProfileRolloverCnt dd MAXIMUM_ROLLOVER_COUNT
+ public HalpPerfCounterLow
+ public HalpPerfCounterHigh
+HalpPerfCounterLow dd 0
+HalpPerfCounterHigh dd 0
+HalpRollOverCount dd 0
+HalpNextRolloverCount dd MAXIMUM_ROLLOVER_COUNT
+HalpProfilingStopped dd -1 ;stopped when this is negative
+HalpPerfCounterInit dd 0
+ public HalpHackEsp
+HalpHackEsp dd 0
+
+_DATA ends
+
+
+_TEXT SEGMENT DWORD PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
+
+ page ,132
+ subttl "Initialize Clock"
+;++
+;
+; VOID
+; HalpInitializeClock (
+; )
+;
+; Routine Description:
+;
+; This routine initialize system time clock using the local timer
+; to generate an interrupt at every 15ms interval
+;
+; See the definition of TIME_INCREMENT and ROLLOVER_COUNT if clock rate
+; needs to be changed.
+;
+; Arguments:
+;
+; None
+;
+; Return Value:
+;
+; None.
+;
+;--
+cPublicProc _HalpInitializeClock ,0
+ enproc 4
+
+;
+; Fill in PCR value with TIME_INCREMENT
+;
+
+ mov eax, TIME_INCREMENT
+ stdCall _KeSetTimeIncrement, <eax, eax>
+
+ pushfd ; save caller's eflag
+ cli ; make sure interrupts are disabled
+
+;
+; Set clock rate for Wyse local timer
+;
+ mov al, ICU_CNT_REG
+ mov dx, My+CpuPtrReg
+ out dx, al
+ mov dx, My+CpuDataReg
+ mov ax, ROLLOVER_COUNT
+ out dx, ax
+
+;
+; Initialize rollover count for performance counter and profiling
+;
+ cmp fs:PcHal.pchPrNum, 0 ;master cpu?
+ jne short HICexit ;jump if not
+
+;
+; Since this happens only on master cpu before other cpu's are started
+; we do not need to aquire Halp8254Lock.
+;
+ stdCall _HalpSetRolloverCount, <MAXIMUM_ROLLOVER_COUNT>
+
+HICexit:
+
+ exproc 4
+ popfd ; restore caller's eflag
+ stdRET _HalpInitializeClock
+
+stdENDP _HalpInitializeClock
+
+ page ,132
+ subttl "Initialize Stall Execution Counter"
+;++
+;
+; VOID
+; HalpInitializeStallExecution (
+; IN CCHAR ProcessorNumber
+; )
+;
+; Routine Description:
+;
+; This routine initialize the per Microsecond counter for
+; KeStallExecutionProcessor
+;
+; Arguments:
+;
+; ProcessorNumber - Processor Number
+;
+; Return Value:
+;
+; None.
+;
+; Note:
+;
+; Current implementation assumes that all the processors share
+; the same Real Time Clock. So, the dispatcher database lock is
+; acquired before entering this routine to guarantee only one
+; processor can access the routine.
+;
+;--
+isc00: sti
+ SPIN_ON_SPINLOCK eax, <isc01>
+
+KiseInterruptCount equ [ebp-12] ; local variable
+
+cPublicProc _HalpInitializeStallExecution ,1
+ enproc 7
+
+ push ebp ; save ebp
+ mov ebp, esp ; set up 12 bytes for local use
+ sub esp, 12
+
+ pushfd ; save caller's eflag
+
+;
+; Initialize Cpu Local Timer to interrupt us for every 15ms at
+; PROFILE_LEVEL-19
+;
+;
+; acquire spin lock to prevent two processors from doing this routine at
+; the same time
+;
+isc01: cli
+ lea eax, iscSpinLock
+ ACQUIRE_SPINLOCK eax, isc00
+;
+; Get and save current local interrupt pointer register
+;
+
+ push ICU_LIPTR
+ call ReadMyCpuReg
+ push eax ; save for later
+ push lipTimer ; set to only timer at PROFILE_LEVEL-19
+ ;(must use an otherwise unused level
+ ; or at least one that won't generate
+ ; an interrupt until all processors
+ ; have been started)
+ push ICU_LIPTR
+ call WriteMyCpuReg
+
+;
+; Get and save current ICU interrupt masks
+;
+ push ICU_IMR0
+ call ReadMyCpuReg ; get local interrupt masks (low)
+ shl eax, 16
+ in ax, dx ; get local interrupt masks (high)
+ push eax ; save the masks
+
+ movzx ecx, _HalpIRQLtoCPL[PROFILE_LEVEL-19]
+ mov eax, IMR_MASK ; all ints masked out
+ btr eax, ecx ; clear bit for local timer
+ out dx, ax ; set new mask (low)
+ rol eax, 16
+ out dx, ax ; set new mask (high)
+
+;
+; Since RTC interrupt will come from PROFILE_LEVEL-19, we need to
+; Save original IDT descriptor and set the descriptor to point to
+; our own handler.
+;
+ movzx ecx, _HalpIRQLtoVector[PROFILE_LEVEL-19]
+ sidt fword ptr [ebp-8] ; get IDT address
+ mov edx, [ebp-6] ; (edx)->IDT
+
+ push dword ptr [edx+8*ecx]
+ ; (TOS) = original desc of IRQ 8
+ push dword ptr [edx+8*ecx + 4]
+ ; each descriptor has 8 bytes
+ push edx ; (TOS) -> IDT
+ mov eax, offset FLAT:RealTimeClockHandler
+ mov word ptr [edx+8*ecx], ax
+ ; Lower half of handler addr
+ mov word ptr [edx+8*ecx+2], KGDT_R0_CODE
+ ; set up selector
+ mov word ptr [edx+8*ecx+4], D_INT032
+ ; 386 interrupt gate
+ shr eax, 16 ; (ax)=higher half of handler addr
+ mov word ptr [edx+8*ecx+6], ax
+ mov dword ptr KiseinterruptCount, 0 ; set no interrupt yet
+
+ mov dx, My+CpuPriortyLevel
+ in ax, dx ;get old CPL
+ shl eax, 16
+ push ICU_CNT_REG
+ call ReadMyCpuReg ;read old tick count
+ push eax ;save for later
+ push ROLLOVER_COUNT
+ push ICU_CNT_REG
+ call WriteMyCpuReg
+ movzx eax, _HalpIRQLtoCPL[PROFILE_LEVEL-19]
+ inc eax ;allow this level interrupt
+ mov dx, My+CpuPriortyLevel
+ out dx, ax
+
+;
+; Now enable the interrupt and start the counter
+; (As a matter of fact, only local timer can come through.)
+;
+
+ xor eax, eax ; (eax) = 0, initialize loopcount
+ sti
+kise10:
+ add eax, 1 ; increment the loopcount
+ jnz short kise10
+;
+; Counter overflowed
+;
+
+ stdCall _DbgBreakPoint
+
+;
+; Our RealTimeClock interrupt handler. The control comes here through
+; irq 8.
+; Note: we discard first two real time clock interrupts and compute the
+; permicrosecond loopcount on receiving of the third real time
+; interrupt. This is because the first interrupt may be already
+; pending in which case the second is generated based on the previous
+; real time tick interval.
+;
+
+RealTimeClockHandler:
+
+ inc dword ptr KiseInterruptCount ; increment interrupt count
+ cmp dword ptr KiseInterruptCount, 2 ; Is this 1st or 2nd interrupt?
+ ja short kise25 ; no, its the third go process it
+ pop eax ; get rid of original ret addr
+ push offset FLAT:kise10 ; set new return addr
+
+;
+; dismiss interrupt at ICU
+;
+ mov dx, My+CpuIntCmd
+@@: in ax, dx
+ test eax, ICU_CMD_BUSY
+ jnz @B
+ mov al, ICU_CLR_INSERV1 ; clear interrupt in service bit
+ out dx, ax
+
+ xor eax, eax ; reset loop counter
+
+cPublicProc _HalpICUSpurious ,0
+ iretd
+stdENDP _HalpICUSpurious
+
+kise25:
+
+;
+; ** temporary - check for incorrect KeStallExecutionProcessorLoopCount
+;
+
+if DBG
+ cmp eax, 0
+ jnz short kise30
+ stdCall _DbgBreakPoint
+
+endif
+ ; never return
+;
+; ** End temporay code
+;
+
+kise30:
+ xor edx, edx ; (edx:eax) = divident
+ mov ecx, TIME_INCREMENT / 10; (ecx) = time spent in the loop
+ div ecx ; (eax) = loop count per microsecond
+ cmp edx, 0 ; Is remainder =0?
+ jz short kise40 ; yes, go kise40
+ inc eax ; increment loopcount by 1
+kise40:
+ movzx ecx, byte ptr [ebp+8] ; Current processor number
+ mov fs:PcStallScaleFactor, eax ; save in per processor data
+
+;
+; Reset return address to kexit
+;
+
+ pop eax ; discard original return address
+ push offset FLAT:kexit ; return to kexit
+
+ and word ptr [esp+8], NOT 0200H ; Disable interrupt upon return
+ iretd
+
+kexit: ; Interrupts are disabled
+; push original tick count (already on stack)
+ push ICU_CNT_REG
+ call WriteMyCpuReg ; restore original tick count
+ shr eax, 16 ; original CPL to AX
+ mov dx, My+CpuPriortyLevel
+ out dx, ax ; restore original CPL
+
+ pop edx ; (edx)->IDT
+ movzx ecx, _HalpIRQLtoVector[PROFILE_LEVEL-19]
+ pop [edx+8*Ecx+4]
+ ; restore higher half of NMI desc
+ pop [edx+8*Ecx]
+ ; restore lower half of NMI desc
+; push original interrupt masks (already on stack)
+ push ICU_IMR1
+ call WriteMyCpuReg ; restore original mask (high)
+ rol eax, 16
+ out dx, ax ; restore original mask (low)
+
+; push original local interrupt pointer (already on stack)
+ push ICU_LIPTR
+ call WriteMyCpuReg ; restore original LIPTR
+
+;
+; dismiss interrupt at ICU
+;
+ mov dx, My+CpuIntCmd
+@@: in ax, dx
+ test eax, ICU_CMD_BUSY
+ jnz @B
+ mov al, ICU_CLR_INSERV1 ; clear interrupt in service bit
+ out dx, ax
+
+ lea eax, iscSpinLock
+ RELEASE_SPINLOCK eax
+
+ exproc 7
+ popfd ; restore caller's eflags
+ mov esp, ebp
+ pop ebp ; restore ebp
+ stdRET _HalpInitializeStallExecution
+
+stdENDP _HalpInitializeStallExecution
+
+ page ,132
+ subttl "Stall Execution"
+;++
+;
+; VOID
+; KeStallExecutionProcessor (
+; IN ULONG MicroSeconds
+; )
+;
+; Routine Description:
+;
+; This function stalls execution for the specified number of microseconds.
+; KeStallExecutionProcessor
+;
+; Arguments:
+;
+; MicroSeconds - Supplies the number of microseconds that execution is to be
+; stalled.
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+MicroSeconds equ [esp + 4]
+
+cPublicProc _KeStallExecutionProcessor ,1
+
+
+ mov ecx, MicroSeconds ; (ecx) = Microseconds
+ jecxz short kese10 ; return if no loop needed
+
+
+ mov eax, fs:PcStallScaleFactor ; get per microsecond
+ ; loop count for the processor
+ mul ecx ; (eax) = desired loop count
+
+if DBG
+
+;
+; Make sure we the loopcount is less than 4G and is not equal to zero
+;
+
+ cmp edx, 0
+ jz short kese
+ stdCall _DbgBreakPoint ; stop ...
+;; align 4
+kese: cmp eax,0
+ jnz short kese0
+ stdCall _DbgBreakPoint ; stop ...
+endif
+
+kese0:
+ sub eax, 1 ; (eax) = (eax) - 1
+ jnz short kese0
+kese10:
+ stdRET _KeStallExecutionProcessor
+
+stdENDP _KeStallExecutionProcessor
+
+
+
+;++
+;
+; PROFILING AND PERFORMANCE COUNTER SUPPORT
+;
+;--
+
+;++
+;
+; HalStartProfileInterrupt(
+; IN ULONG Reserved
+; );
+;
+; Routine Description:
+;
+; What we do here is change the interrupt
+; rate from the slowest thing we can get away with to the value
+; that's been KeSetProfileInterval
+;
+;--
+
+cPublicProc _HalStartProfileInterrupt ,1
+
+;
+; Prevent races by aquiring Halp8254Lock
+;
+
+ pushfd
+HStartPI01:
+ cli
+ test fs:PcHal.pchCurLiptr, lipGlobal
+ jnz short HStartPI08 ;jump if already started
+ lea eax, _Halp8254Lock
+ ACQUIRE_SPINLOCK eax, HStartPI10
+
+;
+; Mark profiling as active
+;
+
+ inc HalpProfilingStopped ;protected by spinlock
+ jnz short HStartPI06 ;jump if RollerCount already set
+
+;
+; Set the interrupt rate to what is actually needed
+;
+
+ stdCall _HalpSetRolloverCount, <HalpProfileRolloverCnt>
+
+HStartPI06:
+ lea eax, _Halp8254Lock
+ RELEASE_SPINLOCK eax
+ push lipDefault+lipGlobalVal
+ push ICU_LIPTR
+ call WriteMyCpuReg
+ mov fs:PcHal.pchCurLiptr, eax
+HStartPI08:
+ popfd
+ stdRET _HalStartProfileInterrupt
+
+HStartPI10:
+ sti
+ SPIN_ON_SPINLOCK eax, HStartPI01
+
+stdENDP _HalStartProfileInterrupt
+
+
+
+;++
+;
+; HalStopProfileInterrupt(
+; IN ULONG Reserved
+; );
+;
+; Routine Description:
+;
+; What we do here is change the interrupt
+; rate from the high profiling rate to the slowest thing we
+; can get away with for PerformanceCounter rollover notification.
+;
+;--
+
+cPublicProc _HalStopProfileInterrupt ,1
+
+;
+; Prevent races
+;
+ pushfd
+HStopPI01:
+ cli
+ test fs:PcHal.pchCurLiptr, lipGlobal
+ jz short HStopPI08 ;jump if already stopped
+ lea eax, _Halp8254Lock
+ ACQUIRE_SPINLOCK eax, HStopPI10
+
+ dec HalpProfilingStopped ;protected by spinlock
+ jns short HStopPI06 ;jump if still someone doing it
+;
+; Set the interrupt rate to "idle"
+;
+
+ stdCall _HalpSetRolloverCount, <MAXIMUM_ROLLOVER_COUNT>
+
+;
+; Turn off profiling hit computation
+;
+
+
+HStopPI06:
+ lea eax, _Halp8254Lock
+ RELEASE_SPINLOCK eax
+ push lipDefault
+ push ICU_LIPTR
+ call WriteMyCpuReg
+ mov fs:PcHal.pchCurLiptr, eax
+HStopPI08:
+ popfd
+ stdRET _HalStopProfileInterrupt
+
+HStopPI10:
+ sti
+ SPIN_ON_SPINLOCK eax, HStopPI01
+stdENDP _HalStopProfileInterrupt
+
+;++
+; ULONG
+; HalSetProfileInterval (
+; ULONG Interval
+; );
+;
+; Routine Description:
+;
+; This procedure sets the interrupt rate (and thus the sampling
+; interval) for the profiling interrupt.
+;
+; If profiling is active (KiProfilingStopped == 0) the actual
+; hardware interrupt rate will be set. Otherwise, a simple
+; rate validation computation is done.
+;
+; Arguments:
+;
+; (TOS+4) - Interval in 100ns unit.
+;
+; Return Value:
+;
+; Interval actually used by system.
+;
+;--
+
+cPublicProc _HalSetProfileInterval ,1
+
+ mov edx, [esp+4] ; [edx] = interval in 100ns unit
+
+ pushfd
+HSetPI01:
+ cli
+ lea eax, _Halp8254Lock
+ ACQUIRE_SPINLOCK eax, HSetPI10
+
+ push edx ; [TOS] = interval
+;
+; Convert the interval to rollover count for Timer1 device.
+; Since timer1 counts down a 16 bit value at a rate of 1.193M counts-per-
+; sec, the computation is:
+; RolloverCount = (Interval * 0.0000001) * (1.193 * 1000000)
+; = Interval * 0.1193
+; = Interval * 1193 / 10000
+;
+
+ mov eax, 1193
+ mul edx ; [edx:eax] = interval * 1193
+ mov ecx, 10000
+ div ecx ; [eax] = rollover count
+ test eax, 0FFFF0000H ; Is high word set?
+ jz short Kspi80 ; if z, no , go initialize 8254
+ pop eax ; else discard original interval
+ push MAXIMUM_ROLLOVER_INTERVAL ; set real interval
+ mov eax, MAXIMUM_ROLLOVER_COUNT ; use max. rollover count
+
+Kspi80:
+ mov HalpProfileRolloverCnt, eax
+ test dword ptr HalpProfilingStopped,-1
+ js short Kspi90
+
+ stdCall _HalpSetRolloverCount, <eax>
+
+Kspi90:
+ lea eax, _Halp8254Lock
+ RELEASE_SPINLOCK eax
+ pop eax ; (eax) = returned Interval
+
+ Popfd
+
+ stdRET _HalSetProfileInterval ; (eax) = cReturn interval
+
+HSetPI10:
+ sti
+ SPIN_ON_SPINLOCK eax, HSetPI01
+stdENDP _HalSetProfileInterval
+
+ page ,132
+ subttl "Set Performance Counter Rollover count"
+;++
+;
+; VOID
+; HalpSetRolloverCount (
+; IN ULONG RolloverCount
+; )
+;
+; Routine Description:
+;
+; This function initialize 8254 timer chip counter 0 to generate
+; timer interrupt at the rate specified by caller. The timer 1 counter0
+; will be initialized to use binary count down, 16-bit counter, and mode
+; 2.
+;
+; Note that 8254 mode 2 will not use the new count immediately. The
+; new count will be loaded at the end of current counting cycle.
+;
+; NOTE: Interrupts must already be disabled and Halp8254Lock must
+; already be aquired!
+;
+; Arguments:
+;
+; RolloverCount [TOS+4] - Value used to set timer 1 counter 0's
+; rollover counter.
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+;
+; Parameter definitions
+;
+
+KsrcRolloverCount equ [esp+4]
+
+cPublicProc _HalpSetRolloverCount ,1
+
+ mov al,COMMAND_8254_COUNTER0+COMMAND_8254_RW_16BIT+COMMAND_8254_MODE2
+ out TIMER1_CONTROL_PORT0, al ;program count mode of timer 0
+ IoDelay
+ mov ecx, KsrcRolloverCount
+ mov HalpNextRolloverCount, ecx ; set new count
+ mov al, cl
+ out TIMER1_DATA_PORT0, al ; program timer 0 LSB count
+ IoDelay
+ mov al,ch
+ out TIMER1_DATA_PORT0, al ; program timer 0 MSB count
+
+ mov HalpPerfCounterInit, 1 ; indicate performance counter has
+ ; been initialized
+ stdRET _HalpSetRolloverCount
+
+stdENDP _HalpSetRollOverCount
+
+ page ,132
+ subttl "Query Performance Counter"
+;++
+;
+; LARGE_INTEGER
+; KeQueryPerformanceCounter (
+; OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
+; )
+;
+; Routine Description:
+;
+; This routine returns current 64-bit performance counter and,
+; optionally, the Performance Frequency.
+;
+; Note this routine can NOT be called at Profiling interrupt
+; service routine. Because this routine depends on IRR0 to determine
+; the actual count.
+;
+; Also note that the performace counter returned by this routine
+; is not necessary the value when this routine is just entered.
+; The value returned is actually the counter value at any point
+; between the routine is entered and is exited.
+;
+; Arguments:
+;
+; PerformanceFrequency [TOS+4] - optionally, supplies the address
+; of a variable to receive the performance counter frequency.
+;
+; Return Value:
+;
+; Current value of the performance counter will be returned.
+;
+;--
+
+;
+; Parameter definitions
+;
+
+KqpcFrequency EQU [esp+12] ; User supplied Performance Frequence
+
+cPublicProc _KeQueryPerformanceCounter ,1
+ push ebx
+ push esi
+
+;
+; First check to see if the performance counter has been initialized yet.
+; Since the kernel debugger calls KeQueryPerformanceCounter to support the
+; !timer command, we need to return something reasonable before 8254
+; initialization has occured. Reading garbage off the 8254 is not reasonable.
+;
+ cmp HalpPerfCounterInit, 0
+ jne Kqpc01 ; ok, perf counter has been initialized
+
+;
+; Initialization hasn't occured yet, so just return zeroes.
+;
+ mov eax, 0
+ mov edx, 0
+ jmp Kqpc20
+
+Kqpc01:
+Kqpc11: pushfd
+ cli
+ lea eax, _Halp8254Lock
+ ACQUIRE_SPINLOCK eax, Kqpc198
+
+;
+; Fetch the base value. Note that interrupts are off.
+;
+; NOTE:
+; Need to watch for Px reading the 'CounterLow', P0 updates both
+; then Px finishes reading 'CounterHigh' [getting the wrong value].
+; After reading both, make sure that 'CounterLow' didn't change.
+; If it did, read it again. This way, we won't have to use a spinlock.
+;
+
+@@:
+ mov ebx, HalpPerfCounterLow
+ mov esi, HalpPerfCounterHigh ; [esi:ebx] = Performance counter
+
+ cmp ebx, HalpPerfCounterLow ;
+ jne @b
+;
+; Fetch the current counter value from the hardware
+;
+
+ mov al, COMMAND_8254_LATCH_READ+COMMAND_8254_COUNTER0
+ ;Latch PIT Ctr 0 command.
+ out TIMER1_CONTROL_PORT0, al
+ IODelay
+ in al, TIMER1_DATA_PORT0 ;Read PIT Ctr 0, LSByte.
+ IODelay
+ movzx ecx,al ;Zero upper bytes of (ECX).
+ in al, TIMER1_DATA_PORT0 ;Read PIT Ctr 0, MSByte.
+ mov ch, al ;(CX) = PIT Ctr 0 count.
+
+ lea eax, _Halp8254Lock
+ RELEASE_SPINLOCK eax
+
+;
+; Now enable interrupts such that if timer interrupt is pending, it can
+; be serviced and update the PerformanceCounter. Note that there could
+; be a long time between the sti and cli because ANY interrupt could come
+; in in between.
+;
+
+ popfd ; don't re-enable interrupts if
+ nop ; the caller had them off!
+ jmp $+2
+
+
+;
+; Fetch the base value again.
+;
+
+@@:
+ mov eax, HalpPerfCounterLow
+ mov edx, HalpPerfCounterHigh ; [edx:eax] = new counter value
+
+ cmp eax, HalpPerfCounterLow
+ jne @b
+
+;
+; Compare the two reads of Performance counter. If they are different,
+; simply returns the new Performance counter. Otherwise, we add the hardware
+; count to the performance counter to form the final result.
+;
+
+ cmp eax, ebx
+ jne short Kqpc20
+ cmp edx, esi
+ jne short Kqpc20
+ neg ecx ; PIT counts down from 0h
+ add ecx, HalpRolloverCount
+ add eax, ecx
+ adc edx, 0 ; [edx:eax] = Final result
+
+;
+; Return the counter
+;
+
+Kqpc20:
+ ; return value is in edx:eax
+
+;
+; Return the freq. if caller wants it.
+;
+
+ or dword ptr KqpcFrequency, 0 ; is it a NULL variable?
+ jz short Kqpc99 ; if z, yes, go exit
+
+ mov ecx, KqpcFrequency ; (ecx)-> Frequency variable
+ mov DWORD PTR [ecx], PERFORMANCE_FREQUENCY ; Set frequency
+ mov DWORD PTR [ecx+4], 0
+
+Kqpc99:
+ pop esi ; restore esi and ebx
+ pop ebx
+ stdRET _KeQueryPerformanceCounter
+
+Kqpc198: popfd
+ SPIN_ON_SPINLOCK eax,<Kqpc11>
+
+stdENDP _KeQueryPerformanceCounter
+
+;++
+;
+; VOID
+; HalCalibratePerformanceCounter (
+; IN volatile PLONG Number
+; )
+;
+; /*++
+;
+; Routine Description:
+;
+; This routine calibrates the performance counter value for a
+; multiprocessor system. The calibration can be done by zeroing
+; the current performance counter, or by calculating a per-processor
+; skewing between each processors counter.
+;
+; Arguments:
+;
+; Number - Supplies a pointer to count of the number of processors in
+; the configuration.
+;
+; Return Value:
+;
+; None.
+;--
+cPublicProc _HalCalibratePerformanceCounter,1
+ mov eax, [esp+4] ; ponter to Number
+ pushfd ; save previous interrupt state
+ cli ; disable interrupts (go to high_level)
+
+ lock dec dword ptr [eax] ; count down
+
+@@: cmp dword ptr [eax], 0 ; wait for all processors to signal
+ jnz short @b
+
+ ;
+ ; Nothing to calibrate on a Wyse MP machine. There is only a single
+ ; 8254 device
+ ;
+
+ popfd ; restore interrupt flag
+ stdRET _HalCalibratePerformanceCounter
+
+stdENDP _HalCalibratePerformanceCounter
+
+
+ page ,132
+ subttl "System Clock Interrupt"
+;++
+;
+; Routine Description:
+;
+;
+; This routine is entered as the result of an interrupt generated by CLOCK2.
+; Its function is to dismiss the interrupt, raise system Irql to
+; CLOCK2_LEVEL, update performance counter and transfer control to the
+; standard system routine to update the system time and the execution
+; time of the current thread
+; and process.
+;
+;
+; Arguments:
+;
+; None
+; Interrupt is disabled
+;
+; Return Value:
+;
+; Does not return, jumps directly to KeUpdateSystemTime, which returns
+;
+; Sets Irql = CLOCK2_LEVEL and dismisses the interrupt
+;
+;--
+ ENTER_DR_ASSIST Hci_a, Hci_t
+
+cPublicProc _HalpClockInterrupt ,0
+
+;
+; Save machine state in trap frame
+;
+
+ ENTER_INTERRUPT Hci_a, Hci_t
+
+;
+; (esp) - base of trap frame
+;
+
+;
+; dismiss interrupt and raise Irql
+;
+
+ movzx eax, _HalpIRQLtoVector[CLOCK2_LEVEL]
+ push eax ; save our interrupt vector number
+ sub esp, 4 ; allocate space to save OldIrql
+
+ stdCall _HalBeginSystemInterrupt, <CLOCK2_LEVEL,eax,esp>
+
+ or al,al ; check for spurious interrupt
+ jz Hci100
+
+;
+; (esp) = OldIrql
+; (esp+4) = Vector
+; (esp+8) = base of trap frame
+; (ebp) = address of trap frame
+;
+ mov eax, TIME_INCREMENT
+
+ cmp fs:PcHal.pchPrNum, 0 ; is this the master cpu?
+ je _KeUpdateSystemTime@0 ; if it is, update system time
+
+ sti
+ stdCall _KeUpdateRunTime,<dword ptr [esp]> ; othewise update runtime
+
+ INTERRUPT_EXIT ; lower irql to old value, iret
+
+Hci100:
+ add esp, 8 ; spurious, no EndOfInterrupt
+ SPURIOUS_INTERRUPT_EXIT ; exit interrupt without eoi
+
+stdENDP _HalpClockInterrupt
+
+ page ,132
+ subttl "System Profile Interrupt"
+;++
+;
+; Routine Description:
+;
+; This routine is entered as the result of a profile interrupt.
+; Its function is to dismiss the interrupt, raise system Irql to
+; PROFILE_LEVEL and transfer control to the standard system routine
+; to process any active profiles.
+;
+; Arguments:
+;
+; None
+; Interrupt is disabled
+;
+; Return Value:
+;
+; Does not return, jumps directly to KeProfileInterrupt, which returns
+;
+; Sets Irql = PROFILE_LEVEL and dismisses the interrupt
+;
+;--
+ ENTER_DR_ASSIST Hpi_a, Hpi_t
+
+cPublicProc _HalpProfileInterrupt ,0
+
+;
+; Save machine state in trap frame
+;
+
+ ENTER_INTERRUPT Hpi_a, Hpi_t
+
+;
+; (esp) - base of trap frame
+;
+
+ movzx eax, _HalpIRQLtoVector[PROFILE_LEVEL]
+ push eax
+ sub esp, 4 ; allocate space to save OldIrql
+ stdCall _HalBeginSystemInterrupt, <PROFILE_LEVEL,eax,esp>
+ or al,al ; check for spurious interrupt
+ jz Hpi100
+;
+; (esp) = OldIrql
+; (esp+4) = H/W vector
+; (esp+8) = base of trap frame
+;
+ test fs:PcHal.pchCurLiptr, lipGlobal
+ je Hpi90 ; if prof disable don't call kernel
+
+ stdCall _KeProfileInterrupt,<ebp> ; (ebp) = trap frame
+
+Hpi90: INTERRUPT_EXIT
+
+Hpi100:
+ add esp, 8 ; spurious, no EndOfInterrupt
+ SPURIOUS_INTERRUPT_EXIT ; exit interrupt without eoi
+
+stdENDP _HalpProfileInterrupt
+
+;++
+;
+; Routine Description:
+;
+; This routine is entered as the result of a performance counter interrupt.
+; Its function is to dismiss the interrupt, raise system Irql to
+; PROFILE_LEVEL-1, update the performance counter, and generate the
+; profile interrupts if any there are any active profiles.
+;
+; Arguments:
+;
+; None
+; Interrupt is disabled
+;
+; Return Value:
+;
+; none
+;
+; Sets Irql = PROFILE_LEVEL-1 and dismisses the interrupt
+;
+;--
+ ENTER_DR_ASSIST Hpci_a, Hpci_t
+
+cPublicProc _HalpPerfCtrInterrupt ,0
+
+;
+; Save machine state in trap frame
+;
+
+ ENTER_INTERRUPT Hpci_a, Hpci_t
+
+;
+; (esp) - base of trap frame
+;
+
+ movzx eax, _HalpIRQLtoVector[PROFILE_LEVEL-1]
+ push eax
+ sub esp, 4 ; allocate space to save OldIrql
+ stdCall _HalBeginSystemInterrupt, <PROFILE_LEVEL-1,eax,esp>
+ or al,al ; check for spurious interrupt
+ jz Hpci100
+;
+; (esp) = OldIrql
+; (esp+4) = H/W vector
+; (esp+8) = base of trap frame
+;
+
+;
+; Update performance counter
+;
+ mov eax, HalpNextRolloverCount
+ mov ecx, HalpRollOverCount
+ mov HalpRollOverCount, eax ; next rollover count
+ add HalpPerfCounterLow, ecx ; update performace counter
+ adc HalpPerfCounterHigh, 0
+
+;
+; Now check is any profiling stuff to do.
+;
+
+ cmp HalpProfilingStopped, 0 ; Has profiling been stopped?
+; je _KeProfileInterrupt@0 ; if prof enabled, jump to kernel
+ js short Hpci99 ; jump if all stopped
+ cli
+ mov dx, My+CpuIntCmd
+@@: in ax, dx ;wait til ICU not busy
+ test eax, ICU_CMD_BUSY
+ jnz @B
+ mov ax, ICU_XMT_GLB_INT
+ out dx, ax ;set profile interrupt to all interested
+
+Hpci99:
+ INTERRUPT_EXIT
+
+Hpci100:
+ add esp, 8 ; spurious, no EndOfInterrupt
+ SPURIOUS_INTERRUPT_EXIT ; exit interrupt without eoi
+
+stdENDP _HalpPerfCtrInterrupt
+
+;++
+;
+; ULONG
+; HalSetTimeIncrement (
+; IN ULONG DesiredIncrement
+; )
+;
+; /*++
+;
+; Routine Description:
+;
+; This routine initialize system time clock to generate an
+; interrupt at every DesiredIncrement interval.
+;
+; Arguments:
+;
+; DesiredIncrement - desired interval between every timer tick (in
+; 100ns unit.)
+;
+; Return Value:
+;
+; The *REAL* time increment set.
+;--
+cPublicProc _HalSetTimeIncrement,1
+
+ mov eax, TIME_INCREMENT
+ stdRET _HalSetTimeIncrement
+
+stdENDP _HalSetTimeIncrement
+_TEXT ends
+ end
+
diff --git a/private/ntos/nthals/halwyse7/i386/wydetect.asm b/private/ntos/nthals/halwyse7/i386/wydetect.asm
new file mode 100644
index 000000000..b18e643ee
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wydetect.asm
@@ -0,0 +1,167 @@
+;++
+;
+; Copyright (c) 1991 Microsoft Corporation
+; Copyright (c) 1992, 1993 Wyse Technology
+;
+; Module Name:
+;
+; wydetect.asm
+;
+; Abstract:
+;
+; This modules detects a Wyse7000 or compatible. It is INCLUDED
+; by WYIPI and other binaries whom need to know how to detect a
+; Wyse7000 type MP machine (ie, setup). It must assemble more or
+; less standalone and run in protect mode.
+;
+; Author:
+;
+; John Fuller (o-johnf) 3-Apr-1992 Convert to Wyse7000i MP system.
+;
+;Revision History:
+;
+; John Fuller (o-johnf) 3-Apr-1992 Convert to Wyse7000i MP system.
+;--
+
+include callconv.inc ; calling convention macros
+
+;*****************************
+; Wyse 7000i MP defines from wy7000mp.inc
+; These are copied into this module to allow it to be build standalone
+; by the setup program.
+;
+WyModel740 Equ 00170335Fh ;EISA id for model 740 system board
+WyModel760 Equ 00178335Fh ;EISA id for model 760 system board
+WyModel780 Equ 00978335Fh ;EISA id for model 780 system board
+; ;(model hasn't been named, but
+; ; 780 is as good as anything)
+
+
+My Equ 00F0h ;WWB slot number specifies local cpu
+CpuCCUptr Equ 0C00h ;CCU pointer register (add WWB slot*16)
+
+
+_DATA SEGMENT DWORD PUBLIC 'DATA'
+
+; wySystemType: SystemType is read from 0c80-0c83h.
+; 0c80-0c81: 5F33: Compressed WYS (5 bit encoding).
+; 0c82-0c83: System Board type.
+;
+; SystemType: Is it a Wyse7000i? Gets init'd by P0 ONLY ONCE.
+; 0: not a Wyse7000i
+; 1: 7000i/model 740
+; 2: 7000i/model 760
+; 3: 7000i/model 780
+;
+wySystemTypeTable label dword
+
+ dd WyModel740 ;type 1
+
+; dd ?????????? add here any other non-ICU type system boards
+
+ public SYSTYPE_NO_ICU
+SYSTYPE_NO_ICU equ ($-wySystemTypeTable)/4 ;highest non-ICU type number
+
+ dd WyModel760 ;type 2
+ dd WyModel780 ;type 3
+
+; dd ?????????? add here any other ICU type system boards
+
+WYTABLE_SIZE equ ($-wySystemTypeTable)/4 ;highest system type number
+
+wySystemType dd 0 ;store EISA ID for system board
+
+_DATA ends
+
+ page ,132
+ subttl "Post InterProcessor Interrupt"
+_TEXT SEGMENT DWORD PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
+
+;++
+; ULONG
+; DetectWyse7 (
+; OUT PBOOLEAN IsConfiguredMp
+; );
+;
+; Routine Description:
+; Determines the type of system (specifically for eisa machines), by reading
+; the system board system ID. It compares the 4 bytes of the ID, to
+; a predefined table <abSystemTypeTable> and returns the index to the
+; found entry.
+;
+; Arguments:
+; IsConfiguredMp - If detected, then this value is
+; set to TRUE if it's an MP system, else FALSE.
+;
+; Return Value:
+; 0 - if not a Wyse7
+; 1 - if type 1
+; 2 - if type 2
+; etc...
+;--
+cPublicProc _DetectWyse7 ,1
+
+ push edi
+ push esi
+ push ebx ; Save C Runtime
+
+ ; 4 byte value is read from 0c80-0c83, and saved in <wySystemType>.
+ ; The value is compared to table in <abSystemTypeTable>, and
+ ; the SystemType is updated accordingly.
+
+ lea edi, wySystemType
+ mov edx, 0c80h
+ cld ; increment edi
+ insb ; 0e CPQ
+ inc edx
+ insb ; 11
+ inc edx
+ insb ; SystemType
+ inc edx
+ insb ; Revision
+
+ mov ebx, wySystemType ;get read EISA ID
+ mov ecx, WYTABLE_SIZE
+@@: cmp ebx, wySystemTypeTable[4*ecx-4]
+ je short @F ;jump if found
+ loop @B
+ jmp short WyNotFound
+
+@@:
+ cmp ecx, SYSTYPE_NO_ICU
+ ja short WyFound ;jump if ICU type system board found
+;
+; We have found an MP-capable system, now we have to verify that
+; we have an actual MP-CPU
+
+ mov eax, 0FFAAh
+ mov edx, My+CpuCCUptr ;register doesn't exist on UP-CPU
+ pushfd ;save interrupt flag
+ cli
+ out dx, al ;write data pattern to register
+ xchg ah, al
+ out 0ECh, al ;precharge bus (non-existant register)
+ in al, dx ;read data pattern again
+ popfd
+ cmp al, ah ;if it's not the data we wrote
+ jne short WyNotFound ; then it's not an MP-CPU
+
+WyFound:
+ mov eax, ecx ; Type found
+ mov ebx, dword ptr [esp+16]
+ mov byte ptr [ebx], 1 ; *IsConfiguredMp = TRUE
+
+WyExit: pop ebx
+ pop esi
+ pop edi
+
+ stdRET _DetectWyse7
+
+WyNotFound:
+ xor eax, eax ; No type
+ jmp short WyExit
+
+stdENDP _DetectWyse7
+
+_TEXT ENDS
diff --git a/private/ntos/nthals/halwyse7/i386/wyhal.c b/private/ntos/nthals/halwyse7/i386/wyhal.c
new file mode 100644
index 000000000..85b724b14
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wyhal.c
@@ -0,0 +1,378 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+Copyright (c) 1992, 1993 Wyse Technology
+
+Module Name:
+
+ wyhal.c
+
+Abstract:
+
+
+ This module implements the initialization of the system dependent
+ functions that define the Hardware Architecture Layer (HAL) for an
+ Wyse 7000i x86 system.
+
+Author:
+
+ David N. Cutler (davec) 25-Apr-1991
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ John Nels Fuller (o-johnf) 26-Mar-1992 convert for Wyse 7000i
+--*/
+
+#include "halp.h"
+
+ADDRESS_USAGE HalpDefaultWyseIoSpace = {
+ NULL, CmResourceTypePort, InternalUsage,
+ {
+ // Standard PC ISA I/O space used...
+ 0x000, 0x10, // ISA DMA
+ 0x0C0, 0x10, // ISA DMA
+ 0x080, 0x10, // DMA
+
+ 0x020, 0x2, // PIC
+ 0x0A0, 0x2, // Cascaded PIC
+
+ 0x040, 0x4, // Timer1, Referesh, Speaker, Control Word
+ 0x048, 0x4, // Timer2, Failsafe
+
+ 0x061, 0x1, // NMI (system control port B)
+ 0x092, 0x1, // system control port A
+
+ 0x070, 0x2, // Cmos/NMI enable
+ 0x0F0, 0x10, // coprocessor ports
+
+ // Standard PC EISA I/O space used...
+ 0x0D0, 0x10, // DMA
+ 0x400, 0x10, // DMA
+ 0x480, 0x10, // DMA
+ 0x4C2, 0xE, // DMA
+ 0x4D4, 0x2C, // DMA
+
+ 0x461, 0x2, // Extended NMI
+ 0x464, 0x2, // Last Eisa Bus Muster granted
+
+ 0x4D0, 0x2, // edge/level control registers
+
+ 0xC84, 0x1, // System board enable
+
+ // Wyse I/O Space used...
+
+ 0x8F0, 0x8, // BCU/ICU on cpu boards
+ 0x800, 0x8, // BCU/ICU on system board
+ 0xCF0, 0x4, // 80486 CCU, Pentium WDC
+ 0xCF4, 0x6, // 80486 WBI, Pentium WDP
+
+ 0, 0
+
+ }
+};
+
+
+VOID
+HalpICUSpurious(
+ VOID
+ );
+
+VOID
+HalpIPInterrupt(
+ VOID
+ );
+
+VOID
+HalpReInitProcessor(
+ ULONG ProcessorNumber
+ );
+
+ULONG HalpBusType;
+
+#ifndef NT_UP
+ULONG
+HalpInitMP(
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+#endif
+
+
+extern CCHAR HalpIRQLtoVector[];
+
+VOID
+HalpPerfCtrInterrupt(
+ VOID
+ );
+
+KSPIN_LOCK HalpSystemHardwareLock;
+
+//BOOLEAN
+//HalpVerifyMachine (
+// VOID
+// );
+
+BOOLEAN
+HalInitSystem (
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+
+
+/*++
+
+Routine Description:
+
+ This function initializes the Hardware Architecture Layer (HAL) for an
+ x86 system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ A value of TRUE is returned if the initialization was successfully
+ completed. Otherwise a value of FALSE is returend.
+
+--*/
+
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
+ PLIST_ENTRY NextMd;
+ KIRQL CurrentIrql;
+ PKPRCB pPRCB;
+ ULONG BuildType;
+
+
+ pPRCB = KeGetCurrentPrcb();
+
+ if (Phase == 0) {
+
+ HalpBusType = LoaderBlock->u.I386.MachineType & 0x00ff;
+
+ //
+ // Verify Prcb version and build flags conform to
+ // this image
+ //
+
+ BuildType = 0;
+#if DBG
+ BuildType |= PRCB_BUILD_DEBUG;
+#endif
+#ifdef NT_UP
+ BuildType |= PRCB_BUILD_UNIPROCESSOR;
+#endif
+
+ if (pPRCB->MajorVersion != PRCB_MAJOR_VERSION) {
+ KeBugCheckEx (MISMATCHED_HAL,
+ 1, pPRCB->MajorVersion, PRCB_MAJOR_VERSION, 0);
+ }
+
+ if (pPRCB->BuildType != BuildType) {
+ KeBugCheckEx (MISMATCHED_HAL,
+ 2, pPRCB->BuildType, BuildType, 0);
+ }
+
+
+ //
+ // Phase 0 initialization
+ // only called by P0
+ //
+
+
+ //
+ // Initialize the ICU spurious interrupt vector
+ //
+
+ KiSetHandlerAddressToIDT( PRIMARY_VECTOR_BASE+16, HalpICUSpurious );
+
+ HalpInitializePICs();
+
+ //
+ // Now that the PICs are initialized, we need to mask them to
+ // reflect the current Irql
+ //
+
+ CurrentIrql = KeGetCurrentIrql();
+ KfLowerIrql(CurrentIrql);
+
+ //
+ // Fill in handlers for APIs which this hal supports
+ //
+
+ HalQuerySystemInformation = HaliQuerySystemInformation;
+ HalSetSystemInformation = HaliSetSystemInformation;
+
+ //
+ // Initialize CMOS
+ //
+
+ HalpInitializeCmos();
+
+ //
+ // Register base IO space used by hal
+ //
+
+ HalpRegisterAddressUsage (&HalpDefaultWyseIoSpace);
+
+ //
+ // Note that HalpInitializeClock MUST be called after
+ // HalpInitializeStallExecution, because HalpInitializeStallExecution
+ // reprograms the timer.
+ //
+
+ HalpInitializeStallExecution(0);
+
+ HalpInitializeClock();
+
+ //
+ // Initialize the clock interrupt vector for the processor that keeps
+ // the system time.
+ //
+
+ KiSetHandlerAddressToIDT( HalpIRQLtoVector[CLOCK2_LEVEL],
+ HalpClockInterrupt );
+
+ //
+ // Initialize the IPI vector
+ //
+
+ KiSetHandlerAddressToIDT( HalpIRQLtoVector[IPI_LEVEL],
+ HalpIPInterrupt);
+
+ //
+ // Initialize the profile interrupt vector.
+ //
+
+ HalStopProfileInterrupt(0);
+
+ KiSetHandlerAddressToIDT( HalpIRQLtoVector[PROFILE_LEVEL],
+ HalpProfileInterrupt);
+
+ //
+ // Initialize the performance counter interrupt vector
+ //
+
+ KiSetHandlerAddressToIDT( HalpIRQLtoVector[PROFILE_LEVEL-1],
+ HalpPerfCtrInterrupt);
+
+ HalpInitializeDisplay();
+
+ //
+ // Initialize spinlock used by HalGetBusData hardware access routines
+ //
+
+ KeInitializeSpinLock(&HalpSystemHardwareLock);
+
+ //
+ // Determine if there is physical memory above 16 MB.
+ //
+
+ LessThan16Mb = TRUE;
+
+ NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
+
+ while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
+ Descriptor = CONTAINING_RECORD( NextMd,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry );
+
+ if (Descriptor->BasePage + Descriptor->PageCount > 0x1000) {
+ LessThan16Mb = FALSE;
+ }
+
+ NextMd = Descriptor->ListEntry.Flink;
+ }
+
+ //
+ // Determine the size need for map buffers. If this system has
+ // memory with a physical address of greater than
+ // MAXIMUM_PHYSICAL_ADDRESS, then allocate a large chunk; otherwise,
+ // allocate a small chunk.
+ //
+
+ if (LessThan16Mb) {
+
+ //
+ // Allocate a small set of map buffers. They are only need for
+ // slave DMA devices.
+ //
+
+ HalpMapBufferSize = INITIAL_MAP_BUFFER_SMALL_SIZE;
+
+ } else {
+
+ //
+ // Allocate a larger set of map buffers. These are used for
+ // slave DMA controllers and Isa cards.
+ //
+
+ HalpMapBufferSize = INITIAL_MAP_BUFFER_LARGE_SIZE;
+
+ }
+
+ //
+ // Allocate map buffers for the adapter objects
+ //
+
+ HalpMapBufferPhysicalAddress.LowPart =
+ HalpAllocPhysicalMemory (LoaderBlock, MAXIMUM_PHYSICAL_ADDRESS,
+ HalpMapBufferSize >> PAGE_SHIFT, TRUE);
+ HalpMapBufferPhysicalAddress.HighPart = 0;
+
+
+ if (!HalpMapBufferPhysicalAddress.LowPart) {
+
+ //
+ // There was not a satisfactory block. Clear the allocation.
+ //
+
+ HalpMapBufferSize = 0;
+ }
+
+ } else {
+
+ //
+ // Phase 1 initialization
+ //
+
+ if (KeGetPcr()->Prcb->Number == 0) {
+ HalpRegisterInternalBusHandlers ();
+ }
+
+ //
+ // enable PROFILE interrupt
+ //
+ HalEnableSystemInterrupt( HalpIRQLtoVector[PROFILE_LEVEL],
+ PROFILE_LEVEL, Latched);
+ //
+ // enable Performance Counter interrupt
+ //
+ HalEnableSystemInterrupt( HalpIRQLtoVector[PROFILE_LEVEL-1],
+ PROFILE_LEVEL-1, Latched);
+ //
+ // enable CLOCK2 interrupt
+ //
+ HalEnableSystemInterrupt( HalpIRQLtoVector[CLOCK2_LEVEL],
+ CLOCK2_LEVEL, Latched);
+ if (KeGetPcr()->Prcb->Number == 0) {
+
+ //
+ // If P0, then enable IPI, IPI's already enabled on other cpu's
+ //
+ HalEnableSystemInterrupt( HalpIRQLtoVector[IPI_LEVEL],
+ IPI_LEVEL, Latched);
+ }
+
+ }
+
+
+ HalpInitMP (Phase, LoaderBlock);
+
+ return TRUE;
+}
diff --git a/private/ntos/nthals/halwyse7/i386/wyipi.asm b/private/ntos/nthals/halwyse7/i386/wyipi.asm
new file mode 100644
index 000000000..297964749
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wyipi.asm
@@ -0,0 +1,775 @@
+ title "Interprocessor Interrupt"
+;++
+;
+;Copyright (c) 1991-1993 Microsoft Corporation
+;Copyright (c) 1992, 1993 Wyse Technology
+;
+;Module Name:
+;
+; wyipi.asm
+;
+;Abstract:
+;
+; Wyse7000i IPI code.
+; Provides the HAL support for Interprocessor Interrupts for the
+; MP Wyse7000i implementation.
+;
+;Author:
+;
+; Ken Reneris (kenr) 13-Jan-1992
+;
+;Revision History:
+;
+; John Fuller (o-johnf) 3-Apr-1992 Convert to Wyse7000i MP system.
+; John Fuller (o-johnf) 31-Aug-1993 Mods for Lazy IRQLs
+;--
+.386p
+ .xlist
+
+;
+; Include Wyse7 dection code
+;
+
+include i386\wydetect.asm
+
+;
+; Normal includes
+;
+
+include hal386.inc
+include i386\kimacro.inc
+include i386\ix8259.inc
+include i386\wy7000mp.inc
+include callconv.inc
+
+ EXTRNP _HalBeginSystemInterrupt,3
+ EXTRNP _HalEndSystemInterrupt,2
+ extrn _HalpDefaultInterruptAffinity:DWORD
+ EXTRNP _KiIpiServiceRoutine,2,IMPORT
+ EXTRNP Kei386EoiHelper,0,IMPORT
+ EXTRNP _HalEnableSystemInterrupt,3
+ EXTRNP _HalpInitializeClock,0
+ EXTRNP _HalDisplayString,1
+ EXTRNP _HalpInitializeStallExecution,1
+ extrn _HalpIRQLtoVector:BYTE
+ extrn _ProcessorsPresent:BYTE
+ extrn _HalpActiveProcessors:DWORD
+
+_DATA SEGMENT DWORD PUBLIC 'DATA'
+
+ public SystemType
+SystemType dd 0
+
+ public _HalpProcessorSlot
+_HalpProcessorSlot db MAXIMUM_PROCESSORS dup (0)
+
+BadHalString db 'HAL: Wyse EISA/MP HAL cannot run on '
+ db 'non-Wyse or non-EISA/MP machine.', cr, lf
+ db ' Replace the hal.dll with the correct hal', cr, lf
+ db ' System is HALTING *********', 0
+_DATA ends
+
+ page ,132
+ subttl "Post InterProcessor Interrupt"
+_TEXT SEGMENT DWORD PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
+
+ if DBG
+ %out _ProcSub
+;++
+;
+; VOID
+; ProcSub(
+; UCHAR Number
+; );
+;
+;Routine Description:
+;
+; Writes Number to BCU general purpose register, restores all
+; registers and flags.
+;
+;Arguments:
+;
+; Number - Procedure entry/exit code
+;
+;Return Value:
+;
+; None. (restores eax)
+;
+;--
+cPublicProc _ProcSub ,1
+ pushfd
+ push eax
+ push edx
+ mov dx, My+CpuPtrReg
+ mov al, BCU_GPR
+ cli
+ out dx, al
+ add edx, CpuDataReg-CpuPtrReg
+ movzx eax, byte ptr [esp][16]
+ out dx, ax
+ pop edx
+ pop eax
+ popfd
+ stdRET _ProcSub
+stdENDP _ProcSub
+
+ endif ;DBG
+
+;++
+;
+; VOID
+; HalInitializeProcessor(
+; ULONG Number
+; );
+;
+;Routine Description:
+;
+; Initialize hal pcr values for current processor (if any)
+; (called shortly after processor reaches kernel, before
+; HalInitSystem if P0)
+;
+; IPI's and KeReadir/LowerIrq's must be available once this function
+; returns. (IPI's are only used once two or more processors are
+; available)
+;
+; . PcHal.pchPrNum = processor number
+; . PcHal.pchPentiumFlag = processor type (80486=0, Pentium=1)
+; . if (P0)
+; . determine what kind of system is it,
+; . if (Not Wyse7000i) Exit;
+; . HalpDefaultInterruptAffinity[Pn] = 1
+; . if (80486)
+; . WBI IACK_MODE = 1 (all WBIs)
+; . CCU_CR[WWB_FPE_EN, PCD_EN] = 0,1?
+; . else (Pentium)
+; . WDP[IACK_MODE, FPE_EN] = 1, 0 (both WDP's)
+; . CpuDiagUart[MCR] = 7 (DTR, RTS, OUT1, -OUT2, -LOOP)
+; . CpuPriortyLevel = 0
+; . PcHal.pchHwIrql = HIGH_LEVEL
+; . ICU_CNT_REG = 0
+; . ICU_LIPTR = lipDefault
+; . BCU_BCTLR[A20M_WWB, A20M_CPU, SLOW_ENB] = 0,0,0
+; . _HalpProcessorSlot[Pn] = BCU_ID
+; . ICU_PSR0,1 = 0
+; . PcIDR = ICU_IMR0,1 = IMR_MASK
+; . ICU_VB0 = PIC1_BASE
+; . ICU_VB1 = PIC2_BASE
+; . ICU_VB2 = IPIv_BASE
+; . if (P0)
+; . _ProcessorsPresent = ~ICU_SYS_CPU & ~(P0_slot_bit+sys_slot_bit)
+; . if (Model760/780) // Init SysBd ICU/BCU/WBI
+; . ICU_ICTLR[IACK_MODE, ICU_AEOI, INT_ENB, MSK_CPURST, WWB_INT] = 1,0,1,0,0
+; . clear pending interrupt
+; . Sys ICU_CNT_REG = 0
+; . Sys WBI IACK_MODE = 1 (all WBIs)
+; . Sys ICU_LIPTR = 0
+; . Sys BCU_BCTLR[A20M_WWB, A20M_CPU, SLOW_ENB] = 0,0,0
+; . Sys ICU_PSR0,1 = 0
+; . Sys ICU_IMR0,1 = IMR_MASK & ~1
+; . Sys ICU_VB0 = PIC1_BASE
+; . Sys ICU_VB1 = PIC2_BASE
+; . Sys ICU_VB2 = IPIv_BASE
+; . Sys ICU_ICTLR[IACK_MODE, ICU_AEOI, INT_ENB, MSK_CPURST, WWB_INT] = 1,1,1,1,1
+; . else
+; . ICU_ICTLR[IACK_MODE, ICU_AEOI, INT_ENB, MSK_CPURST, WWB_INT] = 1,0,1,0,1
+; . ICU_ICTLR[WWB_INT] = 1
+; . PcPDR[0] = 0
+; . clear pending interrupt
+; . else
+; . ICU_ICTLR[IACK_MODE, ICU_AEOI, INT_ENB, MSK_CPURST, WWB_INT] = 1,0,1,1,0
+; . clear pending interrupt
+; . initalize stall count
+; . initialize clock
+; . enable IPI's
+;
+;Arguments:
+;
+; Number - Logical processor number of calling processor
+;
+;Return Value:
+;
+; None.
+;
+;--
+cPublicProc _HalInitializeProcessor ,1
+ enproc 1
+ pushfd
+ cli
+
+; . PcHal.pchPrNum = processor number
+ movzx eax, byte ptr [esp+8] ;get processor number
+ mov fs:PcHal.pchPrNum, al ;save for future reference
+ lock bts _HalpActiveProcessors, eax
+
+; . PcHal.pchPentiumFlag = processor type (80486=0, Pentium=1)
+ pushfd
+ pop ecx
+ xor ecx, 1 shl 21 ;toggle CPUID flag
+ push ecx
+ popfd
+ pushfd
+ pop edx
+ cmp ecx, edx
+ sete Fs:PcHal.pchPentiumFlag
+
+; . if (P0)
+ or eax, eax ;test for processor zero
+ jnz short hipAllCpus ;jump if not
+
+; . determine what kind of system is it,
+; . if (Not Wyse7000i) Exit;
+
+ sub esp, 4
+ stdCall _DetectWyse7, <esp> ;doesn't run if not Wyse 7000i
+ add esp, 4
+ or eax, eax
+ jz NotWyse7
+ mov SystemType, eax
+
+ xor eax, eax ;make sure eax is 0 for hipAllCpus
+
+hipAllCpus:
+; . HalpDefaultInterruptAffinity[Pn] = 1
+ lock bts _HalpDefaultInterruptAffinity, eax
+ mov dword ptr fs:PcStallScaleFactor, INITIAL_STALL_COUNT
+
+; . if (80486)
+ cmp Fs:PcHal.pchPentiumFlag, 0
+ Jne Short hipIsPentium
+
+; . WBI IACK_MODE = 1 (all WBIs)
+ mov dx, My+CpuWBIlow ;point to WBI for data bits 0-32
+ in ax, dx
+ or ax, WBI_IACK_MODE ;set MP interrupt mode
+ out dx, ax
+
+ mov dx, My+CpuWBIhigh ;point to WBI for data bits 33-63
+ in ax, dx
+ or ax, WBI_IACK_MODE ;set MP interrupt mode
+ out dx, ax
+
+ mov dx, My+CpuWBIaddr ;point to WBI for address bits
+ in ax, dx
+ or ax, WBI_IACK_MODE ;set MP interrupt mode
+ out dx, ax
+
+; . CCU_CR[WWB_FPE_EN, PCD_EN] = 0,1?
+ mov al, CCU_CR
+ mov dx, My+CpuCCUptr
+ out dx, al
+ mov dx, My+CpuCCUdata
+ in ax, dx
+ and eax, not WWB_FPE_EN
+ or eax, PCD_EN
+ out dx, ax
+ jmp short hipIs80486
+
+; . else (Pentium)
+hipIsPentium:
+; . WDP[IACK_MODE, FPE_EN] = 1, 0 (both WDP's)
+ mov dx, MyCpuWDPlow
+ in ax, dx
+ and eax, not WDP_FPE_EN
+ or eax, WDP_IACK_MODE
+ out dx, ax
+ mov dx, MyCpuWDPhigh
+ in ax, dx
+ and eax, not WDP_FPE_EN
+ or eax, WDP_IACK_MODE
+ out dx, ax
+
+hipIs80486:
+; . CpuDiagUart[MCR] = 7 (DTR, RTS, OUT1, -OUT2, -LOOP)
+ mov dx, My+CpuDiagUart+4
+ mov al, 7
+ out dx, ax ;disable diag port interrupts
+
+; . CpuPriortyLevel = 0
+ xor eax, eax
+ mov dx, My+CpuPriortyLevel
+ out dx, ax
+
+; . PcHal.pchHwIrql = HIGH_LEVEL
+ mov Fs:PcHal.pchHwIrql, HIGH_LEVEL
+
+ mov dx, My+CpuDataReg ;point to my BCU/ICU
+
+; . ICU_CNT_REG = 0
+ push 0
+ push ICU_CNT_REG
+ call WriteCpuReg ;stop local timer
+
+; . ICU_LIPTR = lipDefault
+ push lipDefault
+ push ICU_LIPTR
+ call WriteCpuReg
+ mov fs:PcHal.pchCurLiptr, eax
+
+; . BCU_BCTLR[A20M_WWB, A20M_CPU, SLOW_ENB] = 0,0,0
+ push BCU_BCTLR
+ call ReadCpuReg
+ and eax, not (A20M_WWB + A20M_CPU + SLOW_ENB)
+ push eax
+ push BCU_BCTLR
+ call WriteCpuReg
+
+; . _HalpProcessorSlot[Pn] = BCU_ID
+ push BCU_ID
+ call ReadCpuReg
+ and al, WWB_ID_MASK ;keep only WWB slot number
+ movzx ecx, byte ptr [esp+8] ;get processor number again
+ mov _HalpProcessorSlot[ecx], al
+ mov fs:PcHal.pchPrSlot, al
+
+; . ICU_PSR0,1 = 0
+ push 0
+ push ICU_PSR0
+ call WriteCpuReg ;clear pending bits in ICU_PSR0
+ out dx, ax ;shortcut to clear ICU_PSR1
+
+; . PcIDR = ICU_IMR0,1 = IMR_MASK
+ push IMR_MASK
+ push ICU_IMR0
+ call WriteCpuReg
+ mov fs:PcIDR, eax
+ shr eax, 16
+ out dx, ax ;shortcut to write ICU_IMR1
+
+; . ICU_VB0 = PIC1_BASE
+ push PIC1_BASE
+ push ICU_VB0
+ call WriteCpuReg
+
+; . ICU_VB1 = PIC2_BASE
+ push PIC2_BASE
+ push ICU_VB1
+ call WriteCpuReg
+
+; . ICU_VB2 = IPIv_BASE
+ push IPIv_BASE
+ push ICU_VB2
+ call WriteCpuReg
+
+; . if (P0)
+ cmp byte ptr [esp+8], 0
+ jnz hipNotP0
+
+; . _ProcessorsPresent = ~ICU_SYS_CPU & ~(P0_slot_bit+sys_slot_bit)
+ push ICU_SYS_CPU
+ call ReadCpuReg
+ not al ;make positive true cpu bits
+ and al, not 1 ;clear system board bit
+ movzx ecx, _HalpProcessorSlot[0] ;get P0 slot number
+ btr eax, ecx ;clear our own bit
+ mov _ProcessorsPresent, al ;save for starting others
+
+; . if (Model760/780) // Init SysBd ICU/BCU/WBI
+ cmp SystemType, SYSTYPE_NO_ICU
+ jna hipNotModel760
+
+; . ICU_ICTLR[IACK_MODE, ICU_AEOI, INT_ENB, MSK_CPURST, WWB_INT] = 1,0,1,0,0
+ push ICU_ICTLR
+ call ReadCpuReg
+ and eax, not (WWB_INT + ICU_AEOI + MSK_CPURST)
+ or eax, IACK_MODE + INT_ENB
+ push eax
+ push ICU_ICTLR
+ call WriteCpuReg
+
+; . clear pending interrupt
+ call ClearPendingInt
+
+ mov dx, Sys+CpuDataReg ;point to system board registers
+
+; . Sys ICU_CNT_REG = 0
+ push 0
+ push ICU_CNT_REG
+ call WriteCpuReg ;disable sys board timer
+
+; . Sys WBI IACK_MODE = 1 (all WBIs)
+ push SYS_WBI_LOW
+ call ReadCpuReg
+ or eax, WBI_IACK_MODE ;set MP interrupt mode
+ push eax
+ push SYS_WBI_LOW
+ call WriteCpuReg
+
+ mov dx, Sys+CpuDataReg ;point to system board registers
+ push SYS_WBI_HIGH
+ call ReadCpuReg
+ or eax, WBI_IACK_MODE ;set MP interrupt mode
+ push eax
+ push SYS_WBI_HIGH
+ call WriteCpuReg
+
+ mov dx, Sys+CpuDataReg ;point to system board registers
+ push SYS_WBI_ADDR
+ call ReadCpuReg
+ or eax, WBI_IACK_MODE ;set MP interrupt mode
+ push eax
+ push SYS_WBI_ADDR
+ call WriteCpuReg
+
+ push 0
+ push ICU_LIPTR
+ call WriteCpuReg
+
+; . Sys ICU_PSR0,1 = 0
+ push 0
+ push ICU_PSR0
+ call WriteCpuReg ;clear pending bits in ICU_PSR0
+
+ push 0
+ push ICU_PSR1
+ call WriteCpuReg ;clear pending bits in ICU_PSR1
+
+; . Sys ICU_IMR0,1 = IMR_MASK & ~1
+ push IMR_MASK and (not 1) ;allow only level 0
+ push ICU_IMR0
+ call WriteCpuReg
+
+ shr eax, 16
+ push eax
+ push ICU_IMR1
+ call WriteCpuReg ;set ICU_IMR1
+
+; . Sys ICU_VB0 = PIC1_BASE
+ push PIC1_BASE
+ push ICU_VB0
+ call WriteCpuReg
+
+; . Sys ICU_VB1 = PIC2_BASE
+ push PIC2_BASE
+ push ICU_VB1
+ call WriteCpuReg
+
+; . Sys ICU_VB2 = IPIv_BASE
+ push IPIv_BASE
+ push ICU_VB2
+ call WriteCpuReg
+
+; . Sys ICU_ICTLR[IACK_MODE, ICU_AEOI, INT_ENB, MSK_CPURST, WWB_INT] = 1,1,1,1,1
+ push ICU_ICTLR
+ call ReadCpuReg
+ or eax, IACK_MODE + INT_ENB + WWB_INT + MSK_CPURST + ICU_AEOI
+ push eax
+ push ICU_ICTLR
+ call WriteCpuReg
+ jmp short hipExit
+
+; . else
+hipNotModel760:
+
+; . ICU_ICTLR[IACK_MODE, ICU_AEOI, INT_ENB, MSK_CPURST, WWB_INT] = 1,0,1,0,1
+ push ICU_ICTLR
+ call ReadCpuReg
+ and eax, not (ICU_AEOI + MSK_CPURST)
+ or eax, IACK_MODE + INT_ENB + WWB_INT
+ push eax
+ push ICU_ICTLR
+ call WriteCpuReg
+
+; . PcPDR[0] = 0
+ and fs:dword ptr PcIDR, not 1 ;allow 8259 interrupt
+ ; distribution, but not until
+ ; 1st HalEnableSystemInterrupt
+; . clear pending interrupt
+ call ClearPendingInt
+ jmp short hipExit
+
+; . else
+hipNotP0:
+
+; . ICU_ICTLR[IACK_MODE, ICU_AEOI, INT_ENB, MSK_CPURST, WWB_INT] = 1,0,1,1,0
+ push ICU_ICTLR
+ call ReadCpuReg
+ and eax, not (WWB_INT + ICU_AEOI)
+ or eax, IACK_MODE + INT_ENB + MSK_CPURST
+ push eax
+ push ICU_ICTLR
+ call WriteCpuReg
+
+; . clear pending interrupt
+ call ClearPendingInt
+
+; . initialize stall count
+ stdCall _HalpInitializeStallExecution, <[esp+8]>
+
+; . initialize clock
+ stdCall _HalpInitializeClock
+
+; . enable IPI's
+ movzx eax, _HalpIRQLtoVector[IPI_LEVEL]
+ stdCall _HalEnableSystemInterrupt, <eax,IPI_LEVEL,1> ;latched interrupt
+
+hipExit:
+ exproc 1
+ popfd
+ stdRET _HalInitializeProcessor
+
+NotWyse7:
+; on a non-Wyse. Display
+; message and HALT system.
+ stdCall _HalDisplayString, <offset BadHalString>
+ hlt
+
+stdENDP _HalInitializeProcessor
+
+
+;++
+;
+; VOID
+; HalRequestIpi(
+; IN ULONG Mask
+; );
+;
+;Routine Description:
+;
+; Requests an interprocessor interrupt
+;
+;Arguments:
+;
+; Mask - Supplies a mask of the processors to be interrupted
+;
+;Return Value:
+;
+; None.
+;
+;--
+cPublicProc _HalRequestIpi ,1
+ enproc 2
+
+ movzx eax, byte ptr [esp+4] ; (eax) = Processor bitmask
+if DBG
+ or eax, eax ; must ipi somebody
+ jz short ipibad
+
+ movzx ecx, byte ptr fs:PcHal.pchPrNum
+ bt eax, ecx ; cannot ipi yourself
+ jc short ipibad
+endif
+
+ xchg eax, ecx ;processor list to ecx
+ mov edx, My+CpuIntCmd ;point to ICU cmd register
+hriNextProcessor:
+ pushfd
+ cli
+@@: in ax, dx ;get ICU busy status
+ test eax, ICU_CMD_BUSY
+ jnz @B ;wait for not busy
+ bsf eax, ecx
+ btr ecx, eax
+ mov al, _HalpProcessorSlot[eax]
+ or al, ICU_IPI_SLOT
+ out dx, ax
+ popfd
+ or ecx, ecx
+ jnz hriNextProcessor
+ exproc 2
+ stdRET _HalRequestIpi
+
+if DBG
+ipibad: int 3
+ stdRET _HalRequestIpi
+endif
+
+stdENDP _HalRequestIpi
+
+
+ page ,132
+ subttl "Wyse7000i IPI Handler"
+;++
+;
+; VOID
+; HalpIPInterrupt (
+; );
+;
+; Routine Description:
+;
+; This routine is entered as the result of an interrupt generated by the
+; IPI hardware.
+;
+; Arguments:
+;
+; None.
+; Interrupt is dismissed
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+ ENTER_DR_ASSIST Hipi_a, Hipi_t
+
+cPublicProc _HalpIPInterrupt ,0
+
+;
+; Save machine state in trap frame
+;
+ ENTER_INTERRUPT Hipi_a, Hipi_t ; (ebp) -> Trap frame
+ enproc 3
+;
+; Save previous IRQL
+;
+ movzx eax, _HalpIRQLtoVector[IPI_LEVEL]
+ push eax ;interrupt vector
+ sub esp, 4 ;space for OldIrql
+
+;raise to new Irql
+
+ stdCall _HalBeginSystemInterrupt, <IPI_LEVEL,eax,esp>
+ or al, al
+ jz Hipi100 ;jump if spurrious interrupt
+
+; Pass TrapFrame to Ipi service rtn
+; Pass Null ExceptionFrame
+
+ stdCall _KiIpiServiceRoutine, <ebp,0>
+
+ exproc 3
+;
+; Do interrupt exit processing
+;
+ INTERRUPT_EXIT ; will return to caller
+
+Hipi100:
+ exproc 3
+ add esp, 8 ; spurious, no EndOfInterrupt
+ SPURIOUS_INTERRUPT_EXIT ; exit interrupt without eoi
+
+stdENDP _HalpIPInterrupt
+;++
+;
+; VOID
+; HalpIrq13Handler (
+; );
+;
+; Routine Description:
+;
+; This routine is entered as the result of an interrupt generated by the
+; EISA DMA buffer chaining interrupt. Currently, NO NT driver uses the DMA
+; buffer chaining capability. For now, this routine is simply commented
+; out.
+;
+; Note: IRQ13 could also be used for coprocessor error, but the Wyse7000i
+; is a 486 machine so coprocessor error is handled as a processor
+; fault and the FERR output of the 486 is masked off the IRQ13
+; input to the 8259 so that the only possible IRQ13 interrupt is for
+; DMA chaining.
+;
+; Arguments:
+;
+; None.
+; Interrupt is dismissed
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+; public _HalpIrq13Handler
+;_HalpIrq13Handler proc
+;
+;_HalpIrq13Handler endp
+
+;++
+; BOOLEAN
+; HalpVerifyMachine (
+; VOID
+; );
+;
+; Routine Description:
+; Return TRUE if this is a Wyse7000i
+;
+;--
+;cPublicProc _HalpVerifyMachine ,0
+; xor eax, eax
+; cmp SystemType, eax
+; setnz al
+; stdRET _HalpVerifyMachine
+;stdENDP _HalpVerifyMachine
+
+
+ public ReadMyCpuReg
+ReadMyCpuReg proc
+ mov dx, My+CpuDataReg
+ReadCpuReg:
+ add edx, CpuPtrReg - CpuDataReg
+ mov al, [esp+4]
+ out dx, al
+ add edx, CpuDataReg - CpuPtrReg
+ in ax, dx
+ ret 4
+ReadMyCpuReg endp
+
+ public WriteMyCpuReg
+WriteMyCpuReg proc
+ Mov dx, My+CpuDataReg
+WriteCpuReg:
+ add edx, CpuPtrReg - CpuDataReg
+ mov al, [esp+4]
+ out dx, al
+ add edx, CpuDataReg - CpuPtrReg
+ mov eax, [esp+8]
+ out dx, ax
+ ret 8
+WriteMyCpuReg endp
+
+D_INT032 EQU 8E00h ; access word for 386 ring 0 interrupt gate
+
+ClearPendingInt proc
+ enter 8,0 ; setup ebp, reserve 8 bytes of stack
+
+ mov dx, My+CpuDataReg
+ push PIC1_BASE+2 ;set vector out register(unused vector)
+ push ICU_VOUT ;in case of int pending
+ call WriteCpuReg
+
+ xchg ecx, eax ;put vector number in ecx
+
+ sidt fword ptr [ebp-8] ; get IDT address
+ mov edx, [ebp-6] ; (edx)->IDT
+
+ push dword ptr [edx+8*ecx]
+ ; (TOS) = original desc of IRQ
+ push dword ptr [edx+8*ecx + 4]
+ ; each descriptor has 8 bytes
+ mov eax, offset FLAT:cpiService
+ mov word ptr [edx+8*ecx], ax
+ ; Lower half of handler addr
+ mov word ptr [edx+8*ecx+2], KGDT_R0_CODE
+ ; set up selector
+ mov word ptr [edx+8*ecx+4], D_INT032
+ ; 386 interrupt gate
+ shr eax, 16 ; (ax)=higher half of handler addr
+ mov word ptr [edx+8*ecx+6], ax
+
+ sti
+ jmp short $+2 ;allow one pending interrupt
+ cli
+
+ pop [edx+8*ecx+4] ; restore higher half of NMI desc
+ pop [edx+8*ecx] ; restore lower half of NMI desc
+
+ leave
+ ret
+ClearPendingInt endp
+
+cpiService proc
+ push edx
+ push eax
+ mov dx, My+CpuIntCmd
+@@: in ax, dx
+ test eax, ICU_CMD_BUSY
+ jnz @B
+ mov al, ICU_CLR_INSERV1 ; clear interrupt in service bit
+ out dx, ax
+ pop eax
+ pop edx
+ iretd
+cpiService endp
+_TEXT ENDS
+ END
diff --git a/private/ntos/nthals/halwyse7/i386/wyirql.asm b/private/ntos/nthals/halwyse7/i386/wyirql.asm
new file mode 100644
index 000000000..28ef5a777
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wyirql.asm
@@ -0,0 +1,667 @@
+ title "Irql Processing"
+;++
+;
+; Copyright (c) 1989-1993 Microsoft Corporation
+; Copyright (c) 1992, 1993 Wyse Technology
+;
+; Module Name:
+;
+; wyirql.asm
+;
+; Abstract:
+;
+; Wyse7000i IRQL
+;
+; This module implements the code necessary to raise and lower i386
+; Irql and dispatch software interrupts with the Wyse ICU hardware.
+;
+; Author:
+;
+; Shie-Lin Tzong (shielint) 8-Jan-1990
+;
+; Environment:
+;
+; Kernel mode only.
+;
+; Revision History:
+;
+; John Vert (jvert) 27-Nov-1991
+; Moved from kernel into HAL
+;
+; John Fuller (o-johnf) 2-Apr-1992
+; Converted to Wyse hardware.
+;
+; John Fuller (o-johnf) 31-Aug-1993
+; Mods for Lazy IRQLs
+;--
+
+.386p
+ .xlist
+include hal386.inc
+include callconv.inc ; calling convention macros
+include i386\ix8259.inc
+include i386\kimacro.inc
+include i386\wy7000mp.inc
+ .list
+
+
+ EXTRNP _KeBugCheck,1,IMPORT
+
+ extrn _HalpApcInterrupt:near
+ extrn _HalpDispatchInterrupt:near
+ extrn _KiUnexpectedInterrupt:near
+ extrn ReadMyCpuReg:NEAR
+ extrn WriteMyCpuReg:NEAR
+ EXTRNP _HalpClockInterrupt,0
+ EXTRNP _HalpIPInterrupt,0
+
+;
+; Initialization control words equates for the PICs
+;
+
+ICW1_ICW4_NEEDED equ 01H
+ICW1_CASCADE equ 00H
+ICW1_INTERVAL8 equ 00H
+ICW1_LEVEL_TRIG equ 08H
+ICW1_EDGE_TRIG equ 00H
+ICW1_ICW equ 10H
+
+ICW4_8086_MODE equ 001H
+ICW4_NORM_EOI equ 000H
+ICW4_NON_BUF_MODE equ 000H
+ICW4_SPEC_FULLY_NESTED equ 010H
+ICW4_NOT_SPEC_FULLY_NESTED equ 000H
+
+OCW2_NON_SPECIFIC_EOI equ 020H
+OCW2_SPECIFIC_EOI equ 060H
+OCW2_SET_PRIORITY equ 0c0H
+
+;
+; Interrupt flag bit maks for EFLAGS
+;
+
+EFLAGS_IF equ 200H
+EFLAGS_SHIFT equ 9
+
+;
+
+_DATA SEGMENT DWORD PUBLIC 'DATA'
+
+;
+; PICsInitializationString - Master PIC initialization command string
+;
+
+PICsInitializationString dw PIC1_PORT0
+
+;
+; Master PIC initialization command
+;
+
+ db ICW1_ICW + ICW1_EDGE_TRIG + ICW1_INTERVAL8 +\
+ ICW1_CASCADE + ICW1_ICW4_NEEDED
+ db PIC1_BASE
+ db 1 SHL PIC_SLAVE_IRQ
+ db ICW4_NOT_SPEC_FULLY_NESTED + \
+ ICW4_NON_BUF_MODE + \
+ ICW4_NORM_EOI + \
+ ICW4_8086_MODE
+ db not (1 shl PIC_SLAVE_IRQ) ;OCW1
+;
+; Slave PIC initialization command strings
+;
+
+ dw PIC2_PORT0
+ db ICW1_ICW + ICW1_EDGE_TRIG + ICW1_INTERVAL8 +\
+ ICW1_CASCADE + ICW1_ICW4_NEEDED
+ db PIC2_BASE
+ db PIC_SLAVE_IRQ
+ db ICW4_NOT_SPEC_FULLY_NESTED + \
+ ICW4_NON_BUF_MODE + \
+ ICW4_NORM_EOI + \
+ ICW4_8086_MODE
+ db 0FFh ;OCW1
+ dw 0 ; end of string
+
+
+ .errnz PROFILE_LEVEL-27 ;error if defines don't match tables
+ .errnz CLOCK2_LEVEL-28 ;error if defines don't match tables
+ .errnz IPI_LEVEL-29 ;error if defines don't match tables
+ .errnz POWER_LEVEL-30 ;error if defines don't match tables
+ .errnz HIGH_LEVEL-31 ;error if defines don't match tables
+;;;;;;;;;;;;;;;;
+;
+; The following tables are generated from this information:
+;
+;KIRQL H/W pri CPL Vector Source Common use Name
+;----- ------- --- ------ ------ ---------- ----
+; 00 31
+; 01 31 APC_LEVEL
+; 02 31 DISPATCH_LEVEL
+; 03 31 WAKE_LEVEL
+; 04 31
+; 05 31
+; 06 31
+; 07 31
+; 08 22 (lo) 22 VB2+7 Local/IPI level 7 reserved
+; 09 21 21 VB2+6 Local/IPI level 6 reserved
+; 10 20 20 VB2+5 Local/IPI level 5 reserved
+; 11 19 19 VB0+7 EISA IRQ7 LPT1
+; 12 18 18 VB0+6 EISA IRQ6 Flpy
+; 13 17 17 VB0+5 EISA IRQ5 LPT2
+; 14 16 16 VB0+4 EISA IRQ4 COM1
+; 15 15 15 VB0+3 EISA IRQ3 COM2
+; 16 14 14 VB1+7 EISA IRQ15
+; 17 13 13 VB1+6 EISA IRQ14 AT disk
+; 18 12 12 VB1+5 EISA IRQ13 DMA chaining
+; 19 11 11 VB1+4 EISA IRQ12
+; 20 10 10 VB1+3 EISA IRQ11
+; 21 9 9 VB1+2 EISA IRQ10
+; 22 8 8 VB1+1 EISA IRQ9
+; 23 7 7 VB1+0 EISA IRQ8 RTC
+; 24 6 6 VB2+4 Local/IPI level 4 reserved
+; 25 5 5 VB0+1 EISA IRQ1 Kbd
+; 26 4 4 VB0+0 EISA IRQ0 8254
+; 27 3 3 VB2+3 Local/IPI level 3 Global IPI PROFILE_LEVEL
+; 28 2 2 VB2+2 Local/IPI level 2 Local Timer CLOCK2_LEVEL
+; 29 1 1 VB2+1 Local/IPI level 1 Slot IPI IPI_LEVEL
+; 30 1 POWER_LEVEL
+; 31 0 (high) 0 VB2+0 Spurious local interrupt HIGH_LEVEL
+;
+;;;;;;;;;;;;;;;;
+
+; CCHAR HalpIRQLtoCPL[36]; this array is used to get the value
+; for the hardware current priority level
+; (CPL) register from the KIRQL.
+ Public _HalpIRQLtoCPL
+_HalpIRQLtoCPL Label Byte ;don't know how to make this symbolic
+ db 31,31,31,31,31,31,31,31,22
+ db 21,20,19,18,17,16,15,14,13
+ db 12,11,10, 9, 8, 7, 6, 5, 4
+ db 3, 2, 1, 1, 0
+ db 0, 0, 0, 0 ;four extra levels for good luck
+
+; CCHAR HalpIRQLtoVector[36]; this array is used to get the interrupt
+; vector used for a given KIRQL, zero
+; means no vector is used for the KIRQL
+ Public _HalpIRQLtoVector
+_HalpIRQLtoVector Label Byte
+ db 0
+ db 0 ;APC_LEVEL
+ db 0 ;DISPATCH_LEVEL
+ db 0 ;WAKE_LEVEL
+ db 0
+ db 0
+ db 0
+ db 0
+ db PRIMARY_VECTOR_BASE+23
+ db PRIMARY_VECTOR_BASE+22
+ db PRIMARY_VECTOR_BASE+21
+ db PRIMARY_VECTOR_BASE+7
+ db PRIMARY_VECTOR_BASE+6
+ db PRIMARY_VECTOR_BASE+5
+ db PRIMARY_VECTOR_BASE+4
+ db PRIMARY_VECTOR_BASE+3
+ db PRIMARY_VECTOR_BASE+15
+ db PRIMARY_VECTOR_BASE+14
+ db PRIMARY_VECTOR_BASE+13
+ db PRIMARY_VECTOR_BASE+12
+ db PRIMARY_VECTOR_BASE+11
+ db PRIMARY_VECTOR_BASE+10
+ db PRIMARY_VECTOR_BASE+9
+ db PRIMARY_VECTOR_BASE+8
+ db PRIMARY_VECTOR_BASE+20
+ db PRIMARY_VECTOR_BASE+1
+ db PRIMARY_VECTOR_BASE
+ db PRIMARY_VECTOR_BASE+19 ;PROFILE_LEVEL
+ db PRIMARY_VECTOR_BASE+18 ;CLOCK2_LEVEL
+ db PRIMARY_VECTOR_BASE+17 ;IPI_LEVEL
+ db 0 ;POWER_LEVEL
+ db 0 ;prevent CPL 0 enable changes ;HIGH_LEVEL
+ db 0, 0, 0, 0 ;four extra levels for good luck
+
+; CCHAR HalpVectorToIRQL[24]; this array is used to obtain the
+; required IRQL from an interrupt
+; vector, it is indexed by
+; interrupt vector-PRIMARY_VECTOR_BASE
+ Public _HalpVectorToIRQL
+_HalpVectorToIRQL Label Byte
+ db PROFILE_LEVEL-1 ;IRQ0
+ db PROFILE_LEVEL-2 ;IRQ1
+ db HIGH_LEVEL ;IRQ2--cascade
+ db PROFILE_LEVEL-12 ;IRQ3
+ db PROFILE_LEVEL-13 ;IRQ4
+ db PROFILE_LEVEL-14 ;IRQ5
+ db PROFILE_LEVEL-15 ;IRQ6
+ db PROFILE_LEVEL-16 ;IRQ7
+
+ db PROFILE_LEVEL-4 ;IRQ8
+ db PROFILE_LEVEL-5 ;IRQ9
+ db PROFILE_LEVEL-6 ;IRQ10
+ db PROFILE_LEVEL-7 ;IRQ11
+ db PROFILE_LEVEL-8 ;IRQ12
+ db PROFILE_LEVEL-9 ;IRQ13
+ db PROFILE_LEVEL-10 ;IRQ14
+ db PROFILE_LEVEL-11 ;IRQ15
+
+ db HIGH_LEVEL ;Local/IPI level 0 (spurious)
+ db IPI_LEVEL ;Local/IPI level 1
+ db CLOCK2_LEVEL ;Local/IPI level 2
+ db PROFILE_LEVEL ;Local/IPI level 3
+ db PROFILE_LEVEL-3 ;Local/IPI level 4
+ db PROFILE_LEVEL-17 ;Local/IPI level 5
+ db PROFILE_LEVEL-18 ;Local/IPI level 6
+ db PROFILE_LEVEL-19 ;Local/IPI level 7
+
+ align 4
+;
+; The following table is a bit map of IRQLs that use ICU local interrpt ptr
+; (it must indicate those IRQLs corresponding to levels used in the ICU_LIPTR)
+;
+ public _HalpLocalInts
+_HalpLocalInts dd (1 shl CLOCK2_LEVEL)+(1 shl IPI_LEVEL)+(1 shl PROFILE_LEVEL)
+
+;
+; The following tables define the addresses of software interrupt routers
+;
+
+;
+; Use this table if there is NO machine state frame on stack already
+;
+
+ public SWInterruptHandlerTable
+SWInterruptHandlerTable label dword
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 0
+ dd offset FLAT:_HalpApcInterrupt ; irql 1
+ dd offset FLAT:_HalpDispatchInterrupt ; irql 2
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 3
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 4
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 5
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 6
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 7
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 8
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 9
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 10
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 11
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 12
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 13
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 14
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 15
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 16
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 17
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 18
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 19
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 20
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 21
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 22
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 23
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 24
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 25
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 26
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 27
+ dd offset FLAT:_KiUnexpectedInterrupt ; irql 28
+ dd offset FLAT:_KIUnexpectedInterrupt ; irql 29
+;
+; The following table picks up the highest pending software irq level
+; from software irr
+;
+
+ public SWInterruptLookUpTable
+SWInterruptLookUpTable label byte
+ db 0 ; SWIRR=0, so highest pending SW irql= 0
+ db 0 ; SWIRR=1, so highest pending SW irql= 0
+ db 1 ; SWIRR=2, so highest pending SW irql= 1
+ db 1 ; SWIRR=3, so highest pending SW irql= 1
+ db 2 ; SWIRR=4, so highest pending SW irql= 2
+ db 2 ; SWIRR=5, so highest pending SW irql= 2
+ db 2 ; SWIRR=6, so highest pending SW irql= 2
+ db 2 ; SWIRR=7, so highest pending SW irql= 2
+ db 3 ; SWIRR=8, so highest pending SW irql= 3
+ db 3 ; SWIRR=9, so highest pending SW irql= 3
+ db 3 ; SWIRR=A, so highest pending SW irql= 3
+ db 3 ; SWIRR=B, so highest pending SW irql= 3
+ db 3 ; SWIRR=C, so highest pending SW irql= 3
+ db 3 ; SWIRR=D, so highest pending SW irql= 3
+ db 3 ; SWIRR=E, so highest pending SW irql= 3
+ db 3 ; SWIRR=F, so highest pending SW irql= 3
+
+ db 4 ; SWIRR=10, so highest pending SW irql= 4
+ db 4 ; SWIRR=11, so highest pending SW irql= 4
+ db 4 ; SWIRR=12, so highest pending SW irql= 4
+ db 4 ; SWIRR=13, so highest pending SW irql= 4
+ db 4 ; SWIRR=14, so highest pending SW irql= 4
+ db 4 ; SWIRR=15, so highest pending SW irql= 4
+ db 4 ; SWIRR=16, so highest pending SW irql= 4
+ db 4 ; SWIRR=17, so highest pending SW irql= 4
+ db 4 ; SWIRR=18, so highest pending SW irql= 4
+ db 4 ; SWIRR=19, so highest pending SW irql= 4
+ db 4 ; SWIRR=1A, so highest pending SW irql= 4
+ db 4 ; SWIRR=1B, so highest pending SW irql= 4
+ db 4 ; SWIRR=1C, so highest pending SW irql= 4
+ db 4 ; SWIRR=1D, so highest pending SW irql= 4
+ db 4 ; SWIRR=1E, so highest pending SW irql= 4
+ db 4 ; SWIRR=1F, so highest pending SW irql= 4
+
+_DATA ENDS
+
+ page ,132
+ subttl "Raise Irql"
+
+_TEXT SEGMENT DWORD PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:FLAT, FS:NOTHING, GS:NOTHING
+;++
+;
+; KIRQL
+; FASTCALL
+; KfRaiseIrql (
+; IN KIRQL NewIrql
+; )
+;
+; Routine Description:
+;
+; This routine is used to raise IRQL to the specified value.
+; The 'lazy irql' algorythm is used, which is to say that the
+; hardware interrupt priority level will not be programmed unless
+; a lower priority interrupt actually comes in.
+;
+; Arguments:
+;
+; (cl) NewIrql - the new irql to be raised to
+;
+;
+; Return Value:
+;
+; OldIrql
+;
+;--
+
+; equates for accessing arguments
+
+cPublicFastCall KfRaiseIrql,1
+cPublicFpo 0, 0
+;
+; Note it is very important that we set the OldIrql AFTER we raised to
+; the new irql. Otherwise, if there is an interrupt comes in between and
+; the OldIrql is not a local variable, the caller will get wrong OldIrql.
+; The bottom line is the raising irql and returning old irql has to be
+; atomic to the caller.
+;
+ mov al, Fs:PcIrql ; (al) = Old Irql
+ mov Fs:PcIrql, cl ; set new irql
+
+if DBG
+ cmp al, cl ; old > new?
+ ja short Kri99 ; yes, go bugcheck
+
+ fstRET KfRaiseIrql
+
+cPublicFpo 2, 2
+Kri99:
+ push ecx ; put new irql where we can find it
+ push eax ; put old irql where we can find it
+ mov byte ptr Fs:PcIrql,0 ; avoid recursive error
+ stdCall _KeBugCheck, <IRQL_NOT_GREATER_OR_EQUAL> ; never return
+endif
+ fstRET KfRaiseIrql
+
+fstENDP KfRaiseIrql
+
+ page ,132
+ subttl "Lower irql"
+
+;++
+;
+; VOID
+; FASTCALL
+; KfLowerIrql (
+; IN KIRQL NewIrql
+; )
+;
+; Routine Description:
+;
+; This routine is used to lower IRQL to the specified value.
+; The IRQL and PIRQL will be updated accordingly. Also, this
+; routine checks to see if any software interrupt should be
+; generated. The following condition will cause software
+; interrupt to be simulated:
+; any software interrupt which has higher priority than
+; current IRQL's is pending.
+;
+; NOTE: This routine simulates software interrupt as long as
+; any pending SW interrupt level is higher than the current
+; IRQL, even when interrupts are disabled.
+;
+; Arguments:
+;
+; (cl) = NewIrql - the new irql to be set.
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+cPublicFastCall KfLowerIrql ,1
+cPublicFpo 0,0
+
+ mov al, cl ; get new irql value
+ if DBG
+ cmp al, Fs:PcIrql
+ ja short KliBug
+ endif
+ pushfd
+ cli
+ mov Fs:PcIrql, al ;save new irql
+ cmp al, Fs:PcHal.pchHwIrql ;does hardware need reprogramming?
+ jb short @F ;jump if it does
+ popfd
+ fstRET KfLowerIrql
+
+@@: mov Fs:PcHal.pchHwIrql, al
+ and eax, 0FFh
+ mov al, _HalpIRQLtoCPL[eax]
+ mov dx, My+CpuPriortyLevel
+ out dx, ax ;set hardware level down
+
+@@: mov eax, Fs:PcIRR ;look for software interrupts
+ and eax, 1Fh
+ jz short @F ;jump if none
+
+ mov al, SWInterruptLookUpTable[eax] ;get swint's irql
+ cmp al, Fs:PcIrql ;high enough to do this int?
+ jbe short @F ;jump if not
+
+ call SWInterruptHandlerTable[eax*4]
+ jmp @B
+
+@@: popfd
+ fstRET KfLowerIrql
+
+ if DBG
+KliBug:
+ push eax ; new irql for debugging
+ push Fs:PcIrql ; old irql for debugging
+ mov byte ptr Fs:PcIrql,HIGH_LEVEL ; avoid recursive error
+ stdCall _KeBugCheck, <IRQL_NOT_LESS_OR_EQUAL> ; never return
+ endif
+
+fstENDP KfLowerIrql
+
+cPublicProc _HalpEndSoftwareInterrupt,1
+cPublicFpo 1,0
+ mov ecx, [esp+4]
+ fstCall KfLowerIrql
+ stdRet _HalpEndSoftwareInterrupt
+stdENDP _HalpEndSoftwareInterrupt
+
+;++
+;
+; VOID
+; KIRQL
+; KeRaiseIrqlToDpcLevel (
+; )
+;
+; Routine Description:
+;
+; This routine is used to raise IRQL to DPC level.
+; The APIC TPR is used to block all lower-priority HW interrupts.
+;
+; Arguments:
+;
+; Return Value:
+;
+; OldIrql - the addr of a variable which old irql should be stored
+;
+;--
+
+cPublicProc _KeRaiseIrqlToDpcLevel,0
+cPublicFpo 0, 0
+
+ mov ecx, DISPATCH_LEVEL
+ jmp @KfRaiseIrql
+
+stdENDP _KeRaiseIrqlToDpcLevel
+
+
+;++
+;
+; VOID
+; KIRQL
+; KeRaiseIrqlToSynchLevel (
+; )
+;
+; Routine Description:
+;
+; This routine is used to raise IRQL to SYNC level.
+; The APIC TPR is used to block all lower-priority HW interrupts.
+;
+; Arguments:
+;
+; Return Value:
+;
+; OldIrql - the addr of a variable which old irql should be stored
+;
+;--
+
+cPublicProc _KeRaiseIrqlToSynchLevel,0
+
+ mov ecx, SYNCH_LEVEL
+ jmp @KfRaiseIrql
+
+stdENDP _KeRaiseIrqlToSynchLevel
+
+
+ page ,132
+ subttl "Get current irql"
+
+;++
+;
+; KIRQL
+; KeGetCurrentIrql (VOID)
+;
+; Routine Description:
+;
+; This routine returns to current IRQL.
+;
+; Arguments:
+;
+; None.
+;
+; Return Value:
+;
+; The current IRQL.
+;
+;--
+
+cPublicProc _KeGetCurrentIrql ,0
+ movzx eax, byte ptr fs:PcIrql ; Current irql is in the PCR
+ stdRET _KeGetCurrentIrql
+stdENDP _KeGetCurrentIrql
+
+;++
+;
+; VOID
+; HalpDisableAllInterrupts (VOID)
+;
+; Routine Description:
+;
+; This routine is called during a system crash. The hal needs all
+; interrupts disabled.
+;
+; Arguments:
+;
+; None.
+;
+; Return Value:
+;
+; None - all interrupts are masked off
+;
+;--
+
+cPublicProc _HalpDisableAllInterrupts,0
+
+ ;
+ ; Raising to HIGH_LEVEL disables interrupts for the Wyse HAL
+ ;
+
+ mov ecx, HIGH_LEVEL
+ fstCall KfRaiseIrql
+ mov al, _HalpIRQLtoCPL[HIGH_LEVEL]
+ mov dx, My+CpuPriortyLevel
+ out dx, ax
+ mov Fs:PcHal.pchHwIrql, HIGH_LEVEL
+ stdRET _HalpDisableAllInterrupts
+
+stdENDP _HalpDisableAllInterrupts
+
+ page ,132
+ subttl "Interrupt Controller Chip Initialization"
+;++
+;
+; VOID
+; HalpInitializePICs (
+; )
+;
+; Routine Description:
+;
+; This routine sends the 8259 PIC initialization commands and
+; masks all the interrupts on 8259s.
+;
+; Arguments:
+;
+; None
+;
+; Return Value:
+;
+; None.
+;
+;--
+cPublicProc _HalpInitializePICs ,0
+
+ push esi ; save caller's esi
+ cli ; disable interrupt
+ lea esi, PICsInitializationString
+
+Hip00:
+ lodsw ; (AX) = PIC port 0 address
+Hip10: movzx edx, ax
+ outsb ; output ICW1
+ IODelay
+ inc edx ; (DX) = PIC port 1 address
+ outsb ; output ICW2
+ IODelay
+ outsb ; output ICW3
+ IODelay
+ outsb ; output ICW4
+ IODelay
+ outsb ; output OCW1 (interrupt mask)
+ lodsw
+ cmp ax, 0 ; end of init string?
+ jne short Hip10 ; go init next PIC
+
+ pop esi ; restore caller's esi
+ sti ; enable interrupt
+ stdRET _HalpInitializePICs
+stdENDP _HalpInitializePICs
+
+_TEXT ends
+ end
diff --git a/private/ntos/nthals/halwyse7/i386/wymapint.c b/private/ntos/nthals/halwyse7/i386/wymapint.c
new file mode 100644
index 000000000..6a8d48717
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wymapint.c
@@ -0,0 +1,185 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ wymapint.c
+
+Abstract:
+
+ This module implements the HAL HalGetInterruptVector routine
+ for an x86 system
+
+Author:
+
+ John Vert (jvert) 17-Jul-1991
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+ John Fuller (o-johnf) 3-Apr-1992 Modifications for Wyse7000i
+--*/
+#include "halp.h"
+#if DBG
+ULONG
+ProcSub(
+ IN UCHAR RoutineNumber
+ );
+
+#define enproc(x) ProcSub(x)
+#define exproc(x) ProcSub((x)|0x80)
+
+#else //DBG
+
+#define enproc(x)
+#define exproc(x)
+
+#endif //DBG
+
+
+extern CCHAR HalpVectorToIRQL[];
+
+ULONG HalpDefaultInterruptAffinity;
+
+BOOLEAN
+HalpTranslateSystemBusAddress(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ );
+
+ULONG
+HalpGetSystemInterruptVector(
+ IN PBUS_HANDLER BusHandler,
+ IN PBUS_HANDLER RootHandler,
+ IN ULONG BusInterruptLevel,
+ IN ULONG BusInterruptVector,
+ OUT PKIRQL Irql,
+ OUT PKAFFINITY Affinity
+ );
+
+
+#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
+
+--*/
+
+{
+ UNREFERENCED_PARAMETER( BusHandler );
+
+ if (BusAddress.HighPart != 0 || *AddressSpace > 1) {
+ return (FALSE);
+ }
+
+ TranslatedAddress->LowPart = BusAddress.LowPart;
+ TranslatedAddress->HighPart = 0;
+
+ return(TRUE);
+}
+
+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;
+
+ UNREFERENCED_PARAMETER( BusHandler );
+ UNREFERENCED_PARAMETER( BusInterruptVector );
+
+ enproc(0x0F);
+
+ SystemVector = BusInterruptLevel + PRIMARY_VECTOR_BASE;
+ if (SystemVector < PRIMARY_VECTOR_BASE ||
+ SystemVector > PRIMARY_VECTOR_BASE + HIGHEST_LEVEL_FOR_8259 ||
+ HalpIDTUsage[SystemVector].Flags & IDTOwned ) {
+
+ //
+ // This is an illegal BusInterruptVector and cannot be connected.
+ //
+
+ return(0);
+ }
+
+ *Irql = (KIRQL) HalpVectorToIRQL[BusInterruptLevel];
+
+ //
+ // On most MP systems the interrupt affinity is all processors.
+ //
+ *Affinity = HalpDefaultInterruptAffinity;
+ ASSERT(HalpDefaultInterruptAffinity);
+
+ exproc(0x0F);
+ return SystemVector;
+}
+
diff --git a/private/ntos/nthals/halwyse7/i386/wynmi.asm b/private/ntos/nthals/halwyse7/i386/wynmi.asm
new file mode 100644
index 000000000..1bf044c0f
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wynmi.asm
@@ -0,0 +1,108 @@
+ title "Wyse7000i NMI Handler"
+;++
+;
+; Copyright (c) 1989 Microsoft Corporation
+;
+; Module Name:
+;
+; wynmi.asm
+;
+; Abstract:
+;
+; Provides Wyse7000 x86 NMI handler
+;
+; Author:
+;
+; Environment:
+;
+; Kernel mode only.
+;
+; Revision History:
+;
+.386p
+
+ .xlist
+include hal386.inc
+include i386\wy7000mp.inc
+include callconv.inc
+
+ extrn ReadMyCpuReg:NEAR
+ extrn WriteMyCpuReg:NEAR
+
+_TEXT SEGMENT DWORD PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
+
+;++
+; NTSTATUS
+; HalHandleNMI(
+; IN OUT PVOID NmiInfo
+; )
+;
+; Routine Description:
+;
+; Called DURING an NMI. The system will BugCheck when an NMI occurs.
+; This function can return the proper bugcheck code, bugcheck itself,
+; or return success which will cause the system to iret from the nmi.
+;
+; This function is called during an NMI - no system services are available.
+; In addition, you don't want to touch any spinlock which is normally
+; used since we may have been interrupted while owning it, etc, etc...
+;
+;Arguments:
+;
+; NmiInfo - Pointer to NMI information structure (TBD)
+; - NULL means no NMI information structure was passed
+;
+;Return Value:
+;
+; BugCheck code
+;
+;--
+cPublicProc _HalHandleNMI,1
+
+ push BCU_STAT1
+ call ReadMyCpuReg
+
+ test al, NMISRC_EXT
+ jnz short WyseDebugNmiButtonPressed
+
+;
+; Decode other Wyse7000 NMI causes here...
+;
+ mov eax, MPFW_FuncTable ;point to firmware entry points
+
+ call dword ptr [eax][fnOS_Panic * 4] ;display NMI code to user
+
+ mov eax, 0f002h ; SYSTEM_FATAL_TRAP
+ stdRET _HalHandleNMI
+
+ public WyseDebugNmiButtonPressed
+WyseDebugNmiButtonPressed:
+;
+; Recessed NMI button on back of CPU card was pressed
+; Go to the debugger, then allow the system to continue
+;
+ int 3
+
+ and eax, NOT NMISRC_EXT
+ push eax
+ push BCU_STAT1
+ call WriteMyCpuReg
+;
+; Re-enable NMIs
+;
+ push BCU_ERRCTLR
+ call ReadMyCpuReg
+ or al, NMI_ENB ;this bit was cleared by the NMI
+ push eax
+ push BCU_ERRCTLR
+ call WriteMyCpuReg
+
+ xor eax, eax ; STATUS_SUCCESS
+ stdRET _HalHandleNMI
+
+stdENDP _HalHandleNMI
+
+_TEXT ends
+
+ end
diff --git a/private/ntos/nthals/halwyse7/i386/wyspin.asm b/private/ntos/nthals/halwyse7/i386/wyspin.asm
new file mode 100644
index 000000000..b9d320668
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wyspin.asm
@@ -0,0 +1,449 @@
+if NT_INST
+
+else
+ TITLE "Spin Locks"
+;++
+;
+; Copyright (c) 1989-1993 Microsoft Corporation
+; Copyright (c) 1993 Wyse Technology
+;
+; Module Name:
+;
+; wyspin.asm
+;
+; Abstract:
+;
+; This module implements stubbed x86 spinlock functions for
+; any HAL. Some HALs may implement these function directly
+; to minimize the amount of code required to perform a spinlock.
+; (ie, out Raise & Lower irql in the fall through path)
+;
+; Author:
+;
+; Bryan Willman (bryanwi) 13 Dec 89
+;
+; Environment:
+;
+; Kernel mode only.
+;
+; Revision History:
+;
+; Ken Reneris (kenr) 22-Jan-1991
+; John Fuller (o-johnf) 19-Apr-1993 modify for Wyse 7000i
+; John Fuller (o-johnf) 31-Aug-1993 modify for Lazy IRQLs
+;--
+
+ PAGE
+
+.486p
+
+include callconv.inc ; calling convention macros
+include i386\kimacro.inc
+include hal386.inc
+include mac386.inc
+include i386\wy7000mp.inc
+
+ EXTRNP KfRaiseIrql,1,,FASTCALL
+ EXTRNP KfLowerIrql,1,,FASTCALL
+ EXTRNP _KeBugCheck,1,IMPORT
+ EXTRNP _KeSetEventBoostPriority, 2, IMPORT
+ EXTRNP _KeWaitForSingleObject,5, IMPORT
+ extrn SWInterruptLookUpTable:byte
+ extrn SWInterruptHandlerTable:dword
+ extrn _HalpIRQLtoCPL:byte
+
+ifdef NT_UP
+ LOCK_ADD equ add
+ LOCK_DEC equ dec
+else
+ LOCK_ADD equ lock add
+ LOCK_DEC equ lock dec
+endif
+
+_TEXT SEGMENT PARA PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:FLAT, FS:NOTHING, GS:NOTHING
+
+ PAGE
+ SUBTTL "Acquire Kernel Spin Lock"
+;++
+;
+; KIRQL
+; FASTCALL
+; KfAcquireSpinLock (
+; IN PKSPIN_LOCK SpinLock
+; )
+;
+; Routine Description:
+;
+; This function raises to DISPATCH_LEVEL and then acquires a the
+; kernel spin lock.
+;
+; Arguments:
+;
+; (ecx) SpinLock - Supplies a pointer to an kernel spin lock.
+;
+; Return Value:
+;
+; OldIrql
+;
+;--
+
+align 16
+cPublicFastCall KfAcquireSpinLock ,1
+
+ifdef NT_UP ; On up build just perform raiseirql
+
+ mov ecx, DISPATCH_LEVEL
+ jmp @KfRaiseIrql@4
+else
+cPublicFpo 0,0
+;
+; On a MP build we raise to dispatch_level
+; and then acquire the spinlock
+;
+
+;
+; Since on the Wyse 7000i the hardware priority of DISPATCH_LEVEL
+; is the same as for all levels below DISPATCH_LEVEL we just need
+; to update PcIrql to raise the level and don't need to touch the
+; hardware.
+;
+ mov al, fs:PcIrql ; get current irql
+
+if DBG
+ cmp al, DISPATCH_LEVEL ; old > new?
+ jbe short @F ; no, we're OK
+ push DISPATCH_LEVEL ; put new irql where we can find it
+ push eax ; put old irql where we can find it
+ mov byte ptr fs:PcIrql,0 ; avoid recursive error
+ stdCall _KeBugCheck, <IRQL_NOT_GREATER_OR_EQUAL>
+@@:
+endif
+
+ mov byte ptr fs:PcIrql, DISPATCH_LEVEL
+
+;
+; Attempt to assert the lock
+;
+
+sl10: ACQUIRE_SPINLOCK ecx,<short sl20>
+ fstRET KfAcquireSpinLock
+
+;
+; Lock is owned, spin till it looks free, then go get it again.
+;
+
+sl20: SPIN_ON_SPINLOCK ecx,sl10
+
+endif
+
+fstENDP KfAcquireSpinLock
+
+
+ PAGE
+ SUBTTL "Acquire Synch Kernel Spin Lock"
+;++
+;
+; KIRQL
+; FASTCALL
+; KeAcquireSpinLockRaiseToSynch (
+; IN PKSPIN_LOCK SpinLock
+; )
+;
+; Routine Description:
+;
+; This function acquires the SpinLock at SYNCH_LEVEL. The function
+; is optmized for hoter locks (the lock is tested before acquired,
+; any spin should occur at OldIrql)
+;
+; Arguments:
+;
+; (ecx) = SpinLock - Supplies a pointer to an kernel spin lock.
+;
+; Return Value:
+;
+; OldIrql - pointer to place old irql
+;
+;--
+
+align 16
+cPublicFastCall KeAcquireSpinLockRaiseToSynch,1
+cPublicFpo 0,0
+
+;
+; Disable interrupts
+;
+
+sls10: cli
+
+;
+; Try to obtain spinlock. Use non-lock operation first
+;
+ TEST_SPINLOCK ecx,<short sls20>
+ ACQUIRE_SPINLOCK ecx,<short sls20>
+
+
+;
+; Got the lock, raise to SYNCH_LEVEL
+;
+
+ mov ecx, SYNCH_LEVEL
+ fstCall KfRaiseIrql ; (al) = OldIrql
+
+;
+; Enable interrupts and return
+;
+
+ sti
+ fstRET KeAcquireSpinLockRaiseToSynch
+
+
+;
+; Lock is owned, spin till it looks free, then go get it again.
+;
+
+sls20: sti
+ SPIN_ON_SPINLOCK ecx,sls10
+
+fstENDP KeAcquireSpinLockRaiseToSynch
+
+ PAGE
+ SUBTTL "Release Kernel Spin Lock"
+
+;++
+;
+; VOID
+; FASTCALL
+; KfReleaseSpinLock (
+; IN PKSPIN_LOCK SpinLock,
+; IN KIRQL NewIrql
+; )
+;
+; Routine Description:
+;
+; This function releases a kernel spin lock and lowers to the new irql
+;
+; Arguments:
+;
+; (ecx) SpinLock - Supplies a pointer to an executive spin lock.
+; (dl) NewIrql - New irql value to set
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+align 16
+cPublicFastCall KfReleaseSpinLock ,2
+
+ifndef NT_UP
+cPublicFpo 2,0
+ RELEASE_SPINLOCK ecx ; release it
+endif
+;
+; NOTE: The following code for the Wyse 7000i does not assume any knowelege
+; of either the current Irql or the new Irql. Therefore, the hardware
+; must be programmed.
+;
+ mov al, dl ; get new irql value
+ if DBG
+ cmp al, Fs:PcIrql
+ ja short KrsBug
+ endif
+ pushfd
+ cli
+ mov Fs:PcIrql, al ;save new irql
+ cmp al, Fs:PcHal.pchHwIrql ;does hardware need reprogramming?
+ jb short @F ;jump if it does
+ popfd
+ fstRET KfReleaseSpinLock
+
+@@: mov Fs:PcHal.pchHwIrql, al
+ and eax, 0FFh
+ mov dx, My+CpuPriortyLevel
+ mov al, _HalpIRQLtoCPL[eax]
+ out dx, ax ;set hardware level down
+
+@@: mov eax, Fs:PcIRR ;look for software interrupts
+ and eax, 1Fh
+ jz short @F ;jump if none
+
+ mov al, SWInterruptLookUpTable[eax] ;get swint's irql
+ cmp al, Fs:PcIrql ;high enough to do this int?
+ jbe short @F ;jump if not
+
+ call SWInterruptHandlerTable[eax*4]
+ jmp @B
+
+@@: popfd
+ fstRET KfReleaseSpinLock
+
+ if DBG
+KrsBug:
+ push eax ; new irql for debugging
+ push Fs:PcIrql ; old irql for debugging
+ mov byte ptr Fs:PcIrql,HIGH_LEVEL ; avoid recursive error
+ stdCall _KeBugCheck, <IRQL_NOT_LESS_OR_EQUAL> ; never return
+ endif
+
+fstENDP KfReleaseSpinLock
+
+;++
+;
+; VOID
+; FASTCALL
+; ExAcquireFastMutex (
+; IN PFAST_MUTEX FastMutex
+; )
+;
+; Routine description:
+;
+; This function acquire ownership of the FastMutex
+;
+; Arguments:
+;
+; (ecx) = FastMutex - Supplies a pointer to the fast mutex
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+cPublicFastCall ExAcquireFastMutex,1
+cPublicFpo 0,1
+
+ push ecx ; Push FAST_MUTEX addr
+ mov ecx, APC_LEVEL
+ fstCall KfRaiseIrql
+
+ pop ecx ; (ecx) = Fast Mutex
+
+cPublicFpo 0,0
+ LOCK_DEC dword ptr [ecx].FmCount ; Get count
+ jz short afm_ret ; The owner? Yes, Done
+
+ inc dword ptr [ecx].FmContention
+
+cPublicFpo 0,1
+ push ecx
+ push eax
+ add ecx, FmEvent ; Wait on Event
+ stdCall _KeWaitForSingleObject,<ecx,WrExecutive,0,0,0>
+ pop eax
+ pop ecx
+
+cPublicFpo 0,0
+afm_ret:
+ mov byte ptr [ecx].FmOldIrql, al
+ fstRet ExAcquireFastMutex
+
+fstENDP ExAcquireFastMutex
+
+;++
+;
+; BOOLEAN
+; FASTCALL
+; ExTryToAcquireFastMutex (
+; IN PFAST_MUTEX FastMutex
+; )
+;
+; Routine description:
+;
+; This function acquire ownership of the FastMutex
+;
+; Arguments:
+;
+; (ecx) = FastMutex - Supplies a pointer to the fast mutex
+;
+; Return Value:
+;
+; Returns TRUE if the FAST_MUTEX was acquired; otherwise false
+;
+;--
+
+cPublicFastCall ExTryToAcquireFastMutex,1
+cPublicFpo 0,0
+
+;
+; Try to acquire
+;
+ cmp dword ptr [ecx].FmCount, 1 ; Busy?
+ jne short tam25 ; Yes, abort
+
+cPublicFpo 0,1
+ push ecx ; Push FAST_MUTEX
+ mov ecx, APC_LEVEL
+ fstCall KfRaiseIrql ; (al) = OldIrql
+
+ mov ecx, [esp] ; Restore FAST_MUTEX
+ mov [esp], eax ; Save OldIrql
+
+ mov eax, 1 ; Value to compare against
+ mov edx, 0 ; Value to set
+ lock cmpxchg dword ptr [ecx].FmCount, edx ; Attempt to acquire
+ jnz short tam20 ; got it?
+
+cPublicFpo 0,0
+ pop edx ; (edx) = OldIrql
+ mov eax, 1 ; return TRUE
+ mov byte ptr [ecx].FmOldIrql, dl ; Store OldIrql
+ fstRet ExTryToAcquireFastMutex
+
+tam20: pop ecx ; (ecx) = OldIrql
+ fstCall KfLowerIrql ; restore OldIrql
+tam25: xor eax, eax ; return FALSE
+ fstRet ExTryToAcquireFastMutex ; all done
+
+fstENDP ExTryToAcquireFastMutex
+
+
+;++
+;
+; VOID
+; FASTCALL
+; ExReleaseFastMutex (
+; IN PFAST_MUTEX FastMutex
+; )
+;
+; Routine description:
+;
+; This function releases ownership of the FastMutex
+;
+; Arguments:
+;
+; (ecx) FastMutex - Supplies a pointer to the fast mutex
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+cPublicFastCall ExReleaseFastMutex,1
+
+cPublicFpo 0,0
+ mov al, byte ptr [ecx].FmOldIrql ; (cl) = OldIrql
+
+ LOCK_ADD dword ptr [ecx].FmCount, 1 ; Remove our count
+ xchg ecx, eax ; (cl) = OldIrql
+ js short rfm05 ; if < 0, set event
+ jnz @KfLowerIrql@4 ; if != 0, don't set event
+
+rfm05: add eax, FmEvent
+ push ecx
+ stdCall _KeSetEventBoostPriority, <eax, 0>
+ pop ecx
+ jmp @KfLowerIrql@4
+
+
+fstENDP ExReleaseFastMutex
+
+
+
+_TEXT ends
+
+ENDIF ; NT_INST
+
+ end
diff --git a/private/ntos/nthals/halwyse7/i386/wysproc.c b/private/ntos/nthals/halwyse7/i386/wysproc.c
new file mode 100644
index 000000000..3c8d2ff1e
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wysproc.c
@@ -0,0 +1,465 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+Copyright (c) 1992, 1993 Wyse Technology
+
+Module Name:
+
+ spsproc.c
+
+Abstract:
+
+ Wyse7000i Start Next Processor c code.
+
+ This module implements the initialization of the system dependent
+ functions that define the Hardware Architecture Layer (HAL) for an
+ Wyse MP 7000i
+
+Author:
+
+ Ken Reneris (kenr) 22-Jan-1991
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+#include "halp.h"
+
+UCHAR HalName[] = "Wyse7000i MP HAL";
+
+#if DBG
+ULONG
+ProcSub(
+ IN UCHAR RoutineNumber
+ );
+
+#define enproc(x) ProcSub(x)
+#define exproc(x) ProcSub((x)|0x80)
+
+#else //DBG
+
+#define enproc(x)
+#define exproc(x)
+
+#endif //DBG
+
+
+PVOID
+HalpRemapVirtualAddress(
+ IN PVOID VirtualAddress,
+ IN PVOID PhysicalAddress,
+ IN BOOLEAN WriteThrough
+ );
+
+VOID
+HalpMapCR3 (
+ IN ULONG VirtAddress,
+ IN PVOID PhysicalAddress,
+ IN ULONG Length
+ );
+
+ULONG
+HalpBuildTiledCR3 (
+ IN PKPROCESSOR_STATE ProcessorState
+ );
+
+VOID
+HalpFreeTiledCR3 (
+ VOID
+ );
+
+VOID HalpInitOtherBuses (VOID);
+
+BOOLEAN
+HalpInitMP (
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ );
+
+ULONG __cdecl
+icu_sync_master (
+ ULONG i_sync,
+ UCHAR i_exp_cfg,
+ ULONG i_timeout
+ );
+
+
+#define LOW_MEMORY 0x000100000
+
+#define MAX_PT 8
+
+extern VOID StartPx_PMStub(VOID);
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpInitMP)
+#pragma alloc_text(INIT,HalAllProcessorsStarted)
+#pragma alloc_text(INIT,HalReportResourceUsage)
+#pragma alloc_text(INIT,HalReportResourceUsage)
+#pragma alloc_text(INIT,HalpInitOtherBuses)
+#pragma alloc_text(INIT,HalpFreeTiledCR3)
+#pragma alloc_text(INIT,HalpMapCR3)
+#pragma alloc_text(INIT,HalpBuildTiledCR3)
+#endif
+
+UCHAR ProcessorsPresent; // bitmap by WWB slot of cpu's present
+PUCHAR MpLowStub; // pointer to low memory bootup stub
+PVOID MpLowStubPhysicalAddress; // pointer to low memory bootup stub
+PUCHAR MppIDT; // pointer to physical memory 0:0
+PVOID MpFreeCR3[MAX_PT]; // remember pool memory to free
+
+
+BOOLEAN
+HalpInitMP (
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+/*++
+
+Routine Description:
+ Allows MP initialization from HalInitSystem.
+
+Arguments:
+ Same as HalInitSystem
+
+Return Value:
+ none.
+
+--*/
+{
+ ULONG paddress;
+ ULONG adjust;
+ PKPCR pPCR;
+
+ enproc(0x0B);
+
+
+ pPCR = KeGetPcr();
+
+ if (Phase == 0) {
+ MppIDT = HalpMapPhysicalMemory (0, 1);
+
+ //
+ // Map system firmware to last 128Kb of memory
+ //
+
+ paddress = 0xFFFE0000; // address of last 128Kb of memory
+ for (adjust = 0x20000 / PAGE_SIZE; adjust; --adjust) {
+ HalpRemapVirtualAddress((PVOID) paddress, (PVOID) paddress, FALSE);
+ paddress += PAGE_SIZE;
+ }
+
+ //
+ // Are other processors installed and running?
+ //
+
+ if ( ProcessorsPresent ) { // any other cpu's installed?
+ adjust = icu_sync_master( 0x80, // SYNC_CONTINUE
+ ProcessorsPresent,// cpu's installed
+ 5 ); // 5*15ms timeout
+ ProcessorsPresent = (UCHAR) (adjust >> 8); // running cpu's
+ }
+
+ if ( !ProcessorsPresent ) {
+ exproc(0x0B);
+ return TRUE;
+ }
+
+ //
+ // Allocate some low memory for processor bootup stub
+ //
+
+ MpLowStubPhysicalAddress = (PVOID)HalpAllocPhysicalMemory (LoaderBlock,
+ LOW_MEMORY, 1, FALSE);
+
+ if (!MpLowStubPhysicalAddress) {
+ ProcessorsPresent = 0; // can't start other cpu's
+ exproc(0x0B);
+ return TRUE;
+ }
+
+ MpLowStub = (PCHAR) HalpMapPhysicalMemory (MpLowStubPhysicalAddress, 1);
+ exproc(0x0B);
+ return TRUE;
+
+ } else {
+
+ //
+ // Phase 1
+ //
+
+ ; // nothing to do
+
+ }
+ exproc(0x0B);
+}
+
+BOOLEAN
+HalAllProcessorsStarted (
+ VOID
+ )
+{
+ return TRUE;
+}
+
+
+VOID
+HalReportResourceUsage (
+ VOID
+ )
+/*++
+
+Routine Description:
+ The registery is now enabled - time to report resources which are
+ used by the HAL.
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ ANSI_STRING AHalName;
+ UNICODE_STRING UHalName;
+
+ HalInitSystemPhase2 ();
+
+ RtlInitAnsiString (&AHalName, HalName);
+ RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE);
+
+ HalpReportResourceUsage (
+ &UHalName, // descriptive name
+ Eisa // Wyse7000 is an Eisa machines
+ );
+
+ RtlFreeUnicodeString (&UHalName);
+}
+
+
+
+VOID
+HalpResetAllProcessors (
+ VOID
+ )
+{
+ // Just return, that will invoke the standard PC reboot code
+}
+
+
+ULONG
+HalpBuildTiledCR3 (
+ IN PKPROCESSOR_STATE ProcessorState
+ )
+/*++
+
+Routine Description:
+ When the x86 processor is reset it starts in real-mode. In order to
+ move the processor from real-mode to protected mode with flat addressing
+ the segment which loads CR0 needs to have it's linear address mapped
+ to machine the phyiscal location of the segment for said instruction so
+ the processor can continue to execute the following instruction.
+
+ This function is called to built such a tiled page directory. In
+ addition, other flat addresses are tiled to match the current running
+ flat address for the new state. Once the processor is in flat mode,
+ we move to a NT tiled page which can then load up the remaining processors
+ state.
+
+Arguments:
+ ProcessorState - The state the new processor should start in.
+
+Return Value:
+ Physical address of Tiled page directory
+
+
+--*/
+{
+ enproc(0x0C);
+#define GetPdeAddress(va) ((PHARDWARE_PTE)((((((ULONG)(va)) >> 22) & 0x3ff) << 2) + (PUCHAR)MpFreeCR3[0]))
+#define GetPteAddress(va) ((PHARDWARE_PTE)((((((ULONG)(va)) >> 12) & 0x3ff) << 2) + (PUCHAR)pPageTable))
+
+// bugbug kenr 27mar92 - fix physical memory usage!
+
+ MpFreeCR3[0] = ExAllocatePool (NonPagedPool, PAGE_SIZE);
+ RtlZeroMemory (MpFreeCR3[0], PAGE_SIZE);
+
+ //
+ // Map page for real mode stub (one page)
+ //
+ HalpMapCR3 ((ULONG) MpLowStubPhysicalAddress,
+ MpLowStubPhysicalAddress,
+ PAGE_SIZE);
+
+ //
+ // Map page for protect mode stub (one page)
+ //
+ HalpMapCR3 ((ULONG) &StartPx_PMStub, NULL, 0x1000);
+
+
+ //
+ // Map page(s) for processors GDT
+ //
+ HalpMapCR3 (ProcessorState->SpecialRegisters.Gdtr.Base, NULL,
+ ProcessorState->SpecialRegisters.Gdtr.Limit);
+
+
+ //
+ // Map page(s) for processors IDT
+ //
+ HalpMapCR3 (ProcessorState->SpecialRegisters.Idtr.Base, NULL,
+ ProcessorState->SpecialRegisters.Idtr.Limit);
+
+ exproc(0x0C);
+ return MmGetPhysicalAddress (MpFreeCR3[0]).LowPart;
+}
+
+
+VOID
+HalpMapCR3 (
+ IN ULONG VirtAddress,
+ IN PVOID PhysicalAddress,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+ Called to build a page table entry for the passed page directory.
+ Used to build a tiled page directory with real-mode & flat mode.
+
+Arguments:
+ VirtAddress - Current virtual address
+ PhysicalAddress - Optional. Physical address to be mapped to, if passed
+ as a NULL then the physical address of the passed
+ virtual address is assumed.
+ Length - number of bytes to map
+
+Return Value:
+ none.
+
+--*/
+{
+ ULONG i;
+ PHARDWARE_PTE PTE;
+ PVOID pPageTable;
+ PHYSICAL_ADDRESS pPhysicalPage;
+
+ enproc(0x0D);
+
+ while (Length) {
+ PTE = GetPdeAddress (VirtAddress);
+ if (!PTE->PageFrameNumber) {
+ pPageTable = ExAllocatePool (NonPagedPool, PAGE_SIZE);
+ RtlZeroMemory (pPageTable, PAGE_SIZE);
+
+ for (i=0; i<MAX_PT; i++) {
+ if (!MpFreeCR3[i]) {
+ MpFreeCR3[i] = pPageTable;
+ break;
+ }
+ }
+ ASSERT (i<MAX_PT);
+
+ pPhysicalPage = MmGetPhysicalAddress (pPageTable);
+ PTE->PageFrameNumber = (pPhysicalPage.LowPart >> PAGE_SHIFT);
+ PTE->Valid = 1;
+ PTE->Write = 1;
+ }
+
+ pPhysicalPage.LowPart = PTE->PageFrameNumber << PAGE_SHIFT;
+ pPhysicalPage.HighPart = 0;
+ pPageTable = MmMapIoSpace (pPhysicalPage, PAGE_SIZE, TRUE);
+
+ PTE = GetPteAddress (VirtAddress);
+
+ if (!PhysicalAddress) {
+ PhysicalAddress = (PVOID)MmGetPhysicalAddress ((PVOID)VirtAddress).LowPart;
+ }
+
+ PTE->PageFrameNumber = ((ULONG) PhysicalAddress >> PAGE_SHIFT);
+ PTE->Valid = 1;
+ PTE->Write = 1;
+
+ MmUnmapIoSpace (pPageTable, PAGE_SIZE);
+
+ PhysicalAddress = 0;
+ VirtAddress += PAGE_SIZE;
+ if (Length > PAGE_SIZE) {
+ Length -= PAGE_SIZE;
+ } else {
+ Length = 0;
+ }
+ }
+ exproc(0x0D);
+}
+
+
+
+VOID
+HalpFreeTiledCR3 (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Free's any memory allocated when the tiled page directory was built.
+
+Arguments:
+ none
+
+Return Value:
+ none
+--*/
+{
+ ULONG i;
+
+ enproc(0x0E);
+
+ for (i=0; MpFreeCR3[i]; i++) {
+ ExFreePool (MpFreeCR3[i]);
+ MpFreeCR3[i] = 0;
+ }
+ exproc(0x0E);
+}
+
+
+
+VOID
+HalpInitOtherBuses (
+ VOID
+ )
+{
+ // no other buses
+}
+
+
+
+NTSTATUS
+HalpGetMcaLog (
+ OUT PMCA_EXCEPTION Exception,
+ OUT PULONG ReturnedLength
+ )
+{
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+HalpMcaRegisterDriver(
+ IN PMCA_DRIVER_INFO DriverInfo
+ )
+{
+ return STATUS_NOT_SUPPORTED;
+}
+
+
+ULONG
+FASTCALL
+HalSystemVectorDispatchEntry (
+ IN ULONG Vector,
+ OUT PKINTERRUPT_ROUTINE **FlatDispatch,
+ OUT PKINTERRUPT_ROUTINE *NoConnection
+ )
+{
+ return FALSE;
+}
diff --git a/private/ntos/nthals/halwyse7/i386/wysproca.asm b/private/ntos/nthals/halwyse7/i386/wysproca.asm
new file mode 100644
index 000000000..07ec04831
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wysproca.asm
@@ -0,0 +1,436 @@
+ title "MP primitives for Wyse 7000i"
+;++
+;
+;Copyright (c) 1991 Microsoft Corporation
+;
+;Module Name:
+;
+; wysproca.asm
+;
+;Abstract:
+;
+; Wyse7000i Start Next Processor assemble code
+;
+; This module along with wysproc.c implement the code to start
+; off additional processors on the Wyse 7000i.
+;
+;Author:
+;
+; Ken Reneris (kenr) 12-Jan-1992
+;
+;Revision History:
+;
+; John Fuller (o-johnf) 7-Apr-1992 convert to Wyse 7000i
+;
+;--
+
+
+
+.386p
+ .xlist
+include hal386.inc
+include callconv.inc ; calling convention macros
+include i386\kimacro.inc
+include mac386.inc
+include i386\wy7000mp.inc
+ .list
+
+ EXTRNP _ExAllocatePool,2,IMPORT
+ EXTRNP _HalpBuildTiledCR3,1
+ EXTRNP _HalpFreeTiledCR3,0
+
+ extrn _MppIDT:DWORD
+ extrn _MpLowStub:DWORD
+ extrn _MpLowStubPhysicalAddress:DWORD
+ extrn _ProcessorsPresent:BYTE
+
+
+
+;
+; Internal defines and structures
+;
+
+PxParamBlock struc
+ SPx_flag dd ?
+ SPx_TiledCR3 dd ?
+ SPx_P0EBP dd ?
+ SPx_PB db processorstatelength dup (?)
+PxParamBlock ends
+
+BootPkg struc
+bpLength db 08h + 80h ;package length + sync flag
+bpDest db ? ;destination bitmap
+bpCode db 08h + 40h+ 80h ;boot_cpu_cmd + mpfw_pkg + cmd_pkg
+ db 0 ;reserved
+bpStartAddr dd ? ;start execution physical addr
+ ;executions starts in flat 32-bit
+ ;non-paged mode.
+BootPkg ends
+
+_DATA SEGMENT DWORD PUBLIC 'DATA'
+
+ public _CpuBootPkg
+_CpuBootPkg BootPkg <>
+
+_DATA ends
+
+_TEXT SEGMENT PARA PUBLIC 'CODE' ; Start 32 bit code
+ ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
+
+;++
+;
+; BOOLEAN
+; HalStartNextProcessor (
+; IN PLOADER_BLOCK pLoaderBlock,
+; IN PKPROCESSOR_STATE pProcessorState
+; )
+;
+; Routine Description:
+;
+; This routine is called by the kernel durning kernel initialization
+; to obtain more processors. It is called until no more processors
+; are available.
+;
+; If another processor exists this function is to initialize it to
+; the passed in processorstate structure, and return TRUE.
+;
+; If another processor does not exists, then a FALSE is returned.
+;
+; Also note that the loader block has been setup for the next processor.
+; The new processor logical thread number can be obtained from it, if
+; required.
+;
+; Arguments:
+; pLoaderBlock, - Loader block which has been intialized for the
+; next processor.
+;
+; pProcessorState - The processor state which is to be loaded into
+; the next processor.
+;
+;
+; Return Value:
+;
+; TRUE - ProcessorNumber was dispatched.
+; FALSE - A processor was not dispatched. no other processors exists.
+;
+;--
+
+pLoaderBlock equ dword ptr [ebp+8] ; zero based
+pProcessorState equ dword ptr [ebp+12]
+
+;
+; Local variables
+;
+
+PxFrame equ [ebp - size PxParamBlock]
+
+
+cPublicProc _HalStartNextProcessor ,2
+ enproc 8
+
+ push ebp ; save ebp
+ mov ebp, esp ;
+
+ sub esp, size PxParamBlock ; Make room for local vars
+
+
+ push esi
+ push edi
+ push ebx
+
+ xor eax, eax
+ mov PxFrame.SPx_flag, eax
+
+ cmp _ProcessorsPresent, al ; any processors left to start
+ je snp_exit ; exit FALSE
+
+ mov esi, OFFSET FLAT:StartPx_RMStub
+ mov ecx, StartPx_RMStub_Len
+ mov edi, _MpLowStub ; Copy RMStub to low memory
+ add edi, size PxParamBlock
+ rep movsb
+
+ lea edi, PxFrame.SPx_PB
+ mov esi, pProcessorState
+ mov ecx, processorstatelength ; Copy processorstate
+ rep movsb ; to PxFrame
+
+ stdCall _HalpBuildTiledCR3, <pProcessorState>
+
+ mov PxFrame.SPx_TiledCR3, eax
+ mov PxFrame.SPx_P0EBP, ebp
+
+ mov ecx, size PxParamBlock ; copy param block
+ lea esi, PxFrame ; to low memory stub
+ mov edi, _MpLowStub
+ mov eax, edi
+ rep movsb
+
+ add eax, size PxParamBlock
+ mov ebx, OFFSET FLAT:StartPx_RMStub
+ sub eax, ebx ; (eax) = adjusted pointer
+ mov bx, word ptr [PxFrame.SPx_PB.PsContextFrame.CsSegCs]
+ mov [eax.SPrxFlatCS], bx ; patch realmode stub with
+ mov [eax.SPrxPMStub], offset _StartPx_PMStub ; valid long jump
+
+ mov ebx, _MppIDT
+ add ebx, WarmResetVector
+
+ cli
+ push dword ptr [ebx] ; Save current vector
+ push ebx ; save ptr to it
+
+ mov eax, _MpLowStubPhysicalAddress
+ mov dword ptr [ebx], eax ; copy of PxFrame is here
+
+ add eax, size PxParamBlock ; calc start execution addr
+ mov _CpuBootPkg.bpStartAddr, eax ; put in start cpu package
+@@: movzx eax, _ProcessorsPresent ; get bitmap of processors
+ bsf ecx, eax ; look for next one
+ jz snp_exitA ; jump if blew it
+ btr eax, ecx ; clear its bit
+ xchg al, _ProcessorsPresent ; save new bitmap
+ xor al, _ProcessorsPresent ; leave only one bit
+ mov _CpuBootPkg.bpDest, al ; save as destination of cmd
+
+ mov ebx, eax
+ mov eax, MPFW_FuncTable
+ push ebx
+ push offset _CpuBootPkg
+ call dword ptr [eax][fnICU_Send_Mstr * 4]
+ add esp, 8
+ ror eax, 16
+ cmp al, 1
+ jne @B ; try another cpu if error
+
+@@:
+ cmp PxFrame.SPx_flag, 0 ; wait for Px to get it's
+ jz @b ; info
+
+ mov eax, 1 ; return TRUE
+snp_exitA:
+ pop ebx ; get ptr to WarmResetVector
+ pop dword ptr [ebx] ; restore WarmResetVector
+
+ sti
+
+ push eax ; save true/false return
+ stdCall _HalpFreeTiledCR3 ; free memory used for tiled
+;; if DBG
+ %out generating stall code
+ EXTRNP _KeStallExecutionProcessor,1
+ push ecx
+ push edx
+
+ stdCall _KeStallExecutionProcessor, <75000> ; wait 75 milliseconds
+
+ pop edx
+ pop ecx
+;; endif ;DBG
+ ; CR3
+ pop eax ; restore return value
+
+snp_exit:
+ pop ebx
+ pop edi
+ pop esi
+ mov esp, ebp
+ pop ebp
+
+ exproc 8
+
+ stdRET _HalStartNextProcessor
+
+stdENDP _HalStartNextProcessor
+
+;++
+;
+; ULONG
+; icu_sync_master (
+; ULONG i_sync,
+; UCHAR i_exp_cfg,
+; ULONG i_timeout
+; );
+;
+; Routine Description:
+;
+; This routine is called by HalpInitMP during phase 0 to determine
+; if any other processors are running.
+;
+; This routine is just a stub to access the firmware roms.
+;
+; Arguments:
+;
+; i_sync specifies wether to wait or continue???
+;
+; i_exp_cfg specifies bitmap of WWB slot to try communicating with
+;
+; i_timeout specifies maximum time to wait for response
+;
+; Return Value:
+;
+; eax[0:7] remaining length of command
+;
+; eax[8:15] bitmap of WWB slots responding (running)
+;
+; eax[16:23] return code, 1=Ok, 2=timeout
+;
+; eax[24:31] reserved
+;
+;--
+public _icu_sync_master
+_icu_sync_master proc
+ mov eax, MPFW_FuncTable
+ jmp dword ptr [eax][fnICU_Sync_Mstr * 4]
+_icu_sync_master endp
+;_TEXT ends ; end 32 bit code
+
+
+;_TEXT16 SEGMENT DWORD PUBLIC USE16 'CODE' ; start 16 bit code
+
+ align 4
+;++
+;
+; VOID
+; StartPx_RMStub
+;
+; Routine Description:
+;
+; When a new processor is started, it starts in 32-bit protected mode
+; with paging disabled and is sent to a copy of this function which has
+; been copied into low memory. (below 1m).
+;
+; Once CR0 has been set, this function jmp's to a StartPx_PMStub
+;
+; Arguments:
+; none
+;
+; Return Value:
+; does not return, jumps to StartPx_PMStub
+;
+;--
+cPublicProc StartPx_RMStub ,0
+ cli
+
+ mov edi, WarmResetVector
+ mov edi, cs:[edi] ; point to processor block
+ ; load the GDT
+ lgdt fword ptr cs:[edi].SPx_PB.PsSpecialRegisters.SrGdtr
+
+ ; load the IDT
+ lidt fword ptr cs:[edi].SPx_PB.PsSpecialRegisters.SrIdtr
+
+ mov eax, cs:[edi].SPx_TiledCR3
+ mov cr3, eax
+
+ mov ebp, dword ptr cs:[edi].SPx_P0EBP
+ mov ecx, dword ptr cs:[edi].SPx_PB.PsContextFrame.CsSegDs
+ mov ebx, dword ptr cs:[edi].SPx_PB.PsSpecialRegisters.SrCr3
+ mov eax, dword ptr cs:[edi].SPx_PB.PsSpecialRegisters.SrCr0
+
+ mov cr0, eax ; into prot mode
+
+ db 0eah ; reload cs:eip
+SPrxPMStub dd 0
+SPrxFlatCS dw 0
+
+StartPx_RMStub_Len equ $ - StartPx_RMStub
+stdENDP StartPx_RMStub
+
+
+;_TEXT16 ends ; End 16 bit code
+
+;_TEXT SEGMENT ; Start 32 bit code
+
+
+;++
+;
+; VOID
+; StartPx_PMStub
+;
+; Routine Description:
+;
+; This function completes the processor's state loading, and signals
+; the requesting processor that the state has been loaded.
+;
+; Arguments:
+; ebx - requested CR3 for this processors_state
+; cx - requested ds for this processors_state
+; ebp - EBP of P0
+;
+; Return Value:
+; does not return - completes the loading of the processors_state
+;
+;--
+ align 16 ; to make sure we don't cross a page boundry
+ ; before reloading CR3
+
+cPublicProc _StartPx_PMStub ,0
+
+ ; process is now in the load image copy of this function.
+ ; (ie, it's not the low memory copy)
+
+ mov cr3, ebx ; get real CR3
+ mov ds, cx ; set real ds
+
+ lea esi, PxFrame.SPx_PB.PsSpecialRegisters
+
+ lldt word ptr ds:[esi].SrLdtr ; load ldtr
+ ltr word ptr ds:[esi].SrTr ; load tss
+
+ lea edi, PxFrame.SPx_PB.PsContextFrame
+ mov es, word ptr ds:[edi].CsSegEs ; Set other selectors
+ mov fs, word ptr ds:[edi].CsSegFs
+ mov gs, word ptr ds:[edi].CsSegGs
+ mov ss, word ptr ds:[edi].CsSegSs
+
+ add esi, SrKernelDr0
+ .errnz (SrKernelDr1 - SrKernelDr0 - 1 * 4)
+ .errnz (SrKernelDr2 - SrKernelDr0 - 2 * 4)
+ .errnz (SrKernelDr3 - SrKernelDr0 - 3 * 4)
+ .errnz (SrKernelDr6 - SrKernelDr0 - 4 * 4)
+ .errnz (SrKernelDr7 - SrKernelDr0 - 5 * 4)
+ lodsd
+ mov dr0, eax ; load dr0-dr7
+ lodsd
+ mov dr1, eax
+ lodsd
+ mov dr2, eax
+ lodsd
+ mov dr3, eax
+ lodsd
+ mov dr6, eax
+ lodsd
+ mov dr7, eax
+
+ mov esp, dword ptr ds:[edi].CsEsp
+ mov esi, dword ptr ds:[edi].CsEsi
+ mov ecx, dword ptr ds:[edi].CsEcx
+
+ push dword ptr ds:[edi].CsEflags
+ popfd ; load eflags
+
+ push dword ptr ds:[edi].CsEip ; make a copy of remaining
+ push dword ptr ds:[edi].CsEax ; registers which need
+ push dword ptr ds:[edi].CsEbx ; loaded
+ push dword ptr ds:[edi].CsEdx
+ push dword ptr ds:[edi].CsEdi
+ push dword ptr ds:[edi].CsEbp
+
+ ; eax, ebx, edx are still free
+
+ inc [PxFrame.SPx_flag] ; Signal p0 that we are
+ ; done with it's data
+ ; Set remaining registers
+ pop ebp
+ pop edi
+ pop edx
+ pop ebx
+ pop eax
+ exproc 0
+ stdRET _StartPx_PMStub ; Set eip
+
+stdENDP _StartPx_PMStub
+
+_TEXT ends ; end 32 bit code
+ end
diff --git a/private/ntos/nthals/halwyse7/i386/wyswint.asm b/private/ntos/nthals/halwyse7/i386/wyswint.asm
new file mode 100644
index 000000000..2e0fd4201
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wyswint.asm
@@ -0,0 +1,336 @@
+ title "Software Interrupts"
+
+;++
+;
+; Copyright (c) 1992-1993 Microsoft Corporation
+; Copyright (c) 1993 Wyse Technology
+;
+; Module Name:
+;
+; wyswint.asm
+;
+; Abstract:
+;
+; This module implements the software interrupt handlers
+; for x86 machines
+;
+; Author:
+;
+; John Vert (jvert) 2-Jan-1992
+;
+; Environment:
+;
+; Kernel mode only.
+;
+; Revision History:
+; John Fuller (o-johnf) 31-Aug-1993 mods to support Wyse Lazy IRQLs
+;
+;--
+
+.386p
+ .xlist
+include hal386.inc
+include callconv.inc ; calling convention macros
+include i386\ix8259.inc
+include i386\kimacro.inc
+include i386\wy7000mp.inc
+ .list
+
+ EXTRNP _KiDeliverApc,3,IMPORT
+ EXTRNP _KiDispatchInterrupt,0,IMPORT
+ EXTRNP Kei386EoiHelper,0,IMPORT
+ EXTRNP _HalEndSystemInterrupt,2
+ extrn SWInterruptHandlerTable:dword
+ extrn SWInterruptLookUpTable:byte
+ifdef IRQL_METRICS
+ extrn HalApcSoftwareIntCount:dword
+ extrn HalDpcSoftwareIntCount:dword
+endif
+
+_TEXT$02 SEGMENT DWORD PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:FLAT, FS:NOTHING, GS:NOTHING
+
+ page ,132
+ subttl "Request Software Interrupt"
+
+;++
+;
+; VOID
+; FASTCALL
+; HalRequestSoftwareInterrupt (
+; IN KIRQL RequestIrql
+; )
+;
+; Routine Description:
+;
+; This routine is used to request a software interrupt to the
+; system. Also, this routine checks to see if any software
+; interrupt should be generated.
+; The following condition will cause software interrupt to
+; be simulated:
+; any software interrupt which has higher priority than
+; current IRQL's is pending.
+;
+; NOTE: This routine simulates software interrupt as long as
+; any pending SW interrupt level is higher than the current
+; IRQL, even when interrupts are disabled.
+;
+; ASSUMPTIONS:
+; 1. This routine is only called for IRQL's 1-4.
+; 2. No bits above bit 4 can be set in PcIRR.
+; 3. All hardware interrups are above IRQL 4.
+;
+; Arguments:
+;
+; (cl) = RequestIrql - Supplies the request IRQL value
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+cPublicFastCall HalRequestSoftwareInterrupt ,1
+cPublicFpo 0, 1
+
+ mov eax,1
+ shl eax, cl ; convert to mask
+ pushfd ; save interrupt mode
+ cli ; disable interrupt
+ or PCR[PcIRR], eax ; set the request bit
+
+ mov eax, PCR[PcIRR] ; get SW interrupt request register
+ and eax, 3 ; mask off pending HW interrupts
+ jz short KsiExit ; exit is none for now
+ mov al, SWInterruptLookUpTable[eax] ; get the highest pending
+ ; software interrupt level
+ cmp al, PCR[PcIrql] ; Is highest SW int level > irql?
+ jbe KsiExit ; No, jmp ksiexit
+ call SWInterruptHandlerTable[eax*4] ; yes, simulate interrupt
+ ; to the appropriate handler
+@@: popfd ; restore original interrupt mode
+ fstRET HalRequestSoftwareInterrupt
+
+KsiExit:
+ cmp cl, PCR[PcHal.pchHwIrql]; compare with Hardware Irql
+ jbe @B ; jump if hardware already above us
+ mov PCR[PcHal.pchHwIrql], cl; ensure KeLowerIrql checks PcIRR
+ popfd ; restore original interrupt mode
+ fstRET HalRequestSoftwareInterrupt
+
+fstENDP HalRequestSoftwareInterrupt
+
+ page ,132
+ subttl "Clear Software Interrupt"
+
+;++
+;
+; VOID
+; HalClearSoftwareInterrupt (
+; IN KIRQL RequestIrql
+; )
+;
+; Routine Description:
+;
+; This routine is used to clear a possible pending software interrupt.
+; Support for this function is optional, and allows the kernel to
+; reduce the number of spurious software interrupts it receives/
+;
+; Arguments:
+;
+; (cl) = RequestIrql - Supplies the request IRQL value
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+cPublicFastCall HalClearSoftwareInterrupt ,1
+cPublicFpo 0, 0
+
+ mov eax,1
+ shl eax, cl ; convert to mask
+
+ not eax
+ and PCR[PcIRR], eax ; clear pending irr bit
+
+ fstRET HalClearSoftwareInterrupt
+fstENDP HalClearSoftwareInterrupt
+
+ page ,132
+ subttl "Dispatch Interrupt"
+;++
+;
+; VOID
+; HalpDispatchInterrupt(
+; VOID
+; );
+;
+; Routine Description:
+;
+; This routine is the interrupt handler for a software interrupt generated
+; at DISPATCH_LEVEL. Its function is to save the machine state, raise
+; Irql to DISPATCH_LEVEL, dismiss the interrupt, and call the DPC
+; delivery routine.
+;
+; Arguments:
+;
+; None
+; Interrupt is disabled
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+ ENTER_DR_ASSIST hdpi_a, hdpi_t
+
+ align dword
+ public _HalpDispatchInterrupt
+_HalpDispatchInterrupt proc
+ifdef IRQL_METRICS
+ lock inc HalDpcSoftwareIntCount
+endif
+;
+; Create IRET frame on stack
+;
+ pop eax
+ pushfd
+ push cs
+ push eax
+
+;
+; Save machine state on trap frame
+;
+
+ ENTER_INTERRUPT hdpi_a, hdpi_t
+.FPO ( FPO_LOCALS+1, 0, 0, 0, 0, FPO_TRAPFRAME )
+
+ public _HalpDispatchInterrupt2ndEntry
+_HalpDispatchInterrupt2ndEntry:
+
+; Save previous IRQL and set new priority level
+
+ push PCR[PcIrql] ; save previous IRQL
+ mov byte ptr PCR[PcIrql], DISPATCH_LEVEL; set new irql
+ btr dword ptr PCR[PcIRR], DISPATCH_LEVEL; clear the pending bit in IRR
+
+;
+; Now it is safe to enable interrupt to allow higher priority interrupt
+; to come in.
+;
+
+ sti
+
+;
+; Go do Dispatch Interrupt processing
+;
+ stdCall _KiDispatchInterrupt
+
+;
+; Do interrupt exit processing
+;
+
+ SOFT_INTERRUPT_EXIT ; will do an iret
+
+_HalpDispatchInterrupt endp
+
+ page ,132
+ subttl "APC Interrupt"
+;++
+;
+; HalpApcInterrupt(
+; VOID
+; );
+;
+; Routine Description:
+;
+; This routine is entered as the result of a software interrupt generated
+; at APC_LEVEL. Its function is to save the machine state, raise Irql to
+; APC_LEVEL, dismiss the interrupt, and call the APC delivery routine.
+;
+; Arguments:
+;
+; None
+; Interrupt is Disabled
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+ ENTER_DR_ASSIST hapc_a, hapc_t
+
+ align dword
+ public _HalpApcInterrupt
+_HalpApcInterrupt proc
+ifdef IRQL_METRICS
+ lock inc HalApcSoftwareIntCount
+endif
+;
+; Create IRET frame on stack
+;
+ pop eax
+ pushfd
+ push cs
+ push eax
+
+;
+; Save machine state in trap frame
+;
+ ENTER_INTERRUPT hapc_a, hapc_t
+.FPO ( FPO_LOCALS+1, 0, 0, 0, 0, FPO_TRAPFRAME )
+
+
+ public _HalpApcInterrupt2ndEntry
+_HalpApcInterrupt2ndEntry:
+
+;
+; Save previous IRQL and set new priority level
+;
+
+ push PCR[PcIrql] ; save previous Irql
+ mov byte ptr PCR[PcIrql], APC_LEVEL ; set new Irql
+ btr dword ptr PCR[PcIRR], APC_LEVEL ; dismiss pending APC
+;
+; Now it is safe to enable interrupt to allow higher priority interrupt
+; to come in.
+;
+
+ sti
+
+;
+; call the APC delivery routine.
+;
+
+ mov eax, [ebp]+TsSegCs ; get interrupted code's CS
+ and eax, MODE_MASK ; extract the mode
+
+ test dword ptr [ebp]+TsEFlags, EFLAGS_V86_MASK
+ jz short @f
+
+ or eax, MODE_MASK ; If v86 frame, then set user_mode
+@@:
+
+;
+; call APC deliver routine
+; Previous mode
+; Null exception frame
+; Trap frame
+
+ stdCall _KiDeliverApc, <eax, 0,ebp>
+
+;
+;
+; Do interrupt exit processing
+;
+
+ SOFT_INTERRUPT_EXIT ; will do an iret
+
+_HalpApcInterrupt endp
+
+_TEXT$02 ends
+ end
diff --git a/private/ntos/nthals/halwyse7/i386/wysysint.asm b/private/ntos/nthals/halwyse7/i386/wysysint.asm
new file mode 100644
index 000000000..ebd2feaec
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/wysysint.asm
@@ -0,0 +1,615 @@
+;++
+;
+;Copyright (c) 1991-1993 Microsoft Corporation
+;Copyright (c) 1992, 1993 Wyse Technology
+;
+;Module Name:
+;
+; wysysint.asm
+;
+;Abstract:
+;
+; This module implements the HAL routines to enable/disable system
+; interrupts, for the MP Wyse7000i implementation
+;
+;Author:
+;
+; John Vert (jvert) 22-Jul-1991
+;
+;Environment:
+;
+; Kernel Mode
+;
+;Revision History:
+;
+;--
+
+
+.386p
+ .xlist
+include hal386.inc
+include callconv.inc ; calling convention macros
+include i386\ix8259.inc
+include i386\kimacro.inc
+include mac386.inc
+include i386\wy7000mp.inc
+ .list
+
+ EXTRNP _KeBugCheck,1,IMPORT
+ extrn WriteMyCpuReg:NEAR
+ EXTRNP _KeLowerIrql,1
+ extrn _HalpVectorToIRQL:BYTE
+ extrn _HalpIRQLtoVector:BYTE
+ extrn _HalpIRQLtoCPL:BYTE
+ extrn _HalpLocalInts:DWORD
+
+;
+; Constants used to initialize CMOS/Real Time Clock
+;
+
+CMOS_CONTROL_PORT EQU 70h ; command port for cmos
+CMOS_DATA_PORT EQU 71h ; cmos data port
+
+;
+; Macros to Read/Write/Reset CMOS to initialize RTC
+;
+
+; CMOS_READ
+;
+; Description: This macro read a byte from the CMOS register specified
+; in (AL).
+;
+; Parameter: (AL) = address/register to read
+; Return: (AL) = data
+;
+; NOTE: IODelay's are not needed on EISA machines.
+
+CMOS_READ MACRO
+ OUT CMOS_CONTROL_PORT,al ; ADDRESS LOCATION AND DISABLE NMI
+; IODelay ; I/O DELAY
+ IN AL,CMOS_DATA_PORT ; READ IN REQUESTED CMOS DATA
+; IODelay ; I/O DELAY
+ENDM
+
+_DATA SEGMENT DWORD PUBLIC 'DATA'
+
+align dword
+
+ public _HalpICUlock ;spinlock for rebroadcasting timer & global IPI's
+_HalpICUlock dd 0
+ public _Halp8259Lock ;spinlock for accessing 8259 mask registers
+_Halp8259Lock dd 0
+ public _i8259_IMR ;global 8259 interrupt mask
+_i8259_IMR dd not (1 shl PIC_SLAVE_IRQ)
+ public _i8259_ISR ;global 8259 interrupts in services
+_i8259_ISR dd 0
+ public _Halp8259Counts ;count of cpu's attached to each 8259 interrupt
+_Halp8259Counts db 16 dup(0)
+
+;
+; HalDismissSystemInterrupt does an indirect jump through this table so it
+; can quickly execute specific code for different interrupts.
+;
+ public HalpSpecialDismissTable
+HalpSpecialDismissTable label dword
+ dd offset FLAT:HalpDismissNormal ; irq 0
+ dd offset FLAT:HalpDismissNormal ; irq 1
+ dd offset FLAT:HalpDismissSpurious ; irq 2
+ dd offset FLAT:HalpDismissNormal ; irq 3
+ dd offset FLAT:HalpDismissNormal ; irq 4
+ dd offset FLAT:HalpDismissNormal ; irq 5
+ dd offset FLAT:HalpDismissNormal ; irq 6
+ dd offset FLAT:HalpDismissIrq07 ; irq 7
+ dd offset FLAT:HalpDismissNormal ; irq 8
+ dd offset FLAT:HalpDismissNormal ; irq 9
+ dd offset FLAT:HalpDismissNormal ; irq A
+ dd offset FLAT:HalpDismissNormal ; irq B
+ dd offset FLAT:HalpDismissNormal ; irq C
+ dd offset FLAT:HalpDismissNormal ; irq D
+ dd offset FLAT:HalpDismissNormal ; irq E
+ dd offset FLAT:HalpDismissIrq0f ; irq F
+ dd offset FLAT:HalpDismissSpurious ; irq 10
+ dd offset FLAT:HalpDismissIPIlevel ; irq 11
+ dd offset FLAT:HalpDismissIPIlevel ; irq 12
+ dd offset FLAT:HalpDismissIPIlevel ; irq 13
+ dd offset FLAT:HalpDismissIPIlevel ; irq 14
+ dd offset FLAT:HalpDismissIPIlevel ; irq 15
+ dd offset FLAT:HalpDismissIPIlevel ; irq 16
+ dd offset FLAT:HalpDismissIPIlevel ; irq 17
+ dd offset FLAT:HalpDismissSpurious ; irq 18
+ dd offset FLAT:HalpDismissSpurious ; irq 19
+ dd offset FLAT:HalpDismissSpurious ; irq 1A
+ dd offset FLAT:HalpDismissSpurious ; irq 1B
+ dd offset FLAT:HalpDismissSpurious ; irq 1C
+ dd offset FLAT:HalpDismissSpurious ; irq 1D
+ dd offset FLAT:HalpDismissSpurious ; irq 1E
+ dd offset FLAT:HalpDismissSpurious ; irq 1F
+ dd offset FLAT:HalpDismissSpurious ; irq 20
+ dd offset FLAT:HalpDismissSpurious ; irq 21
+ dd offset FLAT:HalpDismissSpurious ; irq 22
+ dd offset FLAT:HalpDismissSpurious ; irq 23
+
+_DATA ENDS
+
+_TEXT SEGMENT DWORD PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
+
+
+;++
+;BOOLEAN
+;HalBeginSystemInterrupt(
+; IN KIRQL Irql
+; IN CCHAR Vector,
+; OUT PKIRQL OldIrql
+; )
+;
+;
+;
+;Routine Description:
+;
+; This routine is used to dismiss the specified vector number. It is called
+; before any interrupt service routine code is executed.
+;
+; N.B. This routine does NOT preserve EAX or EBX
+;
+;Arguments:
+;
+; Irql - Supplies the IRQL to raise to
+;
+; Vector - Supplies the vector of the interrupt to be dismissed
+;
+; OldIrql- Location to return OldIrql
+;
+;
+;Return Value:
+;
+; FALSE - Interrupt is spurious and should be ignored
+;
+; TRUE - Interrupt successfully dismissed and Irql raised.
+;
+;--
+align dword
+HbsiIrql equ byte ptr [esp+4+8]
+HbsiVector equ byte ptr [esp+8+8]
+HbsiOldIrql equ dword ptr [esp+12+8]
+
+cPublicProc _HalBeginSystemInterrupt ,3
+ push ecx
+ push edx
+ mov ebx, (-PRIMARY_VECTOR_BASE) and 0FFh
+ add bl, HbsiVector ; (ebx) = 8259 IRQ #
+if DBG
+ cmp ebx, 23h
+ jbe hbsi00
+ int 3
+hbsi00:
+
+endif
+ xor ecx, ecx
+ mov cl, _HalpVectorToIRQL[ebx] ; get h/w Irql of interrupt
+ cmp cl, Fs:PcIrql ; int after raise Irql?
+ jbe short HalpIntBelowIRQL ; jump if it is
+ jmp HalpSpecialDismissTable[ebx*4]
+
+HalpIntBelowIRQL:
+ xor eax, eax
+ mov al, Fs:PcIrql
+ mov dx, My+CpuPriortyLevel
+ mov Fs:PcHal.pchHwIrql, al
+ mov al, _HalpIRQLtoCPL[eax]
+ out dx, ax
+ bt _HalpLocalInts, ecx ; EISA or Local interrupt?
+ jnc short HalpRebroadcastEISAint ; jump if EISA interrupt
+
+ cmp cl, IPI_LEVEL ; IPI's are easy
+ jne HalpEmulateClockOrGlobal ; jmp if not an IPI
+
+ mov cl, byte ptr fs:PcHal.pchPrSlot ; IPIs get resent to
+ or cl, ICU_IPI_SLOT ; the current processor
+ jmp short HalpRebroadcastIPI
+
+HalpRebroadcastEISAint:
+ mov cl, _HalpIRQLtoCPL[ecx] ; get hw interrupt level
+ add cl, ICU_XMT_INT_SND ; make ICU command
+HalpRebroadcastIPI:
+ mov dx, My+CpuIntCmd ; point to ICU command register
+@@: in ax, dx
+ test eax, ICU_CMD_BUSY
+ jnz short @B ; wait for ICU not busy
+ xchg eax, ecx ; get ICU command
+ out dx, ax ; rebroadcast EISA interrupt
+ jmp HalpDismissSpurious ; clear ICU in service bit
+
+HalpEmulateClockOrGlobal:
+; The following code resends a clock or global interrupt by mapping the
+; appropriate ICU_LIPTR value to zero and then broadcasting the level.
+; This must be spinlocked since it will not work it two CPUs try it at
+; the same time.
+
+ cmp cl, CLOCK2_LEVEL ; is this CLOCK or GLOBAL?
+ mov cl, _HalpIRQLtoCPL[ecx] ; (get this int's level #)
+ mov ax, not lipTimer ; (assume timer interrupt)
+ je short @F ; jump if timer interrupt
+ mov ax, not (lipGlobal+lipSerial) ; it is global interrupt
+@@: and ax, fs:word ptr PcHal.pchCurLiptr
+ push eax ; save temp LIPTR
+
+ lea eax, _HalpICUlock ; Serialize access to
+Hec10: ACQUIRE_SPINLOCK eax, HecSpin ; remappings
+
+ push ICU_LIPTR ; Point global interrupt to
+ call WriteMyCpuReg ; make it a clock interrupt
+
+ mov dx, My+CpuIntCmd ; wait for ICU not busy
+@@: in ax, dx
+ test eax, ICU_CMD_BUSY
+ jnz short @B
+
+ xchg eax, ecx ; get int level back
+ add al, ICU_XMT_INT_SND ; make send level command
+ out dx, ax ; to make to clock interrupt
+
+@@: in ax, dx ; wait for ICU not busy
+ test eax, ICU_CMD_BUSY ; before resetting GlobalIpi
+ jnz short @B ; value
+
+ push fs:PcHal.pchCurLiptr
+ push ICU_LIPTR ; Put GlobalIpi back to
+ call WriteMyCpuReg ; normal setting
+
+ lea eax, _HalpICUlock
+ RELEASE_SPINLOCK eax
+
+ jmp HalpDismissSpurious
+
+HecSpin:
+ SPIN_ON_SPINLOCK eax, Hec10
+
+
+HalpDismissSpinF:
+ SPIN_ON_SPINLOCK eax, Hbsi10
+
+ align dword
+HalpDismissIrq0f:
+;
+; Check to see if this is a spurious interrupt
+;
+ lea eax, _Halp8259Lock
+Hbsi10: ACQUIRE_SPINLOCK eax, HalpDismissSpinF
+ mov al, OCW3_READ_ISR ; tell 8259 we want to read ISR
+ out PIC2_PORT0, al
+; IODelay ; delay
+ in al, PIC2_PORT0 ; (al) = content of PIC 1 ISR
+ test al, 10000000B ; Is In-Service register set?
+ jnz HalpDismissNormal2 ; No, this is NOT a spurious int,
+ ; go do the normal interrupt stuff
+
+;
+; This is a spurious interrupt.
+; Because the slave PIC is cascaded to irq2 of master PIC, we need to
+; dismiss the interupt on master PIC's irq2.
+;
+
+ mov al, PIC2_EOI ; Specific eoi to master for pic2 eoi
+ out PIC1_PORT0, al ; send irq2 specific eoi to master
+
+ lea eax, _Halp8259Lock
+ RELEASE_SPINLOCK eax
+
+HalpDismissSpurious:
+ mov dx, My+CpuIntCmd
+@@: in ax, dx
+ test eax, ICU_CMD_BUSY
+ jnz @B
+ mov al, ICU_CLR_INSERV1
+ out dx, ax
+ xor eax, eax ; return FALSE
+; sti
+ pop edx
+ pop ecx
+ stdRET _HalBeginSystemInterrupt
+
+HalpDismissSpin:
+ SPIN_ON_SPINLOCK eax, HalpDismissNormal
+
+HalpDismissSpin7:
+ SPIN_ON_SPINLOCK eax, Hbsi20
+
+ align dword
+HalpDismissIrq07:
+;
+; Check to see if this is a spurious interrupt
+;
+ lea eax, _Halp8259Lock
+Hbsi20: ACQUIRE_SPINLOCK eax, HalpDismissSpin7
+ mov al, OCW3_READ_ISR ; tell 8259 we want to read ISR
+ out PIC1_PORT0, al
+; IODelay ; delay
+ in al, PIC1_PORT0 ; (al) = content of PIC 1 ISR
+ test al, 10000000B ; Is In-Service register set?
+ jnz short HalpDismissNormal2 ; No, so this is a spurious int
+
+ lea eax, _Halp8259Lock
+ RELEASE_SPINLOCK eax
+ jmp HalpDismissSpurious
+
+ align dword
+HalpDismissNormal:
+ lea eax, _Halp8259Lock
+ ACQUIRE_SPINLOCK eax, HalpDismissSpin
+
+ align dword
+HalpDismissNormal2:
+ mov eax, _i8259_IMR ;get current 8259 masks
+ bts _i8259_ISR, ebx ;mark this int as in service
+ or eax, _i8259_ISR ;also mask in service ints
+ SET_8259_MASK ;tell 8259's the news
+ lea eax, _Halp8259Lock
+ RELEASE_SPINLOCK eax
+
+;
+; Dismiss interrupt. Current interrupt is already masked off.
+;
+ mov eax, ebx ; (eax) = IRQ #
+ cmp eax, 8 ; EOI to master or slave?
+
+ jae short Hbsi100 ; EIO to both master and slave
+ or al, PIC1_EOI_MASK ; create specific eoi mask for master
+ out PIC1_PORT0, al ; dismiss the interrupt
+ jmp short Hbsi200 ; IO delay
+
+Hbsi100:
+ mov al, OCW2_NON_SPECIFIC_EOI ; send non specific eoi to slave
+ out PIC2_PORT0, al
+ mov al, PIC2_EOI ; specific eoi to master for pic2 eoi
+ out PIC1_PORT0, al ; send irq2 specific eoi to master
+Hbsi200:
+ PIC1DELAY
+
+HalpDismissIPIlevel:
+
+ mov bl, HbsiIrql
+ mov dx, My+CpuPriortyLevel
+ mov al, _HalpIRQLtoCPL[ebx]
+ mov cl, Fs:PcIrql ; (cl) = Old Irql
+ out dx, ax
+ mov Fs:PcIrql, bl ; set new irql
+ mov edx, HbsiOldIrql ; get addr to store old irql
+ mov Fs:PcHal.pchHwIrql, bl
+ mov [edx], cl ; save old irql in the return variable
+
+ifdef IRQL_METRICS
+ lock inc HalRaiseIrqlCount
+endif
+
+ mov dx, My+CpuIntCmd
+@@: in ax, dx
+ test eax, ICU_CMD_BUSY
+ jnz @B
+ mov al, ICU_CLR_INSERV1 ; clear this processor's in service bit
+ out dx, ax
+
+ sti
+ mov eax, 1 ; return TRUE, interrupt dismissed
+ pop edx
+ pop ecx
+ stdRET _HalBeginSystemInterrupt
+stdENDP _HalBeginSystemInterrupt
+
+;++
+;BOOLEAN
+;HalEndSystemInterrupt(
+; IN KIRQL Irql
+; IN CCHAR Vector,
+; )
+;
+;
+;
+;Routine Description:
+;
+; This routine is used to complete any interrupt h/w processing and to
+; lower the IRQL to the original value.
+;
+;Arguments:
+;
+; Irql - Supplies the IRQL to raise to
+;
+; Vector - Supplies the vector of the interrupt to be dismissed
+;
+;
+;Return Value:
+;
+; FALSE - Interrupt is spurious and should be ignored
+;
+; TRUE - Interrupt successfully dismissed and Irql raised.
+;
+;--
+align dword
+
+cPublicProc _HalEndSystemInterrupt ,2
+ movzx ecx, byte ptr [esp+8]
+
+ ; change stack to be for KeLowerIrql
+ pop eax ;(eax) = ret addr
+ mov edx, [esp] ;(edx) = new irql
+ mov [esp], eax
+ mov [esp+4], edx
+
+ sub cl, PRIMARY_VECTOR_BASE
+ cmp cl, 16
+ jnb _KeLowerIrql@4 ;jump if not 8259 interrupt
+ pushfd
+ lea eax, _Halp8259Lock
+HesiAquireLock:
+ cli
+ ACQUIRE_SPINLOCK eax, HesiSpin
+ mov eax, _i8259_IMR
+ btr _i8259_ISR, ecx
+ or eax, _i8259_ISR
+ SET_8259_MASK
+ lea eax, _Halp8259Lock
+ RELEASE_SPINLOCK eax
+ popfd
+ jmp _KeLowerIrql@4
+
+HesiSpin:
+ popfd
+ pushfd
+ SPIN_ON_SPINLOCK eax, HesiAquireLock
+stdENDP _HalEndSystemInterrupt
+
+;++
+;VOID
+;HalDisableSystemInterrupt(
+; IN CCHAR Vector,
+; IN KIRQL Irql
+; )
+;
+;
+;
+;Routine Description:
+;
+; Disables a system interrupt.
+;
+;Arguments:
+;
+; Vector - Supplies the vector of the interrupt to be disabled
+;
+; Irql - Supplies the interrupt level of the interrupt to be disabled
+;
+;Return Value:
+;
+; None.
+;
+;--
+cPublicProc _HalDisableSystemInterrupt ,2
+ enproc 9
+;
+
+ push ebx
+ movzx ebx, byte ptr [esp+12] ;get IRQL
+ movzx ecx, _HalpIRQLtoVector[ebx]
+ or ecx, ecx
+ jz DisSysIntExit ;jump if not H/W interrupt
+ sub cl, PRIMARY_VECTOR_BASE
+ movzx eax, _HalpIRQLtoCPL[ebx]
+ cli
+ bts fs:PcIDR, eax ;disable int locally
+ jc DisSysIntExit ;jump if already disabled
+ push fs:PcIDR
+ push ICU_IMR0 ;write low interrupt masks
+ call WriteMyCpuReg
+ shr eax, 16
+ out dx, ax ;shortcut to high interrupt masks
+ cmp cl, 16 ;is this an 8259 interrupt?
+ jnb DisSysIntExit ;jump if not
+ lea eax, _Halp8259Lock
+DisSysIntAquire:
+ ACQUIRE_SPINLOCK eax, DisSysIntSpin
+ dec _Halp8259Counts[ecx]
+ jnz short DisSysIntRelease
+ mov eax, _i8259_ISR
+ bts _i8259_IMR, ecx
+ or eax, _i8259_IMR
+ SET_8259_MASK
+
+ lea eax, _Halp8259Lock
+DisSysIntRelease:
+ RELEASE_SPINLOCK eax
+
+DisSysIntExit:
+ exproc 9
+ sti
+ pop ebx
+ stdRET _HalDisableSystemInterrupt
+
+DisSysIntSpin:
+ SPIN_ON_SPINLOCK eax, DisSysIntAquire
+
+stdENDP _HalDisableSystemInterrupt
+
+;++
+;
+;BOOLEAN
+;HalEnableSystemInterrupt(
+; IN ULONG Vector,
+; IN KIRQL Irql,
+; IN KINTERRUPT_MODE InterruptMode
+; )
+;
+;
+;Routine Description:
+;
+; Enables a system interrupt
+;
+;Arguments:
+;
+; Vector - Supplies the vector of the interrupt to be enabled
+;
+; Irql - Supplies the interrupt level of the interrupt to be enabled.
+;
+;Return Value:
+;
+; None.
+;
+;--
+cPublicProc _HalEnableSystemInterrupt ,3
+ enproc 0Ah
+
+ push ebx
+ movzx ebx, byte ptr [esp+12] ;get IRQL
+ movzx ecx, _HalpIRQLtoVector[ebx]
+ or ecx, ecx
+ jz EnbSysIntError ;jump if not H/W interrupt
+ sub cl, PRIMARY_VECTOR_BASE
+ movzx eax, _HalpIRQLtoCPL[ebx]
+ cli
+ btr fs:PcIDR, eax ;enable int locally
+ jnc EnbSysIntExit ;jump if already enabled
+ push fs:PcIDR
+ push ICU_IMR0
+ call WriteMyCpuReg ;write low interrupt masks
+ shr eax, 16
+ out dx, ax ;shortcut to high interrupt masks
+ cmp cl, 16 ;is this an 8259 interrupt?
+ jnb EnbSysIntExit ;jump if not
+ lea eax, _Halp8259Lock
+EnbSysIntAquire:
+ ACQUIRE_SPINLOCK eax, EnbSysIntSpin
+ inc _Halp8259Counts[ecx]
+ cmp _Halp8259Counts[ecx], 1
+ jnz short EnbSysIntRelease
+ mov eax, _i8259_ISR
+ btr _i8259_IMR, ecx
+ or eax, _i8259_IMR
+ SET_8259_MASK
+
+ lea eax, _Halp8259Lock
+EnbSysIntRelease:
+ RELEASE_SPINLOCK eax
+
+EnbSysIntExit:
+ exproc 0Ah
+ sti
+ pop ebx
+ mov eax, 1
+ stdRET _HalEnableSystemInterrupt
+
+EnbSysIntError:
+ if DBG
+ int 3
+ endif
+ exproc 0Ah
+ sti
+ pop ebx
+ xor eax,eax
+ stdRET _HalEnableSystemInterrupt
+
+EnbSysIntSpin:
+ SPIN_ON_SPINLOCK eax, EnbSysIntAquire
+
+stdENDP _HalEnableSystemInterrupt
+
+
+_TEXT ENDS
+ END
diff --git a/private/ntos/nthals/halwyse7/i386/xxbiosa.asm b/private/ntos/nthals/halwyse7/i386/xxbiosa.asm
new file mode 100644
index 000000000..bc0173a17
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxbiosa.asm
@@ -0,0 +1,5 @@
+;
+; Include code from halx86
+; This is a cpp style symbolic link
+
+include ..\halx86\i386\xxbiosa.asm
diff --git a/private/ntos/nthals/halwyse7/i386/xxbiosc.c b/private/ntos/nthals/halwyse7/i386/xxbiosc.c
new file mode 100644
index 000000000..60cf92748
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxbiosc.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\xxbiosc.c"
diff --git a/private/ntos/nthals/halwyse7/i386/xxdisp.c b/private/ntos/nthals/halwyse7/i386/xxdisp.c
new file mode 100644
index 000000000..d48977df0
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxdisp.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\xxdisp.c"
diff --git a/private/ntos/nthals/halwyse7/i386/xxflshbf.c b/private/ntos/nthals/halwyse7/i386/xxflshbf.c
new file mode 100644
index 000000000..b054121cf
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxflshbf.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\xxflshbf.c"
diff --git a/private/ntos/nthals/halwyse7/i386/xxioacc.asm b/private/ntos/nthals/halwyse7/i386/xxioacc.asm
new file mode 100644
index 000000000..8445c3404
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxioacc.asm
@@ -0,0 +1,5 @@
+;
+; Include code from halx86
+; This is a cpp style symbolic link
+
+include ..\halx86\i386\xxioacc.asm
diff --git a/private/ntos/nthals/halwyse7/i386/xxkdsup.c b/private/ntos/nthals/halwyse7/i386/xxkdsup.c
new file mode 100644
index 000000000..6e569b5ac
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxkdsup.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\xxkdsup.c"
diff --git a/private/ntos/nthals/halwyse7/i386/xxmemory.c b/private/ntos/nthals/halwyse7/i386/xxmemory.c
new file mode 100644
index 000000000..920714540
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxmemory.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\xxmemory.c"
diff --git a/private/ntos/nthals/halwyse7/i386/xxstubs.c b/private/ntos/nthals/halwyse7/i386/xxstubs.c
new file mode 100644
index 000000000..8421fb30a
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxstubs.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\xxstubs.c"
diff --git a/private/ntos/nthals/halwyse7/i386/xxtime.c b/private/ntos/nthals/halwyse7/i386/xxtime.c
new file mode 100644
index 000000000..92abb2aeb
--- /dev/null
+++ b/private/ntos/nthals/halwyse7/i386/xxtime.c
@@ -0,0 +1,5 @@
+//
+// Include code from halx86
+// This is a cpp style symbolic link
+
+#include "..\halx86\i386\xxtime.c"