forked from KolibriOS/kolibrios
removing useless files
git-svn-id: svn://kolibrios.org@263 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
3fd82557ce
commit
dd99e0d71a
@ -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
|
@ -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 (0<eax<=4096)
|
||||
;;Result:
|
||||
;; eax - linear address
|
||||
;; eax=0 - not enough memory
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
if used MEM_Alloc
|
||||
MEM_Alloc:
|
||||
;find chain
|
||||
test eax,eax
|
||||
jng MEM_Alloc_Wrong_Size
|
||||
cmp eax,4096
|
||||
jg MEM_Alloc_Wrong_Size
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
dec eax
|
||||
shr eax,4
|
||||
xor edx,edx
|
||||
MEM_Alloc_Find_Size:
|
||||
add edx,4
|
||||
shr eax,1
|
||||
jnz MEM_Alloc_Find_Size
|
||||
MEM_Alloc_Size_Found:
|
||||
mov ecx,edx
|
||||
shr ecx,2
|
||||
add ecx,4
|
||||
mov eax,1
|
||||
shl eax,cl
|
||||
mov esi,eax
|
||||
;esi - block size
|
||||
;edx - offset
|
||||
call MEM_Heap_Lock
|
||||
mov ecx,[MEM_heap_count]
|
||||
dec ecx
|
||||
shl ecx,4
|
||||
MEM_Alloc_Find_Heap:
|
||||
mov eax,[MEM_heap_block+ecx+.heap_linear_address]
|
||||
cmp dword [eax+edx],0
|
||||
jnz MEM_Alloc_Use_Existing
|
||||
sub ecx,16
|
||||
jns MEM_Alloc_Find_Heap
|
||||
;create new bucket page
|
||||
call MEM_Alloc_Page_Linear
|
||||
call MEM_Get_Heap_Number_Linear
|
||||
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
|
||||
mov [ecx+edx],eax
|
||||
lea ebx,[eax+4096]
|
||||
MEM_Alloc_List_loop:
|
||||
mov [eax],eax
|
||||
mov [eax+4],eax
|
||||
add [eax],esi
|
||||
sub [eax+4],esi
|
||||
add eax,esi
|
||||
cmp eax,ebx
|
||||
jnz MEM_Alloc_List_loop
|
||||
sub ebx,esi
|
||||
mov dword [ebx],0
|
||||
sub eax,4096
|
||||
mov dword [eax+4],0
|
||||
mov eax,ecx
|
||||
|
||||
MEM_Alloc_Use_Existing:
|
||||
mov ebx,eax
|
||||
mov eax,[eax+edx]
|
||||
mov ecx,[eax]
|
||||
mov [ebx+edx],ecx
|
||||
test ecx,ecx
|
||||
jz MEM_Alloc_Became_Empty
|
||||
mov dword [ecx+4],0
|
||||
MEM_Alloc_Became_Empty:
|
||||
mov ecx,eax
|
||||
sub ecx,ebx
|
||||
shr ecx,10
|
||||
and ecx,0xFFFFFFFC
|
||||
inc byte [ebx+.range_info+ecx+2]
|
||||
shr edx,2
|
||||
add edx,128
|
||||
dec edx
|
||||
mov [ebx+.range_info+ecx+3],dl
|
||||
|
||||
MEM_Alloc_ret:
|
||||
call MEM_Heap_UnLock
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
MEM_Alloc_Wrong_Size:
|
||||
xor eax,eax
|
||||
ret
|
||||
end if
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;MEM_Free
|
||||
;;Parameters:
|
||||
;; eax - linear address
|
||||
;;Result:
|
||||
;; eax=1 - success
|
||||
;; eax=0 - failed
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
if used MEM_Free
|
||||
MEM_Free:
|
||||
test eax,eax
|
||||
jz MEM_Free_Zero
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
call MEM_Heap_Lock
|
||||
call MEM_Get_Heap_Number_Linear
|
||||
test eax,eax
|
||||
jz MEM_Free_ret
|
||||
mov edx,eax
|
||||
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
|
||||
sub edx,ecx
|
||||
shr edx,10
|
||||
and edx,0xFFFFFFFC
|
||||
mov ebx,[ecx+.range_info+edx]
|
||||
mov esi,ebx
|
||||
shr esi,24
|
||||
sub esi,128
|
||||
mov edi,[ecx+4+4*esi]
|
||||
mov [eax],edi
|
||||
mov dword [eax+4],0
|
||||
test edi,edi
|
||||
jz MEM_Free_Empty_List
|
||||
mov [edi+4],eax
|
||||
MEM_Free_Empty_List:
|
||||
mov [ecx+4+4*esi],eax
|
||||
sub ebx,0x10000
|
||||
mov [ecx+.range_info+edx],ebx
|
||||
test ebx,0xFF0000
|
||||
jnz MEM_Free_ret
|
||||
;delete empty blocks on the page
|
||||
lea edx,[esi+5]
|
||||
and eax,0xFFFFF000
|
||||
mov edi,eax
|
||||
mov eax,1
|
||||
xchg ecx,edx
|
||||
shl eax,cl
|
||||
mov ecx,edx
|
||||
mov edx,eax
|
||||
;edx - size of block
|
||||
;edi - start of page
|
||||
mov eax,edi
|
||||
lea ebx,[eax+4096]
|
||||
MEM_Free_Block_loop:
|
||||
cmp dword [eax+4],0
|
||||
jnz MEM_Free_Block_Not_First
|
||||
mov ebp,dword [eax]
|
||||
mov [ecx+4+4*esi],ebp
|
||||
test ebp,ebp
|
||||
jz MEM_Free_Block_Last
|
||||
mov dword [ebp+4],0
|
||||
MEM_Free_Block_Last:
|
||||
jmp MEM_Free_Block_loop_end
|
||||
MEM_Free_Block_Not_First:
|
||||
mov ebp,dword [eax]
|
||||
push ebp
|
||||
mov ebp,dword [eax+4]
|
||||
pop dword [ebp]
|
||||
mov ebp,dword [eax]
|
||||
test ebp,ebp
|
||||
jz MEM_Free_Block_loop_end
|
||||
push dword [eax+4]
|
||||
pop dword [ebp+4]
|
||||
; jmp MEM_Free_Block_loop_end
|
||||
MEM_Free_Block_loop_end:
|
||||
add eax,edx
|
||||
cmp eax,ebx
|
||||
jnz MEM_Free_Block_loop
|
||||
mov eax,edi
|
||||
call MEM_Free_Page_Linear
|
||||
MEM_Free_ret:
|
||||
call MEM_Heap_UnLock
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
MEM_Free_Zero:
|
||||
inc eax
|
||||
ret
|
||||
end if
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;MEM_Add_Reference
|
||||
;; eax - physical address of page
|
||||
;;Result:
|
||||
;; eax=1 - success
|
||||
;; eax=0 - failed
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
if used MEM_Add_Reference
|
||||
MEM_Add_Reference:
|
||||
push ebx
|
||||
push ecx
|
||||
call MEM_Heap_Lock
|
||||
call MEM_Get_Heap_Number
|
||||
test eax,eax
|
||||
jz MEM_Add_Reference_ret
|
||||
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
|
||||
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
|
||||
shr eax,10
|
||||
and eax,0xFFFFFFFC
|
||||
test dword [ecx+eax+.range_info],0x80000000
|
||||
jnz MEM_Add_Reference_failed
|
||||
inc dword [ecx+eax+.range_info]
|
||||
MEM_Add_Reference_ret:
|
||||
call MEM_Heap_UnLock
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
MEM_Add_Reference_failed:
|
||||
xor eax,eax
|
||||
jmp MEM_Add_Reference_ret
|
||||
end if
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;MEM_Add_Reference_Linear
|
||||
;; eax - linear address of page
|
||||
;;Result:
|
||||
;; eax=1 - success
|
||||
;; eax=0 - failed
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
if used MEM_Add_Reference_Linear
|
||||
MEM_Add_Reference_Linear:
|
||||
push ebx
|
||||
push ecx
|
||||
call MEM_Heap_Lock
|
||||
call MEM_Get_Heap_Number_Linear
|
||||
test eax,eax
|
||||
jz MEM_Add_Reference_Linear_ret
|
||||
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
|
||||
sub eax,ecx
|
||||
shr eax,10
|
||||
and eax,0xFFFFFFFC
|
||||
test dword [ecx+eax+.range_info],0x80000000
|
||||
jnz MEM_Add_Reference_Linear_failed
|
||||
inc dword [ecx+eax+.range_info]
|
||||
mov eax,1
|
||||
MEM_Add_Reference_Linear_ret:
|
||||
call MEM_Heap_UnLock
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
MEM_Add_Reference_Linear_failed:
|
||||
xor eax,eax
|
||||
jmp MEM_Add_Reference_Linear_ret
|
||||
end if
|
||||
end if ;memmanager.inc
|
File diff suppressed because it is too large
Load Diff
@ -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
|
@ -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
|
||||
|
||||
.............
|
||||
.............
|
||||
|
@ -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
|
File diff suppressed because it is too large
Load Diff
@ -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
|
@ -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
|
@ -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
|
@ -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
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user