1 /* 2 * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7 */ 8 #ifndef _KERNEL_ARCH_x86_CPU_H 9 #define _KERNEL_ARCH_x86_CPU_H 10 11 12 #include <module.h> 13 #include <arch/x86/descriptors.h> 14 15 16 // MSR registers (possibly Intel specific) 17 #define IA32_MSR_APIC_BASE 0x1b 18 19 #define IA32_MSR_MTRR_CAPABILITIES 0xfe 20 #define IA32_MSR_MTRR_DEFAULT_TYPE 0x2ff 21 #define IA32_MSR_MTRR_PHYSICAL_BASE_0 0x200 22 #define IA32_MSR_MTRR_PHYSICAL_MASK_0 0x201 23 24 // cpuid eax 1 features 25 #define IA32_FEATURE_MSR (1UL << 5) 26 #define IA32_FEATURE_MTRR (1UL << 12) 27 #define IA32_FEATURE_GLOBAL_PAGES (1UL << 13) 28 #define IA32_FEATURE_SSE (1UL << 25) 29 #define IA32_FEATURE_FXSR (1UL << 24) 30 31 // cr4 flags 32 #define IA32_CR4_GLOBAL_PAGES (1UL << 7) 33 34 // Memory type ranges 35 #define IA32_MTR_UNCACHED 0 36 #define IA32_MTR_WRITE_COMBINING 1 37 #define IA32_MTR_WRITE_THROUGH 4 38 #define IA32_MTR_WRITE_PROTECTED 5 39 #define IA32_MTR_WRITE_BACK 6 40 41 typedef struct x86_cpu_module_info { 42 module_info info; 43 uint32 (*count_mtrrs)(void); 44 void (*init_mtrrs)(void); 45 46 void (*set_mtrr)(uint32 index, uint64 base, uint64 length, uint8 type); 47 status_t (*get_mtrr)(uint32 index, uint64 *_base, uint64 *_length, 48 uint8 *_type); 49 } x86_cpu_module_info; 50 51 52 struct tss { 53 uint16 prev_task; 54 uint16 unused0; 55 uint32 sp0; 56 uint32 ss0; 57 uint32 sp1; 58 uint32 ss1; 59 uint32 sp2; 60 uint32 ss2; 61 uint32 cr3; 62 uint32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi; 63 uint32 es, cs, ss, ds, fs, gs; 64 uint32 ldt_seg_selector; 65 uint16 unused1; 66 uint16 io_map_base; 67 }; 68 69 struct iframe { 70 uint32 gs; 71 uint32 fs; 72 uint32 es; 73 uint32 ds; 74 uint32 edi; 75 uint32 esi; 76 uint32 ebp; 77 uint32 esp; 78 uint32 ebx; 79 uint32 edx; 80 uint32 ecx; 81 uint32 eax; 82 uint32 orig_eax; 83 uint32 orig_edx; 84 uint32 vector; 85 uint32 error_code; 86 uint32 eip; 87 uint32 cs; 88 uint32 flags; 89 uint32 user_esp; 90 uint32 user_ss; 91 }; 92 93 94 #ifdef __cplusplus 95 extern "C" { 96 #endif 97 98 #define nop() __asm__ ("nop"::) 99 100 struct arch_thread; 101 102 void __x86_setup_system_time(uint32 cv_factor); 103 void i386_context_switch(struct arch_thread *old_state, struct arch_thread *new_state, addr_t new_pgdir); 104 void x86_userspace_thread_exit(void); 105 void x86_end_userspace_thread_exit(void); 106 void x86_enter_userspace(addr_t entry, addr_t stackTop); 107 void i386_set_tss_and_kstack(addr_t kstack); 108 void i386_switch_stack_and_call(addr_t stack, void (*func)(void *), void *arg); 109 void i386_swap_pgdir(addr_t new_pgdir); 110 void i386_fnsave(void *fpu_state); 111 void i386_fxsave(void *fpu_state); 112 void i386_frstor(const void *fpu_state); 113 void i386_fxrstor(const void *fpu_state); 114 void i386_fnsave_swap(void *old_fpu_state, const void *new_fpu_state); 115 void i386_fxsave_swap(void *old_fpu_state, const void *new_fpu_state); 116 uint32 x86_read_ebp(); 117 uint32 x86_read_cr0(); 118 void x86_write_cr0(uint32 value); 119 uint32 x86_read_cr4(); 120 void x86_write_cr4(uint32 value); 121 uint64 x86_read_msr(uint32 registerNumber); 122 void x86_write_msr(uint32 registerNumber, uint64 value); 123 void x86_set_task_gate(int32 n, int32 segment); 124 uint32 x86_count_mtrrs(void); 125 void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type); 126 status_t x86_get_mtrr(uint32 index, uint64 *_base, uint64 *_length, uint8 *_type); 127 struct tss *x86_get_main_tss(void); 128 129 #define read_cr3(value) \ 130 __asm__("movl %%cr3,%0" : "=r" (value)) 131 132 #define write_cr3(value) \ 133 __asm__("movl %0,%%cr3" : : "r" (value)) 134 135 #define read_dr3(value) \ 136 __asm__("movl %%dr3,%0" : "=r" (value)) 137 138 #define write_dr3(value) \ 139 __asm__("movl %0,%%dr3" : : "r" (value)) 140 141 #define invalidate_TLB(va) \ 142 __asm__("invlpg (%0)" : : "r" (va)) 143 144 #define wbinvd() \ 145 __asm__("wbinvd") 146 147 #define out8(value,port) \ 148 __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port)) 149 150 #define out16(value,port) \ 151 __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port)) 152 153 #define out32(value,port) \ 154 __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port)) 155 156 #define in8(port) ({ \ 157 uint8 _v; \ 158 __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \ 159 _v; \ 160 }) 161 162 #define in16(port) ({ \ 163 uint16 _v; \ 164 __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \ 165 _v; \ 166 }) 167 168 #define in32(port) ({ \ 169 uint32 _v; \ 170 __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \ 171 _v; \ 172 }) 173 174 #define out8_p(value,port) \ 175 __asm__ ("outb %%al,%%dx\n" \ 176 "\tjmp 1f\n" \ 177 "1:\tjmp 1f\n" \ 178 "1:" : : "a" (value), "d" (port)) 179 180 #define in8_p(port) ({ \ 181 uint8 _v; \ 182 __asm__ volatile ("inb %%dx,%%al\n" \ 183 "\tjmp 1f\n" \ 184 "1:\tjmp 1f\n" \ 185 "1:" : "=a" (_v) : "d" (port)); \ 186 _v; \ 187 }) 188 189 extern segment_descriptor *gGDT; 190 191 192 #ifdef __cplusplus 193 } // extern "C" { 194 #endif 195 196 197 #endif /* _KERNEL_ARCH_x86_CPU_H */ 198