1 /* 2 * Copyright 2002-2005, 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 <SupportDefs.h> 13 #include <arch/x86/descriptors.h> 14 15 16 // MSR registers (possibly Intel specific) 17 #define IA32_MSR_APIC_BASE 0x1b 18 19 struct tss { 20 uint16 prev_task; 21 uint16 unused0; 22 uint32 sp0; 23 uint32 ss0; 24 uint32 sp1; 25 uint32 ss1; 26 uint32 sp2; 27 uint32 ss2; 28 uint32 cr3; 29 uint32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi; 30 uint32 es, cs, ss, ds, fs, gs; 31 uint32 ldt_seg_selector; 32 uint16 unused1; 33 uint16 io_map_base; 34 }; 35 36 struct iframe { 37 uint32 gs; 38 uint32 fs; 39 uint32 es; 40 uint32 ds; 41 uint32 edi; 42 uint32 esi; 43 uint32 ebp; 44 uint32 esp; 45 uint32 ebx; 46 uint32 edx; 47 uint32 ecx; 48 uint32 eax; 49 uint32 orig_eax; 50 uint32 orig_edx; 51 uint32 vector; 52 uint32 error_code; 53 uint32 eip; 54 uint32 cs; 55 uint32 flags; 56 uint32 user_esp; 57 uint32 user_ss; 58 }; 59 60 61 #ifdef __cplusplus 62 extern "C" { 63 #endif 64 65 #define nop() __asm__ ("nop"::) 66 67 struct arch_thread; 68 69 void setup_system_time(uint32 cv_factor); 70 void i386_context_switch(struct arch_thread *old_state, struct arch_thread *new_state, addr_t new_pgdir); 71 void i386_enter_uspace(addr_t entry, void *args1, void *args2, addr_t ustack_top); 72 void i386_set_tss_and_kstack(addr_t kstack); 73 void i386_switch_stack_and_call(addr_t stack, void (*func)(void *), void *arg); 74 void i386_swap_pgdir(addr_t new_pgdir); 75 void i386_fsave(void *fpu_state); 76 void i386_fxsave(void *fpu_state); 77 void i386_frstor(const void *fpu_state); 78 void i386_fxrstor(const void *fpu_state); 79 void i386_fsave_swap(void *old_fpu_state, const void *new_fpu_state); 80 void i386_fxsave_swap(void *old_fpu_state, const void *new_fpu_state); 81 uint64 x86_read_msr(uint32 register); 82 void x86_write_msr(uint32 register, uint64 value); 83 void x86_set_task_gate(int32 n, int32 segment); 84 struct tss *x86_get_main_tss(void); 85 86 #define read_ebp(value) \ 87 __asm__("movl %%ebp,%0" : "=r" (value)) 88 89 #define read_cr3(value) \ 90 __asm__("movl %%cr3,%0" : "=r" (value)) 91 92 #define write_cr3(value) \ 93 __asm__("movl %0,%%cr3" : : "r" (value)) 94 95 #define read_dr3(value) \ 96 __asm__("movl %%dr3,%0" : "=r" (value)) 97 98 #define write_dr3(value) \ 99 __asm__("movl %0,%%dr3" : : "r" (value)) 100 101 #define invalidate_TLB(va) \ 102 __asm__("invlpg (%0)" : : "r" (va)) 103 104 #define out8(value,port) \ 105 __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port)) 106 107 #define out16(value,port) \ 108 __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port)) 109 110 #define out32(value,port) \ 111 __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port)) 112 113 #define in8(port) ({ \ 114 uint8 _v; \ 115 __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \ 116 _v; \ 117 }) 118 119 #define in16(port) ({ \ 120 uint16 _v; \ 121 __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \ 122 _v; \ 123 }) 124 125 #define in32(port) ({ \ 126 uint32 _v; \ 127 __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \ 128 _v; \ 129 }) 130 131 #define out8_p(value,port) \ 132 __asm__ ("outb %%al,%%dx\n" \ 133 "\tjmp 1f\n" \ 134 "1:\tjmp 1f\n" \ 135 "1:" : : "a" (value), "d" (port)) 136 137 #define in8_p(port) ({ \ 138 uint8 _v; \ 139 __asm__ volatile ("inb %%dx,%%al\n" \ 140 "\tjmp 1f\n" \ 141 "1:\tjmp 1f\n" \ 142 "1:" : "=a" (_v) : "d" (port)); \ 143 _v; \ 144 }) 145 146 extern segment_descriptor *gGDT; 147 148 149 #ifdef __cplusplus 150 } // extern "C" { 151 #endif 152 153 154 #endif /* _KERNEL_ARCH_x86_CPU_H */ 155