2e9122a4213a2215480637903b0948910ef6128c
[linux-2.6.git] / arch / mips / kernel / head.S
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1994, 1995 Waldorf Electronics
7  * Written by Ralf Baechle and Andreas Busse
8  * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 Ralf Baechle
9  * Copyright (C) 1996 Paul M. Antoine
10  * Modified for DECStation and hence R3000 support by Paul M. Antoine
11  * Further modifications by David S. Miller and Harald Koerfgen
12  * Copyright (C) 1999 Silicon Graphics, Inc.
13  * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
14  * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
15  */
16 #include <linux/config.h>
17 #include <linux/init.h>
18 #include <linux/threads.h>
19
20 #include <asm/asm.h>
21 #include <asm/regdef.h>
22 #include <asm/page.h>
23 #include <asm/mipsregs.h>
24 #include <asm/stackframe.h>
25
26 #include <kernel-entry-init.h>
27
28         .macro  ARC64_TWIDDLE_PC
29 #if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
30         /* We get launched at a XKPHYS address but the kernel is linked to
31            run at a KSEG0 address, so jump there.  */
32         PTR_LA  t0, \@f
33         jr      t0
34 \@:
35 #endif
36         .endm
37
38         /*
39          * inputs are the text nasid in t1, data nasid in t2.
40          */
41         .macro MAPPED_KERNEL_SETUP_TLB
42 #ifdef CONFIG_MAPPED_KERNEL
43         /*
44          * This needs to read the nasid - assume 0 for now.
45          * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
46          * 0+DVG in tlblo_1.
47          */
48         dli     t0, 0xffffffffc0000000
49         dmtc0   t0, CP0_ENTRYHI
50         li      t0, 0x1c000             # Offset of text into node memory
51         dsll    t1, NASID_SHFT          # Shift text nasid into place
52         dsll    t2, NASID_SHFT          # Same for data nasid
53         or      t1, t1, t0              # Physical load address of kernel text
54         or      t2, t2, t0              # Physical load address of kernel data
55         dsrl    t1, 12                  # 4K pfn
56         dsrl    t2, 12                  # 4K pfn
57         dsll    t1, 6                   # Get pfn into place
58         dsll    t2, 6                   # Get pfn into place
59         li      t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6)
60         or      t0, t0, t1
61         mtc0    t0, CP0_ENTRYLO0        # physaddr, VG, cach exlwr
62         li      t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6)
63         or      t0, t0, t2
64         mtc0    t0, CP0_ENTRYLO1        # physaddr, DVG, cach exlwr
65         li      t0, 0x1ffe000           # MAPPED_KERN_TLBMASK, TLBPGMASK_16M
66         mtc0    t0, CP0_PAGEMASK
67         li      t0, 0                   # KMAP_INX
68         mtc0    t0, CP0_INDEX
69         li      t0, 1
70         mtc0    t0, CP0_WIRED
71         tlbwi
72 #else
73         mtc0    zero, CP0_WIRED
74 #endif
75         .endm
76
77         /*
78          * For the moment disable interrupts, mark the kernel mode and
79          * set ST0_KX so that the CPU does not spit fire when using
80          * 64-bit addresses.  A full initialization of the CPU's status
81          * register is done later in per_cpu_trap_init().
82          */
83         .macro  setup_c0_status set clr
84         .set    push
85         mfc0    t0, CP0_STATUS
86         or      t0, ST0_CU0|\set|0x1f|\clr
87         xor     t0, 0x1f|\clr
88         mtc0    t0, CP0_STATUS
89         .set    noreorder
90         sll     zero,3                          # ehb
91         .set    pop
92         .endm
93
94         .macro  setup_c0_status_pri
95 #ifdef CONFIG_64BIT
96         setup_c0_status ST0_KX 0
97 #else
98         setup_c0_status 0 0
99 #endif
100         .endm
101
102         .macro  setup_c0_status_sec
103 #ifdef CONFIG_64BIT
104         setup_c0_status ST0_KX ST0_BEV
105 #else
106         setup_c0_status 0 ST0_BEV
107 #endif
108         .endm
109
110         /*
111          * Reserved space for exception handlers.
112          * Necessary for machines which link their kernels at KSEG0.
113          */
114         .fill   0x400
115
116 EXPORT(stext)                                   # used for profiling
117 EXPORT(_stext)
118
119 #if defined(CONFIG_QEMU) || defined(CONFIG_MIPS_SIM)
120         /*
121          * Give us a fighting chance of running if execution beings at the
122          * kernel load address.  This is needed because this platform does
123          * not have a ELF loader yet.
124          */
125         j       kernel_entry
126 #endif
127         __INIT
128
129 NESTED(kernel_entry, 16, sp)                    # kernel entry point
130
131         kernel_entry_setup                      # cpu specific setup
132
133         setup_c0_status_pri
134
135         ARC64_TWIDDLE_PC
136
137         PTR_LA          t0, __bss_start         # clear .bss
138         LONG_S          zero, (t0)
139         PTR_LA          t1, __bss_stop - LONGSIZE
140 1:
141         PTR_ADDIU       t0, LONGSIZE
142         LONG_S          zero, (t0)
143         bne             t0, t1, 1b
144
145         LONG_S          a0, fw_arg0             # firmware arguments
146         LONG_S          a1, fw_arg1
147         LONG_S          a2, fw_arg2
148         LONG_S          a3, fw_arg3
149
150         MTC0            zero, CP0_CONTEXT       # clear context register
151         PTR_LA          $28, init_thread_union
152         PTR_ADDIU       sp, $28, _THREAD_SIZE - 32
153         set_saved_sp    sp, t0, t1
154         PTR_SUBU        sp, 4 * SZREG           # init stack pointer
155
156         j               start_kernel
157         END(kernel_entry)
158
159 #ifdef CONFIG_QEMU
160         __INIT
161 #endif
162
163 #ifdef CONFIG_SMP
164 /*
165  * SMP slave cpus entry point.  Board specific code for bootstrap calls this
166  * function after setting up the stack and gp registers.
167  */
168 NESTED(smp_bootstrap, 16, sp)
169         setup_c0_status_sec
170         smp_slave_setup
171         j       start_secondary
172         END(smp_bootstrap)
173 #endif /* CONFIG_SMP */
174
175         __FINIT
176
177         .comm   kernelsp,    NR_CPUS * 8, 8
178         .comm   pgd_current, NR_CPUS * 8, 8
179
180         .comm   fw_arg0, SZREG, SZREG           # firmware arguments
181         .comm   fw_arg1, SZREG, SZREG
182         .comm   fw_arg2, SZREG, SZREG
183         .comm   fw_arg3, SZREG, SZREG
184
185         .macro page name, order
186         .comm   \name, (_PAGE_SIZE << \order), (_PAGE_SIZE << \order)
187         .endm
188
189         /*
190          * On 64-bit we've got three-level pagetables with a slightly
191          * different layout ...
192          */
193         page    swapper_pg_dir, _PGD_ORDER
194 #ifdef CONFIG_64BIT
195         page    invalid_pmd_table, _PMD_ORDER
196 #endif
197         page    invalid_pte_table, _PTE_ORDER