diff --git a/.gitignore b/.gitignore index 021a507..b2b7748 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ build target /kernel/src/arch/x86_64/interrupt/vector.asm +/kernel/src/arch/mipsel/boot/linker.ld *.gen.s *.dtb diff --git a/crate/memory/src/cow.rs b/crate/memory/src/cow.rs index 2ee6b10..26b6948 100644 --- a/crate/memory/src/cow.rs +++ b/crate/memory/src/cow.rs @@ -109,8 +109,8 @@ impl CowExt { self.rc_map.write_decrease(&frame); return true; } - use core::mem::uninitialized; - let mut temp_data: [u8; PAGE_SIZE] = unsafe { uninitialized() }; + use core::mem::MaybeUninit; + let mut temp_data: [u8; PAGE_SIZE] = unsafe { MaybeUninit::uninitialized().into_initialized() }; temp_data[..].copy_from_slice(self.get_page_slice_mut(addr)); self.unmap_shared(addr); diff --git a/crate/memory/src/lib.rs b/crate/memory/src/lib.rs index 61aef37..2b68ad0 100644 --- a/crate/memory/src/lib.rs +++ b/crate/memory/src/lib.rs @@ -1,6 +1,7 @@ #![cfg_attr(not(test), no_std)] #![feature(alloc)] #![feature(nll)] +#![feature(maybe_uninit)] // import macros from log use log::*; diff --git a/crate/memory/src/paging/mock_page_table.rs b/crate/memory/src/paging/mock_page_table.rs index 6395325..525d56c 100644 --- a/crate/memory/src/paging/mock_page_table.rs +++ b/crate/memory/src/paging/mock_page_table.rs @@ -144,10 +144,10 @@ impl MockPageTable { ** @retval MockPageTable the mock page table created */ pub fn new() -> Self { - use core::mem::uninitialized; + use core::mem::MaybeUninit; MockPageTable { entries: [MockEntry::default(); PAGE_COUNT], - data: unsafe { uninitialized() }, + data: unsafe { MaybeUninit::uninitialized().into_initialized() }, page_fault_handler: None, } } diff --git a/crate/memory/src/swap/mock_swapper.rs b/crate/memory/src/swap/mock_swapper.rs index 74564c0..ec71c39 100644 --- a/crate/memory/src/swap/mock_swapper.rs +++ b/crate/memory/src/swap/mock_swapper.rs @@ -5,7 +5,7 @@ use super::Swapper; use alloc::collections::BTreeMap; -use core::mem::uninitialized; +use core::mem::MaybeUninit; const PAGE_SIZE: usize = 4096; @@ -17,7 +17,7 @@ pub struct MockSwapper { impl Swapper for MockSwapper { fn swap_out(&mut self, data: &[u8]) -> Result { let id = self.alloc_id(); - let mut slice: [u8; PAGE_SIZE] = unsafe { uninitialized() }; + let mut slice: [u8; PAGE_SIZE] = unsafe { MaybeUninit::uninitialized().into_initialized() }; slice.copy_from_slice(data); self.map.insert(id, slice); Ok(id) @@ -27,7 +27,7 @@ impl Swapper for MockSwapper { if !self.map.contains_key(&token) { return Err(()); } - let mut slice: [u8; PAGE_SIZE] = unsafe { uninitialized() }; + let mut slice: [u8; PAGE_SIZE] = unsafe { MaybeUninit::uninitialized().into_initialized() }; slice.copy_from_slice(data); self.map.insert(token, slice); Ok(()) @@ -64,8 +64,8 @@ mod test { #[test] fn swap_out_in() { let mut swapper = MockSwapper::default(); - let mut data: [u8; 4096] = unsafe { uninitialized() }; - let data1: [u8; 4096] = unsafe { uninitialized() }; + let mut data: [u8; 4096] = unsafe { MaybeUninit::uninitialized().into_initialized() }; + let data1: [u8; 4096] = unsafe { MaybeUninit::uninitialized().into_initialized() }; let token = swapper.swap_out(&data1).unwrap(); swapper.swap_in(token, &mut data).unwrap(); assert_data_eq(&data, &data1); @@ -74,9 +74,9 @@ mod test { #[test] fn swap_update() { let mut swapper = MockSwapper::default(); - let mut data: [u8; 4096] = unsafe { uninitialized() }; - let data1: [u8; 4096] = unsafe { uninitialized() }; - let data2: [u8; 4096] = unsafe { uninitialized() }; + let mut data: [u8; 4096] = unsafe { MaybeUninit::uninitialized().into_initialized() }; + let data1: [u8; 4096] = unsafe { MaybeUninit::uninitialized().into_initialized() }; + let data2: [u8; 4096] = unsafe { MaybeUninit::uninitialized().into_initialized() }; let token = swapper.swap_out(&data1).unwrap(); swapper.swap_update(token, &data2).unwrap(); swapper.swap_in(token, &mut data).unwrap(); @@ -86,7 +86,7 @@ mod test { #[test] fn invalid_token() { let mut swapper = MockSwapper::default(); - let mut data: [u8; 4096] = unsafe { uninitialized() }; + let mut data: [u8; 4096] = unsafe { MaybeUninit::uninitialized().into_initialized() }; assert_eq!(swapper.swap_in(0, &mut data), Err(())); } } diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 39fb38c..f2b38df 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -82,8 +82,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitvec" -version = "0.11.0" -source = "git+https://github.com/myrrlyn/bitvec.git#8ab20a3e33fe068fc3a4a05eda1211d5fcc1237b" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootloader" @@ -377,7 +377,7 @@ dependencies = [ "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator)", - "bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)", + "bitvec 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader?branch=vga)", "buddy_system_allocator 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -435,7 +435,7 @@ dependencies = [ [[package]] name = "rcore-thread" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-thread#77e8e0778154734ee59525e043caab6339e14d75" +source = "git+https://github.com/rcore-os/rcore-thread#56021ab440fab8c7b819fed6a42649fb8bbaec07" dependencies = [ "deque 0.3.2 (git+https://github.com/rcore-os/deque.git?branch=no_std)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -691,7 +691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator)" = "" -"checksum bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)" = "" +"checksum bitvec 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c28d4291b516ccfbb897d45de3c468c135e6af7c4f1f1aacfaae0a5bc2e6ea2c" "checksum bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfadef5c4e2c2e64067b9ecc061179f12ac7ec65ba613b1f60f3972bbada1f5b" "checksum bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader?branch=vga)" = "" "checksum buddy_system_allocator 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59da15ef556589ee78370281d75b67f2d69ed26465ec0e0f3961e2021502426f" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index af137c4..1e4ec2e 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -53,7 +53,7 @@ bitflags = "1.0" bit_field = "0.9" volatile = "0.2" heapless = "0.4" -bitvec = { git = "https://github.com/myrrlyn/bitvec.git", default-features = false, features = ["alloc"] } +bitvec = { version = "0.11", default-features = false, features = ["alloc"] } console-traits = "0.3" buddy_system_allocator = "0.3" pci = { git = "https://github.com/rcore-os/pci-rs" } diff --git a/kernel/Makefile b/kernel/Makefile index b0ccb2a..6133f11 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -98,6 +98,7 @@ export DTB = $(dtb) qemu_opts := \ -smp cores=$(smp) qemu_net_opts := +qemu_ui_opts := ifeq ($(arch), x86_64) qemu_opts += \ @@ -120,6 +121,8 @@ qemu_opts += \ -machine accel=kvm qemu_net_opts += \ -device vfio-pci,host=$(pci_passthru) +qemu_ui_opts += \ + -vga std endif ifeq ($(extra_nic), on) qemu_net_opts += \ @@ -138,6 +141,9 @@ qemu_opts += \ qemu_net_opts += \ -netdev type=tap,id=net0,script=no,downscript=no \ -device virtio-net-device,netdev=net0 +qemu_ui_opts += \ + -device virtio-gpu-device \ + -device virtio-mouse-device else ifeq ($(arch), riscv64) ifeq ($(board), u540) @@ -158,6 +164,9 @@ endif qemu_net_opts += \ -netdev type=tap,id=net0,script=no,downscript=no \ -device virtio-net-device,netdev=net0 +qemu_ui_opts += \ + -device virtio-gpu-device \ + -device virtio-mouse-device else ifeq ($(arch), aarch64) qemu_opts += \ @@ -271,9 +280,7 @@ justrunnet: build @sudo qemu-system-$(arch) $(qemu_opts) $(qemu_net_opts) justrunui: build - @qemu-system-$(arch) $(qemu_opts) \ - -device virtio-gpu-device \ - -device virtio-mouse-device + @qemu-system-$(arch) $(qemu_opts) $(qemu_ui_opts) justruntest: build @qemu-system-$(arch) $(filter-out -serial mon:stdio, $(qemu_opts)) --append $(init) -serial file:../tests/stdout -monitor null @@ -346,8 +353,9 @@ else ifeq ($(arch), aarch64) @cargo xbuild $(build_args) else ifeq ($(arch), mipsel) @for file in context entry trap ; do \ - $(hostcc) -E src/arch/$(arch)/boot/$${file}.S -o src/arch/$(arch)/boot/$${file}.gen.s ; \ + $(hostcc) -Dboard_$(board) -E src/arch/$(arch)/boot/$${file}.S -o src/arch/$(arch)/boot/$${file}.gen.s ; \ done + $(hostcc) -Dboard_$(board) -E src/arch/$(arch)/boot/linker.ld.S -o src/arch/$(arch)/boot/linker.ld @cargo xbuild $(build_args) endif diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index 5e7cd94..1d27b85 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -212,7 +212,7 @@ impl PageTableImpl { PageTableImpl { page_table: MappedPageTable::new(table, frame_to_page_table), root_frame: frame, - entry: core::mem::uninitialized(), + entry: core::mem::MaybeUninit::uninitialized().into_initialized(), } } } @@ -227,7 +227,7 @@ impl PageTableExt for PageTableImpl { PageTableImpl { page_table: MappedPageTable::new(table, frame_to_page_table), root_frame: frame, - entry: core::mem::uninitialized(), + entry: core::mem::MaybeUninit::uninitialized().into_initialized(), } } } diff --git a/kernel/src/arch/mipsel/board/malta/consts.rs b/kernel/src/arch/mipsel/board/malta/consts.rs index c16d545..8f6fbe7 100644 --- a/kernel/src/arch/mipsel/board/malta/consts.rs +++ b/kernel/src/arch/mipsel/board/malta/consts.rs @@ -1,3 +1,3 @@ /// board specific constants -pub const MEMORY_END: usize = 0x8800_0000; -pub const KERNEL_HEAP_SIZE: usize = 0x0044_0000; +pub const MEMORY_END: usize = 0x8090_0000; +pub const KERNEL_HEAP_SIZE: usize = 0x003b_0000; diff --git a/kernel/src/arch/mipsel/board/malta/device.dts b/kernel/src/arch/mipsel/board/malta/device.dts index bbe1e66..bee60a4 100644 --- a/kernel/src/arch/mipsel/board/malta/device.dts +++ b/kernel/src/arch/mipsel/board/malta/device.dts @@ -9,7 +9,7 @@ chosen { stdio = &uart2; - bootargs = "rust/sh"; + bootargs = "sh"; }; aliases { }; diff --git a/kernel/src/arch/mipsel/board/thinpad/consts.rs b/kernel/src/arch/mipsel/board/thinpad/consts.rs index 98f0a5e..db1971f 100644 --- a/kernel/src/arch/mipsel/board/thinpad/consts.rs +++ b/kernel/src/arch/mipsel/board/thinpad/consts.rs @@ -1,3 +1,3 @@ /// board specific constants pub const MEMORY_END: usize = 0x8080_0000; -pub const KERNEL_HEAP_SIZE: usize = 0x0044_0000; +pub const KERNEL_HEAP_SIZE: usize = 0x0038_0000; diff --git a/kernel/src/arch/mipsel/board/thinpad/device.dts b/kernel/src/arch/mipsel/board/thinpad/device.dts index 5a771c9..ef41be8 100644 --- a/kernel/src/arch/mipsel/board/thinpad/device.dts +++ b/kernel/src/arch/mipsel/board/thinpad/device.dts @@ -9,7 +9,7 @@ chosen { stdio = &uart; - bootargs = ""; + bootargs = "sh"; }; aliases { }; diff --git a/kernel/src/arch/mipsel/boot/linker.ld b/kernel/src/arch/mipsel/boot/linker.ld.S similarity index 93% rename from kernel/src/arch/mipsel/boot/linker.ld rename to kernel/src/arch/mipsel/boot/linker.ld.S index 13adcfc..e231659 100644 --- a/kernel/src/arch/mipsel/boot/linker.ld +++ b/kernel/src/arch/mipsel/boot/linker.ld.S @@ -4,7 +4,11 @@ OUTPUT_ARCH(riscv) ENTRY(_start) +#ifdef board_thinpad +BASE_ADDRESS = 0x80000000; +#else BASE_ADDRESS = 0x80100000; +#endif SECTIONS { diff --git a/kernel/src/arch/mipsel/boot/trap.S b/kernel/src/arch/mipsel/boot/trap.S index 07b7ffa..012d792 100644 --- a/kernel/src/arch/mipsel/boot/trap.S +++ b/kernel/src/arch/mipsel/boot/trap.S @@ -32,6 +32,12 @@ trap_from_kernel: * k1 = old stack pointer * sp = kernel stack */ +#ifdef board_thinpad +#define TRAPFRAME_SIZE 304 +#else +#define TRAPFRAME_SIZE 176 +#endif + # align stack pointer andi k0, sp, 0xf beqz k0, sp_aligned @@ -39,12 +45,13 @@ trap_from_kernel: la k0, 0xfffffff0 and k0, sp, k0 - sw sp, -176(k0) + sw sp, -TRAPFRAME_SIZE(k0) move sp, k0 sp_aligned: - # allocate 38 words for trapframe + 6 extra words - addiu sp, sp, -176 + # allocate 38 / 70 words for trapframe + 6 extra words + + addiu sp, sp, -TRAPFRAME_SIZE # save general registers sw ra, 160(sp) @@ -80,6 +87,42 @@ sp_aligned: sw AT, 40(sp) nop +#ifdef board_thinpad + # save floating point registers + swc1 $f0, 164(sp) + swc1 $f1, 168(sp) + swc1 $f2, 172(sp) + swc1 $f3, 176(sp) + swc1 $f4, 180(sp) + swc1 $f5, 184(sp) + swc1 $f6, 188(sp) + swc1 $f7, 192(sp) + swc1 $f8, 196(sp) + swc1 $f9, 200(sp) + swc1 $f10, 204(sp) + swc1 $f11, 208(sp) + swc1 $f12, 212(sp) + swc1 $f13, 216(sp) + swc1 $f14, 220(sp) + swc1 $f15, 224(sp) + swc1 $f16, 228(sp) + swc1 $f17, 232(sp) + swc1 $f18, 236(sp) + swc1 $f19, 240(sp) + swc1 $f20, 244(sp) + swc1 $f21, 248(sp) + swc1 $f22, 252(sp) + swc1 $f23, 256(sp) + swc1 $f24, 260(sp) + swc1 $f25, 264(sp) + swc1 $f26, 268(sp) + swc1 $f27, 272(sp) + swc1 $f28, 276(sp) + swc1 $f29, 280(sp) + swc1 $f30, 284(sp) + swc1 $f31, 288(sp) +#endif + # save hi/lo mflo t1 sw t1, 36(sp) @@ -158,9 +201,45 @@ trap_return: lw fp, 156(sp) lw ra, 160(sp) +#ifdef board_thinpad + # restore floating point registers + lwc1 $f0, 164(sp) + lwc1 $f1, 168(sp) + lwc1 $f2, 172(sp) + lwc1 $f3, 176(sp) + lwc1 $f4, 180(sp) + lwc1 $f5, 184(sp) + lwc1 $f6, 188(sp) + lwc1 $f7, 192(sp) + lwc1 $f8, 196(sp) + lwc1 $f9, 200(sp) + lwc1 $f10, 204(sp) + lwc1 $f11, 208(sp) + lwc1 $f12, 212(sp) + lwc1 $f13, 216(sp) + lwc1 $f14, 220(sp) + lwc1 $f15, 224(sp) + lwc1 $f16, 228(sp) + lwc1 $f17, 232(sp) + lwc1 $f18, 236(sp) + lwc1 $f19, 240(sp) + lwc1 $f20, 244(sp) + lwc1 $f21, 248(sp) + lwc1 $f22, 252(sp) + lwc1 $f23, 256(sp) + lwc1 $f24, 260(sp) + lwc1 $f25, 264(sp) + lwc1 $f26, 268(sp) + lwc1 $f27, 272(sp) + lwc1 $f28, 276(sp) + lwc1 $f29, 280(sp) + lwc1 $f30, 284(sp) + lwc1 $f31, 288(sp) +#endif + # save kernel stack lw k0, 0(sp) - addiu k1, sp, 176 + addiu k1, sp, TRAPFRAME_SIZE movn k1, k0, k0 la k0, _cur_kstack_ptr diff --git a/kernel/src/arch/mipsel/consts.rs b/kernel/src/arch/mipsel/consts.rs index 48a48d3..e1e5a28 100644 --- a/kernel/src/arch/mipsel/consts.rs +++ b/kernel/src/arch/mipsel/consts.rs @@ -2,11 +2,16 @@ /// pub use super::board::consts::*; -pub const MEMORY_OFFSET: usize = 0x80000000; -pub const KERNEL_OFFSET: usize = 0x80100000; -pub const PHYSICAL_MEMORY_OFFSET: usize = 0x80000000; +pub const MEMORY_OFFSET: usize = 0x8000_0000; -pub const USER_STACK_OFFSET: usize = 0x70000000 - USER_STACK_SIZE; +#[cfg(feature = "board_thinpad")] +pub const KERNEL_OFFSET: usize = 0x8000_0000; +#[cfg(feature = "board_malta")] +pub const KERNEL_OFFSET: usize = 0x8010_0000; + +pub const PHYSICAL_MEMORY_OFFSET: usize = 0x8000_0000; + +pub const USER_STACK_OFFSET: usize = 0x7000_0000 - USER_STACK_SIZE; pub const USER_STACK_SIZE: usize = 0x10000; pub const MAX_DTB_SIZE: usize = 0x2000; diff --git a/kernel/src/arch/mipsel/context.rs b/kernel/src/arch/mipsel/context.rs index 116e9f0..9441313 100644 --- a/kernel/src/arch/mipsel/context.rs +++ b/kernel/src/arch/mipsel/context.rs @@ -52,6 +52,39 @@ pub struct TrapFrame { pub sp: usize, pub fp: usize, pub ra: usize, + /// Floating-point registers (contains garbage if no FP support present) + pub f0: usize, + pub f1: usize, + pub f2: usize, + pub f3: usize, + pub f4: usize, + pub f5: usize, + pub f6: usize, + pub f7: usize, + pub f8: usize, + pub f9: usize, + pub f10: usize, + pub f11: usize, + pub f12: usize, + pub f13: usize, + pub f14: usize, + pub f15: usize, + pub f16: usize, + pub f17: usize, + pub f18: usize, + pub f19: usize, + pub f20: usize, + pub f21: usize, + pub f22: usize, + pub f23: usize, + pub f24: usize, + pub f25: usize, + pub f26: usize, + pub f27: usize, + pub f28: usize, + pub f29: usize, + pub f30: usize, + pub f31: usize, /// Reserved pub reserved: usize, pub __padding: [usize; 2], diff --git a/kernel/src/arch/mipsel/paging.rs b/kernel/src/arch/mipsel/paging.rs index 81815b2..2dd1cdf 100644 --- a/kernel/src/arch/mipsel/paging.rs +++ b/kernel/src/arch/mipsel/paging.rs @@ -155,7 +155,7 @@ impl PageTableImpl { PageTableImpl { page_table: TwoLevelPageTable::new(table), root_frame: frame, - entry: unsafe { core::mem::uninitialized() }, + entry: unsafe { core::mem::MaybeUninit::uninitialized().into_initialized() }, } } } @@ -171,7 +171,7 @@ impl PageTableExt for PageTableImpl { PageTableImpl { page_table: TwoLevelPageTable::new(table), root_frame: frame, - entry: unsafe { core::mem::uninitialized() }, + entry: unsafe { core::mem::MaybeUninit::uninitialized().into_initialized() }, } } diff --git a/kernel/src/arch/riscv32/board/virt/mod.rs b/kernel/src/arch/riscv32/board/virt/mod.rs index a20be5a..210b57c 100644 --- a/kernel/src/arch/riscv32/board/virt/mod.rs +++ b/kernel/src/arch/riscv32/board/virt/mod.rs @@ -1,3 +1,6 @@ +#[path = "../../../../drivers/gpu/fb.rs"] +pub mod fb; + use crate::memory::phys_to_virt; /// Mask all external interrupt except serial. @@ -16,3 +19,7 @@ pub unsafe fn enable_serial_interrupt() { UART16550.add(4).write_volatile(0x0B); UART16550.add(1).write_volatile(0x01); } + +pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferResult { + unimplemented!() +} diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index 96428a1..6ea6a7e 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -1,4 +1,4 @@ -use crate::consts::{KERNEL_OFFSET, MEMORY_END, MEMORY_OFFSET}; +use crate::consts::{KERNEL_OFFSET, MEMORY_END, MEMORY_OFFSET, PHYSICAL_MEMORY_OFFSET}; use crate::memory::{init_heap, Linear, MemoryAttr, MemorySet, FRAME_ALLOCATOR}; use core::mem; use log::*; diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index 185bfe4..b580fef 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -1,12 +1,12 @@ #[cfg(feature = "board_u540")] #[path = "board/u540/mod.rs"] -mod board; +pub mod board; #[cfg(feature = "board_rocket_chip")] #[path = "board/rocket_chip/mod.rs"] -mod board; +pub mod board; #[cfg(not(any(feature = "board_u540", feature = "board_rocket_chip")))] #[path = "board/virt/mod.rs"] -mod board; +pub mod board; pub mod compiler_rt; pub mod consts; diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index dd49568..8baec5f 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -157,7 +157,7 @@ impl PageTableImpl { PageTableImpl { page_table: TopLevelPageTable::new(table, PHYSICAL_MEMORY_OFFSET), root_frame: frame, - entry: unsafe { core::mem::uninitialized() }, + entry: unsafe { core::mem::MaybeUninit::uninitialized().into_initialized() }, } } } @@ -173,7 +173,7 @@ impl PageTableExt for PageTableImpl { PageTableImpl { page_table: TopLevelPageTable::new(table, PHYSICAL_MEMORY_OFFSET), root_frame: frame, - entry: unsafe { core::mem::uninitialized() }, + entry: unsafe { core::mem::MaybeUninit::uninitialized().into_initialized() }, } } @@ -191,6 +191,10 @@ impl PageTableExt for PageTableImpl { } #[cfg(target_arch = "riscv64")] for i in 509..512 { + if (i == 510) { + // MMIO range 0x60000000 - 0x7FFFFFFF does not work as a large page, dunno why + continue; + } let flags = EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE | EF::ACCESSED | EF::DIRTY; let frame = Frame::of_addr(PhysAddr::new( @@ -198,6 +202,42 @@ impl PageTableExt for PageTableImpl { )); table[i].set(frame, flags); } + + // MMIO range 0x60000000 - 0x7FFFFFFF does not work as a large page, dunno why + let flags = EF::VALID | EF::READABLE | EF::WRITABLE; + // map Uartlite for Rocket Chip + #[cfg(feature = "board_rocket_chip")] + self.page_table + .map_to( + Page::of_addr(VirtAddr::new(PHYSICAL_MEMORY_OFFSET + 0x6000_0000)), + Frame::of_addr(PhysAddr::new(0x6000_0000)), + flags, + &mut FrameAllocatorForRiscv, + ) + .unwrap() + .flush(); + // map AXI INTC for Rocket Chip + #[cfg(feature = "board_rocket_chip")] + self.page_table + .map_to( + Page::of_addr(VirtAddr::new(PHYSICAL_MEMORY_OFFSET + 0x6120_0000)), + Frame::of_addr(PhysAddr::new(0x6120_0000)), + flags, + &mut FrameAllocatorForRiscv, + ) + .unwrap() + .flush(); + // map AXI4-Stream Data FIFO for Rocket Chip + #[cfg(feature = "board_rocket_chip")] + self.page_table + .map_to( + Page::of_addr(VirtAddr::new(PHYSICAL_MEMORY_OFFSET + 0x64A0_0000)), + Frame::of_addr(PhysAddr::new(0x64A0_0000)), + flags, + &mut FrameAllocatorForRiscv, + ) + .unwrap() + .flush(); } fn token(&self) -> usize { diff --git a/kernel/src/arch/x86_64/board/mod.rs b/kernel/src/arch/x86_64/board/mod.rs index b6da4ce..f936e17 100755 --- a/kernel/src/arch/x86_64/board/mod.rs +++ b/kernel/src/arch/x86_64/board/mod.rs @@ -1,15 +1,16 @@ #[path = "../../../drivers/gpu/fb.rs"] pub mod fb; -use fb::{ColorConfig, FramebufferInfo, FramebufferResult, FRAME_BUFFER}; use crate::consts::KERNEL_OFFSET; +use crate::memory::phys_to_virt; +use fb::{ColorConfig, FramebufferInfo, FramebufferResult, FRAME_BUFFER}; pub fn init_driver() { #[cfg(not(feature = "nographic"))] fb::init(); } -pub fn probe_fb_info(width : u32, height : u32, depth : u32) -> FramebufferResult { +pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> FramebufferResult { let fb_info = FramebufferInfo { xres: 1024, yres: 768, @@ -22,5 +23,9 @@ pub fn probe_fb_info(width : u32, height : u32, depth : u32) -> FramebufferResul bus_addr: 0xfd00_0000, screen_size: 1024 * 768 * 3, }; - Ok((fb_info, fb::ColorConfig::BGRA8888, KERNEL_OFFSET + 0xf000_0000)) + Ok(( + fb_info, + fb::ColorConfig::BGRA8888, + phys_to_virt(0xfd00_0000), + )) } diff --git a/kernel/src/arch/x86_64/gdt.rs b/kernel/src/arch/x86_64/gdt.rs index e24ef98..aa46848 100644 --- a/kernel/src/arch/x86_64/gdt.rs +++ b/kernel/src/arch/x86_64/gdt.rs @@ -1,5 +1,4 @@ use super::ipi::IPIEventItem; -use alloc::boxed::Box; use alloc::vec::*; use core::sync::atomic::{AtomicBool, Ordering}; use x86_64::registers::model_specific::Msr; @@ -8,7 +7,7 @@ use x86_64::structures::tss::TaskStateSegment; use x86_64::{PrivilegeLevel, VirtAddr}; use crate::consts::MAX_CPU_NUM; -use crate::sync::{Semaphore, SpinLock as Mutex}; +use crate::sync::SpinLock as Mutex; /// Init TSS & GDT. pub fn init() { @@ -36,6 +35,10 @@ pub struct Cpu { } impl Cpu { + pub fn current() -> &'static mut Self { + unsafe { CPUS[super::cpu::id()].as_mut().unwrap() } + } + fn new() -> Self { Cpu { gdt: GlobalDescriptorTable::new(), @@ -57,9 +60,6 @@ impl Cpu { let mut queue = self.ipi_handler_queue.lock(); queue.push(item); } - pub fn current() -> &'static mut Cpu { - unsafe { CPUS[super::cpu::id()].as_mut().unwrap() } - } pub fn handle_ipi(&self) { let mut queue = self.ipi_handler_queue.lock(); let handlers = core::mem::replace(queue.as_mut(), vec![]); @@ -78,7 +78,7 @@ impl Cpu { self.preemption_disabled.load(Ordering::Relaxed) } unsafe fn init(&'static mut self) { - use x86_64::instructions::segmentation::{load_fs, set_cs}; + use x86_64::instructions::segmentation::set_cs; use x86_64::instructions::tables::load_tss; // Set the stack when DoubleFault occurs @@ -98,9 +98,18 @@ impl Cpu { set_cs(KCODE_SELECTOR); // load TSS load_tss(TSS_SELECTOR); - // store address of TSS to GSBase - let mut gsbase = Msr::new(0xC0000101); - gsbase.write(&self.tss as *const _ as u64); + // for fast syscall: + // store address of TSS to kernel_gsbase + let mut kernel_gsbase = Msr::new(0xC0000102); + kernel_gsbase.write(&self.tss as *const _ as u64); + } + + /// 设置从Ring3跳到Ring0时,自动切换栈的地址 + /// + /// 每次进入用户态前,都要调用此函数,才能保证正确返回内核态 + pub fn set_ring0_rsp(&mut self, rsp: usize) { + trace!("gdt.set_ring0_rsp: {:#x}", rsp); + self.tss.privilege_stack_table[0] = VirtAddr::new(rsp as u64); } } diff --git a/kernel/src/arch/x86_64/interrupt/fast_syscall.rs b/kernel/src/arch/x86_64/interrupt/fast_syscall.rs index d096b65..f4a8249 100644 --- a/kernel/src/arch/x86_64/interrupt/fast_syscall.rs +++ b/kernel/src/arch/x86_64/interrupt/fast_syscall.rs @@ -1,5 +1,4 @@ use super::super::gdt; -use super::TrapFrame; use core::mem::transmute; /// `syscall` instruction use x86_64::registers::model_specific::*; diff --git a/kernel/src/arch/x86_64/interrupt/handler.rs b/kernel/src/arch/x86_64/interrupt/handler.rs index d6fb976..2b5c099 100644 --- a/kernel/src/arch/x86_64/interrupt/handler.rs +++ b/kernel/src/arch/x86_64/interrupt/handler.rs @@ -229,3 +229,9 @@ fn invalid_opcode(tf: &mut TrapFrame) { fn error(tf: &TrapFrame) { crate::trap::error(tf); } + +#[no_mangle] +pub unsafe extern "C" fn set_return_rsp(tf: *const TrapFrame) { + use crate::arch::gdt::Cpu; + Cpu::current().set_ring0_rsp(tf.add(1) as usize); +} diff --git a/kernel/src/arch/x86_64/interrupt/trap.asm b/kernel/src/arch/x86_64/interrupt/trap.asm index 2f0424b..d20528d 100644 --- a/kernel/src/arch/x86_64/interrupt/trap.asm +++ b/kernel/src/arch/x86_64/interrupt/trap.asm @@ -49,10 +49,8 @@ __alltraps: .global trap_ret trap_ret: - # store kernel rsp -> TSS.sp0 mov rdi, rsp - add rdi, 720 - mov gs:[4], rdi + call set_return_rsp # pop fp state offset pop rcx @@ -106,6 +104,8 @@ syscall_entry: # - store rip -> rcx # - load rip + # swap in kernel gs + swapgs # store user rsp -> scratch at TSS.sp1 mov gs:[12], rsp # load kernel rsp <- TSS.sp0 @@ -119,8 +119,11 @@ syscall_entry: push 0 # error_code (dummy) push 0 # trap_num (dummy) + # swap out kernel gs + swapgs + # enable interrupt - sti + # sti push rax push rcx @@ -170,10 +173,8 @@ syscall_return: # disable interrupt cli - # store kernel rsp -> TSS.sp0 mov rdi, rsp - add rdi, 720 - mov gs:[4], rdi + call set_return_rsp # pop fp state offset pop rcx diff --git a/kernel/src/arch/x86_64/io.rs b/kernel/src/arch/x86_64/io.rs index 7727c1d..d6f8dcb 100644 --- a/kernel/src/arch/x86_64/io.rs +++ b/kernel/src/arch/x86_64/io.rs @@ -1,7 +1,6 @@ +use super::driver::console::CONSOLE; use super::driver::serial::*; -use super::driver::vga::VGA_WRITER; use core::fmt::{Arguments, Write}; -use super::driver::console::CONSOLE; pub fn getchar() -> char { unsafe { @@ -20,13 +19,14 @@ pub fn putfmt(fmt: Arguments) { } #[cfg(not(feature = "nographic"))] { + use super::driver::vga::VGA_WRITER; unsafe { COM1.force_unlock(); } COM1.lock().write_fmt(fmt).unwrap(); //unsafe { CONSOLE.force_unlock() } //if let Some(console) = CONSOLE.lock().as_mut() { - //console.write_fmt(fmt).unwrap(); + //console.write_fmt(fmt).unwrap(); //} } } diff --git a/kernel/src/arch/x86_64/ipi.rs b/kernel/src/arch/x86_64/ipi.rs index 816d887..3970272 100644 --- a/kernel/src/arch/x86_64/ipi.rs +++ b/kernel/src/arch/x86_64/ipi.rs @@ -9,7 +9,7 @@ use core::sync::atomic::{spin_loop_hint, AtomicU8, Ordering}; pub type IPIEventItem = Box; unsafe fn get_apic() -> XApic { - let mut lapic = unsafe { XApic::new(phys_to_virt(LAPIC_ADDR)) }; + let mut lapic = XApic::new(phys_to_virt(LAPIC_ADDR)); lapic } diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index 0b3cb7d..edda727 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -2,6 +2,7 @@ use bootloader::bootinfo::{BootInfo, MemoryRegionType}; use core::sync::atomic::*; use log::*; +pub mod board; pub mod consts; pub mod cpu; pub mod driver; @@ -15,7 +16,6 @@ pub mod paging; pub mod rand; pub mod syscall; pub mod timer; -pub mod board; static AP_CAN_INIT: AtomicBool = AtomicBool::new(false); diff --git a/kernel/src/arch/x86_64/paging.rs b/kernel/src/arch/x86_64/paging.rs index b8f07ec..2f8c26e 100644 --- a/kernel/src/arch/x86_64/paging.rs +++ b/kernel/src/arch/x86_64/paging.rs @@ -21,7 +21,7 @@ pub trait PageExt { impl PageExt for Page { fn of_addr(address: usize) -> Self { use x86_64; - Page::containing_address(x86_64::VirtAddr::new(address as u64)) + Page::containing_address(VirtAddr::new(address as u64)) } fn range_of(begin: usize, end: usize) -> PageRange { Page::range(Page::of_addr(begin), Page::of_addr(end - 1) + 1) @@ -101,7 +101,7 @@ fn frame_to_page_table(frame: Frame) -> *mut x86PageTable { impl Entry for PageEntry { fn update(&mut self) { - use x86_64::{instructions::tlb::flush, VirtAddr}; + use x86_64::instructions::tlb::flush; let addr = self.1.start_address(); flush(addr); flush_tlb_all(addr.as_u64() as usize); @@ -199,10 +199,10 @@ impl PageTableImpl { /// WARN: You MUST call `core::mem::forget` for it after use! pub unsafe fn active() -> Self { let frame = Cr3::read().0; - let table = unsafe { &mut *frame_to_page_table(frame) }; + let table = &mut *frame_to_page_table(frame); PageTableImpl( MappedPageTable::new(table, frame_to_page_table), - core::mem::uninitialized(), + core::mem::MaybeUninit::uninitialized().into_initialized(), frame, ) } @@ -217,7 +217,7 @@ impl PageTableExt for PageTableImpl { unsafe { PageTableImpl( MappedPageTable::new(table, frame_to_page_table), - core::mem::uninitialized(), + core::mem::MaybeUninit::uninitialized().into_initialized(), frame, ) } diff --git a/kernel/src/drivers/block/ahci.rs b/kernel/src/drivers/block/ahci.rs index f86b909..8e256bd 100644 --- a/kernel/src/drivers/block/ahci.rs +++ b/kernel/src/drivers/block/ahci.rs @@ -8,7 +8,6 @@ use alloc::sync::Arc; use isomorphic_drivers::block::ahci::{AHCI, BLOCK_SIZE}; use crate::drivers::provider::Provider; -use crate::drivers::BlockDriver; use crate::sync::SpinNoIrqLock as Mutex; use super::super::{DeviceType, Driver, BLK_DRIVERS, DRIVERS}; diff --git a/kernel/src/drivers/block/virtio_blk.rs b/kernel/src/drivers/block/virtio_blk.rs index 4a52909..5510851 100644 --- a/kernel/src/drivers/block/virtio_blk.rs +++ b/kernel/src/drivers/block/virtio_blk.rs @@ -11,8 +11,6 @@ use log::*; use rcore_memory::PAGE_SIZE; use volatile::Volatile; -use crate::arch::consts::PHYSICAL_MEMORY_OFFSET; -use crate::drivers::BlockDriver; use crate::sync::SpinNoIrqLock as Mutex; use super::super::bus::virtio_mmio::*; diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index 00c547f..60ca629 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -157,8 +157,9 @@ pub fn init_driver(dev: &PCIDevice) { ); } } - (0x8086, 0x2922) => { + (0x8086, 0x2922) | (0x8086, 0x8d02) => { // 82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] + // C610/X99 series chipset 6-Port SATA Controller [AHCI mode] if let Some(BAR::Memory(addr, len, _, _)) = dev.bars[5] { let irq = unsafe { enable(dev.loc) }; assert!(len as usize <= PAGE_SIZE); diff --git a/kernel/src/drivers/gpu/fb.rs b/kernel/src/drivers/gpu/fb.rs index a772977..7277b86 100644 --- a/kernel/src/drivers/gpu/fb.rs +++ b/kernel/src/drivers/gpu/fb.rs @@ -154,7 +154,7 @@ impl Framebuffer { 8 => ColorDepth8, 16 => ColorDepth16, 32 => ColorDepth32, - 24=> ColorDepth24, + 24 => ColorDepth24, _ => Err(format!("unsupported color depth {}", info.depth))?, }; Ok(Framebuffer { diff --git a/kernel/src/drivers/input/virtio_input.rs b/kernel/src/drivers/input/virtio_input.rs index cf6053d..9c3fd5d 100644 --- a/kernel/src/drivers/input/virtio_input.rs +++ b/kernel/src/drivers/input/virtio_input.rs @@ -11,7 +11,6 @@ use bitflags::*; use device_tree::util::SliceRead; use device_tree::Node; use log::*; -use rcore_memory::paging::PageTable; use rcore_memory::PAGE_SIZE; use volatile::Volatile; diff --git a/kernel/src/drivers/net/router.rs b/kernel/src/drivers/net/router.rs index 65d8b6b..6577d5b 100644 --- a/kernel/src/drivers/net/router.rs +++ b/kernel/src/drivers/net/router.rs @@ -5,35 +5,53 @@ use alloc::string::String; use alloc::sync::Arc; use alloc::vec::Vec; +use bitflags::*; use smoltcp::iface::*; use smoltcp::phy::{self, DeviceCapabilities}; use smoltcp::time::Instant; use smoltcp::wire::*; use smoltcp::Result; -use rcore_memory::PAGE_SIZE; - -use crate::drivers::provider::Provider; use crate::net::SOCKETS; use crate::sync::SpinNoIrqLock as Mutex; use super::super::{DeviceType, Driver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY}; use crate::memory::phys_to_virt; -const AXI_STREAM_FIFO_ISR: *mut u32 = phys_to_virt(0x1820_0000) as *mut u32; -const AXI_STREAM_FIFO_IER: *mut u32 = phys_to_virt(0x1820_0004) as *mut u32; -const AXI_STREAM_FIFO_TDFR: *mut u32 = phys_to_virt(0x1820_0008) as *mut u32; -const AXI_STREAM_FIFO_TDFD: *mut u32 = phys_to_virt(0x1820_0010) as *mut u32; -const AXI_STREAM_FIFO_TLR: *mut u32 = phys_to_virt(0x1820_0014) as *mut u32; -const AXI_STREAM_FIFO_RDFR: *mut u32 = phys_to_virt(0x1820_0018) as *mut u32; -const AXI_STREAM_FIFO_RDFO: *mut u32 = phys_to_virt(0x1820_001C) as *mut u32; -const AXI_STREAM_FIFO_RDFD: *mut u32 = phys_to_virt(0x1820_0020) as *mut u32; -const AXI_STREAM_FIFO_RLR: *mut u32 = phys_to_virt(0x1820_0024) as *mut u32; -const AXI_STREAM_FIFO_TDR: *mut u32 = phys_to_virt(0x1820_002C) as *mut u32; -const AXI_STREAM_FIFO_RDR: *mut u32 = phys_to_virt(0x1820_0030) as *mut u32; +const AXI_STREAM_FIFO_ISR: *mut u32 = phys_to_virt(0x64A0_0000) as *mut u32; +const AXI_STREAM_FIFO_IER: *mut u32 = phys_to_virt(0x64A0_0004) as *mut u32; +const AXI_STREAM_FIFO_TDFR: *mut u32 = phys_to_virt(0x64A0_0008) as *mut u32; +const AXI_STREAM_FIFO_TDFD: *mut u32 = phys_to_virt(0x64A0_0010) as *mut u32; +const AXI_STREAM_FIFO_TLR: *mut u32 = phys_to_virt(0x64A0_0014) as *mut u32; +const AXI_STREAM_FIFO_RDFR: *mut u32 = phys_to_virt(0x64A0_0018) as *mut u32; +const AXI_STREAM_FIFO_RDFO: *mut u32 = phys_to_virt(0x64A0_001C) as *mut u32; +const AXI_STREAM_FIFO_RDFD: *mut u32 = phys_to_virt(0x64A0_0020) as *mut u32; +const AXI_STREAM_FIFO_RLR: *mut u32 = phys_to_virt(0x64A0_0024) as *mut u32; +const AXI_STREAM_FIFO_TDR: *mut u32 = phys_to_virt(0x64A0_002C) as *mut u32; +const AXI_STREAM_FIFO_RDR: *mut u32 = phys_to_virt(0x64A0_0030) as *mut u32; + +const ENABLED_PORTS: u8 = 2; + +bitflags! { + struct AXIStreamFifoInterrupt : u32 { + const RECV_EMPTY = 1 << 19; + const RECV_FULL = 1 << 20; + const TRAN_EMPTY = 1 << 21; + const TRAN_FULL = 1 << 22; + const RECV_RESET = 1 << 23; + const TRAN_RESET = 1 << 24; + const TRAN_SIZE_ERR = 1 << 25; + const RECV_COMPLETE = 1 << 26; + const TRAN_COMPLETE = 1 << 27; + const TRAN_PACKET_OVERRUN_ERR = 1 << 28; + const RECV_PACKET_UNDERRUN_ERR = 1 << 29; + const RECV_PACKET_OVERRUN_READ_ERR = 1 << 30; + const RECV_PACKET_UNDERRUN_READ_ERR = 1 << 31; + } +} pub struct Router { - buffer: Vec>, + buffer: [Vec>; ENABLED_PORTS as usize], } impl Router { @@ -41,13 +59,13 @@ impl Router { true } - fn receive_available(&self) -> bool { - self.buffer.len() > 0 + fn receive_available(&self, port: u8) -> bool { + self.buffer[port as usize].len() > 0 } } #[derive(Clone)] -pub struct RouterDriver(Arc>); +pub struct RouterDriver(Arc>, u8); pub struct RouterRxToken(RouterDriver); pub struct RouterTxToken(RouterDriver); @@ -58,7 +76,7 @@ impl<'a> phy::Device<'a> for RouterDriver { fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { let driver = self.0.lock(); - if driver.transmit_available() && driver.receive_available() { + if driver.transmit_available() && driver.receive_available(self.1) { // potential racing Some((RouterRxToken(self.clone()), RouterTxToken(self.clone()))) } else { @@ -89,7 +107,7 @@ impl phy::RxToken for RouterRxToken { F: FnOnce(&[u8]) -> Result, { let mut router = (self.0).0.lock(); - let buffer = router.buffer.pop().unwrap(); + let buffer = router.buffer[(self.0).1 as usize].pop().unwrap(); f(&buffer) } } @@ -101,14 +119,20 @@ impl phy::TxToken for RouterTxToken { { let mut buffer = vec![0; len]; let res = f(&mut buffer); - debug!("out buf {}", len); + debug!( + "out buf {} data {:x?} port {}", + len, + &buffer[..20], + (self.0).1 + ); unsafe { AXI_STREAM_FIFO_TDR.write_volatile(2); + AXI_STREAM_FIFO_TDFD.write_volatile((self.0).1 as u32); for byte in buffer { AXI_STREAM_FIFO_TDFD.write_volatile(byte as u32); } - AXI_STREAM_FIFO_TLR.write((len * 4) as u32); + AXI_STREAM_FIFO_TLR.write(((len + 1) * 4) as u32); } res } @@ -126,7 +150,10 @@ impl Driver for RouterInterface { let isr = unsafe { AXI_STREAM_FIFO_ISR.read_volatile() }; if isr > 0 { - debug!("handle router interrupt {:b}", isr); + debug!( + "handle router interrupt {:?}", + AXIStreamFifoInterrupt::from_bits_truncate(isr) + ); unsafe { AXI_STREAM_FIFO_ISR.write(isr); let rdfo = AXI_STREAM_FIFO_RDFO.read_volatile(); @@ -134,11 +161,17 @@ impl Driver for RouterInterface { let mut buffer = Vec::new(); let rlr = AXI_STREAM_FIFO_RLR.read_volatile(); let rdr = AXI_STREAM_FIFO_RDR.read_volatile(); - for i in 0..rdfo { + let port = AXI_STREAM_FIFO_RDFD.read_volatile(); + for i in 1..rdfo { buffer.push(AXI_STREAM_FIFO_RDFD.read_volatile() as u8); } - debug!("got packet of length {}", rdfo); - driver.buffer.push(buffer); + debug!( + "got packet of length {} port {} data {:x?}", + rdfo, + port, + &buffer[..20] + ); + driver.buffer[port as usize].push(buffer); } drop(driver); @@ -183,7 +216,7 @@ impl Driver for RouterInterface { } } -pub fn router_init() -> Arc { +pub fn router_init() { unsafe { // reset tx fifo AXI_STREAM_FIFO_TDFR.write_volatile(0xA5); @@ -191,38 +224,40 @@ pub fn router_init() -> Arc { AXI_STREAM_FIFO_RDFR.write_volatile(0xA5); } - let ethernet_addr = EthernetAddress::from_bytes(&[2, 2, 3, 3, 0, 0]); - - let net_driver = RouterDriver(Arc::new(Mutex::new(Router { buffer: Vec::new() }))); - - let ip_addrs = [ - IpCidr::new(IpAddress::v4(10, 0, 0, 1), 24), - IpCidr::new(IpAddress::v4(10, 0, 1, 1), 24), - ]; - let neighbor_cache = NeighborCache::new(BTreeMap::new()); - let routes = Routes::new(BTreeMap::new()); - let iface = EthernetInterfaceBuilder::new(net_driver.clone()) - .ethernet_addr(ethernet_addr) - .ip_addrs(ip_addrs) - .neighbor_cache(neighbor_cache) - .routes(routes) - .finalize(); - - info!("router interface up"); - - let router_iface = RouterInterface { - iface: Mutex::new(iface), - driver: net_driver, - }; - - let driver = Arc::new(router_iface); - DRIVERS.write().push(driver.clone()); - NET_DRIVERS.write().push(driver.clone()); + for i in 0..ENABLED_PORTS { + let ethernet_addr = EthernetAddress::from_bytes(&[2, 2, 3, 3, 0, i]); + + let net_driver = RouterDriver( + Arc::new(Mutex::new(Router { + buffer: [Vec::new(), Vec::new()], + })), + i, + ); + + let ip_addrs = [IpCidr::new(IpAddress::v4(10, 0, i, 1), 24)]; + let neighbor_cache = NeighborCache::new(BTreeMap::new()); + let routes = Routes::new(BTreeMap::new()); + let iface = EthernetInterfaceBuilder::new(net_driver.clone()) + .ethernet_addr(ethernet_addr) + .ip_addrs(ip_addrs) + .neighbor_cache(neighbor_cache) + .routes(routes) + .finalize(); + + info!("router interface up #{}", i); + + let router_iface = RouterInterface { + iface: Mutex::new(iface), + driver: net_driver, + }; + + let driver = Arc::new(router_iface); + DRIVERS.write().push(driver.clone()); + NET_DRIVERS.write().push(driver.clone()); + } // Enable Receive Complete Interrupt unsafe { AXI_STREAM_FIFO_IER.write_volatile(1 << 26); } - - driver } diff --git a/kernel/src/drivers/provider.rs b/kernel/src/drivers/provider.rs index c100990..909a121 100644 --- a/kernel/src/drivers/provider.rs +++ b/kernel/src/drivers/provider.rs @@ -1,10 +1,6 @@ -use alloc::alloc::{alloc_zeroed, dealloc, Layout}; - pub use crate::arch::paging::PageTableImpl; -use crate::consts::PHYSICAL_MEMORY_OFFSET; use crate::memory::{alloc_frame, dealloc_frame, phys_to_virt, virt_to_phys}; use isomorphic_drivers::provider; -use rcore_memory::paging::PageTable; use rcore_memory::PAGE_SIZE; pub struct Provider; diff --git a/kernel/src/drivers/serial/16550_reg.rs b/kernel/src/drivers/serial/16550_reg.rs index 424b839..cd0e87f 100644 --- a/kernel/src/drivers/serial/16550_reg.rs +++ b/kernel/src/drivers/serial/16550_reg.rs @@ -68,12 +68,19 @@ impl SerialPort { impl Write for SerialPort { fn write_str(&mut self, s: &str) -> Result { for c in s.bytes() { - if c == 127 { - self.putchar(8); - self.putchar(b' '); - self.putchar(8); - } else { - self.putchar(c); + match c { + 127 => { + self.putchar(8); + self.putchar(b' '); + self.putchar(8); + } + b'\n' => { + self.putchar(b'\r'); + self.putchar(b'\n'); + } + c => { + self.putchar(c); + } } } Ok(()) diff --git a/kernel/src/drivers/serial/simple_uart.rs b/kernel/src/drivers/serial/simple_uart.rs index ee5c569..0d01b53 100644 --- a/kernel/src/drivers/serial/simple_uart.rs +++ b/kernel/src/drivers/serial/simple_uart.rs @@ -59,12 +59,19 @@ impl SerialPort { impl Write for SerialPort { fn write_str(&mut self, s: &str) -> Result { for c in s.bytes() { - if c == 127 { - self.putchar(8); - self.putchar(b' '); - self.putchar(8); - } else { - self.putchar(c); + match c { + 127 => { + self.putchar(8); + self.putchar(b' '); + self.putchar(8); + } + b'\n' => { + self.putchar(b'\r'); + self.putchar(b'\n'); + } + c => { + self.putchar(c); + } } } Ok(()) diff --git a/kernel/src/drivers/serial/ti_16c550c.rs b/kernel/src/drivers/serial/ti_16c550c.rs index 4f5b51a..49ad0e2 100644 --- a/kernel/src/drivers/serial/ti_16c550c.rs +++ b/kernel/src/drivers/serial/ti_16c550c.rs @@ -68,12 +68,19 @@ impl SerialPort { impl Write for SerialPort { fn write_str(&mut self, s: &str) -> Result { for c in s.bytes() { - if c == 127 { - self.putchar(8); - self.putchar(b' '); - self.putchar(8); - } else { - self.putchar(c); + match c { + 127 => { + self.putchar(8); + self.putchar(b' '); + self.putchar(8); + } + b'\n' => { + self.putchar(b'\r'); + self.putchar(b'\n'); + } + c => { + self.putchar(c); + } } } Ok(()) diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 5d8505e..83ecc55 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -49,15 +49,16 @@ impl FileHandle { if !self.options.read { return Err(FsError::InvalidParam); // FIXME: => EBADF } - let mut len : usize = 0; - if !self.options.nonblock { // block + let mut len: usize = 0; + if !self.options.nonblock { + // block loop { len = self.inode.read_at(offset, buf)?; if len > 0 { break; } } - }else{ + } else { len = self.inode.read_at(offset, buf)?; } Ok(len) diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index ccb8204..fae5dc7 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -94,7 +94,7 @@ impl INode for Stdin { if self.can_read() { buf[0] = self.pop() as u8; Ok(1) - }else{ + } else { Ok(0) } } diff --git a/kernel/src/fs/vga.rs b/kernel/src/fs/vga.rs index 02baed2..42d4d56 100755 --- a/kernel/src/fs/vga.rs +++ b/kernel/src/fs/vga.rs @@ -1,8 +1,9 @@ use rcore_fs::vfs::*; +use crate::arch::board::fb::FRAME_BUFFER; +use crate::memory::phys_to_virt; use alloc::{string::String, sync::Arc, vec::Vec}; use core::any::Any; -use crate::arch::board::fb::FRAME_BUFFER; #[derive(Default)] pub struct Vga; @@ -30,15 +31,19 @@ impl INode for Vga { } fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result { info!("the _offset is {} {}", _offset, _buf[0]); - use crate::consts::KERNEL_OFFSET; use core::slice; - let frame_buffer_data = - unsafe { slice::from_raw_parts_mut((KERNEL_OFFSET + 0xf000_0000) as *mut u8, ( 1024 * 768 * 3) as usize) }; + let frame_buffer_data = unsafe { + slice::from_raw_parts_mut( + phys_to_virt(0xfd00_0000) as *mut u8, + (1024 * 768 * 3) as usize, + ) + }; frame_buffer_data.copy_from_slice(&_buf); return Ok(1024 * 768 * 3); } fn poll(&self) -> Result { - Ok(PollStatus { // TOKNOW and TODO + Ok(PollStatus { + // TOKNOW and TODO read: true, write: false, error: false, diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 1b8f90b..8788476 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -7,6 +7,7 @@ #![feature(panic_info_message)] #![feature(global_asm)] #![feature(fnbox)] +#![feature(maybe_uninit)] #![deny(unused_must_use)] #![no_std] diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 955020f..99c41f0 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -14,10 +14,9 @@ use super::HEAP_ALLOCATOR; pub use crate::arch::paging::*; -use crate::consts::{KERNEL_OFFSET, MEMORY_OFFSET, PHYSICAL_MEMORY_OFFSET}; +use crate::consts::{MEMORY_OFFSET, PHYSICAL_MEMORY_OFFSET}; use crate::process::current_thread; -use crate::sync::{MutexGuard, SpinNoIrq, SpinNoIrqLock}; -use alloc::boxed::Box; +use crate::sync::SpinNoIrqLock; use bitmap_allocator::BitAlloc; use buddy_system_allocator::Heap; use core::mem; @@ -30,9 +29,9 @@ use rcore_memory::*; pub type MemorySet = rcore_memory::memory_set::MemorySet; -// x86_64 support up to 64G memory +// x86_64 support up to 1T memory #[cfg(target_arch = "x86_64")] -pub type FrameAlloc = bitmap_allocator::BitAlloc16M; +pub type FrameAlloc = bitmap_allocator::BitAlloc256M; // RISCV, ARM, MIPS has 1G memory #[cfg(all( @@ -132,13 +131,13 @@ pub fn handle_page_fault(addr: usize) -> bool { pub fn init_heap() { use crate::consts::KERNEL_HEAP_SIZE; - const machine_align: usize = mem::size_of::(); - const heap_block: usize = KERNEL_HEAP_SIZE / machine_align; - static mut HEAP: [usize; heap_block] = [0; heap_block]; + const MACHINE_ALIGN: usize = mem::size_of::(); + const HEAP_BLOCK: usize = KERNEL_HEAP_SIZE / MACHINE_ALIGN; + static mut HEAP: [usize; HEAP_BLOCK] = [0; HEAP_BLOCK]; unsafe { HEAP_ALLOCATOR .lock() - .init(HEAP.as_ptr() as usize, heap_block * machine_align); + .init(HEAP.as_ptr() as usize, HEAP_BLOCK * MACHINE_ALIGN); } info!("heap init end"); } @@ -171,8 +170,9 @@ pub fn enlarge_heap(heap: &mut Heap) { } } -pub fn access_ok(from: usize, len: usize) -> bool { - from < PHYSICAL_MEMORY_OFFSET && (from + len) < PHYSICAL_MEMORY_OFFSET +/// Check whether the address range [addr, addr + len) is not in kernel space +pub fn access_ok(addr: usize, len: usize) -> bool { + addr < PHYSICAL_MEMORY_OFFSET && (addr + len) < PHYSICAL_MEMORY_OFFSET } #[naked] @@ -180,39 +180,19 @@ pub unsafe extern "C" fn read_user_fixup() -> usize { return 1; } -#[no_mangle] -pub fn copy_from_user_u8(addr: *const u8) -> Option { +pub fn copy_from_user(addr: *const T) -> Option { #[naked] #[inline(never)] #[link_section = ".text.copy_user"] - unsafe extern "C" fn read_user_u8(dst: *mut u8, src: *const u8) -> usize { + unsafe extern "C" fn read_user(dst: *mut T, src: *const T) -> usize { dst.copy_from_nonoverlapping(src, 1); 0 } - if !access_ok(addr as usize, size_of::()) { + if !access_ok(addr as usize, size_of::()) { return None; } - let mut dst: u8 = 0; - match unsafe { read_user_u8((&mut dst) as *mut u8, addr) } { - 0 => Some(dst), - _ => None, - } -} - -#[no_mangle] -pub fn copy_from_user_usize(addr: *const usize) -> Option { - #[naked] - #[inline(never)] - #[link_section = ".text.copy_user"] - unsafe extern "C" fn read_user_usize(dst: *mut usize, src: *const usize) -> usize { - dst.copy_from_nonoverlapping(src, 1); - 0 - } - if !access_ok(addr as usize, size_of::()) { - return None; - } - let mut dst: usize = 0; - match unsafe { read_user_usize((&mut dst) as *mut usize, addr) } { + let mut dst: T = unsafe { core::mem::uninitialized() }; + match unsafe { read_user(&mut dst, addr) } { 0 => Some(dst), _ => None, } diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 494f7b7..e08f628 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -1,7 +1,6 @@ pub use self::structs::*; use crate::arch::cpu; use crate::consts::{MAX_CPU_NUM, MAX_PROCESS_NUM}; -use crate::sync::{MutexGuard, SpinNoIrq}; use alloc::{boxed::Box, sync::Arc}; use log::*; pub use rcore_thread::*; diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 908e3ec..b783b37 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -21,7 +21,7 @@ use crate::sync::{Condvar, SpinNoIrqLock as Mutex}; use super::abi::{self, ProcInitInfo}; use crate::processor; -use core::mem::uninitialized; +use core::mem::MaybeUninit; use rcore_fs::vfs::INode; pub struct Thread { @@ -103,7 +103,7 @@ impl Thread { Box::new(Thread { context: Context::null(), // safety: other fields will never be used - ..core::mem::uninitialized() + ..core::mem::MaybeUninit::uninitialized().into_initialized() }) } @@ -146,7 +146,7 @@ impl Thread { ) -> Result<(MemorySet, usize, usize), &'static str> { // Read ELF header // 0x3c0: magic number from ld-musl.so - let mut data: [u8; 0x3c0] = unsafe { uninitialized() }; + let mut data: [u8; 0x3c0] = unsafe { MaybeUninit::uninitialized().into_initialized() }; inode .read_at(0, &mut data) .map_err(|_| "failed to read from INode")?; diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index ddad4cc..f811969 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -1,6 +1,5 @@ //! Kernel shell -use crate::arch::io; use crate::fs::ROOT_INODE; use crate::process::*; use alloc::string::String; diff --git a/kernel/src/sync/condvar.rs b/kernel/src/sync/condvar.rs index 61db073..e9e4ae0 100644 --- a/kernel/src/sync/condvar.rs +++ b/kernel/src/sync/condvar.rs @@ -1,4 +1,5 @@ use super::*; +use crate::process::processor; use crate::thread; use alloc::collections::VecDeque; use alloc::sync::Arc; @@ -26,26 +27,46 @@ impl Condvar { }); } - #[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")] - pub fn wait_any(condvars: &[&Condvar]) { - let token = Arc::new(thread::current()); - // Avoid racing in the same way as the function above - let mut locks = Vec::new(); - locks.reserve(condvars.len()); + fn add_to_wait_queue(&self) -> MutexGuard>, SpinNoIrq> { + let mut lock = self.wait_queue.lock(); + lock.push_back(Arc::new(thread::current())); + return lock; + } + + /// Wait for condvar until condition() returns Some + pub fn wait_event(condvar: &Condvar, mut condition: impl FnMut() -> Option) -> T { + Self::wait_events(&[condvar], condition) + } + + /// Wait for condvars until condition() returns Some + pub fn wait_events(condvars: &[&Condvar], mut condition: impl FnMut() -> Option) -> T { + let thread = thread::current(); + let tid = thread.id(); + let token = Arc::new(thread); for condvar in condvars { let mut lock = condvar.wait_queue.lock(); lock.push_back(token.clone()); - locks.push(lock); } - thread::park_action(move || { - drop(locks); - }); - } + let mut locks = Vec::with_capacity(condvars.len()); + loop { + for condvar in condvars { + let mut lock = condvar.wait_queue.lock(); + locks.push(lock); + } + processor().manager().sleep(tid, 0); + locks.clear(); - fn add_to_wait_queue(&self) -> MutexGuard>, SpinNoIrq> { - let mut lock = self.wait_queue.lock(); - lock.push_back(Arc::new(thread::current())); - return lock; + if let Some(res) = condition() { + let _ = FlagsGuard::no_irq_region(); + processor().manager().cancel_sleeping(tid); + for condvar in condvars { + let mut lock = condvar.wait_queue.lock(); + lock.retain(|t| !Arc::ptr_eq(t, &token)); + } + return res; + } + processor().yield_now(); + } } /// Park current thread and wait for this condvar to be notified. @@ -54,21 +75,28 @@ impl Condvar { S: MutexSupport, { let mutex = guard.mutex; - let lock = self.add_to_wait_queue(); + let token = Arc::new(thread::current()); + let mut lock = self.wait_queue.lock(); + lock.push_back(token.clone()); + thread::park_action(move || { drop(lock); drop(guard); }); - mutex.lock() + let ret = mutex.lock(); + let mut lock = self.wait_queue.lock(); + lock.retain(|t| !Arc::ptr_eq(&t, &token)); + ret } pub fn notify_one(&self) { - if let Some(t) = self.wait_queue.lock().pop_front() { + if let Some(t) = self.wait_queue.lock().front() { t.unpark(); } } pub fn notify_all(&self) { - while let Some(t) = self.wait_queue.lock().pop_front() { + let queue = self.wait_queue.lock(); + for t in queue.iter() { t.unpark(); } } @@ -76,14 +104,15 @@ impl Condvar { /// Return the number of waiters that were woken up. pub fn notify_n(&self, n: usize) -> usize { let mut count = 0; - while count < n { - if let Some(t) = self.wait_queue.lock().pop_front() { - t.unpark(); - count += 1; - } else { + let queue = self.wait_queue.lock(); + for t in queue.iter() { + if count >= n { break; } + t.unpark(); + count += 1; } + count } } diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 52e4986..5e3c46f 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -105,14 +105,17 @@ impl Syscall<'_> { drop(proc); let begin_time_ms = crate::trap::uptime_msec(); - loop { + Condvar::wait_events(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)], move || { use PollEvents as PE; let proc = self.process(); let mut events = 0; for poll in polls.iter_mut() { poll.revents = PE::empty(); if let Some(file_like) = proc.files.get(&(poll.fd as usize)) { - let status = file_like.poll()?; + let status = match file_like.poll() { + Ok(ret) => ret, + Err(err) => return Some(Err(err)), + }; if status.error { poll.revents |= PE::HUP; events += 1; @@ -133,19 +136,15 @@ impl Syscall<'_> { drop(proc); if events > 0 { - return Ok(events); + return Some(Ok(events)); } let current_time_ms = crate::trap::uptime_msec(); if timeout_msecs < (1 << 31) && current_time_ms - begin_time_ms > timeout_msecs { - return Ok(0); + return Some(Ok(0)); } - - // NOTE: To run rustc, uncomment yield_now and comment Condvar. - // Waking up from pipe is unimplemented now. - // thread::yield_now(); - Condvar::wait_any(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)]); - } + return None; + }) } pub fn sys_select( @@ -180,7 +179,7 @@ impl Syscall<'_> { drop(proc); let begin_time_ms = crate::trap::uptime_msec(); - loop { + Condvar::wait_events(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)], move || { let proc = self.process(); let mut events = 0; for (&fd, file_like) in proc.files.iter() { @@ -190,7 +189,10 @@ impl Syscall<'_> { if !err_fds.contains(fd) && !read_fds.contains(fd) && !write_fds.contains(fd) { continue; } - let status = file_like.poll()?; + let status = match file_like.poll() { + Ok(ret) => ret, + Err(err) => return Some(Err(err)), + }; if status.error && err_fds.contains(fd) { err_fds.set(fd); events += 1; @@ -207,23 +209,23 @@ impl Syscall<'_> { drop(proc); if events > 0 { - return Ok(events); + return Some(Ok(events)); } if timeout_msecs == 0 { // no timeout, return now; - return Ok(0); + return Some(Ok(0)); } let current_time_ms = crate::trap::uptime_msec(); // infinity check if timeout_msecs < (1 << 31) && current_time_ms - begin_time_ms > timeout_msecs as usize { - return Ok(0); + return Some(Ok(0)); } - Condvar::wait_any(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)]); - } + return None; + }) } pub fn sys_readv(&mut self, fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResult { @@ -386,7 +388,7 @@ impl Syscall<'_> { flags: usize, ) -> SysResult { let proc = self.process(); - let path = unsafe { check_and_clone_cstr(path)? }; + let path = check_and_clone_cstr(path)?; let stat_ref = unsafe { self.vm().check_write_ptr(stat_ptr)? }; let flags = AtFlags::from_bits_truncate(flags); info!( @@ -537,7 +539,7 @@ impl Syscall<'_> { pub fn sys_chdir(&mut self, path: *const u8) -> SysResult { let mut proc = self.process(); - let path = unsafe { check_and_clone_cstr(path)? }; + let path = check_and_clone_cstr(path)?; if !proc.pid.is_init() { // we trust pid 0 process info!("chdir: path: {:?}", path); @@ -590,8 +592,8 @@ impl Syscall<'_> { newpath: *const u8, ) -> SysResult { let proc = self.process(); - let oldpath = unsafe { check_and_clone_cstr(oldpath)? }; - let newpath = unsafe { check_and_clone_cstr(newpath)? }; + let oldpath = check_and_clone_cstr(oldpath)?; + let newpath = check_and_clone_cstr(newpath)?; info!( "renameat: olddirfd: {}, oldpath: {:?}, newdirfd: {}, newpath: {:?}", olddirfd as isize, oldpath, newdirfd as isize, newpath @@ -611,7 +613,7 @@ impl Syscall<'_> { pub fn sys_mkdirat(&mut self, dirfd: usize, path: *const u8, mode: usize) -> SysResult { let proc = self.process(); - let path = unsafe { check_and_clone_cstr(path)? }; + let path = check_and_clone_cstr(path)?; // TODO: check pathname info!( "mkdirat: dirfd: {}, path: {:?}, mode: {:#o}", @@ -629,7 +631,7 @@ impl Syscall<'_> { pub fn sys_rmdir(&mut self, path: *const u8) -> SysResult { let proc = self.process(); - let path = unsafe { check_and_clone_cstr(path)? }; + let path = check_and_clone_cstr(path)?; info!("rmdir: path: {:?}", path); let (dir_path, file_name) = split_path(&path); @@ -655,8 +657,8 @@ impl Syscall<'_> { flags: usize, ) -> SysResult { let proc = self.process(); - let oldpath = unsafe { check_and_clone_cstr(oldpath)? }; - let newpath = unsafe { check_and_clone_cstr(newpath)? }; + let oldpath = check_and_clone_cstr(oldpath)?; + let newpath = check_and_clone_cstr(newpath)?; let flags = AtFlags::from_bits_truncate(flags); info!( "linkat: olddirfd: {}, oldpath: {:?}, newdirfd: {}, newpath: {:?}, flags: {:?}", @@ -834,11 +836,8 @@ impl Syscall<'_> { return Ok(total_written); } - pub fn sys_fcntl(&mut self, fd : usize, cmd : usize, arg : usize) -> SysResult{ - info!( - "fcntl: fd: {}, cmd: {:x}, arg: {}", - fd, cmd, arg - ); + pub fn sys_fcntl(&mut self, fd: usize, cmd: usize, arg: usize) -> SysResult { + info!("fcntl: fd: {}, cmd: {:x}, arg: {}", fd, cmd, arg); let mut proc = self.process(); let file_like = proc.get_file_like(fd)?; file_like.fcntl(cmd, arg) @@ -886,11 +885,11 @@ impl Process { match path { "/proc/self/exe" => { return Ok(Arc::new(Pseudo::new(&self.exec_path, FileType::SymLink))); - }, + } "/dev/fb0" => { info!("/dev/fb0 will be opened"); return Ok(Arc::new(Vga::default())); - }, + } _ => {} } let (fd_dir_path, fd_name) = split_path(&path); diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 44ac35f..5727802 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -1,7 +1,5 @@ use rcore_memory::memory_set::handler::{Delay, File, Linear}; use rcore_memory::memory_set::MemoryAttr; -use rcore_memory::paging::PageTable; -use rcore_memory::Page; use rcore_memory::PAGE_SIZE; use crate::memory::GlobalFrameAlloc; @@ -53,7 +51,6 @@ impl Syscall<'_> { ); return Ok(addr); } else { - let file = proc.get_file(fd)?; info!("mmap path is {} ", &*file.path); match &*file.path { @@ -64,15 +61,15 @@ impl Syscall<'_> { addr, addr + len, prot.to_attr(), - Linear::new( - ( fb.bus_addr() - addr ) as isize, - ), + Linear::new((fb.bus_addr() - addr) as isize), "mmap_file", ); info!("mmap for /dev/fb0"); + return Ok(addr); + } else { + return Err(SysError::ENOENT); } - return Ok(addr); - }, + } _ => { let inode = file.inode(); self.vm().push( @@ -89,7 +86,7 @@ impl Syscall<'_> { "mmap_file", ); return Ok(addr); - }, + } }; } } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 7771d39..0317b14 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -10,19 +10,19 @@ use rcore_memory::VMError; use crate::arch::cpu; use crate::arch::interrupt::TrapFrame; use crate::arch::syscall::*; -use crate::memory::{copy_from_user_u8, copy_from_user_usize, MemorySet}; +use crate::memory::{copy_from_user, MemorySet}; use crate::process::*; use crate::sync::{Condvar, MutexGuard, SpinNoIrq}; use crate::thread; use crate::util; -use self::custom::*; -use self::fs::*; -use self::mem::*; -use self::misc::*; +pub use self::custom::*; +pub use self::fs::*; +pub use self::mem::*; +pub use self::misc::*; pub use self::net::*; -use self::proc::*; -use self::time::*; +pub use self::proc::*; +pub use self::time::*; mod custom; mod fs; @@ -32,7 +32,9 @@ mod net; mod proc; mod time; +#[cfg(feature = "profile")] use alloc::collections::BTreeMap; +#[cfg(feature = "profile")] use spin::Mutex; #[cfg(feature = "profile")] @@ -100,9 +102,12 @@ impl Syscall<'_> { SYS_WRITEV => self.sys_writev(args[0], args[1] as *const IoVec, args[2]), SYS_SENDFILE => self.sys_sendfile(args[0], args[1], args[2] as *mut usize, args[3]), SYS_FCNTL => { - info!("SYS_FCNTL : {} {} {} {}", args[0], args[1], args[2], args[3]); + info!( + "SYS_FCNTL : {} {} {} {}", + args[0], args[1], args[2], args[3] + ); self.sys_fcntl(args[0], args[1], args[2]) - }, + } SYS_FLOCK => self.unimplemented("flock", Ok(0)), SYS_FSYNC => self.sys_fsync(args[0]), SYS_FDATASYNC => self.sys_fdatasync(args[0]), @@ -291,6 +296,7 @@ impl Syscall<'_> { SYS_GETRANDOM => { self.sys_getrandom(args[0] as *mut u8, args[1] as usize, args[2] as u32) } + SYS_RT_SIGQUEUEINFO => self.unimplemented("rt_sigqueueinfo", Ok(0)), // custom SYS_MAP_PCI_DEVICE => self.sys_map_pci_device(args[0], args[1]), @@ -552,45 +558,32 @@ pub fn spin_and_wait(condvars: &[&Condvar], mut action: impl FnMut() -> Optio return result; } } - loop { - if let Some(result) = action() { - return result; - } - Condvar::wait_any(&condvars); - } + Condvar::wait_events(&condvars, action) } pub fn check_and_clone_cstr(user: *const u8) -> Result { let mut buffer = Vec::new(); for i in 0.. { let addr = unsafe { user.add(i) }; - if let Some(data) = copy_from_user_u8(addr) { - if data > 0 { - buffer.push(data); - } else { - break; - } - } else { - return Err(SysError::EFAULT); + let data = copy_from_user(addr).ok_or(SysError::EFAULT)?; + if data == 0 { + break; } + buffer.push(data); } - return String::from_utf8(buffer).map_err(|_| SysError::EFAULT); + String::from_utf8(buffer).map_err(|_| SysError::EFAULT) } pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result, SysError> { let mut buffer = Vec::new(); for i in 0.. { let addr = unsafe { user.add(i) }; - if let Some(str_addr) = copy_from_user_usize(addr as *const usize) { - if str_addr > 0 { - let string = check_and_clone_cstr(str_addr as *const u8)?; - buffer.push(string); - } else { - break; - } - } else { - return Err(SysError::EFAULT); + let str_ptr = copy_from_user(addr).ok_or(SysError::EFAULT)?; + if str_ptr.is_null() { + break; } + let string = check_and_clone_cstr(str_ptr)?; + buffer.push(string); } - return Ok(buffer); + Ok(buffer) } diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index 2edb9d6..3197ab7 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -6,7 +6,7 @@ use crate::fs::FileLike; use crate::memory::MemorySet; use crate::net::{ Endpoint, LinkLevelEndpoint, NetlinkEndpoint, NetlinkSocketState, PacketSocketState, - RawSocketState, Socket, TcpSocketState, UdpSocketState, SOCKETS, + RawSocketState, Socket, TcpSocketState, UdpSocketState, }; use alloc::boxed::Box; use core::cmp::min; @@ -462,13 +462,13 @@ impl SockAddr { return Ok(0); } - let addr_len = unsafe { vm.check_write_ptr(addr_len)? }; + let addr_len = vm.check_write_ptr(addr_len)?; let max_addr_len = *addr_len as usize; let full_len = self.len()?; let written_len = min(max_addr_len, full_len); if written_len > 0 { - let target = unsafe { vm.check_write_array(addr as *mut u8, written_len)? }; + let target = vm.check_write_array(addr as *mut u8, written_len)?; let source = slice::from_raw_parts(&self as *const SockAddr as *const u8, written_len); target.copy_from_slice(source); } diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 533fa43..a6d6d71 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -1,7 +1,6 @@ //! Syscalls for process use super::*; -use crate::fs::INodeExt; impl Syscall<'_> { /// Fork the current process. Return the child's PID. @@ -153,9 +152,9 @@ impl Syscall<'_> { path, argv, envp ); let mut proc = self.process(); - let path = unsafe { check_and_clone_cstr(path)? }; - let args = unsafe { check_and_clone_cstr_array(argv)? }; - let envs = unsafe { check_and_clone_cstr_array(envp)? }; + let path = check_and_clone_cstr(path)?; + let args = check_and_clone_cstr_array(argv)?; + let envs = check_and_clone_cstr_array(envp)?; if args.is_empty() { error!("exec: args is null"); diff --git a/kernel/targets/mipsel.json b/kernel/targets/mipsel.json index 346e3e8..7cc6d7d 100644 --- a/kernel/targets/mipsel.json +++ b/kernel/targets/mipsel.json @@ -7,7 +7,7 @@ "target-pointer-width": "32", "target-c-int-width": "32", "os": "none", - "features": "+mips32r2,+soft-float", + "features": "+mips32r2,+single-float", "max-atomic-width": "32", "linker": "rust-lld", "linker-flavor": "ld.lld",