Remove obsolete #include <linux/config.h>
[pandora-kernel.git] / arch / frv / kernel / head.S
1 /* head.S: kernel entry point for FR-V kernel
2  *
3  * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <linux/threads.h>
13 #include <linux/linkage.h>
14 #include <asm/ptrace.h>
15 #include <asm/page.h>
16 #include <asm/spr-regs.h>
17 #include <asm/mb86943a.h>
18 #include <asm/cache.h>
19 #include "head.inc"
20
21 ###############################################################################
22 #
23 # void _boot(unsigned long magic, char *command_line) __attribute__((noreturn))
24 #
25 # - if magic is 0xdead1eaf, then command_line is assumed to point to the kernel
26 #   command line string
27 #
28 ###############################################################################
29         .section        .text.head,"ax"
30         .balign         4
31
32         .globl          _boot, __head_reference
33         .type           _boot,@function
34 _boot:
35 __head_reference:
36         sethi.p         %hi(LED_ADDR),gr30
37         setlo           %lo(LED_ADDR),gr30
38
39         LEDS            0x0000
40
41         # calculate reference address for PC-relative stuff
42         call            0f
43 0:      movsg           lr,gr26
44         addi            gr26,#__head_reference-0b,gr26
45
46         # invalidate and disable both of the caches and turn off the memory access checking
47         dcef            @(gr0,gr0),1
48         bar
49
50         sethi.p         %hi(~(HSR0_ICE|HSR0_DCE|HSR0_CBM|HSR0_EIMMU|HSR0_EDMMU)),gr4
51         setlo           %lo(~(HSR0_ICE|HSR0_DCE|HSR0_CBM|HSR0_EIMMU|HSR0_EDMMU)),gr4
52         movsg           hsr0,gr5
53         and             gr4,gr5,gr5
54         movgs           gr5,hsr0
55         movsg           hsr0,gr5
56
57         LEDS            0x0001
58
59         icei            @(gr0,gr0),1
60         dcei            @(gr0,gr0),1
61         bar
62
63         # turn the instruction cache back on
64         sethi.p         %hi(HSR0_ICE),gr4
65         setlo           %lo(HSR0_ICE),gr4
66         movsg           hsr0,gr5
67         or              gr4,gr5,gr5
68         movgs           gr5,hsr0
69         movsg           hsr0,gr5
70
71         bar
72
73         LEDS            0x0002
74
75         # retrieve the parameters (including command line) before we overwrite them
76         sethi.p         %hi(0xdead1eaf),gr7
77         setlo           %lo(0xdead1eaf),gr7
78         subcc           gr7,gr8,gr0,icc0
79         bne             icc0,#0,__head_no_parameters
80
81         sethi.p         %hi(redboot_command_line-1),gr6
82         setlo           %lo(redboot_command_line-1),gr6
83         sethi.p         %hi(__head_reference),gr4
84         setlo           %lo(__head_reference),gr4
85         sub             gr6,gr4,gr6
86         add.p           gr6,gr26,gr6
87         subi            gr9,#1,gr9
88         setlos.p        #511,gr4
89         setlos          #1,gr5
90
91 __head_copy_cmdline:
92         ldubu.p         @(gr9,gr5),gr16
93         subicc          gr4,#1,gr4,icc0
94         stbu.p          gr16,@(gr6,gr5)
95         subicc          gr16,#0,gr0,icc1
96         bls             icc0,#0,__head_end_cmdline
97         bne             icc1,#1,__head_copy_cmdline
98 __head_end_cmdline:
99         stbu            gr0,@(gr6,gr5)
100 __head_no_parameters:
101
102 ###############################################################################
103 #
104 # we need to relocate the SDRAM to 0x00000000 (linux) or 0xC0000000 (uClinux)
105 # - note that we're going to have to run entirely out of the icache whilst
106 #   fiddling with the SDRAM controller registers
107 #
108 ###############################################################################
109 #ifdef CONFIG_MMU
110         call            __head_fr451_describe_sdram
111
112 #else
113         movsg           psr,gr5
114         srli            gr5,#28,gr5
115         subicc          gr5,#3,gr0,icc0
116         beq             icc0,#0,__head_fr551_sdram
117
118         call            __head_fr401_describe_sdram
119         bra             __head_do_sdram
120
121 __head_fr551_sdram:
122         call            __head_fr555_describe_sdram
123         LEDS            0x000d
124
125 __head_do_sdram:
126 #endif
127
128         # preload the registers with invalid values in case any DBR/DARS are marked not present
129         sethi.p         %hi(0xfe000000),gr17            ; unused SDRAM DBR value
130         setlo           %lo(0xfe000000),gr17
131         or.p            gr17,gr0,gr20
132         or              gr17,gr0,gr21
133         or.p            gr17,gr0,gr22
134         or              gr17,gr0,gr23
135
136         # consult the SDRAM controller CS address registers
137         cld             @(gr14,gr0 ),gr20,      cc0,#1  ; DBR0 / DARS0
138         cld             @(gr14,gr11),gr21,      cc1,#1  ; DBR1 / DARS1
139         cld             @(gr14,gr12),gr22,      cc2,#1  ; DBR2 / DARS2
140         cld.p           @(gr14,gr13),gr23,      cc3,#1  ; DBR3 / DARS3
141
142         sll             gr20,gr15,gr20                  ; shift values up for FR551
143         sll             gr21,gr15,gr21
144         sll             gr22,gr15,gr22
145         sll             gr23,gr15,gr23
146
147         LEDS            0x0003
148
149         # assume the lowest valid CS line to be the SDRAM base and get its address
150         subcc           gr20,gr17,gr0,icc0
151         subcc.p         gr21,gr17,gr0,icc1
152         subcc           gr22,gr17,gr0,icc2
153         subcc.p         gr23,gr17,gr0,icc3
154         ckne            icc0,cc4                        ; T if DBR0 != 0xfe000000
155         ckne            icc1,cc5
156         ckne            icc2,cc6
157         ckne            icc3,cc7
158         cor             gr23,gr0,gr24,          cc7,#1  ; GR24 = SDRAM base
159         cor             gr22,gr0,gr24,          cc6,#1
160         cor             gr21,gr0,gr24,          cc5,#1
161         cor             gr20,gr0,gr24,          cc4,#1
162
163         # calculate the displacement required to get the SDRAM into the right place in memory
164         sethi.p         %hi(__sdram_base),gr16
165         setlo           %lo(__sdram_base),gr16
166         sub             gr16,gr24,gr16                  ; delta = __sdram_base - DBRx
167
168         # calculate the new values to go in the controller regs
169         cadd.p          gr20,gr16,gr20,         cc4,#1  ; DCS#0 (new) = DCS#0 (old) + delta
170         cadd            gr21,gr16,gr21,         cc5,#1
171         cadd.p          gr22,gr16,gr22,         cc6,#1
172         cadd            gr23,gr16,gr23,         cc7,#1
173
174         srl             gr20,gr15,gr20                  ; shift values down for FR551
175         srl             gr21,gr15,gr21
176         srl             gr22,gr15,gr22
177         srl             gr23,gr15,gr23
178
179         # work out the address at which the reg updater resides and lock it into icache
180         # also work out the address the updater will jump to when finished
181         sethi.p         %hi(__head_move_sdram-__head_reference),gr18
182         setlo           %lo(__head_move_sdram-__head_reference),gr18
183         sethi.p         %hi(__head_sdram_moved-__head_reference),gr19
184         setlo           %lo(__head_sdram_moved-__head_reference),gr19
185         add.p           gr18,gr26,gr18
186         add             gr19,gr26,gr19
187         add.p           gr19,gr16,gr19                  ; moved = addr + (__sdram_base - DBRx)
188         add             gr18,gr5,gr4                    ; two cachelines probably required
189
190         icpl            gr18,gr0,#1                     ; load and lock the cachelines
191         icpl            gr4,gr0,#1
192         LEDS            0x0004
193         membar
194         bar
195         jmpl            @(gr18,gr0)
196
197         .balign         L1_CACHE_BYTES
198 __head_move_sdram:
199         cst             gr20,@(gr14,gr0 ),      cc4,#1
200         cst             gr21,@(gr14,gr11),      cc5,#1
201         cst             gr22,@(gr14,gr12),      cc6,#1
202         cst             gr23,@(gr14,gr13),      cc7,#1
203         cld             @(gr14,gr0 ),gr20,      cc4,#1
204         cld             @(gr14,gr11),gr21,      cc5,#1
205         cld             @(gr14,gr12),gr22,      cc4,#1
206         cld             @(gr14,gr13),gr23,      cc7,#1
207         bar
208         membar
209         jmpl            @(gr19,gr0)
210
211         .balign         L1_CACHE_BYTES
212 __head_sdram_moved:
213         icul            gr18
214         add             gr18,gr5,gr4
215         icul            gr4
216         icei            @(gr0,gr0),1
217         dcei            @(gr0,gr0),1
218
219         LEDS            0x0005
220
221         # recalculate reference address
222         call            0f
223 0:      movsg           lr,gr26
224         addi            gr26,#__head_reference-0b,gr26
225
226
227 ###############################################################################
228 #
229 # move the kernel image down to the bottom of the SDRAM
230 #
231 ###############################################################################
232         sethi.p         %hi(__kernel_image_size_no_bss+15),gr4
233         setlo           %lo(__kernel_image_size_no_bss+15),gr4
234         srli.p          gr4,#4,gr4                      ; count
235         or              gr26,gr26,gr16                  ; source
236
237         sethi.p         %hi(__sdram_base),gr17          ; destination
238         setlo           %lo(__sdram_base),gr17
239
240         setlos          #8,gr5
241         sub.p           gr16,gr5,gr16                   ; adjust src for LDDU
242         sub             gr17,gr5,gr17                   ; adjust dst for LDDU
243
244         sethi.p         %hi(__head_move_kernel-__head_reference),gr18
245         setlo           %lo(__head_move_kernel-__head_reference),gr18
246         sethi.p         %hi(__head_kernel_moved-__head_reference+__sdram_base),gr19
247         setlo           %lo(__head_kernel_moved-__head_reference+__sdram_base),gr19
248         add             gr18,gr26,gr18
249         icpl            gr18,gr0,#1
250         jmpl            @(gr18,gr0)
251
252         .balign         32
253 __head_move_kernel:
254         lddu            @(gr16,gr5),gr10
255         lddu            @(gr16,gr5),gr12
256         stdu.p          gr10,@(gr17,gr5)
257         subicc          gr4,#1,gr4,icc0
258         stdu.p          gr12,@(gr17,gr5)
259         bhi             icc0,#0,__head_move_kernel
260         jmpl            @(gr19,gr0)
261
262         .balign         32
263 __head_kernel_moved:
264         icul            gr18
265         icei            @(gr0,gr0),1
266         dcei            @(gr0,gr0),1
267
268         LEDS            0x0006
269
270         # recalculate reference address
271         call            0f
272 0:      movsg           lr,gr26
273         addi            gr26,#__head_reference-0b,gr26
274
275
276 ###############################################################################
277 #
278 # rearrange the iomem map and set the protection registers
279 #
280 ###############################################################################
281
282 #ifdef CONFIG_MMU
283         LEDS            0x3301
284         call            __head_fr451_set_busctl
285         LEDS            0x3303
286         call            __head_fr451_survey_sdram
287         LEDS            0x3305
288         call            __head_fr451_set_protection
289
290 #else
291         movsg           psr,gr5
292         srli            gr5,#PSR_IMPLE_SHIFT,gr5
293         subicc          gr5,#PSR_IMPLE_FR551,gr0,icc0
294         beq             icc0,#0,__head_fr555_memmap
295         subicc          gr5,#PSR_IMPLE_FR451,gr0,icc0
296         beq             icc0,#0,__head_fr451_memmap
297
298         LEDS            0x3101
299         call            __head_fr401_set_busctl
300         LEDS            0x3103
301         call            __head_fr401_survey_sdram
302         LEDS            0x3105
303         call            __head_fr401_set_protection
304         bra             __head_done_memmap
305
306 __head_fr451_memmap:
307         LEDS            0x3301
308         call            __head_fr401_set_busctl
309         LEDS            0x3303
310         call            __head_fr401_survey_sdram
311         LEDS            0x3305
312         call            __head_fr451_set_protection
313         bra             __head_done_memmap
314
315 __head_fr555_memmap:
316         LEDS            0x3501
317         call            __head_fr555_set_busctl
318         LEDS            0x3503
319         call            __head_fr555_survey_sdram
320         LEDS            0x3505
321         call            __head_fr555_set_protection
322
323 __head_done_memmap:
324 #endif
325         LEDS            0x0007
326
327 ###############################################################################
328 #
329 # turn the data cache and MMU on
330 # - for the FR451 this'll mean that the window through which the kernel is
331 #   viewed will change
332 #
333 ###############################################################################
334
335 #ifdef CONFIG_MMU
336 #define MMUMODE         HSR0_EIMMU|HSR0_EDMMU|HSR0_EXMMU|HSR0_EDAT|HSR0_XEDAT
337 #else
338 #define MMUMODE         HSR0_EIMMU|HSR0_EDMMU
339 #endif
340
341         movsg           hsr0,gr5
342
343         sethi.p         %hi(MMUMODE),gr4
344         setlo           %lo(MMUMODE),gr4
345         or              gr4,gr5,gr5
346
347 #if defined(CONFIG_FRV_DEFL_CACHE_WTHRU)
348         sethi.p         %hi(HSR0_DCE|HSR0_CBM_WRITE_THRU),gr4
349         setlo           %lo(HSR0_DCE|HSR0_CBM_WRITE_THRU),gr4
350 #elif defined(CONFIG_FRV_DEFL_CACHE_WBACK)
351         sethi.p         %hi(HSR0_DCE|HSR0_CBM_COPY_BACK),gr4
352         setlo           %lo(HSR0_DCE|HSR0_CBM_COPY_BACK),gr4
353 #elif defined(CONFIG_FRV_DEFL_CACHE_WBEHIND)
354         sethi.p         %hi(HSR0_DCE|HSR0_CBM_COPY_BACK),gr4
355         setlo           %lo(HSR0_DCE|HSR0_CBM_COPY_BACK),gr4
356
357         movsg           psr,gr6
358         srli            gr6,#24,gr6
359         cmpi            gr6,#0x50,icc0          // FR451
360         beq             icc0,#0,0f
361         cmpi            gr6,#0x40,icc0          // FR405
362         bne             icc0,#0,1f
363 0:
364         # turn off write-allocate
365         sethi.p         %hi(HSR0_NWA),gr6
366         setlo           %lo(HSR0_NWA),gr6
367         or              gr4,gr6,gr4
368 1:
369
370 #else
371 #error No default cache configuration set
372 #endif
373
374         or              gr4,gr5,gr5
375         movgs           gr5,hsr0
376         bar
377
378         LEDS            0x0008
379
380         sethi.p         %hi(__head_mmu_enabled),gr19
381         setlo           %lo(__head_mmu_enabled),gr19
382         jmpl            @(gr19,gr0)
383
384 __head_mmu_enabled:
385         icei            @(gr0,gr0),#1
386         dcei            @(gr0,gr0),#1
387
388         LEDS            0x0009
389
390 #ifdef CONFIG_MMU
391         call            __head_fr451_finalise_protection
392 #endif
393
394         LEDS            0x000a
395
396 ###############################################################################
397 #
398 # set up the runtime environment
399 #
400 ###############################################################################
401
402         # clear the BSS area
403         sethi.p         %hi(__bss_start),gr4
404         setlo           %lo(__bss_start),gr4
405         sethi.p         %hi(_end),gr5
406         setlo           %lo(_end),gr5
407         or.p            gr0,gr0,gr18
408         or              gr0,gr0,gr19
409
410 0:
411         stdi            gr18,@(gr4,#0)
412         stdi            gr18,@(gr4,#8)
413         stdi            gr18,@(gr4,#16)
414         stdi.p          gr18,@(gr4,#24)
415         addi            gr4,#24,gr4
416         subcc           gr5,gr4,gr0,icc0
417         bhi             icc0,#2,0b
418
419         LEDS            0x000b
420
421         # save the SDRAM details
422         sethi.p         %hi(__sdram_old_base),gr4
423         setlo           %lo(__sdram_old_base),gr4
424         st              gr24,@(gr4,gr0)
425
426         sethi.p         %hi(__sdram_base),gr5
427         setlo           %lo(__sdram_base),gr5
428         sethi.p         %hi(memory_start),gr4
429         setlo           %lo(memory_start),gr4
430         st              gr5,@(gr4,gr0)
431
432         add             gr25,gr5,gr25
433         sethi.p         %hi(memory_end),gr4
434         setlo           %lo(memory_end),gr4
435         st              gr25,@(gr4,gr0)
436
437         # point the TBR at the kernel trap table
438         sethi.p         %hi(__entry_kerneltrap_table),gr4
439         setlo           %lo(__entry_kerneltrap_table),gr4
440         movgs           gr4,tbr
441
442         # set up the exception frame for init
443         sethi.p         %hi(__kernel_frame0_ptr),gr28
444         setlo           %lo(__kernel_frame0_ptr),gr28
445         sethi.p         %hi(_gp),gr16
446         setlo           %lo(_gp),gr16
447         sethi.p         %hi(__entry_usertrap_table),gr4
448         setlo           %lo(__entry_usertrap_table),gr4
449
450         lddi            @(gr28,#0),gr28         ; load __frame & current
451         ldi.p           @(gr29,#4),gr15         ; set current_thread
452
453         or              gr0,gr0,fp
454         or              gr28,gr0,sp
455
456         sti.p           gr4,@(gr28,REG_TBR)
457         setlos          #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
458         movgs           gr5,isr
459
460         # turn on and off various CPU services
461         movsg           psr,gr22
462         sethi.p         %hi(#PSR_EM|PSR_EF|PSR_CM|PSR_NEM),gr4
463         setlo           %lo(#PSR_EM|PSR_EF|PSR_CM|PSR_NEM),gr4
464         or              gr22,gr4,gr22
465         movgs           gr22,psr
466
467         andi            gr22,#~(PSR_PIL|PSR_PS|PSR_S),gr22
468         ori             gr22,#PSR_ET,gr22
469         sti             gr22,@(gr28,REG_PSR)
470
471
472 ###############################################################################
473 #
474 # set up the registers and jump into the kernel
475 #
476 ###############################################################################
477
478         LEDS            0x000c
479
480         # initialise the processor and the peripherals
481         #call           SYMBOL_NAME(processor_init)
482         #call           SYMBOL_NAME(unit_init)
483         #LEDS           0x0aff
484
485         sethi.p         #0xe5e5,gr3
486         setlo           #0xe5e5,gr3
487         or.p            gr3,gr0,gr4
488         or              gr3,gr0,gr5
489         or.p            gr3,gr0,gr6
490         or              gr3,gr0,gr7
491         or.p            gr3,gr0,gr8
492         or              gr3,gr0,gr9
493         or.p            gr3,gr0,gr10
494         or              gr3,gr0,gr11
495         or.p            gr3,gr0,gr12
496         or              gr3,gr0,gr13
497         or.p            gr3,gr0,gr14
498         or              gr3,gr0,gr17
499         or.p            gr3,gr0,gr18
500         or              gr3,gr0,gr19
501         or.p            gr3,gr0,gr20
502         or              gr3,gr0,gr21
503         or.p            gr3,gr0,gr23
504         or              gr3,gr0,gr24
505         or.p            gr3,gr0,gr25
506         or              gr3,gr0,gr26
507         or.p            gr3,gr0,gr27
508 #       or              gr3,gr0,gr30
509         or              gr3,gr0,gr31
510         movgs           gr0,lr
511         movgs           gr0,lcr
512         movgs           gr0,ccr
513         movgs           gr0,cccr
514
515         # initialise the virtual interrupt handling
516         subcc           gr0,gr0,gr0,icc2                /* set Z, clear C */
517
518 #ifdef CONFIG_MMU
519         movgs           gr3,scr2
520         movgs           gr3,scr3
521 #endif
522
523         LEDS            0x0fff
524
525         # invoke the debugging stub if present
526         # - arch/frv/kernel/debug-stub.c will shift control directly to init/main.c
527         #   (it will not return here)
528         break
529         .globl          __debug_stub_init_break
530 __debug_stub_init_break:
531
532         # however, if you need to use an ICE, and don't care about using any userspace
533         # debugging tools (such as the ptrace syscall), you can just step over the break
534         # above and get to the kernel this way
535         # look at arch/frv/kernel/debug-stub.c: debug_stub_init() to see what you've missed
536         call            start_kernel
537
538         .globl          __head_end
539 __head_end:
540         .size           _boot, .-_boot
541
542         # provide a point for GDB to place a break
543         .section        .text.start,"ax"
544         .globl          _start
545         .balign         4
546 _start:
547         call            _boot
548
549         .previous
550 ###############################################################################
551 #
552 # split a tile off of the region defined by GR8-GR9
553 #
554 #       ENTRY:                  EXIT:
555 # GR4   -                       IAMPR value representing tile
556 # GR5   -                       DAMPR value representing tile
557 # GR6   -                       IAMLR value representing tile
558 # GR7   -                       DAMLR value representing tile
559 # GR8   region base pointer     [saved]
560 # GR9   region top pointer      updated to exclude new tile
561 # GR11  xAMLR mask              [saved]
562 # GR25  SDRAM size              [saved]
563 # GR30  LED address             [saved]
564 #
565 # - GR8 and GR9 should be rounded up/down to the nearest megabyte before calling
566 #
567 ###############################################################################
568         .globl          __head_split_region
569         .type           __head_split_region,@function
570 __head_split_region:
571         subcc.p         gr9,gr8,gr4,icc0
572         setlos          #31,gr5
573         scan.p          gr4,gr0,gr6
574         beq             icc0,#0,__head_region_empty
575         sub.p           gr5,gr6,gr6                     ; bit number of highest set bit (1MB=>20)
576         setlos          #1,gr4
577         sll.p           gr4,gr6,gr4                     ; size of region (1 << bitno)
578         subi            gr6,#17,gr6                     ; 1MB => 0x03
579         slli.p          gr6,#4,gr6                      ; 1MB => 0x30
580         sub             gr9,gr4,gr9                     ; move uncovered top down
581
582         or              gr9,gr6,gr4
583         ori             gr4,#xAMPRx_S_USER|xAMPRx_C_CACHED|xAMPRx_V,gr4
584         or.p            gr4,gr0,gr5
585
586         and             gr4,gr11,gr6
587         and.p           gr5,gr11,gr7
588         bralr
589
590 __head_region_empty:
591         or.p            gr0,gr0,gr4
592         or              gr0,gr0,gr5
593         or.p            gr0,gr0,gr6
594         or              gr0,gr0,gr7
595         bralr
596         .size           __head_split_region, .-__head_split_region
597
598 ###############################################################################
599 #
600 # write the 32-bit hex number in GR8 to ttyS0
601 #
602 ###############################################################################
603 #if 0
604         .globl          __head_write_to_ttyS0
605         .type           __head_write_to_ttyS0,@function
606 __head_write_to_ttyS0:
607         sethi.p         %hi(0xfeff9c00),gr31
608         setlo           %lo(0xfeff9c00),gr31
609         setlos          #8,gr20
610
611 0:      ldubi           @(gr31,#5*8),gr21
612         andi            gr21,#0x60,gr21
613         subicc          gr21,#0x60,gr21,icc0
614         bne             icc0,#0,0b
615
616 1:      srli            gr8,#28,gr21
617         slli            gr8,#4,gr8
618
619         addi            gr21,#'0',gr21
620         subicc          gr21,#'9',gr0,icc0
621         bls             icc0,#2,2f
622         addi            gr21,#'A'-'0'-10,gr21
623 2:
624         stbi            gr21,@(gr31,#0*8)
625         subicc          gr20,#1,gr20,icc0
626         bhi             icc0,#2,1b
627
628         setlos          #'\r',gr21
629         stbi            gr21,@(gr31,#0*8)
630
631         setlos          #'\n',gr21
632         stbi            gr21,@(gr31,#0*8)
633
634 3:      ldubi           @(gr31,#5*8),gr21
635         andi            gr21,#0x60,gr21
636         subicc          gr21,#0x60,gr21,icc0
637         bne             icc0,#0,3b
638         bralr
639
640         .size           __head_write_to_ttyS0, .-__head_write_to_ttyS0
641 #endif