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 <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