forked from KolibriOS/kolibrios
kernel: restart, reboot and power off
git-svn-id: svn://kolibrios.org@6244 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
465434cb12
commit
50e97c60fa
@ -1,6 +1,6 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
|
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Shutdown for Menuet ;;
|
;; Shutdown for Menuet ;;
|
||||||
@ -13,11 +13,212 @@
|
|||||||
|
|
||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
use32
|
align 4
|
||||||
become_real:
|
system_shutdown: ; shut down the system
|
||||||
|
|
||||||
|
cmp byte [BOOT_VARS+0x9030], 1
|
||||||
|
jne @F
|
||||||
|
ret
|
||||||
|
@@:
|
||||||
|
call stop_all_services
|
||||||
|
|
||||||
|
yes_shutdown_param:
|
||||||
|
; Shutdown other CPUs, if initialized
|
||||||
|
cmp [ap_initialized], 0
|
||||||
|
jz .no_shutdown_cpus
|
||||||
|
mov edi, [LAPIC_BASE]
|
||||||
|
add edi, 300h
|
||||||
|
mov esi, smpt+4
|
||||||
|
mov ebx, [cpu_count]
|
||||||
|
dec ebx
|
||||||
|
.shutdown_cpus_loop:
|
||||||
|
lodsd
|
||||||
|
push esi
|
||||||
|
xor esi, esi
|
||||||
|
inc esi
|
||||||
|
shl eax, 24
|
||||||
|
mov [edi+10h], eax
|
||||||
|
; assert INIT IPI
|
||||||
|
mov dword [edi], 0C500h
|
||||||
|
call delay_ms
|
||||||
|
@@:
|
||||||
|
test dword [edi], 1000h
|
||||||
|
jnz @b
|
||||||
|
; deassert INIT IPI
|
||||||
|
mov dword [edi], 8500h
|
||||||
|
call delay_ms
|
||||||
|
@@:
|
||||||
|
test dword [edi], 1000h
|
||||||
|
jnz @b
|
||||||
|
; don't send STARTUP IPI: let other CPUs be in wait-for-startup state
|
||||||
|
pop esi
|
||||||
|
dec ebx
|
||||||
|
jnz .shutdown_cpus_loop
|
||||||
|
.no_shutdown_cpus:
|
||||||
|
|
||||||
cli
|
cli
|
||||||
lgdt [realmode_gdt-OS_BASE]
|
call IRQ_mask_all
|
||||||
|
|
||||||
|
mov eax, [OS_BASE + 0x9030]
|
||||||
|
cmp al, SYSTEM_RESTART
|
||||||
|
jne @F
|
||||||
|
|
||||||
|
; load kernel.mnt to _CLEAN_ZONE
|
||||||
|
mov ebx, kernel_file_load
|
||||||
|
pushad
|
||||||
|
call file_system_lfn
|
||||||
|
popad
|
||||||
|
@@:
|
||||||
|
mov esi, OS_BASE+restart_code_start ; move kernel re-starter to 0x5000:0
|
||||||
|
mov edi, OS_BASE+0x50000
|
||||||
|
mov ecx, (restart_code_end - restart_code_start)/4
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
call create_trampoline_pgmap
|
||||||
|
mov cr3, eax
|
||||||
|
jmp @F
|
||||||
|
org $-OS_BASE
|
||||||
|
@@:
|
||||||
|
|
||||||
|
;disable paging
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, 0x7FFFFFFF
|
||||||
|
mov cr0, eax
|
||||||
|
mov eax, cr3
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
|
cmp byte [0x9030], SYSTEM_SHUTDOWN
|
||||||
|
jne no_acpi_power_off
|
||||||
|
|
||||||
|
; system_power_off
|
||||||
|
|
||||||
|
mov ebx, [acpi_fadt_base-OS_BASE]
|
||||||
|
cmp dword [ebx], 'FACP'
|
||||||
|
jne no_acpi_power_off
|
||||||
|
mov esi, [acpi_dsdt_base-OS_BASE]
|
||||||
|
cmp dword [esi], 'DSDT'
|
||||||
|
jne no_acpi_power_off
|
||||||
|
mov eax, [esi+4] ; DSDT length
|
||||||
|
sub eax, 36+4
|
||||||
|
jbe no_acpi_power_off
|
||||||
|
add esi, 36
|
||||||
|
.scan_dsdt:
|
||||||
|
cmp dword [esi], '_S5_'
|
||||||
|
jnz .scan_dsdt_cont
|
||||||
|
cmp byte [esi+4], 12h ; DefPackage opcode
|
||||||
|
jnz .scan_dsdt_cont
|
||||||
|
mov dl, [esi+6]
|
||||||
|
cmp dl, 4 ; _S5_ package must contain 4 bytes
|
||||||
|
; ...in theory; in practice, VirtualBox has 2 bytes
|
||||||
|
ja .scan_dsdt_cont
|
||||||
|
cmp dl, 1
|
||||||
|
jb .scan_dsdt_cont
|
||||||
|
lea esi, [esi+7]
|
||||||
|
xor ecx, ecx
|
||||||
|
cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx
|
||||||
|
jz @f
|
||||||
|
cmp byte [esi], 0xA
|
||||||
|
jnz no_acpi_power_off
|
||||||
|
inc esi
|
||||||
|
mov cl, [esi]
|
||||||
|
@@:
|
||||||
|
inc esi
|
||||||
|
cmp dl, 2
|
||||||
|
jb @f
|
||||||
|
cmp byte [esi], 0
|
||||||
|
jz @f
|
||||||
|
cmp byte [esi], 0xA
|
||||||
|
jnz no_acpi_power_off
|
||||||
|
inc esi
|
||||||
|
mov ch, [esi]
|
||||||
|
@@:
|
||||||
|
jmp do_acpi_power_off
|
||||||
|
.scan_dsdt_cont:
|
||||||
|
inc esi
|
||||||
|
dec eax
|
||||||
|
jnz .scan_dsdt
|
||||||
|
jmp no_acpi_power_off
|
||||||
|
do_acpi_power_off:
|
||||||
|
mov edx, [ebx+48]
|
||||||
|
test edx, edx
|
||||||
|
jz .nosmi
|
||||||
|
mov al, [ebx+52]
|
||||||
|
out dx, al
|
||||||
|
mov edx, [ebx+64]
|
||||||
|
@@:
|
||||||
|
in ax, dx
|
||||||
|
test al, 1
|
||||||
|
jz @b
|
||||||
|
.nosmi:
|
||||||
|
and cx, 0x0707
|
||||||
|
shl cx, 2
|
||||||
|
or cx, 0x2020
|
||||||
|
mov edx, [ebx+64]
|
||||||
|
in ax, dx
|
||||||
|
and ax, 203h
|
||||||
|
or ah, cl
|
||||||
|
out dx, ax
|
||||||
|
mov edx, [ebx+68]
|
||||||
|
test edx, edx
|
||||||
|
jz @f
|
||||||
|
in ax, dx
|
||||||
|
and ax, 203h
|
||||||
|
or ah, ch
|
||||||
|
out dx, ax
|
||||||
|
@@:
|
||||||
|
jmp $
|
||||||
|
|
||||||
|
no_acpi_power_off:
|
||||||
|
jmp 0x50000
|
||||||
|
|
||||||
|
align 4
|
||||||
|
restart_code_start:
|
||||||
|
org 0x50000
|
||||||
|
|
||||||
|
cmp byte [0x9030], SYSTEM_RESTART
|
||||||
|
jne @F
|
||||||
|
|
||||||
|
mov esi, _CLEAN_ZONE-OS_BASE
|
||||||
|
mov edi, 0x10000
|
||||||
|
mov ecx, 0x31000/4
|
||||||
|
cld
|
||||||
|
rep movsd
|
||||||
|
@@:
|
||||||
|
|
||||||
|
xor ebx, ebx
|
||||||
|
xor edx, edx
|
||||||
|
xor ecx, ecx
|
||||||
|
xor esi, esi
|
||||||
|
xor edi, edi
|
||||||
|
xor ebp, ebp
|
||||||
|
lidt [.idt]
|
||||||
|
lgdt [.gdt]
|
||||||
jmp 8:@f
|
jmp 8:@f
|
||||||
|
align 8
|
||||||
|
.gdt:
|
||||||
|
; selector 0 - not used
|
||||||
|
dw 23
|
||||||
|
dd .gdt
|
||||||
|
dw 0
|
||||||
|
; selector 8 - code from 5000:0000 to 1000:FFFF
|
||||||
|
dw 0FFFFh
|
||||||
|
dw 0
|
||||||
|
db 5
|
||||||
|
db 10011011b
|
||||||
|
db 00000000b
|
||||||
|
db 0
|
||||||
|
; selector 10h - data from 1000:0000 to 1000:FFFF
|
||||||
|
dw 0FFFFh
|
||||||
|
dw 0
|
||||||
|
db 1
|
||||||
|
db 10010011b
|
||||||
|
db 00000000b
|
||||||
|
db 0
|
||||||
|
.idt:
|
||||||
|
dw 256*4
|
||||||
|
dd 0
|
||||||
|
org $ - 0x50000
|
||||||
use16
|
use16
|
||||||
@@:
|
@@:
|
||||||
mov ax, 10h
|
mov ax, 10h
|
||||||
@ -26,108 +227,64 @@ use16
|
|||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
and eax, not 80000001h
|
and eax, not 80000001h
|
||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
jmp 0x1000:pr_mode_exit
|
jmp 0x5000:.real_mode
|
||||||
|
|
||||||
pr_mode_exit:
|
align 4
|
||||||
|
.real_mode:
|
||||||
|
|
||||||
; setup stack
|
; setup stack
|
||||||
mov ax, 0x3000
|
|
||||||
mov ss, ax
|
|
||||||
mov esp, 0x0EC00
|
|
||||||
; setup ds
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
lidt [old_ints_h]
|
mov ax, (TMP_STACK_TOP and 0xF0000) shr 4
|
||||||
|
mov ss, ax
|
||||||
|
mov esp, TMP_STACK_TOP and 0xFFFF
|
||||||
|
|
||||||
;remap IRQs
|
;remap IRQs
|
||||||
mov al, 0x11
|
mov al, 0x11
|
||||||
out 0x20, al
|
out 0x20, al
|
||||||
call rdelay
|
|
||||||
out 0xA0, al
|
out 0xA0, al
|
||||||
call rdelay
|
|
||||||
|
|
||||||
mov al, 0x08
|
mov al, 0x08
|
||||||
out 0x21, al
|
out 0x21, al
|
||||||
call rdelay
|
|
||||||
mov al, 0x70
|
mov al, 0x70
|
||||||
out 0xA1, al
|
out 0xA1, al
|
||||||
call rdelay
|
|
||||||
|
|
||||||
mov al, 0x04
|
mov al, 0x04
|
||||||
out 0x21, al
|
out 0x21, al
|
||||||
call rdelay
|
|
||||||
mov al, 0x02
|
mov al, 0x02
|
||||||
out 0xA1, al
|
out 0xA1, al
|
||||||
call rdelay
|
|
||||||
|
|
||||||
mov al, 0x01
|
mov al, 0x01
|
||||||
out 0x21, al
|
out 0x21, al
|
||||||
call rdelay
|
|
||||||
out 0xA1, al
|
out 0xA1, al
|
||||||
call rdelay
|
|
||||||
|
|
||||||
mov al, 0xB8
|
mov al, 0xB8
|
||||||
out 0x21, al
|
out 0x21, al
|
||||||
call rdelay
|
|
||||||
mov al, 0xBD
|
mov al, 0xBD
|
||||||
out 0xA1, al
|
out 0xA1, al
|
||||||
sti
|
|
||||||
|
|
||||||
temp_3456:
|
mov al, 00110100b
|
||||||
|
out 43h, al
|
||||||
|
mov al, 0xFF
|
||||||
|
out 40h, al
|
||||||
|
out 40h, al
|
||||||
|
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov es, ax
|
mov ds, ax
|
||||||
mov al, byte [es:0x9030]
|
mov al, [0x9030]
|
||||||
cmp al, 1
|
cmp al, SYSTEM_RESTART
|
||||||
jl nbw
|
je .restart
|
||||||
cmp al, 4
|
|
||||||
jle nbw32
|
|
||||||
|
|
||||||
nbw:
|
cmp al, SYSTEM_SHUTDOWN
|
||||||
in al, 0x60
|
je .APM_PowerOff
|
||||||
cmp al, 6
|
|
||||||
jae nbw
|
|
||||||
mov bl, al
|
|
||||||
nbw2:
|
|
||||||
in al, 0x60
|
|
||||||
cmp al, bl
|
|
||||||
je nbw2
|
|
||||||
cmp al, 240;ax,240
|
|
||||||
jne nbw31
|
|
||||||
mov al, bl
|
|
||||||
dec ax
|
|
||||||
jmp nbw32
|
|
||||||
nbw31:
|
|
||||||
add bl, 128
|
|
||||||
cmp al, bl
|
|
||||||
jne nbw
|
|
||||||
sub al, 129
|
|
||||||
|
|
||||||
nbw32:
|
mov word[0x0472], 0x1234
|
||||||
|
|
||||||
dec ax
|
|
||||||
dec ax ; 2 = power off
|
|
||||||
jnz no_apm_off
|
|
||||||
call APM_PowerOff
|
|
||||||
jmp $
|
|
||||||
no_apm_off:
|
|
||||||
|
|
||||||
if ~ defined extended_primary_loader ; kernel restarting is not supported
|
|
||||||
dec ax ; 3 = reboot
|
|
||||||
jnz restart_kernel ; 4 = restart kernel
|
|
||||||
end if
|
|
||||||
push 0x40
|
|
||||||
pop ds
|
|
||||||
mov word[0x0072], 0x1234
|
|
||||||
jmp 0xF000:0xFFF0
|
jmp 0xF000:0xFFF0
|
||||||
|
|
||||||
|
.APM_PowerOff:
|
||||||
rdelay:
|
|
||||||
ret
|
|
||||||
|
|
||||||
APM_PowerOff:
|
|
||||||
mov ax, 5304h
|
mov ax, 5304h
|
||||||
xor bx, bx
|
xor bx, bx
|
||||||
int 15h
|
int 15h
|
||||||
@ -166,57 +323,24 @@ APM_PowerOff:
|
|||||||
mov cx, 3
|
mov cx, 3
|
||||||
int 0x15
|
int 0x15
|
||||||
;!!!!!!!!!!!!!!!!!!!!!!!!
|
;!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
ret
|
jmp $
|
||||||
|
|
||||||
if ~ defined extended_primary_loader
|
.restart:
|
||||||
restart_kernel:
|
|
||||||
|
|
||||||
mov ax, 0x0003 ; set text mode for screen
|
|
||||||
int 0x10
|
|
||||||
jmp 0x4000:0000
|
|
||||||
|
|
||||||
restart_kernel_4000:
|
|
||||||
cli
|
|
||||||
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
mov cx, 0x8000
|
|
||||||
push cx
|
|
||||||
push 0x7100
|
|
||||||
pop ds
|
|
||||||
xor si, si
|
|
||||||
xor di, di
|
|
||||||
rep movsw
|
|
||||||
pop cx
|
|
||||||
mov ds, cx
|
|
||||||
push 0x2000
|
|
||||||
pop es
|
|
||||||
rep movsw
|
|
||||||
push 0x9000
|
|
||||||
pop ds
|
|
||||||
push 0x3000
|
|
||||||
pop es
|
|
||||||
mov cx, 0xE000/2
|
|
||||||
rep movsw
|
|
||||||
|
|
||||||
wbinvd ; write and invalidate cache
|
|
||||||
|
|
||||||
mov al, 00110100b
|
|
||||||
out 43h, al
|
|
||||||
jcxz $+2
|
|
||||||
mov al, 0xFF
|
|
||||||
out 40h, al
|
|
||||||
jcxz $+2
|
|
||||||
out 40h, al
|
|
||||||
jcxz $+2
|
|
||||||
sti
|
|
||||||
|
|
||||||
; (hint by Black_mirror)
|
; (hint by Black_mirror)
|
||||||
; We must read data from keyboard port,
|
; We must read data from keyboard port,
|
||||||
; because there may be situation when previous keyboard interrupt is lost
|
; because there may be situation when previous keyboard interrupt is lost
|
||||||
; (due to return to real mode and IRQ reprogramming)
|
; (due to return to real mode and IRQ reprogramming)
|
||||||
; and next interrupt will not be generated (as keyboard waits for handling)
|
; and next interrupt will not be generated (as keyboard waits for handling)
|
||||||
|
|
||||||
|
mov cx, 16
|
||||||
|
@@:
|
||||||
|
in al, 0x64
|
||||||
|
test al, 1
|
||||||
|
jz @F
|
||||||
in al, 0x60
|
in al, 0x60
|
||||||
|
loop @B
|
||||||
|
@@:
|
||||||
|
|
||||||
; bootloader interface
|
; bootloader interface
|
||||||
push 0x1000
|
push 0x1000
|
||||||
@ -224,5 +348,10 @@ restart_kernel_4000:
|
|||||||
mov si, kernel_restart_bootblock
|
mov si, kernel_restart_bootblock
|
||||||
mov ax, 'KL'
|
mov ax, 'KL'
|
||||||
jmp 0x1000:0000
|
jmp 0x1000:0000
|
||||||
end if
|
|
||||||
|
|
||||||
|
align 4
|
||||||
|
org restart_code_start + $
|
||||||
|
restart_code_end:
|
||||||
|
|
||||||
|
org $+OS_BASE
|
||||||
|
use32
|
||||||
|
@ -358,6 +358,10 @@ STDIN_FILENO equ 0
|
|||||||
STDOUT_FILENO equ 1
|
STDOUT_FILENO equ 1
|
||||||
STDERR_FILENO equ 2
|
STDERR_FILENO equ 2
|
||||||
|
|
||||||
|
SYSTEM_SHUTDOWN equ 2
|
||||||
|
SYSTEM_REBOOT equ 3
|
||||||
|
SYSTEM_RESTART equ 4
|
||||||
|
|
||||||
struct SYSCALL_STACK
|
struct SYSCALL_STACK
|
||||||
_eip dd ?
|
_eip dd ?
|
||||||
_edi dd ? ; +4
|
_edi dd ? ; +4
|
||||||
|
@ -173,11 +173,11 @@ end if
|
|||||||
vmode db '/sys/drivers/VMODE.MDR',0
|
vmode db '/sys/drivers/VMODE.MDR',0
|
||||||
;vrr_m db 'VRR_M',0
|
;vrr_m db 'VRR_M',0
|
||||||
kernel_file_load:
|
kernel_file_load:
|
||||||
; load kernel.mnt to 0x7000:0
|
; load kernel.mnt to _CLEAN_ZONE
|
||||||
dd 0 ; subfunction
|
dd 0 ; subfunction
|
||||||
dq 0 ; offset in file
|
dq 0 ; offset in file
|
||||||
dd 0x30000 ; number of bytes to read
|
dd 0x31000 ; number of bytes to read
|
||||||
dd OS_BASE + 0x71000 ; buffer for data
|
dd _CLEAN_ZONE ; buffer for data
|
||||||
db '/RD/1/KERNEL.MNT',0
|
db '/RD/1/KERNEL.MNT',0
|
||||||
|
|
||||||
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
|
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
|
||||||
@ -371,12 +371,10 @@ os_stack_seg rd 1
|
|||||||
srv.fd rd 1
|
srv.fd rd 1
|
||||||
srv.bk rd 1
|
srv.bk rd 1
|
||||||
|
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
|
|
||||||
_display display_t
|
_display display_t
|
||||||
|
|
||||||
|
|
||||||
LFBAddress dd ?
|
LFBAddress dd ?
|
||||||
|
|
||||||
SCR_MODE rw 2
|
SCR_MODE rw 2
|
||||||
|
@ -455,7 +455,27 @@ ACPI_FADT_SIGN equ 0x50434146
|
|||||||
|
|
||||||
acpi_locate:
|
acpi_locate:
|
||||||
push ebx
|
push ebx
|
||||||
|
push edi
|
||||||
|
|
||||||
|
movzx ebx, word [0x40E]
|
||||||
|
shl ebx, 4
|
||||||
|
lea ecx, [ebx+1024]
|
||||||
|
call .check
|
||||||
|
|
||||||
|
test ebx, ebx
|
||||||
|
jz @F
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
@@:
|
||||||
mov ebx, ACPI_HI_RSDP_WINDOW_START
|
mov ebx, ACPI_HI_RSDP_WINDOW_START
|
||||||
|
mov edi, ACPI_HI_RSDP_WINDOW_END
|
||||||
|
call .check
|
||||||
|
.done:
|
||||||
|
mov eax, ebx
|
||||||
|
pop edi
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
|
||||||
.check:
|
.check:
|
||||||
cmp [ebx], dword 0x20445352
|
cmp [ebx], dword 0x20445352
|
||||||
jne .next
|
jne .next
|
||||||
@ -472,17 +492,12 @@ acpi_locate:
|
|||||||
|
|
||||||
test al, al
|
test al, al
|
||||||
jnz .next
|
jnz .next
|
||||||
|
|
||||||
mov eax, ebx
|
|
||||||
pop ebx
|
|
||||||
ret
|
ret
|
||||||
.next:
|
.next:
|
||||||
add ebx, 16
|
add ebx, 16
|
||||||
cmp ebx, ACPI_HI_RSDP_WINDOW_END
|
cmp ebx, edi
|
||||||
jb .check
|
jb .check
|
||||||
|
xor ebx, ebx
|
||||||
pop ebx
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
|
@ -253,7 +253,7 @@ B32:
|
|||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
mov esp, 0x006CC00 ; Set stack
|
mov esp, TMP_STACK_TOP ; Set stack
|
||||||
|
|
||||||
; CLEAR 0x280000 - HEAP_BASE
|
; CLEAR 0x280000 - HEAP_BASE
|
||||||
|
|
||||||
@ -305,12 +305,7 @@ B32:
|
|||||||
align 4
|
align 4
|
||||||
bios32_entry dd ?
|
bios32_entry dd ?
|
||||||
tmp_page_tabs dd ?
|
tmp_page_tabs dd ?
|
||||||
|
|
||||||
use16
|
use16
|
||||||
org $-0x10000
|
|
||||||
include "boot/shutdown.inc" ; shutdown or restart
|
|
||||||
org $+0x10000
|
|
||||||
|
|
||||||
ap_init16:
|
ap_init16:
|
||||||
cli
|
cli
|
||||||
lgdt [cs:gdts_ap-ap_init16]
|
lgdt [cs:gdts_ap-ap_init16]
|
||||||
@ -5722,266 +5717,6 @@ undefined_syscall: ; Undefined system call
|
|||||||
mov [esp + 32], dword -1
|
mov [esp + 32], dword -1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
|
||||||
system_shutdown: ; shut down the system
|
|
||||||
|
|
||||||
cmp byte [BOOT_VARS+0x9030], 1
|
|
||||||
jne @F
|
|
||||||
ret
|
|
||||||
@@:
|
|
||||||
call stop_all_services
|
|
||||||
|
|
||||||
yes_shutdown_param:
|
|
||||||
; Shutdown other CPUs, if initialized
|
|
||||||
cmp [ap_initialized], 0
|
|
||||||
jz .no_shutdown_cpus
|
|
||||||
mov edi, [LAPIC_BASE]
|
|
||||||
add edi, 300h
|
|
||||||
mov esi, smpt+4
|
|
||||||
mov ebx, [cpu_count]
|
|
||||||
dec ebx
|
|
||||||
.shutdown_cpus_loop:
|
|
||||||
lodsd
|
|
||||||
push esi
|
|
||||||
xor esi, esi
|
|
||||||
inc esi
|
|
||||||
shl eax, 24
|
|
||||||
mov [edi+10h], eax
|
|
||||||
; assert INIT IPI
|
|
||||||
mov dword [edi], 0C500h
|
|
||||||
call delay_ms
|
|
||||||
@@:
|
|
||||||
test dword [edi], 1000h
|
|
||||||
jnz @b
|
|
||||||
; deassert INIT IPI
|
|
||||||
mov dword [edi], 8500h
|
|
||||||
call delay_ms
|
|
||||||
@@:
|
|
||||||
test dword [edi], 1000h
|
|
||||||
jnz @b
|
|
||||||
; don't send STARTUP IPI: let other CPUs be in wait-for-startup state
|
|
||||||
pop esi
|
|
||||||
dec ebx
|
|
||||||
jnz .shutdown_cpus_loop
|
|
||||||
.no_shutdown_cpus:
|
|
||||||
|
|
||||||
cli
|
|
||||||
|
|
||||||
if ~ defined extended_primary_loader
|
|
||||||
; load kernel.mnt to 0x7000:0
|
|
||||||
mov ebx, kernel_file_load
|
|
||||||
pushad
|
|
||||||
call file_system_lfn
|
|
||||||
popad
|
|
||||||
|
|
||||||
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0
|
|
||||||
mov edi, OS_BASE+0x40000
|
|
||||||
mov ecx, 1000
|
|
||||||
rep movsb
|
|
||||||
end if
|
|
||||||
|
|
||||||
; mov esi, BOOT_VAR ; restore 0x0 - 0xffff
|
|
||||||
; mov edi, OS_BASE
|
|
||||||
; mov ecx, 0x10000/4
|
|
||||||
; cld
|
|
||||||
; rep movsd
|
|
||||||
|
|
||||||
call IRQ_mask_all
|
|
||||||
|
|
||||||
cmp byte [OS_BASE + 0x9030], 2
|
|
||||||
jnz no_acpi_power_off
|
|
||||||
|
|
||||||
; scan for RSDP
|
|
||||||
; 1) The first 1 Kb of the Extended BIOS Data Area (EBDA).
|
|
||||||
movzx eax, word [OS_BASE + 0x40E]
|
|
||||||
shl eax, 4
|
|
||||||
jz @f
|
|
||||||
mov ecx, 1024/16
|
|
||||||
call scan_rsdp
|
|
||||||
jnc .rsdp_found
|
|
||||||
@@:
|
|
||||||
; 2) The BIOS read-only memory space between 0E0000h and 0FFFFFh.
|
|
||||||
mov eax, 0xE0000
|
|
||||||
mov ecx, 0x2000
|
|
||||||
call scan_rsdp
|
|
||||||
jc no_acpi_power_off
|
|
||||||
.rsdp_found:
|
|
||||||
mov esi, [eax+16] ; esi contains physical address of the RSDT
|
|
||||||
mov ebp, [ipc_tmp]
|
|
||||||
stdcall map_page, ebp, esi, PG_READ
|
|
||||||
lea eax, [esi+1000h]
|
|
||||||
lea edx, [ebp+1000h]
|
|
||||||
stdcall map_page, edx, eax, PG_READ
|
|
||||||
and esi, 0xFFF
|
|
||||||
add esi, ebp
|
|
||||||
cmp dword [esi], 'RSDT'
|
|
||||||
jnz no_acpi_power_off
|
|
||||||
mov ecx, [esi+4]
|
|
||||||
sub ecx, 24h
|
|
||||||
jbe no_acpi_power_off
|
|
||||||
shr ecx, 2
|
|
||||||
add esi, 24h
|
|
||||||
.scan_fadt:
|
|
||||||
lodsd
|
|
||||||
mov ebx, eax
|
|
||||||
lea eax, [ebp+2000h]
|
|
||||||
stdcall map_page, eax, ebx, PG_READ
|
|
||||||
lea eax, [ebp+3000h]
|
|
||||||
add ebx, 0x1000
|
|
||||||
stdcall map_page, eax, ebx, PG_READ
|
|
||||||
and ebx, 0xFFF
|
|
||||||
lea ebx, [ebx+ebp+2000h]
|
|
||||||
cmp dword [ebx], 'FACP'
|
|
||||||
jz .fadt_found
|
|
||||||
loop .scan_fadt
|
|
||||||
jmp no_acpi_power_off
|
|
||||||
.fadt_found:
|
|
||||||
; ebx is linear address of FADT
|
|
||||||
mov edi, [ebx+40] ; physical address of the DSDT
|
|
||||||
lea eax, [ebp+4000h]
|
|
||||||
stdcall map_page, eax, edi, PG_READ
|
|
||||||
lea eax, [ebp+5000h]
|
|
||||||
lea esi, [edi+0x1000]
|
|
||||||
stdcall map_page, eax, esi, PG_READ
|
|
||||||
and esi, 0xFFF
|
|
||||||
sub edi, esi
|
|
||||||
cmp dword [esi+ebp+4000h], 'DSDT'
|
|
||||||
jnz no_acpi_power_off
|
|
||||||
mov eax, [esi+ebp+4004h] ; DSDT length
|
|
||||||
sub eax, 36+4
|
|
||||||
jbe no_acpi_power_off
|
|
||||||
add esi, 36
|
|
||||||
.scan_dsdt:
|
|
||||||
cmp dword [esi+ebp+4000h], '_S5_'
|
|
||||||
jnz .scan_dsdt_cont
|
|
||||||
cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode
|
|
||||||
jnz .scan_dsdt_cont
|
|
||||||
mov dl, [esi+ebp+4000h+6]
|
|
||||||
cmp dl, 4 ; _S5_ package must contain 4 bytes
|
|
||||||
; ...in theory; in practice, VirtualBox has 2 bytes
|
|
||||||
ja .scan_dsdt_cont
|
|
||||||
cmp dl, 1
|
|
||||||
jb .scan_dsdt_cont
|
|
||||||
lea esi, [esi+ebp+4000h+7]
|
|
||||||
xor ecx, ecx
|
|
||||||
cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx
|
|
||||||
jz @f
|
|
||||||
cmp byte [esi], 0xA
|
|
||||||
jnz no_acpi_power_off
|
|
||||||
inc esi
|
|
||||||
mov cl, [esi]
|
|
||||||
@@:
|
|
||||||
inc esi
|
|
||||||
cmp dl, 2
|
|
||||||
jb @f
|
|
||||||
cmp byte [esi], 0
|
|
||||||
jz @f
|
|
||||||
cmp byte [esi], 0xA
|
|
||||||
jnz no_acpi_power_off
|
|
||||||
inc esi
|
|
||||||
mov ch, [esi]
|
|
||||||
@@:
|
|
||||||
jmp do_acpi_power_off
|
|
||||||
.scan_dsdt_cont:
|
|
||||||
inc esi
|
|
||||||
cmp esi, 0x1000
|
|
||||||
jb @f
|
|
||||||
sub esi, 0x1000
|
|
||||||
add edi, 0x1000
|
|
||||||
push eax
|
|
||||||
lea eax, [ebp+4000h]
|
|
||||||
stdcall map_page, eax, edi, PG_READ
|
|
||||||
push PG_READ
|
|
||||||
lea eax, [edi+1000h]
|
|
||||||
push eax
|
|
||||||
lea eax, [ebp+5000h]
|
|
||||||
push eax
|
|
||||||
stdcall map_page
|
|
||||||
pop eax
|
|
||||||
@@:
|
|
||||||
dec eax
|
|
||||||
jnz .scan_dsdt
|
|
||||||
jmp no_acpi_power_off
|
|
||||||
do_acpi_power_off:
|
|
||||||
mov edx, [ebx+48]
|
|
||||||
test edx, edx
|
|
||||||
jz .nosmi
|
|
||||||
mov al, [ebx+52]
|
|
||||||
out dx, al
|
|
||||||
mov edx, [ebx+64]
|
|
||||||
@@:
|
|
||||||
in ax, dx
|
|
||||||
test al, 1
|
|
||||||
jz @b
|
|
||||||
.nosmi:
|
|
||||||
and cx, 0x0707
|
|
||||||
shl cx, 2
|
|
||||||
or cx, 0x2020
|
|
||||||
mov edx, [ebx+64]
|
|
||||||
in ax, dx
|
|
||||||
and ax, 203h
|
|
||||||
or ah, cl
|
|
||||||
out dx, ax
|
|
||||||
mov edx, [ebx+68]
|
|
||||||
test edx, edx
|
|
||||||
jz @f
|
|
||||||
in ax, dx
|
|
||||||
and ax, 203h
|
|
||||||
or ah, ch
|
|
||||||
out dx, ax
|
|
||||||
@@:
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
|
|
||||||
scan_rsdp:
|
|
||||||
add eax, OS_BASE
|
|
||||||
.s:
|
|
||||||
cmp dword [eax], 'RSD '
|
|
||||||
jnz .n
|
|
||||||
cmp dword [eax+4], 'PTR '
|
|
||||||
jnz .n
|
|
||||||
xor edx, edx
|
|
||||||
xor esi, esi
|
|
||||||
@@:
|
|
||||||
add dl, [eax+esi]
|
|
||||||
inc esi
|
|
||||||
cmp esi, 20
|
|
||||||
jnz @b
|
|
||||||
test dl, dl
|
|
||||||
jz .ok
|
|
||||||
.n:
|
|
||||||
add eax, 10h
|
|
||||||
loop .s
|
|
||||||
stc
|
|
||||||
.ok:
|
|
||||||
ret
|
|
||||||
|
|
||||||
no_acpi_power_off:
|
|
||||||
call create_trampoline_pgmap
|
|
||||||
mov cr3, eax
|
|
||||||
jmp become_real+0x10000
|
|
||||||
iglobal
|
|
||||||
align 4
|
|
||||||
realmode_gdt:
|
|
||||||
; selector 0 - not used
|
|
||||||
dw 23
|
|
||||||
dd realmode_gdt-OS_BASE
|
|
||||||
dw 0
|
|
||||||
; selector 8 - code from 1000:0000 to 1000:FFFF
|
|
||||||
dw 0FFFFh
|
|
||||||
dw 0
|
|
||||||
db 1
|
|
||||||
db 10011011b
|
|
||||||
db 00000000b
|
|
||||||
db 0
|
|
||||||
; selector 10h - data from 1000:0000 to 1000:FFFF
|
|
||||||
dw 0FFFFh
|
|
||||||
dw 0
|
|
||||||
db 1
|
|
||||||
db 10010011b
|
|
||||||
db 00000000b
|
|
||||||
db 0
|
|
||||||
endg
|
|
||||||
|
|
||||||
if ~ lang eq sp
|
if ~ lang eq sp
|
||||||
diff16 "end of .text segment",0,$
|
diff16 "end of .text segment",0,$
|
||||||
|
@ -42,7 +42,7 @@ include "gui/event.inc"
|
|||||||
include "gui/font.inc"
|
include "gui/font.inc"
|
||||||
include "gui/button.inc"
|
include "gui/button.inc"
|
||||||
|
|
||||||
; shutdown
|
include "boot/shutdown.inc" ; kernel shutdown
|
||||||
|
|
||||||
; file system
|
; file system
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user