kos-acpi: kernel restart reboot and shutdown

git-svn-id: svn://kolibrios.org@6240 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2016-02-17 02:56:18 +00:00
parent d112b67c4c
commit 6e1bd6d91d
12 changed files with 1417 additions and 729 deletions

View File

@ -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,9 +41,10 @@ use16
pr_mode_exit:
; setup stack
mov ax, 0x3000
mov ax, (TMP_STACK_TOP and 0xF0000) shr 4
mov ss, ax
mov esp, 0x0EC00
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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 пикселя

View File

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

View File

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

View File

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

View File

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

View File

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