(c) versus (C)
[helenos.git] / kernel / arch / ia64 / src / asm.S
blob16c27a3d7828a50fa7591cfd3775278f2292fcec
2 # Copyright (c) 2005 Jakub Jermar
3 # All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
9 # - Redistributions of source code must retain the above copyright
10 #   notice, this list of conditions and the following disclaimer.
11 # - Redistributions in binary form must reproduce the above copyright
12 #   notice, this list of conditions and the following disclaimer in the
13 #   documentation and/or other materials provided with the distribution.
14 # - The name of the author may not be used to endorse or promote products
15 #   derived from this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <arch/register.h>
31 .text
33 /** Copy memory from/to userspace.
34  *
35  * This memcpy() has been taken from the assembler output of
36  * the generic _memcpy() and modified to have the failover part.
37  *
38  * @param in0 Destination address.
39  * @param in1 Source address.
40  * @param in2 Number of byte to copy.
41  */
42 .global memcpy
43 .global memcpy_from_uspace
44 .global memcpy_to_uspace
45 .global memcpy_from_uspace_failover_address
46 .global memcpy_to_uspace_failover_address
47 memcpy:
48 memcpy_from_uspace:
49 memcpy_to_uspace:
50         alloc loc0 = ar.pfs, 3, 1, 0, 0
52         adds r14 = 7, in1
53         mov r2 = ar.lc
54         mov r8 = in1 ;;
55         and r14 = -8, r14 ;;
56         cmp.ne p6, p7 = r14, in1
57 (p7)    br.cond.dpnt 3f ;;
59         cmp.ne p6, p7 = 0, in2
60 (p7)    br.cond.dpnt 2f ;;
61 (p6)    adds r14 = -1, in2
62 (p6)    mov r16 = r0
63 (p6)    mov r17 = r0 ;;
64 (p6)    mov ar.lc = r14
66         add r14 = r16, r8
67         add r15 = r16, in0
68         adds r17 = 1, r17 ;;
69         ld1 r14 = [r14]
70         mov r16 = r17 ;;
71         st1 [r15] = r14
72         br.cloop.sptk.few 1b ;;
74         mov ar.lc = r2
76         mov ar.pfs = loc0
77         br.ret.sptk.many rp
79         adds r14 = 7, in0 ;;
80         and r14 = -8, r14 ;;
81         cmp.eq p6, p7 = r14, in0
82 (p7)    br.cond.dptk 0b
83         shr.u r18 = in2, 3 ;;
84         cmp.ne p6, p7 = 0, r18
85 (p7)    br.cond.dpnt 5f ;;
86 (p6)    adds r14 = -1, r18
87 (p6)    mov r16 = r0
88 (p6)    mov r17 = r0 ;;
89 (p6)    mov ar.lc = r14
91         shladd r14 = r16, 3, r0
92         adds r16 = 1, r17 ;;
93         add r15 = r8, r14
94         add r14 = in0, r14
95         mov r17 = r16 ;;
96         ld8 r15 = [r15] ;;
97         st8 [r14] = r15
98         br.cloop.sptk.few 4b
100         and r15 = 7, in2
101         shladd r14 = r18, 3, r0
102         mov r16 = r0
103         mov r18 = r0 ;;
104         cmp.eq p6, p7 = 0, r15
105         add in0 = r14, in0
106         adds r15 = -1, r15
107         add r17 = r14, r8
108 (p6)    br.cond.dpnt 2b ;;
109         mov ar.lc = r15
111         add r14 = r16, r17
112         add r15 = r16, in0
113         adds r16 = 1, r18 ;;
114         ld1 r14 = [r14]
115         mov r18 = r16 ;;
116         st1 [r15] = r14
117         br.cloop.sptk.few 6b ;;
118         mov ar.lc = r2
120         mov ar.pfs = loc0
121         br.ret.sptk.many rp
122         
123 memcpy_from_uspace_failover_address:
124 memcpy_to_uspace_failover_address:
125         mov r8 = r0                     /* return 0 on failure */
126         mov ar.pfs = loc0
127         br.ret.sptk.many rp
129 .global memsetb
130 memsetb:
131         br _memsetb
133 .global cpu_halt
134 cpu_halt:
135         br cpu_halt
137 .global panic_printf
138 panic_printf:
139         {
140                 br.call.sptk.many b0=printf
141         }
142         br halt
144 /** Switch to userspace - low level code.
146  * @param in0 Userspace entry point address.
147  * @param in1 Userspace stack pointer address.
148  * @param in2 Userspace register stack pointer address.
149  * @param in3 Userspace address of thread uspace_arg_t structure.
150  * @param in4 Value to be stored in IPSR.
151  * @param in5 Value to be stored in RSC.
152  */
153 .global switch_to_userspace
154 switch_to_userspace:
155         alloc loc0 = ar.pfs, 6, 3, 0, 0
156         rsm (PSR_IC_MASK | PSR_I_MASK)          /* disable interruption collection and interrupts */
157         srlz.d ;;
158         srlz.i ;;
159         
160         mov cr.ipsr = in4
161         mov cr.iip = in0
162         mov r12 = in1
164         xor r1 = r1, r1
165         
166         mov loc1 = cr.ifs
167         movl loc2 = PFM_MASK ;;
168         and loc1 = loc2, loc1 ;;
169         mov cr.ifs = loc1 ;;                    /* prevent decrementing BSP by rfi */
171         invala
172         
173         mov loc1 = ar.rsc ;;
174         and loc1 = ~3, loc1 ;;                  
175         mov ar.rsc = loc1 ;;                    /* put RSE into enforced lazy mode */
177         flushrs ;;
178         
179         mov ar.bspstore = in2 ;;
180         mov ar.rsc = in5 ;;
181         
182         mov r8 = in3
183         
184         rfi ;;