etc/services - sync with NetBSD-8
[minix.git] / minix / lib / libc / arch / arm / sys / ucontext.S
blob48a29718c7f2f011a02e9a7cd19c9f13ea86da0d
1 #include <machine/asm.h>
2 #include <ucontextoffsets.h>
5 IMPORT(getuctx)
6 IMPORT(setuctx)
7 IMPORT(resumecontext)
10 /* int getcontext(ucontext_t *ucp)
11  *      Initialise the structure pointed to by ucp to the current user context
12  *      of the calling thread. */
13 ENTRY(getcontext)
14 ENTRY(_getcontext)
15         /* In case a process does not use the FPU and is neither interested in
16          * saving its signal mask, then we can skip the context switch to
17          * PM and kernel altogether and only save general-purpose registers. */
19         mov r3, lr              /* Save return address:
20                                  * When setcontext or swapcontext is called,
21                                  * we jump to this address and continue
22                                  * running. */
24         /* r0 = ucp */
26         /* Check null pointer */
27         cmp r0, #0                      /* ucp == NULL? */
28         bne 3f                          /* Not null, continue */
29         mov r1, #EFAULT
30         ldr r2, =_C_LABEL(errno)
31         str r1, [r2]                    /* errno = EFAULT */
32         mov r0, #-1                     /* return -1 */
33         bx lr
35 3:      /* Check flags */
36         ldr r1, [r0, #UC_FLAGS]         /* r1 = ucp->uc_flags */
37         and r1, r1, #[_UC_IGNFPU|_UC_IGNSIGM]
38         cmp r1, #[_UC_IGNFPU|_UC_IGNSIGM] /* Allowed to ignore both? */
39         beq 1f                          /* If so, skip getuctx */
42         push {r0, r3}
43         bl _C_LABEL(getuctx)            /* getuctx(ucp) */
44         pop {r0, r3}
47         /* Save the context */
48         mov lr, r3              /* Restore lr */
49         str lr, [r0, #LRREG]    /* Save lr */
50         str lr, [r0, #PCREG]    /* Save real RTA in mcp struct */
51         str sp, [r0, #SPREG]    /* Save stack pointer */
52         str fp, [r0, #FPREG]            /* Save fp */
53         str r4, [r0, #REG4]             /* Save r4 */
54         str r5, [r0, #REG5]             /* Save r5 */
55         str r6, [r0, #REG6]             /* Save r6 */
56         str r7, [r0, #REG7]             /* Save r7 */
57         str r8, [r0, #REG8]             /* Save r8 */
58         str r9, [r0, #REG9]             /* Save r9 */
59         str r10, [r0, #REG10]           /* Save r10 */
61         ldr r1, =MCF_MAGIC
62         str r1, [r0, #MAGIC]    /* Set magic value */
64         mov r1, #0
65         str r1, [r0, #REG0]             /* Return 0 */
66         mov r0, #0                      /* Return 0 */
69         bx lr                   /* Restore return address */
72 /* int setcontext(const ucontext_t *ucp)
73  *      Restore the user context pointed to by ucp. A successful call to
74  *      setcontext does not return; program execution resumes at the point
75  *      specified by the ucp argument. If ucp was created with getcontext(),
76  *      program execution continues as if the corresponding call of getcontext()
77  *      had just returned. If ucp was created with makecontext(), program
78  *      execution continues with the function passed to makecontext(). */
79 ENTRY(setcontext)
80         /* In case a process does not use the FPU and is neither interested in
81          * restoring its signal mask, then we can skip the context switch to
82          * PM and kernel altogether and restore state here. */
84         /* r0 = ucp */
86         /* Check null pointer */
87         cmp r0, #0                      /* ucp == NULL? */
88         bne 3f                          /* Not null, continue */
89         mov r1, #EFAULT
90         ldr r2, =_C_LABEL(errno)
91         str r1, [r2]                    /* errno = EFAULT */
92         mov r0, #-1                     /* return -1 */
93         bx lr
95 3:      /* Check flags */
96         ldr r1, [r0, #MAGIC]            /* r1 = ucp->mc_context.mc_magic */
97         ldr r2, =MCF_MAGIC
98         cmp r1, r2              /* is the magic value set (is context valid)?*/
99         beq 4f                          /* is set, proceed */
100         mov r1, #EINVAL                 /* not set, return error code */
101         ldr r2, =_C_LABEL(errno)
102         str r1, [r2]                    /* errno = EINVAL */
103         mov r0, #-1                     /* return -1 */
104         bx lr
107 4:      ldr r1, [r0, #UC_FLAGS]         /* r1 = ucp->uc_flags */
108         and r1, r1, #[_UC_IGNFPU|_UC_IGNSIGM]
109         cmp r1, #[_UC_IGNFPU|_UC_IGNSIGM] /* Allowed to ignore both? */
110         beq 1f                  /* Neither are set, so don't bother restoring FPU
111                                  * state and signal mask */
113         push {r0, r3}
114 0:      bl _C_LABEL(setuctx)            /* setuctx(ucp) */
115         pop {r0, r3}
117 1:      /* Restore the registers */
118         ldr r4,  [r0, #REG4]            /* Restore r4 */
119         ldr r5,  [r0, #REG5]            /* Restore r5 */
120         ldr r6,  [r0, #REG6]            /* Restore r6 */
121         ldr r7,  [r0, #REG7]            /* Restore r7 */
122         ldr r8,  [r0, #REG8]            /* Restore r8 */
123         ldr r9,  [r0, #REG9]            /* Restore r9 */
124         ldr r10, [r0, #REG10]           /* Restore r10 */
125         ldr r12, [r0, #REG12]           /* Restore r12 */
126         ldr fp,  [r0, #FPREG]           /* Restore fp */
127         ldr sp,  [r0, #SPREG]           /* Restore sp */
128         ldr lr,  [r0, #LRREG]           /* Restore lr */
129         mov r3, r0
130         ldr r0,  [r3, #REG0]            /* Restore r0 */
132         ldr pc,  [r3, #PCREG]           /* Restore pc */
135 /* void ctx_start()
136  *      A wrapper to call resumecontext. Makecontext puts the ucp in r4.
137  *      This function moves the ucp into r0 so that the ucp is the first
138  *      parameter for resumecontext. The call to resumecontext will start
139  *      the next context in the linked list (or exit the program if there
140  *      is no context). */
141 ENTRY(ctx_start)
142         mov r0, r4
143         b _C_LABEL(resumecontext)