~ubuntu-branches/ubuntu/saucy/linux-ti-omap4/saucy-proposed

« back to all changes in this revision

Viewing changes to arch/tile/kernel/relocate_kernel.S

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati, Stefan Bader, Upstream Kernel Changes
  • Date: 2012-08-15 17:17:43 UTC
  • Revision ID: package-import@ubuntu.com-20120815171743-h5wnuf51xe7pvdid
Tags: 3.5.0-207.13
[ Paolo Pisati ]

* Start new release

[ Stefan Bader ]

* (config) Enable getabis to use local package copies

[ Upstream Kernel Changes ]

* fixup: gargabe collect iva_seq[0|1] init
* [Config] enable all SND_OMAP_SOC_*s
* fixup: cm2xxx_3xxx.o is needed for omap2_cm_read|write_reg
* fixup: add some snd_soc_dai* helper functions
* fixup: s/snd_soc_dpcm_params/snd_soc_dpcm/g
* fixup: typo, no_host_mode and useless SDP4430 init
* fixup: enable again aess hwmod

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 * copy new kernel into place and then call hv_reexec
15
 
 *
16
 
 */
17
 
 
18
 
#include <linux/linkage.h>
19
 
#include <arch/chip.h>
20
 
#include <asm/page.h>
21
 
#include <hv/hypervisor.h>
22
 
 
23
 
#define ___hvb  MEM_SV_INTRPT + HV_GLUE_START_CPA
24
 
 
25
 
#define ___hv_dispatch(f) (___hvb + (HV_DISPATCH_ENTRY_SIZE * f))
26
 
 
27
 
#define ___hv_console_putc ___hv_dispatch(HV_DISPATCH_CONSOLE_PUTC)
28
 
#define ___hv_halt         ___hv_dispatch(HV_DISPATCH_HALT)
29
 
#define ___hv_reexec       ___hv_dispatch(HV_DISPATCH_REEXEC)
30
 
#define ___hv_flush_remote ___hv_dispatch(HV_DISPATCH_FLUSH_REMOTE)
31
 
 
32
 
#undef RELOCATE_NEW_KERNEL_VERBOSE
33
 
 
34
 
STD_ENTRY(relocate_new_kernel)
35
 
 
36
 
        move    r30, r0         /* page list */
37
 
        move    r31, r1         /* address of page we are on */
38
 
        move    r32, r2         /* start address of new kernel */
39
 
 
40
 
        shri    r1, r1, PAGE_SHIFT
41
 
        addi    r1, r1, 1
42
 
        shli    sp, r1, PAGE_SHIFT
43
 
        addi    sp, sp, -8
44
 
        /* we now have a stack (whether we need one or not) */
45
 
 
46
 
        moveli  r40, lo16(___hv_console_putc)
47
 
        auli    r40, r40, ha16(___hv_console_putc)
48
 
 
49
 
#ifdef RELOCATE_NEW_KERNEL_VERBOSE
50
 
        moveli  r0, 'r'
51
 
        jalr    r40
52
 
 
53
 
        moveli  r0, '_'
54
 
        jalr    r40
55
 
 
56
 
        moveli  r0, 'n'
57
 
        jalr    r40
58
 
 
59
 
        moveli  r0, '_'
60
 
        jalr    r40
61
 
 
62
 
        moveli  r0, 'k'
63
 
        jalr    r40
64
 
 
65
 
        moveli  r0, '\n'
66
 
        jalr    r40
67
 
#endif
68
 
 
69
 
        /*
70
 
         * Throughout this code r30 is pointer to the element of page
71
 
         * list we are working on.
72
 
         *
73
 
         * Normally we get to the next element of the page list by
74
 
         * incrementing r30 by four.  The exception is if the element
75
 
         * on the page list is an IND_INDIRECTION in which case we use
76
 
         * the element with the low bits masked off as the new value
77
 
         * of r30.
78
 
         *
79
 
         * To get this started, we need the value passed to us (which
80
 
         * will always be an IND_INDIRECTION) in memory somewhere with
81
 
         * r30 pointing at it.  To do that, we push the value passed
82
 
         * to us on the stack and make r30 point to it.
83
 
         */
84
 
 
85
 
        sw      sp, r30
86
 
        move    r30, sp
87
 
        addi    sp, sp, -8
88
 
 
89
 
#if CHIP_HAS_CBOX_HOME_MAP()
90
 
        /*
91
 
         * On TILEPro, we need to flush all tiles' caches, since we may
92
 
         * have been doing hash-for-home caching there.  Note that we
93
 
         * must do this _after_ we're completely done modifying any memory
94
 
         * other than our output buffer (which we know is locally cached).
95
 
         * We want the caches to be fully clean when we do the reexec,
96
 
         * because the hypervisor is going to do this flush again at that
97
 
         * point, and we don't want that second flush to overwrite any memory.
98
 
         */
99
 
        {
100
 
         move   r0, zero         /* cache_pa */
101
 
         move   r1, zero
102
 
        }
103
 
        {
104
 
         auli   r2, zero, ha16(HV_FLUSH_EVICT_L2) /* cache_control */
105
 
         movei  r3, -1           /* cache_cpumask; -1 means all client tiles */
106
 
        }
107
 
        {
108
 
         move   r4, zero         /* tlb_va */
109
 
         move   r5, zero         /* tlb_length */
110
 
        }
111
 
        {
112
 
         move   r6, zero         /* tlb_pgsize */
113
 
         move   r7, zero         /* tlb_cpumask */
114
 
        }
115
 
        {
116
 
         move   r8, zero         /* asids */
117
 
         moveli r20, lo16(___hv_flush_remote)
118
 
        }
119
 
        {
120
 
         move   r9, zero         /* asidcount */
121
 
         auli   r20, r20, ha16(___hv_flush_remote)
122
 
        }
123
 
 
124
 
        jalr    r20
125
 
#endif
126
 
 
127
 
        /* r33 is destination pointer, default to zero */
128
 
 
129
 
        moveli  r33, 0
130
 
 
131
 
.Lloop: lw      r10, r30
132
 
 
133
 
        andi    r9, r10, 0xf    /* low 4 bits tell us what type it is */
134
 
        xor     r10, r10, r9    /* r10 is now value with low 4 bits stripped */
135
 
 
136
 
        seqi    r0, r9, 0x1     /* IND_DESTINATION */
137
 
        bzt     r0, .Ltry2
138
 
 
139
 
        move    r33, r10
140
 
 
141
 
#ifdef RELOCATE_NEW_KERNEL_VERBOSE
142
 
        moveli  r0, 'd'
143
 
        jalr    r40
144
 
#endif
145
 
 
146
 
        addi    r30, r30, 4
147
 
        j       .Lloop
148
 
 
149
 
.Ltry2:
150
 
        seqi    r0, r9, 0x2     /* IND_INDIRECTION */
151
 
        bzt     r0, .Ltry4
152
 
 
153
 
        move    r30, r10
154
 
 
155
 
#ifdef RELOCATE_NEW_KERNEL_VERBOSE
156
 
        moveli  r0, 'i'
157
 
        jalr    r40
158
 
#endif
159
 
 
160
 
        j       .Lloop
161
 
 
162
 
.Ltry4:
163
 
        seqi    r0, r9, 0x4     /* IND_DONE */
164
 
        bzt     r0, .Ltry8
165
 
 
166
 
        mf
167
 
 
168
 
#ifdef RELOCATE_NEW_KERNEL_VERBOSE
169
 
        moveli  r0, 'D'
170
 
        jalr    r40
171
 
        moveli  r0, '\n'
172
 
        jalr    r40
173
 
#endif
174
 
 
175
 
        move    r0, r32
176
 
        moveli  r1, 0           /* arg to hv_reexec is 64 bits */
177
 
 
178
 
        moveli  r41, lo16(___hv_reexec)
179
 
        auli    r41, r41, ha16(___hv_reexec)
180
 
 
181
 
        jalr    r41
182
 
 
183
 
        /* we should not get here */
184
 
 
185
 
        moveli  r0, '?'
186
 
        jalr    r40
187
 
        moveli  r0, '\n'
188
 
        jalr    r40
189
 
 
190
 
        j       .Lhalt
191
 
 
192
 
.Ltry8: seqi    r0, r9, 0x8     /* IND_SOURCE */
193
 
        bz      r0, .Lerr       /* unknown type */
194
 
 
195
 
        /* copy page at r10 to page at r33 */
196
 
 
197
 
        move    r11, r33
198
 
 
199
 
        moveli  r0, lo16(PAGE_SIZE)
200
 
        auli    r0, r0, ha16(PAGE_SIZE)
201
 
        add     r33, r33, r0
202
 
 
203
 
        /* copy word at r10 to word at r11 until r11 equals r33 */
204
 
 
205
 
        /* We know page size must be multiple of 16, so we can unroll
206
 
         * 16 times safely without any edge case checking.
207
 
         *
208
 
         * Issue a flush of the destination every 16 words to avoid
209
 
         * incoherence when starting the new kernel.  (Now this is
210
 
         * just good paranoia because the hv_reexec call will also
211
 
         * take care of this.)
212
 
         */
213
 
 
214
 
1:
215
 
        { lw    r0, r10; addi   r10, r10, 4 }
216
 
        { sw    r11, r0; addi   r11, r11, 4 }
217
 
        { lw    r0, r10; addi   r10, r10, 4 }
218
 
        { sw    r11, r0; addi   r11, r11, 4 }
219
 
        { lw    r0, r10; addi   r10, r10, 4 }
220
 
        { sw    r11, r0; addi   r11, r11, 4 }
221
 
        { lw    r0, r10; addi   r10, r10, 4 }
222
 
        { sw    r11, r0; addi   r11, r11, 4 }
223
 
        { lw    r0, r10; addi   r10, r10, 4 }
224
 
        { sw    r11, r0; addi   r11, r11, 4 }
225
 
        { lw    r0, r10; addi   r10, r10, 4 }
226
 
        { sw    r11, r0; addi   r11, r11, 4 }
227
 
        { lw    r0, r10; addi   r10, r10, 4 }
228
 
        { sw    r11, r0; addi   r11, r11, 4 }
229
 
        { lw    r0, r10; addi   r10, r10, 4 }
230
 
        { sw    r11, r0; addi   r11, r11, 4 }
231
 
        { lw    r0, r10; addi   r10, r10, 4 }
232
 
        { sw    r11, r0; addi   r11, r11, 4 }
233
 
        { lw    r0, r10; addi   r10, r10, 4 }
234
 
        { sw    r11, r0; addi   r11, r11, 4 }
235
 
        { lw    r0, r10; addi   r10, r10, 4 }
236
 
        { sw    r11, r0; addi   r11, r11, 4 }
237
 
        { lw    r0, r10; addi   r10, r10, 4 }
238
 
        { sw    r11, r0; addi   r11, r11, 4 }
239
 
        { lw    r0, r10; addi   r10, r10, 4 }
240
 
        { sw    r11, r0; addi   r11, r11, 4 }
241
 
        { lw    r0, r10; addi   r10, r10, 4 }
242
 
        { sw    r11, r0; addi   r11, r11, 4 }
243
 
        { lw    r0, r10; addi   r10, r10, 4 }
244
 
        { sw    r11, r0; addi   r11, r11, 4 }
245
 
        { lw    r0, r10; addi   r10, r10, 4 }
246
 
        { sw    r11, r0 }
247
 
        { flush r11    ; addi   r11, r11, 4 }
248
 
 
249
 
        seq     r0, r33, r11
250
 
        bzt     r0, 1b
251
 
 
252
 
#ifdef RELOCATE_NEW_KERNEL_VERBOSE
253
 
        moveli  r0, 's'
254
 
        jalr    r40
255
 
#endif
256
 
 
257
 
        addi    r30, r30, 4
258
 
        j       .Lloop
259
 
 
260
 
 
261
 
.Lerr:  moveli  r0, 'e'
262
 
        jalr    r40
263
 
        moveli  r0, 'r'
264
 
        jalr    r40
265
 
        moveli  r0, 'r'
266
 
        jalr    r40
267
 
        moveli  r0, '\n'
268
 
        jalr    r40
269
 
.Lhalt:
270
 
        moveli  r41, lo16(___hv_halt)
271
 
        auli    r41, r41, ha16(___hv_halt)
272
 
 
273
 
        jalr    r41
274
 
        STD_ENDPROC(relocate_new_kernel)
275
 
 
276
 
        .section .rodata,"a"
277
 
 
278
 
        .globl relocate_new_kernel_size
279
 
relocate_new_kernel_size:
280
 
        .long .Lend_relocate_new_kernel - relocate_new_kernel