#include "npx.h"
#include "assym.h"
#include "lapic.h"
#include <sys/errno.h>
#include <sys/syscall.h>
#include <machine/codepatch.h>
#include <machine/param.h>
#include <machine/pte.h>
#include <machine/segments.h>
#include <machine/specialreg.h>
#include <machine/trap.h>
#if NLAPIC > 0
#include <machine/i82489reg.h>
#endif
#define SMAP_NOP .byte 0x90, 0x90, 0x90
#define SMAP_STAC CODEPATCH_START ;\
SMAP_NOP ;\
CODEPATCH_END(CPTAG_STAC)
#define SMAP_CLAC CODEPATCH_START ;\
SMAP_NOP ;\
CODEPATCH_END(CPTAG_CLAC)
#define ALIGN_DATA .align 4,0xcc
#define ALIGN_TEXT .align 4,0x90
#define _ALIGN_TEXT ALIGN_TEXT
#include <machine/asm.h>
#define CPL lapic_tpr
#define GET_CURPCB(reg) \
movl CPUVAR(CURPCB), reg
#define CHECK_ASTPENDING(treg) \
movl CPUVAR(CURPROC),treg ; \
cmpl $0, treg ; \
je 1f ; \
cmpl $0,P_MD_ASTPENDING(treg) ; \
1:
#define CLEAR_ASTPENDING(cpreg) \
movl $0,P_MD_ASTPENDING(cpreg)
#define INTR_COPY_FROM_TRAMP_STACK \
movl TRF_SS(%ebp),%eax ; \
movl %eax,IRF_SS(%esp) ; \
movl TRF_ESP(%ebp),%eax ; \
movl %eax,IRF_ESP(%esp) ; \
movl TRF_EFLAGS(%ebp),%eax ; \
movl %eax,IRF_EFLAGS(%esp) ; \
movl TRF_CS(%ebp),%eax ; \
movl %eax,IRF_CS(%esp) ; \
movl TRF_EIP(%ebp),%eax ; \
movl %eax,IRF_EIP(%esp) ; \
movl TRF_ERR(%ebp),%eax ; \
movl %eax,IRF_ERR(%esp) ; \
movl TRF_TRAPNO(%ebp),%eax ; \
movl %eax,IRF_TRAPNO(%esp)
#define INTR_ENABLE_U_PLUS_K \
movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \
movw %ax,%fs ; \
movl CPUVAR(KERN_CR3),%eax ; \
testl %eax,%eax ; \
jz 100f ; \
movl %eax,%cr3 ; \
100:
#define INTRENTRY_LABEL(label) X##label##_untramp
#define INTRENTRY(label) \
; \
testb $SEL_RPL,IRF_CS(%esp) ; \
; \
je INTRENTRY_LABEL(label) ; \
; \
pushl %ebp ; \
pushl %eax ; \
pushl %fs ; \
INTR_ENABLE_U_PLUS_K ; \
jmp 99f ; \
.text ; \
.global INTRENTRY_LABEL(label) ; \
INTRENTRY_LABEL(label): ; \
jmp 98f ; \
; \
99: movl CPUVAR(KERN_ESP),%eax ; \
pushl %eax ; \
pushl $0xdeadbeef ; \
movl %esp,%ebp ; \
movl %eax,%esp ; \
subl $SIZEOF_IRETFRAME,%esp ; \
; \
INTR_COPY_FROM_TRAMP_STACK ; \
movl TRF_FS(%ebp),%eax ; \
movw %ax,%fs ; \
movl TRF_EAX(%ebp),%eax ; \
movl TRF_EBP(%ebp),%ebp ; \
98: INTR_SAVE_ALL
#define INTR_SAVE_ALL \
cld ; \
SMAP_CLAC ; \
; \
subl $44,%esp ; \
movl %eax,TF_EAX(%esp) ; \
; \
; \
movl (TF_EIP - 4)(%esp),%eax ; \
movl %eax,TF_ERR(%esp) ; \
movl %ecx,TF_ECX(%esp) ; \
movl %edx,TF_EDX(%esp) ; \
movl %ebx,TF_EBX(%esp) ; \
movl %ebp,TF_EBP(%esp) ; \
leal TF_EBP(%esp),%ebp ; \
movl %esi,TF_ESI(%esp) ; \
movl %edi,TF_EDI(%esp) ; \
movw %ds,TF_DS(%esp) ; \
movw %es,TF_ES(%esp) ; \
movw %gs,TF_GS(%esp) ; \
movl $GSEL(GDATA_SEL, SEL_KPL),%eax ; \
movw %ax,%ds ; \
movw %ax,%es ; \
xorl %eax,%eax ; \
movw %ax,%gs ; \
movw %fs,TF_FS(%esp) ; \
movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \
movw %ax,%fs
#define INTR_RESTORE_ALL \
popl %fs ; \
popl %gs ; \
popl %es ; \
popl %ds ; \
popl %edi ; \
popl %esi ; \
addl $4,%esp ; \
popl %ebx ; \
popl %edx ; \
popl %ecx ; \
popl %eax ; \
movl 4(%esp),%ebp
#define INTRFASTEXIT \
jmp intr_fast_exit
#define INTR_FAKE_TRAP_PUSH_RPB 0xbadabada
#define INTR_FAKE_TRAP_POP_RBP 0xbcbcbcbc
.globl PTmap, PTD
.set PTmap, (PDSLOT_PTE << PDSHIFT)
.set PTD, (PTmap + PDSLOT_PTE * NBPG)
.data
.globl cpu_id, cpu_vendor
.globl cpu_brandstr
.globl cpuid_level
.globl cpu_miscinfo
.globl cpu_feature, cpu_ecxfeature
.globl ecpu_feature, ecpu_eaxfeature
.globl ecpu_ecxfeature
.globl cpu_cache_eax, cpu_cache_ebx
.globl cpu_cache_ecx, cpu_cache_edx
.globl cpu_perf_eax
.globl cpu_perf_ebx
.globl cpu_perf_edx
.globl cpu_apmi_edx
.globl cold, cnvmem, extmem
.globl cpu_pae
.globl esym
.globl ssym
.globl nkptp_max
.globl boothowto, bootdev, atdevbase
.globl proc0paddr, PTDpaddr, PTDsize
.globl gdt
.globl bootapiver, bootargc, bootargv
.globl lapic_tpr
.globl pg_g_kern
.globl cpu_meltdown
#if NLAPIC > 0
.align NBPG
.globl local_apic, lapic_id
local_apic:
.space LAPIC_ID
lapic_id:
.long 0x00000000
.space LAPIC_TPRI-(LAPIC_ID+4)
lapic_tpr:
.space LAPIC_PPRI-LAPIC_TPRI
lapic_ppr:
.space LAPIC_ISR-LAPIC_PPRI
lapic_isr:
.space NBPG-LAPIC_ISR
#else
lapic_tpr:
.long 0
#endif
cpu_id: .long 0 # saved from 'cpuid' instruction
cpu_pae: .long 0 # are we using PAE paging mode?
cpu_miscinfo: .long 0 # misc info (apic/brand id) from 'cpuid'
cpu_feature: .long 0 # feature flags from 'cpuid' instruction
ecpu_feature: .long 0 # extended feature flags from 'cpuid'
cpu_ecxfeature: .long 0 # ecx feature flags from 'cpuid'
ecpu_eaxfeature: .long 0 # extended eax feature flags
ecpu_ecxfeature: .long 0 # extended ecx feature flags
cpuid_level: .long -1 # max. lvl accepted by 'cpuid' insn
cpu_cache_eax: .long 0
cpu_cache_ebx: .long 0
cpu_cache_ecx: .long 0
cpu_cache_edx: .long 0
cpu_perf_eax: .long 0 # arch. perf. mon. flags from 'cpuid'
cpu_perf_ebx: .long 0 # arch. perf. mon. flags from 'cpuid'
cpu_perf_edx: .long 0 # arch. perf. mon. flags from 'cpuid'
cpu_apmi_edx: .long 0 # adv. power management info. 'cpuid'
cpu_vendor: .space 16 # vendor string returned by 'cpuid' instruction
cpu_brandstr: .space 48 # brand string returned by 'cpuid'
cold: .long 1 # cold till we are not
ssym: .long 0 # ptr to start of syms
esym: .long 0 # ptr to end of syms
cnvmem: .long 0 # conventional memory size
extmem: .long 0 # extended memory size
atdevbase: .long 0 # location of start of iomem in virtual
bootapiver: .long 0 # /boot API version
bootargc: .long 0 # /boot argc
bootargv: .long 0 # /boot argv
bootdev: .long 0 # device we booted from
proc0paddr: .long 0
PTDpaddr: .long 0 # paddr of PTD, for libkvm
PTDsize: .long NBPG # size of PTD, for libkvm
pg_g_kern: .long 0 # 0x100 if global pages should be used
cpu_meltdown: .long 0 # 1 if this CPU has Meltdown
.text
NENTRY(proc_trampoline)
call proc_trampoline_mi
pushl %ebx
call *%esi
addl $4,%esp
#ifdef DIAGNOSTIC
movl $0xfe,%esi
#endif
jmp .Lsyscall_check_asts
.section .codepatch,"a"
.align 8
.globl codepatch_begin
codepatch_begin:
.previous
.section .codepatchend,"a"
.globl codepatch_end
codepatch_end:
.previous
.section .rodata
.globl sigcode
sigcode:
call *SIGF_HANDLER(%esp)
leal SIGF_SC(%esp),%eax # scp (the call may have clobbered the
pushl %eax
pushl %eax # junk to fake return address
movl $SYS_sigreturn,%eax
.globl sigcodecall
sigcodecall:
int $0x80 # enter kernel with args on stack
.globl sigcoderet
sigcoderet:
.globl esigcode
esigcode:
.globl sigfill
sigfill:
int3
esigfill:
.data
.globl sigfillsiz
sigfillsiz:
.long esigfill - sigfill
.text
#ifdef DDB
#define FPADD 4
#else
#define FPADD 0
#endif
ENTRY(kcopy)
#ifdef DDB
pushl %ebp
movl %esp,%ebp
#endif
pushl %esi
pushl %edi
GET_CURPCB(%eax) # load curpcb into eax and set on-fault
pushl PCB_ONFAULT(%eax)
movl $copy_fault, PCB_ONFAULT(%eax)
movl 16+FPADD(%esp),%esi
movl 20+FPADD(%esp),%edi
movl 24+FPADD(%esp),%ecx
movl %edi,%eax
subl %esi,%eax
cmpl %ecx,%eax # overlapping?
jb 1f
shrl $2,%ecx # nope, copy forward by 32-bit words
rep
movsl
movl 24+FPADD(%esp),%ecx
andl $3,%ecx # any bytes left?
rep
movsb
GET_CURPCB(%edx) # XXX save curpcb?
popl PCB_ONFAULT(%edx)
popl %edi
popl %esi
xorl %eax,%eax
#ifdef DDB
leave
#endif
ret
.align 4,0xcc
1: addl %ecx,%edi # copy backward
addl %ecx,%esi
std
andl $3,%ecx # any fractional bytes?
decl %edi
decl %esi
rep
movsb
movl 24+FPADD(%esp),%ecx # copy remainder by 32-bit words
shrl $2,%ecx
subl $3,%esi
subl $3,%edi
rep
movsl
cld
GET_CURPCB(%edx)
popl PCB_ONFAULT(%edx)
popl %edi
popl %esi
xorl %eax,%eax
#ifdef DDB
leave
#endif
ret
ENTRY(copyout)
#ifdef DDB
pushl %ebp
movl %esp,%ebp
#endif
pushl %esi
pushl %edi
GET_CURPCB(%eax)
pushl PCB_ONFAULT(%eax)
movl 16+FPADD(%esp),%esi
movl 20+FPADD(%esp),%edi
movl 24+FPADD(%esp),%eax
movl %edi,%edx
addl %eax,%edx
jc copy_fault
cmpl $VM_MAXUSER_ADDRESS,%edx
ja copy_fault
GET_CURPCB(%edx)
movl $copy_fault,PCB_ONFAULT(%edx)
SMAP_STAC
movl %eax,%ecx
shrl $2,%ecx
rep
movsl
movl %eax,%ecx
andl $3,%ecx
rep
movsb
SMAP_CLAC
popl PCB_ONFAULT(%edx)
popl %edi
popl %esi
xorl %eax,%eax
#ifdef DDB
leave
#endif
ret
ENTRY(_copyin)
#ifdef DDB
pushl %ebp
movl %esp,%ebp
#endif
pushl %esi
pushl %edi
GET_CURPCB(%eax)
pushl PCB_ONFAULT(%eax)
movl $copy_fault,PCB_ONFAULT(%eax)
SMAP_STAC
movl 16+FPADD(%esp),%esi
movl 20+FPADD(%esp),%edi
movl 24+FPADD(%esp),%eax
movl %esi,%edx
addl %eax,%edx
jc copy_fault
cmpl $VM_MAXUSER_ADDRESS,%edx
ja copy_fault
movl %eax,%ecx
shrl $2,%ecx
rep
movsl
movb %al,%cl
andb $3,%cl
rep
movsb
SMAP_CLAC
GET_CURPCB(%edx)
popl PCB_ONFAULT(%edx)
popl %edi
popl %esi
xorl %eax,%eax
#ifdef DDB
leave
#endif
ret
ENTRY(copy_fault)
cld
SMAP_CLAC
GET_CURPCB(%edx)
popl PCB_ONFAULT(%edx)
popl %edi
popl %esi
movl $EFAULT,%eax
#ifdef DDB
leave
#endif
ret
ENTRY(copyoutstr)
#ifdef DDB
pushl %ebp
movl %esp,%ebp
#endif
pushl %esi
pushl %edi
GET_CURPCB(%eax)
pushl PCB_ONFAULT(%eax)
movl $copystr_fault,PCB_ONFAULT(%eax)
SMAP_STAC
movl 16+FPADD(%esp),%esi # esi = from
movl 20+FPADD(%esp),%edi # edi = to
movl 24+FPADD(%esp),%edx # edx = maxlen
movl $VM_MAXUSER_ADDRESS,%eax
subl %edi,%eax
jbe copystr_fault # die if CF == 1 || ZF == 1
cmpl %edx,%eax
jae 1f
movl %eax,%edx
movl %eax,24+FPADD(%esp)
1: incl %edx
1: decl %edx
jz 2f
lodsb
stosb
testb %al,%al
jnz 1b
decl %edx
xorl %eax,%eax
jmp copystr_return
2:
cmpl $VM_MAXUSER_ADDRESS,%edi
jae copystr_fault
movl $ENAMETOOLONG,%eax
jmp copystr_return
ENTRY(_copyinstr)
#ifdef DDB
pushl %ebp
movl %esp,%ebp
#endif
pushl %esi
pushl %edi
GET_CURPCB(%ecx)
pushl PCB_ONFAULT(%ecx)
movl $copystr_fault,PCB_ONFAULT(%ecx)
SMAP_STAC
movl 16+FPADD(%esp),%esi # %esi = from
movl 20+FPADD(%esp),%edi # %edi = to
movl 24+FPADD(%esp),%edx # %edx = maxlen
movl $VM_MAXUSER_ADDRESS,%eax
subl %esi,%eax
jbe copystr_fault # Error if CF == 1 || ZF == 1
cmpl %edx,%eax
jae 1f
movl %eax,%edx
movl %eax,24+FPADD(%esp)
1: incl %edx
1: decl %edx
jz 2f
lodsb
stosb
testb %al,%al
jnz 1b
decl %edx
xorl %eax,%eax
jmp copystr_return
2:
cmpl $VM_MAXUSER_ADDRESS,%esi
jae copystr_fault
movl $ENAMETOOLONG,%eax
jmp copystr_return
ENTRY(copystr_fault)
movl $EFAULT,%eax
copystr_return:
SMAP_CLAC
movl 24+FPADD(%esp),%ecx
subl %edx,%ecx
movl 28+FPADD(%esp),%edx
testl %edx,%edx
jz 8f
movl %ecx,(%edx)
8: GET_CURPCB(%ecx)
popl PCB_ONFAULT(%ecx)
popl %edi
popl %esi
#ifdef DDB
leave
#endif
ret
NENTRY(lgdt)
movl 4(%esp),%eax
lgdt (%eax)
jmp 1f
nop
1:
movl $GSEL(GDATA_SEL, SEL_KPL),%eax
movw %ax,%ds
movw %ax,%es
movw %ax,%ss
movl $GSEL(GCPU_SEL, SEL_KPL),%eax
movw %ax,%fs
popl %eax
pushl $GSEL(GCODE_SEL, SEL_KPL)
pushl %eax
lret
#ifdef DDB
ENTRY(setjmp)
movl 4(%esp),%eax
movl %ebx,(%eax) # save ebx
movl %esp,4(%eax) # save esp
movl %ebp,8(%eax) # save ebp
movl %esi,12(%eax) # save esi
movl %edi,16(%eax) # save edi
movl (%esp),%edx # get rta
movl %edx,20(%eax) # save eip
xorl %eax,%eax # return (0);
ret
ENTRY(longjmp)
movl 4(%esp),%eax
movl (%eax),%ebx # restore ebx
movl 4(%eax),%esp # restore esp
movl 8(%eax),%ebp # restore ebp
movl 12(%eax),%esi # restore esi
movl 16(%eax),%edi # restore edi
movl 20(%eax),%edx # get rta
movl %edx,(%esp) # put in return frame
xorl %eax,%eax # return (1);
incl %eax
ret
#endif
ENTRY(cpu_switchto)
pushl %ebx
pushl %esi
pushl %edi
movl 16(%esp), %esi
movl 20(%esp), %edi
testl %esi,%esi
jz switch_exited
movl P_ADDR(%esi),%ebx
movl %esp,PCB_ESP(%ebx)
movl %ebp,PCB_EBP(%ebx)
switch_exited:
cli
movl %edi, CPUVAR(CURPROC)
movb $SONPROC, P_STAT(%edi)
movl P_ADDR(%edi),%ebx
movl PCB_ESP(%ebx),%esp
movl PCB_EBP(%ebx),%ebp
movl %ebx, CPUVAR(CURPCB)
movl PCB_KSTACK(%ebx),%eax
subl $FRAMESIZE,%eax
movl %eax,CPUVAR(KERN_ESP)
pushl %edi
pushl %esi
call pmap_switch
addl $8,%esp
movl PCB_CR0(%ebx),%ecx
#ifdef MULTIPROCESSOR
movl CPUVAR(SELF), %esi
cmpl PCB_FPCPU(%ebx), %esi
jz 1f
orl $CR0_TS,%ecx
1:
#endif
movl %ecx,%cr0
sti
popl %edi
popl %esi
popl %ebx
ret
ENTRY(cpu_idle_enter)
movl cpu_idle_enter_fcn,%eax
cmpl $0,%eax
je 1f
jmpl *%eax
1:
ret
ENTRY(cpu_idle_cycle)
movl cpu_idle_cycle_fcn,%eax
cmpl $0,%eax
je 1f
call *%eax
ret
1:
sti
hlt
ret
ENTRY(cpu_idle_leave)
movl cpu_idle_leave_fcn,%eax
cmpl $0,%eax
je 1f
jmpl *%eax
1:
ret
ENTRY(savectx)
movl 4(%esp),%edx # edx = p->p_addr
movl %esp,PCB_ESP(%edx)
movl %ebp,PCB_EBP(%edx)
movl PCB_FLAGS(%edx),%ecx
orl $PCB_SAVECTX,%ecx
movl %ecx,PCB_FLAGS(%edx)
ret
#define TRAP(a) pushl $(a) ; jmp alltraps
#define ZTRAP(a) pushl $0 ; TRAP(a)
IDTVEC(div)
ZTRAP(T_DIVIDE)
IDTVEC(dbg)
subl $4,%esp
pushl %eax
movl %dr6,%eax
movl %eax,4(%esp)
andb $~0xf,%al
movl %eax,%dr6
popl %eax
TRAP(T_TRCTRAP)
IDTVEC(nmi)
movl CPUVAR(CURPMAP),%eax
movl PM_PDIRPA(%eax),%eax
movl %eax,%cr3
movl CPUVAR(TSS),%eax
testb $SEL_RPL,TSS_CS(%eax)
jne 1f
movl TSS_ESP(%eax),%esp
subl $12,%esp
movl TSS_EFLAGS(%eax),%ebx
movl %ebx,8(%esp)
movl TSS_CS(%eax),%ebx
movl %ebx,4(%esp)
movl TSS_EIP(%eax),%ebx
movl %ebx,0(%esp)
pushl $0
pushl $T_NMI
jmp 2f
1: subl $20,%esp
pushl $0
pushl $T_NMI
movl TSS_SS(%eax),%ebx
movl %ebx,IRF_SS(%esp)
movl TSS_ESP(%eax),%ebx
movl %ebx,IRF_ESP(%esp)
movl TSS_EFLAGS(%eax),%ebx
movl %ebx,IRF_EFLAGS(%esp)
movl TSS_CS(%eax),%ebx
movl %ebx,IRF_CS(%esp)
movl TSS_EIP(%eax),%ebx
movl %ebx,IRF_EIP(%esp)
2: pushfl
popl %eax
andl $~PSL_NT,%eax
pushl %eax
popfl
movl %cr0,%eax
andl $~CR0_TS,%eax
movl %eax,%cr0
movl CPUVAR(GDT),%eax
movl $GSEL(GNMITSS_SEL, SEL_KPL),%ebx
andl $~0x200,4-SEL_KPL(%eax,%ebx,1)
movl $GSEL(GTSS_SEL, SEL_KPL),%ebx
andl $~0x200,4-SEL_KPL(%eax,%ebx,1)
ltr %bx
movl CPUVAR(TSS),%eax
movl TSS_ECX(%eax),%ecx
movl TSS_EDX(%eax),%edx
movl TSS_ESI(%eax),%esi
movl TSS_EDI(%eax),%edi
movl TSS_EBP(%eax),%ebp
movw TSS_FS(%eax),%fs
movw TSS_GS(%eax),%gs
movw TSS_ES(%eax),%es
movl TSS_DS(%eax),%ebx
pushl %ebx
movl TSS_EBX(%eax),%ebx
movl TSS_EAX(%eax),%eax
popl %ds
jmp alltraps
IDTVEC(bpt)
ZTRAP(T_BPTFLT)
IDTVEC(ofl)
ZTRAP(T_OFLOW)
IDTVEC(bnd)
ZTRAP(T_BOUND)
IDTVEC(ill)
ZTRAP(T_PRIVINFLT)
IDTVEC(dna)
#if NNPX > 0
pushl $0 # dummy error code
pushl $T_DNA
INTRENTRY(dna)
sti
pushl CPUVAR(SELF)
call *npxdna_func
addl $4,%esp
testl %eax,%eax
jz calltrap
#ifdef DIAGNOSTIC
movl $0xfd,%esi
#endif
cli
INTRFASTEXIT
#else
ZTRAP(T_DNA)
#endif
IDTVEC(dble)
TRAP(T_DOUBLEFLT)
IDTVEC(fpusegm)
ZTRAP(T_FPOPFLT)
IDTVEC(tss)
TRAP(T_TSSFLT)
IDTVEC(missing)
TRAP(T_SEGNPFLT)
IDTVEC(stk)
TRAP(T_STKFLT)
IDTVEC(prot)
pushl $T_PROTFLT
pushl %eax
leal doreti_iret+3,%eax
cmpl %eax,12(%esp)
popl %eax
jne 97f
pushl %ebp
pushl %eax
pushl %fs
INTR_ENABLE_U_PLUS_K
movl CPUVAR(KERN_ESP),%eax
pushl %eax
pushl $0xdeadbeef
movl %esp,%ebp
movl %eax,%esp
subl $SIZEOF_IRETFRAME+(5*4),%esp
movl TRF_EFLAGS(%ebp),%eax
movl %eax,IRF_EFLAGS(%esp)
movl TRF_CS(%ebp),%eax
movl %eax,IRF_CS(%esp)
movl TRF_EIP(%ebp),%eax
movl %eax,IRF_EIP(%esp)
movl TRF_ERR(%ebp),%eax
movl %eax,IRF_ERR(%esp)
movl TRF_TRAPNO(%ebp),%eax
movl %eax,IRF_TRAPNO(%esp)
movl 40(%ebp),%eax
movl %eax,20(%esp)
movl 44(%ebp),%eax
movl %eax,24(%esp)
movl 48(%ebp),%eax
movl %eax,28(%esp)
movl 52(%ebp),%eax
movl %eax,32(%esp)
movl 56(%ebp),%eax
movl %eax,36(%esp)
movl TRF_FS(%ebp),%eax
movw %ax,%fs
movl TRF_EAX(%ebp),%eax
movl TRF_EBP(%ebp),%ebp
97: INTRENTRY(prot)
sti
jmp calltrap
IDTVEC(f00f_redirect)
pushl $T_PAGEFLT
INTRENTRY(f00f_redirect)
sti
testb $PGEX_U,TF_ERR(%esp)
jnz calltrap
movl %cr2,%eax
subl idt,%eax
cmpl $(6*8),%eax
jne calltrap
movb $T_PRIVINFLT,TF_TRAPNO(%esp)
jmp calltrap
IDTVEC(page)
TRAP(T_PAGEFLT)
IDTVEC(rsvd)
ZTRAP(T_RESERVED)
IDTVEC(mchk)
ZTRAP(T_MACHK)
IDTVEC(simd)
ZTRAP(T_XFTRAP)
IDTVEC(intrspurious)
iret
IDTVEC(fpu)
#if NNPX > 0
subl $8,%esp
INTRENTRY(fpu)
sti
pushl CPL # if_ppl in intrframe
pushl %esp # push address of intrframe
incl uvmexp+V_TRAP
call npxintr
addl $8,%esp # pop address and if_ppl
#ifdef DIAGNOSTIC
movl $0xfc,%esi
#endif
cli
INTRFASTEXIT
#else
ZTRAP(T_ARITHTRAP)
#endif
IDTVEC(align)
TRAP(T_ALIGNFLT)
KUENTRY(resume_iret)
ZTRAP(T_PROTFLT)
NENTRY(resume_pop_ds)
pushl %es
movl $GSEL(GDATA_SEL, SEL_KPL),%eax
movw %ax,%es
NENTRY(resume_pop_es)
pushl %gs
xorl %eax,%eax
movw %ax,%gs
NENTRY(resume_pop_gs)
pushl %fs
movl $GSEL(GCPU_SEL, SEL_KPL),%eax
movw %ax,%fs
NENTRY(resume_pop_fs)
movl $T_PROTFLT,TF_TRAPNO(%esp)
sti
jmp calltrap
KUENTRY(alltraps)
INTRENTRY(alltraps)
sti
calltrap:
#ifdef DIAGNOSTIC
movl CPL,%ebx
#endif
#if !defined(GPROF) && defined(DDBPROF)
cmpl $T_BPTFLT,TF_TRAPNO(%esp)
jne .Lreal_trap
pushl %esp
subl $4, %esp
pushl %eax
leal dt_prov_kprobe, %eax
movl %eax, 4(%esp)
popl %eax
call dt_prov_kprobe_hook
addl $8, %esp
cmpl $0, %eax
je .Lreal_trap
cmpl $1, %eax
je .Lset_emulate_push_rbp
cmpl $2, %eax
je .Lset_emulate_ret
.Lset_emulate_push_rbp:
movl $INTR_FAKE_TRAP_PUSH_RPB, TF_ERR(%esp)
jmp .Lalltraps_check_asts
.Lset_emulate_ret:
movl $INTR_FAKE_TRAP_POP_RBP, TF_ERR(%esp)
jmp .Lalltraps_check_asts
.Lreal_trap:
#endif
pushl %esp
call trap
addl $4,%esp
.Lalltraps_check_asts:
cli
CHECK_ASTPENDING(%ecx)
je 1f
testb $SEL_RPL,TF_CS(%esp)
jz 1f
5: CLEAR_ASTPENDING(%ecx)
sti
pushl %esp
call ast
addl $4,%esp
jmp .Lalltraps_check_asts
1:
#if !defined(GPROF) && defined(DDBPROF)
cmpl $INTR_FAKE_TRAP_PUSH_RPB, TF_ERR(%esp)
je .Lprobe_fixup_push_rbp
cmpl $INTR_FAKE_TRAP_POP_RBP, TF_ERR(%esp)
je .Lprobe_fixup_pop_rbp
#endif
#ifndef DIAGNOSTIC
INTRFASTEXIT
#else
cmpl CPL,%ebx
jne 3f
#ifdef DIAGNOSTIC
movl $0xfb,%esi
#endif
INTRFASTEXIT
3: sti
pushl $spl_lowered
call printf
addl $4,%esp
#if defined(DDB) && 0
int $3
#endif
movl %ebx,CPL
jmp .Lalltraps_check_asts
.section .rodata
spl_lowered:
.asciz "WARNING: SPL NOT LOWERED ON TRAP EXIT\n"
#endif
.text
#if !defined(GPROF) && defined(DDBPROF)
.Lprobe_fixup_push_rbp:
INTR_RESTORE_ALL
movl %eax,0(%esp)
movl 8(%esp),%eax
movl %eax,4(%esp)
movl 12(%esp),%eax
movl %eax,8(%esp)
movl 16(%esp),%eax
movl %eax,12(%esp)
movl %ebp,16(%esp)
popl %eax
iret
.Lprobe_fixup_pop_rbp:
INTR_RESTORE_ALL
movl %eax, 0(%esp)
movl 20(%esp), %ebp
movl 16(%esp), %eax
movl %eax, 20(%esp)
movl 12(%esp), %eax
movl %eax, 16(%esp)
movl 8(%esp), %eax
movl %eax, 12(%esp)
popl %eax
addl $8, %esp
iret
#endif
.text
#ifdef DIAGNOSTIC
.Lintr_exit_not_blocked:
movl warn_once,%eax
testl %eax,%eax
jnz 1f
incl %eax
movl %eax,warn_once
pushl %esi
pushl %edx
pushl $.Lnot_blocked
call printf
addl $12,%esp
#ifdef DDB
int $3
#endif
1: cli
jmp intr_fast_exit
.data
.global warn_once
warn_once:
.long 0
.section .rodata
.Lnot_blocked:
.asciz "WARNING: INTERRUPTS NOT BLOCKED ON INTERRUPT RETURN 0x%x 0x%x\n"
.text
#endif
IDTVEC(syscall)
subl $8,%esp
INTRENTRY(syscall)
sti
pushl %esp
call syscall
addl $4,%esp
.Lsyscall_check_asts:
cli
CHECK_ASTPENDING(%ecx)
je 1f
CLEAR_ASTPENDING(%ecx)
sti
pushl %esp
call ast
addl $4,%esp
jmp .Lsyscall_check_asts
1:
#ifdef DIAGNOSTIC
movl $0xff,%esi
#endif
jmp intr_fast_exit
NENTRY(intr_fast_exit)
#ifdef DIAGNOSTIC
pushfl
popl %edx
testl $PSL_I,%edx
jnz .Lintr_exit_not_blocked
#endif
INTR_RESTORE_ALL
testb $SEL_RPL,IRF_CS(%esp)
je doreti_iret
pushl %ebp
pushl %eax
pushl %fs
movl $GSEL(GCPU_SEL, SEL_KPL),%eax
movw %ax,%fs
movl CPUVAR(INTR_ESP),%eax
pushl %eax
pushl $0xcafecafe
movl %eax,%ebp
movl TRF_EIP(%esp),%eax
movl %eax,TRF_EIP(%ebp)
movl TRF_CS(%esp),%eax
movl %eax,TRF_CS(%ebp)
movl TRF_EFLAGS(%esp),%eax
movl %eax,TRF_EFLAGS(%ebp)
movl TRF_ESP(%esp),%eax
movl %eax,TRF_ESP(%ebp)
movl TRF_SS(%esp),%eax
movl %eax,TRF_SS(%ebp)
movl TRF__DEADBEEF(%esp),%eax
movl %eax,TRF__DEADBEEF(%ebp)
movl TRF__KERN_ESP(%esp),%eax
movl %eax,TRF__KERN_ESP(%ebp)
movl TRF_FS(%esp),%eax
movl %eax,TRF_FS(%ebp)
movl TRF_EAX(%esp),%eax
movl %eax,TRF_EAX(%ebp)
movl TRF_EBP(%esp),%eax
movl %eax,TRF_EBP(%ebp)
movl %ebp,%esp
movl CPUVAR(USER_CR3),%eax
testl %eax,%eax
jz 1f
jmp iret_tramp
KUENTRY(iret_tramp)
movl %eax,%cr3
1: popl %eax
popl %eax
popl %fs
popl %eax
popl %ebp
.globl doreti_iret
doreti_iret:
addl $IRF_EIP,%esp
iret
#include <i386/i386/vector.s>
#include <i386/isa/icu.s>
#if !defined(SMALL_KERNEL)
ENTRY(sse2_pagezero)
pushl %ebx
movl 8(%esp),%ecx
movl %ecx,%eax
addl $4096,%eax
xor %ebx,%ebx
1:
movnti %ebx,(%ecx)
addl $4,%ecx
cmpl %ecx,%eax
jne 1b
sfence
popl %ebx
ret
ENTRY(i686_pagezero)
pushl %edi
pushl %ebx
movl 12(%esp), %edi
movl $1024, %ecx
.align 4,0x90
1:
xorl %eax, %eax
repe
scasl
jnz 2f
popl %ebx
popl %edi
ret
.align 4,0x90
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
#endif
ENTRY(cpu_paenable)
movl $-1, %eax
testl $CPUID_PAE, cpu_feature
jz 1f
pushl %esi
pushl %edi
movl 12(%esp), %esi
movl %cr3, %edi
orl $0xfe0, %edi
movl %edi, %cr3
addl $KERNBASE, %edi
movl $8, %ecx
rep
movsl
movl $MSR_EFER, %ecx
rdmsr
orl $EFER_NXE, %eax
wrmsr
movl %cr4, %eax
orl $CR4_PAE, %eax
movl %eax, %cr4
movl 12(%esp), %eax
subl $KERNBASE, %eax
movl %eax, %cr3
movl $4*NBPG, %eax
movl %eax, PTDsize
xorl %eax, %eax
popl %edi
popl %esi
1:
ret
#if NLAPIC > 0
#include <i386/i386/apicvec.s>
#endif
.section .rodata
.globl _stac
_stac:
stac
.globl _clac
_clac:
clac