1 // Copyright 2016 The Fuchsia Authors 2 // Copyright (c) 2009 Corey Tabaka 3 // Copyright (c) 2014 Intel Corporation 4 // 5 // Use of this source code is governed by a MIT-style 6 // license that can be found in the LICENSE file or at 7 // https://opensource.org/licenses/MIT 8 9 #pragma once 10 11 /* 12 * System Selectors 13 */ 14 #define NULL_SELECTOR 0x00 15 16 /********* kernel selectors *********/ 17 #define CODE_SELECTOR 0x08 18 #define CODE_64_SELECTOR 0x10 19 #define DATA_SELECTOR 0x18 20 21 /********* user selectors *********/ 22 #define USER_CODE_SELECTOR (0x20 | 3) 23 #define USER_DATA_SELECTOR (0x28 | 3) 24 #define USER_CODE_64_SELECTOR (0x30 | 3) 25 26 #define TSS_SELECTOR(i) ((uint16_t)(0x38 + 16 * (i))) 27 /* 0x40 is used by the second half of the first TSS descriptor */ 28 29 /* selector priviledge level */ 30 #define SELECTOR_PL(s) ((s) & 0x3) 31 32 /* 33 * Descriptor Types 34 */ 35 #define SEG_TYPE_TSS 0x9 36 #define SEG_TYPE_TSS_BUSY 0xb 37 #define SEG_TYPE_TASK_GATE 0x5 38 #define SEG_TYPE_INT_GATE 0xe /* 32 bit */ 39 #define SEG_TYPE_DATA_RW 0x2 40 #define SEG_TYPE_CODE_RW 0xa 41 42 #ifndef __ASSEMBLER__ 43 44 #include <arch/aspace.h> 45 #include <zircon/compiler.h> 46 #include <reg.h> 47 #include <sys/types.h> 48 49 #ifdef __cplusplus 50 #include <arch/x86/ioport.h> 51 52 void x86_set_tss_io_bitmap(IoBitmap& bitmap); 53 void x86_clear_tss_io_bitmap(IoBitmap& bitmap); 54 void x86_reset_tss_io_bitmap(void); 55 #endif // __cplusplus 56 57 __BEGIN_CDECLS 58 59 typedef uint16_t seg_sel_t; 60 61 /* fill in a descriptor in the GDT */ 62 void set_global_desc_64(seg_sel_t sel, uint64_t base, uint32_t limit, 63 uint8_t present, uint8_t ring, uint8_t sys, 64 uint8_t type, uint8_t gran, uint8_t bits); 65 66 /* tss stuff */ 67 void x86_initialize_percpu_tss(void); 68 69 void x86_set_tss_sp(vaddr_t sp); 70 void x86_clear_tss_busy(seg_sel_t sel); 71 gdt_load(uintptr_t base)72static inline void gdt_load(uintptr_t base) { 73 struct gdtr { 74 uint16_t limit; 75 uintptr_t address; 76 } __PACKED; 77 // During VM exit GDTR limit is always set to 0xffff and instead of 78 // trying to maintain the limit aligned with the actual GDT size we 79 // decided to just keep it 0xffff all the time and instead of relying 80 // on the limit just map GDT in the way that accesses beyond GDT cause 81 // page faults. This allows us to avoid calling LGDT on every VM exit. 82 struct gdtr gdtr = { .limit = 0xffff, .address = base }; 83 x86_lgdt((uintptr_t)&gdtr); 84 } 85 86 void gdt_setup(void); 87 uintptr_t gdt_get(void); 88 89 __END_CDECLS 90 91 #endif 92