Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6241 → Rev 6242

/kernel/branches/Kolibri-acpi/kernel.asm
305,12 → 305,7
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,324 → 5717,7
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
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
diff16 "end of .text segment",0,$
end if