1 /* $NetBSD: frameasm.h,v 1.18 2017/09/17 09:59:23 maxv Exp $ */ 2 3 #ifndef _I386_FRAMEASM_H_ 4 #define _I386_FRAMEASM_H_ 5 6 #ifdef _KERNEL_OPT 7 #include "opt_multiprocessor.h" 8 #include "opt_xen.h" 9 #endif 10 11 #if !defined(XEN) 12 #define CLI(reg) cli 13 #define STI(reg) sti 14 #else 15 /* XXX assym.h */ 16 #define TRAP_INSTR int $0x82 17 #define XEN_BLOCK_EVENTS(reg) movb $1,EVTCHN_UPCALL_MASK(reg) 18 #define XEN_UNBLOCK_EVENTS(reg) movb $0,EVTCHN_UPCALL_MASK(reg) 19 #define XEN_TEST_PENDING(reg) testb $0xFF,EVTCHN_UPCALL_PENDING(reg) 20 21 #define CLI(reg) movl CPUVAR(VCPU),reg ; \ 22 XEN_BLOCK_EVENTS(reg) 23 #define STI(reg) movl CPUVAR(VCPU),reg ; \ 24 XEN_UNBLOCK_EVENTS(reg) 25 #define STIC(reg) movl CPUVAR(VCPU),reg ; \ 26 XEN_UNBLOCK_EVENTS(reg) ; \ 27 testb $0xff,EVTCHN_UPCALL_PENDING(reg) 28 #endif 29 30 /* 31 * These are used on interrupt or trap entry or exit. 32 */ 33 #define INTRENTRY \ 34 subl $TF_PUSHSIZE,%esp ; \ 35 movw %gs,TF_GS(%esp) ; \ 36 movw %fs,TF_FS(%esp) ; \ 37 movl %eax,TF_EAX(%esp) ; \ 38 movw %es,TF_ES(%esp) ; \ 39 movw %ds,TF_DS(%esp) ; \ 40 movl $GSEL(GDATA_SEL, SEL_KPL),%eax ; \ 41 movl %edi,TF_EDI(%esp) ; \ 42 movl %esi,TF_ESI(%esp) ; \ 43 movw %ax,%ds ; \ 44 movl %ebp,TF_EBP(%esp) ; \ 45 movw %ax,%es ; \ 46 movl %ebx,TF_EBX(%esp) ; \ 47 movw %ax,%gs ; \ 48 movl %edx,TF_EDX(%esp) ; \ 49 movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \ 50 movl %ecx,TF_ECX(%esp) ; \ 51 movl %eax,%fs ; \ 52 cld 53 54 #define INTRFASTEXIT \ 55 jmp intrfastexit 56 57 #define DO_DEFERRED_SWITCH \ 58 cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \ 59 jz 1f ; \ 60 call _C_LABEL(pmap_load) ; \ 61 1: 62 63 #define DO_DEFERRED_SWITCH_RETRY \ 64 1: ; \ 65 cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \ 66 jz 1f ; \ 67 call _C_LABEL(pmap_load) ; \ 68 jmp 1b ; \ 69 1: 70 71 #define CHECK_DEFERRED_SWITCH \ 72 cmpl $0, CPUVAR(WANT_PMAPLOAD) 73 74 #define CHECK_ASTPENDING(reg) movl CPUVAR(CURLWP),reg ; \ 75 cmpl $0, L_MD_ASTPENDING(reg) 76 #define CLEAR_ASTPENDING(reg) movl $0, L_MD_ASTPENDING(reg) 77 78 /* 79 * IDEPTH_INCR: 80 * increase ci_idepth and switch to the interrupt stack if necessary. 81 * note that the initial value of ci_idepth is -1. 82 * 83 * => should be called with interrupt disabled. 84 * => save the old value of %esp in %eax. 85 */ 86 87 #define IDEPTH_INCR \ 88 incl CPUVAR(IDEPTH); \ 89 movl %esp, %eax; \ 90 jne 999f; \ 91 movl CPUVAR(INTRSTACK), %esp; \ 92 999: pushl %eax; /* eax == pointer to intrframe */ \ 93 94 /* 95 * IDEPTH_DECR: 96 * decrement ci_idepth and switch back to 97 * the original stack saved by IDEPTH_INCR. 98 * 99 * => should be called with interrupt disabled. 100 */ 101 102 #define IDEPTH_DECR \ 103 popl %esp; \ 104 decl CPUVAR(IDEPTH) 105 106 #endif /* _I386_FRAMEASM_H_ */ 107