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