* remove "\r" nonsense
[mascara-docs.git] / amd64 / bareMetalOS-0.5.3 / os / syscalls / ethernet.asm
blob310a749a5cddb38ca7457c7d6bcc65db9d84fa66
1 ; =============================================================================
2 ; BareMetal -- a 64-bit OS written in Assembly for x86-64 systems
3 ; Copyright (C) 2008-2012 Return Infinity -- see LICENSE.TXT
5 ; Ethernet Functions
6 ; =============================================================================
8 align 16
9 db 'DEBUG: ETHERNET '
10 align 16
13 ; Ethernet Type II Frame (64 - 1518 bytes)
14 ; MAC Header (14 bytes)
15 ; Destination MAC Address (6 bytes)
16 ; Source MAC Address (6 bytes)
17 ; EtherType/Length (2 bytes)
18 ; Payload (46 - 1500 bytes)
19 ; CRC (4 bytes)
20 ; Network card handles the Preamble (7 bytes), Start-of-Frame-Delimiter (1 byte), and Interframe Gap (12 bytes)
23 ; -----------------------------------------------------------------------------
24 ; os_ethernet_avail -- Check if Ethernet is available
25 ; IN: Nothing
26 ; OUT: RAX = MAC Address if Ethernet is enabled, otherwise 0
27 os_ethernet_avail:
28 push rsi
29 push rcx
31 cld
32 xor eax, eax
33 cmp byte [os_NetEnabled], 0
34 je os_ethernet_avail_end
36 mov ecx, 6
37 mov rsi, os_NetMAC
38 os_ethernet_avail_loadMAC:
39 shl rax, 8
40 lodsb
41 sub ecx, 1
42 test ecx, ecx
43 jnz os_ethernet_avail_loadMAC
45 os_ethernet_avail_end:
46 pop rcx
47 pop rsi
48 ret
49 ; -----------------------------------------------------------------------------
52 ; -----------------------------------------------------------------------------
53 ; os_ethernet_tx -- Transmit a packet via Ethernet
54 ; IN: RSI = Memory location where data is stored
55 ; RDI = Pointer to 48 bit destination address
56 ; BX = Type of packet (If set to 0 then the EtherType will be set to the length of data)
57 ; CX = Length of data
58 ; OUT: Nothing. All registers preserved
59 os_ethernet_tx:
60 push rsi
61 push rdi
62 push rdx
63 push rcx
64 push rbx
65 push rax
67 cmp byte [os_NetEnabled], 1
68 jne os_ethernet_tx_fail
69 cmp cx, 1500 ; Fail if more then 1500 bytes
70 jg os_ethernet_tx_fail
72 mov rax, os_EthernetBusyLock ; Lock the Ethernet so only one send can happen at a time
73 call os_smp_lock
75 push rsi
76 mov rsi, rdi
77 mov rdi, os_ethernet_tx_buffer ; Build the packet to transfer at this location
78 ; TODO: Ask the driver where in memory the packet should be assembled.
80 ; Copy destination MAC address
81 movsd
82 movsw
84 ; Copy source MAC address
85 mov rsi, os_NetMAC
86 movsd
87 movsw
89 ; Set the EtherType/Length
90 cmp bx, 0
91 jne os_ethernet_tx_typeset ; If EtherType is not set then use the Data Length instead
92 mov bx, cx ; Length of data (Does not include header)
93 os_ethernet_tx_typeset:
94 xchg bl, bh ; x86 is Little-endian but packets use Big-endian
95 mov [rdi], bx
96 add rdi, 2
98 ; Copy the packet data
99 pop rsi
100 mov rax, 0x000000000000FFFF
101 and rcx, rax ; Clear the top 48 bits
102 push rcx
103 rep movsb
104 pop rcx
106 ; Add padding to the packet data if needed
107 cmp cx, 46 ; Data needs to be at least 46 bytes (if not it needs to be padded)
108 jge os_ethernet_tx_nopadding
109 mov ax, 46
110 sub ax, cx ; Padding needed = 46 - CX
111 mov cx, ax
112 xor ax, ax
113 rep stosb ; Store 0x00 CX times
114 mov cx, 46
115 os_ethernet_tx_nopadding:
117 xor eax, eax
118 stosd ; Store a blank CRC value
120 ; Call the send function of the ethernet card driver
121 add cx, 14 ; Add 14 for the header bytes
122 mov rsi, os_ethernet_tx_buffer
123 call qword [os_net_transmit]
125 mov rax, os_EthernetBusyLock
126 call os_smp_unlock
128 os_ethernet_tx_fail:
130 pop rax
131 pop rbx
132 pop rcx
133 pop rdx
134 pop rdi
135 pop rsi
137 ; -----------------------------------------------------------------------------
140 ; -----------------------------------------------------------------------------
141 ; os_ethernet_tx_raw -- Transmit a raw frame via Ethernet
142 ; IN: RSI = Memory location where raw frame is stored
143 ; CX = Length of frame
144 ; OUT: Nothing. All registers preserved
145 os_ethernet_tx_raw:
146 push rsi
147 push rdi
148 push rdx
149 push rcx
150 push rbx
151 push rax
153 cmp byte [os_NetEnabled], 1
154 jne os_ethernet_tx_raw_fail
155 cmp cx, 1500 ; Fail if more then 1500 bytes
156 jg os_ethernet_tx_raw_fail
158 mov rax, os_EthernetBusyLock ; Lock the Ethernet so only one send can happen at a time
159 call os_smp_lock
161 ; Copy the packet data
162 mov rdi, os_ethernet_tx_buffer ; Build the packet to transfer at this location
163 mov rax, 0x000000000000FFFF
164 and rcx, rax ; Clear the top 48 bits
165 push rcx
166 rep movsb
167 pop rcx
169 ; Add padding to the packet data if needed
170 cmp cx, 46 ; Data needs to be at least 46 bytes (if not it needs to be padded)
171 jge os_ethernet_tx_raw_nopadding
172 mov ax, 46
173 sub ax, cx ; Padding needed = 46 - CX
174 mov cx, ax
175 xor ax, ax
176 rep stosb ; Store 0x00 CX times
177 mov cx, 46
178 os_ethernet_tx_raw_nopadding:
180 xor eax, eax
181 stosd ; Store a blank CRC value
183 ; Call the send function of the ethernet card driver
184 mov rsi, os_ethernet_tx_buffer
185 call qword [os_net_transmit]
187 mov rax, os_EthernetBusyLock
188 call os_smp_unlock
190 os_ethernet_tx_raw_fail:
192 pop rax
193 pop rbx
194 pop rcx
195 pop rdx
196 pop rdi
197 pop rsi
199 ; -----------------------------------------------------------------------------
202 ; -----------------------------------------------------------------------------
203 ; os_ethernet_rx -- Polls the Ethernet card for received data
204 ; IN: RDI = Memory location where packet will be stored
205 ; OUT: RCX = Length of packet
206 ; All other registers preserved
207 os_ethernet_rx:
208 push rdi
209 push rsi
210 push rdx
211 push rax
213 xor ecx, ecx
215 cmp byte [os_NetEnabled], 1
216 jne os_ethernet_rx_fail
218 ; Is there anything in the ring buffer?
219 mov al, byte [os_EthernetBuffer_C1]
220 mov dl, byte [os_EthernetBuffer_C2]
221 cmp al, dl ; If both counters are equal then the buffer is empty
222 je os_ethernet_rx_fail
224 ; Read the packet from the ring buffer to RDI
225 mov rsi, os_EthernetBuffer
226 xor rax, rax
227 mov al, byte [os_EthernetBuffer_C1]
228 push rax ; Save the ring element value
229 shl rax, 11 ; Quickly multiply RAX by 2048
230 add rsi, rax ; RSI points to the packet in the ring buffer
231 lodsw ; Load the packet length
232 mov cx, ax ; Copy the packet length to RCX
233 push rcx
234 rep movsb ; Copy the packet to RDI
235 pop rcx
236 pop rax ; Restore the ring element value
237 add al, 1
238 cmp al, 128 ; Max element number is 127
239 jne os_ethernet_rx_buffer_nowrap
240 xor al, al
241 os_ethernet_rx_buffer_nowrap:
242 mov byte [os_EthernetBuffer_C1], al
244 os_ethernet_rx_fail:
246 pop rax
247 pop rdx
248 pop rsi
249 pop rdi
251 ; -----------------------------------------------------------------------------
254 ; -----------------------------------------------------------------------------
255 ; os_ethernet_ack_int -- Acknowledge an interrupt within the NIC
256 ; IN: Nothing
257 ; OUT: RAX = Type of interrupt trigger
258 ; All other registers preserved
259 os_ethernet_ack_int:
260 push rdx
262 call qword [os_net_ack_int]
264 pop rdx
266 ; -----------------------------------------------------------------------------
269 ; -----------------------------------------------------------------------------
270 ; os_ethernet_rx_from_interrupt -- Polls the Ethernet card for received data
271 ; IN: RDI = Memory location where packet will be stored
272 ; OUT: RCX = Length of packet
273 ; All other registers preserved
274 os_ethernet_rx_from_interrupt:
275 push rdi
276 push rsi
277 push rdx
278 push rax
280 xor ecx, ecx
282 ; Call the poll function of the ethernet card driver
283 call qword [os_net_poll]
285 pop rax
286 pop rdx
287 pop rsi
288 pop rdi
290 ; -----------------------------------------------------------------------------
293 ; =============================================================================
294 ; EOF