Remove rd/wrfsbase

This commit is contained in:
Jeremy Soller 2016-10-31 18:04:28 -06:00
parent 8c0c4764f5
commit 4fc9283aff
6 changed files with 32 additions and 29 deletions

View file

@ -11,8 +11,9 @@ pub const GDT_KERNEL_DATA: usize = 2;
pub const GDT_KERNEL_TLS: usize = 3;
pub const GDT_USER_CODE: usize = 4;
pub const GDT_USER_DATA: usize = 5;
pub const GDT_TSS: usize = 6;
pub const GDT_TSS_HIGH: usize = 7;
pub const GDT_USER_TLS: usize = 6;
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_RING_0: u8 = 0 << 5;
@ -55,7 +56,7 @@ pub static mut GDTR: DescriptorTablePointer = DescriptorTablePointer {
};
#[thread_local]
pub static mut GDT: [GdtEntry; 8] = [
pub static mut GDT: [GdtEntry; 9] = [
// Null
GdtEntry::new(0, 0, 0, 0),
// 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),
// User data
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
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
@ -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
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
GDT[GDT_TSS].set_offset(&TSS as *const _ as u32);
GDT[GDT_TSS].set_limit(mem::size_of::<TaskStateSegment>() as u32);

View file

@ -24,8 +24,6 @@ pub unsafe extern fn syscall() {
}
asm!("push r15
rdfsbase r15
push r15
push fs
mov r15, 0x18
mov fs, r15"
@ -35,8 +33,6 @@ pub unsafe extern fn syscall() {
// Interrupt return
asm!("pop fs
pop r15
wrfsbase r15
pop r15
iretq"
: : : : "intel", "volatile");

View file

@ -48,6 +48,9 @@ pub extern crate x86;
/// Offset to user image
pub const USER_OFFSET: usize = 0;
/// Offset to user TCB
pub const USER_TCB_OFFSET: usize = 0xB000_0000;
/// Offset to user arguments
pub const USER_ARG_OFFSET: usize = USER_OFFSET + PML4_SIZE/2;
@ -118,8 +121,6 @@ macro_rules! interrupt {
push r9
push r10
push r11
rdfsbase rax
push rax
push fs
mov rax, 0x18
mov fs, ax"
@ -130,8 +131,6 @@ macro_rules! interrupt {
// Pop scratch registers and return
asm!("pop fs
pop rax
wrfsbase rax
pop r11
pop r10
pop r9
@ -184,8 +183,6 @@ macro_rules! interrupt_stack {
push r9
push r10
push r11
rdfsbase rax
push rax
push fs
mov rax, 0x18
mov fs, ax"
@ -200,8 +197,6 @@ macro_rules! interrupt_stack {
// Pop scratch registers and return
asm!("pop fs
pop rax
wrfsbase rax
pop r11
pop r10
pop r9

View file

@ -158,14 +158,13 @@ pub unsafe extern fn kstart_ap(cpu_id: usize, bsp_table: usize, stack_start: usi
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
asm!("xchg bx, bx
mov ds, ax
mov es, ax
mov fs, ax
mov fs, bx
mov gs, ax
wrfsbase rbx
push rax
push rcx
push rdx
@ -174,7 +173,7 @@ pub unsafe fn usermode(ip: usize, sp: usize, fs: usize) -> ! {
iretq"
: // No output because it never returns
: "{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
"{rdx}"(3 << 12 | 1 << 9), // Flags - Set IOPL and interrupt enable flag
"{rsi}"(gdt::GDT_USER_CODE << 3 | 3), // Code segment

View file

@ -26,9 +26,9 @@ startup_ap:
mov edi, 0x70000
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
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
; load protected mode GDT
@ -91,9 +91,9 @@ startup_arch:
mov edi, 0x70000
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
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
; load protected mode GDT

View file

@ -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> {
let entry;
let mut sp = arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256;
let fs = arch::USER_STACK_OFFSET;
{
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());
} 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((
VirtualAddress::new(segment.p_vaddr as usize),
segment.p_filesz as usize,
@ -602,10 +613,6 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
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);
}
@ -672,7 +679,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
}
// Go to usermode
unsafe { usermode(entry, sp, fs); }
unsafe { usermode(entry, sp); }
}
pub fn exit(status: usize) -> ! {