diff --git a/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc b/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc index 11650deea8..c171931cd3 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc @@ -7,7 +7,7 @@ $Revision$ - +;----------------------------------------------------------------------------- ;********************************************************** ; Непосредственная работа с устройством СD (ATAPI) ;********************************************************** @@ -37,16 +37,17 @@ ReadCDWRetr: xor edi, edi add esi, 8 inc edi +;-------------------------------------- +align 4 .hdreadcache: -; cmp dword [esi+4],0 ; empty -; je .nohdcache cmp [esi], eax ; correct sector je .yeshdcache -.nohdcache: + add esi, 8 inc edi dec ecx jnz .hdreadcache + call find_empty_slot_CD_cache ; ret in edi push edi @@ -66,28 +67,30 @@ ReadCDWRetr: call cd_calculate_cache_1 lea esi, [edi*8+esi] mov [esi], eax ; sector number -; mov dword [esi+4],1 ; hd read - mark as same as in hd +;-------------------------------------- .yeshdcache: mov esi, edi - shl esi, 11;9 + shl esi, 11 ;9 push eax call cd_calculate_cache_2 add esi, eax pop eax - mov edi, ebx;[CDDataBuf_pointer] - mov ecx, 512;/4 + mov edi, ebx ;[CDDataBuf_pointer] + mov ecx, 512 ;/4 cld rep movsd ; move data +;-------------------------------------- .exit: popad ret - +;----------------------------------------------------------------------------- ReadCDWRetr_1: pushad - ; Цикл, пока команда не выполнена успешно или не ; исчерпано количество попыток - mov ECX, MaxRetr + mov ecx, MaxRetr +;-------------------------------------- +align 4 @@NextRetr: ; Подать команду ;************************************************* @@ -103,89 +106,74 @@ ReadCDWRetr_1: ;************************************************* ;ReadCD: push ecx -; pusha -; Задать размер сектора -; mov [CDBlockSize],2048 ;2352 ; Очистить буфер пакетной команды call clear_packet_buffer ; Сформировать пакетную команду для считывания ; сектора данных ; Задать код команды Read CD - mov [PacketCommand], byte 0x28;0xBE + mov [PacketCommand], byte 0x28 ;0xBE ; Задать адрес сектора - mov AX, word [CDSectorAddress+2] - xchg AL, AH - mov word [PacketCommand+2], AX - mov AX, word [CDSectorAddress] - xchg AL, AH - mov word [PacketCommand+4], AX -; mov eax,[CDSectorAddress] -; mov [PacketCommand+2],eax + mov ax, word [CDSectorAddress+2] + xchg al, ah + mov word [PacketCommand+2], ax + mov ax, word [CDSectorAddress] + xchg al, ah + mov word [PacketCommand+4], ax ; Задать количество считываемых секторов mov [PacketCommand+8], byte 1 -; Задать считывание данных в полном объеме -; mov [PacketCommand+9],byte 0xF8 ; Подать команду call SendPacketDatCommand pop ecx -; ret -; cmp [DevErrorCode],0 test eax, eax jz @@End_4 or ecx, ecx ;{SPraid.simba} (for cd load) jz @@End_4 + dec ecx cmp [timer_ticks_enable], 0 jne @f + mov eax, NoTickWaitTime +;-------------------------------------- +align 4 .wait: dec eax -; test eax,eax jz @@NextRetr + jmp .wait +;-------------------------------------- +align 4 @@: -; Задержка на 2,5 секунды -; mov EAX,[timer_ticks] -; add EAX,50 ;250 -;@@Wait: -; call change_task -; cmp EAX,[timer_ticks] -; ja @@Wait loop @@NextRetr +;-------------------------------------- @@End_4: mov dword [DevErrorCode], eax popad ret - - +;----------------------------------------------------------------------------- ; Универсальные процедуры, обеспечивающие выполнение ; пакетных команд в режиме PIO - ; Максимально допустимое время ожидания реакции ; устройства на пакетную команду (в тиках) - +;----------------------------------------------------------------------------- MaxCDWaitTime equ 1000 ;200 ;10 секунд uglobal ; Область памяти для формирования пакетной команды PacketCommand: rb 12 ;DB 12 DUP (?) -; Область памяти для приема данных от дисковода -;CDDataBuf DB 4096 DUP (0) -; Размер принимаемого блока данных в байтах -;CDBlockSize DW ? ; Адрес считываемого сектора данных -CDSectorAddress: - DD ? +CDSectorAddress: dd ? ; Время начала очередной операции с диском -TickCounter_1 DD 0 +TickCounter_1 dd 0 ; Время начала ожидания готовности устройства -WURStartTime DD 0 +WURStartTime dd 0 ; указатель буфера для считывания CDDataBuf_pointer dd 0 endg +;----------------------------------------------------------------------------- ;**************************************************** ;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * ;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ * @@ -200,7 +188,6 @@ endg ;**************************************************** SendPacketDatCommand: xor eax, eax -; mov byte [DevErrorCode],al ; Задать режим CHS mov byte [ATAAddressMode], al ; Послать ATA-команду передачи пакетной команды @@ -209,125 +196,134 @@ SendPacketDatCommand: mov byte [ATASectorNumber], al ; Загрузить размер передаваемого блока mov [ATAHead], al -; mov AX,[CDBlockSize] mov [ATACylinder], CDBlockSize - mov [ATACommand], 0A0h + mov [ATACommand], 0xA0 call SendCommandToHDD_1 test eax, eax -; cmp [DevErrorCode],0 ;проверить код ошибки jnz @@End_8 ;закончить, сохранив код ошибки - ; Ожидание готовности дисковода к приему ; пакетной команды - mov DX, [ATABasePortAddr] - add DX, 7 ;порт 1х7h + mov dx, [ATABasePortAddr] + add dx, 7 ;порт 1х7h mov ecx, NoTickWaitTime +;-------------------------------------- +align 4 @@WaitDevice0: cmp [timer_ticks_enable], 0 jne @f + dec ecx -; test ecx,ecx jz @@Err1_1 + jmp .test +;-------------------------------------- +align 4 @@: call change_task ; Проверить время выполнения команды - mov EAX, [timer_ticks] - sub EAX, [TickCounter_1] - cmp EAX, BSYWaitTime + mov eax, [timer_ticks] + sub eax, [TickCounter_1] + cmp eax, BSYWaitTime ja @@Err1_1 ;ошибка тайм-аута ; Проверить готовность +;-------------------------------------- +align 4 .test: - in AL, DX - test AL, 80h ;состояние сигнала BSY + in al, dx + test al, 0x80 ;состояние сигнала BSY jnz @@WaitDevice0 - test AL, 1 ;состояние сигнала ERR + + test al, 1 ;состояние сигнала ERR jnz @@Err6 - test AL, 08h ;состояние сигнала DRQ + + test al, 0x8 ;состояние сигнала DRQ jz @@WaitDevice0 ; Послать пакетную команду cli - mov DX, [ATABasePortAddr] - mov AX, [PacketCommand] - out DX, AX - mov AX, [PacketCommand+2] - out DX, AX - mov AX, [PacketCommand+4] - out DX, AX - mov AX, [PacketCommand+6] - out DX, AX - mov AX, [PacketCommand+8] - out DX, AX - mov AX, [PacketCommand+10] - out DX, AX + mov dx, [ATABasePortAddr] + mov ax, [PacketCommand] + out dx, ax + mov ax, [PacketCommand+2] + out dx, ax + mov ax, [PacketCommand+4] + out dx, ax + mov ax, [PacketCommand+6] + out dx, ax + mov ax, [PacketCommand+8] + out dx, ax + mov ax, [PacketCommand+10] + out dx, ax sti ; Ожидание готовности данных - mov DX, [ATABasePortAddr] - add DX, 7 ;порт 1х7h + mov dx, [ATABasePortAddr] + add dx, 7 ;порт 1х7h mov ecx, NoTickWaitTime +;-------------------------------------- +align 4 @@WaitDevice1: cmp [timer_ticks_enable], 0 jne @f + dec ecx -; test ecx,ecx jz @@Err1_1 + jmp .test_1 +;-------------------------------------- +align 4 @@: call change_task ; Проверить время выполнения команды - mov EAX, [timer_ticks] - sub EAX, [TickCounter_1] - cmp EAX, MaxCDWaitTime + mov eax, [timer_ticks] + sub eax, [TickCounter_1] + cmp eax, MaxCDWaitTime ja @@Err1_1 ;ошибка тайм-аута ; Проверить готовность +;-------------------------------------- +align 4 .test_1: - in AL, DX - test AL, 80h ;состояние сигнала BSY + in al, dx + test al, 0x80 ;состояние сигнала BSY jnz @@WaitDevice1 - test AL, 1 ;состояние сигнала ERR + + test al, 1 ;состояние сигнала ERR jnz @@Err6_temp - test AL, 08h ;состояние сигнала DRQ + + test al, 0x8 ;состояние сигнала DRQ jz @@WaitDevice1 ; Принять блок данных от контроллера - mov EDI, [CDDataBuf_pointer];0x7000 ;CDDataBuf + mov edi, [CDDataBuf_pointer] ; Загрузить адрес регистра данных контроллера - mov DX, [ATABasePortAddr];порт 1x0h + mov dx, [ATABasePortAddr] ; Загрузить в счетчик размер блока в байтах xor ecx, ecx - mov CX, CDBlockSize + mov cx, CDBlockSize ; Вычислить размер блока в 16-разрядных словах - shr CX, 1;разделить размер блока на 2 + shr cx, 1 ;разделить размер блока на 2 ; Принять блок данных cli cld rep insw sti +;-------------------------------------- ; Успешное завершение приема данных @@End_8: xor eax, eax ret - +;-------------------------------------- ; Записать код ошибки @@Err1_1: xor eax, eax inc eax ret -; mov [DevErrorCode],1 -; ret +;-------------------------------------- @@Err6_temp: mov eax, 7 ret -; mov [DevErrorCode],7 -; ret +;-------------------------------------- @@Err6: mov eax, 6 ret -; mov [DevErrorCode],6 -;@@End_8: -; ret - - - +;----------------------------------------------------------------------------- ;*********************************************** ;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * ;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ * @@ -340,7 +336,6 @@ SendPacketDatCommand: SendPacketNoDatCommand: pushad xor eax, eax -; mov byte [DevErrorCode],al ; Задать режим CHS mov byte [ATAAddressMode], al ; Послать ATA-команду передачи пакетной команды @@ -349,82 +344,93 @@ SendPacketNoDatCommand: mov byte [ATASectorNumber], al mov word [ATACylinder], ax mov byte [ATAHead], al - mov [ATACommand], 0A0h + mov [ATACommand], 0xA0 call SendCommandToHDD_1 -; cmp [DevErrorCode],0 ;проверить код ошибки test eax, eax jnz @@End_9 ;закончить, сохранив код ошибки ; Ожидание готовности дисковода к приему ; пакетной команды - mov DX, [ATABasePortAddr] - add DX, 7 ;порт 1х7h + mov dx, [ATABasePortAddr] + add dx, 7 ;порт 1х7h +;-------------------------------------- +align 4 @@WaitDevice0_1: call change_task ; Проверить время ожидания - mov EAX, [timer_ticks] - sub EAX, [TickCounter_1] - cmp EAX, BSYWaitTime + mov eax, [timer_ticks] + sub eax, [TickCounter_1] + cmp eax, BSYWaitTime ja @@Err1_3 ;ошибка тайм-аута ; Проверить готовность - in AL, DX - test AL, 80h ;состояние сигнала BSY + in al, dx + test al, 0x80 ;состояние сигнала BSY jnz @@WaitDevice0_1 - test AL, 1 ;состояние сигнала ERR + + test al, 1 ;состояние сигнала ERR jnz @@Err6_1 - test AL, 08h ;состояние сигнала DRQ + + test al, 0x8 ;состояние сигнала DRQ jz @@WaitDevice0_1 ; Послать пакетную команду ; cli - mov DX, [ATABasePortAddr] - mov AX, word [PacketCommand] - out DX, AX - mov AX, word [PacketCommand+2] - out DX, AX - mov AX, word [PacketCommand+4] - out DX, AX - mov AX, word [PacketCommand+6] - out DX, AX - mov AX, word [PacketCommand+8] - out DX, AX - mov AX, word [PacketCommand+10] - out DX, AX + mov dx, [ATABasePortAddr] + mov ax, word [PacketCommand] + out dx, ax + mov ax, word [PacketCommand+2] + out dx, ax + mov ax, word [PacketCommand+4] + out dx, ax + mov ax, word [PacketCommand+6] + out dx, ax + mov ax, word [PacketCommand+8] + out dx, ax + mov ax, word [PacketCommand+10] + out dx, ax ; sti cmp [ignore_CD_eject_wait], 1 je @@clear_DEC ; Ожидание подтверждения приема команды - mov DX, [ATABasePortAddr] - add DX, 7 ;порт 1х7h + mov dx, [ATABasePortAddr] + add dx, 7 ;порт 1х7h +;-------------------------------------- +align 4 @@WaitDevice1_1: call change_task ; Проверить время выполнения команды - mov EAX, [timer_ticks] - sub EAX, [TickCounter_1] - cmp EAX, MaxCDWaitTime + mov eax, [timer_ticks] + sub eax, [TickCounter_1] + cmp eax, MaxCDWaitTime ja @@Err1_3 ;ошибка тайм-аута ; Ожидать освобождения устройства - in AL, DX - test AL, 80h ;состояние сигнала BSY + in al, dx + test al, 0x80 ;состояние сигнала BSY jnz @@WaitDevice1_1 - test AL, 1 ;состояние сигнала ERR + + test al, 1 ;состояние сигнала ERR jnz @@Err6_1 - test AL, 40h ;состояние сигнала DRDY + + test al, 0x40 ;состояние сигнала DRDY jz @@WaitDevice1_1 +;-------------------------------------- @@clear_DEC: and [DevErrorCode], 0 popad ret +;-------------------------------------- ; Записать код ошибки @@Err1_3: xor eax, eax inc eax jmp @@End_9 +;-------------------------------------- @@Err6_1: mov eax, 6 +;-------------------------------------- @@End_9: mov [DevErrorCode], eax popad ret - +;----------------------------------------------------------------------------- ;**************************************************** ;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * ;* Входные параметры передаются через глобальные * @@ -445,127 +451,135 @@ SendPacketNoDatCommand: ;* возвращен код ошибки в eax * ;**************************************************** SendCommandToHDD_1: -; pushad -; mov [DevErrorCode],0 not need ; Проверить значение кода режима cmp [ATAAddressMode], 1 ja @@Err2_4 ; Проверить корректность номера канала - mov BX, [ChannelNumber] - cmp BX, 1 + mov bx, [ChannelNumber] + cmp bx, 1 jb @@Err3_4 - cmp BX, 2 + + cmp bx, 2 ja @@Err3_4 ; Установить базовый адрес - dec BX - shl BX, 1 + dec bx + shl ebx, 2 movzx ebx, bx - mov AX, [ebx+StandardATABases] - mov [ATABasePortAddr], AX + mov eax, [cdpos] + dec eax + shr eax, 2 + imul eax, sizeof.IDE_DATA + add eax, IDE_controller_1 + add eax, ebx + mov ax, [eax+IDE_DATA.BAR0_val] + 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_4 - shl AL, 4 - or AL, 10100000b - out DX, AL + + shl al, 4 + or al, 10100000b + out dx, al ; Ожидать, пока диск не будет готов - inc DX + inc dx mov eax, [timer_ticks] mov [TickCounter_1], eax mov ecx, NoTickWaitTime +;-------------------------------------- +align 4 @@WaitHDReady_2: cmp [timer_ticks_enable], 0 jne @f + dec ecx -; test ecx,ecx jz @@Err1_4 + jmp .test +;-------------------------------------- +align 4 @@: call change_task ; Проверить время ожидания mov eax, [timer_ticks] sub eax, [TickCounter_1] - cmp eax, BSYWaitTime;300 ;ожидать 3 сек. + cmp eax, BSYWaitTime ;300 ;ожидать 3 сек. ja @@Err1_4 ;ошибка тайм-аута - ; Прочитать регистр состояния +;-------------------------------------- +align 4 .test: - in AL, DX + in al, dx ; Прочитать регистр состояния ; Проверить состояние сигнала BSY - test AL, 80h + test al, 0x80 jnz @@WaitHDReady_2 ; Проверить состояние сигнала DRQ - test AL, 08h + test al, 0x8 jnz @@WaitHDReady_2 - ; Загрузить команду в регистры контроллера 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_4 - 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 +;-------------------------------------- @@End_10: xor eax, eax ret +;-------------------------------------- ; Записать код ошибки @@Err1_4: xor eax, eax inc eax -; mov [DevErrorCode],1 ret +;-------------------------------------- @@Err2_4: mov eax, 2 -; mov [DevErrorCode],2 ret +;-------------------------------------- @@Err3_4: mov eax, 3 -; mov [DevErrorCode],3 ret +;-------------------------------------- @@Err4_4: mov eax, 4 -; mov [DevErrorCode],4 ret +;-------------------------------------- @@Err5_4: mov eax, 5 -; mov [DevErrorCode],5 -; Завершение работы программы ret -; sti -; popad - +;----------------------------------------------------------------------------- ;************************************************* ;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ * ;* Входные параметры передаются через глобальные * @@ -576,42 +590,50 @@ SendCommandToHDD_1: WaitUnitReady: pusha ; Запомнить время начала операции - mov EAX, [timer_ticks] - mov [WURStartTime], EAX + mov eax, [timer_ticks] + mov [WURStartTime], eax ; Очистить буфер пакетной команды call clear_packet_buffer ; Сформировать команду TEST UNIT READY - mov [PacketCommand], word 00h + mov [PacketCommand], word 0 ; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА mov ecx, NoTickWaitTime +;-------------------------------------- +align 4 @@SendCommand: ; Подать команду проверки готовности call SendPacketNoDatCommand cmp [timer_ticks_enable], 0 jne @f + cmp [DevErrorCode], 0 je @@End_11 + dec ecx -; cmp ecx,0 jz .Error + jmp @@SendCommand +;-------------------------------------- +align 4 @@: call change_task ; Проверить код ошибки cmp [DevErrorCode], 0 je @@End_11 ; Проверить время ожидания готовности - mov EAX, [timer_ticks] - sub EAX, [WURStartTime] - cmp EAX, MaxCDWaitTime + mov eax, [timer_ticks] + sub eax, [WURStartTime] + cmp eax, MaxCDWaitTime jb @@SendCommand +;-------------------------------------- .Error: ; Ошибка тайм-аута mov [DevErrorCode], 1 +;-------------------------------------- @@End_11: popa ret - +;----------------------------------------------------------------------------- ;************************************************* ;* ЗАПРЕТИТЬ СМЕНУ ДИСКА * ;* Входные параметры передаются через глобальные * @@ -635,7 +657,7 @@ prevent_medium_removal: mov [eax], byte 1 popa ret - +;----------------------------------------------------------------------------- ;************************************************* ;* РАЗРЕШИТЬ СМЕНУ ДИСКА * ;* Входные параметры передаются через глобальные * @@ -650,7 +672,7 @@ allow_medium_removal: ; Задать код команды mov [PacketCommand], byte 0x1E ; Задать код запрета - mov [PacketCommand+4], byte 00b + mov [PacketCommand+4], byte 0 ; Подать команду call SendPacketNoDatCommand mov eax, ATAPI_IDE0_lock @@ -659,7 +681,7 @@ allow_medium_removal: mov [eax], byte 0 popa ret - +;----------------------------------------------------------------------------- ;************************************************* ;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД * ;* Входные параметры передаются через глобальные * @@ -673,14 +695,14 @@ LoadMedium: call clear_packet_buffer ; Сформировать команду START/STOP UNIT ; Задать код команды - mov [PacketCommand], word 1Bh + mov [PacketCommand], word 0x1B ; Задать операцию загрузки носителя mov [PacketCommand+4], word 00000011b ; Подать команду call SendPacketNoDatCommand popa ret - +;----------------------------------------------------------------------------- ;************************************************* ;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА * ;* Входные параметры передаются через глобальные * @@ -694,14 +716,14 @@ EjectMedium: call clear_packet_buffer ; Сформировать команду START/STOP UNIT ; Задать код команды - mov [PacketCommand], word 1Bh + mov [PacketCommand], word 0x1B ; Задать операцию извлечения носителя mov [PacketCommand+4], word 00000010b ; Подать команду call SendPacketNoDatCommand popa ret - +;----------------------------------------------------------------------------- ;************************************************* ;* Проверить событие нажатия кнопки извлечения * ;* диска * @@ -715,15 +737,16 @@ proc check_ATAPI_device_event_has_work? sub eax, [timer_ATAPI_check] cmp eax, 100 jb .no -.yes: + xor eax, eax inc eax ret +;-------------------------------------- .no: xor eax, eax ret endp - +;----------------------------------------------------------------------------- align 4 check_ATAPI_device_event: pusha @@ -731,43 +754,96 @@ check_ATAPI_device_event: sub eax, [timer_ATAPI_check] cmp eax, 100 jb .end_1 + + pushfd mov al, [DRIVE_DATA+1] and al, 11b cmp al, 10b jz .ide3 +;-------------------------------------- .ide2_1: mov al, [DRIVE_DATA+1] and al, 1100b cmp al, 1000b jz .ide2 +;-------------------------------------- .ide1_1: mov al, [DRIVE_DATA+1] and al, 110000b cmp al, 100000b jz .ide1 +;-------------------------------------- .ide0_1: mov al, [DRIVE_DATA+1] and al, 11000000b cmp al, 10000000b jz .ide0 +;-------------------------------------- +.ide7_1: + mov al, [DRIVE_DATA+6] + and al, 11b + cmp al, 10b + jz .ide7 +;-------------------------------------- +.ide6_1: + mov al, [DRIVE_DATA+6] + and al, 1100b + cmp al, 1000b + jz .ide6 +;-------------------------------------- +.ide5_1: + mov al, [DRIVE_DATA+6] + and al, 110000b + cmp al, 100000b + jz .ide5 +;-------------------------------------- +.ide4_1: + mov al, [DRIVE_DATA+6] + and al, 11000000b + cmp al, 10000000b + jz .ide4 +;-------------------------------------- +.ide11_1: + mov al, [DRIVE_DATA+11] + and al, 11b + cmp al, 10b + jz .ide11 +;-------------------------------------- +.ide10_1: + mov al, [DRIVE_DATA+11] + and al, 1100b + cmp al, 1000b + jz .ide10 +;-------------------------------------- +.ide9_1: + mov al, [DRIVE_DATA+11] + and al, 110000b + cmp al, 100000b + jz .ide9 +;-------------------------------------- +.ide8_1: + mov al, [DRIVE_DATA+11] + and al, 11000000b + cmp al, 10000000b + jz .ide8 +;-------------------------------------- .end: - - sti + popfd mov eax, [timer_ticks] mov [timer_ATAPI_check], eax +;-------------------------------------- .end_1: popa ret - +;----------------------------------------------------------------------------- .ide3: cli cmp [ATAPI_IDE3_lock], 1 jne .ide2_1 - cmp [IDE_Channel_2], 0 - jne .ide1_1 + cmp [cd_status], 0 jne .end - mov [IDE_Channel_2], 1 + mov ecx, ide_channel2_mutex call mutex_lock call reserve_ok2 @@ -776,23 +852,22 @@ check_ATAPI_device_event: mov [cdpos], 4 call GetEvent_StatusNotification cmp [CDDataBuf+4], byte 1 - je .eject_ide3 - call syscall_cdaudio.free - jmp .ide2_1 -.eject_ide3: - call .eject - call syscall_cdaudio.free - jmp .ide2_1 + jne @f + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide2_1 +;----------------------------------------------------------------------------- .ide2: cli cmp [ATAPI_IDE2_lock], 1 jne .ide1_1 - cmp [IDE_Channel_2], 0 - jne .ide1_1 + cmp [cd_status], 0 jne .end - mov [IDE_Channel_2], 1 + mov ecx, ide_channel2_mutex call mutex_lock call reserve_ok2 @@ -801,23 +876,22 @@ check_ATAPI_device_event: mov [cdpos], 3 call GetEvent_StatusNotification cmp [CDDataBuf+4], byte 1 - je .eject_ide2 - call syscall_cdaudio.free - jmp .ide1_1 -.eject_ide2: - call .eject - call syscall_cdaudio.free - jmp .ide1_1 + jne @f + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide1_1 +;----------------------------------------------------------------------------- .ide1: cli cmp [ATAPI_IDE1_lock], 1 jne .ide0_1 - cmp [IDE_Channel_1], 0 - jne .end + cmp [cd_status], 0 jne .end - mov [IDE_Channel_1], 1 + mov ecx, ide_channel1_mutex call mutex_lock call reserve_ok2 @@ -826,23 +900,22 @@ check_ATAPI_device_event: mov [cdpos], 2 call GetEvent_StatusNotification cmp [CDDataBuf+4], byte 1 - je .eject_ide1 - call syscall_cdaudio.free - jmp .ide0_1 -.eject_ide1: - call .eject - call syscall_cdaudio.free - jmp .ide0_1 + jne @f + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide0_1 +;----------------------------------------------------------------------------- .ide0: cli cmp [ATAPI_IDE0_lock], 1 - jne .end - cmp [IDE_Channel_1], 0 - jne .end + jne .ide7_1 + cmp [cd_status], 0 jne .end - mov [IDE_Channel_1], 1 + mov ecx, ide_channel1_mutex call mutex_lock call reserve_ok2 @@ -851,14 +924,206 @@ check_ATAPI_device_event: mov [cdpos], 1 call GetEvent_StatusNotification cmp [CDDataBuf+4], byte 1 - je .eject_ide0 - call syscall_cdaudio.free - jmp .end -.eject_ide0: - call .eject - call syscall_cdaudio.free - jmp .end + jne @f + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide7_1 +;----------------------------------------------------------------------------- +.ide7: + cli + cmp [ATAPI_IDE7_lock], 1 + jne .ide6_1 + + cmp [cd_status], 0 + jne .end + + mov ecx, ide_channel4_mutex + call mutex_lock + call reserve_ok2 + mov [ChannelNumber], 2 + mov [DiskNumber], 1 + mov [cdpos], 8 + call GetEvent_StatusNotification + cmp [CDDataBuf+4], byte 1 + jne @f + + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide6_1 +;----------------------------------------------------------------------------- +.ide6: + cli + cmp [ATAPI_IDE6_lock], 1 + jne .ide5_1 + + cmp [cd_status], 0 + jne .end + + mov ecx, ide_channel4_mutex + call mutex_lock + call reserve_ok2 + mov [ChannelNumber], 2 + mov [DiskNumber], 0 + mov [cdpos], 7 + call GetEvent_StatusNotification + cmp [CDDataBuf+4], byte 1 + jne @f + + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide5_1 +;----------------------------------------------------------------------------- +.ide5: + cli + cmp [ATAPI_IDE5_lock], 1 + jne .ide4_1 + + cmp [cd_status], 0 + jne .end + + mov ecx, ide_channel3_mutex + call mutex_lock + call reserve_ok2 + mov [ChannelNumber], 1 + mov [DiskNumber], 1 + mov [cdpos], 6 + call GetEvent_StatusNotification + cmp [CDDataBuf+4], byte 1 + jne @f + + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide4_1 +;----------------------------------------------------------------------------- +.ide4: + cli + cmp [ATAPI_IDE4_lock], 1 + jne .ide11_1 + + cmp [cd_status], 0 + jne .end + + mov ecx, ide_channel3_mutex + call mutex_lock + call reserve_ok2 + mov [ChannelNumber], 1 + mov [DiskNumber], 0 + mov [cdpos], 5 + call GetEvent_StatusNotification + cmp [CDDataBuf+4], byte 1 + jne @f + + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide11_1 +;----------------------------------------------------------------------------- +.ide11: + cli + cmp [ATAPI_IDE11_lock], 1 + jne .ide10_1 + + cmp [cd_status], 0 + jne .end + + mov ecx, ide_channel6_mutex + call mutex_lock + call reserve_ok2 + mov [ChannelNumber], 2 + mov [DiskNumber], 1 + mov [cdpos], 12 + call GetEvent_StatusNotification + cmp [CDDataBuf+4], byte 1 + jne @f + + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide10_1 +;----------------------------------------------------------------------------- +.ide10: + cli + cmp [ATAPI_IDE10_lock], 1 + jne .ide9_1 + + cmp [cd_status], 0 + jne .end + + mov ecx, ide_channel6_mutex + call mutex_lock + call reserve_ok2 + mov [ChannelNumber], 2 + mov [DiskNumber], 0 + mov [cdpos], 11 + call GetEvent_StatusNotification + cmp [CDDataBuf+4], byte 1 + jne @f + + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide9_1 +;----------------------------------------------------------------------------- +.ide9: + cli + cmp [ATAPI_IDE9_lock], 1 + jne .ide8_1 + + cmp [cd_status], 0 + jne .end + + mov ecx, ide_channel5_mutex + call mutex_lock + call reserve_ok2 + mov [ChannelNumber], 1 + mov [DiskNumber], 1 + mov [cdpos], 10 + call GetEvent_StatusNotification + cmp [CDDataBuf+4], byte 1 + jne @f + + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .ide8_1 +;----------------------------------------------------------------------------- +.ide8: + cli + cmp [ATAPI_IDE8_lock], 1 + jne .end + + cmp [cd_status], 0 + jne .end + + mov ecx, ide_channel5_mutex + call mutex_lock + call reserve_ok2 + mov [ChannelNumber], 1 + mov [DiskNumber], 0 + mov [cdpos], 9 + call GetEvent_StatusNotification + cmp [CDDataBuf+4], byte 1 + jne @f + + call .eject +;-------------------------------------- +@@: + call syscall_cdaudio.free + jmp .end +;----------------------------------------------------------------------------- .eject: call clear_CD_cache call allow_medium_removal @@ -866,14 +1131,24 @@ check_ATAPI_device_event: call EjectMedium mov [ignore_CD_eject_wait], 0 ret +;----------------------------------------------------------------------------- iglobal timer_ATAPI_check dd 0 ATAPI_IDE0_lock db 0 ATAPI_IDE1_lock db 0 ATAPI_IDE2_lock db 0 ATAPI_IDE3_lock db 0 +ATAPI_IDE4_lock db 0 +ATAPI_IDE5_lock db 0 +ATAPI_IDE6_lock db 0 +ATAPI_IDE7_lock db 0 +ATAPI_IDE8_lock db 0 +ATAPI_IDE9_lock db 0 +ATAPI_IDE10_lock db 0 +ATAPI_IDE11_lock db 0 ignore_CD_eject_wait db 0 endg +;----------------------------------------------------------------------------- ;************************************************* ;* Получить сообщение о событии или состоянии * ;* устройства * @@ -899,7 +1174,7 @@ GetEvent_StatusNotification: call SendPacketDatCommand popa ret - +;----------------------------------------------------------------------------- ;************************************************* ; прочитать информацию из TOC ;* Входные параметры передаются через глобальные * @@ -924,7 +1199,7 @@ Read_TOC: call SendPacketDatCommand popa ret - +;----------------------------------------------------------------------------- ;************************************************* ;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ * ;* Входные параметры передаются через глобальные * @@ -944,10 +1219,11 @@ Read_TOC: ; call SendPacketDatCommand ; popa ; ret - +;----------------------------------------------------------------------------- clear_packet_buffer: ; Очистить буфер пакетной команды and [PacketCommand], dword 0 and [PacketCommand+4], dword 0 and [PacketCommand+8], dword 0 ret +;----------------------------------------------------------------------------- diff --git a/kernel/branches/Kolibri-acpi/blkdev/disk.inc b/kernel/branches/Kolibri-acpi/blkdev/disk.inc index 64379e9195..a1dc94bda6 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/disk.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/disk.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc b/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc index c2f179e6f8..f33df99389 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc @@ -1,12 +1,521 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; 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: 3742 $ +; Read/write functions try to do large operations, +; it is significantly faster than several small operations. +; This requires large buffers. +; We can't use input/output buffers directly - they can be controlled +; by user-mode application, so they can be modified between the operation +; and copying to/from cache, giving invalid data in cache. +; It is unclear how to use cache directly, currently cache items are +; allocated/freed sector-wise, so items for sequential sectors can be +; scattered over all the cache. +; So read/write functions allocate a temporary buffer which is +; 1) not greater than half of free memory and +; 2) not greater than the following constant. +CACHE_MAX_ALLOC_SIZE = 4 shl 20 + +; Legacy interface for filesystems fs_{read,write}32_{sys,app} +; gives only one sector for FS. However, per-sector reading is inefficient, +; so internally fs_read32_{sys,app} reads to the cache several sequential +; sectors, hoping that they will be useful. +; Total number of sectors is given by the following constant. +CACHE_LEGACY_READ_SIZE = 16 + +; This structure describes one item in the cache. +struct CACHE_ITEM +SectorLo dd ? ; low 32 bits of sector +SectorHi dd ? ; high 32 bits of sector +Status dd ? ; one of CACHE_ITEM_* +ends + +; Possible values for CACHE_ITEM_* +CACHE_ITEM_EMPTY = 0 +CACHE_ITEM_COPY = 1 +CACHE_ITEM_MODIFIED = 2 + +; Read several sequential sectors using cache #1. +; in: edx:eax = start sector, relative to start of partition +; in: ecx = number of sectors to read +; in: ebx -> buffer +; in: ebp -> PARTITION +; out: eax = error code, 0 = ok +; out: ecx = number of sectors that were read +fs_read64_sys: +; Save ebx, set ebx to SysCache and let the common part do its work. + push ebx ebx + mov ebx, [ebp+PARTITION.Disk] + add ebx, DISK.SysCache + jmp fs_read64_common + +; Read several sequential sectors using cache #2. +; in: edx:eax = start sector, relative to start of partition +; in: ecx = number of sectors to read +; in: edi -> buffer +; in: ebp -> PARTITION +; out: eax = error code, 0 = ok +; out: ecx = number of sectors that were read +fs_read64_app: +; Save ebx, set ebx to AppCache and let the common part do its work. + push ebx ebx + mov ebx, [ebp+PARTITION.Disk] + add ebx, DISK.AppCache + +; Common part of fs_read64_{app,sys}: +; read several sequential sectors using the given cache. +fs_read64_common: +; 1. Setup stack frame. + push esi edi ; save used registers to be stdcall + push 0 ; initialize .error_code + push ebx edx eax ecx ecx ; initialize stack variables +virtual at esp +.local_vars: +.num_sectors_orig dd ? +; Number of sectors that should be read. Used to generate output value of ecx. +.num_sectors dd ? +; Number of sectors that remain to be read. Decreases from .num_sectors_orig to 0. +.sector_lo dd ? ; low 32 bits of the current sector +.sector_hi dd ? ; high 32 bits of the current sector +.cache dd ? ; pointer to DISKCACHE +.error_code dd ? ; current status +.local_vars_size = $ - .local_vars +.saved_regs rd 2 +.buffer dd ? ; filled by fs_read64_{sys,app} +end virtual +; 2. Validate parameters against partition length: +; immediately return error if edx:eax are beyond partition end, +; decrease .num_sectors and .num_sectors_orig, if needed, +; so that the entire operation fits in the partition limits. + mov eax, dword [ebp+PARTITION.Length] + mov edx, dword [ebp+PARTITION.Length+4] + sub eax, [.sector_lo] + sbb edx, [.sector_hi] + jb .end_of_media + jnz .no_end_of_media + cmp ecx, eax + jbe .no_end_of_media +; If .num_sectors got decreased, set status to DISK_STATUS_END_OF_MEDIA; +; if all subsequent operations would be successful, this would become the final +; status, otherwise this would be rewritten by failed operation. + mov [.num_sectors], eax + mov [.num_sectors_orig], eax + mov [.error_code], DISK_STATUS_END_OF_MEDIA +.no_end_of_media: +; 3. If number of sectors to read is zero, either because zero-sectors operation +; was requested or because it got decreased to zero due to partition limits, +; just return the current status. + cmp [.num_sectors], 0 + jz .return +; 4. Shift sector from partition-relative to absolute. + mov eax, dword [ebp+PARTITION.FirstSector] + mov edx, dword [ebp+PARTITION.FirstSector+4] + add [.sector_lo], eax + adc [.sector_hi], edx +; 5. If the cache is disabled, pass the request directly to the driver. + cmp [ebx+DISKCACHE.pointer], 0 + jz .nocache +; 6. Look for sectors in the cache, sequentially from the beginning. +; Stop at the first sector that is not in the cache +; or when all sectors were read from the cache. +; 6a. Acquire the lock. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_lock +.lookup_in_cache_loop: +; 6b. For each sector, call the lookup function without adding to the cache. + mov eax, [.sector_lo] + mov edx, [.sector_hi] + call cache_lookup_read +; 6c. If it has failed, the sector is not in cache; +; release the lock and go to 7. + jc .not_found_in_cache +; The sector is found in cache. +; 6d. Copy data for the caller, advance [.buffer]. + mov esi, edi + mov edi, [.buffer] + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 + rep movsd + mov [.buffer], edi +; 6e. Advance the sector. + add [.sector_lo], 1 + adc [.sector_hi], 0 +; 6f. Decrement number of sectors left. +; If all sectors were read, release the lock and return. + dec [.num_sectors] + jnz .lookup_in_cache_loop +; Release the lock acquired at 6a. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_unlock +.return: + mov eax, [.error_code] + mov ecx, [.num_sectors_orig] + sub ecx, [.num_sectors] +.nothing: + add esp, .local_vars_size + pop edi esi ebx ebx ; restore used registers to be stdcall + ret +.not_found_in_cache: +; Release the lock acquired at 6a. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_unlock +; The current sector is not present in the cache. +; Ask the driver to read all requested not-yet-read sectors, +; put results in the cache. +; Also, see the comment before the definition of CACHE_MAX_ALLOC_SIZE. +; 7. Allocate buffer for operations. +; Normally, create buffer that is sufficient for all remaining data. +; However, for extra-large requests make an upper limit: +; do not use more than half of the free memory +; or more than CACHE_MAX_ALLOC_SIZE bytes. + mov ecx, [ebx+DISKCACHE.sector_size_log] + mov ebx, [pg_data.pages_free] + shr ebx, 1 + jz .nomemory + cmp ebx, CACHE_MAX_ALLOC_SIZE shr 12 + jbe @f + mov ebx, CACHE_MAX_ALLOC_SIZE shr 12 +@@: + shl ebx, 12 + shr ebx, cl + jz .nomemory + cmp ebx, [.num_sectors] + jbe @f + mov ebx, [.num_sectors] +@@: + mov eax, ebx + shl eax, cl + stdcall kernel_alloc, eax +; If failed, return the appropriate error code. + test eax, eax + jz .nomemory + mov esi, eax +; Split the request to chunks that fit in the allocated buffer. +.read_loop: +; 8. Get iteration size: either size of allocated buffer in sectors +; or number of sectors left, select what is smaller. + cmp ebx, [.num_sectors] + jbe @f + mov ebx, [.num_sectors] +@@: +; 9. Create second portion of local variables. +; Note that variables here and above are esp-relative; +; it means that all addresses should be corrected when esp is changing. + push ebx esi esi + push ebx +; In particular, num_sectors is now [.num_sectors+.local_vars2_size]. +virtual at esp +.local_vars2: +.current_num_sectors dd ? ; number of sectors that were read +.current_buffer dd ? +; pointer inside .allocated_buffer that points +; to the beginning of not-processed data +.allocated_buffer dd ? ; saved in safe place +.iteration_size dd ? ; saved in safe place +.local_vars2_size = $ - .local_vars2 +end virtual +; 10. Call the driver, reading the next chunk. + push esp ; numsectors + push [.sector_hi+.local_vars2_size+4] ; startsector + push [.sector_lo+.local_vars2_size+8] ; startsector + push esi ; buffer + mov esi, [ebp+PARTITION.Disk] + mov al, DISKFUNC.read + call disk_call_driver +; If failed, save error code. + test eax, eax + jz @f + mov [.error_code+.local_vars2_size], eax +@@: +; 11. Copy data for the caller, advance .buffer. + cmp [.current_num_sectors], 0 + jz .copy_done + mov ebx, [.cache+.local_vars2_size] + mov eax, [.current_num_sectors] + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl eax, cl + mov esi, [.allocated_buffer] + mov edi, [.buffer+.local_vars2_size] + mov ecx, eax + shr ecx, 2 + rep movsd + mov [.buffer+.local_vars2_size], edi +; 12. Copy data to the cache. +; 12a. Acquire the lock. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_lock +; 12b. Prepare for the loop: create a local variable that +; stores number of sectors to be copied. + push [.current_num_sectors] +.store_to_cache: +; 12c. For each sector, call the lookup function with adding to the cache, if not yet. + mov eax, [.sector_lo+.local_vars2_size+4] + mov edx, [.sector_hi+.local_vars2_size+4] + call cache_lookup_write + test eax, eax + jnz .cache_error +; 12d. If the sector was already present in the cache as modified, +; data that were read at step 10 for this sector are obsolete, +; so rewrite data for the caller from the cache. + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + jnz .not_modified + mov esi, edi + mov edi, [.buffer+.local_vars2_size+4] + mov eax, [esp] + shl eax, cl + sub edi, eax + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 + rep movsd + add [.current_buffer+4], eax + jmp .sector_done +.not_modified: +; 12e. For each not-modified sector, +; copy data, mark the item as not-modified copy of the disk, +; advance .current_buffer and .sector_hi:.sector_lo to the next sector. + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY + mov eax, 1 + shl eax, cl + mov esi, [.current_buffer+4] + mov ecx, eax + shr ecx, 2 + rep movsd + mov [.current_buffer+4], esi +.sector_done: + add [.sector_lo+.local_vars2_size+4], 1 + adc [.sector_hi+.local_vars2_size+4], 0 +; 12f. Continue the loop 12c-12e until all sectors are read. + dec dword [esp] + jnz .store_to_cache +.cache_error: +; 12g. Restore after the loop: pop the local variable. + pop ecx +; 12h. Release the lock. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_unlock +.copy_done: +; 13. Remove portion of local variables created at step 9. + pop ecx + pop esi esi ebx +; 14. Continue iterations while number of sectors read by the driver +; is equal to number of sectors requested and there are additional sectors. + cmp ecx, ebx + jnz @f + sub [.num_sectors], ebx + jnz .read_loop +@@: +; 15. Free the buffer allocated at step 7 and return. + stdcall kernel_free, esi + jmp .return + +; Special branches: +.nomemory: +; memory allocation failed at step 7: return the corresponding error + mov [.error_code], DISK_STATUS_NO_MEMORY + jmp .return +.nocache: +; step 5, after correcting number of sectors to fit in partition limits +; and advancing partition-relative sector to absolute, +; sees that cache is disabled: pass corrected request to the driver + lea eax, [.num_sectors] + push eax ; numsectors + push [.sector_hi+4] ; startsector + push [.sector_lo+8] ; startsector + push [.buffer+12] ; buffer + mov esi, [ebp+PARTITION.Disk] + mov al, DISKFUNC.read + call disk_call_driver + test eax, eax + jnz @f + mov eax, [.error_code] +@@: + mov ecx, [.num_sectors] + jmp .nothing +.end_of_media: +; requested sector is beyond the partition end: return the corresponding error + mov [.error_code], DISK_STATUS_END_OF_MEDIA + jmp .return + +; Write several sequential sectors using cache #1. +; in: edx:eax = start sector +; in: ecx = number of sectors to write +; in: ebx -> buffer +; in: ebp -> PARTITION +; out: eax = error code, 0 = ok +; out: ecx = number of sectors that were written +fs_write64_sys: +; Save ebx, set ebx to SysCache and let the common part do its work. + push ebx + mov ebx, [ebp+PARTITION.Disk] + add ebx, DISK.SysCache + jmp fs_write64_common + +; Write several sequential sectors using cache #2. +; in: edx:eax = start sector +; in: ecx = number of sectors to write +; in: ebx -> buffer +; in: ebp -> PARTITION +; out: eax = error code, 0 = ok +; out: ecx = number of sectors that were written +fs_write64_app: +; Save ebx, set ebx to AppCache and let the common part do its work. + push ebx + mov ebx, [ebp+PARTITION.Disk] + add ebx, DISK.AppCache + +; Common part of fs_write64_{app,sys}: +; write several sequential sectors using the given cache. +fs_write64_common: +; 1. Setup stack frame. + push esi edi ; save used registers to be stdcall + push 0 ; initialize .error_code + push edx eax ecx ecx ; initialize stack variables + push [.buffer-4] ; copy [.buffer] to [.cur_buffer] + ; -4 is due to esp-relative addressing +virtual at esp +.local_vars: +.cur_buffer dd ? ; pointer to data that are currently copying +.num_sectors_orig dd ? +; Number of sectors that should be written. Used to generate output value of ecx. +.num_sectors dd ? +; Number of sectors that remain to be written. +.sector_lo dd ? ; low 32 bits of the current sector +.sector_hi dd ? ; high 32 bits of the current sector +.error_code dd ? ; current status +.local_vars_size = $ - .local_vars +.saved_regs rd 2 +.buffer dd ? ; filled by fs_write64_{sys,app} +end virtual +; 2. Validate parameters against partition length: +; immediately return error if edx:eax are beyond partition end, +; decrease .num_sectors and .num_sectors_orig, if needed, +; so that the entire operation fits in the partition limits. + mov eax, dword [ebp+PARTITION.Length] + mov edx, dword [ebp+PARTITION.Length+4] + sub eax, [.sector_lo] + sbb edx, [.sector_hi] + jb .end_of_media + jnz .no_end_of_media + cmp ecx, eax + jbe .no_end_of_media +; If .num_sectors got decreased, set status to DISK_STATUS_END_OF_MEDIA; +; if all subsequent operations would be successful, this would become the final +; status, otherwise this would be rewritten by failed operation. + mov [.num_sectors], eax + mov [.num_sectors_orig], eax + mov [.error_code], DISK_STATUS_END_OF_MEDIA +.no_end_of_media: +; 3. If number of sectors to write is zero, either because zero-sectors operation +; was requested or because it got decreased to zero due to partition limits, +; just return the current status. + cmp [.num_sectors], 0 + jz .return +; 4. Shift sector from partition-relative to absolute. + mov eax, dword [ebp+PARTITION.FirstSector] + mov edx, dword [ebp+PARTITION.FirstSector+4] + add [.sector_lo], eax + adc [.sector_hi], edx +; 5. If the cache is disabled, pass the request directly to the driver. + cmp [ebx+DISKCACHE.pointer], 0 + jz .nocache +; 6. Store sectors in the cache, sequentially from the beginning. +; 6a. Acquire the lock. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_lock +.lookup_in_cache_loop: +; 6b. For each sector, call the lookup function with adding to the cache, if not yet. + mov eax, [.sector_lo] + mov edx, [.sector_hi] + call cache_lookup_write + test eax, eax + jnz .cache_error +; 6c. For each sector, copy data, mark the item as modified and not saved, +; advance .current_buffer to the next sector. + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + mov eax, 1 + shl eax, cl + mov esi, [.cur_buffer] + mov ecx, eax + shr ecx, 2 + rep movsd + mov [.cur_buffer], esi +; 6d. Remove the sector from the other cache. +; Normally it should not be there, but prefetching could put to the app cache +; data that normally should belong to the sys cache and vice versa. +; Note: this requires that both caches must be protected by the same lock. + mov eax, [.sector_lo] + mov edx, [.sector_hi] + push ebx + sub ebx, [ebp+PARTITION.Disk] + xor ebx, DISK.SysCache xor DISK.AppCache + add ebx, [ebp+PARTITION.Disk] + call cache_lookup_read + jc @f + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY +@@: + pop ebx +; 6e. Advance .sector_hi:.sector_lo to the next sector. + add [.sector_lo], 1 + adc [.sector_hi], 0 +; 6f. Continue the loop at 6b-6e until all sectors are processed. + dec [.num_sectors] + jnz .lookup_in_cache_loop +.unlock_return: +; 6g. Release the lock and return. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_unlock +.return: + mov eax, [.error_code] + mov ecx, [.num_sectors_orig] + sub ecx, [.num_sectors] +.nothing: + add esp, .local_vars_size + pop edi esi ebx + ret + +; Special branches: +.cache_error: +; error at flushing the cache while adding sector to the cache: +; return the error from the lookup function + mov [.error_code], eax + jmp .unlock_return +.end_of_media: +; requested sector is beyond the partition end: return the corresponding error + mov eax, DISK_STATUS_END_OF_MEDIA + xor ecx, ecx + jmp .nothing +.nocache: +; step 5, after correcting number of sectors to fit in partition limits +; and advancing partition-relative sector to absolute, +; sees that cache is disabled: pass corrected request to the driver + lea eax, [.num_sectors] + push eax ; numsectors + push [.sector_hi+4] ; startsector + push [.sector_lo+8] ; startsector + push [.buffer+12] ; buffer + mov esi, [ebp+PARTITION.Disk] + mov al, DISKFUNC.write + call disk_call_driver + mov ecx, [.num_sectors] + jmp .nothing + +; Legacy. Use fs_read64_sys instead. ; This function is intended to replace the old 'hd_read' function when ; [hdd_appl_data] = 0, so its input/output parameters are the same, except ; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. @@ -14,12 +523,13 @@ $Revision: 3742 $ ; eax is relative to partition start ; out: eax = error code; 0 = ok fs_read32_sys: -; Save ecx, set ecx to SysCache and let the common part do its work. - push ecx - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.SysCache +; Save ebx, set ebx to SysCache and let the common part do its work. + push ebx + mov ebx, [ebp+PARTITION.Disk] + add ebx, DISK.SysCache jmp fs_read32_common +; Legacy. Use fs_read64_app instead. ; This function is intended to replace the old 'hd_read' function when ; [hdd_appl_data] = 1, so its input/output parameters are the same, except ; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. @@ -27,10 +537,10 @@ fs_read32_sys: ; eax is relative to partition start ; out: eax = error code; 0 = ok fs_read32_app: -; Save ecx, set ecx to AppCache and let the common part do its work. - push ecx - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.AppCache +; Save ebx, set ebx to AppCache and let the common part do its work. + push ebx + mov ebx, [ebp+PARTITION.Disk] + add ebx, DISK.AppCache ; This label is the common part of fs_read32_sys and fs_read32_app. fs_read32_common: @@ -41,119 +551,224 @@ fs_read32_common: cmp dword [ebp+PARTITION.Length], eax ja @f mov eax, DISK_STATUS_END_OF_MEDIA - pop ecx + pop ebx ret @@: ; 2. Get the absolute sector on the disk. - push edx esi + push ecx edx esi edi xor edx, edx add eax, dword [ebp+PARTITION.FirstSector] adc edx, dword [ebp+PARTITION.FirstSector+4] ; 3. If there is no cache for this disk, just pass the request to the driver. - cmp [ecx+DISKCACHE.pointer], 0 + cmp [ebx+DISKCACHE.pointer], 0 jnz .scancache push 1 push esp ; numsectors push edx ; startsector push eax ; startsector - push ebx ; buffer + pushd [esp+32]; buffer mov esi, [ebp+PARTITION.Disk] mov al, DISKFUNC.read call disk_call_driver pop ecx - pop esi edx - pop ecx + pop edi esi edx ecx + pop ebx ret .scancache: -; 4. Scan the cache. - push edi ecx ; scan cache - push edx eax + push ebx edx eax virtual at esp +.local_vars: .sector_lo dd ? .sector_hi dd ? .cache dd ? +.local_vars_size = $ - .local_vars +.saved_regs rd 4 +.buffer dd ? end virtual -; The following code is inherited from hd_read. The differences are: -; all code is protected by the cache lock; instead of static calls -; to hd_read_dma/hd_read_pio/bd_read the dynamic call to DISKFUNC.read is used; -; sector is 64-bit, not 32-bit. +; 4. Scan for the requested sector in the cache. +; If found, copy the data and return. +; 4a. Acquire the lock. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock call mutex_lock +; 4b. Call the lookup function without adding to the cache. mov eax, [.sector_lo] mov edx, [.sector_hi] - mov esi, [ecx+DISKCACHE.pointer] - mov ecx, [ecx+DISKCACHE.sad_size] - add esi, 12 - - mov edi, 1 - -.hdreadcache: - - cmp dword [esi+8], 0 ; empty - je .nohdcache - - cmp [esi], eax ; correct sector - jne .nohdcache - cmp [esi+4], edx ; correct sector - je .yeshdcache - -.nohdcache: - - add esi, 12 - inc edi - dec ecx - jnz .hdreadcache - - mov esi, [.cache] - call find_empty_slot64 ; ret in edi + call cache_lookup_read +; If not found, go to 5. + jc .not_found_in_cache +.found_in_cache: +; 4c. Copy the data. + mov esi, edi + mov edi, [.buffer] + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 + rep movsd +; 4d. Release the lock and return success. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_unlock +.return: + xor eax, eax +.return_eax: + add esp, .local_vars_size + pop edi esi edx ecx + pop ebx + ret +.not_found_in_cache: +; 5. Decide whether we need to prefetch further sectors. +; If so, advance to 6. If not, go to 13. +; Assume that devices < 3MB are floppies which are slow +; (ramdisk does not have a cache, so we don't even get here for ramdisk). +; This is a dirty hack, but the entire function is somewhat hacky. Use fs_read64*. + mov ecx, [ebp+PARTITION.Disk] + cmp dword [ecx+DISK.MediaInfo.Capacity+4], 0 + jnz @f + cmp dword [ecx+DISK.MediaInfo.Capacity], 3 shl (20-9) + jb .floppy +@@: +; We want to prefetch CACHE_LEGACY_READ_SIZE sectors. +; 6. Release the lock acquired at step 4a. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_unlock +; 7. Allocate buffer for CACHE_LEGACY_READ_SIZE sectors. + mov eax, CACHE_LEGACY_READ_SIZE + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl eax, cl + stdcall kernel_alloc, eax +; If failed, return the corresponding error code. test eax, eax - jnz .read_done + jz .nomemory +; 8. Create second portion of local variables. + push eax eax + push CACHE_LEGACY_READ_SIZE +virtual at esp +.local_vars2: +.num_sectors dd ? ; number of sectors left +.current_buffer dd ? ; pointer to data that are currently copying +.allocated_buffer dd ? ; saved at safe place +.local_vars2_size = $ - .local_vars2 +end virtual +; 9. Call the driver to read CACHE_LEGACY_READ_SIZE sectors. + push esp ; numsectors + push [.sector_hi+.local_vars2_size+4] ; startsector + push [.sector_lo+.local_vars2_size+8] ; startsector + push eax ; buffer + mov esi, [ebp+PARTITION.Disk] + mov al, DISKFUNC.read + call disk_call_driver +; Note: we're ok if at least one sector is read, +; read error somewhere after that just limits data to be put in cache. + cmp [.num_sectors], 0 + jz .read_error +; 10. Copy data for the caller. + mov esi, [.allocated_buffer] + mov edi, [.buffer+.local_vars2_size] + mov ecx, [ebx+DISKCACHE.sector_size_log] + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 + rep movsd +; 11. Store all sectors that were successfully read to the cache. +; 11a. Acquire the lock. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_lock +.store_to_cache: +; 11b. For each sector, call the lookup function with adding to the cache, if not yet. + mov eax, [.sector_lo+.local_vars2_size] + mov edx, [.sector_hi+.local_vars2_size] + call cache_lookup_write + test eax, eax + jnz .cache_error +; 11c. Ignore sectors marked as modified: for them the cache is more recent that disk data. + mov eax, 1 + shl eax, cl + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + jnz .not_modified + add [.current_buffer], eax + jmp .sector_done +.not_modified: +; 11d. For each sector, copy data, mark the item as not-modified copy of the disk, +; advance .current_buffer and .sector_hi:.sector_lo to the next sector. + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY + mov esi, [.current_buffer] + mov ecx, eax + shr ecx, 2 + rep movsd + mov [.current_buffer], esi +.sector_done: + add [.sector_lo+.local_vars2_size], 1 + adc [.sector_hi+.local_vars2_size], 0 +; 11e. Continue the loop at 11b-11d until all sectors are processed. + dec [.num_sectors] + jnz .store_to_cache +.cache_error: +; 11f. Release the lock. + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock + call mutex_unlock +.copy_done: +; 12. Remove portion of local variables created at step 8, +; free the buffer allocated at step 7 and return. + pop ecx ecx + stdcall kernel_free + jmp .return +.read_error: +; If no sectors were read, free the buffer allocated at step 7 +; and pass the error to the caller. + push eax + stdcall kernel_free, [.allocated_buffer+4] + pop eax + add esp, .local_vars2_size + jmp .return_eax +.nomemory: + mov eax, DISK_STATUS_NO_MEMORY + jmp .return_eax +.floppy: +; We don't want to prefetch anything, just read one sector. +; We are still holding the lock acquired at step 4a. +; 13. Call the lookup function adding sector to the cache. + call cache_lookup_write + test eax, eax + jnz .floppy_cache_error + push esi +; 14. Call the driver to read one sector. push 1 push esp push edx - push [.sector_lo+12] - mov ecx, [.cache+16] - mov eax, edi - shl eax, 9 - add eax, [ecx+DISKCACHE.data] - push eax + push [.sector_lo+16] + push edi mov esi, [ebp+PARTITION.Disk] mov al, DISKFUNC.read call disk_call_driver pop ecx dec ecx - jnz .read_done + jnz .floppy_read_error +; 15. Get the slot and pointer to the cache item, +; change the status to not-modified copy of the disk +; and go to 4c. + pop esi + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY + mov ecx, [ebx+DISKCACHE.sector_size_log] + jmp .found_in_cache - mov ecx, [.cache] - lea eax, [edi*3] - mov esi, [ecx+DISKCACHE.pointer] - lea esi, [eax*4+esi] - - mov eax, [.sector_lo] - mov edx, [.sector_hi] - mov [esi], eax ; sector number - mov [esi+4], edx ; sector number - mov dword [esi+8], 1; hd read - mark as same as in hd - -.yeshdcache: - - mov esi, edi - mov ecx, [.cache] - shl esi, 9 - add esi, [ecx+DISKCACHE.data] - - mov edi, ebx - mov ecx, 512/4 - rep movsd ; move data - xor eax, eax ; successful read -.read_done: - mov ecx, [.cache] +; On error at steps 13-14, release the lock +; and pass the error to the caller. +.floppy_read_error: + pop ecx +.floppy_cache_error: + mov ecx, [ebp+PARTITION.Disk] + add ecx, DISK.CacheLock push eax call mutex_unlock pop eax - add esp, 12 - pop edi esi edx ecx - ret + jmp .return_eax ; This function is intended to replace the old 'hd_write' function when ; [hdd_appl_data] = 0, so its input/output parameters are the same, except @@ -162,11 +777,13 @@ end virtual ; eax is relative to partition start ; out: eax = error code; 0 = ok fs_write32_sys: -; Save ecx, set ecx to SysCache and let the common part do its work. - push ecx - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.SysCache - jmp fs_write32_common +; Just call the advanced function. + push ecx edx + xor edx, edx + mov ecx, 1 + call fs_write64_sys + pop edx ecx + ret ; This function is intended to replace the old 'hd_write' function when ; [hdd_appl_data] = 1, so its input/output parameters are the same, except @@ -175,269 +792,431 @@ fs_write32_sys: ; eax is relative to partition start ; out: eax = error code; 0 = ok fs_write32_app: -; Save ecx, set ecx to AppCache and let the common part do its work. - push ecx - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.AppCache - -; This label is the common part of fs_read32_sys and fs_read32_app. -fs_write32_common: -; 1. Check that the required sector is inside the partition. If no, return -; DISK_STATUS_END_OF_MEDIA. - cmp dword [ebp+PARTITION.Length+4], 0 - jnz @f - cmp dword [ebp+PARTITION.Length], eax - ja @f - mov eax, DISK_STATUS_END_OF_MEDIA - pop ecx - ret -@@: - push edx esi -; 2. Get the absolute sector on the disk. +; Just call the advanced function. + push ecx edx xor edx, edx - add eax, dword [ebp+PARTITION.FirstSector] - adc edx, dword [ebp+PARTITION.FirstSector+4] -; 3. If there is no cache for this disk, just pass request to the driver. - cmp [ecx+DISKCACHE.pointer], 0 - jnz .scancache - push 1 - push esp ; numsectors - push edx ; startsector - push eax ; startsector - push ebx ; buffer - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.write - call disk_call_driver - pop ecx - pop esi edx - pop ecx + mov ecx, 1 + call fs_write64_app + pop edx ecx ret -.scancache: -; 4. Scan the cache. - push edi ecx ; scan cache - push edx eax -virtual at esp -.sector_lo dd ? -.sector_hi dd ? -.cache dd ? -end virtual -; The following code is inherited from hd_write. The differences are: -; all code is protected by the cache lock; -; sector is 64-bit, not 32-bit. - call mutex_lock - ; check if the cache already has the sector and overwrite it - mov eax, [.sector_lo] - mov edx, [.sector_hi] - mov esi, [ecx+DISKCACHE.pointer] - mov ecx, [ecx+DISKCACHE.sad_size] - add esi, 12 +; Lookup for the given sector in the given cache. +; If the sector is not present, return error. +; The caller must acquire the cache lock. +; in: edx:eax = sector +; in: ebx -> DISKCACHE structure +; out: CF set if sector is not in cache +; out: ecx = sector_size_log +; out: esi -> sector:status +; out: edi -> sector data +proc cache_lookup_read + mov esi, [ebx+DISKCACHE.pointer] + add esi, sizeof.CACHE_ITEM mov edi, 1 -.hdwritecache: - cmp dword [esi+8], 0 ; if cache slot is empty - je .not_in_cache_write +.hdreadcache: - cmp [esi], eax ; if the slot has the sector - jne .not_in_cache_write - cmp [esi+4], edx ; if the slot has the sector - je .yes_in_cache_write + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY + je .nohdcache -.not_in_cache_write: - - add esi, 12 - inc edi - dec ecx - jnz .hdwritecache - - ; sector not found in cache - ; write the block to a new location - - mov esi, [.cache] - call find_empty_slot64 ; ret in edi - test eax, eax - jne .hd_write_access_denied - - mov ecx, [.cache] - lea eax, [edi*3] - mov esi, [ecx+DISKCACHE.pointer] - lea esi, [eax*4+esi] - - mov eax, [.sector_lo] - mov edx, [.sector_hi] - mov [esi], eax ; sector number - mov [esi+4], edx ; sector number - -.yes_in_cache_write: - - mov dword [esi+8], 2 ; write - differs from hd - - shl edi, 9 - mov ecx, [.cache] - add edi, [ecx+DISKCACHE.data] - - mov esi, ebx - mov ecx, 512/4 - rep movsd ; move data - xor eax, eax ; success -.hd_write_access_denied: - mov ecx, [.cache] - push eax - call mutex_unlock - pop eax - add esp, 12 - pop edi esi edx ecx + cmp [esi+CACHE_ITEM.SectorLo], eax + jne .nohdcache + cmp [esi+CACHE_ITEM.SectorHi], edx + jne .nohdcache + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl edi, cl + add edi, [ebx+DISKCACHE.data] + clc ret -; This internal function is called from fs_read32_* and fs_write32_*. It is the -; analogue of find_empty_slot for 64-bit sectors. -find_empty_slot64: +.nohdcache: + + add esi, sizeof.CACHE_ITEM + inc edi + cmp edi, [ebx+DISKCACHE.sad_size] + jbe .hdreadcache + stc + ret +endp + +; Lookup for the given sector in the given cache. +; If the sector is not present, allocate space for it, +; possibly flushing data. +; in: edx:eax = sector +; in: ebx -> DISKCACHE structure +; in: ebp -> PARTITION structure +; out: eax = error code +; out: esi -> sector:status +; out: edi -> sector data +proc cache_lookup_write + call cache_lookup_read + jnc .return0 + push edx eax ;----------------------------------------------------------- ; find empty or read slot, flush cache if next 12.5% is used by write -; output : edi = cache slot +; output : ecx = cache slot ;----------------------------------------------------------- +; Note: the code is essentially inherited, so probably +; no analysis of efficiency were done. +; However, it works. .search_again: - mov ecx, [esi+DISKCACHE.sad_size] - mov edi, [esi+DISKCACHE.search_start] - shr ecx, 3 + mov eax, [ebx+DISKCACHE.sad_size] + mov ecx, [ebx+DISKCACHE.search_start] + shr eax, 3 + lea esi, [ecx*sizeof.CACHE_ITEM/4] + shl esi, 2 + add esi, [ebx+DISKCACHE.pointer] .search_for_empty: - inc edi - cmp edi, [esi+DISKCACHE.sad_size] + inc ecx + add esi, sizeof.CACHE_ITEM + cmp ecx, [ebx+DISKCACHE.sad_size] jbe .inside_cache - mov edi, 1 + mov ecx, 1 + mov esi, [ebx+DISKCACHE.pointer] + add esi, sizeof.CACHE_ITEM .inside_cache: - lea eax, [edi*3] - shl eax, 2 - add eax, [esi+DISKCACHE.pointer] - cmp dword [eax+8], 2 + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED jb .found_slot ; it's empty or read - dec ecx + dec eax jnz .search_for_empty stdcall write_cache64, [ebp+PARTITION.Disk] ; no empty slots found, write all test eax, eax jne .found_slot_access_denied jmp .search_again ; and start again .found_slot: - mov [esi+DISKCACHE.search_start], edi + mov [ebx+DISKCACHE.search_start], ecx + popd [esi+CACHE_ITEM.SectorLo] + popd [esi+CACHE_ITEM.SectorHi] + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY + mov edi, ecx + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl edi, cl + add edi, [ebx+DISKCACHE.data] +.return0: xor eax, eax ; success -.found_slot_access_denied: ret +.found_slot_access_denied: + add esp, 8 + ret +endp -; This function is intended to replace the old 'write_cache' function. -proc write_cache64 uses ecx edx esi edi, disk:dword -locals -cache_chain_started dd 0 -cache_chain_size dd ? -cache_chain_pos dd ? -cache_chain_ptr dd ? -endl -saved_esi_pos = 16+12 ; size of local variables + size of registers before esi -; If there is no cache for this disk, nothing to do. - cmp [esi+DISKCACHE.pointer], 0 - jz .flush -;----------------------------------------------------------- -; write all changed sectors to disk -;----------------------------------------------------------- - - ; write difference ( 2 ) from cache to DISK - mov ecx, [esi+DISKCACHE.sad_size] - mov esi, [esi+DISKCACHE.pointer] - add esi, 12 +; Flush the given cache. +; The caller must acquire the cache lock. +; in: ebx -> DISKCACHE +; in: first argument in stdcall convention -> PARTITION +proc write_cache64 +; 1. Setup stack frame. + push esi edi ; save used registers to be stdcall + sub esp, .local_vars_size ; reserve space for local vars +virtual at esp +.local_vars: +.cache_end dd ? ; item past the end of the cache +.size_left dd ? ; items left to scan +.current_ptr dd ? ; pointer to the current item +; +; Write operations are coalesced in chains, +; one chain describes a sequential interval of sectors, +; they can be sequential or scattered in the cache. +.sequential dd ? +; boolean variable, 1 if the current chain is sequential in the cache, +; 0 if additional buffer is needed to perform the operation +.chain_start_pos dd ? ; data of chain start item +.chain_start_ptr dd ? ; pointer to chain start item +.chain_size dd ? ; chain size (thanks, C.O.) +.iteration_size dd ? +; If the chain size is too large, split the operation to several iterations. +; This is size in sectors for one iterations. +.iteration_buffer dd ? ; temporary buffer for non-sequential chains +.local_vars_size = $ - .local_vars + rd 2 ; saved registers + dd ? ; return address +.disk dd ? ; first argument +end virtual +; 1. If there is no cache for this disk, nothing to do, just return zero. + cmp [ebx+DISKCACHE.pointer], 0 + jz .return0 +; 2. Prepare for the loop: initialize current pointer and .size_left, +; calculate .cache_end. + mov ecx, [ebx+DISKCACHE.sad_size] + mov [.size_left], ecx + lea ecx, [ecx*sizeof.CACHE_ITEM/4] + shl ecx, 2 + mov esi, [ebx+DISKCACHE.pointer] + add esi, sizeof.CACHE_ITEM + add ecx, esi + mov [.cache_end], ecx +; 3. Main loop: go over all items, go to 5 for every modified item. +.look: + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + jz .begin_write +.look_next: + add esi, sizeof.CACHE_ITEM + dec [.size_left] + jnz .look +; 4. Return success. +.return0: + xor eax, eax +.return: + add esp, .local_vars_size + pop edi esi ; restore used registers to be stdcall + ret 4 ; return popping one argument +.begin_write: +; We have found a modified item. +; 5. Prepare for chain finding: save the current item, initialize chain variables. + mov [.current_ptr], esi +; Initialize chain as sequential zero-length starting at the current item. + mov [.chain_start_ptr], esi + mov eax, [ebx+DISKCACHE.sad_size] + sub eax, [.size_left] + inc eax + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl eax, cl + add eax, [ebx+DISKCACHE.data] + mov [.chain_start_pos], eax + mov [.chain_size], 0 + mov [.sequential], 1 +; 6. Expand the chain backward. +; Note: the main loop in step 2 looks for items sequentially, +; so the previous item is not modified. If the previous sector +; is present in the cache, it automatically makes the chain scattered. +; 6a. Calculate sector number: one before the sector for the current item. + mov eax, [esi+CACHE_ITEM.SectorLo] + mov edx, [esi+CACHE_ITEM.SectorHi] + sub eax, 1 + sbb edx, 0 +.find_chain_start: +; 6b. For each sector where the previous item does not expand the chain, +; call the lookup function without adding to the cache. + call cache_lookup_read +; 6c. If the sector is not found in cache or is not modified, stop expanding +; and advance to step 7. + jc .found_chain_start + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + jnz .found_chain_start +; 6d. We have found a new block that expands the chain backwards. +; It makes the chain non-sequential. +; Normally, sectors come in sequential blocks, so try to look at previous items +; before returning to 6b; if there is a sequential block indeed, this saves some +; time instead of many full-fledged lookups. + mov [.sequential], 0 + mov [.chain_start_pos], edi +.look_backward: +; 6e. For each sector, update chain start pos/ptr, decrement sector number, +; look at the previous item. + mov [.chain_start_ptr], esi + inc [.chain_size] + sub eax, 1 + sbb edx, 0 + sub esi, sizeof.CACHE_ITEM +; If the previous item exists... + cmp esi, [ebx+DISKCACHE.pointer] + jbe .find_chain_start +; ...describes the correct sector... + cmp [esi+CACHE_ITEM.SectorLo], eax + jnz .find_chain_start + cmp [esi+CACHE_ITEM.SectorHi], edx + jnz .find_chain_start +; ...and is modified... + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + jnz .found_chain_start +; ...expand the chain one sector backwards and continue the loop at 6e. +; Otherwise, advance to step 7 if the previous item describes the correct sector +; but is not modified, and return to step 6b otherwise. mov edi, 1 -.write_cache_more: - cmp dword [esi+8], 2 ; if cache slot is not different - jne .write_chain - mov dword [esi+8], 1 ; same as in hd - mov eax, [esi] - mov edx, [esi+4] ; edx:eax = sector to write -; Объединяем запись цепочки последовательных секторов в одно обращение к диску - cmp ecx, 1 - jz .nonext - cmp dword [esi+12+8], 2 - jnz .nonext - push eax edx + shl edi, cl + sub [.chain_start_pos], edi + jmp .look_backward +.found_chain_start: +; 7. Expand the chain forward. +; 7a. Prepare for the loop at 7b: +; set esi = pointer to current item, edx:eax = current sector. + mov esi, [.current_ptr] + mov eax, [esi+CACHE_ITEM.SectorLo] + mov edx, [esi+CACHE_ITEM.SectorHi] +.look_forward: +; 7b. First, look at the next item. If it describes the next sector: +; if it is modified, expand the chain with that sector and continue this step, +; if it is not modified, the chain is completed, so advance to step 8. + inc [.chain_size] add eax, 1 adc edx, 0 - cmp eax, [esi+12] - jnz @f - cmp edx, [esi+12+4] -@@: - pop edx eax - jnz .nonext - cmp [cache_chain_started], 1 - jz @f - mov [cache_chain_started], 1 - mov [cache_chain_size], 0 - mov [cache_chain_pos], edi - mov [cache_chain_ptr], esi -@@: - inc [cache_chain_size] - cmp [cache_chain_size], 16 - jnz .continue - jmp .write_chain -.nonext: - call .flush_cache_chain - test eax, eax - jnz .nothing - mov [cache_chain_size], 1 - mov [cache_chain_ptr], esi - call .write_cache_sector - test eax, eax - jnz .nothing - jmp .continue -.write_chain: - call .flush_cache_chain - test eax, eax - jnz .nothing -.continue: - add esi, 12 - inc edi - dec ecx - jnz .write_cache_more - call .flush_cache_chain - test eax, eax - jnz .nothing -.flush: - mov esi, [disk] - mov al, DISKFUNC.flush - call disk_call_driver -.nothing: - ret - -.flush_cache_chain: - xor eax, eax - cmp [cache_chain_started], eax - jz @f - call .write_cache_chain - mov [cache_chain_started], 0 -@@: - retn - -.write_cache_sector: - mov [cache_chain_size], 1 - mov [cache_chain_pos], edi -.write_cache_chain: - pusha - mov edi, [cache_chain_pos] - mov ecx, [ebp-saved_esi_pos] - shl edi, 9 - add edi, [ecx+DISKCACHE.data] - mov ecx, [cache_chain_size] - push ecx - push esp ; numsectors - mov eax, [cache_chain_ptr] - pushd [eax+4] - pushd [eax] ; startsector - push edi ; buffer - mov esi, [ebp] - mov esi, [esi+PARTITION.Disk] + add esi, sizeof.CACHE_ITEM + cmp esi, [.cache_end] + jae .find_chain_end + cmp [esi+CACHE_ITEM.SectorLo], eax + jnz .find_chain_end + cmp [esi+CACHE_ITEM.SectorHi], edx + jnz .find_chain_end + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + jnz .found_chain_end + jmp .look_forward +.find_chain_end: +; 7c. Otherwise, call the lookup function. + call cache_lookup_read +; 7d. If the next sector is present in the cache and is modified, +; mark the chain as non-sequential and continue to step 7b. + jc .found_chain_end + cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + jnz .found_chain_end + mov [.sequential], 0 + jmp .look_forward +.found_chain_end: +; 8. Decide whether the chain is sequential or scattered. +; Advance to step 9 for sequential chains, go to step 10 for scattered chains. + cmp [.sequential], 0 + jz .write_non_sequential +.write_sequential: +; 9. Write a sequential chain to disk. +; 9a. Pass the entire chain to the driver. + mov eax, [.chain_start_ptr] + lea ecx, [.chain_size] + push ecx ; numsectors + pushd [eax+CACHE_ITEM.SectorHi] ; startsector + pushd [eax+CACHE_ITEM.SectorLo] ; startsector + push [.chain_start_pos+12] ; buffer + mov esi, [ebp+PARTITION.Disk] mov al, DISKFUNC.write call disk_call_driver +; 9b. If failed, pass the error code to the driver. + test eax, eax + jnz .return +; 9c. If succeeded, mark all sectors in the chain as not-modified, +; advance current item and number of items left to skip the chain. + mov esi, [.current_ptr] + mov eax, [.chain_size] + sub [.size_left], eax +@@: + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY + add esi, sizeof.CACHE_ITEM + dec eax + jnz @b +; 9d. Continue the main loop at step 2 if there are more sectors. +; Return success otherwise. + cmp [.size_left], 0 + jnz .look + jmp .return0 +.write_non_sequential: +; Write a non-sequential chain to the disk. +; 10. Allocate a temporary buffer. +; Use [.chain_size] sectors, but +; not greater than CACHE_MAX_ALLOC_SIZE bytes +; and not greater than half of free memory. + mov eax, [pg_data.pages_free] + shr eax, 1 + jz .nomemory + cmp eax, CACHE_MAX_ALLOC_SIZE shr 12 + jbe @f + mov eax, CACHE_MAX_ALLOC_SIZE shr 12 +@@: + shl eax, 12 + shr eax, cl + jz .nomemory + cmp eax, [.chain_size] + jbe @f + mov eax, [.chain_size] +@@: + mov [.iteration_size], eax + shl eax, cl + stdcall kernel_alloc, eax + test eax, eax + jz .nomemory + mov [.iteration_buffer], eax +.write_non_sequential_iteration: +; 11. Split the chain so that each iteration fits in the allocated buffer. +; Iteration size is the minimum of chain size and allocated size. + mov eax, [.chain_size] + cmp eax, [.iteration_size] + jae @f + mov [.iteration_size], eax +@@: +; 12. Prepare arguments for the driver. + mov esi, [.chain_start_ptr] + mov edi, [.iteration_buffer] + push [.iteration_size] + push esp ; numsectors + push [esi+CACHE_ITEM.SectorHi] ; startsector + push [esi+CACHE_ITEM.SectorLo] ; startsector + push edi ; buffer +; 13. Copy data from the cache to the temporary buffer, +; advancing chain_start pos/ptr and marking sectors as not-modified. +; 13a. Prepare for the loop: push number of sectors to process. + push [.iteration_size+20] ; temporary variable +.copy_loop: +; 13b. For each sector, copy the data. +; Note that edi is advanced automatically. + mov esi, [.chain_start_pos+24] + mov ecx, [ebx+DISKCACHE.sector_size_log] + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 + rep movsd + mov ecx, eax ; keep for 13e +; 13c. Mark the item as not-modified. + mov esi, [.chain_start_ptr+24] + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY +; 13d. Check whether the next sector continues the chain. +; If so, advance to 13e. Otherwise, go to 13f. + mov eax, [esi+CACHE_ITEM.SectorLo] + mov edx, [esi+CACHE_ITEM.SectorHi] + add esi, sizeof.CACHE_ITEM + add eax, 1 + adc edx, 0 + cmp esi, [.cache_end+24] + jae .no_forward + cmp [esi+CACHE_ITEM.SectorLo], eax + jnz .no_forward + cmp [esi+CACHE_ITEM.SectorHi], edx + jnz .no_forward +; 13e. Increment position/pointer to the chain and +; continue the loop. + add [.chain_start_pos+24], ecx + mov [.chain_start_ptr+24], esi + dec dword [esp] + jnz .copy_loop + jmp .copy_done +.no_forward: +; 13f. Call the lookup function without adding to the cache. +; Update position/pointer with returned value. +; Note: for the last sector in the chain, edi/esi may contain +; garbage; we are not going to use them in this case. + push edi + call cache_lookup_read + mov [.chain_start_pos+28], edi + mov [.chain_start_ptr+28], esi + pop edi + dec dword [esp] + jnz .copy_loop +.copy_done: +; 13g. Restore the stack after 13a. pop ecx - mov [esp+28], eax - popa - retn +; 14. Call the driver. + mov esi, [ebp+PARTITION.Disk] + mov al, DISKFUNC.write + call disk_call_driver + pop ecx ; numsectors +; 15. If the driver has returned an error, free the buffer allocated at step 10 +; and pass the error to the caller. +; Otherwise, remove the processed part from the chain and continue iterations +; starting in step 11 if there are more data to process. + test eax, eax + jnz .nonsequential_error + sub [.chain_size], ecx + jnz .write_non_sequential_iteration +; 16. The chain is written. Free the temporary buffer +; and continue the loop at step 2. + stdcall kernel_free, [.iteration_buffer] + mov esi, [.current_ptr] + jmp .look_next +.nonsequential_error: + push eax + stdcall kernel_free, [.iteration_buffer+4] + pop eax + jmp .return +.nomemory: + mov eax, DISK_STATUS_NO_MEMORY + jmp .return endp ; This internal function is called from disk_add to initialize the caching for @@ -452,13 +1231,32 @@ endp ; is most useful example of a non-trivial adjustment. ; esi = pointer to DISK structure disk_init_cache: -; 1. Calculate the suggested cache size. -; 1a. Get the size of free physical memory in pages. +; 1. Verify sector size. The code requires it to be a power of 2 not less than 4. +; In the name of sanity check that sector size is not too small or too large. + bsf ecx, [esi+DISK.MediaInfo.SectorSize] + jz .invalid_sector_size + mov eax, 1 + shl eax, cl + cmp eax, [esi+DISK.MediaInfo.SectorSize] + jnz .invalid_sector_size + cmp ecx, 6 + jb .invalid_sector_size + cmp ecx, 14 + jbe .normal_sector_size +.invalid_sector_size: + DEBUGF 1,'K : sector size %x is invalid\n',[esi+DISK.MediaInfo.SectorSize] + xor eax, eax + ret +.normal_sector_size: + mov [esi+DISK.SysCache.sector_size_log], ecx + mov [esi+DISK.AppCache.sector_size_log], ecx +; 2. Calculate the suggested cache size. +; 2a. Get the size of free physical memory in pages. mov eax, [pg_data.pages_free] -; 1b. Use the value to calculate the size. +; 2b. Use the value to calculate the size. shl eax, 12 - 5 ; 1/32 of it in bytes and eax, -8*4096 ; round down to the multiple of 8 pages -; 1c. Force lower and upper limits. +; 2c. Force lower and upper limits. cmp eax, 1024*1024 jb @f mov eax, 1024*1024 @@ -467,7 +1265,7 @@ disk_init_cache: ja @f mov eax, 128*1024 @@: -; 1d. Give a chance to the driver to adjust the size. +; 2d. Give a chance to the driver to adjust the size. push eax mov al, DISKFUNC.adjust_cache_size call disk_call_driver @@ -475,20 +1273,18 @@ disk_init_cache: mov [esi+DISK.cache_size], eax test eax, eax jz .nocache -; 2. Allocate memory for the cache. -; 2a. Call the allocator. +; 3. Allocate memory for the cache. +; 3a. Call the allocator. stdcall kernel_alloc, eax test eax, eax jnz @f -; 2b. If it failed, say a message and return with eax = 0. +; 3b. If it failed, say a message and return with eax = 0. dbgstr 'no memory for disk cache' jmp .nothing @@: -; 3. Fill two DISKCACHE structures. +; 4. Fill two DISKCACHE structures. mov [esi+DISK.SysCache.pointer], eax - lea ecx, [esi+DISK.SysCache.mutex] - call mutex_init - lea ecx, [esi+DISK.AppCache.mutex] + lea ecx, [esi+DISK.CacheLock] call mutex_init ; The following code is inherited from getcache.inc. mov edx, [esi+DISK.SysCache.pointer] @@ -503,9 +1299,7 @@ disk_init_cache: mov [esi+DISK.AppCache.pointer], edx mov eax, [esi+DISK.SysCache.data_size] - push ebx - call calculate_for_hd64 - pop ebx + call calculate_cache_slots add eax, [esi+DISK.SysCache.pointer] mov [esi+DISK.SysCache.data], eax mov [esi+DISK.SysCache.sad_size], ecx @@ -518,9 +1312,7 @@ disk_init_cache: pop edi mov eax, [esi+DISK.AppCache.data_size] - push ebx - call calculate_for_hd64 - pop ebx + call calculate_cache_slots add eax, [esi+DISK.AppCache.pointer] mov [esi+DISK.AppCache.data], eax mov [esi+DISK.AppCache.sad_size], ecx @@ -532,9 +1324,9 @@ disk_init_cache: rep stosd pop edi -; 4. Return with nonzero al. +; 5. Return with nonzero al. mov al, 1 -; 5. Return. +; 6. Return. .nothing: ret ; No caching is required for this driver. Zero cache pointers and return with @@ -545,18 +1337,16 @@ disk_init_cache: mov al, 1 ret -calculate_for_hd64: +calculate_cache_slots: push eax - mov ebx, eax - shr eax, 9 - lea eax, [eax*3] - shl eax, 2 - sub ebx, eax - shr ebx, 9 - mov ecx, ebx - shl ebx, 9 + mov ecx, [esi+DISK.MediaInfo.SectorSize] + add ecx, sizeof.CACHE_ITEM + xor edx, edx + div ecx + mov ecx, eax + imul eax, [esi+DISK.MediaInfo.SectorSize] + sub [esp], eax pop eax - sub eax, ebx dec ecx ret @@ -577,12 +1367,21 @@ disk_free_cache: ; esi = pointer to DISK disk_sync: ; The algorithm is straightforward. - push esi + cmp [esi+DISK.SysCache.pointer], 0 + jz .nothing + lea ecx, [esi+DISK.CacheLock] + call mutex_lock + push ebx push esi ; for second write_cache64 push esi ; for first write_cache64 - add esi, DISK.SysCache + lea ebx, [esi+DISK.SysCache] call write_cache64 - add esi, DISK.AppCache - DISK.SysCache + add ebx, DISK.AppCache - DISK.SysCache call write_cache64 - pop esi + pop ebx + lea ecx, [esi+DISK.CacheLock] + call mutex_unlock +.nothing: + mov al, DISKFUNC.flush + call disk_call_driver ret diff --git a/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc b/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc index 0825874023..c4f36387f4 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc b/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc index ea787c5afd..d876db1f4a 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc @@ -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 ;----------------------------------------------------------------------------- diff --git a/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc b/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc index 071d713b68..058f1321ec 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/blkdev/rd.inc b/kernel/branches/Kolibri-acpi/blkdev/rd.inc index 12496fcbe9..6bc32e66b4 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/rd.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/rd.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/boot/bootcode.inc b/kernel/branches/Kolibri-acpi/boot/bootcode.inc index e58bee79a3..de2ea45af6 100644 --- a/kernel/branches/Kolibri-acpi/boot/bootcode.inc +++ b/kernel/branches/Kolibri-acpi/boot/bootcode.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/boot/booten.inc b/kernel/branches/Kolibri-acpi/boot/booten.inc index fdc56e6ff1..3f9c228ca3 100644 --- a/kernel/branches/Kolibri-acpi/boot/booten.inc +++ b/kernel/branches/Kolibri-acpi/boot/booten.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/boot/bootvesa.inc b/kernel/branches/Kolibri-acpi/boot/bootvesa.inc index 759256f85b..d8938f1f9a 100644 --- a/kernel/branches/Kolibri-acpi/boot/bootvesa.inc +++ b/kernel/branches/Kolibri-acpi/boot/bootvesa.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/boot/rdload.inc b/kernel/branches/Kolibri-acpi/boot/rdload.inc index d7f206fdfe..d41b6b561d 100644 --- a/kernel/branches/Kolibri-acpi/boot/rdload.inc +++ b/kernel/branches/Kolibri-acpi/boot/rdload.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/boot/shutdown.inc b/kernel/branches/Kolibri-acpi/boot/shutdown.inc index 45cab5f9ed..625c681486 100644 --- a/kernel/branches/Kolibri-acpi/boot/shutdown.inc +++ b/kernel/branches/Kolibri-acpi/boot/shutdown.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/build.bat b/kernel/branches/Kolibri-acpi/build.bat index fef4f7f6d1..04a1cf230b 100644 --- a/kernel/branches/Kolibri-acpi/build.bat +++ b/kernel/branches/Kolibri-acpi/build.bat @@ -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 diff --git a/kernel/branches/Kolibri-acpi/bus/usb/common.inc b/kernel/branches/Kolibri-acpi/bus/usb/common.inc index d77e687a46..a425f6ee1f 100644 --- a/kernel/branches/Kolibri-acpi/bus/usb/common.inc +++ b/kernel/branches/Kolibri-acpi/bus/usb/common.inc @@ -6,7 +6,7 @@ ; ============================================================================= ; Version of all structures related to host controllers. ; Must be the same in kernel and *hci-drivers. -USBHC_VERSION = 1 +USBHC_VERSION = 2 ; USB device must have at least 100ms of stable power before initializing can ; proceed; one timer tick is 10ms, so enforce delay in 10 ticks @@ -46,6 +46,7 @@ USB_STATUS_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 ? diff --git a/kernel/branches/Kolibri-acpi/bus/usb/hccommon.inc b/kernel/branches/Kolibri-acpi/bus/usb/hccommon.inc index 4a066859a3..efc2064f89 100644 --- a/kernel/branches/Kolibri-acpi/bus/usb/hccommon.inc +++ b/kernel/branches/Kolibri-acpi/bus/usb/hccommon.inc @@ -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. diff --git a/kernel/branches/Kolibri-acpi/bus/usb/hub.inc b/kernel/branches/Kolibri-acpi/bus/usb/hub.inc index 6048076841..606a0122bc 100644 --- a/kernel/branches/Kolibri-acpi/bus/usb/hub.inc +++ b/kernel/branches/Kolibri-acpi/bus/usb/hub.inc @@ -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. diff --git a/kernel/branches/Kolibri-acpi/bus/usb/init.inc b/kernel/branches/Kolibri-acpi/bus/usb/init.inc index 7587bb881b..af49513b16 100644 --- a/kernel/branches/Kolibri-acpi/bus/usb/init.inc +++ b/kernel/branches/Kolibri-acpi/bus/usb/init.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/bus/usb/memory.inc b/kernel/branches/Kolibri-acpi/bus/usb/memory.inc index 8a24b656b3..1e55b07db2 100644 --- a/kernel/branches/Kolibri-acpi/bus/usb/memory.inc +++ b/kernel/branches/Kolibri-acpi/bus/usb/memory.inc @@ -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: diff --git a/kernel/branches/Kolibri-acpi/bus/usb/pipe.inc b/kernel/branches/Kolibri-acpi/bus/usb/pipe.inc index ab249d9675..4205dc98f6 100644 --- a/kernel/branches/Kolibri-acpi/bus/usb/pipe.inc +++ b/kernel/branches/Kolibri-acpi/bus/usb/pipe.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/bus/usb/protocol.inc b/kernel/branches/Kolibri-acpi/bus/usb/protocol.inc index 6d720e380b..29bc4a75e1 100644 --- a/kernel/branches/Kolibri-acpi/bus/usb/protocol.inc +++ b/kernel/branches/Kolibri-acpi/bus/usb/protocol.inc @@ -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] diff --git a/kernel/branches/Kolibri-acpi/const.inc b/kernel/branches/Kolibri-acpi/const.inc index 3664e63c5c..9c9cb4087e 100644 --- a/kernel/branches/Kolibri-acpi/const.inc +++ b/kernel/branches/Kolibri-acpi/const.inc @@ -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 ? diff --git a/kernel/branches/Kolibri-acpi/core/apic.inc b/kernel/branches/Kolibri-acpi/core/apic.inc index 48b993ac06..6a529afec8 100644 --- a/kernel/branches/Kolibri-acpi/core/apic.inc +++ b/kernel/branches/Kolibri-acpi/core/apic.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/clipboard.inc b/kernel/branches/Kolibri-acpi/core/clipboard.inc index 689064024b..c06c5f7ecb 100644 --- a/kernel/branches/Kolibri-acpi/core/clipboard.inc +++ b/kernel/branches/Kolibri-acpi/core/clipboard.inc @@ -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: diff --git a/kernel/branches/Kolibri-acpi/core/conf_lib-sp.inc b/kernel/branches/Kolibri-acpi/core/conf_lib-sp.inc index abf7cf5e3e..98beb90382 100644 --- a/kernel/branches/Kolibri-acpi/core/conf_lib-sp.inc +++ b/kernel/branches/Kolibri-acpi/core/conf_lib-sp.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/debug.inc b/kernel/branches/Kolibri-acpi/core/debug.inc index b7c7f9c6b8..a1fcfdcd75 100644 --- a/kernel/branches/Kolibri-acpi/core/debug.inc +++ b/kernel/branches/Kolibri-acpi/core/debug.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/dll.inc b/kernel/branches/Kolibri-acpi/core/dll.inc index d9e150719c..344275ed01 100644 --- a/kernel/branches/Kolibri-acpi/core/dll.inc +++ b/kernel/branches/Kolibri-acpi/core/dll.inc @@ -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/.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] diff --git a/kernel/branches/Kolibri-acpi/core/exports.inc b/kernel/branches/Kolibri-acpi/core/exports.inc index ff1efadacc..0186c46767 100644 --- a/kernel/branches/Kolibri-acpi/core/exports.inc +++ b/kernel/branches/Kolibri-acpi/core/exports.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/heap.inc b/kernel/branches/Kolibri-acpi/core/heap.inc index 5e2a897fe1..7b03cb62d2 100644 --- a/kernel/branches/Kolibri-acpi/core/heap.inc +++ b/kernel/branches/Kolibri-acpi/core/heap.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/irq.inc b/kernel/branches/Kolibri-acpi/core/irq.inc index e1b3df32f6..e6a7ea7870 100644 --- a/kernel/branches/Kolibri-acpi/core/irq.inc +++ b/kernel/branches/Kolibri-acpi/core/irq.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/memory.inc b/kernel/branches/Kolibri-acpi/core/memory.inc index 41159cc1e4..3399b02c44 100644 --- a/kernel/branches/Kolibri-acpi/core/memory.inc +++ b/kernel/branches/Kolibri-acpi/core/memory.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/mtrr.inc b/kernel/branches/Kolibri-acpi/core/mtrr.inc new file mode 100644 index 0000000000..ffb299432e --- /dev/null +++ b/kernel/branches/Kolibri-acpi/core/mtrr.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/peload.inc b/kernel/branches/Kolibri-acpi/core/peload.inc index f447d7a346..4cf5ffd018 100644 --- a/kernel/branches/Kolibri-acpi/core/peload.inc +++ b/kernel/branches/Kolibri-acpi/core/peload.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/sched.inc b/kernel/branches/Kolibri-acpi/core/sched.inc index 8ab5ce515e..4add4b3ccf 100644 --- a/kernel/branches/Kolibri-acpi/core/sched.inc +++ b/kernel/branches/Kolibri-acpi/core/sched.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/sys32-sp.inc b/kernel/branches/Kolibri-acpi/core/sys32-sp.inc index 12a29eda4c..17bf1c3384 100644 --- a/kernel/branches/Kolibri-acpi/core/sys32-sp.inc +++ b/kernel/branches/Kolibri-acpi/core/sys32-sp.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/sys32.inc b/kernel/branches/Kolibri-acpi/core/sys32.inc index 5da9fcf9e9..aa8ffe76fa 100644 --- a/kernel/branches/Kolibri-acpi/core/sys32.inc +++ b/kernel/branches/Kolibri-acpi/core/sys32.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/core/taskman.inc b/kernel/branches/Kolibri-acpi/core/taskman.inc index 1a3333987a..c4e25214a9 100644 --- a/kernel/branches/Kolibri-acpi/core/taskman.inc +++ b/kernel/branches/Kolibri-acpi/core/taskman.inc @@ -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] diff --git a/kernel/branches/Kolibri-acpi/core/v86.inc b/kernel/branches/Kolibri-acpi/core/v86.inc index 6bed883bd9..a71ec99002 100644 --- a/kernel/branches/Kolibri-acpi/core/v86.inc +++ b/kernel/branches/Kolibri-acpi/core/v86.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/data32.inc b/kernel/branches/Kolibri-acpi/data32.inc index e746146c70..ef41a9c13e 100644 --- a/kernel/branches/Kolibri-acpi/data32.inc +++ b/kernel/branches/Kolibri-acpi/data32.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/data32et.inc b/kernel/branches/Kolibri-acpi/data32et.inc index 63d9573f25..689a3ed3ae 100644 --- a/kernel/branches/Kolibri-acpi/data32et.inc +++ b/kernel/branches/Kolibri-acpi/data32et.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/data32sp.inc b/kernel/branches/Kolibri-acpi/data32sp.inc index a0b25b4e97..ae0208d78b 100644 --- a/kernel/branches/Kolibri-acpi/data32sp.inc +++ b/kernel/branches/Kolibri-acpi/data32sp.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/detect/biosdisk.inc b/kernel/branches/Kolibri-acpi/detect/biosdisk.inc index 24bbd433a6..96aa12ec60 100644 --- a/kernel/branches/Kolibri-acpi/detect/biosdisk.inc +++ b/kernel/branches/Kolibri-acpi/detect/biosdisk.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/detect/biosmem.inc b/kernel/branches/Kolibri-acpi/detect/biosmem.inc index 85cf0d1f41..82a99018f0 100644 --- a/kernel/branches/Kolibri-acpi/detect/biosmem.inc +++ b/kernel/branches/Kolibri-acpi/detect/biosmem.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc b/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc index 947c5a6433..7f4f00991e 100644 --- a/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc +++ b/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc @@ -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: - diff --git a/kernel/branches/Kolibri-acpi/detect/getcache.inc b/kernel/branches/Kolibri-acpi/detect/getcache.inc index d91c3fdda5..261d8a860f 100644 --- a/kernel/branches/Kolibri-acpi/detect/getcache.inc +++ b/kernel/branches/Kolibri-acpi/detect/getcache.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/detect/init_ata.inc b/kernel/branches/Kolibri-acpi/detect/init_ata.inc new file mode 100644 index 0000000000..ac784bd7d3 --- /dev/null +++ b/kernel/branches/Kolibri-acpi/detect/init_ata.inc @@ -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 +;----------------------------------------------------------------------------- diff --git a/kernel/branches/Kolibri-acpi/detect/sear_par.inc b/kernel/branches/Kolibri-acpi/detect/sear_par.inc index 6be78160dd..870d545f54 100644 --- a/kernel/branches/Kolibri-acpi/detect/sear_par.inc +++ b/kernel/branches/Kolibri-acpi/detect/sear_par.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt b/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt index 241ddcd883..2503e339bc 100644 --- a/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt +++ b/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt @@ -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 - завершить выполнение потока/процесса ========= diff --git a/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt b/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt index 6eae185b2c..0d0f71b5a4 100644 --- a/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt +++ b/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt @@ -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 =============== diff --git a/kernel/branches/Kolibri-acpi/docs/usbapi.txt b/kernel/branches/Kolibri-acpi/docs/usbapi.txt index f3fe0f0be1..9997afcb13 100644 --- a/kernel/branches/Kolibri-acpi/docs/usbapi.txt +++ b/kernel/branches/Kolibri-acpi/docs/usbapi.txt @@ -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. diff --git a/kernel/branches/Kolibri-acpi/encoding.inc b/kernel/branches/Kolibri-acpi/encoding.inc index c492d6af86..80c1ad39a2 100644 --- a/kernel/branches/Kolibri-acpi/encoding.inc +++ b/kernel/branches/Kolibri-acpi/encoding.inc @@ -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 } diff --git a/kernel/branches/Kolibri-acpi/fs/ext2/blocks.inc b/kernel/branches/Kolibri-acpi/fs/ext2/blocks.inc index f9d11aacb4..0576a5205b 100644 --- a/kernel/branches/Kolibri-acpi/fs/ext2/blocks.inc +++ b/kernel/branches/Kolibri-acpi/fs/ext2/blocks.inc @@ -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); diff --git a/kernel/branches/Kolibri-acpi/fs/ext2/ext2.asm b/kernel/branches/Kolibri-acpi/fs/ext2/ext2.asm index a8f518ae62..665a80c175 100644 --- a/kernel/branches/Kolibri-acpi/fs/ext2/ext2.asm +++ b/kernel/branches/Kolibri-acpi/fs/ext2/ext2.asm @@ -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. diff --git a/kernel/branches/Kolibri-acpi/fs/ext2/ext2.inc b/kernel/branches/Kolibri-acpi/fs/ext2/ext2.inc index e2b9aea194..a03c1ba308 100644 --- a/kernel/branches/Kolibri-acpi/fs/ext2/ext2.inc +++ b/kernel/branches/Kolibri-acpi/fs/ext2/ext2.inc @@ -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. diff --git a/kernel/branches/Kolibri-acpi/fs/ext2/inode.inc b/kernel/branches/Kolibri-acpi/fs/ext2/inode.inc index a743064fa7..01b89053b2 100644 --- a/kernel/branches/Kolibri-acpi/fs/ext2/inode.inc +++ b/kernel/branches/Kolibri-acpi/fs/ext2/inode.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/fs/ext2/resource.inc b/kernel/branches/Kolibri-acpi/fs/ext2/resource.inc index 663632e368..e0a7f2dfa2 100644 --- a/kernel/branches/Kolibri-acpi/fs/ext2/resource.inc +++ b/kernel/branches/Kolibri-acpi/fs/ext2/resource.inc @@ -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. diff --git a/kernel/branches/Kolibri-acpi/fs/fat.inc b/kernel/branches/Kolibri-acpi/fs/fat.inc index aa9f4b8a68..6331002403 100644 --- a/kernel/branches/Kolibri-acpi/fs/fat.inc +++ b/kernel/branches/Kolibri-acpi/fs/fat.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc b/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc index efa433f227..2d74437315 100644 --- a/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc +++ b/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/fs/iso9660.inc b/kernel/branches/Kolibri-acpi/fs/iso9660.inc index 9862d6bd17..a10da72825 100644 --- a/kernel/branches/Kolibri-acpi/fs/iso9660.inc +++ b/kernel/branches/Kolibri-acpi/fs/iso9660.inc @@ -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 +;----------------------------------------------------------------------------- diff --git a/kernel/branches/Kolibri-acpi/fs/ntfs.inc b/kernel/branches/Kolibri-acpi/fs/ntfs.inc index a55cdc4fa9..0b05c7cac0 100644 --- a/kernel/branches/Kolibri-acpi/fs/ntfs.inc +++ b/kernel/branches/Kolibri-acpi/fs/ntfs.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/fs/xfs.asm b/kernel/branches/Kolibri-acpi/fs/xfs.asm index 0ab3de2fac..780f8ded01 100644 --- a/kernel/branches/Kolibri-acpi/fs/xfs.asm +++ b/kernel/branches/Kolibri-acpi/fs/xfs.asm @@ -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 diff --git a/kernel/branches/Kolibri-acpi/fs/xfs.inc b/kernel/branches/Kolibri-acpi/fs/xfs.inc index 7ba2ce68f8..fe9916cf21 100644 --- a/kernel/branches/Kolibri-acpi/fs/xfs.inc +++ b/kernel/branches/Kolibri-acpi/fs/xfs.inc @@ -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. diff --git a/kernel/branches/Kolibri-acpi/gui/event.inc b/kernel/branches/Kolibri-acpi/gui/event.inc index 51feeb30e5..99dce2fb72 100644 --- a/kernel/branches/Kolibri-acpi/gui/event.inc +++ b/kernel/branches/Kolibri-acpi/gui/event.inc @@ -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: diff --git a/kernel/branches/Kolibri-acpi/gui/skincode.inc b/kernel/branches/Kolibri-acpi/gui/skincode.inc index 85f3886745..c90ffe75c2 100644 --- a/kernel/branches/Kolibri-acpi/gui/skincode.inc +++ b/kernel/branches/Kolibri-acpi/gui/skincode.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/gui/skindata.inc b/kernel/branches/Kolibri-acpi/gui/skindata.inc index 4950025a85..b44da52625 100644 --- a/kernel/branches/Kolibri-acpi/gui/skindata.inc +++ b/kernel/branches/Kolibri-acpi/gui/skindata.inc @@ -9,7 +9,7 @@ $Revision$ ; -; WINDOW SKIN DATA +; WINDOW SKIN DATA. ; iglobal diff --git a/kernel/branches/Kolibri-acpi/gui/window.inc b/kernel/branches/Kolibri-acpi/gui/window.inc index a71cd0d4f3..f6e9cc2cfd 100644 --- a/kernel/branches/Kolibri-acpi/gui/window.inc +++ b/kernel/branches/Kolibri-acpi/gui/window.inc @@ -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 ///////////////////////////////// ;------------------------------------------------------------------------------ -;? +;? . ;------------------------------------------------------------------------------ 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] diff --git a/kernel/branches/Kolibri-acpi/hid/keyboard.inc b/kernel/branches/Kolibri-acpi/hid/keyboard.inc index df2b770cbc..41f4dcadce 100644 --- a/kernel/branches/Kolibri-acpi/hid/keyboard.inc +++ b/kernel/branches/Kolibri-acpi/hid/keyboard.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/hid/mousedrv.inc b/kernel/branches/Kolibri-acpi/hid/mousedrv.inc index 2dc322a83b..ddf11ad96a 100644 --- a/kernel/branches/Kolibri-acpi/hid/mousedrv.inc +++ b/kernel/branches/Kolibri-acpi/hid/mousedrv.inc @@ -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 -;----------------------------------------------------------------------------- diff --git a/kernel/branches/Kolibri-acpi/init.inc b/kernel/branches/Kolibri-acpi/init.inc index 466503348c..b4491daf82 100644 --- a/kernel/branches/Kolibri-acpi/init.inc +++ b/kernel/branches/Kolibri-acpi/init.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/kernel.asm b/kernel/branches/Kolibri-acpi/kernel.asm index 2fa35afbe4..bbf983a785 100644 --- a/kernel/branches/Kolibri-acpi/kernel.asm +++ b/kernel/branches/Kolibri-acpi/kernel.asm @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. +;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; PROGRAMMING: ;; Ivan Poddubny ;; Marat Zakiyanov (Mario79) @@ -291,7 +291,7 @@ B32: ; ENABLE PAGING - mov eax, sys_pgdir-OS_BASE + mov eax, sys_proc-OS_BASE+PROC.pdt_0 mov cr3, eax mov eax, cr0 @@ -309,6 +309,25 @@ use16 org $-0x10000 include "boot/shutdown.inc" ; shutdown or restart org $+0x10000 + +ap_init16: + cli + lgdt [cs:gdts_ap-ap_init16] + mov eax, [cs:cr3_ap-ap_init16] + mov cr3, eax + mov eax, [cs:cr4_ap-ap_init16] + mov cr4, eax + mov eax, CR0_PE+CR0_PG+CR0_WP + mov cr0, eax + jmp pword os_code:ap_init_high +align 16 +gdts_ap: + dw gdte-gdts-1 + dd gdts + dw 0 +cr3_ap dd ? +cr4_ap dd ? +ap_init16_size = $ - ap_init16 use32 __DEBUG__ fix 1 @@ -335,15 +354,15 @@ high_code: bt [cpu_caps], CAPS_PGE jnc @F - or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL + or dword [sys_proc+PROC.pdt_0+(OS_BASE shr 20)], PG_GLOBAL mov ebx, cr4 or ebx, CR4_PGE mov cr4, ebx @@: xor eax, eax - mov dword [sys_pgdir], eax - mov dword [sys_pgdir+4], eax + mov dword [sys_proc+PROC.pdt_0], eax + mov dword [sys_proc+PROC.pdt_0+4], eax mov eax, cr3 mov cr3, eax ; flush TLB @@ -369,78 +388,17 @@ high_code: call mutex_init mov ecx, ide_channel2_mutex call mutex_init + mov ecx, ide_channel3_mutex + call mutex_init + mov ecx, ide_channel4_mutex + call mutex_init + mov ecx, ide_channel5_mutex + call mutex_init + mov ecx, ide_channel6_mutex + call mutex_init ;----------------------------------------------------------------------------- ; SAVE REAL MODE VARIABLES ;----------------------------------------------------------------------------- -save_variables_IDE_controller: - xor eax, eax - mov ax, [BOOT_VARS + BOOT_IDE_INTERR_16] - mov [IDE_Interrupt], ax -;-------------------------------------- - mov ax, [BOOT_VARS + BOOT_IDE_PI_16] - mov [IDEContrProgrammingInterface], ax -;-------------------------------------- - mov ax, [BOOT_VARS + BOOT_IDE_BASE_ADDR] - mov [IDEContrRegsBaseAddr], ax -;-------------------------------------- - mov ax, [BOOT_VARS + BOOT_IDE_BAR0_16] - cmp ax, 0 - je @f - cmp ax, 1 - jne .no_PATA_BAR0 -@@: - mov ax, 0x1F0 - jmp @f -.no_PATA_BAR0: - and ax, 0xFFFC -@@: - mov [StandardATABases], ax - mov [hd_address_table], eax - mov [hd_address_table+8], eax - mov [IDE_BAR0_val], ax -;-------------------------------------- - mov ax, [BOOT_VARS + BOOT_IDE_BAR1_16] - cmp ax, 0 - je @f - cmp ax, 1 - jne .no_PATA_BAR1 -@@: - mov ax, 0x3F4 - jmp @f -.no_PATA_BAR1: - and ax, 0xFFFC -@@: - mov [IDE_BAR1_val], ax -;-------------------------------------- - mov ax, [BOOT_VARS + BOOT_IDE_BAR2_16] - cmp ax, 0 - je @f - cmp ax, 1 - jne .no_PATA_BAR2 -@@: - mov ax, 0x170 - jmp @f -.no_PATA_BAR2: - and ax, 0xFFFC -@@: - mov [StandardATABases+2], ax - mov [hd_address_table+16], eax - mov [hd_address_table+24], eax - mov [IDE_BAR2_val], ax -;-------------------------------------- - mov ax, [BOOT_VARS + BOOT_IDE_BAR3_16] - cmp ax, 0 - je @f - cmp ax, 1 - jne .no_PATA_BAR3 -@@: - mov ax, 0x374 - jmp @f -.no_PATA_BAR3: - and ax, 0xFFFC -@@: - mov [IDE_BAR3_val], ax - ; --------------- APM --------------------- ; init selectors @@ -476,7 +434,7 @@ save_variables_IDE_controller: mov al, [BOOT_VARS+BOOT_DMA] ; DMA access mov [allow_dma_access], al movzx eax, byte [BOOT_VARS+BOOT_BPP] ; bpp - mov [_display.bpp], eax + mov [_display.bits_per_pixel], eax mov [_display.vrefresh], 60 mov al, [BOOT_VARS+BOOT_DEBUG_PRINT] ; If nonzero, duplicates debug output to the screen mov [debug_direct_print], al @@ -486,11 +444,13 @@ save_variables_IDE_controller: mov [_display.width], eax mov [display_width_standard], eax dec eax + mov [Screen_Max_X], eax mov [screen_workarea.right], eax movzx eax, word [BOOT_VARS+BOOT_Y_RES]; Y max mov [_display.height], eax mov [display_height_standard], eax dec eax + mov [Screen_Max_Y], eax mov [screen_workarea.bottom], eax movzx eax, word [BOOT_VARS+BOOT_VESA_MODE] ; screen mode mov dword [SCR_MODE], eax @@ -520,34 +480,56 @@ save_variables_IDE_controller: mov edi, BiosDisksData rep movsd -; GRAPHICS ADDRESSES +setvideomode: mov eax, [BOOT_VARS+BOOT_LFB] mov [LFBAddress], eax - cmp [SCR_MODE], word 0100000000000000b - jge setvesa20 - cmp [SCR_MODE], word 0x13 ; EGA 320*200 256 colors - je v20ga32 - jmp v20ga24 + cmp word [SCR_MODE], 0x0012 ; VGA (640x480 16 colors) + je .vga + cmp word [SCR_MODE], 0x0013 ; MCGA (320*200 256 colors) + je .32bpp + cmp byte [_display.bits_per_pixel], 32 + je .32bpp + cmp byte [_display.bits_per_pixel], 24 + je .24bpp + cmp byte [_display.bits_per_pixel], 16 + je .16bpp +; cmp byte [_display.bits_per_pixel], 15 +; je .15bpp -setvesa20: - mov [PUTPIXEL], dword Vesa20_putpixel24 ; Vesa 2.0 - mov [GETPIXEL], dword Vesa20_getpixel24 - cmp byte [_display.bpp], 24 - jz v20ga24 -v20ga32: - mov [PUTPIXEL], dword Vesa20_putpixel32 - mov [GETPIXEL], dword Vesa20_getpixel32 - jmp no_mode_0x12 -v20ga24: - cmp [SCR_MODE], word 0x12 ; 16 C VGA 640x480 - jne no_mode_0x12 - mov [PUTPIXEL], dword VGA_putpixel - mov [GETPIXEL], dword Vesa20_getpixel32 -no_mode_0x12: + .vga: + mov [PUTPIXEL], VGA_putpixel + mov [GETPIXEL], Vesa20_getpixel32 ; Conversion buffer is 32 bpp + mov [_display.bytes_per_pixel], 4 ; Conversion buffer is 32 bpp + jmp .finish - mov [MOUSE_PICTURE], dword mousepointer +; .15bpp: +; mov [PUTPIXEL], Vesa20_putpixel15 +; mov [GETPIXEL], Vesa20_getpixel15 +; mov [_display.bytes_per_pixel], 2 +; jmp .finish + + .16bpp: + mov [PUTPIXEL], Vesa20_putpixel16 + mov [GETPIXEL], Vesa20_getpixel16 + mov [_display.bytes_per_pixel], 2 + jmp .finish + + .24bpp: + mov [PUTPIXEL], Vesa20_putpixel24 + mov [GETPIXEL], Vesa20_getpixel24 + mov [_display.bytes_per_pixel], 3 + jmp .finish + + .32bpp: + mov [PUTPIXEL], Vesa20_putpixel32 + mov [GETPIXEL], Vesa20_getpixel32 + mov [_display.bytes_per_pixel], 4 +; jmp .finish + + .finish: + mov [MOUSE_PICTURE], mousepointer mov [_display.check_mouse], check_mouse_area_for_putpixel mov [_display.check_m_pixel], check_mouse_area_for_getpixel @@ -637,7 +619,7 @@ no_mode_0x12: call init_fpu call init_malloc - stdcall alloc_kernel_space, 0x51000 + stdcall alloc_kernel_space, 0x50000 ; FIXME check size mov [default_io_map], eax add eax, 0x2000 @@ -653,9 +635,6 @@ no_mode_0x12: add eax, ebx mov [proc_mem_tab], eax - add eax, ebx - mov [tmp_task_pdir], eax - add eax, ebx mov [tmp_task_ptab], eax @@ -714,7 +693,26 @@ no_mode_0x12: mov esi, boot_setostask call boot_log - mov edx, SLOT_BASE+256 + mov edi, sys_proc + list_init edi + lea ecx, [edi+PROC.thr_list] + list_init ecx + mov [edi+PROC.pdt_0_phys], sys_proc-OS_BASE+PROC.pdt_0 + + mov eax, -1 + mov edi, thr_slot_map+4 + mov [edi-4], dword 0xFFFFFFF8 + stosd + stosd + stosd + stosd + stosd + stosd + stosd + + mov [current_process], sys_proc + + mov edx, SLOT_BASE+256*1 mov ebx, [os_stack_seg] add ebx, 0x2000 call setup_os_slot @@ -737,6 +735,69 @@ no_mode_0x12: mov dword [current_slot], SLOT_BASE + 256*2 mov dword [TASK_BASE], CURRENT_TASK + 32*2 +; Move other CPUs to deep sleep, if it is useful +uglobal +use_mwait_for_idle db 0 +endg + cmp [cpu_vendor+8], 'ntel' + jnz .no_wake_cpus + bt [cpu_caps+4], CAPS_MONITOR-32 + jnc .no_wake_cpus + dbgstr 'using mwait for idle loop' + inc [use_mwait_for_idle] + mov ebx, [cpu_count] + cmp ebx, 1 + jbe .no_wake_cpus + call create_trampoline_pgmap + mov [cr3_ap+OS_BASE], eax + mov eax, cr4 + mov [cr4_ap+OS_BASE], eax + mov esi, OS_BASE + ap_init16 + mov edi, OS_BASE + 8000h + mov ecx, (ap_init16_size + 3) / 4 + rep movsd + stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW+PG_NOCACHE + mov [LAPIC_BASE], eax + lea edi, [eax+300h] + mov esi, smpt+4 + dec ebx +.wake_cpus_loop: + lodsd + push esi + xor esi, esi + inc esi + shl eax, 24 + mov [edi+10h], eax +; assert INIT IPI + mov dword [edi], 0C500h + call delay_ms +@@: + test dword [edi], 1000h + jnz @b +; deassert INIT IPI + mov dword [edi], 8500h + call delay_ms +@@: + test dword [edi], 1000h + jnz @b +; send STARTUP IPI + mov dword [edi], 600h + (8000h shr 12) + call delay_ms +@@: + test dword [edi], 1000h + jnz @b + pop esi + dec ebx + jnz .wake_cpus_loop + mov eax, [cpu_count] + dec eax +@@: + cmp [ap_initialized], eax + jnz @b + mov eax, [cr3_ap+OS_BASE] + call free_page +.no_wake_cpus: + ; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f mov esi, boot_initirq @@ -758,10 +819,12 @@ no_mode_0x12: call PIT_init ; Register ramdisk file system - mov esi, boot_initramdisk - call boot_log - call ramdisk_init + cmp [boot_dev+OS_BASE+0x10000], 1 + je @f + call register_ramdisk +;-------------------------------------- +@@: mov esi, boot_initapic call boot_log ; Try to Initialize APIC @@ -775,58 +838,77 @@ no_mode_0x12: stdcall enable_irq, 2 ; @#$%! PIC stdcall enable_irq, 13 ; co-processor - cmp [IDEContrProgrammingInterface], 0 - je @f +; Setup serial output console (if enabled) +if defined debug_com_base - 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, [IDE_BAR1_val] ;0x3F4 - add dx, 2 ;0x3F6 + ; reserve port so nobody else will use it + xor ebx, ebx + mov ecx, debug_com_base + mov edx, debug_com_base+7 + call r_f_port_area + + ; enable Divisor latch + mov dx, debug_com_base+3 + mov al, 1 shl 7 out dx, al - mov dx, [IDE_BAR3_val] ;0x374 - add dx, 2 ;0x376 + + ; Set speed to 115200 baud (max speed) + mov dx, debug_com_base + mov al, 0x01 out dx, al -@@: + + mov dx, debug_com_base+1 + mov al, 0x00 + out dx, al + + ; No parity, 8bits words, one stop bit, dlab bit back to 0 + mov dx, debug_com_base+3 + mov al, 3 + out dx, al + + ; disable interrupts + mov dx, debug_com_base+1 + mov al, 0 + out dx, al + + ; clear + enable fifo (64 bits) + mov dx, debug_com_base+2 + mov al, 0x7 + 1 shl 5 + out dx, al + +end if + + +;----------------------------------------------------------------------------- +; show SVN version of kernel on the message board +;----------------------------------------------------------------------------- + mov eax, [version_inf.rev] + DEBUGF 1, "K : kernel SVN r%d\n", eax +;----------------------------------------------------------------------------- +; show CPU count on the message board +;----------------------------------------------------------------------------- + mov eax, [cpu_count] + test eax, eax + jnz @F + mov al, 1 ; at least one CPU +@@: + DEBUGF 1, "K : %d CPU detected\n", eax +;----------------------------------------------------------------------------- +; detect Floppy drives ;----------------------------------------------------------------------------- -;!!!!!!!!!!!!!!!!!!!!!!!!!! -; mov esi, boot_detectdisks -; call boot_log -;include 'detect/disks.inc' mov esi, boot_detectfloppy call boot_log include 'detect/dev_fd.inc' - mov esi, boot_detecthdcd - call boot_log -include 'detect/dev_hdcd.inc' - mov esi, boot_getcache - call boot_log -include 'detect/getcache.inc' - mov esi, boot_detectpart - call boot_log -include 'detect/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 [dma_hdd],1 - +;----------------------------------------------------------------------------- +; create pci-devices list +;----------------------------------------------------------------------------- + mov [pci_access_enabled], 1 + call pci_enum +;----------------------------------------------------------------------------- +; initialisation IDE ATA code +;----------------------------------------------------------------------------- +include 'detect/init_ata.inc' +;----------------------------------------------------------------------------- if 0 mov ax, [OS_BASE+0x10000+bx_from_load] cmp ax, 'r1'; if using not ram disk, then load librares and parameters {SPraid.simba} @@ -877,10 +959,11 @@ end if ; mov esi, boot_devices ; call boot_log - mov [pci_access_enabled], 1 - call pci_enum + call clear_pci_ide_interrupts - stdcall load_driver, szVidintel +include "detect/vortex86.inc" ; Vortex86 SoC detection code + + stdcall load_pe_driver, szVidintel, 0 call usb_init @@ -919,6 +1002,7 @@ end if mov esi, 250 ; wait 1/4 a second call delay_ms rdtsc + sti sub eax, ecx xor edx, edx @@ -986,6 +1070,45 @@ end if stdcall map_page, tss._io_map_1, \ [SLOT_BASE+256+APPDATA.io_map+4], PG_MAP +; SET KEYBOARD PARAMETERS + mov al, 0xf6 ; reset keyboard, scan enabled + call kb_write_wait_ack + test ah, ah + jnz .no_keyboard + +iglobal +align 4 +ps2_keyboard_functions: + dd .end - $ + dd 0 ; no close + dd ps2_set_lights +.end: +endg + stdcall register_keyboard, ps2_keyboard_functions, 0 + ; mov al, 0xED ; Keyboard LEDs - only for testing! + ; call kb_write_wait_ack + ; mov al, 111b + ; call kb_write_wait_ack + + mov al, 0xF3 ; set repeat rate & delay + call kb_write_wait_ack + mov al, 0; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 + call kb_write_wait_ack + ;// mike.dld [ + call set_lights + ;// mike.dld ] + stdcall attach_int_handler, 1, irq1, 0 + DEBUGF 1, "K : IRQ1 return code %x\n", eax +.no_keyboard: + +; Load PS/2 mouse driver + + stdcall load_pe_driver, szPS2MDriver, 0 + + mov esi, boot_setmouse + call boot_log + call setmouse + ; LOAD FIRST APPLICATION cmp byte [launcher_start], 1 ; Check if starting LAUNCHER is selected on blue screen (1 = yes) jnz first_app_found @@ -1004,119 +1127,6 @@ end if first_app_found: - cli - -; SET KEYBOARD PARAMETERS - mov al, 0xf6 ; reset keyboard, scan enabled - call kb_write - test ah, ah - jnz .no_keyboard - - ; wait until 8042 is ready - xor ecx, ecx - @@: - in al, 64h - and al, 00000010b - loopnz @b - -iglobal -align 4 -ps2_keyboard_functions: - dd .end - $ - dd 0 ; no close - dd ps2_set_lights -.end: -endg - stdcall register_keyboard, ps2_keyboard_functions, 0 - ; mov al, 0xED ; Keyboard LEDs - only for testing! - ; call kb_write - ; call kb_read - ; mov al, 111b - ; call kb_write - ; call kb_read - - mov al, 0xF3 ; set repeat rate & delay - call kb_write -; call kb_read - mov al, 0; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 - call kb_write -; call kb_read - ;// mike.dld [ - call set_lights - ;// mike.dld ] - stdcall attach_int_handler, 1, irq1, 0 - DEBUGF 1, "K : IRQ1 error code %x\n", eax -.no_keyboard: - -; SET MOUSE - - stdcall load_driver, szPS2MDriver -; stdcall load_driver, szCOM_MDriver - - mov esi, boot_setmouse - call boot_log - call setmouse - -; Setup serial output console (if enabled) - -if defined debug_com_base - - ; enable Divisor latch - - mov dx, debug_com_base+3 - mov al, 1 shl 7 - out dx, al - - ; Set speed to 115200 baud (max speed) - - mov dx, debug_com_base - mov al, 0x01 - out dx, al - - mov dx, debug_com_base+1 - mov al, 0x00 - out dx, al - - ; No parity, 8bits words, one stop bit, dlab bit back to 0 - - mov dx, debug_com_base+3 - mov al, 3 - out dx, al - - ; disable interrupts - - mov dx, debug_com_base+1 - mov al, 0 - out dx, al - - ; clear + enable fifo (64 bits) - - mov dx, debug_com_base+2 - mov al, 0x7 + 1 shl 5 - out dx, al - - -end if - mov eax, [version_inf.rev] - DEBUGF 1, "K : kernel SVN r%d\n", eax - - mov eax, [cpu_count] - test eax, eax - jnz @F - mov al, 1 ; at least one CPU -@@: - DEBUGF 1, "K : %d CPU detected\n", eax - -include "detect/vortex86.inc" ; Vortex86 SoC detection code - - DEBUGF 1, "K : BAR0 %x \n", [IDE_BAR0_val]:4 - DEBUGF 1, "K : BAR1 %x \n", [IDE_BAR1_val]:4 - DEBUGF 1, "K : BAR2 %x \n", [IDE_BAR2_val]:4 - DEBUGF 1, "K : BAR3 %x \n", [IDE_BAR3_val]:4 - DEBUGF 1, "K : BAR4 %x \n", [IDEContrRegsBaseAddr]:4 - DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", [IDEContrProgrammingInterface]:4 - DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4 - ; START MULTITASKING ; A 'All set - press ESC to start' messages if need @@ -1129,104 +1139,38 @@ if preboot_blogesc jne .bll1 end if - push eax edx - mov dx, [IDEContrRegsBaseAddr] - xor eax, eax - add dx, 2 - in al, dx - DEBUGF 1, "K : Primary Bus Master IDE Status Register %x\n", eax - - add dx, 8 - in al, dx - DEBUGF 1, "K : Secondary Bus Master IDE Status Register %x\n", eax - pop edx eax - - cmp [IDEContrRegsBaseAddr], 0 - setnz [dma_hdd] - - cmp [IDEContrProgrammingInterface], 0 - je set_interrupts_for_IDE_controllers.continue - - mov ax, [IDE_Interrupt] - cmp al, 0xff - jne @f - - mov [dma_hdd], 0 - jmp set_interrupts_for_IDE_controllers.end_set_interrupts -@@: -;----------------------------------------------------------------------------- -; set interrupts for IDE Controller -;----------------------------------------------------------------------------- - mov esi, boot_set_int_IDE - call boot_log -set_interrupts_for_IDE_controllers: - mov ax, [IDEContrProgrammingInterface] - cmp ax, 0x0180 - je .pata_ide - - cmp ax, 0x018a - jne .sata_ide -;-------------------------------------- -.pata_ide: - cmp [IDEContrRegsBaseAddr], 0 - je .end_set_interrupts - - stdcall attach_int_handler, 14, IDE_irq_14_handler, 0 - DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax - stdcall attach_int_handler, 15, IDE_irq_15_handler, 0 - DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax - jmp .enable_IDE_interrupt -;-------------------------------------- -.sata_ide: - cmp ax, 0x0185 - je .sata_ide_1 - - cmp ax, 0x018f - jne .end_set_interrupts -;-------------------------------------- -.sata_ide_1: - cmp [IDEContrRegsBaseAddr], 0 - je .end_set_interrupts - - mov ax, [IDE_Interrupt] - movzx eax, al - stdcall attach_int_handler, eax, IDE_common_irq_handler, 0 - DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [IDE_Interrupt]:1, eax -;-------------------------------------- -.enable_IDE_interrupt: - mov esi, boot_enabling_ide - call boot_log -; Enable interrupts in IDE controller for DMA - mov al, 0 - mov dx, [IDE_BAR1_val] ;0x3F4 - add dx, 2 ;0x3F6 - out dx, al - mov dx, [IDE_BAR3_val] ;0x374 - add dx, 2 ;0x376 - out dx, al -;-------------------------------------- -.end_set_interrupts: -;----------------------------------------------------------------------------- - cmp [dma_hdd], 0 - je .print_pio -.print_dma: - DEBUGF 1, "K : IDE DMA mode\n" - jmp .continue - -.print_pio: - DEBUGF 1, "K : IDE PIO mode\n" -.continue: - mov [timer_ticks_enable], 1 ; for cd driver sti -; call change_task + + call mtrr_validate jmp osloop ; Fly :) +uglobal +align 4 +ap_initialized dd 0 +endg + +ap_init_high: + mov ax, os_stack + mov bx, app_data + mov cx, app_tls + mov ss, ax + mov ds, bx + mov es, bx + mov fs, cx + mov gs, bx + xor esp, esp + mov eax, sys_proc-OS_BASE+PROC.pdt_0 + mov cr3, eax + lock inc [ap_initialized] + jmp idle_loop + + include 'unpacker.inc' align 4 @@ -1284,7 +1228,11 @@ proc setup_os_slot mov dword [edx+APPDATA.cur_dir], sysdir_path - mov [edx + APPDATA.dir_table], sys_pgdir - OS_BASE + mov [edx + APPDATA.process], sys_proc + + lea ebx, [edx+APPDATA.list] + lea ecx, [sys_proc+PROC.thr_list] + list_add_tail ebx, ecx mov eax, edx shr eax, 3 @@ -1309,18 +1257,20 @@ osloop: xchg eax, [osloop_nonperiodic_work] test eax, eax jz .no_periodic -; call [draw_pointer] + call __sys_draw_pointer call window_check_events call mouse_check_events call checkmisc call checkVga_N13 +;-------------------------------------- .no_periodic: call stack_handler call check_fdd_motor_status call check_ATAPI_device_event call check_lights_state call check_timers + jmp osloop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; @@ -1359,13 +1309,35 @@ align 4 osloop_nonperiodic_work dd ? endg -align 4 +uglobal +align 64 +idle_addr rb 64 +endg + idle_thread: sti -idle_loop: - hlt - jmp idle_loop +; The following code can be executed by all CPUs in the system. +; All other parts of the kernel do not expect multi-CPU. +; Also, APs don't even have a stack here. +; Beware. Don't do anything here. Anything at all. +idle_loop: + cmp [use_mwait_for_idle], 0 + jnz idle_loop_mwait + +idle_loop_hlt: + hlt + jmp idle_loop_hlt + +idle_loop_mwait: + mov eax, idle_addr + xor ecx, ecx + xor edx, edx + monitor + xor ecx, ecx + mov eax, 20h ; or 10h + mwait + jmp idle_loop_mwait ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1688,280 +1660,231 @@ draw_num_text: mov eax, [esp+64+8] ; background color (if given) mov edi, [esp+64+4] jmp dtext - -align 4 - -sys_setup: - -; 1=roland mpu midi base , base io address -; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus -; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave -; 5=system language, 1eng 2fi 3ger 4rus -; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave -; 8=fat32 partition in hd -; 9 -; 10 = sound dma channel -; 11 = enable lba read -; 12 = enable pci access - - - and [esp+32], dword 0 - dec ebx ; MIDI - jnz nsyse1 - cmp ecx, 0x100 - - jb nsyse1 - mov esi, 65535 - cmp esi, ecx - - jb nsyse1 - mov [midi_base], cx ;bx - mov word [mididp], cx;bx - inc cx ;bx - mov word [midisp], cx;bx - ret - +;----------------------------------------------------------------------------- iglobal midi_base dw 0 endg +;----------------------------------------------------------------------------- +align 4 +sys_setup: +; 1 = roland mpu midi base , base io address +; 2 = keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus +; 3 = not used +; 4 = not used +; 5 = system language, 1eng 2fi 3ger 4rus +; 6 = not used +; 7 = not used +; 8 = not used +; 9 = not used +; 10 = not used +; 11 = enable lba read +; 12 = enable pci access +;----------------------------------------------------------------------------- + and [esp+32], dword 0 +; F.21.1 - set MPU MIDI base port + dec ebx + jnz @f + + cmp ecx, 0x100 + jb @f + + mov esi, 65535 + cmp esi, ecx + jb @f + + mov [midi_base], cx + mov word [mididp], cx + inc cx + mov word [midisp], cx + ret +;-------------------------------------- +@@: +; F.21.2 - set keyboard layout + dec ebx + jnz @f - nsyse1: - dec ebx ; KEYBOARD - jnz nsyse2 mov edi, [TASK_BASE] mov eax, [edi+TASKDATA.mem_start] add eax, edx - +; 1 = normal layout dec ecx - jnz kbnobase + jnz .shift + mov ebx, keymap mov ecx, 128 call memmove ret - kbnobase: +;-------------------------------------- +.shift: +; 2 = layout at pressed Shift dec ecx - jnz kbnoshift + jnz .alt mov ebx, keymap_shift mov ecx, 128 call memmove ret - kbnoshift: +;-------------------------------------- +.alt: +; 3 = layout at pressed Alt dec ecx - jnz kbnoalt + jnz .country + mov ebx, keymap_alt mov ecx, 128 call memmove ret - kbnoalt: +;-------------------------------------- +.country: +; country identifier sub ecx, 6 - jnz kbnocountry + jnz .error + mov word [keyboard], dx ret - kbnocountry: - mov [esp+32], dword 1 - ret - nsyse2: - dec ebx ; CD - jnz nsyse4 +;-------------------------------------- +@@: +; F.21.5 - set system language + sub ebx, 3 + jnz @f - test ecx, ecx - jz nosesl - - cmp ecx, 4 - ja nosesl - mov [cd_base], cl - - dec ecx - jnz noprma - mov eax, [hd_address_table] - mov [cdbase], eax ;0x1f0 - mov [cdid], 0xa0 -noprma: - - dec ecx - jnz noprsl - mov eax, [hd_address_table] - mov [cdbase], eax ;0x1f0 - mov [cdid], 0xb0 -noprsl: - dec ecx - jnz nosema - mov eax, [hd_address_table+16] - mov [cdbase], eax ;0x170 - mov [cdid], 0xa0 -nosema: - dec ecx - jnz nosesl - mov eax, [hd_address_table+16] - mov [cdbase], eax ;0x170 - mov [cdid], 0xb0 -nosesl: - ret - -iglobal -cd_base db 0 - -endg - nsyse4: - - sub ebx, 2 ; SYSTEM LANGUAGE - jnz nsyse5 mov [syslang], ecx ret - nsyse5: - - sub ebx, 2 ; HD BASE - obsolete - jnz nsyse7 - - nosethd: - ret - -nsyse7: - -; cmp eax,8 ; HD PARTITION - obsolete - dec ebx - jnz nsyse8 - ret - -nsyse8: -; cmp eax,11 ; ENABLE LBA READ +;-------------------------------------- +@@: +; F.21.11 - enable/disable low-level access to HD and ecx, 1 - sub ebx, 3 - jnz no_set_lba_read + sub ebx, 6 + jnz @f + mov [lba_read_enabled], ecx ret - -no_set_lba_read: -; cmp eax,12 ; ENABLE PCI ACCESS +;-------------------------------------- +@@: +; F.21.12 - enable/disable low-level access to PCI dec ebx - jnz sys_setup_err + jnz .error + mov [pci_access_enabled], ecx ret - -sys_setup_err: +;-------------------------------------- +.error: or [esp+32], dword -1 ret - +;----------------------------------------------------------------------------- align 4 - sys_getsetup: - -; 1=roland mpu midi base , base io address -; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus -; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave -; 5=system language, 1eng 2fi 3ger 4rus -; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave -; 8=fat32 partition in hd -; 9=get hs timer tic - -; cmp eax,1 +; 1 = roland mpu midi base , base io address +; 2 = keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus +; 3 = not used +; 4 = not used +; 5 = system language, 1eng 2fi 3ger 4rus +; 6 = not used +; 7 = not used +; 8 = not used +; 9 = get hs timer tic +; 10 = not used +; 11 = get the state "lba read" +; 12 = get the state "pci access" +;----------------------------------------------------------------------------- +; F.26.1 - get MPU MIDI base port dec ebx - jnz ngsyse1 + jnz @f + movzx eax, [midi_base] mov [esp+32], eax ret -ngsyse1: -; cmp eax,2 +;-------------------------------------- +@@: +; F.26.2 - get keyboard layout dec ebx - jnz ngsyse2 + jnz @f mov edi, [TASK_BASE] mov ebx, [edi+TASKDATA.mem_start] add ebx, edx - -; cmp ebx,1 +; 1 = normal layout dec ecx - jnz kbnobaseret + jnz .shift + mov eax, keymap mov ecx, 128 call memmove ret -kbnobaseret: -; cmp ebx,2 +;-------------------------------------- +.shift: +; 2 = layout with pressed Shift dec ecx - jnz kbnoshiftret + jnz .alt mov eax, keymap_shift mov ecx, 128 call memmove ret -kbnoshiftret: -; cmp ebx,3 +;-------------------------------------- +.alt: +; 3 = layout with pressed Alt dec ecx - jne kbnoaltret + jne .country mov eax, keymap_alt mov ecx, 128 call memmove ret -kbnoaltret: -; cmp ebx,9 +;-------------------------------------- +.country: +; 9 = country identifier sub ecx, 6 - jnz ngsyse2 + jnz .error + movzx eax, word [keyboard] mov [esp+32], eax ret +;-------------------------------------- +@@: +; F.26.5 - get system language + sub ebx, 3 + jnz @f - -ngsyse2: -; cmp eax,3 - dec ebx - jnz ngsyse3 - movzx eax, [cd_base] - mov [esp+32], eax - ret -ngsyse3: -; cmp eax,5 - sub ebx, 2 - jnz ngsyse5 mov eax, [syslang] mov [esp+32], eax ret -ngsyse5: -; cmp eax,7 +;-------------------------------------- +@@: +; F.26.9 - get the value of the time counter + sub ebx, 4 + jnz @f + + mov eax, [timer_ticks] + mov [esp+32], eax + ret +;-------------------------------------- +@@: +; F.26.11 - Find out whether low-level HD access is enabled sub ebx, 2 - jnz ngsyse7 - xor eax, eax - mov [esp+32], eax - ret -ngsyse7: -; cmp eax,8 - dec ebx - jnz ngsyse8 - mov eax, [fat32part] - mov [esp+32], eax - ret -ngsyse8: -; cmp eax,9 - dec ebx - jnz ngsyse9 - mov eax, [timer_ticks];[0xfdf0] - mov [esp+32], eax - ret -ngsyse9: -; cmp eax,11 - sub ebx, 2 - jnz ngsyse11 + jnz @f + mov eax, [lba_read_enabled] mov [esp+32], eax ret -ngsyse11: -; cmp eax,12 +;-------------------------------------- +@@: +; F.26.12 - Find out whether low-level PCI access is enabled dec ebx - jnz ngsyse12 + jnz .error + mov eax, [pci_access_enabled] mov [esp+32], eax ret -ngsyse12: - mov [esp+32], dword 1 +;-------------------------------------- +.error: + or [esp+32], dword -1 ret - - +;----------------------------------------------------------------------------- get_timer_ticks: mov eax, [timer_ticks] ret - +;----------------------------------------------------------------------------- iglobal align 4 mousefn dd msscreen, mswin, msbutton, msset @@ -1970,7 +1893,7 @@ mousefn dd msscreen, mswin, msbutton, msset dd app_delete_cursor dd msz endg - +;----------------------------------------------------------------------------- readmousepos: ; eax=0 screen relative @@ -2443,27 +2366,15 @@ sysfn_minimize: ; 18.10 = minimize window ;------------------------------------------------------------------------------ align 4 sysfn_getdiskinfo: ; 18.11 = get disk info table -; cmp ecx,1 dec ecx - jnz full_table - small_table: - call for_all_tables - mov ecx, 10 - cld - rep movsb - ret - for_all_tables: + jnz .exit +.small_table: mov edi, edx mov esi, DRIVE_DATA - ret - full_table: -; cmp ecx,2 - dec ecx - jnz exit_for_anyone - call for_all_tables - mov ecx, DRIVE_DATA_SIZE/4 + mov ecx, DRIVE_DATA_SIZE ;10 cld - rep movsd + rep movsb +.exit: ret ;------------------------------------------------------------------------------ sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) @@ -2495,10 +2406,10 @@ sysfn_centermouse: ; 18.15 = mouse centered ;* mouse centered - start code- Mario79 ;mouse_centered: ; push eax - mov eax, [_display.width] + mov eax, [Screen_Max_X] shr eax, 1 mov [MOUSE_X], ax - mov eax, [_display.height] + mov eax, [Screen_Max_Y] shr eax, 1 mov [MOUSE_Y], ax call wakeup_osloop @@ -2540,12 +2451,13 @@ sysfn_mouse_acceleration: ; 18.19 = set/get mouse features ; cmp ecx,4 ; set mouse pointer position dec ecx jnz .set_mouse_button - cmp dx, word[_display.height] - jae .end + cmp dx, word[Screen_Max_Y] + ja .end rol edx, 16 - cmp dx, word[_display.width] - jae .end + cmp dx, word[Screen_Max_X] + ja .end mov [MOUSE_X], edx + mov [mouse_active], 1 call wakeup_osloop ret .set_mouse_button: @@ -2631,7 +2543,9 @@ sysfn_set_screen_sizes: mov eax, ecx mov ecx, [_display.pitch] mov [_display.width], eax + dec eax mov [_display.height], edx + dec edx ; eax - new Screen_Max_X ; edx - new Screen_Max_Y mov [do_not_touch_winmap], 1 @@ -2968,22 +2882,22 @@ nosb8: jnz nosb9 ; ecx = [left]*65536 + [right] ; edx = [top]*65536 + [bottom] - mov eax, [_display.width] - mov ebx, [_display.height] + mov eax, [Screen_Max_X] + mov ebx, [Screen_Max_Y] ; check [right] cmp cx, ax - jae .exit + ja .exit ; check [left] ror ecx, 16 cmp cx, ax - jae .exit + ja .exit ; check [bottom] cmp dx, bx - jae .exit + ja .exit ; check [top] ror edx, 16 cmp dx, bx - jae .exit + ja .exit movzx eax, cx ; [left] movzx ebx, dx ; [top] @@ -3021,8 +2935,8 @@ force_redraw_background: and [draw_data+32 + RECT.left], 0 and [draw_data+32 + RECT.top], 0 push eax ebx - mov eax, [_display.width] - mov ebx, [_display.height] + mov eax, [Screen_Max_X] + mov ebx, [Screen_Max_Y] mov [draw_data+32 + RECT.right], eax mov [draw_data+32 + RECT.bottom], ebx pop ebx eax @@ -3096,7 +3010,9 @@ sys_getkey: jne .finish cmp [KEY_COUNT], byte 0 je .finish - movzx eax, byte [KEY_BUFF] + movzx ax, byte [KEY_BUFF + 120 + 2] + shl eax, 8 + mov al, byte [KEY_BUFF] shl eax, 8 push eax dec byte [KEY_COUNT] @@ -3106,6 +3022,9 @@ sys_getkey: mov eax, KEY_BUFF + 1 mov ebx, KEY_BUFF call memmove + add eax, 120 + 2 + add ebx, 120 + 2 + call memmove pop eax ;-------------------------------------- align 4 @@ -3207,7 +3126,8 @@ sys_cpuusage: mov edx, 0x100000*16 cmp ecx, 1 shl 5 je .os_mem - mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size] + mov edx, [SLOT_BASE+ecx*8+APPDATA.process] + mov edx, [edx+PROC.mem_used] mov eax, std_application_base_address .os_mem: stosd @@ -3378,9 +3298,9 @@ sys_redrawstat: add edx, draw_data - CURRENT_TASK mov [edx + RECT.left], 0 mov [edx + RECT.top], 0 - mov eax, [_display.width] + mov eax, [Screen_Max_X] mov [edx + RECT.right], eax - mov eax, [_display.height] + mov eax, [Screen_Max_Y] mov [edx + RECT.bottom], eax srl1: @@ -3679,7 +3599,7 @@ markz: cmp [edx+TASKDATA.state], 9 jz .nokill lea edx, [(edx-(CURRENT_TASK and 1FFFFFFFh))*8+SLOT_BASE] - cmp [edx+APPDATA.dir_table], sys_pgdir - OS_BASE + cmp [edx+APPDATA.process], sys_proc jz .nokill call request_terminate jmp .common @@ -4703,113 +4623,39 @@ putimage_get16bpp: ; ret ;----------------------------------------------------------------------------- align 4 -kb_read: - - push ecx edx - - mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's - kr_loop: - in al, 0x64 - test al, 1 - jnz kr_ready - loop kr_loop - mov ah, 1 - jmp kr_exit - kr_ready: - push ecx - mov ecx, 32 - kr_delay: - loop kr_delay - pop ecx - in al, 0x60 - xor ah, ah - kr_exit: - - pop edx ecx - - ret -;----------------------------------------------------------------------------- -align 4 -kb_write: +kb_write_wait_ack: push ecx edx mov dl, al -; mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's -; kw_loop1: -; in al,0x64 -; test al,0x20 -; jz kw_ok1 -; loop kw_loop1 -; mov ah,1 -; jmp kw_exit -; kw_ok1: - in al, 0x60 mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's - kw_loop: +.wait_output_ready: in al, 0x64 test al, 2 - jz kw_ok - loop kw_loop + jz @f + loop .wait_output_ready mov ah, 1 - jmp kw_exit - kw_ok: + jmp .nothing +@@: mov al, dl out 0x60, al - mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's - kw_loop3: - in al, 0x64 - test al, 2 - jz kw_ok3 - loop kw_loop3 - mov ah, 1 - jmp kw_exit - kw_ok3: - mov ah, 8 - kw_loop4: - mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's - kw_loop5: + mov ecx, 0xfffff; last 0xffff, new value in view of fast CPU's +.wait_ack: in al, 0x64 test al, 1 - jnz kw_ok4 - loop kw_loop5 - dec ah - jnz kw_loop4 - kw_ok4: + jnz @f + loop .wait_ack + mov ah, 1 + jmp .nothing +@@: + in al, 0x60 xor ah, ah - kw_exit: +.nothing: pop edx ecx ret ;----------------------------------------------------------------------------- -align 4 -kb_cmd: - - mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's - c_wait: - in al, 0x64 - test al, 2 - jz c_send - loop c_wait - jmp c_error - c_send: - mov al, bl - out 0x64, al - mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's - c_accept: - in al, 0x64 - test al, 2 - jz c_ok - loop c_accept - c_error: - mov ah, 1 - jmp c_exit - c_ok: - xor ah, ah - c_exit: - ret - setmouse: ; set mousepicture -pointer ; ps2 mouse enable @@ -4947,9 +4793,9 @@ endg jnz @f mov word [msg_board_pos+2], (42*6) add word [msg_board_pos], 10 - mov ax, word [_display.height] + mov ax, word [Screen_Max_Y] cmp word [msg_board_pos], ax - jb @f + jbe @f mov word [msg_board_pos], 10 @@: ; // end if @@ -5166,14 +5012,14 @@ sys_gs: ; direct screen access .1: ; resolution - mov eax, [_display.width] + mov eax, [Screen_Max_X] shl eax, 16 - mov ax, word [_display.height] + mov ax, word [Screen_Max_Y] add eax, 0x00010001 mov [esp+32], eax ret .2: ; bits per pixel - mov eax, [_display.bpp] + mov eax, [_display.bits_per_pixel] mov [esp+32], eax ret .3: ; bytes per scanline @@ -5254,43 +5100,66 @@ syscall_drawrect: ; DrawRect align 4 syscall_getscreensize: ; GetScreenSize - mov ax, word [_display.width] + mov ax, word [Screen_Max_X] shl eax, 16 - mov ax, word [_display.height] + mov ax, word [Screen_Max_Y] mov [esp + 32], eax ret - +;----------------------------------------------------------------------------- align 4 +syscall_cdaudio: +; ECX - position of CD/DVD-drive +; 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. + cmp ecx, 11 + ja .exit -syscall_cdaudio: ; CD + mov eax, ecx + shr eax, 2 + lea eax, [eax*5] + mov al, [eax+DRIVE_DATA+1] + + push ecx ebx + mov ebx, ecx + and ebx, 11b + shl ebx, 1 + mov cl, 6 + sub cl, bl + shr al, cl + test al, 2 ; it's not an ATAPI device + pop ebx ecx + + jz .exit cmp ebx, 4 - jb .audio - jz .eject + je .eject + cmp ebx, 5 - jnz .ret + je .load +;-------------------------------------- +.exit: + ret +;-------------------------------------- .load: call .reserve call LoadMedium - ;call .free jmp .free -; ret +;-------------------------------------- .eject: call .reserve call clear_CD_cache call allow_medium_removal call EjectMedium -; call .free jmp .free -; ret -.audio: - call sys_cd_audio - mov [esp+36-4], eax -.ret: - ret - +;-------------------------------------- .reserve: call reserve_cd + + mov ebx, ecx + inc ebx + mov [cdpos], ebx + mov eax, ecx shr eax, 1 and eax, 1 @@ -5300,32 +5169,19 @@ syscall_cdaudio: ; CD and eax, 1 mov [DiskNumber], al call reserve_cd_channel - and ebx, 3 - inc ebx - mov [cdpos], ebx - add ebx, ebx - mov cl, 8 - sub cl, bl - mov al, [DRIVE_DATA+1] - shr al, cl - test al, 2 - jz .free;.err ret +;-------------------------------------- .free: call free_cd_channel and [cd_status], 0 ret -.err: - call .free -; pop eax - ret ;----------------------------------------------------------------------------- align 4 syscall_getpixel_WinMap: ; GetPixel WinMap - cmp ebx, [_display.width] - jb @f - cmp ecx, [_display.height] - jb @f + cmp ebx, [Screen_Max_X] + jbe @f + cmp ecx, [Screen_Max_Y] + jbe @f xor eax, eax jmp .store ;-------------------------------------- @@ -5342,7 +5198,8 @@ align 4 ;----------------------------------------------------------------------------- align 4 syscall_getpixel: ; GetPixel - mov ecx, [_display.width] + mov ecx, [Screen_Max_X] + inc ecx xor edx, edx mov eax, ebx div ecx @@ -5587,6 +5444,8 @@ set_screen: pushfd cli + mov [Screen_Max_X], eax + mov [Screen_Max_Y], edx mov [_display.pitch], ecx mov [screen_workarea.right], eax @@ -5628,8 +5487,8 @@ set_screen: call repos_windows xor eax, eax xor ebx, ebx - mov ecx, [_display.width] - mov edx, [_display.height] + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] call calculatescreen pop edi pop esi @@ -5713,10 +5572,41 @@ system_shutdown: ; shut down the system ret @@: call stop_all_services - movi eax, 3 - call sys_cd_audio yes_shutdown_param: +; Shutdown other CPUs, if initialized + cmp [ap_initialized], 0 + jz .no_shutdown_cpus + mov edi, [LAPIC_BASE] + add edi, 300h + mov esi, smpt+4 + mov ebx, [cpu_count] + dec ebx +.shutdown_cpus_loop: + lodsd + push esi + xor esi, esi + inc esi + shl eax, 24 + mov [edi+10h], eax +; assert INIT IPI + mov dword [edi], 0C500h + call delay_ms +@@: + test dword [edi], 1000h + jnz @b +; deassert INIT IPI + mov dword [edi], 8500h + call delay_ms +@@: + test dword [edi], 1000h + jnz @b +; don't send STARTUP IPI: let other CPUs be in wait-for-startup state + pop esi + dec ebx + jnz .shutdown_cpus_loop +.no_shutdown_cpus: + cli if ~ defined extended_primary_loader @@ -5740,22 +5630,6 @@ end if call IRQ_mask_all -if 0 - mov word [OS_BASE+0x467+0], pr_mode_exit - mov word [OS_BASE+0x467+2], 0x1000 - - mov al, 0x0F - out 0x70, al - mov al, 0x05 - out 0x71, al - - mov al, 0xFE - out 0x64, al - - hlt - jmp $-1 - -else cmp byte [OS_BASE + 0x9030], 2 jnz no_acpi_power_off @@ -5901,21 +5775,6 @@ do_acpi_power_off: jmp $ -no_acpi_power_off: - mov word [OS_BASE+0x467+0], pr_mode_exit - mov word [OS_BASE+0x467+2], 0x1000 - - mov al, 0x0F - out 0x70, al - mov al, 0x05 - out 0x71, al - - mov al, 0xFE - out 0x64, al - - hlt - jmp $-1 - scan_rsdp: add eax, OS_BASE .s: @@ -5938,7 +5797,33 @@ scan_rsdp: stc .ok: ret -end if + +no_acpi_power_off: + call create_trampoline_pgmap + mov cr3, eax + jmp become_real+0x10000 +iglobal +align 4 +realmode_gdt: +; selector 0 - not used + dw 23 + dd realmode_gdt-OS_BASE + dw 0 +; selector 8 - code from 1000:0000 to 1000:FFFF + dw 0FFFFh + dw 0 + db 1 + db 10011011b + db 00000000b + db 0 +; selector 10h - data from 1000:0000 to 1000:FFFF + dw 0FFFFh + dw 0 + db 1 + db 10010011b + db 00000000b + db 0 +endg if ~ lang eq sp diff16 "end of .text segment",0,$ diff --git a/kernel/branches/Kolibri-acpi/kernel32.inc b/kernel/branches/Kolibri-acpi/kernel32.inc index 141766885d..e1b871a132 100644 --- a/kernel/branches/Kolibri-acpi/kernel32.inc +++ b/kernel/branches/Kolibri-acpi/kernel32.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/kernelsp.inc b/kernel/branches/Kolibri-acpi/kernelsp.inc index 661889dbb5..bd2d5c40ec 100644 --- a/kernel/branches/Kolibri-acpi/kernelsp.inc +++ b/kernel/branches/Kolibri-acpi/kernelsp.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/macros.inc b/kernel/branches/Kolibri-acpi/macros.inc index 3f8d590d6f..0295709bb4 100644 --- a/kernel/branches/Kolibri-acpi/macros.inc +++ b/kernel/branches/Kolibri-acpi/macros.inc @@ -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. diff --git a/kernel/branches/Kolibri-acpi/makefile b/kernel/branches/Kolibri-acpi/makefile index 2e25eb2f73..c279227726 100644 --- a/kernel/branches/Kolibri-acpi/makefile +++ b/kernel/branches/Kolibri-acpi/makefile @@ -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 diff --git a/kernel/branches/Kolibri-acpi/network/ARP.inc b/kernel/branches/Kolibri-acpi/network/ARP.inc index 2fb07730ec..faf4c8c002 100644 --- a/kernel/branches/Kolibri-acpi/network/ARP.inc +++ b/kernel/branches/Kolibri-acpi/network/ARP.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; 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 diff --git a/kernel/branches/Kolibri-acpi/network/IPv4.inc b/kernel/branches/Kolibri-acpi/network/IPv4.inc index b3c582486d..18acc53d97 100644 --- a/kernel/branches/Kolibri-acpi/network/IPv4.inc +++ b/kernel/branches/Kolibri-acpi/network/IPv4.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; 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 diff --git a/kernel/branches/Kolibri-acpi/network/PPPoE.inc b/kernel/branches/Kolibri-acpi/network/PPPoE.inc index c3f9e533e6..f67167b4c3 100644 --- a/kernel/branches/Kolibri-acpi/network/PPPoE.inc +++ b/kernel/branches/Kolibri-acpi/network/PPPoE.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/network/ethernet.inc b/kernel/branches/Kolibri-acpi/network/ethernet.inc index 05fa7e6484..b688543407 100644 --- a/kernel/branches/Kolibri-acpi/network/ethernet.inc +++ b/kernel/branches/Kolibri-acpi/network/ethernet.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; 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 diff --git a/kernel/branches/Kolibri-acpi/network/icmp.inc b/kernel/branches/Kolibri-acpi/network/icmp.inc index 165f45b26c..fea37bec91 100644 --- a/kernel/branches/Kolibri-acpi/network/icmp.inc +++ b/kernel/branches/Kolibri-acpi/network/icmp.inc @@ -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" diff --git a/kernel/branches/Kolibri-acpi/network/queue.inc b/kernel/branches/Kolibri-acpi/network/queue.inc index d919509e2c..09955e5639 100644 --- a/kernel/branches/Kolibri-acpi/network/queue.inc +++ b/kernel/branches/Kolibri-acpi/network/queue.inc @@ -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 } \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/network/socket.inc b/kernel/branches/Kolibri-acpi/network/socket.inc index 12ddd6e876..8da38da169 100644 --- a/kernel/branches/Kolibri-acpi/network/socket.inc +++ b/kernel/branches/Kolibri-acpi/network/socket.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Part of the TCP/IP network stack for KolibriOS ;; @@ -293,6 +293,7 @@ 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 diff --git a/kernel/branches/Kolibri-acpi/network/stack.inc b/kernel/branches/Kolibri-acpi/network/stack.inc index 20ca64e73f..6f121aa799 100644 --- a/kernel/branches/Kolibri-acpi/network/stack.inc +++ b/kernel/branches/Kolibri-acpi/network/stack.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/network/tcp.inc b/kernel/branches/Kolibri-acpi/network/tcp.inc index 4675e18fc3..82f29f244c 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Part of the TCP/IP network stack for KolibriOS ;; @@ -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 diff --git a/kernel/branches/Kolibri-acpi/network/tcp_input.inc b/kernel/branches/Kolibri-acpi/network/tcp_input.inc index d618461912..79625d160c 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_input.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_input.inc @@ -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" diff --git a/kernel/branches/Kolibri-acpi/network/tcp_subr.inc b/kernel/branches/Kolibri-acpi/network/tcp_subr.inc index 91514a8d29..63ef16b97b 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_subr.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_subr.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Part of the TCP/IP network stack for KolibriOS ;; @@ -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 diff --git a/kernel/branches/Kolibri-acpi/network/tcp_timer.inc b/kernel/branches/Kolibri-acpi/network/tcp_timer.inc index 522a055e81..1b591e204a 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_timer.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_timer.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc b/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc index 65128da742..e26944022b 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc @@ -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: diff --git a/kernel/branches/Kolibri-acpi/network/udp.inc b/kernel/branches/Kolibri-acpi/network/udp.inc index 3640b765ea..6401563328 100644 --- a/kernel/branches/Kolibri-acpi/network/udp.inc +++ b/kernel/branches/Kolibri-acpi/network/udp.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; 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 diff --git a/kernel/branches/Kolibri-acpi/video/blitter.inc b/kernel/branches/Kolibri-acpi/video/blitter.inc index 6fec38ab22..0d15b4833b 100644 --- a/kernel/branches/Kolibri-acpi/video/blitter.inc +++ b/kernel/branches/Kolibri-acpi/video/blitter.inc @@ -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 ? diff --git a/kernel/branches/Kolibri-acpi/video/cursors.inc b/kernel/branches/Kolibri-acpi/video/cursors.inc index 8839830f09..9a91144f14 100644 --- a/kernel/branches/Kolibri-acpi/video/cursors.inc +++ b/kernel/branches/Kolibri-acpi/video/cursors.inc @@ -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 diff --git a/kernel/branches/Kolibri-acpi/video/vesa20.inc b/kernel/branches/Kolibri-acpi/video/vesa20.inc index 1f84201ea8..16d43bcc79 100644 --- a/kernel/branches/Kolibri-acpi/video/vesa20.inc +++ b/kernel/branches/Kolibri-acpi/video/vesa20.inc @@ -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 ;; ;; ;; ;; VESA20.INC ;; @@ -19,93 +19,130 @@ $Revision$ - -; If you're planning to write your own video driver I suggest -; you replace the VESA12.INC file and see those instructions. - - -;----------------------------------------------------------------------------- -; getpixel -; -; in: -; eax = x coordinate -; ebx = y coordinate -; -; ret: -; ecx = 00 RR GG BB -;----------------------------------------------------------------------------- +uglobal align 4 -getpixel: - push eax ebx edx edi - call dword [GETPIXEL] - pop edi edx ebx eax - ret -;----------------------------------------------------------------------------- + bgr_cur_line rd 1920 ; maximum width of screen + bgr_next_line rd 1920 +endg + +iglobal align 4 -Vesa20_getpixel24: + overlapping_of_points_ptr dd overlapping_of_points +endg + + +;----------------------------------------------------------------------------- ; eax = x ; ebx = y -;-------------------------------------- -; check for hardware cursor + +align 4 +Vesa20_getpixel16: + + ; check for hardware cursor cmp [_display.select_cursor], select_cursor je @f cmp [_display.select_cursor], 0 jne .no_mouseunder -;-------------------------------------- + @@: + + ; check mouse area for putpixel + test ecx, 0x04000000 ; don't load to mouseunder area + jnz .no_mouseunder + call [_display.check_m_pixel] + test ecx, ecx ; 0xff000000 + jnz @f + + .no_mouseunder: +; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier + mov ebx, [BPSLine_calc_area+ebx*4] + lea edi, [eax*2] ; edi = x*2 + add edi, ebx ; edi = x*2+(y*y multiplier) + + movzx ecx, word[LFB_BASE+edi] + shl ecx, 3 + ror ecx, 8 + shl cx, 2 + ror ecx, 8 + shl cl, 3 + rol ecx, 16 + @@: + and ecx, 0x00ffffff + ret + +;----------------------------------------------------------------------------- +; eax = x +; ebx = y + align 4 -@@: -; check mouse area for putpixel +Vesa20_getpixel24: + + ; check for hardware cursor + cmp [_display.select_cursor], select_cursor + je @f + cmp [_display.select_cursor], 0 + jne .no_mouseunder + @@: + + ; check mouse area for putpixel test ecx, 0x04000000 ; don't load to mouseunder area jnz .no_mouseunder call [_display.check_m_pixel] - test ecx, ecx ;0xff000000 + test ecx, ecx ; 0xff000000 jnz @f -;-------------------------------------- -align 4 -.no_mouseunder: -;-------------------------------------- + + .no_mouseunder: ; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier mov ebx, [BPSLine_calc_area+ebx*4] - lea edi, [eax+eax*2]; edi = x*3 + lea edi, [eax+eax*2] ; edi = x*3 add edi, ebx ; edi = x*3+(y*y multiplier) + mov ecx, [LFB_BASE+edi] -;-------------------------------------- -align 4 -@@: - and ecx, 0xffffff + @@: + and ecx, 0x00ffffff ret + ;----------------------------------------------------------------------------- +; eax = x +; ebx = y + align 4 Vesa20_getpixel32: -;-------------------------------------- -; check for hardware cursor + + ; check for hardware cursor cmp [_display.select_cursor], select_cursor je @f cmp [_display.select_cursor], 0 jne .no_mouseunder -;-------------------------------------- -align 4 -@@: -; check mouse area for putpixel + @@: + + ; check mouse area for putpixel test ecx, 0x04000000 ; don't load to mouseunder area jnz .no_mouseunder call [_display.check_m_pixel] - test ecx, ecx ;0xff000000 + test ecx, ecx ; 0xff000000 jnz @f -;-------------------------------------- -align 4 -.no_mouseunder: -;-------------------------------------- + + .no_mouseunder: ; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier mov ebx, [BPSLine_calc_area+ebx*4] - lea edi, [ebx+eax*4]; edi = x*4+(y*y multiplier) + lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) + mov ecx, [LFB_BASE+edi] -;-------------------------------------- -align 4 -@@: - and ecx, 0xffffff + @@: + and ecx, 0x00ffffff ret + ;----------------------------------------------------------------------------- +; ebx = pointer +; ecx = size [x|y] +; edx = coordinates [x|y] +; ebp = pointer to 'get' function +; esi = pointer to 'init' function +; edi = parameter for 'get' function + +align 16 +vesa20_putimage: + virtual at esp putimg: .real_sx dd ? @@ -134,15 +171,7 @@ virtual at esp .ret_addr dd ? .arg_0 dd ? end virtual -;----------------------------------------------------------------------------- -align 16 -; ebx = pointer -; ecx = size [x|y] -; edx = coordinates [x|y] -; ebp = pointer to 'get' function -; esi = pointer to 'init' function -; edi = parameter for 'get' function -vesa20_putimage: + pushad sub esp, putimg.stack_data ; save pointer to image @@ -168,45 +197,34 @@ vesa20_putimage: add ebx, [putimg.image_cy] mov [putimg.abs_cy], ebx ; real_sx = MIN(wnd_sx-image_cx, image_sx); - mov ebx, [eax-twdw + WDATA.box.width]; ebx = wnd_sx -; \begin{diamond}[20.08.2006] -; note that WDATA.box.width is one pixel less than real window x-size - inc ebx -; \end{diamond}[20.08.2006] + mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx + inc ebx ; WDATA.box.width is one pixel less than real window x-size sub ebx, [putimg.image_cx] ja @f add esp, putimg.stack_data popad ret -;-------------------------------------- -align 4 -@@: + + @@: cmp ebx, [putimg.image_sx] jbe .end_x mov ebx, [putimg.image_sx] -;-------------------------------------- -align 4 -.end_x: + .end_x: mov [putimg.real_sx], ebx ; init real_sy - mov ebx, [eax-twdw + WDATA.box.height]; ebx = wnd_sy -; \begin{diamond}[20.08.2006] + mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy inc ebx -; \end{diamond}[20.08.2006] sub ebx, [putimg.image_cy] ja @f add esp, putimg.stack_data popad ret -;-------------------------------------- -align 4 -@@: + + @@: cmp ebx, [putimg.image_sy] jbe .end_y mov ebx, [putimg.image_sy] -;-------------------------------------- -align 4 -.end_y: + .end_y: mov [putimg.real_sy], ebx ; line increment mov eax, [putimg.image_sx] @@ -218,13 +236,13 @@ align 4 add eax, [putimg.arg_0] mov [putimg.line_increment], eax ; winmap new line increment - mov eax, [_display.width] + mov eax, [Screen_Max_X] + inc eax sub eax, [putimg.real_sx] mov [putimg.winmap_newline], eax ; screen new line increment mov eax, [_display.pitch] - mov ebx, [_display.bpp] - shr ebx, 3 + mov ebx, [_display.bytes_per_pixel] imul ecx, ebx sub eax, ecx mov [putimg.screen_newline], eax @@ -235,67 +253,268 @@ align 4 ; imul edx, [BytesPerScanLine] mov edx, [BPSLine_calc_area+edx*4] mov eax, [putimg.abs_cx] -; movzx ebx, byte [ScreenBPP] -; shr ebx, 3 imul eax, ebx add edx, eax ; pointer to pixel map mov eax, [putimg.abs_cy] +; imul eax, [Screen_Max_X] +; add eax, [putimg.abs_cy] mov eax, [d_width_calc_area + eax*4] add eax, [putimg.abs_cx] add eax, [_WinMapAddress] xchg eax, ebp -;-------------------------------------- + mov ecx, [putimg.real_sx] add ecx, [putimg.abs_cx] mov [putimg.real_sx_and_abs_cx], ecx mov ecx, [putimg.real_sy] add ecx, [putimg.abs_cy] mov [putimg.real_sy_and_abs_cy], ecx -;-------------------------------------- + ; get process number mov ebx, [CURRENT_TASK] - cmp byte [_display.bpp], 32 + + cmp byte [_display.bits_per_pixel], 16 + je put_image_end_16 + cmp byte [_display.bits_per_pixel], 24 + je put_image_end_24 + cmp byte [_display.bits_per_pixel], 32 je put_image_end_32 -;-------------------------------------- -put_image_end_24: + +;------------------------------------------------------------------------------ + +put_image_end_16: + mov edi, [putimg.real_sy] -;-------------------------------------- + +; check for hardware cursor + mov ecx, [_display.select_cursor] + cmp ecx, select_cursor + je put_image_end_16_new + cmp ecx, 0 + je put_image_end_16_old + .new_line: + mov ecx, [putimg.real_sx] + .new_x: + push [putimg.edi] + mov eax, [putimg.ebp+4] + call eax + cmp [ebp], bl + jne .skip +; convert to 16 bpp and store to LFB + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + mov [LFB_BASE+edx], ax + .skip: + add edx, 2 + inc ebp + dec ecx + jnz .new_x + + add esi, [putimg.line_increment] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] + + cmp [putimg.ebp], putimage_get1bpp + jz .correct + cmp [putimg.ebp], putimage_get2bpp + jz .correct + cmp [putimg.ebp], putimage_get4bpp + jnz @f + .correct: + mov eax, [putimg.edi] + mov byte [eax], 80h + @@: + dec edi + jnz .new_line + .finish: + add esp, putimg.stack_data + popad + ret + +;------------------------------------------------------------------------------ + +align 4 +put_image_end_16_old: + + .new_line: + mov ecx, [putimg.real_sx] + .new_x: + push [putimg.edi] + mov eax, [putimg.ebp+4] + call eax + cmp [ebp], bl + jne .skip + + push ecx + neg ecx + add ecx, [putimg.real_sx_and_abs_cx + 4] + shl ecx, 16 + add ecx, [putimg.real_sy_and_abs_cy + 4] + sub ecx, edi + +; check mouse area for putpixel + call check_mouse_area_for_putpixel + pop ecx + +; convert to 16 bpp and store to LFB +;; and eax, 00000000111110001111110011111000b +;; shr ah, 2 +;; shr ax, 3 +;; ror eax, 8 +;; add al, ah +;; rol eax, 8 + mov [LFB_BASE+edx], ax + .skip: + inc edx + inc edx + inc ebp + dec ecx + jnz .new_x + + add esi, [putimg.line_increment] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] + + cmp [putimg.ebp], putimage_get1bpp + jz .correct + cmp [putimg.ebp], putimage_get2bpp + jz .correct + cmp [putimg.ebp], putimage_get4bpp + jnz @f + .correct: + mov eax, [putimg.edi] + mov byte [eax], 80h + @@: + dec edi + jnz .new_line + jmp put_image_end_16.finish + +;------------------------------------------------------------------------------ + +align 4 +put_image_end_16_new: + + .new_line: + mov ecx, [putimg.real_sx] + + .new_x: + push [putimg.edi] + mov eax, [putimg.ebp+4] + call eax + + cmp [ebp], bl + jne .skip + + push ecx + .sh: + neg ecx + add ecx, [putimg.real_sx_and_abs_cx + 4] + +; check for X + cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] + jae .no_mouse_area + + sub cx, [X_UNDER_subtraction_CUR_hot_x] + jb .no_mouse_area + + shl ecx, 16 + add ecx, [putimg.real_sy_and_abs_cy + 4] + sub ecx, edi + +; check for Y + cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] + jae .no_mouse_area + + sub cx, [Y_UNDER_subtraction_CUR_hot_y] + jb .no_mouse_area + +; check mouse area for putpixel + call check_mouse_area_for_putpixel_new.1 + cmp ecx, -1 ; SHIT HAPPENS? + jne .no_mouse_area + + mov ecx, [esp] + jmp .sh + + .no_mouse_area: + pop ecx +; convert to 16 bpp and store to LFB + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + mov [LFB_BASE+edx], ax + + .skip: + add edx, 2 + inc ebp + dec ecx + jnz .new_x + + add esi, [putimg.line_increment] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] + + cmp [putimg.ebp], putimage_get1bpp + jz .correct + cmp [putimg.ebp], putimage_get2bpp + jz .correct + cmp [putimg.ebp], putimage_get4bpp + jnz @f + + .correct: + mov eax, [putimg.edi] + mov byte [eax], 80h + + @@: + dec edi + jnz .new_line + jmp put_image_end_16.finish + +;------------------------------------------------------------------------------ + +align 4 +put_image_end_24: + + mov edi, [putimg.real_sy] + ; check for hardware cursor mov ecx, [_display.select_cursor] cmp ecx, select_cursor je put_image_end_24_new cmp ecx, 0 je put_image_end_24_old -;-------------------------------------- -align 4 -.new_line: + .new_line: mov ecx, [putimg.real_sx] -;-------------------------------------- -align 4 -.new_x: + .new_x: push [putimg.edi] mov eax, [putimg.ebp+4] call eax cmp [ebp], bl jne .skip -;-------------------------------------- -; store to real LFB + +; store to LFB mov [LFB_BASE+edx], ax shr eax, 16 mov [LFB_BASE+edx+2], al -;-------------------------------------- -align 4 -.skip: + + .skip: add edx, 3 inc ebp dec ecx jnz .new_x add esi, [putimg.line_increment] - add edx, [putimg.screen_newline];[BytesPerScanLine] - add ebp, [putimg.winmap_newline];[Screen_Max_X] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] cmp [putimg.ebp], putimage_get1bpp jz .correct @@ -303,28 +522,23 @@ align 4 jz .correct cmp [putimg.ebp], putimage_get4bpp jnz @f -;-------------------------------------- -align 4 -.correct: + .correct: mov eax, [putimg.edi] mov byte [eax], 80h -;-------------------------------------- -align 4 -@@: + @@: dec edi jnz .new_line -;-------------------------------------- -align 4 -.finish: + .finish: add esp, putimg.stack_data popad ret + ;------------------------------------------------------------------------------ + align 4 put_image_end_24_old: -;-------------------------------------- -align 4 -.new_line: + + .new_line: mov ecx, [putimg.real_sx] ;-------------------------------------- align 4 @@ -334,9 +548,8 @@ align 4 call eax cmp [ebp], bl jne .skip -;-------------------------------------- - push ecx + push ecx neg ecx add ecx, [putimg.real_sx_and_abs_cx + 4] shl ecx, 16 @@ -346,21 +559,20 @@ align 4 ; check mouse area for putpixel call check_mouse_area_for_putpixel pop ecx -; store to real LFB +; store to LFB mov [LFB_BASE+edx], ax shr eax, 16 mov [LFB_BASE+edx+2], al -;-------------------------------------- -align 4 -.skip: + + .skip: add edx, 3 inc ebp dec ecx jnz .new_x add esi, [putimg.line_increment] - add edx, [putimg.screen_newline];[BytesPerScanLine] - add ebp, [putimg.winmap_newline];[Screen_Max_X] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] cmp [putimg.ebp], putimage_get1bpp jz .correct @@ -368,40 +580,36 @@ align 4 jz .correct cmp [putimg.ebp], putimage_get4bpp jnz @f -;-------------------------------------- -align 4 -.correct: + + .correct: mov eax, [putimg.edi] mov byte [eax], 80h -;-------------------------------------- -align 4 -@@: + + @@: dec edi jnz .new_line jmp put_image_end_24.finish + ;------------------------------------------------------------------------------ + align 4 put_image_end_24_new: -;-------------------------------------- -align 4 -.new_line: + + .new_line: mov ecx, [putimg.real_sx] -;-------------------------------------- -align 4 -.new_x: + + .new_x: push [putimg.edi] mov eax, [putimg.ebp+4] call eax cmp [ebp], bl jne .skip -;-------------------------------------- + push ecx -;-------------------------------------- -align 4 -.sh: + .sh: neg ecx add ecx, [putimg.real_sx_and_abs_cx + 4] -;-------------------------------------- + ; check for X cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] jae .no_mouse_area @@ -413,40 +621,39 @@ align 4 add ecx, [putimg.real_sy_and_abs_cy + 4] sub ecx, edi -;-------------------------------------- + ; check for Y cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] jae .no_mouse_area sub cx, [Y_UNDER_subtraction_CUR_hot_y] jb .no_mouse_area -;-------------------------------------- + ; check mouse area for putpixel call check_mouse_area_for_putpixel_new.1 - cmp ecx, -1 ;SHIT HAPPENS? + cmp ecx, -1 ; SHIT HAPPENS? jne .no_mouse_area mov ecx, [esp] jmp .sh -;-------------------------------------- -align 4 -.no_mouse_area: + + .no_mouse_area: pop ecx -; store to real LFB + +; store to LFB mov [LFB_BASE+edx], ax shr eax, 16 mov [LFB_BASE+edx+2], al -;-------------------------------------- -align 4 -.skip: + + .skip: add edx, 3 inc ebp dec ecx jnz .new_x add esi, [putimg.line_increment] - add edx, [putimg.screen_newline];[BytesPerScanLine] - add ebp, [putimg.winmap_newline];[Screen_Max_X] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] cmp [putimg.ebp], putimage_get1bpp jz .correct @@ -454,54 +661,52 @@ align 4 jz .correct cmp [putimg.ebp], putimage_get4bpp jnz @f -;-------------------------------------- -align 4 -.correct: + + .correct: mov eax, [putimg.edi] mov byte [eax], 80h -;-------------------------------------- -align 4 -@@: + + @@: dec edi jnz .new_line jmp put_image_end_24.finish + ;------------------------------------------------------------------------------ + align 4 put_image_end_32: + mov edi, [putimg.real_sy] -;-------------------------------------- + ; check for hardware cursor mov ecx, [_display.select_cursor] cmp ecx, select_cursor je put_image_end_32_new cmp ecx, 0 je put_image_end_32_old -;-------------------------------------- -align 4 -.new_line: + + .new_line: mov ecx, [putimg.real_sx] -;-------------------------------------- -align 4 -.new_x: + + .new_x: push [putimg.edi] mov eax, [putimg.ebp+4] call eax cmp [ebp], bl jne .skip -;-------------------------------------- -; store to real LFB + +; store to LFB mov [LFB_BASE+edx], eax -;-------------------------------------- -align 4 -.skip: + + .skip: add edx, 4 inc ebp dec ecx jnz .new_x add esi, [putimg.line_increment] - add edx, [putimg.screen_newline];[BytesPerScanLine] - add ebp, [putimg.winmap_newline];[Screen_Max_X] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] cmp [putimg.ebp], putimage_get1bpp jz .correct @@ -509,47 +714,40 @@ align 4 jz .correct cmp [putimg.ebp], putimage_get4bpp jnz @f -;-------------------------------------- -align 4 -.correct: + + .correct: mov eax, [putimg.edi] mov byte [eax], 80h -;-------------------------------------- -align 4 -@@: + + @@: dec edi jnz .new_line -;-------------------------------------- -align 4 -.finish: + + .finish: add esp, putimg.stack_data popad cmp [SCR_MODE], 0x12 jne @f call VGA__putimage -;-------------------------------------- -align 4 -@@: + @@: mov [EGA_counter], 1 ret + ;------------------------------------------------------------------------------ + align 4 put_image_end_32_old: -;-------------------------------------- -align 4 -.new_line: + + .new_line: mov ecx, [putimg.real_sx] -;-------------------------------------- -align 4 -.new_x: + .new_x: push [putimg.edi] mov eax, [putimg.ebp+4] call eax cmp [ebp], bl jne .skip -;-------------------------------------- - push ecx + push ecx neg ecx add ecx, [putimg.real_sx_and_abs_cx + 4] shl ecx, 16 @@ -559,19 +757,18 @@ align 4 ; check mouse area for putpixel call check_mouse_area_for_putpixel pop ecx -; store to real LFB +; store to LFB mov [LFB_BASE+edx], eax -;-------------------------------------- -align 4 -.skip: + + .skip: add edx, 4 inc ebp dec ecx jnz .new_x add esi, [putimg.line_increment] - add edx, [putimg.screen_newline];[BytesPerScanLine] - add ebp, [putimg.winmap_newline];[Screen_Max_X] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] cmp [putimg.ebp], putimage_get1bpp jz .correct @@ -579,83 +776,76 @@ align 4 jz .correct cmp [putimg.ebp], putimage_get4bpp jnz @f -;-------------------------------------- -align 4 -.correct: + + .correct: mov eax, [putimg.edi] mov byte [eax], 80h -;-------------------------------------- -align 4 -@@: + + @@: dec edi jnz .new_line jmp put_image_end_32.finish + ;------------------------------------------------------------------------------ + align 4 put_image_end_32_new: -;-------------------------------------- -align 4 -.new_line: + + .new_line: mov ecx, [putimg.real_sx] -;-------------------------------------- -align 4 -.new_x: + + .new_x: push [putimg.edi] mov eax, [putimg.ebp+4] call eax cmp [ebp], bl jne .skip -;-------------------------------------- + push ecx -;-------------------------------------- -align 4 -.sh: + + .sh: neg ecx add ecx, [putimg.real_sx_and_abs_cx + 4] -;-------------------------------------- + ; check for X cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] jae .no_mouse_area - sub cx, [X_UNDER_subtraction_CUR_hot_x] jb .no_mouse_area - shl ecx, 16 add ecx, [putimg.real_sy_and_abs_cy + 4] sub ecx, edi -;-------------------------------------- + ; check for Y cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] jae .no_mouse_area - sub cx, [Y_UNDER_subtraction_CUR_hot_y] jb .no_mouse_area -;-------------------------------------- + ; check mouse area for putpixel call check_mouse_area_for_putpixel_new.1 - cmp ecx, -1 ;SHIT HAPPENS? + cmp ecx, -1 ; SHIT HAPPENS? jne .no_mouse_area mov ecx, [esp] jmp .sh -;-------------------------------------- -align 4 -.no_mouse_area: + + .no_mouse_area: pop ecx -; store to real LFB + +; store to LFB mov [LFB_BASE+edx], eax -;-------------------------------------- -align 4 -.skip: + + .skip: add edx, 4 inc ebp dec ecx jnz .new_x add esi, [putimg.line_increment] - add edx, [putimg.screen_newline];[BytesPerScanLine] - add ebp, [putimg.winmap_newline];[Screen_Max_X] + add edx, [putimg.screen_newline] + add ebp, [putimg.winmap_newline] cmp [putimg.ebp], putimage_get1bpp jz .correct @@ -663,71 +853,155 @@ align 4 jz .correct cmp [putimg.ebp], putimage_get4bpp jnz @f -;-------------------------------------- -align 4 -.correct: + + .correct: mov eax, [putimg.edi] mov byte [eax], 80h -;-------------------------------------- -align 4 -@@: + + @@: dec edi jnz .new_line jmp put_image_end_32.finish + ;------------------------------------------------------------------------------ +; eax = x coordinate +; ebx = y coordinate +; ecx = xx RR GG BB +; xx flags: +; 0x01000000 color inversion +; 0x02000000 used for draw_rectangle without top line (for drawwindow_III and drawwindow_IV) +; edi = 0x00000001 force + align 4 __sys_putpixel: -; eax = x coordinate -; ebx = y coordinate -; ecx = ?? RR GG BB ; 0x01000000 negation - ; 0x02000000 used for draw_rectangle without top line - ; for example drawwindow_III and drawwindow_IV -; edi = 0x00000001 force - pushad - cmp eax, [_display.width] - jae .exit - cmp ebx, [_display.height] - jae .exit + cmp [Screen_Max_X], eax + jb .exit + cmp [Screen_Max_Y], ebx + jb .exit test edi, 1 ; force ? jnz .forced -; not forced: +; not forced mov edx, [d_width_calc_area + ebx*4] add edx, [_WinMapAddress] movzx edx, byte [eax+edx] cmp edx, [CURRENT_TASK] jne .exit -;-------------------------------------- -align 4 -.forced: -; check if negation + + .forced: +; check for color inversion test ecx, 0x01000000 - jz .noneg + jz .no_inv + + push eax ebx edx edi + call [GETPIXEL] + pop edi edx ebx eax - call getpixel not ecx - rol ecx, 8 mov cl, [esp+32-8+3] ror ecx, 8 mov [esp+32-8], ecx -;-------------------------------------- -align 4 -.noneg: -; OK to set pixel - call dword [PUTPIXEL]; call the real put_pixel function -;-------------------------------------- -align 4 -.exit: + .no_inv: + call [PUTPIXEL] ; call the real put_pixel function + .exit: popad ret + ;----------------------------------------------------------------------------- +; eax = x +; ebx = y + +align 4 +Vesa20_putpixel16: + + mov ecx, eax + shl ecx, 16 + mov cx, bx + +; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier + mov ebx, [BPSLine_calc_area+ebx*4] + lea edi, [eax*2]; edi = x*2 + mov eax, [esp+32-8+4] + +; check for hardware cursor + cmp [_display.select_cursor], 0 + jne @f +; check mouse area for putpixel + test eax, 0x04000000 + jnz @f + call check_mouse_area_for_putpixel + @@: +; store to LFB + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + + mov [LFB_BASE+ebx+edi], ax + ret + +;----------------------------------------------------------------------------- +; eax = x +; ebx = y + +align 4 +Vesa20_putpixel16_new: + + mov ecx, eax + shl ecx, 16 + mov cx, bx + +; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier + mov ebx, [BPSLine_calc_area+ebx*4] + lea edi, [eax*2]; edi = x*2 + mov eax, [esp+32-8+4] + +; check for hardware cursor + cmp [_display.select_cursor], select_cursor + jne @f +; check mouse area for putpixel + test eax, 0x04000000 + jnz @f + +; check for Y + cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] + jae @f + sub cx, [Y_UNDER_subtraction_CUR_hot_y] + jb @f + rol ecx, 16 + +; check for X + cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] + jae @f + sub cx, [X_UNDER_subtraction_CUR_hot_x] + jb @f + ror ecx, 16 + + call check_mouse_area_for_putpixel_new.1 + @@: +; store to LFB + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + + mov [LFB_BASE+ebx+edi], ax + ret + +;----------------------------------------------------------------------------- +; eax = x +; ebx = y + align 4 Vesa20_putpixel24: -; eax = x -; ebx = y + mov ecx, eax shl ecx, 16 mov cx, bx @@ -736,7 +1010,7 @@ Vesa20_putpixel24: mov ebx, [BPSLine_calc_area+ebx*4] lea edi, [eax+eax*2]; edi = x*3 mov eax, [esp+32-8+4] -;-------------------------------------- + ; check for hardware cursor cmp [_display.select_cursor], 0 jne @f @@ -744,19 +1018,21 @@ Vesa20_putpixel24: test eax, 0x04000000 jnz @f call check_mouse_area_for_putpixel -;-------------------------------------- -align 4 -@@: -; store to real LFB + @@: + +; store to LFB mov [LFB_BASE+ebx+edi], ax shr eax, 16 mov [LFB_BASE+ebx+edi+2], al ret + ;----------------------------------------------------------------------------- +; eax = x +; ebx = y + align 4 Vesa20_putpixel24_new: -; eax = x -; ebx = y + mov ecx, eax shl ecx, 16 mov cx, bx @@ -765,55 +1041,52 @@ Vesa20_putpixel24_new: mov ebx, [BPSLine_calc_area+ebx*4] lea edi, [eax+eax*2]; edi = x*3 mov eax, [esp+32-8+4] -;-------------------------------------- + ; check for hardware cursor cmp [_display.select_cursor], select_cursor jne @f ; check mouse area for putpixel test eax, 0x04000000 jnz @f -;-------------------------------------- + ; check for Y cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] jae @f - sub cx, [Y_UNDER_subtraction_CUR_hot_y] jb @f - rol ecx, 16 -;-------------------------------------- + ; check for X cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] jae @f - sub cx, [X_UNDER_subtraction_CUR_hot_x] jb @f - ror ecx, 16 call check_mouse_area_for_putpixel_new.1 -;-------------------------------------- -align 4 -@@: -; store to real LFB + @@: +; store to LFB mov [LFB_BASE+ebx+edi], ax shr eax, 16 mov [LFB_BASE+ebx+edi+2], al ret + ;----------------------------------------------------------------------------- -align 4 -Vesa20_putpixel32: ; eax = x ; ebx = y + +align 4 +Vesa20_putpixel32: + mov ecx, eax shl ecx, 16 mov cx, bx ; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier mov ebx, [BPSLine_calc_area+ebx*4] - lea edi, [ebx+eax*4]; edi = x*4+(y*y multiplier) - mov eax, [esp+32-8+4]; eax = color -;-------------------------------------- + lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) + mov eax, [esp+32-8+4] ; eax = color + ; check for hardware cursor cmp [_display.select_cursor], 0 jne @f @@ -821,79 +1094,78 @@ Vesa20_putpixel32: test eax, 0x04000000 jnz @f call check_mouse_area_for_putpixel -;-------------------------------------- -align 4 -@@: + @@: and eax, 0xffffff -; store to real LFB +; store to LFB mov [LFB_BASE+edi], eax ret + ;----------------------------------------------------------------------------- -align 4 -Vesa20_putpixel32_new: ; eax = x ; ebx = y + +align 4 +Vesa20_putpixel32_new: + mov ecx, eax shl ecx, 16 mov cx, bx ; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier mov ebx, [BPSLine_calc_area+ebx*4] - lea edi, [ebx+eax*4]; edi = x*4+(y*y multiplier) - mov eax, [esp+32-8+4]; eax = color -;-------------------------------------- + lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) + mov eax, [esp+32-8+4] ; eax = color + ; check for hardware cursor cmp [_display.select_cursor], select_cursor jne @f ; check mouse area for putpixel test eax, 0x04000000 jnz @f -;-------------------------------------- + ; check for Y cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] jae @f - sub cx, [Y_UNDER_subtraction_CUR_hot_y] jb @f - rol ecx, 16 -;-------------------------------------- + ; check for X cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] jae @f - sub cx, [X_UNDER_subtraction_CUR_hot_x] jb @f - ror ecx, 16 call check_mouse_area_for_putpixel_new.1 -;-------------------------------------- -align 4 -@@: - and eax, 0xffffff -; store to real LFB + @@: + and eax, 0x00ffffff +; store to LFB mov [LFB_BASE+edi], eax ret + ;----------------------------------------------------------------------------- + align 4 calculate_edi: +; mov edi, ebx +; imul edi, [Screen_Max_X] +; add edi, ebx mov edi, [d_width_calc_area + ebx*4] add edi, eax ret + + ;----------------------------------------------------------------------------- ; DRAWLINE ;----------------------------------------------------------------------------- -align 4 -__sys_draw_line: -; draw a line -; eax = HIWORD = x1 -; LOWORD = x2 -; ebx = HIWORD = y1 -; LOWORD = y2 +; eax = x1 shl 16 + x2 +; ebx = y1 shl 16 + y2 ; ecx = color ; edi = force ? - pusha + +align 4 +__sys_draw_line: dl_x1 equ esp+20 dl_y1 equ esp+16 @@ -902,6 +1174,8 @@ dl_y2 equ esp+8 dl_dx equ esp+4 dl_dy equ esp+0 + pusha + xor edx, edx ; clear edx xor esi, esi ; unpack arguments xor ebp, ebp @@ -922,31 +1196,27 @@ dl_dy equ esp+0 call vline push edx ; necessary to rightly restore stack frame at .exit jmp .exit -;-------------------------------------- -align 4 -.x2lx1: + + .x2lx1: neg esi ; get esi absolute value -;-------------------------------------- -align 4 -.no_vline: + + .no_vline: ; checking y-axis... sub ebp, ebx ; ebp = y2-y1 push ebp ; save y2-y1 jl .y2ly1 ; is y2 less than y1 ? jg .no_hline ; y1 > y2 ? - mov edx, [dl_x2]; else (if y1=y2) + mov edx, [dl_x2] ; else (if y1=y2) call hline jmp .exit -;-------------------------------------- -align 4 -.y2ly1: + + .y2ly1: neg ebp ; get ebp absolute value -;-------------------------------------- -align 4 -.no_hline: + + .no_hline: cmp ebp, esi jle .x_rules ; |y2-y1| < |x2-x1| ? - cmp [dl_y2], ebx; make sure y1 is at the begining + cmp [dl_y2], ebx ; make sure y1 is at the begining jge .no_reverse1 neg dword [dl_dx] mov edx, [dl_x2] @@ -955,30 +1225,24 @@ align 4 mov edx, [dl_y2] mov [dl_y2], ebx mov [dl_y1], edx -;-------------------------------------- -align 4 -.no_reverse1: + + .no_reverse1: mov eax, [dl_dx] cdq ; extend eax sing to edx shl eax, 16 ; using 16bit fix-point maths idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1) -;-------------------------------------- + ; correction for the remainder of the division shl edx, 1 cmp ebp, edx jb @f inc eax -;-------------------------------------- -align 4 -@@: -;-------------------------------------- + @@: mov edx, ebp ; edx = counter (number of pixels to draw) - mov ebp, 1 *65536; <<16 ; ebp = dy = 1.0 + mov ebp, 1 shl 16 ; ebp = dy = 1.0 mov esi, eax ; esi = dx jmp .y_rules -;-------------------------------------- -align 4 -.x_rules: + .x_rules: cmp [dl_x2], eax ; make sure x1 is at the begining jge .no_reverse2 neg dword [dl_dy] @@ -988,61 +1252,45 @@ align 4 mov edx, [dl_y2] mov [dl_y2], ebx mov [dl_y1], edx -;-------------------------------------- -align 4 -.no_reverse2: + .no_reverse2: xor edx, edx mov eax, [dl_dy] cdq ; extend eax sing to edx shl eax, 16 ; using 16bit fix-point maths idiv esi ; eax = ((y2-y1)*65536)/(x2-x1) -;-------------------------------------- ; correction for the remainder of the division shl edx, 1 cmp esi, edx jb @f inc eax -;-------------------------------------- -align 4 -@@: -;-------------------------------------- + @@: mov edx, esi ; edx = counter (number of pixels to draw) - mov esi, 1 *65536;<< 16 ; esi = dx = 1.0 + mov esi, 1 shl 16 ; esi = dx = 1.0 mov ebp, eax ; ebp = dy -;-------------------------------------- -align 4 -.y_rules: + + .y_rules: mov eax, [dl_x1] mov ebx, [dl_y1] shl eax, 16 shl ebx, 16 - and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area -;----------------------------------------------------------------------------- -align 4 -.draw: + and ecx, 0xFBFFFFFF ; negate 0x04000000 save to mouseunder area + .draw: push eax ebx -;-------------------------------------- + ; correction for the remainder of the division test ah, 0x80 jz @f add eax, 1 shl 16 -;-------------------------------------- -align 4 -@@: -;-------------------------------------- + @@: shr eax, 16 -;-------------------------------------- ; correction for the remainder of the division test bh, 0x80 jz @f add ebx, 1 shl 16 -;-------------------------------------- -align 4 -@@: -;-------------------------------------- + @@: shr ebx, 16 -; and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area +; and ecx, 0xFBFFFFFF ; negate 0x04000000 save to mouseunder area ; call [putpixel] call __sys_putpixel pop ebx eax @@ -1053,36 +1301,34 @@ align 4 ; force last drawn pixel to be at (x2,y2) mov eax, [dl_x2] mov ebx, [dl_y2] -; and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area +; and ecx, 0xFBFFFFFF ;n egate 0x04000000 save to mouseunder area ; call [putpixel] call __sys_putpixel -;-------------------------------------- -align 4 -.exit: + + .exit: add esp, 6*4 popa ; call [draw_pointer] ret + ;------------------------------------------------------------------------------ -align 4 -hline: ; draw an horizontal line ; eax = x1 ; edx = x2 ; ebx = y ; ecx = color ; edi = force ? + +align 4 +hline: + push eax edx cmp edx, eax ; make sure x2 is above x1 jge @f xchg eax, edx -;-------------------------------------- -align 4 -@@: + @@: and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area -;-------------------------------------- -align 4 -@@: + @@: ; call [putpixel] call __sys_putpixel inc eax @@ -1090,26 +1336,25 @@ align 4 jle @b pop edx eax ret + ;------------------------------------------------------------------------------ -align 4 -vline: ; draw a vertical line ; eax = x ; ebx = y1 ; edx = y2 ; ecx = color ; edi = force ? + +align 4 +vline: + push ebx edx cmp edx, ebx ; make sure y2 is above y1 jge @f xchg ebx, edx -;-------------------------------------- -align 4 -@@: + @@: and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area -;-------------------------------------- -align 4 -@@: + @@: ; call [putpixel] call __sys_putpixel inc ebx @@ -1117,8 +1362,17 @@ align 4 jle @b pop edx ebx ret + ;------------------------------------------------------------------------------ +; eax cx +; ebx cy +; ecx xe +; edx ye +; edi color + align 4 +vesa20_drawbar: + virtual at esp drbar: .bar_sx dd ? @@ -1136,61 +1390,43 @@ drbar: .real_sy_and_abs_cy dd ? .stack_data = 4*13 end virtual -;-------------------------------------- -align 4 -; eax cx -; ebx cy -; ecx xe -; edx ye -; edi color -vesa20_drawbar: + pushad sub esp, drbar.stack_data mov [drbar.color], edi sub edx, ebx - jle .exit ;// mike.dld, 2005-01-29 + jle .exit sub ecx, eax - jle .exit ;// mike.dld, 2005-01-29 + jle .exit mov [drbar.bar_sy], edx mov [drbar.bar_sx], ecx mov [drbar.bar_cx], eax mov [drbar.bar_cy], ebx mov edi, [TASK_BASE] - add eax, [edi-twdw + WDATA.box.left]; win_cx - add ebx, [edi-twdw + WDATA.box.top]; win_cy + add eax, [edi-twdw + WDATA.box.left] ; win_cx + add ebx, [edi-twdw + WDATA.box.top] ; win_cy mov [drbar.abs_cx], eax mov [drbar.abs_cy], ebx ; real_sx = MIN(wnd_sx-bar_cx, bar_sx); - mov ebx, [edi-twdw + WDATA.box.width]; ebx = wnd_sx -; \begin{diamond}[20.08.2006] -; note that WDATA.box.width is one pixel less than real window x-size - inc ebx -; \end{diamond}[20.08.2006] + mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx + inc ebx ; WDATA.box.width is one pixel less than real window x-size sub ebx, [drbar.bar_cx] ja @f -;-------------------------------------- -align 4 -.exit: ;// mike.dld, 2005-01-29 + .exit: add esp, drbar.stack_data popad xor eax, eax inc eax ret -;-------------------------------------- -align 4 -@@: + @@: cmp ebx, [drbar.bar_sx] jbe .end_x mov ebx, [drbar.bar_sx] -;-------------------------------------- -align 4 -.end_x: + .end_x: mov [drbar.real_sx], ebx ; real_sy = MIN(wnd_sy-bar_cy, bar_sy); - mov ebx, [edi-twdw + WDATA.box.height]; ebx = wnd_sy -; \begin{diamond}[20.08.2006] + mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy inc ebx -; \end{diamond} sub ebx, [drbar.bar_cy] ja @f add esp, drbar.stack_data @@ -1198,24 +1434,20 @@ align 4 xor eax, eax inc eax ret -;-------------------------------------- -align 4 -@@: + @@: cmp ebx, [drbar.bar_sy] jbe .end_y mov ebx, [drbar.bar_sy] -;-------------------------------------- -align 4 -.end_y: + .end_y: mov [drbar.real_sy], ebx ; line_inc_map - mov eax, [_display.width] + mov eax, [Screen_Max_X] sub eax, [drbar.real_sx] + inc eax mov [drbar.line_inc_map], eax ; line_inc_scr mov eax, [drbar.real_sx] - mov ebx, [_display.bpp] - shr ebx, 3 + mov ebx, [_display.bytes_per_pixel] imul eax, ebx neg eax add eax, [_display.pitch] @@ -1229,12 +1461,14 @@ align 4 add edx, eax ; pointer to pixel map mov eax, [drbar.abs_cy] +; imul eax, [Screen_Max_X] +; add eax, [drbar.abs_cy] mov eax, [d_width_calc_area + eax*4] add eax, [drbar.abs_cx] add eax, [_WinMapAddress] xchg eax, ebp -;-------------------------------------- + mov ebx, [drbar.real_sx] add ebx, [drbar.abs_cx] mov [drbar.real_sx_and_abs_cx], ebx @@ -1243,7 +1477,7 @@ align 4 mov [drbar.real_sy_and_abs_cy], ebx add edx, LFB_BASE -;-------------------------------------- + ; get process number mov ebx, [CURRENT_TASK] ; bl - process num mov esi, [drbar.real_sy] @@ -1251,41 +1485,42 @@ align 4 rol eax, 8 mov bh, al ; 0x80 drawing gradient bars ror eax, 8 - cmp byte [_display.bpp], 24 - jne draw_bar_end_32 + + cmp byte [_display.bits_per_pixel], 16 + je draw_bar_end_16 + cmp byte [_display.bits_per_pixel], 24 + je draw_bar_end_24 + cmp byte [_display.bits_per_pixel], 32 + je draw_bar_end_32 + ;-------------------------------------- -align 4 -draw_bar_end_24: ; eax - color high RRGGBB ; bl - process num ; ecx - temp ; edx - pointer to screen ; esi - counter ; edi - counter -;-------------------------------------- + +align 4 +draw_bar_end_24: + ; check for hardware cursor mov ecx, [_display.select_cursor] cmp ecx, select_cursor je draw_bar_end_24_new cmp ecx, 0 je draw_bar_end_24_old -;-------------------------------------- -align 4 -.new_y: + .new_y: mov edi, [drbar.real_sx] -;-------------------------------------- -align 4 -.new_x: + .new_x: cmp byte [ebp], bl jne .skip -;-------------------------------------- -; store to real LFB + +; store to LFB mov [edx], ax shr eax, 16 mov [edx + 2], al -;-------------------------------------- -align 4 -.skip: + .skip: ; add pixel add edx, 3 inc ebp @@ -1300,31 +1535,26 @@ align 4 test al, al jz @f dec al -;-------------------------------------- -align 4 -@@: + @@: dec esi jnz .new_y -;-------------------------------------- -align 4 -.end: + .end: add esp, drbar.stack_data popad xor eax, eax ret + ;------------------------------------------------------------------------------ + align 4 draw_bar_end_24_old: -;-------------------------------------- -align 4 -.new_y: + + .new_y: mov edi, [drbar.real_sx] -;-------------------------------------- -align 4 -.new_x: + .new_x: cmp byte [ebp], bl jne .skip -;-------------------------------------- + mov ecx, [drbar.real_sx_and_abs_cx] sub ecx, edi shl ecx, 16 @@ -1332,14 +1562,12 @@ align 4 sub ecx, esi ; check mouse area for putpixel call check_mouse_area_for_putpixel -; store to real LFB +; store to LFB mov [edx], ax shr eax, 16 mov [edx + 2], al mov eax, [drbar.color] -;-------------------------------------- -align 4 -.skip: + .skip: ; add pixel add edx, 3 inc ebp @@ -1354,48 +1582,41 @@ align 4 test al, al jz @f dec al -;-------------------------------------- -align 4 -@@: + @@: dec esi jnz .new_y jmp draw_bar_end_24.end + ;------------------------------------------------------------------------------ + align 4 draw_bar_end_24_new: -;-------------------------------------- -align 4 -.new_y: + + .new_y: mov edi, [drbar.real_sx] -;-------------------------------------- -align 4 -.new_x: + .new_x: cmp byte [ebp], bl jne .skip -;-------------------------------------- + mov ecx, [drbar.real_sy_and_abs_cy] sub ecx, esi -;-------------------------------------- + ; check for Y cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] jae .no_mouse_area - sub cx, [Y_UNDER_subtraction_CUR_hot_y] jb .no_mouse_area - rol ecx, 16 add ecx, [drbar.real_sx_and_abs_cx] sub ecx, edi -;-------------------------------------- + ; check for X cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] jae .no_mouse_area - sub cx, [X_UNDER_subtraction_CUR_hot_x] jb .no_mouse_area - ror ecx, 16 -;-------------------------------------- + ; check mouse area for putpixel push eax call check_mouse_area_for_putpixel_new.1 @@ -1404,115 +1625,102 @@ align 4 mov [edx + 2], al pop eax jmp .skip -; store to real LFB -;-------------------------------------- -align 4 -.no_mouse_area: + + .no_mouse_area: +; store to LFB mov [edx], ax ror eax, 16 mov [edx + 2], al rol eax, 16 -;-------------------------------------- -align 4 -.skip: + .skip: + ; add pixel add edx, 3 inc ebp dec edi jnz .new_x + ; add line add edx, [drbar.line_inc_scr] add ebp, [drbar.line_inc_map] + ; drawing gradient bars test bh, 0x80 jz @f test al, al jz @f dec al -;-------------------------------------- -align 4 -@@: + @@: dec esi jnz .new_y jmp draw_bar_end_24.end + ;------------------------------------------------------------------------------ -align 4 -draw_bar_end_32: ; eax - color high RRGGBB ; bl - process num ; ecx - temp ; edx - pointer to screen ; esi - counter ; edi - counter -;-------------------------------------- + +draw_bar_end_32: + ; check for hardware cursor mov ecx, [_display.select_cursor] cmp ecx, select_cursor je draw_bar_end_32_new cmp ecx, 0 je draw_bar_end_32_old -;-------------------------------------- -align 4 -.new_y: + + .new_y: mov edi, [drbar.real_sx] -;-------------------------------------- -align 4 -.new_x: + .new_x: cmp byte [ebp], bl jne .skip -;-------------------------------------- -; store to real LFB + +; store to LFB mov [edx], eax mov eax, [drbar.color] -;-------------------------------------- -align 4 -.skip: + .skip: + ; add pixel add edx, 4 inc ebp dec edi jnz .new_x + ; add line add edx, [drbar.line_inc_scr] add ebp, [drbar.line_inc_map] + ; drawing gradient bars test bh, 0x80 jz @f test al, al jz @f dec al -;-------------------------------------- -align 4 -@@: + @@: dec esi jnz .new_y -;-------------------------------------- -align 4 -.end: + .end: add esp, drbar.stack_data popad cmp [SCR_MODE], 0x12 jne @f call VGA_draw_bar -;-------------------------------------- -align 4 -@@: + @@: xor eax, eax mov [EGA_counter], 1 ret -;------------------------------------------------------------------------------ -align 4 + draw_bar_end_32_old: -;-------------------------------------- -align 4 -.new_y: + + .new_y: mov edi, [drbar.real_sx] -;-------------------------------------- -align 4 -.new_x: + .new_x: cmp byte [ebp], bl jne .skip -;-------------------------------------- + mov ecx, [drbar.real_sx_and_abs_cx] sub ecx, edi shl ecx, 16 @@ -1521,12 +1729,10 @@ align 4 ; check mouse area for putpixel call check_mouse_area_for_putpixel -; store to real LFB +; store to LFB mov [edx], eax mov eax, [drbar.color] -;-------------------------------------- -align 4 -.skip: + .skip: ; add pixel add edx, 4 inc ebp @@ -1541,67 +1747,112 @@ align 4 test al, al jz @f dec al -;-------------------------------------- -align 4 -@@: + @@: dec esi jnz .new_y jmp draw_bar_end_32.end + ;------------------------------------------------------------------------------ + align 4 draw_bar_end_32_new: -;-------------------------------------- -align 4 -.new_y: + + .new_y: mov edi, [drbar.real_sx] -;-------------------------------------- -align 4 -.new_x: + .new_x: cmp byte [ebp], bl jne .skip -;-------------------------------------- + mov ecx, [drbar.real_sy_and_abs_cy] sub ecx, esi -;-------------------------------------- + ; check for Y cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] jae .no_mouse_area - sub cx, [Y_UNDER_subtraction_CUR_hot_y] jb .no_mouse_area - rol ecx, 16 add ecx, [drbar.real_sx_and_abs_cx] sub ecx, edi -;-------------------------------------- + ; check for X cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] jae .no_mouse_area - sub cx, [X_UNDER_subtraction_CUR_hot_x] jb .no_mouse_area - ror ecx, 16 -;-------------------------------------- + ; check mouse area for putpixel push eax call check_mouse_area_for_putpixel_new.1 mov [edx], eax pop eax jmp .skip -; store to real LFB -;-------------------------------------- -align 4 -.no_mouse_area: + .no_mouse_area: + +; store to LFB mov [edx], eax -;-------------------------------------- -align 4 -.skip: + .skip: + ; add pixel add edx, 4 inc ebp dec edi jnz .new_x + +; add line + add edx, [drbar.line_inc_scr] + add ebp, [drbar.line_inc_map] + +; drawing gradient bars + test bh, 0x80 + jz @f + test al, al + jz @f + dec al + @@: + dec esi + jnz .new_y + jmp draw_bar_end_32.end + +;------------------------------------------------------------------------------ +; eax - color high RRGGBB +; bl - process num +; ecx - temp +; edx - pointer to screen +; esi - counter +; edi - counter + +align 4 +draw_bar_end_16: + +; check for hardware cursor + mov ecx, [_display.select_cursor] + cmp ecx, select_cursor + je draw_bar_end_16_new + cmp ecx, 0 + je draw_bar_end_16_old + .new_y: + mov edi, [drbar.real_sx] + .new_x: + cmp byte [ebp], bl + jne .skip +; convert to 16 bpp and store to LFB + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + mov [edx], ax + mov eax, [drbar.color] + .skip: + +; add pixel + add edx, 2 + inc ebp + dec edi + jnz .new_x ; add line add edx, [drbar.line_inc_scr] add ebp, [drbar.line_inc_map] @@ -1611,21 +1862,159 @@ align 4 test al, al jz @f dec al -;-------------------------------------- -align 4 -@@: + @@: dec esi jnz .new_y - jmp draw_bar_end_32.end + .end: + add esp, drbar.stack_data + popad + cmp [SCR_MODE], 0x12 + jne @f + call VGA_draw_bar + @@: + xor eax, eax + mov [EGA_counter], 1 + ret + ;------------------------------------------------------------------------------ + +align 4 +draw_bar_end_16_old: + + .new_y: + mov edi, [drbar.real_sx] + .new_x: + cmp byte [ebp], bl + jne .skip + + mov ecx, [drbar.real_sx_and_abs_cx] + sub ecx, edi + shl ecx, 16 + add ecx, [drbar.real_sy_and_abs_cy] + sub ecx, esi + +; check mouse area for putpixel + call check_mouse_area_for_putpixel +; convert to 16 bpp and store to LFB + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + mov [edx], ax + mov eax, [drbar.color] +.skip: + +; add pixel + add edx, 2 + inc ebp + dec edi + jnz .new_x + +; add line + add edx, [drbar.line_inc_scr] + add ebp, [drbar.line_inc_map] + +; drawing gradient bars + test bh, 0x80 + jz @f + test al, al + jz @f + dec al + @@: + dec esi + jnz .new_y + jmp draw_bar_end_16.end + +;------------------------------------------------------------------------------ + +align 4 +draw_bar_end_16_new: + + .new_y: + mov edi, [drbar.real_sx] + .new_x: + cmp byte [ebp], bl + jne .skip + + mov ecx, [drbar.real_sy_and_abs_cy] + sub ecx, esi + +; check for Y + cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh] + jae .no_mouse_area + sub cx, [Y_UNDER_subtraction_CUR_hot_y] + jb .no_mouse_area + rol ecx, 16 + add ecx, [drbar.real_sx_and_abs_cx] + sub ecx, edi + +; check for X + cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh] + jae .no_mouse_area + sub cx, [X_UNDER_subtraction_CUR_hot_x] + jb .no_mouse_area + ror ecx, 16 + +; check mouse area for putpixel + push eax + call check_mouse_area_for_putpixel_new.1 + push eax + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + mov [edx], ax + pop eax + pop eax + jmp .skip + + .no_mouse_area: +; convert to 16 bpp and store to LFB + push eax + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + mov [edx], ax + pop eax + .skip: + +; add pixel + add edx, 2 + inc ebp + dec edi + jnz .new_x + +; add line + add edx, [drbar.line_inc_scr] + add ebp, [drbar.line_inc_map] + +; drawing gradient bars + test bh, 0x80 + jz @f + test al, al + jz @f + dec al + @@: + dec esi + jnz .new_y + jmp draw_bar_end_16.end + +;------------------------------------------------------------------------------ + align 4 vesa20_drawbackground_tiled: + pushad ; External loop for all y from start to end mov ebx, [draw_data+32+RECT.top] ; y start -;-------------------------------------- -align 4 -dp2: + dp2: mov ebp, [draw_data+32+RECT.left] ; x start ; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp] ; and LFB data (output for our function) [edi] @@ -1635,13 +2024,14 @@ dp2: xchg ebp, eax add ebp, eax add ebp, eax + cmp byte [_display.bytes_per_pixel], 2 + je @f add ebp, eax - cmp byte [_display.bpp], 24 ; 24 or 32 bpp ? - x size - jz @f + cmp byte [_display.bytes_per_pixel], 3 + je @f add ebp, eax -;-------------------------------------- -align 4 -@@: + + @@: add ebp, LFB_BASE ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB call calculate_edi @@ -1674,14 +2064,11 @@ align 4 ; edx = 1 ; esi -> bgr memory, edi -> output ; ebp = offset in WinMapAddress -;-------------------------------------- -align 4 -dp3: + dp3: cmp [ebp], dl - jnz nbgp -;-------------------------------------- - push eax ecx + jnz .next_pix + push eax ecx mov ecx, eax shl ecx, 16 add ecx, ebx @@ -1693,47 +2080,52 @@ dp3: je @f cmp [_display.select_cursor], 0 jne .no_mouseunder -;-------------------------------------- -align 4 -@@: + @@: and eax, 0xffffff ; check mouse area for putpixel call [_display.check_mouse] -;-------------------------------------- -align 4 -.no_mouseunder: -; store to real LFB + .no_mouseunder: + + cmp byte [_display.bits_per_pixel], 16 + je .16bpp +; store to LFB mov [edi], ax shr eax, 16 mov [edi+2], al - pop ecx eax -;-------------------------------------- -align 4 -nbgp: + jmp .next_pix + + .16bpp: +; convert to 16 bpp and store to LFB + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + mov [edi], ax + pop ecx eax + +; Advance to next pixel + .next_pix: add esi, 3 - add edi, 3 -;-------------------------------------- -align 4 -@@: - cmp byte [_display.bpp], 25 ; 24 or 32 bpp? - sbb edi, -1 ; +1 for 32 bpp -; I do not use 'inc eax' because this is slightly slower then 'add eax,1' + add edi, [_display.bytes_per_pixel] + add ebp, edx add eax, edx cmp eax, [draw_data+32+RECT.right] ja dp4 sub ecx, edx jnz dp3 + ; next tile block on x-axis mov ecx, [BgrDataWidth] sub esi, ecx sub esi, ecx sub esi, ecx jmp dp3 -;-------------------------------------- -align 4 -dp4: + + dp4: ; next scan line inc ebx cmp ebx, [draw_data+32+RECT.bottom] @@ -1743,31 +2135,36 @@ dp4: cmp [SCR_MODE], 0x12 jne @f call VGA_drawbackground -;-------------------------------------- -align 4 -@@: + @@: ret + ;------------------------------------------------------------------------------ + align 4 vesa20_drawbackground_stretch: + pushad ; Helper variables -; calculate 2^32*(BgrDataWidth) mod (ScreenWidth) +; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1) mov eax, [BgrDataWidth] + dec eax xor edx, edx - div dword [_display.width] + div dword [Screen_Max_X] push eax ; high xor eax, eax - div dword [_display.width] + div dword [Screen_Max_X] push eax ; low + ; the same for height mov eax, [BgrDataHeight] + dec eax xor edx, edx - div dword [_display.height] + div dword [Screen_Max_Y] push eax ; high xor eax, eax - div dword [_display.height] + div dword [Screen_Max_Y] push eax ; low + ; External loop for all y from start to end mov ebx, [draw_data+32+RECT.top] ; y start mov ebp, [draw_data+32+RECT.left] ; x start @@ -1779,16 +2176,18 @@ vesa20_drawbackground_stretch: xchg ebp, eax add ebp, eax add ebp, eax - add ebp, eax - cmp byte [_display.bpp], 24 ; 24 or 32 bpp ? - x size + cmp byte [_display.bytes_per_pixel], 2 jz @f add ebp, eax -;-------------------------------------- -align 4 -@@: + cmp byte [_display.bytes_per_pixel], 3 + jz @f + add ebp, eax + @@: + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB call calculate_edi xchg edi, ebp + ; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress push ebx push eax @@ -1814,19 +2213,17 @@ align 4 push eax push edx push esi + ; 3) Smooth horizontal -;-------------------------------------- -align 4 -bgr_resmooth0: + bgr_resmooth0: mov ecx, [esp+8] mov edx, [esp+4] mov esi, [esp] push edi mov edi, bgr_cur_line call smooth_line -;-------------------------------------- -align 4 -bgr_resmooth1: + + bgr_resmooth1: mov eax, [esp+16+4] inc eax cmp eax, [BgrDataHeight] @@ -1839,15 +2236,14 @@ bgr_resmooth1: add esi, [BgrDataWidth] mov edi, bgr_next_line call smooth_line -;-------------------------------------- -align 4 -bgr.no2nd: + + bgr.no2nd: pop edi -;-------------------------------------- -align 4 -sdp3: + + sdp3: xor esi, esi mov ecx, [esp+12] + ; 4) Loop through redraw rectangle and copy background data ; Registers meaning: ; esi = offset in current line, edi -> output @@ -1860,9 +2256,8 @@ sdp3: ; precalculated constants: ; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1) ; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1) -;-------------------------------------- -align 4 -sdp3a: + + sdp3a: mov eax, [_WinMapAddress] cmp [ebp+eax], byte 1 jnz snbgp @@ -1871,36 +2266,44 @@ sdp3a: jz .novert mov ebx, [bgr_next_line+esi] call [overlapping_of_points_ptr] -;-------------------------------------- -align 4 -.novert: + + .novert: push ecx ; check for hardware cursor cmp [_display.select_cursor], select_cursor je @f cmp [_display.select_cursor], 0 jne .no_mouseunder -;-------------------------------------- -align 4 -@@: + @@: mov ecx, [esp+20+4] ;x shl ecx, 16 add ecx, [esp+24+4] ;y ; check mouse area for putpixel call [_display.check_mouse] -;-------------------------------------- -align 4 -.no_mouseunder: -; store to real LFB + .no_mouseunder: + + cmp [_display.bits_per_pixel], 16 + jne .not_16bpp +; convert to 16 bpp and store to LFB + and eax, 00000000111110001111110011111000b + shr ah, 2 + shr ax, 3 + ror eax, 8 + add al, ah + rol eax, 8 + mov [LFB_BASE+edi], ax + pop ecx + jmp snbgp + .not_16bpp: + +; store to LFB mov [LFB_BASE+edi], ax shr eax, 16 mov [LFB_BASE+edi+2], al pop ecx -;-------------------------------------- -align 4 -snbgp: - cmp byte [_display.bpp], 25 - sbb edi, -4 + + snbgp: + add edi, [_display.bytes_per_pixel] add ebp, 1 mov eax, [esp+20] add eax, 1 @@ -1908,28 +2311,30 @@ snbgp: add esi, 4 cmp eax, [draw_data+32+RECT.right] jbe sdp3a -;-------------------------------------- -align 4 -sdp4: + + sdp4: ; next y mov ebx, [esp+24] add ebx, 1 mov [esp+24], ebx cmp ebx, [draw_data+32+RECT.bottom] ja sdpdone + ; advance edi, ebp to next scan line sub eax, [draw_data+32+RECT.left] sub ebp, eax - add ebp, [_display.width] + add ebp, [Screen_Max_X] + add ebp, 1 sub edi, eax sub edi, eax - sub edi, eax - cmp byte [_display.bpp], 24 + cmp byte [_display.bytes_per_pixel], 2 jz @f sub edi, eax -;-------------------------------------- -align 4 -@@: + cmp byte [_display.bytes_per_pixel], 3 + jz @f + sub edi, eax + + @@: add edi, [_display.pitch] ; restore ecx,edx; advance esi to next background line mov eax, [esp+28] @@ -1951,31 +2356,23 @@ align 4 push edi mov esi, bgr_next_line mov edi, bgr_cur_line - mov ecx, [_display.width] + mov ecx, [Screen_Max_X] + inc ecx rep movsd jmp bgr_resmooth1 -;-------------------------------------- -align 4 -sdpdone: + + sdpdone: add esp, 44 popad mov [EGA_counter], 1 cmp [SCR_MODE], 0x12 jne @f call VGA_drawbackground -;-------------------------------------- -align 4 -@@: + @@: ret -uglobal -;-------------------------------------- -align 4 -bgr_cur_line rd 1920 ; maximum width of screen -bgr_next_line rd 1920 -;-------------------------------------- -endg ;-------------------------------------- + align 4 smooth_line: mov al, [esi+2] @@ -1986,9 +2383,7 @@ smooth_line: mov ebx, [esi+2] shr ebx, 8 call [overlapping_of_points_ptr] -;-------------------------------------- -align 4 -@@: + @@: stosd mov eax, [esp+20+8] add eax, 1 @@ -2002,13 +2397,13 @@ align 4 lea eax, [eax*3] sub esi, eax jmp smooth_line -;-------------------------------------- -align 4 -@@: + @@: mov eax, [draw_data+32+RECT.left] mov [esp+20+8], eax ret + ;------------------------------------------------------------------------------ + align 16 overlapping_of_points: if 0 @@ -2072,27 +2467,22 @@ else ret end if -iglobal -;-------------------------------------- -align 4 -overlapping_of_points_ptr dd overlapping_of_points -;-------------------------------------- -endg + ;------------------------------------------------------------------------------ + align 4 init_background: + mov edi, BgrAuxTable xor edx, edx -;-------------------------------------- -align 4 -.loop2: + + .loop2: mov eax, edx shl eax, 8 neg eax mov ecx, 0x200 -;-------------------------------------- -align 4 -.loop1: + + .loop1: mov byte [edi], ah inc edi add eax, edx @@ -2102,13 +2492,14 @@ align 4 test byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8) jz @f mov [overlapping_of_points_ptr], overlapping_of_points_mmx -;-------------------------------------- -align 4 -@@: + @@: ret + ;------------------------------------------------------------------------------ + align 16 overlapping_of_points_mmx: + movd mm0, eax movd mm4, eax movd mm1, ebx @@ -2125,5 +2516,7 @@ overlapping_of_points_mmx: packuswb mm1, mm2 paddb mm4, mm1 movd eax, mm4 + ret + ;------------------------------------------------------------------------------