超级调用swi 82的最初流程

原创文章,转载请注明出处.转载自: Li Haifeng's Blog
本文链接地址: 超级调用swi 82的最初流程



xen/arch/arm/kernel/entry-armv.S


__vectors_start:


swi SYS_ERROR0 /* Reset */


b vector_undefined_instruction + stubs_offset


ldr pc, .LCvswi + stubs_offset


b vector_prefetch_abort + stubs_offset


b vector_data_abort + stubs_offset


b vector_addrexcptn + stubs_offset


b vector_irq + stubs_offset


b vector_fiq + stubs_offset


.globl __vectors_end


__vectors_end:


/*


 * We group all the following data together to optimise


 * for CPUs with separate I & D caches.


 */


.align 5


.LCvswi:


.word vector_swi


————–
xen/arch/arm/hypervisor/hypervisor.S


ENTRY(vector_swi)


sub sp, sp, #S_FRAME_SIZE


stmia sp, {r0 – r12}


add r8, sp, #S_PC


stmdb r8, {sp, lr}^


mrs r8, spsr


str lr, [sp, #S_PC]


str r8, [sp, #S_PSR]


vcpu r8


add r8, r8, #(OFFSET_ARCH_VCPU + OFFSET_GUEST_CONTEXT)


ldr r9, [r8, #(OFFSET_SYS_REGS+OFFSET_VPSR)]


ldr r10, [sp, #S_SP]


cmp r9, #PSR_MODE_USR


streq   r10, [r8, #(OFFSET_SYS_REGS+OFFSET_VUSP)]


strne   r10, [r8, #(OFFSET_SYS_REGS+OFFSET_VKSP)]


ldr     r8, [sp, #S_PSR]


bic     r8, r8, #PSR_MODE_MASK


orr     r8, r8, r9


str     r8, [sp, #S_PSR]


ldr r10, [lr, #-4]


bic r10, r10, #0xff000000


cmp r10, #HYPERCALL_VECTOR_NO


moveq r12, #0x18


movne r12, #0x08


str r12, [sp, #S_CONTEXT]


beq process_hypercalls  //BEQ  也就是条件跳转 当r10与 82比较,相等的时候,就跳转到process_hypercalls标号处


b do_upcall                     //这个do_upcall和evtchn_do_upcall好相似,实际上也是的。


process_hypercalls:


enable_irq


adr lr, ret_from_hypercall


adr tbl, hypercall_table


add tbl, tbl, scno, lsl #2


ldr pc, [tbl]


ENTRY(hypercall_table)


__hypercall_start:


.long do_set_trap_table     /*  0 */


.long do_mmu_update


.long do_ni_hypercall


.long do_stack_switch


.long do_set_callbacks


.long do_fpu_taskswitch     /*  5 */


.long do_sched_op_compat


.long do_domctl


.long do_set_debugreg


.long do_get_debugreg


.long do_update_descriptor  /* 10 */


.long do_ni_hypercall


.long do_memory_op


.long do_multicall


.long do_update_va_mapping


.long do_set_timer_op       /* 15 */


.long do_event_channel_op


。。。。。。
————-


看一下do_upcall的定义:


xen/arch/arm/kernel/entry-common.S


/*


 * Send event to guest domain


 */


ENTRY(do_upcall)


vcpu    r10


ldr r11, [r10, #OFFSET_VCPU_INFO]


add r10, r10, #(OFFSET_ARCH_VCPU + OFFSET_GUEST_CONTEXT)


ldr lr, [r10, #OFFSET_HYPERVISOR_CALLBACK]


cmp lr, #0


beq restore


@DRE_start


@ldrb r9, [r11, #OFFSET_EVTCHN_UPCALL_MASK]


@cmp r9, #1


@beq restore


@DRE_end


mov r9, #0x01


strb r9, [r11, #OFFSET_EVTCHN_UPCALL_MASK]


mov r4, #PSR_MODE_SVC


str r4, [r10, #(OFFSET_SYS_REGS + OFFSET_VPSR)]


@ Load virtual kernel stack pointer


ldr r11, [r10, #(OFFSET_SYS_REGS + OFFSET_VKSP)]


@ Align VKSP in 8-byte boundary


sub r12, r11, #S_FRAME_SIZE


tst r12, #4


bicne r12, r12, #4


tst r12, #4


1:


bne 1b


@ Update effective virtual kernel stack pointer.


str r12, [r10, #(OFFSET_SYS_REGS + OFFSET_VKSP)]


@ Create bounce frame in guest stack


ldmia sp!, {r0-r8}


stmia r12!, {r0-r8}


ldmia sp!, {r0-r8}


stmia r12!, {r0-r8}


sub r12, r12, #S_FRAME_SIZE


ldr r0, =.LCupcall


stmia r0, {r12,lr}


ldmia r0, {sp, lr}^


ldr r0, [r12, #S_CONTEXT]


ldr r1, [r12, #S_PSR]


ldr r2, [r10, #(OFFSET_SYS_REGS + OFFSET_VFAR)]


ldr r3, [r10, #(OFFSET_SYS_REGS + OFFSET_VFSR)]


mov r7, #PSR_MODE_USR


msr spsr, r7


ldr r5, =DOMAIN_KERNEL_VALUE


mcr     p15, 0, r5, c3, c0, 0   @ Load DAC


movs pc, lr


.LCupcall:


.long 0


.long 0



From Li Haifeng's Blog, post 超级调用swi 82的最初流程

Post Footer automatically generated by wp-posturl plugin for wordpress.

分享到: