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_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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) -> ! {
|
||||
|
|
Loading…
Reference in a new issue