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