Remove rd/wrfsbase
This commit is contained in:
parent
8c0c4764f5
commit
4fc9283aff
|
@ -11,8 +11,9 @@ pub const GDT_KERNEL_DATA: usize = 2;
|
||||||
pub const GDT_KERNEL_TLS: usize = 3;
|
pub const GDT_KERNEL_TLS: usize = 3;
|
||||||
pub const GDT_USER_CODE: usize = 4;
|
pub const GDT_USER_CODE: usize = 4;
|
||||||
pub const GDT_USER_DATA: usize = 5;
|
pub const GDT_USER_DATA: usize = 5;
|
||||||
pub const GDT_TSS: usize = 6;
|
pub const GDT_USER_TLS: usize = 6;
|
||||||
pub const GDT_TSS_HIGH: usize = 7;
|
pub const GDT_TSS: usize = 7;
|
||||||
|
pub const GDT_TSS_HIGH: usize = 8;
|
||||||
|
|
||||||
pub const GDT_A_PRESENT: u8 = 1 << 7;
|
pub const GDT_A_PRESENT: u8 = 1 << 7;
|
||||||
pub const GDT_A_RING_0: u8 = 0 << 5;
|
pub const GDT_A_RING_0: u8 = 0 << 5;
|
||||||
|
@ -55,7 +56,7 @@ pub static mut GDTR: DescriptorTablePointer = DescriptorTablePointer {
|
||||||
};
|
};
|
||||||
|
|
||||||
#[thread_local]
|
#[thread_local]
|
||||||
pub static mut GDT: [GdtEntry; 8] = [
|
pub static mut GDT: [GdtEntry; 9] = [
|
||||||
// Null
|
// Null
|
||||||
GdtEntry::new(0, 0, 0, 0),
|
GdtEntry::new(0, 0, 0, 0),
|
||||||
// Kernel code
|
// Kernel code
|
||||||
|
@ -68,6 +69,8 @@ pub static mut GDT: [GdtEntry; 8] = [
|
||||||
GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_EXECUTABLE | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
|
GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_EXECUTABLE | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
|
||||||
// User data
|
// User data
|
||||||
GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
|
GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
|
||||||
|
// User TLS
|
||||||
|
GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
|
||||||
// TSS
|
// TSS
|
||||||
GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_TSS_AVAIL, 0),
|
GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_TSS_AVAIL, 0),
|
||||||
// TSS must be 16 bytes long, twice the normal size
|
// TSS must be 16 bytes long, twice the normal size
|
||||||
|
@ -113,6 +116,9 @@ pub unsafe fn init(tcb_offset: usize, stack_offset: usize) {
|
||||||
// Set the TLS segment to the offset of the Thread Control Block
|
// Set the TLS segment to the offset of the Thread Control Block
|
||||||
GDT[GDT_KERNEL_TLS].set_offset(tcb_offset as u32);
|
GDT[GDT_KERNEL_TLS].set_offset(tcb_offset as u32);
|
||||||
|
|
||||||
|
// Set the User TLS segment to the offset of the user TCB
|
||||||
|
GDT[GDT_USER_TLS].set_offset(::USER_TCB_OFFSET as u32);
|
||||||
|
|
||||||
// We can now access our TSS, which is a thread local
|
// We can now access our TSS, which is a thread local
|
||||||
GDT[GDT_TSS].set_offset(&TSS as *const _ as u32);
|
GDT[GDT_TSS].set_offset(&TSS as *const _ as u32);
|
||||||
GDT[GDT_TSS].set_limit(mem::size_of::<TaskStateSegment>() as u32);
|
GDT[GDT_TSS].set_limit(mem::size_of::<TaskStateSegment>() as u32);
|
||||||
|
|
|
@ -24,8 +24,6 @@ pub unsafe extern fn syscall() {
|
||||||
}
|
}
|
||||||
|
|
||||||
asm!("push r15
|
asm!("push r15
|
||||||
rdfsbase r15
|
|
||||||
push r15
|
|
||||||
push fs
|
push fs
|
||||||
mov r15, 0x18
|
mov r15, 0x18
|
||||||
mov fs, r15"
|
mov fs, r15"
|
||||||
|
@ -35,8 +33,6 @@ pub unsafe extern fn syscall() {
|
||||||
|
|
||||||
// Interrupt return
|
// Interrupt return
|
||||||
asm!("pop fs
|
asm!("pop fs
|
||||||
pop r15
|
|
||||||
wrfsbase r15
|
|
||||||
pop r15
|
pop r15
|
||||||
iretq"
|
iretq"
|
||||||
: : : : "intel", "volatile");
|
: : : : "intel", "volatile");
|
||||||
|
|
|
@ -48,6 +48,9 @@ pub extern crate x86;
|
||||||
/// Offset to user image
|
/// Offset to user image
|
||||||
pub const USER_OFFSET: usize = 0;
|
pub const USER_OFFSET: usize = 0;
|
||||||
|
|
||||||
|
/// Offset to user TCB
|
||||||
|
pub const USER_TCB_OFFSET: usize = 0xB000_0000;
|
||||||
|
|
||||||
/// Offset to user arguments
|
/// Offset to user arguments
|
||||||
pub const USER_ARG_OFFSET: usize = USER_OFFSET + PML4_SIZE/2;
|
pub const USER_ARG_OFFSET: usize = USER_OFFSET + PML4_SIZE/2;
|
||||||
|
|
||||||
|
@ -118,8 +121,6 @@ macro_rules! interrupt {
|
||||||
push r9
|
push r9
|
||||||
push r10
|
push r10
|
||||||
push r11
|
push r11
|
||||||
rdfsbase rax
|
|
||||||
push rax
|
|
||||||
push fs
|
push fs
|
||||||
mov rax, 0x18
|
mov rax, 0x18
|
||||||
mov fs, ax"
|
mov fs, ax"
|
||||||
|
@ -130,8 +131,6 @@ macro_rules! interrupt {
|
||||||
|
|
||||||
// Pop scratch registers and return
|
// Pop scratch registers and return
|
||||||
asm!("pop fs
|
asm!("pop fs
|
||||||
pop rax
|
|
||||||
wrfsbase rax
|
|
||||||
pop r11
|
pop r11
|
||||||
pop r10
|
pop r10
|
||||||
pop r9
|
pop r9
|
||||||
|
@ -184,8 +183,6 @@ macro_rules! interrupt_stack {
|
||||||
push r9
|
push r9
|
||||||
push r10
|
push r10
|
||||||
push r11
|
push r11
|
||||||
rdfsbase rax
|
|
||||||
push rax
|
|
||||||
push fs
|
push fs
|
||||||
mov rax, 0x18
|
mov rax, 0x18
|
||||||
mov fs, ax"
|
mov fs, ax"
|
||||||
|
@ -200,8 +197,6 @@ macro_rules! interrupt_stack {
|
||||||
|
|
||||||
// Pop scratch registers and return
|
// Pop scratch registers and return
|
||||||
asm!("pop fs
|
asm!("pop fs
|
||||||
pop rax
|
|
||||||
wrfsbase rax
|
|
||||||
pop r11
|
pop r11
|
||||||
pop r10
|
pop r10
|
||||||
pop r9
|
pop r9
|
||||||
|
|
|
@ -158,14 +158,13 @@ pub unsafe extern fn kstart_ap(cpu_id: usize, bsp_table: usize, stack_start: usi
|
||||||
kmain_ap(cpu_id);
|
kmain_ap(cpu_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn usermode(ip: usize, sp: usize, fs: usize) -> ! {
|
pub unsafe fn usermode(ip: usize, sp: usize) -> ! {
|
||||||
// Go to usermode
|
// Go to usermode
|
||||||
asm!("xchg bx, bx
|
asm!("xchg bx, bx
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, bx
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
wrfsbase rbx
|
|
||||||
push rax
|
push rax
|
||||||
push rcx
|
push rcx
|
||||||
push rdx
|
push rdx
|
||||||
|
@ -174,7 +173,7 @@ pub unsafe fn usermode(ip: usize, sp: usize, fs: usize) -> ! {
|
||||||
iretq"
|
iretq"
|
||||||
: // No output because it never returns
|
: // No output because it never returns
|
||||||
: "{rax}"(gdt::GDT_USER_DATA << 3 | 3), // Data segment
|
: "{rax}"(gdt::GDT_USER_DATA << 3 | 3), // Data segment
|
||||||
"{rbx}"(fs), // TLS segment
|
"{rbx}"(gdt::GDT_USER_TLS << 3 | 3), // TLS segment
|
||||||
"{rcx}"(sp), // Stack pointer
|
"{rcx}"(sp), // Stack pointer
|
||||||
"{rdx}"(3 << 12 | 1 << 9), // Flags - Set IOPL and interrupt enable flag
|
"{rdx}"(3 << 12 | 1 << 9), // Flags - Set IOPL and interrupt enable flag
|
||||||
"{rsi}"(gdt::GDT_USER_CODE << 3 | 3), // Code segment
|
"{rsi}"(gdt::GDT_USER_CODE << 3 | 3), // Code segment
|
||||||
|
|
|
@ -26,9 +26,9 @@ startup_ap:
|
||||||
mov edi, 0x70000
|
mov edi, 0x70000
|
||||||
mov cr3, edi
|
mov cr3, edi
|
||||||
|
|
||||||
;enable FSGSBASE, FXSAVE/FXRSTOR, Page Global, Page Address Extension, and Page Size Extension
|
;enable FXSAVE/FXRSTOR, Page Global, Page Address Extension, and Page Size Extension
|
||||||
mov eax, cr4
|
mov eax, cr4
|
||||||
or eax, 1 << 16 | 1 << 9 | 1 << 7 | 1 << 5 | 1 << 4
|
or eax, 1 << 9 | 1 << 7 | 1 << 5 | 1 << 4
|
||||||
mov cr4, eax
|
mov cr4, eax
|
||||||
|
|
||||||
; load protected mode GDT
|
; load protected mode GDT
|
||||||
|
@ -91,9 +91,9 @@ startup_arch:
|
||||||
mov edi, 0x70000
|
mov edi, 0x70000
|
||||||
mov cr3, edi
|
mov cr3, edi
|
||||||
|
|
||||||
;enable FSGSBASE, FXSAVE/FXRSTOR, Page Global, Page Address Extension, and Page Size Extension
|
;enable FXSAVE/FXRSTOR, Page Global, Page Address Extension, and Page Size Extension
|
||||||
mov eax, cr4
|
mov eax, cr4
|
||||||
or eax, 1 << 16 | 1 << 9 | 1 << 7 | 1 << 5 | 1 << 4
|
or eax, 1 << 9 | 1 << 7 | 1 << 5 | 1 << 4
|
||||||
mov cr4, eax
|
mov cr4, eax
|
||||||
|
|
||||||
; load protected mode GDT
|
; load protected mode GDT
|
||||||
|
|
|
@ -448,7 +448,6 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
||||||
pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||||
let entry;
|
let entry;
|
||||||
let mut sp = arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256;
|
let mut sp = arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256;
|
||||||
let fs = arch::USER_STACK_OFFSET;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
|
@ -555,6 +554,18 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||||
|
|
||||||
context.image.push(memory.to_shared());
|
context.image.push(memory.to_shared());
|
||||||
} else if segment.p_type == program_header::PT_TLS {
|
} else if segment.p_type == program_header::PT_TLS {
|
||||||
|
let memory = context::memory::Memory::new(
|
||||||
|
VirtualAddress::new(arch::USER_TCB_OFFSET),
|
||||||
|
4096,
|
||||||
|
entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
unsafe { *(arch::USER_TCB_OFFSET as *mut usize) = arch::USER_TLS_OFFSET + segment.p_memsz as usize; }
|
||||||
|
|
||||||
|
context.image.push(memory.to_shared());
|
||||||
|
|
||||||
tls_option = Some((
|
tls_option = Some((
|
||||||
VirtualAddress::new(segment.p_vaddr as usize),
|
VirtualAddress::new(segment.p_vaddr as usize),
|
||||||
segment.p_filesz as usize,
|
segment.p_filesz as usize,
|
||||||
|
@ -602,10 +613,6 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||||
file_size);
|
file_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set TLS pointer
|
|
||||||
//TODO: Do not use stack to store TLS pointer, use a TCB structure instead
|
|
||||||
unsafe { *(arch::USER_STACK_OFFSET as *mut usize) = tls.mem.start_address().get() + size; }
|
|
||||||
|
|
||||||
context.tls = Some(tls);
|
context.tls = Some(tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,7 +679,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go to usermode
|
// Go to usermode
|
||||||
unsafe { usermode(entry, sp, fs); }
|
unsafe { usermode(entry, sp); }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit(status: usize) -> ! {
|
pub fn exit(status: usize) -> ! {
|
||||||
|
|
Loading…
Reference in a new issue