mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
Fix typos and add utils
This commit is contained in:
parent
b2f2c55c9b
commit
d96fe31e36
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -8,3 +8,7 @@ regression/apps/signal_c/signal_test filter=lfs diff=lfs merge=lfs -text
|
||||
regression/apps/busybox/busybox filter=lfs diff=lfs merge=lfs -text
|
||||
regression/apps/pthread/pthread_test filter=lfs diff=lfs merge=lfs -text
|
||||
regression/apps/hello_pie/hello filter=lfs diff=lfs merge=lfs -text
|
||||
regression/apps/network/tcp/client filter=lfs diff=lfs merge=lfs -text
|
||||
regression/apps/network/tcp/server filter=lfs diff=lfs merge=lfs -text
|
||||
regression/apps/network/udp/client filter=lfs diff=lfs merge=lfs -text
|
||||
regression/apps/network/udp/server filter=lfs diff=lfs merge=lfs -text
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -18,3 +18,6 @@ regression/ramdisk/build/
|
||||
|
||||
# qemu log file
|
||||
qemu.log
|
||||
|
||||
# packet dump file
|
||||
virtio-net.pcap
|
||||
|
137
Cargo.lock
generated
137
Cargo.lock
generated
@ -59,6 +59,15 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
|
||||
|
||||
[[package]]
|
||||
name = "atomic-polyfill"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
@ -145,6 +154,12 @@ dependencies = [
|
||||
name = "cpio-decoder"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "critical-section"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.15"
|
||||
@ -198,6 +213,38 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "956673bd3cb347512bf988d1e8d89ac9a82b64f6eec54d3c01c3529dac019882"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"defmt-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-macros"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4abc4821bd84d3d8f49945ddb24d029be9385ed9b77c99bf2f6296847a6a9f0"
|
||||
dependencies = [
|
||||
"defmt-parser",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-parser"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "269924c02afd7f94bc4cecbfa5c379f6ffcf9766b3408fe63d22c728654eccd0"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
@ -233,6 +280,15 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
@ -248,6 +304,19 @@ dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.7.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
|
||||
dependencies = [
|
||||
"atomic-polyfill",
|
||||
"hash32",
|
||||
"rustc_version",
|
||||
"spin 0.9.4",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
@ -461,6 +530,7 @@ dependencies = [
|
||||
"lru",
|
||||
"pod",
|
||||
"ringbuf",
|
||||
"smoltcp",
|
||||
"spin 0.9.4",
|
||||
"time",
|
||||
"typeflags",
|
||||
@ -495,6 +565,7 @@ dependencies = [
|
||||
name = "jinux-virtio"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"align_ext",
|
||||
"bitflags",
|
||||
"component",
|
||||
"int-to-c-enum",
|
||||
@ -568,6 +639,12 @@ dependencies = [
|
||||
"hashbrown 0.13.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "managed"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
@ -607,6 +684,30 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.56"
|
||||
@ -668,6 +769,15 @@ dependencies = [
|
||||
"wait-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.9"
|
||||
@ -680,6 +790,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
@ -695,6 +811,21 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smoltcp"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e9786ac45091b96f946693e05bfa4d8ca93e2d3341237d97a380107a6b38dea"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"cfg-if",
|
||||
"defmt",
|
||||
"heapless",
|
||||
"log",
|
||||
"managed",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
@ -719,6 +850,12 @@ dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
|
@ -7,6 +7,7 @@ input = { name = "jinux-input" }
|
||||
block = { name = "jinux-block" }
|
||||
time = { name = "jinux-time" }
|
||||
framebuffer = { name = "jinux-framebuffer" }
|
||||
network = { name = "jinux-network" }
|
||||
main = { name = "jinux" }
|
||||
|
||||
[whitelist]
|
||||
|
@ -3,6 +3,7 @@ pub mod hpet;
|
||||
pub mod pit;
|
||||
|
||||
use core::any::Any;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use alloc::{boxed::Box, collections::BinaryHeap, sync::Arc, vec::Vec};
|
||||
use spin::{Mutex, Once};
|
||||
@ -12,7 +13,7 @@ use crate::arch::x86::kernel;
|
||||
use crate::trap::IrqAllocateHandle;
|
||||
|
||||
pub const TIMER_IRQ_NUM: u8 = 32;
|
||||
pub static mut TICK: u64 = 0;
|
||||
pub static TICK: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
static TIMER_IRQ: Once<IrqAllocateHandle> = Once::new();
|
||||
|
||||
@ -30,11 +31,7 @@ pub fn init() {
|
||||
}
|
||||
|
||||
fn timer_callback(trap_frame: &TrapFrame) {
|
||||
let current_ms;
|
||||
unsafe {
|
||||
current_ms = TICK;
|
||||
TICK += 1;
|
||||
}
|
||||
let current_ms = TICK.fetch_add(1, Ordering::SeqCst);
|
||||
let mut timeout_list = TIMEOUT_LIST.get().unwrap().lock();
|
||||
let mut callbacks: Vec<Arc<TimerCallback>> = Vec::new();
|
||||
while let Some(t) = timeout_list.peek() {
|
||||
@ -121,10 +118,18 @@ where
|
||||
F: Fn(&TimerCallback) + Send + Sync + 'static,
|
||||
T: Any + Send + Sync,
|
||||
{
|
||||
unsafe {
|
||||
let timer_callback = TimerCallback::new(TICK + timeout, Arc::new(data), Box::new(callback));
|
||||
let timer_callback = TimerCallback::new(
|
||||
TICK.load(Ordering::SeqCst) + timeout,
|
||||
Arc::new(data),
|
||||
Box::new(callback),
|
||||
);
|
||||
let arc = Arc::new(timer_callback);
|
||||
TIMEOUT_LIST.get().unwrap().lock().push(arc.clone());
|
||||
arc
|
||||
}
|
||||
}
|
||||
|
||||
/// The time since the system boots up.
|
||||
/// The currently returned results are in milliseconds.
|
||||
pub fn read_monotonic_milli_seconds() -> u64 {
|
||||
TICK.load(Ordering::SeqCst)
|
||||
}
|
||||
|
@ -18,4 +18,4 @@ pub const KVA_START: usize = (usize::MAX) << PAGE_SIZE_BITS;
|
||||
|
||||
pub const DEFAULT_LOG_LEVEL: Level = Level::Error;
|
||||
/// This value represent the base timer frequency in Hz
|
||||
pub const TIMER_FREQ: u64 = 100;
|
||||
pub const TIMER_FREQ: u64 = 1000;
|
||||
|
@ -3,9 +3,12 @@
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::timer::{add_timeout_list, TimerCallback, TICK};
|
||||
use crate::{config::TIMER_FREQ, prelude::*};
|
||||
use core::time::Duration;
|
||||
use core::{sync::atomic::Ordering, time::Duration};
|
||||
use spin::Mutex;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use crate::arch::x86::timer::read_monotonic_milli_seconds;
|
||||
|
||||
/// A timer invokes a callback function after a specified span of time elapsed.
|
||||
///
|
||||
/// A new timer is initially inactive. Only after a timeout value is set with
|
||||
@ -63,10 +66,9 @@ impl Timer {
|
||||
}
|
||||
let tick_count =
|
||||
timeout.as_secs() * TIMER_FREQ + timeout.subsec_nanos() as u64 / NANOS_DIVIDE;
|
||||
unsafe {
|
||||
lock.start_tick = TICK;
|
||||
lock.timeout_tick = TICK + tick_count;
|
||||
}
|
||||
let tick = TICK.load(Ordering::SeqCst);
|
||||
lock.start_tick = tick;
|
||||
lock.timeout_tick = tick + tick_count;
|
||||
lock.timer_callback = Some(add_timeout_list(tick_count, self.clone(), timer_callback));
|
||||
}
|
||||
|
||||
@ -75,10 +77,10 @@ impl Timer {
|
||||
/// If the timer is not set, then the remaining timeout value is zero.
|
||||
pub fn remain(&self) -> Duration {
|
||||
let lock = self.inner.lock();
|
||||
let tick_remain;
|
||||
unsafe {
|
||||
tick_remain = lock.timeout_tick as i64 - TICK as i64;
|
||||
}
|
||||
let tick_remain = {
|
||||
let tick = TICK.load(Ordering::SeqCst) as i64;
|
||||
lock.timeout_tick as i64 - tick
|
||||
};
|
||||
if tick_remain <= 0 {
|
||||
Duration::new(0, 0)
|
||||
} else {
|
||||
|
@ -16,7 +16,7 @@ ifneq (, $(wildcard $(INITRAMFS)/. ))
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: all clean prepare_libs
|
||||
.PHONY: all clean prepare_libs copy_special_files
|
||||
|
||||
all: $(RAMDISK)
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
use jinux_frame::trap::TrapFrame;
|
||||
use jinux_pci::msix::MSIX;
|
||||
use jinux_util::frame_ptr::InFramePtr;
|
||||
use jinux_virtio::{device::block::device::BLKDevice, PCIVirtioDevice, VitrioPciCommonCfg};
|
||||
use jinux_virtio::{device::block::device::BLKDevice, PCIVirtioDevice, VirtioPciCommonCfg};
|
||||
use log::debug;
|
||||
use spin::Mutex;
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::{BlockDevice, BLK_COMPONENT};
|
||||
|
||||
pub struct VirtioBlockDevice {
|
||||
blk_device: Mutex<BLKDevice>,
|
||||
pub common_cfg: InFramePtr<VitrioPciCommonCfg>,
|
||||
pub common_cfg: InFramePtr<VirtioPciCommonCfg>,
|
||||
msix: MSIX,
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use jinux_frame::trap::TrapFrame;
|
||||
use jinux_pci::msix::MSIX;
|
||||
use jinux_util::frame_ptr::InFramePtr;
|
||||
use jinux_virtio::device::input::device::InputProp;
|
||||
use jinux_virtio::VitrioPciCommonCfg;
|
||||
use jinux_virtio::VirtioPciCommonCfg;
|
||||
use jinux_virtio::{
|
||||
device::input::{device::InputDevice, InputConfigSelect},
|
||||
PCIVirtioDevice,
|
||||
@ -18,7 +18,7 @@ use virtio_input_decoder::{DecodeType, Decoder};
|
||||
use crate::INPUTDevice;
|
||||
pub struct VirtioInputDevice {
|
||||
input_device: InputDevice,
|
||||
common_cfg: InFramePtr<VitrioPciCommonCfg>,
|
||||
common_cfg: InFramePtr<VirtioPciCommonCfg>,
|
||||
msix: Mutex<MSIX>,
|
||||
name: String,
|
||||
callbacks: Mutex<Vec<Arc<dyn Fn(DecodeType) + Send + Sync + 'static>>>,
|
||||
@ -57,7 +57,7 @@ impl VirtioInputDevice {
|
||||
let mut msix = virtio_device.msix;
|
||||
|
||||
let config_msix_vector =
|
||||
common_cfg.read_at(offset_of!(VitrioPciCommonCfg, config_msix_vector)) as usize;
|
||||
common_cfg.read_at(offset_of!(VirtioPciCommonCfg, config_msix_vector)) as usize;
|
||||
|
||||
let mut event_irq_number = 0;
|
||||
for i in 0..msix.table_size as usize {
|
||||
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||
[dependencies]
|
||||
bitflags = "1.3"
|
||||
spin = "0.9.4"
|
||||
align_ext = { path = "../../../framework/libs/align_ext" }
|
||||
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||
jinux-pci = { path = "../pci" }
|
||||
jinux-util = { path = "../../libs/jinux-util" }
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
device::block::{BlkReq, BlkResp, ReqType, RespStatus, BLK_SIZE},
|
||||
device::VirtioDeviceError,
|
||||
queue::{QueueError, VirtQueue},
|
||||
VitrioPciCommonCfg,
|
||||
VirtioPciCommonCfg,
|
||||
};
|
||||
|
||||
use super::{BLKFeatures, VirtioBLKConfig};
|
||||
@ -27,13 +27,13 @@ impl BLKDevice {
|
||||
pub(crate) fn new(
|
||||
cap: &CapabilityVirtioData,
|
||||
bars: [Option<BAR>; 6],
|
||||
common_cfg: &InFramePtr<VitrioPciCommonCfg>,
|
||||
common_cfg: &InFramePtr<VirtioPciCommonCfg>,
|
||||
notify_base_address: usize,
|
||||
notify_off_multiplier: u32,
|
||||
mut msix_vector_left: Vec<u16>,
|
||||
) -> Result<Self, VirtioDeviceError> {
|
||||
let config = VirtioBLKConfig::new(cap, bars);
|
||||
let num_queues = common_cfg.read_at(offset_of!(VitrioPciCommonCfg, num_queues)) as u16;
|
||||
let num_queues = common_cfg.read_at(offset_of!(VirtioPciCommonCfg, num_queues)) as u16;
|
||||
if num_queues != 1 {
|
||||
return Err(VirtioDeviceError::QueuesAmountDoNotMatch(num_queues, 1));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{device::VirtioDeviceError, queue::VirtQueue, VitrioPciCommonCfg};
|
||||
use crate::{device::VirtioDeviceError, queue::VirtQueue, VirtioPciCommonCfg};
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use bitflags::bitflags;
|
||||
use jinux_frame::offset_of;
|
||||
@ -56,7 +56,7 @@ impl InputDevice {
|
||||
pub fn new(
|
||||
cap: &CapabilityVirtioData,
|
||||
bars: [Option<BAR>; 6],
|
||||
common_cfg: &InFramePtr<VitrioPciCommonCfg>,
|
||||
common_cfg: &InFramePtr<VirtioPciCommonCfg>,
|
||||
notify_base_address: usize,
|
||||
notify_off_multiplier: u32,
|
||||
mut msix_vector_left: Vec<u16>,
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::{device::block::device::BLKDevice, Feature, VirtioDeviceType, VitrioPciCommonCfg};
|
||||
use crate::{
|
||||
device::block::device::BLKDevice, queue::QueueError, Feature, VirtioDeviceType,
|
||||
VirtioPciCommonCfg,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use jinux_pci::{
|
||||
capability::{vendor::virtio::CapabilityVirtioData, Capability},
|
||||
@ -43,11 +46,17 @@ pub enum VirtioDeviceError {
|
||||
CapabilityListError,
|
||||
}
|
||||
|
||||
impl From<QueueError> for VirtioDeviceError {
|
||||
fn from(_: QueueError) -> Self {
|
||||
VirtioDeviceError::QueueUnknownError
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VirtioInfo {
|
||||
pub device_type: VirtioDeviceType,
|
||||
pub notify_base_address: u64,
|
||||
pub notify_off_multiplier: u32,
|
||||
pub common_cfg_frame_ptr: InFramePtr<VitrioPciCommonCfg>,
|
||||
pub common_cfg_frame_ptr: InFramePtr<VirtioPciCommonCfg>,
|
||||
pub device_cap_cfg: CapabilityVirtioData,
|
||||
}
|
||||
|
||||
@ -68,7 +77,7 @@ impl VirtioInfo {
|
||||
match cap_data.cfg_type {
|
||||
PCI_VIRTIO_CAP_COMMON_CFG => {
|
||||
common_cfg_frame_ptr_some =
|
||||
Some(VitrioPciCommonCfg::new(&cap_data, bars));
|
||||
Some(VirtioPciCommonCfg::new(&cap_data, bars));
|
||||
}
|
||||
PCI_VIRTIO_CAP_NOTIFY_CFG => {
|
||||
notify_off_multiplier = cap_data.option.unwrap();
|
||||
@ -140,7 +149,8 @@ impl VirtioDevice {
|
||||
}
|
||||
|
||||
pub(crate) fn negotiate_features(features: u64, device_type: VirtioDeviceType) -> u64 {
|
||||
let device_specified_features = features & ((1 << 24) - 1);
|
||||
let mask = ((1u64 << 24) - 1) | (((1u64 << 24) - 1) << 50);
|
||||
let device_specified_features = features & mask;
|
||||
let device_support_features = match device_type {
|
||||
VirtioDeviceType::Network => todo!(),
|
||||
VirtioDeviceType::Block => BLKDevice::negotiate_features(device_specified_features),
|
||||
|
@ -119,7 +119,7 @@ bitflags! {
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// all device features, bits 0~23 are sepecified by device
|
||||
/// all device features, bits 0~23 and 50~63 are sepecified by device.
|
||||
/// if using this struct to translate u64, use from_bits_truncate function instead of from_bits
|
||||
///
|
||||
struct Feature: u64 {
|
||||
@ -144,7 +144,7 @@ bitflags! {
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct VitrioPciCommonCfg {
|
||||
pub struct VirtioPciCommonCfg {
|
||||
device_feature_select: u32,
|
||||
device_feature: u32,
|
||||
driver_feature_select: u32,
|
||||
@ -164,7 +164,7 @@ pub struct VitrioPciCommonCfg {
|
||||
queue_device: u64,
|
||||
}
|
||||
|
||||
impl VitrioPciCommonCfg {
|
||||
impl VirtioPciCommonCfg {
|
||||
pub(crate) fn new(cap: &CapabilityVirtioData, bars: [Option<BAR>; 6]) -> InFramePtr<Self> {
|
||||
let bar = cap.bar;
|
||||
let offset = cap.offset;
|
||||
@ -219,7 +219,7 @@ impl VirtioDeviceType {
|
||||
|
||||
pub struct PCIVirtioDevice {
|
||||
/// common config of one device
|
||||
pub common_cfg: InFramePtr<VitrioPciCommonCfg>,
|
||||
pub common_cfg: InFramePtr<VirtioPciCommonCfg>,
|
||||
pub device: VirtioDevice,
|
||||
pub msix: MSIX,
|
||||
}
|
||||
@ -269,35 +269,35 @@ impl PCIVirtioDevice {
|
||||
let common_cfg_frame_ptr = &virtio_info.common_cfg_frame_ptr;
|
||||
|
||||
// Reset device
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, device_status), 0 as u8);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, device_status), 0 as u8);
|
||||
|
||||
let num_queues: u16 =
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, num_queues));
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, num_queues));
|
||||
debug!("num_queues:{:x}", num_queues);
|
||||
// the table size of msix should be equal to n+1 or 2 where n is the virtqueue amount
|
||||
assert!(msix.table_size == 2 || msix.table_size == (num_queues + 1));
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, config_msix_vector),
|
||||
offset_of!(VirtioPciCommonCfg, config_msix_vector),
|
||||
config_msix_vector,
|
||||
);
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_status),
|
||||
offset_of!(VirtioPciCommonCfg, device_status),
|
||||
(DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER).bits(),
|
||||
);
|
||||
// negotiate features
|
||||
// get the value of device features
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_feature_select),
|
||||
offset_of!(VirtioPciCommonCfg, device_feature_select),
|
||||
0 as u32,
|
||||
);
|
||||
let mut low: u32 =
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, device_feature));
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, device_feature));
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_feature_select),
|
||||
offset_of!(VirtioPciCommonCfg, device_feature_select),
|
||||
1 as u32,
|
||||
);
|
||||
let mut high: u32 =
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VitrioPciCommonCfg, device_feature));
|
||||
common_cfg_frame_ptr.read_at(offset_of!(VirtioPciCommonCfg, device_feature));
|
||||
let mut feature = (high as u64) << 32;
|
||||
feature |= low as u64;
|
||||
// let the device to negotiate Features
|
||||
@ -307,26 +307,26 @@ impl PCIVirtioDevice {
|
||||
low = driver_features as u32;
|
||||
high = (driver_features >> 32) as u32;
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, driver_feature_select),
|
||||
offset_of!(VirtioPciCommonCfg, driver_feature_select),
|
||||
0 as u32,
|
||||
);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, driver_feature), low);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, driver_feature), low);
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, driver_feature_select),
|
||||
offset_of!(VirtioPciCommonCfg, driver_feature_select),
|
||||
1 as u32,
|
||||
);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VitrioPciCommonCfg, driver_feature), high);
|
||||
common_cfg_frame_ptr.write_at(offset_of!(VirtioPciCommonCfg, driver_feature), high);
|
||||
|
||||
// change to features ok status
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_status),
|
||||
offset_of!(VirtioPciCommonCfg, device_status),
|
||||
(DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER | DeviceStatus::FEATURES_OK).bits(),
|
||||
);
|
||||
let device = VirtioDevice::new(&virtio_info, bars, msix_vector_list).unwrap();
|
||||
|
||||
// change to driver ok status
|
||||
common_cfg_frame_ptr.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, device_status),
|
||||
offset_of!(VirtioPciCommonCfg, device_status),
|
||||
(DeviceStatus::ACKNOWLEDGE
|
||||
| DeviceStatus::DRIVER
|
||||
| DeviceStatus::FEATURES_OK
|
||||
@ -351,7 +351,7 @@ impl PCIVirtioDevice {
|
||||
{
|
||||
let config_msix_vector =
|
||||
self.common_cfg
|
||||
.read_at(offset_of!(VitrioPciCommonCfg, config_msix_vector)) as usize;
|
||||
.read_at(offset_of!(VirtioPciCommonCfg, config_msix_vector)) as usize;
|
||||
for i in 0..self.msix.table_size as usize {
|
||||
let msix = self.msix.table.get_mut(i).unwrap();
|
||||
if !msix.irq_handle.is_empty() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Virtqueue
|
||||
|
||||
use super::VitrioPciCommonCfg;
|
||||
use super::VirtioPciCommonCfg;
|
||||
use alloc::vec::Vec;
|
||||
use bitflags::bitflags;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
@ -55,29 +55,29 @@ pub struct VirtQueue {
|
||||
impl VirtQueue {
|
||||
/// Create a new VirtQueue.
|
||||
pub(crate) fn new(
|
||||
cfg: &InFramePtr<VitrioPciCommonCfg>,
|
||||
cfg: &InFramePtr<VirtioPciCommonCfg>,
|
||||
idx: usize,
|
||||
size: u16,
|
||||
notify_base_address: usize,
|
||||
notify_off_multiplier: u32,
|
||||
msix_vector: u16,
|
||||
) -> Result<Self, QueueError> {
|
||||
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_select), idx as u16);
|
||||
cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_select), idx as u16);
|
||||
assert_eq!(
|
||||
cfg.read_at(offset_of!(VitrioPciCommonCfg, queue_select)),
|
||||
cfg.read_at(offset_of!(VirtioPciCommonCfg, queue_select)),
|
||||
idx as u16
|
||||
);
|
||||
if !size.is_power_of_two() {
|
||||
return Err(QueueError::InvalidArgs);
|
||||
}
|
||||
|
||||
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_size), size);
|
||||
cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_size), size);
|
||||
cfg.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, queue_msix_vector),
|
||||
offset_of!(VirtioPciCommonCfg, queue_msix_vector),
|
||||
msix_vector,
|
||||
);
|
||||
assert_eq!(
|
||||
cfg.read_at(offset_of!(VitrioPciCommonCfg, queue_msix_vector)),
|
||||
cfg.read_at(offset_of!(VirtioPciCommonCfg, queue_msix_vector)),
|
||||
msix_vector
|
||||
);
|
||||
|
||||
@ -109,17 +109,17 @@ impl VirtQueue {
|
||||
debug!("queue_device start paddr:{:x?}", used_frame_ptr.paddr());
|
||||
|
||||
cfg.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, queue_desc),
|
||||
offset_of!(VirtioPciCommonCfg, queue_desc),
|
||||
desc_frame_ptr.paddr() as u64,
|
||||
);
|
||||
|
||||
cfg.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, queue_driver),
|
||||
offset_of!(VirtioPciCommonCfg, queue_driver),
|
||||
avail_frame_ptr.paddr() as u64,
|
||||
);
|
||||
|
||||
cfg.write_at(
|
||||
offset_of!(VitrioPciCommonCfg, queue_device),
|
||||
offset_of!(VirtioPciCommonCfg, queue_device),
|
||||
used_frame_ptr.paddr() as u64,
|
||||
);
|
||||
|
||||
@ -137,7 +137,7 @@ impl VirtQueue {
|
||||
temp.write_at(offset_of!(Descriptor, next), i + 1);
|
||||
}
|
||||
avail_frame_ptr.write_at(offset_of!(AvailRing, flags), 0 as u16);
|
||||
cfg.write_at(offset_of!(VitrioPciCommonCfg, queue_enable), 1 as u16);
|
||||
cfg.write_at(offset_of!(VirtioPciCommonCfg, queue_enable), 1 as u16);
|
||||
Ok(VirtQueue {
|
||||
descs,
|
||||
avail: avail_frame_ptr,
|
||||
@ -305,6 +305,14 @@ impl VirtQueue {
|
||||
self.queue_size
|
||||
}
|
||||
|
||||
/// whether the driver should notify the device
|
||||
pub fn should_notify(&self) -> bool {
|
||||
// read barrier
|
||||
fence(Ordering::SeqCst);
|
||||
let flags = self.used.read_at(offset_of!(UsedRing, flags));
|
||||
flags & 0x0001u16 == 0u16
|
||||
}
|
||||
|
||||
/// notify that there are available rings
|
||||
pub fn notify(&mut self) {
|
||||
self.notify
|
||||
|
@ -163,6 +163,7 @@ fn match_and_call(
|
||||
}
|
||||
|
||||
infos.sort();
|
||||
debug!("component infos: {infos:?}");
|
||||
info!("Components initializing...");
|
||||
|
||||
for i in infos {
|
||||
|
@ -24,6 +24,7 @@ virtio-input-decoder = "0.1.4"
|
||||
ascii = { version = "1.1", default-features = false, features = ["alloc"] }
|
||||
intrusive-collections = "0.9.5"
|
||||
time = { version = "0.3", default-features = false, features = ["alloc"] }
|
||||
smoltcp = { version = "0.9.1", default-features = false, features = ["alloc", "log", "medium-ethernet", "medium-ip", "proto-dhcpv4", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw", "socket-dhcpv4"] }
|
||||
|
||||
# parse elf file
|
||||
xmas-elf = "0.8.0"
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use crate::events::Observer;
|
||||
use crate::fs::utils::{AccessMode, IoEvents, IoctlCmd, Metadata, Poller, SeekFrom, StatusFlags};
|
||||
use crate::net::socket::Socket;
|
||||
use crate::prelude::*;
|
||||
|
||||
use core::any::Any;
|
||||
@ -67,6 +68,10 @@ pub trait FileLike: Send + Sync + Any {
|
||||
) -> Result<Weak<dyn Observer<IoEvents>>> {
|
||||
return_errno_with_message!(Errno::EINVAL, "unregister_observer is not supported")
|
||||
}
|
||||
|
||||
fn as_socket(&self) -> Option<&dyn Socket> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn FileLike {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::events::{Events, Observer, Subject};
|
||||
use crate::net::socket::Socket;
|
||||
use crate::prelude::*;
|
||||
|
||||
use core::cell::Cell;
|
||||
@ -101,6 +102,12 @@ impl FileTable {
|
||||
.ok_or(Error::with_message(Errno::EBADF, "fd not exits"))
|
||||
}
|
||||
|
||||
pub fn get_socket(&self, sockfd: FileDescripter) -> Result<&dyn Socket> {
|
||||
self.get_file(sockfd)?
|
||||
.as_socket()
|
||||
.ok_or_else(|| Error::with_message(Errno::ENOTSOCK, "the fd is not a socket"))
|
||||
}
|
||||
|
||||
pub fn get_entry(&self, fd: FileDescripter) -> Result<&FileTableEntry> {
|
||||
self.table
|
||||
.get(fd as usize)
|
||||
|
@ -8,6 +8,7 @@ use keyable_arc::KeyableWeak;
|
||||
|
||||
/// A pollee maintains a set of active events, which can be polled with
|
||||
/// pollers or be monitored with observers.
|
||||
#[derive(Clone)]
|
||||
pub struct Pollee {
|
||||
inner: Arc<PolleeInner>,
|
||||
}
|
||||
|
@ -16,14 +16,17 @@
|
||||
#![feature(specialization)]
|
||||
#![feature(fn_traits)]
|
||||
#![feature(linked_list_remove)]
|
||||
#![feature(trait_alias)]
|
||||
#![feature(register_tool)]
|
||||
#![feature(trait_upcasting)]
|
||||
#![register_tool(component_access_control)]
|
||||
|
||||
use crate::{
|
||||
prelude::*,
|
||||
process::status::ProcessStatus,
|
||||
thread::{kernel_thread::KernelThreadExt, Thread},
|
||||
};
|
||||
use jinux_frame::exit_qemu;
|
||||
use process::Process;
|
||||
|
||||
extern crate alloc;
|
||||
@ -36,6 +39,7 @@ pub mod driver;
|
||||
pub mod error;
|
||||
pub mod events;
|
||||
pub mod fs;
|
||||
pub mod net;
|
||||
pub mod prelude;
|
||||
mod process;
|
||||
pub mod syscall;
|
||||
@ -46,6 +50,7 @@ pub mod vm;
|
||||
|
||||
pub fn init(ramdisk: &[u8]) {
|
||||
driver::init();
|
||||
net::init();
|
||||
process::fifo_scheduler::init();
|
||||
fs::initramfs::init(ramdisk).unwrap();
|
||||
device::init().unwrap();
|
||||
@ -56,6 +61,7 @@ fn init_thread() {
|
||||
"[kernel] Spawn init thread, tid = {}",
|
||||
current_thread!().tid()
|
||||
);
|
||||
net::lazy_init();
|
||||
// driver::pci::virtio::block::block_device_test();
|
||||
let thread = Thread::spawn_kernel_thread(|| {
|
||||
println!("[kernel] Hello world from kernel!");
|
||||
@ -70,9 +76,14 @@ fn init_thread() {
|
||||
);
|
||||
|
||||
print_banner();
|
||||
run_busybox().expect("run busybox fails");
|
||||
let busybox = run_busybox().expect("run busybox fails");
|
||||
|
||||
loop {
|
||||
// If busybox becomes zombie, then exit qemu.
|
||||
if *busybox.status().lock() == ProcessStatus::Zombie {
|
||||
println!("Exit jinux.");
|
||||
exit_qemu(jinux_frame::QemuExitCode::Success);
|
||||
}
|
||||
// We don't have preemptive scheduler now.
|
||||
// The long running init thread should yield its own execution to allow other tasks to go on.
|
||||
Thread::yield_now();
|
||||
|
@ -17,12 +17,13 @@ pub(crate) use core::any::Any;
|
||||
pub(crate) use core::ffi::CStr;
|
||||
pub(crate) use int_to_c_enum::TryFromInt;
|
||||
pub(crate) use jinux_frame::config::PAGE_SIZE;
|
||||
pub(crate) use jinux_frame::sync::{Mutex, MutexGuard};
|
||||
// pub(crate) use jinux_frame::sync::{Mutex, MutexGuard};
|
||||
pub(crate) use jinux_frame::vm::Vaddr;
|
||||
pub(crate) use jinux_frame::{print, println};
|
||||
pub(crate) use log::{debug, error, info, trace, warn};
|
||||
pub(crate) use pod::Pod;
|
||||
pub(crate) use spin::RwLock;
|
||||
pub(crate) use spin::{Mutex, MutexGuard};
|
||||
|
||||
/// return current process
|
||||
#[macro_export]
|
||||
|
@ -69,16 +69,30 @@ use crate::syscall::write::sys_write;
|
||||
use crate::syscall::writev::sys_writev;
|
||||
use jinux_frame::cpu::UserContext;
|
||||
|
||||
use self::accept::sys_accept;
|
||||
use self::bind::sys_bind;
|
||||
use self::connect::sys_connect;
|
||||
use self::getpeername::sys_getpeername;
|
||||
use self::getsockname::sys_getsockname;
|
||||
use self::listen::sys_listen;
|
||||
use self::pread64::sys_pread64;
|
||||
use self::recvfrom::sys_recvfrom;
|
||||
use self::sendto::sys_sendto;
|
||||
use self::setsockopt::sys_setsockopt;
|
||||
use self::shutdown::sys_shutdown;
|
||||
use self::socket::sys_socket;
|
||||
|
||||
mod accept;
|
||||
mod access;
|
||||
mod arch_prctl;
|
||||
mod bind;
|
||||
mod brk;
|
||||
mod chdir;
|
||||
mod clock_gettime;
|
||||
mod clock_nanosleep;
|
||||
mod clone;
|
||||
mod close;
|
||||
mod connect;
|
||||
mod constants;
|
||||
mod dup;
|
||||
mod epoll;
|
||||
@ -93,15 +107,18 @@ mod getdents64;
|
||||
mod getegid;
|
||||
mod geteuid;
|
||||
mod getgid;
|
||||
mod getpeername;
|
||||
mod getpgrp;
|
||||
mod getpid;
|
||||
mod getppid;
|
||||
mod getsockname;
|
||||
mod gettid;
|
||||
mod gettimeofday;
|
||||
mod getuid;
|
||||
mod ioctl;
|
||||
mod kill;
|
||||
mod link;
|
||||
mod listen;
|
||||
mod lseek;
|
||||
mod madvise;
|
||||
mod mkdir;
|
||||
@ -117,6 +134,7 @@ mod pread64;
|
||||
mod prlimit64;
|
||||
mod read;
|
||||
mod readlink;
|
||||
mod recvfrom;
|
||||
mod rename;
|
||||
mod rmdir;
|
||||
mod rt_sigaction;
|
||||
@ -124,9 +142,13 @@ mod rt_sigprocmask;
|
||||
mod rt_sigreturn;
|
||||
mod sched_yield;
|
||||
mod select;
|
||||
mod sendto;
|
||||
mod set_robust_list;
|
||||
mod set_tid_address;
|
||||
mod setpgid;
|
||||
mod setsockopt;
|
||||
mod shutdown;
|
||||
mod socket;
|
||||
mod stat;
|
||||
mod symlink;
|
||||
mod tgkill;
|
||||
@ -199,6 +221,17 @@ define_syscall_nums!(
|
||||
SYS_DUP2 = 33,
|
||||
SYS_PAUSE = 34,
|
||||
SYS_GETPID = 39,
|
||||
SYS_SOCKET = 41,
|
||||
SYS_CONNECT = 42,
|
||||
SYS_ACCEPT = 43,
|
||||
SYS_SENDTO = 44,
|
||||
SYS_RECVFROM = 45,
|
||||
SYS_SHUTDOWN = 48,
|
||||
SYS_BIND = 49,
|
||||
SYS_LISTEN = 50,
|
||||
SYS_GETSOCKNAME = 51,
|
||||
SYS_GETPEERNAME = 52,
|
||||
SYS_SETSOCKOPT = 54,
|
||||
SYS_CLONE = 56,
|
||||
SYS_FORK = 57,
|
||||
SYS_EXECVE = 59,
|
||||
@ -340,6 +373,17 @@ pub fn syscall_dispatch(
|
||||
SYS_DUP2 => syscall_handler!(2, sys_dup2, args),
|
||||
SYS_PAUSE => syscall_handler!(0, sys_pause),
|
||||
SYS_GETPID => syscall_handler!(0, sys_getpid),
|
||||
SYS_SOCKET => syscall_handler!(3, sys_socket, args),
|
||||
SYS_CONNECT => syscall_handler!(3, sys_connect, args),
|
||||
SYS_ACCEPT => syscall_handler!(3, sys_accept, args),
|
||||
SYS_SENDTO => syscall_handler!(6, sys_sendto, args),
|
||||
SYS_RECVFROM => syscall_handler!(6, sys_recvfrom, args),
|
||||
SYS_SHUTDOWN => syscall_handler!(2, sys_shutdown, args),
|
||||
SYS_BIND => syscall_handler!(3, sys_bind, args),
|
||||
SYS_LISTEN => syscall_handler!(2, sys_listen, args),
|
||||
SYS_GETSOCKNAME => syscall_handler!(3, sys_getsockname, args),
|
||||
SYS_GETPEERNAME => syscall_handler!(3, sys_getpeername, args),
|
||||
SYS_SETSOCKOPT => syscall_handler!(5, sys_setsockopt, args),
|
||||
SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()),
|
||||
SYS_FORK => syscall_handler!(0, sys_fork, context.clone()),
|
||||
SYS_EXECVE => syscall_handler!(3, sys_execve, args, context),
|
||||
|
@ -1,5 +1,10 @@
|
||||
use crate::prelude::*;
|
||||
use crate::{
|
||||
net::socket::SocketAddr,
|
||||
prelude::*,
|
||||
util::net::{InAddr, SaFamily, SockAddr, SockAddrIn, SockAddrIn6, SockAddrUn},
|
||||
};
|
||||
use jinux_frame::vm::VmIo;
|
||||
pub mod net;
|
||||
|
||||
/// copy bytes from user space of current process. The bytes len is the len of dest.
|
||||
pub fn read_bytes_from_user(src: Vaddr, dest: &mut [u8]) -> Result<()> {
|
||||
@ -35,3 +40,51 @@ pub fn read_cstring_from_user(addr: Vaddr, max_len: usize) -> Result<CString> {
|
||||
read_bytes_from_user(addr, &mut buffer)?;
|
||||
Ok(CString::from(CStr::from_bytes_until_nul(&buffer)?))
|
||||
}
|
||||
|
||||
pub fn read_socket_addr_from_user(addr: Vaddr, addr_len: usize) -> Result<SocketAddr> {
|
||||
debug_assert!(addr_len >= core::mem::size_of::<SockAddr>());
|
||||
let sockaddr: SockAddr = read_val_from_user(addr)?;
|
||||
let socket_addr = match sockaddr.sa_family()? {
|
||||
SaFamily::AF_UNSPEC => {
|
||||
return_errno_with_message!(Errno::EINVAL, "the socket addr family is unspecified")
|
||||
}
|
||||
SaFamily::AF_UNIX => {
|
||||
debug_assert!(addr_len >= core::mem::size_of::<SockAddrUn>());
|
||||
let sock_addr_un: SockAddrUn = read_val_from_user(addr)?;
|
||||
todo!()
|
||||
}
|
||||
SaFamily::AF_INET => {
|
||||
debug_assert!(addr_len >= core::mem::size_of::<SockAddrIn>());
|
||||
let sock_addr_in: SockAddrIn = read_val_from_user(addr)?;
|
||||
SocketAddr::from(sock_addr_in)
|
||||
}
|
||||
SaFamily::AF_INET6 => {
|
||||
debug_assert!(addr_len >= core::mem::size_of::<SockAddrIn6>());
|
||||
let sock_addr_in6: SockAddrIn6 = read_val_from_user(addr)?;
|
||||
todo!()
|
||||
}
|
||||
_ => {
|
||||
return_errno_with_message!(Errno::EAFNOSUPPORT, "cannot support address for the family")
|
||||
}
|
||||
};
|
||||
Ok(socket_addr)
|
||||
}
|
||||
|
||||
pub fn write_socket_addr_to_user(
|
||||
socket_addr: &SocketAddr,
|
||||
dest: Vaddr,
|
||||
max_len: usize,
|
||||
) -> Result<usize> {
|
||||
match socket_addr {
|
||||
SocketAddr::Unix => todo!(),
|
||||
SocketAddr::IPv4(addr, port) => {
|
||||
let in_addr = InAddr::from(*addr);
|
||||
let sock_addr_in = SockAddrIn::new(*port, in_addr);
|
||||
let write_size = core::mem::size_of::<SockAddrIn>();
|
||||
debug_assert!(max_len >= write_size);
|
||||
write_val_to_user(dest, &sock_addr_in)?;
|
||||
Ok(write_size)
|
||||
}
|
||||
SocketAddr::IPv6 => todo!(),
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
extern crate alloc;
|
||||
|
||||
use core::fmt::Debug;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use alloc::sync::Arc;
|
||||
@ -16,15 +17,30 @@ enum InFramePtrAccessMethod {
|
||||
VmFrame(Arc<VmFrame>),
|
||||
}
|
||||
|
||||
impl InFramePtrAccessMethod {
|
||||
fn read_val<T: Pod>(&self, offset: usize) -> Result<T> {
|
||||
match self {
|
||||
InFramePtrAccessMethod::Mmio(mmio) => mmio.read_val(offset),
|
||||
InFramePtrAccessMethod::VmFrame(frame) => frame.read_val(offset),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An in-frame pointer to a POD value, enabling safe access
|
||||
/// to a POD value given its physical memory address.
|
||||
#[derive(Debug)]
|
||||
pub struct InFramePtr<T: 'static> {
|
||||
access_method: InFramePtrAccessMethod,
|
||||
offset: usize,
|
||||
marker: PhantomData<&'static mut T>,
|
||||
}
|
||||
|
||||
impl<T: Debug + Pod + 'static> Debug for InFramePtr<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let inner = self.access_method.read_val::<T>(self.offset).unwrap();
|
||||
f.write_fmt(format_args!("{:?}", inner))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Pod> InFramePtr<T> {
|
||||
/// This function only allow the physical address in the MMIO region.
|
||||
///
|
||||
@ -49,6 +65,12 @@ impl<T: Pod> InFramePtr<T> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn read(&self) -> T {
|
||||
self.access_method
|
||||
.read_val::<T>(self.offset)
|
||||
.expect("read inner from frame failed")
|
||||
}
|
||||
|
||||
pub fn read_at<F: Pod>(&self, offset: *const F) -> F {
|
||||
match &self.access_method {
|
||||
InFramePtrAccessMethod::Mmio(mmio) => mmio
|
||||
|
Loading…
x
Reference in New Issue
Block a user