summaryrefslogblamecommitdiffstats
path: root/private/ntos/nthals/halcbus/i386/cbusmisc.asm
blob: 4223fcf3c08d609efe6e9d78b49f85452221e8f5 (plain) (tree)
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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406





















































































































































































































































































































































































































                                                                               

	title "miscellaneous MP primitives for the Corollary MP machines"
;++
;
;Copyright (c) 1992, 1993, 1994  Corollary Inc
;
;Module Name:
;
;    cbusmisc.asm
;
;Abstract:
;
;   This module contains miscellaneous MP primitives for the
;   Corollary MP machines.
;
;Author:
;
;   Landy Wang (landy@corollary.com) 26-Mar-1992
;
;Revision History:
;
;--



.386p
        .xlist
include hal386.inc
include callconv.inc                    ; calling convention macros
include i386\kimacro.inc
include cbus.inc

;
; enable the Pentium internal cache to its full capability
;
CR0_INTERNAL_ON	equ	(not (CR0_NW or CR0_CD))
CR0_INTERNAL_OFF equ	(CR0_NW or CR0_CD)

        .list

INIT 	SEGMENT DWORD PUBLIC 'CODE'	; Start 32 bit code
        ASSUME  DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING

;++
;
; VOID
; i486cacheon
;
; Routine Description:
;
;   This function enables the calling processor's internal cache.
;   Executed by each processor (via HalInitializeProcessor) in the
;   Corollary Cbus1 and Cbus2 architectures.
;
;   Note: This must be run before HalpInitializeStallExecution().
;
; Return Value:
;   none.
;
;--

cPublicProc _i486cacheon   ,0

	pushfd
	cli

	; Enable the 486 processor internal cache if it wasn't already.

	mov	eax, cr0			; get real cr0
	test	eax, CR0_INTERNAL_OFF           ; see if CPU cache on already
        jz      short @f                        ; no op if it is

	; hard code the WBINVD instruction to flush internal cache.
	; this would cause an opcode trap on 386, but we will ship
	; only 486 (Cbus1) and Pentium (Cbus2).

	db	00fh                            ; ESCAPE
        db	009h                            ; write-back invalidate

	and	eax, CR0_INTERNAL_ON            ; enable CPU internal cache
	jmp	@f				; flush queues
@@:
	mov	cr0, eax			; put cr0 back
	popfd

        stdRET    _i486cacheon
stdENDP _i486cacheon

;++
;
; VOID
; i486cacheoff
;
; Routine Description:
;
;   This function disables the calling processor's internal cache.
;   Executed by each processor (via HalInitializeProcessor) in the
;   Corollary Cbus1 and Cbus2 architectures.
;
;   Note: This must be run before HalpInitializeStallExecution().
;
; Return Value:
;   none.
;
;--

cPublicProc _i486cacheoff  ,0

	pushfd
	cli

	; Disable the 486 processor internal cache if it wasn't already.

	mov	eax, cr0			; get real cr0
	test	eax, CR0_INTERNAL_OFF           ; see if CPU cache on already
        jnz     short @f                        ; no op if it is

	; hard code the WBINVD instruction to flush internal cache.
	; this would cause an opcode trap on 386, but we will ship
	; only 486 (Cbus1) and Pentium (Cbus2).

	db	00fh                            ; ESCAPE
        db	009h                            ; write-back invalidate

	or	eax, CR0_INTERNAL_OFF           ; disable CPU internal cache
	jmp	@f				; flush queues
@@:
	mov	cr0, eax			; put cr0 back
	popfd

        stdRET    _i486cacheoff
stdENDP _i486cacheoff

;++
;
; VOID
; CbusDefaultStall (VOID)
;
; Routine Description:
;
;    This routine initializes the calling processor's stall execution to
;    a reasonable value until we later give it a real value in HalInitSystem.
;
; Arguments:
;
;    None.
;
; Return Value:
;
;    None.
;
;--

cPublicProc _CbusDefaultStall   ,0
        mov     dword ptr PCR[PcStallScaleFactor], INITIAL_STALL_COUNT
        stdRET    _CbusDefaultStall
stdENDP _CbusDefaultStall

INIT 	ends					; end 32 bit init code

_TEXT   SEGMENT PARA PUBLIC 'CODE'
        ASSUME  DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING

        page ,132
        subttl  "KeQueryPerformanceCounter"
;++
;
; 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.
;
;--


cPublicProc _KeQueryPerformanceCounter      ,1

        jmp	dword ptr [_CbusQueryPerformanceCounter]

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 processor's counter.
;
; Arguments:
;
;     Number - Supplies a pointer to the count of the number of processors in
;     the configuration.
;
; Return Value:
;
;     None.
;--
cPublicProc _HalCalibratePerformanceCounter,1

	;
	; Calibration is already handled by the Cbus HAL for both Cbus1
	; and Cbus2.
	;

        stdRET    _HalCalibratePerformanceCounter

stdENDP _HalCalibratePerformanceCounter

        page ,132
        subttl  "CbusRebootHandler"
;++
;
; VOID
; CbusRebootHandler(
;       VOID
;       );
;
; Routine Description:
;
;    This routine is the interrupt handler for an IPI interrupt generated
;    at a priority just below that of normal IPIs.  Its function is to
;    force all additional processors to flush their internal cache and halt.
;    This puts the processors in a more conducive state for system reset.
;
;    This routine is run only by the non-boot processors.
;
;    Since this routine is entered directly via an interrupt gate, interrupt
;    protection via cli is not necessary.
;
; Arguments:
;
;    None
;
; Return Value:
;
;    None.
;
;--

        ENTER_DR_ASSIST hirs_a, hirs_t

cPublicProc _CbusRebootHandler   ,0

	;
	; Save machine state on trap frame
	;

        ENTER_INTERRUPT hirs_a, hirs_t

	; keep it simple, just issue the EOI right now.
	; no changing of taskpri/irql is needed here.
	; Thus, the EOI serves as the HalEndSystemInterrupt.

	mov     eax, _CbusRebootVector
	CBUS_EOI eax, ecx			; destroy eax & ecx

        mov     eax, dword ptr PCR[PcHal.PcrNumber]

	; the boot processor will take care of the reboot from this point on.
        ; however, ensure that our internal cache is flushed and halt.

	db	00fh                            ; ESCAPE
        db	009h                            ; write-back invalidate
	hlt

	;
	; we should never reach this point, but if we do, just return our
	; processor number (loaded above).
	;
        stdRET    _CbusRebootHandler
stdENDP _CbusRebootHandler

        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, PCR[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 @f
        int	3

	align	4
@@:	cmp     eax,0
        jnz     short @f
        int	3
@@:
endif
ALIGN 16
        jmp     kese05

ALIGN 16
kese05:
        sub     eax, 1                          ; (eax) = (eax) - 1
        jnz     short kese05

	align	4
kese10:
        stdRET    _KeStallExecutionProcessor

stdENDP _KeStallExecutionProcessor

;++
;
; ULONG
; HalSetTimeIncrement (
;     IN ULONG DesiredIncrement
;     )
;
; /*++
;
; Routine Description:
;
;       This routine initializes the system time clock to generate an
;       interrupt at every DesiredIncrement interval.
;
; Arguments:
;
;       DesiredIncrement - desired interval between every timer tick in
;                        100ns units.
;
; Return Value:
;
;       The *REAL* time increment set - this can be different from what he
;       requested due to hardware limitations.
;--

cPublicProc _HalSetTimeIncrement,1

	mov	eax, _CbusBackend		; use hardware handler
	jmp	HalSetTimeIncrement[ eax ]	; JMP to set the interval
                                                ; counter
stdENDP _HalSetTimeIncrement

_TEXT	ends					; end 32 bit code

	end