xref: /netbsd-src/sys/arch/i386/include/frameasm.h (revision 376bcb54d12937980e62a3bbac6e2c4fd894095e)
1*376bcb54Sriastradh /*	$NetBSD: frameasm.h,v 1.35 2022/07/30 14:11:00 riastradh Exp $	*/
265d13326Sfvdl 
365d13326Sfvdl #ifndef _I386_FRAMEASM_H_
465d13326Sfvdl #define _I386_FRAMEASM_H_
565d13326Sfvdl 
665d13326Sfvdl #ifdef _KERNEL_OPT
765d13326Sfvdl #include "opt_multiprocessor.h"
826315d04Sbouyer #include "opt_xen.h"
926315d04Sbouyer #endif
1026315d04Sbouyer 
111e3d30b0Scherry 
121e3d30b0Scherry #ifdef XEN
1326315d04Sbouyer /* XXX assym.h */
1426315d04Sbouyer #define TRAP_INSTR	int	$0x82
1526315d04Sbouyer #define XEN_BLOCK_EVENTS(reg)	movb	$1,EVTCHN_UPCALL_MASK(reg)
1626315d04Sbouyer #define XEN_UNBLOCK_EVENTS(reg)	movb	$0,EVTCHN_UPCALL_MASK(reg)
1726315d04Sbouyer #define XEN_TEST_PENDING(reg)	testb	$0xFF,EVTCHN_UPCALL_PENDING(reg)
181e3d30b0Scherry #endif /* XEN */
1926315d04Sbouyer 
201e3d30b0Scherry #if defined(XENPV)
2120161b72Scegger #define CLI(reg)	movl	CPUVAR(VCPU),reg ;  \
2226315d04Sbouyer 			XEN_BLOCK_EVENTS(reg)
2320161b72Scegger #define STI(reg)	movl	CPUVAR(VCPU),reg ;  \
2426315d04Sbouyer 			XEN_UNBLOCK_EVENTS(reg)
2520161b72Scegger #define STIC(reg)	movl	CPUVAR(VCPU),reg ;  \
2626315d04Sbouyer 			XEN_UNBLOCK_EVENTS(reg)  ; \
2726315d04Sbouyer 			testb	$0xff,EVTCHN_UPCALL_PENDING(reg)
28c24c993fSbouyer #define PUSHF(reg) 	movl	CPUVAR(VCPU),reg ;  \
29c24c993fSbouyer 			movzbl	EVTCHN_UPCALL_MASK(reg), reg; \
30c24c993fSbouyer 			pushl	reg
31c24c993fSbouyer #define POPF(reg)	call _C_LABEL(xen_write_psl); \
32c24c993fSbouyer 			addl    $4,%esp
331e3d30b0Scherry #else
341e3d30b0Scherry #define CLI(reg)	cli
351e3d30b0Scherry #define STI(reg)	sti
36c24c993fSbouyer #define PUSHF(reg)	pushf
37c24c993fSbouyer #define POPF(reg)	popf
381e3d30b0Scherry #ifdef XENPVHVM
391e3d30b0Scherry #define STIC(reg)	sti ; \
401e3d30b0Scherry 			movl	CPUVAR(VCPU),reg ; \
411e3d30b0Scherry 			XEN_UNBLOCK_EVENTS(reg)  ; \
421e3d30b0Scherry 			testb	$0xff,EVTCHN_UPCALL_PENDING(reg)
431e3d30b0Scherry #endif /* XENPVHVM */
441e3d30b0Scherry 
451e3d30b0Scherry #endif /* XENPV */
4665d13326Sfvdl 
479ef803feSmaxv #define HP_NAME_CLAC		1
489ef803feSmaxv #define HP_NAME_STAC		2
499ef803feSmaxv #define HP_NAME_NOLOCK		3
506fcf3f0aSmaxv #define HP_NAME_RETFENCE	4
51*376bcb54Sriastradh #define HP_NAME_CAS_64		5
52*376bcb54Sriastradh #define HP_NAME_SPLLOWER	6
53*376bcb54Sriastradh #define HP_NAME_MUTEX_EXIT	7
549ef803feSmaxv 
5599d8611cSmaxv #define HOTPATCH(name, size) \
5699d8611cSmaxv 123:						; \
57541cbcfaSmaxv 	.pushsection	.rodata.hotpatch, "a"	; \
5899d8611cSmaxv 	.byte		name			; \
5999d8611cSmaxv 	.byte		size			; \
6099d8611cSmaxv 	.long		123b			; \
61541cbcfaSmaxv 	.popsection
6299d8611cSmaxv 
63655db1e2Smaxv #define SMAP_ENABLE \
64655db1e2Smaxv 	HOTPATCH(HP_NAME_CLAC, 3)		; \
65d7e7c07fSmaxv 	.byte 0x90, 0x90, 0x90
66655db1e2Smaxv 
67655db1e2Smaxv #define SMAP_DISABLE \
68655db1e2Smaxv 	HOTPATCH(HP_NAME_STAC, 3)		; \
69d7e7c07fSmaxv 	.byte 0x90, 0x90, 0x90
70655db1e2Smaxv 
7165d13326Sfvdl /*
7265d13326Sfvdl  * These are used on interrupt or trap entry or exit.
7365d13326Sfvdl  */
7465d13326Sfvdl #define	INTRENTRY \
75655db1e2Smaxv 	SMAP_ENABLE			; \
7665d13326Sfvdl 	subl	$TF_PUSHSIZE,%esp	; \
775aa0bc76Sgmcgarry 	movw	%gs,TF_GS(%esp)		; \
785aa0bc76Sgmcgarry 	movw	%fs,TF_FS(%esp) 	; \
79d1486d51Sjunyoung 	movl	%eax,TF_EAX(%esp)	; \
805aa0bc76Sgmcgarry 	movw	%es,TF_ES(%esp) 	; \
815aa0bc76Sgmcgarry 	movw	%ds,TF_DS(%esp) 	; \
82d1486d51Sjunyoung 	movl	$GSEL(GDATA_SEL, SEL_KPL),%eax	; \
8365d13326Sfvdl 	movl	%edi,TF_EDI(%esp)	; \
8465d13326Sfvdl 	movl	%esi,TF_ESI(%esp)	; \
855aa0bc76Sgmcgarry 	movw	%ax,%ds			; \
8665d13326Sfvdl 	movl	%ebp,TF_EBP(%esp)	; \
875aa0bc76Sgmcgarry 	movw	%ax,%es			; \
8865d13326Sfvdl 	movl	%ebx,TF_EBX(%esp)	; \
895aa0bc76Sgmcgarry 	movw	%ax,%gs			; \
9065d13326Sfvdl 	movl	%edx,TF_EDX(%esp)	; \
91d1486d51Sjunyoung 	movl	$GSEL(GCPU_SEL, SEL_KPL),%eax	; \
9265d13326Sfvdl 	movl	%ecx,TF_ECX(%esp)	; \
93d1486d51Sjunyoung 	movl	%eax,%fs		; \
94157166fcSmaxv 	cld
9565d13326Sfvdl 
9665d13326Sfvdl #define	INTRFASTEXIT \
97d283fae6Smaxv 	jmp	intrfastexit
9865d13326Sfvdl 
99356342daSmaxv #define INTR_RECURSE_HWFRAME \
100356342daSmaxv 	pushfl				; \
101356342daSmaxv 	pushl	%cs			; \
102356342daSmaxv 	pushl	%esi			;
103356342daSmaxv 
10424a1632cSyamt #define	CHECK_DEFERRED_SWITCH \
105d749a2d0Syamt 	cmpl	$0, CPUVAR(WANT_PMAPLOAD)
106d749a2d0Syamt 
107a50e3bc1Sthorpej #define	CHECK_ASTPENDING(reg)	movl	CPUVAR(CURLWP),reg	; \
1086c336cd7Syamt 				cmpl	$0, L_MD_ASTPENDING(reg)
109b07ec3fcSad #define	CLEAR_ASTPENDING(reg)	movl	$0, L_MD_ASTPENDING(reg)
11065d13326Sfvdl 
11198cfc473Syamt /*
112560337f7Smaxv  * If the FPU state is not in the CPU, restore it. Executed with interrupts
113560337f7Smaxv  * disabled.
114560337f7Smaxv  *
115560337f7Smaxv  *     %ebx must not be modified
116560337f7Smaxv  */
117560337f7Smaxv #define HANDLE_DEFERRED_FPU	\
118560337f7Smaxv 	movl	CPUVAR(CURLWP),%eax			; \
119560337f7Smaxv 	testl	$MDL_FPU_IN_CPU,L_MD_FLAGS(%eax)	; \
120560337f7Smaxv 	jnz	1f					; \
121560337f7Smaxv 	pushl	%eax					; \
122560337f7Smaxv 	call	_C_LABEL(fpu_handle_deferred)		; \
123560337f7Smaxv 	popl	%eax					; \
124560337f7Smaxv 	orl	$MDL_FPU_IN_CPU,L_MD_FLAGS(%eax)	; \
125560337f7Smaxv 1:
126560337f7Smaxv 
127560337f7Smaxv /*
12898cfc473Syamt  * IDEPTH_INCR:
12998cfc473Syamt  * increase ci_idepth and switch to the interrupt stack if necessary.
13098cfc473Syamt  * note that the initial value of ci_idepth is -1.
13198cfc473Syamt  *
13298cfc473Syamt  * => should be called with interrupt disabled.
13398cfc473Syamt  * => save the old value of %esp in %eax.
13498cfc473Syamt  */
13598cfc473Syamt 
13698cfc473Syamt #define	IDEPTH_INCR \
13798cfc473Syamt 	incl	CPUVAR(IDEPTH); \
13898cfc473Syamt 	movl	%esp, %eax; \
13998cfc473Syamt 	jne	999f; \
14098cfc473Syamt 	movl	CPUVAR(INTRSTACK), %esp; \
141c81b3a79Syamt 999:	pushl	%eax; /* eax == pointer to intrframe */ \
14298cfc473Syamt 
14398cfc473Syamt /*
14498cfc473Syamt  * IDEPTH_DECR:
14598cfc473Syamt  * decrement ci_idepth and switch back to
14698cfc473Syamt  * the original stack saved by IDEPTH_INCR.
14798cfc473Syamt  *
14898cfc473Syamt  * => should be called with interrupt disabled.
14998cfc473Syamt  */
15098cfc473Syamt 
15198cfc473Syamt #define	IDEPTH_DECR \
15298cfc473Syamt 	popl	%esp; \
15398cfc473Syamt 	decl	CPUVAR(IDEPTH)
15498cfc473Syamt 
15565d13326Sfvdl #endif /* _I386_FRAMEASM_H_ */
156