This commit is contained in:
parent
1cccf16bfe
commit
76e31b5e42
8 changed files with 48 additions and 2 deletions
|
@ -22,6 +22,7 @@ global_asm!(include_str!("isr.s"), options(att_syntax));
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct ISRState {
|
pub struct ISRState {
|
||||||
|
pub ds: u64,
|
||||||
pub rax: u64,
|
pub rax: u64,
|
||||||
pub rbx: u64,
|
pub rbx: u64,
|
||||||
pub rcx: u64,
|
pub rcx: u64,
|
||||||
|
|
|
@ -31,10 +31,17 @@ isr_common:
|
||||||
push %rcx
|
push %rcx
|
||||||
push %rbx
|
push %rbx
|
||||||
push %rax
|
push %rax
|
||||||
|
mov %ds, %rax
|
||||||
|
push %rax
|
||||||
mov %rsp, %rdi
|
mov %rsp, %rdi
|
||||||
|
|
||||||
call isr_handler
|
call isr_handler
|
||||||
|
|
||||||
|
pop %rax
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
pop %rax
|
pop %rax
|
||||||
pop %rbx
|
pop %rbx
|
||||||
pop %rcx
|
pop %rcx
|
||||||
|
|
|
@ -6,4 +6,30 @@ syscall:
|
||||||
mov %rsp, %gs:8
|
mov %rsp, %gs:8
|
||||||
mov %gs:0, %rsp
|
mov %gs:0, %rsp
|
||||||
swapgs
|
swapgs
|
||||||
jmp .
|
sti
|
||||||
|
push %r11
|
||||||
|
push %r10
|
||||||
|
push %r9
|
||||||
|
push %r8
|
||||||
|
push %rsi
|
||||||
|
push %rdi
|
||||||
|
push %rdx
|
||||||
|
push %rcx
|
||||||
|
push %rax
|
||||||
|
|
||||||
|
call syscall_handler
|
||||||
|
|
||||||
|
pop %rax
|
||||||
|
pop %rcx
|
||||||
|
pop %rdx
|
||||||
|
pop %rdi
|
||||||
|
pop %rsi
|
||||||
|
pop %r8
|
||||||
|
pop %r9
|
||||||
|
pop %r10
|
||||||
|
pop %r11
|
||||||
|
cli
|
||||||
|
swapgs
|
||||||
|
mov %gs:8, %rsp
|
||||||
|
swapgs
|
||||||
|
sysretq
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
.global jump_usermode
|
.global jump_usermode
|
||||||
jump_usermode:
|
jump_usermode:
|
||||||
|
cli // Ensure consistency in segment registers
|
||||||
mov $0x1b, %ax
|
mov $0x1b, %ax
|
||||||
mov %ax, %ds
|
mov %ax, %ds
|
||||||
mov %ax, %es
|
mov %ax, %es
|
||||||
mov %ax, %fs
|
mov %ax, %fs
|
||||||
mov %ax, %gs
|
mov %ax, %gs
|
||||||
|
sti
|
||||||
push $0x1b
|
push $0x1b
|
||||||
push $0
|
push $0
|
||||||
pushf
|
pushf
|
||||||
|
|
|
@ -41,6 +41,7 @@ pub fn send_eoi() {
|
||||||
address.add(REGISTER_EOI).write_volatile(0);
|
address.add(REGISTER_EOI).write_volatile(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// It's unsafe to get the LAPIC ID if interrupts are enabled, because the task can have migrated to a different core.
|
||||||
pub fn get_current_lapic_id() -> usize {
|
pub fn get_current_lapic_id() -> usize {
|
||||||
let address = ADDRESS.load(Ordering::SeqCst);
|
let address = ADDRESS.load(Ordering::SeqCst);
|
||||||
let lapic_id = unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 };
|
let lapic_id = unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 };
|
||||||
|
|
|
@ -10,4 +10,5 @@ pub mod process;
|
||||||
pub mod scheduler;
|
pub mod scheduler;
|
||||||
pub mod smp;
|
pub mod smp;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
|
mod syscall;
|
||||||
pub mod task;
|
pub mod task;
|
||||||
|
|
2
kernel/src/sys/syscall.rs
Normal file
2
kernel/src/sys/syscall.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#[no_mangle]
|
||||||
|
extern "C" fn syscall_handler() {}
|
|
@ -40,6 +40,7 @@ pub struct Task {
|
||||||
pub sleep_until_us: usize,
|
pub sleep_until_us: usize,
|
||||||
pub block_on_semaphore: Option<Arc<RawSemaphore>>,
|
pub block_on_semaphore: Option<Arc<RawSemaphore>>,
|
||||||
pub semaphore_requested_count: usize,
|
pub semaphore_requested_count: usize,
|
||||||
|
user_stack: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -64,8 +65,10 @@ pub fn allocate_stack() -> u64 {
|
||||||
pub fn switch_task(current_state: &mut ISRState, new_task: Task) {
|
pub fn switch_task(current_state: &mut ISRState, new_task: Task) {
|
||||||
let lapic_id = get_current_lapic_id();
|
let lapic_id = get_current_lapic_id();
|
||||||
let mut current_tasks = CURRENT_TASKS.lock();
|
let mut current_tasks = CURRENT_TASKS.lock();
|
||||||
|
let cpu_data = &mut CPUDATA.lock()[lapic_id];
|
||||||
if let Some(mut current_task) = current_tasks[lapic_id].take() {
|
if let Some(mut current_task) = current_tasks[lapic_id].take() {
|
||||||
current_task.state = *current_state;
|
current_task.state = *current_state;
|
||||||
|
current_task.user_stack = cpu_data.user_stack;
|
||||||
if current_task.task_state == TaskState::Terminated {
|
if current_task.task_state == TaskState::Terminated {
|
||||||
unsafe {
|
unsafe {
|
||||||
get_kernel_process().lock().address_space.switch();
|
get_kernel_process().lock().address_space.switch();
|
||||||
|
@ -90,7 +93,8 @@ pub fn switch_task(current_state: &mut ISRState, new_task: Task) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let kernel_stack = new_task.kernel_stack.as_ptr() as u64 + STACK_SIZE as u64;
|
let kernel_stack = new_task.kernel_stack.as_ptr() as u64 + STACK_SIZE as u64;
|
||||||
CPUDATA.lock()[lapic_id].kernel_stack = kernel_stack;
|
cpu_data.kernel_stack = kernel_stack;
|
||||||
|
cpu_data.user_stack = new_task.user_stack;
|
||||||
current_tasks[get_current_lapic_id()] = Some(new_task);
|
current_tasks[get_current_lapic_id()] = Some(new_task);
|
||||||
schedule_timer_interrupt();
|
schedule_timer_interrupt();
|
||||||
}
|
}
|
||||||
|
@ -100,6 +104,7 @@ pub fn create_task(process: Arc<Spinlock<Process>>, func: fn()) -> Task {
|
||||||
id: NEXT_TASK_ID.fetch_add(1, Ordering::SeqCst),
|
id: NEXT_TASK_ID.fetch_add(1, Ordering::SeqCst),
|
||||||
process,
|
process,
|
||||||
state: ISRState {
|
state: ISRState {
|
||||||
|
ds: 0x10,
|
||||||
rax: 0,
|
rax: 0,
|
||||||
rbx: 0,
|
rbx: 0,
|
||||||
rcx: 0,
|
rcx: 0,
|
||||||
|
@ -129,6 +134,7 @@ pub fn create_task(process: Arc<Spinlock<Process>>, func: fn()) -> Task {
|
||||||
sleep_until_us: 0,
|
sleep_until_us: 0,
|
||||||
block_on_semaphore: None,
|
block_on_semaphore: None,
|
||||||
semaphore_requested_count: 0,
|
semaphore_requested_count: 0,
|
||||||
|
user_stack: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn create_idle_task() {
|
fn create_idle_task() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue