Skip to content

Commit 66ebd71

Browse files
authored
Merge pull request #110 from ReturnInfinity/zerocopy
Zerocopy
2 parents 32eb966 + db1957c commit 66ebd71

File tree

10 files changed

+212
-139
lines changed

10 files changed

+212
-139
lines changed

api/libBareMetal.asm

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77

88
; Kernel functions
99
b_input equ 0x0000000000100010 ; Scans keyboard for input. OUT: AL = 0 if no key pressed, otherwise ASCII code
10-
b_output equ 0x0000000000100018 ; Displays a number of characters. IN: RSI = message location, RCX = number of characters
10+
b_output equ 0x0000000000100018 ; Displays a number of characters. IN: RSI = Memory address of message, RCX = number of characters
1111

12-
b_net_tx equ 0x0000000000100020 ; Transmit a packet via a network interface. IN: RSI = Memory location where packet is stored, RCX = Length of packet, RDX = Device
13-
b_net_rx equ 0x0000000000100028 ; Polls the network interface for received packet. IN: RDI = Memory location where packet will be stored, RDX = Device. OUT: RCX = Length of packet
12+
b_net_tx equ 0x0000000000100020 ; Transmit a packet via a network interface. IN: RSI = Memory address of where packet is stored, RCX = Length of packet, RDX = Device
13+
b_net_rx equ 0x0000000000100028 ; Polls the network interface for received packet. IN: RDX = Device. OUT: RDI = Memory address of where packet was stored, RCX = Length of packet
1414

15-
b_nvs_read equ 0x0000000000100030 ; Read data from a non-volatile storage device. IN: RAX = Starting sector, RCX = Number of sectors to read, RDX = Device, RDI = Memory location to store data
16-
b_nvs_write equ 0x0000000000100038 ; Write data to a non-volatile storage device. IN: RAX = Starting sector, RCX = Number of sectors to write, RDX = Device, RSI = Memory location of data to store
15+
b_nvs_read equ 0x0000000000100030 ; Read data from a non-volatile storage device. IN: RAX = Starting sector, RCX = Number of sectors to read, RDX = Device, RDI = Memory address to store data
16+
b_nvs_write equ 0x0000000000100038 ; Write data to a non-volatile storage device. IN: RAX = Starting sector, RCX = Number of sectors to write, RDX = Device, RSI = Memory address of data to store
1717

1818
b_system equ 0x0000000000100040 ; Configure system. IN: RCX = Function, RAX = Variable 1, RDX = Variable 2. OUT: RAX = Result
1919

@@ -35,7 +35,8 @@ SCREEN_X_GET equ 0x21
3535
SCREEN_Y_GET equ 0x22
3636
SCREEN_PPSL_GET equ 0x23
3737
SCREEN_BPP_GET equ 0x24
38-
MAC_GET equ 0x30
38+
NET_STATUS equ 0x30
39+
NET_CONFIG equ 0x31
3940
BUS_READ equ 0x50
4041
BUS_WRITE equ 0x51
4142
STDOUT_SET equ 0x52

api/libBareMetal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void b_net_tx(void *mem, u64 len, u64 iid) {
3030

3131
u64 b_net_rx(void *mem, u64 iid) {
3232
u64 tlong;
33-
asm volatile ("call *0x00100028" : "=c"(tlong) : "D"(mem), "d"(iid));
33+
asm volatile ("call *0x00100028" : "=D"(mem), "=c"(tlong) : "d"(iid));
3434
return tlong;
3535
}
3636

api/libBareMetal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ u64 b_system(u64 function, u64 var1, u64 var2);
4848
#define SCREEN_Y_GET 0x22
4949
#define SCREEN_PPSL_GET 0x23
5050
#define SCREEN_BPP_GET 0x24
51-
#define MAC_GET 0x30
51+
#define NET_STATUS 0x30
52+
#define NET_CONFIG 0x31
5253
#define BUS_READ 0x50
5354
#define BUS_WRITE 0x51
5455
#define STDOUT_SET 0x52

src/drivers/net/i8254x.asm

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,13 @@ net_i8254x_init:
2323
add rdi, rax
2424

2525
mov ax, 0x8254 ; Driver tag for i8254x
26-
stosw
27-
add rdi, 14
26+
mov [rdi+nt_ID], ax
2827

2928
; Get the Base Memory Address of the device
3029
mov al, 0 ; Read BAR0
3130
call os_bus_read_bar
32-
stosq ; Save the base
31+
mov [rdi+nt_base], rax ; Save the base
3332
push rax ; Save the base for gathering the MAC later
34-
mov rax, rcx
35-
stosq ; Save the length
3633

3734
; Set PCI Status/Command values
3835
mov dl, 0x01 ; Read Status/Command
@@ -44,7 +41,8 @@ net_i8254x_init:
4441

4542
; Get the MAC address
4643
pop rsi ; Restore the base
47-
sub rdi, 24 ; 8 bytes into net table entry
44+
push rdi
45+
add rdi, 8
4846
mov eax, [rsi+i8254x_RAL] ; RAL
4947
stosb
5048
shr eax, 8
@@ -57,31 +55,32 @@ net_i8254x_init:
5755
stosb
5856
shr eax, 8
5957
stosb
58+
pop rdi
6059

6160
; Set base addresses for TX and RX descriptors
6261
xor ecx, ecx
6362
mov cl, byte [os_net_icount]
6463
shl ecx, 15
6564

66-
add rdi, 0x22
6765
mov rax, os_tx_desc
6866
add rax, rcx
69-
stosq
67+
mov [rdi+nt_tx_desc], rax
7068
mov rax, os_rx_desc
7169
add rax, rcx
72-
stosq
70+
mov [rdi+nt_rx_desc], rax
7371

7472
; Reset the device
7573
xor edx, edx
7674
mov dl, [os_net_icount]
7775
call net_i8254x_reset
7876

7977
; Store call addresses
80-
sub rdi, 0x20
78+
mov rax, net_i8254x_config
79+
mov [rdi+nt_config], rax
8180
mov rax, net_i8254x_transmit
82-
stosq
81+
mov [rdi+nt_transmit], rax
8382
mov rax, net_i8254x_poll
84-
stosq
83+
mov [rdi+nt_poll], rax
8584

8685
net_i8254x_init_error:
8786

@@ -215,6 +214,34 @@ net_i8254x_reset_nextdesc:
215214
; -----------------------------------------------------------------------------
216215

217216

217+
; -----------------------------------------------------------------------------
218+
; net_i8254x_config -
219+
; IN: RAX = Base address to store packets
220+
; RDX = Interface ID
221+
; OUT: Nothing
222+
net_i8254x_config:
223+
push rdi
224+
push rcx
225+
push rax
226+
227+
mov rdi, [rdx+nt_rx_desc]
228+
mov ecx, i8254x_MAX_DESC
229+
call os_virt_to_phys
230+
net_i8254x_config_next_record:
231+
stosq
232+
add rdi, 8
233+
add rax, 2048
234+
dec ecx
235+
cmp ecx, 0
236+
jnz net_i8254x_config_next_record
237+
238+
pop rax
239+
pop rcx
240+
pop rdi
241+
ret
242+
; -----------------------------------------------------------------------------
243+
244+
218245
; -----------------------------------------------------------------------------
219246
; net_i8254x_transmit - Transmit a packet via an Intel 8254x NIC
220247
; IN: RSI = Location of packet
@@ -270,9 +297,9 @@ net_i8254x_transmit:
270297

271298
; -----------------------------------------------------------------------------
272299
; net_i8254x_poll - Polls the Intel 8254x NIC for a received packet
273-
; IN: RDI = Location to store packet
274-
; RDX = Interface ID
275-
; OUT: RCX = Length of packet
300+
; IN: RDX = Interface ID
301+
; OUT: RDI = Location of stored packet
302+
; RCX = Length of packet
276303
; Note: RDESC Descriptor Format:
277304
; First Qword:
278305
; Bits 63:0 - Buffer Address
@@ -283,8 +310,8 @@ net_i8254x_transmit:
283310
; Bits 47:40 - Errors
284311
; Bits 63:48 - Special
285312
net_i8254x_poll:
286-
push rdi
287313
push rsi ; Used for the base MMIO of the NIC
314+
push rbx
288315
push rax
289316

290317
mov rdi, [rdx+nt_rx_desc]
@@ -293,8 +320,9 @@ net_i8254x_poll:
293320
; Calculate the descriptor to read from
294321
mov eax, [rdx+nt_rx_head] ; Get rx_lasthead
295322
shl eax, 4 ; Quick multiply by 16
296-
add eax, 8 ; Offset to bytes received
297323
add rdi, rax ; Add offset to RDI
324+
mov rbx, [rdi]
325+
add rdi, 8 ; Offset to bytes received
298326
; Todo: read all 64 bits. check status bit for DD
299327
xor ecx, ecx ; Clear RCX
300328
mov cx, [rdi] ; Get the packet length
@@ -303,6 +331,7 @@ net_i8254x_poll:
303331

304332
xor eax, eax
305333
stosq ; Clear the descriptor length and status
334+
mov rdi, rbx
306335

307336
; Increment i8254x_rx_lasthead and the Receive Descriptor Tail
308337
mov eax, [rdx+nt_rx_head] ; Get rx_lasthead
@@ -315,16 +344,10 @@ net_i8254x_poll:
315344
and eax, i8254x_MAX_DESC - 1
316345
mov [rsi+i8254x_RDT], eax ; Write the updated Receive Descriptor Tail
317346

318-
pop rax
319-
pop rsi
320-
pop rdi
321-
ret
322-
323347
net_i8254x_poll_end:
324-
xor ecx, ecx
325348
pop rax
349+
pop rbx
326350
pop rsi
327-
pop rdi
328351
ret
329352
; -----------------------------------------------------------------------------
330353

@@ -346,8 +369,7 @@ net_i8254x_poll_end:
346369

347370

348371
; Constants
349-
i8254x_MAX_PKT_SIZE equ 16384
350-
i8254x_MAX_DESC equ 16 ; Must be 16, 32, 64, 128, etc.
372+
i8254x_MAX_DESC equ 2048 ; Must be 16, 32, 64, 128, etc. Each descriptor is 16 bytes
351373

352374
; Register list (13.2) (All registers should be accessed as 32-bit values)
353375

src/drivers/net/i8257x.asm

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,13 @@ net_i8257x_init:
2626
add rdi, rax
2727

2828
mov ax, 0x8257 ; Driver tag for i8257x
29-
stosw
30-
add rdi, 14
29+
mov [rdi+nt_ID], ax
3130

3231
; Get the Base Memory Address of the device
3332
mov al, 0 ; Read BAR0
3433
call os_bus_read_bar
35-
stosq ; Save the base
34+
mov [rdi+nt_base], rax ; Save the base
3635
push rax ; Save the base for gathering the MAC later
37-
mov rax, rcx
38-
stosq ; Save the length
3936

4037
; Set PCI Status/Command values
4138
mov dl, 0x01 ; Read Status/Command
@@ -47,7 +44,8 @@ net_i8257x_init:
4744

4845
; Get the MAC address
4946
pop rsi ; Restore the base
50-
sub rdi, 24 ; 8 bytes into net table entry
47+
push rdi
48+
add rdi, 8
5149
mov eax, [rsi+i8257x_RAL] ; RAL
5250
stosb
5351
shr eax, 8
@@ -60,31 +58,32 @@ net_i8257x_init:
6058
stosb
6159
shr eax, 8
6260
stosb
61+
pop rdi
6362

6463
; Set base addresses for TX and RX descriptors
6564
xor ecx, ecx
6665
mov cl, byte [os_net_icount]
6766
shl ecx, 15
6867

69-
add rdi, 0x22
7068
mov rax, os_tx_desc
7169
add rax, rcx
72-
stosq
70+
mov [rdi+nt_tx_desc], rax
7371
mov rax, os_rx_desc
7472
add rax, rcx
75-
stosq
73+
mov [rdi+nt_rx_desc], rax
7674

7775
; Reset the device
7876
xor edx, edx
7977
mov dl, [os_net_icount]
8078
call net_i8257x_reset
8179

8280
; Store call addresses
83-
sub rdi, 0x20
81+
mov rax, net_i8257x_config
82+
mov [rdi+nt_config], rax
8483
mov rax, net_i8257x_transmit
85-
stosq
84+
mov [rdi+nt_transmit], rax
8685
mov rax, net_i8257x_poll
87-
stosq
86+
mov [rdi+nt_poll], rax
8887

8988
net_i8257x_init_error:
9089

@@ -217,6 +216,34 @@ net_i8257x_reset_nextdesc:
217216
; -----------------------------------------------------------------------------
218217

219218

219+
; -----------------------------------------------------------------------------
220+
; net_i8257x_config -
221+
; IN: RAX = Base address to store packets
222+
; RDX = Interface ID
223+
; OUT: Nothing
224+
net_i8257x_config:
225+
push rdi
226+
push rcx
227+
push rax
228+
229+
mov rdi, [rdx+nt_rx_desc]
230+
mov ecx, i8257x_MAX_DESC
231+
call os_virt_to_phys
232+
net_i8257x_config_next_record:
233+
stosq
234+
add rdi, 8
235+
add rax, 2048
236+
dec ecx
237+
cmp ecx, 0
238+
jnz net_i8257x_config_next_record
239+
240+
pop rax
241+
pop rcx
242+
pop rdi
243+
ret
244+
; -----------------------------------------------------------------------------
245+
246+
220247
; -----------------------------------------------------------------------------
221248
; net_i8257x_transmit - Transmit a packet via an Intel 8257x NIC
222249
; IN: RSI = Location of packet
@@ -285,8 +312,8 @@ net_i8257x_transmit:
285312
; Bits 47:40 - Errors
286313
; Bits 63:48 - VLAN
287314
net_i8257x_poll:
288-
push rdi
289315
push rsi ; Used for the base MMIO of the NIC
316+
push rbx
290317
push rax
291318

292319
mov rdi, [rdx+nt_rx_desc]
@@ -295,8 +322,9 @@ net_i8257x_poll:
295322
; Calculate the descriptor to read from
296323
mov eax, [rdx+nt_rx_head] ; Get rx_lasthead
297324
shl eax, 4 ; Quick multiply by 16
298-
add eax, 8 ; Offset to bytes received
299325
add rdi, rax ; Add offset to RDI
326+
mov rbx, [rdi]
327+
add rdi, 8 ; Offset to bytes received
300328
; Todo: read all 64 bits. check status bit for DD
301329
xor ecx, ecx ; Clear RCX
302330
mov cx, [rdi] ; Get the packet length
@@ -305,6 +333,7 @@ net_i8257x_poll:
305333

306334
xor eax, eax
307335
stosq ; Clear the descriptor length and status
336+
mov rdi, rbx
308337

309338
; Increment i8257x_rx_lasthead and the Receive Descriptor Tail
310339
mov eax, [rdx+nt_rx_head] ; Get rx_lasthead
@@ -317,23 +346,16 @@ net_i8257x_poll:
317346
and eax, i8257x_MAX_DESC - 1
318347
mov [rsi+i8257x_RDT], eax ; Write the updated Receive Descriptor Tail
319348

320-
pop rax
321-
pop rsi
322-
pop rdi
323-
ret
324-
325349
net_i8257x_poll_end:
326-
xor ecx, ecx
327350
pop rax
351+
pop rbx
328352
pop rsi
329-
pop rdi
330353
ret
331354
; -----------------------------------------------------------------------------
332355

333356

334357
; Constants
335-
i8257x_MAX_PKT_SIZE equ 16384
336-
i8257x_MAX_DESC equ 16 ; Must be 16, 32, 64, 128, etc.
358+
i8257x_MAX_DESC equ 2048 ; Must be 16, 32, 64, 128, etc. Each descriptor is 16 bytes
337359

338360
; Register list (13.3) (All registers should be accessed as 32-bit values)
339361

0 commit comments

Comments
 (0)