From b6f863a2e2490aca695861c10b257551ba598498 Mon Sep 17 00:00:00 2001 From: Rus Date: Thu, 28 Feb 2008 21:01:15 +0000 Subject: [PATCH] Refactored function 42, now its faster in about 100 times, than the old version from Menuet. See sysfuncs.txt (sysfuncr.txt) for more details. git-svn-id: svn://kolibrios.org@760 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/docs/sysfuncr.txt | 37 ++++++++++++++----- kernel/trunk/docs/sysfuncs.txt | 39 +++++++++++++++----- kernel/trunk/kernel.asm | 67 +++++++++++++++++++++------------- 3 files changed, 97 insertions(+), 46 deletions(-) diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index 77fd9b76ad..a19a516008 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -2036,26 +2036,43 @@ dd 638 * eax = -1 для некорректного ebx ====================================================================== -========== Функция 42 - прочитать данные, полученные по IRQ. ========= +========== Функция 42 - работа с данными, полученными по IRQ. ======= ====================================================================== + +------------------------ Чтение данных ------------------------------- При возникновении IRQ система может считывать данные из указанных ранее функцией 44 портов и записывать эти данные в буфер. -Описываемая функция считывает побайтно данные из этого буфера. +Описываемая функция считывает данные из этого буфера в буфер +указанный в качестве параметра. Параметры: * eax = 42 - номер функции - * ebx = номер IRQ, 0..15 -Возвращаемое значение: (ситуацию можно различить по значению ecx) + * bl = номер IRQ, 0..15 + * bh = номер подфункции, 0 +Остальная часть регистра ebx должна быть обнулена. + * ecx = указатель на буфер, куда будут приниматься данные +Возвращаемое значение: (ситуацию можно различить по значению eax) * если поток не является владельцем IRQ (или номер IRQ задан неверно): - * ecx = 2 + * eax = -1 * если данных нет: * eax = 0 - * ecx = 1 - * ebx разрушается * если всё в порядке и данные были: - * eax = размер данных, ещё не прочитанных из буфера (в байтах) - * ecx = 0 - * ebx = очередной байт + * eax = размер данных, прочитанных из буфера (в байтах) + +Смотрите замечания ниже. + +------------------------ Узнать размер данных в буфере --------------- +Параметры: + * eax = 42 - номер функции + * bl = номер IRQ, 0..15 + * bh = номер подфункции, 1 +Остальная часть регистра ebx должна быть обнулена. +Возвращаемое значение: (ситуацию можно различить по значению eax) + * если поток не является владельцем IRQ + (или номер IRQ задан неверно): + * eax = -1 + * если всё в порядке, в eax размер данных + Замечания: * Предварительно поток должен зарезервировать для себя указанный IRQ функцией 45. diff --git a/kernel/trunk/docs/sysfuncs.txt b/kernel/trunk/docs/sysfuncs.txt index eb3c09dfe6..d3d4ae73ba 100644 --- a/kernel/trunk/docs/sysfuncs.txt +++ b/kernel/trunk/docs/sysfuncs.txt @@ -2010,26 +2010,45 @@ Returned value: * eax = -1 for incorrect ebx ====================================================================== -==================== Function 42 - read IRQ data. ==================== +==================== Function 42 - work with IRQ data. =============== ====================================================================== + +------------------------ Reading data -------------------------------- + When an IRQ occurs, the system reads data from ports indicated earlier by function 44 and writes this data to internal buffer. This function reads out data from that buffer -bytewise. +to the buffer specified as parameter. Parameters: * eax = 42 - function number - * ebx = IRQ number, 0..15 -Returned value: (use value of ecx to distinguish) + * bl = IRQ number, 0..15 + * bh = subfunction number, 0 +Other part of register ebx, must be zero. + * ecx = pointer to the receive buffer +Returned value: (use value of eax to distinguish) * if the thread is not IRQ owner (or IRQ number is incorrect): - * ecx = 2 + * eax = -1 * if there is no data: * eax = 0 - * ecx = 1 - * ebx destroyed * if all is ok: - * eax = byte size of data, not yet read from buffer - * ecx = 0 - * ebx = current byte + * eax = byte size of data, read from buffer + +See remarks below. + +------------------------ Get data size ------------------------------- + +Parameters: + * eax = 42 - function number + * bl = IRQ number, 0..15 + * bh = subfunction number, 0 +Other part of register ebx, must be zero. + * ecx = pointer to receive buffer +Returned value: (use value of eax to distinguish) + * if the thread is not IRQ owner (or IRQ number is incorrect): + * eax = -1 + * if all is ok: + * eax = byte size of data in buffer + Remarks: * Previously the thread must reserve indicated IRQ for itself by function 45. diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index ccb92737ca..8fc92e46fa 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -3933,52 +3933,67 @@ sys_programirq: align 4 get_irq_data: - cmp ebx,16 + movzx esi, bh ; save number of subfunction, if bh = 1, return data size, otherwise, read data + xor bh, bh + cmp ebx, 16 jae .not_owner - mov eax, [4 * ebx + irq_owner] + mov edx, [4 * ebx + irq_owner] ; check for irq owner - mov edi,[TASK_BASE] + mov eax,[TASK_BASE] - cmp eax,[edi+TASKDATA.pid] + cmp edx,[eax+TASKDATA.pid] je gidril1 .not_owner: - mov [esp+28],dword 2 ; ecx=2 - ret + xor edx, edx + dec edx + jmp gid1 gidril1: - shl ebx,12 - xor ecx, ecx - inc ecx - lea eax,[ebx + IRQ_SAVE] - mov edx,[eax] - test edx,edx + shl ebx, 12 + lea eax, [ebx + IRQ_SAVE] ; calculate address of the beginning of buffer + 0x0 - data size + mov edx, [eax] ; + 0x4 - data offset + dec esi + jz gid1 + test edx, edx ; check if buffer is empty jz gid1 - dec edx - mov [eax], edx + mov ebx, [eax + 0x4] + mov edi, ecx - mov ecx, [eax + 0x4] + mov ecx, 4000 ; buffer size, used frequently - cmp ecx, 4000 + cmp ebx, ecx ; check for the end of buffer, if end of buffer, begin cycle again jb @f - xor ecx, ecx + xor ebx, ebx @@: - inc ecx - mov [eax + 0x4], ecx - dec ecx - add eax, ecx - movzx ebx,byte [eax + 0x10] + lea esi, [ebx + edx] ; calculate data size and offset + cld + cmp esi, ecx ; if greater than the buffer size, begin cycle again + jbe @f - xor ecx, ecx + sub ecx, ebx + sub edx, ecx + + lea esi, [eax + ebx + 0x10] + rep movsb + + xor ebx, ebx + @@: + lea esi, [eax + ebx + 0x10] + mov ecx, edx + add ebx, edx + + rep movsb + mov edx, [eax] + mov [eax], ecx ; set data size to zero + mov [eax + 0x4], ebx ; set data offset gid1: - mov [esp+32],edx - mov [esp+28],ecx - mov [esp+20],ebx + mov [esp+32], edx ; eax ret