Skip to content

Commit 99d90da

Browse files
stlankesmkroening
andauthored
add BSD socket layer (#633)
This PR realize a classical BSD socket layer. To realize a BSD socket layer, the executor has to return directly UNIX-like error number because the layer depends on a C interface and doesn't support Rust's error handling. Co-authored-by: Martin Kröning <mkroening@posteo.net>
1 parent f61b60e commit 99d90da

File tree

24 files changed

+1700
-360
lines changed

24 files changed

+1700
-360
lines changed

Cargo.lock

Lines changed: 30 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pci = ["num-derive"]
5555
acpi = []
5656
smp = ["include-transformed"]
5757
fsgsbase = []
58+
trace = []
5859
tcp = [
5960
"async-task",
6061
"futures-lite",
@@ -71,6 +72,7 @@ ahash = { version = "0.8", default-features = false }
7172
align-address = "0.1"
7273
bitflags = "1.3"
7374
crossbeam-utils = { version = "0.8", default-features = false }
75+
dyn-clone = "1.0"
7476
hashbrown = { version = "0.13", default-features = false }
7577
hermit-entry = { version = "0.9", features = ["kernel"] }
7678
hermit-sync = "0.1.2"
@@ -87,6 +89,7 @@ qemu-exit = "3.0"
8789
rand_chacha = { version = "0.3", default-features = false }
8890
futures-lite = { version = "1.11", default-features = false, optional = true }
8991
async-task = { version = "4.3", default-features = false, optional = true }
92+
lock_api = "0.4"
9093

9194
[dependencies.smoltcp]
9295
version = "0.8"

src/arch/x86_64/kernel/apic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use alloc::vec::Vec;
2-
#[cfg(any(feature = "pci", feature = "smp"))]
2+
#[cfg(feature = "smp")]
33
use core::arch::x86_64::_mm_mfence;
44
use core::hint::spin_loop;
55
#[cfg(feature = "smp")]

src/drivers/net/mod.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ pub mod virtio_net;
66
#[cfg(feature = "pci")]
77
pub mod virtio_pci;
88

9+
use alloc::vec::Vec;
10+
911
use crate::arch::kernel::apic;
1012
use crate::arch::kernel::core_local::*;
1113
use crate::arch::kernel::interrupts::ExceptionStackFrame;
@@ -31,9 +33,7 @@ pub trait NetworkInterface {
3133
/// Check if a packet is available
3234
fn has_packet(&self) -> bool;
3335
/// Get RX buffer with an received packet
34-
fn receive_rx_buffer(&mut self) -> Result<(&'static mut [u8], usize), ()>;
35-
/// Tells driver, that buffer is consumed and can be deallocated
36-
fn rx_buffer_consumed(&mut self, trf_handle: usize);
36+
fn receive_rx_buffer(&mut self) -> Result<Vec<u8>, ()>;
3737
/// Enable / disable the polling mode of the network interface
3838
fn set_polling_mode(&mut self, value: bool);
3939
/// Handle interrupt and check if a packet is available
@@ -63,10 +63,9 @@ pub extern "x86-interrupt" fn network_irqhandler(_stack_frame: ExceptionStackFra
6363
};
6464

6565
if has_packet {
66-
// handle incoming packets
66+
let core_scheduler = core_scheduler();
6767
#[cfg(feature = "tcp")]
68-
crate::net::network_poll();
69-
70-
core_scheduler().scheduler();
68+
core_scheduler.wakeup_async_tasks();
69+
core_scheduler.scheduler();
7170
}
7271
}

src/drivers/net/rtl8139.rs

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#![allow(dead_code)]
44

55
use alloc::boxed::Box;
6-
use alloc::collections::{btree_map, BTreeMap};
6+
use alloc::vec::Vec;
77
use core::mem;
88

99
use x86::io::*;
@@ -209,7 +209,7 @@ pub struct RTL8139Driver {
209209
rxbuffer: Box<[u8]>,
210210
rxpos: usize,
211211
txbuffer: Box<[u8]>,
212-
box_map: BTreeMap<usize, Box<[u8]>>,
212+
polling_mode_counter: u32,
213213
}
214214

215215
impl NetworkInterface for RTL8139Driver {
@@ -270,7 +270,7 @@ impl NetworkInterface for RTL8139Driver {
270270
false
271271
}
272272

273-
fn receive_rx_buffer(&mut self) -> Result<(&'static mut [u8], usize), ()> {
273+
fn receive_rx_buffer(&mut self) -> Result<Vec<u8>, ()> {
274274
let cmd = unsafe { inb(self.iobase + CR) };
275275

276276
if (cmd & CR_BUFE) != CR_BUFE {
@@ -282,25 +282,18 @@ impl NetworkInterface for RTL8139Driver {
282282
let pos = (self.rxpos + mem::size_of::<u16>()) % RX_BUF_LEN;
283283

284284
// do we reach the end of the receive buffers?
285-
// in this case, we have to copy the data in boxed slice
285+
// in this case, we conact the two slices to one vec
286286
let buf = if pos + length as usize > RX_BUF_LEN {
287287
let first = &self.rxbuffer[pos..RX_BUF_LEN];
288288
let second = &self.rxbuffer[..length as usize - first.len()];
289-
let msg = [first, second].concat().into_boxed_slice();
290-
291-
// buffer address to release box in `rx_buffer_consumed`
292-
match self.box_map.entry(self.rxpos) {
293-
btree_map::Entry::Vacant(entry) => entry.insert(msg),
294-
btree_map::Entry::Occupied(_) => unreachable!(),
295-
}
289+
[first, second].concat()
296290
} else {
297-
&mut self.rxbuffer[pos..][..length.into()]
291+
(self.rxbuffer[pos..][..length.into()]).to_vec()
298292
};
299-
// SAFETY: This is a blatant lie and very unsound.
300-
// The API must be fixed or the buffer may never touched again.
301-
let buf = unsafe { mem::transmute(buf) };
302293

303-
Ok((buf, self.rxpos))
294+
self.consume_current_buffer();
295+
296+
Ok(buf)
304297
} else {
305298
error!(
306299
"RTL8192: invalid header {:#x}, rx_pos {}\n",
@@ -314,43 +307,22 @@ impl NetworkInterface for RTL8139Driver {
314307
}
315308
}
316309

317-
// Tells driver, that buffer is consumed and can be deallocated
318-
fn rx_buffer_consumed(&mut self, handle: usize) {
319-
if self.rxpos != handle {
320-
warn!("Invalid handle {} != {}", self.rxpos, handle)
321-
}
322-
323-
drop(self.box_map.remove(&self.rxpos));
324-
325-
let length = self.rx_peek_u16();
326-
self.advance_rxpos(usize::from(length) + mem::size_of::<u16>());
327-
328-
// packets are dword aligned
329-
self.rxpos = ((self.rxpos + 3) & !0x3) % RX_BUF_LEN;
330-
if self.rxpos >= 0x10 {
331-
unsafe {
332-
outw(self.iobase + CAPR, (self.rxpos - 0x10).try_into().unwrap());
333-
}
334-
} else {
335-
unsafe {
336-
outw(
337-
self.iobase + CAPR,
338-
(RX_BUF_LEN - (0x10 - self.rxpos)).try_into().unwrap(),
339-
);
340-
}
341-
}
342-
}
343-
344310
fn set_polling_mode(&mut self, value: bool) {
345311
if value {
346-
// disable interrupts from the NIC
347-
unsafe {
348-
outw(self.iobase + IMR, INT_MASK_NO_ROK);
312+
if self.polling_mode_counter == 0 {
313+
// disable interrupts from the NIC
314+
unsafe {
315+
outw(self.iobase + IMR, INT_MASK_NO_ROK);
316+
}
349317
}
318+
self.polling_mode_counter += 1;
350319
} else {
351-
// Enable all known interrupts by setting the interrupt mask.
352-
unsafe {
353-
outw(self.iobase + IMR, INT_MASK);
320+
self.polling_mode_counter -= 1;
321+
if self.polling_mode_counter == 0 {
322+
// Enable all known interrupts by setting the interrupt mask.
323+
unsafe {
324+
outw(self.iobase + IMR, INT_MASK);
325+
}
354326
}
355327
}
356328
}
@@ -390,6 +362,27 @@ impl NetworkInterface for RTL8139Driver {
390362
}
391363

392364
impl RTL8139Driver {
365+
// Tells driver, that buffer is consumed and can be deallocated
366+
fn consume_current_buffer(&mut self) {
367+
let length = self.rx_peek_u16();
368+
self.advance_rxpos(usize::from(length) + mem::size_of::<u16>());
369+
370+
// packets are dword aligned
371+
self.rxpos = ((self.rxpos + 3) & !0x3) % RX_BUF_LEN;
372+
if self.rxpos >= 0x10 {
373+
unsafe {
374+
outw(self.iobase + CAPR, (self.rxpos - 0x10).try_into().unwrap());
375+
}
376+
} else {
377+
unsafe {
378+
outw(
379+
self.iobase + CAPR,
380+
(RX_BUF_LEN - (0x10 - self.rxpos)).try_into().unwrap(),
381+
);
382+
}
383+
}
384+
}
385+
393386
fn rx_peek_u16(&self) -> u16 {
394387
u16::from_ne_bytes(
395388
self.rxbuffer[self.rxpos..][..mem::size_of::<u16>()]
@@ -611,6 +604,6 @@ pub fn init_device(adapter: &pci::PciAdapter) -> Result<RTL8139Driver, DriverErr
611604
rxbuffer,
612605
rxpos: 0,
613606
txbuffer,
614-
box_map: BTreeMap::new(),
607+
polling_mode_counter: 0,
615608
})
616609
}

src/drivers/net/virtio_mmio.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ impl VirtioNetDriver {
141141
),
142142
num_vqs: 0,
143143
irq,
144+
polling_mode_counter: 0,
144145
})
145146
}
146147

0 commit comments

Comments
 (0)