Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3724 → Rev 3725

/kernel/branches/Kolibri-acpi/blkdev/disk.inc
349,10 → 349,8
inc eax
cmp byte [ebx+eax-1], 0
jnz @b
; 2b. Call the heap manager. Note that it can change ebx.
push ebx
; 2b. Call the heap manager.
call malloc
pop ebx
; 2c. Check the result. If allocation failed, go to 7.
pop esi ; restore allocated pointer to DISK
test eax, eax
/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc
11,7 → 11,8
; Low-level driver for HDD access
; DMA support by Mario79
; Access through BIOS by diamond
 
; LBA48 support by Mario79
;-----------------------------------------------------------------------------
align 4
hd_read:
;-----------------------------------------------------------
21,8 → 22,6
and [hd_error], 0
push ecx esi edi ; scan cache
 
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
call calculate_cache
add esi, 8
 
29,7 → 28,6
mov edi, 1
 
hdreadcache:
 
cmp dword [esi+4], 0; empty
je nohdcache
 
37,7 → 35,6
je yeshdcache
 
nohdcache:
 
add esi, 8
inc edi
dec ecx
49,12 → 46,6
; Read through BIOS?
cmp [hdpos], 0x80
jae .bios
; hd_read_{dma,pio} use old ATA with 28 bit for sector number
cmp eax, 0x10000000
jb @f
inc [hd_error]
jmp return_01
@@:
; DMA read is permitted if [allow_dma_access]=1 or 2
cmp [allow_dma_access], 2
ja .nodma
70,20 → 61,17
@@:
cmp [hd_error], 0
jne return_01
; lea esi,[edi*8+HD_CACHE]
; push eax
 
call calculate_cache_1
lea esi, [edi*8+esi]
; pop eax
 
mov [esi], eax ; sector number
mov dword [esi+4], 1; hd read - mark as same as in hd
 
yeshdcache:
 
mov esi, edi
shl esi, 9
; add esi,HD_CACHE+65536
 
push eax
call calculate_cache_2
add esi, eax
93,18 → 81,33
mov ecx, 512/4
cld
rep movsd ; move data
 
return_01:
pop edi esi ecx
ret
 
;-----------------------------------------------------------------------------
align 4
hd_read_pio:
push eax edx
 
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ;адрес регистра головок
mov al, byte [hdid]
add al, 128+64+32
out dx, al; номер головки/номер диска
call wait_for_hd_idle
cmp [hd_error], 0
jne hd_read_error
 
; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4]
cmp eax, 0x10000000
jae .lba48
;--------------------------------------
.lba28:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
112,36 → 115,78
out dx, al; ATAFeatures регистр "особенностей"
inc edx
inc eax
out dx, al; ATASectorCount счётчик секторов
out dx, al ; ATA Sector Counter счётчик секторов
inc edx
mov eax, [esp+4]
out dx, al; ATASectorNumber регистр номера сектора
mov eax, [esp+4+4]
out dx, al ; LBA Low LBA (7:0)
shr eax, 8
inc edx
out dx, al; ATACylinder номер цилиндра (младший байт)
out dx, al ; LBA Mid LBA (15:8)
shr eax, 8
inc edx
out dx, al; номер цилиндра (старший байт)
out dx, al ; LBA High LBA (23:16)
shr eax, 8
inc edx
and al, 1+2+4+8
and al, 1+2+4+8 ; LBA (27:24)
add al, byte [hdid]
add al, 128+64+32
out dx, al; номер головки/номер диска
inc edx
mov al, 20h
mov al, 20h ; READ SECTOR(S)
out dx, al; ATACommand регистр команд
sti
 
popfd
jmp .continue
;--------------------------------------
.lba48:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al ; Features Previous Reserved
out dx, al ; Features Current Reserved
inc edx
out dx, al ; Sector Count Previous Sector count (15:8)
inc eax
out dx, al ; Sector Count Current Sector count (7:0)
inc edx
mov eax, [esp+4+4]
rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax ; because only 32 bit cache
inc edx
out dx, al ; LBA Mid Previous LBA (39:32)
inc edx
out dx, al ; LBA High Previous LBA (47:40)
sub edx, 2
mov eax, [esp+4+4]
out dx, al ; LBA Low Current LBA (7:0)
shr eax, 8
inc edx
out dx, al ; LBA Mid Current LBA (15:8)
shr eax, 8
inc edx
out dx, al ; LBA High Current LBA (23:16)
inc edx
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
inc edx
mov al, 24h ; READ SECTOR(S) EXT
out dx, al ; ATACommand регистр команд
popfd
;--------------------------------------
.continue:
call wait_for_sector_buffer
 
cmp [hd_error], 0
jne hd_read_error
 
pushfd
cli
push edi
shl edi, 9
; add edi,HD_CACHE+65536
 
push eax
call calculate_cache_2
add edi, eax
152,27 → 197,11
cld
rep insw
pop edi
sti
popfd
 
pop edx eax
ret
 
disable_ide_int:
; mov edx,[hdbase]
; add edx,0x206
; mov al,2
; out dx,al
cli
ret
 
enable_ide_int:
; mov edx,[hdbase]
; add edx,0x206
; mov al,0
; out dx,al
sti
ret
 
;-----------------------------------------------------------------------------
align 4
hd_write:
;-----------------------------------------------------------
182,16 → 211,11
push ecx esi edi
 
; check if the cache already has the sector and overwrite it
 
; mov ecx,cache_max
; mov esi,HD_CACHE+8
call calculate_cache
add esi, 8
 
mov edi, 1
 
hdwritecache:
 
cmp dword [esi+4], 0; if cache slot is empty
je not_in_cache_write
 
199,7 → 223,6
je yes_in_cache_write
 
not_in_cache_write:
 
add esi, 8
inc edi
dec ecx
207,25 → 230,19
 
; sector not found in cache
; write the block to a new location
 
call find_empty_slot ; ret in edi
cmp [hd_error], 0
jne hd_write_access_denied
 
; lea esi,[edi*8+HD_CACHE]
; push eax
call calculate_cache_1
lea esi, [edi*8+esi]
; pop eax
 
mov [esi], eax ; sector number
 
yes_in_cache_write:
 
mov dword [esi+4], 2; write - differs from hd
 
shl edi, 9
; add edi,HD_CACHE+65536
 
push eax
call calculate_cache_2
add edi, eax
235,48 → 252,100
mov ecx, 512/4
cld
rep movsd ; move data
 
hd_write_access_denied:
pop edi esi ecx
ret
 
;-----------------------------------------------------------------------------
align 4
cache_write_pio:
cmp dword[esi], 0x10000000
jae .bad
; call disable_ide_int
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ;адрес регистра головок
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
 
call wait_for_hd_idle
cmp [hd_error], 0
jne hd_write_error
 
; ATA with 28 or 48 bit for sector number?
mov eax, [esi]
cmp eax, 0x10000000
jae .lba48
;--------------------------------------
.lba28:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al
out dx, al ; ATA Features регистр "особенностей"
inc edx
inc eax
out dx, al
out dx, al ; ATA Sector Counter счётчик секторов
inc edx
mov eax, [esi] ; eax = sector to write
out dx, al
out dx, al ; LBA Low LBA (7:0)
shr eax, 8
inc edx
out dx, al
out dx, al ; LBA Mid LBA (15:8)
shr eax, 8
inc edx
out dx, al
out dx, al ; LBA High LBA (23:16)
shr eax, 8
inc edx
and al, 1+2+4+8
and al, 1+2+4+8 ; LBA (27:24)
add al, byte [hdid]
add al, 128+64+32
out dx, al
out dx, al ; номер головки/номер диска
inc edx
mov al, 30h
out dx, al
sti
 
mov al, 30h ; WRITE SECTOR(S)
out dx, al ; ATACommand регистр команд
popfd
jmp .continue
;--------------------------------------
.lba48:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al ; Features Previous Reserved
out dx, al ; Features Current Reserved
inc edx
out dx, al ; Sector Count Previous Sector count (15:8)
inc eax
out dx, al ; Sector Count Current Sector count (7:0)
inc edx
mov eax, [esi]
rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax ; because only 32 bit cache
inc edx
out dx, al ; LBA Mid Previous LBA (39:32)
inc edx
out dx, al ; LBA High Previous LBA (47:40)
sub edx, 2
mov eax, [esi]
out dx, al ; LBA Low Current LBA (7:0)
shr eax, 8
inc edx
out dx, al ; LBA Mid Current LBA (15:8)
shr eax, 8
inc edx
out dx, al ; LBA High Current LBA (23:16)
inc edx
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
inc edx
mov al, 34h ; WRITE SECTOR(S) EXT
out dx, al ; ATACommand регистр команд
popfd
;--------------------------------------
.continue:
call wait_for_sector_buffer
 
cmp [hd_error], 0
284,10 → 353,11
 
push ecx esi
 
pushfd
cli
mov esi, edi
shl esi, 9
; add esi,HD_CACHE+65536 ; esi = from memory position
 
push eax
call calculate_cache_2
add esi, eax
297,18 → 367,13
mov edx, [hdbase]
cld
rep outsw
sti
popfd
 
; call enable_ide_int
pop esi ecx
 
ret
.bad:
inc [hd_error]
ret
 
;-----------------------------------------------------------------------------
align 4
save_hd_wait_timeout:
 
push eax
mov eax, [timer_ticks]
add eax, 300 ; 3 sec timeout
315,47 → 380,29
mov [hd_wait_timeout], eax
pop eax
ret
 
;-----------------------------------------------------------------------------
align 4
check_hd_wait_timeout:
 
push eax
mov eax, [hd_wait_timeout]
cmp [timer_ticks], eax
jg hd_timeout_error
 
pop eax
mov [hd_error], 0
ret
 
;iglobal
; hd_timeout_str db 'K : FS - HD timeout',0
; hd_read_str db 'K : FS - HD read error',0
; hd_write_str db 'K : FS - HD write error',0
; hd_lba_str db 'K : FS - HD LBA error',0
;endg
 
;-----------------------------------------------------------------------------
hd_timeout_error:
 
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_timeout_str
; call sys_msg_board_str
if lang eq sp
DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
else
DEBUGF 1,"K : FS - HD timeout\n"
end if
 
mov [hd_error], 1
pop eax
ret
 
;-----------------------------------------------------------------------------
hd_read_error:
 
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_read_str
; call sys_msg_board_str
if lang eq sp
DEBUGF 1,"K : FS - HD error de lectura\n"
else
363,13 → 410,10
end if
pop edx eax
ret
 
;-----------------------------------------------------------------------------
hd_write_error_dma:
pop esi
hd_write_error:
 
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_write_str
; call sys_msg_board_str
if lang eq sp
DEBUGF 1,"K : FS - HD error de escritura\n"
else
376,25 → 420,8
DEBUGF 1,"K : FS - HD write error\n"
end if
ret
 
hd_write_error_dma:
; call clear_hd_cache
; call clear_application_table_status
; mov esi, hd_write_str
; call sys_msg_board_str
if lang eq sp
DEBUGF 1,"K : FS - HD error de escritura\n"
else
DEBUGF 1,"K : FS - HD write error\n"
end if
pop esi
ret
 
;-----------------------------------------------------------------------------
hd_lba_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_lba_str
; call sys_msg_board_str
if lang eq sp
DEBUGF 1,"K : FS - HD error en LBA\n"
else
401,11 → 428,9
DEBUGF 1,"K : FS - HD LBA error\n"
end if
jmp LBA_read_ret
 
 
;-----------------------------------------------------------------------------
align 4
wait_for_hd_idle:
 
push eax edx
 
call save_hd_wait_timeout
412,9 → 437,9
 
mov edx, [hdbase]
add edx, 0x7
 
;--------------------------------------
align 4
wfhil1:
 
call check_hd_wait_timeout
cmp [hd_error], 0
jne @f
424,14 → 449,11
jnz wfhil1
 
@@:
 
pop edx eax
ret
 
 
;-----------------------------------------------------------------------------
align 4
wait_for_sector_buffer:
 
push eax edx
 
mov edx, [hdbase]
438,9 → 460,9
add edx, 0x7
 
call save_hd_wait_timeout
 
;--------------------------------------
align 4
hdwait_sbuf: ; wait for sector buffer to be ready
 
call check_hd_wait_timeout
cmp [hd_error], 0
jne @f
460,16 → 482,16
mov [hd_error], 1
 
buf_wait_ok:
 
pop edx eax
ret
 
; \begin{Mario79}
;-----------------------------------------------------------------------------
align 4
wait_for_sector_dma_ide0:
push eax
push edx
call save_hd_wait_timeout
;--------------------------------------
align 4
.wait:
call change_task
cmp [irq14_func], hdd_irq14
485,12 → 507,14
pop edx
pop eax
ret
 
;-----------------------------------------------------------------------------
align 4
wait_for_sector_dma_ide1:
push eax
push edx
call save_hd_wait_timeout
;--------------------------------------
align 4
.wait:
call change_task
cmp [irq15_func], hdd_irq15
507,7 → 531,7
pop edx
pop eax
ret
 
;-----------------------------------------------------------------------------
iglobal
align 4
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
521,7 → 545,7
irq14_func dd hdd_irq_null
irq15_func dd hdd_irq_null
endg
 
;-----------------------------------------------------------------------------
uglobal
; all uglobals are zeroed at boot
dma_process dd 0
534,7 → 558,7
dma_hdd db 0
allow_dma_access db 0
endg
 
;-----------------------------------------------------------------------------
align 4
hdd_irq14:
pushfd
544,27 → 568,12
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
; call update_counters
; mov ebx, [dma_process]
; cmp [CURRENT_TASK], ebx
; jz .noswitch
; mov [dma_task_switched], 1
; mov edi, [dma_slot_ptr]
; mov eax, [CURRENT_TASK]
; mov [dma_process], eax
; mov eax, [TASK_BASE]
; mov [dma_slot_ptr], eax
; mov [CURRENT_TASK], ebx
; mov [TASK_BASE], edi
; mov byte [DONT_SWITCH], 1
; call do_change_task
.noswitch:
popad
popfd
align 4
hdd_irq_null:
ret
 
;-----------------------------------------------------------------------------
align 4
hdd_irq15:
pushfd
575,25 → 584,10
add dx, 8
mov al, 0
out dx, al
; call update_counters
; mov ebx, [dma_process]
; cmp [CURRENT_TASK], ebx
; jz .noswitch
; mov [dma_task_switched], 1
; mov edi, [dma_slot_ptr]
; mov eax, [CURRENT_TASK]
; mov [dma_process], eax
; mov eax, [TASK_BASE]
; mov [dma_slot_ptr], eax
; mov [CURRENT_TASK], ebx
; mov [TASK_BASE], edi
; mov byte [DONT_SWITCH], 1
; call do_change_task
.noswitch:
popad
popfd
ret
 
;-----------------------------------------------------------------------------
align 4
hd_read_dma:
push eax
614,7 → 608,7
push ecx esi edi
mov esi, eax
shl edi, 9
; add edi, HD_CACHE+0x10000
 
push eax
call calculate_cache_2
add edi, eax
646,37 → 640,97
add edx, 2
mov al, 6
out dx, al
 
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ; адрес регистра головок
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
 
call wait_for_hd_idle
cmp [hd_error], 0
jnz hd_read_error
call disable_ide_int
 
; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4]
; -10h because the PreCache hits the boundary between lba28 and lba48
; 10h = 16 - size of PreCache
cmp eax, 0x10000000-10h
jae .lba48
;--------------------------------------
.lba28:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al
out dx, al ; ATA Features регистр "особенностей"
inc edx
mov eax, 10h
out dx, al
mov eax, 10h ; Sector Counter = 16 ; PreCache
out dx, al ; ATA Sector Counter счётчик секторов
inc edx
mov eax, [esp+4]
out dx, al
mov eax, [esp+4+4]
out dx, al ; LBA Low LBA (7:0)
shr eax, 8
inc edx
out dx, al
out dx, al ; LBA Mid LBA (15:8)
shr eax, 8
inc edx
out dx, al
out dx, al ; LBA High LBA (23:16)
shr eax, 8
inc edx
and al, 0xF
and al, 0xF ; LBA (27:24)
add al, byte [hdid]
add al, 11100000b
out dx, al
out dx, al ; номер головки/номер диска
inc edx
mov al, 0xC8
out dx, al
mov al, 0xC8 ; READ DMA
out dx, al ; ATACommand регистр команд
jmp .continue
;--------------------------------------
.lba48:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al ; Features Previous Reserved
out dx, al ; Features Current Reserved
inc edx
out dx, al ; Sector Count Previous Sector count (15:8)
mov eax, 10h ; Sector Counter = 16 PreCache
out dx, al ; Sector Count Current Sector count (7:0)
inc edx
mov eax, [esp+4+4]
rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax ; because only 32 bit cache
inc edx
out dx, al ; LBA Mid Previous LBA (39:32)
inc edx
out dx, al ; LBA High Previous LBA (47:40)
sub edx, 2
mov eax, [esp+4+4]
out dx, al ; LBA Low Current LBA (7:0)
shr eax, 8
inc edx
out dx, al ; LBA Mid Current LBA (15:8)
shr eax, 8
inc edx
out dx, al ; LBA High Current LBA (23:16)
inc edx
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
inc edx
mov al, 25h ; READ DMA EXT
out dx, al ; ATACommand регистр команд
;--------------------------------------
.continue:
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jz @f
add dx, 8
@@:
686,7 → 740,8
mov [dma_process], eax
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
cmp [hdbase], 0x1F0
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
jmp @f
693,8 → 748,9
.ide1:
mov [irq15_func], hdd_irq15
@@:
call enable_ide_int
cmp [hdbase], 0x1F0
popfd
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .wait_ide1
call wait_for_sector_dma_ide0
jmp @f
709,17 → 765,17
pop eax
mov [dma_cur_sector], eax
jmp hd_read_dma
 
;-----------------------------------------------------------------------------
align 4
write_cache_sector:
mov [cache_chain_size], 1
mov [cache_chain_pos], edi
;--------------------------------------
align 4
write_cache_chain:
cmp [hdpos], 0x80
jae bd_write_cache_chain
mov eax, [cache_chain_ptr]
cmp dword[eax], 0x10000000
jae .bad
push esi
mov eax, IDE_descriptor_table
mov edx, eax
752,38 → 808,98
add edx, 2
mov al, 6
out dx, al
 
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ; адрес регистра головок
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
 
call wait_for_hd_idle
cmp [hd_error], 0
jnz hd_write_error_dma
call disable_ide_int
 
; ATA with 28 or 48 bit for sector number?
mov esi, [cache_chain_ptr]
mov eax, [esi]
; -40h because the PreCache hits the boundary between lba28 and lba48
; 40h = 64 - the maximum number of sectors to be written for one command
cmp eax, 0x10000000-40h
jae .lba48
;--------------------------------------
.lba28:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al
out dx, al ; ATA Features регистр "особенностей"
inc edx
mov al, [cache_chain_size]
out dx, al
mov al, [cache_chain_size] ; Sector Counter
out dx, al ; ATA Sector Counter счётчик секторов
inc edx
mov esi, [cache_chain_ptr]
mov eax, [esi]
out dx, al
out dx, al ; LBA Low LBA (7:0)
shr eax, 8
inc edx
out dx, al
out dx, al ; LBA Mid LBA (15:8)
shr eax, 8
inc edx
out dx, al
out dx, al ; LBA High LBA (23:16)
shr eax, 8
inc edx
and al, 0xF
and al, 0xF ; LBA (27:24)
add al, byte [hdid]
add al, 11100000b
out dx, al
out dx, al ; номер головки/номер диска
inc edx
mov al, 0xCA
out dx, al
mov al, 0xCA ; WRITE DMA
out dx, al ; ATACommand регистр команд
jmp .continue
;--------------------------------------
.lba48:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al ; Features Previous Reserved
out dx, al ; Features Current Reserved
inc edx
out dx, al ; Sector Count Previous Sector count (15:8)
mov al, [cache_chain_size] ; Sector Counter
out dx, al ; Sector Count Current Sector count (7:0)
inc edx
mov eax, [esi]
rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax ; because only 32 bit cache
inc edx
out dx, al ; LBA Mid Previous LBA (39:32)
inc edx
out dx, al ; LBA High Previous LBA (47:40)
sub edx, 2
mov eax, [esi]
out dx, al ; LBA Low Current LBA (7:0)
shr eax, 8
inc edx
out dx, al ; LBA Mid Current LBA (15:8)
shr eax, 8
inc edx
out dx, al ; LBA High Current LBA (23:16)
inc edx
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
inc edx
mov al, 35h ; WRITE DMA EXT
out dx, al ; ATACommand регистр команд
;--------------------------------------
.continue:
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jz @f
add dx, 8
@@:
793,7 → 909,8
mov [dma_process], eax
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
cmp [hdbase], 0x1F0
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
jmp @f
800,9 → 917,10
.ide1:
mov [irq15_func], hdd_irq15
@@:
call enable_ide_int
popfd
mov [dma_cur_sector], not 0x40
cmp [hdbase], 0x1F0
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .wait_ide1
call wait_for_sector_dma_ide0
jmp @f
813,15 → 931,16
jnz hd_write_error_dma
pop esi
ret
.bad:
inc [hd_error]
ret
 
;-----------------------------------------------------------------------------
uglobal
IDEContrRegsBaseAddr dw ?
IDEContrProgrammingInterface dw ?
IDE_BAR0_val dw ?
IDE_BAR1_val dw ?
IDE_BAR2_val dw ?
IDE_BAR3_val dw ?
endg
; \end{Mario79}
 
;-----------------------------------------------------------------------------
; \begin{diamond}
uglobal
bios_hdpos dd 0 ; 0 is invalid value for [hdpos]
828,6 → 947,8
bios_cur_sector dd ?
bios_read_len dd ?
endg
;-----------------------------------------------------------------------------
align 4
bd_read:
push eax
push edx
847,7 → 968,7
push ecx esi edi
mov esi, eax
shl edi, 9
; add edi, HD_CACHE+0x10000
 
push eax
call calculate_cache_2
add edi, eax
881,7 → 1002,8
.v86err:
mov [hd_error], 1
jmp hd_read_error
 
;-----------------------------------------------------------------------------
align 4
bd_write_cache_chain:
pusha
mov esi, [cache_chain_pos]
909,12 → 1031,13
popa
mov [hd_error], 1
jmp hd_write_error
 
;-----------------------------------------------------------------------------
uglobal
int13_regs_in rb sizeof.v86_regs
int13_regs_out rb sizeof.v86_regs
endg
 
;-----------------------------------------------------------------------------
align 4
int13_call:
; Because this code uses fixed addresses,
; it can not be run simultaniously by many threads.
965,9 → 1088,9
@@:
ret
; \end{diamond}
 
;-----------------------------------------------------------------------------
align 4
reserve_hd1:
 
cli
cmp [hd1_status], 0
je reserve_ok1
977,7 → 1100,6
jmp reserve_hd1
 
reserve_ok1:
 
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
986,12 → 1108,12
pop eax
sti
ret
;********************************************
 
;-----------------------------------------------------------------------------
uglobal
hd_in_cache db ?
endg
 
;-----------------------------------------------------------------------------
align 4
reserve_hd_channel:
; BIOS disk accesses are protected with common mutex hd1_status
; This must be modified when hd1_status will not be valid!
1030,7 → 1152,7
sti
.ret:
ret
 
;-----------------------------------------------------------------------------
free_hd_channel:
; see comment at reserve_hd_channel
cmp [hdpos], 0x80
1044,4 → 1166,4
.IDE_Channel_2:
mov [IDE_Channel_2], 0
ret
;********************************************
;-----------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc
136,14 → 136,7
ret
;--------------------------------------------------------------------
align 4
clear_hd_cache:
ret
;--------------------------------------------------------------------
align 4
calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
221,7 → 214,6
;--------------------------------------------------------------------
align 4
calculate_cache_1:
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
290,7 → 282,6
;--------------------------------------------------------------------
align 4
calculate_cache_2:
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
644,9 → 635,6
;--------------------------------------------------------------------
align 4
cd_calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
697,7 → 685,6
;--------------------------------------------------------------------
align 4
cd_calculate_cache_1:
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
740,7 → 727,6
;--------------------------------------------------------------------
align 4
cd_calculate_cache_2:
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
/kernel/branches/Kolibri-acpi/boot/bootcode.inc
387,7 → 387,12
 
push 0
pop es
and word [es:BOOT_IDE_BASE_ADDR], 0
xor ax, ax
and word [es:BOOT_IDE_BASE_ADDR], ax ;0
and word [es:BOOT_IDE_BAR0_16], ax ;0
and word [es:BOOT_IDE_BAR1_16], ax ;0
and word [es:BOOT_IDE_BAR2_16], ax ;0
and word [es:BOOT_IDE_BAR3_16], ax ;0
; \begin{Mario79}
; find HDD IDE DMA PCI device
; check for PCI BIOS
400,14 → 405,17
; class 1 = mass storage
; subclass 1 = IDE controller
; a) class 1, subclass 1, programming interface 0x80
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x80
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found
; b) class 1, subclass 1, programming interface 0x8A
jnc .found_1 ; Parallel IDE Controller
; b) class 1, subclass 1, programming interface 0x8f
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8A
mov ecx, 1*10000h + 1*100h + 0x8f
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found
414,17 → 422,68
; c) class 1, subclass 1, programming interface 0x85
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x85
xor si, si
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jc .nopci
.found:
; get memory base
jnc .found
; d) class 1, subclass 1, programming interface 0x8A
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8A
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1 ; Parallel IDE Controller
 
jmp .nopci
.found_1:
; get memory base BAR4
mov ax, 0xB10A
mov di, 0x20 ; memory base is config register at 0x20
push cx
int 0x1A
jc .nopci
jc .no_BAR4 ;.nopci
and cx, 0xFFF0 ; clear address decode type
mov [es:BOOT_IDE_BASE_ADDR], cx
.no_BAR4:
pop cx
.found:
; get memory base BAR0
mov ax, 0xB10A
mov di, 0x10 ; memory base is config register at 0x10
push cx
int 0x1A
jc .no_BAR0 ;.nopci
mov [es:BOOT_IDE_BAR0_16], cx
.no_BAR0:
pop cx
; get memory base BAR1
mov ax, 0xB10A
mov di, 0x14 ; memory base is config register at 0x14
push cx
int 0x1A
jc .no_BAR1 ;.nopci
mov [es:BOOT_IDE_BAR1_16], cx
.no_BAR1:
pop cx
; get memory base BAR2
mov ax, 0xB10A
mov di, 0x18 ; memory base is config register at 0x18
push cx
int 0x1A
jc .no_BAR2 ;.nopci
mov [es:BOOT_IDE_BAR2_16], cx
.no_BAR2:
pop cx
; get memory base BAR3
mov ax, 0xB10A
mov di, 0x1C ; memory base is config register at 0x1c
push cx
int 0x1A
jc .no_BAR3 ;.nopci
mov [es:BOOT_IDE_BAR3_16], cx
.no_BAR3:
pop cx
.nopci:
; \end{Mario79}
 
550,8 → 609,8
; following 4 lines set variables to 1 if its current value is 0
cmp byte [di+preboot_dma-preboot_device], 1
adc byte [di+preboot_dma-preboot_device], 0
cmp byte [di+preboot_biosdisk-preboot_device], 1
adc byte [di+preboot_biosdisk-preboot_device], 0
; cmp byte [di+preboot_biosdisk-preboot_device], 1
; adc byte [di+preboot_biosdisk-preboot_device], 0
;; default value for VRR is OFF
; cmp byte [di+preboot_vrrm-preboot_device], 0
; jnz @f
/kernel/branches/Kolibri-acpi/bus/usb/ehci.inc
81,27 → 81,21
; * The hardware requires 32-bytes alignment of the hardware part, so
; the entire descriptor must be 32-bytes aligned. Since the allocator
; (usb_allocate_common) allocates memory sequentially from page start
; (aligned on 0x1000 bytes), size of the structure must be divisible by 32.
; (aligned on 0x1000 bytes), block size for the allocator must be divisible
; by 32; ehci_alloc_td ensures this.
; * The hardware also requires that the hardware part must not cross page
; boundary; the allocator satisfies this automatically.
struct ehci_gtd ehci_hardware_td
Flags dd ?
; Copy of flags from the call to usb_*_transfer_async.
SoftwarePart rd sizeof.usb_gtd/4
; Software part, common for all controllers.
rd 3 ; padding
ends
 
if sizeof.ehci_gtd mod 32
.err ehci_gtd must be 32-bytes aligned
end if
 
; EHCI-specific part of a pipe descriptor.
; * This structure corresponds to the Queue Head from the EHCI specification.
; * The hardware requires 32-bytes alignment of the hardware part.
; Since the allocator (usb_allocate_common) allocates memory sequentially
; from page start (aligned on 0x1000 bytes), size of the structure must be
; divisible by 32.
; from page start (aligned on 0x1000 bytes), block size for the allocator
; must be divisible by 32; ehci_alloc_pipe ensures this.
; * The hardware requires also that the hardware part must not cross page
; boundary; the allocator satisfies this automatically.
struct ehci_pipe
154,15 → 148,8
; from the new TD, if any.
BaseList dd ?
; Pointer to head of the corresponding pipe list.
SoftwarePart rd sizeof.usb_pipe/4
; Software part, common for all controllers.
rd 2 ; padding
ends
 
if sizeof.ehci_pipe mod 32
.err ehci_pipe must be 32-bytes aligned
end if
 
; This structure describes the static head of every list of pipes.
; The hardware requires 32-bytes alignment of this structure.
; All instances of this structure are located sequentially in ehci_controller,
764,7 → 751,7
; and stores USB device address in the ehci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
proc ehci_set_device_address
mov byte [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart], cl
mov byte [ebx+ehci_pipe.Token-sizeof.ehci_pipe], cl
call usb_subscribe_control
ret
endp
773,7 → 760,7
; in: esi -> usb_controller, ebx -> usb_pipe
; out: eax = endpoint address
proc ehci_get_device_address
mov eax, [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
mov eax, [ebx+ehci_pipe.Token-sizeof.ehci_pipe]
and eax, 7Fh
ret
endp
793,11 → 780,11
; stores the packet size in ehci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
proc ehci_set_endpoint_packet_size
mov eax, [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
mov eax, [ebx+ehci_pipe.Token-sizeof.ehci_pipe]
and eax, not (0x7FF shl 16)
shl ecx, 16
or eax, ecx
mov [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart], eax
mov [ebx+ehci_pipe.Token-sizeof.ehci_pipe], eax
; Wait until hardware cache is evicted.
call usb_subscribe_control
ret
818,10 → 805,10
proc ehci_alloc_pipe
push ebx
mov ebx, ehci_ep_mutex
stdcall usb_allocate_common, sizeof.ehci_pipe
stdcall usb_allocate_common, (sizeof.ehci_pipe + sizeof.usb_pipe + 1Fh) and not 1Fh
test eax, eax
jz @f
add eax, ehci_pipe.SoftwarePart
add eax, sizeof.ehci_pipe
@@:
pop ebx
ret
834,7 → 821,7
dd ? ; return address
.ptr dd ?
end virtual
sub [.ptr], ehci_pipe.SoftwarePart
sub [.ptr], sizeof.ehci_pipe
jmp usb_free_common
endp
 
853,9 → 840,9
end virtual
; 1. Zero all fields in the hardware part.
push eax ecx
sub edi, ehci_pipe.SoftwarePart
sub edi, sizeof.ehci_pipe
xor eax, eax
movi ecx, ehci_pipe.SoftwarePart/4
movi ecx, sizeof.ehci_pipe/4
rep stosd
pop ecx eax
; 2. Setup PID in the first TD and make sure that the it is not active.
862,16 → 849,16
xor edx, edx
test byte [.endpoint], 80h
setnz dh
mov [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], edx
mov [eax+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], 1
mov [eax+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], 1
mov [eax+ehci_gtd.Token-sizeof.ehci_gtd], edx
mov [eax+ehci_gtd.NextTD-sizeof.ehci_gtd], 1
mov [eax+ehci_gtd.AlternateNextTD-sizeof.ehci_gtd], 1
; 3. Store physical address of the first TD.
sub eax, ehci_gtd.SoftwarePart
sub eax, sizeof.ehci_gtd
call get_phys_addr
mov [edi+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart], eax
mov [edi+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe], eax
; 4. Fill ehci_pipe.Flags except for S- and C-masks.
; Copy location from the config pipe.
mov eax, [ecx+ehci_pipe.Flags-ehci_pipe.SoftwarePart]
mov eax, [ecx+ehci_pipe.Flags-sizeof.ehci_pipe]
and eax, 3FFF0000h
; Use 1 requests per microframe for control/bulk endpoints,
; use value from the endpoint descriptor for periodic endpoints
884,9 → 871,9
@@:
shl edx, 30
or eax, edx
mov [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart], eax
mov [edi+ehci_pipe.Flags-sizeof.ehci_pipe], eax
; 5. Fill ehci_pipe.Token.
mov eax, [ecx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
mov eax, [ecx+ehci_pipe.Token-sizeof.ehci_pipe]
; copy following fields from the config pipe:
; DeviceAddress, EndpointSpeed, ControlEndpoint if new type is control
mov ecx, eax
915,7 → 902,7
@@:
or eax, 40000000h
.nonak:
mov [edi+ehci_pipe.Token-ehci_pipe.SoftwarePart], eax
mov [edi+ehci_pipe.Token-sizeof.ehci_pipe], eax
; 5. Select the corresponding list and insert to the list.
; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
lea edx, [esi+ehci_controller.ControlED.SoftwarePart-sizeof.ehci_controller]
931,7 → 918,7
; another for split transactions.
; This could fail if the requested bandwidth is not available;
; if so, return an error.
test word [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart+2], 3FFFh
test word [edi+ehci_pipe.Flags-sizeof.ehci_pipe+2], 3FFFh
jnz .interrupt_fs
call ehci_select_hs_interrupt_list
jmp .interrupt_common
940,9 → 927,9
.interrupt_common:
test edx, edx
jz .return0
mov word [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart], ax
mov word [edi+ehci_pipe.Flags-sizeof.ehci_pipe], ax
.insert:
mov [edi+ehci_pipe.BaseList-ehci_pipe.SoftwarePart], edx
mov [edi+ehci_pipe.BaseList-sizeof.ehci_pipe], edx
; Insert to the head of the corresponding list.
; Note: inserting to the head guarantees that the list traverse in
; ehci_process_updated_schedule, once started, will not interact with new pipes.
957,8 → 944,8
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
; store the physical address of the new pipe to previous NextQH.
mov ecx, [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart]
mov [edi+ehci_pipe.NextQH-ehci_pipe.SoftwarePart], ecx
lea eax, [edi-ehci_pipe.SoftwarePart]
mov [edi+ehci_pipe.NextQH-sizeof.ehci_pipe], ecx
lea eax, [edi-sizeof.ehci_pipe]
call get_phys_addr
inc eax
inc eax
1058,15 → 1045,21
; this corresponds to 4001h bytes. If the requested size is
; greater, we should split the transfer into several descriptors.
; Boundaries to split must be multiples of endpoint transfer size
; to avoid short packets except in the end of the transfer,
; 4000h is always a good value.
; to avoid short packets except in the end of the transfer.
cmp [size], 4001h
jbe .lastpacket
; 2. While the remaining data cannot fit in one descriptor,
; allocate full descriptors (of maximal possible size).
mov edi, 4000h
; 2a. Calculate size of one descriptor: must be a multiple of transfer size
; and must be not greater than 4001h.
movzx ecx, word [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe]
mov eax, 4001h
xor edx, edx
mov edi, eax
div ecx
sub edi, edx
mov [packetSize], edi
.fullpackets:
cmp [size], edi
jbe .lastpacket
call ehci_alloc_packet
test eax, eax
jz .fail
1073,7 → 1066,8
mov [td], eax
add [buffer], edi
sub [size], edi
jmp .fullpackets
cmp [size], 4001h
ja .fullpackets
; 3. The remaining data can fit in one packet;
; allocate the last descriptor with size = size of remaining data.
.lastpacket:
1084,7 → 1078,7
jz .fail
; 9. Update flags in the last packet.
mov edx, [flags]
mov [ecx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], edx
mov [ecx+ehci_gtd.Flags-sizeof.ehci_gtd], edx
; 10. Fill AlternateNextTD field in all allocated TDs.
; If the caller says that short transfer is ok, the queue must advance to
; the next descriptor, which is in eax.
1093,7 → 1087,7
push eax
test dl, 1
jz .disable_short
sub eax, ehci_gtd.SoftwarePart
sub eax, sizeof.ehci_gtd
jmp @f
.disable_short:
mov eax, [ebx+usb_pipe.Controller]
1104,7 → 1098,7
@@:
cmp edx, [esp]
jz @f
mov [edx+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], eax
mov [edx+ehci_gtd.AlternateNextTD-sizeof.ehci_gtd], eax
mov edx, [edx+usb_gtd.NextVirt]
jmp @b
@@:
1144,28 → 1138,28
call usb_init_transfer
pop eax
; 3. Copy PID to the new descriptor.
mov edx, [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
mov [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], edx
mov [eax+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], 1
mov [eax+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], 1
mov edx, [ecx+ehci_gtd.Token-sizeof.ehci_gtd]
mov [eax+ehci_gtd.Token-sizeof.ehci_gtd], edx
mov [eax+ehci_gtd.NextTD-sizeof.ehci_gtd], 1
mov [eax+ehci_gtd.AlternateNextTD-sizeof.ehci_gtd], 1
; 4. Save the returned value (next descriptor).
push eax
; 5. Store the physical address of the next descriptor.
sub eax, ehci_gtd.SoftwarePart
sub eax, sizeof.ehci_gtd
call get_phys_addr
mov [ecx+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], eax
mov [ecx+ehci_gtd.NextTD-sizeof.ehci_gtd], eax
; 6. For zero-length transfers, store zero in all fields for buffer addresses.
; Otherwise, fill them with real values.
xor eax, eax
mov [ecx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], eax
mov [ecx+ehci_gtd.Flags-sizeof.ehci_gtd], eax
repeat 10
mov [ecx+ehci_gtd.BufferPointers-ehci_gtd.SoftwarePart+(%-1)*4], eax
mov [ecx+ehci_gtd.BufferPointers-sizeof.ehci_gtd+(%-1)*4], eax
end repeat
cmp [.packetSize], eax
jz @f
mov eax, [.buffer]
call get_phys_addr
mov [ecx+ehci_gtd.BufferPointers-ehci_gtd.SoftwarePart], eax
mov [ecx+ehci_gtd.BufferPointers-sizeof.ehci_gtd], eax
and eax, 0xFFF
mov edx, [.packetSize]
add edx, eax
1174,25 → 1168,25
mov eax, [.buffer]
add eax, 0x1000
call get_pg_addr
mov [ecx+ehci_gtd.BufferPointers+4-ehci_gtd.SoftwarePart], eax
mov [ecx+ehci_gtd.BufferPointers+4-sizeof.ehci_gtd], eax
sub edx, 0x1000
jbe @f
mov eax, [.buffer]
add eax, 0x2000
call get_pg_addr
mov [ecx+ehci_gtd.BufferPointers+8-ehci_gtd.SoftwarePart], eax
mov [ecx+ehci_gtd.BufferPointers+8-sizeof.ehci_gtd], eax
sub edx, 0x1000
jbe @f
mov eax, [.buffer]
add eax, 0x3000
call get_pg_addr
mov [ecx+ehci_gtd.BufferPointers+12-ehci_gtd.SoftwarePart], eax
mov [ecx+ehci_gtd.BufferPointers+12-sizeof.ehci_gtd], eax
sub edx, 0x1000
jbe @f
mov eax, [.buffer]
add eax, 0x4000
call get_pg_addr
mov [ecx+ehci_gtd.BufferPointers+16-ehci_gtd.SoftwarePart], eax
mov [ecx+ehci_gtd.BufferPointers+16-sizeof.ehci_gtd], eax
@@:
; 7. Fill Token field:
; set Status = 0 (inactive, ehci_insert_transfer would mark everything active);
1202,7 → 1196,7
; set current page to 0;
; do not interrupt on complete (ehci_insert_transfer sets this bit where needed);
; set DataToggle to bit 2 of [.direction].
mov eax, [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
mov eax, [ecx+ehci_gtd.Token-sizeof.ehci_gtd]
and eax, 300h ; keep PID code
mov edx, [.direction]
test edx, edx
1222,7 → 1216,7
mov edx, [.packetSize]
shl edx, 16
or eax, edx
mov [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart], eax
mov [ecx+ehci_gtd.Token-sizeof.ehci_gtd], eax
; 4. Restore the returned value saved in step 2.
pop eax
.nothing:
1234,10 → 1228,10
; ehci_alloc_transfer.
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
proc ehci_insert_transfer
or byte [ecx+ehci_gtd.Token+1-ehci_gtd.SoftwarePart], 80h ; set IOC bit
or byte [ecx+ehci_gtd.Token+1-sizeof.ehci_gtd], 80h ; set IOC bit
mov eax, [esp+4]
.activate:
or byte [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], 80h ; set Active bit
or byte [eax+ehci_gtd.Token-sizeof.ehci_gtd], 80h ; set Active bit
cmp eax, ecx
mov eax, [eax+usb_gtd.NextVirt]
jnz .activate
1328,7 → 1322,7
.found_hs_hub:
mov edx, [edx+usb_hub.ConfigPipe]
inc ecx
mov edx, [edx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
mov edx, [edx+ehci_pipe.Token-sizeof.ehci_pipe]
shl ecx, 23
and edx, 7Fh
shl edx, 16
1338,15 → 1332,15
.common:
; 5. Create pseudo-pipe in the stack.
; See ehci_init_pipe: only .Controller, .Token, .Flags fields are used.
push esi ; ehci_pipe.SoftwarePart.Controller
push esi ; usb_pipe.Controller
mov ecx, esp
sub esp, ehci_pipe.SoftwarePart - ehci_pipe.Flags - 4
sub esp, sizeof.ehci_pipe - ehci_pipe.Flags - 4
push edx ; ehci_pipe.Flags
push eax ; ehci_pipe.Token
; 6. Notify the protocol layer.
call usb_new_device
; 7. Cleanup the stack after step 5 and return.
add esp, ehci_pipe.SoftwarePart - ehci_pipe.Flags + 8
add esp, sizeof.ehci_pipe - ehci_pipe.Flags + 8
pop ecx ebx ; restore used registers
ret
endp
1658,7 → 1652,7
; if either of conditions holds, exit from the internal loop.
cmp ebx, [esp]
jz .tddone
cmp byte [ebx+ehci_gtd.Token-ehci_gtd.SoftwarePart], 0
cmp byte [ebx+ehci_gtd.Token-sizeof.ehci_gtd], 0
js .tddone
; Release the queue lock while processing one descriptor:
; callback function could (and often would) schedule another transfer.
1690,7 → 1684,7
; cmp [eax+usb_pipe.Type], INTERRUPT_PIPE
; jnz @f
; DEBUGF 1,'K : finalized TD for pipe %x:\n',eax
; lea eax, [ebx-ehci_gtd.SoftwarePart]
; lea eax, [ebx-sizeof.ehci_gtd]
; DEBUGF 1,'K : %x %x %x %x\n',[eax],[eax+4],[eax+8],[eax+12]
; DEBUGF 1,'K : %x %x %x %x\n',[eax+16],[eax+20],[eax+24],[eax+28]
;@@:
1697,7 → 1691,7
; 1. Remove this descriptor from the list of descriptors for this pipe.
call usb_unlink_td
; 2. Calculate actual number of bytes transferred.
mov eax, [ebx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
mov eax, [ebx+ehci_gtd.Token-sizeof.ehci_gtd]
lea edx, [eax+eax]
shr edx, 17
sub edx, [ebx+usb_gtd.Length]
1715,7 → 1709,7
xor ecx, ecx
test al, 40h
jnz .error
test byte [ebx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], 1
test byte [ebx+ehci_gtd.Flags-sizeof.ehci_gtd], 1
jnz .notify
cmp edx, [ebx+usb_gtd.Length]
jnz .special
1745,7 → 1739,7
ret
.error:
push ebx
sub ebx, ehci_gtd.SoftwarePart
sub ebx, sizeof.ehci_gtd
DEBUGF 1,'K : TD failed:\n'
DEBUGF 1,'K : %x %x %x %x\n',[ebx],[ebx+4],[ebx+8],[ebx+12]
DEBUGF 1,'K : %x %x %x %x\n',[ebx+16],[ebx+20],[ebx+24],[ebx+28]
1752,7 → 1746,7
pop ebx
DEBUGF 1,'K : pipe now:\n'
mov ecx, [ebx+usb_gtd.Pipe]
sub ecx, ehci_pipe.SoftwarePart
sub ecx, sizeof.ehci_pipe
DEBUGF 1,'K : %x %x %x %x\n',[ecx],[ecx+4],[ecx+8],[ecx+12]
DEBUGF 1,'K : %x %x %x %x\n',[ecx+16],[ecx+20],[ecx+24],[ecx+28]
DEBUGF 1,'K : %x %x %x %x\n',[ecx+32],[ecx+36],[ecx+40],[ecx+44]
1802,7 → 1796,7
; it is not an error; in this case, go to 4 with ecx = 0.
cmp ecx, USB_STATUS_UNDERRUN
jnz @f
test byte [ebx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], 1
test byte [ebx+ehci_gtd.Flags-sizeof.ehci_gtd], 1
jz @f
xor ecx, ecx
pop edx ; length
1832,20 → 1826,20
; to the next transfer. (According to the standard, "A control pipe may also
; support functional stall as well, but this is not recommended.").
mov edx, [ebx+usb_gtd.Pipe]
mov eax, [ebx+ehci_gtd.NextTD-ehci_gtd.SoftwarePart]
mov eax, [ebx+ehci_gtd.NextTD-sizeof.ehci_gtd]
or al, 1
mov [edx+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart], eax
mov [edx+ehci_pipe.Overlay.AlternateNextTD-ehci_pipe.SoftwarePart], eax
mov [edx+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe], eax
mov [edx+ehci_pipe.Overlay.AlternateNextTD-sizeof.ehci_pipe], eax
cmp [edx+usb_pipe.Type], CONTROL_PIPE
jz .control
; Bulk/interrupt transfer; halt the queue.
mov [edx+ehci_pipe.Overlay.Token-ehci_pipe.SoftwarePart], 40h
mov [edx+ehci_pipe.Overlay.Token-sizeof.ehci_pipe], 40h
pop edx
jmp .notify
; Control transfer.
.control:
and [edx+ehci_pipe.Overlay.Token-ehci_pipe.SoftwarePart], 0
dec [edx+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart]
and [edx+ehci_pipe.Overlay.Token-sizeof.ehci_pipe], 0
dec [edx+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe]
pop edx
jmp .notify
endp
1855,7 → 1849,7
proc ehci_unlink_pipe
cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE
jnz @f
test word [ebx+ehci_pipe.Flags-ehci_pipe.SoftwarePart+2], 3FFFh
test word [ebx+ehci_pipe.Flags-sizeof.ehci_pipe+2], 3FFFh
jnz .interrupt_fs
call ehci_hs_interrupt_list_unlink
jmp .interrupt_common
1870,9 → 1864,9
mov edx, esi
sub edx, eax
cmp edx, sizeof.ehci_controller
mov edx, [ebx+ehci_pipe.NextQH-ehci_pipe.SoftwarePart]
mov edx, [ebx+ehci_pipe.NextQH-sizeof.ehci_pipe]
jb .prev_is_static
mov [eax+ehci_pipe.NextQH-ehci_pipe.SoftwarePart], edx
mov [eax+ehci_pipe.NextQH-sizeof.ehci_pipe], edx
ret
.prev_is_static:
mov [eax+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], edx
1882,10 → 1876,10
proc ehci_alloc_td
push ebx
mov ebx, ehci_gtd_mutex
stdcall usb_allocate_common, sizeof.ehci_gtd
stdcall usb_allocate_common, (sizeof.ehci_gtd + sizeof.usb_gtd + 1Fh) and not 1Fh
test eax, eax
jz @f
add eax, ehci_gtd.SoftwarePart
add eax, sizeof.ehci_gtd
@@:
pop ebx
ret
1895,6 → 1889,6
; frees all additional data associated with the transfer descriptor.
; EHCI has no additional data, so just free ehci_gtd structure.
proc ehci_free_td
sub dword [esp+4], ehci_gtd.SoftwarePart
sub dword [esp+4], sizeof.ehci_gtd
jmp usb_free_common
endp
/kernel/branches/Kolibri-acpi/bus/usb/memory.inc
26,7 → 26,7
endg
 
; sanity check: structures in UHCI and OHCI should be the same for allocation
if (sizeof.ohci_pipe=sizeof.uhci_pipe)&(ohci_pipe.SoftwarePart=uhci_pipe.SoftwarePart)
if (sizeof.ohci_pipe = sizeof.uhci_pipe)
 
; Allocates one endpoint structure for UHCI/OHCI.
; Returns pointer to software part (usb_pipe) in eax.
33,10 → 33,10
proc usb1_allocate_endpoint
push ebx
mov ebx, usb1_ep_mutex
stdcall usb_allocate_common, sizeof.ohci_pipe
stdcall usb_allocate_common, (sizeof.ohci_pipe + sizeof.usb_pipe + 0Fh) and not 0Fh
test eax, eax
jz @f
add eax, ohci_pipe.SoftwarePart
add eax, sizeof.ohci_pipe
@@:
pop ebx
ret
45,7 → 45,7
; Free one endpoint structure for UHCI/OHCI.
; Stdcall with one argument, pointer to software part (usb_pipe).
proc usb1_free_endpoint
sub dword [esp+4], ohci_pipe.SoftwarePart
sub dword [esp+4], sizeof.ohci_pipe
jmp usb_free_common
endp
 
55,7 → 55,7
end if
 
; sanity check: structures in UHCI and OHCI should be the same for allocation
if (sizeof.ohci_gtd=sizeof.uhci_gtd)&(ohci_gtd.SoftwarePart=uhci_gtd.SoftwarePart)
if (sizeof.ohci_gtd = sizeof.uhci_gtd)
 
; Allocates one general transfer descriptor structure for UHCI/OHCI.
; Returns pointer to software part (usb_gtd) in eax.
62,10 → 62,10
proc usb1_allocate_general_td
push ebx
mov ebx, usb_gtd_mutex
stdcall usb_allocate_common, sizeof.ohci_gtd
stdcall usb_allocate_common, (sizeof.ohci_gtd + sizeof.usb_gtd + 0Fh) and not 0Fh
test eax, eax
jz @f
add eax, ohci_gtd.SoftwarePart
add eax, sizeof.ohci_gtd
@@:
pop ebx
ret
74,7 → 74,7
; Free one general transfer descriptor structure for UHCI/OHCI.
; Stdcall with one argument, pointer to software part (usb_gtd).
proc usb1_free_general_td
sub dword [esp+4], ohci_gtd.SoftwarePart
sub dword [esp+4], sizeof.ohci_gtd
jmp usb_free_common
endp
 
/kernel/branches/Kolibri-acpi/bus/usb/ohci.inc
44,8 → 44,8
; specification.
; * The hardware requires 16-bytes alignment of the hardware part.
; Since the allocator (usb_allocate_common) allocates memory sequentially
; from page start (aligned on 0x1000 bytes), size of the structure must be
; divisible by 16.
; from page start (aligned on 0x1000 bytes), block size for the allocator
; must be divisible by 16; usb1_allocate_endpoint ensures this.
struct ohci_pipe
; All addresses are physical.
Flags dd ?
95,14 → 95,8
; * There is no "next" list for Bulk and Control lists, they are processed
; separately from others.
; * There is no "next" list for Periodic list for 1ms interval.
SoftwarePart rd sizeof.usb_pipe/4
; Software part, common for all controllers.
ends
 
if sizeof.ohci_pipe mod 16
.err ohci_pipe must be 16-bytes aligned
end if
 
; This structure describes the static head of every list of pipes.
; The hardware requires 16-bytes alignment of this structure.
; All instances of this structure are located sequentially in uhci_controller,
204,7 → 198,8
; * The hardware requires 16-bytes alignment of the hardware part, so
; the entire descriptor must be 16-bytes aligned. Since the allocator
; (usb_allocate_common) allocates memory sequentially from page start
; (aligned on 0x1000 bytes), size of the structure must be divisible by 16.
; (aligned on 0x1000 bytes), block size for the allocator must be
; divisible by 16; usb1_allocate_generic_td ensures this.
struct ohci_gtd
; ------------------------------ hardware fields ------------------------------
; All addresses in this part are physical.
248,15 → 243,9
; Virtual pointer to the next processed TD.
BufEnd dd ?
; Physical address of the last byte in the buffer for this TD.
dd ? ; padding for 16-bytes alignment
SoftwarePart rd sizeof.usb_gtd/4
; Common part for all controllers.
dd ? ; padding to align with uhci_gtd
ends
 
if sizeof.ohci_gtd mod 16
.err ohci_gtd must be 16-bytes aligned
end if
 
; OHCI isochronous transfer descriptor.
; * The structure describes transfers to be performed on Isochronous endpoints.
; * The structure includes two parts, the hardware part and the software part.
726,7 → 715,7
.tdloop:
mov ecx, [eax+ohci_gtd.NextTD]
mov [eax+ohci_gtd.NextTD], ebx
lea ebx, [eax+ohci_gtd.SoftwarePart]
lea ebx, [eax+sizeof.ohci_gtd]
test ecx, ecx
jz .tddone
call usb_td_to_virt
893,7 → 882,7
; and stores USB device address in the ohci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
proc ohci_set_device_address
mov byte [ebx+ohci_pipe.Flags-ohci_pipe.SoftwarePart], cl
mov byte [ebx+ohci_pipe.Flags-sizeof.ohci_pipe], cl
; Wait until the hardware will forget the old value.
call usb_subscribe_control
ret
903,7 → 892,7
; in: esi -> usb_controller, ebx -> usb_pipe
; out: eax = endpoint address
proc ohci_get_device_address
mov eax, [ebx+ohci_pipe.Flags-ohci_pipe.SoftwarePart]
mov eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
and eax, 7Fh
ret
endp
923,7 → 912,7
; stores the packet size in ohci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
proc ohci_set_endpoint_packet_size
mov byte [ebx+ohci_pipe.Flags+2-ohci_pipe.SoftwarePart], cl
mov byte [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe], cl
; Wait until the hardware will forget the old value.
call usb_subscribe_control
ret
943,20 → 932,20
.interval dd ?
end virtual
; 1. Initialize the queue of transfer descriptors: empty.
sub eax, ohci_gtd.SoftwarePart
sub eax, sizeof.ohci_gtd
call get_phys_addr
mov [edi+ohci_pipe.TailP-ohci_pipe.SoftwarePart], eax
mov [edi+ohci_pipe.HeadP-ohci_pipe.SoftwarePart], eax
mov [edi+ohci_pipe.TailP-sizeof.ohci_pipe], eax
mov [edi+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
; 2. Generate ohci_pipe.Flags, see the description in ohci_pipe.
mov eax, [ecx+ohci_pipe.Flags-ohci_pipe.SoftwarePart]
mov eax, [ecx+ohci_pipe.Flags-sizeof.ohci_pipe]
and eax, 0x207F ; keep Speed bit and FunctionAddress
mov edx, [.endpoint]
and edx, 15
shl edx, 7
or eax, edx
mov [edi+ohci_pipe.Flags-ohci_pipe.SoftwarePart], eax
mov [edi+ohci_pipe.Flags-sizeof.ohci_pipe], eax
mov eax, [.maxpacket]
mov word [edi+ohci_pipe.Flags+2-ohci_pipe.SoftwarePart], ax
mov word [edi+ohci_pipe.Flags+2-sizeof.ohci_pipe], ax
cmp [.type], CONTROL_PIPE
jz @f
test byte [.endpoint], 80h
963,7 → 952,7
setnz al
inc eax
shl al, 3
or byte [edi+ohci_pipe.Flags+1-ohci_pipe.SoftwarePart], al
or byte [edi+ohci_pipe.Flags+1-sizeof.ohci_pipe], al
@@:
; 3. Insert the new pipe to the corresponding list of endpoints.
; 3a. Use Control list for control pipes, Bulk list for bulk pipes.
992,11 → 981,11
mov [edi+usb_pipe.PrevVirt], edx
mov [ecx+usb_pipe.PrevVirt], edi
mov [edx+usb_pipe.NextVirt], edi
mov ecx, [edx+ohci_pipe.NextED-ohci_pipe.SoftwarePart]
mov [edi+ohci_pipe.NextED-ohci_pipe.SoftwarePart], ecx
lea eax, [edi-ohci_pipe.SoftwarePart]
mov ecx, [edx+ohci_pipe.NextED-sizeof.ohci_pipe]
mov [edi+ohci_pipe.NextED-sizeof.ohci_pipe], ecx
lea eax, [edi-sizeof.ohci_pipe]
call get_phys_addr
mov [edx+ohci_pipe.NextED-ohci_pipe.SoftwarePart], eax
mov [edx+ohci_pipe.NextED-sizeof.ohci_pipe], eax
; 4. Return something non-zero.
ret
.return0:
1069,15 → 1058,22
; this corresponds to 1001h bytes. If the requested size is
; greater, we should split the transfer into several descriptors.
; Boundaries to split must be multiples of endpoint transfer size
; to avoid short packets except in the end of the transfer,
; 1000h is always a good value.
; to avoid short packets except in the end of the transfer.
cmp [size], 1001h
jbe .lastpacket
; 2. While the remaining data cannot fit in one packet,
; allocate page-sized descriptors.
mov edi, 1000h
; allocate full-sized descriptors.
; 2a. Calculate size of one descriptor: must be a multiple of transfer size
; and must be not greater than 1001h.
movzx ecx, word [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe]
mov eax, 1001h
xor edx, edx
mov edi, eax
div ecx
sub edi, edx
; 2b. Allocate in loop.
mov [packetSize], edi
.fullpackets:
cmp [size], edi
jbe .lastpacket
call ohci_alloc_packet
test eax, eax
jz .fail
1084,7 → 1080,8
mov [td], eax
add [buffer], edi
sub [size], edi
jmp .fullpackets
cmp [size], 1001h
ja .fullpackets
; 3. The remaining data can fit in one descriptor;
; allocate the last descriptor with size = size of remaining data.
.lastpacket:
1094,7 → 1091,7
test eax, eax
jz .fail
; 4. Enable an immediate interrupt on completion of the last packet.
and byte [ecx+ohci_gtd.Flags+2-ohci_gtd.SoftwarePart], not (7 shl (21-16))
and byte [ecx+ohci_gtd.Flags+2-sizeof.ohci_gtd], not (7 shl (21-16))
; 5. If a short transfer is ok for a caller, set the corresponding bit in
; the last descriptor, but not in others.
; Note: even if the caller says that short transfers are ok,
1104,7 → 1101,7
; transparently to the caller.
test [flags], 1
jz @f
or byte [ecx+ohci_gtd.Flags+2-ohci_gtd.SoftwarePart], 1 shl (18-16)
or byte [ecx+ohci_gtd.Flags+2-sizeof.ohci_gtd], 1 shl (18-16)
@@:
ret
.fail:
1143,24 → 1140,24
; 3. Save the returned value (next descriptor).
push eax
; 4. Store the physical address of the next descriptor.
sub eax, ohci_gtd.SoftwarePart
sub eax, sizeof.ohci_gtd
call get_phys_addr
mov [ecx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart], eax
mov [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd], eax
; 5. For zero-length transfers, store zero in both fields for buffer addresses.
; Otherwise, fill them with real values.
xor eax, eax
mov [ecx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart], eax
mov [ecx+ohci_gtd.BufEnd-ohci_gtd.SoftwarePart], eax
mov [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
mov [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
cmp [.packetSize], eax
jz @f
mov eax, [.buffer]
call get_phys_addr
mov [ecx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart], eax
mov [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
mov eax, [.buffer]
add eax, [.packetSize]
dec eax
call get_phys_addr
mov [ecx+ohci_gtd.BufEnd-ohci_gtd.SoftwarePart], eax
mov [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
@@:
; 6. Generate Flags field:
; - set bufferRounding (bit 18) to zero = disallow short transfers;
1179,7 → 1176,7
and edx, (3 shl 2)
shl edx, 24 - 2
lea eax, [eax + edx + (7 shl 21) + (15 shl 28)]
mov [ecx+ohci_gtd.Flags-ohci_gtd.SoftwarePart], eax
mov [ecx+ohci_gtd.Flags-sizeof.ohci_gtd], eax
; 7. Restore the returned value saved in step 3.
pop eax
.nothing:
1192,8 → 1189,8
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
proc ohci_insert_transfer
; 1. Advance the queue of transfer descriptors.
mov eax, [ecx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart]
mov [ebx+ohci_pipe.TailP-ohci_pipe.SoftwarePart], eax
mov eax, [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd]
mov [ebx+ohci_pipe.TailP-sizeof.ohci_pipe], eax
; 2. For control and bulk pipes, notify the controller that
; there is new work in control/bulk queue respectively.
ohci_notify_new_work:
1393,7 → 1390,7
mov edx, [ebx+usb_gtd.Pipe]
test [edx+usb_pipe.Flags], USB_FLAG_CLOSED
jz @f
lea eax, [ebx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart]
lea eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
xor ebx, ebx
jmp .next_td2
@@:
1402,13 → 1399,13
; 3. Get number of bytes that remain to be transferred.
; If CurBufPtr is zero, everything was transferred.
xor edx, edx
cmp [ebx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart], edx
cmp [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], edx
jz .gotlen
; Otherwise, the remaining length is
; (BufEnd and 0xFFF) - (CurBufPtr and 0xFFF) + 1,
; plus 0x1000 if BufEnd and CurBufPtr are in different pages.
mov edx, [ebx+ohci_gtd.BufEnd-ohci_gtd.SoftwarePart]
mov eax, [ebx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart]
mov edx, [ebx+ohci_gtd.BufEnd-sizeof.ohci_gtd]
mov eax, [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd]
mov ecx, edx
and edx, 0xFFF
inc edx
1425,7 → 1422,7
neg edx
; 4. Check for error. If so, go to 7.
push ebx
mov eax, [ebx+ohci_gtd.Flags-ohci_gtd.SoftwarePart]
mov eax, [ebx+ohci_gtd.Flags-sizeof.ohci_gtd]
shr eax, 28
jnz .error
.notify:
1451,7 → 1448,7
stdcall usb1_free_general_td, ebx
@@:
pop ebx
lea eax, [ebx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart]
lea eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
.next_td2:
push ebx
mov ebx, eax
1484,10 → 1481,10
push eax
push edx
; DEBUGF 1,'K : TD failed:\n'
; DEBUGF 1,'K : %x %x %x %x\n',[ebx-ohci_gtd.SoftwarePart],[ebx-ohci_gtd.SoftwarePart+4],[ebx-ohci_gtd.SoftwarePart+8],[ebx-ohci_gtd.SoftwarePart+12]
; DEBUGF 1,'K : %x %x %x %x\n',[ebx-ohci_gtd.SoftwarePart+16],[ebx-ohci_gtd.SoftwarePart+20],[ebx-ohci_gtd.SoftwarePart+24],[ebx-ohci_gtd.SoftwarePart+28]
; DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd],[ebx-sizeof.ohci_gtd+4],[ebx-sizeof.ohci_gtd+8],[ebx-sizeof.ohci_gtd+12]
; DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd+16],[ebx-sizeof.ohci_gtd+20],[ebx-sizeof.ohci_gtd+24],[ebx-sizeof.ohci_gtd+28]
; mov eax, [ebx+usb_gtd.Pipe]
; DEBUGF 1,'K : pipe: %x %x %x %x\n',[eax-ohci_pipe.SoftwarePart],[eax-ohci_pipe.SoftwarePart+4],[eax-ohci_pipe.SoftwarePart+8],[eax-ohci_pipe.SoftwarePart+12]
; DEBUGF 1,'K : pipe: %x %x %x %x\n',[eax-sizeof.ohci_pipe],[eax-sizeof.ohci_pipe+4],[eax-sizeof.ohci_pipe+8],[eax-sizeof.ohci_pipe+12]
; 7b. Traverse the list of descriptors looking for the final packet
; for this transfer.
; Free and unlink non-final descriptors, except the current one.
1517,18 → 1514,18
; After that, go to step 5 with eax = 0 (no error).
cmp dword [.error_code], USB_STATUS_UNDERRUN
jnz .no_underrun
test byte [ebx+ohci_gtd.Flags+2-ohci_gtd.SoftwarePart], 1 shl (18-16)
test byte [ebx+ohci_gtd.Flags+2-sizeof.ohci_gtd], 1 shl (18-16)
jz .no_underrun
and dword [.error_code], 0
mov ecx, [ebx+usb_gtd.Pipe]
mov edx, [ecx+ohci_pipe.HeadP-ohci_pipe.SoftwarePart]
mov edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
and edx, 2
.advance_queue:
mov eax, [ebx+usb_gtd.NextVirt]
sub eax, ohci_gtd.SoftwarePart
sub eax, sizeof.ohci_gtd
call get_phys_addr
or eax, edx
mov [ecx+ohci_pipe.HeadP-ohci_pipe.SoftwarePart], eax
mov [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
push ebx
mov ebx, ecx
call ohci_notify_new_work
1562,10 → 1559,10
; support functional stall as well, but this is not recommended.").
; Advance the transfer queue to the next descriptor.
mov ecx, [ebx+usb_gtd.Pipe]
mov edx, [ecx+ohci_pipe.HeadP-ohci_pipe.SoftwarePart]
mov edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
and edx, 2 ; keep toggleCarry bit
cmp [ecx+usb_pipe.Type], CONTROL_PIPE
jnz @f
jz @f
inc edx ; set Halted bit
@@:
jmp .advance_queue
1577,7 → 1574,7
proc ohci_unlink_pipe
cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE
jnz @f
mov eax, [ebx+ohci_pipe.Flags-ohci_pipe.SoftwarePart]
mov eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
bt eax, 13
setc cl
bt eax, 11
1589,7 → 1586,7
mov eax, [ebx+usb_pipe.PrevVirt]
mov [edx+usb_pipe.PrevVirt], eax
mov [eax+usb_pipe.NextVirt], edx
mov edx, [ebx+ohci_pipe.NextED-ohci_pipe.SoftwarePart]
mov [eax+ohci_pipe.NextED-ohci_pipe.SoftwarePart], edx
mov edx, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
mov [eax+ohci_pipe.NextED-sizeof.ohci_pipe], edx
ret
endp
/kernel/branches/Kolibri-acpi/bus/usb/protocol.inc
459,10 → 459,7
; save length for step 2
push eax
add eax, sizeof.usb_device_data + 8
; Note that malloc destroys ebx.
push ebx
call malloc
pop ebx
; 1b. If failed, say something to the debug board and stop the initialization.
test eax, eax
jz .nomemory
/kernel/branches/Kolibri-acpi/bus/usb/scheduler.inc
432,14 → 432,14
; in the list header.
proc ehci_hs_interrupt_list_unlink
; get target list
mov edx, [ebx+ehci_pipe.BaseList-ehci_pipe.SoftwarePart]
mov edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
; TODO: calculate real bandwidth
movzx eax, word [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart+2]
mov ecx, [ebx+ehci_pipe.Flags-ehci_pipe.SoftwarePart]
movzx eax, word [ebx+ehci_pipe.Token-sizeof.ehci_pipe+2]
mov ecx, [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
and eax, (1 shl 11) - 1
shr ecx, 30
imul eax, ecx
movzx ecx, byte [ebx+ehci_pipe.Flags-ehci_pipe.SoftwarePart]
movzx ecx, byte [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
add edx, ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart
; update bandwidth
.dec_bandwidth:
/kernel/branches/Kolibri-acpi/bus/usb/uhci.inc
20,9 → 20,8
USB_PID_OUT = 0E1h
; UHCI does not support an interrupt on root hub status change. We must poll
; the controller periodically. This is the period in timer ticks (10ms).
; We use the value 100 ms: it is valid value for USB hub poll rate (1-255 ms),
; small enough to be responsible to connect events and large enough to not
; load CPU too often.
; We use the value 100 ticks: it is small enough to be responsive to connect
; events and large enough to not load CPU too often.
UHCI_POLL_INTERVAL = 100
; the following constant is an invalid encoding for length fields in
; uhci_gtd; it is used to check whether an inactive TD has been
42,8 → 41,8
; software book-keeping.
; * The hardware requires 16-bytes alignment of the hardware part.
; Since the allocator (usb_allocate_common) allocates memory sequentially
; from page start (aligned on 0x1000 bytes), size of the structure must be
; divisible by 16.
; from page start (aligned on 0x1000 bytes), block size for the allocator
; must be divisible by 16; usb1_allocate_endpoint ensures this.
struct uhci_pipe
NextQH dd ?
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next QH.
81,14 → 80,8
ErrorTD dd ?
; Usually NULL. If nonzero, it is a pointer to descriptor which was error'd
; and should be freed sometime in the future (the hardware could still use it).
SoftwarePart rd sizeof.usb_pipe/4
; Common part for all controllers, described by usb_pipe structure.
ends
 
if sizeof.uhci_pipe mod 16
.err uhci_pipe must be 16-bytes aligned
end if
 
; This structure describes the static head of every list of pipes.
; The hardware requires 16-bytes alignment of this structure.
; All instances of this structure are located sequentially in uhci_controller,
167,7 → 160,8
; * The hardware requires 16-bytes alignment of the hardware part, so
; the entire descriptor must be 16-bytes aligned. Since the allocator
; (uhci_allocate_common) allocates memory sequentially from page start
; (aligned on 0x1000 bytes), size of the structure must be divisible by 16.
; (aligned on 0x1000 bytes), block size for the allocator must be
; divisible by 16; usb1_allocate_general_td ensures this.
struct uhci_gtd
NextTD dd ?
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next TD.
231,14 → 225,8
; bit 0: 1 = short packet is NOT allowed
; (before the TD is processed, it is the copy of bit 29 of ControlStatus;
; some controllers modify that bit, so we need a copy in a safe place)
SoftwarePart rd sizeof.usb_gtd/4
; Software part, common for all controllers.
ends
 
if sizeof.uhci_gtd mod 16
.err uhci_gtd must be 16-bytes aligned
end if
 
; UHCI requires that the entire transfer buffer should be on one page.
; If the actual buffer crosses page boundary, uhci_alloc_packet
; allocates additional memory for buffer for hardware.
853,7 → 841,7
; if either of conditions holds, exit from the internal loop.
cmp ebx, [esp]
jz .tddone
mov eax, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
mov eax, [ebx+uhci_gtd.ControlStatus-sizeof.uhci_gtd]
test eax, 1 shl 23 ; active?
jnz .tddone
; Release the queue lock while processing one descriptor:
889,10 → 877,10
; DEBUGF 1,'K : %x %x %x %x\n',[ebx-4],[ebx],[ebx+4],[ebx+8]
; 2. If this is IN transfer into special buffer, copy the data
; to target location.
mov edx, [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
mov edx, [ebx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
and edx, not 1 ; clear lsb (used for another goal)
jz .nocopy
cmp byte [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart], USB_PID_IN
cmp byte [ebx+uhci_gtd.Token-sizeof.uhci_gtd], USB_PID_IN
jnz .nocopy
; Note: we assume that pointer to buffer is valid in the memory space of
; the USB thread. This means that buffer must reside in kernel memory
900,7 → 888,7
push esi edi
mov esi, [edx+uhci_original_buffer.UsedBuffer]
mov edi, [edx+uhci_original_buffer.OrigBuffer]
mov ecx, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
mov ecx, [ebx+uhci_gtd.ControlStatus-sizeof.uhci_gtd]
inc ecx
and ecx, 7FFh
mov edx, ecx
913,8 → 901,8
.nocopy:
; 3. Calculate actual number of bytes transferred.
; 3a. Read the state.
mov eax, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
mov ecx, [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart]
mov eax, [ebx+uhci_gtd.ControlStatus-sizeof.uhci_gtd]
mov ecx, [ebx+uhci_gtd.Token-sizeof.uhci_gtd]
; 3b. Get number of bytes processed.
lea edx, [eax+1]
and edx, 7FFh
938,7 → 926,7
xor ecx, ecx
test eax, 1 shl 22
jnz .error
test byte [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
test byte [ebx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
jz .notify
cmp edx, [ebx+usb_gtd.Length]
jz .notify
946,7 → 934,7
; 5. There was an error while processing this packet.
; The hardware has stopped processing the queue.
DEBUGF 1,'K : TD failed:\n'
if uhci_gtd.SoftwarePart <> 20
if sizeof.uhci_gtd <> 20
.err modify offsets for debug output
end if
DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8]
955,17 → 943,17
push edx
push eax
mov eax, [ebx+usb_gtd.Pipe]
DEBUGF 1,'K : pipe: %x %x\n',[eax+0-uhci_pipe.SoftwarePart],[eax+4-uhci_pipe.SoftwarePart]
DEBUGF 1,'K : pipe: %x %x\n',[eax+0-sizeof.uhci_pipe],[eax+4-sizeof.uhci_pipe]
; 5b. Store the current TD as an error packet.
; If an error packet is already stored for this pipe,
; it is definitely not used already, so free the old packet.
mov eax, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
mov eax, [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
test eax, eax
jz @f
stdcall uhci_free_td, eax
@@:
mov eax, [ebx+usb_gtd.Pipe]
mov [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], ebx
mov [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe], ebx
; 5c. Traverse the list of descriptors looking for the final packet
; for this transfer.
; Free and unlink non-final descriptors, except the current one.
1019,7 → 1007,7
; After that, go to step 6 with ecx = 0 (no error).
cmp ecx, USB_STATUS_UNDERRUN
jnz @f
test byte [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
test byte [ebx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
jnz @f
; The controller has stopped this queue on the error packet.
; Update uhci_pipe.HeadTD to point to the next packet in the queue.
1026,10 → 1014,10
call uhci_fix_toggle
xor ecx, ecx
.control:
mov eax, [ebx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart]
mov eax, [ebx+uhci_gtd.NextTD-sizeof.uhci_gtd]
and al, not 0xF
mov edx, [ebx+usb_gtd.Pipe]
mov [edx+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
mov [edx+uhci_pipe.HeadTD-sizeof.uhci_pipe], eax
pop edx ; length
jmp .notify
@@:
1047,7 → 1035,7
push ecx
mov eax, [ebx+usb_gtd.Pipe]
push [ebx+usb_gtd.NextVirt]
cmp ebx, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
cmp ebx, [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
jz @f
stdcall uhci_free_td, ebx
@@:
1065,10 → 1053,10
cmp [edx+usb_pipe.Type], CONTROL_PIPE
jz .control
; Bulk/interrupt transfer; halt the queue.
mov eax, [ebx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart]
mov eax, [ebx+uhci_gtd.NextTD-sizeof.uhci_gtd]
and al, not 0xF
inc eax ; set Halted bit
mov [edx+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
mov [edx+uhci_pipe.HeadTD-sizeof.uhci_pipe], eax
pop edx ; restore length saved in step 5a
.notify:
; 6. Either the descriptor in ebx was processed without errors,
1094,7 → 1082,7
push [ebx+usb_gtd.NextVirt]
; 7b. Free the descriptor, unless it is saved as ErrorTD.
mov eax, [ebx+usb_gtd.Pipe]
cmp [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], ebx
cmp [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe], ebx
jz @f
stdcall uhci_free_td, ebx
@@:
1118,9 → 1106,9
; 2. The hardware expects next packet with toggle = (ErrorTD.toggle xor 1),
; the current value in next packet is (ebx.toggle xor 1).
; Nothing to do if ErrorTD.toggle == ebx.toggle.
mov eax, [ecx+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
mov eax, [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart]
xor eax, [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart]
mov eax, [ecx+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
mov eax, [eax+uhci_gtd.Token-sizeof.uhci_gtd]
xor eax, [ebx+uhci_gtd.Token-sizeof.uhci_gtd]
test eax, 1 shl 19
jz .nothing
; 3. Lock the transfer queue.
1130,13 → 1118,13
; (inclusive).
mov eax, [ebx+usb_gtd.NextVirt]
.loop:
xor byte [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart+2], 1 shl (19-16)
xor byte [eax+uhci_gtd.Token-sizeof.uhci_gtd+2], 1 shl (19-16)
cmp eax, [ecx+usb_pipe.LastTD-usb_pipe.Lock]
mov eax, [eax+usb_gtd.NextVirt]
jnz .loop
; 5. Flip the toggle bit in uhci_pipe structure.
xor byte [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart-usb_pipe.Lock+2], 1 shl (19-16)
or dword [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart-usb_pipe.Lock], eax
xor byte [ecx+uhci_pipe.Token-sizeof.uhci_pipe-usb_pipe.Lock+2], 1 shl (19-16)
or dword [ecx+uhci_pipe.Token-sizeof.uhci_pipe-usb_pipe.Lock], eax
; 6. Unlock the transfer queue.
call mutex_unlock
.nothing:
1338,7 → 1326,7
; and stores USB device address in the uhci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
proc uhci_set_device_address
mov byte [ebx+uhci_pipe.Token+1-uhci_pipe.SoftwarePart], cl
mov byte [ebx+uhci_pipe.Token+1-sizeof.uhci_pipe], cl
call usb_subscription_done
ret
endp
1347,7 → 1335,7
; in: esi -> usb_controller, ebx -> usb_pipe
; out: eax = endpoint address
proc uhci_get_device_address
mov al, byte [ebx+uhci_pipe.Token+1-uhci_pipe.SoftwarePart]
mov al, byte [ebx+uhci_pipe.Token+1-sizeof.uhci_pipe]
and eax, 7Fh
ret
endp
1372,8 → 1360,8
proc uhci_set_endpoint_packet_size
dec ecx
shl ecx, 21
and [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], (1 shl 21) - 1
or [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], ecx
and [ebx+uhci_pipe.Token-sizeof.uhci_pipe], (1 shl 21) - 1
or [ebx+uhci_pipe.Token-sizeof.uhci_pipe], ecx
; uhci_pipe.Token field is purely for software bookkeeping and does not affect
; the hardware; thus, we can continue initialization immediately.
call usb_subscription_done
1395,18 → 1383,18
.interval dd ?
end virtual
; 1. Initialize ErrorTD to zero.
and [edi+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], 0
and [edi+uhci_pipe.ErrorTD-sizeof.uhci_pipe], 0
; 2. Initialize HeadTD to the physical address of the first TD.
push eax ; store pointer to the first TD for step ?
sub eax, uhci_gtd.SoftwarePart
push eax ; store pointer to the first TD for step 4
sub eax, sizeof.uhci_gtd
call get_phys_addr
mov [edi+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
mov [edi+uhci_pipe.HeadTD-sizeof.uhci_pipe], eax
; 3. Initialize Token field:
; take DeviceAddress and LowSpeedDevice from the parent pipe,
; take Endpoint and MaximumLength fields from API arguments,
; set PID depending on pipe type and provided pipe direction,
; set DataToggle to zero.
mov eax, [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
mov eax, [ecx+uhci_pipe.Token-sizeof.uhci_pipe]
and eax, 0x107F00 ; keep DeviceAddress and LowSpeedDevice
mov edx, [.endpoint]
and edx, 15
1424,20 → 1412,22
jz @f
mov al, USB_PID_IN
@@:
mov [edi+uhci_pipe.Token-uhci_pipe.SoftwarePart], eax
mov [edi+uhci_pipe.Token-sizeof.uhci_pipe], eax
; 4. Initialize the first TD:
; copy Token from uhci_pipe.Token zeroing reserved bit 20,
; set ControlStatus for future transfers, bit make it inactive,
; set bit 0 in NextTD = "no next TD".
; set bit 0 in NextTD = "no next TD",
; zero OrigBufferInfo.
pop edx ; restore pointer saved in step 2
mov [edx+uhci_gtd.Token-uhci_gtd.SoftwarePart], eax
and byte [edx+uhci_gtd.Token+2-uhci_gtd.SoftwarePart], not (1 shl (20-16))
mov [edx+uhci_gtd.Token-sizeof.uhci_gtd], eax
and byte [edx+uhci_gtd.Token+2-sizeof.uhci_gtd], not (1 shl (20-16))
and eax, 1 shl 20
shl eax, 6
or eax, UHCI_INVALID_LENGTH + (3 shl 27)
; not processed, inactive, allow 3 errors
mov [edx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart], eax
mov [edx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 1
and [edx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 0
mov [edx+uhci_gtd.ControlStatus-sizeof.uhci_gtd], eax
mov [edx+uhci_gtd.NextTD-sizeof.uhci_gtd], 1
; 5. Select the corresponding list and insert to the list.
; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
lea edx, [esi+uhci_controller.ControlED.SoftwarePart-sizeof.uhci_controller]
1471,8 → 1461,8
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
; store the physical address of the new pipe to previous NextQH.
mov ecx, [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart]
mov [edi+uhci_pipe.NextQH-uhci_pipe.SoftwarePart], ecx
lea eax, [edi-uhci_pipe.SoftwarePart]
mov [edi+uhci_pipe.NextQH-sizeof.uhci_pipe], ecx
lea eax, [edi-sizeof.uhci_pipe]
call get_phys_addr
inc eax
inc eax
1486,13 → 1476,13
 
; This procedure is called when a pipe is closing (either due to API call
; or due to disconnect); it unlinks a pipe from the corresponding list.
if uhci_static_ep.SoftwarePart <> uhci_pipe.SoftwarePart
.err uhci_unlink_pipe assumes that uhci_static_ep.SoftwarePart == uhci_pipe.SoftwarePart
if uhci_static_ep.SoftwarePart <> sizeof.uhci_pipe
.err uhci_unlink_pipe assumes that uhci_static_ep.SoftwarePart == sizeof.uhci_pipe
end if
proc uhci_unlink_pipe
cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE
jnz @f
mov eax, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
mov eax, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
cmp al, USB_PID_IN
setz ch
bt eax, 20
1510,8 → 1500,8
mov [eax+usb_pipe.NextVirt], edx
; Note: eax could be either usb_pipe or usb_static_ep;
; fortunately, NextQH and SoftwarePart have same offsets in both.
mov edx, [ebx+uhci_pipe.NextQH-uhci_pipe.SoftwarePart]
mov [eax+uhci_pipe.NextQH-uhci_pipe.SoftwarePart], edx
mov edx, [ebx+uhci_pipe.NextQH-sizeof.uhci_pipe]
mov [eax+uhci_pipe.NextQH-sizeof.uhci_pipe], edx
ret
endp
 
1519,7 → 1509,7
; For UHCI, this includes usb_pipe structure and ErrorTD, if present.
proc uhci_free_pipe
mov eax, [esp+4]
mov eax, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
mov eax, [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
test eax, eax
jz @f
stdcall uhci_free_td, eax
1544,7 → 1534,7
; with size <= endpoint max packet size.
; 2. Get the maximum packet size for endpoint from uhci_pipe.Token
; and generate Token field for TDs.
mov edi, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
mov edi, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
mov eax, edi
shr edi, 21
inc edi
1602,14 → 1592,14
; transparently to the caller.
test [flags], 1
jz @f
and byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], not (1 shl (29-24))
and byte [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], not 1
and byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], not (1 shl (29-24))
and byte [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], not 1
@@:
; 6. Update toggle bit in uhci_pipe structure from current value of [token].
mov edx, [token]
xor edx, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
xor edx, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
and edx, 1 shl 19
xor [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], edx
xor [ebx+uhci_pipe.Token-sizeof.uhci_pipe], edx
.nothing:
ret
.fail:
1652,12 → 1642,10
; 1c. We need a temporary buffer. Allocate [packetSize]*2 bytes, so that
; there must be [packetSize] bytes on one page,
; plus space for a header uhci_original_buffer.
push ebx
mov eax, [.packetSize]
add eax, eax
add eax, sizeof.uhci_original_buffer
call malloc
pop ebx
; 1d. If failed, return zero.
test eax, eax
jz .nothing
1712,31 → 1700,36
; mark it as last one (this will be changed when further packets will be
; allocated), copy Token field from uhci_pipe.Token zeroing bit 20,
; generate ControlStatus field, mark as Active
; (for last descriptor, this will be changed by uhci_insert_transfer).
mov [eax+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 1 ; no next TD
mov edx, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
mov [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart], edx
and byte [eax+uhci_gtd.Token+2-uhci_gtd.SoftwarePart], not (1 shl (20-16))
; (for last descriptor, this will be changed by uhci_insert_transfer),
; zero OrigBufferInfo (otherwise uhci_free_td would try to free it).
and [eax+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 0
mov [eax+uhci_gtd.NextTD-sizeof.uhci_gtd], 1 ; no next TD
mov edx, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
mov [eax+uhci_gtd.Token-sizeof.uhci_gtd], edx
and byte [eax+uhci_gtd.Token+2-sizeof.uhci_gtd], not (1 shl (20-16))
and edx, 1 shl 20
shl edx, 6
or edx, UHCI_INVALID_LENGTH + (1 shl 23) + (3 shl 27)
; not processed, active, allow 3 errors
mov [eax+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart], edx
mov [eax+uhci_gtd.ControlStatus-sizeof.uhci_gtd], edx
; 5. Initialize remaining fields of the current TD.
; 5a. Store pointer to the buffer allocated in step 1 (or zero).
pop [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
pop [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
; 5b. Store physical address of the next TD.
push eax
sub eax, uhci_gtd.SoftwarePart
sub eax, sizeof.uhci_gtd
call get_phys_addr
; use Depth traversal unless this is the first TD in the transfer stage;
; for Control/Bulk pipes, use Depth traversal unless this is the first TD
; in the transfer stage;
; uhci_insert_transfer will set Depth traversal for the first TD and clear
; it in the last TD
test [ebx+usb_pipe.Type], 1
jnz @f
cmp ecx, [ebx+usb_pipe.LastTD]
jz @f
or eax, 4
@@:
mov [ecx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], eax
mov [ecx+uhci_gtd.NextTD-sizeof.uhci_gtd], eax
; 5c. Store physical address of the buffer: zero if no data present,
; the temporary buffer if it was allocated, the given buffer otherwise.
xor eax, eax
1743,7 → 1736,7
cmp [.packetSize], eax
jz .hasphysbuf
mov eax, [.buffer]
mov edx, [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
mov edx, [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
test edx, edx
jz @f
mov eax, [edx+uhci_original_buffer.UsedBuffer]
1750,7 → 1743,7
@@:
call get_phys_addr
.hasphysbuf:
mov [ecx+uhci_gtd.Buffer-uhci_gtd.SoftwarePart], eax
mov [ecx+uhci_gtd.Buffer-sizeof.uhci_gtd], eax
; 5d. For IN transfers, disallow short packets.
; This will be overridden, if needed, by uhci_alloc_transfer.
mov eax, [.token]
1758,13 → 1751,13
dec edx
cmp al, USB_PID_IN
jnz @f
or byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], 1 shl (29-24) ; disallow short packets
or byte [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
or byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], 1 shl (29-24) ; disallow short packets
or byte [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
@@:
; 5e. Get Token field: combine [.token] with [.packetSize].
shl edx, 21
or edx, eax
mov [ecx+uhci_gtd.Token-uhci_gtd.SoftwarePart], edx
mov [ecx+uhci_gtd.Token-sizeof.uhci_gtd], edx
; 6. Flip toggle bit in [.token].
xor eax, 1 shl 19
mov [.token], eax
1785,11 → 1778,14
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
proc uhci_insert_transfer
; DEBUGF 1,'K : uhci_insert_transfer: eax=%x, ecx=%x, [esp+4]=%x\n',eax,ecx,[esp+4]
and byte [eax+uhci_gtd.ControlStatus+2-uhci_gtd.SoftwarePart], not (1 shl (23-16)) ; clear Active bit
or byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], 1 shl (24-24) ; set InterruptOnComplete bit
and byte [eax+uhci_gtd.ControlStatus+2-sizeof.uhci_gtd], not (1 shl (23-16)) ; clear Active bit
or byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], 1 shl (24-24) ; set InterruptOnComplete bit
mov eax, [esp+4]
or byte [eax+uhci_gtd.ControlStatus+2-uhci_gtd.SoftwarePart], 1 shl (23-16) ; set Active bit
or byte [eax+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 4 ; set Depth bit
or byte [eax+uhci_gtd.ControlStatus+2-sizeof.uhci_gtd], 1 shl (23-16) ; set Active bit
test [ebx+usb_pipe.Type], 1
jnz @f
or byte [eax+uhci_gtd.NextTD-sizeof.uhci_gtd], 4 ; set Depth bit
@@:
ret
endp
 
1798,7 → 1794,7
; and the temporary buffer, if present.
proc uhci_free_td
mov eax, [esp+4]
mov eax, [eax+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
mov eax, [eax+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
and eax, not 1
jz .nobuf
push ebx
1805,6 → 1801,6
call free
pop ebx
.nobuf:
sub dword [esp+4], uhci_gtd.SoftwarePart
sub dword [esp+4], sizeof.uhci_gtd
jmp usb_free_common
endp
/kernel/branches/Kolibri-acpi/const.inc
272,6 → 272,11
BOOT_APM_CODE_32 equ 0x9050
BOOT_APM_CODE_16 equ 0x9052
BOOT_APM_DATA_16 equ 0x9054
BOOT_IDE_BAR0_16 equ 0x9056
BOOT_IDE_BAR1_16 equ 0x9058
BOOT_IDE_BAR2_16 equ 0x905A
BOOT_IDE_BAR3_16 equ 0x905C
BOOT_IDE_PI_16 equ 0x905E
 
TMP_FILE_NAME equ 0
TMP_CMD_LINE equ 1024
/kernel/branches/Kolibri-acpi/core/malloc.inc
22,7 → 22,7
;
align 4
malloc:
push esi
push ebx esi
 
; nb = ((size+7)&~7)+8;
 
96,7 → 96,7
mov ecx, mst.mutex
call mutex_unlock
mov eax, esi
pop esi
pop esi ebx
ret
 
.split:
205,7 → 205,7
test eax, eax
jz .exit
 
push edi
push ebx edi
mov edi, eax
add edi, -8
 
298,7 → 298,7
mov eax, esi
pop esi
.fail:
pop edi
pop edi ebx
.exit:
ret
 
/kernel/branches/Kolibri-acpi/core/v86.inc
896,6 → 896,7
iretd
.found:
mov cr3, eax
mov esi, [ebx+APPDATA.saved_esp0]
sub word [esi-sizeof.v86_regs+v86_regs.esp], 6
mov ecx, [esi-sizeof.v86_regs+v86_regs.eip]
mov word [edx], cx
916,7 → 917,7
call update_counters
lea edi, [ebx + 0x100000000 - SLOT_BASE]
shr edi, 3
add edi, TASK_DATA
add edi, CURRENT_TASK
call find_next_task.found
call do_change_task
popad
/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc
44,6 → 44,8
jmp EndFindHDD
 
FindHDD_1:
DEBUGF 1, "K : Channel %d ",[ChannelNumber]:2
DEBUGF 1, "Disk %d\n",[DiskNumber]:1
call ReadHDD_ID
cmp [DevErrorCode], 0
jne FindHDD_2
52,7 → 54,7
cmp [Sector512+12], word 255
ja FindHDD_2
inc byte [DRIVE_DATA+1]
jmp FindHDD_2_2
jmp Print_Device_Name
FindHDD_2:
call DeviceReset
cmp [DevErrorCode], 0
62,6 → 64,21
jne FindHDD_2_2
inc byte [DRIVE_DATA+1]
inc byte [DRIVE_DATA+1]
Print_Device_Name:
pushad
pushfd
mov esi, Sector512+27*2
mov edi, dev_name
mov ecx, 20
cld
@@:
lodsw
xchg ah, al
stosw
loop @b
popfd
popad
DEBUGF 1, "K : Dev: %s \n", dev_name
FindHDD_2_2:
ret
 
70,10 → 87,11
shl byte [DRIVE_DATA+1], 2
ret
 
 
; Адрес считываемого сектора в режиме LBA
uglobal
SectorAddress DD ?
dev_name:
rb 41
endg
;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА *
/kernel/branches/Kolibri-acpi/detect/getcache.inc
206,7 → 206,4
ret
 
end_get_cache:
; mov [cache_ide0_pointer],HD_CACHE
; mov [cache_ide0_system_data],HD_CACHE+65536
; mov [cache_ide0_system_sad_size],1919
popa
/kernel/branches/Kolibri-acpi/detect/sear_par.inc
17,7 → 17,8
search_partitions_ide0:
test [DRIVE_DATA+1], byte 0x40
jz search_partitions_ide1
mov [hdbase], 0x1f0
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x0
mov [hdpos], 1
mov [known_part], 1
39,7 → 40,8
search_partitions_ide1:
test [DRIVE_DATA+1], byte 0x10
jz search_partitions_ide2
mov [hdbase], 0x1f0
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x10
mov [hdpos], 2
mov [known_part], 1
61,7 → 63,8
search_partitions_ide2:
test [DRIVE_DATA+1], byte 0x4
jz search_partitions_ide3
mov [hdbase], 0x170
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x0
mov [hdpos], 3
mov [known_part], 1
83,7 → 86,8
search_partitions_ide3:
test [DRIVE_DATA+1], byte 0x1
jz end_search_partitions_ide
mov [hdbase], 0x170
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10
mov [hdpos], 4
mov [known_part], 1
/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt
1794,6 → 1794,23
* При создании процесса/потока текущая папка наследуется от
родителя.
 
---- Подфункция 3 - установить доп. системную директорию для ядра ----
Параметры:
* eax = 30 - номер функции
* ebx = 3 - номер подфункции
* ecx = указатель на блок данных:
sysdir_name rb 64
sysdir_path rb 64
Пример:
dir_name1 db 'addappl',0
rb 64-8
dir_path1 db 'HD0/1',0
rb 64-6
Возвращаемое значение:
* функция не возвращает значения
Замечания:
* Функция может быть вызвана только 1 раз за 1 сессию работы ОС.
 
======================================================================
========= Функция 34 - узнать кому принадлежит точка экрана. =========
======================================================================
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
1776,6 → 1776,23
* At process/thread creation the current folder will be inherited
from the parent.
 
--- Subfunction 3 - install the add.system directory for the kernel --
Parameters:
* eax = 30 - function number
* ebx = 3 - subfunction number
* ecx = pointer to a block of data:
sysdir_name rb 64
sysdir_path rb 64
For example:
dir_name1 db 'addappl',0
rb 64-8
dir_path1 db 'HD0/1',0
rb 64-6
Returned value:
* function does not return value
Remarks:
* The function can be called only 1 time for 1 session of the OS.
 
======================================================================
========= Function 34 - who owner the pixel on the screen. ===========
======================================================================
/kernel/branches/Kolibri-acpi/drivers/vidintel.asm
310,7 → 310,9
end if
and byte [esi+7000Bh], not 80h ; PIPEACONF: disable pipe
and byte [esi+7100Bh], not 80h ; PIPEBCONF: disable pipe
if 1
cmp [deviceType], gen4_start
jb .wait_watching_scanline
; g45 and later: use special flag from PIPE*CONF
mov edx, 10000h
@@:
mov ecx, 1000h
319,20 → 321,17
jz @f
dec edx
jnz @b
.not_disabled:
sti
jmp .return
jmp .not_disabled
@@:
test byte [esi+7100Bh], 40h ; PIPEBCONF: wait until pipe disabled
jz @f
jz .disabled
mov ecx, 1000h
loop $
dec edx
jnz @b
jmp .not_disabled
@@:
else
; alternative way of waiting for pipe stop, works too
; pineview and before: wait while scanline still changes
.wait_watching_scanline:
mov edx, 1000h
.dis1:
push dword [esi+71000h]
354,7 → 353,6
sti
jmp .return
.disabled:
end if
lea eax, [esi+61183h]
cmp [deviceType], ironlake_start
jb @f
378,6 → 376,7
and ecx, not 15
shl ecx, 2
mov dword [edx+10188h], ecx ; DSPASTRIDE: set scanline length
mov dword [edx+10184h], 0 ; DSPALINOFF: force write to DSPA* registers
and byte [esi+61233h], not 80h ; PFIT_CONTROL: disable panel fitting
or byte [edx+1000Bh], 80h ; PIPEACONF: enable pipe
; and byte [edx+1000Ah], not 0Ch ; PIPEACONF: enable Display+Cursor Planes
437,6 → 436,9
dw 0x29b2 ; q35g
dw 0x29c2 ; g33g
dw 0x29d2 ; q33g
dw 0xa001 ; pineview
dw 0xa011 ; pineview
gen4_start = ($ - pciids) / 2
dw 0x2a02 ; i965gm
dw 0x2a12 ; i965gm
dw 0x2a42 ; gm45
446,8 → 448,6
dw 0x2e32 ; g45
dw 0x2e42 ; g45
dw 0x2e92 ; g45
dw 0xa001 ; pineview
dw 0xa011 ; pineview
ironlake_start = ($ - pciids) / 2
dw 0x0042 ; ironlake_d
dw 0x0046 ; ironlake_m
/kernel/branches/Kolibri-acpi/fs/ext2.inc
4,8 → 4,8
;; Distributed under terms of the GNU General Public License ;;
;; 02.02.2010 turbanoff - support 70.5 ;;
;; 23.01.2010 turbanoff - support 70.0 70.1 ;;
;; 21.06.2013 yogev_ezra - Translate Russian comments ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
17,31 → 17,34
EXT2_BOOT_LOADER_INO = 5
EXT2_UNDEL_DIR_INO = 6
 
;флаги, указываемый в inode файла
;RUS: флаги, указываемые в inode файла ;ENG: flags specified in file inode
EXT2_S_IFREG = 0x8000
EXT2_S_IFDIR = 0x4000
EXT2_S_IFMT = 0xF000 ;маска для типа файла
EXT2_S_IFMT = 0xF000 ;RUS: маска для типа файла ;ENG: mask for file type
 
;флаги, указываемые в linked list родительской папки
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге
EXT2_FT_DIR = 2 ;это папка
;RUS: флаги, указываемые в linked list родительской папки
;ENG: flags specified in linked list of parent folder
EXT2_FT_REG_FILE = 1 ;RUS: это файл, запись в родительском каталоге
;ENG: this is a file, record in parent catalog
EXT2_FT_DIR = 2 ;RUS: это папка ;ENG: this is a folder
 
;флаги используемые KolibriOS
;RUS: флаги используемые KolibriOS ;ENG: flags used by KolibriOS
FS_FT_HIDDEN = 2
FS_FT_DIR = 0x10 ;это папка
FS_FT_ASCII = 0 ;имя в ascii
FS_FT_UNICODE = 1 ;имя в unicode
FS_FT_DIR = 0x10 ;RUS: это папка ;ENG: this is a folder
FS_FT_ASCII = 0 ;RUS: имя в ascii ;ENG: name in ASCII
FS_FT_UNICODE = 1 ;RUS: имя в unicode ;ENG: name in UNICODE
 
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;тип файла должен указываться в директории
EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;экстенты
EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ;гибкие группы блоков
;реализованные ext[234] features
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;RUS: тип файла должен указываться в директории
;ENG: file type must be specified in the folder
EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;RUS: экстенты ;ENG: extents
EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ;RUS: гибкие группы блоков ;ENG: flexible block groups
 
;RUS: реализованные ext[234] features ;ENG: implemented ext[234] features
EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
or EXT4_FEATURE_INCOMPAT_EXTENTS \
or EXT4_FEATURE_INCOMPAT_FLEX_BG
 
 
;флаги, указываемые для inode в i_flags
;RUS: флаги, указываемые для inode в i_flags ;ENG: flags specified for inode in i_flags
EXT2_EXTENTS_FL = 0x00080000
 
struct EXT2_INODE_STRUC
147,26 → 150,31
log_groups_per_flex db ? ;+372
ends
 
struct EXT4_EXTENT_HEADER ;заголовок блока экстентов/индексов
eh_magic dw ? ;в текущей реализации ext4 должно быть 0xF30A
eh_entries dw ? ;количество экстентов/индексов в блоке
eh_max dw ? ;max количество (используется при записи)
eh_depth dw ? ;глубина дерева (0, если это блок экстентов)
struct EXT4_EXTENT_HEADER ;RUS: заголовок блока экстентов/индексов
eh_magic dw ? ;RUS: в текущей реализации ext4 должно быть 0xF30A
eh_entries dw ? ;RUS: количество экстентов/индексов в блоке
eh_max dw ? ;RUS: max количество (используется при записи)
eh_depth dw ? ;RUS: глубина дерева (0, если это блок экстентов)
eh_generation dd ? ;???
ends
 
struct EXT4_EXTENT ;экстент
ee_block dd ? ;номер ext4 блока
ee_len dw ? ;длина экстента
ee_start_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS)
ee_start_lo dd ? ;младшие 32 бита 48-битного адреса
struct EXT4_EXTENT ;RUS: экстент ;ENG: extent
ee_block dd ? ;RUS: номер ext4 блока ;ENG: number of ext4 block
ee_len dw ? ;RUS: длина экстента ;ENG: extent length
ee_start_hi dw ? ;RUS: старшие 16 бит 48-битного адреса (пока не используются в KOS)
;ENG: upper 16 bits of the 48-bit address (not used in KolibriOS yet)
ee_start_lo dd ? ;RUS: младшие 32 бита 48-битного адреса
;ENG: lower 32 bits of the 48-bit address
ends
 
struct EXT4_EXTENT_IDX ;индес - указатель на блок с экстентами/индексами
ei_block dd ? ;номер ext4 блока
ei_leaf_lo dd ? ;младшие 32 бит 48-битного адреса
ei_leaf_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS)
ei_unused dw ? ;зарезервировано
struct EXT4_EXTENT_IDX ;RUS: индекс - указатель на блок с экстентами/индексами
;ENG: index - pointer to block of extents/indexes
ei_block dd ? ;RUS: номер ext4 блока ;ENG: number of ext4 block
ei_leaf_lo dd ? ;RUS: младшие 32 бит 48-битного адреса
;ENG: lower 32 bits of the 48-bit address
ei_leaf_hi dw ? ;RUS: старшие 16 бит 48-битного адреса (пока не используются в KOS)
;ENG: upper 16 bits of the 48-bit address (not used in KolibriOS yet)
ei_unused dw ? ;RUS: зарезервировано ;ENG: reserved
ends
 
ext2_test_superblock:
230,7 → 238,7
 
shl eax, 7
mov [ext2_data.count_pointer_in_block], eax
mov edx, eax ; потом еще квадрат найдем
mov edx, eax ;RUS: потом еще квадрат найдем ;ENG: we'll find a square later
 
shl eax, 2
mov [ext2_data.block_size], eax
294,11 → 302,11
 
;===================================================================
;получает номер блока из extent inode
;in: ecx = номер блока по порядку
; ebp = адрес extent header`а
;out: ecx - адрес очередного блока в случае успеха
; eax - номер ошибки (если равно 0, то ошибки нет)
;RUS: получает номер блока из extent inode ;ENG: receives block number from extent inode
;RUS: in: ecx = номер блока по порядку ;ENG: in: ecx = consecutive block number
;RUS: ebp = адрес extent header`а ;ENG: ebp = address of extent header
;RUS: out: ecx - адрес очередного блока в случае успеха ;ENG: out: ecx - address of next block, if successful
;RUS: eax - номер ошибки (если равно 0, то ошибки нет) ;ENG: eax - error number (0 - no error)
ext4_block_recursive_search:
cmp word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
jne .fail
369,10 → 377,10
 
;===================================================================
;получает адрес ext2 блока из inode с определнным номером
;in: ecx = номер блока в inode (0..)
; ebp = адрес inode
;out: ecx = адрес очередного блока
; eax - error code
;RUS: in: ecx = номер блока в inode (0..) ;ENG: in: ecx = number of block in inode (0..)
;RUS: ebp = адрес inode ;ENG: ebp = inode address
;RUS: out: ecx = адрес очередного блока ;ENG: out: ecx = next block address
;RUS: eax - error code ;ENG: eax - error code
ext2_get_inode_block:
test [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
jz @F
411,7 → 419,8
mov eax, ecx
div [ext2_data.count_pointer_in_block_square]
 
;eax - номер в полученном блоке edx - номер дальше
;RUS: eax - номер в полученном блоке edx - номер дальше
;ENG: eax - current block number, edx - next block number
mov eax, [ebx + eax*4]
call ext2_get_block
test eax, eax
450,9 → 459,9
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz @F ;если не было ошибки
jnz @F ;RUS: если не было ошибки ;ENG: if there was no error
 
mov ecx, [ebx + ecx*4] ;заносим результат
mov ecx, [ebx + ecx*4] ;RUS: заносим результат ;ENG: ???
@@:
pop ebx
ret
481,8 → 490,10
mov edx, 32
mul edx ; address block_group in global_desc_table
 
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
; найдем блок в котором он находится
;RUS: в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
;RUS: найдем блок в котором он находится
;ENG: in eax - inode group offset relative to global descriptor table start
;ENG: let's find the block this inode is in
div [ext2_data.block_size]
add eax, [ecx + EXT2_SB_STRUC.first_data_block]
inc eax
491,32 → 502,32
test eax, eax
jnz .fail
 
add ebx, edx ; локальный номер в блоке
mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table]; номер блока - в терминах ext2
 
add ebx, edx ;RUS: локальный номер в блоке ;ENG: local number inside block
mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table] ;RUS: номер блока - в терминах ext2
;ENG: block number - in ext2 terms
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512)
add eax, [PARTITION_START] ;RUS: а старт раздела - в терминах hdd (512)
;ENG: partition start - in HDD terms (512)
;RUS: eax - указывает на таблицу inode-ов на hdd ;ENG: eax - points to inode table on HDD
mov esi, eax ;RUS: сохраним его пока в esi ;ENG: let's save it in esi for now
 
;eax - указывает на таблицу inode-ов на hdd
mov esi, eax ;сохраним его пока в esi
 
; прибавим локальный адрес inode-а
;RUS: прибавим локальный адрес inode-а ;ENG: add local address of inode
pop eax ; index
mov ecx, [ext2_data.inode_size]
mul ecx ; (index * inode_size)
mov ebp, 512
div ebp ;поделим на размер блока
div ebp ;RUS: поделим на размер блока ;ENG: divide by block size
 
add eax, esi ;нашли адрес блока для чтения
add eax, esi ;RUS: нашли адрес блока для чтения ;ENG: found block address to read
mov ebx, [ext2_data.ext2_temp_block]
call hd_read
cmp [hd_error], 0
jnz .fail
 
mov esi, edx ;добавим "остаток"
add esi, ebx ;к адресу
rep movsb ;копируем inode
mov esi, edx ;RUS: добавим "остаток" ;ENG: add the "remainder"
add esi, ebx ;RUS: к адресу ;ENG: to the address
rep movsb ;RUS: копируем inode ;ENG: copy inode
xor eax, eax
.fail:
mov PUSHAD_EAX, eax
745,7 → 756,8
lea esp, [edi + 32]
xor eax, eax ;зарезервировано: нули в текущей реализации
xor eax, eax ;RUS: зарезервировано: нули в текущей реализации
;ENG: reserved: zeros in current implementation
lea edi, [edx + 12]
mov ecx, 20 / 4
rep stosd
760,12 → 772,12
or ebx, -1
ret
.error_empty_dir: ;inode папки без блоков
.error_root: ;root - не папка
.error_empty_dir: ;RUS: inode папки без блоков ;ENG: inode of folder without blocks
.error_root: ;RUS: root - не папка ;ENG: root is not a folder
mov eax, ERROR_FS_FAIL
jmp .error_ret
 
.error_not_found: ;файл не найден
.error_not_found: ;RUS: файл не найден ;ENG: file not found
mov eax, ERROR_FILE_NOT_FOUND
jmp .error_ret
867,9 → 879,9
jz @F
mov esi, ebx ; esi = pointer to first_wanted
mov ebx, [esi+4]
mov eax, [esi] ; ebx : eax - стартовый номер байта
mov eax, [esi] ;RUS: ebx : eax - стартовый номер байта ;ENG: ebx : eax - start byte number
 
;///// сравним хватит ли нам файла или нет
;RUS: ///// сравним хватит ли нам файла или нет ;ENG: ///// check if file is big enough for us
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great
jb .size_less
886,7 → 898,8
xor ebx, ebx
xor eax, eax
.size_great:
add eax, ecx ;add to first_wanted кол-во байт для чтения
add eax, ecx ;RUS: add to first_wanted кол-во байт для чтения
;ENG: add to first_wanted number of bytes to read
adc ebx, 0
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
893,16 → 906,16
ja .size_great_great
jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great
jae .size_great_great ; and if it's equal, no matter where we jump
 
.size_great_less:
push 1 ;читаем по границе размера
push 1 ;RUS: читаем по границе размера ;ENG: reading till the end of file
mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;(размер - старт) = сколько читать
sub ecx, [esi] ;RUS: (размер - старт) = сколько читать ;ENG: to read = (size - start)
jmp @F
 
.size_great_great:
push 0 ;читаем столько сколько запросили
push 0 ;RUS: читаем столько, сколько запросили ;ENG: reading as much as requested
 
@@:
;здесь мы точно знаем сколько байт читать - ecx
934,7 → 947,8
add ebx, edx
 
neg edx
add edx, [ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока
add edx, [ext2_data.block_size] ;RUS: block_size - стартовый байт = сколько байт 1-го блока
;ENG: block_size - start byte = number of bytes in 1st block
cmp ecx, edx
jbe .only_one_block
 
943,7 → 957,7
mov ecx, edx
 
mov esi, ebx
rep movsb ;кусок 1-го блока
rep movsb ;RUS: кусок 1-го блока ;ENG: part of 1st block
jmp .calc_blocks_count
 
.zero_start:
1031,7 → 1045,7
ext2_test_block_by_name:
sub esp, 256 ;EXT2_filename
mov edx, ebx
add edx, [ext2_data.block_size] ;запомним конец блока
add edx, [ext2_data.block_size] ;RUS: запомним конец блока ;ENG: save block end
 
.start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0
1045,7 → 1059,7
 
mov ecx, edi
lea edi, [esp + 4]
sub ecx, edi ;кол-во байт в получившейся строке
sub ecx, edi ;RUS: кол-во байт в получившейся строке ;ENG: number of bytes in resulting string
 
mov esi, [esp]
@@:
1061,12 → 1075,12
call char_toupper
cmp al, ah
je @B
@@: ;не подошло
@@: ;RUS: не подошло ;ENG: didn't fit
pop esi
.next_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
add ebx, eax ;к след. записи
cmp ebx, edx ;проверим конец ли
add ebx, eax ;RUS: к след. записи ;ENG: go to next record
cmp ebx, edx ;RUS: проверим конец ли ;ENG: check if this is the end
jb .start_rec
add esp, 256
ret
1073,7 → 1087,7
 
.test_find:
cmp byte [esi], 0
je .ret ;нашли конец
je .ret ;RUS: нашли конец ;ENG: the end reached
cmp byte [esi], '/'
jne @B
inc esi
1111,27 → 1125,28
call ext2_test_block_by_name
pop edi ecx
 
cmp edi, esi ;нашли имя?
je .next_folder_block ;не нашли -> к след. блоку
cmp edi, esi ;RUS: нашли имя? ;ENG: did we find a name?
je .next_folder_block ;RUS: не нашли -> к след. блоку ;ENG: we didn't -> moving to next block
cmp byte [esi], 0 ;дошли до "конца" пути -> возваращаемся
cmp byte [esi], 0 ;RUS: дошли до "конца" пути -> возваращаемся
;ENG: reached the "end" of path -> returning
jz .get_inode_ret
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;нашли, но это не папка
jne .not_found
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;RUS: нашли, но это не папка
jne .not_found ;ENG: found, but it's not a folder
 
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] ;все же папка.
mov ebx, [ext2_data.ext2_save_inode] ;RUS: все же папка. ;ENG: it's a folder afterall
call ext2_get_inode
test eax, eax
jnz .error_get_inode
pop ecx ;в стеке лежит кол-во блоков
pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks
mov ebp, ebx
jmp .next_path_part
.next_folder_block:
;к следующему блоку в текущей папке
pop eax ;счетчик блоков
pop eax ;RUS: счетчик блоков ;ENG: blocks counter
sub eax, [ext2_data.count_block_in_block]
jle .not_found
1144,8 → 1159,8
ret
 
.get_inode_ret:
pop ecx ;в стеке лежит кол-во блоков
mov dl, [ebx + EXT2_DIR_STRUC.name] ;в dl - первый символ ()
pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks
mov dl, [ebx + EXT2_DIR_STRUC.name] ;RUS: в dl - первый символ () ;ENG: ???
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode
1182,7 → 1197,7
ret
 
.is_root:
xor ebx, ebx ;root не может быть скрытым
xor ebx, ebx ;RUS: root не может быть скрытым ;ENG: root cannot be hidden
mov ebp, [ext2_data.root_inode]
@@:
xor eax, eax
/kernel/branches/Kolibri-acpi/fs/fat32.inc
166,10 → 166,8
; FAT size requires knowledge of some calculated values, which are also used
; in the normal operation, let's hope for the best and allocate data now; if
; it will prove wrong, just deallocate it.
push ebx
movi eax, sizeof.FAT
call malloc
pop ebx
test eax, eax
jz .return0
mov ecx, [ebp+8]
2441,7 → 2439,6
pop eax
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
pop edi
test eax, eax
jz @f
push ERROR_DEVICE
/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc
525,25 → 525,29
 
fs_OnHd0:
call reserve_hd1
mov [hdbase], 0x1F0
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1F0
mov [hdid], 0
push 1
jmp fs_OnHd
fs_OnHd1:
call reserve_hd1
mov [hdbase], 0x1F0
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1F0
mov [hdid], 0x10
push 2
jmp fs_OnHd
fs_OnHd2:
call reserve_hd1
mov [hdbase], 0x170
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0
push 3
jmp fs_OnHd
fs_OnHd3:
call reserve_hd1
mov [hdbase], 0x170
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10
push 4
fs_OnHd:
932,24 → 936,30
pop eax
inc eax
ret
 
;-----------------------------------------------------------------------------
process_replace_file_name:
; in
; esi - path with filename(f.70)
;
; out
; ebp - full filename
pushfd
cli
mov ebp, [full_file_name_table]
mov edi, [full_file_name_table.size]
dec edi
shl edi, 7
add edi, ebp
xor edi, edi
.loop:
cmp edi, ebp
jb .notfound
cmp edi, [full_file_name_table.size]
jae .notfound
push esi edi
shl edi, 7 ; edi*128
add edi, ebp
@@:
cmp byte [edi], 0
cmp byte [edi], 0 ; end of dir_name
jz .dest_done
lodsb
test al, al
jz .cont
or al, 20h
or al, 20h ; 32 - space char
scasb
jz @b
jmp .cont
962,10 → 972,12
jmp .found
.cont:
pop edi esi
sub edi, 128
inc edi
jmp .loop
.found:
pop edi eax
shl edi, 7 ; edi*128
add edi, ebp
mov ebp, esi
cmp byte [esi], 0
lea esi, [edi+64]
973,7 → 985,12
.notfound:
xor ebp, ebp
.ret:
popfd
ret
;-----------------------------------------------------------------------------
uglobal
lock_flag_for_f30_3 rb 1
endg
 
sys_current_directory:
; mov esi, [current_slot]
988,7 → 1005,45
jz .set
dec ebx
jz .get
dec ebx
jz .mount_additional_directory
ret
 
.mount_additional_directory:
; sysfunction 30.2: [for app] eax=30,ebx=3,ecx->dir name+dir path (128)
; for our code: nothing
 
; check lock of the function
cmp [lock_flag_for_f30_3], 1
je @f
mov esi, ecx
mov edi, sysdir_name1
; copying fake directory name
mov ecx, 63
pushfd
cli
cld
rep movsb
; terminator of name, in case if we get the inlet trash
inc esi
xor eax, eax
stosb
; copying real directory path for mounting
mov ecx, 63
rep movsb
; terminator of name, in case if we get the inlet trash
xor eax, eax
stosb
; increase the pointer of inputs for procedure "process_replace_file_name"
mov [full_file_name_table.size], 2
; block the ability to call f.30.3 because for one session is necessary
; for us only once
mov [lock_flag_for_f30_3], 1
popfd
@@:
ret
.get:
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
; for our code: ebx->buffer,ecx=len
/kernel/branches/Kolibri-acpi/fs/parse_fn.inc
32,6 → 32,17
; Parser_params will initialize: sysdir_name = "sys", sysdir_path = <sysdir>
sysdir_name rb 64
sysdir_path rb 64
sysdir_name1 rb 64
sysdir_path1 rb 64
 
; for example:
;dir_name1 db 'addappl',0
; rb 64-8
;dir_path1 db 'HD0/1',0
; rb 64-6
endg
 
uglobal
tmp_file_name_table dd ?
endg
 
/kernel/branches/Kolibri-acpi/fs/part_set.inc
77,10 → 77,10
.inode_size dd ?
.count_pointer_in_block dd ? ; block_size / 4
.count_pointer_in_block_square dd ? ; (block_size / 4)**2
.ext2_save_block dd ? ; блок на глобальную 1 процедуру
.ext2_temp_block dd ? ; блок для мелких процедур
.ext2_save_inode dd ? ; inode на глобальную процедуру
.ext2_temp_inode dd ? ; inode для мелких процедур
.ext2_save_block dd ? ;RUS: блок на глобальную 1 процедуру ;ENG: block for 1 global procedure
.ext2_temp_block dd ? ;RUS: блок для мелких процедур ;ENG: block for small procedures
.ext2_save_inode dd ? ;RUS: inode на глобальную процедуру ;ENG: inode for global procedure
.ext2_temp_inode dd ? ;RUS: inode для мелких процедур ;ENG: inode for small procedures
.sb dd ? ; superblock
.groups_count dd ?
if $ > fs_dependent_data_end
/kernel/branches/Kolibri-acpi/gui/font.inc
7,8 → 7,6
 
$Revision$
 
include "lang.inc"
 
;------------------------------------------------------------------------------
align 4
dtext_asciiz_esi: ; for skins title out
/kernel/branches/Kolibri-acpi/init.inc
453,6 → 453,9
acpi_dev_size rd 1
 
acpi_rsdt_base rd 1
acpi_fadt_base rd 1
acpi_dsdt_base rd 1
acpi_dsdt_size rd 1
acpi_madt_base rd 1
acpi_ioapic_base rd 1
 
464,6 → 467,7
ACPI_HI_RSDP_WINDOW_END equ 0x00100000
ACPI_RSDP_CHECKSUM_LENGTH equ 20
ACPI_MADT_SIGN equ 0x43495041
ACPI_FADT_SIGN equ 0x50434146
 
 
acpi_locate:
535,10 → 539,23
jz .done
 
mov ecx, [eax+16]
mov edx, ACPI_MADT_SIGN
mov edx, 0x50434146
mov [acpi_rsdt_base-OS_BASE], ecx
call rsdt_find
mov [acpi_fadt_base-OS_BASE], eax
test eax, eax
jz @f
 
mov eax, [eax+40]
mov [acpi_dsdt_base-OS_BASE], eax
mov eax, [eax+4]
mov [acpi_dsdt_size-OS_BASE], eax
 
@@:
mov edx, ACPI_MADT_SIGN
mov ecx, [acpi_rsdt_base-OS_BASE]
call rsdt_find
test eax, eax
jz .done
 
mov [acpi_madt_base-OS_BASE], eax
/kernel/branches/Kolibri-acpi/kernel.asm
358,8 → 358,44
call mutex_init
 
; SAVE REAL MODE VARIABLES
xor eax, eax
mov ax, [BOOT_VAR + BOOT_IDE_PI_16]
mov [IDEContrProgrammingInterface], ax
mov ax, [BOOT_VAR + BOOT_IDE_BASE_ADDR]
mov [IDEContrRegsBaseAddr], ax
mov ax, [BOOT_VAR + BOOT_IDE_BAR0_16]
mov [IDE_BAR0_val], ax
 
cmp ax, 0
je @f
 
cmp ax, 1
je @f
 
and ax, 0xfff0
mov [StandardATABases], ax
mov [hd_address_table], eax
mov [hd_address_table+8], eax
@@:
mov ax, [BOOT_VAR + BOOT_IDE_BAR1_16]
mov [IDE_BAR1_val], ax
mov ax, [BOOT_VAR + BOOT_IDE_BAR2_16]
mov [IDE_BAR2_val], ax
 
cmp ax, 0
je @f
 
cmp ax, 1
je @f
 
and ax, 0xfff0
mov [StandardATABases+2], ax
mov [hd_address_table+16], eax
mov [hd_address_table+24], eax
@@:
mov ax, [BOOT_VAR + BOOT_IDE_BAR3_16]
mov [IDE_BAR3_val], ax
 
; --------------- APM ---------------------
 
; init selectors
1014,6 → 1050,12
@@:
DEBUGF 1, "K : %d CPU detected\n", eax
 
DEBUGF 1, "K : BAR0 %x \n", [IDE_BAR0_val]:4
DEBUGF 1, "K : BAR1 %x \n", [IDE_BAR1_val]:4
DEBUGF 1, "K : BAR2 %x \n", [IDE_BAR2_val]:4
DEBUGF 1, "K : BAR3 %x \n", [IDE_BAR3_val]:4
DEBUGF 1, "K : BAR4 %x \n", [IDEContrRegsBaseAddr]:4
DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", [IDEContrProgrammingInterface]:4
; START MULTITASKING
 
; A 'All set - press ESC to start' messages if need
1028,6 → 1070,17
 
cmp [IDEContrRegsBaseAddr], 0
setnz [dma_hdd]
 
cmp [dma_hdd], 0
je .print_pio
.print_dma:
DEBUGF 1, "K : IDE DMA mode\n"
jmp .continue
 
.print_pio:
DEBUGF 1, "K : IDE PIO mode\n"
.continue:
 
mov [timer_ticks_enable], 1 ; for cd driver
 
sti
1585,23 → 1638,27
 
dec ecx
jnz noprma
mov [cdbase], 0x1f0
mov eax, [hd_address_table]
mov [cdbase], eax ;0x1f0
mov [cdid], 0xa0
noprma:
 
dec ecx
jnz noprsl
mov [cdbase], 0x1f0
mov eax, [hd_address_table]
mov [cdbase], eax ;0x1f0
mov [cdid], 0xb0
noprsl:
dec ecx
jnz nosema
mov [cdbase], 0x170
mov eax, [hd_address_table+16]
mov [cdbase], eax ;0x170
mov [cdid], 0xa0
nosema:
dec ecx
jnz nosesl
mov [cdbase], 0x170
mov eax, [hd_address_table+16]
mov [cdbase], eax ;0x170
mov [cdid], 0xb0
nosesl:
ret
1630,7 → 1687,8
 
cmp ecx, 1
jnz noprmahd
mov [hdbase], 0x1f0
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
and dword [hdid], 0x0
mov dword [hdpos], ecx
; call set_FAT32_variables
1638,7 → 1696,8
 
cmp ecx, 2
jnz noprslhd
mov [hdbase], 0x1f0
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x10
mov dword [hdpos], ecx
; call set_FAT32_variables
1646,7 → 1705,8
 
cmp ecx, 3
jnz nosemahd
mov [hdbase], 0x170
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
and dword [hdid], 0x0
mov dword [hdpos], ecx
; call set_FAT32_variables
1654,7 → 1714,8
 
cmp ecx, 4
jnz noseslhd
mov [hdbase], 0x170
mov eax,[hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10
mov dword [hdpos], ecx
; call set_FAT32_variables
5409,7 → 5470,6
; calculate data area for fast getting offset to _WinMapAddress
xor eax, eax
mov ecx, [_display.height]
inc ecx
mov edi, d_width_calc_area
cld
@@:
5424,7 → 5484,6
; calculate data area for fast getting offset to LFB
xor eax, eax
mov ecx, [_display.height]
inc ecx
mov edi, BPSLine_calc_area
cld
@@:
5816,7 → 5875,6
 
__REV__ = __REV
 
uglobals_size = $ - endofcode
if ~ lang eq sp
diff16 "end of kernel code",0,$
end if
/kernel/branches/Kolibri-acpi/network/ARP.inc
55,10 → 55,9
 
ends
 
uglobal
align 4
uglobal
 
 
ARP_table rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry)
 
ARP_entries_num rd NET_DEVICES_MAX
176,13 → 175,13
cmp ecx, sizeof.ARP_header
jb .exit
 
call NET_ptr_to_num
call NET_ptr_to_num4
cmp edi, -1
jz .exit
 
inc [ARP_PACKETS_RX + 4*edi] ; update stats
inc [ARP_PACKETS_RX + edi] ; update stats
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: got packet from %u.%u.%u.%u through device %u\n",\
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: got packet from %u.%u.%u.%u (device*4=%u)\n",\
[edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP + 1]:1,\
[edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi
 
190,7 → 189,7
; First, check for IP collision
 
mov eax, [edx + ARP_header.SenderIP]
cmp eax, [IP_LIST + 4*edi]
cmp eax, [IP_LIST + edi]
je .collision
 
;---------------------
201,12 → 200,12
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n"
 
mov ecx, [ARP_entries_num + 4*edi]
mov ecx, [ARP_entries_num + edi]
test ecx, ecx
jz .exit
 
mov esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)
imul esi, edi
mov esi, edi
imul esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
add esi, ARP_table
.loop:
cmp [esi + ARP_entry.IP], eax
245,7 → 244,7
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: its a request\n"
 
mov eax, [IP_LIST + 4*edi]
mov eax, [IP_LIST + edi]
cmp eax, [edx + ARP_header.TargetIP] ; Is it looking for my IP address?
jne .exit
 
262,7 → 261,7
movsd ; Move sender IP to Dest IP
 
pop esi
mov esi, [NET_DRV_LIST + 4*esi]
mov esi, [NET_DRV_LIST + esi]
lea esi, [esi + ETH_DEVICE.mac]
lea edi, [edx + ARP_header.SenderMAC]
movsd ; Copy MAC address from in MAC_LIST
290,7 → 289,7
ret
 
.collision:
inc [ARP_CONFLICTS + 4*edi]
inc [ARP_CONFLICTS + edi]
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n"
 
.exit:
337,11 → 336,11
movsw ;
movsd ;
 
; mov esi, [ebx + NET_DEVICE.number]
xor esi, esi ;;;; FIXME
inc esi ;;;;;;;;;
inc [ARP_PACKETS_TX + 4*esi] ; assume we will succeed
lea esi, [IP_LIST + 4*esi] ; SenderIP
push edi
call NET_ptr_to_num4
inc [ARP_PACKETS_TX + edi] ; assume we will succeed
lea esi, [IP_LIST + edi] ; SenderIP
pop edi
movsd
 
mov esi, ETH_BROADCAST ; DestMac
364,7 → 363,7
; ARP_add_entry (or update)
;
; IN: esi = ptr to entry (can easily be made on the stack)
; edi = device num
; edi = device num*4
; OUT: eax = entry #, -1 on error
; esi = ptr to newly created entry
;
374,17 → 373,17
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_add_entry: device=%u\n", edi
 
mov ecx, [ARP_entries_num + 4*edi]
mov ecx, [ARP_entries_num + edi]
cmp ecx, ARP_TABLE_SIZE ; list full ?
jae .full
 
; From this point on, we can only fail if IP has a static entry, or if table is corrupt.
 
inc [ARP_entries_num + 4*edi] ; assume we will succeed
inc [ARP_entries_num + edi] ; assume we will succeed
 
push edi
xor ecx, ecx
imul edi, ARP_TABLE_SIZE*sizeof.ARP_entry
imul edi, ARP_TABLE_SIZE*sizeof.ARP_entry/4
add edi, ARP_table
mov eax, [esi + ARP_entry.IP]
.loop:
419,7 → 418,7
 
.error:
pop edi
dec [ARP_entries_num + 4*edi]
dec [ARP_entries_num + edi]
DEBUGF DEBUG_NETWORK_ERROR, "ARP_add_entry_failed\n"
.full:
mov eax, -1
475,7 → 474,7
; This function translates an IP address to a MAC address
;
; IN: eax = IPv4 address
; edi = device number
; edi = device number * 4
; OUT: eax = -1 on error, -2 means request send
; else, ax = first two bytes of mac (high 16 bits of eax will be 0)
; ebx = last four bytes of mac
487,7 → 486,7
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah
rol eax, 16
DEBUGF DEBUG_NETWORK_VERBOSE, ".%u.%u device: %u\n", al, ah, edi
DEBUGF DEBUG_NETWORK_VERBOSE, ".%u.%u device*4: %u\n", al, ah, edi
rol eax, 16
 
cmp eax, 0xffffffff
496,11 → 495,11
;--------------------------------
; Try to find the IP in ARP_table
 
mov ecx, [ARP_entries_num + 4*edi]
mov ecx, [ARP_entries_num + edi]
test ecx, ecx
jz .not_in_list
mov esi, edi
imul esi, sizeof.ARP_entry * ARP_TABLE_SIZE
imul esi, (sizeof.ARP_entry * ARP_TABLE_SIZE)/4
add esi, ARP_table + ARP_entry.IP
.scan_loop:
cmp [esi], eax
538,7 → 537,7
pop edi eax ; IP in eax, device number in ebx, for ARP_output_request
 
push esi edi
mov ebx, [NET_DRV_LIST + 4*edi]
mov ebx, [NET_DRV_LIST + edi]
call ARP_output_request
pop edi esi
.found_it:
655,7 → 654,6
.write:
; esi = pointer to buffer
mov edi, eax
shr edi, 2
call ARP_add_entry ; out: eax = entry number, -1 on error
ret
 
/kernel/branches/Kolibri-acpi/network/IPv4.inc
55,8 → 55,8
ends
 
 
uglobal
align 4
uglobal
 
IP_LIST rd NET_DEVICES_MAX
SUBNET_LIST rd NET_DEVICES_MAX
69,6 → 69,7
IP_packets_dumped rd NET_DEVICES_MAX
 
FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot
 
endg
 
 
223,8 → 224,7
;-----------------------------------
; Check if destination IP is correct
 
call NET_ptr_to_num
shl edi, 2
call NET_ptr_to_num4
 
; check if it matches local ip (Using RFC1122 strong end system model)
 
586,9 → 586,9
push ebx ; push the mac onto the stack
push ax
 
inc [IP_packets_tx + 4*edi] ; update stats
inc [IP_packets_tx + edi] ; update stats
 
mov ebx, [NET_DRV_LIST + 4*edi]
mov ebx, [NET_DRV_LIST + edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 10 + 6]
857,7 → 857,7
; IPv4_route
;
; IN: eax = Destination IP
; OUT: edi = device number
; OUT: edi = device number*4
; eax = ip of gateway if nescessary, unchanged otherwise
;
;---------------------------------------------------------------------------
890,8 → 890,7
.invalid:
mov eax, [GATEWAY_LIST+4] ;;; FIXME
.broadcast:
xor edi, edi ; if none found, use device 1 as default ;;;; FIXME
inc di
mov edi, 4 ; if none found, use device 1 as default ;;;; FIXME
ret
 
 
/kernel/branches/Kolibri-acpi/network/IPv6.inc
30,8 → 30,8
ends
 
 
uglobal
align 4
uglobal
 
IPv6:
.addresses rd 4*NET_DEVICES_MAX
/kernel/branches/Kolibri-acpi/network/PPPoE.inc
23,8 → 23,11
ends
 
uglobal
align 4
 
PPPoE_SID dw ?
PPPoE_MAC dp ?
 
endg
 
;-----------------------------------------------------------------
63,6 → 66,11
 
; First, find open PPPoE socket
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov eax, net_sockets
 
.next_socket:
76,6 → 84,11
cmp [eax + SOCKET.Protocol], PPP_PROTO_ETHERNET
jne .next_socket
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
; Now, send it to the this socket
 
mov ecx, [esp + 4]
84,6 → 97,11
jmp SOCKET_input
 
.dump:
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n'
call kernel_free
add esp, 4
/kernel/branches/Kolibri-acpi/network/ethernet.inc
32,8 → 32,8
 
ends
 
iglobal
align 4
iglobal
 
ETH_BROADCAST dp 0xffffffffffff
endg
57,9 → 57,8
mov ecx, [esp+4]
 
DEBUGF DEBUG_NETWORK_VERBOSE,"ETH_input: size=%u\n", ecx
cmp ecx, ETH_FRAME_MINIMUM
sub ecx, sizeof.ETH_header
jb .dump
sub ecx, sizeof.ETH_header
 
lea edx, [eax + sizeof.ETH_header]
mov ax, [eax + ETH_header.Type]
/kernel/branches/Kolibri-acpi/network/icmp.inc
97,10 → 97,12
ends
 
 
uglobal
align 4
uglobal
 
ICMP_PACKETS_TX rd NET_DEVICES_MAX
ICMP_PACKETS_RX rd NET_DEVICES_MAX
 
endg
 
 
156,9 → 158,17
pop ecx edx
jne .checksum_mismatch
 
; Check packet type
 
cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets
 
; Update stats (and validate device ptr)
call NET_ptr_to_num4
cmp edi, -1
je .dump
inc [ICMP_PACKETS_RX + edi]
 
; We well re-use the packet so we can create the response as fast as possible
; Notice: this only works on pure ethernet
 
166,14 → 176,6
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
 
mov esi, [esp] ; Start of buffer
 
; Update stats (and validate device ptr)
call NET_ptr_to_num
cmp edi, -1
je .dump
inc [ICMP_PACKETS_RX + 4*edi]
inc [ICMP_PACKETS_TX + 4*edi]
 
cmp ebx, LOOPBACK_DEVICE
je .loopback
 
225,6 → 227,11
 
; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [UDP_PACKETS_TX + edi]
@@:
ret
 
 
233,6 → 240,11
.check_sockets:
; Look for an open ICMP socket
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov esi, [edi] ; ipv4 source address
mov eax, net_sockets
.try_more:
240,7 → 252,7
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump
jz .dump_
 
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
254,11 → 266,17
; cmp [eax + ICMP_SOCKET.Identifier],
; jne .next_socket
 
; call IPv4_dest_to_dev
; cmp edi,-1
; je .dump
; inc [ICMP_PACKETS_RX+edi]
; Update stats (and validate device ptr)
call NET_ptr_to_num4
cmp edi, -1
je .dump_
inc [ICMP_PACKETS_RX + edi]
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "socket=%x\n", eax
 
pusha
269,7 → 287,17
mov esi, edx
jmp SOCKET_input
 
.dump_:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: no socket found\n"
jmp .dump
 
 
.checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n"
 
336,6 → 364,11
push edx edi
DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
386,6 → 419,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
/kernel/branches/Kolibri-acpi/network/loopback.inc
17,6 → 17,7
$Revision: 2891 $
 
iglobal
align 4
 
LOOPBACK_DEVICE:
 
/kernel/branches/Kolibri-acpi/network/queue.inc
28,6 → 28,7
size dd ? ; number of queued packets in this queue
w_ptr dd ? ; current writing pointer in queue
r_ptr dd ? ; current reading pointer
mutex MUTEX
 
ends
 
44,9 → 45,23
 
macro add_to_queue ptr, size, entry_size, failaddr {
 
local .ok, .no_wrap
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
 
cmp [ptr + queue.size], size ; Check if queue isnt full
jae failaddr
jb .ok
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr
 
.ok:
inc [ptr + queue.size] ; if not full, queue one more
 
mov edi, [ptr + queue.w_ptr] ; Current write pointer (FIFO!)
58,10 → 73,14
jb .no_wrap
 
sub edi, size*entry_size
 
.no_wrap:
mov [ptr + queue.w_ptr], edi
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
 
}
 
 
68,9 → 87,23
 
macro get_from_queue ptr, size, entry_size, failaddr {
 
local .ok, .no_wrap
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
 
cmp [ptr + queue.size], 0 ; any packets queued?
je failaddr
ja .ok
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr
 
.ok:
dec [ptr + queue.size] ; if so, dequeue one
 
mov esi, [ptr + queue.r_ptr]
89,6 → 122,11
 
pop esi
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
 
}
 
macro init_queue ptr {
97,4 → 135,7
lea edi, [ptr + sizeof.queue]
mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi
 
lea ecx, [ptr + queue.mutex]
call mutex_init
}
/kernel/branches/Kolibri-acpi/network/socket.inc
17,7 → 17,6
 
$Revision$
 
 
struct SOCKET
 
NextPtr dd ? ; pointer to next socket in list
195,10 → 194,14
SOCKET_QUEUE_LOCATION = (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue)
 
uglobal
align 4
 
net_sockets rd 4
last_socket_num dd ?
last_UDP_port dw ? ; These values give the number of the last used ephemeral port
last_TCP_port dw ? ;
socket_mutex MUTEX
 
endg
 
 
232,6 → 235,9
xchg al, ah
mov [last_TCP_port], ax
 
mov ecx, socket_mutex
call mutex_init
 
}
 
;-----------------------------------------------------------------
242,11 → 248,13
align 4
sys_socket:
 
mov dword[esp+20], 0 ; Set error code to 0
 
cmp ebx, 255
jz SOCKET_debug
 
cmp ebx, .number
ja s_error
ja .error
jmp dword [.table + 4*ebx]
 
.table:
263,9 → 271,9
dd SOCKET_pair ; 10
.number = ($ - .table) / 4 - 1
 
s_error:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET: error\n"
.error:
mov dword [esp+32], -1
mov dword[esp+20], EINVAL
 
ret
 
287,16 → 295,16
push ecx edx esi
call SOCKET_alloc
pop esi edx ecx
jz s_error
jz .nobuffs
 
mov [esp+32], edi ; return socketnumber
DEBUGF DEBUG_NETWORK_VERBOSE, "socknum=%u\n", edi
 
; push edx
; and edx, SO_NONBLOCK
or [eax + SOCKET.options], SO_NONBLOCK ;edx
; pop edx
; and edx, not SO_NONBLOCK
test edx, SO_NONBLOCK
jz @f
or [eax + SOCKET.options], SO_NONBLOCK
and edx, not SO_NONBLOCK
@@:
 
mov [eax + SOCKET.Domain], ecx
mov [eax + SOCKET.Type], edx
322,25 → 330,28
je .pppoe
 
.no_ppp:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_open: Unknown socket family/protocol\n"
.unsupported:
push eax
call SOCKET_free
pop eax
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
align 4
.nobuffs:
mov dword[esp+20], ENOBUFS
mov dword[esp+32], -1
ret
 
.raw:
test esi, esi ; IP_PROTO_IP
jz .ip
jz .raw_ip
 
cmp esi, IP_PROTO_ICMP
je .icmp
je .raw_icmp
 
cmp esi, IP_PROTO_UDP
je .udp
jmp .unsupported
 
cmp esi, IP_PROTO_TCP
je .tcp
 
ret
 
align 4
.udp:
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
359,7 → 370,7
 
 
align 4
.ip:
.raw_ip:
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
366,7 → 377,7
 
 
align 4
.icmp:
.raw_icmp:
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
398,10 → 409,10
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp esi, 2
jb s_error
jb .invalid
 
cmp word [edx], AF_INET4
je .af_inet4
409,18 → 420,24
cmp word [edx], AF_LOCAL
je .af_local
 
jmp s_error
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
.af_local:
; TODO: write code here
 
mov dword [esp+32], 0
ret
 
.af_inet4:
 
cmp esi, 6
jb s_error
jb .invalid
 
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
je .udp
428,12 → 445,11
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
je .tcp
 
jmp s_error
jmp .notsupp
 
.tcp:
.udp:
 
cmp ebx, [edx + 4] ; First, fill in the IP
mov ebx, [edx + 4] ; First, fill in the IP
test ebx, ebx ; If IP is 0, use default
jnz @f
mov ebx, [IP_LIST + 4] ;;;;; FIXME !i!i!i
442,7 → 458,7
 
mov bx, [edx + 2] ; Now fill in the local port if it's still available
call SOCKET_check_port
jz s_error ; ZF is set by socket_check_port, on error
jz .addrinuse ; ZF is set by socket_check_port, on error
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\
[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
451,9 → 467,14
mov dword [esp+32], 0
ret
 
.addrinuse:
mov dword[esp+32], -1
mov dword[esp+20], EADDRINUSE
ret
 
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_connect
470,16 → 491,24
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp esi, 8
jb s_error
jb .invalid
 
cmp word [edx], AF_INET4
je .af_inet4
 
jmp s_error
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
.af_inet4:
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
499,7 → 528,7
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
je .ip
 
jmp s_error
jmp .notsupp
 
align 4
.udp:
557,18 → 586,15
pop [eax + TCP_SOCKET.ISS]
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
 
 
TCP_sendseqinit eax
 
; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer
 
mov ebx, eax
 
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create
call SOCKET_ring_create ; TODO: check if memory was available or not
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
call SOCKET_ring_create ; TODO: same here
 
pusha
lea ecx, [ebx + SOCKET.mutex]
575,14 → 601,40
call mutex_unlock
popa
 
push ebx
mov eax, ebx
call TCP_output
pop eax
 
;;; TODO: wait for successfull connection if blocking socket
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jz .loop
 
mov dword[esp+20], EWOULDBLOCK
mov dword[esp+32], -1
ret
 
.loop:
cmp [eax + TCP_SOCKET.t_state], TCPS_CLOSED
je .fail
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
je .established
ja .fail
 
call SOCKET_block
jmp .loop
 
.fail:
mov eax, [eax + SOCKET.errorcode]
mov [esp+20], eax
mov dword[esp+32], -1
ret
 
.established:
mov dword [esp+32], 0
ret
 
 
align 4
.ip:
pusha
619,16 → 671,16
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp [eax + SOCKET.Domain], AF_INET4
jne s_error
jne .notsupp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jne s_error
jne .invalid
 
cmp [eax + TCP_SOCKET.LocalPort], 0
je s_error
je .already
 
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
651,10 → 703,24
pop eax
 
mov dword [esp+32], 0
ret
 
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
.already:
mov dword[esp+20], EALREADY
mov dword[esp+32], -1
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_accept
671,16 → 737,16
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
test [eax + SOCKET.options], SO_ACCEPTCON
jz s_error
jz .invalid
 
cmp [eax + SOCKET.Domain], AF_INET4
jne s_error
jne .notsupp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jne s_error
jne .invalid
 
.loop:
get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .block
688,14 → 754,15
; Ok, we got a socket ptr
mov eax, [esi]
 
; Convert it to a socket number
call SOCKET_ptr_to_num
jz .invalid ; FIXME ?
 
; Change thread ID to that of the current thread
mov ebx, [TASK_BASE]
mov ebx, [ebx + TASKDATA.pid]
mov [eax + SOCKET.TID], ebx
 
; Convert it to a socket number
call SOCKET_ptr_to_num
jz s_error
; and return it to caller
mov [esp+32], eax
ret
702,11 → 769,26
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz s_error
jnz .wouldblock
 
call SOCKET_block
jmp .loop
 
.wouldblock:
mov dword[esp+20], EWOULDBLOCK
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
;-----------------------------------------------------------------
;
; SOCKET_close
721,11 → 803,10
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_close: socknum=%u\n", ecx
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
mov dword [esp+32], 0 ; The socket exists, so we will succeed in closing it.
 
.socket:
or [eax + SOCKET.options], SO_NONBLOCK ; Mark the socket as non blocking, we dont want it to block any longer!
 
test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state?
749,10 → 830,17
 
call TCP_usrclosed
call TCP_output ;;;; Fixme: is this nescessary??
call SOCKET_free
 
ret
 
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_receive
770,29 → 858,52
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
.loop:
push edi
call [eax + SOCKET.rcv_proc]
pop edi
 
cmp ebx, EWOULDBLOCK
jne .return
 
test edi, MSG_DONTWAIT
jnz .return_err
 
; test [eax + SOCKET.options], SO_NONBLOCK
; jnz .return_err
 
call SOCKET_block
jmp .loop
 
 
.invalid:
push EINVAL
pop ebx
.return_err:
mov eax, -1
.return:
mov [esp+20], ebx
mov [esp+32], eax
ret
 
 
 
 
 
align 4
SOCKET_receive_dgram:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n"
 
mov ebx, esi
mov edi, edx ; addr to buffer
mov ebx, esi ; bufferlength
 
.loop:
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .block ; destroys esi and ecx
 
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .wouldblock ; sets esi only on success.
mov ecx, [esi + socket_queue_entry.data_size]
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: %u bytes data\n", ecx
 
cmp ecx, ebx
cmp ecx, ebx ; If data segment does not fit in applications buffer, abort
ja .too_small
 
push ecx
800,7 → 911,8
mov esi, [esi + socket_queue_entry.data_ptr]
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi
 
; copy the data
; copy the data from kernel buffer to application buffer
mov edi, edx ; bufferaddr
shr ecx, 1
jnc .nb
movsb
814,24 → 926,22
rep movsd
.nd:
 
call kernel_free ; remove the packet
pop eax
 
call kernel_free ; free kernel buffer
pop eax ; return number of bytes copied to application
xor ebx, ebx
ret
 
.too_small:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Buffer too small\n"
.fail:
mov eax, -1
push EMSGSIZE
pop ebx
ret
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz .fail
.wouldblock:
push EWOULDBLOCK
pop ebx
ret
 
call SOCKET_block
jmp .loop
 
 
align 4
850,56 → 960,42
 
mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream
 
; ... continue to SOCKET_receive_stream
 
align 4
SOCKET_receive_stream:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: STREAM\n"
 
mov ebx, edi
cmp [eax + STREAM_SOCKET.rcv + RING_BUFFER.size], 0
je .wouldblock
 
test edi, MSG_PEEK
jnz .peek
 
mov ecx, esi
mov edi, edx
xor edx, edx
 
test ebx, MSG_DONTWAIT
jnz .dontwait
.loop:
cmp [eax + STREAM_SOCKET.rcv + RING_BUFFER.size], 0
je .block
.dontwait:
test ebx, MSG_PEEK
jnz .peek
 
add eax, STREAM_SOCKET.rcv
call SOCKET_ring_read
call SOCKET_ring_free
call SOCKET_ring_read ; copy data from kernel buffer to application buffer
call SOCKET_ring_free ; free read memory
 
mov eax, ecx ; return number of bytes copied
xor ebx, ebx ; errorcode = 0 (no error)
ret
 
.wouldblock:
push EWOULDBLOCK
pop ebx
ret
 
.peek:
mov eax, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size]
xor ebx, ebx
ret
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz .return0
 
call SOCKET_block
jmp .loop
 
.return0:
test [eax + SOCKET.options], SS_CANTRCVMORE
jz .ok
 
xor eax, eax
dec eax
ret
 
.ok:
xor eax, eax
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_send
918,7 → 1014,7
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
mov ecx, esi
mov esi, edx
925,7 → 1021,12
 
jmp [eax + SOCKET.snd_proc]
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
 
align 4
SOCKET_send_udp:
 
934,10 → 1035,15
mov [esp+32], ecx
call UDP_output
cmp eax, -1
je s_error
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+20], EMSGSIZE ; FIXME: UDP_output should return error codes!
ret
 
 
align 4
SOCKET_send_tcp:
 
949,8 → 1055,12
pop eax
 
mov [esp+32], ecx
 
call TCP_output
mov [eax + SOCKET.errorcode], 0
push eax
call TCP_output ; FIXME: this doesnt look pretty, does it?
pop eax
mov eax, [eax + SOCKET.errorcode]
mov [esp+20], eax
ret
 
 
960,12 → 1070,17
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: IPv4\n"
 
mov [esp+32], ecx
call IPv4_output_raw
call IPv4_output_raw ; FIXME: IPv4_output_raw should return error codes!
cmp eax, -1
je s_error
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+20], EMSGSIZE
ret
 
 
align 4
SOCKET_send_icmp:
 
972,12 → 1087,17
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: ICMP\n"
 
mov [esp+32], ecx
call ICMP_output_raw
call ICMP_output_raw ; FIXME: errorcodes
cmp eax, -1
je s_error
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+20], EMSGSIZE
ret
 
 
align 4
SOCKET_send_pppoe:
 
986,13 → 1106,18
mov [esp+32], ecx
mov ebx, [eax + SOCKET.device]
 
call PPPoE_discovery_output
call PPPoE_discovery_output ; FIXME: errorcodes
cmp eax, -1
je s_error
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+20], EMSGSIZE
ret
 
 
 
align 4
SOCKET_send_local:
 
1016,7 → 1141,7
; get the other side's socket and check if it still exists
mov eax, [eax + SOCKET.device]
call SOCKET_check
jz s_error
jz .invalid
 
; allright, shove in the data!
push eax
1032,7 → 1157,12
 
ret
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_get_options
1053,14 → 1183,14
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_get_opt\n"
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp dword [edx], IP_PROTO_TCP
jne s_error
jne .invalid
cmp dword [edx+4], -2
je @f
cmp dword [edx+4], -3
jne s_error
jne .invalid
@@:
; mov eax, [edx+12]
; test eax, eax
1085,8 → 1215,13
mov dword [esp+32], 0
ret
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
ret
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_set_options
1103,19 → 1238,19
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt\n"
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp dword [edx], SOL_SOCKET
jne s_error
jne .invalid
 
cmp dword [edx+4], SO_BINDTODEVICE
je .bind
 
cmp dword [edx+4], SO_BLOCK
je .block
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
ret
 
jmp s_error
 
.bind:
cmp dword [edx+8], 0
je .unbind
1122,11 → 1257,11
 
movzx edx, byte [edx + 9]
cmp edx, NET_DEVICES_MAX
ja s_error
ja .invalid
 
mov edx, [NET_DRV_LIST + 4*edx]
test edx, edx
jz s_error
jz .already
mov [eax + SOCKET.device], edx
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx
1140,23 → 1275,14
mov dword [esp+32], 0 ; success!
ret
 
.block:
cmp dword [edx+8], 0
je .unblock
 
and [eax + SOCKET.options], not SO_NONBLOCK
 
mov dword [esp+32], 0 ; success!
.already:
mov dword[esp+20], EALREADY
mov dword[esp+32], -1
ret
 
.unblock:
or [eax + SOCKET.options], SO_NONBLOCK
 
mov dword [esp+32], 0 ; success!
ret
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_pair
1174,7 → 1300,7
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n"
 
call SOCKET_alloc
jz s_error
jz .nomem1
mov [esp+32], edi ; application's eax
 
mov [eax + SOCKET.Domain], AF_LOCAL
1186,8 → 1312,8
mov ebx, eax
 
call SOCKET_alloc
jz .error
mov [esp+24], edi ; application's ebx
jz .nomem2
mov [esp+20], edi ; application's ebx
 
mov [eax + SOCKET.Domain], AF_LOCAL
mov [eax + SOCKET.Type], SOCK_STREAM
1209,10 → 1335,13
 
ret
 
.error:
.nomem2:
mov eax, ebx
call SOCKET_free
jmp s_error
.nomem1:
mov dword[esp+32], -1
mov dword[esp+28], ENOMEM
ret
 
 
 
1238,7 → 1367,7
jz .returnall
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
mov esi, eax
mov ecx, SOCKETBUFFSIZE/4
1259,8 → 1388,12
.done:
xor eax, eax
stosd
mov dword[esp+32], eax
ret
 
mov dword [esp+32], 0
.invalid:
mov dword[esp+32], -1
mov dword[esp+28], EINVAL
ret
 
 
1342,6 → 1475,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_port: "
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov ecx, [eax + SOCKET.Protocol]
mov edx, [eax + IP_SOCKET.LocalIP]
mov esi, net_sockets
1360,10 → 1498,20
cmp [esi + UDP_SOCKET.LocalPort], bx
jne .next_socket
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x already in use\n", bx ; FIXME: find a way to print big endian values with debugf
ret
 
.port_ok:
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x is free\n", bx ; FIXME: find a way to print big endian values with debugf
mov [eax + UDP_SOCKET.LocalPort], bx
or bx, bx ; clear the zero-flag
1659,7 → 1807,7
; Suspends the thread attached to a socket
;
; IN: eax = socket ptr
; OUT: /
; OUT: eax = unchanged
;
;-----------------------------------------------------------------
align 4
1668,6 → 1816,7
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
 
pushf
push eax
cli
 
; Set the 'socket is blocked' flag
1685,6 → 1834,7
pop edx
 
call change_task
pop eax
popf
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n"
1699,7 → 1849,7
; notify's the owner of a socket that something happened
;
; IN: eax = socket ptr
; OUT: /
; OUT: eax = unchanged
;
;-----------------------------------------------------------------
align 4
1713,8 → 1863,8
test [eax + SOCKET.state], SS_BLOCKED
jnz .unblock
 
test [eax + SOCKET.options], SO_NONBLOCK
jz .error
; test [eax + SOCKET.options], SO_NONBLOCK
; jz .error
 
push eax ecx esi
 
1811,9 → 1961,14
pop eax
 
; set send-and receive procedures to return -1
mov [eax + SOCKET.snd_proc], s_error
mov [eax + SOCKET.rcv_proc], s_error
mov [eax + SOCKET.snd_proc], .not_yet
mov [eax + SOCKET.rcv_proc], .not_yet
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
; find first free socket number and use it
mov edi, [last_socket_num]
.next_socket_number:
1872,12 → 2027,23
 
mov [net_sockets + SOCKET.NextPtr], eax
or eax, eax ; used to clear zero flag
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
.exit:
pop ebx
 
ret
 
.not_yet:
mov dword[esp+20], ENOTCONN
mov dword[esp+32], -1
ret
 
 
;----------------------------------------------------
;
; SOCKET_free
1893,6 → 2059,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: %x\n", eax
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
call SOCKET_check
jz .error
 
1915,6 → 2086,7
mov eax, ebx
.no_tcp:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: freeing socket %x\n", eax
push eax ; this will be passed to kernel_free
mov ebx, [eax + SOCKET.NextPtr]
mov eax, [eax + SOCKET.PrevPtr]
1937,6 → 2109,12
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: success!\n"
 
.error:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
ret
 
;------------------------------------
2005,6 → 2183,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_num_to_ptr: num=%u ", ecx
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov eax, net_sockets
 
.next_socket:
2016,11 → 2199,21
 
test eax, eax
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ptr=%x\n", eax
ret
 
.error:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_nuto_ptr: not found\n", eax
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: not found\n", eax
ret
 
 
2129,8 → 2322,16
align 4
SOCKET_process_end:
 
pushf
cli ; FIXME
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
push ebx
mov ebx, net_sockets
 
2148,14 → 2349,45
mov [ebx + SOCKET.PID], 0
mov eax, ebx
mov ebx, [ebx + SOCKET.NextPtr]
 
pusha
call SOCKET_close.socket
mov ecx, socket_mutex
call mutex_unlock
popa
 
pusha
cmp [eax + SOCKET.Domain], AF_INET4
jne .free
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jne .free
 
call TCP_close
jmp .closed
 
.free:
call SOCKET_free
 
.closed:
popa
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
jmp .next_socket_test
 
.done:
pop ebx
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
popf
 
ret
 
 
2196,8 → 2428,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connected: %x\n", eax
 
and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.options], SS_ISCONNECTED
and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.state], SS_ISCONNECTED
 
jmp SOCKET_notify
 
2218,8 → 2450,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnecting: %x\n", eax
 
and [eax + SOCKET.options], not (SS_ISCONNECTING)
or [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
and [eax + SOCKET.state], not (SS_ISCONNECTING)
or [eax + SOCKET.state], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
 
jmp SOCKET_notify
 
2239,8 → 2471,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnected: %x\n", eax
 
and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
or [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
je .tcp
2272,7 → 2504,7
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax
 
or [eax + SOCKET.options], SS_CANTRCVMORE
or [eax + SOCKET.state], SS_CANTRCVMORE
 
call SOCKET_notify
 
2294,9 → 2526,14
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_send_more: %x\n", eax
 
or [eax + SOCKET.options], SS_CANTSENDMORE
mov [eax + SOCKET.snd_proc], s_error
or [eax + SOCKET.state], SS_CANTSENDMORE
mov [eax + SOCKET.snd_proc], .notconn
 
call SOCKET_notify
 
ret
 
.notconn:
mov dword[esp+20], ENOTCONN
mov dword[esp+32], -1
ret
/kernel/branches/Kolibri-acpi/network/stack.inc
81,7 → 81,6
SO_USELOOPBACK = 1 shl 8
SO_BINDTODEVICE = 1 shl 9
 
SO_BLOCK = 1 shl 10 ; TO BE REMOVED
SO_NONBLOCK = 1 shl 31
 
; Socket flags for user calls
104,9 → 103,9
SS_RESTARTSYS = 0x0100 ; restart blocked system calls
SS_ISDISCONNECTED = 0x0800 ; socket disconnected from peer
 
SS_ASYNC = 0x0100 ; async i/o notify
SS_ISCONFIRMING = 0x0200 ; deciding to accept connection req
SS_MORETOCOME = 0x0400
SS_ASYNC = 0x1000 ; async i/o notify
SS_ISCONFIRMING = 0x2000 ; deciding to accept connection req
SS_MORETOCOME = 0x4000
 
SS_BLOCKED = 0x8000
 
115,7 → 114,15
MAX_backlog = 20 ; maximum backlog for stream sockets
 
; Error Codes
ENOBUFS = 55
ENOBUFS = 1
EOPNOTSUPP = 4
EWOULDBLOCK = 6
ENOTCONN = 9
EALREADY = 10
EINVAL = 11
EMSGSIZE = 12
ENOMEM = 18
EADDRINUSE = 20
ECONNREFUSED = 61
ECONNRESET = 52
ETIMEDOUT = 60
213,8 → 220,8
 
 
 
uglobal
align 4
uglobal
 
NET_RUNNING dd ?
NET_DRV_LIST rd NET_DEVICES_MAX
450,29 → 457,33
;-----------------------------------------------------------------
align 4
NET_ptr_to_num:
 
call NET_ptr_to_num4
ror edi, 2 ; If -1, stay -1
; valid device numbers have last two bits 0, so do just shr
 
ret
 
align 4
NET_ptr_to_num4: ; Todo, place number in device structure so we only need to verify?
 
push ecx
 
mov ecx, NET_DEVICES_MAX
mov edi, NET_DRV_LIST
 
.loop:
cmp ebx, [edi]
jz .found
je .found
add edi, 4
dec ecx
jnz .loop
 
; repnz scasd could work too if eax is used instead of ebx!
 
or edi, -1
 
pop ecx
ret
 
.found:
sub edi, NET_DRV_LIST
shr edi, 2
 
pop ecx
ret
 
/kernel/branches/Kolibri-acpi/network/tcp.inc
127,8 → 127,9
 
ends
 
uglobal
align 4
uglobal
 
TCP_segments_tx rd NET_DEVICES_MAX
TCP_segments_rx rd NET_DEVICES_MAX
TCP_segments_missed rd NET_DEVICES_MAX
136,7 → 137,7
; TCP_bytes_rx rq NET_DEVICES_MAX
; TCP_bytes_tx rq NET_DEVICES_MAX
TCP_sequence_num dd ?
TCP_queue rd TCP_QUEUE_SIZE*sizeof.TCP_queue_entry/4
TCP_queue rd (TCP_QUEUE_SIZE*sizeof.TCP_queue_entry + sizeof.queue)/4
TCP_input_event dd ?
endg
 
163,6 → 164,10
movi ebx, 1
mov ecx, TCP_process_input
call new_sys_threads
test eax, eax
jns @f
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP, error %d\n', eax
@@:
 
}
 
/kernel/branches/Kolibri-acpi/network/tcp_input.inc
50,6 → 50,9
 
add esp, sizeof.TCP_queue_entry
 
call NET_ptr_to_num4
inc [TCP_segments_rx + edi]
 
xor edx, edx
mov eax, [TCP_input_event]
mov ebx, [eax + EVENT.id]
62,7 → 65,8
popf
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
 
inc [TCP_segments_missed] ; FIXME: use correct interface
call NET_ptr_to_num4
inc [TCP_segments_missed + edi]
 
add esp, sizeof.TCP_queue_entry - 8
call kernel_free
146,6 → 150,11
; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0)
 
.findpcb:
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov ebx, net_sockets
mov si, [edx + TCP_header.DestinationPort]
 
152,7 → 161,7
.socket_loop:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .respond_seg_reset
jz .no_socket ;respond_seg_reset
 
cmp [ebx + SOCKET.Domain], AF_INET4
jne .socket_loop
176,13 → 185,13
test ax, ax
jnz .socket_loop
.found_socket: ; ebx now contains the socketpointer
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: socket ptr=%x state=%u flags=%x\n", ebx, [ebx + TCP_SOCKET.t_state], [edx + TCP_header.Flags]:2
 
;-------------
; update stats
 
inc [TCP_segments_rx] ; FIXME: correct interface?
 
;----------------------------
; Check if socket isnt closed
 
1161,10 → 1170,18
.ack_la:
jnc .ack_processed
 
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop ebx
 
push ebx
mov eax, ebx
call TCP_disconnect
jmp .drop
pop ebx
 
jmp .destroy_new_socket
 
.ack_tw:
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait
1223,7 → 1240,10
 
and [ebx + TCP_SOCKET.temp_bits], not TCP_BIT_DROPSOCKET
 
;;; call SOCKET_notify_owner
pusha
mov eax, ebx
call SOCKET_notify
popa
 
jmp .trim_then_step6
 
1298,7 → 1318,10
;;; TODO: update stats
 
; set socket state to connected
mov [ebx + SOCKET.state], SS_ISCONNECTED
push eax
mov eax, ebx
call SOCKET_is_connected
pop eax
mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
 
; Do window scaling on this connection ?
1620,6 → 1643,13
pop ebx
jmp .destroy_new_socket
 
.no_socket:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
.respond_seg_reset:
test [edx + TCP_header.Flags], TH_RST
jnz .drop_no_socket
/kernel/branches/Kolibri-acpi/network/tcp_output.inc
35,6 → 35,8
call mutex_lock
pop eax
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket locked\n"
 
; We'll detect the length of the data to be transmitted, and flags to be used
; If there is some data, or any critical controls to send (SYN / RST), then transmit
; Otherwise, investigate further
216,6 → 218,7
mov ebx, TCP_max_win
shl ebx, cl
pop ecx
 
cmp ebx, ecx
jb @f
mov ebx, ecx
549,7 → 552,8
pop ecx
pop eax
 
inc [TCP_segments_tx] ; FIXME: correct interface?
call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
 
; update advertised receive window
test ecx, ecx
570,6 → 574,8
;--------------
; unlock socket
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: unlocking socket 0x%x\n", eax
 
push eax
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
606,7 → 612,8
 
 
.send_error:
add esp, 8
add esp, 4
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
/kernel/branches/Kolibri-acpi/network/tcp_subr.inc
164,7 → 164,7
 
;;; TODO: check if error code is "Connection timed out' and handle accordingly
 
mov [eax + SOCKET.errorcode], ebx
; mov [eax + SOCKET.errorcode], ebx
 
 
 
302,6 → 302,11
; And send the segment
 
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
@@:
ret
 
.error:
378,6 → 383,11
; And send the segment
 
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
@@:
ret
 
.error:
/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc
97,6 → 97,9
 
call SOCKET_is_disconnecting
call TCP_usrclosed
 
push eax
call TCP_output
pop eax
 
ret
/kernel/branches/Kolibri-acpi/network/udp.inc
27,10 → 27,12
ends
 
 
uglobal
align 4
uglobal
 
UDP_PACKETS_TX rd NET_DEVICES_MAX
UDP_PACKETS_RX rd NET_DEVICES_MAX
 
endg
 
 
114,6 → 116,7
;
;-----------------------------------------------------------------
align 4
diff16 "UDP packetgfgfgfgfs", 0, $
UDP_input:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: size=%u\n", ecx
139,6 → 142,11
; IP Packet UDP Destination Port = local Port
; IP Packet SA = Remote IP
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov cx, [esi + UDP_header.SourcePort]
mov dx, [esi + UDP_header.DestinationPort]
mov edi, [edi + 4] ; ipv4 source address
147,7 → 155,7
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump
jz .dump_
 
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
160,6 → 168,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: socket=%x\n", eax
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
;;; TODO: when packet is processed, check more sockets!
 
; cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
182,7 → 195,8
popa
 
.updatesock:
inc [UDP_PACKETS_RX] ; Fixme: correct interface?
call NET_ptr_to_num4
inc [UDP_PACKETS_RX + edi]
 
movzx ecx, [esi + UDP_header.Length]
sub ecx, sizeof.UDP_header
202,7 → 216,17
 
jmp .updatesock
 
.dump_:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: no socket found\n"
 
jmp .dump
 
.checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
 
274,7 → 298,8
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
inc [UDP_PACKETS_TX] ; FIXME: correct device?
call NET_ptr_to_num4
inc [UDP_PACKETS_TX + edi]
@@:
 
ret