1010; Initialize an Intel 8259x NIC
1111; IN: RDX = Packed Bus address (as per syscalls/bus.asm)
1212net_i8259x_init:
13+ push rdi
1314 push rsi
1415 push rdx
1516 push rcx
1617 push rax
1718
19+ mov rdi , net_table
20+ xor eax , eax
21+ mov al , [ os_net_icount ]
22+ shl eax , 7 ; Quick multiply by 128
23+ add rdi , rax
24+
25+ mov ax , 0x8259 ; Driver tag for i8259x
26+ stosw
27+ add rdi , 14
28+
1829 ; Get the Base Memory Address of the device
1930 mov al , 0 ; Read BAR0
2031 call os_bus_read_bar
21- mov [ os_NetIOBaseMem ], rax ; Save it as the base
22- mov [ os_NetIOLength ], rcx ; Save the length
32+ stosq ; Save the base
33+ push rax ; Save the base for gathering the MAC later
34+ mov rax , rcx
35+ stosq ; Save the length
2336
2437 ; Set PCI Status/Command values
2538 mov dl , 0x01 ; Read Status/Command
@@ -30,29 +43,53 @@ net_i8259x_init:
3043 call os_bus_write ; Write updated Status/Command
3144
3245 ; Get the MAC address
33- mov rsi , [ os_NetIOBaseMem ]
46+ pop rsi ; Restore the base
47+ sub rdi , 24 ; 8 bytes into net table entry
3448 mov eax , [ rsi + i8259x_RAL ] ; RAL
35- mov [ os_NetMAC ], al
49+ stosb
3650 shr eax , 8
37- mov [ os_NetMAC + 1 ], al
51+ stosb
3852 shr eax , 8
39- mov [ os_NetMAC + 2 ], al
53+ stosb
4054 shr eax , 8
41- mov [ os_NetMAC + 3 ], al
55+ stosb
4256 mov eax , [ rsi + i8259x_RAH ] ; RAH
43- mov [ os_NetMAC + 4 ], al
57+ stosb
4458 shr eax , 8
45- mov [ os_NetMAC + 5 ], al
59+ stosb
60+
61+ ; Set base addresses for TX and RX descriptors
62+ xor ecx , ecx
63+ mov cl , byte [ os_net_icount ]
64+ shl ecx , 15
65+
66+ add rdi , 0x22
67+ mov rax , os_tx_desc
68+ add rax , rcx
69+ stosq
70+ mov rax , os_rx_desc
71+ add rax , rcx
72+ stosq
4673
4774 ; Reset the device
75+ xor edx , edx
76+ mov dl , [ os_net_icount ]
4877 call net_i8259x_reset
4978
79+ ; Store call addresses
80+ sub rdi , 0x20
81+ mov rax , net_i8259x_transmit
82+ stosq
83+ mov rax , net_i8259x_poll
84+ stosq
85+
5086net_i8259x_init_error:
5187
5288 pop rax
5389 pop rcx
5490 pop rdx
5591 pop rsi
92+ pop rdi
5693 ret
5794; -----------------------------------------------------------------------------
5895
@@ -62,10 +99,19 @@ net_i8259x_init_error:
6299; IN: Nothing
63100; OUT: Nothing, all registers preserved
64101net_i8259x_reset:
102+ push rdi
65103 push rsi
66104 push rax
67105
68- mov rsi , [ os_NetIOBaseMem ]
106+ ; Gather Base Address from net_table
107+ mov rsi , net_table
108+ xor eax , eax
109+ mov al , [ os_net_icount ]
110+ shl eax , 7 ; Quick multiply by 128
111+ add rsi , rax
112+ add rsi , 16
113+ mov rsi , [ rsi ]
114+ mov rdi , rsi
69115
70116 ; Disable Interrupts (4.6.3.1)
71117 xor eax , eax
@@ -138,7 +184,11 @@ net_i8259x_reset_dma_wait:
138184 ; Create RX descriptors
139185 push rdi
140186 mov ecx , i8259x_MAX_DESC
187+ xor eax , eax
188+ mov al , byte [ os_net_icount ]
189+ shl eax , 15
141190 mov rdi , os_rx_desc
191+ add rdi , rax
142192net_i8259x_reset_nextdesc:
143193 mov rax , os_PacketBuffers ; Default packet will go here
144194 stosq
@@ -181,7 +231,10 @@ net_i8259x_reset_nextdesc:
181231 bts eax , 28 ; i8259x_SRRCTL_DROP_EN
182232 mov [ rsi + i8259x_SRRCTL ], eax
183233 ; Set up RX descriptor ring 0
184- mov rax , os_rx_desc
234+ xor eax , eax
235+ mov al , byte [ os_net_icount ]
236+ shl eax , 15
237+ add rax , os_rx_desc
185238 mov [ rsi + i8259x_RDBAL ], eax
186239 shr rax , 32
187240 mov [ rsi + i8259x_RDBAH ], eax
@@ -254,7 +307,10 @@ net_i8259x_init_rx_enable_wait:
254307 btc eax , i8259x_RTTDCS_ARBDIS
255308 mov [ rsi + i8259x_RTTDCS ], eax
256309 ; Set up TX descriptor ring 0
257- mov rax , os_tx_desc
310+ xor eax , eax
311+ mov al , byte [ os_net_icount ]
312+ shl eax , 15
313+ add rax , os_tx_desc
258314 mov [ rsi + i8259x_TDBAL ], eax ; Bits 6:0 are ignored, memory alignment at 128bytes
259315 shr rax , 32
260316 mov [ rsi + i8259x_TDBAH ], eax
@@ -288,21 +344,21 @@ net_i8259x_init_tx_enable_wait:
288344 ; or eax, 0x80000000 ; GPIE_PBA_SUPPORT
289345 ; or eax, 0x40000000 ; GPIE_EIAME
290346 ; mov [rsi+0x00898], eax ; Set Ixgbe_GPIE
291-
347+
292348 ; ; Step 2:- We don't use the minimum threshold interrupt
293-
349+
294350 ; ; Step 3:-
295351 ; mov eax, 0x0000FFFF
296352 ; mov [rsi+i8259x_EIAC], eax
297353
298354 ; ; Step 4:- In our case we prefer to not auto-mask the interrupts
299355 ; ; TODO- Set EITR
300-
356+
301357 ; ; Step 5:-
302358 ; mov eax, [rsi+i8259x_EIMS]
303359 ; or eax, 0x00000001
304360 ; mov [rsi+i8259x_EIMS], eax
305-
361+
306362
307363; DEBUG - Enable Promiscuous mode
308364 mov eax , [ rsi + i8259x_FCTRL ]
@@ -316,13 +372,15 @@ net_i8259x_init_tx_enable_wait:
316372
317373 pop rax
318374 pop rsi
375+ pop rdi
319376 ret
320377; -----------------------------------------------------------------------------
321378
322379
323380; -----------------------------------------------------------------------------
324381; net_i8259x_transmit - Transmit a packet via an Intel 8259x NIC
325382; IN: RSI = Location of packet
383+ ; RDX = Interface ID
326384; RCX = Length of packet
327385; OUT: Nothing
328386; Note: Transmit Descriptor (TDESC) Layout - Legacy Mode (7.2.3.2.2):
@@ -333,10 +391,10 @@ net_i8259x_transmit:
333391 push rdi
334392 push rax
335393
336- mov rdi , os_tx_desc ; Transmit Descriptor Base Address
394+ mov rdi , [ rdx + nt_tx_desc ] ; Transmit Descriptor Base Address
337395
338396 ; Calculate the descriptor to write to
339- mov eax , [ i8259x_tx_lasttail ]
397+ mov eax , [ rdx + nt_tx_head ] ; Get tx_lasttail
340398 push rax ; Save lasttail
341399 shl eax , 4 ; Quick multiply by 16
342400 add rdi , rax ; Add offset to RDI
@@ -354,8 +412,8 @@ net_i8259x_transmit:
354412 pop rax ; Restore lasttail
355413 add eax , 1
356414 and eax , i8259x_MAX_DESC - 1
357- mov [ i8259x_tx_lasttail ], eax
358- mov rdi , [ os_NetIOBaseMem ]
415+ mov [ rdx + nt_tx_head ], eax ; Set tx_lasttail
416+ mov rdi , [ rdx + nt_base ] ; Load the base MMIO of the NIC
359417 mov [ rdi + i8259x_TDT ], eax ; TDL - Transmit Descriptor Tail
360418
361419 ; TDESC.STA.DD (bit 32) should be 1 once the hardware has sent the packet
@@ -369,6 +427,7 @@ net_i8259x_transmit:
369427; -----------------------------------------------------------------------------
370428; net_i8259x_poll - Polls the Intel 8259x NIC for a received packet
371429; IN: RDI = Location to store packet
430+ ; RDX = Interface ID
372431; OUT: RCX = Length of packet
373432; Note: Receive Descriptor (RDESC) Layout - Legacy Mode (7.1.5):
374433; Bits 63:0 - Buffer Address
@@ -379,11 +438,11 @@ net_i8259x_poll:
379438 push rsi ; Used for the base MMIO of the NIC
380439 push rax
381440
382- mov rdi , os_rx_desc
383- mov rsi , [ os_NetIOBaseMem ] ; Load the base MMIO of the NIC
441+ mov rdi , [ rdx + nt_rx_desc ]
442+ mov rsi , [ rdx + nt_base ] ; Load the base MMIO of the NIC
384443
385444 ; Calculate the descriptor to read from
386- mov eax , [ i8259x_rx_lasthead ]
445+ mov eax , [ rdx + nt_rx_head ] ; Get rx_lasthead
387446 shl eax , 4 ; Quick multiply by 16
388447 add eax , 8 ; Offset to bytes received
389448 add rdi , rax ; Add offset to RDI
@@ -397,10 +456,11 @@ net_i8259x_poll:
397456 stosq ; Clear the descriptor length and status
398457
399458 ; Increment i8259x_rx_lasthead and the Receive Descriptor Tail
400- mov eax , [ i8259x_rx_lasthead ]
459+ mov eax , [ rdx + nt_rx_head ] ; Get rx_lasthead
401460 add eax , 1
402461 and eax , i8259x_MAX_DESC - 1
403- mov [ i8259x_rx_lasthead ], eax
462+ mov [ rdx + nt_rx_head ], eax ; Set rx_lasthead
463+
404464 mov eax , [ rsi + i8259x_RDT ] ; Read the current Receive Descriptor Tail
405465 add eax , 1 ; Add 1 to the Receive Descriptor Tail
406466 and eax , i8259x_MAX_DESC - 1
@@ -420,10 +480,6 @@ net_i8259x_poll_end:
420480; -----------------------------------------------------------------------------
421481
422482
423- ; Variables
424- i8259x_tx_lasttail: dd 0
425- i8259x_rx_lasthead: dd 0
426-
427483; Constants
428484i8259x_MAX_PKT_SIZE equ 16384
429485i8259x_MAX_DESC equ 4096 ; Must be 16, 32, 64, 128, etc.
0 commit comments