The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/swtch.S

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: cpuswitch.S,v 1.41 2003/11/15 08:44:18 scw Exp $       */
    2 
    3 /*-
    4  * Copyright 2003 Wasabi Systems, Inc.
    5  * All rights reserved.
    6  *
    7  * Written by Steve C. Woodford for Wasabi Systems, Inc.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed for the NetBSD Project by
   20  *      Wasabi Systems, Inc.
   21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
   22  *    or promote products derived from this software without specific prior
   23  *    written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
   29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   35  * POSSIBILITY OF SUCH DAMAGE.
   36  */
   37 /*-
   38  * Copyright (c) 1994-1998 Mark Brinicombe.
   39  * Copyright (c) 1994 Brini.
   40  * All rights reserved.
   41  *
   42  * This code is derived from software written for Brini by Mark Brinicombe
   43  *
   44  * Redistribution and use in source and binary forms, with or without
   45  * modification, are permitted provided that the following conditions
   46  * are met:
   47  * 1. Redistributions of source code must retain the above copyright
   48  *    notice, this list of conditions and the following disclaimer.
   49  * 2. Redistributions in binary form must reproduce the above copyright
   50  *    notice, this list of conditions and the following disclaimer in the
   51  *    documentation and/or other materials provided with the distribution.
   52  * 3. All advertising materials mentioning features or use of this software
   53  *    must display the following acknowledgement:
   54  *      This product includes software developed by Brini.
   55  * 4. The name of the company nor the name of the author may be used to
   56  *    endorse or promote products derived from this software without specific
   57  *    prior written permission.
   58  *
   59  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
   60  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   61  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   62  * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   63  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   64  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   65  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   69  * SUCH DAMAGE.
   70  *
   71  * RiscBSD kernel project
   72  *
   73  * cpuswitch.S
   74  *
   75  * cpu switching functions
   76  *
   77  * Created      : 15/10/94
   78  *
   79  */
   80 
   81 #include "assym.s"
   82 #include "opt_sched.h"
   83 
   84 #include <machine/asm.h>
   85 #include <machine/asmacros.h>
   86 #include <machine/armreg.h>
   87 __FBSDID("$FreeBSD: releng/10.0/sys/arm/arm/swtch.S 254847 2013-08-25 11:23:38Z andrew $");
   88 
   89 #define DOMAIN_CLIENT   0x01
   90 
   91 #ifdef _ARM_ARCH_6
   92 #define GET_PCPU(tmp) \
   93         mrc p15, 0, tmp, c13, c0, 4;
   94 #else
   95 .Lcurpcpu:
   96         .word   _C_LABEL(__pcpu)
   97 
   98 #define GET_PCPU(tmp) \
   99         ldr     tmp, .Lcurpcpu
  100 #endif
  101 
  102 .Lcpufuncs:     
  103         .word   _C_LABEL(cpufuncs)
  104 .Lblocked_lock:
  105         .word   _C_LABEL(blocked_lock)
  106 
  107 ENTRY(cpu_throw)
  108         mov     r5, r1
  109 
  110         /*
  111          * r0 = oldtd
  112          * r5 = newtd
  113          */
  114 
  115         GET_PCPU(r7)
  116 
  117 #ifdef VFP
  118         /*
  119          * vfp_discard will clear pcpu->pc_vfpcthread, and modify
  120          * and modify the control as needed.
  121          */
  122         ldr     r4, [r7, #(PC_VFPCTHREAD)]      /* this thread using vfp? */
  123         cmp     r0, r4
  124         bne     3f
  125         bl      _C_LABEL(vfp_discard)           /* yes, shut down vfp */
  126 3:
  127 #endif          /* VFP */
  128 
  129         ldr     r7, [r5, #(TD_PCB)]             /* r7 = new thread's PCB */
  130   
  131         /* Switch to lwp0 context */
  132 
  133         ldr     r9, .Lcpufuncs
  134 #if !defined(CPU_ARM11) && !defined(CPU_CORTEXA) && !defined(CPU_MV_PJ4B)
  135         mov     lr, pc
  136         ldr     pc, [r9, #CF_IDCACHE_WBINV_ALL]
  137 #endif
  138         ldr     r0, [r7, #(PCB_PL1VEC)]
  139         ldr     r1, [r7, #(PCB_DACR)]
  140         /*
  141          * r0 = Pointer to L1 slot for vector_page (or NULL)
  142          * r1 = lwp0's DACR
  143          * r5 = lwp0
  144          * r6 = exit func
  145          * r7 = lwp0's PCB
  146          * r9 = cpufuncs
  147          */
  148 
  149         /*
  150          * Ensure the vector table is accessible by fixing up lwp0's L1
  151          */
  152         cmp     r0, #0                  /* No need to fixup vector table? */
  153         ldrne   r3, [r0]                /* But if yes, fetch current value */
  154         ldrne   r2, [r7, #(PCB_L1VEC)]  /* Fetch new vector_page value */
  155         mcr     p15, 0, r1, c3, c0, 0   /* Update DACR for lwp0's context */
  156         cmpne   r3, r2                  /* Stuffing the same value? */
  157         strne   r2, [r0]                /* Store if not. */
  158 
  159 #ifdef PMAP_INCLUDE_PTE_SYNC
  160         /*
  161          * Need to sync the cache to make sure that last store is
  162          * visible to the MMU.
  163          */
  164         movne   r1, #4
  165         movne   lr, pc
  166         ldrne   pc, [r9, #CF_DCACHE_WB_RANGE]
  167 #endif /* PMAP_INCLUDE_PTE_SYNC */
  168 
  169         /*
  170          * Note: We don't do the same optimisation as cpu_switch() with
  171          * respect to avoiding flushing the TLB if we're switching to
  172          * the same L1 since this process' VM space may be about to go
  173          * away, so we don't want *any* turds left in the TLB.
  174          */
  175 
  176         /* Switch the memory to the new process */
  177         ldr     r0, [r7, #(PCB_PAGEDIR)]
  178         mov     lr, pc
  179         ldr     pc, [r9, #CF_CONTEXT_SWITCH]
  180 
  181         /* Restore all the save registers */
  182 #ifndef _ARM_ARCH_5E
  183         add     r1, r7, #PCB_R8
  184         ldmia   r1, {r8-r13}
  185 #else
  186         ldr     r8, [r7, #(PCB_R8)]
  187         ldr     r9, [r7, #(PCB_R9)]
  188         ldr     r10, [r7, #(PCB_R10)]
  189         ldr     r11, [r7, #(PCB_R11)]
  190         ldr     r12, [r7, #(PCB_R12)]
  191         ldr     r13, [r7, #(PCB_SP)]
  192 #endif
  193 
  194         /* We have a new curthread now so make a note it */
  195         GET_CURTHREAD_PTR(r6)
  196         str     r5, [r6]
  197 
  198         /* Set the new tp */
  199         ldr     r6, [r5, #(TD_MD + MD_TP)]
  200 #ifdef ARM_TP_ADDRESS
  201         ldr     r4, =ARM_TP_ADDRESS
  202         str     r6, [r4]
  203         ldr     r6, [r5, #(TD_MD + MD_RAS_START)]
  204         str     r6, [r4, #4] /* ARM_RAS_START */
  205         ldr     r6, [r5, #(TD_MD + MD_RAS_END)]
  206         str     r6, [r4, #8] /* ARM_RAS_END */
  207 #else
  208         mcr p15, 0, r6, c13, c0, 3
  209 #endif
  210         /* Hook in a new pcb */
  211         GET_PCPU(r6)
  212         str     r7, [r6, #PC_CURPCB]
  213 
  214         add     sp, sp, #4;
  215         ldmfd   sp!, {r4-r7, pc}
  216 END(cpu_throw)
  217 
  218 ENTRY(cpu_switch)
  219         stmfd   sp!, {r4-r7, lr}
  220         sub     sp, sp, #4;
  221 #ifdef __ARM_EABI__
  222         .save   {r4-r7, lr}
  223         .pad    #4
  224 #endif
  225 
  226         mov     r6, r2 /* Save the mutex */
  227 
  228 .Lswitch_resume:
  229         /* rem: r0 = old lwp */
  230         /* rem: interrupts are disabled */
  231 
  232         /* Process is now on a processor. */
  233         /* We have a new curthread now so make a note it */
  234         GET_CURTHREAD_PTR(r7)
  235         str     r1, [r7]
  236 
  237         /* Hook in a new pcb */
  238         GET_PCPU(r7)
  239         ldr     r2, [r1, #TD_PCB]
  240         str     r2, [r7, #PC_CURPCB]
  241 
  242         /* rem: r1 = new process */
  243         /* rem: interrupts are enabled */
  244 
  245         /* Stage two : Save old context */
  246 
  247         /* Get the user structure for the old thread. */
  248         ldr     r2, [r0, #(TD_PCB)]
  249         mov     r4, r0 /* Save the old thread. */
  250 
  251         /* Save all the registers in the old thread's pcb */
  252 #ifndef _ARM_ARCH_5E
  253         add     r7, r2, #(PCB_R8)
  254         stmia   r7, {r8-r13}
  255 #else
  256         strd    r8, [r2, #(PCB_R8)]
  257         strd    r10, [r2, #(PCB_R10)]
  258         strd    r12, [r2, #(PCB_R12)]
  259 #endif
  260         str     pc, [r2, #(PCB_PC)]
  261 
  262         /*
  263          * NOTE: We can now use r8-r13 until it is time to restore
  264          * them for the new process.
  265          */
  266 #ifdef ARM_TP_ADDRESS
  267         /* Store the old tp */
  268         ldr     r3, =ARM_TP_ADDRESS
  269         ldr     r9, [r3]
  270         str     r9, [r0, #(TD_MD + MD_TP)]
  271         ldr     r9, [r3, #4]
  272         str     r9, [r0, #(TD_MD + MD_RAS_START)]
  273         ldr     r9, [r3, #8]
  274         str     r9, [r0, #(TD_MD + MD_RAS_END)]
  275 
  276         /* Set the new tp */
  277         ldr     r9, [r1, #(TD_MD + MD_TP)]
  278         str     r9, [r3]
  279         ldr     r9, [r1, #(TD_MD + MD_RAS_START)]
  280         str     r9, [r3, #4]
  281         ldr     r9, [r1, #(TD_MD + MD_RAS_END)]
  282         str     r9, [r3, #8]
  283 #else
  284         /* Store the old tp */
  285         mrc p15, 0, r9, c13, c0, 3
  286         str     r9, [r0, #(TD_MD + MD_TP)]
  287 
  288         /* Set the new tp */
  289         ldr     r9, [r1, #(TD_MD + MD_TP)]
  290         mcr p15, 0, r9, c13, c0, 3
  291 #endif
  292         
  293         /* Get the user structure for the new process in r9 */
  294         ldr     r9, [r1, #(TD_PCB)]
  295 
  296         mrs     r3, cpsr
  297         /*
  298          * We can do that, since
  299          * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE
  300          */
  301         orr     r8, r3, #(PSR_UND32_MODE)
  302         msr     cpsr_c, r8
  303 
  304         str     sp, [r2, #(PCB_UND_SP)]
  305 
  306         msr     cpsr_c, r3              /* Restore the old mode */
  307         /* rem: r2 = old PCB */
  308         /* rem: r9 = new PCB */
  309         /* rem: interrupts are enabled */
  310 
  311 #ifdef VFP
  312         /*
  313          * vfp_store will clear pcpu->pc_vfpcthread, save 
  314          * registers and state, and modify the control as needed.
  315          * a future exception will bounce the backup settings in the fp unit.
  316          * XXX vfp_store can't change r4
  317          */
  318         GET_PCPU(r7)
  319         ldr     r8, [r7, #(PC_VFPCTHREAD)]
  320         cmp     r4, r8                          /* old thread used vfp? */
  321         bne     1f                              /* no, don't save */
  322         cmp     r1, r4                          /* same thread ? */
  323         beq     1f                              /* yes, skip vfp store */
  324 #ifdef SMP
  325         ldr     r8, [r7, #(PC_CPU)]             /* last used on this cpu? */
  326         ldr     r3, [r2, #(PCB_VFPCPU)]
  327         cmp     r8, r3          /* last cpu to use these registers? */
  328         bne     1f              /* no. these values are stale */
  329 #endif
  330         add     r0, r2, #(PCB_VFPSTATE)
  331         bl      _C_LABEL(vfp_store)
  332 1:
  333 #endif          /* VFP */
  334 
  335         /* r1 now free! */
  336 
  337         /* Third phase : restore saved context */
  338 
  339         /* rem: r2 = old PCB */
  340         /* rem: r9 = new PCB */
  341         /* rem: interrupts are enabled */
  342 
  343         ldr     r5, [r9, #(PCB_DACR)]           /* r5 = new DACR */
  344         mov     r2, #DOMAIN_CLIENT
  345         cmp     r5, r2, lsl #(PMAP_DOMAIN_KERNEL * 2) /* Sw to kernel thread? */
  346         beq     .Lcs_context_switched        /* Yup. Don't flush cache */
  347         mrc     p15, 0, r0, c3, c0, 0           /* r0 = old DACR */
  348         /*
  349          * Get the new L1 table pointer into r11.  If we're switching to
  350          * an LWP with the same address space as the outgoing one, we can
  351          * skip the cache purge and the TTB load.
  352          *
  353          * To avoid data dep stalls that would happen anyway, we try
  354          * and get some useful work done in the mean time.
  355          */
  356         mrc     p15, 0, r10, c2, c0, 0          /* r10 = old L1 */
  357         ldr     r11, [r9, #(PCB_PAGEDIR)]       /* r11 = new L1 */
  358 
  359 
  360         teq     r10, r11                        /* Same L1? */
  361         cmpeq   r0, r5                          /* Same DACR? */
  362         beq     .Lcs_context_switched           /* yes! */
  363 
  364 #if !defined(CPU_ARM11) && !defined(CPU_CORTEXA) && !defined(CPU_MV_PJ4B)
  365         /*
  366          * Definately need to flush the cache.
  367          */
  368 
  369         ldr     r1, .Lcpufuncs
  370         mov     lr, pc
  371         ldr     pc, [r1, #CF_IDCACHE_WBINV_ALL]
  372 #endif
  373 .Lcs_cache_purge_skipped:
  374         /* rem: r6 = lock */
  375         /* rem: r9 = new PCB */
  376         /* rem: r10 = old L1 */
  377         /* rem: r11 = new L1 */
  378 
  379         mov     r2, #0x00000000
  380         ldr     r7, [r9, #(PCB_PL1VEC)]
  381 
  382         /*
  383          * Ensure the vector table is accessible by fixing up the L1
  384          */
  385         cmp     r7, #0                  /* No need to fixup vector table? */
  386         ldrne   r2, [r7]                /* But if yes, fetch current value */
  387         ldrne   r0, [r9, #(PCB_L1VEC)]  /* Fetch new vector_page value */
  388         mcr     p15, 0, r5, c3, c0, 0   /* Update DACR for new context */
  389         cmpne   r2, r0                  /* Stuffing the same value? */
  390 #ifndef PMAP_INCLUDE_PTE_SYNC
  391         strne   r0, [r7]                /* Nope, update it */
  392 #else
  393         beq     .Lcs_same_vector
  394         str     r0, [r7]                /* Otherwise, update it */
  395 
  396         /*
  397          * Need to sync the cache to make sure that last store is
  398          * visible to the MMU.
  399          */
  400         ldr     r2, .Lcpufuncs
  401         mov     r0, r7
  402         mov     r1, #4
  403         mov     lr, pc
  404         ldr     pc, [r2, #CF_DCACHE_WB_RANGE]
  405 
  406 .Lcs_same_vector:
  407 #endif /* PMAP_INCLUDE_PTE_SYNC */
  408 
  409         cmp     r10, r11                /* Switching to the same L1? */
  410         ldr     r10, .Lcpufuncs
  411         beq     .Lcs_same_l1            /* Yup. */
  412         /*
  413          * Do a full context switch, including full TLB flush.
  414          */
  415         mov     r0, r11
  416         mov     lr, pc
  417         ldr     pc, [r10, #CF_CONTEXT_SWITCH]
  418 
  419         b       .Lcs_context_switched
  420 
  421         /*
  422          * We're switching to a different process in the same L1.
  423          * In this situation, we only need to flush the TLB for the
  424          * vector_page mapping, and even then only if r7 is non-NULL.
  425          */
  426 .Lcs_same_l1:
  427         cmp     r7, #0
  428         movne   r0, #0                  /* We *know* vector_page's VA is 0x0 */
  429         movne   lr, pc
  430         ldrne   pc, [r10, #CF_TLB_FLUSHID_SE]
  431         /*
  432          * We can do that, since
  433          * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE
  434          */
  435 
  436 .Lcs_context_switched:
  437 
  438         /* Release the old thread */
  439         str     r6, [r4, #TD_LOCK]
  440 #if defined(SCHED_ULE) && defined(SMP)
  441         ldr     r6, .Lblocked_lock
  442         GET_CURTHREAD_PTR(r3)
  443 
  444 1:
  445         ldr     r4, [r3, #TD_LOCK]
  446         cmp     r4, r6
  447         beq     1b
  448 #endif
  449         
  450         /* XXXSCW: Safe to re-enable FIQs here */
  451 
  452         /* rem: r9 = new PCB */
  453 
  454         mrs     r3, cpsr
  455         /*
  456          * We can do that, since
  457          * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE
  458          */
  459         orr     r2, r3, #(PSR_UND32_MODE)
  460         msr     cpsr_c, r2
  461 
  462         ldr     sp, [r9, #(PCB_UND_SP)]
  463 
  464         msr     cpsr_c, r3              /* Restore the old mode */
  465         /* Restore all the save registers */
  466 #ifndef _ARM_ARCH_5E
  467         add     r7, r9, #PCB_R8
  468         ldmia   r7, {r8-r13}
  469         sub     r7, r7, #PCB_R8         /* restore PCB pointer */
  470 #else
  471         mov     r7, r9
  472         ldr     r8, [r7, #(PCB_R8)]
  473         ldr     r9, [r7, #(PCB_R9)]
  474         ldr     r10, [r7, #(PCB_R10)]
  475         ldr     r11, [r7, #(PCB_R11)]
  476         ldr     r12, [r7, #(PCB_R12)]
  477         ldr     r13, [r7, #(PCB_SP)]
  478 #endif
  479 
  480         /* rem: r5 = new lwp's proc */
  481         /* rem: r6 = lock */
  482         /* rem: r7 = new PCB */
  483 
  484 .Lswitch_return:
  485 
  486         /*
  487          * Pull the registers that got pushed when either savectx() or
  488          * cpu_switch() was called and return.
  489          */
  490         add     sp, sp, #4;
  491         ldmfd   sp!, {r4-r7, pc}
  492 #ifdef DIAGNOSTIC
  493 .Lswitch_bogons:
  494         adr     r0, .Lswitch_panic_str
  495         bl      _C_LABEL(panic)
  496 1:      nop
  497         b       1b
  498 
  499 .Lswitch_panic_str:
  500         .asciz  "cpu_switch: sched_qs empty with non-zero sched_whichqs!\n"
  501 #endif
  502 END(cpu_switch)
  503 
  504 ENTRY(savectx)
  505         stmfd   sp!, {r4-r7, lr}
  506         sub     sp, sp, #4
  507         /*
  508          * r0 = pcb
  509          */
  510         /* Store all the registers in the process's pcb */
  511         add     r2, r0, #(PCB_R8)
  512         stmia   r2, {r8-r13}
  513 #ifdef VFP
  514         /*
  515          * vfp_store will clear pcpu->pc_vfpcthread, save 
  516          * registers and state, and modify the control as needed.
  517          * a future exception will bounce the backup settings in the fp unit.
  518          */
  519         GET_PCPU(r7)
  520         ldr     r4, [r7, #(PC_VFPCTHREAD)]      /* vfp thread */
  521         ldr     r2, [r7, #(PC_CURTHREAD)]       /* current thread */
  522         cmp     r4, r2
  523         bne     1f
  524 #ifdef SMP
  525         ldr     r2, [r7, #(PC_CPU)]     /* last used on this cpu? */
  526         ldr     r3, [r0, #(PCB_VFPCPU)]
  527         cmp     r2, r3
  528         bne     1f              /* no. these values are stale */
  529 #endif
  530         add     r0, r0, #(PCB_VFPSTATE)
  531         bl      _C_LABEL(vfp_store)
  532 1:
  533 #endif          /* VFP */
  534         add     sp, sp, #4;
  535         ldmfd   sp!, {r4-r7, pc}
  536 END(savectx)
  537 
  538 ENTRY(fork_trampoline)
  539         STOP_UNWINDING  /* Can't unwind beyond the thread enty point */
  540         mov     r1, r5
  541         mov     r2, sp
  542         mov     r0, r4
  543         mov     fp, #0
  544         bl      _C_LABEL(fork_exit)
  545         /* Kill irq"s */
  546         mrs     r0, cpsr
  547         orr     r0, r0, #(I32_bit|F32_bit)
  548         msr     cpsr_c, r0
  549         DO_AST
  550         PULLFRAME
  551 
  552         movs    pc, lr                  /* Exit */
  553 
  554 AST_LOCALS
  555 END(fork_trampoline)
  556 

Cache object: c631b029e62f8899ead03592ae20ec82


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.