Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 29 additions & 18 deletions src/drivers/net/virtio-net.asm
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ virtio_net_init_reset_wait:
mov eax, [rsi+VIRTIO_DEVICE_FEATURE]
mov eax, 1
mov [rsi+VIRTIO_DRIVER_FEATURE_SELECT], eax
; TODO - Check into how LEGACY affects the 12-byte header
mov eax, 1 ; Feature bits 63:32 - LEGACY (32)
mov [rsi+VIRTIO_DRIVER_FEATURE], eax

Expand All @@ -297,18 +298,19 @@ virtio_net_init_reset_wait:
xor eax, eax
mov [rsi+VIRTIO_QUEUE_SELECT], ax
mov ax, [rsi+VIRTIO_QUEUE_SIZE] ; Return the size of the queue
mov ecx, eax ; Store queue size in ECX
mov rax, [r8+nt_rx_desc]
mov [r8+0x7E], ax ; Store receive queue size in net_table
mov ecx, eax ; Store receive queue size in ECX
mov rax, [r8+nt_rx_desc] ; Set address of Descriptor ring
mov [rsi+VIRTIO_QUEUE_DESC], eax
rol rax, 32
mov [rsi+VIRTIO_QUEUE_DESC+8], eax
rol rax, 32
add rax, 4096
add rax, 4096 ; Set address of Available ring
mov [rsi+VIRTIO_QUEUE_DRIVER], eax
rol rax, 32
mov [rsi+VIRTIO_QUEUE_DRIVER+8], eax
rol rax, 32
add rax, 4096
add rax, 4096 ; Set address of Used ring
mov [rsi+VIRTIO_QUEUE_DEVICE], eax
rol rax, 32
mov [rsi+VIRTIO_QUEUE_DEVICE+8], eax
Expand All @@ -323,18 +325,19 @@ virtio_net_init_reset_wait:
mov eax, 1
mov [rsi+VIRTIO_QUEUE_SELECT], ax
mov ax, [rsi+VIRTIO_QUEUE_SIZE] ; Return the size of the queue
mov ecx, eax ; Store queue size in ECX
mov rax, [r8+nt_tx_desc]
mov [r8+0x7C], ax ; Store transmit queue size in net_table
mov ecx, eax ; Store transmit queue size in ECX
mov rax, [r8+nt_tx_desc] ; Set address of Descriptor ring
mov [rsi+VIRTIO_QUEUE_DESC], eax
rol rax, 32
mov [rsi+VIRTIO_QUEUE_DESC+8], eax
rol rax, 32
add rax, 4096
add rax, 4096 ; Set address of Available ring
mov [rsi+VIRTIO_QUEUE_DRIVER], eax
rol rax, 32
mov [rsi+VIRTIO_QUEUE_DRIVER+8], eax
rol rax, 32
add rax, 4096
add rax, 4096 ; Set address of Used ring
mov [rsi+VIRTIO_QUEUE_DEVICE], eax
rol rax, 32
mov [rsi+VIRTIO_QUEUE_DEVICE+8], eax
Expand All @@ -356,10 +359,12 @@ virtio_net_init_pop_tx_d:
; Populate RX Descriptor Table Entries
xor ecx, ecx
mov rdi, [r8+nt_rx_desc]
mov rbx, [os_PacketBase]
virtio_net_init_pop_rx_d:
mov rax, os_PacketBuffers ; 64-bit Address
mov rax, rbx ; 64-bit Address
add rbx, 2048
stosq
mov eax, 1536 ; 32-bit Length
mov eax, 2048 ; 32-bit Length
stosd
mov ax, VIRTQ_DESC_F_WRITE
stosw ; 16-bit Flags
Expand All @@ -368,13 +373,15 @@ virtio_net_init_pop_rx_d:
stosw ; 16-bit Next
cmp cl, 0
jne virtio_net_init_pop_rx_d
mov [os_PacketBase], rbx

; Populate RX Available Ring Entries
mov rdi, [r8+nt_rx_desc]
add rdi, 0x1000
xor eax, eax
stosw ; 16-bit flags
mov ax, 128
mov ax, [r8+0x7C] ; Gather queue size
dec ax ; Mark all descriptors (minus 1) as available
stosw ; 16-bit index
xor eax, eax
virtio_net_init_pop_rx_a:
Expand Down Expand Up @@ -509,31 +516,35 @@ net_virtio_transmit_wait:
net_virtio_poll:
push r8
push rsi
push rbx
push rax

; Gather info from driver info
mov r8, [rdx+nt_rx_desc]
mov bx, [rdx+0x7E] ; Receive queue size
dec bx ; Ex: 0x100 becomes 0xFF

; Check if the Used Ring Index has changed from the last known value
mov rdi, r8
add rdi, 0x2000 ; Offset to Used Ring
xor eax, eax
mov ax, [rdi+2] ; Load Used Ring Index
and ax, bx
cmp ax, [rdx+0x78] ; Check against the last known index value
je net_virtio_poll_nodata ; If equal then bail out

; Get size of packet that was received
mov ax, [rdx+0x78] ; Last known index
mov ax, [rdx+0x78] ; Get last known Used Ring Index
shl eax, 3 ; Quick multiply by 8
add eax, 4 ; Add offset to entries
add eax, 4 ; Add offset to entries (skip 16-bit Flags and 16-bit Index)
add rdi, rax ; RDI points to the Used Ring Entry
mov rcx, [rdi] ; Load the 32-bit Index and 32-bit Length
mov rcx, [rdi] ; Load the 32-bit ID (low bits) and 32-bit Length (high bits) together

; Populate RX Available Ring
mov rdi, r8
add rdi, 0x1002 ; Add offset to the Available Ring
mov ax, [rdi] ; 16-bit Index
inc ax
and ax, 0x00FF ; Wrap back to 0 if greater than 255
inc ax ; 65535 will wrap back around to 0
mov [rdi], ax ; 16-bit Index

; Set RDI to address of packet
Expand All @@ -552,12 +563,12 @@ net_virtio_poll:
; Increment internal counters
mov ax, [rdx+0x78] ; lastrx
inc ax
and ax, 0x00FF ; Wrap back to 0 if greater than 255
and ax, bx ; Wrap back to 0 if greater than queue length
mov [rdx+0x78], ax ; lastrx
mov [r8+0x2002], ax ; Store the new Used Ring Index

net_virtio_poll_nodata:
pop rax
pop rbx
pop rsi
pop r8
ret
Expand Down
4 changes: 4 additions & 0 deletions src/init/64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ make_interrupt_gate_stubs:
mov rax, 0x200000 ; Stacks start at 2MiB
mov [os_StackBase], rax

; Configure Network packet buffer base
mov eax, 0x300000
mov [os_PacketBase], rax

; Configure the serial port (if present)
call serial_init

Expand Down
1 change: 1 addition & 0 deletions src/sysvar.asm
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ os_LocalAPICAddress: equ os_SystemVariables + 0x0000
os_IOAPICAddress: equ os_SystemVariables + 0x0008
os_SysConfEn: equ os_SystemVariables + 0x0010 ; Enabled bits: 0=PS/2 Keyboard, 1=PS/2 Mouse, 2=Serial, 4=HPET, 5=xHCI
os_StackBase: equ os_SystemVariables + 0x0020
os_PacketBase: equ os_SystemVariables + 0x0028
sys_timer: equ os_SystemVariables + 0x0048
os_HPET_Address: equ os_SystemVariables + 0x0050
os_AHCI_Base: equ os_SystemVariables + 0x0058
Expand Down