acpi: update

git-svn-id: svn://kolibrios.org@5201 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2014-12-01 03:51:07 +00:00
parent 1ae250fff2
commit e6265b4399
90 changed files with 8528 additions and 6039 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -16,6 +16,7 @@ DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable
DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters
DISK_STATUS_NO_MEDIA = 2 ; no media present
DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data
DISK_STATUS_NO_MEMORY = 4 ; insufficient memory for driver operation
; Driver flags. Represent bits in DISK.DriverFlags.
DISK_NO_INSERT_NOTIFICATION = 1
; Media flags. Represent bits in DISKMEDIAINFO.Flags.
@ -101,14 +102,13 @@ ends
; there are two distinct caches for a disk, one for "system" data,and the other
; for "application" data.
struct DISKCACHE
mutex MUTEX
; Lock to protect the cache.
; The following fields are inherited from data32.inc:cache_ideX.
pointer dd ?
data_size dd ? ; unused
data dd ?
sad_size dd ?
search_start dd ?
sector_size_log dd ?
ends
; This structure represents a disk device and its media for the kernel.
@ -169,6 +169,8 @@ struct DISK
; Pointer to array of .NumPartitions pointers to PARTITION structures.
cache_size dd ?
; inherited from cache_ideX_size
CacheLock MUTEX
; Lock to protect both caches.
SysCache DISKCACHE
AppCache DISKCACHE
; Two caches for the disk.
@ -270,13 +272,13 @@ disk_list_mutex MUTEX
endg
iglobal
; The function 'disk_scan_partitions' needs three 512-byte buffers for
; The function 'disk_scan_partitions' needs three sector-sized buffers for
; MBR, bootsector and fs-temporary sector data. It can not use the static
; buffers always, since it can be called for two or more disks in parallel.
; However, this case is not typical. We reserve three static 512-byte buffers
; and a flag that these buffers are currently used. If 'disk_scan_partitions'
; detects that the buffers are currently used, it allocates buffers from the
; heap.
; heap. Also, the heap is used when sector size is other than 512.
; The flag is implemented as a global dword variable. When the static buffers
; are not used, the value is -1. When the static buffers are used, the value
; is normally 0 and temporarily can become greater. The function increments
@ -637,28 +639,25 @@ disk_scan_partitions:
; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list.
and [esi+DISK.NumPartitions], 0
and [esi+DISK.Partitions], 0
; 2. Currently we can work only with 512-bytes sectors. Check this restriction.
; The only exception is 2048-bytes CD/DVD, but they are not supported yet by
; this code.
cmp [esi+DISK.MediaInfo.SectorSize], 512
jz .doscan
DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize]
ret
.doscan:
; 3. Acquire the buffer for MBR and bootsector tests. See the comment before
; 2. Acquire the buffer for MBR and bootsector tests. See the comment before
; the 'partition_buffer_users' variable.
mov eax, [esi+DISK.MediaInfo.SectorSize]
cmp eax, 512
jnz @f
mov ebx, mbr_buffer ; assume the global buffer is free
lock inc [partition_buffer_users]
jz .buffer_acquired ; yes, it is free
lock dec [partition_buffer_users] ; no, we must allocate
stdcall kernel_alloc, 512*3
@@:
lea eax, [eax*3]
stdcall kernel_alloc, eax
test eax, eax
jz .nothing
xchg eax, ebx
.buffer_acquired:
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no
; more than MAX_NUM_PARTITION times.
; 4. Prepare things for the loop.
; 3. Prepare things for the loop.
; ebp will hold the sector number for current MBR/EBR.
; [esp] will hold the sector number for current extended partition, if there
; is one.
@ -667,6 +666,10 @@ disk_scan_partitions:
push MAX_NUM_PARTITIONS ; the counter of max MBRs to process
xor ebp, ebp ; start from sector zero
push ebp ; no extended partition yet
; 4. MBR is 512 bytes long. If sector size is less than 512 bytes,
; assume no MBR, no partitions and go to 10.
cmp [esi+DISK.MediaInfo.SectorSize], 512
jb .notmbr
.new_mbr:
; 5. Read the current sector.
; Note that 'read' callback operates with 64-bit sector numbers, so we must
@ -985,7 +988,7 @@ end virtual
; a three-sectors-sized buffer. This function saves ebx in the stack
; immediately before ebp.
mov ebx, [ebp-4] ; get buffer
add ebx, 512 ; advance over MBR data to bootsector data
add ebx, [esi+DISK.MediaInfo.SectorSize] ; advance over MBR data to bootsector data
add ebp, 8 ; ebp points to part of PARTITION structure
xor eax, eax ; first sector of the partition
call fs_read32_sys
@ -996,7 +999,7 @@ end virtual
; ebp -> first three fields of PARTITION structure, .start, .length, .disk;
; [esp] = error code after bootsector read: 0 = ok, otherwise = failed,
; ebx points to the buffer for bootsector,
; ebx+512 points to 512-bytes buffer that can be used for anything.
; ebx+[esi+DISK.MediaInfo.SectorSize] points to sector-sized buffer that can be used for anything.
call fat_create_partition
test eax, eax
jnz .success

File diff suppressed because it is too large Load Diff

View File

@ -379,10 +379,16 @@ RecalibrateFDD:
mov al, 8
call FDCDataOutput
call FDCDataInput
push eax
; DEBUGF 1,' %x',al
call FDCDataInput
; DEBUGF 1,' %x',al
; DEBUGF 1,'\n'
pop eax
test al, 0xC0
jz @f
mov [FDC_Status], FDC_DiskNotFound
@@:
.fail:
call save_timer_fdd_motor
popa

View File

@ -17,7 +17,7 @@ hdbase dd ?
hdid dd ?
hdpos dd ?
ends
;-----------------------------------------------------------------------------
iglobal
align 4
ide_callbacks:
@ -35,18 +35,34 @@ hd0_data HD_DATA ?, 0, 1
hd1_data HD_DATA ?, 0x10, 2
hd2_data HD_DATA ?, 0, 3
hd3_data HD_DATA ?, 0x10, 4
hd4_data HD_DATA ?, 0, 5
hd5_data HD_DATA ?, 0x10, 6
hd6_data HD_DATA ?, 0, 7
hd7_data HD_DATA ?, 0x10, 8
hd8_data HD_DATA ?, 0, 9
hd9_data HD_DATA ?, 0x10, 10
hd10_data HD_DATA ?, 0, 11
hd11_data HD_DATA ?, 0x10, 12
hd_address_table:
dd 0x1f0, 0x00, 0x1f0, 0x10
dd 0x170, 0x00, 0x170, 0x10
ide_mutex_table:
dd ide_channel1_mutex
dd ide_channel2_mutex
dd ide_channel3_mutex
dd ide_channel4_mutex
dd ide_channel5_mutex
dd ide_channel6_mutex
endg
;-----------------------------------------------------------------------------
uglobal
ide_mutex MUTEX
ide_channel1_mutex MUTEX
ide_channel2_mutex MUTEX
ide_channel3_mutex MUTEX
ide_channel4_mutex MUTEX
ide_channel5_mutex MUTEX
ide_channel6_mutex MUTEX
endg
;-----------------------------------------------------------------------------
proc ide_read stdcall uses edi, \
hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data
@ -67,15 +83,13 @@ endl
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
mov ecx, ide_channel2_mutex
mov eax, [hd_data]
push ecx
mov ecx, [hd_address_table]
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0
pop ecx
jne .IDE_Channel_2
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov ecx, [hd_data]
mov ecx, [ecx+HD_DATA.hdpos]
dec ecx
shr ecx, 1
shl ecx, 2
mov ecx, [ecx + ide_mutex_table]
mov [channel_lock], ecx
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
@ -83,6 +97,7 @@ endl
; Worker procedures use global variables and edi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase]
@ -98,55 +113,65 @@ endl
; DMA read is permitted if [allow_dma_access]=1 or 2
cmp [allow_dma_access], 2
ja .nodma
cmp [dma_hdd], 1
jnz .nodma
;--------------------------------------
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jnz @f
test [DRIVE_DATA+1], byte 10100000b
push eax ecx
mov ecx, [hdpos]
dec ecx
shr ecx, 2
imul ecx, sizeof.IDE_DATA
add ecx, IDE_controller_1
mov [IDE_controller_pointer], ecx
mov eax, [hdpos]
dec eax
and eax, 11b
shr eax, 1
add eax, ecx
cmp [eax+IDE_DATA.dma_hdd_channel_1], 1
pop ecx eax
jnz .nodma
jmp .dma
@@:
test [DRIVE_DATA+1], byte 1010b
jnz .nodma
.dma:
;--------------------------------------
call hd_read_dma
jmp @f
;--------------------------------------
.nodma:
call hd_read_pio
;--------------------------------------
@@:
cmp [hd_error], 0
jnz .fail
mov ecx, [numsectors]
inc dword [ecx] ; one more sector is read
dec [sectors_todo]
jz .done
inc eax
jnz .sectors_loop
;--------------------------------------
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
;--------------------------------------
.done:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
;-----------------------------------------------------------------------------
proc ide_write stdcall uses esi edi, \
hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data
@ -167,15 +192,13 @@ endl
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
mov ecx, ide_channel2_mutex
mov eax, [hd_data]
push ecx
mov ecx, [hd_address_table]
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0
pop ecx
jne .IDE_Channel_2
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov ecx, [hd_data]
mov ecx, [ecx+HD_DATA.hdpos]
dec ecx
shr ecx, 1
shl ecx, 2
mov ecx, [ecx + ide_mutex_table]
mov [channel_lock], ecx
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
@ -183,6 +206,7 @@ endl
; Worker procedures use global variables and esi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase]
@ -200,66 +224,79 @@ endl
mov ecx, 16
cmp ecx, [sectors_todo]
jbe @f
mov ecx, [sectors_todo]
;--------------------------------------
@@:
mov [cache_chain_size], cl
; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2
jae .nodma
cmp [dma_hdd], 1
jnz .nodma
;--------------------------------------
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jnz @f
test [DRIVE_DATA+1], byte 10100000b
push eax ecx
mov ecx, [hdpos]
dec ecx
shr ecx, 2
imul ecx, sizeof.IDE_DATA
add ecx, IDE_controller_1
mov [IDE_controller_pointer], ecx
mov eax, [hdpos]
dec eax
and eax, 11b
shr eax, 1
add eax, ecx
cmp [eax+IDE_DATA.dma_hdd_channel_1], 1
pop ecx eax
jnz .nodma
jmp .dma
@@:
test [DRIVE_DATA+1], byte 1010b
jnz .nodma
.dma:
;--------------------------------------
call cache_write_dma
jmp .common
;--------------------------------------
.nodma:
mov [cache_chain_size], 1
call cache_write_pio
;--------------------------------------
.common:
cmp [hd_error], 0
jnz .fail
movzx ecx, [cache_chain_size]
mov eax, [numsectors]
add [eax], ecx
sub [sectors_todo], ecx
jz .done
add [edi], ecx
jc .fail
shl ecx, 9
add esi, ecx
jmp .sectors_loop
;--------------------------------------
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
;--------------------------------------
.done:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
;-----------------------------------------------------------------------------
; This is a stub.
proc ide_querymedia stdcall, hd_data, mediainfo
mov eax, [mediainfo]
@ -270,14 +307,12 @@ proc ide_querymedia stdcall, hd_data, mediainfo
xor eax, eax
ret
endp
;-----------------------------------------------------------------------------
align 4
; input: eax = sector, edi -> buffer
; output: edi = edi + 512
hd_read_pio:
push eax edx
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ;адрес регистра головок
@ -286,9 +321,9 @@ hd_read_pio:
out dx, al; номер головки/номер диска
call wait_for_hd_idle
cmp [hd_error], 0
jne hd_read_error
; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4]
cmp eax, 0x10000000
@ -372,7 +407,6 @@ hd_read_pio:
pushfd
cli
mov ecx, 256
mov edx, [hdbase]
cld
@ -393,6 +427,7 @@ cache_write_pio:
out dx, al ; номер головки/номер диска
call wait_for_hd_idle
cmp [hd_error], 0
jne hd_write_error
@ -550,13 +585,14 @@ wait_for_hd_idle:
align 4
wfhil1:
call check_hd_wait_timeout
cmp [hd_error], 0
jne @f
in al, dx
test al, 128
jnz wfhil1
;--------------------------------------
@@:
pop edx eax
ret
@ -573,6 +609,7 @@ wait_for_sector_buffer:
align 4
hdwait_sbuf: ; wait for sector buffer to be ready
call check_hd_wait_timeout
cmp [hd_error], 0
jne @f
@ -587,9 +624,10 @@ hdwait_sbuf: ; wait for sector buffer to be ready
test al, 1 ; previous command ended up with an error
jz buf_wait_ok
;--------------------------------------
@@:
mov [hd_error], 1
;--------------------------------------
buf_wait_ok:
pop edx eax
ret
@ -606,22 +644,17 @@ wait_for_sector_dma_ide0:
align 4
.wait:
call change_task
cmp [IDE_common_irq_param], 0
jz .done
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
popfd
;--------------------------------------
align 4
.done:
pop edx
pop eax
@ -636,23 +669,17 @@ wait_for_sector_dma_ide1:
align 4
.wait:
call change_task
cmp [IDE_common_irq_param], 0
jz .done
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
popfd
;--------------------------------------
align 4
.done:
pop edx
pop eax
@ -660,7 +687,8 @@ align 4
;-----------------------------------------------------------------------------
iglobal
align 4
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
; note that IDE descriptor table must be 4-byte aligned
; and do not cross 4K boundary
IDE_descriptor_table:
dd IDE_DMA
dw 0x2000
@ -673,19 +701,14 @@ endg
;-----------------------------------------------------------------------------
uglobal
; all uglobals are zeroed at boot
dma_process dd 0
dma_slot_ptr dd 0
cache_chain_pos dd 0
cache_chain_ptr dd 0
cache_chain_size db 0
cache_chain_started db 0
dma_task_switched db 0
dma_hdd db 0
allow_dma_access db 0
endg
;-----------------------------------------------------------------------------
align 4
IDE_irq_14_handler:
; DEBUGF 1, 'K : IDE_irq_14_handler %x\n', [IDE_common_irq_param]:2
cmp [IDE_common_irq_param], irq14_num
jne .exit
@ -693,7 +716,8 @@ IDE_irq_14_handler:
cli
pushad
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
; test whether it is our interrupt?
add edx, 2
in al, dx
@ -715,18 +739,17 @@ IDE_irq_14_handler:
mov al, 1
ret
;--------------------------------------
align 4
@@:
popad
popfd
;--------------------------------------
align 4
.exit:
mov al, 0
ret
;-----------------------------------------------------------------------------
align 4
IDE_irq_15_handler:
; DEBUGF 1, 'K : IDE_irq_15_handler %x\n', [IDE_common_irq_param]:2
cmp [IDE_common_irq_param], irq15_num
jne .exit
@ -734,7 +757,8 @@ IDE_irq_15_handler:
cli
pushad
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
add dx, 8
; test whether it is our interrupt?
add edx, 2
@ -757,26 +781,26 @@ IDE_irq_15_handler:
mov al, 1
ret
;--------------------------------------
align 4
@@:
popad
popfd
;--------------------------------------
align 4
.exit:
mov al, 0
ret
;-----------------------------------------------------------------------------
align 4
IDE_common_irq_handler:
; DEBUGF 1, 'K : IDE_common_irq_handler %x\n', [IDE_common_irq_param]:2
pushfd
cli
cmp [IDE_common_irq_param], 0
je .exit
pushfd
cli
pushad
xor ebx, ebx
mov dx, [IDEContrRegsBaseAddr]
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
mov eax, IDE_common_irq_param
cmp [eax], irq14_num
mov [eax], bl
@ -784,7 +808,6 @@ IDE_common_irq_handler:
add dx, 8
;--------------------------------------
align 4
@@:
; test whether it is our interrupt?
add edx, 2
@ -807,13 +830,11 @@ align 4
mov al, 1
ret
;--------------------------------------
align 4
@@:
popad
popfd
;--------------------------------------
align 4
.exit:
popfd
mov al, 0
ret
;-----------------------------------------------------------------------------
@ -824,26 +845,31 @@ hd_read_dma:
mov edx, [dma_hdpos]
cmp edx, [hdpos]
jne .notread
mov edx, [dma_cur_sector]
cmp eax, edx
jb .notread
add edx, 15
cmp [esp+4], edx
ja .notread
mov eax, [esp+4]
sub eax, [dma_cur_sector]
shl eax, 9
add eax, (OS_BASE+IDE_DMA)
push ecx esi
mov esi, eax
mov ecx, 512/4
cld
rep movsd
pop esi ecx
pop edx
pop eax
ret
;--------------------------------------
.notread:
; set data for PRD Table
mov eax, IDE_descriptor_table
@ -851,13 +877,18 @@ hd_read_dma:
mov word [eax+4], 0x2000
sub eax, OS_BASE
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
mov eax, [hdpos]
dec eax
test eax, 10b
pop eax
jz @f
add edx, 8
;--------------------------------------
@@:
push edx
; Bus Master IDE PRD Table Address
@ -881,9 +912,9 @@ hd_read_dma:
out dx, al ; номер головки/номер диска
call wait_for_hd_idle
cmp [hd_error], 0
jnz hd_read_error
; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4]
; -10h because the PreCache hits the boundary between lba28 and lba48
@ -961,47 +992,55 @@ hd_read_dma:
;--------------------------------------
.continue:
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
mov eax, [hdpos]
dec eax
test eax, 10b
jz @f
add dx, 8
;--------------------------------------
@@:
; set write to memory and Start Bus Master
mov al, 9
out dx, al
mov eax, [CURRENT_TASK]
mov [dma_process], eax
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
mov eax, [hdpos]
dec eax
test eax, 10b
jnz .ide1
mov [IDE_common_irq_param], irq14_num
jmp @f
;--------------------------------------
.ide1:
mov [IDE_common_irq_param], irq15_num
;--------------------------------------
@@:
popfd
; wait for interrupt
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
mov eax, [hdpos]
dec eax
test eax, 10b
jnz .wait_ide1
call wait_for_sector_dma_ide0
jmp @f
;--------------------------------------
.wait_ide1:
call wait_for_sector_dma_ide1
;--------------------------------------
@@:
cmp [hd_error], 0
jnz hd_read_error
mov eax, [hdpos]
mov [dma_hdpos], eax
pop edx
pop eax
mov [dma_cur_sector], eax
jmp hd_read_dma
;-----------------------------------------------------------------------------
@ -1011,6 +1050,7 @@ cache_write_dma:
; set data for PRD Table
mov eax, IDE_descriptor_table
mov edx, eax
pusha
mov edi, (OS_BASE+IDE_DMA)
mov dword [edx], IDE_DMA
@ -1021,15 +1061,21 @@ cache_write_dma:
cld
rep movsd
popa
sub eax, OS_BASE
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
mov eax, [hdpos]
dec eax
test eax, 10b
pop eax
jz @f
add edx, 8
;--------------------------------------
@@:
push edx
; Bus Master IDE PRD Table Address
@ -1053,9 +1099,9 @@ cache_write_dma:
out dx, al ; номер головки/номер диска
call wait_for_hd_idle
cmp [hd_error], 0
jnz hd_write_error_dma
; ATA with 28 or 48 bit for sector number?
mov esi, [cache_chain_ptr]
mov eax, [esi]
@ -1134,52 +1180,93 @@ cache_write_dma:
;--------------------------------------
.continue:
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
mov eax, [hdpos]
dec eax
test eax, 10b
jz @f
add dx, 8
;--------------------------------------
@@:
; set write to device and Start Bus Master
mov al, 1
out dx, al
mov eax, [CURRENT_TASK]
mov [dma_process], eax
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
mov eax, [hdpos]
dec eax
test eax, 10b
jnz .ide1
mov [IDE_common_irq_param], irq14_num
jmp @f
;--------------------------------------
.ide1:
mov [IDE_common_irq_param], irq15_num
;--------------------------------------
@@:
popfd
; wait for interrupt
mov [dma_cur_sector], not 0x40
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
mov eax, [hdpos]
dec eax
test eax, 10b
jnz .wait_ide1
call wait_for_sector_dma_ide0
jmp @f
;--------------------------------------
.wait_ide1:
call wait_for_sector_dma_ide1
;--------------------------------------
@@:
cmp [hd_error], 0
jnz hd_write_error_dma
pop esi
ret
;-----------------------------------------------------------------------------
uglobal
proc clear_pci_ide_interrupts
mov esi, pcidev_list
;--------------------------------------
align 4
IDE_Interrupt dw ?
IDEContrRegsBaseAddr dw ?
IDEContrProgrammingInterface dw ?
IDE_BAR0_val dw ?
IDE_BAR1_val dw ?
IDE_BAR2_val dw ?
IDE_BAR3_val dw ?
endg
.loop:
mov esi, [esi+PCIDEV.fd]
cmp esi, pcidev_list
jz .done
; cmp [esi+PCIDEV.class], 0x01018F
mov eax, [esi+PCIDEV.class]
shr eax, 4
cmp eax, 0x01018
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
;-----------------------------------------------------------------------------

View File

@ -41,53 +41,29 @@ find_empty_slot_CD_cache:
ret
;--------------------------------------------------------------------
clear_CD_cache:
DEBUGF 1, 'K : clear_CD_cache\n'
pusha
.ide0:
mov esi, [cdpos]
dec esi
imul esi, sizeof.IDE_CACHE
add esi, cache_ide0
xor eax, eax
cmp [cdpos], 1
jne .ide1
mov [cache_ide0_search_start], eax
mov ecx, [cache_ide0_system_sad_size]
mov edi, [cache_ide0_pointer]
mov [esi+IDE_CACHE.search_start], eax
mov ecx, [esi+IDE_CACHE.system_sad_size]
mov edi, [esi+IDE_CACHE.pointer]
call .clear
mov [cache_ide0_appl_search_start], eax
mov ecx, [cache_ide0_appl_sad_size]
mov edi, [cache_ide0_data_pointer]
jmp .continue
.ide1:
cmp [cdpos], 2
jne .ide2
mov [cache_ide1_search_start], eax
mov ecx, [cache_ide1_system_sad_size]
mov edi, [cache_ide1_pointer]
call .clear
mov [cache_ide1_appl_search_start], eax
mov ecx, [cache_ide1_appl_sad_size]
mov edi, [cache_ide1_data_pointer]
jmp .continue
.ide2:
cmp [cdpos], 3
jne .ide3
mov [cache_ide2_search_start], eax
mov ecx, [cache_ide2_system_sad_size]
mov edi, [cache_ide2_pointer]
call .clear
mov [cache_ide2_appl_search_start], eax
mov ecx, [cache_ide2_appl_sad_size]
mov edi, [cache_ide2_data_pointer]
jmp .continue
.ide3:
mov [cache_ide3_search_start], eax
mov ecx, [cache_ide3_system_sad_size]
mov edi, [cache_ide3_pointer]
call .clear
mov [cache_ide3_appl_search_start], eax
mov ecx, [cache_ide3_appl_sad_size]
mov edi, [cache_ide3_data_pointer]
.continue:
mov [esi+IDE_CACHE.appl_search_start], eax
mov ecx, [esi+IDE_CACHE.appl_sad_size]
mov edi, [esi+IDE_CACHE.data_pointer]
call .clear
popa
ret
;--------------------------------------
.clear:
shl ecx, 1
cld
@ -96,272 +72,131 @@ clear_CD_cache:
;--------------------------------------------------------------------
align 4
cd_calculate_cache:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
; 1 - IDE0 ... 12 - IDE11
push eax
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov esi, [cache_ide0_pointer]
jne @f
mov ecx, [eax+IDE_CACHE.system_sad_size]
mov esi, [eax+IDE_CACHE.pointer]
pop eax
ret
.ide0_appl_data:
mov ecx, [cache_ide0_appl_sad_size]
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx, [cache_ide1_appl_sad_size]
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx, [cache_ide2_appl_sad_size]
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx, [cache_ide3_appl_sad_size]
mov esi, [cache_ide3_data_pointer]
;--------------------------------------
@@:
mov ecx, [eax+IDE_CACHE.appl_sad_size]
mov esi, [eax+IDE_CACHE.data_pointer]
pop eax
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_1:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
; 1 - IDE0 ... 12 - IDE11
push eax
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov esi, [cache_ide0_pointer]
jne @f
mov esi, [eax+IDE_CACHE.pointer]
pop eax
ret
.ide0_appl_data:
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi, [cache_ide3_data_pointer]
;--------------------------------------
@@:
mov esi, [eax+IDE_CACHE.data_pointer]
pop eax
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_2:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
; 1 - IDE0 ... 12 - IDE11
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov eax, [cache_ide0_system_data]
jne @f
mov eax, [eax+IDE_CACHE.system_data]
ret
.ide0_appl_data:
mov eax, [cache_ide0_appl_data]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov eax, [cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax, [cache_ide1_appl_data]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov eax, [cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax, [cache_ide2_appl_data]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov eax, [cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax, [cache_ide3_appl_data]
;--------------------------------------
@@:
mov eax, [eax+IDE_CACHE.appl_data]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_3:
; mov ecx,cache_max*10/100
; mov edi,[cache_search_start]
; 1 - IDE0 ... 12 - IDE11
push eax
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov edi, [cache_ide0_search_start]
jne @f
mov edi, [eax+IDE_CACHE.search_start]
pop eax
ret
.ide0_appl_data:
mov edi, [cache_ide0_appl_search_start]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov edi, [cache_ide1_search_start]
ret
.ide1_appl_data:
mov edi, [cache_ide1_appl_search_start]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov edi, [cache_ide2_search_start]
ret
.ide2_appl_data:
mov edi, [cache_ide2_appl_search_start]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov edi, [cache_ide3_search_start]
ret
.ide3_appl_data:
mov edi, [cache_ide3_appl_search_start]
;--------------------------------------
@@:
mov edi, [eax+IDE_CACHE.appl_search_start]
pop eax
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_4:
; cmp edi,cache_max
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
; 1 - IDE0 ... 12 - IDE11
push eax
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0
jne .ide0_appl_data
cmp edi, [cache_ide0_system_sad_size]
jne @f
cmp edi, [eax+IDE_CACHE.system_sad_size]
pop eax
ret
.ide0_appl_data:
cmp edi, [cache_ide0_appl_sad_size]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
cmp edi, [cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi, [cache_ide1_appl_sad_size]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
cmp edi, [cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi, [cache_ide2_appl_sad_size]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
cmp edi, [cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi, [cache_ide3_appl_sad_size]
;--------------------------------------
@@:
cmp edi, [eax+IDE_CACHE.appl_sad_size]
pop eax
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_5:
; mov [cache_search_start],edi
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
; 1 - IDE0 ... 12 - IDE11
push eax
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov [cache_ide0_search_start], edi
jne @f
mov [eax+IDE_CACHE.search_start], edi
pop eax
ret
.ide0_appl_data:
mov [cache_ide0_appl_search_start], edi
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov [cache_ide1_search_start], edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start], edi
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov [cache_ide2_search_start], edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start], edi
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov [cache_ide3_search_start], edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start], edi
;--------------------------------------
@@:
mov [eax+IDE_CACHE.appl_search_start], edi
pop eax
ret
;--------------------------------------------------------------------
;align 4
;calculate_linear_to_real:
; shr eax, 12
; mov eax, [page_tabs+eax*4]
; and eax, 0xFFFFF000
; ret

View File

@ -22,11 +22,6 @@ ramdisk_functions:
.size = $ - ramdisk_functions
endg
; See memmap.inc.
; Currently size of memory allocated for the ramdisk is fixed.
; This should be revisited when/if memory map would become more dynamic.
RAMDISK_CAPACITY = 2880 ; in sectors
iglobal
align 4
ramdisk_actual_size dd RAMDISK_CAPACITY

View File

@ -394,145 +394,27 @@ sayerr:
push 0
popf
sti
; set up esp
movzx esp, sp
push 0
pop es
xor ax, ax
and word [es:BOOT_IDE_BASE_ADDR], ax ;0
and word [es:BOOT_IDE_BAR0_16], ax ;0
and word [es:BOOT_IDE_BAR1_16], ax ;0
and word [es:BOOT_IDE_BAR2_16], ax ;0
and word [es:BOOT_IDE_BAR3_16], ax ;0
; \begin{Mario79}
; find HDD IDE DMA PCI device
; check for PCI BIOS
mov ax, 0xB101
int 0x1A
jc .nopci
cmp edx, 'PCI '
jnz .nopci
; find PCI class code
; class 1 = mass storage
; subclass 1 = IDE controller
; a) class 1, subclass 1, programming interface 0x80
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x80
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1 ; Parallel IDE Controller
; b) class 1, subclass 1, programming interface 0x8f
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8f
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1
; c) class 1, subclass 1, programming interface 0x85
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x85
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1
; d) class 1, subclass 1, programming interface 0x8A
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8A
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1 ; Parallel IDE Controller
; Controller not found!
xor ax, ax
mov [es:BOOT_IDE_PI_16], ax
jmp .nopci
;--------------------------------------
.found_1:
; get memory base BAR4
mov ax, 0xB10A
mov di, 0x20 ; memory base is config register at 0x20
push cx
int 0x1A
jc .no_BAR4 ;.nopci
and cx, 0xFFFC ; clear address decode type
mov [es:BOOT_IDE_BASE_ADDR], cx
.no_BAR4:
pop cx
;--------------------------------------
.found:
; get Interrupt Line
mov ax, 0xB10A
mov di, 0x3c ; memory base is config register at 0x3c
push cx
int 0x1A
jc .no_Interrupt ;.nopci
mov [es:BOOT_IDE_INTERR_16], cx
.no_Interrupt:
pop cx
;--------------------------------------
; get memory base BAR0
mov ax, 0xB10A
mov di, 0x10 ; memory base is config register at 0x10
push cx
int 0x1A
jc .no_BAR0 ;.nopci
mov [es:BOOT_IDE_BAR0_16], cx
.no_BAR0:
pop cx
;--------------------------------------
; get memory base BAR1
mov ax, 0xB10A
mov di, 0x14 ; memory base is config register at 0x14
push cx
int 0x1A
jc .no_BAR1 ;.nopci
mov [es:BOOT_IDE_BAR1_16], cx
.no_BAR1:
pop cx
;--------------------------------------
; get memory base BAR2
mov ax, 0xB10A
mov di, 0x18 ; memory base is config register at 0x18
push cx
int 0x1A
jc .no_BAR2 ;.nopci
mov [es:BOOT_IDE_BAR2_16], cx
.no_BAR2:
pop cx
;--------------------------------------
; get memory base BAR3
mov ax, 0xB10A
mov di, 0x1C ; memory base is config register at 0x1c
push cx
int 0x1A
jc .no_BAR3 ;.nopci
mov [es:BOOT_IDE_BAR3_16], cx
.no_BAR3:
pop cx
;--------------------------------------
.nopci:
; \end{Mario79}
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование
out 0x60, al
xor cx, cx
wait_loop: ; variant 2
; reading state of port of 8042 controller
@@:
in al, 64h
and al, 00000010b ; ready flag
; wait until 8042 controller is ready
loopnz wait_loop
test al, 1
loopz @b
in al, 0x60
;;;/diamond today 5.02.2008
; set keyboard typematic rate & delay
@ -541,16 +423,19 @@ wait_loop: ; variant 2
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
test al, 1
loopz @b
in al, 0x60
mov al, 0
out 0x60, al
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
test al, 1
loopz @b
in al, 0x60
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sti
; --------------- APM ---------------------
and word [es:BOOT_APM_VERSION], 0 ; ver = 0.0 (APM not found)
mov ax, 0x5300

View File

@ -55,7 +55,7 @@ boot_dev db 0 ; 0=floppy, 1=hd
start_msg db "Press [abcde] to change settings, press [Enter] to continue booting",13,10,0
time_msg db " or wait "
time_str db " 5 seconds"
db " before automatical continuation",13,10,0
db " to continue automatically",13,10,0
current_cfg_msg db "Current settings:",13,10,0
curvideo_msg db " [a] Videomode: ",0

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -221,11 +221,13 @@ calc_vmodes_table:
cmp [es:mi.BitsPerPixel], 32 ;It show only videomodes to have support 24 and 32 bpp
jb @f
; cmp [es:mi.BitsPerPixel],16
; jne .l0
; cmp [es:mi.GreenMaskSize],5
; jne .l0
; 16 bpp might actually be 15 bpp
cmp [es:mi.BitsPerPixel], 16
jne .l0
cmp [es:mi.GreenMaskSize], 5
jne .l0
; mov [es:mi.BitsPerPixel],15
jmp @f ; 15 bpp isnt supported ATM
.l0:
@ -368,6 +370,8 @@ if defined extended_primary_loader
je .ok_found_mode
cmp word [es:si+8], 24
je .ok_found_mode
cmp word [es:si+8], 16
je .ok_found_mode
@@:
add si, size_of_step
cmp word [es:si], -1
@ -392,7 +396,8 @@ end if
; mov word [home_cursor],ax
; mov word [preboot_graph],ax
;SET default video of mode first probe will fined a move of work 1024x768@32
mov cx, 32
.find_mode:
mov ax, 1024
mov bx, 768
mov si, modes_table
@ -411,6 +416,8 @@ end if
call .loops
test ax, ax
jz .ok_found_mode
sub cx, 8
jnz .find_mode
mov si, modes_table
if ~ defined extended_primary_loader
@ -474,18 +481,15 @@ end if
jne .next
cmp bx, word [es:si+2]
jne .next
cmp word [es:si+8], 32
je .ok
cmp word [es:si+8], 24
je .ok
cmp cx, word [es:si+8]
jne .next
xor ax, ax
ret
.next:
add si, size_of_step
cmp word [es:si], -1
je .exit
jmp .loops
.ok:
xor ax, ax
ret
.exit:
or ax, -1
ret

View File

@ -9,10 +9,10 @@ $Revision$
read_ramdisk:
; READ RAMDISK IMAGE FROM HD
; READ RAMDISK IMAGE FROM HD (only for IDE0, IDE1, IDE2, IDE3)
cmp [boot_dev+OS_BASE+0x10000], 1
jne no_sys_on_hd
jne no_sys_on_hd.1
xor ebp, ebp
.hd_loop:
@ -69,9 +69,19 @@ read_ramdisk:
jb .hd_loop
jmp no_sys_on_hd
.yes:
DEBUGF 1, "K : RD found: %s\n", read_image_fsinfo.name
pop edi esi eax
jmp yes_sys_on_hd
call register_ramdisk
jmp yes_sys_on_hd
;-----------------------------------------------------------------------------
; Register ramdisk file system
register_ramdisk:
mov esi, boot_initramdisk
call boot_log
call ramdisk_init
ret
;-----------------------------------------------------------------------------
iglobal
align 4
read_image_fsinfo:
@ -79,7 +89,7 @@ read_image_fsinfo:
dq 0 ; offset: zero
dd 1474560 ; size
dd RAMDISK ; buffer
db '/hd'
.name db '/hd'
.name_digit db '0'
db '/'
.partition:
@ -99,6 +109,8 @@ read_image:
ret
no_sys_on_hd:
DEBUGF 1, "K : RD not found\n"
.1:
; test_to_format_ram_disk (need if not using ram disk)
cmp [boot_dev+OS_BASE+0x10000], 3
jne not_format_ram_disk

View File

@ -13,8 +13,24 @@
$Revision$
use32
become_real:
cli
lgdt [realmode_gdt-OS_BASE]
jmp 8:@f
use16
@@:
mov ax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, cr0
and eax, not 80000001h
mov cr0, eax
jmp 0x1000:pr_mode_exit
align 4
pr_mode_exit:
; setup stack
@ -166,7 +182,7 @@ restart_kernel_4000:
pop es
mov cx, 0x8000
push cx
push 0x7000
push 0x7100
pop ds
xor si, si
xor di, di

View File

@ -1,11 +1,10 @@
@echo off
cls
set languages=en ru ge et sp
set drivers=com_mouse emu10k1x fm801 infinity sis sound viasound vt823x
set targets=all kernel drivers clean
set targets=kernel clean
call :Check_Target %1
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2
for %%a in (kernel) do if %%a==%target% call :Check_Lang %2
call :Target_%target%
if ERRORLEVEL 0 goto Exit_OK
@ -56,51 +55,6 @@ goto :eof
goto :eof
:Target_all
call :Target_kernel
call :Target_drivers
goto :eof
:Target_drivers
echo *** building drivers ...
if not exist bin\drivers mkdir bin\drivers
cd drivers
for %%a in (%drivers%) do (
fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj
if not %errorlevel%==0 goto :Error_FasmFailed
)
cd ..
kpack >nul 2>&1
if %errorlevel%==9009 goto :Error_KpackFailed
echo *
echo ##############################################
echo *
echo Kpack KolibriOS drivers?
echo *
set /P res=[y/n]?
if "%res%"=="y" (
echo *
echo Compressing system
echo *
for %%a in (bin\drivers\*.obj) do (
echo ================== kpack %%a
kpack %%a
if not %errorlevel%==0 goto :Error_KpackFailed
)
)
goto :eof
:Target_clean
echo *** cleaning ...
rmdir /S /Q bin
@ -114,14 +68,6 @@ echo.
pause
exit 1
:Error_KpackFailed
echo *** NOTICE ***
echo If you want to pack all applications you may
echo place "kpack" in accessible directory or system %PATH%.
echo You can get this tool from KolibriOS distribution kit.
pause
exit 1
:Exit_OK
echo.
echo all operations have been done

View File

@ -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_BUFUNDERRUN = 13 ; underflow of internal controller buffer
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_CAN_FREE = 2
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 @@ NewDevice dd ?
; 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 @@ NextVirt dd ?
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 @@ DeviceDescrSize db ?
; 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 ?

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; USB Host Controller support code: hardware-independent part,
; common for all controller types.
@ -114,7 +124,7 @@ proc get_phys_addr
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 +138,17 @@ proc usb_subscribe_control
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,13 +275,18 @@ proc usb_process_one_wait_list
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
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.

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Support for USB (non-root) hubs:
; powering up/resetting/disabling ports,
; watching for adding/removing devices.

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Initialization of the USB subsystem.
; Provides usb_init procedure, includes all needed files.
@ -55,7 +65,7 @@ proc usb_init
mov esi, pcidev_list
push 0
.kickoff:
mov esi, [esi+PCIDEV.list.next]
mov esi, [esi+PCIDEV.fd]
cmp esi, pcidev_list
jz .done_kickoff
cmp word [esi+PCIDEV.class+1], 0x0C03
@ -108,7 +118,7 @@ proc usb_init
; for all EHCI controllers.
mov eax, pcidev_list
.scan_ehci:
mov eax, [eax+PCIDEV.list.next]
mov eax, [eax+PCIDEV.fd]
cmp eax, pcidev_list
jz .done_ehci
cmp [eax+PCIDEV.class], 0x0C0320
@ -120,7 +130,7 @@ proc usb_init
; for all UHCI and OHCI controllers.
mov eax, pcidev_list
.scan_usb1:
mov eax, [eax+PCIDEV.list.next]
mov eax, [eax+PCIDEV.fd]
cmp eax, pcidev_list
jz .done_usb1
cmp [eax+PCIDEV.class], 0x0C0300

View File

@ -1,3 +1,12 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Memory management for USB structures.
; Protocol layer uses the common kernel heap malloc/free.
; Hardware layer has special requirements:

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Functions for USB pipe manipulation: opening/closing, sending data etc.
;
USB_STDCALL_VERIFY = 1
@ -13,6 +23,11 @@ else
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 +253,17 @@ proc usb_close_pipe_nolock
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,36 +286,66 @@ proc usb_close_pipe_nolock
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
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,14 +396,23 @@ proc usb_pipe_closed
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
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 +429,74 @@ proc usb_pipe_closed
.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 +630,69 @@ endl
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

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5177 $
; Implementation of the USB protocol for device enumeration.
; Manage a USB device when it becomes ready for USB commands:
; configure, enumerate, load the corresponding driver(s),
@ -33,6 +43,19 @@ USB_INTERFACE_POWER_DESCR = 8
; 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,21 +202,36 @@ ends
; 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
; 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 +239,10 @@ proc usb_new_device
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 +265,14 @@ proc usb_new_device
; 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 +308,7 @@ proc usb_new_device
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 +321,29 @@ proc usb_new_device
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.
; Use the return value from usb_control_async as our return value;
; if it is zero, then something has failed.
; 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.
.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 +402,23 @@ endp
; 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
; Load data to registers for further references.
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 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 +427,49 @@ proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, l
; 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).
@ -642,7 +726,7 @@ end if
; 3d. Free old memory.
call free
pop eax
; 4. Issue control transfer GET_DESCRIPTOR(DEVICE) for full descriptor.
; 4. Issue control transfer GET_DESCRIPTOR(CONFIGURATION) for full descriptor.
movzx ecx, [eax+usb_device_data.DeviceDescrSize]
mov edx, [eax+usb_device_data.ConfigDataSize]
lea eax, [eax+ecx+sizeof.usb_device_data]

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -179,8 +179,7 @@ struct TSS
_io_map_1 rb 4096
ends
PARTITION_COUNT equ 64
DRIVE_DATA_SIZE equ (16+PARTITION_COUNT*100)
DRIVE_DATA_SIZE equ 16
OS_BASE equ 0x80000000
@ -205,7 +204,7 @@ FDD_BUFF equ (OS_BASE+0x000D000) ;512
WIN_TEMP_XY equ (OS_BASE+0x000F300)
KEY_COUNT equ (OS_BASE+0x000F400)
KEY_BUFF equ (OS_BASE+0x000F401)
KEY_BUFF equ (OS_BASE+0x000F401) ; 120*2 + 2*2 = 244 bytes, actually 255 bytes
BTN_COUNT equ (OS_BASE+0x000F500)
BTN_BUFF equ (OS_BASE+0x000F501)
@ -220,11 +219,7 @@ TASK_ACTIVATE equ (OS_BASE+0x000FF01)
TMP_STACK_TOP equ 0x006CC00
sys_pgdir equ (OS_BASE+0x006F000)
lfb_pd_0 equ (OS_BASE+0x0070000)
lfb_pd_1 equ (OS_BASE+0x0071000)
lfb_pd_2 equ (OS_BASE+0x0072000)
lfb_pd_3 equ (OS_BASE+0x0073000)
sys_proc equ (OS_BASE+0x006F000)
SLOT_BASE equ (OS_BASE+0x0080000)
@ -233,10 +228,6 @@ VGABasePtr equ (OS_BASE+0x00A0000)
CLEAN_ZONE equ (_CLEAN_ZONE-OS_BASE)
IDE_DMA equ (_IDE_DMA-OS_BASE)
; unused?
SB16Buffer equ (OS_BASE+0x02A0000)
SB16_Status equ (OS_BASE+0x02B0000)
UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000)
virtual at (OS_BASE+0x05FFF80)
@ -252,7 +243,7 @@ kernel_tabs equ (page_tabs+ (OS_BASE shr 10)) ;0xFDE00000
master_tab equ (page_tabs+ (page_tabs shr 10)) ;0xFDFF70000
LFB_BASE equ 0xFE000000
LFB_SIZE equ 12*1024*1024
new_app_base equ 0;
@ -277,6 +268,8 @@ REG_EDI equ (RING0_STACK_SIZE-52)
REG_RET equ (RING0_STACK_SIZE-56) ;irq0.return
PAGE_SIZE equ 4096
PG_UNMAP equ 0x000
PG_MAP equ 0x001
PG_WRITE equ 0x002
@ -306,7 +299,7 @@ BOOT_DEBUG_PRINT equ 0x901E ;byte If nonzero, duplicates debug output to
BOOT_DMA equ 0x901F ;
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no
BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr
;BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr ; now free and is not used
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount
BOOT_APM_ENTRY equ 0x9040
@ -315,12 +308,12 @@ BOOT_APM_FLAGS equ 0x9046 ;unused
BOOT_APM_CODE_32 equ 0x9050
BOOT_APM_CODE_16 equ 0x9052
BOOT_APM_DATA_16 equ 0x9054
BOOT_IDE_BAR0_16 equ 0x9056
BOOT_IDE_BAR1_16 equ 0x9058
BOOT_IDE_BAR2_16 equ 0x905A
BOOT_IDE_BAR3_16 equ 0x905C
BOOT_IDE_PI_16 equ 0x905E
BOOT_IDE_INTERR_16 equ 0x9060
;BOOT_IDE_BAR0_16 equ 0x9056 ; now free and is not used
;BOOT_IDE_BAR1_16 equ 0x9058 ; now free and is not used
;BOOT_IDE_BAR2_16 equ 0x905A ; now free and is not used
;BOOT_IDE_BAR3_16 equ 0x905C ; now free and is not used
;BOOT_IDE_PI_16 equ 0x905E ; now free and is not used
;BOOT_IDE_INTERR_16 equ 0x9060 ; now free and is not used
TMP_FILE_NAME equ 0
TMP_CMD_LINE equ 1024
@ -437,7 +430,7 @@ struct display_t
y dd ?
width dd ?
height dd ?
bpp dd ?
bits_per_pixel dd ?
vrefresh dd ?
pitch dd ?
lfb dd ?
@ -461,6 +454,8 @@ struct display_t
mask_seqno dd ?
check_mouse dd ?
check_m_pixel dd ?
bytes_per_pixel dd ?
ends
struct BOOT_DATA
@ -507,14 +502,13 @@ struct MUTEX
ends
struct PCIDEV
list LHEAD
vid_did dd ?
bk dd ?
fd dd ?
vendor_device_id dd ?
class dd ?
svid_sdid dd ?
devfn db ?
bus db ?
irq_line db ?
rb 1
rb 2
owner dd ? ; pointer to SRV or 0
ends
@ -625,6 +619,28 @@ struct COFF_SYM
NumAuxSymbols db ?
ends
struct STRIPPED_PE_HEADER
Signature dw ?
Characteristics dw ?
AddressOfEntryPoint dd ?
ImageBase dd ?
SectionAlignmentLog db ?
FileAlignmentLog db ?
MajorOSVersion db ?
MinorOSVersion db ?
SizeOfImage dd ?
SizeOfStackReserve dd ?
SizeOfHeapReserve dd ?
SizeOfHeaders dd ?
Subsystem db ?
NumberOfRvaAndSizes db ?
NumberOfSections dw ?
ends
STRIPPED_PE_SIGNATURE = 0x4503 ; 'PE' xor 'S'
SPE_DIRECTORY_IMPORT = 0
SPE_DIRECTORY_EXPORT = 1
SPE_DIRECTORY_BASERELOC = 2
struct IOCTL
handle dd ?
io_code dd ?

View File

@ -1,10 +1,12 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
iglobal
IRQ_COUNT dd 24

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
;------------------------------------------------------------------------------
align 4
sys_clipboard:

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Éste archivo debe ser editado con codificación CP866
ugui_mouse_speed cp850 'velocidad del ratón',0

View File

@ -136,9 +136,18 @@ debug_getcontext:
; ecx=pid
; edx=sizeof(CONTEXT)
; esi->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp edx, 28h
jnz .ret
; destroys eax,ebx,ecx,edx,esi,edi
xor ebx, ebx ; 0 - get only gp regs
cmp edx, 40
je .std_ctx
cmp edx, 48+288
jne .ret
inc ebx ; 1 - get sse context
; TODO legacy 32-bit FPU/MMX context
.std_ctx:
; push ecx
; mov ecx, esi
call check_region
@ -147,8 +156,15 @@ debug_getcontext:
jnz .ret
call get_debuggee_slot
jc .ret
shr eax, 5
cmp eax, [fpu_owner]
jne @f
inc bh ; set swap context flag
@@:
shl eax, 8
mov edi, esi
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
mov eax, [eax+SLOT_BASE+APPDATA.pl0_stack]
lea esi, [eax+RING0_STACK_SIZE]
.ring0:
@ -178,6 +194,29 @@ debug_getcontext:
mov [edi+4], eax
lodsd ;esp
mov [edi+18h], eax
dec bl
js .ret
dec bl
jns .ret
test bh, bh ; check swap flag
jz @F
ffree st0 ; swap context
@@:
add esi, 4 ;top of ring0 stack
;fpu/sse context saved here
add edi, 40
mov eax, 1 ;sse context
stosd
xor eax, eax ;reserved dword
stosd
mov ecx, 288/4
rep movsd ;copy sse context
.ret:
sti
ret

View File

@ -123,13 +123,13 @@ proc get_service stdcall, sz_name:dword
stdcall strncmp, edx, [sz_name], 16
test eax, eax
je .ok
mov eax, edx
je .nothing
mov edx, [edx+SRV.fd]
jmp @B
.not_load:
mov eax, [sz_name]
; Try to load .dll driver first. If not, fallback to .obj.
push edi
sub esp, 36
mov edi, esp
@ -150,12 +150,6 @@ proc get_service stdcall, sz_name:dword
stdcall load_pe_driver, edi, 0
add esp, 36
pop edi
test eax, eax
jnz .nothing
pop ebp
jmp load_driver
.ok:
mov eax, edx
.nothing:
ret
endp
@ -794,177 +788,6 @@ proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
ret
endp
align 4
proc load_driver stdcall, driver_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
start dd ?
file_name rb 13+16+4+1 ; '/sys/drivers/<up-to-16-chars>.obj'
endl
lea edx, [file_name]
mov dword [edx], '/sys'
mov dword [edx+4], '/dri'
mov dword [edx+8], 'vers'
mov byte [edx+12], '/'
mov esi, [driver_name]
.redo:
lea edx, [file_name]
lea edi, [edx+13]
mov ecx, 16
@@:
lodsb
test al, al
jz @f
stosb
loop @b
@@:
mov dword [edi], '.obj'
mov byte [edi+4], 0
stdcall load_file, edx
test eax, eax
jz .exit
mov [coff], eax
movzx ecx, [eax+COFF_HEADER.nSections]
xor ebx, ebx
lea edx, [eax+20]
@@:
add ebx, [edx+COFF_SECTION.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, sizeof.COFF_SECTION
dec ecx
jnz @B
mov [img_size], ebx
stdcall kernel_alloc, ebx
test eax, eax
jz .fail
mov [img_base], eax
mov edi, eax
xor eax, eax
mov ecx, [img_size]
add ecx, 4095
and ecx, not 4095
shr ecx, 2
cld
rep stosd
mov edx, [coff]
movzx ebx, [edx+COFF_HEADER.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+COFF_SECTION.VirtualAddress], edi
mov esi, [eax+COFF_SECTION.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+COFF_SECTION.SizeOfRawData]
jmp .next
.copy:
add esi, edx
mov ecx, [eax+COFF_SECTION.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15
and edi, not 15
add eax, sizeof.COFF_SECTION
dec ebx
jnz @B
mov ebx, [edx+COFF_HEADER.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+COFF_HEADER.nSymbols]
add ecx, ecx
lea ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
lea eax, [edx+20]
stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
[strings], __exports
test eax, eax
jz .link_fail
mov ebx, [coff]
stdcall fix_coff_relocs, ebx, [sym], 0
stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
test eax, eax
jz .link_fail
mov eax, [eax]
shr eax, 16
cmp eax, DRV_COMPAT
jb .ver_fail
cmp eax, DRV_CURRENT
ja .ver_fail
mov ebx, [coff]
stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
mov [start], eax
stdcall kernel_free, [coff]
mov ebx, [start]
stdcall ebx, DRV_ENTRY
test eax, eax
jnz .ok
stdcall kernel_free, [img_base]
xor eax, eax
ret
.ok:
mov ebx, [img_base]
mov [eax+SRV.base], ebx
mov ecx, [start]
mov [eax+SRV.entry], ecx
ret
.ver_fail:
mov esi, msg_CR
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov esi, msg_version
call sys_msg_board_str
mov esi, msg_www
call sys_msg_board_str
jmp .cleanup
.link_fail:
mov esi, msg_module
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
.cleanup:
stdcall kernel_free, [img_base]
.fail:
stdcall kernel_free, [coff]
.exit:
xor eax, eax
ret
endp
; in: edx -> COFF_SECTION struct
; out: eax = alignment as mask for bits to drop
coff_get_align:
@ -1009,10 +832,9 @@ proc load_library stdcall, file_name:dword
; ignore timestamp
cli
mov esi, [CURRENT_TASK]
shl esi, 8
mov esi, [current_process]
lea edi, [fullname]
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
mov ebx, [esi+PROC.dlls_list_ptr]
test ebx, ebx
jz .not_in_process
mov esi, [ebx+HDLL.fd]
@ -1372,28 +1194,21 @@ endp
; out: eax = APPDATA.dlls_list_ptr if all is OK,
; NULL if memory allocation failed
init_dlls_in_thread:
mov ebx, [current_slot]
mov eax, [ebx+APPDATA.dlls_list_ptr]
mov ebx, [current_process]
mov eax, [ebx+PROC.dlls_list_ptr]
test eax, eax
jnz .ret
push [ebx+APPDATA.dir_table]
mov eax, 8
call malloc
pop edx
call malloc ; FIXME
test eax, eax
jz .ret
mov [eax], eax
mov [eax+4], eax
mov ecx, [TASK_COUNT]
mov ebx, SLOT_BASE+256
.set:
cmp [ebx+APPDATA.dir_table], edx
jnz @f
mov [ebx+APPDATA.dlls_list_ptr], eax
@@:
add ebx, 256
dec ecx
jnz .set
mov ebx, [current_process]
mov [ebx+PROC.dlls_list_ptr], eax
.ret:
ret
@ -1414,59 +1229,10 @@ dereference_dll:
destroy_hdll:
push ebx ecx esi edi
push eax
mov ebx, [eax+HDLL.base]
mov esi, [eax+HDLL.parent]
mov edx, [esi+DLLDESCR.size]
; The following actions require the context of application where HDLL is mapped.
; However, destroy_hdll can be called in the context of OS thread when
; cleaning up objects created by the application which is destroyed.
; So remember current cr3 and set it to page table of target.
mov eax, [ecx+APPDATA.dir_table]
; Because we cheat with cr3, disable interrupts: task switch would restore
; page table from APPDATA of current thread.
; Also set [current_slot] because it is used by user_free.
pushf
cli
push [current_slot]
mov [current_slot], ecx
mov ecx, cr3
push ecx
mov cr3, eax
push ebx ; argument for user_free
mov eax, ebx
shr ebx, 12
push ebx
mov esi, [esi+DLLDESCR.data]
shr esi, 12
.unmap_loop:
push eax
mov eax, 2
xchg eax, [page_tabs+ebx*4]
mov ecx, [page_tabs+esi*4]
and eax, not 0xFFF
and ecx, not 0xFFF
cmp eax, ecx
jz @f
call free_page
@@:
pop eax
invlpg [eax]
add eax, 0x1000
inc ebx
inc esi
sub edx, 0x1000
ja .unmap_loop
pop ebx
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
call user_free
; Restore context.
pop eax
mov cr3, eax
pop [current_slot]
popf
; Ok, cheating is done.
pop eax
push eax
mov esi, [eax+HDLL.parent]
mov eax, [eax+HDLL.refcount]

View File

@ -7,11 +7,6 @@
$Revision$
iglobal
szKernel db 'KERNEL', 0
szVersion db 'version',0
endg
align 4
__exports:
export 'KERNEL', \
@ -48,6 +43,7 @@ __exports:
get_phys_addr, 'GetPhysAddr', \ ; eax
map_space, 'MapSpace', \
release_pages, 'ReleasePages', \
alloc_dma24, 'AllocDMA24', \ ; stdcall
\
mutex_init, 'MutexInit', \ ; gcc fastcall
mutex_lock, 'MutexLock', \ ; gcc fastcall
@ -94,6 +90,7 @@ __exports:
load_cursor, 'LoadCursor', \ ;stdcall
\
get_curr_task, 'GetCurrentTask', \
change_task, 'ChangeTask', \
load_file, 'LoadFile', \ ;retval eax, ebx
delay_ms, 'Sleep', \
\
@ -105,6 +102,7 @@ __exports:
strrchr, 'strrchr', \
\
timer_hs, 'TimerHS', \
timer_hs, 'TimerHs', \ ; shit happens
cancel_timer_hs, 'CancelTimerHS', \
\
reg_usb_driver, 'RegUSBDriver', \
@ -120,6 +118,8 @@ __exports:
NET_ptr_to_num, 'NetPtrToNum', \
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

View File

@ -129,15 +129,11 @@ proc init_kernel_heap
loop @B
stdcall alloc_pages, dword 32
or eax, PG_SW
mov ebx, HEAP_BASE
mov ecx, 32
mov edx, eax
mov edi, HEAP_BASE
.l1:
stdcall map_page, edi, edx, PG_SW
add edi, 0x1000
add edx, 0x1000
dec ecx
jnz .l1
call commit_pages
mov edi, HEAP_BASE ;descriptors
mov ebx, HEAP_BASE+sizeof.MEM_BLOCK ;free space
@ -480,46 +476,39 @@ proc kernel_alloc stdcall, size:dword
mov [pages_count], ebx
stdcall alloc_kernel_space, eax
mov [lin_addr], eax
mov ebx, [pages_count]
test eax, eax
jz .err
mov [lin_addr], eax
mov ecx, [pages_count]
mov edx, eax
mov ebx, ecx
shr ecx, 3
jz .next
shr ebx, 3
jz .tail
and ebx, not 7
push ebx
shl ebx, 3
stdcall alloc_pages, ebx
pop ecx ; yes ecx!!!
and eax, eax
test eax, eax
jz .err
mov edi, eax
mov edx, [lin_addr]
@@:
stdcall map_page, edx, edi, dword PG_SW
add edx, 0x1000
add edi, 0x1000
dec ecx
jnz @B
.next:
mov ecx, [pages_count]
and ecx, 7
mov ecx, ebx
or eax, PG_SW
mov ebx, [lin_addr]
call commit_pages
mov edx, ebx ; this dirty hack
.tail:
mov ebx, [pages_count]
and ebx, 7
jz .end
@@:
push ecx
call alloc_page
pop ecx
test eax, eax
jz .err
stdcall map_page, edx, eax, dword PG_SW
add edx, 0x1000
dec ecx
dec ebx
jnz @B
.end:
mov eax, [lin_addr]
@ -569,33 +558,36 @@ restore block_base
restore block_size
restore block_flags
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;; USER HEAP ;;;;;;;;;;;;;;;;;
HEAP_TOP equ 0x80000000
align 4
proc init_heap
mov ebx, [current_slot]
mov eax, [ebx+APPDATA.heap_top]
mov ebx, [current_process]
mov eax, [ebx+PROC.heap_top]
test eax, eax
jz @F
sub eax, [ebx+APPDATA.heap_base]
sub eax, 4096
sub eax, [ebx+PROC.heap_base]
sub eax, PAGE_SIZE
ret
@@:
mov esi, [ebx+APPDATA.mem_size]
lea ecx, [ebx+PROC.heap_lock]
call mutex_init
mov esi, [ebx+PROC.mem_used]
add esi, 4095
and esi, not 4095
mov [ebx+APPDATA.mem_size], esi
mov [ebx+PROC.mem_used], esi
mov eax, HEAP_TOP
mov [ebx+APPDATA.heap_base], esi
mov [ebx+APPDATA.heap_top], eax
mov [ebx+PROC.heap_base], esi
mov [ebx+PROC.heap_top], eax
sub eax, esi
shr esi, 10
mov ecx, eax
sub eax, 4096
sub eax, PAGE_SIZE
or ecx, FREE_BLOCK
mov [page_tabs+esi], ecx
ret
@ -608,25 +600,28 @@ proc user_alloc stdcall, alloc_size:dword
push esi
push edi
mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
mov ecx, [alloc_size]
add ecx, (4095+4096)
add ecx, (4095+PAGE_SIZE)
and ecx, not 4095
mov ebx, [current_slot]
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top
l_0:
mov esi, dword [ebx+PROC.heap_base] ; heap_base
mov edi, dword [ebx+PROC.heap_top] ; heap_top
.scan:
cmp esi, edi
jae m_exit
jae .m_exit
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
test al, FREE_BLOCK
jz test_used
jz .test_used
and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size
jb m_next
jb .m_next
jz @f
lea edx, [esi+ecx]
@ -648,12 +643,14 @@ l_0:
jnz @B
.no:
mov edx, [current_slot]
mov edx, [current_process]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
add [edx+PROC.mem_used], ebx
lea ecx, [edx+PROC.heap_lock]
call mutex_unlock
lea eax, [esi+4096]
@ -661,15 +658,19 @@ l_0:
pop esi
pop ebx
ret
test_used:
.test_used:
test al, USED_BLOCK
jz m_exit
jz .m_exit
and eax, 0xFFFFF000
m_next:
.m_next:
add esi, eax
jmp l_0
m_exit:
jmp .scan
.m_exit:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
xor eax, eax
pop edi
pop esi
@ -684,14 +685,17 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
push esi
push edi
mov ebx, [current_slot]
mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
mov edx, [address]
and edx, not 0xFFF
mov [address], edx
sub edx, 0x1000
jb .error
mov esi, [ebx+APPDATA.heap_base]
mov edi, [ebx+APPDATA.heap_top]
mov esi, [ebx+PROC.heap_base]
mov edi, [ebx+PROC.heap_top]
cmp edx, esi
jb .error
.scan:
@ -708,6 +712,10 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
mov esi, ecx
jmp .scan
.error:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
xor eax, eax
pop edi
pop esi
@ -759,13 +767,14 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
mov [page_tabs+ebx*4], ecx
.nothird:
mov edx, [current_slot]
mov edx, [current_process]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
add [edx+PROC.mem_used], ebx
lea ecx, [edx+PROC.heap_lock]
call mutex_unlock
mov eax, [address]
@ -782,10 +791,14 @@ proc user_free stdcall, base:dword
mov esi, [base]
test esi, esi
jz .exit
jz .fail
push ebx
mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
xor ebx, ebx
shr esi, 12
mov eax, [page_tabs+(esi-1)*4]
@ -821,25 +834,30 @@ proc user_free stdcall, base:dword
.released:
push edi
mov edx, [current_slot]
mov esi, dword [edx+APPDATA.heap_base]
mov edi, dword [edx+APPDATA.heap_top]
sub ebx, [edx+APPDATA.mem_size]
mov edx, [current_process]
lea ecx, [edx+PROC.heap_lock]
mov esi, dword [edx+PROC.heap_base]
mov edi, dword [edx+PROC.heap_top]
sub ebx, [edx+PROC.mem_used]
neg ebx
call update_mem_size
mov [edx+PROC.mem_used], ebx
call user_normalize
pop edi
pop ebx
pop esi
ret
.exit:
call mutex_unlock
xor eax, eax
inc eax
pop ebx
pop esi
ret
.cantfree:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
jmp .exit
.fail:
xor eax, eax
pop ebx
pop esi
ret
endp
@ -968,6 +986,13 @@ user_realloc:
ret
@@:
push ecx edx
push eax
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_lock
pop eax
lea ecx, [eax - 0x1000]
shr ecx, 12
mov edx, [page_tabs+ecx*4]
@ -975,6 +1000,10 @@ user_realloc:
jnz @f
; attempt to realloc invalid pointer
.ret0:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop edx ecx
xor eax, eax
ret
@ -1009,16 +1038,16 @@ user_realloc:
jnz .nofreeall
mov eax, [page_tabs+ecx*4]
and eax, not 0xFFF
mov edx, [current_slot]
mov ebx, [APPDATA.mem_size+edx]
mov edx, [current_process]
mov ebx, [edx+PROC.mem_used]
sub ebx, eax
add ebx, 0x1000
or al, FREE_BLOCK
mov [page_tabs+ecx*4], eax
push esi edi
mov esi, [APPDATA.heap_base+edx]
mov edi, [APPDATA.heap_top+edx]
call update_mem_size
mov esi, [edx+PROC.heap_base]
mov edi, [edx+PROC.heap_top]
mov [edx+PROC.mem_used], ebx
call user_normalize
pop edi esi
jmp .ret0 ; all freed
@ -1030,11 +1059,11 @@ user_realloc:
shr ebx, 12
sub ebx, edx
push ebx ecx edx
mov edx, [current_slot]
mov edx, [current_process]
shl ebx, 12
sub ebx, [APPDATA.mem_size+edx]
sub ebx, [edx+PROC.mem_used]
neg ebx
call update_mem_size
mov [edx+PROC.mem_used], ebx
pop edx ecx ebx
lea eax, [ecx+1]
shl eax, 12
@ -1044,8 +1073,8 @@ user_realloc:
shl ebx, 12
jz .ret
push esi
mov esi, [current_slot]
mov esi, [APPDATA.heap_top+esi]
mov esi, [current_process]
mov esi, [esi+PROC.heap_top]
shr esi, 12
@@:
cmp edx, esi
@ -1064,12 +1093,16 @@ user_realloc:
or ebx, FREE_BLOCK
mov [page_tabs+ecx*4], ebx
.ret:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop eax edx ecx
ret
.realloc_add:
; get some additional memory
mov eax, [current_slot]
mov eax, [APPDATA.heap_top+eax]
mov eax, [current_process]
mov eax, [eax+PROC.heap_top]
shr eax, 12
cmp edx, eax
jae .cant_inplace
@ -1101,17 +1134,21 @@ user_realloc:
cld
rep stosd
pop edi
mov edx, [current_slot]
mov edx, [current_process]
shl ebx, 12
add ebx, [APPDATA.mem_size+edx]
call update_mem_size
add [edx+PROC.mem_used], ebx
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop eax edx ecx
ret
.cant_inplace:
push esi edi
mov eax, [current_slot]
mov esi, [APPDATA.heap_base+eax]
mov edi, [APPDATA.heap_top+eax]
mov eax, [current_process]
mov esi, [eax+PROC.heap_base]
mov edi, [eax+PROC.heap_top]
shr esi, 12
shr edi, 12
sub ebx, ecx
@ -1174,58 +1211,25 @@ user_realloc:
jnz @b
.no:
push ebx
mov edx, [current_slot]
mov edx, [current_process]
shl ebx, 12
add ebx, [APPDATA.mem_size+edx]
call update_mem_size
add [edx+PROC.mem_used], ebx
pop ebx
@@:
mov dword [page_tabs+esi*4], 2
inc esi
dec ebx
jnz @b
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop eax edi esi edx ecx
ret
if 0
align 4
proc alloc_dll
pushf
cli
bsf eax, [dll_map]
jnz .find
popf
xor eax, eax
ret
.find:
btr [dll_map], eax
popf
shl eax, 5
add eax, dll_tab
ret
endp
align 4
proc alloc_service
pushf
cli
bsf eax, [srv_map]
jnz .find
popf
xor eax, eax
ret
.find:
btr [srv_map], eax
popf
shl eax, 0x02
lea eax, [srv_tab+eax+eax*8] ;srv_tab+eax*36
ret
endp
end if
;;;;;;;;;;;;;; SHARED ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;; SHARED MEMORY ;;;;;;;;;;;;;;;;;
; param

View File

@ -1,10 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
IRQ_RESERVED equ 24
IRQ_POOL_SIZE equ 48

View File

@ -123,19 +123,19 @@ proc alloc_pages stdcall, count:dword
endp
align 4
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
map_page:
push ebx
mov eax, [phis_addr]
mov eax, [esp+12] ; phis_addr
and eax, not 0xFFF
or eax, [flags]
mov ebx, [lin_addr]
or eax, [esp+16] ; flags
mov ebx, [esp+8] ; lin_addr
shr ebx, 12
mov [page_tabs+ebx*4], eax
mov eax, [lin_addr]
invlpg [eax]
mov eax, [esp+8] ; lin_addr
pop ebx
ret
endp
invlpg [eax]
ret 12
align 4
map_space: ;not implemented
@ -350,9 +350,64 @@ proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
ret
endp
uglobal
sb16_buffer_allocated db 0
endg
; Allocates [.size] bytes so that the target memory block
; is inside one 64K page for 24-bit DMA controller,
; that is, somewhere between 00xx0000h and 00xxFFFFh.
proc alloc_dma24
; Implementation note.
; The only user of that function is SB16 driver,
; so just return a statically allocated buffer.
virtual at esp
dd ? ; return address
.size dd ?
end virtual
cmp [sb16_buffer_allocated], 0
jnz .fail
inc [sb16_buffer_allocated]
mov eax, SB16Buffer
ret 4
.fail:
xor eax, eax
ret 4
endp
; Allocates a physical page for master page table
; that duplicates first Mb of OS_BASE at address 0;
; used for starting APs and for shutting down,
; where it is important to execute code in trivial-mapped pages.
; Returns eax = allocated physical page.
proc create_trampoline_pgmap
; The only non-trivial moment:
; we need a linear address to fill information,
; but we don't need it outside of this function,
; so we're returning physical address.
; Therefore, allocate memory with kernel_alloc,
; this will allocate physical page and a linear address somewhere,
; and deallocate only linear address with free_kernel_space.
stdcall kernel_alloc, 0x1000
mov edi, eax
mov esi, master_tab
mov ecx, 1024
rep movsd
mov ecx, [master_tab+(OS_BASE shr 20)]
mov [eax], ecx
mov edi, eax
call get_pg_addr
push eax
stdcall free_kernel_space, edi
pop eax
ret
endp
align 4
init_LFB:
xchg bx, bx
proc init_LFB
locals
pg_count dd ?
endl
cmp dword [LFBAddress], -1
jne @f
@ -381,33 +436,61 @@ init_LFB:
@@:
call init_mtrr
xor edx, edx
mov eax, [LFBAddress]
mov edx, LFB_BASE
mov esi, [LFBAddress]
mov edi, 0x00C00000
mov dword [exp_lfb+4], edx
shr edi, 12
mov [pg_count], edi
shr edi, 10
bt [cpu_caps], CAPS_PSE
jnc .map_page_tables
or esi, PG_LARGE+PG_UW
mov edx, sys_proc+PROC.pdt_0+(LFB_BASE shr 20)
@@:
mov [edx], esi
add edx, 4
add esi, 0x00400000
dec edi
jnz @B
bt [cpu_caps], CAPS_PGE
setc dh ;eliminate branch and
mov ecx, LFB_SIZE/4096
mov edi, lfb_pd_0
lea eax, [eax+edx+PG_UW] ;set PG_GLOBAL if supported
jnc @F
or dword [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)], PG_GLOBAL
@@:
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
.map_pte:
.map_page_tables:
@@:
call alloc_page
stdcall map_page_table, edx, eax
add edx, 0x00400000
dec edi
jnz @B
mov eax, [LFBAddress]
mov edi, page_tabs + (LFB_BASE shr 10)
or eax, PG_UW
mov ecx, [pg_count]
cld
@@:
stosd
add eax, 0x1000
loop .map_pte
dec ecx
jnz @B
mov ecx, (LFB_SIZE/4096)/1024
mov edi, sys_pgdir+(LFB_BASE shr 20)
lea eax, [(lfb_pd_0-OS_BASE)+PG_UW]
.map_pde:
stosd
add eax, 0x1000
loop .map_pde
mov dword [exp_lfb+4], LFB_BASE
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
endp
align 4
proc new_mem_resize stdcall, new_size:dword
@ -417,7 +500,9 @@ proc new_mem_resize stdcall, new_size:dword
push edi
mov edx, [current_slot]
cmp [edx+APPDATA.heap_base], 0
mov ebx, [edx+APPDATA.process]
cmp [ebx+PROC.heap_base], 0
jne .exit
mov edi, [new_size]
@ -425,7 +510,7 @@ proc new_mem_resize stdcall, new_size:dword
and edi, not 4095
mov [new_size], edi
mov esi, [edx+APPDATA.mem_size]
mov esi, [ebx+PROC.mem_used]
add esi, 4095
and esi, not 4095
@ -460,7 +545,8 @@ proc new_mem_resize stdcall, new_size:dword
.update_size:
mov edx, [current_slot]
mov ebx, [new_size]
call update_mem_size
mov edx, [edx+APPDATA.process]
mov [edx+PROC.mem_used], ebx
.exit:
pop edi
pop esi
@ -536,38 +622,6 @@ proc new_mem_resize stdcall, new_size:dword
endp
align 4
update_mem_size:
; in: edx = slot base
; ebx = new memory size
; destroys eax,ecx,edx
mov [APPDATA.mem_size+edx], ebx
;search threads and update
;application memory size infomation
mov ecx, [APPDATA.dir_table+edx]
mov eax, 2
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax, [TASK_COUNT]
jg .search_threads_end
mov edx, eax
shl edx, 5
cmp word [CURRENT_TASK+edx+TASKDATA.state], 9 ;if slot empty?
jz .search_threads_next
shl edx, 3
cmp [SLOT_BASE+edx+APPDATA.dir_table], ecx ;if it is our thread?
jnz .search_threads_next
mov [SLOT_BASE+edx+APPDATA.mem_size], ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
ret
; param
; eax= linear address
;
@ -624,11 +678,6 @@ end if
pop ebx ;restore exception number (#PF)
ret
; xchg bx, bx
; add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
; restore_ring3_context
; iretd
.user_space:
test eax, PG_MAP
jnz .err_access ;Страница присутствует
@ -668,9 +717,8 @@ end if
; access denied? this may be a result of copy-on-write protection for DLL
; check list of HDLLs
and ebx, not 0xFFF
mov eax, [CURRENT_TASK]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
mov eax, [current_process]
mov eax, [eax+PROC.dlls_list_ptr]
test eax, eax
jz .fail
mov esi, [eax+HDLL.fd]
@ -746,120 +794,129 @@ end if
endp
; returns number of mapped bytes
proc map_mem stdcall, lin_addr:dword,slot:dword,\
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
push 0 ; initialize number of mapped bytes
locals
count dd ?
process dd ?
endl
mov [count], 0
cmp [buf_size], 0
jz .exit
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
mov eax, [SLOT_BASE+eax+APPDATA.process]
test eax, eax
jz .exit
stdcall map_page, [ipc_pdir], eax, PG_UW
mov [process], eax
mov ebx, [ofs]
shr ebx, 22
mov esi, [ipc_pdir]
mov edi, [ipc_ptab]
mov eax, [esi+ebx*4]
mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table
mov esi, [ipc_ptab]
and eax, 0xFFFFF000
jz .exit
stdcall map_page, edi, eax, PG_UW
; inc ebx
; add edi, 0x1000
; mov eax, [esi+ebx*4]
; test eax, eax
; jz @f
; and eax, 0xFFFFF000
; stdcall map_page, edi, eax
stdcall map_page, esi, eax, PG_SW
@@:
mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
inc ecx ; ???????????
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [ipc_ptab]
.map:
stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit
add dword [ebp-4], 4096
add [ofs], 4096
add [count], PAGE_SIZE
add [ofs], PAGE_SIZE
dec ecx
jz .exit
add edi, 0x1000
add edi, PAGE_SIZE
inc edx
cmp edx, 0x400
cmp edx, 1024
jnz .map
inc ebx
mov eax, [ipc_pdir]
mov eax, [eax+ebx*4]
mov eax, [process]
mov eax, [eax+PROC.pdt_0+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page, esi, eax, PG_UW
stdcall map_page, esi, eax, PG_SW
xor edx, edx
jmp .map
.exit:
pop eax
mov eax, [count]
ret
endp
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
push 0 ; initialize number of mapped bytes
locals
count dd ?
process dd ?
endl
mov [count], 0
cmp [buf_size], 0
jz .exit
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
stdcall map_page, [proc_mem_pdir], eax, PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [proc_mem_pdir]
mov edi, [proc_mem_tab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
mov eax, [SLOT_BASE+eax+APPDATA.process]
test eax, eax
jz .exit
stdcall map_page, edi, eax, PG_UW
mov [process], eax
mov ebx, [ofs]
shr ebx, 22
mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table
mov esi, [proc_mem_tab]
and eax, 0xFFFFF000
jz .exit
stdcall map_page, esi, eax, PG_SW
@@:
mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
inc ecx ; ???????????
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [proc_mem_tab]
.map:
stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit
add dword [ebp-4], 0x1000
add edi, 0x1000
add [ofs], 0x1000
inc edx
add [count], PAGE_SIZE
add [ofs], PAGE_SIZE
dec ecx
jz .exit
add edi, PAGE_SIZE
inc edx
cmp edx, 1024
jnz .map
inc ebx
mov eax, [process]
mov eax, [eax+PROC.pdt_0+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page, esi, eax, PG_SW
xor edx, edx
jmp .map
.exit:
pop eax
mov eax, [count]
ret
endp
@ -905,7 +962,8 @@ proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
push ebx ecx
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
mov eax, [SLOT_BASE+eax+APPDATA.process]
mov eax, [eax+PROC.dlls_list_ptr]
test eax, eax
jz .no_hdll
mov ecx, [eax+HDLL.fd]
@ -992,29 +1050,6 @@ sys_IPC:
mov [esp+32], eax
ret
;align 4
;proc set_ipc_buff
; mov eax,[current_slot]
; pushf
; cli
; mov [eax+APPDATA.ipc_start],ebx ;set fields in extended information area
; mov [eax+APPDATA.ipc_size],ecx
;
; add ecx, ebx
; add ecx, 4095
; and ecx, not 4095
;
;.touch: mov eax, [ebx]
; add ebx, 0x1000
; cmp ebx, ecx
; jb .touch
;
; popf
; xor eax, eax
; ret
;endp
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
locals
dst_slot dd ?
@ -1033,7 +1068,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
mov [dst_slot], eax
shl eax, 8
mov edi, [eax+SLOT_BASE+0xa0] ;is ipc area defined?
mov edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined?
test edi, edi
jz .no_ipc_area
@ -1041,7 +1076,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
and ebx, 0xFFF
mov [dst_offset], ebx
mov esi, [eax+SLOT_BASE+0xa4]
mov esi, [eax+SLOT_BASE+APPDATA.ipc_size]
mov [buf_size], esi
mov ecx, [ipc_tmp]
@ -1054,7 +1089,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
pop edi esi
@@:
mov [used_buf], ecx
stdcall map_mem, ecx, [dst_slot], \
stdcall map_mem_ipc, ecx, [dst_slot], \
edi, esi, PG_SW
mov edi, [dst_offset]
@ -1125,7 +1160,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
.ret:
mov eax, [used_buf]
cmp eax, [ipc_tmp]
jz @f
je @f
stdcall free_kernel_space, eax
@@:
pop eax
@ -1329,113 +1364,6 @@ proc load_pe_driver stdcall, file:dword, cmdline:dword
ret
endp
align 4
proc init_mtrr
cmp [BOOT_VARS+BOOT_MTRR], byte 2
je .exit
bt [cpu_caps], CAPS_MTRR
jnc .exit
mov eax, cr0
or eax, 0x60000000 ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
mov ecx, 0x2FF
rdmsr ;
; has BIOS already initialized MTRRs?
test ah, 8
jnz .skip_init
; rarely needed, so mainly placeholder
; main memory - cached
push eax
mov eax, [MEM_AMOUNT]
; round eax up to next power of 2
dec eax
bsr ecx, eax
mov ebx, 2
shl ebx, cl
dec ebx
; base of memory range = 0, type of memory range = MEM_WB
xor edx, edx
mov eax, MEM_WB
mov ecx, 0x200
wrmsr
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
; clear unused MTRRs
xor eax, eax
xor edx, edx
@@:
inc ecx
wrmsr
cmp ecx, 0x20F
jb @b
; enable MTRRs
pop eax
or ah, 8
and al, 0xF0; default memtype = UC
mov ecx, 0x2FF
wrmsr
.skip_init:
stdcall set_mtrr, [LFBAddress], [LFBSize], MEM_WC
wbinvd ;again invalidate
mov eax, cr0
and eax, not 0x60000000
mov cr0, eax ; enable caching
.exit:
ret
endp
align 4
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
; find unused register
mov ecx, 0x201
@@:
rdmsr
dec ecx
test ah, 8
jz .found
rdmsr
mov al, 0; clear memory type field
cmp eax, [base]
jz .ret
add ecx, 3
cmp ecx, 0x210
jb @b
; no free registers, ignore the call
.ret:
ret
.found:
; found, write values
xor edx, edx
mov eax, [base]
or eax, [mem_type]
wrmsr
mov ebx, [size]
dec ebx
mov eax, 0xFFFFFFFF
mov edx, 0x00000000
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
ret
endp
align 4
proc create_ring_buffer stdcall, size:dword, flags:dword
locals

View File

@ -0,0 +1,881 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5130 $
; Initializes MTRRs.
proc init_mtrr
cmp [BOOT_VARS+BOOT_MTRR], byte 2
je .exit
bt [cpu_caps], CAPS_MTRR
jnc .exit
call mtrr_reconfigure
stdcall set_mtrr, [LFBAddress], 0x1000000, MEM_WC
.exit:
ret
endp
; Helper procedure for mtrr_reconfigure and set_mtrr,
; called before changes in MTRRs.
proc mtrr_begin_change
mov eax, cr0
or eax, 0x60000000 ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
ret
endp
; Helper procedure for mtrr_reconfigure and set_mtrr,
; called after changes in MTRRs.
proc mtrr_end_change
wbinvd ;again invalidate
mov eax, cr0
and eax, not 0x60000000
mov cr0, eax ; enable caching
ret
endp
; Some limits to number of structures located in the stack.
MAX_USEFUL_MTRRS = 16
MAX_RANGES = 16
; mtrr_reconfigure keeps a list of MEM_WB ranges.
; This structure describes one item in the list.
struct mtrr_range
next dd ? ; next item
start dq ? ; first byte
length dq ? ; length in bytes
ends
uglobal
align 4
num_variable_mtrrs dd 0 ; number of variable-range MTRRs
endg
; Helper procedure for MTRR initialization.
; Takes MTRR configured by BIOS and tries to recongifure them
; in order to allow non-UC data at top of 4G memory.
; Example: if low part of physical memory is 3.5G = 0xE0000000 bytes wide,
; BIOS can configure two MTRRs so that the first MTRR describes [0, 4G) as WB
; and the second MTRR describes [3.5G, 4G) as UC;
; WB+UC=UC, so the resulting memory map would be as needed,
; but in this configuration our attempts to map LFB at (say) 0xE8000000 as WC
; would be ignored, WB+UC+WC is still UC.
; So we must keep top of 4G memory not covered by MTRRs,
; using three WB MTRRs [0,2G) + [2G,3G) + [3G,3.5G),
; this gives the same memory map, but allows to add further entries.
; See mtrrtest.asm for detailed input/output from real hardware+BIOS.
proc mtrr_reconfigure
push ebp ; we're called from init_LFB, and it feels hurt when ebp is destroyed
; 1. Prepare local variables.
; 1a. Create list of MAX_RANGES free (aka not yet allocated) ranges.
xor eax, eax
lea ecx, [eax+MAX_RANGES]
.init_ranges:
sub esp, sizeof.mtrr_range - 4
push eax
mov eax, esp
dec ecx
jnz .init_ranges
mov eax, esp
; 1b. Fill individual local variables.
xor edx, edx
sub esp, MAX_USEFUL_MTRRS * 16 ; .mtrrs
push edx ; .mtrrs_end
push edx ; .num_used_mtrrs
push eax ; .first_free_range
push edx ; .first_range: no ranges yet
mov cl, [cpu_phys_addr_width]
or eax, -1
shl eax, cl ; note: this uses cl&31 = cl-32, not the entire cl
push eax ; .phys_reserved_mask
virtual at esp
.phys_reserved_mask dd ?
.first_range dd ?
.first_free_range dd ?
.num_used_mtrrs dd ?
.mtrrs_end dd ?
.mtrrs rq MAX_USEFUL_MTRRS * 2
.local_vars_size = $ - esp
end virtual
; 2. Get the number of variable-range MTRRs from MTRRCAP register.
; Abort if zero.
mov ecx, 0xFE
rdmsr
test al, al
jz .abort
mov byte [num_variable_mtrrs], al
; 3. Validate MTRR_DEF_TYPE register.
mov ecx, 0x2FF
rdmsr
; If BIOS has not initialized variable-range MTRRs, fallback to step 7.
test ah, 8
jz .fill_ranges_from_memory_map
; If the default memory type (not covered by MTRRs) is not UC,
; then probably BIOS did something strange, so it is better to exit immediately
; hoping for the best.
cmp al, MEM_UC
jnz .abort
; 4. Validate all variable-range MTRRs
; and copy configured MTRRs to the local array [.mtrrs].
; 4a. Prepare for the loop over existing variable-range MTRRs.
mov ecx, 0x200
lea edi, [.mtrrs]
.get_used_mtrrs_loop:
; 4b. For every MTRR, read PHYSBASEn and PHYSMASKn.
; In PHYSBASEn, clear upper bits and copy to ebp:ebx.
rdmsr
or edx, [.phys_reserved_mask]
xor edx, [.phys_reserved_mask]
mov ebp, edx
mov ebx, eax
inc ecx
; If PHYSMASKn is not active, ignore this MTRR.
rdmsr
inc ecx
test ah, 8
jz .get_used_mtrrs_next
; 4c. For every active MTRR, check that number of local entries is not too large.
inc [.num_used_mtrrs]
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
ja .abort
; 4d. For every active MTRR, store PHYSBASEn with upper bits cleared.
; This contains the MTRR base and the memory type in low byte.
mov [edi], ebx
mov [edi+4], ebp
; 4e. For every active MTRR, check that the range is continuous:
; PHYSMASKn with upper bits set must be negated power of two, and
; low bits of PHYSBASEn must be zeroes:
; PHYSMASKn = 1...10...0,
; PHYSBASEn = x...x0...0,
; this defines a continuous range from x...x0...0 to x...x1...1,
; length = 10...0 = negated PHYSMASKn.
; Store length in the local array.
and eax, not 0xFFF
or edx, [.phys_reserved_mask]
mov dword [edi+8], 0
mov dword [edi+12], 0
sub [edi+8], eax
sbb [edi+12], edx
; (x and -x) is the maximum power of two that divides x.
; Condition for powers of two: (x and -x) equals x.
and eax, [edi+8]
and edx, [edi+12]
cmp eax, [edi+8]
jnz .abort
cmp edx, [edi+12]
jnz .abort
sub eax, 1
sbb edx, 0
and eax, not 0xFFF
and eax, ebx
jnz .abort
and edx, ebp
jnz .abort
; 4f. For every active MTRR, validate memory type: it must be either WB or UC.
add edi, 16
cmp bl, MEM_UC
jz .get_used_mtrrs_next
cmp bl, MEM_WB
jnz .abort
.get_used_mtrrs_next:
; 4g. Repeat the loop at 4b-4f for all [num_variable_mtrrs] entries.
mov eax, [num_variable_mtrrs]
lea eax, [0x200+eax*2]
cmp ecx, eax
jb .get_used_mtrrs_loop
; 4h. If no active MTRRs were detected, fallback to step 7.
cmp [.num_used_mtrrs], 0
jz .fill_ranges_from_memory_map
mov [.mtrrs_end], edi
; 5. Generate sorted list of ranges marked as WB.
; 5a. Prepare for the loop over configured MTRRs filled at step 4.
lea ecx, [.mtrrs]
.fill_wb_ranges:
; 5b. Ignore non-WB MTRRs.
mov ebx, [ecx]
cmp bl, MEM_WB
jnz .next_wb_range
mov ebp, [ecx+4]
and ebx, not 0xFFF ; clear memory type and reserved bits
; ebp:ebx = start of the range described by the current MTRR.
; 5c. Find the first existing range containing a point greater than ebp:ebx.
lea esi, [.first_range]
.find_range_wb:
; If there is no next range or start of the next range is greater than ebp:ebx,
; exit the loop to 5d.
mov edi, [esi]
test edi, edi
jz .found_place_wb
mov eax, ebx
mov edx, ebp
sub eax, dword [edi+mtrr_range.start]
sbb edx, dword [edi+mtrr_range.start+4]
jb .found_place_wb
; Otherwise, if end of the next range is greater than or equal to ebp:ebx,
; exit the loop to 5e.
mov esi, edi
sub eax, dword [edi+mtrr_range.length]
sbb edx, dword [edi+mtrr_range.length+4]
jb .expand_wb
or eax, edx
jnz .find_range_wb
jmp .expand_wb
.found_place_wb:
; 5d. ebp:ebx is not within any existing range.
; Insert a new range between esi and edi.
; (Later, during 5e, it can be merged with the following ranges.)
mov eax, [.first_free_range]
test eax, eax
jz .abort
mov [esi], eax
mov edx, [eax+mtrr_range.next]
mov [.first_free_range], edx
mov dword [eax+mtrr_range.start], ebx
mov dword [eax+mtrr_range.start+4], ebp
; Don't fill [eax+mtrr_range.next] and [eax+mtrr_range.length] yet,
; they will be calculated including merges at step 5e.
mov esi, edi
mov edi, eax
.expand_wb:
; 5e. The range at edi contains ebp:ebx, and esi points to the first range
; to be checked for merge: esi=edi if ebp:ebx was found in an existing range,
; esi is next after edi if a new range with ebp:ebx was created.
; Merge it with following ranges while start of the next range is not greater
; than the end of the new range.
add ebx, [ecx+8]
adc ebp, [ecx+12]
; ebp:ebx = end of the range described by the current MTRR.
.expand_wb_loop:
; If there is no next range or start of the next range is greater than ebp:ebx,
; exit the loop to 5g.
test esi, esi
jz .expand_wb_done
mov eax, ebx
mov edx, ebp
sub eax, dword [esi+mtrr_range.start]
sbb edx, dword [esi+mtrr_range.start+4]
jb .expand_wb_done
; Otherwise, if end of the next range is greater than or equal to ebp:ebx,
; exit the loop to 5f.
sub eax, dword [esi+mtrr_range.length]
sbb edx, dword [esi+mtrr_range.length+4]
jb .expand_wb_last
; Otherwise, the current range is completely within the new range.
; Free it and continue the loop.
mov edx, [esi+mtrr_range.next]
cmp esi, edi
jz @f
mov eax, [.first_free_range]
mov [esi+mtrr_range.next], eax
mov [.first_free_range], esi
@@:
mov esi, edx
jmp .expand_wb_loop
.expand_wb_last:
; 5f. Start of the new range is inside range described by esi,
; end of the new range is inside range described by edi.
; If esi is equal to edi, the new range is completely within
; an existing range, so proceed to the next range.
cmp esi, edi
jz .next_wb_range
; Otherwise, set end of interval at esi to end of interval at edi
; and free range described by edi.
mov ebx, dword [esi+mtrr_range.start]
mov ebp, dword [esi+mtrr_range.start+4]
add ebx, dword [esi+mtrr_range.length]
adc ebp, dword [esi+mtrr_range.length+4]
mov edx, [esi+mtrr_range.next]
mov eax, [.first_free_range]
mov [esi+mtrr_range.next], eax
mov [.first_free_range], esi
mov esi, edx
.expand_wb_done:
; 5g. We have found the next range (maybe 0) after merging and
; the new end of range (maybe ebp:ebx from the new range
; or end of another existing interval calculated at step 5f).
; Write them to range at edi.
mov [edi+mtrr_range.next], esi
sub ebx, dword [edi+mtrr_range.start]
sbb ebp, dword [edi+mtrr_range.start+4]
mov dword [edi+mtrr_range.length], ebx
mov dword [edi+mtrr_range.length+4], ebp
.next_wb_range:
; 5h. Continue the loop 5b-5g over all configured MTRRs.
add ecx, 16
cmp ecx, [.mtrrs_end]
jb .fill_wb_ranges
; 6. Exclude all ranges marked as UC.
; 6a. Prepare for the loop over configured MTRRs filled at step 4.
lea ecx, [.mtrrs]
.fill_uc_ranges:
; 6b. Ignore non-UC MTRRs.
mov ebx, [ecx]
cmp bl, MEM_UC
jnz .next_uc_range
mov ebp, [ecx+4]
and ebx, not 0xFFF ; clear memory type and reserved bits
; ebp:ebx = start of the range described by the current MTRR.
lea esi, [.first_range]
; 6c. Find the first existing range containing a point greater than ebp:ebx.
.find_range_uc:
; If there is no next range, ignore this MTRR,
; exit the loop and continue to next MTRR.
mov edi, [esi]
test edi, edi
jz .next_uc_range
; If start of the next range is greater than or equal to ebp:ebx,
; exit the loop to 6e.
mov eax, dword [edi+mtrr_range.start]
mov edx, dword [edi+mtrr_range.start+4]
sub eax, ebx
sbb edx, ebp
jnb .truncate_uc
; Otherwise, continue the loop if end of the next range is less than ebp:ebx,
; exit the loop to 6d otherwise.
mov esi, edi
add eax, dword [edi+mtrr_range.length]
adc edx, dword [edi+mtrr_range.length+4]
jnb .find_range_uc
; 6d. ebp:ebx is inside (or at end of) an existing range.
; Split the range. (The second range, maybe containing completely within UC-range,
; maybe of zero length, can be removed at step 6e, if needed.)
mov edi, [.first_free_range]
test edi, edi
jz .abort
mov dword [edi+mtrr_range.start], ebx
mov dword [edi+mtrr_range.start+4], ebp
mov dword [edi+mtrr_range.length], eax
mov dword [edi+mtrr_range.length+4], edx
mov eax, [edi+mtrr_range.next]
mov [.first_free_range], eax
mov eax, [esi+mtrr_range.next]
mov [edi+mtrr_range.next], eax
; don't change [esi+mtrr_range.next] yet, it will be filled at step 6e
mov eax, ebx
mov edx, ebp
sub eax, dword [esi+mtrr_range.start]
sbb edx, dword [esi+mtrr_range.start+4]
mov dword [esi+mtrr_range.length], eax
mov dword [esi+mtrr_range.length+4], edx
.truncate_uc:
; 6e. edi is the first range after ebp:ebx, check it and next ranges
; for intersection with the new range, truncate heads.
add ebx, [ecx+8]
adc ebp, [ecx+12]
; ebp:ebx = end of the range described by the current MTRR.
.truncate_uc_loop:
; If start of the next range is greater than ebp:ebx,
; exit the loop to 6g.
mov eax, ebx
mov edx, ebp
sub eax, dword [edi+mtrr_range.start]
sbb edx, dword [edi+mtrr_range.start+4]
jb .truncate_uc_done
; Otherwise, if end of the next range is greater than ebp:ebx,
; exit the loop to 6f.
sub eax, dword [edi+mtrr_range.length]
sbb edx, dword [edi+mtrr_range.length+4]
jb .truncate_uc_last
; Otherwise, the current range is completely within the new range.
; Free it and continue the loop if there is a next range.
; If that was a last range, exit the loop to 6g.
mov edx, [edi+mtrr_range.next]
mov eax, [.first_free_range]
mov [.first_free_range], edi
mov [edi+mtrr_range.next], eax
mov edi, edx
test edi, edi
jnz .truncate_uc_loop
jmp .truncate_uc_done
.truncate_uc_last:
; 6f. The range at edi partially intersects with the UC-range described by MTRR.
; Truncate it from the head.
mov dword [edi+mtrr_range.start], ebx
mov dword [edi+mtrr_range.start+4], ebp
neg eax
adc edx, 0
neg edx
mov dword [edi+mtrr_range.length], eax
mov dword [edi+mtrr_range.length+4], edx
.truncate_uc_done:
; 6g. We have found the next range (maybe 0) after intersection.
; Write it to [esi+mtrr_range.next].
mov [esi+mtrr_range.next], edi
.next_uc_range:
; 6h. Continue the loop 6b-6g over all configured MTRRs.
add ecx, 16
cmp ecx, [.mtrrs_end]
jb .fill_uc_ranges
; Sanity check: if there are no ranges after steps 5-6,
; fallback to step 7. Otherwise, go to 8.
cmp [.first_range], 0
jnz .ranges_ok
.fill_ranges_from_memory_map:
; 7. BIOS has not configured variable-range MTRRs.
; Create one range from 0 to [MEM_AMOUNT].
mov eax, [.first_free_range]
mov edx, [eax+mtrr_range.next]
mov [.first_free_range], edx
mov [.first_range], eax
xor edx, edx
mov [eax+mtrr_range.next], edx
mov dword [eax+mtrr_range.start], edx
mov dword [eax+mtrr_range.start+4], edx
mov ecx, [MEM_AMOUNT]
mov dword [eax+mtrr_range.length], ecx
mov dword [eax+mtrr_range.length+4], edx
.ranges_ok:
; 8. We have calculated list of WB-ranges.
; Now we should calculate a list of MTRRs so that
; * every MTRR describes a range with length = power of 2 and start that is aligned,
; * every MTRR can be WB or UC
; * (sum of all WB ranges) minus (sum of all UC ranges) equals the calculated list
; * top of 4G memory must not be covered by any ranges
; Example: range [0,0xBC000000) can be converted to
; [0,0x80000000)+[0x80000000,0xC0000000)-[0xBC000000,0xC0000000)
; WB +WB -UC
; but not to [0,0x100000000)-[0xC0000000,0x100000000)-[0xBC000000,0xC0000000).
; 8a. Check that list of ranges is [0,something) plus, optionally, [4G,something).
; This holds in practice (see mtrrtest.asm for real-life examples)
; and significantly simplifies the code: ranges are independent, start of range
; is almost always aligned (the only exception >4G upper memory can be easily covered),
; there is no need to consider adding holes before start of range, only
; append them to end of range.
xor eax, eax
mov edi, [.first_range]
cmp dword [edi+mtrr_range.start], eax
jnz .abort
cmp dword [edi+mtrr_range.start+4], eax
jnz .abort
cmp dword [edi+mtrr_range.length+4], eax
jnz .abort
mov edx, [edi+mtrr_range.next]
test edx, edx
jz @f
cmp dword [edx+mtrr_range.start], eax
jnz .abort
cmp dword [edx+mtrr_range.start+4], 1
jnz .abort
cmp [edx+mtrr_range.next], eax
jnz .abort
@@:
; 8b. Initialize: no MTRRs filled.
mov [.num_used_mtrrs], eax
lea esi, [.mtrrs]
.range2mtrr_loop:
; 8c. If we are dealing with upper-memory range (after 4G)
; with length > start, create one WB MTRR with [start,2*start),
; reset start to 2*start and return to this step.
; Example: [4G,24G) -> [4G,8G) {returning} + [8G,16G) {returning}
; + [16G,24G) {advancing to ?}.
mov eax, dword [edi+mtrr_range.length+4]
test eax, eax
jz .less4G
mov edx, dword [edi+mtrr_range.start+4]
cmp eax, edx
jb .start_aligned
inc [.num_used_mtrrs]
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
ja .abort
mov dword [esi], MEM_WB
mov dword [esi+4], edx
mov dword [esi+8], 0
mov dword [esi+12], edx
add esi, 16
add dword [edi+mtrr_range.start+4], edx
sub dword [edi+mtrr_range.length+4], edx
jnz .range2mtrr_loop
cmp dword [edi+mtrr_range.length], 0
jz .range2mtrr_next
.less4G:
; 8d. If we are dealing with low-memory range (before 4G)
; and appending a maximal-size hole would create a range covering top of 4G,
; create a maximal-size WB range and return to this step.
; Example: for [0,0xBC000000) the following steps would consider
; variants [0,0x80000000)+(another range to be splitted) and
; [0,0x100000000)-(another range to be splitted); we forbid the last variant,
; so the first variant must be used.
bsr ecx, dword [edi+mtrr_range.length]
xor edx, edx
inc edx
shl edx, cl
lea eax, [edx*2]
add eax, dword [edi+mtrr_range.start]
jnz .start_aligned
inc [.num_used_mtrrs]
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
ja .abort
mov eax, dword [edi+mtrr_range.start]
mov dword [esi], eax
or dword [esi], MEM_WB
mov dword [esi+4], 0
mov dword [esi+8], edx
mov dword [esi+12], 0
add esi, 16
add dword [edi+mtrr_range.start], edx
sub dword [edi+mtrr_range.length], edx
jnz .less4G
jmp .range2mtrr_next
.start_aligned:
; Start is aligned for any allowed length, maximum-size hole is allowed.
; Select the best MTRR configuration for one range.
; length=...101101
; Without hole at the end, we need one WB MTRR for every 1-bit in length:
; length=...100000 + ...001000 + ...000100 + ...000001
; We can also append one hole at the end so that one 0-bit (selected by us)
; becomes 1 and all lower bits become 0 for WB-range:
; length=...110000 - (...00010 + ...00001)
; In this way, we need one WB MTRR for every 1-bit higher than the selected bit,
; one WB MTRR for the selected bit, one UC MTRR for every 0-bit between
; the selected bit and lowest 1-bit (they become 1-bits after negation)
; and one UC MTRR for lowest 1-bit.
; So we need to select 0-bit with the maximal difference
; (number of 0-bits) - (number of 1-bits) between selected and lowest 1-bit,
; this equals the gain from using a hole. If the difference is negative for
; all 0-bits, don't append hole.
; Note that lowest 1-bit is not included when counting, but selected 0-bit is.
; 8e. Find the optimal bit position for hole.
; eax = current difference, ebx = best difference,
; ecx = hole bit position, edx = current bit position.
xor eax, eax
xor ebx, ebx
xor ecx, ecx
bsf edx, dword [edi+mtrr_range.length]
jnz @f
bsf edx, dword [edi+mtrr_range.length+4]
add edx, 32
@@:
push edx ; save position of lowest 1-bit for step 8f
.calc_stat:
inc edx
cmp edx, 64
jae .stat_done
inc eax ; increment difference in hope for 1-bit
; Note: bt conveniently works with both .length and .length+4,
; depending on whether edx>=32.
bt dword [edi+mtrr_range.length], edx
jc .calc_stat
dec eax ; hope was wrong, decrement difference to correct 'inc'
dec eax ; and again, now getting the real difference
cmp eax, ebx
jle .calc_stat
mov ebx, eax
mov ecx, edx
jmp .calc_stat
.stat_done:
; 8f. If we decided to create a hole, flip all bits between lowest and selected.
pop edx ; restore position of lowest 1-bit saved at step 8e
test ecx, ecx
jz .fill_hi_init
@@:
inc edx
cmp edx, ecx
ja .fill_hi_init
btc dword [edi+mtrr_range.length], edx
jmp @b
.fill_hi_init:
; 8g. Create MTRR ranges corresponding to upper 32 bits.
sub ecx, 32
.fill_hi_loop:
bsr edx, dword [edi+mtrr_range.length+4]
jz .fill_hi_done
inc [.num_used_mtrrs]
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
ja .abort
mov eax, dword [edi+mtrr_range.start]
mov [esi], eax
mov eax, dword [edi+mtrr_range.start+4]
mov [esi+4], eax
xor eax, eax
mov [esi+8], eax
bts eax, edx
mov [esi+12], eax
cmp edx, ecx
jl .fill_hi_uc
or dword [esi], MEM_WB
add dword [edi+mtrr_range.start+4], eax
jmp @f
.fill_hi_uc:
sub dword [esi+4], eax
sub dword [edi+mtrr_range.start+4], eax
@@:
add esi, 16
sub dword [edi+mtrr_range.length], eax
jmp .fill_hi_loop
.fill_hi_done:
; 8h. Create MTRR ranges corresponding to lower 32 bits.
add ecx, 32
.fill_lo_loop:
bsr edx, dword [edi+mtrr_range.length]
jz .range2mtrr_next
inc [.num_used_mtrrs]
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
ja .abort
mov eax, dword [edi+mtrr_range.start]
mov [esi], eax
mov eax, dword [edi+mtrr_range.start+4]
mov [esi+4], eax
xor eax, eax
mov [esi+12], eax
bts eax, edx
mov [esi+8], eax
cmp edx, ecx
jl .fill_lo_uc
or dword [esi], MEM_WB
add dword [edi+mtrr_range.start], eax
jmp @f
.fill_lo_uc:
sub dword [esi], eax
sub dword [edi+mtrr_range.start], eax
@@:
add esi, 16
sub dword [edi+mtrr_range.length], eax
jmp .fill_lo_loop
.range2mtrr_next:
; 8i. Repeat the loop at 8c-8h for all ranges.
mov edi, [edi+mtrr_range.next]
test edi, edi
jnz .range2mtrr_loop
; 9. We have calculated needed MTRRs, now setup them in the CPU.
; 9a. Abort if number of MTRRs is too large.
mov eax, [num_variable_mtrrs]
cmp [.num_used_mtrrs], eax
ja .abort
; 9b. Prepare for changes.
call mtrr_begin_change
; 9c. Prepare for loop over MTRRs.
lea esi, [.mtrrs]
mov ecx, 0x200
@@:
; 9d. For every MTRR, copy PHYSBASEn as is: step 8 has configured
; start value and type bits as needed.
mov eax, [esi]
mov edx, [esi+4]
wrmsr
inc ecx
; 9e. For every MTRR, calculate PHYSMASKn = -(length) or 0x800
; with upper bits cleared, 0x800 = MTRR is valid.
xor eax, eax
xor edx, edx
sub eax, [esi+8]
sbb edx, [esi+12]
or eax, 0x800
or edx, [.phys_reserved_mask]
xor edx, [.phys_reserved_mask]
wrmsr
inc ecx
; 9f. Continue steps 9d and 9e for all MTRRs calculated at step 8.
add esi, 16
dec [.num_used_mtrrs]
jnz @b
; 9g. Zero other MTRRs.
xor eax, eax
xor edx, edx
mov ebx, [num_variable_mtrrs]
lea ebx, [0x200+ebx*2]
@@:
cmp ecx, ebx
jae @f
wrmsr
inc ecx
wrmsr
inc ecx
jmp @b
@@:
; 9i. Configure MTRR_DEF_TYPE.
mov ecx, 0x2FF
rdmsr
or ah, 8 ; enable variable-ranges MTRR
and al, 0xF0; default memtype = UC
wrmsr
; 9j. Changes are done.
call mtrr_end_change
.abort:
add esp, .local_vars_size + MAX_RANGES * sizeof.mtrr_range
pop ebp
ret
endp
; Allocate&set one MTRR for given range.
; size must be power of 2 that divides base.
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
; find unused register
mov ecx, 0x201
.scan:
rdmsr
dec ecx
test ah, 8
jz .found
rdmsr
test edx, edx
jnz @f
and eax, not 0xFFF ; clear reserved bits
cmp eax, [base]
jz .ret
@@:
add ecx, 3
mov eax, [num_variable_mtrrs]
lea eax, [0x200+eax*2]
cmp ecx, eax
jb .scan
; no free registers, ignore the call
.ret:
ret
.found:
; found, write values
call mtrr_begin_change
xor edx, edx
mov eax, [base]
or eax, [mem_type]
wrmsr
mov al, [cpu_phys_addr_width]
xor edx, edx
bts edx, eax
xor eax, eax
sub eax, [size]
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
call mtrr_end_change
ret
endp
; Helper procedure for mtrr_validate.
; Calculates memory type for given address according to variable-range MTRRs.
; Assumes that MTRRs are enabled.
; in: ebx = 32-bit physical address
; out: eax = memory type for ebx
proc mtrr_get_real_type
; 1. Initialize: we have not yet found any MTRRs covering ebx.
push 0
mov ecx, 0x201
.mtrr_loop:
; 2. For every MTRR, check whether it is valid; if not, continue to the next MTRR.
rdmsr
dec ecx
test ah, 8
jz .next
; 3. For every valid MTRR, check whether (ebx and PHYSMASKn) == PHYSBASEn,
; excluding low 12 bits.
and eax, ebx
push eax
rdmsr
test edx, edx
pop edx
jnz .next
xor edx, eax
and edx, not 0xFFF
jnz .next
; 4. If so, set the bit corresponding to memory type defined by this MTRR.
and eax, 7
bts [esp], eax
.next:
; 5. Continue loop at 2-4 for all variable-range MTRRs.
add ecx, 3
mov eax, [num_variable_mtrrs]
lea eax, [0x200+eax*2]
cmp ecx, eax
jb .mtrr_loop
; 6. If no MTRRs cover address in ebx, use default MTRR type from MTRR_DEF_CAP.
pop edx
test edx, edx
jz .default
; 7. Find&clear 1-bit in edx.
bsf eax, edx
btr edx, eax
; 8. If there was only one 1-bit, then all MTRRs are consistent, return that bit.
test edx, edx
jz .nothing
; Otherwise, return MEM_UC (e.g. WB+UC is UC).
xor eax, eax
.nothing:
ret
.default:
mov ecx, 0x2FF
rdmsr
movzx eax, al
ret
endp
; If MTRRs are configured improperly, this is not obvious to the user;
; everything works, but the performance can be horrible.
; Try to detect this and let the user know that the low performance
; is caused by some problem and is not a global property of the system.
; Let's hope he would report it to developers...
proc mtrr_validate
; 1. If MTRRs are not supported, they cannot be configured improperly.
; Note: VirtualBox claims MTRR support in cpuid, but emulates MTRRCAP=0,
; which is efficiently equivalent to absent MTRRs.
; So check [num_variable_mtrrs] instead of CAPS_MTRR in [cpu_caps].
cmp [num_variable_mtrrs], 0
jz .exit
; 2. If variable-range MTRRs are not configured, this is a problem.
mov ecx, 0x2FF
rdmsr
test ah, 8
jz .fail
; 3. Get the memory type for address somewhere inside working memory.
; It must be write-back.
mov ebx, 0x27FFFF
call mtrr_get_real_type
cmp al, MEM_WB
jnz .fail
; 4. If we're using a mode with LFB,
; get the memory type for last pixel of the framebuffer.
; It must be write-combined.
test word [SCR_MODE], 0x4000
jz .exit
mov eax, [_display.pitch]
mul [_display.height]
dec eax
; LFB is mapped to virtual address LFB_BASE,
; it uses global pages if supported by CPU.
mov ebx, [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)]
test ebx, PG_LARGE
jnz @f
mov ebx, [page_tabs+(LFB_BASE shr 10)]
@@:
and ebx, not 0xFFF
add ebx, eax
call mtrr_get_real_type
cmp al, MEM_WC
jz .exit
; 5. The check at step 4 fails on Bochs:
; Bochs BIOS configures MTRRs in a strange way not respecting [cpu_phys_addr_width],
; so mtrr_reconfigure avoids to touch anything.
; However, Bochs core ignores MTRRs (keeping them only for rdmsr/wrmsr),
; so we don't care about proper setting for Bochs.
; Use northbridge PCI id to detect Bochs: it emulates either i440fx or i430fx
; depending on configuration file.
mov eax, [pcidev_list.fd]
cmp eax, pcidev_list ; sanity check: fail if no PCI devices
jz .fail
cmp [eax+PCIDEV.vendor_device_id], 0x12378086
jz .exit
cmp [eax+PCIDEV.vendor_device_id], 0x01228086
jnz .fail
.exit:
ret
.fail:
mov ebx, mtrr_user_message
mov ebp, notifyapp
call fs_execute_from_sysdir_param
ret
endp

View File

@ -24,15 +24,30 @@ proc load_PE stdcall, file_name:dword
mov [image], eax
mov edx, [eax+60]
mov edx, [eax+STRIPPED_PE_HEADER.SizeOfImage]
; mov cl, [eax+STRIPPED_PE_HEADER.Subsystem]
cmp word [eax], STRIPPED_PE_SIGNATURE
jz @f
stdcall kernel_alloc, [eax+80+edx]
mov edx, [eax+60]
; mov cl, [eax+5Ch+edx]
mov edx, [eax+80+edx]
@@:
mov [entry], 0
; cmp cl, 1
; jnz .cleanup
stdcall kernel_alloc, edx
test eax, eax
jz .cleanup
mov [base], eax
stdcall map_PE, eax, [image]
push ebx ebp
mov ebx, [image]
mov ebp, eax
call map_PE
pop ebp ebx
mov [entry], eax
test eax, eax
@ -48,199 +63,200 @@ proc load_PE stdcall, file_name:dword
ret
endp
DWORD equ dword
PTR equ
align 4
map_PE: ;stdcall base:dword, image:dword
cld
push ebp
map_PE: ;ebp=base:dword, ebx=image:dword
push edi
push esi
push ebx
sub esp, 60
mov ebx, DWORD PTR [esp+84]
mov ebp, DWORD PTR [esp+80]
mov edx, ebx
mov esi, ebx
add edx, DWORD PTR [ebx+60]
mov edi, ebp
mov DWORD PTR [esp+32], edx
mov ecx, DWORD PTR [edx+84]
sub esp, .locals_size
virtual at esp
.numsections dd ?
.import_names dd ?
.import_targets dd ?
.peheader dd ?
.bad_import dd ?
.import_idx dd ?
.import_descr dd ?
.relocs_rva dd ?
.relocs_size dd ?
.section_header_size dd ?
.AddressOfEntryPoint dd ?
.ImageBase dd ?
.locals_size = $ - esp
end virtual
cmp word [ebx], STRIPPED_PE_SIGNATURE
jz .stripped
mov edx, ebx
add edx, [ebx+60]
movzx eax, word [edx+6]
mov [.numsections], eax
mov eax, [edx+40]
mov [.AddressOfEntryPoint], eax
mov eax, [edx+52]
mov [.ImageBase], eax
mov ecx, [edx+84]
mov [.section_header_size], 40
mov eax, [edx+128]
mov [.import_descr], eax
mov eax, [edx+160]
mov [.relocs_rva], eax
mov eax, [edx+164]
mov [.relocs_size], eax
add edx, 256
jmp .common
.stripped:
mov eax, [ebx+STRIPPED_PE_HEADER.AddressOfEntryPoint]
mov [.AddressOfEntryPoint], eax
mov eax, [ebx+STRIPPED_PE_HEADER.ImageBase]
mov [.ImageBase], eax
movzx eax, [ebx+STRIPPED_PE_HEADER.NumberOfSections]
mov [.numsections], eax
movzx ecx, [ebx+STRIPPED_PE_HEADER.NumberOfRvaAndSizes]
xor eax, eax
mov [.relocs_rva], eax
mov [.relocs_size], eax
test ecx, ecx
jz @f
mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_IMPORT*8]
@@:
mov [.import_descr], eax
cmp ecx, SPE_DIRECTORY_BASERELOC
jbe @f
mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8]
mov [.relocs_rva], eax
mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8+4]
mov [.relocs_size], eax
@@:
mov [.section_header_size], 28
lea edx, [ebx+ecx*8+sizeof.STRIPPED_PE_HEADER+8]
mov ecx, [ebx+STRIPPED_PE_HEADER.SizeOfHeaders]
.common:
mov esi, ebx
mov edi, ebp
shr ecx, 2
rep movsd
movzx eax, WORD PTR [edx+6]
mov DWORD PTR [esp+36], 0
mov DWORD PTR [esp+16], eax
jmp L2
L3:
mov eax, DWORD PTR [edx+264]
cmp [.numsections], 0
jz .nosections
.copy_sections:
mov eax, [edx+8]
test eax, eax
je L4
je .no_section_data
mov esi, ebx
mov edi, ebp
add esi, DWORD PTR [edx+268]
add esi, [edx+12]
mov ecx, eax
add edi, DWORD PTR [edx+260]
add edi, [edx+4]
add ecx, 3
shr ecx, 2
rep movsd
L4:
mov ecx, DWORD PTR [edx+256]
.no_section_data:
mov ecx, [edx]
cmp ecx, eax
jbe L6
jbe .no_section_fill
sub ecx, eax
add eax, DWORD PTR [edx+260]
add eax, [edx+4]
lea edi, [eax+ebp]
xor eax, eax
rep stosb
L6:
inc DWORD PTR [esp+36]
add edx, 40
L2:
mov esi, DWORD PTR [esp+16]
cmp DWORD PTR [esp+36], esi
jne L3
mov edi, DWORD PTR [esp+32]
cmp DWORD PTR [edi+164], 0
je L9
pushd [edi+164]
.no_section_fill:
add edx, [.section_header_size]
dec [.numsections]
jnz .copy_sections
.nosections:
cmp [.relocs_size], 0
je .no_relocations
mov esi, ebp
mov ecx, ebp
sub esi, DWORD PTR [edi+52]
add ecx, DWORD PTR [edi+160]
mov eax, esi
shr eax, 16
mov DWORD PTR [esp+16], eax
L12:
mov eax, [ecx+4]
sub [esp], eax
lea ebx, [eax-8]
xor edi, edi
sub esi, [.ImageBase]
add ecx, [.relocs_rva]
.relocs_block:
mov edi, [ecx]
add edi, ebp
mov ebx, [ecx+4]
add ecx, 8
sub [.relocs_size], ebx
sub ebx, 8
shr ebx, 1
jmp L13
L14:
movzx eax, WORD PTR [ecx+8+edi*2]
jz .relocs_next_block
.one_reloc:
movzx eax, word [ecx]
add ecx, 2
mov edx, eax
shr eax, 12
and edx, 4095
add edx, DWORD PTR [ecx]
cmp ax, 2
je L17
cmp ax, 3
je L18
dec ax
jne L15
mov eax, DWORD PTR [esp+16]
add WORD PTR [edx+ebp], ax
L17:
add WORD PTR [edx+ebp], si
L18:
add DWORD PTR [edx+ebp], esi
L15:
inc edi
L13:
cmp edi, ebx
jne L14
add ecx, DWORD PTR [ecx+4]
L11:
cmp dword [esp], 0
jg L12
pop eax
L9:
mov edx, DWORD PTR [esp+32]
cmp DWORD PTR [edx+132], 0
je L20
mov eax, ebp
add eax, DWORD PTR [edx+128]
mov DWORD PTR [esp+40], 0
add eax, 20
mov DWORD PTR [esp+56], eax
L22:
mov ecx, DWORD PTR [esp+56]
cmp DWORD PTR [ecx-16], 0
jne L23
cmp DWORD PTR [ecx-8], 0
je L25
L23:
mov edi, DWORD PTR [__exports+32]
mov esi, DWORD PTR [__exports+28]
mov eax, DWORD PTR [esp+56]
mov DWORD PTR [esp+20], edi
add edi, OS_BASE
add esi, OS_BASE
mov DWORD PTR [esp+44], esi
mov ecx, DWORD PTR [eax-4]
mov DWORD PTR [esp+48], edi
mov edx, DWORD PTR [eax-20]
cmp eax, 3
jne @f
add [edx+edi], esi
@@:
dec ebx
jnz .one_reloc
.relocs_next_block:
cmp [.relocs_size], 0
jg .relocs_block
.no_relocations:
cmp [.import_descr], 0
je .no_imports
add [.import_descr], ebp
mov [.bad_import], 0
.import_block:
mov ecx, [.import_descr]
cmp dword [ecx+4], 0
jne @f
cmp dword [ecx+12], 0
je .done_imports
@@:
mov edx, dword [ecx]
mov ecx, dword [ecx+16]
test edx, edx
jnz @f
mov edx, ecx
@@:
mov DWORD PTR [esp+52], 0
mov [.import_idx], 0
add ecx, ebp
add edx, ebp
mov DWORD PTR [esp+24], edx
mov DWORD PTR [esp+28], ecx
L26:
mov esi, DWORD PTR [esp+52]
mov edi, DWORD PTR [esp+24]
mov eax, DWORD PTR [edi+esi*4]
mov [.import_names], edx
mov [.import_targets], ecx
.import_func:
mov esi, [.import_idx]
mov edi, [.import_names]
mov eax, [edi+esi*4]
test eax, eax
je L27
test eax, eax
js L27
je .next_import_block
js .next_import_block
lea edi, [ebp+eax]
mov eax, DWORD PTR [esp+28]
mov DWORD PTR [eax+esi*4], 0
mov eax, [.import_targets]
mov dword [eax+esi*4], 0
lea esi, [edi+2]
push eax
movzx ebx, word [edi]
push 32
movzx eax, WORD PTR [edi]
mov edx, DWORD PTR [esp+56]
mov eax, DWORD PTR [edx+eax*4]
mov ecx, [__exports+32]
mov eax, [ecx+OS_BASE+ebx*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop ebx
test eax, eax
jz .import_func_found
xor ebx, ebx
test eax, eax
jne L32
jmp L30
L33:
push ecx
.import_func_candidate:
push 32
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4]
mov ecx, [__exports+32]
mov eax, [ecx+OS_BASE+ebx*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop edx
test eax, eax
jne L34
mov esi, DWORD PTR [esp+44]
mov edx, DWORD PTR [esp+52]
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+ebx*4]
add eax, OS_BASE
mov DWORD PTR [ecx+edx*4], eax
jmp L36
L34:
je .import_func_found
inc ebx
L32:
cmp ebx, DWORD PTR [__exports+24]
jb L33
L36:
cmp ebx, DWORD PTR [__exports+24]
jne L37
cmp ebx, [__exports+24]
jb .import_func_candidate
mov esi, msg_unresolved
call sys_msg_board_str
@ -249,34 +265,30 @@ L36:
mov esi, msg_CR
call sys_msg_board_str
mov DWORD PTR [esp+40], 1
jmp L37
L30:
movzx eax, WORD PTR [edi]
mov esi, DWORD PTR [esp+44]
mov edi, DWORD PTR [esp+52]
mov edx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+eax*4]
mov [.bad_import], 1
jmp .next_import_func
.import_func_found:
mov esi, [__exports+28]
mov edx, [.import_idx]
mov ecx, [.import_targets]
mov eax, [esi+OS_BASE+ebx*4]
add eax, OS_BASE
mov DWORD PTR [edx+edi*4], eax
L37:
inc DWORD PTR [esp+52]
jmp L26
L27:
add DWORD PTR [esp+56], 20
jmp L22
L25:
mov [ecx+edx*4], eax
.next_import_func:
inc [.import_idx]
jmp .import_func
.next_import_block:
add [.import_descr], 20
jmp .import_block
.done_imports:
xor eax, eax
cmp DWORD PTR [esp+40], 0
jne L40
L20:
mov ecx, DWORD PTR [esp+32]
cmp [.bad_import], 0
jne @f
.no_imports:
mov eax, ebp
add eax, DWORD PTR [ecx+40]
L40:
add esp, 60
pop ebx
add eax, [.AddressOfEntryPoint]
@@:
add esp, .locals_size
pop esi
pop edi
pop ebp
ret 8
ret

View File

@ -29,8 +29,7 @@ irq0:
.nocounter:
xor ecx, ecx ; send End Of Interrupt signal
call irq_eoi
; btr dword[DONT_SWITCH], 0
; jc .return
mov bl, SCHEDULE_ANY_PRIORITY
call find_next_task
jz .return ; if there is only one running process
@ -44,26 +43,10 @@ change_task:
pushfd
cli
pushad
if 0
; \begin{Mario79} ; <- must be refractoried, if used...
cmp [dma_task_switched], 1
jne .find_next_task
mov [dma_task_switched], 0
mov ebx, [dma_process]
cmp [CURRENT_TASK], ebx
je .return
mov edi, [dma_slot_ptr]
mov [CURRENT_TASK], ebx
mov [TASK_BASE], edi
jmp @f
.find_next_task:
; \end{Mario79}
end if
mov bl, SCHEDULE_ANY_PRIORITY
call find_next_task
jz .return ; the same task -> skip switch
@@:
; mov byte[DONT_SWITCH], 1
call do_change_task
.return:
popad
@ -121,10 +104,11 @@ do_change_task:
Mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
Mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
; set new thread memory-map
mov ecx, APPDATA.dir_table
mov eax, [ebx+ecx] ;offset>0x7F
cmp eax, [esi+ecx] ;offset>0x7F
mov eax, [ebx+APPDATA.process]
cmp eax, [current_process]
je @f
mov [current_process], eax
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax
@@:
; set tss.esp0
@ -159,7 +143,7 @@ do_change_task:
jz @f
xor eax, eax
mov dr6, eax
lea esi, [ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table];offset>0x7F
lea esi, [ebx+APPDATA.dbg_regs]
cld
macro lodsReg [reg] {
lodsd

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Éste archivo debe ser editado con codificación CP866
msg_sel_ker cp850 "núcleo", 0

View File

@ -413,23 +413,26 @@ endg
align 4
terminate: ; terminate application
destroy_thread:
.slot equ esp+4 ;locals
.process equ esp ;ptr to parent process
.slot equ esp ;locals
push esi ;save .slot
shl esi, 8
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0
jne @F
mov edx, [SLOT_BASE+esi+APPDATA.process]
test edx, edx
jnz @F
pop esi
shl esi, 5
mov [CURRENT_TASK+esi+TASKDATA.state], 9
ret
@@:
push edx ;save .process
lea edx, [SLOT_BASE+esi]
call scheduler_remove_thread
;mov esi,process_terminating
;call sys_msg_board_str
call lock_application_table
; if the process is in V86 mode...
@ -442,14 +445,14 @@ terminate: ; terminate application
; ...it has page directory for V86 mode
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
mov ecx, [esi+4]
mov [eax+SLOT_BASE+APPDATA.dir_table], ecx
mov [eax+SLOT_BASE+APPDATA.process], ecx
; ...and I/O permission map for V86 mode
mov ecx, [esi+12]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [esi+8]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
.nov86:
;destroy per-thread kernel objects
mov esi, [.slot]
shl esi, 8
add esi, SLOT_BASE+APP_OBJ_OFFSET
@ -467,11 +470,6 @@ terminate: ; terminate application
pop esi
jmp @B
@@:
mov eax, [.slot]
shl eax, 8
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
mov esi, [.slot]
cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2
jne @F
@ -630,6 +628,9 @@ terminate: ; terminate application
je @F
call free_page
@@:
lea ebx, [edi+APPDATA.list]
list_del ebx ;destroys edx, ecx
mov eax, 0x20202020
stosd
stosd
@ -745,7 +746,17 @@ terminate: ; terminate application
add ecx, 0x100
jmp .xd0
.xd1:
; call systest
;release slot
bts [thr_slot_map], esi
mov ecx, [.process]
lea eax, [ecx+PROC.thr_list]
cmp eax, [eax+LHEAD.next]
jne @F
call destroy_process.internal
@@:
sti ; .. and life goes on
mov eax, [draw_limits.left]
@ -760,18 +771,10 @@ terminate: ; terminate application
call unlock_application_table
;mov esi,process_terminated
;call sys_msg_board_str
add esp, 4
add esp, 8
ret
restore .slot
;build_scheduler:
; mov esi, boot_sched_1
; call boot_log
; call build_process_gdt_tss_pointer
; mov esi,boot_sched_2
; call boot_log
; ret
restore .process
; Three following procedures are used to guarantee that
; some part of kernel code will not be terminated from outside

View File

@ -70,7 +70,7 @@ proc fs_execute
filename rd 256 ;1024/4
flags dd ?
save_cr3 dd ?
save_proc dd ?
slot dd ?
slot_base dd ?
file_base dd ?
@ -215,7 +215,7 @@ proc fs_execute
call lock_application_table
call get_new_process_place
call alloc_thread_slot
test eax, eax
mov esi, -0x20 ; too many processes
jz .err
@ -248,18 +248,23 @@ proc fs_execute
loop .copy_process_name_loop
.copy_process_name_done:
mov ebx, cr3
mov [save_cr3], ebx
mov ebx, [current_process]
mov [save_proc], ebx
stdcall create_app_space, [hdr_mem], [file_base], [file_size]
stdcall create_process, [hdr_mem], [file_base], [file_size]
mov esi, -30; no memory
test eax, eax
jz .failed
mov ebx, [hdr_mem]
mov [eax+PROC.mem_used], ebx
mov ebx, [slot_base]
mov [ebx+APPDATA.dir_table], eax
mov eax, [hdr_mem]
mov [ebx+APPDATA.mem_size], eax
mov [ebx+APPDATA.process], eax
lea edx, [ebx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail edx, ecx
xor edx, edx
cmp word [6], '02'
@ -292,7 +297,7 @@ end if
lea ecx, [filename]
stdcall set_app_params , [slot], eax, ebx, ecx, [flags]
mov eax, [save_cr3]
mov eax, [save_proc]
call set_cr3
mov eax, [process_number];set result
@ -301,7 +306,7 @@ end if
jmp .final
.failed:
mov eax, [save_cr3]
mov eax, [save_proc]
call set_cr3
.err:
.err_hdr:
@ -385,53 +390,55 @@ test_app_header:
ret
align 4
proc get_new_process_place
alloc_thread_slot:
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; eax=[new_thread_slot]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
mov eax, CURRENT_TASK
mov ebx, [TASK_COUNT]
inc ebx
shl ebx, 5
add ebx, eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax, ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax, 0x20
cmp word [eax+0xa], 9;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx, eax
sub eax, CURRENT_TASK
shr eax, 5 ;calculate slot index
cmp eax, 256
jge .failed ;it should be <256
mov word [ebx+0xa], 9;set process state to 9 (for slot after hight boundary)
ret
.failed:
mov edx, thr_slot_map
pushfd
cli
.l1:
bsf eax, [edx]
jnz .found
add edx, 4
cmp edx, thr_slot_map+32
jb .l1
popfd
xor eax, eax
ret
endp
.found:
btr [edx], eax
sub edx, thr_slot_map
lea eax, [eax+edx*8]
popfd
ret
align 4
proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
proc create_process stdcall, app_size:dword,img_base:dword,img_size:dword
locals
app_pages dd ?
img_pages dd ?
dir_addr dd ?
process dd ?
app_tabs dd ?
endl
push ebx
push esi
push edi
mov ecx, pg_data.mutex
call mutex_lock
xor eax, eax
mov [dir_addr], eax
mov [process], eax
mov eax, [app_size]
add eax, 4095
@ -454,39 +461,59 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
shr ecx, 12
mov [img_pages], ecx
if GREEDY_KERNEL
lea eax, [ecx+ebx+2];only image size
else
lea eax, [eax+ebx+2];all requested memory
end if
cmp eax, [pg_data.pages_free]
ja .fail
call alloc_page
stdcall kernel_alloc, 0x2000
test eax, eax
jz .fail
mov [dir_addr], eax
stdcall map_page, [tmp_task_pdir], eax, dword PG_SW
mov [process], eax
lea edi, [eax+PROC.heap_lock]
mov ecx, (PROC.ht_next-PROC.heap_lock)/4
list_init eax
add eax, PROC.thr_list
list_init eax
mov edi, [tmp_task_pdir]
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
cld
rep stosd
mov ecx, (PROC.pdt_0 - PROC.htab)/4
@@:
stosd
inc eax
cmp eax, ecx
jbe @B
mov [edi-4096+PROC.ht_next], 1 ;reserve handle 0
mov eax, edi
call get_pg_addr
mov [edi-4096+PROC.pdt_0_phys], eax
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_pgdir+(OS_BASE shr 20)
xor eax, eax
rep stosd
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_proc+PROC.pdt_0+(OS_BASE shr 20)
rep movsd
mov eax, [dir_addr]
mov eax, [edi-8192+PROC.pdt_0_phys]
or eax, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
and eax, -4096
lea eax, [edi-8192]
call set_cr3
mov edx, [app_tabs]
mov edi, new_app_base
mov ecx, [app_tabs]
test ecx, ecx
jz .done
xor edi, edi
@@:
call alloc_page
test eax, eax
@ -494,81 +521,81 @@ end if
stdcall map_page_table, edi, eax
add edi, 0x00400000
dec edx
jnz @B
loop @B
mov edi, new_app_base
shr edi, 10
add edi, page_tabs
mov edi, page_tabs
mov ecx, [app_tabs]
shl ecx, 10
xor eax, eax
rep stosd
xor edx, edx
mov ecx, [img_pages]
jcxz .bss
sub [app_pages], ecx
mov ebx, PG_UW
mov edx, new_app_base
mov esi, [img_base]
mov edi, new_app_base
shr esi, 10
shr edi, 10
add esi, page_tabs
add edi, page_tabs
mov edi, page_tabs
.remap:
lodsd
and eax, 0xFFFFF000
or eax, ebx; force user level r/w access
stosd
add edx, 0x1000
dec [app_pages]
dec ecx
jnz .remap
mov ecx, [app_pages]
test ecx, ecx
loop .remap
.bss:
mov ebx, [app_pages]
test ebx, ebx
jz .done
if GREEDY_KERNEL
mov eax, 0x02
rep stosd
else
.alloc:
.map_bss:
call alloc_page
test eax, eax
jz .fail
stdcall map_page, edx, eax, dword PG_UW
add edx, 0x1000
dec [app_pages]
jnz .alloc
end if
dec ebx
jnz .map_bss
.done:
stdcall map_page, [tmp_task_pdir], dword 0, dword PG_UNMAP
mov ecx, pg_data.mutex
call mutex_unlock
mov eax, [dir_addr]
mov eax, [process]
pop edi
pop esi
pop ebx
ret
.fail:
mov ecx, pg_data.mutex
call mutex_unlock
cmp [dir_addr], 0
cmp [process], 0
je @f
stdcall destroy_app_space, [dir_addr], 0
;; stdcall destroy_app_space, [dir_addr], 0
@@:
xor eax, eax
pop edi
pop esi
pop ebx
ret
endp
align 4
set_cr3:
pushfd
cli
mov ebx, [current_slot]
mov [ebx+APPDATA.dir_table], eax
mov [current_process], eax
mov [ebx+APPDATA.process], eax
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax
popfd
ret
align 4
@ -582,6 +609,8 @@ proc destroy_page_table stdcall, pg_tab:dword
mov eax, [esi]
test eax, 1
jz .next
test eax, 2
jz .next
test eax, 1 shl 9
jnz .next ;skip shared pages
call free_page
@ -594,46 +623,25 @@ proc destroy_page_table stdcall, pg_tab:dword
endp
align 4
proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
destroy_process: ;fastcall ecx= ptr to process
xor edx, edx
push edx
mov eax, 0x1
mov ebx, [pg_dir]
.loop:
;eax = current slot of process
mov ecx, eax
shl ecx, 5
cmp byte [CURRENT_TASK+ecx+0xa], 9;if process running?
jz @f ;skip empty slots
shl ecx, 3
add ecx, SLOT_BASE
cmp [ecx+APPDATA.dir_table], ebx;compare page directory addresses
jnz @f
mov [ebp-4], ecx
inc edx ;thread found
@@:
inc eax
cmp eax, [TASK_COUNT] ;exit loop if we look through all processes
jle .loop
lea eax, [ecx+PROC.thr_list]
cmp eax, [eax+LHEAD.next]
jne .exit
;edx = number of threads
;our process is zombi so it isn't counted
pop ecx
cmp edx, 1
jg .ret
;if there isn't threads then clear memory.
mov esi, [dlls_list]
call destroy_all_hdlls;ecx=APPDATA
align 4
.internal:
push ecx
mov ecx, pg_data.mutex
call mutex_lock
mov esi, [ecx+PROC.dlls_list_ptr]
call destroy_all_hdlls
mov eax, [pg_dir]
and eax, not 0xFFF
stdcall map_page, [tmp_task_pdir], eax, PG_SW
mov esi, [tmp_task_pdir]
mov edi, (OS_BASE shr 20)/4
; mov ecx, pg_data.mutex
; call mutex_lock
mov esi, [esp]
add esi, PROC.pdt_0
mov edi, (0x80000000 shr 20)/4
.destroy:
mov eax, [esi]
test eax, 1
@ -648,16 +656,13 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
dec edi
jnz .destroy
mov eax, [pg_dir]
call free_page
.exit:
call kernel_free ;ecx still in stack
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
stdcall map_page, [tmp_task_pdir], 0, PG_UNMAP
mov ecx, pg_data.mutex
call mutex_unlock
.ret:
; mov ecx, pg_data.mutex
; call mutex_unlock
.exit:
ret
endp
align 4
get_pid:
@ -708,6 +713,10 @@ check_region:
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax, 1
ret
if 0
mov eax, [CURRENT_TASK]
; jmp check_process_region
;-----------------------------------------------------------------------------
@ -732,57 +741,13 @@ check_region:
mov eax, 1
ret
; call MEM_Get_Linear_Address
; push ebx
; push ecx
; push edx
; mov edx,ebx
; and edx,not (4096-1)
; sub ebx,edx
; add ecx,ebx
; mov ebx,edx
; add ecx,(4096-1)
; and ecx,not (4096-1)
;.loop:
;;eax - linear address of page directory
;;ebx - current page
;;ecx - current size
; mov edx,ebx
; shr edx,22
; mov edx,[eax+4*edx]
; and edx,not (4096-1)
; test edx,edx
; jz .failed1
; push eax
; mov eax,edx
; call MEM_Get_Linear_Address
; mov edx,ebx
; shr edx,12
; and edx,(1024-1)
; mov eax,[eax+4*edx]
; and eax,not (4096-1)
; test eax,eax
; pop eax
; jz .failed1
; add ebx,4096
; sub ecx,4096
; jg .loop
; pop edx
; pop ecx
; pop ebx
.ok:
mov eax, 1
ret
;
;.failed1:
; pop edx
; pop ecx
; pop ebx
.failed:
xor eax, eax
ret
end if
align 4
proc read_process_memory
@ -954,7 +919,7 @@ proc new_sys_threads
call lock_application_table
call get_new_process_place
call alloc_thread_slot
test eax, eax
jz .failed
@ -976,20 +941,12 @@ proc new_sys_threads
mov ecx, 11
rep movsb ;copy process name
mov eax, [ebx+APPDATA.heap_base]
mov [edx+APPDATA.heap_base], eax
mov eax, [ebx+APPDATA.process]
mov [edx+APPDATA.process], eax
mov ecx, [ebx+APPDATA.heap_top]
mov [edx+APPDATA.heap_top], ecx
mov eax, [ebx+APPDATA.mem_size]
mov [edx+APPDATA.mem_size], eax
mov ecx, [ebx+APPDATA.dir_table]
mov [edx+APPDATA.dir_table], ecx;copy page directory
mov eax, [ebx+APPDATA.dlls_list_ptr]
mov [edx+APPDATA.dlls_list_ptr], eax
lea ebx, [edx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail ebx, ecx ;add thread to process child's list
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
@ -1118,8 +1075,8 @@ proc set_app_params stdcall,slot:dword, params:dword,\
add eax, 256
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
; cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
; ja @f
mov eax, [cmd_line]
@ -1158,8 +1115,8 @@ proc set_app_params stdcall,slot:dword, params:dword,\
mov eax, edx
add eax, 1024
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
; cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
; ja @f
stdcall strncpy, edx, [app_path], 1024
@@:
mov ebx, [slot]
@ -1188,9 +1145,9 @@ proc set_app_params stdcall,slot:dword, params:dword,\
xor eax, eax
mov [ecx+0], dword eax
mov [ecx+4], dword eax
mov eax, [_display.width]
mov eax, [Screen_Max_X]
mov [ecx+8], eax
mov eax, [_display.height]
mov eax, [Screen_Max_Y]
mov [ecx+12], eax
mov ebx, [pl0_stack]

View File

@ -14,9 +14,7 @@ DEBUG_SHOW_IO = 0
struct V86_machine
; page directory
pagedir dd ?
; translation table: V86 address -> flat linear address
pages dd ?
process dd ?
; mutex to protect all data from writing by multiple threads at one time
mutex dd ?
; i/o permission map
@ -38,91 +36,87 @@ v86_create:
and dword [eax+V86_machine.mutex], 0
; allocate tables
mov ebx, eax
; We allocate 4 pages.
; First is main page directory for V86 mode.
; Second page:
; first half (0x800 bytes) is page table for addresses 0 - 0x100000,
; second half is for V86-to-linear translation.
; Third and fourth are for I/O permission map.
push 8000h ; blocks less than 8 pages are discontinuous
stdcall create_process, 4096, eax, 4096 ;FIXME
test eax, eax
jz .fail2
mov [eax+PROC.mem_used], 4096
mov [ebx+V86_machine.process], eax
push 2000h
call kernel_alloc
test eax, eax
jz .fail2
mov [ebx+V86_machine.pagedir], eax
push edi eax
mov edi, eax
add eax, 1800h
mov [ebx+V86_machine.pages], eax
mov [ebx+V86_machine.iopm], eax
; initialize tables
mov ecx, 2000h/4
xor eax, eax
rep stosd
mov [ebx+V86_machine.iopm], edi
dec eax
mov ecx, 2000h/4
rep stosd
pop eax
; page directory: first entry is page table...
push edi
mov edi, eax
add eax, 1000h
push eax
call get_pg_addr
or al, PG_UW
stosd
; ...and also copy system page tables
; thx to Serge, system is located at high addresses
add edi, (OS_BASE shr 20) - 4
push esi
mov esi, (OS_BASE shr 20) + sys_pgdir
mov ecx, 0x80000000 shr 22
rep movsd
mov eax, -1
mov ecx, 2000h/4
rep stosd
mov eax, [ebx+V86_machine.process]
mov eax, [eax+PROC.pdt_0_phys]
pushfd
cli
mov cr3, eax
mov eax, [ebx+V86_machine.pagedir] ;root dir also is
call get_pg_addr ;used as page table
or al, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
pop esi
; now V86 specific: initialize known addresses in first Mb
pop eax
; first page - BIOS data (shared between all machines!)
; physical address = 0
; linear address = OS_BASE
mov dword [eax], 111b
mov dword [eax+800h], OS_BASE
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
; physical address = 0x9C000
; linear address = 0x8009C000
; (I have seen one computer with EBDA segment = 0x9D80,
; all other computers use less memory)
mov ecx, 4
mov edx, 0x9C000
push eax
lea edi, [eax+0x9C*4]
mov eax, PG_UW
mov [page_tabs], eax
invlpg [eax]
mov byte [0x500], 0xCD
mov byte [0x501], 0x13
mov byte [0x502], 0xF4
mov byte [0x503], 0xCD
mov byte [0x504], 0x10
mov byte [0x505], 0xF4
mov eax, 0x99000+PG_UW
mov edi, page_tabs+0x99*4
mov edx, 0x1000
mov ecx, 7
@@:
lea eax, [edx + OS_BASE]
mov [edi+800h], eax
lea eax, [edx + 111b]
stosd
add edx, 0x1000
add eax, edx
loop @b
pop eax
pop edi
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
; physical address = 0xC0000
; linear address = 0x800C0000
mov ecx, 0xC0
mov eax, 0xC0000+PG_UW
mov edi, page_tabs+0xC0*4
mov ecx, 64
@@:
mov edx, ecx
shl edx, 12
push edx
or edx, 111b
mov [eax+ecx*4], edx
pop edx
add edx, OS_BASE
mov [eax+ecx*4+0x800], edx
inc cl
jnz @b
stosd
add eax, edx
loop @b
mov eax, sys_proc
push ebx
call set_cr3
pop ebx
popfd
pop edi
mov eax, ebx
ret
.fail2:
@ -132,15 +126,16 @@ v86_create:
xor eax, eax
ret
;not used
; Destroy V86 machine
; in: eax = handle
; out: nothing
; destroys: eax, ebx, ecx, edx (due to free)
v86_destroy:
push eax
stdcall kernel_free, [eax+V86_machine.pagedir]
pop eax
jmp free
;v86_destroy:
; push eax
; stdcall kernel_free, [eax+V86_machine.pagedir]
; pop eax
; jmp free
; Translate V86-address to linear address
; in: eax=V86 address
@ -150,28 +145,30 @@ v86_destroy:
v86_get_lin_addr:
push ecx edx
mov ecx, eax
mov edx, [esi+V86_machine.pages]
shr ecx, 12
mov edx, [page_tabs+ecx*4]
and eax, 0xFFF
add eax, [edx+ecx*4] ; atomic operation, no mutex needed
and edx, 0xFFFFF000
or eax, edx
pop edx ecx
ret
;not used
; Sets linear address for V86-page
; in: eax=linear address (must be page-aligned)
; ecx=V86 page (NOT address!)
; esi=handle
; out: nothing
; destroys: nothing
v86_set_page:
push eax ebx
mov ebx, [esi+V86_machine.pagedir]
mov [ebx+ecx*4+0x1800], eax
call get_pg_addr
or al, 111b
mov [ebx+ecx*4+0x1000], eax
pop ebx eax
ret
;v86_set_page:
; push eax ebx
; mov ebx, [esi+V86_machine.pagedir]
; mov [ebx+ecx*4+0x1800], eax
; call get_pg_addr
; or al, 111b
; mov [ebx+ecx*4+0x1000], eax
; pop ebx eax
; ret
; Allocate memory in V86 machine
; in: eax=size (in bytes)
@ -214,21 +211,7 @@ init_sys_v86:
mov [sys_v86_machine], eax
test eax, eax
jz .ret
mov byte [OS_BASE + 0x500], 0xCD
mov byte [OS_BASE + 0x501], 0x13
mov byte [OS_BASE + 0x502], 0xF4
mov byte [OS_BASE + 0x503], 0xCD
mov byte [OS_BASE + 0x504], 0x10
mov byte [OS_BASE + 0x505], 0xF4
mov esi, eax
mov ebx, [eax+V86_machine.pagedir]
; one page for stack, two pages for results (0x2000 bytes = 16 sectors)
mov dword [ebx+0x99*4+0x1000], 0x99000 or 111b
mov dword [ebx+0x99*4+0x1800], OS_BASE + 0x99000
mov dword [ebx+0x9A*4+0x1000], 0x9A000 or 111b
mov dword [ebx+0x9A*4+0x1800], OS_BASE + 0x9A000
mov dword [ebx+0x9B*4+0x1000], 0x9B000 or 111b
mov dword [ebx+0x9B*4+0x1800], OS_BASE + 0x9B000
if ~DEBUG_SHOW_IO
; allow access to all ports
mov ecx, [esi+V86_machine.iopm]
@ -272,36 +255,38 @@ ends
; eax = 3 - IRQ is already hooked by another VM
; destroys: nothing
v86_start:
pushad
cli
mov ecx, [CURRENT_TASK]
shl ecx, 8
add ecx, SLOT_BASE
mov ecx, [current_slot]
mov eax, [esi+V86_machine.iopm]
call get_pg_addr
inc eax
push dword [ecx+APPDATA.io_map]
push dword [ecx+APPDATA.io_map+4]
mov dword [ecx+APPDATA.io_map], eax
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax
add eax, 0x1000
mov dword [ecx+APPDATA.io_map+4], eax
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax
push [ecx+APPDATA.dir_table]
push [ecx+APPDATA.process]
push [ecx+APPDATA.saved_esp0]
mov [ecx+APPDATA.saved_esp0], esp
mov [tss._esp0], esp
mov eax, [esi+V86_machine.pagedir]
mov eax, [esi+V86_machine.iopm]
call get_pg_addr
mov [ecx+APPDATA.dir_table], eax
mov cr3, eax
inc eax
mov dword [ecx+APPDATA.io_map], eax
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax
; mov [irq_tab+5*4], my05
mov eax, [esi+V86_machine.iopm]
add eax, 0x1000
call get_pg_addr
inc eax
mov dword [ecx+APPDATA.io_map+4], eax
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax
mov eax, [esi+V86_machine.process]
mov [ecx+APPDATA.process], eax
mov [current_process], eax
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax
; We do not enable interrupts, because V86 IRQ redirector assumes that
; machine is running
@ -782,19 +767,21 @@ end if
mov esp, esi
cli
mov ecx, [CURRENT_TASK]
shl ecx, 8
mov ecx, [current_slot]
pop eax
mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax
mov [ecx+APPDATA.saved_esp0], eax
mov [tss._esp0], eax
pop eax
mov [SLOT_BASE+ecx+APPDATA.dir_table], eax
mov [ecx+APPDATA.process], eax
mov [current_process], eax
pop ebx
mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx
mov dword [ecx+APPDATA.io_map+4], ebx
mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx
pop ebx
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx
mov dword [ecx+APPDATA.io_map], ebx
mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax
sti
@ -843,11 +830,10 @@ v86_irq:
pop eax
v86_irq2:
mov esi, [v86_irqhooks+edi*8] ; get VM handle
mov eax, [esi+V86_machine.pagedir]
call get_pg_addr
mov eax, [esi+V86_machine.process]
mov ecx, [CURRENT_TASK]
shl ecx, 8
cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax
cmp [SLOT_BASE+ecx+APPDATA.process], eax
jnz .notcurrent
lea eax, [edi+8]
cmp al, 10h
@ -860,7 +846,7 @@ v86_irq2:
mov ebx, SLOT_BASE + 0x100
mov ecx, [TASK_COUNT]
.scan:
cmp [ebx+APPDATA.dir_table], eax
cmp [ebx+APPDATA.process], eax
jnz .cont
push ecx
mov ecx, [ebx+APPDATA.saved_esp0]
@ -895,6 +881,7 @@ v86_irq2:
popad
iretd
.found:
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax
mov esi, [ebx+APPDATA.saved_esp0]
sub word [esi-sizeof.v86_regs+v86_regs.esp], 6

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -140,24 +140,20 @@ end if
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0
if ~ lang eq sp
msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0
end if
;msg_module db 'in module ',0
;if ~ lang eq sp
;msg_version db 'incompatible driver version',13,10,0
;msg_www db 'please visit www.kolibrios.org',13,10,0
;end if
msg_CR db 13,10,0
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
szHwMouse db 'ATI2D',0
szPS2MDriver db 'PS2MOUSE',0
szPS2MDriver db '/rd/1/drivers/PS2MOUSE.SYS',0
;szCOM_MDriver db 'COM_MOUSE',0
szVidintel db 'vidintel',0
szVidintel db '/rd/1/drivers/vidintel.sys',0
szUSB db 'USB',0
szAtiHW db '/rd/1/drivers/ati2d.drv',0
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0
sz_EXPORTS db '_EXPORTS',0
@ -168,8 +164,10 @@ firstapp db 'LAUNCHER',0
notifyapp db '@notify',0
if lang eq ru
ud_user_message cp866 'Ошибка: неподдерживаемая инструкция процессора',0
mtrr_user_message cp866 '"Обнаружена проблема с конфигурацией MTRR.\nПроизводительность может быть пониженной" -dW',0
else if ~ lang eq sp
ud_user_message db 'Error: unsupported processor instruction',0
mtrr_user_message db '"There is a problem with MTRR configuration.\nPerformance can be low" -dW',0
end if
vmode db '/sys/drivers/VMODE.MDR',0
@ -179,7 +177,7 @@ kernel_file_load:
dd 0 ; subfunction
dq 0 ; offset in file
dd 0x30000 ; number of bytes to read
dd OS_BASE + 0x70000 ; buffer for data
dd OS_BASE + 0x71000 ; buffer for data
db '/RD/1/KERNEL.MNT',0
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
@ -347,6 +345,8 @@ mem_block_list rd 64*2
mem_used_list rd 64*2
mem_hash_cnt rd 64
thr_slot_map rd 8
cpu_freq rq 1
heap_mutex MUTEX
@ -378,12 +378,14 @@ _display display_t
_WinMapAddress rd 1
_WinMapSize rd 1
LFBAddress rd 1
LFBAddress dd ?
Screen_Max_X dd ?
Screen_Max_Y dd ?
SCR_MODE rw 2
PUTPIXEL rd 1
GETPIXEL rd 1
PUTPIXEL dd ?
GETPIXEL dd ?
if VESA_1_2_VIDEO
BANK_SWITCH rd 1 reserved for vesa 1.2
@ -399,7 +401,7 @@ d_width_calc_area rd 1140
mouseunder rd 16*24
MOUSE_PICTURE rd 1
MOUSE_PICTURE dd ?
MOUSE_SCROLL_H rw 1
MOUSE_X: rw 1
@ -436,14 +438,15 @@ proc_mem_map rd 1
proc_mem_pdir rd 1
proc_mem_tab rd 1
tmp_task_pdir rd 1
tmp_task_ptab rd 1
default_io_map rd 1
LFBSize rd 1
current_slot rd 1
current_process rd 1
current_slot rd 1 ; i.e. cureent thread
; status
hd1_status rd 1 ; 0 - free : other - pid
@ -460,8 +463,6 @@ cdid rd 1
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
@ -494,63 +495,12 @@ BgrDataHeight rd 1
skin_data rd 1
cache_ide0:
cache_ide0_pointer rd 1
cache_ide0_size rd 1 ; not use
cache_ide0_data_pointer rd 1
cache_ide0_system_data_size rd 1 ; not use
cache_ide0_appl_data_size rd 1 ; not use
cache_ide0_system_data rd 1
cache_ide0_appl_data rd 1
cache_ide0_system_sad_size rd 1
cache_ide0_appl_sad_size rd 1
cache_ide0_search_start rd 1
cache_ide0_appl_search_start rd 1
cache_ide1:
cache_ide1_pointer rd 1
cache_ide1_size rd 1 ; not use
cache_ide1_data_pointer rd 1
cache_ide1_system_data_size rd 1 ; not use
cache_ide1_appl_data_size rd 1 ; not use
cache_ide1_system_data rd 1
cache_ide1_appl_data rd 1
cache_ide1_system_sad_size rd 1
cache_ide1_appl_sad_size rd 1
cache_ide1_search_start rd 1
cache_ide1_appl_search_start rd 1
cache_ide2:
cache_ide2_pointer rd 1
cache_ide2_size rd 1 ; not use
cache_ide2_data_pointer rd 1
cache_ide2_system_data_size rd 1 ; not use
cache_ide2_appl_data_size rd 1 ; not use
cache_ide2_system_data rd 1
cache_ide2_appl_data rd 1
cache_ide2_system_sad_size rd 1
cache_ide2_appl_sad_size rd 1
cache_ide2_search_start rd 1
cache_ide2_appl_search_start rd 1
cache_ide3:
cache_ide3_pointer rd 1
cache_ide3_size rd 1 ; not use
cache_ide3_data_pointer rd 1
cache_ide3_system_data_size rd 1 ; not use
cache_ide3_appl_data_size rd 1 ; not use
cache_ide3_system_data rd 1
cache_ide3_appl_data rd 1
cache_ide3_system_sad_size rd 1
cache_ide3_appl_sad_size rd 1
cache_ide3_search_start rd 1
cache_ide3_appl_search_start rd 1
debug_step_pointer rd 1
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled
cpu_phys_addr_width rb 1 ; also known as MAXPHYADDR in Intel manuals
hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache
cd_appl_data rb 1 ; 0 = system cache, 1 - application cache
@ -575,16 +525,21 @@ end if
org (OS_BASE+0x0100000)
RAMDISK: rb 2880*512
rb 2856*4 ; not used
; Currently size of memory allocated for the ramdisk is fixed.
; This should be revisited when/if memory map would become more dynamic.
RAMDISK_CAPACITY = 2880 ; in sectors
RAMDISK: rb RAMDISK_CAPACITY*512
_CLEAN_ZONE:
BgrAuxTable rb 32768
align 65536
SB16Buffer rb 65536
align 4096
_IDE_DMA rb 16*512
BgrAuxTable rb 32768
BUTTON_INFO rb 64*1024
RESERVED_PORTS: rb 64*1024
FLOPPY_BUFF: rb 18*512 ;one track
sys_pgmap: rb 1024*1024/8

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
boot_initirq latin1 'Algväärtustan IRQ',0
boot_picinit latin1 'Algväärtustan PIC',0
boot_v86machine latin1 'Algväärtustan süsteemi V86 masinat',0

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5088 $
boot_initirq: cp850 'Inicializar IRQ',0
boot_picinit: cp850 'Inicializar PIC',0
boot_v86machine: cp850 'Inicializar sistema V86',0
@ -37,7 +47,8 @@ if preboot_blogesc
boot_tasking: cp850 'Todo configurado - presiona ESC para iniciar',0
end if
msg_version: cp850 'versión incompatible del controlador',13,10,0
msg_www: cp850 'por favor, visita www.kolibrios.org',13,10,0
;msg_version: cp850 'versión incompatible del controlador',13,10,0
;msg_www: cp850 'por favor, visita www.kolibrios.org',13,10,0
ud_user_message:cp850 'Error: instrucción no soportada por el procesador',0
mtrr_user_message cp850 '"There is a problem with MTRR configuration.\nPerformance can be low" -dW',0

View File

@ -1,10 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2008-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2008-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
; Detect all BIOS hard drives.
; diamond, 2008
; Do not include USB mass storages. CleverMouse, 2013

View File

@ -1,10 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2009-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2009-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Query physical memory map from BIOS.
; diamond, 2009

View File

@ -17,93 +17,192 @@ $Revision$
;****************************************************
;* ПОИСК HDD и CD *
;****************************************************
cmp [IDEContrProgrammingInterface], 0
cmp [ecx+IDE_DATA.ProgrammingInterface], 0
je EndFindHDD
FindHDD:
push ecx
xor ebx, ebx
inc ebx
cmp ecx, IDE_controller_2
jne @f
add bl, 5
jmp .find
@@:
cmp ecx, IDE_controller_3
jne .find
add bl, 10
;--------------------------------------
.find:
mov [ChannelNumber], 1
mov [DiskNumber], 0
call FindHDD_3
; mov ax,[Sector512+176]
; mov [DRIVE_DATA+6],ax
; mov ax,[Sector512+126]
; mov [DRIVE_DATA+8],ax
; mov ax,[Sector512+128]
; mov [DRIVE_DATA+8],ax
call FindHDD_2
mov [DiskNumber], 1
call FindHDD_3
; mov al,[Sector512+176]
; mov [DRIVE_DATA+7],al
call FindHDD_2
inc [ChannelNumber]
mov [DiskNumber], 0
call FindHDD_3
; mov al,[Sector512+176]
; mov [DRIVE_DATA+8],al
call FindHDD_2
mov [DiskNumber], 1
call FindHDD_1
; mov al,[Sector512+176]
; mov [DRIVE_DATA+9],al
pop ecx
jmp EndFindHDD
;-----------------------------------------------------------------------------
FindHDD_2:
call FindHDD_1
shl byte [ebx+DRIVE_DATA], 2
ret
;-----------------------------------------------------------------------------
FindHDD_1:
DEBUGF 1, "K : Channel %d ",[ChannelNumber]:2
DEBUGF 1, "Disk %d\n",[DiskNumber]:1
push ebx ecx
call ReadHDD_ID
pop ecx ebx
cmp [DevErrorCode], 7
je .end
cmp [DevErrorCode], 0
jne FindHDD_2
jne .FindCD
cmp [Sector512+6], word 16
ja FindHDD_2
ja .FindCD
cmp [Sector512+12], word 255
ja FindHDD_2
inc byte [DRIVE_DATA+1]
jmp Print_Device_Name
FindHDD_2:
ja .FindCD
inc byte [ebx+DRIVE_DATA]
jmp .Print_Device_Name
;--------------------------------------
.FindCD:
push ebx ecx
call DeviceReset
pop ecx ebx
cmp [DevErrorCode], 0
jne FindHDD_2_2
jne .end
push ebx ecx
call ReadCD_ID
pop ecx ebx
cmp [DevErrorCode], 0
jne FindHDD_2_2
inc byte [DRIVE_DATA+1]
inc byte [DRIVE_DATA+1]
Print_Device_Name:
jne .end
add [ebx+DRIVE_DATA], byte 2
;--------------------------------------
.Print_Device_Name:
pushad
pushfd
xor ebx, ebx
mov bx, [ChannelNumber]
dec ebx
shl ebx, 1
add bl, [DiskNumber]
shl ebx, 1
call calculate_IDE_device_values_storage
;--------------------------------------
.copy_dev_name:
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
xor eax, eax
mov ax, [Sector512+64*2]
DEBUGF 1, "K : PIO mode %x\n", eax
DEBUGF 1, "K : PIO possible modes %x\n", al
mov ax, [Sector512+51*2]
mov al, ah
call convert_Sector512_value
DEBUGF 1, "K : PIO set mode %x\n", ah
mov ax, [Sector512+63*2]
DEBUGF 1, "K : Multiword DMA mode %x\n", eax
DEBUGF 1, "K : Multiword DMA possible modes %x\n", al
mov al, ah
call convert_Sector512_value
DEBUGF 1, "K : Multiword DMA set mode %x\n", ah
mov ax, [Sector512+88*2]
DEBUGF 1, "K : Ultra DMA mode %x\n", eax
FindHDD_2_2:
ret
DEBUGF 1, "K : Ultra DMA possible modes %x\n", al
FindHDD_3:
call FindHDD_1
shl byte [DRIVE_DATA+1], 2
ret
mov [ebx+IDE_DEVICE.UDMA_possible_modes], al
mov al, ah
call convert_Sector512_value
DEBUGF 1, "K : Ultra DMA set mode %x\n", ah
mov [ebx+IDE_DEVICE.UDMA_set_mode], ah
popfd
popad
ret
;--------------------------------------
.end:
DEBUGF 1, "K : Device not found\n"
ret
;-----------------------------------------------------------------------------
calculate_IDE_device_values_storage:
cmp ecx, IDE_controller_1
jne @f
add ebx, IDE_device_1
jmp .exit
;--------------------------------------
@@:
cmp ecx, IDE_controller_2
jne @f
add ebx, IDE_device_2
jmp .exit
;--------------------------------------
@@:
add ebx, IDE_device_3
;--------------------------------------
.exit:
ret
;-----------------------------------------------------------------------------
convert_Sector512_value:
mov ecx, 8
xor ah, ah
;--------------------------------------
@@:
test al, 1b
jnz .end
shr al, 1
inc ah
loop @b
xor ah, ah
;--------------------------------------
.end:
ret
;-----------------------------------------------------------------------------
; Адрес считываемого сектора в режиме LBA
uglobal
SectorAddress DD ?
SectorAddress dd ?
dev_name:
rb 41
endg
;-----------------------------------------------------------------------------
;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА *
;* Входные параметры передаются через глобальные *
@ -119,32 +218,32 @@ ReadHDD_ID:
; Послать команду идентификации устройства
mov [ATAFeatures], 0
mov [ATAHead], 0
mov [ATACommand], 0ECh
mov [ATACommand], 0xEC
call SendCommandToHDD
cmp [DevErrorCode], 0;проверить код ошибки
cmp [DevErrorCode], 0 ;проверить код ошибки
jne @@End ;закончить, сохранив код ошибки
mov DX, [ATABasePortAddr]
add DX, 7 ;адрес регистра состояни
mov dx, [ATABasePortAddr]
add dx, 7 ;адрес регистра состояни
mov ecx, 0xffff
@@WaitCompleet:
; Проверить время выполнения команды
dec ecx
; cmp ecx,0
jz @@Error1 ;ошибка тайм-аута
; Проверить готовность
in AL, DX
test AL, 80h ;состояние сигнала BSY
in al, dx
test al, 80h ;состояние сигнала BSY
jnz @@WaitCompleet
test AL, 1 ;состояние сигнала ERR
test al, 1 ;состояние сигнала ERR
jnz @@Error6
test AL, 08h ;состояние сигнала DRQ
test al, 08h ;состояние сигнала DRQ
jz @@WaitCompleet
; Принять блок данных от контроллера
; mov AX,DS
; mov ES,AX
mov EDI, Sector512 ;offset Sector512
mov DX, [ATABasePortAddr];регистр данных
mov CX, 256 ;число считываемых слов
mov edi, Sector512
mov dx, [ATABasePortAddr];регистр данных
mov cx, 256 ;число считываемых слов
rep insw ;принять блок данных
ret
; Записать код ошибки
@ -155,34 +254,32 @@ ReadHDD_ID:
mov [DevErrorCode], 6
@@End:
ret
iglobal
; Стандартные базовые адреса каналов 1 и 2
StandardATABases DW 1F0h, 170h
endg
;-----------------------------------------------------------------------------
uglobal
; Стандартные базовые адреса каналов 1 и 2
StandardATABases dw ?, ? ; 1F0h, 170h
; Номер канала
ChannelNumber DW ?
ChannelNumber dw ?
; Номер диска
DiskNumber DB ?
DiskNumber db ?
; Базовый адрес группы портов контроллера ATA
ATABasePortAddr DW ?
ATABasePortAddr dw ?
; Параметры ATA-команды
ATAFeatures DB ? ;особенности
ATASectorCount DB ? ;количество обрабатываемых секторов
ATASectorNumber DB ? ;номер начального сектора
ATACylinder DW ? ;номер начального цилиндра
ATAHead DB ? ;номер начальной головки
ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA)
ATACommand DB ? ;код команды, подлежащей выполнению
ATAFeatures db ? ;особенности
ATASectorCount db ? ;количество обрабатываемых секторов
ATASectorNumber db ? ;номер начального сектора
ATACylinder dw ? ;номер начального цилиндра
ATAHead db ? ;номер начальной головки
ATAAddressMode db ? ;режим адресации (0 - CHS, 1 - LBA)
ATACommand db ? ;код команды, подлежащей выполнению
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
; интервал ожидания, 2 - неверный код режима адресации,
; 3 - неверный номер канала, 4 - неверный номер диска,
; 5 - неверный номер головки, 6 - ошибка при выполнении
; команды)
; команды, 7 - таймаут при выборе канала)
DevErrorCode dd ?
endg
;-----------------------------------------------------------------------------
;****************************************************
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
;* Входные параметры передаются через глобальные *
@ -207,89 +304,85 @@ SendCommandToHDD:
cmp [ATAAddressMode], 1
ja @@Err2
; Проверить корректность номера канала
mov BX, [ChannelNumber]
cmp BX, 1
mov bx, [ChannelNumber]
cmp bx, 1
jb @@Err3
cmp BX, 2
cmp bx, 2
ja @@Err3
; Установить базовый адрес
dec BX
shl BX, 1
dec bx
shl bx, 1
movzx ebx, bx
mov AX, [ebx+StandardATABases]
mov [ATABasePortAddr], AX
mov ax, [ebx+StandardATABases]
mov [ATABasePortAddr], ax
; Ожидание готовности HDD к приему команды
; Выбрать нужный диск
mov DX, [ATABasePortAddr]
add DX, 6 ;адрес регистра головок
mov AL, [DiskNumber]
cmp AL, 1 ;проверить номера диска
mov dx, [ATABasePortAddr]
add dx, 6 ;адрес регистра головок
mov al, [DiskNumber]
cmp al, 1 ;проверить номера диска
ja @@Err4
shl AL, 4
or AL, 10100000b
out DX, AL
shl al, 4
or al, 10100000b
out dx, al
; Ожидать, пока диск не будет готов
inc DX
inc dx
mov ecx, 0xfff
; mov eax,[timer_ticks]
; mov [TickCounter_1],eax
@@WaitHDReady:
; Проверить время ожидани
dec ecx
; cmp ecx,0
jz @@Err1
; mov eax,[timer_ticks]
; sub eax,[TickCounter_1]
; cmp eax,300 ;ожидать 300 тиков
; ja @@Err1 ;ошибка тайм-аута
; Прочитать регистр состояни
in AL, DX
in al, dx
; Проверить состояние сигнала BSY
test AL, 80h
test al, 80h
jnz @@WaitHDReady
; Проверить состояние сигнала DRQ
test AL, 08h
test al, 08h
jnz @@WaitHDReady
; Загрузить команду в регистры контроллера
cli
mov DX, [ATABasePortAddr]
inc DX ;регистр "особенностей"
mov AL, [ATAFeatures]
out DX, AL
inc DX ;счетчик секторов
mov AL, [ATASectorCount]
out DX, AL
inc DX ;регистр номера сектора
mov AL, [ATASectorNumber]
out DX, AL
inc DX ;номер цилиндра (младший байт)
mov AX, [ATACylinder]
out DX, AL
inc DX ;номер цилиндра (старший байт)
mov AL, AH
out DX, AL
inc DX ;номер головки/номер диска
mov AL, [DiskNumber]
shl AL, 4
cmp [ATAHead], 0Fh;проверить номер головки
mov dx, [ATABasePortAddr]
inc dx ;регистр "особенностей"
mov al, [ATAFeatures]
out dx, AL
inc dx ;счетчик секторов
mov al, [ATASectorCount]
out dx, AL
inc dx ;регистр номера сектора
mov al, [ATASectorNumber]
out dx, AL
inc dx ;номер цилиндра (младший байт)
mov ax, [ATACylinder]
out dx, AL
inc dx ;номер цилиндра (старший байт)
mov al, AH
out dx, AL
inc dx ;номер головки/номер диска
mov al, [DiskNumber]
shl al, 4
cmp [ATAHead], 0xF ;проверить номер головки
ja @@Err5
or AL, [ATAHead]
or AL, 10100000b
mov AH, [ATAAddressMode]
shl AH, 6
or AL, AH
out DX, AL
or al, [ATAHead]
or al, 10100000b
mov ah, [ATAAddressMode]
shl ah, 6
or al, ah
out dx, al
; Послать команду
mov AL, [ATACommand]
inc DX ;регистр команд
out DX, AL
mov al, [ATACommand]
inc dx ;регистр команд
out dx, al
sti
; Сбросить признак ошибки
mov [DevErrorCode], 0
ret
; Записать код ошибки
@@Err1:
mov [DevErrorCode], 1
mov [DevErrorCode], 7
ret
@@Err2:
mov [DevErrorCode], 2
@ -304,7 +397,7 @@ SendCommandToHDD:
mov [DevErrorCode], 5
; Завершение работы программы
ret
;-----------------------------------------------------------------------------
;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI *
;* Входные параметры передаются через глобальные *
@ -323,33 +416,32 @@ ReadCD_ID:
mov [ATASectorNumber], 0
mov [ATACylinder], 0
mov [ATAHead], 0
mov [ATACommand], 0A1h
mov [ATACommand], 0xA1
call SendCommandToHDD
cmp [DevErrorCode], 0;проверить код ошибки
jne @@End_1 ;закончить, сохранив код ошибки
; Ожидать готовность данных HDD
mov DX, [ATABasePortAddr]
add DX, 7 ;порт 1х7h
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
mov ecx, 0xffff
@@WaitCompleet_1:
; Проверить врем
dec ecx
; cmp ecx,0
jz @@Error1_1 ;ошибка тайм-аута
; Проверить готовность
in AL, DX
test AL, 80h ;состояние сигнала BSY
in al, dx
test al, 80h ;состояние сигнала BSY
jnz @@WaitCompleet_1
test AL, 1 ;состояние сигнала ERR
test al, 1 ;состояние сигнала ERR
jnz @@Error6_1
test AL, 08h ;состояние сигнала DRQ
test al, 08h ;состояние сигнала DRQ
jz @@WaitCompleet_1
; Принять блок данных от контроллера
; mov AX,DS
; mov ES,AX
mov EDI, Sector512 ;offset Sector512
mov DX, [ATABasePortAddr];порт 1x0h
mov CX, 256;число считываемых слов
mov edi, Sector512 ;offset Sector512
mov dx, [ATABasePortAddr];порт 1x0h
mov cx, 256;число считываемых слов
rep insw
ret
; Записать код ошибки
@ -360,7 +452,7 @@ ReadCD_ID:
mov [DevErrorCode], 6
@@End_1:
ret
;-----------------------------------------------------------------------------
;*************************************************
;* СБРОС УСТРОЙСТВА *
;* Входные параметры передаются через глобальные *
@ -370,39 +462,40 @@ ReadCD_ID:
;*************************************************
DeviceReset:
; Проверить корректность номера канала
mov BX, [ChannelNumber]
cmp BX, 1
mov bx, [ChannelNumber]
cmp bx, 1
jb @@Err3_2
cmp BX, 2
cmp bx, 2
ja @@Err3_2
; Установить базовый адрес
dec BX
shl BX, 1
dec bx
shl bx, 1
movzx ebx, bx
mov DX, [ebx+StandardATABases]
mov [ATABasePortAddr], DX
mov dx, [ebx+StandardATABases]
mov [ATABasePortAddr], dx
; Выбрать нужный диск
add DX, 6 ;адрес регистра головок
mov AL, [DiskNumber]
cmp AL, 1 ;проверить номера диска
add dx, 6 ;адрес регистра головок
mov al, [DiskNumber]
cmp al, 1 ;проверить номера диска
ja @@Err4_2
shl AL, 4
or AL, 10100000b
out DX, AL
shl al, 4
or al, 10100000b
out dx, al
; Послать команду "Сброс"
mov AL, 08h
inc DX ;регистр команд
out DX, AL
mov al, 0x8
inc dx ;регистр команд
out dx, al
mov ecx, 0x80000
@@WaitHDReady_1:
; Проверить время ожидани
dec ecx
; cmp ecx,0
je @@Err1_2 ;ошибка тайм-аута
; Прочитать регистр состояни
in AL, DX
in al, dx
; Проверить состояние сигнала BSY
test AL, 80h
test al, 80h
jnz @@WaitHDReady_1
; Сбросить признак ошибки
mov [DevErrorCode], 0
@ -418,6 +511,5 @@ DeviceReset:
mov [DevErrorCode], 4
; Записать код ошибки
ret
;-----------------------------------------------------------------------------
EndFindHDD:

View File

@ -7,6 +7,7 @@
$Revision$
;-----------------------------------------------------------------------------
pusha
mov eax, [pg_data.pages_free]
@ -20,89 +21,167 @@ $Revision$
; check a upper size of the cache, no more than 1 Mb on the physical device
cmp eax, 1024*1024
jbe @f
mov eax, 1024*1024
jmp .continue
;--------------------------------------
@@:
; check a lower size of the cache, not less than 128 Kb on the physical device
cmp eax, 128*1024
jae @f
mov eax, 128*1024
@@:
.continue:
mov [cache_ide0_size], eax
mov [cache_ide1_size], eax
mov [cache_ide2_size], eax
mov [cache_ide3_size], eax
xor eax, eax
mov [hdd_appl_data], 1;al
mov [cd_appl_data], 1
jae .continue
test byte [DRIVE_DATA+1], 2
je .ide2
mov esi, cache_ide3
call get_cache_ide
.ide2:
test byte [DRIVE_DATA+1], 8
je .ide1
mov esi, cache_ide2
call get_cache_ide
.ide1:
test byte [DRIVE_DATA+1], 0x20
je .ide0
mov esi, cache_ide1
call get_cache_ide
.ide0:
mov eax, 128*1024
;--------------------------------------
.continue:
push ecx
mov ecx, 12
mov esi, cache_ide0+IDE_CACHE.size
cld
@@:
mov [esi], eax
add esi, sizeof.IDE_CACHE
loop @b
pop ecx
xor eax, eax
mov [hdd_appl_data], 1 ;al
mov [cd_appl_data], 1
;--------------------------------------
test byte [DRIVE_DATA+1], 0x80
je @f
mov esi, cache_ide0
call get_cache_ide
;--------------------------------------
@@:
jmp end_get_cache
test byte [DRIVE_DATA+1], 0x20
je @f
mov esi, cache_ide1
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+1], 8
je @f
mov esi, cache_ide2
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+1], 2
je @f
mov esi, cache_ide3
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+6], 0x80
je @f
mov esi, cache_ide4
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+6], 0x20
je @f
mov esi, cache_ide5
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+6], 8
je @f
mov esi, cache_ide6
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+6], 2
je @f
mov esi, cache_ide7
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+11], 0x80
je @f
mov esi, cache_ide8
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+11], 0x20
je @f
mov esi, cache_ide9
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+11], 8
je @f
mov esi, cache_ide10
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+11], 2
je end_get_cache
mov esi, cache_ide11
call get_cache_ide
jmp end_get_cache
;-----------------------------------------------------------------------------
get_cache_ide:
and [esi+cache_ide0_search_start-cache_ide0], 0
and [esi+cache_ide0_appl_search_start-cache_ide0], 0
and [esi+IDE_CACHE.search_start], 0
and [esi+IDE_CACHE.appl_search_start], 0
push ecx
stdcall kernel_alloc, [esi+cache_ide0_size-cache_ide0]
mov [esi+cache_ide0_pointer-cache_ide0], eax
; DEBUGF 1, "K : IDE_CACHE.size %x\n", [esi+IDE_CACHE.size]
stdcall kernel_alloc, [esi+IDE_CACHE.size]
mov [esi+IDE_CACHE.pointer], eax
pop ecx
mov edx, eax
mov eax, [esi+cache_ide0_size-cache_ide0]
mov eax, [esi+IDE_CACHE.size]
shr eax, 3
mov [esi+cache_ide0_system_data_size-cache_ide0], eax
; DEBUGF 1, "K : IDE_CACHE.system_data_size %x\n", eax
mov [esi+IDE_CACHE.system_data_size], eax
mov ebx, eax
imul eax, 7
mov [esi+cache_ide0_appl_data_size-cache_ide0], eax
; DEBUGF 1, "K : IDE_CACHE.appl_data_size %x\n", eax
mov [esi+IDE_CACHE.appl_data_size], eax
add ebx, edx
mov [esi+cache_ide0_data_pointer-cache_ide0], ebx
mov [esi+IDE_CACHE.data_pointer], ebx
.cd:
push ecx
mov eax, [esi+cache_ide0_system_data_size-cache_ide0]
mov eax, [esi+IDE_CACHE.system_data_size]
call calculate_for_cd
add eax, [esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0], eax
mov [esi+cache_ide0_system_sad_size-cache_ide0], ecx
add eax, [esi+IDE_CACHE.pointer]
mov [esi+IDE_CACHE.system_data], eax
mov [esi+IDE_CACHE.system_sad_size], ecx
push edi
mov edi, [esi+cache_ide0_pointer-cache_ide0]
mov edi, [esi+IDE_CACHE.pointer]
call clear_ide_cache
pop edi
mov eax, [esi+cache_ide0_appl_data_size-cache_ide0]
mov eax, [esi+IDE_CACHE.appl_data_size]
call calculate_for_cd
add eax, [esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0], eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0], ecx
add eax, [esi+IDE_CACHE.data_pointer]
mov [esi+IDE_CACHE.appl_data], eax
mov [esi+IDE_CACHE.appl_sad_size], ecx
push edi
mov edi, [esi+cache_ide0_data_pointer-cache_ide0]
mov edi, [esi+IDE_CACHE.data_pointer]
call clear_ide_cache
pop edi
pop ecx
ret
;-----------------------------------------------------------------------------
calculate_for_cd:
push eax
mov ebx, eax
@ -116,7 +195,7 @@ calculate_for_cd:
sub eax, ebx
dec ecx
ret
;-----------------------------------------------------------------------------
clear_ide_cache:
push eax
shl ecx, 1
@ -125,6 +204,6 @@ clear_ide_cache:
rep stosd
pop eax
ret
;-----------------------------------------------------------------------------
end_get_cache:
popa

View File

@ -0,0 +1,464 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5147 $
;-----------------------------------------------------------------------------
; find the IDE controller in the device list
;-----------------------------------------------------------------------------
mov ecx, IDE_controller_1
mov esi, pcidev_list
;--------------------------------------
align 4
.loop:
mov esi, [esi+PCIDEV.fd]
cmp esi, pcidev_list
jz find_IDE_controller_done
mov eax, [esi+PCIDEV.class]
; shr eax, 4
; cmp eax, 0x01018
shr eax, 7
cmp eax, 0x010180 shr 7
jnz .loop
;--------------------------------------
.found:
mov eax, [esi+PCIDEV.class]
DEBUGF 1, 'K : IDE controller programming interface %x\n', eax
mov [ecx+IDE_DATA.ProgrammingInterface], eax
mov ah, [esi+PCIDEV.bus]
mov al, 2
mov bh, [esi+PCIDEV.devfn]
;--------------------------------------
mov dx, 0x1F0
test byte [esi+PCIDEV.class], 1
jz @f
mov bl, 0x10
push eax
call pci_read_reg
and eax, 0xFFFC
mov edx, eax
pop eax
@@:
DEBUGF 1, 'K : BAR0 IDE base addr %x\n', dx
mov [StandardATABases], dx
mov [ecx+IDE_DATA.BAR0_val], dx
;--------------------------------------
mov dx, 0x3F4
test byte [esi+PCIDEV.class], 1
jz @f
mov bl, 0x14
push eax
call pci_read_reg
and eax, 0xFFFC
mov edx, eax
pop eax
@@:
DEBUGF 1, 'K : BAR1 IDE base addr %x\n', dx
mov [ecx+IDE_DATA.BAR1_val], dx
;--------------------------------------
mov dx, 0x170
test byte [esi+PCIDEV.class], 4
jz @f
mov bl, 0x18
push eax
call pci_read_reg
and eax, 0xFFFC
mov edx, eax
pop eax
@@:
DEBUGF 1, 'K : BAR2 IDE base addr %x\n', dx
mov [StandardATABases+2], dx
mov [ecx+IDE_DATA.BAR2_val], dx
;--------------------------------------
mov dx, 0x374
test byte [esi+PCIDEV.class], 4
jz @f
mov bl, 0x1C
push eax
call pci_read_reg
and eax, 0xFFFC
mov edx, eax
pop eax
@@:
DEBUGF 1, 'K : BAR3 IDE base addr %x\n', dx
mov [ecx+IDE_DATA.BAR3_val], dx
;--------------------------------------
mov bl, 0x20
push eax
call pci_read_reg
and eax, 0xFFFC
DEBUGF 1, 'K : BAR4 IDE controller register base addr %x\n', ax
mov [ecx+IDE_DATA.RegsBaseAddres], ax
pop eax
;--------------------------------------
mov bl, 0x3C
push eax
call pci_read_reg
and eax, 0xFF
DEBUGF 1, 'K : IDE Interrupt %x\n', al
mov [ecx+IDE_DATA.Interrupt], ax
pop eax
add ecx, sizeof.IDE_DATA
;--------------------------------------
jmp .loop
;-----------------------------------------------------------------------------
uglobal
align 4
;--------------------------------------
IDE_controller_pointer dd ?
;--------------------------------------
IDE_controller_1 IDE_DATA
IDE_controller_2 IDE_DATA
IDE_controller_3 IDE_DATA
;--------------------------------------
cache_ide0 IDE_CACHE
cache_ide1 IDE_CACHE
cache_ide2 IDE_CACHE
cache_ide3 IDE_CACHE
cache_ide4 IDE_CACHE
cache_ide5 IDE_CACHE
cache_ide6 IDE_CACHE
cache_ide7 IDE_CACHE
cache_ide8 IDE_CACHE
cache_ide9 IDE_CACHE
cache_ide10 IDE_CACHE
cache_ide11 IDE_CACHE
;--------------------------------------
IDE_device_1 rd 2
IDE_device_2 rd 2
IDE_device_3 rd 2
;--------------------------------------
endg
;-----------------------------------------------------------------------------
; START of initialisation IDE ATA code
;-----------------------------------------------------------------------------
Init_IDE_ATA_controller:
cmp [ecx+IDE_DATA.ProgrammingInterface], 0
jne @f
ret
;--------------------------------------
@@:
mov esi, boot_disabling_ide
call boot_log
;--------------------------------------
; Disable IDE interrupts, because the search
; for IDE partitions is in the PIO mode.
;--------------------------------------
.disable_IDE_interrupt:
; Disable interrupts in IDE controller for PIO
mov al, 2
mov dx, [ecx+IDE_DATA.BAR1_val] ;0x3F4
add dx, 2 ;0x3F6
out dx, al
mov dx, [ecx+IDE_DATA.BAR3_val] ;0x374
add dx, 2 ;0x376
out dx, al
;-----------------------------------------------------------------------------
; set current ata bases
@@:
mov ax, [ecx+IDE_DATA.BAR0_val]
mov [StandardATABases], ax
mov ax, [ecx+IDE_DATA.BAR2_val]
mov [StandardATABases+2], ax
mov esi, boot_detecthdcd
call boot_log
;--------------------------------------
include 'dev_hdcd.inc'
;--------------------------------------
ret
;-----------------------------------------------------------------------------
Init_IDE_ATA_controller_2:
cmp [ecx+IDE_DATA.ProgrammingInterface], 0
jne @f
ret
;--------------------------------------
@@:
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
; 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, [ecx+IDE_DATA.BAR0_val] ;0x1F0
add dx, 0x7 ;0x1F7
in al, dx
mov dx, [ecx+IDE_DATA.BAR2_val] ;0x170
add dx, 0x7 ;0x177
in al, dx
;-----------------------------------------------------------------------------
; push eax edx
; mov dx, [ecx+IDE_DATA.RegsBaseAddres]
; 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 [ecx+IDE_DATA.RegsBaseAddres], 0
; setnz [ecx+IDE_DATA.dma_hdd]
;-----------------------------------------------------------------------------
; set interrupts for IDE Controller
;-----------------------------------------------------------------------------
pushfd
cli
.enable_IDE_interrupt:
mov esi, boot_enabling_ide
call boot_log
; Enable interrupts in IDE controller for DMA
xor ebx, ebx
cmp ecx, IDE_controller_2
jne @f
add ebx, 5
jmp .check_DRIVE_DATA
;--------------------------------------
@@:
cmp ecx, IDE_controller_3
jne .check_DRIVE_DATA
add ebx, 10
;--------------------------------------
.check_DRIVE_DATA:
mov al, 0
mov ah, [ebx+DRIVE_DATA+1]
test ah, 10100000b ; check for ATAPI devices
jz @f
;--------------------------------------
.ch1_pio_set_ATAPI:
DEBUGF 1, "K : IDE CH1 PIO, because ATAPI drive present\n"
jmp .ch1_pio_set_for_all
;--------------------------------------
.ch1_pio_set_no_devices:
DEBUGF 1, "K : IDE CH1 PIO because no devices\n"
jmp .ch1_pio_set_for_all
;-------------------------------------
.ch1_pio_set:
DEBUGF 1, "K : IDE CH1 PIO because device not support UDMA\n"
;-------------------------------------
.ch1_pio_set_for_all:
mov [ecx+IDE_DATA.dma_hdd_channel_1], al
jmp .ch2_check
;--------------------------------------
@@:
xor ebx, ebx
call calculate_IDE_device_values_storage
test ah, 1010000b
jz .ch1_pio_set_no_devices
test ah, 1000000b
jz @f
cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al
je .ch1_pio_set
cmp [ebx+IDE_DEVICE.UDMA_set_mode], al
je .ch1_pio_set
;--------------------------------------
@@:
test ah, 10000b
jz @f
add ebx, 2
cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al
je .ch1_pio_set
cmp [ebx+IDE_DEVICE.UDMA_set_mode], al
je .ch1_pio_set
;--------------------------------------
@@:
mov dx, [ecx+IDE_DATA.BAR1_val] ;0x3F4
add dx, 2 ;0x3F6
out dx, al
DEBUGF 1, "K : IDE CH1 DMA enabled\n"
mov [ecx+IDE_DATA.dma_hdd_channel_1], byte 1
;--------------------------------------
.ch2_check:
test ah, 1010b ; check for ATAPI devices
jz @f
;--------------------------------------
.ch2_pio_set_ATAPI:
DEBUGF 1, "K : IDE CH2 PIO, because ATAPI drive present\n"
jmp .ch2_pio_set_for_all
;--------------------------------------
.ch2_pio_set_no_devices:
DEBUGF 1, "K : IDE CH2 PIO because no devices\n"
jmp .ch2_pio_set_for_all
;--------------------------------------
.ch2_pio_set:
DEBUGF 1, "K : IDE CH2 PIO because device not support UDMA\n"
;--------------------------------------
.ch2_pio_set_for_all:
mov [ecx+IDE_DATA.dma_hdd_channel_2], al
jmp .set_interrupts_for_IDE_controllers
;--------------------------------------
@@:
mov ebx, 4
call calculate_IDE_device_values_storage
test ah, 101b
jz .ch2_pio_set_no_devices
test ah, 100b
jz @f
cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al
je .ch2_pio_set
cmp [ebx+IDE_DEVICE.UDMA_set_mode], al
je .ch2_pio_set
;--------------------------------------
@@:
test ah, 1b
jz @f
add ebx, 2
cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al
je .ch2_pio_set
cmp [ebx+IDE_DEVICE.UDMA_set_mode], al
je .ch2_pio_set
;--------------------------------------
@@:
mov dx, [ecx+IDE_DATA.BAR3_val] ;0x374
add dx, 2 ;0x376
out dx, al
DEBUGF 1, "K : IDE CH2 DMA enabled\n"
mov [ecx+IDE_DATA.dma_hdd_channel_2], byte 1
;--------------------------------------
.set_interrupts_for_IDE_controllers:
mov esi, boot_set_int_IDE
call boot_log
;--------------------------------------
mov eax, [ecx+IDE_DATA.ProgrammingInterface]
; cmp ax, 0x0180
; je .pata_ide
; cmp ax, 0x018a
; jne .sata_ide
test al, 1 ; 0 - legacy PCI mode, 1 - native PCI mode
jnz .sata_ide
;--------------------------------------
.pata_ide:
cmp [ecx+IDE_DATA.RegsBaseAddres], 0
je .end_set_interrupts
push ecx
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
pop ecx
jmp .end_set_interrupts
;--------------------------------------
.sata_ide:
; cmp ax, 0x0185
; je .sata_ide_1
; cmp ax, 0x018f
; jne .end_set_interrupts
;--------------------------------------
;.sata_ide_1:
; Some weird controllers generate an interrupt even if IDE interrupts
; are disabled and no IDE devices. For example, notebook ASUS K72F -
; IDE controller 010185 generates false interrupt when we work with
; the IDE controller 01018f. For this reason, the interrupt handler
; does not need to be installed if both channel IDE controller
; running in PIO mode.
cmp [ecx+IDE_DATA.RegsBaseAddres], 0
je .end_set_interrupts
cmp [ecx+IDE_DATA.dma_hdd_channel_1], 0
jne @f
cmp [ecx+IDE_DATA.dma_hdd_channel_2], 0
je .end_set_interrupts
;--------------------------------------
@@:
mov ax, [ecx+IDE_DATA.Interrupt]
movzx eax, al
push ecx
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0
pop ecx
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [ecx+IDE_DATA.Interrupt]:1, eax
;--------------------------------------
.end_set_interrupts:
popfd
ret
;-----------------------------------------------------------------------------
; END of initialisation IDE ATA code
;-----------------------------------------------------------------------------
find_IDE_controller_done:
mov ecx, IDE_controller_1
mov [IDE_controller_pointer], ecx
call Init_IDE_ATA_controller
mov ecx, IDE_controller_2
mov [IDE_controller_pointer], ecx
call Init_IDE_ATA_controller
mov ecx, IDE_controller_3
mov [IDE_controller_pointer], ecx
call Init_IDE_ATA_controller
;-----------------------------------------------------------------------------
mov esi, boot_getcache
call boot_log
include 'getcache.inc'
;-----------------------------------------------------------------------------
mov esi, boot_detectpart
call boot_log
include 'sear_par.inc'
;-----------------------------------------------------------------------------
mov esi, boot_init_sys
call boot_log
call Parser_params
if ~ defined extended_primary_loader
; ramdisk image should be loaded by extended primary loader if it exists
; READ RAMDISK IMAGE FROM HD
include '../boot/rdload.inc'
end if
;-----------------------------------------------------------------------------
mov ecx, IDE_controller_1
mov [IDE_controller_pointer], ecx
call Init_IDE_ATA_controller_2
mov ecx, IDE_controller_2
mov [IDE_controller_pointer], ecx
call Init_IDE_ATA_controller_2
mov ecx, IDE_controller_3
mov [IDE_controller_pointer], ecx
call Init_IDE_ATA_controller_2
;-----------------------------------------------------------------------------

View File

@ -8,63 +8,203 @@
$Revision$
search_partitions:
push ecx
; 1. Fill missing parameters in HD_DATA structures.
mov eax, [hd_address_table]
mov [hd0_data.hdbase], eax ;0x1f0
xor eax, eax
mov edx, IDE_controller_1
mov ax, [edx + IDE_DATA.BAR0_val]
mov [hd0_data.hdbase], eax
mov [hd1_data.hdbase], eax
mov eax, [hd_address_table+16]
mov ax, [edx + IDE_DATA.BAR2_val]
mov [hd2_data.hdbase], eax
mov [hd3_data.hdbase], eax
mov edx, IDE_controller_2
mov ax, [edx + IDE_DATA.BAR0_val]
mov [hd4_data.hdbase], eax
mov [hd5_data.hdbase], eax
mov ax, [edx + IDE_DATA.BAR2_val]
mov [hd6_data.hdbase], eax
mov [hd7_data.hdbase], eax
mov edx, IDE_controller_3
mov ax, [edx + IDE_DATA.BAR0_val]
mov [hd8_data.hdbase], eax
mov [hd9_data.hdbase], eax
mov ax, [edx + IDE_DATA.BAR2_val]
mov [hd10_data.hdbase], eax
mov [hd11_data.hdbase], eax
; 2. Notify the system about /hd* disks.
; For every existing disk, call ide_disk_add with correct parameters.
; Generate name "hdN" on the stack; this is 4 bytes including terminating zero.
;-----------------------------------------------------------------------------
; 2a. /hd0: exists if mask 0x40 in [DRIVE_DATA+1] is set,
; data: hd0_data,
; number of partitions: [DRIVE_DATA+2]
test [DRIVE_DATA+1], byte 0x40
jz @f
push 'hd0'
mov eax, esp ; name
mov edx, hd0_data
call ide_disk_add
mov [DRIVE_DATA+2], al
pop ecx ; restore the stack
;-----------------------------------------------------------------------------
@@:
; 2b. /hd1: exists if mask 0x10 in [DRIVE_DATA+1] is set,
; data: hd1_data,
; number of partitions: [DRIVE_DATA+3]
test [DRIVE_DATA+1], byte 0x10
jz @f
push 'hd1'
mov eax, esp
mov edx, hd1_data
call ide_disk_add
mov [DRIVE_DATA+3], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2c. /hd2: exists if mask 4 in [DRIVE_DATA+1] is set,
; data: hd2_data,
; number of partitions: [DRIVE_DATA+4]
test [DRIVE_DATA+1], byte 4
jz @f
push 'hd2'
mov eax, esp
mov edx, hd2_data
call ide_disk_add
mov [DRIVE_DATA+4], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2d. /hd3: exists if mask 1 in [DRIVE_DATA+1] is set,
; data: hd3_data,
; number of partitions: [DRIVE_DATA+5]
test [DRIVE_DATA+1], byte 1
jz @f
push 'hd3'
mov eax, esp
mov edx, hd3_data
call ide_disk_add
mov [DRIVE_DATA+5], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2e. /hd4: exists if mask 0x40 in [DRIVE_DATA+6] is set,
; data: hd4_data,
; number of partitions: [DRIVE_DATA+7]
test [DRIVE_DATA+6], byte 0x40
jz @f
push 'hd4'
mov eax, esp ; name
mov edx, hd4_data
call ide_disk_add
mov [DRIVE_DATA+7], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2f. /hd5: exists if mask 0x10 in [DRIVE_DATA+6] is set,
; data: hd5_data,
; number of partitions: [DRIVE_DATA+8]
test [DRIVE_DATA+6], byte 0x10
jz @f
push 'hd5'
mov eax, esp
mov edx, hd5_data
call ide_disk_add
mov [DRIVE_DATA+8], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2g. /hd6: exists if mask 4 in [DRIVE_DATA+6] is set,
; data: hd6_data,
; number of partitions: [DRIVE_DATA+9]
test [DRIVE_DATA+6], byte 4
jz @f
push 'hd6'
mov eax, esp
mov edx, hd6_data
call ide_disk_add
mov [DRIVE_DATA+9], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2h. /hd7: exists if mask 1 in [DRIVE_DATA+6] is set,
; data: hd7_data,
; number of partitions: [DRIVE_DATA+10]
test [DRIVE_DATA+6], byte 1
jz @f
push 'hd7'
mov eax, esp
mov edx, hd7_data
call ide_disk_add
mov [DRIVE_DATA+10], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2i. /hd8: exists if mask 0x40 in [DRIVE_DATA+11] is set,
; data: hd8_data,
; number of partitions: [DRIVE_DATA+12]
test [DRIVE_DATA+11], byte 0x40
jz @f
push 'hd8'
mov eax, esp ; name
mov edx, hd8_data
call ide_disk_add
mov [DRIVE_DATA+12], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2j. /hd9: exists if mask 0x10 in [DRIVE_DATA+11] is set,
; data: hd9_data,
; number of partitions: [DRIVE_DATA+13]
test [DRIVE_DATA+11], byte 0x10
jz @f
push 'hd9'
mov eax, esp
mov edx, hd9_data
call ide_disk_add
mov [DRIVE_DATA+13], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2k. /hd10: exists if mask 4 in [DRIVE_DATA+11] is set,
; data: hd10_data,
; number of partitions: [DRIVE_DATA+14]
test [DRIVE_DATA+14], byte 4
jz @f
push 'hd10'
mov eax, esp
mov edx, hd10_data
call ide_disk_add
mov [DRIVE_DATA+9], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2l. /hd11: exists if mask 1 in [DRIVE_DATA+11] is set,
; data: hd11_data,
; number of partitions: [DRIVE_DATA+15]
test [DRIVE_DATA+11], byte 1
jz @f
push 'hd11'
mov eax, esp
mov edx, hd11_data
call ide_disk_add
mov [DRIVE_DATA+15], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 3. Notify the system about /bd* disks.
; 3a. Check whether there are BIOS disks. If no, skip step 3.
@ -115,10 +255,10 @@ endg
pop ecx ecx ; restore stack after name
.nobd:
jmp end_search_partitions
;-----------------------------------------------------------------------------
; Helper procedure for search_partitions, adds one IDE disk.
; For compatibility, number of partitions for IDE disks is kept in a separate variable,
; so the procedure returns number of partitions.
; For compatibility, number of partitions for IDE disks is kept in a separate
; variable, so the procedure returns number of partitions.
; eax -> name, edx -> disk data
proc ide_disk_add
stdcall disk_add, ide_callbacks, eax, edx, 0
@ -134,6 +274,6 @@ proc ide_disk_add
@@:
ret
endp
end_search_partitions:
;-----------------------------------------------------------------------------
end_search_partitions:
pop ecx

View File

@ -86,9 +86,9 @@
* рисуется внешняя рамка цвета, указанного в edi,
шириной 1 пиксель
* рисуется заголовок - прямоугольник с левым верхним углом (1,1)
и правым нижним (xsize-1,min(25,ysize)) цвета, указанного в esi
и правым нижним (xsize-1,min(20,ysize-1)) цвета, указанного в esi
(с учетом градиента)
* если ysize>=26, то закрашивается рабочая область окна -
* если ysize>21, то закрашивается рабочая область окна -
прямоугольник с левым верхним углом (1,21) и правым нижним
(xsize-1,ysize-1) (размерами (xsize-1)*(ysize-21)) - цветом,
указанным в edx (с учетом градиента)
@ -151,7 +151,9 @@
Возвращаемое значение:
* если буфер пуст, возвращается eax=1
* если буфер непуст, то возвращается al=0, ah=код нажатой клавиши,
старшее слово регистра eax обнулено
биты 16-23 содержат сканкод нажатой клавиши в режиме ASCII,
в режме сканкодов биты обнулены.
биты 23-31 обнулены
* если есть "горячая клавиша", то возвращается
al=2, ah=сканкод нажатой клавиши (0 для управляющих клавиш),
старшее слово регистра eax содержит состояние управляющих клавиш
@ -816,9 +818,9 @@
вызове, оно может измениться в последующих версиях ядра.
======================================================================
======== Функция 18, подфункция 10 - свернуть окно приложения. =======
========= Функция 18, подфункция 10 - свернуть активное окно. ========
======================================================================
Сворачивает собственное окно.
Сворачивает активное окно.
Параметры:
* eax = 18 - номер функции
* ebx = 10 - номер подфункции
@ -843,8 +845,7 @@
* eax = 18 - номер функции
* ebx = 11 - номер подфункции
* ecx = тип таблицы:
* 1 = короткая версия, 10 байт
* 2 = полная версия, 65536 байт
* 1 = короткая версия, 16 байт
* edx = указатель на буфер (в приложении) для таблицы
Возвращаемое значение:
* функция не возвращает значения
@ -861,6 +862,8 @@
Например, для стандартной конфигурации из одного 1.44-дисковода
здесь будет 40h, а для случая 1.2Mb на A: и 1.44Mb на B:
значение оказывается 24h.
Первый контроллер IDE:
* +1: byte: информация о жёстких дисках и CD-приводах, AABBCCDD,
где AA соответствует контроллеру IDE0, ..., DD - IDE3:
* 0 = устройство отсутствует
@ -869,31 +872,36 @@
Например, в случае HD на IDE0 и CD на IDE2 здесь будет 48h.
* +2: 4 db: число найденных разделов на жёстких дисках с
соответственно IDE0,...,IDE3.
Второй контроллер IDE:
* +6: byte: информация о жёстких дисках и CD-приводах, AABBCCDD
где AA соответствует контроллеру IDE4, ..., DD - IDE7:
* 0 = устройство отсутствует
* 1 = жёсткий диск
* 2 = CD-привод
Например, в случае HD на IDE4 и CD на IDE6 здесь будет 48h.
* +7: 4 db: число найденных разделов на жёстких дисках с
соответственно IDE4,...,IDE7.
Третий контроллер IDE:
* +11: byte: информация о жёстких дисках и CD-приводах, AABBCCDD
где AA соответствует контроллеру IDE8, ..., DD - IDE11:
* 0 = устройство отсутствует
* 1 = жёсткий диск
* 2 = CD-привод
Например, в случае HD на IDE8 и CD на IDE10 здесь будет 48h.
* +12: 4 db: число найденных разделов на жёстких дисках с
соответственно IDE8,...,IDE11.
При отсутствии жёсткого диска на IDEx соответствующий байт
нулевой, при наличии показывает число распознанных разделов,
которых может и не быть (если носитель не отформатирован или
если файловая система не поддерживается). В текущей версии ядра
для жёстких дисков поддерживаются только FAT16, FAT32 и NTFS.
* +6: 4 db: зарезервировано
Формат таблицы: полная версия:
* +0: 10 db: такие же, как и в короткой версии
* +10: 100 db: данные для первого раздела
* +110: 100 db: данные для второго раздела
* ...
* +10+100*(n-1): 100 db: данные для последнего раздела
Разделы расположены в следующем порядке: сначала последовательно все
распознанные разделы на HD на IDE0 (если есть),
затем на HD на IDE1 (если есть) и т.д. до IDE3.
Формат информации о разделе:
* +0: dword: начальный физический сектор раздела
* +4: dword: последний физический сектор раздела
(принадлежит разделу)
* +8: byte: тип файловой системы:
16=FAT16, 32=FAT32, 1=NTFS
* формат дальнейших данных зависит от файловой системы,
может меняться с изменениями в ядре и поэтому не описывается
для жёстких дисков поддерживаются только FAT12/16/32, NTFS,
ext2/3/4 и XFS.
Замечания:
* Короткая таблица может быть использована для получения информации
* Таблица может быть использована для получения информации
об имеющихся устройствах.
======================================================================
@ -1208,20 +1216,6 @@ dd 1675
соответствующую текущей стране иконку.
* Приложение @panel переключает раскладки по запросу пользователя.
======================================================================
=========== Функция 21, подфункция 3 - установить базу CD. ===========
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 3 - номер подфункции
* ecx = база CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Возвращаемое значение:
* eax = 0
Замечания:
* База CD используется функцией 24.
* Получить установленную базу CD можно вызовом
подфункции 3 функции 26.
======================================================================
========= Функция 21, подфункция 5 - установить язык системы. ========
======================================================================
@ -1239,52 +1233,6 @@ dd 1675
переменную не использует.
* Получить язык системы можно вызовом подфункции 5 функции 26.
======================================================================
=========== Функция 21, подфункция 7 - установить базу HD. ===========
======================================================================
База HD нужна для определения, на какой жёсткий диск писать, при
использовании устаревшего синтаксиса /HD в устаревшей функции 58;
при использовании современного синтаксиса /HD0,/HD1,/HD2,/HD3
база устанавливается автоматически.
Параметры:
* eax = 21 - номер функции
* ebx = 7 - номер подфункции
* ecx = база HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Возвращаемое значение:
* eax = 0
Замечания:
* Любое приложение в любой момент времени может изменить базу.
* Не следует изменять базу, когда какое-нибудь приложение работает
с жёстким диском. Если не хотите глюков системы.
* Получить установленную базу можно вызовом подфункции 7 функции 26.
* Следует также определить используемый раздел жёсткого диска
подфункцией 8.
======================================================================
========== Функция 21, подфункция 8 - установить раздел HD. ==========
======================================================================
Раздел HD нужен для определения, на какой раздел жёсткого диска
писать, при использовании устаревшего синтаксиса /HD в устаревшей
функции 58; при использовании современного синтаксиса
/HD0,/HD1,/HD2,/HD3 база и раздел устанавливаются автоматически.
Параметры:
* eax = 21 - номер функции
* ebx = 8 - номер подфункции
* ecx = раздел HD (считая с 1)
Возвращаемое значение:
* eax = 0
Замечания:
* Любое приложение в любой момент времени может изменить раздел.
* Не следует изменять раздел, когда какое-нибудь приложение работает
с жёстким диском. Если не хотите глюков системы.
* Получить установленный раздел можно вызовом подфункции 8
функции 26.
* Проверок на корректность не делается.
* Узнать число разделов на жёстком диске можно вызовом
подфункции 11 функции 18.
* Следует также определить используемую базу жёсткого диска
подфункцией 7.
======================================================================
====================== Функция 21, подфункция 11 =====================
=========== Разрешить/запретить низкоуровневый доступ к HD. ==========
@ -1315,122 +1263,6 @@ dd 1675
* Текущая реализация использует только младший бит ecx.
* Получить текущее состояние можно вызовом подфункции 12 функции 26.
======================================================================
============= Функция 21, подфункция 13, подподфункция 1 =============
==== Инициализировать + получить информацию о драйвере vmode.mdr. ====
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 1 - номер функции драйвера
* edx = указатель на буфер размера 512 байт
Возвращаемое значение:
* если драйвер не загружен (никогда не бывает в текущей реализации):
* eax = -1
* ebx, ecx разрушаются
* если драйвер загружен:
* eax = 'MDAZ' (в стиле fasm'а, т.е. 'M' - младший байт,
'Z' - старший) - сигнатура
* ebx = текущая частота развёртки (в Гц)
* ecx разрушается
* буфер, на который указывает edx, заполнен
Формат буфера:
* +0: 32*byte: имя драйвера, "Trans VideoDriver" (без кавычек,
дополнено пробелами)
* +32 = +0x20: dword: версия драйвера (версия x.y кодируется как
y*65536+x), для текущей реализации 1 (1.0)
* +36 = +0x24: 7*dword: зарезервировано (0 в текущей реализации)
* +64 = +0x40: 32*word: список поддерживаемых видеорежимов (каждое
слово - номер видеорежима, после собственно списка идут нули)
* +128 = +0x80: 32*(5*word): список поддерживаемых частот развёрток
для видеорежимов: для каждого видеорежима, указанного в предыдущем
поле, указано до 5 поддерживаемых частот
(в неиспользуемых позициях записаны нули)
Замечания:
* Функция инициализирует драйвер (если он ещё не инициализирован)
и должна вызываться первой, перед остальными (иначе они будут
возвращать -1, ничего не делая).
* В текущей реализации поддерживается только одна частота развёртки
на видеорежим.
======================================================================
============= Функция 21, подфункция 13, подподфункция 2 =============
============= Получить информацию о текущем видеорежиме. =============
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 2 - номер функции драйвера
Возвращаемое значение:
* eax = -1 - драйвер не загружен или не инициализирован;
ebx,ecx разрушаются
* eax = [ширина]*65536 + [высота]
* ebx = частота вертикальной развёртки (в Гц)
* ecx = номер текущего видеорежима
Замечания:
* Драйвер предварительно должен быть инициализирован вызовом
функции драйвера 1.
* Если нужны только размеры экрана, целесообразней использовать
функцию 14 с учётом того, что она возвращает размеры на 1 меньше.
======================================================================
= Функция 21, подфункция 13, подподфункция 3 - установить видеорежим.
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 3 - номер функции драйвера
* edx = [частота развёртки]*65536 + [номер видеорежима]
Возвращаемое значение:
* eax = -1 - драйвер не загружен, не инициализирован или
произошла ошибка
* eax = 0 - успешно
* ebx, ecx разрушаются
Замечания:
* Драйвер предварительно должен быть инициализирован вызовом
функции драйвера 1.
* Номер видеорежима и частота должны быть в таблице, возвращаемой
функцией драйвера 1.
======================================================================
============= Функция 21, подфункция 13, подподфункция 4 =============
================= Вернуться к начальному видеорежиму. ================
======================================================================
Возвращает экран в видеорежим, установленный при загрузке системы.
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 4 - номер функции драйвера
Возвращаемое значение:
* eax = -1 - драйвер не загружен или не инициализирован
* eax = 0 - успешно
* ebx, ecx разрушаются
Замечания:
* Драйвер предварительно должен быть инициализирован вызовом
функции драйвера 1.
======================================================================
============= Функция 21, подфункция 13, подподфункция 5 =============
======== Увеличить/уменьшить размер видимой области монитора. ========
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 5 - номер функции драйвера
* edx = 0/1 - уменьшить/увеличить размер по горизонтали
на одну позицию
* edx = 2/3 - в текущей реализации не поддерживается; планируется
как уменьшение/увеличение размера по вертикали на одну позицию
Возвращаемое значение:
* eax = -1 - драйвер не загружен или не инициализирован
* eax = 0 - успешно
* ebx, ecx разрушаются
Замечания:
* Драйвер предварительно должен быть инициализирован вызовом
функции драйвера 1.
* Функция влияет только на физический размер изображения
на мониторе; логический размер (число пикселей) не меняется.
======================================================================
============ Функция 22 - установить системную дату/время. ===========
======================================================================
@ -1493,59 +1325,6 @@ dd 1675
с eax=0, если сложение ebx с текущим значением счётчика времени
вызовет 32-битное переполнение.
======================================================================
======= Функция 24, подфункция 1 - начать проигрывать CD-audio. ======
======================================================================
Параметры:
* eax = 24 - номер функции
* ebx = 1 - номер подфункции
* ecx = 0x00FRSSMM, где
* MM = начальная минута
* SS = начальная секунда
* FR = начальный фрейм
Возвращаемое значение:
* eax = 0 - успешно
* eax = 1 - не определена база CD
Замечания:
* Предварительно нужно определить базовый порт CD вызовом
подфункции 3 функции 21.
* В секунде 75 фреймов, в минуте 60 секунд.
* Функция асинхронна (возвращает управление, когда началось
проигрывание).
======================================================================
===== Функция 24, подфункция 2 - получить информацию о дорожках. =====
======================================================================
Параметры:
* eax = 24 - номер функции
* ebx = 2 - номер подфункции
* ecx = указатель на буфер для таблицы
(максимум 8*64h+4 байт=100 дорожек)
Возвращаемое значение:
* eax = 0 - успешно
* eax = 1 - не определена база CD
Замечания:
* Формат таблицы с информацией о дорожках такой же, как и для
ATAPI-CD команды 43h (READ TOC), обычной таблицы (подкоманда 00h).
Адреса возвращаются в формате MSF.
* Предварительно нужно определить базовый порт CD вызовом
подфункции 3 функции 21.
* Функция возвращает информацию только о не более чем 100
первых дорожках. В большинстве случаев этого достаточно.
======================================================================
==== Функция 24, подфункция 3 - остановить проигрываемое CD-audio. ===
======================================================================
Параметры:
* eax = 24 - номер функции
* ebx = 1 - номер подфункции
Возвращаемое значение:
* eax = 0 - успешно
* eax = 1 - не определена база CD
Замечания:
* Предварительно нужно определить базовый порт CD вызовом
подфункции 3 функции 21.
======================================================================
======= Функция 24, подфункция 4 - извлечь лоток привода диска. ======
======================================================================
@ -1553,7 +1332,9 @@ dd 1675
* eax = 24 - номер функции
* ebx = 4 - номер подфункции
* ecx = номер CD/DVD-диска
(от 0=Primary Master до 3=Secondary Slave)
от 0=Primary Master до 3=Secondary Slave для первого IDE контр.
от 4=Primary Master до 7=Secondary Slave для второго IDE контр.
от 8=Primary Master до 11=Secondary Slave для третьего IDE контр.
Возвращаемое значение:
* функция не возвращает значения
Замечания:
@ -1571,7 +1352,9 @@ dd 1675
* eax = 24 - номер функции
* ebx = 5 - номер подфункции
* ecx = номер CD/DVD-диска
(от 0=Primary Master до 3=Secondary Slave)
от 0=Primary Master до 3=Secondary Slave для первого IDE контр.
от 4=Primary Master до 7=Secondary Slave для второго IDE контр.
от 8=Primary Master до 11=Secondary Slave для третьего IDE контр.
Возвращаемое значение:
* функция не возвращает значения
Замечания:
@ -1648,18 +1431,6 @@ dd 1675
(используя описываемую функцию).
* Приложение @panel переключает раскладки по запросу пользователя.
======================================================================
============ Функция 26, подфункция 3 - получить базу CD. ============
======================================================================
Параметры:
* eax = 26 - номер функции
* ebx = 3 - номер подфункции
Возвращаемое значение:
* eax = база CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Замечания:
* База CD используется функцией 24.
* Установить базу CD можно вызовом подфункции 3 функции 21.
======================================================================
========== Функция 26, подфункция 5 - получить язык системы. =========
======================================================================
@ -1674,42 +1445,6 @@ dd 1675
соответствующую иконку (используя описываемую функцию).
* Установить язык системы можно вызовом подфункции 5 функции 21.
======================================================================
============ Функция 26, подфункция 7 - получить базу HD. ============
======================================================================
База HD нужна для определения, на какой жёсткий диск писать, при
использовании устаревшего синтаксиса /HD в устаревшей функции 58;
при использовании современного синтаксиса /HD0,/HD1,/HD2,/HD3
база устанавливается автоматически.
Параметры:
* eax = 26 - номер функции
* ebx = 7 - номер подфункции
Возвращаемое значение:
* eax = база HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Замечания:
* Любое приложение в любой момент времени может изменить базу.
* Установить базу можно вызовом подфункции 7 функции 21.
* Получить используемый раздел жёсткого диска можно подфункцией 8.
======================================================================
=========== Функция 26, подфункция 8 - получить раздел HD. ===========
======================================================================
Раздел HD нужен для определения, на какой раздел жёсткого диска
писать, при использовании устаревшего синтаксиса /HD в устаревшей
функции 58; при использовании современного синтаксиса
/HD0,/HD1,/HD2,/HD3 база и раздел устанавливаются автоматически.
Параметры:
* eax = 26 - номер функции
* ebx = 8 - номер подфункции
Возвращаемое значение:
* eax = раздел HD (считая с 1)
Замечания:
* Любое приложение в любой момент времени может изменить раздел.
* Установить раздел можно вызовом подфункции 8 функции 21.
* Узнать число разделов на жёстком диске можно вызовом
подфункции 11 функции 18.
* Получить используемую базу жёсткого диска можно подфункцией 7.
======================================================================
=== Функция 26, подфункция 9 - получить значение счётчика времени. ===
======================================================================
@ -2543,221 +2278,6 @@ dword-значение цвета 0x00RRGGBB
* Если BIOS не поддерживает это расширение, поведение функции
эмулируется (через аналоги подфункций функции 62 режима ядра).
======================================================================
============== Функция 58 - работа с файловой системой. ==============
======================================================================
Параметры:
* eax = 58
* ebx = указатель на информационную структуру
Возвращаемое значение:
* eax = 0 - успешно; иначе код ошибки файловой системы
* в зависимости от подфункции может возвращаться значение и
в других регистрах
Общий формат информационной структуры:
* +0: dword: номер подфункции
* +4: dword: номер блока
* +8: dword: размер
* +12 = +0xC: dword: указатель на данные
* +16 = +0x10: dword: указатель на память для работы системы
(4096 байт)
* +20 = +0x14: n db: ASCIIZ-строка с именем файла
Уточнения - в документации на соответствующую подфункцию.
Имя файла нечувствительно к регистру латинских букв,
русские буквы должны быть заглавными.
Формат имени файла:
/base/number/dir1/dir2/.../dirn/file,
где /base/number идентифицирует устройство, на котором ищется файл:
одно из
* /RD/1 = /RAMDISK/1 для доступа к рамдиску
* /FD/1 = /FLOPPYDISK/1 для доступа к первому флоппи-дисководу,
/FD/2 = /FLOPPYDISK/2 для второго флоппи-дисковода
* /HD/x = /HARDDISK/x - устаревший вариант доступа к жёсткому диску
(в этом случае база определяется подфункцией 7 функции 21),
x - номер раздела (считая с 1)
* /HD0/x, /HD1/x, /HD2/x, /HD3/x для доступа соответственно
к устройствам IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave);
x - номер раздела на выбранном винчестере, изменяется от 1 до 255
(на каждом из винчестеров нумерация начинается с 1)
Замечания:
* В первых двух случаях допускается использование FIRST вместо 1,
SECOND вместо 2, но использовать эту возможность
не рекомендуется для удобства перехода на будущие расширения.
* Накладывается ограничение n<=39.
* Имена папок и файла dir1,...,dirn,file должны быть в формате 8.3:
имя не более 8 символов, точка, расширение не более 3 символов.
Хвостовые пробелы игнорируются. Других пробелов быть не должно.
Если имя занимает ровно 8 символов, точку можно опустить
(хотя пользоваться этим не рекомендуется для удобства перехода
на будущие расширения).
* Функция не поддерживает папок на рамдиске.
Примеры:
* '/RAMDISK/FIRST/KERNEL.ASM',0
'/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0
* '/hd0/1/menuet/pics/tanzania.bmp',0
Доступные подфункции:
* подфункция 0 - чтение файла/папки
* подфункция 8 - LBA-чтение с устройства
* подфункция 15 - получение информации о файловой системе
======================================================================
========== Функция 58, подфункция 0 - прочитать файл/папку. ==========
======================================================================
Параметры:
* eax = 58
* ebx = указатель на информационную структуру
Формат информационной структуры:
* +0: dword: 0 = номер подфункции
* +4: dword: номер блока для чтения (считая с 0)
* +8: dword: число блоков для чтения
* +12 = +0xC: dword: указатель на буфер, куда будут записаны данные
* +16 = +0x10: dword: указатель на буфер для работы системы
(4096 байт)
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в
общем описании
Возвращаемое значение:
* eax = 0 - успешно, иначе код ошибки файловой системы
* ebx = размер файла (в байтах) или
-1=0xffffffff, если файл не найден
Замечания:
* Размер блока - 512 байт.
* Эта функция устарела, для чтения файлов используйте подфункцию 0
функции 70, для чтения папок - подфункцию 1 функции 70.
* Функция позволяет читать содержимое папки. Из файловых систем
поддерживается только FAT. Формат FAT-папки описан в любой
документации по FAT.
* Размер папки определяется по размеру цепочки кластеров в FAT.
* Если файл кончился раньше, чем был прочитан последний запрошенный
блок, то функция прочитает, сколько сможет, после чего вернёт
eax=6 (EOF).
* Функция позволяет читать корневые папки /rd/1,/fd/x,/hd[n]/x, но
в первых двух случаях текущая реализация не следует
установленным правилам:
для /rd/1:
* если указано 0 блоков для чтения, считается,
что запрашивается 1;
* если запрашивается больше 14 блоков или начальный блок
не меньше 14-го, то возвращается eax=5 (not found) и ebx=-1;
* размер корневого каталога рамдиска = 14 блоков,
0x1C00=7168 байт; но возвращается ebx=0
(за исключением случая предыдущего пункта);
* как ни странно, можно прочитать 14-й блок (там, вообще говоря,
мусор - напоминаю, счёт ведётся с 0);
* если был запрошен хотя бы один блок с номером, не меньшим 14,
то возвращается eax=6(EOF); иначе eax=0.
Для /fd/x:
* если начальный блок не меньше 14-го, то возвращается
eax=5 (not found) и ebx=0;
* кстати говоря, формат FAT12 допускает дискеты с размером
корневого каталога меньше или больше 14 блоков;
* проверки длины не делается;
* если удалось прочитать данные с дискеты, возвращается
eax=0,ebx=0; в противном случае eax=10 (access denied), ebx=-1.
* Функция обрабатывает чтение специальных папок /,/rd,/fd,/hd[n];
но результат не соответствует ожидаемому
(по работе с обычными файлами/папками), не следует установленным
правилам, может измениться в следующих версиях ядра и потому
не описывается. Для получения информации об оборудовании
используйте подфункцию 11 функции 18 или
читайте соответствующие папки подфункцией 1 функции 70.
======================================================================
========= Функция 58, подфункция 8 - LBA-чтение с устройства. ========
======================================================================
Параметры:
* eax = 58 - номер функции
* ebx = указатель на информационную структуру
Формат информационной структуры:
* +0: dword: 8 = номер подфункции
* +4: dword: номер блока для чтения (считая с 0)
* +8: dword: игнорируется (устанавливайте в 1)
* +12 = +0xC: dword: указатель на буфер, куда будут записаны данные
(512 байт)
* +16 = +0x10: dword: указатель на буфер для работы системы
(4096 байт)
* +20 = +0x14: ASCIIZ-имя устройства: нечувствительно к регистру,
одно из /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n,
1<=n<=4 - номер устройства: 1=IDE0, ..., 4=IDE3.
Вместо цифр допускается, хотя и не рекомендуется для удобства
перехода на будущие расширения,
использование 'first','second','third','fourth'.
Возвращаемое значение:
* если указано имя устройства /hd/xxx, где xxx не находится
в списке выше:
* eax = ebx = 1
* если указано неправильное имя устройства
(за исключением предыдущего случая):
* eax = 5
* ebx не меняется
* если LBA-доступ запрещён подфункцией 11 функции 21:
* eax = 2
* ebx разрушается
* для рамдиска: попытка чтения блока за пределами рамдиска
(18*2*80 блоков) приводит к
* eax = 3
* ebx = 0
* при успешном чтении:
* eax = ebx = 0
Замечания:
* Размер блока - 512 байт; читается один блок.
* Не следует полагаться на возвращаемое значение,
оно может измениться в следующих версиях.
* Требуется, чтобы был разрешён LBA-доступ к устройствам
подфункцией 11 функции 21. Узнать это можно вызовом
подфункцией 11 функции 26.
* LBA-чтение дискеты не поддерживается.
* Функция считывает данные физического жёсткого диска;
если по каким-то причинам нужны данные конкретного раздела,
придётся определять начальный сектор этого раздела
(либо напрямую через MBR, либо из расширенной структуры,
возвращаемой той же подфункцией 11 функции 18).
* Функция не проверяет код ошибки жёсткого диска, так что запрос
несуществующего сектора всё равно что-то прочитает
(вероятнее всего, нули, но это определяется устройством) и
это будет считаться успехом (eax=0).
======================================================================
= Функция 58, подфункция 15 - получить информацию о файловой системе.
======================================================================
Параметры:
* eax = 58 - номер функции
* ebx = указатель на информационную структуру
Формат информационной структуры:
* +0: dword: 15 = номер подфункции
* +4: dword: игнорируется
* +8: dword: игнорируется
* +12 = +0xC: dword: игнорируется
* +16 = +0x10: dword: игнорируется
* +20 = +0x14: (проверяется только второй символ, сразу после слэша)
/rd=/RAMDISK или /hd=/HARDDISK
Возвращаемое значение:
* если второй символ не принадлежит множеству {'r','R','h','H'}:
* eax = 3
* ebx = ecx = dword [fileinfo] = 0
* для рамдиска:
* eax = 0 (успех)
* ebx = общее число кластеров = 2847
* ecx = число свободных кластеров
* dword [fileinfo] = размер кластера = 512
* для жёсткого диска: база и раздел определяются подфункциями 7 и 8
функции 21:
* eax = 0 (успех)
* ebx = общее число кластеров
* ecx = число свободных кластеров
* dword [fileinfo] = размер кластера (в байтах)
Замечания:
* Не удивляйтесь странному расположению 4-го возвращаемого
параметра - когда писался этот код, при системных вызовах
приложению возвращались только регистры eax,ebx,ecx (из
pushad-структуры, передающейся как аргумент системной функции).
Теперь это исправлено, так что, возможно, имеет смысл возвращать
размер кластера в edx, пока эту функцию не начали использовать.
* Вообще-то ещё существует подфункция 11 функции 18, возвращающая
информацию о файловой системе. По расширенной таблице дисковой
подсистемы можно определить размер кластера (там он хранится
в секторах) и общее число кластеров для жёстких дисков.
======================================================================
=========== Функция 60 - Inter Process Communication (IPC). ==========
======================================================================
@ -4544,12 +4064,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
Возвращаемое значение:
* eax = socketnum1, -1 для ошибки
* ebx = socketnum2, код ошибки в случае ошибки
Замечания:
Optstruct: dd level
dd optionname
dd optlength
db options...
======================================================================
========== Функция -1 - завершить выполнение потока/процесса =========

View File

@ -82,9 +82,9 @@ Remarks:
* The window of type I looks as follows:
* draw external frame of color indicated in edi, 1 pixel in width
* draw header - rectangle with the left upper corner (1,1) and
right lower (xsize-1,min(25,ysize)) color indicated in esi
right lower (xsize-1,min(20,ysize-1)) color indicated in esi
(taking a gradient into account)
* if ysize>=26, fill the working area of the window -
* if ysize>21, fill the working area of the window -
rectangle with the left upper corner (1,21) and right lower
(xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color
indicated in edx (taking a gradient into account)
@ -148,7 +148,10 @@ Parameters:
Returned value:
* if the buffer is empty, function returns eax=1
* if the buffer is not empty, function returns al=0,
ah=code of the pressed key, high word of eax is zero
ah=code of the pressed key,
bits 16-23 = contain scancode for pressed key in ASCII mode,
in the scancodes mode this bits cleared.
bits 23-31 = zero
* if there is "hotkey", function returns al=2,
ah=scancode of the pressed key (0 for control keys),
high word of eax contains a status of control keys at the moment
@ -815,9 +818,9 @@ Remarks:
changed in future versions of the kernel.
======================================================================
===== Function 18, subfunction 10 - minimize application window. =====
======= Function 18, subfunction 10 - minimize topmost window. =======
======================================================================
Minimizes the own window.
Minimizes the topmost (active) window.
Parameters:
* eax = 18 - function number
* ebx = 10 - subfunction number
@ -828,8 +831,8 @@ Remarks:
keeps position and sizes.
* Restoring of an application window occurs at its activation by
subfunction 3.
* Usually there is no necessity to minimize/restire a window
obviously: minimization of a window is carried out by the system
* Usually there is no necessity to minimize/restore a window
explicitly: minimization of a window is carried out by the system
at pressing the minimization button (for skinned windows
it is defined automatically by function 0,
for other windows it can be defined manually by function 8),
@ -842,8 +845,7 @@ Parameters:
* eax = 18 - function number
* ebx = 11 - subfunction number
* ecx = type of the table:
* 1 = short version, 10 bytes
* 2 = full version, 65536 bytes
* 1 = short version, 16 bytes
* edx = pointer to the buffer (in the application) for the table
Returned value:
* function does not return value
@ -859,42 +861,49 @@ Format of the table: short version:
* 5 = 2.88Mb, 3.5'' (such drives are not used anymore)
For example, for the standard configuration from one 1.44-drive
here will be 40h, and for the case 1.2Mb on A: and 1.44Mb on B:
the value is 24h.
the value is 24h.
First IDE controller:
* +1: byte: information about hard disks and CD-drives, AABBCCDD,
where AA corresponds to the controller IDE0, ..., DD - IDE3:
* 0 = device is absent
* 0 = device not found
* 1 = hard drive
* 2 = CD-drive
For example, in the case HD on IDE0 and CD on IDE2
this field contains 48h.
* +2: 4 db: number of the retrieved partitions on hard disks
at accordingly IDE0,...,IDE3.
at accordingly IDE0,...,IDE3.
Second IDE controller:
* +6: byte: information about hard disks and CD-drives, AABBCCDD,
where AA corresponds to the controller IDE4, ..., DD - IDE7:
* 0 = device not found
* 1 = hard drive
* 2 = CD-drive
For example, in the case HD on IDE4 and CD on IDE6
this field contains 48h.
* +7: 4 db: number of the retrieved partitions on hard disks
at accordingly IDE4,...,IDE7.
Third IDE controller:
* +11: byte: information about hard disks and CD-drives, AABBCCDD,
where AA corresponds to the controller IDE8, ..., DD - IDE11:
* 0 = device not found
* 1 = hard drive
* 2 = CD-drive
For example, in the case HD on IDE8 and CD on IDE10
this field contains 48h.
* +12: 4 db: number of the retrieved partitions on hard disks
at accordingly IDE8,...,IDE11.
If the hard disk on IDEx is absent, appropriate byte is zero,
otherwise it shows number of the recognized partitions, which
can be not presented (if the drive is not formatted or if
the file system is not supported). Current version of the kernel
supports only FAT16, FAT32 and NTFS for hard disks.
* +6: 4 db: reserved
Format of the table: full version:
* +0: 10 db: same as for the short version
* +10: 100 db: data for the first partition
* +110: 100 db: data for the second partition
* ...
* +10+100*(n-1): 100 db: data for the last partition
The partitions are located as follows: at first sequentially all
recoginzed partitions on HD on IDE0 (if present),
then on HD on IDE1 (if present) and so on up to IDE3.
Format of the information about partition
(at moment only FAT is supported):
* +0: dword: first physical sector of the partition
* +4: dword: last physical sector of the partition
(belongs to the partition)
* +8: byte: file system type:
16=FAT16, 32=FAT32, 1=NTFS
* other data are dependent on file system, are modified with
kernel modifications and therefore are not described
supports only FAT12/16/32, NTFS, ext2/3/4 and XFS for hard disks.
Remarks:
* The short table can be used for obtaining the information about
* The table can be used for obtaining the information about
available devices.
======================================================================
@ -1208,19 +1217,6 @@ Remarks:
the corresponding icon.
* The application @panel switches layouts on user request.
======================================================================
============== Function 21, subfunction 3 - set CD base. =============
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 3 - subfunction number
* ecx = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Returned value:
* eax = 0
Remarks:
* CD base is used by function 24.
* To get CD base use subfunction 3 of function 26.
======================================================================
========== Function 21, subfunction 5 - set system language. =========
======================================================================
@ -1238,49 +1234,6 @@ Remarks:
use this variable.
* To get system language use subfunction 5 of function 26.
======================================================================
============== Function 21, subfunction 7 - set HD base. =============
======================================================================
The HD base defines hard disk to write with usage of obsolete
syntax /HD in obsolete function 58; at usage of modern syntax
/HD0,/HD1,/HD2,/HD3 base is set automatically.
Parameters:
* eax = 21 - function number
* ebx = 7 - subfunction number
* ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Returned value:
* eax = 0
Remarks:
* Any application at any time can change the base.
* Do not change base, when any application works with hard disk.
If you do not want system bugs.
* To get HD base use subfunction 7 of function 26.
* It is also necessary to define used partition of hard disk by
subfunction 8.
======================================================================
========= Function 21, subfunction 8 - set used HD partition. ========
======================================================================
The HD partition defines partition of the hard disk to write with
usage of obsolete syntax /HD and obsolete function 58;
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
base and partition are set automatically.
Parameters:
* eax = 21 - function number
* ebx = 8 - subfunction number
* ecx = HD partition (beginning from 1)
Return value:
* eax = 0
Remarks:
* Any application at any time can change partition.
* Do not change partition when any application works with hard disk.
If you do not want system bugs.
* To get used partition use subfunction 8 of function 26.
* There is no correctness checks.
* To get the number of partitions of a hard disk use
subfunction 11 of function 18.
* It is also necessary to define used HD base by subfunction 7.
======================================================================
Function 21, subfunction 11 - enable/disable low-level access to HD.
======================================================================
@ -1309,120 +1262,6 @@ Remarks:
* The current implementation uses only low bit of ecx.
* To get current status use subfunction 12 of function 26.
======================================================================
============ Function 21, subfunction 13, subsubfunction 1 ===========
======== Initialize + get information on the driver vmode.mdr. =======
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 1 - number of the driver function
* edx = pointer to 512-bytes buffer
Returned value:
* if driver is not loaded
(never happens in the current implementation):
* eax = -1
* ebx, ecx destroyed
* if driver is loaded:
* eax = 'MDAZ' (in fasm style, that is 'M' - low byte, 'Z' - high)
- signature
* ebx = current frequency of the scanning (in Hz)
* ecx destroyed
* buffer pointed to by edx is filled
Format of the buffer:
* +0: 32*byte: driver name, "Trans VideoDriver"
(without quotes, supplemented by spaces)
* +32 = +0x20: dword: driver version (version x.y is encoded as
y*65536+x), for the current implementation is 1 (1.0)
* +36 = +0x24: 7*dword: reserved (0 in the current implementation)
* +64 = +0x40: 32*word: list of supported videomodes (each word
is number of a videomode, after list itself there are zeroes)
* +128 = +0x80: 32*(5*word): list of supported frequences of the
scannings for videomodes: for each videomode listed in the
previous field up to 5 supported frequences are given
(unused positions contain zeroes)
Remarks:
* Function initializes the driver (if it is not initialized yet)
and must be called first, before others (otherwise they will do
nothing and return -1).
* The current implementation supports only one frequency
of the scanning on videomode.
======================================================================
============ Function 21, subfunction 13, subsubfunction 2 ===========
================ Get information on current videomode. ===============
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 2 - number of the driver function
Returned value:
* eax = -1 - driver is not loaded or not initialized;
ebx,ecx are destroyed
* eax = [width]*65536 + [height]
* ebx = frequency of the vertical scanning (in Hz)
* ecx = number of current videomode
Remarks:
* Driver must be initialized by call to
driver function 1.
* If only screen sizes are required, it is more expedient to use
function 14 taking into account that it
returns sizes on 1 less.
======================================================================
=== Function 21, subfunction 13, subsubfunction 3 - set videomode. ===
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 3 - number of the driver function
* edx = [scanning frequency]*65536 + [videomode number]
Returned value:
* eax = -1 - driver is not loaded, not initialized or
an error has occured
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by driver function 1.
* The videomode number and frequency must be in the table
returned by driver function 1.
======================================================================
============ Function 21, subfunction 13, subsubfunction 4 ===========
================== Return to the initial videomode. ==================
======================================================================
Returns the screen to the videomode set at system boot.
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 4 - number of the driver function
Returned value:
* eax = -1 - driver is not loaded or not initialized
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by call to driver function 1.
======================================================================
============ Function 21, subfunction 13, subsubfunction 5 ===========
===== Increase/decrease the size of the visible area of monitor. =====
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 5 - number of the driver function
* edx = 0/1 - decrease/increase horizontal size on 1 position
* edx = 2/3 - is not supported in the current implementation;
is planned as decrease/increase vertical size on 1 position
Returned value:
* eax = -1 - driver is not loaded or not initialized
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by call to driver function 1.
* Function influences only the physical size of the screen image;
the logical size (number of pixels) does not change.
======================================================================
================= Function 22 - set system date/time. ================
======================================================================
@ -1484,58 +1323,6 @@ Remarks:
if the addition of ebx with the current value of time counter
makes 32-bit overflow.
======================================================================
======== Function 24, subfunction 1 - begin to play CD-audio. ========
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 1 - subfunction number
* ecx = 0x00FRSSMM, where
* MM = starting minute
* SS = starting second
* FR = starting frame
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* Previously CD base must be defined by the call to
subfunction 3 of function 21.
* One second includes 75 frames, one minute includes 60 seconds.
* The function is asynchronous (returns control, when play begins).
======================================================================
======= Function 24, subfunction 2 - get information on tracks. ======
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 2 - subfunction number
* ecx = pointer to the buffer for the table
(maximum 8*64h+4 bytes=100 tracks)
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* The format of the table with tracks information is the same as
for ATAPI-CD command 43h (READ TOC), usual table (subcommand 00h).
Function returns addresses in MSF.
* Previously CD base port must be set by call to
subfunction 3 of function 21.
* Function returns information only about no more than 100
first tracks. In most cases it is enough.
======================================================================
========== Function 24, subfunction 3 - stop play CD-audio. ==========
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 1 - subfunction number
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* Previously CD base port must be defined by call to
subfunction 3 of function 21.
======================================================================
======= Function 24, subfunction 4 - eject tray of disk drive. =======
======================================================================
@ -1543,7 +1330,9 @@ Parameters:
* eax = 24 - function number
* ebx = 4 - subfunction number
* ecx = position of CD/DVD-drive
(from 0=Primary Master to 3=Secondary Slave)
from 0=Primary Master to 3=Secondary Slave for first IDE contr.
from 4=Primary Master to 7=Secondary Slave for second IDE contr.
from 8=Primary Master to 11=Secondary Slave for third IDE contr.
Returned value:
* function does not return value
Remarks:
@ -1561,7 +1350,9 @@ Parameters:
* eax = 24 - function number
* ebx = 5 - subfunction number
* ecx = position of CD/DVD-drive
(from 0=Primary Master to 3=Secondary Slave)
from 0=Primary Master to 3=Secondary Slave for first IDE contr.
from 4=Primary Master to 7=Secondary Slave for second IDE contr.
from 8=Primary Master to 11=Secondary Slave for third IDE contr.
Returned value:
* function does not return value
Remarks:
@ -1635,18 +1426,6 @@ Remarks:
the corresponding icon (using this function).
* The application @panel switches layouts on user request.
======================================================================
============== Function 26, subfunction 3 - get CD base. =============
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 3 - subfunction number
Returned value:
* eax = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Remarks:
* CD base is used by function 24.
* To set CD base use subfunction 3 of function 21.
======================================================================
========== Function 26, subfunction 5 - get system language. =========
======================================================================
@ -1661,41 +1440,6 @@ Remarks:
appropriate icon (using this function).
* To set system language use subfunction 5 of function 21.
======================================================================
============== Function 26, subfunction 7 - get HD base. =============
======================================================================
The HD base defines hard disk to write with usage of obsolete
syntax /HD in obsolete function 58; at usage of modern syntax
/HD0,/HD1,/HD2,/HD3 base is set automatically.
Parameters:
* eax = 26 - function number
* ebx = 7 - subfunction number
Returned value:
* eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Remarks:
* Any application in any time can change HD base.
* To set base use subfunction 7 of function 21.
* To get used partition of hard disk use subfunction 8.
======================================================================
========= Function 26, subfunction 8 - get used HD partition. ========
======================================================================
The HD partition defines partition of the hard disk to write with
usage of obsolete syntax /HD in obsolete function 58;
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
base and partition are set automatically.
Parameters:
* eax = 26 - function number
* ebx = 8 - subfunction number
Returned value:
* eax = HD partition (beginning from 1)
Remarks:
* Any application in any time can change partition.
* To set partition use subfunction 8 of function 21.
* To get number of partitions on a hard disk use
subfunction 11 of function 18.
* To get base of used hard disk, use subfunction 7.
======================================================================
=== Function 26, subfunction 9 - get the value of the time counter. ==
======================================================================
@ -2315,8 +2059,7 @@ Remarks:
Parameters:
* eax = 48 - function number
* ebx = 8 - subfunction number
* ecx = pointer to a block for function 58, in
which the fields of intermediate buffer and file name are filled
* ecx = pointer to filename of the skin
Returned value:
* eax = 0 - success
* otherwise eax = file system error code; if file does not
@ -2526,219 +2269,6 @@ Remarks:
* If BIOS does not support this extension, its behavior is emulated
(through kernel-mode analogues of subfunctions of function 62).
======================================================================
================ Function 58 - work with file system. ================
======================================================================
Parameters:
* eax = 58
* ebx = pointer to the information structure
Returned value:
* eax = 0 - success; otherwise file system error code
* some subfunctions return value in other registers too
General format of the information structure:
* +0: dword: subfunction number
* +4: dword: number of block
* +8: dword: size
* +12 = +0xC: dword: pointer to data
* +16 = +0x10: dword: pointer to a memory for system operations
(4096 bytes)
* +20 = +0x14: n db: ASCIIZ-string with the file name
Specifications - in documentation on the appropriate subfunction.
Filename is case-insensitive for latin letters, russian letters
must be capital.
Format of filename:
/base/number/dir1/dir2/.../dirn/file,
where /base/number identifies device, on which file is located:
one of
* /RD/1 = /RAMDISK/1 to access ramdisk
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive,
/FD/2 = /FLOPPYDISK/2 to access second one
* /HD/x = /HARDDISK/x - obsolete variant of access to hard disk
(in this case base is defined by subfunction 7 of function 21),
x - partition number (beginning from 1)
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices
IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave);
x - partition number on the selected hard drive, varies from 1
to 255 (on each hard drive the indexing starts from 1)
Remarks:
* In the first two cases it is also possible to use FIRST
instead of 1, SECOND instead of 2, but it is not recommended
for convenience of transition to the future extensions.
* Limitation n<=39 is imposed.
* Names of folders and file dir1,...,dirn,file must have the
format 8.3: name no more than 8 characters, dot, extension no
more than 3 characters. Trailing spaces are ignored, no other
spaces is allowed. If name occupies equally 8 characters,
dot may be omitted (though it is not recommended to use this
feature for convenience of transition to the future extensions).
* This function does not support folders on ramdisk.
Examples:
* '/RAMDISK/FIRST/KERNEL.ASM',0
'/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0
* '/hd0/1/menuet/pics/tanzania.bmp',0
Existing subfunctions:
* subfunction 0 - read file/folder
* subfunction 8 - LBA-read from device
* subfunction 15 - get file system information
======================================================================
=========== Function 58, subfunction 0 - read file/folder. ===========
======================================================================
Parameters:
* eax = 58
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 0 = subfunction number
* +4: dword: first block to read (beginning from 0)
* +8: dword: amount of blocks to read
* +12 = +0xC: dword: pointer to buffer for data
* +16 = +0x10: dword: pointer to buffer for system operations
(4096 bytes)
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx = file size (in bytes) or -1=0xffffffff, if file was not found
Remarks:
* Block size is 512 bytes.
* This function is obsolete, for reading files use subfunction 0
of function 70, for reading folders - subfunction 1 of
function 70.
* Function can read contents of a folder. Only FAT file system is
supported. The format of FAT-folder is described
in any FAT documentation.
* Size of a folder is determined by size of FAT clusters chain.
* If file was ended before last requested block was read,
the function will read as many as it can, and after that return
eax=6 (EOF).
* Function can read root folders /rd/1,/fd/x,/hd[n]/x, but
in the first two cases the current implementation does not follow
to the declared rules:
for /rd/1:
* if one want to read 0 blocks, function considers,
that he requested 1;
* if one requests more than 14 blocks or starting block is
not less than 14, function returns eax=5 (not found) and ebx=-1;
* size of ramdisk root folder is 14 blocks,
0x1C00=7168 bytes; but function returns ebx=0
(except of the case of previous item);
* strangely enough, it is possible to read 14th block (which
generally contains a garbage - I remind, the indexing begins
from 0);
* if some block with the number not less than 14 was requested,
function returns eax=6(EOF); otherwise eax=0.
For /fd/x:
* if the start block is not less than 14, function returns
eax=5 (not found) and ebx=0;
* note that format of FAT12 allows floppies with the root size
more or less than 14 blocks;
* check for length is not performed;
* if data was successful read, function returns
eax=0,ebx=0; otherwise eax=10 (access denied), ebx=-1.
* The function handles reading of special folders /,/rd,/fd,/hd[n];
but the result does not correspond to expected (on operations with
normal files/folders), does not follow the declared rules,
may be changed in future versions of the kernel and consequently
is not described. To obtain the information about the equipment
use subfunction 11 of function 18 or
read corresponding folder with subfunction 1 of function 70.
======================================================================
========= Function 58, subfunction 8 - LBA-read from device. =========
======================================================================
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 8 = subfunction number
* +4: dword: number of block to read (beginning from 0)
* +8: dword: ignored (set to 1)
* +12 = +0xC: dword: pointer to buffer for data (512 bytes)
* +16 = +0x10: dword: pointer to buffer for system operations
(4096 bytes)
* +20 = +0x14: ASCIIZ-name of device: case-insensitive, one of
/rd/1 = /RamDisk/1, /hd/n = /HardDisk/n,
1<=n<=4 - number of device: 1=IDE0, ..., 4=IDE3.
Instead of digits it is allowed, though not recommended for
convenience of transition to future extensions, to use
'first','second','third','fourth'.
Returned value:
* for device name /hd/xxx, where xxx is not in the list above:
* eax = ebx = 1
* for invalid device name (except for the previous case):
* eax = 5
* ebx does not change
* if LBA-access is disabled by subfunction 11 of function 21:
* eax = 2
* ebx destroyed
* for ramdisk: attempt to read block outside ramdisk
(18*2*80 blocks) results in
* eax = 3
* ebx = 0
* for successful read:
* eax = ebx = 0
Remarks:
* Block size is 512 bytes; function reads one block.
* Do not depend on returned value, it can be changed
in future versions.
* Function requires that LBA-access to devices is enabled by
subfunction 11 of function 21. To check this one can use
subfunction 11 of function 26.
* LBA-read of floppy is not supported.
* Function reads data on physical hard drive; if for any reason
data of the concrete partition are required, application must
define starting sector of this partition (either directly
through MBR, or from the full structure returned by
subfunction 11 of function 18).
* Function does not check error code of hard disk, so request of
nonexisting sector reads something (most probably it will be
zeroes, but this is defined by device) and this is considered
as success (eax=0).
======================================================================
==== Function 58, subfunction 15 - get information on file system. ===
======================================================================
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 15 = subfunction number
* +4: dword: ignored
* +8: dword: ignored
* +12 = +0xC: dword: ignored
* +16 = +0x10: dword: ignored
* +20 = +0x14: (only second character is checked)
/rd=/RAMDISK or /hd=/HARDDISK
Returned value:
* if the second character does not belong to set {'r','R','h','H'}:
* eax = 3
* ebx = ecx = dword [fileinfo] = 0
* for ramdisk:
* eax = 0 (success)
* ebx = total number of clusters = 2847
* ecx = number of free clusters
* dword [fileinfo] = cluster size = 512
* for hard disk: base and partition are defined by subfunctions
7 and 8 of function 21:
* eax = 0 (success)
* ebx = total number of clusters
* ecx = number of free clusters
* dword [fileinfo] = cluster size (in bytes)
Remarks:
* Be not surprised to strange layout of 4th returned parameter
- when this code was writing, at system calls application got
only registers eax,ebx,ecx (from pushad-structure transmitted
as argument to the system function). Now it is corrected, so,
probably, it is meaningful to return cluster size in edx, while
this function is not used yet.
* There exists also subfunction 11 of function 18,
which returns information on file system. From the full table
of disk subsystem it is possible to deduce cluster size (there
it is stored in sectors) and total number of clusters
for hard disks.
======================================================================
========== Function 60 - Inter Process Communication (IPC). ==========
======================================================================
@ -4502,12 +4032,6 @@ Parameters:
Returned value:
* eax = socketnum1, -1 on error
* ebx = socketnum2, errorcode on error
Remarks:
Optstruct: dd level
dd optionname
dd optlength
db options...
======================================================================
=============== Function -1 - terminate thread/process ===============

View File

@ -186,6 +186,7 @@ USB_STATUS_BUFOVERRUN = 12 ; overflow of internal controller buffer
USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer
USB_STATUS_CLOSED = 16 ; pipe closed, either explicitly with USBClosePipe
; or due to device disconnect
USB_STATUS_CANCELLED = 17 ; transfer cancelled with USBAbortPipe
If several transfers are queued for the same pipe, their callback functions
are called in the same order as they were queued.
@ -194,6 +195,11 @@ implicitly due to device disconnect, all callback functions are called
with USB_STATUS_CLOSED. The call to DeviceDisconnected() occurs after
all callbacks.
void __stdcall USBAbortPipe(void* pipe);
Initiates cancellation of all active transfers for the given pipe. Asynchronous.
When a transfer will be cancelled, the associated callback function
will be called with USB_STATUS_CANCELLED.
void* __stdcall USBGetParam(void* pipe0, int param);
Returns miscellaneous parameters of the device.
pipe0 is the pointer to the config pipe.

View File

@ -1,148 +1,133 @@
; fetch the UTF-8 character in string+offs to char
; common part for all encodings: translate pseudographics
; Pseudographics for the boot screen:
; 0x2500 -> 0xC4, 0x2502 -> 0xB3, 0x250C -> 0xDA, 0x2510 -> 0xBF,
; 0x2514 -> 0xC0, 0x2518 -> 0xD9, 0x252C -> 0xC2, 0x2534 -> 0xC1, 0x2551 -> 0xBA
macro fetch_utf8_char string, offs, char, graph
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5082 $
; fetch the UTF-8 character in addrspace:offs to char
macro fetch_utf8_char addrspace, offs, char
{ local first_byte, b
virtual at 0
db string
if offs >= $
char = -1
else
; fetch first byte
load first_byte byte from offs
load first_byte byte from addrspace:offs
if first_byte < 0x80
char = first_byte
offs = offs + 1
else if first_byte < 0xC0
.err Invalid UTF-8 string
err Invalid UTF-8 string
else if first_byte < 0xE0
char = first_byte and 0x1F
load b byte from offs + 1
load b byte from addrspace:offs + 1
char = (char shl 6) + (b and 0x3F)
offs = offs + 2
else if first_byte < 0xF0
char = first_byte and 0xF
load b byte from offs + 1
load b byte from addrspace:offs + 1
char = (char shl 6) + (b and 0x3F)
load b byte from offs + 2
load b byte from addrspace:offs + 2
char = (char shl 6) + (b and 0x3F)
offs = offs + 3
else if first_byte < 0xF8
char = first_byte and 0x7
load b byte from offs + 1
load b byte from addrspace:offs + 1
char = (char shl 6) + (b and 0x3F)
load b byte from offs + 2
load b byte from addrspace:offs + 2
char = (char shl 6) + (b and 0x3F)
load b byte from offs + 3
load b byte from addrspace:offs + 3
char = (char shl 6) + (b and 0x3F)
offs = offs + 4
else
.err Invalid UTF-8 string
end if
err Invalid UTF-8 string
end if
}
; Worker macro for all encodings.
; Common part for all encodings: map characters 0-0x7F trivially,
; translate pseudographics.
; Pseudographics for the boot screen:
; 0x2500 -> 0xC4, 0x2502 -> 0xB3, 0x250C -> 0xDA, 0x2510 -> 0xBF,
; 0x2514 -> 0xC0, 0x2518 -> 0xD9, 0x252C -> 0xC2, 0x2534 -> 0xC1, 0x2551 -> 0xBA
macro convert_utf8 encoding, [arg]
{ common
local ..addrspace, offs, char
offs = 0
virtual at 0
..addrspace:: db arg
..addrspace#.size = $
end virtual
while offs < ..addrspace#.size
fetch_utf8_char ..addrspace, offs, char
if char = 0x2500
graph = 0xC4
db 0xC4
else if char = 0x2502
graph = 0xB3
db 0xB3
else if char = 0x250C
graph = 0xDA
db 0xDA
else if char = 0x2510
graph = 0xBF
db 0xBF
else if char = 0x2514
graph = 0xC0
db 0xC0
else if char = 0x2518
graph = 0xD9
db 0xD9
else if char = 0x252C
graph = 0xC2
db 0xC2
else if char = 0x2534
graph = 0xC1
db 0xC1
else if char = 0x2551
graph = 0xBA
db 0xBA
else if char < 0x80
db char
else
graph = 0
encoding char
end if
end while
}
macro declare_encoding encoding
{
macro encoding [arg]
\{ common convert_utf8 encoding#char, arg \}
struc encoding [arg]
\{ common convert_utf8 encoding#char, arg \}
macro encoding#char char
}
; Russian: use CP866.
; 0x00-0x7F - trivial map
; 0x410-0x43F -> 0x80-0xAF
; 0x440-0x44F -> 0xE0-0xEF
; 0x401 -> 0xF0, 0x451 -> 0xF1
macro cp866 [arg]
{ local offs, char, graph
offs = 0
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x80
db char
else if char = 0x401
declare_encoding cp866
{
if char = 0x401
db 0xF0
else if char = 0x451
db 0xF1
else if (char < 0x410) | (char > 0x44F)
.err Failed to convert to CP866
err Failed to convert to CP866
else if char < 0x440
db char - 0x410 + 0x80
else
db char - 0x440 + 0xE0
end if
end while
}
struc cp866 [arg]
{
common
cp866 arg
}
; Latin-1 encoding
; 0x00-0xFF - trivial map
macro latin1 [arg]
{ local offs, char, graph
offs = 0
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x100
declare_encoding latin1
{
if char < 0x100
db char
else
.err Failed to convert to Latin-1
err Failed to convert to Latin-1
end if
end while
}
struc latin1 [arg]
{
common
latin1 arg
}
; CP850 encoding
macro cp850 [arg]
{ local offs, char, graph
offs = 0
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x80
db char
else if char = 0xBF
declare_encoding cp850
{
if char = 0xBF
db 0xA8
else if char = 0xE1
db 0xA0
@ -157,11 +142,4 @@ macro cp850 [arg]
else
err Failed to convert to CP850
end if
end while
}
struc cp850 [arg]
{
common
cp850 arg
}

View File

@ -2,11 +2,14 @@
;; ;;
;; Contains ext2 block handling code. ;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4891 $
;---------------------------------------------------------------------
; Write ext2 block from memory to disk.
; Input: eax = i_block (block number in ext2 terms);

View File

@ -2,11 +2,14 @@
;; ;;
;; Contains ext2 initialization, plus syscall handling code. ;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5089 $
include 'ext2.inc'
include 'blocks.inc'
include 'inode.inc'
@ -56,6 +59,8 @@ endp
;---------------------------------------------------------------------
proc ext2_create_partition
push ebx
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .fail
mov eax, 2 ; Superblock starts at 1024-bytes.
add ebx, 512 ; Get pointer to fs-specific buffer.

View File

@ -2,11 +2,14 @@
;; ;;
;; Contains ext2 structures, and macros. ;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4891 $
; Future jobs for driver, in order of preference:
; * clean up existing extents support.
; * add b-tree directories support.

View File

@ -2,11 +2,14 @@
;; ;;
;; Contains ext2 inode handling code. ;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4891 $
;---------------------------------------------------------------------
; Receives block number from extent-based inode.
; Input: ecx = number of block in inode

View File

@ -2,11 +2,14 @@
;; ;;
;; Contains common resource allocation + freeing code. ;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4891 $
;---------------------------------------------------------------------
; Frees a resource (block/inode).
; Input: eax = resource ID.

View File

@ -154,6 +154,9 @@ fat_create_partition.return0:
xor eax, eax
ret
fat_create_partition:
; sector size must be 512
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .return0
; bootsector must have been successfully read
cmp dword [esp+4], 0
jnz .return0

View File

@ -43,6 +43,30 @@ rootdirs:
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
db 3,'cd4'
dd fs_OnCd4
dd fs_NextCd
db 3,'cd5'
dd fs_OnCd5
dd fs_NextCd
db 3,'cd6'
dd fs_OnCd6
dd fs_NextCd
db 3,'cd7'
dd fs_OnCd7
dd fs_NextCd
db 3,'cd8'
dd fs_OnCd8
dd fs_NextCd
db 3,'cd9'
dd fs_OnCd9
dd fs_NextCd
db 4,'cd10'
dd fs_OnCd10
dd fs_NextCd
db 4,'cd11'
dd fs_OnCd11
dd fs_NextCd
;***********************************************
db 0
@ -57,6 +81,22 @@ virtual_root_query:
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
dd fs_HasCd4
db 'cd4',0
dd fs_HasCd5
db 'cd5',0
dd fs_HasCd6
db 'cd6',0
dd fs_HasCd7
db 'cd7',0
dd fs_HasCd8
db 'cd8',0
dd fs_HasCd9
db 'cd9',0
dd fs_HasCd10
db 'cd10',0
dd fs_HasCd11
db 'cd11',0
;**********************************************
dd 0
endg
@ -149,8 +189,8 @@ file_system_lfn:
cmp dword [ebx], 1
jnz .access_denied
xor eax, eax
mov ebp, [ebx+12] ;количество блоков для считывания
mov edx, [ebx+16] ;куда записывать рузельтат
mov ebp, [ebx+12] ;the number of blocks to read
mov edx, [ebx+16] ;where to write the result
; add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
@ -404,8 +444,7 @@ file_system_lfn:
fs_NotImplemented:
mov eax, 2
ret
;*******************************************************
;-----------------------------------------------------------------------------
fs_OnCd0:
call reserve_cd
mov [ChannelNumber], 1
@ -413,6 +452,7 @@ fs_OnCd0:
push 6
push 1
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd1:
call reserve_cd
mov [ChannelNumber], 1
@ -420,6 +460,7 @@ fs_OnCd1:
push 4
push 2
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd2:
call reserve_cd
mov [ChannelNumber], 2
@ -427,22 +468,96 @@ fs_OnCd2:
push 2
push 3
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd3:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 1
push 0
push 4
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd4:
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 0
push 6
push 5
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd5:
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 1
push 4
push 6
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd6:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 0
push 2
push 7
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd7:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 1
push 0
push 8
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd8:
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 0
push 6
push 9
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd9:
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 1
push 4
push 10
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd10:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 0
push 2
push 11
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd11:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 1
push 0
push 12
;-----------------------------------------------------------------------------
fs_OnCd:
call reserve_cd_channel
pop eax
mov [cdpos], eax
call reserve_cd_channel
pop eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl, al
mov bl, [DRIVE_DATA+1]
push eax
mov eax, [cdpos]
dec eax
shr eax, 2
lea eax, [eax*5]
mov bl, [eax+DRIVE_DATA+1]
pop eax
shr bl, cl
test bl, 2
pop ebx ecx
@ -472,7 +587,7 @@ fs_OnCd:
and [cd_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
;-----------------------------------------------------------------------------
fs_CdServices:
dd fs_CdRead
dd fs_CdReadFolder
@ -485,32 +600,74 @@ fs_CdServices:
dd fs_NotImplemented
dd fs_NotImplemented
fs_NumCdServices = ($ - fs_CdServices)/4
;*******************************************************
;-----------------------------------------------------------------------------
fs_HasCd0:
test byte [DRIVE_DATA+1], 10000000b
setnz al
ret
;--------------------------------------
fs_HasCd1:
test byte [DRIVE_DATA+1], 00100000b
setnz al
ret
;--------------------------------------
fs_HasCd2:
test byte [DRIVE_DATA+1], 00001000b
setnz al
ret
;--------------------------------------
fs_HasCd3:
test byte [DRIVE_DATA+1], 00000010b
setnz al
ret
;*******************************************************
;--------------------------------------
fs_HasCd4:
test byte [DRIVE_DATA+6], 10000000b
setnz al
ret
;--------------------------------------
fs_HasCd5:
test byte [DRIVE_DATA+6], 00100000b
setnz al
ret
;--------------------------------------
fs_HasCd6:
test byte [DRIVE_DATA+6], 00001000b
setnz al
ret
;--------------------------------------
fs_HasCd7:
test byte [DRIVE_DATA+6], 00000010b
setnz al
ret
;--------------------------------------
fs_HasCd8:
test byte [DRIVE_DATA+11], 10000000b
setnz al
ret
;--------------------------------------
fs_HasCd9:
test byte [DRIVE_DATA+11], 00100000b
setnz al
ret
;--------------------------------------
fs_HasCd10:
test byte [DRIVE_DATA+11], 00001000b
setnz al
ret
;--------------------------------------
fs_HasCd11:
test byte [DRIVE_DATA+11], 00000010b
setnz al
ret
;-----------------------------------------------------------------------------
;
; fs_NextXXX functions:
; in: eax = partition number, from which start to scan
; out: CF=1 => no more partitions
; CF=0 => eax=next partition number
;*******************************************************
;
;-----------------------------------------------------------------------------
fs_NextCd:
; we always have /cdX/1
test eax, eax
@ -520,8 +677,6 @@ fs_NextCd:
clc
@@:
ret
;*******************************************************
;-----------------------------------------------------------------------------
process_replace_file_name:
; in

View File

@ -7,18 +7,15 @@
$Revision$
;-----------------------------------------------------------------------------
uglobal
cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
endg
;-----------------------------------------------------------------------------
reserve_cd:
cli
cmp [cd_status], 0
je reserve_ok2
@ -26,9 +23,8 @@ reserve_cd:
sti
call change_task
jmp reserve_cd
reserve_ok2:
;-----------------------------------------------------------------------------
reserve_ok2:
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
@ -37,48 +33,105 @@ reserve_cd:
pop eax
sti
ret
;-----------------------------------------------------------------------------
reserve_cd_channel:
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
pushad
mov ecx, ide_channel1_mutex
call mutex_lock
mov [IDE_Channel_1], 1
popad
ret
.IDE_Channel_2:
pushad
mov ecx, ide_channel2_mutex
call mutex_lock
mov [IDE_Channel_2], 1
popad
ret
mov eax, [cdpos]
dec eax
shr eax, 2
test eax, eax
jnz .1
cmp [ChannelNumber], 1
jne @f
mov ecx, ide_channel1_mutex
jmp .mutex_lock
;--------------------------------------
@@:
mov ecx, ide_channel2_mutex
jmp .mutex_lock
;--------------------------------------
.1:
dec eax
jnz .2
cmp [ChannelNumber], 1
jne @f
mov ecx, ide_channel3_mutex
jmp .mutex_lock
;--------------------------------------
@@:
mov ecx, ide_channel4_mutex
jmp .mutex_lock
;--------------------------------------
.2:
cmp [ChannelNumber], 1
jne @f
mov ecx, ide_channel5_mutex
jmp .mutex_lock
;--------------------------------------
@@:
mov ecx, ide_channel6_mutex
.mutex_lock:
call mutex_lock
popad
ret
;-----------------------------------------------------------------------------
free_cd_channel:
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
pushad
mov ecx, ide_channel1_mutex
call mutex_unlock
popad
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
pushad
mov ecx, ide_channel2_mutex
call mutex_unlock
popad
ret
mov eax, [cdpos]
dec eax
shr eax, 2
test eax, eax
jnz .1
cmp [ChannelNumber], 1
jne @f
mov ecx, ide_channel1_mutex
jmp .mutex_unlock
;--------------------------------------
@@:
mov ecx, ide_channel2_mutex
jmp .mutex_unlock
;--------------------------------------
.1:
dec eax
jnz .2
cmp [ChannelNumber], 1
jne @f
mov ecx, ide_channel3_mutex
jmp .mutex_unlock
;--------------------------------------
@@:
mov ecx, ide_channel4_mutex
jmp .mutex_unlock
;--------------------------------------
.2:
cmp [ChannelNumber], 1
jne @f
mov ecx, ide_channel5_mutex
jmp .mutex_unlock
;--------------------------------------
@@:
mov ecx, ide_channel6_mutex
.mutex_unlock:
call mutex_unlock
popad
ret
;-----------------------------------------------------------------------------
uglobal
cd_status dd 0
endg
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
;
; fs_CdRead - LFN variant for reading CD disk
;
@ -91,91 +144,114 @@ endg
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
;-----------------------------------------------------------------------------
fs_CdRead:
push edi
cmp byte [esi], 0
jnz @f
;--------------------------------------
.noaccess:
pop edi
;--------------------------------------
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
;--------------------------------------
.noaccess_3:
pop eax edx ecx edi
jmp .noaccess_2
;--------------------------------------
@@:
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
;--------------------------------------
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
;--------------------------------------
.reteof:
mov eax, 6; end of file
pop edi
ret
;--------------------------------------
@@:
mov ebx, [ebx]
;--------------------------------------
.l1:
push ecx edx
push 0
mov eax, [edi+10] ; реальный размер файловой секции
mov eax, [edi+10] ; real size of the file section
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
;--------------------------------------
@@:
mov eax, [edi+2]
mov [CDSectorAddress], eax
;--------------------------------------
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector:
test ecx, ecx
jz .done
sub ebx, 2048
jae .next
add ebx, 2048
jnz .incomplete_sector
cmp ecx, 2048
jb .incomplete_sector
; we may read and memmove complete sector
mov [CDDataBuf_pointer], edx
call ReadCDWRetr; читаем сектор файла
call ReadCDWRetr ; read sector of file
cmp [DevErrorCode], 0
jne .noaccess_3
add edx, 2048
sub ecx, 2048
;--------------------------------------
.next:
inc dword [CDSectorAddress]
jmp .new_sector
;--------------------------------------
.incomplete_sector:
; we must read and memmove incomplete sector
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr; читаем сектор файла
call ReadCDWRetr ; read sector of file
cmp [DevErrorCode], 0
jne .noaccess_3
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
mov ecx, 2048
;--------------------------------------
@@:
sub ecx, ebx
push edi esi ecx
@ -189,19 +265,19 @@ fs_CdRead:
pop ecx
xor ebx, ebx
jmp .next
;--------------------------------------
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
;--------------------------------------
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
;
; fs_CdReadFolder - LFN variant for reading CD disk folder
;
@ -215,30 +291,37 @@ fs_CdRead:
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
;-----------------------------------------------------------------------------
fs_CdReadFolder:
push edi
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
;--------------------------------------
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
pop edi
;--------------------------------------
.noaccess_1:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
;--------------------------------------
.found_dir:
mov eax, [edi+2] ; eax=cluster
mov [CDSectorAddress], eax
mov eax, [edi+10] ; размер директрории
mov eax, [edi+10] ; directory size
;--------------------------------------
.doit:
; init header
push eax ecx
@ -250,21 +333,23 @@ fs_CdReadFolder:
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
; начинаем переброску БДВК в УСВК
;.mainloop:
mov [cd_counter_block], dword 0
dec dword [CDSectorAddress]
push ecx
;--------------------------------------
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; читаем сектор директории
call ReadCDWRetr ; read sector of directory
cmp [DevErrorCode], 0
jne .noaccess_1
call .get_names_from_buffer
sub eax, 2048
; директория закончилась?
; directory is over?
ja .read_to_buffer
mov edi, [cd_counter_block]
mov [edx+8], edi
mov edi, [ebx]
@ -272,24 +357,30 @@ fs_CdReadFolder:
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
;--------------------------------------
@@:
pop ecx edi
mov ebx, [edx+4]
ret
;--------------------------------------
.get_names_from_buffer:
mov [cd_current_pointer_of_input_2], CDDataBuf
push eax esi edi edx
;--------------------------------------
.get_names_from_buffer_1:
call cd_get_name
jc .end_buffer
inc dword [cd_counter_block]
mov eax, [cd_counter_block]
cmp [ebx], eax
jae .get_names_from_buffer_1
test ecx, ecx
jz .get_names_from_buffer_1
mov edi, [cd_counter_block]
mov [edx+4], edi
dec ecx
@ -298,189 +389,209 @@ fs_CdReadFolder:
add edi, 40
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode
; jmp .unicode
;--------------------------------------
.ansi:
cmp [cd_counter_block], 2
jbe .ansi_parent_directory
cld
lodsw
xchg ah, al
call uni2ansi_char
cld
stosb
; проверка конца файла
; check end of file
mov ax, [esi]
cmp ax, word 3B00h; сепаратор конца файла ';'
cmp ax, word 3B00h ; separator end of file ';'
je .cd_get_parameters_of_file_1
; проверка для файлов не заканчивающихся сепаратором
; check for files not ending with separator
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_1
; проверка конца папки
; check the end of the directory
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .ansi
;--------------------------------------
.cd_get_parameters_of_file_1:
mov [edi], byte 0
call cd_get_parameters_of_file
add [cd_mem_location], 304
jmp .get_names_from_buffer_1
;--------------------------------------
.ansi_parent_directory:
cmp [cd_counter_block], 2
je @f
mov [edi], byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
;--------------------------------------
@@:
mov [edi], word '..'
add edi, 2
jmp .cd_get_parameters_of_file_1
;--------------------------------------
.unicode:
cmp [cd_counter_block], 2
jbe .unicode_parent_directory
cld
movsw
; проверка конца файла
; check end of file
mov ax, [esi]
cmp ax, word 3B00h; сепаратор конца файла ';'
cmp ax, word 3B00h; separator end of file ';'
je .cd_get_parameters_of_file_2
; проверка для файлов не заканчивающихся сепаратором
; check for files not ending with separator
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_2
; проверка конца папки
; check the end of the directory
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .unicode
;--------------------------------------
.cd_get_parameters_of_file_2:
mov [edi], word 0
call cd_get_parameters_of_file
add [cd_mem_location], 560
jmp .get_names_from_buffer_1
;--------------------------------------
.unicode_parent_directory:
cmp [cd_counter_block], 2
je @f
mov [edi], word 2E00h; '.'
add edi, 2
jmp .cd_get_parameters_of_file_2
;--------------------------------------
@@:
mov [edi], dword 2E002E00h; '..'
add edi, 4
jmp .cd_get_parameters_of_file_2
;--------------------------------------
.end_buffer:
pop edx edi esi eax
ret
;-----------------------------------------------------------------------------
cd_get_parameters_of_file:
mov edi, [cd_mem_location]
cd_get_parameters_of_file_1:
; получаем атрибуты файла
; get file attributes
xor eax, eax
; файл не архивировался
; file is not archived
inc eax
shl eax, 1
; это каталог?
; is a directory?
test [ebp-8], byte 2
jz .file
inc eax
;--------------------------------------
.file:
; метка тома не как в FAT, в этом виде отсутсвует
; файл не является системным
; not as a volume label in the FAT, in this form not available
; file is not a system
shl eax, 3
; файл является скрытым? (атрибут существование)
; file is hidden? (attribute of existence)
test [ebp-8], byte 1
jz .hidden
inc eax
;--------------------------------------
.hidden:
shl eax, 1
; файл всегда только для чтения, так как это CD
; file is always read-only, as this CD
inc eax
mov [edi], eax
; получаем время для файла
;час
; get the time to file
; hour
movzx eax, byte [ebp-12]
shl eax, 8
;минута
; minute
mov al, [ebp-11]
shl eax, 8
;секунда
; second
mov al, [ebp-10]
;время создания файла
; file creation time
mov [edi+8], eax
;время последнего доступа
; last access time
mov [edi+16], eax
;время последней записи
; last write time
mov [edi+24], eax
; получаем дату для файла
;год
; get date for file
; year
movzx eax, byte [ebp-15]
add eax, 1900
shl eax, 8
;месяц
; month
mov al, [ebp-14]
shl eax, 8
;день
; day
mov al, [ebp-13]
;дата создания файла
; file creation date
mov [edi+12], eax
;время последнего доступа
; last access date
mov [edi+20], eax
;время последней записи
; last write date
mov [edi+28], eax
; получаем тип данных имени
; get the data type of name
xor eax, eax
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode_1
mov [edi+4], eax
jmp @f
;--------------------------------------
.unicode_1:
inc eax
mov [edi+4], eax
;--------------------------------------
@@:
; получаем размер файла в байтах
; get the file size in bytes
xor eax, eax
mov [edi+32+4], eax
mov eax, [ebp-23]
mov [edi+32], eax
ret
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
;
; fs_CdGetFileInfo - LFN variant for CD
; get file/directory attributes structure
;
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
fs_CdGetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
;--------------------------------------
@@:
push edi
call cd_find_lfn
pushfd
cmp [DevErrorCode], 0
jz @f
popfd
pop edi
mov eax, 11
ret
;--------------------------------------
@@:
popfd
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
;--------------------------------------
@@:
mov edi, edx
@ -493,32 +604,31 @@ fs_CdGetFileInfo:
pop edi
xor eax, eax
ret
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
cd_find_lfn:
mov [cd_appl_data], 0
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
; 16 сектор начало набора дескрипторов томов
; Sector 16 - start set of volume descriptors
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
call prevent_medium_removal
; тестовое чтение
; testing of reading
mov [CDSectorAddress], dword 16
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr;_1
cmp [DevErrorCode], 0
jne .access_denied
; вычисление последней сессии
; calculation of the last session
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
call Read_TOC
mov ah, [CDDataBuf+4+4]
mov al, [CDDataBuf+4+5]
@ -529,7 +639,7 @@ cd_find_lfn:
mov [CDSectorAddress], eax
; mov [CDSectorAddress],dword 15
mov [CDDataBuf_pointer], CDDataBuf
;--------------------------------------
.start:
inc dword [CDSectorAddress]
call ReadCDWRetr;_1
@ -537,111 +647,128 @@ cd_find_lfn:
jne .access_denied
.start_check:
; проверка на вшивость
; checking for "lice"
cmp [CDDataBuf+1], dword 'CD00'
jne .access_denied
cmp [CDDataBuf+5], byte '1'
jne .access_denied
; сектор является терминатором набор дескрипторов томов?
; sector is the terminator of set of descriptors volumes?
cmp [CDDataBuf], byte 0xff
je .access_denied
; сектор является дополнительным и улучшенным дескриптором тома?
; sector is an additional and improved descriptor of volume?
cmp [CDDataBuf], byte 0x2
jne .start
; сектор является дополнительным дескриптором тома?
; sector is an additional descriptor of volume?
cmp [CDDataBuf+6], byte 0x1
jne .start
; параметры root директрории
mov eax, [CDDataBuf+0x9c+2]; начало root директрории
; parameters of root directory
mov eax, [CDDataBuf+0x9c+2]; start of root directory
mov [CDSectorAddress], eax
mov eax, [CDDataBuf+0x9c+10]; размер root директрории
mov eax, [CDDataBuf+0x9c+10]; size of root directory
cmp byte [esi], 0
jnz @f
mov [cd_current_pointer_of_input], CDDataBuf+0x9c
jmp .done
;--------------------------------------
@@:
; начинаем поиск
; start the search
.mainloop:
dec dword [CDSectorAddress]
;--------------------------------------
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; читаем сектор директории
call ReadCDWRetr ; read sector of directory
cmp [DevErrorCode], 0
jne .access_denied
push ebp
call cd_find_name_in_buffer
pop ebp
jnc .found
sub eax, 2048
; директория закончилась?
; directory is over?
cmp eax, 0
ja .read_to_buffer
; нет искомого элемента цепочки
; desired element of chain is not found
.access_denied:
pop esi eax
mov [cd_appl_data], 1
stc
ret
; искомый элемент цепочки найден
.found:
; конец пути файла
;--------------------------------------
; desired element of chain found
.found:
; the end of the file path
cmp byte [esi-1], 0
jz .done
.nested:
mov eax, [cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; начало директории
mov eax, [eax+2+8]; размер директории
pop dword [CDSectorAddress] ; beginning of the directory
mov eax, [eax+2+8] ; size of directory
jmp .mainloop
; указатель файла найден
.done:
;--------------------------------------
; file pointer found
.done:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .nested
;--------------------------------------
@@:
pop esi eax
mov [cd_appl_data], 1
clc
ret
;-----------------------------------------------------------------------------
cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2], CDDataBuf
;--------------------------------------
.start:
call cd_get_name
jc .not_found
call cd_compare_name
jc .start
;--------------------------------------
.found:
clc
ret
;--------------------------------------
.not_found:
stc
ret
;-----------------------------------------------------------------------------
cd_get_name:
push eax
mov ebp, [cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input], ebp
mov eax, [ebp]
test eax, eax ; входы закончились?
test eax, eax ; entry's is over?
jz .next_sector
cmp ebp, CDDataBuf+2048 ; буфер закончился?
cmp ebp, CDDataBuf+2048 ; buffer is over?
jae .next_sector
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2], eax; следующий вход каталога
add ebp, 33; указатель установлен на начало имени
add [cd_current_pointer_of_input_2], eax ; next entry of directory
add ebp, 33; pointer is set to the beginning of the name
pop eax
clc
ret
;--------------------------------------
.next_sector:
pop eax
stc
ret
;-----------------------------------------------------------------------------
cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
; in: esi->name, ebp->name
@ -650,6 +777,7 @@ cd_compare_name:
; destroys eax
push esi eax edi
mov edi, ebp
;--------------------------------------
.loop:
cld
lodsb
@ -666,94 +794,118 @@ cd_compare_name:
sub edi, 2
scasw
jne .name_not_coincide
;--------------------------------------
.coincides:
cmp [esi], byte '/'; разделитель пути, конец имени текущего элемента
cmp [esi], byte '/' ; path separator is end of current element
je .done
cmp [esi], byte 0; разделитель пути, конец имени текущего элемента
cmp [esi], byte 0 ; path separator end of name
je .done
jmp .loop
;--------------------------------------
.name_not_coincide:
pop edi eax esi
stc
ret
;--------------------------------------
.done:
; проверка конца файла
cmp [edi], word 3B00h; сепаратор конца файла ';'
; check end of file
cmp [edi], word 3B00h; separator end of file ';'
je .done_1
; проверка для файлов не заканчивающихся сепаратором
; check for files not ending with separator
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp edi, eax
je .done_1
; проверка конца папки
; check the end of directory
movzx eax, byte [ebp-1]
add eax, ebp
cmp edi, eax
jne .name_not_coincide
;--------------------------------------
.done_1:
pop edi eax
add esp, 4
inc esi
clc
ret
;-----------------------------------------------------------------------------
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, 0x80 ; 'А'
jb .ret
cmp al, 0x90 ; 'Р'
jb .rus1
cmp al, 0x9F ; 'Я'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 0xE0-0x90
;--------------------------------------
.ret:
ret
;--------------------------------------
.rus1:
; 0x80-0x8F -> 0xA0-0xAF
.az:
add al, 0x20
ret
;-----------------------------------------------------------------------------
uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character
; out: al=converted ANSI character
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
;--------------------------------------
.unk:
mov al, '_'
jmp .doit
;--------------------------------------
.yo1:
mov al, 0xF0 ; 'Ё' in cp866
jmp .doit
;--------------------------------------
.yo2:
mov al, 0xF1 ; 'ё' in cp866
jmp .doit
;--------------------------------------
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
;--------------------------------------
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
;--------------------------------------
.ascii:
.doit:
ret
;-----------------------------------------------------------------------------

View File

@ -152,6 +152,8 @@ ntfs_test_bootsec:
ret
proc ntfs_create_partition
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .nope
mov edx, dword [ebp+PARTITION.Length]
cmp dword [esp+4], 0
jz .boot_read_ok

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5089 $
include 'xfs.inc'
;
@ -15,6 +25,8 @@ include 'xfs.inc'
; returns 0 (not XFS or invalid) / pointer to partition structure
xfs_create_partition:
push ebx ecx edx esi edi
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .error
cmp dword[ebx + xfs_sb.sb_magicnum], XFS_SB_MAGIC ; signature
jne .error

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; from stat.h
; distinguish file types
S_IFMT = 0170000o ; These bits determine file type.

View File

@ -454,7 +454,11 @@ align 4
cmp al, 120
jae .result ;overflow
inc byte[KEY_COUNT]
mov [KEY_COUNT+1+eax], dl
mov [KEY_BUFF+eax], dl
; store empty scancode
add eax, 120+2
mov [KEY_BUFF+eax], byte 0
sub eax, 120+2
;--------------------------------------
align 4
.result:

View File

@ -11,7 +11,7 @@ $Revision$
include "skindata.inc"
;skin_data = 0x00778000
;------------------------------------------------------------------------------
;-----------------------------------------------------------------
align 4
read_skin_file:
stdcall load_file, ebx
@ -121,7 +121,7 @@ parse_skin_data:
lea esi, [ebx+SKIN_PARAMS.dtp.data]
mov edi, common_colours
mov ecx, [ebx+SKIN_PARAMS.dtp.size]
and ecx, 127
and ecx, 255
rep movsb
mov eax, dword[ebx+SKIN_PARAMS.margin.right]
mov dword[_skinmargins+0], eax

View File

@ -9,7 +9,7 @@ $Revision$
;
; WINDOW SKIN DATA
; WINDOW SKIN DATA.
;
iglobal

View File

@ -26,7 +26,7 @@ macro FuncTable name, table_name, [label]
}
uglobal
common_colours rd 32
common_colours rd 48
draw_limits RECT
endg
@ -34,7 +34,7 @@ align 4
;------------------------------------------------------------------------------
syscall_draw_window: ;///// system function 0 /////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;? <description>.
;------------------------------------------------------------------------------
mov eax, edx
shr eax, 24
@ -173,7 +173,10 @@ align 4
syscall_display_settings.02:
dec ebx
mov esi, ecx
and edx, 127
cmp edx, 192
jnae @f
mov edx, 192 ; max size
@@:
mov edi, common_colours
mov ecx, edx
rep movsb
@ -183,7 +186,10 @@ syscall_display_settings.02:
align 4
syscall_display_settings.03:
mov edi, ecx
and edx, 127
cmp edx, 192
jnae @f
mov edx, 192 ; max size
@@:
mov esi, common_colours
mov ecx, edx
rep movsb
@ -209,7 +215,7 @@ align 4
syscall_display_settings.06:
xor esi, esi
mov edi, [_display.width]
mov edi, [Screen_Max_X]
mov eax, ecx
movsx ebx, ax
sar eax, 16
@ -233,7 +239,7 @@ align 4
;--------------------------------------
align 4
.check_horizontal:
mov edi, [_display.height]
mov edi, [Screen_Max_Y]
mov eax, edx
movsx ebx, ax
sar eax, 16
@ -294,8 +300,8 @@ align 4
syscall_display_settings._.calculate_whole_screen:
xor eax, eax
xor ebx, ebx
mov ecx, [_display.width]
mov edx, [_display.height]
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
jmp calculatescreen
;------------------------------------------------------------------------------
align 4
@ -303,11 +309,9 @@ syscall_display_settings._.redraw_whole_screen:
xor eax, eax
mov [draw_limits.left], eax
mov [draw_limits.top], eax
mov eax, [_display.width]
dec eax
mov eax, [Screen_Max_X]
mov [draw_limits.right], eax
mov eax, [_display.height]
dec eax
mov eax, [Screen_Max_Y]
mov [draw_limits.bottom], eax
mov eax, window_data
jmp redrawscreen
@ -586,9 +590,9 @@ align 4
mov eax, [edi + WDATA.box.left]
add eax, [edi + WDATA.box.width]
mov ebx, [_display.width]
mov ebx, [Screen_Max_X]
cmp eax, ebx
jl .fix_vertical
jle .fix_vertical
mov eax, [edi + WDATA.box.width]
sub eax, ebx
jle @f
@ -603,9 +607,9 @@ align 4
.fix_vertical:
mov eax, [edi + WDATA.box.top]
add eax, [edi + WDATA.box.height]
mov ebx, [_display.height]
mov ebx, [Screen_Max_Y]
cmp eax, ebx
jl .fix_client_box
jle .fix_client_box
mov eax, [edi + WDATA.box.height]
sub eax, ebx
jle @f
@ -819,12 +823,8 @@ drawwindow_I: ;////////////////////////////////////////////////////////////////
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
@ -1718,9 +1718,9 @@ window._.check_window_position: ;//////////////////////////////////////////////
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
mov esi, [_display.width]
mov esi, [Screen_Max_X]
cmp ecx, esi
jae .fix_width_high
ja .fix_width_high
;--------------------------------------
align 4
.check_left:
@ -1732,9 +1732,9 @@ align 4
;--------------------------------------
align 4
.check_height:
mov esi, [_display.height]
mov esi, [Screen_Max_Y]
cmp edx, esi
jae .fix_height_high
ja .fix_height_high
;--------------------------------------
align 4
.check_top:
@ -1992,7 +1992,7 @@ align 4
sub ebp, [ff_xsz]
add ebp, [ff_x]
add ebp, [_display.width] ; screen.x
add ebp, [Screen_Max_X] ; screen.x
inc ebp
inc ebx
cmp ebx, [ff_ysz]

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -25,8 +25,6 @@ VKEY_CONTROL = 0000000000001100b
VKEY_ALT = 0000000000110000b
uglobal
align 4
kb_state dd 0
ext_code db 0
keyboard_mode db 0
@ -35,7 +33,6 @@ uglobal
altmouseb db 0
ctrl_alt_del db 0
kb_lights db 0
old_kb_lights db 0
align 4
@ -45,6 +42,13 @@ align 4
endg
iglobal
kb_lights db 2
align 4
kb_state dd VKEY_NUMLOCK
endg
iglobal
align 4
hotkey_tests dd hotkey_test0
dd hotkey_test1
dd hotkey_test2
@ -457,19 +461,40 @@ send_scancode:
test bl, bl
jz .exit.irq1
test [kb_state], VKEY_NUMLOCK
jz .dowrite
cmp cl, 0xE0 ; extended keycode
jne @f
cmp ch, 53
jne .dowrite
cmp cl, 0xE0
jz .dowrite
mov bl, '/'
jmp .dowrite
@@:
cmp ch, 55
jnz @f
jne @f
mov bl, 0x2A ;*
mov bl, '*'
jmp .dowrite
;--------------------------------------
@@:
cmp ch, 74
jne @f
mov bl, '-'
jmp .dowrite
@@:
cmp ch, 78
jne @f
mov bl, '+'
jmp .dowrite
@@:
test [kb_state], VKEY_NUMLOCK
jz .dowrite
cmp ch, 71
jb .dowrite
@ -488,7 +513,19 @@ send_scancode:
jae .exit.irq1
inc eax
mov [KEY_COUNT], al
mov [KEY_COUNT+eax], bl
; store ascii or scancode
mov [KEY_COUNT+eax], bl ; actually KEY_BUFF + EAX - 1
; store original scancode
add eax, 120+2
push ecx
cmp [keyboard_mode], 0; return from keymap
je @f
xor ch, ch
@@:
mov [KEY_COUNT+eax], ch ; actually KEY_BUFF + EAX - 1
pop ecx
sub eax, 120+2
.exit.irq1:
ret
;---------------------------------------------------------------------
@ -518,9 +555,9 @@ set_lights:
ps2_set_lights:
stdcall disable_irq, 1
mov al, 0xED
call kb_write
call kb_write_wait_ack
mov al, [esp+8]
call kb_write
call kb_write_wait_ack
stdcall enable_irq, 1
ret 8

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -24,16 +24,12 @@ $Revision$
uglobal
;--------------------------------------
align 4
mousecount dd 0x0
mousedata dd 0x0
Y_UNDER_sub_CUR_hot_y_add_curh:
dw 0
Y_UNDER_subtraction_CUR_hot_y:
dw 0
X_UNDER_sub_CUR_hot_x_add_curh:
dw 0
X_UNDER_subtraction_CUR_hot_x:
dw 0
mousecount dd ?
mousedata dd ?
Y_UNDER_sub_CUR_hot_y_add_curh dw ?
Y_UNDER_subtraction_CUR_hot_y dw ?
X_UNDER_sub_CUR_hot_x_add_curh dw ?
X_UNDER_subtraction_CUR_hot_x dw ?
endg
iglobal
@ -44,9 +40,12 @@ mouse_speed_factor:
dd 3
mouse_timer_ticks dd 0
endg
;-----------------------------------------------------------------------------
align 4
draw_mouse_under:
; return old picture
cmp [_display.restore_cursor], 0
je @F
@ -57,15 +56,13 @@ draw_mouse_under:
stdcall [_display.restore_cursor], eax, ebx
popad
ret
;--------------------------------------
align 4
@@:
@@:
pushad
xor ecx, ecx
xor edx, edx
;--------------------------------------
align 4
mres:
mres:
movzx eax, word [X_UNDER]
movzx ebx, word [Y_UNDER]
add eax, ecx
@ -97,7 +94,9 @@ mres:
jnz mres
popad
ret
;-----------------------------------------------------------------------------
align 4
save_draw_mouse:
cmp [_display.move_cursor], 0
@ -111,6 +110,9 @@ save_draw_mouse:
push eax
push ebx
; mov ecx, [Screen_Max_X]
; inc ecx
; mul ecx
mov eax, [d_width_calc_area + eax*4]
add eax, [_WinMapAddress]
@ -170,11 +172,13 @@ drm:
push edx
; helloworld
push ecx
add eax, ecx; save picture under mouse
add eax, ecx ; save picture under mouse
add ebx, edx
push ecx
or ecx, 0x04000000 ; don't load to mouseunder area
call getpixel
push eax ebx edx edi
call [GETPIXEL]
pop edi edx ebx eax
mov [COLOR_TEMP], ecx
pop ecx
mov eax, edx
@ -226,7 +230,9 @@ drm:
add esp, 8
popad
ret
;-----------------------------------------------------------------------------
align 4
combine_colors:
; in
@ -241,7 +247,7 @@ combine_colors:
push edx
push ecx
xor ecx, ecx
; byte 2
; byte 0
mov eax, 0xff
sub al, [esi+0]
mov ebx, [esp]
@ -295,7 +301,9 @@ combine_colors:
pop ebx
pop eax
ret
;-----------------------------------------------------------------------------
align 4
check_mouse_area_for_getpixel:
; in:
@ -314,18 +322,18 @@ check_mouse_area_for_getpixel:
cmp ebx, ecx
ja .no_mouse_area
; offset Y
sub bx, [Y_UNDER] ;[MOUSE_Y]
sub bx, [Y_UNDER] ; [MOUSE_Y]
;--------------------------------------
; check for X
xor ecx, ecx
mov cx, [X_UNDER] ;[MOUSE_X]
mov cx, [X_UNDER] ; [MOUSE_X]
cmp eax, ecx
jb .no_mouse_area
add ecx, 15 ; mouse cursor X size
cmp eax, ecx
ja .no_mouse_area
; offset X
sub ax, [X_UNDER] ;[MOUSE_X]
sub ax, [X_UNDER] ; [MOUSE_X]
;--------------------------------------
; eax = offset x
; ebx = offset y
@ -338,13 +346,14 @@ check_mouse_area_for_getpixel:
or ecx, 0xff000000
pop ebx eax
ret
;--------------------------------------
align 4
.no_mouse_area:
.no_mouse_area:
xor ecx, ecx
pop ebx eax
ret
;-----------------------------------------------------------------------------
align 4
check_mouse_area_for_putpixel:
; in:
@ -361,12 +370,12 @@ check_mouse_area_for_putpixel:
cmp cx, ax
ja .no_mouse_area
; offset Y
sub cx, [Y_UNDER] ;[MOUSE_Y]
sub cx, [Y_UNDER] ; [MOUSE_Y]
mov ax, cx
shl eax, 16
;--------------------------------------
; check for X
mov ax, [X_UNDER] ;[MOUSE_X]
mov ax, [X_UNDER] ; [MOUSE_X]
shr ecx, 16
cmp cx, ax
jb .no_mouse_area
@ -374,9 +383,9 @@ check_mouse_area_for_putpixel:
cmp cx, ax
ja .no_mouse_area
; offset X
sub cx, [X_UNDER] ;[MOUSE_X]
sub cx, [X_UNDER] ; [MOUSE_X]
mov ax, cx
;--------------------------------------
; eax = (offset y) shl 16 + (offset x)
pop ecx
@ -384,8 +393,8 @@ check_mouse_area_for_putpixel:
push eax ebx
mov ebx, eax
shr ebx, 16 ;y
and eax, 0xffff ;x
shr ebx, 16 ; y
and eax, 0xffff ; x
shl ebx, 6
shl eax, 2
@ -408,17 +417,15 @@ check_mouse_area_for_putpixel:
add esi, 16*24*3
call combine_colors
pop edi esi
;--------------------------------------
align 4
.end:
mov eax, ecx
ret
;--------------------------------------
align 4
.no_mouse_area:
.no_mouse_area:
pop eax
ret
;-----------------------------------------------------------------------------
align 4
__sys_draw_pointer:
pushad
@ -430,14 +437,14 @@ __sys_draw_pointer:
je @f
mov [redrawmouse_unconditional], 0
jmp redrawmouse
;--------------------------------------
align 4
@@:
@@:
cmp eax, ecx
jne redrawmouse
cmp ebx, edx
je nodmp
;--------------------------------------
align 4
redrawmouse:
pushfd
@ -465,62 +472,62 @@ redrawmouse:
mov [X_UNDER_subtraction_CUR_hot_x], ax
add eax, [cur.w]
mov [X_UNDER_sub_CUR_hot_x_add_curh], ax
;--------------------------------------
align 4
@@:
@@:
popfd
;--------------------------------------
align 4
nodmp:
nodmp:
popad
ret
;-----------------------------------------------------------------------------
align 4
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword
proc set_mouse_data stdcall uses edx, 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 .absolute_x
call mouse_acceleration
add ax, [MOUSE_X];[XCoordinate]
add ax, [MOUSE_X]
cmp ax, 0
jge @@M1
jge .check_x
mov eax, 0
jmp @@M2
jmp .set_x
.absolute_x:
mov edx, [_display.width]
mul edx
shr eax, 15
.check_x:
cmp ax, word[Screen_Max_X]
jl .set_x
mov ax, word[Screen_Max_X]
.set_x:
mov [MOUSE_X], ax
;--------------------------------------
align 4
@@M1:
cmp ax, word [_display.width]
jl @@M2
mov ax, word [_display.width]
dec ax
;--------------------------------------
align 4
@@M2:
mov [MOUSE_X], ax;[XCoordinate]
mov eax, [YMoving]
test [BtnState], 0x40000000
jnz .absolute_y
neg eax
call mouse_acceleration
add ax, [MOUSE_Y];[YCoordinate]
add ax, [MOUSE_Y]
cmp ax, 0
jge @@M3
jge .check_y
mov ax, 0
jmp @@M4
jmp .set_y
.absolute_y:
mov edx, [_display.height]
mul edx
shr eax, 15
.check_y:
cmp ax, word[Screen_Max_Y]
jl .set_y
mov ax, word[Screen_Max_Y]
.set_y:
mov [MOUSE_Y], ax
;--------------------------------------
align 4
@@M3:
cmp ax, word [_display.height]
jl @@M4
mov ax, word [_display.height]
dec ax
;--------------------------------------
align 4
@@M4:
mov [MOUSE_Y], ax;[YCoordinate]
mov eax, [VScroll]
add [MOUSE_SCROLL_V], ax
@ -533,7 +540,9 @@ align 4
call wakeup_osloop
ret
endp
;-----------------------------------------------------------------------------
align 4
mouse_acceleration:
push eax
@ -545,8 +554,5 @@ mouse_acceleration:
;push edx
imul eax, [mouse_speed_factor]
;pop edx
;--------------------------------------
align 4
@@:
@@:
ret
;-----------------------------------------------------------------------------

View File

@ -128,12 +128,12 @@ proc init_mem
mov [pg_data.kernel_tables-OS_BASE], edx
xor eax, eax
mov edi, sys_pgdir-OS_BASE
mov ecx, 4096/4
mov edi, sys_proc-OS_BASE
mov ecx, 8192/4
cld
rep stosd
mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20)
mov edx, (sys_proc-OS_BASE+PROC.pdt_0)+ 0x800; (OS_BASE shr 20)
bt [cpu_caps-OS_BASE], CAPS_PSE
jnc .no_PSE
@ -177,9 +177,9 @@ proc init_mem
dec ecx
jnz .map_kernel_tabs
mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE
mov dword [sys_proc-OS_BASE+PROC.pdt_0+(page_tabs shr 20)], sys_proc+PROC.pdt_0+PG_SW-OS_BASE
mov edi, (sys_pgdir-OS_BASE)
mov edi, (sys_proc+PROC.pdt_0-OS_BASE)
lea esi, [edi+(OS_BASE shr 20)]
movsd
movsd
@ -345,15 +345,13 @@ align 4
proc test_cpu
locals
cpu_type dd ?
cpu_id dd ?
cpu_Intel dd ?
cpu_AMD dd ?
endl
xor eax, eax
mov [cpu_type], eax
mov [cpu_caps-OS_BASE], eax
mov [cpu_caps+4-OS_BASE], eax
mov [cpu_phys_addr_width-OS_BASE], 32
pushfd
pop eax
@ -378,7 +376,6 @@ proc test_cpu
pop eax
xor eax, ecx
je .end_cpuid
mov [cpu_id], 1
xor eax, eax
cpuid
@ -386,13 +383,7 @@ proc test_cpu
mov [cpu_vendor-OS_BASE], ebx
mov [cpu_vendor+4-OS_BASE], edx
mov [cpu_vendor+8-OS_BASE], ecx
cmp ebx, dword [intel_str-OS_BASE]
jne .check_AMD
cmp edx, dword [intel_str+4-OS_BASE]
jne .check_AMD
cmp ecx, dword [intel_str+8-OS_BASE]
jne .check_AMD
mov [cpu_Intel], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
@ -402,42 +393,26 @@ proc test_cpu
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
bt edx, CAPS_PAE
jnc @f
mov [cpu_phys_addr_width-OS_BASE], 36
@@:
mov eax, 0x80000000
cpuid
cmp eax, 0x80000008
jb @f
mov eax, 0x80000008
cpuid
mov [cpu_phys_addr_width-OS_BASE], al
@@:
mov eax, [cpu_sign-OS_BASE]
shr eax, 8
and eax, 0x0f
ret
.end_cpuid:
mov eax, [cpu_type]
ret
.check_AMD:
cmp ebx, dword [AMD_str-OS_BASE]
jne .unknown
cmp edx, dword [AMD_str+4-OS_BASE]
jne .unknown
cmp ecx, dword [AMD_str+8-OS_BASE]
jne .unknown
mov [cpu_AMD], 1
cmp eax, 1
jl .unknown
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
shr eax, 8
and eax, 0x0f
ret
.unknown:
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
shr eax, 8
and eax, 0x0f
ret
endp
iglobal

File diff suppressed because it is too large Load Diff

View File

@ -98,17 +98,35 @@ struct DBG_REGS
dr7 dd ?
ends
struct PROC
list LHEAD
thr_list LHEAD
heap_lock MUTEX
heap_base rd 1
heap_top rd 1
mem_used rd 1
dlls_list_ptr rd 1
pdt_0_phys rd 1
pdt_1_phys rd 1
io_map_0 rd 1
io_map_1 rd 1
ht_lock rd 1
ht_next rd 1
htab rd (4096-$)/4
pdt_0 rd 1024
ends
struct APPDATA
app_name rb 11
rb 5
fpu_state dd ? ;+16
ev_count_ dd ? ;unused ;+20
exc_handler dd ? ;+24
except_mask dd ? ;+28
pl0_stack dd ? ;+32
heap_base dd ? ;+36
heap_top dd ? ;+40
list LHEAD ;+16
process dd ? ;+24
fpu_state dd ? ;+28
exc_handler dd ? ;+32
except_mask dd ? ;+36
pl0_stack dd ? ;+40
cursor dd ? ;+44
fd_ev dd ? ;+48
bk_ev dd ? ;+52
@ -124,7 +142,7 @@ struct APPDATA
wait_test dd ? ;+96 +++
wait_param dd ? ;+100 +++
tls_base dd ? ;+104
dlls_list_ptr dd ? ;+108
dd ? ;+108
event_filter dd ? ;+112
draw_bgr_x dd ? ;+116
draw_bgr_y dd ? ;+120
@ -133,7 +151,7 @@ struct APPDATA
wnd_shape dd ? ;+128
wnd_shape_scale dd ? ;+132
dd ? ;+136
mem_size dd ? ;+140
dd ? ;+140
saved_box BOX ;+144
ipc_start dd ? ;+160
ipc_size dd ? ;+164
@ -142,7 +160,7 @@ struct APPDATA
terminate_protection dd ? ;+176
keyboard_mode db ? ;+180
rb 3
dir_table dd ? ;+184
dd ? ;+184
dbg_event_mem dd ? ;+188
dbg_regs DBG_REGS ;+192
wnd_caption dd ? ;+212
@ -152,6 +170,36 @@ struct APPDATA
ends
struct IDE_DATA
ProgrammingInterface dd ?
Interrupt dw ?
RegsBaseAddres dw ?
BAR0_val dw ?
BAR1_val dw ?
BAR2_val dw ?
BAR3_val dw ?
dma_hdd_channel_1 db ?
dma_hdd_channel_2 db ?
ends
struct IDE_CACHE
pointer dd ?
size dd ? ; not use
data_pointer dd ?
system_data_size dd ? ; not use
appl_data_size dd ? ; not use
system_data dd ?
appl_data dd ?
system_sad_size dd ?
appl_sad_size dd ?
search_start dd ?
appl_search_start dd ?
ends
struct IDE_DEVICE
UDMA_possible_modes db ?
UDMA_set_mode db ?
ends
; Core functions
include "core/sync.inc" ; macros for synhronization objects
@ -160,6 +208,7 @@ include "core/sched.inc" ; process scheduling
include "core/syscall.inc" ; system call
include "core/fpu.inc" ; all fpu/sse support
include "core/memory.inc"
include "core/mtrr.inc"
include "core/heap.inc" ; kernel and app heap
include "core/malloc.inc" ; small kernel heap
include "core/taskman.inc"
@ -242,7 +291,6 @@ include "blkdev/bd_drv.inc"
; CD drive controller
include "blkdev/cdrom.inc"
include "blkdev/cd_drv.inc"
; Character devices

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Éste archivo debe ser editado con codificación CP866
version cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0

View File

@ -89,6 +89,12 @@ macro Mov op1,op2,op3 ; op1 = op2 = op3
mov op1, op2
}
macro list_init head
{
mov [head+LHEAD.next], head
mov [head+LHEAD.prev], head
}
macro __list_add new, prev, next
{
mov [next+LHEAD.prev], new
@ -111,10 +117,10 @@ macro list_add_tail new, head
macro list_del entry
{
mov edx, [entry+list_fd]
mov ecx, [entry+list_bk]
mov [edx+list_bk], ecx
mov [ecx+list_fd], edx
mov edx, [entry+LHEAD.next]
mov ecx, [entry+LHEAD.prev]
mov [edx+LHEAD.prev], ecx
mov [ecx+LHEAD.next], edx
}
; MOV Immediate.

View File

@ -1,47 +1,38 @@
FASM=fasm
FLAGS=-m 65536
languages=en|ru|ge|et|sp
drivers_src=com_mouse emu10k1x fm801 infinity sis sound vt823x
.PHONY: all kernel drivers bootloader clean
all: kernel drivers bootloader
kernel: check_lang
@echo "*** building kernel with language '$(lang)' ..."
@mkdir -p bin
@echo "lang fix $(lang)" > lang.inc
@echo "--- building 'bin/kernel.mnt' ..."
@$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt
@rm -f lang.inc
drivers:
@echo "*** building drivers ..."
@mkdir -p bin/drivers
@cd drivers; for f in $(drivers_src); do \
echo "--- building 'bin/drivers/$${f}.obj' ..."; \
$(FASM) $(FLAGS) "$${f}.asm" "../bin/drivers/$${f}.obj" || exit $?; \
done
bootloader: check_lang
@echo "*** building bootloader with language '$(lang)' ..."
@mkdir -p bin
@echo "lang fix $(lang)" > lang.inc
@echo "--- building 'bin/boot_fat12.bin' ..."
@$(FASM) $(FLAGS) bootloader/boot_fat12.asm bin/boot_fat12.bin
@rm -f lang.inc
check_lang:
@case "$(lang)" in \
$(languages)) \
;; \
*) \
echo "*** error: language is incorrect or not specified"; \
exit 1; \
;; \
esac
clean:
rm -rf bin
rm -f lang.inc
FASM=fasm
FLAGS=-m 65536
languages=en|ru|ge|et|sp
.PHONY: all kernel bootloader clean
all: kernel bootloader
kernel: check_lang
@echo "*** building kernel with language '$(lang)' ..."
@mkdir -p bin
@echo "lang fix $(lang)" > lang.inc
@echo "--- building 'bin/kernel.mnt' ..."
@$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt
@rm -f lang.inc
bootloader: check_lang
@echo "*** building bootloader with language '$(lang)' ..."
@mkdir -p bin
@echo "lang fix $(lang)" > lang.inc
@echo "--- building 'bin/boot_fat12.bin' ..."
@$(FASM) $(FLAGS) bootloader/boot_fat12.asm bin/boot_fat12.bin
@rm -f lang.inc
check_lang:
@case "$(lang)" in \
$(languages)) \
;; \
*) \
echo "*** error: language is incorrect or not specified"; \
exit 1; \
;; \
esac
clean:
rm -rf bin
rm -f lang.inc

View File

@ -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 ;;
;; ;;
;; ARP.INC ;;
@ -318,10 +318,9 @@ ARP_output_request:
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\
[esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
lea eax, [ebx + ETH_DEVICE.mac] ; local device mac
mov edx, ETH_BROADCAST ; broadcast mac
mov ax, ETHER_PROTO_ARP
mov ecx, sizeof.ARP_header
mov di, ETHER_PROTO_ARP
mov edx, ETH_BROADCAST ; broadcast mac
call ETH_output
jz .exit

View File

@ -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 ;;
;; ;;
;; IPv4.INC ;;
@ -267,10 +267,9 @@ IPv4_input: ; TODO: add IPv4
cmp eax, 224
je .ip_ok
; or a loopback address (127.0.0.0/8)
; maybe we just dont have an IP yet and should accept everything on the IP level
and eax, 0x00ffffff
cmp eax, 127
cmp [IP_LIST + edi], 0
je .ip_ok
; or it's just not meant for us.. :(
@ -577,11 +576,11 @@ IPv4_find_fragment_slot:
; edx = Source IP
; di = TTL shl 8 + protocol
;
; OUT: eax = pointer to buffer start
; ebx = pointer to device struct (needed for sending procedure)
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer
; edi = pointer to start of data (0 on error)
; OUT: eax = pointer to buffer start / 0 on error
; ebx = device ptr (send packet through this device)
; ecx = data length
; edx = size of complete frame
; edi = start of IPv4 payload
;
;------------------------------------------------------------------
align 4
@ -595,7 +594,6 @@ IPv4_output:
push ecx di eax
call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
push edx
test edi, edi
jz .loopback
@ -607,12 +605,11 @@ IPv4_output:
inc [IPv4_packets_tx + edi] ; update stats
mov ax, ETHER_PROTO_IPv4
mov ebx, [NET_DRV_LIST + edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6 + 8 + 2]
add ecx, sizeof.IPv4_header
mov di, ETHER_PROTO_IPv4
mov edx, esp
call ETH_output
jz .eth_error
add esp, 6 ; pop the mac out of the stack
@ -642,18 +639,18 @@ IPv4_output:
.eth_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ethernet error\n"
add esp, 3*4+2+6
xor edi, edi
xor eax, eax
ret
.arp_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
add esp, 3*4+2
xor edi, edi
xor eax, eax
ret
.too_large:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: Packet too large!\n"
xor edi, edi
xor eax, eax
ret
.loopback:
@ -675,7 +672,7 @@ IPv4_output:
; ecx = data length
; esi = data ptr
;
; OUT: /
; OUT: eax = -1 on error
;
;------------------------------------------------------------------
align 4
@ -699,15 +696,13 @@ IPv4_output_raw:
push ax
inc [IPv4_packets_tx + 4*edi]
mov ax, ETHER_PROTO_IPv4
mov ebx, [NET_DRV_LIST + 4*edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6 + 4]
add ecx, sizeof.IPv4_header
mov di, ETHER_PROTO_IPv4
mov edx, esp
call ETH_output
jz .error
add esp, 6 ; pop the mac
mov dword[esp+4+4], edx
@ -746,7 +741,7 @@ IPv4_output_raw:
add esp, 8+4+4
.too_large:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n"
sub edi, edi
or eax, -1
ret
@ -795,13 +790,9 @@ IPv4_fragment:
.new_fragment:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
mov eax, [esp + 3*4]
mov ax, ETHER_PROTO_IPv4
lea ebx, [esp + 4*4]
mov di , ETHER_PROTO_IPv4
call ETH_output
cmp edi, -1
jz .err
; copy header

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2012-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2012-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; PPPoE.INC ;;
@ -14,6 +14,9 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5015 $
struct PPPoE_frame
VersionAndType db ?
Code db ?
@ -240,17 +243,15 @@ PPPoE_session_input:
;
; PPPoE_output
;
; IN:
; IN: ax = protocol
; ebx = device ptr
; ecx = packet size
;
; di = protocol
;
; OUT: edi = 0 on error, pointer to buffer otherwise
; eax = buffer start
; ebx = to device structure
; ecx = unchanged (packet size of embedded data)
; OUT: eax = buffer start / 0 on error
; ebx = device ptr
; ecx = packet size
; edx = size of complete buffer
; edi = start of PPP payload
;
;-----------------------------------------------------------------
align 4
@ -258,13 +259,12 @@ PPPoE_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: size=%u device=%x\n", ecx, ebx
pushw di
pushw ax
pushw [PPPoE_SID]
lea eax, [ebx + ETH_DEVICE.mac]
lea edx, [PPPoE_MAC]
mov ax, ETHER_PROTO_PPP_SESSION
add ecx, PPPoE_frame.Payload + 2
mov di, ETHER_PROTO_PPP_SESSION
lea edx, [PPPoE_MAC]
call ETH_output
jz .eth_error
@ -287,8 +287,7 @@ PPPoE_output:
.eth_error:
add esp, 4
xor edi, edi
xor eax, eax
ret

View File

@ -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 ;;
;; ;;
;; ETHERNET.INC ;;
@ -86,11 +86,7 @@ ETH_input:
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 @@ ETH_input:
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
@ -150,14 +145,14 @@ ETH_process_input:
cmp ax, ETHER_PROTO_ARP
je ARP_input
cmp ax, ETHER_PROTO_IPv6
je IPv6_input
; cmp ax, ETHER_PROTO_IPv6
; je IPv6_input
cmp ax, ETHER_PROTO_PPP_DISCOVERY
je PPPoE_discovery_input
; cmp ax, ETHER_PROTO_PPP_DISCOVERY
; je PPPoE_discovery_input
cmp ax, ETHER_PROTO_PPP_SESSION
je PPPoE_session_input
; cmp ax, ETHER_PROTO_PPP_SESSION
; je PPPoE_session_input
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
@ -171,17 +166,16 @@ ETH_process_input:
;
; ETH_output
;
; IN: eax = pointer to source mac
; IN: ax = protocol
; ebx = device ptr
; ecx = packet size
; ecx = payload size
; edx = pointer to destination mac
; di = protocol
;
; OUT: edi = 0 on error, pointer to buffer otherwise
; eax = buffer start
; ebx = to device structure
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer
; OUT: eax = start of ethernet frame / 0 on error
; ebx = device ptr
; ecx = payload size
; edx = ethernet frame size
; edi = start of ethernet payload
;
;-----------------------------------------------------------------
align 4
@ -189,11 +183,11 @@ ETH_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
cmp ecx, [ebx + NET_DEVICE.mtu]
cmp ecx, [ebx + ETH_DEVICE.mtu]
ja .exit
push ecx
push di eax edx
push ax edx
add ecx, sizeof.ETH_header
stdcall kernel_alloc, ecx
@ -204,7 +198,7 @@ ETH_output:
pop esi
movsd
movsw
pop esi
lea esi, [ebx + ETH_DEVICE.mac]
movsd
movsw
pop ax
@ -227,13 +221,13 @@ ETH_output:
.out_of_ram:
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
add esp, 4+4+2+4
sub edi, edi
add esp, 4+2+4
xor eax, eax
ret
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
sub edi, edi
xor eax, eax
ret

View File

@ -294,12 +294,12 @@ ICMP_input:
call mutex_unlock
popa
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: no socket found\n"
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
jmp .dump
.checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n"
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"

View File

@ -28,7 +28,6 @@ struct queue
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 @@ macro add_to_queue ptr, size, entry_size, failaddr {
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 @@ local .ok, .no_wrap
.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 @@ macro get_from_queue ptr, size, entry_size, failaddr {
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 @@ local .ok, .no_wrap
pop esi
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
spin_unlock_irqrestore
}
@ -136,6 +117,4 @@ macro init_queue ptr {
mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi
lea ecx, [ptr + queue.mutex]
call mutex_init
}

View File

@ -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 @@ SOCKET_open:
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 @@ SOCKET_close:
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 @@ SOCKET_pair:
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 @@ SOCKET_pair:
mov ebx, eax
call SOCKET_alloc
test eax, eax
jz .nomem2
mov [esp+20], edi ; application's ebx
@ -1220,10 +1223,13 @@ SOCKET_pair:
lea eax, [eax + STREAM_SOCKET.rcv]
call SOCKET_ring_create
test eax, eax
jz .nomem1
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
pop eax
test eax, eax
jz .nomem2
ret
@ -1465,7 +1471,8 @@ SOCKET_input:
;--------------------------
;
; eax = ptr to ring struct (just a buffer of the right size)
; IN: eax = ptr to ring struct (just a buffer of the right size)
; OUT: eax = unchanged / 0 on error
;
align 4
SOCKET_ring_create:
@ -1476,6 +1483,8 @@ SOCKET_ring_create:
push edx
stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
pop edx
test eax, eax
jz .fail
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax
@ -1493,6 +1502,7 @@ SOCKET_ring_create:
mov eax, esi
pop esi
.fail:
ret
;-----------------------------------------------------------------
@ -1536,6 +1546,7 @@ SOCKET_ring_write:
jb @f
sub edi, SOCKET_MAXDATA ; WRAP
@@:
mov [eax + RING_BUFFER.write_ptr], edi
pop edi
@ -1707,8 +1718,9 @@ SOCKET_block:
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
pushf
push eax
pushf
cli
; Set the 'socket is blocked' flag
@ -1724,12 +1736,12 @@ SOCKET_block:
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 +1764,54 @@ SOCKET_notify:
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
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
; PID not found, TODO: close socket!
jmp .done
.found_pid:
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
.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
; 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], eax
cmp [esi + TASKDATA.pid], ebx
je .found
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next
jmp .error
.found:
; Run the thread
mov [esi + TASKDATA.state], 0 ; Running
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n"
.done:
pop esi ecx eax
.error2:
; PID not found, TODO: close socket!
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: error finding thread 0x%x !\n", ebx
pop esi ecx ebx
ret
.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
pop esi ecx ebx
ret
.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
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n"
pop esi ecx ebx
ret
@ -1830,7 +1826,6 @@ SOCKET_notify:
; IN: /
; OUT: eax = 0 on error, socket ptr otherwise
; edi = socket number
; ZF = cleared on error
;
;--------------------------------------------------------------------
align 4
@ -1917,7 +1912,6 @@ SOCKET_alloc:
@@:
mov [net_sockets + SOCKET.NextPtr], eax
or eax, eax ; used to clear zero flag
pusha
mov ecx, socket_mutex
@ -1968,8 +1962,14 @@ SOCKET_free:
jnz .no_tcp
mov ebx, eax
cmp [ebx + STREAM_SOCKET.rcv.start_ptr], 0
je @f
stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr]
@@:
cmp [ebx + STREAM_SOCKET.snd.start_ptr], 0
je @f
stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
@@:
mov eax, ebx
.no_tcp:
@ -2022,6 +2022,7 @@ SOCKET_fork:
push ebx
call SOCKET_alloc
pop ebx
test eax, eax
jz .fail
push eax
@ -2101,7 +2102,8 @@ SOCKET_num_to_ptr:
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
@ -2210,6 +2212,8 @@ SOCKET_check_owner:
align 4
SOCKET_process_end:
ret ; FIXME
cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all?
je .quickret ; nope, exit immediately

View File

@ -110,7 +110,7 @@ SS_MORETOCOME = 0x4000
SS_BLOCKED = 0x8000
SOCKET_MAXDATA = 4096*8 ; must be 4096*(power of 2) where 'power of 2' is at least 8
SOCKET_MAXDATA = 4096*64 ; must be 4096*(power of 2) where 'power of 2' is at least 8
MAX_backlog = 20 ; maximum backlog for stream sockets
; Error Codes
@ -313,10 +313,15 @@ stack_handler:
test [net_10ms], 0x3f ; 640ms
jnz .exit
TCP_timer_640ms
ARP_decrease_entry_ttls
IPv4_decrease_fragment_ttls
xor edx, edx
mov eax, [TCP_timer1_event]
mov ebx, [eax + EVENT.id]
xor esi, esi
call raise_event
.exit:
ret

View File

@ -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 ;;
@ -96,6 +96,7 @@ TCP_RTTVAR_SHIFT = 2
TCP_BIT_NEEDOUTPUT = 1 shl 0
TCP_BIT_TIMESTAMP = 1 shl 1
TCP_BIT_DROPSOCKET = 1 shl 2
TCP_BIT_FIN_IS_ACKED = 1 shl 3
TCP_BIT_SENDALOT = 1 shl 0
@ -119,13 +120,13 @@ ends
struct TCP_queue_entry
ip_ptr dd ?
segment_ptr dd ?
segment_size dd ?
device_ptr dd ?
ip_ptr dd ?
segment_ptr dd ?
segment_size dd ?
device_ptr dd ?
buffer_ptr dd ?
timestamp dd ?
buffer_ptr dd ?
timestamp dd ?
ends
@ -141,6 +142,7 @@ align 4
TCP_sequence_num dd ?
TCP_queue rd (TCP_QUEUE_SIZE*sizeof.TCP_queue_entry + sizeof.queue)/4
TCP_input_event dd ?
TCP_timer1_event dd ?
endg
uglobal
@ -224,7 +226,15 @@ macro TCP_init {
call new_sys_threads
test eax, eax
jns @f
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP, error %d\n', eax
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP input, error %d\n', eax
@@:
movi ebx, 1
mov ecx, TCP_timer_640ms
call new_sys_threads
test eax, eax
jns @f
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP timer, error %d\n', eax
@@:
}
@ -264,6 +274,8 @@ TCP_api:
jz .packets_missed ; 2
dec bl
jz .packets_dumped ; 3
dec bl
jz .packets_queued ; 4
.error:
mov eax, -1
@ -284,3 +296,7 @@ TCP_api:
.packets_dumped:
mov eax, [TCP_segments_dumped + eax]
ret
.packets_queued:
mov eax, [TCP_queue + queue.size]
ret

View File

@ -1,20 +1,20 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; Based on the code of 4.4BSD ;;
;; Based on the algorithms used in 4.4BSD ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 3407 $
$Revision: 5155 $
;-----------------------------------------------------------------
;
@ -43,11 +43,7 @@ TCP_input:
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
@ -62,7 +58,6 @@ TCP_input:
ret
.fail:
popf
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
call NET_ptr_to_num4
@ -536,11 +531,9 @@ endl
cmp eax, [ebx + TCP_SOCKET.SND_UNA]
jne .not_uni_xfer
; - The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp).
;;; TODO
; jnz .not_uni_xfer
; - The reassembly list of out-of-order segments for the connection is empty.
cmp [ebx + TCP_SOCKET.seg_next], 0
jne .not_uni_xfer
; Complete processing of received data
@ -845,7 +838,7 @@ endl
pop word [ebx + TCP_SOCKET.SND_SCALE]
@@:
;;; TODO: call TCP_reassemble
call TCP_reassemble
mov eax, [edx + TCP_header.SequenceNumber]
dec eax
@ -1099,8 +1092,7 @@ endl
pop ebx edx ecx
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is acked\n"
stc
or [temp_bits], TCP_BIT_FIN_IS_ACKED
jmp .wakeup
.finiacked:
@ -1114,19 +1106,15 @@ endl
pop edx ecx
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is not acked\n"
clc
;----------------------------------------
; Wake up process waiting on send buffer
.wakeup:
pushf ; Keep the flags (Carry flag)
mov eax, ebx
call SOCKET_notify
; Update TCPS
mov eax, [edx + TCP_header.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax
cmp eax, [ebx + TCP_SOCKET.SND_NXT]
@ -1134,8 +1122,6 @@ endl
mov [ebx + TCP_SOCKET.SND_NXT], eax
@@:
popf
; General ACK handling complete
; Now do the state-specific ones
; Carry flag is set when our FIN is acked
@ -1158,7 +1144,8 @@ endl
.ack_fw1:
jnc .ack_processed
test [temp_bits], TCP_BIT_FIN_IS_ACKED
jz .ack_processed
test [ebx + SOCKET.state], SS_CANTRCVMORE
jnz @f
@ -1171,7 +1158,8 @@ endl
jmp .ack_processed
.ack_c:
jnc .ack_processed
test [temp_bits], TCP_BIT_FIN_IS_ACKED
jz .ack_processed
mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
mov eax, ebx
@ -1183,7 +1171,8 @@ endl
jmp .ack_processed
.ack_la:
jnc .ack_processed
test [temp_bits], TCP_BIT_FIN_IS_ACKED
jz .ack_processed
push ebx
lea ecx, [ebx + SOCKET.mutex]
@ -1246,9 +1235,13 @@ align 4
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create
test eax, eax
jz .drop
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
test eax, eax
jz .drop
and [temp_bits], not TCP_BIT_DROPSOCKET
@ -1257,7 +1250,7 @@ align 4
call SOCKET_notify
popa
jmp .trim_then_step6
jmp .trim
;------------
; Active Open
@ -1350,9 +1343,9 @@ align 4
mov eax, [ebx + TCP_SOCKET.t_rtt]
test eax, eax
je .trim_then_step6
je .trim
call TCP_xmit_timer
jmp .trim_then_step6
jmp .trim
.simultaneous_open:
@ -1363,8 +1356,7 @@ align 4
;-------------------------------------
; Common processing for receipt of SYN
.trim_then_step6:
.trim:
inc [edx + TCP_header.SequenceNumber]
; Drop any received data that doesnt fit in the receive window.
@ -1377,17 +1369,12 @@ align 4
;;; TODO: update stats
.dont_trim:
mov eax, [edx + TCP_header.SequenceNumber]
mov [ebx + TCP_SOCKET.RCV_UP], eax
dec eax
mov [ebx + TCP_SOCKET.SND_WL1], eax
;-------
; step 6
.ack_processed:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK processed\n"
;----------------------------------------------
@ -1592,14 +1579,14 @@ align 4
jnz .need_output
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jz .dumpit
jz .done
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n"
.need_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n"
call TCP_output
.dumpit:
.done:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
call NET_packet_free
@ -1619,7 +1606,7 @@ align 4
pop eax edx
test [edx + TCP_header.Flags], TH_RST
jnz .dumpit
jnz .done
or [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jmp .need_output
@ -1633,7 +1620,7 @@ align 4
pop edx ebx
test [edx + TCP_header.Flags], TH_RST
jnz .dumpit
jnz .done
;;; if its a multicast/broadcast, also drop
@ -1642,7 +1629,7 @@ align 4
test [edx + TCP_header.Flags], TH_SYN
jnz .respond_syn
jmp .dumpit
jmp .done
;---------
; Respond
@ -1661,8 +1648,10 @@ align 4
pop ebx
jmp .destroy_new_socket
.no_socket:
;-----------------------------------------
; The connection has no associated socket
.no_socket:
pusha
mov ecx, socket_mutex
call mutex_unlock
@ -1692,8 +1681,8 @@ align 4
call TCP_respond_segment
jmp .drop_no_socket
;-----
; Drop
;------------------------------------------------
; Unlock socket mutex and prepare to drop segment
.drop:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Dropping segment\n"
@ -1703,6 +1692,9 @@ align 4
call mutex_unlock
popa
;--------------------------------------------
; Destroy the newly created socket if needed
.destroy_new_socket:
test [temp_bits], TCP_BIT_DROPSOCKET
jz .drop_no_socket
@ -1710,6 +1702,9 @@ align 4
mov eax, ebx
call SOCKET_free
;------------------
; Drop the segment
.drop_no_socket:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n"

View File

@ -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 ;;
@ -14,7 +14,7 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 3514 $
$Revision: 5015 $
align 4
iglobal
@ -143,7 +143,7 @@ TCP_pull_out_of_band:
;
;-------------------------
align 4
TCP_drop:
TCP_drop: ; FIXME CHECKME TODO
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_drop: %x\n", eax
@ -290,7 +290,6 @@ TCP_respond:
mov ecx, sizeof.TCP_header
mov di, IP_PROTO_TCP shl 8 + 128
call IPv4_output
test edi, edi
jz .error
pop esi cx
push edx eax

View File

@ -14,7 +14,7 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 3143 $
$Revision: 5013 $
timer_flag_retransmission = 1 shl 0
timer_flag_keepalive = 1 shl 1
@ -61,13 +61,18 @@ local .exit
}
;----------------------
; 640 ms timer
;----------------------
macro TCP_timer_640ms { ; TODO: implement timed wait timer!
align 4
proc TCP_timer_640ms ; TODO: implement timed wait timer!
local .loop
local .exit
xor esi, esi
mov ecx, MANUAL_DESTROY
call create_event
mov [TCP_timer1_event], eax
.wait:
mov eax, [TCP_timer1_event]
mov ebx, [eax + EVENT.id]
call wait_event
; Update TCP sequence number
@ -81,7 +86,7 @@ local .exit
mov eax, [eax + SOCKET.NextPtr]
.check_only:
or eax, eax
jz .exit
jz .wait
cmp [eax + SOCKET.Domain], AF_INET4
jne .loop
@ -157,9 +162,8 @@ local .exit
mov [eax + TCP_SOCKET.t_force], 0
jmp .loop
.exit:
}
endp

View File

@ -14,6 +14,8 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
;-------------------------
;
@ -186,7 +188,7 @@ TCP_connect:
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:

View File

@ -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 ;;
;; ;;
;; UDP.INC ;;
@ -245,6 +245,8 @@ UDP_input:
; ecx = number of bytes to send
; esi = pointer to data
;
; OUT: eax = -1 on error
;
;-----------------------------------------------------------------
align 4

View File

@ -1,10 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5164 $
struct BLITTER_BLOCK
xmin dd ?
ymin dd ?

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -295,15 +295,17 @@ proc set_cursor stdcall, hcursor:dword
; jne .fail
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
ret
jmp .end
;--------------------------------------
align 4
.fail:
mov eax, [def_cursor]
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
align 4
.end:
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
ret
endp
;------------------------------------------------------------------------------
@ -578,6 +580,40 @@ align 4
endp
;------------------------------------------------------------------------------
align 4
proc restore_16 stdcall, x:dword, y:dword
push ebx
mov ebx, [cur_saved_base]
mov edx, [cur.h]
test edx, edx
jz .ret
push esi
push edi
mov esi, cur_saved_data
;--------------------------------------
align 4
@@:
mov edi, ebx
add ebx, [_display.pitch]
mov ecx, [cur.w]
rep movsw
dec edx
jnz @B
pop edi
;--------------------------------------
align 4
.ret:
pop esi
pop ebx
ret
endp
;------------------------------------------------------------------------------
align 4
proc move_cursor_24 stdcall, hcursor:dword, x:dword, y:dword
locals
h dd ?
@ -817,6 +853,129 @@ align 4
endp
;------------------------------------------------------------------------------
align 4
proc move_cursor_16 stdcall, hcursor:dword, x:dword, y:dword
locals
h dd ?
_dx dd ?
_dy dd ?
endl
mov esi, [hcursor]
mov ecx, [x]
mov eax, [y]
xor edx, edx
sub ecx, [esi+CURSOR.hot_x]
lea ebx, [ecx+32-1]
mov [x], ecx
sets dl
dec edx
and ecx, edx ;clip x to 0<=x
mov [cur.left], ecx
mov edi, ecx
sub edi, [x]
mov [_dx], edi
xor edx, edx
sub eax, [esi+CURSOR.hot_y]
lea edi, [eax+32-1]
mov [y], eax
sets dl
dec edx
and eax, edx ;clip y to 0<=y
mov [cur.top], eax
mov edx, eax
sub edx, [y]
mov [_dy], edx
; mul dword [BytesPerScanLine]
mov eax, [BPSLine_calc_area+eax*4]
lea edx, [LFB_BASE+eax+ecx*2]
mov [cur_saved_base], edx
cmp ebx, [Screen_Max_X]
jbe @F
mov ebx, [Screen_Max_X]
;--------------------------------------
align 4
@@:
cmp edi, [Screen_Max_Y]
jbe @F
mov edi, [Screen_Max_Y]
;--------------------------------------
align 4
@@:
mov [cur.right], ebx
mov [cur.bottom], edi
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
sub ebx, [_dx]
sub edi, [_dy]
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
mov eax, edi
mov edi, cur_saved_data
;--------------------------------------
align 4
@@:
mov esi, edx
add edx, [_display.pitch]
mov ecx, [cur.w]
rep movsw
dec eax
jnz @B
;draw cursor
mov ebx, [cur_saved_base]
mov eax, [_dy]
shl eax, 5
add eax, [_dx]
mov esi, [hcursor]
mov esi, [esi+CURSOR.base]
lea edx, [esi+eax*4]
;--------------------------------------
align 4
.row:
mov ecx, [cur.w]
mov esi, edx
mov edi, ebx
add edx, 32*4
add ebx, [_display.pitch]
;--------------------------------------
align 4
.pix:
lodsd
test eax, 0xFF000000
jz @F
; convert to 16 bpp and store to real LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edi], ax
;--------------------------------------
align 4
@@:
add edi, 2
dec ecx
jnz .pix
dec [h]
jnz .row
ret
endp
;------------------------------------------------------------------------------
align 4
check_mouse_area_for_getpixel_new:
; in:
; eax = x
@ -852,7 +1011,10 @@ check_mouse_area_for_getpixel_new:
add eax, ebx
mov ebx, eax
shl eax, 2
cmp byte [_display.bpp], 32
cmp byte [_display.bits_per_pixel], 32
je @f
sub eax, ebx
cmp byte [_display.bits_per_pixel], 24
je @f
sub eax, ebx
;--------------------------------------
@ -927,13 +1089,29 @@ align 4
add ecx, ebx
mov ebx, ecx
shl ecx, 2
cmp byte [_display.bpp], 24
cmp byte [_display.bits_per_pixel], 16
je .16
cmp byte [_display.bits_per_pixel], 24
je .24
and eax, 0xFFFFFF
mov [ecx + cur_saved_data], eax ;store new color to
jmp @f
;--------------------------------------
align 4
.16:
sub ecx, ebx
sub ecx, ebx
; convert to 16 bpp and store to real LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [ecx + cur_saved_data], ax ;store new color to
jmp @f
;--------------------------------------
align 4
.24:
sub ecx, ebx
mov [ecx + cur_saved_data], ax ;store new color to
@ -1001,9 +1179,9 @@ init_display:
mov ebx, restore_32
mov ecx, move_cursor_32
mov edx, Vesa20_putpixel32_new
mov eax, [_display.bpp]
mov eax, [_display.bits_per_pixel]
cmp al, 32
jne .24
jne .not_32bpp
.set:
mov [_display.select_cursor], select_cursor
@ -1022,12 +1200,30 @@ init_display:
mov [def_cursor], eax
ret
.24:
.not_32bpp:
cmp al, 24
jne .not_24bpp
mov ebx, restore_24
mov ecx, move_cursor_24
mov edx, Vesa20_putpixel24_new
cmp al, 24
je .set
jmp .set
.not_24bpp:
cmp al, 16
jne .not_16bpp
mov ebx, restore_16
mov ecx, move_cursor_16
mov edx, Vesa20_putpixel16_new
jmp .set
.not_16bpp:
; cmp al, 15
; jne .fail
; mov ebx, restore_15
; mov ecx, move_cursor_15
; mov edx, Vesa20_putpixel15_new
; jmp .set
.fail:
xor eax, eax

File diff suppressed because it is too large Load Diff