i8254x driver: Now in PE format!

git-svn-id: svn://kolibrios.org@4522 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2014-01-23 17:47:35 +00:00
parent 6471aac71c
commit 738e6b0db0
9 changed files with 382 additions and 147 deletions

View File

@ -138,7 +138,7 @@ FASM_PROGRAMS:=\
drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \ drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \
drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \ drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \
drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \ drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \
drivers/i8254x.obj:DRIVERS/I8254X.obj:$(REPOSITORY)/drivers/ethernet/i8254x.asm \ drivers/i8254x.sys:DRIVERS/I8254X.SYS:$(REPOSITORY)/drivers/ethernet/i8254x.asm \
drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \ drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \
drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \ drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \
drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \ drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \

View File

@ -138,7 +138,7 @@ FASM_PROGRAMS:=\
drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \ drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \
drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \ drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \
drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \ drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \
drivers/i8254x.obj:DRIVERS/I8254X.obj:$(REPOSITORY)/drivers/ethernet/i8254x.asm \ drivers/i8254x.sys:DRIVERS/I8254X.SYS:$(REPOSITORY)/drivers/ethernet/i8254x.asm \
drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \ drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \
drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \ drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \
drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \ drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \

View File

@ -138,7 +138,7 @@ FASM_PROGRAMS:=\
drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \ drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \
drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \ drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \
drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \ drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \
drivers/i8254x.obj:DRIVERS/I8254X.obj:$(REPOSITORY)/drivers/ethernet/i8254x.asm \ drivers/i8254x.sys:DRIVERS/I8254X.SYS:$(REPOSITORY)/drivers/ethernet/i8254x.asm \
drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \ drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \
drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \ drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \
drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \ drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \

View File

@ -139,7 +139,7 @@ FASM_PROGRAMS:=\
drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \ drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \
drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \ drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \
drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \ drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \
drivers/i8254x.obj:DRIVERS/I8254X.obj:$(REPOSITORY)/drivers/ethernet/i8254x.asm \ drivers/i8254x.sys:DRIVERS/I8254X.SYS:$(REPOSITORY)/drivers/ethernet/i8254x.asm \
drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \ drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \
drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \ drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \
drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \ drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \

View File

@ -138,7 +138,7 @@ FASM_PROGRAMS:=\
drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \ drivers/3c59x.obj:DRIVERS/3C59X.obj:$(REPOSITORY)/drivers/ethernet/3c59x.asm \
drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \ drivers/dec21x4x.obj:DRIVERS/DEC21X4X.obj:$(REPOSITORY)/drivers/ethernet/dec21x4x.asm \
drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \ drivers/forcedeth.obj:DRIVERS/FORCEDETH.obj:$(REPOSITORY)/drivers/ethernet/forcedeth.asm \
drivers/i8254x.obj:DRIVERS/I8254X.obj:$(REPOSITORY)/drivers/ethernet/i8254x.asm \ drivers/i8254x.sys:DRIVERS/I8254X.SYS:$(REPOSITORY)/drivers/ethernet/i8254x.asm \
drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \ drivers/i8255x.obj:DRIVERS/I8255X.obj:$(REPOSITORY)/drivers/ethernet/i8255x.asm \
drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \ drivers/mtd80x.obj:DRIVERS/MTD80X.obj:$(REPOSITORY)/drivers/ethernet/mtd80x.asm \
drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \ drivers/pcnet32.obj:DRIVERS/PCNET32.obj:$(REPOSITORY)/drivers/ethernet/pcnet32.asm \

View File

@ -14,14 +14,15 @@
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format MS COFF format PE DLL native
entry START
API_VERSION = 0x01000100 CURRENT_API = 0x0200
DRIVER_VERSION = 5 COMPATIBLE_API = 0x0100
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API
MAX_DEVICES = 16 MAX_DEVICES = 16
DEBUG = 1
__DEBUG__ = 1 __DEBUG__ = 1
__DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only __DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only
@ -30,18 +31,13 @@ format MS COFF
RX_RING_SIZE = 8 ; Must be a power of 2, and minimum 8 RX_RING_SIZE = 8 ; Must be a power of 2, and minimum 8
TX_RING_SIZE = 8 ; Must be a power of 2, and minimum 8 TX_RING_SIZE = 8 ; Must be a power of 2, and minimum 8
section '.flat' readable writable executable
include '../proc32.inc'
include '../struct.inc' include '../struct.inc'
include '../macros.inc' include '../macros.inc'
include '../proc32.inc'
include '../imports.inc'
include '../fdo.inc' include '../fdo.inc'
include '../netdrv.inc' include '../netdrv_pe.inc'
public START
public service_proc
public version
; Register list ; Register list
REG_CTRL = 0x0000 ; Control Register REG_CTRL = 0x0000 ; Control Register
@ -270,32 +266,26 @@ RXDESC_IXSM = 0x00000004 ; Ignore cksum indication
RXDESC_EOP = 0x00000002 ; End Of Packet RXDESC_EOP = 0x00000002 ; End Of Packet
RXDESC_DD = 0x00000001 ; Descriptor Done RXDESC_DD = 0x00000001 ; Descriptor Done
virtual at ebx struct device ETH_DEVICE
device:
ETH_DEVICE
.mmio_addr dd ? mmio_addr dd ?
.pci_bus dd ? pci_bus dd ?
.pci_dev dd ? pci_dev dd ?
.irq_line db ? irq_line db ?
.cur_rx dd ? cur_rx dd ?
.cur_tx dd ? cur_tx dd ?
.last_tx dd ? last_tx dd ?
rb 0x100 - (($ - device) and 0xff) ; align 256 rb 0x100 - ($ and 0xff) ; align 256
.rx_desc rb RX_RING_SIZE*sizeof.RDESC*2
rb 0x100 - (($ - device) and 0xff) ; align 256 rx_desc rb RX_RING_SIZE*sizeof.RDESC*2
.tx_desc rb TX_RING_SIZE*sizeof.TDESC*2
sizeof.device_struct = $ - device rb 0x100 - ($ and 0xff) ; align 256
end virtual tx_desc rb TX_RING_SIZE*sizeof.TDESC*2
section '.flat' code readable align 16
ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
@ -304,28 +294,22 @@ section '.flat' code readable align 16
;; (standard driver proc) ;; ;; (standard driver proc) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4 proc START stdcall, reason:dword, cmdline:dword
proc START stdcall, state:dword
cmp [state], 1 cmp [reason], DRV_ENTRY
jne .exit jne .fail
.entry:
DEBUGF 1,"Loading driver\n" DEBUGF 1,"Loading driver\n"
stdcall RegService, my_service, service_proc invoke RegService, my_service, service_proc
ret ret
.fail: .fail:
.exit:
xor eax, eax xor eax, eax
ret ret
endp endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; proc SERVICE_PROC ;; ;; proc SERVICE_PROC ;;
@ -347,7 +331,7 @@ proc service_proc stdcall, ioctl:dword
cmp [edx + IOCTL.out_size], 4 cmp [edx + IOCTL.out_size], 4
jb .fail jb .fail
mov eax, [edx + IOCTL.output] mov eax, [edx + IOCTL.output]
mov [eax], dword API_VERSION mov dword[eax], API_VERSION
xor eax, eax xor eax, eax
ret ret
@ -375,9 +359,9 @@ proc service_proc stdcall, ioctl:dword
mov ax, [eax+1] ; mov ax, [eax+1] ;
.nextdevice: .nextdevice:
mov ebx, [esi] mov ebx, [esi]
cmp al, byte [device.pci_bus] cmp al, byte[ebx + device.pci_bus]
jne .next jne .next
cmp ah, byte [device.pci_dev] cmp ah, byte[ebx + device.pci_dev]
je .find_devicenum ; Device is already loaded, let's find it's device number je .find_devicenum ; Device is already loaded, let's find it's device number
.next: .next:
add esi, 4 add esi, 4
@ -389,41 +373,39 @@ proc service_proc stdcall, ioctl:dword
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card
jae .fail jae .fail
allocate_and_clear ebx, sizeof.device_struct, .fail ; Allocate the buffer for device structure allocate_and_clear ebx, sizeof.device, .fail ; Allocate the buffer for device structure
; Fill in the direct call addresses into the struct ; Fill in the direct call addresses into the struct
mov [device.reset], reset mov [ebx + device.reset], reset
mov [device.transmit], transmit mov [ebx + device.transmit], transmit
mov [device.unload], unload mov [ebx + device.unload], unload
mov [device.name], my_service mov [ebx + device.name], my_service
; save the pci bus and device numbers ; save the pci bus and device numbers
mov eax, [edx + IOCTL.input] mov eax, [edx + IOCTL.input]
movzx ecx, byte [eax+1] movzx ecx, byte [eax+1]
mov [device.pci_bus], ecx mov [ebx + device.pci_bus], ecx
movzx ecx, byte [eax+2] movzx ecx, byte [eax+2]
mov [device.pci_dev], ecx mov [ebx + device.pci_dev], ecx
; Now, it's time to find the base mmio addres of the PCI device ; Now, it's time to find the base mmio addres of the PCI device
PCI_find_mmio32 stdcall PCI_find_mmio32, [ebx + device.pci_bus], [ebx + device.pci_dev] ; returns in eax
; Create virtual mapping of the physical memory ; Create virtual mapping of the physical memory
push 1Bh ; PG_SW+PG_NOCACHE invoke MapIoMem, eax, 10000h, PG_SW+PG_NOCACHE
push 10000h ; size of the map mov [ebx + device.mmio_addr], eax
push eax
call MapIoMem
mov [device.mmio_addr], eax
; We've found the mmio address, find IRQ now ; We've found the mmio address, find IRQ now
PCI_find_irq invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
mov [ebx + device.irq_line], al
DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.mmio_addr]:8 [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.mmio_addr]:8
; Ok, the eth_device structure is ready, let's probe the device ; Ok, the eth_device structure is ready, let's probe the device
call probe ; this function will output in eax call probe ; this function will output in eax
@ -436,9 +418,8 @@ proc service_proc stdcall, ioctl:dword
call start_i8254x call start_i8254x
mov [device.type], NET_TYPE_ETH mov [ebx + device.type], NET_TYPE_ETH
call NetRegDev invoke NetRegDev
cmp eax, -1 cmp eax, -1
je .destroy je .destroy
@ -448,7 +429,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum: .find_devicenum:
DEBUGF 1,"Trying to find device number of already registered device\n" DEBUGF 1,"Trying to find device number of already registered device\n"
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx invoke NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi ; into a device number in edi
mov eax, edi ; Application wants it in eax instead mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax DEBUGF 1,"Kernel says: %u\n", eax
@ -460,7 +441,7 @@ proc service_proc stdcall, ioctl:dword
; todo: reset device into virgin state ; todo: reset device into virgin state
.err: .err:
stdcall KernelFree, ebx invoke KernelFree, ebx
.fail: .fail:
or eax, -1 or eax, -1
@ -503,15 +484,18 @@ probe:
DEBUGF 1,"Probe\n" DEBUGF 1,"Probe\n"
PCI_make_bus_master ; Make the device a bus master
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
or al, PCI_CMD_MASTER
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
; TODO: validate the device ; TODO: validate the device
call read_mac call read_mac
movzx eax, [device.irq_line] movzx eax, [ebx + device.irq_line]
DEBUGF 1,"Attaching int handler to irq %x\n", eax:1 DEBUGF 1,"Attaching int handler to irq %x\n", eax:1
stdcall AttachIntHandler, eax, int_handler, dword 0 invoke AttachIntHandler, eax, int_handler, ebx
test eax, eax test eax, eax
jnz @f jnz @f
DEBUGF 2,"Could not attach int handler!\n" DEBUGF 2,"Could not attach int handler!\n"
@ -523,14 +507,14 @@ probe:
reset_dontstart: reset_dontstart:
DEBUGF 1,"Reset\n" DEBUGF 1,"Reset\n"
mov esi, [device.mmio_addr] mov esi, [ebx + device.mmio_addr]
or dword[esi + REG_CTRL], CTRL_RST ; reset device or dword[esi + REG_CTRL], CTRL_RST ; reset device
.loop: .loop:
push esi push esi
xor esi, esi xor esi, esi
inc esi inc esi
call Sleep invoke Sleep
pop esi pop esi
test dword[esi + REG_CTRL], CTRL_RST test dword[esi + REG_CTRL], CTRL_RST
jnz .loop jnz .loop
@ -567,17 +551,17 @@ reset_dontstart:
align 4 align 4
init_rx: init_rx:
lea edi, [device.rx_desc] lea edi, [ebx + device.rx_desc]
mov ecx, RX_RING_SIZE mov ecx, RX_RING_SIZE
.loop: .loop:
push ecx push ecx
push edi push edi
stdcall KernelAlloc, MAX_PKT_SIZE invoke KernelAlloc, MAX_PKT_SIZE
DEBUGF 1,"RX buffer: 0x%x\n", eax DEBUGF 1,"RX buffer: 0x%x\n", eax
pop edi pop edi
mov dword[edi + RX_RING_SIZE*sizeof.RDESC], eax mov dword[edi + RX_RING_SIZE*sizeof.RDESC], eax
push edi push edi
GetRealAddr invoke GetPhysAddr
pop edi pop edi
mov [edi + RDESC.addr_l], eax mov [edi + RDESC.addr_l], eax
mov [edi + RDESC.addr_h], 0 mov [edi + RDESC.addr_h], 0
@ -588,10 +572,10 @@ init_rx:
dec ecx dec ecx
jnz .loop jnz .loop
mov [device.cur_rx], 0 mov [ebx + device.cur_rx], 0
lea eax, [device.rx_desc] lea eax, [ebx + device.rx_desc]
GetRealAddr invoke GetPhysAddr
mov dword[esi + REG_RDBAL], eax ; Receive Descriptor Base Address Low mov dword[esi + REG_RDBAL], eax ; Receive Descriptor Base Address Low
mov dword[esi + REG_RDBAH], 0 ; Receive Descriptor Base Address High mov dword[esi + REG_RDBAH], 0 ; Receive Descriptor Base Address High
mov dword[esi + REG_RDLEN], RX_RING_SIZE*sizeof.RDESC ; Receive Descriptor Length mov dword[esi + REG_RDLEN], RX_RING_SIZE*sizeof.RDESC ; Receive Descriptor Length
@ -607,7 +591,7 @@ init_rx:
align 4 align 4
init_tx: init_tx:
lea edi, [device.tx_desc] lea edi, [ebx + device.tx_desc]
mov ecx, TX_RING_SIZE mov ecx, TX_RING_SIZE
.loop: .loop:
mov [edi + TDESC.addr_l], eax mov [edi + TDESC.addr_l], eax
@ -618,11 +602,11 @@ init_tx:
dec ecx dec ecx
jnz .loop jnz .loop
mov [device.cur_tx], 0 mov [ebx + device.cur_tx], 0
mov [device.last_tx], 0 mov [ebx + device.last_tx], 0
lea eax, [device.tx_desc] lea eax, [ebx + device.tx_desc]
GetRealAddr invoke GetPhysAddr
mov dword[esi + REG_TDBAL], eax ; Transmit Descriptor Base Address Low mov dword[esi + REG_TDBAL], eax ; Transmit Descriptor Base Address Low
mov dword[esi + REG_TDBAH], 0 ; Transmit Descriptor Base Address High mov dword[esi + REG_TDBAH], 0 ; Transmit Descriptor Base Address High
mov dword[esi + REG_TDLEN], RX_RING_SIZE*sizeof.TDESC ; Transmit Descriptor Length mov dword[esi + REG_TDLEN], RX_RING_SIZE*sizeof.TDESC ; Transmit Descriptor Length
@ -640,7 +624,7 @@ reset:
start_i8254x: start_i8254x:
mov esi, [device.mmio_addr] mov esi, [ebx + device.mmio_addr]
or dword[esi + REG_RCTL], RCTL_EN ; Enable the receiver or dword[esi + REG_RCTL], RCTL_EN ; Enable the receiver
xor eax, eax xor eax, eax
@ -651,8 +635,8 @@ start_i8254x:
mov dword[esi + REG_IMS], 0x1F6DC ; Enable interrupt types mov dword[esi + REG_IMS], 0x1F6DC ; Enable interrupt types
mov eax, [esi + REG_ICR] ; Clear pending interrupts mov eax, [esi + REG_ICR] ; Clear pending interrupts
mov [device.mtu], 1514 mov [ebx + device.mtu], 1514
mov [device.state], ETH_LINK_UNKOWN ; Set link state to unknown mov [ebx + device.state], ETH_LINK_UNKOWN ; Set link state to unknown
xor eax, eax xor eax, eax
ret ret
@ -665,15 +649,15 @@ read_mac:
DEBUGF 1,"Read MAC\n" DEBUGF 1,"Read MAC\n"
mov esi, [device.mmio_addr] mov esi, [ebx + device.mmio_addr]
mov eax, [esi+0x5400] ; RAL mov eax, [esi+0x5400] ; RAL
test eax, eax test eax, eax
jz .try_eeprom jz .try_eeprom
mov dword[device.mac], eax mov dword[ebx + device.mac], eax
mov eax, [esi+0x5404] ; RAH mov eax, [esi+0x5404] ; RAH
mov word[device.mac+4], ax mov word[ebx + device.mac+4], ax
jmp .mac_ok jmp .mac_ok
@ -681,21 +665,22 @@ read_mac:
mov dword[esi+0x14], 0x00000001 mov dword[esi+0x14], 0x00000001
mov eax, [esi+0x14] mov eax, [esi+0x14]
shr eax, 16 shr eax, 16
mov word[device.mac], ax mov word[ebx + device.mac], ax
mov dword[esi+0x14], 0x00000101 mov dword[esi+0x14], 0x00000101
mov eax, [esi+0x14] mov eax, [esi+0x14]
shr eax, 16 shr eax, 16
mov word[device.mac+2], ax mov word[ebx + device.mac+2], ax
mov dword[esi+0x14], 0x00000201 mov dword[esi+0x14], 0x00000201
mov eax, [esi+0x14] mov eax, [esi+0x14]
shr eax, 16 shr eax, 16
mov word[device.mac+4], ax mov word[ebx + device.mac+4], ax
.mac_ok: .mac_ok:
DEBUGF 1,"MAC = %x-%x-%x-%x-%x-%x\n",\ DEBUGF 1,"MAC = %x-%x-%x-%x-%x-%x\n",\
[device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
ret ret
@ -726,12 +711,12 @@ proc transmit stdcall bufferptr, buffersize
jb .fail jb .fail
; Program the descriptor (use legacy mode) ; Program the descriptor (use legacy mode)
mov edi, [device.cur_tx] mov edi, [ebx + device.cur_tx]
DEBUGF 1, "Using TX desc: %u\n", edi DEBUGF 1, "Using TX desc: %u\n", edi
shl edi, 4 ; edi = edi * sizeof.TDESC shl edi, 4 ; edi = edi * sizeof.TDESC
lea edi, [device.tx_desc + edi] lea edi, [ebx + device.tx_desc + edi]
mov dword[edi + TX_RING_SIZE*sizeof.TDESC], eax ; Store the data location (for driver) mov dword[edi + TX_RING_SIZE*sizeof.TDESC], eax ; Store the data location (for driver)
GetRealAddr invoke GetPhysAddr
mov [edi + TDESC.addr_l], eax ; Data location (for hardware) mov [edi + TDESC.addr_l], eax ; Data location (for hardware)
mov [edi + TDESC.addr_h], 0 mov [edi + TDESC.addr_h], 0
@ -740,19 +725,19 @@ proc transmit stdcall bufferptr, buffersize
mov [edi + TDESC.length_cso_cmd], ecx mov [edi + TDESC.length_cso_cmd], ecx
mov [edi + TDESC.status], 0 mov [edi + TDESC.status], 0
; Tell i8254x wich descriptor(s) we programmed ; Tell i8254x wich descriptor(s) we programmed, by moving the tail
mov edi, [device.mmio_addr] mov edi, [ebx + device.mmio_addr]
mov eax, [device.cur_tx] mov eax, [ebx + device.cur_tx]
inc eax inc eax
and eax, TX_RING_SIZE-1 and eax, TX_RING_SIZE-1
mov [device.cur_tx], eax mov [ebx + device.cur_tx], eax
mov dword[edi + REG_TDT], eax ; TDT - Transmit Descriptor Tail mov dword[edi + REG_TDT], eax ; TDT - Transmit Descriptor Tail
; Update stats ; Update stats
inc [device.packets_tx] inc [ebx + device.packets_tx]
mov eax, [buffersize] mov eax, [buffersize]
add dword[device.bytes_tx], eax add dword[ebx + device.bytes_tx], eax
adc dword[device.bytes_tx + 4], 0 adc dword[ebx + device.bytes_tx + 4], 0
popf popf
xor eax, eax xor eax, eax
@ -760,7 +745,7 @@ proc transmit stdcall bufferptr, buffersize
.fail: .fail:
DEBUGF 2,"Send failed\n" DEBUGF 2,"Send failed\n"
stdcall KernelFree, [bufferptr] invoke KernelFree, [bufferptr]
popf popf
or eax, -1 or eax, -1
ret ret
@ -789,8 +774,7 @@ int_handler:
mov esi, device_list mov esi, device_list
.nextdevice: .nextdevice:
mov ebx, [esi] mov ebx, [esi]
mov edi, [ebx + device.mmio_addr]
mov edi, [device.mmio_addr]
mov eax, [edi + REG_ICR] mov eax, [edi + REG_ICR]
test eax, eax test eax, eax
jnz .got_it jnz .got_it
@ -805,7 +789,6 @@ int_handler:
ret ret
.got_it: .got_it:
DEBUGF 1,"Device: %x Status: %x\n", ebx, eax DEBUGF 1,"Device: %x Status: %x\n", ebx, eax
;--------- ;---------
@ -818,9 +801,9 @@ int_handler:
.retaddr: .retaddr:
pop ebx eax pop ebx eax
; Get last descriptor addr ; Get last descriptor addr
mov esi, [device.cur_rx] mov esi, [ebx + device.cur_rx]
shl esi, 4 ; esi = esi * sizeof.RDESC shl esi, 4 ; esi = esi * sizeof.RDESC
lea esi, [device.rx_desc + esi] lea esi, [ebx + device.rx_desc + esi]
cmp byte[esi + RDESC.status_h], 0 ; Check status field cmp byte[esi + RDESC.status_h], 0 ; Check status field
je .no_rx je .no_rx
@ -832,30 +815,30 @@ int_handler:
push dword[esi + RX_RING_SIZE*sizeof.RDESC] ; Get packet pointer push dword[esi + RX_RING_SIZE*sizeof.RDESC] ; Get packet pointer
; Update stats ; Update stats
add dword[device.bytes_rx], ecx add dword[ebx + device.bytes_rx], ecx
adc dword[device.bytes_rx + 4], 0 adc dword[ebx + device.bytes_rx + 4], 0
inc [device.packets_rx] inc [ebx + device.packets_rx]
; Allocate new descriptor ; Allocate new descriptor
push esi push esi
stdcall KernelAlloc, MAX_PKT_SIZE invoke KernelAlloc, MAX_PKT_SIZE
pop esi pop esi
mov dword[esi + RX_RING_SIZE*sizeof.RDESC], eax mov dword[esi + RX_RING_SIZE*sizeof.RDESC], eax
GetRealAddr invoke GetPhysAddr
mov [esi + RDESC.addr_l], eax mov [esi + RDESC.addr_l], eax
mov [esi + RDESC.status_l], 0 mov [esi + RDESC.status_l], 0
mov [esi + RDESC.status_h], 0 mov [esi + RDESC.status_h], 0
; Move the receive descriptor tail ; Move the receive descriptor tail
mov esi, [device.mmio_addr] mov esi, [ebx + device.mmio_addr]
mov eax, [device.cur_rx] mov eax, [ebx + device.cur_rx]
mov [esi + REG_RDT], eax mov [esi + REG_RDT], eax
; Move to next rx desc ; Move to next rx desc
inc [device.cur_rx] inc [ebx + device.cur_rx]
and [device.cur_rx], RX_RING_SIZE-1 and [ebx + device.cur_rx], RX_RING_SIZE-1
jmp Eth_input jmp [Eth_input]
.no_rx: .no_rx:
;-------------- ;--------------
@ -877,9 +860,9 @@ int_handler:
DEBUGF 1,"Transmit done\n" DEBUGF 1,"Transmit done\n"
.txdesc_loop: .txdesc_loop:
mov edi, [device.last_tx] mov edi, [ebx + device.last_tx]
shl edi, 4 ; edi = edi * sizeof.TDESC shl edi, 4 ; edi = edi * sizeof.TDESC
lea edi, [device.tx_desc + edi] lea edi, [ebx + device.tx_desc + edi]
test [edi + TDESC.status], TXDESC_DD ; Descriptor done? test [edi + TDESC.status], TXDESC_DD ; Descriptor done?
jz .no_tx jz .no_tx
cmp dword[edi + TX_RING_SIZE*sizeof.TDESC], 0 cmp dword[edi + TX_RING_SIZE*sizeof.TDESC], 0
@ -890,18 +873,17 @@ int_handler:
push ebx push ebx
push dword[edi + TX_RING_SIZE*sizeof.TDESC] push dword[edi + TX_RING_SIZE*sizeof.TDESC]
mov dword[edi + TX_RING_SIZE*sizeof.TDESC], 0 mov dword[edi + TX_RING_SIZE*sizeof.TDESC], 0
call KernelFree invoke KernelFree
pop ebx pop ebx
inc [device.last_tx] inc [ebx + device.last_tx]
and [device.last_tx], TX_RING_SIZE-1 and [ebx + device.last_tx], TX_RING_SIZE-1
jmp .txdesc_loop jmp .txdesc_loop
.no_tx: .no_tx:
pop edi esi ebx pop edi esi ebx
xor eax, eax xor eax, eax
inc eax inc eax
ret ret
@ -909,15 +891,14 @@ int_handler:
; End of code ; End of code
section '.data' data readable writable align 16 section '.data' readable writable
include '../peimport.inc'
include_debug_strings
my_service db 'I8254X', 0 ; max 16 chars include zero
align 4 align 4
devices dd 0 devices dd 0
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
my_service db 'I8254X',0 ; max 16 chars include zero
include_debug_strings ; All data wich FDO uses will be included here
device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling

130
drivers/netdrv_pe.inc Normal file
View File

@ -0,0 +1,130 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This macro will prepend driver name to all debug output through DEBUGF macro
; The driver name is taken from my_service label
if defined my_service
macro DEBUGF _level,_format, [args] {
common DEBUGF _level, "%s: " # _format, my_service, args
}
end if
include 'pci_pe.inc'
include 'mii.inc'
; Kernel variables
PAGESIZE = 4096
; Network driver types
NET_TYPE_ETH = 1
NET_TYPE_SLIP = 2
; Link state
ETH_LINK_DOWN = 0 ; Link is down
ETH_LINK_UNKOWN = 1b ; There could be an active link
ETH_LINK_FD = 10b ; full duplex flag
ETH_LINK_10M = 100b ; 10 mbit
ETH_LINK_100M = 1000b ; 100 mbit
ETH_LINK_1G = 10000b ; gigabit
; Macro to easily set i/o addresses to access device.
; In the beginning of a procedure (or ofter edx may have been destroyed),
; always use set_io with offset 0 to reset the variables.
LAST_IO = 0
macro set_io baseaddr, offset {
if offset = 0
mov edx, baseaddr
else if offset = LAST_IO
else
add edx, offset - LAST_IO
end if
LAST_IO = offset
}
; Macro to allocate a contiguous buffer in memory
; And initialise it to all zeros
; This macro will destroy eax, ecx and edi !
macro allocate_and_clear dest, size, err {
; We need to allocate at least 8 pages, if we want a contiguous area in ram
push edx
if (size < 8*4096) & (size > 4096)
invoke KernelAlloc, 8*4096
else
invoke KernelAlloc, size
end if
pop edx
test eax, eax
jz err
mov dest, eax
mov edi, eax ; look at last part of code!
; Release the unused pages (if any)
if (size < 8*4096) & (size > 4096)
add eax, (size/4096+1)*4096
mov ecx, 8-(size/4096+1)
push edx
invoke ReleasePages
pop edx
end if
; Clear the allocated buffer
mov ecx, size/4 ; divide by 4 because of DWORD
xor eax, eax
rep stosd
if (size - size/4*4)
mov ecx, size - size/4*4
rep stosb
end if
}
struct NET_DEVICE
type dd ? ; Type field
mtu dd ? ; Maximal Transmission Unit
name dd ? ; Ptr to 0 terminated string
unload dd ? ; Ptrs to driver functions
reset dd ? ;
transmit dd ? ;
bytes_tx dq ? ; Statistics, updated by the driver
bytes_rx dq ? ;
packets_tx dd ? ;
packets_rx dd ? ;
state dd ? ; link state (0 = no link)
hwacc dd ? ; bitmask stating enabled HW accelerations
ends
struct ETH_DEVICE NET_DEVICE
mac dp ?
dw ? ; qword alignment
ends

117
drivers/pci_pe.inc Normal file
View File

@ -0,0 +1,117 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
struct PCI_header
vendor_id dw ?
device_id dw ?
command dw ?
status dw ?
revision_id db ?
prog_if db ?
subclass db ?
class_code db ?
cache_line_size db ?
latency_timer db ?
header_type db ?
bist db ?
ends
struct PCI_header00 PCI_header
base_addr_0 dd ?
base_addr_1 dd ?
base_addr_2 dd ?
base_addr_3 dd ?
base_addr_4 dd ?
base_addr_5 dd ?
cardbus_cis_ptr dd ?
subsys_vendor dw ?
subsys_id dw ?
exp_rom_addr dd ?
cap_ptr db ?
reserved rb 7
interrupt_line db ?
interrupt_pin db ?
min_grant db ?
max_latency db ?
ends
; Base address bits
PCI_BASE_ADDRESS_SPACE_IO = 0x01
PCI_BASE_ADDRESS_IO_MASK = 0xFFFFFFFC
PCI_BASE_ADDRESS_MEM_MASK = 0xFFFFFFF0
; command bits
PCI_CMD_PIO = 1 ; bit0: io space control
PCI_CMD_MMIO = 2 ; bit1: memory space control
PCI_CMD_MASTER = 4 ; bit2: device acts as a PCI master
if used PCI_find_io
proc PCI_find_io stdcall bus, dev
push esi
xor eax, eax
mov esi, PCI_BASE_ADDRESS_0
.check:
invoke PciRead32, [bus], [dev], esi
test eax, PCI_BASE_ADDRESS_IO_MASK
jz .inc
test eax, PCI_BASE_ADDRESS_SPACE_IO
jz .inc
and eax, PCI_BASE_ADDRESS_IO_MASK
pop esi
ret
.inc:
add esi, 4
cmp esi, PCI_BASE_ADDRESS_5
jbe .check
pop esi
xor eax, eax
ret
endp
end if
if used PCI_find_mmio32
proc PCI_find_mmio32 stdcall bus, dev
push esi
mov esi, PCI_header00.base_addr_0
.check:
invoke PciRead32, [bus], [dev], esi
test eax, PCI_BASE_ADDRESS_SPACE_IO ; mmio address?
jnz .inc
test eax, 100b ; 64 bit?
jnz .inc
and eax, not 1111b
pop esi
ret
.inc:
add esi, 4
cmp esi, PCI_header00.base_addr_5
jbe .check
xor eax, eax
pop esi
ret
endp
end if

View File

@ -149,6 +149,13 @@ import core,\
\ \
TimerHS,\ TimerHS,\
CancelTimerHS,\ CancelTimerHS,\
\
NetRegDev,\
NetUnRegDev,\
NetPtrToNum,\
NetLinkChanged,\
Eth_input,\
IPv4_input,\
\ \
GetPCIList GetPCIList
end data end data