linux/arch/nds32/kernel/head.S
<<
>>
Prefs
   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 <linux/pgtable.h>
   7#include <asm/ptrace.h>
   8#include <asm/asm-offsets.h>
   9#include <asm/page.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
  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        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
 1891:      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
 198