diff --git a/kernel/branches/Kolibri-acpi/boot/shutdown.inc b/kernel/branches/Kolibri-acpi/boot/shutdown.inc index cbd5de76a4..83d3c4aae5 100644 --- a/kernel/branches/Kolibri-acpi/boot/shutdown.inc +++ b/kernel/branches/Kolibri-acpi/boot/shutdown.inc @@ -13,18 +13,212 @@ $Revision$ -use32 -become_real: +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_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 - cli - ltr bx - lgdt [realmode_gdt-OS_BASE] + 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 @@ -33,109 +227,64 @@ use16 mov fs, ax mov gs, ax mov ss, ax + mov eax, cr0 and eax, not 80000001h mov cr0, eax - jmp 0x1000:pr_mode_exit + jmp 0x5000:.real_mode -pr_mode_exit: +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 -;setup ds - push cs - pop ds - - lidt [old_ints_h] ;remap IRQs mov al, 0x11 out 0x20, al - call rdelay out 0xA0, al - call rdelay mov al, 0x08 out 0x21, al - call rdelay mov al, 0x70 out 0xA1, al - call rdelay mov al, 0x04 out 0x21, al - call rdelay mov al, 0x02 out 0xA1, al - call rdelay mov al, 0x01 out 0x21, al - call rdelay out 0xA1, al - call rdelay mov al, 0xB8 out 0x21, al - call rdelay mov al, 0xBD out 0xA1, al - sti -temp_3456: + mov al, 00110100b + out 43h, al + mov al, 0xFF + out 40h, al + out 40h, al + xor ax, ax - mov es, ax - mov al, byte [es:0x9030] - cmp al, 1 - jl nbw - cmp al, 4 - jle nbw32 + mov ds, ax + mov al, [0x9030] + cmp al, SYSTEM_RESTART + je .restart -nbw: - in al, 0x60 - 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 + cmp al, SYSTEM_SHUTDOWN + je .APM_PowerOff -nbw32: - - 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 + mov word[0x0472], 0x1234 jmp 0xF000:0xFFF0 - -rdelay: - ret - -APM_PowerOff: +.APM_PowerOff: mov ax, 5304h xor bx, bx int 15h @@ -174,67 +323,24 @@ APM_PowerOff: mov cx, 3 int 0x15 ;!!!!!!!!!!!!!!!!!!!!!!!! - ret + jmp $ -if ~ defined extended_primary_loader -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 +.restart: ; (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) + + mov cx, 16 +@@: + in al, 0x64 + test al, 1 + jz @F in al, 0x60 + loop @B +@@: ; bootloader interface push 0x1000 @@ -242,5 +348,10 @@ xchg bx, bx mov si, kernel_restart_bootblock mov ax, 'KL' jmp 0x1000:0000 -end if +align 4 +org restart_code_start + $ +restart_code_end: + +org $+OS_BASE +use32 diff --git a/kernel/branches/Kolibri-acpi/data32.inc b/kernel/branches/Kolibri-acpi/data32.inc index 7017547411..2c846bd348 100644 --- a/kernel/branches/Kolibri-acpi/data32.inc +++ b/kernel/branches/Kolibri-acpi/data32.inc @@ -372,12 +372,10 @@ os_stack_seg rd 1 srv.fd rd 1 srv.bk rd 1 - align 16 _display display_t - LFBAddress dd ? SCR_MODE rw 2 diff --git a/kernel/branches/Kolibri-acpi/init.inc b/kernel/branches/Kolibri-acpi/init.inc index c49755bb4f..dd7478416d 100644 --- a/kernel/branches/Kolibri-acpi/init.inc +++ b/kernel/branches/Kolibri-acpi/init.inc @@ -463,8 +463,10 @@ acpi_locate: call .check test ebx, ebx - jnz .done + jz @F + jmp .done +@@: mov ebx, ACPI_HI_RSDP_WINDOW_START mov edi, ACPI_HI_RSDP_WINDOW_END call .check diff --git a/kernel/branches/Kolibri-acpi/kernel.asm b/kernel/branches/Kolibri-acpi/kernel.asm index cb9ce4cef6..5f12517cc8 100644 --- a/kernel/branches/Kolibri-acpi/kernel.asm +++ b/kernel/branches/Kolibri-acpi/kernel.asm @@ -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,323 +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 - 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,$ diff --git a/kernel/branches/Kolibri-acpi/kernel32.inc b/kernel/branches/Kolibri-acpi/kernel32.inc index 4d0263b1c7..762293082b 100644 --- a/kernel/branches/Kolibri-acpi/kernel32.inc +++ b/kernel/branches/Kolibri-acpi/kernel32.inc @@ -42,7 +42,7 @@ include "gui/event.inc" include "gui/font.inc" include "gui/button.inc" -; shutdown +include "boot/shutdown.inc" ; kernel shutdown ; file system