e0f37e973a4621240bb3ddcf79c60cf7bb36a6d6
[linux-flexiantxendom0-3.2.10.git] / arch / mips64 / 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  * Head.S contains the MIPS exception handler and startup code.
7  *
8  * Copyright (C) 1994, 1995 Waldorf Electronics
9  * Written by Ralf Baechle and Andreas Busse
10  * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle
11  * Copyright (C) 1999 Silicon Graphics, Inc.
12  */
13 #include <linux/config.h>
14 #include <linux/init.h>
15 #include <asm/asm.h>
16 #include <asm/regdef.h>
17 #include <asm/processor.h>
18 #include <asm/mipsregs.h>
19 #include <asm/stackframe.h>
20 #include <asm/pgtable.h>
21 #include <asm/sn/addrs.h>
22 #include <asm/sn/sn0/hubni.h>
23 #include <asm/sn/klkernvars.h>
24
25         .macro  ARC64_TWIDDLE_PC
26 #if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
27         /* We get launched at a XKPHYS address but the kernel is linked to
28            run at a KSEG0 address, so jump there.  */
29         PTR_LA  t0, \@f
30         jr      t0
31 \@:
32 #endif
33         .endm
34
35 #ifdef CONFIG_SGI_IP27
36         /*
37          * outputs the local nasid into res.  IP27 stuff.
38          */
39         .macro GET_NASID_ASM res
40         dli     \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
41         ld      \res, (\res)
42         and     \res, NSRI_NODEID_MASK
43         dsrl    \res, NSRI_NODEID_SHFT
44         .endm
45 #endif /* CONFIG_SGI_IP27 */
46
47         /*
48          * inputs are the text nasid in t1, data nasid in t2.
49          */
50         .macro MAPPED_KERNEL_SETUP_TLB
51 #ifdef CONFIG_MAPPED_KERNEL
52         /*
53          * This needs to read the nasid - assume 0 for now.
54          * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
55          * 0+DVG in tlblo_1.
56          */
57         dli     t0, 0xffffffffc0000000
58         dmtc0   t0, CP0_ENTRYHI
59         li      t0, 0x1c000             # Offset of text into node memory
60         dsll    t1, NASID_SHFT          # Shift text nasid into place
61         dsll    t2, NASID_SHFT          # Same for data nasid
62         or      t1, t1, t0              # Physical load address of kernel text
63         or      t2, t2, t0              # Physical load address of kernel data
64         dsrl    t1, 12                  # 4K pfn
65         dsrl    t2, 12                  # 4K pfn
66         dsll    t1, 6                   # Get pfn into place
67         dsll    t2, 6                   # Get pfn into place
68         li      t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6)
69         or      t0, t0, t1
70         mtc0    t0, CP0_ENTRYLO0        # physaddr, VG, cach exlwr
71         li      t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6)
72         or      t0, t0, t2
73         mtc0    t0, CP0_ENTRYLO1        # physaddr, DVG, cach exlwr
74         li      t0, 0x1ffe000           # MAPPED_KERN_TLBMASK, TLBPGMASK_16M
75         mtc0    t0, CP0_PAGEMASK
76         li      t0, 0                   # KMAP_INX
77         mtc0    t0, CP0_INDEX
78         li      t0, 1
79         mtc0    t0, CP0_WIRED
80         tlbwi
81 #else
82         mtc0    zero, CP0_WIRED
83 #endif
84         .endm
85
86         .text
87
88 EXPORT(stext)                                   # used for profiling
89 EXPORT(_stext)
90
91         __INIT
92
93 NESTED(kernel_entry, 16, sp)                    # kernel entry point
94
95         ori     sp, 0xf                         # align stack on 16 byte.
96         xori    sp, 0xf
97
98 #ifdef CONFIG_SGI_IP27
99         GET_NASID_ASM   t1
100         move    t2, t1                          # text and data are here
101         MAPPED_KERNEL_SETUP_TLB
102 #endif /* IP27 */
103
104         ARC64_TWIDDLE_PC
105
106         CLI                                     # disable interrupts
107
108         PTR_LA  $28, init_thread_union          # init current pointer
109         daddiu  sp, $28, KERNEL_STACK_SIZE-32
110         set_saved_sp    sp, t0, t1
111
112         /*
113          * The firmware/bootloader passes argc/argp/envp
114          * to us as arguments.  But clear bss first because
115          * the romvec and other important info is stored there
116          * by prom_init().
117          */
118         PTR_LA  t0, __bss_start
119         sd      zero, (t0)
120         PTR_LA  t1, __bss_stop - 8
121 1:
122         daddiu  t0, 8
123         sd      zero, (t0)
124         bne     t0, t1, 1b
125
126         dsubu   sp, 4*SZREG                     # init stack pointer
127
128         j       init_arch
129         END(kernel_entry)
130
131 #ifdef CONFIG_SMP
132 /*
133  * SMP slave cpus entry point.  Board specific code for bootstrap calls this
134  * function after setting up the stack and gp registers.
135  */
136 NESTED(smp_bootstrap, 16, sp)
137 #ifdef CONFIG_SGI_IP27
138         GET_NASID_ASM   t1
139         li      t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
140                     KLDIR_OFF_POINTER + K0BASE
141         dsll    t1, NASID_SHFT
142         or      t0, t0, t1
143         ld      t0, 0(t0)                       # t0 points to kern_vars struct
144         lh      t1, KV_RO_NASID_OFFSET(t0)
145         lh      t2, KV_RW_NASID_OFFSET(t0)
146         MAPPED_KERNEL_SETUP_TLB
147         ARC64_TWIDDLE_PC
148 #endif /* CONFIG_SGI_IP27 */
149
150         CLI
151
152         /*
153          * For the moment set ST0_KU so the CPU will not spit fire when
154          * executing 64-bit instructions.  The full initialization of the
155          * CPU's status register is done later in per_cpu_trap_init().
156          */
157         mfc0    t0, CP0_STATUS
158         or      t0, ST0_KX
159         mtc0    t0, CP0_STATUS
160
161         jal     start_secondary
162
163         END(smp_bootstrap)
164 #endif /* CONFIG_SMP */
165
166         __FINIT
167
168         declare_saved_sp
169
170 #undef PAGE_SIZE
171 #define PAGE_SIZE       0x1000
172
173         .macro  page name, order=0
174         .globl  \name
175 \name:  .size   \name, (PAGE_SIZE << \order)
176         .org    . + (PAGE_SIZE << \order)
177         .type   \name, @object
178         .endm
179
180         .data
181         .align  PAGE_SHIFT
182
183         page    swapper_pg_dir, 1
184         page    invalid_pte_table, 0
185         page    invalid_pmd_table, 1
186         page    kptbl, _PGD_ORDER
187         .globl  ekptbl
188         page    kpmdtbl, 0
189 ekptbl: