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