Skip to content

Commit 68aff11

Browse files
author
Ian Seyler
committed
Start of ENA driver
1 parent d430545 commit 68aff11

File tree

4 files changed

+281
-0
lines changed

4 files changed

+281
-0
lines changed

build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ BUILDFLAGS=""
1212
# -dNO_I8254X Remove i8254x Gigabit driver
1313
# -dNO_I8257X Remove i8257x Gigabit driver
1414
# -dNO_I8259X Remove i8259x 10-Gigabit driver
15+
# -dNO_ENA Remove ENA driver
1516
# HID
1617
# -dNO_XHCI Remove xHCI USB driver (hid)
1718
# -dNO_LFB Remove LFB text driver

src/drivers.asm

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
%ifndef NO_VIRTIO
5151
%include "drivers/net/virtio-net.asm"
5252
%endif
53+
%ifndef NO_ENA
54+
%include "drivers/net/ena.asm"
55+
%endif
5356
; %include "drivers/net/r8169.asm"
5457

5558
; Video
@@ -158,6 +161,16 @@ dw 0x1572 ; X710 (SFP+)
158161
dw 0x0000
159162
%endif
160163

164+
%ifndef NO_ENA
165+
dw 0x0EC2 ; Driver ID
166+
dw 0x1D0F ; Vendor ID (Amazon)
167+
dw 0x0EC2 ; ENA_PF
168+
dw 0x1EC2 ; ENA_LLQ_PF
169+
dw 0xEC20 ; ENA_VF
170+
dw 0xEC21 ; ENA_LLQ_VF
171+
dw 0x0000
172+
%endif
173+
161174
; Realtek 816x/811x Gigabit Ethernet
162175
;dw 0x8169 ; Driver ID
163176
;dw 0x10EC ; Vendor ID

src/drivers/net/ena.asm

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
; =============================================================================
2+
; BareMetal -- a 64-bit OS written in Assembly for x86-64 systems
3+
; Copyright (C) 2008-2025 Return Infinity -- see LICENSE.TXT
4+
;
5+
; Elastic Network Adapter Driver
6+
; =============================================================================
7+
8+
9+
; -----------------------------------------------------------------------------
10+
; Initialize an ENA NIC
11+
; IN: RDX = Packed Bus address (as per syscalls/bus.asm)
12+
net_ena_init:
13+
push rdi
14+
push rsi
15+
push rdx
16+
push rcx
17+
push rax
18+
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, 0x0EC2 ; Driver tag for ena
26+
mov [rdi+nt_ID], ax
27+
28+
; Get the Base Memory Address of the device
29+
mov al, 0 ; Read BAR0
30+
call os_bus_read_bar
31+
mov [rdi+nt_base], rax ; Save the base
32+
push rax ; Save the base for gathering the MAC later
33+
34+
; Set PCI Status/Command values
35+
mov dl, 0x01 ; Read Status/Command
36+
call os_bus_read
37+
bts eax, 10 ; Set Interrupt Disable
38+
bts eax, 2 ; Enable Bus Master
39+
bts eax, 1 ; Enable Memory Space
40+
call os_bus_write ; Write updated Status/Command
41+
42+
; Usually the MAC would be read from the device MMIO here but ENA works differently
43+
44+
; Set base addresses for TX and RX descriptors
45+
xor ecx, ecx
46+
mov cl, byte [os_net_icount]
47+
shl ecx, 15
48+
49+
mov rax, os_tx_desc
50+
add rax, rcx
51+
mov [rdi+nt_tx_desc], rax
52+
mov rax, os_rx_desc
53+
add rax, rcx
54+
mov [rdi+nt_rx_desc], rax
55+
56+
; Reset the device
57+
xor edx, edx
58+
mov dl, [os_net_icount]
59+
call net_ena_reset
60+
61+
; Store call addresses
62+
mov rax, net_ena_config
63+
mov [rdi+nt_config], rax
64+
mov rax, net_ena_transmit
65+
mov [rdi+nt_transmit], rax
66+
mov rax, net_ena_poll
67+
mov [rdi+nt_poll], rax
68+
69+
net_ena_init_error:
70+
71+
pop rax
72+
pop rcx
73+
pop rdx
74+
pop rsi
75+
pop rdi
76+
ret
77+
; -----------------------------------------------------------------------------
78+
79+
80+
; -----------------------------------------------------------------------------
81+
; net_ena_reset - Reset an ENA NIC
82+
; IN: RDX = Interface ID
83+
; OUT: Nothing, all registers preserved
84+
net_ena_reset:
85+
push rdi
86+
push rsi
87+
push rax
88+
89+
; Gather Base Address from net_table
90+
mov rsi, net_table
91+
xor eax, eax
92+
mov al, [os_net_icount]
93+
shl eax, 7 ; Quick multiply by 128
94+
add rsi, rax
95+
add rsi, 16
96+
mov rsi, [rsi]
97+
mov rdi, rsi
98+
99+
; Stop queues if they are running
100+
101+
; Check ENA_DEV_STS.READY
102+
mov eax, [rsi+ENA_DEV_STS]
103+
test eax, 1
104+
; poll bit with timeout
105+
106+
; Check versions
107+
mov eax, [rsi+ENA_VERSION]
108+
mov eax, [rsi+ENA_CONTROLLER_VERSION]
109+
110+
; Check capabilities
111+
mov eax, [rsi+ENA_CAPS]
112+
mov eax, [rsi+ENA_CAPS_EXT]
113+
114+
; Set device memory
115+
mov rax, 0x600000
116+
mov [rsi+ENA_AQ_BASE_LO], eax
117+
shr rax, 32
118+
mov [rsi+ENA_AQ_BASE_HI], eax
119+
mov rax, 0x610000
120+
mov [rsi+ENA_ACQ_BASE_LO], eax
121+
shr rax, 32
122+
mov [rsi+ENA_ACQ_BASE_HI], eax
123+
mov rax, 0x620000
124+
mov [rsi+ENA_AENQ_BASE_LO], eax
125+
shr rax, 32
126+
mov [rsi+ENA_AENQ_BASE_HI], eax
127+
128+
; Create Admin Queue
129+
; Admin Submission Queue (AQ)
130+
; Admin Completion Queue (ACQ)
131+
132+
; Check ENA_DEV_STS.READY
133+
134+
; Build an Admin command
135+
; opcode ENA_ADMIN_GET_FEATURE = 0x0009
136+
; feat_id ENA_ADMIN_DEVICE_ATTRIBUTES = 1
137+
; Put it in the queue
138+
; Wait for completion
139+
; Check head has changed
140+
; Verify command
141+
; Verify status (ENA_ADMIN_SUCCESS)
142+
; MAC Address at offset 0x0 of returned data
143+
144+
pop rax
145+
pop rsi
146+
pop rdi
147+
ret
148+
; -----------------------------------------------------------------------------
149+
150+
151+
; -----------------------------------------------------------------------------
152+
; net_ena_config -
153+
; IN: RAX = Base address to store packets
154+
; RDX = Interface ID
155+
; OUT: Nothing
156+
net_ena_config:
157+
push rdi
158+
push rcx
159+
push rax
160+
161+
pop rax
162+
pop rcx
163+
pop rdi
164+
ret
165+
; -----------------------------------------------------------------------------
166+
167+
168+
; -----------------------------------------------------------------------------
169+
; net_ena_transmit - Transmit a packet via an ENA NIC
170+
; IN: RSI = Location of packet
171+
; RDX = Interface ID
172+
; RCX = Length of packet
173+
; OUT: Nothing
174+
net_ena_transmit:
175+
push rdi
176+
push rbx
177+
push rax
178+
179+
mov rdi, [rdx+nt_tx_desc] ; Transmit Descriptor Base Address
180+
181+
pop rax
182+
pop rbx
183+
pop rdi
184+
ret
185+
; -----------------------------------------------------------------------------
186+
187+
188+
; -----------------------------------------------------------------------------
189+
; net_ena_poll - Polls the ENA NIC for a received packet
190+
; IN: RDX = Interface ID
191+
; OUT: RDI = Location of stored packet
192+
; RCX = Length of packet
193+
net_ena_poll:
194+
push rsi ; Used for the base MMIO of the NIC
195+
push rbx
196+
push rax
197+
198+
mov rdi, [rdx+nt_rx_desc]
199+
mov rsi, [rdx+nt_base] ; Load the base MMIO of the NIC
200+
201+
net_ena_poll_end:
202+
pop rax
203+
pop rbx
204+
pop rsi
205+
ret
206+
; -----------------------------------------------------------------------------
207+
208+
209+
; -----------------------------------------------------------------------------
210+
; net_ena_ack_int - Acknowledge an internal interrupt of the Intel 8254x NIC
211+
; IN: Nothing
212+
; OUT: RAX = Ethernet status
213+
;net_ena_ack_int:
214+
; push rdi
215+
;
216+
; pop rdi
217+
; ret
218+
; -----------------------------------------------------------------------------
219+
220+
221+
; Register list (All registers should be accessed as 32-bit values)
222+
223+
; General Control Registers
224+
225+
ENA_VERSION equ 0x00
226+
ENA_CONTROLLER_VERSION equ 0x04
227+
ENA_CAPS equ 0x08
228+
ENA_CAPS_EXT equ 0x0C
229+
ENA_AQ_BASE_LO equ 0x10
230+
ENA_AQ_BASE_HI equ 0x14
231+
ENA_AQ_CAPS equ 0x18
232+
ENA_ACQ_BASE_LO equ 0x20
233+
ENA_ACQ_BASE_HI equ 0x24
234+
ENA_ACQ_CAPS equ 0x28
235+
ENA_AQ_DB equ 0x2C
236+
ENA_ACQ_TAIL equ 0x30
237+
ENA_AENQ_CAPS equ 0x34
238+
ENA_AENQ_BASE_LO equ 0x38
239+
ENA_AENQ_BASE_HI equ 0x3C
240+
ENA_AENQ_HEAD_DB equ 0x40
241+
ENA_AENQ_TAIL equ 0x44
242+
ENA_INTR_MASK equ 0x4C
243+
ENA_DEV_CTL equ 0x54
244+
ENA_DEV_STS equ 0x58
245+
ENA_MMIO_REG_READ equ 0x5C
246+
ENA_MMIO_RESP_LO equ 0x60
247+
ENA_MMIO_RESP_HI equ 0x64
248+
ENA_RSS_IND_ENTRY_UPDATE equ 0x68
249+
250+
251+
; Register bits
252+
253+
254+
255+
; =============================================================================
256+
; EOF

src/init/net.asm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ init_net_probe_found:
6767
cmp bx, 0x8259
6868
je init_net_probe_found_i8259x
6969
%endif
70+
%ifndef NO_ENA
71+
cmp bx, 0x0EC2
72+
je init_net_probe_found_ena
73+
%endif
74+
7075
; cmp bx, 0x8169
7176
; je init_net_probe_found_r8169
7277
jmp init_net_probe_not_found
@@ -95,6 +100,12 @@ init_net_probe_found_i8259x:
95100
jmp init_net_probe_found_finish
96101
%endif
97102

103+
%ifndef NO_ENA
104+
init_net_probe_found_ena:
105+
call net_ena_init
106+
jmp init_net_probe_found_finish
107+
%endif
108+
98109
;init_net_probe_found_r8169:
99110
; call net_r8169_init
100111
; jmp init_net_probe_found_finish

0 commit comments

Comments
 (0)