forked from rcore-os/zCore
Merge remote-tracking branch 'rcore-os/master' into vmo
This commit is contained in:
commit
851faba694
|
@ -55,12 +55,28 @@ jobs:
|
|||
with:
|
||||
command: doc
|
||||
|
||||
build-aarch64:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: nightly-2020-06-04
|
||||
override: true
|
||||
target: aarch64-unknown-linux-gnu
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
use-cross: true
|
||||
args: -p zircon-loader --all-features --target aarch64-unknown-linux-gnu
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Pull prebuilt images
|
||||
run: git lfs pull -X prebuilt/zircon/bringup.zbi prebuilt/zircon/core-tests.zbi
|
||||
run: git lfs pull -X prebuilt/zircon/x64/bringup.zbi prebuilt/zircon/x64/core-tests.zbi prebuilt/zircon/arm64
|
||||
- name: Prepare rootfs
|
||||
run: make rootfs
|
||||
- name: Test
|
||||
|
@ -99,7 +115,7 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Pull prebuilt images
|
||||
run: git lfs pull -X prebuilt/zircon/bringup.zbi
|
||||
run: git lfs pull -X prebuilt/zircon/x64/bringup.zbi prebuilt/zircon/arm64
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
|
|
|
@ -7,7 +7,6 @@ members = [
|
|||
"linux-syscall",
|
||||
"linux-loader",
|
||||
"kernel-hal-unix",
|
||||
"kernel-hal-bare",
|
||||
"kernel-hal",
|
||||
]
|
||||
|
||||
|
|
4
Makefile
4
Makefile
|
@ -1,5 +1,5 @@
|
|||
ROOTFS_TAR := alpine-minirootfs-3.11.3-x86_64.tar.gz
|
||||
ROOTFS_URL := http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/x86_64/$(ROOTFS_TAR)
|
||||
ROOTFS_TAR := alpine-minirootfs-3.12.0-x86_64.tar.gz
|
||||
ROOTFS_URL := http://dl-cdn.alpinelinux.org/alpine/v3.12/releases/x86_64/$(ROOTFS_TAR)
|
||||
|
||||
.PHONY: rootfs
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ cargo run --release -p linux-loader /bin/busybox [args]
|
|||
Run native Zircon program (shell):
|
||||
|
||||
```sh
|
||||
cargo run --release -p zircon-loader prebuilt/zircon
|
||||
cargo run --release -p zircon-loader prebuilt/zircon/x64
|
||||
```
|
||||
|
||||
Run Zircon on bare-metal (zCore):
|
||||
|
|
|
@ -11,10 +11,10 @@ description = "Kernel HAL implementation for bare metal environment."
|
|||
log = "0.4"
|
||||
spin = "0.5"
|
||||
git-version = "0.3"
|
||||
executor = { git = "https://github.com/rcore-os/executor.git", rev = "e8ffcfb" }
|
||||
trapframe = "0.3.0"
|
||||
executor = { git = "https://github.com/rcore-os/executor.git", rev = "a2d02ee9" }
|
||||
trapframe = "0.4.1"
|
||||
kernel-hal = { path = "../kernel-hal" }
|
||||
naive-timer = { git = "https://github.com/rcore-os/naive-timer.git", rev="d0cfe04" }
|
||||
naive-timer = "0.1.0"
|
||||
lazy_static = { version = "1.4", features = ["spin_no_std" ] }
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
|
|
|
@ -3,6 +3,7 @@ use {
|
|||
acpi::{parse_rsdp, Acpi, AcpiHandler, PhysicalMapping},
|
||||
alloc::{collections::VecDeque, vec::Vec},
|
||||
apic::{LocalApic, XApic},
|
||||
core::arch::x86_64::{__cpuid, _mm_clflush, _mm_mfence},
|
||||
core::convert::TryFrom,
|
||||
core::fmt::{Arguments, Write},
|
||||
core::ptr::NonNull,
|
||||
|
@ -444,3 +445,20 @@ pub fn outpd(port: u16, value: u32) {
|
|||
pub fn inpd(port: u16) -> u32 {
|
||||
unsafe { Port::new(port).read() }
|
||||
}
|
||||
|
||||
/// Flush the physical frame.
|
||||
#[export_name = "hal_frame_flush"]
|
||||
pub fn frame_flush(target: PhysAddr) {
|
||||
unsafe {
|
||||
for paddr in (target..target + PAGE_SIZE).step_by(cacheline_size()) {
|
||||
_mm_clflush(phys_to_virt(paddr) as *const u8);
|
||||
}
|
||||
_mm_mfence();
|
||||
}
|
||||
}
|
||||
|
||||
/// Get cache line size in bytes.
|
||||
fn cacheline_size() -> usize {
|
||||
let leaf = unsafe { __cpuid(1).ebx };
|
||||
(((leaf >> 8) & 0xff) << 3) as usize
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ extern crate lazy_static;
|
|||
use alloc::boxed::Box;
|
||||
use core::time::Duration;
|
||||
use core::{
|
||||
arch::x86_64::{__cpuid, _mm_clflush, _mm_mfence},
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
|
@ -177,23 +176,6 @@ pub fn frame_zero_in_range(target: PhysAddr, start: usize, end: usize) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Flush the physical frame.
|
||||
#[export_name = "hal_frame_flush"]
|
||||
pub fn frame_flush(target: PhysAddr) {
|
||||
unsafe {
|
||||
for paddr in (target..target + PAGE_SIZE).step_by(cacheline_size()) {
|
||||
_mm_clflush(phys_to_virt(paddr) as *const u8);
|
||||
}
|
||||
_mm_mfence();
|
||||
}
|
||||
}
|
||||
|
||||
/// Get cache line size in bytes.
|
||||
fn cacheline_size() -> usize {
|
||||
let leaf = unsafe { __cpuid(1).ebx };
|
||||
(((leaf >> 8) & 0xff) << 3) as usize
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref NAIVE_TIMER: Mutex<Timer> = Mutex::new(Timer::default());
|
||||
}
|
||||
|
|
|
@ -16,3 +16,4 @@ lazy_static = "1.4"
|
|||
kernel-hal = { path = "../kernel-hal" }
|
||||
async-std = "1.5"
|
||||
git-version = "0.3"
|
||||
trapframe = "0.4.1"
|
||||
|
|
|
@ -22,17 +22,15 @@ use {
|
|||
tempfile::tempdir,
|
||||
};
|
||||
|
||||
pub use self::trap::syscall_entry;
|
||||
pub use kernel_hal::defs::*;
|
||||
use kernel_hal::vdso::*;
|
||||
pub use kernel_hal::*;
|
||||
use std::io::Read;
|
||||
pub use trapframe::syscall_fn_entry as syscall_entry;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
include!("macos.rs");
|
||||
|
||||
mod trap;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Thread {
|
||||
thread: usize,
|
||||
|
@ -67,9 +65,7 @@ task_local! {
|
|||
|
||||
#[export_name = "hal_context_run"]
|
||||
unsafe fn context_run(context: &mut UserContext) {
|
||||
trap::run_user(&mut context.general);
|
||||
// cause: syscall
|
||||
context.trap_num = 0x100;
|
||||
context.run_fncall();
|
||||
}
|
||||
|
||||
/// Page Table
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
use super::GeneralRegs;
|
||||
|
||||
// User: (musl)
|
||||
// - fs:0 (pthread.self) = user fsbase
|
||||
// - fs:48 (pthread.canary2) = kernel fsbase
|
||||
//
|
||||
// Kernel: (glibc)
|
||||
// - fs:0 (pthread.self) = kernel fsbase
|
||||
// - fs:64 (pthread.???) = kernel stack
|
||||
// - fs:72 (pthread.???) = init user fsbase
|
||||
//
|
||||
#[cfg(target_os = "linux")]
|
||||
global_asm!(
|
||||
r#"
|
||||
.macro SWITCH_TO_KERNEL_STACK
|
||||
mov rsp, fs:48 # rsp = kernel fsbase
|
||||
mov rsp, [rsp + 64] # rsp = kernel stack
|
||||
.endm
|
||||
.macro SAVE_KERNEL_STACK
|
||||
mov fs:64, rsp
|
||||
.endm
|
||||
.macro PUSH_USER_FSBASE
|
||||
push fs:0
|
||||
.endm
|
||||
.macro SWITCH_TO_KERNEL_FSBASE
|
||||
mov eax, 158 # SYS_arch_prctl
|
||||
mov edi, 0x1002 # SET_FS
|
||||
mov rsi, fs:48 # rsi = kernel fsbase
|
||||
syscall
|
||||
.endm
|
||||
.macro POP_USER_FSBASE
|
||||
mov rsi, [rsp + 18 * 8] # rsi = user fsbase
|
||||
mov rdx, fs:0 # rdx = kernel fsbase
|
||||
test rsi, rsi
|
||||
jnz 1f # if not 0, goto set
|
||||
0: lea rsi, [rdx + 72] # rsi = init user fsbase
|
||||
mov [rsi], rsi # user_fs:0 = user fsbase
|
||||
1: mov eax, 158 # SYS_arch_prctl
|
||||
mov edi, 0x1002 # SET_FS
|
||||
syscall # set fsbase
|
||||
mov fs:48, rdx # user_fs:48 = kernel fsbase
|
||||
.endm
|
||||
|
||||
.global unix_syscall_entry
|
||||
.global run_user
|
||||
"#
|
||||
);
|
||||
|
||||
// User: (musl)
|
||||
// - gs:0 (pthread.self) = user gsbase
|
||||
// - gs:48 (pthread.canary2) = kernel gsbase
|
||||
//
|
||||
// Kernel: (darwin)
|
||||
// - gs:0 (pthread.tsd[self]) = kernel gsbase - 224
|
||||
// - gs:48 (pthread.tsd[6]) = kernel stack
|
||||
// - gs:240 (pthread.tsd[30]) = init user fsbase
|
||||
//
|
||||
// Ref:
|
||||
// - Set gsbase:
|
||||
// - https://gist.github.com/aras-p/5389747
|
||||
// - Get gsbase:
|
||||
// - https://github.com/DynamoRIO/dynamorio/issues/1568#issuecomment-239819506
|
||||
// - https://github.com/apple/darwin-libpthread/blob/03c4628c8940cca6fd6a82957f683af804f62e7f/src/internal.h#L241
|
||||
#[cfg(target_os = "macos")]
|
||||
global_asm!(
|
||||
r#"
|
||||
.macro SWITCH_TO_KERNEL_STACK
|
||||
mov rsp, gs:48 # rsp = kernel gsbase
|
||||
mov rsp, [rsp + 48] # rsp = kernel stack
|
||||
.endm
|
||||
.macro SAVE_KERNEL_STACK
|
||||
mov gs:48, rsp
|
||||
.endm
|
||||
.macro PUSH_USER_FSBASE
|
||||
push gs:0
|
||||
.endm
|
||||
.macro SWITCH_TO_KERNEL_FSBASE
|
||||
mov rdi, gs:48 # rdi = kernel gsbase
|
||||
mov eax, 0x3000003
|
||||
syscall # set gsbase
|
||||
.endm
|
||||
.macro POP_USER_FSBASE
|
||||
mov rdi, [rsp + 18 * 8] # rdi = user gsbase
|
||||
mov rsi, gs:0
|
||||
add rsi, 224 # rsi = kernel gsbase
|
||||
test rdi, rdi
|
||||
jnz 1f # if not 0, goto set
|
||||
0: lea rdi, [rsi + 30*8] # rdi = init user gsbase
|
||||
# = pthread.tsd[30] (kernel gsbase + 30 * 8)
|
||||
mov [rdi], rdi # user_gs:0 = user gsbase
|
||||
1: mov eax, 0x3000003
|
||||
syscall # set gsbase
|
||||
mov gs:48, rsi # user_gs:48 = kernel gsbase
|
||||
.endm
|
||||
|
||||
.global _unix_syscall_entry
|
||||
.global _run_user
|
||||
.set _unix_syscall_entry, unix_syscall_entry
|
||||
.set _run_user, run_user
|
||||
"#
|
||||
);
|
||||
|
||||
global_asm!(
|
||||
r#"
|
||||
.intel_syntax noprefix
|
||||
unix_syscall_entry:
|
||||
# save rsp
|
||||
lea r11, [rsp + 8] # save rsp to r11 (clobber)
|
||||
|
||||
SWITCH_TO_KERNEL_STACK
|
||||
pop rsp
|
||||
lea rsp, [rsp + 20*8] # rsp = top of trap frame
|
||||
|
||||
# push trap frame (struct GeneralRegs)
|
||||
push 0 # ignore gs_base
|
||||
PUSH_USER_FSBASE
|
||||
pushfq # push rflags
|
||||
push [r11 - 8] # push rip
|
||||
push r15
|
||||
push r14
|
||||
push r13
|
||||
push r12
|
||||
push r11
|
||||
push r10
|
||||
push r9
|
||||
push r8
|
||||
push r11 # push rsp
|
||||
push rbp
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
push rcx
|
||||
push rbx
|
||||
push rax
|
||||
|
||||
# restore callee-saved registers
|
||||
SWITCH_TO_KERNEL_STACK
|
||||
pop rbx
|
||||
pop rbx
|
||||
pop rbp
|
||||
pop r12
|
||||
pop r13
|
||||
pop r14
|
||||
pop r15
|
||||
|
||||
SWITCH_TO_KERNEL_FSBASE
|
||||
|
||||
# go back to Rust
|
||||
ret
|
||||
|
||||
# extern "C" fn run_user(&mut GeneralRegs)
|
||||
run_user:
|
||||
# save callee-saved registers
|
||||
push r15
|
||||
push r14
|
||||
push r13
|
||||
push r12
|
||||
push rbp
|
||||
push rbx
|
||||
|
||||
push rdi
|
||||
SAVE_KERNEL_STACK
|
||||
mov rsp, rdi
|
||||
|
||||
POP_USER_FSBASE
|
||||
|
||||
# pop trap frame (struct GeneralRegs)
|
||||
pop rax
|
||||
pop rbx
|
||||
pop rcx
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rbp
|
||||
pop r8 # skip rsp
|
||||
pop r8
|
||||
pop r9
|
||||
pop r10
|
||||
pop r11
|
||||
pop r12
|
||||
pop r13
|
||||
pop r14
|
||||
pop r15
|
||||
pop r11 # r11 = rip. FIXME: don't overwrite r11!
|
||||
popfq # pop rflags
|
||||
mov rsp, [rsp - 8*11] # restore rsp
|
||||
jmp r11 # restore rip
|
||||
"#
|
||||
);
|
||||
|
||||
extern "C" {
|
||||
#[link_name = "unix_syscall_entry"]
|
||||
pub fn syscall_entry();
|
||||
pub fn run_user(regs: &mut GeneralRegs);
|
||||
}
|
|
@ -9,6 +9,6 @@ description = "Kernel HAL interface definations."
|
|||
|
||||
[dependencies]
|
||||
bitflags = "1.2"
|
||||
trapframe = "0.3.0"
|
||||
trapframe = "0.4.1"
|
||||
numeric-enum-macro = "0.2"
|
||||
acpi = "1.0.0"
|
||||
|
|
|
@ -392,3 +392,21 @@ pub fn inpd(_port: u16) -> u32 {
|
|||
pub fn apic_local_id() -> u8 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Fill random bytes to the buffer
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn fill_random(buf: &mut [u8]) {
|
||||
// TODO: optimize
|
||||
for x in buf.iter_mut() {
|
||||
let mut r = 0;
|
||||
unsafe {
|
||||
core::arch::x86_64::_rdrand16_step(&mut r);
|
||||
}
|
||||
*x = r as _;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn fill_random(_buf: &mut [u8]) {
|
||||
// TODO
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -185,3 +185,29 @@ index 7baa69755e0..18cdb981f0c 100644
|
|||
+zcore_syscall_entry:
|
||||
+ .quad 0xdeadbeaf
|
||||
+.popsection
|
||||
diff --git a/zircon/system/ulib/zircon/zircon-syscall-arm64.S b/zircon/system/ulib/zircon/zircon-syscall-arm64.S
|
||||
index 50598676cb2..fc69f203ed0 100644
|
||||
--- a/zircon/system/ulib/zircon/zircon-syscall-arm64.S
|
||||
+++ b/zircon/system/ulib/zircon/zircon-syscall-arm64.S
|
||||
@@ -6,7 +6,11 @@
|
||||
|
||||
.macro zircon_syscall num, name, caller
|
||||
mov x16, #\num
|
||||
- svc #0x0
|
||||
+ push_regpair x29, x30
|
||||
+ adr x29, zcore_syscall_entry
|
||||
+ ldr x29, [x29]
|
||||
+ blr x29
|
||||
+ pop_regpair x29, x30
|
||||
// This symbol at the return address identifies this as an approved call site.
|
||||
.hidden CODE_SYSRET_\name\()_VIA_\caller
|
||||
CODE_SYSRET_\name\()_VIA_\caller\():
|
||||
@@ -46,3 +50,8 @@ CODE_SYSRET_\name\()_VIA_\caller\():
|
||||
.cfi_same_value \reg0
|
||||
.cfi_same_value \reg1
|
||||
.endm
|
||||
+
|
||||
+.pushsection .rodata
|
||||
+zcore_syscall_entry:
|
||||
+ .quad 0xdeadbeaf
|
||||
+.popsection
|
|
@ -23,8 +23,8 @@ rboot = { path = "../rboot", default-features = false }
|
|||
kernel-hal-bare = { path = "../kernel-hal-bare" }
|
||||
lazy_static = { version = "1.4", features = ["spin_no_std" ] }
|
||||
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "03bd9909" }
|
||||
trapframe = "0.3.0"
|
||||
executor = { git = "https://github.com/rcore-os/executor.git", rev = "e8ffcfb" }
|
||||
trapframe = "0.4.1"
|
||||
executor = { git = "https://github.com/rcore-os/executor.git", rev = "a2d02ee9" }
|
||||
zircon-object = { path = "../zircon-object" }
|
||||
zircon-loader = { path = "../zircon-loader", default-features = false, optional = true }
|
||||
linux-loader = { path = "../linux-loader", default-features = false, optional = true }
|
||||
|
|
|
@ -74,7 +74,7 @@ justrun: $(QEMU_DISK)
|
|||
$(qemu) $(qemu_opts)
|
||||
|
||||
build-test: build
|
||||
cp ../prebuilt/zircon/core-tests.zbi $(ESP)/EFI/zCore/fuchsia.zbi
|
||||
cp ../prebuilt/zircon/x64/core-tests.zbi $(ESP)/EFI/zCore/fuchsia.zbi
|
||||
echo 'cmdline=LOG=warn:userboot=test/core/standalone-test:userboot.shutdown:core-tests=$(test_filter)' >> $(ESP)/EFI/Boot/rboot.conf
|
||||
|
||||
build: $(kernel_img)
|
||||
|
@ -86,7 +86,7 @@ $(kernel_img): kernel bootloader
|
|||
ifeq ($(linux), 1)
|
||||
cp x86_64.img $(ESP)/EFI/zCore/fuchsia.zbi
|
||||
else
|
||||
cp ../prebuilt/zircon/$(zbi_file).zbi $(ESP)/EFI/zCore/fuchsia.zbi
|
||||
cp ../prebuilt/zircon/x64/$(zbi_file).zbi $(ESP)/EFI/zCore/fuchsia.zbi
|
||||
endif
|
||||
cp $(kernel) $(ESP)/EFI/zCore/zcore.elf
|
||||
|
||||
|
|
|
@ -47,12 +47,12 @@ pub extern "C" fn _start(boot_info: &BootInfo) -> ! {
|
|||
fn main(ramfs_data: &[u8], cmdline: &str) {
|
||||
use zircon_loader::{run_userboot, Images};
|
||||
let images = Images::<&[u8]> {
|
||||
userboot: include_bytes!("../../prebuilt/zircon/userboot.so"),
|
||||
vdso: include_bytes!("../../prebuilt/zircon/libzircon.so"),
|
||||
userboot: include_bytes!("../../prebuilt/zircon/x64/userboot.so"),
|
||||
vdso: include_bytes!("../../prebuilt/zircon/x64/libzircon.so"),
|
||||
zbi: ramfs_data,
|
||||
};
|
||||
let _proc = run_userboot(&images, cmdline);
|
||||
executor::run();
|
||||
run();
|
||||
}
|
||||
|
||||
#[cfg(feature = "linux")]
|
||||
|
@ -67,7 +67,15 @@ fn main(ramfs_data: &'static mut [u8], _cmdline: &str) {
|
|||
let device = Arc::new(MemBuf::new(ramfs_data));
|
||||
let rootfs = rcore_fs_sfs::SimpleFileSystem::open(device).unwrap();
|
||||
let _proc = linux_loader::run(args, envs, rootfs);
|
||||
executor::run();
|
||||
run();
|
||||
}
|
||||
|
||||
fn run() -> ! {
|
||||
loop {
|
||||
executor::run_until_idle();
|
||||
x86_64::instructions::interrupts::enable_interrupts_and_hlt();
|
||||
x86_64::instructions::interrupts::disable();
|
||||
}
|
||||
}
|
||||
|
||||
fn get_log_level(cmdline: &str) -> &str {
|
||||
|
|
|
@ -108,8 +108,11 @@ pub fn run_userboot(images: &Images<impl AsRef<[u8]>>, cmdline: &str) -> Arc<Pro
|
|||
let stack_bottom = vmar
|
||||
.map(None, stack_vmo.clone(), 0, stack_vmo.len(), flags)
|
||||
.unwrap();
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
// WARN: align stack to 16B, then emulate a 'call' (push rip)
|
||||
let sp = stack_bottom + stack_vmo.len() - 8;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
let sp = stack_bottom + stack_vmo.len();
|
||||
|
||||
// channel
|
||||
let (user_channel, kernel_channel) = Channel::create();
|
||||
|
@ -183,7 +186,16 @@ fn spawn(thread: Arc<Thread>) {
|
|||
thread.time_add(time);
|
||||
trace!("back from user: {:#x?}", cx);
|
||||
EXCEPTIONS_USER.add(1);
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
let exit;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
match cx.trap_num {
|
||||
0 => exit = handle_syscall(&thread, &mut cx.general).await,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let mut exit = false;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
match cx.trap_num {
|
||||
0x100 => exit = handle_syscall(&thread, &mut cx.general).await,
|
||||
0x20..=0x3f => {
|
||||
|
@ -195,11 +207,15 @@ fn spawn(thread: Arc<Thread>) {
|
|||
}
|
||||
0xe => {
|
||||
EXCEPTIONS_PGFAULT.add(1);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let flags = if cx.error_code & 0x2 == 0 {
|
||||
MMUFlags::READ
|
||||
} else {
|
||||
MMUFlags::WRITE
|
||||
};
|
||||
// FIXME:
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
let flags = MMUFlags::WRITE;
|
||||
error!(
|
||||
"page fualt from user mode {:#x} {:#x?}",
|
||||
kernel_hal::fetch_fault_vaddr(),
|
||||
|
@ -234,9 +250,13 @@ fn spawn(thread: Arc<Thread>) {
|
|||
}
|
||||
|
||||
async fn handle_syscall(thread: &Arc<Thread>, regs: &mut GeneralRegs) -> bool {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let num = regs.rax as u32;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
let num = regs.x16 as u32;
|
||||
// LibOS: Function call ABI
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let args = unsafe {
|
||||
let a6 = (regs.rsp as *const usize).read();
|
||||
let a7 = (regs.rsp as *const usize).add(1).read();
|
||||
|
@ -246,15 +266,29 @@ async fn handle_syscall(thread: &Arc<Thread>, regs: &mut GeneralRegs) -> bool {
|
|||
};
|
||||
// RealOS: Zircon syscall ABI
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let args = [
|
||||
regs.rdi, regs.rsi, regs.rdx, regs.r10, regs.r8, regs.r9, regs.r12, regs.r13,
|
||||
];
|
||||
// ARM64
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
let args = [
|
||||
regs.x0, regs.x1, regs.x2, regs.x3, regs.x4, regs.x5, regs.x6, regs.x7,
|
||||
];
|
||||
let mut syscall = Syscall {
|
||||
regs,
|
||||
thread: thread.clone(),
|
||||
spawn_fn: spawn,
|
||||
exit: false,
|
||||
};
|
||||
syscall.regs.rax = syscall.syscall(num, args).await as usize;
|
||||
let ret = syscall.syscall(num, args).await as usize;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
syscall.regs.rax = ret;
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
syscall.regs.x0 = ret;
|
||||
}
|
||||
syscall.exit
|
||||
}
|
||||
|
|
|
@ -70,7 +70,10 @@ mod tests {
|
|||
kernel_hal_unix::init();
|
||||
|
||||
let opt = Opt {
|
||||
prebuilt_path: PathBuf::from("../prebuilt/zircon"),
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
prebuilt_path: PathBuf::from("../prebuilt/zircon/x64"),
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
prebuilt_path: PathBuf::from("../prebuilt/zircon/arm64"),
|
||||
cmdline: String::from(""),
|
||||
};
|
||||
let images = open_images(&opt.prebuilt_path).expect("failed to read file");
|
||||
|
|
|
@ -22,7 +22,6 @@ futures = { version = "0.3", default-features = false, features = ["alloc", "asy
|
|||
xmas-elf = { version = "0.7", optional = true }
|
||||
region-alloc = { git = "https://github.com/rzswh/region-allocator", rev = "122c7a71" }
|
||||
lazy_static = { version = "1.4", features = ["spin_no_std" ] }
|
||||
apic = { git = "https://github.com/rcore-os/apic-rs", rev = "fb86bd7" }
|
||||
acpi = "1.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -180,11 +180,21 @@ impl Thread {
|
|||
{
|
||||
let mut inner = self.inner.lock();
|
||||
let context = inner.context.as_mut().ok_or(ZxError::BAD_STATE)?;
|
||||
context.general.rip = entry;
|
||||
context.general.rsp = stack;
|
||||
context.general.rdi = arg1;
|
||||
context.general.rsi = arg2;
|
||||
context.general.rflags |= 0x3202;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
context.general.rip = entry;
|
||||
context.general.rsp = stack;
|
||||
context.general.rdi = arg1;
|
||||
context.general.rsi = arg2;
|
||||
context.general.rflags |= 0x3202;
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
context.elr = entry;
|
||||
context.sp = stack;
|
||||
context.general.x0 = arg1;
|
||||
context.general.x1 = arg2;
|
||||
}
|
||||
inner.state = ThreadState::Running;
|
||||
self.base.signal_set(Signal::THREAD_RUNNING);
|
||||
}
|
||||
|
@ -202,7 +212,10 @@ impl Thread {
|
|||
let mut inner = self.inner.lock();
|
||||
let context = inner.context.as_mut().ok_or(ZxError::BAD_STATE)?;
|
||||
context.general = regs;
|
||||
context.general.rflags |= 0x3202;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
context.general.rflags |= 0x3202;
|
||||
}
|
||||
inner.state = ThreadState::Running;
|
||||
self.base.signal_set(Signal::THREAD_RUNNING);
|
||||
}
|
||||
|
|
|
@ -11,9 +11,7 @@ numeric_enum! {
|
|||
Vector = 2,
|
||||
Debug = 4,
|
||||
SingleStep = 5,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
FS = 6,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
GS = 7,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
use {super::*, core::arch::x86_64::_rdrand32_step};
|
||||
use super::*;
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
impl Syscall<'_> {
|
||||
pub fn sys_cprng_draw_once(&self, buf: usize, len: usize) -> ZxResult {
|
||||
info!("cprng_draw_once: buf=({:#x}; {:?})", buf, len);
|
||||
if len % 4 == 0 {
|
||||
let size = len / 4;
|
||||
let mut res = vec![0u32; size];
|
||||
res.iter_mut().for_each(|value| unsafe {
|
||||
// TODO: move to HAL
|
||||
_rdrand32_step(value);
|
||||
});
|
||||
UserOutPtr::<u32>::from(buf).write_array(&res)?;
|
||||
Ok(())
|
||||
} else {
|
||||
unimplemented!()
|
||||
}
|
||||
pub fn sys_cprng_draw_once(&self, mut buf: UserOutPtr<u8>, len: usize) -> ZxResult {
|
||||
info!("cprng_draw_once: buf=({:?}; {:?})", buf, len);
|
||||
let mut res = vec![0u8; len];
|
||||
kernel_hal::fill_random(&mut res);
|
||||
buf.write_array(&res)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ impl Syscall<'_> {
|
|||
}
|
||||
Sys::VMAR_PROTECT => self.sys_vmar_protect(a0 as _, a1 as _, a2 as _, a3 as _),
|
||||
Sys::VMAR_DESTROY => self.sys_vmar_destroy(a0 as _),
|
||||
Sys::CPRNG_DRAW_ONCE => self.sys_cprng_draw_once(a0 as _, a1 as _),
|
||||
Sys::CPRNG_DRAW_ONCE => self.sys_cprng_draw_once(a0.into(), a1 as _),
|
||||
Sys::NANOSLEEP => self.sys_nanosleep(a0.into()).await,
|
||||
Sys::CLOCK_GET => self.sys_clock_get(a0 as _, a1.into()),
|
||||
Sys::CLOCK_READ => self.sys_clock_read(a0 as _, a1.into()),
|
||||
|
@ -292,6 +292,7 @@ impl Syscall<'_> {
|
|||
Sys::PCI_ADD_SUBTRACT_IO_RANGE => {
|
||||
self.sys_pci_add_subtract_io_range(a0 as _, a1 != 0, a2 as _, a3 as _, a4 != 0)
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
Sys::PCI_CFG_PIO_RW => self.sys_pci_cfg_pio_rw(
|
||||
a0 as _,
|
||||
a1 as _,
|
||||
|
|
|
@ -105,6 +105,7 @@ impl Syscall<'_> {
|
|||
.set_debug_addr(addr);
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
Property::RegisterFs => {
|
||||
let thread = proc.get_object::<Thread>(handle_value)?;
|
||||
assert!(Arc::ptr_eq(&thread, &self.thread));
|
||||
|
|
|
@ -34,6 +34,7 @@ impl Syscall<'_> {
|
|||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn sys_pci_cfg_pio_rw(
|
||||
&self,
|
||||
handle: HandleValue,
|
||||
|
@ -45,26 +46,21 @@ impl Syscall<'_> {
|
|||
width: usize,
|
||||
write: bool,
|
||||
) -> ZxResult {
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
return Err(ZxError::NOT_SUPPORTED);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
info!(
|
||||
info!(
|
||||
"pci.cfg_pio_rw: handle={:#x}, addr={:x}:{:x}:{:x}, offset={:#x}, width={:#x}, write={:#}",
|
||||
handle, bus, dev, func, offset, width, write
|
||||
);
|
||||
let proc = self.thread.proc();
|
||||
proc.get_object::<Resource>(handle)?
|
||||
.validate(ResourceKind::ROOT)?;
|
||||
if write {
|
||||
let value = value_ptr.read()?;
|
||||
pio_config_write(bus, dev, func, offset, value, width)?;
|
||||
} else {
|
||||
let value = pio_config_read(bus, dev, func, offset, width)?;
|
||||
value_ptr.write(value)?;
|
||||
}
|
||||
Ok(())
|
||||
let proc = self.thread.proc();
|
||||
proc.get_object::<Resource>(handle)?
|
||||
.validate(ResourceKind::ROOT)?;
|
||||
if write {
|
||||
let value = value_ptr.read()?;
|
||||
pio_config_write(bus, dev, func, offset, value, width)?;
|
||||
} else {
|
||||
let value = pio_config_read(bus, dev, func, offset, width)?;
|
||||
value_ptr.write(value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: review
|
||||
|
|
Loading…
Reference in New Issue