Add the task section of LoongArch in OSTD
This commit is contained in:
parent
e4db73e1a0
commit
93c562f5d2
|
|
@ -0,0 +1,105 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! The architecture support of context switch.
|
||||
|
||||
use crate::task::TaskContextApi;
|
||||
|
||||
core::arch::global_asm!(include_str!("switch.S"));
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub(crate) struct TaskContext {
|
||||
pub regs: CalleeRegs,
|
||||
pub ra: usize,
|
||||
/// Thread-local storage pointer.
|
||||
pub tp: usize,
|
||||
}
|
||||
|
||||
/// Callee-saved registers.
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct CalleeRegs {
|
||||
/// sp
|
||||
pub sp: usize,
|
||||
/// fp
|
||||
pub fp: usize,
|
||||
/// s0
|
||||
pub s0: usize,
|
||||
/// s1
|
||||
pub s1: usize,
|
||||
/// s2
|
||||
pub s2: usize,
|
||||
/// s3
|
||||
pub s3: usize,
|
||||
/// s4
|
||||
pub s4: usize,
|
||||
/// s5
|
||||
pub s5: usize,
|
||||
/// s6
|
||||
pub s6: usize,
|
||||
/// s7
|
||||
pub s7: usize,
|
||||
/// s8
|
||||
pub s8: usize,
|
||||
}
|
||||
|
||||
impl CalleeRegs {
|
||||
/// Creates new `CalleeRegs`
|
||||
pub const fn new() -> Self {
|
||||
CalleeRegs {
|
||||
sp: 0,
|
||||
fp: 0,
|
||||
s0: 0,
|
||||
s1: 0,
|
||||
s2: 0,
|
||||
s3: 0,
|
||||
s4: 0,
|
||||
s5: 0,
|
||||
s6: 0,
|
||||
s7: 0,
|
||||
s8: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TaskContext {
|
||||
pub const fn new() -> Self {
|
||||
TaskContext {
|
||||
regs: CalleeRegs::new(),
|
||||
ra: 0,
|
||||
tp: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets thread-local storage pointer.
|
||||
pub fn set_tls_pointer(&mut self, tls: usize) {
|
||||
self.tp = tls;
|
||||
}
|
||||
|
||||
/// Gets thread-local storage pointer.
|
||||
pub fn tls_pointer(&self) -> usize {
|
||||
self.tp
|
||||
}
|
||||
}
|
||||
|
||||
impl TaskContextApi for TaskContext {
|
||||
fn set_instruction_pointer(&mut self, ip: usize) {
|
||||
self.ra = ip;
|
||||
}
|
||||
|
||||
fn instruction_pointer(&self) -> usize {
|
||||
self.ra
|
||||
}
|
||||
|
||||
fn set_stack_pointer(&mut self, sp: usize) {
|
||||
self.regs.sp = sp;
|
||||
}
|
||||
|
||||
fn stack_pointer(&self) -> usize {
|
||||
self.regs.sp
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
pub(crate) unsafe fn context_switch(cur: *mut TaskContext, nxt: *const TaskContext);
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/* SPDX-License-Identifier: MPL-2.0 */
|
||||
|
||||
.text
|
||||
.global context_switch
|
||||
context_switch: # (cur: *mut TaskContext, nxt: *TaskContext)
|
||||
# Save cur's register
|
||||
st.d $sp, $a0, 0x0
|
||||
st.d $fp, $a0, 0x8
|
||||
st.d $s0, $a0, 0x10
|
||||
st.d $s1, $a0, 0x18
|
||||
st.d $s2, $a0, 0x20
|
||||
st.d $s3, $a0, 0x28
|
||||
st.d $s4, $a0, 0x30
|
||||
st.d $s5, $a0, 0x38
|
||||
st.d $s6, $a0, 0x40
|
||||
st.d $s7, $a0, 0x48
|
||||
st.d $s8, $a0, 0x50
|
||||
st.d $ra, $a0, 0x58 # return address
|
||||
st.d $tp, $a0, 0x60 # thread-local storage pointer
|
||||
|
||||
# Restore nxt's registers
|
||||
ld.d $sp, $a1, 0x0
|
||||
ld.d $fp, $a1, 0x8
|
||||
ld.d $s0, $a1, 0x10
|
||||
ld.d $s1, $a1, 0x18
|
||||
ld.d $s2, $a1, 0x20
|
||||
ld.d $s3, $a1, 0x28
|
||||
ld.d $s4, $a1, 0x30
|
||||
ld.d $s5, $a1, 0x38
|
||||
ld.d $s6, $a1, 0x40
|
||||
ld.d $s7, $a1, 0x48
|
||||
ld.d $s8, $a1, 0x50
|
||||
ld.d $ra, $a1, 0x58 # return address
|
||||
ld.d $tp, $a1, 0x60 # thread-local storage pointer
|
||||
ret
|
||||
Loading…
Reference in New Issue