diff --git a/kernel/trunk/core/mem.inc b/kernel/trunk/core/mem.inc deleted file mode 100644 index 16aed7c3cf..0000000000 --- a/kernel/trunk/core/mem.inc +++ /dev/null @@ -1,469 +0,0 @@ -if ~defined mem_inc -mem_inc_fix: -mem_inc fix mem_inc_fix -;include "memmanag.inc" -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;High-level memory management in MenuetOS. -;;It uses memory manager in memmanager.inc -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -second_base_address=0xC0000000 -std_application_base_address=0x10000000 -general_page_table_ dd 0 -general_page_table=general_page_table_+second_base_address -;----------------------------------------------------------------------------- -create_general_page_table: -;input -; none -;output -; none -;Procedure create general page directory and write -;it address to [general_page_table]. - pushad - mov eax,1 ;alloc 1 page - mov ebx,general_page_table ;write address to [general_page_table] - call MEM_Alloc_Pages ;allocate page directory - mov eax,[general_page_table] - call MEM_Get_Linear_Address ;eax - linear address of page directory - mov edi,eax - mov ebx,eax ;copy address of page directory to safe place - xor eax,eax - mov ecx,4096/4 - cld - rep stosd ;clear page directory - - mov eax,4 - mov edx,eax - call MEM_Alloc_Pages ;alloc page tables for 0x0-0x1000000 region - cmp eax,edx - jnz $ ;hang if not enough memory - -;fill page tables - xor esi,esi - mov ebp,7 - -.loop: -;esi - number of page in page directory -;ebp - current page address -;ebx - linear address of page directory - mov eax,[ebx+4*esi] - add dword [ebx+4*esi],7 ;add flags to address of page table - call MEM_Get_Linear_Address -;eax - linear address of page table - mov ecx,4096/4 -;ecx (counter) - number of pages in page table -;current address=4Mb*esi - -.loop1: - mov [eax],ebp ;write page address (with flags) in page table - add eax,4 - add ebp,4096 ;size of page=4096 bytes - loop .loop1 - - inc esi ;next page directory entry - cmp esi,edx - jnz .loop - -;map region 0x80000000-0x807fffff to LFB - mov eax,2 ;size of the region is 4Mb so only 1 page table needed - mov edx,ebx ;ebx still contains linear address of the page directory - add ebx,0x800 - call MEM_Alloc_Pages ;alloc page table for the region - mov eax,[ebx] - add dword [ebx],7 ;add flags - call MEM_Get_Linear_Address ;get linear address of the page table - mov ecx,4096/4 ;number of pages in page table - mov edi,[0xfe80] - add edi,7 -.loop3: -;eax - linear address of page table -;edi - current linear address with flags - mov [eax],edi - add eax,4 - add edi,4096 - loop .loop3 - mov eax,[ebx+4] - call MEM_Get_Linear_Address - add dword [ebx+4],7 - mov ecx,4096/4 -.loop31: - mov [eax],edi - add eax,4 - add edi,4096 - loop .loop31 - -;map region 0xC0000000-* to 0x0-* - mov esi,edx ;esi=linear address of the page directory - lea edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00) - mov ecx,4 - rep movsd ;first 16Mb of the region mapped as 0x0-0x1000000 block - mov eax,[0xfe8c] ;eax=memory size - add eax,0x3fffff - shr eax,22 - mov esi,eax ;calculate number of entries in page directory - sub esi,4 ;subtract entries for first 16Mb. - mov ebp,0x1000000+7 ;start physical address with flags - -;mapping memory higher than 16Mb -.loop4: -;esi (counter) - number of entries in page directory -;edi - address of entry - test esi,esi - jle .loop4end - call MEM_Alloc_Page ;alloc page table for entry in page directory - mov [edi],eax - add dword [edi],7 ;write physical address of page table in page directory - add edi,4 ;move entry pointer - call MEM_Get_Linear_Address - mov ecx,eax - xor edx,edx - -.loop5: -;ecx - linear address of page table -;edx - index of page in page table -;ebp - current mapped physical address with flags - mov [ecx+4*edx],ebp ;write address of page in page table - add ebp,0x1000 ;move to next page - inc edx - cmp edx,4096/4 - jl .loop5 - - dec esi - jmp .loop4 -.loop4end: - -.set_cr3: -;set value of cr3 register to the address of page directory - mov eax,[general_page_table] - add eax,8+16 ;add flags - mov cr3,eax ;now we have full access paging - - popad - ret -;----------------------------------------------------------------------------- -simple_clone_cr3_table: -;Parameters: -; eax - physical address of cr3 table (page directory) -;result: -; eax - physical address of clone of cr3 table. -;Function copy only page directory. - push ecx - push edx - push esi - push edi - call MEM_Get_Linear_Address -;eax - linear address of cr3 table - mov esi,eax - call MEM_Alloc_Page - test eax,eax - jz .failed -;eax - physical address of new page diretory - mov edx,eax - call MEM_Get_Linear_Address - mov edi,eax - mov ecx,4096/4 - cld -;esi - address of old page directory -;edi - address of new page directory - rep movsd ;copy page directory - mov eax,edx -.failed: - pop edi - pop esi - pop edx - pop ecx - ret - -;----------------------------------------------------------------------------- -create_app_cr3_table: -;Parameters: -; eax - slot of process (index in 0x3000 table) -;result: -; eax - physical address of table. -;This function create page directory for new process and -;write it physical address to offset 0xB8 of extended -;process information. - push ebx - - mov ebx,eax - mov eax,[general_page_table] - call simple_clone_cr3_table ;clone general page table - shl ebx,8 - mov [second_base_address+0x80000+ebx+APPDATA.dir_table],eax ;save address of page directory - - pop ebx - ret -;----------------------------------------------------------------------------- -get_cr3_table: -;Input: -; eax - slot of process -;result: -; eax - physical address of page directory - shl eax,8 ;size of process extended information=256 bytes - mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table] - ret -;----------------------------------------------------------------------------- -dispose_app_cr3_table: -;Input: -; eax - slot of process -;result: -; none -;This procedure frees page directory, -;page tables and all memory of process. - pushad - mov ebp,eax -;ebp = process slot in the procedure. - shl eax,8 - mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table] - mov ebx,eax -;ebx = physical address of page directory - call MEM_Get_Linear_Address - mov edi,eax -;edi = linear address of page directory - mov eax,[edi+(std_application_base_address shr 20)] - and eax,not (4096-1) - call MEM_Get_Linear_Address - mov esi,eax -;esi = linear address of first page table - -;search threads -; mov ecx,0x200 - xor edx,edx - mov eax,0x2 - -.loop: -;eax = current slot of process - mov ecx,eax - shl ecx,5 - cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9 ;if process running? - jz .next ;skip empty slots - shl ecx,3 - cmp [second_base_address+0x80000+ecx+APPDATA.dir_table],ebx ;compare page directory addresses - jnz .next - inc edx ;thread found -.next: - inc eax - cmp eax,[0x3004] ;exit loop if we look through all processes - jle .loop - -;edx = number of threads -;our process is zombi so it isn't counted - cmp edx,1 - jg .threadsexists -;if there isn't threads then clear memory. - add edi,std_application_base_address shr 20 - -.loop1: -;edi = linear address of current directory entry -;esi = linear address of current page table - test esi,esi - jz .loop1end - xor ecx,ecx - -.loop2: -;ecx = index of page - mov eax,[esi+4*ecx] - test eax,eax - jz .loopend ;skip empty entries - and eax,not (4096-1) ;clear flags - push ecx - call MEM_Free_Page ;free page - pop ecx -.loopend: - inc ecx - cmp ecx,1024 ;there are 1024 pages in page table - jl .loop2 - - mov eax,esi - call MEM_Free_Page_Linear ;free page table -.loop1end: - add edi,4 ;move to next directory entry - mov eax,[edi] - and eax,not (4096-1) - call MEM_Get_Linear_Address - mov esi,eax ;calculate linear address of new page table - test edi,0x800 - jz .loop1 ;test if we at 0x80000000 address? - - and edi,not (4096-1) ;clear offset of page directory entry - mov eax,edi - call MEM_Free_Page_Linear ;free page directory - popad - ret - -.threadsexists: ;do nothing - popad ;last thread will free memory - ret -;----------------------------------------------------------------------------- -mem_alloc_specified_region: -;eax - linear directory address -;ebx - start address (aligned to 4096 bytes) -;ecx - size in pages -;result: -; eax=1 - ok -; eax=0 - failed -;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval. - pushad - mov ebp,ebx ;save start address for recoil - mov esi,eax -.gen_loop: -;esi = linear directory address -;ebx = current address -;ecx = remaining size in pages - mov edx,ebx - shr edx,22 - mov edi,[esi+4*edx] ;find directory entry for current address - test edi,edi - jnz .table_exists ;check if page table allocated - call MEM_Alloc_Page ;alloc page table - test eax,eax - jz .failed - mov [esi+4*edx],eax - add dword [esi+4*edx],7 ;write it address with flags - call MEM_Get_Linear_Address - call mem_fill_page ;clear page table - jmp .table_linear -.table_exists: -;calculate linear address of page table - mov eax,edi - and eax,not (4096-1) ;clear flags - call MEM_Get_Linear_Address -.table_linear: -;eax = linear address of page table - mov edx,ebx - shr edx,12 - and edx,(1024-1) ;calculate index in page table - mov edi,eax - -.loop: -;edi = linear address of page table -;edx = current page table index -;ecx = remaining size in pages -;ebx = current address - test ecx,ecx - jle .endloop1 ;all requested pages allocated - - call MEM_Alloc_Page ;alloc new page - test eax,eax - jz .failed - mov [edi+4*edx],eax - add dword [edi+4*edx],7 ;write it address with flags - call MEM_Get_Linear_Address - call mem_fill_page ;clear new page -;go to next page table entry - dec ecx - add ebx,4096 - inc edx - test edx,(1024-1) - jnz .loop - - jmp .gen_loop - -.endloop1: - popad - mov eax,1 ;ok - ret - -.failed: -;calculate data for recoil - sub ebx,ebp - shr ebx,12 - mov ecx,ebx ;calculate number of allocated pages - mov eax,esi ;restore linear address of page directory - mov ebx,ebp ;restore initial address - call mem_free_specified_region ;free all allocated pages - popad - xor eax,eax ;fail - ret -;----------------------------------------------------------------------------- -mem_fill_page: -;Input: -; eax - address -;result: -; none -;set to zero 4096 bytes at eax address. - push ecx - push edi - mov edi,eax - mov ecx,4096/4 - xor eax,eax - rep stosd - lea eax,[edi-4096] - pop edi - pop ecx - ret -;----------------------------------------------------------------------------- -mem_free_specified_region: -;eax - linear page directory address -;ebx - start address (aligned to 4096 bytes) -;ecx - size in pages -;result - none -;Free pages in [ebx;ebx+4096*ecx) region. - pushad - mov esi,eax - xor ebp,ebp - -.gen_loop: -;esi = linear page directory address -;ebx = current address -;ecx = remaining pages -;ebp = 0 for first page table -; 1 otherwise - mov edx,ebx - shr edx,22 - mov eax,[esi+4*edx] ;find directory entry for current address - and eax,not (4096-1) - test eax,eax - jnz .table_exists -;skip absent page tables - mov edx,ebx - shr edx,12 - and edx,(1024-1) ;edx - index of current page - add ebx,1 shl 22 - add ecx,edx - and ebx,not ((1 shl 22)-1) - mov ebp,1 ;set flag - sub ecx,1024 ;ecx=ecx-(1024-edx) - jg .gen_loop - popad - ret -.table_exists: - call MEM_Get_Linear_Address -;eax - linear address of table - mov edx,ebx - shr edx,12 - and edx,(1024-1) ;edx - index of current page - mov edi,eax - -.loop: -;edi = linear address of page table entry -;edx = index of page table entry -;ecx = remaining pages - test ecx,ecx - jle .endloop1 - - mov eax,[edi+4*edx] - and eax,not (4096-1) - call MEM_Free_Page ;free page - mov dword [edi+4*edx],0 ;and clear page table entry - dec ecx - inc edx - cmp edx,1024 - jl .loop - - test ebp,ebp - jz .first_page - mov eax,edi - call MEM_Free_Page_Linear ;free page table - mov edx,ebx - shr edx,22 - mov dword [esi+4*edx],0 ;and clear page directory entry -.first_page: - add ebx,1 shl 22 - and ebx,not ((1 shl 22)-1) ;calculate new current address - mov ebp,1 ;set flag - jmp .gen_loop - -.endloop1: - popad - ret -end if diff --git a/kernel/trunk/core/memmanag.inc b/kernel/trunk/core/memmanag.inc deleted file mode 100644 index 7055213ac1..0000000000 --- a/kernel/trunk/core/memmanag.inc +++ /dev/null @@ -1,833 +0,0 @@ -if ~defined memmanager_inc -memmanager_inc_fix: -memmanager_inc fix memmanager_inc_fix -;for testing in applications -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Memory allocator for MenuetOS kernel -;; Andrey Halyavin, halyavin@land.ru 2005 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; heap block structure - -;; you can handle several ranges of -;; pages simultaneosly. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -.heap_linear_address equ 0 -.heap_block_size equ 4 -.heap_physical_address equ 8 -.heap_reserved equ 12 -.heap_block_info equ 16 -max_heaps equ 8 -.range_info equ 36 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; memory manager data -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -uglobal - MEM_heap_block rd .heap_block_info*max_heaps/4 - MEM_heap_count rd 1 - MEM_cli_count rd 1 - MEM_cli_prev rd 1 - MEM_FreeSpace rd 1 -; MEM_AllSpace rd 1 -endg -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Init -;;Initialize memory manager structures. -;;Must be called first. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -MEM_Init: - push eax - xor eax,eax - mov [MEM_cli_prev],eax ;init value = 0 - dec eax - mov [MEM_cli_count],eax ;init value = -1 - pop eax - ret -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Heap_Lock -;;Wait until all operations with heap will be finished. -;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations -;;with heap are forbidden. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -MEM_Heap_Lock: - pushfd - cli - inc dword [MEM_cli_count] - jz MEM_Heap_First_Lock - add esp,4 - ret -MEM_Heap_First_Lock: ;save interrupt flag - shr dword [esp],9 - and dword [esp],1 - pop dword [MEM_cli_prev] - ret -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Heap_UnLock -;;After this routine operations with heap are allowed. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -MEM_Heap_UnLock: - dec dword [MEM_cli_count] - js MEM_Heap_UnLock_last - ret -MEM_Heap_UnLock_last: - cmp dword [MEM_cli_prev],0 ;restore saved interrupt flag - jz MEM_Heap_UnLock_No_sti - sti -MEM_Heap_UnLock_No_sti: - ret -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Add_Heap -;;Add new range to memory manager. -;;eax - linear address -;;ebx - size in pages -;;ecx - physical address -;;Result: -;; eax=1 - success -;; eax=0 - failed -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -MEM_Add_Heap: - push edx - call MEM_Heap_Lock - mov edx,[MEM_heap_count] - cmp edx,max_heaps - jz MEM_Add_Heap_Error - inc dword [MEM_heap_count] - shl edx,4 - mov [MEM_heap_block+edx+.heap_linear_address],eax - mov [MEM_heap_block+edx+.heap_block_size],ebx - shl dword [MEM_heap_block+edx+.heap_block_size],12 - mov [MEM_heap_block+edx+.heap_physical_address],ecx - lea edx,[4*ebx+.range_info+4095] ;calculate space for page info table - and edx,0xFFFFF000 - - push edi - mov edi,edx - shr edi,12 - sub edi,ebx ;edi=-free space - sub [MEM_FreeSpace],edi -; sub [MEM_AllSpace],edi - - mov [eax],eax - add [eax],edx ;first 4 bytes - pointer to first free page -;clean page info area - lea edi,[eax+4] - mov ecx,edx - shr ecx,2 - push eax - xor eax,eax - rep stosd - pop eax - pop edi -;create free pages list. - mov ecx,[eax] - shl ebx,12 - add eax,ebx ;eax - address after block -MEM_Add_Heap_loop: - add ecx,4096 - mov [ecx-4096],ecx ;set forward pointer - cmp ecx,eax - jnz MEM_Add_Heap_loop - mov dword [ecx-4096],0 ;set end of list -MEM_Add_Heap_ret: - call MEM_Heap_UnLock - pop edx - ret -MEM_Add_Heap_Error: - xor eax,eax - jmp MEM_Add_Heap_ret -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Get_Physical_Address -;;Translate linear address to physical address -;;Parameters: -;; eax - linear address -;;Result: -;; eax - physical address -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Get_Physical_Address -MEM_Get_Physical_Address: - push ecx - call MEM_Heap_Lock - mov ecx,[MEM_heap_count] - dec ecx - shl ecx,4 -MEM_Get_Physical_Address_loop: - sub eax,[MEM_heap_block+ecx+.heap_linear_address] - jl MEM_Get_Physical_Address_next - cmp eax,[MEM_heap_block+ecx+.heap_block_size] - jge MEM_Get_Physical_Address_next - add eax,[MEM_heap_block+ecx+.heap_physical_address] - jmp MEM_Get_Physical_Address_loopend -MEM_Get_Physical_Address_next: - add eax,[MEM_heap_block+ecx+.heap_linear_address] - sub ecx,16 - jns MEM_Get_Physical_Address_loop - xor eax,eax ;address not found -MEM_Get_Physical_Address_loopend: - call MEM_Heap_UnLock - pop ecx - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Get_Linear_Address -;;Translate physical address to linear address. -;;Parameters: -;; eax - physical address -;;Result: -;; eax - linear address -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Get_Linear_Address -MEM_Get_Linear_Address: - push ecx - call MEM_Heap_Lock - mov ecx,[MEM_heap_count] - dec ecx - shl ecx,4 -MEM_Get_Linear_Address_loop: - sub eax,[MEM_heap_block+ecx+.heap_physical_address] - jl MEM_Get_Linear_Address_Next - cmp eax,[MEM_heap_block+ecx+.heap_block_size] - jge MEM_Get_Linear_Address_Next - add eax,[MEM_heap_block+ecx+.heap_linear_address] - call MEM_Heap_UnLock - pop ecx - ret -MEM_Get_Linear_Address_Next: - add eax,[MEM_heap_block+ecx+.heap_physical_address] - sub ecx,16 - jns MEM_Get_Linear_Address_loop - call MEM_Heap_UnLock - pop ecx - xor eax,eax ;address not found - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Alloc_Page -;;Allocate and add reference to page -;;Result: -;; eax<>0 - physical address of page -;; eax=0 - not enough memory -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Alloc_Page -MEM_Alloc_Page: - push ecx - call MEM_Heap_Lock - mov ecx,[MEM_heap_count] - dec ecx - shl ecx,4 -MEM_Alloc_Page_loop: - push ecx - mov ecx,[MEM_heap_block+ecx+.heap_linear_address] - cmp dword [ecx],0 - jz MEM_Alloc_Page_loopend - mov eax,[ecx] - push dword [eax] - pop dword [ecx] - sub eax,ecx - push eax - shr eax,10 - mov word [ecx+.range_info+eax],1 - pop eax - pop ecx - add eax,[MEM_heap_block+ecx+.heap_physical_address] - dec [MEM_FreeSpace] - jmp MEM_Alloc_Page_ret -MEM_Alloc_Page_loopend: - pop ecx - sub ecx,16 - jns MEM_Alloc_Page_loop - xor eax,eax -MEM_Alloc_Page_ret: - call MEM_Heap_UnLock - pop ecx - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Alloc_Page_Linear -;;Allocate and add reference to page -;;Result: -;; eax<>0 - linear address of page -;; eax=0 - not enough memory -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Alloc_Page_Linear -MEM_Alloc_Page_Linear: - push ecx - call MEM_Heap_Lock - mov ecx,[MEM_heap_count] - dec ecx - shl ecx,4 -MEM_Alloc_Page_Linear_loop: - push ecx - mov ecx,[MEM_heap_block+ecx+.heap_linear_address] - cmp dword [ecx],0 - jz MEM_Alloc_Page_Linear_loopend - mov eax,[ecx] - push dword [eax] - pop dword [ecx] - push eax - sub eax,ecx - shr eax,10 - mov word [ecx+.range_info+eax],1 - pop eax - pop ecx - dec [MEM_FreeSpace] - jmp MEM_Alloc_Page_Linear_ret -MEM_Alloc_Page_Linear_loopend: - pop ecx - sub ecx,16 - jns MEM_Alloc_Page_Linear_loop - xor eax,eax -MEM_Alloc_Page_Linear_ret: - call MEM_Heap_UnLock - pop ecx - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Free_Page -;;Remove reference and free page if number of -;;references is equal to 0 -;;Parameters: -;; eax - physical address of page -;;Result: -;; eax - 1 success -;; eax - 0 failed -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if (used MEM_Free_Page) | (used MEM_Free_Page_Linear) -MEM_Free_Page: - test eax,eax - jz MEM_Free_Page_Zero - test eax,0xFFF - jnz MEM_Free_Page_Not_Aligned - push ebx - push ecx - push edx - call MEM_Heap_Lock - mov ecx,[MEM_heap_count] - dec ecx - shl ecx,4 -MEM_Free_Page_Heap_loop: - sub eax,[MEM_heap_block+ecx+.heap_physical_address] - js MEM_Free_Page_Heap_loopnext - cmp eax,[MEM_heap_block+ecx+.heap_block_size] - jl MEM_Free_Page_Heap_loopend -MEM_Free_Page_Heap_loopnext: - add eax,[MEM_heap_block+ecx+.heap_physical_address] - sub ecx,16 - jns MEM_Free_Page_Heap_loop - xor eax,eax - inc eax - jmp MEM_Free_Page_ret -MEM_Free_Page_Heap_loopend: - mov ecx,[MEM_heap_block+ecx+.heap_linear_address] - mov ebx,eax - add eax,ecx - shr ebx,10 - mov edx,[ecx+.range_info+ebx] - test edx,0x80000000 - jnz MEM_Free_Page_Bucket - test dx,dx - jz MEM_Free_Page_Error - dec word [ecx+.range_info+ebx] - jnz MEM_Free_Page_OK -MEM_Free_Page_Bucket: - push dword [ecx] - mov [ecx],eax - pop dword [eax] - mov dword [ecx+.range_info+ebx],0 - inc [MEM_FreeSpace] -MEM_Free_Page_OK: - mov eax,1 -MEM_Free_Page_ret: - call MEM_Heap_UnLock - pop edx - pop ecx - pop ebx - ret -MEM_Free_Page_Error: - xor eax,eax - jmp MEM_Free_Page_ret -MEM_Free_Page_Zero: - inc eax - ret -MEM_Free_Page_Not_Aligned: - xor eax,eax - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Free_Page_Linear -;;Remove reference and free page if number of -;;references is equal to 0 -;;Parameters: -;; eax - linear address of page -;;Result: -;; eax - 1 success -;; eax - 0 failed -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Free_Page_Linear -MEM_Free_Page_Linear: - test eax,eax - jz MEM_Free_Page_Zero - test eax,0xFFF - jnz MEM_Free_Page_Not_Aligned - push ebx - push ecx - push edx - call MEM_Heap_Lock - mov ecx,[MEM_heap_count] - dec ecx - shl ecx,4 - -MEM_Free_Page_Linear_Heap_loop: - sub eax,[MEM_heap_block+ecx+.heap_linear_address] - js MEM_Free_Page_Linear_Heap_loopnext - cmp eax,[MEM_heap_block+ecx+.heap_block_size] - jl MEM_Free_Page_Heap_loopend -MEM_Free_Page_Linear_Heap_loopnext: - add eax,[MEM_heap_block+ecx+.heap_linear_address] - sub ecx,16 - jns MEM_Free_Page_Linear_Heap_loop - xor eax,eax - inc eax - jmp MEM_Free_Page_ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Alloc_Pages -;;Allocates set of pages. -;;Parameters: -;; eax - number of pages -;; ebx - buffer for physical addresses -;;Result: -;; eax - number of allocated pages -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Alloc_Pages -MEM_Alloc_Pages: - push eax - push ebx - push ecx - mov ecx,eax - test ecx,ecx - jz MEM_Alloc_Pages_ret -MEM_Alloc_Pages_loop: - call MEM_Alloc_Page - test eax,eax - jz MEM_Alloc_Pages_ret - mov [ebx],eax - add ebx,4 - dec ecx - jnz MEM_Alloc_Pages_loop -MEM_Alloc_Pages_ret: - sub [esp+8],ecx - pop ecx - pop ebx - pop eax - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Alloc_Pages_Linear -;;Allocates set of pages. -;;Parameters: -;; eax - number of pages -;; ebx - buffer for linear addresses -;;Result: -;; eax - number of allocated pages -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Alloc_Pages_Linear -MEM_Alloc_Pages_Linear: - push eax - push ebx - push ecx - mov ecx,eax - test ecx,ecx - jz MEM_Alloc_Pages_Linear_ret -MEM_Alloc_Pages_Linear_loop: - call MEM_Alloc_Page_Linear - test eax,eax - jz MEM_Alloc_Pages_Linear_ret - mov [ebx],eax - add ebx,4 - dec ecx - jnz MEM_Alloc_Pages_Linear_loop -MEM_Alloc_Pages_Linear_ret: - sub [esp+8],ecx - pop ecx - pop ebx - pop eax - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Free_Pages -;;Parameters: -;; eax - number of pages -;; ebx - array of addresses -;;Result: -;; eax=1 - succcess -;; eax=0 - failed -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Free_Pages -MEM_Free_Pages: - push ebx - push ecx - mov ecx,eax - test ecx,ecx - jz MEM_Free_Pages_ret -MEM_Free_Pages_loop: - mov eax,[ebx] - call MEM_Free_Page - add ebx,4 - test eax,eax - jz MEM_Free_Pages_ret - dec ecx - jnz MEM_Free_Pages_loop -MEM_Free_Pages_ret: - pop ecx - pop ebx - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Free_Pages_Linear -;;Parameters: -;; eax - number of pages -;; ebx - array of addresses -;;Result: -;; eax=1 - succcess -;; eax=0 - failed -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Free_Pages_Linear -MEM_Free_Pages_Linear: - push ebx - push ecx - mov ecx,eax - test ecx,ecx - jz MEM_Free_Pages_Linear_ret -MEM_Free_Pages_Linear_loop: - mov eax,[ebx] - call MEM_Free_Page_Linear - add ebx,4 - test eax,eax - jz MEM_Free_Pages_Linear_ret - dec ecx - jnz MEM_Free_Pages_Linear_loop -MEM_Free_Pages_Linear_ret: - pop ecx - pop ebx - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Get_Heap_Number -;;Calculate number of heap which pointer belongs to. -;;Parameter: -;; eax - address -;;Result: -;; ecx - number of heap*16. -;; eax=0 if address not found. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Get_Heap_Number -MEM_Get_Heap_Number: - call MEM_Heap_Lock - mov ecx,[MEM_heap_count] - dec ecx - shl ecx,4 -MEM_Get_Heap_loop: - sub eax,[MEM_heap_block+ecx+.heap_physical_address] - jl MEM_Get_Heap_loopnext - cmp eax,[MEM_heap_block+ecx+.heap_block_size] - jl MEM_Get_Heap_loopend -MEM_Get_Heap_loopnext: - add eax,[MEM_heap_block+ecx+.heap_physical_address] - sub ecx,16 - jns MEM_Get_Heap_loop - call MEM_Heap_UnLock - xor eax,eax - ret -MEM_Get_Heap_loopend: - add eax,[MEM_heap_block+ecx+.heap_physical_address] - call MEM_Heap_UnLock - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Get_Heap_Number_Linear -;;Calculate number of heap which pointer belongs to. -;;Parameter: -;; eax - address -;;Result: -;; ecx - number of heap*16. -;; eax=0 if address not found. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -if used MEM_Get_Heap_Number_Linear -MEM_Get_Heap_Number_Linear: - call MEM_Heap_Lock - mov ecx,[MEM_heap_count] - dec ecx - shl ecx,4 -MEM_Get_Heap_Linear_loop: - sub eax,[MEM_heap_block+ecx+.heap_linear_address] - jl MEM_Get_Heap_Linear_loopnext - cmp eax,[MEM_heap_block+ecx+.heap_block_size] - jl MEM_Get_Heap_Linear_loopend -MEM_Get_Heap_Linear_loopnext: - add eax,[MEM_heap_block+ecx+.heap_linear_address] - sub ecx,16 - jns MEM_Get_Heap_Linear_loop - call MEM_Heap_UnLock - xor eax,eax - ret -MEM_Get_Heap_Linear_loopend: - add eax,[MEM_heap_block+ecx+.heap_linear_address] - call MEM_Heap_UnLock - ret -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;MEM_Alloc -;;Allocate small region. -;;Parameters: -;; eax - size (00 - ok -; 0 - failed. -;This function find least empty slot. -;It doesn't increase [0x3004]! - mov eax,0x3000+second_base_address - push ebx - mov ebx,[0x3004] - 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+TASKDATA.state],9 ;check process state, 9 means that process slot is empty - jnz .newprocessplace -.endnewprocessplace: - mov ebx,eax - sub eax,0x3000+second_base_address - shr eax,5 ;calculate slot index - cmp eax,256 - jge .failed ;it should be <256 - mov word [ebx+TASKDATA.state],9 ;set process state to 9 (for slot after hight boundary) - mov [new_process_place],eax ;save process slot - pop ebx - ret -.failed: - xor eax,eax - pop ebx - ret -;----------------------------------------------------------------------------- -safe_sti: - cmp byte [0xe000], 1 - jne @f - sti - @@:ret - -;----------------------------------------------------------------------------- -new_sys_threads: -;eax=1 - create thread -; ebx=thread start -; ecx=thread stack value -;result: -; eax=pid - xor edx,edx ; flags=0 - pushad - - cmp eax,1 - jnz .ret ;other subfunctions - mov esi,new_process_loading - call sys_msg_board_str -;lock application_table_status mutex -.table_status: - cli - cmp [application_table_status],0 - je .stf - sti - call change_task - jmp .table_status -.stf: - call set_application_table_status -;find free process slot - - call find_new_process_place - test eax,eax - jz .failed - -;set parameters for thread - xor eax,eax - mov [app_i_param],eax - mov [app_i_icon],eax - mov [app_start],ebx - mov [app_esp],ecx - - mov esi,[0x3000] - shl esi,8 - add esi,0x80000+APPDATA.app_name - mov ebx,esi ;ebx=esi - pointer to extended information about current thread - - mov edi,[new_process_place] - shl edi,8 - add edi,0x80000 - lea edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread - mov ecx,256/4 - rep stosd ;clean extended information about new thread - mov edi,edx - mov ecx,11 - rep movsb ;copy process name - mov eax,[ebx+APPDATA.mem_size] - mov [app_mem],eax ;set memory size - mov eax,[ebx+APPDATA.dir_table] - mov dword [edx-APPDATA.app_name+APPDATA.dir_table],eax ;copy page directory -; mov eax,[new_process_place] -; mov ebx,[0x3000] -; call addreference_app_cr3_table - - push 0 ;no parameters - call fs_execute.add_app_parameters ;start thread - mov [esp+28],eax - popad - ret - -.failed: - sti - popad - mov eax,-1 - ret -.ret: - popad - ret -;----------------------------------------------------------------------------- -new_mem_resize: -;input: -; ebx - new size -;result: -; [esp+36]:=0 - normal -; [esp+36]:=1 - error -;This function set new application memory size. - mov esi,ebx ;save new size - add ebx,4095 - and ebx,not (4096-1) ;round up size - mov ecx,[0x3000] - shl ecx,8 - mov edx,[0x80000 + APPDATA.mem_size +ecx] - add edx,4095 - and edx,not (4096-1) ;old size - mov eax,[0x80000 + APPDATA.dir_table+ecx] - call MEM_Get_Linear_Address -;eax - linear address of page directory - call MEM_Heap_Lock ;guarantee that two threads willn't - ;change memory size simultaneously - cmp ebx,edx -; mov esi,ebx ;save new size - jg .expand - -.free: - sub edx,ebx - jz .unlock ;do nothing - mov ecx,edx - shr ecx,12 - add ebx,std_application_base_address - call mem_free_specified_region ;free unnecessary pages - jmp .unlock - -.expand: - sub ebx,edx - mov ecx,ebx - shr ecx,12 - mov ebx,edx - add ebx,std_application_base_address - call mem_alloc_specified_region ;alloc necessary pages - test eax,eax - jz .failed ;not enough memory - -.unlock: - mov ebx,esi - mov eax,[0x3000] - shl eax,8 - mov [eax+0x80000 + APPDATA.mem_size],ebx ;write new memory size -;search threads and update -;application memory size infomation - mov ecx,[eax+0x80000 + APPDATA.dir_table] - mov eax,2 - -.search_threads: -;eax = current slot -;ebx = new memory size -;ecx = page directory - cmp eax,[0x3004] - jg .search_threads_end - mov edx,eax - shl edx,5 - cmp word [0x3000+edx+TASKDATA.state],9 ;if slot empty? - jz .search_threads_next - shl edx,3 - cmp [edx+0x80000+APPDATA.dir_table],ecx ;if it is our thread? - jnz .search_threads_next - mov [edx+0x80000+APPDATA.mem_size],ebx ;update memory size -.search_threads_next: - inc eax - jmp .search_threads -.search_threads_end: - - call MEM_Heap_UnLock - mov dword [esp+36],0 - ret - -.failed: - call MEM_Heap_UnLock - mov dword [esp+36],1 - ret -;----------------------------------------------------------------------------- -pid_to_slot: -;Input: -; eax - pid of process -;Output: -; eax - slot of process or 0 if process don't exists -;Search process by PID. - push ebx - push ecx - mov ebx,[0x3004] - shl ebx,5 - mov ecx,2*32 - -.loop: -;ecx=offset of current process info entry -;ebx=maximum permitted offset - cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9 - jz .endloop ;skip empty slots - cmp [second_base_address+0x3000+ecx+TASKDATA.pid],eax ;check PID - jz .pid_found -.endloop: - add ecx,32 - cmp ecx,ebx - jle .loop - - pop ecx - pop ebx - xor eax,eax - ret - -.pid_found: - shr ecx,5 - mov eax,ecx ;convert offset to index of slot - pop ecx - pop ebx - ret -;----------------------------------------------------------------------------- -is_new_process: -;Input: -; eax - process slot -;Output: -; eax=1 - it is new process -; eax=0 - it is old process -; shl eax,5 -; mov eax,[second_base_address+0x3000+eax+0x10] -; cmp eax,std_application_base_address ;check base address of application -; jz .new_process -; xor eax,eax -; ret - -;.new_process: - mov eax,1 - ret -;----------------------------------------------------------------------------- -write_process_memory: -;Input: -; eax - process slot -; ebx - buffer address -; ecx - buffer size -; edx - start address in other process -;Output: -; eax - number of bytes written - pushad - shl eax,8 - mov eax,[0x80000+eax+APPDATA.dir_table] - call MEM_Get_Linear_Address - mov ebp,eax -;ebp=linear address of page directory of other process. - add edx,std_application_base_address ;convert to linear address - test ecx,ecx - jle .ret - -.write_loop: -;ebx = current buffer address -;ecx>0 = current size -;edx = current address in other process -;ebp = linear address of page directory - - call MEM_Heap_Lock ;cli - mov esi,edx - shr esi,22 - mov eax,[ebp+4*esi] ;find page directory entry - and eax,not (4096-1) ;clear flags - test eax,eax - jz .page_not_found - call MEM_Get_Linear_Address ;calculate linear address of page table - test eax,eax - jz .page_not_found - mov esi,edx - shr esi,12 - and esi,1023 - mov eax,[eax+4*esi] ;find page table entry - and eax,not (4096-1) - test eax,eax - jz .page_not_found - call MEM_Get_Linear_Address ;calculate linear address of page - test eax,eax - jz .page_not_found - mov edi,eax - call MEM_Add_Reference_Linear;guarantee that page willn't disappear - call MEM_Heap_UnLock ;sti - - mov esi,edx - and esi,4095 - add edi,esi ;add offset in page -;edi = linear address corresponding edx in other process - sub esi,4096 - neg esi ;esi - number of remaining bytes in page - cmp esi,ecx - jl .min_ecx - mov esi,ecx -.min_ecx: ;esi=min(ecx,esi) - number of bytes to write - sub ecx,esi - push ecx - mov ecx,esi ;ecx - number of bytes to write - mov esi,ebx ;esi - source, edi - destination - add edx,ecx ;move pointer in address space of other process - push edi - -;move ecx bytes - test ecx,3 - jnz .not_aligned - shr ecx,2 - rep movsd - jmp .next_iter -.not_aligned: - rep movsb -.next_iter: - - pop eax - and eax,not (4096-1) ;eax - linear address of current page - call MEM_Free_Page_Linear ;free reference - mov ebx,esi ;new pointer to buffer - movsb automaticaly advance it. - pop ecx ;restore number of remaining bytes - test ecx,ecx - jnz .write_loop -.ret: - popad - mov eax,ecx - ret - -.page_not_found: - call MEM_Heap_UnLock ;error has appeared in critical region - sub ecx,[esp+24] ;[esp+24]<-->ecx - neg ecx ;ecx=number_of_written_bytes - mov [esp+28],ecx ;[esp+28]<-->eax - popad - ret -;----------------------------------------------------------------------------- -syscall_test: -;for testing memory manager from applications. - mov edx,ecx - mov ecx,ebx - call trans_address - mov ebx,eax - mov eax,[0x3000] - call read_process_memory - ret -;----------------------------------------------------------------------------- -read_process_memory: -;Input: -; eax - process slot -; ebx - buffer address -; ecx - buffer size -; edx - start address in other process -;Output: -; eax - number of bytes read. - pushad - shl eax,8 - mov eax,[0x80000+eax+APPDATA.dir_table] - call MEM_Get_Linear_Address - mov ebp,eax - add edx,std_application_base_address -.read_loop: -;ebx = current buffer address -;ecx>0 = current size -;edx = current address in other process -;ebp = linear address of page directory - - call MEM_Heap_Lock ;cli - mov esi,edx - shr esi,22 - mov eax,[ebp+4*esi] ;find page directory entry - and eax,not (4096-1) - test eax,eax - jz .page_not_found - call MEM_Get_Linear_Address - test eax,eax - jz .page_not_found - mov esi,edx - shr esi,12 - and esi,1023 - mov eax,[eax+4*esi] ;find page table entry - and eax,not (4096-1) - test eax,eax - jz .page_not_found - call MEM_Get_Linear_Address ;calculate linear address of page - test eax,eax - jz .page_not_found - mov esi,eax - call MEM_Add_Reference_Linear;guarantee that page willn't disappear - call MEM_Heap_UnLock ;sti - - mov edi,edx - and edi,4095 - add esi,edi ;add offset in page -;esi = linear address corresponding edx in other process - sub edi,4096 - neg edi - -;edi=min(edi,ecx) - number of bytes to copy - cmp edi,ecx - jl .min_ecx - mov edi,ecx -.min_ecx: - - sub ecx,edi ;update size of remaining bytes - add edx,edi ;update current pointer in other address space. - push ecx - mov ecx,edi ;ecx - number of bytes to read - mov edi,ebx ;esi - source, edi - destination - push esi -;move ecx bytes - test ecx,3 - jnz .not_aligned - shr ecx,2 - rep movsd - jmp .next_iter -.not_aligned: - rep movsb -.next_iter: - pop eax - and eax,not (4096-1) ;eax - linear address of current page - call MEM_Free_Page_Linear ;free reference - mov ebx,edi ;new pointer to buffer - movsb automaticaly advance it. - pop ecx ;restore number of remaining bytes - test ecx,ecx - jnz .read_loop - - popad - mov eax,ecx - ret - -.page_not_found: - call MEM_Heap_UnLock ;error has appeared in critical region - sub ecx,[esp+24] ;[esp+24]<-->ecx - neg ecx ;ecx=number_of_read_bytes - mov [esp+28],ecx ;[esp+28]<-->eax - popad - ret -;----------------------------------------------------------------------------- -check_region: -;input: -; ebx - start of buffer -; ecx - size of buffer -;result: -; eax = 1 region lays in app memory -; eax = 0 region don't lays in app memory - mov eax,[0x3000] - jmp check_process_region -;----------------------------------------------------------------------------- -check_process_region: -;input: -; eax - slot -; ebx - start of buffer -; ecx - size of buffer -;result: -; eax = 1 region lays in app memory -; eax = 0 region don't lays in app memory - test ecx,ecx - jle .ok - shl eax,5 - cmp word [0x3000+eax+TASKDATA.state],0 - jnz .failed - shl eax,3 - mov eax,[0x80000+eax+APPDATA.dir_table] - test eax,eax - jz .failed - 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 -;----------------------------------------------------------------------------- -new_sys_ipc: -;input: -; eax=1 - set ipc buffer area -; ebx=address of buffer -; ecx=size of buffer -; eax=2 - send message -; ebx=PID -; ecx=address of message -; edx=size of message - cmp eax,1 - jnz .no_ipc_def -;set ipc buffer area - mov edi,[0x3000] - shl edi,8 - add edi,0x80000 - cli - mov [edi+APPDATA.ipc_start],ebx ;set fields in extended information area - mov [edi+APPDATA.ipc_size],ecx - sti - mov [esp+36],dword 0 ;success - ret - -.no_ipc_def: - cmp eax,2 - jnz .no_ipc_send -;send message - cli -;obtain slot from PID - mov eax,ebx - call pid_to_slot - test eax,eax - jz .no_pid - mov ebp,eax -;ebp = slot of other process - shl eax,8 - mov edi,[eax+0x80000+APPDATA.ipc_start] ;is ipc area defined? - test edi,edi - jz .no_ipc_area - mov esi,[eax+0x80000+APPDATA.ipc_size] ;esi - size of buffer - push dword -1 ;temp variable for read_process_memory - mov ebx,esp - push ecx - push edx - mov ecx,4 ;read 4 bytes - mov eax,ebp - mov edx,edi ;from beginning of buffer. - call read_process_memory - mov eax,[esp+8] - test eax,eax - jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now - add edx,4 ;move to next 4 bytes - mov eax,ebp - call read_process_memory ;read size of occupied space in buffer - sub esi,8 - sub esi,[esp] - sub esi,[esp+8] ;esi=(buffer size)-(occupied size)-(message size)-(header of message size) - js .buffer_overflow ;esi<0 - not enough memory in buffer - mov esi,[esp+8] ;previous offset - add dword [esp+8],8 - mov edi,[esp] - add [esp+8],edi ;add (size of message)+(size of header of message) to [buffer+4] - mov eax,ebp - call write_process_memory - add edx,esi - sub edx,4 ;move to beginning of place for our message - mov eax,[second_base_address+0x3010] - mov eax,[eax+TASKDATA.pid] ;eax - our PID - mov [esp+8],eax - mov eax,ebp - call write_process_memory ;write PID - mov ebx,esp ;address of size of message - mov eax,ebp - add edx,4 - call write_process_memory ;write size of message - add edx,4 - pop ecx ;ecx - size of message - pop eax - call trans_address - mov ebx,eax ;ebx - linear address of message - add esp,4 ;pop temporary variable - mov eax,ebp - call write_process_memory ;write message - sti -;awake other process - shl ebp,8 - mov eax,ebp - or [eax+0x80000+APPDATA.event_mask],dword 0x40 - - cmp dword [check_idle_semaphore],20 - jge .ipc_no_cis - mov dword [check_idle_semaphore],5 -.ipc_no_cis: - mov dword [esp+36],0 - ret -.no_ipc_send: - mov dword [esp+36],-1 - ret -.no_pid: - sti - mov dword [esp+36],4 - ret -.no_ipc_area: - sti - mov dword [esp+36],1 - ret -.ipc_blocked: - sti - add esp,12 - mov dword [esp+36],2 - ret -.buffer_overflow: - sti - add esp,12 - mov dword [esp+36],3 - ret -;----------------------------------------------------------------------------- -trans_address: -;Input -; eax - application address -;Output -; eax - linear address for kernel - add eax,std_application_base_address - ret -;----------------------------------------------------------------------------- - -; \begin{diamond} - include 'debug.inc' - -fs_execute: -; ebx - cmdline -; edx - flags -; ebp - full filename -; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it - pushad -; check filename length - with terminating NULL must be no more than 1024 symbols - mov edi, ebp - mov ecx, 1024 - xor eax, eax - repnz scasb - jz @f - popad - mov eax, -ERROR_FILE_NOT_FOUND - ret -@@: - - mov esi, new_process_loading - call sys_msg_board_str ; write message to message board - -; lock application_table_status mutex -.table_status: - cli - cmp [application_table_status], 0 - jz .stf - sti - call change_task - jmp .table_status -.stf: - call set_application_table_status - push ebx ; save command line pointer for add_app_parameters - - call find_new_process_place ; find new process slot - call safe_sti - test eax, eax - mov ecx, -0x20 ; too many processes - jz .failed - -; write application name - push edi - mov ecx, edi - sub ecx, ebp - mov [appl_path], ebp - mov [appl_path_size], ecx - dec edi - std - mov al, '/' - repnz scasb - cld - jnz @f - inc edi -@@: - inc edi -; now edi points to name without path - mov esi, edi - mov ecx, 8 ; 8 chars for name - mov edi, [new_process_place] - shl edi, cl - add edi, 0x80000+APPDATA.app_name -.copy_process_name_loop: - lodsb - cmp al, '.' - jz .copy_process_name_done - test al, al - jz .copy_process_name_done - stosb - loop .copy_process_name_loop -.copy_process_name_done: - mov al, ' ' - rep stosb - pop eax - mov cl, 3 ; 3 chars for extension - dec esi -@@: - dec eax - cmp eax, esi - jbe .copy_process_ext_done - cmp byte [eax], '.' - jnz @b - lea esi, [eax+1] -.copy_process_ext_loop: - lodsb - test al, al - jz .copy_process_ext_done - stosb - loop .copy_process_ext_loop -.copy_process_ext_done: - mov al, ' ' - rep stosb - -; read header - lea eax, [esp+8+36] - mov edi, 0x90000 - call dword [eax-4] - mov ecx, eax - neg ecx - jnz .cleanfailed -; check menuet signature - mov ecx, -0x1F - cmp dword [0x90000], 'MENU' - jnz .cleanfailed - cmp word [0x90004], 'ET' - jnz .cleanfailed - call get_app_params - mov ecx, -0x1F - jc .cleanfailed -; sanity check - because we will load all file, -; file size must be not greater than memory size - mov eax, [esp+8+36] - cmp [app_mem], eax - jb .cleanfailed - - mov eax, [new_process_place] - inc ecx ; -0x1E = no memory - call create_app_cr3_table - test eax, eax - jz .cleanfailed_mem - - call MEM_Get_Linear_Address - - mov ebx, std_application_base_address - mov ecx, [app_mem] - add ecx, 4095 - shr ecx, 12 - mov edx, eax ; edx - linear address of page directory - call mem_alloc_specified_region - mov ecx, -0x1E ; no memory - test eax, eax - jz .cleanfailed_mem1 - - add edx, std_application_base_address shr 20 - mov eax, [edx] - and eax, not 4095 - call MEM_Get_Linear_Address - push edx ; save pointer to first page table - mov edx, eax -; read file -; first block is already read to 0x90000 - mov eax, [edx] - and eax, not 0xFFF - call MEM_Get_Linear_Address - mov esi, 0x90000 - mov edi, eax - mov ecx, 512/4 - rep movsd - sub edi, eax -.loop1: -; [esp] = pointer to current page directory entry -; edx = pointer to current page table -; edi = offset in page - mov eax, [edx] - and eax, not 0xFFF - call MEM_Get_Linear_Address - push edi - add edi, eax - lea eax, [esp+8+36+8] - call dword [eax-4] - pop edi - test eax, eax - jnz .endloop1 - add edi, 512 ; new offset - cmp edi, 4096 - jb .loop1 - xor edi, edi - add edx, 4 ; go to next page - test edx, 4096-1 - jnz .loop1 - pop eax - add eax, 4 ; go to next directory entry - push eax - mov eax, [eax] - and eax, not 0xFFF - call MEM_Get_Linear_Address - mov edx, eax - jmp .loop1 -.endloop1: - pop edx - cmp eax, 6 - jnz .cleanfailed_mem2 - call .add_app_parameters - mov [esp+28], eax - popad - ret - -.cleanfailed_mem2: -; file read error; free all allocated mem - mov ecx, eax - neg ecx - mov eax, [new_process_place] - call dispose_app_cr3_table - jmp .cleanfailed -.cleanfailed_mem1: -; there is mem for directory entry, but there is no mem for pages -; so free directory entry - mov eax, [new_process_place] - shl eax, 8 - mov eax, [0x80000+eax+0xB8] - call MEM_Free_Page -.cleanfailed_mem: -; there is no mem for directory entry, display message - mov esi, start_not_enough_memory - call sys_msg_board_str -.cleanfailed: - push ecx -; clean process name, this avoid problems with @panel - mov edi, [new_process_place] - shl edi, 8 - add edi, 0x80000+APPDATA.app_name - mov ecx, 11 - mov al, ' ' - rep stosb - pop eax -.failed: - pop ebx - mov [esp+28], eax - popad - mov [application_table_status], 0 - call safe_sti - ret -; \end{diamond} -.add_app_parameters: -;input: -; [esp] - pointer to parameters -; [esp+4]-[esp+36] pushad registers. -;result -; eax - pid of new process -; or zero if failed - cli - mov ebx,[new_process_place] - cmp ebx,[0x3004] - jle .noinc - inc dword [0x3004] ;update number of processes -.noinc: - -; mov ebx,[new_process_place] -;set 0x8c field of extended information about process -;(size of application memory) - shl ebx,8 - mov eax,[app_mem] - mov [second_base_address+0x80000+APPDATA.mem_size+ebx],eax -;set 0x10 field of information about process -;(application base address) -; mov ebx,[new_process_place] -; shl ebx,5 - shr ebx,3 - mov dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address - -;add command line parameters -.add_command_line: - mov edx,[app_i_param] - test edx,edx - jz .no_command_line ;application don't need parameters - mov eax,[esp+4] - test eax,eax - jz .no_command_line ;no parameters specified -;calculate parameter length - mov esi,eax - xor ecx,ecx - inc ecx ; include terminating null -.command_line_len: - cmp byte [esi],0 - jz .command_line_len_end - inc esi - inc ecx - cmp ecx,256 - jl .command_line_len - -.command_line_len_end: -;ecx - parameter length -;edx - address of parameters in new process address space - mov ebx,eax ;ebx - address of parameters in our address space - mov eax,[new_process_place] - call write_process_memory ;copy parameters to new process address space - -.no_command_line: -;****************************************************************** - mov edx,[app_i_icon] - test edx,edx - jz .no_command_line_1 ;application don't need path of file - mov ebx,[appl_path] - mov ecx,[appl_path_size] - mov eax,[new_process_place] - call write_process_memory ;copy path of file to new process address space -.no_command_line_1: -;****************************************************************** - mov ebx,[new_process_place] - mov eax,ebx - shl ebx,5 - mov [ebx+window_data+WDATA.fl_wstate],WSTATE_NORMAL - mov [ebx+window_data+WDATA.fl_redraw],1 - add ebx,0x3000 ;ebx - pointer to information about process - mov [ebx+TASKDATA.wnd_number],al ;set window number on screen = process slot - - mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function) - - inc dword [process_number] - mov eax,[process_number] - mov [ebx+TASKDATA.pid],eax ;set PID - - mov ecx,ebx - add ecx,draw_data-0x3000 ;ecx - pointer to draw data -;set draw data to full screen - mov [ecx+RECT.left],dword 0 - mov [ecx+RECT.top],dword 0 - mov eax,[0xfe00] - mov [ecx+RECT.right],eax - mov eax,[0xfe04] - mov [ecx+RECT.bottom],eax -;set cr3 register in TSS of application - mov ecx,[new_process_place] - shl ecx,8 - mov eax,[0x80000+APPDATA.dir_table+ecx] - add eax,8+16 ;add flags - mov [l.cr3],eax - - mov eax,[app_start] - mov [l.eip],eax ;set eip in TSS - mov eax,[app_esp] - mov [l.esp],eax ;set stack in TSS - -;gdt - ;mov ebx,[new_process_place] - ;shl ebx,3 - mov ax,app_code ;ax - selector of code segment - ;add ax,bx - mov [l.cs],ax - mov ax,app_data - ;add ax,bx ;ax - selector of data segment - mov [l.ss],ax - mov [l.ds],ax - mov [l.es],ax - mov [l.fs],ax - mov ax,graph_data ;ax - selector of graphic segment - mov [l.gs],ax - mov [l.io],word 128 - mov [l.eflags],dword 0x11202 - mov [l.ss0],os_data - mov ebx,[new_process_place] - shl ebx,12 - add ebx,sysint_stack_data+4096 - mov [l.esp0],ebx - -;copy tss to it place - mov eax,tss_sceleton - mov ebx,[new_process_place] - imul ebx,tss_step - add ebx,tss_data ;ebx - address of application TSS - mov ecx,120 - call memmove - -;Add IO access table - bit array of permitted ports - or eax,-1 - mov edi,[new_process_place] - imul edi,tss_step - add edi,tss_data+128 - mov ecx,2048 - cld - rep stosd ;full access to 2048*8=16384 ports - - mov ecx,ebx ;ecx - address of application TSS - mov edi,[new_process_place] - shl edi,3 -;set TSS descriptor - mov [edi+gdts+tss0+0],word tss_step ;limit (size) - mov [edi+gdts+tss0+2],cx ;part of offset - mov eax,ecx - shr eax,16 - mov [edi+gdts+tss0+4],al ;part of offset - mov [edi+gdts+tss0+7],ah ;part of offset - mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags - - -;flush keyboard and buttons queue - mov [0xf400],byte 0 - mov [0xf500],byte 0 - - mov edi,[new_process_place] - shl edi,5 - add edi,window_data - mov ebx,[new_process_place] - movzx esi,word [0xC000+ebx*2] - lea esi,[0xC400+esi*2] - call windowactivate ;gui initialization - - mov ebx,[new_process_place] - shl ebx,5 -; set if debuggee - test byte [esp+28], 1 - jz .no_debug - mov [0x3000+ebx+TASKDATA.state], 1 ; set process state - suspended - mov eax, [0x3000] - mov [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current - jmp .debug -.no_debug: - mov [0x3000+ebx+TASKDATA.state], 0 ; set process state - running -.debug: - - mov esi,new_process_running - call sys_msg_board_str ;output information about succefull startup - -; add esp,4 ;pop pointer to parameters -; popad - mov eax,[process_number] ;set result - mov [application_table_status],0 ;unlock application_table_status mutex - call safe_sti - ret 4 - -end if diff --git a/kernel/trunk/core/physmem.inc b/kernel/trunk/core/physmem.inc deleted file mode 100644 index 90d08ab294..0000000000 --- a/kernel/trunk/core/physmem.inc +++ /dev/null @@ -1,220 +0,0 @@ -virtual at 0 -physical_mem_block: - .start rd 1 - .size rd 1 - .flags rd 1 ;0-free, pid-used. -.sizeof: -end virtual -max_physical_mem_blocks = 24 -uglobal - num_physical_mem_blocks rd 1 - physical_mem_blocks rd 3*max_physical_mem_blocks -endg -Init_Physical_Memory_Manager: - pushad - mov edi,physical_mem_blocks - mov ecx,3*max_physical_mem_blocks - xor eax,eax - cld - rep stosd - mov dword [num_physical_mem_blocks],2 - mov [physical_mem_blocks+physical_mem_block.start],0x60000 - mov [physical_mem_blocks+physical_mem_block.size],0x20000 ;128Kb - mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.start],0x780000 - mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.size],0x80000 ;512Kb - popad - ret -Insert_Block: -;input: -; eax - handle -;output: -; none - push eax ecx esi edi - sub eax,[num_physical_mem_blocks] - neg eax - mov edi,physical_mem_block.sizeof - imul eax,edi - shr eax,2 - mov ecx,eax - mov esi,[num_physical_mem_blocks] - imul esi,edi - add esi,physical_mem_blocks - lea edi,[esi+physical_mem_block.sizeof] - std - rep movsd - pop edi esi ecx eax - ret -Delete_Block: -;input: -; eax - handle -;output: -; none - pushad - mov edi,eax - sub eax,[num_physical_mem_blocks] - neg eax - dec eax - mov esi,physical_mem_block.sizeof - imul eax,esi - imul edi,esi - add edi,physical_mem_blocks - lea esi,[edi+physical_mem_block.sizeof] - mov ecx,eax - shr ecx,2 - cld - rep movsd - popad - ret -Allocate_Physical_Block: -;input: -; eax - size -;output: -; eax - address or 0 if not enough memory. - pushad - cmp [num_physical_mem_blocks],max_physical_mem_blocks - jge .error - mov ebx,eax - xor eax,eax - mov esi,physical_mem_blocks -.loop: - cmp dword [esi+physical_mem_block.flags],0 - jnz .next - cmp [esi+physical_mem_block.size],ebx - jg .addblock - jz .noaddblock -.next: - inc eax - add esi,physical_mem_block.sizeof - cmp eax,[num_physical_mem_blocks] - jl .loop -.error: - popad - xor eax,eax - ret -.noaddblock: - mov eax,[esi+physical_mem_block.start] - mov [esp+28],eax - mov eax,[0x3010] - mov eax,[eax+TASKDATA.pid] - mov [esi+physical_mem_block.flags],eax - popad - ret -.addblock: - call Insert_Block - inc dword [num_physical_mem_blocks] - mov eax,[esi+physical_mem_block.start] - mov [esp+28],eax - mov ecx,[0x3010] - mov ecx,[ecx+TASKDATA.pid] - mov [esi+physical_mem_block.flags],ecx - mov ecx,[esi+physical_mem_block.size] - mov [esi+physical_mem_block.size],ebx - sub ecx,ebx - mov [esi+physical_mem_block.sizeof+physical_mem_block.size],ecx - add ebx,[esi+physical_mem_block.start] - mov [esi+physical_mem_block.sizeof+physical_mem_block.start],ebx - mov dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0 - popad - ret -Free_Physical_Block: -;input: -; eax - address -;output: -; none - pushad - test eax,eax - jz .ret - mov ebx,eax - xor eax,eax - mov esi,physical_mem_blocks -.loop: - cmp ebx,[esi+physical_mem_block.start] - jz .endloop - inc eax - add esi,physical_mem_block.sizeof - cmp eax,[num_physical_mem_blocks] - jl .loop - jmp .ret -.endloop: - mov dword [esi+physical_mem_block.flags],0 - test eax,eax - jz .no_union_previous - cmp dword [esi-physical_mem_block.sizeof+physical_mem_block.flags],0 - jnz .no_union_previous - mov ebx,[esi-physical_mem_block.sizeof+physical_mem_block.start] - add ebx,[esi-physical_mem_block.sizeof+physical_mem_block.size] - cmp ebx,[esi+physical_mem_block.start] - jnz .no_union_previous - mov ebx,[esi+physical_mem_block.size] - add [esi-physical_mem_block.sizeof+physical_mem_block.size],ebx - call Delete_Block - dec eax - dec [num_physical_mem_blocks] -.no_union_previous: - inc eax - cmp eax,[num_physical_mem_blocks] - jge .no_union_next - cmp dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0 - jnz .no_union_next - mov ebx,[esi+physical_mem_block.start] - add ebx,[esi+physical_mem_block.size] - cmp ebx,[esi+physical_mem_block.sizeof+physical_mem_block.start] - jnz .no_union_next - mov ebx,[esi+physical_mem_block.sizeof+physical_mem_block.size] - add [esi+physical_mem_block.size],ebx - call Delete_Block - dec [num_physical_mem_blocks] -.no_union_next: -.ret: - popad - ret - -sys_allocate_physical_block: -;eax - subfunction number - mov eax,ebx - call Allocate_Physical_Block - mov [esp+36],eax - ret -sys_free_physical_block: -;eax - subfunction number - mov eax,ebx - call Free_Physical_Block - ret -sys_set_buffer: - add ecx,std_application_base_address -isys_set_buffer: ;for using in kernel -;eax - subfunction number -;ebx - physical address -;ecx - buffer start -;edx - buffer size - lea edi,[ebx+second_base_address] - mov esi,ecx - mov ecx,edx - cld - rep movsb - ret -sys_get_buffer: - add ecx,std_application_base_address -isys_get_buffer: ;for using in kernel -;eax - subfunction number -;ebx - physical address -;ecx - buffer start -;edx - buffer size - mov edi,ecx - lea esi,[ebx+second_base_address] - mov ecx,edx - cld - rep movsb - ret -sys_internal_services: - cmp eax,4 - jle sys_sheduler - cmp eax,5 - jz sys_allocate_physical_block - cmp eax,6 - jz sys_free_physical_block - cmp eax,7 - jz sys_set_buffer - cmp eax,8 - jz sys_get_buffer - ret \ No newline at end of file diff --git a/kernel/trunk/docs/apm/README.TXT b/kernel/trunk/docs/apm/README.TXT index 6351265609..9f77c0ae89 100644 --- a/kernel/trunk/docs/apm/README.TXT +++ b/kernel/trunk/docs/apm/README.TXT @@ -2,7 +2,7 @@ Advanced Power Management SYSTEM CALL -eax = 70 +eax = 49 dx = íîìåð ôóíêöèè APM BIOS (àíàëîãè÷åí ax â ðåàëüíîì ðåæèìå) îñòàëüíûå (bx, cx) ðåãèñòðû ïî ñïåöèôèêàöèè (ñì. apm.txt) ðåçóëüòàò : ïî ñïåöèôèêàöèè (âêëþ÷àÿ CF), ñòàðøàÿ ÷àñòü 32 áèòíûõ ðåãèñòðîâ íå îïðåäåëåíà @@ -18,12 +18,13 @@ Boot: ÈÇÌÅÍÅÍÈß -sys32.inc +bootcode.inc syscall.inc kernel.asm bootcode.inc +shutdown.inc -##############[core\sys32.inc]##################### +##############[boot\bootcode.inc]################## Òðè íîâûõ äåñêðèïòîðà @@ -57,19 +58,19 @@ os_data_l: db 0x00 ; --------------- APM --------------------- apm_code_32: - dw 0x10 ; limit 64kb + dw 0x0f ; limit 64kb db 0, 0, 0 - dw 11011111b *256 +10011010b + dw 11010000b *256 +10011010b db 0x00 apm_code_16: - dw 0x10 + dw 0x0f db 0, 0, 0 - dw 10011111b *256 +10011010b + dw 10010000b *256 +10011010b db 0x00 apm_data_16: - dw 0x10 + dw 0x0f db 0, 0, 0 - dw 10011111b *256 +10010010b + dw 10010000b *256 +10010010b db 0x00 ; ----------------------------------------- app_code_l: @@ -95,7 +96,6 @@ graph_data_l: db 0x00 tss0_l: - times (max_processes+10) dd 0,0 ............. ............. @@ -106,12 +106,11 @@ tss0_l: ............. - dd undefined_syscall ; 65-UTF - dd sys_process_def ; 66-Process definitions - keyboard - dd sys_window_move ; 67-Window move or resize - dd sys_internal_services ; 68-Some internal services - dd sys_debug_services ; 69-Debug - dd sys_apm ; 70-APM + dd display_number ; 47-WriteNum + dd display_settings ; 48-SetRedrawType and SetButtonType + dd sys_apm ; 49-Advanced Power Management (APM) + dd random_shaped_window ; 50-Window shape & scale + dd syscall_threads ; 51-Threads ............. @@ -152,7 +151,7 @@ align 4 sys_apm: cmp word [apm_vf], 0 ; Check APM BIOS enable jne @f - or [esp + 40], byte 1 ; error + or [esp + 56], byte 1 ; error mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported ret @@ -161,7 +160,7 @@ sys_apm: cmp al, 3 ja @f - and [esp + 40], byte 0xfe ; emulate func 0..3 as func 0 + and [esp + 56], byte 0xfe ; emulate func 0..3 as func 0 mov eax, [apm_vf] mov [esp + 36], eax shr eax, 16 @@ -176,8 +175,8 @@ sys_apm: mov [esp + 32], ecx mov [esp + 36], eax setc al - and [esp + 40], byte 0xfe - or [esp + 40], al + and [esp + 56], byte 0xfe + or [esp + 56], al ret ; ----------------------------------------- @@ -213,10 +212,10 @@ undefined_syscall: ; Undefined system call msg_apm:db ' APM x.x ', 0 @@: and ax, 0xf0f add ax, '00' - mov [msg_apm - 0x10000 + 5], ah - mov [msg_apm - 0x10000 + 7], al - _setcursor 0, 3 mov si, msg_apm - 0x10000 + mov [si + 5], ah + mov [si + 7], al + _setcursor 0, 3 call printplain _setcursor d80x25_top_num,0 ; ------------------ @@ -253,3 +252,22 @@ apm_end: ............. ............. +##############[boot\shutdown.inc]################## + +Ðåøåíèå ïðîáëåìû APM poweroff + +............. +............. + +APM_PowerOff: + mov ax, 5304h + xor bx, bx + int 15h +;!!!!!!!!!!!!!!!!!!!!!!!! +mov ax,0x5300 +xor bx,bx +int 0x15 +push ax + +............. +............. diff --git a/kernel/trunk/fs/fs_phys.inc b/kernel/trunk/fs/fs_phys.inc deleted file mode 100644 index 418945d02b..0000000000 --- a/kernel/trunk/fs/fs_phys.inc +++ /dev/null @@ -1,111 +0,0 @@ -hd_phys_read: -;eax - sector number -;ebx - destination - pushad - call wait_for_hd_idle - popad - push edx - push eax - cli - xor eax,eax - mov edx,[hdbase] - inc edx - out dx,al - inc edx - inc eax - out dx,al - inc edx -;write sector number. - mov eax,[esp] - out dx,al - shr eax,8 - inc edx - out dx,al - shr eax,8 - inc edx - out dx,al - shr eax,8 - inc edx - and al,1+2+4+8 - add al,byte [hdid] ;+0 or +16 - or al,32+64+128 - out dx,al - inc edx - mov al,0x20 - out dx,al - sti - - call wait_for_sector_buffer - cmp [hd_error],0 - jnz hd_read_error - cli - push edi - mov edi,ebx - mov ecx,256 - mov edx,[hdbase] - cld - rep insw - pop edi - sti - pop edx - pop eax - ret - -hd_phys_write: -;eax - sector number -;ebx - destination - cmp eax,[partition_start] - jb .ret - cmp eax,[partition_end] - ja .ret - pushad - call wait_for_hd_idle - popad - push edx - push eax - cli - xor eax,eax - mov edx,[hdbase] - inc edx - out dx,al - inc edx - inc eax - out dx,al -;write sector number - inc edx - mov eax,[esp] - out dx,al - shr eax,8 - inc edx - out dx,al - shr eax,8 - inc edx - out dx,al - shr eax,8 - inc edx - and al,1+2+4+8 - add al,byte [hdid] ;+0 or +16 - or al,32+64+128 - out dx,al - - inc edx - mov al,0x30 - out dx,al - sti - - call wait_for_sector_buffer - cmp [hd_error],0 - jnz hd_write_error - cli - push esi - mov esi,ebx - mov ecx,256 - mov edx,[hdbase] - cld - rep outsw - pop esi - sti - pop edx - pop eax -.ret: - ret \ No newline at end of file diff --git a/kernel/trunk/network/eth_drv/3c59x.inc b/kernel/trunk/network/eth_drv/3c59x.inc deleted file mode 100644 index 4280823c59..0000000000 --- a/kernel/trunk/network/eth_drv/3c59x.inc +++ /dev/null @@ -1,2380 +0,0 @@ -;; Copyright (c) 2004, Endre Kozma -;; All rights reserved. -;; -;; Redistribution and use in source and binary forms, with or without -;; modification, are permitted provided that the following conditions are -;; met: -;; -;; 1. Redistributions of source code must retain the above copyright notice, -;; this list of conditions and the following disclaimer. -;; -;; 2. Redistributions in binary form must reproduce the above copyright -;; notice, this list of conditions and the following disclaimer in the -;; documentation and/or other materials provided with the distribution. -;; -;; 3. The name of the author may not be used to endorse or promote products -;; derived from this software without specific prior written permission. -;; -;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; 3C59X.INC ;; -;; ;; -;; Ethernet driver for Menuet OS ;; -;; ;; -;; Driver for 3Com fast etherlink 3c59x and ;; -;; etherlink XL 3c900 and 3c905 cards ;; -;; References: ;; -;; www.3Com.com - data sheets ;; -;; DP83840A.pdf - ethernet physical layer ;; -;; 3c59x.c - linux driver ;; -;; ethernet driver template by Mike Hibbett ;; -;; ;; -;; Credits ;; -;; Mike Hibbett, ;; -;; who kindly supplied me with a 3Com905C-TX-M card ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; History -;; ======= -;; $Log: 3C59X.INC,v $ -;; Revision 1.3 2004/07/11 12:21:12 kozma -;; Support of vortex chips (3c59x) added. -;; Support of 3c920 and 3c982 added. -;; Corrections. -;; -;; Revision 1.2 2004/06/12 19:40:20 kozma -;; Function e3c59x_set_available_media added in order to set -;; the default media in case auto detection finds no valid link. -;; Incorrect mii check removed (3c900 Cyclone works now). -;; Cleanups. -;; -;; Revision 1.1 2004/06/12 18:27:15 kozma -;; Initial revision -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; comment the next line out if you don't want debug info printed -; on the debug board. This option adds a lot of bytes to the driver -; so it's worth to comment it out. -; E3C59X_DEBUG equ 1 - -; forcing full duplex mode makes sense at some cards and link types - E3C59X_FORCE_FD equ 1 - -macro virt_to_dma reg -{ -if defined E3C59X_LINUX - sub reg, [virt_addr] - add reg, [dma_addr] -end if -} - -macro dma_to_virt reg -{ -if defined E3C59X_LINUX - sub reg, [dma_addr] - add reg, [virt_addr] -end if -} - -macro zero_to_virt reg -{ -if defined E3C59X_LINUX - add reg, [virt_addr] -end if -} - -macro virt_to_zero reg -{ -if defined E3C59X_LINUX - sub reg, [virt_addr] -end if -} - -macro zero_to_dma reg -{ -if defined E3C59X_LINUX - add reg, [dma_addr] -end if -} - -macro dma_to_zero reg -{ -if defined E3C59X_LINUX - sub reg, [dma_addr] -end if -} - -macro strtbl name, [string] -{ -common - label name dword -forward - local label - dd label -forward - label db string, 0 -} - -; Ethernet frame symbols - ETH_ALEN equ 6 - ETH_HLEN equ (2*ETH_ALEN+2) - ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for - ; mininmum 64bytes frame length -; PCI programming - PCI_REG_COMMAND equ 0x4 ; command register - PCI_REG_STATUS equ 0x6 ; status register - PCI_REG_LATENCY equ 0xd ; latency timer register - PCI_REG_CAP_PTR equ 0x34 ; capabilities pointer - PCI_REG_CAPABILITY_ID equ 0x0 ; capapility ID in pm register block - PCI_REG_PM_STATUS equ 0x4 ; power management status register - PCI_REG_PM_CTRL equ 0x4 ; power management control register - PCI_BIT_PIO equ 0 ; bit0: io space control - PCI_BIT_MMIO equ 1 ; bit1: memory space control - PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master -; Registers - E3C59X_REG_POWER_MGMT_CTRL equ 0x7c - E3C59X_REG_UP_LIST_PTR equ 0x38 - E3C59X_REG_UP_PKT_STATUS equ 0x30 - E3C59X_REG_TX_FREE_THRESH equ 0x2f - E3C59X_REG_DN_LIST_PTR equ 0x24 - E3C59X_REG_DMA_CTRL equ 0x20 - E3C59X_REG_TX_STATUS equ 0x1b - E3C59X_REG_RX_STATUS equ 0x18 - E3C59X_REG_TX_DATA equ 0x10 -; Common window registers - E3C59X_REG_INT_STATUS equ 0xe - E3C59X_REG_COMMAND equ 0xe -; Register window 7 - E3C59X_REG_MASTER_STATUS equ 0xc - E3C59X_REG_POWER_MGMT_EVENT equ 0xc - E3C59X_REG_MASTER_LEN equ 0x6 - E3C59X_REG_VLAN_ETHER_TYPE equ 0x4 - E3C59X_REG_VLAN_MASK equ 0x0 - E3C59X_REG_MASTER_ADDRESS equ 0x0 -; Register window 6 - E3C59X_REG_BYTES_XMITTED_OK equ 0xc - E3C59X_REG_BYTES_RCVD_OK equ 0xa - E3C59X_REG_UPPER_FRAMES_OK equ 0x9 - E3C59X_REG_FRAMES_DEFERRED equ 0x8 - E3C59X_REG_FRAMES_RCVD_OK equ 0x7 - E3C59X_REG_FRAMES_XMITTED_OK equ 0x6 - E3C59X_REG_RX_OVERRUNS equ 0x5 - E3C59X_REG_LATE_COLLISIONS equ 0x4 - E3C59X_REG_SINGLE_COLLISIONS equ 0x3 - E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2 - E3C59X_REG_SQE_ERRORS equ 0x1 - E3C59X_REG_CARRIER_LOST equ 0x0 -; Register window 5 - E3C59X_REG_INDICATION_ENABLE equ 0xc - E3C59X_REG_INTERRUPT_ENABLE equ 0xa - E3C59X_REG_TX_RECLAIM_THRESH equ 0x9 - E3C59X_REG_RX_FILTER equ 0x8 - E3C59X_REG_RX_EARLY_THRESH equ 0x6 - E3C59X_REG_TX_START_THRESH equ 0x0 -; Register window 4 - E3C59X_REG_UPPER_BYTES_OK equ 0xe - E3C59X_REG_BAD_SSD equ 0xc - E3C59X_REG_MEDIA_STATUS equ 0xa - E3C59X_REG_PHYSICAL_MGMT equ 0x8 - E3C59X_REG_NETWORK_DIAGNOSTIC equ 0x6 - E3C59X_REG_FIFO_DIAGNOSTIC equ 0x4 - E3C59X_REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported -; Bits in register window 4 - E3C59X_BIT_AUTOSELECT equ 24 -; Register window 3 - E3C59X_REG_TX_FREE equ 0xc - E3C59X_REG_RX_FREE equ 0xa - E3C59X_REG_MEDIA_OPTIONS equ 0x8 - E3C59X_REG_MAC_CONTROL equ 0x6 - E3C59X_REG_MAX_PKT_SIZE equ 0x4 - E3C59X_REG_INTERNAL_CONFIG equ 0x0 -; Register window 2 - E3C59X_REG_RESET_OPTIONS equ 0xc - E3C59X_REG_STATION_MASK_HI equ 0xa - E3C59X_REG_STATION_MASK_MID equ 0x8 - E3C59X_REG_STATION_MASK_LO equ 0x6 - E3C59X_REG_STATION_ADDRESS_HI equ 0x4 - E3C59X_REG_STATION_ADDRESS_MID equ 0x2 - E3C59X_REG_STATION_ADDRESS_LO equ 0x0 -; Register window 1 - E3C59X_REG_TRIGGER_BITS equ 0xc - E3C59X_REG_SOS_BITS equ 0xa - E3C59X_REG_WAKE_ON_TIMER equ 0x8 - E3C59X_REG_SMB_RXBYTES equ 0x7 - E3C59X_REG_SMB_DIAG equ 0x5 - E3C59X_REG_SMB_ARB equ 0x4 - E3C59X_REG_SMB_STATUS equ 0x2 - E3C59X_REG_SMB_ADDRESS equ 0x1 - E3C59X_REG_SMB_FIFO_DATA equ 0x0 -; Register window 0 - E3C59X_REG_EEPROM_DATA equ 0xc - E3C59X_REG_EEPROM_COMMAND equ 0xa - E3C59X_REG_BIOS_ROM_DATA equ 0x8 - E3C59X_REG_BIOS_ROM_ADDR equ 0x4 -; Physical management bits - E3C59X_BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData - E3C59X_BIT_MGMT_DATA equ 1 ; MII management data bit - E3C59X_BIT_MGMT_CLK equ 0 ; MII management clock -; MII commands - E3C59X_MII_CMD_MASK equ (1111b shl 10) - E3C59X_MII_CMD_READ equ (0110b shl 10) - E3C59X_MII_CMD_WRITE equ (0101b shl 10) -; MII registers - E3C59X_REG_MII_BMCR equ 0 ; basic mode control register - E3C59X_REG_MII_BMSR equ 1 ; basic mode status register - E3C59X_REG_MII_ANAR equ 4 ; auto negotiation advertisement register - E3C59X_REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register - E3C59X_REG_MII_ANER equ 6 ; auto negotiation expansion register -; MII bits - E3C59X_BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete - E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6 -; eeprom bits and commands - E3C59X_EEPROM_CMD_READ equ 0x80 - E3C59X_EEPROM_BIT_BUSY equ 15 -; eeprom registers - E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa - E3C59X_EEPROM_REG_CAPABILITIES equ 0x10 -; Commands for command register - E3C59X_SELECT_REGISTER_WINDOW equ (1 shl 11) - - IS_VORTEX equ 0x1 - IS_BOOMERANG equ 0x2 - IS_CYCLONE equ 0x4 - IS_TORNADO equ 0x8 - EEPROM_8BIT equ 0x10 - HAS_PWR_CTRL equ 0x20 - HAS_MII equ 0x40 - HAS_NWAY equ 0x80 - HAS_CB_FNS equ 0x100 - INVERT_MII_PWR equ 0x200 - INVERT_LED_PWR equ 0x400 - MAX_COLLISION_RESET equ 0x800 - EEPROM_OFFSET equ 0x1000 - HAS_HWCKSM equ 0x2000 - EXTRA_PREAMBLE equ 0x4000 - -iglobal - align 4 -e3c59x_hw_versions: - dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps - dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex - dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex - dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx - dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4 - dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII - dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT - dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo - dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO - dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo - dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC - dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL - dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx - dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4 - dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx - dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC - dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx - dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado - dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone - dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone - dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane - dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane - dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \ - or INVERT_MII_PWR or HAS_HWCKSM ; 3c556 Laptop Tornado - dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \ - or INVERT_MII_PWR or HAS_HWCKSM ; 3c556B Laptop Hurricane - dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus - dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus - dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \ - or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE575BT Cyclone CardBus - dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ - or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CCFE575CT Tornado CardBus - dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ - or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE656 Cyclone CardBus - dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ - or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFEM656B Cyclone+Winmodem CardBus - dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ - or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CXFEM656C Tornado+Winmodem CardBus - dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado - dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado - dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A - dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B - dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4 - dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado -E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions -endg - -; RX/TX buffers sizes - E3C59X_MAX_ETH_PKT_SIZE equ 1536 ; max packet size - E3C59X_NUM_RX_DESC equ 4 ; a power of 2 number - E3C59X_NUM_TX_DESC equ 4 ; a power of 2 number - E3C59X_RX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC) - E3C59X_TX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC) -; Download Packet Descriptor - E3C59X_DPD_DN_NEXT_PTR equ 0 - E3C59X_DPD_FRAME_START_HDR equ 4 - E3C59X_DPD_DN_FRAG_ADDR equ 8 ; for packet data - E3C59X_DPD_DN_FRAG_LEN equ 12 ; for packet data - E3C59X_DPD_SIZE equ 16 ; a power of 2 number -; Upload Packet Descriptor - E3C59X_UPD_UP_NEXT_PTR equ 0 - E3C59X_UPD_PKT_STATUS equ 4 - E3C59X_UPD_UP_FRAG_ADDR equ 8 ; for packet data - E3C59X_UPD_UP_FRAG_LEN equ 12 ; for packet data - E3C59X_UPD_SIZE equ 16 - -; RX/TX buffers -if defined E3C59X_LINUX - E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment - e3c59x_rx_buff = 0 -else - E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment - e3c59x_rx_buff = eth_data_start -end if - - e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE - e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE - e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC) - -uglobal -e3c59x_curr_upd: dd 0 -e3c59x_prev_dpd: dd 0 -e3c59x_prev_tx_frame: dd 0 -e3c59x_transmit_function: dd 0 -e3c59x_receive_function: dd 0 -endg - -iglobal -e3c59x_ver_id: db 17 -endg -uglobal -e3c59x_full_bus_master: db 0 -e3c59x_has_hwcksm: db 0 -e3c59x_preamble: db 0 -e3c59x_dn_list_ptr_cleared: db 0 -e3c59x_self_directed_packet: rb 6 -endg - -if defined E3C59X_DEBUG -e3c59x_hw_type_str: db "Detected hardware type : ", 0 -e3c59x_device_str: db "Device ID : 0x" -e3c59x_device_id_str: db "ffff", 13, 10, 0 -e3c59x_vendor_str: db "Vendor ID : 0x" -e3c59x_vendor_id_str: db "ffff", 13, 10, 0 -e3c59x_io_info_str: db "IO address : 0x" -e3c59x_io_addr_str: db "ffff", 13, 10, 0 -e3c59x_mac_info_str: db "MAC address : " -e3c59x_mac_addr_str: db "ff:ff:ff:ff:ff:ff", 13, 10, 0 -e3c59x_boomerang_str: db " (boomerang)", 13, 10, 0 -e3c59x_vortex_str: db " (vortex)", 13, 10, 0 -e3c59x_link_type_str: db "Established link type : ", 0 -e3c59x_new_line_str: db 13, 10, 0 -e3c59x_link_type: dd 0 - -e3c59x_charset: db '0123456789abcdef' - -strtbl e3c59x_link_str, \ - "No valid link type detected", \ - "10BASE-T half duplex", \ - "10BASE-T full-duplex", \ - "100BASE-TX half duplex", \ - "100BASE-TX full duplex", \ - "100BASE-T4", \ - "100BASE-FX", \ - "10Mbps AUI", \ - "10Mbps COAX (BNC)", \ - "miiDevice - not supported" - -strtbl e3c59x_hw_str, \ - "3c590 Vortex 10Mbps", \ - "3c592 EISA 10Mbps Demon/Vortex", \ - "3c597 EISA Fast Demon/Vortex", \ - "3c595 Vortex 100baseTx", \ - "3c595 Vortex 100baseT4", \ - "3c595 Vortex 100base-MII", \ - "3c900 Boomerang 10baseT", \ - "3c900 Boomerang 10Mbps Combo", \ - "3c900 Cyclone 10Mbps TPO", \ - "3c900 Cyclone 10Mbps Combo", \ - "3c900 Cyclone 10Mbps TPC", \ - "3c900B-FL Cyclone 10base-FL", \ - "3c905 Boomerang 100baseTx", \ - "3c905 Boomerang 100baseT4", \ - "3c905B Cyclone 100baseTx", \ - "3c905B Cyclone 10/100/BNC", \ - "3c905B-FX Cyclone 100baseFx", \ - "3c905C Tornado", \ - "3c980 Cyclone", \ - "3c982 Dual Port Server Cyclone", \ - "3cSOHO100-TX Hurricane", \ - "3c555 Laptop Hurricane", \ - "3c556 Laptop Tornado", \ - "3c556B Laptop Hurricane", \ - "3c575 [Megahertz] 10/100 LAN CardBus", \ - "3c575 Boomerang CardBus", \ - "3CCFE575BT Cyclone CardBus", \ - "3CCFE575CT Tornado CardBus", \ - "3CCFE656 Cyclone CardBus", \ - "3CCFEM656B Cyclone+Winmodem CardBus", \ - "3CXFEM656C Tornado+Winmodem CardBus", \ - "3c450 HomePNA Tornado", \ - "3c920 Tornado", \ - "3c982 Hydra Dual Port A", \ - "3c982 Hydra Dual Port B", \ - "3c905B-T4", \ - "3c920B-EMB-WNM Tornado" - -end if ; defined E3C59X_DEBUG - -;*************************************************************************** -; Function -; e3c59x_debug -; Description -; prints debug info to the debug board -; Parameters -; ebp - io_addr -; Return value -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** -if defined E3C59X_DEBUG - align 4 -e3c59x_debug: - pushad -; print device type - mov esi, e3c59x_hw_type_str - call sys_msg_board_str - movzx ecx, byte [e3c59x_ver_id] - mov esi, [e3c59x_hw_str+ecx*4] - call sys_msg_board_str - mov esi, e3c59x_boomerang_str - cmp dword [e3c59x_transmit_function], e3c59x_boomerang_transmit - jz .boomerang - mov esi, e3c59x_vortex_str -.boomerang: - call sys_msg_board_str -; print device/vendor - mov ax, [pci_data+2] - mov cl, 2 - mov ebx, e3c59x_device_id_str - call e3c59x_print_hex - mov esi, e3c59x_device_str - call sys_msg_board_str - mov ax, [pci_data] - mov cl, 2 - mov ebx, e3c59x_vendor_id_str - call e3c59x_print_hex - mov esi, e3c59x_vendor_str - call sys_msg_board_str -; print io address - mov ax, [io_addr] - mov ebx, e3c59x_io_addr_str - mov cl, 2 - call e3c59x_print_hex - mov esi, e3c59x_io_info_str - call sys_msg_board_str -; print MAC address - mov ebx, e3c59x_mac_addr_str - xor ecx, ecx -.mac_loop: - push ecx - mov al, [node_addr+ecx] - mov cl, 1 - call e3c59x_print_hex - inc ebx - pop ecx - inc cl - cmp cl, 6 - jne .mac_loop - mov esi, e3c59x_mac_info_str - call sys_msg_board_str -; print link type - mov esi, e3c59x_link_type_str - call sys_msg_board_str - xor eax, eax - bsr ax, word [e3c59x_link_type] - jz @f - sub ax, 4 -@@: - mov esi, [e3c59x_link_str+eax*4] - call sys_msg_board_str - mov esi, e3c59x_new_line_str - call sys_msg_board_str - popad - ret - -;*************************************************************************** -; Function -; e3c59x_print_hex -; Description -; prints a hexadecimal value -; Parameters -; eax - value to be printed out -; ebx - where to print -; cl - value size (1, 2, 4) -; Return value -; ebx - end address after the print -; Destroyed registers -; eax, ebx -; -;*************************************************************************** - align 4 -e3c59x_print_hex: - cmp cl, 1 - je .print_byte - cmp cl, 2 - jz .print_word -.print_dword: - push eax - bswap eax - xchg ah, al - call .print_word - pop eax -.print_word: - push eax - xchg ah, al - call .print_byte - pop eax -.print_byte: - movzx eax, al - push eax - and al, 0xf0 - shr al, 4 - mov al, byte [eax+e3c59x_charset] - mov [ebx], al - inc ebx - pop eax - and al, 0x0f - mov al, byte [eax+e3c59x_charset] - mov [ebx], al - inc ebx - ret -end if ; defined E3C59X_DEBUG - -;*************************************************************************** -; Function -; e3c59x_try_link_detect -; Description -; e3c59x_try_link_detect checks if link exists -; Parameters -; ebp - io_addr -; Return value -; al - 0 ; no link detected -; al - 1 ; link detected -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** - align 4 -e3c59x_try_link_detect: -; download self-directed packet - mov edi, node_addr - mov bx, 0x0608 ; packet type - mov esi, e3c59x_self_directed_packet - mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes - call dword [e3c59x_transmit_function] -; switch to register window 5 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 - out dx, ax -; program RxFilter for promiscuous operation - mov ax, (10000b shl 11) - lea edx, [ebp+E3C59X_REG_RX_FILTER] - in al, dx - or al, 1111b - lea edx, [ebp+E3C59X_REG_COMMAND] - out dx, ax -; switch to register window 4 - mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 - out dx, ax -; check loop - xor ebx, ebx - mov ecx, 0xffff ; 65535 tries -.loop: - push ecx ebx - call dword [e3c59x_receive_function] - pop ebx ecx - test al, al - jnz .finish -.no_packet_received: -; switch to register window 4 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 - out dx, ax -; read linkbeatdetect - lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] - in ax, dx - test ah, 1000b ; test linkBeatDetect - jnz .link_detected - xor al, al - jmp .finish -.link_detected: -; test carrierSense - test al, 100000b - jz .no_carrier_sense - inc ebx -.no_carrier_sense: - dec ecx - jns .loop -; assume the link is good if 0 < ebx < 25 % - test ebx, ebx - setnz al - jz .finish - cmp ebx, 16384 ; 25% - setb al -.finish: -if defined E3C59X_DEBUG - test al, al - jz @f - or byte [e3c59x_link_type+1], 100b -@@: -end if ; defined E3C59X_DEBUG - ret - -;*************************************************************************** -; Function -; e3c59x_try_phy -; Description -; e3c59x_try_phy checks the auto-negotiation function -; in the PHY at PHY index. It can also be extended to -; include link detection for non-IEEE 802.3u -; auto-negotiation devices, for instance the BCM5000. -; Parameters -; ah - PHY index -; ebp - io_addr -; Return value -; al - 0 link is auto-negotiated -; al - 1 no link is auto-negotiated -; Destroyed registers -; eax, ebx, ecx, edx, esi -; -;*************************************************************************** - align 4 -e3c59x_try_phy: - mov al, E3C59X_REG_MII_BMCR - push eax - call e3c59x_mdio_read ; returns with window #4 - or ah, 0x80 ; software reset - mov ebx, eax - pop eax - push eax - call e3c59x_mdio_write ; returns with window #4 -; wait for reset to complete - mov esi, 2000 ; 2000ms = 2s - call delay_ms - pop eax - push eax - call e3c59x_mdio_read ; returns with window #4 - test ah, 0x80 - jnz .fail_finish - pop eax - push eax -; wait for a while after reset - mov esi, 20 ; 20ms - call delay_ms - pop eax - push eax - mov al, E3C59X_REG_MII_BMSR - call e3c59x_mdio_read ; returns with window #4 - test al, 1 ; extended capability supported? - jz .no_ext_cap -; auto-neg capable? - test al, 1000b - jz .fail_finish ; not auto-negotiation capable -; auto-neg complete? - test al, 100000b - jnz .auto_neg_ok -; restart auto-negotiation - pop eax - push eax - mov al, E3C59X_REG_MII_ANAR - push eax - call e3c59x_mdio_read ; returns with window #4 - or ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX - mov ebx, eax - pop eax - call e3c59x_mdio_write ; returns with window #4 - pop eax - push eax - call e3c59x_mdio_read ; returns with window #4 - mov ebx, eax - or bh, 10010b ; restart auto-negotiation - pop eax - push eax - call e3c59x_mdio_write ; returns with window #4 - mov esi, 4000 ; 4000ms = 4 seconds - call delay_ms - pop eax - push eax - mov al, E3C59X_REG_MII_BMSR - call e3c59x_mdio_read ; returns with window #4 - test al, 100000b ; auto-neg complete? - jnz .auto_neg_ok - jmp .fail_finish -.auto_neg_ok: -; compare advertisement and link partner ability registers - pop eax - push eax - mov al, E3C59X_REG_MII_ANAR - call e3c59x_mdio_read ; returns with window #4 - xchg eax, [esp] - mov al, E3C59X_REG_MII_ANLPAR - call e3c59x_mdio_read ; returns with window #4 - pop ebx - and eax, ebx - and eax, 1111100000b - push eax -if defined E3C59X_DEBUG - mov word [e3c59x_link_type], ax -end if ; defined E3C59X_DEBUG -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax -; set full-duplex mode - lea edx, [ebp+E3C59X_REG_MAC_CONTROL] - in ax, dx - and ax, not 0x120 ; clear full duplex and flow control - pop ebx - test ebx, (1010b shl 5) ; check for full-duplex - jz .half_duplex - or ax, 0x120 ; set full duplex and flow control -.half_duplex: - out dx, ax - mov al, 1 - ret -.no_ext_cap: -; not yet implemented BCM5000 -.fail_finish: - pop eax - xor al, al - ret - -;*************************************************************************** -; Function -; e3c59x_try_mii -; Description -; e3c59x_try_MII checks the on-chip auto-negotiation logic -; or an off-chip MII PHY, depending upon what is set in -; xcvrSelect by the caller. -; It exits when it finds the first device with a good link. -; Parameters -; ebp - io_addr -; Return value -; al - 0 -; al - 1 -; Destroyed registers -; eax, ebx, ecx, edx, esi -; -;*************************************************************************** - align 4 -e3c59x_try_mii: -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - in eax, dx - and eax, (1111b shl 20) - cmp eax, (1000b shl 20) ; is auto-negotiation set? - jne .mii_device -; auto-negotiation is set -; switch to register window 4 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 - out dx, ax -; PHY==24 is the on-chip auto-negotiation logic -; it supports only 10base-T and 100base-TX - mov ah, 24 - call e3c59x_try_phy - test al, al - jz .fail_finish - mov cl, 24 - jmp .check_preamble -.mii_device: - cmp eax, (0110b shl 20) - jne .fail_finish - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 - out dx, ax - lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] - in ax, dx - and al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA) - cmp al, (1 shl E3C59X_BIT_MGMT_DATA) - je .serch_for_phy - xor al, al - ret -.serch_for_phy: -; search for PHY - mov cl, 31 -.search_phy_loop: - cmp cl, 24 - je .next_phy - mov ah, cl ; ah = phy - mov al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register - push ecx - call e3c59x_mdio_read - pop ecx - test ax, ax - jz .next_phy - cmp ax, 0xffff - je .next_phy - mov ah, cl ; ah = phy - push ecx - call e3c59x_try_phy - pop ecx - test al, al - jnz .check_preamble -.next_phy: - dec cl - jns .search_phy_loop -.fail_finish: - xor al, al - ret -; epilog -.check_preamble: - push eax ; eax contains the return value of e3c59x_try_phy -; check hard coded preamble forcing - movzx eax, byte [e3c59x_ver_id] - test word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE - setnz [e3c59x_preamble] ; force preamble - jnz .finish -; check mii for preamble suppression - mov ah, cl - mov al, E3C59X_REG_MII_BMSR - call e3c59x_mdio_read - test al, 1000000b ; preamble suppression? - setz [e3c59x_preamble] ; no -.finish: - pop eax - ret - -;*************************************************************************** -; Function -; e3c59x_test_packet -; Description -; e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port -; Parameters -; ebp - io_addr -; Return value -; al - 0 -; al - 1 -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** - align 4 -e3c59x_test_packet: -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax -; set fullDuplexEnable in MacControl register - lea edx, [ebp+E3C59X_REG_MAC_CONTROL] - in ax, dx - or ax, 0x120 - out dx, ax -; switch to register window 5 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 - out dx, ax -; set RxFilter to enable individual address matches - mov ax, (10000b shl 11) - lea edx, [ebp+E3C59X_REG_RX_FILTER] - in al, dx - or al, 1 - lea edx, [ebp+E3C59X_REG_COMMAND] - out dx, ax -; issue RxEnable and TxEnable - call e3c59x_rx_reset - call e3c59x_tx_reset -; download a self-directed test packet - mov edi, node_addr - mov bx, 0x0608 ; packet type - mov esi, e3c59x_self_directed_packet - mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes - call dword [e3c59x_transmit_function] -; wait for 2s - mov esi, 2000 ; 2000ms = 2s - call delay_ms -; check if self-directed packet is received - call dword [e3c59x_receive_function] - test al, al - jnz .finish -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax -; clear fullDuplexEnable in MacControl register - lea edx, [ebp+E3C59X_REG_MAC_CONTROL] - in ax, dx - and ax, not 0x120 - out dx, ax - xor al, al -.finish: - ret - -;*************************************************************************** -; Function -; e3c59x_try_loopback -; Description -; tries a loopback packet for 10BASE2 or AUI port -; Parameters -; al - 0: 10Mbps AUI connector -; 1: 10BASE-2 -; ebp - io_addr -; Return value -; al - 0 -; al - 1 -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** - align 4 -e3c59x_try_loopback: - push eax -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax - pop eax - push eax -if defined E3C59X_DEBUG - mov bl, al - inc bl - shl bl, 3 - or byte [e3c59x_link_type+1], bl -end if ; defined E3C59X_DEBUG - test al, al ; aui or coax? - jz .complete_loopback -; enable 100BASE-2 DC-DC converter - mov ax, (10b shl 11) ; EnableDcConverter - out dx, ax -.complete_loopback: - mov cl, 2 ; give a port 3 chances to complete a loopback -.next_try: - push ecx - call e3c59x_test_packet - pop ecx - test al, al - jnz .finish - dec cl - jns .next_try -.finish: - xchg eax, [esp] - test al, al - jz .aui_finish -; issue DisableDcConverter command - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (10111b shl 11) - out dx, ax -.aui_finish: - pop eax ; al contains the result of operation -if defined E3C59X_DEBUG - test al, al - jnz @f - and byte [e3c59x_link_type+1], not 11000b -@@: -end if ; defined E3C59X_DEBUG - ret - -;*************************************************************************** -; Function -; e3c59x_set_available_media -; Description -; sets the first available media -; Parameters -; ebp - io_addr -; Return value -; al - 0 -; al - 1 -; Destroyed registers -; eax, edx -; -;*************************************************************************** - align 4 -e3c59x_set_available_media: -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - in eax, dx - push eax - lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] - in ax, dx - test al, 10b - jz @f -; baseTXAvailable - pop eax - and eax, not (1111b shl 20) - or eax, (100b shl 20) -if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD - mov word [e3c59x_link_type], (1 shl 8) -else if defined E3C59X_DEBUG - mov word [e3c59x_link_type], (1 shl 7) -end if - jmp .set_media -@@: - test al, 100b - jz @f -; baseFXAvailable - pop eax - and eax, not (1111b shl 20) - or eax, (101b shl 20) -if defined E3C59X_DEBUG - mov word [e3c59x_link_type], (1 shl 10) -end if - jmp .set_media -@@: - test al, 1000000b - jz @f -; miiDevice - pop eax - and eax, not (1111b shl 20) - or eax, (0110b shl 20) -if defined E3C59X_DEBUG - mov word [e3c59x_link_type], (1 shl 13) -end if - jmp .set_media -@@: - test al, 1000b - jz @f -.set_default: -; 10bTAvailable - pop eax - and eax, not (1111b shl 20) -if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD - mov word [e3c59x_link_type], (1 shl 6) -else if defined E3C59X_DEBUG - mov word [e3c59x_link_type], (1 shl 5) -end if ; E3C59X_FORCE_FD - jmp .set_media -@@: - test al, 10000b - jz @f -; coaxAvailable - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (10b shl 11) ; EnableDcConverter - out dx, ax - pop eax - and eax, not (1111b shl 20) - or eax, (11b shl 20) -if defined E3C59X_DEBUG - mov word [e3c59x_link_type], (1 shl 12) -end if ; defined E3C59X_DEBUG - jmp .set_media -@@: - test al, 10000b - jz .set_default -; auiAvailable - pop eax - and eax, not (1111b shl 20) - or eax, (1 shl 20) -if defined E3C59X_DEBUG - mov word [e3c59x_link_type], (1 shl 11) -end if ; defined E3C59X_DEBUG -.set_media: - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - out dx, eax -if defined E3C59X_FORCE_FD -; set fullDuplexEnable in MacControl register - lea edx, [ebp+E3C59X_REG_MAC_CONTROL] - in ax, dx - or ax, 0x120 - out dx, ax -end if ; E3C59X_FORCE_FD - mov al, 1 - ret - -;*************************************************************************** -; Function -; e3c59x_set_active_port -; Description -; It selects the media port (transceiver) to be used -; Parameters: -; ebp - io_addr -; Return value: -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** - align 4 -e3c59x_set_active_port: -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - in eax, dx - test eax, (1 shl 24) ; check if autoselect enable - jz .set_first_available_media -; check 100BASE-TX and 10BASE-T - lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] - in ax, dx - test al, 1010b ; check whether 100BASE-TX or 10BASE-T available - jz .mii_device ; they are not available -; set auto-negotiation - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - in eax, dx - and eax, not (1111b shl 20) - or eax, (1000b shl 20) - out dx, eax - call e3c59x_try_mii - test al, al - jz .mii_device - ret -.mii_device: -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax -; check for off-chip mii device - lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] - in ax, dx - test al, 1000000b ; check miiDevice - jz .base_fx - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - in eax, dx - and eax, not (1111b shl 20) - or eax, (0110b shl 20) ; set MIIDevice - out dx, eax - call e3c59x_try_mii - test al, al - jz .base_fx - ret -.base_fx: -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax -; check for 100BASE-FX - lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] - in ax, dx ; read media option register - test al, 100b ; check 100BASE-FX - jz .aui_enable - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - in eax, dx - and eax, not (1111b shl 20) - or eax, (0101b shl 20) ; set 100base-FX - out dx, eax - call e3c59x_try_link_detect - test al, al - jz .aui_enable - ret -.aui_enable: -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax -; check for 10Mbps AUI connector - lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] - in ax, dx ; read media option register - test al, 100000b ; check 10Mbps AUI connector - jz .coax_available - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - in eax, dx - and eax, not (1111b shl 20) - or eax, (0001b shl 20) ; set 10Mbps AUI connector - out dx, eax - xor al, al ; try 10Mbps AUI connector - call e3c59x_try_loopback - test al, al - jz .coax_available - ret -.coax_available: -; switch to register window 3 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 - out dx, ax -; check for coaxial 10BASE-2 port - lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] - in ax, dx ; read media option register - test al, 10000b ; check 10BASE-2 - jz .set_first_available_media - lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] - in eax, dx - and eax, not (1111b shl 20) - or eax, (0011b shl 20) ; set 10BASE-2 - out dx, eax - mov al, 1 - call e3c59x_try_loopback - test al, al - jz .set_first_available_media - ret -.set_first_available_media: - jmp e3c59x_set_available_media - -;*************************************************************************** -; Function -; e3c59x_wake_up -; Description -; set the power state to D0 -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** - align 4 -e3c59x_wake_up: -; wake up - we directly do it by programming PCI -; check if the device is power management capable - mov al, 2 - mov ah, [pci_bus] - mov bl, PCI_REG_STATUS - mov bh, [pci_dev] - push eax ebx - call pci_read_reg - test al, 10000b ; is there "new capabilities" linked list? - pop ebx eax - jz .device_awake -; search for power management register - mov al, 1 - mov bl, PCI_REG_CAP_PTR - push eax ebx - call pci_read_reg - mov cl, al - cmp cl, 0x3f - pop ebx eax - jbe .device_awake -; traverse the list - mov al, 2 -.pm_loop: - mov bl, cl - push eax ebx - call pci_read_reg - cmp al, 1 - je .set_pm_state - test ah, ah - mov cl, ah - pop ebx eax - jnz .pm_loop - jmp .device_awake -; waku up the device if necessary -.set_pm_state: - pop ebx eax - add bl, PCI_REG_PM_CTRL - push eax ebx - call pci_read_reg - mov cx, ax - test cl, 3 - pop ebx eax - jz .device_awake - and cl, not 11b ; set state to D0 - call pci_write_reg -.device_awake: - ret - -;*************************************************************************** -; Function -; e3c59x_probe -; Description -; Searches for an ethernet card, enables it and clears the rx buffer -; If a card was found, it enables the ethernet -> TCPIP link -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** - align 4 -e3c59x_probe: - movzx ebp, word [io_addr] - mov al, 2 - mov ah, [pci_bus] - mov bh, [pci_dev] - mov bl, PCI_REG_COMMAND - push ebp eax ebx - call pci_read_reg - mov cx, ax - or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) - and cl, not (1 shl PCI_BIT_MMIO) - pop ebx eax - call pci_write_reg -; wake up the card - call e3c59x_wake_up - pop ebp -; get chip version - mov ax, [pci_data+2] - mov ecx, E3C59X_HW_VERSIONS_SIZE/4-1 -.chip_ver_loop: - cmp ax, [e3c59x_hw_versions+ecx*4] - jz .chip_ver_found - dec ecx - jns .chip_ver_loop - xor ecx, ecx -.chip_ver_found: - mov [e3c59x_ver_id], cl - test word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM - setnz [e3c59x_has_hwcksm] -; set pci latency for vortex cards - test word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX - jz .not_vortex - mov cx, 11111000b ; 248 = max latency - mov al, 1 - mov ah, [pci_bus] - mov bl, PCI_REG_LATENCY - mov bh, [pci_dev] - call pci_write_reg -.not_vortex: -; set RX/TX functions - mov ax, E3C59X_EEPROM_REG_CAPABILITIES - call e3c59x_read_eeprom - test al, 100000b ; full bus master? - setnz [e3c59x_full_bus_master] - jnz .boomerang_func - mov dword [e3c59x_transmit_function], e3c59x_vortex_transmit - mov dword [e3c59x_receive_function], e3c59x_vortex_poll - jmp @f -.boomerang_func: ; full bus master, so use boomerang functions - mov dword [e3c59x_transmit_function], e3c59x_boomerang_transmit - mov dword [e3c59x_receive_function], e3c59x_boomerang_poll -@@: -; read MAC from eeprom - mov ecx, 2 -.mac_loop: - lea ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx] - call e3c59x_read_eeprom - xchg ah, al ; htons - mov [node_addr+ecx*2], ax - dec ecx - jns .mac_loop - test byte [e3c59x_full_bus_master], 0xff - jz .set_preamble -; switch to register window 2 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 - out dx, ax -; activate xcvr by setting some magic bits - lea edx, [ebp+E3C59X_REG_RESET_OPTIONS] - in ax, dx - and ax, not 0x4010 - movzx ebx, byte [e3c59x_ver_id] - test word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR - jz @f - or al, 0x10 -@@: - test word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR - jz @f - or ah, 0x40 -@@: - out dx, ax -.set_preamble: -; use preamble as default - mov byte [e3c59x_preamble], 1 ; enable preamble - -;*************************************************************************** -; Function -; e3c59x_reset -; Description -; Place the chip (ie, the ethernet card) into a virgin state -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** -e3c59x_reset: -; issue global reset - call e3c59x_global_reset -; disable interrupts - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (1110b shl 11) - out dx, ax -; enable Statistics - mov ax, (10101b shl 11) - out dx, ax -; set indication - mov ax, (1111b shl 11) or 0x6c6 - out dx, ax -; acknowledge (clear) every interrupt indicator - mov ax, (1101b shl 11) or 0x661 - out dx, ax -; switch to register window 2 - mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 - out dx, ax -; write MAC addres back into the station address registers - lea edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO] - mov esi, node_addr - cld - outsw - add edx, 2 - outsw - add edx, 2 - outsw - add edx, 2 -; clear station mask - xor eax, eax - out dx, ax - add edx, 2 - out dx, ax - add edx, 2 - out dx, ax -; switch to register window 6 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+6 - out dx, ax -; clear all statistics by reading - lea edx, [ebp+E3C59X_REG_CARRIER_LOST] - mov cl, 9 -.stat_clearing_loop: - in al, dx - inc edx - dec cl - jns .stat_clearing_loop - in ax, dx - add dx, 2 - in ax, dx -; switch to register window 4 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 - out dx, ax -; clear BadSSD - lea edx, [ebp+E3C59X_REG_BAD_SSD] - in al, dx -; clear extra statistics bit in NetworkDiagnostic - lea edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC] - in ax, dx - or ax, 0x0040 - out dx, ax -; SetRxEarlyThreshold - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2) - out dx, ax - test byte [e3c59x_full_bus_master], 0xff - jz .skip_boomerang_setting -; set upRxEarlyEnable - lea edx, [ebp+E3C59X_REG_DMA_CTRL] - in eax, dx - or eax, 0x20 - out dx, eax -; TxFreeThreshold - lea edx, [ebp+E3C59X_REG_TX_FREE_THRESH] - mov al, (E3C59X_MAX_ETH_PKT_SIZE / 256) - out dx, al -; program DnListPtr - lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] - xor eax, eax - out dx, eax -.skip_boomerang_setting: -; initialization - call e3c59x_rx_reset - call e3c59x_tx_reset - call e3c59x_set_active_port - call e3c59x_rx_reset - call e3c59x_tx_reset -; switch to register window 5 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 - out dx, ax -; program RxFilter for promiscuous operation - mov ax, (10000b shl 11) - lea edx, [ebp+E3C59X_REG_RX_FILTER] - in al, dx - or al, 1111b - lea edx, [ebp+E3C59X_REG_COMMAND] - out dx, ax -; switch to register window 4 - mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 - out dx, ax -; wait for linkDetect - lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] - mov cl, 20 ; wait for max 2s - mov esi, 100 ; 100ms -.link_detect_loop: - call delay_ms - in ax, dx - test ah, 1000b ; linkDetect - jnz @f - dec cl - jnz .link_detect_loop -@@: -; Indicate that we have successfully reset the card - mov eax, [pci_data] - mov [eth_status], eax -if defined E3C59X_DEBUG - call e3c59x_debug -end if ; defined E3C59X_DEBUG - ret - -;*************************************************************************** -; Function -; e3c59x_global_reset -; Description -; resets the device -; Parameters: -; ebp - io_addr -; Return value: -; Destroyed registers -; ax, ecx, edx, esi -; -;*************************************************************************** - align 4 -e3c59x_global_reset: -; GlobalReset - lea edx, [ebp+E3C59X_REG_COMMAND] - xor eax, eax -; or al, 0x14 - out dx, ax -; wait for GlobalReset to complete - mov ecx, 64000 -.global_reset_loop: - in ax, dx - test ah, 10000b ; check CmdInProgress - jz .finish - dec ecx - jnz .global_reset_loop -.finish: -; wait for 2 seconds for NIC to boot - mov esi, 2000 ; 2000ms = 2s - push ebp - call delay_ms - pop ebp - ret - -;*************************************************************************** -; Function -; e3c59x_tx_reset -; Description -; resets and enables transmitter engine -; Parameters: -; ebp - io_addr -; Return value: -; Destroyed registers -; ax, ecx, edx -; -;*************************************************************************** - align 4 -e3c59x_tx_reset: -; TxReset - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (01011b shl 11) - out dx, ax -; wait for TxReset to complete - mov ecx, 2000 -.tx_reset_loop: - in ax, dx - test ah, 10000b ; check CmdInProgress - jz .tx_enable - dec ecx - jns .tx_reset_loop - test byte [e3c59x_full_bus_master], 0xff - jz .tx_enable -; init last_dpd - mov dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE - mov dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE -.tx_enable: - mov ax, (01001b shl 11) ; TxEnable - out dx, ax - ret - -;*************************************************************************** -; Function -; e3c59x_rx_reset -; Description -; resets and enables receiver engine -; Parameters: -; ebp - io_addr -; Return value: -; Destroyed registers -; eax, ebx, ecx, edx, edi, esi -; -;*************************************************************************** - align 4 -e3c59x_rx_reset: - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (0101b shl 11) or 0x4 ; RxReset - out dx, ax -; wait for RxReset to complete - mov ecx, 200000 -.rx_reset_loop: - in ax, dx - test ah, 10000b ; check CmdInProgress - jz .setup_upd - dec ecx - jns .rx_reset_loop -.setup_upd: -; check if full bus mastering - test byte [e3c59x_full_bus_master], 0xff - jz .rx_enable -; create upd ring - mov eax, e3c59x_upd_buff - zero_to_virt eax - mov [e3c59x_curr_upd], eax - mov esi, eax - virt_to_dma esi - mov edi, e3c59x_rx_buff - zero_to_dma edi - mov ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE - zero_to_virt ebx - mov cl, E3C59X_NUM_RX_DESC-1 -.upd_loop: - mov [ebx+E3C59X_UPD_UP_NEXT_PTR], esi - and dword [eax+E3C59X_UPD_PKT_STATUS], 0 - mov [eax+E3C59X_UPD_UP_FRAG_ADDR], edi - mov dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31) - add edi, E3C59X_MAX_ETH_FRAME_SIZE - add esi, E3C59X_UPD_SIZE - mov ebx, eax - add eax, E3C59X_UPD_SIZE - dec cl - jns .upd_loop - mov eax, e3c59x_upd_buff - zero_to_dma eax - lea edx, [ebp+E3C59X_REG_UP_LIST_PTR] - out dx, eax ; write E3C59X_REG_UP_LIST_PTR - lea edx, [ebp+E3C59X_REG_COMMAND] -.rx_enable: - mov ax, (00100b shl 11) ; RxEnable - out dx, ax - ret - -;*************************************************************************** -; Function -; e3c59x_write_eeprom -; Description -; reads eeprom -; Note : the caller must switch to the register window 0 -; before calling this function -; Parameters: -; ax - register to be read (only the first 63 words can be read) -; cx - value to be read into the register -; Return value: -; ax - word read -; Destroyed registers -; ax, ebx, edx -; -;*************************************************************************** -; align 4 -;e3c59x_write_eeprom: -; mov edx, [io_addr] -; add edx, E3C59X_REG_EEPROM_COMMAND -; cmp ah, 11b -; ja .finish ; address may have a value of maximal 1023 -; shl ax, 2 -; shr al, 2 -; push eax -;; wait for busy -; mov ebx, 0xffff -;@@: -; in ax, dx -; test ah, 0x80 -; jz .write_enable -; dec ebx -; jns @r -;; write enable -;.write_enable: -; xor eax, eax -; mov eax, (11b shl 4) -; out dx, ax -;; wait for busy -; mov ebx, 0xffff -;@@: -; in ax, dx -; test ah, 0x80 -; jz .erase_loop -; dec ebx -; jns @r -;.erase_loop: -; pop eax -; push eax -; or ax, (11b shl 6) ; erase register -; out dx, ax -; mov ebx, 0xffff -;@@: -; in ax, dx -; test ah, 0x80 -; jz .write_reg -; dec ebx -; jns @r -;.write_reg: -; add edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND -; mov eax, ecx -; out dx, ax -;; write enable -; add edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA -; xor eax, eax -; mov eax, (11b shl 4) -; out dx, ax -; wait for busy -; mov ebx, 0xffff -;@@: -; in ax, dx -; test ah, 0x80 -; jz .issue_write_reg -; dec ebx -; jns @r -;.issue_write_reg: -; pop eax -; or ax, 01b shl 6 -; out dx, ax -;.finish: -; ret -;*************************************************************************** -; Function -; e3c59x_read_eeprom -; Description -; reads eeprom -; Parameters: -; ax - register to be read (only the first 63 words can be read) -; ebp - io_addr -; Return value: -; ax - word read -; Destroyed registers -; ax, ebx, edx, ebp -; -;*************************************************************************** - align 4 -e3c59x_read_eeprom: - push eax -; switch to register window 0 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+0 - out dx, ax - pop eax - and ax, 111111b ; take only the first 6 bits into account - movzx ebx, byte [e3c59x_ver_id] - test word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT - jz @f - add ax, 0x230 ; hardware constant - jmp .read -@@: - add ax, E3C59X_EEPROM_CMD_READ - test word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET - jz .read - add ax, 0x30 -.read: - lea edx, [ebp+E3C59X_REG_EEPROM_COMMAND] - out dx, ax - mov ebx, 0xffff ; duration of about 162 us ;-) -.wait_for_reading: - in ax, dx - test ah, 0x80 ; check bit eepromBusy - jz .read_data - dec ebx - jns .wait_for_reading -.read_data: - lea edx, [ebp+E3C59X_REG_EEPROM_DATA] - in ax, dx - ret - -;*************************************************************************** -; Function -; e3c59x_mdio_sync -; Description -; initial synchronization -; Parameters -; ebp - io_addr -; Return value -; Destroyed registers -; ax, edx, cl -; -;*************************************************************************** - align 4 -e3c59x_mdio_sync: -; switch to register window 4 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 - out dx, ax - cmp byte [e3c59x_preamble], 0 - je .no_preamble -; send 32 logic ones - lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] - mov cl, 31 -.loop: - mov ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR) - out dx, ax - in ax, dx ; delay - mov ax, (1 shl E3C59X_BIT_MGMT_DATA) \ - or (1 shl E3C59X_BIT_MGMT_DIR) \ - or (1 shl E3C59X_BIT_MGMT_CLK) - out dx, ax - in ax, dx ; delay - dec cl - jns .loop -.no_preamble: - ret - -;*************************************************************************** -; Function -; e3c59x_mdio_read -; Description -; read MII register -; see page 16 in D83840A.pdf -; Parameters -; ah - PHY addr -; al - register addr -; ebp - io_addr -; Return value -; ax - register read -; Destroyed registers -; eax, ebx, cx, edx -; -;*************************************************************************** - align 4 -e3c59x_mdio_read: - push eax - call e3c59x_mdio_sync ; returns with window #4 - pop eax - lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] - shl al, 3 - shr ax, 3 - and ax, not E3C59X_MII_CMD_MASK - or ax, E3C59X_MII_CMD_READ - mov ebx, eax - xor ecx, ecx - mov cl, 13 -.cmd_loop: - mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii - bt ebx, ecx - jnc .zero_bit - or al, (1 shl E3C59X_BIT_MGMT_DATA) -.zero_bit: - out dx, ax - push eax - in ax, dx ; delay - pop eax - or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write - out dx, ax - in ax, dx ; delay - dec cl - jns .cmd_loop -; read data (18 bits with the two transition bits) - mov cl, 17 - xor ebx, ebx -.read_loop: - shl ebx, 1 - xor eax, eax ; read comand - out dx, ax - in ax, dx ; delay - in ax, dx - test al, (1 shl E3C59X_BIT_MGMT_DATA) - jz .dont_set - inc ebx -.dont_set: - mov ax, (1 shl E3C59X_BIT_MGMT_CLK) - out dx, ax - in ax, dx ; delay - dec cl - jns .read_loop - mov eax, ebx - ret - -;*************************************************************************** -; Function -; e3c59x_mdio_write -; Description -; write MII register -; see page 16 in D83840A.pdf -; Parameters -; ah - PHY addr -; al - register addr -; bx - word to be written -; ebp - io_addr -; Return value -; ax - register read -; Destroyed registers -; eax, ebx, cx, edx -; -;*************************************************************************** - align 4 -e3c59x_mdio_write: - push eax - call e3c59x_mdio_sync - pop eax - lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] - shl al, 3 - shr ax, 3 - and ax, not E3C59X_MII_CMD_MASK - or ax, E3C59X_MII_CMD_WRITE - shl eax, 2 - or eax, 10b ; transition bits - shl eax, 16 - mov ax, bx - mov ebx, eax - mov ecx, 31 -.cmd_loop: - mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii - bt ebx, ecx - jnc .zero_bit - or al, (1 shl E3C59X_BIT_MGMT_DATA) -.zero_bit: - out dx, ax - push eax - in ax, dx ; delay - pop eax - or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write - out dx, ax - in ax, dx ; delay - dec ecx - jns .cmd_loop - ret - -;*************************************************************************** -; Function -; e3c59x_transmit -; Description -; Transmits a packet of data via the ethernet card -; edi - Pointer to 48 bit destination address -; bx - Type of packet -; ecx - size of packet -; esi - pointer to packet data -; ebp - io_addr -; Destroyed registers -; eax, ecx, edx, ebp -; -;*************************************************************************** - align 4 -e3c59x_transmit: - jmp dword [e3c59x_transmit_function] - -;*************************************************************************** -; Function -; e3c59x_check_tx_status -; Description -; Checks TxStatus queue. -; Return value -; al - 0 no error was found -; al - 1 error was found TxReset is needed -; Destroyed registers -; eax, ecx, edx, ebp -; -;*************************************************************************** -e3c59x_check_tx_status: - movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC -; clear TxStatus queue - lea edx, [ebp+E3C59X_REG_TX_STATUS] - mov cl, 31 ; max number of queue entries -.tx_status_loop: - in al, dx - test al, al - jz .finish ; no error - test al, 0x3f - jnz .finish ; error -.no_error_found: -; clear current TxStatus entry which advances the next one - xor al, al - out dx, al - dec cl - jns .tx_status_loop -.finish: - ret - -;*************************************************************************** -; Function -; e3c59x_vortex_transmit -; Description -; Transmits a packet of data via the ethernet card -; edi - Pointer to 48 bit destination address -; bx - Type of packet -; ecx - size of packet -; esi - pointer to packet data -; ebp - io_addr -; Destroyed registers -; eax, edx, ecx, edi, esi, ebp -; -;*************************************************************************** - align 4 -e3c59x_vortex_transmit: - push ecx - call e3c59x_check_tx_status - pop ecx - test al, al - jz .no_error_found - jmp e3c59x_tx_reset -.no_error_found: -; switch to register window 7 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 - out dx, ax -; check for master operation in progress - lea edx, [ebp+E3C59X_REG_MASTER_STATUS] - in ax, dx - test ah, 0x80 - jnz .finish ; no DMA for sending -; dword boundary correction - cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE - ja .finish ; packet is too long -; write Frame Start Header - mov eax, ecx -; add header length and extend the complete length to dword boundary - add eax, ETH_HLEN+3 - and eax, not 3 - lea edx, [ebp+E3C59X_REG_TX_DATA] - out dx, eax -; prepare the complete frame - push esi - mov esi, edi - mov edi, e3c59x_tx_buff - zero_to_virt edi - cld -; copy destination address - movsd - movsw -; copy source address - mov esi, node_addr - movsd - movsw -; copy packet type - mov [edi], bx - add edi, 2 -; copy packet data - pop esi - push ecx - shr ecx, 2 - rep movsd - pop ecx - and ecx, 3 - rep movsb - mov ecx, eax -; program frame address to be sent - lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] - mov eax, e3c59x_tx_buff - zero_to_dma eax - out dx, eax -; program frame length - lea edx, [ebp+E3C59X_REG_MASTER_LEN] - mov eax, ecx - out dx, ax -; start DMA Down - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (10100b shl 11) + 1 ; StartDMADown - out dx, ax -.finish: - ret - -;*************************************************************************** -; Function -; e3c59x_boomerang_transmit -; Description -; Transmits a packet of data via the ethernet card -; edi - Pointer to 48 bit destination address -; bx - Type of packet -; ecx - size of packet -; esi - pointer to packet data -; ebp - io_addr -; Destroyed registers -; eax, ebx, ecx, edx, esi, edi, ebp -; -;*************************************************************************** - align 4 -e3c59x_boomerang_transmit: - push ecx - call e3c59x_check_tx_status - pop ecx - test al, al - jz .no_error_found - jmp e3c59x_tx_reset -.no_error_found: - cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE - ja .finish ; packet is too long -; calculate descriptor address - mov eax, [e3c59x_prev_dpd] - cmp eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE - jb @f -; wrap around - mov eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE -@@: - add eax, E3C59X_DPD_SIZE - zero_to_virt eax - push eax -; check DnListPtr - lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] - in eax, dx -; mark if Dn_List_Ptr is cleared - test eax, eax - setz [e3c59x_dn_list_ptr_cleared] -; finish if no more free descriptor is available - FIXME! - cmp eax, [esp] - pop eax - jz .finish - push eax esi - mov esi, edi -; calculate tx_buffer address - mov edi, [e3c59x_prev_tx_frame] - cmp edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE - jb @f -; wrap around - mov edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE -@@: - add edi, E3C59X_MAX_ETH_FRAME_SIZE - zero_to_virt edi - mov eax, edi - cld -; copy destination address - movsd - movsw -; copy source address - mov esi, node_addr - movsd - movsw -; copy packet type - mov [edi], bx - add edi, 2 -; copy packet data - pop esi - push ecx - shr ecx, 2 - rep movsd - pop ecx - push ecx - and ecx, 3 - rep movsb -; padding, do we really need it? - pop ecx - add ecx, ETH_HLEN - cmp ecx, ETH_ZLEN - jae @f - mov ecx, ETH_ZLEN -@@: -; calculate - mov ebx, ecx - test byte [e3c59x_has_hwcksm], 0xff - jz @f - or ebx, (1 shl 26) ; set AddTcpChecksum -@@: - or ebx, 0x8000 ; transmission complete notification - or ecx, 0x80000000 ; last fragment -; program DPD - mov edi, eax - pop eax - and dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0 - mov dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx - virt_to_dma edi - mov dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi - mov [eax+E3C59X_DPD_DN_FRAG_LEN], ecx -; calculate physical address - virt_to_dma eax - push eax - cmp byte [e3c59x_dn_list_ptr_cleared], 0 - jz .add_to_list -; write Dn_List_Ptr - out dx, eax - jmp .finish -.add_to_list: -; DnStall - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, ((110b shl 11)+2) - out dx, ax -; wait for DnStall to complete - mov ecx, 6000 -.wait_for_stall: - in ax, dx ; read E3C59X_REG_INT_STATUS - test ah, 10000b - jz .dnstall_ok - dec ecx - jnz .wait_for_stall -.dnstall_ok: - pop eax - push eax - mov ebx, [e3c59x_prev_dpd] - zero_to_virt ebx - mov [ebx], eax - lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] - in eax, dx - test eax, eax - jnz .dnunstall -; if Dn_List_Ptr has been cleared fill it up - pop eax - push eax - out dx, eax -.dnunstall: -; DnUnStall - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, ((110b shl 11)+3) - out dx, ax -.finish: - pop eax - dma_to_zero eax - mov [e3c59x_prev_dpd], eax - dma_to_zero edi - mov [e3c59x_prev_tx_frame], edi - ret - -;*************************************************************************** -; Function -; e3c59x_poll -; Description -; Polls the ethernet card for a received packet -; Received data, if any, ends up in Ether_buffer -; Destroyed registers -; eax, ebx, edx, ecx, edi, esi, ebp -; -;*************************************************************************** - align 4 -e3c59x_poll: - jmp dword [e3c59x_receive_function] - -;*************************************************************************** -; Function -; e3c59x_vortex_poll -; Description -; Polls the ethernet card for a received packet -; Received data, if any, ends up in Ether_buffer -; Parameters -; ebp - io_addr -; Return value -; al - 0 ; no packet received -; al - 1 ; packet received -; Destroyed registers -; eax, ebx, edx, ecx, edi, esi, ebp -; -;*************************************************************************** - align 4 -e3c59x_vortex_poll: - and word [eth_rx_data_len], 0 ; assume no packet received - movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC -.rx_status_loop: -; examine RxStatus - lea edx, [ebp+E3C59X_REG_RX_STATUS] - in ax, dx - test ax, ax - jz .finish - test ah, 0x80 ; rxIncomplete - jz .check_error - jmp .finish -.check_error: - test ah, 0x40 - jz .check_length -; discard the top frame received advancing the next one - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (01000b shl 11) - out dx, ax - jmp .rx_status_loop -.check_length: - and eax, 0x1fff - cmp eax, E3C59X_MAX_ETH_PKT_SIZE - ja .discard_frame ; frame is too long discard it -.check_dma: - push eax -; switch to register window 7 - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 - out dx, ax -; check for master operation in progress - lea edx, [ebp+E3C59X_REG_MASTER_STATUS] - in ax, dx - test ah, 0x80 - jz .read_frame ; no DMA for receiving - pop eax - jmp .finish -.read_frame: -; program buffer address to read in - lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] -if defined E3C59X_LINUX - mov eax, e3c59x_rx_buff - zero_to_dma eax -else - mov eax, Ether_buffer -end if - out dx, eax -; program frame length - lea edx, [ebp+E3C59X_REG_MASTER_LEN] - mov ax, 1560 - out dx, ax -; start DMA Up - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (10100b shl 11) ; StartDMAUp - out dx, ax -; check for master operation in progress -.dma_loop: - lea edx, [ebp+E3C59X_REG_MASTER_STATUS] - in ax, dx - test ah, 0x80 - jnz .dma_loop -; registrate the received packet length - pop eax - mov word [eth_rx_data_len], ax -; discard the top frame received -.discard_frame: - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, (01000b shl 11) - out dx, ax -.finish: -; set return value - cmp word [eth_rx_data_len], 0 - setne al - ret - -;*************************************************************************** -; Function -; e3c59x_boomerang_poll -; Description -; Polls the ethernet card for a received packet -; Received data, if any, ends up in Ether_buffer -; Parameters -; ebp - io_addr -; Return value -; al - 0 ; no packet received -; al - 1 ; packet received -; Destroyed registers -; eax, edx, ecx, edi, esi, ebp -; -;*************************************************************************** - align 4 -e3c59x_boomerang_poll: - and word [eth_rx_data_len], 0 ; assume no packet received - movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC -; check if packet is uploaded - mov eax, [e3c59x_curr_upd] - test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete - jnz .check_error - jmp .finish -; packet is uploaded check for any error -.check_error: - test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError - jz .copy_packet_length - and dword [eax+E3C59X_UPD_PKT_STATUS], 0 - jmp .finish -.copy_packet_length: - mov ecx, [eax+E3C59X_UPD_PKT_STATUS] - and ecx, 0x1fff - cmp ecx, E3C59X_MAX_ETH_PKT_SIZE - jbe .copy_packet - and dword [eax+E3C59X_UPD_PKT_STATUS], 0 - jmp .finish -.copy_packet: - push ecx - mov word [eth_rx_data_len], cx - mov esi, [eax+E3C59X_UPD_UP_FRAG_ADDR] - dma_to_virt esi - mov edi, Ether_buffer - shr ecx, 2 ; first copy dword-wise - cld - rep movsd ; copy the dwords - pop ecx - and ecx, 3 - rep movsb ; copy the rest bytes - mov eax, [e3c59x_curr_upd] - and dword [eax+E3C59X_UPD_PKT_STATUS], 0 - virt_to_zero eax - cmp eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE - jb .no_wrap -; wrap around - mov eax, e3c59x_upd_buff-E3C59X_UPD_SIZE -.no_wrap: - add eax, E3C59X_UPD_SIZE - zero_to_virt eax - mov [e3c59x_curr_upd], eax -.finish: -; check if the NIC is in the upStall state - lea edx, [ebp+E3C59X_REG_UP_PKT_STATUS] - in eax, dx - test ah, 0x20 ; UpStalled - jz .noUpUnStall -; issue upUnStall command - lea edx, [ebp+E3C59X_REG_COMMAND] - mov ax, ((110b shl 11)+1) ; upUnStall - out dx, ax -.noUpUnStall: -; set return value - cmp word [eth_rx_data_len], 0 - setnz al - ret diff --git a/kernel/trunk/network/eth_drv/i8255x.inc b/kernel/trunk/network/eth_drv/i8255x.inc deleted file mode 100644 index 2aeb86414b..0000000000 --- a/kernel/trunk/network/eth_drv/i8255x.inc +++ /dev/null @@ -1,739 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; I8255X.INC ;; -;; ;; -;; Ethernet driver for Menuet OS ;; -;; ;; -;; Version 0.3 11 August 2003 ;; -;; ;; -;; This driver is based on the eepro100 driver from ;; -;; the etherboot 5.0.6 project. The copyright statement is ;; -;; ;; -;; GNU GENERAL PUBLIC LICENSE ;; -;; Version 2, June 1991 ;; -;; ;; -;; remaining parts Copyright 2002 Mike Hibbett, ;; -;; mikeh@oceanfree.net ;; -;; ;; -;; See file COPYING for details ;; -;; ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -;******************************************************************** -; Interface -; I8255x_reset -; I8255x_probe -; I8255x_poll -; I8255x_transmit -; -; These functions are referenced in ethernet.inc -; -;******************************************************************** - - -rxfd_status equ eth_data_start -rxfd_command equ eth_data_start + 2 -rxfd_link equ eth_data_start + 4 -rxfd_rx_buf_addr equ eth_data_start + 8 -rxfd_count equ eth_data_start + 12 -rxfd_size equ eth_data_start + 14 -rxfd_packet equ eth_data_start + 16 - - - -uglobal -eeprom_data: times 16 dd 0 - -align 4 - -lstats: -tx_good_frames: dd 0 -tx_coll16_errs: dd 0 -tx_late_colls: dd 0 -tx_underruns: dd 0 -tx_lost_carrier: dd 0 -tx_deferred: dd 0 -tx_one_colls: dd 0 -tx_multi_colls: dd 0 -tx_total_colls: dd 0 -rx_good_frames: dd 0 -rx_crc_errs: dd 0 -rx_align_errs: dd 0 -rx_resource_errs: dd 0 -rx_overrun_errs: dd 0 -rx_colls_errs: dd 0 -rx_runt_errs: dd 0 -done_marker: dd 0 - -align 4 - -confcmd: -confcmd_status: dw 0 -confcmd_command: dw 0 -confcmd_link: dd 0 -endg - -iglobal -confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1 - db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2 - db 0x80, 0x3f, 0x05 -endg - -uglobal -align 4 - -txfd: -txfd_status: dw 0 -txfd_command: dw 0 -txfd_link: dd 0 -txfd_tx_desc_addr: dd 0 -txfd_count: dd 0 -txfd_tx_buf_addr0: dd 0 -txfd_tx_buf_size0: dd 0 -txfd_tx_buf_addr1: dd 0 -txfd_tx_buf_size1: dd 0 - -align 4 - -hdr: -hdr_dst_addr: times 6 db 0 -hdr_src_addr: times 6 db 0 -hdr_type: dw 0 -endg - - -;*************************************************************************** -; Function -; wait_for_cmd_done -; -; Description -; waits for the hardware to complete a command -; port address in edx -; -; al destroyed -;*************************************************************************** -wait_for_cmd_done: - in al, dx - cmp al, 0 - jne wait_for_cmd_done - ret - - - -;*************************************************************************** -; Function -; mdio_read -; -; Description -; This probably reads a register in the "physical media interface chip" -; Phy_id in ebx -; location in ecx -; -; Data returned in eax -; -;*************************************************************************** -mdio_read: - mov edx, [io_addr] - add edx, 16 ; SCBCtrlMDI - - mov eax, 0x08000000 - shl ecx, 16 - or eax, ecx - shl ebx, 21 - or eax, ebx - - out dx, eax - -mrlp: - call delay_us - in eax, dx - mov ecx, eax - and ecx, 0x10000000 - jz mrlp - - and eax, 0xffff - ret - - - -;*************************************************************************** -; Function -; mdio_write -; -; Description -; This probably writes a register in the "physical media interface chip" -; Phy_id in ebx -; location in ecx -; data in edx -; Data returned in eax -; -;*************************************************************************** -mdio_write: - mov eax, 0x04000000 - shl ecx, 16 - or eax, ecx - shl ebx, 21 - or eax, ebx - or eax, edx - - mov edx, [io_addr] - add edx, 16 ; SCBCtrlMDI - out dx, eax - -mwlp: - call delay_us - in eax, dx - mov ecx, eax - and ecx, 0x10000000 - jz mwlp - - and eax, 0xffff - ret - - - -;/***********************************************************************/ -;/* I82557 related defines */ -;/***********************************************************************/ - -; Serial EEPROM section. -; A "bit" grungy, but we work our way through bit-by-bit :->. -; EEPROM_Ctrl bits. -EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock. -EE_CS equ 0x02 ; EEPROM chip select. -EE_DATA_WRITE equ 0x04 ; EEPROM chip data in. -EE_DATA_READ equ 0x08 ; EEPROM chip data out. -EE_WRITE_0 equ 0x4802 -EE_WRITE_1 equ 0x4806 -EE_ENB equ 0x4802 - - -; The EEPROM commands include the alway-set leading bit. -EE_READ_CMD equ 6 - -; The SCB accepts the following controls for the Tx and Rx units: -CU_START equ 0x0010 -CU_RESUME equ 0x0020 -CU_STATSADDR equ 0x0040 -CU_SHOWSTATS equ 0x0050 ; Dump statistics counters. -CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands. -CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters. - -RX_START equ 0x0001 -RX_RESUME equ 0x0002 -RX_ABORT equ 0x0004 -RX_ADDR_LOAD equ 0x0006 -RX_RESUMENR equ 0x0007 -INT_MASK equ 0x0100 -DRVR_INT equ 0x0200 ; Driver generated interrupt. - - -;*************************************************************************** -; Function -; do_eeprom_cmd -; -; Description -; writes a cmd to the ethernet cards eeprom, by bit bashing -; cmd in ebx -; cmd length in ecx -; return in eax -;*************************************************************************** -do_eeprom_cmd: - mov edx, [io_addr] ; We only require the value in dx - add dx, 14 ; the value SCBeeprom - - mov ax, EE_ENB - out dx, ax - call delay_us - - mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK - out dx, ax - call delay_us - - ; dx holds ee_addr - ; ecx holds count - ; eax holds cmd - xor edi, edi ; this will be the receive data - -dec_001: - mov esi, 1 - - dec ecx - shl esi, cl - inc ecx - and esi, ebx - mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags.. - cmp esi,0 - jz dec_002 - mov eax, EE_WRITE_1 - -dec_002: - out dx, ax - call delay_us - - or ax, EE_SHIFT_CLK - out dx, ax - call delay_us - - shl edi,1 - - in ax, dx - and ax, EE_DATA_READ - cmp ax,0 - jz dec_003 - inc edi - -dec_003: - loop dec_001 - - mov ax, EE_ENB - out dx, ax - call delay_us - - mov ax, 0x4800 - out dx, ax - call delay_us - - mov eax, edi - - ret - - - -;*************************************************************************** -; Function -; I8255x_reset -; Description -; Place the chip (ie, the ethernet card) into a virgin state -; No inputs -; All registers destroyed -; -;*************************************************************************** -I8255x_reset: - ret - - - -;*************************************************************************** -; Function -; I8255x_probe -; Description -; Searches for an ethernet card, enables it and clears the rx buffer -; If a card was found, it enables the ethernet -> TCPIP link -; -;*************************************************************************** -I8255x_probe: - mov eax, [io_addr] - - mov ebx, [pci_bus] - mov ecx, [pci_dev] - mov edx, 0x04 ; PCI_COMMAND - call pcibios_read_config_word - - or ax, 0x05 - mov ebx, [pci_bus] - mov ecx, [pci_dev] - mov edx, 0x04 ; PCI_COMMAND - call pcibios_write_config_word - - mov ebx, 0x6000000 - mov ecx, 27 - call do_eeprom_cmd - and eax, 0xffe0000 - cmp eax, 0xffe0000 - je bige - - mov ebx, 0x1800000 - mov ecx, 0x40 - jmp doread - -bige: - mov ebx, 0x6000000 - mov ecx, 0x100 - -doread: - ; do-eeprom-cmd will destroy all registers - ; we have eesize in ecx - ; read_cmd in ebx - - ; Ignore full eeprom - just load the mac address - mov ecx, 0 - -drlp: - push ecx ; save count - push ebx - mov eax, ecx - shl eax, 16 - or ebx, eax - mov ecx, 27 - call do_eeprom_cmd - - pop ebx - pop ecx - - mov edx, ecx - shl edx, 2 - mov esi, eeprom_data - add esi, edx - mov [esi], eax - - inc ecx - cmp ecx, 16 - jne drlp - - ; OK, we have the MAC address. - ; Now reset the card - - mov edx, [io_addr] - add dx, 8 ; SCBPort - xor eax, eax ; The reset cmd == 0 - out dx, eax - - mov esi, 10 - call delay_ms ; Give the card time to warm up. - - mov eax, lstats - mov edx, [io_addr] - add edx, 4 ; SCBPointer - out dx, eax - - mov eax, 0x0140 ; INT_MASK | CU_STATSADDR - mov edx, [io_addr] - add edx, 2 ; SCBCmd - out dx, ax - - call wait_for_cmd_done - - mov eax, 0 - mov edx, [io_addr] - add edx, 4 ; SCBPointer - out dx, eax - - mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD - mov edx, [io_addr] - add edx, 2 ; SCBCmd - out dx, ax - - call wait_for_cmd_done - - ; build rxrd structure - mov ax, 0x0001 - mov [rxfd_status], ax - mov ax, 0x0000 - mov [rxfd_command], ax - - mov eax, rxfd_status - mov [rxfd_link], eax - - mov eax, Ether_buffer - mov [rxfd_rx_buf_addr], eax - - mov ax, 0 - mov [rxfd_count], ax - - mov ax, 1528 - mov [rxfd_size], ax - - mov edx, [io_addr] - add edx, 4 ; SCBPointer - - mov eax, rxfd_status - out dx, eax - - mov edx, [io_addr] - add edx, 2 ; SCBCmd - - mov ax, 0x0101 ; INT_MASK | RX_START - out dx, ax - - call wait_for_cmd_done - - ; start the reciver - - mov ax, 0 - mov [rxfd_status], ax - - mov ax, 0xc000 - mov [rxfd_command], ax - - mov edx, [io_addr] - add edx, 4 ; SCBPointer - - mov eax, rxfd_status - out dx, eax - - mov edx, [io_addr] - add edx, 2 ; SCBCmd - - mov ax, 0x0101 ; INT_MASK | RX_START - out dx, ax - - ; Init TX Stuff - - mov edx, [io_addr] - add edx, 4 ; SCBPointer - - mov eax, 0 - out dx, eax - - mov edx, [io_addr] - add edx, 2 ; SCBCmd - - mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE - out dx, ax - - call wait_for_cmd_done - - ; Set TX Base address - - ; First, set up confcmd values - - mov ax, 2 - mov [confcmd_command], ax - mov eax, txfd - mov [confcmd_link], eax - - mov ax, 1 - mov [txfd_command], ax ; CmdIASetup - - mov ax, 0 - mov [txfd_status], ax - - mov eax, confcmd - mov [txfd_link], eax - - ; ETH_ALEN is 6 bytes - - mov esi, eeprom_data - mov edi, node_addr - mov ecx, 3 -drp000: - mov eax, [esi] - mov [edi], al - shr eax, 8 - inc edi - mov [edi], al - inc edi - add esi, 4 - loop drp000 - - ; Hard code your MAC address into node_addr at this point, - ; If you cannot read the MAC address from the eeprom in the previous step. - ; You also have to write the mac address into txfd_tx_desc_addr, rather - ; than taking data from eeprom_data - - mov esi, eeprom_data - mov edi, txfd_tx_desc_addr - mov ecx, 3 -drp001: - mov eax, [esi] - mov [edi], al - shr eax, 8 - inc edi - mov [edi], al - inc edi - add esi, 4 - loop drp001 - - mov esi, eeprom_data + (6 * 4) - mov eax, [esi] - shr eax, 8 - and eax, 0x3f - cmp eax, 4 ; DP83840 - je drp002 - cmp eax, 10 ; DP83840A - je drp002 - jmp drp003 - -drp002: - mov ebx, [esi] - and ebx, 0x1f - push ebx - mov ecx, 23 - call mdio_read - pop ebx - or eax, 0x0422 - mov ecx, 23 - mov edx, eax - call mdio_write - -drp003: - mov ax, 0x4002 ; Cmdsuspend | CmdConfigure - mov [confcmd_command], ax - mov ax, 0 - mov [confcmd_status], ax - mov eax, txfd - mov [confcmd_link], eax - mov ebx, confcmd_data - mov al, 0x88 ; fifo of 8 each - mov [ebx + 1], al - mov al, 0 - mov [ebx + 4], al - mov al, 0x80 - mov [ebx + 5], al - mov al, 0x48 - mov [ebx + 15], al - mov al, 0x80 - mov [ebx + 19], al - mov al, 0x05 - mov [ebx + 21], al - - mov eax, txfd - mov edx, [io_addr] - add edx, 4 ; SCBPointer - out dx, eax - - mov eax, 0x0110 ; INT_MASK | CU_START - mov edx, [io_addr] - add edx, 2 ; SCBCmd - out dx, ax - - call wait_for_cmd_done -jmp skip - - ; wait for thing to start -drp004: - mov ax, [txfd_status] - cmp ax, 0 - je drp004 - -skip: - ; Indicate that we have successfully reset the card - mov eax, [pci_data] - mov [eth_status], eax - -I8255x_exit: - ret - - - -;*************************************************************************** -; Function -; I8255x_poll -; -; Description -; Polls the ethernet card for a received packet -; Received data, if any, ends up in Ether_buffer -; -;*************************************************************************** -I8255x_poll: - mov ax, 0 ; assume no data - mov [eth_rx_data_len], ax - - mov ax, [rxfd_status] - cmp ax, 0 - je i8p_exit - - mov ax, 0 - mov [rxfd_status], ax - - mov ax, 0xc000 - mov [rxfd_command], ax - - mov edx, [io_addr] - add edx, 4 ; SCBPointer - - mov eax, rxfd_status - out dx, eax - - mov edx, [io_addr] - add edx, 2 ; SCBCmd - - mov ax, 0x0101 ; INT_MASK | RX_START - out dx, ax - - call wait_for_cmd_done - - mov esi, rxfd_packet - mov edi, Ether_buffer - mov ecx, 1518 - cld - rep movsb - - mov ax, [rxfd_count] - and ax, 0x3fff - mov [eth_rx_data_len], ax - -i8p_exit: - ret - - - -;*************************************************************************** -; Function -; I8255x_transmit -; -; Description -; Transmits a packet of data via the ethernet card -; Pointer to 48 bit destination address in edi -; Type of packet in bx -; size of packet in ecx -; pointer to packet data in esi -; -;*************************************************************************** -I8255x_transmit: - - mov [hdr_type], bx - - mov eax, [edi] - mov [hdr_dst_addr], eax - mov ax, [edi+4] - mov [hdr_dst_addr+4], ax - - mov eax, [node_addr] - mov [hdr_src_addr], eax - mov ax, [node_addr+4] - mov [hdr_src_addr+4], ax - - mov edx, [io_addr] - in ax, dx - and ax, 0xfc00 - out dx, ax - - xor ax, ax - mov [txfd_status], ax - mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex - mov [txfd_command], ax - mov eax, txfd - mov [txfd_link], eax - mov eax, 0x02208000 - mov [txfd_count], eax - mov eax, txfd_tx_buf_addr0 - mov [txfd_tx_desc_addr], eax - mov eax, hdr - mov [txfd_tx_buf_addr0], eax - mov eax, 14 ; sizeof hdr - mov [txfd_tx_buf_size0], eax - - ; Copy the buffer address and size in - mov eax, esi - mov [txfd_tx_buf_addr1], eax - mov eax, ecx - mov [txfd_tx_buf_size1], eax - - mov eax, txfd - mov edx, [io_addr] - add edx, 4 ; SCBPointer - out dx, eax - - mov ax, 0x0110 ; INT_MASK | CU_START - mov edx, [io_addr] - add edx, 2 ; SCBCmd - out dx, ax - - call wait_for_cmd_done - - mov edx, [io_addr] - in ax, dx - -I8t_001: - mov ax, [txfd_status] - cmp ax, 0 - je I8t_001 - - mov edx, [io_addr] - in ax, dx - - ret \ No newline at end of file diff --git a/kernel/trunk/network/eth_drv/pcnet32.inc b/kernel/trunk/network/eth_drv/pcnet32.inc deleted file mode 100644 index 4f6e3db1ad..0000000000 --- a/kernel/trunk/network/eth_drv/pcnet32.inc +++ /dev/null @@ -1,814 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; PCNET32.INC ;; -;; ;; -;; Ethernet driver for Menuet OS ;; -;; ;; -;; Version 1.0 31 July 2004 ;; -;; ;; -;; This driver is based on the PCNet32 driver from ;; -;; the etherboot 5.0.6 project. The copyright statement is ;; -;; ;; -;; GNU GENERAL PUBLIC LICENSE ;; -;; Version 2, June 1991 ;; -;; ;; -;; remaining parts Copyright 2004 Jarek Pelczar, ;; -;; jpelczar@interia.pl ;; -;; ;; -;; See file COPYING for details ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;macro PutStr X -;{ -; local .__xyz1 -; local .__xyz2 -; push esi -; mov esi,.__xyz1 -; call sys_msg_board_str -; push eax -; mov eax,1 -; call delay_hs -; pop eax -; jmp .__xyz2 -;.__xyz1: -; db X -; db 13,10,0 -;.__xyz2: -; pop esi -;} -PCNET32_PORT_AUI equ 0x00 -PCNET32_PORT_10BT equ 0x01 -PCNET32_PORT_GPSI equ 0x02 -PCNET32_PORT_MII equ 0x03 -PCNET32_PORT_PORTSEL equ 0x03 -PCNET32_PORT_ASEL equ 0x04 -PCNET32_PORT_100 equ 0x40 -PCNET32_PORT_FD equ 0x80 -PCNET32_DMA_MASK equ 0xffffffff -PCNET32_LOG_TX_BUFFERS equ 1 -PCNET32_LOG_RX_BUFFERS equ 2 -PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS) -PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1) -PCNET32_TX_RING_LEN_BITS equ 0 -PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS) -PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1) -PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4) -PCNET32_PKT_BUF_SZ equ 1544 -PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8 -pcnet32_txb equ (eth_data_start) -pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) -pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) -pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) -virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) -pcnet32_private: -.mode dw ? -.tlen_rlen dw ? -.phys_addr db ?,?,?,?,?,? -.reserved dw ? -.filter dd ?,? -.rx_ring dd ? -.tx_ring dd ? -.cur_rx dd ? -.cur_tx dd ? -.dirty_rx dd ? -.dirty_tx dd ? -.tx_full db ? -.options dd ? -.full_duplex db ? -.chip_version dd ? -.mii db ? -.ltint db ? -.dxsuflo db ? -.fset db ? -.fdx db ? -end virtual -virtual at 0 -pcnet32_rx_head: -.base dd ? -.buf_length dw ? -.status dw ? -.msg_length dd ? -.reserved dd ? -end virtual -virtual at 0 -pcnet32_tx_head: -.base dd ? -.length dw ? -.status dw ? -.misc dd ? -.reserved dd ? -end virtual - -uglobal -pcnet32_access: -.read_csr dd ? -.write_csr dd ? -.read_bcr dd ? -.write_bcr dd ? -.read_rap dd ? -.write_rap dd ? -.reset dd ? -endg - -iglobal -pcnet32_options_mapping: -dd PCNET32_PORT_ASEL ; 0 Auto-select -dd PCNET32_PORT_AUI ; 1 BNC/AUI -dd PCNET32_PORT_AUI ; 2 AUI/BNC -dd PCNET32_PORT_ASEL ; 3 not supported -dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD -dd PCNET32_PORT_ASEL ; 5 not supported -dd PCNET32_PORT_ASEL ; 6 not supported -dd PCNET32_PORT_ASEL ; 7 not supported -dd PCNET32_PORT_ASEL ; 8 not supported -dd PCNET32_PORT_MII ; 9 MII 10baseT -dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD -dd PCNET32_PORT_MII ; 11 MII (autosel) -dd PCNET32_PORT_10BT ; 12 10BaseT -dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx -dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD -dd PCNET32_PORT_ASEL ; 15 not supported -endg - -PCNET32_WIO_RDP equ 0x10 -PCNET32_WIO_RAP equ 0x12 -PCNET32_WIO_RESET equ 0x14 -PCNET32_WIO_BDP equ 0x16 -PCNET32_DWIO_RDP equ 0x10 -PCNET32_DWIO_RAP equ 0x14 -PCNET32_DWIO_RESET equ 0x18 -PCNET32_DWIO_BDP equ 0x1C -PCNET32_TOTAL_SIZE equ 0x20 -; ebx - index -; return: -; eax - data -pcnet32_wio_read_csr: - push edx - lea edx,[ebp+PCNET32_WIO_RAP] - mov ax,bx - out dx,ax - lea edx,[ebp+PCNET32_WIO_RDP] - in ax,dx - and eax,0xffff - pop edx - ret -; eax - data -; ebx - index -pcnet32_wio_write_csr: - push edx - lea edx,[ebp+PCNET32_WIO_RAP] - xchg eax,ebx - out dx,ax - xchg eax,ebx - lea edx,[ebp+PCNET32_WIO_RDP] - out dx,ax - pop edx - ret -; ebx - index -; return: -; eax - data -pcnet32_wio_read_bcr: - push edx - lea edx,[ebp+PCNET32_WIO_RAP] - mov ax,bx - out dx,ax - lea edx,[ebp+PCNET32_WIO_BDP] - in ax,dx - and eax,0xffff - pop edx - ret -; eax - data -; ebx - index -pcnet32_wio_write_bcr: - push edx - lea edx,[ebp+PCNET32_WIO_RAP] - xchg eax,ebx - out dx,ax - xchg eax,ebx - lea edx,[ebp+PCNET32_WIO_BDP] - out dx,ax - pop edx - ret -pcnet32_wio_read_rap: - push edx - lea edx,[ebp+PCNET32_WIO_RAP] - in ax,dx - and eax,0xffff - pop edx - ret -; eax - val -pcnet32_wio_write_rap: - push edx - lea edx,[ebp+PCNET32_WIO_RAP] - out dx,ax - pop edx - ret -pcnet32_wio_reset: - push edx - push eax - lea edx,[ebp+PCNET32_WIO_RESET] - in ax,dx - pop eax - pop edx - ret -pcnet32_wio_check: - push edx - mov ax,88 - lea edx,[ebp+PCNET32_WIO_RAP] - out dx,ax - nop - nop - in ax,dx - cmp ax,88 - sete al - pop edx - ret - -iglobal -pcnet32_wio: - dd pcnet32_wio_read_csr - dd pcnet32_wio_write_csr - dd pcnet32_wio_read_bcr - dd pcnet32_wio_write_bcr - dd pcnet32_wio_read_rap - dd pcnet32_wio_write_rap - dd pcnet32_wio_reset -endg - -; ebx - index -; return: -; eax - data -pcnet32_dwio_read_csr: - push edx - lea edx,[ebp+PCNET32_DWIO_RAP] - mov ebx,eax - out dx,eax - lea edx,[ebp+PCNET32_DWIO_RDP] - in eax,dx - and eax,0xffff - pop edx - ret -; ebx - index -; eax - data -pcnet32_dwio_write_csr: - push edx - lea edx,[ebp+PCNET32_DWIO_RAP] - xchg eax,ebx - out dx,eax - lea edx,[ebp+PCNET32_DWIO_RDP] - xchg eax,ebx - out dx,eax - pop edx - ret -; ebx - index -; return: -; eax - data -pcnet32_dwio_read_bcr: - push edx - lea edx,[ebp+PCNET32_DWIO_RAP] - mov ebx,eax - out dx,eax - lea edx,[ebp+PCNET32_DWIO_BDP] - in eax,dx - and eax,0xffff - pop edx - ret -; ebx - index -; eax - data -pcnet32_dwio_write_bcr: - push edx - lea edx,[ebp+PCNET32_DWIO_RAP] - xchg eax,ebx - out dx,eax - lea edx,[ebp+PCNET32_DWIO_BDP] - xchg eax,ebx - out dx,eax - pop edx - ret -pcnet32_dwio_read_rap: - push edx - lea edx,[ebp+PCNET32_DWIO_RAP] - in eax,dx - and eax,0xffff - pop edx - ret -; eax - val -pcnet32_dwio_write_rap: - push edx - lea edx,[ebp+PCNET32_DWIO_RAP] - out dx,eax - pop edx - ret -pcnet32_dwio_reset: - push edx - push eax - lea edx,[ebp+PCNET32_DWIO_RESET] - in eax,dx - pop eax - pop edx - ret -pcnet32_dwio_check: - push edx - lea edx,[PCNET32_DWIO_RAP] - mov eax,88 - out dx,eax - nop - nop - in eax,dx - and eax,0xffff - cmp eax,88 - sete al - pop edx - ret - -iglobal -pcnet32_dwio: - dd pcnet32_dwio_read_csr - dd pcnet32_dwio_write_csr - dd pcnet32_dwio_read_bcr - dd pcnet32_dwio_write_bcr - dd pcnet32_dwio_read_rap - dd pcnet32_dwio_write_rap - dd pcnet32_dwio_reset -endg - -pcnet32_init_ring: - mov [pcnet32_private.tx_full],0 - mov [pcnet32_private.cur_rx],0 - mov [pcnet32_private.cur_tx],0 - mov [pcnet32_private.dirty_rx],0 - mov [pcnet32_private.dirty_tx],0 - mov edi,pcnet32_rx_ring - mov ecx,PCNET32_RX_RING_SIZE - mov ebx,pcnet32_rxb -.rx_init: - mov [edi+pcnet32_rx_head.base],ebx - mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG - mov [edi+pcnet32_rx_head.status],word 0x8000 - add ebx,PCNET32_PKT_BUF_SZ -; inc ebx - add edi,16 - loop .rx_init - mov edi,pcnet32_tx_ring - mov ecx,PCNET32_TX_RING_SIZE -.tx_init: - mov [edi+pcnet32_tx_head.base],dword 0 - mov [edi+pcnet32_tx_head.status],word 0 - add edi,16 - loop .tx_init - mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) - mov esi,node_addr - mov edi,pcnet32_private.phys_addr - cld - movsd - movsw - mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring - mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring - ret -pcnet32_reset: - ; Reset PCNET32 - mov ebp,[io_addr] - call dword [pcnet32_access.reset] - ; set 32bit mode - mov ebx,20 - mov eax,2 - call dword [pcnet32_access.write_bcr] - ; set/reset autoselect bit - mov ebx,2 - call dword [pcnet32_access.read_bcr] - and eax,not 2 - test [pcnet32_private.options],PCNET32_PORT_ASEL - jz .L1 - or eax,2 -.L1: - call dword [pcnet32_access.write_bcr] - ; Handle full duplex setting - cmp byte [pcnet32_private.full_duplex],0 - je .L2 - mov ebx,9 - call dword [pcnet32_access.read_bcr] - and eax,not 3 - test [pcnet32_private.options],PCNET32_PORT_FD - jz .L3 - or eax,1 - cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI - jne .L4 - or eax,2 - jmp .L4 -.L3: - test [pcnet32_private.options],PCNET32_PORT_ASEL - jz .L4 - cmp [pcnet32_private.chip_version],0x2627 - jne .L4 - or eax,3 -.L4: - mov ebx,9 - call dword [pcnet32_access.write_bcr] -.L2: - ; set/reset GPSI bit - mov ebx,124 - call dword [pcnet32_access.read_csr] - mov ecx,[pcnet32_private.options] - and ecx,PCNET32_PORT_PORTSEL - cmp ecx,PCNET32_PORT_GPSI - jne .L5 - or eax,0x10 -.L5: - call dword [pcnet32_access.write_csr] - cmp [pcnet32_private.mii],0 - je .L6 - test [pcnet32_private.options],PCNET32_PORT_ASEL - jnz .L6 - mov ebx,32 - call dword [pcnet32_access.read_bcr] - and eax,not 0x38 - test [pcnet32_private.options],PCNET32_PORT_FD - jz .L7 - or eax,0x10 -.L7: - test [pcnet32_private.options],PCNET32_PORT_100 - jz .L8 - or eax,0x08 -.L8: - call dword [pcnet32_access.write_bcr] - jmp .L9 -.L6: - test [pcnet32_private.options],PCNET32_PORT_ASEL - jz .L9 - mov ebx,32 -; PutStr "ASEL, enable auto-negotiation" - call dword [pcnet32_access.read_bcr] - and eax,not 0x98 - or eax,0x20 - call dword [pcnet32_access.write_bcr] -.L9: - cmp [pcnet32_private.ltint],0 - je .L10 - mov ebx,5 - call dword [pcnet32_access.read_csr] - or eax,(1 shl 14) - call dword [pcnet32_access.write_csr] -.L10: - mov eax,[pcnet32_private.options] - and eax,PCNET32_PORT_PORTSEL - shl eax,7 - mov [pcnet32_private.mode],ax - mov [pcnet32_private.filter],dword 0xffffffff - mov [pcnet32_private.filter+4],dword 0xffffffff - call pcnet32_init_ring - mov ebx,1 - mov eax,pcnet32_private - and eax,0xffff - call dword [pcnet32_access.write_csr] - mov eax,pcnet32_private - mov ebx,2 - shr eax,16 - call dword [pcnet32_access.write_csr] - mov ebx,4 - mov eax,0x0915 - call dword [pcnet32_access.write_csr] - mov ebx,0 - mov eax,1 - call dword [pcnet32_access.write_csr] - mov ecx,100 -.L11: - xor ebx,ebx - call dword [pcnet32_access.read_csr] - test ax,0x100 - jnz .L12 - loop .L11 -.L12: -; PutStr "hardware reset" - xor ebx,ebx - mov eax,0x0002 - call dword [pcnet32_access.write_csr] - xor ebx,ebx - call dword [pcnet32_access.read_csr] -; PutStr "PCNET reset complete" - ret -pcnet32_adjust_pci_device: - ;*******Get current setting************************ - mov al, 2 ;read a word - mov bh, [pci_dev] - mov ah, [pci_bus] - mov bl, 0x04 ;from command Register - call pci_read_reg - ;******see if its already set as bus master******** - mov bx, ax - and bx,5 - cmp bx,5 - je pcnet32_adjust_pci_device_Latency - ;******Make card a bus master******* - mov cx, ax ;value to write - mov bh, [pci_dev] - mov al, 2 ;write a word - or cx,5 - mov ah, [pci_bus] - mov bl, 0x04 ;to command register - call pci_write_reg - ;******Check latency setting*********** -pcnet32_adjust_pci_device_Latency: - ;*******Get current latency setting************************ -; mov al, 1 ;read a byte -; mov bh, [pci_dev] -; mov ah, [pci_bus] -; mov bl, 0x0D ;from Lantency Timer Register -; call pci_read_reg - ;******see if its aat least 64 clocks******** -; cmp ax,64 -; jge pcnet32_adjust_pci_device_Done - ;******Set latency to 32 clocks******* -; mov cx, 64 ;value to write -; mov bh, [pci_dev] -; mov al, 1 ;write a byte -; mov ah, [pci_bus] -; mov bl, 0x0D ;to Lantency Timer Register -; call pci_write_reg - ;******Check latency setting*********** -pcnet32_adjust_pci_device_Done: - ret -pcnet32_probe: - mov ebp,[io_addr] - call pcnet32_wio_reset - xor ebx,ebx - call pcnet32_wio_read_csr - cmp eax,4 - jne .try_dwio - call pcnet32_wio_check - and al,al - jz .try_dwio -; PutStr "Using WIO" - mov esi,pcnet32_wio - jmp .L1 -.try_dwio: - call pcnet32_dwio_reset - xor ebx,ebx - call pcnet32_dwio_read_csr - cmp eax,4 - jne .no_dev - call pcnet32_dwio_check - and al,al - jz .no_dev -; PutStr "Using DWIO" - mov esi,pcnet32_dwio - jmp .L1 -.no_dev: -; PutStr "PCNET32 not found" - ret -.L1: - mov edi,pcnet32_access - mov ecx,7 - cld - rep movsd - mov ebx,88 - call dword [pcnet32_access.read_csr] - mov ecx,eax - mov ebx,89 - call dword [pcnet32_access.read_csr] - shl eax,16 - or eax,ecx - mov ecx,eax - and ecx,0xfff - cmp ecx,3 - jne .no_dev - shr eax,12 - and eax,0xffff - mov [pcnet32_private.chip_version],eax -; PutStr "PCNET32 chip version OK" - mov [pcnet32_private.fdx],0 - mov [pcnet32_private.mii],0 - mov [pcnet32_private.fset],0 - mov [pcnet32_private.dxsuflo],0 - mov [pcnet32_private.ltint],0 - mov eax,[pcnet32_private.chip_version] - cmp eax,0x2420 - je .L2 - cmp eax,0x2430 - je .L3 - cmp eax,0x2621 - je .L4 - cmp eax,0x2623 - je .L5 - cmp eax,0x2624 - je .L6 - cmp eax,0x2625 - je .L7 - cmp eax,0x2626 - je .L8 - cmp eax,0x2627 - je .L9 -; PutStr "Invalid chip rev" - jmp .no_dev -.L2: -; PutStr "PCnet/PCI 79C970" - jmp .L10 -.L3: -; PutStr "PCnet/PCI 79C970" - jmp .L10 -.L4: -; PutStr "PCnet/PCI II 79C970A" - mov [pcnet32_private.fdx],1 - jmp .L10 -.L5: -; PutStr "PCnet/FAST 79C971" - mov [pcnet32_private.fdx],1 - mov [pcnet32_private.mii],1 - mov [pcnet32_private.fset],1 - mov [pcnet32_private.ltint],1 - jmp .L10 -.L6: -; PutStr "PCnet/FAST+ 79C972" - mov [pcnet32_private.fdx],1 - mov [pcnet32_private.mii],1 - mov [pcnet32_private.fset],1 - jmp .L10 -.L7: -; PutStr "PCnet/FAST III 79C973" - mov [pcnet32_private.fdx],1 - mov [pcnet32_private.mii],1 - jmp .L10 -.L8: -; PutStr "PCnet/Home 79C978" - mov [pcnet32_private.fdx],1 - mov ebx,49 - call dword [pcnet32_access.read_bcr] - call dword [pcnet32_access.write_bcr] - jmp .L10 -.L9: -; PutStr "PCnet/FAST III 79C975" - mov [pcnet32_private.fdx],1 - mov [pcnet32_private.mii],1 -.L10: - cmp [pcnet32_private.fset],1 - jne .L11 - mov ebx,18 - call dword [pcnet32_access.read_bcr] - or eax,0x800 - call dword [pcnet32_access.write_bcr] - mov ebx,80 - call dword [pcnet32_access.read_csr] - and eax,0xc00 - or eax,0xc00 - call dword [pcnet32_access.write_csr] - mov [pcnet32_private.dxsuflo],1 - mov [pcnet32_private.ltint],1 -.L11: - ; read MAC - mov edi,node_addr - mov edx,ebp - mov ecx,6 -.Lmac: - in al,dx - stosb - inc edx - loop .Lmac -; PutStr "MAC read" - call pcnet32_adjust_pci_device -; PutStr "PCI done" - mov eax,PCNET32_PORT_ASEL - mov [pcnet32_private.options],eax - mov [pcnet32_private.mode],word 0x0003 - mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) - mov esi,node_addr - mov edi,pcnet32_private.phys_addr - cld - movsd - movsw - mov [pcnet32_private.filter],dword 0 - mov [pcnet32_private.filter+4],dword 0 - mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring - mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring -; PutStr "Switching to 32" - mov ebx,20 - mov eax,2 - call dword [pcnet32_access.write_bcr] - mov ebx,1 - mov eax,(pcnet32_private and 0xffff) - call dword [pcnet32_access.write_csr] - mov ebx,2 - mov eax,(pcnet32_private shr 16) and 0xffff - call dword [pcnet32_access.write_csr] - mov ebx,0 - mov eax,1 - call dword [pcnet32_access.write_csr] - mov esi,1 - call delay_ms - call pcnet32_reset - mov eax, [pci_data] - mov [eth_status], eax - ret -pcnet32_poll: - xor eax,eax - mov [eth_rx_data_len],ax - mov eax,[pcnet32_private.cur_rx] - and eax,PCNET32_RX_RING_MOD_MASK - mov ebx,eax - imul esi,eax,PCNET32_PKT_BUF_SZ - add esi,pcnet32_rxb - shl ebx,4 - add ebx,pcnet32_rx_ring - mov cx,[ebx+pcnet32_rx_head.status] - test cx,0x8000 - jnz .L1 - cmp ch,3 - jne .L1 -; PutStr "PCNETRX" - mov ecx,[ebx+pcnet32_rx_head.msg_length] - and ecx,0xfff - sub ecx,4 - mov [eth_rx_data_len],cx - push ecx - shr ecx,2 - mov edi,Ether_buffer - cld - rep movsd - pop ecx - and ecx,3 - rep movsb - mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG - or [ebx+pcnet32_rx_head.status],word 0x8000 - inc [pcnet32_private.cur_rx] -.L1: - ret -; Pointer to 48 bit destination address in edi -; Type of packet in bx -; size of packet in ecx -; pointer to packet data in esi -pcnet32_xmit: - push edi - push esi - push ebx - push ecx -; PutStr "PCNETTX" - mov esi,edi - mov edi,[pcnet32_private.cur_tx] - imul edi,PCNET32_PKT_BUF_SZ - add edi,pcnet32_txb ; edi=ptxb - mov eax,edi - cld ; copy MAC - movsd - movsw - mov esi,node_addr - cld - movsd - movsw - mov [edi],bx - add edi,2 - mov esi,[esp+8] - mov ecx,[esp] - push ecx - shr ecx,2 - cld - rep movsd - pop ecx - and ecx,3 - rep movsb -; mov ecx,[esp] -; add ecx,14 ; ETH_HLEN -; xor eax,eax -; pad to min length (60=ETH_ZLEN) -; cmp ecx,60 -; jae .L1 -; sub ecx,60 -; cld -; rep stosb -;.L1: - mov edi,pcnet32_tx_ring+0 ; entry=0 - mov ecx,[esp] - add ecx,14 - cmp cx,60 - jae .L1 - mov cx,60 -.L1: - neg cx - mov [edi+pcnet32_tx_head.length],cx - mov [edi+pcnet32_tx_head.misc],dword 0 - mov [edi+pcnet32_tx_head.base],eax - mov [edi+pcnet32_tx_head.status],word 0x8300 - ; trigger an immediate send poll - mov ebx,0 - mov eax,0x0008 ; 0x0048 - mov ebp,[io_addr] - call dword [pcnet32_access.write_csr] - mov dword [pcnet32_private.cur_tx],0 - ; wait for TX to complete - mov ecx,[timer_ticks];[0xfdf0] - add ecx,100 -.L2: - mov ax,[edi+pcnet32_tx_head.status] - test ax,0x8000 - jz .L3 - cmp ecx,[timer_ticks];[0xfdf0] - jb .L4 - mov esi,10 - call delay_ms - jnz .L2 -.L4: -; PutStr "PCNET: Send timeout" -.L3: - mov dword [edi+pcnet32_tx_head.base],0 - pop ecx - pop ebx - pop esi - pop edi - ret diff --git a/kernel/trunk/network/eth_drv/rtl8029.inc b/kernel/trunk/network/eth_drv/rtl8029.inc deleted file mode 100644 index 40683316b1..0000000000 --- a/kernel/trunk/network/eth_drv/rtl8029.inc +++ /dev/null @@ -1,955 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; RTL8029.INC ;; -;; ;; -;; Ethernet driver for Menuet OS ;; -;; ;; -;; Version 0.2 31 July 2002 ;; -;; ;; -;; This driver is based on the ns8390 driver from ;; -;; the etherboot 5.0.6 project. The copyright statement is ;; -;; ;; -;; GNU GENERAL PUBLIC LICENSE ;; -;; Version 2, June 1991 ;; -;; ;; -;; remaining parts Copyright 2002 Mike Hibbett, ;; -;; mikeh@oceanfree.net ;; -;; ;; -;; See file COPYING for details ;; -;; ;; -;; While this implementation handles only PCI bus RTL8029 ;; -;; hardware, it can be easily adapted to other NE2000 clone ;; -;; products. I just dont have any to try! ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - - -;******************************************************************** -; Interface -; rtl8029_reset -; rtl8029_probe -; rtl8029_poll -; rtl8029_transmit -; -;******************************************************************** - - - - -;************************************************************************** -; 8390 Register Definitions -;************************************************************************** -D8390_P0_COMMAND equ 0x00 -D8390_P0_PSTART equ 0x01 -D8390_P0_PSTOP equ 0x02 -D8390_P0_BOUND equ 0x03 -D8390_P0_TSR equ 0x04 -D8390_P0_TPSR equ 0x04 -D8390_P0_TBCR0 equ 0x05 -D8390_P0_TBCR1 equ 0x06 -D8390_P0_ISR equ 0x07 -D8390_P0_RSAR0 equ 0x08 -D8390_P0_RSAR1 equ 0x09 -D8390_P0_RBCR0 equ 0x0A -D8390_P0_RBCR1 equ 0x0B -D8390_P0_RSR equ 0x0C -D8390_P0_RCR equ 0x0C -D8390_P0_TCR equ 0x0D -D8390_P0_DCR equ 0x0E -D8390_P0_IMR equ 0x0F -D8390_P1_COMMAND equ 0x00 -D8390_P1_PAR0 equ 0x01 -D8390_P1_PAR1 equ 0x02 -D8390_P1_PAR2 equ 0x03 -D8390_P1_PAR3 equ 0x04 -D8390_P1_PAR4 equ 0x05 -D8390_P1_PAR5 equ 0x06 -D8390_P1_CURR equ 0x07 -D8390_P1_MAR0 equ 0x08 - -D8390_COMMAND_PS0 equ 0x0 ; Page 0 select -D8390_COMMAND_PS1 equ 0x40 ; Page 1 select -D8390_COMMAND_PS2 equ 0x80 ; Page 2 select -D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control -D8390_COMMAND_RD1 equ 0x10 -D8390_COMMAND_RD0 equ 0x08 -D8390_COMMAND_TXP equ 0x04 ; transmit packet -D8390_COMMAND_STA equ 0x02 ; start -D8390_COMMAND_STP equ 0x01 ; stop - -D8390_COMMAND_RD2_STA equ 0x22 -D8390_COMMAND_RD2_STP equ 0x21 -D8390_COMMAND_RD1_STA equ 0x12 -D8390_COMMAND_RD0_STA equ 0x0A -D8390_COMMAND_PS0_RD2_STP equ 0x21 -D8390_COMMAND_PS1_RD2_STP equ 0x61 -D8390_COMMAND_PS0_RD2_STA equ 0x22 -D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26 - -D8390_RCR_MON equ 0x20 ; monitor mode - -D8390_DCR_FT1 equ 0x40 -D8390_DCR_LS equ 0x08 ; Loopback select -D8390_DCR_WTS equ 0x01 ; Word transfer select - -D8390_DCR_FT1_LS equ 0x48 -D8390_DCR_WTS_FT1_LS equ 0x49 - -D8390_ISR_PRX equ 0x01 ; successful recv -D8390_ISR_PTX equ 0x02 ; successful xmit -D8390_ISR_RXE equ 0x04 ; receive error -D8390_ISR_TXE equ 0x08 ; transmit error -D8390_ISR_OVW equ 0x10 ; Overflow -D8390_ISR_CNT equ 0x20 ; Counter overflow -D8390_ISR_RDC equ 0x40 ; Remote DMA complete -D8390_ISR_RST equ 0x80 ; reset - -D8390_RSTAT_PRX equ 0x01 ; successful recv -D8390_RSTAT_CRC equ 0x02 ; CRC error -D8390_RSTAT_FAE equ 0x04 ; Frame alignment error -D8390_RSTAT_OVER equ 0x08 ; FIFO overrun - -D8390_TXBUF_SIZE equ 6 -D8390_RXBUF_END equ 32 -D8390_PAGE_SIZE equ 256 - -ETH_ALEN equ 6 -ETH_HLEN equ 14 -ETH_ZLEN equ 60 -ETH_FRAME_LEN equ 1514 - -FLAG_PIO equ 0x01 -FLAG_16BIT equ 0x02 -ASIC_PIO equ 0 - -VENDOR_NONE equ 0 -VENDOR_WD equ 1 -VENDOR_NOVELL equ 2 -VENDOR_3COM equ 3 - -NE_ASIC_OFFSET equ 0x10 -NE_RESET equ 0x0F ; Used to reset card -NE_DATA equ 0x00 ; Used to read/write NIC mem - -MEM_8192 equ 32 -MEM_16384 equ 64 -MEM_32768 equ 128 - -ISA_MAX_ADDR equ 0x400 - -uglobal -eth_flags: db 0 -eth_vendor: db 0 -eth_nic_base: dw 0 -eth_asic_base: dw 0 -eth_memsize: db 0 -eth_rx_start: db 0 -eth_tx_start: db 0 -eth_bmem: dd 0 -eth_rmem: dd 0 -romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -endg - -iglobal -test_data: db 'NE*000 memory',0 -test_buffer: db ' ',0 -endg - -uglobal -eth_type: dw 0 -pkthdr: db 0,0,0,0 ; status, next, (short) len -pktoff: dw 0 -eth_rx_data_ptr: dd 0 -eth_tmp_len: dw 0 -endg - - - -;*************************************************************************** -; Function -; eth_pio_read -; -; Description -; Read a frame from the ethernet card via Programmed I/O -; src in ebx -; cnt in ecx -; dst in edi -;*************************************************************************** -eth_pio_read: - mov al, [eth_flags] - and al, FLAG_16BIT - cmp al, 0 - je epr_001 - - inc ecx - and ecx, 0xFFFFFFFE - -epr_001: - mov al, D8390_COMMAND_RD2_STA - mov dx, [eth_nic_base] - add dx, D8390_P0_COMMAND - out dx, al - - mov al, cl - mov dx, [eth_nic_base] - add dx, D8390_P0_RBCR0 - out dx, al - - mov al, ch - mov dx, [eth_nic_base] - add dx, D8390_P0_RBCR1 - out dx, al - - mov al, bl - mov dx, [eth_nic_base] - add dx, D8390_P0_RSAR0 - out dx, al - - mov al, bh - mov dx, [eth_nic_base] - add dx, D8390_P0_RSAR1 - out dx, al - - mov al, D8390_COMMAND_RD0_STA - mov dx, [eth_nic_base] - add dx, D8390_P0_COMMAND - out dx, al - - mov dx, [eth_asic_base] - add dx, ASIC_PIO - - mov al, [eth_flags] - and al, FLAG_16BIT - cmp al, 0 - je epr_003 - - shr ecx, 1 - -epr_002: - ; 2 bytes at a time - in ax, dx - mov [edi], ax - add edi, 2 - loop epr_002 - ret - -epr_003: - ; 1 byte at a time - in al, dx - mov [edi], al - inc edi - loop epr_003 - ret - - - - -;*************************************************************************** -; Function -; eth_pio_write -; -; Description -; writes a frame to the ethernet card via Programmed I/O -; dst in ebx -; cnt in ecx -; src in esi -;*************************************************************************** -eth_pio_write: - mov al, [eth_flags] - and al, FLAG_16BIT - cmp al, 0 - je epw_001 - - inc ecx - and ecx, 0xFFFFFFFE - -epw_001: - mov al, D8390_COMMAND_RD2_STA - mov dx, [eth_nic_base] - add dx, D8390_P0_COMMAND - out dx, al - - mov al, D8390_ISR_RDC - mov dx, [eth_nic_base] - add dx, D8390_P0_ISR - out dx, al - - - mov al, cl - mov dx, [eth_nic_base] - add dx, D8390_P0_RBCR0 - out dx, al - - mov al, ch - mov dx, [eth_nic_base] - add dx, D8390_P0_RBCR1 - out dx, al - - mov al, bl - mov dx, [eth_nic_base] - add dx, D8390_P0_RSAR0 - out dx, al - - mov al, bh - mov dx, [eth_nic_base] - add dx, D8390_P0_RSAR1 - out dx, al - - mov al, D8390_COMMAND_RD1_STA - mov dx, [eth_nic_base] - add dx, D8390_P0_COMMAND - out dx, al - - mov dx, [eth_asic_base] - add dx, ASIC_PIO - - mov al, [eth_flags] - and al, FLAG_16BIT - cmp al, 0 - je epw_003 - - shr ecx, 1 - -epw_002: - ; 2 bytes at a time - mov ax, [esi] - add esi, 2 - out dx, ax - - loop epw_002 - jmp epw_004 - -epw_003: - ; 1 byte at a time - mov al, [esi] - inc esi - out dx, al - loop epw_003 - -epw_004: - mov dx, [eth_nic_base] - add dx, D8390_P0_ISR - -epw_005: - in al, dx - and al, D8390_ISR_RDC - cmp al, D8390_ISR_RDC - jne epw_005 - - ret - - - -;*************************************************************************** -; Function -; rtl8029_reset -; Description -; Place the chip (ie, the ethernet card) into a virgin state -; No inputs -; All registers destroyed -; -;*************************************************************************** -rtl8029_reset: - mov bx, [eth_nic_base] - - mov dx, bx - add dx, D8390_P0_COMMAND - mov al, D8390_COMMAND_PS0_RD2_STP - out dx, al - - mov dx, bx - add dx, D8390_P0_DCR - mov al, [eth_flags] - and al, FLAG_16BIT - cmp al, FLAG_16BIT - jne nsr_001 - - mov al, 0x49 - jmp nsr_002 - -nsr_001: - mov al, 0x48 - -nsr_002: - out dx, al - - xor al, al - - mov dx, bx - add dx, D8390_P0_RBCR0 - out dx, al - - mov dx, bx - add dx, D8390_P0_RBCR1 - out dx, al - - mov dx, bx - add dx, D8390_P0_RCR - mov al, 0x20 - out dx, al - - mov dx, bx - add dx, D8390_P0_TCR - mov al, 2 - out dx, al - - mov dx, bx - add dx, D8390_P0_TPSR - mov al, [eth_tx_start] - out dx, al - - mov dx, bx - add dx, D8390_P0_PSTART - mov al, [eth_rx_start] - out dx, al - - mov dx, bx - add dx, D8390_P0_PSTOP - mov al, [eth_memsize] - out dx, al - - mov dx, bx - add dx, D8390_P0_BOUND - mov al, [eth_memsize] - dec al - out dx, al - - mov dx, bx - add dx, D8390_P0_ISR - mov al, 0xff - out dx, al - - mov dx, bx - add dx, D8390_P0_IMR - xor al, al - out dx, al - - mov dx, bx - add dx, D8390_P0_COMMAND - mov al, D8390_COMMAND_PS1_RD2_STP - out dx, al - - mov dx, bx - add dx, D8390_P1_PAR0 - mov esi, node_addr - mov ecx, ETH_ALEN - -nsr_003: - mov al, [esi] - out dx, al - - inc esi - inc dx - loop nsr_003 - - mov dx, bx - add dx, D8390_P1_MAR0 - mov ecx, ETH_ALEN - - mov al, 0xff - -nsr_004: - out dx, al - inc dx - loop nsr_004 - - mov dx, bx - add dx, D8390_P1_CURR - mov al, [eth_rx_start] - out dx, al - - mov dx, bx - add dx, D8390_P0_COMMAND - mov al, D8390_COMMAND_PS0_RD2_STA - out dx, al - - mov dx, bx - add dx, D8390_P0_ISR - mov al, 0xff - out dx, al - - mov dx, bx - add dx, D8390_P0_TCR - mov al, 0 - out dx, al - - mov dx, bx - add dx, D8390_P0_RCR - mov al, 4 - out dx, al - - ret - - - -;*************************************************************************** -; Function -; rtl8029_probe -; Description -; Searches for an ethernet card, enables it and clears the rx buffer -; If a card was found, it enables the ethernet -> TCPIP link -; -;*************************************************************************** -rtl8029_probe: - mov eax, [io_addr] - mov [eth_nic_base], ax ; The IO address space is 16 bit only - - mov al, VENDOR_NONE - mov [eth_vendor], al - - mov al, [eth_vendor] - cmp al, VENDOR_NONE - - jne ep_check_have_vendor - xor eax, eax - mov [eth_bmem], eax - - mov al, FLAG_PIO - mov [eth_flags], al - - mov ax, [eth_nic_base] - add ax, NE_ASIC_OFFSET - mov [eth_asic_base], ax - - mov al, MEM_16384 - mov [eth_memsize], al - - mov al, 32 - mov [eth_tx_start], al - - add al, D8390_TXBUF_SIZE - mov [eth_rx_start], al - - mov dx, [eth_asic_base] - add dx, NE_RESET - - in al, dx - out dx, al - - in al, 0x84 - - mov bx, [eth_nic_base] - - mov dx, bx - add dx, D8390_P0_COMMAND - mov al, D8390_COMMAND_RD2_STP - out dx, al - - mov dx, bx - add dx, D8390_P0_RCR - mov al, D8390_RCR_MON - out dx, al - - mov dx, bx - add dx, D8390_P0_DCR - mov al, D8390_DCR_FT1_LS - out dx, al - - mov dx, bx - add dx, D8390_P0_PSTART - mov al, MEM_8192 - out dx, al - - mov dx, bx - add dx, D8390_P0_PSTOP - mov al, MEM_16384 - out dx, al - - mov esi, test_data - mov ebx, 8192 - mov ecx, 14 - call eth_pio_write - - mov ebx, 8192 - mov ecx, 14 - mov edi, test_buffer - call eth_pio_read - - mov esi, test_buffer - mov edi, test_data - mov ecx, 13 - cld - rep cmpsb - - je ep_set_vendor - - mov al, [eth_flags] - or al, FLAG_16BIT - mov [eth_flags], al - - mov al, MEM_32768 - mov [eth_memsize], al - - mov al, 64 - mov [eth_tx_start], al - - add al, D8390_TXBUF_SIZE - mov [eth_rx_start], al - - mov bx, [eth_nic_base] - - mov dx, bx - add dx, D8390_P0_DCR - mov al, D8390_DCR_WTS_FT1_LS - out dx, al - - mov dx, bx - add dx, D8390_P0_PSTART - mov al, MEM_16384 - out dx, al - - mov dx, bx - add dx, D8390_P0_PSTOP - mov al, MEM_32768 - out dx, al - - mov esi, test_data - mov ebx, 16384 - mov ecx, 14 - call eth_pio_write - - mov ebx, 16384 - mov ecx, 14 - mov edi, test_buffer - call eth_pio_read - - mov esi, test_buffer - mov edi, test_data - mov ecx, 13 - cld - rep cmpsb - -ep_set_vendor: - ; this bit is odd - probably left over from my hacking - mov ax, [eth_nic_base] - cmp ax, 0 - je rtl8029_exit - cmp ax, ISA_MAX_ADDR - jbe ep_001 - mov al, [eth_flags] - or al, FLAG_16BIT - mov [eth_flags], al - -ep_001: - mov al, VENDOR_NOVELL - mov [eth_vendor], al - - mov ebx, 0 - mov ecx, 16 - mov edi, romdata - call eth_pio_read - - - mov ecx, ETH_ALEN - mov esi, romdata - mov edi, node_addr - - mov bl, [eth_flags] - and bl, FLAG_16BIT - -ep_002: - mov al, [esi] - mov [edi], al - - inc edi - inc esi - cmp bl, FLAG_16BIT - jne ep_003 - - inc esi - -ep_003: - loop ep_002 - -ep_check_have_vendor: - mov al, [eth_vendor] - cmp al, VENDOR_NONE - je rtl8029_exit - - cmp al, VENDOR_3COM - je ep_reset_card - - mov eax, [eth_bmem] - mov [eth_rmem], eax - -ep_reset_card: - ; Reset the card - call rtl8029_reset - - ; Indicate that we have successfully reset the card - mov eax, [pci_data] - mov [eth_status], eax - -rtl8029_exit: - ret - - - -;*************************************************************************** -; Function -; rtl8029_poll -; -; Description -; Polls the ethernet card for a received packet -; Received data, if any, ends up in Ether_buffer -; -;*************************************************************************** -rtl8029_poll: - mov eax, Ether_buffer - mov [eth_rx_data_ptr], eax - - mov bx, [eth_nic_base] - - mov dx, bx - add dx, D8390_P0_RSR - in al, dx - - and al, D8390_RSTAT_PRX - cmp al, D8390_RSTAT_PRX - jne nsp_exit - - mov dx, bx - add dx, D8390_P0_BOUND - in al, dx - inc al - - cmp al, [eth_memsize] - jb nsp_001 - - mov al, [eth_rx_start] - -nsp_001: - mov ch, al - - mov dx, bx - add dx, D8390_P0_COMMAND - mov al, D8390_COMMAND_PS1 - out dx, al - - mov dx, bx - add dx, D8390_P1_CURR - in al, dx ; get current page - mov cl, al - - mov dx, bx - add dx, D8390_P0_COMMAND - mov al, D8390_COMMAND_PS0 - out dx, al - - cmp cl, [eth_memsize] - jb nsp_002 - - mov cl, [eth_rx_start] - -nsp_002: - cmp cl, ch - je nsp_exit - - xor ax, ax - mov ah, ch - - mov [pktoff], ax - - mov al, [eth_flags] - and al, FLAG_PIO - cmp al, FLAG_PIO - jne nsp_003 - - movzx ebx, word [pktoff] - mov edi, pkthdr - mov ecx, 4 - call eth_pio_read - jmp nsp_004 - -nsp_003: - mov edi, [eth_rmem] - movzx eax, word [pktoff] - add edi, eax - mov eax, [edi] - mov [pkthdr], eax - -nsp_004: - mov ax, [pktoff] - add ax, 4 - mov [pktoff], ax - - mov ax, [pkthdr + 2] - sub ax, 4 - - mov [eth_tmp_len], ax - - cmp ax, ETH_ZLEN - jb nsp_exit - - cmp ax, ETH_FRAME_LEN - ja nsp_exit - - mov al, [pkthdr] - and al, D8390_RSTAT_PRX - cmp al, D8390_RSTAT_PRX - jne nsp_exit - - ; Right, we can now get the data - - mov ax, [eth_tmp_len] - mov [eth_rx_data_len], ax - - xor ebx, ebx - mov bh, [eth_memsize] - sub bx, [pktoff] - - cmp [eth_tmp_len], bx - jbe nsp_005 - - mov al, [eth_flags] - and al, FLAG_PIO - cmp al, FLAG_PIO - jne nsp_006 - - push ebx - mov ecx, ebx - xor ebx, ebx - mov bx, [pktoff] - mov edi, [eth_rx_data_ptr] - call eth_pio_read - pop ebx - jmp nsp_007 - -nsp_006: - ; Not implemented, as we are using PIO mode on this card - -nsp_007: - xor ax, ax - mov ah, [eth_rx_start] - mov [pktoff], ax - - mov eax, [eth_rx_data_ptr] - add eax, ebx - mov [eth_rx_data_ptr], eax - - mov ax, [eth_tmp_len] - sub ax, bx - mov [eth_tmp_len], ax - -nsp_005: - mov al, [eth_flags] - and al, FLAG_PIO - cmp al, FLAG_PIO - jne nsp_008 - - xor ebx, ebx - mov bx, [pktoff] - xor ecx, ecx - mov cx, [eth_tmp_len] - mov edi, [eth_rx_data_ptr] - call eth_pio_read - jmp nsp_009 - -nsp_008: - ; Not implemented, as we are using PIO mode on this card - -nsp_009: - mov al, [pkthdr+1] - cmp al, [eth_rx_start] - jne nsp_010 - - mov al, [eth_memsize] - -nsp_010: - mov dx, [eth_nic_base] - add dx, D8390_P0_BOUND - dec al - out dx, al - -nsp_exit: - ret - - - -;*************************************************************************** -; Function -; rtl8029_transmit -; -; Description -; Transmits a packet of data via the ethernet card -; Pointer to 48 bit destination address in edi -; Type of packet in bx -; size of packet in ecx -; pointer to packet data in esi -; -;*************************************************************************** -rtl8029_transmit: - mov [eth_type], bx - - pusha - - mov esi, edi - xor bx, bx - mov bh, [eth_tx_start] - mov ecx, ETH_ALEN - call eth_pio_write - - mov esi, node_addr - xor bx, bx - mov bh, [eth_tx_start] - add bx, ETH_ALEN - mov ecx, ETH_ALEN - call eth_pio_write - - mov esi, eth_type - xor bx, bx - mov bh, [eth_tx_start] - add bx, ETH_ALEN - add bx, ETH_ALEN - mov ecx, 2 - call eth_pio_write - - popa - - xor bx, bx - mov bh, [eth_tx_start] - add bx, ETH_HLEN - push ecx - call eth_pio_write - pop ecx - - add ecx, ETH_HLEN - cmp ecx, ETH_ZLEN - jae nst_001 - - mov ecx, ETH_ZLEN - -nst_001: - push ecx - - mov bx, [eth_nic_base] - - mov dx, bx - add dx, D8390_P0_COMMAND - mov al, D8390_COMMAND_PS0_RD2_STA - out dx, al - - mov dx, bx - add dx, D8390_P0_TPSR - mov al, [eth_tx_start] - out dx, al - - pop ecx - - mov dx, bx - add dx, D8390_P0_TBCR0 - mov al, cl - out dx, al - - mov dx, bx - add dx, D8390_P0_TBCR1 - mov al, ch - out dx, al - - mov dx, bx - add dx, D8390_P0_COMMAND - mov al, D8390_COMMAND_PS0_TXP_RD2_STA - out dx, al - - ret diff --git a/kernel/trunk/network/eth_drv/rtl8139.inc b/kernel/trunk/network/eth_drv/rtl8139.inc deleted file mode 100644 index d4e50b4225..0000000000 --- a/kernel/trunk/network/eth_drv/rtl8139.inc +++ /dev/null @@ -1,595 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; RTL8139.INC ;; -;; ;; -;; Ethernet driver for Menuet OS ;; -;; ;; -;; Version 0.2 11 August 2003 ;; -;; ;; -;; Driver for chips of RealTek 8139 family ;; -;; References: ;; -;; www.realtek.com.hw - data sheets ;; -;; rtl8139.c - linux driver ;; -;; 8139too.c - linux driver ;; -;; ethernet driver template by Mike Hibbett ;; -;; ;; -;; The copyright statement is ;; -;; ;; -;; GNU GENERAL PUBLIC LICENSE ;; -;; Version 2, June 1991 ;; -;; ;; -;; Copyright 2003 Endre Kozma, ;; -;; endre.kozma@axelero.hu ;; -;; ;; -;; See file COPYING for details ;; -;; ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ETH_ALEN equ 6 - ETH_HLEN equ (2 * ETH_ALEN + 2) - ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for - ; mininmum 64bytes frame length - - PCI_REG_COMMAND equ 0x04 ; command register - PCI_BIT_PIO equ 0 ; bit0: io space control - PCI_BIT_MMIO equ 1 ; bit1: memory space control - PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master - - RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0 - RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4 - RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor - RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor - RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address - RTL8139_REG_COMMAND equ 0x37 ; command register - RTL8139_REG_CAPR equ 0x38 ; current address of packet read - RTL8139_REG_IMR equ 0x3c ; interrupt mask register - RTL8139_REG_ISR equ 0x3e ; interrupt status register - RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register - RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0 - RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1 - RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2 - RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3 - RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0 - RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0 - RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1 - RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2 - RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3 - RTL8139_REG_MPC equ 0x4c ; missed packet counter - RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register - RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1 - RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4 - RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register - RTL8139_REG_BMCR equ 0x62 ; basic mode control register - RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register - -; 5.1 packet header - RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes - RTL8139_BIT_LONG equ 3 ; total packet length > 4k - RTL8139_BIT_CRC equ 2 ; crc error occured - RTL8139_BIT_FAE equ 1 ; frame alignment error occured - RTL8139_BIT_ROK equ 0 ; received packet is ok -; 5.4 command register - RTL8139_BIT_RST equ 4 ; reset bit - RTL8139_BIT_RE equ 3 ; receiver enabled - RTL8139_BIT_TE equ 2 ; transmitter enabled - RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored -; 5.6 interrupt status register - RTL8139_BIT_ISR_TOK equ 2 ; transmit ok - RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt - RTL8139_BIT_ISR_ROK equ 0 ; receive ok -; 5.7 transmit configyration register - RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst - RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16) -; 5.8 receive configuration register - RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold - RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator - RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst - RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping - RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356 - RTL8139_BIT_AER equ 5 ; accept error packets - RTL8139_BIT_AR equ 4 ; accept runt packets - RTL8139_BIT_AB equ 3 ; accept broadcast packets - RTL8139_BIT_AM equ 2 ; accept multicast packets - RTL8139_BIT_APM equ 1 ; accept physical match packets - RTL8139_BIT_AAP equ 0 ; accept all packets -; 5.9 93C46/93C56 command register - RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1 - RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0 - RTL8139_BIT_93C46_EECS equ 3 ; chip select - RTL8139_BIT_93C46_EESK equ 2 ; serial data clock - RTL8139_BIT_93C46_EEDI equ 1 ; serial data input - RTL8139_BIT_93C46_EEDO equ 0 ; serial data output -; 5.11 configuration register 1 - RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1 - RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips - RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips - RTL8139_BIT_PMEn equ 0 ; power management enabled -; 5.14 configuration register 4 - RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4 -; 6.2 transmit status register - RTL8139_BIT_ERTXTH equ 16 ; early TX threshold - RTL8139_BIT_TOK equ 15 ; transmit ok - RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed -; 6.18 basic mode control register - RTL8139_BIT_ANE equ 12 ; auto negotiation enable -; 6.20 auto negotiation advertisement register - RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex - RTL8139_BIT_TX equ 7 ; 100base-T - RTL8139_BIT_10FD equ 6 ; 10base-T full duplex - RTL8139_BIT_10 equ 5 ; 10base-T - RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001 -; RX/TX buffer size - RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k - RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN) - MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC - RTL8139_NUM_TX_DESC equ 4 - RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC) - RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16) - RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128 - ; 4==256 5==512 6==1024 7==2048 - RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256 - RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128 - ; 4==256 5==512 6==1024 7==unlimited - RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128 - ; 4==256 5==512 6==1024 7==no threshold - RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \ - or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \ - or (1 shl RTL8139_BIT_NOWRAP) \ - or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \ - or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \ - or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \ - or (1 shl RTL8139_BIT_AM)) - RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout - - EE_93C46_REG_ETH_ID equ 7 ; MAC offset - EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address - EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address - EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address - EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress - - VER_RTL8139 equ 1100000b - VER_RTL8139A equ 1110000b -; VER_RTL8139AG equ 1110100b - VER_RTL8139B equ 1111000b - VER_RTL8130 equ VER_RTL8139B - VER_RTL8139C equ 1110100b - VER_RTL8100 equ 1111010b - VER_RTL8100B equ 1110101b - VER_RTL8139D equ VER_RTL8100B - VER_RTL8139CP equ 1110110b - VER_RTL8101 equ 1110111b - - IDX_RTL8139 equ 0 - IDX_RTL8139A equ 1 - IDX_RTL8139B equ 2 - IDX_RTL8139C equ 3 - IDX_RTL8100 equ 4 - IDX_RTL8139D equ 5 - IDX_RTL8139D equ 6 - IDX_RTL8101 equ 7 - - -; These two must be 4 byte aligned ( which they are ) -rtl8139_rx_buff equ eth_data_start -rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE) - -uglobal - align 4 -rtl8139_rx_buff_offset: dd 0 -curr_tx_desc: dd 0 -endg - -iglobal -hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C - db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101 -HW_VER_ARRAY_SIZE = $-hw_ver_array -endg - -uglobal -hw_ver_id: db 0 -endg - -;*************************************************************************** -; Function -; rtl8139_probe -; Description -; Searches for an ethernet card, enables it and clears the rx buffer -; If a card was found, it enables the ethernet -> TCPIP link -; Destroyed registers -; eax, ebx, ecx, edx -; -;*************************************************************************** -rtl8139_probe: -; enable the device - mov al, 2 - mov ah, [pci_bus] - mov bh, [pci_dev] - mov bl, PCI_REG_COMMAND - call pci_read_reg - mov cx, ax - or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) - and cl, not (1 shl PCI_BIT_MMIO) - mov al, 2 - mov ah, [pci_bus] - mov bh, [pci_dev] - mov bl, PCI_REG_COMMAND - call pci_write_reg -; get chip version - mov edx, [io_addr] - add edx, RTL8139_REG_TXCONFIG_2 - in ax, dx - shr ah, 2 - shr ax, 6 - and al, 01111111b - mov ecx, HW_VER_ARRAY_SIZE-1 -.chip_ver_loop: - cmp al, [hw_ver_array+ecx] - je .chip_ver_found - dec ecx - jns .chip_ver_loop - xor cl, cl ; default RTL8139 -.chip_ver_found: - mov [hw_ver_id], cl -; wake up the chip - mov edx, [io_addr] - add edx, RTL8139_REG_HLTCLK - mov al, 'R' ; run the clock - out dx, al -; unlock config and BMCR registers - add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK - mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) - out dx, al -; enable power management - add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR - in al, dx - cmp byte [hw_ver_id], IDX_RTL8139B - jl .old_chip -; set LWAKE pin to active high (default value). -; it is for Wake-On-LAN functionality of some motherboards. -; this signal is used to inform the motherboard to execute a wake-up process. -; only at newer chips. - or al, (1 shl RTL8139_BIT_PMEn) - and al, not (1 shl RTL8139_BIT_LWACT) - out dx, al - add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1 - in al, dx - and al, not (1 shl RTL8139_BIT_LWPTN) - out dx, al - jmp .finish_wake_up -.old_chip: -; wake up older chips - and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN)) - out dx, al -.finish_wake_up: -; lock config and BMCR registers - xor al, al - mov edx, [io_addr] - add edx, RTL8139_REG_9346CR - out dx, al -;*************************************************************************** -; Function -; rt8139_reset -; Description -; Place the chip (ie, the ethernet card) into a virgin state -; Destroyed registers -; eax, ebx, ecx, edx -; -;*************************************************************************** -rtl8139_reset: - mov edx, [io_addr] - add edx, RTL8139_REG_COMMAND - mov al, 1 shl RTL8139_BIT_RST - out dx, al - mov cx, 1000 ; wait no longer for the reset -.wait_for_reset: - in al, dx - test al, 1 shl RTL8139_BIT_RST - jz .reset_completed ; RST remains 1 during reset - dec cx - jns .wait_for_reset -.reset_completed: -; get MAC (hardware address) - mov ecx, 2 -.mac_read_loop: - lea eax, [EE_93C46_REG_ETH_ID+ecx] - push ecx - call rtl8139_read_eeprom - pop ecx - mov [node_addr+ecx*2], ax - dec ecx - jns .mac_read_loop -; unlock config and BMCR registers - mov edx, [io_addr] - add edx, RTL8139_REG_9346CR - mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) - out dx, al -; initialize multicast registers (no filtering) - mov eax, 0xffffffff - add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR - out dx, eax - add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0 - out dx, eax -; enable Rx/Tx - mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE) - add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4 - out dx, al -; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold -; accept broadcast packets, accept physical match packets - mov ax, RTL8139_RX_CONFIG - add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND - out dx, ax -; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 - mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \ - or (RTL8139_TXRR shl RTL8139_BIT_TXRR) - add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG - out dx, ax -; enable auto negotiation - add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG - in ax, dx - or ax, (1 shl RTL8139_BIT_ANE) - out dx, ax -; set auto negotiation advertisement - add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR - in ax, dx - or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \ - or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \ - or (1 shl RTL8139_BIT_TXFD) - out dx, ax -; lock config and BMCR registers - xor eax, eax - add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR - out dx, al -; init RX/TX pointers - mov [rtl8139_rx_buff_offset], eax - mov [curr_tx_desc], eax -; clear missing packet counter - add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR - out dx, eax -; disable all interrupts - add edx, RTL8139_REG_IMR - RTL8139_REG_MPC - out dx, ax -; set RxBuffer address, init RX buffer offset, init TX ring - mov eax, rtl8139_rx_buff - add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR - out dx, eax -; Indicate that we have successfully reset the card - mov eax, [pci_data] - mov [eth_status], eax - ret - -;*************************************************************************** -; Function -; rtl8139_read_eeprom -; Description -; reads eeprom type 93c46 and 93c56 -; Parameters -; al - word to be read (6bit in case of 93c46 and 8bit otherwise) -; Return value -; ax - word read in -; Destroyed register(s) -; eax, cx, ebx, edx -; -;*************************************************************************** -rtl8139_read_eeprom: - movzx ebx, al - mov edx, [io_addr] - add edx, RTL8139_REG_RXCONFIG - in al, dx - test al, (1 shl RTL8139_BIT_9356SEL) - jz .type_93c46 -; and bl, 01111111b ; don't care first bit - or bx, EE_93C56_READ_CMD ; it contains start bit - mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter - jmp .read_eeprom -.type_93c46: - and bl, 00111111b - or bx, EE_93C46_READ_CMD ; it contains start bit - mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter -.read_eeprom: - add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0 -; mov al, (1 shl RTL8139_BIT_93C46_EEM1) -; out dx, al - mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ - or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom - out dx, al -.cmd_loop: - mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) - bt bx, cx - jnc .zero_bit - or al, (1 shl RTL8139_BIT_93C46_EEDI) -.zero_bit: - out dx, al -; push eax -; in eax, dx ; eeprom delay -; pop eax - or al, (1 shl RTL8139_BIT_93C46_EESK) - out dx, al -; in eax, dx ; eeprom delay - dec cx - jns .cmd_loop -; in eax, dx ; eeprom delay - mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) - out dx, al - mov cl, 0xf -.read_loop: - shl ebx, 1 - mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ - or (1 shl RTL8139_BIT_93C46_EECS) \ - or (1 shl RTL8139_BIT_93C46_EESK) - out dx, al -; in eax, dx ; eeprom delay - in al, dx - and al, (1 shl RTL8139_BIT_93C46_EEDO) - jz .dont_set - inc ebx -.dont_set: - mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ - or (1 shl RTL8139_BIT_93C46_EECS) - out dx, al -; in eax, dx ; eeprom delay - dec cl - jns .read_loop - xor al, al - out dx, al - mov ax, bx - ret - -;*************************************************************************** -; Function -; rtl8139_transmit -; Description -; Transmits a packet of data via the ethernet card -; Pointer to 48 bit destination address in edi -; Type of packet in bx -; size of packet in ecx -; pointer to packet data in esi -; Destroyed registers -; eax, edx, esi, edi -; ToDo -; for waiting of timeout the rtl8139 internal timer -; should be used -; -;*************************************************************************** -rtl8139_transmit: - cmp ecx, MAX_ETH_FRAME_SIZE - jg .finish ; packet is too long - push ecx -; check descriptor - mov ecx, [curr_tx_desc] - mov edx, [io_addr] - lea edx, [edx+ecx*4+RTL8139_REG_TSD0] - push edx ebx - in ax, dx - and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) - cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) - jz .send_packet - test ax, 0x1fff ; or no size given - jz .send_packet -; wait for timeout - mov ebx, RTL8139_TX_TIMEOUT - mov eax, 0x5 ; delay x/100 secs - int 0x40 - in ax, dx - and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) - cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) - jz .send_packet -; chip hung, reset it - call rtl8139_reset -; reset the card -.send_packet: -; calculate tx_buffer address - pop ebx - push esi - mov eax, MAX_ETH_FRAME_SIZE - mul dword [curr_tx_desc] - mov esi, edi - lea edi, [rtl8139_tx_buff+eax] - mov eax, edi - cld -; copy destination address - movsd - movsw -; copy source address - mov esi, node_addr - movsd - movsw -; copy packet type - mov [edi], bx - add edi, 2 -; copy the packet data - pop esi edx ecx - push ecx - shr ecx, 2 - rep movsd - pop ecx - push ecx - and ecx, 3 - rep movsb -; set address - add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0 - out dx, eax -; set size and early threshold - pop eax ; pick up the size - add eax, ETH_HLEN - cmp eax, ETH_ZLEN - jnc .no_pad - mov eax, ETH_ZLEN -.no_pad: - or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH) - add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0 - out dx, eax -; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... - inc dword [curr_tx_desc] - and dword [curr_tx_desc], 3 -.finish: - ret - -;*************************************************************************** -; Function -; rtl8139_poll -; -; Description -; Polls the ethernet card for a received packet -; Received data, if any, ends up in Ether_buffer -; Destroyed register(s) -; eax, edx, ecx -; -;*************************************************************************** -rtl8139_poll: - mov word [eth_rx_data_len], 0 - mov edx, [io_addr] - add edx, RTL8139_REG_COMMAND - in al, dx - test al, (1 shl RTL8139_BIT_BUFE) - jnz .finish -; new packet received copy it from rx_buffer into Ether_buffer - mov eax, rtl8139_rx_buff - add eax, [rtl8139_rx_buff_offset] -; check if packet is ok - test byte [eax], (1 shl RTL8139_BIT_ROK) - jz .reset_rx -; packet is ok copy it into the Ether_buffer - movzx ecx, word [eax+2] ; packet length - sub ecx, 4 ; don't copy CRC - mov word [eth_rx_data_len], cx - push ecx - shr ecx, 2 ; first copy dword-wise - lea esi, [eax+4] ; don't copy the packet header - mov edi, Ether_buffer - cld - rep movsd ; copy the dwords - pop ecx - and ecx, 3 - rep movsb ; copy the rest bytes -; update rtl8139_rx_buff_offset - movzx eax, word [eax+2] ; packet length - add eax, [rtl8139_rx_buff_offset] - add eax, 4+3 ; packet header is 4 bytes long + dword alignment - and eax, not 3 ; dword alignment - cmp eax, RTL8139_RX_BUFFER_SIZE - jl .no_wrap - sub eax, RTL8139_RX_BUFFER_SIZE -.no_wrap: - mov [rtl8139_rx_buff_offset], eax -; update CAPR register - sub eax, 0x10 ; value 0x10 is a constant for CAPR - add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND - out dx, ax -.finish: -; clear active interrupt sources - mov edx, [io_addr] - add edx, RTL8139_REG_ISR - in ax, dx - out dx, ax - ret -.reset_rx: - in al, dx ; read command register - push eax - and al, not (1 shl RTL8139_BIT_RE) - out dx, al - pop eax - out dx, al - add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND - mov ax, RTL8139_RX_CONFIG - out dx, ax - ret diff --git a/kernel/trunk/network/eth_drv/sis900.inc b/kernel/trunk/network/eth_drv/sis900.inc deleted file mode 100644 index af54313b9e..0000000000 --- a/kernel/trunk/network/eth_drv/sis900.inc +++ /dev/null @@ -1,1148 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; SIS900.INC ;; -;; ;; -;; Ethernet driver for Menuet OS ;; -;; ;; -;; Version 0.4 26 April 2004 ;; -;; ;; -;; This driver is based on the SIS900 driver from ;; -;; the etherboot 5.0.6 project. The copyright statement is ;; -;; ;; -;; GNU GENERAL PUBLIC LICENSE ;; -;; Version 2, June 1991 ;; -;; ;; -;; remaining parts Copyright 2004 Jason Delozier, ;; -;; cordata51@hotmail.com ;; -;; ;; -;; See file COPYING for details ;; -;; ;; -;; Updates: ;; -;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;******************************************************************** -; Interface -; SIS900_reset -; SIS900_probe -; SIS900_poll -; SIS900_transmit -; -;******************************************************************** -;******************************************************************** -; Comments: -; Known to work with the following SIS900 ethernet cards: -; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x91 -; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x90 -; -; If your card is not listed, try it and let me know if it -; functions properly and it will be aded to the list. If not -; we may be able to add support for it. -; -; How To Use: -; Add the following lines to Ethernet.inc in their appropriate locations -; -; include "Sis900.INC" -; dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, -; SIS900_transmit -; dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, -; SIS900_transmit ;untested -; -; ToDo: -; - Enable MII interface for reading speed -; and duplex settings. -; -; - Update Poll routine to support packet fragmentation. -; -; - Add additional support for other sis900 based cards -; -;******************************************************************** - -; comment the next line out if you don't want debug info printed -; on the debug board. This option adds a lot of bytes to the driver -; so it's worth to comment it out. -; SIS900_DEBUG equ 1 - - -;* buffers and descriptors -cur_rx db 0 -NUM_RX_DESC equ 4 ;* Number of RX descriptors * -NUM_TX_DESC equ 1 ;* Number of TX descriptors * -RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * -TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer * - -uglobal -align 4 -txd: times (3 * NUM_TX_DESC) dd 0 -rxd: times (3 * NUM_RX_DESC) dd 0 -endg - -txb equ eth_data_start -rxb equ txb + (NUM_TX_DESC * TX_BUFF_SZ) -SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address * -SIS900_ETH_HLEN equ 14 ;* Size of ethernet header * -SIS900_ETH_ZLEN equ 60 ;* Minimum packet length * -SIS900_DSIZE equ 0x00000fff -SIS900_CRC_SIZE equ 4 -SIS900_RFADDR_shift equ 16 -;SIS900 Symbolic offsets to registers. - SIS900_cr equ 0x0 ; Command Register - SIS900_cfg equ 0x4 ; Configuration Register - SIS900_mear equ 0x8 ; EEPROM Access Register - SIS900_ptscr equ 0xc ; PCI Test Control Register - SIS900_isr equ 0x10 ; Interrupt Status Register - SIS900_imr equ 0x14 ; Interrupt Mask Register - SIS900_ier equ 0x18 ; Interrupt Enable Register - SIS900_epar equ 0x18 ; Enhanced PHY Access Register - SIS900_txdp equ 0x20 ; Transmit Descriptor Pointer Register - SIS900_txcfg equ 0x24 ; Transmit Configuration Register - SIS900_rxdp equ 0x30 ; Receive Descriptor Pointer Register - SIS900_rxcfg equ 0x34 ; Receive Configuration Register - SIS900_flctrl equ 0x38 ; Flow Control Register - SIS900_rxlen equ 0x3c ; Receive Packet Length Register - SIS900_rfcr equ 0x48 ; Receive Filter Control Register - SIS900_rfdr equ 0x4C ; Receive Filter Data Register - SIS900_pmctrl equ 0xB0 ; Power Management Control Register - SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register -;SIS900 Command Register Bits - SIS900_RELOAD equ 0x00000400 - SIS900_ACCESSMODE equ 0x00000200 - SIS900_RESET equ 0x00000100 - SIS900_SWI equ 0x00000080 - SIS900_RxRESET equ 0x00000020 - SIS900_TxRESET equ 0x00000010 - SIS900_RxDIS equ 0x00000008 - SIS900_RxENA equ 0x00000004 - SIS900_TxDIS equ 0x00000002 - SIS900_TxENA equ 0x00000001 -;SIS900 Configuration Register Bits - SIS900_DESCRFMT equ 0x00000100 ; 7016 specific - SIS900_REQALG equ 0x00000080 - SIS900_SB equ 0x00000040 - SIS900_POW equ 0x00000020 - SIS900_EXD equ 0x00000010 - SIS900_PESEL equ 0x00000008 - SIS900_LPM equ 0x00000004 - SIS900_BEM equ 0x00000001 - SIS900_RND_CNT equ 0x00000400 - SIS900_FAIR_BACKOFF equ 0x00000200 - SIS900_EDB_MASTER_EN equ 0x00002000 -;SIS900 Eeprom Access Reigster Bits - SIS900_MDC equ 0x00000040 - SIS900_MDDIR equ 0x00000020 - SIS900_MDIO equ 0x00000010 ; 7016 specific - SIS900_EECS equ 0x00000008 - SIS900_EECLK equ 0x00000004 - SIS900_EEDO equ 0x00000002 - SIS900_EEDI equ 0x00000001 -;SIS900 TX Configuration Register Bits - SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding - SIS900_MLB equ 0x20000000 ;Mac Loopback Enable - SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup) - SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du -;SIS900 RX Configuration Register Bits - SIS900_AJAB equ 0x08000000 ; - SIS900_ATX equ 0x10000000 ;Accept Transmit Packets - SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes) - SIS900_AEP equ 0x80000000 ;accept error packets -;SIS900 Interrupt Reigster Bits - SIS900_WKEVT equ 0x10000000 - SIS900_TxPAUSEEND equ 0x08000000 - SIS900_TxPAUSE equ 0x04000000 - SIS900_TxRCMP equ 0x02000000 - SIS900_RxRCMP equ 0x01000000 - SIS900_DPERR equ 0x00800000 - SIS900_SSERR equ 0x00400000 - SIS900_RMABT equ 0x00200000 - SIS900_RTABT equ 0x00100000 - SIS900_RxSOVR equ 0x00010000 - SIS900_HIBERR equ 0x00008000 - SIS900_SWINT equ 0x00001000 - SIS900_MIBINT equ 0x00000800 - SIS900_TxURN equ 0x00000400 - SIS900_TxIDLE equ 0x00000200 - SIS900_TxERR equ 0x00000100 - SIS900_TxDESC equ 0x00000080 - SIS900_TxOK equ 0x00000040 - SIS900_RxORN equ 0x00000020 - SIS900_RxIDLE equ 0x00000010 - SIS900_RxEARLY equ 0x00000008 - SIS900_RxERR equ 0x00000004 - SIS900_RxDESC equ 0x00000002 - SIS900_RxOK equ 0x00000001 -;SIS900 Interrupt Enable Reigster Bits - SIS900_IE equ 0x00000001 -;SIS900 Revision ID - SIS900B_900_REV equ 0x03 - SIS630A_900_REV equ 0x80 - SIS630E_900_REV equ 0x81 - SIS630S_900_REV equ 0x82 - SIS630EA1_900_REV equ 0x83 - SIS630ET_900_REV equ 0x84 - SIS635A_900_REV equ 0x90 - SIS900_960_REV equ 0x91 -;SIS900 Receive Filter Control Register Bits - SIS900_RFEN equ 0x80000000 - SIS900_RFAAB equ 0x40000000 - SIS900_RFAAM equ 0x20000000 - SIS900_RFAAP equ 0x10000000 - SIS900_RFPromiscuous equ 0x70000000 -;SIS900 Reveive Filter Data Mask - SIS900_RFDAT equ 0x0000FFFF -;SIS900 Eeprom Address - SIS900_EEPROMSignature equ 0x00 - SIS900_EEPROMVendorID equ 0x02 - SIS900_EEPROMDeviceID equ 0x03 - SIS900_EEPROMMACAddr equ 0x08 - SIS900_EEPROMChecksum equ 0x0b -;The EEPROM commands include the alway-set leading bit. -;SIS900 Eeprom Command - SIS900_EEread equ 0x0180 - SIS900_EEwrite equ 0x0140 - SIS900_EEerase equ 0x01C0 - SIS900_EEwriteEnable equ 0x0130 - SIS900_EEwriteDisable equ 0x0100 - SIS900_EEeraseAll equ 0x0120 - SIS900_EEwriteAll equ 0x0110 - SIS900_EEaddrMask equ 0x013F - SIS900_EEcmdShift equ 16 -;For SiS962 or SiS963, request the eeprom software access - SIS900_EEREQ equ 0x00000400 - SIS900_EEDONE equ 0x00000200 - SIS900_EEGNT equ 0x00000100 -;General Varibles - SIS900_pci_revision: db 0 - SIS900_Status dd 0x03000000 -sis900_specific_table: -; dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0 -; dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0 - dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0 - dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0 - dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN - dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0 - dd SIS900_960_REV,SIS960_get_mac_addr,0 - dd SIS900B_900_REV,SIS900_get_mac_addr,0 - dd 0,0,0,0 ; end of list -sis900_get_mac_func: dd 0 -sis900_special_func: dd 0 -sis900_table_entries: db 8 - -;*************************************************************************** -; Function -; SIS900_probe -; Description -; Searches for an ethernet card, enables it and clears the rx buffer -; If a card was found, it enables the ethernet -> TCPIP link -;not done - still need to probe mii transcievers -;*************************************************************************** -if defined SIS900_DEBUG -SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0 -end if -SIS900_probe: -;******Wake Up Chip******* - mov al, 4 - mov bh, [pci_dev] - mov ecx, 0 - mov ah, [pci_bus] - mov bl, 0x40 - call pci_write_reg -;*******Set some PCI Settings********* - call SIS900_adjust_pci_device -;*****Get Card Revision****** - mov al, 1 ;one byte to read - mov bh, [pci_dev] - mov ah, [pci_bus] - mov bl, 0x08 ;Revision Register - call pci_read_reg - mov [SIS900_pci_revision], al ;save the revision for later use -;****** Look up through the sis900_specific_table - mov esi,sis900_specific_table -.probe_loop: - cmp dword [esi],0 ; Check if we reached end of the list - je .probe_loop_failed - cmp al,[esi] ; Check if revision is OK - je .probe_loop_ok - add esi,12 ; Advance to next entry - jmp .probe_loop -.probe_loop_failed: - jmp SIS900_Probe_Unsupported -;*********Find Get Mac Function********* -.probe_loop_ok: - mov eax,[esi+4] ; Get pointer to "get MAC" function - mov [sis900_get_mac_func],eax - mov eax,[esi+8] ; Get pointer to special initialization fn - mov [sis900_special_func],eax -;******** Get MAC ******** - call dword [sis900_get_mac_func] -;******** Call special initialization fn if requested ******** - cmp dword [sis900_special_func],0 - je .no_special_init - call dword [sis900_special_func] -.no_special_init: -;******** Set table entries ******** - mov al,[SIS900_pci_revision] - cmp al,SIS635A_900_REV - jae .ent16 - cmp al,SIS900B_900_REV - je .ent16 - jmp .ent8 -.ent16: - mov byte [sis900_table_entries],16 -.ent8: -;*******Probe for mii transceiver******* -;TODO!!********************* -;*******Initialize Device******* - call sis900_init - ret - -SIS900_Probe_Unsupported: -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Str_Unsupported - call sys_msg_board_str -end if - ret -;*************************************************************************** -; Function: sis900_init -; -; Description: resets the ethernet controller chip and various -; data structures required for sending and receiving packets. -; -; Arguments: -; -; returns: none -;not done -;*************************************************************************** -sis900_init: - call SIS900_reset ;Done - call SIS900_init_rxfilter ;Done - call SIS900_init_txd ;Done - call SIS900_init_rxd ;Done - call SIS900_set_rx_mode ;done - call SIS900_set_tx_mode - ;call SIS900_check_mode - ret - -;*************************************************************************** -; Function -; SIS900_reset -; Description -; disables interrupts and soft resets the controller chip -; -;done+ -;*************************************************************************** -if defined SIS900_DEBUG - SIS900_Debug_Reset_Failed db 'Reset Failed ',0 -end if -SIS900_reset: - ;******Disable Interrupts and reset Receive Filter******* - mov ebp, [io_addr] ; base address - xor eax, eax ; 0 to initialize - lea edx,[ebp+SIS900_ier] - out dx, eax ; Write 0 to location - lea edx,[ebp+SIS900_imr] - out dx, eax ; Write 0 to location - lea edx,[ebp+SIS900_rfcr] - out dx, eax ; Write 0 to location - ;*******Reset Card*********************************************** - lea edx,[ebp+SIS900_cr] - in eax, dx ; Get current Command Register - or eax, SIS900_RESET ; set flags - or eax, SIS900_RxRESET ; - or eax, SIS900_TxRESET ; - out dx, eax ; Write new Command Register - ;*******Wait Loop************************************************ - lea edx,[ebp+SIS900_isr] - mov ecx, [SIS900_Status] ; Status we would like to see from card - mov ebx, 2001 ; only loop 1000 times -SIS900_Wait: - dec ebx ; 1 less loop - jz SIS900_DoneWait_e ; 1000 times yet? - in eax, dx ; move interrup status to eax - and eax, ecx - xor ecx, eax - jz SIS900_DoneWait - jmp SIS900_Wait -SIS900_DoneWait_e: -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Reset_Failed - call sys_msg_board_str -end if -SIS900_DoneWait: - ;*******Set Configuration Register depending on Card Revision******** - lea edx,[ebp+SIS900_cfg] - mov eax, SIS900_PESEL ; Configuration Register Bit - mov bl, [SIS900_pci_revision] ; card revision - mov cl, SIS635A_900_REV ; Check card revision - cmp bl, cl - je SIS900_RevMatch - mov cl, SIS900B_900_REV ; Check card revision - cmp bl, cl - je SIS900_RevMatch - out dx, eax ; no revision match - jmp SIS900_Reset_Complete -SIS900_RevMatch: ; Revision match - or eax, SIS900_RND_CNT ; Configuration Register Bit - out dx, eax -SIS900_Reset_Complete: - mov eax, [pci_data] - mov [eth_status], eax - ret - -;*************************************************************************** -; Function: sis_init_rxfilter -; -; Description: sets receive filter address to our MAC address -; -; Arguments: -; -; returns: -;done+ -;*************************************************************************** -SIS900_init_rxfilter: - ;****Get Receive Filter Control Register ******** - mov ebp, [io_addr] ; base address - lea edx,[ebp+SIS900_rfcr] - in eax, dx ; get register - push eax - ;****disable packet filtering before setting filter******* - mov eax, SIS900_RFEN ;move receive filter enable flag - not eax ;1s complement - pop ebx ;and with our saved register - and eax, ebx ;disable receiver - push ebx ;save filter for another use - out dx, eax ;set receive disabled - ;********load MAC addr to filter data register********* - xor ecx, ecx -SIS900_RXINT_Mac_Write: - ;high word of eax tells card which mac byte to write - mov eax, ecx - lea edx,[ebp+SIS900_rfcr] - shl eax, 16 ; - out dx, eax ; - lea edx,[ebp+SIS900_rfdr] - mov ax, word [node_addr+ecx*2] ; Get Mac ID word - out dx, ax ; Send Mac ID - inc cl ; send next word - cmp cl, 3 ; more to send? - jne SIS900_RXINT_Mac_Write - ;********enable packet filitering ***** - pop eax ;old register value - lea edx,[ebp+SIS900_rfcr] - or eax, SIS900_RFEN ;enable filtering - out dx, eax ;set register - ret - -;*************************************************************************** -;* -;* Function: sis_init_txd -;* -;* Description: initializes the Tx descriptor -;* -;* Arguments: -;* -;* returns: -;*done -;*************************************************************************** -SIS900_init_txd: - ;********** initialize TX descriptor ************** - mov [txd], dword 0 ;put link to next descriptor in link field - mov [txd+4],dword 0 ;clear status field - mov [txd+8], dword txb ;save address to buffer ptr field - ;*************** load Transmit Descriptor Register *************** - mov dx, [io_addr] ; base address - add dx, SIS900_txdp ; TX Descriptor Pointer - mov eax, txd ; First Descriptor - out dx, eax ; move the pointer - ret - -;*************************************************************************** -;* Function: sis_init_rxd -;* -;* Description: initializes the Rx descriptor ring -;* -;* Arguments: -;* -;* Returns: -;*done -;*************************************************************************** -SIS900_init_rxd: - xor ecx,ecx - mov [cur_rx], cl ;Set cuurent rx discriptor to 0 - ;******** init RX descriptors ******** -SIS900_init_rxd_Loop: - mov eax, ecx ;current descriptor - imul eax, 12 ; - mov ebx, ecx ;determine next link descriptor - inc ebx ; - cmp ebx, NUM_RX_DESC ; - jne SIS900_init_rxd_Loop_0 ; - xor ebx, ebx ; -SIS900_init_rxd_Loop_0: ; - imul ebx, 12 ; - add ebx, rxd ; - mov [rxd+eax], ebx ;save link to next descriptor - mov [rxd+eax+4],dword RX_BUFF_SZ ;status bits init to buf size - mov ebx, ecx ;find where the buf is located - imul ebx,RX_BUFF_SZ ; - add ebx, rxb ; - mov [rxd+eax+8], ebx ;save buffer pointer - inc ecx ;next descriptor - cmp ecx, NUM_RX_DESC ; - jne SIS900_init_rxd_Loop ; - ;********* load Receive Descriptor Register with address of first - ; descriptor********* - mov dx, [io_addr] - add dx, SIS900_rxdp - mov eax, rxd - out dx, eax - ret - -;*************************************************************************** -;* Function: sis900_set_tx_mode -;* -;* Description: -;* sets the transmit mode to allow for full duplex -;* -;* -;* Arguments: -;* -;* Returns: -;* -;* Comments: -;* If you are having problems transmitting packet try changing the -;* Max DMA Burst, Possible settings are as follows: -;* 0x00000000 = 512 bytes -;* 0x00100000 = 4 bytes -;* 0x00200000 = 8 bytes -;* 0x00300000 = 16 bytes -;* 0x00400000 = 32 bytes -;* 0x00500000 = 64 bytes -;* 0x00600000 = 128 bytes -;* 0x00700000 = 256 bytes -;*************************************************************************** -SIS900_set_tx_mode: - mov ebp,[io_addr] - lea edx,[ebp+SIS900_cr] - in eax, dx ; Get current Command Register - or eax, SIS900_TxENA ;Enable Receive - out dx, eax - lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset - mov eax, SIS900_ATP ;allow automatic padding - or eax, SIS900_HBI ;allow heartbeat ignore - or eax, SIS900_CSI ;allow carrier sense ignore - or eax, 0x00600000 ;Max DMA Burst - or eax, 0x00000100 ;TX Fill Threshold - or eax, 0x00000020 ;TX Drain Threshold - out dx, eax - ret - -;*************************************************************************** -;* Function: sis900_set_rx_mode -;* -;* Description: -;* sets the receive mode to accept all broadcast packets and packets -;* with our MAC address, and reject all multicast packets. Also allows -;* full-duplex -;* -;* Arguments: -;* -;* Returns: -;* -;* Comments: -;* If you are having problems receiving packet try changing the -;* Max DMA Burst, Possible settings are as follows: -;* 0x00000000 = 512 bytes -;* 0x00100000 = 4 bytes -;* 0x00200000 = 8 bytes -;* 0x00300000 = 16 bytes -;* 0x00400000 = 32 bytes -;* 0x00500000 = 64 bytes -;* 0x00600000 = 128 bytes -;* 0x00700000 = 256 bytes -;*************************************************************************** -SIS900_mc_filter: times 16 dw 0 -SIS900_set_rx_mode: - mov ebp,[io_addr] - ;**************update Multicast Hash Table in Receive Filter - mov ebx, 0xffff - xor cl, cl -SIS900_set_rx_mode_Loop: - mov eax, ecx - shl eax, 1 - mov [SIS900_mc_filter+eax], ebx - lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset - mov eax, 4 ;determine table entry - add al, cl - shl eax, 16 - out dx, eax ;tell card which entry to modify - lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset - mov eax, ebx ;entry value - out dx, ax ;write value to table in card - inc cl ;next entry - cmp cl,[sis900_table_entries] ; - jl SIS900_set_rx_mode_Loop - ;*******Set Receive Filter Control Register************* - lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset - mov eax, SIS900_RFAAB ;accecpt all broadcast packets - or eax, SIS900_RFAAM ;accept all multicast packets - or eax, SIS900_RFAAP ;Accept all packets - or eax, SIS900_RFEN ;enable receiver filter - out dx, eax - ;******Enable Receiver************ - lea edx,[ebp+SIS900_cr] ; Command Register offset - in eax, dx ; Get current Command Register - or eax, SIS900_RxENA ;Enable Receive - out dx, eax - ;*********Set - lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset - mov eax, SIS900_ATX ;Accept Transmit Packets - ; (Req for full-duplex and PMD Loopback) - or eax, 0x00600000 ;Max DMA Burst - or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes - out dx, eax ; - ret - -;*************************************************************************** -; * SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model -; * @pci_dev: the sis900 pci device -; * @net_dev: the net device to get address for -; * -; * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM -; * is shared by -; * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first -; * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access -; * by LAN, otherwise is not. After MAC address is read from EEPROM, send -; * EEDONE signal to refuse EEPROM access by LAN. -; * The EEPROM map of SiS962 or SiS963 is different to SiS900. -; * The signature field in SiS962 or SiS963 spec is meaningless. -; * MAC address is read into @net_dev->dev_addr. -; *done -;* -;* Return 0 is EAX = failure -;*Done+ -;*************************************************************************** -if defined SIS900_DEBUG -SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0 -SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0 -SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0 -SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0 -end if -SIS960_get_mac_addr: - mov ebp,[io_addr] - ;**********Send Request for eeprom access********************* - lea edx,[ebp+SIS900_mear] ; Eeprom access register - mov eax, SIS900_EEREQ ; Request access to eeprom - out dx, eax ; Send request - xor ebx,ebx ; - ;******Loop 4000 times and if access not granted error out***** -SIS96X_Get_Mac_Wait: - in eax, dx ;get eeprom status - and eax, SIS900_EEGNT ;see if eeprom access granted flag is set - jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom - inc ebx ;else keep waiting - cmp ebx, 4000 ;have we tried 4000 times yet? - jl SIS96X_Get_Mac_Wait ;if not ask again - xor eax, eax ;return zero in eax indicating failure - ;*******Debug ********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Failed - call sys_msg_board_str -end if - jmp SIS960_get_mac_addr_done - ;**********EEprom access granted, read MAC from card************* -SIS900_Got_EEP_Access: - ; zero based so 3-16 bit reads will take place - mov ecx, 2 -SIS96x_mac_read_loop: - mov eax, SIS900_EEPROMMACAddr ;Base Mac Address - add eax, ecx ;Current Mac Byte Offset - push ecx - call sis900_read_eeprom ;try to read 16 bits - pop ecx - mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID varible - dec ecx ;one less word to read - jns SIS96x_mac_read_loop ;if more read more - mov eax, 1 ;return non-zero indicating success - ;*******Debug Print MAC ID to debug window********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Address2 - call sys_msg_board_str - mov edx, node_addr - call Create_Mac_String -end if - ;**********Tell EEPROM We are Done Accessing It********************* -SIS960_get_mac_addr_done: - lea edx,[ebp+SIS900_mear] ; Eeprom access register - mov eax, SIS900_EEDONE ;tell eeprom we are done - out dx,eax - ret -;*************************************************************************** -;* sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model -;* @pci_dev: the sis900 pci device -;* @net_dev: the net device to get address for -;* -;* Older SiS900 and friends, use EEPROM to store MAC address. -;* MAC address is read from read_eeprom() into @net_dev->dev_addr. -;* done/untested -;*************************************************************************** -SIS900_get_mac_addr: - ;*******Debug ********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Start - call sys_msg_board_str -end if - ;******** check to see if we have sane EEPROM ******* - mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature - call sis900_read_eeprom ;try to read 16 bits - cmp ax, 0xffff - je SIS900_Bad_Eeprom - cmp ax, 0 - je SIS900_Bad_Eeprom - ;**************Read MacID************** - ; zero based so 3-16 bit reads will take place - mov ecx, 2 -SIS900_mac_read_loop: - mov eax, SIS900_EEPROMMACAddr ;Base Mac Address - add eax, ecx ;Current Mac Byte Offset - push ecx - call sis900_read_eeprom ;try to read 16 bits - pop ecx - mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID storage - dec ecx ;one less word to read - jns SIS900_mac_read_loop ;if more read more - mov eax, 1 ;return non-zero indicating success - ;*******Debug Print MAC ID to debug window********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Address - call sys_msg_board_str - mov edx, node_addr - call Create_Mac_String -end if - ret - -SIS900_Bad_Eeprom: - xor eax, eax - ;*******Debug ********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Failed - call sys_msg_board_str -end if - ret -;*************************************************************************** -;* Get_Mac_SIS635_900_REV: - Get MAC address for model 635 -;* -;* -;*************************************************************************** -Get_Mac_SIS635_900_REV: -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Start - call sys_msg_board_str -end if - mov ebp,[io_addr] - lea edx,[ebp+SIS900_rfcr] - in eax,dx - mov edi,eax ; EDI=rfcrSave - lea edx,[ebp+SIS900_cr] - or eax,SIS900_RELOAD - out dx,eax - xor eax,eax - out dx,eax - ; Disable packet filtering before setting filter - lea edx,[ebp+SIS900_rfcr] - mov eax,edi - and edi,not SIS900_RFEN - out dx,eax - ; Load MAC to filter data register - xor ecx,ecx - mov esi,node_addr -.get_mac_loop: - lea edx,[ebp+SIS900_rfcr] - mov eax,ecx - shl eax,SIS900_RFADDR_shift - out dx,eax - lea edx,[ebp+SIS900_rfdr] - in eax,dx - mov [esi],ax - add esi,2 - inc ecx - cmp ecx,3 - jne .get_mac_loop - ; Enable packet filtering - ;lea edx,[ebp+SIS900_rfcr] - ;mov eax,edi - ;or eax,SIS900_RFEN - ;out dx, eax - ;*******Debug Print MAC ID to debug window********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Address - call sys_msg_board_str - mov edx, node_addr - call Create_Mac_String -end if - ret -;*************************************************************************** -;* Function: sis900_read_eeprom -;* -;* Description: reads and returns a given location from EEPROM -;* -;* Arguments: eax - location: requested EEPROM location -;* -;* Returns: eax : contents of requested EEPROM location -;* -; Read Serial EEPROM through EEPROM Access Register, Note that location is -; in word (16 bits) unit */ -;done+ -;*************************************************************************** -sis900_read_eeprom: - push esi - push edx - push ecx - push ebx - mov ebp,[io_addr] - mov ebx, eax ;location of Mac byte to read - or ebx, SIS900_EEread ; - lea edx,[ebp+SIS900_mear] ; Eeprom access register - xor eax, eax ; start send - out dx,eax - call SIS900_Eeprom_Delay_1 - mov eax, SIS900_EECLK - out dx, eax - call SIS900_Eeprom_Delay_1 - ;************ Shift the read command (9) bits out. ********* - mov cl, 8 ; -sis900_read_eeprom_Send: - mov eax, 1 - shl eax, cl - and eax, ebx - jz SIS900_Read_Eeprom_8 - mov eax, 9 - jmp SIS900_Read_Eeprom_9 -SIS900_Read_Eeprom_8: - mov eax, 8 -SIS900_Read_Eeprom_9: - out dx, eax - call SIS900_Eeprom_Delay_1 - or eax, SIS900_EECLK - out dx, eax - call SIS900_Eeprom_Delay_1 - cmp cl, 0 - je sis900_read_eeprom_Send_Done - dec cl - jmp sis900_read_eeprom_Send - ;********************* -sis900_read_eeprom_Send_Done: - mov eax, SIS900_EECS ; - out dx, eax - call SIS900_Eeprom_Delay_1 - ;********** Read 16-bits of data in *************** - mov cx, 16 ;16 bits to read -sis900_read_eeprom_Send2: - mov eax, SIS900_EECS - out dx, eax - call SIS900_Eeprom_Delay_1 - or eax, SIS900_EECLK - out dx, eax - call SIS900_Eeprom_Delay_1 - in eax, dx - shl ebx, 1 - and eax, SIS900_EEDO - jz SIS900_Read_Eeprom_0 - or ebx, 1 -SIS900_Read_Eeprom_0: - dec cx - jnz sis900_read_eeprom_Send2 - ;************** Terminate the EEPROM access. ************** - xor eax, eax - out dx, eax - call SIS900_Eeprom_Delay_1 - mov eax, SIS900_EECLK - out dx, eax - mov eax, ebx - and eax, 0x0000ffff ;return only 16 bits - pop ebx - pop ecx - pop edx - pop esi - ret -;*************************************************************************** -; Function -; SIS900_Eeprom_Delay_1 -; Description -; -; -; -; -;*************************************************************************** -SIS900_Eeprom_Delay_1: - push eax - in eax, dx - pop eax - ret - -;*************************************************************************** -; Function -; SIS900_poll -; Description -; polls card to see if there is a packet waiting -; -; Currently only supports one descriptor per packet, if packet is fragmented -; between multiple descriptors you will lose part of the packet -;*************************************************************************** -if defined SIS900_DEBUG -SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0 -SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0 -SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0 -end if -SIS900_poll: - ;**************Get Status ************** - xor eax, eax ;get RX_Status - mov [eth_rx_data_len], ax - mov al, [cur_rx] ;find current discriptor - imul eax, 12 ; - mov ecx, [rxd+eax+4] ; get receive status - ;**************Check Status ************** - mov ebx, ecx ;move status - ;Check RX_Status to see if packet is waiting - and ebx, 0x80000000 - jnz SIS900_poll_IS_packet - ret - ;**********There is a packet waiting check it for errors************** -SIS900_poll_IS_packet: - mov ebx, ecx ;move status - and ebx, 0x67C0000 ;see if there are any errors - jnz SIS900_Poll_Error_Status - ;**************Check size of packet************* - and ecx, SIS900_DSIZE ;get packet size minus CRC - cmp cx, SIS900_CRC_SIZE - ;make sure packet contains data - jle SIS900_Poll_Error_Size - ;*******Copy Good Packet to receive buffer****** - sub cx, SIS900_CRC_SIZE ;dont want crc - mov word [eth_rx_data_len], cx ;save size of packet - ;**********Continue copying packet**************** - push ecx - ; first copy dword-wise, divide size by 4 - shr ecx, 2 - mov esi, [rxd+eax+8] ; set source - mov edi, Ether_buffer ; set destination - cld ; clear direction - rep movsd ; copy the dwords - pop ecx - and ecx, 3 ; - rep movsb - ;********Debug, tell user we have a good packet************* -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Pull_Packet_good - call sys_msg_board_str -end if - jmp SIS900_Poll_Cnt ; - ;*************Error occured let user know through debug window*********** -SIS900_Poll_Error_Status: -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Pull_Bad_Packet_Status - call sys_msg_board_str -end if - jmp SIS900_Poll_Cnt -SIS900_Poll_Error_Size: -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Pull_Bad_Packet_Size - call sys_msg_board_str -end if - ;*************Increment to next available descriptor************** -SIS900_Poll_Cnt: - ;Reset status, allow ethernet card access to descriptor - mov ecx, RX_BUFF_SZ - mov [rxd+eax+4], ecx ; - inc [cur_rx] ;get next descriptor - and [cur_rx],3 ;only 4 descriptors 0-3 - ;******Enable Receiver************ - mov ebp, [io_addr] ; Base Address - lea edx,[ebp+SIS900_cr] ; Command Register offset - in eax, dx ; Get current Command Register - or eax, SIS900_RxENA ;Enable Receive - out dx, eax - ret -;*************************************************************************** -; Function -; SIS900_transmit -; Description -; Transmits a packet of data via the ethernet card -; Pointer to 48 bit destination address in edi -; Type of packet in bx -; size of packet in ecx -; pointer to packet data in esi -; -; only one transmit descriptor is used -; -;*************************************************************************** -if defined SIS900_DEBUG -SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0 -SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0 -end if -SIS900_transmit: - mov ebp, [io_addr] ; Base Address - ;******** Stop the transmitter ******** - lea edx,[ebp+SIS900_cr] ; Command Register offset - in eax, dx ; Get current Command Register - or eax, SIS900_TxDIS ; Disable Transmitter - out dx, eax - ;*******load Transmit Descriptor Register ******* - lea edx,[ebp+SIS900_txdp] - mov eax, txd - out dx, eax - ;******* copy packet to descriptor******* - push esi - mov esi, edi ;copy destination addess - mov edi, txb - cld - movsd - movsw - mov esi, node_addr ;copy my mac address - movsd - movsw - mov [edi], bx ;copy packet type - add edi, 2 - pop esi ;restore pointer to source of packet - push ecx ;save packet size - shr ecx, 2 ;divide by 4, size in bytes send in dwords - rep movsd ;copy data to decriptor - pop ecx ;restore packet size - push ecx ;save packet size - and ecx, 3 ;last three bytes if not a multiple of 4 - rep movsb - ;**************set length tag************** - pop ecx ;restore packet size - add ecx, SIS900_ETH_HLEN ;add header to length - and ecx, SIS900_DSIZE ; - ;**************pad to minimum packet size **************not needed - ;cmp ecx, SIS900_ETH_ZLEN - ;jge SIS900_transmit_Size_Ok - ;push ecx - ;mov ebx, SIS900_ETH_ZLEN - ;sub ebx, ecx - ;mov ecx, ebx - ;rep movsb - ;pop ecx -SIS900_transmit_Size_Ok: - mov [txd+4], dword 0x80000000 ;card owns descriptor - or [txd+4], ecx ;set size of packet -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Transmit_Packet - call sys_msg_board_str -end if - ;***************restart the transmitter ******** - lea edx,[ebp+SIS900_cr] - in eax, dx ; Get current Command Register - or eax, SIS900_TxENA ; Enable Transmitter - out dx, eax - ;****make sure packet transmitted successfully**** -; mov esi,10 -; call delay_ms - mov eax, [txd+4] - and eax, 0x6200000 - jz SIS900_transmit_OK - ;**************Tell user there was an error through debug window -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Transmit_Packet_Err - call sys_msg_board_str -end if -SIS900_transmit_OK: - ;******** Disable interrupts by clearing the interrupt mask. ******** - lea edx,[ebp+SIS900_imr] ; Interupt Mask Register - xor eax, eax - out dx,eax - ret - -;*************************************************************************** -;* Function: Create_Mac_String -;* -;* Description: Converts the 48 bit value to a string for display -;* -;* String Format: XX:XX:XX:XX:XX:XX -;* -;* Arguments: node_addr is location of 48 bit MAC ID -;* -;* Returns: Prints string to general debug window -;* -;* -;done -;*************************************************************************** -if defined SIS900_DEBUG - -SIS900_Char_String db '0','1','2','3','4','5','6','7','8','9' - db 'A','B','C','D','E','F' -Mac_str_build: times 20 db 0 -Create_Mac_String: - pusha - xor ecx, ecx -Create_Mac_String_loop: - mov al,byte [edx+ecx];[node_addr+ecx] - push eax - shr eax, 4 - and eax, 0x0f - mov bl, byte [SIS900_Char_String+eax] - mov [Mac_str_build+ecx*3], bl - pop eax - and eax, 0x0f - mov bl, byte [SIS900_Char_String+eax] - mov [Mac_str_build+1+ecx*3], bl - cmp ecx, 5 - je Create_Mac_String_done - mov bl, ':' - mov [Mac_str_build+2+ecx*3], bl - inc ecx - jmp Create_Mac_String_loop -Create_Mac_String_done: ;Insert CR and Zero Terminate - mov [Mac_str_build+2+ecx*3],byte 13 - mov [Mac_str_build+3+ecx*3],byte 10 - mov [Mac_str_build+4+ecx*3],byte 0 - mov esi, Mac_str_build - call sys_msg_board_str ;Print String to message board - popa - ret -end if -;*************************************************************************** -;* Set device to be a busmaster in case BIOS neglected to do so. -;* Also adjust PCI latency timer to a reasonable value, 64. -;*************************************************************************** -SIS900_adjust_pci_device: - ;*******Get current setting************************ - mov al, 2 ;read a word - mov bh, [pci_dev] - mov ah, [pci_bus] - mov bl, 0x04 ;from command Register - call pci_read_reg - ;******see if its already set as bus master******** - mov bx, ax - and bx,5 - cmp bx,5 - je SIS900_adjust_pci_device_Latency - ;******Make card a bus master******* - mov cx, ax ;value to write - mov bh, [pci_dev] - mov al, 2 ;write a word - or cx,5 - mov ah, [pci_bus] - mov bl, 0x04 ;to command register - call pci_write_reg - ;******Check latency setting*********** -SIS900_adjust_pci_device_Latency: - ;*******Get current latency setting************************ - mov al, 1 ;read a byte - mov bh, [pci_dev] - mov ah, [pci_bus] - mov bl, 0x0D ;from Lantency Timer Register - call pci_read_reg - ;******see if its aat least 64 clocks******** - cmp ax,64 - jge SIS900_adjust_pci_device_Done - ;******Set latency to 32 clocks******* - mov cx, 64 ;value to write - mov bh, [pci_dev] - mov al, 1 ;write a byte - mov ah, [pci_bus] - mov bl, 0x0D ;to Lantency Timer Register - call pci_write_reg - ;******Check latency setting*********** -SIS900_adjust_pci_device_Done: - ret