forked from KolibriOS/kolibrios
kos-acpi: kernel restart reboot and shutdown
git-svn-id: svn://kolibrios.org@6240 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
d112b67c4c
commit
6e1bd6d91d
@ -15,7 +15,14 @@ $Revision$
|
||||
|
||||
use32
|
||||
become_real:
|
||||
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]
|
||||
jmp 8:@f
|
||||
use16
|
||||
@ -34,10 +41,11 @@ use16
|
||||
pr_mode_exit:
|
||||
|
||||
; setup stack
|
||||
mov ax, 0x3000
|
||||
mov ax, (TMP_STACK_TOP and 0xF0000) shr 4
|
||||
mov ss, ax
|
||||
mov esp, 0x0EC00
|
||||
; setup ds
|
||||
mov esp, TMP_STACK_TOP and 0xFFFF
|
||||
|
||||
;setup ds
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
@ -173,31 +181,41 @@ restart_kernel:
|
||||
|
||||
mov ax, 0x0003 ; set text mode for screen
|
||||
int 0x10
|
||||
jmp 0x4000:0000
|
||||
jmp 0x5000:0000
|
||||
|
||||
restart_kernel_4000:
|
||||
restart_kernel_5001:
|
||||
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 0x7100
|
||||
pop ds
|
||||
mov cx, 0x4000
|
||||
rep movsd
|
||||
|
||||
push 0x8100
|
||||
pop ds
|
||||
push 0x2000
|
||||
pop es
|
||||
rep movsw
|
||||
push 0x9000
|
||||
mov cx, 0x4000
|
||||
rep movsd
|
||||
|
||||
push 0x9100
|
||||
pop ds
|
||||
push 0x3000
|
||||
pop es
|
||||
mov cx, 0xE000/2
|
||||
rep movsw
|
||||
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
|
||||
|
||||
|
@ -358,6 +358,10 @@ STDIN_FILENO equ 0
|
||||
STDOUT_FILENO equ 1
|
||||
STDERR_FILENO equ 2
|
||||
|
||||
SYSTEM_SHUTDOWN equ 2
|
||||
SYSTEM_REBOOT equ 3
|
||||
SYSTEM_RESTART equ 4
|
||||
|
||||
struct SYSCALL_STACK
|
||||
_eip dd ?
|
||||
_edi dd ? ; +4
|
||||
|
@ -132,10 +132,10 @@ align 4
|
||||
jnz .futex_wait_timeout
|
||||
mov ecx, [ebp+FUTEX.pointer]
|
||||
mov eax, edx
|
||||
lock cmpxchg [ecx], edx ;wait until old_value == new_value
|
||||
jz .wait_slow
|
||||
lock cmpxchg [ecx], edx
|
||||
je .wait_slow
|
||||
|
||||
mov [esp+SYSCALL_STACK._eax], 0
|
||||
mov [esp+SYSCALL_STACK._eax], -2
|
||||
ret
|
||||
|
||||
.wait_slow:
|
||||
@ -148,13 +148,13 @@ align 4
|
||||
lea esi, [ebp+FUTEX.wait_list]
|
||||
|
||||
list_add_tail esp, esi ;esp= new waiter, esi= list head
|
||||
|
||||
mov eax, edx
|
||||
.again:
|
||||
mov [ebx+TASKDATA.state], 1
|
||||
call change_task
|
||||
|
||||
lock cmpxchg [ecx], edx
|
||||
jz .again
|
||||
je .again
|
||||
|
||||
list_del esp
|
||||
add esp, sizeof.MUTEX_WAITER
|
||||
@ -174,9 +174,9 @@ align 4
|
||||
mov ecx, [ebp+FUTEX.pointer]
|
||||
mov eax, edx
|
||||
lock cmpxchg [ecx], edx ;wait until old_value == new_value
|
||||
jz .wait_slow_timeout
|
||||
je .wait_slow_timeout
|
||||
|
||||
mov [esp+SYSCALL_STACK._eax], 0
|
||||
mov [esp+SYSCALL_STACK._eax], -2
|
||||
ret
|
||||
|
||||
align 4
|
||||
@ -210,6 +210,7 @@ align 4
|
||||
test eax, eax
|
||||
jz .timeout
|
||||
|
||||
mov eax, edx
|
||||
lock cmpxchg [ecx], edx
|
||||
jz .again_timeout
|
||||
@@:
|
||||
@ -231,7 +232,7 @@ align 4
|
||||
|
||||
align 4
|
||||
;ecx futex handle
|
||||
;edx numder of threads
|
||||
;edx number of threads
|
||||
;edi current process
|
||||
;ebp futex object
|
||||
.futex_wake:
|
||||
|
@ -940,12 +940,6 @@ proc new_sys_threads
|
||||
mov ecx, 11
|
||||
rep movsb ;copy process name
|
||||
|
||||
mov eax, [ebx+APPDATA.process]
|
||||
mov [edx+APPDATA.process], eax
|
||||
|
||||
lea ebx, [edx+APPDATA.list]
|
||||
lea ecx, [eax+PROC.thr_list]
|
||||
list_add_tail ebx, ecx ;add thread to process child's list
|
||||
|
||||
mov eax, [ebx+APPDATA.tls_base]
|
||||
test eax, eax
|
||||
@ -959,6 +953,13 @@ proc new_sys_threads
|
||||
@@:
|
||||
mov [edx+APPDATA.tls_base], eax
|
||||
|
||||
mov eax, [ebx+APPDATA.process]
|
||||
mov [edx+APPDATA.process], eax
|
||||
|
||||
lea ebx, [edx+APPDATA.list]
|
||||
lea ecx, [eax+PROC.thr_list]
|
||||
list_add_tail ebx, ecx ;add thread to process child's list
|
||||
|
||||
lea eax, [app_cmdline]
|
||||
stdcall set_app_params , [slot], eax, dword 0, \
|
||||
dword 0, [flags]
|
||||
|
@ -173,11 +173,12 @@ end if
|
||||
vmode db '/sys/drivers/VMODE.MDR',0
|
||||
;vrr_m db 'VRR_M',0
|
||||
kernel_file_load:
|
||||
; load kernel.mnt to 0x7000:0
|
||||
|
||||
; load kernel.mnt to _CLEAN_ZONE
|
||||
dd 0 ; subfunction
|
||||
dq 0 ; offset in file
|
||||
dd 0x30000 ; number of bytes to read
|
||||
dd OS_BASE + 0x71000 ; buffer for data
|
||||
dd 0x31000 ; number of bytes to read
|
||||
dd _CLEAN_ZONE ; buffer for data
|
||||
db '/RD/1/KERNEL.MNT',0
|
||||
|
||||
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
|
||||
|
@ -25,20 +25,18 @@
|
||||
* ecx = [координата по оси y]*65536 + [размер по оси y]
|
||||
* edx = 0xXYRRGGBB, где:
|
||||
* Y = стиль окна:
|
||||
* Y=0 - тип I - окно фиксированных размеров
|
||||
* Y=1 - только определить область окна, ничего не рисовать
|
||||
* Y=2 - тип II - окно изменяемых размеров
|
||||
* Y=3 - окно со скином
|
||||
* Y=4 - окно со скином фиксированных размеров
|
||||
* Y=0,2 эти стили являются устаревшими и не должны более использоваться,
|
||||
они оставлены для совместимости со старыми приложениями
|
||||
* остальные возможные значения (от 5 до 15) зарезервированы,
|
||||
вызов функции с такими Y игнорируется
|
||||
* RR, GG, BB = соответственно красная, зеленая, синяя
|
||||
составляющие цвета рабочей области окна
|
||||
(игнорируется для стиля Y=1)
|
||||
* X = DCBA (биты)
|
||||
* A = 1 - у окна есть заголовок; для стилей Y=3,4 адрес строки
|
||||
заголовка задаётся в edi, для прочих стилей
|
||||
используется подфункция 1 функции 71
|
||||
* A = 1 - у окна есть заголовок
|
||||
* B = 1 - координаты всех графических примитивов задаются
|
||||
относительно клиентской области окна
|
||||
* C = 1 - не закрашивать рабочую область при отрисовке окна
|
||||
@ -52,7 +50,7 @@
|
||||
X=8 - обычный градиент,
|
||||
для окон типа II X=4 - негативный градиент
|
||||
* прочие значения X и Y зарезервированы
|
||||
* edi = 0x00RRGGBB - цвет рамки
|
||||
* edi = адрес строки заголовка для стилей Y=3,4 (также см. функцию 71.1)
|
||||
Возвращаемое значение:
|
||||
* функция не возвращает значения
|
||||
Замечания:
|
||||
@ -82,35 +80,9 @@
|
||||
* Размеры окна понимаются в смысле координат правого нижнего угла.
|
||||
Это же относится и ко всем остальным функциям.
|
||||
Это означает, что реальные размеры на 1 пиксель больше.
|
||||
* Вид окна типа I:
|
||||
* рисуется внешняя рамка цвета, указанного в edi,
|
||||
шириной 1 пиксель
|
||||
* рисуется заголовок - прямоугольник с левым верхним углом (1,1)
|
||||
и правым нижним (xsize-1,min(20,ysize-1)) цвета, указанного в esi
|
||||
(с учетом градиента)
|
||||
* если ysize>21, то закрашивается рабочая область окна -
|
||||
прямоугольник с левым верхним углом (1,21) и правым нижним
|
||||
(xsize-1,ysize-1) (размерами (xsize-1)*(ysize-21)) - цветом,
|
||||
указанным в edx (с учетом градиента)
|
||||
* если A=1 и строка заголовка установлена подфункцией 1
|
||||
функции 71, то она выводится в соответствующем месте заголовка
|
||||
* Вид окна стиля Y=1:
|
||||
* полностью определяется приложением
|
||||
* Вид окна типа II:
|
||||
* рисуется внешняя рамка шириной 1 пиксель "затенённого" цвета
|
||||
edi (все составляющие цвета уменьшаются в два раза)
|
||||
* рисуется промежуточная рамка шириной 3 пикселя цвета edi
|
||||
* рисуется внутренняя рамка шириной 1 пиксель
|
||||
"затенённого" цвета edi
|
||||
* рисуется заголовок - прямоугольник с левым верхним углом (4,4)
|
||||
и правым нижним (xsize-4,min(20,ysize)) цвета, указанного в esi
|
||||
(с учетом градиента)
|
||||
* если ysize>=26, то закрашивается рабочая область окна -
|
||||
прямоугольник с левым верхним углом (5,20) и правым нижним
|
||||
(xsize-5,ysize-5) - цветом, указанным в edx (с учетом градиента)
|
||||
* если A=1 и строка заголовка установлена подфункцией 1
|
||||
функции 71, то она выводится в соответствующем месте заголовка
|
||||
* Вид окна со скином:
|
||||
* Вид окна со скином Y=3,4:
|
||||
* рисуется внешняя рамка шириной 1 пиксель
|
||||
цвета 'outer' из скина
|
||||
* рисуется промежуточная рамка шириной 3 пикселя
|
||||
|
@ -25,19 +25,17 @@ Parameters:
|
||||
* ecx = [coordinate on axis y]*65536 + [size on axis y]
|
||||
* edx = 0xXYRRGGBB, where:
|
||||
* Y = style of the window:
|
||||
* Y=0 - type I - fixed-size window
|
||||
* Y=1 - only define window area, draw nothing
|
||||
* Y=2 - type II - variable-size window
|
||||
* Y=3 - skinned window
|
||||
* Y=4 - skinned fixed-size window
|
||||
* other possible values (from 5 up to 15) are reserved,
|
||||
* Y=0,2 window types are outdated and should not be used anymore,
|
||||
they are retained for compatibility with old programs.
|
||||
* other possible values (from 5 to 15) are reserved,
|
||||
function call with such Y is ignored
|
||||
* RR, GG, BB = accordingly red, green, blue components of a color
|
||||
of the working area of the window (are ignored for style Y=1)
|
||||
* X = DCBA (bits)
|
||||
* A = 1 - window has caption; for styles Y=3,4 caption string
|
||||
must be passed in edi, for other styles use
|
||||
subfunction 1 of function 71
|
||||
* A = 1 - window has caption
|
||||
* B = 1 - coordinates of all graphics primitives are relative to
|
||||
window client area
|
||||
* C = 1 - don't fill working area on window draw
|
||||
@ -47,11 +45,8 @@ Parameters:
|
||||
* esi = 0xXYRRGGBB - color of the header
|
||||
* RR, GG, BB define color
|
||||
* Y=0 - usual window, Y=1 - unmovable window (works for all window styles)
|
||||
* X defines a gradient of header: X=0 - no gradient,
|
||||
X=8 - usual gradient,
|
||||
for windows of a type II X=4 - negative gradient
|
||||
* other values of X and Y are reserved
|
||||
* edi = 0x00RRGGBB - color of the frame
|
||||
* X not used, other values of Y are reserved
|
||||
* edi = caption string for styles Y=3,4 (also can be set by func 71.1)
|
||||
Returned value:
|
||||
* function does not return value
|
||||
Remarks:
|
||||
@ -79,34 +74,9 @@ Remarks:
|
||||
* The sizes of the window are understood in sence of coordinates
|
||||
of the right lower corner. This concerns all other functions too.
|
||||
It means, that the real sizes are on 1 pixel more.
|
||||
* The window of type I looks as follows:
|
||||
* draw external frame of color indicated in edi, 1 pixel in width
|
||||
* draw header - rectangle with the left upper corner (1,1) and
|
||||
right lower (xsize-1,min(20,ysize-1)) color indicated in esi
|
||||
(taking a gradient into account)
|
||||
* if ysize>21, fill the working area of the window -
|
||||
rectangle with the left upper corner (1,21) and right lower
|
||||
(xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color
|
||||
indicated in edx (taking a gradient into account)
|
||||
* if A=1 and caption has been already set by subfunction 1
|
||||
of function 71, it is drawn in the corresponding place of header
|
||||
* The window of style Y=1 looks as follows:
|
||||
* completely defined by the application
|
||||
* The window of type II looks as follows:
|
||||
* draw external frame of width 1 pixel with the "shaded" color
|
||||
edi (all components of the color decrease twice)
|
||||
* draw intermediate frame of width 3 pixels with color edi
|
||||
* draw internal frame of width 1 pixel with the "shaded" color edi
|
||||
* draw header - rectangle with the left upper corner (4,4)
|
||||
and right lower (xsize-4,min(20,ysize)) color, indicated in esi
|
||||
(taking a gradient into account)
|
||||
* if ysize>=26, fill the working area of the window -
|
||||
rectangle with the left upper corner (5,20) and right lower
|
||||
(xsize-5,ysize-5) with color indicated in edx
|
||||
(taking a gradient into account)
|
||||
* if A=1 and caption has been already set by subfunction 1
|
||||
of function 71, it is drawn in the corresponding place of header
|
||||
* The skinned window looks as follows:
|
||||
* The skinned window Y=3,4 looks as follows:
|
||||
* draw external frame of width 1 pixel
|
||||
with color 'outer' from the skin
|
||||
* draw intermediate frame of width 3 pixel
|
||||
@ -4794,14 +4764,31 @@ Parameters:
|
||||
* edx = control value
|
||||
* esi = timeout in system ticks or 0 for infinity
|
||||
Returned value:
|
||||
* eax = 0 - successfull, -1 on timeout
|
||||
|
||||
* eax = 0 - successfull
|
||||
-1 - timeout
|
||||
-2 - futex dword does not have the same value as edx
|
||||
Remarks:
|
||||
* This operation tests that the value at the futex dword still
|
||||
* This functionn tests that the value at the futex dword still
|
||||
contains the expected control value, and if so, then sleeps
|
||||
waiting for a wake operation on the futex.
|
||||
* The futex handle must have been created by subfunction 0
|
||||
|
||||
======================================================================
|
||||
=============== Function 77, Subfunction 3, Futex wake ===============
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 77 - function number
|
||||
* ebx = 3 - subfunction number
|
||||
* ecx = futex handle
|
||||
* edx = number of waiters to wake
|
||||
Returned value:
|
||||
* eax = number of waiters that were woken up
|
||||
|
||||
Remarks:
|
||||
* This function wakes at most edx of the waiters that are
|
||||
waiting (e.g., inside futex wait) on the futex dword
|
||||
* The futex handle must have been created by subfunction 0
|
||||
|
||||
======================================================================
|
||||
=============== Function -1 - terminate thread/process ===============
|
||||
======================================================================
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -455,7 +455,25 @@ ACPI_FADT_SIGN equ 0x50434146
|
||||
|
||||
acpi_locate:
|
||||
push ebx
|
||||
push edi
|
||||
|
||||
movzx ebx, word [0x40E]
|
||||
shl ebx, 4
|
||||
lea ecx, [ebx+1024]
|
||||
call .check
|
||||
|
||||
test ebx, ebx
|
||||
jnz .done
|
||||
|
||||
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:
|
||||
cmp [ebx], dword 0x20445352
|
||||
jne .next
|
||||
@ -472,17 +490,12 @@ acpi_locate:
|
||||
|
||||
test al, al
|
||||
jnz .next
|
||||
|
||||
mov eax, ebx
|
||||
pop ebx
|
||||
ret
|
||||
.next:
|
||||
add ebx, 16
|
||||
cmp ebx, ACPI_HI_RSDP_WINDOW_END
|
||||
cmp ebx, edi
|
||||
jb .check
|
||||
|
||||
pop ebx
|
||||
xor eax, eax
|
||||
xor ebx, ebx
|
||||
ret
|
||||
|
||||
align 4
|
||||
|
@ -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
|
||||
|
||||
@ -2177,7 +2177,7 @@ sys_end:
|
||||
@@:
|
||||
|
||||
mov eax, [TASK_BASE]
|
||||
mov [eax+TASKDATA.state], 3; terminate this program
|
||||
mov [eax+TASKDATA.state], TSTATE_ZOMBIE
|
||||
call wakeup_osloop
|
||||
|
||||
.waitterm: ; wait here for termination
|
||||
@ -3746,7 +3746,7 @@ nobackgr:
|
||||
align 4
|
||||
markz:
|
||||
push ecx edx
|
||||
cmp [edx+TASKDATA.state], 9
|
||||
cmp [edx+TASKDATA.state], TSTATE_FREE
|
||||
jz .nokill
|
||||
lea edx, [(edx-(CURRENT_TASK and 1FFFFFFFh))*8+SLOT_BASE]
|
||||
cmp [edx+APPDATA.process], sys_proc
|
||||
@ -3760,7 +3760,7 @@ markz:
|
||||
pop edx ecx
|
||||
test eax, eax
|
||||
jz @f
|
||||
mov [edx+TASKDATA.state], byte 3
|
||||
mov [edx+TASKDATA.state], TSTATE_ZOMBIE
|
||||
@@:
|
||||
add edx, 0x20
|
||||
loop markz
|
||||
@ -5766,103 +5766,64 @@ yes_shutdown_param:
|
||||
.no_shutdown_cpus:
|
||||
|
||||
cli
|
||||
call IRQ_mask_all
|
||||
|
||||
if ~ defined extended_primary_loader
|
||||
; load kernel.mnt to 0x7000:0
|
||||
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, 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, 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
|
||||
|
||||
; 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]
|
||||
;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'
|
||||
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
|
||||
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+ebp+4000h], '_S5_'
|
||||
cmp dword [esi], '_S5_'
|
||||
jnz .scan_dsdt_cont
|
||||
cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode
|
||||
cmp byte [esi+4], 12h ; DefPackage opcode
|
||||
jnz .scan_dsdt_cont
|
||||
mov dl, [esi+ebp+4000h+6]
|
||||
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+ebp+4000h+7]
|
||||
lea esi, [esi+7]
|
||||
xor ecx, ecx
|
||||
cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx
|
||||
jz @f
|
||||
@ -5884,21 +5845,6 @@ end if
|
||||
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
|
||||
@ -5932,34 +5878,143 @@ do_acpi_power_off:
|
||||
@@:
|
||||
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
|
||||
|
||||
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:
|
||||
@ -5970,7 +6025,7 @@ realmode_gdt:
|
||||
; selector 8 - code from 1000:0000 to 1000:FFFF
|
||||
dw 0FFFFh
|
||||
dw 0
|
||||
db 1
|
||||
db 5
|
||||
db 10011011b
|
||||
db 00000000b
|
||||
db 0
|
||||
@ -5983,6 +6038,8 @@ realmode_gdt:
|
||||
db 0
|
||||
endg
|
||||
|
||||
org $+OS_BASE
|
||||
|
||||
if ~ lang eq sp
|
||||
diff16 "end of .text segment",0,$
|
||||
end if
|
||||
|
@ -634,6 +634,8 @@ ipv4_output:
|
||||
push ecx ax edi
|
||||
mov eax, edi
|
||||
call ipv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
|
||||
test eax, eax
|
||||
jz .no_route
|
||||
push edx
|
||||
test edi, edi
|
||||
jz .loopback
|
||||
@ -683,6 +685,12 @@ ipv4_output:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.no_route:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: No route to host!\n"
|
||||
add esp, 2*4+2
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.arp_error:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
|
||||
add esp, 4
|
||||
@ -917,7 +925,7 @@ endp
|
||||
; ebx = outgoing device / 0 ;
|
||||
; edx = Source IP ;
|
||||
; ;
|
||||
; OUT: eax = Destination IP (or gateway IP) ;
|
||||
; OUT: eax = Destination IP (may be gateway), 0 on error ;
|
||||
; edx = Source IP ;
|
||||
; edi = device number*4 ;
|
||||
; ;
|
||||
@ -926,7 +934,7 @@ endp
|
||||
; ;
|
||||
;-----------------------------------------------------------------;
|
||||
align 4
|
||||
ipv4_route: ; TODO: return error if no valid route found
|
||||
ipv4_route:
|
||||
|
||||
test ebx, ebx
|
||||
jnz .got_device
|
||||
@ -979,6 +987,7 @@ ipv4_route: ; TODO: return error if no valid route found
|
||||
ret
|
||||
|
||||
.fail:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
|
@ -571,10 +571,11 @@ align 4
|
||||
jnz @B
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.ret:
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
endp
|
||||
@ -605,10 +606,11 @@ align 4
|
||||
jnz @B
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.ret:
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
endp
|
||||
|
Loading…
Reference in New Issue
Block a user