mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16: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)
|
![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
|
## Building
|
||||||
|
|
||||||
### Environment
|
### Environment
|
||||||
|
@ -77,7 +77,7 @@ qemu_net_opts :=
|
|||||||
|
|
||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
qemu_opts += \
|
qemu_opts += \
|
||||||
-bios $(OVMF) \
|
-drive if=pflash,format=raw,readonly,file=$(OVMF) \
|
||||||
-drive format=raw,file=fat:rw:$(ESP) \
|
-drive format=raw,file=fat:rw:$(ESP) \
|
||||||
-serial mon:stdio \
|
-serial mon:stdio \
|
||||||
-m 4G \
|
-m 4G \
|
||||||
@ -93,13 +93,15 @@ qemu_net_opts += \
|
|||||||
-netdev type=tap,id=net0,script=no,downscript=no \
|
-netdev type=tap,id=net0,script=no,downscript=no \
|
||||||
-device e1000e,netdev=net0
|
-device e1000e,netdev=net0
|
||||||
else
|
else
|
||||||
qemu_opts += \
|
|
||||||
-machine accel=kvm
|
|
||||||
qemu_net_opts += \
|
qemu_net_opts += \
|
||||||
-device vfio-pci,host=$(PCI_PASSTHRU)
|
-device vfio-pci,host=$(PCI_PASSTHRU)
|
||||||
qemu_ui_opts += \
|
qemu_ui_opts += \
|
||||||
-vga std
|
-vga std
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(shell uname), Darwin)
|
||||||
|
qemu_opts += \
|
||||||
|
-machine accel=hvf
|
||||||
|
endif
|
||||||
ifeq ($(EXTRA_NIC), on)
|
ifeq ($(EXTRA_NIC), on)
|
||||||
qemu_net_opts += \
|
qemu_net_opts += \
|
||||||
-netdev type=tap,id=net1,script=no,downscript=no \
|
-netdev type=tap,id=net1,script=no,downscript=no \
|
||||||
|
@ -59,3 +59,7 @@
|
|||||||
|
|
||||||
- fn main_start():第一个核的启动
|
- fn main_start():第一个核的启动
|
||||||
- fn others_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 board;
|
||||||
pub mod consts;
|
pub mod consts;
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
|
pub mod fp;
|
||||||
pub mod gdt;
|
pub mod gdt;
|
||||||
pub mod interrupt;
|
pub mod interrupt;
|
||||||
pub mod io;
|
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::interrupt::get_trap_num;
|
||||||
use crate::arch::{
|
use crate::arch::{
|
||||||
cpu,
|
cpu,
|
||||||
|
fp::FpState,
|
||||||
memory::{get_page_fault_addr, set_page_table},
|
memory::{get_page_fault_addr, set_page_table},
|
||||||
paging::*,
|
paging::*,
|
||||||
};
|
};
|
||||||
@ -51,12 +52,18 @@ use xmas_elf::{
|
|||||||
/// Tid type
|
/// Tid type
|
||||||
pub type Tid = usize;
|
pub type Tid = usize;
|
||||||
|
|
||||||
|
pub struct ThreadContext {
|
||||||
|
user: Box<UserContext>,
|
||||||
|
/// TODO: lazy fp
|
||||||
|
fp: Box<FpState>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Mutable part of a thread struct
|
/// Mutable part of a thread struct
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ThreadInner {
|
pub struct ThreadInner {
|
||||||
/// user context
|
/// user context
|
||||||
/// None when thread is running in user
|
/// None when thread is running in user
|
||||||
context: Option<Box<UserContext>>,
|
context: Option<ThreadContext>,
|
||||||
/// Kernel performs futex wake when thread exits.
|
/// Kernel performs futex wake when thread exits.
|
||||||
/// Ref: [http://man7.org/linux/man-pages/man2/set_tid_address.2.html]
|
/// Ref: [http://man7.org/linux/man-pages/man2/set_tid_address.2.html]
|
||||||
pub clear_child_tid: usize,
|
pub clear_child_tid: usize,
|
||||||
@ -304,7 +311,10 @@ impl Thread {
|
|||||||
let thread = Thread {
|
let thread = Thread {
|
||||||
tid: 0, // allocated below
|
tid: 0, // allocated below
|
||||||
inner: Mutex::new(ThreadInner {
|
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,
|
clear_child_tid: 0,
|
||||||
sig_mask: Sigset::default(),
|
sig_mask: Sigset::default(),
|
||||||
signal_alternate_stack: SignalStack::default(),
|
signal_alternate_stack: SignalStack::default(),
|
||||||
@ -381,7 +391,10 @@ impl Thread {
|
|||||||
let new_thread = Thread {
|
let new_thread = Thread {
|
||||||
tid: 0, // allocated below
|
tid: 0, // allocated below
|
||||||
inner: Mutex::new(ThreadInner {
|
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,
|
clear_child_tid: 0,
|
||||||
sig_mask,
|
sig_mask,
|
||||||
signal_alternate_stack: sigaltstack,
|
signal_alternate_stack: sigaltstack,
|
||||||
@ -416,6 +429,10 @@ impl Thread {
|
|||||||
new_context.set_syscall_ret(0);
|
new_context.set_syscall_ret(0);
|
||||||
new_context.set_sp(stack_top);
|
new_context.set_sp(stack_top);
|
||||||
new_context.set_tls(tls);
|
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 sig_mask = self.inner.lock().sig_mask;
|
||||||
let sigaltstack = self.inner.lock().signal_alternate_stack;
|
let sigaltstack = self.inner.lock().signal_alternate_stack;
|
||||||
@ -423,7 +440,7 @@ impl Thread {
|
|||||||
tid: 0,
|
tid: 0,
|
||||||
inner: Mutex::new(ThreadInner {
|
inner: Mutex::new(ThreadInner {
|
||||||
clear_child_tid,
|
clear_child_tid,
|
||||||
context: Some(Box::new(new_context)),
|
context: Some(thread_context),
|
||||||
sig_mask,
|
sig_mask,
|
||||||
signal_alternate_stack: sigaltstack,
|
signal_alternate_stack: sigaltstack,
|
||||||
}),
|
}),
|
||||||
@ -435,11 +452,11 @@ impl Thread {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn begin_running(&self) -> Box<UserContext> {
|
pub fn begin_running(&self) -> ThreadContext {
|
||||||
self.inner.lock().context.take().unwrap()
|
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);
|
self.inner.lock().context = Some(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,9 +485,14 @@ pub fn spawn(thread: Arc<Thread>) {
|
|||||||
let temp = thread.clone();
|
let temp = thread.clone();
|
||||||
let future = async move {
|
let future = async move {
|
||||||
loop {
|
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);
|
trace!("go to user: {:#x?}", cx);
|
||||||
|
thread_context.fp.restore();
|
||||||
cx.run();
|
cx.run();
|
||||||
|
thread_context.fp.save();
|
||||||
|
|
||||||
let trap_num = get_trap_num(&cx);
|
let trap_num = get_trap_num(&cx);
|
||||||
trace!("back from user: {:#x?} trap_num {:#x}", cx, trap_num);
|
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");
|
panic!("page fault handle failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Syscall => exit = handle_syscall(&thread, &mut cx).await,
|
Syscall => exit = handle_syscall(&thread, cx).await,
|
||||||
IrqMin..=IrqMax => {
|
IrqMin..=IrqMax => {
|
||||||
crate::arch::interrupt::ack(trap_num);
|
crate::arch::interrupt::ack(trap_num);
|
||||||
trace!("handle irq {:#x}", trap_num);
|
trace!("handle irq {:#x}", trap_num);
|
||||||
@ -506,10 +528,10 @@ pub fn spawn(thread: Arc<Thread>) {
|
|||||||
|
|
||||||
// check signals
|
// check signals
|
||||||
if !exit {
|
if !exit {
|
||||||
exit = handle_signal(&thread, &mut cx);
|
exit = handle_signal(&thread, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
thread.end_running(cx);
|
thread.end_running(thread_context);
|
||||||
if exit {
|
if exit {
|
||||||
info!("thread {} stopped", thread.tid);
|
info!("thread {} stopped", thread.tid);
|
||||||
break;
|
break;
|
||||||
|
@ -191,7 +191,7 @@ pub fn handle_signal(thread: &Arc<Thread>, tf: &mut UserContext) -> bool {
|
|||||||
let mut inner = thread.inner.lock();
|
let mut inner = thread.inner.lock();
|
||||||
let sig_mask = inner.sig_mask;
|
let sig_mask = inner.sig_mask;
|
||||||
|
|
||||||
// update sig mask
|
// update sig mask (see man sigaction(2))
|
||||||
// 1. block current
|
// 1. block current
|
||||||
// 2. block mask in disposition
|
// 2. block mask in disposition
|
||||||
inner.sig_mask.add(signal);
|
inner.sig_mask.add(signal);
|
||||||
|
Loading…
Reference in New Issue
Block a user