1// 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#ifdef CONFIG_CPU_DCACHE_DISABLE 61 #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_NON 62#else 63 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 64 #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WT 65 #else 66 #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WB 67 #endif 68#endif 69 70/* set NTC cacheability, mutliple page size in use */ 71 mfsr $r3, $MMU_CTL 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) 78#else 79 ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC0) 80#endif 81 82#ifdef CONFIG_ANDES_PAGE_SIZE_4KB 83 ori $r3, $r3, #(MMU_CTL_mskMPZIU) 84#else 85 ori $r3, $r3, #(MMU_CTL_mskMPZIU|MMU_CTL_D8KB) 86#endif 87#ifdef CONFIG_HW_SUPPORT_UNALIGNMENT_ACCESS 88 li $r0, #MMU_CTL_UNA 89 or $r3, $r3, $r0 90#endif 91 mtsr $r3, $MMU_CTL 92 isb 93 94/* set page size and size of kernel image */ 95 mfsr $r0, $MMU_CFG 96 srli $r3, $r0, MMU_CFG_offfEPSZ 97 zeb $r3, $r3 98 bnez $r3, _extra_page_size_support 99#ifdef CONFIG_ANDES_PAGE_SIZE_4KB 100 li $r5, #SZ_4K ! Use 4KB page size 101#else 102 li $r5, #SZ_8K ! Use 8KB page size 103 li $r3, #1 104#endif 105 mtsr $r3, $TLB_MISC 106 b _image_size_check 107 108_extra_page_size_support: ! Use epzs pages size 109 clz $r6, $r3 110 subri $r2, $r6, #31 111 li $r3, #1 112 sll $r3, $r3, $r2 113 /* MMU_CFG.EPSZ value -> meaning */ 114 mul $r5, $r3, $r3 115 slli $r5, $r5, #14 116 /* MMU_CFG.EPSZ -> TLB_MISC.ACC_PSZ */ 117 addi $r3, $r2, #0x2 118 mtsr $r3, $TLB_MISC 119 120_image_size_check: 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 /* 127 * we just map the kernel to the maximum way - 1 of tlb 128 * reserver one way for UART VA mapping 129 * it will cause page fault if UART mapping cover the kernel mapping 130 * 131 * direct mapping is not supported now. 132 */ 133 li $r2, 't' 134 beqz $r6, __error ! MMU_CFG.TBW = 0 is direct mappin 135 addi $r0, $r0, #0x2 ! MMU_CFG.TBS value -> meaning 136 sll $r0, $r6, $r0 ! entries = k-way * n-set 137 mul $r6, $r0, $r5 ! max size = entries * page size 138 /* check kernel image size */ 139 la $r3, (_end - PAGE_OFFSET) 140 li $r2, 's' 141 bgt $r3, $r6, __error 142 143 li $r2, #(PHYS_OFFSET + TLB_DATA_kernel_text_attr) 144 li $r3, PAGE_OFFSET 145 add $r6, $r6, $r3 146 147_tlb: 148 mtsr $r3, $TLB_VPN 149 dsb 150 tlbop $r2, RWR 151 isb 152 add $r3, $r3, $r5 153 add $r2, $r2, $r5 154 bgt $r6, $r3, _tlb 155 mfsr $r3, $TLB_MISC ! setup access page size 156 li $r2, #~0xf 157 and $r3, $r3, $r2 158#ifdef CONFIG_ANDES_PAGE_SIZE_8KB 159 ori $r3, $r3, #0x1 160#endif 161 mtsr $r3, $TLB_MISC 162 163 mfsr $r0, $MISC_CTL ! Enable BTB and RTP and shadow sp 164 ori $r0, $r0, #MISC_init 165 mtsr $r0, $MISC_CTL 166 167 mfsr $p1, $PSW 168 li $r15, #~PSW_clr ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE 169 and $p1, $p1, $r15 170 ori $p1, $p1, #PSW_init 171 mtsr $p1, $IPSW ! when iret, it will automatically enable MMU 172 la $lp, __mmap_switched 173 mtsr $lp, $IPC 174 iret 175 nop 176 177 .type __switch_data, %object 178__switch_data: 179 .long __bss_start ! $r6 180 .long _end ! $r7 181 .long __atags_pointer ! $atag_pointer 182 .long init_task ! $r9, move to $r25 183 .long init_thread_union + THREAD_SIZE ! $sp 184 185 186/* 187 * The following fragment of code is executed with the MMU on in MMU mode, 188 * and uses absolute addresses; this is not position independent. 189 */ 190 .align 191 .type __mmap_switched, %function 192__mmap_switched: 193 la $r3, __switch_data 194 lmw.bim $r6, [$r3], $r9, #0b0001 195 move $r25, $r9 196 move $fp, #0 ! Clear BSS (and zero $fp) 197 beq $r7, $r6, _RRT 1981: swi.bi $fp, [$r6], #4 199 bne $r7, $r6, 1b 200 swi $r10, [$r8] 201 202_RRT: 203 b start_kernel 204 205__error: 206 b __error 207