1 /* 2 ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 3 ** Distributed under the terms of the NewOS License. 4 */ 5 #ifndef _KERNEL_ARCH_x86_CPU_H 6 #define _KERNEL_ARCH_x86_CPU_H 7 8 #include <ktypes.h> 9 #include <arch/x86/thread_struct.h> 10 #include <arch/x86/descriptors.h> 11 12 #define PAGE_SIZE 4096 13 14 #define _BIG_ENDIAN 0 15 #define _LITTLE_ENDIAN 1 16 17 struct tss { 18 uint16 prev_task; 19 uint16 unused0; 20 uint32 sp0; 21 uint32 ss0; 22 uint32 sp1; 23 uint32 ss1; 24 uint32 sp2; 25 uint32 ss2; 26 uint32 sp3; 27 uint32 ss3; 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 /**************************************************************************/ 37 38 typedef struct ptentry { // page table entry 39 unsigned int present:1; 40 unsigned int rw:1; 41 unsigned int user:1; 42 unsigned int write_through:1; 43 unsigned int cache_disabled:1; 44 unsigned int accessed:1; 45 unsigned int dirty:1; 46 unsigned int reserved:1; 47 unsigned int global:1; 48 unsigned int avail:3; 49 unsigned int addr:20; 50 } ptentry; 51 52 typedef struct pdentry { // page directory entry 53 unsigned int present:1; 54 unsigned int rw:1; 55 unsigned int user:1; 56 unsigned int write_through:1; 57 unsigned int cache_disabled:1; 58 unsigned int accessed:1; 59 unsigned int reserved:1; 60 unsigned int page_size:1; 61 unsigned int global:1; 62 unsigned int avail:3; 63 unsigned int addr:20; 64 } pdentry; 65 66 struct iframe { 67 unsigned int gs; 68 unsigned int fs; 69 unsigned int es; 70 unsigned int ds; 71 unsigned int edi; 72 unsigned int esi; 73 unsigned int ebp; 74 unsigned int esp; 75 unsigned int ebx; 76 unsigned int edx; 77 unsigned int ecx; 78 unsigned int eax; 79 unsigned int orig_eax; 80 unsigned int orig_edx; 81 unsigned int vector; 82 unsigned int error_code; 83 unsigned int eip; 84 unsigned int cs; 85 unsigned int flags; 86 unsigned int user_esp; 87 unsigned int user_ss; 88 }; 89 90 #define nop() __asm__ ("nop"::) 91 92 void setup_system_time(unsigned int cv_factor); 93 void i386_context_switch(struct arch_thread *old_state, struct arch_thread *new_state, addr new_pgdir); 94 void i386_enter_uspace(addr entry, void *args1, void *args2, addr ustack_top); 95 void i386_set_tss_and_kstack(addr kstack); 96 void i386_switch_stack_and_call(addr stack, void (*func)(void *), void *arg); 97 void i386_swap_pgdir(addr new_pgdir); 98 void i386_fsave(void *fpu_state); 99 void i386_fxsave(void *fpu_state); 100 void i386_frstor(void *fpu_state); 101 void i386_fxrstor(void *fpu_state); 102 void i386_fsave_swap(void *old_fpu_state, void *new_fpu_state); 103 void i386_fxsave_swap(void *old_fpu_state, void *new_fpu_state); 104 105 #define read_ebp(value) \ 106 __asm__("movl %%ebp,%0" : "=r" (value)) 107 108 #define read_dr3(value) \ 109 __asm__("movl %%dr3,%0" : "=r" (value)) 110 111 #define write_dr3(value) \ 112 __asm__("movl %0,%%dr3" : : "r" (value)) 113 114 #define invalidate_TLB(va) \ 115 __asm__("invlpg (%0)" : : "r" (va)) 116 117 #define out8(value,port) \ 118 __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port)) 119 120 #define out16(value,port) \ 121 __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port)) 122 123 #define out32(value,port) \ 124 __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port)) 125 126 #define in8(port) ({ \ 127 unsigned char _v; \ 128 __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \ 129 _v; \ 130 }) 131 132 #define in16(port) ({ \ 133 unsigned short _v; \ 134 __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \ 135 _v; \ 136 }) 137 138 #define in32(port) ({ \ 139 unsigned int _v; \ 140 __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \ 141 _v; \ 142 }) 143 144 #define out8_p(value,port) \ 145 __asm__ ("outb %%al,%%dx\n" \ 146 "\tjmp 1f\n" \ 147 "1:\tjmp 1f\n" \ 148 "1:" : : "a" (value), "d" (port)) 149 150 #define in8_p(port) ({ \ 151 unsigned char _v; \ 152 __asm__ volatile ("inb %%dx,%%al\n" \ 153 "\tjmp 1f\n" \ 154 "1:\tjmp 1f\n" \ 155 "1:" : "=a" (_v) : "d" (port)); \ 156 _v; \ 157 }) 158 159 extern segment_descriptor *gGDT; 160 161 #endif /* _KERNEL_ARCH_x86_CPU_H */ 162