summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halcbus/i386/cbus.inc
blob: 11484238e9413ce7703798c635e71c3c12e004eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
;++
;
;   Copyright (c) 1992, 1993, 1994  Corollary Inc
;
;   Module Name:
;
;	cbus.inc
;
;   Abstract:
;
;	Corollary MP include file
;
;   Author:
;
;   Landy Wang (landy@corollary.com) 26-Mar-1992
;--



;*****************************
;
;	Corollary MP defines
;
;	this should be built from a C header file to minimize
;	the possiblity of falling out of sync.
;
;*****************************


;
; Well known virtual address of the task priority register
;

LOCALAPIC   equ     0fffe0000h
APIC        equ     ds:[LOCALAPIC]

;
; The SPURIOUS task priority varies depending on Cbus platform.
; It is set when we initialize the platform and cannot be declared
; here.  APC and DPC vectors are the same for Cbus1 and Cbus2
; so they can be inlined here.
;

APC_TASKPRI		equ	01Fh	; Hardware priority of APCs
DPC_TASKPRI		equ	02Fh	; Hardware priority of DPCs

CBUS2_LEVEL_TRIGGERED_INTERRUPT  equ     1
CBUS2_EDGE_TRIGGERED_INTERRUPT   equ     2

;
; Here is the assembly version of the CBUS_NTHAL structure declared in cbus_nt.h
;

RequestIPI			equ	000h
HalRequestSWIntr		equ	004h
HalQueryPerformanceCounter	equ	008h
HalBootCPU			equ	00ch

HalInitializePlatform		equ	010h
HalInitializeCPU		equ	014h
EnableNonDeviceInterrupt	equ	018h
EnableDeviceInterrupt		equ	01ch

DisableInterrupt		equ	020h
LinkInterrupt			equ	024h
MapVector			equ	028h
ParseRRD			equ	02ch

ResolveNMI			equ	030h
HalInitInterrupts		equ	034h
HalResetAllOtherProcessors      equ     038h
HalInitOtherBuses		equ	03ch

HalSetTimeIncrement             equ     040h
HalTranslateAddress             equ     044h

;
; The kernel leaves some space in 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
; dependent.  this order MUST match the definitions in cbus_nt.h.
;

PcrE struc
    PcrNumber 		dd	    0	    ; this CPU's logical CPU number
    PcrBit 		dd	    0	    ; this CPU's logical bit number
    PcrCSR   		dd	    0	    ; pointer to this CPU's CSR
    PcrTaskpri 		dd	    0	    ; taskpri reg ptr
    PcrBroadcast	dd	    0	    ; interrupt everyone but this CPU
    PcrAllOthers	dd	    0	    ; all other CPUs but this one
    PcrLEDOn		dd	    0	    ; pointer to this CPU's LED ON
    PcrLEDOff		dd	    0	    ; pointer to this CPU's LED OFF
    PcrTickOffset	dd	    0	    ; nsec left before calling
					    ; KeUpdateRunTime on CPU1 or above
PcrE ends

;
; Offsets of various registers needed for the context switch when
; a system reboot is initiated by an additional processor.
; the space for this array is declared in cbus.c - so bump it there
; if you need more...
;

REBOOT_EIP			equ	0
REBOOT_ESP			equ	4
REBOOT_EBP			equ	8
REBOOT_EBX			equ	12
REBOOT_ESI			equ	16
REBOOT_EDI			equ	20
REBOOT_EFL			equ	24
REBOOT_CR3			equ	28


;
; ack the interrupt controller (CBC or APIC).
;
; we must derive the bus number so we know which bus' interrupt
; controller to EOI for systems with multiple I/O busses.
; so translate the vector to a bus/irqline pair for the EOI...
;
; WARNING: for the APIC, this will automatically lower the
; internal priority register to the level it was prior to
; receipt of the interrupt.
;
; the caller must initialize scratchreg to the interrupting vector.
;

CBUS_EOI	macro	reg1, reg2
local fix_level
local check_cpu
local do_eoi
local no_eoi
        ;
        ; reg1 holds the vector that originally interrupted execution,
        ; now translate the vector to the correct bridge-based EOI address.
        ;
        cmp     reg1, [_Cbus2ClockVector]
        je      short check_cpu
        cmp     [_Cbus2FixLevelInterrupts], 1
        jne     short do_eoi
	;
	; first check the polarity of the interrupt (ie. level or edge)
	; to determine whether the level-triggered interrupt hardware
	; work-around need be applied.  need to ensure that no interrupts
        ; occur while we're performing the workaround for the level-triggered
        ; interrupt fix.  the fix consists of clearing and resetting the
        ; hardware interrupt map entry for this vector.  this will cause
        ; an internal latch in the CBC to be cleared.  this problem will
        ; be fixed with the PCIB, at which time, RRD will pass a bit in
        ; the configuration table which will cause this code to no longer
        ; be executed.
	;
fix_level:
        movzx   reg2, byte ptr [_Cbus2InterruptPolarity + reg1]
        cmp     reg2, CBUS2_LEVEL_TRIGGERED_INTERRUPT
        jne     short do_eoi
        mov     reg2, dword ptr [_CbusVectorToEoi+4*reg1]
	sub	reg2, [_Cbus2EoiToHwmap]
	mov	reg1, dword ptr [_CbusVectorToHwmap+4*reg1]
	pushfd
	cli
	mov	dword ptr [reg2], 0
	mov	dword ptr [reg2], reg1	                ; must _write_ EOI
	popfd
	jmp     short no_eoi
check_cpu:
        ;
        ; on C-bus II, the clock interrupt must only be EOI'd by
        ; a single CPU.  make it the boot CPU so that this code
        ; will work when only 1 CPU is present.
        ;
        cmp     dword ptr PCR[PcHal.PcrNumber], 0
        jne     short no_eoi
        cmp     [_Cbus2FixLevelInterrupts], 1
        je      short fix_level
do_eoi:
        mov     reg2, dword ptr [_CbusVectorToEoi+4*reg1]
	mov	dword ptr dword ptr [reg2], reg1	; must _write_ EOI
no_eoi:
endm

POKE_LEDS	macro   reg1, reg2
local ledset
		mov	reg1, PCR[PcPrcb]		; point at Prcb
		mov	reg2, [reg1].PbCurrentThread	; Current thread
	        cmp     reg2, [reg1].PbIdleThread	; Idle Thread
	        je      short @f
	
	        mov     reg1, PCR[PcHal.PcrLEDOn]	; get my LED ON address
		mov	dword ptr [reg1], 1		; set it
                jmp     short ledset
	
@@:
	        mov     reg1, PCR[PcHal.PcrLEDOff]	; get my LED OFF address
                mov     dword ptr [reg1], 0             ; set it
ledset:
                endm

;
; Declare all the externs that most of our MASM code will be using
;

        extrn   _CbusLocalApic:                 DWORD
	extrn	_CbusApicRedirPort:             DWORD
	extrn	_CbusIOApic:                    DWORD

        extrn   _ProfileVector:                 DWORD

	;
	; vectors used to communicate reboot and redirection table requested
        ; changes to the boot processor.  also the global interprocessor                ; interrupt vector that any processor can use to interrupt any other
        ; processor(s).
	;
	extrn   _CbusIpiVector:                 DWORD
        extrn   _CbusRebootVector:              DWORD
        extrn   _CbusRedirVector:               DWORD

        extrn   _CbusClockVector:               DWORD
	extrn   _CbusQueryPerformanceCounter:   DWORD
	extrn   _CbusVectorToIrql:              DWORD
	extrn   _CbusIrqlToVector:              DWORD
	extrn   _CbusBackend:                   DWORD
	extrn   _CbusRequestIPI:                DWORD
	extrn   _CbusRequestSoftwareInterrupt:  DWORD
	extrn   _CbusProcessorMask:             DWORD
	extrn	_CbusBootedProcessors:          DWORD
	extrn	_CbusRebootRegs:                DWORD

	extrn   _Cbus2BridgesFound:             DWORD
	extrn	_Cbus2SendIPI:                  DWORD
	extrn	_Cbus2Poke8042:                 DWORD
	extrn	_Cbus2IrqlToCbus2Addr:          DWORD
	extrn   _Cbus2FixLevelInterrupts:       DWORD
	extrn   _Cbus2CheckSpuriousClock:       DWORD
	extrn   _Cbus2EnableBroadcast:          DWORD
	extrn   _Cbus2ClockVector:              DWORD
	extrn   _Cbus2InterruptPolarity:        DWORD
	extrn	_Cbus2EoiToHwmap:               DWORD
	extrn	_CbusTimeStamp:                 DWORD
	extrn	_Cbus2TimeStamp0:               DWORD
        extrn   _CbusVectorToEoi:               DWORD
        extrn   _CbusVectorToHwmap:             DWORD
        extrn   _CbusProcessors:                DWORD

	extrn	_HalpFindFirstSetRight:         BYTE
	extrn   _Halp8254Lock:                  DWORD
	extrn   _MppIDT:                        DWORD
	extrn   _MpLowStub:                     DWORD
	extrn   _MpLowStubPhysicalAddress:      DWORD
	extrn   _MpCount:                       DWORD

;
; Declare all the functions that our MASM code will be calling
;

        EXTRNP  _DbgBreakPoint,0,IMPORT

        EXTRNP  _HalEnableSystemInterrupt, 3
        EXTRNP  _HalDisableSystemInterrupt, 2
        EXTRNP  _HalpAcquireCmosSpinLock, 0
        EXTRNP  _HalpReleaseCmosSpinLock, 0

        EXTRNP  _KeBugCheck,1,IMPORT
        EXTRNP  _KeSetTimeIncrement,2,IMPORT
        EXTRNP  _KeUpdateRunTime,1,IMPORT
        EXTRNP  _KeUpdateSystemTime,0
        EXTRNP  Kei386EoiHelper,0,IMPORT

        EXTRNP	_KiIpiServiceRoutine,2,IMPORT
        EXTRNP  _KiDeliverApc,3,IMPORT
        EXTRNP  _KiDispatchInterrupt,0,IMPORT

        EXTRNP  _ExAllocatePool,2,IMPORT

        EXTRNP  _HalpBuildTiledCR3,1
        EXTRNP  _HalpFreeTiledCR3,0
        EXTRNP	_HalpProfileInterrupt2ndEntry,0