linux/arch/mips/kernel/head.S
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 1994, 1995 Waldorf Electronics
   7 * Written by Ralf Baechle and Andreas Busse
   8 * Copyright (C) 1994 - 99, 2003, 06 Ralf Baechle
   9 * Copyright (C) 1996 Paul M. Antoine
  10 * Modified for DECStation and hence R3000 support by Paul M. Antoine
  11 * Further modifications by David S. Miller and Harald Koerfgen
  12 * Copyright (C) 1999 Silicon Graphics, Inc.
  13 * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  14 * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  15 */
  16#include <linux/init.h>
  17#include <linux/threads.h>
  18
  19#include <asm/addrspace.h>
  20#include <asm/asm.h>
  21#include <asm/asmmacro.h>
  22#include <asm/irqflags.h>
  23#include <asm/regdef.h>
  24#include <asm/page.h>
  25#include <asm/pgtable-bits.h>
  26#include <asm/mipsregs.h>
  27#include <asm/stackframe.h>
  28
  29#include <kernel-entry-init.h>
  30
  31        /*
  32         * inputs are the text nasid in t1, data nasid in t2.
  33         */
  34        .macro MAPPED_KERNEL_SETUP_TLB
  35#ifdef CONFIG_MAPPED_KERNEL
  36        /*
  37         * This needs to read the nasid - assume 0 for now.
  38         * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
  39         * 0+DVG in tlblo_1.
  40         */
  41        dli     t0, 0xffffffffc0000000
  42        dmtc0   t0, CP0_ENTRYHI
  43        li      t0, 0x1c000             # Offset of text into node memory
  44        dsll    t1, NASID_SHFT          # Shift text nasid into place
  45        dsll    t2, NASID_SHFT          # Same for data nasid
  46        or      t1, t1, t0              # Physical load address of kernel text
  47        or      t2, t2, t0              # Physical load address of kernel data
  48        dsrl    t1, 12                  # 4K pfn
  49        dsrl    t2, 12                  # 4K pfn
  50        dsll    t1, 6                   # Get pfn into place
  51        dsll    t2, 6                   # Get pfn into place
  52        li      t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6)
  53        or      t0, t0, t1
  54        mtc0    t0, CP0_ENTRYLO0        # physaddr, VG, cach exlwr
  55        li      t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6)
  56        or      t0, t0, t2
  57        mtc0    t0, CP0_ENTRYLO1        # physaddr, DVG, cach exlwr
  58        li      t0, 0x1ffe000           # MAPPED_KERN_TLBMASK, TLBPGMASK_16M
  59        mtc0    t0, CP0_PAGEMASK
  60        li      t0, 0                   # KMAP_INX
  61        mtc0    t0, CP0_INDEX
  62        li      t0, 1
  63        mtc0    t0, CP0_WIRED
  64        tlbwi
  65#else
  66        mtc0    zero, CP0_WIRED
  67#endif
  68        .endm
  69
  70        /*
  71         * For the moment disable interrupts, mark the kernel mode and
  72         * set ST0_KX so that the CPU does not spit fire when using
  73         * 64-bit addresses.  A full initialization of the CPU's status
  74         * register is done later in per_cpu_trap_init().
  75         */
  76        .macro  setup_c0_status set clr
  77        .set    push
  78#ifdef CONFIG_MIPS_MT_SMTC
  79        /*
  80         * For SMTC, we need to set privilege and disable interrupts only for
  81         * the current TC, using the TCStatus register.
  82         */
  83        mfc0    t0, CP0_TCSTATUS
  84        /* Fortunately CU 0 is in the same place in both registers */
  85        /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
  86        li      t1, ST0_CU0 | 0x08001c00
  87        or      t0, t1
  88        /* Clear TKSU, leave IXMT */
  89        xori    t0, 0x00001800
  90        mtc0    t0, CP0_TCSTATUS
  91        _ehb
  92        /* We need to leave the global IE bit set, but clear EXL...*/
  93        mfc0    t0, CP0_STATUS
  94        or      t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr
  95        xor     t0, ST0_EXL | ST0_ERL | \clr
  96        mtc0    t0, CP0_STATUS
  97#else
  98        mfc0    t0, CP0_STATUS
  99        or      t0, ST0_CU0|\set|0x1f|\clr
 100        xor     t0, 0x1f|\clr
 101        mtc0    t0, CP0_STATUS
 102        .set    noreorder
 103        sll     zero,3                          # ehb
 104#endif
 105        .set    pop
 106        .endm
 107
 108        .macro  setup_c0_status_pri
 109#ifdef CONFIG_64BIT
 110        setup_c0_status ST0_KX 0
 111#else
 112        setup_c0_status 0 0
 113#endif
 114        .endm
 115
 116        .macro  setup_c0_status_sec
 117#ifdef CONFIG_64BIT
 118        setup_c0_status ST0_KX ST0_BEV
 119#else
 120        setup_c0_status 0 ST0_BEV
 121#endif
 122        .endm
 123
 124#ifndef CONFIG_NO_EXCEPT_FILL
 125        /*
 126         * Reserved space for exception handlers.
 127         * Necessary for machines which link their kernels at KSEG0.
 128         */
 129        .fill   0x400
 130#endif
 131
 132EXPORT(_stext)
 133
 134#ifdef CONFIG_BOOT_RAW
 135        /*
 136         * Give us a fighting chance of running if execution beings at the
 137         * kernel load address.  This is needed because this platform does
 138         * not have a ELF loader yet.
 139         */
 140FEXPORT(__kernel_entry)
 141        j       kernel_entry
 142#endif
 143
 144        __REF
 145
 146NESTED(kernel_entry, 16, sp)                    # kernel entry point
 147
 148        kernel_entry_setup                      # cpu specific setup
 149
 150        setup_c0_status_pri
 151
 152        /* We might not get launched at the address the kernel is linked to,
 153           so we jump there.  */
 154        PTR_LA  t0, 0f
 155        jr      t0
 1560:
 157
 158#ifdef CONFIG_MIPS_MT_SMTC
 159        /*
 160         * In SMTC kernel, "CLI" is thread-specific, in TCStatus.
 161         * We still need to enable interrupts globally in Status,
 162         * and clear EXL/ERL.
 163         *
 164         * TCContext is used to track interrupt levels under
 165         * service in SMTC kernel. Clear for boot TC before
 166         * allowing any interrupts.
 167         */
 168        mtc0    zero, CP0_TCCONTEXT
 169
 170        mfc0    t0, CP0_STATUS
 171        ori     t0, t0, 0xff1f
 172        xori    t0, t0, 0x001e
 173        mtc0    t0, CP0_STATUS
 174#endif /* CONFIG_MIPS_MT_SMTC */
 175
 176        PTR_LA          t0, __bss_start         # clear .bss
 177        LONG_S          zero, (t0)
 178        PTR_LA          t1, __bss_stop - LONGSIZE
 1791:
 180        PTR_ADDIU       t0, LONGSIZE
 181        LONG_S          zero, (t0)
 182        bne             t0, t1, 1b
 183
 184        LONG_S          a0, fw_arg0             # firmware arguments
 185        LONG_S          a1, fw_arg1
 186        LONG_S          a2, fw_arg2
 187        LONG_S          a3, fw_arg3
 188
 189        MTC0            zero, CP0_CONTEXT       # clear context register
 190        PTR_LA          $28, init_thread_union
 191        /* Set the SP after an empty pt_regs.  */
 192        PTR_LI          sp, _THREAD_SIZE - 32 - PT_SIZE
 193        PTR_ADDU        sp, $28
 194        back_to_back_c0_hazard
 195        set_saved_sp    sp, t0, t1
 196        PTR_SUBU        sp, 4 * SZREG           # init stack pointer
 197
 198        j               start_kernel
 199        END(kernel_entry)
 200
 201        __CPUINIT
 202
 203#ifdef CONFIG_SMP
 204/*
 205 * SMP slave cpus entry point.  Board specific code for bootstrap calls this
 206 * function after setting up the stack and gp registers.
 207 */
 208NESTED(smp_bootstrap, 16, sp)
 209#ifdef CONFIG_MIPS_MT_SMTC
 210        /*
 211         * Read-modify-writes of Status must be atomic, and this
 212         * is one case where CLI is invoked without EXL being
 213         * necessarily set. The CLI and setup_c0_status will
 214         * in fact be redundant for all but the first TC of
 215         * each VPE being booted.
 216         */
 217        DMT     10      # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */
 218        jal     mips_ihb
 219#endif /* CONFIG_MIPS_MT_SMTC */
 220        setup_c0_status_sec
 221        smp_slave_setup
 222#ifdef CONFIG_MIPS_MT_SMTC
 223        andi    t2, t2, VPECONTROL_TE
 224        beqz    t2, 2f
 225        EMT             # emt
 2262:
 227#endif /* CONFIG_MIPS_MT_SMTC */
 228        j       start_secondary
 229        END(smp_bootstrap)
 230#endif /* CONFIG_SMP */
 231
 232        __FINIT
 233