152 lines
3.7 KiB
NASM
152 lines
3.7 KiB
NASM
|
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
|