XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
/* Independently written AMD64 System V instruction shims. C# owns policy. */
.section .text
.global _start
.type _start,@function
_start:
    cli
    cld
    xor %rbp,%rbp
    and $-16,%rsp
    mov %rsp,xfe_initial_stack_top(%rip)
    xor %eax,%eax
    mov %ax,%fs
    xor %edx,%edx
    mov $0xc0000100,%ecx      /* IA32_FS_BASE starts empty; each runtime thread installs its own TLS */
    wrmsr
    mov %cr0,%rax
    and $-13,%rax             /* clear EM and TS */
    or $0x10002,%rax          /* MP and CR0.WP: supervisor writes obey RO PTEs */
    mov %rax,%cr0
    mov %cr4,%rax
    and $-262145,%rax         /* OSXSAVE off: supported context state is x87/SSE, no AVX/YMM use */
    or $0x600,%rax            /* OSFXSR, OSXMMEXCPT */
    mov %rax,%cr4
    sub $16,%rsp
    movl $0x1f80,(%rsp)
    ldmxcsr (%rsp)
    add $16,%rsp
    fninit
    call xfe_boot_info
    mov %rax,%rdi
    call XfeKernelMain
1:  cli
    hlt
    jmp 1b
.size _start,.-_start

.global xfe_load_gdt
.type xfe_load_gdt,@function
xfe_load_gdt:
    lgdt (%rdi)
    pushq $8
    lea 1f(%rip),%rax
    push %rax
    lretq
1:  mov $16,%eax
    mov %ax,%ds
    mov %ax,%es
    mov %ax,%ss
    ret
.size xfe_load_gdt,.-xfe_load_gdt

/* Intentional fault probes used only by the boot protection self-test. The C#
   handler validates CR2, saved RIP and the error code before choosing recovery. */
.global xfe_probe_access
.type xfe_probe_access,@function
xfe_probe_access:
    cmp $1,%esi
    je xfe_probe_write_fault
    cmp $2,%esi
    je 1f
.global xfe_probe_read_fault
xfe_probe_read_fault:
    mov (%rdi),%rax
.global xfe_probe_read_resume
xfe_probe_read_resume:
    ret
.global xfe_probe_write_fault
xfe_probe_write_fault:
    movb $0,(%rdi)
.global xfe_probe_write_resume
xfe_probe_write_resume:
    ret
1:  call *%rdi
    ret
.global xfe_probe_execute_resume
xfe_probe_execute_resume:
    add $8,%rsp               /* discard the faulting indirect call's return */
    ret
.size xfe_probe_access,.-xfe_probe_access

/* System V call context. IRQ frames on the outgoing stack retain all volatile
   registers. FXSAVE64 and IA32_FS_BASE are switched for every kernel thread. */
.global xfe_context_switch
.type xfe_context_switch,@function
xfe_context_switch:
    mov %rax,80(%rdi)
    mov %rdx,88(%rdi)
    mov %rbx,0(%rdi)
    mov %rbp,8(%rdi)
    mov %r12,16(%rdi)
    mov %r13,24(%rdi)
    mov %r14,32(%rdi)
    mov %r15,40(%rdi)
    mov %rsp,48(%rdi)
    lea 1f(%rip),%rax
    mov %rax,56(%rdi)
    pushfq
    popq 64(%rdi)
    mov $0xc0000100,%ecx
    rdmsr
    shl $32,%rdx
    or %rdx,%rax
    mov %rax,72(%rdi)
    fxsave64 96(%rdi)
    mov %rsi,%r11
    mov 72(%r11),%rax
    mov %rax,%rdx
    shr $32,%rdx
    wrmsr
    fxrstor64 96(%r11)
    mov 0(%r11),%rbx
    mov 8(%r11),%rbp
    mov 16(%r11),%r12
    mov 24(%r11),%r13
    mov 32(%r11),%r14
    mov 40(%r11),%r15
    mov 48(%r11),%rsp
    pushq 64(%r11)
    popfq
    jmp *56(%r11)
1:  ret
.size xfe_context_switch,.-xfe_context_switch

.global xfe_thread_trampoline
.type xfe_thread_trampoline,@function
xfe_thread_trampoline:
    sub $8,%rsp
    mov %rbx,%rdi
    call xfe_kernel_thread_entry
    ud2
.size xfe_thread_trampoline,.-xfe_thread_trampoline

/* Real preemption probe: never yields, calls a helper or allocates the red zone.
   Distinct per-thread values occupy all 128 bytes below the live RSP; they must
   survive at least three real LAPIC ticks, with independent FS and XMM15 state. */
.global xfe_thread_probe
.type xfe_thread_probe,@function
xfe_thread_probe:
    push %rbx
    push %r12
    mov %rdi,%rbx
    mov 8(%rbx),%r12
    movq %r12,%xmm15
    .irp displacement,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128
        mov %r12,%rax
        xor $\displacement,%rax
        mov %rax,-\displacement(%rsp)
    .endr
1:  incq 16(%rbx)
    mov %fs:0,%rax
    cmp %r12,%rax
    jne 3f
    movq %xmm15,%rax
    cmp %r12,%rax
    jne 3f
    .irp displacement,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128
        mov %r12,%rax
        xor $\displacement,%rax
        cmp %rax,-\displacement(%rsp)
        jne 3f
    .endr
    mov 56(%rbx),%rax
    mov (%rax),%rax
    sub 64(%rbx),%rax
    cmp $3,%rax
    jb 2f
    mov 32(%rbx),%rax
    cmpq $100000,(%rax)
    jb 2f
    cmpq $100000,16(%rbx)
    jae 4f
2:  lfence
    rdtsc
    shl $32,%rdx
    or %rdx,%rax
    cmp 48(%rbx),%rax
    ja 3f
    pause
    jmp 1b
3:  incq 24(%rbx)
4:  movq $1,40(%rbx)
    mov $1,%eax
    pop %r12
    pop %rbx
    ret
.size xfe_thread_probe,.-xfe_thread_probe

/* Keep all integer and SSE registers. IDT IST3 selects the current thread's
   private interrupt stack, preserving both the interrupted red zone and a
   suspended IRQ frame when the scheduler switches to another kernel thread. */
.type xfe_interrupt_common,@function
xfe_interrupt_common:
    cld
    push %rax
    push %rbx
    push %rcx
    push %rdx
    push %rbp
    push %rdi
    push %rsi
    push %r8
    push %r9
    push %r10
    push %r11
    push %r12
    push %r13
    push %r14
    push %r15
    mov %rsp,%rdi
    mov %rsp,%rbx
    and $-16,%rsp
    sub $512,%rsp
    fxsave64 (%rsp)
    call XfeHandleInterrupt
    fxrstor64 (%rsp)
    mov %rbx,%rsp
    pop %r15
    pop %r14
    pop %r13
    pop %r12
    pop %r11
    pop %r10
    pop %r9
    pop %r8
    pop %rsi
    pop %rdi
    pop %rbp
    pop %rdx
    pop %rcx
    pop %rbx
    pop %rax
    add $16,%rsp
    iretq
.size xfe_interrupt_common,.-xfe_interrupt_common

.macro ISR number
.global xfe_isr_\number
.type xfe_isr_\number,@function
xfe_isr_\number:
    .if (\number != 8) && (\number != 10) && (\number != 11) && (\number != 12) && (\number != 13) && (\number != 14) && (\number != 17) && (\number != 21) && (\number != 29) && (\number != 30)
        pushq $0
    .endif
    pushq $\number
    jmp xfe_interrupt_common
.size xfe_isr_\number,.-xfe_isr_\number
.endm
.altmacro
.set vector,0
.rept 256
    ISR %vector
    .set vector,vector+1
.endr

.section .rodata
.global xfe_isr_table
.type xfe_isr_table,@object
xfe_isr_table:
.macro ISR_POINTER number
    .quad xfe_isr_\number
.endm
.set vector,0
.rept 256
    ISR_POINTER %vector
    .set vector,vector+1
.endr
.size xfe_isr_table,.-xfe_isr_table
.section .note.GNU-stack,"",@progbits