1 2 #ifndef _I386_PROTO_H 3 #define _I386_PROTO_H 4 5 #include <machine/vm.h> 6 7 #define K_STACK_SIZE I386_PAGE_SIZE 8 9 #ifndef __ASSEMBLY__ 10 11 /* Hardware interrupt handlers. */ 12 void hwint00(void); 13 void hwint01(void); 14 void hwint02(void); 15 void hwint03(void); 16 void hwint04(void); 17 void hwint05(void); 18 void hwint06(void); 19 void hwint07(void); 20 void hwint08(void); 21 void hwint09(void); 22 void hwint10(void); 23 void hwint11(void); 24 void hwint12(void); 25 void hwint13(void); 26 void hwint14(void); 27 void hwint15(void); 28 29 /* Exception handlers (real or protected mode), in numerical order. */ 30 void int00(void), divide_error (void); 31 void int01(void), single_step_exception (void); 32 void int02(void), nmi (void); 33 void int03(void), breakpoint_exception (void); 34 void int04(void), overflow (void); 35 void int05(void), bounds_check (void); 36 void int06(void), inval_opcode (void); 37 void int07(void), copr_not_available (void); 38 void double_fault(void); 39 void copr_seg_overrun(void); 40 void inval_tss(void); 41 void segment_not_present(void); 42 void stack_exception(void); 43 void general_protection(void); 44 void page_fault(void); 45 void copr_error(void); 46 void alignment_check(void); 47 void machine_check(void); 48 void simd_exception(void); 49 50 void restore_user_context_int(struct proc *); 51 void restore_user_context_sysenter(struct proc *); 52 void restore_user_context_syscall(struct proc *); 53 54 /* Software interrupt handlers, in numerical order. */ 55 void trp(void); 56 void ipc_entry_softint_orig(void); 57 void ipc_entry_softint_um(void); 58 void ipc_entry_sysenter(void); 59 void ipc_entry_syscall_cpu0(void); 60 void ipc_entry_syscall_cpu1(void); 61 void ipc_entry_syscall_cpu2(void); 62 void ipc_entry_syscall_cpu3(void); 63 void ipc_entry_syscall_cpu4(void); 64 void ipc_entry_syscall_cpu5(void); 65 void ipc_entry_syscall_cpu6(void); 66 void ipc_entry_syscall_cpu7(void); 67 void kernel_call_entry_orig(void); 68 void kernel_call_entry_um(void); 69 void level0_call(void); 70 71 /* exception.c */ 72 struct exception_frame { 73 reg_t vector; /* which interrupt vector was triggered */ 74 reg_t errcode; /* zero if no exception does not push err code */ 75 reg_t eip; 76 reg_t cs; 77 reg_t eflags; 78 reg_t esp; /* undefined if trap is nested */ 79 reg_t ss; /* undefined if trap is nested */ 80 }; 81 82 void exception(struct exception_frame * frame); 83 84 /* klib.S */ 85 __dead void monitor(void); 86 __dead void reset(void); 87 __dead void poweroff_vmware_clihlt(void); 88 __dead void x86_triplefault(void); 89 reg_t read_cr0(void); 90 reg_t read_cr2(void); 91 void write_cr0(unsigned long value); 92 unsigned long read_cr4(void); 93 void write_cr4(unsigned long value); 94 void write_cr3(unsigned long value); 95 unsigned long read_cpu_flags(void); 96 phys_bytes vir2phys(void *); 97 void phys_insb(u16_t port, phys_bytes buf, size_t count); 98 void phys_insw(u16_t port, phys_bytes buf, size_t count); 99 void phys_outsb(u16_t port, phys_bytes buf, size_t count); 100 void phys_outsw(u16_t port, phys_bytes buf, size_t count); 101 u32_t read_cr3(void); 102 void reload_cr3(void); 103 void i386_invlpg(phys_bytes linaddr); 104 vir_bytes phys_memset(phys_bytes ph, u32_t c, phys_bytes bytes); 105 void reload_ds(void); 106 void ia32_msr_read(u32_t reg, u32_t * hi, u32_t * lo); 107 void ia32_msr_write(u32_t reg, u32_t hi, u32_t lo); 108 void fninit(void); 109 void clts(void); 110 void fxsave(void *); 111 void fnsave(void *); 112 int fxrstor(void *); 113 int __fxrstor_end(void *); 114 int frstor(void *); 115 int __frstor_end(void *); 116 int __frstor_failure(void *); 117 unsigned short fnstsw(void); 118 void fnstcw(unsigned short* cw); 119 void x86_lgdt(void *); 120 void x86_lldt(u32_t); 121 void x86_ltr(u32_t); 122 void x86_lidt(void *); 123 void x86_load_kerncs(void); 124 void x86_load_ds(u32_t); 125 void x86_load_ss(u32_t); 126 void x86_load_es(u32_t); 127 void x86_load_fs(u32_t); 128 void x86_load_gs(u32_t); 129 130 /* ipc functions in usermapped_ipc.S */ 131 int usermapped_send_softint(endpoint_t dest, message *m_ptr); 132 int usermapped_receive_softint(endpoint_t src, message *m_ptr, int *status_ptr); 133 int usermapped_sendrec_softint(endpoint_t src_dest, message *m_ptr); 134 int usermapped_sendnb_softint(endpoint_t dest, message *m_ptr); 135 int usermapped_notify_softint(endpoint_t dest); 136 int usermapped_do_kernel_call_softint(message *m_ptr); 137 int usermapped_senda_softint(asynmsg_t *table, size_t count); 138 139 int usermapped_send_syscall(endpoint_t dest, message *m_ptr); 140 int usermapped_receive_syscall(endpoint_t src, message *m_ptr, int *status_ptr); 141 int usermapped_sendrec_syscall(endpoint_t src_dest, message *m_ptr); 142 int usermapped_sendnb_syscall(endpoint_t dest, message *m_ptr); 143 int usermapped_notify_syscall(endpoint_t dest); 144 int usermapped_do_kernel_call_syscall(message *m_ptr); 145 int usermapped_senda_syscall(asynmsg_t *table, size_t count); 146 147 int usermapped_send_sysenter(endpoint_t dest, message *m_ptr); 148 int usermapped_receive_sysenter(endpoint_t src, message *m_ptr, int *status_ptr); 149 int usermapped_sendrec_sysenter(endpoint_t src_dest, message *m_ptr); 150 int usermapped_sendnb_sysenter(endpoint_t dest, message *m_ptr); 151 int usermapped_notify_sysenter(endpoint_t dest); 152 int usermapped_do_kernel_call_sysenter(message *m_ptr); 153 int usermapped_senda_sysenter(asynmsg_t *table, size_t count); 154 155 void switch_k_stack(void * esp, void (* continuation)(void)); 156 157 void __switch_address_space(struct proc * p, struct proc ** __ptproc); 158 #define switch_address_space(proc) \ 159 __switch_address_space(proc, get_cpulocal_var_ptr(ptproc)) 160 161 void refresh_tlb(void); 162 163 /* multiboot.c */ 164 void multiboot_init(void); 165 166 /* protect.c */ 167 struct tss_s { 168 reg_t backlink; 169 reg_t sp0; /* stack pointer to use during interrupt */ 170 reg_t ss0; /* " segment " " " " */ 171 reg_t sp1; 172 reg_t ss1; 173 reg_t sp2; 174 reg_t ss2; 175 reg_t cr3; 176 reg_t ip; 177 reg_t flags; 178 reg_t ax; 179 reg_t cx; 180 reg_t dx; 181 reg_t bx; 182 reg_t sp; 183 reg_t bp; 184 reg_t si; 185 reg_t di; 186 reg_t es; 187 reg_t cs; 188 reg_t ss; 189 reg_t ds; 190 reg_t fs; 191 reg_t gs; 192 reg_t ldt; 193 u16_t trap; 194 u16_t iobase; 195 /* u8_t iomap[0]; */ 196 } __attribute__((packed)); 197 198 void enable_iop(struct proc *pp); 199 u32_t read_cs(void); 200 u32_t read_ds(void); 201 u32_t read_ss(void); 202 203 void add_memmap(kinfo_t *cbi, u64_t addr, u64_t len); 204 phys_bytes alloc_lowest(kinfo_t *cbi, phys_bytes len); 205 void vm_enable_paging(void); 206 void cut_memmap(kinfo_t *cbi, phys_bytes start, phys_bytes end); 207 phys_bytes pg_roundup(phys_bytes b); 208 void pg_info(reg_t *, u32_t **); 209 void pg_clear(void); 210 void pg_identity(kinfo_t *); 211 phys_bytes pg_load(void); 212 void pg_map(phys_bytes phys, vir_bytes vaddr, vir_bytes vaddr_end, kinfo_t *cbi); 213 int pg_mapkernel(void); 214 void pg_mapproc(struct proc *p, struct boot_image *ip, kinfo_t *cbi); 215 216 /* prototype of an interrupt vector table entry */ 217 struct gate_table_s { 218 void(*gate) (void); 219 unsigned char vec_nr; 220 unsigned char privilege; 221 }; 222 223 /* copies an array of vectors to the IDT. The last vector must be zero filled */ 224 void idt_copy_vectors(struct gate_table_s * first); 225 void idt_copy_vectors_pic(void); 226 void idt_reload(void); 227 228 EXTERN void * k_stacks_start; 229 extern void * k_stacks; 230 231 #define get_k_stack_top(cpu) ((void *)(((char*)(k_stacks)) \ 232 + 2 * ((cpu) + 1) * K_STACK_SIZE)) 233 234 void mfence(void); 235 #define barrier() do { mfence(); } while(0) 236 237 238 #ifndef __GNUC__ 239 /* call a function to read the stack fram pointer (%ebp) */ 240 reg_t read_ebp(void); 241 #define get_stack_frame(__X) ((reg_t)read_ebp()) 242 #else 243 /* read %ebp directly */ 244 #define get_stack_frame(__X) ((reg_t)__builtin_frame_address(0)) 245 #endif 246 247 /* 248 * sets up TSS for a cpu and assigns kernel stack and cpu id 249 */ 250 int tss_init(unsigned cpu, void * kernel_stack); 251 252 void int_gate_idt(unsigned vec_nr, vir_bytes offset, unsigned dpl_type); 253 254 void __copy_msg_from_user_end(void); 255 void __copy_msg_to_user_end(void); 256 void __user_copy_msg_pointer_failure(void); 257 258 int platform_tbl_checksum_ok(void *ptr, unsigned int length); 259 int platform_tbl_ptr(phys_bytes start, phys_bytes end, unsigned 260 increment, void * buff, unsigned size, phys_bytes * phys_addr, int ((* 261 cmp_f)(void *))); 262 263 /* breakpoints.c */ 264 int breakpoint_set(phys_bytes linaddr, int bp, const int flags); 265 #define BREAKPOINT_COUNT 4 266 #define BREAKPOINT_FLAG_RW_MASK (3 << 0) 267 #define BREAKPOINT_FLAG_RW_EXEC (0 << 0) 268 #define BREAKPOINT_FLAG_RW_WRITE (1 << 0) 269 #define BREAKPOINT_FLAG_RW_RW (2 << 0) 270 #define BREAKPOINT_FLAG_LEN_MASK (3 << 2) 271 #define BREAKPOINT_FLAG_LEN_1 (0 << 2) 272 #define BREAKPOINT_FLAG_LEN_2 (1 << 2) 273 #define BREAKPOINT_FLAG_LEN_4 (2 << 2) 274 #define BREAKPOINT_FLAG_MODE_MASK (3 << 4) 275 #define BREAKPOINT_FLAG_MODE_OFF (0 << 4) 276 #define BREAKPOINT_FLAG_MODE_LOCAL (1 << 4) 277 #define BREAKPOINT_FLAG_MODE_GLOBAL (2 << 4) 278 279 /* functions defined in architecture-independent kernel source. */ 280 #include "kernel/proto.h" 281 282 #endif /* __ASSEMBLY__ */ 283 284 #endif 285