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/mipsregs.h>
  25#include <asm/stackframe.h>
  26
  27#include <kernel-entry-init.h>
  28
  29        /*
  30         * For the moment disable interrupts, mark the kernel mode and
  31         * set ST0_KX so that the CPU does not spit fire when using
  32         * 64-bit addresses.  A full initialization of the CPU's status
  33         * register is done later in per_cpu_trap_init().
  34         */
  35        .macro  setup_c0_status set clr
  36        .set    push
  37        mfc0    t0, CP0_STATUS
  38        or      t0, ST0_CU0|\set|0x1f|\clr
  39        xor     t0, 0x1f|\clr
  40        mtc0    t0, CP0_STATUS
  41        .set    noreorder
  42        sll     zero,3                          # ehb
  43        .set    pop
  44        .endm
  45
  46        .macro  setup_c0_status_pri
  47#ifdef CONFIG_64BIT
  48        setup_c0_status ST0_KX 0
  49#else
  50        setup_c0_status 0 0
  51#endif
  52        .endm
  53
  54        .macro  setup_c0_status_sec
  55#ifdef CONFIG_64BIT
  56        setup_c0_status ST0_KX ST0_BEV
  57#else
  58        setup_c0_status 0 ST0_BEV
  59#endif
  60        .endm
  61
  62#ifndef CONFIG_NO_EXCEPT_FILL
  63        /*
  64         * Reserved space for exception handlers.
  65         * Necessary for machines which link their kernels at KSEG0.
  66         */
  67        .fill   0x400
  68#endif
  69
  70EXPORT(_stext)
  71
  72#ifdef CONFIG_BOOT_RAW
  73        /*
  74         * Give us a fighting chance of running if execution beings at the
  75         * kernel load address.  This is needed because this platform does
  76         * not have a ELF loader yet.
  77         */
  78FEXPORT(__kernel_entry)
  79        j       kernel_entry
  80#endif
  81
  82        __REF
  83
  84NESTED(kernel_entry, 16, sp)                    # kernel entry point
  85
  86        kernel_entry_setup                      # cpu specific setup
  87
  88        setup_c0_status_pri
  89
  90        /* We might not get launched at the address the kernel is linked to,
  91           so we jump there.  */
  92        PTR_LA  t0, 0f
  93        jr      t0
  940:
  95
  96#ifdef CONFIG_USE_OF
  97#ifdef CONFIG_MIPS_RAW_APPENDED_DTB
  98        PTR_LA          t2, __appended_dtb
  99
 100#ifdef CONFIG_CPU_BIG_ENDIAN
 101        li              t1, 0xd00dfeed
 102#else
 103        li              t1, 0xedfe0dd0
 104#endif
 105        lw              t0, (t2)
 106        beq             t0, t1, dtb_found
 107#endif
 108        li              t1, -2
 109        move            t2, a1
 110        beq             a0, t1, dtb_found
 111
 112        li              t2, 0
 113dtb_found:
 114#endif
 115        PTR_LA          t0, __bss_start         # clear .bss
 116        LONG_S          zero, (t0)
 117        PTR_LA          t1, __bss_stop - LONGSIZE
 1181:
 119        PTR_ADDIU       t0, LONGSIZE
 120        LONG_S          zero, (t0)
 121        bne             t0, t1, 1b
 122
 123        LONG_S          a0, fw_arg0             # firmware arguments
 124        LONG_S          a1, fw_arg1
 125        LONG_S          a2, fw_arg2
 126        LONG_S          a3, fw_arg3
 127
 128#ifdef CONFIG_USE_OF
 129        LONG_S          t2, fw_passed_dtb
 130#endif
 131
 132        MTC0            zero, CP0_CONTEXT       # clear context register
 133        PTR_LA          $28, init_thread_union
 134        /* Set the SP after an empty pt_regs.  */
 135        PTR_LI          sp, _THREAD_SIZE - 32 - PT_SIZE
 136        PTR_ADDU        sp, $28
 137        back_to_back_c0_hazard
 138        set_saved_sp    sp, t0, t1
 139        PTR_SUBU        sp, 4 * SZREG           # init stack pointer
 140
 141#ifdef CONFIG_RELOCATABLE
 142        /* Copy kernel and apply the relocations */
 143        jal             relocate_kernel
 144
 145        /* Repoint the sp into the new kernel image */
 146        PTR_LI          sp, _THREAD_SIZE - 32 - PT_SIZE
 147        PTR_ADDU        sp, $28
 148        set_saved_sp    sp, t0, t1
 149        PTR_SUBU        sp, 4 * SZREG           # init stack pointer
 150
 151        /*
 152         * relocate_kernel returns the entry point either
 153         * in the relocated kernel or the original if for
 154         * some reason relocation failed - jump there now
 155         * with instruction hazard barrier because of the
 156         * newly sync'd icache.
 157         */
 158        jr.hb           v0
 159#else
 160        j               start_kernel
 161#endif
 162        END(kernel_entry)
 163
 164#ifdef CONFIG_SMP
 165/*
 166 * SMP slave cpus entry point.  Board specific code for bootstrap calls this
 167 * function after setting up the stack and gp registers.
 168 */
 169NESTED(smp_bootstrap, 16, sp)
 170        smp_slave_setup
 171        setup_c0_status_sec
 172        j       start_secondary
 173        END(smp_bootstrap)
 174#endif /* CONFIG_SMP */
 175