#include <machine/asmacros.h>
#include <machine/cputypes.h>
#include <machine/pmap.h>
#include <machine/specialreg.h>
#include "assym.inc"
#define IDXSHIFT 10
.text
ENTRY(sse2_pagezero)
pushl %ebx
movl 8(%esp),%ecx
movl %ecx,%eax
addl $4096,%eax
xor %ebx,%ebx
jmp 1f
.p2align 4,0x90
1:
movnti %ebx,(%ecx)
movnti %ebx,4(%ecx)
addl $8,%ecx
cmpl %ecx,%eax
jne 1b
sfence
popl %ebx
ret
END(sse2_pagezero)
ENTRY(i686_pagezero)
pushl %edi
pushl %ebx
movl 12(%esp),%edi
movl $1024,%ecx
ALIGN_TEXT
1:
xorl %eax,%eax
repe
scasl
jnz 2f
popl %ebx
popl %edi
ret
ALIGN_TEXT
2:
incl %ecx
subl $4,%edi
movl %ecx,%edx
cmpl $16,%ecx
jge 3f
movl %edi,%ebx
andl $0x3f,%ebx
shrl %ebx
shrl %ebx
movl $16,%ecx
subl %ebx,%ecx
3:
subl %ecx,%edx
rep
stosl
movl %edx,%ecx
testl %edx,%edx
jnz 1b
popl %ebx
popl %edi
ret
END(i686_pagezero)
ENTRY(fillw)
pushl %edi
movl 8(%esp),%eax
movl 12(%esp),%edi
movl 16(%esp),%ecx
rep
stosw
popl %edi
ret
END(fillw)
ENTRY(memmove)
pushl %ebp
movl %esp,%ebp
pushl %esi
pushl %edi
movl 8(%ebp),%edi
movl 12(%ebp),%esi
1:
movl 16(%ebp),%ecx
movl %edi,%eax
subl %esi,%eax
cmpl %ecx,%eax
jb 1f
shrl $2,%ecx
rep
movsl
movl 16(%ebp),%ecx
andl $3,%ecx
rep
movsb
popl %edi
popl %esi
movl 8(%ebp),%eax
popl %ebp
ret
ALIGN_TEXT
1:
addl %ecx,%edi
addl %ecx,%esi
decl %edi
decl %esi
andl $3,%ecx
std
rep
movsb
movl 16(%ebp),%ecx
shrl $2,%ecx
subl $3,%esi
subl $3,%edi
rep
movsl
popl %edi
popl %esi
cld
movl 8(%ebp),%eax
popl %ebp
ret
END(memmove)
ENTRY(memcpy)
pushl %edi
pushl %esi
movl 12(%esp),%edi
movl 16(%esp),%esi
movl 20(%esp),%ecx
movl %edi,%eax
shrl $2,%ecx
rep
movsl
movl 20(%esp),%ecx
andl $3,%ecx
rep
movsb
popl %esi
popl %edi
ret
END(memcpy)
ENTRY(lgdt)
movl 4(%esp),%eax
lgdt (%eax)
jmp 1f
nop
1:
movl $KDSEL,%eax
movl %eax,%ds
movl %eax,%es
movl %eax,%gs
movl %eax,%ss
movl $KPSEL,%eax
movl %eax,%fs
movl (%esp),%eax
pushl %eax
movl $KCSEL,4(%esp)
lret
END(lgdt)
ENTRY(ssdtosd)
pushl %ebx
movl 8(%esp),%ecx
movl 8(%ecx),%ebx
shll $16,%ebx
movl (%ecx),%edx
roll $16,%edx
movb %dh,%bl
movb %dl,%bh
rorl $8,%ebx
movl 4(%ecx),%eax
movw %ax,%dx
andl $0xf0000,%eax
orl %eax,%ebx
movl 12(%esp),%ecx
movl %edx,(%ecx)
movl %ebx,4(%ecx)
popl %ebx
ret
END(ssdtosd)
ENTRY(reset_dbregs)
movl $0,%eax
movl %eax,%dr7
movl %eax,%dr0
movl %eax,%dr1
movl %eax,%dr2
movl %eax,%dr3
movl %eax,%dr6
ret
END(reset_dbregs)
ENTRY(setjmp)
movl 4(%esp),%eax
movl %ebx,(%eax)
movl %esp,4(%eax)
movl %ebp,8(%eax)
movl %esi,12(%eax)
movl %edi,16(%eax)
movl (%esp),%edx
movl %edx,20(%eax)
xorl %eax,%eax
ret
END(setjmp)
ENTRY(longjmp)
movl 4(%esp),%eax
movl (%eax),%ebx
movl 4(%eax),%esp
movl 8(%eax),%ebp
movl 12(%eax),%esi
movl 16(%eax),%edi
movl 20(%eax),%edx
movl %edx,(%esp)
xorl %eax,%eax
incl %eax
ret
END(longjmp)
ENTRY(rdmsr_safe)
movl PCPU(CURPCB),%ecx
movl $msr_onfault,PCB_ONFAULT(%ecx)
movl 4(%esp),%ecx
rdmsr
movl 8(%esp),%ecx
movl %eax,(%ecx)
movl %edx,4(%ecx)
xorl %eax,%eax
movl PCPU(CURPCB),%ecx
movl %eax,PCB_ONFAULT(%ecx)
ret
ENTRY(wrmsr_safe)
movl PCPU(CURPCB),%ecx
movl $msr_onfault,PCB_ONFAULT(%ecx)
movl 4(%esp),%ecx
movl 8(%esp),%eax
movl 12(%esp),%edx
wrmsr
xorl %eax,%eax
movl PCPU(CURPCB),%ecx
movl %eax,PCB_ONFAULT(%ecx)
ret
ALIGN_TEXT
msr_onfault:
movl PCPU(CURPCB),%ecx
movl $0,PCB_ONFAULT(%ecx)
movl $EFAULT,%eax
ret
.altmacro
.macro rsb_seq_label l
rsb_seq_\l:
.endm
.macro rsb_call_label l
call rsb_seq_\l
.endm
.macro rsb_seq count
ll=1
.rept \count
rsb_call_label %(ll)
nop
rsb_seq_label %(ll)
addl $4,%esp
ll=ll+1
.endr
.endm
ENTRY(rsb_flush)
rsb_seq 32
ret
ENTRY(handle_ibrs_entry)
cmpb $0,hw_ibrs_ibpb_active
je 1f
movl $MSR_IA32_SPEC_CTRL,%ecx
rdmsr
orl $(IA32_SPEC_CTRL_IBRS|IA32_SPEC_CTRL_STIBP),%eax
orl $(IA32_SPEC_CTRL_IBRS|IA32_SPEC_CTRL_STIBP)>>32,%edx
wrmsr
movb $1,PCPU(IBPB_SET)
1: jmp rsb_flush
END(handle_ibrs_entry)
ENTRY(handle_ibrs_exit)
cmpb $0,PCPU(IBPB_SET)
je 1f
movl $MSR_IA32_SPEC_CTRL,%ecx
rdmsr
andl $~(IA32_SPEC_CTRL_IBRS|IA32_SPEC_CTRL_STIBP),%eax
andl $~((IA32_SPEC_CTRL_IBRS|IA32_SPEC_CTRL_STIBP)>>32),%edx
wrmsr
movb $0,PCPU(IBPB_SET)
1: ret
END(handle_ibrs_exit)
ENTRY(mds_handler_void)
ret
END(mds_handler_void)
ENTRY(mds_handler_verw)
subl $4, %esp
movw %ds, (%esp)
verw (%esp)
addl $4, %esp
ret
END(mds_handler_verw)
ENTRY(mds_handler_ivb)
movl %cr0, %eax
testb $CR0_TS, %al
je 1f
clts
1: movl PCPU(MDS_BUF), %edx
movdqa %xmm0, PCPU(MDS_TMP)
pxor %xmm0, %xmm0
lfence
orpd (%edx), %xmm0
orpd (%edx), %xmm0
mfence
movl $40, %ecx
addl $16, %edx
2: movntdq %xmm0, (%edx)
addl $16, %edx
decl %ecx
jnz 2b
mfence
movdqa PCPU(MDS_TMP),%xmm0
testb $CR0_TS, %al
je 3f
movl %eax, %cr0
3: ret
END(mds_handler_ivb)
ENTRY(mds_handler_bdw)
movl %cr0, %eax
testb $CR0_TS, %al
je 1f
clts
1: movl PCPU(MDS_BUF), %ebx
movdqa %xmm0, PCPU(MDS_TMP)
pxor %xmm0, %xmm0
movl %ebx, %edi
movl %ebx, %esi
movl $40, %ecx
2: movntdq %xmm0, (%ebx)
addl $16, %ebx
decl %ecx
jnz 2b
mfence
movl $1536, %ecx
rep; movsb
lfence
movdqa PCPU(MDS_TMP),%xmm0
testb $CR0_TS, %al
je 3f
movl %eax, %cr0
3: ret
END(mds_handler_bdw)
ENTRY(mds_handler_skl_sse)
movl %cr0, %eax
testb $CR0_TS, %al
je 1f
clts
1: movl PCPU(MDS_BUF), %edi
movl PCPU(MDS_BUF64), %edx
movdqa %xmm0, PCPU(MDS_TMP)
pxor %xmm0, %xmm0
lfence
orpd (%edx), %xmm0
orpd (%edx), %xmm0
xorl %eax, %eax
2: clflushopt 5376(%edi, %eax, 8)
addl $8, %eax
cmpl $8 * 12, %eax
jb 2b
sfence
movl $6144, %ecx
xorl %eax, %eax
rep; stosb
mfence
movdqa PCPU(MDS_TMP), %xmm0
testb $CR0_TS, %al
je 3f
movl %eax, %cr0
3: ret
END(mds_handler_skl_sse)
ENTRY(mds_handler_skl_avx)
movl %cr0, %eax
testb $CR0_TS, %al
je 1f
clts
1: movl PCPU(MDS_BUF), %edi
movl PCPU(MDS_BUF64), %edx
vmovdqa %ymm0, PCPU(MDS_TMP)
vpxor %ymm0, %ymm0, %ymm0
lfence
vorpd (%edx), %ymm0, %ymm0
vorpd (%edx), %ymm0, %ymm0
xorl %eax, %eax
2: clflushopt 5376(%edi, %eax, 8)
addl $8, %eax
cmpl $8 * 12, %eax
jb 2b
sfence
movl $6144, %ecx
xorl %eax, %eax
rep; stosb
mfence
vmovdqa PCPU(MDS_TMP), %ymm0
testb $CR0_TS, %al
je 3f
movl %eax, %cr0
3: ret
END(mds_handler_skl_avx)
ENTRY(mds_handler_skl_avx512)
movl %cr0, %eax
testb $CR0_TS, %al
je 1f
clts
1: movl PCPU(MDS_BUF), %edi
movl PCPU(MDS_BUF64), %edx
vmovdqa64 %zmm0, PCPU(MDS_TMP)
vpxord %zmm0, %zmm0, %zmm0
lfence
vorpd (%edx), %zmm0, %zmm0
vorpd (%edx), %zmm0, %zmm0
xorl %eax, %eax
2: clflushopt 5376(%edi, %eax, 8)
addl $8, %eax
cmpl $8 * 12, %eax
jb 2b
sfence
movl $6144, %ecx
xorl %eax, %eax
rep; stosb
mfence
vmovdqa64 PCPU(MDS_TMP), %zmm0
testb $CR0_TS, %al
je 3f
movl %eax, %cr0
3: ret
END(mds_handler_skl_avx512)
ENTRY(mds_handler_silvermont)
movl %cr0, %eax
testb $CR0_TS, %al
je 1f
clts
1: movl PCPU(MDS_BUF), %edx
movdqa %xmm0, PCPU(MDS_TMP)
pxor %xmm0, %xmm0
movl $16, %ecx
2: movntdq %xmm0, (%edx)
addl $16, %edx
decl %ecx
jnz 2b
mfence
movdqa PCPU(MDS_TMP),%xmm0
testb $CR0_TS, %al
je 3f
movl %eax, %cr0
3: ret
END(mds_handler_silvermont)
ENTRY(cpu_sync_core)
popl %eax
pushfl
pushl %cs
pushl %eax
iretl
END(cpu_sync_core)