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_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);

View file

@ -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");

View file

@ -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

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); 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

View file

@ -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

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> { 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) -> ! {