acpi: update

git-svn-id: svn://kolibrios.org@3725 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2013-06-28 08:02:49 +00:00
parent 658fbe4d63
commit 38f0b2a169
43 changed files with 1819 additions and 1038 deletions

View File

@ -349,10 +349,8 @@ disk_add:
inc eax inc eax
cmp byte [ebx+eax-1], 0 cmp byte [ebx+eax-1], 0
jnz @b jnz @b
; 2b. Call the heap manager. Note that it can change ebx. ; 2b. Call the heap manager.
push ebx
call malloc call malloc
pop ebx
; 2c. Check the result. If allocation failed, go to 7. ; 2c. Check the result. If allocation failed, go to 7.
pop esi ; restore allocated pointer to DISK pop esi ; restore allocated pointer to DISK
test eax, eax test eax, eax

File diff suppressed because it is too large Load Diff

View File

@ -136,14 +136,7 @@ found_slot_access_denied:
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
clear_hd_cache:
ret
;--------------------------------------------------------------------
align 4
calculate_cache: calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [hdpos], 1 cmp [hdpos], 1
@ -221,7 +214,6 @@ calculate_cache:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
calculate_cache_1: calculate_cache_1:
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [hdpos], 1 cmp [hdpos], 1
@ -290,7 +282,6 @@ calculate_cache_1:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
calculate_cache_2: calculate_cache_2:
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [hdpos], 1 cmp [hdpos], 1
@ -644,9 +635,6 @@ clear_CD_cache:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache: cd_calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [cdpos], 1 cmp [cdpos], 1
@ -697,7 +685,6 @@ cd_calculate_cache:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_1: cd_calculate_cache_1:
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [cdpos], 1 cmp [cdpos], 1
@ -740,7 +727,6 @@ cd_calculate_cache_1:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_2: cd_calculate_cache_2:
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [cdpos], 1 cmp [cdpos], 1

View File

@ -387,7 +387,12 @@ sayerr:
push 0 push 0
pop es 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} ; \begin{Mario79}
; find HDD IDE DMA PCI device ; find HDD IDE DMA PCI device
; check for PCI BIOS ; check for PCI BIOS
@ -400,31 +405,85 @@ sayerr:
; class 1 = mass storage ; class 1 = mass storage
; subclass 1 = IDE controller ; subclass 1 = IDE controller
; a) class 1, subclass 1, programming interface 0x80 ; a) class 1, subclass 1, programming interface 0x80
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103 mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x80 mov ecx, 1*10000h + 1*100h + 0x80
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0 xor si, si ; device index = 0
int 0x1A int 0x1A
jnc .found jnc .found_1 ; Parallel IDE Controller
; b) class 1, subclass 1, programming interface 0x8A ; b) class 1, subclass 1, programming interface 0x8f
mov ax, 0xB103 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 xor si, si ; device index = 0
int 0x1A int 0x1A
jnc .found jnc .found
; c) class 1, subclass 1, programming interface 0x85 ; c) class 1, subclass 1, programming interface 0x85
mov ax, 0xB103 mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x85 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 int 0x1A
jc .nopci jnc .found
.found: ; d) class 1, subclass 1, programming interface 0x8A
; get memory base ; 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 ax, 0xB10A
mov di, 0x20 ; memory base is config register at 0x20 mov di, 0x20 ; memory base is config register at 0x20
push cx
int 0x1A int 0x1A
jc .nopci jc .no_BAR4 ;.nopci
and cx, 0xFFF0 ; clear address decode type and cx, 0xFFF0 ; clear address decode type
mov [es:BOOT_IDE_BASE_ADDR], cx 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: .nopci:
; \end{Mario79} ; \end{Mario79}
@ -550,8 +609,8 @@ end if
; following 4 lines set variables to 1 if its current value is 0 ; following 4 lines set variables to 1 if its current value is 0
cmp byte [di+preboot_dma-preboot_device], 1 cmp byte [di+preboot_dma-preboot_device], 1
adc byte [di+preboot_dma-preboot_device], 0 adc byte [di+preboot_dma-preboot_device], 0
cmp byte [di+preboot_biosdisk-preboot_device], 1 ; cmp byte [di+preboot_biosdisk-preboot_device], 1
adc byte [di+preboot_biosdisk-preboot_device], 0 ; adc byte [di+preboot_biosdisk-preboot_device], 0
;; default value for VRR is OFF ;; default value for VRR is OFF
; cmp byte [di+preboot_vrrm-preboot_device], 0 ; cmp byte [di+preboot_vrrm-preboot_device], 0
; jnz @f ; jnz @f

View File

@ -81,27 +81,21 @@ ends
; * The hardware requires 32-bytes alignment of the hardware part, so ; * The hardware requires 32-bytes alignment of the hardware part, so
; the entire descriptor must be 32-bytes aligned. Since the allocator ; the entire descriptor must be 32-bytes aligned. Since the allocator
; (usb_allocate_common) allocates memory sequentially from page start ; (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 ; * The hardware also requires that the hardware part must not cross page
; boundary; the allocator satisfies this automatically. ; boundary; the allocator satisfies this automatically.
struct ehci_gtd ehci_hardware_td struct ehci_gtd ehci_hardware_td
Flags dd ? Flags dd ?
; Copy of flags from the call to usb_*_transfer_async. ; 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 ends
if sizeof.ehci_gtd mod 32
.err ehci_gtd must be 32-bytes aligned
end if
; EHCI-specific part of a pipe descriptor. ; EHCI-specific part of a pipe descriptor.
; * This structure corresponds to the Queue Head from the EHCI specification. ; * This structure corresponds to the Queue Head from the EHCI specification.
; * The hardware requires 32-bytes alignment of the hardware part. ; * The hardware requires 32-bytes alignment of the hardware part.
; Since the allocator (usb_allocate_common) allocates memory sequentially ; Since the allocator (usb_allocate_common) allocates memory sequentially
; from page start (aligned on 0x1000 bytes), size of the structure must be ; from page start (aligned on 0x1000 bytes), block size for the allocator
; divisible by 32. ; must be divisible by 32; ehci_alloc_pipe ensures this.
; * The hardware requires also that the hardware part must not cross page ; * The hardware requires also that the hardware part must not cross page
; boundary; the allocator satisfies this automatically. ; boundary; the allocator satisfies this automatically.
struct ehci_pipe struct ehci_pipe
@ -154,15 +148,8 @@ Overlay ehci_hardware_td ?
; from the new TD, if any. ; from the new TD, if any.
BaseList dd ? BaseList dd ?
; Pointer to head of the corresponding pipe list. ; Pointer to head of the corresponding pipe list.
SoftwarePart rd sizeof.usb_pipe/4
; Software part, common for all controllers.
rd 2 ; padding
ends 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. ; This structure describes the static head of every list of pipes.
; The hardware requires 32-bytes alignment of this structure. ; The hardware requires 32-bytes alignment of this structure.
; All instances of this structure are located sequentially in ehci_controller, ; All instances of this structure are located sequentially in ehci_controller,
@ -764,7 +751,7 @@ endp
; and stores USB device address in the ehci_pipe structure. ; and stores USB device address in the ehci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address ; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
proc ehci_set_device_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 call usb_subscribe_control
ret ret
endp endp
@ -773,7 +760,7 @@ endp
; in: esi -> usb_controller, ebx -> usb_pipe ; in: esi -> usb_controller, ebx -> usb_pipe
; out: eax = endpoint address ; out: eax = endpoint address
proc ehci_get_device_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 and eax, 7Fh
ret ret
endp endp
@ -793,11 +780,11 @@ endp
; stores the packet size in ehci_pipe structure. ; stores the packet size in ehci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size ; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
proc ehci_set_endpoint_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) and eax, not (0x7FF shl 16)
shl ecx, 16 shl ecx, 16
or eax, ecx 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. ; Wait until hardware cache is evicted.
call usb_subscribe_control call usb_subscribe_control
ret ret
@ -818,10 +805,10 @@ endg
proc ehci_alloc_pipe proc ehci_alloc_pipe
push ebx push ebx
mov ebx, ehci_ep_mutex 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 test eax, eax
jz @f jz @f
add eax, ehci_pipe.SoftwarePart add eax, sizeof.ehci_pipe
@@: @@:
pop ebx pop ebx
ret ret
@ -834,7 +821,7 @@ virtual at esp
dd ? ; return address dd ? ; return address
.ptr dd ? .ptr dd ?
end virtual end virtual
sub [.ptr], ehci_pipe.SoftwarePart sub [.ptr], sizeof.ehci_pipe
jmp usb_free_common jmp usb_free_common
endp endp
@ -853,25 +840,25 @@ virtual at ebp+8
end virtual end virtual
; 1. Zero all fields in the hardware part. ; 1. Zero all fields in the hardware part.
push eax ecx push eax ecx
sub edi, ehci_pipe.SoftwarePart sub edi, sizeof.ehci_pipe
xor eax, eax xor eax, eax
movi ecx, ehci_pipe.SoftwarePart/4 movi ecx, sizeof.ehci_pipe/4
rep stosd rep stosd
pop ecx eax pop ecx eax
; 2. Setup PID in the first TD and make sure that the it is not active. ; 2. Setup PID in the first TD and make sure that the it is not active.
xor edx, edx xor edx, edx
test byte [.endpoint], 80h test byte [.endpoint], 80h
setnz dh setnz dh
mov [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], edx mov [eax+ehci_gtd.Token-sizeof.ehci_gtd], edx
mov [eax+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], 1 mov [eax+ehci_gtd.NextTD-sizeof.ehci_gtd], 1
mov [eax+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], 1 mov [eax+ehci_gtd.AlternateNextTD-sizeof.ehci_gtd], 1
; 3. Store physical address of the first TD. ; 3. Store physical address of the first TD.
sub eax, ehci_gtd.SoftwarePart sub eax, sizeof.ehci_gtd
call get_phys_addr 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. ; 4. Fill ehci_pipe.Flags except for S- and C-masks.
; Copy location from the config pipe. ; 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 and eax, 3FFF0000h
; Use 1 requests per microframe for control/bulk endpoints, ; Use 1 requests per microframe for control/bulk endpoints,
; use value from the endpoint descriptor for periodic endpoints ; use value from the endpoint descriptor for periodic endpoints
@ -884,9 +871,9 @@ end virtual
@@: @@:
shl edx, 30 shl edx, 30
or eax, edx 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. ; 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: ; copy following fields from the config pipe:
; DeviceAddress, EndpointSpeed, ControlEndpoint if new type is control ; DeviceAddress, EndpointSpeed, ControlEndpoint if new type is control
mov ecx, eax mov ecx, eax
@ -915,7 +902,7 @@ end virtual
@@: @@:
or eax, 40000000h or eax, 40000000h
.nonak: .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. ; 5. Select the corresponding list and insert to the list.
; 5a. Use Control list for control pipes, Bulk list for bulk pipes. ; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
lea edx, [esi+ehci_controller.ControlED.SoftwarePart-sizeof.ehci_controller] lea edx, [esi+ehci_controller.ControlED.SoftwarePart-sizeof.ehci_controller]
@ -931,7 +918,7 @@ end virtual
; another for split transactions. ; another for split transactions.
; This could fail if the requested bandwidth is not available; ; This could fail if the requested bandwidth is not available;
; if so, return an error. ; 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 jnz .interrupt_fs
call ehci_select_hs_interrupt_list call ehci_select_hs_interrupt_list
jmp .interrupt_common jmp .interrupt_common
@ -940,9 +927,9 @@ end virtual
.interrupt_common: .interrupt_common:
test edx, edx test edx, edx
jz .return0 jz .return0
mov word [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart], ax mov word [edi+ehci_pipe.Flags-sizeof.ehci_pipe], ax
.insert: .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. ; Insert to the head of the corresponding list.
; Note: inserting to the head guarantees that the list traverse in ; Note: inserting to the head guarantees that the list traverse in
; ehci_process_updated_schedule, once started, will not interact with new pipes. ; ehci_process_updated_schedule, once started, will not interact with new pipes.
@ -957,8 +944,8 @@ end virtual
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe, ; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
; store the physical address of the new pipe to previous NextQH. ; store the physical address of the new pipe to previous NextQH.
mov ecx, [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart] mov ecx, [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart]
mov [edi+ehci_pipe.NextQH-ehci_pipe.SoftwarePart], ecx mov [edi+ehci_pipe.NextQH-sizeof.ehci_pipe], ecx
lea eax, [edi-ehci_pipe.SoftwarePart] lea eax, [edi-sizeof.ehci_pipe]
call get_phys_addr call get_phys_addr
inc eax inc eax
inc eax inc eax
@ -1058,22 +1045,29 @@ endl
; this corresponds to 4001h bytes. If the requested size is ; this corresponds to 4001h bytes. If the requested size is
; greater, we should split the transfer into several descriptors. ; greater, we should split the transfer into several descriptors.
; Boundaries to split must be multiples of endpoint transfer size ; Boundaries to split must be multiples of endpoint transfer size
; to avoid short packets except in the end of the transfer, ; to avoid short packets except in the end of the transfer.
; 4000h is always a good value. cmp [size], 4001h
jbe .lastpacket
; 2. While the remaining data cannot fit in one descriptor, ; 2. While the remaining data cannot fit in one descriptor,
; allocate full descriptors (of maximal possible size). ; 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 mov [packetSize], edi
.fullpackets: .fullpackets:
cmp [size], edi
jbe .lastpacket
call ehci_alloc_packet call ehci_alloc_packet
test eax, eax test eax, eax
jz .fail jz .fail
mov [td], eax mov [td], eax
add [buffer], edi add [buffer], edi
sub [size], edi sub [size], edi
jmp .fullpackets cmp [size], 4001h
ja .fullpackets
; 3. The remaining data can fit in one packet; ; 3. The remaining data can fit in one packet;
; allocate the last descriptor with size = size of remaining data. ; allocate the last descriptor with size = size of remaining data.
.lastpacket: .lastpacket:
@ -1084,7 +1078,7 @@ endl
jz .fail jz .fail
; 9. Update flags in the last packet. ; 9. Update flags in the last packet.
mov edx, [flags] 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. ; 10. Fill AlternateNextTD field in all allocated TDs.
; If the caller says that short transfer is ok, the queue must advance to ; If the caller says that short transfer is ok, the queue must advance to
; the next descriptor, which is in eax. ; the next descriptor, which is in eax.
@ -1093,7 +1087,7 @@ endl
push eax push eax
test dl, 1 test dl, 1
jz .disable_short jz .disable_short
sub eax, ehci_gtd.SoftwarePart sub eax, sizeof.ehci_gtd
jmp @f jmp @f
.disable_short: .disable_short:
mov eax, [ebx+usb_pipe.Controller] mov eax, [ebx+usb_pipe.Controller]
@ -1104,7 +1098,7 @@ endl
@@: @@:
cmp edx, [esp] cmp edx, [esp]
jz @f 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] mov edx, [edx+usb_gtd.NextVirt]
jmp @b jmp @b
@@: @@:
@ -1144,28 +1138,28 @@ end virtual
call usb_init_transfer call usb_init_transfer
pop eax pop eax
; 3. Copy PID to the new descriptor. ; 3. Copy PID to the new descriptor.
mov edx, [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart] mov edx, [ecx+ehci_gtd.Token-sizeof.ehci_gtd]
mov [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], edx mov [eax+ehci_gtd.Token-sizeof.ehci_gtd], edx
mov [eax+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], 1 mov [eax+ehci_gtd.NextTD-sizeof.ehci_gtd], 1
mov [eax+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], 1 mov [eax+ehci_gtd.AlternateNextTD-sizeof.ehci_gtd], 1
; 4. Save the returned value (next descriptor). ; 4. Save the returned value (next descriptor).
push eax push eax
; 5. Store the physical address of the next descriptor. ; 5. Store the physical address of the next descriptor.
sub eax, ehci_gtd.SoftwarePart sub eax, sizeof.ehci_gtd
call get_phys_addr 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. ; 6. For zero-length transfers, store zero in all fields for buffer addresses.
; Otherwise, fill them with real values. ; Otherwise, fill them with real values.
xor eax, eax xor eax, eax
mov [ecx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], eax mov [ecx+ehci_gtd.Flags-sizeof.ehci_gtd], eax
repeat 10 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 end repeat
cmp [.packetSize], eax cmp [.packetSize], eax
jz @f jz @f
mov eax, [.buffer] mov eax, [.buffer]
call get_phys_addr 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 and eax, 0xFFF
mov edx, [.packetSize] mov edx, [.packetSize]
add edx, eax add edx, eax
@ -1174,25 +1168,25 @@ end repeat
mov eax, [.buffer] mov eax, [.buffer]
add eax, 0x1000 add eax, 0x1000
call get_pg_addr 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 sub edx, 0x1000
jbe @f jbe @f
mov eax, [.buffer] mov eax, [.buffer]
add eax, 0x2000 add eax, 0x2000
call get_pg_addr 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 sub edx, 0x1000
jbe @f jbe @f
mov eax, [.buffer] mov eax, [.buffer]
add eax, 0x3000 add eax, 0x3000
call get_pg_addr 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 sub edx, 0x1000
jbe @f jbe @f
mov eax, [.buffer] mov eax, [.buffer]
add eax, 0x4000 add eax, 0x4000
call get_pg_addr 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: ; 7. Fill Token field:
; set Status = 0 (inactive, ehci_insert_transfer would mark everything active); ; set Status = 0 (inactive, ehci_insert_transfer would mark everything active);
@ -1202,7 +1196,7 @@ end repeat
; set current page to 0; ; set current page to 0;
; do not interrupt on complete (ehci_insert_transfer sets this bit where needed); ; do not interrupt on complete (ehci_insert_transfer sets this bit where needed);
; set DataToggle to bit 2 of [.direction]. ; 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 and eax, 300h ; keep PID code
mov edx, [.direction] mov edx, [.direction]
test edx, edx test edx, edx
@ -1222,7 +1216,7 @@ end repeat
mov edx, [.packetSize] mov edx, [.packetSize]
shl edx, 16 shl edx, 16
or eax, edx 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. ; 4. Restore the returned value saved in step 2.
pop eax pop eax
.nothing: .nothing:
@ -1234,10 +1228,10 @@ endp
; ehci_alloc_transfer. ; ehci_alloc_transfer.
; ecx -> last descriptor for the transfer, ebx -> usb_pipe ; ecx -> last descriptor for the transfer, ebx -> usb_pipe
proc ehci_insert_transfer 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] mov eax, [esp+4]
.activate: .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 cmp eax, ecx
mov eax, [eax+usb_gtd.NextVirt] mov eax, [eax+usb_gtd.NextVirt]
jnz .activate jnz .activate
@ -1328,7 +1322,7 @@ proc ehci_new_device
.found_hs_hub: .found_hs_hub:
mov edx, [edx+usb_hub.ConfigPipe] mov edx, [edx+usb_hub.ConfigPipe]
inc ecx inc ecx
mov edx, [edx+ehci_pipe.Token-ehci_pipe.SoftwarePart] mov edx, [edx+ehci_pipe.Token-sizeof.ehci_pipe]
shl ecx, 23 shl ecx, 23
and edx, 7Fh and edx, 7Fh
shl edx, 16 shl edx, 16
@ -1338,15 +1332,15 @@ proc ehci_new_device
.common: .common:
; 5. Create pseudo-pipe in the stack. ; 5. Create pseudo-pipe in the stack.
; See ehci_init_pipe: only .Controller, .Token, .Flags fields are used. ; 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 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 edx ; ehci_pipe.Flags
push eax ; ehci_pipe.Token push eax ; ehci_pipe.Token
; 6. Notify the protocol layer. ; 6. Notify the protocol layer.
call usb_new_device call usb_new_device
; 7. Cleanup the stack after step 5 and return. ; 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 pop ecx ebx ; restore used registers
ret ret
endp endp
@ -1658,7 +1652,7 @@ proc ehci_process_updated_list
; if either of conditions holds, exit from the internal loop. ; if either of conditions holds, exit from the internal loop.
cmp ebx, [esp] cmp ebx, [esp]
jz .tddone jz .tddone
cmp byte [ebx+ehci_gtd.Token-ehci_gtd.SoftwarePart], 0 cmp byte [ebx+ehci_gtd.Token-sizeof.ehci_gtd], 0
js .tddone js .tddone
; Release the queue lock while processing one descriptor: ; Release the queue lock while processing one descriptor:
; callback function could (and often would) schedule another transfer. ; callback function could (and often would) schedule another transfer.
@ -1690,14 +1684,14 @@ proc ehci_process_updated_td
; cmp [eax+usb_pipe.Type], INTERRUPT_PIPE ; cmp [eax+usb_pipe.Type], INTERRUPT_PIPE
; jnz @f ; jnz @f
; DEBUGF 1,'K : finalized TD for pipe %x:\n',eax ; 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],[eax+4],[eax+8],[eax+12]
; DEBUGF 1,'K : %x %x %x %x\n',[eax+16],[eax+20],[eax+24],[eax+28] ; DEBUGF 1,'K : %x %x %x %x\n',[eax+16],[eax+20],[eax+24],[eax+28]
;@@: ;@@:
; 1. Remove this descriptor from the list of descriptors for this pipe. ; 1. Remove this descriptor from the list of descriptors for this pipe.
call usb_unlink_td call usb_unlink_td
; 2. Calculate actual number of bytes transferred. ; 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] lea edx, [eax+eax]
shr edx, 17 shr edx, 17
sub edx, [ebx+usb_gtd.Length] sub edx, [ebx+usb_gtd.Length]
@ -1715,7 +1709,7 @@ proc ehci_process_updated_td
xor ecx, ecx xor ecx, ecx
test al, 40h test al, 40h
jnz .error jnz .error
test byte [ebx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], 1 test byte [ebx+ehci_gtd.Flags-sizeof.ehci_gtd], 1
jnz .notify jnz .notify
cmp edx, [ebx+usb_gtd.Length] cmp edx, [ebx+usb_gtd.Length]
jnz .special jnz .special
@ -1745,14 +1739,14 @@ proc ehci_process_updated_td
ret ret
.error: .error:
push ebx push ebx
sub ebx, ehci_gtd.SoftwarePart sub ebx, sizeof.ehci_gtd
DEBUGF 1,'K : TD failed:\n' 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],[ebx+4],[ebx+8],[ebx+12]
DEBUGF 1,'K : %x %x %x %x\n',[ebx+16],[ebx+20],[ebx+24],[ebx+28] DEBUGF 1,'K : %x %x %x %x\n',[ebx+16],[ebx+20],[ebx+24],[ebx+28]
pop ebx pop ebx
DEBUGF 1,'K : pipe now:\n' DEBUGF 1,'K : pipe now:\n'
mov ecx, [ebx+usb_gtd.Pipe] 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],[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+16],[ecx+20],[ecx+24],[ecx+28]
DEBUGF 1,'K : %x %x %x %x\n',[ecx+32],[ecx+36],[ecx+40],[ecx+44] DEBUGF 1,'K : %x %x %x %x\n',[ecx+32],[ecx+36],[ecx+40],[ecx+44]
@ -1802,7 +1796,7 @@ proc ehci_process_updated_td
; it is not an error; in this case, go to 4 with ecx = 0. ; it is not an error; in this case, go to 4 with ecx = 0.
cmp ecx, USB_STATUS_UNDERRUN cmp ecx, USB_STATUS_UNDERRUN
jnz @f jnz @f
test byte [ebx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], 1 test byte [ebx+ehci_gtd.Flags-sizeof.ehci_gtd], 1
jz @f jz @f
xor ecx, ecx xor ecx, ecx
pop edx ; length pop edx ; length
@ -1832,20 +1826,20 @@ proc ehci_process_updated_td
; to the next transfer. (According to the standard, "A control pipe may also ; to the next transfer. (According to the standard, "A control pipe may also
; support functional stall as well, but this is not recommended."). ; support functional stall as well, but this is not recommended.").
mov edx, [ebx+usb_gtd.Pipe] 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 or al, 1
mov [edx+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart], eax mov [edx+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe], eax
mov [edx+ehci_pipe.Overlay.AlternateNextTD-ehci_pipe.SoftwarePart], eax mov [edx+ehci_pipe.Overlay.AlternateNextTD-sizeof.ehci_pipe], eax
cmp [edx+usb_pipe.Type], CONTROL_PIPE cmp [edx+usb_pipe.Type], CONTROL_PIPE
jz .control jz .control
; Bulk/interrupt transfer; halt the queue. ; 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 pop edx
jmp .notify jmp .notify
; Control transfer. ; Control transfer.
.control: .control:
and [edx+ehci_pipe.Overlay.Token-ehci_pipe.SoftwarePart], 0 and [edx+ehci_pipe.Overlay.Token-sizeof.ehci_pipe], 0
dec [edx+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart] dec [edx+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe]
pop edx pop edx
jmp .notify jmp .notify
endp endp
@ -1855,7 +1849,7 @@ endp
proc ehci_unlink_pipe proc ehci_unlink_pipe
cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE
jnz @f 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 jnz .interrupt_fs
call ehci_hs_interrupt_list_unlink call ehci_hs_interrupt_list_unlink
jmp .interrupt_common jmp .interrupt_common
@ -1870,9 +1864,9 @@ proc ehci_unlink_pipe
mov edx, esi mov edx, esi
sub edx, eax sub edx, eax
cmp edx, sizeof.ehci_controller 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 jb .prev_is_static
mov [eax+ehci_pipe.NextQH-ehci_pipe.SoftwarePart], edx mov [eax+ehci_pipe.NextQH-sizeof.ehci_pipe], edx
ret ret
.prev_is_static: .prev_is_static:
mov [eax+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], edx mov [eax+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], edx
@ -1882,10 +1876,10 @@ endp
proc ehci_alloc_td proc ehci_alloc_td
push ebx push ebx
mov ebx, ehci_gtd_mutex 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 test eax, eax
jz @f jz @f
add eax, ehci_gtd.SoftwarePart add eax, sizeof.ehci_gtd
@@: @@:
pop ebx pop ebx
ret ret
@ -1895,6 +1889,6 @@ endp
; frees all additional data associated with the transfer descriptor. ; frees all additional data associated with the transfer descriptor.
; EHCI has no additional data, so just free ehci_gtd structure. ; EHCI has no additional data, so just free ehci_gtd structure.
proc ehci_free_td proc ehci_free_td
sub dword [esp+4], ehci_gtd.SoftwarePart sub dword [esp+4], sizeof.ehci_gtd
jmp usb_free_common jmp usb_free_common
endp endp

View File

@ -26,17 +26,17 @@ usb_gtd_mutex MUTEX
endg endg
; sanity check: structures in UHCI and OHCI should be the same for allocation ; 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. ; Allocates one endpoint structure for UHCI/OHCI.
; Returns pointer to software part (usb_pipe) in eax. ; Returns pointer to software part (usb_pipe) in eax.
proc usb1_allocate_endpoint proc usb1_allocate_endpoint
push ebx push ebx
mov ebx, usb1_ep_mutex 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 test eax, eax
jz @f jz @f
add eax, ohci_pipe.SoftwarePart add eax, sizeof.ohci_pipe
@@: @@:
pop ebx pop ebx
ret ret
@ -45,7 +45,7 @@ endp
; Free one endpoint structure for UHCI/OHCI. ; Free one endpoint structure for UHCI/OHCI.
; Stdcall with one argument, pointer to software part (usb_pipe). ; Stdcall with one argument, pointer to software part (usb_pipe).
proc usb1_free_endpoint proc usb1_free_endpoint
sub dword [esp+4], ohci_pipe.SoftwarePart sub dword [esp+4], sizeof.ohci_pipe
jmp usb_free_common jmp usb_free_common
endp endp
@ -55,17 +55,17 @@ else
end if end if
; sanity check: structures in UHCI and OHCI should be the same for allocation ; 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. ; Allocates one general transfer descriptor structure for UHCI/OHCI.
; Returns pointer to software part (usb_gtd) in eax. ; Returns pointer to software part (usb_gtd) in eax.
proc usb1_allocate_general_td proc usb1_allocate_general_td
push ebx push ebx
mov ebx, usb_gtd_mutex 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 test eax, eax
jz @f jz @f
add eax, ohci_gtd.SoftwarePart add eax, sizeof.ohci_gtd
@@: @@:
pop ebx pop ebx
ret ret
@ -74,7 +74,7 @@ endp
; Free one general transfer descriptor structure for UHCI/OHCI. ; Free one general transfer descriptor structure for UHCI/OHCI.
; Stdcall with one argument, pointer to software part (usb_gtd). ; Stdcall with one argument, pointer to software part (usb_gtd).
proc usb1_free_general_td proc usb1_free_general_td
sub dword [esp+4], ohci_gtd.SoftwarePart sub dword [esp+4], sizeof.ohci_gtd
jmp usb_free_common jmp usb_free_common
endp endp

View File

@ -44,8 +44,8 @@ OhciRhPortStatusReg = 54h
; specification. ; specification.
; * The hardware requires 16-bytes alignment of the hardware part. ; * The hardware requires 16-bytes alignment of the hardware part.
; Since the allocator (usb_allocate_common) allocates memory sequentially ; Since the allocator (usb_allocate_common) allocates memory sequentially
; from page start (aligned on 0x1000 bytes), size of the structure must be ; from page start (aligned on 0x1000 bytes), block size for the allocator
; divisible by 16. ; must be divisible by 16; usb1_allocate_endpoint ensures this.
struct ohci_pipe struct ohci_pipe
; All addresses are physical. ; All addresses are physical.
Flags dd ? Flags dd ?
@ -95,14 +95,8 @@ NextED dd ?
; * There is no "next" list for Bulk and Control lists, they are processed ; * There is no "next" list for Bulk and Control lists, they are processed
; separately from others. ; separately from others.
; * There is no "next" list for Periodic list for 1ms interval. ; * There is no "next" list for Periodic list for 1ms interval.
SoftwarePart rd sizeof.usb_pipe/4
; Software part, common for all controllers.
ends 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. ; This structure describes the static head of every list of pipes.
; The hardware requires 16-bytes alignment of this structure. ; The hardware requires 16-bytes alignment of this structure.
; All instances of this structure are located sequentially in uhci_controller, ; All instances of this structure are located sequentially in uhci_controller,
@ -204,7 +198,8 @@ end if
; * The hardware requires 16-bytes alignment of the hardware part, so ; * The hardware requires 16-bytes alignment of the hardware part, so
; the entire descriptor must be 16-bytes aligned. Since the allocator ; the entire descriptor must be 16-bytes aligned. Since the allocator
; (usb_allocate_common) allocates memory sequentially from page start ; (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 struct ohci_gtd
; ------------------------------ hardware fields ------------------------------ ; ------------------------------ hardware fields ------------------------------
; All addresses in this part are physical. ; All addresses in this part are physical.
@ -248,15 +243,9 @@ NextTD dd ?
; Virtual pointer to the next processed TD. ; Virtual pointer to the next processed TD.
BufEnd dd ? BufEnd dd ?
; Physical address of the last byte in the buffer for this TD. ; Physical address of the last byte in the buffer for this TD.
dd ? ; padding for 16-bytes alignment dd ? ; padding to align with uhci_gtd
SoftwarePart rd sizeof.usb_gtd/4
; Common part for all controllers.
ends ends
if sizeof.ohci_gtd mod 16
.err ohci_gtd must be 16-bytes aligned
end if
; OHCI isochronous transfer descriptor. ; OHCI isochronous transfer descriptor.
; * The structure describes transfers to be performed on Isochronous endpoints. ; * The structure describes transfers to be performed on Isochronous endpoints.
; * The structure includes two parts, the hardware part and the software part. ; * The structure includes two parts, the hardware part and the software part.
@ -726,7 +715,7 @@ end virtual
.tdloop: .tdloop:
mov ecx, [eax+ohci_gtd.NextTD] mov ecx, [eax+ohci_gtd.NextTD]
mov [eax+ohci_gtd.NextTD], ebx mov [eax+ohci_gtd.NextTD], ebx
lea ebx, [eax+ohci_gtd.SoftwarePart] lea ebx, [eax+sizeof.ohci_gtd]
test ecx, ecx test ecx, ecx
jz .tddone jz .tddone
call usb_td_to_virt call usb_td_to_virt
@ -893,7 +882,7 @@ endp
; and stores USB device address in the ohci_pipe structure. ; and stores USB device address in the ohci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address ; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
proc ohci_set_device_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. ; Wait until the hardware will forget the old value.
call usb_subscribe_control call usb_subscribe_control
ret ret
@ -903,7 +892,7 @@ endp
; in: esi -> usb_controller, ebx -> usb_pipe ; in: esi -> usb_controller, ebx -> usb_pipe
; out: eax = endpoint address ; out: eax = endpoint address
proc ohci_get_device_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 and eax, 7Fh
ret ret
endp endp
@ -923,7 +912,7 @@ endp
; stores the packet size in ohci_pipe structure. ; stores the packet size in ohci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size ; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
proc ohci_set_endpoint_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. ; Wait until the hardware will forget the old value.
call usb_subscribe_control call usb_subscribe_control
ret ret
@ -943,27 +932,27 @@ virtual at ebp+8
.interval dd ? .interval dd ?
end virtual end virtual
; 1. Initialize the queue of transfer descriptors: empty. ; 1. Initialize the queue of transfer descriptors: empty.
sub eax, ohci_gtd.SoftwarePart sub eax, sizeof.ohci_gtd
call get_phys_addr call get_phys_addr
mov [edi+ohci_pipe.TailP-ohci_pipe.SoftwarePart], eax mov [edi+ohci_pipe.TailP-sizeof.ohci_pipe], eax
mov [edi+ohci_pipe.HeadP-ohci_pipe.SoftwarePart], eax mov [edi+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
; 2. Generate ohci_pipe.Flags, see the description in ohci_pipe. ; 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 and eax, 0x207F ; keep Speed bit and FunctionAddress
mov edx, [.endpoint] mov edx, [.endpoint]
and edx, 15 and edx, 15
shl edx, 7 shl edx, 7
or eax, edx 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 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 cmp [.type], CONTROL_PIPE
jz @f jz @f
test byte [.endpoint], 80h test byte [.endpoint], 80h
setnz al setnz al
inc eax inc eax
shl al, 3 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. ; 3. Insert the new pipe to the corresponding list of endpoints.
; 3a. Use Control list for control pipes, Bulk list for bulk pipes. ; 3a. Use Control list for control pipes, Bulk list for bulk pipes.
@ -992,11 +981,11 @@ end virtual
mov [edi+usb_pipe.PrevVirt], edx mov [edi+usb_pipe.PrevVirt], edx
mov [ecx+usb_pipe.PrevVirt], edi mov [ecx+usb_pipe.PrevVirt], edi
mov [edx+usb_pipe.NextVirt], edi mov [edx+usb_pipe.NextVirt], edi
mov ecx, [edx+ohci_pipe.NextED-ohci_pipe.SoftwarePart] mov ecx, [edx+ohci_pipe.NextED-sizeof.ohci_pipe]
mov [edi+ohci_pipe.NextED-ohci_pipe.SoftwarePart], ecx mov [edi+ohci_pipe.NextED-sizeof.ohci_pipe], ecx
lea eax, [edi-ohci_pipe.SoftwarePart] lea eax, [edi-sizeof.ohci_pipe]
call get_phys_addr 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. ; 4. Return something non-zero.
ret ret
.return0: .return0:
@ -1069,22 +1058,30 @@ endl
; this corresponds to 1001h bytes. If the requested size is ; this corresponds to 1001h bytes. If the requested size is
; greater, we should split the transfer into several descriptors. ; greater, we should split the transfer into several descriptors.
; Boundaries to split must be multiples of endpoint transfer size ; Boundaries to split must be multiples of endpoint transfer size
; to avoid short packets except in the end of the transfer, ; to avoid short packets except in the end of the transfer.
; 1000h is always a good value. cmp [size], 1001h
jbe .lastpacket
; 2. While the remaining data cannot fit in one packet, ; 2. While the remaining data cannot fit in one packet,
; allocate page-sized descriptors. ; allocate full-sized descriptors.
mov edi, 1000h ; 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 mov [packetSize], edi
.fullpackets: .fullpackets:
cmp [size], edi
jbe .lastpacket
call ohci_alloc_packet call ohci_alloc_packet
test eax, eax test eax, eax
jz .fail jz .fail
mov [td], eax mov [td], eax
add [buffer], edi add [buffer], edi
sub [size], edi sub [size], edi
jmp .fullpackets cmp [size], 1001h
ja .fullpackets
; 3. The remaining data can fit in one descriptor; ; 3. The remaining data can fit in one descriptor;
; allocate the last descriptor with size = size of remaining data. ; allocate the last descriptor with size = size of remaining data.
.lastpacket: .lastpacket:
@ -1094,7 +1091,7 @@ endl
test eax, eax test eax, eax
jz .fail jz .fail
; 4. Enable an immediate interrupt on completion of the last packet. ; 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 ; 5. If a short transfer is ok for a caller, set the corresponding bit in
; the last descriptor, but not in others. ; the last descriptor, but not in others.
; Note: even if the caller says that short transfers are ok, ; Note: even if the caller says that short transfers are ok,
@ -1104,7 +1101,7 @@ endl
; transparently to the caller. ; transparently to the caller.
test [flags], 1 test [flags], 1
jz @f 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 ret
.fail: .fail:
@ -1143,24 +1140,24 @@ end virtual
; 3. Save the returned value (next descriptor). ; 3. Save the returned value (next descriptor).
push eax push eax
; 4. Store the physical address of the next descriptor. ; 4. Store the physical address of the next descriptor.
sub eax, ohci_gtd.SoftwarePart sub eax, sizeof.ohci_gtd
call get_phys_addr 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. ; 5. For zero-length transfers, store zero in both fields for buffer addresses.
; Otherwise, fill them with real values. ; Otherwise, fill them with real values.
xor eax, eax xor eax, eax
mov [ecx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart], eax mov [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
mov [ecx+ohci_gtd.BufEnd-ohci_gtd.SoftwarePart], eax mov [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
cmp [.packetSize], eax cmp [.packetSize], eax
jz @f jz @f
mov eax, [.buffer] mov eax, [.buffer]
call get_phys_addr 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] mov eax, [.buffer]
add eax, [.packetSize] add eax, [.packetSize]
dec eax dec eax
call get_phys_addr 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: ; 6. Generate Flags field:
; - set bufferRounding (bit 18) to zero = disallow short transfers; ; - set bufferRounding (bit 18) to zero = disallow short transfers;
@ -1179,7 +1176,7 @@ end virtual
and edx, (3 shl 2) and edx, (3 shl 2)
shl edx, 24 - 2 shl edx, 24 - 2
lea eax, [eax + edx + (7 shl 21) + (15 shl 28)] 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. ; 7. Restore the returned value saved in step 3.
pop eax pop eax
.nothing: .nothing:
@ -1192,8 +1189,8 @@ endp
; ecx -> last descriptor for the transfer, ebx -> usb_pipe ; ecx -> last descriptor for the transfer, ebx -> usb_pipe
proc ohci_insert_transfer proc ohci_insert_transfer
; 1. Advance the queue of transfer descriptors. ; 1. Advance the queue of transfer descriptors.
mov eax, [ecx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart] mov eax, [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd]
mov [ebx+ohci_pipe.TailP-ohci_pipe.SoftwarePart], eax mov [ebx+ohci_pipe.TailP-sizeof.ohci_pipe], eax
; 2. For control and bulk pipes, notify the controller that ; 2. For control and bulk pipes, notify the controller that
; there is new work in control/bulk queue respectively. ; there is new work in control/bulk queue respectively.
ohci_notify_new_work: ohci_notify_new_work:
@ -1393,7 +1390,7 @@ proc ohci_process_finalized_td
mov edx, [ebx+usb_gtd.Pipe] mov edx, [ebx+usb_gtd.Pipe]
test [edx+usb_pipe.Flags], USB_FLAG_CLOSED test [edx+usb_pipe.Flags], USB_FLAG_CLOSED
jz @f jz @f
lea eax, [ebx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart] lea eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
xor ebx, ebx xor ebx, ebx
jmp .next_td2 jmp .next_td2
@@: @@:
@ -1402,13 +1399,13 @@ proc ohci_process_finalized_td
; 3. Get number of bytes that remain to be transferred. ; 3. Get number of bytes that remain to be transferred.
; If CurBufPtr is zero, everything was transferred. ; If CurBufPtr is zero, everything was transferred.
xor edx, edx xor edx, edx
cmp [ebx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart], edx cmp [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], edx
jz .gotlen jz .gotlen
; Otherwise, the remaining length is ; Otherwise, the remaining length is
; (BufEnd and 0xFFF) - (CurBufPtr and 0xFFF) + 1, ; (BufEnd and 0xFFF) - (CurBufPtr and 0xFFF) + 1,
; plus 0x1000 if BufEnd and CurBufPtr are in different pages. ; plus 0x1000 if BufEnd and CurBufPtr are in different pages.
mov edx, [ebx+ohci_gtd.BufEnd-ohci_gtd.SoftwarePart] mov edx, [ebx+ohci_gtd.BufEnd-sizeof.ohci_gtd]
mov eax, [ebx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart] mov eax, [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd]
mov ecx, edx mov ecx, edx
and edx, 0xFFF and edx, 0xFFF
inc edx inc edx
@ -1425,7 +1422,7 @@ proc ohci_process_finalized_td
neg edx neg edx
; 4. Check for error. If so, go to 7. ; 4. Check for error. If so, go to 7.
push ebx push ebx
mov eax, [ebx+ohci_gtd.Flags-ohci_gtd.SoftwarePart] mov eax, [ebx+ohci_gtd.Flags-sizeof.ohci_gtd]
shr eax, 28 shr eax, 28
jnz .error jnz .error
.notify: .notify:
@ -1451,7 +1448,7 @@ proc ohci_process_finalized_td
stdcall usb1_free_general_td, ebx stdcall usb1_free_general_td, ebx
@@: @@:
pop ebx pop ebx
lea eax, [ebx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart] lea eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
.next_td2: .next_td2:
push ebx push ebx
mov ebx, eax mov ebx, eax
@ -1484,10 +1481,10 @@ proc ohci_process_finalized_td
push eax push eax
push edx push edx
; DEBUGF 1,'K : TD failed:\n' ; 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-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-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+16],[ebx-sizeof.ohci_gtd+20],[ebx-sizeof.ohci_gtd+24],[ebx-sizeof.ohci_gtd+28]
; mov eax, [ebx+usb_gtd.Pipe] ; 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 ; 7b. Traverse the list of descriptors looking for the final packet
; for this transfer. ; for this transfer.
; Free and unlink non-final descriptors, except the current one. ; Free and unlink non-final descriptors, except the current one.
@ -1517,18 +1514,18 @@ end virtual
; After that, go to step 5 with eax = 0 (no error). ; After that, go to step 5 with eax = 0 (no error).
cmp dword [.error_code], USB_STATUS_UNDERRUN cmp dword [.error_code], USB_STATUS_UNDERRUN
jnz .no_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 jz .no_underrun
and dword [.error_code], 0 and dword [.error_code], 0
mov ecx, [ebx+usb_gtd.Pipe] 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 and edx, 2
.advance_queue: .advance_queue:
mov eax, [ebx+usb_gtd.NextVirt] mov eax, [ebx+usb_gtd.NextVirt]
sub eax, ohci_gtd.SoftwarePart sub eax, sizeof.ohci_gtd
call get_phys_addr call get_phys_addr
or eax, edx or eax, edx
mov [ecx+ohci_pipe.HeadP-ohci_pipe.SoftwarePart], eax mov [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
push ebx push ebx
mov ebx, ecx mov ebx, ecx
call ohci_notify_new_work call ohci_notify_new_work
@ -1562,10 +1559,10 @@ end virtual
; support functional stall as well, but this is not recommended."). ; support functional stall as well, but this is not recommended.").
; Advance the transfer queue to the next descriptor. ; Advance the transfer queue to the next descriptor.
mov ecx, [ebx+usb_gtd.Pipe] 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 and edx, 2 ; keep toggleCarry bit
cmp [ecx+usb_pipe.Type], CONTROL_PIPE cmp [ecx+usb_pipe.Type], CONTROL_PIPE
jnz @f jz @f
inc edx ; set Halted bit inc edx ; set Halted bit
@@: @@:
jmp .advance_queue jmp .advance_queue
@ -1577,7 +1574,7 @@ endp
proc ohci_unlink_pipe proc ohci_unlink_pipe
cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE
jnz @f jnz @f
mov eax, [ebx+ohci_pipe.Flags-ohci_pipe.SoftwarePart] mov eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
bt eax, 13 bt eax, 13
setc cl setc cl
bt eax, 11 bt eax, 11
@ -1589,7 +1586,7 @@ proc ohci_unlink_pipe
mov eax, [ebx+usb_pipe.PrevVirt] mov eax, [ebx+usb_pipe.PrevVirt]
mov [edx+usb_pipe.PrevVirt], eax mov [edx+usb_pipe.PrevVirt], eax
mov [eax+usb_pipe.NextVirt], edx mov [eax+usb_pipe.NextVirt], edx
mov edx, [ebx+ohci_pipe.NextED-ohci_pipe.SoftwarePart] mov edx, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
mov [eax+ohci_pipe.NextED-ohci_pipe.SoftwarePart], edx mov [eax+ohci_pipe.NextED-sizeof.ohci_pipe], edx
ret ret
endp endp

View File

@ -459,10 +459,7 @@ proc usb_after_set_endpoint_size
; save length for step 2 ; save length for step 2
push eax push eax
add eax, sizeof.usb_device_data + 8 add eax, sizeof.usb_device_data + 8
; Note that malloc destroys ebx.
push ebx
call malloc call malloc
pop ebx
; 1b. If failed, say something to the debug board and stop the initialization. ; 1b. If failed, say something to the debug board and stop the initialization.
test eax, eax test eax, eax
jz .nomemory jz .nomemory

View File

@ -432,14 +432,14 @@ endp
; in the list header. ; in the list header.
proc ehci_hs_interrupt_list_unlink proc ehci_hs_interrupt_list_unlink
; get target list ; 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 ; TODO: calculate real bandwidth
movzx eax, word [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart+2] movzx eax, word [ebx+ehci_pipe.Token-sizeof.ehci_pipe+2]
mov ecx, [ebx+ehci_pipe.Flags-ehci_pipe.SoftwarePart] mov ecx, [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
and eax, (1 shl 11) - 1 and eax, (1 shl 11) - 1
shr ecx, 30 shr ecx, 30
imul eax, ecx 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 add edx, ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart
; update bandwidth ; update bandwidth
.dec_bandwidth: .dec_bandwidth:

View File

@ -20,9 +20,8 @@ USB_PID_IN = 69h
USB_PID_OUT = 0E1h USB_PID_OUT = 0E1h
; UHCI does not support an interrupt on root hub status change. We must poll ; 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). ; 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), ; We use the value 100 ticks: it is small enough to be responsive to connect
; small enough to be responsible to connect events and large enough to not ; events and large enough to not load CPU too often.
; load CPU too often.
UHCI_POLL_INTERVAL = 100 UHCI_POLL_INTERVAL = 100
; the following constant is an invalid encoding for length fields in ; the following constant is an invalid encoding for length fields in
; uhci_gtd; it is used to check whether an inactive TD has been ; uhci_gtd; it is used to check whether an inactive TD has been
@ -42,8 +41,8 @@ UHCI_INVALID_LENGTH = 700h
; software book-keeping. ; software book-keeping.
; * The hardware requires 16-bytes alignment of the hardware part. ; * The hardware requires 16-bytes alignment of the hardware part.
; Since the allocator (usb_allocate_common) allocates memory sequentially ; Since the allocator (usb_allocate_common) allocates memory sequentially
; from page start (aligned on 0x1000 bytes), size of the structure must be ; from page start (aligned on 0x1000 bytes), block size for the allocator
; divisible by 16. ; must be divisible by 16; usb1_allocate_endpoint ensures this.
struct uhci_pipe struct uhci_pipe
NextQH dd ? NextQH dd ?
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next QH. ; 1. First bit (bit 0) is Terminate bit. 1 = there is no next QH.
@ -81,14 +80,8 @@ Token dd ?
ErrorTD dd ? ErrorTD dd ?
; Usually NULL. If nonzero, it is a pointer to descriptor which was error'd ; 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). ; 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 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. ; This structure describes the static head of every list of pipes.
; The hardware requires 16-bytes alignment of this structure. ; The hardware requires 16-bytes alignment of this structure.
; All instances of this structure are located sequentially in uhci_controller, ; All instances of this structure are located sequentially in uhci_controller,
@ -167,7 +160,8 @@ end if
; * The hardware requires 16-bytes alignment of the hardware part, so ; * The hardware requires 16-bytes alignment of the hardware part, so
; the entire descriptor must be 16-bytes aligned. Since the allocator ; the entire descriptor must be 16-bytes aligned. Since the allocator
; (uhci_allocate_common) allocates memory sequentially from page start ; (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 struct uhci_gtd
NextTD dd ? NextTD dd ?
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next TD. ; 1. First bit (bit 0) is Terminate bit. 1 = there is no next TD.
@ -231,14 +225,8 @@ OrigBufferInfo dd ?
; bit 0: 1 = short packet is NOT allowed ; bit 0: 1 = short packet is NOT allowed
; (before the TD is processed, it is the copy of bit 29 of ControlStatus; ; (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) ; 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 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. ; UHCI requires that the entire transfer buffer should be on one page.
; If the actual buffer crosses page boundary, uhci_alloc_packet ; If the actual buffer crosses page boundary, uhci_alloc_packet
; allocates additional memory for buffer for hardware. ; allocates additional memory for buffer for hardware.
@ -853,7 +841,7 @@ proc uhci_process_updated_list
; if either of conditions holds, exit from the internal loop. ; if either of conditions holds, exit from the internal loop.
cmp ebx, [esp] cmp ebx, [esp]
jz .tddone 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? test eax, 1 shl 23 ; active?
jnz .tddone jnz .tddone
; Release the queue lock while processing one descriptor: ; Release the queue lock while processing one descriptor:
@ -889,10 +877,10 @@ proc uhci_process_finalized_td
; DEBUGF 1,'K : %x %x %x %x\n',[ebx-4],[ebx],[ebx+4],[ebx+8] ; 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 ; 2. If this is IN transfer into special buffer, copy the data
; to target location. ; 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) and edx, not 1 ; clear lsb (used for another goal)
jz .nocopy 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 jnz .nocopy
; Note: we assume that pointer to buffer is valid in the memory space of ; 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 ; the USB thread. This means that buffer must reside in kernel memory
@ -900,7 +888,7 @@ proc uhci_process_finalized_td
push esi edi push esi edi
mov esi, [edx+uhci_original_buffer.UsedBuffer] mov esi, [edx+uhci_original_buffer.UsedBuffer]
mov edi, [edx+uhci_original_buffer.OrigBuffer] 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 inc ecx
and ecx, 7FFh and ecx, 7FFh
mov edx, ecx mov edx, ecx
@ -913,8 +901,8 @@ proc uhci_process_finalized_td
.nocopy: .nocopy:
; 3. Calculate actual number of bytes transferred. ; 3. Calculate actual number of bytes transferred.
; 3a. Read the state. ; 3a. Read the state.
mov eax, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart] mov eax, [ebx+uhci_gtd.ControlStatus-sizeof.uhci_gtd]
mov ecx, [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart] mov ecx, [ebx+uhci_gtd.Token-sizeof.uhci_gtd]
; 3b. Get number of bytes processed. ; 3b. Get number of bytes processed.
lea edx, [eax+1] lea edx, [eax+1]
and edx, 7FFh and edx, 7FFh
@ -938,7 +926,7 @@ proc uhci_process_finalized_td
xor ecx, ecx xor ecx, ecx
test eax, 1 shl 22 test eax, 1 shl 22
jnz .error jnz .error
test byte [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1 test byte [ebx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
jz .notify jz .notify
cmp edx, [ebx+usb_gtd.Length] cmp edx, [ebx+usb_gtd.Length]
jz .notify jz .notify
@ -946,7 +934,7 @@ proc uhci_process_finalized_td
; 5. There was an error while processing this packet. ; 5. There was an error while processing this packet.
; The hardware has stopped processing the queue. ; The hardware has stopped processing the queue.
DEBUGF 1,'K : TD failed:\n' DEBUGF 1,'K : TD failed:\n'
if uhci_gtd.SoftwarePart <> 20 if sizeof.uhci_gtd <> 20
.err modify offsets for debug output .err modify offsets for debug output
end if end if
DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8] DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8]
@ -955,17 +943,17 @@ end if
push edx push edx
push eax push eax
mov eax, [ebx+usb_gtd.Pipe] 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. ; 5b. Store the current TD as an error packet.
; If an error packet is already stored for this pipe, ; If an error packet is already stored for this pipe,
; it is definitely not used already, so free the old packet. ; 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 test eax, eax
jz @f jz @f
stdcall uhci_free_td, eax stdcall uhci_free_td, eax
@@: @@:
mov eax, [ebx+usb_gtd.Pipe] 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 ; 5c. Traverse the list of descriptors looking for the final packet
; for this transfer. ; for this transfer.
; Free and unlink non-final descriptors, except the current one. ; Free and unlink non-final descriptors, except the current one.
@ -1019,17 +1007,17 @@ end if
; After that, go to step 6 with ecx = 0 (no error). ; After that, go to step 6 with ecx = 0 (no error).
cmp ecx, USB_STATUS_UNDERRUN cmp ecx, USB_STATUS_UNDERRUN
jnz @f jnz @f
test byte [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1 test byte [ebx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
jnz @f jnz @f
; The controller has stopped this queue on the error packet. ; The controller has stopped this queue on the error packet.
; Update uhci_pipe.HeadTD to point to the next packet in the queue. ; Update uhci_pipe.HeadTD to point to the next packet in the queue.
call uhci_fix_toggle call uhci_fix_toggle
xor ecx, ecx xor ecx, ecx
.control: .control:
mov eax, [ebx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart] mov eax, [ebx+uhci_gtd.NextTD-sizeof.uhci_gtd]
and al, not 0xF and al, not 0xF
mov edx, [ebx+usb_gtd.Pipe] 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 pop edx ; length
jmp .notify jmp .notify
@@: @@:
@ -1047,7 +1035,7 @@ end if
push ecx push ecx
mov eax, [ebx+usb_gtd.Pipe] mov eax, [ebx+usb_gtd.Pipe]
push [ebx+usb_gtd.NextVirt] 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 jz @f
stdcall uhci_free_td, ebx stdcall uhci_free_td, ebx
@@: @@:
@ -1065,10 +1053,10 @@ end if
cmp [edx+usb_pipe.Type], CONTROL_PIPE cmp [edx+usb_pipe.Type], CONTROL_PIPE
jz .control jz .control
; Bulk/interrupt transfer; halt the queue. ; 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 and al, not 0xF
inc eax ; set Halted bit 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 pop edx ; restore length saved in step 5a
.notify: .notify:
; 6. Either the descriptor in ebx was processed without errors, ; 6. Either the descriptor in ebx was processed without errors,
@ -1094,7 +1082,7 @@ end if
push [ebx+usb_gtd.NextVirt] push [ebx+usb_gtd.NextVirt]
; 7b. Free the descriptor, unless it is saved as ErrorTD. ; 7b. Free the descriptor, unless it is saved as ErrorTD.
mov eax, [ebx+usb_gtd.Pipe] 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 jz @f
stdcall uhci_free_td, ebx stdcall uhci_free_td, ebx
@@: @@:
@ -1118,9 +1106,9 @@ proc uhci_fix_toggle
; 2. The hardware expects next packet with toggle = (ErrorTD.toggle xor 1), ; 2. The hardware expects next packet with toggle = (ErrorTD.toggle xor 1),
; the current value in next packet is (ebx.toggle xor 1). ; the current value in next packet is (ebx.toggle xor 1).
; Nothing to do if ErrorTD.toggle == ebx.toggle. ; Nothing to do if ErrorTD.toggle == ebx.toggle.
mov eax, [ecx+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart] mov eax, [ecx+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
mov eax, [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart] mov eax, [eax+uhci_gtd.Token-sizeof.uhci_gtd]
xor eax, [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart] xor eax, [ebx+uhci_gtd.Token-sizeof.uhci_gtd]
test eax, 1 shl 19 test eax, 1 shl 19
jz .nothing jz .nothing
; 3. Lock the transfer queue. ; 3. Lock the transfer queue.
@ -1130,13 +1118,13 @@ proc uhci_fix_toggle
; (inclusive). ; (inclusive).
mov eax, [ebx+usb_gtd.NextVirt] mov eax, [ebx+usb_gtd.NextVirt]
.loop: .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] cmp eax, [ecx+usb_pipe.LastTD-usb_pipe.Lock]
mov eax, [eax+usb_gtd.NextVirt] mov eax, [eax+usb_gtd.NextVirt]
jnz .loop jnz .loop
; 5. Flip the toggle bit in uhci_pipe structure. ; 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) xor byte [ecx+uhci_pipe.Token-sizeof.uhci_pipe-usb_pipe.Lock+2], 1 shl (19-16)
or dword [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart-usb_pipe.Lock], eax or dword [ecx+uhci_pipe.Token-sizeof.uhci_pipe-usb_pipe.Lock], eax
; 6. Unlock the transfer queue. ; 6. Unlock the transfer queue.
call mutex_unlock call mutex_unlock
.nothing: .nothing:
@ -1338,7 +1326,7 @@ endp
; and stores USB device address in the uhci_pipe structure. ; and stores USB device address in the uhci_pipe structure.
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address ; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
proc uhci_set_device_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 call usb_subscription_done
ret ret
endp endp
@ -1347,7 +1335,7 @@ endp
; in: esi -> usb_controller, ebx -> usb_pipe ; in: esi -> usb_controller, ebx -> usb_pipe
; out: eax = endpoint address ; out: eax = endpoint address
proc uhci_get_device_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 and eax, 7Fh
ret ret
endp endp
@ -1372,8 +1360,8 @@ endp
proc uhci_set_endpoint_packet_size proc uhci_set_endpoint_packet_size
dec ecx dec ecx
shl ecx, 21 shl ecx, 21
and [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], (1 shl 21) - 1 and [ebx+uhci_pipe.Token-sizeof.uhci_pipe], (1 shl 21) - 1
or [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], ecx or [ebx+uhci_pipe.Token-sizeof.uhci_pipe], ecx
; uhci_pipe.Token field is purely for software bookkeeping and does not affect ; uhci_pipe.Token field is purely for software bookkeeping and does not affect
; the hardware; thus, we can continue initialization immediately. ; the hardware; thus, we can continue initialization immediately.
call usb_subscription_done call usb_subscription_done
@ -1395,18 +1383,18 @@ virtual at ebp+8
.interval dd ? .interval dd ?
end virtual end virtual
; 1. Initialize ErrorTD to zero. ; 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. ; 2. Initialize HeadTD to the physical address of the first TD.
push eax ; store pointer to the first TD for step ? push eax ; store pointer to the first TD for step 4
sub eax, uhci_gtd.SoftwarePart sub eax, sizeof.uhci_gtd
call get_phys_addr 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: ; 3. Initialize Token field:
; take DeviceAddress and LowSpeedDevice from the parent pipe, ; take DeviceAddress and LowSpeedDevice from the parent pipe,
; take Endpoint and MaximumLength fields from API arguments, ; take Endpoint and MaximumLength fields from API arguments,
; set PID depending on pipe type and provided pipe direction, ; set PID depending on pipe type and provided pipe direction,
; set DataToggle to zero. ; 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 and eax, 0x107F00 ; keep DeviceAddress and LowSpeedDevice
mov edx, [.endpoint] mov edx, [.endpoint]
and edx, 15 and edx, 15
@ -1424,20 +1412,22 @@ end virtual
jz @f jz @f
mov al, USB_PID_IN 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: ; 4. Initialize the first TD:
; copy Token from uhci_pipe.Token zeroing reserved bit 20, ; copy Token from uhci_pipe.Token zeroing reserved bit 20,
; set ControlStatus for future transfers, bit make it inactive, ; 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 pop edx ; restore pointer saved in step 2
mov [edx+uhci_gtd.Token-uhci_gtd.SoftwarePart], eax mov [edx+uhci_gtd.Token-sizeof.uhci_gtd], eax
and byte [edx+uhci_gtd.Token+2-uhci_gtd.SoftwarePart], not (1 shl (20-16)) and byte [edx+uhci_gtd.Token+2-sizeof.uhci_gtd], not (1 shl (20-16))
and eax, 1 shl 20 and eax, 1 shl 20
shl eax, 6 shl eax, 6
or eax, UHCI_INVALID_LENGTH + (3 shl 27) or eax, UHCI_INVALID_LENGTH + (3 shl 27)
; not processed, inactive, allow 3 errors ; not processed, inactive, allow 3 errors
mov [edx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart], eax and [edx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 0
mov [edx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 1 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. ; 5. Select the corresponding list and insert to the list.
; 5a. Use Control list for control pipes, Bulk list for bulk pipes. ; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
lea edx, [esi+uhci_controller.ControlED.SoftwarePart-sizeof.uhci_controller] lea edx, [esi+uhci_controller.ControlED.SoftwarePart-sizeof.uhci_controller]
@ -1471,8 +1461,8 @@ end virtual
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe, ; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
; store the physical address of the new pipe to previous NextQH. ; store the physical address of the new pipe to previous NextQH.
mov ecx, [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart] mov ecx, [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart]
mov [edi+uhci_pipe.NextQH-uhci_pipe.SoftwarePart], ecx mov [edi+uhci_pipe.NextQH-sizeof.uhci_pipe], ecx
lea eax, [edi-uhci_pipe.SoftwarePart] lea eax, [edi-sizeof.uhci_pipe]
call get_phys_addr call get_phys_addr
inc eax inc eax
inc eax inc eax
@ -1486,13 +1476,13 @@ endp
; This procedure is called when a pipe is closing (either due to API call ; 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. ; or due to disconnect); it unlinks a pipe from the corresponding list.
if 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 == uhci_pipe.SoftwarePart .err uhci_unlink_pipe assumes that uhci_static_ep.SoftwarePart == sizeof.uhci_pipe
end if end if
proc uhci_unlink_pipe proc uhci_unlink_pipe
cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE cmp [ebx+usb_pipe.Type], INTERRUPT_PIPE
jnz @f 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 cmp al, USB_PID_IN
setz ch setz ch
bt eax, 20 bt eax, 20
@ -1510,8 +1500,8 @@ proc uhci_unlink_pipe
mov [eax+usb_pipe.NextVirt], edx mov [eax+usb_pipe.NextVirt], edx
; Note: eax could be either usb_pipe or usb_static_ep; ; Note: eax could be either usb_pipe or usb_static_ep;
; fortunately, NextQH and SoftwarePart have same offsets in both. ; fortunately, NextQH and SoftwarePart have same offsets in both.
mov edx, [ebx+uhci_pipe.NextQH-uhci_pipe.SoftwarePart] mov edx, [ebx+uhci_pipe.NextQH-sizeof.uhci_pipe]
mov [eax+uhci_pipe.NextQH-uhci_pipe.SoftwarePart], edx mov [eax+uhci_pipe.NextQH-sizeof.uhci_pipe], edx
ret ret
endp endp
@ -1519,7 +1509,7 @@ endp
; For UHCI, this includes usb_pipe structure and ErrorTD, if present. ; For UHCI, this includes usb_pipe structure and ErrorTD, if present.
proc uhci_free_pipe proc uhci_free_pipe
mov eax, [esp+4] 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 test eax, eax
jz @f jz @f
stdcall uhci_free_td, eax stdcall uhci_free_td, eax
@ -1544,7 +1534,7 @@ endl
; with size <= endpoint max packet size. ; with size <= endpoint max packet size.
; 2. Get the maximum packet size for endpoint from uhci_pipe.Token ; 2. Get the maximum packet size for endpoint from uhci_pipe.Token
; and generate Token field for TDs. ; 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 mov eax, edi
shr edi, 21 shr edi, 21
inc edi inc edi
@ -1602,14 +1592,14 @@ endl
; transparently to the caller. ; transparently to the caller.
test [flags], 1 test [flags], 1
jz @f jz @f
and byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], not (1 shl (29-24)) and byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], not (1 shl (29-24))
and byte [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], not 1 and byte [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], not 1
@@: @@:
; 6. Update toggle bit in uhci_pipe structure from current value of [token]. ; 6. Update toggle bit in uhci_pipe structure from current value of [token].
mov edx, [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 and edx, 1 shl 19
xor [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], edx xor [ebx+uhci_pipe.Token-sizeof.uhci_pipe], edx
.nothing: .nothing:
ret ret
.fail: .fail:
@ -1652,12 +1642,10 @@ end virtual
; 1c. We need a temporary buffer. Allocate [packetSize]*2 bytes, so that ; 1c. We need a temporary buffer. Allocate [packetSize]*2 bytes, so that
; there must be [packetSize] bytes on one page, ; there must be [packetSize] bytes on one page,
; plus space for a header uhci_original_buffer. ; plus space for a header uhci_original_buffer.
push ebx
mov eax, [.packetSize] mov eax, [.packetSize]
add eax, eax add eax, eax
add eax, sizeof.uhci_original_buffer add eax, sizeof.uhci_original_buffer
call malloc call malloc
pop ebx
; 1d. If failed, return zero. ; 1d. If failed, return zero.
test eax, eax test eax, eax
jz .nothing jz .nothing
@ -1712,45 +1700,50 @@ end virtual
; mark it as last one (this will be changed when further packets will be ; 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, ; allocated), copy Token field from uhci_pipe.Token zeroing bit 20,
; generate ControlStatus field, mark as Active ; generate ControlStatus field, mark as Active
; (for last descriptor, this will be changed by uhci_insert_transfer). ; (for last descriptor, this will be changed by uhci_insert_transfer),
mov [eax+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 1 ; no next TD ; zero OrigBufferInfo (otherwise uhci_free_td would try to free it).
mov edx, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart] and [eax+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 0
mov [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart], edx mov [eax+uhci_gtd.NextTD-sizeof.uhci_gtd], 1 ; no next TD
and byte [eax+uhci_gtd.Token+2-uhci_gtd.SoftwarePart], not (1 shl (20-16)) 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 and edx, 1 shl 20
shl edx, 6 shl edx, 6
or edx, UHCI_INVALID_LENGTH + (1 shl 23) + (3 shl 27) or edx, UHCI_INVALID_LENGTH + (1 shl 23) + (3 shl 27)
; not processed, active, allow 3 errors ; 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. ; 5. Initialize remaining fields of the current TD.
; 5a. Store pointer to the buffer allocated in step 1 (or zero). ; 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. ; 5b. Store physical address of the next TD.
push eax push eax
sub eax, uhci_gtd.SoftwarePart sub eax, sizeof.uhci_gtd
call get_phys_addr 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 ; uhci_insert_transfer will set Depth traversal for the first TD and clear
; it in the last TD ; it in the last TD
test [ebx+usb_pipe.Type], 1
jnz @f
cmp ecx, [ebx+usb_pipe.LastTD] cmp ecx, [ebx+usb_pipe.LastTD]
jz @f jz @f
or eax, 4 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, ; 5c. Store physical address of the buffer: zero if no data present,
; the temporary buffer if it was allocated, the given buffer otherwise. ; the temporary buffer if it was allocated, the given buffer otherwise.
xor eax, eax xor eax, eax
cmp [.packetSize], eax cmp [.packetSize], eax
jz .hasphysbuf jz .hasphysbuf
mov eax, [.buffer] mov eax, [.buffer]
mov edx, [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart] mov edx, [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
test edx, edx test edx, edx
jz @f jz @f
mov eax, [edx+uhci_original_buffer.UsedBuffer] mov eax, [edx+uhci_original_buffer.UsedBuffer]
@@: @@:
call get_phys_addr call get_phys_addr
.hasphysbuf: .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. ; 5d. For IN transfers, disallow short packets.
; This will be overridden, if needed, by uhci_alloc_transfer. ; This will be overridden, if needed, by uhci_alloc_transfer.
mov eax, [.token] mov eax, [.token]
@ -1758,13 +1751,13 @@ end virtual
dec edx dec edx
cmp al, USB_PID_IN cmp al, USB_PID_IN
jnz @f jnz @f
or byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], 1 shl (29-24) ; disallow short packets or byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], 1 shl (29-24) ; disallow short packets
or byte [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1 or byte [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
@@: @@:
; 5e. Get Token field: combine [.token] with [.packetSize]. ; 5e. Get Token field: combine [.token] with [.packetSize].
shl edx, 21 shl edx, 21
or edx, eax 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]. ; 6. Flip toggle bit in [.token].
xor eax, 1 shl 19 xor eax, 1 shl 19
mov [.token], eax mov [.token], eax
@ -1785,11 +1778,14 @@ endp
; ecx -> last descriptor for the transfer, ebx -> usb_pipe ; ecx -> last descriptor for the transfer, ebx -> usb_pipe
proc uhci_insert_transfer proc uhci_insert_transfer
; DEBUGF 1,'K : uhci_insert_transfer: eax=%x, ecx=%x, [esp+4]=%x\n',eax,ecx,[esp+4] ; 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 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-uhci_gtd.SoftwarePart], 1 shl (24-24) ; set InterruptOnComplete bit or byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], 1 shl (24-24) ; set InterruptOnComplete bit
mov eax, [esp+4] 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.ControlStatus+2-sizeof.uhci_gtd], 1 shl (23-16) ; set Active bit
or byte [eax+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 4 ; set Depth bit test [ebx+usb_pipe.Type], 1
jnz @f
or byte [eax+uhci_gtd.NextTD-sizeof.uhci_gtd], 4 ; set Depth bit
@@:
ret ret
endp endp
@ -1798,13 +1794,13 @@ endp
; and the temporary buffer, if present. ; and the temporary buffer, if present.
proc uhci_free_td proc uhci_free_td
mov eax, [esp+4] 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 and eax, not 1
jz .nobuf jz .nobuf
push ebx push ebx
call free call free
pop ebx pop ebx
.nobuf: .nobuf:
sub dword [esp+4], uhci_gtd.SoftwarePart sub dword [esp+4], sizeof.uhci_gtd
jmp usb_free_common jmp usb_free_common
endp endp

View File

@ -272,6 +272,11 @@ BOOT_APM_FLAGS equ 0x9046 ;unused
BOOT_APM_CODE_32 equ 0x9050 BOOT_APM_CODE_32 equ 0x9050
BOOT_APM_CODE_16 equ 0x9052 BOOT_APM_CODE_16 equ 0x9052
BOOT_APM_DATA_16 equ 0x9054 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_FILE_NAME equ 0
TMP_CMD_LINE equ 1024 TMP_CMD_LINE equ 1024

View File

@ -22,7 +22,7 @@ $Revision$
; ;
align 4 align 4
malloc: malloc:
push esi push ebx esi
; nb = ((size+7)&~7)+8; ; nb = ((size+7)&~7)+8;
@ -96,7 +96,7 @@ malloc:
mov ecx, mst.mutex mov ecx, mst.mutex
call mutex_unlock call mutex_unlock
mov eax, esi mov eax, esi
pop esi pop esi ebx
ret ret
.split: .split:
@ -205,7 +205,7 @@ free:
test eax, eax test eax, eax
jz .exit jz .exit
push edi push ebx edi
mov edi, eax mov edi, eax
add edi, -8 add edi, -8
@ -298,7 +298,7 @@ free:
mov eax, esi mov eax, esi
pop esi pop esi
.fail: .fail:
pop edi pop edi ebx
.exit: .exit:
ret ret

View File

@ -896,6 +896,7 @@ v86_irq2:
iretd iretd
.found: .found:
mov cr3, eax mov cr3, eax
mov esi, [ebx+APPDATA.saved_esp0]
sub word [esi-sizeof.v86_regs+v86_regs.esp], 6 sub word [esi-sizeof.v86_regs+v86_regs.esp], 6
mov ecx, [esi-sizeof.v86_regs+v86_regs.eip] mov ecx, [esi-sizeof.v86_regs+v86_regs.eip]
mov word [edx], cx mov word [edx], cx
@ -916,7 +917,7 @@ v86_irq2:
call update_counters call update_counters
lea edi, [ebx + 0x100000000 - SLOT_BASE] lea edi, [ebx + 0x100000000 - SLOT_BASE]
shr edi, 3 shr edi, 3
add edi, TASK_DATA add edi, CURRENT_TASK
call find_next_task.found call find_next_task.found
call do_change_task call do_change_task
popad popad

View File

@ -44,6 +44,8 @@ FindHDD:
jmp EndFindHDD jmp EndFindHDD
FindHDD_1: FindHDD_1:
DEBUGF 1, "K : Channel %d ",[ChannelNumber]:2
DEBUGF 1, "Disk %d\n",[DiskNumber]:1
call ReadHDD_ID call ReadHDD_ID
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne FindHDD_2 jne FindHDD_2
@ -52,7 +54,7 @@ FindHDD_1:
cmp [Sector512+12], word 255 cmp [Sector512+12], word 255
ja FindHDD_2 ja FindHDD_2
inc byte [DRIVE_DATA+1] inc byte [DRIVE_DATA+1]
jmp FindHDD_2_2 jmp Print_Device_Name
FindHDD_2: FindHDD_2:
call DeviceReset call DeviceReset
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
@ -62,6 +64,21 @@ FindHDD_1:
jne FindHDD_2_2 jne FindHDD_2_2
inc byte [DRIVE_DATA+1] inc byte [DRIVE_DATA+1]
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: FindHDD_2_2:
ret ret
@ -70,10 +87,11 @@ FindHDD_3:
shl byte [DRIVE_DATA+1], 2 shl byte [DRIVE_DATA+1], 2
ret ret
; Адрес считываемого сектора в режиме LBA ; Адрес считываемого сектора в режиме LBA
uglobal uglobal
SectorAddress DD ? SectorAddress DD ?
dev_name:
rb 41
endg endg
;************************************************* ;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * ;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА *

View File

@ -206,7 +206,4 @@ clear_ide_cache:
ret ret
end_get_cache: 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 popa

View File

@ -17,7 +17,8 @@ $Revision$
search_partitions_ide0: search_partitions_ide0:
test [DRIVE_DATA+1], byte 0x40 test [DRIVE_DATA+1], byte 0x40
jz search_partitions_ide1 jz search_partitions_ide1
mov [hdbase], 0x1f0 mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x0 mov [hdid], 0x0
mov [hdpos], 1 mov [hdpos], 1
mov [known_part], 1 mov [known_part], 1
@ -39,7 +40,8 @@ $Revision$
search_partitions_ide1: search_partitions_ide1:
test [DRIVE_DATA+1], byte 0x10 test [DRIVE_DATA+1], byte 0x10
jz search_partitions_ide2 jz search_partitions_ide2
mov [hdbase], 0x1f0 mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x10 mov [hdid], 0x10
mov [hdpos], 2 mov [hdpos], 2
mov [known_part], 1 mov [known_part], 1
@ -61,7 +63,8 @@ $Revision$
search_partitions_ide2: search_partitions_ide2:
test [DRIVE_DATA+1], byte 0x4 test [DRIVE_DATA+1], byte 0x4
jz search_partitions_ide3 jz search_partitions_ide3
mov [hdbase], 0x170 mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x0 mov [hdid], 0x0
mov [hdpos], 3 mov [hdpos], 3
mov [known_part], 1 mov [known_part], 1
@ -83,7 +86,8 @@ $Revision$
search_partitions_ide3: search_partitions_ide3:
test [DRIVE_DATA+1], byte 0x1 test [DRIVE_DATA+1], byte 0x1
jz end_search_partitions_ide jz end_search_partitions_ide
mov [hdbase], 0x170 mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10 mov [hdid], 0x10
mov [hdpos], 4 mov [hdpos], 4
mov [known_part], 1 mov [known_part], 1

View File

@ -1794,6 +1794,23 @@ dd 1675
* При создании процесса/потока текущая папка наследуется от * При создании процесса/потока текущая папка наследуется от
родителя. родителя.
---- Подфункция 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 - узнать кому принадлежит точка экрана. ========= ========= Функция 34 - узнать кому принадлежит точка экрана. =========
====================================================================== ======================================================================

View File

@ -1776,6 +1776,23 @@ Remarks:
* At process/thread creation the current folder will be inherited * At process/thread creation the current folder will be inherited
from the parent. 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. =========== ========= Function 34 - who owner the pixel on the screen. ===========
====================================================================== ======================================================================

View File

@ -310,7 +310,9 @@ if 1
end if end if
and byte [esi+7000Bh], not 80h ; PIPEACONF: disable pipe and byte [esi+7000Bh], not 80h ; PIPEACONF: disable pipe
and byte [esi+7100Bh], not 80h ; PIPEBCONF: 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 edx, 10000h
@@: @@:
mov ecx, 1000h mov ecx, 1000h
@ -319,20 +321,17 @@ if 1
jz @f jz @f
dec edx dec edx
jnz @b jnz @b
.not_disabled: jmp .not_disabled
sti
jmp .return
@@: @@:
test byte [esi+7100Bh], 40h ; PIPEBCONF: wait until pipe disabled test byte [esi+7100Bh], 40h ; PIPEBCONF: wait until pipe disabled
jz @f jz .disabled
mov ecx, 1000h mov ecx, 1000h
loop $ loop $
dec edx dec edx
jnz @b jnz @b
jmp .not_disabled jmp .not_disabled
@@: ; pineview and before: wait while scanline still changes
else .wait_watching_scanline:
; alternative way of waiting for pipe stop, works too
mov edx, 1000h mov edx, 1000h
.dis1: .dis1:
push dword [esi+71000h] push dword [esi+71000h]
@ -354,7 +353,6 @@ else
sti sti
jmp .return jmp .return
.disabled: .disabled:
end if
lea eax, [esi+61183h] lea eax, [esi+61183h]
cmp [deviceType], ironlake_start cmp [deviceType], ironlake_start
jb @f jb @f
@ -378,6 +376,7 @@ end if
and ecx, not 15 and ecx, not 15
shl ecx, 2 shl ecx, 2
mov dword [edx+10188h], ecx ; DSPASTRIDE: set scanline length 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 and byte [esi+61233h], not 80h ; PFIT_CONTROL: disable panel fitting
or byte [edx+1000Bh], 80h ; PIPEACONF: enable pipe or byte [edx+1000Bh], 80h ; PIPEACONF: enable pipe
; and byte [edx+1000Ah], not 0Ch ; PIPEACONF: enable Display+Cursor Planes ; and byte [edx+1000Ah], not 0Ch ; PIPEACONF: enable Display+Cursor Planes
@ -437,6 +436,9 @@ i965_start = ($ - pciids) / 2
dw 0x29b2 ; q35g dw 0x29b2 ; q35g
dw 0x29c2 ; g33g dw 0x29c2 ; g33g
dw 0x29d2 ; q33g dw 0x29d2 ; q33g
dw 0xa001 ; pineview
dw 0xa011 ; pineview
gen4_start = ($ - pciids) / 2
dw 0x2a02 ; i965gm dw 0x2a02 ; i965gm
dw 0x2a12 ; i965gm dw 0x2a12 ; i965gm
dw 0x2a42 ; gm45 dw 0x2a42 ; gm45
@ -446,8 +448,6 @@ i965_start = ($ - pciids) / 2
dw 0x2e32 ; g45 dw 0x2e32 ; g45
dw 0x2e42 ; g45 dw 0x2e42 ; g45
dw 0x2e92 ; g45 dw 0x2e92 ; g45
dw 0xa001 ; pineview
dw 0xa011 ; pineview
ironlake_start = ($ - pciids) / 2 ironlake_start = ($ - pciids) / 2
dw 0x0042 ; ironlake_d dw 0x0042 ; ironlake_d
dw 0x0046 ; ironlake_m dw 0x0046 ; ironlake_m

View File

@ -4,7 +4,7 @@
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; 02.02.2010 turbanoff - support 70.5 ;; ;; 02.02.2010 turbanoff - support 70.5 ;;
;; 23.01.2010 turbanoff - support 70.0 70.1 ;; ;; 23.01.2010 turbanoff - support 70.0 70.1 ;;
;; ;; ;; 21.06.2013 yogev_ezra - Translate Russian comments ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -17,31 +17,34 @@ EXT2_ACL_DATA_INO = 4
EXT2_BOOT_LOADER_INO = 5 EXT2_BOOT_LOADER_INO = 5
EXT2_UNDEL_DIR_INO = 6 EXT2_UNDEL_DIR_INO = 6
;флаги, указываемый в inode файла ;RUS: флаги, указываемые в inode файла ;ENG: flags specified in file inode
EXT2_S_IFREG = 0x8000 EXT2_S_IFREG = 0x8000
EXT2_S_IFDIR = 0x4000 EXT2_S_IFDIR = 0x4000
EXT2_S_IFMT = 0xF000 ;маска для типа файла EXT2_S_IFMT = 0xF000 ;RUS: маска для типа файла ;ENG: mask for file type
;флаги, указываемые в linked list родительской папки ;RUS: флаги, указываемые в linked list родительской папки
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге ;ENG: flags specified in linked list of parent folder
EXT2_FT_DIR = 2 ;это папка 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_HIDDEN = 2
FS_FT_DIR = 0x10 ;это папка FS_FT_DIR = 0x10 ;RUS: это папка ;ENG: this is a folder
FS_FT_ASCII = 0 ;имя в ascii FS_FT_ASCII = 0 ;RUS: имя в ascii ;ENG: name in ASCII
FS_FT_UNICODE = 1 ;имя в unicode FS_FT_UNICODE = 1 ;RUS: имя в unicode ;ENG: name in UNICODE
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;тип файла должен указываться в директории EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;RUS: тип файла должен указываться в директории
EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;экстенты ;ENG: file type must be specified in the folder
EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ;гибкие группы блоков EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;RUS: экстенты ;ENG: extents
;реализованные ext[234] features 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 \ EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
or EXT4_FEATURE_INCOMPAT_EXTENTS \ or EXT4_FEATURE_INCOMPAT_EXTENTS \
or EXT4_FEATURE_INCOMPAT_FLEX_BG or EXT4_FEATURE_INCOMPAT_FLEX_BG
;RUS: флаги, указываемые для inode в i_flags ;ENG: flags specified for inode in i_flags
;флаги, указываемые для inode в i_flags
EXT2_EXTENTS_FL = 0x00080000 EXT2_EXTENTS_FL = 0x00080000
struct EXT2_INODE_STRUC struct EXT2_INODE_STRUC
@ -147,26 +150,31 @@ struct EXT2_SB_STRUC
log_groups_per_flex db ? ;+372 log_groups_per_flex db ? ;+372
ends ends
struct EXT4_EXTENT_HEADER ;заголовок блока экстентов/индексов struct EXT4_EXTENT_HEADER ;RUS: заголовок блока экстентов/индексов
eh_magic dw ? ;в текущей реализации ext4 должно быть 0xF30A eh_magic dw ? ;RUS: в текущей реализации ext4 должно быть 0xF30A
eh_entries dw ? ;количество экстентов/индексов в блоке eh_entries dw ? ;RUS: количество экстентов/индексов в блоке
eh_max dw ? ;max количество (используется при записи) eh_max dw ? ;RUS: max количество (используется при записи)
eh_depth dw ? ;глубина дерева (0, если это блок экстентов) eh_depth dw ? ;RUS: глубина дерева (0, если это блок экстентов)
eh_generation dd ? ;??? eh_generation dd ? ;???
ends ends
struct EXT4_EXTENT ;экстент struct EXT4_EXTENT ;RUS: экстент ;ENG: extent
ee_block dd ? ;номер ext4 блока ee_block dd ? ;RUS: номер ext4 блока ;ENG: number of ext4 block
ee_len dw ? ;длина экстента ee_len dw ? ;RUS: длина экстента ;ENG: extent length
ee_start_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS) ee_start_hi dw ? ;RUS: старшие 16 бит 48-битного адреса (пока не используются в KOS)
ee_start_lo dd ? ;младшие 32 бита 48-битного адреса ;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 ends
struct EXT4_EXTENT_IDX ;индес - указатель на блок с экстентами/индексами struct EXT4_EXTENT_IDX ;RUS: индекс - указатель на блок с экстентами/индексами
ei_block dd ? ;номер ext4 блока ;ENG: index - pointer to block of extents/indexes
ei_leaf_lo dd ? ;младшие 32 бит 48-битного адреса ei_block dd ? ;RUS: номер ext4 блока ;ENG: number of ext4 block
ei_leaf_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS) ei_leaf_lo dd ? ;RUS: младшие 32 бит 48-битного адреса
ei_unused dw ? ;зарезервировано ;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 ends
ext2_test_superblock: ext2_test_superblock:
@ -230,7 +238,7 @@ ext2_setup:
shl eax, 7 shl eax, 7
mov [ext2_data.count_pointer_in_block], eax 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 shl eax, 2
mov [ext2_data.block_size], eax mov [ext2_data.block_size], eax
@ -294,11 +302,11 @@ ext2_get_block:
;=================================================================== ;===================================================================
;получает номер блока из extent inode ;RUS: получает номер блока из extent inode ;ENG: receives block number from extent inode
;in: ecx = номер блока по порядку ;RUS: in: ecx = номер блока по порядку ;ENG: in: ecx = consecutive block number
; ebp = адрес extent header`а ;RUS: ebp = адрес extent header`а ;ENG: ebp = address of extent header
;out: ecx - адрес очередного блока в случае успеха ;RUS: out: ecx - адрес очередного блока в случае успеха ;ENG: out: ecx - address of next block, if successful
; eax - номер ошибки (если равно 0, то ошибки нет) ;RUS: eax - номер ошибки (если равно 0, то ошибки нет) ;ENG: eax - error number (0 - no error)
ext4_block_recursive_search: ext4_block_recursive_search:
cmp word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC cmp word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
jne .fail jne .fail
@ -369,10 +377,10 @@ ext4_block_recursive_search:
;=================================================================== ;===================================================================
;получает адрес ext2 блока из inode с определнным номером ;получает адрес ext2 блока из inode с определнным номером
;in: ecx = номер блока в inode (0..) ;RUS: in: ecx = номер блока в inode (0..) ;ENG: in: ecx = number of block in inode (0..)
; ebp = адрес inode ;RUS: ebp = адрес inode ;ENG: ebp = inode address
;out: ecx = адрес очередного блока ;RUS: out: ecx = адрес очередного блока ;ENG: out: ecx = next block address
; eax - error code ;RUS: eax - error code ;ENG: eax - error code
ext2_get_inode_block: ext2_get_inode_block:
test [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL test [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
jz @F jz @F
@ -411,7 +419,8 @@ ext2_get_inode_block:
mov eax, ecx mov eax, ecx
div [ext2_data.count_pointer_in_block_square] 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] mov eax, [ebx + eax*4]
call ext2_get_block call ext2_get_block
test eax, eax test eax, eax
@ -450,9 +459,9 @@ ext2_get_inode_block:
mov ebx, [ext2_data.ext2_temp_block] mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block call ext2_get_block
test eax, eax 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 pop ebx
ret ret
@ -481,8 +490,10 @@ ext2_get_inode:
mov edx, 32 mov edx, 32
mul edx ; address block_group in global_desc_table 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] div [ext2_data.block_size]
add eax, [ecx + EXT2_SB_STRUC.first_data_block] add eax, [ecx + EXT2_SB_STRUC.first_data_block]
inc eax inc eax
@ -491,32 +502,32 @@ ext2_get_inode:
test eax, eax test eax, eax
jnz .fail jnz .fail
add ebx, edx ; локальный номер в блоке add ebx, edx ;RUS: локальный номер в блоке ;ENG: local number inside block
mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table]; номер блока - в терминах ext2 mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table] ;RUS: номер блока - в терминах ext2
;ENG: block number - in ext2 terms
mov ecx, [ext2_data.log_block_size] mov ecx, [ext2_data.log_block_size]
shl eax, cl 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 ;RUS: прибавим локальный адрес inode-а ;ENG: add local address of inode
mov esi, eax ;сохраним его пока в esi
; прибавим локальный адрес inode-а
pop eax ; index pop eax ; index
mov ecx, [ext2_data.inode_size] mov ecx, [ext2_data.inode_size]
mul ecx ; (index * inode_size) mul ecx ; (index * inode_size)
mov ebp, 512 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] mov ebx, [ext2_data.ext2_temp_block]
call hd_read call hd_read
cmp [hd_error], 0 cmp [hd_error], 0
jnz .fail jnz .fail
mov esi, edx ;добавим "остаток" mov esi, edx ;RUS: добавим "остаток" ;ENG: add the "remainder"
add esi, ebx ;к адресу add esi, ebx ;RUS: к адресу ;ENG: to the address
rep movsb ;копируем inode rep movsb ;RUS: копируем inode ;ENG: copy inode
xor eax, eax xor eax, eax
.fail: .fail:
mov PUSHAD_EAX, eax mov PUSHAD_EAX, eax
@ -745,7 +756,8 @@ ext2_HdReadFolder:
lea esp, [edi + 32] lea esp, [edi + 32]
xor eax, eax ;зарезервировано: нули в текущей реализации xor eax, eax ;RUS: зарезервировано: нули в текущей реализации
;ENG: reserved: zeros in current implementation
lea edi, [edx + 12] lea edi, [edx + 12]
mov ecx, 20 / 4 mov ecx, 20 / 4
rep stosd rep stosd
@ -760,12 +772,12 @@ ext2_HdReadFolder:
or ebx, -1 or ebx, -1
ret ret
.error_empty_dir: ;inode папки без блоков .error_empty_dir: ;RUS: inode папки без блоков ;ENG: inode of folder without blocks
.error_root: ;root - не папка .error_root: ;RUS: root - не папка ;ENG: root is not a folder
mov eax, ERROR_FS_FAIL mov eax, ERROR_FS_FAIL
jmp .error_ret jmp .error_ret
.error_not_found: ;файл не найден .error_not_found: ;RUS: файл не найден ;ENG: file not found
mov eax, ERROR_FILE_NOT_FOUND mov eax, ERROR_FILE_NOT_FOUND
jmp .error_ret jmp .error_ret
@ -867,9 +879,9 @@ ext2_HdRead:
jz @F jz @F
mov esi, ebx ; esi = pointer to first_wanted mov esi, ebx ; esi = pointer to first_wanted
mov ebx, [esi+4] 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 cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great ja .size_great
jb .size_less jb .size_less
@ -886,23 +898,24 @@ ext2_HdRead:
xor ebx, ebx xor ebx, ebx
xor eax, eax xor eax, eax
.size_great: .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 adc ebx, 0
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great_great ja .size_great_great
jb .size_great_less jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax 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: .size_great_less:
push 1 ;читаем по границе размера push 1 ;RUS: читаем по границе размера ;ENG: reading till the end of file
mov ecx, [ebp + EXT2_INODE_STRUC.i_size] mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;(размер - старт) = сколько читать sub ecx, [esi] ;RUS: (размер - старт) = сколько читать ;ENG: to read = (size - start)
jmp @F jmp @F
.size_great_great: .size_great_great:
push 0 ;читаем столько сколько запросили push 0 ;RUS: читаем столько, сколько запросили ;ENG: reading as much as requested
@@: @@:
;здесь мы точно знаем сколько байт читать - ecx ;здесь мы точно знаем сколько байт читать - ecx
@ -934,7 +947,8 @@ ext2_HdRead:
add ebx, edx add ebx, edx
neg 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 cmp ecx, edx
jbe .only_one_block jbe .only_one_block
@ -943,7 +957,7 @@ ext2_HdRead:
mov ecx, edx mov ecx, edx
mov esi, ebx mov esi, ebx
rep movsb ;кусок 1-го блока rep movsb ;RUS: кусок 1-го блока ;ENG: part of 1st block
jmp .calc_blocks_count jmp .calc_blocks_count
.zero_start: .zero_start:
@ -1031,7 +1045,7 @@ ext2_HdRead:
ext2_test_block_by_name: ext2_test_block_by_name:
sub esp, 256 ;EXT2_filename sub esp, 256 ;EXT2_filename
mov edx, ebx mov edx, ebx
add edx, [ext2_data.block_size] ;запомним конец блока add edx, [ext2_data.block_size] ;RUS: запомним конец блока ;ENG: save block end
.start_rec: .start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0 cmp [ebx + EXT2_DIR_STRUC.inode], 0
@ -1045,7 +1059,7 @@ ext2_test_block_by_name:
mov ecx, edi mov ecx, edi
lea edi, [esp + 4] lea edi, [esp + 4]
sub ecx, edi ;кол-во байт в получившейся строке sub ecx, edi ;RUS: кол-во байт в получившейся строке ;ENG: number of bytes in resulting string
mov esi, [esp] mov esi, [esp]
@@: @@:
@ -1061,19 +1075,19 @@ ext2_test_block_by_name:
call char_toupper call char_toupper
cmp al, ah cmp al, ah
je @B je @B
@@: ;не подошло @@: ;RUS: не подошло ;ENG: didn't fit
pop esi pop esi
.next_rec: .next_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
add ebx, eax ;к след. записи add ebx, eax ;RUS: к след. записи ;ENG: go to next record
cmp ebx, edx ;проверим конец ли cmp ebx, edx ;RUS: проверим конец ли ;ENG: check if this is the end
jb .start_rec jb .start_rec
add esp, 256 add esp, 256
ret ret
.test_find: .test_find:
cmp byte [esi], 0 cmp byte [esi], 0
je .ret ;нашли конец je .ret ;RUS: нашли конец ;ENG: the end reached
cmp byte [esi], '/' cmp byte [esi], '/'
jne @B jne @B
inc esi inc esi
@ -1111,27 +1125,28 @@ ext2_find_lfn:
call ext2_test_block_by_name call ext2_test_block_by_name
pop edi ecx pop edi ecx
cmp edi, esi ;нашли имя? cmp edi, esi ;RUS: нашли имя? ;ENG: did we find a name?
je .next_folder_block ;не нашли -> к след. блоку 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 jz .get_inode_ret
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;нашли, но это не папка cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;RUS: нашли, но это не папка
jne .not_found jne .not_found ;ENG: found, but it's not a folder
mov eax, [ebx + EXT2_DIR_STRUC.inode] 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 call ext2_get_inode
test eax, eax test eax, eax
jnz .error_get_inode jnz .error_get_inode
pop ecx ;в стеке лежит кол-во блоков pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks
mov ebp, ebx mov ebp, ebx
jmp .next_path_part jmp .next_path_part
.next_folder_block: .next_folder_block:
;к следующему блоку в текущей папке ;к следующему блоку в текущей папке
pop eax ;счетчик блоков pop eax ;RUS: счетчик блоков ;ENG: blocks counter
sub eax, [ext2_data.count_block_in_block] sub eax, [ext2_data.count_block_in_block]
jle .not_found jle .not_found
@ -1144,8 +1159,8 @@ ext2_find_lfn:
ret ret
.get_inode_ret: .get_inode_ret:
pop ecx ;в стеке лежит кол-во блоков pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks
mov dl, [ebx + EXT2_DIR_STRUC.name] ;в dl - первый символ () mov dl, [ebx + EXT2_DIR_STRUC.name] ;RUS: в dl - первый символ () ;ENG: ???
mov eax, [ebx + EXT2_DIR_STRUC.inode] mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode call ext2_get_inode
@ -1182,7 +1197,7 @@ ext2_HdGetFileInfo:
ret ret
.is_root: .is_root:
xor ebx, ebx ;root не может быть скрытым xor ebx, ebx ;RUS: root не может быть скрытым ;ENG: root cannot be hidden
mov ebp, [ext2_data.root_inode] mov ebp, [ext2_data.root_inode]
@@: @@:
xor eax, eax xor eax, eax

View File

@ -166,10 +166,8 @@ fat_create_partition:
; FAT size requires knowledge of some calculated values, which are also used ; 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 ; in the normal operation, let's hope for the best and allocate data now; if
; it will prove wrong, just deallocate it. ; it will prove wrong, just deallocate it.
push ebx
movi eax, sizeof.FAT movi eax, sizeof.FAT
call malloc call malloc
pop ebx
test eax, eax test eax, eax
jz .return0 jz .return0
mov ecx, [ebp+8] mov ecx, [ebp+8]
@ -2441,7 +2439,6 @@ fat_SetFileEnd:
pop eax pop eax
lea ebx, [ebp+FAT.buffer] lea ebx, [ebp+FAT.buffer]
call fs_write32_sys call fs_write32_sys
pop edi
test eax, eax test eax, eax
jz @f jz @f
push ERROR_DEVICE push ERROR_DEVICE

View File

@ -525,25 +525,29 @@ fs_NumFloppyServices = ($ - fs_FloppyServices)/4
fs_OnHd0: fs_OnHd0:
call reserve_hd1 call reserve_hd1
mov [hdbase], 0x1F0 mov eax, [hd_address_table]
mov [hdbase], eax ;0x1F0
mov [hdid], 0 mov [hdid], 0
push 1 push 1
jmp fs_OnHd jmp fs_OnHd
fs_OnHd1: fs_OnHd1:
call reserve_hd1 call reserve_hd1
mov [hdbase], 0x1F0 mov eax, [hd_address_table]
mov [hdbase], eax ;0x1F0
mov [hdid], 0x10 mov [hdid], 0x10
push 2 push 2
jmp fs_OnHd jmp fs_OnHd
fs_OnHd2: fs_OnHd2:
call reserve_hd1 call reserve_hd1
mov [hdbase], 0x170 mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0 mov [hdid], 0
push 3 push 3
jmp fs_OnHd jmp fs_OnHd
fs_OnHd3: fs_OnHd3:
call reserve_hd1 call reserve_hd1
mov [hdbase], 0x170 mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10 mov [hdid], 0x10
push 4 push 4
fs_OnHd: fs_OnHd:
@ -932,24 +936,30 @@ biosdisk_enum_root:
pop eax pop eax
inc eax inc eax
ret ret
;-----------------------------------------------------------------------------
process_replace_file_name: process_replace_file_name:
; in
; esi - path with filename(f.70)
;
; out
; ebp - full filename
pushfd
cli
mov ebp, [full_file_name_table] mov ebp, [full_file_name_table]
mov edi, [full_file_name_table.size] xor edi, edi
dec edi
shl edi, 7
add edi, ebp
.loop: .loop:
cmp edi, ebp cmp edi, [full_file_name_table.size]
jb .notfound jae .notfound
push esi edi 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 jz .dest_done
lodsb lodsb
test al, al test al, al
jz .cont jz .cont
or al, 20h or al, 20h ; 32 - space char
scasb scasb
jz @b jz @b
jmp .cont jmp .cont
@ -962,10 +972,12 @@ process_replace_file_name:
jmp .found jmp .found
.cont: .cont:
pop edi esi pop edi esi
sub edi, 128 inc edi
jmp .loop jmp .loop
.found: .found:
pop edi eax pop edi eax
shl edi, 7 ; edi*128
add edi, ebp
mov ebp, esi mov ebp, esi
cmp byte [esi], 0 cmp byte [esi], 0
lea esi, [edi+64] lea esi, [edi+64]
@ -973,7 +985,12 @@ process_replace_file_name:
.notfound: .notfound:
xor ebp, ebp xor ebp, ebp
.ret: .ret:
popfd
ret ret
;-----------------------------------------------------------------------------
uglobal
lock_flag_for_f30_3 rb 1
endg
sys_current_directory: sys_current_directory:
; mov esi, [current_slot] ; mov esi, [current_slot]
@ -988,7 +1005,45 @@ sys_current_directory:
jz .set jz .set
dec ebx dec ebx
jz .get jz .get
dec ebx
jz .mount_additional_directory
ret 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: .get:
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len ; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
; for our code: ebx->buffer,ecx=len ; for our code: ebx->buffer,ecx=len

View File

@ -32,6 +32,17 @@ uglobal
; Parser_params will initialize: sysdir_name = "sys", sysdir_path = <sysdir> ; Parser_params will initialize: sysdir_name = "sys", sysdir_path = <sysdir>
sysdir_name rb 64 sysdir_name rb 64
sysdir_path 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 ? tmp_file_name_table dd ?
endg endg

View File

@ -77,10 +77,10 @@ ext2_data:
.inode_size dd ? .inode_size dd ?
.count_pointer_in_block dd ? ; block_size / 4 .count_pointer_in_block dd ? ; block_size / 4
.count_pointer_in_block_square dd ? ; (block_size / 4)**2 .count_pointer_in_block_square dd ? ; (block_size / 4)**2
.ext2_save_block dd ? ; блок на глобальную 1 процедуру .ext2_save_block dd ? ;RUS: блок на глобальную 1 процедуру ;ENG: block for 1 global procedure
.ext2_temp_block dd ? ; блок для мелких процедур .ext2_temp_block dd ? ;RUS: блок для мелких процедур ;ENG: block for small procedures
.ext2_save_inode dd ? ; inode на глобальную процедуру .ext2_save_inode dd ? ;RUS: inode на глобальную процедуру ;ENG: inode for global procedure
.ext2_temp_inode dd ? ; inode для мелких процедур .ext2_temp_inode dd ? ;RUS: inode для мелких процедур ;ENG: inode for small procedures
.sb dd ? ; superblock .sb dd ? ; superblock
.groups_count dd ? .groups_count dd ?
if $ > fs_dependent_data_end if $ > fs_dependent_data_end

View File

@ -7,8 +7,6 @@
$Revision$ $Revision$
include "lang.inc"
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
align 4 align 4
dtext_asciiz_esi: ; for skins title out dtext_asciiz_esi: ; for skins title out

View File

@ -453,6 +453,9 @@ acpi_dev_data rd 1
acpi_dev_size rd 1 acpi_dev_size rd 1
acpi_rsdt_base 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_madt_base rd 1
acpi_ioapic_base rd 1 acpi_ioapic_base rd 1
@ -464,6 +467,7 @@ ACPI_HI_RSDP_WINDOW_START equ 0x000E0000
ACPI_HI_RSDP_WINDOW_END equ 0x00100000 ACPI_HI_RSDP_WINDOW_END equ 0x00100000
ACPI_RSDP_CHECKSUM_LENGTH equ 20 ACPI_RSDP_CHECKSUM_LENGTH equ 20
ACPI_MADT_SIGN equ 0x43495041 ACPI_MADT_SIGN equ 0x43495041
ACPI_FADT_SIGN equ 0x50434146
acpi_locate: acpi_locate:
@ -535,9 +539,22 @@ check_acpi:
jz .done jz .done
mov ecx, [eax+16] mov ecx, [eax+16]
mov edx, ACPI_MADT_SIGN mov edx, 0x50434146
mov [acpi_rsdt_base-OS_BASE], ecx mov [acpi_rsdt_base-OS_BASE], ecx
call rsdt_find 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 test eax, eax
jz .done jz .done

View File

@ -358,8 +358,44 @@ high_code:
call mutex_init call mutex_init
; SAVE REAL MODE VARIABLES ; 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 ax, [BOOT_VAR + BOOT_IDE_BASE_ADDR]
mov [IDEContrRegsBaseAddr], ax 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 --------------------- ; --------------- APM ---------------------
; init selectors ; init selectors
@ -1014,6 +1050,12 @@ end if
@@: @@:
DEBUGF 1, "K : %d CPU detected\n", eax 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 ; START MULTITASKING
; A 'All set - press ESC to start' messages if need ; A 'All set - press ESC to start' messages if need
@ -1028,6 +1070,17 @@ end if
cmp [IDEContrRegsBaseAddr], 0 cmp [IDEContrRegsBaseAddr], 0
setnz [dma_hdd] 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 mov [timer_ticks_enable], 1 ; for cd driver
sti sti
@ -1585,25 +1638,29 @@ endg
dec ecx dec ecx
jnz noprma jnz noprma
mov [cdbase], 0x1f0 mov eax, [hd_address_table]
mov [cdbase], eax ;0x1f0
mov [cdid], 0xa0 mov [cdid], 0xa0
noprma: noprma:
dec ecx dec ecx
jnz noprsl jnz noprsl
mov [cdbase], 0x1f0 mov eax, [hd_address_table]
mov [cdbase], eax ;0x1f0
mov [cdid], 0xb0 mov [cdid], 0xb0
noprsl: noprsl:
dec ecx dec ecx
jnz nosema jnz nosema
mov [cdbase], 0x170 mov eax, [hd_address_table+16]
mov [cdbase], eax ;0x170
mov [cdid], 0xa0 mov [cdid], 0xa0
nosema: nosema:
dec ecx dec ecx
jnz nosesl jnz nosesl
mov [cdbase], 0x170 mov eax, [hd_address_table+16]
mov [cdbase], eax ;0x170
mov [cdid], 0xb0 mov [cdid], 0xb0
nosesl: nosesl:
ret ret
iglobal iglobal
@ -1630,7 +1687,8 @@ endg
cmp ecx, 1 cmp ecx, 1
jnz noprmahd jnz noprmahd
mov [hdbase], 0x1f0 mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
and dword [hdid], 0x0 and dword [hdid], 0x0
mov dword [hdpos], ecx mov dword [hdpos], ecx
; call set_FAT32_variables ; call set_FAT32_variables
@ -1638,7 +1696,8 @@ endg
cmp ecx, 2 cmp ecx, 2
jnz noprslhd jnz noprslhd
mov [hdbase], 0x1f0 mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x10 mov [hdid], 0x10
mov dword [hdpos], ecx mov dword [hdpos], ecx
; call set_FAT32_variables ; call set_FAT32_variables
@ -1646,7 +1705,8 @@ endg
cmp ecx, 3 cmp ecx, 3
jnz nosemahd jnz nosemahd
mov [hdbase], 0x170 mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
and dword [hdid], 0x0 and dword [hdid], 0x0
mov dword [hdpos], ecx mov dword [hdpos], ecx
; call set_FAT32_variables ; call set_FAT32_variables
@ -1654,7 +1714,8 @@ endg
cmp ecx, 4 cmp ecx, 4
jnz noseslhd jnz noseslhd
mov [hdbase], 0x170 mov eax,[hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10 mov [hdid], 0x10
mov dword [hdpos], ecx mov dword [hdpos], ecx
; call set_FAT32_variables ; call set_FAT32_variables
@ -5409,7 +5470,6 @@ calculate_fast_getting_offset_for_WinMapAddress:
; calculate data area for fast getting offset to _WinMapAddress ; calculate data area for fast getting offset to _WinMapAddress
xor eax, eax xor eax, eax
mov ecx, [_display.height] mov ecx, [_display.height]
inc ecx
mov edi, d_width_calc_area mov edi, d_width_calc_area
cld cld
@@: @@:
@ -5424,7 +5484,6 @@ calculate_fast_getting_offset_for_LFB:
; calculate data area for fast getting offset to LFB ; calculate data area for fast getting offset to LFB
xor eax, eax xor eax, eax
mov ecx, [_display.height] mov ecx, [_display.height]
inc ecx
mov edi, BPSLine_calc_area mov edi, BPSLine_calc_area
cld cld
@@: @@:
@ -5816,7 +5875,6 @@ include "data32.inc"
__REV__ = __REV __REV__ = __REV
uglobals_size = $ - endofcode
if ~ lang eq sp if ~ lang eq sp
diff16 "end of kernel code",0,$ diff16 "end of kernel code",0,$
end if end if

View File

@ -55,9 +55,8 @@ struct ARP_header
ends ends
align 4
uglobal uglobal
align 4
ARP_table rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry) ARP_table rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry)
@ -83,7 +82,7 @@ macro ARP_init {
xor eax, eax xor eax, eax
mov edi, ARP_entries_num mov edi, ARP_entries_num
mov ecx, 4*NET_DEVICES_MAX mov ecx, 4*NET_DEVICES_MAX
rep stosd rep stosd
} }
@ -176,13 +175,13 @@ ARP_input:
cmp ecx, sizeof.ARP_header cmp ecx, sizeof.ARP_header
jb .exit jb .exit
call NET_ptr_to_num call NET_ptr_to_num4
cmp edi, -1 cmp edi, -1
jz .exit 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]:1, [edx + ARP_header.SenderIP + 1]:1,\
[edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi [edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi
@ -190,7 +189,7 @@ ARP_input:
; First, check for IP collision ; First, check for IP collision
mov eax, [edx + ARP_header.SenderIP] mov eax, [edx + ARP_header.SenderIP]
cmp eax, [IP_LIST + 4*edi] cmp eax, [IP_LIST + edi]
je .collision je .collision
;--------------------- ;---------------------
@ -201,12 +200,12 @@ ARP_input:
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n" 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 test ecx, ecx
jz .exit jz .exit
mov esi, (ARP_TABLE_SIZE * sizeof.ARP_entry) mov esi, edi
imul esi, edi imul esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
add esi, ARP_table add esi, ARP_table
.loop: .loop:
cmp [esi + ARP_entry.IP], eax cmp [esi + ARP_entry.IP], eax
@ -245,7 +244,7 @@ ARP_input:
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: its a request\n" 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? cmp eax, [edx + ARP_header.TargetIP] ; Is it looking for my IP address?
jne .exit jne .exit
@ -262,7 +261,7 @@ ARP_input:
movsd ; Move sender IP to Dest IP movsd ; Move sender IP to Dest IP
pop esi pop esi
mov esi, [NET_DRV_LIST + 4*esi] mov esi, [NET_DRV_LIST + esi]
lea esi, [esi + ETH_DEVICE.mac] lea esi, [esi + ETH_DEVICE.mac]
lea edi, [edx + ARP_header.SenderMAC] lea edi, [edx + ARP_header.SenderMAC]
movsd ; Copy MAC address from in MAC_LIST movsd ; Copy MAC address from in MAC_LIST
@ -290,7 +289,7 @@ ARP_input:
ret ret
.collision: .collision:
inc [ARP_CONFLICTS + 4*edi] inc [ARP_CONFLICTS + edi]
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n"
.exit: .exit:
@ -337,11 +336,11 @@ ARP_output_request:
movsw ; movsw ;
movsd ; movsd ;
; mov esi, [ebx + NET_DEVICE.number] push edi
xor esi, esi ;;;; FIXME call NET_ptr_to_num4
inc esi ;;;;;;;;; inc [ARP_PACKETS_TX + edi] ; assume we will succeed
inc [ARP_PACKETS_TX + 4*esi] ; assume we will succeed lea esi, [IP_LIST + edi] ; SenderIP
lea esi, [IP_LIST + 4*esi] ; SenderIP pop edi
movsd movsd
mov esi, ETH_BROADCAST ; DestMac mov esi, ETH_BROADCAST ; DestMac
@ -364,7 +363,7 @@ ARP_output_request:
; ARP_add_entry (or update) ; ARP_add_entry (or update)
; ;
; IN: esi = ptr to entry (can easily be made on the stack) ; 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 ; OUT: eax = entry #, -1 on error
; esi = ptr to newly created entry ; esi = ptr to newly created entry
; ;
@ -374,17 +373,17 @@ ARP_add_entry:
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_add_entry: device=%u\n", edi 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 ? cmp ecx, ARP_TABLE_SIZE ; list full ?
jae .full jae .full
; From this point on, we can only fail if IP has a static entry, or if table is corrupt. ; 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 push edi
xor ecx, ecx xor ecx, ecx
imul edi, ARP_TABLE_SIZE*sizeof.ARP_entry imul edi, ARP_TABLE_SIZE*sizeof.ARP_entry/4
add edi, ARP_table add edi, ARP_table
mov eax, [esi + ARP_entry.IP] mov eax, [esi + ARP_entry.IP]
.loop: .loop:
@ -409,7 +408,7 @@ ARP_add_entry:
.add: .add:
push ecx push ecx
mov ecx, sizeof.ARP_entry/2 mov ecx, sizeof.ARP_entry/2
rep movsw rep movsw
pop ecx pop ecx
lea esi, [edi - sizeof.ARP_entry] lea esi, [edi - sizeof.ARP_entry]
pop edi pop edi
@ -419,7 +418,7 @@ ARP_add_entry:
.error: .error:
pop edi pop edi
dec [ARP_entries_num + 4*edi] dec [ARP_entries_num + edi]
DEBUGF DEBUG_NETWORK_ERROR, "ARP_add_entry_failed\n" DEBUGF DEBUG_NETWORK_ERROR, "ARP_add_entry_failed\n"
.full: .full:
mov eax, -1 mov eax, -1
@ -451,12 +450,12 @@ ARP_del_entry:
; move all trailing entries, sizeof.ARP_entry bytes to left. ; move all trailing entries, sizeof.ARP_entry bytes to left.
mov edi, esi mov edi, esi
add esi, sizeof.ARP_entry add esi, sizeof.ARP_entry
rep movsw rep movsw
; now add an empty entry to the end (erasing previous one) ; now add an empty entry to the end (erasing previous one)
xor eax, eax xor eax, eax
mov ecx, sizeof.ARP_entry/2 mov ecx, sizeof.ARP_entry/2
rep stosw rep stosw
pop edi pop edi
dec [ARP_entries_num + 4*edi] dec [ARP_entries_num + 4*edi]
@ -475,7 +474,7 @@ ARP_del_entry:
; This function translates an IP address to a MAC address ; This function translates an IP address to a MAC address
; ;
; IN: eax = IPv4 address ; IN: eax = IPv4 address
; edi = device number ; edi = device number * 4
; OUT: eax = -1 on error, -2 means request send ; OUT: eax = -1 on error, -2 means request send
; else, ax = first two bytes of mac (high 16 bits of eax will be 0) ; else, ax = first two bytes of mac (high 16 bits of eax will be 0)
; ebx = last four bytes of mac ; ebx = last four bytes of mac
@ -487,7 +486,7 @@ ARP_IP_to_MAC:
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah
rol eax, 16 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 rol eax, 16
cmp eax, 0xffffffff cmp eax, 0xffffffff
@ -496,11 +495,11 @@ ARP_IP_to_MAC:
;-------------------------------- ;--------------------------------
; Try to find the IP in ARP_table ; Try to find the IP in ARP_table
mov ecx, [ARP_entries_num + 4*edi] mov ecx, [ARP_entries_num + edi]
test ecx, ecx test ecx, ecx
jz .not_in_list jz .not_in_list
mov esi, edi 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 add esi, ARP_table + ARP_entry.IP
.scan_loop: .scan_loop:
cmp [esi], eax cmp [esi], eax
@ -538,7 +537,7 @@ ARP_IP_to_MAC:
pop edi eax ; IP in eax, device number in ebx, for ARP_output_request pop edi eax ; IP in eax, device number in ebx, for ARP_output_request
push esi edi push esi edi
mov ebx, [NET_DRV_LIST + 4*edi] mov ebx, [NET_DRV_LIST + edi]
call ARP_output_request call ARP_output_request
pop edi esi pop edi esi
.found_it: .found_it:
@ -647,7 +646,7 @@ ARP_api:
imul ecx, sizeof.ARP_entry imul ecx, sizeof.ARP_entry
lea esi, [eax + ecx] lea esi, [eax + ecx]
mov ecx, sizeof.ARP_entry/2 mov ecx, sizeof.ARP_entry/2
rep movsw rep movsw
xor eax, eax xor eax, eax
ret ret
@ -655,7 +654,6 @@ ARP_api:
.write: .write:
; esi = pointer to buffer ; esi = pointer to buffer
mov edi, eax mov edi, eax
shr edi, 2
call ARP_add_entry ; out: eax = entry number, -1 on error call ARP_add_entry ; out: eax = entry number, -1 on error
ret ret

View File

@ -55,8 +55,8 @@ struct FRAGMENT_entry ; This structure will replace the ethern
ends ends
align 4
uglobal uglobal
align 4
IP_LIST rd NET_DEVICES_MAX IP_LIST rd NET_DEVICES_MAX
SUBNET_LIST rd NET_DEVICES_MAX SUBNET_LIST rd NET_DEVICES_MAX
@ -69,6 +69,7 @@ uglobal
IP_packets_dumped rd NET_DEVICES_MAX IP_packets_dumped rd NET_DEVICES_MAX
FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot
endg endg
@ -84,7 +85,7 @@ macro IPv4_init {
xor eax, eax xor eax, eax
mov edi, IP_LIST mov edi, IP_LIST
mov ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4 mov ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4
rep stosd rep stosd
} }
@ -223,8 +224,7 @@ IPv4_input: ; TODO: add IPv4
;----------------------------------- ;-----------------------------------
; Check if destination IP is correct ; Check if destination IP is correct
call NET_ptr_to_num call NET_ptr_to_num4
shl edi, 2
; check if it matches local ip (Using RFC1122 strong end system model) ; check if it matches local ip (Using RFC1122 strong end system model)
@ -476,10 +476,10 @@ IPv4_input: ; TODO: add IPv4
push cx ; First copy dword-wise, then byte-wise push cx ; First copy dword-wise, then byte-wise
shr cx, 2 ; shr cx, 2 ;
rep movsd ; rep movsd ;
pop cx ; pop cx ;
and cx, 3 ; and cx, 3 ;
rep movsb ; rep movsb ;
push eax push eax
push edx ; Push pointer to fragment onto stack push edx ; Push pointer to fragment onto stack
@ -586,9 +586,9 @@ IPv4_output:
push ebx ; push the mac onto the stack push ebx ; push the mac onto the stack
push ax 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] lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp mov edx, esp
mov ecx, [esp + 10 + 6] mov ecx, [esp + 10 + 6]
@ -696,7 +696,7 @@ IPv4_output_raw:
;; todo: check socket options if we should add header, or just compute checksum ;; todo: check socket options if we should add header, or just compute checksum
push edi ecx push edi ecx
rep movsb rep movsb
pop ecx edi pop ecx edi
; [edi + IPv4_header.VersionAndIHL] ; IPv4, normal length (no Optional header) ; [edi + IPv4_header.VersionAndIHL] ; IPv4, normal length (no Optional header)
@ -786,7 +786,7 @@ IPv4_fragment:
; copy header ; copy header
mov esi, [esp + 2*4] mov esi, [esp + 2*4]
mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header!
rep movsd rep movsd
; copy data ; copy data
mov esi, [esp + 2*4] mov esi, [esp + 2*4]
@ -795,7 +795,7 @@ IPv4_fragment:
mov ecx, [esp + 1*4] mov ecx, [esp + 1*4]
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment: copying %u bytes\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment: copying %u bytes\n", ecx
rep movsb rep movsb
; now, correct header ; now, correct header
mov ecx, [esp + 1*4] mov ecx, [esp + 1*4]
@ -823,7 +823,7 @@ IPv4_fragment:
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
mov ecx, [esp+4] mov ecx, [esp+4]
add [esp], ecx add [esp], ecx
mov ecx, [esp+3*4+6+4] ; ptr to begin of buff mov ecx, [esp+3*4+6+4] ; ptr to begin of buff
@ -857,7 +857,7 @@ IPv4_fragment:
; IPv4_route ; IPv4_route
; ;
; IN: eax = Destination IP ; IN: eax = Destination IP
; OUT: edi = device number ; OUT: edi = device number*4
; eax = ip of gateway if nescessary, unchanged otherwise ; eax = ip of gateway if nescessary, unchanged otherwise
; ;
;--------------------------------------------------------------------------- ;---------------------------------------------------------------------------
@ -890,8 +890,7 @@ IPv4_route:
.invalid: .invalid:
mov eax, [GATEWAY_LIST+4] ;;; FIXME mov eax, [GATEWAY_LIST+4] ;;; FIXME
.broadcast: .broadcast:
xor edi, edi ; if none found, use device 1 as default ;;;; FIXME mov edi, 4 ; if none found, use device 1 as default ;;;; FIXME
inc di
ret ret

View File

@ -30,8 +30,8 @@ struct IPv6_header
ends ends
align 4
uglobal uglobal
align 4
IPv6: IPv6:
.addresses rd 4*NET_DEVICES_MAX .addresses rd 4*NET_DEVICES_MAX
@ -57,7 +57,7 @@ macro IPv6_init {
xor eax, eax xor eax, eax
mov edi, IPv6 mov edi, IPv6
mov ecx, (4*4*4+2*4)MAX_IP mov ecx, (4*4*4+2*4)MAX_IP
rep stosd rep stosd
} }

View File

@ -23,8 +23,11 @@ struct PPPoE_frame
ends ends
uglobal uglobal
align 4
PPPoE_SID dw ? PPPoE_SID dw ?
PPPoE_MAC dp ? PPPoE_MAC dp ?
endg endg
;----------------------------------------------------------------- ;-----------------------------------------------------------------
@ -63,6 +66,11 @@ PPPoE_discovery_input:
; First, find open PPPoE socket ; First, find open PPPoE socket
pusha
mov ecx, socket_mutex
call mutex_lock
popa
mov eax, net_sockets mov eax, net_sockets
.next_socket: .next_socket:
@ -76,6 +84,11 @@ PPPoE_discovery_input:
cmp [eax + SOCKET.Protocol], PPP_PROTO_ETHERNET cmp [eax + SOCKET.Protocol], PPP_PROTO_ETHERNET
jne .next_socket jne .next_socket
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
; Now, send it to the this socket ; Now, send it to the this socket
mov ecx, [esp + 4] mov ecx, [esp + 4]
@ -84,6 +97,11 @@ PPPoE_discovery_input:
jmp SOCKET_input jmp SOCKET_input
.dump: .dump:
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n' DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n'
call kernel_free call kernel_free
add esp, 4 add esp, 4
@ -134,7 +152,7 @@ PPPoE_discovery_output:
mov edx, ecx mov edx, ecx
mov edi, eax mov edi, eax
rep movsb rep movsb
cmp edx, 60 ; Min ETH size cmp edx, 60 ; Min ETH size
ja @f ja @f

View File

@ -32,8 +32,8 @@ struct ETH_DEVICE NET_DEVICE
ends ends
align 4
iglobal iglobal
align 4
ETH_BROADCAST dp 0xffffffffffff ETH_BROADCAST dp 0xffffffffffff
endg endg
@ -57,9 +57,8 @@ ETH_input:
mov ecx, [esp+4] mov ecx, [esp+4]
DEBUGF DEBUG_NETWORK_VERBOSE,"ETH_input: size=%u\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE,"ETH_input: size=%u\n", ecx
cmp ecx, ETH_FRAME_MINIMUM
jb .dump
sub ecx, sizeof.ETH_header sub ecx, sizeof.ETH_header
jb .dump
lea edx, [eax + sizeof.ETH_header] lea edx, [eax + sizeof.ETH_header]
mov ax, [eax + ETH_header.Type] mov ax, [eax + ETH_header.Type]

View File

@ -97,10 +97,12 @@ struct ICMP_header
ends ends
align 4
uglobal uglobal
align 4
ICMP_PACKETS_TX rd NET_DEVICES_MAX ICMP_PACKETS_TX rd NET_DEVICES_MAX
ICMP_PACKETS_RX rd NET_DEVICES_MAX ICMP_PACKETS_RX rd NET_DEVICES_MAX
endg endg
@ -116,7 +118,7 @@ macro ICMP_init {
xor eax, eax xor eax, eax
mov edi, ICMP_PACKETS_TX mov edi, ICMP_PACKETS_TX
mov ecx, 2*NET_DEVICES_MAX mov ecx, 2*NET_DEVICES_MAX
rep stosd rep stosd
} }
@ -156,9 +158,17 @@ ICMP_input:
pop ecx edx pop ecx edx
jne .checksum_mismatch jne .checksum_mismatch
; Check packet type
cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request? cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets 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 ; We well re-use the packet so we can create the response as fast as possible
; Notice: this only works on pure ethernet ; Notice: this only works on pure ethernet
@ -166,14 +176,6 @@ ICMP_input:
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
mov esi, [esp] ; Start of buffer 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 cmp ebx, LOOPBACK_DEVICE
je .loopback je .loopback
@ -225,6 +227,11 @@ ICMP_input:
; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!) ; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [UDP_PACKETS_TX + edi]
@@:
ret ret
@ -233,6 +240,11 @@ ICMP_input:
.check_sockets: .check_sockets:
; Look for an open ICMP socket ; Look for an open ICMP socket
pusha
mov ecx, socket_mutex
call mutex_lock
popa
mov esi, [edi] ; ipv4 source address mov esi, [edi] ; ipv4 source address
mov eax, net_sockets mov eax, net_sockets
.try_more: .try_more:
@ -240,7 +252,7 @@ ICMP_input:
.next_socket: .next_socket:
mov eax, [eax + SOCKET.NextPtr] mov eax, [eax + SOCKET.NextPtr]
or eax, eax or eax, eax
jz .dump jz .dump_
cmp [eax + SOCKET.Domain], AF_INET4 cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket jne .next_socket
@ -254,10 +266,16 @@ ICMP_input:
; cmp [eax + ICMP_SOCKET.Identifier], ; cmp [eax + ICMP_SOCKET.Identifier],
; jne .next_socket ; jne .next_socket
; call IPv4_dest_to_dev ; Update stats (and validate device ptr)
; cmp edi,-1 call NET_ptr_to_num4
; je .dump cmp edi, -1
; inc [ICMP_PACKETS_RX+edi] je .dump_
inc [ICMP_PACKETS_RX + edi]
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
DEBUGF DEBUG_NETWORK_VERBOSE, "socket=%x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "socket=%x\n", eax
@ -269,6 +287,16 @@ ICMP_input:
mov esi, edx mov esi, edx
jmp SOCKET_input 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: .checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n" DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n"
@ -327,15 +355,20 @@ ICMP_output:
add edi, sizeof.ICMP_header add edi, sizeof.ICMP_header
push cx push cx
shr cx, 2 shr cx, 2
rep movsd rep movsd
pop cx pop cx
and cx, 3 and cx, 3
rep movsb rep movsb
sub edi, edx ;;; TODO: find a better way to remember start of packet sub edi, edx ;;; TODO: find a better way to remember start of packet
push edx edi push edx edi
DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n" DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret ret
.exit: .exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n" DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
@ -373,7 +406,7 @@ ICMP_output_raw:
push edi ecx push edi ecx
DEBUGF DEBUG_NETWORK_VERBOSE, "copying %u bytes from %x to %x\n", ecx, esi, edi DEBUGF DEBUG_NETWORK_VERBOSE, "copying %u bytes from %x to %x\n", ecx, esi, edi
rep movsb rep movsb
pop ecx edi pop ecx edi
mov [edi + ICMP_header.Checksum], 0 mov [edi + ICMP_header.Checksum], 0
@ -386,6 +419,11 @@ ICMP_output_raw:
DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n" DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret ret
.exit: .exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n" DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"

View File

@ -17,6 +17,7 @@
$Revision: 2891 $ $Revision: 2891 $
iglobal iglobal
align 4
LOOPBACK_DEVICE: LOOPBACK_DEVICE:
@ -39,7 +40,7 @@ LOOPBACK_DEVICE:
.namestr db 'loopback', 0 .namestr db 'loopback', 0
.dummy_fn: .dummy_fn:
ret ret
endg endg

View File

@ -23,11 +23,12 @@ $Revision$
; (you can see some examples below) ; (you can see some examples below)
struct queue struct queue
size dd ? ; number of queued packets in this queue size dd ? ; number of queued packets in this queue
w_ptr dd ? ; current writing pointer in queue w_ptr dd ? ; current writing pointer in queue
r_ptr dd ? ; current reading pointer r_ptr dd ? ; current reading pointer
mutex MUTEX
ends ends
@ -44,23 +45,41 @@ ends
macro add_to_queue ptr, size, entry_size, failaddr { macro add_to_queue ptr, size, entry_size, failaddr {
cmp [ptr + queue.size], size ; Check if queue isnt full local .ok, .no_wrap
jae failaddr
inc [ptr + queue.size] ; if not full, queue one more pusha
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
mov edi, [ptr + queue.w_ptr] ; Current write pointer (FIFO!) cmp [ptr + queue.size], size ; Check if queue isnt full
mov ecx, entry_size/4 ; Write the queue entry jb .ok
rep movsd ;
lea ecx, [size*entry_size+ptr+sizeof.queue] pusha
cmp edi, ecx ; entry size lea ecx, [ptr + queue.mutex]
jb .no_wrap call mutex_unlock
popa
jmp failaddr
sub edi, size*entry_size .ok:
inc [ptr + queue.size] ; if not full, queue one more
mov edi, [ptr + queue.w_ptr] ; Current write pointer (FIFO!)
mov ecx, entry_size/4 ; Write the queue entry
rep movsd ;
lea ecx, [size*entry_size+ptr+sizeof.queue]
cmp edi, ecx ; entry size
jb .no_wrap
sub edi, size*entry_size
.no_wrap: .no_wrap:
mov [ptr + queue.w_ptr], edi mov [ptr + queue.w_ptr], edi
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
} }
@ -68,33 +87,55 @@ macro add_to_queue ptr, size, entry_size, failaddr {
macro get_from_queue ptr, size, entry_size, failaddr { macro get_from_queue ptr, size, entry_size, failaddr {
cmp [ptr + queue.size], 0 ; any packets queued? local .ok, .no_wrap
je failaddr
dec [ptr + queue.size] ; if so, dequeue one pusha
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
mov esi, [ptr + queue.r_ptr] cmp [ptr + queue.size], 0 ; any packets queued?
push esi ja .ok
add esi, entry_size pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr
lea ecx, [size*entry_size+ptr+sizeof.queue] .ok:
cmp esi, ecx ; entry size dec [ptr + queue.size] ; if so, dequeue one
jb .no_wrap
sub esi, size*entry_size mov esi, [ptr + queue.r_ptr]
push esi
add esi, entry_size
lea ecx, [size*entry_size+ptr+sizeof.queue]
cmp esi, ecx ; entry size
jb .no_wrap
sub esi, size*entry_size
.no_wrap: .no_wrap:
mov dword [ptr + queue.r_ptr], esi mov dword [ptr + queue.r_ptr], esi
pop esi pop esi
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
} }
macro init_queue ptr { macro init_queue ptr {
mov [ptr + queue.size] , 0 mov [ptr + queue.size] , 0
lea edi, [ptr + sizeof.queue] lea edi, [ptr + sizeof.queue]
mov [ptr + queue.w_ptr], edi mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi mov [ptr + queue.r_ptr], edi
lea ecx, [ptr + queue.mutex]
call mutex_init
} }

File diff suppressed because it is too large Load Diff

View File

@ -81,7 +81,6 @@ SO_REUSEPORT = 1 shl 7
SO_USELOOPBACK = 1 shl 8 SO_USELOOPBACK = 1 shl 8
SO_BINDTODEVICE = 1 shl 9 SO_BINDTODEVICE = 1 shl 9
SO_BLOCK = 1 shl 10 ; TO BE REMOVED
SO_NONBLOCK = 1 shl 31 SO_NONBLOCK = 1 shl 31
; Socket flags for user calls ; Socket flags for user calls
@ -104,9 +103,9 @@ SS_ISABORTING = 0x0080 ; aborting fd references - close()
SS_RESTARTSYS = 0x0100 ; restart blocked system calls SS_RESTARTSYS = 0x0100 ; restart blocked system calls
SS_ISDISCONNECTED = 0x0800 ; socket disconnected from peer SS_ISDISCONNECTED = 0x0800 ; socket disconnected from peer
SS_ASYNC = 0x0100 ; async i/o notify SS_ASYNC = 0x1000 ; async i/o notify
SS_ISCONFIRMING = 0x0200 ; deciding to accept connection req SS_ISCONFIRMING = 0x2000 ; deciding to accept connection req
SS_MORETOCOME = 0x0400 SS_MORETOCOME = 0x4000
SS_BLOCKED = 0x8000 SS_BLOCKED = 0x8000
@ -115,7 +114,15 @@ SOCKET_MAXDATA = 4096*32 ; must be 4096*(power of 2) where 'power
MAX_backlog = 20 ; maximum backlog for stream sockets MAX_backlog = 20 ; maximum backlog for stream sockets
; Error Codes ; Error Codes
ENOBUFS = 55 ENOBUFS = 1
EOPNOTSUPP = 4
EWOULDBLOCK = 6
ENOTCONN = 9
EALREADY = 10
EINVAL = 11
EMSGSIZE = 12
ENOMEM = 18
EADDRINUSE = 20
ECONNREFUSED = 61 ECONNREFUSED = 61
ECONNRESET = 52 ECONNRESET = 52
ETIMEDOUT = 60 ETIMEDOUT = 60
@ -213,8 +220,8 @@ include "socket.inc"
align 4
uglobal uglobal
align 4
NET_RUNNING dd ? NET_RUNNING dd ?
NET_DRV_LIST rd NET_DEVICES_MAX NET_DRV_LIST rd NET_DEVICES_MAX
@ -239,7 +246,7 @@ stack_init:
xor eax, eax xor eax, eax
mov edi, NET_RUNNING mov edi, NET_RUNNING
mov ecx, (NET_DEVICES_MAX + 2) mov ecx, (NET_DEVICES_MAX + 2)
rep stosd rep stosd
PPPoE_init PPPoE_init
@ -264,8 +271,8 @@ stack_init:
; Wakeup every tick. ; Wakeup every tick.
proc stack_handler_has_work? proc stack_handler_has_work?
mov eax, [timer_ticks] mov eax, [timer_ticks]
cmp eax, [net_10ms] cmp eax, [net_10ms]
ret ret
endp endp
@ -359,7 +366,7 @@ NET_add_device:
mov ecx, NET_DEVICES_MAX ; We need to check whole list because a device may be removed without re-organizing list mov ecx, NET_DEVICES_MAX ; We need to check whole list because a device may be removed without re-organizing list
mov edi, NET_DRV_LIST mov edi, NET_DRV_LIST
repne scasd ; See if device is already in the list repne scasd ; See if device is already in the list
jz .error jz .error
;---------------------------- ;----------------------------
@ -368,7 +375,7 @@ NET_add_device:
mov ecx, NET_DEVICES_MAX mov ecx, NET_DEVICES_MAX
mov edi, NET_DRV_LIST mov edi, NET_DRV_LIST
repne scasd repne scasd
jnz .error jnz .error
sub edi, 4 sub edi, 4
@ -419,7 +426,7 @@ NET_remove_device:
mov ecx, NET_DEVICES_MAX mov ecx, NET_DEVICES_MAX
mov edi, NET_DRV_LIST mov edi, NET_DRV_LIST
repne scasd repne scasd
jnz .error jnz .error
;------------------------ ;------------------------
@ -450,29 +457,33 @@ NET_remove_device:
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
NET_ptr_to_num: 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 push ecx
mov ecx, NET_DEVICES_MAX mov ecx, NET_DEVICES_MAX
mov edi, NET_DRV_LIST mov edi, NET_DRV_LIST
.loop: .loop:
cmp ebx, [edi] cmp ebx, [edi]
jz .found je .found
add edi, 4 add edi, 4
dec ecx dec ecx
jnz .loop jnz .loop
; repnz scasd could work too if eax is used instead of ebx!
or edi, -1 or edi, -1
pop ecx pop ecx
ret ret
.found: .found:
sub edi, NET_DRV_LIST sub edi, NET_DRV_LIST
shr edi, 2
pop ecx pop ecx
ret ret
@ -652,7 +663,7 @@ sys_network:
mov edi, ecx mov edi, ecx
mov ecx, 64/4 ; max length mov ecx, 64/4 ; max length
rep movsd rep movsd
xor eax, eax xor eax, eax
mov [esp+32], eax mov [esp+32], eax

View File

@ -127,8 +127,9 @@ struct TCP_queue_entry
ends ends
align 4
uglobal uglobal
align 4
TCP_segments_tx rd NET_DEVICES_MAX TCP_segments_tx rd NET_DEVICES_MAX
TCP_segments_rx rd NET_DEVICES_MAX TCP_segments_rx rd NET_DEVICES_MAX
TCP_segments_missed rd NET_DEVICES_MAX TCP_segments_missed rd NET_DEVICES_MAX
@ -136,7 +137,7 @@ uglobal
; TCP_bytes_rx rq NET_DEVICES_MAX ; TCP_bytes_rx rq NET_DEVICES_MAX
; TCP_bytes_tx rq NET_DEVICES_MAX ; TCP_bytes_tx rq NET_DEVICES_MAX
TCP_sequence_num dd ? 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 ? TCP_input_event dd ?
endg endg
@ -153,7 +154,7 @@ macro TCP_init {
xor eax, eax xor eax, eax
mov edi, TCP_segments_tx mov edi, TCP_segments_tx
mov ecx, (6*NET_DEVICES_MAX) mov ecx, (6*NET_DEVICES_MAX)
rep stosd rep stosd
pseudo_random eax pseudo_random eax
mov [TCP_sequence_num], eax mov [TCP_sequence_num], eax
@ -163,6 +164,10 @@ macro TCP_init {
movi ebx, 1 movi ebx, 1
mov ecx, TCP_process_input mov ecx, TCP_process_input
call new_sys_threads call new_sys_threads
test eax, eax
jns @f
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP, error %d\n', eax
@@:
} }

View File

@ -50,6 +50,9 @@ TCP_input:
add esp, sizeof.TCP_queue_entry add esp, sizeof.TCP_queue_entry
call NET_ptr_to_num4
inc [TCP_segments_rx + edi]
xor edx, edx xor edx, edx
mov eax, [TCP_input_event] mov eax, [TCP_input_event]
mov ebx, [eax + EVENT.id] mov ebx, [eax + EVENT.id]
@ -62,7 +65,8 @@ TCP_input:
popf popf
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n" 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 add esp, sizeof.TCP_queue_entry - 8
call kernel_free call kernel_free
@ -146,13 +150,18 @@ TCP_process_input:
; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0) ; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0)
.findpcb: .findpcb:
pusha
mov ecx, socket_mutex
call mutex_lock
popa
mov ebx, net_sockets mov ebx, net_sockets
mov si, [edx + TCP_header.DestinationPort] mov si, [edx + TCP_header.DestinationPort]
.socket_loop: .socket_loop:
mov ebx, [ebx + SOCKET.NextPtr] mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx or ebx, ebx
jz .respond_seg_reset jz .no_socket ;respond_seg_reset
cmp [ebx + SOCKET.Domain], AF_INET4 cmp [ebx + SOCKET.Domain], AF_INET4
jne .socket_loop jne .socket_loop
@ -176,13 +185,13 @@ TCP_process_input:
test ax, ax test ax, ax
jnz .socket_loop jnz .socket_loop
.found_socket: ; ebx now contains the socketpointer .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 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 ; Check if socket isnt closed
@ -907,7 +916,7 @@ TCP_process_input:
mov ecx, [esp] mov ecx, [esp]
add ecx, SOCKET.mutex add ecx, SOCKET.mutex
call mutex_lock call mutex_lock
pop ebx pop ebx
; Continue processing ; Continue processing
xor edx, edx xor edx, edx
@ -1161,9 +1170,17 @@ TCP_process_input:
.ack_la: .ack_la:
jnc .ack_processed jnc .ack_processed
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop ebx
push ebx
mov eax, ebx mov eax, ebx
call TCP_disconnect call TCP_disconnect
jmp .drop pop ebx
jmp .destroy_new_socket
.ack_tw: .ack_tw:
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
@ -1223,7 +1240,10 @@ align 4
and [ebx + TCP_SOCKET.temp_bits], not TCP_BIT_DROPSOCKET 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 jmp .trim_then_step6
@ -1298,7 +1318,10 @@ align 4
;;; TODO: update stats ;;; TODO: update stats
; set socket state to connected ; 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 mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
; Do window scaling on this connection ? ; Do window scaling on this connection ?
@ -1620,6 +1643,13 @@ align 4
pop ebx pop ebx
jmp .destroy_new_socket jmp .destroy_new_socket
.no_socket:
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
.respond_seg_reset: .respond_seg_reset:
test [edx + TCP_header.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jnz .drop_no_socket jnz .drop_no_socket

View File

@ -35,6 +35,8 @@ TCP_output:
call mutex_lock call mutex_lock
pop eax 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 ; 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 ; If there is some data, or any critical controls to send (SYN / RST), then transmit
; Otherwise, investigate further ; Otherwise, investigate further
@ -216,6 +218,7 @@ TCP_output:
mov ebx, TCP_max_win mov ebx, TCP_max_win
shl ebx, cl shl ebx, cl
pop ecx pop ecx
cmp ebx, ecx cmp ebx, ecx
jb @f jb @f
mov ebx, ecx mov ebx, ecx
@ -449,7 +452,7 @@ TCP_send:
mov ecx, [esp + 4] mov ecx, [esp + 4]
lea esi, [esp + 8] lea esi, [esp + 8]
shr ecx, 2 ; count is in bytes, we will work with dwords shr ecx, 2 ; count is in bytes, we will work with dwords
rep movsd rep movsd
pop ecx ; full TCP packet size pop ecx ; full TCP packet size
pop esi ; headersize pop esi ; headersize
@ -549,7 +552,8 @@ TCP_send:
pop ecx pop ecx
pop eax pop eax
inc [TCP_segments_tx] ; FIXME: correct interface? call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
; update advertised receive window ; update advertised receive window
test ecx, ecx test ecx, ecx
@ -570,6 +574,8 @@ TCP_send:
;-------------- ;--------------
; unlock socket ; unlock socket
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: unlocking socket 0x%x\n", eax
push eax push eax
lea ecx, [eax + SOCKET.mutex] lea ecx, [eax + SOCKET.mutex]
call mutex_unlock call mutex_unlock
@ -606,7 +612,8 @@ TCP_send:
.send_error: .send_error:
add esp, 8 add esp, 4
pop eax
lea ecx, [eax + SOCKET.mutex] lea ecx, [eax + SOCKET.mutex]
call mutex_unlock call mutex_unlock

View File

@ -164,7 +164,7 @@ TCP_drop:
;;; TODO: check if error code is "Connection timed out' and handle accordingly ;;; 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 @@ TCP_respond:
; And send the segment ; And send the segment
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
@@:
ret ret
.error: .error:
@ -378,6 +383,11 @@ TCP_respond_segment:
; And send the segment ; And send the segment
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
@@:
ret ret
.error: .error:

View File

@ -97,6 +97,9 @@ TCP_disconnect:
call SOCKET_is_disconnecting call SOCKET_is_disconnecting
call TCP_usrclosed call TCP_usrclosed
push eax
call TCP_output call TCP_output
pop eax
ret ret

View File

@ -27,10 +27,12 @@ struct UDP_header
ends ends
align 4
uglobal uglobal
align 4
UDP_PACKETS_TX rd NET_DEVICES_MAX UDP_PACKETS_TX rd NET_DEVICES_MAX
UDP_PACKETS_RX rd NET_DEVICES_MAX UDP_PACKETS_RX rd NET_DEVICES_MAX
endg endg
@ -46,7 +48,7 @@ macro UDP_init {
xor eax, eax xor eax, eax
mov edi, UDP_PACKETS_TX mov edi, UDP_PACKETS_TX
mov ecx, 2*NET_DEVICES_MAX mov ecx, 2*NET_DEVICES_MAX
rep stosd rep stosd
} }
@ -114,6 +116,7 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
diff16 "UDP packetgfgfgfgfs", 0, $
UDP_input: UDP_input:
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: size=%u\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: size=%u\n", ecx
@ -139,6 +142,11 @@ UDP_input:
; IP Packet UDP Destination Port = local Port ; IP Packet UDP Destination Port = local Port
; IP Packet SA = Remote IP ; IP Packet SA = Remote IP
pusha
mov ecx, socket_mutex
call mutex_lock
popa
mov cx, [esi + UDP_header.SourcePort] mov cx, [esi + UDP_header.SourcePort]
mov dx, [esi + UDP_header.DestinationPort] mov dx, [esi + UDP_header.DestinationPort]
mov edi, [edi + 4] ; ipv4 source address mov edi, [edi + 4] ; ipv4 source address
@ -147,7 +155,7 @@ UDP_input:
.next_socket: .next_socket:
mov eax, [eax + SOCKET.NextPtr] mov eax, [eax + SOCKET.NextPtr]
or eax, eax or eax, eax
jz .dump jz .dump_
cmp [eax + SOCKET.Domain], AF_INET4 cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket jne .next_socket
@ -160,6 +168,11 @@ UDP_input:
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: socket=%x\n", eax 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! ;;; TODO: when packet is processed, check more sockets!
; cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff ; cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
@ -182,7 +195,8 @@ UDP_input:
popa popa
.updatesock: .updatesock:
inc [UDP_PACKETS_RX] ; Fixme: correct interface? call NET_ptr_to_num4
inc [UDP_PACKETS_RX + edi]
movzx ecx, [esi + UDP_header.Length] movzx ecx, [esi + UDP_header.Length]
sub ecx, sizeof.UDP_header sub ecx, sizeof.UDP_header
@ -202,6 +216,16 @@ UDP_input:
jmp .updatesock 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: .checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n" DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
@ -257,10 +281,10 @@ UDP_output:
sub ecx, sizeof.UDP_header sub ecx, sizeof.UDP_header
add edi, sizeof.UDP_header add edi, sizeof.UDP_header
shr ecx, 2 shr ecx, 2
rep movsd rep movsd
mov ecx, [esp] mov ecx, [esp]
and ecx, 3 and ecx, 3
rep movsb rep movsb
pop ecx edi pop ecx edi
pop dword [edi + UDP_header.SourcePort] pop dword [edi + UDP_header.SourcePort]
@ -274,7 +298,8 @@ UDP_output:
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
test eax, eax test eax, eax
jnz @f jnz @f
inc [UDP_PACKETS_TX] ; FIXME: correct device? call NET_ptr_to_num4
inc [UDP_PACKETS_TX + edi]
@@: @@:
ret ret