kos-acpi: reworked restart etc

git-svn-id: svn://kolibrios.org@6242 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2016-02-17 14:32:29 +00:00
parent a73038cb78
commit d4aeb26207
5 changed files with 238 additions and 449 deletions

View File

@ -13,18 +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
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 ebx, ebx
xor edx, edx xor edx, edx
xor ecx, ecx xor ecx, ecx
xor esi, esi xor esi, esi
xor edi, edi xor edi, edi
xor ebp, ebp xor ebp, ebp
cli lidt [.idt]
ltr bx lgdt [.gdt]
lgdt [realmode_gdt-OS_BASE]
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
@ -33,109 +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, (TMP_STACK_TOP and 0xF0000) shr 4 mov ax, (TMP_STACK_TOP and 0xF0000) shr 4
mov ss, ax mov ss, ax
mov esp, TMP_STACK_TOP and 0xFFFF mov esp, TMP_STACK_TOP and 0xFFFF
;setup ds
push cs
pop ds
lidt [old_ints_h]
;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
@ -174,67 +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 0x5000:0000
restart_kernel_5001:
cli
push ds
pop es
xor si, si
xor di, di
push 0x7100
pop ds
mov cx, 0x4000
rep movsd
push 0x8100
pop ds
push 0x2000
pop es
mov cx, 0x4000
rep movsd
push 0x9100
pop ds
push 0x3000
pop es
mov cx, 0x4000
rep movsd
xchg bx, bx
push 0xA100
pop ds
push 0x4000
pop es
mov cx, 0x800
rep movsd
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
@ -242,5 +348,10 @@ xchg bx, bx
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

View File

@ -372,12 +372,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

View File

@ -463,8 +463,10 @@ acpi_locate:
call .check call .check
test ebx, ebx test ebx, ebx
jnz .done 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 mov edi, ACPI_HI_RSDP_WINDOW_END
call .check call .check

View File

@ -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,323 +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
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_kernel_5000 ; move kernel re-starter to 0x5000:0
mov edi, OS_BASE+0x50000
mov ecx, (restart_code_end - restart_kernel_5000)/4
rep movsd
@@:
;disable paging
call create_trampoline_pgmap
mov cr3, eax
jmp @F
org $-OS_BASE
@@:
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_kernel_5000:
org 0x50000
cmp byte [0x9030], SYSTEM_RESTART
jne @F
xchg bx, bx
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
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
@@:
mov ax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, cr0
and eax, not 80000001h
mov cr0, eax
jmp 0x5000:.real_mode
align 4
.real_mode:
; setup stack
mov ax, (TMP_STACK_TOP and 0xF0000) shr 4
mov ss, ax
mov esp, TMP_STACK_TOP and 0xFFFF
;remap IRQs
mov al, 0x11
out 0x20, al
out 0xA0, al
mov al, 0x08
out 0x21, al
mov al, 0x70
out 0xA1, al
mov al, 0x04
out 0x21, al
mov al, 0x02
out 0xA1, al
mov al, 0x01
out 0x21, al
out 0xA1, al
mov al, 0xB8
out 0x21, al
mov al, 0xBD
out 0xA1, al
mov al, 00110100b
out 43h, al
mov al, 0xFF
out 40h, al
out 40h, al
mov al, byte [es:0x9030]
cmp al, SYSTEM_RESTART
je .do_restart
jmp $
.do_restart:
mov ax, 0x0003 ; set text mode for screen
int 0x10
sti
; (hint by Black_mirror)
; We must read data from keyboard port,
; because there may be situation when previous keyboard interrupt is lost
; (due to return to real mode and IRQ reprogramming)
; and next interrupt will not be generated (as keyboard waits for handling)
in al, 0x60
; bootloader interface
push 0x1000
pop ds
mov si, kernel_restart_bootblock
mov ax, 'KL'
jmp 0x1000:0000
align 4
org restart_kernel_5000 + $
restart_code_end:
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 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
endg
org $+OS_BASE
if ~ lang eq sp if ~ lang eq sp
diff16 "end of .text segment",0,$ diff16 "end of .text segment",0,$

View File

@ -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