/kernel/branches/kolibri-process/lang.inc |
---|
File deleted |
/kernel/branches/kolibri-process/blkdev/disk_cache.inc |
---|
258,7 → 258,25 |
call cache_lookup_write |
test eax, eax |
jnz .cache_error |
; 12d. For each sector, copy data, mark the item as not-modified copy of the disk, |
; 12d. If the sector was already present in the cache as modified, |
; data that were read at step 10 for this sector are obsolete, |
; so rewrite data for the caller from the cache. |
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
jnz .not_modified |
mov esi, ecx |
shl esi, 9 |
add esi, [ebx+DISKCACHE.data] |
mov edi, [esp+4] |
mov ecx, [esp] |
shl ecx, 9-2 |
sub edi, ecx |
mov ecx, 512/4 |
rep movsd |
add [.current_buffer+8], 512 |
jmp .sector_done |
.not_modified: |
; 12e. For each not-modified sector, |
; copy data, mark the item as not-modified copy of the disk, |
; advance .current_buffer and .sector_hi:.sector_lo to the next sector. |
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
mov esi, [.current_buffer+8] |
268,16 → 286,17 |
mov ecx, 512/4 |
rep movsd |
mov [.current_buffer+8], esi |
.sector_done: |
add [.sector_lo+.local_vars2_size+8], 1 |
adc [.sector_hi+.local_vars2_size+8], 0 |
; 12e. Continue the loop 12c-12d until all sectors are read. |
; 12f. Continue the loop 12c-12e until all sectors are read. |
dec dword [esp] |
jnz .store_to_cache |
.cache_error: |
; 12f. Restore after the loop: pop the local variable and restore edi. |
; 12g. Restore after the loop: pop the local variable and restore edi. |
pop ecx |
pop edi |
; 12g. Release the lock. |
; 12h. Release the lock. |
mov ecx, [ebp+PARTITION.Disk] |
add ecx, DISK.CacheLock |
call mutex_unlock |
651,7 → 670,13 |
call cache_lookup_write |
test eax, eax |
jnz .cache_error |
; 11c. For each sector, copy data, mark the item as not-modified copy of the disk, |
; 11c. Ignore sectors marked as modified: for them the cache is more recent that disk data. |
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
jnz .not_modified |
add [.current_buffer], 512 |
jmp .sector_done |
.not_modified: |
; 11d. For each sector, copy data, mark the item as not-modified copy of the disk, |
; advance .current_buffer and .sector_hi:.sector_lo to the next sector. |
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
mov esi, [.current_buffer] |
661,13 → 686,14 |
mov ecx, 512/4 |
rep movsd |
mov [.current_buffer], esi |
.sector_done: |
add [.sector_lo+.local_vars2_size], 1 |
adc [.sector_hi+.local_vars2_size], 0 |
; 11d. Continue the loop at 11b-11c until all sectors are processed. |
; 11e. Continue the loop at 11b-11d until all sectors are processed. |
dec [.num_sectors] |
jnz .store_to_cache |
.cache_error: |
; 11e. Release the lock. |
; 11f. Release the lock. |
mov ecx, [ebp+PARTITION.Disk] |
add ecx, DISK.CacheLock |
call mutex_unlock |
695,11 → 721,9 |
call cache_lookup_write |
test eax, eax |
jnz .floppy_cache_error |
; 14. Mark the item as empty for the case of read error. |
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY |
push ecx |
; 15. Call the driver to read one sector. |
; 14. Call the driver to read one sector. |
push 1 |
push esp |
push edx |
713,7 → 737,7 |
pop ecx |
dec ecx |
jnz .floppy_read_error |
; 16. Get the slot and pointer to the cache item, |
; 15. Get the slot and pointer to the cache item, |
; change the status to not-modified copy of the disk |
; and go to 4c. |
pop ecx |
723,7 → 747,7 |
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
jmp .found_in_cache |
; On error at steps 13-15, release the lock |
; On error at steps 13-14, release the lock |
; and pass the error to the caller. |
.floppy_read_error: |
pop ecx |
849,6 → 873,7 |
mov [ebx+DISKCACHE.search_start], ecx |
popd [esi+CACHE_ITEM.SectorLo] |
popd [esi+CACHE_ITEM.SectorHi] |
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY |
.return0: |
xor eax, eax ; success |
ret |
/kernel/branches/kolibri-process/blkdev/hd_drv.inc |
---|
1183,3 → 1183,35 |
IDE_BAR3_val dw ? |
endg |
;----------------------------------------------------------------------------- |
proc clear_pci_ide_interrupts |
mov esi, pcidev_list |
.loop: |
mov esi, [esi+PCIDEV.fd] |
cmp esi, pcidev_list |
jz .done |
cmp [esi+PCIDEV.class], 0x01018F |
jnz .loop |
mov ah, [esi+PCIDEV.bus] |
mov al, 2 |
mov bh, [esi+PCIDEV.devfn] |
mov bl, 0x20 |
call pci_read_reg |
and eax, 0FFFCh |
mov edx, eax |
add edx, 2 |
in al, dx |
DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al |
out dx, al |
in al, dx |
DEBUGF 1,'-> %x; ',al |
add edx, 8 |
in al, dx |
DEBUGF 1,'port[%x] = %x ',dx,al |
out dx, al |
in al, dx |
DEBUGF 1,'-> %x\n',al |
jmp .loop |
.done: |
ret |
endp |
/kernel/branches/kolibri-process/bus/pci/pci32.inc |
---|
722,3 → 722,9 |
leave |
ret |
endp |
; Export for drivers. Just returns the pointer to the pci-devices list. |
proc get_pcidev_list |
mov eax, pcidev_list |
ret |
endp |
/kernel/branches/kolibri-process/bus/usb/common.inc |
---|
6,7 → 6,7 |
; ============================================================================= |
; Version of all structures related to host controllers. |
; Must be the same in kernel and *hci-drivers. |
USBHC_VERSION = 1 |
USBHC_VERSION = 2 |
; USB device must have at least 100ms of stable power before initializing can |
; proceed; one timer tick is 10ms, so enforce delay in 10 ticks |
46,6 → 46,7 |
USB_STATUS_CLOSED = 16 ; pipe closed |
; either explicitly with USBClosePipe |
; or implicitly due to device disconnect |
USB_STATUS_CANCELLED = 17 ; transfer cancelled with USBAbortPipe |
; Possible speeds of USB devices |
USB_SPEED_FS = 0 ; full-speed |
63,6 → 64,9 |
USB_FLAG_EXTRA_WAIT = 4 |
; The pipe was in wait list, while another event occured; |
; when the first wait will be done, reinsert the pipe to wait list |
USB_FLAG_DISABLED = 8 |
; The pipe is temporarily disabled so that it is not visible to hardware |
; but still remains in software list. Used for usb_abort_pipe. |
USB_FLAG_CLOSED_BIT = 0 ; USB_FLAG_CLOSED = 1 shl USB_FLAG_CLOSED_BIT |
; ============================================================================= |
136,6 → 140,14 |
; Initiate configuration of a new device (create pseudo-pipe describing that |
; device and call usb_new_device). |
; esi -> usb_controller, eax = speed (one of USB_SPEED_* constants). |
DisablePipe dd ? |
; This procedure temporarily removes the given pipe from hardware queue. |
; esi -> usb_controller, ebx -> usb_pipe |
EnablePipe dd ? |
; This procedure reinserts the given pipe to hardware queue |
; after DisablePipe, with clearing transfer queue. |
; esi -> usb_controller, ebx -> usb_pipe |
; edx -> current descriptor, eax -> new last descriptor |
ends |
; pointers to kernel API functions that are called from *HCI-drivers |
307,6 → 319,8 |
PrevVirt dd ? |
; Previous endpoint in the processing list. |
; See also NextVirt field and the description before NextVirt field. |
BaseList dd ? |
; Pointer to head of the processing list. |
; |
; Every pipe has the associated transfer queue, that is, the double-linked |
; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt |
427,6 → 441,8 |
; Size of device descriptor. |
Speed db ? |
; Device speed, one of USB_SPEED_*. |
Timer dd ? |
; Handle of timer that handles request timeout. |
NumInterfaces dd ? |
; Number of interfaces. |
ConfigDataSize dd ? |
/kernel/branches/kolibri-process/bus/usb/hccommon.inc |
---|
114,7 → 114,7 |
ret |
endp |
; Put the given control pipe in the wait list; |
; Put the given control/bulk pipe in the wait list; |
; called when the pipe structure is changed and a possible hardware cache |
; needs to be synchronized. When it will be known that the cache is updated, |
; usb_subscription_done procedure will be called. |
128,6 → 128,17 |
ret |
endp |
; Same as usb_subscribe_control, but for interrupt/isochronous pipe. |
proc usb_subscribe_periodic |
cmp [ebx+usb_pipe.NextWait], -1 |
jnz @f |
mov eax, [esi+usb_controller.WaitPipeListPeriodic] |
mov [ebx+usb_pipe.NextWait], eax |
mov [esi+usb_controller.WaitPipeListPeriodic], ebx |
@@: |
ret |
endp |
; Called after synchronization of hardware cache with software changes. |
; Continues process of device enumeration based on when it was delayed |
; due to call to usb_subscribe_control. |
254,7 → 265,7 |
mov [esi+usb_controller.WaitPipeListAsync+edx], ebx |
jmp .continue |
.process: |
; 7. Call the handler depending on USB_FLAG_CLOSED. |
; 7. Call the handler depending on USB_FLAG_CLOSED and USB_FLAG_DISABLED. |
or [ebx+usb_pipe.NextWait], -1 |
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED |
jz .nodisconnect |
261,6 → 272,11 |
call usb_pipe_closed |
jmp .continue |
.nodisconnect: |
test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED |
jz .nodisabled |
call usb_pipe_disabled |
jmp .continue |
.nodisabled: |
call usb_subscription_done |
.continue: |
; 8. Restore edx and next pipe saved in step 5 and continue the loop. |
/kernel/branches/kolibri-process/bus/usb/pipe.inc |
---|
13,6 → 13,11 |
stdcall arg |
end if |
} |
if USB_STDCALL_VERIFY |
STDCALL_VERIFY_EXTRA = 20h |
else |
STDCALL_VERIFY_EXTRA = 0 |
end if |
; Initialization of usb_static_ep structure, |
; called from controller-specific initialization; edi -> usb_static_ep |
238,8 → 243,17 |
call mutex_lock |
push ecx |
; 3b. Let the controller-specific code do its job. |
test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED |
jnz @f |
mov eax, [esi+usb_controller.HardwareFunc] |
call [eax+usb_hardware_func.DisablePipe] |
@@: |
mov eax, [esi+usb_controller.HardwareFunc] |
call [eax+usb_hardware_func.UnlinkPipe] |
mov edx, [ebx+usb_pipe.NextVirt] |
mov eax, [ebx+usb_pipe.PrevVirt] |
mov [edx+usb_pipe.PrevVirt], eax |
mov [eax+usb_pipe.NextVirt], edx |
; 3c. Release the corresponding lock. |
pop ecx |
call mutex_unlock |
262,6 → 276,40 |
ret |
endp |
; This procedure is called when all transfers are aborted |
; either due to call to usb_abort_pipe or due to pipe closing. |
; It notifies all callbacks and frees all transfer descriptors. |
; ebx -> usb_pipe, esi -> usb_controller, edi -> usb_hardware_func |
; three stack parameters: status code for callback functions |
; and descriptors where to start and stop. |
proc usb_pipe_aborted |
virtual at esp |
dd ? ; return address |
.status dd ? ; USB_STATUS_CLOSED or USB_STATUS_CANCELLED |
.first_td dd ? |
.last_td dd ? |
end virtual |
; Loop over all transfers, calling the driver with the given status |
; and freeing all descriptors except the last one. |
.loop: |
mov edx, [.first_td] |
cmp edx, [.last_td] |
jz .done |
mov ecx, [edx+usb_gtd.Callback] |
test ecx, ecx |
jz .no_callback |
stdcall_verify ecx, ebx, [.status+12+STDCALL_VERIFY_EXTRA], \ |
[edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData] |
mov edx, [.first_td] |
.no_callback: |
mov eax, [edx+usb_gtd.NextVirt] |
mov [.first_td], eax |
stdcall [edi+usb_hardware_func.FreeTD], edx |
jmp .loop |
.done: |
ret 12 |
endp |
; This procedure is called when a pipe with USB_FLAG_CLOSED is removed from the |
; corresponding wait list. It means that the hardware has fully forgot about it. |
; ebx -> usb_pipe, esi -> usb_controller |
268,30 → 316,26 |
proc usb_pipe_closed |
push edi |
mov edi, [esi+usb_controller.HardwareFunc] |
; 1. Loop over all transfers, calling the driver with USB_STATUS_CLOSED |
; and freeing all descriptors. |
; 1. Notify all registered callbacks with status USB_STATUS_CLOSED, if any, |
; and free all transfer descriptors, including the last one. |
lea ecx, [ebx+usb_pipe.Lock] |
call mutex_lock |
mov edx, [ebx+usb_pipe.LastTD] |
test edx, edx |
jz .no_transfer |
mov edx, [edx+usb_gtd.NextVirt] |
.transfer_loop: |
cmp edx, [ebx+usb_pipe.LastTD] |
jz .transfer_done |
mov ecx, [edx+usb_gtd.Callback] |
test ecx, ecx |
jz .no_callback |
mov eax, [edx+usb_gtd.NextVirt] |
push edx |
stdcall_verify ecx, ebx, USB_STATUS_CLOSED, \ |
[edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData] |
pop edx |
.no_callback: |
push [edx+usb_gtd.NextVirt] |
stdcall [edi+usb_hardware_func.FreeTD], edx |
pop edx |
jmp .transfer_loop |
.transfer_done: |
stdcall [edi+usb_hardware_func.FreeTD], edx |
push eax |
call mutex_unlock |
push USB_STATUS_CLOSED |
call usb_pipe_aborted |
; It is safe to free LastTD here: |
; usb_*_transfer_async do not enqueue new transfers if USB_FLAG_CLOSED is set. |
stdcall [edi+usb_hardware_func.FreeTD], [ebx+usb_pipe.LastTD] |
jmp @f |
.no_transfer: |
call mutex_unlock |
@@: |
; 2. Decrement number of pipes for the device. |
; If this pipe is the last pipe, go to 5. |
mov ecx, [ebx+usb_pipe.DeviceData] |
342,7 → 386,16 |
dec eax |
jnz .notify_loop |
.notify_done: |
; 6. Bus address, if assigned, can now be reused. |
; 6. Kill the timer, if active. |
; (Usually not; possible if device is disconnected |
; while processing SET_ADDRESS request). |
mov eax, [ebx+usb_pipe.DeviceData] |
cmp [eax+usb_device_data.Timer], 0 |
jz @f |
stdcall cancel_timer_hs, [eax+usb_device_data.Timer] |
mov [eax+usb_device_data.Timer], 0 |
@@: |
; 7. Bus address, if assigned, can now be reused. |
call [edi+usb_hardware_func.GetDeviceAddress] |
test eax, eax |
jz @f |
349,7 → 402,7 |
bts [esi+usb_controller.ExistingAddresses], eax |
@@: |
dbgstr 'USB device disconnected' |
; 7. All drivers have returned from disconnect callback, |
; 8. All drivers have returned from disconnect callback, |
; so all drivers should not use any device-related pipes. |
; Free the remaining pipes. |
mov eax, [ebx+usb_pipe.DeviceData] |
366,15 → 419,74 |
.free_done: |
stdcall [edi+usb_hardware_func.FreePipe], ebx |
pop eax |
; 8. Free the usb_device_data structure. |
; 9. Free the usb_device_data structure. |
sub eax, usb_device_data.ClosedPipeList - usb_pipe.NextSibling |
call free |
; 9. Return. |
; 10. Return. |
.nothing: |
pop edi |
ret |
endp |
; This procedure is called when a pipe with USB_FLAG_DISABLED is removed from the |
; corresponding wait list. It means that the hardware has fully forgot about it. |
; ebx -> usb_pipe, esi -> usb_controller |
proc usb_pipe_disabled |
push edi |
mov edi, [esi+usb_controller.HardwareFunc] |
; 1. Acquire pipe lock. |
lea ecx, [ebx+usb_pipe.Lock] |
call mutex_lock |
; 2. Clear USB_FLAG_DISABLED in pipe state. |
and [ebx+usb_pipe.Flags], not USB_FLAG_DISABLED |
; 3. Sanity check: ignore uninitialized pipes. |
cmp [ebx+usb_pipe.LastTD], 0 |
jz .no_transfer |
; 4. Acquire the first and last to-be-cancelled transfer descriptor, |
; save them in stack for the step 6, |
; ask the controller driver to enable the pipe for hardware, |
; removing transfers between first and last to-be-cancelled descriptors. |
lea ecx, [esi+usb_controller.ControlLock] |
cmp [ebx+usb_pipe.Type], BULK_PIPE |
jb @f ; control pipe |
lea ecx, [esi+usb_controller.BulkLock] |
jz @f ; bulk pipe |
lea ecx, [esi+usb_controller.PeriodicLock] |
@@: |
call mutex_lock |
mov eax, [ebx+usb_pipe.BaseList] |
mov edx, [eax+usb_pipe.NextVirt] |
mov [ebx+usb_pipe.NextVirt], edx |
mov [ebx+usb_pipe.PrevVirt], eax |
mov [edx+usb_pipe.PrevVirt], ebx |
mov [eax+usb_pipe.NextVirt], ebx |
mov eax, [ebx+usb_pipe.LastTD] |
mov edx, [eax+usb_gtd.NextVirt] |
mov [eax+usb_gtd.NextVirt], eax |
mov [eax+usb_gtd.PrevVirt], eax |
push eax |
push edx |
push ecx |
call [edi+usb_hardware_func.EnablePipe] |
pop ecx |
call mutex_unlock |
; 5. Release pipe lock acquired at step 1. |
; Callbacks called at step 6 can insert new transfers, |
; so we cannot call usb_pipe_aborted while holding pipe lock. |
lea ecx, [ebx+usb_pipe.Lock] |
call mutex_unlock |
; 6. Notify all registered callbacks with status USB_STATUS_CANCELLED, if any. |
; Two arguments describing transfers range were pushed at step 4. |
push USB_STATUS_CANCELLED |
call usb_pipe_aborted |
pop edi |
ret |
.no_transfer: |
call mutex_unlock |
pop edi |
ret |
endp |
; Part of API for drivers, see documentation for USBNormalTransferAsync. |
proc usb_normal_transfer_async stdcall uses ebx edi,\ |
pipe:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword |
508,6 → 620,69 |
ret |
endp |
; Part of API for drivers, see documentation for USBAbortPipe. |
proc usb_abort_pipe |
push ebx esi ; save used registers to be stdcall |
virtual at esp |
rd 2 ; saved registers |
dd ? ; return address |
.pipe dd ? |
end virtual |
mov ebx, [.pipe] |
; 1. Acquire pipe lock. |
lea ecx, [ebx+usb_pipe.Lock] |
call mutex_lock |
; 2. If the pipe is already closed or abort is in progress, |
; just release pipe lock and return. |
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED + USB_FLAG_DISABLED |
jnz .nothing |
; 3. Mark the pipe as aborting. |
or [ebx+usb_pipe.Flags], USB_FLAG_DISABLED |
; 4. We cannot do anything except adding new transfers concurrently with hardware. |
; Ask the controller driver to (temporarily) remove the pipe from hardware queue. |
mov esi, [ebx+usb_pipe.Controller] |
; 4a. Acquire queue lock. |
lea ecx, [esi+usb_controller.ControlLock] |
cmp [ebx+usb_pipe.Type], BULK_PIPE |
jb @f ; control pipe |
lea ecx, [esi+usb_controller.BulkLock] |
jz @f ; bulk pipe |
lea ecx, [esi+usb_controller.PeriodicLock] |
@@: |
call mutex_lock |
push ecx |
; 4b. Call the driver. |
mov eax, [esi+usb_controller.HardwareFunc] |
call [eax+usb_hardware_func.DisablePipe] |
; 4c. Remove the pipe from software list. |
mov eax, [ebx+usb_pipe.NextVirt] |
mov edx, [ebx+usb_pipe.PrevVirt] |
mov [eax+usb_pipe.PrevVirt], edx |
mov [edx+usb_pipe.NextVirt], eax |
; 4c. Register the pipe in corresponding wait list. |
test [ebx+usb_pipe.Type], 1 |
jz .control_bulk |
call usb_subscribe_periodic |
jmp @f |
.control_bulk: |
call usb_subscribe_control |
@@: |
; 4d. Release queue lock. |
pop ecx |
call mutex_unlock |
; 4e. Notify the USB thread about new work. |
push ebx esi edi |
call usb_wakeup |
pop edi esi ebx |
; That's all for now. To be continued in usb_pipe_disabled. |
; 5. Release pipe lock acquired at step 1 and return. |
.nothing: |
lea ecx, [ebx+usb_pipe.Lock] |
call mutex_unlock |
pop esi ebx |
ret 4 |
endp |
; Part of API for drivers, see documentation for USBGetParam. |
proc usb_get_param |
virtual at esp |
/kernel/branches/kolibri-process/bus/usb/protocol.inc |
---|
33,6 → 33,19 |
; read to the debug board. |
USB_DUMP_DESCRIPTORS = 1 |
; According to the USB specification (9.2.6.3), |
; any device must response to SET_ADDRESS in 50 ms, or 5 timer ticks. |
; Of course, our world is far from ideal. |
; I have seen devices that just NAK everything when being reset from working |
; state, but start to work after second reset. |
; Our strategy is as follows: give 2 seconds for the first attempt, |
; this should be enough for normal devices and not too long to detect buggy ones. |
; If the device continues NAKing, reset it and retry several times, |
; doubling the interval: 2s -> 4s -> 8s -> 16s. Give up after that. |
; Numbers are quite arbitrary. |
TIMEOUT_SET_ADDRESS_INITIAL = 200 |
TIMEOUT_SET_ADDRESS_LAST = 1600 |
; ============================================================================= |
; ================================ Structures ================================= |
; ============================================================================= |
179,7 → 192,22 |
; out: eax = 0 <=> failed, the caller should disable the port. |
proc usb_new_device |
push ebx edi ; save used registers to be stdcall |
; 1. Allocate resources. Any device uses the following resources: |
; 1. Check whether we're here because we were trying to reset |
; already-registered device in hope to fix something serious. |
; If so, skip allocation and go to 6. |
movzx eax, [esi+usb_controller.ResettingPort] |
mov edx, [esi+usb_controller.ResettingHub] |
test edx, edx |
jz .test_roothub |
mov edx, [edx+usb_hub.ConnectedDevicesPtr] |
mov ebx, [edx+eax*4] |
jmp @f |
.test_roothub: |
mov ebx, [esi+usb_controller.DevicesByPort+eax*4] |
@@: |
test ebx, ebx |
jnz .try_set_address |
; 2. Allocate resources. Any device uses the following resources: |
; - device address in the bus |
; - memory for device data |
; - pipe for zero endpoint |
186,14 → 214,14 |
; If some allocation fails, we must undo our actions. Closing the pipe |
; is a hard task, so we avoid it and open the pipe as the last resource. |
; The order for other two allocations is quite arbitrary. |
; 1a. Allocate a bus address. |
; 2a. Allocate a bus address. |
push ecx |
call usb_set_address_request |
pop ecx |
; 1b. If failed, just return zero. |
; 2b. If failed, just return zero. |
test eax, eax |
jz .nothing |
; 1c. Allocate memory for device data. |
; 2c. Allocate memory for device data. |
; For now, we need sizeof.usb_device_data and extra 8 bytes for GET_DESCRIPTOR |
; input and output, see usb_after_set_address. Later we will reallocate it |
; to actual size needed for descriptors. |
201,10 → 229,10 |
push ecx |
call malloc |
pop ecx |
; 1d. If failed, free the bus address and return zero. |
; 2d. If failed, free the bus address and return zero. |
test eax, eax |
jz .nomemory |
; 1e. Open pipe for endpoint zero. |
; 2e. Open pipe for endpoint zero. |
; For now, we do not know the actual maximum packet size; |
; for full-speed devices it can be any of 8, 16, 32, 64 bytes, |
; low-speed devices must have 8 bytes, high-speed devices must have 64 bytes. |
227,12 → 255,14 |
; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes. |
xchg eax, ebx |
pop eax |
; 1f. If failed, free the memory, the bus address and return zero. |
; 2f. If failed, free the memory, the bus address and return zero. |
test ebx, ebx |
jz .freememory |
; 2. Store pointer to device data in the pipe structure. |
; 3. Store pointer to device data in the pipe structure. |
mov [ebx+usb_pipe.DeviceData], eax |
; 3. Init device data, using usb_controller.Resetting* variables. |
; 4. Init device data, using usb_controller.Resetting* variables. |
mov [eax+usb_device_data.Timer], edi |
mov dword [eax+usb_device_data.DeviceDescriptor], TIMEOUT_SET_ADDRESS_INITIAL |
mov [eax+usb_device_data.TTHub], edi |
mov [eax+usb_device_data.TTPort], 0 |
mov [eax+usb_device_data.NumInterfaces], edi |
268,7 → 298,7 |
mov [eax+usb_device_data.Port], cl |
mov edx, [esi+usb_controller.ResettingHub] |
mov [eax+usb_device_data.Hub], edx |
; 4. Store pointer to the config pipe in the hub data. |
; 5. Store pointer to the config pipe in the hub data. |
; Config pipe serves as device identifier. |
; Root hubs use the array inside usb_controller structure, |
; non-root hubs use the array immediately after usb_hub structure. |
281,16 → 311,29 |
mov [esi+usb_controller.DevicesByPort+ecx*4], ebx |
@@: |
call usb_reinit_pipe_list |
; 5. Issue SET_ADDRESS control request, using buffer filled in step 1a. |
; 6. Issue SET_ADDRESS control request, using buffer filled in step 2a. |
; 6a. Configure timer to force reset after timeout. |
; Note: we can't use self-destructing timer, because we need to be able to cancel it, |
; and for self-destructing timer we could have race condition in cancelling/destructing. |
; DEBUGF 1,'K : pipe %x\n',ebx |
.try_set_address: |
xor edi, edi |
mov edx, [ebx+usb_pipe.DeviceData] |
stdcall timer_hs, [edx+usb_device_data.DeviceDescriptor], 7FFFFFFFh, usb_abort_pipe, ebx |
test eax, eax |
jz .nothing |
mov edx, [ebx+usb_pipe.DeviceData] |
mov [edx+usb_device_data.Timer], eax |
; 6b. If it succeeded, setup timer to configure wait timeout. |
lea eax, [esi+usb_controller.SetAddressBuffer] |
stdcall usb_control_async, ebx, eax, edi, edi, usb_set_address_callback, edi, edi |
; Use the return value from usb_control_async as our return value; |
; if it is zero, then something has failed. |
lea eax, [esi+usb_controller.SetAddressBuffer] |
stdcall usb_control_async, ebx, eax, edi, edi, usb_set_address_callback, edi, edi |
.nothing: |
; 6. Return. |
; 7. Return. |
pop edi ebx ; restore used registers to be stdcall |
ret |
; Handlers of failures in steps 1b, 1d, 1f. |
; Handlers of failures in steps 2b, 2d, 2f. |
.freememory: |
call free |
jmp .freeaddr |
349,16 → 392,23 |
; Note that USB stack uses esi = pointer to usb_controller. |
proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword |
push ebx ; save ebx to be stdcall |
mov ebx, [pipe] |
; 1. In any case, cancel the timer. |
mov eax, [ebx+usb_pipe.DeviceData] |
stdcall cancel_timer_hs, [eax+usb_device_data.Timer] |
mov eax, [ebx+usb_pipe.DeviceData] |
mov [eax+usb_device_data.Timer], 0 |
; Load data to registers for further references. |
mov ebx, [pipe] |
mov ecx, dword [esi+usb_controller.SetAddressBuffer+2] |
mov eax, [esi+usb_controller.HardwareFunc] |
; 1. Check whether the device has accepted new address. If so, proceed to 2. |
; Otherwise, go to 3. |
; 2. Check whether the device has accepted new address. If so, proceed to 3. |
; Otherwise, go to 4 if killed by usb_set_address_timeout or to 5 otherwise. |
cmp [status], USB_STATUS_CANCELLED |
jz .timeout |
cmp [status], 0 |
jnz .error |
; 2. Address accepted. |
; 2a. The controller-specific structure for the control pipe still uses |
; 3. Address accepted. |
; 3a. The controller-specific structure for the control pipe still uses |
; zero address. Call the controller-specific function to change it to |
; the actual address. |
; Note that the hardware could cache the controller-specific structure, |
367,25 → 417,49 |
; be safe to continue. |
; dbgstr 'address set in device' |
call [eax+usb_hardware_func.SetDeviceAddress] |
; 2b. If the port is in non-root hub, clear 'reset in progress' flag. |
; In any case, proceed to 4. |
; 3b. If the port is in non-root hub, clear 'reset in progress' flag. |
; In any case, proceed to 6. |
mov eax, [esi+usb_controller.ResettingHub] |
test eax, eax |
jz .return |
and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS |
.return: |
; 4. Address configuration done, we can proceed with other ports. |
; 6. Address configuration done, we can proceed with other ports. |
; Call the worker function for that. |
call usb_test_pending_port |
.wakeup: |
push esi edi |
call usb_wakeup |
pop edi esi |
.nothing: |
pop ebx ; restore ebx to be stdcall |
ret |
.timeout: |
; 4. Device continues to NAK the request. Reset it and retry. |
mov edx, [ebx+usb_pipe.DeviceData] |
mov ecx, [edx+usb_device_data.DeviceDescriptor] |
add ecx, ecx |
cmp ecx, TIMEOUT_SET_ADDRESS_LAST |
ja .error |
mov [edx+usb_device_data.DeviceDescriptor], ecx |
dbgstr 'Timeout in USB device initialization, trying to reset...' |
cmp [esi+usb_controller.ResettingHub], 0 |
jz .reset_roothub |
push esi |
mov esi, [esi+usb_controller.ResettingHub] |
call usb_hub_initiate_reset |
pop esi |
jmp .nothing |
.reset_roothub: |
movzx ecx, [esi+usb_controller.ResettingPort] |
call [eax+usb_hardware_func.InitiateReset] |
jmp .wakeup |
.error: |
; 3. Device error: device not responding, disconnect etc. |
; 5. Device error: device not responding, disconnect etc. |
DEBUGF 1,'K : error %d in SET_ADDRESS, USB device disabled\n',[status] |
; 3a. The address has not been accepted. Mark it as free. |
; 5a. The address has not been accepted. Mark it as free. |
bts dword [esi+usb_controller.ExistingAddresses], ecx |
; 3b. Disable the port with bad device. |
; 5b. Disable the port with bad device. |
; For the root hub, call the controller-specific function and go to 6. |
; For non-root hubs, let the hub code do its work and return (the request |
; could take some time, the hub code is responsible for proceeding). |
/kernel/branches/kolibri-process/core/exports.inc |
---|
122,6 → 122,8 |
NET_link_changed, 'NetLinkChanged', \ |
ETH_input, 'Eth_input', \ |
\ |
get_pcidev_list, 'GetPCIList', \ |
\ |
0, 'LFBAddress' ; must be the last one |
load kernel_exports_count dword from __exports + 24 |
load kernel_exports_addresses dword from __exports + 28 |
/kernel/branches/kolibri-process/core/memory.inc |
---|
232,12 → 232,24 |
mov edi, ebx |
shr edi, 12 |
lea edi, [page_tabs+edi*4] |
if USE_FIX_FOR_INVALID_MS_VIRTUAL_PC_2007 |
mov edx, eax |
@@: |
mov eax, edx |
stosd |
invlpg [ebx] |
add edx, 0x1000 |
add ebx, 0x1000 |
loop @B |
else |
@@: |
stosd |
invlpg [ebx] |
add eax, 0x1000 |
add ebx, 0x1000 |
loop @B |
end if |
pop edi |
/kernel/branches/kolibri-process/data32.inc |
---|
465,8 → 465,6 |
hdbase rd 1 ; for boot 0x1f0 |
hdid rd 1 |
hdpos rd 1 ; for boot 0x1 |
label known_part dword |
fat32part rd 1 ; for boot 0x1 |
cdpos rd 1 |
;CPUID information |
/kernel/branches/kolibri-process/gui/window.inc |
---|
817,12 → 817,8 |
jnz .exit |
; does client area have a positive size on screen? |
mov edx, [esi + WDATA.box.top] |
add edx, 21 + 5 |
mov ebx, [esi + WDATA.box.top] |
add ebx, [esi + WDATA.box.height] |
cmp edx, ebx |
jg .exit |
cmp [esi + WDATA.box.height], 21 |
jle .exit |
; okay, let's draw it |
mov eax, 1 |
/kernel/branches/kolibri-process/hid/mousedrv.inc |
---|
482,9 → 482,12 |
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword |
mov eax, [BtnState] |
and eax, 0x3FFFFFFF ; Top 2 bits are used to flag absolute movements |
mov [BTN_DOWN], eax |
mov eax, [XMoving] |
test [BtnState], 0x80000000 |
jnz @@M1 |
call mouse_acceleration |
add ax, [MOUSE_X];[XCoordinate] |
cmp ax, 0 |
503,6 → 506,8 |
mov [MOUSE_X], ax;[XCoordinate] |
mov eax, [YMoving] |
test [BtnState], 0x40000000 |
jnz @@M3 |
neg eax |
call mouse_acceleration |
/kernel/branches/kolibri-process/kernel.asm |
---|
766,7 → 766,29 |
call unmask_timer |
stdcall enable_irq, 2 ; @#$%! PIC |
stdcall enable_irq, 13 ; co-processor |
;----------------------------------------------------------------------------- |
; show SVN version of kernel on the message board |
;----------------------------------------------------------------------------- |
mov eax, [version_inf.rev] |
DEBUGF 1, "K : kernel SVN r%d\n", eax |
;----------------------------------------------------------------------------- |
; show CPU count on the message board |
;----------------------------------------------------------------------------- |
mov eax, [cpu_count] |
test eax, eax |
jnz @F |
mov al, 1 ; at least one CPU |
@@: |
DEBUGF 1, "K : %d CPU detected\n", eax |
;----------------------------------------------------------------------------- |
; detect Floppy drives |
;----------------------------------------------------------------------------- |
mov esi, boot_detectfloppy |
call boot_log |
include 'detect/dev_fd.inc' |
;----------------------------------------------------------------------------- |
; START of initialisation IDE ATA code |
;----------------------------------------------------------------------------- |
cmp [IDEContrProgrammingInterface], 0 |
je @f |
786,14 → 808,15 |
add dx, 2 ;0x376 |
out dx, al |
@@: |
; show base variables of IDE controller |
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 |
DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4 |
;----------------------------------------------------------------------------- |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
; mov esi, boot_detectdisks |
; call boot_log |
;include 'detect/disks.inc' |
mov esi, boot_detectfloppy |
call boot_log |
include 'detect/dev_fd.inc' |
mov esi, boot_detecthdcd |
call boot_log |
include 'detect/dev_hdcd.inc' |
803,8 → 826,132 |
mov esi, boot_detectpart |
call boot_log |
include 'detect/sear_par.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
;----------------------------------------------------------------------------- |
mov dx, [IDEContrRegsBaseAddr] |
; test whether it is our interrupt? |
add dx, 2 |
in al, dx |
test al, 100b |
jz @f |
; clear Bus Master IDE Status register |
; clear Interrupt bit |
out dx, al |
@@: |
add dx, 8 |
; test whether it is our interrupt? |
in al, dx |
test al, 100b |
jz @f |
; clear Bus Master IDE Status register |
; clear Interrupt bit |
out dx, al |
@@: |
; read status register and remove the interrupt request |
mov dx, [IDE_BAR0_val] ;0x1F0 |
add dx, 0x7 ;0x1F7 |
in al, dx |
mov dx, [IDE_BAR2_val] ;0x170 |
add dx, 0x7 ;0x177 |
in al, dx |
;----------------------------------------------------------------------------- |
push eax edx |
mov dx, [IDEContrRegsBaseAddr] |
xor eax, eax |
add dx, 2 |
in al, dx |
DEBUGF 1, "K : Primary Bus Master IDE Status Register %x\n", eax |
add dx, 8 |
in al, dx |
DEBUGF 1, "K : Secondary Bus Master IDE Status Register %x\n", eax |
pop edx eax |
cmp [IDEContrRegsBaseAddr], 0 |
setnz [dma_hdd] |
cmp [IDEContrProgrammingInterface], 0 |
je set_interrupts_for_IDE_controllers.continue |
;----------------------------------------------------------------------------- |
; set interrupts for IDE Controller |
;----------------------------------------------------------------------------- |
mov esi, boot_set_int_IDE |
call boot_log |
set_interrupts_for_IDE_controllers: |
mov ax, [IDEContrProgrammingInterface] |
cmp ax, 0x0180 |
je .pata_ide |
cmp ax, 0x018a |
jne .sata_ide |
;-------------------------------------- |
.pata_ide: |
cmp [IDEContrRegsBaseAddr], 0 |
je .end_set_interrupts |
stdcall attach_int_handler, 14, IDE_irq_14_handler, 0 |
DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax |
stdcall attach_int_handler, 15, IDE_irq_15_handler, 0 |
DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax |
jmp .enable_IDE_interrupt |
;-------------------------------------- |
.sata_ide: |
cmp ax, 0x0185 |
je .sata_ide_1 |
cmp ax, 0x018f |
jne .end_set_interrupts |
;-------------------------------------- |
.sata_ide_1: |
cmp [IDEContrRegsBaseAddr], 0 |
je .end_set_interrupts |
mov ax, [IDE_Interrupt] |
movzx eax, al |
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0 |
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [IDE_Interrupt]:1, eax |
;-------------------------------------- |
.enable_IDE_interrupt: |
mov esi, boot_enabling_ide |
call boot_log |
; Enable interrupts in IDE controller for DMA |
mov al, 0 |
mov ah, [DRIVE_DATA+1] |
test ah, 10100000b |
jz @f |
DEBUGF 1, "K : IDE CH1 PIO, because ATAPI drive present\n" |
jmp .ch2_check |
@@: |
mov dx, [IDE_BAR1_val] ;0x3F4 |
add dx, 2 ;0x3F6 |
out dx, al |
DEBUGF 1, "K : IDE CH1 DMA enabled\n" |
.ch2_check: |
test ah, 1010b |
jz @f |
DEBUGF 1, "K : IDE CH2 PIO, because ATAPI drive present\n" |
jmp .end_set_interrupts |
@@: |
mov dx, [IDE_BAR3_val] ;0x374 |
add dx, 2 ;0x376 |
out dx, al |
DEBUGF 1, "K : IDE CH2 DMA enabled\n" |
;-------------------------------------- |
.end_set_interrupts: |
;----------------------------------------------------------------------------- |
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: |
;----------------------------------------------------------------------------- |
; END of initialisation IDE ATA code |
;----------------------------------------------------------------------------- |
mov esi, boot_init_sys |
call boot_log |
call Parser_params |
817,7 → 964,6 |
include 'boot/rdload.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
end if |
; mov [dma_hdd],1 |
if 0 |
mov ax, [OS_BASE+0x10000+bx_from_load] |
871,34 → 1017,8 |
mov [pci_access_enabled], 1 |
call pci_enum |
;----------------------------------------------------------------------------- |
mov dx, [IDEContrRegsBaseAddr] |
; test whether it is our interrupt? |
add dx, 2 |
in al, dx |
test al, 100b |
jz @f |
; clear Bus Master IDE Status register |
; clear Interrupt bit |
out dx, al |
@@: |
add dx, 8 |
; test whether it is our interrupt? |
in al, dx |
test al, 100b |
jz @f |
; clear Bus Master IDE Status register |
; clear Interrupt bit |
out dx, al |
@@: |
; read status register and remove the interrupt request |
mov dx, [IDE_BAR0_val] ;0x1F0 |
add dx, 0x7 ;0x1F7 |
in al, dx |
mov dx, [IDE_BAR2_val] ;0x170 |
add dx, 0x7 ;0x177 |
in al, dx |
;----------------------------------------------------------------------------- |
call clear_pci_ide_interrupts |
include "detect/vortex86.inc" ; Vortex86 SoC detection code |
stdcall load_driver, szVidintel |
1069,7 → 1189,7 |
DEBUGF 1, "K : IRQ1 error code %x\n", eax |
.no_keyboard: |
; SET MOUSE |
; Load PS/2 mouse driver |
stdcall load_driver, szPS2MDriver |
; stdcall load_driver, szCOM_MDriver |
1079,17 → 1199,20 |
call setmouse |
; Setup serial output console (if enabled) |
if defined debug_com_base |
; reserve port so nobody else will use it |
xor ebx, ebx |
mov ecx, debug_com_base |
mov edx, debug_com_base+7 |
call r_f_port_area |
; enable Divisor latch |
mov dx, debug_com_base+3 |
mov al, 1 shl 7 |
out dx, al |
; Set speed to 115200 baud (max speed) |
mov dx, debug_com_base |
mov al, 0x01 |
out dx, al |
1099,43 → 1222,21 |
out dx, al |
; No parity, 8bits words, one stop bit, dlab bit back to 0 |
mov dx, debug_com_base+3 |
mov al, 3 |
out dx, al |
; disable interrupts |
mov dx, debug_com_base+1 |
mov al, 0 |
out dx, al |
; clear + enable fifo (64 bits) |
mov dx, debug_com_base+2 |
mov al, 0x7 + 1 shl 5 |
out dx, al |
end if |
mov eax, [version_inf.rev] |
DEBUGF 1, "K : kernel SVN r%d\n", eax |
mov eax, [cpu_count] |
test eax, eax |
jnz @F |
mov al, 1 ; at least one CPU |
@@: |
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 |
DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4 |
; START MULTITASKING |
; A 'All set - press ESC to start' messages if need |
1148,102 → 1249,6 |
jne .bll1 |
end if |
push eax edx |
mov dx, [IDEContrRegsBaseAddr] |
xor eax, eax |
add dx, 2 |
in al, dx |
DEBUGF 1, "K : Primary Bus Master IDE Status Register %x\n", eax |
add dx, 8 |
in al, dx |
DEBUGF 1, "K : Secondary Bus Master IDE Status Register %x\n", eax |
pop edx eax |
cmp [IDEContrRegsBaseAddr], 0 |
setnz [dma_hdd] |
cmp [IDEContrProgrammingInterface], 0 |
je set_interrupts_for_IDE_controllers.continue |
;----------------------------------------------------------------------------- |
; set interrupts for IDE Controller |
;----------------------------------------------------------------------------- |
mov esi, boot_set_int_IDE |
call boot_log |
set_interrupts_for_IDE_controllers: |
mov ax, [IDEContrProgrammingInterface] |
cmp ax, 0x0180 |
je .pata_ide |
cmp ax, 0x018a |
jne .sata_ide |
;-------------------------------------- |
.pata_ide: |
cmp [IDEContrRegsBaseAddr], 0 |
je .end_set_interrupts |
stdcall attach_int_handler, 14, IDE_irq_14_handler, 0 |
DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax |
stdcall attach_int_handler, 15, IDE_irq_15_handler, 0 |
DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax |
jmp .enable_IDE_interrupt |
;-------------------------------------- |
.sata_ide: |
cmp ax, 0x0185 |
je .sata_ide_1 |
cmp ax, 0x018f |
jne .end_set_interrupts |
;-------------------------------------- |
.sata_ide_1: |
cmp [IDEContrRegsBaseAddr], 0 |
je .end_set_interrupts |
mov ax, [IDE_Interrupt] |
movzx eax, al |
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0 |
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [IDE_Interrupt]:1, eax |
;-------------------------------------- |
.enable_IDE_interrupt: |
mov esi, boot_enabling_ide |
call boot_log |
; Enable interrupts in IDE controller for DMA |
mov al, 0 |
mov ah, [DRIVE_DATA+1] |
test ah, 10100000b |
jz @f |
DEBUGF 1, "K : IDE CH1 PIO, because ATAPI drive present\n" |
jmp .ch2_check |
@@: |
mov dx, [IDE_BAR1_val] ;0x3F4 |
add dx, 2 ;0x3F6 |
out dx, al |
DEBUGF 1, "K : IDE CH1 DMA enabled\n" |
.ch2_check: |
test ah, 1010b |
jz @f |
DEBUGF 1, "K : IDE CH2 PIO, because ATAPI drive present\n" |
jmp .end_set_interrupts |
@@: |
mov dx, [IDE_BAR3_val] ;0x374 |
add dx, 2 ;0x376 |
out dx, al |
DEBUGF 1, "K : IDE CH2 DMA enabled\n" |
;-------------------------------------- |
.end_set_interrupts: |
;----------------------------------------------------------------------------- |
cmp [dma_hdd], 0 |
je .print_pio |
.print_dma: |
DEBUGF 1, "K : IDE DMA mode\n" |
jmp .continue |
.print_pio: |
DEBUGF 1, "K : IDE PIO mode\n" |
.continue: |
mov [timer_ticks_enable], 1 ; for cd driver |
sti |
1946,22 → 1951,8 |
mov [esp+32], eax |
ret |
ngsyse5: |
; cmp eax,7 |
sub ebx, 2 |
jnz ngsyse7 |
xor eax, eax |
mov [esp+32], eax |
ret |
ngsyse7: |
; cmp eax,8 |
dec ebx |
jnz ngsyse8 |
mov eax, [fat32part] |
mov [esp+32], eax |
ret |
ngsyse8: |
; cmp eax,9 |
dec ebx |
sub ebx, 4 |
jnz ngsyse9 |
mov eax, [timer_ticks];[0xfdf0] |
mov [esp+32], eax |
2216,9 → 2207,6 |
movzx eax, word [MOUSE_Y] |
movzx ebx, word [MOUSE_X] |
; mov ecx, [Screen_Max_X] |
; inc ecx |
; mul ecx |
mov eax, [d_width_calc_area + eax*4] |
add eax, [_WinMapAddress] |
/kernel/branches/kolibri-process/network/ethernet.inc |
---|
86,11 → 86,7 |
push ebx |
mov esi, esp |
pushf |
cli |
add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail |
popf |
add esp, sizeof.ETH_queue_entry |
xor edx, edx |
102,10 → 98,9 |
ret |
.fail: |
popf |
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n" |
DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n" |
add esp, sizeof.ETH_queue_entry - 8 |
pop ebx |
call NET_packet_free |
add esp, 4 |
/kernel/branches/kolibri-process/network/queue.inc |
---|
28,7 → 28,6 |
size dd ? ; number of queued packets in this queue |
w_ptr dd ? ; current writing pointer in queue |
r_ptr dd ? ; current reading pointer |
mutex MUTEX |
ends |
47,18 → 46,12 |
local .ok, .no_wrap |
pusha |
lea ecx, [ptr + queue.mutex] |
call mutex_lock |
popa |
spin_lock_irqsave |
cmp [ptr + queue.size], size ; Check if queue isnt full |
jb .ok |
pusha |
lea ecx, [ptr + queue.mutex] |
call mutex_unlock |
popa |
spin_unlock_irqrestore |
jmp failaddr |
.ok: |
76,10 → 69,7 |
.no_wrap: |
mov [ptr + queue.w_ptr], edi |
pusha |
lea ecx, [ptr + queue.mutex] |
call mutex_unlock |
popa |
spin_unlock_irqrestore |
} |
89,18 → 79,12 |
local .ok, .no_wrap |
pusha |
lea ecx, [ptr + queue.mutex] |
call mutex_lock |
popa |
spin_lock_irqsave |
cmp [ptr + queue.size], 0 ; any packets queued? |
ja .ok |
pusha |
lea ecx, [ptr + queue.mutex] |
call mutex_unlock |
popa |
spin_unlock_irqrestore |
jmp failaddr |
.ok: |
122,10 → 106,7 |
pop esi |
pusha |
lea ecx, [ptr + queue.mutex] |
call mutex_unlock |
popa |
spin_unlock_irqrestore |
} |
136,6 → 117,4 |
mov [ptr + queue.w_ptr], edi |
mov [ptr + queue.r_ptr], edi |
lea ecx, [ptr + queue.mutex] |
call mutex_init |
} |
/kernel/branches/kolibri-process/network/socket.inc |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; Part of the TCP/IP network stack for KolibriOS ;; |
293,6 → 293,7 |
push ecx edx esi |
call SOCKET_alloc |
pop esi edx ecx |
test eax, eax |
jz .nobuffs |
mov [esp+32], edi ; return socketnumber |
697,7 → 698,7 |
test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state? |
jz @f |
call SOCKET_notify.unblock ; Unblock it. |
call SOCKET_notify ; Unblock it. |
@@: |
cmp [eax + SOCKET.Domain], AF_INET4 |
1192,6 → 1193,7 |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n" |
call SOCKET_alloc |
test eax, eax |
jz .nomem1 |
mov [esp+32], edi ; application's eax |
1204,6 → 1206,7 |
mov ebx, eax |
call SOCKET_alloc |
test eax, eax |
jz .nomem2 |
mov [esp+20], edi ; application's ebx |
1707,8 → 1710,9 |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax |
push eax |
pushf |
push eax |
cli |
; Set the 'socket is blocked' flag |
1724,12 → 1728,12 |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx |
mov [eax + SOCKET.TID], edx |
pop edx |
popf |
call change_task |
pop eax |
popf |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n" |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continuing\n" |
ret |
1752,70 → 1756,54 |
call SOCKET_check |
jz .error |
test [eax + SOCKET.state], SS_BLOCKED |
jnz .unblock |
; test [eax + SOCKET.options], SO_NONBLOCK |
; jz .error |
push eax ecx esi |
; socket exists and is of non blocking type. |
; We'll try to flag an event to the thread |
mov eax, [eax + SOCKET.TID] |
test eax, eax |
jz .done |
mov ecx, 1 |
mov esi, TASK_DATA + TASKDATA.pid |
.next_pid: |
cmp [esi], eax |
je .found_pid |
; Find the associated thread's TASK_DATA |
push ebx ecx esi |
mov ebx, [eax + SOCKET.TID] |
test ebx, ebx |
jz .error2 |
xor ecx, ecx |
inc ecx |
mov esi, TASK_DATA |
.next: |
cmp [esi + TASKDATA.pid], ebx |
je .found |
inc ecx |
add esi, 0x20 |
cmp ecx, [TASK_COUNT] |
jbe .next_pid |
jbe .next |
.error2: |
; PID not found, TODO: close socket! |
jmp .done |
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: error finding thread 0x%x !\n", ebx |
pop esi ecx ebx |
ret |
.found_pid: |
.error: |
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: invalid socket ptr: 0x%x !\n", eax |
ret |
.found: |
test [eax + SOCKET.state], SS_BLOCKED |
jnz .un_block |
; socket and thread exists and socket is of non blocking type. |
; We'll try to flag an event to the thread. |
shl ecx, 8 |
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax |
jmp .done |
pop esi ecx ebx |
ret |
.unblock: |
push eax ecx esi |
; Clear the 'socket is blocked' flag |
and [eax + SOCKET.state], not SS_BLOCKED |
; Find the thread's TASK_DATA |
mov eax, [eax + SOCKET.TID] |
test eax, eax |
jz .error |
xor ecx, ecx |
inc ecx |
mov esi, TASK_DATA |
.next: |
cmp [esi + TASKDATA.pid], eax |
je .found |
inc ecx |
add esi, 0x20 |
cmp ecx, [TASK_COUNT] |
jbe .next |
jmp .error |
.found: |
.un_block: |
; socket and thread exists and socket is of blocking type |
; We'll try to unblock it. |
and [eax + SOCKET.state], not SS_BLOCKED ; Clear the 'socket is blocked' flag |
mov [esi + TASKDATA.state], 0 ; Run the thread |
; Run the thread |
mov [esi + TASKDATA.state], 0 ; Running |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n" |
.done: |
pop esi ecx eax |
.error: |
pop esi ecx ebx |
ret |
1830,7 → 1818,6 |
; IN: / |
; OUT: eax = 0 on error, socket ptr otherwise |
; edi = socket number |
; ZF = cleared on error |
; |
;-------------------------------------------------------------------- |
align 4 |
1917,7 → 1904,6 |
@@: |
mov [net_sockets + SOCKET.NextPtr], eax |
or eax, eax ; used to clear zero flag |
pusha |
mov ecx, socket_mutex |
2022,6 → 2008,7 |
push ebx |
call SOCKET_alloc |
pop ebx |
test eax, eax |
jz .fail |
push eax |
2101,7 → 2088,8 |
call mutex_unlock |
popa |
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: not found\n", eax |
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: socket %u not found!\n", eax |
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: caller = 0x%x\n", [esp] |
ret |
/kernel/branches/kolibri-process/network/tcp_input.inc |
---|
43,11 → 43,7 |
push ebx ecx esi edi ; mind the order |
mov esi, esp |
pushf |
cli |
add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail |
popf |
add esp, sizeof.TCP_queue_entry |
call NET_ptr_to_num4 |
/kernel/branches/kolibri-process/network/tcp_usreq.inc |
---|
186,7 → 186,7 |
mov eax, [esp+4] |
mov [eax + SOCKET.errorcode], ETIMEDOUT |
and [eax + SOCKET.state], not SS_ISCONNECTING |
call SOCKET_notify.unblock |
call SOCKET_notify |
ret 4 |
.fail: |
/kernel/branches/kolibri-process/video/vesa20.inc |
---|
242,8 → 242,6 |
add edx, eax |
; pointer to pixel map |
mov eax, [putimg.abs_cy] |
; imul eax, [Screen_Max_X] |
; add eax, [putimg.abs_cy] |
mov eax, [d_width_calc_area + eax*4] |
add eax, [putimg.abs_cx] |
688,7 → 686,6 |
; for example drawwindow_III and drawwindow_IV |
; edi = 0x00000001 force |
;;; mov [novesachecksum], dword 0 |
pushad |
cmp [Screen_Max_X], eax |
jb .exit |
882,9 → 879,6 |
;----------------------------------------------------------------------------- |
align 4 |
calculate_edi: |
; mov edi, ebx |
; imul edi, [Screen_Max_X] |
; add edi, ebx |
mov edi, [d_width_calc_area + ebx*4] |
add edi, eax |
ret |