mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 08:06:17 +04:00
Add fp save and restore and use accel=hvf in macOS
This commit is contained in:
parent
34ca9963cb
commit
e32597ac82
11
README.md
11
README.md
@ -15,6 +15,17 @@ Supported architectures and boards:
|
||||
|
||||
![demo](./docs/2_OSLab/os2atc/demo.png)
|
||||
|
||||
## What's included
|
||||
|
||||
rCore has the following features:
|
||||
|
||||
* Linux compatible syscall interface: run Linux userspace programs
|
||||
* Network stack
|
||||
* Simple file system
|
||||
* Signal system
|
||||
* Async IO
|
||||
* Kernel module
|
||||
|
||||
## Building
|
||||
|
||||
### Environment
|
||||
|
@ -77,7 +77,7 @@ qemu_net_opts :=
|
||||
|
||||
ifeq ($(ARCH), x86_64)
|
||||
qemu_opts += \
|
||||
-bios $(OVMF) \
|
||||
-drive if=pflash,format=raw,readonly,file=$(OVMF) \
|
||||
-drive format=raw,file=fat:rw:$(ESP) \
|
||||
-serial mon:stdio \
|
||||
-m 4G \
|
||||
@ -93,13 +93,15 @@ qemu_net_opts += \
|
||||
-netdev type=tap,id=net0,script=no,downscript=no \
|
||||
-device e1000e,netdev=net0
|
||||
else
|
||||
qemu_opts += \
|
||||
-machine accel=kvm
|
||||
qemu_net_opts += \
|
||||
-device vfio-pci,host=$(PCI_PASSTHRU)
|
||||
qemu_ui_opts += \
|
||||
-vga std
|
||||
endif
|
||||
ifeq ($(shell uname), Darwin)
|
||||
qemu_opts += \
|
||||
-machine accel=hvf
|
||||
endif
|
||||
ifeq ($(EXTRA_NIC), on)
|
||||
qemu_net_opts += \
|
||||
-netdev type=tap,id=net1,script=no,downscript=no \
|
||||
|
@ -59,3 +59,7 @@
|
||||
|
||||
- fn main_start():第一个核的启动
|
||||
- fn others_start():其他核的启动
|
||||
|
||||
### fp
|
||||
|
||||
- struct FpState:浮点的状态
|
43
kernel/src/arch/x86_64/fp.rs
Normal file
43
kernel/src/arch/x86_64/fp.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// state saved by fxsave64
|
||||
// 512 bytes
|
||||
// https://www.felixcloutier.com/x86/fxsave#tbl-3-47
|
||||
#[repr(C, align(16))]
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub struct FpState {
|
||||
// 0
|
||||
word1: u64,
|
||||
word2: u64,
|
||||
// 16
|
||||
word3: u64,
|
||||
mxcsr: u32,
|
||||
mxcsr_mask: u32,
|
||||
// 32
|
||||
mm: [u64; 16],
|
||||
// 160
|
||||
xmm: [u64; 32],
|
||||
// 416
|
||||
rest: [u64; 12],
|
||||
}
|
||||
|
||||
impl FpState {
|
||||
pub fn new() -> Self {
|
||||
assert!(core::mem::size_of::<Self>() == 512);
|
||||
Self {
|
||||
// default value
|
||||
mxcsr: 0x1f80,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(&mut self) {
|
||||
unsafe {
|
||||
core::arch::x86_64::_fxsave64(self as *mut FpState as *mut u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restore(&self) {
|
||||
unsafe {
|
||||
core::arch::x86_64::_fxrstor64(self as *const FpState as *const u8);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ pub mod acpi;
|
||||
pub mod board;
|
||||
pub mod consts;
|
||||
pub mod cpu;
|
||||
pub mod fp;
|
||||
pub mod gdt;
|
||||
pub mod interrupt;
|
||||
pub mod io;
|
||||
|
@ -6,6 +6,7 @@ use crate::arch::interrupt::consts::{is_page_fault, IrqMax, IrqMin, Syscall, Tim
|
||||
use crate::arch::interrupt::get_trap_num;
|
||||
use crate::arch::{
|
||||
cpu,
|
||||
fp::FpState,
|
||||
memory::{get_page_fault_addr, set_page_table},
|
||||
paging::*,
|
||||
};
|
||||
@ -51,12 +52,18 @@ use xmas_elf::{
|
||||
/// Tid type
|
||||
pub type Tid = usize;
|
||||
|
||||
pub struct ThreadContext {
|
||||
user: Box<UserContext>,
|
||||
/// TODO: lazy fp
|
||||
fp: Box<FpState>,
|
||||
}
|
||||
|
||||
/// Mutable part of a thread struct
|
||||
#[derive(Default)]
|
||||
pub struct ThreadInner {
|
||||
/// user context
|
||||
/// None when thread is running in user
|
||||
context: Option<Box<UserContext>>,
|
||||
context: Option<ThreadContext>,
|
||||
/// Kernel performs futex wake when thread exits.
|
||||
/// Ref: [http://man7.org/linux/man-pages/man2/set_tid_address.2.html]
|
||||
pub clear_child_tid: usize,
|
||||
@ -304,7 +311,10 @@ impl Thread {
|
||||
let thread = Thread {
|
||||
tid: 0, // allocated below
|
||||
inner: Mutex::new(ThreadInner {
|
||||
context: Some(Box::from(context)),
|
||||
context: Some(ThreadContext {
|
||||
user: Box::from(context),
|
||||
fp: Box::new(FpState::new()),
|
||||
}),
|
||||
clear_child_tid: 0,
|
||||
sig_mask: Sigset::default(),
|
||||
signal_alternate_stack: SignalStack::default(),
|
||||
@ -381,7 +391,10 @@ impl Thread {
|
||||
let new_thread = Thread {
|
||||
tid: 0, // allocated below
|
||||
inner: Mutex::new(ThreadInner {
|
||||
context: Some(Box::new(context)),
|
||||
context: Some(ThreadContext {
|
||||
user: Box::new(context),
|
||||
fp: Box::new(FpState::new()),
|
||||
}),
|
||||
clear_child_tid: 0,
|
||||
sig_mask,
|
||||
signal_alternate_stack: sigaltstack,
|
||||
@ -416,6 +429,10 @@ impl Thread {
|
||||
new_context.set_syscall_ret(0);
|
||||
new_context.set_sp(stack_top);
|
||||
new_context.set_tls(tls);
|
||||
let thread_context = ThreadContext {
|
||||
user: Box::new(new_context),
|
||||
fp: Box::new(FpState::new()),
|
||||
};
|
||||
|
||||
let sig_mask = self.inner.lock().sig_mask;
|
||||
let sigaltstack = self.inner.lock().signal_alternate_stack;
|
||||
@ -423,7 +440,7 @@ impl Thread {
|
||||
tid: 0,
|
||||
inner: Mutex::new(ThreadInner {
|
||||
clear_child_tid,
|
||||
context: Some(Box::new(new_context)),
|
||||
context: Some(thread_context),
|
||||
sig_mask,
|
||||
signal_alternate_stack: sigaltstack,
|
||||
}),
|
||||
@ -435,11 +452,11 @@ impl Thread {
|
||||
res
|
||||
}
|
||||
|
||||
pub fn begin_running(&self) -> Box<UserContext> {
|
||||
pub fn begin_running(&self) -> ThreadContext {
|
||||
self.inner.lock().context.take().unwrap()
|
||||
}
|
||||
|
||||
pub fn end_running(&self, cx: Box<UserContext>) {
|
||||
pub fn end_running(&self, cx: ThreadContext) {
|
||||
self.inner.lock().context = Some(cx);
|
||||
}
|
||||
|
||||
@ -468,9 +485,14 @@ pub fn spawn(thread: Arc<Thread>) {
|
||||
let temp = thread.clone();
|
||||
let future = async move {
|
||||
loop {
|
||||
let mut cx = thread.begin_running();
|
||||
let mut thread_context = thread.begin_running();
|
||||
let cx = &mut thread_context.user;
|
||||
|
||||
trace!("go to user: {:#x?}", cx);
|
||||
thread_context.fp.restore();
|
||||
cx.run();
|
||||
thread_context.fp.save();
|
||||
|
||||
let trap_num = get_trap_num(&cx);
|
||||
trace!("back from user: {:#x?} trap_num {:#x}", cx, trap_num);
|
||||
|
||||
@ -487,7 +509,7 @@ pub fn spawn(thread: Arc<Thread>) {
|
||||
panic!("page fault handle failed");
|
||||
}
|
||||
}
|
||||
Syscall => exit = handle_syscall(&thread, &mut cx).await,
|
||||
Syscall => exit = handle_syscall(&thread, cx).await,
|
||||
IrqMin..=IrqMax => {
|
||||
crate::arch::interrupt::ack(trap_num);
|
||||
trace!("handle irq {:#x}", trap_num);
|
||||
@ -506,10 +528,10 @@ pub fn spawn(thread: Arc<Thread>) {
|
||||
|
||||
// check signals
|
||||
if !exit {
|
||||
exit = handle_signal(&thread, &mut cx);
|
||||
exit = handle_signal(&thread, cx);
|
||||
}
|
||||
|
||||
thread.end_running(cx);
|
||||
thread.end_running(thread_context);
|
||||
if exit {
|
||||
info!("thread {} stopped", thread.tid);
|
||||
break;
|
||||
|
@ -191,7 +191,7 @@ pub fn handle_signal(thread: &Arc<Thread>, tf: &mut UserContext) -> bool {
|
||||
let mut inner = thread.inner.lock();
|
||||
let sig_mask = inner.sig_mask;
|
||||
|
||||
// update sig mask
|
||||
// update sig mask (see man sigaction(2))
|
||||
// 1. block current
|
||||
// 2. block mask in disposition
|
||||
inner.sig_mask.add(signal);
|
||||
|
Loading…
Reference in New Issue
Block a user