mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
aarch64: context switch is runnable!
This commit is contained in:
parent
67b920cc16
commit
5610d0bdb0
@ -5,8 +5,7 @@ use super::bcm2837::interrupt::{Controller, Interrupt};
|
||||
pub fn handle_irq(tf: &mut TrapFrame) {
|
||||
let controller = Timer::new();
|
||||
if controller.is_pending() {
|
||||
println!("Timer tick {}...", super::timer::get_cycle());
|
||||
super::timer::set_next();
|
||||
// ::trap::timer();
|
||||
::trap::timer();
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ pub fn get_cycle() -> u64 {
|
||||
}
|
||||
|
||||
pub fn set_next() {
|
||||
// 1000 ms
|
||||
timer::tick_in(1000 * 1000);
|
||||
// 10 ms
|
||||
timer::tick_in(10 * 1000);
|
||||
}
|
||||
|
@ -18,6 +18,9 @@ setup:
|
||||
# store the desired EL1 stack pointer in x1
|
||||
adr x1, _start
|
||||
|
||||
# use SP_ELx for Exception level ELx
|
||||
msr SPsel, #1
|
||||
|
||||
# read the current exception level into x0 (ref: C5.2.1)
|
||||
mrs x0, CurrentEL
|
||||
and x0, x0, #0b1100
|
||||
|
@ -116,6 +116,8 @@ impl Context {
|
||||
tlbi vmalle1is // invalidate the TLB entry for the entry that changes
|
||||
dsb ish // ensure TLB invalidation is complete
|
||||
isb // synchronize context on this processor
|
||||
|
||||
str xzr, [x1]
|
||||
ret"
|
||||
: : : : "volatile" );
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ mod handler;
|
||||
mod context;
|
||||
mod syndrome;
|
||||
|
||||
use super::cortex_a::regs::*;
|
||||
pub use self::context::*;
|
||||
pub use self::handler::*;
|
||||
|
||||
@ -34,8 +35,9 @@ pub unsafe fn disable() {
|
||||
/// return: status(usize)
|
||||
#[inline(always)]
|
||||
pub unsafe fn disable_and_store() -> usize {
|
||||
// TODO
|
||||
0
|
||||
let daif = DAIF.get() as usize;
|
||||
disable();
|
||||
daif
|
||||
}
|
||||
|
||||
/// Use the original status to restore the process
|
||||
@ -44,5 +46,5 @@ pub unsafe fn disable_and_store() -> usize {
|
||||
/// * flags: original status(usize)
|
||||
#[inline(always)]
|
||||
pub unsafe fn restore(flags: usize) {
|
||||
// TODO
|
||||
DAIF.set(flags as u32);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Entrance and initialization for aarch64.
|
||||
|
||||
extern crate atags;
|
||||
extern crate cortex_a;
|
||||
|
||||
pub mod io;
|
||||
pub mod paging;
|
||||
@ -13,72 +14,16 @@ pub mod board;
|
||||
|
||||
pub use self::board::timer;
|
||||
|
||||
/// TODO
|
||||
/// The entry point of kernel
|
||||
#[no_mangle] // don't mangle the name of this function
|
||||
pub extern "C" fn rust_main() -> ! {
|
||||
// Init board to enable serial port.
|
||||
board::init();
|
||||
|
||||
// First init log mod, so that we can print log info.
|
||||
// FIXME
|
||||
::logging::init();
|
||||
|
||||
let (start, end) = memory::memory_map().expect("failed to find memory map");
|
||||
println!("The value of start is: {:#x?}, end is {:#x?}", start, end);
|
||||
|
||||
::logging::init(); // FIXME
|
||||
interrupt::init();
|
||||
memory::init();
|
||||
timer::init();
|
||||
|
||||
//let mut v = vec![];
|
||||
//for i in 0..1000 {
|
||||
// v.push(i);
|
||||
// println!("{:?}", v);
|
||||
//}
|
||||
|
||||
::process::init();
|
||||
|
||||
unsafe { interrupt::enable(); }
|
||||
|
||||
super::fs::show_logo();
|
||||
|
||||
loop {
|
||||
print!(">> ");
|
||||
loop {
|
||||
let c = io::getchar();
|
||||
match c {
|
||||
'\u{7f}' => {
|
||||
print!("\u{7f}");
|
||||
}
|
||||
'b' => unsafe {
|
||||
println!("brk 233");
|
||||
asm!("brk 233");
|
||||
},
|
||||
'c' => unsafe {
|
||||
println!("sys_putc");
|
||||
asm!(
|
||||
"mov x8, #30
|
||||
mov x0, #65
|
||||
svc 0"
|
||||
);
|
||||
},
|
||||
't' => unsafe {
|
||||
println!("{}", timer::get_cycle());
|
||||
},
|
||||
' '...'\u{7e}' => {
|
||||
print!("{}", c);
|
||||
}
|
||||
'\n' | '\r' => {
|
||||
print!("\n");
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ::kmain();
|
||||
::kmain();
|
||||
}
|
||||
|
||||
global_asm!(include_str!("boot/boot.S"));
|
||||
|
@ -26,6 +26,62 @@ pub fn show_logo() {
|
||||
println!("{}", LOGO);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sys_call(id: usize, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> i32 {
|
||||
let ret: i32;
|
||||
unsafe {
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
asm!("ecall"
|
||||
: "={x10}" (ret)
|
||||
: "{x10}" (id), "{x11}" (arg0), "{x12}" (arg1), "{x13}" (arg2), "{x14}" (arg3), "{x15}" (arg4), "{x16}" (arg5)
|
||||
: "memory"
|
||||
: "volatile");
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
asm!("int 0x40"
|
||||
: "={rax}" (ret)
|
||||
: "{rax}" (id), "{rdi}" (arg0), "{rsi}" (arg1), "{rdx}" (arg2), "{rcx}" (arg3), "{r8}" (arg4), "{r9}" (arg5)
|
||||
: "memory"
|
||||
: "intel" "volatile");
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
asm!("svc 0"
|
||||
: "={x0}" (ret)
|
||||
: "{x8}" (id), "{x0}" (arg0), "{x1}" (arg1), "{x2}" (arg2), "{x3}" (arg3), "{x4}" (arg4), "{x5}" (arg5)
|
||||
: "memory"
|
||||
: "volatile");
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn test_shell(prefix: &str) -> ! {
|
||||
show_logo();
|
||||
loop {
|
||||
print!("{}", prefix);
|
||||
loop {
|
||||
let c = super::arch::io::getchar();
|
||||
match c {
|
||||
'\u{7f}' => {
|
||||
print!("\u{7f}");
|
||||
}
|
||||
'c' => unsafe {
|
||||
print!("sys_putc: ");
|
||||
sys_call(30, 'A' as usize, 0, 0, 0, 0, 0);
|
||||
},
|
||||
't' => unsafe {
|
||||
println!("sys_get_time: {}", sys_call(17, 0, 0, 0, 0, 0, 0));
|
||||
},
|
||||
' '...'\u{7e}' => {
|
||||
print!("{}", c);
|
||||
}
|
||||
'\n' | '\r' => {
|
||||
print!("\n");
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shell() {
|
||||
show_logo();
|
||||
|
||||
|
@ -66,9 +66,14 @@ pub mod arch;
|
||||
|
||||
pub fn kmain() -> ! {
|
||||
process::init();
|
||||
|
||||
use process::*;
|
||||
processor().add(Context::new_kernel(kernel_proc2, 2333));
|
||||
processor().add(Context::new_user_test(kernel_proc3));
|
||||
|
||||
unsafe { arch::interrupt::enable(); }
|
||||
|
||||
fs::shell();
|
||||
// fs::shell();
|
||||
|
||||
// thread::test::local_key();
|
||||
// thread::test::unpack();
|
||||
@ -86,3 +91,12 @@ pub fn kmain() -> ! {
|
||||
/// It should be defined in memory mod, but in Rust `global_allocator` must be in root mod.
|
||||
#[global_allocator]
|
||||
static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();
|
||||
|
||||
|
||||
pub extern "C" fn kernel_proc2(arg: usize) -> ! {
|
||||
fs::test_shell(&format!("proc2-{}>> ", arg));
|
||||
}
|
||||
|
||||
pub extern "C" fn kernel_proc3(arg: usize) -> ! {
|
||||
fs::test_shell(&format!("proc3-{}$ ", arg));
|
||||
}
|
||||
|
@ -33,6 +33,15 @@ impl Context {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_user_test(entry: extern fn(usize) -> !) -> Self {
|
||||
let ms = MemorySet::new();
|
||||
let user_stack = ::memory::alloc_stack();
|
||||
Context {
|
||||
arch: unsafe { ArchContext::new_user_thread(entry as usize, user_stack.top - 8, ms.kstack_top(), false, ms.token()) },
|
||||
memory_set: ms,
|
||||
}
|
||||
}
|
||||
|
||||
/// Make a new user thread from ELF data
|
||||
pub fn new_user(data: &[u8]) -> Self {
|
||||
// Parse elf
|
||||
@ -143,4 +152,4 @@ fn memory_attr_from(elf_flags: Flags) -> MemoryAttr {
|
||||
// TODO: handle readonly
|
||||
if elf_flags.is_execute() { flags = flags.execute(); }
|
||||
flags
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,32 @@
|
||||
use spin::Once;
|
||||
use sync::{SpinNoIrqLock, Mutex, MutexGuard, SpinNoIrq};
|
||||
use sync::{Mutex, MutexGuard, SpinNoIrq, SpinNoIrqLock};
|
||||
pub use self::context::Context;
|
||||
pub use ucore_process::processor::{*, Context as _whatever};
|
||||
pub use ucore_process::scheduler::*;
|
||||
pub use ucore_process::thread::*;
|
||||
|
||||
use arch::timer;
|
||||
|
||||
mod context;
|
||||
|
||||
type Processor = Processor_<Context, StrideScheduler>;
|
||||
|
||||
pub fn init() {
|
||||
PROCESSOR.call_once(||
|
||||
PROCESSOR.call_once(|| {
|
||||
SpinNoIrqLock::new({
|
||||
let mut processor = Processor::new(
|
||||
unsafe { Context::new_init() },
|
||||
// NOTE: max_time_slice <= 5 to ensure 'priority' test pass
|
||||
StrideScheduler::new(5),
|
||||
);
|
||||
extern fn idle1(arg: usize) -> ! {
|
||||
extern "C" fn idle(arg: usize) -> ! {
|
||||
loop {
|
||||
println!("idle 1 {}", timer::get_cycle());
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
unsafe { asm!("wfi" :::: "volatile") }
|
||||
}
|
||||
}
|
||||
extern fn idle2(arg: usize) -> ! {
|
||||
loop {
|
||||
println!("idle 2 {}", timer::get_cycle());
|
||||
}
|
||||
}
|
||||
processor.add(Context::new_kernel(idle1, 0));
|
||||
processor.add(Context::new_kernel(idle2, 0));
|
||||
processor.add(Context::new_kernel(idle, 0));
|
||||
processor
|
||||
})
|
||||
);
|
||||
});
|
||||
info!("process init end");
|
||||
}
|
||||
|
||||
|
@ -217,6 +217,8 @@ impl MutexSupport for Spin {
|
||||
asm!("pause" :::: "volatile");
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
asm!("nop" :::: "volatile");
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
asm!("yield" :::: "volatile");
|
||||
}
|
||||
}
|
||||
fn before_lock() -> Self::GuardData {}
|
||||
@ -247,6 +249,8 @@ impl MutexSupport for SpinNoIrq {
|
||||
asm!("pause" :::: "volatile");
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
asm!("nop" :::: "volatile");
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
asm!("yield" :::: "volatile");
|
||||
}
|
||||
}
|
||||
fn before_lock() -> Self::GuardData {
|
||||
@ -267,4 +271,4 @@ impl MutexSupport for Condvar {
|
||||
fn after_unlock(&self) {
|
||||
self.notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user