/*1* arch/xtensa/kernel/head.S2*3* Xtensa Processor startup code.4*5* This file is subject to the terms and conditions of the GNU General Public6* License. See the file "COPYING" in the main directory of this archive7* for more details.8*9* Copyright (C) 2001 - 2005 Tensilica Inc.10*11* Chris Zankel <[email protected]>12* Marc Gauthier <[email protected], [email protected]>13* Joe Taylor <[email protected], [email protected]>14* Kevin Chea15*/1617#include <asm/processor.h>18#include <asm/page.h>19#include <asm/cacheasm.h>2021#include <linux/init.h>22#include <linux/linkage.h>2324/*25* This module contains the entry code for kernel images. It performs the26* minimal setup needed to call the generic C routines.27*28* Prerequisites:29*30* - The kernel image has been loaded to the actual address where it was31* compiled to.32* - a2 contains either 0 or a pointer to a list of boot parameters.33* (see setup.c for more details)34*35*/3637/*38* _start39*40* The bootloader passes a pointer to a list of boot parameters in a2.41*/4243/* The first bytes of the kernel image must be an instruction, so we44* manually allocate and define the literal constant we need for a jx45* instruction.46*/4748__HEAD49.globl _start50_start: _j 2f51.align 4521: .word _startup532: l32r a0, 1b54jx a05556.section .init.text, "ax"57.align 458_startup:5960/* Disable interrupts and exceptions. */6162movi a0, LOCKLEVEL63wsr a0, PS6465/* Preserve the pointer to the boot parameter list in EXCSAVE_1 */6667wsr a2, EXCSAVE_16869/* Start with a fresh windowbase and windowstart. */7071movi a1, 172movi a0, 073wsr a1, WINDOWSTART74wsr a0, WINDOWBASE75rsync7677/* Set a0 to 0 for the remaining initialization. */7879movi a0, 08081/* Clear debugging registers. */8283#if XCHAL_HAVE_DEBUG84wsr a0, IBREAKENABLE85wsr a0, ICOUNT86movi a1, 1587wsr a0, ICOUNTLEVEL8889.set _index, 090.rept XCHAL_NUM_DBREAK - 191wsr a0, DBREAKC + _index92.set _index, _index + 193.endr94#endif9596/* Clear CCOUNT (not really necessary, but nice) */9798wsr a0, CCOUNT # not really necessary, but nice99100/* Disable zero-loops. */101102#if XCHAL_HAVE_LOOPS103wsr a0, LCOUNT104#endif105106/* Disable all timers. */107108.set _index, 0109.rept XCHAL_NUM_TIMERS - 1110wsr a0, CCOMPARE + _index111.set _index, _index + 1112.endr113114/* Interrupt initialization. */115116movi a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE117wsr a0, INTENABLE118wsr a2, INTCLEAR119120/* Disable coprocessors. */121122#if XCHAL_CP_NUM > 0123wsr a0, CPENABLE124#endif125126/* Set PS.INTLEVEL=1, PS.WOE=0, kernel stack, PS.EXCM=0127*128* Note: PS.EXCM must be cleared before using any loop129* instructions; otherwise, they are silently disabled, and130* at most one iteration of the loop is executed.131*/132133movi a1, 1134wsr a1, PS135rsync136137/* Initialize the caches.138* a2, a3 are just working registers (clobbered).139*/140141#if XCHAL_DCACHE_LINE_LOCKABLE142___unlock_dcache_all a2 a3143#endif144145#if XCHAL_ICACHE_LINE_LOCKABLE146___unlock_icache_all a2 a3147#endif148149___invalidate_dcache_all a2 a3150___invalidate_icache_all a2 a3151152isync153154/* Unpack data sections155*156* The linker script used to build the Linux kernel image157* creates a table located at __boot_reloc_table_start158* that contans the information what data needs to be unpacked.159*160* Uses a2-a7.161*/162163movi a2, __boot_reloc_table_start164movi a3, __boot_reloc_table_end1651661: beq a2, a3, 3f # no more entries?167l32i a4, a2, 0 # start destination (in RAM)168l32i a5, a2, 4 # end desination (in RAM)169l32i a6, a2, 8 # start source (in ROM)170addi a2, a2, 12 # next entry171beq a4, a5, 1b # skip, empty entry172beq a4, a6, 1b # skip, source and dest. are the same1731742: l32i a7, a6, 0 # load word175addi a6, a6, 4176s32i a7, a4, 0 # store word177addi a4, a4, 4178bltu a4, a5, 2b179j 1b1801813:182/* All code and initialized data segments have been copied.183* Now clear the BSS segment.184*/185186movi a2, __bss_start # start of BSS187movi a3, __bss_stop # end of BSS188189__loopt a2, a3, a4, 2190s32i a0, a2, 0191__endla a2, a4, 4192193#if XCHAL_DCACHE_IS_WRITEBACK194195/* After unpacking, flush the writeback cache to memory so the196* instructions/data are available.197*/198199___flush_dcache_all a2 a3200#endif201202/* Setup stack and enable window exceptions (keep irqs disabled) */203204movi a1, init_thread_union205addi a1, a1, KERNEL_STACK_SIZE206207movi a2, 0x00040001 # WOE=1, INTLEVEL=1, UM=0208wsr a2, PS # (enable reg-windows; progmode stack)209rsync210211/* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/212213movi a2, debug_exception214wsr a2, EXCSAVE + XCHAL_DEBUGLEVEL215216/* Set up EXCSAVE[1] to point to the exc_table. */217218movi a6, exc_table219xsr a6, EXCSAVE_1220221/* init_arch kick-starts the linux kernel */222223movi a4, init_arch224callx4 a4225226movi a4, start_kernel227callx4 a4228229should_never_return:230j should_never_return231232233/*234* BSS section235*/236237__PAGE_ALIGNED_BSS238#ifdef CONFIG_MMU239ENTRY(swapper_pg_dir)240.fill PAGE_SIZE, 1, 0241#endif242ENTRY(empty_zero_page)243.fill PAGE_SIZE, 1, 0244245246