mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-26 01:43:29 +04:00
Merge branch 'master' of github.com:rcore-os/rCore
This commit is contained in:
commit
ff54128273
@ -33,6 +33,7 @@ impl Clone for Box<dyn MemoryHandler> {
|
|||||||
|
|
||||||
pub trait FrameAllocator: Debug + Clone + Send + Sync + 'static {
|
pub trait FrameAllocator: Debug + Clone + Send + Sync + 'static {
|
||||||
fn alloc(&self) -> Option<PhysAddr>;
|
fn alloc(&self) -> Option<PhysAddr>;
|
||||||
|
fn alloc_contiguous(&self, size: usize, align_log2: usize) -> Option<PhysAddr>;
|
||||||
fn dealloc(&self, target: PhysAddr);
|
fn dealloc(&self, target: PhysAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
kernel/Cargo.lock
generated
2
kernel/Cargo.lock
generated
@ -91,7 +91,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "bitmap-allocator"
|
name = "bitmap-allocator"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/rcore-os/bitmap-allocator#ede748530a026f89b15f1b162abb78be44deec44"
|
source = "git+https://github.com/rcore-os/bitmap-allocator#03bd9909d0dc85e99f5559b97a163ab81073df83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -9,6 +9,12 @@ pub unsafe fn init_external_interrupt() {
|
|||||||
const HART0_S_MODE_INTERRUPT_ENABLES: *mut u32 = phys_to_virt(0x0C00_2080) as *mut u32;
|
const HART0_S_MODE_INTERRUPT_ENABLES: *mut u32 = phys_to_virt(0x0C00_2080) as *mut u32;
|
||||||
const SERIAL: u32 = 0xa;
|
const SERIAL: u32 = 0xa;
|
||||||
HART0_S_MODE_INTERRUPT_ENABLES.write_volatile(1 << SERIAL);
|
HART0_S_MODE_INTERRUPT_ENABLES.write_volatile(1 << SERIAL);
|
||||||
|
|
||||||
|
const SERIAL_PRIO: *mut u32 = phys_to_virt(0x0C000000 + (SERIAL as usize) * 4) as *mut u32;
|
||||||
|
SERIAL_PRIO.write_volatile(7); // QEMU: priority[irq] <- value & 0x7, hence the 7 here.
|
||||||
|
|
||||||
|
const HART0_S_MODE_PRIO_THRESH: *mut u32 = phys_to_virt(0x0C00_0000 + 0x20_1000) as *mut u32;
|
||||||
|
HART0_S_MODE_PRIO_THRESH.write_volatile(0); // Permits everything
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn enable_serial_interrupt() {
|
pub unsafe fn enable_serial_interrupt() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub use crate::arch::paging::PageTableImpl;
|
pub use crate::arch::paging::PageTableImpl;
|
||||||
use crate::memory::{alloc_frame, dealloc_frame, phys_to_virt, virt_to_phys};
|
use crate::memory::{alloc_frame_contiguous, dealloc_frame, phys_to_virt, virt_to_phys};
|
||||||
use isomorphic_drivers::provider;
|
use isomorphic_drivers::provider;
|
||||||
use rcore_memory::PAGE_SIZE;
|
use rcore_memory::PAGE_SIZE;
|
||||||
|
|
||||||
@ -24,13 +24,7 @@ impl provider::Provider for Provider {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr {
|
extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr {
|
||||||
// TODO: allocate continuous pages
|
let paddr = alloc_frame_contiguous(pages, 0).unwrap();
|
||||||
let mut paddr = alloc_frame().unwrap();
|
|
||||||
for _ in 1..pages {
|
|
||||||
let paddr_new = alloc_frame().unwrap();
|
|
||||||
assert_eq!(paddr - PAGE_SIZE, paddr_new);
|
|
||||||
paddr = paddr_new;
|
|
||||||
}
|
|
||||||
trace!("alloc DMA: paddr={:#x}, pages={}", paddr, pages);
|
trace!("alloc DMA: paddr={:#x}, pages={}", paddr, pages);
|
||||||
paddr
|
paddr
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
#![feature(optin_builtin_traits)]
|
#![feature(optin_builtin_traits)]
|
||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
#![feature(global_asm)]
|
#![feature(global_asm)]
|
||||||
|
#![feature(negative_impls)]
|
||||||
#![feature(alloc_prelude)]
|
#![feature(alloc_prelude)]
|
||||||
|
#![feature(const_fn)]
|
||||||
#![deny(unused_must_use)]
|
#![deny(unused_must_use)]
|
||||||
#![deny(stable_features)]
|
#![deny(stable_features)]
|
||||||
#![deny(unused_unsafe)]
|
#![deny(unused_unsafe)]
|
||||||
|
@ -48,10 +48,7 @@ pub type FrameAlloc = bitmap_allocator::BitAlloc1M;
|
|||||||
#[cfg(feature = "board_k210")]
|
#[cfg(feature = "board_k210")]
|
||||||
pub type FrameAlloc = bitmap_allocator::BitAlloc4K;
|
pub type FrameAlloc = bitmap_allocator::BitAlloc4K;
|
||||||
|
|
||||||
lazy_static! {
|
pub static FRAME_ALLOCATOR: SpinNoIrqLock<FrameAlloc> = SpinNoIrqLock::new(FrameAlloc::DEFAULT);
|
||||||
pub static ref FRAME_ALLOCATOR: SpinNoIrqLock<FrameAlloc> =
|
|
||||||
SpinNoIrqLock::new(FrameAlloc::default());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert physical address to virtual address
|
/// Convert physical address to virtual address
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -85,6 +82,16 @@ impl FrameAllocator for GlobalFrameAlloc {
|
|||||||
ret
|
ret
|
||||||
// TODO: try to swap out when alloc failed
|
// TODO: try to swap out when alloc failed
|
||||||
}
|
}
|
||||||
|
fn alloc_contiguous(&self, size: usize, align_log2: usize) -> Option<PhysAddr> {
|
||||||
|
// get the real address of the alloc frame
|
||||||
|
let ret = FRAME_ALLOCATOR
|
||||||
|
.lock()
|
||||||
|
.alloc_contiguous(size, align_log2)
|
||||||
|
.map(|id| id * PAGE_SIZE + MEMORY_OFFSET);
|
||||||
|
trace!("Allocate frame: {:x?}", ret);
|
||||||
|
ret
|
||||||
|
// TODO: try to swap out when alloc failed
|
||||||
|
}
|
||||||
fn dealloc(&self, target: usize) {
|
fn dealloc(&self, target: usize) {
|
||||||
trace!("Deallocate frame: {:x}", target);
|
trace!("Deallocate frame: {:x}", target);
|
||||||
FRAME_ALLOCATOR
|
FRAME_ALLOCATOR
|
||||||
@ -99,6 +106,9 @@ pub fn alloc_frame() -> Option<usize> {
|
|||||||
pub fn dealloc_frame(target: usize) {
|
pub fn dealloc_frame(target: usize) {
|
||||||
GlobalFrameAlloc.dealloc(target);
|
GlobalFrameAlloc.dealloc(target);
|
||||||
}
|
}
|
||||||
|
pub fn alloc_frame_contiguous(size: usize, align_log2: usize) -> Option<usize> {
|
||||||
|
GlobalFrameAlloc.alloc_contiguous(size, align_log2)
|
||||||
|
}
|
||||||
|
|
||||||
pub struct KernelStack(usize);
|
pub struct KernelStack(usize);
|
||||||
const KSTACK_SIZE: usize = 0x4000; //16KB
|
const KSTACK_SIZE: usize = 0x4000; //16KB
|
||||||
|
@ -31,8 +31,9 @@ use crate::arch::interrupt;
|
|||||||
use crate::processor;
|
use crate::processor;
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
|
||||||
use rcore_thread::std_thread::yield_now;
|
use rcore_thread::std_thread::yield_now;
|
||||||
|
|
||||||
pub type SpinLock<T> = Mutex<T, Spin>;
|
pub type SpinLock<T> = Mutex<T, Spin>;
|
||||||
@ -41,7 +42,8 @@ pub type SleepLock<T> = Mutex<T, Condvar>;
|
|||||||
|
|
||||||
pub struct Mutex<T: ?Sized, S: MutexSupport> {
|
pub struct Mutex<T: ?Sized, S: MutexSupport> {
|
||||||
lock: AtomicBool,
|
lock: AtomicBool,
|
||||||
support: S,
|
support: MaybeUninit<S>,
|
||||||
|
support_initialization: AtomicU8, // 0 = uninitialized, 1 = initializing, 2 = initialized
|
||||||
user: UnsafeCell<(usize, usize)>, // (cid, tid)
|
user: UnsafeCell<(usize, usize)>, // (cid, tid)
|
||||||
data: UnsafeCell<T>,
|
data: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
@ -76,11 +78,12 @@ impl<T, S: MutexSupport> Mutex<T, S> {
|
|||||||
/// drop(lock);
|
/// drop(lock);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new(user_data: T) -> Mutex<T, S> {
|
pub const fn new(user_data: T) -> Mutex<T, S> {
|
||||||
Mutex {
|
Mutex {
|
||||||
lock: AtomicBool::new(false),
|
lock: AtomicBool::new(false),
|
||||||
data: UnsafeCell::new(user_data),
|
data: UnsafeCell::new(user_data),
|
||||||
support: S::new(),
|
support: MaybeUninit::uninit(),
|
||||||
|
support_initialization: AtomicU8::new(0),
|
||||||
user: UnsafeCell::new((0, 0)),
|
user: UnsafeCell::new((0, 0)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,7 +103,7 @@ impl<T: ?Sized, S: MutexSupport> Mutex<T, S> {
|
|||||||
let mut try_count = 0;
|
let mut try_count = 0;
|
||||||
// Wait until the lock looks unlocked before retrying
|
// Wait until the lock looks unlocked before retrying
|
||||||
while self.lock.load(Ordering::Relaxed) {
|
while self.lock.load(Ordering::Relaxed) {
|
||||||
self.support.cpu_relax();
|
unsafe { &*self.support.as_ptr() }.cpu_relax();
|
||||||
try_count += 1;
|
try_count += 1;
|
||||||
if try_count == 0x100000 {
|
if try_count == 0x100000 {
|
||||||
let (cid, tid) = unsafe { *self.user.get() };
|
let (cid, tid) = unsafe { *self.user.get() };
|
||||||
@ -133,6 +136,9 @@ impl<T: ?Sized, S: MutexSupport> Mutex<T, S> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn lock(&self) -> MutexGuard<T, S> {
|
pub fn lock(&self) -> MutexGuard<T, S> {
|
||||||
let support_guard = S::before_lock();
|
let support_guard = S::before_lock();
|
||||||
|
|
||||||
|
self.ensure_support();
|
||||||
|
|
||||||
self.obtain_lock();
|
self.obtain_lock();
|
||||||
MutexGuard {
|
MutexGuard {
|
||||||
mutex: self,
|
mutex: self,
|
||||||
@ -150,6 +156,28 @@ impl<T: ?Sized, S: MutexSupport> Mutex<T, S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ensure_support(&self) {
|
||||||
|
let initialization = self.support_initialization.load(Ordering::Relaxed);
|
||||||
|
if (initialization == 2) {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (initialization == 1
|
||||||
|
|| self
|
||||||
|
.support_initialization
|
||||||
|
.compare_and_swap(0, 1, Ordering::Acquire)
|
||||||
|
!= 0)
|
||||||
|
{
|
||||||
|
// Wait for another thread to initialize
|
||||||
|
while self.support_initialization.load(Ordering::Acquire) == 1 {
|
||||||
|
core::sync::atomic::spin_loop_hint();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// My turn to initialize
|
||||||
|
(unsafe { core::ptr::write(self.support.as_ptr() as *mut _, S::new()) });
|
||||||
|
self.support_initialization.store(2, Ordering::Release);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Force unlock the spinlock.
|
/// Force unlock the spinlock.
|
||||||
///
|
///
|
||||||
/// This is *extremely* unsafe if the lock is not held by the current
|
/// This is *extremely* unsafe if the lock is not held by the current
|
||||||
@ -212,7 +240,7 @@ impl<'a, T: ?Sized, S: MutexSupport> Drop for MutexGuard<'a, T, S> {
|
|||||||
/// The dropping of the MutexGuard will release the lock it was created from.
|
/// The dropping of the MutexGuard will release the lock it was created from.
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.mutex.lock.store(false, Ordering::Release);
|
self.mutex.lock.store(false, Ordering::Release);
|
||||||
self.mutex.support.after_unlock();
|
unsafe { &*self.mutex.support.as_ptr() }.after_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +47,9 @@ impl Syscall<'_> {
|
|||||||
let slice = unsafe { self.vm().check_read_array(base, len)? };
|
let slice = unsafe { self.vm().check_read_array(base, len)? };
|
||||||
let file_like = proc.get_file_like(fd)?;
|
let file_like = proc.get_file_like(fd)?;
|
||||||
let len = file_like.write(slice)?;
|
let len = file_like.write(slice)?;
|
||||||
// if len == 1 && !proc.pid.is_init() {
|
if len == 1 && !proc.pid.is_init() {
|
||||||
// println!("write content: {}", slice[0] as char);
|
println!("write content: {}", slice[0] as char);
|
||||||
// }
|
}
|
||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1825,6 +1825,8 @@ impl IoVecs {
|
|||||||
if readv {
|
if readv {
|
||||||
vm.check_write_array(iov.base, iov.len)?;
|
vm.check_write_array(iov.base, iov.len)?;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
vm.check_read_array(iov.base, iov.len)?;
|
vm.check_read_array(iov.base, iov.len)?;
|
||||||
}
|
}
|
||||||
slices.push(slice::from_raw_parts_mut(iov.base, iov.len));
|
slices.push(slice::from_raw_parts_mut(iov.base, iov.len));
|
||||||
|
Loading…
Reference in New Issue
Block a user