diff --git a/src/drivers/net/virtio-net.asm b/src/drivers/net/virtio-net.asm index c477975..093536a 100644 --- a/src/drivers/net/virtio-net.asm +++ b/src/drivers/net/virtio-net.asm @@ -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 @@ -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 @@ -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 @@ -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 @@ -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: @@ -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 @@ -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 diff --git a/src/init/64.asm b/src/init/64.asm index 0dcd055..a8c3c4a 100644 --- a/src/init/64.asm +++ b/src/init/64.asm @@ -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 diff --git a/src/sysvar.asm b/src/sysvar.asm index 1f41c9b..20f50b0 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -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