root/arch/nds32/kernel/head.S

/* [<][>][^][v][top][bottom][index][help] */
   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 <linux/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
  27 ENTRY(_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         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
 133 
 134         li      $r2, #(PHYS_OFFSET + TLB_DATA_kernel_text_attr)
 135         li      $r3, PAGE_OFFSET
 136         add     $r6, $r6, $r3
 137 
 138 _tlb:
 139         mtsr    $r3, $TLB_VPN
 140         dsb
 141         tlbop   $r2, RWR
 142         isb
 143         add     $r3, $r3, $r5
 144         add     $r2, $r2, $r5
 145         bgt     $r6, $r3, _tlb
 146         mfsr    $r3, $TLB_MISC      ! setup access page size
 147         li      $r2, #~0xf
 148         and     $r3, $r3, $r2
 149 #ifdef CONFIG_ANDES_PAGE_SIZE_8KB
 150         ori    $r3, $r3, #0x1
 151 #endif
 152         mtsr    $r3, $TLB_MISC
 153 
 154         mfsr    $r0, $MISC_CTL      ! Enable BTB, RTP, shadow sp, and HW_PRE
 155         ori     $r0, $r0, #MISC_init
 156         mtsr    $r0, $MISC_CTL
 157 
 158         mfsr    $p1, $PSW
 159         li      $r15, #~PSW_clr             ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE
 160         and     $p1, $p1, $r15
 161         ori     $p1, $p1, #PSW_init
 162         mtsr    $p1, $IPSW                  ! when iret, it will automatically enable MMU
 163         la      $lp, __mmap_switched
 164         mtsr    $lp, $IPC
 165         iret
 166         nop
 167 
 168         .type   __switch_data, %object
 169 __switch_data:
 170         .long   __bss_start                 ! $r6
 171         .long   _end                        ! $r7
 172         .long   __atags_pointer             ! $atag_pointer
 173         .long   init_task                   ! $r9, move to $r25
 174         .long   init_thread_union + THREAD_SIZE    ! $sp
 175 
 176 
 177 /*
 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.
 180  */
 181         .align
 182         .type   __mmap_switched, %function
 183 __mmap_switched:
 184         la  $r3, __switch_data
 185         lmw.bim $r6, [$r3], $r9, #0b0001
 186         move    $r25, $r9
 187         move    $fp, #0             ! Clear  BSS (and zero $fp)
 188         beq $r7, $r6, _RRT
 189 1:      swi.bi  $fp, [$r6], #4
 190         bne $r7, $r6, 1b
 191         swi     $r10, [$r8]
 192 
 193 _RRT:
 194         b   start_kernel
 195 
 196 __error:
 197         b   __error

/* [<][>][^][v][top][bottom][index][help] */