upload tizen1.0 source
[kernel/linux-2.6.36.git] / arch / tile / mm / migrate_32.S
1 /*
2  * Copyright 2010 Tilera Corporation. All Rights Reserved.
3  *
4  *   This program is free software; you can redistribute it and/or
5  *   modify it under the terms of the GNU General Public License
6  *   as published by the Free Software Foundation, version 2.
7  *
8  *   This program is distributed in the hope that it will be useful, but
9  *   WITHOUT ANY WARRANTY; without even the implied warranty of
10  *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11  *   NON INFRINGEMENT.  See the GNU General Public License for
12  *   more details.
13  *
14  * This routine is a helper for migrating the home of a set of pages to
15  * a new cpu.  See the documentation in homecache.c for more information.
16  */
17
18 #include <linux/linkage.h>
19 #include <linux/threads.h>
20 #include <asm/page.h>
21 #include <asm/types.h>
22 #include <asm/asm-offsets.h>
23 #include <hv/hypervisor.h>
24
25         .text
26
27 /*
28  * First, some definitions that apply to all the code in the file.
29  */
30
31 /* Locals (caller-save) */
32 #define r_tmp           r10
33 #define r_save_sp       r11
34
35 /* What we save where in the stack frame; must include all callee-saves. */
36 #define FRAME_SP        4
37 #define FRAME_R30       8
38 #define FRAME_R31       12
39 #define FRAME_R32       16
40 #define FRAME_R33       20
41 #define FRAME_R34       24
42 #define FRAME_R35       28
43 #define FRAME_SIZE      32
44
45
46
47
48 /*
49  * On entry:
50  *
51  *   r0 low word of the new context PA to install (moved to r_context_lo)
52  *   r1 high word of the new context PA to install (moved to r_context_hi)
53  *   r2 low word of PTE to use for context access (moved to r_access_lo)
54  *   r3 high word of PTE to use for context access (moved to r_access_lo)
55  *   r4 ASID to use for new context (moved to r_asid)
56  *   r5 pointer to cpumask with just this cpu set in it (r_my_cpumask)
57  */
58
59 /* Arguments (caller-save) */
60 #define r_context_lo_in r0
61 #define r_context_hi_in r1
62 #define r_access_lo_in  r2
63 #define r_access_hi_in  r3
64 #define r_asid_in       r4
65 #define r_my_cpumask    r5
66
67 /* Locals (callee-save); must not be more than FRAME_xxx above. */
68 #define r_save_ics      r30
69 #define r_context_lo    r31
70 #define r_context_hi    r32
71 #define r_access_lo     r33
72 #define r_access_hi     r34
73 #define r_asid          r35
74
75 STD_ENTRY(flush_and_install_context)
76         /*
77          * Create a stack frame; we can't touch it once we flush the
78          * cache until we install the new page table and flush the TLB.
79          */
80         {
81          move r_save_sp, sp
82          sw sp, lr
83          addi sp, sp, -FRAME_SIZE
84         }
85         addi r_tmp, sp, FRAME_SP
86         {
87          sw r_tmp, r_save_sp
88          addi r_tmp, sp, FRAME_R30
89         }
90         {
91          sw r_tmp, r30
92          addi r_tmp, sp, FRAME_R31
93         }
94         {
95          sw r_tmp, r31
96          addi r_tmp, sp, FRAME_R32
97         }
98         {
99          sw r_tmp, r32
100          addi r_tmp, sp, FRAME_R33
101         }
102         {
103          sw r_tmp, r33
104          addi r_tmp, sp, FRAME_R34
105         }
106         {
107          sw r_tmp, r34
108          addi r_tmp, sp, FRAME_R35
109         }
110         sw r_tmp, r35
111
112         /* Move some arguments to callee-save registers. */
113         {
114          move r_context_lo, r_context_lo_in
115          move r_context_hi, r_context_hi_in
116         }
117         {
118          move r_access_lo, r_access_lo_in
119          move r_access_hi, r_access_hi_in
120         }
121         move r_asid, r_asid_in
122
123         /* Disable interrupts, since we can't use our stack. */
124         {
125          mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
126          movei r_tmp, 1
127         }
128         mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
129
130         /* First, flush our L2 cache. */
131         {
132          move r0, zero  /* cache_pa */
133          move r1, zero
134         }
135         {
136          auli r2, zero, ha16(HV_FLUSH_EVICT_L2)  /* cache_control */
137          move r3, r_my_cpumask  /* cache_cpumask */
138         }
139         {
140          move r4, zero  /* tlb_va */
141          move r5, zero  /* tlb_length */
142         }
143         {
144          move r6, zero  /* tlb_pgsize */
145          move r7, zero  /* tlb_cpumask */
146         }
147         {
148          move r8, zero  /* asids */
149          move r9, zero  /* asidcount */
150         }
151         jal hv_flush_remote
152         bnz r0, .Ldone
153
154         /* Now install the new page table. */
155         {
156          move r0, r_context_lo
157          move r1, r_context_hi
158         }
159         {
160          move r2, r_access_lo
161          move r3, r_access_hi
162         }
163         {
164          move r4, r_asid
165          movei r5, HV_CTX_DIRECTIO
166         }
167         jal hv_install_context
168         bnz r0, .Ldone
169
170         /* Finally, flush the TLB. */
171         {
172          movei r0, 0   /* preserve_global */
173          jal hv_flush_all
174         }
175
176 .Ldone:
177         /* Reset interrupts back how they were before. */
178         mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
179
180         /* Restore the callee-saved registers and return. */
181         addli lr, sp, FRAME_SIZE
182         {
183          lw lr, lr
184          addli r_tmp, sp, FRAME_R30
185         }
186         {
187          lw r30, r_tmp
188          addli r_tmp, sp, FRAME_R31
189         }
190         {
191          lw r31, r_tmp
192          addli r_tmp, sp, FRAME_R32
193         }
194         {
195          lw r32, r_tmp
196          addli r_tmp, sp, FRAME_R33
197         }
198         {
199          lw r33, r_tmp
200          addli r_tmp, sp, FRAME_R34
201         }
202         {
203          lw r34, r_tmp
204          addli r_tmp, sp, FRAME_R35
205         }
206         {
207          lw r35, r_tmp
208          addi sp, sp, FRAME_SIZE
209         }
210         jrp lr
211         STD_ENDPROC(flush_and_install_context)