blob: 71f57bd70f3b8ce109b3e842d7f16819964a45e4 [file] [log] [blame]
Greentime Hu001d9532017-10-24 14:33:30 +08001// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2005-2017 Andes Technology Corporation
3
4#include <linux/linkage.h>
5#include <linux/init.h>
6#include <asm/ptrace.h>
7#include <asm/asm-offsets.h>
8#include <asm/page.h>
9#include <asm/pgtable.h>
10#include <asm/sizes.h>
11#include <asm/thread_info.h>
12
13#ifdef CONFIG_CPU_BIG_ENDIAN
14#define OF_DT_MAGIC 0xd00dfeed
15#else
16#define OF_DT_MAGIC 0xedfe0dd0
17#endif
18
19 .globl swapper_pg_dir
20 .equ swapper_pg_dir, TEXTADDR - 0x4000
21
22/*
23 * Kernel startup entry point.
24 */
25 .section ".head.text", "ax"
26 .type _stext, %function
27ENTRY(_stext)
28 setgie.d ! Disable interrupt
29 isb
30/*
31 * Disable I/D-cache and enable it at a proper time
32 */
33 mfsr $r0, $mr8
34 li $r1, #~(CACHE_CTL_mskIC_EN|CACHE_CTL_mskDC_EN)
35 and $r0, $r0, $r1
36 mtsr $r0, $mr8
37
38/*
39 * Process device tree blob
40 */
41 andi $r0,$r2,#0x3
42 li $r10, 0
43 bne $r0, $r10, _nodtb
44 lwi $r0, [$r2]
45 li $r1, OF_DT_MAGIC
46 bne $r0, $r1, _nodtb
47 move $r10, $r2
48_nodtb:
49
50/*
51 * Create a temporary mapping area for booting, before start_kernel
52 */
53 sethi $r4, hi20(swapper_pg_dir)
54 li $p0, (PAGE_OFFSET - PHYS_OFFSET)
55 sub $r4, $r4, $p0
56 tlbop FlushAll ! invalidate TLB\n"
57 isb
58 mtsr $r4, $L1_PPTB ! load page table pointer\n"
59
60/* set NTC0 cacheable/writeback, mutliple page size in use */
61 mfsr $r3, $MMU_CTL
62 li $r0, #~MMU_CTL_mskNTC0
63 and $r3, $r3, $r0
64#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
65 ori $r3, $r3, #(MMU_CTL_mskMPZIU|(MMU_CTL_CACHEABLE_WB << MMU_CTL_offNTC0))
66#else
67 ori $r3, $r3, #(MMU_CTL_mskMPZIU|(MMU_CTL_CACHEABLE_WB << MMU_CTL_offNTC0)|MMU_CTL_D8KB)
68#endif
69#ifdef CONFIG_HW_SUPPORT_UNALIGNMENT_ACCESS
70 li $r0, #MMU_CTL_UNA
71 or $r3, $r3, $r0
72#endif
73 mtsr $r3, $MMU_CTL
74 isb
75
76/* set page size and size of kernel image */
77 mfsr $r0, $MMU_CFG
78 srli $r3, $r0, MMU_CFG_offfEPSZ
79 zeb $r3, $r3
80 bnez $r3, _extra_page_size_support
81#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
82 li $r5, #SZ_4K ! Use 4KB page size
83#else
84 li $r5, #SZ_8K ! Use 8KB page size
85 li $r3, #1
86#endif
87 mtsr $r3, $TLB_MISC
88 b _image_size_check
89
90_extra_page_size_support: ! Use epzs pages size
91 clz $r6, $r3
92 subri $r2, $r6, #31
93 li $r3, #1
94 sll $r3, $r3, $r2
95 /* MMU_CFG.EPSZ value -> meaning */
96 mul $r5, $r3, $r3
97 slli $r5, $r5, #14
98 /* MMU_CFG.EPSZ -> TLB_MISC.ACC_PSZ */
99 addi $r3, $r2, #0x2
100 mtsr $r3, $TLB_MISC
101
102_image_size_check:
103 /* calculate the image maximum size accepted by TLB config */
104 andi $r6, $r0, MMU_CFG_mskTBW
105 andi $r0, $r0, MMU_CFG_mskTBS
106 srli $r6, $r6, MMU_CFG_offTBW
107 srli $r0, $r0, MMU_CFG_offTBS
108 /*
109 * we just map the kernel to the maximum way - 1 of tlb
110 * reserver one way for UART VA mapping
111 * it will cause page fault if UART mapping cover the kernel mapping
112 *
113 * direct mapping is not supported now.
114 */
115 li $r2, 't'
116 beqz $r6, __error ! MMU_CFG.TBW = 0 is direct mappin
117 addi $r0, $r0, #0x2 ! MMU_CFG.TBS value -> meaning
118 sll $r0, $r6, $r0 ! entries = k-way * n-set
119 mul $r6, $r0, $r5 ! max size = entries * page size
120 /* check kernel image size */
121 la $r3, (_end - PAGE_OFFSET)
122 li $r2, 's'
123 bgt $r3, $r6, __error
124
125 li $r2, #(PHYS_OFFSET + TLB_DATA_kernel_text_attr)
126 li $r3, PAGE_OFFSET
127 add $r6, $r6, $r3
128
129_tlb:
130 mtsr $r3, $TLB_VPN
131 dsb
132 tlbop $r2, RWR
133 isb
134 add $r3, $r3, $r5
135 add $r2, $r2, $r5
136 bgt $r6, $r3, _tlb
137 mfsr $r3, $TLB_MISC ! setup access page size
138 li $r2, #~0xf
139 and $r3, $r3, $r2
140#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
141 ori $r3, $r3, #0x1
142#endif
143 mtsr $r3, $TLB_MISC
144
145 mfsr $r0, $MISC_CTL ! Enable BTB and RTP and shadow sp
146 ori $r0, $r0, #MISC_init
147 mtsr $r0, $MISC_CTL
148
149 mfsr $p1, $PSW
150 li $r15, #~PSW_clr ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE
151 and $p1, $p1, $r15
152 ori $p1, $p1, #PSW_init
153 mtsr $p1, $IPSW ! when iret, it will automatically enable MMU
154 la $lp, __mmap_switched
155 mtsr $lp, $IPC
156 iret
157 nop
158
159 .type __switch_data, %object
160__switch_data:
161 .long __bss_start ! $r6
162 .long _end ! $r7
163 .long __atags_pointer ! $atag_pointer
164 .long init_task ! $r9, move to $r25
165 .long init_thread_union + THREAD_SIZE ! $sp
166
167
168/*
169 * The following fragment of code is executed with the MMU on in MMU mode,
170 * and uses absolute addresses; this is not position independent.
171 */
172 .align
173 .type __mmap_switched, %function
174__mmap_switched:
175 la $r3, __switch_data
176 lmw.bim $r6, [$r3], $r9, #0b0001
177 move $r25, $r9
178 move $fp, #0 ! Clear BSS (and zero $fp)
179 beq $r7, $r6, _RRT
1801: swi.bi $fp, [$r6], #4
181 bne $r7, $r6, 1b
182 swi $r10, [$r8]
183
184_RRT:
185 b start_kernel
186
187__error:
188 b __error