summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halsp/i386/spreboot.asm
blob: af936fee1e8a0d5662dd76d449d7f60ba1ad479c (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
        title "SystemPro reboot"
;++
;
;Copyright (c) 1991  Microsoft Corporation
;
;Module Name:
;
;    spreboot.asm
;
;Abstract:
;
;    SystemPro reboot code.
;
;Author:
;
;    Ken Reneris (kenr) 13-Jan-1992
;
;Revision History:
;
;--
.386p
        .xlist

include hal386.inc
include i386\kimacro.inc
include i386\ix8259.inc
include callconv.inc                ; calling convention macros
include i386\spmp.inc

        EXTRNP  _HalRequestIpi,1
        EXTRNP  _KeStallExecutionProcessor,1

        extrn   _SpProcessorControlPort:WORD
        extrn   _SpCpuCount:BYTE
        extrn   _SpType:BYTE
        extrn   _HalpProcessorPCR:DWORD


;
; Defines to let us diddle the CMOS clock and the keyboard
;

CMOS_CTRL   equ     70h
CMOS_DATA   equ     71h

KEYB_RESET  equ     0feh
KEYB_PORT   equ     64h


_TEXT   SEGMENT DWORD PUBLIC 'CODE'       ; Start 32 bit code
        ASSUME  DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING

;++
;
; VOID
; HalpResetAllProcessors (
;       VOID
;       );
;
;Routine Description:
;
;   Called at last phase of reboot code.
;
;   Some SystemPro clones do not reboot properly by having the keyboard
;   issue a reset.  (The bootup roms do not reset the other processors
;   properly).
;
;   To work around this, we attempt to use P0 to halt all the other
;   processors before reseting the computer.
;
;   Note: P0 may not respond to an IPI if it's stuck or in the debugger.
;   In this case we will just use the current processor to reset the
;   computer.  This will not work on every machine, but the machine
;   was in some sort of crashed state to begin with.  (it does work
;   on all compaq SystemPros).
;
;   N.B.
;
;       will not return
;
;--

cPublicProc _HalpResetAllProcessors, 0

;
; Belize SystemPros can not halt processors in the same manner; however
; simply resetting the machine via the keyboard controller works - so
; skip this code on a belize.
;
        cmp     _SpType, SMP_SYSPRO2
        je      rb20                        ; Belize, just reset

        cmp     byte ptr fs:PcHal.PcrNumber, 0      ; boot processor?
        je      HalpRebootNow                       ; Yes, reset everyone

;
; Try signal the boot processor to perform the reboot
;
        mov     ecx, offset FLAT:HalpRebootNow      ; Zap P0's IPI handler
        mov     eax, _HalpProcessorPCR[0]           ; be reboot function
        xchg    [eax].PcHal.PcrIpiType, ecx

        stdCall _HalRequestIpi,<1>                  ; Send P0 an IPI
        stdCall _KeStallExecutionProcessor,<50000>  ; Let P0 reboot us

;
; P0 didn't reboot the machine - just do it with the current processor
;

HalpRebootNow:
        xor     ecx, ecx

rb10:   cmp     cl, _SpCpuCount             ; halt each processor
        jae     short rb20


        mov     dx, _SpProcessorControlPort[ecx*2]
        in      al, dx                      ; (al) = original content of PCP
        or      al, INTDIS                  ; Disable IPI interrupt

        cmp     cl, fs:PcHal.PcrNumber      ; cl == currentprocessor?
        je      short @f                    ; don't halt ourselves
        or      al, SLEEP

        cmp     _SpType, SMP_ACER           ; On acer MP machines
        jne     short @f                    ; reset other processors
        or      al, RESET                   ; (not tested to work on other
                                            ;  other machines)
@@:     out     dx, al

        inc     ecx
        jmp     short rb10

rb20:
        xor     eax, eax

;
; Send the reset command to the keyboard controller
;

        mov     edx, KEYB_PORT
        mov     al,  KEYB_RESET
        out     dx, al

@@:     hlt
        jmp     @b

stdENDP _HalpResetAllProcessors

_TEXT   ENDS
        END