1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
4 #include <linux/linkage.h>
5 #include <linux/init.h>
6 #include <linux/pgtable.h>
7 #include <asm/ptrace.h>
8 #include <asm/asm-offsets.h>
10 #include <linux/sizes.h>
11 #include <asm/thread_info.h>
13 #ifdef CONFIG_CPU_BIG_ENDIAN
14 #define OF_DT_MAGIC 0xd00dfeed
16 #define OF_DT_MAGIC 0xedfe0dd0
20 .equ swapper_pg_dir, TEXTADDR - 0x4000
23 * Kernel startup entry point.
25 .section ".head.text", "ax"
26 .type _stext, %function
28 setgie.d ! Disable interrupt
31 * Disable I/D-cache and enable it at a proper time
34 li $r1, #~(CACHE_CTL_mskIC_EN|CACHE_CTL_mskDC_EN)
39 * Process device tree blob
51 * Create a temporary mapping area for booting, before start_kernel
53 sethi $r4, hi20(swapper_pg_dir)
54 li $p0, (PAGE_OFFSET - PHYS_OFFSET)
56 tlbop FlushAll ! invalidate TLB\n"
58 mtsr $r4, $L1_PPTB ! load page table pointer\n"
60 #ifdef CONFIG_CPU_DCACHE_DISABLE
61 #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_NON
63 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
64 #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WT
66 #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WB
70 /* set NTC cacheability, mutliple page size in use */
72 #if CONFIG_MEMORY_START >= 0xc0000000
73 ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC3)
74 #elif CONFIG_MEMORY_START >= 0x80000000
75 ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC2)
76 #elif CONFIG_MEMORY_START >= 0x40000000
77 ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC1)
79 ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC0)
82 #ifdef CONFIG_ANDES_PAGE_SIZE_4KB
83 ori $r3, $r3, #(MMU_CTL_mskMPZIU)
85 ori $r3, $r3, #(MMU_CTL_mskMPZIU|MMU_CTL_D8KB)
87 #ifdef CONFIG_HW_SUPPORT_UNALIGNMENT_ACCESS
94 /* set page size and size of kernel image */
96 srli $r3, $r0, MMU_CFG_offfEPSZ
98 bnez $r3, _extra_page_size_support
99 #ifdef CONFIG_ANDES_PAGE_SIZE_4KB
100 li $r5, #SZ_4K ! Use 4KB page size
102 li $r5, #SZ_8K ! Use 8KB page size
108 _extra_page_size_support: ! Use epzs pages size
113 /* MMU_CFG.EPSZ value -> meaning */
116 /* MMU_CFG.EPSZ -> TLB_MISC.ACC_PSZ */
121 /* calculate the image maximum size accepted by TLB config */
122 andi $r6, $r0, MMU_CFG_mskTBW
123 andi $r0, $r0, MMU_CFG_mskTBS
124 srli $r6, $r6, MMU_CFG_offTBW
125 srli $r0, $r0, MMU_CFG_offTBS
126 addi $r6, $r6, #0x1 ! MMU_CFG.TBW value -> meaning
127 addi $r0, $r0, #0x2 ! MMU_CFG.TBS value -> meaning
128 sll $r0, $r6, $r0 ! entries = k-way * n-set
129 mul $r6, $r0, $r5 ! max size = entries * page size
130 /* check kernel image size */
131 la $r3, (_end - PAGE_OFFSET)
132 bgt $r3, $r6, __error
134 li $r2, #(PHYS_OFFSET + TLB_DATA_kernel_text_attr)
146 mfsr $r3, $TLB_MISC ! setup access page size
149 #ifdef CONFIG_ANDES_PAGE_SIZE_8KB
154 mfsr $r0, $MISC_CTL ! Enable BTB, RTP, shadow sp, and HW_PRE
155 ori $r0, $r0, #MISC_init
159 li $r15, #~PSW_clr ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE
161 ori $p1, $p1, #PSW_init
162 mtsr $p1, $IPSW ! when iret, it will automatically enable MMU
163 la $lp, __mmap_switched
168 .type __switch_data, %object
170 .long __bss_start ! $r6
172 .long __atags_pointer ! $atag_pointer
173 .long init_task ! $r9, move to $r25
174 .long init_thread_union + THREAD_SIZE ! $sp
178 * The following fragment of code is executed with the MMU on in MMU mode,
179 * and uses absolute addresses; this is not position independent.
182 .type __mmap_switched, %function
184 la $r3, __switch_data
185 lmw.bim $r6, [$r3], $r9, #0b0001
187 move $fp, #0 ! Clear BSS (and zero $fp)
189 1: swi.bi $fp, [$r6], #4