From bfe03b8ea04d4fb6acae3a1a23408a41804f2848 Mon Sep 17 00:00:00 2001 From: equation314 Date: Mon, 6 May 2019 23:30:01 +0800 Subject: [PATCH 01/10] aarch64: fix vm clone fault in fork --- kernel/Cargo.lock | 8 +++---- kernel/Cargo.toml | 2 +- kernel/src/arch/aarch64/paging.rs | 39 ++++++++----------------------- 3 files changed, 15 insertions(+), 34 deletions(-) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index eea1e41..b76366e 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -14,8 +14,8 @@ dependencies = [ [[package]] name = "aarch64" -version = "2.2.2" -source = "git+https://github.com/rcore-os/aarch64#14a08f4d285ae0ff515b03bff9f5e66eb68feaed" +version = "2.5.0" +source = "git+https://github.com/rcore-os/aarch64#e52eae8dc35069661bb948b2c4443af98d1e62d7" 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)", @@ -359,7 +359,7 @@ dependencies = [ name = "rcore" version = "0.2.0" dependencies = [ - "aarch64 2.2.2 (git+https://github.com/rcore-os/aarch64)", + "aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)", "apic 0.1.0 (git+https://github.com/rcore-os/apic-rs)", "bcm2837 0.1.0 (git+https://github.com/rcore-os/bcm2837)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -653,7 +653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aarch64 2.2.2 (git+https://github.com/equation314/aarch64)" = "" -"checksum aarch64 2.2.2 (git+https://github.com/rcore-os/aarch64)" = "" +"checksum aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)" = "" "checksum apic 0.1.0 (git+https://github.com/rcore-os/apic-rs)" = "" "checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" "checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 8ef38d7..2c3ed11 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -81,7 +81,7 @@ pc-keyboard = "0.5" riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } [target.'cfg(target_arch = "aarch64")'.dependencies] -aarch64 = { git = "https://github.com/rcore-os/aarch64" } +aarch64 = { git = "https://github.com/rcore-os/aarch64", version = "2.5.0" } bcm2837 = { git = "https://github.com/rcore-os/bcm2837", optional = true } [target.'cfg(target_arch = "mips")'.dependencies] diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index fc03b45..4d9e4a3 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -12,7 +12,7 @@ use rcore_memory::paging::*; use crate::consts::{KERNEL_OFFSET, KERNEL_PML4, RECURSIVE_INDEX}; use crate::memory::{active_table, alloc_frame, dealloc_frame}; -pub struct ActivePageTable(RecursivePageTable<'static>); +pub struct ActivePageTable(RecursivePageTable); pub struct PageEntry(PageTableEntry); @@ -34,8 +34,7 @@ impl PageTable for ActivePageTable { } fn unmap(&mut self, addr: usize) { - let (_frame, flush) = self.0.unmap(Page::of_addr(addr as u64)).unwrap(); - flush.flush(); + self.0.unmap(Page::of_addr(addr as u64)).unwrap().1.flush(); } fn get_entry(&mut self, vaddr: usize) -> Option<&mut Entry> { @@ -50,16 +49,9 @@ impl PageTableExt for ActivePageTable { const TEMP_PAGE_ADDR: usize = KERNEL_OFFSET | 0xcafeb000; } -const ROOT_PAGE_TABLE: *mut Aarch64PageTable = (KERNEL_OFFSET - | (RECURSIVE_INDEX << 39) - | (RECURSIVE_INDEX << 30) - | (RECURSIVE_INDEX << 21) - | (RECURSIVE_INDEX << 12)) - as *mut Aarch64PageTable; - impl ActivePageTable { pub unsafe fn new() -> Self { - ActivePageTable(RecursivePageTable::new(&mut *(ROOT_PAGE_TABLE as *mut _)).unwrap()) + ActivePageTable(RecursivePageTable::new(RECURSIVE_INDEX as u16)) } } @@ -198,12 +190,6 @@ pub struct InactivePageTable0 { impl InactivePageTable for InactivePageTable0 { type Active = ActivePageTable; - fn new() -> Self { - // When the new InactivePageTable is created for the user MemorySet, it's use ttbr1 as the - // TTBR. And the kernel TTBR ttbr0 will never changed, so we needn't call map_kernel() - Self::new_bare() - } - fn new_bare() -> Self { let target = alloc_frame().expect("failed to allocate frame"); let frame = Frame::of_addr(target as u64); @@ -220,17 +206,8 @@ impl InactivePageTable for InactivePageTable0 { } fn map_kernel(&mut self) { - let table = unsafe { &mut *ROOT_PAGE_TABLE }; - let e0 = table[KERNEL_PML4].clone(); - assert!(!e0.is_unused()); - - self.edit(|_| { - table[KERNEL_PML4].set_frame( - Frame::containing_address(e0.addr()), - EF::default(), - MairNormal::attr_value(), - ); - }); + // When the new InactivePageTable is created for the user MemorySet, it's use ttbr0 as the + // TTBR. And the kernel TTBR ttbr1 will never changed, so we needn't call map_kernel() } fn token(&self) -> usize { @@ -250,7 +227,11 @@ impl InactivePageTable for InactivePageTable0 { } fn edit(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T { - let target = ttbr_el1_read(1).start_address().as_u64() as usize; + let target = ttbr_el1_read(1); + if self.p4_frame == target { + return f(&mut active_table()); + } + let target = target.start_address().as_u64() as usize; active_table().with_temporary_map( target, |active_table, p4_table: &mut Aarch64PageTable| { From 2f2cbb81acdcedb156a145548a8d419e84fa1b66 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Tue, 7 May 2019 08:40:25 +0800 Subject: [PATCH 02/10] Embed rocket chip dtb in code --- kernel/Makefile | 7 +- kernel/build.rs | 6 +- .../arch/riscv32/board/rocket_chip/device.dts | 112 ++++++++++++++++++ .../arch/riscv32/board/rocket_chip/linker.ld | 50 ++++++++ .../src/arch/riscv32/board/rocket_chip/mod.rs | 18 +++ kernel/src/arch/riscv32/memory.rs | 2 +- kernel/src/arch/riscv32/mod.rs | 21 +++- 7 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 kernel/src/arch/riscv32/board/rocket_chip/device.dts create mode 100644 kernel/src/arch/riscv32/board/rocket_chip/linker.ld create mode 100644 kernel/src/arch/riscv32/board/rocket_chip/mod.rs diff --git a/kernel/Makefile b/kernel/Makefile index d8bb97a..faba997 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -75,10 +75,13 @@ board := raspi3 need_bootloader := true endif -# currently only mipsel architecture needs DTB linked to the kernel +# currently only mipsel architecture and rocket-chip needs DTB linked to the kernel ifeq ($(arch), mipsel) dtb := src/arch/$(arch)/board/$(board)/device.dtb endif +ifeq ($(board), rocket_chip) +dtb := src/arch/riscv32/board/$(board)/device.dtb +endif # mipssim does not support SMP ifeq ($(board), mipssim) @@ -330,6 +333,8 @@ ifeq ($(arch), x86_64) else ifeq ($(arch), $(filter $(arch), riscv32 riscv64)) ifeq ($(board), k210) @cp src/arch/riscv32/board/k210/linker.ld src/arch/riscv32/boot/linker64.ld +else ifeq ($(board), rocket_chip) + @cp src/arch/riscv32/board/rocket_chip/linker.ld src/arch/riscv32/boot/linker64.ld else @cp src/arch/riscv32/board/u540/linker.ld src/arch/riscv32/boot/linker64.ld endif diff --git a/kernel/build.rs b/kernel/build.rs index 8e1440f..286606b 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -16,7 +16,11 @@ fn main() { gen_vector_asm().unwrap(); } "riscv32" => {} - "riscv64" => {} + "riscv64" => { + if board == "rocket_chip" { + gen_dtb_asm(&String::from("riscv32"), &board).unwrap(); + } + } "mipsel" => { gen_dtb_asm(&arch, &board).unwrap(); } diff --git a/kernel/src/arch/riscv32/board/rocket_chip/device.dts b/kernel/src/arch/riscv32/board/rocket_chip/device.dts new file mode 100644 index 0000000..774c238 --- /dev/null +++ b/kernel/src/arch/riscv32/board/rocket_chip/device.dts @@ -0,0 +1,112 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "freechips,rocketchip-unknown-dev"; + model = "freechips,rocketchip-unknown"; + L14: cpus { + #address-cells = <1>; + #size-cells = <0>; + L5: cpu@0 { + clock-frequency = <0>; + compatible = "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <16384>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <16384>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + next-level-cache = <&L6>; + reg = <0>; + riscv,isa = "rv64imafdc"; + status = "okay"; + timebase-frequency = <1000000>; + tlb-split; + L3: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + L6: memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x10000000>; + }; + L13: soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "freechips,rocketchip-unknown-soc", "simple-bus"; + ranges; + L11: blkdev-controller@10015000 { + compatible = "ucbbar,blkdev"; + interrupt-parent = <&L0>; + interrupts = <3>; + reg = <0x10015000 0x1000>; + reg-names = "control"; + }; + L1: clint@2000000 { + compatible = "riscv,clint0"; + interrupts-extended = <&L3 3 &L3 7>; + reg = <0x2000000 0x10000>; + reg-names = "control"; + }; + L2: debug-controller@0 { + compatible = "sifive,debug-013", "riscv,debug-013"; + interrupts-extended = <&L3 65535>; + reg = <0x0 0x1000>; + reg-names = "control"; + }; + L8: error-device@3000 { + compatible = "sifive,error0"; + reg = <0x3000 0x1000>; + reg-names = "mem"; + }; + L10: external-interrupts { + interrupt-parent = <&L0>; + interrupts = <1 2>; + }; + L0: interrupt-controller@c000000 { + #interrupt-cells = <1>; + compatible = "riscv,plic0"; + interrupt-controller; + interrupts-extended = <&L3 11 &L3 9>; + reg = <0xc000000 0x4000000>; + reg-names = "control"; + riscv,max-priority = <7>; + riscv,ndev = <3>; + }; + L7: mmio-port-axi4@60000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x60000000 0x60000000 0x20000000>; + + serial0: serial@60000000 { + compatible = "xlnx,xps-uartlite-1.00.a"; + reg = <0x0 0x6000000 0x1000>; + interrupt-parent = <&L10>; + interrupts = <1>; + }; + + serial_net: serial@60010000 { + compatible = "xlnx,xps-uartlite-1.00.a"; + reg = <0x0 0x60010000 0x1000>; + interrupt-parent = <&L10>; + interrupts = <2>; + }; + }; + L9: rom@10000 { + compatible = "sifive,rom0"; + reg = <0x10000 0x10000>; + reg-names = "mem"; + }; + }; +}; \ No newline at end of file diff --git a/kernel/src/arch/riscv32/board/rocket_chip/linker.ld b/kernel/src/arch/riscv32/board/rocket_chip/linker.ld new file mode 100644 index 0000000..ba9d08a --- /dev/null +++ b/kernel/src/arch/riscv32/board/rocket_chip/linker.ld @@ -0,0 +1,50 @@ +/* Copy from bbl-ucore : https://ring00.github.io/bbl-ucore */ + +/* Simple linker script for the ucore kernel. + See the GNU ld 'info' manual ("info ld") to learn the syntax. */ + +OUTPUT_ARCH(riscv) +ENTRY(_start) + +BASE_ADDRESS = 0xffffffffc0200000; + +SECTIONS +{ + /* Load the kernel at this address: "." means the current address */ + . = BASE_ADDRESS; + start = .; + + .text : { + stext = .; + *(.text.entry) + *(.text .text.*) + . = ALIGN(4K); + etext = .; + } + + .rodata : { + srodata = .; + *(.rodata .rodata.*) + *(.dtb) + . = ALIGN(4K); + erodata = .; + } + + .data : { + sdata = .; + *(.data .data.*) + edata = .; + } + + .stack : { + *(.bss.stack) + } + + .bss : { + sbss = .; + *(.bss .bss.*) + ebss = .; + } + + PROVIDE(end = .); +} diff --git a/kernel/src/arch/riscv32/board/rocket_chip/mod.rs b/kernel/src/arch/riscv32/board/rocket_chip/mod.rs new file mode 100644 index 0000000..0e2ac03 --- /dev/null +++ b/kernel/src/arch/riscv32/board/rocket_chip/mod.rs @@ -0,0 +1,18 @@ +use super::consts::KERNEL_OFFSET; + +/// Mask all external interrupt except serial. +pub unsafe fn init_external_interrupt() { + const HART0_S_MODE_INTERRUPT_ENABLES: *mut u64 = (KERNEL_OFFSET + 0x0C00_2080) as *mut u64; + HART0_S_MODE_INTERRUPT_ENABLES.write_volatile(0xf); +} + +/// Claim and complete external interrupt by reading and writing to +/// PLIC Interrupt Claim/Complete Register. +pub unsafe fn handle_external_interrupt() { + const HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 = + (KERNEL_OFFSET + 0x0C20_2000) as *mut u32; + // claim + let source = HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE.read_volatile(); + // complete + HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE.write_volatile(source); +} \ No newline at end of file diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index 314c7f2..04a3388 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -92,7 +92,7 @@ fn remap_the_kernel(dtb: usize) { Linear::new(offset), "bss", ); - // TODO: dtb on rocket chip + // dtb on rocket chip is embedded into kernel #[cfg(not(feature = "board_rocket_chip"))] ms.push( dtb, diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index 75b7ccc..e34c2ea 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -1,7 +1,10 @@ #[cfg(feature = "board_u540")] #[path = "board/u540/mod.rs"] mod board; -#[cfg(not(feature = "board_u540"))] +#[cfg(feature = "board_rocket_chip")] +#[path = "board/rocket_chip/mod.rs"] +mod board; +#[cfg(not(any(feature = "board_u540", feature = "board_rocket_chip")))] #[path = "board/virt/mod.rs"] mod board; @@ -23,10 +26,20 @@ use log::*; #[no_mangle] pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! { - let device_tree_vaddr = device_tree_paddr - MEMORY_OFFSET + KERNEL_OFFSET; + let mut device_tree_vaddr = device_tree_paddr - MEMORY_OFFSET + KERNEL_OFFSET; unsafe { cpu::set_cpu_id(hartid); + + } + + #[cfg(feature = "board_rocket_chip")] + { + extern "C" { + fn _dtb_start(); + fn _dtb_end(); + } + device_tree_vaddr = _dtb_start as usize; } if hartid != BOOT_HART_ID { @@ -53,7 +66,7 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! { memory::init(device_tree_vaddr); timer::init(); // FIXME: init driver on u540 - #[cfg(not(any(feature = "board_u540", feature = "board_rocket_chip")))] + #[cfg(not(any(feature = "board_u540")))] crate::drivers::init(device_tree_vaddr); #[cfg(not(feature = "board_k210"))] unsafe { @@ -115,3 +128,5 @@ global_asm!(include_str!("boot/entry64.asm")); #[cfg(feature = "board_k210")] global_asm!(include_str!("boot/entry_k210.asm")); global_asm!(include_str!("boot/trap.asm")); +#[cfg(feature = "board_rocket_chip")] +global_asm!(include_str!("boot/dtb.gen.s")); From 03a8b3e449cc3885bf77302492efc7697aefe42f Mon Sep 17 00:00:00 2001 From: equation314 Date: Tue, 7 May 2019 22:37:53 +0800 Subject: [PATCH 03/10] aarch64: disable FP/SIMD registers again, update crates --- bootloader/Cargo.lock | 16 +++++++-------- bootloader/Cargo.toml | 4 ++-- bootloader/src/main.rs | 10 +++------- kernel/Cargo.lock | 25 ++++++------------------ kernel/Cargo.toml | 2 +- kernel/src/arch/aarch64/interrupt/mod.rs | 8 +++----- kernel/targets/aarch64.json | 2 +- 7 files changed, 24 insertions(+), 43 deletions(-) diff --git a/bootloader/Cargo.lock b/bootloader/Cargo.lock index 2100950..4eaba05 100644 --- a/bootloader/Cargo.lock +++ b/bootloader/Cargo.lock @@ -2,8 +2,8 @@ # It is not intended for manual editing. [[package]] name = "aarch64" -version = "2.2.2" -source = "git+https://github.com/rcore-os/aarch64#14a08f4d285ae0ff515b03bff9f5e66eb68feaed" +version = "2.5.0" +source = "git+https://github.com/rcore-os/aarch64#797c24f07f9d90542eb094530b6f63fe3ea7dded" 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)", @@ -14,8 +14,8 @@ dependencies = [ [[package]] name = "bcm2837" -version = "0.1.0" -source = "git+https://github.com/rcore-os/bcm2837#446f0ea04deb5216ba5e08f10af36e5c1729e6fd" +version = "1.0.0" +source = "git+https://github.com/rcore-os/bcm2837#b29a8db5504b7eaa6f8adf2c3ff916d1ffd15194" dependencies = [ "volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -98,8 +98,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "rcore-bootloader" version = "0.1.0" dependencies = [ - "aarch64 2.2.2 (git+https://github.com/rcore-os/aarch64)", - "bcm2837 0.1.0 (git+https://github.com/rcore-os/bcm2837)", + "aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)", + "bcm2837 1.0.0 (git+https://github.com/rcore-os/bcm2837)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -205,8 +205,8 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum aarch64 2.2.2 (git+https://github.com/rcore-os/aarch64)" = "" -"checksum bcm2837 0.1.0 (git+https://github.com/rcore-os/bcm2837)" = "" +"checksum aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)" = "" +"checksum bcm2837 1.0.0 (git+https://github.com/rcore-os/bcm2837)" = "" "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 cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" diff --git a/bootloader/Cargo.toml b/bootloader/Cargo.toml index 26ecb92..7fca683 100644 --- a/bootloader/Cargo.toml +++ b/bootloader/Cargo.toml @@ -9,8 +9,8 @@ xmas-elf = "0.6.2" fixedvec = "0.2.3" [target.'cfg(target_arch = "aarch64")'.dependencies] -aarch64 = { git = "https://github.com/rcore-os/aarch64" } -bcm2837 = { git = "https://github.com/rcore-os/bcm2837" } +aarch64 = { git = "https://github.com/rcore-os/aarch64", version = "2.5.0" } +bcm2837 = { git = "https://github.com/rcore-os/bcm2837", version = "1.0.0" } [build-dependencies] cc = "1.0" diff --git a/bootloader/src/main.rs b/bootloader/src/main.rs index c886029..e9c16a5 100644 --- a/bootloader/src/main.rs +++ b/bootloader/src/main.rs @@ -10,11 +10,7 @@ extern crate xmas_elf; use core::mem::transmute; use core::slice; use fixedvec::FixedVec; -use xmas_elf::{ - header, - program::{ProgramHeader, ProgramHeader32, ProgramHeader64}, - ElfFile, -}; +use xmas_elf::{header, program::{self, ProgramHeader}, ElfFile}; #[cfg(target_arch = "aarch64")] #[path = "arch/aarch64/mod.rs"] @@ -46,7 +42,7 @@ pub extern "C" fn boot_main() -> ! { let kernel_elf = ElfFile::new(kernel).unwrap(); header::sanity_check(&kernel_elf).unwrap(); - let mut preallocated_space = alloc_stack!([ProgramHeader64; 32]); + let mut preallocated_space = alloc_stack!([program::ProgramHeader64; 32]); let mut segments = FixedVec::new(&mut preallocated_space); for program_header in kernel_elf.program_iter() { @@ -76,7 +72,7 @@ pub extern "C" fn boot_main() -> ! { let kernel_elf = ElfFile::new(kernel).unwrap(); header::sanity_check(&kernel_elf).unwrap(); - let mut preallocated_space = alloc_stack!([ProgramHeader32; 32]); + let mut preallocated_space = alloc_stack!([program::ProgramHeader32; 32]); let mut segments = FixedVec::new(&mut preallocated_space); for program_header in kernel_elf.program_iter() { diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index b76366e..15dc395 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -1,21 +1,9 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "aarch64" -version = "2.2.2" -source = "git+https://github.com/equation314/aarch64#14a08f4d285ae0ff515b03bff9f5e66eb68feaed" -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)", - "register 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "aarch64" version = "2.5.0" -source = "git+https://github.com/rcore-os/aarch64#e52eae8dc35069661bb948b2c4443af98d1e62d7" +source = "git+https://github.com/rcore-os/aarch64#797c24f07f9d90542eb094530b6f63fe3ea7dded" 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)", @@ -52,10 +40,10 @@ dependencies = [ [[package]] name = "bcm2837" -version = "0.1.0" -source = "git+https://github.com/rcore-os/bcm2837#446f0ea04deb5216ba5e08f10af36e5c1729e6fd" +version = "1.0.0" +source = "git+https://github.com/rcore-os/bcm2837#b29a8db5504b7eaa6f8adf2c3ff916d1ffd15194" dependencies = [ - "aarch64 2.2.2 (git+https://github.com/equation314/aarch64)", + "aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)", "volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -361,7 +349,7 @@ version = "0.2.0" dependencies = [ "aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)", "apic 0.1.0 (git+https://github.com/rcore-os/apic-rs)", - "bcm2837 0.1.0 (git+https://github.com/rcore-os/bcm2837)", + "bcm2837 1.0.0 (git+https://github.com/rcore-os/bcm2837)", "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)", @@ -652,12 +640,11 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum aarch64 2.2.2 (git+https://github.com/equation314/aarch64)" = "" "checksum aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)" = "" "checksum apic 0.1.0 (git+https://github.com/rcore-os/apic-rs)" = "" "checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" "checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a" -"checksum bcm2837 0.1.0 (git+https://github.com/rcore-os/bcm2837)" = "" +"checksum bcm2837 1.0.0 (git+https://github.com/rcore-os/bcm2837)" = "" "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)" = "" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 2c3ed11..9547d31 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -82,7 +82,7 @@ riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } [target.'cfg(target_arch = "aarch64")'.dependencies] aarch64 = { git = "https://github.com/rcore-os/aarch64", version = "2.5.0" } -bcm2837 = { git = "https://github.com/rcore-os/bcm2837", optional = true } +bcm2837 = { git = "https://github.com/rcore-os/bcm2837", version = "1.0.0", optional = true } [target.'cfg(target_arch = "mips")'.dependencies] mips = "^0.2.0" diff --git a/kernel/src/arch/aarch64/interrupt/mod.rs b/kernel/src/arch/aarch64/interrupt/mod.rs index 70b05cb..c7f0050 100644 --- a/kernel/src/arch/aarch64/interrupt/mod.rs +++ b/kernel/src/arch/aarch64/interrupt/mod.rs @@ -11,12 +11,10 @@ pub use self::handler::*; /// Set the exception vector address pub fn init() { - unsafe { - asm!( - "adr x0, __vectors; - msr vbar_el1, x0" - ); + extern "C" { + fn __vectors(); } + VBAR_EL1.set(__vectors as u64); } /// Enable the interrupt (only IRQ). diff --git a/kernel/targets/aarch64.json b/kernel/targets/aarch64.json index 149246a..25078de 100644 --- a/kernel/targets/aarch64.json +++ b/kernel/targets/aarch64.json @@ -20,7 +20,7 @@ }, "llvm-target": "aarch64-unknown-none", "no-compiler-rt": true, - "features": "+a53,+strict-align,-neon", + "features": "+a53,+strict-align,-neon,-fp-armv8", "max-atomic-width": 128, "os": "none", "panic": "abort", From 2fb09109bbbe3f8202cfbb088fd1c4e28ee26f4f Mon Sep 17 00:00:00 2001 From: equation314 Date: Wed, 8 May 2019 00:04:41 +0800 Subject: [PATCH 04/10] Fix wrong display in console driver --- kernel/src/arch/aarch64/board/raspi3/mod.rs | 7 ++++++- kernel/src/drivers/console/mod.rs | 4 ++-- kernel/src/util/escape_parser.rs | 8 ++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs index 0480e35..3caf828 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mod.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -78,5 +78,10 @@ pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> FramebufferResult { ))?; } - Ok((info, fb::ColorConfig::BGRA8888, vaddr)) + let color_config = match info.depth { + 16 => ColorConfig::RGB565, + 32 => ColorConfig::BGRA8888, + _ => Err(format!("unsupported color depth {}", info.depth))?, + }; + Ok((info, color_config, vaddr)) } diff --git a/kernel/src/drivers/console/mod.rs b/kernel/src/drivers/console/mod.rs index 853cce0..fb06376 100644 --- a/kernel/src/drivers/console/mod.rs +++ b/kernel/src/drivers/console/mod.rs @@ -28,7 +28,7 @@ pub struct ConsoleChar { impl Default for ConsoleChar { fn default() -> Self { ConsoleChar { - ascii_char: 0, + ascii_char: b' ', attr: CharacterAttribute::default(), } } @@ -152,7 +152,7 @@ impl Console { fn new_line(&mut self) { let attr_blank = ConsoleChar { - ascii_char: 0, + ascii_char: b' ', attr: self.parser.char_attribute(), }; for j in self.col..self.buf.num_col { diff --git a/kernel/src/util/escape_parser.rs b/kernel/src/util/escape_parser.rs index 472f437..38b9269 100644 --- a/kernel/src/util/escape_parser.rs +++ b/kernel/src/util/escape_parser.rs @@ -156,8 +156,12 @@ impl EscapeParser { } let csi = CSI::new(byte, &self.params); if csi == CSI::SGR { - for ¶m in self.params.iter() { - self.char_attr.apply_sgr(param); + if self.params.is_empty() { + self.char_attr.apply_sgr(0); + } else { + for ¶m in self.params.iter() { + self.char_attr.apply_sgr(param); + } } } self.status = ParseStatus::Text; From 2e599b0bab2ee522bd11d0c665207841939d2711 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 8 May 2019 11:02:23 +0800 Subject: [PATCH 05/10] Fix Rocket Chip serial interrupt --- kernel/Makefile | 2 +- .../arch/riscv32/board/rocket_chip/device.dts | 12 ++++---- .../src/arch/riscv32/board/rocket_chip/mod.rs | 30 ++++++++++++++++++- kernel/src/arch/riscv32/interrupt.rs | 2 +- kernel/src/arch/riscv32/memory.rs | 27 +++++++++++++++++ kernel/src/arch/riscv32/mod.rs | 1 - kernel/src/fs/stdio.rs | 14 +-------- 7 files changed, 65 insertions(+), 23 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index faba997..b0ccb2a 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -75,7 +75,7 @@ board := raspi3 need_bootloader := true endif -# currently only mipsel architecture and rocket-chip needs DTB linked to the kernel +# currently only mipsel architecture and rocket-chip need DTB linked to the kernel ifeq ($(arch), mipsel) dtb := src/arch/$(arch)/board/$(board)/device.dtb endif diff --git a/kernel/src/arch/riscv32/board/rocket_chip/device.dts b/kernel/src/arch/riscv32/board/rocket_chip/device.dts index 774c238..42cf330 100644 --- a/kernel/src/arch/riscv32/board/rocket_chip/device.dts +++ b/kernel/src/arch/riscv32/board/rocket_chip/device.dts @@ -91,16 +91,16 @@ serial0: serial@60000000 { compatible = "xlnx,xps-uartlite-1.00.a"; - reg = <0x0 0x6000000 0x1000>; - interrupt-parent = <&L10>; + reg = <0x6000000 0x1000>; + interrupt-parent = <&axi_intc>; interrupts = <1>; }; - serial_net: serial@60010000 { - compatible = "xlnx,xps-uartlite-1.00.a"; - reg = <0x0 0x60010000 0x1000>; + axi_intc: axi_intc@61200000 { + compatible = "xlnx,xps-intc-1.00.a"; + reg = <0x61200000 0x1000>; interrupt-parent = <&L10>; - interrupts = <2>; + interrupts = <1>; }; }; L9: rom@10000 { diff --git a/kernel/src/arch/riscv32/board/rocket_chip/mod.rs b/kernel/src/arch/riscv32/board/rocket_chip/mod.rs index 0e2ac03..7e996b6 100644 --- a/kernel/src/arch/riscv32/board/rocket_chip/mod.rs +++ b/kernel/src/arch/riscv32/board/rocket_chip/mod.rs @@ -4,15 +4,43 @@ use super::consts::KERNEL_OFFSET; pub unsafe fn init_external_interrupt() { const HART0_S_MODE_INTERRUPT_ENABLES: *mut u64 = (KERNEL_OFFSET + 0x0C00_2080) as *mut u64; HART0_S_MODE_INTERRUPT_ENABLES.write_volatile(0xf); + + // mask interrupts first + const AXI_INTC_IER: *mut u32 = (KERNEL_OFFSET + 0x1900_0008) as *mut u32; + AXI_INTC_IER.write_volatile(0x0); + + // acknowledge all interrupts + const AXI_INTC_IAR: *mut u32 = (KERNEL_OFFSET + 0x1900_000C) as *mut u32; + AXI_INTC_IAR.write_volatile(0xffffffff); + + const AXI_INTC_MER: *mut u32 = (KERNEL_OFFSET + 0x1900_001C) as *mut u32; + // Hardware Interrupt enable | Enable irq output + AXI_INTC_MER.write_volatile(0b11); + + // enable all interrupts + AXI_INTC_IER.write_volatile(0xffffffff); + } /// Claim and complete external interrupt by reading and writing to /// PLIC Interrupt Claim/Complete Register. pub unsafe fn handle_external_interrupt() { const HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 = - (KERNEL_OFFSET + 0x0C20_2000) as *mut u32; + (KERNEL_OFFSET + 0x0C20_1004) as *mut u32; // claim let source = HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE.read_volatile(); // complete HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE.write_volatile(source); + + // acknowledge all interrupts + const AXI_INTC_IAR: *mut u32 = (KERNEL_OFFSET + 0x1900_000C) as *mut u32; + AXI_INTC_IAR.write_volatile(0xffffffff); +} + +pub unsafe fn enable_serial_interrupt() { + const SERIAL_BASE: *mut u32 = (KERNEL_OFFSET + 0x18000000) as *mut u32; + const UART_CTRL_REG: usize = 3; + // Intr enable | rx reset | tx reset + const UART_IE: u32 = 0x13; + SERIAL_BASE.add(UART_CTRL_REG).write_volatile(UART_IE); } \ No newline at end of file diff --git a/kernel/src/arch/riscv32/interrupt.rs b/kernel/src/arch/riscv32/interrupt.rs index b498e65..12735f6 100644 --- a/kernel/src/arch/riscv32/interrupt.rs +++ b/kernel/src/arch/riscv32/interrupt.rs @@ -74,7 +74,7 @@ pub extern "C" fn rust_trap(tf: &mut TrapFrame) { } fn external() { - #[cfg(feature = "board_u540")] + #[cfg(any(feature = "board_u540", feature = "board_rocket_chip"))] unsafe { super::board::handle_external_interrupt(); } diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index 04a3388..304e9f6 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -133,6 +133,33 @@ fn remap_the_kernel(dtb: usize) { Linear::new(offset), "uart16550", ); + // map PLIC for Rocket Chip + #[cfg(feature = "board_rocket_chip")] + ms.push( + KERNEL_OFFSET + 0x0C20_1000, + KERNEL_OFFSET + 0x0C20_1000 + PAGE_SIZE, + MemoryAttr::default(), + Linear::new(offset), + "plic2", + ); + // map UART for Rocket Chip + #[cfg(feature = "board_rocket_chip")] + ms.push( + KERNEL_OFFSET + 0x18000000, + KERNEL_OFFSET + 0x18000000 + PAGE_SIZE, + MemoryAttr::default(), + Linear::new(-(KERNEL_OFFSET as isize + 0x18000000 - 0x60000000)), + "uartlite", + ); + // map AXI INTC for Rocket Chip + #[cfg(feature = "board_rocket_chip")] + ms.push( + KERNEL_OFFSET + 0x19000000, + KERNEL_OFFSET + 0x19000000 + PAGE_SIZE, + MemoryAttr::default(), + Linear::new(-(KERNEL_OFFSET as isize + 0x19000000 - 0x61200000)), + "axi_intc", + ); unsafe { ms.activate(); } diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index e34c2ea..028d666 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -70,7 +70,6 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! { crate::drivers::init(device_tree_vaddr); #[cfg(not(feature = "board_k210"))] unsafe { - #[cfg(not(feature = "board_rocket_chip"))] board::enable_serial_interrupt(); board::init_external_interrupt(); } diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index d13520a..57e242c 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -29,14 +29,7 @@ impl Stdin { return c; } } - #[cfg(feature = "board_rocket_chip")] - loop { - let c = crate::arch::io::getchar(); - if c != '\0' && c as u8 != 254 { - return c; - } - } - #[cfg(not(any(feature = "board_k210", feature = "board_rocket_chip")))] + #[cfg(not(feature = "board_k210"))] loop { let mut buf_lock = self.buf.lock(); match buf_lock.pop_front() { @@ -48,11 +41,6 @@ impl Stdin { } } pub fn can_read(&self) -> bool { - // Currently, rocket-chip implementation rely on htif interface, the serial interrupt DO - // NOT work, so return true always - #[cfg(feature = "board_rocket_chip")] - return true; - #[cfg(not(feature = "board_rocket_chip"))] return self.buf.lock().len() > 0; } } From 537eecaf5ebaa1bf0b175831544e6b1a395d5a4b Mon Sep 17 00:00:00 2001 From: chyyuu Date: Wed, 8 May 2019 13:16:00 +0800 Subject: [PATCH 06/10] fix bug: the values of CloneFlags --- kernel/src/syscall/proc.rs | 46 ++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index fbdbc2d..e5269db 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -350,27 +350,29 @@ impl Syscall<'_> { bitflags! { pub struct CloneFlags: usize { - const CSIGNAL = 0x000000ff; - const VM = 0x0000100; - const FS = 0x0000200; - const FILES = 0x0000400; - const SIGHAND = 0x0000800; - const PTRACE = 0x0002000; - const VFORK = 0x0004000; - const PARENT = 0x0008000; - const SYSVSEM = 0x0008000; - const SETTLS = 0x0008000; - const PARENT_SETTID = 0x0010000; - const CHILD_CLEARTID = 0x0020000; - const DETACHED = 0x0040000; - const UNTRACED = 0x0080000; - const CHILD_SETTID = 0x0100000; - const NEWCGROUP = 0x0200000; - const NEWUTS = 0x0400000; - const NEWIPC = 0x0800000; - const NEWUSER = 0x1000000; - const NEWPID = 0x2000000; - const NEWNET = 0x4000000; - const IO = 0x8000000; + const CSIGNAL = 0x000000ff; + const VM = 0x00000100; + const FS = 0x00000200; + const FILES = 0x00000400; + const SIGHAND = 0x00000800; + const PTRACE = 0x00002000; + const VFORK = 0x00004000; + const PARENT = 0x00008000; + const THREAD = 0x00010000; + const NEWNS = 0x00020000; + const SYSVSEM = 0x00040000; + const SETTLS = 0x00080000; + const PARENT_SETTID = 0x00100000; + const CHILD_CLEARTID = 0x00200000; + const DETACHED = 0x00400000; + const UNTRACED = 0x00800000; + const CHILD_SETTID = 0x01000000; + const NEWCGROUP = 0x02000000; + const NEWUTS = 0x04000000; + const NEWIPC = 0x08000000; + const NEWUSER = 0x10000000; + const NEWPID = 0x20000000; + const NEWNET = 0x40000000; + const IO = 0x80000000; } } From 2fa3338b4fbb1baad161249b824d6a44bee0f48c Mon Sep 17 00:00:00 2001 From: chyyuu Date: Wed, 8 May 2019 13:18:04 +0800 Subject: [PATCH 07/10] add unimplemented syscall SYS_MEMNARRIER from musl-1.1.22 with pthread OPs --- kernel/src/syscall/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index c05e7ee..ef2c892 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -263,6 +263,7 @@ impl Syscall<'_> { SYS_SETGROUPS => self.unimplemented("setgroups", Ok(0)), SYS_SETPRIORITY => self.sys_set_priority(args[0]), SYS_PRCTL => self.unimplemented("prctl", Ok(0)), + SYS_MEMBARRIER => self.unimplemented("membarrier", Ok(0)), SYS_PRLIMIT64 => self.sys_prlimit64( args[0], args[1], From d9d21a3db1f68b60ba85ec4a586fb999422be070 Mon Sep 17 00:00:00 2001 From: chyyuu Date: Wed, 8 May 2019 16:39:34 +0800 Subject: [PATCH 08/10] fix bug: sys_futex should not check timeout parameter for musl libc 1.1.22 --- kernel/src/syscall/misc.rs | 21 ++++++++++++--------- kernel/src/syscall/mod.rs | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index e504aa8..f792ced 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -59,15 +59,16 @@ impl Syscall<'_> { uaddr: usize, op: u32, val: i32, - timeout: *const TimeSpec, +// timeout: *const TimeSpec, ) -> SysResult { info!( - "futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}", + //"futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}", + "futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}. timeout ALWAYS 0", thread::current().id(), uaddr, op, - val, - timeout + val +// timeout ); // if op & OP_PRIVATE == 0 { // unimplemented!("futex only support process-private"); @@ -77,11 +78,13 @@ impl Syscall<'_> { return Err(SysError::EINVAL); } let atomic = unsafe { self.vm().check_write_ptr(uaddr as *mut AtomicI32)? }; - let _timeout = if timeout.is_null() { - None - } else { - Some(unsafe { *self.vm().check_read_ptr(timeout)? }) - }; + // musl libc 1.1.22 _wake FUN didn't provide timeout, ___futexwait FUN set timeout=0 + // now rcore just ignored the timeout parameter. TODO +// let _timeout = if timeout.is_null() { +// None +// } else { +// Some(unsafe { *self.vm().check_read_ptr(timeout)? }) +// }; const OP_WAIT: u32 = 0; const OP_WAKE: u32 = 1; diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index ef2c892..9af2b88 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -229,7 +229,7 @@ impl Syscall<'_> { args[0], args[1] as u32, args[2] as i32, - args[3] as *const TimeSpec, + // args[3] as *const TimeSpec, ), // time From ccc7eea11417297bbabb40e27e743cf05c2b8180 Mon Sep 17 00:00:00 2001 From: chyyuu Date: Wed, 8 May 2019 19:08:04 +0800 Subject: [PATCH 09/10] add ioctl request id: FIONBIO (no real action, just return Ok(0)). p.s. for rustc --- kernel/src/fs/file_like.rs | 1 + kernel/src/fs/ioctl.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index ae5ae6b..5e847f1 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -34,6 +34,7 @@ impl FileLike { match request { // TODO: place flags & path in FileLike in stead of FileHandle/Socket FIOCLEX => Ok(0), + FIONBIO => Ok(0), _ => { match self { FileLike::File(file) => file.io_control(request as u32, arg1)?, diff --git a/kernel/src/fs/ioctl.rs b/kernel/src/fs/ioctl.rs index 3eb3509..45bdebd 100644 --- a/kernel/src/fs/ioctl.rs +++ b/kernel/src/fs/ioctl.rs @@ -34,3 +34,7 @@ pub const FIONCLEX: usize = 0x6602; pub const FIOCLEX: usize = 0x5451; #[cfg(target_arch = "mips")] pub const FIOCLEX: usize = 0x6601; + +// rustc using pipe and ioctl pipe file with this request id +// for non-blocking/blocking IO control setting +pub const FIONBIO: usize = 0x5421; \ No newline at end of file From e3595dd0f55fed2184858235e21541bec6579390 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 8 May 2019 19:23:07 +0800 Subject: [PATCH 10/10] Implement sys_copy_file_range and use it for sendfile --- kernel/src/syscall/fs.rs | 52 ++++++++++++++++++++++++++++++-------- kernel/src/syscall/misc.rs | 30 ++++++++++++---------- kernel/src/syscall/mod.rs | 10 +++++++- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 0031baa..401a950 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -736,10 +736,22 @@ impl Syscall<'_> { in_fd: usize, offset_ptr: *mut usize, count: usize, + ) -> SysResult { + self.sys_copy_file_range(in_fd, offset_ptr, out_fd, 0 as *mut usize, count, 0) + } + + pub fn sys_copy_file_range( + &mut self, + in_fd: usize, + in_offset: *mut usize, + out_fd: usize, + out_offset: *mut usize, + count: usize, + flags: usize, ) -> SysResult { info!( - "sendfile:BEG out: {}, in: {}, offset_ptr: {:?}, count: {}", - out_fd, in_fd, offset_ptr, count + "copy_file_range:BEG in: {}, out: {}, in_offset: {:?}, out_offset: {:?}, count: {} flags {}", + in_fd, out_fd, in_offset, out_offset, count, flags ); let proc = self.process(); // We know it's save, pacify the borrow checker @@ -748,12 +760,25 @@ impl Syscall<'_> { let out_file = unsafe { (*proc_cell.get()).get_file(out_fd)? }; let mut buffer = [0u8; 1024]; - let mut read_offset = if !offset_ptr.is_null() { - unsafe { *self.vm().check_read_ptr(offset_ptr)? } + // for in_offset and out_offset + // null means update file offset + // non-null means update {in,out}_offset instead + + let mut read_offset = if !in_offset.is_null() { + unsafe { *self.vm().check_read_ptr(in_offset)? } } else { in_file.seek(SeekFrom::Current(0))? as usize }; + let orig_out_file_offset = out_file.seek(SeekFrom::Current(0))?; + let write_offset = if !out_offset.is_null() { + out_file.seek(SeekFrom::Start( + unsafe { *self.vm().check_read_ptr(out_offset)? } as u64, + ))? as usize + } else { + 0 + }; + // read from specified offset and write new offset back let mut bytes_read = 0; let mut total_written = 0; @@ -772,8 +797,8 @@ impl Syscall<'_> { let write_len = out_file.write(&buffer[bytes_written..(bytes_written + rlen)])?; if write_len == 0 { info!( - "sendfile:END_ERR out: {}, in: {}, offset_ptr: {:?}, count: {} = bytes_read {}, bytes_written {}, write_len {}", - out_fd, in_fd, offset_ptr, count, bytes_read, bytes_written, write_len + "copy_file_range:END_ERR in: {}, out: {}, in_offset: {:?}, out_offset: {:?}, count: {} = bytes_read {}, bytes_written {}, write_len {}", + in_fd, out_fd, in_offset, out_offset, count, bytes_read, bytes_written, write_len ); return Err(SysError::EBADF); } @@ -783,16 +808,23 @@ impl Syscall<'_> { total_written += bytes_written; } - if !offset_ptr.is_null() { + if !in_offset.is_null() { unsafe { - offset_ptr.write(read_offset); + in_offset.write(read_offset); } } else { in_file.seek(SeekFrom::Current(bytes_read as i64))?; } + + if !out_offset.is_null() { + unsafe { + out_offset.write(write_offset + total_written); + } + out_file.seek(SeekFrom::Start(orig_out_file_offset))?; + } info!( - "sendfile:END out: {}, in: {}, offset_ptr: {:?}, count: {} = bytes_read {}, total_written {}", - out_fd, in_fd, offset_ptr, count, bytes_read, total_written + "copy_file_range:END in: {}, out: {}, in_offset: {:?}, out_offset: {:?}, count: {} flags {}", + in_fd, out_fd, in_offset, out_offset, count, flags ); return Ok(total_written); } diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index f792ced..119cf8b 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -59,16 +59,15 @@ impl Syscall<'_> { uaddr: usize, op: u32, val: i32, -// timeout: *const TimeSpec, + timeout: *const TimeSpec, ) -> SysResult { info!( - //"futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}", - "futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}. timeout ALWAYS 0", + "futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}", thread::current().id(), uaddr, op, - val -// timeout + val, + timeout ); // if op & OP_PRIVATE == 0 { // unimplemented!("futex only support process-private"); @@ -78,13 +77,6 @@ impl Syscall<'_> { return Err(SysError::EINVAL); } let atomic = unsafe { self.vm().check_write_ptr(uaddr as *mut AtomicI32)? }; - // musl libc 1.1.22 _wake FUN didn't provide timeout, ___futexwait FUN set timeout=0 - // now rcore just ignored the timeout parameter. TODO -// let _timeout = if timeout.is_null() { -// None -// } else { -// Some(unsafe { *self.vm().check_read_ptr(timeout)? }) -// }; const OP_WAIT: u32 = 0; const OP_WAKE: u32 = 1; @@ -95,6 +87,12 @@ impl Syscall<'_> { match op & 0xf { OP_WAIT => { + let _timeout = if timeout.is_null() { + None + } else { + Some(unsafe { *self.vm().check_read_ptr(timeout)? }) + }; + if atomic.load(Ordering::Acquire) != val { return Err(SysError::EAGAIN); } @@ -113,7 +111,13 @@ impl Syscall<'_> { } } - pub fn sys_reboot(&mut self, _magic: u32, _magic2: u32, cmd: u32, _arg: *const u8) -> SysResult { + pub fn sys_reboot( + &mut self, + _magic: u32, + _magic2: u32, + cmd: u32, + _arg: *const u8, + ) -> SysResult { // we will skip verifying magic if cmd == LINUX_REBOOT_CMD_HALT { unsafe { diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 9af2b88..101dfc4 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -229,7 +229,7 @@ impl Syscall<'_> { args[0], args[1] as u32, args[2] as i32, - // args[3] as *const TimeSpec, + args[3] as *const TimeSpec, ), // time @@ -276,6 +276,14 @@ impl Syscall<'_> { args[2] as u32, args[3] as *const u8, ), + SYS_COPY_FILE_RANGE => self.sys_copy_file_range( + args[0], + args[1] as *mut usize, + args[2], + args[3] as *mut usize, + args[4], + args[5], + ), // custom SYS_MAP_PCI_DEVICE => self.sys_map_pci_device(args[0], args[1]),