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:
@@ -253,7 +253,7 @@ B32:
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
mov esp, 0x006CC00 ; Set stack
|
||||
mov esp, TMP_STACK_TOP ; Set stack
|
||||
|
||||
; CLEAR 0x280000 - HEAP_BASE
|
||||
|
||||
@@ -305,12 +305,7 @@ B32:
|
||||
align 4
|
||||
bios32_entry dd ?
|
||||
tmp_page_tabs dd ?
|
||||
|
||||
use16
|
||||
org $-0x10000
|
||||
include "boot/shutdown.inc" ; shutdown or restart
|
||||
org $+0x10000
|
||||
|
||||
ap_init16:
|
||||
cli
|
||||
lgdt [cs:gdts_ap-ap_init16]
|
||||
@@ -5722,266 +5717,6 @@ undefined_syscall: ; Undefined system call
|
||||
mov [esp + 32], dword -1
|
||||
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
|
||||
diff16 "end of .text segment",0,$
|
||||
|
Reference in New Issue
Block a user