1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 08:06:17 +04:00

Fix compilation for mipsel

This commit is contained in:
Jiajie Chen 2020-07-06 00:20:16 +08:00
parent 455a29ba55
commit 2589319769
15 changed files with 107 additions and 357 deletions

2
kernel/Cargo.lock generated
View File

@ -709,7 +709,7 @@ checksum = "3a385d94f3f62e60445a0adb9ff8d9621faa272234530d4c0f848ec98f88e316"
[[package]]
name = "trapframe"
version = "0.4.3"
source = "git+https://github.com/rcore-os/trapframe-rs?rev=b7fb4ff#b7fb4ffb3d8d36355842867837e13384c68212a2"
source = "git+https://github.com/rcore-os/trapframe-rs?rev=063a844#063a844654aaf37af2ef2afac305b4b025407441"
dependencies = [
"raw-cpuid",
"x86_64",

View File

@ -70,7 +70,7 @@ rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "517af47"
rlibc = "1.0"
smoltcp = { git = "https://github.com/rcore-os/smoltcp", rev = "5bd87c7c", default-features = false, features = ["alloc", "log", "ethernet", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] }
spin = "0.5"
trapframe = { git = "https://github.com/rcore-os/trapframe-rs", rev = "b7fb4ff" }
trapframe = { git = "https://github.com/rcore-os/trapframe-rs", rev = "063a844" }
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "dfa70e14" }
volatile = "0.2"
woke = "0.0.2"

View File

@ -7,5 +7,4 @@ pub const USER_STACK_OFFSET: usize = 0x0000_8000_0000_0000 - USER_STACK_SIZE;
pub const USER_STACK_SIZE: usize = 1 * 1024 * 1024;
pub const KSEG2_START: usize = 0xffff_fe80_0000_0000;
#[cfg(target_arch = "aarch64")]
pub const ARCH: &'static str = "aarch64";

View File

@ -14,3 +14,5 @@ pub const USER_STACK_SIZE: usize = 0x10000;
pub const MAX_DTB_SIZE: usize = 0x2000;
pub const KSEG2_START: usize = 0xfe80_0000;
pub const ARCH: &'static str = "mipsel";

View File

@ -1,340 +0,0 @@
use mips::registers::cp0;
use mips::tlb::TLBEntry;
/// Saved registers on a trap.
#[derive(Clone)]
#[repr(C)]
pub struct TrapFrame {
/// Non-zero if the kernel stack is not 16-byte-aligned
pub unaligned_kstack: usize,
/// unused 12 bytes
pub unused: [usize; 3],
/// CP0 status register
pub status: cp0::status::Status,
/// CP0 cause register
pub cause: cp0::cause::Cause,
/// CP0 EPC register
pub epc: usize,
/// CP0 vaddr register
pub vaddr: usize,
/// HI/LO registers
pub hi: usize,
pub lo: usize,
/// General registers
pub at: usize,
pub v0: usize,
pub v1: usize,
pub a0: usize,
pub a1: usize,
pub a2: usize,
pub a3: usize,
pub t0: usize,
pub t1: usize,
pub t2: usize,
pub t3: usize,
pub t4: usize,
pub t5: usize,
pub t6: usize,
pub t7: usize,
pub s0: usize,
pub s1: usize,
pub s2: usize,
pub s3: usize,
pub s4: usize,
pub s5: usize,
pub s6: usize,
pub s7: usize,
pub t8: usize,
pub t9: usize,
pub k0: usize,
pub k1: usize,
pub gp: usize,
pub sp: usize,
pub fp: usize,
pub ra: usize,
/// Floating-point registers (contains garbage if no FP support present)
pub f0: usize,
pub f1: usize,
pub f2: usize,
pub f3: usize,
pub f4: usize,
pub f5: usize,
pub f6: usize,
pub f7: usize,
pub f8: usize,
pub f9: usize,
pub f10: usize,
pub f11: usize,
pub f12: usize,
pub f13: usize,
pub f14: usize,
pub f15: usize,
pub f16: usize,
pub f17: usize,
pub f18: usize,
pub f19: usize,
pub f20: usize,
pub f21: usize,
pub f22: usize,
pub f23: usize,
pub f24: usize,
pub f25: usize,
pub f26: usize,
pub f27: usize,
pub f28: usize,
pub f29: usize,
pub f30: usize,
pub f31: usize,
/// Reserved
pub reserved: usize,
pub __padding: [usize; 2],
}
impl TrapFrame {
/// Constructs TrapFrame for a new kernel thread.
///
/// The new thread starts at function `entry` with an usize argument `arg`.
/// The stack pointer will be set to `sp`.
fn new_kernel_thread(entry: extern "C" fn(usize) -> !, arg: usize, sp: usize) -> Self {
use core::mem::zeroed;
let mut tf: Self = unsafe { zeroed() };
tf.a0 = arg;
tf.sp = sp;
tf.epc = entry as usize;
tf.status = cp0::status::read();
tf.status.set_kernel_mode();
tf.status.set_ie();
tf.status.set_exl();
tf
}
/// Constructs TrapFrame for a new user thread.
///
/// The new thread starts at `entry_addr`.
/// The stack pointer will be set to `sp`.
pub fn new_user_thread(entry_addr: usize, sp: usize) -> Self {
use core::mem::zeroed;
let mut tf: Self = unsafe { zeroed() };
tf.sp = sp;
tf.epc = entry_addr;
tf.status = cp0::status::read();
tf.status.set_user_mode();
tf.status.set_ie();
tf.status.set_exl();
tf
}
}
use core::fmt::{Debug, Error, Formatter};
impl Debug for TrapFrame {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
f.debug_struct("TrapFrame")
.field("status", &self.status.bits)
.field("epc", &self.epc)
.field("cause", &self.cause.bits)
.field("vaddr", &self.vaddr)
.field("at", &self.at)
.field("v0", &self.v0)
.field("v1", &self.v1)
.field("a0", &self.a0)
.field("a1", &self.a1)
.field("a2", &self.a2)
.field("a3", &self.a3)
.field("t0", &self.t0)
.field("t1", &self.t1)
.field("t2", &self.t2)
.field("t3", &self.t3)
.field("t4", &self.t4)
.field("t5", &self.t5)
.field("t6", &self.t6)
.field("t7", &self.t7)
.field("s0", &self.s0)
.field("s1", &self.s1)
.field("s2", &self.s2)
.field("s3", &self.s3)
.field("s4", &self.s4)
.field("s5", &self.s5)
.field("s6", &self.s6)
.field("s7", &self.s7)
.field("t8", &self.t8)
.field("t9", &self.t9)
.field("k0", &self.k0)
.field("k1", &self.k1)
.field("gp", &self.gp)
.field("sp", &self.sp)
.field("fp", &self.fp)
.field("ra", &self.ra)
.finish()
}
}
/// Kernel stack contents for a new thread
#[derive(Debug)]
#[repr(C)]
pub struct InitStack {
context: ContextData,
tf: TrapFrame,
}
impl InitStack {
/// Push the InitStack on the stack and transfer to a Context.
unsafe fn push_at(self, stack_top: usize) -> Context {
let ptr = (stack_top as *mut Self).sub(1); //real kernel stack top
*ptr = self;
Context { sp: ptr as usize }
}
}
extern "C" {
fn trap_return();
fn _cur_tls();
}
/// Saved registers for kernel context switches.
#[derive(Debug, Default)]
#[repr(C)]
struct ContextData {
/// Return address
ra: usize,
/// Page table token
satp: usize,
/// s[0] = TLS
/// s[1] = reserved
/// s[2..11] = Callee-saved registers
s: [usize; 12],
__padding: [usize; 2],
}
impl ContextData {
fn new(satp: usize, tls: usize) -> Self {
let mut context = ContextData {
ra: trap_return as usize,
satp: satp,
..ContextData::default()
};
context.s[0] = tls;
context
}
}
/// Context of a kernel thread.
#[derive(Debug)]
#[repr(C)]
pub struct Context {
/// The stack pointer of the suspended thread.
/// A `ContextData` is stored here.
sp: usize,
}
impl Context {
/// Switch to another kernel thread.
///
/// Push all callee-saved registers at the current kernel stack.
/// Store current sp, switch to target.
/// Pop all callee-saved registers, then return to the target.
#[inline(always)]
pub unsafe fn switch(&mut self, target: &mut Self) {
extern "C" {
fn switch_context(src: *mut Context, dst: *mut Context);
}
TLBEntry::clear_all();
switch_context(self as *mut Context, target as *mut Context);
}
/// Constructs a null Context for the current running thread.
pub unsafe fn null() -> Self {
Context { sp: 0 }
}
/// Constructs Context for a new kernel thread.
///
/// The new thread starts at function `entry` with an usize argument `arg`.
/// The stack pointer will be set to `kstack_top`.
/// The SATP register will be set to `satp`.
pub unsafe fn new_kernel_thread(
entry: extern "C" fn(usize) -> !,
arg: usize,
kstack_top: usize,
satp: usize,
) -> Self {
info!(
"New kernel thread @ {:x}, stack = {:x}",
entry as usize, kstack_top
);
InitStack {
context: ContextData::new(satp, 0),
tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top),
}
.push_at(kstack_top)
}
/// Constructs Context for a new user thread.
///
/// The new thread starts at `entry_addr`.
/// The stack pointer of user and kernel mode will be set to `ustack_top`, `kstack_top`.
/// The SATP register will be set to `satp`.
pub unsafe fn new_user_thread(
entry_addr: usize,
ustack_top: usize,
kstack_top: usize,
satp: usize,
) -> Self {
info!(
"New user thread @ {:x}, stack = {:x}",
entry_addr, kstack_top
);
InitStack {
context: ContextData::new(satp, 0),
tf: TrapFrame::new_user_thread(entry_addr, ustack_top),
}
.push_at(kstack_top)
}
/// Fork a user process and get the new Context.
///
/// The stack pointer in kernel mode will be set to `kstack_top`.
/// The SATP register will be set to `satp`.
/// All the other registers are same as the original.
pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, satp: usize) -> Self {
let tls = *(_cur_tls as *const usize);
InitStack {
context: ContextData::new(satp, tls),
tf: {
let mut tf = tf.clone();
// fork function's ret value, the new process is 0
tf.v0 = 0;
tf
},
}
.push_at(kstack_top)
}
/// Fork a user thread and get the new Context.
///
/// The stack pointer in kernel mode will be set to `kstack_top`.
/// The SATP register will be set to `satp`.
/// The new user stack will be set to `ustack_top`.
/// The new thread pointer will be set to `tls`.
/// All the other registers are same as the original.
pub unsafe fn new_clone(
tf: &TrapFrame,
ustack_top: usize,
kstack_top: usize,
satp: usize,
tls: usize,
) -> Self {
InitStack {
context: ContextData::new(satp, tls),
tf: {
let mut tf = tf.clone();
tf.sp = ustack_top; // sp
tf.v0 = 0; // return value
tf
},
}
.push_at(kstack_top)
}
}

View File

@ -0,0 +1,14 @@
//! SPDX-License-Identifier: (Apache-2.0 OR MIT)
#[derive(Debug, Copy, Clone, Default)]
pub struct FpState {}
impl FpState {
pub fn new() -> Self {
Self { ..Self::default() }
}
pub fn save(&mut self) {}
pub fn restore(&self) {}
}

View File

@ -0,0 +1,9 @@
pub const IrqMin: usize = 0x20;
pub const IrqMax: usize = 0x3f;
pub const Syscall: usize = 0x100;
pub const Timer: usize = IrqMin + 0;
pub fn is_page_fault(trap: usize) -> bool {
false
}

View File

@ -1,4 +1,3 @@
pub use self::context::*;
use crate::arch::paging::get_root_page_table_ptr;
use crate::drivers::IRQ_MANAGER;
use log::*;
@ -6,9 +5,9 @@ use mips::addr::*;
use mips::interrupts;
use mips::paging::PageTable as MIPSPageTable;
use mips::registers::cp0;
use trapframe::{TrapFrame, UserContext};
#[path = "context.rs"]
mod context;
pub mod consts;
/// Initialize interrupt
pub fn init() {
@ -61,7 +60,7 @@ pub extern "C" fn stack_pointer_not_aligned(sp: usize) {
///
/// This function is called from `trap.asm`.
#[no_mangle]
pub extern "C" fn rust_trap(tf: &mut TrapFrame) {
pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
use cp0::cause::Exception as E;
trace!("Exception @ CPU{}: {:?} ", 0, tf.cause.cause());
match tf.cause.cause() {
@ -73,7 +72,6 @@ pub extern "C" fn rust_trap(tf: &mut TrapFrame) {
E::ReservedInstruction => {
if !reserved_inst(tf) {
error!("Unhandled Exception @ CPU{}: {:?} ", 0, tf.cause.cause());
crate::trap::error(tf)
} else {
tf.epc = tf.epc + 4;
}
@ -83,7 +81,6 @@ pub extern "C" fn rust_trap(tf: &mut TrapFrame) {
}
_ => {
error!("Unhandled Exception @ CPU{}: {:?} ", 0, tf.cause.cause());
crate::trap::error(tf)
}
}
trace!("Interrupt end");
@ -147,7 +144,8 @@ fn syscall(tf: &mut TrapFrame) {
tf.epc
);
let ret = crate::syscall::syscall(tf.v0, arguments, tf) as isize;
//let ret = crate::syscall::syscall(tf.v0, arguments, tf) as isize;
let ret = 0;
// comply with mips n32 abi, always return a positive value
// https://git.musl-libc.org/cgit/musl/tree/arch/mipsn32/syscall_arch.h
if ret < 0 {
@ -194,7 +192,7 @@ fn set_trapframe_register(rt: usize, val: usize, tf: &mut TrapFrame) {
31 => tf.ra = val,
_ => {
error!("Unknown register {:?} ", rt);
crate::trap::error(tf)
//crate::trap::error(tf)
}
}
}
@ -266,7 +264,7 @@ fn page_fault(tf: &mut TrapFrame) {
tf.epc = crate::memory::read_user_fixup as usize;
return;
}
crate::trap::error(tf);
//crate::trap::error(tf);
}
}
@ -283,8 +281,24 @@ fn page_fault(tf: &mut TrapFrame) {
tf.epc = crate::memory::read_user_fixup as usize;
return;
}
crate::trap::error(tf);
//crate::trap::error(tf);
}
}
}
}
pub fn enable_irq(irq: usize) {
// TODO
}
pub fn get_trap_num(cx: &UserContext) -> usize {
cx.cause
}
pub fn ack(_irq: usize) {
// TODO
}
pub fn wait_for_interrupt() {
// TODO
}

View File

@ -69,3 +69,11 @@ extern "C" {
fn bootstack();
fn bootstacktop();
}
pub fn set_page_table(vmtoken: usize) {
// TODO
}
pub fn get_page_fault_addr() -> usize {
// TODO
}

View File

@ -1,11 +1,13 @@
pub mod consts;
pub mod cpu;
pub mod driver;
pub mod fp;
pub mod interrupt;
pub mod io;
pub mod memory;
pub mod paging;
pub mod rand;
pub mod signal;
pub mod syscall;
pub mod timer;
@ -49,7 +51,7 @@ pub extern "C" fn rust_main() -> ! {
println!("Hello MIPS 32 from CPU {}, dtb @ {:#x}", cpu_id, dtb_start);
crate::drivers::init(dtb_start);
//crate::drivers::init(dtb_start);
crate::process::init();
// TODO: start other CPU

View File

@ -0,0 +1,36 @@
use crate::signal::Siginfo;
use crate::signal::SignalUserContext;
use trapframe::UserContext;
// mcontext
#[repr(C)]
#[derive(Clone, Debug)]
pub struct MachineContext {}
impl MachineContext {
pub fn from_tf(tf: &UserContext) -> Self {
Self {}
}
pub fn fill_tf(&self, tf: &mut UserContext) {}
}
// TODO
pub const RET_CODE: [u8; 7] = [0; 7];
pub fn set_signal_handler(
tf: &mut UserContext,
sp: usize,
handler: usize,
signo: usize,
siginfo: *const Siginfo,
ucontext: *const SignalUserContext,
) {
//tf.sp = sp;
//tf.elr = handler;
// pass handler argument
//tf.general.x0 = signo as usize;
//tf.general.x1 = siginfo as usize;
//tf.general.x2 = ucontext as usize;
}

View File

@ -1,3 +1,4 @@
use core::time::Duration;
use log::*;
use mips::registers::cp0;
@ -17,3 +18,8 @@ pub fn set_next() {
cp0::count::write_u32(0);
cp0::compare::write_u32(timebase);
}
pub fn timer_now() -> Duration {
// TODO
Duration::from_nanos(0)
}

View File

@ -13,7 +13,7 @@ pub const TCGETS: usize = 0x540D;
#[cfg(not(target_arch = "mips"))]
pub const TCSETS: usize = 0x5402;
#[cfg(target_arch = "mips")]
pub const TCGETS: usize = 0x540E;
pub const TCSETS: usize = 0x540E;
#[cfg(not(target_arch = "mips"))]
pub const TIOCGPGRP: usize = 0x540F;

View File

@ -516,7 +516,7 @@ pub fn spawn(thread: Arc<Thread>) {
crate::arch::interrupt::ack(trap_num);
trace!("handle irq {:#x}", trap_num);
if trap_num == Timer {
crate::arch::interrupt::timer();
//crate::arch::interrupt::timer();
}
IRQ_MANAGER.read().try_handle_interrupt(Some(trap_num));
}

2
user

@ -1 +1 @@
Subproject commit 291df7f66ed42f642cd691554fa0c88e59cdb894
Subproject commit 63342746297b9694676c82a716601d736ebab1a1