regulator: Merge up pending fix
[linux-2.6-microblaze.git] / arch / parisc / kernel / head.S
1 /* This file is subject to the terms and conditions of the GNU General Public
2  * License.  See the file "COPYING" in the main directory of this archive
3  * for more details.
4  *
5  * Copyright (C) 1999-2007 by Helge Deller <deller@gmx.de>
6  * Copyright 1999 SuSE GmbH (Philipp Rumpf)
7  * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
8  * Copyright 2000 Hewlett Packard (Paul Bame, bame@puffin.external.hp.com)
9  * Copyright (C) 2001 Grant Grundler (Hewlett Packard)
10  * Copyright (C) 2004 Kyle McMartin <kyle@debian.org>
11  *
12  * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
13  */
14
15 #include <asm/asm-offsets.h>
16 #include <asm/psw.h>
17 #include <asm/pdc.h>
18         
19 #include <asm/assembly.h>
20
21 #include <linux/linkage.h>
22 #include <linux/init.h>
23 #include <linux/pgtable.h>
24
25         .level  1.1
26
27         __INITDATA
28 ENTRY(boot_args)
29         .word 0 /* arg0 */
30         .word 0 /* arg1 */
31         .word 0 /* arg2 */
32         .word 0 /* arg3 */
33 END(boot_args)
34
35         __HEAD
36
37         .align  4
38         .import init_task,data
39         .import init_stack,data
40         .import fault_vector_20,code    /* IVA parisc 2.0 32 bit */
41 #ifndef CONFIG_64BIT
42         .import fault_vector_11,code    /* IVA parisc 1.1 32 bit */
43         .import $global$                /* forward declaration */
44 #endif /*!CONFIG_64BIT*/
45 ENTRY(parisc_kernel_start)
46         .proc
47         .callinfo
48
49         /* Make sure sr4-sr7 are set to zero for the kernel address space */
50         mtsp    %r0,%sr4
51         mtsp    %r0,%sr5
52         mtsp    %r0,%sr6
53         mtsp    %r0,%sr7
54
55         /* Clear BSS (shouldn't the boot loader do this?) */
56
57         .import __bss_start,data
58         .import __bss_stop,data
59
60         load32          PA(__bss_start),%r3
61         load32          PA(__bss_stop),%r4
62 $bss_loop:
63         cmpb,<<,n       %r3,%r4,$bss_loop
64         stw,ma          %r0,4(%r3)
65
66         /* Save away the arguments the boot loader passed in (32 bit args) */
67         load32          PA(boot_args),%r1
68         stw,ma          %arg0,4(%r1)
69         stw,ma          %arg1,4(%r1)
70         stw,ma          %arg2,4(%r1)
71         stw,ma          %arg3,4(%r1)
72
73 #if !defined(CONFIG_64BIT) && defined(CONFIG_PA20)
74         /* This 32-bit kernel was compiled for PA2.0 CPUs. Check current CPU
75          * and halt kernel if we detect a PA1.x CPU. */
76         ldi             32,%r10
77         mtctl           %r10,%cr11
78         .level 2.0
79         mfctl,w         %cr11,%r10
80         .level 1.1
81         comib,<>,n      0,%r10,$cpu_ok
82
83         load32          PA(msg1),%arg0
84         ldi             msg1_end-msg1,%arg1
85 $iodc_panic:
86         copy            %arg0, %r10
87         copy            %arg1, %r11
88         load32          PA(init_stack),%sp
89 #define MEM_CONS 0x3A0
90         ldw             MEM_CONS+32(%r0),%arg0  // HPA
91         ldi             ENTRY_IO_COUT,%arg1
92         ldw             MEM_CONS+36(%r0),%arg2  // SPA
93         ldw             MEM_CONS+8(%r0),%arg3   // layers
94         load32          PA(__bss_start),%r1
95         stw             %r1,-52(%sp)            // arg4
96         stw             %r0,-56(%sp)            // arg5
97         stw             %r10,-60(%sp)           // arg6 = ptr to text
98         stw             %r11,-64(%sp)           // arg7 = len
99         stw             %r0,-68(%sp)            // arg8
100         load32          PA(.iodc_panic_ret), %rp
101         ldw             MEM_CONS+40(%r0),%r1    // ENTRY_IODC
102         bv,n            (%r1)
103 .iodc_panic_ret:
104         b .                             /* wait endless with ... */
105         or              %r10,%r10,%r10  /* qemu idle sleep */
106 msg1:   .ascii "Can't boot kernel which was built for PA8x00 CPUs on this machine.\r\n"
107 msg1_end:
108
109 $cpu_ok:
110 #endif
111
112         .level  PA_ASM_LEVEL
113
114         /* Initialize startup VM. Just map first 16/32 MB of memory */
115         load32          PA(swapper_pg_dir),%r4
116         mtctl           %r4,%cr24       /* Initialize kernel root pointer */
117         mtctl           %r4,%cr25       /* Initialize user root pointer */
118
119 #if CONFIG_PGTABLE_LEVELS == 3
120         /* Set pmd in pgd */
121         load32          PA(pmd0),%r5
122         shrd            %r5,PxD_VALUE_SHIFT,%r3 
123         ldo             (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
124         stw             %r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4)
125         ldo             ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r4
126 #else
127         /* 2-level page table, so pmd == pgd */
128         ldo             ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4
129 #endif
130
131         /* Fill in pmd with enough pte directories */
132         load32          PA(pg0),%r1
133         SHRREG          %r1,PxD_VALUE_SHIFT,%r3
134         ldo             (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
135
136         ldi             ASM_PT_INITIAL,%r1
137
138 1:
139         stw             %r3,0(%r4)
140         ldo             (PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
141         addib,>         -1,%r1,1b
142 #if CONFIG_PGTABLE_LEVELS == 3
143         ldo             ASM_PMD_ENTRY_SIZE(%r4),%r4
144 #else
145         ldo             ASM_PGD_ENTRY_SIZE(%r4),%r4
146 #endif
147
148
149         /* Now initialize the PTEs themselves.  We use RWX for
150          * everything ... it will get remapped correctly later */
151         ldo             0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
152         load32          (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
153         load32          PA(pg0),%r1
154
155 $pgt_fill_loop:
156         STREGM          %r3,ASM_PTE_ENTRY_SIZE(%r1)
157         ldo             (1<<PFN_PTE_SHIFT)(%r3),%r3 /* add one PFN */
158         addib,>         -1,%r11,$pgt_fill_loop
159         nop
160
161         /* Load the return address...er...crash 'n burn */
162         copy            %r0,%r2
163
164         /* And the RFI Target address too */
165         load32          start_parisc,%r11
166
167         /* And the initial task pointer */
168         load32          init_task,%r6
169         mtctl           %r6,%cr30
170
171         /* And the stack pointer too */
172         load32          init_stack,%sp
173         tophys_r1       %sp
174 #if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER)
175         .import _mcount,data
176         /* initialize mcount FPTR */
177         /* Get the global data pointer */
178         loadgp
179         load32          PA(_mcount), %r10
180         std             %dp,0x18(%r10)
181 #endif
182
183 #define MEM_PDC_LO 0x388
184 #define MEM_PDC_HI 0x35C
185 #ifdef CONFIG_64BIT
186         /* Get PDCE_PROC for monarch CPU. */
187         ldw             MEM_PDC_LO(%r0),%r3
188         ldw             MEM_PDC_HI(%r0),%r10
189         depd            %r10, 31, 32, %r3        /* move to upper word */
190 #endif
191
192
193 #ifdef CONFIG_SMP
194         /* Set the smp rendezvous address into page zero.
195         ** It would be safer to do this in init_smp_config() but
196         ** it's just way easier to deal with here because
197         ** of 64-bit function ptrs and the address is local to this file.
198         */
199         load32          PA(smp_slave_stext),%r10
200         stw             %r10,0x10(%r0)  /* MEM_RENDEZ */
201         stw             %r0,0x28(%r0)   /* MEM_RENDEZ_HI - assume addr < 4GB */
202
203         /* FALLTHROUGH */
204         .procend
205
206 #ifdef CONFIG_HOTPLUG_CPU
207         /* common_stext is far away in another section... jump there */
208         load32          PA(common_stext), %rp
209         bv,n            (%rp)
210
211         /* common_stext and smp_slave_stext needs to be in text section */
212         .text
213 #endif
214
215         /*
216         ** Code Common to both Monarch and Slave processors.
217         ** Entry:
218         **
219         **  1.1:        
220         **    %r11 must contain RFI target address.
221         **    %r25/%r26 args to pass to target function
222         **    %r2  in case rfi target decides it didn't like something
223         **
224         **  2.0w:
225         **    %r3  PDCE_PROC address
226         **    %r11 RFI target address
227         **
228         ** Caller must init: SR4-7, %sp, %r10, %cr24/25, 
229         */
230 common_stext:
231         .proc
232         .callinfo
233 #else
234         /* Clear PDC entry point - we won't use it */
235         stw             %r0,0x10(%r0)   /* MEM_RENDEZ */
236         stw             %r0,0x28(%r0)   /* MEM_RENDEZ_HI */
237 #endif /*CONFIG_SMP*/
238
239 #ifdef CONFIG_64BIT
240         mfctl           %cr30,%r6               /* PCX-W2 firmware bug */
241         tophys_r1       %r6
242
243         /* Save the rfi target address */
244         STREG           %r11,  TASK_PT_GR11(%r6)
245         /* Switch to wide mode Superdome doesn't support narrow PDC
246         ** calls.
247         */
248 1:      mfia            %rp             /* clear upper part of pcoq */
249         ldo             2f-1b(%rp),%rp
250         depdi           0,31,32,%rp
251         bv              (%rp)
252         ssm             PSW_SM_W,%r0
253
254         /* Set Wide mode as the "Default" (eg for traps)
255         ** First trap occurs *right* after (or part of) rfi for slave CPUs.
256         ** Someday, palo might not do this for the Monarch either.
257         */
258 2:
259
260         ldo             PDC_PSW(%r0),%arg0              /* 21 */
261         ldo             PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */
262         ldo             PDC_PSW_WIDE_BIT(%r0),%arg2     /* 2 */
263         load32          PA(stext_pdc_ret), %rp
264         bv              (%r3)
265         copy            %r0,%arg3
266
267 stext_pdc_ret:
268         LDREG           TASK_PT_GR11(%r6), %r11
269         tovirt_r1       %r6
270         mtctl           %r6,%cr30               /* restore task thread info */
271 #endif
272
273 #ifndef CONFIG_64BIT
274         /* clear all BTLBs */
275         ldi             PDC_BLOCK_TLB,%arg0
276         load32          PA(stext_pdc_btlb_ret), %rp
277         ldw             MEM_PDC_LO(%r0),%r3
278         bv              (%r3)
279         ldi             PDC_BTLB_PURGE_ALL,%arg1
280 stext_pdc_btlb_ret:
281 #endif
282
283         /* PARANOID: clear user scratch/user space SR's */
284         mtsp    %r0,%sr0
285         mtsp    %r0,%sr1
286         mtsp    %r0,%sr2
287         mtsp    %r0,%sr3
288
289         /* Initialize Protection Registers */
290         mtctl   %r0,%cr8
291         mtctl   %r0,%cr9
292         mtctl   %r0,%cr12
293         mtctl   %r0,%cr13
294
295         /* Initialize the global data pointer */
296         loadgp
297
298         /* Set up our interrupt table.  HPMCs might not work after this! 
299          *
300          * We need to install the correct iva for PA1.1 or PA2.0. The
301          * following short sequence of instructions can determine this
302          * (without being illegal on a PA1.1 machine).
303          */
304 #ifndef CONFIG_64BIT
305         ldi             32,%r10
306         mtctl           %r10,%cr11
307         .level 2.0
308         mfctl,w         %cr11,%r10
309         .level 1.1
310         comib,<>,n      0,%r10,$is_pa20
311         ldil            L%PA(fault_vector_11),%r10
312         b               $install_iva
313         ldo             R%PA(fault_vector_11)(%r10),%r10
314
315 $is_pa20:
316         .level          PA_ASM_LEVEL /* restore 1.1 || 2.0w */
317 #endif /*!CONFIG_64BIT*/
318         load32          PA(fault_vector_20),%r10
319
320 $install_iva:
321         mtctl           %r10,%cr14
322
323         b               aligned_rfi  /* Prepare to RFI! Man all the cannons! */
324         nop
325
326         .align 128
327 aligned_rfi:
328         pcxt_ssm_bug
329
330         copy            %r3, %arg0      /* PDCE_PROC for smp_callin() */
331
332         rsm             PSW_SM_QUIET,%r0        /* off troublesome PSW bits */
333         /* Don't need NOPs, have 8 compliant insn before rfi */
334
335         mtctl           %r0,%cr17       /* Clear IIASQ tail */
336         mtctl           %r0,%cr17       /* Clear IIASQ head */
337
338         /* Load RFI target into PC queue */
339         mtctl           %r11,%cr18      /* IIAOQ head */
340         ldo             4(%r11),%r11
341         mtctl           %r11,%cr18      /* IIAOQ tail */
342
343         load32          KERNEL_PSW,%r10
344         mtctl           %r10,%ipsw
345
346         tovirt_r1       %sp
347
348         /* Jump through hyperspace to Virt Mode */
349         rfi
350         nop
351
352         .procend
353
354 #ifdef CONFIG_SMP
355
356         .import smp_init_current_idle_task,data
357         .import smp_callin,code
358
359 #ifndef CONFIG_64BIT
360 smp_callin_rtn:
361         .proc
362         .callinfo
363         break   1,1             /*  Break if returned from start_secondary */
364         nop
365         nop
366         .procend
367 #endif /*!CONFIG_64BIT*/
368
369 /***************************************************************************
370 * smp_slave_stext is executed by all non-monarch Processors when the Monarch
371 * pokes the slave CPUs in smp.c:smp_boot_cpus().
372 *
373 * Once here, registers values are initialized in order to branch to virtual
374 * mode. Once all available/eligible CPUs are in virtual mode, all are
375 * released and start out by executing their own idle task.
376 *****************************************************************************/
377 smp_slave_stext:
378         .proc
379         .callinfo
380
381         /*
382         ** Initialize Space registers
383         */
384         mtsp       %r0,%sr4
385         mtsp       %r0,%sr5
386         mtsp       %r0,%sr6
387         mtsp       %r0,%sr7
388
389 #ifdef CONFIG_64BIT
390         /*
391          *  Enable Wide mode early, in case the task_struct for the idle
392          *  task in smp_init_current_idle_task was allocated above 4GB.
393          */
394 1:      mfia            %rp             /* clear upper part of pcoq */
395         ldo             2f-1b(%rp),%rp
396         depdi           0,31,32,%rp
397         bv              (%rp)
398         ssm             PSW_SM_W,%r0
399 2:
400 #endif
401
402         /*  Initialize the SP - monarch sets up smp_init_current_idle_task */
403         load32          PA(smp_init_current_idle_task),%r6
404         LDREG           0(%r6),%r6
405         mtctl           %r6,%cr30
406         tophys_r1       %r6
407         LDREG           TASK_STACK(%r6),%sp
408         tophys_r1       %sp
409         ldo             FRAME_SIZE(%sp),%sp
410
411         /* point CPU to kernel page tables */
412         load32          PA(swapper_pg_dir),%r4
413         mtctl           %r4,%cr24       /* Initialize kernel root pointer */
414         mtctl           %r4,%cr25       /* Initialize user root pointer */
415
416 #ifdef CONFIG_64BIT
417         /* Setup PDCE_PROC entry */
418         copy            %arg0,%r3
419 #else
420         /* Load RFI *return* address in case smp_callin bails */
421         load32          smp_callin_rtn,%r2
422 #endif
423         
424         /* Load RFI target address.  */
425         load32          smp_callin,%r11
426         
427         /* ok...common code can handle the rest */
428         b               common_stext
429         nop
430
431         .procend
432 #endif /* CONFIG_SMP */
433
434 #ifndef CONFIG_64BIT
435         .section .data..ro_after_init
436
437         .align  4
438         .export $global$,data
439
440         .type   $global$,@object
441         .size   $global$,4
442 $global$:       
443         .word 0
444 #endif /*!CONFIG_64BIT*/